sliftutils 1.7.9 → 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.
Files changed (92) hide show
  1. package/bin/storageserver.js +4 -0
  2. package/{teststorage → examplestorage}/browser.tsx +18 -22
  3. package/{teststorage/server.ts → examplestorage/exampleserver.ts} +4 -6
  4. package/index.d.ts +770 -84
  5. package/misc/dist/environment.ts.cache +3 -3
  6. package/misc/dist/getSecret.ts.cache +139 -0
  7. package/misc/dist/strings.ts.cache +13 -0
  8. package/misc/dist/zip.ts.cache +9 -0
  9. package/misc/getSecret.ts +38 -16
  10. package/misc/https/cloudflareHelpers.d.ts +19 -0
  11. package/misc/https/cloudflareHelpers.ts +69 -0
  12. package/misc/https/dist/certs.ts.cache +115 -179
  13. package/misc/https/dist/cloudflareHelpers.ts.cache +68 -0
  14. package/misc/https/dist/dns.ts.cache +112 -100
  15. package/misc/https/dist/hostServer.ts.cache +130 -0
  16. package/misc/https/dist/httpsCerts.ts.cache +24 -5
  17. package/misc/https/dist/persistentLocalStorage.ts.cache +3 -2
  18. package/misc/https/dns.d.ts +41 -8
  19. package/misc/https/dns.ts +104 -106
  20. package/misc/https/hostServer.d.ts +0 -3
  21. package/misc/https/hostServer.ts +12 -8
  22. package/package.json +3 -2
  23. package/render-utils/dist/observer.tsx.cache +3 -2
  24. package/spec.txt +0 -55
  25. package/storage/ArchivesDisk.d.ts +67 -0
  26. package/storage/ArchivesDisk.ts +369 -0
  27. package/storage/BulkDatabase2/dist/BulkDatabaseBase.ts.cache +1242 -0
  28. package/storage/BulkDatabase2/dist/BulkDatabaseFormat.ts.cache +513 -0
  29. package/storage/BulkDatabase2/dist/BulkDatabaseMerge.ts.cache +352 -0
  30. package/storage/BulkDatabase2/dist/BulkDatabaseReader.ts.cache +306 -0
  31. package/storage/BulkDatabase2/dist/LoadedIndex.ts.cache +435 -0
  32. package/storage/BulkDatabase2/dist/WriteOverlay.ts.cache +58 -0
  33. package/storage/BulkDatabase2/dist/blockCache.ts.cache +179 -0
  34. package/storage/BulkDatabase2/dist/mergeLock.ts.cache +149 -0
  35. package/storage/BulkDatabase2/dist/mergeMarkers.ts.cache +101 -0
  36. package/storage/BulkDatabase2/dist/streamLog.ts.cache +227 -0
  37. package/storage/BulkDatabase2/dist/syncClient.ts.cache +104 -0
  38. package/storage/IArchives.d.ts +127 -1
  39. package/storage/IArchives.ts +201 -1
  40. package/storage/backblaze.d.ts +29 -2
  41. package/storage/backblaze.ts +214 -78
  42. package/storage/dist/ArchivesDisk.ts.cache +373 -0
  43. package/storage/dist/FileFolderAPI.tsx.cache +508 -65
  44. package/storage/dist/IArchives.ts.cache +44 -0
  45. package/storage/dist/IndexedDBFileFolderAPI.ts.cache +8 -2
  46. package/storage/dist/JSONStorage.ts.cache +6 -2
  47. package/storage/dist/PendingManager.tsx.cache +1 -1
  48. package/storage/dist/TransactionStorage.ts.cache +231 -92
  49. package/storage/dist/backblaze.ts.cache +797 -0
  50. package/storage/dist/fileSystemPointer.ts.cache +36 -3
  51. package/storage/dist/remoteFileStorage.ts.cache +495 -0
  52. package/storage/remoteStorage/ArchivesRemote.d.ts +34 -18
  53. package/storage/remoteStorage/ArchivesRemote.ts +85 -65
  54. package/storage/remoteStorage/ArchivesUrl.d.ts +48 -0
  55. package/storage/remoteStorage/ArchivesUrl.ts +86 -0
  56. package/storage/remoteStorage/accessPage.tsx +111 -28
  57. package/storage/remoteStorage/blobStore.d.ts +128 -25
  58. package/storage/remoteStorage/blobStore.ts +757 -290
  59. package/storage/remoteStorage/cliArgs.d.ts +1 -0
  60. package/storage/remoteStorage/cliArgs.ts +9 -0
  61. package/storage/remoteStorage/createArchives.d.ts +85 -0
  62. package/storage/remoteStorage/createArchives.ts +612 -0
  63. package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +197 -0
  64. package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +85 -0
  65. package/storage/remoteStorage/dist/accessPage.tsx.cache +222 -0
  66. package/storage/remoteStorage/dist/blobStore.ts.cache +837 -0
  67. package/storage/remoteStorage/dist/cliArgs.ts.cache +16 -0
  68. package/storage/remoteStorage/dist/createArchives.ts.cache +610 -0
  69. package/storage/remoteStorage/dist/remoteConfig.ts.cache +206 -0
  70. package/storage/remoteStorage/dist/sourceWrapper.ts.cache +223 -0
  71. package/storage/remoteStorage/dist/storageController.ts.cache +500 -0
  72. package/storage/remoteStorage/dist/storageServer.ts.cache +106 -0
  73. package/storage/remoteStorage/dist/storageServerCli.ts.cache +39 -0
  74. package/storage/remoteStorage/dist/storageServerState.ts.cache +518 -0
  75. package/storage/remoteStorage/grantAccess.js +4 -0
  76. package/storage/remoteStorage/grantAccessCli.d.ts +1 -0
  77. package/storage/remoteStorage/grantAccessCli.ts +27 -0
  78. package/storage/remoteStorage/remoteConfig.d.ts +29 -0
  79. package/storage/remoteStorage/remoteConfig.ts +194 -0
  80. package/storage/remoteStorage/sourceWrapper.d.ts +41 -0
  81. package/storage/remoteStorage/sourceWrapper.ts +223 -0
  82. package/storage/remoteStorage/spec.md +31 -0
  83. package/storage/remoteStorage/storageController.d.ts +30 -27
  84. package/storage/remoteStorage/storageController.ts +297 -159
  85. package/storage/remoteStorage/storageServer.d.ts +6 -0
  86. package/storage/remoteStorage/storageServer.ts +88 -94
  87. package/storage/remoteStorage/storageServerCli.d.ts +1 -0
  88. package/storage/remoteStorage/storageServerCli.ts +38 -0
  89. package/storage/remoteStorage/storageServerState.d.ts +43 -0
  90. package/storage/remoteStorage/storageServerState.ts +540 -0
  91. package/testsite/server.ts +0 -2
  92. 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 mobxTyped_1 = require("../misc/mobxTyped");
16
- const observer_1 = require("../misc/observer");
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
- let displayData = (0, mobxTyped_1.observable)({
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
- const storageKey = "syncFileSystemCamera3";
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(1)
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(this.filePath);
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
- throw new Error(`File not found: ${filePath}`);
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
- const dirPath = path_1.default.join(this.rootPath, entry.name);
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
- // NOTE: Blocks until the user provides a directory
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 handle;
162
- let storedId = localStorage.getItem(storageKey);
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
- if (doneLoad)
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 (_a) { }
175
- doneLoad = true;
176
- if (handle) {
177
- return handle;
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
- let fileCallback;
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
- localStorage.removeItem(storageKey);
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
- try {
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
- try {
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
- catch (error) {
260
- return undefined;
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
- for await (const [name, entry] of handle) {
287
- if (entry.kind === "file") {
288
- keys.push(entry.name);
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"; */