UNPKG

24.7 kBJavaScriptView Raw
1"use strict";
2var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4 return new (P || (P = Promise))(function (resolve, reject) {
5 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8 step((generator = generator.apply(thisArg, _arguments || [])).next());
9 });
10};
11Object.defineProperty(exports, "__esModule", { value: true });
12const convert_1 = require("../convert");
13const languageclient_1 = require("../languageclient");
14const fs_1 = require("fs");
15const rimraf = require("rimraf");
16/** Public: Adapts workspace/applyEdit commands to editors. */
17class ApplyEditAdapter {
18 /** Public: Attach to a {LanguageClientConnection} to receive edit events. */
19 static attach(connection) {
20 connection.onApplyEdit((m) => ApplyEditAdapter.onApplyEdit(m));
21 }
22 /** Tries to apply edits and reverts if anything goes wrong. Returns the checkpoint, so the caller can revert changes if needed. */
23 static applyEdits(buffer, edits) {
24 const checkpoint = buffer.createCheckpoint();
25 try {
26 // Sort edits in reverse order to prevent edit conflicts.
27 edits.sort((edit1, edit2) => -edit1.oldRange.compare(edit2.oldRange));
28 edits.reduce((previous, current) => {
29 validateEdit(buffer, current, previous);
30 buffer.setTextInRange(current.oldRange, current.newText);
31 return current;
32 }, null);
33 buffer.groupChangesSinceCheckpoint(checkpoint);
34 return checkpoint;
35 }
36 catch (err) {
37 buffer.revertToCheckpoint(checkpoint);
38 throw err;
39 }
40 }
41 static onApplyEdit(params) {
42 return __awaiter(this, void 0, void 0, function* () {
43 return ApplyEditAdapter.apply(params.edit);
44 });
45 }
46 static apply(workspaceEdit) {
47 return __awaiter(this, void 0, void 0, function* () {
48 normalize(workspaceEdit);
49 // Keep checkpoints from all successful buffer edits
50 const checkpoints = [];
51 const promises = (workspaceEdit.documentChanges || []).map((edit) => __awaiter(this, void 0, void 0, function* () {
52 if (!languageclient_1.TextDocumentEdit.is(edit)) {
53 return ApplyEditAdapter.handleResourceOperation(edit).catch((err) => {
54 throw Error(`Error during ${edit.kind} resource operation: ${err.message}`);
55 });
56 }
57 const path = convert_1.default.uriToPath(edit.textDocument.uri);
58 const editor = (yield atom.workspace.open(path, {
59 searchAllPanes: true,
60 // Open new editors in the background.
61 activatePane: false,
62 activateItem: false,
63 }));
64 const buffer = editor.getBuffer();
65 const edits = convert_1.default.convertLsTextEdits(edit.edits);
66 const checkpoint = ApplyEditAdapter.applyEdits(buffer, edits);
67 checkpoints.push({ buffer, checkpoint });
68 }));
69 // Apply all edits or fail and revert everything
70 const applied = yield Promise.all(promises)
71 .then(() => true)
72 .catch((err) => {
73 atom.notifications.addError("workspace/applyEdits failed", {
74 description: "Failed to apply edits.",
75 detail: err.message,
76 });
77 checkpoints.forEach(({ buffer, checkpoint }) => {
78 buffer.revertToCheckpoint(checkpoint);
79 });
80 return false;
81 });
82 return { applied };
83 });
84 }
85 static handleResourceOperation(edit) {
86 var _a, _b, _c, _d, _e, _f, _g;
87 return __awaiter(this, void 0, void 0, function* () {
88 if (languageclient_1.DeleteFile.is(edit)) {
89 const path = convert_1.default.uriToPath(edit.uri);
90 const stats = yield fs_1.promises.lstat(path).catch(() => false);
91 const ignoreIfNotExists = (_a = edit.options) === null || _a === void 0 ? void 0 : _a.ignoreIfNotExists;
92 if (!stats) {
93 if (ignoreIfNotExists !== false) {
94 return;
95 }
96 throw Error(`Target doesn't exist.`);
97 }
98 if (stats.isDirectory()) {
99 if ((_b = edit.options) === null || _b === void 0 ? void 0 : _b.recursive) {
100 return new Promise((resolve, reject) => {
101 rimraf(path, { glob: false }, (err) => {
102 if (err) {
103 reject(err);
104 }
105 resolve();
106 });
107 });
108 }
109 return fs_1.promises.rmdir(path, { recursive: (_c = edit.options) === null || _c === void 0 ? void 0 : _c.recursive });
110 }
111 return fs_1.promises.unlink(path);
112 }
113 if (languageclient_1.RenameFile.is(edit)) {
114 const oldPath = convert_1.default.uriToPath(edit.oldUri);
115 const newPath = convert_1.default.uriToPath(edit.newUri);
116 const exists = yield fs_1.promises
117 .access(newPath)
118 .then(() => true)
119 .catch(() => false);
120 const ignoreIfExists = (_d = edit.options) === null || _d === void 0 ? void 0 : _d.ignoreIfExists;
121 const overwrite = (_e = edit.options) === null || _e === void 0 ? void 0 : _e.overwrite;
122 if (exists && ignoreIfExists && !overwrite) {
123 return;
124 }
125 if (exists && !ignoreIfExists && !overwrite) {
126 throw Error(`Target exists.`);
127 }
128 return fs_1.promises.rename(oldPath, newPath);
129 }
130 if (languageclient_1.CreateFile.is(edit)) {
131 const path = convert_1.default.uriToPath(edit.uri);
132 const exists = yield fs_1.promises
133 .access(path)
134 .then(() => true)
135 .catch(() => false);
136 const ignoreIfExists = (_f = edit.options) === null || _f === void 0 ? void 0 : _f.ignoreIfExists;
137 const overwrite = (_g = edit.options) === null || _g === void 0 ? void 0 : _g.overwrite;
138 if (exists && ignoreIfExists && !overwrite) {
139 return;
140 }
141 return fs_1.promises.writeFile(path, "");
142 }
143 });
144 }
145}
146exports.default = ApplyEditAdapter;
147function normalize(workspaceEdit) {
148 const documentChanges = workspaceEdit.documentChanges || [];
149 if (!("documentChanges" in workspaceEdit) && "changes" in workspaceEdit) {
150 Object.keys(workspaceEdit.changes || []).forEach((uri) => {
151 documentChanges.push({
152 textDocument: {
153 version: null,
154 uri,
155 },
156 edits: workspaceEdit.changes[uri],
157 });
158 });
159 }
160 workspaceEdit.documentChanges = documentChanges;
161}
162function validateEdit(buffer, edit, prevEdit) {
163 const path = buffer.getPath() || "";
164 if (prevEdit && edit.oldRange.end.compare(prevEdit.oldRange.start) > 0) {
165 throw Error(`Found overlapping edit ranges in ${path}`);
166 }
167 const startRow = edit.oldRange.start.row;
168 const startCol = edit.oldRange.start.column;
169 const lineLength = buffer.lineLengthForRow(startRow);
170 if (lineLength == null || startCol > lineLength) {
171 throw Error(`Out of range edit on ${path}:${startRow + 1}:${startCol + 1}`);
172 }
173}
174//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbHktZWRpdC1hZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL2FkYXB0ZXJzL2FwcGx5LWVkaXQtYWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUNBLHdDQUFnQztBQUNoQyxzREFVMEI7QUFFMUIsMkJBQTJDO0FBQzNDLGlDQUFnQztBQUVoQyw4REFBOEQ7QUFDOUQsTUFBcUIsZ0JBQWdCO0lBQ25DLDZFQUE2RTtJQUN0RSxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQW9DO1FBQ3ZELFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ2hFLENBQUM7SUFFRCxtSUFBbUk7SUFDNUgsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFrQixFQUFFLEtBQXlCO1FBQ3BFLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFBO1FBQzVDLElBQUk7WUFDRix5REFBeUQ7WUFDekQsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUE7WUFDckUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQWlDLEVBQUUsT0FBTyxFQUFFLEVBQUU7Z0JBQzFELFlBQVksQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFBO2dCQUN2QyxNQUFNLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO2dCQUN4RCxPQUFPLE9BQU8sQ0FBQTtZQUNoQixDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7WUFDUixNQUFNLENBQUMsMkJBQTJCLENBQUMsVUFB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RTtRQUN0RSxNQUFNLEtBQUssQ0FBQyxvQ0FBb0MsSUFBSSxFQUFFLENBQUMsQ0FBQTtLQUN4RDtJQUNELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQTtJQUN4QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUE7SUFDM0MsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQ3BELElBQUksVUFBVSxJQUFJLElBQUksSUFBSSxRQUFRLEdBQUcsVUFBVSxFQUFFO1FBQy9DLE1BQU0sS0FBSyxDQUFDLHdCQUF3QixJQUFJLElBQUksUUFBUSxHQUFHLENBQUMsSUFBSSxRQUFRLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQTtLQUM1RTtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSAqIGFzIGF0b21JZGUgZnJvbSBcImF0b20taWRlLWJhc2VcIlxuaW1wb3J0IENvbnZlcnQgZnJvbSBcIi4uL2NvbnZlcnRcIlxuaW1wb3J0IHtcbiAgTGFuZ3VhZ2VDbGllbnRDb25uZWN0aW9uLFxuICBBcHBseVdvcmtzcGFjZUVkaXRQYXJhbXMsXG4gIEFwcGx5V29ya3NwYWNlRWRpdFJlc3BvbnNlLFxuICBXb3Jrc3BhY2VFZGl0LFxuICBUZXh0RG9jdW1lbnRFZGl0LFxuICBDcmVhdGVGaWxlLFxuICBSZW5hbWVGaWxlLFxuICBEZWxldGVGaWxlLFxuICBEb2N1bWVudFVyaSxcbn0gZnJvbSBcIi4uL2xhbmd1YWdlY2xpZW50XCJcbmltcG9ydCB7IFRleHRCdWZmZXIsIFRleHRFZGl0b3IgfSBmcm9tIFwiYXRvbVwiXG5pbXBvcnQgeyBwcm9taXNlcyBhcyBmc3AsIFN0YXRzIH0gZnJvbSBcImZzXCJcbmltcG9ydCAqIGFzIHJpbXJhZiBmcm9tIFwicmltcmFmXCJcblxuLyoqIFB1YmxpYzogQWRhcHRzIHdvcmtzcGFjZS9hcHBseUVkaXQgY29tbWFuZHMgdG8gZWRpdG9ycy4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFwcGx5RWRpdEFkYXB0ZXIge1xuICAvKiogUHVibGljOiBBdHRhY2ggdG8gYSB7TGFuZ3VhZ2VDbGllbnRDb25uZWN0aW9ufSB0byByZWNlaXZlIGVkaXQgZXZlbnRzLiAqL1xuICBwdWJsaWMgc3RhdGljIGF0dGFjaChjb25uZWN0aW9uOiBMYW5ndWFnZUNsaWVudENvbm5lY3Rpb24pOiB2b2lkIHtcbiAgICBjb25uZWN0aW9uLm9uQXBwbHlFZGl0KChtKSA9PiBBcHBseUVkaXRBZGFwdGVyLm9uQXBwbHlFZGl0KG0pKVxuICB9XG5cbiAgLyoqIFRyaWVzIHRvIGFwcGx5IGVkaXRzIGFuZCByZXZlcnRzIGlmIGFueXRoaW5nIGdvZXMgd3JvbmcuIFJldHVybnMgdGhlIGNoZWNrcG9pbnQsIHNvIHRoZSBjYWxsZXIgY2FuIHJldmVydCBjaGFuZ2VzIGlmIG5lZWRlZC4gKi9cbiAgcHVibGljIHN0YXRpYyBhcHBseUVkaXRzKGJ1ZmZlcjogVGV4dEJ1ZmZlciwgZWRpdHM6IGF0b21JZGUuVGV4dEVkaXRbXSk6IG51bWJlciB7XG4gICAgY29uc3QgY2hlY2twb2ludCA9IGJ1ZmZlci5jcmVhdGVDaGVja3BvaW50KClcbiAgICB0cnkge1xuICAgICAgLy8gU29ydCBlZGl0cyBpbiByZXZlcnNlIG9yZGVyIHRvIHByZXZlbnQgZWRpdCBjb25mbGljdHMuXG4gICAgICBlZGl0cy5zb3J0KChlZGl0MSwgZWRpdDIpID0+IC1lZGl0MS5vbGRSYW5nZS5jb21wYXJlKGVkaXQyLm9sZFJhbmdlKSlcbiAgICAgIGVkaXRzLnJlZHVjZSgocHJldmlvdXM6IGF0b21JZGUuVGV4dEVkaXQgfCBudWxsLCBjdXJyZW50KSA9PiB7XG4gICAgICAgIHZhbGlkYXRlRWRpdChidWZmZXIsIGN1cnJlbnQsIHByZXZpb3VzKVxuICAgICAgICBidWZmZXIuc2V0VGV4dEluUmFuZ2UoY3VycmVudC5vbGRSYW5nZSwgY3VycmVudC5uZXdUZXh0KVxuICAgICAgICByZXR1cm4gY3VycmVudFxuICAgICAgfSwgbnVsbClcbiAgICAgIGJ1ZmZlci5ncm91cENoYW5nZXNTaW5jZUNoZWNrcG9pbnQoY2hlY2twb2ludClcbiAgICAgIHJldHVybiBjaGVja3BvaW50XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBidWZmZXIucmV2ZXJ0VG9DaGVja3BvaW50KGNoZWNrcG9pbnQpXG4gICAgICB0aHJvdyBlcnJcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGFzeW5jIG9uQXBwbHlFZGl0KHBhcmFtczogQXBwbHlXb3Jrc3BhY2VFZGl0UGFyYW1zKTogUHJvbWlzZTxBcHBseVdvcmtzcGFjZUVkaXRSZXNwb25zZT4ge1xuICAgIHJldHVybiBBcHBseUVkaXRBZGFwdGVyLmFwcGx5KHBhcmFtcy5lZGl0KVxuICB9XG5cbiAgcHVibGljIHN0YXRpYyBhc3luYyBhcHBseSh3b3Jrc3BhY2VFZGl0OiBXb3Jrc3BhY2VFZGl0KTogUHJvbWlzZTxBcHBseVdvcmtzcGFjZUVkaXRSZXNwb25zZT4ge1xuICAgIG5vcm1hbGl6ZSh3b3Jrc3BhY2VFZGl0KVxuXG4gICAgLy8gS2VlcCBjaGVja3BvaW50cyBmcm9tIGFsbCBzdWNjZXNzZnVsIGJ1ZmZlciBlZGl0c1xuICAgIGNvbnN0IGNoZWNrcG9pbnRzOiBBcnJheTx7IGJ1ZmZlcjogVGV4dEJ1ZmZlcjsgY2hlY2twb2ludDogbnVtYmVyIH0+ID0gW11cblxuICAgIGNvbnN0IHByb21pc2VzID0gKHdvcmtzcGFjZUVkaXQuZG9jdW1lbnRDaGFuZ2VzIHx8IFtdKS5tYXAoYXN5bmMgKGVkaXQpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgIGlmICghVGV4dERvY3VtZW50RWRpdC5pcyhlZGl0KSkge1xuICAgICAgICByZXR1cm4gQXBwbHlFZGl0QWRhcHRlci5oYW5kbGVSZXNvdXJjZU9wZXJhdGlvbihlZGl0KS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgdGhyb3cgRXJyb3IoYEVycm9yIGR1cmluZyAke2VkaXQua2luZH0gcmVzb3VyY2Ugb3BlcmF0aW9uOiAke2Vyci5tZXNzYWdlfWApXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgICBjb25zdCBwYXRoID0gQ29udmVydC51cmlUb1BhdGgoZWRpdC50ZXh0RG9jdW1lbnQudXJpKVxuICAgICAgY29uc3QgZWRpdG9yID0gKGF3YWl0IGF0b20ud29ya3NwYWNlLm9wZW4ocGF0aCwge1xuICAgICAgICBzZWFyY2hBbGxQYW5lczogdHJ1ZSxcbiAgICAgICAgLy8gT3BlbiBuZXcgZWRpdG9ycyBpbiB0aGUgYmFja2dyb3VuZC5cbiAgICAgICAgYWN0aXZhdGVQYW5lOiBmYWxzZSxcbiAgICAgICAgYWN0aXZhdGVJdGVtOiBmYWxzZSxcbiAgICAgIH0pKSBhcyBUZXh0RWRpdG9yXG4gICAgICBjb25zdCBidWZmZXIgPSBlZGl0b3IuZ2V0QnVmZmVyKClcbiAgICAgIGNvbnN0IGVkaXRzID0gQ29udmVydC5jb252ZXJ0THNUZXh0RWRpdHMoZWRpdC5lZGl0cylcbiAgICAgIGNvbnN0IGNoZWNrcG9pbnQgPSBBcHBseUVkaXRBZGFwdGVyLmFwcGx5RWRpdHMoYnVmZmVyLCBlZGl0cylcbiAgICAgIGNoZWNrcG9pbnRzLnB1c2goeyBidWZmZXIsIGNoZWNrcG9pbnQgfSlcbiAgICB9KVxuXG4gICAgLy8gQXBwbHkgYWxsIGVkaXRzIG9yIGZhaWwgYW5kIHJldmVydCBldmVyeXRoaW5nXG4gICAgY29uc3QgYXBwbGllZCA9IGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKVxuICAgICAgLnRoZW4oKCkgPT4gdHJ1ZSlcbiAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIGF0b20ubm90aWZpY2F0aW9ucy5hZGRFcnJvcihcIndvcmtzcGFjZS9hcHBseUVkaXRzIGZhaWxlZFwiLCB7XG4gICAgICAgICAgZGVzY3JpcHRpb246IFwiRmFpbGVkIHRvIGFwcGx5IGVkaXRzLlwiLFxuICAgICAgICAgIGRldGFpbDogZXJyLm1lc3NhZ2UsXG4gICAgICAgIH0pXG4gICAgICAgIGNoZWNrcG9pbnRzLmZvckVhY2goKHsgYnVmZmVyLCBjaGVja3BvaW50IH0pID0+IHtcbiAgICAgICAgICBidWZmZXIucmV2ZXJ0VG9DaGVja3BvaW50KGNoZWNrcG9pbnQpXG4gICAgICAgIH0pXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfSlcblxuICAgIHJldHVybiB7IGFwcGxpZWQgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgYXN5bmMgaGFuZGxlUmVzb3VyY2VPcGVyYXRpb24oZWRpdDogQ3JlYXRlRmlsZSB8IFJlbmFtZUZpbGUgfCBEZWxldGVGaWxlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKERlbGV0ZUZpbGUuaXMoZWRpdCkpIHtcbiAgICAgIGNvbnN0IHBhdGggPSBDb252ZXJ0LnVyaVRvUGF0aChlZGl0LnVyaSlcbiAgICAgIGNvbnN0IHN0YXRzOiBib29sZWFuIHwgU3RhdHMgPSBhd2FpdCBmc3AubHN0YXQocGF0aCkuY2F0Y2goKCkgPT4gZmFsc2UpXG4gICAgICBjb25zdCBpZ25vcmVJZk5vdEV4aXN0cyA9IGVkaXQub3B0aW9ucz8uaWdub3JlSWZOb3RFeGlzdHNcblxuICAgICAgaWYgKCFzdGF0cykge1xuICAgICAgICBpZiAoaWdub3JlSWZOb3RFeGlzdHMgIT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgRXJyb3IoYFRhcmdldCBkb2Vzbid0IGV4aXN0LmApXG4gICAgICB9XG5cbiAgICAgIGlmIChzdGF0cy5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIGlmIChlZGl0Lm9wdGlvbnM/LnJlY3Vyc2l2ZSkge1xuICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICByaW1yYWYocGF0aCwgeyBnbG9iOiBmYWxzZSB9LCAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlc29sdmUoKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmc3Aucm1kaXIocGF0aCwgeyByZWN1cnNpdmU6IGVkaXQub3B0aW9ucz8ucmVjdXJzaXZlIH0pXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmc3AudW5saW5rKHBhdGgpXG4gICAgfVxuICAgIGlmIChSZW5hbWVGaWxlLmlzKGVkaXQpKSB7XG4gICAgICBjb25zdCBvbGRQYXRoID0gQ29udmVydC51cmlUb1BhdGgoZWRpdC5vbGRVcmkpXG4gICAgICBjb25zdCBuZXdQYXRoID0gQ29udmVydC51cmlUb1BhdGgoZWRpdC5uZXdVcmkpXG4gICAgICBjb25zdCBleGlzdHMgPSBhd2FpdCBmc3BcbiAgICAgICAgLmFjY2VzcyhuZXdQYXRoKVxuICAgICAgICAudGhlbigoKSA9PiB0cnVlKVxuICAgICAgICAuY2F0Y2goKCkgPT4gZmFsc2UpXG4gICAgICBjb25zdCBpZ25vcmVJZkV4aXN0cyA9IGVkaXQub3B0aW9ucz8uaWdub3JlSWZFeGlzdHNcbiAgICAgIGNvbnN0IG92ZXJ3cml0ZSA9IGVkaXQub3B0aW9ucz8ub3ZlcndyaXRlXG5cbiAgICAgIGlmIChleGlzdHMgJiYgaWdub3JlSWZFeGlzdHMgJiYgIW92ZXJ3cml0ZSkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgaWYgKGV4aXN0cyAmJiAhaWdub3JlSWZFeGlzdHMgJiYgIW92ZXJ3cml0ZSkge1xuICAgICAgICB0aHJvdyBFcnJvcihgVGFyZ2V0IGV4aXN0cy5gKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gZnNwLnJlbmFtZShvbGRQYXRoLCBuZXdQYXRoKVxuICAgIH1cbiAgICBpZiAoQ3JlYXRlRmlsZS5pcyhlZGl0KSkge1xuICAgICAgY29uc3QgcGF0aCA9IENvbnZlcnQudXJpVG9QYXRoKGVkaXQudXJpKVxuICAgICAgY29uc3QgZXhpc3RzID0gYXdhaXQgZnNwXG4gICAgICAgIC5hY2Nlc3MocGF0aClcbiAgICAgICAgLnRoZW4oKCkgPT4gdHJ1ZSlcbiAgICAgICAgLmNhdGNoKCgpID0+IGZhbHNlKVxuICAgICAgY29uc3QgaWdub3JlSWZFeGlzdHMgPSBlZGl0Lm9wdGlvbnM/Lmlnbm9yZUlmRXhpc3RzXG4gICAgICBjb25zdCBvdmVyd3JpdGUgPSBlZGl0Lm9wdGlvbnM/Lm92ZXJ3cml0ZVxuXG4gICAgICBpZiAoZXhpc3RzICYmIGlnbm9yZUlmRXhpc3RzICYmICFvdmVyd3JpdGUpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmc3Aud3JpdGVGaWxlKHBhdGgsIFwiXCIpXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZSh3b3Jrc3BhY2VFZGl0OiBXb3Jrc3BhY2VFZGl0KTogdm9pZCB7XG4gIGNvbnN0IGRvY3VtZW50Q2hhbmdlcyA9IHdvcmtzcGFjZUVkaXQuZG9jdW1lbnRDaGFuZ2VzIHx8IFtdXG5cbiAgaWYgKCEoXCJkb2N1bWVudENoYW5nZXNcIiBpbiB3b3Jrc3BhY2VFZGl0KSAmJiBcImNoYW5nZXNcIiBpbiB3b3Jrc3BhY2VFZGl0KSB7XG4gICAgT2JqZWN0LmtleXMod29ya3NwYWNlRWRpdC5jaGFuZ2VzIHx8IFtdKS5mb3JFYWNoKCh1cmk6IERvY3VtZW50VXJpKSA9PiB7XG4gICAgICBkb2N1bWVudENoYW5nZXMucHVzaCh7XG4gICAgICAgIHRleHREb2N1bWVudDoge1xuICAgICAgICAgIHZlcnNpb246IG51bGwsXG4gICAgICAgICAgdXJpLFxuICAgICAgICB9LFxuICAgICAgICBlZGl0czogd29ya3NwYWNlRWRpdC5jaGFuZ2VzIVt1cmldLFxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgd29ya3NwYWNlRWRpdC5kb2N1bWVudENoYW5nZXMgPSBkb2N1bWVudENoYW5nZXNcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVFZGl0KGJ1ZmZlcjogVGV4dEJ1ZmZlciwgZWRpdDogYXRvbUlkZS5UZXh0RWRpdCwgcHJldkVkaXQ6IGF0b21JZGUuVGV4dEVkaXQgfCBudWxsKTogdm9pZCB7XG4gIGNvbnN0IHBhdGggPSBidWZmZXIuZ2V0UGF0aCgpIHx8IFwiXCJcbiAgaWYgKHByZXZFZGl0ICYmIGVkaXQub2xkUmFuZ2UuZW5kLmNvbXBhcmUocHJldkVkaXQub2xkUmFuZ2Uuc3RhcnQpID4gMCkge1xuICAgIHRocm93IEVycm9yKGBGb3VuZCBvdmVybGFwcGluZyBlZGl0IHJhbmdlcyBpbiAke3BhdGh9YClcbiAgfVxuICBjb25zdCBzdGFydFJvdyA9IGVkaXQub2xkUmFuZ2Uuc3RhcnQucm93XG4gIGNvbnN0IHN0YXJ0Q29sID0gZWRpdC5vbGRSYW5nZS5zdGFydC5jb2x1bW5cbiAgY29uc3QgbGluZUxlbmd0aCA9IGJ1ZmZlci5saW5lTGVuZ3RoRm9yUm93KHN0YXJ0Um93KVxuICBpZiAobGluZUxlbmd0aCA9PSBudWxsIHx8IHN0YXJ0Q29sID4gbGluZUxlbmd0aCkge1xuICAgIHRocm93IEVycm9yKGBPdXQgb2YgcmFuZ2UgZWRpdCBvbiAke3BhdGh9OiR7c3RhcnRSb3cgKyAxfToke3N0YXJ0Q29sICsgMX1gKVxuICB9XG59XG4iXX0=
\No newline at end of file