sliftutils 1.7.10 → 1.7.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/examplestorage/exampleserver.ts +0 -2
- package/index.d.ts +290 -54
- package/misc/dist/environment.ts.cache +3 -3
- package/misc/dist/getSecret.ts.cache +139 -0
- package/misc/dist/strings.ts.cache +13 -0
- package/misc/dist/zip.ts.cache +9 -0
- package/misc/getSecret.ts +38 -16
- package/misc/https/cloudflareHelpers.d.ts +19 -0
- package/misc/https/cloudflareHelpers.ts +69 -0
- package/misc/https/dist/certs.ts.cache +115 -179
- package/misc/https/dist/cloudflareHelpers.ts.cache +68 -0
- package/misc/https/dist/dns.ts.cache +112 -100
- package/misc/https/dist/hostServer.ts.cache +130 -0
- package/misc/https/dist/httpsCerts.ts.cache +24 -5
- package/misc/https/dist/persistentLocalStorage.ts.cache +3 -2
- package/misc/https/dns.d.ts +41 -12
- package/misc/https/dns.ts +104 -101
- package/misc/https/hostServer.d.ts +0 -6
- package/misc/https/hostServer.ts +9 -5
- package/package.json +2 -2
- package/render-utils/dist/observer.tsx.cache +3 -2
- package/spec.txt +0 -90
- package/storage/ArchivesDisk.d.ts +2 -0
- package/storage/ArchivesDisk.ts +7 -3
- package/storage/BulkDatabase2/dist/BulkDatabaseBase.ts.cache +1242 -0
- package/storage/BulkDatabase2/dist/BulkDatabaseFormat.ts.cache +513 -0
- package/storage/BulkDatabase2/dist/BulkDatabaseMerge.ts.cache +352 -0
- package/storage/BulkDatabase2/dist/BulkDatabaseReader.ts.cache +306 -0
- package/storage/BulkDatabase2/dist/LoadedIndex.ts.cache +435 -0
- package/storage/BulkDatabase2/dist/WriteOverlay.ts.cache +58 -0
- package/storage/BulkDatabase2/dist/blockCache.ts.cache +179 -0
- package/storage/BulkDatabase2/dist/mergeLock.ts.cache +149 -0
- package/storage/BulkDatabase2/dist/mergeMarkers.ts.cache +101 -0
- package/storage/BulkDatabase2/dist/streamLog.ts.cache +227 -0
- package/storage/BulkDatabase2/dist/syncClient.ts.cache +104 -0
- package/storage/IArchives.d.ts +47 -15
- package/storage/IArchives.ts +86 -31
- package/storage/backblaze.d.ts +15 -0
- package/storage/backblaze.ts +199 -79
- package/storage/dist/ArchivesDisk.ts.cache +373 -0
- package/storage/dist/FileFolderAPI.tsx.cache +508 -65
- package/storage/dist/IArchives.ts.cache +44 -0
- package/storage/dist/IndexedDBFileFolderAPI.ts.cache +8 -2
- package/storage/dist/JSONStorage.ts.cache +6 -2
- package/storage/dist/PendingManager.tsx.cache +1 -1
- package/storage/dist/TransactionStorage.ts.cache +231 -92
- package/storage/dist/backblaze.ts.cache +797 -0
- package/storage/dist/fileSystemPointer.ts.cache +36 -3
- package/storage/dist/remoteFileStorage.ts.cache +495 -0
- package/storage/remoteStorage/ArchivesRemote.d.ts +5 -1
- package/storage/remoteStorage/ArchivesRemote.ts +28 -8
- package/storage/remoteStorage/ArchivesUrl.d.ts +2 -0
- package/storage/remoteStorage/ArchivesUrl.ts +16 -4
- package/storage/remoteStorage/blobStore.d.ts +52 -3
- package/storage/remoteStorage/blobStore.ts +414 -101
- package/storage/remoteStorage/createArchives.d.ts +31 -10
- package/storage/remoteStorage/createArchives.ts +470 -253
- package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +197 -0
- package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +85 -0
- package/storage/remoteStorage/dist/accessPage.tsx.cache +222 -0
- package/storage/remoteStorage/dist/blobStore.ts.cache +837 -0
- package/storage/remoteStorage/dist/cliArgs.ts.cache +16 -0
- package/storage/remoteStorage/dist/createArchives.ts.cache +610 -0
- package/storage/remoteStorage/dist/remoteConfig.ts.cache +206 -0
- package/storage/remoteStorage/dist/sourceWrapper.ts.cache +223 -0
- package/storage/remoteStorage/dist/storageController.ts.cache +500 -0
- package/storage/remoteStorage/dist/storageServer.ts.cache +106 -0
- package/storage/remoteStorage/dist/storageServerCli.ts.cache +39 -0
- package/storage/remoteStorage/dist/storageServerState.ts.cache +518 -0
- package/storage/remoteStorage/remoteConfig.d.ts +8 -0
- package/storage/remoteStorage/remoteConfig.ts +105 -5
- package/storage/remoteStorage/sourceWrapper.d.ts +41 -0
- package/storage/remoteStorage/sourceWrapper.ts +223 -0
- package/storage/remoteStorage/spec.md +31 -0
- package/storage/remoteStorage/storageController.d.ts +11 -0
- package/storage/remoteStorage/storageController.ts +109 -40
- package/storage/remoteStorage/storageServer.d.ts +0 -5
- package/storage/remoteStorage/storageServer.ts +17 -10
- package/storage/remoteStorage/storageServerCli.ts +0 -3
- package/storage/remoteStorage/storageServerState.d.ts +7 -1
- package/storage/remoteStorage/storageServerState.ts +230 -48
- package/testsite/server.ts +0 -2
- package/yarn.lock +11 -6
|
@@ -9,31 +9,89 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
9
9
|
return (mod && mod.__esModule && mod.default) ? mod : { "default": mod };
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
|
|
12
|
-
//exports.resetStorageLocation = exports.getFileStorage = exports.getFileStorageNested = exports.getDirectoryHandle = void 0;
|
|
12
|
+
//exports.tryToLoadPointer = exports.getRemoteFileStorageFactory = exports.disposeFileURL = exports.getFileURL = exports.wrapHandle = exports.resetStorageLocation = exports.getFileStorage = exports.getFileStorageNested2 = exports.getFileStorageNested = exports.getDirectoryHandle = exports.pickPrivateFolder = exports.listPrivateFolders = exports.isPrivateFileSystemActive = exports.usePrivateFileSystem = exports.NodeJSDirectoryHandleWrapper = exports.NodeJSFileHandleWrapper = exports.setStorageRootOverride = exports.setFileAPIKey = void 0;
|
|
13
13
|
const preact_1 = __importDefault(require("preact"));
|
|
14
14
|
const fileSystemPointer_1 = require("./fileSystemPointer");
|
|
15
|
-
const
|
|
16
|
-
const observer_1 = require("../
|
|
15
|
+
const mobx_1 = require("mobx");
|
|
16
|
+
const observer_1 = require("../render-utils/observer");
|
|
17
17
|
const caching_1 = require("socket-function/src/caching");
|
|
18
18
|
const typesafecss_1 = require("typesafecss");
|
|
19
19
|
const batching_1 = require("socket-function/src/batching");
|
|
20
20
|
const IndexedDBFileFolderAPI_1 = require("./IndexedDBFileFolderAPI");
|
|
21
|
+
const remoteFileStorage_1 = require("./remoteFileStorage");
|
|
21
22
|
const fs_1 = __importDefault(require("fs"));
|
|
22
23
|
const path_1 = __importDefault(require("path"));
|
|
23
24
|
// NOTE: IndexedDB is required for iOS, at least. We MIGHT want to make
|
|
24
25
|
// this a user supported toggle too, so they can choose during runtime if they want it.
|
|
25
26
|
// DO NOT enable this is isNode
|
|
26
27
|
const USE_INDEXED_DB = false;
|
|
27
|
-
|
|
28
|
+
// How often a worker rechecks the pointer IndexedDB for a granted handle when none is available yet.
|
|
29
|
+
const WORKER_POLL_INTERVAL_MS = 60 * 1000;
|
|
30
|
+
let displayData = (0, mobx_1.observable)({
|
|
28
31
|
ui: undefined,
|
|
29
32
|
}, undefined, { deep: false });
|
|
30
|
-
|
|
33
|
+
let fileAPIKey = "";
|
|
34
|
+
function getFileAPIKey() {
|
|
35
|
+
if (!fileAPIKey)
|
|
36
|
+
throw new Error("Must call setFileAPIKey before using file system. Just pass any key. This prevents reusing the file system api that other development apps might be using.");
|
|
37
|
+
return fileAPIKey;
|
|
38
|
+
}
|
|
39
|
+
function setFileAPIKey(key) {
|
|
40
|
+
fileAPIKey = key;
|
|
41
|
+
}
|
|
42
|
+
exports.setFileAPIKey = setFileAPIKey;
|
|
43
|
+
// A directory handle to serve as the storage root instead of resolving one via
|
|
44
|
+
// the picker / stored-pointer / remote flow. Set this in a context that can't run
|
|
45
|
+
// the interactive resolution — most importantly a Web Worker, which has no DOM to
|
|
46
|
+
// prompt with and no localStorage pointer. The owning window resolves the handle
|
|
47
|
+
// (with its permission grant) and postMessages it in; the worker calls this before
|
|
48
|
+
// touching any storage. When set, getDirectoryHandle returns it directly and skips
|
|
49
|
+
// every DOM / localStorage branch below.
|
|
50
|
+
let storageRootOverride;
|
|
51
|
+
function setStorageRootOverride(handle) {
|
|
52
|
+
storageRootOverride = handle;
|
|
53
|
+
}
|
|
54
|
+
exports.setStorageRootOverride = setStorageRootOverride;
|
|
55
|
+
function remoteConfigKey() { return getFileAPIKey() + ":remote"; }
|
|
56
|
+
function loadRemoteConfig() {
|
|
57
|
+
try {
|
|
58
|
+
const s = localStorage.getItem(remoteConfigKey());
|
|
59
|
+
if (!s)
|
|
60
|
+
return undefined;
|
|
61
|
+
const c = JSON.parse(s);
|
|
62
|
+
if (c && typeof c.url === "string" && typeof c.password === "string")
|
|
63
|
+
return c;
|
|
64
|
+
}
|
|
65
|
+
catch ( /* ignore */_a) { /* ignore */ }
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
function saveRemoteConfig(c) { localStorage.setItem(remoteConfigKey(), JSON.stringify(c)); }
|
|
69
|
+
// The server is always HTTPS on the filehoster's default port, so the user only needs to type the host
|
|
70
|
+
// (e.g. "65.109.93.113"). We strip any scheme/path they include and default the port if omitted.
|
|
71
|
+
const DEFAULT_REMOTE_PORT = 8787; // matches remoteFileServer.js's default
|
|
72
|
+
function normalizeServerUrl(raw) {
|
|
73
|
+
let s = raw.trim().replace(/^\w+:\/\//, "").replace(/\/.*$/, "");
|
|
74
|
+
if (!s)
|
|
75
|
+
return "";
|
|
76
|
+
if (!/:\d+$/.test(s))
|
|
77
|
+
s += ":" + DEFAULT_REMOTE_PORT;
|
|
78
|
+
return "https://" + s;
|
|
79
|
+
}
|
|
80
|
+
// One shared remote DirectoryWrapper (and therefore one shared range cache) per remote config.
|
|
81
|
+
let remoteHandle;
|
|
82
|
+
function getRemoteHandle(remote) {
|
|
83
|
+
const key = remote.url + "\0" + remote.password;
|
|
84
|
+
if (!remoteHandle || remoteHandle.key !== key) {
|
|
85
|
+
remoteHandle = { key, handle: (0, remoteFileStorage_1.getRemoteDirectoryHandle)(remote.url, remote.password) };
|
|
86
|
+
}
|
|
87
|
+
return remoteHandle.handle;
|
|
88
|
+
}
|
|
31
89
|
let DirectoryPrompter = class DirectoryPrompter extends preact_1.default.Component {
|
|
32
90
|
render() {
|
|
33
91
|
if (!displayData.ui)
|
|
34
92
|
return undefined;
|
|
35
93
|
return (preact_1.default.createElement("div", { className: typesafecss_1.css.position("fixed").pos(0, 0).size("100vw", "100vh")
|
|
36
|
-
.zIndex(
|
|
94
|
+
.zIndex(2147483647)
|
|
37
95
|
.background("white")
|
|
38
96
|
.center
|
|
39
97
|
.fontSize(40) }, displayData.ui));
|
|
@@ -42,21 +100,124 @@ let DirectoryPrompter = class DirectoryPrompter extends preact_1.default.Compone
|
|
|
42
100
|
DirectoryPrompter = __decorate([
|
|
43
101
|
observer_1.observer
|
|
44
102
|
], DirectoryPrompter);
|
|
103
|
+
// "Connect to a server" option for the directory prompt: collapses to a button, expands to address +
|
|
104
|
+
// password fields. On connect it ACTUALLY connects (testRemoteConnection); only on success does it
|
|
105
|
+
// persist the config and call onConnected, so the caller (getDirectoryHandle) resolves with a working
|
|
106
|
+
// remote handle. Failures are shown to the user (and logged, without the password), never swallowed.
|
|
107
|
+
// `initial` pre-fills + expands the form (used to retry a remembered server that stopped working).
|
|
108
|
+
let ServerConnectForm = class ServerConnectForm extends preact_1.default.Component {
|
|
109
|
+
constructor() {
|
|
110
|
+
var _a, _b;
|
|
111
|
+
super(...arguments);
|
|
112
|
+
this.obs = (0, mobx_1.observable)({
|
|
113
|
+
expanded: !!this.props.initial,
|
|
114
|
+
url: ((_a = this.props.initial) === null || _a === void 0 ? void 0 : _a.url) || "",
|
|
115
|
+
password: ((_b = this.props.initial) === null || _b === void 0 ? void 0 : _b.password) || "",
|
|
116
|
+
error: "", connecting: false, needsCert: false, showPassword: false,
|
|
117
|
+
});
|
|
118
|
+
this.connect = async () => {
|
|
119
|
+
const s = this.obs;
|
|
120
|
+
s.error = "";
|
|
121
|
+
s.needsCert = false;
|
|
122
|
+
s.connecting = true;
|
|
123
|
+
try {
|
|
124
|
+
const url = this.cleanUrl();
|
|
125
|
+
if (!url) {
|
|
126
|
+
s.error = "Enter a server address.";
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const result = await (0, remoteFileStorage_1.testRemoteConnection)(url, s.password.trim());
|
|
130
|
+
if (result.status === "ok") {
|
|
131
|
+
const config = { url, password: s.password.trim() };
|
|
132
|
+
saveRemoteConfig(config); // remember for next session
|
|
133
|
+
this.props.onConnected(config); // hand the verified server back to getDirectoryHandle
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (result.status === "unauthorized") {
|
|
137
|
+
s.error = "The server rejected that password.";
|
|
138
|
+
console.error("Remote connect: unauthorized for", url);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
// Got nothing back — usually the self-signed certificate isn't trusted yet, but show the
|
|
142
|
+
// actual error too so a wrong address / down server / CORS issue is diagnosable.
|
|
143
|
+
s.needsCert = true;
|
|
144
|
+
s.error = "Couldn't reach the server: " + result.error;
|
|
145
|
+
console.error("Remote connect: unreachable", url, "-", result.error);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
s.error = "Connection error: " + (e.message || String(e));
|
|
150
|
+
console.error("Remote connect threw:", e);
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
s.connecting = false;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
cleanUrl() { return normalizeServerUrl(this.obs.url); }
|
|
158
|
+
render() {
|
|
159
|
+
const s = this.obs;
|
|
160
|
+
const inputCss = typesafecss_1.css.fontSize(28).pad2(24, 14).width(560).maxWidth("80vw");
|
|
161
|
+
const btnCss = typesafecss_1.css.fontSize(32).pad2(60, 30);
|
|
162
|
+
if (!s.expanded) {
|
|
163
|
+
return preact_1.default.createElement("button", { className: btnCss, onClick: () => s.expanded = true }, "Connect to a server");
|
|
164
|
+
}
|
|
165
|
+
return (preact_1.default.createElement("div", { className: typesafecss_1.css.vbox(16).center },
|
|
166
|
+
preact_1.default.createElement("input", { className: inputCss, placeholder: "server address (e.g. 65.109.93.113, or host:port)", value: s.url, onInput: e => s.url = e.target.value }),
|
|
167
|
+
preact_1.default.createElement("div", { className: typesafecss_1.css.hbox(10).center },
|
|
168
|
+
preact_1.default.createElement("input", { className: inputCss, type: s.showPassword ? "text" : "password", placeholder: "password (six words)", value: s.password, onInput: e => s.password = e.target.value }),
|
|
169
|
+
preact_1.default.createElement("button", { className: typesafecss_1.css.fontSize(22).pad2(24, 12), onClick: () => s.showPassword = !s.showPassword }, s.showPassword ? "Hide" : "Show")),
|
|
170
|
+
s.error ? preact_1.default.createElement("div", { className: typesafecss_1.css.fontSize(22).color("red").maxWidth("80vw") }, s.error) : null,
|
|
171
|
+
s.needsCert ? (preact_1.default.createElement("div", { className: typesafecss_1.css.vbox(10).center.fontSize(20).maxWidth(620).maxWidth("80vw").textAlign("center").color("hsl(0, 0%, 25%)") },
|
|
172
|
+
preact_1.default.createElement("div", null, "This server uses a self-signed certificate, so your browser has to trust it once:"),
|
|
173
|
+
preact_1.default.createElement("div", null, "1. Open the server in a new tab (button below). \u00A0 2. Accept the security warning (Advanced \u2192 Proceed). \u00A0 3. Come back and click Retry."),
|
|
174
|
+
preact_1.default.createElement("button", { className: typesafecss_1.css.fontSize(26).pad2(40, 20), onClick: () => { const u = this.cleanUrl(); if (u)
|
|
175
|
+
window.open(u + "/", "_blank"); } }, "Open server & accept certificate"))) : null,
|
|
176
|
+
preact_1.default.createElement("div", { className: typesafecss_1.css.hbox(16) },
|
|
177
|
+
preact_1.default.createElement("button", { className: btnCss, disabled: s.connecting, onClick: this.connect }, s.connecting ? "Connecting…" : s.needsCert ? "Retry" : "Connect"),
|
|
178
|
+
preact_1.default.createElement("button", { className: btnCss, onClick: () => { s.expanded = false; s.error = ""; s.needsCert = false; } }, "Back"))));
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
ServerConnectForm = __decorate([
|
|
182
|
+
observer_1.observer
|
|
183
|
+
], ServerConnectForm);
|
|
45
184
|
class NodeJSFileHandleWrapper {
|
|
46
185
|
constructor(filePath) {
|
|
47
186
|
this.filePath = filePath;
|
|
187
|
+
this.kind = "file";
|
|
48
188
|
}
|
|
189
|
+
get name() { return path_1.default.basename(this.filePath); }
|
|
49
190
|
async getFile() {
|
|
50
191
|
const stats = await fs_1.default.promises.stat(this.filePath);
|
|
192
|
+
const filePath = this.filePath;
|
|
51
193
|
return {
|
|
52
194
|
size: stats.size,
|
|
53
195
|
lastModified: stats.mtimeMs,
|
|
54
196
|
arrayBuffer: async () => {
|
|
55
|
-
const buffer = await fs_1.default.promises.readFile(
|
|
197
|
+
const buffer = await fs_1.default.promises.readFile(filePath);
|
|
56
198
|
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
57
|
-
}
|
|
199
|
+
},
|
|
200
|
+
slice: (start, end) => ({
|
|
201
|
+
arrayBuffer: async () => {
|
|
202
|
+
const clampedStart = Math.min(Math.max(start, 0), stats.size);
|
|
203
|
+
const clampedEnd = Math.min(Math.max(end, clampedStart), stats.size);
|
|
204
|
+
const length = clampedEnd - clampedStart;
|
|
205
|
+
const fileHandle = await fs_1.default.promises.open(filePath, "r");
|
|
206
|
+
try {
|
|
207
|
+
const buffer = Buffer.alloc(length);
|
|
208
|
+
await fileHandle.read(buffer, 0, length, clampedStart);
|
|
209
|
+
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
210
|
+
}
|
|
211
|
+
finally {
|
|
212
|
+
await fileHandle.close();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
})
|
|
58
216
|
};
|
|
59
217
|
}
|
|
218
|
+
async getURL() {
|
|
219
|
+
return "file://" + path_1.default.resolve(this.filePath);
|
|
220
|
+
}
|
|
60
221
|
async createWritable(config) {
|
|
61
222
|
let fileHandle;
|
|
62
223
|
const flags = (config === null || config === void 0 ? void 0 : config.keepExistingData) ? "r+" : "w";
|
|
@@ -84,10 +245,15 @@ class NodeJSFileHandleWrapper {
|
|
|
84
245
|
};
|
|
85
246
|
}
|
|
86
247
|
}
|
|
248
|
+
exports.NodeJSFileHandleWrapper = NodeJSFileHandleWrapper;
|
|
87
249
|
class NodeJSDirectoryHandleWrapper {
|
|
88
250
|
constructor(rootPath) {
|
|
89
251
|
this.rootPath = rootPath;
|
|
252
|
+
this.kind = "directory";
|
|
90
253
|
}
|
|
254
|
+
get name() { return path_1.default.basename(this.rootPath); }
|
|
255
|
+
get fullPath() { return this.rootPath; }
|
|
256
|
+
entries() { return this[Symbol.asyncIterator](); }
|
|
91
257
|
async removeEntry(key, options) {
|
|
92
258
|
const entryPath = path_1.default.join(this.rootPath, key);
|
|
93
259
|
if (options === null || options === void 0 ? void 0 : options.recursive) {
|
|
@@ -107,7 +273,12 @@ class NodeJSDirectoryHandleWrapper {
|
|
|
107
273
|
await fs_1.default.promises.writeFile(filePath, Buffer.alloc(0));
|
|
108
274
|
}
|
|
109
275
|
else if (!exists) {
|
|
110
|
-
|
|
276
|
+
// Tag as ENOENT so readWithRetry treats it as a genuinely-missing file (return undefined now)
|
|
277
|
+
// rather than a transient read failure to retry 6× with backoff — missing files are normal
|
|
278
|
+
// (a concurrent merge deletes a file mid-read), and retrying them is catastrophically slow.
|
|
279
|
+
const err = new Error(`File not found: ${filePath}`);
|
|
280
|
+
err.code = "ENOENT";
|
|
281
|
+
throw err;
|
|
111
282
|
}
|
|
112
283
|
return new NodeJSFileHandleWrapper(filePath);
|
|
113
284
|
}
|
|
@@ -129,66 +300,194 @@ class NodeJSDirectoryHandleWrapper {
|
|
|
129
300
|
await fs_1.default.promises.mkdir(this.rootPath, { recursive: true });
|
|
130
301
|
const entries = await fs_1.default.promises.readdir(this.rootPath, { withFileTypes: true });
|
|
131
302
|
for (const entry of entries) {
|
|
303
|
+
const childPath = path_1.default.join(this.rootPath, entry.name);
|
|
132
304
|
if (entry.isFile()) {
|
|
133
|
-
yield [entry.name,
|
|
134
|
-
kind: "file",
|
|
135
|
-
name: entry.name,
|
|
136
|
-
getFile: async () => new NodeJSFileHandleWrapper(path_1.default.join(this.rootPath, entry.name))
|
|
137
|
-
}];
|
|
305
|
+
yield [entry.name, new NodeJSFileHandleWrapper(childPath)];
|
|
138
306
|
}
|
|
139
307
|
else if (entry.isDirectory()) {
|
|
140
|
-
|
|
141
|
-
yield [entry.name, {
|
|
142
|
-
kind: "directory",
|
|
143
|
-
name: entry.name,
|
|
144
|
-
getDirectoryHandle: async (key, options) => {
|
|
145
|
-
return new NodeJSDirectoryHandleWrapper(dirPath).getDirectoryHandle(key, options);
|
|
146
|
-
}
|
|
147
|
-
}];
|
|
308
|
+
yield [entry.name, new NodeJSDirectoryHandleWrapper(childPath)];
|
|
148
309
|
}
|
|
149
310
|
}
|
|
150
311
|
}
|
|
151
312
|
}
|
|
152
|
-
|
|
313
|
+
exports.NodeJSDirectoryHandleWrapper = NodeJSDirectoryHandleWrapper;
|
|
314
|
+
// When set, getDirectoryHandle skips every prompt + remote check and serves from the browser's Origin
|
|
315
|
+
// Private File System (OPFS). One named subfolder is "current" per fileAPIKey; pickPrivateFolder /
|
|
316
|
+
// resetStorageLocation switch which one. Set this in app startup BEFORE the first getDirectoryHandle.
|
|
317
|
+
let opfsEnabled = false;
|
|
318
|
+
const OPFS_FOLDERS_DIR = "folders";
|
|
319
|
+
const OPFS_DEFAULT_FOLDER = "default";
|
|
320
|
+
function opfsCurrentKey() { return getFileAPIKey() + ":opfs:current"; }
|
|
321
|
+
function getCurrentOpfsFolder() {
|
|
322
|
+
return localStorage.getItem(opfsCurrentKey()) || OPFS_DEFAULT_FOLDER;
|
|
323
|
+
}
|
|
324
|
+
function setCurrentOpfsFolder(name) {
|
|
325
|
+
localStorage.setItem(opfsCurrentKey(), name);
|
|
326
|
+
}
|
|
327
|
+
// Switches getDirectoryHandle to the Origin Private File System. No directory picker, no permission
|
|
328
|
+
// prompt, no remote server check. Persists nothing — call on every app start before reading storage.
|
|
329
|
+
function usePrivateFileSystem() {
|
|
330
|
+
opfsEnabled = true;
|
|
331
|
+
}
|
|
332
|
+
exports.usePrivateFileSystem = usePrivateFileSystem;
|
|
333
|
+
// Whether the OPFS branch is in effect (so other callers can adapt — e.g. skip the "find data subdir"
|
|
334
|
+
// hack in getFileStorageNested2 since OPFS is always a clean root we own end-to-end).
|
|
335
|
+
function isPrivateFileSystemActive() {
|
|
336
|
+
return opfsEnabled;
|
|
337
|
+
}
|
|
338
|
+
exports.isPrivateFileSystemActive = isPrivateFileSystemActive;
|
|
339
|
+
async function getOpfsFoldersDir() {
|
|
340
|
+
var _a;
|
|
341
|
+
if (!((_a = navigator.storage) === null || _a === void 0 ? void 0 : _a.getDirectory)) {
|
|
342
|
+
throw new Error("Private File System Access API not supported in this browser");
|
|
343
|
+
}
|
|
344
|
+
if (location.protocol === "file:") {
|
|
345
|
+
throw new Error("Private File System API is disallowed in file:// locations. Host on an actual origin.");
|
|
346
|
+
}
|
|
347
|
+
const root = await navigator.storage.getDirectory();
|
|
348
|
+
const keyed = await root.getDirectoryHandle(getFileAPIKey(), { create: true });
|
|
349
|
+
return await keyed.getDirectoryHandle(OPFS_FOLDERS_DIR, { create: true });
|
|
350
|
+
}
|
|
351
|
+
async function getCurrentOpfsHandle() {
|
|
352
|
+
const folders = await getOpfsFoldersDir();
|
|
353
|
+
const folder = await folders.getDirectoryHandle(getCurrentOpfsFolder(), { create: true });
|
|
354
|
+
return folder;
|
|
355
|
+
}
|
|
356
|
+
// All previously-used OPFS subfolders under this fileAPIKey, sorted alphabetically (timestamp-named
|
|
357
|
+
// auto-generated folders therefore sort chronologically). Use this to surface a list, then call
|
|
358
|
+
// pickPrivateFolder(name) to switch.
|
|
359
|
+
async function listPrivateFolders() {
|
|
360
|
+
var _a;
|
|
361
|
+
if (!((_a = navigator.storage) === null || _a === void 0 ? void 0 : _a.getDirectory))
|
|
362
|
+
return [];
|
|
363
|
+
let folders;
|
|
364
|
+
try {
|
|
365
|
+
folders = await getOpfsFoldersDir();
|
|
366
|
+
}
|
|
367
|
+
catch (_b) {
|
|
368
|
+
return [];
|
|
369
|
+
}
|
|
370
|
+
const names = [];
|
|
371
|
+
for await (const [name, handle] of folders) {
|
|
372
|
+
if (handle.kind === "directory")
|
|
373
|
+
names.push(name);
|
|
374
|
+
}
|
|
375
|
+
return names.sort();
|
|
376
|
+
}
|
|
377
|
+
exports.listPrivateFolders = listPrivateFolders;
|
|
378
|
+
// Switch to a specific OPFS subfolder and reload so getDirectoryHandle re-resolves to it. The folder
|
|
379
|
+
// is created if it doesn't exist yet.
|
|
380
|
+
function pickPrivateFolder(name) {
|
|
381
|
+
setCurrentOpfsFolder(name);
|
|
382
|
+
window.location.reload();
|
|
383
|
+
}
|
|
384
|
+
exports.pickPrivateFolder = pickPrivateFolder;
|
|
385
|
+
// Returns the directory handle to use — local (Node / picked folder) OR a remote server, both as the
|
|
386
|
+
// same DirectoryWrapper, so callers don't know or care which it is. A remembered server is VERIFIED
|
|
387
|
+
// (we actually connect) before use; if it no longer works we re-prompt, just like a local folder whose
|
|
388
|
+
// permission was lost. Blocks until ready (or the user dismisses, which rejects).
|
|
153
389
|
exports.getDirectoryHandle = (0, caching_1.lazy)(async function getDirectoryHandle() {
|
|
390
|
+
// An injected root (e.g. a Web Worker handed the handle by its owning window)
|
|
391
|
+
// short-circuits the whole interactive resolution — no picker, no DOM, no
|
|
392
|
+
// localStorage. Must come first so a worker never reaches the branches below.
|
|
393
|
+
if (storageRootOverride) {
|
|
394
|
+
return storageRootOverride;
|
|
395
|
+
}
|
|
396
|
+
// A worker can't show the picker (no DOM / no user activation) and can't read localStorage, but
|
|
397
|
+
// it CAN open the pointer IndexedDB the main-thread picker persists to. Poll it for a handle
|
|
398
|
+
// whose permission is already granted; the owning window may also postMessage a handle in
|
|
399
|
+
// mid-poll (checked each iteration). This has to come before the isNode branch: typesafecss's
|
|
400
|
+
// isNode() returns true in workers (window is undefined), so a worker would otherwise fall into
|
|
401
|
+
// the Node branch and try to use fs/path.
|
|
402
|
+
if ("WorkerGlobalScope" in globalThis) {
|
|
403
|
+
while (true) {
|
|
404
|
+
if (storageRootOverride)
|
|
405
|
+
return storageRootOverride;
|
|
406
|
+
let handle = await (0, fileSystemPointer_1.findGrantedPointerHandle)("readwrite");
|
|
407
|
+
if (handle)
|
|
408
|
+
return handle;
|
|
409
|
+
await new Promise(resolve => setTimeout(resolve, WORKER_POLL_INTERVAL_MS));
|
|
410
|
+
}
|
|
411
|
+
}
|
|
154
412
|
if ((0, typesafecss_1.isNode)()) {
|
|
155
413
|
return new NodeJSDirectoryHandleWrapper(path_1.default.resolve("./data/"));
|
|
156
414
|
}
|
|
415
|
+
if (opfsEnabled) {
|
|
416
|
+
return getCurrentOpfsHandle();
|
|
417
|
+
}
|
|
418
|
+
// A server connected in a previous session: only reuse it if it still actually works.
|
|
419
|
+
const savedRemote = loadRemoteConfig();
|
|
420
|
+
if (savedRemote) {
|
|
421
|
+
const result = await (0, remoteFileStorage_1.testRemoteConnection)(savedRemote.url, savedRemote.password);
|
|
422
|
+
if (result.status === "ok")
|
|
423
|
+
return getRemoteHandle(savedRemote);
|
|
424
|
+
console.warn(`Saved remote server didn't connect (${result.status})${result.status === "unreachable" ? ": " + result.error : ""} — re-prompting.`);
|
|
425
|
+
}
|
|
157
426
|
let root = document.createElement("div");
|
|
158
427
|
document.body.appendChild(root);
|
|
159
428
|
preact_1.default.render(preact_1.default.createElement(DirectoryPrompter, null), root);
|
|
160
429
|
try {
|
|
161
|
-
let
|
|
162
|
-
let
|
|
430
|
+
let resolveHandle;
|
|
431
|
+
let rejectHandle;
|
|
432
|
+
const promise = new Promise((res, rej) => { resolveHandle = res; rejectHandle = rej; });
|
|
433
|
+
const pickLocal = async () => {
|
|
434
|
+
try {
|
|
435
|
+
const handle = await window.showDirectoryPicker();
|
|
436
|
+
await handle.requestPermission({ mode: "readwrite" });
|
|
437
|
+
const storedId = await (0, fileSystemPointer_1.storeFileSystemPointer)({ mode: "readwrite", handle });
|
|
438
|
+
localStorage.setItem(getFileAPIKey(), storedId);
|
|
439
|
+
resolveHandle(handle);
|
|
440
|
+
}
|
|
441
|
+
catch (e) {
|
|
442
|
+
console.error("Directory pick failed/cancelled:", e); // stay on the prompt
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
const onConnected = (config) => { saveRemoteConfig(config); resolveHandle(getRemoteHandle(config)); };
|
|
446
|
+
// The three options, rendered fresh each time. If a saved server just failed, pre-fill + expand
|
|
447
|
+
// the connect form so the user can retry or fix it.
|
|
448
|
+
const renderOptions = () => (preact_1.default.createElement(preact_1.default.Fragment, null,
|
|
449
|
+
preact_1.default.createElement("button", { className: typesafecss_1.css.fontSize(40).pad2(80, 40), onClick: pickLocal }, "Pick Data Directory"),
|
|
450
|
+
preact_1.default.createElement(ServerConnectForm, { onConnected: onConnected, initial: savedRemote }),
|
|
451
|
+
preact_1.default.createElement("button", { className: typesafecss_1.css.fontSize(40).pad2(80, 40), onClick: () => rejectHandle(new Error("User dismissed file system access prompt")) }, "Dismiss")));
|
|
452
|
+
// A previously-picked local folder: try to restore it (may need a click). Skipped when a saved
|
|
453
|
+
// server failed — that user wants the server, so go straight to the (pre-filled) prompt.
|
|
454
|
+
const storedId = !savedRemote && localStorage.getItem(getFileAPIKey());
|
|
163
455
|
if (storedId) {
|
|
164
456
|
let doneLoad = false;
|
|
165
|
-
setTimeout(() => {
|
|
166
|
-
|
|
167
|
-
return;
|
|
168
|
-
console.log("Waiting for user to click");
|
|
169
|
-
displayData.ui = "Click anywhere to allow file system access";
|
|
170
|
-
}, 500);
|
|
457
|
+
setTimeout(() => { if (!doneLoad)
|
|
458
|
+
displayData.ui = "Click anywhere to allow file system access"; }, 500);
|
|
171
459
|
try {
|
|
172
|
-
handle = await tryToLoadPointer(storedId);
|
|
460
|
+
const handle = await tryToLoadPointer(storedId);
|
|
461
|
+
doneLoad = true;
|
|
462
|
+
if (handle)
|
|
463
|
+
return handle;
|
|
173
464
|
}
|
|
174
|
-
catch (
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
465
|
+
catch (e) {
|
|
466
|
+
doneLoad = true;
|
|
467
|
+
console.error(e);
|
|
468
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
469
|
+
if (msg.includes("user activation") || msg.includes("User activation")) {
|
|
470
|
+
displayData.ui = (preact_1.default.createElement("div", { className: typesafecss_1.css.vbox(20).center },
|
|
471
|
+
preact_1.default.createElement("button", { className: typesafecss_1.css.fontSize(40).pad2(80, 40), onClick: async () => {
|
|
472
|
+
displayData.ui = "Loading...";
|
|
473
|
+
try {
|
|
474
|
+
const h = await tryToLoadPointer(storedId);
|
|
475
|
+
if (h) {
|
|
476
|
+
resolveHandle(h);
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
catch (retryError) {
|
|
481
|
+
console.error("Retry failed:", retryError);
|
|
482
|
+
}
|
|
483
|
+
displayData.ui = preact_1.default.createElement("div", { className: typesafecss_1.css.vbox(20).center }, renderOptions());
|
|
484
|
+
} }, "Click to restore file system access"),
|
|
485
|
+
renderOptions()));
|
|
486
|
+
return await promise;
|
|
487
|
+
}
|
|
178
488
|
}
|
|
179
489
|
}
|
|
180
|
-
|
|
181
|
-
let promise = new Promise(resolve => {
|
|
182
|
-
fileCallback = resolve;
|
|
183
|
-
});
|
|
184
|
-
displayData.ui = (preact_1.default.createElement("button", { className: typesafecss_1.css.fontSize(40).pad2(80, 40), onClick: async () => {
|
|
185
|
-
console.log("Waiting for user to give permission");
|
|
186
|
-
const handle = await window.showDirectoryPicker();
|
|
187
|
-
await handle.requestPermission({ mode: "readwrite" });
|
|
188
|
-
let storedId = await (0, fileSystemPointer_1.storeFileSystemPointer)({ mode: "readwrite", handle });
|
|
189
|
-
localStorage.setItem(storageKey, storedId);
|
|
190
|
-
fileCallback(handle);
|
|
191
|
-
} }, "Pick Media Directory"));
|
|
490
|
+
displayData.ui = preact_1.default.createElement("div", { className: typesafecss_1.css.vbox(20).center }, renderOptions());
|
|
192
491
|
return await promise;
|
|
193
492
|
}
|
|
194
493
|
finally {
|
|
@@ -205,6 +504,42 @@ exports.getFileStorageNested = (0, caching_1.cache)(async function getFileStorag
|
|
|
205
504
|
}
|
|
206
505
|
return wrapHandle(base);
|
|
207
506
|
});
|
|
507
|
+
// Supports if the user selects the folder that contains the data folder or the data folder directly. If pathStr is an absolute path (and we're in nodejs) we use it directly.
|
|
508
|
+
exports.getFileStorageNested2 = (0, caching_1.cache)(async function getFileStorage(pathStr) {
|
|
509
|
+
let base;
|
|
510
|
+
pathStr = pathStr.replaceAll("\\", "/");
|
|
511
|
+
if ((0, typesafecss_1.isNode)()) {
|
|
512
|
+
if (path_1.default.isAbsolute(pathStr)) {
|
|
513
|
+
return wrapHandle(new NodeJSDirectoryHandleWrapper(pathStr));
|
|
514
|
+
}
|
|
515
|
+
base = new NodeJSDirectoryHandleWrapper(path_1.default.resolve("./data/"));
|
|
516
|
+
}
|
|
517
|
+
else {
|
|
518
|
+
base = await (0, exports.getDirectoryHandle)();
|
|
519
|
+
// Skip the "find data subdir" hack under OPFS — that's for picked directories where the user
|
|
520
|
+
// might have selected a folder with unrelated files; OPFS is a clean root we own end-to-end.
|
|
521
|
+
if (!opfsEnabled) {
|
|
522
|
+
let dirs = [];
|
|
523
|
+
let alls = [];
|
|
524
|
+
for await (const [name, entry] of base) {
|
|
525
|
+
if (entry.kind === "directory") {
|
|
526
|
+
dirs.push(name);
|
|
527
|
+
}
|
|
528
|
+
alls.push(name);
|
|
529
|
+
}
|
|
530
|
+
// HACK: If there are enough files, it's almost certainly not a directory that contains collections. It's probably the user's data instead
|
|
531
|
+
if (dirs.includes(".git") || dirs.includes("data") || alls.length > 100) {
|
|
532
|
+
base = await base.getDirectoryHandle("data", { create: true });
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
for (let part of pathStr.split("/")) {
|
|
537
|
+
if (!part)
|
|
538
|
+
continue;
|
|
539
|
+
base = await base.getDirectoryHandle(part, { create: true });
|
|
540
|
+
}
|
|
541
|
+
return wrapHandle(base);
|
|
542
|
+
});
|
|
208
543
|
exports.getFileStorage = (0, caching_1.lazy)(async function getFileStorage() {
|
|
209
544
|
if (USE_INDEXED_DB) {
|
|
210
545
|
return await (0, IndexedDBFileFolderAPI_1.getFileStorageIndexDB)();
|
|
@@ -213,7 +548,18 @@ exports.getFileStorage = (0, caching_1.lazy)(async function getFileStorage() {
|
|
|
213
548
|
return wrapHandle(handle);
|
|
214
549
|
});
|
|
215
550
|
function resetStorageLocation() {
|
|
216
|
-
|
|
551
|
+
if (opfsEnabled) {
|
|
552
|
+
// Don't delete previous folder — listPrivateFolders / pickPrivateFolder still need it. Just point
|
|
553
|
+
// "current" at a fresh timestamp-named one so the next reload starts clean.
|
|
554
|
+
setCurrentOpfsFolder(new Date().toISOString().replace(/[:.]/g, "-"));
|
|
555
|
+
window.location.reload();
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
localStorage.removeItem(getFileAPIKey());
|
|
559
|
+
try {
|
|
560
|
+
localStorage.removeItem(remoteConfigKey());
|
|
561
|
+
}
|
|
562
|
+
catch ( /* ignore */_a) { /* ignore */ }
|
|
217
563
|
window.location.reload();
|
|
218
564
|
}
|
|
219
565
|
exports.resetStorageLocation = resetStorageLocation;
|
|
@@ -234,31 +580,78 @@ async function fixedGetFileHandle(config) {
|
|
|
234
580
|
}
|
|
235
581
|
return await config.handle.getFileHandle(config.key, { create: true });
|
|
236
582
|
}
|
|
583
|
+
// A file that genuinely does not exist. We must NOT retry these, otherwise reading many missing
|
|
584
|
+
// files (a common pattern) gets catastrophically slow.
|
|
585
|
+
function isMissingError(error) {
|
|
586
|
+
let name = error === null || error === void 0 ? void 0 : error.name;
|
|
587
|
+
let code = error === null || error === void 0 ? void 0 : error.code;
|
|
588
|
+
return name === "NotFoundError" || code === "ENOENT";
|
|
589
|
+
}
|
|
590
|
+
const MAX_READ_RETRIES = 6;
|
|
591
|
+
// The browser File System Access API can transiently fail reads under heavy load (it appears to
|
|
592
|
+
// throttle when a page issues many reads at once). Those failures surface as errors OTHER than
|
|
593
|
+
// "not found", so we retry them with backoff. A real missing file (NotFoundError / ENOENT) returns
|
|
594
|
+
// undefined immediately with no retry.
|
|
595
|
+
async function readWithRetry(label, key, read) {
|
|
596
|
+
let backoff = 25;
|
|
597
|
+
for (let attempt = 0;; attempt++) {
|
|
598
|
+
try {
|
|
599
|
+
return await read();
|
|
600
|
+
}
|
|
601
|
+
catch (error) {
|
|
602
|
+
if (isMissingError(error))
|
|
603
|
+
return undefined;
|
|
604
|
+
let name = (error === null || error === void 0 ? void 0 : error.name) || "Error";
|
|
605
|
+
let message = (error === null || error === void 0 ? void 0 : error.message) || String(error);
|
|
606
|
+
if (attempt >= MAX_READ_RETRIES) {
|
|
607
|
+
console.warn(`${label} gave up on ${JSON.stringify(key)} after ${attempt} retries (${name}): ${message.slice(0, 200)}`);
|
|
608
|
+
return undefined;
|
|
609
|
+
}
|
|
610
|
+
console.warn(`${label} retrying ${JSON.stringify(key)} (attempt ${attempt + 1}, ${name}): ${message.slice(0, 200)}`);
|
|
611
|
+
await new Promise(resolve => setTimeout(resolve, backoff));
|
|
612
|
+
backoff = Math.min(backoff * 2, 1000);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
237
616
|
function wrapHandleFiles(handle) {
|
|
617
|
+
// Log the full path (root + filename) when available, so a failing file is identifiable.
|
|
618
|
+
const pathOf = (key) => handle.fullPath ? handle.fullPath + "/" + key : key;
|
|
238
619
|
return {
|
|
239
620
|
async getInfo(key) {
|
|
240
|
-
|
|
621
|
+
return readWithRetry("getInfo", pathOf(key), async () => {
|
|
241
622
|
const file = await handle.getFileHandle(key);
|
|
242
623
|
const fileContent = await file.getFile();
|
|
243
624
|
return {
|
|
244
625
|
size: fileContent.size,
|
|
245
626
|
lastModified: fileContent.lastModified,
|
|
246
627
|
};
|
|
247
|
-
}
|
|
248
|
-
catch (error) {
|
|
249
|
-
return undefined;
|
|
250
|
-
}
|
|
628
|
+
});
|
|
251
629
|
},
|
|
252
630
|
async get(key) {
|
|
253
|
-
|
|
631
|
+
return readWithRetry("get", pathOf(key), async () => {
|
|
254
632
|
const file = await handle.getFileHandle(key);
|
|
255
633
|
const fileContent = await file.getFile();
|
|
256
634
|
const arrayBuffer = await fileContent.arrayBuffer();
|
|
635
|
+
// Under load the FS Access API can resolve with a truncated buffer and no error.
|
|
636
|
+
// Treat a short read as transient so readWithRetry retries it.
|
|
637
|
+
if (arrayBuffer.byteLength !== fileContent.size) {
|
|
638
|
+
throw Object.assign(new Error(`Short read: got ${arrayBuffer.byteLength} of ${fileContent.size} bytes`), { name: "ShortReadError" });
|
|
639
|
+
}
|
|
257
640
|
return Buffer.from(arrayBuffer);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
641
|
+
});
|
|
642
|
+
},
|
|
643
|
+
async getRange(key, config) {
|
|
644
|
+
return readWithRetry("getRange", pathOf(key), async () => {
|
|
645
|
+
const file = await handle.getFileHandle(key);
|
|
646
|
+
const fileContent = await file.getFile();
|
|
647
|
+
const clampedStart = Math.min(Math.max(config.start, 0), fileContent.size);
|
|
648
|
+
const clampedEnd = Math.min(Math.max(config.end, clampedStart), fileContent.size);
|
|
649
|
+
const arrayBuffer = await fileContent.slice(config.start, config.end).arrayBuffer();
|
|
650
|
+
if (arrayBuffer.byteLength !== clampedEnd - clampedStart) {
|
|
651
|
+
throw Object.assign(new Error(`Short range read: got ${arrayBuffer.byteLength} of ${clampedEnd - clampedStart} bytes`), { name: "ShortReadError" });
|
|
652
|
+
}
|
|
653
|
+
return Buffer.from(arrayBuffer);
|
|
654
|
+
});
|
|
262
655
|
},
|
|
263
656
|
async append(key, value) {
|
|
264
657
|
await appendQueue(key)(async () => {
|
|
@@ -281,13 +674,22 @@ function wrapHandleFiles(handle) {
|
|
|
281
674
|
async remove(key) {
|
|
282
675
|
await handle.removeEntry(key);
|
|
283
676
|
},
|
|
284
|
-
async getKeys() {
|
|
677
|
+
async getKeys(includeFolders = false) {
|
|
285
678
|
const keys = [];
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
679
|
+
try {
|
|
680
|
+
for await (const [name, entry] of handle) {
|
|
681
|
+
if (entry.kind === "file" || includeFolders) {
|
|
682
|
+
keys.push(entry.name);
|
|
683
|
+
}
|
|
289
684
|
}
|
|
290
685
|
}
|
|
686
|
+
catch (error) {
|
|
687
|
+
let name = (error === null || error === void 0 ? void 0 : error.name) || "Error";
|
|
688
|
+
let message = (error === null || error === void 0 ? void 0 : error.message) || String(error);
|
|
689
|
+
// A failure mid-iteration would silently truncate the listing, so surface it loudly.
|
|
690
|
+
console.error(`getKeys directory iteration failed after ${keys.length} entries (${name}): ${message.slice(0, 300)}`);
|
|
691
|
+
throw error;
|
|
692
|
+
}
|
|
291
693
|
return keys;
|
|
292
694
|
},
|
|
293
695
|
async reset() {
|
|
@@ -330,8 +732,48 @@ function wrapHandle(handle) {
|
|
|
330
732
|
return {
|
|
331
733
|
...wrapHandleFiles(handle),
|
|
332
734
|
folder: wrapHandleNested(handle),
|
|
735
|
+
isRemote: handle.isRemote,
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
exports.wrapHandle = wrapHandle;
|
|
739
|
+
// Returns a URL for a file's bytes, ready to drop into <video>/<img>/fetch. A native (local) file becomes
|
|
740
|
+
// an in-memory blob: URL; a remote file becomes an https URL into the server's range-capable /media
|
|
741
|
+
// endpoint (auth token in the query, since a media element can't send headers). Both support HTTP range /
|
|
742
|
+
// seeking. ALWAYS hand the result to disposeFileURL when finished — for blob: URLs that frees memory.
|
|
743
|
+
async function getFileURL(file) {
|
|
744
|
+
if (file.getURL)
|
|
745
|
+
return file.getURL();
|
|
746
|
+
// Native FileSystemFileHandle (or any Blob-backed file): a blob: URL over the File itself.
|
|
747
|
+
const f = await file.getFile();
|
|
748
|
+
return URL.createObjectURL(f);
|
|
749
|
+
}
|
|
750
|
+
exports.getFileURL = getFileURL;
|
|
751
|
+
// Releases a URL from getFileURL. blob: URLs leak until the document is gone unless revoked; https/file:
|
|
752
|
+
// URLs need no cleanup, so this is a no-op for them.
|
|
753
|
+
function disposeFileURL(url) {
|
|
754
|
+
if (url.startsWith("blob:")) {
|
|
755
|
+
try {
|
|
756
|
+
URL.revokeObjectURL(url);
|
|
757
|
+
}
|
|
758
|
+
catch ( /* not in a browser, or already revoked */_a) { /* not in a browser, or already revoked */ }
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
exports.disposeFileURL = disposeFileURL;
|
|
762
|
+
// A StorageFactory backed by a remote server (path -> FileStorage), for code that injects its own
|
|
763
|
+
// storage into BulkDatabase2 rather than going through the directory prompt.
|
|
764
|
+
function getRemoteFileStorageFactory(url, password, options) {
|
|
765
|
+
const root = (0, remoteFileStorage_1.getRemoteDirectoryHandle)(url, password, options);
|
|
766
|
+
return async (pathStr) => {
|
|
767
|
+
let base = root;
|
|
768
|
+
for (const part of pathStr.replaceAll("\\", "/").split("/")) {
|
|
769
|
+
if (!part)
|
|
770
|
+
continue;
|
|
771
|
+
base = await base.getDirectoryHandle(part, { create: true });
|
|
772
|
+
}
|
|
773
|
+
return wrapHandle(base);
|
|
333
774
|
};
|
|
334
775
|
}
|
|
776
|
+
exports.getRemoteFileStorageFactory = getRemoteFileStorageFactory;
|
|
335
777
|
async function tryToLoadPointer(pointer) {
|
|
336
778
|
let result = await (0, fileSystemPointer_1.getFileSystemPointer)({ pointer });
|
|
337
779
|
if (!result)
|
|
@@ -341,5 +783,6 @@ async function tryToLoadPointer(pointer) {
|
|
|
341
783
|
return;
|
|
342
784
|
return handle;
|
|
343
785
|
}
|
|
344
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmlsZUZvbGRlckFQSS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIkZpbGVGb2xkZXJBUEkudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLG9EQUE0QjtBQUM1QiwyREFBbUY7QUFDbkYsaURBQStDO0FBQy9DLCtDQUE0QztBQUM1Qyx5REFBMEQ7QUFDMUQsNkNBQTBDO0FBRTFDLDJEQUEyRDtBQUMzRCxxRUFBaUU7QUFDakUsNENBQW9CO0FBQ3BCLGdEQUF3QjtBQUV4Qix1RUFBdUU7QUFDdkUsd0ZBQXdGO0FBQ3hGLCtCQUErQjtBQUMvQixNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUM7QUE2QjdCLElBQUksV0FBVyxHQUFHLElBQUEsc0JBQVUsRUFBQztJQUN6QixFQUFFLEVBQUUsU0FBaUQ7Q0FDeEQsRUFBRSxTQUFTLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztBQUUvQixNQUFNLFVBQVUsR0FBRyx1QkFBdUIsQ0FBQztBQUczQyxJQUFNLGlCQUFpQixHQUF2QixNQUFNLGlCQUFrQixTQUFRLGdCQUFNLENBQUMsU0FBUztJQUM1QyxNQUFNO1FBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQUUsT0FBTyxTQUFTLENBQUM7UUFDdEMsT0FBTyxDQUNILHdDQUFLLFNBQVMsRUFDVixpQkFBRyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDO2lCQUNqRCxNQUFNLENBQUMsQ0FBQyxDQUFDO2lCQUNULFVBQVUsQ0FBQyxPQUFPLENBQUM7aUJBQ25CLE1BQU07aUJBQ04sUUFBUSxDQUFDLEVBQUUsQ0FBQyxJQUVoQixXQUFXLENBQUMsRUFBRSxDQUNiLENBQ1QsQ0FBQztJQUNOLENBQUM7Q0FDSixDQUFBO0FBZkssaUJBQWlCO0lBRHRCLG1CQUFRO0dBQ0gsaUJB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VztZQUMzQixNQUFNLE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUVELEtBQUssQ0FBQyxPQUFPO1lBQ1QsTUFBTSxJQUFJLEdBQWEsRUFBRSxDQUFDO1lBQzFCLElBQUksS0FBSyxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxFQUFFLENBQUM7Z0JBQ3ZDLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUUsQ0FBQztvQkFDN0IsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzFCLENBQUM7WUFDTCxDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUM7UUFDaEIsQ0FBQztLQUNKLENBQUM7QUFDTixDQUFDO0FBRUQsU0FBUyxVQUFVLENBQUMsTUFBd0I7SUFDeEMsT0FBTztRQUNILEdBQUcsZUFBZSxDQUFDLE1BQU0sQ0FBQztRQUMxQixNQUFNLEVBQUUsZ0JBQWdCLENBQUMsTUFBTSxDQUFDO0tBQ25DLENBQUM7QUFDTixDQUFDO0FBRUQsS0FBSyxVQUFVLGdCQUFnQixDQUFDLE9BQWU7SUFDM0MsSUFBSSxNQUFNLEdBQUcsTUFBTSxJQUFBLHdDQUFvQixFQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUNyRCxJQUFJLENBQUMsTUFBTTtRQUFFLE9BQU87SUFDcEIsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFBLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxnQkFBZ0IsRUFBRSxDQUFBLENBQUM7SUFDOUMsSUFBSSxDQUFDLE1BQU07UUFBRSxPQUFPO0lBQ3BCLE9BQU8sTUFBaUMsQ0FBQztBQUM3QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHByZWFjdCBmcm9tIFwicHJlYWN0XCI7XG5pbXBvcnQgeyBnZXRGaWxlU3lzdGVtUG9pbnRlciwgc3RvcmVGaWxlU3lzdGVtUG9pbnRlciB9IGZyb20gXCIuL2ZpbGVTeXN0ZW1Qb2ludGVyXCI7XG5pbXBvcnQgeyBvYnNlcnZhYmxlIH0gZnJvbSBcIi4uL21pc2MvbW9ieFR5cGVkXCI7XG5pbXBvcnQgeyBvYnNlcnZlciB9IGZyb20gXCIuLi9taXNjL29ic2VydmVyXCI7XG5pbXBvcnQgeyBjYWNoZSwgbGF6eSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2NhY2hpbmdcIjtcbmltcG9ydCB7IGNzcywgaXNOb2RlIH0gZnJvbSBcInR5cGVzYWZlY3NzXCI7XG5pbXBvcnQgeyBJU3RvcmFnZVJhdyB9IGZyb20gXCIuL0lTdG9yYWdlXCI7XG5pbXBvcnQgeyBydW5JblNlcmlhbCB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2JhdGNoaW5nXCI7XG5pbXBvcnQgeyBnZXRGaWxlU3RvcmFnZUluZGV4REIgfSBmcm9tIFwiLi9JbmRleGVkREJGaWxlRm9sZGVyQVBJXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG4vLyBOT1RFOiBJbmRleGVkREIgaXMgcmVxdWlyZWQgZm9yIGlPUywgYXQgbGVhc3QuIFdlIE1JR0hUIHdhbnQgdG8gbWFrZVxuLy8gIHRoaXMgYSB1c2VyIHN1cHBvcnRlZCB0b2dnbGUgdG9vLCBzbyB0aGV5IGNhbiBjaG9vc2UgZHVyaW5nIHJ1bnRpbWUgaWYgdGhleSB3YW50IGl0LlxuLy8gRE8gTk9UIGVuYWJsZSB0aGlzIGlzIGlzTm9kZVxuY29uc3QgVVNFX0lOREVYRURfREIgPSBmYWxzZTtcblxudHlwZSBGaWxlV3JhcHBlciA9IHtcbiAgICBnZXRGaWxlKCk6IFByb21pc2U8e1xuICAgICAgICBzaXplOiBudW1iZXI7XG4gICAgICAgIGxhc3RNb2RpZmllZDogbnVtYmVyO1xuICAgICAgICBhcnJheUJ1ZmZlcigpOiBQcm9taXNlPEFycmF5QnVmZmVyPjtcbiAgICB9PjtcbiAgICBjcmVhdGVXcml0YWJsZShjb25maWc/OiB7IGtlZXBFeGlzdGluZ0RhdGE/OiBib29sZWFuIH0pOiBQcm9taXNlPHtcbiAgICAgICAgc2VlayhvZmZzZXQ6IG51bWJlcik6IFByb21pc2U8dm9pZD47XG4gICAgICAgIHdyaXRlKHZhbHVlOiBCdWZmZXIpOiBQcm9taXNlPHZvaWQ+O1xuICAgICAgICBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+O1xuICAgIH0+O1xufTtcbnR5cGUgRGlyZWN0b3J5V3JhcHBlciA9IHtcbiAgICByZW1vdmVFbnRyeShrZXk6IHN0cmluZywgb3B0aW9ucz86IHsgcmVjdXJzaXZlPzogYm9vbGVhbiB9KTogUHJvbWlzZTx2b2lkPjtcbiAgICBnZXRGaWxlSGFuZGxlKGtleTogc3RyaW5nLCBvcHRpb25zPzogeyBjcmVhdGU/OiBib29sZWFuIH0pOiBQcm9taXNlPEZpbGVXcmFwcGVyPjtcbiAgICBnZXREaXJlY3RvcnlIYW5kbGUoa2V5OiBzdHJpbmcsIG9wdGlvbnM/OiB7IGNyZWF0ZT86IGJvb2xlYW4gfSk6IFByb21pc2U8RGlyZWN0b3J5V3JhcHBlcj47XG4gICAgW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSgpOiBBc3luY0l0ZXJhYmxlSXRlcmF0b3I8W3N0cmluZywge1xuICAgICAgICBraW5kOiBcImZpbGVcIjtcbiAgICAgICAgbmFtZTogc3RyaW5nO1xuICAgICAgICBnZXRGaWxlKCk6IFByb21pc2U8RmlsZVdyYXBwZXI+O1xuICAgIH0gfCB7XG4gICAgICAgIGtpbmQ6IFwiZGlyZWN0b3J5XCI7XG4gICAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgICAgZ2V0RGlyZWN0b3J5SGFuZGxlKGtleTogc3RyaW5nLCBvcHRpb25zPzogeyBjcmVhdGU/OiBib29sZWFuIH0pOiBQcm9taXNlPERpcmVjdG9yeVdyYXBwZXI+O1xuICAgIH1dPjtcbn07XG5cbmxldCBkaXNwbGF5RGF0YSA9IG9ic2VydmFibGUoe1xuICAgIHVpOiB1bmRlZmluZWQgYXMgdW5kZWZpbmVkIHwgcHJlYWN0LkNvbXBvbmVudENoaWxkcmVuLFxufSwgdW5kZWZpbmVkLCB7IGRlZXA6IGZhbHNlIH0pO1xuXG5jb25zdCBzdG9yYWdlS2V5ID0gXCJzeW5jRmlsZVN5c3RlbUNhbWVyYTNcIjtcblxuQG9ic2VydmVyXG5jbGFzcyBEaXJlY3RvcnlQcm9tcHRlciBleHRlbmRzIHByZWFjdC5Db21wb25lbnQge1xuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCFkaXNwbGF5RGF0YS51aSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPXtcbiAgICAgICAgICAgICAgICBjc3MucG9zaXRpb24oXCJmaXhlZFwiKS5wb3MoMCwgMCkuc2l6ZShcIjEwMHZ3XCIsIFwiMTAwdmhcIilcbiAgICAgICAgICAgICAgICAgICAgLnpJbmRleCgxKVxuICAgICAgICAgICAgICAgICAgICAuYmFja2dyb3VuZChcIndoaXRlXCIpXG4gICAgICAgICAgICAgICAgICAgIC5jZW50ZXJcbiAgICAgICAgICAgICAgICAgICAgLmZvbnRTaXplKDQwKVxuICAgICAgICAgICAgfT5cbiAgICAgICAgICAgICAgICB7ZGlzcGxheURhdGEudWl9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9XG59XG5cbmNsYXNzIE5vZGVKU0ZpbGVIYW5kbGVXcmFwcGVyIGltcGxlbWVudHMgRmlsZVdyYXBwZXIge1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZmlsZVBhdGg6IHN0cmluZykge1xuICAgIH1cblxuICAgIGFzeW5jIGdldEZpbGUoKSB7XG4gICAgICAgIGNvbnN0IHN0YXRzID0gYXdhaXQgZnMucHJvbWlzZXMuc3RhdCh0aGlzLmZpbGVQYXRoKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNpemU6IHN0YXRzLnNpemUsXG4gICAgICAgICAgICBsYXN0TW9kaWZpZWQ6IHN0YXRzLm10aW1lTXMsXG4gICAgICAgICAgICBhcnJheUJ1ZmZlcjogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IGF3YWl0IGZzLnByb21pc2VzLnJlYWRGaWxlKHRoaXMuZmlsZVBhdGgpO1xuICAgICAgICAgICAgICAgIHJldHVybiBidWZmZXIuYnVmZmVyLnNsaWNlKGJ1ZmZlci5ieXRlT2Zmc2V0LCBidWZmZXIuYnl0ZU9mZnNldCArIGJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBhc3luYyBjcmVhdGVXcml0YWJsZShjb25maWc/OiB7IGtlZXBFeGlzdGluZ0RhdGE/OiBib29sZWFuIH0pIHtcbiAgICAgICAgbGV0IGZpbGVIYW5kbGU6IGZzLnByb21pc2VzLkZpbGVIYW5kbGU7XG4gICAgICAgIGNvbnN0IGZsYWdzID0gY29uZmlnPy5rZWVwRXhpc3RpbmdEYXRhID8gXCJyK1wiIDogXCJ3XCI7XG5cbiAgICAgICAgLy8gRW5zdXJlIHRoZSBkaXJlY3RvcnkgZXhpc3RzXG4gICAgICAgIGF3YWl0IGZzLnByb21pc2VzLm1rZGlyKHBhdGguZGlybmFtZSh0aGlzLmZpbGVQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgICAgICAgLy8gT3BlbiBvciBjcmVhdGUgdGhlIGZpbGVcbiAgICAgICAgaWYgKGNvbmZpZz8ua2VlcEV4aXN0aW5nRGF0YSAmJiBhd2FpdCBmcy5wcm9taXNlcy5hY2Nlc3ModGhpcy5maWxlUGF0aCkudGhlbigoKSA9PiB0cnVlKS5jYXRjaCgoKSA9PiBmYWxzZSkpIHtcbiAgICAgICAgICAgIGZpbGVIYW5kbGUgPSBhd2FpdCBmcy5wcm9taXNlcy5vcGVuKHRoaXMuZmlsZVBhdGgsIGZsYWdzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZpbGVIYW5kbGUgPSBhd2FpdCBmcy5wcm9taXNlcy5vcGVuKHRoaXMuZmlsZVBhdGgsIFwid1wiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBwb3NpdGlvbiA9IDA7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNlZWs6IGFzeW5jIChvZmZzZXQ6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gb2Zmc2V0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHdyaXRlOiBhc3luYyAodmFsdWU6IEJ1ZmZlcikgPT4ge1xuICAgICAgICAgICAgICAgIGF3YWl0IGZpbGVIYW5kbGUud3JpdGUodmFsdWUsIDAsIHZhbHVlLmxlbmd0aCwgcG9zaXRpb24pO1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uICs9IHZhbHVlLmxlbmd0aDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjbG9zZTogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGF3YWl0IGZpbGVIYW5kbGUuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmNsYXNzIE5vZGVKU0RpcmVjdG9yeUhhbmRsZVdyYXBwZXIgaW1wbGVtZW50cyBEaXJlY3RvcnlXcmFwcGVyIHtcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJvb3RQYXRoOiBzdHJpbmcpIHtcbiAgICB9XG5cbiAgICBhc3luYyByZW1vdmVFbnRyeShrZXk6IHN0cmluZywgb3B0aW9ucz86IHsgcmVjdXJzaXZlPzogYm9vbGVhbiB9KSB7XG4gICAgICAgIGNvbnN0IGVudHJ5UGF0aCA9IHBhdGguam9pbih0aGlzLnJvb3RQYXRoLCBrZXkpO1xuICAgICAgICBpZiAob3B0aW9ucz8ucmVjdXJzaXZlKSB7XG4gICAgICAgICAgICBhd2FpdCBmcy5wcm9taXNlcy5ybShlbnRyeVBhdGgsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGF3YWl0IGZzLnByb21pc2VzLnVubGluayhlbnRyeVBhdGgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0RmlsZUhhbmRsZShrZXk6IHN0cmluZywgb3B0aW9ucz86IHsgY3JlYXRlPzogYm9vbGVhbiB9KTogUHJvbWlzZTxGaWxlV3JhcHBlcj4ge1xuICAgICAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGguam9pbih0aGlzLnJvb3RQYXRoLCBrZXkpO1xuXG4gICAgICAgIGNvbnN0IGV4aXN0cyA9IGF3YWl0IGZzLnByb21pc2VzLmFjY2VzcyhmaWxlUGF0aCkudGhlbigoKSA9PiB0cnVlKS5jYXRjaCgoKSA9PiBmYWxzZSk7XG5cbiAgICAgICAgaWYgKCFleGlzdHMgJiYgb3B0aW9ucz8uY3JlYXRlKSB7XG4gICAgICAgICAgICAvLyBFbnN1cmUgdGhlIGRpcmVjdG9yeSBleGlzdHNcbiAgICAgICAgICAgIGF3YWl0IGZzLnByb21pc2VzLm1rZGlyKHBhdGguZGlybmFtZShmaWxlUGF0aCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICAgICAgLy8gQ3JlYXRlIHRoZSBmaWxlXG4gICAgICAgICAgICBhd2FpdCBmcy5wcm9taXNlcy53cml0ZUZpbGUoZmlsZVBhdGgsIEJ1ZmZlci5hbGxvYygwKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoIWV4aXN0cykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGaWxlIG5vdCBmb3VuZDogJHtmaWxlUGF0aH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgTm9kZUpTRmlsZUhhbmRsZVdyYXBwZXIoZmlsZVBhdGgpO1xuICAgIH1cblxuICAgIGFzeW5jIGdldERpcmVjdG9yeUhhbmRsZShrZXk6IHN0cmluZywgb3B0aW9ucz86IHsgY3JlYXRlPzogYm9vbGVhbiB9KTogUHJvbWlzZTxEaXJlY3RvcnlXcmFwcGVyPiB7XG4gICAgICAgIGNvbnN0IGRpclBhdGggPSBwYXRoLmpvaW4odGhpcy5yb290UGF0aCwga2V5KTtcblxuICAgICAgICBpZiAob3B0aW9ucz8uY3JlYXRlKSB7XG4gICAgICAgICAgICBhd2FpdCBmcy5wcm9taXNlcy5ta2RpcihkaXJQYXRoLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGV4aXN0cyA9IGF3YWl0IGZzLnByb21pc2VzLmFjY2VzcyhkaXJQYXRoKS50aGVuKCgpID0+IHRydWUpLmNhdGNoKCgpID0+IGZhbHNlKTtcbiAgICAgICAgICAgIGlmICghZXhpc3RzKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBEaXJlY3Rvcnkgbm90IGZvdW5kOiAke2RpclBhdGh9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IE5vZGVKU0RpcmVjdG9yeUhhbmRsZVdyYXBwZXIoZGlyUGF0aCk7XG4gICAgfVxuXG4gICAgYXN5bmMgKltTeW1ib2wuYXN5bmNJdGVyYXRvcl0oKTogQXN5bmNJdGVyYWJsZUl0ZXJhdG9yPFtzdHJpbmcsIHtcbiAgICAgICAga2luZDogXCJmaWxlXCI7XG4gICAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgICAgZ2V0RmlsZSgpOiBQcm9taXNlPEZpbGVXcmFwcGVyPjtcbiAgICB9IHwge1xuICAgICAgICBraW5kOiBcImRpcmVjdG9yeVwiO1xuICAgICAgICBuYW1lOiBzdHJpbmc7XG4gICAgICAgIGdldERpcmVjdG9yeUhhbmRsZShrZXk6IHN0cmluZywgb3B0aW9ucz86IHsgY3JlYXRlPzogYm9vbGVhbiB9KTogUHJvbWlzZTxEaXJlY3RvcnlXcmFwcGVyPjtcbiAgICB9XT4ge1xuICAgICAgICAvLyBFbnN1cmUgZGlyZWN0b3J5IGV4aXN0c1xuICAgICAgICBhd2FpdCBmcy5wcm9taXNlcy5ta2Rpcih0aGlzLnJvb3RQYXRoLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICAgICAgICBjb25zdCBlbnRyaWVzID0gYXdhaXQgZnMucHJvbWlzZXMucmVhZGRpcih0aGlzLnJvb3RQYXRoLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XG5cbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICAgICAgICBpZiAoZW50cnkuaXNGaWxlKCkpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCBbZW50cnkubmFtZSwge1xuICAgICAgICAgICAgICAgICAgICBraW5kOiBcImZpbGVcIixcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogZW50cnkubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgZ2V0RmlsZTogYXN5bmMgKCkgPT4gbmV3IE5vZGVKU0ZpbGVIYW5kbGVXcmFwcGVyKHBhdGguam9pbih0aGlzLnJvb3RQYXRoLCBlbnRyeS5uYW1lKSlcbiAgICAgICAgICAgICAgICB9XTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZW50cnkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRpclBhdGggPSBwYXRoLmpvaW4odGhpcy5yb290UGF0aCwgZW50cnkubmFtZSk7XG4gICAgICAgICAgICAgICAgeWllbGQgW2VudHJ5Lm5hbWUsIHtcbiAgICAgICAgICAgICAgICAgICAga2luZDogXCJkaXJlY3RvcnlcIixcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogZW50cnkubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgZ2V0RGlyZWN0b3J5SGFuZGxlOiBhc3luYyAoa2V5OiBzdHJpbmcsIG9wdGlvbnM/OiB7IGNyZWF0ZT86IGJvb2xlYW4gfSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBOb2RlSlNEaXJlY3RvcnlIYW5kbGVXcmFwcGVyKGRpclBhdGgpLmdldERpcmVjdG9yeUhhbmRsZShrZXksIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cblxuLy8gTk9URTogQmxvY2tzIHVudGlsIHRoZSB1c2VyIHByb3ZpZGVzIGEgZGlyZWN0b3J5XG5leHBvcnQgY29uc3QgZ2V0RGlyZWN0b3J5SGFuZGxlID0gbGF6eShhc3luYyBmdW5jdGlvbiBnZXREaXJlY3RvcnlIYW5kbGUoKTogUHJvbWlzZTxEaXJlY3RvcnlXcmFwcGVyPiB7XG4gICAgaWYgKGlzTm9kZSgpKSB7XG4gICAgICAgIHJldHVybiBuZXcgTm9kZUpTRGlyZWN0b3J5SGFuZGxlV3JhcHBlcihwYXRoLnJlc29sdmUoXCIuL2RhdGEvXCIpKTtcbiAgICB9XG4gICAgbGV0IHJvb3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQocm9vdCk7XG4gICAgcHJlYWN0LnJlbmRlcig8RGlyZWN0b3J5UHJvbXB0ZXIgLz4sIHJvb3QpO1xuICAgIHRyeSB7XG5cbiAgICAgICAgbGV0IGhhbmRsZTogRGlyZWN0b3J5V3JhcHBlciB8IHVuZGVmaW5lZDtcblxuICAgICAgICBsZXQgc3RvcmVkSWQgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShzdG9yYWdlS2V5KTtcbiAgICAgICAgaWYgKHN0b3JlZElkKSB7XG4gICAgICAgICAgICBsZXQgZG9uZUxvYWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChkb25lTG9hZCkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiV2FpdGluZyBmb3IgdXNlciB0byBjbGlja1wiKTtcbiAgICAgICAgICAgICAgICBkaXNwbGF5RGF0YS51aSA9IFwiQ2xpY2sgYW55d2hlcmUgdG8gYWxsb3cgZmlsZSBzeXN0ZW0gYWNjZXNzXCI7XG4gICAgICAgICAgICB9LCA1MDApO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBoYW5kbGUgPSBhd2FpdCB0cnlUb0xvYWRQb2ludGVyKHN0b3JlZElkKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggeyB9XG4gICAgICAgICAgICBkb25lTG9hZCA9IHRydWU7XG4gICAgICAgICAgICBpZiAoaGFuZGxlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgZmlsZUNhbGxiYWNrOiAoaGFuZGxlOiBEaXJlY3RvcnlXcmFwcGVyKSA9PiB2b2lkO1xuICAgICAgICBsZXQgcHJvbWlzZSA9IG5ldyBQcm9taXNlPERpcmVjdG9yeVdyYXBwZXI+KHJlc29sdmUgPT4ge1xuICAgICAgICAgICAgZmlsZUNhbGxiYWNrID0gcmVzb2x2ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGRpc3BsYXlEYXRhLnVpID0gKFxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17Y3NzLmZvbnRTaXplKDQwKS5wYWQyKDgwLCA0MCl9XG4gICAgICAgICAgICAgICAgb25DbGljaz17YXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIldhaXRpbmcgZm9yIHVzZXIgdG8gZ2l2ZSBwZXJtaXNzaW9uXCIpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGUgPSBhd2FpdCB3aW5kb3cuc2hvd0RpcmVjdG9yeVBpY2tlcigpO1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBoYW5kbGUucmVxdWVzdFBlcm1pc3Npb24oeyBtb2RlOiBcInJlYWR3cml0ZVwiIH0pO1xuICAgICAgICAgICAgICAgICAgICBsZXQgc3RvcmVkSWQgPSBhd2FpdCBzdG9yZUZpbGVTeXN0ZW1Qb2ludGVyKHsgbW9kZTogXCJyZWFkd3JpdGVcIiwgaGFuZGxlIH0pO1xuICAgICAgICAgICAgICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShzdG9yYWdlS2V5LCBzdG9yZWRJZCk7XG4gICAgICAgICAgICAgICAgICAgIGZpbGVDYWxsYmFjayhoYW5kbGUgYXMgYW55KTtcbiAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIFBpY2sgTWVkaWEgRGlyZWN0b3J5XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHByb21pc2U7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgcHJlYWN0LnJlbmRlcihudWxsLCByb290KTtcbiAgICAgICAgcm9vdC5yZW1vdmUoKTtcbiAgICB9XG59KTtcblxuZXhwb3J0IGNvbnN0IGdldEZpbGVTdG9yYWdlTmVzdGVkID0gY2FjaGUoYXN5bmMgZnVuY3Rpb24gZ2V0RmlsZVN0b3JhZ2UocGF0aDogc3RyaW5nKTogUHJvbWlzZTxGaWxlU3RvcmFnZT4ge1xuICAgIGxldCBiYXNlID0gYXdhaXQgZ2V0RGlyZWN0b3J5SGFuZGxlKCk7XG4gICAgZm9yIChsZXQgcGFydCBvZiBwYXRoLnNwbGl0KFwiL1wiKSkge1xuICAgICAgICBpZiAoIXBhcnQpIGNvbnRpbnVlO1xuICAgICAgICBiYXNlID0gYXdhaXQgYmFzZS5nZXREaXJlY3RvcnlIYW5kbGUocGFydCwgeyBjcmVhdGU6IHRydWUgfSk7XG4gICAgfVxuICAgIHJldHVybiB3cmFwSGFuZGxlKGJhc2UpO1xufSk7XG5leHBvcnQgY29uc3QgZ2V0RmlsZVN0b3JhZ2UgPSBsYXp5KGFzeW5jIGZ1bmN0aW9uIGdldEZpbGVTdG9yYWdlKCk6IFByb21pc2U8RmlsZVN0b3JhZ2U+IHtcbiAgICBpZiAoVVNFX0lOREVYRURfREIpIHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGdldEZpbGVTdG9yYWdlSW5kZXhEQigpO1xuICAgIH1cblxuICAgIGxldCBoYW5kbGUgPSBhd2FpdCBnZXREaXJlY3RvcnlIYW5kbGUoKTtcbiAgICByZXR1cm4gd3JhcEhhbmRsZShoYW5kbGUpO1xufSk7XG5leHBvcnQgZnVuY3Rpb24gcmVzZXRTdG9yYWdlTG9jYXRpb24oKSB7XG4gICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oc3RvcmFnZUtleSk7XG4gICAgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpO1xufVxuXG5leHBvcnQgdHlwZSBOZXN0ZWRGaWxlU3RvcmFnZSA9IHtcbiAgICBoYXNLZXkoa2V5OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+O1xuICAgIGdldFN0b3JhZ2Uoa2V5OiBzdHJpbmcpOiBQcm9taXNlPEZpbGVTdG9yYWdlPjtcbiAgICByZW1vdmVTdG9yYWdlKGtleTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPjtcbiAgICBnZXRLZXlzKCk6IFByb21pc2U8c3RyaW5nW10+O1xufTtcblxuZXhwb3J0IHR5cGUgRmlsZVN0b3JhZ2UgPSBJU3RvcmFnZVJhdyAmIHtcbiAgICBmb2xkZXI6IE5lc3RlZEZpbGVTdG9yYWdlO1xufTtcblxubGV0IGFwcGVuZFF1ZXVlID0gY2FjaGUoKGtleTogc3RyaW5nKSA9PiB7XG4gICAgcmV0dXJuIHJ1bkluU2VyaWFsKChmbmM6ICgpID0+IFByb21pc2U8dm9pZD4pID0+IGZuYygpKTtcbn0pO1xuXG5cbmFzeW5jIGZ1bmN0aW9uIGZpeGVkR2V0RmlsZUhhbmRsZShjb25maWc6IHtcbiAgICBoYW5kbGU6IERpcmVjdG9yeVdyYXBwZXI7XG4gICAga2V5OiBzdHJpbmc7XG4gICAgY3JlYXRlOiB0cnVlO1xufSk6IFByb21pc2U8RmlsZVdyYXBwZXI+O1xuYXN5bmMgZnVuY3Rpb24gZml4ZWRHZXRGaWxlSGFuZGxlKGNvbmZpZzoge1xuICAgIGhhbmRsZTogRGlyZWN0b3J5V3JhcHBlcjtcbiAgICBrZXk6IHN0cmluZztcbiAgICBjcmVhdGU/OiBib29sZWFuO1xufSk6IFByb21pc2U8RmlsZVdyYXBwZXIgfCB1bmRlZmluZWQ+O1xuYXN5bmMgZnVuY3Rpb24gZml4ZWRHZXRGaWxlSGFuZGxlKGNvbmZpZzoge1xuICAgIGhhbmRsZTogRGlyZWN0b3J5V3JhcHBlcjtcbiAgICBrZXk6IHN0cmluZztcbiAgICBjcmVhdGU/OiBib29sZWFuO1xufSk6IFByb21pc2U8RmlsZVdyYXBwZXIgfCB1bmRlZmluZWQ+IHtcbiAgICBpZiAoY29uZmlnLmtleS5pbmNsdWRlcyhcIi9cIikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgdXNlIGZvbGRlcnMgZGlyZWN0bHkgaW4gZmlsZSBzeXN0ZW0gcmVhZCAvIHdyaXRlcy4gVXNlIGEgd3JhcHBlciB3aGljaCBoYW5kbGVzIHRoZSBmb2xkZXIgbmF2aWdhdGlvbi4gUGF0aCB3YXMgJHtKU09OLnN0cmluZ2lmeShjb25maWcua2V5KX1gKTtcbiAgICB9XG4gICAgLy8gQUxXQVlTIHRyeSB3aXRob3V0IGNyZWF0ZSwgYmVjYXVzZSB0aGUgc3NoZnMtd2luIHN1Y2tzIGFuZCBkb2Vzbid0IHN1cHBvcnQgYGNyZWF0ZTogdHJ1ZWA/IFd0Zi4uLlxuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBjb25maWcuaGFuZGxlLmdldEZpbGVIYW5kbGUoY29uZmlnLmtleSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAgIGlmICghY29uZmlnLmNyZWF0ZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIGF3YWl0IGNvbmZpZy5oYW5kbGUuZ2V0RmlsZUhhbmRsZShjb25maWcua2V5LCB7IGNyZWF0ZTogdHJ1ZSB9KTtcbn1cblxuZnVuY3Rpb24gd3JhcEhhbmRsZUZpbGVzKGhhbmRsZTogRGlyZWN0b3J5V3JhcHBlcik6IElTdG9yYWdlUmF3IHtcbiAgICByZXR1cm4ge1xuICAgICAgICBhc3luYyBnZXRJbmZvKGtleTogc3RyaW5nKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpbGUgPSBhd2FpdCBoYW5kbGUuZ2V0RmlsZUhhbmRsZShrZXkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpbGVDb250ZW50ID0gYXdhaXQgZmlsZS5nZXRGaWxlKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgc2l6ZTogZmlsZUNvbnRlbnQuc2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgbGFzdE1vZGlmaWVkOiBmaWxlQ29udGVudC5sYXN0TW9kaWZpZWQsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgYXN5bmMgZ2V0KGtleTogc3RyaW5nKTogUHJvbWlzZTxCdWZmZXIgfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZSA9IGF3YWl0IGhhbmRsZS5nZXRGaWxlSGFuZGxlKGtleSk7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZUNvbnRlbnQgPSBhd2FpdCBmaWxlLmdldEZpbGUoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhcnJheUJ1ZmZlciA9IGF3YWl0IGZpbGVDb250ZW50LmFycmF5QnVmZmVyKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGFycmF5QnVmZmVyKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBhc3luYyBhcHBlbmQoa2V5OiBzdHJpbmcsIHZhbHVlOiBCdWZmZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgICAgIGF3YWl0IGFwcGVuZFF1ZXVlKGtleSkoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIE5PVEU6IEludGVyZXN0aW5nIHBvaW50LiBDaHJvbWUgZG9lc24ndCBvcHRpbWl6ZSB0aGlzIHRvIGJlIGFuIGFwcGVuZCwgYW5kIGluc3RlYWRcbiAgICAgICAgICAgICAgICAvLyAgcmV3cml0ZXMgdGhlIGVudGlyZSBmaWxlLlxuICAgICAgICAgICAgICAgIGNvbnN0IGZpbGUgPSBhd2FpdCBmaXhlZEdldEZpbGVIYW5kbGUoeyBoYW5kbGUsIGtleSwgY3JlYXRlOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IHdyaXRhYmxlID0gYXdhaXQgZmlsZS5jcmVhdGVXcml0YWJsZSh7IGtlZXBFeGlzdGluZ0RhdGE6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgbGV0IG9mZnNldCA9IChhd2FpdCBmaWxlLmdldEZpbGUoKSkuc2l6ZTtcbiAgICAgICAgICAgICAgICBhd2FpdCB3cml0YWJsZS5zZWVrKG9mZnNldCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgd3JpdGFibGUud3JpdGUodmFsdWUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHdyaXRhYmxlLmNsb3NlKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSxcblxuICAgICAgICBhc3luYyBzZXQoa2V5OiBzdHJpbmcsIHZhbHVlOiBCdWZmZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgICAgIGNvbnN0IGZpbGUgPSBhd2FpdCBmaXhlZEdldEZpbGVIYW5kbGUoeyBoYW5kbGUsIGtleSwgY3JlYXRlOiB0cnVlIH0pO1xuICAgICAgICAgICAgY29uc3Qgd3JpdGFibGUgPSBhd2FpdCBmaWxlLmNyZWF0ZVdyaXRhYmxlKCk7XG4gICAgICAgICAgICBhd2FpdCB3cml0YWJsZS53cml0ZSh2YWx1ZSk7XG4gICAgICAgICAgICBhd2FpdCB3cml0YWJsZS5jbG9zZSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGFzeW5jIHJlbW92ZShrZXk6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICAgICAgYXdhaXQgaGFuZGxlLnJlbW92ZUVudHJ5KGtleSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgYXN5bmMgZ2V0S2V5cygpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgICAgICAgICBjb25zdCBrZXlzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgZm9yIGF3YWl0IChjb25zdCBbbmFtZSwgZW50cnldIG9mIGhhbmRsZSkge1xuICAgICAgICAgICAgICAgIGlmIChlbnRyeS5raW5kID09PSBcImZpbGVcIikge1xuICAgICAgICAgICAgICAgICAgICBrZXlzLnB1c2goZW50cnkubmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGtleXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgYXN5bmMgcmVzZXQoKSB7XG4gICAgICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IFtuYW1lLCBlbnRyeV0gb2YgaGFuZGxlKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgaGFuZGxlLnJlbW92ZUVudHJ5KGVudHJ5Lm5hbWUsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgIH07XG59XG5cbmZ1bmN0aW9uIHdyYXBIYW5kbGVOZXN0ZWQoaGFuZGxlOiBEaXJlY3RvcnlXcmFwcGVyKTogTmVzdGVkRmlsZVN0b3JhZ2Uge1xuICAgIHJldHVybiB7XG4gICAgICAgIGFzeW5jIGhhc0tleShrZXk6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBoYW5kbGUuZ2V0RGlyZWN0b3J5SGFuZGxlKGtleSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBhc3luYyBnZXRTdG9yYWdlKGtleTogc3RyaW5nKTogUHJvbWlzZTxGaWxlU3RvcmFnZT4ge1xuICAgICAgICAgICAgY29uc3Qgc3ViRGlyZWN0b3J5ID0gYXdhaXQgaGFuZGxlLmdldERpcmVjdG9yeUhhbmRsZShrZXksIHsgY3JlYXRlOiB0cnVlIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHdyYXBIYW5kbGUoc3ViRGlyZWN0b3J5KTtcbiAgICAgICAgfSxcblxuICAgICAgICBhc3luYyByZW1vdmVTdG9yYWdlKGtleTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgICAgICBhd2FpdCBoYW5kbGUucmVtb3ZlRW50cnkoa2V5LCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgfSxcblxuICAgICAgICBhc3luYyBnZXRLZXlzKCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAgICAgICAgIGNvbnN0IGtleXM6IHN0cmluZ1tdID0gW107XG4gICAgICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IFtuYW1lLCBlbnRyeV0gb2YgaGFuZGxlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVudHJ5LmtpbmQgPT09IFwiZGlyZWN0b3J5XCIpIHtcbiAgICAgICAgICAgICAgICAgICAga2V5cy5wdXNoKGVudHJ5Lm5hbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBrZXlzO1xuICAgICAgICB9LFxuICAgIH07XG59XG5cbmZ1bmN0aW9uIHdyYXBIYW5kbGUoaGFuZGxlOiBEaXJlY3RvcnlXcmFwcGVyKTogRmlsZVN0b3JhZ2Uge1xuICAgIHJldHVybiB7XG4gICAgICAgIC4uLndyYXBIYW5kbGVGaWxlcyhoYW5kbGUpLFxuICAgICAgICBmb2xkZXI6IHdyYXBIYW5kbGVOZXN0ZWQoaGFuZGxlKSxcbiAgICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiB0cnlUb0xvYWRQb2ludGVyKHBvaW50ZXI6IHN0cmluZykge1xuICAgIGxldCByZXN1bHQgPSBhd2FpdCBnZXRGaWxlU3lzdGVtUG9pbnRlcih7IHBvaW50ZXIgfSk7XG4gICAgaWYgKCFyZXN1bHQpIHJldHVybjtcbiAgICBsZXQgaGFuZGxlID0gYXdhaXQgcmVzdWx0Py5vblVzZXJBY3RpdmF0aW9uKCk7XG4gICAgaWYgKCFoYW5kbGUpIHJldHVybjtcbiAgICByZXR1cm4gaGFuZGxlIGFzIGFueSBhcyBEaXJlY3RvcnlXcmFwcGVyO1xufSJdfQ==
|
|
345
|
-
/* _JS_SOURCE_HASH = "2c171fd06df7fe1cfb75e04ee9f78c65385c23788b53f9fe0775b27670622e69"; */
|
|
786
|
+
exports.tryToLoadPointer = tryToLoadPointer;
|
|
787
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmlsZUZvbGRlckFQSS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIkZpbGVGb2xkZXJBUEkudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLG9EQUE0QjtBQUM1QiwyREFBNkc7QUFDN0csK0JBQWtDO0FBQ2xDLHVEQUFvRDtBQUNwRCx5REFBMEQ7QUFDMUQsNkNBQTBDO0FBRTFDLDJEQUEyRDtBQUMzRCxxRUFBaUU7QUFDakUsMkRBQW9HO0FBQ3BHLDRDQUFvQjtBQUNwQixnREFBd0I7QUFzQnhCLHVFQUF1RTtBQUN2RSx3RkFBd0Y7QUFDeEYsK0JBQStCO0FBQy9CLE1BQU0sY0FBYyxHQUFHLEtBQUssQ0FBQztBQUU3QixxR0FBcUc7QUFDckcsTUFBTSx1QkFBdUIsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBNEMxQyxJQUFJLFdBQVcsR0FBRyxJQUFBLGlCQUFVLEVBQUM7SUFDekIsRUFBRSxFQUFFLFNBQWlEO0NBQ3hELEVBQUUsU0FBUyxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7QUFFL0IsSUFBSSxVQUFVLEdBQUcsRUFBRSxDQUFDO0FBQ3BCLFNBQVMsYUFBYTtJQUNsQixJQUFJLENBQUMsVUFBVTtRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsNEpBQTRKLENBQUMsQ0FBQztJQUMvTCxPQUFPLFVBQVUsQ0FBQztBQUN0QixDQUFDO0FBQ0QsU0FBZ0IsYUFBYSxDQUFDLEdBQVc7SUFDckMsVUFBVSxHQUFHLEdBQUcsQ0FBQztBQUNyQixDQUFDO0FBRkQsc0NBRUM7QUFFRCwrRUFBK0U7QUFDL0Usa0ZBQWtGO0FBQ2xGLGtGQUFrRjtBQUNsRixpRkFBaUY7QUFDakYsbUZBQW1GO0FBQ25GLG1GQUFtRjtBQUNuRix5Q0FBeUM7QUFDekMsSUFBSSxtQkFBMEQsQ0FBQztBQUMvRCxTQUFnQixzQkFBc0IsQ0FBQyxNQUE2QztJQUNoRixtQkFBbUIsR0FBRyxNQUFNLENBQUM7QUFDakMs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O0lBQ3JELElBQUksQ0FBQyxNQUFNO1FBQUUsT0FBTztJQUNwQixJQUFJLE1BQU0sR0FBRyxNQUFNLENBQUEsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLGdCQUFnQixFQUFFLENBQUEsQ0FBQztJQUM5QyxJQUFJLENBQUMsTUFBTTtRQUFFLE9BQU87SUFDcEIsT0FBTyxNQUFpQyxDQUFDO0FBQzdDLENBQUM7QUFORCw0Q0FNQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwcmVhY3QgZnJvbSBcInByZWFjdFwiO1xuaW1wb3J0IHsgZmluZEdyYW50ZWRQb2ludGVySGFuZGxlLCBnZXRGaWxlU3lzdGVtUG9pbnRlciwgc3RvcmVGaWxlU3lzdGVtUG9pbnRlciB9IGZyb20gXCIuL2ZpbGVTeXN0ZW1Qb2ludGVyXCI7XG5pbXBvcnQgeyBvYnNlcnZhYmxlIH0gZnJvbSBcIm1vYnhcIjtcbmltcG9ydCB7IG9ic2VydmVyIH0gZnJvbSBcIi4uL3JlbmRlci11dGlscy9vYnNlcnZlclwiO1xuaW1wb3J0IHsgY2FjaGUsIGxhenkgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9jYWNoaW5nXCI7XG5pbXBvcnQgeyBjc3MsIGlzTm9kZSB9IGZyb20gXCJ0eXBlc2FmZWNzc1wiO1xuaW1wb3J0IHsgSVN0b3JhZ2VSYXcgfSBmcm9tIFwiLi9JU3RvcmFnZVwiO1xuaW1wb3J0IHsgcnVuSW5TZXJpYWwgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9iYXRjaGluZ1wiO1xuaW1wb3J0IHsgZ2V0RmlsZVN0b3JhZ2VJbmRleERCIH0gZnJvbSBcIi4vSW5kZXhlZERCRmlsZUZvbGRlckFQSVwiO1xuaW1wb3J0IHsgZ2V0UmVtb3RlRGlyZWN0b3J5SGFuZGxlLCB0ZXN0UmVtb3RlQ29ubmVjdGlvbiwgUmVtb3RlT3B0aW9ucyB9IGZyb20gXCIuL3JlbW90ZUZpbGVTdG9yYWdlXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5kZWNsYXJlIGdsb2JhbCB7XG4gICAgaW50ZXJmYWNlIFdpbmRvdyB7XG4gICAgICAgIHNob3dTYXZlRmlsZVBpY2tlcihjb25maWc/OiB7XG4gICAgICAgICAgICB0eXBlczoge1xuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBzdHJpbmc7IGFjY2VwdDogeyBbbWltZVR5cGU6IHN0cmluZ106IHN0cmluZ1tdIH1cbiAgICAgICAgICAgIH1bXTtcbiAgICAgICAgfSk6IFByb21pc2U8RmlsZVN5c3RlbUZpbGVIYW5kbGU+O1xuICAgICAgICBzaG93RGlyZWN0b3J5UGlja2VyKCk6IFByb21pc2U8RmlsZVN5c3RlbURpcmVjdG9yeUhhbmRsZT47XG4gICAgICAgIHNob3dPcGVuRmlsZVBpY2tlcihjb25maWc/OiB7XG4gICAgICAgICAgICB0eXBlczoge1xuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBzdHJpbmc7IGFjY2VwdDogeyBbbWltZVR5cGU6IHN0cmluZ106IHN0cmluZ1tdIH1cbiAgICAgICAgICAgIH1bXTtcbiAgICAgICAgfSk6IFByb21pc2U8RmlsZVN5c3RlbUZpbGVIYW5kbGVbXT47XG4gICAgfVxuICAgIGludGVyZmFjZSBGaWxlU3lzdGVtRGlyZWN0b3J5SGFuZGxlIHtcbiAgICAgICAgcmVxdWVzdFBlcm1pc3Npb24oY29uZmlnPzogeyBtb2RlOiBcInJlYWRcIiB8IFwicmVhZHdyaXRlXCIgfSk6IFByb21pc2U8UGVybWlzc2lvblN0YXRlPjtcbiAgICB9XG59XG5cblxuLy8gTk9URTogSW5kZXhlZERCIGlzIHJlcXVpcmVkIGZvciBpT1MsIGF0IGxlYXN0LiBXZSBNSUdIVCB3YW50IHRvIG1ha2Vcbi8vICB0aGlzIGEgdXNlciBzdXBwb3J0ZWQgdG9nZ2xlIHRvbywgc28gdGhleSBjYW4gY2hvb3NlIGR1cmluZyBydW50aW1lIGlmIHRoZXkgd2FudCBpdC5cbi8vIERPIE5PVCBlbmFibGUgdGhpcyBpcyBpc05vZGVcbmNvbnN0IFVTRV9JTkRFWEVEX0RCID0gZmFsc2U7XG5cbi8vIEhvdyBvZnRlbiBhIHdvcmtlciByZWNoZWNrcyB0aGUgcG9pbnRlciBJbmRleGVkREIgZm9yIGEgZ3JhbnRlZCBoYW5kbGUgd2hlbiBub25lIGlzIGF2YWlsYWJsZSB5ZXQuXG5jb25zdCBXT1JLRVJfUE9MTF9JTlRFUlZBTF9NUyA9IDYwICogMTAwMDtcblxuLy8gVGhlc2UgbWlycm9yIHRoZSBzdWJzZXQgb2YgdGhlIG5hdGl2ZSBGaWxlU3lzdGVtRmlsZUhhbmRsZSAvIEZpbGVTeXN0ZW1EaXJlY3RvcnlIYW5kbGUgQVBJIHdlIHVzZSwgc29cbi8vIHRoZSBuYXRpdmUgYnJvd3NlciBoYW5kbGVzLCB0aGUgTm9kZSBoYW5kbGVzLCBhbmQgdGhlIHJlbW90ZSBoYW5kbGVzIGFyZSBhbGwgaW50ZXJjaGFuZ2VhYmxlIOKAlCBhbmRcbi8vIGNvZGUgd3JpdHRlbiBhZ2FpbnN0IHRoZSBuYXRpdmUgaGFuZGxlIChlLmcuIGEgcmVjdXJzaXZlIHdhbGsgb3ZlciBgaGFuZGxlLmVudHJpZXMoKWApIHdvcmtzIG9uIGFueSBvZlxuLy8gdGhlbS4ga2luZC9uYW1lIGFuZCBlbnRyaWVzKCkgYXJlIHBhcnQgb2YgdGhhdCBjb250cmFjdC5cbmV4cG9ydCB0eXBlIEZpbGVXcmFwcGVyID0ge1xuICAgIHJlYWRvbmx5IGtpbmQ6IFwiZmlsZVwiO1xuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgICBnZXRGaWxlKCk6IFByb21pc2U8e1xuICAgICAgICBzaXplOiBudW1iZXI7XG4gICAgICAgIGxhc3RNb2RpZmllZDogbnVtYmVyO1xuICAgICAgICBhcnJheUJ1ZmZlcigpOiBQcm9taXNlPEFycmF5QnVmZmVyPjtcbiAgICAgICAgLy8gTWF0Y2hlcyBCbG9iLnNsaWNlICh3aGljaCB0aGUgbmF0aXZlIEZpbGUgb2JqZWN0IHByb3ZpZGVzKSwgc28gdGhlIGJyb3dzZXJcbiAgICAgICAgLy8gIGltcGxlbWVudGF0aW9uIHdvcmtzIHZhbmlsbGEuIEVuZCBpcyBleGNsdXNpdmUsIGJvdGggY2xhbXBlZCB0byB0aGUgZmlsZSBzaXplLlxuICAgICAgICBzbGljZShzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlcik6IHsgYXJyYXlCdWZmZXIoKTogUHJvbWlzZTxBcnJheUJ1ZmZlcj4gfTtcbiAgICB9PjtcbiAgICBjcmVhdGVXcml0YWJsZShjb25maWc/OiB7IGtlZXBFeGlzdGluZ0RhdGE/OiBib29sZWFuIH0pOiBQcm9taXNlPHtcbiAgICAgICAgc2VlayhvZmZzZXQ6IG51bWJlcik6IFByb21pc2U8dm9pZD47XG4gICAgICAgIHdyaXRlKHZhbHVlOiBCdWZmZXIpOiBQcm9taXNlPHZvaWQ+O1xuICAgICAgICBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+O1xuICAgIH0+O1xuICAgIC8vIFJldHVybnMgYSBVUkwgZm9yIHRoZSBmaWxlJ3MgYnl0ZXMsIHVzYWJsZSBpbiA8dmlkZW8+LzxpbWc+L2ZldGNoLiBPcHRpb25hbCDigJQgdGhlIG5hdGl2ZSBicm93c2VyXG4gICAgLy8gRmlsZVN5c3RlbUZpbGVIYW5kbGUgaGFzIG5vIHN1Y2ggbWV0aG9kLCBzbyBwcmVmZXIgdGhlIGdldEZpbGVVUkwoKSBoZWxwZXIsIHdoaWNoIGZhbGxzIGJhY2sgdG8gYVxuICAgIC8vIGJsb2I6IFVSTCB2aWEgY3JlYXRlT2JqZWN0VVJMIGZvciBuYXRpdmUgaGFuZGxlcy4gQWx3YXlzIHJlbGVhc2UgaXQgd2l0aCBkaXNwb3NlRmlsZVVSTCB3aGVuIGRvbmUuXG4gICAgZ2V0VVJMPygpOiBQcm9taXNlPHN0cmluZz47XG59O1xuZXhwb3J0IHR5cGUgRGlyZWN0b3J5V3JhcHBlciA9IHtcbiAgICByZWFkb25seSBraW5kOiBcImRpcmVjdG9yeVwiO1xuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgICAvLyBGdWxsIHBhdGggZnJvbSB0aGUgc3RvcmFnZSByb290LCBmb3IgZGlhZ25vc3RpY3MvbG9nZ2luZyAodGhlIG5hdGl2ZSBoYW5kbGUgZG9lc24ndCBleHBvc2UgcGF0aHMsXG4gICAgLy8gc28gaXQncyBvcHRpb25hbCkuIGUuZy4gXCJidWxrRGF0YWJhc2VzMi9teUNvbGxlY3Rpb25cIi5cbiAgICByZWFkb25seSBmdWxsUGF0aD86IHN0cmluZztcbiAgICAvLyBUcnVlIHdoZW4gdGhpcyBzdG9yYWdlIGlzIHNlcnZlZCBvdmVyIHRoZSBuZXR3b3JrIChhIHJlbW90ZSBzZXJ2ZXIpIHJhdGhlciB0aGFuIGEgbG9jYWwgZGlzaywgc29cbiAgICAvLyBjYWxsZXJzIGNhbiBhZGFwdCBmb3IgdGhlIGhpZ2hlciBsYXRlbmN5L2Nvc3QgKGxvY2FsL25hdGl2ZSBoYW5kbGVzIGxlYXZlIGl0IHVuZGVmaW5lZCA9IGZhbHNlKS5cbiAgICByZWFkb25seSBpc1JlbW90ZT86IGJvb2xlYW47XG4gICAgcmVtb3ZlRW50cnkoa2V5OiBzdHJpbmcsIG9wdGlvbnM/OiB7IHJlY3Vyc2l2ZT86IGJvb2xlYW4gfSk6IFByb21pc2U8dm9pZD47XG4gICAgZ2V0RmlsZUhhbmRsZShrZXk6IHN0cmluZywgb3B0aW9ucz86IHsgY3JlYXRlPzogYm9vbGVhbiB9KTogUHJvbWlzZTxGaWxlV3JhcHBlcj47XG4gICAgZ2V0RGlyZWN0b3J5SGFuZGxlKGtleTogc3RyaW5nLCBvcHRpb25zPzogeyBjcmVhdGU/OiBib29sZWFuIH0pOiBQcm9taXNlPERpcmVjdG9yeVdyYXBwZXI+O1xuICAgIC8vIEVhY2ggZW50cnkgSVMgYSBoYW5kbGUgKGZpbGUgb3IgZGlyZWN0b3J5KSwgc28gYSByZWN1cnNpdmUgd2FsayBrZWVwcyB3b3JraW5nIGF0IGV2ZXJ5IGxldmVsLlxuICAgIGVudHJpZXMoKTogQXN5bmNJdGVyYWJsZUl0ZXJhdG9yPFtzdHJpbmcsIEZpbGVXcmFwcGVyIHwgRGlyZWN0b3J5V3JhcHBlcl0+O1xuICAgIFtTeW1ib2wuYXN5bmNJdGVyYXRvcl0oKTogQXN5bmNJdGVyYWJsZUl0ZXJhdG9yPFtzdHJpbmcsIEZpbGVXcmFwcGVyIHwgRGlyZWN0b3J5V3JhcHBlcl0+O1xufTtcblxubGV0IGRpc3BsYXlEYXRhID0gb2JzZXJ2YWJsZSh7XG4gICAgdWk6IHVuZGVmaW5lZCBhcyB1bmRlZmluZWQgfCBwcmVhY3QuQ29tcG9uZW50Q2hpbGRyZW4sXG59LCB1bmRlZmluZWQsIHsgZGVlcDogZmFsc2UgfSk7XG5cbmxldCBmaWxlQVBJS2V5ID0gXCJcIjtcbmZ1bmN0aW9uIGdldEZpbGVBUElLZXkoKSB7XG4gICAgaWYgKCFmaWxlQVBJS2V5KSB0aHJvdyBuZXcgRXJyb3IoXCJNdXN0IGNhbGwgc2V0RmlsZUFQSUtleSBiZWZvcmUgdXNpbmcgZmlsZSBzeXN0ZW0uIEp1c3QgcGFzcyBhbnkga2V5LiBUaGlzIHByZXZlbnRzIHJldXNpbmcgdGhlIGZpbGUgc3lzdGVtIGFwaSB0aGF0IG90aGVyIGRldmVsb3BtZW50IGFwcHMgbWlnaHQgYmUgdXNpbmcuXCIpO1xuICAgIHJldHVybiBmaWxlQVBJS2V5O1xufVxuZXhwb3J0IGZ1bmN0aW9uIHNldEZpbGVBUElLZXkoa2V5OiBzdHJpbmcpIHtcbiAgICBmaWxlQVBJS2V5ID0ga2V5O1xufVxuXG4vLyBBIGRpcmVjdG9yeSBoYW5kbGUgdG8gc2VydmUgYXMgdGhlIHN0b3JhZ2Ugcm9vdCBpbnN0ZWFkIG9mIHJlc29sdmluZyBvbmUgdmlhXG4vLyB0aGUgcGlja2VyIC8gc3RvcmVkLXBvaW50ZXIgLyByZW1vdGUgZmxvdy4gU2V0IHRoaXMgaW4gYSBjb250ZXh0IHRoYXQgY2FuJ3QgcnVuXG4vLyB0aGUgaW50ZXJhY3RpdmUgcmVzb2x1dGlvbiDigJQgbW9zdCBpbXBvcnRhbnRseSBhIFdlYiBXb3JrZXIsIHdoaWNoIGhhcyBubyBET00gdG9cbi8vIHByb21wdCB3aXRoIGFuZCBubyBsb2NhbFN0b3JhZ2UgcG9pbnRlci4gVGhlIG93bmluZyB3aW5kb3cgcmVzb2x2ZXMgdGhlIGhhbmRsZVxuLy8gKHdpdGggaXRzIHBlcm1pc3Npb24gZ3JhbnQpIGFuZCBwb3N0TWVzc2FnZXMgaXQgaW47IHRoZSB3b3JrZXIgY2FsbHMgdGhpcyBiZWZvcmVcbi8vIHRvdWNoaW5nIGFueSBzdG9yYWdlLiBXaGVuIHNldCwgZ2V0RGlyZWN0b3J5SGFuZGxlIHJldHVybnMgaXQgZGlyZWN0bHkgYW5kIHNraXBzXG4vLyBldmVyeSBET00gLyBsb2NhbFN0b3JhZ2UgYnJhbmNoIGJlbG93LlxubGV0IHN0b3JhZ2VSb290T3ZlcnJpZGU6IEZpbGVTeXN0ZW1EaXJlY3RvcnlIYW5kbGUgfCB1bmRlZmluZWQ7XG5leHBvcnQgZnVuY3Rpb24gc2V0U3RvcmFnZVJvb3RPdmVycmlkZShoYW5kbGU6IEZpbGVTeXN0ZW1EaXJlY3RvcnlIYW5kbGUgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgICBzdG9yYWdlUm9vdE92ZXJyaWRlID0gaGFuZGxlO1xufVxuXG4vLyAtLS0tIHJlbW90ZSAoc2VydmVyKSBzdG9yYWdlIGNvbmZpZyAtLS0tXG4vLyBJbnN0ZWFkIG9mIGEgbG9jYWwgZm9sZGVyLCB0aGUgdXNlciBjYW4gcG9pbnQgYXQgYSByZW1vdGVGaWxlU2VydmVyLmpzIGluc3RhbmNlIChVUkwgKyBwYXNzd29yZCkuXG4vLyBXaGVuIGNvbmZpZ3VyZWQsIGdldEZpbGVTdG9yYWdlTmVzdGVkMiBzZXJ2ZXMgZXZlcnl0aGluZyBmcm9tIHRoYXQgc2VydmVyLiBQZXJzaXN0ZWQgaW4gbG9jYWxTdG9yYWdlLlxudHlwZSBSZW1vdGVDb25maWcgPSB7IHVybDogc3RyaW5nOyBwYXNzd29yZDogc3RyaW5nIH07XG5mdW5jdGlvbiByZW1vdGVDb25maWdLZXkoKSB7IHJldHVybiBnZXRGaWxlQVBJS2V5KCkgKyBcIjpyZW1vdGVcIjsgfVxuZnVuY3Rpb24gbG9hZFJlbW90ZUNvbmZpZygpOiBSZW1vdGVDb25maWcgfCB1bmRlZmluZWQge1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHMgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShyZW1vdGVDb25maWdLZXkoKSk7XG4gICAgICAgIGlmICghcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3QgYyA9IEpTT04ucGFyc2Uocyk7XG4gICAgICAgIGlmIChjICYmIHR5cGVvZiBjLnVybCA9PT0gXCJzdHJpbmdcIiAmJiB0eXBlb2YgYy5wYXNzd29yZCA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIGM7XG4gICAgfSBjYXRjaCB7IC8qIGlnbm9yZSAqLyB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIHNhdmVSZW1vdGVDb25maWcoYzogUmVtb3RlQ29uZmlnKSB7IGxvY2FsU3RvcmFnZS5zZXRJdGVtKHJlbW90ZUNvbmZpZ0tleSgpLCBKU09OLnN0cmluZ2lmeShjKSk7IH1cblxuLy8gVGhlIHNlcnZlciBpcyBhbHdheXMgSFRUUFMgb24gdGhlIGZpbGVob3N0ZXIncyBkZWZhdWx0IHBvcnQsIHNvIHRoZSB1c2VyIG9ubHkgbmVlZHMgdG8gdHlwZSB0aGUgaG9zdFxuLy8gKGUuZy4gXCI2NS4xMDkuOTMuMTEzXCIpLiBXZSBzdHJpcCBhbnkgc2NoZW1lL3BhdGggdGhleSBpbmNsdWRlIGFuZCBkZWZhdWx0IHRoZSBwb3J0IGlmIG9taXR0ZWQuXG5jb25zdCBERUZBVUxUX1JFTU9URV9QT1JUID0gODc4NzsgLy8gbWF0Y2hlcyByZW1vdGVGaWxlU2VydmVyLmpzJ3MgZGVmYXVsdFxuZnVuY3Rpb24gbm9ybWFsaXplU2VydmVyVXJsKHJhdzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBsZXQgcyA9IHJhdy50cmltKCkucmVwbGFjZSgvXlxcdys6XFwvXFwvLywgXCJcIikucmVwbGFjZSgvXFwvLiokLywgXCJcIik7XG4gICAgaWYgKCFzKSByZXR1cm4gXCJcIjtcbiAgICBpZiAoIS86XFxkKyQvLnRlc3QocykpIHMgKz0gXCI6XCIgKyBERUZBVUxUX1JFTU9URV9QT1JUO1xuICAgIHJldHVybiBcImh0dHBzOi8vXCIgKyBzO1xufVxuXG4vLyBPbmUgc2hhcmVkIHJlbW90ZSBEaXJlY3RvcnlXcmFwcGVyIChhbmQgdGhlcmVmb3JlIG9uZSBzaGFyZWQgcmFuZ2UgY2FjaGUpIHBlciByZW1vdGUgY29uZmlnLlxubGV0IHJlbW90ZUhhbmRsZTogeyBrZXk6IHN0cmluZzsgaGFuZGxlOiBEaXJlY3RvcnlXcmFwcGVyIH0gfCB1bmRlZmluZWQ7XG5mdW5jdGlvbiBnZXRSZW1vdGVIYW5kbGUocmVtb3RlOiBSZW1vdGVDb25maWcpOiBEaXJlY3RvcnlXcmFwcGVyIHtcbiAgICBjb25zdCBrZXkgPSByZW1vdGUudXJsICsgXCJcXDBcIiArIHJlbW90ZS5wYXNzd29yZDtcbiAgICBpZiAoIXJlbW90ZUhhbmRsZSB8fCByZW1vdGVIYW5kbGUua2V5ICE9PSBrZXkpIHtcbiAgICAgICAgcmVtb3RlSGFuZGxlID0geyBrZXksIGhhbmRsZTogZ2V0UmVtb3RlRGlyZWN0b3J5SGFuZGxlKHJlbW90ZS51cmwsIHJlbW90ZS5wYXNzd29yZCkgfTtcbiAgICB9XG4gICAgcmV0dXJuIHJlbW90ZUhhbmRsZS5oYW5kbGU7XG59XG5cbkBvYnNlcnZlclxuY2xhc3MgRGlyZWN0b3J5UHJvbXB0ZXIgZXh0ZW5kcyBwcmVhY3QuQ29tcG9uZW50IHtcbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGlmICghZGlzcGxheURhdGEudWkpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT17XG4gICAgICAgICAgICAgICAgY3NzLnBvc2l0aW9uKFwiZml4ZWRcIikucG9zKDAsIDApLnNpemUoXCIxMDB2d1wiLCBcIjEwMHZoXCIpXG4gICAgICAgICAgICAgICAgICAgIC56SW5kZXgoMjE0NzQ4MzY0NylcbiAgICAgICAgICAgICAgICAgICAgLmJhY2tncm91bmQoXCJ3aGl0ZVwiKVxuICAgICAgICAgICAgICAgICAgICAuY2VudGVyXG4gICAgICAgICAgICAgICAgICAgIC5mb250U2l6ZSg0MClcbiAgICAgICAgICAgIH0+XG4gICAgICAgICAgICAgICAge2Rpc3BsYXlEYXRhLnVpfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICk7XG4gICAgfVxufVxuXG4vLyBcIkNvbm5lY3QgdG8gYSBzZXJ2ZXJcIiBvcHRpb24gZm9yIHRoZSBkaXJlY3RvcnkgcHJvbXB0OiBjb2xsYXBzZXMgdG8gYSBidXR0b24sIGV4cGFuZHMgdG8gYWRkcmVzcyArXG4vLyBwYXNzd29yZCBmaWVsZHMuIE9uIGNvbm5lY3QgaXQgQUNUVUFMTFkgY29ubmVjdHMgKHRlc3RSZW1vdGVDb25uZWN0aW9uKTsgb25seSBvbiBzdWNjZXNzIGRvZXMgaXRcbi8vIHBlcnNpc3QgdGhlIGNvbmZpZyBhbmQgY2FsbCBvbkNvbm5lY3RlZCwgc28gdGhlIGNhbGxlciAoZ2V0RGlyZWN0b3J5SGFuZGxlKSByZXNvbHZlcyB3aXRoIGEgd29ya2luZ1xuLy8gcmVtb3RlIGhhbmRsZS4gRmFpbHVyZXMgYXJlIHNob3duIHRvIHRoZSB1c2VyIChhbmQgbG9nZ2VkLCB3aXRob3V0IHRoZSBwYXNzd29yZCksIG5ldmVyIHN3YWxsb3dlZC5cbi8vIGBpbml0aWFsYCBwcmUtZmlsbHMgKyBleHBhbmRzIHRoZSBmb3JtICh1c2VkIHRvIHJldHJ5IGEgcmVtZW1iZXJlZCBzZXJ2ZXIgdGhhdCBzdG9wcGVkIHdvcmtpbmcpLlxuQG9ic2VydmVyXG5jbGFzcyBTZXJ2ZXJDb25uZWN0Rm9ybSBleHRlbmRzIHByZWFjdC5Db21wb25lbnQ8eyBvbkNvbm5lY3RlZDogKGNvbmZpZzogUmVtb3RlQ29uZmlnKSA9PiB2b2lkOyBpbml0aWFsPzogUmVtb3RlQ29uZmlnIH0+IHtcbiAgICBwcml2YXRlIG9icyA9IG9ic2VydmFibGUoe1xuICAgICAgICBleHBhbmRlZDogISF0aGlzLnByb3BzLmluaXRpYWwsXG4gICAgICAgIHVybDogdGhpcy5wcm9wcy5pbml0aWFsPy51cmwgfHwgXCJcIixcbiAgICAgICAgcGFzc3dvcmQ6IHRoaXMucHJvcHMuaW5pdGlhbD8ucGFzc3dvcmQgfHwgXCJcIixcbiAgICAgICAgZXJyb3I6IFwiXCIsIGNvbm5lY3Rpbmc6IGZhbHNlLCBuZWVkc0NlcnQ6IGZhbHNlLCBzaG93UGFzc3dvcmQ6IGZhbHNlLFxuICAgIH0pO1xuICAgIHByaXZhdGUgY2xlYW5VcmwoKSB7IHJldHVybiBub3JtYWxpemVTZXJ2ZXJVcmwodGhpcy5vYnMudXJsKTsgfVxuICAgIHByaXZhdGUgY29ubmVjdCA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IHRoaXMub2JzO1xuICAgICAgICBzLmVycm9yID0gXCJcIjtcbiAgICAgICAgcy5uZWVkc0NlcnQgPSBmYWxzZTtcbiAgICAgICAgcy5jb25uZWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHRoaXMuY2xlYW5VcmwoKTtcbiAgICAgICAgICAgIGlmICghdXJsKSB7IHMuZXJyb3IgPSBcIkVudGVyIGEgc2VydmVyIGFkZHJlc3MuXCI7IHJldHVybjsgfVxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGVzdFJlbW90ZUNvbm5lY3Rpb24odXJsLCBzLnBhc3N3b3JkLnRyaW0oKSk7XG4gICAgICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJva1wiKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29uZmlnOiBSZW1vdGVDb25maWcgPSB7IHVybCwgcGFzc3dvcmQ6IHMucGFzc3dvcmQudHJpbSgpIH07XG4gICAgICAgICAgICAgICAgc2F2ZVJlbW90ZUNvbmZpZyhjb25maWcpOyAgICAgICAgICAgICAvLyByZW1lbWJlciBmb3IgbmV4dCBzZXNzaW9uXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkNvbm5lY3RlZChjb25maWcpOyAgICAgICAvLyBoYW5kIHRoZSB2ZXJpZmllZCBzZXJ2ZXIgYmFjayB0byBnZXREaXJlY3RvcnlIYW5kbGVcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJ1bmF1dGhvcml6ZWRcIikge1xuICAgICAgICAgICAgICAgIHMuZXJyb3IgPSBcIlRoZSBzZXJ2ZXIgcmVqZWN0ZWQgdGhhdCBwYXNzd29yZC5cIjtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiUmVtb3RlIGNvbm5lY3Q6IHVuYXV0aG9yaXplZCBmb3JcIiwgdXJsKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gR290IG5vdGhpbmcgYmFjayDigJQgdXN1YWxseSB0aGUgc2VsZi1zaWduZWQgY2VydGlmaWNhdGUgaXNuJ3QgdHJ1c3RlZCB5ZXQsIGJ1dCBzaG93IHRoZVxuICAgICAgICAgICAgICAgIC8vIGFjdHVhbCBlcnJvciB0b28gc28gYSB3cm9uZyBhZGRyZXNzIC8gZG93biBzZXJ2ZXIgLyBDT1JTIGlzc3VlIGlzIGRpYWdub3NhYmxlLlxuICAgICAgICAgICAgICAgIHMubmVlZHNDZXJ0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBzLmVycm9yID0gXCJDb3VsZG4ndCByZWFjaCB0aGUgc2VydmVyOiBcIiArIHJlc3VsdC5lcnJvcjtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiUmVtb3RlIGNvbm5lY3Q6IHVucmVhY2hhYmxlXCIsIHVybCwgXCItXCIsIHJlc3VsdC5lcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHMuZXJyb3IgPSBcIkNvbm5lY3Rpb24gZXJyb3I6IFwiICsgKChlIGFzIEVycm9yKS5tZXNzYWdlIHx8IFN0cmluZyhlKSk7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiUmVtb3RlIGNvbm5lY3QgdGhyZXc6XCIsIGUpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgcy5jb25uZWN0aW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJlbmRlcigpIHtcbiAgICAgICAgY29uc3QgcyA9IHRoaXMub2JzO1xuICAgICAgICBjb25zdCBpbnB1dENzcyA9IGNzcy5mb250U2l6ZSgyOCkucGFkMigyNCwgMTQpLndpZHRoKDU2MCkubWF4V2lkdGgoXCI4MHZ3XCIpO1xuICAgICAgICBjb25zdCBidG5Dc3MgPSBjc3MuZm9udFNpemUoMzIpLnBhZDIoNjAsIDMwKTtcbiAgICAgICAgaWYgKCFzLmV4cGFuZGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gPGJ1dHRvbiBjbGFzc05hbWU9e2J0bkNzc30gb25DbGljaz17KCkgPT4gcy5leHBhbmRlZCA9IHRydWV9PkNvbm5lY3QgdG8gYSBzZXJ2ZXI8L2J1dHRvbj47XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPXtjc3MudmJveCgxNikuY2VudGVyfT5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3NOYW1lPXtpbnB1dENzc30gcGxhY2Vob2xkZXI9XCJzZXJ2ZXIgYWRkcmVzcyAoZS5nLiA2NS4xMDkuOTMuMTEzLCBvciBob3N0OnBvcnQpXCIgdmFsdWU9e3MudXJsfVxuICAgICAgICAgICAgICAgICAgICBvbklucHV0PXtlID0+IHMudXJsID0gKGUudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpLnZhbHVlfSAvPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPXtjc3MuaGJveCgxMCkuY2VudGVyfT5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzTmFtZT17aW5wdXRDc3N9IHR5cGU9e3Muc2hvd1Bhc3N3b3JkID8gXCJ0ZXh0XCIgOiBcInBhc3N3b3JkXCJ9IHBsYWNlaG9sZGVyPVwicGFzc3dvcmQgKHNpeCB3b3JkcylcIiB2YWx1ZT17cy5wYXNzd29yZH1cbiAgICAgICAgICAgICAgICAgICAgICAgIG9uSW5wdXQ9e2UgPT4gcy5wYXNzd29yZCA9IChlLnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZX0gLz5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWU9e2Nzcy5mb250U2l6ZSgyMikucGFkMigyNCwgMTIpfSBvbkNsaWNrPXsoKSA9PiBzLnNob3dQYXNzd29yZCA9ICFzLnNob3dQYXNzd29yZH0+XG4gICAgICAgICAgICAgICAgICAgICAgICB7cy5zaG93UGFzc3dvcmQgPyBcIkhpZGVcIiA6IFwiU2hvd1wifVxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB7cy5lcnJvciA/IDxkaXYgY2xhc3NOYW1lPXtjc3MuZm9udFNpemUoMjIpLmNvbG9yKFwicmVkXCIpLm1heFdpZHRoKFwiODB2d1wiKX0+e3MuZXJyb3J9PC9kaXY+IDogbnVsbH1cbiAgICAgICAgICAgICAgICB7cy5uZWVkc0NlcnQgPyAoXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPXtjc3MudmJveCgxMCkuY2VudGVyLmZvbnRTaXplKDIwKS5tYXhXaWR0aCg2MjApLm1heFdpZHRoKFwiODB2d1wiKS50ZXh0QWxpZ24oXCJjZW50ZXJcIikuY29sb3IoXCJoc2woMCwgMCUsIDI1JSlcIil9PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5UaGlzIHNlcnZlciB1c2VzIGEgc2VsZi1zaWduZWQgY2VydGlmaWNhdGUsIHNvIHlvdXIgYnJvd3NlciBoYXMgdG8gdHJ1c3QgaXQgb25jZTo8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+MS4gT3BlbiB0aGUgc2VydmVyIGluIGEgbmV3IHRhYiAoYnV0dG9uIGJlbG93KS4gJm5ic3A7IDIuIEFjY2VwdCB0aGUgc2VjdXJpdHkgd2FybmluZyAoQWR2YW5jZWQg4oaSIFByb2NlZWQpLiAmbmJzcDsgMy4gQ29tZSBiYWNrIGFuZCBjbGljayBSZXRyeS48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3NOYW1lPXtjc3MuZm9udFNpemUoMjYpLnBhZDIoNDAsIDIwKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiB7IGNvbnN0IHUgPSB0aGlzLmNsZWFuVXJsKCk7IGlmICh1KSB3aW5kb3cub3Blbih1ICsgXCIvXCIsIFwiX2JsYW5rXCIpOyB9fT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVuIHNlcnZlciAmYW1wOyBhY2NlcHQgY2VydGlmaWNhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICApIDogbnVsbH1cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT17Y3NzLmhib3goMTYpfT5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWU9e2J0bkNzc30gZGlzYWJsZWQ9e3MuY29ubmVjdGluZ30gb25DbGljaz17dGhpcy5jb25uZWN0fT5cbiAgICAgICAgICAgICAgICAgICAgICAgIHtzLmNvbm5lY3RpbmcgPyBcIkNvbm5lY3RpbmfigKZcIiA6IHMubmVlZHNDZXJ0ID8gXCJSZXRyeVwiIDogXCJDb25uZWN0XCJ9XG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT17YnRuQ3NzfSBvbkNsaWNrPXsoKSA9PiB7IHMuZXhwYW5kZWQgPSBmYWxzZTsgcy5lcnJvciA9IFwiXCI7IHMubmVlZHNDZXJ0ID0gZmFsc2U7IH19PkJhY2s8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICApO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIE5vZGVKU0ZpbGVIYW5kbGVXcmFwcGVyIGltcGxlbWVudHMgRmlsZVdyYXBwZXIge1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZmlsZVBhdGg6IHN0cmluZykge1xuICAgIH1cbiAgICByZWFkb25seSBraW5kID0gXCJmaWxlXCIgYXMgY29uc3Q7XG4gICAgZ2V0IG5hbWUoKSB7IHJldHVybiBwYXRoLmJhc2VuYW1lKHRoaXMuZmlsZVBhdGgpOyB9XG5cbiAgICBhc3luYyBnZXRGaWxlKCkge1xuICAgICAgICBjb25zdCBzdGF0cyA9IGF3YWl0IGZzLnByb21pc2VzLnN0YXQodGhpcy5maWxlUGF0aCk7XG4gICAgICAgIGNvbnN0IGZpbGVQYXRoID0gdGhpcy5maWxlUGF0aDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNpemU6IHN0YXRzLnNpemUsXG4gICAgICAgICAgICBsYXN0TW9kaWZpZWQ6IHN0YXRzLm10aW1lTXMsXG4gICAgICAgICAgICBhcnJheUJ1ZmZlcjogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IGF3YWl0IGZzLnByb21pc2VzLnJlYWRGaWxlKGZpbGVQYXRoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYnVmZmVyLmJ1ZmZlci5zbGljZShidWZmZXIuYnl0ZU9mZnNldCwgYnVmZmVyLmJ5dGVPZmZzZXQgKyBidWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2xpY2U6IChzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlcikgPT4gKHtcbiAgICAgICAgICAgICAgICBhcnJheUJ1ZmZlcjogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjbGFtcGVkU3RhcnQgPSBNYXRoLm1pbihNYXRoLm1heChzdGFydCwgMCksIHN0YXRzLnNpemUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjbGFtcGVkRW5kID0gTWF0aC5taW4oTWF0aC5tYXgoZW5kLCBjbGFtcGVkU3RhcnQpLCBzdGF0cy5zaXplKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gY2xhbXBlZEVuZCAtIGNsYW1wZWRTdGFydDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlsZUhhbmRsZSA9IGF3YWl0IGZzLnByb21pc2VzLm9wZW4oZmlsZVBhdGgsIFwiclwiKTtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyhsZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgZmlsZUhhbmRsZS5yZWFkKGJ1ZmZlciwgMCwgbGVuZ3RoLCBjbGFtcGVkU3RhcnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlci5idWZmZXIuc2xpY2UoYnVmZmVyLmJ5dGVPZmZzZXQsIGJ1ZmZlci5ieXRlT2Zmc2V0ICsgYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgZmlsZUhhbmRsZS5jbG9zZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBhc3luYyBnZXRVUkwoKSB7XG4gICAgICAgIHJldHVybiBcImZpbGU6Ly9cIiArIHBhdGgucmVzb2x2ZSh0aGlzLmZpbGVQYXRoKTtcbiAgICB9XG5cbiAgICBhc3luYyBjcmVhdGVXcml0YWJsZShjb25maWc/OiB7IGtlZXBFeGlzdGluZ0RhdGE/OiBib29sZWFuIH0pIHtcbiAgICAgICAgbGV0IGZpbGVIYW5kbGU6IGZzLnByb21pc2VzLkZpbGVIYW5kbGU7XG4gICAgICAgIGNvbnN0IGZsYWdzID0gY29uZmlnPy5rZWVwRXhpc3RpbmdEYXRhID8gXCJyK1wiIDogXCJ3XCI7XG5cbiAgICAgICAgLy8gRW5zdXJlIHRoZSBkaXJlY3RvcnkgZXhpc3RzXG4gICAgICAgIGF3YWl0IGZzLnByb21pc2VzLm1rZGlyKHBhdGguZGlybmFtZSh0aGlzLmZpbGVQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgICAgICAgLy8gT3BlbiBvciBjcmVhdGUgdGhlIGZpbGVcbiAgICAgICAgaWYgKGNvbmZpZz8ua2VlcEV4aXN0aW5nRGF0YSAmJiBhd2FpdCBmcy5wcm9taXNlcy5hY2Nlc3ModGhpcy5maWxlUGF0aCkudGhlbigoKSA9PiB0cnVlKS5jYXRjaCgoKSA9PiBmYWxzZSkpIHtcbiAgICAgICAgICAgIGZpbGVIYW5kbGUgPSBhd2FpdCBmcy5wcm9taXNlcy5vcGVuKHRoaXMuZmlsZVBhdGgsIGZsYWdzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZpbGVIYW5kbGUgPSBhd2FpdCBmcy5wcm9taXNlcy5vcGVuKHRoaXMuZmlsZVBhdGgsIFwid1wiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBwb3NpdGlvbiA9IDA7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNlZWs6IGFzeW5jIChvZmZzZXQ6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gb2Zmc2V0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHdyaXRlOiBhc3luYyAodmFsdWU6IEJ1ZmZlcikgPT4ge1xuICAgICAgICAgICAgICAgIGF3YWl0IGZpbGVIYW5kbGUud3JpdGUodmFsdWUsIDAsIHZhbHVlLmxlbmd0aCwgcG9zaXRpb24pO1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uICs9IHZhbHVlLmxlbmd0aDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjbG9zZTogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGF3YWl0IGZpbGVIYW5kbGUuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBOb2RlSlNEaXJlY3RvcnlIYW5kbGVXcmFwcGVyIGltcGxlbWVudHMgRGlyZWN0b3J5V3JhcHBlciB7XG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSByb290UGF0aDogc3RyaW5nKSB7XG4gICAgfVxuICAgIHJlYWRvbmx5IGtpbmQgPSBcImRpcmVjdG9yeVwiIGFzIGNvbnN0O1xuICAgIGdldCBuYW1lKCkgeyByZXR1cm4gcGF0aC5iYXNlbmFtZSh0aGlzLnJvb3RQYXRoKTsgfVxuICAgIGdldCBmdWxsUGF0aCgpIHsgcmV0dXJuIHRoaXMucm9vdFBhdGg7IH1cbiAgICBlbnRyaWVzKCkgeyByZXR1cm4gdGhpc1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0oKTsgfVxuXG4gICAgYXN5bmMgcmVtb3ZlRW50cnkoa2V5OiBzdHJpbmcsIG9wdGlvbnM/OiB7IHJlY3Vyc2l2ZT86IGJvb2xlYW4gfSkge1xuICAgICAgICBjb25zdCBlbnRyeVBhdGggPSBwYXRoLmpvaW4odGhpcy5yb290UGF0aCwga2V5KTtcbiAgICAgICAgaWYgKG9wdGlvbnM/LnJlY3Vyc2l2ZSkge1xuICAgICAgICAgICAgYXdhaXQgZnMucHJvbWlzZXMucm0oZW50cnlQYXRoLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhd2FpdCBmcy5wcm9taXNlcy51bmxpbmsoZW50cnlQYXRoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIGdldEZpbGVIYW5kbGUoa2V5OiBzdHJpbmcsIG9wdGlvbnM/OiB7IGNyZWF0ZT86IGJvb2xlYW4gfSk6IFByb21pc2U8RmlsZVdyYXBwZXI+IHtcbiAgICAgICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4odGhpcy5yb290UGF0aCwga2V5KTtcblxuICAgICAgICBjb25zdCBleGlzdHMgPSBhd2FpdCBmcy5wcm9taXNlcy5hY2Nlc3MoZmlsZVBhdGgpLnRoZW4oKCkgPT4gdHJ1ZSkuY2F0Y2goKCkgPT4gZmFsc2UpO1xuXG4gICAgICAgIGlmICghZXhpc3RzICYmIG9wdGlvbnM/LmNyZWF0ZSkge1xuICAgICAgICAgICAgLy8gRW5zdXJlIHRoZSBkaXJlY3RvcnkgZXhpc3RzXG4gICAgICAgICAgICBhd2FpdCBmcy5wcm9taXNlcy5ta2RpcihwYXRoLmRpcm5hbWUoZmlsZVBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgZmlsZVxuICAgICAgICAgICAgYXdhaXQgZnMucHJvbWlzZXMud3JpdGVGaWxlKGZpbGVQYXRoLCBCdWZmZXIuYWxsb2MoMCkpO1xuICAgICAgICB9IGVsc2UgaWYgKCFleGlzdHMpIHtcbiAgICAgICAgICAgIC8vIFRhZyBhcyBFTk9FTlQgc28gcmVhZFdpdGhSZXRyeSB0cmVhdHMgaXQgYXMgYSBnZW51aW5lbHktbWlzc2luZyBmaWxlIChyZXR1cm4gdW5kZWZpbmVkIG5vdylcbiAgICAgICAgICAgIC8vIHJhdGhlciB0aGFuIGEgdHJhbnNpZW50IHJlYWQgZmFpbHVyZSB0byByZXRyeSA2w5cgd2l0aCBiYWNrb2ZmIOKAlCBtaXNzaW5nIGZpbGVzIGFyZSBub3JtYWxcbiAgICAgICAgICAgIC8vIChhIGNvbmN1cnJlbnQgbWVyZ2UgZGVsZXRlcyBhIGZpbGUgbWlkLXJlYWQpLCBhbmQgcmV0cnlpbmcgdGhlbSBpcyBjYXRhc3Ryb3BoaWNhbGx5IHNsb3cuXG4gICAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgRXJyb3IoYEZpbGUgbm90IGZvdW5kOiAke2ZpbGVQYXRofWApIGFzIEVycm9yICYgeyBjb2RlPzogc3RyaW5nIH07XG4gICAgICAgICAgICBlcnIuY29kZSA9IFwiRU5PRU5UXCI7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IE5vZGVKU0ZpbGVIYW5kbGVXcmFwcGVyKGZpbGVQYXRoKTtcbiAgICB9XG5cbiAgICBhc3luYyBnZXREaXJlY3RvcnlIYW5kbGUoa2V5OiBzdHJpbmcsIG9wdGlvbnM/OiB7IGNyZWF0ZT86IGJvb2xlYW4gfSk6IFByb21pc2U8RGlyZWN0b3J5V3JhcHBlcj4ge1xuICAgICAgICBjb25zdCBkaXJQYXRoID0gcGF0aC5qb2luKHRoaXMucm9vdFBhdGgsIGtleSk7XG5cbiAgICAgICAgaWYgKG9wdGlvbnM/LmNyZWF0ZSkge1xuICAgICAgICAgICAgYXdhaXQgZnMucHJvbWlzZXMubWtkaXIoZGlyUGF0aCwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBleGlzdHMgPSBhd2FpdCBmcy5wcm9taXNlcy5hY2Nlc3MoZGlyUGF0aCkudGhlbigoKSA9PiB0cnVlKS5jYXRjaCgoKSA9PiBmYWxzZSk7XG4gICAgICAgICAgICBpZiAoIWV4aXN0cykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRGlyZWN0b3J5IG5vdCBmb3VuZDogJHtkaXJQYXRofWApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBOb2RlSlNEaXJlY3RvcnlIYW5kbGVXcmFwcGVyKGRpclBhdGgpO1xuICAgIH1cblxuICAgIGFzeW5jICpbU3ltYm9sLmFzeW5jSXRlcmF0b3JdKCk6IEFzeW5jSXRlcmFibGVJdGVyYXRvcjxbc3RyaW5nLCBGaWxlV3JhcHBlciB8IERpcmVjdG9yeVdyYXBwZXJdPiB7XG4gICAgICAgIC8vIEVuc3VyZSBkaXJlY3RvcnkgZXhpc3RzXG4gICAgICAgIGF3YWl0IGZzLnByb21pc2VzLm1rZGlyKHRoaXMucm9vdFBhdGgsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuXG4gICAgICAgIGNvbnN0IGVudHJpZXMgPSBhd2FpdCBmcy5wcm9taXNlcy5yZWFkZGlyKHRoaXMucm9vdFBhdGgsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KTtcblxuICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkUGF0aCA9IHBhdGguam9pbih0aGlzLnJvb3RQYXRoLCBlbnRyeS5uYW1lKTtcbiAgICAgICAgICAgIGlmIChlbnRyeS5pc0ZpbGUoKSkge1xuICAgICAgICAgICAgICAgIHlpZWxkIFtlbnRyeS5uYW1lLCBuZXcgTm9kZUpTRmlsZUhhbmRsZVdyYXBwZXIoY2hpbGRQYXRoKV07XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCBbZW50cnkubmFtZSwgbmV3IE5vZGVKU0RpcmVjdG9yeUhhbmRsZVdyYXBwZXIoY2hpbGRQYXRoKV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cblxuLy8gV2hlbiBzZXQsIGdldERpcmVjdG9yeUhhbmRsZSBza2lwcyBldmVyeSBwcm9tcHQgKyByZW1vdGUgY2hlY2sgYW5kIHNlcnZlcyBmcm9tIHRoZSBicm93c2VyJ3MgT3JpZ2luXG4vLyBQcml2YXRlIEZpbGUgU3lzdGVtIChPUEZTKS4gT25lIG5hbWVkIHN1YmZvbGRlciBpcyBcImN1cnJlbnRcIiBwZXIgZmlsZUFQSUtleTsgcGlja1ByaXZhdGVGb2xkZXIgL1xuLy8gcmVzZXRTdG9yYWdlTG9jYXRpb24gc3dpdGNoIHdoaWNoIG9uZS4gU2V0IHRoaXMgaW4gYXBwIHN0YXJ0dXAgQkVGT1JFIHRoZSBmaXJzdCBnZXREaXJlY3RvcnlIYW5kbGUuXG5sZXQgb3Bmc0VuYWJsZWQgPSBmYWxzZTtcbmNvbnN0IE9QRlNfRk9MREVSU19ESVIgPSBcImZvbGRlcnNcIjtcbmNvbnN0IE9QRlNfREVGQVVMVF9GT0xERVIgPSBcImRlZmF1bHRcIjtcbmZ1bmN0aW9uIG9wZnNDdXJyZW50S2V5KCkgeyByZXR1cm4gZ2V0RmlsZUFQSUtleSgpICsgXCI6b3BmczpjdXJyZW50XCI7IH1cbmZ1bmN0aW9uIGdldEN1cnJlbnRPcGZzRm9sZGVyKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGxvY2FsU3RvcmFnZS5nZXRJdGVtKG9wZnNDdXJyZW50S2V5KCkpIHx8IE9QRlNfREVGQVVMVF9GT0xERVI7XG59XG5mdW5jdGlvbiBzZXRDdXJyZW50T3Bmc0ZvbGRlcihuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShvcGZzQ3VycmVudEtleSgpLCBuYW1lKTtcbn1cblxuLy8gU3dpdGNoZXMgZ2V0RGlyZWN0b3J5SGFuZGxlIHRvIHRoZSBPcmlnaW4gUHJpdmF0ZSBGaWxlIFN5c3RlbS4gTm8gZGlyZWN0b3J5IHBpY2tlciwgbm8gcGVybWlzc2lvblxuLy8gcHJvbXB0LCBubyByZW1vdGUgc2VydmVyIGNoZWNrLiBQZXJzaXN0cyBub3RoaW5nIOKAlCBjYWxsIG9uIGV2ZXJ5IGFwcCBzdGFydCBiZWZvcmUgcmVhZGluZyBzdG9yYWdlLlxuZXhwb3J0IGZ1bmN0aW9uIHVzZVByaXZhdGVGaWxlU3lzdGVtKCk6IHZvaWQge1xuICAgIG9wZnNFbmFibGVkID0gdHJ1ZTtcbn1cblxuLy8gV2hldGhlciB0aGUgT1BGUyBicmFuY2ggaXMgaW4gZWZmZWN0IChzbyBvdGhlciBjYWxsZXJzIGNhbiBhZGFwdCDigJQgZS5nLiBza2lwIHRoZSBcImZpbmQgZGF0YSBzdWJkaXJcIlxuLy8gaGFjayBpbiBnZXRGaWxlU3RvcmFnZU5lc3RlZDIgc2luY2UgT1BGUyBpcyBhbHdheXMgYSBjbGVhbiByb290IHdlIG93biBlbmQtdG8tZW5kKS5cbmV4cG9ydCBmdW5jdGlvbiBpc1ByaXZhdGVGaWxlU3lzdGVtQWN0aXZlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBvcGZzRW5hYmxlZDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0T3Bmc0ZvbGRlcnNEaXIoKTogUHJvbWlzZTxGaWxlU3lzdGVtRGlyZWN0b3J5SGFuZGxlPiB7XG4gICAgaWYgKCFuYXZpZ2F0b3Iuc3RvcmFnZT8uZ2V0RGlyZWN0b3J5KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlByaXZhdGUgRmlsZSBTeXN0ZW0gQWNjZXNzIEFQSSBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnJvd3NlclwiKTtcbiAgICB9XG4gICAgaWYgKGxvY2F0aW9uLnByb3RvY29sID09PSBcImZpbGU6XCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUHJpdmF0ZSBGaWxlIFN5c3RlbSBBUEkgaXMgZGlzYWxsb3dlZCBpbiBmaWxlOi8vIGxvY2F0aW9ucy4gSG9zdCBvbiBhbiBhY3R1YWwgb3JpZ2luLlwiKTtcbiAgICB9XG4gICAgY29uc3Qgcm9vdCA9IGF3YWl0IG5hdmlnYXRvci5zdG9yYWdlLmdldERpcmVjdG9yeSgpO1xuICAgIGNvbnN0IGtleWVkID0gYXdhaXQgcm9vdC5nZXREaXJlY3RvcnlIYW5kbGUoZ2V0RmlsZUFQSUtleSgpLCB7IGNyZWF0ZTogdHJ1ZSB9KTtcbiAgICByZXR1cm4gYXdhaXQga2V5ZWQuZ2V0RGlyZWN0b3J5SGFuZGxlKE9QRlNfRk9MREVSU19ESVIsIHsgY3JlYXRlOiB0cnVlIH0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRDdXJyZW50T3Bmc0hhbmRsZSgpOiBQcm9taXNlPERpcmVjdG9yeVdyYXBwZXI+IHtcbiAgICBjb25zdCBmb2xkZXJzID0gYXdhaXQgZ2V0T3Bmc0ZvbGRlcnNEaXIoKTtcbiAgICBjb25zdCBmb2xkZXIgPSBhd2FpdCBmb2xkZXJzLmdldERpcmVjdG9yeUhhbmRsZShnZXRDdXJyZW50T3Bmc0ZvbGRlcigpLCB7IGNyZWF0ZTogdHJ1ZSB9KTtcbiAgICByZXR1cm4gZm9sZGVyIGFzIHVua25vd24gYXMgRGlyZWN0b3J5V3JhcHBlcjtcbn1cblxuLy8gQWxsIHByZXZpb3VzbHktdXNlZCBPUEZTIHN1YmZvbGRlcnMgdW5kZXIgdGhpcyBmaWxlQVBJS2V5LCBzb3J0ZWQgYWxwaGFiZXRpY2FsbHkgKHRpbWVzdGFtcC1uYW1lZFxuLy8gYXV0by1nZW5lcmF0ZWQgZm9sZGVycyB0aGVyZWZvcmUgc29ydCBjaHJvbm9sb2dpY2FsbHkpLiBVc2UgdGhpcyB0byBzdXJmYWNlIGEgbGlzdCwgdGhlbiBjYWxsXG4vLyBwaWNrUHJpdmF0ZUZvbGRlcihuYW1lKSB0byBzd2l0Y2guXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbGlzdFByaXZhdGVGb2xkZXJzKCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBpZiAoIW5hdmlnYXRvci5zdG9yYWdlPy5nZXREaXJlY3RvcnkpIHJldHVybiBbXTtcbiAgICBsZXQgZm9sZGVyczogRmlsZVN5c3RlbURpcmVjdG9yeUhhbmRsZTtcbiAgICB0cnkgeyBmb2xkZXJzID0gYXdhaXQgZ2V0T3Bmc0ZvbGRlcnNEaXIoKTsgfSBjYXRjaCB7IHJldHVybiBbXTsgfVxuICAgIGNvbnN0IG5hbWVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGZvciBhd2FpdCAoY29uc3QgW25hbWUsIGhhbmRsZV0gb2YgKGZvbGRlcnMgYXMgdW5rbm93biBhcyBBc3luY0l0ZXJhYmxlPFtzdHJpbmcsIHsga2luZDogc3RyaW5nIH1dPikpIHtcbiAgICAgICAgaWYgKGhhbmRsZS5raW5kID09PSBcImRpcmVjdG9yeVwiKSBuYW1lcy5wdXNoKG5hbWUpO1xuICAgIH1cbiAgICByZXR1cm4gbmFtZXMuc29ydCgpO1xufVxuXG4vLyBTd2l0Y2ggdG8gYSBzcGVjaWZpYyBPUEZTIHN1YmZvbGRlciBhbmQgcmVsb2FkIHNvIGdldERpcmVjdG9yeUhhbmRsZSByZS1yZXNvbHZlcyB0byBpdC4gVGhlIGZvbGRlclxuLy8gaXMgY3JlYXRlZCBpZiBpdCBkb2Vzbid0IGV4aXN0IHlldC5cbmV4cG9ydCBmdW5jdGlvbiBwaWNrUHJpdmF0ZUZvbGRlcihuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBzZXRDdXJyZW50T3Bmc0ZvbGRlcihuYW1lKTtcbiAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7XG59XG5cbi8vIFJldHVybnMgdGhlIGRpcmVjdG9yeSBoYW5kbGUgdG8gdXNlIOKAlCBsb2NhbCAoTm9kZSAvIHBpY2tlZCBmb2xkZXIpIE9SIGEgcmVtb3RlIHNlcnZlciwgYm90aCBhcyB0aGVcbi8vIHNhbWUgRGlyZWN0b3J5V3JhcHBlciwgc28gY2FsbGVycyBkb24ndCBrbm93IG9yIGNhcmUgd2hpY2ggaXQgaXMuIEEgcmVtZW1iZXJlZCBzZXJ2ZXIgaXMgVkVSSUZJRURcbi8vICh3ZSBhY3R1YWxseSBjb25uZWN0KSBiZWZvcmUgdXNlOyBpZiBpdCBubyBsb25nZXIgd29ya3Mgd2UgcmUtcHJvbXB0LCBqdXN0IGxpa2UgYSBsb2NhbCBmb2xkZXIgd2hvc2Vcbi8vIHBlcm1pc3Npb24gd2FzIGxvc3QuIEJsb2NrcyB1bnRpbCByZWFkeSAob3IgdGhlIHVzZXIgZGlzbWlzc2VzLCB3aGljaCByZWplY3RzKS5cbmV4cG9ydCBjb25zdCBnZXREaXJlY3RvcnlIYW5kbGUgPSBsYXp5KGFzeW5jIGZ1bmN0aW9uIGdldERpcmVjdG9yeUhhbmRsZSgpOiBQcm9taXNlPERpcmVjdG9yeVdyYXBwZXI+IHtcbiAgICAvLyBBbiBpbmplY3RlZCByb290IChlLmcuIGEgV2ViIFdvcmtlciBoYW5kZWQgdGhlIGhhbmRsZSBieSBpdHMgb3duaW5nIHdpbmRvdylcbiAgICAvLyBzaG9ydC1jaXJjdWl0cyB0aGUgd2hvbGUgaW50ZXJhY3RpdmUgcmVzb2x1dGlvbiDigJQgbm8gcGlja2VyLCBubyBET00sIG5vXG4gICAgLy8gbG9jYWxTdG9yYWdlLiBNdXN0IGNvbWUgZmlyc3Qgc28gYSB3b3JrZXIgbmV2ZXIgcmVhY2hlcyB0aGUgYnJhbmNoZXMgYmVsb3cuXG4gICAgaWYgKHN0b3JhZ2VSb290T3ZlcnJpZGUpIHtcbiAgICAgICAgcmV0dXJuIHN0b3JhZ2VSb290T3ZlcnJpZGUgYXMgdW5rbm93biBhcyBEaXJlY3RvcnlXcmFwcGVyO1xuICAgIH1cbiAgICAvLyBBIHdvcmtlciBjYW4ndCBzaG93IHRoZSBwaWNrZXIgKG5vIERPTSAvIG5vIHVzZXIgYWN0aXZhdGlvbikgYW5kIGNhbid0IHJlYWQgbG9jYWxTdG9yYWdlLCBidXRcbiAgICAvLyBpdCBDQU4gb3BlbiB0aGUgcG9pbnRlciBJbmRleGVkREIgdGhlIG1haW4tdGhyZWFkIHBpY2tlciBwZXJzaXN0cyB0by4gUG9sbCBpdCBmb3IgYSBoYW5kbGVcbiAgICAvLyB3aG9zZSBwZXJtaXNzaW9uIGlzIGFscmVhZHkgZ3JhbnRlZDsgdGhlIG93bmluZyB3aW5kb3cgbWF5IGFsc28gcG9zdE1lc3NhZ2UgYSBoYW5kbGUgaW5cbiAgICAvLyBtaWQtcG9sbCAoY2hlY2tlZCBlYWNoIGl0ZXJhdGlvbikuIFRoaXMgaGFzIHRvIGNvbWUgYmVmb3JlIHRoZSBpc05vZGUgYnJhbmNoOiB0eXBlc2FmZWNzcydzXG4gICAgLy8gaXNOb2RlKCkgcmV0dXJucyB0cnVlIGluIHdvcmtlcnMgKHdpbmRvdyBpcyB1bmRlZmluZWQpLCBzbyBhIHdvcmtlciB3b3VsZCBvdGhlcndpc2UgZmFsbCBpbnRvXG4gICAgLy8gdGhlIE5vZGUgYnJhbmNoIGFuZCB0cnkgdG8gdXNlIGZzL3BhdGguXG4gICAgaWYgKFwiV29ya2VyR2xvYmFsU2NvcGVcIiBpbiBnbG9iYWxUaGlzKSB7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICBpZiAoc3RvcmFnZVJvb3RPdmVycmlkZSkgcmV0dXJuIHN0b3JhZ2VSb290T3ZlcnJpZGUgYXMgdW5rbm93biBhcyBEaXJlY3RvcnlXcmFwcGVyO1xuICAgICAgICAgICAgbGV0IGhhbmRsZSA9IGF3YWl0IGZpbmRHcmFudGVkUG9pbnRlckhhbmRsZShcInJlYWR3cml0ZVwiKTtcbiAgICAgICAgICAgIGlmIChoYW5kbGUpIHJldHVybiBoYW5kbGUgYXMgdW5rbm93biBhcyBEaXJlY3RvcnlXcmFwcGVyO1xuICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIFdPUktFUl9QT0xMX0lOVEVSVkFMX01TKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzTm9kZSgpKSB7XG4gICAgICAgIHJldHVybiBuZXcgTm9kZUpTRGlyZWN0b3J5SGFuZGxlV3JhcHBlcihwYXRoLnJlc29sdmUoXCIuL2RhdGEvXCIpKTtcbiAgICB9XG4gICAgaWYgKG9wZnNFbmFibGVkKSB7XG4gICAgICAgIHJldHVybiBnZXRDdXJyZW50T3Bmc0hhbmRsZSgpO1xuICAgIH1cblxuICAgIC8vIEEgc2VydmVyIGNvbm5lY3RlZCBpbiBhIHByZXZpb3VzIHNlc3Npb246IG9ubHkgcmV1c2UgaXQgaWYgaXQgc3RpbGwgYWN0dWFsbHkgd29ya3MuXG4gICAgY29uc3Qgc2F2ZWRSZW1vdGUgPSBsb2FkUmVtb3RlQ29uZmlnKCk7XG4gICAgaWYgKHNhdmVkUmVtb3RlKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRlc3RSZW1vdGVDb25uZWN0aW9uKHNhdmVkUmVtb3RlLnVybCwgc2F2ZWRSZW1vdGUucGFzc3dvcmQpO1xuICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJva1wiKSByZXR1cm4gZ2V0UmVtb3RlSGFuZGxlKHNhdmVkUmVtb3RlKTtcbiAgICAgICAgY29uc29sZS53YXJuKGBTYXZlZCByZW1vdGUgc2VydmVyIGRpZG4ndCBjb25uZWN0ICgke3Jlc3VsdC5zdGF0dXN9KSR7cmVzdWx0LnN0YXR1cyA9PT0gXCJ1bnJlYWNoYWJsZVwiID8gXCI6IFwiICsgcmVzdWx0LmVycm9yIDogXCJcIn0g4oCUIHJlLXByb21wdGluZy5gKTtcbiAgICB9XG5cbiAgICBsZXQgcm9vdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChyb290KTtcbiAgICBwcmVhY3QucmVuZGVyKDxEaXJlY3RvcnlQcm9tcHRlciAvPiwgcm9vdCk7XG4gICAgdHJ5IHtcbiAgICAgICAgbGV0IHJlc29sdmVIYW5kbGUhOiAoaDogRGlyZWN0b3J5V3JhcHBlcikgPT4gdm9pZDtcbiAgICAgICAgbGV0IHJlamVjdEhhbmRsZSE6IChlOiBFcnJvcikgPT4gdm9pZDtcbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IG5ldyBQcm9taXNlPERpcmVjdG9yeVdyYXBwZXI+KChyZXMsIHJlaikgPT4geyByZXNvbHZlSGFuZGxlID0gcmVzOyByZWplY3RIYW5kbGUgPSByZWo7IH0pO1xuXG4gICAgICAgIGNvbnN0IHBpY2tMb2NhbCA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaGFuZGxlID0gYXdhaXQgd2luZG93LnNob3dEaXJlY3RvcnlQaWNrZXIoKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBoYW5kbGUucmVxdWVzdFBlcm1pc3Npb24oeyBtb2RlOiBcInJlYWR3cml0ZVwiIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0b3JlZElkID0gYXdhaXQgc3RvcmVGaWxlU3lzdGVtUG9pbnRlcih7IG1vZGU6IFwicmVhZHdyaXRlXCIsIGhhbmRsZSB9KTtcbiAgICAgICAgICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShnZXRGaWxlQVBJS2V5KCksIHN0b3JlZElkKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlSGFuZGxlKGhhbmRsZSBhcyBhbnkpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJEaXJlY3RvcnkgcGljayBmYWlsZWQvY2FuY2VsbGVkOlwiLCBlKTsgLy8gc3RheSBvbiB0aGUgcHJvbXB0XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IG9uQ29ubmVjdGVkID0gKGNvbmZpZzogUmVtb3RlQ29uZmlnKSA9PiB7IHNhdmVSZW1vdGVDb25maWcoY29uZmlnKTsgcmVzb2x2ZUhhbmRsZShnZXRSZW1vdGVIYW5kbGUoY29uZmlnKSk7IH07XG4gICAgICAgIC8vIFRoZSB0aHJlZSBvcHRpb25zLCByZW5kZXJlZCBmcmVzaCBlYWNoIHRpbWUuIElmIGEgc2F2ZWQgc2VydmVyIGp1c3QgZmFpbGVkLCBwcmUtZmlsbCArIGV4cGFuZFxuICAgICAgICAvLyB0aGUgY29ubmVjdCBmb3JtIHNvIHRoZSB1c2VyIGNhbiByZXRyeSBvciBmaXggaXQuXG4gICAgICAgIGNvbnN0IHJlbmRlck9wdGlvbnMgPSAoKSA9PiAoXG4gICAgICAgICAgICA8PlxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3NOYW1lPXtjc3MuZm9udFNpemUoNDApLnBhZDIoODAsIDQwKX0gb25DbGljaz17cGlja0xvY2FsfT5QaWNrIERhdGEgRGlyZWN0b3J5PC9idXR0b24+XG4gICAgICAgICAgICAgICAgPFNlcnZlckNvbm5lY3RGb3JtIG9uQ29ubmVjdGVkPXtvbkNvbm5lY3RlZH0gaW5pdGlhbD17c2F2ZWRSZW1vdGV9IC8+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWU9e2Nzcy5mb250U2l6ZSg0MCkucGFkMig4MCwgNDApfVxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiByZWplY3RIYW5kbGUobmV3IEVycm9yKFwiVXNlciBkaXNtaXNzZWQgZmlsZSBzeXN0ZW0gYWNjZXNzIHByb21wdFwiKSl9PkRpc21pc3M8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvPlxuICAgICAgICApO1xuXG4gICAgICAgIC8vIEEgcHJldmlvdXNseS1waWNrZWQgbG9jYWwgZm9sZGVyOiB0cnkgdG8gcmVzdG9yZSBpdCAobWF5IG5lZWQgYSBjbGljaykuIFNraXBwZWQgd2hlbiBhIHNhdmVkXG4gICAgICAgIC8vIHNlcnZlciBmYWlsZWQg4oCUIHRoYXQgdXNlciB3YW50cyB0aGUgc2VydmVyLCBzbyBnbyBzdHJhaWdodCB0byB0aGUgKHByZS1maWxsZWQpIHByb21wdC5cbiAgICAgICAgY29uc3Qgc3RvcmVkSWQgPSAhc2F2ZWRSZW1vdGUgJiYgbG9jYWxTdG9yYWdlLmdldEl0ZW0oZ2V0RmlsZUFQSUtleSgpKTtcbiAgICAgICAgaWYgKHN0b3JlZElkKSB7XG4gICAgICAgICAgICBsZXQgZG9uZUxvYWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4geyBpZiAoIWRvbmVMb2FkKSBkaXNwbGF5RGF0YS51aSA9IFwiQ2xpY2sgYW55d2hlcmUgdG8gYWxsb3cgZmlsZSBzeXN0ZW0gYWNjZXNzXCI7IH0sIDUwMCk7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZSA9IGF3YWl0IHRyeVRvTG9hZFBvaW50ZXIoc3RvcmVkSWQpO1xuICAgICAgICAgICAgICAgIGRvbmVMb2FkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBpZiAoaGFuZGxlKSByZXR1cm4gaGFuZGxlO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGRvbmVMb2FkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1zZyA9IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFN0cmluZyhlKTtcbiAgICAgICAgICAgICAgICBpZiAobXNnLmluY2x1ZGVzKFwidXNlciBhY3RpdmF0aW9uXCIpIHx8IG1zZy5pbmNsdWRlcyhcIlVzZXIgYWN0aXZhdGlvblwiKSkge1xuICAgICAgICAgICAgICAgICAgICBkaXNwbGF5RGF0YS51aSA9IChcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPXtjc3MudmJveCgyMCkuY2VudGVyfT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT17Y3NzLmZvbnRTaXplKDQwKS5wYWQyKDgwLCA0MCl9IG9uQ2xpY2s9e2FzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheURhdGEudWkgPSBcIkxvYWRpbmcuLi5cIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGggPSBhd2FpdCB0cnlUb0xvYWRQb2ludGVyKHN0b3JlZElkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoKSB7IHJlc29sdmVIYW5kbGUoaCk7IHJldHVybjsgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChyZXRyeUVycm9yKSB7IGNvbnNvbGUuZXJyb3IoXCJSZXRyeSBmYWlsZWQ6XCIsIHJldHJ5RXJyb3IpOyB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXlEYXRhLnVpID0gPGRpdiBjbGFzc05hbWU9e2Nzcy52Ym94KDIwKS5jZW50ZXJ9PntyZW5kZXJPcHRpb25zKCl9PC9kaXY+O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19PkNsaWNrIHRvIHJlc3RvcmUgZmlsZSBzeXN0ZW0gYWNjZXNzPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3JlbmRlck9wdGlvbnMoKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgcHJvbWlzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZGlzcGxheURhdGEudWkgPSA8ZGl2IGNsYXNzTmFtZT17Y3NzLnZib3goMjApLmNlbnRlcn0+e3JlbmRlck9wdGlvbnMoKX08L2Rpdj47XG4gICAgICAgIHJldHVybiBhd2FpdCBwcm9taXNlO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIHByZWFjdC5yZW5kZXIobnVsbCwgcm9vdCk7XG4gICAgICAgIHJvb3QucmVtb3ZlKCk7XG4gICAgfVxufSk7XG5cbmV4cG9ydCBjb25zdCBnZXRGaWxlU3RvcmFnZU5lc3RlZCA9IGNhY2hlKGFzeW5jIGZ1bmN0aW9uIGdldEZpbGVTdG9yYWdlKHBhdGg6IHN0cmluZyk6IFByb21pc2U8RmlsZVN0b3JhZ2U+IHtcbiAgICBsZXQgYmFzZSA9IGF3YWl0IGdldERpcmVjdG9yeUhhbmRsZSgpO1xuICAgIGZvciAobGV0IHBhcnQgb2YgcGF0aC5zcGxpdChcIi9cIikpIHtcbiAgICAgICAgaWYgKCFwYXJ0KSBjb250aW51ZTtcbiAgICAgICAgYmFzZSA9IGF3YWl0IGJhc2UuZ2V0RGlyZWN0b3J5SGFuZGxlKHBhcnQsIHsgY3JlYXRlOiB0cnVlIH0pO1xuICAgIH1cbiAgICByZXR1cm4gd3JhcEhhbmRsZShiYXNlKTtcbn0pO1xuLy8gU3VwcG9ydHMgaWYgdGhlIHVzZXIgc2VsZWN0cyB0aGUgZm9sZGVyIHRoYXQgY29udGFpbnMgdGhlIGRhdGEgZm9sZGVyIG9yIHRoZSBkYXRhIGZvbGRlciBkaXJlY3RseS4gSWYgcGF0aFN0ciBpcyBhbiBhYnNvbHV0ZSBwYXRoIChhbmQgd2UncmUgaW4gbm9kZWpzKSB3ZSB1c2UgaXQgZGlyZWN0bHkuXG5leHBvcnQgY29uc3QgZ2V0RmlsZVN0b3JhZ2VOZXN0ZWQyID0gY2FjaGUoYXN5bmMgZnVuY3Rpb24gZ2V0RmlsZVN0b3JhZ2UocGF0aFN0cjogc3RyaW5nKTogUHJvbWlzZTxGaWxlU3RvcmFnZT4ge1xuICAgIGxldCBiYXNlOiBEaXJlY3RvcnlXcmFwcGVyO1xuICAgIHBhdGhTdHIgPSBwYXRoU3RyLnJlcGxhY2VBbGwoXCJcXFxcXCIsIFwiL1wiKTtcbiAgICBpZiAoaXNOb2RlKCkpIHtcbiAgICAgICAgaWYgKHBhdGguaXNBYnNvbHV0ZShwYXRoU3RyKSkge1xuICAgICAgICAgICAgcmV0dXJuIHdyYXBIYW5kbGUobmV3IE5vZGVKU0RpcmVjdG9yeUhhbmRsZVdyYXBwZXIocGF0aFN0cikpO1xuICAgICAgICB9XG4gICAgICAgIGJhc2UgPSBuZXcgTm9kZUpTRGlyZWN0b3J5SGFuZGxlV3JhcHBlcihwYXRoLnJlc29sdmUoXCIuL2RhdGEvXCIpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBiYXNlID0gYXdhaXQgZ2V0RGlyZWN0b3J5SGFuZGxlKCk7XG4gICAgICAgIC8vIFNraXAgdGhlIFwiZmluZCBkYXRhIHN1YmRpclwiIGhhY2sgdW5kZXIgT1BGUyDigJQgdGhhdCdzIGZvciBwaWNrZWQgZGlyZWN0b3JpZXMgd2hlcmUgdGhlIHVzZXJcbiAgICAgICAgLy8gbWlnaHQgaGF2ZSBzZWxlY3RlZCBhIGZvbGRlciB3aXRoIHVucmVsYXRlZCBmaWxlczsgT1BGUyBpcyBhIGNsZWFuIHJvb3Qgd2Ugb3duIGVuZC10by1lbmQuXG4gICAgICAgIGlmICghb3Bmc0VuYWJsZWQpIHtcbiAgICAgICAgICAgIGxldCBkaXJzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgbGV0IGFsbHM6IHN0cmluZ1tdID0gW107XG4gICAgICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IFtuYW1lLCBlbnRyeV0gb2YgYmFzZSkge1xuICAgICAgICAgICAgICAgIGlmIChlbnRyeS5raW5kID09PSBcImRpcmVjdG9yeVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpcnMucHVzaChuYW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYWxscy5wdXNoKG5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gSEFDSzogSWYgdGhlcmUgYXJlIGVub3VnaCBmaWxlcywgaXQncyBhbG1vc3QgY2VydGFpbmx5IG5vdCBhIGRpcmVjdG9yeSB0aGF0IGNvbnRhaW5zIGNvbGxlY3Rpb25zLiBJdCdzIHByb2JhYmx5IHRoZSB1c2VyJ3MgZGF0YSBpbnN0ZWFkXG4gICAgICAgICAgICBpZiAoZGlycy5pbmNsdWRlcyhcIi5naXRcIikgfHwgZGlycy5pbmNsdWRlcyhcImRhdGFcIikgfHwgYWxscy5sZW5ndGggPiAxMDApIHtcbiAgICAgICAgICAgICAgICBiYXNlID0gYXdhaXQgYmFzZS5nZXREaXJlY3RvcnlIYW5kbGUoXCJkYXRhXCIsIHsgY3JlYXRlOiB0cnVlIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGZvciAobGV0IHBhcnQgb2YgcGF0aFN0ci5zcGxpdChcIi9cIikpIHtcbiAgICAgICAgaWYgKCFwYXJ0KSBjb250aW51ZTtcbiAgICAgICAgYmFzZSA9IGF3YWl0IGJhc2UuZ2V0RGlyZWN0b3J5SGFuZGxlKHBhcnQsIHsgY3JlYXRlOiB0cnVlIH0pO1xuICAgIH1cbiAgICByZXR1cm4gd3JhcEhhbmRsZShiYXNlKTtcbn0pO1xuZXhwb3J0IGNvbnN0IGdldEZpbGVTdG9yYWdlID0gbGF6eShhc3luYyBmdW5jdGlvbiBnZXRGaWxlU3RvcmFnZSgpOiBQcm9taXNlPEZpbGVTdG9yYWdlPiB7XG4gICAgaWYgKFVTRV9JTkRFWEVEX0RCKSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBnZXRGaWxlU3RvcmFnZUluZGV4REIoKTtcbiAgICB9XG4gICAgbGV0IGhhbmRsZSA9IGF3YWl0IGdldERpcmVjdG9yeUhhbmRsZSgpO1xuICAgIHJldHVybiB3cmFwSGFuZGxlKGhhbmRsZSk7XG59KTtcbmV4cG9ydCBmdW5jdGlvbiByZXNldFN0b3JhZ2VMb2NhdGlvbigpIHtcbiAgICBpZiAob3Bmc0VuYWJsZWQpIHtcbiAgICAgICAgLy8gRG9uJ3QgZGVsZXRlIHByZXZpb3VzIGZvbGRlciDigJQgbGlzdFByaXZhdGVGb2xkZXJzIC8gcGlja1ByaXZhdGVGb2xkZXIgc3RpbGwgbmVlZCBpdC4gSnVzdCBwb2ludFxuICAgICAgICAvLyBcImN1cnJlbnRcIiBhdCBhIGZyZXNoIHRpbWVzdGFtcC1uYW1lZCBvbmUgc28gdGhlIG5leHQgcmVsb2FkIHN0YXJ0cyBjbGVhbi5cbiAgICAgICAgc2V0Q3VycmVudE9wZnNGb2xkZXIobmV3IERhdGUoKS50b0lTT1N0cmluZygpLnJlcGxhY2UoL1s6Ll0vZywgXCItXCIpKTtcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGdldEZpbGVBUElLZXkoKSk7XG4gICAgdHJ5IHsgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0ocmVtb3RlQ29uZmlnS2V5KCkpOyB9IGNhdGNoIHsgLyogaWdub3JlICovIH1cbiAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7XG59XG5cbmV4cG9ydCB0eXBlIE5lc3RlZEZpbGVTdG9yYWdlID0ge1xuICAgIGhhc0tleShrZXk6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj47XG4gICAgZ2V0U3RvcmFnZShrZXk6IHN0cmluZyk6IFByb21pc2U8RmlsZVN0b3JhZ2U+O1xuICAgIHJlbW92ZVN0b3JhZ2Uoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+O1xuICAgIGdldEtleXMoaW5jbHVkZUZvbGRlcnM/OiBib29sZWFuKTogUHJvbWlzZTxzdHJpbmdbXT47XG59O1xuXG5leHBvcnQgdHlwZSBGaWxlU3RvcmFnZSA9IElTdG9yYWdlUmF3ICYge1xuICAgIGZvbGRlcjogTmVzdGVkRmlsZVN0b3JhZ2U7XG4gICAgLy8gTWlycm9ycyBEaXJlY3RvcnlXcmFwcGVyLmlzUmVtb3RlOiB0cnVlIHdoZW4gdGhpcyBzdG9yYWdlIGlzIHNlcnZlZCBvdmVyIHRoZSBuZXR3b3JrLiBMZXRzIGNhbGxlcnNcbiAgICAvLyAoZS5nLiBCdWxrRGF0YWJhc2UyLCB3aGljaCBza2lwcyBhdXRvbWF0aWMgY29tcGFjdGlvbiBvdmVyIHRoZSBuZXR3b3JrIGJ5IGRlZmF1bHQpIGFkYXB0LlxuICAgIGlzUmVtb3RlPzogYm9vbGVhbjtcbn07XG5cbmxldCBhcHBlbmRRdWV1ZSA9IGNhY2hlKChrZXk6IHN0cmluZykgPT4ge1xuICAgIHJldHVybiBydW5JblNlcmlhbCgoZm5jOiAoKSA9PiBQcm9taXNlPHZvaWQ+KSA9PiBmbmMoKSk7XG59KTtcblxuXG5hc3luYyBmdW5jdGlvbiBmaXhlZEdldEZpbGVIYW5kbGUoY29uZmlnOiB7XG4gICAgaGFuZGxlOiBEaXJlY3RvcnlXcmFwcGVyO1xuICAgIGtleTogc3RyaW5nO1xuICAgIGNyZWF0ZTogdHJ1ZTtcbn0pOiBQcm9taXNlPEZpbGVXcmFwcGVyPjtcbmFzeW5jIGZ1bmN0aW9uIGZpeGVkR2V0RmlsZUhhbmRsZShjb25maWc6IHtcbiAgICBoYW5kbGU6IERpcmVjdG9yeVdyYXBwZXI7XG4gICAga2V5OiBzdHJpbmc7XG4gICAgY3JlYXRlPzogYm9vbGVhbjtcbn0pOiBQcm9taXNlPEZpbGVXcmFwcGVyIHwgdW5kZWZpbmVkPjtcbmFzeW5jIGZ1bmN0aW9uIGZpeGVkR2V0RmlsZUhhbmRsZShjb25maWc6IHtcbiAgICBoYW5kbGU6IERpcmVjdG9yeVdyYXBwZXI7XG4gICAga2V5OiBzdHJpbmc7XG4gICAgY3JlYXRlPzogYm9vbGVhbjtcbn0pOiBQcm9taXNlPEZpbGVXcmFwcGVyIHwgdW5kZWZpbmVkPiB7XG4gICAgaWYgKGNvbmZpZy5rZXkuaW5jbHVkZXMoXCIvXCIpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHVzZSBmb2xkZXJzIGRpcmVjdGx5IGluIGZpbGUgc3lzdGVtIHJlYWQgLyB3cml0ZXMuIFVzZSBhIHdyYXBwZXIgd2hpY2ggaGFuZGxlcyB0aGUgZm9sZGVyIG5hdmlnYXRpb24uIFBhdGggd2FzICR7SlNPTi5zdHJpbmdpZnkoY29uZmlnLmtleSl9YCk7XG4gICAgfVxuICAgIC8vIEFMV0FZUyB0cnkgd2l0aG91dCBjcmVhdGUsIGJlY2F1c2UgdGhlIHNzaGZzLXdpbiBzdWNrcyBhbmQgZG9lc24ndCBzdXBwb3J0IGBjcmVhdGU6IHRydWVgPyBXdGYuLi5cbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgY29uZmlnLmhhbmRsZS5nZXRGaWxlSGFuZGxlKGNvbmZpZy5rZXkpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgICBpZiAoIWNvbmZpZy5jcmVhdGUpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBhd2FpdCBjb25maWcuaGFuZGxlLmdldEZpbGVIYW5kbGUoY29uZmlnLmtleSwgeyBjcmVhdGU6IHRydWUgfSk7XG59XG5cbi8vIEEgZmlsZSB0aGF0IGdlbnVpbmVseSBkb2VzIG5vdCBleGlzdC4gV2UgbXVzdCBOT1QgcmV0cnkgdGhlc2UsIG90aGVyd2lzZSByZWFkaW5nIG1hbnkgbWlzc2luZ1xuLy8gZmlsZXMgKGEgY29tbW9uIHBhdHRlcm4pIGdldHMgY2F0YXN0cm9waGljYWxseSBzbG93LlxuZnVuY3Rpb24gaXNNaXNzaW5nRXJyb3IoZXJyb3I6IHVua25vd24pOiBib29sZWFuIHtcbiAgICBsZXQgbmFtZSA9IChlcnJvciBhcyB7IG5hbWU/OiBzdHJpbmcgfSk/Lm5hbWU7XG4gICAgbGV0IGNvZGUgPSAoZXJyb3IgYXMgeyBjb2RlPzogc3RyaW5nIH0pPy5jb2RlO1xuICAgIHJldHVybiBuYW1lID09PSBcIk5vdEZvdW5kRXJyb3JcIiB8fCBjb2RlID09PSBcIkVOT0VOVFwiO1xufVxuXG5jb25zdCBNQVhfUkVBRF9SRVRSSUVTID0gNjtcblxuLy8gVGhlIGJyb3dzZXIgRmlsZSBTeXN0ZW0gQWNjZXNzIEFQSSBjYW4gdHJhbnNpZW50bHkgZmFpbCByZWFkcyB1bmRlciBoZWF2eSBsb2FkIChpdCBhcHBlYXJzIHRvXG4vLyB0aHJvdHRsZSB3aGVuIGEgcGFnZSBpc3N1ZXMgbWFueSByZWFkcyBhdCBvbmNlKS4gVGhvc2UgZmFpbHVyZXMgc3VyZmFjZSBhcyBlcnJvcnMgT1RIRVIgdGhhblxuLy8gXCJub3QgZm91bmRcIiwgc28gd2UgcmV0cnkgdGhlbSB3aXRoIGJhY2tvZmYuIEEgcmVhbCBtaXNzaW5nIGZpbGUgKE5vdEZvdW5kRXJyb3IgLyBFTk9FTlQpIHJldHVybnNcbi8vIHVuZGVmaW5lZCBpbW1lZGlhdGVseSB3aXRoIG5vIHJldHJ5LlxuYXN5bmMgZnVuY3Rpb24gcmVhZFdpdGhSZXRyeTxUPihsYWJlbDogc3RyaW5nLCBrZXk6IHN0cmluZywgcmVhZDogKCkgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VCB8IHVuZGVmaW5lZD4ge1xuICAgIGxldCBiYWNrb2ZmID0gMjU7XG4gICAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IDsgYXR0ZW1wdCsrKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgcmVhZCgpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgaWYgKGlzTWlzc2luZ0Vycm9yKGVycm9yKSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGxldCBuYW1lID0gKGVycm9yIGFzIHsgbmFtZT86IHN0cmluZyB9KT8ubmFtZSB8fCBcIkVycm9yXCI7XG4gICAgICAgICAgICBsZXQgbWVzc2FnZSA9IChlcnJvciBhcyB7IG1lc3NhZ2U/OiBzdHJpbmcgfSk/Lm1lc3NhZ2UgfHwgU3RyaW5nKGVycm9yKTtcbiAgICAgICAgICAgIGlmIChhdHRlbXB0ID49IE1BWF9SRUFEX1JFVFJJRVMpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYCR7bGFiZWx9IGdhdmUgdXAgb24gJHtKU09OLnN0cmluZ2lmeShrZXkpfSBhZnRlciAke2F0dGVtcHR9IHJldHJpZXMgKCR7bmFtZX0pOiAke21lc3NhZ2Uuc2xpY2UoMCwgMjAwKX1gKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc29sZS53YXJuKGAke2xhYmVsfSByZXRyeWluZyAke0pTT04uc3RyaW5naWZ5KGtleSl9IChhdHRlbXB0ICR7YXR0ZW1wdCArIDF9LCAke25hbWV9KTogJHttZXNzYWdlLnNsaWNlKDAsIDIwMCl9YCk7XG4gICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgYmFja29mZikpO1xuICAgICAgICAgICAgYmFja29mZiA9IE1hdGgubWluKGJhY2tvZmYgKiAyLCAxMDAwKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gd3JhcEhhbmRsZUZpbGVzKGhhbmRsZTogRGlyZWN0b3J5V3JhcHBlcik6IElTdG9yYWdlUmF3IHtcbiAgICAvLyBMb2cgdGhlIGZ1bGwgcGF0aCAocm9vdCArIGZpbGVuYW1lKSB3aGVuIGF2YWlsYWJsZSwgc28gYSBmYWlsaW5nIGZpbGUgaXMgaWRlbnRpZmlhYmxlLlxuICAgIGNvbnN0IHBhdGhPZiA9IChrZXk6IHN0cmluZykgPT4gaGFuZGxlLmZ1bGxQYXRoID8gaGFuZGxlLmZ1bGxQYXRoICsgXCIvXCIgKyBrZXkgOiBrZXk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYXN5bmMgZ2V0SW5mbyhrZXk6IHN0cmluZykge1xuICAgICAgICAgICAgcmV0dXJuIHJlYWRXaXRoUmV0cnkoXCJnZXRJbmZvXCIsIHBhdGhPZihrZXkpLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZSA9IGF3YWl0IGhhbmRsZS5nZXRGaWxlSGFuZGxlKGtleSk7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZUNvbnRlbnQgPSBhd2FpdCBmaWxlLmdldEZpbGUoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBzaXplOiBmaWxlQ29udGVudC5zaXplLFxuICAgICAgICAgICAgICAgICAgICBsYXN0TW9kaWZpZWQ6IGZpbGVDb250ZW50Lmxhc3RNb2RpZmllZCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sXG4gICAgICAgIGFzeW5jIGdldChrZXk6IHN0cmluZyk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZFdpdGhSZXRyeShcImdldFwiLCBwYXRoT2Yoa2V5KSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpbGUgPSBhd2FpdCBoYW5kbGUuZ2V0RmlsZUhhbmRsZShrZXkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpbGVDb250ZW50ID0gYXdhaXQgZmlsZS5nZXRGaWxlKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgYXJyYXlCdWZmZXIgPSBhd2FpdCBmaWxlQ29udGVudC5hcnJheUJ1ZmZlcigpO1xuICAgICAgICAgICAgICAgIC8vIFVuZGVyIGxvYWQgdGhlIEZTIEFjY2VzcyBBUEkgY2FuIHJlc29sdmUgd2l0aCBhIHRydW5jYXRlZCBidWZmZXIgYW5kIG5vIGVycm9yLlxuICAgICAgICAgICAgICAgIC8vICBUcmVhdCBhIHNob3J0IHJlYWQgYXMgdHJhbnNpZW50IHNvIHJlYWRXaXRoUmV0cnkgcmV0cmllcyBpdC5cbiAgICAgICAgICAgICAgICBpZiAoYXJyYXlCdWZmZXIuYnl0ZUxlbmd0aCAhPT0gZmlsZUNvbnRlbnQuc2l6ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBPYmplY3QuYXNzaWduKG5ldyBFcnJvcihgU2hvcnQgcmVhZDogZ290ICR7YXJyYXlCdWZmZXIuYnl0ZUxlbmd0aH0gb2YgJHtmaWxlQ29udGVudC5zaXplfSBieXRlc2ApLCB7IG5hbWU6IFwiU2hvcnRSZWFkRXJyb3JcIiB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGFycmF5QnVmZmVyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuXG4gICAgICAgIGFzeW5jIGdldFJhbmdlKGtleTogc3RyaW5nLCBjb25maWc6IHsgc3RhcnQ6IG51bWJlcjsgZW5kOiBudW1iZXIgfSk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZFdpdGhSZXRyeShcImdldFJhbmdlXCIsIHBhdGhPZihrZXkpLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZSA9IGF3YWl0IGhhbmRsZS5nZXRGaWxlSGFuZGxlKGtleSk7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZUNvbnRlbnQgPSBhd2FpdCBmaWxlLmdldEZpbGUoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjbGFtcGVkU3RhcnQgPSBNYXRoLm1pbihNYXRoLm1heChjb25maWcuc3RhcnQsIDApLCBmaWxlQ29udGVudC5zaXplKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjbGFtcGVkRW5kID0gTWF0aC5taW4oTWF0aC5tYXgoY29uZmlnLmVuZCwgY2xhbXBlZFN0YXJ0KSwgZmlsZUNvbnRlbnQuc2l6ZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgYXJyYXlCdWZmZXIgPSBhd2FpdCBmaWxlQ29udGVudC5zbGljZShjb25maWcuc3RhcnQsIGNvbmZpZy5lbmQpLmFycmF5QnVmZmVyKCk7XG4gICAgICAgICAgICAgICAgaWYgKGFycmF5QnVmZmVyLmJ5dGVMZW5ndGggIT09IGNsYW1wZWRFbmQgLSBjbGFtcGVkU3RhcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgT2JqZWN0LmFzc2lnbihuZXcgRXJyb3IoYFNob3J0IHJhbmdlIHJlYWQ6IGdvdCAke2FycmF5QnVmZmVyLmJ5dGVMZW5ndGh9IG9mICR7Y2xhbXBlZEVuZCAtIGNsYW1wZWRTdGFydH0gYnl0ZXNgKSwgeyBuYW1lOiBcIlNob3J0UmVhZEVycm9yXCIgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBCdWZmZXIuZnJvbShhcnJheUJ1ZmZlcik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSxcblxuICAgICAgICBhc3luYyBhcHBlbmQoa2V5OiBzdHJpbmcsIHZhbHVlOiBCdWZmZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgICAgIGF3YWl0IGFwcGVuZFF1ZXVlKGtleSkoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIE5PVEU6IEludGVyZXN0aW5nIHBvaW50LiBDaHJvbWUgZG9lc24ndCBvcHRpbWl6ZSB0aGlzIHRvIGJlIGFuIGFwcGVuZCwgYW5kIGluc3RlYWRcbiAgICAgICAgICAgICAgICAvLyAgcmV3cml0ZXMgdGhlIGVudGlyZSBmaWxlLlxuICAgICAgICAgICAgICAgIGNvbnN0IGZpbGUgPSBhd2FpdCBmaXhlZEdldEZpbGVIYW5kbGUoeyBoYW5kbGUsIGtleSwgY3JlYXRlOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IHdyaXRhYmxlID0gYXdhaXQgZmlsZS5jcmVhdGVXcml0YWJsZSh7IGtlZXBFeGlzdGluZ0RhdGE6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgbGV0IG9mZnNldCA9IChhd2FpdCBmaWxlLmdldEZpbGUoKSkuc2l6ZTtcbiAgICAgICAgICAgICAgICBhd2FpdCB3cml0YWJsZS5zZWVrKG9mZnNldCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgd3JpdGFibGUud3JpdGUodmFsdWUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHdyaXRhYmxlLmNsb3NlKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSxcblxuICAgICAgICBhc3luYyBzZXQoa2V5OiBzdHJpbmcsIHZhbHVlOiBCdWZmZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgICAgIGNvbnN0IGZpbGUgPSBhd2FpdCBmaXhlZEdldEZpbGVIYW5kbGUoeyBoYW5kbGUsIGtleSwgY3JlYXRlOiB0cnVlIH0pO1xuICAgICAgICAgICAgY29uc3Qgd3JpdGFibGUgPSBhd2FpdCBmaWxlLmNyZWF0ZVdyaXRhYmxlKCk7XG4gICAgICAgICAgICBhd2FpdCB3cml0YWJsZS53cml0ZSh2YWx1ZSk7XG4gICAgICAgICAgICBhd2FpdCB3cml0YWJsZS5jbG9zZSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGFzeW5jIHJlbW92ZShrZXk6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICAgICAgYXdhaXQgaGFuZGxlLnJlbW92ZUVudHJ5KGtleSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgYXN5bmMgZ2V0S2V5cyhpbmNsdWRlRm9sZGVyczogYm9vbGVhbiA9IGZhbHNlKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgICAgICAgICAgY29uc3Qga2V5czogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgZm9yIGF3YWl0IChjb25zdCBbbmFtZSwgZW50cnldIG9mIGhhbmRsZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZW50cnkua2luZCA9PT0gXCJmaWxlXCIgfHwgaW5jbHVkZUZvbGRlcnMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleXMucHVzaChlbnRyeS5uYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgbGV0IG5hbWUgPSAoZXJyb3IgYXMgeyBuYW1lPzogc3RyaW5nIH0pPy5uYW1lIHx8IFwiRXJyb3JcIjtcbiAgICAgICAgICAgICAgICBsZXQgbWVzc2FnZSA9IChlcnJvciBhcyB7IG1lc3NhZ2U/OiBzdHJpbmcgfSk/Lm1lc3NhZ2UgfHwgU3RyaW5nKGVycm9yKTtcbiAgICAgICAgICAgICAgICAvLyBBIGZhaWx1cmUgbWlkLWl0ZXJhdGlvbiB3b3VsZCBzaWxlbnRseSB0cnVuY2F0ZSB0aGUgbGlzdGluZywgc28gc3VyZmFjZSBpdCBsb3VkbHkuXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgZ2V0S2V5cyBkaXJlY3RvcnkgaXRlcmF0aW9uIGZhaWxlZCBhZnRlciAke2tleXMubGVuZ3RofSBlbnRyaWVzICgke25hbWV9KTogJHttZXNzYWdlLnNsaWNlKDAsIDMwMCl9YCk7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ga2V5cztcbiAgICAgICAgfSxcblxuICAgICAgICBhc3luYyByZXNldCgpIHtcbiAgICAgICAgICAgIGZvciBhd2FpdCAoY29uc3QgW25hbWUsIGVudHJ5XSBvZiBoYW5kbGUpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBoYW5kbGUucmVtb3ZlRW50cnkoZW50cnkubmFtZSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gd3JhcEhhbmRsZU5lc3RlZChoYW5kbGU6IERpcmVjdG9yeVdyYXBwZXIpOiBOZXN0ZWRGaWxlU3RvcmFnZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYXN5bmMgaGFzS2V5KGtleTogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IGhhbmRsZS5nZXREaXJlY3RvcnlIYW5kbGUoa2V5KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGFzeW5jIGdldFN0b3JhZ2Uoa2V5OiBzdHJpbmcpOiBQcm9taXNlPEZpbGVTdG9yYWdlPiB7XG4gICAgICAgICAgICBjb25zdCBzdWJEaXJlY3RvcnkgPSBhd2FpdCBoYW5kbGUuZ2V0RGlyZWN0b3J5SGFuZGxlKGtleSwgeyBjcmVhdGU6IHRydWUgfSk7XG4gICAgICAgICAgICByZXR1cm4gd3JhcEhhbmRsZShzdWJEaXJlY3RvcnkpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGFzeW5jIHJlbW92ZVN0b3JhZ2Uoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgICAgIGF3YWl0IGhhbmRsZS5yZW1vdmVFbnRyeShrZXksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICB9LFxuXG4gICAgICAgIGFzeW5jIGdldEtleXMoKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgICAgICAgICAgY29uc3Qga2V5czogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgICAgIGZvciBhd2FpdCAoY29uc3QgW25hbWUsIGVudHJ5XSBvZiBoYW5kbGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoZW50cnkua2luZCA9PT0gXCJkaXJlY3RvcnlcIikge1xuICAgICAgICAgICAgICAgICAgICBrZXlzLnB1c2goZW50cnkubmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGtleXM7XG4gICAgICAgIH0sXG4gICAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdyYXBIYW5kbGUoaGFuZGxlOiBEaXJlY3RvcnlXcmFwcGVyKTogRmlsZVN0b3JhZ2Uge1xuICAgIHJldHVybiB7XG4gICAgICAgIC4uLndyYXBIYW5kbGVGaWxlcyhoYW5kbGUpLFxuICAgICAgICBmb2xkZXI6IHdyYXBIYW5kbGVOZXN0ZWQoaGFuZGxlKSxcbiAgICAgICAgaXNSZW1vdGU6IGhhbmRsZS5pc1JlbW90ZSxcbiAgICB9O1xufVxuXG4vLyBSZXR1cm5zIGEgVVJMIGZvciBhIGZpbGUncyBieXRlcywgcmVhZHkgdG8gZHJvcCBpbnRvIDx2aWRlbz4vPGltZz4vZmV0Y2guIEEgbmF0aXZlIChsb2NhbCkgZmlsZSBiZWNvbWVzXG4vLyBhbiBpbi1tZW1vcnkgYmxvYjogVVJMOyBhIHJlbW90ZSBmaWxlIGJlY29tZXMgYW4gaHR0cHMgVVJMIGludG8gdGhlIHNlcnZlcidzIHJhbmdlLWNhcGFibGUgL21lZGlhXG4vLyBlbmRwb2ludCAoYXV0aCB0b2tlbiBpbiB0aGUgcXVlcnksIHNpbmNlIGEgbWVkaWEgZWxlbWVudCBjYW4ndCBzZW5kIGhlYWRlcnMpLiBCb3RoIHN1cHBvcnQgSFRUUCByYW5nZSAvXG4vLyBzZWVraW5nLiBBTFdBWVMgaGFuZCB0aGUgcmVzdWx0IHRvIGRpc3Bvc2VGaWxlVVJMIHdoZW4gZmluaXNoZWQg4oCUIGZvciBibG9iOiBVUkxzIHRoYXQgZnJlZXMgbWVtb3J5LlxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldEZpbGVVUkwoZmlsZTogRmlsZVdyYXBwZXIpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGlmIChmaWxlLmdldFVSTCkgcmV0dXJuIGZpbGUuZ2V0VVJMKCk7XG4gICAgLy8gTmF0aXZlIEZpbGVTeXN0ZW1GaWxlSGFuZGxlIChvciBhbnkgQmxvYi1iYWNrZWQgZmlsZSk6IGEgYmxvYjogVVJMIG92ZXIgdGhlIEZpbGUgaXRzZWxmLlxuICAgIGNvbnN0IGYgPSBhd2FpdCBmaWxlLmdldEZpbGUoKTtcbiAgICByZXR1cm4gVVJMLmNyZWF0ZU9iamVjdFVSTChmIGFzIHVua25vd24gYXMgQmxvYik7XG59XG5cbi8vIFJlbGVhc2VzIGEgVVJMIGZyb20gZ2V0RmlsZVVSTC4gYmxvYjogVVJMcyBsZWFrIHVudGlsIHRoZSBkb2N1bWVudCBpcyBnb25lIHVubGVzcyByZXZva2VkOyBodHRwcy9maWxlOlxuLy8gVVJMcyBuZWVkIG5vIGNsZWFudXAsIHNvIHRoaXMgaXMgYSBuby1vcCBmb3IgdGhlbS5cbmV4cG9ydCBmdW5jdGlvbiBkaXNwb3NlRmlsZVVSTCh1cmw6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh1cmwuc3RhcnRzV2l0aChcImJsb2I6XCIpKSB7XG4gICAgICAgIHRyeSB7IFVSTC5yZXZva2VPYmplY3RVUkwodXJsKTsgfSBjYXRjaCB7IC8qIG5vdCBpbiBhIGJyb3dzZXIsIG9yIGFscmVhZHkgcmV2b2tlZCAqLyB9XG4gICAgfVxufVxuXG4vLyBBIFN0b3JhZ2VGYWN0b3J5IGJhY2tlZCBieSBhIHJlbW90ZSBzZXJ2ZXIgKHBhdGggLT4gRmlsZVN0b3JhZ2UpLCBmb3IgY29kZSB0aGF0IGluamVjdHMgaXRzIG93blxuLy8gc3RvcmFnZSBpbnRvIEJ1bGtEYXRhYmFzZTIgcmF0aGVyIHRoYW4gZ29pbmcgdGhyb3VnaCB0aGUgZGlyZWN0b3J5IHByb21wdC5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZW1vdGVGaWxlU3RvcmFnZUZhY3RvcnkodXJsOiBzdHJpbmcsIHBhc3N3b3JkOiBzdHJpbmcsIG9wdGlvbnM/OiBSZW1vdGVPcHRpb25zKTogKHBhdGhTdHI6IHN0cmluZykgPT4gUHJvbWlzZTxGaWxlU3RvcmFnZT4ge1xuICAgIGNvbnN0IHJvb3QgPSBnZXRSZW1vdGVEaXJlY3RvcnlIYW5kbGUodXJsLCBwYXNzd29yZCwgb3B0aW9ucyk7XG4gICAgcmV0dXJuIGFzeW5jIChwYXRoU3RyOiBzdHJpbmcpID0+IHtcbiAgICAgICAgbGV0IGJhc2U6IERpcmVjdG9yeVdyYXBwZXIgPSByb290O1xuICAgICAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGF0aFN0ci5yZXBsYWNlQWxsKFwiXFxcXFwiLCBcIi9cIikuc3BsaXQoXCIvXCIpKSB7XG4gICAgICAgICAgICBpZiAoIXBhcnQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgYmFzZSA9IGF3YWl0IGJhc2UuZ2V0RGlyZWN0b3J5SGFuZGxlKHBhcnQsIHsgY3JlYXRlOiB0cnVlIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB3cmFwSGFuZGxlKGJhc2UpO1xuICAgIH07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0cnlUb0xvYWRQb2ludGVyKHBvaW50ZXI6IHN0cmluZykge1xuICAgIGxldCByZXN1bHQgPSBhd2FpdCBnZXRGaWxlU3lzdGVtUG9pbnRlcih7IHBvaW50ZXIgfSk7XG4gICAgaWYgKCFyZXN1bHQpIHJldHVybjtcbiAgICBsZXQgaGFuZGxlID0gYXdhaXQgcmVzdWx0Py5vblVzZXJBY3RpdmF0aW9uKCk7XG4gICAgaWYgKCFoYW5kbGUpIHJldHVybjtcbiAgICByZXR1cm4gaGFuZGxlIGFzIGFueSBhcyBEaXJlY3RvcnlXcmFwcGVyO1xufSJdfQ==
|
|
788
|
+
/* _JS_SOURCE_HASH = "43cb0c3dd5b191683c168a59e5117a62eee04ed66ca81588a27c8ad1fd491142"; */
|