sliftutils 1.7.10 → 1.7.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/examplestorage/exampleserver.ts +0 -2
  2. package/index.d.ts +290 -54
  3. package/misc/dist/environment.ts.cache +3 -3
  4. package/misc/dist/getSecret.ts.cache +139 -0
  5. package/misc/dist/strings.ts.cache +13 -0
  6. package/misc/dist/zip.ts.cache +9 -0
  7. package/misc/getSecret.ts +38 -16
  8. package/misc/https/cloudflareHelpers.d.ts +19 -0
  9. package/misc/https/cloudflareHelpers.ts +69 -0
  10. package/misc/https/dist/certs.ts.cache +115 -179
  11. package/misc/https/dist/cloudflareHelpers.ts.cache +68 -0
  12. package/misc/https/dist/dns.ts.cache +112 -100
  13. package/misc/https/dist/hostServer.ts.cache +130 -0
  14. package/misc/https/dist/httpsCerts.ts.cache +24 -5
  15. package/misc/https/dist/persistentLocalStorage.ts.cache +3 -2
  16. package/misc/https/dns.d.ts +41 -12
  17. package/misc/https/dns.ts +104 -101
  18. package/misc/https/hostServer.d.ts +0 -6
  19. package/misc/https/hostServer.ts +9 -5
  20. package/package.json +2 -2
  21. package/render-utils/dist/observer.tsx.cache +3 -2
  22. package/spec.txt +0 -90
  23. package/storage/ArchivesDisk.d.ts +2 -0
  24. package/storage/ArchivesDisk.ts +7 -3
  25. package/storage/BulkDatabase2/dist/BulkDatabaseBase.ts.cache +1242 -0
  26. package/storage/BulkDatabase2/dist/BulkDatabaseFormat.ts.cache +513 -0
  27. package/storage/BulkDatabase2/dist/BulkDatabaseMerge.ts.cache +352 -0
  28. package/storage/BulkDatabase2/dist/BulkDatabaseReader.ts.cache +306 -0
  29. package/storage/BulkDatabase2/dist/LoadedIndex.ts.cache +435 -0
  30. package/storage/BulkDatabase2/dist/WriteOverlay.ts.cache +58 -0
  31. package/storage/BulkDatabase2/dist/blockCache.ts.cache +179 -0
  32. package/storage/BulkDatabase2/dist/mergeLock.ts.cache +149 -0
  33. package/storage/BulkDatabase2/dist/mergeMarkers.ts.cache +101 -0
  34. package/storage/BulkDatabase2/dist/streamLog.ts.cache +227 -0
  35. package/storage/BulkDatabase2/dist/syncClient.ts.cache +104 -0
  36. package/storage/IArchives.d.ts +47 -15
  37. package/storage/IArchives.ts +86 -31
  38. package/storage/backblaze.d.ts +15 -0
  39. package/storage/backblaze.ts +199 -79
  40. package/storage/dist/ArchivesDisk.ts.cache +373 -0
  41. package/storage/dist/FileFolderAPI.tsx.cache +508 -65
  42. package/storage/dist/IArchives.ts.cache +44 -0
  43. package/storage/dist/IndexedDBFileFolderAPI.ts.cache +8 -2
  44. package/storage/dist/JSONStorage.ts.cache +6 -2
  45. package/storage/dist/PendingManager.tsx.cache +1 -1
  46. package/storage/dist/TransactionStorage.ts.cache +231 -92
  47. package/storage/dist/backblaze.ts.cache +797 -0
  48. package/storage/dist/fileSystemPointer.ts.cache +36 -3
  49. package/storage/dist/remoteFileStorage.ts.cache +495 -0
  50. package/storage/remoteStorage/ArchivesRemote.d.ts +5 -1
  51. package/storage/remoteStorage/ArchivesRemote.ts +28 -8
  52. package/storage/remoteStorage/ArchivesUrl.d.ts +2 -0
  53. package/storage/remoteStorage/ArchivesUrl.ts +16 -4
  54. package/storage/remoteStorage/blobStore.d.ts +52 -3
  55. package/storage/remoteStorage/blobStore.ts +414 -101
  56. package/storage/remoteStorage/createArchives.d.ts +31 -10
  57. package/storage/remoteStorage/createArchives.ts +470 -253
  58. package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +197 -0
  59. package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +85 -0
  60. package/storage/remoteStorage/dist/accessPage.tsx.cache +222 -0
  61. package/storage/remoteStorage/dist/blobStore.ts.cache +837 -0
  62. package/storage/remoteStorage/dist/cliArgs.ts.cache +16 -0
  63. package/storage/remoteStorage/dist/createArchives.ts.cache +610 -0
  64. package/storage/remoteStorage/dist/remoteConfig.ts.cache +206 -0
  65. package/storage/remoteStorage/dist/sourceWrapper.ts.cache +223 -0
  66. package/storage/remoteStorage/dist/storageController.ts.cache +500 -0
  67. package/storage/remoteStorage/dist/storageServer.ts.cache +106 -0
  68. package/storage/remoteStorage/dist/storageServerCli.ts.cache +39 -0
  69. package/storage/remoteStorage/dist/storageServerState.ts.cache +518 -0
  70. package/storage/remoteStorage/remoteConfig.d.ts +8 -0
  71. package/storage/remoteStorage/remoteConfig.ts +105 -5
  72. package/storage/remoteStorage/sourceWrapper.d.ts +41 -0
  73. package/storage/remoteStorage/sourceWrapper.ts +223 -0
  74. package/storage/remoteStorage/spec.md +31 -0
  75. package/storage/remoteStorage/storageController.d.ts +11 -0
  76. package/storage/remoteStorage/storageController.ts +109 -40
  77. package/storage/remoteStorage/storageServer.d.ts +0 -5
  78. package/storage/remoteStorage/storageServer.ts +17 -10
  79. package/storage/remoteStorage/storageServerCli.ts +0 -3
  80. package/storage/remoteStorage/storageServerState.d.ts +7 -1
  81. package/storage/remoteStorage/storageServerState.ts +230 -48
  82. package/testsite/server.ts +0 -2
  83. package/yarn.lock +11 -6
@@ -6,7 +6,8 @@ const zip_1 = require("../misc/zip");
6
6
  const batching_1 = require("socket-function/src/batching");
7
7
  const format_1 = require("socket-function/src/formatting/format");
8
8
  const PendingManager_1 = require("./PendingManager");
9
- const buildFlag_1 = require("../../buildFlag");
9
+ const environment_1 = require("../misc/environment");
10
+ const batching_2 = require("socket-function/src/batching");
10
11
  /*
11
12
  // Spec:
12
13
  // - Zip individual large values
@@ -38,9 +39,10 @@ UPDATE now we use chunks, because append is too slow.
38
39
 
39
40
  IMPORTANT! If there are multiple writers, we clobber writes from other writers when we compress
40
41
  */
42
+ const DISK_CHECK_INTERVAL = misc_1.timeInMinute * 5;
41
43
  const FILE_CHUNK_SIZE = 1024 * 1024;
44
+ const FILE_MAX_LIFETIME = misc_1.timeInMinute * 30;
42
45
  const FILE_ZIP_THRESHOLD = 16 * 1024 * 1024;
43
- const ZIP_THRESHOLD = 4096;
44
46
  const START_BYTES = Buffer.from([236, 49, 112, 121, 27, 127, 227, 63]);
45
47
  const END_BYTES = Buffer.from([220, 111, 243, 202, 200, 79, 213, 63]);
46
48
  // Delay writes, so we batch better, and thrash the disk less
@@ -50,16 +52,27 @@ const fileLockSection = (0, batching_1.runInSerial)(async (fnc) => {
50
52
  });
51
53
  const CHUNK_EXT = ".chunk";
52
54
  const ourId = Date.now() + Math.random();
55
+ let seqNum = 0;
56
+ function getNextChunkPath() {
57
+ return `${Date.now()}_${seqNum++}_${ourId}.chunk`;
58
+ }
53
59
  class TransactionStorage {
54
- constructor(rawStorage, debugName, writeDelay = WRITE_DELAY) {
60
+ constructor(rawStorage, debugName, writeDelay = WRITE_DELAY,
61
+ // When set, we poll the underlying storage and reload if another process/tab writes new
62
+ // chunk files. Off by default, as it costs a periodic disk scan and most collections are
63
+ // only written by a single process.
64
+ resyncFromDisk = false) {
55
65
  this.rawStorage = rawStorage;
56
66
  this.debugName = debugName;
57
67
  this.writeDelay = writeDelay;
68
+ this.resyncFromDisk = resyncFromDisk;
58
69
  this.cache = new Map();
59
- this.currentChunk = 0;
60
- this.currentChunkSize = 0;
70
+ // Maps file name to our last known write timestamp
71
+ this.diskFiles = new Map();
72
+ this.currentChunk = undefined;
61
73
  this.entryCount = 0;
62
- this.init = this.loadAllTransactions();
74
+ this.resyncCallbacks = [];
75
+ this.init = this.loadAllTransactions(true);
63
76
  this.pendingAppends = [];
64
77
  this.extraAppends = 0;
65
78
  this.updatePendingAppends = (0, misc_1.throttleFunction)(100, async () => {
@@ -74,20 +87,51 @@ class TransactionStorage {
74
87
  });
75
88
  this.compressing = false;
76
89
  TransactionStorage.allStorage.push(this);
90
+ // VERY useful for debugging.
91
+ globalThis[`tx${this.debugName}`] = this;
77
92
  }
78
93
  // Helps get rid of parse errors which constantly log. Also, uses less space
79
94
  static async compressAll() {
80
- for (let storage of TransactionStorage.allStorage) {
81
- await storage.compressTransactionLog(true);
95
+ await fileLockSection(async () => {
96
+ for (let storage of TransactionStorage.allStorage) {
97
+ await storage.compressTransactionLog(true);
98
+ }
99
+ });
100
+ }
101
+ watchResync(callback) {
102
+ this.resyncCallbacks.push(callback);
103
+ }
104
+ getCurrentChunk() {
105
+ if (this.currentChunk && this.currentChunk.timeCreated < Date.now() - FILE_MAX_LIFETIME) {
106
+ this.currentChunk = undefined;
107
+ }
108
+ if (!this.currentChunk) {
109
+ this.currentChunk = {
110
+ path: getNextChunkPath(),
111
+ size: 0,
112
+ timeCreated: Date.now()
113
+ };
114
+ // Timestamp will be updated after actual write
115
+ this.diskFiles.set(this.currentChunk.path, 0);
116
+ }
117
+ return this.currentChunk.path;
118
+ }
119
+ updateDiskFileTimestamp(file) {
120
+ this.diskFiles.set(file, Date.now());
121
+ }
122
+ onAddToChunk(size) {
123
+ if (!this.currentChunk)
124
+ return;
125
+ this.currentChunk.size += size;
126
+ if (this.currentChunk.size >= FILE_CHUNK_SIZE) {
127
+ this.currentChunk = undefined;
82
128
  }
83
129
  }
84
- getChunk(chunk) { return `${chunk}_${ourId}${CHUNK_EXT}`; }
85
130
  async get(key) {
86
131
  await this.init;
87
132
  const value = this.cache.get(key);
88
- if (value && value.isZipped && value.value) {
89
- value.value = await zip_1.Zip.gunzip(value.value);
90
- value.isZipped = false;
133
+ if (value && value.isZipped) {
134
+ throw new Error(`Transactions should be unzipped on file ready, so this state should be impossible. Key: ${key}`);
91
135
  }
92
136
  return value === null || value === void 0 ? void 0 : value.value;
93
137
  }
@@ -97,11 +141,6 @@ class TransactionStorage {
97
141
  // Time is set on disk write, as Date.now() is too slow
98
142
  let entry = { key, value, isZipped: false, time: 0 };
99
143
  this.cache.set(key, entry);
100
- if (value.length >= ZIP_THRESHOLD) {
101
- value = await zip_1.Zip.gzip(value);
102
- entry.value = value;
103
- entry.isZipped = true;
104
- }
105
144
  await this.pushAppend(entry);
106
145
  }
107
146
  async remove(key) {
@@ -154,18 +193,15 @@ class TransactionStorage {
154
193
  }
155
194
  let newChunks = this.chunkBuffers(buffers);
156
195
  for (let chunk of newChunks) {
157
- let file = this.getChunk(this.currentChunk);
196
+ let file = this.getCurrentChunk();
158
197
  if (!await this.rawStorage.get(file)) {
159
198
  let { header, headerBuffer } = this.getHeader(false);
160
199
  await this.rawStorage.set(file, headerBuffer);
161
200
  }
162
201
  let content = chunk.buffer;
163
202
  await this.rawStorage.append(file, content);
164
- this.currentChunkSize += content.length;
165
- if (this.currentChunkSize >= FILE_CHUNK_SIZE) {
166
- this.currentChunk++;
167
- this.currentChunkSize = 0;
168
- }
203
+ this.updateDiskFileTimestamp(file);
204
+ this.onAddToChunk(content.length);
169
205
  }
170
206
  await this.compressTransactionLog();
171
207
  }
@@ -181,37 +217,75 @@ class TransactionStorage {
181
217
  await this.init;
182
218
  return Array.from(this.cache.keys());
183
219
  }
184
- async loadAllTransactions() {
185
- if ((0, buildFlag_1.isInBuild)())
220
+ async checkDisk() {
221
+ if (this.init)
222
+ await this.init;
223
+ const anyChanges = async () => {
224
+ let keys = await this.rawStorage.getKeys();
225
+ let diskFiles = keys.filter(key => key.endsWith(CHUNK_EXT));
226
+ // Check if any known files have been modified externally (disk timestamp newer than ours)
227
+ for (let file of diskFiles) {
228
+ let ourTimestamp = this.diskFiles.get(file);
229
+ if (ourTimestamp === undefined) {
230
+ return true;
231
+ }
232
+ let info = await this.rawStorage.getInfo(file);
233
+ if (info && info.lastModified > ourTimestamp) {
234
+ return true;
235
+ }
236
+ }
237
+ return false;
238
+ };
239
+ if (!await anyChanges())
186
240
  return;
241
+ await fileLockSection(async () => {
242
+ if (!await anyChanges())
243
+ return;
244
+ console.log(`Found new changes in collection from other tab. Loading them now. ${this.debugName}`);
245
+ await this.loadAllTransactions();
246
+ });
247
+ }
248
+ // NOTE: This is either called in init (which blocks all other calls), or inside of the global file lock, so it is safe to load.
249
+ async loadAllTransactions(initialLoad) {
250
+ var _a;
251
+ if ((0, environment_1.isInBuild)())
252
+ return [];
253
+ if (initialLoad && this.resyncFromDisk) {
254
+ (0, batching_2.runInfinitePoll)(DISK_CHECK_INTERVAL, () => this.checkDisk());
255
+ }
187
256
  let time = Date.now();
188
257
  const keys = await this.rawStorage.getKeys();
189
258
  const transactionFiles = keys.filter(key => key.endsWith(CHUNK_EXT));
190
- (0, misc_1.sort)(transactionFiles, x => parseInt(x));
191
- let size = 0;
192
- for (const file of transactionFiles) {
193
- let chunk = parseInt(file);
194
- let curSize = await this.loadTransactionFile(file);
195
- if (chunk >= this.currentChunk) {
196
- this.currentChunk = chunk;
197
- this.currentChunkSize = curSize;
198
- }
199
- size += curSize;
259
+ // Populate diskFiles with actual timestamps from disk
260
+ this.diskFiles = new Map();
261
+ for (let file of transactionFiles) {
262
+ let info = await this.rawStorage.getInfo(file);
263
+ this.diskFiles.set(file, (_a = info === null || info === void 0 ? void 0 : info.lastModified) !== null && _a !== void 0 ? _a : Date.now());
264
+ }
265
+ let size = { value: 0 };
266
+ let entryList = [];
267
+ for (let file of transactionFiles) {
268
+ entryList.push(await this.parseTransactionFile(file, size));
200
269
  }
270
+ let entries = entryList.flat();
271
+ this.applyTransactionEntries(entries, initialLoad);
201
272
  time = Date.now() - time;
202
273
  if (time > 50) {
203
- console.log(`Loaded ${this.debugName} in ${(0, format_1.formatTime)(time)}, ${(0, format_1.formatNumber)(this.cache.size)} keys, ${(0, format_1.formatNumber)(size)}B`);
274
+ console.log(`Loaded ${this.debugName} in ${(0, format_1.formatTime)(time)}, ${(0, format_1.formatNumber)(this.cache.size)} keys, from ${(0, format_1.formatNumber)(transactionFiles.length)} files, entries ${(0, format_1.formatNumber)(entries.length)}, total size ${(0, format_1.formatNumber)(size.value)}B`, transactionFiles);
204
275
  }
205
276
  this.init = undefined;
277
+ return transactionFiles;
206
278
  }
207
- async loadTransactionFile(filename) {
279
+ // ONLY call this inside of loadAllTransactions
280
+ async parseTransactionFile(filename, size) {
208
281
  const fullFile = await this.rawStorage.get(filename);
209
282
  if (!fullFile)
210
- return 0;
283
+ return [];
211
284
  if (fullFile.length < 4) {
212
285
  //console.error(`Transaction in ${this.debugName} file ${filename} is too small, skipping`);
213
- return 0;
286
+ return [];
214
287
  }
288
+ size.value += fullFile.length;
215
289
  let headerSize = fullFile.readUInt32LE(0);
216
290
  let headerBuffer = fullFile.slice(4, 4 + headerSize);
217
291
  let header;
@@ -220,7 +294,7 @@ class TransactionStorage {
220
294
  }
221
295
  catch (e) {
222
296
  console.error(`Failed to parse header of transaction file in ${this.debugName}, ${filename}`);
223
- return 0;
297
+ return [];
224
298
  }
225
299
  let content = fullFile.slice(4 + headerSize);
226
300
  if (header.zipped) {
@@ -259,18 +333,70 @@ class TransactionStorage {
259
333
  let { entry } = entryObj;
260
334
  offset = entryObj.offset;
261
335
  entries.push(entry);
336
+ }
337
+ return entries;
338
+ }
339
+ applyTransactionEntries(entries, initialLoad) {
340
+ let pendingWriteTimes = new Map();
341
+ for (const entry of this.pendingAppends) {
342
+ let prevTime = pendingWriteTimes.get(entry.key);
343
+ if (prevTime && prevTime > entry.time) {
344
+ continue;
345
+ }
346
+ pendingWriteTimes.set(entry.key, entry.time);
347
+ }
348
+ let latest = new Map();
349
+ for (const entry of entries) {
350
+ let pendingTime = pendingWriteTimes.get(entry.key);
351
+ if (pendingTime && pendingTime > entry.time) {
352
+ continue;
353
+ }
354
+ let prev = latest.get(entry.key);
355
+ if (prev && prev.time > entry.time) {
356
+ continue;
357
+ }
358
+ latest.set(entry.key, entry);
359
+ }
360
+ let anyChanged = false;
361
+ for (let entry of latest.values()) {
262
362
  if (entry.value === undefined) {
363
+ if (!this.cache.has(entry.key))
364
+ continue;
365
+ anyChanged = true;
263
366
  this.cache.delete(entry.key);
264
367
  }
265
368
  else {
266
- let prev = this.cache.get(entry.key);
267
- if (prev && (prev.time > entry.time)) {
268
- continue;
369
+ if (!anyChanged && !initialLoad) {
370
+ const hasChanged = () => {
371
+ let prev = this.cache.get(entry.key);
372
+ if (!prev) {
373
+ return true;
374
+ }
375
+ if (!!prev.value !== !!entry.value)
376
+ return true;
377
+ if (prev.value && entry.value && !prev.value.equals(entry.value)) {
378
+ return true;
379
+ }
380
+ return false;
381
+ };
382
+ anyChanged = hasChanged() || anyChanged;
269
383
  }
270
384
  this.cache.set(entry.key, entry);
271
385
  }
272
386
  }
273
- return fullFile.length;
387
+ if (anyChanged && !initialLoad) {
388
+ console.warn(`Transaction storage ${this.debugName} changed on disk, triggering full download from disk`);
389
+ for (const callback of this.resyncCallbacks) {
390
+ try {
391
+ callback();
392
+ }
393
+ catch (e) {
394
+ setImmediate(() => {
395
+ throw e;
396
+ });
397
+ }
398
+ }
399
+ }
274
400
  }
275
401
  readTransactionEntry(buffer, offset) {
276
402
  function readSlice(count) {
@@ -292,6 +418,10 @@ class TransactionStorage {
292
418
  return undefined;
293
419
  let isZipped = (flags & 1) === 1;
294
420
  let isDelete = (flags & 2) === 2;
421
+ if (isZipped) {
422
+ value = zip_1.Zip.gunzipSync(value);
423
+ isZipped = false;
424
+ }
295
425
  let entry = { key, value, isZipped, time };
296
426
  if (isDelete) {
297
427
  entry.value = undefined;
@@ -351,53 +481,62 @@ class TransactionStorage {
351
481
  async compressTransactionLog(force) {
352
482
  if (this.compressing)
353
483
  return;
354
- this.compressing = true;
355
- let existingDiskEntries = await this.rawStorage.getKeys();
356
- existingDiskEntries = existingDiskEntries.filter(x => x.endsWith(CHUNK_EXT));
357
- let compressNow = force || (this.entryCount > 100 && this.entryCount > this.cache.size * 3
358
- // NOTE: This compress check breaks down if we only have very large values, but... those
359
- // don't work ANYWAYS (it is better to use one file per value instead).
360
- // - Maybe we should throw, or at least warn, on sets of value > 1MB,
361
- // at which point they should just use a file per value
362
- || existingDiskEntries.length > Math.max(10, Math.ceil(this.entryCount / 1000))
363
- || existingDiskEntries.length > 1000 * 10);
364
- if (!compressNow)
365
- return;
366
- console.log(`Compressing ${this.debugName} transaction log, ${this.entryCount} entries, ${this.cache.size} keys`);
367
- // Load off disk, in case there are other writes. We still race with them, but at least
368
- // this reduces the race condition considerably
369
- (0, misc_1.sort)(existingDiskEntries, x => parseInt(x));
370
- for (let entry of existingDiskEntries) {
371
- await this.loadTransactionFile(entry);
372
- }
373
- this.entryCount = this.cache.size;
374
- let nextStart = Math.max(...existingDiskEntries.map(x => parseInt(x))) + 1;
375
- let buffers = [];
376
- for (const entry of this.cache.values()) {
377
- let buffer = this.serializeTransactionEntry(entry);
378
- buffers.push(buffer);
379
- }
380
- let newChunks = this.chunkBuffers(buffers);
381
- let curChunk = nextStart;
382
- for (let chunk of newChunks) {
383
- let file = this.getChunk(curChunk++);
384
- let content = chunk.buffer;
385
- let { header, headerBuffer } = this.getHeader(
386
- // AND, never compress the last one, otherwise we can't append to it!
387
- content.length >= FILE_ZIP_THRESHOLD && chunk !== newChunks[newChunks.length - 1]);
388
- if (header.zipped) {
389
- content = await zip_1.Zip.gzip(content);
484
+ try {
485
+ this.compressing = true;
486
+ let existingDiskEntries = await this.rawStorage.getKeys();
487
+ existingDiskEntries = existingDiskEntries.filter(x => x.endsWith(CHUNK_EXT));
488
+ let compressNow = force || (this.entryCount > 100 && this.entryCount > this.cache.size * 3
489
+ // NOTE: This compress check breaks down if we only have very large values, but... those
490
+ // don't work ANYWAYS (it is better to use one file per value instead).
491
+ // - Maybe we should throw, or at least warn, on sets of value > 1MB,
492
+ // at which point they should just use a file per value
493
+ || existingDiskEntries.length > Math.max(10, Math.ceil(this.entryCount / 1000))
494
+ || existingDiskEntries.length > 1000 * 10);
495
+ if (!compressNow)
496
+ return;
497
+ console.log(`Compressing ${this.debugName} transaction log, ${this.entryCount} entries, ${this.cache.size} keys`);
498
+ // Load off disk, in case there are other writes. We still race with them, but at least
499
+ // this reduces the race condition considerably
500
+ existingDiskEntries = await this.loadAllTransactions();
501
+ this.entryCount = this.cache.size;
502
+ let buffers = [];
503
+ for (const entry of this.cache.values()) {
504
+ let buffer = this.serializeTransactionEntry(entry);
505
+ buffers.push(buffer);
506
+ }
507
+ let newChunks = this.chunkBuffers(buffers);
508
+ let newFiles = [];
509
+ for (let chunk of newChunks) {
510
+ // Don't use the previous current chunk for the new file. Also clear it afterwards so it's not reused for any future rights.
511
+ this.currentChunk = undefined;
512
+ let file = this.getCurrentChunk();
513
+ this.currentChunk = undefined;
514
+ newFiles.push(file);
515
+ let content = chunk.buffer;
516
+ let { header, headerBuffer } = this.getHeader(content.length >= FILE_ZIP_THRESHOLD);
517
+ if (header.zipped) {
518
+ content = await zip_1.Zip.gzip(content);
519
+ }
520
+ let buffer = Buffer.concat([headerBuffer, content]);
521
+ await this.rawStorage.set(file, buffer);
522
+ this.updateDiskFileTimestamp(file);
523
+ let verified = await this.rawStorage.get(file);
524
+ if (!(verified === null || verified === void 0 ? void 0 : verified.equals(buffer))) {
525
+ console.error(`Failed to verify transaction file ${file} in ${this.debugName}`);
526
+ throw new Error(`Failed to verify transaction file ${file} in ${this.debugName}`);
527
+ }
528
+ }
529
+ // This is the ONLY time we can delete old files, as we know for sure the new file has all of our data.
530
+ // Any future readers won't know this, unless they write it themselves (or unless they audit it against
531
+ // the other generations, which is annoying).
532
+ for (const file of existingDiskEntries) {
533
+ await this.rawStorage.remove(file);
534
+ this.diskFiles.delete(file);
390
535
  }
391
- let buffer = Buffer.concat([headerBuffer, content]);
392
- await this.rawStorage.set(file, buffer);
393
536
  }
394
- // This is the ONLY time we can delete old files, as we know for sure the new file has all of our data.
395
- // Any future readers won't know this, unless they write it themselves (or unless they audit it against
396
- // the other generations, which is annoying).
397
- for (const file of existingDiskEntries) {
398
- await this.rawStorage.remove(file);
537
+ finally {
538
+ this.compressing = false;
399
539
  }
400
- this.currentChunk = curChunk;
401
540
  }
402
541
  async reset() {
403
542
  await fileLockSection(async () => {
@@ -409,13 +548,13 @@ class TransactionStorage {
409
548
  catch (_a) { }
410
549
  this.pendingAppends = [];
411
550
  this.cache.clear();
412
- this.currentChunk = 0;
413
- this.currentChunkSize = 0;
551
+ this.diskFiles.clear();
552
+ this.currentChunk = undefined;
414
553
  this.entryCount = 0;
415
554
  });
416
555
  }
417
556
  }
418
557
  exports.TransactionStorage = TransactionStorage;
419
558
  TransactionStorage.allStorage = [];
420
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNhY3Rpb25TdG9yYWdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiVHJhbnNhY3Rpb25TdG9yYWdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1EQUE4RTtBQUU5RSxxQ0FBa0M7QUFDbEMsMkRBQTJEO0FBQzNELGtFQUFpRjtBQUNqRixxREFBOEM7QUFDOUMsK0NBQTRDO0FBRTVDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7RUE4QkU7QUFHRixNQUFNLGVBQWUsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBRXBDLE1BQU0sa0JBQWtCLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFFNUMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBQzNCLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN2RSxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdEUsNkRBQTZEO0FBQzdELE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQztBQWF4QixNQUFNLGVBQWUsR0FBRyxJQUFBLHNCQUFXLEVBQUMsS0FBSyxFQUFFLEdBQXdCLEVBQUUsRUFBRTtJQUNuRSxNQUFNLEdBQUcsRUFBRSxDQUFDO0FBQ2hCLENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDO0FBQzNCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7QUFFekMsTUFB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RyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RGLENBQUM7WUFBQyxXQUFNLENBQUMsQ0FBQyxDQUFDO1lBRVgsSUFBSSxDQUFDLGNBQWMsR0FBRyxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQztZQUN0QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO1lBQzFCLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO1FBQ3hCLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQzs7QUE5WkwsZ0RBK1pDO0FBelprQiw2QkFBVSxHQUF5QixFQUFFLEFBQTNCLENBQTRCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUHJvbWlzZU9iaiwgc29ydCwgdGhyb3R0bGVGdW5jdGlvbiB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL21pc2NcIjtcbmltcG9ydCB7IElTdG9yYWdlLCBJU3RvcmFnZVJhdyB9IGZyb20gXCIuL0lTdG9yYWdlXCI7XG5pbXBvcnQgeyBaaXAgfSBmcm9tIFwiLi4vbWlzYy96aXBcIjtcbmltcG9ydCB7IHJ1bkluU2VyaWFsIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvYmF0Y2hpbmdcIjtcbmltcG9ydCB7IGZvcm1hdE51bWJlciwgZm9ybWF0VGltZSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2Zvcm1hdHRpbmcvZm9ybWF0XCI7XG5pbXBvcnQgeyBzZXRQZW5kaW5nIH0gZnJvbSBcIi4vUGVuZGluZ01hbmFnZXJcIjtcbmltcG9ydCB7IGlzSW5CdWlsZCB9IGZyb20gXCIuLi8uLi9idWlsZEZsYWdcIjtcblxuLypcbi8vIFNwZWM6XG4vLyAgICAgIC0gWmlwIGluZGl2aWR1YWwgbGFyZ2UgdmFsdWVzXG4vLyAgICAgIC0gU3RvcmVzIGEgdHJhbnNhY3Rpb24gbG9nXG4vLyAgICAgICAgICAtIFRyYW5zYWN0aW9uIGxvZyBoYXMgYSBoZWFkZXIsIHdoaWNoIGlzIEpTT04sIGZvciB0aGluZ3Mgc3VjaCBhcyBcInppcHBlZFwiXG4vLyAgICAgICAgICAtIFRyYW5zYWN0aW9uIGxvZyB1c2VzIGxlbmd0aCBwcmVmaXhlZCB2YWx1ZXMsIHdpdGggYSBzcGVjaWFsIDggYnl0ZXMgdG8gZGVub3RlIHRoZSBlbmQsXG4vLyAgICAgICAgICAgICAgYW5kIDggZm9yIHRoZSBzdGFydC5cbi8vICAgICAgICAgIC0gV2hlbiB0cmFuc2FjdGlvbiBsb2cgaXMgaXRlcmF0ZWQgb24sIGlmIHRoZSBieXRlcyBhdCB0aGUgZW5kICh1c2luZyB0aGUgbGVuZ3RoIHByZWZpeClcbi8vICAgICAgICAgICAgICBkb24ndCBtYXRjaCB0aGUgZW5kIGJ5dGVzIE9SIHRoZSBzdGFydCBieXRlcyBhcmUgd3JvbmcsIHdlIHNraXAgdGhlIHN0YXJ0IGJ5dGVzLFxuLy8gICAgICAgICAgICAgIGFuZCBpdGVyYXRpbmcgdW50aWwgd2UgZmluZCBuZXcgc3RhcnQgYnl0ZXMgdGhhdCBtYXRjaCBvdXIgc3BlY2lhbCBieXRlcy4gVGhlbiB3ZSB0cnlcbi8vICAgICAgICAgICAgICB0byByZWFkIHRoZXNlIHZhbHVlcy5cbi8vICAgICAgICAgIC0gRWFjaCB0cmFuc2FjdGlvbiBlbnRyeSBoYXMgYSBieXRlIGZvciBmbGFncywgb25lIGJpdCB3aGljaCBkZW5vdGVzIGlmIHRoZSB2YWx1ZSBpcyB6aXBwZWQgb3Igbm90LlxuLy8gICAgICAtIENvbXByZXNzZXMgdGhlIGxvZyBhZnRlciB0aGVyZSBhcmUgM1ggZW50cmllcyB0aGFuIGtleXMgKGFuZCA+IDEwMClcbi8vICAgICAgICAgIC0gQm90aCBkZWR1cGUga2V5cywgYW5kIHppcFxuLy8gICAgICAtIEFzc3VtZXMgYWxsIGZpbGVzIGluIHJhd1N0b3JhZ2UgZW5kaW5nIHdpdGggLnR4IGFyZSB0cmFuc2FjdGlvbiBsb2dzXG4vLyAgICAgIC0gTmFtZXMgZmlsZXMgbGlrZSBgJHtnZW5lcmF0aW9ufS50eGBcbi8vICAgICAgICAgIC0gV2hlbiBjb21wcmVzc2luZywgd2UgaW5jcmVtZW50IHRoZSBnZW5lcmF0aW9uLCBhbmQgd3JpdGUgdG8gYSBuZXcgZmlsZSwgYW5kIGRlbGV0ZVxuLy8gICAgICAgICAgICAgIGFueSBnZW5lcmF0aW9ucyB0aGF0IGFyZSBvbGRlciB0aGFuIHRoZSBuZXcgb25lXG4vLyAgICAgICAgICAtIE9uIHJlYWRpbmcsIHdlIHJlYWQgZnJvbSBhbGwgZ2VuZXJhdGlvbiBmaWxlcyB0aGF0IGV4aXN0LCBpbiBjYXNlIHNvbWUgYXJlIGNvcnJ1cHRlZFxuLy8gICAgICAtIE9uIGxvYWQsIGxvYWRzIGluIGFsbCB0cmFuc2FjdGlvbiBsb2dzLCBhbmQgc3RvcmVzIGFsbCB2YWx1ZXMgaW4gYSBNYXA8c3RyaW5nLCBCdWZmZXI+XG4vLyAgICAgIC0gT24gd3JpdGVzIGltbWVkaWF0ZWx5IHVwZGF0ZXMgdGhlIGluIG1lbW9yeSBNYXAsIGFuZCB0aGVuIHdyaXRlcyB0byB0aGUgdHJhbnNhY3Rpb24gbG9nXG4vLyAgICAgIC0gQ2FjaGVzIHRoZSBsYXN0IHRyYW5zYWN0aW9uIGZpbGUgbmFtZSBpbiBtZW1vcnlcbi8vICAgICAgLSBNYWtlcyBzdXJlIGFsbCBmaWxlIHN5c3RlbSB3cml0ZXMgKGJ1dCBub3QgTWFwIHVwZGF0ZXMpIGFyZSBkb25lIHdpdGggZmlsZUxvY2tTZWN0aW9uLFxuLy8gICAgICAgICAgc28gdGhleSBuZXZlciBvdmVybGFwLlxuLy8gICAgICAtIEJ1ZmZlcnMgcGVuZGluZyBhcHBlbmRzIGluIG1lbW9yeSwgc28gdGhleSBjYW4gd3JpdHRlbiBhbGwgYXQgb25jZSAoYWZ0ZXIgdGhlIGZpcnN0IG9uZVxuLy8gICAgICAgICAgaXMgYmxvY2tpbmcgaW4gZmlsZUxvY2tTZWN0aW9uKS5cblxuVVBEQVRFIG5vdyB3ZSB1c2UgY2h1bmtzLCBiZWNhdXNlIGFwcGVuZCBpcyB0b28gc2xvdy5cblxuSU1QT1JUQU5UISBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgd3JpdGVycywgd2UgY2xvYmJlciB3cml0ZXMgZnJvbSBvdGhlciB3cml0ZXJzIHdoZW4gd2UgY29tcHJlc3NcbiovXG5cblxuY29uc3QgRklMRV9DSFVOS19TSVpFID0gMTAyNCAqIDEwMjQ7XG5cbmNvbnN0IEZJTEVfWklQX1RIUkVTSE9MRCA9IDE2ICogMTAyNCAqIDEwMjQ7XG5cbmNvbnN0IFpJUF9USFJFU0hPTEQgPSA0MDk2O1xuY29uc3QgU1RBUlRfQllURVMgPSBCdWZmZXIuZnJvbShbMjM2LCA0OSwgMTEyLCAxMjEsIDI3LCAxMjcsIDIyNywgNjNdKTtcbmNvbnN0IEVORF9CWVRFUyA9IEJ1ZmZlci5mcm9tKFsyMjAsIDExMSwgMjQzLCAyMDIsIDIwMCwgNzksIDIxMywgNjNdKTtcbi8vIERlbGF5IHdyaXRlcywgc28gd2UgYmF0Y2ggYmV0dGVyLCBhbmQgdGhyYXNoIHRoZSBkaXNrIGxlc3NcbmNvbnN0IFdSSVRFX0RFTEFZID0gNTAwO1xuXG5pbnRlcmZhY2UgVHJhbnNhY3Rpb25FbnRyeSB7XG4gICAga2V5OiBzdHJpbmc7XG4gICAgdmFsdWU6IEJ1ZmZlciB8IHVuZGVmaW5lZDtcbiAgICBpc1ppcHBlZDogYm9vbGVhbjtcbiAgICB0aW1lOiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBUcmFuc2FjdGlvbkhlYWRlciB7XG4gICAgemlwcGVkOiBib29sZWFuO1xufVxuXG5jb25zdCBmaWxlTG9ja1NlY3Rpb24gPSBydW5JblNlcmlhbChhc3luYyAoZm5jOiAoKSA9PiBQcm9taXNlPHZvaWQ+KSA9PiB7XG4gICAgYXdhaXQgZm5jKCk7XG59KTtcblxuY29uc3QgQ0hVTktfRVhUID0gXCIuY2h1bmtcIjtcbmNvbnN0IG91cklkID0gRGF0ZS5ub3coKSArIE1hdGgucmFuZG9tKCk7XG5cbmV4cG9ydCBjbGFzcyBUcmFuc2FjdGlvblN0b3JhZ2UgaW1wbGVtZW50cyBJU3RvcmFnZTxCdWZmZXI+IHtcbiAgICBwdWJsaWMgY2FjaGU6IE1hcDxzdHJpbmcsIFRyYW5zYWN0aW9uRW50cnk+ID0gbmV3IE1hcCgpO1xuICAgIHByaXZhdGUgY3VycmVudENodW5rID0gMDtcbiAgICBwcml2YXRlIGN1cnJlbnRDaHVua1NpemUgPSAwO1xuICAgIHByaXZhdGUgZW50cnlDb3VudCA9IDA7XG5cbiAgICBwcml2YXRlIHN0YXRpYyBhbGxTdG9yYWdlOiBUcmFuc2FjdGlvblN0b3JhZ2VbXSA9IFtdO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgcmF3U3RvcmFnZTogSVN0b3JhZ2VSYXcsXG4gICAgICAgIHByaXZhdGUgZGVidWdOYW1lOiBzdHJpbmcsXG4gICAgICAgIHByaXZhdGUgd3JpdGVEZWxheSA9IFdSSVRFX0RFTEFZXG4gICAgKSB7XG4gICAgICAgIFRyYW5zYWN0aW9uU3RvcmFnZS5hbGxTdG9yYWdlLnB1c2godGhpcyk7XG4gICAgfVxuICAgIC8vIEhlbHBzIGdldCByaWQgb2YgcGFyc2UgZXJyb3JzIHdoaWNoIGNvbnN0YW50bHkgbG9nLiBBbHNvLCB1c2VzIGxlc3Mgc3BhY2VcbiAgICBwdWJsaWMgc3RhdGljIGFzeW5jIGNvbXByZXNzQWxsKCkge1xuICAgICAgICBmb3IgKGxldCBzdG9yYWdlIG9mIFRyYW5zYWN0aW9uU3RvcmFnZS5hbGxTdG9yYWdlKSB7XG4gICAgICAgICAgICBhd2FpdCBzdG9yYWdlLmNvbXByZXNzVHJhbnNhY3Rpb25Mb2codHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXQ6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQgPSB0aGlzLmxvYWRBbGxUcmFuc2FjdGlvbnMoKTtcblxuICAgIHByaXZhdGUgZ2V0Q2h1bmsoY2h1bms6IG51bWJlcikgeyByZXR1cm4gYCR7Y2h1bmt9XyR7b3VySWR9JHtDSFVOS19FWFR9YDsgfVxuXG4gICAgcHVibGljIGFzeW5jIGdldChrZXk6IHN0cmluZyk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdDtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmNhY2hlLmdldChrZXkpO1xuICAgICAgICBpZiAodmFsdWUgJiYgdmFsdWUuaXNaaXBwZWQgJiYgdmFsdWUudmFsdWUpIHtcbiAgICAgICAgICAgIHZhbHVlLnZhbHVlID0gYXdhaXQgWmlwLmd1bnppcCh2YWx1ZS52YWx1ZSk7XG4gICAgICAgICAgICB2YWx1ZS5pc1ppcHBlZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZT8udmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHNldChrZXk6IHN0cmluZywgdmFsdWU6IEJ1ZmZlcik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAodGhpcy5pbml0KSBhd2FpdCB0aGlzLmluaXQ7XG5cbiAgICAgICAgLy8gVGltZSBpcyBzZXQgb24gZGlzayB3cml0ZSwgYXMgRGF0ZS5ub3coKSBpcyB0b28gc2xvd1xuICAgICAgICBsZXQgZW50cnk6IFRyYW5zYWN0aW9uRW50cnkgPSB7IGtleSwgdmFsdWUsIGlzWmlwcGVkOiBmYWxzZSwgdGltZTogMCB9O1xuICAgICAgICB0aGlzLmNhY2hlLnNldChrZXksIGVudHJ5KTtcblxuICAgICAgICBpZiAodmFsdWUubGVuZ3RoID49IFpJUF9USFJFU0hPTEQpIHtcbiAgICAgICAgICAgIHZhbHVlID0gYXdhaXQgWmlwLmd6aXAodmFsdWUpO1xuICAgICAgICAgICAgZW50cnkudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICAgIGVudHJ5LmlzWmlwcGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB0aGlzLnB1c2hBcHBlbmQoZW50cnkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyByZW1vdmUoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKHRoaXMuaW5pdCkgYXdhaXQgdGhpcy5pbml0O1xuICAgICAgICB0aGlzLmNhY2hlLmRlbGV0ZShrZXkpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMucHVzaEFwcGVuZCh7IGtleSwgdmFsdWU6IHVuZGVmaW5lZCwgaXNaaXBwZWQ6IGZhbHNlLCB0aW1lOiAwIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRJbmZvKGtleTogc3RyaW5nKTogUHJvbWlzZTx7IHNpemU6IG51bWJlcjsgbGFzdE1vZGlmaWVkOiBudW1iZXIgfSB8IHVuZGVmaW5lZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLmluaXQ7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5jYWNoZS5nZXQoa2V5KTtcbiAgICAgICAgaWYgKCF2YWx1ZT8udmFsdWUpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB7IHNpemU6IHZhbHVlLnZhbHVlLmxlbmd0aCwgbGFzdE1vZGlmaWVkOiB2YWx1ZS50aW1lIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBwZW5kaW5nQXBwZW5kczogVHJhbnNhY3Rpb25FbnRyeVtdID0gW107XG4gICAgcHJpdmF0ZSBleHRyYUFwcGVuZHMgPSAwO1xuICAgIHByaXZhdGUgcGVuZGluZ1dyaXRlOiBQcm9taXNlPHZvaWQ+IHwgdW5kZWZpbmVkO1xuICAgIGFzeW5jIHB1c2hBcHBlbmQoZW50cnk6IFRyYW5zYWN0aW9uRW50cnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5lbnRyeUNvdW50Kys7XG4gICAgICAgIHRoaXMucGVuZGluZ0FwcGVuZHMucHVzaChlbnRyeSk7XG4gICAgICAgIHZvaWQgdGhpcy51cGRhdGVQZW5kaW5nQXBwZW5kcygpO1xuICAgICAgICBpZiAodGhpcy5wZW5kaW5nV3JpdGUpIHJldHVybiB0aGlzLnBlbmRpbmdXcml0ZTtcbiAgICAgICAgdGhpcy5wZW5kaW5nV3JpdGUgPSBmaWxlTG9ja1NlY3Rpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgLy8gRGVsYXkgdG8gYWxsb3cgYmF0Y2hpbmcsIGFuZCBkZWR1cGluZ1xuICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIHRoaXMud3JpdGVEZWxheSkpO1xuICAgICAgICAgICAgbGV0IGN1ckFwcGVuZHMgPSB0aGlzLnBlbmRpbmdBcHBlbmRzO1xuICAgICAgICAgICAgdGhpcy5wZW5kaW5nQXBwZW5kcyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5wZW5kaW5nV3JpdGUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGV0IGFwcGVuZHNEZWR1cGVkOiBNYXA8c3RyaW5nLCBUcmFuc2FjdGlvbkVudHJ5PiA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGN1ckFwcGVuZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgYXBwZW5kc0RlZHVwZWQuc2V0KGVudHJ5LmtleSwgZW50cnkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjdXJBcHBlbmRzID0gQXJyYXkuZnJvbShhcHBlbmRzRGVkdXBlZC52YWx1ZXMoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmV4dHJhQXBwZW5kcyArPSBjdXJBcHBlbmRzLmxlbmd0aDtcbiAgICAgICAgICAgIHZvaWQgdGhpcy51cGRhdGVQZW5kaW5nQXBwZW5kcygpO1xuICAgICAgICAgICAgaWYgKGN1ckFwcGVuZHMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgICAgICAgICB0cnkge1xuXG4gICAgICAgICAgICAgICAgbGV0IHRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGVudHJ5IG9mIGN1ckFwcGVuZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgZW50cnkudGltZSA9IHRpbWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IG5ld1N1bSA9IDA7XG4gICAgICAgICAgICAgICAgbGV0IGJ1ZmZlcnM6IEJ1ZmZlcltdID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBjdXJBcHBlbmRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBidWZmZXIgPSB0aGlzLnNlcmlhbGl6ZVRyYW5zYWN0aW9uRW50cnkoZW50cnkpO1xuICAgICAgICAgICAgICAgICAgICBidWZmZXJzLnB1c2goYnVmZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgbmV3U3VtICs9IGJ1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IG5ld0NodW5rcyA9IHRoaXMuY2h1bmtCdWZmZXJzKGJ1ZmZlcnMpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGNodW5rIG9mIG5ld0NodW5rcykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgZmlsZSA9IHRoaXMuZ2V0Q2h1bmsodGhpcy5jdXJyZW50Q2h1bmspO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWF3YWl0IHRoaXMucmF3U3RvcmFnZS5nZXQoZmlsZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCB7IGhlYWRlciwgaGVhZGVyQnVmZmVyIH0gPSB0aGlzLmdldEhlYWRlcihmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJhd1N0b3JhZ2Uuc2V0KGZpbGUsIGhlYWRlckJ1ZmZlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbnRlbnQgPSBjaHVuay5idWZmZXI7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmF3U3RvcmFnZS5hcHBlbmQoZmlsZSwgY29udGVudCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudENodW5rU2l6ZSArPSBjb250ZW50Lmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudENodW5rU2l6ZSA+PSBGSUxFX0NIVU5LX1NJWkUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudENodW5rKys7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRDaHVua1NpemUgPSAwO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5jb21wcmVzc1RyYW5zYWN0aW9uTG9nKCk7XG4gICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHRoaXMuZXh0cmFBcHBlbmRzIC09IGN1ckFwcGVuZHMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIHZvaWQgdGhpcy51cGRhdGVQZW5kaW5nQXBwZW5kcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy5wZW5kaW5nV3JpdGU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1cGRhdGVQZW5kaW5nQXBwZW5kcyA9IHRocm90dGxlRnVuY3Rpb24oMTAwLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGxldCBhcHBlbmRDb3VudCA9IHRoaXMucGVuZGluZ0FwcGVuZHMubGVuZ3RoICsgdGhpcy5leHRyYUFwcGVuZHM7XG4gICAgICAgIGxldCBncm91cCA9IGBUcmFuc2FjdGlvbiAoJHt0aGlzLmRlYnVnTmFtZX0pYDtcbiAgICAgICAgLy9jb25zb2xlLmxvZyhgVXBkYXRlIHBlbmRpbmcgYXBwZW5kcyAke2dyb3VwfTogJHthcHBlbmRDb3VudH1gKTtcbiAgICAgICAgaWYgKCFhcHBlbmRDb3VudCkge1xuICAgICAgICAgICAgc2V0UGVuZGluZyhncm91cCwgXCJcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc2V0UGVuZGluZyhncm91cCwgYFBlbmRpbmcgYXBwZW5kczogJHthcHBlbmRDb3VudH1gKTtcbiAgICB9KTtcblxuICAgIHB1YmxpYyBhc3luYyBnZXRLZXlzKCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAgICAgaWYgKHRoaXMuaW5pdCkgYXdhaXQgdGhpcy5pbml0O1xuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmNhY2hlLmtleXMoKSk7XG4gICAgfVxuXG5cbiAgICBwcml2YXRlIGFzeW5jIGxvYWRBbGxUcmFuc2FjdGlvbnMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmIChpc0luQnVpbGQoKSkgcmV0dXJuO1xuICAgICAgICBsZXQgdGltZSA9IERhdGUubm93KCk7XG4gICAgICAgIGNvbnN0IGtleXMgPSBhd2FpdCB0aGlzLnJhd1N0b3JhZ2UuZ2V0S2V5cygpO1xuICAgICAgICBjb25zdCB0cmFuc2FjdGlvbkZpbGVzID0ga2V5cy5maWx0ZXIoa2V5ID0+IGtleS5lbmRzV2l0aChDSFVOS19FWFQpKTtcblxuICAgICAgICBzb3J0KHRyYW5zYWN0aW9uRmlsZXMsIHggPT4gcGFyc2VJbnQoeCkpO1xuXG4gICAgICAgIGxldCBzaXplID0gMDtcbiAgICAgICAgZm9yIChjb25zdCBmaWxlIG9mIHRyYW5zYWN0aW9uRmlsZXMpIHtcbiAgICAgICAgICAgIGxldCBjaHVuayA9IHBhcnNlSW50KGZpbGUpO1xuICAgICAgICAgICAgbGV0IGN1clNpemUgPSBhd2FpdCB0aGlzLmxvYWRUcmFuc2FjdGlvbkZpbGUoZmlsZSk7XG4gICAgICAgICAgICBpZiAoY2h1bmsgPj0gdGhpcy5jdXJyZW50Q2h1bmspIHtcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRDaHVuayA9IGNodW5rO1xuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudENodW5rU2l6ZSA9IGN1clNpemU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaXplICs9IGN1clNpemU7XG4gICAgICAgIH1cbiAgICAgICAgdGltZSA9IERhdGUubm93KCkgLSB0aW1lO1xuICAgICAgICBpZiAodGltZSA+IDUwKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgTG9hZGVkICR7dGhpcy5kZWJ1Z05hbWV9IGluICR7Zm9ybWF0VGltZSh0aW1lKX0sICR7Zm9ybWF0TnVtYmVyKHRoaXMuY2FjaGUuc2l6ZSl9IGtleXMsICR7Zm9ybWF0TnVtYmVyKHNpemUpfUJgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuaW5pdCA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGxvYWRUcmFuc2FjdGlvbkZpbGUoZmlsZW5hbWU6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgICAgIGNvbnN0IGZ1bGxGaWxlID0gYXdhaXQgdGhpcy5yYXdTdG9yYWdlLmdldChmaWxlbmFtZSk7XG4gICAgICAgIGlmICghZnVsbEZpbGUpIHJldHVybiAwO1xuICAgICAgICBpZiAoZnVsbEZpbGUubGVuZ3RoIDwgNCkge1xuICAgICAgICAgICAgLy9jb25zb2xlLmVycm9yKGBUcmFuc2FjdGlvbiBpbiAke3RoaXMuZGVidWdOYW1lfSBmaWxlICR7ZmlsZW5hbWV9IGlzIHRvbyBzbWFsbCwgc2tpcHBpbmdgKTtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGxldCBoZWFkZXJTaXplID0gZnVsbEZpbGUucmVhZFVJbnQzMkxFKDApO1xuICAgICAgICBsZXQgaGVhZGVyQnVmZmVyID0gZnVsbEZpbGUuc2xpY2UoNCwgNCArIGhlYWRlclNpemUpO1xuICAgICAgICBsZXQgaGVhZGVyOiBUcmFuc2FjdGlvbkhlYWRlcjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGhlYWRlciA9IEpTT04ucGFyc2UoaGVhZGVyQnVmZmVyLnRvU3RyaW5nKCkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcGFyc2UgaGVhZGVyIG9mIHRyYW5zYWN0aW9uIGZpbGUgaW4gJHt0aGlzLmRlYnVnTmFtZX0sICR7ZmlsZW5hbWV9YCk7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY29udGVudCA9IGZ1bGxGaWxlLnNsaWNlKDQgKyBoZWFkZXJTaXplKTtcbiAgICAgICAgaWYgKGhlYWRlci56aXBwZWQpIHtcbiAgICAgICAgICAgIGNvbnRlbnQgPSBhd2FpdCBaaXAuZ3VuemlwKGNvbnRlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG9mZnNldCA9IDA7XG4gICAgICAgIGxldCBlbnRyaWVzOiBUcmFuc2FjdGlvbkVudHJ5W10gPSBbXTtcbiAgICAgICAgd2hpbGUgKG9mZnNldCA8IGNvbnRlbnQubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoIWNvbnRlbnQuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBTVEFSVF9CWVRFUy5sZW5ndGgpLmVxdWFscyhTVEFSVF9CWVRFUykpIHtcbiAgICAgICAgICAgICAgICBsZXQgcyA9IG9mZnNldDtcbiAgICAgICAgICAgICAgICB3aGlsZSAob2Zmc2V0IDwgY29udGVudC5sZW5ndGggJiYgIWNvbnRlbnQuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBTVEFSVF9CWVRFUy5sZW5ndGgpLmVxdWFscyhTVEFSVF9CWVRFUykpIHtcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0Kys7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBsZW4gPSBvZmZzZXQgLSBzO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgRm91bmQgYmFkIGJ5dGVzIGluICR7ZmlsZW5hbWV9LCBza2lwcGluZyAke2xlbn0gYnl0ZXMgYXQgb2Zmc2V0ICR7c30uIFRvdGFsIGZpbGUgYnl0ZXMgJHtjb250ZW50Lmxlbmd0aH0sIHJlYWQgJHtlbnRyaWVzLmxlbmd0aH0gZW50cmllc2ApO1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPj0gY29udGVudC5sZW5ndGgpIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IGVudHJ5T2JqOiB7IGVudHJ5OiBUcmFuc2FjdGlvbkVudHJ5LCBvZmZzZXQ6IG51bWJlciB9IHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBlbnRyeU9iaiA9IHRoaXMucmVhZFRyYW5zYWN0aW9uRW50cnkoY29udGVudCwgb2Zmc2V0KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgICAgICAgIGlmIChlLm1lc3NhZ2UuaW5jbHVkZXMoXCJSZWFkIHBhc3QgZW5kIG9mIGJ1ZmZlclwiKSkge1xuICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWVudHJ5T2JqKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBGYWlsZWQgdG8gcmVhZCB0cmFuc2FjdGlvbiBlbnRyeSBpbiBpbiAke3RoaXMuZGVidWdOYW1lfSwgZmlsZSAke2ZpbGVuYW1lfSBhdCBvZmZzZXQgJHtvZmZzZXR9LCBza2lwcGluZyBiYWQgYnl0ZXMsIHJlYWRpbmcgcmVtYWluZGVyIG9mIGZpbGVgKTtcbiAgICAgICAgICAgICAgICBvZmZzZXQrKztcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZW50cnlDb3VudCsrO1xuICAgICAgICAgICAgbGV0IHsgZW50cnkgfSA9IGVudHJ5T2JqO1xuICAgICAgICAgICAgb2Zmc2V0ID0gZW50cnlPYmoub2Zmc2V0O1xuICAgICAgICAgICAgZW50cmllcy5wdXNoKGVudHJ5KTtcblxuICAgICAgICAgICAgaWYgKGVudHJ5LnZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhY2hlLmRlbGV0ZShlbnRyeS5rZXkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgcHJldiA9IHRoaXMuY2FjaGUuZ2V0KGVudHJ5LmtleSk7XG4gICAgICAgICAgICAgICAgaWYgKHByZXYgJiYgKHByZXYudGltZSA+IGVudHJ5LnRpbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmNhY2hlLnNldChlbnRyeS5rZXksIGVudHJ5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZnVsbEZpbGUubGVuZ3RoO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVhZFRyYW5zYWN0aW9uRW50cnkoYnVmZmVyOiBCdWZmZXIsIG9mZnNldDogbnVtYmVyKToge1xuICAgICAgICBlbnRyeTogVHJhbnNhY3Rpb25FbnRyeTtcbiAgICAgICAgb2Zmc2V0OiBudW1iZXI7XG4gICAgfSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGZ1bmN0aW9uIHJlYWRTbGljZShjb3VudDogbnVtYmVyKSB7XG4gICAgICAgICAgICBjb25zdCBzbGljZSA9IGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIGNvdW50KTtcbiAgICAgICAgICAgIGlmIChzbGljZS5sZW5ndGggPCBjb3VudCkgdGhyb3cgbmV3IEVycm9yKGBSZWFkIHBhc3QgZW5kIG9mIGJ1ZmZlciBhdCBvZmZzZXQgJHtvZmZzZXR9LyR7YnVmZmVyLmxlbmd0aH1gKTtcbiAgICAgICAgICAgIG9mZnNldCArPSBjb3VudDtcbiAgICAgICAgICAgIHJldHVybiBzbGljZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXJlYWRTbGljZShTVEFSVF9CWVRFUy5sZW5ndGgpLmVxdWFscyhTVEFSVF9CWVRFUykpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgICAgY29uc3Qga2V5TGVuZ3RoID0gcmVhZFNsaWNlKDQpLnJlYWRVSW50MzJMRSgwKTtcbiAgICAgICAgY29uc3QgdmFsdWVMZW5ndGggPSByZWFkU2xpY2UoNCkucmVhZFVJbnQzMkxFKDApO1xuICAgICAgICBjb25zdCB0aW1lID0gcmVhZFNsaWNlKDgpLnJlYWREb3VibGVMRSgwKTtcbiAgICAgICAgY29uc3QgZmxhZ3MgPSByZWFkU2xpY2UoMSkucmVhZFVJbnQ4KDApO1xuXG4gICAgICAgIGNvbnN0IGtleSA9IHJlYWRTbGljZShrZXlMZW5ndGgpLnRvU3RyaW5nKCk7XG4gICAgICAgIGxldCB2YWx1ZSA9IHJlYWRTbGljZSh2YWx1ZUxlbmd0aCk7XG5cbiAgICAgICAgaWYgKCFyZWFkU2xpY2UoRU5EX0JZVEVTLmxlbmd0aCkuZXF1YWxzKEVORF9CWVRFUykpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgICAgbGV0IGlzWmlwcGVkID0gKGZsYWdzICYgMSkgPT09IDE7XG4gICAgICAgIGxldCBpc0RlbGV0ZSA9IChmbGFncyAmIDIpID09PSAyO1xuXG4gICAgICAgIGxldCBlbnRyeTogVHJhbnNhY3Rpb25FbnRyeSA9IHsga2V5LCB2YWx1ZSwgaXNaaXBwZWQsIHRpbWUgfTtcbiAgICAgICAgaWYgKGlzRGVsZXRlKSB7XG4gICAgICAgICAgICBlbnRyeS52YWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBlbnRyeSwgb2Zmc2V0IH07XG4gICAgfVxuXG4gICAgLy8gVE9ETzogTWFrZSB0aGlzIGRpcmVjdGx5IGdvIGZyb20gVHJhbnNhY3Rpb25FbnRyeVtdIHRvIEJ1ZmZlciwgYnkgcHJlLWFsbG9jYXRpbmcsIHNvIGl0IGlzIG1vcmUgZWZmaWNpZW50XG4gICAgcHJpdmF0ZSBzZXJpYWxpemVUcmFuc2FjdGlvbkVudHJ5KGVudHJ5OiBUcmFuc2FjdGlvbkVudHJ5KTogQnVmZmVyIHtcbiAgICAgICAgbGV0IGtleUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKGVudHJ5LmtleSk7XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyhcbiAgICAgICAgICAgIFNUQVJUX0JZVEVTLmxlbmd0aCArIDQgKyA0ICsgOCArIDEgKyBrZXlCdWZmZXIubGVuZ3RoICsgKGVudHJ5LnZhbHVlPy5sZW5ndGggfHwgMCkgKyBFTkRfQllURVMubGVuZ3RoXG4gICAgICAgICk7XG4gICAgICAgIGxldCBvZmZzZXQgPSAwO1xuXG4gICAgICAgIFNUQVJUX0JZVEVTLmNvcHkoYnVmZmVyLCBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgKz0gU1RBUlRfQllURVMubGVuZ3RoO1xuXG4gICAgICAgIGJ1ZmZlci53cml0ZVVJbnQzMkxFKGtleUJ1ZmZlci5sZW5ndGgsIG9mZnNldCk7XG4gICAgICAgIG9mZnNldCArPSA0O1xuXG4gICAgICAgIGJ1ZmZlci53cml0ZVVJbnQzMkxFKGVudHJ5LnZhbHVlID8gZW50cnkudmFsdWUubGVuZ3RoIDogMCwgb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0ICs9IDQ7XG5cbiAgICAgICAgYnVmZmVyLndyaXRlRG91YmxlTEUoZW50cnkudGltZSwgb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0ICs9IDg7XG5cbiAgICAgICAgbGV0IGZsYWdzID0gMDtcbiAgICAgICAgaWYgKGVudHJ5LmlzWmlwcGVkKSBmbGFncyB8PSAxO1xuICAgICAgICBpZiAoZW50cnkudmFsdWUgPT09IHVuZGVmaW5lZCkgZmxhZ3MgfD0gMjtcbiAgICAgICAgYnVmZmVyLndyaXRlVUludDgoZmxhZ3MsIG9mZnNldCk7XG4gICAgICAgIG9mZnNldCArPSAxO1xuXG4gICAgICAgIGtleUJ1ZmZlci5jb3B5KGJ1ZmZlciwgb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0ICs9IGtleUJ1ZmZlci5sZW5ndGg7XG5cbiAgICAgICAgaWYgKGVudHJ5LnZhbHVlKSB7XG4gICAgICAgICAgICBlbnRyeS52YWx1ZS5jb3B5KGJ1ZmZlciwgb2Zmc2V0KTtcbiAgICAgICAgICAgIG9mZnNldCArPSBlbnRyeS52YWx1ZS5sZW5ndGg7XG4gICAgICAgIH1cblxuICAgICAgICBFTkRfQllURVMuY29weShidWZmZXIsIG9mZnNldCk7XG4gICAgICAgIG9mZnNldCArPSBFTkRfQllURVMubGVuZ3RoO1xuXG4gICAgICAgIHJldHVybiBidWZmZXI7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRIZWFkZXIoemlwOiBib29sZWFuKSB7XG4gICAgICAgIGNvbnN0IGhlYWRlcjogVHJhbnNhY3Rpb25IZWFkZXIgPSB7IHppcHBlZDogemlwIH07XG4gICAgICAgIGxldCBoZWFkZXJCdWZmZXIgPSBCdWZmZXIuZnJvbShKU09OLnN0cmluZ2lmeShoZWFkZXIpKTtcbiAgICAgICAgbGV0IGhlYWRlclNpemUgPSBCdWZmZXIuYWxsb2MoNCk7XG4gICAgICAgIGhlYWRlclNpemUud3JpdGVVSW50MzJMRShoZWFkZXJCdWZmZXIubGVuZ3RoLCAwKTtcbiAgICAgICAgcmV0dXJuIHsgaGVhZGVyLCBoZWFkZXJCdWZmZXI6IEJ1ZmZlci5jb25jYXQoW2hlYWRlclNpemUsIGhlYWRlckJ1ZmZlcl0pIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjaHVua0J1ZmZlcnMoYnVmZmVyczogQnVmZmVyW10pIHtcbiAgICAgICAgbGV0IG5ld0NodW5rczoge1xuICAgICAgICAgICAgYnVmZmVyczogQnVmZmVyW107XG4gICAgICAgICAgICBzaXplOiBudW1iZXI7XG4gICAgICAgIH1bXSA9IFtdO1xuICAgICAgICBuZXdDaHVua3MucHVzaCh7IGJ1ZmZlcnM6IFtdLCBzaXplOiAwIH0pO1xuICAgICAgICBmb3IgKGNvbnN0IGJ1ZmZlciBvZiBidWZmZXJzKSB7XG4gICAgICAgICAgICBpZiAobmV3Q2h1bmtzW25ld0NodW5rcy5sZW5ndGggLSAxXS5zaXplICsgYnVmZmVyLmxlbmd0aCA+PSBGSUxFX0NIVU5LX1NJWkUpIHtcbiAgICAgICAgICAgICAgICBuZXdDaHVua3MucHVzaCh7IGJ1ZmZlcnM6IFtdLCBzaXplOiAwIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbmV3Q2h1bmtzW25ld0NodW5rcy5sZW5ndGggLSAxXS5idWZmZXJzLnB1c2goYnVmZmVyKTtcbiAgICAgICAgICAgIG5ld0NodW5rc1tuZXdDaHVua3MubGVuZ3RoIC0gMV0uc2l6ZSArPSBidWZmZXIubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXdDaHVua3MubWFwKHggPT4gKHsgYnVmZmVyOiBCdWZmZXIuY29uY2F0KHguYnVmZmVycyksIHNpemU6IHguc2l6ZSB9KSk7XG4gICAgfVxuXG5cbiAgICBwcml2YXRlIGNvbXByZXNzaW5nID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBhc3luYyBjb21wcmVzc1RyYW5zYWN0aW9uTG9nKGZvcmNlPzogYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAodGhpcy5jb21wcmVzc2luZykgcmV0dXJuO1xuICAgICAgICB0aGlzLmNvbXByZXNzaW5nID0gdHJ1ZTtcblxuICAgICAgICBsZXQgZXhpc3RpbmdEaXNrRW50cmllcyA9IGF3YWl0IHRoaXMucmF3U3RvcmFnZS5nZXRLZXlzKCk7XG4gICAgICAgIGV4aXN0aW5nRGlza0VudHJpZXMgPSBleGlzdGluZ0Rpc2tFbnRyaWVzLmZpbHRlcih4ID0+IHguZW5kc1dpdGgoQ0hVTktfRVhUKSk7XG4gICAgICAgIGxldCBjb21wcmVzc05vdyA9IGZvcmNlIHx8IChcbiAgICAgICAgICAgIHRoaXMuZW50cnlDb3VudCA+IDEwMCAmJiB0aGlzLmVudHJ5Q291bnQgPiB0aGlzLmNhY2hlLnNpemUgKiAzXG4gICAgICAgICAgICAvLyBOT1RFOiBUaGlzIGNvbXByZXNzIGNoZWNrIGJyZWFrcyBkb3duIGlmIHdlIG9ubHkgaGF2ZSB2ZXJ5IGxhcmdlIHZhbHVlcywgYnV0Li4uIHRob3NlXG4gICAgICAgICAgICAvLyAgZG9uJ3Qgd29yayBBTllXQVlTIChpdCBpcyBiZXR0ZXIgdG8gdXNlIG9uZSBmaWxlIHBlciB2YWx1ZSBpbnN0ZWFkKS5cbiAgICAgICAgICAgIC8vICAtIE1heWJlIHdlIHNob3VsZCB0aHJvdywgb3IgYXQgbGVhc3Qgd2Fybiwgb24gc2V0cyBvZiB2YWx1ZSA+IDFNQixcbiAgICAgICAgICAgIC8vICAgICAgYXQgd2hpY2ggcG9pbnQgdGhleSBzaG91bGQganVzdCB1c2UgYSBmaWxlIHBlciB2YWx1ZVxuICAgICAgICAgICAgfHwgZXhpc3RpbmdEaXNrRW50cmllcy5sZW5ndGggPiBNYXRoLm1heCgxMCwgTWF0aC5jZWlsKHRoaXMuZW50cnlDb3VudCAvIDEwMDApKVxuICAgICAgICAgICAgfHwgZXhpc3RpbmdEaXNrRW50cmllcy5sZW5ndGggPiAxMDAwICogMTBcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCFjb21wcmVzc05vdykgcmV0dXJuO1xuICAgICAgICBjb25zb2xlLmxvZyhgQ29tcHJlc3NpbmcgJHt0aGlzLmRlYnVnTmFtZX0gdHJhbnNhY3Rpb24gbG9nLCAke3RoaXMuZW50cnlDb3VudH0gZW50cmllcywgJHt0aGlzLmNhY2hlLnNpemV9IGtleXNgKTtcblxuICAgICAgICAvLyBMb2FkIG9mZiBkaXNrLCBpbiBjYXNlIHRoZXJlIGFyZSBvdGhlciB3cml0ZXMuIFdlIHN0aWxsIHJhY2Ugd2l0aCB0aGVtLCBidXQgYXQgbGVhc3RcbiAgICAgICAgLy8gIHRoaXMgcmVkdWNlcyB0aGUgcmFjZSBjb25kaXRpb24gY29uc2lkZXJhYmx5XG5cbiAgICAgICAgc29ydChleGlzdGluZ0Rpc2tFbnRyaWVzLCB4ID0+IHBhcnNlSW50KHgpKTtcbiAgICAgICAgZm9yIChsZXQgZW50cnkgb2YgZXhpc3RpbmdEaXNrRW50cmllcykge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5sb2FkVHJhbnNhY3Rpb25GaWxlKGVudHJ5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZW50cnlDb3VudCA9IHRoaXMuY2FjaGUuc2l6ZTtcblxuICAgICAgICBsZXQgbmV4dFN0YXJ0ID0gTWF0aC5tYXgoLi4uZXhpc3RpbmdEaXNrRW50cmllcy5tYXAoeCA9PiBwYXJzZUludCh4KSkpICsgMTtcblxuICAgICAgICBsZXQgYnVmZmVyczogQnVmZmVyW10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLmNhY2hlLnZhbHVlcygpKSB7XG4gICAgICAgICAgICBsZXQgYnVmZmVyID0gdGhpcy5zZXJpYWxpemVUcmFuc2FjdGlvbkVudHJ5KGVudHJ5KTtcbiAgICAgICAgICAgIGJ1ZmZlcnMucHVzaChidWZmZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG5ld0NodW5rcyA9IHRoaXMuY2h1bmtCdWZmZXJzKGJ1ZmZlcnMpO1xuXG4gICAgICAgIGxldCBjdXJDaHVuayA9IG5leHRTdGFydDtcbiAgICAgICAgZm9yIChsZXQgY2h1bmsgb2YgbmV3Q2h1bmtzKSB7XG4gICAgICAgICAgICBsZXQgZmlsZSA9IHRoaXMuZ2V0Q2h1bmsoY3VyQ2h1bmsrKyk7XG4gICAgICAgICAgICBsZXQgY29udGVudCA9IGNodW5rLmJ1ZmZlcjtcbiAgICAgICAgICAgIGxldCB7IGhlYWRlciwgaGVhZGVyQnVmZmVyIH0gPSB0aGlzLmdldEhlYWRlcihcbiAgICAgICAgICAgICAgICAvLyBBTkQsIG5ldmVyIGNvbXByZXNzIHRoZSBsYXN0IG9uZSwgb3RoZXJ3aXNlIHdlIGNhbid0IGFwcGVuZCB0byBpdCFcbiAgICAgICAgICAgICAgICBjb250ZW50Lmxlbmd0aCA+PSBGSUxFX1pJUF9USFJFU0hPTEQgJiYgY2h1bmsgIT09IG5ld0NodW5rc1tuZXdDaHVua3MubGVuZ3RoIC0gMV1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoaGVhZGVyLnppcHBlZCkge1xuICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBhd2FpdCBaaXAuZ3ppcChjb250ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBidWZmZXIgPSBCdWZmZXIuY29uY2F0KFtoZWFkZXJCdWZmZXIsIGNvbnRlbnRdKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmF3U3RvcmFnZS5zZXQoZmlsZSwgYnVmZmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoaXMgaXMgdGhlIE9OTFkgdGltZSB3ZSBjYW4gZGVsZXRlIG9sZCBmaWxlcywgYXMgd2Uga25vdyBmb3Igc3VyZSB0aGUgbmV3IGZpbGUgaGFzIGFsbCBvZiBvdXIgZGF0YS5cbiAgICAgICAgLy8gIEFueSBmdXR1cmUgcmVhZGVycyB3b24ndCBrbm93IHRoaXMsIHVubGVzcyB0aGV5IHdyaXRlIGl0IHRoZW1zZWx2ZXMgKG9yIHVubGVzcyB0aGV5IGF1ZGl0IGl0IGFnYWluc3RcbiAgICAgICAgLy8gICAgICB0aGUgb3RoZXIgZ2VuZXJhdGlvbnMsIHdoaWNoIGlzIGFubm95aW5nKS5cbiAgICAgICAgZm9yIChjb25zdCBmaWxlIG9mIGV4aXN0aW5nRGlza0VudHJpZXMpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmF3U3RvcmFnZS5yZW1vdmUoZmlsZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmN1cnJlbnRDaHVuayA9IGN1ckNodW5rO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyByZXNldCgpIHtcbiAgICAgICAgYXdhaXQgZmlsZUxvY2tTZWN0aW9uKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGxldCBleGlzdGluZ0Rpc2tFbnRyaWVzID0gYXdhaXQgdGhpcy5yYXdTdG9yYWdlLmdldEtleXMoKTtcbiAgICAgICAgICAgIGV4aXN0aW5nRGlza0VudHJpZXMgPSBleGlzdGluZ0Rpc2tFbnRyaWVzLmZpbHRlcih4ID0+IHguZW5kc1dpdGgoQ0hVTktfRVhUKSk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKGV4aXN0aW5nRGlza0VudHJpZXMubWFwKHggPT4gdGhpcy5yYXdTdG9yYWdlLnJlbW92ZSh4KSkpO1xuICAgICAgICAgICAgfSBjYXRjaCB7IH1cblxuICAgICAgICAgICAgdGhpcy5wZW5kaW5nQXBwZW5kcyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5jYWNoZS5jbGVhcigpO1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50Q2h1bmsgPSAwO1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50Q2h1bmtTaXplID0gMDtcbiAgICAgICAgICAgIHRoaXMuZW50cnlDb3VudCA9IDA7XG4gICAgICAgIH0pO1xuICAgIH1cbn0iXX0=
421
- /* _JS_SOURCE_HASH = "d6b565522e0199b1511007a3ea7bb1eef1a46c338996c583da6090466f49bf59"; */
559
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNhY3Rpb25TdG9yYWdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiVHJhbnNhY3Rpb25TdG9yYWdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1EQUEwRztBQUUxRyxxQ0FBa0M7QUFDbEMsMkRBQWtFO0FBQ2xFLGtFQUFpRjtBQUNqRixxREFBOEM7QUFDOUMscURBQWdEO0FBRWhELDJEQUErRDtBQUUvRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VBOEJFO0FBRUYsTUFBTSxtQkFBbUIsR0FBRyxtQkFBWSxHQUFHLENBQUMsQ0FBQztBQUU3QyxNQUFNLGVBQWUsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ3BDLE1BQU0saUJBQWlCLEdBQUcsbUJBQVksR0FBRyxFQUFFLENBQUM7QUFFNUMsTUFBTSxrQkFBa0IsR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUU1QyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdkUsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3RFLDZEQUE2RDtBQUM3RCxNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUM7QUFjeEIsTUFBTSxlQUFlLEdBQUcsSUFBQSxzQkFBVyxFQUFDLEtBQUssRUFBRSxHQUF3QixFQUFFLEVBQUU7SUFDbkUsTUFBTSxHQUFHLEVBQUUsQ0FBQztBQUNoQixDQUFDLENBQUMsQ0FBQztBQUVILE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQztBQUMzQixNQUFN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QUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0RixDQUFDO1lBQUMsV0FBTSxDQUFDLENBQUMsQ0FBQztZQUVYLElBQUksQ0FBQyxjQUFjLEdBQUcsRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsWUFBWSxHQUFHLFNBQVMsQ0FBQztZQUM5QixJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztRQUN4QixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7O0FBcmlCTCxnREFzaUJDO0FBM2hCa0IsNkJBQVUsR0FBeUIsRUFBRSxBQUEzQixDQUE0QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFByb21pc2VPYmosIGNvbXBhcmVBcnJheSwgc29ydCwgdGhyb3R0bGVGdW5jdGlvbiwgdGltZUluTWludXRlIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvbWlzY1wiO1xuaW1wb3J0IHsgSVN0b3JhZ2UsIElTdG9yYWdlUmF3IH0gZnJvbSBcIi4vSVN0b3JhZ2VcIjtcbmltcG9ydCB7IFppcCB9IGZyb20gXCIuLi9taXNjL3ppcFwiO1xuaW1wb3J0IHsgZGVsYXksIHJ1bkluU2VyaWFsIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvYmF0Y2hpbmdcIjtcbmltcG9ydCB7IGZvcm1hdE51bWJlciwgZm9ybWF0VGltZSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2Zvcm1hdHRpbmcvZm9ybWF0XCI7XG5pbXBvcnQgeyBzZXRQZW5kaW5nIH0gZnJvbSBcIi4vUGVuZGluZ01hbmFnZXJcIjtcbmltcG9ydCB7IGlzSW5CdWlsZCB9IGZyb20gXCIuLi9taXNjL2Vudmlyb25tZW50XCI7XG5pbXBvcnQgeyBpc05vZGUgfSBmcm9tIFwidHlwZXNhZmVjc3NcIjtcbmltcG9ydCB7IHJ1bkluZmluaXRlUG9sbCB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2JhdGNoaW5nXCI7XG5cbi8qXG4vLyBTcGVjOlxuLy8gICAgICAtIFppcCBpbmRpdmlkdWFsIGxhcmdlIHZhbHVlc1xuLy8gICAgICAtIFN0b3JlcyBhIHRyYW5zYWN0aW9uIGxvZ1xuLy8gICAgICAgICAgLSBUcmFuc2FjdGlvbiBsb2cgaGFzIGEgaGVhZGVyLCB3aGljaCBpcyBKU09OLCBmb3IgdGhpbmdzIHN1Y2ggYXMgXCJ6aXBwZWRcIlxuLy8gICAgICAgICAgLSBUcmFuc2FjdGlvbiBsb2cgdXNlcyBsZW5ndGggcHJlZml4ZWQgdmFsdWVzLCB3aXRoIGEgc3BlY2lhbCA4IGJ5dGVzIHRvIGRlbm90ZSB0aGUgZW5kLFxuLy8gICAgICAgICAgICAgIGFuZCA4IGZvciB0aGUgc3RhcnQuXG4vLyAgICAgICAgICAtIFdoZW4gdHJhbnNhY3Rpb24gbG9nIGlzIGl0ZXJhdGVkIG9uLCBpZiB0aGUgYnl0ZXMgYXQgdGhlIGVuZCAodXNpbmcgdGhlIGxlbmd0aCBwcmVmaXgpXG4vLyAgICAgICAgICAgICAgZG9uJ3QgbWF0Y2ggdGhlIGVuZCBieXRlcyBPUiB0aGUgc3RhcnQgYnl0ZXMgYXJlIHdyb25nLCB3ZSBza2lwIHRoZSBzdGFydCBieXRlcyxcbi8vICAgICAgICAgICAgICBhbmQgaXRlcmF0aW5nIHVudGlsIHdlIGZpbmQgbmV3IHN0YXJ0IGJ5dGVzIHRoYXQgbWF0Y2ggb3VyIHNwZWNpYWwgYnl0ZXMuIFRoZW4gd2UgdHJ5XG4vLyAgICAgICAgICAgICAgdG8gcmVhZCB0aGVzZSB2YWx1ZXMuXG4vLyAgICAgICAgICAtIEVhY2ggdHJhbnNhY3Rpb24gZW50cnkgaGFzIGEgYnl0ZSBmb3IgZmxhZ3MsIG9uZSBiaXQgd2hpY2ggZGVub3RlcyBpZiB0aGUgdmFsdWUgaXMgemlwcGVkIG9yIG5vdC5cbi8vICAgICAgLSBDb21wcmVzc2VzIHRoZSBsb2cgYWZ0ZXIgdGhlcmUgYXJlIDNYIGVudHJpZXMgdGhhbiBrZXlzIChhbmQgPiAxMDApXG4vLyAgICAgICAgICAtIEJvdGggZGVkdXBlIGtleXMsIGFuZCB6aXBcbi8vICAgICAgLSBBc3N1bWVzIGFsbCBmaWxlcyBpbiByYXdTdG9yYWdlIGVuZGluZyB3aXRoIC50eCBhcmUgdHJhbnNhY3Rpb24gbG9nc1xuLy8gICAgICAtIE5hbWVzIGZpbGVzIGxpa2UgYCR7Z2VuZXJhdGlvbn0udHhgXG4vLyAgICAgICAgICAtIFdoZW4gY29tcHJlc3NpbmcsIHdlIGluY3JlbWVudCB0aGUgZ2VuZXJhdGlvbiwgYW5kIHdyaXRlIHRvIGEgbmV3IGZpbGUsIGFuZCBkZWxldGVcbi8vICAgICAgICAgICAgICBhbnkgZ2VuZXJhdGlvbnMgdGhhdCBhcmUgb2xkZXIgdGhhbiB0aGUgbmV3IG9uZVxuLy8gICAgICAgICAgLSBPbiByZWFkaW5nLCB3ZSByZWFkIGZyb20gYWxsIGdlbmVyYXRpb24gZmlsZXMgdGhhdCBleGlzdCwgaW4gY2FzZSBzb21lIGFyZSBjb3JydXB0ZWRcbi8vICAgICAgLSBPbiBsb2FkLCBsb2FkcyBpbiBhbGwgdHJhbnNhY3Rpb24gbG9ncywgYW5kIHN0b3JlcyBhbGwgdmFsdWVzIGluIGEgTWFwPHN0cmluZywgQnVmZmVyPlxuLy8gICAgICAtIE9uIHdyaXRlcyBpbW1lZGlhdGVseSB1cGRhdGVzIHRoZSBpbiBtZW1vcnkgTWFwLCBhbmQgdGhlbiB3cml0ZXMgdG8gdGhlIHRyYW5zYWN0aW9uIGxvZ1xuLy8gICAgICAtIENhY2hlcyB0aGUgbGFzdCB0cmFuc2FjdGlvbiBmaWxlIG5hbWUgaW4gbWVtb3J5XG4vLyAgICAgIC0gTWFrZXMgc3VyZSBhbGwgZmlsZSBzeXN0ZW0gd3JpdGVzIChidXQgbm90IE1hcCB1cGRhdGVzKSBhcmUgZG9uZSB3aXRoIGZpbGVMb2NrU2VjdGlvbixcbi8vICAgICAgICAgIHNvIHRoZXkgbmV2ZXIgb3ZlcmxhcC5cbi8vICAgICAgLSBCdWZmZXJzIHBlbmRpbmcgYXBwZW5kcyBpbiBtZW1vcnksIHNvIHRoZXkgY2FuIHdyaXR0ZW4gYWxsIGF0IG9uY2UgKGFmdGVyIHRoZSBmaXJzdCBvbmVcbi8vICAgICAgICAgIGlzIGJsb2NraW5nIGluIGZpbGVMb2NrU2VjdGlvbikuXG5cblVQREFURSBub3cgd2UgdXNlIGNodW5rcywgYmVjYXVzZSBhcHBlbmQgaXMgdG9vIHNsb3cuXG5cbklNUE9SVEFOVCEgSWYgdGhlcmUgYXJlIG11bHRpcGxlIHdyaXRlcnMsIHdlIGNsb2JiZXIgd3JpdGVzIGZyb20gb3RoZXIgd3JpdGVycyB3aGVuIHdlIGNvbXByZXNzXG4qL1xuXG5jb25zdCBESVNLX0NIRUNLX0lOVEVSVkFMID0gdGltZUluTWludXRlICogNTtcblxuY29uc3QgRklMRV9DSFVOS19TSVpFID0gMTAyNCAqIDEwMjQ7XG5jb25zdCBGSUxFX01BWF9MSUZFVElNRSA9IHRpbWVJbk1pbnV0ZSAqIDMwO1xuXG5jb25zdCBGSUxFX1pJUF9USFJFU0hPTEQgPSAxNiAqIDEwMjQgKiAxMDI0O1xuXG5jb25zdCBTVEFSVF9CWVRFUyA9IEJ1ZmZlci5mcm9tKFsyMzYsIDQ5LCAxMTIsIDEyMSwgMjcsIDEyNywgMjI3LCA2M10pO1xuY29uc3QgRU5EX0JZVEVTID0gQnVmZmVyLmZyb20oWzIyMCwgMTExLCAyNDMsIDIwMiwgMjAwLCA3OSwgMjEzLCA2M10pO1xuLy8gRGVsYXkgd3JpdGVzLCBzbyB3ZSBiYXRjaCBiZXR0ZXIsIGFuZCB0aHJhc2ggdGhlIGRpc2sgbGVzc1xuY29uc3QgV1JJVEVfREVMQVkgPSA1MDA7XG5cbmludGVyZmFjZSBUcmFuc2FjdGlvbkVudHJ5IHtcbiAgICBrZXk6IHN0cmluZztcbiAgICB2YWx1ZTogQnVmZmVyIHwgdW5kZWZpbmVkO1xuICAgIC8vIE5PVEU6IFdlIGRpc2FibGVkIHBlci1lbnRyeSB6aXBwaW5nLiBFaXRoZXIgdXNlIGEgcmF3IGNvbGxlY3Rpb24gc28geW91IGRvbid0IGhhdmUgdG8gbG9hZCBhbGwgb2YgdGhlbSBpbnRvIG1lbW9yeSBvciBzaGFyZCB5b3VyIGNvbGxlY3Rpb24uIFppcHBpbmcgaXMgb25seSBhIGJhbmQtYWlkIHNvbHV0aW9uIGZvciBtZW1vcnkgaXNzdWVzLiBBTFNPLCBpdCBtYWtlcyBsb2FkaW5nIHNsb3dlciwgd2hpY2ggbWFrZXMgYWxsIG90aGVyIGFwcGxpY2F0aW9ucyB0aGF0IGRvbid0IG5lZWQgemlwcGluZyB3b3JzZS5cbiAgICBpc1ppcHBlZDogYm9vbGVhbjtcbiAgICB0aW1lOiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBUcmFuc2FjdGlvbkhlYWRlciB7XG4gICAgemlwcGVkOiBib29sZWFuO1xufVxuXG5jb25zdCBmaWxlTG9ja1NlY3Rpb24gPSBydW5JblNlcmlhbChhc3luYyAoZm5jOiAoKSA9PiBQcm9taXNlPHZvaWQ+KSA9PiB7XG4gICAgYXdhaXQgZm5jKCk7XG59KTtcblxuY29uc3QgQ0hVTktfRVhUID0gXCIuY2h1bmtcIjtcbmNvbnN0IG91cklkID0gRGF0ZS5ub3coKSArIE1hdGgucmFuZG9tKCk7XG5sZXQgc2VxTnVtID0gMDtcblxuZnVuY3Rpb24gZ2V0TmV4dENodW5rUGF0aCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHtEYXRlLm5vdygpfV8ke3NlcU51bSsrfV8ke291cklkfS5jaHVua2A7XG59XG5cbmV4cG9ydCBjbGFzcyBUcmFuc2FjdGlvblN0b3JhZ2UgaW1wbGVtZW50cyBJU3RvcmFnZTxCdWZmZXI+IHtcbiAgICBwdWJsaWMgY2FjaGU6IE1hcDxzdHJpbmcsIFRyYW5zYWN0aW9uRW50cnk+ID0gbmV3IE1hcCgpO1xuICAgIC8vIE1hcHMgZmlsZSBuYW1lIHRvIG91ciBsYXN0IGtub3duIHdyaXRlIHRpbWVzdGFtcFxuICAgIHByaXZhdGUgZGlza0ZpbGVzOiBNYXA8c3RyaW5nLCBudW1iZXI+ID0gbmV3IE1hcCgpO1xuICAgIHByaXZhdGUgY3VycmVudENodW5rOiB7XG4gICAgICAgIHBhdGg6IHN0cmluZztcbiAgICAgICAgc2l6ZTogbnVtYmVyO1xuICAgICAgICB0aW1lQ3JlYXRlZDogbnVtYmVyO1xuICAgIH0gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgcHJpdmF0ZSBlbnRyeUNvdW50ID0gMDtcblxuICAgIHByaXZhdGUgc3RhdGljIGFsbFN0b3JhZ2U6IFRyYW5zYWN0aW9uU3RvcmFnZVtdID0gW107XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSByYXdTdG9yYWdlOiBJU3RvcmFnZVJhdyxcbiAgICAgICAgcHJpdmF0ZSBkZWJ1Z05hbWU6IHN0cmluZyxcbiAgICAgICAgcHJpdmF0ZSB3cml0ZURlbGF5ID0gV1JJVEVfREVMQVksXG4gICAgICAgIC8vIFdoZW4gc2V0LCB3ZSBwb2xsIHRoZSB1bmRlcmx5aW5nIHN0b3JhZ2UgYW5kIHJlbG9hZCBpZiBhbm90aGVyIHByb2Nlc3MvdGFiIHdyaXRlcyBuZXdcbiAgICAgICAgLy8gY2h1bmsgZmlsZXMuIE9mZiBieSBkZWZhdWx0LCBhcyBpdCBjb3N0cyBhIHBlcmlvZGljIGRpc2sgc2NhbiBhbmQgbW9zdCBjb2xsZWN0aW9ucyBhcmVcbiAgICAgICAgLy8gb25seSB3cml0dGVuIGJ5IGEgc2luZ2xlIHByb2Nlc3MuXG4gICAgICAgIHByaXZhdGUgcmVzeW5jRnJvbURpc2sgPSBmYWxzZVxuICAgICkge1xuICAgICAgICBUcmFuc2FjdGlvblN0b3JhZ2UuYWxsU3RvcmFnZS5wdXNoKHRoaXMpO1xuICAgICAgICAvLyBWRVJZIHVzZWZ1bCBmb3IgZGVidWdnaW5nLlxuICAgICAgICAoZ2xvYmFsVGhpcyBhcyBhbnkpW2B0eCR7dGhpcy5kZWJ1Z05hbWV9YF0gPSB0aGlzO1xuICAgIH1cbiAgICAvLyBIZWxwcyBnZXQgcmlkIG9mIHBhcnNlIGVycm9ycyB3aGljaCBjb25zdGFudGx5IGxvZy4gQWxzbywgdXNlcyBsZXNzIHNwYWNlXG4gICAgcHVibGljIHN0YXRpYyBhc3luYyBjb21wcmVzc0FsbCgpIHtcbiAgICAgICAgYXdhaXQgZmlsZUxvY2tTZWN0aW9uKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGZvciAobGV0IHN0b3JhZ2Ugb2YgVHJhbnNhY3Rpb25TdG9yYWdlLmFsbFN0b3JhZ2UpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBzdG9yYWdlLmNvbXByZXNzVHJhbnNhY3Rpb25Mb2codHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVzeW5jQ2FsbGJhY2tzOiAoKCkgPT4gdm9pZClbXSA9IFtdO1xuICAgIHB1YmxpYyB3YXRjaFJlc3luYyhjYWxsYmFjazogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgICAgICB0aGlzLnJlc3luY0NhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXQ6IFByb21pc2U8dW5rbm93bj4gfCB1bmRlZmluZWQgPSB0aGlzLmxvYWRBbGxUcmFuc2FjdGlvbnModHJ1ZSk7XG5cbiAgICBwcml2YXRlIGdldEN1cnJlbnRDaHVuaygpOiBzdHJpbmcge1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50Q2h1bmsgJiYgdGhpcy5jdXJyZW50Q2h1bmsudGltZUNyZWF0ZWQgPCBEYXRlLm5vdygpIC0gRklMRV9NQVhfTElGRVRJTUUpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudENodW5rID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5jdXJyZW50Q2h1bmspIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudENodW5rID0ge1xuICAgICAgICAgICAgICAgIHBhdGg6IGdldE5leHRDaHVua1BhdGgoKSxcbiAgICAgICAgICAgICAgICBzaXplOiAwLFxuICAgICAgICAgICAgICAgIHRpbWVDcmVhdGVkOiBEYXRlLm5vdygpXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gVGltZXN0YW1wIHdpbGwgYmUgdXBkYXRlZCBhZnRlciBhY3R1YWwgd3JpdGVcbiAgICAgICAgICAgIHRoaXMuZGlza0ZpbGVzLnNldCh0aGlzLmN1cnJlbnRDaHVuay5wYXRoLCAwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50Q2h1bmsucGF0aDtcbiAgICB9XG4gICAgcHJpdmF0ZSB1cGRhdGVEaXNrRmlsZVRpbWVzdGFtcChmaWxlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kaXNrRmlsZXMuc2V0KGZpbGUsIERhdGUubm93KCkpO1xuICAgIH1cbiAgICBwcml2YXRlIG9uQWRkVG9DaHVuayhzaXplOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmN1cnJlbnRDaHVuaykgcmV0dXJuO1xuICAgICAgICB0aGlzLmN1cnJlbnRDaHVuay5zaXplICs9IHNpemU7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRDaHVuay5zaXplID49IEZJTEVfQ0hVTktfU0laRSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50Q2h1bmsgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0KGtleTogc3RyaW5nKTogUHJvbWlzZTxCdWZmZXIgfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5pbml0O1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuY2FjaGUuZ2V0KGtleSk7XG4gICAgICAgIGlmICh2YWx1ZSAmJiB2YWx1ZS5pc1ppcHBlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUcmFuc2FjdGlvbnMgc2hvdWxkIGJlIHVuemlwcGVkIG9uIGZpbGUgcmVhZHksIHNvIHRoaXMgc3RhdGUgc2hvdWxkIGJlIGltcG9zc2libGUuIEtleTogJHtrZXl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlPy52YWx1ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgc2V0KGtleTogc3RyaW5nLCB2YWx1ZTogQnVmZmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLmluaXQpIGF3YWl0IHRoaXMuaW5pdDtcblxuICAgICAgICAvLyBUaW1lIGlzIHNldCBvbiBkaXNrIHdyaXRlLCBhcyBEYXRlLm5vdygpIGlzIHRvbyBzbG93XG4gICAgICAgIGxldCBlbnRyeTogVHJhbnNhY3Rpb25FbnRyeSA9IHsga2V5LCB2YWx1ZSwgaXNaaXBwZWQ6IGZhbHNlLCB0aW1lOiAwIH07XG4gICAgICAgIHRoaXMuY2FjaGUuc2V0KGtleSwgZW50cnkpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMucHVzaEFwcGVuZChlbnRyeSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHJlbW92ZShrZXk6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAodGhpcy5pbml0KSBhd2FpdCB0aGlzLmluaXQ7XG4gICAgICAgIHRoaXMuY2FjaGUuZGVsZXRlKGtleSk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5wdXNoQXBwZW5kKHsga2V5LCB2YWx1ZTogdW5kZWZpbmVkLCBpc1ppcHBlZDogZmFsc2UsIHRpbWU6IDAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGdldEluZm8oa2V5OiBzdHJpbmcpOiBQcm9taXNlPHsgc2l6ZTogbnVtYmVyOyBsYXN0TW9kaWZpZWQ6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdDtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmNhY2hlLmdldChrZXkpO1xuICAgICAgICBpZiAoIXZhbHVlPy52YWx1ZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHsgc2l6ZTogdmFsdWUudmFsdWUubGVuZ3RoLCBsYXN0TW9kaWZpZWQ6IHZhbHVlLnRpbWUgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHBlbmRpbmdBcHBlbmRzOiBUcmFuc2FjdGlvbkVudHJ5W10gPSBbXTtcbiAgICBwcml2YXRlIGV4dHJhQXBwZW5kcyA9IDA7XG4gICAgcHJpdmF0ZSBwZW5kaW5nV3JpdGU6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQ7XG4gICAgYXN5bmMgcHVzaEFwcGVuZChlbnRyeTogVHJhbnNhY3Rpb25FbnRyeSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmVudHJ5Q291bnQrKztcbiAgICAgICAgdGhpcy5wZW5kaW5nQXBwZW5kcy5wdXNoKGVudHJ5KTtcbiAgICAgICAgdm9pZCB0aGlzLnVwZGF0ZVBlbmRpbmdBcHBlbmRzKCk7XG4gICAgICAgIGlmICh0aGlzLnBlbmRpbmdXcml0ZSkgcmV0dXJuIHRoaXMucGVuZGluZ1dyaXRlO1xuICAgICAgICB0aGlzLnBlbmRpbmdXcml0ZSA9IGZpbGVMb2NrU2VjdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAvLyBEZWxheSB0byBhbGxvdyBiYXRjaGluZywgYW5kIGRlZHVwaW5nXG4gICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgdGhpcy53cml0ZURlbGF5KSk7XG4gICAgICAgICAgICBsZXQgY3VyQXBwZW5kcyA9IHRoaXMucGVuZGluZ0FwcGVuZHM7XG4gICAgICAgICAgICB0aGlzLnBlbmRpbmdBcHBlbmRzID0gW107XG4gICAgICAgICAgICB0aGlzLnBlbmRpbmdXcml0ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsZXQgYXBwZW5kc0RlZHVwZWQ6IE1hcDxzdHJpbmcsIFRyYW5zYWN0aW9uRW50cnk+ID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgY3VyQXBwZW5kcykge1xuICAgICAgICAgICAgICAgICAgICBhcHBlbmRzRGVkdXBlZC5zZXQoZW50cnkua2V5LCBlbnRyeSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGN1ckFwcGVuZHMgPSBBcnJheS5mcm9tKGFwcGVuZHNEZWR1cGVkLnZhbHVlcygpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZXh0cmFBcHBlbmRzICs9IGN1ckFwcGVuZHMubGVuZ3RoO1xuICAgICAgICAgICAgdm9pZCB0aGlzLnVwZGF0ZVBlbmRpbmdBcHBlbmRzKCk7XG4gICAgICAgICAgICBpZiAoY3VyQXBwZW5kcy5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICAgICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgICAgICBsZXQgdGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgZW50cnkgb2YgY3VyQXBwZW5kcykge1xuICAgICAgICAgICAgICAgICAgICBlbnRyeS50aW1lID0gdGltZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgbmV3U3VtID0gMDtcbiAgICAgICAgICAgICAgICBsZXQgYnVmZmVyczogQnVmZmVyW10gPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGN1ckFwcGVuZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGJ1ZmZlciA9IHRoaXMuc2VyaWFsaXplVHJhbnNhY3Rpb25FbnRyeShlbnRyeSk7XG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlcnMucHVzaChidWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICBuZXdTdW0gKz0gYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgbmV3Q2h1bmtzID0gdGhpcy5jaHVua0J1ZmZlcnMoYnVmZmVycyk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgY2h1bmsgb2YgbmV3Q2h1bmtzKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBmaWxlID0gdGhpcy5nZXRDdXJyZW50Q2h1bmsoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFhd2FpdCB0aGlzLnJhd1N0b3JhZ2UuZ2V0KGZpbGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgeyBoZWFkZXIsIGhlYWRlckJ1ZmZlciB9ID0gdGhpcy5nZXRIZWFkZXIoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5yYXdTdG9yYWdlLnNldChmaWxlLCBoZWFkZXJCdWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGxldCBjb250ZW50ID0gY2h1bmsuYnVmZmVyO1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJhd1N0b3JhZ2UuYXBwZW5kKGZpbGUsIGNvbnRlbnQpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZURpc2tGaWxlVGltZXN0YW1wKGZpbGUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uQWRkVG9DaHVuayhjb250ZW50Lmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5jb21wcmVzc1RyYW5zYWN0aW9uTG9nKCk7XG4gICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHRoaXMuZXh0cmFBcHBlbmRzIC09IGN1ckFwcGVuZHMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIHZvaWQgdGhpcy51cGRhdGVQZW5kaW5nQXBwZW5kcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy5wZW5kaW5nV3JpdGU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1cGRhdGVQZW5kaW5nQXBwZW5kcyA9IHRocm90dGxlRnVuY3Rpb24oMTAwLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGxldCBhcHBlbmRDb3VudCA9IHRoaXMucGVuZGluZ0FwcGVuZHMubGVuZ3RoICsgdGhpcy5leHRyYUFwcGVuZHM7XG4gICAgICAgIGxldCBncm91cCA9IGBUcmFuc2FjdGlvbiAoJHt0aGlzLmRlYnVnTmFtZX0pYDtcbiAgICAgICAgLy9jb25zb2xlLmxvZyhgVXBkYXRlIHBlbmRpbmcgYXBwZW5kcyAke2dyb3VwfTogJHthcHBlbmRDb3VudH1gKTtcbiAgICAgICAgaWYgKCFhcHBlbmRDb3VudCkge1xuICAgICAgICAgICAgc2V0UGVuZGluZyhncm91cCwgXCJcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc2V0UGVuZGluZyhncm91cCwgYFBlbmRpbmcgYXBwZW5kczogJHthcHBlbmRDb3VudH1gKTtcbiAgICB9KTtcblxuICAgIHB1YmxpYyBhc3luYyBnZXRLZXlzKCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAgICAgaWYgKHRoaXMuaW5pdCkgYXdhaXQgdGhpcy5pbml0O1xuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmNhY2hlLmtleXMoKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGNoZWNrRGlzaygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKHRoaXMuaW5pdCkgYXdhaXQgdGhpcy5pbml0O1xuICAgICAgICBjb25zdCBhbnlDaGFuZ2VzID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgbGV0IGtleXMgPSBhd2FpdCB0aGlzLnJhd1N0b3JhZ2UuZ2V0S2V5cygpO1xuICAgICAgICAgICAgbGV0IGRpc2tGaWxlcyA9IGtleXMuZmlsdGVyKGtleSA9PiBrZXkuZW5kc1dpdGgoQ0hVTktfRVhUKSk7XG4gICAgICAgICAgICAvLyBDaGVjayBpZiBhbnkga25vd24gZmlsZXMgaGF2ZSBiZWVuIG1vZGlmaWVkIGV4dGVybmFsbHkgKGRpc2sgdGltZXN0YW1wIG5ld2VyIHRoYW4gb3VycylcbiAgICAgICAgICAgIGZvciAobGV0IGZpbGUgb2YgZGlza0ZpbGVzKSB7XG4gICAgICAgICAgICAgICAgbGV0IG91clRpbWVzdGFtcCA9IHRoaXMuZGlza0ZpbGVzLmdldChmaWxlKTtcbiAgICAgICAgICAgICAgICBpZiAob3VyVGltZXN0YW1wID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBpbmZvID0gYXdhaXQgdGhpcy5yYXdTdG9yYWdlLmdldEluZm8oZmlsZSk7XG4gICAgICAgICAgICAgICAgaWYgKGluZm8gJiYgaW5mby5sYXN0TW9kaWZpZWQgPiBvdXJUaW1lc3RhbXApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICBpZiAoIWF3YWl0IGFueUNoYW5nZXMoKSkgcmV0dXJuO1xuXG4gICAgICAgIGF3YWl0IGZpbGVMb2NrU2VjdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIWF3YWl0IGFueUNoYW5nZXMoKSkgcmV0dXJuO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYEZvdW5kIG5ldyBjaGFuZ2VzIGluIGNvbGxlY3Rpb24gZnJvbSBvdGhlciB0YWIuIExvYWRpbmcgdGhlbSBub3cuICR7dGhpcy5kZWJ1Z05hbWV9YCk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmxvYWRBbGxUcmFuc2FjdGlvbnMoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICAvLyBOT1RFOiBUaGlzIGlzIGVpdGhlciBjYWxsZWQgaW4gaW5pdCAod2hpY2ggYmxvY2tzIGFsbCBvdGhlciBjYWxscyksIG9yIGluc2lkZSBvZiB0aGUgZ2xvYmFsIGZpbGUgbG9jaywgc28gaXQgaXMgc2FmZSB0byBsb2FkLlxuICAgIHByaXZhdGUgYXN5bmMgbG9hZEFsbFRyYW5zYWN0aW9ucyhpbml0aWFsTG9hZD86IGJvb2xlYW4pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgICAgIGlmIChpc0luQnVpbGQoKSkgcmV0dXJuIFtdO1xuXG4gICAgICAgIGlmIChpbml0aWFsTG9hZCAmJiB0aGlzLnJlc3luY0Zyb21EaXNrKSB7XG4gICAgICAgICAgICBydW5JbmZpbml0ZVBvbGwoRElTS19DSEVDS19JTlRFUlZBTCwgKCkgPT4gdGhpcy5jaGVja0Rpc2soKSk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdGltZSA9IERhdGUubm93KCk7XG4gICAgICAgIGNvbnN0IGtleXMgPSBhd2FpdCB0aGlzLnJhd1N0b3JhZ2UuZ2V0S2V5cygpO1xuICAgICAgICBjb25zdCB0cmFuc2FjdGlvbkZpbGVzID0ga2V5cy5maWx0ZXIoa2V5ID0+IGtleS5lbmRzV2l0aChDSFVOS19FWFQpKTtcbiAgICAgICAgLy8gUG9wdWxhdGUgZGlza0ZpbGVzIHdpdGggYWN0dWFsIHRpbWVzdGFtcHMgZnJvbSBkaXNrXG4gICAgICAgIHRoaXMuZGlza0ZpbGVzID0gbmV3IE1hcCgpO1xuICAgICAgICBmb3IgKGxldCBmaWxlIG9mIHRyYW5zYWN0aW9uRmlsZXMpIHtcbiAgICAgICAgICAgIGxldCBpbmZvID0gYXdhaXQgdGhpcy5yYXdTdG9yYWdlLmdldEluZm8oZmlsZSk7XG4gICAgICAgICAgICB0aGlzLmRpc2tGaWxlcy5zZXQoZmlsZSwgaW5mbz8ubGFzdE1vZGlmaWVkID8/IERhdGUubm93KCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHNpemUgPSB7IHZhbHVlOiAwIH07XG4gICAgICAgIGxldCBlbnRyeUxpc3Q6IFRyYW5zYWN0aW9uRW50cnlbXVtdID0gW107XG4gICAgICAgIGZvciAobGV0IGZpbGUgb2YgdHJhbnNhY3Rpb25GaWxlcykge1xuICAgICAgICAgICAgZW50cnlMaXN0LnB1c2goYXdhaXQgdGhpcy5wYXJzZVRyYW5zYWN0aW9uRmlsZShmaWxlLCBzaXplKSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGVudHJpZXMgPSBlbnRyeUxpc3QuZmxhdCgpO1xuICAgICAgICB0aGlzLmFwcGx5VHJhbnNhY3Rpb25FbnRyaWVzKGVudHJpZXMsIGluaXRpYWxMb2FkKTtcblxuICAgICAgICB0aW1lID0gRGF0ZS5ub3coKSAtIHRpbWU7XG4gICAgICAgIGlmICh0aW1lID4gNTApIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBMb2FkZWQgJHt0aGlzLmRlYnVnTmFtZX0gaW4gJHtmb3JtYXRUaW1lKHRpbWUpfSwgJHtmb3JtYXROdW1iZXIodGhpcy5jYWNoZS5zaXplKX0ga2V5cywgZnJvbSAke2Zvcm1hdE51bWJlcih0cmFuc2FjdGlvbkZpbGVzLmxlbmd0aCl9IGZpbGVzLCBlbnRyaWVzICR7Zm9ybWF0TnVtYmVyKGVudHJpZXMubGVuZ3RoKX0sIHRvdGFsIHNpemUgJHtmb3JtYXROdW1iZXIoc2l6ZS52YWx1ZSl9QmAsIHRyYW5zYWN0aW9uRmlsZXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pbml0ID0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gdHJhbnNhY3Rpb25GaWxlcztcbiAgICB9XG5cbiAgICAvLyBPTkxZIGNhbGwgdGhpcyBpbnNpZGUgb2YgbG9hZEFsbFRyYW5zYWN0aW9uc1xuICAgIHByaXZhdGUgYXN5bmMgcGFyc2VUcmFuc2FjdGlvbkZpbGUoZmlsZW5hbWU6IHN0cmluZywgc2l6ZTogeyB2YWx1ZTogbnVtYmVyIH0pOiBQcm9taXNlPFRyYW5zYWN0aW9uRW50cnlbXT4ge1xuICAgICAgICBjb25zdCBmdWxsRmlsZSA9IGF3YWl0IHRoaXMucmF3U3RvcmFnZS5nZXQoZmlsZW5hbWUpO1xuICAgICAgICBpZiAoIWZ1bGxGaWxlKSByZXR1cm4gW107XG4gICAgICAgIGlmIChmdWxsRmlsZS5sZW5ndGggPCA0KSB7XG4gICAgICAgICAgICAvL2NvbnNvbGUuZXJyb3IoYFRyYW5zYWN0aW9uIGluICR7dGhpcy5kZWJ1Z05hbWV9IGZpbGUgJHtmaWxlbmFtZX0gaXMgdG9vIHNtYWxsLCBza2lwcGluZ2ApO1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIHNpemUudmFsdWUgKz0gZnVsbEZpbGUubGVuZ3RoO1xuICAgICAgICBsZXQgaGVhZGVyU2l6ZSA9IGZ1bGxGaWxlLnJlYWRVSW50MzJMRSgwKTtcbiAgICAgICAgbGV0IGhlYWRlckJ1ZmZlciA9IGZ1bGxGaWxlLnNsaWNlKDQsIDQgKyBoZWFkZXJTaXplKTtcbiAgICAgICAgbGV0IGhlYWRlcjogVHJhbnNhY3Rpb25IZWFkZXI7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBoZWFkZXIgPSBKU09OLnBhcnNlKGhlYWRlckJ1ZmZlci50b1N0cmluZygpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHBhcnNlIGhlYWRlciBvZiB0cmFuc2FjdGlvbiBmaWxlIGluICR7dGhpcy5kZWJ1Z05hbWV9LCAke2ZpbGVuYW1lfWApO1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIGxldCBjb250ZW50ID0gZnVsbEZpbGUuc2xpY2UoNCArIGhlYWRlclNpemUpO1xuICAgICAgICBpZiAoaGVhZGVyLnppcHBlZCkge1xuICAgICAgICAgICAgY29udGVudCA9IGF3YWl0IFppcC5ndW56aXAoY29udGVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICAgICAgbGV0IGVudHJpZXM6IFRyYW5zYWN0aW9uRW50cnlbXSA9IFtdO1xuICAgICAgICB3aGlsZSAob2Zmc2V0IDwgY29udGVudC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghY29udGVudC5zbGljZShvZmZzZXQsIG9mZnNldCArIFNUQVJUX0JZVEVTLmxlbmd0aCkuZXF1YWxzKFNUQVJUX0JZVEVTKSkge1xuICAgICAgICAgICAgICAgIGxldCBzID0gb2Zmc2V0O1xuICAgICAgICAgICAgICAgIHdoaWxlIChvZmZzZXQgPCBjb250ZW50Lmxlbmd0aCAmJiAhY29udGVudC5zbGljZShvZmZzZXQsIG9mZnNldCArIFNUQVJUX0JZVEVTLmxlbmd0aCkuZXF1YWxzKFNUQVJUX0JZVEVTKSkge1xuICAgICAgICAgICAgICAgICAgICBvZmZzZXQrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IGxlbiA9IG9mZnNldCAtIHM7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBGb3VuZCBiYWQgYnl0ZXMgaW4gJHtmaWxlbmFtZX0sIHNraXBwaW5nICR7bGVufSBieXRlcyBhdCBvZmZzZXQgJHtzfS4gVG90YWwgZmlsZSBieXRlcyAke2NvbnRlbnQubGVuZ3RofSwgcmVhZCAke2VudHJpZXMubGVuZ3RofSBlbnRyaWVzYCk7XG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA+PSBjb250ZW50Lmxlbmd0aCkgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgZW50cnlPYmo6IHsgZW50cnk6IFRyYW5zYWN0aW9uRW50cnksIG9mZnNldDogbnVtYmVyIH0gfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGVudHJ5T2JqID0gdGhpcy5yZWFkVHJhbnNhY3Rpb25FbnRyeShjb250ZW50LCBvZmZzZXQpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgICAgICAgaWYgKGUubWVzc2FnZS5pbmNsdWRlcyhcIlJlYWQgcGFzdCBlbmQgb2YgYnVmZmVyXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIG9mZnNldCArPSAxO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghZW50cnlPYmopIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYEZhaWxlZCB0byByZWFkIHRyYW5zYWN0aW9uIGVudHJ5IGluIGluICR7dGhpcy5kZWJ1Z05hbWV9LCBmaWxlICR7ZmlsZW5hbWV9IGF0IG9mZnNldCAke29mZnNldH0sIHNraXBwaW5nIGJhZCBieXRlcywgcmVhZGluZyByZW1haW5kZXIgb2YgZmlsZWApO1xuICAgICAgICAgICAgICAgIG9mZnNldCsrO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmVudHJ5Q291bnQrKztcbiAgICAgICAgICAgIGxldCB7IGVudHJ5IH0gPSBlbnRyeU9iajtcbiAgICAgICAgICAgIG9mZnNldCA9IGVudHJ5T2JqLm9mZnNldDtcbiAgICAgICAgICAgIGVudHJpZXMucHVzaChlbnRyeSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGVudHJpZXM7XG4gICAgfVxuICAgIHByaXZhdGUgYXBwbHlUcmFuc2FjdGlvbkVudHJpZXMoZW50cmllczogVHJhbnNhY3Rpb25FbnRyeVtdLCBpbml0aWFsTG9hZD86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgbGV0IHBlbmRpbmdXcml0ZVRpbWVzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLnBlbmRpbmdBcHBlbmRzKSB7XG4gICAgICAgICAgICBsZXQgcHJldlRpbWUgPSBwZW5kaW5nV3JpdGVUaW1lcy5nZXQoZW50cnkua2V5KTtcbiAgICAgICAgICAgIGlmIChwcmV2VGltZSAmJiBwcmV2VGltZSA+IGVudHJ5LnRpbWUpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBlbmRpbmdXcml0ZVRpbWVzLnNldChlbnRyeS5rZXksIGVudHJ5LnRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBsYXRlc3QgPSBuZXcgTWFwPHN0cmluZywgVHJhbnNhY3Rpb25FbnRyeT4oKTtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICAgICAgICBsZXQgcGVuZGluZ1RpbWUgPSBwZW5kaW5nV3JpdGVUaW1lcy5nZXQoZW50cnkua2V5KTtcbiAgICAgICAgICAgIGlmIChwZW5kaW5nVGltZSAmJiBwZW5kaW5nVGltZSA+IGVudHJ5LnRpbWUpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBwcmV2ID0gbGF0ZXN0LmdldChlbnRyeS5rZXkpO1xuICAgICAgICAgICAgaWYgKHByZXYgJiYgcHJldi50aW1lID4gZW50cnkudGltZSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGF0ZXN0LnNldChlbnRyeS5rZXksIGVudHJ5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBhbnlDaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGVudHJ5IG9mIGxhdGVzdC52YWx1ZXMoKSkge1xuICAgICAgICAgICAgaWYgKGVudHJ5LnZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY2FjaGUuaGFzKGVudHJ5LmtleSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGFueUNoYW5nZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FjaGUuZGVsZXRlKGVudHJ5LmtleSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICghYW55Q2hhbmdlZCAmJiAhaW5pdGlhbExvYWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaGFzQ2hhbmdlZCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBwcmV2ID0gdGhpcy5jYWNoZS5nZXQoZW50cnkua2V5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcHJldikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcHJldi52YWx1ZSAhPT0gISFlbnRyeS52YWx1ZSkgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJldi52YWx1ZSAmJiBlbnRyeS52YWx1ZSAmJiAhcHJldi52YWx1ZS5lcXVhbHMoZW50cnkudmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIGFueUNoYW5nZWQgPSBoYXNDaGFuZ2VkKCkgfHwgYW55Q2hhbmdlZDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLmNhY2hlLnNldChlbnRyeS5rZXksIGVudHJ5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhbnlDaGFuZ2VkICYmICFpbml0aWFsTG9hZCkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKGBUcmFuc2FjdGlvbiBzdG9yYWdlICR7dGhpcy5kZWJ1Z05hbWV9IGNoYW5nZWQgb24gZGlzaywgdHJpZ2dlcmluZyBmdWxsIGRvd25sb2FkIGZyb20gZGlza2ApO1xuICAgICAgICAgICAgZm9yIChjb25zdCBjYWxsYmFjayBvZiB0aGlzLnJlc3luY0NhbGxiYWNrcykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBzZXRJbW1lZGlhdGUoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZWFkVHJhbnNhY3Rpb25FbnRyeShidWZmZXI6IEJ1ZmZlciwgb2Zmc2V0OiBudW1iZXIpOiB7XG4gICAgICAgIGVudHJ5OiBUcmFuc2FjdGlvbkVudHJ5O1xuICAgICAgICBvZmZzZXQ6IG51bWJlcjtcbiAgICB9IHwgdW5kZWZpbmVkIHtcbiAgICAgICAgZnVuY3Rpb24gcmVhZFNsaWNlKGNvdW50OiBudW1iZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IHNsaWNlID0gYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgY291bnQpO1xuICAgICAgICAgICAgaWYgKHNsaWNlLmxlbmd0aCA8IGNvdW50KSB0aHJvdyBuZXcgRXJyb3IoYFJlYWQgcGFzdCBlbmQgb2YgYnVmZmVyIGF0IG9mZnNldCAke29mZnNldH0vJHtidWZmZXIubGVuZ3RofWApO1xuICAgICAgICAgICAgb2Zmc2V0ICs9IGNvdW50O1xuICAgICAgICAgICAgcmV0dXJuIHNsaWNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcmVhZFNsaWNlKFNUQVJUX0JZVEVTLmxlbmd0aCkuZXF1YWxzKFNUQVJUX0JZVEVTKSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICBjb25zdCBrZXlMZW5ndGggPSByZWFkU2xpY2UoNCkucmVhZFVJbnQzMkxFKDApO1xuICAgICAgICBjb25zdCB2YWx1ZUxlbmd0aCA9IHJlYWRTbGljZSg0KS5yZWFkVUludDMyTEUoMCk7XG4gICAgICAgIGNvbnN0IHRpbWUgPSByZWFkU2xpY2UoOCkucmVhZERvdWJsZUxFKDApO1xuICAgICAgICBjb25zdCBmbGFncyA9IHJlYWRTbGljZSgxKS5yZWFkVUludDgoMCk7XG5cbiAgICAgICAgY29uc3Qga2V5ID0gcmVhZFNsaWNlKGtleUxlbmd0aCkudG9TdHJpbmcoKTtcbiAgICAgICAgbGV0IHZhbHVlID0gcmVhZFNsaWNlKHZhbHVlTGVuZ3RoKTtcblxuICAgICAgICBpZiAoIXJlYWRTbGljZShFTkRfQllURVMubGVuZ3RoKS5lcXVhbHMoRU5EX0JZVEVTKSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICBsZXQgaXNaaXBwZWQgPSAoZmxhZ3MgJiAxKSA9PT0gMTtcbiAgICAgICAgbGV0IGlzRGVsZXRlID0gKGZsYWdzICYgMikgPT09IDI7XG5cbiAgICAgICAgaWYgKGlzWmlwcGVkKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IFppcC5ndW56aXBTeW5jKHZhbHVlKTtcbiAgICAgICAgICAgIGlzWmlwcGVkID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgZW50cnk6IFRyYW5zYWN0aW9uRW50cnkgPSB7IGtleSwgdmFsdWUsIGlzWmlwcGVkLCB0aW1lIH07XG4gICAgICAgIGlmIChpc0RlbGV0ZSkge1xuICAgICAgICAgICAgZW50cnkudmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgZW50cnksIG9mZnNldCB9O1xuICAgIH1cblxuICAgIC8vIFRPRE86IE1ha2UgdGhpcyBkaXJlY3RseSBnbyBmcm9tIFRyYW5zYWN0aW9uRW50cnlbXSB0byBCdWZmZXIsIGJ5IHByZS1hbGxvY2F0aW5nLCBzbyBpdCBpcyBtb3JlIGVmZmljaWVudFxuICAgIHByaXZhdGUgc2VyaWFsaXplVHJhbnNhY3Rpb25FbnRyeShlbnRyeTogVHJhbnNhY3Rpb25FbnRyeSk6IEJ1ZmZlciB7XG4gICAgICAgIGxldCBrZXlCdWZmZXIgPSBCdWZmZXIuZnJvbShlbnRyeS5rZXkpO1xuICAgICAgICBjb25zdCBidWZmZXIgPSBCdWZmZXIuYWxsb2MoXG4gICAgICAgICAgICBTVEFSVF9CWVRFUy5sZW5ndGggKyA0ICsgNCArIDggKyAxICsga2V5QnVmZmVyLmxlbmd0aCArIChlbnRyeS52YWx1ZT8ubGVuZ3RoIHx8IDApICsgRU5EX0JZVEVTLmxlbmd0aFxuICAgICAgICApO1xuICAgICAgICBsZXQgb2Zmc2V0ID0gMDtcblxuICAgICAgICBTVEFSVF9CWVRFUy5jb3B5KGJ1ZmZlciwgb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0ICs9IFNUQVJUX0JZVEVTLmxlbmd0aDtcblxuICAgICAgICBidWZmZXIud3JpdGVVSW50MzJMRShrZXlCdWZmZXIubGVuZ3RoLCBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgKz0gNDtcblxuICAgICAgICBidWZmZXIud3JpdGVVSW50MzJMRShlbnRyeS52YWx1ZSA/IGVudHJ5LnZhbHVlLmxlbmd0aCA6IDAsIG9mZnNldCk7XG4gICAgICAgIG9mZnNldCArPSA0O1xuXG4gICAgICAgIGJ1ZmZlci53cml0ZURvdWJsZUxFKGVudHJ5LnRpbWUsIG9mZnNldCk7XG4gICAgICAgIG9mZnNldCArPSA4O1xuXG4gICAgICAgIGxldCBmbGFncyA9IDA7XG4gICAgICAgIGlmIChlbnRyeS5pc1ppcHBlZCkgZmxhZ3MgfD0gMTtcbiAgICAgICAgaWYgKGVudHJ5LnZhbHVlID09PSB1bmRlZmluZWQpIGZsYWdzIHw9IDI7XG4gICAgICAgIGJ1ZmZlci53cml0ZVVJbnQ4KGZsYWdzLCBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgKz0gMTtcblxuICAgICAgICBrZXlCdWZmZXIuY29weShidWZmZXIsIG9mZnNldCk7XG4gICAgICAgIG9mZnNldCArPSBrZXlCdWZmZXIubGVuZ3RoO1xuXG4gICAgICAgIGlmIChlbnRyeS52YWx1ZSkge1xuICAgICAgICAgICAgZW50cnkudmFsdWUuY29weShidWZmZXIsIG9mZnNldCk7XG4gICAgICAgICAgICBvZmZzZXQgKz0gZW50cnkudmFsdWUubGVuZ3RoO1xuICAgICAgICB9XG5cbiAgICAgICAgRU5EX0JZVEVTLmNvcHkoYnVmZmVyLCBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgKz0gRU5EX0JZVEVTLmxlbmd0aDtcblxuICAgICAgICByZXR1cm4gYnVmZmVyO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0SGVhZGVyKHppcDogYm9vbGVhbikge1xuICAgICAgICBjb25zdCBoZWFkZXI6IFRyYW5zYWN0aW9uSGVhZGVyID0geyB6aXBwZWQ6IHppcCB9O1xuICAgICAgICBsZXQgaGVhZGVyQnVmZmVyID0gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoaGVhZGVyKSk7XG4gICAgICAgIGxldCBoZWFkZXJTaXplID0gQnVmZmVyLmFsbG9jKDQpO1xuICAgICAgICBoZWFkZXJTaXplLndyaXRlVUludDMyTEUoaGVhZGVyQnVmZmVyLmxlbmd0aCwgMCk7XG4gICAgICAgIHJldHVybiB7IGhlYWRlciwgaGVhZGVyQnVmZmVyOiBCdWZmZXIuY29uY2F0KFtoZWFkZXJTaXplLCBoZWFkZXJCdWZmZXJdKSB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgY2h1bmtCdWZmZXJzKGJ1ZmZlcnM6IEJ1ZmZlcltdKSB7XG4gICAgICAgIGxldCBuZXdDaHVua3M6IHtcbiAgICAgICAgICAgIGJ1ZmZlcnM6IEJ1ZmZlcltdO1xuICAgICAgICAgICAgc2l6ZTogbnVtYmVyO1xuICAgICAgICB9W10gPSBbXTtcbiAgICAgICAgbmV3Q2h1bmtzLnB1c2goeyBidWZmZXJzOiBbXSwgc2l6ZTogMCB9KTtcbiAgICAgICAgZm9yIChjb25zdCBidWZmZXIgb2YgYnVmZmVycykge1xuICAgICAgICAgICAgaWYgKG5ld0NodW5rc1tuZXdDaHVua3MubGVuZ3RoIC0gMV0uc2l6ZSArIGJ1ZmZlci5sZW5ndGggPj0gRklMRV9DSFVOS19TSVpFKSB7XG4gICAgICAgICAgICAgICAgbmV3Q2h1bmtzLnB1c2goeyBidWZmZXJzOiBbXSwgc2l6ZTogMCB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5ld0NodW5rc1tuZXdDaHVua3MubGVuZ3RoIC0gMV0uYnVmZmVycy5wdXNoKGJ1ZmZlcik7XG4gICAgICAgICAgICBuZXdDaHVua3NbbmV3Q2h1bmtzLmxlbmd0aCAtIDFdLnNpemUgKz0gYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3Q2h1bmtzLm1hcCh4ID0+ICh7IGJ1ZmZlcjogQnVmZmVyLmNvbmNhdCh4LmJ1ZmZlcnMpLCBzaXplOiB4LnNpemUgfSkpO1xuICAgIH1cblxuXG4gICAgcHJpdmF0ZSBjb21wcmVzc2luZyA9IGZhbHNlO1xuICAgIHByaXZhdGUgYXN5bmMgY29tcHJlc3NUcmFuc2FjdGlvbkxvZyhmb3JjZT86IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKHRoaXMuY29tcHJlc3NpbmcpIHJldHVybjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuY29tcHJlc3NpbmcgPSB0cnVlO1xuXG4gICAgICAgICAgICBsZXQgZXhpc3RpbmdEaXNrRW50cmllcyA9IGF3YWl0IHRoaXMucmF3U3RvcmFnZS5nZXRLZXlzKCk7XG4gICAgICAgICAgICBleGlzdGluZ0Rpc2tFbnRyaWVzID0gZXhpc3RpbmdEaXNrRW50cmllcy5maWx0ZXIoeCA9PiB4LmVuZHNXaXRoKENIVU5LX0VYVCkpO1xuICAgICAgICAgICAgbGV0IGNvbXByZXNzTm93ID0gZm9yY2UgfHwgKFxuICAgICAgICAgICAgICAgIHRoaXMuZW50cnlDb3VudCA+IDEwMCAmJiB0aGlzLmVudHJ5Q291bnQgPiB0aGlzLmNhY2hlLnNpemUgKiAzXG4gICAgICAgICAgICAgICAgLy8gTk9URTogVGhpcyBjb21wcmVzcyBjaGVjayBicmVha3MgZG93biBpZiB3ZSBvbmx5IGhhdmUgdmVyeSBsYXJnZSB2YWx1ZXMsIGJ1dC4uLiB0aG9zZVxuICAgICAgICAgICAgICAgIC8vICBkb24ndCB3b3JrIEFOWVdBWVMgKGl0IGlzIGJldHRlciB0byB1c2Ugb25lIGZpbGUgcGVyIHZhbHVlIGluc3RlYWQpLlxuICAgICAgICAgICAgICAgIC8vICAtIE1heWJlIHdlIHNob3VsZCB0aHJvdywgb3IgYXQgbGVhc3Qgd2Fybiwgb24gc2V0cyBvZiB2YWx1ZSA+IDFNQixcbiAgICAgICAgICAgICAgICAvLyAgICAgIGF0IHdoaWNoIHBvaW50IHRoZXkgc2hvdWxkIGp1c3QgdXNlIGEgZmlsZSBwZXIgdmFsdWVcbiAgICAgICAgICAgICAgICB8fCBleGlzdGluZ0Rpc2tFbnRyaWVzLmxlbmd0aCA+IE1hdGgubWF4KDEwLCBNYXRoLmNlaWwodGhpcy5lbnRyeUNvdW50IC8gMTAwMCkpXG4gICAgICAgICAgICAgICAgfHwgZXhpc3RpbmdEaXNrRW50cmllcy5sZW5ndGggPiAxMDAwICogMTBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoIWNvbXByZXNzTm93KSByZXR1cm47XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgQ29tcHJlc3NpbmcgJHt0aGlzLmRlYnVnTmFtZX0gdHJhbnNhY3Rpb24gbG9nLCAke3RoaXMuZW50cnlDb3VudH0gZW50cmllcywgJHt0aGlzLmNhY2hlLnNpemV9IGtleXNgKTtcblxuICAgICAgICAgICAgLy8gTG9hZCBvZmYgZGlzaywgaW4gY2FzZSB0aGVyZSBhcmUgb3RoZXIgd3JpdGVzLiBXZSBzdGlsbCByYWNlIHdpdGggdGhlbSwgYnV0IGF0IGxlYXN0XG4gICAgICAgICAgICAvLyAgdGhpcyByZWR1Y2VzIHRoZSByYWNlIGNvbmRpdGlvbiBjb25zaWRlcmFibHlcbiAgICAgICAgICAgIGV4aXN0aW5nRGlza0VudHJpZXMgPSBhd2FpdCB0aGlzLmxvYWRBbGxUcmFuc2FjdGlvbnMoKTtcblxuICAgICAgICAgICAgdGhpcy5lbnRyeUNvdW50ID0gdGhpcy5jYWNoZS5zaXplO1xuXG5cbiAgICAgICAgICAgIGxldCBidWZmZXJzOiBCdWZmZXJbXSA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLmNhY2hlLnZhbHVlcygpKSB7XG4gICAgICAgICAgICAgICAgbGV0IGJ1ZmZlciA9IHRoaXMuc2VyaWFsaXplVHJhbnNhY3Rpb25FbnRyeShlbnRyeSk7XG4gICAgICAgICAgICAgICAgYnVmZmVycy5wdXNoKGJ1ZmZlcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBuZXdDaHVua3MgPSB0aGlzLmNodW5rQnVmZmVycyhidWZmZXJzKTtcblxuICAgICAgICAgICAgbGV0IG5ld0ZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgY2h1bmsgb2YgbmV3Q2h1bmtzKSB7XG4gICAgICAgICAgICAgICAgLy8gRG9uJ3QgdXNlIHRoZSBwcmV2aW91cyBjdXJyZW50IGNodW5rIGZvciB0aGUgbmV3IGZpbGUuIEFsc28gY2xlYXIgaXQgYWZ0ZXJ3YXJkcyBzbyBpdCdzIG5vdCByZXVzZWQgZm9yIGFueSBmdXR1cmUgcmlnaHRzLiBcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRDaHVuayA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBsZXQgZmlsZSA9IHRoaXMuZ2V0Q3VycmVudENodW5rKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50Q2h1bmsgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgbmV3RmlsZXMucHVzaChmaWxlKTtcbiAgICAgICAgICAgICAgICBsZXQgY29udGVudCA9IGNodW5rLmJ1ZmZlcjtcbiAgICAgICAgICAgICAgICBsZXQgeyBoZWFkZXIsIGhlYWRlckJ1ZmZlciB9ID0gdGhpcy5nZXRIZWFkZXIoXG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnQubGVuZ3RoID49IEZJTEVfWklQX1RIUkVTSE9MRFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgaWYgKGhlYWRlci56aXBwZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IGF3YWl0IFppcC5nemlwKGNvbnRlbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgYnVmZmVyID0gQnVmZmVyLmNvbmNhdChbaGVhZGVyQnVmZmVyLCBjb250ZW50XSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5yYXdTdG9yYWdlLnNldChmaWxlLCBidWZmZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlRGlza0ZpbGVUaW1lc3RhbXAoZmlsZSk7XG4gICAgICAgICAgICAgICAgbGV0IHZlcmlmaWVkID0gYXdhaXQgdGhpcy5yYXdTdG9yYWdlLmdldChmaWxlKTtcbiAgICAgICAgICAgICAgICBpZiAoIXZlcmlmaWVkPy5lcXVhbHMoYnVmZmVyKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gdmVyaWZ5IHRyYW5zYWN0aW9uIGZpbGUgJHtmaWxlfSBpbiAke3RoaXMuZGVidWdOYW1lfWApO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byB2ZXJpZnkgdHJhbnNhY3Rpb24gZmlsZSAke2ZpbGV9IGluICR7dGhpcy5kZWJ1Z05hbWV9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBPTkxZIHRpbWUgd2UgY2FuIGRlbGV0ZSBvbGQgZmlsZXMsIGFzIHdlIGtub3cgZm9yIHN1cmUgdGhlIG5ldyBmaWxlIGhhcyBhbGwgb2Ygb3VyIGRhdGEuXG4gICAgICAgICAgICAvLyAgQW55IGZ1dHVyZSByZWFkZXJzIHdvbid0IGtub3cgdGhpcywgdW5sZXNzIHRoZXkgd3JpdGUgaXQgdGhlbXNlbHZlcyAob3IgdW5sZXNzIHRoZXkgYXVkaXQgaXQgYWdhaW5zdFxuICAgICAgICAgICAgLy8gICAgICB0aGUgb3RoZXIgZ2VuZXJhdGlvbnMsIHdoaWNoIGlzIGFubm95aW5nKS5cbiAgICAgICAgICAgIGZvciAoY29uc3QgZmlsZSBvZiBleGlzdGluZ0Rpc2tFbnRyaWVzKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5yYXdTdG9yYWdlLnJlbW92ZShmaWxlKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2tGaWxlcy5kZWxldGUoZmlsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICB0aGlzLmNvbXByZXNzaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgcmVzZXQoKSB7XG4gICAgICAgIGF3YWl0IGZpbGVMb2NrU2VjdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBsZXQgZXhpc3RpbmdEaXNrRW50cmllcyA9IGF3YWl0IHRoaXMucmF3U3RvcmFnZS5nZXRLZXlzKCk7XG4gICAgICAgICAgICBleGlzdGluZ0Rpc2tFbnRyaWVzID0gZXhpc3RpbmdEaXNrRW50cmllcy5maWx0ZXIoeCA9PiB4LmVuZHNXaXRoKENIVU5LX0VYVCkpO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChleGlzdGluZ0Rpc2tFbnRyaWVzLm1hcCh4ID0+IHRoaXMucmF3U3RvcmFnZS5yZW1vdmUoeCkpKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggeyB9XG5cbiAgICAgICAgICAgIHRoaXMucGVuZGluZ0FwcGVuZHMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuY2FjaGUuY2xlYXIoKTtcbiAgICAgICAgICAgIHRoaXMuZGlza0ZpbGVzLmNsZWFyKCk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRDaHVuayA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMuZW50cnlDb3VudCA9IDA7XG4gICAgICAgIH0pO1xuICAgIH1cbn0iXX0=
560
+ /* _JS_SOURCE_HASH = "2978a7922e02bba139ad18653f71a102bfb3bf8f99e4ddda2b3e7595b294431e"; */