sliftutils 1.7.115 → 1.7.117

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 (33) hide show
  1. package/index.d.ts +12 -5
  2. package/package.json +2 -2
  3. package/spec.txt +4 -5
  4. package/storage/ArchivesDisk.ts +8 -8
  5. package/storage/IArchives.d.ts +6 -2
  6. package/storage/IArchives.ts +7 -3
  7. package/storage/TransactionFile.d.ts +1 -1
  8. package/storage/TransactionFile.ts +11 -11
  9. package/storage/archiveHelpers.d.ts +3 -1
  10. package/storage/archiveHelpers.ts +19 -14
  11. package/storage/dist/ArchivesDisk.ts.cache +10 -10
  12. package/storage/dist/IArchives.ts.cache +2 -2
  13. package/storage/dist/TransactionFile.ts.cache +13 -13
  14. package/storage/dist/archiveHelpers.ts.cache +19 -16
  15. package/storage/remoteStorage/ArchivesDelayed.ts +1 -1
  16. package/storage/remoteStorage/ArchivesRemote.ts +2 -2
  17. package/storage/remoteStorage/blobStore.d.ts +1 -1
  18. package/storage/remoteStorage/blobStore.ts +15 -9
  19. package/storage/remoteStorage/bucketDisk.ts +2 -2
  20. package/storage/remoteStorage/chainStartup.ts +1 -1
  21. package/storage/remoteStorage/createArchives.ts +1 -1
  22. package/storage/remoteStorage/dist/ArchivesDelayed.ts.cache +3 -3
  23. package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +4 -4
  24. package/storage/remoteStorage/dist/blobStore.ts.cache +20 -11
  25. package/storage/remoteStorage/dist/bucketDisk.ts.cache +4 -4
  26. package/storage/remoteStorage/dist/chainStartup.ts.cache +3 -3
  27. package/storage/remoteStorage/dist/createArchives.ts.cache +3 -3
  28. package/storage/remoteStorage/dist/storageController.ts.cache +2 -2
  29. package/storage/remoteStorage/dist/storeSync.ts.cache +8 -8
  30. package/storage/remoteStorage/storageController.d.ts +1 -0
  31. package/storage/remoteStorage/storageController.ts +1 -1
  32. package/storage/remoteStorage/storeSync.ts +6 -6
  33. package/yarn.lock +4 -4
@@ -107,9 +107,9 @@ class TransactionFile {
107
107
  deletedEntries() {
108
108
  return this.deleted.entries();
109
109
  }
110
- /** Stores a value as of `time` (floored to whole milliseconds - see applySet). Returns false when something at least as new is already here, in which case nothing changed - an out-of-order write is not an error, it is just late. */
110
+ /** Stores a value as of `time` (rounded to whole milliseconds - see applySet). Returns false when something at least as new is already here, in which case nothing changed - an out-of-order write is not an error, it is just late. */
111
111
  set(key, value, time) {
112
- time = Math.floor(time);
112
+ time = Math.round(time);
113
113
  if (!this.applySet(key, value, time, Date.now()))
114
114
  return false;
115
115
  this.append({ k: key, t: time, v: value });
@@ -117,7 +117,7 @@ class TransactionFile {
117
117
  }
118
118
  /** Deletes as of `time`, keeping the tombstone. A key that had a live value keeps it in the tombstone as MARKED for deletion (readable and restorable until dropValue). Returns false when something at least as new is already here. */
119
119
  delete(key, time) {
120
- time = Math.floor(time);
120
+ time = Math.round(time);
121
121
  let live = this.values.get(key);
122
122
  if (!this.applyDelete(key, time, Date.now(), live === null || live === void 0 ? void 0 : live.value, live === null || live === void 0 ? void 0 : live.time))
123
123
  return false;
@@ -131,7 +131,7 @@ class TransactionFile {
131
131
  }
132
132
  /** Undoes a marked deletion: the kept value becomes live again, as of `time` (a fresh time, so the restore outranks the deletion everywhere it propagated). Returns false when there is no marked value to restore, or something at least as new is already here. */
133
133
  unmark(key, time) {
134
- time = Math.floor(time);
134
+ time = Math.round(time);
135
135
  let tombstone = this.deleted.get(key);
136
136
  if (!tombstone || tombstone.value === undefined)
137
137
  return false;
@@ -154,12 +154,12 @@ class TransactionFile {
154
154
  had = this.deleted.delete(key) || had;
155
155
  if (!had)
156
156
  return;
157
- this.append({ k: key, t: Math.floor(Date.now()), p: 1 });
157
+ this.append({ k: key, t: Math.round(Date.now()), p: 1 });
158
158
  }
159
- // Times are floored to whole milliseconds on every path into the maps (load replays through here too, so fractional times persisted by older code heal on startup). Disk mtimes carry fractional milliseconds but utimes round-trips only whole ones, so a fractional time can never be reproduced by propagation - every copy of the value would compare "older" than the original forever, and the same write would be re-pushed and re-copied every round.
159
+ // Times are ROUNDED to whole milliseconds on every path into the maps (load replays through here too, so fractional times persisted by older code heal on startup). Disk mtimes carry fractional milliseconds but utimes round-trips only whole ones, so a fractional time can never be reproduced by propagation - every copy of the value would compare "older" than the original forever, and the same write would be re-pushed and re-copied every round. Round rather than floor, to match ArchivesDisk (see its get2): utimes goes through a seconds double and can land a hair below the stamped millisecond.
160
160
  applySet(key, value, time, changedAt) {
161
- time = Math.floor(time);
162
- changedAt = Math.floor(changedAt);
161
+ time = Math.round(time);
162
+ changedAt = Math.round(changedAt);
163
163
  if (time < this.timeOf(key))
164
164
  return false;
165
165
  this.deleted.delete(key);
@@ -167,10 +167,10 @@ class TransactionFile {
167
167
  return true;
168
168
  }
169
169
  applyDelete(key, time, changedAt, value, valueTime) {
170
- time = Math.floor(time);
171
- changedAt = Math.floor(changedAt);
170
+ time = Math.round(time);
171
+ changedAt = Math.round(changedAt);
172
172
  if (valueTime !== undefined) {
173
- valueTime = Math.floor(valueTime);
173
+ valueTime = Math.round(valueTime);
174
174
  }
175
175
  if (time < this.timeOf(key))
176
176
  return false;
@@ -251,5 +251,5 @@ class TransactionFile {
251
251
  }
252
252
  }
253
253
  exports.TransactionFile = TransactionFile;
254
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNhY3Rpb25GaWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiVHJhbnNhY3Rpb25GaWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLDRDQUFvQjtBQUNwQixnREFBd0I7QUFDeEIseURBQW1EO0FBRW5ELG9iQUFvYjtBQUNwYixFQUFFO0FBQ0Ysb0tBQW9LO0FBRXBLLCtJQUErSTtBQUMvSSxNQUFNLGFBQWEsR0FBRyxDQUFDLENBQUM7QUFDeEIsOEZBQThGO0FBQzlGLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDO0FBQ2pDLHNMQUFzTDtBQUN0TCxNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUM7QUF5QnhCLE1BQWEsZUFBZTtJQUN4QixZQUFvQixRQUFnQjtRQUFoQixhQUFRLEdBQVIsUUFBUSxDQUFRO1FBRTVCLFdBQU0sR0FBRyxJQUFJLEdBQUcsRUFBdUIsQ0FBQztRQUN4QyxZQUFPLEdBQUcsSUFBSSxHQUFHLEVBQTJCLENBQUM7UUFDckQsNEdBQTRHO1FBQ3BHLGVBQVUsR0FBRyxDQUFDLENBQUM7UUFDZixZQUFPLEdBQWEsRUFBRSxDQUFDO1FBRS9CLGdHQUFnRztRQUN4RixlQUFVLEdBQWtCLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUV0RCw4RkFBOEY7UUFDdkYsU0FBSSxHQUFHLElBQUEsY0FBSSxFQUFDLEtBQUssSUFBSSxFQUFFO1lBQzFCLElBQUksSUFBWSxDQUFDO1lBQ2pCLElBQUksQ0FBQztnQkFDRCxJQUFJLEdBQUcsTUFBTSxZQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzdELENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNULElBQUssQ0FBdUIsQ0FBQyxJQUFJLEtBQUssUUFBUTtvQkFBRSxPQUFPO2dCQUN2RCxNQUFNLENBQUMsQ0FBQztZQUNaLENBQUM7WUFDRCxJQUFJLE9BQU8sR0FBRyxD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Q0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3pGLG9HQUFvRztRQUNwRyxNQUFNLFlBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDbEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBQ3ZELE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxJQUFJLENBQUMsUUFBUSxLQUFLLFdBQVcsb0JBQW9CLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxlQUFlLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxhQUFhLENBQUMsQ0FBQztRQUN2SSxNQUFNLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUMvQixDQUFDO0NBQ0o7QUFuT0QsMENBbU9DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IGxhenkgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9jYWNoaW5nXCI7XG5cbi8vIEEgcGVyc2lzdGVudCBNYXAgdGhhdCBrbm93cyBhYm91dCB0aW1lIGFuZCBhYm91dCBkZWxldGlvbnMuIEV2ZXJ5IHZhbHVlIGNhcnJpZXMgdGhlIHRpbWUgaXQgd2FzIHdyaXR0ZW4sIHNvIGEgd3JpdGUgdGhhdCBhcnJpdmVzIG91dCBvZiBvcmRlciBpcyBzaW1wbHkgbm90IGFwcGxpZWQgLSB0aGUgbWFwIGNhbm5vdCBiZSBtYWRlIHRvIGdvIGJhY2t3YXJkcy4gQSBkZWxldGVkIGtleSBrZWVwcyBpdHMgdGltZSB0b28sIGFzIGEgdG9tYnN0b25lIGluIGEgc2Vjb25kIG1hcCwgc28gXCJ3YXMgdGhpcyBkZWxldGVkLCBhbmQgd2hlblwiIGlzIGFzIGNoZWFwIHRvIGFzayBhcyBcImRvZXMgdGhpcyBleGlzdFwiLCBhbmQgZXhwaXJpbmcgb2xkIHRvbWJzdG9uZXMgaXMgYSB3YWxrIG9mIHRoZSB0b21ic3RvbmVzIGFsb25lIHJhdGhlciB0aGFuIG9mIGV2ZXJ5dGhpbmcuXG4vL1xuLy8gT24gZGlzayBpdCBpcyBvbmUgYXBwZW5kLW9ubHkgbG9nIG9mIHRoZSBzZXRzLCBkZWxldGVzIGFuZCBwdXJnZXMgdGhhdCBwcm9kdWNlZCBib3RoIG1hcHMsIHJld3JpdHRlbiBmcm9tIHRoZW0gd2hlbmV2ZXIgaXQgaGFzIGdyb3duIHRvIHNldmVyYWwgdGltZXMgdGhlaXIgc2l6ZS5cblxuLy8gVGhlIGxvZyBpcyByZXdyaXR0ZW4gb25jZSBpdCBob2xkcyB0aGlzIG1hbnkgdGltZXMgbW9yZSByZWNvcmRzIHRoYW4gdGhlcmUgYXJlIGtleXMgKGEgbG9nIG9mIDMgcmVjb3JkcyBwZXIgc3Vydml2aW5nIGtleSBpcyBtb3N0bHkgaGlzdG9yeSlcbmNvbnN0IENPTVBBQ1RfUkFUSU8gPSAzO1xuLy8gLi4uYnV0IG5ldmVyIGZvciBhIHNtYWxsIGxvZywgd2hlcmUgdGhlIHJld3JpdGUgd291bGQgY29zdCBtb3JlIHRoYW4gdGhlIGhpc3RvcnkgaXQgcmVtb3Zlc1xuY29uc3QgTUlOX0NPTVBBQ1RfUkVDT1JEUyA9IDEwMDA7XG4vLyBBcHBlbmRzIGFyZSBjb2FsZXNjZWQgZm9yIHRoaXMgbG9uZy4gQSBjcmFzaCBsb3NlcyBhdCBtb3N0IHRoaXMgbXVjaCAtIHRoZSBjYWxsZXJzIG9mIHRoaXMgY2xhc3MgdHJlYXQgdGhlaXIgZGF0YSBhcyByZWNvbnN0cnVjdGlibGUgLSBhbmQgdGhlIGFsdGVybmF0aXZlIGlzIGEgZmlsZSB3cml0ZSBwZXIgc2V0LlxuY29uc3QgRkxVU0hfREVMQVkgPSA1MDA7XG5cbi8qKiBBIGxpdmUgdmFsdWU6IHdoYXQgd2FzIHN0b3JlZCwgd2hlbiBpdCB3YXMgd3JpdHRlbiAodGhlIGNhbGxlcidzIG9yZGVyaW5nKSwgYW5kIHdoZW4gd2UgbGFzdCBjaGFuZ2VkIGl0IChvdXJzKS4gKi9cbmV4cG9ydCB0eXBlIExvZ0VudHJ5PFQ+ID0geyB2YWx1ZTogVDsgdGltZTogbnVtYmVyOyBjaGFuZ2VkQXQ6IG51bWJlciB9O1xuLyoqIEEgZGVsZXRlZCBrZXk6IHdoZW4gaXQgd2FzIGRlbGV0ZWQsIGFuZCB3aGVuIHdlIGxlYXJuZWQuIFdoZW4gdGhlIGtleSBoYWQgYSBsaXZlIHZhbHVlIGF0IGRlbGV0aW9uIHRpbWUgaXQgaXMgTUFSS0VEIHJhdGhlciB0aGFuIGdvbmUgLSB0aGUgdmFsdWUgKGFuZCBpdHMgb3JpZ2luYWwgd3JpdGUgdGltZSkgcmlkZXMgYWxvbmcsIHNvIHRoZSB1bmRlcmx5aW5nIGRhdGEgY2FuIHN0aWxsIGJlIHJlYWQgYW5kIHRoZSBkZWxldGlvbiBjYW4gYmUgdW5kb25lIChzZWUgdW5tYXJrKSB1bnRpbCB0aGUgaGlzdG9yeSBpcyBkcm9wcGVkIChzZWUgZHJvcFZhbHVlKS4gKi9cbmV4cG9ydCB0eXBlIExvZ1RvbWJzdG9uZTxUPiA9IHsgdGltZTogbnVtYmVyOyBjaGFuZ2VkQXQ6IG51bWJlcjsgdmFsdWU/OiBUOyB2YWx1ZVRpbWU/OiBudW1iZXIgfTtcblxuLy8gT25lIGxpbmUgb2YgdGhlIGxvZywgd2l0aCBzaW5nbGUtbGV0dGVyIGZpZWxkIG5hbWVzIGJlY2F1c2UgdGhlcmUgaXMgb25lIHJlY29yZCBwZXIgc2V0L2RlbGV0ZS9wdXJnZSBldmVyIG1hZGUgYW5kIHRoZSBmaWVsZCBuYW1lcyBhcmUgbW9zdCBvZiBhIHJlY29yZCdzIG92ZXJoZWFkLiBKU09OLnN0cmluZ2lmeSBlc2NhcGVzIG5ld2xpbmVzIGluc2lkZSBrZXlzIGFuZCB2YWx1ZXMsIHNvIGEgcmVjb3JkIGNhbiBuZXZlciBjb250YWluIHRoZSBzZXBhcmF0b3IuXG50eXBlIExvZ1JlY29yZDxUPiA9IHtcbiAgICAvLyBrZXlcbiAgICBrOiBzdHJpbmc7XG4gICAgLy8gdGltZSwgbGFzdE1vZGlmaWVkIHRpbWUgb2YgdGhlIGZpbGUsIG9yIHRoZSBkZWxldGUgdGltZSwgb3IgdGhlIHB1cmdlIHRpbWVcbiAgICB0OiBudW1iZXI7XG4gICAgLy8gdmFsdWVcbiAgICB2PzogVDtcbiAgICAvLyBkZWxldGVkLCB0aGUgZmlsZSBvbiBkaXNrIGlzIGRlbGV0ZWQsIHByZXNlcnZlZCB3aGVuIHdlIGNvbXBhY3RcbiAgICBkPzogMTtcbiAgICAvLyBtYXJrZWQgZm9yIGRlbGV0aW9uOiBkZWxldGVkLCBidXQgdGhlIHZhbHVlICh2KSBhbmQgaXRzIG9yaWdpbmFsIHdyaXRlIHRpbWUgKHcpIGFyZSBrZXB0LCBzbyB0aGUgZGF0YSBpcyBzdGlsbCByZWFkYWJsZSBhbmQgcmVzdG9yYWJsZS4gUHJlc2VydmVkIHdoZW4gd2UgY29tcGFjdC5cbiAgICBtPzogMTtcbiAgICAvLyB3cml0ZVRpbWUsIHRoZSBvcmlnaW5hbCB3cml0ZSB0aW1lIG9mIGEgbWFya2VkLWZvci1kZWxldGlvbiB2YWx1ZSAodCBpcyB0aGUgREVMRVRFIHRpbWUgb24gdGhvc2UgcmVjb3JkcylcbiAgICB3PzogbnVtYmVyO1xuICAgIC8vIHB1cmdlZCwgdGhlIGZpbGUgb24gZGlzayBpcyBkZWxldGVkLCBub3QgcHJlc2VydmVkIHdoZW4gd2UgY29tcGFjdFxuICAgIHA/OiAxO1xufTtcblxuZXhwb3J0IGNsYXNzIFRyYW5zYWN0aW9uRmlsZTxUPiB7XG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBmaWxlUGF0aDogc3RyaW5nKSB7IH1cblxuICAgIHByaXZhdGUgdmFsdWVzID0gbmV3IE1hcDxzdHJpbmcsIExvZ0VudHJ5PFQ+PigpO1xuICAgIHByaXZhdGUgZGVsZXRlZCA9IG5ldyBNYXA8c3RyaW5nLCBMb2dUb21ic3RvbmU8VD4+KCk7XG4gICAgLy8gUmVjb3JkcyB0aGUgbG9nIGhvbGRzICh3cml0dGVuIHBsdXMgcGVuZGluZykgLSB3aGF0IGNvbXBhY3Rpb24gaXMgZGVjaWRlZCBhZ2FpbnN0LCBOT1QgdGhlIG51bWJlciBvZiBrZXlzXG4gICAgcHJpdmF0ZSBsb2dSZWNvcmRzID0gMDtcbiAgICBwcml2YXRlIHBlbmRpbmc6IHN0cmluZ1tdID0gW107XG4gICAgcHJpdmF0ZSBmbHVzaFRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IHVuZGVmaW5lZDtcbiAgICAvLyBTZXJpYWxpemVzIGV2ZXJ5dGhpbmcgdGhhdCB0b3VjaGVzIHRoZSBmaWxlLCBzbyBhbiBhcHBlbmQgY2FuIG5ldmVyIGludGVybGVhdmUgd2l0aCBhIHJld3JpdGVcbiAgICBwcml2YXRlIHdyaXRlQ2hhaW46IFByb21pc2U8dm9pZD4gPSBQcm9taXNlLnJlc29sdmUoKTtcblxuICAgIC8qKiBSZWFkcyB0aGUgbG9nIGFuZCByZXBsYXlzIGl0IGludG8gbWVtb3J5LiBFdmVyeSBvdGhlciBtZXRob2QgYXNzdW1lcyB0aGlzIGhhcyBmaW5pc2hlZC4gKi9cbiAgICBwdWJsaWMgbG9hZCA9IGxhenkoYXN5bmMgKCkgPT4ge1xuICAgICAgICBsZXQgZGF0YTogc3RyaW5nO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZGF0YSA9IGF3YWl0IGZzLnByb21pc2VzLnJlYWRGaWxlKHRoaXMuZmlsZVBhdGgsIFwidXRmOFwiKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgaWYgKChlIGFzIHsgY29kZT86IHN0cmluZyB9KS5jb2RlID09PSBcIkVOT0VOVFwiKSByZXR1cm47XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGxldCBhcHBsaWVkID0gMDtcbiAgICAgICAgbGV0IGRhbWFnZWQgPSAwO1xuICAgICAgICBmb3IgKGxldCBsaW5lIG9mIGRhdGEuc3BsaXQoXCJcXG5cIikpIHtcbiAgICAgICAgICAgIGlmICghbGluZSkgY29udGludWU7XG4gICAgICAgICAgICBsZXQgcmVjb3JkOiBMb2dSZWNvcmQ8VD4gfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJlY29yZCA9IEpTT04ucGFyc2UobGluZSkgYXMgTG9nUmVjb3JkPFQ+O1xuICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgLy8gQSBjcmFzaCBtaWQtYXBwZW5kIGxlYXZlcyBhIHRvcm4gZmluYWwgbGluZTsgYW55dGhpbmcgZWFybGllciBtZWFucyByZWFsIGRhbWFnZS4gRWl0aGVyIHdheSB0aGUgcmVzdCBvZiB0aGUgbG9nIGlzIHN0aWxsIHdvcnRoIGhhdmluZyAtIHRoaXMgaXMgYW4gaW5kZXgsIGFuZCBzY2FubmluZyByZWJ1aWxkcyB3aGF0ZXZlciB3ZSBsb3NlLlxuICAgICAgICAgICAgICAgIGRhbWFnZWQrKztcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGFwcGxpZWQrKztcbiAgICAgICAgICAgIC8vIFJlcGxheWVkIHRocm91Z2ggdGhlIHNhbWUgb3JkZXJpbmcgcnVsZXMgdGhhdCBwcm9kdWNlZCBpdCwgc28gYSBsb2cgd3JpdHRlbiBvdXQgb2Ygb3JkZXIgc3RpbGwgbGFuZHMgb24gdGhlIHNhbWUgc3RhdGVcbiAgICAgICAgICAgIGlmIChyZWNvcmQucCkge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsdWVzLmRlbGV0ZShyZWNvcmQuayk7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWxldGVkLmRlbGV0ZShyZWNvcmQuayk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlY29yZC5tKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcHBseURlbGV0ZShyZWNvcmQuaywgcmVjb3JkLnQsIHJlY29yZC50LCByZWNvcmQudiwgcmVjb3JkLncpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChyZWNvcmQuZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlEZWxldGUocmVjb3JkLmssIHJlY29yZC50LCByZWNvcmQudCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlY29yZC52ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFwcGx5U2V0KHJlY29yZC5rLCByZWNvcmQudiwgcmVjb3JkLnQsIHJlY29yZC50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxvZ1JlY29yZHMgPSBhcHBsaWVkO1xuICAgICAgICBpZiAoZGFtYWdlZCkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHtkYW1hZ2VkfSBkYW1hZ2VkIHJlY29yZChzKSBpbiAke3RoaXMuZmlsZVBhdGh9IHdlcmUgc2tpcHBlZDsgJHthcHBsaWVkfSBhcHBsaWVkLCBsZWF2aW5nICR7dGhpcy52YWx1ZXMuc2l6ZX0gdmFsdWVzIGFuZCAke3RoaXMuZGVsZXRlZC5zaXplfSB0b21ic3RvbmVzYCk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8qKiBUaGUgbGl2ZSB2YWx1ZSwgb3IgdW5kZWZpbmVkIHdoZW4gdGhlIGtleSBkb2VzIG5vdCBleGlzdCBoZXJlIChkZWxldGVkIGluY2x1ZGVkIC0gYSBkZWxldGlvbiBpcyBhbiBhYnNlbmNlLCBzZWUgZ2V0RGVsZXRlZCBmb3IgaXRzIHRpbWUpLiAqL1xuICAgIHB1YmxpYyBnZXQoa2V5OiBzdHJpbmcpOiBMb2dFbnRyeTxUPiB8IHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlcy5nZXQoa2V5KTtcbiAgICB9XG4gICAgLyoqIFdoZW4gdGhlIGtleSB3YXMgZGVsZXRlZCwgaWYgaXQgd2FzICh2YWx1ZSBpbmNsdWRlZCB3aGVuIHRoZSBkZWxldGlvbiBpcyBzdGlsbCBtYXJrZWQgLSBzZWUgTG9nVG9tYnN0b25lKS4gQWJzZW50IGJvdGggaGVyZSBhbmQgaW4gZ2V0IG1lYW5zIHdlIGhhdmUgbmV2ZXIgaGVhcmQgb2YgaXQuICovXG4gICAgcHVibGljIGdldERlbGV0ZWQoa2V5OiBzdHJpbmcpOiBMb2dUb21ic3RvbmU8VD4gfCB1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gdGhpcy5kZWxldGVkLmdldChrZXkpO1xuICAgIH1cbiAgICAvKiogVGhlIHRpbWUgdGhlIGtleSBsYXN0IGNoYW5nZWQgZWl0aGVyIHdheSwgb3IgMCBpZiB3ZSBoYXZlIG5ldmVyIGhlYXJkIG9mIGl0IC0gd2hhdCBhIG5ldyB3cml0ZSBoYXMgdG8gYmVhdC4gKi9cbiAgICBwdWJsaWMgdGltZU9mKGtleTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IGxpdmUgPSB0aGlzLnZhbHVlcy5nZXQoa2V5KTtcbiAgICAgICAgaWYgKGxpdmUpIHJldHVybiBsaXZlLnRpbWU7XG4gICAgICAgIHJldHVybiB0aGlzLmRlbGV0ZWQuZ2V0KGtleSk/LnRpbWUgfHwgMDtcbiAgICB9XG5cbiAgICAvKiogTygxKSwgYW5kIGNvdW50cyBvbmx5IHdoYXQgZXhpc3RzLiAqL1xuICAgIHB1YmxpYyBnZXQgc2l6ZSgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZXMuc2l6ZTtcbiAgICB9XG4gICAgcHVibGljIGdldCBkZWxldGVkU2l6ZSgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5kZWxldGVkLnNpemU7XG4gICAgfVxuICAgIC8qKiBMaXZlIHZhbHVlcyBvbmx5LiBMaXZlLCBpbiBpbnNlcnRpb24gb3JkZXIgLSBkZWxldGluZyBkdXJpbmcgaXRlcmF0aW9uIGlzIHNhZmUgKEpTIHNraXBzIGVudHJpZXMgcmVtb3ZlZCBiZWZvcmUgdGhleSBhcmUgcmVhY2hlZCksIHdoaWNoIGlzIHdoYXQgdGhlIHBhc3NlcyB0aGF0IHdhbGsgZXZlcnl0aGluZyBhbmQgcHJ1bmUgYXMgdGhleSBnbyByZWx5IG9uLiAqL1xuICAgIHB1YmxpYyBlbnRyaWVzKCk6IEl0ZXJhYmxlSXRlcmF0b3I8W3N0cmluZywgTG9nRW50cnk8VD5dPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlcy5lbnRyaWVzKCk7XG4gICAgfVxuICAgIC8qKiBUaGUgdG9tYnN0b25lcywgd2hpY2ggaXMgYSBtdWNoIHNtYWxsZXIgd2FsayB0aGFuIHRoZSB2YWx1ZXMgLSBzbyBleHBpcmluZyB0aGVtLCBvciBsaXN0aW5nIHdoYXQgd2FzIGRlbGV0ZWQgc2luY2Ugc29tZSB0aW1lLCBjb3N0cyB3aGF0IGl0IHNob3VsZC4gKi9cbiAgICBwdWJsaWMgZGVsZXRlZEVudHJpZXMoKTogSXRlcmFibGVJdGVyYXRvcjxbc3RyaW5nLCBMb2dUb21ic3RvbmU8VD5dPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmRlbGV0ZWQuZW50cmllcygpO1xuICAgIH1cblxuICAgIC8qKiBTdG9yZXMgYSB2YWx1ZSBhcyBvZiBgdGltZWAgKGZsb29yZWQgdG8gd2hvbGUgbWlsbGlzZWNvbmRzIC0gc2VlIGFwcGx5U2V0KS4gUmV0dXJucyBmYWxzZSB3aGVuIHNvbWV0aGluZyBhdCBsZWFzdCBhcyBuZXcgaXMgYWxyZWFkeSBoZXJlLCBpbiB3aGljaCBjYXNlIG5vdGhpbmcgY2hhbmdlZCAtIGFuIG91dC1vZi1vcmRlciB3cml0ZSBpcyBub3QgYW4gZXJyb3IsIGl0IGlzIGp1c3QgbGF0ZS4gKi9cbiAgICBwdWJsaWMgc2V0KGtleTogc3RyaW5nLCB2YWx1ZTogVCwgdGltZTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIHRpbWUgPSBNYXRoLmZsb29yKHRpbWUpO1xuICAgICAgICBpZiAoIXRoaXMuYXBwbHlTZXQoa2V5LCB2YWx1ZSwgdGltZSwgRGF0ZS5ub3coKSkpIHJldHVybiBmYWxzZTtcbiAgICAgICAgdGhpcy5hcHBlbmQoeyBrOiBrZXksIHQ6IHRpbWUsIHY6IHZhbHVlIH0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKiogRGVsZXRlcyBhcyBvZiBgdGltZWAsIGtlZXBpbmcgdGhlIHRvbWJzdG9uZS4gQSBrZXkgdGhhdCBoYWQgYSBsaXZlIHZhbHVlIGtlZXBzIGl0IGluIHRoZSB0b21ic3RvbmUgYXMgTUFSS0VEIGZvciBkZWxldGlvbiAocmVhZGFibGUgYW5kIHJlc3RvcmFibGUgdW50aWwgZHJvcFZhbHVlKS4gUmV0dXJucyBmYWxzZSB3aGVuIHNvbWV0aGluZyBhdCBsZWFzdCBhcyBuZXcgaXMgYWxyZWFkeSBoZXJlLiAqL1xuICAgIHB1YmxpYyBkZWxldGUoa2V5OiBzdHJpbmcsIHRpbWU6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICB0aW1lID0gTWF0aC5mbG9vcih0aW1lKTtcbiAgICAgICAgbGV0IGxpdmUgPSB0aGlzLnZhbHVlcy5nZXQoa2V5KTtcbiAgICAgICAgaWYgKCF0aGlzLmFwcGx5RGVsZXRlKGtleSwgdGltZSwgRGF0ZS5ub3coKSwgbGl2ZT8udmFsdWUsIGxpdmU/LnRpbWUpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChsaXZlKSB7XG4gICAgICAgICAgICB0aGlzLmFwcGVuZCh7IGs6IGtleSwgdDogdGltZSwgbTogMSwgdjogbGl2ZS52YWx1ZSwgdzogbGl2ZS50aW1lIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hcHBlbmQoeyBrOiBrZXksIHQ6IHRpbWUsIGQ6IDEgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqIFVuZG9lcyBhIG1hcmtlZCBkZWxldGlvbjogdGhlIGtlcHQgdmFsdWUgYmVjb21lcyBsaXZlIGFnYWluLCBhcyBvZiBgdGltZWAgKGEgZnJlc2ggdGltZSwgc28gdGhlIHJlc3RvcmUgb3V0cmFua3MgdGhlIGRlbGV0aW9uIGV2ZXJ5d2hlcmUgaXQgcHJvcGFnYXRlZCkuIFJldHVybnMgZmFsc2Ugd2hlbiB0aGVyZSBpcyBubyBtYXJrZWQgdmFsdWUgdG8gcmVzdG9yZSwgb3Igc29tZXRoaW5nIGF0IGxlYXN0IGFzIG5ldyBpcyBhbHJlYWR5IGhlcmUuICovXG4gICAgcHVibGljIHVubWFyayhrZXk6IHN0cmluZywgdGltZTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIHRpbWUgPSBNYXRoLmZsb29yKHRpbWUpO1xuICAgICAgICBsZXQgdG9tYnN0b25lID0gdGhpcy5kZWxldGVkLmdldChrZXkpO1xuICAgICAgICBpZiAoIXRvbWJzdG9uZSB8fCB0b21ic3RvbmUudmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoIXRoaXMuYXBwbHlTZXQoa2V5LCB0b21ic3RvbmUudmFsdWUsIHRpbWUsIERhdGUubm93KCkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHRoaXMuYXBwZW5kKHsgazoga2V5LCB0OiB0aW1lLCB2OiB0b21ic3RvbmUudmFsdWUgfSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKiBEcm9wcyBhIG1hcmtlZCBkZWxldGlvbidzIGtlcHQgdmFsdWUgKGl0cyBoaXN0b3J5IGhhcyBiZWVuIHBoeXNpY2FsbHkgcmVtb3ZlZCksIGxlYXZpbmcgYSBwbGFpbiB0b21ic3RvbmUgd2l0aCB0aGUgc2FtZSBkZWxldGUgdGltZS4gKi9cbiAgICBwdWJsaWMgZHJvcFZhbHVlKGtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGxldCB0b21ic3RvbmUgPSB0aGlzLmRlbGV0ZWQuZ2V0KGtleSk7XG4gICAgICAgIGlmICghdG9tYnN0b25lIHx8IHRvbWJzdG9uZS52YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgICAgIHRoaXMuZGVsZXRlZC5zZXQoa2V5LCB7IHRpbWU6IHRvbWJzdG9uZS50aW1lLCBjaGFuZ2VkQXQ6IERhdGUubm93KCkgfSk7XG4gICAgICAgIHRoaXMuYXBwZW5kKHsgazoga2V5LCB0OiB0b21ic3RvbmUudGltZSwgZDogMSB9KTtcbiAgICB9XG5cbiAgICAvKiogRm9yZ2V0cyB0aGUga2V5IGVudGlyZWx5LCB0b21ic3RvbmUgaW5jbHVkZWQgLSBmb3IgYSB0b21ic3RvbmUgb2xkIGVub3VnaCB0aGF0IG5vYm9keSBuZWVkcyB0byBoZWFyIGFib3V0IHRoZSBkZWxldGlvbiBhbnkgbW9yZSwgYW5kIGZvciBhbiBlbnRyeSB0aGF0IHR1cm5lZCBvdXQgbmV2ZXIgdG8gaGF2ZSBleGlzdGVkLiBOb3QgYSBkZWxldGlvbjogaXQgbGVhdmVzIG5vdGhpbmcgYmVoaW5kIHRvIHByb3BhZ2F0ZS4gKi9cbiAgICBwdWJsaWMgcHVyZ2Uoa2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgbGV0IGhhZCA9IHRoaXMudmFsdWVzLmRlbGV0ZShrZXkpO1xuICAgICAgICBoYWQgPSB0aGlzLmRlbGV0ZWQuZGVsZXRlKGtleSkgfHwgaGFkO1xuICAgICAgICBpZiAoIWhhZCkgcmV0dXJuO1xuICAgICAgICB0aGlzLmFwcGVuZCh7IGs6IGtleSwgdDogTWF0aC5mbG9vcihEYXRlLm5vdygpKSwgcDogMSB9KTtcbiAgICB9XG5cbiAgICAvLyBUaW1lcyBhcmUgZmxvb3JlZCB0byB3aG9sZSBtaWxsaXNlY29uZHMgb24gZXZlcnkgcGF0aCBpbnRvIHRoZSBtYXBzIChsb2FkIHJlcGxheXMgdGhyb3VnaCBoZXJlIHRvbywgc28gZnJhY3Rpb25hbCB0aW1lcyBwZXJzaXN0ZWQgYnkgb2xkZXIgY29kZSBoZWFsIG9uIHN0YXJ0dXApLiBEaXNrIG10aW1lcyBjYXJyeSBmcmFjdGlvbmFsIG1pbGxpc2Vjb25kcyBidXQgdXRpbWVzIHJvdW5kLXRyaXBzIG9ubHkgd2hvbGUgb25lcywgc28gYSBmcmFjdGlvbmFsIHRpbWUgY2FuIG5ldmVyIGJlIHJlcHJvZHVjZWQgYnkgcHJvcGFnYXRpb24gLSBldmVyeSBjb3B5IG9mIHRoZSB2YWx1ZSB3b3VsZCBjb21wYXJlIFwib2xkZXJcIiB0aGFuIHRoZSBvcmlnaW5hbCBmb3JldmVyLCBhbmQgdGhlIHNhbWUgd3JpdGUgd291bGQgYmUgcmUtcHVzaGVkIGFuZCByZS1jb3BpZWQgZXZlcnkgcm91bmQuXG4gICAgcHJpdmF0ZSBhcHBseVNldChrZXk6IHN0cmluZywgdmFsdWU6IFQsIHRpbWU6IG51bWJlciwgY2hhbmdlZEF0OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgdGltZSA9IE1hdGguZmxvb3IodGltZSk7XG4gICAgICAgIGNoYW5nZWRBdCA9IE1hdGguZmxvb3IoY2hhbmdlZEF0KTtcbiAgICAgICAgaWYgKHRpbWUgPCB0aGlzLnRpbWVPZihrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHRoaXMuZGVsZXRlZC5kZWxldGUoa2V5KTtcbiAgICAgICAgdGhpcy52YWx1ZXMuc2V0KGtleSwgeyB2YWx1ZSwgdGltZSwgY2hhbmdlZEF0IH0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFwcGx5RGVsZXRlKGtleTogc3RyaW5nLCB0aW1lOiBudW1iZXIsIGNoYW5nZWRBdDogbnVtYmVyLCB2YWx1ZT86IFQsIHZhbHVlVGltZT86IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICB0aW1lID0gTWF0aC5mbG9vcih0aW1lKTtcbiAgICAgICAgY2hhbmdlZEF0ID0gTWF0aC5mbG9vcihjaGFuZ2VkQXQpO1xuICAgICAgICBpZiAodmFsdWVUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHZhbHVlVGltZSA9IE1hdGguZmxvb3IodmFsdWVUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGltZSA8IHRoaXMudGltZU9mKGtleSkpIHJldHVybiBmYWxzZTtcbiAgICAgICAgdGhpcy52YWx1ZXMuZGVsZXRlKGtleSk7XG4gICAgICAgIHRoaXMuZGVsZXRlZC5zZXQoa2V5LCB7IHRpbWUsIGNoYW5nZWRBdCwgdmFsdWUsIHZhbHVlVGltZSB9KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhcHBlbmQocmVjb3JkOiBMb2dSZWNvcmQ8VD4pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nLnB1c2goSlNPTi5zdHJpbmdpZnkocmVjb3JkKSk7XG4gICAgICAgIHRoaXMubG9nUmVjb3JkcysrO1xuICAgICAgICB0aGlzLnNjaGVkdWxlRmx1c2goKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNjaGVkdWxlRmx1c2goKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmZsdXNoVGltZXIgIT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICAgICAgICB0aGlzLmZsdXNoVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZmx1c2hUaW1lciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHZvaWQgdGhpcy5mbHVzaCgpLmNhdGNoKChlOiBFcnJvcikgPT4gY29uc29sZS5lcnJvcihgRmx1c2hpbmcgJHt0aGlzLmZpbGVQYXRofSBmYWlsZWQ6ICR7ZS5zdGFjayA/PyBlfWApKTtcbiAgICAgICAgfSwgRkxVU0hfREVMQVkpO1xuICAgICAgICAodGhpcy5mbHVzaFRpbWVyIGFzIHsgdW5yZWY/OiAoKSA9PiB2b2lkIH0pLnVucmVmPy4oKTtcbiAgICB9XG5cbiAgICAvKiogV3JpdGVzIGV2ZXJ5dGhpbmcgcGVuZGluZyAocmV3cml0aW5nIHRoZSBsb2cgZmlyc3QgaWYgaXQgaGFzIGdyb3duIHRvbyBmYXIgcGFzdCB3aGF0IGl0IGRlc2NyaWJlcykuICovXG4gICAgcHVibGljIGFzeW5jIGZsdXNoKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBsZXQgcmVzdWx0ID0gdGhpcy53cml0ZUNoYWluLnRoZW4oKCkgPT4gdGhpcy53cml0ZSgpKTtcbiAgICAgICAgLy8gVGhlIGNoYWluIG9ubHkgZXhpc3RzIHRvIHNlcmlhbGl6ZSB3cml0ZXMsIHNvIGl0IG11c3Qgbm90IHN0YXkgcmVqZWN0ZWQ6IGEgZmFpbHVyZSBiZWxvbmdzIHRvIHRoZSBjYWxsZXIgdGhhdCBhc2tlZCBmb3IgdGhpcyBmbHVzaCwgbm90IHRvIGV2ZXJ5IGZsdXNoIGFmdGVyIGl0XG4gICAgICAgIHRoaXMud3JpdGVDaGFpbiA9IHJlc3VsdC5jYXRjaCgoKSA9PiB7IH0pO1xuICAgICAgICBhd2FpdCByZXN1bHQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBkaXJlY3RvcnkgPSBsYXp5KGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgZnMucHJvbWlzZXMubWtkaXIocGF0aC5kaXJuYW1lKHRoaXMuZmlsZVBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICB9KTtcblxuICAgIHByaXZhdGUgYXN5bmMgd3JpdGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLmxvZ1JlY29yZHMgPiBNYXRoLm1heChNSU5fQ09NUEFDVF9SRUNPUkRTLCAodGhpcy52YWx1ZXMuc2l6ZSArIHRoaXMuZGVsZXRlZC5zaXplKSAqIENPTVBBQ1RfUkFUSU8pKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNvbXBhY3QoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB0aGlzLmFwcGVuZFBlbmRpbmcoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGFwcGVuZFBlbmRpbmcoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICghdGhpcy5wZW5kaW5nLmxlbmd0aCkgcmV0dXJuO1xuICAgICAgICBsZXQgcmVjb3JkcyA9IHRoaXMucGVuZGluZztcbiAgICAgICAgdGhpcy5wZW5kaW5nID0gW107XG4gICAgICAgIGF3YWl0IHRoaXMuZGlyZWN0b3J5KCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBmcy5wcm9taXNlcy5hcHBlbmRGaWxlKHRoaXMuZmlsZVBhdGgsIHJlY29yZHMuam9pbihcIlxcblwiKSArIFwiXFxuXCIpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBQdXQgdGhlbSBiYWNrIHJhdGhlciB0aGFuIGxvc2UgdGhlbTogdGhlIHZhbHVlcyBhcmUgc3RpbGwgaW4gbWVtb3J5LCBzbyBhbGwgdGhhdCBpcyBhdCByaXNrIGlzIGhhdmluZyB0byByZWJ1aWxkIHRoZW0gYnkgc2Nhbm5pbmdcbiAgICAgICAgICAgIHRoaXMucGVuZGluZyA9IHJlY29yZHMuY29uY2F0KHRoaXMucGVuZGluZyk7XG4gICAgICAgICAgICB0aGlzLnNjaGVkdWxlRmx1c2goKTtcbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZXdyaXRlcyB0aGUgbG9nIGFzIHRoZSBjdXJyZW50IGNvbnRlbnRzIG9mIGJvdGggbWFwcy4gVGhleSBhcmUgdGhlIHRydXRoIC0gdGhlIGxvZyBvbmx5IGV4aXN0cyB0byByZWJ1aWxkIHRoZW0gLSBzbyB0aGUgc25hcHNob3QgSVMgdGhlIG5ldyBsb2cuXG4gICAgcHJpdmF0ZSBhc3luYyBjb21wYWN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBsZXQgcmVjb3Jkczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgW2tleSwgZW50cnldIG9mIHRoaXMudmFsdWVzKSB7XG4gICAgICAgICAgICByZWNvcmRzLnB1c2goSlNPTi5zdHJpbmdpZnkoeyBrOiBrZXksIHQ6IGVudHJ5LnRpbWUsIHY6IGVudHJ5LnZhbHVlIH0gc2F0aXNmaWVzIExvZ1JlY29yZDxUPikpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IFtrZXksIHRvbWJzdG9uZV0gb2YgdGhpcy5kZWxldGVkKSB7XG4gICAgICAgICAgICBpZiAodG9tYnN0b25lLnZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZWNvcmRzLnB1c2goSlNPTi5zdHJpbmdpZnkoeyBrOiBrZXksIHQ6IHRvbWJzdG9uZS50aW1lLCBtOiAxLCB2OiB0b21ic3RvbmUudmFsdWUsIHc6IHRvbWJzdG9uZS52YWx1ZVRpbWUgfSBzYXRpc2ZpZXMgTG9nUmVjb3JkPFQ+KSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlY29yZHMucHVzaChKU09OLnN0cmluZ2lmeSh7IGs6IGtleSwgdDogdG9tYnN0b25lLnRpbWUsIGQ6IDEgfSBzYXRpc2ZpZXMgTG9nUmVjb3JkPFQ+KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2xlYXJlZCB3aXRoIHRoZSBzbmFwc2hvdDogZXZlcnkgcGVuZGluZyByZWNvcmQgaXMgYWxyZWFkeSByZWZsZWN0ZWQgaW4gdGhlIG1hcHMsIHNvIHRoZSBzbmFwc2hvdCBjb250YWlucyBpdC4gQW55dGhpbmcgYXBwZW5kZWQgZnJvbSBoZXJlIG9uIGlzIE5PVCBpbiB0aGUgc25hcHNob3QsIGFuZCBsYW5kcyBpbiB0aGUgbmV3IGxvZyBhZnRlciB0aGUgcmVuYW1lLlxuICAgICAgICB0aGlzLnBlbmRpbmcgPSBbXTtcbiAgICAgICAgbGV0IHN0YXJ0ZWRXaXRoID0gdGhpcy5sb2dSZWNvcmRzO1xuICAgICAgICBsZXQgdGVtcFBhdGggPSBgJHt0aGlzLmZpbGVQYXRofS5jb21wYWN0aW5nYDtcbiAgICAgICAgYXdhaXQgdGhpcy5kaXJlY3RvcnkoKTtcbiAgICAgICAgYXdhaXQgZnMucHJvbWlzZXMud3JpdGVGaWxlKHRlbXBQYXRoLCByZWNvcmRzLmxlbmd0aCAmJiBgJHtyZWNvcmRzLmpvaW4oXCJcXG5cIil9XFxuYCB8fCBcIlwiKTtcbiAgICAgICAgLy8gUmVwbGFjZXMgdGhlIG9sZCBsb2cgaW4gb25lIHN0ZXAsIHNvIGEgY3Jhc2ggbGVhdmVzIGVpdGhlciB0aGUgd2hvbGUgb2xkIGxvZyBvciB0aGUgd2hvbGUgbmV3IG9uZVxuICAgICAgICBhd2FpdCBmcy5wcm9taXNlcy5yZW5hbWUodGVtcFBhdGgsIHRoaXMuZmlsZVBhdGgpO1xuICAgICAgICB0aGlzLmxvZ1JlY29yZHMgPSByZWNvcmRzLmxlbmd0aCArIHRoaXMucGVuZGluZy5sZW5ndGg7XG4gICAgICAgIGNvbnNvbGUubG9nKGBSZXdyb3RlICR7dGhpcy5maWxlUGF0aH06ICR7c3RhcnRlZFdpdGh9IGxvZyByZWNvcmRzIGZvciAke3RoaXMudmFsdWVzLnNpemV9IHZhbHVlcyBhbmQgJHt0aGlzLmRlbGV0ZWQuc2l6ZX0gdG9tYnN0b25lc2ApO1xuICAgICAgICBhd2FpdCB0aGlzLmFwcGVuZFBlbmRpbmcoKTtcbiAgICB9XG59XG4iXX0=
255
- /* _JS_SOURCE_HASH = "d824e43ae5e10d911177de31b9bb2e17c6e004ec48884b0d208f143f8b5c643e"; */
254
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNhY3Rpb25GaWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiVHJhbnNhY3Rpb25GaWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLDRDQUFvQjtBQUNwQixnREFBd0I7QUFDeEIseURBQW1EO0FBRW5ELG9iQUFvYjtBQUNwYixFQUFFO0FBQ0Ysb0tBQW9LO0FBRXBLLCtJQUErSTtBQUMvSSxNQUFNLGFBQWEsR0FBRyxDQUFDLENBQUM7QUFDeEIsOEZBQThGO0FBQzlGLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDO0FBQ2pDLHNMQUFzTDtBQUN0TCxNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUM7QUF5QnhCLE1BQWEsZUFBZTtJQUN4QixZQUFvQixRQUFnQjtRQUFoQixhQUFRLEdBQVIsUUFBUSxDQUFRO1FBRTVCLFdBQU0sR0FBRyxJQUFJLEdBQUcsRUFBdUIsQ0FBQztRQUN4QyxZQUFPLEdBQUcsSUFBSSxHQUFHLEVBQTJCLENBQUM7UUFDckQsNEdBQTRHO1FBQ3BHLGVBQVUsR0FBRyxDQUFDLENBQUM7UUFDZixZQUFPLEdBQWEsRUFBRSxDQUFDO1FBRS9CLGdHQUFnRztRQUN4RixlQUFVLEdBQWtCLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUV0RCw4RkFBOEY7UUFDdkYsU0FBSSxHQUFHLElBQUEsY0FBSSxFQUFDLEtBQUssSUFBSSxFQUFFO1lBQzFCLElBQUksSUFBWSxDQUFDO1lBQ2pCLElBQUksQ0FBQztnQkFDRCxJQUFJLEdBQUcsTUFBTSxZQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzdELENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNULElBQUssQ0FBdUIsQ0FBQyxJQUFJLEtBQUssUUFBUTtvQkFBRSxPQUFPO2dCQUN2RCxNQUFNLENBQUMsQ0FBQztZQUNaLENBQUM7WUFDRCxJQUFJLE9BQU8sR0FBRyxD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QUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3pGLG9HQUFvRztRQUNwRyxNQUFNLFlBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDbEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBQ3ZELE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxJQUFJLENBQUMsUUFBUSxLQUFLLFdBQVcsb0JBQW9CLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxlQUFlLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxhQUFhLENBQUMsQ0FBQztRQUN2SSxNQUFNLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUMvQixDQUFDO0NBQ0o7QUFuT0QsMENBbU9DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IGxhenkgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9jYWNoaW5nXCI7XG5cbi8vIEEgcGVyc2lzdGVudCBNYXAgdGhhdCBrbm93cyBhYm91dCB0aW1lIGFuZCBhYm91dCBkZWxldGlvbnMuIEV2ZXJ5IHZhbHVlIGNhcnJpZXMgdGhlIHRpbWUgaXQgd2FzIHdyaXR0ZW4sIHNvIGEgd3JpdGUgdGhhdCBhcnJpdmVzIG91dCBvZiBvcmRlciBpcyBzaW1wbHkgbm90IGFwcGxpZWQgLSB0aGUgbWFwIGNhbm5vdCBiZSBtYWRlIHRvIGdvIGJhY2t3YXJkcy4gQSBkZWxldGVkIGtleSBrZWVwcyBpdHMgdGltZSB0b28sIGFzIGEgdG9tYnN0b25lIGluIGEgc2Vjb25kIG1hcCwgc28gXCJ3YXMgdGhpcyBkZWxldGVkLCBhbmQgd2hlblwiIGlzIGFzIGNoZWFwIHRvIGFzayBhcyBcImRvZXMgdGhpcyBleGlzdFwiLCBhbmQgZXhwaXJpbmcgb2xkIHRvbWJzdG9uZXMgaXMgYSB3YWxrIG9mIHRoZSB0b21ic3RvbmVzIGFsb25lIHJhdGhlciB0aGFuIG9mIGV2ZXJ5dGhpbmcuXG4vL1xuLy8gT24gZGlzayBpdCBpcyBvbmUgYXBwZW5kLW9ubHkgbG9nIG9mIHRoZSBzZXRzLCBkZWxldGVzIGFuZCBwdXJnZXMgdGhhdCBwcm9kdWNlZCBib3RoIG1hcHMsIHJld3JpdHRlbiBmcm9tIHRoZW0gd2hlbmV2ZXIgaXQgaGFzIGdyb3duIHRvIHNldmVyYWwgdGltZXMgdGhlaXIgc2l6ZS5cblxuLy8gVGhlIGxvZyBpcyByZXdyaXR0ZW4gb25jZSBpdCBob2xkcyB0aGlzIG1hbnkgdGltZXMgbW9yZSByZWNvcmRzIHRoYW4gdGhlcmUgYXJlIGtleXMgKGEgbG9nIG9mIDMgcmVjb3JkcyBwZXIgc3Vydml2aW5nIGtleSBpcyBtb3N0bHkgaGlzdG9yeSlcbmNvbnN0IENPTVBBQ1RfUkFUSU8gPSAzO1xuLy8gLi4uYnV0IG5ldmVyIGZvciBhIHNtYWxsIGxvZywgd2hlcmUgdGhlIHJld3JpdGUgd291bGQgY29zdCBtb3JlIHRoYW4gdGhlIGhpc3RvcnkgaXQgcmVtb3Zlc1xuY29uc3QgTUlOX0NPTVBBQ1RfUkVDT1JEUyA9IDEwMDA7XG4vLyBBcHBlbmRzIGFyZSBjb2FsZXNjZWQgZm9yIHRoaXMgbG9uZy4gQSBjcmFzaCBsb3NlcyBhdCBtb3N0IHRoaXMgbXVjaCAtIHRoZSBjYWxsZXJzIG9mIHRoaXMgY2xhc3MgdHJlYXQgdGhlaXIgZGF0YSBhcyByZWNvbnN0cnVjdGlibGUgLSBhbmQgdGhlIGFsdGVybmF0aXZlIGlzIGEgZmlsZSB3cml0ZSBwZXIgc2V0LlxuY29uc3QgRkxVU0hfREVMQVkgPSA1MDA7XG5cbi8qKiBBIGxpdmUgdmFsdWU6IHdoYXQgd2FzIHN0b3JlZCwgd2hlbiBpdCB3YXMgd3JpdHRlbiAodGhlIGNhbGxlcidzIG9yZGVyaW5nKSwgYW5kIHdoZW4gd2UgbGFzdCBjaGFuZ2VkIGl0IChvdXJzKS4gKi9cbmV4cG9ydCB0eXBlIExvZ0VudHJ5PFQ+ID0geyB2YWx1ZTogVDsgdGltZTogbnVtYmVyOyBjaGFuZ2VkQXQ6IG51bWJlciB9O1xuLyoqIEEgZGVsZXRlZCBrZXk6IHdoZW4gaXQgd2FzIGRlbGV0ZWQsIGFuZCB3aGVuIHdlIGxlYXJuZWQuIFdoZW4gdGhlIGtleSBoYWQgYSBsaXZlIHZhbHVlIGF0IGRlbGV0aW9uIHRpbWUgaXQgaXMgTUFSS0VEIHJhdGhlciB0aGFuIGdvbmUgLSB0aGUgdmFsdWUgKGFuZCBpdHMgb3JpZ2luYWwgd3JpdGUgdGltZSkgcmlkZXMgYWxvbmcsIHNvIHRoZSB1bmRlcmx5aW5nIGRhdGEgY2FuIHN0aWxsIGJlIHJlYWQgYW5kIHRoZSBkZWxldGlvbiBjYW4gYmUgdW5kb25lIChzZWUgdW5tYXJrKSB1bnRpbCB0aGUgaGlzdG9yeSBpcyBkcm9wcGVkIChzZWUgZHJvcFZhbHVlKS4gKi9cbmV4cG9ydCB0eXBlIExvZ1RvbWJzdG9uZTxUPiA9IHsgdGltZTogbnVtYmVyOyBjaGFuZ2VkQXQ6IG51bWJlcjsgdmFsdWU/OiBUOyB2YWx1ZVRpbWU/OiBudW1iZXIgfTtcblxuLy8gT25lIGxpbmUgb2YgdGhlIGxvZywgd2l0aCBzaW5nbGUtbGV0dGVyIGZpZWxkIG5hbWVzIGJlY2F1c2UgdGhlcmUgaXMgb25lIHJlY29yZCBwZXIgc2V0L2RlbGV0ZS9wdXJnZSBldmVyIG1hZGUgYW5kIHRoZSBmaWVsZCBuYW1lcyBhcmUgbW9zdCBvZiBhIHJlY29yZCdzIG92ZXJoZWFkLiBKU09OLnN0cmluZ2lmeSBlc2NhcGVzIG5ld2xpbmVzIGluc2lkZSBrZXlzIGFuZCB2YWx1ZXMsIHNvIGEgcmVjb3JkIGNhbiBuZXZlciBjb250YWluIHRoZSBzZXBhcmF0b3IuXG50eXBlIExvZ1JlY29yZDxUPiA9IHtcbiAgICAvLyBrZXlcbiAgICBrOiBzdHJpbmc7XG4gICAgLy8gdGltZSwgbGFzdE1vZGlmaWVkIHRpbWUgb2YgdGhlIGZpbGUsIG9yIHRoZSBkZWxldGUgdGltZSwgb3IgdGhlIHB1cmdlIHRpbWVcbiAgICB0OiBudW1iZXI7XG4gICAgLy8gdmFsdWVcbiAgICB2PzogVDtcbiAgICAvLyBkZWxldGVkLCB0aGUgZmlsZSBvbiBkaXNrIGlzIGRlbGV0ZWQsIHByZXNlcnZlZCB3aGVuIHdlIGNvbXBhY3RcbiAgICBkPzogMTtcbiAgICAvLyBtYXJrZWQgZm9yIGRlbGV0aW9uOiBkZWxldGVkLCBidXQgdGhlIHZhbHVlICh2KSBhbmQgaXRzIG9yaWdpbmFsIHdyaXRlIHRpbWUgKHcpIGFyZSBrZXB0LCBzbyB0aGUgZGF0YSBpcyBzdGlsbCByZWFkYWJsZSBhbmQgcmVzdG9yYWJsZS4gUHJlc2VydmVkIHdoZW4gd2UgY29tcGFjdC5cbiAgICBtPzogMTtcbiAgICAvLyB3cml0ZVRpbWUsIHRoZSBvcmlnaW5hbCB3cml0ZSB0aW1lIG9mIGEgbWFya2VkLWZvci1kZWxldGlvbiB2YWx1ZSAodCBpcyB0aGUgREVMRVRFIHRpbWUgb24gdGhvc2UgcmVjb3JkcylcbiAgICB3PzogbnVtYmVyO1xuICAgIC8vIHB1cmdlZCwgdGhlIGZpbGUgb24gZGlzayBpcyBkZWxldGVkLCBub3QgcHJlc2VydmVkIHdoZW4gd2UgY29tcGFjdFxuICAgIHA/OiAxO1xufTtcblxuZXhwb3J0IGNsYXNzIFRyYW5zYWN0aW9uRmlsZTxUPiB7XG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBmaWxlUGF0aDogc3RyaW5nKSB7IH1cblxuICAgIHByaXZhdGUgdmFsdWVzID0gbmV3IE1hcDxzdHJpbmcsIExvZ0VudHJ5PFQ+PigpO1xuICAgIHByaXZhdGUgZGVsZXRlZCA9IG5ldyBNYXA8c3RyaW5nLCBMb2dUb21ic3RvbmU8VD4+KCk7XG4gICAgLy8gUmVjb3JkcyB0aGUgbG9nIGhvbGRzICh3cml0dGVuIHBsdXMgcGVuZGluZykgLSB3aGF0IGNvbXBhY3Rpb24gaXMgZGVjaWRlZCBhZ2FpbnN0LCBOT1QgdGhlIG51bWJlciBvZiBrZXlzXG4gICAgcHJpdmF0ZSBsb2dSZWNvcmRzID0gMDtcbiAgICBwcml2YXRlIHBlbmRpbmc6IHN0cmluZ1tdID0gW107XG4gICAgcHJpdmF0ZSBmbHVzaFRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IHVuZGVmaW5lZDtcbiAgICAvLyBTZXJpYWxpemVzIGV2ZXJ5dGhpbmcgdGhhdCB0b3VjaGVzIHRoZSBmaWxlLCBzbyBhbiBhcHBlbmQgY2FuIG5ldmVyIGludGVybGVhdmUgd2l0aCBhIHJld3JpdGVcbiAgICBwcml2YXRlIHdyaXRlQ2hhaW46IFByb21pc2U8dm9pZD4gPSBQcm9taXNlLnJlc29sdmUoKTtcblxuICAgIC8qKiBSZWFkcyB0aGUgbG9nIGFuZCByZXBsYXlzIGl0IGludG8gbWVtb3J5LiBFdmVyeSBvdGhlciBtZXRob2QgYXNzdW1lcyB0aGlzIGhhcyBmaW5pc2hlZC4gKi9cbiAgICBwdWJsaWMgbG9hZCA9IGxhenkoYXN5bmMgKCkgPT4ge1xuICAgICAgICBsZXQgZGF0YTogc3RyaW5nO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZGF0YSA9IGF3YWl0IGZzLnByb21pc2VzLnJlYWRGaWxlKHRoaXMuZmlsZVBhdGgsIFwidXRmOFwiKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgaWYgKChlIGFzIHsgY29kZT86IHN0cmluZyB9KS5jb2RlID09PSBcIkVOT0VOVFwiKSByZXR1cm47XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGxldCBhcHBsaWVkID0gMDtcbiAgICAgICAgbGV0IGRhbWFnZWQgPSAwO1xuICAgICAgICBmb3IgKGxldCBsaW5lIG9mIGRhdGEuc3BsaXQoXCJcXG5cIikpIHtcbiAgICAgICAgICAgIGlmICghbGluZSkgY29udGludWU7XG4gICAgICAgICAgICBsZXQgcmVjb3JkOiBMb2dSZWNvcmQ8VD4gfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJlY29yZCA9IEpTT04ucGFyc2UobGluZSkgYXMgTG9nUmVjb3JkPFQ+O1xuICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgLy8gQSBjcmFzaCBtaWQtYXBwZW5kIGxlYXZlcyBhIHRvcm4gZmluYWwgbGluZTsgYW55dGhpbmcgZWFybGllciBtZWFucyByZWFsIGRhbWFnZS4gRWl0aGVyIHdheSB0aGUgcmVzdCBvZiB0aGUgbG9nIGlzIHN0aWxsIHdvcnRoIGhhdmluZyAtIHRoaXMgaXMgYW4gaW5kZXgsIGFuZCBzY2FubmluZyByZWJ1aWxkcyB3aGF0ZXZlciB3ZSBsb3NlLlxuICAgICAgICAgICAgICAgIGRhbWFnZWQrKztcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGFwcGxpZWQrKztcbiAgICAgICAgICAgIC8vIFJlcGxheWVkIHRocm91Z2ggdGhlIHNhbWUgb3JkZXJpbmcgcnVsZXMgdGhhdCBwcm9kdWNlZCBpdCwgc28gYSBsb2cgd3JpdHRlbiBvdXQgb2Ygb3JkZXIgc3RpbGwgbGFuZHMgb24gdGhlIHNhbWUgc3RhdGVcbiAgICAgICAgICAgIGlmIChyZWNvcmQucCkge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsdWVzLmRlbGV0ZShyZWNvcmQuayk7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWxldGVkLmRlbGV0ZShyZWNvcmQuayk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlY29yZC5tKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcHBseURlbGV0ZShyZWNvcmQuaywgcmVjb3JkLnQsIHJlY29yZC50LCByZWNvcmQudiwgcmVjb3JkLncpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChyZWNvcmQuZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlEZWxldGUocmVjb3JkLmssIHJlY29yZC50LCByZWNvcmQudCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlY29yZC52ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFwcGx5U2V0KHJlY29yZC5rLCByZWNvcmQudiwgcmVjb3JkLnQsIHJlY29yZC50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxvZ1JlY29yZHMgPSBhcHBsaWVkO1xuICAgICAgICBpZiAoZGFtYWdlZCkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHtkYW1hZ2VkfSBkYW1hZ2VkIHJlY29yZChzKSBpbiAke3RoaXMuZmlsZVBhdGh9IHdlcmUgc2tpcHBlZDsgJHthcHBsaWVkfSBhcHBsaWVkLCBsZWF2aW5nICR7dGhpcy52YWx1ZXMuc2l6ZX0gdmFsdWVzIGFuZCAke3RoaXMuZGVsZXRlZC5zaXplfSB0b21ic3RvbmVzYCk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8qKiBUaGUgbGl2ZSB2YWx1ZSwgb3IgdW5kZWZpbmVkIHdoZW4gdGhlIGtleSBkb2VzIG5vdCBleGlzdCBoZXJlIChkZWxldGVkIGluY2x1ZGVkIC0gYSBkZWxldGlvbiBpcyBhbiBhYnNlbmNlLCBzZWUgZ2V0RGVsZXRlZCBmb3IgaXRzIHRpbWUpLiAqL1xuICAgIHB1YmxpYyBnZXQoa2V5OiBzdHJpbmcpOiBMb2dFbnRyeTxUPiB8IHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlcy5nZXQoa2V5KTtcbiAgICB9XG4gICAgLyoqIFdoZW4gdGhlIGtleSB3YXMgZGVsZXRlZCwgaWYgaXQgd2FzICh2YWx1ZSBpbmNsdWRlZCB3aGVuIHRoZSBkZWxldGlvbiBpcyBzdGlsbCBtYXJrZWQgLSBzZWUgTG9nVG9tYnN0b25lKS4gQWJzZW50IGJvdGggaGVyZSBhbmQgaW4gZ2V0IG1lYW5zIHdlIGhhdmUgbmV2ZXIgaGVhcmQgb2YgaXQuICovXG4gICAgcHVibGljIGdldERlbGV0ZWQoa2V5OiBzdHJpbmcpOiBMb2dUb21ic3RvbmU8VD4gfCB1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gdGhpcy5kZWxldGVkLmdldChrZXkpO1xuICAgIH1cbiAgICAvKiogVGhlIHRpbWUgdGhlIGtleSBsYXN0IGNoYW5nZWQgZWl0aGVyIHdheSwgb3IgMCBpZiB3ZSBoYXZlIG5ldmVyIGhlYXJkIG9mIGl0IC0gd2hhdCBhIG5ldyB3cml0ZSBoYXMgdG8gYmVhdC4gKi9cbiAgICBwdWJsaWMgdGltZU9mKGtleTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IGxpdmUgPSB0aGlzLnZhbHVlcy5nZXQoa2V5KTtcbiAgICAgICAgaWYgKGxpdmUpIHJldHVybiBsaXZlLnRpbWU7XG4gICAgICAgIHJldHVybiB0aGlzLmRlbGV0ZWQuZ2V0KGtleSk/LnRpbWUgfHwgMDtcbiAgICB9XG5cbiAgICAvKiogTygxKSwgYW5kIGNvdW50cyBvbmx5IHdoYXQgZXhpc3RzLiAqL1xuICAgIHB1YmxpYyBnZXQgc2l6ZSgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZXMuc2l6ZTtcbiAgICB9XG4gICAgcHVibGljIGdldCBkZWxldGVkU2l6ZSgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5kZWxldGVkLnNpemU7XG4gICAgfVxuICAgIC8qKiBMaXZlIHZhbHVlcyBvbmx5LiBMaXZlLCBpbiBpbnNlcnRpb24gb3JkZXIgLSBkZWxldGluZyBkdXJpbmcgaXRlcmF0aW9uIGlzIHNhZmUgKEpTIHNraXBzIGVudHJpZXMgcmVtb3ZlZCBiZWZvcmUgdGhleSBhcmUgcmVhY2hlZCksIHdoaWNoIGlzIHdoYXQgdGhlIHBhc3NlcyB0aGF0IHdhbGsgZXZlcnl0aGluZyBhbmQgcHJ1bmUgYXMgdGhleSBnbyByZWx5IG9uLiAqL1xuICAgIHB1YmxpYyBlbnRyaWVzKCk6IEl0ZXJhYmxlSXRlcmF0b3I8W3N0cmluZywgTG9nRW50cnk8VD5dPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlcy5lbnRyaWVzKCk7XG4gICAgfVxuICAgIC8qKiBUaGUgdG9tYnN0b25lcywgd2hpY2ggaXMgYSBtdWNoIHNtYWxsZXIgd2FsayB0aGFuIHRoZSB2YWx1ZXMgLSBzbyBleHBpcmluZyB0aGVtLCBvciBsaXN0aW5nIHdoYXQgd2FzIGRlbGV0ZWQgc2luY2Ugc29tZSB0aW1lLCBjb3N0cyB3aGF0IGl0IHNob3VsZC4gKi9cbiAgICBwdWJsaWMgZGVsZXRlZEVudHJpZXMoKTogSXRlcmFibGVJdGVyYXRvcjxbc3RyaW5nLCBMb2dUb21ic3RvbmU8VD5dPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmRlbGV0ZWQuZW50cmllcygpO1xuICAgIH1cblxuICAgIC8qKiBTdG9yZXMgYSB2YWx1ZSBhcyBvZiBgdGltZWAgKHJvdW5kZWQgdG8gd2hvbGUgbWlsbGlzZWNvbmRzIC0gc2VlIGFwcGx5U2V0KS4gUmV0dXJucyBmYWxzZSB3aGVuIHNvbWV0aGluZyBhdCBsZWFzdCBhcyBuZXcgaXMgYWxyZWFkeSBoZXJlLCBpbiB3aGljaCBjYXNlIG5vdGhpbmcgY2hhbmdlZCAtIGFuIG91dC1vZi1vcmRlciB3cml0ZSBpcyBub3QgYW4gZXJyb3IsIGl0IGlzIGp1c3QgbGF0ZS4gKi9cbiAgICBwdWJsaWMgc2V0KGtleTogc3RyaW5nLCB2YWx1ZTogVCwgdGltZTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIHRpbWUgPSBNYXRoLnJvdW5kKHRpbWUpO1xuICAgICAgICBpZiAoIXRoaXMuYXBwbHlTZXQoa2V5LCB2YWx1ZSwgdGltZSwgRGF0ZS5ub3coKSkpIHJldHVybiBmYWxzZTtcbiAgICAgICAgdGhpcy5hcHBlbmQoeyBrOiBrZXksIHQ6IHRpbWUsIHY6IHZhbHVlIH0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKiogRGVsZXRlcyBhcyBvZiBgdGltZWAsIGtlZXBpbmcgdGhlIHRvbWJzdG9uZS4gQSBrZXkgdGhhdCBoYWQgYSBsaXZlIHZhbHVlIGtlZXBzIGl0IGluIHRoZSB0b21ic3RvbmUgYXMgTUFSS0VEIGZvciBkZWxldGlvbiAocmVhZGFibGUgYW5kIHJlc3RvcmFibGUgdW50aWwgZHJvcFZhbHVlKS4gUmV0dXJucyBmYWxzZSB3aGVuIHNvbWV0aGluZyBhdCBsZWFzdCBhcyBuZXcgaXMgYWxyZWFkeSBoZXJlLiAqL1xuICAgIHB1YmxpYyBkZWxldGUoa2V5OiBzdHJpbmcsIHRpbWU6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICB0aW1lID0gTWF0aC5yb3VuZCh0aW1lKTtcbiAgICAgICAgbGV0IGxpdmUgPSB0aGlzLnZhbHVlcy5nZXQoa2V5KTtcbiAgICAgICAgaWYgKCF0aGlzLmFwcGx5RGVsZXRlKGtleSwgdGltZSwgRGF0ZS5ub3coKSwgbGl2ZT8udmFsdWUsIGxpdmU/LnRpbWUpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChsaXZlKSB7XG4gICAgICAgICAgICB0aGlzLmFwcGVuZCh7IGs6IGtleSwgdDogdGltZSwgbTogMSwgdjogbGl2ZS52YWx1ZSwgdzogbGl2ZS50aW1lIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hcHBlbmQoeyBrOiBrZXksIHQ6IHRpbWUsIGQ6IDEgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqIFVuZG9lcyBhIG1hcmtlZCBkZWxldGlvbjogdGhlIGtlcHQgdmFsdWUgYmVjb21lcyBsaXZlIGFnYWluLCBhcyBvZiBgdGltZWAgKGEgZnJlc2ggdGltZSwgc28gdGhlIHJlc3RvcmUgb3V0cmFua3MgdGhlIGRlbGV0aW9uIGV2ZXJ5d2hlcmUgaXQgcHJvcGFnYXRlZCkuIFJldHVybnMgZmFsc2Ugd2hlbiB0aGVyZSBpcyBubyBtYXJrZWQgdmFsdWUgdG8gcmVzdG9yZSwgb3Igc29tZXRoaW5nIGF0IGxlYXN0IGFzIG5ldyBpcyBhbHJlYWR5IGhlcmUuICovXG4gICAgcHVibGljIHVubWFyayhrZXk6IHN0cmluZywgdGltZTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIHRpbWUgPSBNYXRoLnJvdW5kKHRpbWUpO1xuICAgICAgICBsZXQgdG9tYnN0b25lID0gdGhpcy5kZWxldGVkLmdldChrZXkpO1xuICAgICAgICBpZiAoIXRvbWJzdG9uZSB8fCB0b21ic3RvbmUudmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoIXRoaXMuYXBwbHlTZXQoa2V5LCB0b21ic3RvbmUudmFsdWUsIHRpbWUsIERhdGUubm93KCkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHRoaXMuYXBwZW5kKHsgazoga2V5LCB0OiB0aW1lLCB2OiB0b21ic3RvbmUudmFsdWUgfSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKiBEcm9wcyBhIG1hcmtlZCBkZWxldGlvbidzIGtlcHQgdmFsdWUgKGl0cyBoaXN0b3J5IGhhcyBiZWVuIHBoeXNpY2FsbHkgcmVtb3ZlZCksIGxlYXZpbmcgYSBwbGFpbiB0b21ic3RvbmUgd2l0aCB0aGUgc2FtZSBkZWxldGUgdGltZS4gKi9cbiAgICBwdWJsaWMgZHJvcFZhbHVlKGtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGxldCB0b21ic3RvbmUgPSB0aGlzLmRlbGV0ZWQuZ2V0KGtleSk7XG4gICAgICAgIGlmICghdG9tYnN0b25lIHx8IHRvbWJzdG9uZS52YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgICAgIHRoaXMuZGVsZXRlZC5zZXQoa2V5LCB7IHRpbWU6IHRvbWJzdG9uZS50aW1lLCBjaGFuZ2VkQXQ6IERhdGUubm93KCkgfSk7XG4gICAgICAgIHRoaXMuYXBwZW5kKHsgazoga2V5LCB0OiB0b21ic3RvbmUudGltZSwgZDogMSB9KTtcbiAgICB9XG5cbiAgICAvKiogRm9yZ2V0cyB0aGUga2V5IGVudGlyZWx5LCB0b21ic3RvbmUgaW5jbHVkZWQgLSBmb3IgYSB0b21ic3RvbmUgb2xkIGVub3VnaCB0aGF0IG5vYm9keSBuZWVkcyB0byBoZWFyIGFib3V0IHRoZSBkZWxldGlvbiBhbnkgbW9yZSwgYW5kIGZvciBhbiBlbnRyeSB0aGF0IHR1cm5lZCBvdXQgbmV2ZXIgdG8gaGF2ZSBleGlzdGVkLiBOb3QgYSBkZWxldGlvbjogaXQgbGVhdmVzIG5vdGhpbmcgYmVoaW5kIHRvIHByb3BhZ2F0ZS4gKi9cbiAgICBwdWJsaWMgcHVyZ2Uoa2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgbGV0IGhhZCA9IHRoaXMudmFsdWVzLmRlbGV0ZShrZXkpO1xuICAgICAgICBoYWQgPSB0aGlzLmRlbGV0ZWQuZGVsZXRlKGtleSkgfHwgaGFkO1xuICAgICAgICBpZiAoIWhhZCkgcmV0dXJuO1xuICAgICAgICB0aGlzLmFwcGVuZCh7IGs6IGtleSwgdDogTWF0aC5yb3VuZChEYXRlLm5vdygpKSwgcDogMSB9KTtcbiAgICB9XG5cbiAgICAvLyBUaW1lcyBhcmUgUk9VTkRFRCB0byB3aG9sZSBtaWxsaXNlY29uZHMgb24gZXZlcnkgcGF0aCBpbnRvIHRoZSBtYXBzIChsb2FkIHJlcGxheXMgdGhyb3VnaCBoZXJlIHRvbywgc28gZnJhY3Rpb25hbCB0aW1lcyBwZXJzaXN0ZWQgYnkgb2xkZXIgY29kZSBoZWFsIG9uIHN0YXJ0dXApLiBEaXNrIG10aW1lcyBjYXJyeSBmcmFjdGlvbmFsIG1pbGxpc2Vjb25kcyBidXQgdXRpbWVzIHJvdW5kLXRyaXBzIG9ubHkgd2hvbGUgb25lcywgc28gYSBmcmFjdGlvbmFsIHRpbWUgY2FuIG5ldmVyIGJlIHJlcHJvZHVjZWQgYnkgcHJvcGFnYXRpb24gLSBldmVyeSBjb3B5IG9mIHRoZSB2YWx1ZSB3b3VsZCBjb21wYXJlIFwib2xkZXJcIiB0aGFuIHRoZSBvcmlnaW5hbCBmb3JldmVyLCBhbmQgdGhlIHNhbWUgd3JpdGUgd291bGQgYmUgcmUtcHVzaGVkIGFuZCByZS1jb3BpZWQgZXZlcnkgcm91bmQuIFJvdW5kIHJhdGhlciB0aGFuIGZsb29yLCB0byBtYXRjaCBBcmNoaXZlc0Rpc2sgKHNlZSBpdHMgZ2V0Mik6IHV0aW1lcyBnb2VzIHRocm91Z2ggYSBzZWNvbmRzIGRvdWJsZSBhbmQgY2FuIGxhbmQgYSBoYWlyIGJlbG93IHRoZSBzdGFtcGVkIG1pbGxpc2Vjb25kLlxuICAgIHByaXZhdGUgYXBwbHlTZXQoa2V5OiBzdHJpbmcsIHZhbHVlOiBULCB0aW1lOiBudW1iZXIsIGNoYW5nZWRBdDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIHRpbWUgPSBNYXRoLnJvdW5kKHRpbWUpO1xuICAgICAgICBjaGFuZ2VkQXQgPSBNYXRoLnJvdW5kKGNoYW5nZWRBdCk7XG4gICAgICAgIGlmICh0aW1lIDwgdGhpcy50aW1lT2Yoa2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICB0aGlzLmRlbGV0ZWQuZGVsZXRlKGtleSk7XG4gICAgICAgIHRoaXMudmFsdWVzLnNldChrZXksIHsgdmFsdWUsIHRpbWUsIGNoYW5nZWRBdCB9KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhcHBseURlbGV0ZShrZXk6IHN0cmluZywgdGltZTogbnVtYmVyLCBjaGFuZ2VkQXQ6IG51bWJlciwgdmFsdWU/OiBULCB2YWx1ZVRpbWU/OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgdGltZSA9IE1hdGgucm91bmQodGltZSk7XG4gICAgICAgIGNoYW5nZWRBdCA9IE1hdGgucm91bmQoY2hhbmdlZEF0KTtcbiAgICAgICAgaWYgKHZhbHVlVGltZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB2YWx1ZVRpbWUgPSBNYXRoLnJvdW5kKHZhbHVlVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRpbWUgPCB0aGlzLnRpbWVPZihrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHRoaXMudmFsdWVzLmRlbGV0ZShrZXkpO1xuICAgICAgICB0aGlzLmRlbGV0ZWQuc2V0KGtleSwgeyB0aW1lLCBjaGFuZ2VkQXQsIHZhbHVlLCB2YWx1ZVRpbWUgfSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXBwZW5kKHJlY29yZDogTG9nUmVjb3JkPFQ+KTogdm9pZCB7XG4gICAgICAgIHRoaXMucGVuZGluZy5wdXNoKEpTT04uc3RyaW5naWZ5KHJlY29yZCkpO1xuICAgICAgICB0aGlzLmxvZ1JlY29yZHMrKztcbiAgICAgICAgdGhpcy5zY2hlZHVsZUZsdXNoKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzY2hlZHVsZUZsdXNoKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5mbHVzaFRpbWVyICE9PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICAgICAgdGhpcy5mbHVzaFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmZsdXNoVGltZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB2b2lkIHRoaXMuZmx1c2goKS5jYXRjaCgoZTogRXJyb3IpID0+IGNvbnNvbGUuZXJyb3IoYEZsdXNoaW5nICR7dGhpcy5maWxlUGF0aH0gZmFpbGVkOiAke2Uuc3RhY2sgPz8gZX1gKSk7XG4gICAgICAgIH0sIEZMVVNIX0RFTEFZKTtcbiAgICAgICAgKHRoaXMuZmx1c2hUaW1lciBhcyB7IHVucmVmPzogKCkgPT4gdm9pZCB9KS51bnJlZj8uKCk7XG4gICAgfVxuXG4gICAgLyoqIFdyaXRlcyBldmVyeXRoaW5nIHBlbmRpbmcgKHJld3JpdGluZyB0aGUgbG9nIGZpcnN0IGlmIGl0IGhhcyBncm93biB0b28gZmFyIHBhc3Qgd2hhdCBpdCBkZXNjcmliZXMpLiAqL1xuICAgIHB1YmxpYyBhc3luYyBmbHVzaCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IHRoaXMud3JpdGVDaGFpbi50aGVuKCgpID0+IHRoaXMud3JpdGUoKSk7XG4gICAgICAgIC8vIFRoZSBjaGFpbiBvbmx5IGV4aXN0cyB0byBzZXJpYWxpemUgd3JpdGVzLCBzbyBpdCBtdXN0IG5vdCBzdGF5IHJlamVjdGVkOiBhIGZhaWx1cmUgYmVsb25ncyB0byB0aGUgY2FsbGVyIHRoYXQgYXNrZWQgZm9yIHRoaXMgZmx1c2gsIG5vdCB0byBldmVyeSBmbHVzaCBhZnRlciBpdFxuICAgICAgICB0aGlzLndyaXRlQ2hhaW4gPSByZXN1bHQuY2F0Y2goKCkgPT4geyB9KTtcbiAgICAgICAgYXdhaXQgcmVzdWx0O1xuICAgIH1cblxuICAgIHByaXZhdGUgZGlyZWN0b3J5ID0gbGF6eShhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IGZzLnByb21pc2VzLm1rZGlyKHBhdGguZGlybmFtZSh0aGlzLmZpbGVQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgfSk7XG5cbiAgICBwcml2YXRlIGFzeW5jIHdyaXRlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAodGhpcy5sb2dSZWNvcmRzID4gTWF0aC5tYXgoTUlOX0NPTVBBQ1RfUkVDT1JEUywgKHRoaXMudmFsdWVzLnNpemUgKyB0aGlzLmRlbGV0ZWQuc2l6ZSkgKiBDT01QQUNUX1JBVElPKSkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jb21wYWN0KCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgdGhpcy5hcHBlbmRQZW5kaW5nKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBhcHBlbmRQZW5kaW5nKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoIXRoaXMucGVuZGluZy5sZW5ndGgpIHJldHVybjtcbiAgICAgICAgbGV0IHJlY29yZHMgPSB0aGlzLnBlbmRpbmc7XG4gICAgICAgIHRoaXMucGVuZGluZyA9IFtdO1xuICAgICAgICBhd2FpdCB0aGlzLmRpcmVjdG9yeSgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgZnMucHJvbWlzZXMuYXBwZW5kRmlsZSh0aGlzLmZpbGVQYXRoLCByZWNvcmRzLmpvaW4oXCJcXG5cIikgKyBcIlxcblwiKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgLy8gUHV0IHRoZW0gYmFjayByYXRoZXIgdGhhbiBsb3NlIHRoZW06IHRoZSB2YWx1ZXMgYXJlIHN0aWxsIGluIG1lbW9yeSwgc28gYWxsIHRoYXQgaXMgYXQgcmlzayBpcyBoYXZpbmcgdG8gcmVidWlsZCB0aGVtIGJ5IHNjYW5uaW5nXG4gICAgICAgICAgICB0aGlzLnBlbmRpbmcgPSByZWNvcmRzLmNvbmNhdCh0aGlzLnBlbmRpbmcpO1xuICAgICAgICAgICAgdGhpcy5zY2hlZHVsZUZsdXNoKCk7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmV3cml0ZXMgdGhlIGxvZyBhcyB0aGUgY3VycmVudCBjb250ZW50cyBvZiBib3RoIG1hcHMuIFRoZXkgYXJlIHRoZSB0cnV0aCAtIHRoZSBsb2cgb25seSBleGlzdHMgdG8gcmVidWlsZCB0aGVtIC0gc28gdGhlIHNuYXBzaG90IElTIHRoZSBuZXcgbG9nLlxuICAgIHByaXZhdGUgYXN5bmMgY29tcGFjdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgbGV0IHJlY29yZHM6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGZvciAobGV0IFtrZXksIGVudHJ5XSBvZiB0aGlzLnZhbHVlcykge1xuICAgICAgICAgICAgcmVjb3Jkcy5wdXNoKEpTT04uc3RyaW5naWZ5KHsgazoga2V5LCB0OiBlbnRyeS50aW1lLCB2OiBlbnRyeS52YWx1ZSB9IHNhdGlzZmllcyBMb2dSZWNvcmQ8VD4pKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBba2V5LCB0b21ic3RvbmVdIG9mIHRoaXMuZGVsZXRlZCkge1xuICAgICAgICAgICAgaWYgKHRvbWJzdG9uZS52YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmVjb3Jkcy5wdXNoKEpTT04uc3RyaW5naWZ5KHsgazoga2V5LCB0OiB0b21ic3RvbmUudGltZSwgbTogMSwgdjogdG9tYnN0b25lLnZhbHVlLCB3OiB0b21ic3RvbmUudmFsdWVUaW1lIH0gc2F0aXNmaWVzIExvZ1JlY29yZDxUPikpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNvcmRzLnB1c2goSlNPTi5zdHJpbmdpZnkoeyBrOiBrZXksIHQ6IHRvbWJzdG9uZS50aW1lLCBkOiAxIH0gc2F0aXNmaWVzIExvZ1JlY29yZDxUPikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIENsZWFyZWQgd2l0aCB0aGUgc25hcHNob3Q6IGV2ZXJ5IHBlbmRpbmcgcmVjb3JkIGlzIGFscmVhZHkgcmVmbGVjdGVkIGluIHRoZSBtYXBzLCBzbyB0aGUgc25hcHNob3QgY29udGFpbnMgaXQuIEFueXRoaW5nIGFwcGVuZGVkIGZyb20gaGVyZSBvbiBpcyBOT1QgaW4gdGhlIHNuYXBzaG90LCBhbmQgbGFuZHMgaW4gdGhlIG5ldyBsb2cgYWZ0ZXIgdGhlIHJlbmFtZS5cbiAgICAgICAgdGhpcy5wZW5kaW5nID0gW107XG4gICAgICAgIGxldCBzdGFydGVkV2l0aCA9IHRoaXMubG9nUmVjb3JkcztcbiAgICAgICAgbGV0IHRlbXBQYXRoID0gYCR7dGhpcy5maWxlUGF0aH0uY29tcGFjdGluZ2A7XG4gICAgICAgIGF3YWl0IHRoaXMuZGlyZWN0b3J5KCk7XG4gICAgICAgIGF3YWl0IGZzLnByb21pc2VzLndyaXRlRmlsZSh0ZW1wUGF0aCwgcmVjb3Jkcy5sZW5ndGggJiYgYCR7cmVjb3Jkcy5qb2luKFwiXFxuXCIpfVxcbmAgfHwgXCJcIik7XG4gICAgICAgIC8vIFJlcGxhY2VzIHRoZSBvbGQgbG9nIGluIG9uZSBzdGVwLCBzbyBhIGNyYXNoIGxlYXZlcyBlaXRoZXIgdGhlIHdob2xlIG9sZCBsb2cgb3IgdGhlIHdob2xlIG5ldyBvbmVcbiAgICAgICAgYXdhaXQgZnMucHJvbWlzZXMucmVuYW1lKHRlbXBQYXRoLCB0aGlzLmZpbGVQYXRoKTtcbiAgICAgICAgdGhpcy5sb2dSZWNvcmRzID0gcmVjb3Jkcy5sZW5ndGggKyB0aGlzLnBlbmRpbmcubGVuZ3RoO1xuICAgICAgICBjb25zb2xlLmxvZyhgUmV3cm90ZSAke3RoaXMuZmlsZVBhdGh9OiAke3N0YXJ0ZWRXaXRofSBsb2cgcmVjb3JkcyBmb3IgJHt0aGlzLnZhbHVlcy5zaXplfSB2YWx1ZXMgYW5kICR7dGhpcy5kZWxldGVkLnNpemV9IHRvbWJzdG9uZXNgKTtcbiAgICAgICAgYXdhaXQgdGhpcy5hcHBlbmRQZW5kaW5nKCk7XG4gICAgfVxufVxuIl19
255
+ /* _JS_SOURCE_HASH = "486c49e162e79d8a7f9efcfb6e329d66add50298027f9b02f626298237eae8ff"; */
@@ -6,7 +6,7 @@ const storageLogs_1 = require("./remoteStorage/storageLogs");
6
6
  // Cross-archive file operations built ON TOP of IArchives (copy, move) - helpers over the interface, not part of it, so they live beside it rather than in it.
7
7
  const LARGE_COPY_THRESHOLD = 64 * 1024 * 1024;
8
8
  const LARGE_COPY_CHUNK = 32 * 1024 * 1024;
9
- /** Copies one file between two archives. The source's CURRENT size and write time always come from getInfo right here - callers never supply them, because a stale size turns into ranged reads of a file that has changed (failing forever), and a stale write time re-orders history. Small files go as a single get2+set; past LARGE_COPY_THRESHOLD the copy streams through setLargeFile in LARGE_COPY_CHUNK ranged reads, so the whole file is never in memory. Returns the copied file's info, and undefined for every way the copy did NOT land: the source doesn't have the file, the destination already had a NEWER file (refused up front rather than roll it back), or the destination silently dropped the write (its own only-take-latest won a race we lost - caught by confirming with getInfo afterward). The refused/dropped cases are logged as errors; a caller that treats undefined as "missing at the source" must getInfo the destination to learn the actual latest value. */
9
+ /** Copies one file between two archives. The source's CURRENT size and write time always come from getInfo right here - callers never supply them, because a stale size turns into ranged reads of a file that has changed (failing forever), and a stale write time re-orders history. Small files go as a single get2+set; past LARGE_COPY_THRESHOLD the copy streams through setLargeFile in LARGE_COPY_CHUNK ranged reads, so the whole file is never in memory. Returns the copied file's info, and undefined for every way the copy did NOT land: the source doesn't have the file, and with preserveWriteTime the two guarded cases - the destination already held something NEWER (refused up front rather than roll it back), or the destination silently dropped the write (its own only-take-latest won a race we lost - caught by confirming with getInfo afterward). The refused/dropped cases are logged as errors; a caller that treats undefined as "missing at the source" must getInfo the destination to learn the actual latest value. */
10
10
  async function copyArchiveFile(config) {
11
11
  let { from, to, path } = config;
12
12
  let toPath = config.toPath || path;
@@ -14,14 +14,15 @@ async function copyArchiveFile(config) {
14
14
  if (!info)
15
15
  return undefined;
16
16
  let size = info.size;
17
- // internal (synchronization between replicas of the same key) preserves the source's write time, so ordering survives propagation. A plain copy is a NEW write and is stamped now: the source's old stamp would make it LOSE to any newer write or tombstone at the destination, silently - move a file back to a folder it was deleted from and the copy is dropped, then the caller deletes the source, and the file is gone entirely.
18
- let writeTime = Math.floor(config.internal && info.writeTime || Date.now());
19
- // A destination that already holds a NEWER file must not be overwritten with our older one - and the destination's own only-take-latest would drop the write SILENTLY, leaving the caller believing the copy happened. Refusing here, loudly, is what turns "the remote has something we missed" from a masked bug into a log line the caller can act on.
20
- let destInfo = await to.getInfo(toPath, { noFallbacks: config.noFallbacks });
21
- // Compared at whole-millisecond precision, here and at the confirm below: disk mtimes carry fractional milliseconds, but utimes round-trips only whole ones, so sub-millisecond differences are storage artifacts of the SAME time, not ordering
22
- if (destInfo && Math.floor(destInfo.writeTime) > Math.floor(writeTime)) {
23
- (0, storageLogs_1.logStorageError)(`Copy refused - a newer file exists at the destination. Refusing to copy ${JSON.stringify(path)} from ${from.getDebugName()} to ${to.getDebugName()}${toPath !== path && ` (as ${JSON.stringify(toPath)})` || ""}: ours ${size} bytes at ${(0, format_1.formatDateTimeDetailed)(writeTime)}, theirs ${destInfo.size} bytes at ${(0, format_1.formatDateTimeDetailed)(destInfo.writeTime)} - copying would roll it back`);
24
- return undefined;
17
+ let writeTime = Math.round(config.preserveWriteTime && info.writeTime || Date.now());
18
+ if (config.preserveWriteTime) {
19
+ // A destination that already holds a NEWER file must not be overwritten with our older one - and the destination's own only-take-latest would drop the write SILENTLY, leaving the caller believing the copy happened. Refusing here, loudly, is what turns "the remote has something we missed" from a masked bug into a log line the caller can act on. (A fresh-stamped copy needs no such guard - nothing at the destination can be newer than now - so plain copies skip the round trip.)
20
+ let destInfo = await to.getInfo(toPath, { noFallbacks: config.noFallbacks });
21
+ // Compared at whole-millisecond precision (ROUNDED, matching ArchivesDisk - see its get2), here and at the confirm below: disk mtimes carry fractional milliseconds, but utimes round-trips only whole ones, so sub-millisecond differences are storage artifacts of the SAME time, not ordering
22
+ if (destInfo && Math.round(destInfo.writeTime) > Math.round(writeTime)) {
23
+ (0, storageLogs_1.logStorageError)(`Copy refused - a newer file exists at the destination. Refusing to copy ${JSON.stringify(path)} from ${from.getDebugName()} to ${to.getDebugName()}${toPath !== path && ` (as ${JSON.stringify(toPath)})` || ""}: ours ${size} bytes at ${(0, format_1.formatDateTimeDetailed)(writeTime)}, theirs ${destInfo.size} bytes at ${(0, format_1.formatDateTimeDetailed)(destInfo.writeTime)} - copying would roll it back`);
24
+ return undefined;
25
+ }
25
26
  }
26
27
  let copiedSize;
27
28
  if (size <= LARGE_COPY_THRESHOLD) {
@@ -59,11 +60,13 @@ async function copyArchiveFile(config) {
59
60
  });
60
61
  copiedSize = totalSize;
61
62
  }
62
- // Every backend drops a superseded write SILENTLY (its only-take-latest is the last line of defense against races the up-front check can't see), so a returned set is not proof the copy landed - only the destination reporting the file at OUR time or newer is. Newer also counts as landed: the destination is at least as new as what we pushed (and b2 always stamps its own, later, upload time).
63
- let confirmed = await to.getInfo(toPath, { noFallbacks: config.noFallbacks });
64
- if (!confirmed || Math.floor(confirmed.writeTime) < Math.floor(writeTime)) {
65
- (0, storageLogs_1.logStorageError)(`Copy was silently dropped by the destination. Copy of ${JSON.stringify(path)} from ${from.getDebugName()} to ${to.getDebugName()}${toPath !== path && ` (as ${JSON.stringify(toPath)})` || ""}: our copy was ${copiedSize} bytes at ${(0, format_1.formatDateTimeDetailed)(writeTime)}, but the destination reports ${confirmed && `${confirmed.size} bytes at ${(0, format_1.formatDateTimeDetailed)(confirmed.writeTime)}` || "nothing"} (a newer write or deletion won the race)`);
66
- return undefined;
63
+ if (config.preserveWriteTime) {
64
+ // Every backend drops a superseded write SILENTLY (its only-take-latest is the last line of defense against races the up-front check can't see), so a returned set is not proof the copy landed - only the destination reporting the file at OUR time or newer is. Newer also counts as landed: the destination is at least as new as what we pushed (and b2 always stamps its own, later, upload time). Only for preserved stamps: a fresh stamp cannot lose the race, and moveArchiveFile does its own confirm before deleting anything.
65
+ let confirmed = await to.getInfo(toPath, { noFallbacks: config.noFallbacks });
66
+ if (!confirmed || Math.round(confirmed.writeTime) < Math.round(writeTime)) {
67
+ (0, storageLogs_1.logStorageError)(`Copy was silently dropped by the destination. Copy of ${JSON.stringify(path)} from ${from.getDebugName()} to ${to.getDebugName()}${toPath !== path && ` (as ${JSON.stringify(toPath)})` || ""}: our copy was ${copiedSize} bytes at ${(0, format_1.formatDateTimeDetailed)(writeTime)}, but the destination reports ${confirmed && `${confirmed.size} bytes at ${(0, format_1.formatDateTimeDetailed)(confirmed.writeTime)}` || "nothing"} (a newer write or deletion won the race)`);
68
+ return undefined;
69
+ }
67
70
  }
68
71
  return { writeTime, size: copiedSize };
69
72
  }
@@ -104,5 +107,5 @@ async function moveArchiveFile(config) {
104
107
  await from.del(path);
105
108
  }
106
109
  exports.moveArchiveFile = moveArchiveFile;
107
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJjaGl2ZUhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJhcmNoaXZlSGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxrRUFBK0U7QUFDL0UsNkRBQThEO0FBRTlELCtKQUErSjtBQUUvSixNQUFNLG9CQUFvQixHQUFHLEVBQUUsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQzlDLE1BQU0sZ0JBQWdCLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFFMUMsdThCQUF1OEI7QUFDaDhCLEtBQUssVUFBVSxlQUFlLENBQUMsTUFVckM7SUFDRyxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxNQUFNLENBQUM7SUFDaEMsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUM7SUFDbkMsSUFBSSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUN6RSxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQzVCLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDckIseWFBQXlhO0lBQ3phLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQzVFLDBWQUEwVjtJQUMxVixJQUFJLFFBQVEsR0FBRyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQzdFLGlQQUFpUDtJQUNqUCxJQUFJLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FB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LENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLFlBQVksRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO0lBQ2hJLENBQUM7SUFDRCxJQUFJLFNBQVMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQzlFLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNiLE1BQU0sSUFBSSxLQUFLLENBQUMsdUVBQXVFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLFlBQVksRUFBRSxzQkFBc0IsRUFBRSxDQUFDLFlBQVksRUFBRSxvQkFBb0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsdURBQXVELENBQUMsQ0FBQztJQUNyUixDQUFDO0lBQ0QsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3pCLENBQUM7QUEvQkQsMENBK0JDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gVHlwZS1vbmx5OiBJQXJjaGl2ZXMudHMgcmUtZXhwb3J0cyBvdXIgZnVuY3Rpb25zLCBzbyBhIHZhbHVlIGltcG9ydCBiYWNrIGF0IGl0IHdvdWxkIGJlIGEgcmVxdWlyZSBjeWNsZVxuaW1wb3J0IHR5cGUgeyBJQXJjaGl2ZXMgfSBmcm9tIFwiLi9JQXJjaGl2ZXNcIjtcbmltcG9ydCB7IGZvcm1hdERhdGVUaW1lRGV0YWlsZWQgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9mb3JtYXR0aW5nL2Zvcm1hdFwiO1xuaW1wb3J0IHsgbG9nU3RvcmFnZUVycm9yIH0gZnJvbSBcIi4vcmVtb3RlU3RvcmFnZS9zdG9yYWdlTG9nc1wiO1xuXG4vLyBDcm9zcy1hcmNoaXZlIGZpbGUgb3BlcmF0aW9ucyBidWlsdCBPTiBUT1Agb2YgSUFyY2hpdmVzIChjb3B5LCBtb3ZlKSAtIGhlbHBlcnMgb3ZlciB0aGUgaW50ZXJmYWNlLCBub3QgcGFydCBvZiBpdCwgc28gdGhleSBsaXZlIGJlc2lkZSBpdCByYXRoZXIgdGhhbiBpbiBpdC5cblxuY29uc3QgTEFSR0VfQ09QWV9USFJFU0hPTEQgPSA2NCAqIDEwMjQgKiAxMDI0O1xuY29uc3QgTEFSR0VfQ09QWV9DSFVOSyA9IDMyICogMTAyNCAqIDEwMjQ7XG5cbi8qKiBDb3BpZXMgb25lIGZpbGUgYmV0d2VlbiB0d28gYXJjaGl2ZXMuIFRoZSBzb3VyY2UncyBDVVJSRU5UIHNpemUgYW5kIHdyaXRlIHRpbWUgYWx3YXlzIGNvbWUgZnJvbSBnZXRJbmZvIHJpZ2h0IGhlcmUgLSBjYWxsZXJzIG5ldmVyIHN1cHBseSB0aGVtLCBiZWNhdXNlIGEgc3RhbGUgc2l6ZSB0dXJucyBpbnRvIHJhbmdlZCByZWFkcyBvZiBhIGZpbGUgdGhhdCBoYXMgY2hhbmdlZCAoZmFpbGluZyBmb3JldmVyKSwgYW5kIGEgc3RhbGUgd3JpdGUgdGltZSByZS1vcmRlcnMgaGlzdG9yeS4gU21hbGwgZmlsZXMgZ28gYXMgYSBzaW5nbGUgZ2V0MitzZXQ7IHBhc3QgTEFSR0VfQ09QWV9USFJFU0hPTEQgdGhlIGNvcHkgc3RyZWFtcyB0aHJvdWdoIHNldExhcmdlRmlsZSBpbiBMQVJHRV9DT1BZX0NIVU5LIHJhbmdlZCByZWFkcywgc28gdGhlIHdob2xlIGZpbGUgaXMgbmV2ZXIgaW4gbWVtb3J5LiBSZXR1cm5zIHRoZSBjb3BpZWQgZmlsZSdzIGluZm8sIGFuZCB1bmRlZmluZWQgZm9yIGV2ZXJ5IHdheSB0aGUgY29weSBkaWQgTk9UIGxhbmQ6IHRoZSBzb3VyY2UgZG9lc24ndCBoYXZlIHRoZSBmaWxlLCB0aGUgZGVzdGluYXRpb24gYWxyZWFkeSBoYWQgYSBORVdFUiBmaWxlIChyZWZ1c2VkIHVwIGZyb250IHJhdGhlciB0aGFuIHJvbGwgaXQgYmFjayksIG9yIHRoZSBkZXN0aW5hdGlvbiBzaWxlbnRseSBkcm9wcGVkIHRoZSB3cml0ZSAoaXRzIG93biBvbmx5LXRha2UtbGF0ZXN0IHdvbiBhIHJhY2Ugd2UgbG9zdCAtIGNhdWdodCBieSBjb25maXJtaW5nIHdpdGggZ2V0SW5mbyBhZnRlcndhcmQpLiBUaGUgcmVmdXNlZC9kcm9wcGVkIGNhc2VzIGFyZSBsb2dnZWQgYXMgZXJyb3JzOyBhIGNhbGxlciB0aGF0IHRyZWF0cyB1bmRlZmluZWQgYXMgXCJtaXNzaW5nIGF0IHRoZSBzb3VyY2VcIiBtdXN0IGdldEluZm8gdGhlIGRlc3RpbmF0aW9uIHRvIGxlYXJuIHRoZSBhY3R1YWwgbGF0ZXN0IHZhbHVlLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvcHlBcmNoaXZlRmlsZShjb25maWc6IHtcbiAgICBmcm9tOiBJQXJjaGl2ZXM7XG4gICAgdG86IElBcmNoaXZlcztcbiAgICBwYXRoOiBzdHJpbmc7XG4gICAgLyoqIFRoZSBwYXRoIGF0IHRoZSBkZXN0aW5hdGlvbiAtIGRlZmF1bHRzIHRvIHBhdGggKHRoZSBjb21tb24gY2FzZTogdGhlIHNhbWUga2V5IG1vdmluZyBiZXR3ZWVuIHR3byBhcmNoaXZlcykuICovXG4gICAgdG9QYXRoPzogc3RyaW5nO1xuICAgIGZvcmNlU2V0SW1tdXRhYmxlPzogYm9vbGVhbjtcbiAgICBub0NoZWNrcz86IGJvb2xlYW47XG4gICAgaW50ZXJuYWw/OiBib29sZWFuO1xuICAgIG5vRmFsbGJhY2tzPzogYm9vbGVhbjtcbn0pOiBQcm9taXNlPHsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgbGV0IHsgZnJvbSwgdG8sIHBhdGggfSA9IGNvbmZpZztcbiAgICBsZXQgdG9QYXRoID0gY29uZmlnLnRvUGF0aCB8fCBwYXRoO1xuICAgIGxldCBpbmZvID0gYXdhaXQgZnJvbS5nZXRJbmZvKHBhdGgsIHsgbm9GYWxsYmFja3M6IGNvbmZpZy5ub0ZhbGxiYWNrcyB9KTtcbiAgICBpZiAoIWluZm8pIHJldHVybiB1bmRlZmluZWQ7XG4gICAgbGV0IHNpemUgPSBpbmZvLnNpemU7XG4gICAgLy8gaW50ZXJuYWwgKHN5bmNocm9uaXphdGlvbiBiZXR3ZWVuIHJlcGxpY2FzIG9mIHRoZSBzYW1lIGtleSkgcHJlc2VydmVzIHRoZSBzb3VyY2UncyB3cml0ZSB0aW1lLCBzbyBvcmRlcmluZyBzdXJ2aXZlcyBwcm9wYWdhdGlvbi4gQSBwbGFpbiBjb3B5IGlzIGEgTkVXIHdyaXRlIGFuZCBpcyBzdGFtcGVkIG5vdzogdGhlIHNvdXJjZSdzIG9sZCBzdGFtcCB3b3VsZCBtYWtlIGl0IExPU0UgdG8gYW55IG5ld2VyIHdyaXRlIG9yIHRvbWJzdG9uZSBhdCB0aGUgZGVzdGluYXRpb24sIHNpbGVudGx5IC0gbW92ZSBhIGZpbGUgYmFjayB0byBhIGZvbGRlciBpdCB3YXMgZGVsZXRlZCBmcm9tIGFuZCB0aGUgY29weSBpcyBkcm9wcGVkLCB0aGVuIHRoZSBjYWxsZXIgZGVsZXRlcyB0aGUgc291cmNlLCBhbmQgdGhlIGZpbGUgaXMgZ29uZSBlbnRpcmVseS5cbiAgICBsZXQgd3JpdGVUaW1lID0gTWF0aC5mbG9vcihjb25maWcuaW50ZXJuYWwgJiYgaW5mby53cml0ZVRpbWUgfHwgRGF0ZS5ub3coKSk7XG4gICAgLy8gQSBkZXN0aW5hdGlvbiB0aGF0IGFscmVhZHkgaG9sZHMgYSBORVdFUiBmaWxlIG11c3Qgbm90IGJlIG92ZXJ3cml0dGVuIHdpdGggb3VyIG9sZGVyIG9uZSAtIGFuZCB0aGUgZGVzdGluYXRpb24ncyBvd24gb25seS10YWtlLWxhdGVzdCB3b3VsZCBkcm9wIHRoZSB3cml0ZSBTSUxFTlRMWSwgbGVhdmluZyB0aGUgY2FsbGVyIGJlbGlldmluZyB0aGUgY29weSBoYXBwZW5lZC4gUmVmdXNpbmcgaGVyZSwgbG91ZGx5LCBpcyB3aGF0IHR1cm5zIFwidGhlIHJlbW90ZSBoYXMgc29tZXRoaW5nIHdlIG1pc3NlZFwiIGZyb20gYSBtYXNrZWQgYnVnIGludG8gYSBsb2cgbGluZSB0aGUgY2FsbGVyIGNhbiBhY3Qgb24uXG4gICAgbGV0IGRlc3RJbmZvID0gYXdhaXQgdG8uZ2V0SW5mbyh0b1BhdGgsIHsgbm9GYWxsYmFja3M6IGNvbmZpZy5ub0ZhbGxiYWNrcyB9KTtcbiAgICAvLyBDb21wYXJlZCBhdCB3aG9sZS1taWxsaXNlY29uZCBwcmVjaXNpb24sIGhlcmUgYW5kIGF0IHRoZSBjb25maXJtIGJlbG93OiBkaXNrIG10aW1lcyBjYXJyeSBmcmFjdGlvbmFsIG1pbGxpc2Vjb25kcywgYnV0IHV0aW1lcyByb3VuZC10cmlwcyBvbmx5IHdob2xlIG9uZXMsIHNvIHN1Yi1taWxsaXNlY29uZCBkaWZmZXJlbmNlcyBhcmUgc3RvcmFnZSBhcnRpZmFjdHMgb2YgdGhlIFNBTUUgdGltZSwgbm90IG9yZGVyaW5nXG4gICAgaWYgKGRlc3RJbmZvICYmIE1hdGguZmxvb3IoZGVzdEluZm8ud3JpdGVUaW1lKSA+IE1hdGguZmxvb3Iod3JpdGVUaW1lKSkge1xuICAgICAgICBsb2dTdG9yYWdlRXJyb3IoYENvcHkgcmVmdXNlZCAtIGEgbmV3ZXIgZmlsZSBleGlzdHMgYXQgdGhlIGRlc3RpbmF0aW9uLiBSZWZ1c2luZyB0byBjb3B5ICR7SlNPTi5zdHJpbmdpZnkocGF0aCl9IGZyb20gJHtmcm9tLmdldERlYnVnTmFtZSgpfSB0byAke3RvLmdldERlYnVnTmFtZSgpfSR7dG9QYXRoICE9PSBwYXRoICYmIGAgKGFzICR7SlNPTi5zdHJpbmdpZnkodG9QYXRoKX0pYCB8fCBcIlwifTogb3VycyAke3NpemV9IGJ5dGVzIGF0ICR7Zm9ybWF0RGF0ZVRpbWVEZXRhaWxlZCh3cml0ZVRpbWUpfSwgdGhlaXJzICR7ZGVzdEluZm8uc2l6ZX0gYnl0ZXMgYXQgJHtmb3JtYXREYXRlVGltZURldGFpbGVkKGRlc3RJbmZvLndyaXRlVGltZSl9IC0gY29weWluZyB3b3VsZCByb2xsIGl0IGJhY2tgKTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgbGV0IGNvcGllZFNpemU6IG51bWJlcjtcbiAgICBpZiAoc2l6ZSA8PSBMQVJHRV9DT1BZX1RIUkVTSE9MRCkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gYXdhaXQgZnJvbS5nZXQyKHBhdGgsIHsgaW50ZXJuYWw6IGNvbmZpZy5pbnRlcm5hbCwgbm9GYWxsYmFja3M6IGNvbmZpZy5ub0ZhbGxiYWNrcyB9KTtcbiAgICAgICAgLy8gRW1wdHkgY291bnRzIGFzIGFic2VudCwgbmV2ZXIgYXMgY29udGVudCB0byBjb3B5OiBhbiBlbXB0eSBmaWxlIElTIGEgZGVsZXRpb24sIHNldCByZWZ1c2VzIGVtcHR5IGJ1ZmZlcnMsIGFuZCBkZWxldGlvbnMgdHJhdmVsIHRocm91Z2ggdGhlaXIgb3duIHBhdGggKGRlbCAvIHNjYW4gdG9tYnN0b25lcylcbiAgICAgICAgaWYgKCFyZXN1bHQgfHwgIXJlc3VsdC5kYXRhIHx8ICFyZXN1bHQuZGF0YS5sZW5ndGgpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIGF3YWl0IHRvLnNldCh0b1BhdGgsIHJlc3VsdC5kYXRhLCB7IGxhc3RNb2RpZmllZDogd3JpdGVUaW1lLCBmb3JjZVNldEltbXV0YWJsZTogY29uZmlnLmZvcmNlU2V0SW1tdXRhYmxlLCBub0NoZWNrczogY29uZmlnLm5vQ2hlY2tzLCBpbnRlcm5hbDogY29uZmlnLmludGVybmFsIH0pO1xuICAgICAgICBjb3BpZWRTaXplID0gcmVzdWx0LmRhdGEubGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIENvbnN0IHNvIHRoZSBjbG9zdXJlIGtlZXBzIHRoZSBuYXJyb3dlZCB0eXBlXG4gICAgICAgIGNvbnN0IHRvdGFsU2l6ZSA9IHNpemU7XG4gICAgICAgIGxldCBvZmZzZXQgPSAwO1xuICAgICAgICBhd2FpdCB0by5zZXRMYXJnZUZpbGUoe1xuICAgICAgICAgICAgcGF0aDogdG9QYXRoLFxuICAgICAgICAgICAgbGFzdE1vZGlmaWVkOiB3cml0ZVRpbWUsXG4gICAgICAgICAgICBmb3JjZVNldEltbXV0YWJsZTogY29uZmlnLmZvcmNlU2V0SW1tdXRhYmxlLFxuICAgICAgICAgICAgbm9DaGVja3M6IGNvbmZpZy5ub0NoZWNrcyxcbiAgICAgICAgICAgIGludGVybmFsOiBjb25maWcuaW50ZXJuYWwsXG4gICAgICAgICAgICByZXN0YXJ0U3RyZWFtOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXROZXh0RGF0YTogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPj0gdG90YWxTaXplKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIGxldCBlbmQgPSBNYXRoLm1pbihvZmZzZXQgKyBMQVJHRV9DT1BZX0NIVU5LLCB0b3RhbFNpemUpO1xuICAgICAgICAgICAgICAgIGxldCBkYXRhID0gYXdhaXQgZnJvbS5nZXQocGF0aCwgeyByYW5nZTogeyBzdGFydDogb2Zmc2V0LCBlbmQgfSwgaW50ZXJuYWw6IGNvbmZpZy5pbnRlcm5hbCwgbm9GYWxsYmFja3M6IGNvbmZpZy5ub0ZhbGxiYWNrcyB9KTtcbiAgICAgICAgICAgICAgICBpZiAoIWRhdGEgfHwgIWRhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUmFuZ2VkIHJlYWQgcmV0dXJuZWQgbm90aGluZyBtaWQtY29weS4gUmVhZGluZyAke0pTT04uc3RyaW5naWZ5KHBhdGgpfSBmcm9tICR7ZnJvbS5nZXREZWJ1Z05hbWUoKX0gcmV0dXJuZWQgJHtkYXRhICYmIGRhdGEubGVuZ3RoIHx8IFwibm90aGluZ1wifSBhdCAke29mZnNldH0tJHtlbmR9IChleHBlY3RlZCAke2VuZCAtIG9mZnNldH0gYnl0ZXMgb2YgYSAke3RvdGFsU2l6ZX0gYnl0ZSBmaWxlIC0gaXQgY2hhbmdlZCBvciB2YW5pc2hlZCBtaWQtY29weSlgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IGRhdGEubGVuZ3RoO1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvcGllZFNpemUgPSB0b3RhbFNpemU7XG4gICAgfVxuICAgIC8vIEV2ZXJ5IGJhY2tlbmQgZHJvcHMgYSBzdXBlcnNlZGVkIHdyaXRlIFNJTEVOVExZIChpdHMgb25seS10YWtlLWxhdGVzdCBpcyB0aGUgbGFzdCBsaW5lIG9mIGRlZmVuc2UgYWdhaW5zdCByYWNlcyB0aGUgdXAtZnJvbnQgY2hlY2sgY2FuJ3Qgc2VlKSwgc28gYSByZXR1cm5lZCBzZXQgaXMgbm90IHByb29mIHRoZSBjb3B5IGxhbmRlZCAtIG9ubHkgdGhlIGRlc3RpbmF0aW9uIHJlcG9ydGluZyB0aGUgZmlsZSBhdCBPVVIgdGltZSBvciBuZXdlciBpcy4gTmV3ZXIgYWxzbyBjb3VudHMgYXMgbGFuZGVkOiB0aGUgZGVzdGluYXRpb24gaXMgYXQgbGVhc3QgYXMgbmV3IGFzIHdoYXQgd2UgcHVzaGVkIChhbmQgYjIgYWx3YXlzIHN0YW1wcyBpdHMgb3duLCBsYXRlciwgdXBsb2FkIHRpbWUpLlxuICAgIGxldCBjb25maXJtZWQgPSBhd2FpdCB0by5nZXRJbmZvKHRvUGF0aCwgeyBub0ZhbGxiYWNrczogY29uZmlnLm5vRmFsbGJhY2tzIH0pO1xuICAgIGlmICghY29uZmlybWVkIHx8IE1hdGguZmxvb3IoY29uZmlybWVkLndyaXRlVGltZSkgPCBNYXRoLmZsb29yKHdyaXRlVGltZSkpIHtcbiAgICAgICAgbG9nU3RvcmFnZUVycm9yKGBDb3B5IHdhcyBzaWxlbnRseSBkcm9wcGVkIGJ5IHRoZSBkZXN0aW5hdGlvbi4gQ29weSBvZiAke0pTT04uc3RyaW5naWZ5KHBhdGgpfSBmcm9tICR7ZnJvbS5nZXREZWJ1Z05hbWUoKX0gdG8gJHt0by5nZXREZWJ1Z05hbWUoKX0ke3RvUGF0aCAhPT0gcGF0aCAmJiBgIChhcyAke0pTT04uc3RyaW5naWZ5KHRvUGF0aCl9KWAgfHwgXCJcIn06IG91ciBjb3B5IHdhcyAke2NvcGllZFNpemV9IGJ5dGVzIGF0ICR7Zm9ybWF0RGF0ZVRpbWVEZXRhaWxlZCh3cml0ZVRpbWUpfSwgYnV0IHRoZSBkZXN0aW5hdGlvbiByZXBvcnRzICR7Y29uZmlybWVkICYmIGAke2NvbmZpcm1lZC5zaXplfSBieXRlcyBhdCAke2Zvcm1hdERhdGVUaW1lRGV0YWlsZWQoY29uZmlybWVkLndyaXRlVGltZSl9YCB8fCBcIm5vdGhpbmdcIn0gKGEgbmV3ZXIgd3JpdGUgb3IgZGVsZXRpb24gd29uIHRoZSByYWNlKWApO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4geyB3cml0ZVRpbWUsIHNpemU6IGNvcGllZFNpemUgfTtcbn1cblxuLyoqXG4gKiBNb3ZlcyBvbmUgZmlsZSAtIGJldHdlZW4gdHdvIGFyY2hpdmVzLCBvciBiZXR3ZWVuIHR3byBwYXRocyBvZiBvbmUuIFdoZW4gZnJvbSBhbmQgdG8gYXJlIHRoZSBTQU1FXG4gKiBhcmNoaXZlcyBpbnN0YW5jZSBhbmQgaXQgaW1wbGVtZW50cyBtb3ZlLCB0aGUgYmFja2VuZCBtb3ZlcyB0aGUgZmlsZSBpdHNlbGYgKGJhY2tibGF6ZSBjb3BpZXNcbiAqIHNlcnZlci1zaWRlLCBkaXNrIHJlbmFtZXMsIHRoZSBzdG9yYWdlIHNlcnZlciByZWxvY2F0ZXMgaXQgbm9kZS1zaWRlKSBhbmQgdGhlIGJ5dGVzIG5ldmVyIHRyYXZlbFxuICogdGhyb3VnaCB1cy4gRXZlcnl0aGluZyBlbHNlIGlzIHRoZSBzYWZlIGZhbGxiYWNrOiBjb3B5LCB0aGVuIENPTkZJUk0gdGhlIGRlc3RpbmF0aW9uIGFjdHVhbGx5XG4gKiByZXBvcnRzIHRoZSBmaWxlIChnZXRJbmZvKSwgYW5kIG9ubHkgdGhlbiBkZWxldGUgdGhlIHNvdXJjZSAtIHRoZSBvbmUgb3JkZXIgaW4gd2hpY2ggbm8gZmFpbHVyZVxuICogY2FuIGxvc2UgdGhlIGZpbGUsIG9ubHkgYXQgd29yc3QgbGVhdmUgaXQgaW4gYm90aCBwbGFjZXMuIFRocm93cyB3aGVuIHRoZSBzb3VyY2UgZG9lc24ndCBoYXZlIHRoZVxuICogZmlsZSwgb3Igd2hlbiB0aGUgY29weSBjYW5ub3QgYmUgY29uZmlybWVkICh0aGUgc291cmNlIGlzIHRoZW4gbGVmdCB1bnRvdWNoZWQpLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbW92ZUFyY2hpdmVGaWxlKGNvbmZpZzoge1xuICAgIGZyb206IElBcmNoaXZlcztcbiAgICB0bzogSUFyY2hpdmVzO1xuICAgIHBhdGg6IHN0cmluZztcbiAgICAvKiogVGhlIHBhdGggYXQgdGhlIGRlc3RpbmF0aW9uIC0gZGVmYXVsdHMgdG8gcGF0aCAobW92aW5nIGJldHdlZW4gdHdvIGFyY2hpdmVzKS4gUmVxdWlyZWQgaW4gcHJhY3RpY2Ugd2hlbiBmcm9tIGFuZCB0byBhcmUgdGhlIHNhbWUgYXJjaGl2ZXMsIHdoZXJlIHRoZSBzYW1lIHBhdGggd291bGQgYmUgYSBuby1vcC4gKi9cbiAgICB0b1BhdGg/OiBzdHJpbmc7XG4gICAgbm9GYWxsYmFja3M/OiBib29sZWFuO1xufSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxldCB7IGZyb20sIHRvLCBwYXRoIH0gPSBjb25maWc7XG4gICAgbGV0IHRvUGF0aCA9IGNvbmZpZy50b1BhdGggfHwgcGF0aDtcbiAgICBpZiAoZnJvbSA9PT0gdG8pIHtcbiAgICAgICAgaWYgKHBhdGggPT09IHRvUGF0aCkgcmV0dXJuO1xuICAgICAgICBpZiAoZnJvbS5tb3ZlKSB7XG4gICAgICAgICAgICBhd2FpdCBmcm9tLm1vdmUoeyBmcm9tUGF0aDogcGF0aCwgdG9QYXRoIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxldCBjb3BpZWQgPSBhd2FpdCBjb3B5QXJjaGl2ZUZpbGUoeyBmcm9tLCB0bywgcGF0aCwgdG9QYXRoLCBub0ZhbGxiYWNrczogY29uZmlnLm5vRmFsbGJhY2tzIH0pO1xuICAgIGlmICghY29waWVkKSB7XG4gICAgICAgIC8vIFVuZGVmaW5lZCBpcyB0d28gY2FzZXMgKHNlZSBjb3B5QXJjaGl2ZUZpbGUpIC0gYXNraW5nIHRoZSBzb3VyY2Ugd2hpY2ggb25lIGtlZXBzIHRoZSBlcnJvciBob25lc3RcbiAgICAgICAgbGV0IHNvdXJjZUluZm8gPSBhd2FpdCBmcm9tLmdldEluZm8ocGF0aCwgeyBub0ZhbGxiYWNrczogY29uZmlnLm5vRmFsbGJhY2tzIH0pO1xuICAgICAgICBpZiAoc291cmNlSW5mbykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNb3ZlIHJlZnVzZWQgLSBhIG5ld2VyIGZpbGUgZXhpc3RzIGF0IHRoZSBkZXN0aW5hdGlvbi4gQ2Fubm90IG1vdmUgJHtKU09OLnN0cmluZ2lmeShwYXRoKX0gKCR7c291cmNlSW5mby5zaXplfSBieXRlcyBhdCAke2Zvcm1hdERhdGVUaW1lRGV0YWlsZWQoc291cmNlSW5mby53cml0ZVRpbWUpfSkgZnJvbSAke2Zyb20uZ2V0RGVidWdOYW1lKCl9OiAke3RvLmdldERlYnVnTmFtZSgpfSBob2xkcyBzb21ldGhpbmcgbmV3ZXIgYXQgJHtKU09OLnN0cmluZ2lmeSh0b1BhdGgpfSwgYW5kIHRoZSBjb3B5IHdhcyByZWZ1c2VkIHJhdGhlciB0aGFuIHJvbGwgaXQgYmFjayAtIHRoZSBzb3VyY2UgaXMgbGVmdCB1bnRvdWNoZWRgKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1vdmUgc291cmNlIGRvZXMgbm90IGV4aXN0LiBDYW5ub3QgbW92ZSAke0pTT04uc3RyaW5naWZ5KHBhdGgpfTogJHtmcm9tLmdldERlYnVnTmFtZSgpfSBkb2VzIG5vdCBoYXZlIGl0YCk7XG4gICAgfVxuICAgIGxldCBjb25maXJtZWQgPSBhd2FpdCB0by5nZXRJbmZvKHRvUGF0aCwgeyBub0ZhbGxiYWNrczogY29uZmlnLm5vRmFsbGJhY2tzIH0pO1xuICAgIGlmICghY29uZmlybWVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTW92ZSBjb3B5IGNvdWxkIG5vdCBiZSBjb25maXJtZWQgLSB0aGUgc291cmNlIGlzIGtlcHQuIE5vdCBkZWxldGluZyAke0pTT04uc3RyaW5naWZ5KHBhdGgpfSBmcm9tICR7ZnJvbS5nZXREZWJ1Z05hbWUoKX0gYWZ0ZXIgY29weWluZyBpdDogJHt0by5nZXREZWJ1Z05hbWUoKX0gZG9lcyBub3QgcmVwb3J0ICR7SlNPTi5zdHJpbmdpZnkodG9QYXRoKX0gKHRoZSBjb3B5IGNsYWltZWQgdG8gc3VjY2VlZCwgc28gc29tZXRoaW5nIGlzIHdyb25nKWApO1xuICAgIH1cbiAgICBhd2FpdCBmcm9tLmRlbChwYXRoKTtcbn1cbiJdfQ==
108
- /* _JS_SOURCE_HASH = "277836fc71ac37c02353ae0fba3d85636b575e4b47c024e0905a1979795b465e"; */
110
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJjaGl2ZUhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJhcmNoaXZlSGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxrRUFBK0U7QUFDL0UsNkRBQThEO0FBRTlELCtKQUErSjtBQUUvSixNQUFNLG9CQUFvQixHQUFHLEVBQUUsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQzlDLE1BQU0sZ0JBQWdCLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFFMUMsOC9CQUE4L0I7QUFDdi9CLEtBQUssVUFBVSxlQUFlLENBQUMsTUFZckM7SUFDRyxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxNQUFNLENBQUM7SUFDaEMsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUM7SUFDbkMsSUFBSSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUN6RSxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQzVCLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDckIsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsaUJBQWlCLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNyRixJQUFJLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQzNCLCtkQUErZDtRQUMvZCxJQUFJLFFBQVEsR0FBRyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBQzdFLGlTQUFpUztRQUNqUyxJQUFJLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDckUsSUFBQSw2QkFBZSxFQUFDLDJFQUEyRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxZQUFZLEVBQUUsT0FBTyxFQUFFLENBQUMsWUFBWSxFQUFFLEdBQUcsTUFBTSxLQUFLLElBQUksSUFBSSxRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxFQUFFLFVBQVUsSUFBSSxhQUFhLElBQUEsK0JBQXNCLEVBQUMsU0FBUyxDQUFDLFlBQVksUUFBUSxDQUFDLElBQUksYUFBYSxJQUFBLCtCQUFzQixFQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsK0JBQStCLENBQUMsQ0FBQztZQUM3WSxPQUFPLFNBQVMsQ0FBQztRQUNyQixDQUFDO0lBQ0wsQ0FBQztJQUNELElBQUksVUFBa0IsQ0FBQztJQUN2QixJQUFJLElBQUksSUFBSSxvQkFBb0IsRUFBRSxDQUFDO1FBQy9CLElBQUksTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsRUFBRSxXQUFXLEVBQUUsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDbkcsZ0xBQWdMO1FBQ2hMLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTyxTQUFTLENBQUM7UUFDckUsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLENBQUMsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ2xLLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUNwQyxDQUFDO1NBQU0sQ0FBQztRQUNKLCtDQUErQztRQUMvQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDdkIsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2YsTUFBTSxFQUFFLENBQUMsWUFBWSxDQUFDO1lBQ2xCLElBQUksRUFBRSxNQUFNO1lBQ1osWUFBWSxFQUFFLFNBQVM7WUFDdkIsaUJBQWlCLEVBQUUsTUFBTSxDQUFDLGlCQUFpQjtZQUMzQyxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVE7WUFDekIsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRO1lBQ3pCLGFBQWEsRUFBRSxHQUFHLEVBQUU7Z0JBQ2hCLE1BQU0sR0FBRyxDQUFDLENBQUM7WUFDZixDQUFDO1lBQ0QsV0FBVyxFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUNwQixJQUFJLE1BQU0sSUFBSSxTQUFTO29CQUFFLE9BQU8sU0FBUyxDQUFDO2dCQUMxQyxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxnQkFBZ0IsRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDekQsSUFBSSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLEtBQUssRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO2dCQUMvSCxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO29CQUN4QixNQUFNLElBQUksS0FBSyxDQUFDLGtEQUFrRCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxZQUFZLEVBQUUsYUFBYSxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxTQUFTLE9BQU8sTUFBTSxJQUFJLEdBQUcsY0FBYyxHQUFHLEdBQUcsTUFBTSxlQUFlLFNBQVMsK0NBQStDLENBQUMsQ0FBQztnQkFDMVIsQ0FBQztnQkFDRCxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQztnQkFDdEIsT0FBTyxJQUFJLENBQUM7WUFDaEIsQ0FBQztTQUNKLENBQUMsQ0FBQztRQUNILFVBQVUsR0FBRyxTQUFTLENBQUM7SUFDM0IsQ0FBQztJQUNELElBQUksTUFBTSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDM0IsMmdCQUEyZ0I7UUFDM2dCLElBQUksU0FBUyxHQUFHLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxXQUFXLEVBQUUsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDOUUsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDeEUsSUFBQSw2QkFBZSxFQUFDLHlEQUF5RCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxZQUFZLEVBQUUsT0FBTyxFQUFFLENBQUMsWUFBWSxFQUFFLEdBQUcsTUFBTSxLQUFLLElBQUksSUFBSSxRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxFQUFFLGtCQUFrQixVQUFVLGFBQWEsSUFBQSwrQkFBc0IsRUFBQyxTQUFTLENBQUMsaUNBQWlDLFNBQVMsSUFBSSxHQUFHLFNBQVMsQ0FBQyxJQUFJLGFBQWEsSUFBQSwrQkFBc0IsRUFBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEVBQUUsSUFBSSxTQUFTLDJDQUEyQyxDQUFDLENBQUM7WUFDM2MsT0FBTyxTQUFTLENBQUM7UUFDckIsQ0FBQztJQUNMLENBQUM7SUFDRCxPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsQ0FBQztBQUMzQyxDQUFDO0FBdEVELDBDQXNFQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0ksS0FBSyxVQUFVLGVBQWUsQ0FBQyxNQU9yQztJQUNHLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQztJQUNoQyxJQUFJLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQztJQUNuQyxJQUFJLElBQUksS0FBSyxFQUFFLEVBQUUsQ0FBQztRQUNkLElBQUksSUFBSSxLQUFLLE1BQU07WUFBRSxPQUFPO1FBQzVCLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ1osTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQzVDLE9BQU87UUFDWCxDQUFDO0lBQ0wsQ0FBQztJQUNELElBQUksTUFBTSxHQUFHLE1BQU0sZUFBZSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUNoRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDVixvR0FBb0c7UUFDcEcsSUFBSSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUMvRSxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2IsTUFBTSxJQUFJLEtBQUssQ0FBQyxzRUFBc0UsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxVQUFVLENBQUMsSUFBSSxhQUFhLElBQUEsK0JBQXNCLEVBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxVQUFVLElBQUksQ0FBQyxZQUFZLEVBQUUsS0FBSyxFQUFFLENBQUMsWUFBWSxFQUFFLDZCQUE2QixJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxvRkFBb0YsQ0FBQyxDQUFDO1FBQ3ZYLENBQUM7UUFDRCxNQUFNLElBQUksS0FBSyxDQUFDLDJDQUEyQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxZQUFZLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztJQUNoSSxDQUFDO0lBQ0QsSUFBSSxTQUFTLEdBQUcsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUM5RSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDYixNQUFNLElBQUksS0FBSyxDQUFDLHVFQUF1RSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxZQUFZLEVBQUUsc0JBQXNCLEVBQUUsQ0FBQyxZQUFZLEVBQUUsb0JBQW9CLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLHVEQUF1RCxDQUFDLENBQUM7SUFDclIsQ0FBQztJQUNELE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN6QixDQUFDO0FBL0JELDBDQStCQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIFR5cGUtb25seTogSUFyY2hpdmVzLnRzIHJlLWV4cG9ydHMgb3VyIGZ1bmN0aW9ucywgc28gYSB2YWx1ZSBpbXBvcnQgYmFjayBhdCBpdCB3b3VsZCBiZSBhIHJlcXVpcmUgY3ljbGVcbmltcG9ydCB0eXBlIHsgSUFyY2hpdmVzIH0gZnJvbSBcIi4vSUFyY2hpdmVzXCI7XG5pbXBvcnQgeyBmb3JtYXREYXRlVGltZURldGFpbGVkIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvZm9ybWF0dGluZy9mb3JtYXRcIjtcbmltcG9ydCB7IGxvZ1N0b3JhZ2VFcnJvciB9IGZyb20gXCIuL3JlbW90ZVN0b3JhZ2Uvc3RvcmFnZUxvZ3NcIjtcblxuLy8gQ3Jvc3MtYXJjaGl2ZSBmaWxlIG9wZXJhdGlvbnMgYnVpbHQgT04gVE9QIG9mIElBcmNoaXZlcyAoY29weSwgbW92ZSkgLSBoZWxwZXJzIG92ZXIgdGhlIGludGVyZmFjZSwgbm90IHBhcnQgb2YgaXQsIHNvIHRoZXkgbGl2ZSBiZXNpZGUgaXQgcmF0aGVyIHRoYW4gaW4gaXQuXG5cbmNvbnN0IExBUkdFX0NPUFlfVEhSRVNIT0xEID0gNjQgKiAxMDI0ICogMTAyNDtcbmNvbnN0IExBUkdFX0NPUFlfQ0hVTksgPSAzMiAqIDEwMjQgKiAxMDI0O1xuXG4vKiogQ29waWVzIG9uZSBmaWxlIGJldHdlZW4gdHdvIGFyY2hpdmVzLiBUaGUgc291cmNlJ3MgQ1VSUkVOVCBzaXplIGFuZCB3cml0ZSB0aW1lIGFsd2F5cyBjb21lIGZyb20gZ2V0SW5mbyByaWdodCBoZXJlIC0gY2FsbGVycyBuZXZlciBzdXBwbHkgdGhlbSwgYmVjYXVzZSBhIHN0YWxlIHNpemUgdHVybnMgaW50byByYW5nZWQgcmVhZHMgb2YgYSBmaWxlIHRoYXQgaGFzIGNoYW5nZWQgKGZhaWxpbmcgZm9yZXZlciksIGFuZCBhIHN0YWxlIHdyaXRlIHRpbWUgcmUtb3JkZXJzIGhpc3RvcnkuIFNtYWxsIGZpbGVzIGdvIGFzIGEgc2luZ2xlIGdldDIrc2V0OyBwYXN0IExBUkdFX0NPUFlfVEhSRVNIT0xEIHRoZSBjb3B5IHN0cmVhbXMgdGhyb3VnaCBzZXRMYXJnZUZpbGUgaW4gTEFSR0VfQ09QWV9DSFVOSyByYW5nZWQgcmVhZHMsIHNvIHRoZSB3aG9sZSBmaWxlIGlzIG5ldmVyIGluIG1lbW9yeS4gUmV0dXJucyB0aGUgY29waWVkIGZpbGUncyBpbmZvLCBhbmQgdW5kZWZpbmVkIGZvciBldmVyeSB3YXkgdGhlIGNvcHkgZGlkIE5PVCBsYW5kOiB0aGUgc291cmNlIGRvZXNuJ3QgaGF2ZSB0aGUgZmlsZSwgYW5kIHdpdGggcHJlc2VydmVXcml0ZVRpbWUgdGhlIHR3byBndWFyZGVkIGNhc2VzIC0gdGhlIGRlc3RpbmF0aW9uIGFscmVhZHkgaGVsZCBzb21ldGhpbmcgTkVXRVIgKHJlZnVzZWQgdXAgZnJvbnQgcmF0aGVyIHRoYW4gcm9sbCBpdCBiYWNrKSwgb3IgdGhlIGRlc3RpbmF0aW9uIHNpbGVudGx5IGRyb3BwZWQgdGhlIHdyaXRlIChpdHMgb3duIG9ubHktdGFrZS1sYXRlc3Qgd29uIGEgcmFjZSB3ZSBsb3N0IC0gY2F1Z2h0IGJ5IGNvbmZpcm1pbmcgd2l0aCBnZXRJbmZvIGFmdGVyd2FyZCkuIFRoZSByZWZ1c2VkL2Ryb3BwZWQgY2FzZXMgYXJlIGxvZ2dlZCBhcyBlcnJvcnM7IGEgY2FsbGVyIHRoYXQgdHJlYXRzIHVuZGVmaW5lZCBhcyBcIm1pc3NpbmcgYXQgdGhlIHNvdXJjZVwiIG11c3QgZ2V0SW5mbyB0aGUgZGVzdGluYXRpb24gdG8gbGVhcm4gdGhlIGFjdHVhbCBsYXRlc3QgdmFsdWUuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29weUFyY2hpdmVGaWxlKGNvbmZpZzoge1xuICAgIGZyb206IElBcmNoaXZlcztcbiAgICB0bzogSUFyY2hpdmVzO1xuICAgIHBhdGg6IHN0cmluZztcbiAgICAvKiogVGhlIHBhdGggYXQgdGhlIGRlc3RpbmF0aW9uIC0gZGVmYXVsdHMgdG8gcGF0aCAodGhlIGNvbW1vbiBjYXNlOiB0aGUgc2FtZSBrZXkgbW92aW5nIGJldHdlZW4gdHdvIGFyY2hpdmVzKS4gKi9cbiAgICB0b1BhdGg/OiBzdHJpbmc7XG4gICAgLyoqIFN0YW1wcyB0aGUgZGVzdGluYXRpb24gd2l0aCB0aGUgU09VUkNFJ3Mgd3JpdGUgdGltZSBpbnN0ZWFkIG9mIG5vdywgYW5kIHR1cm5zIG9uIHRoZSBvcmRlcmluZyBndWFyZHMgYXJvdW5kIGl0ICh0aGUgbmV3ZXItZGVzdGluYXRpb24gcmVmdXNhbCB1cCBmcm9udCwgYW5kIHRoZSBnZXRJbmZvIGNvbmZpcm0gYWZ0ZXIpLiBPTkxZIGZvciBzeW5jaHJvbml6YXRpb24gYmV0d2VlbiByZXBsaWNhcyBvZiB0aGUgc2FtZSBrZXksIHdoZXJlIHRoZSBoaWdoZXIgd3JpdGUgdGltZSBtdXN0IHdpbiBhbmQgb3JkZXJpbmcgbXVzdCBzdXJ2aXZlIHByb3BhZ2F0aW9uIC0gbmV2ZXIgZm9yIGEgdXNlci10cmlnZ2VyZWQgY29weTogYSBwbGFpbiBjb3B5IGlzIGEgTkVXIHdyaXRlLCBhbmQgdGhlIHNvdXJjZSdzIG9sZCBzdGFtcCB3b3VsZCBtYWtlIGl0IExPU0UgdG8gYW55IG5ld2VyIHdyaXRlIG9yIHRvbWJzdG9uZSBhdCB0aGUgZGVzdGluYXRpb24sIHNpbGVudGx5IChtb3ZlIGEgZmlsZSBiYWNrIHRvIGEgZm9sZGVyIGl0IHdhcyBkZWxldGVkIGZyb20gYW5kIHRoZSBjb3B5IGlzIGRyb3BwZWQsIHRoZW4gdGhlIGNhbGxlciBkZWxldGVzIHRoZSBzb3VyY2UsIGFuZCB0aGUgZmlsZSBpcyBnb25lIGVudGlyZWx5KS4gKi9cbiAgICBwcmVzZXJ2ZVdyaXRlVGltZT86IGJvb2xlYW47XG4gICAgZm9yY2VTZXRJbW11dGFibGU/OiBib29sZWFuO1xuICAgIG5vQ2hlY2tzPzogYm9vbGVhbjtcbiAgICBpbnRlcm5hbD86IGJvb2xlYW47XG4gICAgbm9GYWxsYmFja3M/OiBib29sZWFuO1xufSk6IFByb21pc2U8eyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ+IHtcbiAgICBsZXQgeyBmcm9tLCB0bywgcGF0aCB9ID0gY29uZmlnO1xuICAgIGxldCB0b1BhdGggPSBjb25maWcudG9QYXRoIHx8IHBhdGg7XG4gICAgbGV0IGluZm8gPSBhd2FpdCBmcm9tLmdldEluZm8ocGF0aCwgeyBub0ZhbGxiYWNrczogY29uZmlnLm5vRmFsbGJhY2tzIH0pO1xuICAgIGlmICghaW5mbykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBsZXQgc2l6ZSA9IGluZm8uc2l6ZTtcbiAgICBsZXQgd3JpdGVUaW1lID0gTWF0aC5yb3VuZChjb25maWcucHJlc2VydmVXcml0ZVRpbWUgJiYgaW5mby53cml0ZVRpbWUgfHwgRGF0ZS5ub3coKSk7XG4gICAgaWYgKGNvbmZpZy5wcmVzZXJ2ZVdyaXRlVGltZSkge1xuICAgICAgICAvLyBBIGRlc3RpbmF0aW9uIHRoYXQgYWxyZWFkeSBob2xkcyBhIE5FV0VSIGZpbGUgbXVzdCBub3QgYmUgb3ZlcndyaXR0ZW4gd2l0aCBvdXIgb2xkZXIgb25lIC0gYW5kIHRoZSBkZXN0aW5hdGlvbidzIG93biBvbmx5LXRha2UtbGF0ZXN0IHdvdWxkIGRyb3AgdGhlIHdyaXRlIFNJTEVOVExZLCBsZWF2aW5nIHRoZSBjYWxsZXIgYmVsaWV2aW5nIHRoZSBjb3B5IGhhcHBlbmVkLiBSZWZ1c2luZyBoZXJlLCBsb3VkbHksIGlzIHdoYXQgdHVybnMgXCJ0aGUgcmVtb3RlIGhhcyBzb21ldGhpbmcgd2UgbWlzc2VkXCIgZnJvbSBhIG1hc2tlZCBidWcgaW50byBhIGxvZyBsaW5lIHRoZSBjYWxsZXIgY2FuIGFjdCBvbi4gKEEgZnJlc2gtc3RhbXBlZCBjb3B5IG5lZWRzIG5vIHN1Y2ggZ3VhcmQgLSBub3RoaW5nIGF0IHRoZSBkZXN0aW5hdGlvbiBjYW4gYmUgbmV3ZXIgdGhhbiBub3cgLSBzbyBwbGFpbiBjb3BpZXMgc2tpcCB0aGUgcm91bmQgdHJpcC4pXG4gICAgICAgIGxldCBkZXN0SW5mbyA9IGF3YWl0IHRvLmdldEluZm8odG9QYXRoLCB7IG5vRmFsbGJhY2tzOiBjb25maWcubm9GYWxsYmFja3MgfSk7XG4gICAgICAgIC8vIENvbXBhcmVkIGF0IHdob2xlLW1pbGxpc2Vjb25kIHByZWNpc2lvbiAoUk9VTkRFRCwgbWF0Y2hpbmcgQXJjaGl2ZXNEaXNrIC0gc2VlIGl0cyBnZXQyKSwgaGVyZSBhbmQgYXQgdGhlIGNvbmZpcm0gYmVsb3c6IGRpc2sgbXRpbWVzIGNhcnJ5IGZyYWN0aW9uYWwgbWlsbGlzZWNvbmRzLCBidXQgdXRpbWVzIHJvdW5kLXRyaXBzIG9ubHkgd2hvbGUgb25lcywgc28gc3ViLW1pbGxpc2Vjb25kIGRpZmZlcmVuY2VzIGFyZSBzdG9yYWdlIGFydGlmYWN0cyBvZiB0aGUgU0FNRSB0aW1lLCBub3Qgb3JkZXJpbmdcbiAgICAgICAgaWYgKGRlc3RJbmZvICYmIE1hdGgucm91bmQoZGVzdEluZm8ud3JpdGVUaW1lKSA+IE1hdGgucm91bmQod3JpdGVUaW1lKSkge1xuICAgICAgICAgICAgbG9nU3RvcmFnZUVycm9yKGBDb3B5IHJlZnVzZWQgLSBhIG5ld2VyIGZpbGUgZXhpc3RzIGF0IHRoZSBkZXN0aW5hdGlvbi4gUmVmdXNpbmcgdG8gY29weSAke0pTT04uc3RyaW5naWZ5KHBhdGgpfSBmcm9tICR7ZnJvbS5nZXREZWJ1Z05hbWUoKX0gdG8gJHt0by5nZXREZWJ1Z05hbWUoKX0ke3RvUGF0aCAhPT0gcGF0aCAmJiBgIChhcyAke0pTT04uc3RyaW5naWZ5KHRvUGF0aCl9KWAgfHwgXCJcIn06IG91cnMgJHtzaXplfSBieXRlcyBhdCAke2Zvcm1hdERhdGVUaW1lRGV0YWlsZWQod3JpdGVUaW1lKX0sIHRoZWlycyAke2Rlc3RJbmZvLnNpemV9IGJ5dGVzIGF0ICR7Zm9ybWF0RGF0ZVRpbWVEZXRhaWxlZChkZXN0SW5mby53cml0ZVRpbWUpfSAtIGNvcHlpbmcgd291bGQgcm9sbCBpdCBiYWNrYCk7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxldCBjb3BpZWRTaXplOiBudW1iZXI7XG4gICAgaWYgKHNpemUgPD0gTEFSR0VfQ09QWV9USFJFU0hPTEQpIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IGZyb20uZ2V0MihwYXRoLCB7IGludGVybmFsOiBjb25maWcuaW50ZXJuYWwsIG5vRmFsbGJhY2tzOiBjb25maWcubm9GYWxsYmFja3MgfSk7XG4gICAgICAgIC8vIEVtcHR5IGNvdW50cyBhcyBhYnNlbnQsIG5ldmVyIGFzIGNvbnRlbnQgdG8gY29weTogYW4gZW1wdHkgZmlsZSBJUyBhIGRlbGV0aW9uLCBzZXQgcmVmdXNlcyBlbXB0eSBidWZmZXJzLCBhbmQgZGVsZXRpb25zIHRyYXZlbCB0aHJvdWdoIHRoZWlyIG93biBwYXRoIChkZWwgLyBzY2FuIHRvbWJzdG9uZXMpXG4gICAgICAgIGlmICghcmVzdWx0IHx8ICFyZXN1bHQuZGF0YSB8fCAhcmVzdWx0LmRhdGEubGVuZ3RoKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICBhd2FpdCB0by5zZXQodG9QYXRoLCByZXN1bHQuZGF0YSwgeyBsYXN0TW9kaWZpZWQ6IHdyaXRlVGltZSwgZm9yY2VTZXRJbW11dGFibGU6IGNvbmZpZy5mb3JjZVNldEltbXV0YWJsZSwgbm9DaGVja3M6IGNvbmZpZy5ub0NoZWNrcywgaW50ZXJuYWw6IGNvbmZpZy5pbnRlcm5hbCB9KTtcbiAgICAgICAgY29waWVkU2l6ZSA9IHJlc3VsdC5kYXRhLmxlbmd0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDb25zdCBzbyB0aGUgY2xvc3VyZSBrZWVwcyB0aGUgbmFycm93ZWQgdHlwZVxuICAgICAgICBjb25zdCB0b3RhbFNpemUgPSBzaXplO1xuICAgICAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICAgICAgYXdhaXQgdG8uc2V0TGFyZ2VGaWxlKHtcbiAgICAgICAgICAgIHBhdGg6IHRvUGF0aCxcbiAgICAgICAgICAgIGxhc3RNb2RpZmllZDogd3JpdGVUaW1lLFxuICAgICAgICAgICAgZm9yY2VTZXRJbW11dGFibGU6IGNvbmZpZy5mb3JjZVNldEltbXV0YWJsZSxcbiAgICAgICAgICAgIG5vQ2hlY2tzOiBjb25maWcubm9DaGVja3MsXG4gICAgICAgICAgICBpbnRlcm5hbDogY29uZmlnLmludGVybmFsLFxuICAgICAgICAgICAgcmVzdGFydFN0cmVhbTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0TmV4dERhdGE6IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0ID49IHRvdGFsU2l6ZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBsZXQgZW5kID0gTWF0aC5taW4ob2Zmc2V0ICsgTEFSR0VfQ09QWV9DSFVOSywgdG90YWxTaXplKTtcbiAgICAgICAgICAgICAgICBsZXQgZGF0YSA9IGF3YWl0IGZyb20uZ2V0KHBhdGgsIHsgcmFuZ2U6IHsgc3RhcnQ6IG9mZnNldCwgZW5kIH0sIGludGVybmFsOiBjb25maWcuaW50ZXJuYWwsIG5vRmFsbGJhY2tzOiBjb25maWcubm9GYWxsYmFja3MgfSk7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhIHx8ICFkYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFJhbmdlZCByZWFkIHJldHVybmVkIG5vdGhpbmcgbWlkLWNvcHkuIFJlYWRpbmcgJHtKU09OLnN0cmluZ2lmeShwYXRoKX0gZnJvbSAke2Zyb20uZ2V0RGVidWdOYW1lKCl9IHJldHVybmVkICR7ZGF0YSAmJiBkYXRhLmxlbmd0aCB8fCBcIm5vdGhpbmdcIn0gYXQgJHtvZmZzZXR9LSR7ZW5kfSAoZXhwZWN0ZWQgJHtlbmQgLSBvZmZzZXR9IGJ5dGVzIG9mIGEgJHt0b3RhbFNpemV9IGJ5dGUgZmlsZSAtIGl0IGNoYW5nZWQgb3IgdmFuaXNoZWQgbWlkLWNvcHkpYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG9mZnNldCArPSBkYXRhLmxlbmd0aDtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBjb3BpZWRTaXplID0gdG90YWxTaXplO1xuICAgIH1cbiAgICBpZiAoY29uZmlnLnByZXNlcnZlV3JpdGVUaW1lKSB7XG4gICAgICAgIC8vIEV2ZXJ5IGJhY2tlbmQgZHJvcHMgYSBzdXBlcnNlZGVkIHdyaXRlIFNJTEVOVExZIChpdHMgb25seS10YWtlLWxhdGVzdCBpcyB0aGUgbGFzdCBsaW5lIG9mIGRlZmVuc2UgYWdhaW5zdCByYWNlcyB0aGUgdXAtZnJvbnQgY2hlY2sgY2FuJ3Qgc2VlKSwgc28gYSByZXR1cm5lZCBzZXQgaXMgbm90IHByb29mIHRoZSBjb3B5IGxhbmRlZCAtIG9ubHkgdGhlIGRlc3RpbmF0aW9uIHJlcG9ydGluZyB0aGUgZmlsZSBhdCBPVVIgdGltZSBvciBuZXdlciBpcy4gTmV3ZXIgYWxzbyBjb3VudHMgYXMgbGFuZGVkOiB0aGUgZGVzdGluYXRpb24gaXMgYXQgbGVhc3QgYXMgbmV3IGFzIHdoYXQgd2UgcHVzaGVkIChhbmQgYjIgYWx3YXlzIHN0YW1wcyBpdHMgb3duLCBsYXRlciwgdXBsb2FkIHRpbWUpLiBPbmx5IGZvciBwcmVzZXJ2ZWQgc3RhbXBzOiBhIGZyZXNoIHN0YW1wIGNhbm5vdCBsb3NlIHRoZSByYWNlLCBhbmQgbW92ZUFyY2hpdmVGaWxlIGRvZXMgaXRzIG93biBjb25maXJtIGJlZm9yZSBkZWxldGluZyBhbnl0aGluZy5cbiAgICAgICAgbGV0IGNvbmZpcm1lZCA9IGF3YWl0IHRvLmdldEluZm8odG9QYXRoLCB7IG5vRmFsbGJhY2tzOiBjb25maWcubm9GYWxsYmFja3MgfSk7XG4gICAgICAgIGlmICghY29uZmlybWVkIHx8IE1hdGgucm91bmQoY29uZmlybWVkLndyaXRlVGltZSkgPCBNYXRoLnJvdW5kKHdyaXRlVGltZSkpIHtcbiAgICAgICAgICAgIGxvZ1N0b3JhZ2VFcnJvcihgQ29weSB3YXMgc2lsZW50bHkgZHJvcHBlZCBieSB0aGUgZGVzdGluYXRpb24uIENvcHkgb2YgJHtKU09OLnN0cmluZ2lmeShwYXRoKX0gZnJvbSAke2Zyb20uZ2V0RGVidWdOYW1lKCl9IHRvICR7dG8uZ2V0RGVidWdOYW1lKCl9JHt0b1BhdGggIT09IHBhdGggJiYgYCAoYXMgJHtKU09OLnN0cmluZ2lmeSh0b1BhdGgpfSlgIHx8IFwiXCJ9OiBvdXIgY29weSB3YXMgJHtjb3BpZWRTaXplfSBieXRlcyBhdCAke2Zvcm1hdERhdGVUaW1lRGV0YWlsZWQod3JpdGVUaW1lKX0sIGJ1dCB0aGUgZGVzdGluYXRpb24gcmVwb3J0cyAke2NvbmZpcm1lZCAmJiBgJHtjb25maXJtZWQuc2l6ZX0gYnl0ZXMgYXQgJHtmb3JtYXREYXRlVGltZURldGFpbGVkKGNvbmZpcm1lZC53cml0ZVRpbWUpfWAgfHwgXCJub3RoaW5nXCJ9IChhIG5ld2VyIHdyaXRlIG9yIGRlbGV0aW9uIHdvbiB0aGUgcmFjZSlgKTtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgd3JpdGVUaW1lLCBzaXplOiBjb3BpZWRTaXplIH07XG59XG5cbi8qKlxuICogTW92ZXMgb25lIGZpbGUgLSBiZXR3ZWVuIHR3byBhcmNoaXZlcywgb3IgYmV0d2VlbiB0d28gcGF0aHMgb2Ygb25lLiBXaGVuIGZyb20gYW5kIHRvIGFyZSB0aGUgU0FNRVxuICogYXJjaGl2ZXMgaW5zdGFuY2UgYW5kIGl0IGltcGxlbWVudHMgbW92ZSwgdGhlIGJhY2tlbmQgbW92ZXMgdGhlIGZpbGUgaXRzZWxmIChiYWNrYmxhemUgY29waWVzXG4gKiBzZXJ2ZXItc2lkZSwgZGlzayByZW5hbWVzLCB0aGUgc3RvcmFnZSBzZXJ2ZXIgcmVsb2NhdGVzIGl0IG5vZGUtc2lkZSkgYW5kIHRoZSBieXRlcyBuZXZlciB0cmF2ZWxcbiAqIHRocm91Z2ggdXMuIEV2ZXJ5dGhpbmcgZWxzZSBpcyB0aGUgc2FmZSBmYWxsYmFjazogY29weSwgdGhlbiBDT05GSVJNIHRoZSBkZXN0aW5hdGlvbiBhY3R1YWxseVxuICogcmVwb3J0cyB0aGUgZmlsZSAoZ2V0SW5mbyksIGFuZCBvbmx5IHRoZW4gZGVsZXRlIHRoZSBzb3VyY2UgLSB0aGUgb25lIG9yZGVyIGluIHdoaWNoIG5vIGZhaWx1cmVcbiAqIGNhbiBsb3NlIHRoZSBmaWxlLCBvbmx5IGF0IHdvcnN0IGxlYXZlIGl0IGluIGJvdGggcGxhY2VzLiBUaHJvd3Mgd2hlbiB0aGUgc291cmNlIGRvZXNuJ3QgaGF2ZSB0aGVcbiAqIGZpbGUsIG9yIHdoZW4gdGhlIGNvcHkgY2Fubm90IGJlIGNvbmZpcm1lZCAodGhlIHNvdXJjZSBpcyB0aGVuIGxlZnQgdW50b3VjaGVkKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1vdmVBcmNoaXZlRmlsZShjb25maWc6IHtcbiAgICBmcm9tOiBJQXJjaGl2ZXM7XG4gICAgdG86IElBcmNoaXZlcztcbiAgICBwYXRoOiBzdHJpbmc7XG4gICAgLyoqIFRoZSBwYXRoIGF0IHRoZSBkZXN0aW5hdGlvbiAtIGRlZmF1bHRzIHRvIHBhdGggKG1vdmluZyBiZXR3ZWVuIHR3byBhcmNoaXZlcykuIFJlcXVpcmVkIGluIHByYWN0aWNlIHdoZW4gZnJvbSBhbmQgdG8gYXJlIHRoZSBzYW1lIGFyY2hpdmVzLCB3aGVyZSB0aGUgc2FtZSBwYXRoIHdvdWxkIGJlIGEgbm8tb3AuICovXG4gICAgdG9QYXRoPzogc3RyaW5nO1xuICAgIG5vRmFsbGJhY2tzPzogYm9vbGVhbjtcbn0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsZXQgeyBmcm9tLCB0bywgcGF0aCB9ID0gY29uZmlnO1xuICAgIGxldCB0b1BhdGggPSBjb25maWcudG9QYXRoIHx8IHBhdGg7XG4gICAgaWYgKGZyb20gPT09IHRvKSB7XG4gICAgICAgIGlmIChwYXRoID09PSB0b1BhdGgpIHJldHVybjtcbiAgICAgICAgaWYgKGZyb20ubW92ZSkge1xuICAgICAgICAgICAgYXdhaXQgZnJvbS5tb3ZlKHsgZnJvbVBhdGg6IHBhdGgsIHRvUGF0aCB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBsZXQgY29waWVkID0gYXdhaXQgY29weUFyY2hpdmVGaWxlKHsgZnJvbSwgdG8sIHBhdGgsIHRvUGF0aCwgbm9GYWxsYmFja3M6IGNvbmZpZy5ub0ZhbGxiYWNrcyB9KTtcbiAgICBpZiAoIWNvcGllZCkge1xuICAgICAgICAvLyBVbmRlZmluZWQgaXMgdHdvIGNhc2VzIChzZWUgY29weUFyY2hpdmVGaWxlKSAtIGFza2luZyB0aGUgc291cmNlIHdoaWNoIG9uZSBrZWVwcyB0aGUgZXJyb3IgaG9uZXN0XG4gICAgICAgIGxldCBzb3VyY2VJbmZvID0gYXdhaXQgZnJvbS5nZXRJbmZvKHBhdGgsIHsgbm9GYWxsYmFja3M6IGNvbmZpZy5ub0ZhbGxiYWNrcyB9KTtcbiAgICAgICAgaWYgKHNvdXJjZUluZm8pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTW92ZSByZWZ1c2VkIC0gYSBuZXdlciBmaWxlIGV4aXN0cyBhdCB0aGUgZGVzdGluYXRpb24uIENhbm5vdCBtb3ZlICR7SlNPTi5zdHJpbmdpZnkocGF0aCl9ICgke3NvdXJjZUluZm8uc2l6ZX0gYnl0ZXMgYXQgJHtmb3JtYXREYXRlVGltZURldGFpbGVkKHNvdXJjZUluZm8ud3JpdGVUaW1lKX0pIGZyb20gJHtmcm9tLmdldERlYnVnTmFtZSgpfTogJHt0by5nZXREZWJ1Z05hbWUoKX0gaG9sZHMgc29tZXRoaW5nIG5ld2VyIGF0ICR7SlNPTi5zdHJpbmdpZnkodG9QYXRoKX0sIGFuZCB0aGUgY29weSB3YXMgcmVmdXNlZCByYXRoZXIgdGhhbiByb2xsIGl0IGJhY2sgLSB0aGUgc291cmNlIGlzIGxlZnQgdW50b3VjaGVkYCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNb3ZlIHNvdXJjZSBkb2VzIG5vdCBleGlzdC4gQ2Fubm90IG1vdmUgJHtKU09OLnN0cmluZ2lmeShwYXRoKX06ICR7ZnJvbS5nZXREZWJ1Z05hbWUoKX0gZG9lcyBub3QgaGF2ZSBpdGApO1xuICAgIH1cbiAgICBsZXQgY29uZmlybWVkID0gYXdhaXQgdG8uZ2V0SW5mbyh0b1BhdGgsIHsgbm9GYWxsYmFja3M6IGNvbmZpZy5ub0ZhbGxiYWNrcyB9KTtcbiAgICBpZiAoIWNvbmZpcm1lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1vdmUgY29weSBjb3VsZCBub3QgYmUgY29uZmlybWVkIC0gdGhlIHNvdXJjZSBpcyBrZXB0LiBOb3QgZGVsZXRpbmcgJHtKU09OLnN0cmluZ2lmeShwYXRoKX0gZnJvbSAke2Zyb20uZ2V0RGVidWdOYW1lKCl9IGFmdGVyIGNvcHlpbmcgaXQ6ICR7dG8uZ2V0RGVidWdOYW1lKCl9IGRvZXMgbm90IHJlcG9ydCAke0pTT04uc3RyaW5naWZ5KHRvUGF0aCl9ICh0aGUgY29weSBjbGFpbWVkIHRvIHN1Y2NlZWQsIHNvIHNvbWV0aGluZyBpcyB3cm9uZylgKTtcbiAgICB9XG4gICAgYXdhaXQgZnJvbS5kZWwocGF0aCk7XG59XG4iXX0=
111
+ /* _JS_SOURCE_HASH = "c42b6ba2a7fe758066fc4b334dce59e66428b8ced3dbb25eb8b055a7f14937ae"; */
@@ -70,7 +70,7 @@ export class ArchivesDelayed implements IArchives {
70
70
 
71
71
  // The shared engine of set and del - an empty buffer is exactly a deletion here
72
72
  private async buffer(fileName: string, data: Buffer, lastModified: number | undefined, config?: SetConfig): Promise<string> {
73
- let writeTime = Math.floor(lastModified || Date.now());
73
+ let writeTime = Math.round(lastModified || Date.now());
74
74
  let existing = this.pending.get(fileName);
75
75
  // An older write never overwrites a newer one (see IArchives.set) - including against a write still sitting here
76
76
  if (existing && writeTime < existing.writeTime) return fileName;
@@ -180,13 +180,13 @@ export class ArchivesRemote implements IArchives {
180
180
  return await this.call(() => this.controller.getInfo({ account: this.account, bucketName: this.bucketName, path: fileName, sourceConfig: this.config.sourceConfig, includeTombstones: config?.includeTombstones }));
181
181
  }
182
182
  public async findInfo(prefix: string, config?: FindConfig): Promise<ArchiveFileInfo[]> {
183
- return await this.call(() => this.controller.findInfo({ account: this.account, bucketName: this.bucketName, prefix, sourceConfig: this.config.sourceConfig, shallow: config?.shallow, type: config?.type, includeMarked: config?.includeMarked }));
183
+ return await this.call(() => this.controller.findInfo({ account: this.account, bucketName: this.bucketName, prefix, sourceConfig: this.config.sourceConfig, shallow: config?.shallow, type: config?.type, includeMarked: config?.includeMarked, internal: config?.internal }));
184
184
  }
185
185
  public async find(prefix: string, config?: FindConfig): Promise<string[]> {
186
186
  return (await this.findInfo(prefix, config)).map(x => x.path);
187
187
  }
188
188
  public async getChangesAfter2(config: ChangesAfterConfig): Promise<ArchiveFileInfo[]> {
189
- return await this.call(() => this.controller.getChangesAfter2({ account: this.account, bucketName: this.bucketName, sourceConfig: this.config.sourceConfig, time: config.time, routes: config.routes }));
189
+ return await this.call(() => this.controller.getChangesAfter2({ account: this.account, bucketName: this.bucketName, sourceConfig: this.config.sourceConfig, time: config.time, routes: config.routes, internal: config.internal }));
190
190
  }
191
191
  public async getConfig(): Promise<ArchivesConfig> {
192
192
  return await this.call(() => this.controller.getArchivesConfig({ account: this.account, bucketName: this.bucketName }));
@@ -304,7 +304,7 @@ export declare class BlobStore {
304
304
  private assertFreshWriteTarget;
305
305
  private assertMutable;
306
306
  private assertInternalWriteAccepted;
307
- /** Internal (store-to-store) read: purely the local disk, completely short-circuiting the index and holder resolution - the caller is another store, and chasing OUR remote holders while answering it is how infinite get loops between stores form. No window or route checks: if the bytes are on our disk, the caller may have them. Note this reads the disk past any write delay, so a fast write still buffered in memory is invisible here; the caller re-finds it once it flushes. */
307
+ /** Internal (store-to-store) read: never goes to OTHER sources - the caller is another store, and chasing OUR remote holders while answering it is how infinite get loops between stores form - but the INDEX still gates, because it is the source of truth: a marked deletion keeps its bytes on disk as history (see writeToSources), so the disk alone would happily serve a DELETED file as live. Index says live -> the disk provides the bytes (past any write delay, so a fast write still buffered in memory is invisible here; the caller re-finds it once it flushes). Index says deleted -> the tombstone is the answer, never the disk. No window or route checks. */
308
308
  private getInternal2;
309
309
  /** Internal (store-to-store) write: the local disk plus our index, with NO downstream fan-out - the pushing store owns propagation, and fanning its pushes back out is how write loops between stores form. Only-take-latest still applies here. */
310
310
  private setInternal;
@@ -153,7 +153,7 @@ export class BlobStore {
153
153
  if (provided) {
154
154
  console.log(`Store ${JSON.stringify(this.storeName)} (folder ${this.folder}) initialized with no configuration; the requesting client provided routing config version ${getConfigVersion(provided)} - adopting it`);
155
155
  // Straight onto the disk, not through set(): set waits for init, which is what is running right now
156
- await this.ownDisk.set(ROUTING_FILE, Buffer.from(serializeRemoteConfig(provided)), { lastModified: Math.floor(Date.now()) });
156
+ await this.ownDisk.set(ROUTING_FILE, Buffer.from(serializeRemoteConfig(provided)), { lastModified: Math.round(Date.now()) });
157
157
  await this.applyRoutingConfig();
158
158
  } else {
159
159
  logStorageWarn(`Store ${JSON.stringify(this.storeName)} (folder ${this.folder}) initialized with no configuration, and the requesting client had no routing config naming it either - running unconfigured`);
@@ -378,7 +378,7 @@ export class BlobStore {
378
378
  throw new Error(`Empty write refused: set was called with an empty buffer for ${JSON.stringify(key)} (store ${this.folder}): an empty file IS a deletion in this system and would read back as missing - call del instead`);
379
379
  }
380
380
  await this.init();
381
- let writeTime = Math.floor(config.lastModified || Date.now());
381
+ let writeTime = Math.round(config.lastModified || Date.now());
382
382
  let route = getRoute(key);
383
383
  // The routing file defines the windows/routes, so they can't possibly apply to it (and it never flows through validation) - but it has a rule of its own, which is ours to enforce because the file is ours
384
384
  if (key === ROUTING_FILE) {
@@ -476,6 +476,8 @@ export class BlobStore {
476
476
  // Deletions are not in here at all, which is what a listing wants: an empty file IS a missing file
477
477
  for (let [key, entry] of this.indexEntries()) {
478
478
  if (!key.startsWith(prefix)) continue;
479
+ // See FindConfig.internal: an entry held by one of our OTHER sources cannot be served to a peer's internal read, so it must not be listed to one either
480
+ if (config.internal && this.slotForSourcesListIndex(entry.sourcesListIndex) !== 0) continue;
479
481
  infos.set(key, { path: key, createTime: entry.writeTime, size: entry.size });
480
482
  }
481
483
  if (config.includeMarked) {
@@ -499,6 +501,8 @@ export class BlobStore {
499
501
  for (let [key, entry] of this.indexEntries()) {
500
502
  if (entry.changedAt <= config.time) continue;
501
503
  if (!inRoutes(key)) continue;
504
+ // See ChangesAfterConfig.internal (deletions below are always reported - they are index-only)
505
+ if (config.internal && this.slotForSourcesListIndex(entry.sourcesListIndex) !== 0) continue;
502
506
  files.push({ path: key, createTime: entry.writeTime, size: entry.size });
503
507
  }
504
508
  for (let [key, tombstone] of this.deletedEntries()) {
@@ -649,7 +653,7 @@ export class BlobStore {
649
653
  await this.init();
650
654
  let key = config?.path;
651
655
  if (key) {
652
- let writeTime = Math.floor(config?.lastModified || Date.now());
656
+ let writeTime = Math.round(config?.lastModified || Date.now());
653
657
  let route = getRoute(key);
654
658
  if (key !== ROUTING_FILE) {
655
659
  this.assertWriteTarget(key, route, config?.lastModified);
@@ -1009,18 +1013,20 @@ export class BlobStore {
1009
1013
  }
1010
1014
  }
1011
1015
 
1012
- /** Internal (store-to-store) read: purely the local disk, completely short-circuiting the index and holder resolution - the caller is another store, and chasing OUR remote holders while answering it is how infinite get loops between stores form. No window or route checks: if the bytes are on our disk, the caller may have them. Note this reads the disk past any write delay, so a fast write still buffered in memory is invisible here; the caller re-finds it once it flushes. */
1016
+ /** Internal (store-to-store) read: never goes to OTHER sources - the caller is another store, and chasing OUR remote holders while answering it is how infinite get loops between stores form - but the INDEX still gates, because it is the source of truth: a marked deletion keeps its bytes on disk as history (see writeToSources), so the disk alone would happily serve a DELETED file as live. Index says live -> the disk provides the bytes (past any write delay, so a fast write still buffered in memory is invisible here; the caller re-finds it once it flushes). Index says deleted -> the tombstone is the answer, never the disk. No window or route checks. */
1013
1017
  private async getInternal2(config: { path: string; range?: { start: number; end: number }; includeTombstones?: boolean }): Promise<{ data: Buffer; writeTime: number; size: number } | undefined> {
1014
1018
  await this.init();
1015
- // includeTombstones forwards to the disk: a flag-caller (a peer store's synchronization) needs to see our deletions, not just our content. A tombstone deleted from disk entirely only lives in our index, so fall back to that.
1016
- let result = await this.getDiskSource().disk.get2(config.path, { range: config.range, includeTombstones: config.includeTombstones });
1017
- if (!result || !result.data) {
1019
+ let key = config.path;
1020
+ if (!this.getIndexEntry(key)) {
1021
+ // Deleted, or never here: a flag-caller (a peer store's synchronization) needs to see our deletions, not just our content
1018
1022
  if (config.includeTombstones) {
1019
- let deleted = this.getDeletedEntry(config.path);
1023
+ let deleted = this.getDeletedEntry(key);
1020
1024
  if (deleted) return { data: Buffer.alloc(0), writeTime: deleted.writeTime, size: 0 };
1021
1025
  }
1022
1026
  return undefined;
1023
1027
  }
1028
+ let result = await this.getDiskSource().disk.get2(key, { range: config.range });
1029
+ if (!result || !result.data) return undefined;
1024
1030
  return { data: result.data, writeTime: result.writeTime, size: result.size };
1025
1031
  }
1026
1032
 
@@ -1058,7 +1064,7 @@ export class BlobStore {
1058
1064
  if (lastModified < await this.currentWriteTime(key)) return;
1059
1065
  }
1060
1066
  // Fast writes are not handled here: a source that was configured with a write delay buffers them itself (see ArchivesDelayed), so this write lands in memory and returns, exactly as it would have. The index is updated either way, so the write is immediately visible to readers of this store.
1061
- await this.writeToSources(key, data, Math.floor(lastModified || Date.now()));
1067
+ await this.writeToSources(key, data, Math.round(lastModified || Date.now()));
1062
1068
  }
1063
1069
 
1064
1070
  /** The instant every delayed write must be on its source: the end of our own write window that contains now, minus the flush margin (so the next window's source finds the data on handoff). The LATEST end among covering windows - overlapping windows hand off at the last one. No window contains now (an inert store, or a moment between our windows) -> 0, i.e. nothing may be delayed at all. */
@@ -51,8 +51,8 @@ export async function readRoutingFile(folder: string): Promise<{ data: Buffer; w
51
51
  try {
52
52
  let data = await fs.promises.readFile(filePath);
53
53
  let stats = await fs.promises.stat(filePath);
54
- // Floored like every time ArchivesDisk reports - sub-millisecond mtime digits can't round-trip through utimes, so they are noise, not ordering
55
- return { data, writeTime: Math.floor(stats.mtimeMs) };
54
+ // Rounded like every time ArchivesDisk reports (see its get2) - sub-millisecond mtime digits can't round-trip through utimes, so they are noise, not ordering
55
+ return { data, writeTime: Math.round(stats.mtimeMs) };
56
56
  } catch (e) {
57
57
  if ((e as { code?: string }).code === "ENOENT") return undefined;
58
58
  throw e;
@@ -392,7 +392,7 @@ export function chooseStartupConfig(config: { configured: RemoteConfig; probes:
392
392
  export async function writeRoutingToAllStores(config: { configured: RemoteConfig; sources: SourceWrapper[]; debugName: string }): Promise<{ failures: string[]; total: number }> {
393
393
  let { configured, sources, debugName } = config;
394
394
  let routingData = serializeRemoteConfig(configured);
395
- let routingWriteTime = Math.floor(Date.now());
395
+ let routingWriteTime = Math.round(Date.now());
396
396
  let targets: SourceWrapper[] = [];
397
397
  let seen = new Set<string>();
398
398
  for (let source of sources) {
@@ -565,7 +565,7 @@ export class ArchivesChain implements IArchives {
565
565
  // Checked before the first node is written to, not just by each node as it arrives: every server would reject it anyway, and finding that out one node at a time is how a config write ends up half-applied
566
566
  assertValidRemoteConfig(parseRoutingData(data));
567
567
  let state = await this.state.getState();
568
- let writeTime = Math.floor(config?.lastModified || Date.now());
568
+ let writeTime = Math.round(config?.lastModified || Date.now());
569
569
  let written: string[] = [];
570
570
  let errors: string[] = [];
571
571
  // One write per STORE, not per server: the write lands in the store the entry NAMES, so two entries sharing a URL but naming different stores are two separate deliveries - deduping by URL alone leaves the second store unconfigured forever