sliftutils 1.7.23 → 1.7.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +23 -0
- package/package.json +1 -1
- package/storage/ArchivesDisk.ts +1 -1
- package/storage/IArchives.d.ts +1 -0
- package/storage/IArchives.ts +4 -0
- package/storage/backblaze.ts +1 -1
- package/storage/dist/ArchivesDisk.ts.cache +3 -3
- package/storage/dist/IArchives.ts.cache +2 -2
- package/storage/dist/backblaze.ts.cache +3 -3
- package/storage/remoteStorage/ArchivesRemote.ts +1 -1
- package/storage/remoteStorage/ArchivesUrl.ts +1 -1
- package/storage/remoteStorage/blobStore.d.ts +17 -0
- package/storage/remoteStorage/blobStore.ts +167 -27
- package/storage/remoteStorage/createArchives.ts +23 -7
- package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +3 -3
- package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +3 -3
- package/storage/remoteStorage/dist/blobStore.ts.cache +170 -49
- package/storage/remoteStorage/dist/createArchives.ts.cache +16 -5
- package/storage/remoteStorage/dist/deployTakeover.ts.cache +9 -43
- package/storage/remoteStorage/dist/sourceWrapper.ts.cache +4 -4
- package/storage/remoteStorage/dist/storageServerState.ts.cache +170 -30
- package/storage/remoteStorage/sourceWrapper.d.ts +4 -0
- package/storage/remoteStorage/sourceWrapper.ts +10 -0
- package/storage/remoteStorage/spec.md +7 -1
- package/storage/remoteStorage/storageServerState.d.ts +1 -0
- package/storage/remoteStorage/storageServerState.ts +135 -43
|
@@ -122,6 +122,23 @@ type SourceState = {
|
|
|
122
122
|
// Watermark for getChangesAfter polls
|
|
123
123
|
changesAfterTime: number;
|
|
124
124
|
lastMissCheck: number;
|
|
125
|
+
// Per-slot stop token: a removed source's loops stop without touching the rest of the store
|
|
126
|
+
stopped: { stop: boolean };
|
|
127
|
+
// Source slots are stable forever (index entries reference sources by slot number), so a
|
|
128
|
+
// removed source's slot stays in the arrays, marked dead - never scanned, written, or read
|
|
129
|
+
dead?: boolean;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// One source of a live source-list update; see BlobStore.updateSources
|
|
133
|
+
export type BlobSourceSpec = {
|
|
134
|
+
// Matched against ArchivesSource.identity ("disk" for the base slot); equal identities pair
|
|
135
|
+
// off in order
|
|
136
|
+
identity: string;
|
|
137
|
+
validWindow: [number, number];
|
|
138
|
+
route?: [number, number];
|
|
139
|
+
noFullSync?: boolean;
|
|
140
|
+
// Only called for sources that don't match an existing live slot
|
|
141
|
+
create: () => IArchives;
|
|
125
142
|
};
|
|
126
143
|
|
|
127
144
|
// What a scanned listing entry meant when compared against our index
|
|
@@ -135,6 +152,18 @@ function formatScanTally(tally: ScanTally, total: number): string {
|
|
|
135
152
|
return `${tally.new} new paths (${pct(tally.new)}), ${tally.updated} newer writes (${pct(tally.updated)}), ${tally.tombstone} deletions (${pct(tally.tombstone)}), ${tally.unchanged} unchanged (${pct(tally.unchanged)}), ${tally.filtered} outside window/route (${pct(tally.filtered)})`;
|
|
136
153
|
}
|
|
137
154
|
|
|
155
|
+
function newSourceState(): SourceState {
|
|
156
|
+
return {
|
|
157
|
+
supportsChangesAfter: false,
|
|
158
|
+
initialScan: promiseObj(),
|
|
159
|
+
scanComplete: false,
|
|
160
|
+
scannedCount: 0,
|
|
161
|
+
changesAfterTime: 0,
|
|
162
|
+
lastMissCheck: 0,
|
|
163
|
+
stopped: { stop: false },
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
138
167
|
export class BlobStore implements IBucketStore {
|
|
139
168
|
constructor(
|
|
140
169
|
private folder: string,
|
|
@@ -173,18 +202,18 @@ export class BlobStore implements IBucketStore {
|
|
|
173
202
|
private syncActivities = new Set<SyncActivity>();
|
|
174
203
|
private dirty = new Map<string, IndexEntry | undefined>();
|
|
175
204
|
private overlay = new Map<string, OverlayEntry>();
|
|
176
|
-
private sourceStates = this.sources.map(()
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
lastMissCheck: 0,
|
|
183
|
-
}));
|
|
205
|
+
private sourceStates = this.sources.map(() => newSourceState());
|
|
206
|
+
private syncStarted = false;
|
|
207
|
+
|
|
208
|
+
private isLive(sourceIndex: number): boolean {
|
|
209
|
+
return !!this.sources[sourceIndex] && !this.sourceStates[sourceIndex].dead;
|
|
210
|
+
}
|
|
184
211
|
|
|
185
212
|
public init = lazy(async () => {
|
|
186
213
|
await this.loadIndex();
|
|
214
|
+
this.syncStarted = true;
|
|
187
215
|
for (let i = 0; i < this.sources.length; i++) {
|
|
216
|
+
if (!this.isLive(i)) continue;
|
|
188
217
|
void this.runSourceSync(i);
|
|
189
218
|
}
|
|
190
219
|
runInfinitePoll(FAST_FLUSH_POLL, () => this.flushOverlay(), this.stopped);
|
|
@@ -195,10 +224,14 @@ export class BlobStore implements IBucketStore {
|
|
|
195
224
|
}
|
|
196
225
|
});
|
|
197
226
|
|
|
198
|
-
// Stops all synchronization scans/polls and flushes pending writes.
|
|
199
|
-
//
|
|
227
|
+
// Stops all synchronization scans/polls and flushes pending writes. Only used when the store
|
|
228
|
+
// genuinely cannot continue (rawDisk flip, process shutdown) - routine config changes go
|
|
229
|
+
// through updateSources instead, which the store survives.
|
|
200
230
|
public async dispose(): Promise<void> {
|
|
201
231
|
this.stopped.stop = true;
|
|
232
|
+
for (let state of this.sourceStates) {
|
|
233
|
+
state.stopped.stop = true;
|
|
234
|
+
}
|
|
202
235
|
await this.flushOverlay(true);
|
|
203
236
|
await this.flushIndex();
|
|
204
237
|
}
|
|
@@ -254,6 +287,100 @@ export class BlobStore implements IBucketStore {
|
|
|
254
287
|
this.dirty.set(key, undefined);
|
|
255
288
|
}
|
|
256
289
|
|
|
290
|
+
/** Applies a config change to the RUNNING store: windows/routes update in place, new sources
|
|
291
|
+
* are added (their sync starts immediately), and removed sources' slots go dead (their scans
|
|
292
|
+
* stop, their index entries drop). The store survives every routine config evolution - it is
|
|
293
|
+
* never destroyed for a source-list change, only for structural flips it cannot express
|
|
294
|
+
* (rawDisk). Pending fast writes are re-capped to the new flush deadline (flushing
|
|
295
|
+
* immediately when it has already passed). */
|
|
296
|
+
public updateSources(specs: BlobSourceSpec[]): void {
|
|
297
|
+
if (!specs.length || specs[0].identity !== "disk") {
|
|
298
|
+
throw new Error(`updateSources expects the disk source first (identity "disk"), got ${JSON.stringify(specs.map(x => x.identity))} (store ${this.folder})`);
|
|
299
|
+
}
|
|
300
|
+
let setWindow = (i: number, window: [number, number]) => {
|
|
301
|
+
let old = this.sources[i].validWindow;
|
|
302
|
+
if (old[0] === window[0] && old[1] === window[1]) return;
|
|
303
|
+
console.log(`Valid window changed for ${this.sources[i].source.getDebugName()} (store ${this.folder}): [${old.join(", ")}] -> [${window.join(", ")}]`);
|
|
304
|
+
this.sources[i].validWindow = window;
|
|
305
|
+
};
|
|
306
|
+
setWindow(0, specs[0].validWindow);
|
|
307
|
+
// Live slots pair with specs by identity, in order (the same endpoint can appear several
|
|
308
|
+
// times, e.g. one entry per window)
|
|
309
|
+
let liveByIdentity = new Map<string, number[]>();
|
|
310
|
+
let originalLength = this.sources.length;
|
|
311
|
+
for (let i = 1; i < originalLength; i++) {
|
|
312
|
+
if (!this.isLive(i)) continue;
|
|
313
|
+
let id = this.sources[i].identity;
|
|
314
|
+
if (id === undefined) continue;
|
|
315
|
+
let list = liveByIdentity.get(id);
|
|
316
|
+
if (!list) {
|
|
317
|
+
list = [];
|
|
318
|
+
liveByIdentity.set(id, list);
|
|
319
|
+
}
|
|
320
|
+
list.push(i);
|
|
321
|
+
}
|
|
322
|
+
let matched = new Set<number>();
|
|
323
|
+
for (let spec of specs.slice(1)) {
|
|
324
|
+
let slot = liveByIdentity.get(spec.identity)?.shift();
|
|
325
|
+
if (slot !== undefined) {
|
|
326
|
+
matched.add(slot);
|
|
327
|
+
setWindow(slot, spec.validWindow);
|
|
328
|
+
let existing = this.sources[slot];
|
|
329
|
+
if (JSON.stringify(existing.route) !== JSON.stringify(spec.route)) {
|
|
330
|
+
console.log(`Route changed for ${existing.source.getDebugName()} (store ${this.folder}): ${JSON.stringify(existing.route)} -> ${JSON.stringify(spec.route)}`);
|
|
331
|
+
existing.route = spec.route;
|
|
332
|
+
}
|
|
333
|
+
existing.noFullSync = spec.noFullSync;
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
let source = spec.create();
|
|
337
|
+
this.sources.push({ source, validWindow: spec.validWindow, route: spec.route, noFullSync: spec.noFullSync, identity: spec.identity });
|
|
338
|
+
this.sourceStates.push(newSourceState());
|
|
339
|
+
this.sourceFileCounts.push(0);
|
|
340
|
+
this.sourceByteCounts.push(0);
|
|
341
|
+
console.log(`Added sync source ${source.getDebugName()} (store ${this.folder})`);
|
|
342
|
+
if (this.syncStarted) {
|
|
343
|
+
void this.runSourceSync(this.sources.length - 1);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
for (let i = 1; i < originalLength; i++) {
|
|
347
|
+
if (!this.isLive(i) || matched.has(i)) continue;
|
|
348
|
+
this.removeSource(i);
|
|
349
|
+
}
|
|
350
|
+
let deadline = this.sources[0].validWindow[1] - WINDOW_END_FLUSH_MARGIN;
|
|
351
|
+
let recapped = 0;
|
|
352
|
+
for (let entry of this.overlay.values()) {
|
|
353
|
+
if (entry.flushAt <= deadline) continue;
|
|
354
|
+
entry.flushAt = deadline;
|
|
355
|
+
recapped++;
|
|
356
|
+
}
|
|
357
|
+
if (recapped) {
|
|
358
|
+
console.log(`Re-capped ${recapped} pending fast writes to the new flush deadline ${new Date(deadline).toISOString()} (store ${this.folder})`);
|
|
359
|
+
if (deadline <= Date.now()) {
|
|
360
|
+
void this.flushOverlay().catch((e: Error) => console.error(`Flushing fast writes after a valid window change failed (store ${this.folder}): ${e.stack ?? e}`));
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// The slot stays in the arrays forever (index entries reference sources by slot number); it
|
|
366
|
+
// just goes dead - loops stop, and its index entries drop (other sources' scans re-find any
|
|
367
|
+
// copy that's still reachable through the new config)
|
|
368
|
+
private removeSource(sourceIndex: number): void {
|
|
369
|
+
let state = this.sourceStates[sourceIndex];
|
|
370
|
+
let source = this.sources[sourceIndex].source;
|
|
371
|
+
state.dead = true;
|
|
372
|
+
state.stopped.stop = true;
|
|
373
|
+
state.scanComplete = true;
|
|
374
|
+
state.initialScan.resolve(undefined);
|
|
375
|
+
let dropped = 0;
|
|
376
|
+
for (let [key, entry] of this.mem) {
|
|
377
|
+
if (entry.source !== sourceIndex) continue;
|
|
378
|
+
this.deleteIndexEntry(key);
|
|
379
|
+
dropped++;
|
|
380
|
+
}
|
|
381
|
+
console.log(`Removed sync source ${source.getDebugName()} (store ${this.folder}): its scans are stopped and ${dropped} index entries it held were dropped`);
|
|
382
|
+
}
|
|
383
|
+
|
|
257
384
|
/** Rescans our own disk's metadata into the index - used around valid window handoffs, where
|
|
258
385
|
* another process wrote files to the shared folder that our index hasn't seen. */
|
|
259
386
|
public async rescanBase(): Promise<void> {
|
|
@@ -324,7 +451,7 @@ export class BlobStore implements IBucketStore {
|
|
|
324
451
|
debugName: x.source.getDebugName(),
|
|
325
452
|
fileCount: this.sourceFileCounts[i],
|
|
326
453
|
byteCount: this.sourceByteCounts[i],
|
|
327
|
-
})),
|
|
454
|
+
})).filter((x, i) => this.isLive(i)),
|
|
328
455
|
readerDiskLimit: this.config?.readerDiskLimit,
|
|
329
456
|
syncing: [...this.syncActivities],
|
|
330
457
|
};
|
|
@@ -351,7 +478,7 @@ export class BlobStore implements IBucketStore {
|
|
|
351
478
|
source.byteCount += entry.size;
|
|
352
479
|
}
|
|
353
480
|
}
|
|
354
|
-
return { fileCount, byteCount, sources };
|
|
481
|
+
return { fileCount, byteCount, sources: sources.filter((x, i) => this.isLive(i)) };
|
|
355
482
|
}
|
|
356
483
|
|
|
357
484
|
private async flushIndex(): Promise<void> {
|
|
@@ -374,10 +501,12 @@ export class BlobStore implements IBucketStore {
|
|
|
374
501
|
// ── synchronization ──
|
|
375
502
|
|
|
376
503
|
private async runSourceSync(sourceIndex: number): Promise<void> {
|
|
377
|
-
let { source
|
|
504
|
+
let { source } = this.sources[sourceIndex];
|
|
378
505
|
let state = this.sourceStates[sourceIndex];
|
|
506
|
+
// Read live for every pass, not captured - updateSources can change it while loops run
|
|
507
|
+
let noFullSync = () => this.sources[sourceIndex].noFullSync;
|
|
379
508
|
let listing: Map<string, number> | undefined;
|
|
380
|
-
while (!this.stopped.stop) {
|
|
509
|
+
while (!this.stopped.stop && !state.stopped.stop) {
|
|
381
510
|
try {
|
|
382
511
|
let config = await source.getConfig();
|
|
383
512
|
state.supportsChangesAfter = !!(config.supportsChangesAfter && source.getChangesAfter);
|
|
@@ -390,11 +519,11 @@ export class BlobStore implements IBucketStore {
|
|
|
390
519
|
}
|
|
391
520
|
state.scanComplete = true;
|
|
392
521
|
state.initialScan.resolve(undefined);
|
|
393
|
-
if (this.stopped.stop) return;
|
|
522
|
+
if (this.stopped.stop || state.stopped.stop) return;
|
|
394
523
|
if (listing) {
|
|
395
524
|
await this.reconcileSource(sourceIndex, listing);
|
|
396
525
|
}
|
|
397
|
-
if (!noFullSync) {
|
|
526
|
+
if (!noFullSync()) {
|
|
398
527
|
try {
|
|
399
528
|
await this.copySourceFiles(sourceIndex);
|
|
400
529
|
} catch (e) {
|
|
@@ -404,20 +533,20 @@ export class BlobStore implements IBucketStore {
|
|
|
404
533
|
if (state.supportsChangesAfter) {
|
|
405
534
|
runInfinitePoll(CHANGES_POLL_INTERVAL, async () => {
|
|
406
535
|
await this.pollChanges(sourceIndex);
|
|
407
|
-
if (!noFullSync) await this.copySourceFiles(sourceIndex);
|
|
408
|
-
},
|
|
536
|
+
if (!noFullSync()) await this.copySourceFiles(sourceIndex);
|
|
537
|
+
}, state.stopped);
|
|
409
538
|
// Change polls only show what the source HAS, never what it's missing, so pushes run on
|
|
410
539
|
// the full-rescan cadence (findInfo on an index-backed source is cheap)
|
|
411
540
|
runInfinitePoll(FULL_RESCAN_INTERVAL, async () => {
|
|
412
541
|
let files = await source.findInfo("");
|
|
413
542
|
await this.reconcileSource(sourceIndex, new Map(files.map(x => [x.path, x.createTime])));
|
|
414
|
-
},
|
|
543
|
+
}, state.stopped);
|
|
415
544
|
} else {
|
|
416
545
|
runInfinitePoll(FULL_RESCAN_INTERVAL, async () => {
|
|
417
546
|
let rescan = await this.scanSource(sourceIndex);
|
|
418
547
|
await this.reconcileSource(sourceIndex, rescan);
|
|
419
|
-
if (!noFullSync) await this.copySourceFiles(sourceIndex);
|
|
420
|
-
},
|
|
548
|
+
if (!noFullSync()) await this.copySourceFiles(sourceIndex);
|
|
549
|
+
}, state.stopped);
|
|
421
550
|
}
|
|
422
551
|
}
|
|
423
552
|
|
|
@@ -441,6 +570,8 @@ export class BlobStore implements IBucketStore {
|
|
|
441
570
|
clearInterval(progressTimer);
|
|
442
571
|
this.syncActivities.delete(activity);
|
|
443
572
|
}
|
|
573
|
+
// The source may have been removed while the listing was in flight; its results are dead
|
|
574
|
+
if (state.stopped.stop) return new Map();
|
|
444
575
|
let indexSizeBefore = this.mem.size;
|
|
445
576
|
let seen = new Map<string, number>();
|
|
446
577
|
let tally = newScanTally();
|
|
@@ -488,10 +619,11 @@ export class BlobStore implements IBucketStore {
|
|
|
488
619
|
// what's missing and re-sends it.
|
|
489
620
|
private async reconcileSource(sourceIndex: number, listing: Map<string, number>): Promise<void> {
|
|
490
621
|
let { source, validWindow, route } = this.sources[sourceIndex];
|
|
622
|
+
let state = this.sourceStates[sourceIndex];
|
|
491
623
|
let acceptsWrites = windowAcceptsWrites(validWindow);
|
|
492
624
|
try {
|
|
493
625
|
for (let [key, entry] of this.mem) {
|
|
494
|
-
if (this.stopped.stop) return;
|
|
626
|
+
if (this.stopped.stop || state.stopped.stop) return;
|
|
495
627
|
if (entry.source === sourceIndex) continue;
|
|
496
628
|
// The routing file is NEVER synchronized between storage nodes - it is only ever
|
|
497
629
|
// written directly to each node, and only ever read off our own disk
|
|
@@ -517,6 +649,8 @@ export class BlobStore implements IBucketStore {
|
|
|
517
649
|
}
|
|
518
650
|
|
|
519
651
|
private applyScanned(sourceIndex: number, file: ArchiveFileInfo): ScanOutcome {
|
|
652
|
+
// An in-flight scan can outlive its source's removal; its results are dead
|
|
653
|
+
if (!this.isLive(sourceIndex)) return "filtered";
|
|
520
654
|
if (file.path === ROUTING_FILE) {
|
|
521
655
|
// The routing config is NEVER pulled from other sources - it only ever arrives as an
|
|
522
656
|
// explicit, version-validated write, and is only ever read off our own disk. Route and
|
|
@@ -564,6 +698,7 @@ export class BlobStore implements IBucketStore {
|
|
|
564
698
|
private async copySourceFiles(sourceIndex: number): Promise<void> {
|
|
565
699
|
if (sourceIndex === 0) return;
|
|
566
700
|
let { source } = this.sources[sourceIndex];
|
|
701
|
+
let state = this.sourceStates[sourceIndex];
|
|
567
702
|
let pending: { key: string; entry: IndexEntry }[] = [];
|
|
568
703
|
let totalBytes = 0;
|
|
569
704
|
for (let [key, entry] of this.mem) {
|
|
@@ -608,7 +743,7 @@ export class BlobStore implements IBucketStore {
|
|
|
608
743
|
let nextIndex = 0;
|
|
609
744
|
let failed = false;
|
|
610
745
|
let copyWorker = async () => {
|
|
611
|
-
while (!failed && !this.stopped.stop) {
|
|
746
|
+
while (!failed && !this.stopped.stop && !state.stopped.stop) {
|
|
612
747
|
let index = nextIndex++;
|
|
613
748
|
if (index >= pending.length) return;
|
|
614
749
|
let { key, entry } = pending[index];
|
|
@@ -656,6 +791,7 @@ export class BlobStore implements IBucketStore {
|
|
|
656
791
|
// most every 5 seconds)
|
|
657
792
|
private async checkMissingKey(key: string): Promise<void> {
|
|
658
793
|
for (let i = 0; i < this.sources.length; i++) {
|
|
794
|
+
if (!this.isLive(i)) continue;
|
|
659
795
|
let { source } = this.sources[i];
|
|
660
796
|
let state = this.sourceStates[i];
|
|
661
797
|
if (i === 0 && !state.scanComplete) {
|
|
@@ -674,7 +810,7 @@ export class BlobStore implements IBucketStore {
|
|
|
674
810
|
|
|
675
811
|
private async getIndexEntry(key: string): Promise<IndexEntry | undefined> {
|
|
676
812
|
let entry = this.mem.get(key);
|
|
677
|
-
if (entry && this.
|
|
813
|
+
if (entry && this.isLive(entry.source)) return entry;
|
|
678
814
|
if (entry) {
|
|
679
815
|
// The source list changed and this entry's source no longer exists; treat as missing
|
|
680
816
|
this.deleteIndexEntry(key);
|
|
@@ -732,7 +868,7 @@ export class BlobStore implements IBucketStore {
|
|
|
732
868
|
// The holder is down or lost the file. ANY other source's copy beats no value - even an
|
|
733
869
|
// OLDER one - and it's copied onto our disk so the next read doesn't depend on luck.
|
|
734
870
|
for (let i = 0; i < this.sources.length; i++) {
|
|
735
|
-
if (i === holder) continue;
|
|
871
|
+
if (i === holder || !this.isLive(i)) continue;
|
|
736
872
|
let fallback: { data: Buffer; writeTime: number; size: number } | undefined;
|
|
737
873
|
try {
|
|
738
874
|
fallback = await this.sources[i].source.get2(key);
|
|
@@ -808,6 +944,7 @@ export class BlobStore implements IBucketStore {
|
|
|
808
944
|
private getWritableSources(config?: { ignoreWindow?: boolean }): number[] {
|
|
809
945
|
let writable: number[] = [];
|
|
810
946
|
for (let i = 0; i < this.sources.length; i++) {
|
|
947
|
+
if (!this.isLive(i)) continue;
|
|
811
948
|
if (!config?.ignoreWindow && !windowAcceptsWrites(this.sources[i].validWindow)) continue;
|
|
812
949
|
writable.push(i);
|
|
813
950
|
}
|
|
@@ -915,7 +1052,7 @@ export class BlobStore implements IBucketStore {
|
|
|
915
1052
|
supportsChangesAfter: this.sourceStates[i].supportsChangesAfter,
|
|
916
1053
|
initialScanComplete: this.sourceStates[i].scanComplete,
|
|
917
1054
|
scannedCount: this.sourceStates[i].scannedCount,
|
|
918
|
-
})),
|
|
1055
|
+
})).filter((x, i) => this.isLive(i)),
|
|
919
1056
|
};
|
|
920
1057
|
}
|
|
921
1058
|
|
|
@@ -986,6 +1123,7 @@ export class BlobStore implements IBucketStore {
|
|
|
986
1123
|
if (this.mem.get(key) !== entry) continue;
|
|
987
1124
|
let holder: number | undefined;
|
|
988
1125
|
for (let i = 1; i < this.sources.length; i++) {
|
|
1126
|
+
if (!this.isLive(i)) continue;
|
|
989
1127
|
try {
|
|
990
1128
|
let info = await this.sources[i].source.getInfo(key);
|
|
991
1129
|
if (info && info.writeTime >= entry.writeTime) {
|
|
@@ -1021,7 +1159,9 @@ export class BlobStore implements IBucketStore {
|
|
|
1021
1159
|
if (entry.size !== 0) continue;
|
|
1022
1160
|
if (entry.writeTime > cutoff) continue;
|
|
1023
1161
|
this.deleteIndexEntry(key);
|
|
1024
|
-
for (let
|
|
1162
|
+
for (let i = 0; i < this.sources.length; i++) {
|
|
1163
|
+
if (!this.isLive(i)) continue;
|
|
1164
|
+
let sourceEntry = this.sources[i];
|
|
1025
1165
|
if (!windowAcceptsWrites(sourceEntry.validWindow)) continue;
|
|
1026
1166
|
let source = sourceEntry.source;
|
|
1027
1167
|
if (!(source instanceof ArchivesBackblaze)) continue;
|
|
@@ -92,7 +92,7 @@ export class ArchivesChain implements IArchives {
|
|
|
92
92
|
|
|
93
93
|
public getDebugName() {
|
|
94
94
|
let urls = this.activeConfig.sources.map(x => typeof x === "string" && x || (x as HostedConfig | BackblazeConfig).url);
|
|
95
|
-
return `chain
|
|
95
|
+
return `chain ${urls.join(", ")}`;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
// Lazy init that rethrows its error to every caller, while a background timer resets and
|
|
@@ -354,13 +354,27 @@ export class ArchivesChain implements IArchives {
|
|
|
354
354
|
} else {
|
|
355
355
|
console.log(`Storage routing config changed for ${this.getDebugName()} (version ${getConfigVersion(state.config)} -> ${getConfigVersion(latest)}), rebuilding sources`);
|
|
356
356
|
}
|
|
357
|
-
|
|
357
|
+
// Sources are matched IGNORING the valid window: config updates routinely just move
|
|
358
|
+
// windows (reduce the forever-window, append a new entry after it), and a window-only
|
|
359
|
+
// change must reuse the existing wrapper (connection, pings, latency history) instead of
|
|
360
|
+
// dispose-and-reconnect. The same URL can appear several times differing only by window
|
|
361
|
+
// (deploy window splits), so equal keys pair off in order.
|
|
362
|
+
let strippedKey = (config: HostedConfig | BackblazeConfig) => JSON.stringify({ ...config, validWindow: undefined });
|
|
363
|
+
let oldByConfig = new Map<string, SourceWrapper[]>();
|
|
364
|
+
for (let source of state.sources) {
|
|
365
|
+
let key = strippedKey(source.config);
|
|
366
|
+
let list = oldByConfig.get(key);
|
|
367
|
+
if (!list) {
|
|
368
|
+
list = [];
|
|
369
|
+
oldByConfig.set(key, list);
|
|
370
|
+
}
|
|
371
|
+
list.push(source);
|
|
372
|
+
}
|
|
358
373
|
let sources: SourceWrapper[] = [];
|
|
359
374
|
for (let sourceConfig of latest.sources.map(normalizeSource)) {
|
|
360
|
-
let
|
|
361
|
-
let old = oldByConfig.get(key);
|
|
375
|
+
let old = oldByConfig.get(strippedKey(sourceConfig))?.shift();
|
|
362
376
|
if (old) {
|
|
363
|
-
|
|
377
|
+
old.updateValidWindow(sourceConfig.validWindow);
|
|
364
378
|
sources.push(old);
|
|
365
379
|
} else {
|
|
366
380
|
sources.push(await this.createChainSource(sourceConfig));
|
|
@@ -368,8 +382,10 @@ export class ArchivesChain implements IArchives {
|
|
|
368
382
|
}
|
|
369
383
|
// In-flight requests still hold the old wrappers and finish fine; dispose just stops any
|
|
370
384
|
// background reconnect/ping loops
|
|
371
|
-
for (let
|
|
372
|
-
leftover
|
|
385
|
+
for (let leftovers of oldByConfig.values()) {
|
|
386
|
+
for (let leftover of leftovers) {
|
|
387
|
+
leftover.dispose();
|
|
388
|
+
}
|
|
373
389
|
}
|
|
374
390
|
this.activeConfig = latest;
|
|
375
391
|
this.statePromise = Promise.resolve({ config: latest, sources });
|
|
@@ -53,7 +53,7 @@ class ArchivesRemote {
|
|
|
53
53
|
SocketFunction_1.SocketFunction.ENABLE_CLIENT_MODE = true;
|
|
54
54
|
}
|
|
55
55
|
getDebugName() {
|
|
56
|
-
return `remoteStorage
|
|
56
|
+
return `remoteStorage ${this.parsed.address}:${this.parsed.port} account ${this.account} bucket ${this.bucketName}`;
|
|
57
57
|
}
|
|
58
58
|
isConnected() {
|
|
59
59
|
return SocketFunction_1.SocketFunction.isNodeConnected(this.nodeId);
|
|
@@ -194,5 +194,5 @@ class ArchivesRemote {
|
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
exports.ArchivesRemote = ArchivesRemote;
|
|
197
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXJjaGl2ZXNSZW1vdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJBcmNoaXZlc1JlbW90ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxNQUFNLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztBQUUxQixtRUFBZ0U7QUFDaEUsbURBQXdEO0FBQ3hELDJEQUFxRDtBQUNyRCxrREFBNkU7QUFFN0UsaURBQWdGO0FBQ2hGLDJEQUc2QjtBQUU3QixrR0FBa0c7QUFDbEcsK0ZBQStGO0FBQy9GLGlHQUFpRztBQUNqRyxzREFBc0Q7QUFFdEQsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0FBQ3JDLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFhN0MsU0FBZ0IsZUFBZSxDQUFDLEdBQVc7SUFDdkMsSUFBSSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDckIsSUFBSSxDQUFDLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQzFCLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQy9HLENBQUM7SUFDRCxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQztBQUN6RCxDQUFDO0FBTkQsMENBTUM7QUFFRCx1RkFBdUY7QUFDaEYsS0FBSyxVQUFVLG1CQUFtQixDQUFDLE1BQXlEO0lBQy9GLDRGQUE0RjtJQUM1RiwwREFBMEQ7SUFDMUQsK0JBQWMsQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7SUFDekMsSUFBSSxVQUFVLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FB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OUpELHdDQThKQyIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5hbGxvd2NsaWVudCA9IHRydWU7XG5cbmltcG9ydCB7IFNvY2tldEZ1bmN0aW9uIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9Tb2NrZXRGdW5jdGlvblwiO1xuaW1wb3J0IHsgdGltZUluTWludXRlIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvbWlzY1wiO1xuaW1wb3J0IHsgZGVsYXkgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9iYXRjaGluZ1wiO1xuaW1wb3J0IHsgZ2V0SWRlbnRpdHlDQSwgbG9hZElkZW50aXR5Q0EsIHNpZ24gfSBmcm9tIFwiLi4vLi4vbWlzYy9odHRwcy9jZXJ0c1wiO1xuaW1wb3J0IHsgSUFyY2hpdmVzLCBBcmNoaXZlRmlsZUluZm8sIEFyY2hpdmVzQ29uZmlnLCBBcmNoaXZlc1N5bmNTdGF0dXMgfSBmcm9tIFwiLi4vSUFyY2hpdmVzXCI7XG5pbXBvcnQgeyBwYXJzZUhvc3RlZFVybCwgZ2V0QnVja2V0QmFzZVVybCwgYnVpbGRGaWxlVXJsIH0gZnJvbSBcIi4vcmVtb3RlQ29uZmlnXCI7XG5pbXBvcnQge1xuICAgIFJlbW90ZVN0b3JhZ2VDb250cm9sbGVyLCBTVE9SQUdFX0FVVEhfUFVSUE9TRSxcbiAgICBTVE9SQUdFX05PVF9BVVRIRU5USUNBVEVELCBTVE9SQUdFX0FDQ0VTU19ERU5JRUQsXG59IGZyb20gXCIuL3N0b3JhZ2VDb250cm9sbGVyXCI7XG5cbi8vIEEgYnVja2V0IG9uIG91ciByZW1vdGUgc3RvcmFnZSBzZXJ2ZXIgKHN0b3JhZ2VTZXJ2ZXIudHMpLCB1c2VkIGxpa2UgQXJjaGl2ZXNCYWNrYmxhemUuIFdvcmtzIGluXG4vLyBOb2RlLmpzIGFuZCB0aGUgYnJvd3Nlci4gQXV0aGVudGljYXRlcyB3aXRoIHRoaXMgbWFjaGluZSdzIGNlcnRzLnRzIGlkZW50aXR5OyBpZiB0aGUgYWNjb3VudFxuLy8gaGFzbid0IHRydXN0ZWQgdGhpcyBtYWNoaW5lIHlldCBpdCByZXF1ZXN0cyBhY2Nlc3MsIGFuZCBieSBkZWZhdWx0IHdhaXRzLCBsb2dnaW5nIGluc3RydWN0aW9uc1xuLy8gZXZlcnkgbWludXRlIChjYWxscyBibG9jayB1bnRpbCBhY2Nlc3MgaXMgZ3JhbnRlZCkuXG5cbmNvbnN0IEFDQ0VTU19SRVRSWV9ERUxBWSA9IDEwMDAgKiAzMDtcbmNvbnN0IExBUkdFX0ZJTEVfUEFSVF9TSVpFID0gOCAqIDEwMjQgKiAxMDI0O1xuXG5leHBvcnQgdHlwZSBBcmNoaXZlc1JlbW90ZUNvbmZpZyA9IHtcbiAgICAvLyBUaGUgYnVja2V0J3Mgcm91dGluZyBVUkwsIHdoaWNoIGFkZHJlc3NlcyB0aGUgc2VydmVyLCBhY2NvdW50LCBhbmQgYnVja2V0IGluIG9uZTpcbiAgICAvLyAgaHR0cHM6Ly9zdG9yYWdlLmV4YW1wbGUuY29tOjQ0NDQvZmlsZS88YWNjb3VudD4vPGJ1Y2tldE5hbWU+L3N0b3JhZ2Uvc3RvcmFnZXJvdXRpbmcuanNvblxuICAgIHVybDogc3RyaW5nO1xuICAgIC8vIEFjY2VzcyBpcyBjaGVja2VkIGFnYWluc3QgdGhpcyBhY2NvdW50IChkZWZhdWx0cyB0byB0aGUgYWNjb3VudCBpbiB0aGUgdXJsKVxuICAgIGFjY291bnROYW1lPzogc3RyaW5nO1xuICAgIC8vIGZhbHNlOiBhY2Nlc3MtZGVuaWVkIGNhbGxzIHRocm93IGltbWVkaWF0ZWx5ICh0aGUgZXJyb3IgaW5jbHVkZXMgdGhlIGFjY2VzcyBwYWdlIGxpbmspXG4gICAgLy8gaW5zdGVhZCBvZiByZXF1ZXN0aW5nIGFjY2VzcyBhbmQgYmxvY2tpbmcgdW50aWwgaXQgaXMgZ3JhbnRlZCAodGhlIGRlZmF1bHQpLlxuICAgIHdhaXRGb3JBY2Nlc3M/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlU3RvcmFnZVVybCh1cmw6IHN0cmluZyk6IHsgYWRkcmVzczogc3RyaW5nOyBwb3J0OiBudW1iZXIgfSB7XG4gICAgbGV0IHUgPSBuZXcgVVJMKHVybCk7XG4gICAgaWYgKHUucHJvdG9jb2wgIT09IFwiaHR0cHM6XCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTdG9yYWdlIFVSTCBtdXN0IHVzZSBodHRwcywgZ290ICR7SlNPTi5zdHJpbmdpZnkodS5wcm90b2NvbCl9IGluICR7SlNPTi5zdHJpbmdpZnkodXJsKX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgYWRkcmVzczogdS5ob3N0bmFtZSwgcG9ydDogK3UucG9ydCB8fCA0NDMgfTtcbn1cblxuLy8gQXV0aGVudGljYXRlcyBhIGNvbm5lY3Rpb24gdG8gYSBzdG9yYWdlIHNlcnZlciB3aXRoIHRoaXMgbWFjaGluZSdzIGNlcnRzLnRzIGlkZW50aXR5XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXV0aGVudGljYXRlU3RvcmFnZShjb25maWc6IHsgYWRkcmVzczogc3RyaW5nOyBwb3J0OiBudW1iZXI7IG5vZGVJZDogc3RyaW5nIH0pOiBQcm9taXNlPHsgbWFjaGluZUlkOiBzdHJpbmc7IGlwOiBzdHJpbmcgfT4ge1xuICAgIC8vIGhvc3RTZXJ2ZXIgbm9kZUlkcyBhcmUgbWFjaGluZS1zcGVjaWZpYywgc28gY29ubmVjdGlvbnMgYnkgZG9tYWluIG11c3QgdGFyZ2V0IFwiYW55IHNlcnZlclxuICAgIC8vIGF0IHRoaXMgYWRkcmVzc1wiICh3aGljaCBpcyBob3cgYnJvd3NlcnMgYWx3YXlzIGNvbm5lY3QpXG4gICAgU29ja2V0RnVuY3Rpb24uRU5BQkxFX0NMSUVOVF9NT0RFID0gdHJ1ZTtcbiAgICBsZXQgcm9vdERvbWFpbiA9IGNvbmZpZy5hZGRyZXNzLnNwbGl0KFwiLlwiKS5zbGljZSgtMikuam9pbihcIi5cIik7XG4gICAgYXdhaXQgbG9hZElkZW50aXR5Q0Eocm9vdERvbWFpbik7XG4gICAgbGV0IGNhID0gZ2V0SWRlbnRpdHlDQShyb290RG9tYWluKTtcbiAgICBsZXQgZGF0YSA9IHtcbiAgICAgICAgcHVycG9zZTogU1RPUkFHRV9BVVRIX1BVUlBPU0UsXG4gICAgICAgIHRpbWU6IERhdGUubm93KCksXG4gICAgICAgIHNlcnZlcjogYCR7Y29uZmlnLmFkZHJlc3N9OiR7Y29uZmlnLnBvcnR9YCxcbiAgICB9O1xuICAgIGxldCBzaWduYXR1cmUgPSBzaWduKHsga2V5OiBjYS5rZXkgfSwgZGF0YSk7XG4gICAgcmV0dXJuIGF3YWl0IFJlbW90ZVN0b3JhZ2VDb250cm9sbGVyLm5vZGVzW2NvbmZpZy5ub2RlSWRdLmF1dGhlbnRpY2F0ZSh7IGNlcnRQZW06IGNhLmNlcnQudG9TdHJpbmcoKSwgc2lnbmF0dXJlLCBkYXRhIH0pO1xufVxuXG5leHBvcnQgY2xhc3MgQXJjaGl2ZXNSZW1vdGUgaW1wbGVtZW50cyBJQXJjaGl2ZXMge1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgY29uZmlnOiBBcmNoaXZlc1JlbW90ZUNvbmZpZykge1xuICAgICAgICAvLyBob3N0U2VydmVyIG5vZGVJZHMgYXJlIG1hY2hpbmUtc3BlY2lmaWMsIHNvIGNvbm5lY3Rpb25zIGJ5IGRvbWFpbiBtdXN0IHRhcmdldCBcImFueVxuICAgICAgICAvLyBzZXJ2ZXIgYXQgdGhpcyBhZGRyZXNzXCIgKHdoaWNoIGlzIGhvdyBicm93c2VycyBhbHdheXMgY29ubmVjdClcbiAgICAgICAgU29ja2V0RnVuY3Rpb24uRU5BQkxFX0NMSUVOVF9NT0RFID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHBhcnNlZCA9IHBhcnNlSG9zdGVkVXJsKHRoaXMuY29uZmlnLnVybCk7XG4gICAgcHJpdmF0ZSBhY2NvdW50ID0gdGhpcy5jb25maWcuYWNjb3VudE5hbWUgfHwgdGhpcy5wYXJzZWQuYWNjb3VudDtcbiAgICBwcml2YXRlIGJ1Y2tldE5hbWUgPSB0aGlzLnBhcnNlZC5idWNrZXROYW1lO1xuICAgIHByaXZhdGUgbm9kZUlkID0gU29ja2V0RnVuY3Rpb24uY29ubmVjdCh7IGFkZHJlc3M6IHRoaXMucGFyc2VkLmFkZHJlc3MsIHBvcnQ6IHRoaXMucGFyc2VkLnBvcnQgfSk7XG4gICAgcHJpdmF0ZSBjb250cm9sbGVyID0gUmVtb3RlU3RvcmFnZUNvbnRyb2xsZXIubm9kZXNbdGhpcy5ub2RlSWRdO1xuICAgIHByaXZhdGUgbGFzdERlbmllZExvZyA9IDA7XG5cbiAgICBwdWJsaWMgZ2V0RGVidWdOYW1lKCkge1xuICAgICAgICByZXR1cm4gYHJlbW90ZVN0b3JhZ2UvJHt0aGlzLnBhcnNlZC5hZGRyZXNzfToke3RoaXMucGFyc2VkLnBvcnR9LyR7dGhpcy5hY2NvdW50fS8ke3RoaXMuYnVja2V0TmFtZX1gO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIFNvY2tldEZ1bmN0aW9uLmlzTm9kZUNvbm5lY3RlZCh0aGlzLm5vZGVJZCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHBpbmcoKTogUHJvbWlzZTx7IHRha2VvdmVyPzogc3RyaW5nIH0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY29udHJvbGxlci5waW5nKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBhdXRoZW50aWNhdGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IGF1dGhlbnRpY2F0ZVN0b3JhZ2UoeyBhZGRyZXNzOiB0aGlzLnBhcnNlZC5hZGRyZXNzLCBwb3J0OiB0aGlzLnBhcnNlZC5wb3J0LCBub2RlSWQ6IHRoaXMubm9kZUlkIH0pO1xuICAgIH1cblxuICAgIC8vIFJ1bnMgYSBjYWxsLCBhdXRoZW50aWNhdGluZyAoYW5kIHJlLWF1dGhlbnRpY2F0aW5nIGFmdGVyIHJlY29ubmVjdHMpIGFzIG5lZWRlZC4gVW5saWtlXG4gICAgLy8gY2FsbCgpLCBkb2VzIE5PVCB3YWl0IGZvciBhY2NvdW50IGFjY2Vzcy5cbiAgICBwcml2YXRlIGFzeW5jIGNhbGxBdXRoZWQ8VD4oZm5jOiAoKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgZm5jKCk7XG4gICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgICAgaWYgKCFTdHJpbmcoZS5zdGFjayB8fCBlKS5pbmNsdWRlcyhTVE9SQUdFX05PVF9BVVRIRU5USUNBVEVEKSkgdGhyb3cgZTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuYXV0aGVudGljYXRlKCk7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgZm5jKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZXR1cm5zIHVuZGVmaW5lZCBpZiB0aGlzIG1hY2hpbmUgaGFzIGFjY2VzcyB0byB0aGUgYWNjb3VudC4gT3RoZXJ3aXNlIHB1dHMgaW4gYW4gYWNjZXNzXG4gICAgLy8gcmVxdWVzdCBhbmQgcmV0dXJucyBvdXIgbWFjaGluZUlkICsgaXAgKHNvIHRoZSBjYWxsZXIgY2FuIGRpc3BsYXkgdGhlbSBhbG9uZ3NpZGUgdGhlIGxpbmssXG4gICAgLy8gZm9yIHRoZSBhcHByb3ZlciB0byBtYXRjaCB0aGUgaW5jb21pbmcgcmVxdWVzdCkgYW5kIHRoZSBsaW5rIHRvIHRoZSBncmFudCBwYWdlLlxuICAgIHB1YmxpYyBhc3luYyB3YWl0aW5nRm9yQWNjZXNzKCk6IFByb21pc2U8eyBsaW5rOiBzdHJpbmc7IG1hY2hpbmVJZDogc3RyaW5nOyBpcDogc3RyaW5nIH0gfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgbGV0IHN0YXRlID0gYXdhaXQgdGhpcy5jYWxsQXV0aGVkKCgpID0+IHRoaXMuY29udHJvbGxlci5nZXRBY2Nlc3NTdGF0ZSh0aGlzLmFjY291bnQpKTtcbiAgICAgICAgaWYgKHN0YXRlLmhhc0FjY2VzcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IHJlcXVlc3RlZCA9IGF3YWl0IHRoaXMuY2FsbEF1dGhlZCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIucmVxdWVzdEFjY2Vzcyh0aGlzLmFjY291bnQpKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGxpbms6IGBodHRwczovLyR7dGhpcy5wYXJzZWQuYWRkcmVzc306JHt0aGlzLnBhcnNlZC5wb3J0fS8ke3RoaXMuYWNjb3VudH1gLFxuICAgICAgICAgICAgbWFjaGluZUlkOiByZXF1ZXN0ZWQubWFjaGluZUlkLFxuICAgICAgICAgICAgaXA6IHJlcXVlc3RlZC5pcCxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgaGFzV3JpdGVBY2Nlc3MoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIGxldCBzdGF0ZSA9IGF3YWl0IHRoaXMuY2FsbEF1dGhlZCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZ2V0QWNjZXNzU3RhdGUodGhpcy5hY2NvdW50KSk7XG4gICAgICAgIHJldHVybiAhIXN0YXRlLmhhc0FjY2VzcztcbiAgICB9XG5cbiAgICAvLyBSZWdpc3RlcnMgb3VyIGFjY2VzcyByZXF1ZXN0IHNlcnZlci1zaWRlIChzbyBhbiBhZG1pbiBoYXMgYSByZXF1ZXN0SWQgdG8gZ3JhbnQpIGFuZCBsb2dzIHRoZVxuICAgIC8vIGdyYW50IGluc3RydWN0aW9ucywgYXQgbW9zdCBvbmNlIGEgbWludXRlXG4gICAgcHJpdmF0ZSBhc3luYyByZWdpc3RlckFjY2Vzc1JlcXVlc3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGxldCByZXF1ZXN0ZWQgPSBhd2FpdCB0aGlzLmNhbGxBdXRoZWQoKCkgPT4gdGhpcy5jb250cm9sbGVyLnJlcXVlc3RBY2Nlc3ModGhpcy5hY2NvdW50KSk7XG4gICAgICAgIGlmIChEYXRlLm5vdygpIC0gdGhpcy5sYXN0RGVuaWVkTG9nID4gdGltZUluTWludXRlKSB7XG4gICAgICAgICAgICB0aGlzLmxhc3REZW5pZWRMb2cgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYE5vIGFjY2VzcyB0byBzdG9yYWdlIGFjY291bnQgJHtKU09OLnN0cmluZ2lmeSh0aGlzLmFjY291bnQpfSBvbiAke3RoaXMucGFyc2VkLmFkZHJlc3N9OiR7dGhpcy5wYXJzZWQucG9ydH0gKG91ciBtYWNoaW5lICR7cmVxdWVzdGVkLm1hY2hpbmVJZH0sIGlwICR7cmVxdWVzdGVkLmlwfSkuIFNlZSBodHRwczovLyR7dGhpcy5wYXJzZWQuYWRkcmVzc306JHt0aGlzLnBhcnNlZC5wb3J0fS8ke3RoaXMuYWNjb3VudH0gLSBvciBncmFudCBpdCB3aXRoOiAke3JlcXVlc3RlZC5ncmFudEFjY2Vzc0NvbW1hbmR9YCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSdW5zIGEgY2FsbCwgYXV0aGVudGljYXRpbmcgKGFuZCByZS1hdXRoZW50aWNhdGluZyBhZnRlciByZWNvbm5lY3RzKSBhbmQgd2FpdGluZyBmb3IgYWNjb3VudFxuICAgIC8vIGFjY2VzcyBhcyBuZWVkZWQuIFdpdGggd2FpdEZvckFjY2VzcyBmYWxzZSwgZGVuaWVkIGNhbGxzIHRocm93IGltbWVkaWF0ZWx5IGluc3RlYWQgLSBidXQgdGhlXG4gICAgLy8gYWNjZXNzIHJlcXVlc3QgaXMgc3RpbGwgcmVnaXN0ZXJlZCAoaW4gdGhlIGJhY2tncm91bmQpLCBzbyB0aGUgZGVuaWFsIGlzIGdyYW50YWJsZS5cbiAgICBwcml2YXRlIGFzeW5jIGNhbGw8VD4oZm5jOiAoKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhd2FpdCBmbmMoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgICAgICAgIGxldCBtZXNzYWdlID0gU3RyaW5nKGUuc3RhY2sgfHwgZSk7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoU1RPUkFHRV9OT1RfQVVUSEVOVElDQVRFRCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5hdXRoZW50aWNhdGUoKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKFNUT1JBR0VfQUNDRVNTX0RFTklFRCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLndhaXRGb3JBY2Nlc3MgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2b2lkIHRoaXMucmVnaXN0ZXJBY2Nlc3NSZXF1ZXN0KCkuY2F0Y2goKCkgPT4geyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlckFjY2Vzc1JlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZGVsYXkoQUNDRVNTX1JFVFJZX0RFTEFZKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0KGZpbGVOYW1lOiBzdHJpbmcsIGNvbmZpZz86IHsgcmFuZ2U/OiB7IHN0YXJ0OiBudW1iZXI7IGVuZDogbnVtYmVyIH0gfSk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCB0aGlzLmdldDIoZmlsZU5hbWUsIGNvbmZpZyk7XG4gICAgICAgIHJldHVybiByZXN1bHQgJiYgcmVzdWx0LmRhdGEgfHwgdW5kZWZpbmVkO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0MihmaWxlTmFtZTogc3RyaW5nLCBjb25maWc/OiB7IHJhbmdlPzogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlciB9IH0pOiBQcm9taXNlPHsgZGF0YTogQnVmZmVyOyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IHRoaXMuY2FsbCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZ2V0Mih0aGlzLmFjY291bnQsIHRoaXMuYnVja2V0TmFtZSwgZmlsZU5hbWUsIGNvbmZpZz8ucmFuZ2UpKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCAmJiB7IGRhdGE6IEJ1ZmZlci5mcm9tKHJlc3VsdC5kYXRhKSwgd3JpdGVUaW1lOiByZXN1bHQud3JpdGVUaW1lLCBzaXplOiByZXN1bHQuc2l6ZSB9IHx8IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIHNldChmaWxlTmFtZTogc3RyaW5nLCBkYXRhOiBCdWZmZXIsIGNvbmZpZz86IHsgbGFzdE1vZGlmaWVkPzogbnVtYmVyIH0pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICBhd2FpdCB0aGlzLmNhbGwoKCkgPT4gdGhpcy5jb250cm9sbGVyLnNldCh0aGlzLmFjY291bnQsIHRoaXMuYnVja2V0TmFtZSwgZmlsZU5hbWUsIGRhdGEsIGNvbmZpZz8ubGFzdE1vZGlmaWVkKSk7XG4gICAgICAgIHJldHVybiBmaWxlTmFtZTtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGRlbChmaWxlTmFtZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuY2FsbCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZGVsKHRoaXMuYWNjb3VudCwgdGhpcy5idWNrZXROYW1lLCBmaWxlTmFtZSkpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0SW5mbyhmaWxlTmFtZTogc3RyaW5nKTogUHJvbWlzZTx7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfSB8IHVuZGVmaW5lZD4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jYWxsKCgpID0+IHRoaXMuY29udHJvbGxlci5nZXRJbmZvKHRoaXMuYWNjb3VudCwgdGhpcy5idWNrZXROYW1lLCBmaWxlTmFtZSkpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZmluZEluZm8ocHJlZml4OiBzdHJpbmcsIGNvbmZpZz86IHsgc2hhbGxvdz86IGJvb2xlYW47IHR5cGU6IFwiZmlsZXNcIiB8IFwiZm9sZGVyc1wiIH0pOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNhbGwoKCkgPT4gdGhpcy5jb250cm9sbGVyLmZpbmRJbmZvKHRoaXMuYWNjb3VudCwgdGhpcy5idWNrZXROYW1lLCBwcmVmaXgsIGNvbmZpZykpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZmluZChwcmVmaXg6IHN0cmluZywgY29uZmlnPzogeyBzaGFsbG93PzogYm9vbGVhbjsgdHlwZTogXCJmaWxlc1wiIHwgXCJmb2xkZXJzXCIgfSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAgICAgcmV0dXJuIChhd2FpdCB0aGlzLmZpbmRJbmZvKHByZWZpeCwgY29uZmlnKSkubWFwKHggPT4geC5wYXRoKTtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGdldENoYW5nZXNBZnRlcih0aW1lOiBudW1iZXIpOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNhbGwoKCkgPT4gdGhpcy5jb250cm9sbGVyLmdldENoYW5nZXNBZnRlcih0aGlzLmFjY291bnQsIHRoaXMuYnVja2V0TmFtZSwgdGltZSkpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0Q29uZmlnKCk6IFByb21pc2U8QXJjaGl2ZXNDb25maWc+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2FsbCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZ2V0QXJjaGl2ZXNDb25maWcodGhpcy5hY2NvdW50LCB0aGlzLmJ1Y2tldE5hbWUpKTtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGdldFN5bmNTdGF0dXMoKTogUHJvbWlzZTxBcmNoaXZlc1N5bmNTdGF0dXM+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2FsbCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZ2V0U3luY1N0YXR1cyh0aGlzLmFjY291bnQsIHRoaXMuYnVja2V0TmFtZSkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzZXRMYXJnZUZpbGUoY29uZmlnOiB7IHBhdGg6IHN0cmluZzsgZ2V0TmV4dERhdGEoKTogUHJvbWlzZTxCdWZmZXIgfCB1bmRlZmluZWQ+IH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgLy8gRW5zdXJlIHdlJ3JlIGF1dGhlbnRpY2F0ZWQgd2l0aCBhY2Nlc3MgQkVGT1JFIGNvbnN1bWluZyBhbnkgZGF0YSAodGhlIHN0cmVhbSBjYW5ub3QgYmVcbiAgICAgICAgLy8gcmV3b3VuZCwgc28gd2UgY2FuJ3QgdXNlIHRoZSByZXRyeSBsb29wIGFyb3VuZCB0aGUgYWN0dWFsIHVwbG9hZClcbiAgICAgICAgYXdhaXQgdGhpcy5jYWxsKCgpID0+IHRoaXMuY29udHJvbGxlci5nZXRJbmZvKHRoaXMuYWNjb3VudCwgdGhpcy5idWNrZXROYW1lLCBjb25maWcucGF0aCkpO1xuICAgICAgICBsZXQgdXBsb2FkSWQgPSBhd2FpdCB0aGlzLmNvbnRyb2xsZXIuc3RhcnRMYXJnZUZpbGUodGhpcy5hY2NvdW50LCB0aGlzLmJ1Y2tldE5hbWUsIGNvbmZpZy5wYXRoKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICAgICAgbGV0IGRhdGEgPSBhd2FpdCBjb25maWcuZ2V0TmV4dERhdGEoKTtcbiAgICAgICAgICAgICAgICBpZiAoIWRhdGEpIGJyZWFrO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGRhdGEubGVuZ3RoOyBvZmZzZXQgKz0gTEFSR0VfRklMRV9QQVJUX1NJWkUpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5jb250cm9sbGVyLnVwbG9hZFBhcnQodXBsb2FkSWQsIGRhdGEuc3ViYXJyYXkob2Zmc2V0LCBvZmZzZXQgKyBMQVJHRV9GSUxFX1BBUlRfU0laRSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY29udHJvbGxlci5maW5pc2hMYXJnZUZpbGUodXBsb2FkSWQpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuY29udHJvbGxlci5jYW5jZWxMYXJnZUZpbGUodXBsb2FkSWQpO1xuICAgICAgICAgICAgfSBjYXRjaCB7IH1cbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0VVJMKHBhdGg6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIC8vIE9ubHkgYWN0dWFsbHkgbG9hZHMgZm9yIHB1YmxpYyBidWNrZXRzICh0aGUgc2VydmVyIHJlamVjdHMgcGxhaW4gVVJMIHJlYWRzIG90aGVyd2lzZSlcbiAgICAgICAgcmV0dXJuIGJ1aWxkRmlsZVVybChnZXRCdWNrZXRCYXNlVXJsKHRoaXMuY29uZmlnLnVybCksIHBhdGgpO1xuICAgIH1cbn1cbiJdfQ==
|
|
198
|
-
/* _JS_SOURCE_HASH = "
|
|
197
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXJjaGl2ZXNSZW1vdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJBcmNoaXZlc1JlbW90ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxNQUFNLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztBQUUxQixtRUFBZ0U7QUFDaEUsbURBQXdEO0FBQ3hELDJEQUFxRDtBQUNyRCxrREFBNkU7QUFFN0UsaURBQWdGO0FBQ2hGLDJEQUc2QjtBQUU3QixrR0FBa0c7QUFDbEcsK0ZBQStGO0FBQy9GLGlHQUFpRztBQUNqRyxzREFBc0Q7QUFFdEQsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0FBQ3JDLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFhN0MsU0FBZ0IsZUFBZSxDQUFDLEdBQVc7SUFDdkMsSUFBSSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDckIsSUFBSSxDQUFDLENBQUMsUUFBUSxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQzFCLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQy9HLENBQUM7SUFDRCxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQztBQUN6RCxDQUFDO0FBTkQsMENBTUM7QUFFRCx1RkFBdUY7QUFDaEYsS0FBSyxVQUFVLG1CQUFtQixDQUFDLE1BQXlEO0lBQy9GLDRGQUE0RjtJQUM1RiwwREFBMEQ7SUFDMUQsK0JBQWMsQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7SUFDekMsSUFBSSxVQUFVLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQy9ELE1BQU0sSUFBQSxzQkFBYyxFQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2pDLElBQUksRUFBRSxHQUFHLElBQUEscUJBQWEsRUFBQyxVQUFVLENBQUMsQ0FBQztJQUNuQyxJQUFJLElBQUksR0FBRztRQUNQLE9BQU8sRUFBRSx3Q0FBb0I7UUFDN0IsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7UUFDaEIsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFO0tBQzdDLENBQUM7SUFDRixJQUFJLFNBQVMsR0FBRyxJQUFBLFlBQUksRUFBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDNUMsT0FBTyxNQUFNLDJDQUF1QixDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsWUFBWSxDQUFDLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFDN0gsQ0FBQztBQWRELGtEQWNDO0FBRUQsTUFBYSxjQUFjO0lBQ3ZCLFlBQW9CLE1BQTRCO1FBQTVCLFdBQU0sR0FBTixNQUFNLENBQXNCO1FBTXhDLFdBQU0sR0FBRyxJQUFBLDZCQUFjLEVBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QyxZQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUM7UUFDekQsZUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO1FBQ3BDLFdBQU0sR0FBRywrQkFBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzFGLGVBQVUsR0FBRywyQ0FBdUIsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hELGtCQUFhLEdBQUcsQ0FBQyxDQUFDO1FBVnRCLHFGQUFxRjtRQUNyRixpRUFBaUU7UUFDakUsK0JBQWMsQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7SUFDN0MsQ0FBQztJQVNNLFlBQVk7UUFDZixPQUFPLGlCQUFpQixJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksWUFBWSxJQUFJLENBQUMsT0FBTyxXQUFXLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUN4SCxDQUFDO0lBRU0sV0FBVztRQUNkLE9BQU8sK0JBQWMsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFTSxLQUFLLENBQUMsSUFBSTtRQUNiLE9BQU8sTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3hDLENBQUM7SUFFTyxLQUFLLENBQUMsWUFBWTtRQUN0QixNQUFNLG1CQUFtQixDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDN0csQ0FBQztJQUVELHlGQUF5RjtJQUN6Riw0Q0FBNEM7SUFDcEMsS0FBSyxDQUFDLFVBQVUsQ0FBSSxHQUFxQjtRQUM3QyxJQUFJLENBQUM7WUFDRCxPQUFPLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFDdkIsQ0FBQztRQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7WUFDZCxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLDZDQUF5QixDQUFDO2dCQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3ZFLE1BQU0sSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQzFCLE9BQU8sTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUN2QixDQUFDO0lBQ0wsQ0FBQztJQUVELDJGQUEyRjtJQUMzRiw2RkFBNkY7SUFDN0Ysa0ZBQWtGO0lBQzNFLEtBQUssQ0FBQyxnQkFBZ0I7UUFDekIsSUFBSSxLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ3RGLElBQUksS0FBSyxDQUFDLFNBQVM7WUFBRSxPQUFPLFNBQVMsQ0FBQztRQUN0QyxJQUFJLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDekYsT0FBTztZQUNILElBQUksRUFBRSxXQUFXLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDMUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxTQUFTO1lBQzlCLEVBQUUsRUFBRSxTQUFTLENBQUMsRUFBRTtTQUNuQixDQUFDO0lBQ04sQ0FBQztJQUVNLEtBQUssQ0FBQyxjQUFjO1FBQ3ZCLElBQUksS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUN0RixPQUFPLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO0lBQzdCLENBQUM7SUFFRCwrRkFBK0Y7SUFDL0YsNENBQTRDO0lBQ3BDLEtBQUssQ0FBQyxxQkFBcUI7UUFDL0IsSUFBSSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ3pGLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxhQUFhLEdBQUcsbUJBQVksRUFBRSxDQUFDO1lBQ2pELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ2hDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0NBQWdDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxpQkFBaUIsU0FBUyxDQUFDLFNBQVMsUUFBUSxTQUFTLENBQUMsRUFBRSxrQkFBa0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE9BQU8sd0JBQXdCLFNBQVMsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUM7UUFDblQsQ0FBQztJQUNMLENBQUM7SUFFRCwrRkFBK0Y7SUFDL0YsK0ZBQStGO0lBQy9GLHNGQUFzRjtJQUM5RSxLQUFLLENBQUMsSUFBSSxDQUFJLEdBQXFCO1FBQ3ZDLE9BQU8sSUFBSSxFQUFFLENBQUM7WUFDVixJQUFJLENBQUM7Z0JBQ0QsT0FBTyxNQUFNLEdBQUcsRUFBRSxDQUFDO1lBQ3ZCLENBQUM7WUFBQyxPQUFPLENBQU0sRUFBRSxDQUFDO2dCQUNkLElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUNuQyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsNkNBQXlCLENBQUMsRUFBRSxDQUFDO29CQUM5QyxNQUFNLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztvQkFDMUIsU0FBUztnQkFDYixDQUFDO2dCQUNELElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyx5Q0FBcUIsQ0FBQyxFQUFFLENBQUM7b0JBQzFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEtBQUssS0FBSyxFQUFFLENBQUM7d0JBQ3RDLEtBQUssSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO3dCQUNuRCxNQUFNLENBQUMsQ0FBQztvQkFDWixDQUFDO29CQUNELE1BQU0sSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7b0JBQ25DLE1BQU0sSUFBQSxnQkFBSyxFQUFDLGtCQUFrQixDQUFDLENBQUM7b0JBQ2hDLFNBQVM7Z0JBQ2IsQ0FBQztnQkFDRCxNQUFNLENBQUMsQ0FBQztZQUNaLENBQUM7UUFDTCxDQUFDO0lBQ0wsQ0FBQztJQUVNLEtBQUssQ0FBQyxHQUFHLENBQUMsUUFBZ0IsRUFBRSxNQUFtRDtRQUNsRixJQUFJLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQy9DLE9BQU8sTUFBTSxJQUFJLE1BQU0sQ0FBQyxJQUFJLElBQUksU0FBUyxDQUFDO0lBQzlDLENBQUM7SUFDTSxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQWdCLEVBQUUsTUFBbUQ7UUFDbkYsSUFBSSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDakgsT0FBTyxNQUFNLElBQUksRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxTQUFTLENBQUM7SUFDckgsQ0FBQztJQUNNLEtBQUssQ0FBQyxHQUFHLENBQUMsUUFBZ0IsRUFBRSxJQUFZLEVBQUUsTUFBa0M7UUFDL0UsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO1FBQ2hILE9BQU8sUUFBUSxDQUFDO0lBQ3BCLENBQUM7SUFDTSxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQWdCO1FBQzdCLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUN4RixDQUFDO0lBQ00sS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFnQjtRQUNqQyxPQUFPLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUNuRyxDQUFDO0lBQ00sS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFjLEVBQUUsTUFBeUQ7UUFDM0YsT0FBTyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQzFHLENBQUM7SUFDTSxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQWMsRUFBRSxNQUF5RDtRQUN2RixPQUFPLENBQUMsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBQ00sS0FBSyxDQUFDLGVBQWUsQ0FBQyxJQUFZO1FBQ3JDLE9BQU8sTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3ZHLENBQUM7SUFDTSxLQUFLLENBQUMsU0FBUztRQUNsQixPQUFPLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7SUFDbkcsQ0FBQztJQUNNLEtBQUssQ0FBQyxhQUFhO1FBQ3RCLE9BQU8sTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7SUFDL0YsQ0FBQztJQUVNLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBb0U7UUFDMUYseUZBQXlGO1FBQ3pGLG9FQUFvRTtRQUNwRSxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQzNGLElBQUksUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoRyxJQUFJLENBQUM7WUFDRCxPQUFPLElBQUksRUFBRSxDQUFDO2dCQUNWLElBQUksSUFBSSxHQUFHLE1BQU0sTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUN0QyxJQUFJLENBQUMsSUFBSTtvQkFBRSxNQUFNO2dCQUNqQixLQUFLLElBQUksTUFBTSxHQUFHLENBQUMsRUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLElBQUksb0JBQW9CLEVBQUUsQ0FBQztvQkFDeEUsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLG9CQUFvQixDQUFDLENBQUMsQ0FBQztnQkFDckcsQ0FBQztZQUNMLENBQUM7WUFDRCxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3BELENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1QsSUFBSSxDQUFDO2dCQUNELE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDcEQsQ0FBQztZQUFDLFdBQU0sQ0FBQyxDQUFDLENBQUM7WUFDWCxNQUFNLENBQUMsQ0FBQztRQUNaLENBQUM7SUFDTCxDQUFDO0lBRU0sS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFZO1FBQzVCLHdGQUF3RjtRQUN4RixPQUFPLElBQUEsMkJBQVksRUFBQyxJQUFBLCtCQUFnQixFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDakUsQ0FBQztDQUNKO0FBOUpELHdDQThKQyIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5hbGxvd2NsaWVudCA9IHRydWU7XG5cbmltcG9ydCB7IFNvY2tldEZ1bmN0aW9uIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9Tb2NrZXRGdW5jdGlvblwiO1xuaW1wb3J0IHsgdGltZUluTWludXRlIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvbWlzY1wiO1xuaW1wb3J0IHsgZGVsYXkgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9iYXRjaGluZ1wiO1xuaW1wb3J0IHsgZ2V0SWRlbnRpdHlDQSwgbG9hZElkZW50aXR5Q0EsIHNpZ24gfSBmcm9tIFwiLi4vLi4vbWlzYy9odHRwcy9jZXJ0c1wiO1xuaW1wb3J0IHsgSUFyY2hpdmVzLCBBcmNoaXZlRmlsZUluZm8sIEFyY2hpdmVzQ29uZmlnLCBBcmNoaXZlc1N5bmNTdGF0dXMgfSBmcm9tIFwiLi4vSUFyY2hpdmVzXCI7XG5pbXBvcnQgeyBwYXJzZUhvc3RlZFVybCwgZ2V0QnVja2V0QmFzZVVybCwgYnVpbGRGaWxlVXJsIH0gZnJvbSBcIi4vcmVtb3RlQ29uZmlnXCI7XG5pbXBvcnQge1xuICAgIFJlbW90ZVN0b3JhZ2VDb250cm9sbGVyLCBTVE9SQUdFX0FVVEhfUFVSUE9TRSxcbiAgICBTVE9SQUdFX05PVF9BVVRIRU5USUNBVEVELCBTVE9SQUdFX0FDQ0VTU19ERU5JRUQsXG59IGZyb20gXCIuL3N0b3JhZ2VDb250cm9sbGVyXCI7XG5cbi8vIEEgYnVja2V0IG9uIG91ciByZW1vdGUgc3RvcmFnZSBzZXJ2ZXIgKHN0b3JhZ2VTZXJ2ZXIudHMpLCB1c2VkIGxpa2UgQXJjaGl2ZXNCYWNrYmxhemUuIFdvcmtzIGluXG4vLyBOb2RlLmpzIGFuZCB0aGUgYnJvd3Nlci4gQXV0aGVudGljYXRlcyB3aXRoIHRoaXMgbWFjaGluZSdzIGNlcnRzLnRzIGlkZW50aXR5OyBpZiB0aGUgYWNjb3VudFxuLy8gaGFzbid0IHRydXN0ZWQgdGhpcyBtYWNoaW5lIHlldCBpdCByZXF1ZXN0cyBhY2Nlc3MsIGFuZCBieSBkZWZhdWx0IHdhaXRzLCBsb2dnaW5nIGluc3RydWN0aW9uc1xuLy8gZXZlcnkgbWludXRlIChjYWxscyBibG9jayB1bnRpbCBhY2Nlc3MgaXMgZ3JhbnRlZCkuXG5cbmNvbnN0IEFDQ0VTU19SRVRSWV9ERUxBWSA9IDEwMDAgKiAzMDtcbmNvbnN0IExBUkdFX0ZJTEVfUEFSVF9TSVpFID0gOCAqIDEwMjQgKiAxMDI0O1xuXG5leHBvcnQgdHlwZSBBcmNoaXZlc1JlbW90ZUNvbmZpZyA9IHtcbiAgICAvLyBUaGUgYnVja2V0J3Mgcm91dGluZyBVUkwsIHdoaWNoIGFkZHJlc3NlcyB0aGUgc2VydmVyLCBhY2NvdW50LCBhbmQgYnVja2V0IGluIG9uZTpcbiAgICAvLyAgaHR0cHM6Ly9zdG9yYWdlLmV4YW1wbGUuY29tOjQ0NDQvZmlsZS88YWNjb3VudD4vPGJ1Y2tldE5hbWU+L3N0b3JhZ2Uvc3RvcmFnZXJvdXRpbmcuanNvblxuICAgIHVybDogc3RyaW5nO1xuICAgIC8vIEFjY2VzcyBpcyBjaGVja2VkIGFnYWluc3QgdGhpcyBhY2NvdW50IChkZWZhdWx0cyB0byB0aGUgYWNjb3VudCBpbiB0aGUgdXJsKVxuICAgIGFjY291bnROYW1lPzogc3RyaW5nO1xuICAgIC8vIGZhbHNlOiBhY2Nlc3MtZGVuaWVkIGNhbGxzIHRocm93IGltbWVkaWF0ZWx5ICh0aGUgZXJyb3IgaW5jbHVkZXMgdGhlIGFjY2VzcyBwYWdlIGxpbmspXG4gICAgLy8gaW5zdGVhZCBvZiByZXF1ZXN0aW5nIGFjY2VzcyBhbmQgYmxvY2tpbmcgdW50aWwgaXQgaXMgZ3JhbnRlZCAodGhlIGRlZmF1bHQpLlxuICAgIHdhaXRGb3JBY2Nlc3M/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlU3RvcmFnZVVybCh1cmw6IHN0cmluZyk6IHsgYWRkcmVzczogc3RyaW5nOyBwb3J0OiBudW1iZXIgfSB7XG4gICAgbGV0IHUgPSBuZXcgVVJMKHVybCk7XG4gICAgaWYgKHUucHJvdG9jb2wgIT09IFwiaHR0cHM6XCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTdG9yYWdlIFVSTCBtdXN0IHVzZSBodHRwcywgZ290ICR7SlNPTi5zdHJpbmdpZnkodS5wcm90b2NvbCl9IGluICR7SlNPTi5zdHJpbmdpZnkodXJsKX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgYWRkcmVzczogdS5ob3N0bmFtZSwgcG9ydDogK3UucG9ydCB8fCA0NDMgfTtcbn1cblxuLy8gQXV0aGVudGljYXRlcyBhIGNvbm5lY3Rpb24gdG8gYSBzdG9yYWdlIHNlcnZlciB3aXRoIHRoaXMgbWFjaGluZSdzIGNlcnRzLnRzIGlkZW50aXR5XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXV0aGVudGljYXRlU3RvcmFnZShjb25maWc6IHsgYWRkcmVzczogc3RyaW5nOyBwb3J0OiBudW1iZXI7IG5vZGVJZDogc3RyaW5nIH0pOiBQcm9taXNlPHsgbWFjaGluZUlkOiBzdHJpbmc7IGlwOiBzdHJpbmcgfT4ge1xuICAgIC8vIGhvc3RTZXJ2ZXIgbm9kZUlkcyBhcmUgbWFjaGluZS1zcGVjaWZpYywgc28gY29ubmVjdGlvbnMgYnkgZG9tYWluIG11c3QgdGFyZ2V0IFwiYW55IHNlcnZlclxuICAgIC8vIGF0IHRoaXMgYWRkcmVzc1wiICh3aGljaCBpcyBob3cgYnJvd3NlcnMgYWx3YXlzIGNvbm5lY3QpXG4gICAgU29ja2V0RnVuY3Rpb24uRU5BQkxFX0NMSUVOVF9NT0RFID0gdHJ1ZTtcbiAgICBsZXQgcm9vdERvbWFpbiA9IGNvbmZpZy5hZGRyZXNzLnNwbGl0KFwiLlwiKS5zbGljZSgtMikuam9pbihcIi5cIik7XG4gICAgYXdhaXQgbG9hZElkZW50aXR5Q0Eocm9vdERvbWFpbik7XG4gICAgbGV0IGNhID0gZ2V0SWRlbnRpdHlDQShyb290RG9tYWluKTtcbiAgICBsZXQgZGF0YSA9IHtcbiAgICAgICAgcHVycG9zZTogU1RPUkFHRV9BVVRIX1BVUlBPU0UsXG4gICAgICAgIHRpbWU6IERhdGUubm93KCksXG4gICAgICAgIHNlcnZlcjogYCR7Y29uZmlnLmFkZHJlc3N9OiR7Y29uZmlnLnBvcnR9YCxcbiAgICB9O1xuICAgIGxldCBzaWduYXR1cmUgPSBzaWduKHsga2V5OiBjYS5rZXkgfSwgZGF0YSk7XG4gICAgcmV0dXJuIGF3YWl0IFJlbW90ZVN0b3JhZ2VDb250cm9sbGVyLm5vZGVzW2NvbmZpZy5ub2RlSWRdLmF1dGhlbnRpY2F0ZSh7IGNlcnRQZW06IGNhLmNlcnQudG9TdHJpbmcoKSwgc2lnbmF0dXJlLCBkYXRhIH0pO1xufVxuXG5leHBvcnQgY2xhc3MgQXJjaGl2ZXNSZW1vdGUgaW1wbGVtZW50cyBJQXJjaGl2ZXMge1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgY29uZmlnOiBBcmNoaXZlc1JlbW90ZUNvbmZpZykge1xuICAgICAgICAvLyBob3N0U2VydmVyIG5vZGVJZHMgYXJlIG1hY2hpbmUtc3BlY2lmaWMsIHNvIGNvbm5lY3Rpb25zIGJ5IGRvbWFpbiBtdXN0IHRhcmdldCBcImFueVxuICAgICAgICAvLyBzZXJ2ZXIgYXQgdGhpcyBhZGRyZXNzXCIgKHdoaWNoIGlzIGhvdyBicm93c2VycyBhbHdheXMgY29ubmVjdClcbiAgICAgICAgU29ja2V0RnVuY3Rpb24uRU5BQkxFX0NMSUVOVF9NT0RFID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHBhcnNlZCA9IHBhcnNlSG9zdGVkVXJsKHRoaXMuY29uZmlnLnVybCk7XG4gICAgcHJpdmF0ZSBhY2NvdW50ID0gdGhpcy5jb25maWcuYWNjb3VudE5hbWUgfHwgdGhpcy5wYXJzZWQuYWNjb3VudDtcbiAgICBwcml2YXRlIGJ1Y2tldE5hbWUgPSB0aGlzLnBhcnNlZC5idWNrZXROYW1lO1xuICAgIHByaXZhdGUgbm9kZUlkID0gU29ja2V0RnVuY3Rpb24uY29ubmVjdCh7IGFkZHJlc3M6IHRoaXMucGFyc2VkLmFkZHJlc3MsIHBvcnQ6IHRoaXMucGFyc2VkLnBvcnQgfSk7XG4gICAgcHJpdmF0ZSBjb250cm9sbGVyID0gUmVtb3RlU3RvcmFnZUNvbnRyb2xsZXIubm9kZXNbdGhpcy5ub2RlSWRdO1xuICAgIHByaXZhdGUgbGFzdERlbmllZExvZyA9IDA7XG5cbiAgICBwdWJsaWMgZ2V0RGVidWdOYW1lKCkge1xuICAgICAgICByZXR1cm4gYHJlbW90ZVN0b3JhZ2UgJHt0aGlzLnBhcnNlZC5hZGRyZXNzfToke3RoaXMucGFyc2VkLnBvcnR9IGFjY291bnQgJHt0aGlzLmFjY291bnR9IGJ1Y2tldCAke3RoaXMuYnVja2V0TmFtZX1gO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIFNvY2tldEZ1bmN0aW9uLmlzTm9kZUNvbm5lY3RlZCh0aGlzLm5vZGVJZCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHBpbmcoKTogUHJvbWlzZTx7IHRha2VvdmVyPzogc3RyaW5nIH0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY29udHJvbGxlci5waW5nKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBhdXRoZW50aWNhdGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IGF1dGhlbnRpY2F0ZVN0b3JhZ2UoeyBhZGRyZXNzOiB0aGlzLnBhcnNlZC5hZGRyZXNzLCBwb3J0OiB0aGlzLnBhcnNlZC5wb3J0LCBub2RlSWQ6IHRoaXMubm9kZUlkIH0pO1xuICAgIH1cblxuICAgIC8vIFJ1bnMgYSBjYWxsLCBhdXRoZW50aWNhdGluZyAoYW5kIHJlLWF1dGhlbnRpY2F0aW5nIGFmdGVyIHJlY29ubmVjdHMpIGFzIG5lZWRlZC4gVW5saWtlXG4gICAgLy8gY2FsbCgpLCBkb2VzIE5PVCB3YWl0IGZvciBhY2NvdW50IGFjY2Vzcy5cbiAgICBwcml2YXRlIGFzeW5jIGNhbGxBdXRoZWQ8VD4oZm5jOiAoKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgZm5jKCk7XG4gICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgICAgaWYgKCFTdHJpbmcoZS5zdGFjayB8fCBlKS5pbmNsdWRlcyhTVE9SQUdFX05PVF9BVVRIRU5USUNBVEVEKSkgdGhyb3cgZTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuYXV0aGVudGljYXRlKCk7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgZm5jKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZXR1cm5zIHVuZGVmaW5lZCBpZiB0aGlzIG1hY2hpbmUgaGFzIGFjY2VzcyB0byB0aGUgYWNjb3VudC4gT3RoZXJ3aXNlIHB1dHMgaW4gYW4gYWNjZXNzXG4gICAgLy8gcmVxdWVzdCBhbmQgcmV0dXJucyBvdXIgbWFjaGluZUlkICsgaXAgKHNvIHRoZSBjYWxsZXIgY2FuIGRpc3BsYXkgdGhlbSBhbG9uZ3NpZGUgdGhlIGxpbmssXG4gICAgLy8gZm9yIHRoZSBhcHByb3ZlciB0byBtYXRjaCB0aGUgaW5jb21pbmcgcmVxdWVzdCkgYW5kIHRoZSBsaW5rIHRvIHRoZSBncmFudCBwYWdlLlxuICAgIHB1YmxpYyBhc3luYyB3YWl0aW5nRm9yQWNjZXNzKCk6IFByb21pc2U8eyBsaW5rOiBzdHJpbmc7IG1hY2hpbmVJZDogc3RyaW5nOyBpcDogc3RyaW5nIH0gfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgbGV0IHN0YXRlID0gYXdhaXQgdGhpcy5jYWxsQXV0aGVkKCgpID0+IHRoaXMuY29udHJvbGxlci5nZXRBY2Nlc3NTdGF0ZSh0aGlzLmFjY291bnQpKTtcbiAgICAgICAgaWYgKHN0YXRlLmhhc0FjY2VzcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IHJlcXVlc3RlZCA9IGF3YWl0IHRoaXMuY2FsbEF1dGhlZCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIucmVxdWVzdEFjY2Vzcyh0aGlzLmFjY291bnQpKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGxpbms6IGBodHRwczovLyR7dGhpcy5wYXJzZWQuYWRkcmVzc306JHt0aGlzLnBhcnNlZC5wb3J0fS8ke3RoaXMuYWNjb3VudH1gLFxuICAgICAgICAgICAgbWFjaGluZUlkOiByZXF1ZXN0ZWQubWFjaGluZUlkLFxuICAgICAgICAgICAgaXA6IHJlcXVlc3RlZC5pcCxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgaGFzV3JpdGVBY2Nlc3MoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIGxldCBzdGF0ZSA9IGF3YWl0IHRoaXMuY2FsbEF1dGhlZCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZ2V0QWNjZXNzU3RhdGUodGhpcy5hY2NvdW50KSk7XG4gICAgICAgIHJldHVybiAhIXN0YXRlLmhhc0FjY2VzcztcbiAgICB9XG5cbiAgICAvLyBSZWdpc3RlcnMgb3VyIGFjY2VzcyByZXF1ZXN0IHNlcnZlci1zaWRlIChzbyBhbiBhZG1pbiBoYXMgYSByZXF1ZXN0SWQgdG8gZ3JhbnQpIGFuZCBsb2dzIHRoZVxuICAgIC8vIGdyYW50IGluc3RydWN0aW9ucywgYXQgbW9zdCBvbmNlIGEgbWludXRlXG4gICAgcHJpdmF0ZSBhc3luYyByZWdpc3RlckFjY2Vzc1JlcXVlc3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGxldCByZXF1ZXN0ZWQgPSBhd2FpdCB0aGlzLmNhbGxBdXRoZWQoKCkgPT4gdGhpcy5jb250cm9sbGVyLnJlcXVlc3RBY2Nlc3ModGhpcy5hY2NvdW50KSk7XG4gICAgICAgIGlmIChEYXRlLm5vdygpIC0gdGhpcy5sYXN0RGVuaWVkTG9nID4gdGltZUluTWludXRlKSB7XG4gICAgICAgICAgICB0aGlzLmxhc3REZW5pZWRMb2cgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYE5vIGFjY2VzcyB0byBzdG9yYWdlIGFjY291bnQgJHtKU09OLnN0cmluZ2lmeSh0aGlzLmFjY291bnQpfSBvbiAke3RoaXMucGFyc2VkLmFkZHJlc3N9OiR7dGhpcy5wYXJzZWQucG9ydH0gKG91ciBtYWNoaW5lICR7cmVxdWVzdGVkLm1hY2hpbmVJZH0sIGlwICR7cmVxdWVzdGVkLmlwfSkuIFNlZSBodHRwczovLyR7dGhpcy5wYXJzZWQuYWRkcmVzc306JHt0aGlzLnBhcnNlZC5wb3J0fS8ke3RoaXMuYWNjb3VudH0gLSBvciBncmFudCBpdCB3aXRoOiAke3JlcXVlc3RlZC5ncmFudEFjY2Vzc0NvbW1hbmR9YCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSdW5zIGEgY2FsbCwgYXV0aGVudGljYXRpbmcgKGFuZCByZS1hdXRoZW50aWNhdGluZyBhZnRlciByZWNvbm5lY3RzKSBhbmQgd2FpdGluZyBmb3IgYWNjb3VudFxuICAgIC8vIGFjY2VzcyBhcyBuZWVkZWQuIFdpdGggd2FpdEZvckFjY2VzcyBmYWxzZSwgZGVuaWVkIGNhbGxzIHRocm93IGltbWVkaWF0ZWx5IGluc3RlYWQgLSBidXQgdGhlXG4gICAgLy8gYWNjZXNzIHJlcXVlc3QgaXMgc3RpbGwgcmVnaXN0ZXJlZCAoaW4gdGhlIGJhY2tncm91bmQpLCBzbyB0aGUgZGVuaWFsIGlzIGdyYW50YWJsZS5cbiAgICBwcml2YXRlIGFzeW5jIGNhbGw8VD4oZm5jOiAoKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhd2FpdCBmbmMoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgICAgICAgIGxldCBtZXNzYWdlID0gU3RyaW5nKGUuc3RhY2sgfHwgZSk7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoU1RPUkFHRV9OT1RfQVVUSEVOVElDQVRFRCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5hdXRoZW50aWNhdGUoKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKFNUT1JBR0VfQUNDRVNTX0RFTklFRCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLndhaXRGb3JBY2Nlc3MgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2b2lkIHRoaXMucmVnaXN0ZXJBY2Nlc3NSZXF1ZXN0KCkuY2F0Y2goKCkgPT4geyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlckFjY2Vzc1JlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZGVsYXkoQUNDRVNTX1JFVFJZX0RFTEFZKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0KGZpbGVOYW1lOiBzdHJpbmcsIGNvbmZpZz86IHsgcmFuZ2U/OiB7IHN0YXJ0OiBudW1iZXI7IGVuZDogbnVtYmVyIH0gfSk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCB0aGlzLmdldDIoZmlsZU5hbWUsIGNvbmZpZyk7XG4gICAgICAgIHJldHVybiByZXN1bHQgJiYgcmVzdWx0LmRhdGEgfHwgdW5kZWZpbmVkO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0MihmaWxlTmFtZTogc3RyaW5nLCBjb25maWc/OiB7IHJhbmdlPzogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlciB9IH0pOiBQcm9taXNlPHsgZGF0YTogQnVmZmVyOyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IHRoaXMuY2FsbCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZ2V0Mih0aGlzLmFjY291bnQsIHRoaXMuYnVja2V0TmFtZSwgZmlsZU5hbWUsIGNvbmZpZz8ucmFuZ2UpKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCAmJiB7IGRhdGE6IEJ1ZmZlci5mcm9tKHJlc3VsdC5kYXRhKSwgd3JpdGVUaW1lOiByZXN1bHQud3JpdGVUaW1lLCBzaXplOiByZXN1bHQuc2l6ZSB9IHx8IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIHNldChmaWxlTmFtZTogc3RyaW5nLCBkYXRhOiBCdWZmZXIsIGNvbmZpZz86IHsgbGFzdE1vZGlmaWVkPzogbnVtYmVyIH0pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICBhd2FpdCB0aGlzLmNhbGwoKCkgPT4gdGhpcy5jb250cm9sbGVyLnNldCh0aGlzLmFjY291bnQsIHRoaXMuYnVja2V0TmFtZSwgZmlsZU5hbWUsIGRhdGEsIGNvbmZpZz8ubGFzdE1vZGlmaWVkKSk7XG4gICAgICAgIHJldHVybiBmaWxlTmFtZTtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGRlbChmaWxlTmFtZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuY2FsbCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZGVsKHRoaXMuYWNjb3VudCwgdGhpcy5idWNrZXROYW1lLCBmaWxlTmFtZSkpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0SW5mbyhmaWxlTmFtZTogc3RyaW5nKTogUHJvbWlzZTx7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfSB8IHVuZGVmaW5lZD4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jYWxsKCgpID0+IHRoaXMuY29udHJvbGxlci5nZXRJbmZvKHRoaXMuYWNjb3VudCwgdGhpcy5idWNrZXROYW1lLCBmaWxlTmFtZSkpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZmluZEluZm8ocHJlZml4OiBzdHJpbmcsIGNvbmZpZz86IHsgc2hhbGxvdz86IGJvb2xlYW47IHR5cGU6IFwiZmlsZXNcIiB8IFwiZm9sZGVyc1wiIH0pOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNhbGwoKCkgPT4gdGhpcy5jb250cm9sbGVyLmZpbmRJbmZvKHRoaXMuYWNjb3VudCwgdGhpcy5idWNrZXROYW1lLCBwcmVmaXgsIGNvbmZpZykpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZmluZChwcmVmaXg6IHN0cmluZywgY29uZmlnPzogeyBzaGFsbG93PzogYm9vbGVhbjsgdHlwZTogXCJmaWxlc1wiIHwgXCJmb2xkZXJzXCIgfSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAgICAgcmV0dXJuIChhd2FpdCB0aGlzLmZpbmRJbmZvKHByZWZpeCwgY29uZmlnKSkubWFwKHggPT4geC5wYXRoKTtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGdldENoYW5nZXNBZnRlcih0aW1lOiBudW1iZXIpOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNhbGwoKCkgPT4gdGhpcy5jb250cm9sbGVyLmdldENoYW5nZXNBZnRlcih0aGlzLmFjY291bnQsIHRoaXMuYnVja2V0TmFtZSwgdGltZSkpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0Q29uZmlnKCk6IFByb21pc2U8QXJjaGl2ZXNDb25maWc+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2FsbCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZ2V0QXJjaGl2ZXNDb25maWcodGhpcy5hY2NvdW50LCB0aGlzLmJ1Y2tldE5hbWUpKTtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGdldFN5bmNTdGF0dXMoKTogUHJvbWlzZTxBcmNoaXZlc1N5bmNTdGF0dXM+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2FsbCgoKSA9PiB0aGlzLmNvbnRyb2xsZXIuZ2V0U3luY1N0YXR1cyh0aGlzLmFjY291bnQsIHRoaXMuYnVja2V0TmFtZSkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzZXRMYXJnZUZpbGUoY29uZmlnOiB7IHBhdGg6IHN0cmluZzsgZ2V0TmV4dERhdGEoKTogUHJvbWlzZTxCdWZmZXIgfCB1bmRlZmluZWQ+IH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgLy8gRW5zdXJlIHdlJ3JlIGF1dGhlbnRpY2F0ZWQgd2l0aCBhY2Nlc3MgQkVGT1JFIGNvbnN1bWluZyBhbnkgZGF0YSAodGhlIHN0cmVhbSBjYW5ub3QgYmVcbiAgICAgICAgLy8gcmV3b3VuZCwgc28gd2UgY2FuJ3QgdXNlIHRoZSByZXRyeSBsb29wIGFyb3VuZCB0aGUgYWN0dWFsIHVwbG9hZClcbiAgICAgICAgYXdhaXQgdGhpcy5jYWxsKCgpID0+IHRoaXMuY29udHJvbGxlci5nZXRJbmZvKHRoaXMuYWNjb3VudCwgdGhpcy5idWNrZXROYW1lLCBjb25maWcucGF0aCkpO1xuICAgICAgICBsZXQgdXBsb2FkSWQgPSBhd2FpdCB0aGlzLmNvbnRyb2xsZXIuc3RhcnRMYXJnZUZpbGUodGhpcy5hY2NvdW50LCB0aGlzLmJ1Y2tldE5hbWUsIGNvbmZpZy5wYXRoKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICAgICAgbGV0IGRhdGEgPSBhd2FpdCBjb25maWcuZ2V0TmV4dERhdGEoKTtcbiAgICAgICAgICAgICAgICBpZiAoIWRhdGEpIGJyZWFrO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGRhdGEubGVuZ3RoOyBvZmZzZXQgKz0gTEFSR0VfRklMRV9QQVJUX1NJWkUpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5jb250cm9sbGVyLnVwbG9hZFBhcnQodXBsb2FkSWQsIGRhdGEuc3ViYXJyYXkob2Zmc2V0LCBvZmZzZXQgKyBMQVJHRV9GSUxFX1BBUlRfU0laRSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY29udHJvbGxlci5maW5pc2hMYXJnZUZpbGUodXBsb2FkSWQpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuY29udHJvbGxlci5jYW5jZWxMYXJnZUZpbGUodXBsb2FkSWQpO1xuICAgICAgICAgICAgfSBjYXRjaCB7IH1cbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0VVJMKHBhdGg6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIC8vIE9ubHkgYWN0dWFsbHkgbG9hZHMgZm9yIHB1YmxpYyBidWNrZXRzICh0aGUgc2VydmVyIHJlamVjdHMgcGxhaW4gVVJMIHJlYWRzIG90aGVyd2lzZSlcbiAgICAgICAgcmV0dXJuIGJ1aWxkRmlsZVVybChnZXRCdWNrZXRCYXNlVXJsKHRoaXMuY29uZmlnLnVybCksIHBhdGgpO1xuICAgIH1cbn1cbiJdfQ==
|
|
198
|
+
/* _JS_SOURCE_HASH = "6b5b27f980ca9e58b650a0dfb7e14290fe3aad0d761dcc1e33263117c69ea437"; */
|
|
@@ -13,7 +13,7 @@ class ArchivesUrl {
|
|
|
13
13
|
this.base = base;
|
|
14
14
|
}
|
|
15
15
|
getDebugName() {
|
|
16
|
-
return `url
|
|
16
|
+
return `url ${this.base}`;
|
|
17
17
|
}
|
|
18
18
|
readOnlyError(operation) {
|
|
19
19
|
return new Error(`${operation} is not supported over URL-form access (no API access to this source, only public URL reads). Source: ${this.base}`);
|
|
@@ -86,5 +86,5 @@ class ArchivesUrl {
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
exports.ArchivesUrl = ArchivesUrl;
|
|
89
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXJjaGl2ZXNVcmwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJBcmNoaXZlc1VybC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxNQUFNLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztBQUUxQixxREFBNEU7QUFFNUUsaURBQThDO0FBRTlDLGtGQUFrRjtBQUNsRixpR0FBaUc7QUFDakcsaUdBQWlHO0FBRWpHLE1BQWEsV0FBVztJQUNwQiwyRkFBMkY7SUFDM0YsWUFBb0IsSUFBWTtRQUFaLFNBQUksR0FBSixJQUFJLENBQVE7SUFBSSxDQUFDO0lBRTlCLFlBQVk7UUFDZixPQUFPLE9BQU8sSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFTyxhQUFhLENBQUMsU0FBaUI7UUFDbkMsT0FBTyxJQUFJLEtBQUssQ0FBQyxHQUFHLFNBQVMseUdBQXlHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZKLENBQUM7SUFFTSxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQWdCLEVBQUUsTUFBbUQ7UUFDbEYsSUFBSSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMvQyxPQUFPLE1BQU0sSUFBSSxNQUFNLENBQUMsSUFBSSxJQUFJLFNBQVMsQ0FBQztJQUM5QyxDQUFDO0lBQ00sS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFnQixFQUFFLE1BQW1EO1FBQ25GLElBQUksR0FBRyxHQUFHLElBQUEsMkJBQVksRUFBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzVDLElBQUksT0FBTyxHQUEyQixFQUFFLENBQUM7UUFDekMsSUFBSSxLQUFLLEdBQUcsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLEtBQUssQ0FBQztRQUMxQixJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1IsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLFNBQVMs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QUFFLE1BQXlEO1FBQzNGLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFTSxLQUFLLENBQUMsTUFBTSxDQUFDLElBQVk7UUFDNUIsT0FBTyxJQUFBLDJCQUFZLEVBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBQ00sS0FBSyxDQUFDLFNBQVM7UUFDbEIsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDO0lBRU0sS0FBSyxDQUFDLGNBQWM7UUFDdkIsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztDQUNKO0FBL0VELGtDQStFQyIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5hbGxvd2NsaWVudCA9IHRydWU7XG5cbmltcG9ydCB7IGh0dHBzUmVxdWVzdCwgSHR0cHNSZXNwb25zZUluZm8gfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9odHRwc1wiO1xuaW1wb3J0IHsgSUFyY2hpdmVzLCBBcmNoaXZlRmlsZUluZm8sIEFyY2hpdmVzQ29uZmlnIH0gZnJvbSBcIi4uL0lBcmNoaXZlc1wiO1xuaW1wb3J0IHsgYnVpbGRGaWxlVXJsIH0gZnJvbSBcIi4vcmVtb3RlQ29uZmlnXCI7XG5cbi8vIFJlYWQtb25seSBJQXJjaGl2ZXMgb3ZlciBhIHB1YmxpYyBidWNrZXQncyBwbGFpbi1VUkwgZm9ybSAob3VyIHN0b3JhZ2Ugc2VydmVyJ3Ncbi8vIC9maWxlLzxhY2NvdW50Pi88YnVja2V0TmFtZT4vLi4uIHJvdXRlLCBvciBhIGJhY2tibGF6ZSBmcmllbmRseSBVUkwpLiBVc2VkIHdoZW4gd2UgaGF2ZSBubyBBUElcbi8vIGFjY2VzcyB0byBhIHNvdXJjZS4gT25seSBzaW5nbGUtZmlsZSByZWFkcyB3b3JrOiB0aGVyZSBpcyBubyBsaXN0aW5nLCBhbmQgd3JpdGVzIGFsd2F5cyB0aHJvdy5cblxuZXhwb3J0IGNsYXNzIEFyY2hpdmVzVXJsIGltcGxlbWVudHMgSUFyY2hpdmVzIHtcbiAgICAvLyBiYXNlIGlzIHRoZSBidWNrZXQncyBwdWJsaWMgYmFzZSBVUkwsIGUuZy4gaHR0cHM6Ly9ob3N0OnBvcnQvZmlsZS88YWNjb3VudD4vPGJ1Y2tldE5hbWU+
|
|
90
|
-
/* _JS_SOURCE_HASH = "
|
|
89
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXJjaGl2ZXNVcmwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJBcmNoaXZlc1VybC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxNQUFNLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztBQUUxQixxREFBNEU7QUFFNUUsaURBQThDO0FBRTlDLGtGQUFrRjtBQUNsRixpR0FBaUc7QUFDakcsaUdBQWlHO0FBRWpHLE1BQWEsV0FBVztJQUNwQiwyRkFBMkY7SUFDM0YsWUFBb0IsSUFBWTtRQUFaLFNBQUksR0FBSixJQUFJLENBQVE7SUFBSSxDQUFDO0lBRTlCLFlBQVk7UUFDZixPQUFPLE9BQU8sSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFTyxhQUFhLENBQUMsU0FBaUI7UUFDbkMsT0FBTyxJQUFJLEtBQUssQ0FBQyxHQUFHLFNBQVMseUdBQXlHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZKLENBQUM7SUFFTSxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQWdCLEVBQUUsTUFBbUQ7UUFDbEYsSUFBSSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMvQyxPQUFPLE1BQU0sSUFBSSxNQUFNLENBQUMsSUFBSSxJQUFJLFNBQVMsQ0FBQztJQUM5QyxDQUFDO0lBQ00sS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFnQixFQUFFLE1BQW1EO1FBQ25GLElBQUksR0FBRyxHQUFHLElBQUEsMkJBQVksRUFBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzVDLElBQUksT0FBTyxHQUEyQixFQUFFLENBQUM7UUFDekMsSUFBSSxLQUFLLEdBQUcsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLEtBQUssQ0FBQztRQUMxQixJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1IsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLFNBQVMs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QUFFLE1BQXlEO1FBQzNGLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFTSxLQUFLLENBQUMsTUFBTSxDQUFDLElBQVk7UUFDNUIsT0FBTyxJQUFBLDJCQUFZLEVBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBQ00sS0FBSyxDQUFDLFNBQVM7UUFDbEIsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDO0lBRU0sS0FBSyxDQUFDLGNBQWM7UUFDdkIsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztDQUNKO0FBL0VELGtDQStFQyIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5hbGxvd2NsaWVudCA9IHRydWU7XG5cbmltcG9ydCB7IGh0dHBzUmVxdWVzdCwgSHR0cHNSZXNwb25zZUluZm8gfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9odHRwc1wiO1xuaW1wb3J0IHsgSUFyY2hpdmVzLCBBcmNoaXZlRmlsZUluZm8sIEFyY2hpdmVzQ29uZmlnIH0gZnJvbSBcIi4uL0lBcmNoaXZlc1wiO1xuaW1wb3J0IHsgYnVpbGRGaWxlVXJsIH0gZnJvbSBcIi4vcmVtb3RlQ29uZmlnXCI7XG5cbi8vIFJlYWQtb25seSBJQXJjaGl2ZXMgb3ZlciBhIHB1YmxpYyBidWNrZXQncyBwbGFpbi1VUkwgZm9ybSAob3VyIHN0b3JhZ2Ugc2VydmVyJ3Ncbi8vIC9maWxlLzxhY2NvdW50Pi88YnVja2V0TmFtZT4vLi4uIHJvdXRlLCBvciBhIGJhY2tibGF6ZSBmcmllbmRseSBVUkwpLiBVc2VkIHdoZW4gd2UgaGF2ZSBubyBBUElcbi8vIGFjY2VzcyB0byBhIHNvdXJjZS4gT25seSBzaW5nbGUtZmlsZSByZWFkcyB3b3JrOiB0aGVyZSBpcyBubyBsaXN0aW5nLCBhbmQgd3JpdGVzIGFsd2F5cyB0aHJvdy5cblxuZXhwb3J0IGNsYXNzIEFyY2hpdmVzVXJsIGltcGxlbWVudHMgSUFyY2hpdmVzIHtcbiAgICAvLyBiYXNlIGlzIHRoZSBidWNrZXQncyBwdWJsaWMgYmFzZSBVUkwsIGUuZy4gaHR0cHM6Ly9ob3N0OnBvcnQvZmlsZS88YWNjb3VudD4vPGJ1Y2tldE5hbWU+XG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBiYXNlOiBzdHJpbmcpIHsgfVxuXG4gICAgcHVibGljIGdldERlYnVnTmFtZSgpIHtcbiAgICAgICAgcmV0dXJuIGB1cmwgJHt0aGlzLmJhc2V9YDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlYWRPbmx5RXJyb3Iob3BlcmF0aW9uOiBzdHJpbmcpOiBFcnJvciB7XG4gICAgICAgIHJldHVybiBuZXcgRXJyb3IoYCR7b3BlcmF0aW9ufSBpcyBub3Qgc3VwcG9ydGVkIG92ZXIgVVJMLWZvcm0gYWNjZXNzIChubyBBUEkgYWNjZXNzIHRvIHRoaXMgc291cmNlLCBvbmx5IHB1YmxpYyBVUkwgcmVhZHMpLiBTb3VyY2U6ICR7dGhpcy5iYXNlfWApO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXQoZmlsZU5hbWU6IHN0cmluZywgY29uZmlnPzogeyByYW5nZT86IHsgc3RhcnQ6IG51bWJlcjsgZW5kOiBudW1iZXIgfSB9KTogUHJvbWlzZTxCdWZmZXIgfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZ2V0MihmaWxlTmFtZSwgY29uZmlnKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCAmJiByZXN1bHQuZGF0YSB8fCB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBnZXQyKGZpbGVOYW1lOiBzdHJpbmcsIGNvbmZpZz86IHsgcmFuZ2U/OiB7IHN0YXJ0OiBudW1iZXI7IGVuZDogbnVtYmVyIH0gfSk6IFByb21pc2U8eyBkYXRhOiBCdWZmZXI7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfSB8IHVuZGVmaW5lZD4ge1xuICAgICAgICBsZXQgdXJsID0gYnVpbGRGaWxlVXJsKHRoaXMuYmFzZSwgZmlsZU5hbWUpO1xuICAgICAgICBsZXQgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICAgICAgICBsZXQgcmFuZ2UgPSBjb25maWc/LnJhbmdlO1xuICAgICAgICBpZiAocmFuZ2UpIHtcbiAgICAgICAgICAgIGhlYWRlcnNbXCJSYW5nZVwiXSA9IGBieXRlcz0ke3JhbmdlLnN0YXJ0fS0ke3JhbmdlLmVuZCAtIDF9YDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzcG9uc2U6IEh0dHBzUmVzcG9uc2VJbmZvID0geyBoZWFkZXJzOiB7fSB9O1xuICAgICAgICBsZXQgZGF0YTogQnVmZmVyO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZGF0YSA9IGF3YWl0IGh0dHBzUmVxdWVzdCh1cmwsIHVuZGVmaW5lZCwgXCJHRVRcIiwgZmFsc2UsIHsgaGVhZGVycywgb3V0UmVzcG9uc2U6IHJlc3BvbnNlIH0pO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBodHRwc1JlcXVlc3QgdGhyb3dzIG9uIGFueSBub24tMnh4OyBhIG1pc3NpbmcgZmlsZSBpcyBhIG5vcm1hbCBhYnNlbnQgcmVzdWx0LCBub3QgYW4gZXJyb3IuXG4gICAgICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzQ29kZSA9PT0gNDA0KSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBBIHJlYWwgMjA2IG9ubHkgcmV0dXJucyB0aGUgcmVxdWVzdGVkIHNsaWNlLCBzbyB0aGUgZnVsbCBzaXplIGxpdmVzIGluIENvbnRlbnQtUmFuZ2UncyB0b3RhbC5cbiAgICAgICAgbGV0IHNpemUgPSBkYXRhLmxlbmd0aDtcbiAgICAgICAgbGV0IGNvbnRlbnRSYW5nZSA9IHJlc3BvbnNlLmhlYWRlcnNbXCJjb250ZW50LXJhbmdlXCJdO1xuICAgICAgICBsZXQgdG90YWwgPSBjb250ZW50UmFuZ2UgJiYgTnVtYmVyKGNvbnRlbnRSYW5nZS5zcGxpdChcIi9cIilbMV0pO1xuICAgICAgICBpZiAodG90YWwgJiYgTnVtYmVyLmlzRmluaXRlKHRvdGFsKSkge1xuICAgICAgICAgICAgc2l6ZSA9IHRvdGFsO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNlcnZlcnMgdGhhdCBkb24ndCBzdXBwb3J0IHJhbmdlcyByZXR1cm4gdGhlIGZ1bGwgZmlsZSB3aXRoIGEgMjAwIChvdXJzIHNlcnZlcyByZWFsXG4gICAgICAgIC8vIDIwNnMsIGJ1dCBiYWNrYmxhemUgZnJpZW5kbHkgVVJMcyBhbmQgcHJveGllcyBtYXkgbm90KVxuICAgICAgICBpZiAocmFuZ2UgJiYgcmVzcG9uc2Uuc3RhdHVzQ29kZSA9PT0gMjAwKSB7XG4gICAgICAgICAgICBkYXRhID0gZGF0YS5zdWJhcnJheShNYXRoLm1pbihyYW5nZS5zdGFydCwgZGF0YS5sZW5ndGgpLCBNYXRoLm1pbihyYW5nZS5lbmQsIGRhdGEubGVuZ3RoKSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGxhc3RNb2RpZmllZCA9IHJlc3BvbnNlLmhlYWRlcnNbXCJsYXN0LW1vZGlmaWVkXCJdO1xuICAgICAgICBsZXQgd3JpdGVUaW1lID0gbGFzdE1vZGlmaWVkICYmIG5ldyBEYXRlKGxhc3RNb2RpZmllZCkuZ2V0VGltZSgpIHx8IDA7XG4gICAgICAgIHJldHVybiB7IGRhdGEsIHdyaXRlVGltZSwgc2l6ZSB9O1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0SW5mbyhmaWxlTmFtZTogc3RyaW5nKTogUHJvbWlzZTx7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfSB8IHVuZGVmaW5lZD4ge1xuICAgICAgICBsZXQgcmVzdWx0ID0gYXdhaXQgdGhpcy5nZXQyKGZpbGVOYW1lKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCAmJiB7IHdyaXRlVGltZTogcmVzdWx0LndyaXRlVGltZSwgc2l6ZTogcmVzdWx0LnNpemUgfSB8fCB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHNldChmaWxlTmFtZTogc3RyaW5nLCBkYXRhOiBCdWZmZXIsIGNvbmZpZz86IHsgbGFzdE1vZGlmaWVkPzogbnVtYmVyIH0pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgICB0aHJvdyB0aGlzLnJlYWRPbmx5RXJyb3IoXCJzZXRcIik7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBkZWwoZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aHJvdyB0aGlzLnJlYWRPbmx5RXJyb3IoXCJkZWxcIik7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBzZXRMYXJnZUZpbGUoY29uZmlnOiB7IHBhdGg6IHN0cmluZzsgZ2V0TmV4dERhdGEoKTogUHJvbWlzZTxCdWZmZXIgfCB1bmRlZmluZWQ+IH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhyb3cgdGhpcy5yZWFkT25seUVycm9yKFwic2V0TGFyZ2VGaWxlXCIpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZmluZChwcmVmaXg6IHN0cmluZywgY29uZmlnPzogeyBzaGFsbG93PzogYm9vbGVhbjsgdHlwZTogXCJmaWxlc1wiIHwgXCJmb2xkZXJzXCIgfSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAgICAgdGhyb3cgdGhpcy5yZWFkT25seUVycm9yKFwiZmluZCAobGlzdGluZylcIik7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBmaW5kSW5mbyhwcmVmaXg6IHN0cmluZywgY29uZmlnPzogeyBzaGFsbG93PzogYm9vbGVhbjsgdHlwZTogXCJmaWxlc1wiIHwgXCJmb2xkZXJzXCIgfSk6IFByb21pc2U8QXJjaGl2ZUZpbGVJbmZvW10+IHtcbiAgICAgICAgdGhyb3cgdGhpcy5yZWFkT25seUVycm9yKFwiZmluZEluZm8gKGxpc3RpbmcpXCIpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRVUkwocGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIGJ1aWxkRmlsZVVybCh0aGlzLmJhc2UsIHBhdGgpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0Q29uZmlnKCk6IFByb21pc2U8QXJjaGl2ZXNDb25maWc+IHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBoYXNXcml0ZUFjY2VzcygpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbiJdfQ==
|
|
90
|
+
/* _JS_SOURCE_HASH = "f79da9defa3a53604c042be74a73ab55dd1221a4530683b81f9bcb35645e499b"; */
|