sliftutils 1.7.96 → 1.7.98

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 (55) hide show
  1. package/dist/treeSummary.ts.cache +2 -2
  2. package/index.d.ts +18 -1
  3. package/misc/dist/environment.ts.cache +2 -2
  4. package/misc/dist/getSecret.ts.cache +2 -2
  5. package/misc/dist/strings.ts.cache +2 -2
  6. package/misc/dist/zip.ts.cache +2 -2
  7. package/misc/https/dist/certs.ts.cache +2 -2
  8. package/misc/https/dist/persistentLocalStorage.ts.cache +2 -2
  9. package/package.json +1 -1
  10. package/render-utils/dist/observer.tsx.cache +2 -2
  11. package/storage/dist/ArchivesDisk.ts.cache +2 -2
  12. package/storage/dist/FileFolderAPI.tsx.cache +2 -2
  13. package/storage/dist/IndexedDBFileFolderAPI.ts.cache +2 -2
  14. package/storage/dist/JSONStorage.ts.cache +2 -2
  15. package/storage/dist/LogMap.ts.cache +2 -2
  16. package/storage/dist/PendingManager.tsx.cache +2 -2
  17. package/storage/dist/TransactionStorage.ts.cache +2 -2
  18. package/storage/dist/archiveHelpers.ts.cache +2 -2
  19. package/storage/dist/backblaze.ts.cache +2 -2
  20. package/storage/dist/fileSystemPointer.ts.cache +2 -2
  21. package/storage/dist/remoteFileStorage.ts.cache +2 -2
  22. package/storage/remoteStorage/blobStore.d.ts +2 -0
  23. package/storage/remoteStorage/blobStore.ts +19 -1
  24. package/storage/remoteStorage/chainStartup.d.ts +1 -0
  25. package/storage/remoteStorage/chainStartup.ts +6 -1
  26. package/storage/remoteStorage/createArchives.ts +4 -3
  27. package/storage/remoteStorage/dist/ArchivesDelayed.ts.cache +2 -2
  28. package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +2 -2
  29. package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +2 -2
  30. package/storage/remoteStorage/dist/accessStats.ts.cache +2 -2
  31. package/storage/remoteStorage/dist/blobStore.ts.cache +21 -2
  32. package/storage/remoteStorage/dist/bucketDisk.ts.cache +2 -2
  33. package/storage/remoteStorage/dist/certTrustModal.tsx.cache +2 -2
  34. package/storage/remoteStorage/dist/chainStartup.ts.cache +469 -0
  35. package/storage/remoteStorage/dist/cliArgs.ts.cache +2 -2
  36. package/storage/remoteStorage/dist/createArchives.ts.cache +52 -361
  37. package/storage/remoteStorage/dist/deployTakeover.ts.cache +2 -2
  38. package/storage/remoteStorage/dist/intermediateManagement.ts.cache +2 -2
  39. package/storage/remoteStorage/dist/intermediateSources.ts.cache +2 -2
  40. package/storage/remoteStorage/dist/remoteConfig.ts.cache +2 -2
  41. package/storage/remoteStorage/dist/serverConfig.ts.cache +2 -2
  42. package/storage/remoteStorage/dist/sourceWrapper.ts.cache +2 -2
  43. package/storage/remoteStorage/dist/sourcesList.ts.cache +2 -2
  44. package/storage/remoteStorage/dist/storageClientController.ts.cache +45 -4
  45. package/storage/remoteStorage/dist/storageServerState.ts.cache +16 -5
  46. package/storage/remoteStorage/dist/storeConfig.ts.cache +7 -2
  47. package/storage/remoteStorage/dist/storePlan.ts.cache +2 -2
  48. package/storage/remoteStorage/dist/storeSources.ts.cache +2 -2
  49. package/storage/remoteStorage/dist/storeSync.ts.cache +2 -2
  50. package/storage/remoteStorage/dist/validation.ts.cache +2 -2
  51. package/storage/remoteStorage/storageClientController.d.ts +14 -0
  52. package/storage/remoteStorage/storageClientController.ts +42 -1
  53. package/storage/remoteStorage/storageServerState.d.ts +1 -1
  54. package/storage/remoteStorage/storageServerState.ts +11 -2
  55. package/storage/remoteStorage/storeConfig.ts +5 -0
@@ -0,0 +1,469 @@
1
+ "use strict"; var console = (function shimConsole() { let baseConsole = globalThis.console; if (typeof window !== "undefined") return baseConsole; let name = __filename.replaceAll("\\", "/").split("/").pop(); let dirName = __dirname.replaceAll("\\", "/").split("/").pop(); let context = { __FILE__: __filename, __DIR__: __dirname, __NAME__: name, __DIRNAME__: dirName }; let newConsole = { ...baseConsole }; for (let shim of ["log", "info", "warn", "error"]) { newConsole[shim] = (...args) => { args.push(context); baseConsole[shim](...args); }; } newConsole.__context = context; return newConsole; })(); "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
3
+ //exports.RoutingRewriteLoop = exports.writeRoutingToAllStores = exports.chooseStartupConfig = exports.disposeProbes = exports.probeSources = exports.ChainStateManager = exports.CONFIG_WRITE_REFRESH_INTERVAL = exports.CONFIG_WRITE_RETRY_INTERVAL = void 0;
4
+ const misc_1 = require("socket-function/src/misc");
5
+ const remoteConfig_1 = require("./remoteConfig");
6
+ const sourceWrapper_1 = require("./sourceWrapper");
7
+ const intermediateSources_1 = require("./intermediateSources");
8
+ const storageClientController_1 = require("./storageClientController");
9
+ // The LIFECYCLE of an ArchivesChain's state, and nothing else: initializing it (probing every configured source, deciding which routing config to run, writing ours out when it is the newest), the retry when initialization fails, the poll that adopts newer configs, the availability recheck, and the loop that keeps re-writing our config. None of this is request dispatch - the chain (createArchives.ts) asks the ChainStateManager for the current state and dispatches over it.
10
+ const CONFIG_POLL_INTERVAL = 5 * 60 * 1000;
11
+ const AVAILABILITY_RECHECK_THROTTLE = 5 * 1000;
12
+ // The routing config write is retried on this cadence while it is failing. A store that never received the config rejects every write aimed at it, so this not landing is a big deal - each failed attempt is logged.
13
+ exports.CONFIG_WRITE_RETRY_INTERVAL = 5 * 60 * 1000;
14
+ // ...and even after success it is re-written on this cadence, in case a store lost it or a server appeared late
15
+ exports.CONFIG_WRITE_REFRESH_INTERVAL = 60 * 60 * 1000;
16
+ /** The chain's state and everything about HAVING one: init (with its retry), the config poll, availability rechecks, and the routing rewrite loop. The chain constructs one, asks it getState() on every call, and disposes it. */
17
+ class ChainStateManager {
18
+ constructor(config) {
19
+ this.config = config;
20
+ this.initRetryDelay = sourceWrapper_1.RETRY_START_DELAY;
21
+ this.disposed = false;
22
+ this.lastAvailabilityRecheck = 0;
23
+ this.configured = config.configured;
24
+ this.activeConfig = config.configured;
25
+ this.routingRewriter = new RoutingRewriteLoop({
26
+ configured: config.configured,
27
+ debugName: config.debugName,
28
+ latest: () => this.latestState,
29
+ });
30
+ this.unsubscribeRoutingPush = (0, storageClientController_1.onServerRoutingChanged)(() => {
31
+ void this.refreshActiveConfig().catch((e) => { var _a; return console.error(`Config refresh failed for ${this.config.debugName()}: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`); });
32
+ });
33
+ // So a server can ask what config we intended for a store name (see StorageClientController.getRoutingConfigForName)
34
+ this.untrackConfig = (0, storageClientController_1.trackChainConfig)({ configured: config.configured, active: () => this.activeConfig });
35
+ }
36
+ /** The newest adopted state, synchronously - undefined until the first init finishes. */
37
+ latest() {
38
+ return this.latestState;
39
+ }
40
+ getState() {
41
+ if (this.disposed) {
42
+ return Promise.reject(new Error(`ArchivesChain ${this.config.debugName()} has been disposed`));
43
+ }
44
+ if (!this.statePromise) {
45
+ let promise = this.init();
46
+ this.statePromise = promise;
47
+ promise.then(() => {
48
+ this.initRetryDelay = sourceWrapper_1.RETRY_START_DELAY;
49
+ }, (e) => {
50
+ var _a, _b, _c;
51
+ if (this.disposed || this.initRetryTimer)
52
+ return;
53
+ console.error(`Storage init failed for ${this.config.debugName()}, retrying in ${Math.round(this.initRetryDelay / 1000)}s. ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`);
54
+ this.initRetryTimer = setTimeout(() => {
55
+ this.initRetryTimer = undefined;
56
+ if (this.disposed)
57
+ return;
58
+ if (this.statePromise === promise) {
59
+ this.statePromise = undefined;
60
+ }
61
+ this.getState().catch(() => { });
62
+ }, this.initRetryDelay);
63
+ (_c = (_b = this.initRetryTimer).unref) === null || _c === void 0 ? void 0 : _c.call(_b);
64
+ this.initRetryDelay = Math.min(sourceWrapper_1.RETRY_MAX_DELAY, this.initRetryDelay * sourceWrapper_1.RETRY_GROWTH);
65
+ });
66
+ }
67
+ return this.statePromise;
68
+ }
69
+ async init() {
70
+ let configs = this.configured.sources.map(remoteConfig_1.normalizeSource);
71
+ let readOnly = this.isReadOnly(this.configured);
72
+ let probes = await probeSources(configs, readOnly);
73
+ try {
74
+ let { active, needsWrite, existing } = chooseStartupConfig({ configured: this.configured, probes, debugName: this.config.debugName() });
75
+ let sources = await this.buildSources(active);
76
+ let configWriteFailed = false;
77
+ if (needsWrite) {
78
+ console.log(`Storage routing config for ${this.config.debugName()} is out of date (stored version ${existing && (0, remoteConfig_1.getConfigVersion)(existing) || "none"}, ours ${(0, remoteConfig_1.getConfigVersion)(this.configured)})`);
79
+ let { failures, total } = await writeRoutingToAllStores({ configured: this.configured, sources, debugName: this.config.debugName() });
80
+ configWriteFailed = failures.length > 0;
81
+ if (failures.length && failures.length === total) {
82
+ // Nobody has our config, so running on it would just disagree with every server. The stored one (when there is one) is what the servers actually run.
83
+ console.error(`The storage routing config for ${this.config.debugName()} (version ${(0, remoteConfig_1.getConfigVersion)(this.configured)}) could not be written to ANY of the ${total} stores. ${existing && `Running on the stored config (version ${(0, remoteConfig_1.getConfigVersion)(existing)}) until a write succeeds.` || `No stored config exists either, so servers will reject writes until this succeeds.`} Retrying in ${exports.CONFIG_WRITE_RETRY_INTERVAL / 1000}s. Failures: ${failures.join(" | ")}`);
84
+ if (existing) {
85
+ active = existing;
86
+ for (let source of sources) {
87
+ source.dispose();
88
+ }
89
+ sources = await this.buildSources(active);
90
+ }
91
+ }
92
+ else if (failures.length) {
93
+ console.error(`The storage routing config for ${this.config.debugName()} (version ${(0, remoteConfig_1.getConfigVersion)(this.configured)}) was written to ${total - failures.length} of ${total} stores. Retrying the rest in ${exports.CONFIG_WRITE_RETRY_INTERVAL / 1000}s (they also pull it from the stores that have it). Failures: ${failures.join(" | ")}`);
94
+ }
95
+ }
96
+ for (let source of sources) {
97
+ let probe = probes.find(x => x.responded && x.sourceConfig.url === source.config.url);
98
+ if (probe) {
99
+ source.seedLatency(probe.latency);
100
+ }
101
+ }
102
+ this.activeConfig = active;
103
+ this.startConfigPoll();
104
+ let state = { config: active, sources };
105
+ this.latestState = state;
106
+ this.routingRewriter.start(configWriteFailed);
107
+ return state;
108
+ }
109
+ finally {
110
+ disposeProbes(probes);
111
+ }
112
+ }
113
+ /** Clientside, a config with public sources is served entirely over plain URL downloads - no API connection, no access grant, and no writing. directConnect opts out of that. */
114
+ isReadOnly(config) {
115
+ if (this.config.directConnect || (0, misc_1.isNode)())
116
+ return false;
117
+ return config.sources.map(remoteConfig_1.normalizeSource).some(x => x.public);
118
+ }
119
+ async createChainSource(sourceConfig, readOnly) {
120
+ let source = await sourceWrapper_1.SourceWrapper.create(sourceConfig, { readOnly });
121
+ source.startPinging();
122
+ return source;
123
+ }
124
+ async buildSources(config) {
125
+ let readOnly = this.isReadOnly(config);
126
+ let sources = [];
127
+ for (let sourceConfig of config.sources.map(remoteConfig_1.normalizeSource)) {
128
+ sources.push(await this.createChainSource(sourceConfig, readOnly));
129
+ }
130
+ return sources;
131
+ }
132
+ startConfigPoll() {
133
+ var _a, _b;
134
+ if (this.pollTimer || this.disposed)
135
+ return;
136
+ this.pollTimer = setInterval(() => {
137
+ void this.refreshActiveConfig().catch((e) => {
138
+ var _a;
139
+ console.error(`Checking for a new storage routing config failed for ${this.config.debugName()}: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`);
140
+ });
141
+ }, CONFIG_POLL_INTERVAL);
142
+ (_b = (_a = this.pollTimer).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
143
+ }
144
+ refreshActiveConfig() {
145
+ if (!this.configRefreshInFlight) {
146
+ this.configRefreshInFlight = this.checkForNewConfig().finally(() => {
147
+ this.configRefreshInFlight = undefined;
148
+ });
149
+ }
150
+ return this.configRefreshInFlight;
151
+ }
152
+ async fetchLatestConfig(state) {
153
+ var _a;
154
+ let errors = [];
155
+ for (let source of state.sources) {
156
+ try {
157
+ let latest = await source.readRoutingConfig();
158
+ if (latest)
159
+ return (0, remoteConfig_1.normalizeRemoteConfig)(latest);
160
+ }
161
+ catch (e) {
162
+ errors.push(`${source.config.url}: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`);
163
+ }
164
+ }
165
+ if (errors.length === state.sources.length) {
166
+ throw new Error(`No storage source could give us the routing config for ${this.config.debugName()}: ${errors.join(" | ")}`);
167
+ }
168
+ return undefined;
169
+ }
170
+ async checkForNewConfig() {
171
+ if (this.disposed || !this.statePromise)
172
+ return;
173
+ let state;
174
+ try {
175
+ state = await this.statePromise;
176
+ }
177
+ catch (_a) {
178
+ return;
179
+ }
180
+ let latest = await this.fetchLatestConfig(state);
181
+ if (!latest)
182
+ return;
183
+ await this.adoptNewConfig(state, latest);
184
+ }
185
+ async adoptNewConfig(state, latest) {
186
+ var _a;
187
+ if (JSON.stringify(latest) === JSON.stringify(state.config))
188
+ return;
189
+ let received = new Date().toISOString();
190
+ let onlyIntermediatesChanged = JSON.stringify((0, intermediateSources_1.resolveIntermediateSources)(latest)) === JSON.stringify((0, intermediateSources_1.resolveIntermediateSources)(state.config));
191
+ if (onlyIntermediatesChanged) {
192
+ console.log(`Storage routing switchover windows changed (version ${(0, remoteConfig_1.getConfigVersion)(state.config)} -> ${(0, remoteConfig_1.getConfigVersion)(latest)}), received ${received}, rebuilding sources. New config: ${JSON.stringify(latest)}`);
193
+ }
194
+ else {
195
+ console.log(`Storage routing config changed (version ${(0, remoteConfig_1.getConfigVersion)(state.config)} -> ${(0, remoteConfig_1.getConfigVersion)(latest)}), received ${received}, rebuilding sources. New config: ${JSON.stringify(latest)}`);
196
+ }
197
+ let strippedKey = (config) => JSON.stringify({ ...config, validWindow: undefined });
198
+ let oldByConfig = new Map();
199
+ for (let source of state.sources) {
200
+ let key = strippedKey(source.config);
201
+ let list = oldByConfig.get(key);
202
+ if (!list) {
203
+ list = [];
204
+ oldByConfig.set(key, list);
205
+ }
206
+ list.push(source);
207
+ }
208
+ let readOnly = this.isReadOnly(latest);
209
+ let sources = [];
210
+ for (let sourceConfig of latest.sources.map(remoteConfig_1.normalizeSource)) {
211
+ let old = (_a = oldByConfig.get(strippedKey(sourceConfig))) === null || _a === void 0 ? void 0 : _a.shift();
212
+ if (old) {
213
+ old.updateValidWindow(sourceConfig.validWindow);
214
+ sources.push(old);
215
+ }
216
+ else {
217
+ sources.push(await this.createChainSource(sourceConfig, readOnly));
218
+ }
219
+ }
220
+ for (let leftovers of oldByConfig.values()) {
221
+ for (let leftover of leftovers) {
222
+ leftover.dispose();
223
+ }
224
+ }
225
+ this.activeConfig = latest;
226
+ let newState = { config: latest, sources };
227
+ this.latestState = newState;
228
+ this.statePromise = Promise.resolve(newState);
229
+ }
230
+ /** Every source failed: re-contact all of them (routing re-read + connection re-attempt) and adopt whatever config comes back. Throttled, and deduplicated across concurrent callers. */
231
+ recheckAvailability() {
232
+ if (this.availabilityRecheckInFlight)
233
+ return this.availabilityRecheckInFlight;
234
+ if (Date.now() - this.lastAvailabilityRecheck < AVAILABILITY_RECHECK_THROTTLE)
235
+ return Promise.resolve();
236
+ this.lastAvailabilityRecheck = Date.now();
237
+ this.availabilityRecheckInFlight = this.recheckAvailabilityNow().finally(() => {
238
+ this.availabilityRecheckInFlight = undefined;
239
+ });
240
+ return this.availabilityRecheckInFlight;
241
+ }
242
+ async recheckAvailabilityNow() {
243
+ if (this.disposed || !this.statePromise)
244
+ return;
245
+ let state;
246
+ try {
247
+ state = await this.statePromise;
248
+ }
249
+ catch (_a) {
250
+ return;
251
+ }
252
+ console.log(`Every storage source failed for ${this.config.debugName()}; re-contacting all ${state.sources.length} sources (routing re-read + connection re-attempt)`);
253
+ let results = await Promise.all(state.sources.map(async (source) => {
254
+ try {
255
+ return await source.readRoutingConfig();
256
+ }
257
+ catch (_a) {
258
+ return undefined;
259
+ }
260
+ }));
261
+ let latest = results.find(x => x);
262
+ if (!latest)
263
+ return;
264
+ await this.adoptNewConfig(state, latest);
265
+ }
266
+ dispose() {
267
+ var _a;
268
+ this.disposed = true;
269
+ this.untrackConfig();
270
+ (_a = this.unsubscribeRoutingPush) === null || _a === void 0 ? void 0 : _a.call(this);
271
+ if (this.pollTimer) {
272
+ clearInterval(this.pollTimer);
273
+ }
274
+ if (this.initRetryTimer) {
275
+ clearTimeout(this.initRetryTimer);
276
+ }
277
+ this.routingRewriter.dispose();
278
+ let statePromise = this.statePromise;
279
+ if (statePromise) {
280
+ void statePromise.then(state => {
281
+ for (let source of state.sources) {
282
+ source.dispose();
283
+ }
284
+ }, () => { });
285
+ }
286
+ }
287
+ }
288
+ exports.ChainStateManager = ChainStateManager;
289
+ /** One throwaway SourceWrapper per configured source, each asked for its stored routing config - which also measures first-contact latency, seeded into the real sources afterwards. The probes MUST be disposed (disposeProbes) once the caller is done with them. */
290
+ async function probeSources(configs, readOnly) {
291
+ return await Promise.all(configs.map(async (sourceConfig) => {
292
+ var _a;
293
+ let probe = await sourceWrapper_1.SourceWrapper.create(sourceConfig, { background: false, readOnly });
294
+ let start = Date.now();
295
+ try {
296
+ let existing = await probe.readRoutingConfig();
297
+ return { probe, sourceConfig, responded: true, latency: Date.now() - start, existing, error: "" };
298
+ }
299
+ catch (e) {
300
+ return { probe, sourceConfig, responded: false, latency: 0, existing: undefined, error: `${sourceConfig.url}: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}` };
301
+ }
302
+ }));
303
+ }
304
+ exports.probeSources = probeSources;
305
+ function disposeProbes(probes) {
306
+ for (let probe of probes) {
307
+ probe.probe.dispose();
308
+ }
309
+ }
310
+ exports.disposeProbes = disposeProbes;
311
+ /**
312
+ * Which routing config the chain should RUN: the newest of ours and every stored one. needsWrite
313
+ * when ours is strictly the newest, meaning the stores have to be told about it. A stored config
314
+ * with our exact version but DIFFERENT content wins without a write, loudly: config updates must
315
+ * bump the version, or they are ignored - silently taking the changed one would make "what is the
316
+ * bucket running" depend on which process started last.
317
+ *
318
+ * Throws when no source answered at all: with nothing stored and nobody to write to, there is no
319
+ * config to run.
320
+ */
321
+ function chooseStartupConfig(config) {
322
+ let { configured, probes, debugName } = config;
323
+ let found = probes.find(x => x.responded);
324
+ if (!found) {
325
+ throw new Error(`Cannot initialize storage for ${debugName}: no source answered. ${probes.map(x => x.error).join(" | ")}`);
326
+ }
327
+ let existing = found.existing;
328
+ let active = configured;
329
+ let needsWrite = true;
330
+ if (existing && (0, remoteConfig_1.getConfigVersion)(existing) >= (0, remoteConfig_1.getConfigVersion)(configured)) {
331
+ if ((0, remoteConfig_1.getConfigVersion)(existing) === (0, remoteConfig_1.getConfigVersion)(configured) && JSON.stringify(existing) !== JSON.stringify(configured)) {
332
+ console.error(`Archives configuration updated without updating the version, for ${found.sourceConfig.url}. Updates will be ignored until you increase the version. Using: ${JSON.stringify(existing)}, ignoring: ${JSON.stringify(configured)}`);
333
+ }
334
+ active = existing;
335
+ needsWrite = false;
336
+ }
337
+ if (needsWrite) {
338
+ let best;
339
+ let conflictUrl;
340
+ for (let probe of probes) {
341
+ let stored = probe.existing;
342
+ if (!stored)
343
+ continue;
344
+ if (!best || (0, remoteConfig_1.getConfigVersion)(stored) > (0, remoteConfig_1.getConfigVersion)(best)) {
345
+ best = stored;
346
+ }
347
+ if ((0, remoteConfig_1.getConfigVersion)(stored) === (0, remoteConfig_1.getConfigVersion)(configured) && JSON.stringify(stored) !== JSON.stringify(configured)) {
348
+ conflictUrl = probe.sourceConfig.url;
349
+ }
350
+ }
351
+ if (best && (0, remoteConfig_1.getConfigVersion)(best) >= (0, remoteConfig_1.getConfigVersion)(configured)) {
352
+ if (conflictUrl && (0, remoteConfig_1.getConfigVersion)(best) === (0, remoteConfig_1.getConfigVersion)(configured)) {
353
+ console.error(`Archives configuration updated without updating the version, for ${conflictUrl}. Updates will be ignored until you increase the version. Using: ${JSON.stringify(best)}, ignoring: ${JSON.stringify(configured)}`);
354
+ }
355
+ active = best;
356
+ needsWrite = false;
357
+ }
358
+ }
359
+ return { active, needsWrite, existing };
360
+ }
361
+ exports.chooseStartupConfig = chooseStartupConfig;
362
+ /**
363
+ * Writes the given routing config to every configured store, one write per url+name: the write
364
+ * lands in the store the entry NAMES, so two entries sharing a URL but naming different stores are
365
+ * two separate deliveries - deduping by URL alone leaves the second store unconfigured forever. All
366
+ * in parallel, every failure tolerated (no-write-access included - the attempt classifies it,
367
+ * nothing pre-checks it): a down node must not stop the others from getting the config - they would
368
+ * then reject writes as unconfigured precisely BECAUSE it never arrived - and it must never stop
369
+ * the chain from starting. A store that missed it pulls it off its peers, and the rewrite loop
370
+ * tries again (see RoutingRewriteLoop).
371
+ */
372
+ async function writeRoutingToAllStores(config) {
373
+ let { configured, sources, debugName } = config;
374
+ let routingData = (0, remoteConfig_1.serializeRemoteConfig)(configured);
375
+ let routingWriteTime = Date.now();
376
+ let targets = [];
377
+ let seen = new Set();
378
+ for (let source of sources) {
379
+ let key = `${source.config.url}|${source.config.name}`;
380
+ if (seen.has(key))
381
+ continue;
382
+ seen.add(key);
383
+ targets.push(source);
384
+ }
385
+ console.log(`Writing routing config version ${(0, remoteConfig_1.getConfigVersion)(configured)} for ${debugName} to all ${targets.length} stores (write time ${new Date(routingWriteTime).toISOString()}): ${targets.map(x => `${x.config.url} (store ${JSON.stringify(x.config.name)})`).join(", ")}`);
386
+ let failures = [];
387
+ await Promise.all(targets.map(async (source) => {
388
+ var _a;
389
+ try {
390
+ await source.write(archives => archives.set(remoteConfig_1.ROUTING_FILE, routingData, { lastModified: routingWriteTime }));
391
+ console.log(`Wrote storage routing config version ${(0, remoteConfig_1.getConfigVersion)(configured)} to ${source.config.url} (store ${JSON.stringify(source.config.name)})`);
392
+ }
393
+ catch (e) {
394
+ failures.push(`${source.config.url} (store ${JSON.stringify(source.config.name)}): ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`);
395
+ }
396
+ }));
397
+ return { failures, total: targets.length };
398
+ }
399
+ exports.writeRoutingToAllStores = writeRoutingToAllStores;
400
+ /**
401
+ * The periodic re-write of the chain's in-code config: failures retried on the short interval - a
402
+ * store without the config rejects every write aimed at it, so this not landing is a big deal,
403
+ * logged on every attempt - and even success repeated hourly, in case a store lost it. The failure
404
+ * this exists for: a server whose trust was only granted AFTER startup, so the startup write was
405
+ * rejected and nothing else would ever retry it.
406
+ */
407
+ class RoutingRewriteLoop {
408
+ constructor(config) {
409
+ this.config = config;
410
+ this.disposed = false;
411
+ }
412
+ /** (Re)arms the loop - called at the end of every init, with whether that init's write failed (which picks the short retry interval). */
413
+ start(failedAtStartup) {
414
+ this.schedule(failedAtStartup && exports.CONFIG_WRITE_RETRY_INTERVAL || exports.CONFIG_WRITE_REFRESH_INTERVAL);
415
+ }
416
+ dispose() {
417
+ this.disposed = true;
418
+ if (this.timer) {
419
+ clearTimeout(this.timer);
420
+ }
421
+ }
422
+ schedule(delay) {
423
+ var _a, _b;
424
+ if (this.disposed)
425
+ return;
426
+ if (this.timer) {
427
+ clearTimeout(this.timer);
428
+ }
429
+ this.timer = setTimeout(() => {
430
+ this.timer = undefined;
431
+ void this.rewrite().catch((e) => {
432
+ var _a;
433
+ console.error(`Rewriting the storage routing config for ${this.config.debugName()} failed: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`);
434
+ this.schedule(exports.CONFIG_WRITE_RETRY_INTERVAL);
435
+ });
436
+ }, delay);
437
+ (_b = (_a = this.timer).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
438
+ }
439
+ async rewrite() {
440
+ if (this.disposed)
441
+ return;
442
+ let configured = this.config.configured;
443
+ let state = this.config.latest();
444
+ if (!state) {
445
+ this.schedule(exports.CONFIG_WRITE_RETRY_INTERVAL);
446
+ return;
447
+ }
448
+ // The bucket adopted a NEWER config than our in-code one, so ours is stale and every store would (rightly) refuse it
449
+ if ((0, remoteConfig_1.getConfigVersion)(state.config) > (0, remoteConfig_1.getConfigVersion)(configured)) {
450
+ this.schedule(exports.CONFIG_WRITE_REFRESH_INTERVAL);
451
+ return;
452
+ }
453
+ // Same version but different content: startup already decided the stored one wins until the version is bumped (see chooseStartupConfig), and re-writing ours would flip the bucket back and forth between the two
454
+ if ((0, remoteConfig_1.getConfigVersion)(state.config) === (0, remoteConfig_1.getConfigVersion)(configured) && JSON.stringify(state.config) !== JSON.stringify(configured)) {
455
+ this.schedule(exports.CONFIG_WRITE_REFRESH_INTERVAL);
456
+ return;
457
+ }
458
+ let { failures, total } = await writeRoutingToAllStores({ configured, sources: state.sources, debugName: this.config.debugName() });
459
+ if (failures.length) {
460
+ console.error(`The periodic routing config write for ${this.config.debugName()} (version ${(0, remoteConfig_1.getConfigVersion)(configured)}) failed on ${failures.length} of ${total} stores - retrying in ${exports.CONFIG_WRITE_RETRY_INTERVAL / 1000}s: ${failures.join(" | ")}`);
461
+ this.schedule(exports.CONFIG_WRITE_RETRY_INTERVAL);
462
+ return;
463
+ }
464
+ this.schedule(exports.CONFIG_WRITE_REFRESH_INTERVAL);
465
+ }
466
+ }
467
+ exports.RoutingRewriteLoop = RoutingRewriteLoop;
468
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhaW5TdGFydHVwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY2hhaW5TdGFydHVwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1EQUFrRDtBQUVsRCxpREFBK0g7QUFDL0gsbURBQWtHO0FBQ2xHLCtEQUFtRTtBQUNuRSx1RUFBcUY7QUFFckYsNGRBQTRkO0FBRTVkLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDM0MsTUFBTSw2QkFBNkIsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQy9DLHNOQUFzTjtBQUN6TSxRQUFBLDJCQUEyQixHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQ3pELGdIQUFnSDtBQUNuRyxRQUFBLDZCQUE2QixHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBTzVELG1PQUFtTztBQUNuTyxNQUFhLGlCQUFpQjtJQWMxQixZQUFvQixNQUtuQjtRQUxtQixXQUFNLEdBQU4sTUFBTSxDQUt6QjtRQVpPLG1CQUFjLEdBQUcsaUNBQWlCLENBQUM7UUFHbkMsYUFBUSxHQUFHLEtBQUssQ0FBQztRQXNOakIsNEJBQXVCLEdBQUcsQ0FBQyxDQUFDO1FBNU1oQyxJQUFJLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUM7UUFDcEMsSUFBSSxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxrQkFBa0IsQ0FBQztZQUMxQyxVQUFVLEVBQUUsTUFBTSxDQUFDLFVBQVU7WUFDN0IsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTO1lBQzNCLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVztTQUNqQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBQSxnREFBc0IsRUFBQyxHQUFHLEVBQUU7WUFDdEQsS0FBSyxJ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QTZCLENBQUMsQ0FBQztZQUM3QyxPQUFPO1FBQ1gsQ0FBQztRQUNELElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLEdBQUcsTUFBTSx1QkFBdUIsQ0FBQyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDcEksSUFBSSxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDbEIsT0FBTyxDQUFDLEtBQUssQ0FBQyx5Q0FBeUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsYUFBYSxJQUFBLCtCQUFnQixFQUFDLFVBQVUsQ0FBQyxlQUFlLFFBQVEsQ0FBQyxNQUFNLE9BQU8sS0FBSyx5QkFBeUIsbUNBQTJCLEdBQUcsSUFBSSxNQUFNLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzFQLElBQUksQ0FBQyxRQUFRLENBQUMsbUNBQTJCLENBQUMsQ0FBQztZQUMzQyxPQUFPO1FBQ1gsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRLENBQUMscUNBQTZCLENBQUMsQ0FBQztJQUNqRCxDQUFDO0NBQ0o7QUFoRUQsZ0RBZ0VDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXNOb2RlIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvbWlzY1wiO1xuaW1wb3J0IHsgUmVtb3RlQ29uZmlnLCBTb3VyY2VDb25maWcgfSBmcm9tIFwiLi4vSUFyY2hpdmVzXCI7XG5pbXBvcnQgeyBST1VUSU5HX0ZJTEUsIGdldENvbmZpZ1ZlcnNpb24sIHNlcmlhbGl6ZVJlbW90ZUNvbmZpZywgbm9ybWFsaXplUmVtb3RlQ29uZmlnLCBub3JtYWxpemVTb3VyY2UgfSBmcm9tIFwiLi9yZW1vdGVDb25maWdcIjtcbmltcG9ydCB7IFNvdXJjZVdyYXBwZXIsIFJFVFJZX1NUQVJUX0RFTEFZLCBSRVRSWV9NQVhfREVMQVksIFJFVFJZX0dST1dUSCB9IGZyb20gXCIuL3NvdXJjZVdyYXBwZXJcIjtcbmltcG9ydCB7IHJlc29sdmVJbnRlcm1lZGlhdGVTb3VyY2VzIH0gZnJvbSBcIi4vaW50ZXJtZWRpYXRlU291cmNlc1wiO1xuaW1wb3J0IHsgb25TZXJ2ZXJSb3V0aW5nQ2hhbmdlZCwgdHJhY2tDaGFpbkNvbmZpZyB9IGZyb20gXCIuL3N0b3JhZ2VDbGllbnRDb250cm9sbGVyXCI7XG5cbi8vIFRoZSBMSUZFQ1lDTEUgb2YgYW4gQXJjaGl2ZXNDaGFpbidzIHN0YXRlLCBhbmQgbm90aGluZyBlbHNlOiBpbml0aWFsaXppbmcgaXQgKHByb2JpbmcgZXZlcnkgY29uZmlndXJlZCBzb3VyY2UsIGRlY2lkaW5nIHdoaWNoIHJvdXRpbmcgY29uZmlnIHRvIHJ1biwgd3JpdGluZyBvdXJzIG91dCB3aGVuIGl0IGlzIHRoZSBuZXdlc3QpLCB0aGUgcmV0cnkgd2hlbiBpbml0aWFsaXphdGlvbiBmYWlscywgdGhlIHBvbGwgdGhhdCBhZG9wdHMgbmV3ZXIgY29uZmlncywgdGhlIGF2YWlsYWJpbGl0eSByZWNoZWNrLCBhbmQgdGhlIGxvb3AgdGhhdCBrZWVwcyByZS13cml0aW5nIG91ciBjb25maWcuIE5vbmUgb2YgdGhpcyBpcyByZXF1ZXN0IGRpc3BhdGNoIC0gdGhlIGNoYWluIChjcmVhdGVBcmNoaXZlcy50cykgYXNrcyB0aGUgQ2hhaW5TdGF0ZU1hbmFnZXIgZm9yIHRoZSBjdXJyZW50IHN0YXRlIGFuZCBkaXNwYXRjaGVzIG92ZXIgaXQuXG5cbmNvbnN0IENPTkZJR19QT0xMX0lOVEVSVkFMID0gNSAqIDYwICogMTAwMDtcbmNvbnN0IEFWQUlMQUJJTElUWV9SRUNIRUNLX1RIUk9UVExFID0gNSAqIDEwMDA7XG4vLyBUaGUgcm91dGluZyBjb25maWcgd3JpdGUgaXMgcmV0cmllZCBvbiB0aGlzIGNhZGVuY2Ugd2hpbGUgaXQgaXMgZmFpbGluZy4gQSBzdG9yZSB0aGF0IG5ldmVyIHJlY2VpdmVkIHRoZSBjb25maWcgcmVqZWN0cyBldmVyeSB3cml0ZSBhaW1lZCBhdCBpdCwgc28gdGhpcyBub3QgbGFuZGluZyBpcyBhIGJpZyBkZWFsIC0gZWFjaCBmYWlsZWQgYXR0ZW1wdCBpcyBsb2dnZWQuXG5leHBvcnQgY29uc3QgQ09ORklHX1dSSVRFX1JFVFJZX0lOVEVSVkFMID0gNSAqIDYwICogMTAwMDtcbi8vIC4uLmFuZCBldmVuIGFmdGVyIHN1Y2Nlc3MgaXQgaXMgcmUtd3JpdHRlbiBvbiB0aGlzIGNhZGVuY2UsIGluIGNhc2UgYSBzdG9yZSBsb3N0IGl0IG9yIGEgc2VydmVyIGFwcGVhcmVkIGxhdGVcbmV4cG9ydCBjb25zdCBDT05GSUdfV1JJVEVfUkVGUkVTSF9JTlRFUlZBTCA9IDYwICogNjAgKiAxMDAwO1xuXG5leHBvcnQgdHlwZSBDaGFpblN0YXRlID0ge1xuICAgIGNvbmZpZzogUmVtb3RlQ29uZmlnO1xuICAgIHNvdXJjZXM6IFNvdXJjZVdyYXBwZXJbXTtcbn07XG5cbi8qKiBUaGUgY2hhaW4ncyBzdGF0ZSBhbmQgZXZlcnl0aGluZyBhYm91dCBIQVZJTkcgb25lOiBpbml0ICh3aXRoIGl0cyByZXRyeSksIHRoZSBjb25maWcgcG9sbCwgYXZhaWxhYmlsaXR5IHJlY2hlY2tzLCBhbmQgdGhlIHJvdXRpbmcgcmV3cml0ZSBsb29wLiBUaGUgY2hhaW4gY29uc3RydWN0cyBvbmUsIGFza3MgaXQgZ2V0U3RhdGUoKSBvbiBldmVyeSBjYWxsLCBhbmQgZGlzcG9zZXMgaXQuICovXG5leHBvcnQgY2xhc3MgQ2hhaW5TdGF0ZU1hbmFnZXIge1xuICAgIHB1YmxpYyByZWFkb25seSBjb25maWd1cmVkOiBSZW1vdGVDb25maWc7XG4gICAgLyoqIFRoZSBuZXdlc3QgYWRvcHRlZCBjb25maWcgLSB3aGF0IGdldERlYnVnTmFtZSBhbmQgZGlzcGF0Y2ggZGVjaXNpb25zIHJlYWQuIFN0YXJ0cyBhcyB0aGUgY29uZmlndXJlZCBvbmUgYW5kIG1vdmVzIHdpdGggZXZlcnkgYWRvcHRpb24uICovXG4gICAgcHVibGljIGFjdGl2ZUNvbmZpZzogUmVtb3RlQ29uZmlnO1xuICAgIHByaXZhdGUgc3RhdGVQcm9taXNlOiBQcm9taXNlPENoYWluU3RhdGU+IHwgdW5kZWZpbmVkO1xuICAgIC8vIFRoZSByZXNvbHZlZCBzdGF0ZSwgZm9yIHN5bmNocm9ub3VzIGFjY2VzcyAoZ2V0R2V0VVJMcykgLSBhbHdheXMgdGhlIG5ld2VzdCBhZG9wdGVkIGNvbmZpZywgd2hlcmUgc3RhdGVQcm9taXNlIG1heSBicmllZmx5IGxhZyBkdXJpbmcgYSByZWJ1aWxkXG4gICAgcHJpdmF0ZSBsYXRlc3RTdGF0ZTogQ2hhaW5TdGF0ZSB8IHVuZGVmaW5lZDtcbiAgICBwcml2YXRlIGluaXRSZXRyeURlbGF5ID0gUkVUUllfU1RBUlRfREVMQVk7XG4gICAgcHJpdmF0ZSBpbml0UmV0cnlUaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCB1bmRlZmluZWQ7XG4gICAgcHJpdmF0ZSBwb2xsVGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldEludGVydmFsPiB8IHVuZGVmaW5lZDtcbiAgICBwcml2YXRlIGRpc3Bvc2VkID0gZmFsc2U7XG4gICAgcHJpdmF0ZSB1bnN1YnNjcmliZVJvdXRpbmdQdXNoOiAoKCkgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XG4gICAgcHJpdmF0ZSByb3V0aW5nUmV3cml0ZXI6IFJvdXRpbmdSZXdyaXRlTG9vcDtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgY29uZmlnOiB7XG4gICAgICAgIGNvbmZpZ3VyZWQ6IFJlbW90ZUNvbmZpZztcbiAgICAgICAgZGVidWdOYW1lOiAoKSA9PiBzdHJpbmc7XG4gICAgICAgIC8qKiBTZWUgQXJjaGl2ZXNDaGFpbk9wdGlvbnMuZGlyZWN0Q29ubmVjdC4gKi9cbiAgICAgICAgZGlyZWN0Q29ubmVjdD86IGJvb2xlYW47XG4gICAgfSkge1xuICAgICAgICB0aGlzLmNvbmZpZ3VyZWQgPSBjb25maWcuY29uZmlndXJlZDtcbiAgICAgICAgdGhpcy5hY3RpdmVDb25maWcgPSBjb25maWcuY29uZmlndXJlZDtcbiAgICAgICAgdGhpcy5yb3V0aW5nUmV3cml0ZXIgPSBuZXcgUm91dGluZ1Jld3JpdGVMb29wKHtcbiAgICAgICAgICAgIGNvbmZpZ3VyZWQ6IGNvbmZpZy5jb25maWd1cmVkLFxuICAgICAgICAgICAgZGVidWdOYW1lOiBjb25maWcuZGVidWdOYW1lLFxuICAgICAgICAgICAgbGF0ZXN0OiAoKSA9PiB0aGlzLmxhdGVzdFN0YXRlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy51bnN1YnNjcmliZVJvdXRpbmdQdXNoID0gb25TZXJ2ZXJSb3V0aW5nQ2hhbmdlZCgoKSA9PiB7XG4gICAgICAgICAgICB2b2lkIHRoaXMucmVmcmVzaEFjdGl2ZUNvbmZpZygpLmNhdGNoKChlOiBFcnJvcikgPT4gY29uc29sZS5lcnJvcihgQ29uZmlnIHJlZnJlc2ggZmFpbGVkIGZvciAke3RoaXMuY29uZmlnLmRlYnVnTmFtZSgpfTogJHtlLnN0YWNrID8/IGV9YCkpO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gU28gYSBzZXJ2ZXIgY2FuIGFzayB3aGF0IGNvbmZpZyB3ZSBpbnRlbmRlZCBmb3IgYSBzdG9yZSBuYW1lIChzZWUgU3RvcmFnZUNsaWVudENvbnRyb2xsZXIuZ2V0Um91dGluZ0NvbmZpZ0Zvck5hbWUpXG4gICAgICAgIHRoaXMudW50cmFja0NvbmZpZyA9IHRyYWNrQ2hhaW5Db25maWcoeyBjb25maWd1cmVkOiBjb25maWcuY29uZmlndXJlZCwgYWN0aXZlOiAoKSA9PiB0aGlzLmFjdGl2ZUNvbmZpZyB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVudHJhY2tDb25maWc6ICgpID0+IHZvaWQ7XG5cbiAgICAvKiogVGhlIG5ld2VzdCBhZG9wdGVkIHN0YXRlLCBzeW5jaHJvbm91c2x5IC0gdW5kZWZpbmVkIHVudGlsIHRoZSBmaXJzdCBpbml0IGZpbmlzaGVzLiAqL1xuICAgIHB1YmxpYyBsYXRlc3QoKTogQ2hhaW5TdGF0ZSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiB0aGlzLmxhdGVzdFN0YXRlO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRTdGF0ZSgpOiBQcm9taXNlPENoYWluU3RhdGU+IHtcbiAgICAgICAgaWYgKHRoaXMuZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoYEFyY2hpdmVzQ2hhaW4gJHt0aGlzLmNvbmZpZy5kZWJ1Z05hbWUoKX0gaGFzIGJlZW4gZGlzcG9zZWRgKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlUHJvbWlzZSkge1xuICAgICAgICAgICAgbGV0IHByb21pc2UgPSB0aGlzLmluaXQoKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdGVQcm9taXNlID0gcHJvbWlzZTtcbiAgICAgICAgICAgIHByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmV0cnlEZWxheSA9IFJFVFJZX1NUQVJUX0RFTEFZO1xuICAgICAgICAgICAgfSwgKGU6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZGlzcG9zZWQgfHwgdGhpcy5pbml0UmV0cnlUaW1lcikgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFN0b3JhZ2UgaW5pdCBmYWlsZWQgZm9yICR7dGhpcy5jb25maWcuZGVidWdOYW1lKCl9LCByZXRyeWluZyBpbiAke01hdGgucm91bmQodGhpcy5pbml0UmV0cnlEZWxheSAvIDEwMDApfXMuICR7ZS5zdGFjayA/PyBlfWApO1xuICAgICAgICAgICAgICAgIHRoaXMuaW5pdFJldHJ5VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0UmV0cnlUaW1lciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGlzcG9zZWQpIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGVQcm9taXNlID09PSBwcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlUHJvbWlzZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmdldFN0YXRlKCkuY2F0Y2goKCkgPT4geyB9KTtcbiAgICAgICAgICAgICAgICB9LCB0aGlzLmluaXRSZXRyeURlbGF5KTtcbiAgICAgICAgICAgICAgICAodGhpcy5pbml0UmV0cnlUaW1lciBhcyB7IHVucmVmPzogKCkgPT4gdm9pZCB9KS51bnJlZj8uKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmV0cnlEZWxheSA9IE1hdGgubWluKFJFVFJZX01BWF9ERUxBWSwgdGhpcy5pbml0UmV0cnlEZWxheSAqIFJFVFJZX0dST1dUSCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZVByb21pc2U7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBpbml0KCk6IFByb21pc2U8Q2hhaW5TdGF0ZT4ge1xuICAgICAgICBsZXQgY29uZmlncyA9IHRoaXMuY29uZmlndXJlZC5zb3VyY2VzLm1hcChub3JtYWxpemVTb3VyY2UpO1xuICAgICAgICBsZXQgcmVhZE9ubHkgPSB0aGlzLmlzUmVhZE9ubHkodGhpcy5jb25maWd1cmVkKTtcbiAgICAgICAgbGV0IHByb2JlcyA9IGF3YWl0IHByb2JlU291cmNlcyhjb25maWdzLCByZWFkT25seSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgeyBhY3RpdmUsIG5lZWRzV3JpdGUsIGV4aXN0aW5nIH0gPSBjaG9vc2VTdGFydHVwQ29uZmlnKHsgY29uZmlndXJlZDogdGhpcy5jb25maWd1cmVkLCBwcm9iZXMsIGRlYnVnTmFtZTogdGhpcy5jb25maWcuZGVidWdOYW1lKCkgfSk7XG4gICAgICAgICAgICBsZXQgc291cmNlcyA9IGF3YWl0IHRoaXMuYnVpbGRTb3VyY2VzKGFjdGl2ZSk7XG4gICAgICAgICAgICBsZXQgY29uZmlnV3JpdGVGYWlsZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChuZWVkc1dyaXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFN0b3JhZ2Ugcm91dGluZyBjb25maWcgZm9yICR7dGhpcy5jb25maWcuZGVidWdOYW1lKCl9IGlzIG91dCBvZiBkYXRlIChzdG9yZWQgdmVyc2lvbiAke2V4aXN0aW5nICYmIGdldENvbmZpZ1ZlcnNpb24oZXhpc3RpbmcpIHx8IFwibm9uZVwifSwgb3VycyAke2dldENvbmZpZ1ZlcnNpb24odGhpcy5jb25maWd1cmVkKX0pYCk7XG4gICAgICAgICAgICAgICAgbGV0IHsgZmFpbHVyZXMsIHRvdGFsIH0gPSBhd2FpdCB3cml0ZVJvdXRpbmdUb0FsbFN0b3Jlcyh7IGNvbmZpZ3VyZWQ6IHRoaXMuY29uZmlndXJlZCwgc291cmNlcywgZGVidWdOYW1lOiB0aGlzLmNvbmZpZy5kZWJ1Z05hbWUoKSB9KTtcbiAgICAgICAgICAgICAgICBjb25maWdXcml0ZUZhaWxlZCA9IGZhaWx1cmVzLmxlbmd0aCA+IDA7XG4gICAgICAgICAgICAgICAgaWYgKGZhaWx1cmVzLmxlbmd0aCAmJiBmYWlsdXJlcy5sZW5ndGggPT09IHRvdGFsKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIE5vYm9keSBoYXMgb3VyIGNvbmZpZywgc28gcnVubmluZyBvbiBpdCB3b3VsZCBqdXN0IGRpc2FncmVlIHdpdGggZXZlcnkgc2VydmVyLiBUaGUgc3RvcmVkIG9uZSAod2hlbiB0aGVyZSBpcyBvbmUpIGlzIHdoYXQgdGhlIHNlcnZlcnMgYWN0dWFsbHkgcnVuLlxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBUaGUgc3RvcmFnZSByb3V0aW5nIGNvbmZpZyBmb3IgJHt0aGlzLmNvbmZpZy5kZWJ1Z05hbWUoKX0gKHZlcnNpb24gJHtnZXRDb25maWdWZXJzaW9uKHRoaXMuY29uZmlndXJlZCl9KSBjb3VsZCBub3QgYmUgd3JpdHRlbiB0byBBTlkgb2YgdGhlICR7dG90YWx9IHN0b3Jlcy4gJHtleGlzdGluZyAmJiBgUnVubmluZyBvbiB0aGUgc3RvcmVkIGNvbmZpZyAodmVyc2lvbiAke2dldENvbmZpZ1ZlcnNpb24oZXhpc3RpbmcpfSkgdW50aWwgYSB3cml0ZSBzdWNjZWVkcy5gIHx8IGBObyBzdG9yZWQgY29uZmlnIGV4aXN0cyBlaXRoZXIsIHNvIHNlcnZlcnMgd2lsbCByZWplY3Qgd3JpdGVzIHVudGlsIHRoaXMgc3VjY2VlZHMuYH0gUmV0cnlpbmcgaW4gJHtDT05GSUdfV1JJVEVfUkVUUllfSU5URVJWQUwgLyAxMDAwfXMuIEZhaWx1cmVzOiAke2ZhaWx1cmVzLmpvaW4oXCIgfCBcIil9YCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aXZlID0gZXhpc3Rpbmc7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBzb3VyY2Ugb2Ygc291cmNlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZS5kaXNwb3NlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VzID0gYXdhaXQgdGhpcy5idWlsZFNvdXJjZXMoYWN0aXZlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZmFpbHVyZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFRoZSBzdG9yYWdlIHJvdXRpbmcgY29uZmlnIGZvciAke3RoaXMuY29uZmlnLmRlYnVnTmFtZSgpfSAodmVyc2lvbiAke2dldENvbmZpZ1ZlcnNpb24odGhpcy5jb25maWd1cmVkKX0pIHdhcyB3cml0dGVuIHRvICR7dG90YWwgLSBmYWlsdXJlcy5sZW5ndGh9IG9mICR7dG90YWx9IHN0b3Jlcy4gUmV0cnlpbmcgdGhlIHJlc3QgaW4gJHtDT05GSUdfV1JJVEVfUkVUUllfSU5URVJWQUwgLyAxMDAwfXMgKHRoZXkgYWxzbyBwdWxsIGl0IGZyb20gdGhlIHN0b3JlcyB0aGF0IGhhdmUgaXQpLiBGYWlsdXJlczogJHtmYWlsdXJlcy5qb2luKFwiIHwgXCIpfWApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IHNvdXJjZSBvZiBzb3VyY2VzKSB7XG4gICAgICAgICAgICAgICAgbGV0IHByb2JlID0gcHJvYmVzLmZpbmQoeCA9PiB4LnJlc3BvbmRlZCAmJiB4LnNvdXJjZUNvbmZpZy51cmwgPT09IHNvdXJjZS5jb25maWcudXJsKTtcbiAgICAgICAgICAgICAgICBpZiAocHJvYmUpIHtcbiAgICAgICAgICAgICAgICAgICAgc291cmNlLnNlZWRMYXRlbmN5KHByb2JlLmxhdGVuY3kpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuYWN0aXZlQ29uZmlnID0gYWN0aXZlO1xuICAgICAgICAgICAgdGhpcy5zdGFydENvbmZpZ1BvbGwoKTtcbiAgICAgICAgICAgIGxldCBzdGF0ZTogQ2hhaW5TdGF0ZSA9IHsgY29uZmlnOiBhY3RpdmUsIHNvdXJjZXMgfTtcbiAgICAgICAgICAgIHRoaXMubGF0ZXN0U3RhdGUgPSBzdGF0ZTtcbiAgICAgICAgICAgIHRoaXMucm91dGluZ1Jld3JpdGVyLnN0YXJ0KGNvbmZpZ1dyaXRlRmFpbGVkKTtcbiAgICAgICAgICAgIHJldHVybiBzdGF0ZTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGRpc3Bvc2VQcm9iZXMocHJvYmVzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBDbGllbnRzaWRlLCBhIGNvbmZpZyB3aXRoIHB1YmxpYyBzb3VyY2VzIGlzIHNlcnZlZCBlbnRpcmVseSBvdmVyIHBsYWluIFVSTCBkb3dubG9hZHMgLSBubyBBUEkgY29ubmVjdGlvbiwgbm8gYWNjZXNzIGdyYW50LCBhbmQgbm8gd3JpdGluZy4gZGlyZWN0Q29ubmVjdCBvcHRzIG91dCBvZiB0aGF0LiAqL1xuICAgIHByaXZhdGUgaXNSZWFkT25seShjb25maWc6IFJlbW90ZUNvbmZpZyk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAodGhpcy5jb25maWcuZGlyZWN0Q29ubmVjdCB8fCBpc05vZGUoKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gY29uZmlnLnNvdXJjZXMubWFwKG5vcm1hbGl6ZVNvdXJjZSkuc29tZSh4ID0+IHgucHVibGljKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGNyZWF0ZUNoYWluU291cmNlKHNvdXJjZUNvbmZpZzogU291cmNlQ29uZmlnLCByZWFkT25seTogYm9vbGVhbik6IFByb21pc2U8U291cmNlV3JhcHBlcj4ge1xuICAgICAgICBsZXQgc291cmNlID0gYXdhaXQgU291cmNlV3JhcHBlci5jcmVhdGUoc291cmNlQ29uZmlnLCB7IHJlYWRPbmx5IH0pO1xuICAgICAgICBzb3VyY2Uuc3RhcnRQaW5naW5nKCk7XG4gICAgICAgIHJldHVybiBzb3VyY2U7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBidWlsZFNvdXJjZXMoY29uZmlnOiBSZW1vdGVDb25maWcpOiBQcm9taXNlPFNvdXJjZVdyYXBwZXJbXT4ge1xuICAgICAgICBsZXQgcmVhZE9ubHkgPSB0aGlzLmlzUmVhZE9ubHkoY29uZmlnKTtcbiAgICAgICAgbGV0IHNvdXJjZXM6IFNvdXJjZVdyYXBwZXJbXSA9IFtdO1xuICAgICAgICBmb3IgKGxldCBzb3VyY2VDb25maWcgb2YgY29uZmlnLnNvdXJjZXMubWFwKG5vcm1hbGl6ZVNvdXJjZSkpIHtcbiAgICAgICAgICAgIHNvdXJjZXMucHVzaChhd2FpdCB0aGlzLmNyZWF0ZUNoYWluU291cmNlKHNvdXJjZUNvbmZpZywgcmVhZE9ubHkpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc291cmNlcztcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXJ0Q29uZmlnUG9sbCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMucG9sbFRpbWVyIHx8IHRoaXMuZGlzcG9zZWQpIHJldHVybjtcbiAgICAgICAgdGhpcy5wb2xsVGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICB2b2lkIHRoaXMucmVmcmVzaEFjdGl2ZUNvbmZpZygpLmNhdGNoKChlOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYENoZWNraW5nIGZvciBhIG5ldyBzdG9yYWdlIHJvdXRpbmcgY29uZmlnIGZhaWxlZCBmb3IgJHt0aGlzLmNvbmZpZy5kZWJ1Z05hbWUoKX06ICR7ZS5zdGFjayA/PyBlfWApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIENPTkZJR19QT0xMX0lOVEVSVkFMKTtcbiAgICAgICAgKHRoaXMucG9sbFRpbWVyIGFzIHsgdW5yZWY/OiAoKSA9PiB2b2lkIH0pLnVucmVmPy4oKTtcbiAgICB9XG5cbiAgICAvLyBEZWR1cGxpY2F0ZXMgY29uY3VycmVudCByZWZyZXNoZXMgKHRoZSBwb2xsIHRpbWVyIGFuZCB3cm9uZy10YXJnZXQgd3JpdGUgcmV0cmllcyBzaGFyZSB0aGlzKVxuICAgIHByaXZhdGUgY29uZmlnUmVmcmVzaEluRmxpZ2h0OiBQcm9taXNlPHZvaWQ+IHwgdW5kZWZpbmVkO1xuICAgIHB1YmxpYyByZWZyZXNoQWN0aXZlQ29uZmlnKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoIXRoaXMuY29uZmlnUmVmcmVzaEluRmxpZ2h0KSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZ1JlZnJlc2hJbkZsaWdodCA9IHRoaXMuY2hlY2tGb3JOZXdDb25maWcoKS5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ1JlZnJlc2hJbkZsaWdodCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZ1JlZnJlc2hJbkZsaWdodDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGZldGNoTGF0ZXN0Q29uZmlnKHN0YXRlOiBDaGFpblN0YXRlKTogUHJvbWlzZTxSZW1vdGVDb25maWcgfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgbGV0IGVycm9yczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgc291cmNlIG9mIHN0YXRlLnNvdXJjZXMpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbGV0IGxhdGVzdCA9IGF3YWl0IHNvdXJjZS5yZWFkUm91dGluZ0NvbmZpZygpO1xuICAgICAgICAgICAgICAgIGlmIChsYXRlc3QpIHJldHVybiBub3JtYWxpemVSZW1vdGVDb25maWcobGF0ZXN0KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChgJHtzb3VyY2UuY29uZmlnLnVybH06ICR7KGUgYXMgRXJyb3IpLnN0YWNrID8/IGV9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVycm9ycy5sZW5ndGggPT09IHN0YXRlLnNvdXJjZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHN0b3JhZ2Ugc291cmNlIGNvdWxkIGdpdmUgdXMgdGhlIHJvdXRpbmcgY29uZmlnIGZvciAke3RoaXMuY29uZmlnLmRlYnVnTmFtZSgpfTogJHtlcnJvcnMuam9pbihcIiB8IFwiKX1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgY2hlY2tGb3JOZXdDb25maWcoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLmRpc3Bvc2VkIHx8ICF0aGlzLnN0YXRlUHJvbWlzZSkgcmV0dXJuO1xuICAgICAgICBsZXQgc3RhdGU6IENoYWluU3RhdGU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzdGF0ZSA9IGF3YWl0IHRoaXMuc3RhdGVQcm9taXNlO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbGF0ZXN0ID0gYXdhaXQgdGhpcy5mZXRjaExhdGVzdENvbmZpZyhzdGF0ZSk7XG4gICAgICAgIGlmICghbGF0ZXN0KSByZXR1cm47XG4gICAgICAgIGF3YWl0IHRoaXMuYWRvcHROZXdDb25maWcoc3RhdGUsIGxhdGVzdCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBhZG9wdE5ld0NvbmZpZyhzdGF0ZTogQ2hhaW5TdGF0ZSwgbGF0ZXN0OiBSZW1vdGVDb25maWcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKEpTT04uc3RyaW5naWZ5KGxhdGVzdCkgPT09IEpTT04uc3RyaW5naWZ5KHN0YXRlLmNvbmZpZykpIHJldHVybjtcbiAgICAgICAgbGV0IHJlY2VpdmVkID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgICBsZXQgb25seUludGVybWVkaWF0ZXNDaGFuZ2VkID0gSlNPTi5zdHJpbmdpZnkocmVzb2x2ZUludGVybWVkaWF0ZVNvdXJjZXMobGF0ZXN0KSkgPT09IEpTT04uc3RyaW5naWZ5KHJlc29sdmVJbnRlcm1lZGlhdGVTb3VyY2VzKHN0YXRlLmNvbmZpZykpO1xuICAgICAgICBpZiAob25seUludGVybWVkaWF0ZXNDaGFuZ2VkKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgU3RvcmFnZSByb3V0aW5nIHN3aXRjaG92ZXIgd2luZG93cyBjaGFuZ2VkICh2ZXJzaW9uICR7Z2V0Q29uZmlnVmVyc2lvbihzdGF0ZS5jb25maWcpfSAtPiAke2dldENvbmZpZ1ZlcnNpb24obGF0ZXN0KX0pLCByZWNlaXZlZCAke3JlY2VpdmVkfSwgcmVidWlsZGluZyBzb3VyY2VzLiBOZXcgY29uZmlnOiAke0pTT04uc3RyaW5naWZ5KGxhdGVzdCl9YCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgU3RvcmFnZSByb3V0aW5nIGNvbmZpZyBjaGFuZ2VkICh2ZXJzaW9uICR7Z2V0Q29uZmlnVmVyc2lvbihzdGF0ZS5jb25maWcpfSAtPiAke2dldENvbmZpZ1ZlcnNpb24obGF0ZXN0KX0pLCByZWNlaXZlZCAke3JlY2VpdmVkfSwgcmVidWlsZGluZyBzb3VyY2VzLiBOZXcgY29uZmlnOiAke0pTT04uc3RyaW5naWZ5KGxhdGVzdCl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHN0cmlwcGVkS2V5ID0gKGNvbmZpZzogU291cmNlQ29uZmlnKSA9PiBKU09OLnN0cmluZ2lmeSh7IC4uLmNvbmZpZywgdmFsaWRXaW5kb3c6IHVuZGVmaW5lZCB9KTtcbiAgICAgICAgbGV0IG9sZEJ5Q29uZmlnID0gbmV3IE1hcDxzdHJpbmcsIFNvdXJjZVdyYXBwZXJbXT4oKTtcbiAgICAgICAgZm9yIChsZXQgc291cmNlIG9mIHN0YXRlLnNvdXJjZXMpIHtcbiAgICAgICAgICAgIGxldCBrZXkgPSBzdHJpcHBlZEtleShzb3VyY2UuY29uZmlnKTtcbiAgICAgICAgICAgIGxldCBsaXN0ID0gb2xkQnlDb25maWcuZ2V0KGtleSk7XG4gICAgICAgICAgICBpZiAoIWxpc3QpIHtcbiAgICAgICAgICAgICAgICBsaXN0ID0gW107XG4gICAgICAgICAgICAgICAgb2xkQnlDb25maWcuc2V0KGtleSwgbGlzdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsaXN0LnB1c2goc291cmNlKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVhZE9ubHkgPSB0aGlzLmlzUmVhZE9ubHkobGF0ZXN0KTtcbiAgICAgICAgbGV0IHNvdXJjZXM6IFNvdXJjZVdyYXBwZXJbXSA9IFtdO1xuICAgICAgICBmb3IgKGxldCBzb3VyY2VDb25maWcgb2YgbGF0ZXN0LnNvdXJjZXMubWFwKG5vcm1hbGl6ZVNvdXJjZSkpIHtcbiAgICAgICAgICAgIGxldCBvbGQgPSBvbGRCeUNvbmZpZy5nZXQoc3RyaXBwZWRLZXkoc291cmNlQ29uZmlnKSk/LnNoaWZ0KCk7XG4gICAgICAgICAgICBpZiAob2xkKSB7XG4gICAgICAgICAgICAgICAgb2xkLnVwZGF0ZVZhbGlkV2luZG93KHNvdXJjZUNvbmZpZy52YWxpZFdpbmRvdyk7XG4gICAgICAgICAgICAgICAgc291cmNlcy5wdXNoKG9sZCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNvdXJjZXMucHVzaChhd2FpdCB0aGlzLmNyZWF0ZUNoYWluU291cmNlKHNvdXJjZUNvbmZpZywgcmVhZE9ubHkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBsZWZ0b3ZlcnMgb2Ygb2xkQnlDb25maWcudmFsdWVzKCkpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGxlZnRvdmVyIG9mIGxlZnRvdmVycykge1xuICAgICAgICAgICAgICAgIGxlZnRvdmVyLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFjdGl2ZUNvbmZpZyA9IGxhdGVzdDtcbiAgICAgICAgbGV0IG5ld1N0YXRlOiBDaGFpblN0YXRlID0geyBjb25maWc6IGxhdGVzdCwgc291cmNlcyB9O1xuICAgICAgICB0aGlzLmxhdGVzdFN0YXRlID0gbmV3U3RhdGU7XG4gICAgICAgIHRoaXMuc3RhdGVQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKG5ld1N0YXRlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGxhc3RBdmFpbGFiaWxpdHlSZWNoZWNrID0gMDtcbiAgICBwcml2YXRlIGF2YWlsYWJpbGl0eVJlY2hlY2tJbkZsaWdodDogUHJvbWlzZTx2b2lkPiB8IHVuZGVmaW5lZDtcbiAgICAvKiogRXZlcnkgc291cmNlIGZhaWxlZDogcmUtY29udGFjdCBhbGwgb2YgdGhlbSAocm91dGluZyByZS1yZWFkICsgY29ubmVjdGlvbiByZS1hdHRlbXB0KSBhbmQgYWRvcHQgd2hhdGV2ZXIgY29uZmlnIGNvbWVzIGJhY2suIFRocm90dGxlZCwgYW5kIGRlZHVwbGljYXRlZCBhY3Jvc3MgY29uY3VycmVudCBjYWxsZXJzLiAqL1xuICAgIHB1YmxpYyByZWNoZWNrQXZhaWxhYmlsaXR5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAodGhpcy5hdmFpbGFiaWxpdHlSZWNoZWNrSW5GbGlnaHQpIHJldHVybiB0aGlzLmF2YWlsYWJpbGl0eVJlY2hlY2tJbkZsaWdodDtcbiAgICAgICAgaWYgKERhdGUubm93KCkgLSB0aGlzLmxhc3RBdmFpbGFiaWxpdHlSZWNoZWNrIDwgQVZBSUxBQklMSVRZX1JFQ0hFQ0tfVEhST1RUTEUpIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgdGhpcy5sYXN0QXZhaWxhYmlsaXR5UmVjaGVjayA9IERhdGUubm93KCk7XG4gICAgICAgIHRoaXMuYXZhaWxhYmlsaXR5UmVjaGVja0luRmxpZ2h0ID0gdGhpcy5yZWNoZWNrQXZhaWxhYmlsaXR5Tm93KCkuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmF2YWlsYWJpbGl0eVJlY2hlY2tJbkZsaWdodCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLmF2YWlsYWJpbGl0eVJlY2hlY2tJbkZsaWdodDtcbiAgICB9XG4gICAgcHJpdmF0ZSBhc3luYyByZWNoZWNrQXZhaWxhYmlsaXR5Tm93KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAodGhpcy5kaXNwb3NlZCB8fCAhdGhpcy5zdGF0ZVByb21pc2UpIHJldHVybjtcbiAgICAgICAgbGV0IHN0YXRlOiBDaGFpblN0YXRlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgc3RhdGUgPSBhd2FpdCB0aGlzLnN0YXRlUHJvbWlzZTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5sb2coYEV2ZXJ5IHN0b3JhZ2Ugc291cmNlIGZhaWxlZCBmb3IgJHt0aGlzLmNvbmZpZy5kZWJ1Z05hbWUoKX07IHJlLWNvbnRhY3RpbmcgYWxsICR7c3RhdGUuc291cmNlcy5sZW5ndGh9IHNvdXJjZXMgKHJvdXRpbmcgcmUtcmVhZCArIGNvbm5lY3Rpb24gcmUtYXR0ZW1wdClgKTtcbiAgICAgICAgbGV0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChzdGF0ZS5zb3VyY2VzLm1hcChhc3luYyBzb3VyY2UgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgc291cmNlLnJlYWRSb3V0aW5nQ29uZmlnKCk7XG4gICAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KSk7XG4gICAgICAgIGxldCBsYXRlc3QgPSByZXN1bHRzLmZpbmQoeCA9PiB4KTtcbiAgICAgICAgaWYgKCFsYXRlc3QpIHJldHVybjtcbiAgICAgICAgYXdhaXQgdGhpcy5hZG9wdE5ld0NvbmZpZyhzdGF0ZSwgbGF0ZXN0KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kaXNwb3NlZCA9IHRydWU7XG4gICAgICAgIHRoaXMudW50cmFja0NvbmZpZygpO1xuICAgICAgICB0aGlzLnVuc3Vic2NyaWJlUm91dGluZ1B1c2g/LigpO1xuICAgICAgICBpZiAodGhpcy5wb2xsVGltZXIpIHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5wb2xsVGltZXIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmluaXRSZXRyeVRpbWVyKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5pbml0UmV0cnlUaW1lcik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yb3V0aW5nUmV3cml0ZXIuZGlzcG9zZSgpO1xuICAgICAgICBsZXQgc3RhdGVQcm9taXNlID0gdGhpcy5zdGF0ZVByb21pc2U7XG4gICAgICAgIGlmIChzdGF0ZVByb21pc2UpIHtcbiAgICAgICAgICAgIHZvaWQgc3RhdGVQcm9taXNlLnRoZW4oc3RhdGUgPT4ge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IHNvdXJjZSBvZiBzdGF0ZS5zb3VyY2VzKSB7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZS5kaXNwb3NlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgKCkgPT4geyB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IHR5cGUgU291cmNlUHJvYmUgPSB7XG4gICAgcHJvYmU6IFNvdXJjZVdyYXBwZXI7XG4gICAgc291cmNlQ29uZmlnOiBTb3VyY2VDb25maWc7XG4gICAgcmVzcG9uZGVkOiBib29sZWFuO1xuICAgIGxhdGVuY3k6IG51bWJlcjtcbiAgICBleGlzdGluZzogUmVtb3RlQ29uZmlnIHwgdW5kZWZpbmVkO1xuICAgIGVycm9yOiBzdHJpbmc7XG59O1xuXG4vKiogT25lIHRocm93YXdheSBTb3VyY2VXcmFwcGVyIHBlciBjb25maWd1cmVkIHNvdXJjZSwgZWFjaCBhc2tlZCBmb3IgaXRzIHN0b3JlZCByb3V0aW5nIGNvbmZpZyAtIHdoaWNoIGFsc28gbWVhc3VyZXMgZmlyc3QtY29udGFjdCBsYXRlbmN5LCBzZWVkZWQgaW50byB0aGUgcmVhbCBzb3VyY2VzIGFmdGVyd2FyZHMuIFRoZSBwcm9iZXMgTVVTVCBiZSBkaXNwb3NlZCAoZGlzcG9zZVByb2Jlcykgb25jZSB0aGUgY2FsbGVyIGlzIGRvbmUgd2l0aCB0aGVtLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHByb2JlU291cmNlcyhjb25maWdzOiBTb3VyY2VDb25maWdbXSwgcmVhZE9ubHk6IGJvb2xlYW4pOiBQcm9taXNlPFNvdXJjZVByb2JlW10+IHtcbiAgICByZXR1cm4gYXdhaXQgUHJvbWlzZS5hbGwoY29uZmlncy5tYXAoYXN5bmMgc291cmNlQ29uZmlnID0+IHtcbiAgICAgICAgbGV0IHByb2JlID0gYXdhaXQgU291cmNlV3JhcHBlci5jcmVhdGUoc291cmNlQ29uZmlnLCB7IGJhY2tncm91bmQ6IGZhbHNlLCByZWFkT25seSB9KTtcbiAgICAgICAgbGV0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCBleGlzdGluZyA9IGF3YWl0IHByb2JlLnJlYWRSb3V0aW5nQ29uZmlnKCk7XG4gICAgICAgICAgICByZXR1cm4geyBwcm9iZSwgc291cmNlQ29uZmlnLCByZXNwb25kZWQ6IHRydWUsIGxhdGVuY3k6IERhdGUubm93KCkgLSBzdGFydCwgZXhpc3RpbmcsIGVycm9yOiBcIlwiIH07XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiB7IHByb2JlLCBzb3VyY2VDb25maWcsIHJlc3BvbmRlZDogZmFsc2UsIGxhdGVuY3k6IDAsIGV4aXN0aW5nOiB1bmRlZmluZWQsIGVycm9yOiBgJHtzb3VyY2VDb25maWcudXJsfTogJHsoZSBhcyBFcnJvcikuc3RhY2sgPz8gZX1gIH07XG4gICAgICAgIH1cbiAgICB9KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkaXNwb3NlUHJvYmVzKHByb2JlczogU291cmNlUHJvYmVbXSk6IHZvaWQge1xuICAgIGZvciAobGV0IHByb2JlIG9mIHByb2Jlcykge1xuICAgICAgICBwcm9iZS5wcm9iZS5kaXNwb3NlKCk7XG4gICAgfVxufVxuXG4vKipcbiAqIFdoaWNoIHJvdXRpbmcgY29uZmlnIHRoZSBjaGFpbiBzaG91bGQgUlVOOiB0aGUgbmV3ZXN0IG9mIG91cnMgYW5kIGV2ZXJ5IHN0b3JlZCBvbmUuIG5lZWRzV3JpdGVcbiAqIHdoZW4gb3VycyBpcyBzdHJpY3RseSB0aGUgbmV3ZXN0LCBtZWFuaW5nIHRoZSBzdG9yZXMgaGF2ZSB0byBiZSB0b2xkIGFib3V0IGl0LiBBIHN0b3JlZCBjb25maWdcbiAqIHdpdGggb3VyIGV4YWN0IHZlcnNpb24gYnV0IERJRkZFUkVOVCBjb250ZW50IHdpbnMgd2l0aG91dCBhIHdyaXRlLCBsb3VkbHk6IGNvbmZpZyB1cGRhdGVzIG11c3RcbiAqIGJ1bXAgdGhlIHZlcnNpb24sIG9yIHRoZXkgYXJlIGlnbm9yZWQgLSBzaWxlbnRseSB0YWtpbmcgdGhlIGNoYW5nZWQgb25lIHdvdWxkIG1ha2UgXCJ3aGF0IGlzIHRoZVxuICogYnVja2V0IHJ1bm5pbmdcIiBkZXBlbmQgb24gd2hpY2ggcHJvY2VzcyBzdGFydGVkIGxhc3QuXG4gKlxuICogVGhyb3dzIHdoZW4gbm8gc291cmNlIGFuc3dlcmVkIGF0IGFsbDogd2l0aCBub3RoaW5nIHN0b3JlZCBhbmQgbm9ib2R5IHRvIHdyaXRlIHRvLCB0aGVyZSBpcyBub1xuICogY29uZmlnIHRvIHJ1bi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNob29zZVN0YXJ0dXBDb25maWcoY29uZmlnOiB7IGNvbmZpZ3VyZWQ6IFJlbW90ZUNvbmZpZzsgcHJvYmVzOiBTb3VyY2VQcm9iZVtdOyBkZWJ1Z05hbWU6IHN0cmluZyB9KTogeyBhY3RpdmU6IFJlbW90ZUNvbmZpZzsgbmVlZHNXcml0ZTogYm9vbGVhbjsgZXhpc3Rpbmc6IFJlbW90ZUNvbmZpZyB8IHVuZGVmaW5lZCB9IHtcbiAgICBsZXQgeyBjb25maWd1cmVkLCBwcm9iZXMsIGRlYnVnTmFtZSB9ID0gY29uZmlnO1xuICAgIGxldCBmb3VuZCA9IHByb2Jlcy5maW5kKHggPT4geC5yZXNwb25kZWQpO1xuICAgIGlmICghZm91bmQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgaW5pdGlhbGl6ZSBzdG9yYWdlIGZvciAke2RlYnVnTmFtZX06IG5vIHNvdXJjZSBhbnN3ZXJlZC4gJHtwcm9iZXMubWFwKHggPT4geC5lcnJvcikuam9pbihcIiB8IFwiKX1gKTtcbiAgICB9XG4gICAgbGV0IGV4aXN0aW5nID0gZm91bmQuZXhpc3Rpbmc7XG4gICAgbGV0IGFjdGl2ZSA9IGNvbmZpZ3VyZWQ7XG4gICAgbGV0IG5lZWRzV3JpdGUgPSB0cnVlO1xuICAgIGlmIChleGlzdGluZyAmJiBnZXRDb25maWdWZXJzaW9uKGV4aXN0aW5nKSA+PSBnZXRDb25maWdWZXJzaW9uKGNvbmZpZ3VyZWQpKSB7XG4gICAgICAgIGlmIChnZXRDb25maWdWZXJzaW9uKGV4aXN0aW5nKSA9PT0gZ2V0Q29uZmlnVmVyc2lvbihjb25maWd1cmVkKSAmJiBKU09OLnN0cmluZ2lmeShleGlzdGluZykgIT09IEpTT04uc3RyaW5naWZ5KGNvbmZpZ3VyZWQpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBBcmNoaXZlcyBjb25maWd1cmF0aW9uIHVwZGF0ZWQgd2l0aG91dCB1cGRhdGluZyB0aGUgdmVyc2lvbiwgZm9yICR7Zm91bmQuc291cmNlQ29uZmlnLnVybH0uIFVwZGF0ZXMgd2lsbCBiZSBpZ25vcmVkIHVudGlsIHlvdSBpbmNyZWFzZSB0aGUgdmVyc2lvbi4gVXNpbmc6ICR7SlNPTi5zdHJpbmdpZnkoZXhpc3RpbmcpfSwgaWdub3Jpbmc6ICR7SlNPTi5zdHJpbmdpZnkoY29uZmlndXJlZCl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgYWN0aXZlID0gZXhpc3Rpbmc7XG4gICAgICAgIG5lZWRzV3JpdGUgPSBmYWxzZTtcbiAgICB9XG4gICAgaWYgKG5lZWRzV3JpdGUpIHtcbiAgICAgICAgbGV0IGJlc3Q6IFJlbW90ZUNvbmZpZyB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGNvbmZsaWN0VXJsOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICAgIGZvciAobGV0IHByb2JlIG9mIHByb2Jlcykge1xuICAgICAgICAgICAgbGV0IHN0b3JlZCA9IHByb2JlLmV4aXN0aW5nO1xuICAgICAgICAgICAgaWYgKCFzdG9yZWQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKCFiZXN0IHx8IGdldENvbmZpZ1ZlcnNpb24oc3RvcmVkKSA+IGdldENvbmZpZ1ZlcnNpb24oYmVzdCkpIHtcbiAgICAgICAgICAgICAgICBiZXN0ID0gc3RvcmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGdldENvbmZpZ1ZlcnNpb24oc3RvcmVkKSA9PT0gZ2V0Q29uZmlnVmVyc2lvbihjb25maWd1cmVkKSAmJiBKU09OLnN0cmluZ2lmeShzdG9yZWQpICE9PSBKU09OLnN0cmluZ2lmeShjb25maWd1cmVkKSkge1xuICAgICAgICAgICAgICAgIGNvbmZsaWN0VXJsID0gcHJvYmUuc291cmNlQ29uZmlnLnVybDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoYmVzdCAmJiBnZXRDb25maWdWZXJzaW9uKGJlc3QpID49IGdldENvbmZpZ1ZlcnNpb24oY29uZmlndXJlZCkpIHtcbiAgICAgICAgICAgIGlmIChjb25mbGljdFVybCAmJiBnZXRDb25maWdWZXJzaW9uKGJlc3QpID09PSBnZXRDb25maWdWZXJzaW9uKGNvbmZpZ3VyZWQpKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgQXJjaGl2ZXMgY29uZmlndXJhdGlvbiB1cGRhdGVkIHdpdGhvdXQgdXBkYXRpbmcgdGhlIHZlcnNpb24sIGZvciAke2NvbmZsaWN0VXJsfS4gVXBkYXRlcyB3aWxsIGJlIGlnbm9yZWQgdW50aWwgeW91IGluY3JlYXNlIHRoZSB2ZXJzaW9uLiBVc2luZzogJHtKU09OLnN0cmluZ2lmeShiZXN0KX0sIGlnbm9yaW5nOiAke0pTT04uc3RyaW5naWZ5KGNvbmZpZ3VyZWQpfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYWN0aXZlID0gYmVzdDtcbiAgICAgICAgICAgIG5lZWRzV3JpdGUgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geyBhY3RpdmUsIG5lZWRzV3JpdGUsIGV4aXN0aW5nIH07XG59XG5cbi8qKlxuICogV3JpdGVzIHRoZSBnaXZlbiByb3V0aW5nIGNvbmZpZyB0byBldmVyeSBjb25maWd1cmVkIHN0b3JlLCBvbmUgd3JpdGUgcGVyIHVybCtuYW1lOiB0aGUgd3JpdGVcbiAqIGxhbmRzIGluIHRoZSBzdG9yZSB0aGUgZW50cnkgTkFNRVMsIHNvIHR3byBlbnRyaWVzIHNoYXJpbmcgYSBVUkwgYnV0IG5hbWluZyBkaWZmZXJlbnQgc3RvcmVzIGFyZVxuICogdHdvIHNlcGFyYXRlIGRlbGl2ZXJpZXMgLSBkZWR1cGluZyBieSBVUkwgYWxvbmUgbGVhdmVzIHRoZSBzZWNvbmQgc3RvcmUgdW5jb25maWd1cmVkIGZvcmV2ZXIuIEFsbFxuICogaW4gcGFyYWxsZWwsIGV2ZXJ5IGZhaWx1cmUgdG9sZXJhdGVkIChuby13cml0ZS1hY2Nlc3MgaW5jbHVkZWQgLSB0aGUgYXR0ZW1wdCBjbGFzc2lmaWVzIGl0LFxuICogbm90aGluZyBwcmUtY2hlY2tzIGl0KTogYSBkb3duIG5vZGUgbXVzdCBub3Qgc3RvcCB0aGUgb3RoZXJzIGZyb20gZ2V0dGluZyB0aGUgY29uZmlnIC0gdGhleSB3b3VsZFxuICogdGhlbiByZWplY3Qgd3JpdGVzIGFzIHVuY29uZmlndXJlZCBwcmVjaXNlbHkgQkVDQVVTRSBpdCBuZXZlciBhcnJpdmVkIC0gYW5kIGl0IG11c3QgbmV2ZXIgc3RvcFxuICogdGhlIGNoYWluIGZyb20gc3RhcnRpbmcuIEEgc3RvcmUgdGhhdCBtaXNzZWQgaXQgcHVsbHMgaXQgb2ZmIGl0cyBwZWVycywgYW5kIHRoZSByZXdyaXRlIGxvb3BcbiAqIHRyaWVzIGFnYWluIChzZWUgUm91dGluZ1Jld3JpdGVMb29wKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdyaXRlUm91dGluZ1RvQWxsU3RvcmVzKGNvbmZpZzogeyBjb25maWd1cmVkOiBSZW1vdGVDb25maWc7IHNvdXJjZXM6IFNvdXJjZVdyYXBwZXJbXTsgZGVidWdOYW1lOiBzdHJpbmcgfSk6IFByb21pc2U8eyBmYWlsdXJlczogc3RyaW5nW107IHRvdGFsOiBudW1iZXIgfT4ge1xuICAgIGxldCB7IGNvbmZpZ3VyZWQsIHNvdXJjZXMsIGRlYnVnTmFtZSB9ID0gY29uZmlnO1xuICAgIGxldCByb3V0aW5nRGF0YSA9IHNlcmlhbGl6ZVJlbW90ZUNvbmZpZyhjb25maWd1cmVkKTtcbiAgICBsZXQgcm91dGluZ1dyaXRlVGltZSA9IERhdGUubm93KCk7XG4gICAgbGV0IHRhcmdldHM6IFNvdXJjZVdyYXBwZXJbXSA9IFtdO1xuICAgIGxldCBzZWVuID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgZm9yIChsZXQgc291cmNlIG9mIHNvdXJjZXMpIHtcbiAgICAgICAgbGV0IGtleSA9IGAke3NvdXJjZS5jb25maWcudXJsfXwke3NvdXJjZS5jb25maWcubmFtZX1gO1xuICAgICAgICBpZiAoc2Vlbi5oYXMoa2V5KSkgY29udGludWU7XG4gICAgICAgIHNlZW4uYWRkKGtleSk7XG4gICAgICAgIHRhcmdldHMucHVzaChzb3VyY2UpO1xuICAgIH1cbiAgICBjb25zb2xlLmxvZyhgV3JpdGluZyByb3V0aW5nIGNvbmZpZyB2ZXJzaW9uICR7Z2V0Q29uZmlnVmVyc2lvbihjb25maWd1cmVkKX0gZm9yICR7ZGVidWdOYW1lfSB0byBhbGwgJHt0YXJnZXRzLmxlbmd0aH0gc3RvcmVzICh3cml0ZSB0aW1lICR7bmV3IERhdGUocm91dGluZ1dyaXRlVGltZSkudG9JU09TdHJpbmcoKX0pOiAke3RhcmdldHMubWFwKHggPT4gYCR7eC5jb25maWcudXJsfSAoc3RvcmUgJHtKU09OLnN0cmluZ2lmeSh4LmNvbmZpZy5uYW1lKX0pYCkuam9pbihcIiwgXCIpfWApO1xuICAgIGxldCBmYWlsdXJlczogc3RyaW5nW10gPSBbXTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbCh0YXJnZXRzLm1hcChhc3luYyBzb3VyY2UgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgc291cmNlLndyaXRlKGFyY2hpdmVzID0+IGFyY2hpdmVzLnNldChST1VUSU5HX0ZJTEUsIHJvdXRpbmdEYXRhLCB7IGxhc3RNb2RpZmllZDogcm91dGluZ1dyaXRlVGltZSB9KSk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgV3JvdGUgc3RvcmFnZSByb3V0aW5nIGNvbmZpZyB2ZXJzaW9uICR7Z2V0Q29uZmlnVmVyc2lvbihjb25maWd1cmVkKX0gdG8gJHtzb3VyY2UuY29uZmlnLnVybH0gKHN0b3JlICR7SlNPTi5zdHJpbmdpZnkoc291cmNlLmNvbmZpZy5uYW1lKX0pYCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGZhaWx1cmVzLnB1c2goYCR7c291cmNlLmNvbmZpZy51cmx9IChzdG9yZSAke0pTT04uc3RyaW5naWZ5KHNvdXJjZS5jb25maWcubmFtZSl9KTogJHsoZSBhcyBFcnJvcikuc3RhY2sgPz8gZX1gKTtcbiAgICAgICAgfVxuICAgIH0pKTtcbiAgICByZXR1cm4geyBmYWlsdXJlcywgdG90YWw6IHRhcmdldHMubGVuZ3RoIH07XG59XG5cbi8qKlxuICogVGhlIHBlcmlvZGljIHJlLXdyaXRlIG9mIHRoZSBjaGFpbidzIGluLWNvZGUgY29uZmlnOiBmYWlsdXJlcyByZXRyaWVkIG9uIHRoZSBzaG9ydCBpbnRlcnZhbCAtIGFcbiAqIHN0b3JlIHdpdGhvdXQgdGhlIGNvbmZpZyByZWplY3RzIGV2ZXJ5IHdyaXRlIGFpbWVkIGF0IGl0LCBzbyB0aGlzIG5vdCBsYW5kaW5nIGlzIGEgYmlnIGRlYWwsXG4gKiBsb2dnZWQgb24gZXZlcnkgYXR0ZW1wdCAtIGFuZCBldmVuIHN1Y2Nlc3MgcmVwZWF0ZWQgaG91cmx5LCBpbiBjYXNlIGEgc3RvcmUgbG9zdCBpdC4gVGhlIGZhaWx1cmVcbiAqIHRoaXMgZXhpc3RzIGZvcjogYSBzZXJ2ZXIgd2hvc2UgdHJ1c3Qgd2FzIG9ubHkgZ3JhbnRlZCBBRlRFUiBzdGFydHVwLCBzbyB0aGUgc3RhcnR1cCB3cml0ZSB3YXNcbiAqIHJlamVjdGVkIGFuZCBub3RoaW5nIGVsc2Ugd291bGQgZXZlciByZXRyeSBpdC5cbiAqL1xuZXhwb3J0IGNsYXNzIFJvdXRpbmdSZXdyaXRlTG9vcCB7XG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBjb25maWc6IHtcbiAgICAgICAgY29uZmlndXJlZDogUmVtb3RlQ29uZmlnO1xuICAgICAgICBkZWJ1Z05hbWU6ICgpID0+IHN0cmluZztcbiAgICAgICAgLyoqIFRoZSBjaGFpbidzIG5ld2VzdCBhZG9wdGVkIHN0YXRlOiB3aGF0IGRlY2lkZXMgd2hldGhlciBvdXJzIGlzIHN0aWxsIHRoZSBjb25maWcgdG8gd3JpdGUsIGFuZCB0aGUgc291cmNlcyBpdCBpcyB3cml0dGVuIHRocm91Z2guIFVuZGVmaW5lZCB1bnRpbCB0aGUgZmlyc3QgaW5pdCBmaW5pc2hlcy4gKi9cbiAgICAgICAgbGF0ZXN0OiAoKSA9PiB7IGNvbmZpZzogUmVtb3RlQ29uZmlnOyBzb3VyY2VzOiBTb3VyY2VXcmFwcGVyW10gfSB8IHVuZGVmaW5lZDtcbiAgICB9KSB7IH1cblxuICAgIHByaXZhdGUgdGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgdW5kZWZpbmVkO1xuICAgIHByaXZhdGUgZGlzcG9zZWQgPSBmYWxzZTtcblxuICAgIC8qKiAoUmUpYXJtcyB0aGUgbG9vcCAtIGNhbGxlZCBhdCB0aGUgZW5kIG9mIGV2ZXJ5IGluaXQsIHdpdGggd2hldGhlciB0aGF0IGluaXQncyB3cml0ZSBmYWlsZWQgKHdoaWNoIHBpY2tzIHRoZSBzaG9ydCByZXRyeSBpbnRlcnZhbCkuICovXG4gICAgcHVibGljIHN0YXJ0KGZhaWxlZEF0U3RhcnR1cDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB0aGlzLnNjaGVkdWxlKGZhaWxlZEF0U3RhcnR1cCAmJiBDT05GSUdfV1JJVEVfUkVUUllfSU5URVJWQUwgfHwgQ09ORklHX1dSSVRFX1JFRlJFU0hfSU5URVJWQUwpO1xuICAgIH1cblxuICAgIHB1YmxpYyBkaXNwb3NlKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICAgICAgaWYgKHRoaXMudGltZXIpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc2NoZWR1bGUoZGVsYXk6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5kaXNwb3NlZCkgcmV0dXJuO1xuICAgICAgICBpZiAodGhpcy50aW1lcikge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudGltZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB2b2lkIHRoaXMucmV3cml0ZSgpLmNhdGNoKChlOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFJld3JpdGluZyB0aGUgc3RvcmFnZSByb3V0aW5nIGNvbmZpZyBmb3IgJHt0aGlzLmNvbmZpZy5kZWJ1Z05hbWUoKX0gZmFpbGVkOiAke2Uuc3RhY2sgPz8gZX1gKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNjaGVkdWxlKENPTkZJR19XUklURV9SRVRSWV9JTlRFUlZBTCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZGVsYXkpO1xuICAgICAgICAodGhpcy50aW1lciBhcyB7IHVucmVmPzogKCkgPT4gdm9pZCB9KS51bnJlZj8uKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZXdyaXRlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAodGhpcy5kaXNwb3NlZCkgcmV0dXJuO1xuICAgICAgICBsZXQgY29uZmlndXJlZCA9IHRoaXMuY29uZmlnLmNvbmZpZ3VyZWQ7XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuY29uZmlnLmxhdGVzdCgpO1xuICAgICAgICBpZiAoIXN0YXRlKSB7XG4gICAgICAgICAgICB0aGlzLnNjaGVkdWxlKENPTkZJR19XUklURV9SRVRSWV9JTlRFUlZBTCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGhlIGJ1Y2tldCBhZG9wdGVkIGEgTkVXRVIgY29uZmlnIHRoYW4gb3VyIGluLWNvZGUgb25lLCBzbyBvdXJzIGlzIHN0YWxlIGFuZCBldmVyeSBzdG9yZSB3b3VsZCAocmlnaHRseSkgcmVmdXNlIGl0XG4gICAgICAgIGlmIChnZXRDb25maWdWZXJzaW9uKHN0YXRlLmNvbmZpZykgPiBnZXRDb25maWdWZXJzaW9uKGNvbmZpZ3VyZWQpKSB7XG4gICAgICAgICAgICB0aGlzLnNjaGVkdWxlKENPTkZJR19XUklURV9SRUZSRVNIX0lOVEVSVkFMKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBTYW1lIHZlcnNpb24gYnV0IGRpZmZlcmVudCBjb250ZW50OiBzdGFydHVwIGFscmVhZHkgZGVjaWRlZCB0aGUgc3RvcmVkIG9uZSB3aW5zIHVudGlsIHRoZSB2ZXJzaW9uIGlzIGJ1bXBlZCAoc2VlIGNob29zZVN0YXJ0dXBDb25maWcpLCBhbmQgcmUtd3JpdGluZyBvdXJzIHdvdWxkIGZsaXAgdGhlIGJ1Y2tldCBiYWNrIGFuZCBmb3J0aCBiZXR3ZWVuIHRoZSB0d29cbiAgICAgICAgaWYgKGdldENvbmZpZ1ZlcnNpb24oc3RhdGUuY29uZmlnKSA9PT0gZ2V0Q29uZmlnVmVyc2lvbihjb25maWd1cmVkKSAmJiBKU09OLnN0cmluZ2lmeShzdGF0ZS5jb25maWcpICE9PSBKU09OLnN0cmluZ2lmeShjb25maWd1cmVkKSkge1xuICAgICAgICAgICAgdGhpcy5zY2hlZHVsZShDT05GSUdfV1JJVEVfUkVGUkVTSF9JTlRFUlZBTCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHsgZmFpbHVyZXMsIHRvdGFsIH0gPSBhd2FpdCB3cml0ZVJvdXRpbmdUb0FsbFN0b3Jlcyh7IGNvbmZpZ3VyZWQsIHNvdXJjZXM6IHN0YXRlLnNvdXJjZXMsIGRlYnVnTmFtZTogdGhpcy5jb25maWcuZGVidWdOYW1lKCkgfSk7XG4gICAgICAgIGlmIChmYWlsdXJlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFRoZSBwZXJpb2RpYyByb3V0aW5nIGNvbmZpZyB3cml0ZSBmb3IgJHt0aGlzLmNvbmZpZy5kZWJ1Z05hbWUoKX0gKHZlcnNpb24gJHtnZXRDb25maWdWZXJzaW9uKGNvbmZpZ3VyZWQpfSkgZmFpbGVkIG9uICR7ZmFpbHVyZXMubGVuZ3RofSBvZiAke3RvdGFsfSBzdG9yZXMgLSByZXRyeWluZyBpbiAke0NPTkZJR19XUklURV9SRVRSWV9JTlRFUlZBTCAvIDEwMDB9czogJHtmYWlsdXJlcy5qb2luKFwiIHwgXCIpfWApO1xuICAgICAgICAgICAgdGhpcy5zY2hlZHVsZShDT05GSUdfV1JJVEVfUkVUUllfSU5URVJWQUwpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2NoZWR1bGUoQ09ORklHX1dSSVRFX1JFRlJFU0hfSU5URVJWQUwpO1xuICAgIH1cbn1cbiJdfQ==
469
+ /* _JS_SOURCE_HASH = "345513ed712441e3375ce3ca46cdcecc33d5dca1ad899285ab99c7e5df90275c"; */
@@ -1,4 +1,4 @@
1
- "use strict"; var console = (function shimConsole() { let baseConsole = globalThis.console; if (typeof window !== "undefined") return baseConsole; let name = __filename.replaceAll("\\", "/").split("/").pop(); let dirName = __dirname.replaceAll("\\", "/").split("/").pop(); let context = { __FILE__: __filename, __DIR__: __dirname, __NAME__: name, __DIRNAME__: dirName }; let newConsole = { ...baseConsole }; for (let shim of ["log", "info", "warn", "error"]) { newConsole[shim] = (...args) => { args.push(context); baseConsole[shim](...args); }; } newConsole.__context = context; return newConsole; })(); "use strict";
1
+ "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
3
3
  //exports.getFlag = exports.getArg = void 0;
4
4
  function getArg(name) {
@@ -18,4 +18,4 @@ function getFlag(name) {
18
18
  }
19
19
  exports.getFlag = getFlag;
20
20
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpQXJncy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNsaUFyZ3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsU0FBZ0IsTUFBTSxDQUFDLElBQVk7SUFDL0IsSUFBSSxLQUFLLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzlDLElBQUksS0FBSyxHQUFHLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUNoQyxJQUFJLEtBQUssR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNwQyxJQUFJLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUNuQyxNQUFNLElBQUksS0FBSyxDQUFDLHVCQUF1QixJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNqQixDQUFDO0FBUkQsd0JBUUM7QUFFRCxpR0FBaUc7QUFDakcsU0FBZ0IsT0FBTyxDQUFDLElBQVk7SUFDaEMsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUM7QUFDOUMsQ0FBQztBQUZELDBCQUVDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGZ1bmN0aW9uIGdldEFyZyhuYW1lOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGxldCBpbmRleCA9IHByb2Nlc3MuYXJndi5pbmRleE9mKGAtLSR7bmFtZX1gKTtcbiAgICBpZiAoaW5kZXggPCAwKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGxldCB2YWx1ZSA9IHByb2Nlc3MuYXJndltpbmRleCArIDFdO1xuICAgIGlmICghdmFsdWUgfHwgdmFsdWUuc3RhcnRzV2l0aChcIi0tXCIpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyB2YWx1ZSBmb3IgLS0ke25hbWV9YCk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqIEEgdmFsdWVsZXNzIGJvb2xlYW4gZmxhZzogdHJ1ZSB3aGVuIC0tbmFtZSBpcyBwcmVzZW50ICh3aXRoIG5vdGhpbmcsIG9yIGEgZm9sbG93aW5nIGZsYWcpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZsYWcobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHByb2Nlc3MuYXJndi5pbmNsdWRlcyhgLS0ke25hbWV9YCk7XG59XG4iXX0=
21
- /* _JS_SOURCE_HASH = "278be05b4cc3ee4341865f15340f300a4c0f6ac3f0e3961e2de17b9f1108db2a"; */
21
+ /* _JS_SOURCE_HASH = "b0659c03406d03521ce38ac5f9ba314dcb2b4184db0b749117b20795220c3d97"; */