atom-languageclient
Version:
Integrate Language Servers with Atom
174 lines • 24.7 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 languageclient_1 = require("../languageclient");
const fs_1 = require("fs");
const rimraf = require("rimraf");
/** Public: Adapts workspace/applyEdit commands to editors. */
class ApplyEditAdapter {
/** Public: Attach to a {LanguageClientConnection} to receive edit events. */
static attach(connection) {
connection.onApplyEdit((m) => ApplyEditAdapter.onApplyEdit(m));
}
/** Tries to apply edits and reverts if anything goes wrong. Returns the checkpoint, so the caller can revert changes if needed. */
static applyEdits(buffer, edits) {
const checkpoint = buffer.createCheckpoint();
try {
// Sort edits in reverse order to prevent edit conflicts.
edits.sort((edit1, edit2) => -edit1.oldRange.compare(edit2.oldRange));
edits.reduce((previous, current) => {
validateEdit(buffer, current, previous);
buffer.setTextInRange(current.oldRange, current.newText);
return current;
}, null);
buffer.groupChangesSinceCheckpoint(checkpoint);
return checkpoint;
}
catch (err) {
buffer.revertToCheckpoint(checkpoint);
throw err;
}
}
static onApplyEdit(params) {
return __awaiter(this, void 0, void 0, function* () {
return ApplyEditAdapter.apply(params.edit);
});
}
static apply(workspaceEdit) {
return __awaiter(this, void 0, void 0, function* () {
normalize(workspaceEdit);
// Keep checkpoints from all successful buffer edits
const checkpoints = [];
const promises = (workspaceEdit.documentChanges || []).map((edit) => __awaiter(this, void 0, void 0, function* () {
if (!languageclient_1.TextDocumentEdit.is(edit)) {
return ApplyEditAdapter.handleResourceOperation(edit).catch((err) => {
throw Error(`Error during ${edit.kind} resource operation: ${err.message}`);
});
}
const path = convert_1.default.uriToPath(edit.textDocument.uri);
const editor = (yield atom.workspace.open(path, {
searchAllPanes: true,
// Open new editors in the background.
activatePane: false,
activateItem: false,
}));
const buffer = editor.getBuffer();
const edits = convert_1.default.convertLsTextEdits(edit.edits);
const checkpoint = ApplyEditAdapter.applyEdits(buffer, edits);
checkpoints.push({ buffer, checkpoint });
}));
// Apply all edits or fail and revert everything
const applied = yield Promise.all(promises)
.then(() => true)
.catch((err) => {
atom.notifications.addError("workspace/applyEdits failed", {
description: "Failed to apply edits.",
detail: err.message,
});
checkpoints.forEach(({ buffer, checkpoint }) => {
buffer.revertToCheckpoint(checkpoint);
});
return false;
});
return { applied };
});
}
static handleResourceOperation(edit) {
var _a, _b, _c, _d, _e, _f, _g;
return __awaiter(this, void 0, void 0, function* () {
if (languageclient_1.DeleteFile.is(edit)) {
const path = convert_1.default.uriToPath(edit.uri);
const stats = yield fs_1.promises.lstat(path).catch(() => false);
const ignoreIfNotExists = (_a = edit.options) === null || _a === void 0 ? void 0 : _a.ignoreIfNotExists;
if (!stats) {
if (ignoreIfNotExists !== false) {
return;
}
throw Error(`Target doesn't exist.`);
}
if (stats.isDirectory()) {
if ((_b = edit.options) === null || _b === void 0 ? void 0 : _b.recursive) {
return new Promise((resolve, reject) => {
rimraf(path, { glob: false }, (err) => {
if (err) {
reject(err);
}
resolve();
});
});
}
return fs_1.promises.rmdir(path, { recursive: (_c = edit.options) === null || _c === void 0 ? void 0 : _c.recursive });
}
return fs_1.promises.unlink(path);
}
if (languageclient_1.RenameFile.is(edit)) {
const oldPath = convert_1.default.uriToPath(edit.oldUri);
const newPath = convert_1.default.uriToPath(edit.newUri);
const exists = yield fs_1.promises
.access(newPath)
.then(() => true)
.catch(() => false);
const ignoreIfExists = (_d = edit.options) === null || _d === void 0 ? void 0 : _d.ignoreIfExists;
const overwrite = (_e = edit.options) === null || _e === void 0 ? void 0 : _e.overwrite;
if (exists && ignoreIfExists && !overwrite) {
return;
}
if (exists && !ignoreIfExists && !overwrite) {
throw Error(`Target exists.`);
}
return fs_1.promises.rename(oldPath, newPath);
}
if (languageclient_1.CreateFile.is(edit)) {
const path = convert_1.default.uriToPath(edit.uri);
const exists = yield fs_1.promises
.access(path)
.then(() => true)
.catch(() => false);
const ignoreIfExists = (_f = edit.options) === null || _f === void 0 ? void 0 : _f.ignoreIfExists;
const overwrite = (_g = edit.options) === null || _g === void 0 ? void 0 : _g.overwrite;
if (exists && ignoreIfExists && !overwrite) {
return;
}
return fs_1.promises.writeFile(path, "");
}
});
}
}
exports.default = ApplyEditAdapter;
function normalize(workspaceEdit) {
const documentChanges = workspaceEdit.documentChanges || [];
if (!("documentChanges" in workspaceEdit) && "changes" in workspaceEdit) {
Object.keys(workspaceEdit.changes || []).forEach((uri) => {
documentChanges.push({
textDocument: {
version: null,
uri,
},
edits: workspaceEdit.changes[uri],
});
});
}
workspaceEdit.documentChanges = documentChanges;
}
function validateEdit(buffer, edit, prevEdit) {
const path = buffer.getPath() || "";
if (prevEdit && edit.oldRange.end.compare(prevEdit.oldRange.start) > 0) {
throw Error(`Found overlapping edit ranges in ${path}`);
}
const startRow = edit.oldRange.start.row;
const startCol = edit.oldRange.start.column;
const lineLength = buffer.lineLengthForRow(startRow);
if (lineLength == null || startCol > lineLength) {
throw Error(`Out of range edit on ${path}:${startRow + 1}:${startCol + 1}`);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbHktZWRpdC1hZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL2FkYXB0ZXJzL2FwcGx5LWVkaXQtYWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUNBLHdDQUFnQztBQUNoQyxzREFVMEI7QUFFMUIsMkJBQTJDO0FBQzNDLGlDQUFnQztBQUVoQyw4REFBOEQ7QUFDOUQsTUFBcUIsZ0JBQWdCO0lBQ25DLDZFQUE2RTtJQUN0RSxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQW9DO1FBQ3ZELFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ2hFLENBQUM7SUFFRCxtSUFBbUk7SUFDNUgsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFrQixFQUFFLEtBQXlCO1FBQ3BFLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFBO1FBQzVDLElBQUk7WUFDRix5REFBeUQ7WUFDekQsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUE7WUFDckUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQWlDLEVBQUUsT0FBTyxFQUFFLEVBQUU7Z0JBQzFELFlBQVksQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFBO2dCQUN2QyxNQUFNLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO2dCQUN4RCxPQUFPLE9BQU8sQ0FBQTtZQUNoQixDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7WUFDUixNQUFNLENBQUMsMkJBQTJCLENBQUMsVUFB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RTtRQUN0RSxNQUFNLEtBQUssQ0FBQyxvQ0FBb0MsSUFBSSxFQUFFLENBQUMsQ0FBQTtLQUN4RDtJQUNELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQTtJQUN4QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUE7SUFDM0MsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQ3BELElBQUksVUFBVSxJQUFJLElBQUksSUFBSSxRQUFRLEdBQUcsVUFBVSxFQUFFO1FBQy9DLE1BQU0sS0FBSyxDQUFDLHdCQUF3QixJQUFJLElBQUksUUFBUSxHQUFHLENBQUMsSUFBSSxRQUFRLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQTtLQUM1RTtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSAqIGFzIGF0b21JZGUgZnJvbSBcImF0b20taWRlLWJhc2VcIlxuaW1wb3J0IENvbnZlcnQgZnJvbSBcIi4uL2NvbnZlcnRcIlxuaW1wb3J0IHtcbiAgTGFuZ3VhZ2VDbGllbnRDb25uZWN0aW9uLFxuICBBcHBseVdvcmtzcGFjZUVkaXRQYXJhbXMsXG4gIEFwcGx5V29ya3NwYWNlRWRpdFJlc3BvbnNlLFxuICBXb3Jrc3BhY2VFZGl0LFxuICBUZXh0RG9jdW1lbnRFZGl0LFxuICBDcmVhdGVGaWxlLFxuICBSZW5hbWVGaWxlLFxuICBEZWxldGVGaWxlLFxuICBEb2N1bWVudFVyaSxcbn0gZnJvbSBcIi4uL2xhbmd1YWdlY2xpZW50XCJcbmltcG9ydCB7IFRleHRCdWZmZXIsIFRleHRFZGl0b3IgfSBmcm9tIFwiYXRvbVwiXG5pbXBvcnQgeyBwcm9taXNlcyBhcyBmc3AsIFN0YXRzIH0gZnJvbSBcImZzXCJcbmltcG9ydCAqIGFzIHJpbXJhZiBmcm9tIFwicmltcmFmXCJcblxuLyoqIFB1YmxpYzogQWRhcHRzIHdvcmtzcGFjZS9hcHBseUVkaXQgY29tbWFuZHMgdG8gZWRpdG9ycy4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFwcGx5RWRpdEFkYXB0ZXIge1xuICAvKiogUHVibGljOiBBdHRhY2ggdG8gYSB7TGFuZ3VhZ2VDbGllbnRDb25uZWN0aW9ufSB0byByZWNlaXZlIGVkaXQgZXZlbnRzLiAqL1xuICBwdWJsaWMgc3RhdGljIGF0dGFjaChjb25uZWN0aW9uOiBMYW5ndWFnZUNsaWVudENvbm5lY3Rpb24pOiB2b2lkIHtcbiAgICBjb25uZWN0aW9uLm9uQXBwbHlFZGl0KChtKSA9PiBBcHBseUVkaXRBZGFwdGVyLm9uQXBwbHlFZGl0KG0pKVxuICB9XG5cbiAgLyoqIFRyaWVzIHRvIGFwcGx5IGVkaXRzIGFuZCByZXZlcnRzIGlmIGFueXRoaW5nIGdvZXMgd3JvbmcuIFJldHVybnMgdGhlIGNoZWNrcG9pbnQsIHNvIHRoZSBjYWxsZXIgY2FuIHJldmVydCBjaGFuZ2VzIGlmIG5lZWRlZC4gKi9cbiAgcHVibGljIHN0YXRpYyBhcHBseUVkaXRzKGJ1ZmZlcjogVGV4dEJ1ZmZlciwgZWRpdHM6IGF0b21JZGUuVGV4dEVkaXRbXSk6IG51bWJlciB7XG4gICAgY29uc3QgY2hlY2twb2ludCA9IGJ1ZmZlci5jcmVhdGVDaGVja3BvaW50KClcbiAgICB0cnkge1xuICAgICAgLy8gU29ydCBlZGl0cyBpbiByZXZlcnNlIG9yZGVyIHRvIHByZXZlbnQgZWRpdCBjb25mbGljdHMuXG4gICAgICBlZGl0cy5zb3J0KChlZGl0MSwgZWRpdDIpID0+IC1lZGl0MS5vbGRSYW5nZS5jb21wYXJlKGVkaXQyLm9sZFJhbmdlKSlcbiAgICAgIGVkaXRzLnJlZHVjZSgocHJldmlvdXM6IGF0b21JZGUuVGV4dEVkaXQgfCBudWxsLCBjdXJyZW50KSA9PiB7XG4gICAgICAgIHZhbGlkYXRlRWRpdChidWZmZXIsIGN1cnJlbnQsIHByZXZpb3VzKVxuICAgICAgICBidWZmZXIuc2V0VGV4dEluUmFuZ2UoY3VycmVudC5vbGRSYW5nZSwgY3VycmVudC5uZXdUZXh0KVxuICAgICAgICByZXR1cm4gY3VycmVudFxuICAgICAgfSwgbnVsbClcbiAgICAgIGJ1ZmZlci5ncm91cENoYW5nZXNTaW5jZUNoZWNrcG9pbnQoY2hlY2twb2ludClcbiAgICAgIHJldHVybiBjaGVja3BvaW50XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBidWZmZXIucmV2ZXJ0VG9DaGVja3BvaW50KGNoZWNrcG9pbnQpXG4gICAgICB0aHJvdyBlcnJcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGFzeW5jIG9uQXBwbHlFZGl0KHBhcmFtczogQXBwbHlXb3Jrc3BhY2VFZGl0UGFyYW1zKTogUHJvbWlzZTxBcHBseVdvcmtzcGFjZUVkaXRSZXNwb25zZT4ge1xuICAgIHJldHVybiBBcHBseUVkaXRBZGFwdGVyLmFwcGx5KHBhcmFtcy5lZGl0KVxuICB9XG5cbiAgcHVibGljIHN0YXRpYyBhc3luYyBhcHBseSh3b3Jrc3BhY2VFZGl0OiBXb3Jrc3BhY2VFZGl0KTogUHJvbWlzZTxBcHBseVdvcmtzcGFjZUVkaXRSZXNwb25zZT4ge1xuICAgIG5vcm1hbGl6ZSh3b3Jrc3BhY2VFZGl0KVxuXG4gICAgLy8gS2VlcCBjaGVja3BvaW50cyBmcm9tIGFsbCBzdWNjZXNzZnVsIGJ1ZmZlciBlZGl0c1xuICAgIGNvbnN0IGNoZWNrcG9pbnRzOiBBcnJheTx7IGJ1ZmZlcjogVGV4dEJ1ZmZlcjsgY2hlY2twb2ludDogbnVtYmVyIH0+ID0gW11cblxuICAgIGNvbnN0IHByb21pc2VzID0gKHdvcmtzcGFjZUVkaXQuZG9jdW1lbnRDaGFuZ2VzIHx8IFtdKS5tYXAoYXN5bmMgKGVkaXQpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgIGlmICghVGV4dERvY3VtZW50RWRpdC5pcyhlZGl0KSkge1xuICAgICAgICByZXR1cm4gQXBwbHlFZGl0QWRhcHRlci5oYW5kbGVSZXNvdXJjZU9wZXJhdGlvbihlZGl0KS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgdGhyb3cgRXJyb3IoYEVycm9yIGR1cmluZyAke2VkaXQua2luZH0gcmVzb3VyY2Ugb3BlcmF0aW9uOiAke2Vyci5tZXNzYWdlfWApXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgICBjb25zdCBwYXRoID0gQ29udmVydC51cmlUb1BhdGgoZWRpdC50ZXh0RG9jdW1lbnQudXJpKVxuICAgICAgY29uc3QgZWRpdG9yID0gKGF3YWl0IGF0b20ud29ya3NwYWNlLm9wZW4ocGF0aCwge1xuICAgICAgICBzZWFyY2hBbGxQYW5lczogdHJ1ZSxcbiAgICAgICAgLy8gT3BlbiBuZXcgZWRpdG9ycyBpbiB0aGUgYmFja2dyb3VuZC5cbiAgICAgICAgYWN0aXZhdGVQYW5lOiBmYWxzZSxcbiAgICAgICAgYWN0aXZhdGVJdGVtOiBmYWxzZSxcbiAgICAgIH0pKSBhcyBUZXh0RWRpdG9yXG4gICAgICBjb25zdCBidWZmZXIgPSBlZGl0b3IuZ2V0QnVmZmVyKClcbiAgICAgIGNvbnN0IGVkaXRzID0gQ29udmVydC5jb252ZXJ0THNUZXh0RWRpdHMoZWRpdC5lZGl0cylcbiAgICAgIGNvbnN0IGNoZWNrcG9pbnQgPSBBcHBseUVkaXRBZGFwdGVyLmFwcGx5RWRpdHMoYnVmZmVyLCBlZGl0cylcbiAgICAgIGNoZWNrcG9pbnRzLnB1c2goeyBidWZmZXIsIGNoZWNrcG9pbnQgfSlcbiAgICB9KVxuXG4gICAgLy8gQXBwbHkgYWxsIGVkaXRzIG9yIGZhaWwgYW5kIHJldmVydCBldmVyeXRoaW5nXG4gICAgY29uc3QgYXBwbGllZCA9IGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKVxuICAgICAgLnRoZW4oKCkgPT4gdHJ1ZSlcbiAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIGF0b20ubm90aWZpY2F0aW9ucy5hZGRFcnJvcihcIndvcmtzcGFjZS9hcHBseUVkaXRzIGZhaWxlZFwiLCB7XG4gICAgICAgICAgZGVzY3JpcHRpb246IFwiRmFpbGVkIHRvIGFwcGx5IGVkaXRzLlwiLFxuICAgICAgICAgIGRldGFpbDogZXJyLm1lc3NhZ2UsXG4gICAgICAgIH0pXG4gICAgICAgIGNoZWNrcG9pbnRzLmZvckVhY2goKHsgYnVmZmVyLCBjaGVja3BvaW50IH0pID0+IHtcbiAgICAgICAgICBidWZmZXIucmV2ZXJ0VG9DaGVja3BvaW50KGNoZWNrcG9pbnQpXG4gICAgICAgIH0pXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfSlcblxuICAgIHJldHVybiB7IGFwcGxpZWQgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgYXN5bmMgaGFuZGxlUmVzb3VyY2VPcGVyYXRpb24oZWRpdDogQ3JlYXRlRmlsZSB8IFJlbmFtZUZpbGUgfCBEZWxldGVGaWxlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKERlbGV0ZUZpbGUuaXMoZWRpdCkpIHtcbiAgICAgIGNvbnN0IHBhdGggPSBDb252ZXJ0LnVyaVRvUGF0aChlZGl0LnVyaSlcbiAgICAgIGNvbnN0IHN0YXRzOiBib29sZWFuIHwgU3RhdHMgPSBhd2FpdCBmc3AubHN0YXQocGF0aCkuY2F0Y2goKCkgPT4gZmFsc2UpXG4gICAgICBjb25zdCBpZ25vcmVJZk5vdEV4aXN0cyA9IGVkaXQub3B0aW9ucz8uaWdub3JlSWZOb3RFeGlzdHNcblxuICAgICAgaWYgKCFzdGF0cykge1xuICAgICAgICBpZiAoaWdub3JlSWZOb3RFeGlzdHMgIT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgRXJyb3IoYFRhcmdldCBkb2Vzbid0IGV4aXN0LmApXG4gICAgICB9XG5cbiAgICAgIGlmIChzdGF0cy5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIGlmIChlZGl0Lm9wdGlvbnM/LnJlY3Vyc2l2ZSkge1xuICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICByaW1yYWYocGF0aCwgeyBnbG9iOiBmYWxzZSB9LCAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlc29sdmUoKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmc3Aucm1kaXIocGF0aCwgeyByZWN1cnNpdmU6IGVkaXQub3B0aW9ucz8ucmVjdXJzaXZlIH0pXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmc3AudW5saW5rKHBhdGgpXG4gICAgfVxuICAgIGlmIChSZW5hbWVGaWxlLmlzKGVkaXQpKSB7XG4gICAgICBjb25zdCBvbGRQYXRoID0gQ29udmVydC51cmlUb1BhdGgoZWRpdC5vbGRVcmkpXG4gICAgICBjb25zdCBuZXdQYXRoID0gQ29udmVydC51cmlUb1BhdGgoZWRpdC5uZXdVcmkpXG4gICAgICBjb25zdCBleGlzdHMgPSBhd2FpdCBmc3BcbiAgICAgICAgLmFjY2VzcyhuZXdQYXRoKVxuICAgICAgICAudGhlbigoKSA9PiB0cnVlKVxuICAgICAgICAuY2F0Y2goKCkgPT4gZmFsc2UpXG4gICAgICBjb25zdCBpZ25vcmVJZkV4aXN0cyA9IGVkaXQub3B0aW9ucz8uaWdub3JlSWZFeGlzdHNcbiAgICAgIGNvbnN0IG92ZXJ3cml0ZSA9IGVkaXQub3B0aW9ucz8ub3ZlcndyaXRlXG5cbiAgICAgIGlmIChleGlzdHMgJiYgaWdub3JlSWZFeGlzdHMgJiYgIW92ZXJ3cml0ZSkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgaWYgKGV4aXN0cyAmJiAhaWdub3JlSWZFeGlzdHMgJiYgIW92ZXJ3cml0ZSkge1xuICAgICAgICB0aHJvdyBFcnJvcihgVGFyZ2V0IGV4aXN0cy5gKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gZnNwLnJlbmFtZShvbGRQYXRoLCBuZXdQYXRoKVxuICAgIH1cbiAgICBpZiAoQ3JlYXRlRmlsZS5pcyhlZGl0KSkge1xuICAgICAgY29uc3QgcGF0aCA9IENvbnZlcnQudXJpVG9QYXRoKGVkaXQudXJpKVxuICAgICAgY29uc3QgZXhpc3RzID0gYXdhaXQgZnNwXG4gICAgICAgIC5hY2Nlc3MocGF0aClcbiAgICAgICAgLnRoZW4oKCkgPT4gdHJ1ZSlcbiAgICAgICAgLmNhdGNoKCgpID0+IGZhbHNlKVxuICAgICAgY29uc3QgaWdub3JlSWZFeGlzdHMgPSBlZGl0Lm9wdGlvbnM/Lmlnbm9yZUlmRXhpc3RzXG4gICAgICBjb25zdCBvdmVyd3JpdGUgPSBlZGl0Lm9wdGlvbnM/Lm92ZXJ3cml0ZVxuXG4gICAgICBpZiAoZXhpc3RzICYmIGlnbm9yZUlmRXhpc3RzICYmICFvdmVyd3JpdGUpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmc3Aud3JpdGVGaWxlKHBhdGgsIFwiXCIpXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZSh3b3Jrc3BhY2VFZGl0OiBXb3Jrc3BhY2VFZGl0KTogdm9pZCB7XG4gIGNvbnN0IGRvY3VtZW50Q2hhbmdlcyA9IHdvcmtzcGFjZUVkaXQuZG9jdW1lbnRDaGFuZ2VzIHx8IFtdXG5cbiAgaWYgKCEoXCJkb2N1bWVudENoYW5nZXNcIiBpbiB3b3Jrc3BhY2VFZGl0KSAmJiBcImNoYW5nZXNcIiBpbiB3b3Jrc3BhY2VFZGl0KSB7XG4gICAgT2JqZWN0LmtleXMod29ya3NwYWNlRWRpdC5jaGFuZ2VzIHx8IFtdKS5mb3JFYWNoKCh1cmk6IERvY3VtZW50VXJpKSA9PiB7XG4gICAgICBkb2N1bWVudENoYW5nZXMucHVzaCh7XG4gICAgICAgIHRleHREb2N1bWVudDoge1xuICAgICAgICAgIHZlcnNpb246IG51bGwsXG4gICAgICAgICAgdXJpLFxuICAgICAgICB9LFxuICAgICAgICBlZGl0czogd29ya3NwYWNlRWRpdC5jaGFuZ2VzIVt1cmldLFxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgd29ya3NwYWNlRWRpdC5kb2N1bWVudENoYW5nZXMgPSBkb2N1bWVudENoYW5nZXNcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVFZGl0KGJ1ZmZlcjogVGV4dEJ1ZmZlciwgZWRpdDogYXRvbUlkZS5UZXh0RWRpdCwgcHJldkVkaXQ6IGF0b21JZGUuVGV4dEVkaXQgfCBudWxsKTogdm9pZCB7XG4gIGNvbnN0IHBhdGggPSBidWZmZXIuZ2V0UGF0aCgpIHx8IFwiXCJcbiAgaWYgKHByZXZFZGl0ICYmIGVkaXQub2xkUmFuZ2UuZW5kLmNvbXBhcmUocHJldkVkaXQub2xkUmFuZ2Uuc3RhcnQpID4gMCkge1xuICAgIHRocm93IEVycm9yKGBGb3VuZCBvdmVybGFwcGluZyBlZGl0IHJhbmdlcyBpbiAke3BhdGh9YClcbiAgfVxuICBjb25zdCBzdGFydFJvdyA9IGVkaXQub2xkUmFuZ2Uuc3RhcnQucm93XG4gIGNvbnN0IHN0YXJ0Q29sID0gZWRpdC5vbGRSYW5nZS5zdGFydC5jb2x1bW5cbiAgY29uc3QgbGluZUxlbmd0aCA9IGJ1ZmZlci5saW5lTGVuZ3RoRm9yUm93KHN0YXJ0Um93KVxuICBpZiAobGluZUxlbmd0aCA9PSBudWxsIHx8IHN0YXJ0Q29sID4gbGluZUxlbmd0aCkge1xuICAgIHRocm93IEVycm9yKGBPdXQgb2YgcmFuZ2UgZWRpdCBvbiAke3BhdGh9OiR7c3RhcnRSb3cgKyAxfToke3N0YXJ0Q29sICsgMX1gKVxuICB9XG59XG4iXX0=
;