cdk-nextjs 0.7.5 → 0.7.7

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 (69) hide show
  1. package/.jsii +38 -38
  2. package/.jsii.tabl.json +1 -1
  3. package/README.md +12 -3
  4. package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +31 -13
  5. package/docs/adapter-runtime.md +1 -1
  6. package/docs/caching-guide.md +11 -1
  7. package/docs/harness-coverage.md +11 -9
  8. package/lib/adapter/adapter.mjs +220 -149
  9. package/lib/adapter/aws-cache-store.d.ts +242 -7
  10. package/lib/adapter/aws-cache-store.js +520 -54
  11. package/lib/adapter/aws-cache-store.test.js +710 -3
  12. package/lib/adapter/build-outputs.js +23 -1
  13. package/lib/adapter/build-outputs.test.js +18 -1
  14. package/lib/adapter/cache-handler.d.ts +4 -3
  15. package/lib/adapter/cache-handler.js +1 -1
  16. package/lib/adapter/cache-handler.mjs +552 -91
  17. package/lib/adapter/cache-handler.test.js +31 -1
  18. package/lib/adapter/cache-utils.d.ts +68 -2
  19. package/lib/adapter/cache-utils.js +108 -2
  20. package/lib/adapter/cache-utils.test.js +45 -1
  21. package/lib/adapter/init-cache.d.ts +1 -1
  22. package/lib/adapter/init-cache.js +60 -37
  23. package/lib/adapter/init-cache.test.js +55 -2
  24. package/lib/adapter/local-file-cache-handler.d.ts +2 -2
  25. package/lib/adapter/local-file-cache-handler.js +4 -5
  26. package/lib/adapter/s3-cache-handler.d.ts +23 -7
  27. package/lib/adapter/s3-cache-handler.js +63 -27
  28. package/lib/adapter/s3-cache-handler.test.js +168 -1
  29. package/lib/adapter/use-cache-common.d.ts +53 -1
  30. package/lib/adapter/use-cache-common.js +121 -14
  31. package/lib/adapter/use-cache-common.test.js +138 -1
  32. package/lib/adapter/use-cache-default-handler.js +36 -6
  33. package/lib/adapter/use-cache-default-handler.mjs +557 -51
  34. package/lib/adapter/use-cache-handlers.test.js +247 -7
  35. package/lib/adapter/use-cache-remote-handler.js +10 -9
  36. package/lib/adapter/use-cache-remote-handler.mjs +597 -101
  37. package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +2 -1
  38. package/lib/lambdas/post-deploy/prune-revalidation-table.js +35 -13
  39. package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +19 -1
  40. package/lib/nextjs-api.js +1 -1
  41. package/lib/nextjs-build/nextjs-build.d.ts +0 -7
  42. package/lib/nextjs-build/nextjs-build.js +4 -11
  43. package/lib/nextjs-build/nextjs-build.test.js +4 -3
  44. package/lib/nextjs-cache.js +1 -1
  45. package/lib/nextjs-compute/nextjs-containers.js +1 -1
  46. package/lib/nextjs-compute/nextjs-functions.js +1 -1
  47. package/lib/nextjs-distribution.js +1 -1
  48. package/lib/nextjs-post-deploy.js +1 -1
  49. package/lib/nextjs-static-assets.js +1 -1
  50. package/lib/root-constructs/nextjs-base-construct.js +1 -1
  51. package/lib/root-constructs/nextjs-global-containers.js +1 -1
  52. package/lib/root-constructs/nextjs-global-functions.js +1 -1
  53. package/lib/root-constructs/nextjs-regional-containers.js +1 -1
  54. package/lib/root-constructs/nextjs-regional-functions.js +1 -1
  55. package/lib/runtime/core.js +18 -4
  56. package/lib/runtime/core.test.js +17 -1
  57. package/lib/runtime/image.d.ts +19 -0
  58. package/lib/runtime/image.js +28 -2
  59. package/lib/runtime/image.test.js +43 -1
  60. package/lib/runtime/lambda.mjs +30 -6
  61. package/lib/runtime/server.mjs +30 -6
  62. package/lib/runtime/tag-manifest.d.ts +15 -0
  63. package/lib/runtime/tag-manifest.js +24 -0
  64. package/lib/runtime/tag-manifest.test.d.ts +1 -0
  65. package/lib/runtime/tag-manifest.test.js +21 -0
  66. package/lib/utils/deployment-build-id.d.ts +11 -0
  67. package/lib/utils/deployment-build-id.js +15 -0
  68. package/package.json +3 -3
  69. package/scripts/e2e-harness/README.md +1 -1
@@ -38,21 +38,43 @@ function createDefaultUseCacheHandler(options = {}) {
38
38
  const memory = new use_cache_common_1.EntryLru((0, use_cache_common_1.numberFromEnv)("CDK_NEXTJS_USE_CACHE_MEMORY_BYTES", use_cache_common_1.DEFAULT_MEMORY_BYTES));
39
39
  const pending = new use_cache_common_1.PendingSets();
40
40
  const debug = (0, debug_1.default)("cdk-nextjs:cache-handler:use-cache:default");
41
+ // Expired entries, which `get` drops anyway, don't count as held for a
42
+ // refresh to wait for, nor hold `completeSince`'s pruning back past the
43
+ // next scan.
44
+ tags.judgeEntriesOf((scan) => scan ? memory.oldestTimestamp((0, use_cache_common_1.now)()) : memory.oldestBound((0, use_cache_common_1.now)()), () => memory.holdsLive((0, use_cache_common_1.now)()));
45
+ /**
46
+ * Read the markers of whichever of `tagList` are untracked: first, when the
47
+ * answer depends on them, or else in the background. Read either way, so
48
+ * the tags join the rolling re-read, which catches a revalidation whose log
49
+ * row failed to write.
50
+ */
51
+ const ensureTags = (needed, tagList) => (0, use_cache_common_1.awaitIf)(needed, tags.ensure(tagList), "Error reading cache tags:");
41
52
  return {
42
- async get(cacheKey) {
53
+ async get(cacheKey, softTags = []) {
43
54
  await pending.wait(cacheKey);
44
55
  const stored = memory.get(cacheKey);
45
56
  if (!stored) {
46
57
  debug(`MISS ${cacheKey}`);
47
58
  return undefined;
48
59
  }
49
- if ((0, use_cache_common_1.now)() > stored.timestamp + stored.revalidate * 1000) {
60
+ if ((0, use_cache_common_1.isPastRevalidate)(stored, (0, use_cache_common_1.now)())) {
50
61
  debug(`EXPIRED ${cacheKey}`);
51
62
  memory.delete(cacheKey);
52
63
  return undefined;
53
64
  }
54
- await tags.ensure(stored.tags);
55
- const state = tags.state(stored.tags, stored.timestamp);
65
+ // Only an entry older than what the manifest fully knows needs its tags'
66
+ // markers read first: see `completeSince`. Every entry stored since the
67
+ // instance started is newer, so its first read waits on nothing - nor
68
+ // does a new path's, whose implicit tags it has never read.
69
+ await ensureTags(stored.timestamp < tags.completeSince, [
70
+ ...stored.tags,
71
+ ...softTags,
72
+ ]);
73
+ // Implicit tags count once expired, not stale, as Next.js compares
74
+ // `getExpiration`'s answer.
75
+ const state = tags.expiration(softTags) >= stored.timestamp
76
+ ? "expired"
77
+ : tags.state(stored.tags, stored.timestamp);
56
78
  if (state === "expired") {
57
79
  debug(`EXPIRED BY TAG ${cacheKey}`);
58
80
  memory.delete(cacheKey);
@@ -72,7 +94,11 @@ function createDefaultUseCacheHandler(options = {}) {
72
94
  return;
73
95
  }
74
96
  memory.set(cacheKey, stored);
75
- tags.track(stored.tags);
97
+ // In the background, now rather than at the first `get`: a
98
+ // revalidation from before the log's first lookback with an `expire`
99
+ // still to come expires this entry when it comes, and only the marker
100
+ // says so. See `completeSince`.
101
+ void ensureTags(false, stored.tags);
76
102
  debug(`SET ${cacheKey}`);
77
103
  }
78
104
  catch (error) {
@@ -84,7 +110,11 @@ function createDefaultUseCacheHandler(options = {}) {
84
110
  }
85
111
  },
86
112
  ...(0, use_cache_common_1.tagMethods)(tags),
113
+ // `Infinity` has Next.js pass the implicit tags to `get` instead, so they
114
+ // are judged against the entry read: whether answering needs a marker
115
+ // read depends on that entry's `timestamp`, which this does not know.
116
+ getExpiration: async () => Infinity,
87
117
  };
88
118
  }
89
119
  exports.default = (0, use_cache_common_1.lazyHandler)(() => createDefaultUseCacheHandler());
90
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlLWNhY2hlLWRlZmF1bHQtaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVyL3VzZS1jYWNoZS1kZWZhdWx0LWhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFvREEsb0VBNERDO0FBaEhEOzs7Ozs7Ozs7O0VBVUU7QUFDRixzREFBc0Q7QUFDdEQsa0RBQTZCO0FBTTdCLHlEQVk0QjtBQU81Qjs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILFNBQWdCLDRCQUE0QixDQUMxQyxVQUF5QyxFQUFFO0lBRTNDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLElBQUksSUFBQSxvQ0FBaUIsR0FBRSxDQUFDO0lBQ2pELE1BQU0sTUFBTSxHQUFHLElBQUksMkJBQVEsQ0FDekIsSUFBQSxnQ0FBYSxFQUFDLG1DQUFtQyxFQUFFLHVDQUFvQixDQUFDLENBQ3pFLENBQUM7SUFDRixNQUFNLE9BQU8sR0FBRyxJQUFJLDhCQUFXLEVBQUUsQ0FBQztJQUNsQyxNQUFNLEtBQUssR0FBRyxJQUFBLGVBQVEsRUFBQyw0Q0FBNEMsQ0FBQyxDQUFDO0lBRXJFLE9BQU87UUFDTCxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQWdCO1lBQ3hCLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM3QixNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3BDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDWixLQUFLLENBQUMsUUFBUSxRQUFRLEVBQUUsQ0FBQyxDQUFDO2dCQUMxQixPQUFPLFNBQVMsQ0FBQztZQUNuQixDQUFDO1lBQ0QsSUFBSSxJQUFBLHNCQUFHLEdBQUUsR0FBRyxNQUFNLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxVQUFVLEdBQUcsSUFBSSxFQUFFLENBQUM7Z0JBQ3hELEtBQUssQ0FBQyxXQUFXLFFBQVEsRUFBRSxDQUFDLENBQUM7Z0JBQzdCLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3hCLE9BQU8sU0FBUyxDQUFDO1lBQ25CLENBQUM7WUFDRCxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQy9CLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDeEQsSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3hCLEtBQUssQ0FBQyxrQkFBa0IsUUFBUSxFQUFFLENBQUMsQ0FBQztnQkFDcEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDeEIsT0FBTyxTQUFTLENBQUM7WUFDbkIsQ0FBQztZQUNELEtBQUssQ0FBQyxPQUFPLFFBQVEsR0FBRyxLQUFLLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbkUsd0VBQXdFO1lBQ3hFLGlFQUFpRTtZQUNqRSxPQUFPLElBQUEsK0JBQVksRUFBQyxNQUFNLEVBQUUsS0FBSyxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMxRSxDQUFDO1FBRUQsS0FBSyxDQUFDLEdBQUcsQ0FDUCxRQUFnQixFQUNoQixZQUFpQztZQUVqQyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQztnQkFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEsZ0NBQWEsRUFBQyxZQUFZLENBQUMsQ0FBQztnQkFDakQsSUFBSSxJQUFBLGlDQUFjLEVBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztvQkFDM0IsS0FBSyxDQUFDLHNCQUFzQixRQUFRLEVBQUUsQ0FBQyxDQUFDO29CQUN4QyxPQUFPO2dCQUNULENBQUM7Z0JBQ0QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzdCLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUN4QixLQUFLLENBQUMsT0FBTyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQzNCLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLGlFQUFpRTtnQkFDakUsS0FBSyxDQUFDLGNBQWMsUUFBUSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDekMsQ0FBQztvQkFBUyxDQUFDO2dCQUNULElBQUksRUFBRSxDQUFDO1lBQ1QsQ0FBQztRQUNILENBQUM7UUFFRCxHQUFHLElBQUEsNkJBQVUsRUFBQyxJQUFJLENBQUM7S0FDcEIsQ0FBQztBQUNKLENBQUM7QUFFRCxrQkFBZSxJQUFBLDhCQUFXLEVBQUMsR0FBRyxFQUFFLENBQUMsNEJBQTRCLEVBQUUsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgVGhlIGBjYWNoZUhhbmRsZXJzLmRlZmF1bHRgIGhhbmRsZXIsIGZvciBwbGFpbiBgJ3VzZSBjYWNoZSdgLlxuICBTZWU6IGh0dHBzOi8vbmV4dGpzLm9yZy9kb2NzL2FwcC9hcGktcmVmZXJlbmNlL2NvbmZpZy9uZXh0LWNvbmZpZy1qcy9jYWNoZUhhbmRsZXJzXG5cbiAgU3RvcmFnZSBzdGF5cyBpbiBtZW1vcnksIHBlciBpbnN0YW5jZSwgYXMgTmV4dC5qcyBpbnRlbmRzIGZvciBgJ3VzZSBjYWNoZSdgXG4gIChgJ3VzZSBjYWNoZTogcmVtb3RlJ2AgaXMgdGhlIHNoYXJlZCBvbmUpLiBXaGF0IHRoaXMgY2hhbmdlcyBpcyB0YWdzOiBOZXh0LmpzJ3NcbiAgYnVpbHQtaW4gaGFuZGxlciBrZWVwcyB0aGVtIGluIGEgcHJvY2Vzcy1sb2NhbCBtYXAsIHNvIGEgYHJldmFsaWRhdGVUYWdgIG9uXG4gIG9uZSBpbnN0YW5jZSBsZWZ0IGV2ZXJ5IG90aGVyIGluc3RhbmNlIHNlcnZpbmcgdGhlIHJldmFsaWRhdGVkIGVudHJ5LiBIZXJlXG4gIHRoZXkgZ28gdGhyb3VnaCB0aGUgcmV2YWxpZGF0aW9uIHRhYmxlJ3MgbWFya2VyIHJvd3MuIFNlZVxuICBgVHJhY2tlZFRhZ01hcmtlcnNgLlxuKi9cbi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IGdldERlYnVnIGZyb20gXCJkZWJ1Z1wiO1xuaW1wb3J0IHR5cGUge1xuICBDYWNoZUVudHJ5LFxuICBDYWNoZUhhbmRsZXIsXG59IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL2xpYi9jYWNoZS1oYW5kbGVycy90eXBlc1wiO1xuaW1wb3J0IHsgVHJhY2tlZFRhZ01hcmtlcnMgfSBmcm9tIFwiLi9hd3MtY2FjaGUtc3RvcmVcIjtcbmltcG9ydCB7XG4gIGNhY2hlRW50cnlPZixcbiAgREVGQVVMVF9NRU1PUllfQllURVMsXG4gIEVudHJ5THJ1LFxuICBpc0R5bmFtaWNFbnRyeSxcbiAgbGF6eUhhbmRsZXIsXG4gIG5vdyxcbiAgbnVtYmVyRnJvbUVudixcbiAgUGVuZGluZ1NldHMsXG4gIHNoYXJlZFRhZ01hbmlmZXN0LFxuICBzdG9yZWRFbnRyeU9mLFxuICB0YWdNZXRob2RzLFxufSBmcm9tIFwiLi91c2UtY2FjaGUtY29tbW9uXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVmYXVsdFVzZUNhY2hlSGFuZGxlck9wdGlvbnMge1xuICAvKiogVGFnIHN0YXRlOyB0aGUgcHJvY2Vzcy13aWRlIG9uZSBmcm9tIHRoZSBlbnZpcm9ubWVudCBieSBkZWZhdWx0LiAqL1xuICB0YWdzPzogVHJhY2tlZFRhZ01hcmtlcnM7XG59XG5cbi8qKlxuICogQSBgJ3VzZSBjYWNoZSdgIGhhbmRsZXIgd2l0aCB0aGUgc2VtYW50aWNzIG9mIE5leHQuanMncyBidWlsdC1pbiBvbmVcbiAqIChgbmV4dC9kaXN0L3NlcnZlci9saWIvY2FjaGUtaGFuZGxlcnMvZGVmYXVsdC5qc2ApIGFuZCB0YWdzIHNoYXJlZCBhY3Jvc3NcbiAqIGluc3RhbmNlcy5cbiAqXG4gKiBBbiBlcXVpdmFsZW50IHJhdGhlciB0aGFuIGEgd3JhcHBlcjogdGhlIGJ1aWx0LWluIGhhbmRsZXIganVkZ2VzIHRhZ3MgYWdhaW5zdFxuICogdGhlIG1vZHVsZS1sZXZlbCBgdGFnc01hbmlmZXN0YCBvZiB3aGljaGV2ZXIgY29weSBvZiBgbmV4dGAgaXQgd2FzIHJlcXVpcmVkXG4gKiBmcm9tLCBhbmQgdGhpcyBidW5kbGUgY2Fubm90IGJlIHN1cmUgb2YgcmVhY2hpbmcgdGhlIGNvcHkgdGhlIHNlcnZlciBsb2FkZWRcbiAqICh0aGUgc2FtZSByZWFzb24gYFMzQ2FjaGVIYW5kbGVyYCByZWFkcyB0aGF0IG1hbmlmZXN0IGZyb20gdGhlIG1vZHVsZSBjYWNoZVxuICogaW5zdGVhZCBvZiByZXF1aXJpbmcgaXQpLiBLZWVwaW5nIHRoZSB0YWcgc3RhdGUgaGVyZSByZW1vdmVzIHRoZSBxdWVzdGlvbi5cbiAqXG4gKiBBcyBpbiB0aGUgYnVpbHQtaW4gaGFuZGxlciwgYW4gZW50cnkgaXMgZHJvcHBlZCBvbmNlIGl0IGlzIHBhc3QgYHJldmFsaWRhdGVgXG4gKiByYXRoZXIgdGhhbiBzZXJ2ZWQgc3RhbGU6IGFuIGluLW1lbW9yeSBlbnRyeSBpcyBsaWtlbHkgZXZpY3RlZCBiZWZvcmUgYVxuICogYmFja2dyb3VuZCByZWZyZXNoIHdvdWxkIHBheSBvZmYuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVEZWZhdWx0VXNlQ2FjaGVIYW5kbGVyKFxuICBvcHRpb25zOiBEZWZhdWx0VXNlQ2FjaGVIYW5kbGVyT3B0aW9ucyA9IHt9LFxuKTogQ2FjaGVIYW5kbGVyIHtcbiAgY29uc3QgdGFncyA9IG9wdGlvbnMudGFncyA/PyBzaGFyZWRUYWdNYW5pZmVzdCgpO1xuICBjb25zdCBtZW1vcnkgPSBuZXcgRW50cnlMcnUoXG4gICAgbnVtYmVyRnJvbUVudihcIkNES19ORVhUSlNfVVNFX0NBQ0hFX01FTU9SWV9CWVRFU1wiLCBERUZBVUxUX01FTU9SWV9CWVRFUyksXG4gICk7XG4gIGNvbnN0IHBlbmRpbmcgPSBuZXcgUGVuZGluZ1NldHMoKTtcbiAgY29uc3QgZGVidWcgPSBnZXREZWJ1ZyhcImNkay1uZXh0anM6Y2FjaGUtaGFuZGxlcjp1c2UtY2FjaGU6ZGVmYXVsdFwiKTtcblxuICByZXR1cm4ge1xuICAgIGFzeW5jIGdldChjYWNoZUtleTogc3RyaW5nKTogUHJvbWlzZTxDYWNoZUVudHJ5IHwgdW5kZWZpbmVkPiB7XG4gICAgICBhd2FpdCBwZW5kaW5nLndhaXQoY2FjaGVLZXkpO1xuICAgICAgY29uc3Qgc3RvcmVkID0gbWVtb3J5LmdldChjYWNoZUtleSk7XG4gICAgICBpZiAoIXN0b3JlZCkge1xuICAgICAgICBkZWJ1ZyhgTUlTUyAke2NhY2hlS2V5fWApO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgaWYgKG5vdygpID4gc3RvcmVkLnRpbWVzdGFtcCArIHN0b3JlZC5yZXZhbGlkYXRlICogMTAwMCkge1xuICAgICAgICBkZWJ1ZyhgRVhQSVJFRCAke2NhY2hlS2V5fWApO1xuICAgICAgICBtZW1vcnkuZGVsZXRlKGNhY2hlS2V5KTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHRhZ3MuZW5zdXJlKHN0b3JlZC50YWdzKTtcbiAgICAgIGNvbnN0IHN0YXRlID0gdGFncy5zdGF0ZShzdG9yZWQudGFncywgc3RvcmVkLnRpbWVzdGFtcCk7XG4gICAgICBpZiAoc3RhdGUgPT09IFwiZXhwaXJlZFwiKSB7XG4gICAgICAgIGRlYnVnKGBFWFBJUkVEIEJZIFRBRyAke2NhY2hlS2V5fWApO1xuICAgICAgICBtZW1vcnkuZGVsZXRlKGNhY2hlS2V5KTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGRlYnVnKGBISVQgJHtjYWNoZUtleX0ke3N0YXRlID09PSBcInN0YWxlXCIgPyBcIiAoc3RhbGUgdGFnKVwiIDogXCJcIn1gKTtcbiAgICAgIC8vIGByZXZhbGlkYXRlOiAtMWAgaXMgaG93IHRoZSBidWlsdC1pbiBoYW5kbGVyIHJlcG9ydHMgYSBzdGFsZSB0YWc6IHRoZVxuICAgICAgLy8gd3JhcHBlciBzZXJ2ZXMgdGhlIGVudHJ5IGFuZCByZWdlbmVyYXRlcyBpdCBpbiB0aGUgYmFja2dyb3VuZC5cbiAgICAgIHJldHVybiBjYWNoZUVudHJ5T2Yoc3RvcmVkLCBzdGF0ZSA9PT0gXCJzdGFsZVwiID8gLTEgOiBzdG9yZWQucmV2YWxpZGF0ZSk7XG4gICAgfSxcblxuICAgIGFzeW5jIHNldChcbiAgICAgIGNhY2hlS2V5OiBzdHJpbmcsXG4gICAgICBwZW5kaW5nRW50cnk6IFByb21pc2U8Q2FjaGVFbnRyeT4sXG4gICAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBjb25zdCBkb25lID0gcGVuZGluZy5iZWdpbihjYWNoZUtleSk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBzdG9yZWQgPSBhd2FpdCBzdG9yZWRFbnRyeU9mKHBlbmRpbmdFbnRyeSk7XG4gICAgICAgIGlmIChpc0R5bmFtaWNFbnRyeShzdG9yZWQpKSB7XG4gICAgICAgICAgZGVidWcoYFNLSVAgZHluYW1pYyBlbnRyeSAke2NhY2hlS2V5fWApO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBtZW1vcnkuc2V0KGNhY2hlS2V5LCBzdG9yZWQpO1xuICAgICAgICB0YWdzLnRyYWNrKHN0b3JlZC50YWdzKTtcbiAgICAgICAgZGVidWcoYFNFVCAke2NhY2hlS2V5fWApO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gVGhlIHN0cmVhbSBlcnJvcmVkOiBzdG9yZSBub3RoaW5nIHJhdGhlciB0aGFuIGEgcGFydGlhbCBlbnRyeS5cbiAgICAgICAgZGVidWcoYFNFVCBGQUlMRUQgJHtjYWNoZUtleX1gLCBlcnJvcik7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBkb25lKCk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC4uLnRhZ01ldGhvZHModGFncyksXG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGxhenlIYW5kbGVyKCgpID0+IGNyZWF0ZURlZmF1bHRVc2VDYWNoZUhhbmRsZXIoKSk7XG4iXX0=
120
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlLWNhY2hlLWRlZmF1bHQtaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVyL3VzZS1jYWNoZS1kZWZhdWx0LWhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFzREEsb0VBcUdDO0FBM0pEOzs7Ozs7Ozs7O0VBVUU7QUFDRixzREFBc0Q7QUFDdEQsa0RBQTZCO0FBTTdCLHlEQWM0QjtBQU81Qjs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILFNBQWdCLDRCQUE0QixDQUMxQyxVQUF5QyxFQUFFO0lBRTNDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLElBQUksSUFBQSxvQ0FBaUIsR0FBRSxDQUFDO0lBQ2pELE1BQU0sTUFBTSxHQUFHLElBQUksMkJBQVEsQ0FDekIsSUFBQSxnQ0FBYSxFQUFDLG1DQUFtQyxFQUFFLHVDQUFvQixDQUFDLENBQ3pFLENBQUM7SUFDRixNQUFNLE9BQU8sR0FBRyxJQUFJLDhCQUFXLEVBQUUsQ0FBQztJQUNsQyxNQUFNLEtBQUssR0FBRyxJQUFBLGVBQVEsRUFBQyw0Q0FBNEMsQ0FBQyxDQUFDO0lBQ3JFLHVFQUF1RTtJQUN2RSx3RUFBd0U7SUFDeEUsYUFBYTtJQUNiLElBQUksQ0FBQyxjQUFjLENBQ2pCLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FDUCxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsSUFBQSxzQkFBRyxHQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFBLHNCQUFHLEdBQUUsQ0FBQyxFQUNsRSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUEsc0JBQUcsR0FBRSxDQUFDLENBQzlCLENBQUM7SUFFRjs7Ozs7T0FLRztJQUNILE1BQU0sVUFBVSxHQUFHLENBQUMsTUFBZSxFQUFFLE9BQTBCLEVBQUUsRUFBRSxDQUNqRSxJQUFBLDBCQUFPLEVBQUMsTUFB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TyxLQUFLLEVBQUUsQ0FBQztnQkFDZixpRUFBaUU7Z0JBQ2pFLEtBQUssQ0FBQyxjQUFjLFFBQVEsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3pDLENBQUM7b0JBQVMsQ0FBQztnQkFDVCxJQUFJLEVBQUUsQ0FBQztZQUNULENBQUM7UUFDSCxDQUFDO1FBRUQsR0FBRyxJQUFBLDZCQUFVLEVBQUMsSUFBSSxDQUFDO1FBRW5CLDBFQUEwRTtRQUMxRSxzRUFBc0U7UUFDdEUsc0VBQXNFO1FBQ3RFLGFBQWEsRUFBRSxLQUFLLElBQUksRUFBRSxDQUFDLFFBQVE7S0FDcEMsQ0FBQztBQUNKLENBQUM7QUFFRCxrQkFBZSxJQUFBLDhCQUFXLEVBQUMsR0FBRyxFQUFFLENBQUMsNEJBQTRCLEVBQUUsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgVGhlIGBjYWNoZUhhbmRsZXJzLmRlZmF1bHRgIGhhbmRsZXIsIGZvciBwbGFpbiBgJ3VzZSBjYWNoZSdgLlxuICBTZWU6IGh0dHBzOi8vbmV4dGpzLm9yZy9kb2NzL2FwcC9hcGktcmVmZXJlbmNlL2NvbmZpZy9uZXh0LWNvbmZpZy1qcy9jYWNoZUhhbmRsZXJzXG5cbiAgU3RvcmFnZSBzdGF5cyBpbiBtZW1vcnksIHBlciBpbnN0YW5jZSwgYXMgTmV4dC5qcyBpbnRlbmRzIGZvciBgJ3VzZSBjYWNoZSdgXG4gIChgJ3VzZSBjYWNoZTogcmVtb3RlJ2AgaXMgdGhlIHNoYXJlZCBvbmUpLiBXaGF0IHRoaXMgY2hhbmdlcyBpcyB0YWdzOiBOZXh0LmpzJ3NcbiAgYnVpbHQtaW4gaGFuZGxlciBrZWVwcyB0aGVtIGluIGEgcHJvY2Vzcy1sb2NhbCBtYXAsIHNvIGEgYHJldmFsaWRhdGVUYWdgIG9uXG4gIG9uZSBpbnN0YW5jZSBsZWZ0IGV2ZXJ5IG90aGVyIGluc3RhbmNlIHNlcnZpbmcgdGhlIHJldmFsaWRhdGVkIGVudHJ5LiBIZXJlXG4gIHRoZXkgZ28gdGhyb3VnaCB0aGUgcmV2YWxpZGF0aW9uIHRhYmxlJ3MgbWFya2VyIHJvd3MuIFNlZVxuICBgVHJhY2tlZFRhZ01hcmtlcnNgLlxuKi9cbi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IGdldERlYnVnIGZyb20gXCJkZWJ1Z1wiO1xuaW1wb3J0IHR5cGUge1xuICBDYWNoZUVudHJ5LFxuICBDYWNoZUhhbmRsZXIsXG59IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL2xpYi9jYWNoZS1oYW5kbGVycy90eXBlc1wiO1xuaW1wb3J0IHsgVHJhY2tlZFRhZ01hcmtlcnMgfSBmcm9tIFwiLi9hd3MtY2FjaGUtc3RvcmVcIjtcbmltcG9ydCB7XG4gIGF3YWl0SWYsXG4gIGNhY2hlRW50cnlPZixcbiAgREVGQVVMVF9NRU1PUllfQllURVMsXG4gIEVudHJ5THJ1LFxuICBpc0R5bmFtaWNFbnRyeSxcbiAgaXNQYXN0UmV2YWxpZGF0ZSxcbiAgbGF6eUhhbmRsZXIsXG4gIG5vdyxcbiAgbnVtYmVyRnJvbUVudixcbiAgUGVuZGluZ1NldHMsXG4gIHNoYXJlZFRhZ01hbmlmZXN0LFxuICBzdG9yZWRFbnRyeU9mLFxuICB0YWdNZXRob2RzLFxufSBmcm9tIFwiLi91c2UtY2FjaGUtY29tbW9uXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVmYXVsdFVzZUNhY2hlSGFuZGxlck9wdGlvbnMge1xuICAvKiogVGFnIHN0YXRlOyB0aGUgcHJvY2Vzcy13aWRlIG9uZSBmcm9tIHRoZSBlbnZpcm9ubWVudCBieSBkZWZhdWx0LiAqL1xuICB0YWdzPzogVHJhY2tlZFRhZ01hcmtlcnM7XG59XG5cbi8qKlxuICogQSBgJ3VzZSBjYWNoZSdgIGhhbmRsZXIgd2l0aCB0aGUgc2VtYW50aWNzIG9mIE5leHQuanMncyBidWlsdC1pbiBvbmVcbiAqIChgbmV4dC9kaXN0L3NlcnZlci9saWIvY2FjaGUtaGFuZGxlcnMvZGVmYXVsdC5qc2ApIGFuZCB0YWdzIHNoYXJlZCBhY3Jvc3NcbiAqIGluc3RhbmNlcy5cbiAqXG4gKiBBbiBlcXVpdmFsZW50IHJhdGhlciB0aGFuIGEgd3JhcHBlcjogdGhlIGJ1aWx0LWluIGhhbmRsZXIganVkZ2VzIHRhZ3MgYWdhaW5zdFxuICogdGhlIG1vZHVsZS1sZXZlbCBgdGFnc01hbmlmZXN0YCBvZiB3aGljaGV2ZXIgY29weSBvZiBgbmV4dGAgaXQgd2FzIHJlcXVpcmVkXG4gKiBmcm9tLCBhbmQgdGhpcyBidW5kbGUgY2Fubm90IGJlIHN1cmUgb2YgcmVhY2hpbmcgdGhlIGNvcHkgdGhlIHNlcnZlciBsb2FkZWRcbiAqICh0aGUgc2FtZSByZWFzb24gYFMzQ2FjaGVIYW5kbGVyYCByZWFkcyB0aGF0IG1hbmlmZXN0IGZyb20gdGhlIG1vZHVsZSBjYWNoZVxuICogaW5zdGVhZCBvZiByZXF1aXJpbmcgaXQpLiBLZWVwaW5nIHRoZSB0YWcgc3RhdGUgaGVyZSByZW1vdmVzIHRoZSBxdWVzdGlvbi5cbiAqXG4gKiBBcyBpbiB0aGUgYnVpbHQtaW4gaGFuZGxlciwgYW4gZW50cnkgaXMgZHJvcHBlZCBvbmNlIGl0IGlzIHBhc3QgYHJldmFsaWRhdGVgXG4gKiByYXRoZXIgdGhhbiBzZXJ2ZWQgc3RhbGU6IGFuIGluLW1lbW9yeSBlbnRyeSBpcyBsaWtlbHkgZXZpY3RlZCBiZWZvcmUgYVxuICogYmFja2dyb3VuZCByZWZyZXNoIHdvdWxkIHBheSBvZmYuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVEZWZhdWx0VXNlQ2FjaGVIYW5kbGVyKFxuICBvcHRpb25zOiBEZWZhdWx0VXNlQ2FjaGVIYW5kbGVyT3B0aW9ucyA9IHt9LFxuKTogQ2FjaGVIYW5kbGVyIHtcbiAgY29uc3QgdGFncyA9IG9wdGlvbnMudGFncyA/PyBzaGFyZWRUYWdNYW5pZmVzdCgpO1xuICBjb25zdCBtZW1vcnkgPSBuZXcgRW50cnlMcnUoXG4gICAgbnVtYmVyRnJvbUVudihcIkNES19ORVhUSlNfVVNFX0NBQ0hFX01FTU9SWV9CWVRFU1wiLCBERUZBVUxUX01FTU9SWV9CWVRFUyksXG4gICk7XG4gIGNvbnN0IHBlbmRpbmcgPSBuZXcgUGVuZGluZ1NldHMoKTtcbiAgY29uc3QgZGVidWcgPSBnZXREZWJ1ZyhcImNkay1uZXh0anM6Y2FjaGUtaGFuZGxlcjp1c2UtY2FjaGU6ZGVmYXVsdFwiKTtcbiAgLy8gRXhwaXJlZCBlbnRyaWVzLCB3aGljaCBgZ2V0YCBkcm9wcyBhbnl3YXksIGRvbid0IGNvdW50IGFzIGhlbGQgZm9yIGFcbiAgLy8gcmVmcmVzaCB0byB3YWl0IGZvciwgbm9yIGhvbGQgYGNvbXBsZXRlU2luY2VgJ3MgcHJ1bmluZyBiYWNrIHBhc3QgdGhlXG4gIC8vIG5leHQgc2Nhbi5cbiAgdGFncy5qdWRnZUVudHJpZXNPZihcbiAgICAoc2NhbikgPT5cbiAgICAgIHNjYW4gPyBtZW1vcnkub2xkZXN0VGltZXN0YW1wKG5vdygpKSA6IG1lbW9yeS5vbGRlc3RCb3VuZChub3coKSksXG4gICAgKCkgPT4gbWVtb3J5LmhvbGRzTGl2ZShub3coKSksXG4gICk7XG5cbiAgLyoqXG4gICAqIFJlYWQgdGhlIG1hcmtlcnMgb2Ygd2hpY2hldmVyIG9mIGB0YWdMaXN0YCBhcmUgdW50cmFja2VkOiBmaXJzdCwgd2hlbiB0aGVcbiAgICogYW5zd2VyIGRlcGVuZHMgb24gdGhlbSwgb3IgZWxzZSBpbiB0aGUgYmFja2dyb3VuZC4gUmVhZCBlaXRoZXIgd2F5LCBzb1xuICAgKiB0aGUgdGFncyBqb2luIHRoZSByb2xsaW5nIHJlLXJlYWQsIHdoaWNoIGNhdGNoZXMgYSByZXZhbGlkYXRpb24gd2hvc2UgbG9nXG4gICAqIHJvdyBmYWlsZWQgdG8gd3JpdGUuXG4gICAqL1xuICBjb25zdCBlbnN1cmVUYWdzID0gKG5lZWRlZDogYm9vbGVhbiwgdGFnTGlzdDogcmVhZG9ubHkgc3RyaW5nW10pID0+XG4gICAgYXdhaXRJZihuZWVkZWQsIHRhZ3MuZW5zdXJlKHRhZ0xpc3QpLCBcIkVycm9yIHJlYWRpbmcgY2FjaGUgdGFnczpcIik7XG5cbiAgcmV0dXJuIHtcbiAgICBhc3luYyBnZXQoXG4gICAgICBjYWNoZUtleTogc3RyaW5nLFxuICAgICAgc29mdFRhZ3M6IHN0cmluZ1tdID0gW10sXG4gICAgKTogUHJvbWlzZTxDYWNoZUVudHJ5IHwgdW5kZWZpbmVkPiB7XG4gICAgICBhd2FpdCBwZW5kaW5nLndhaXQoY2FjaGVLZXkpO1xuICAgICAgY29uc3Qgc3RvcmVkID0gbWVtb3J5LmdldChjYWNoZUtleSk7XG4gICAgICBpZiAoIXN0b3JlZCkge1xuICAgICAgICBkZWJ1ZyhgTUlTUyAke2NhY2hlS2V5fWApO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgaWYgKGlzUGFzdFJldmFsaWRhdGUoc3RvcmVkLCBub3coKSkpIHtcbiAgICAgICAgZGVidWcoYEVYUElSRUQgJHtjYWNoZUtleX1gKTtcbiAgICAgICAgbWVtb3J5LmRlbGV0ZShjYWNoZUtleSk7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICAvLyBPbmx5IGFuIGVudHJ5IG9sZGVyIHRoYW4gd2hhdCB0aGUgbWFuaWZlc3QgZnVsbHkga25vd3MgbmVlZHMgaXRzIHRhZ3MnXG4gICAgICAvLyBtYXJrZXJzIHJlYWQgZmlyc3Q6IHNlZSBgY29tcGxldGVTaW5jZWAuIEV2ZXJ5IGVudHJ5IHN0b3JlZCBzaW5jZSB0aGVcbiAgICAgIC8vIGluc3RhbmNlIHN0YXJ0ZWQgaXMgbmV3ZXIsIHNvIGl0cyBmaXJzdCByZWFkIHdhaXRzIG9uIG5vdGhpbmcgLSBub3JcbiAgICAgIC8vIGRvZXMgYSBuZXcgcGF0aCdzLCB3aG9zZSBpbXBsaWNpdCB0YWdzIGl0IGhhcyBuZXZlciByZWFkLlxuICAgICAgYXdhaXQgZW5zdXJlVGFncyhzdG9yZWQudGltZXN0YW1wIDwgdGFncy5jb21wbGV0ZVNpbmNlLCBbXG4gICAgICAgIC4uLnN0b3JlZC50YWdzLFxuICAgICAgICAuLi5zb2Z0VGFncyxcbiAgICAgIF0pO1xuICAgICAgLy8gSW1wbGljaXQgdGFncyBjb3VudCBvbmNlIGV4cGlyZWQsIG5vdCBzdGFsZSwgYXMgTmV4dC5qcyBjb21wYXJlc1xuICAgICAgLy8gYGdldEV4cGlyYXRpb25gJ3MgYW5zd2VyLlxuICAgICAgY29uc3Qgc3RhdGUgPVxuICAgICAgICB0YWdzLmV4cGlyYXRpb24oc29mdFRhZ3MpID49IHN0b3JlZC50aW1lc3RhbXBcbiAgICAgICAgICA/IFwiZXhwaXJlZFwiXG4gICAgICAgICAgOiB0YWdzLnN0YXRlKHN0b3JlZC50YWdzLCBzdG9yZWQudGltZXN0YW1wKTtcbiAgICAgIGlmIChzdGF0ZSA9PT0gXCJleHBpcmVkXCIpIHtcbiAgICAgICAgZGVidWcoYEVYUElSRUQgQlkgVEFHICR7Y2FjaGVLZXl9YCk7XG4gICAgICAgIG1lbW9yeS5kZWxldGUoY2FjaGVLZXkpO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgZGVidWcoYEhJVCAke2NhY2hlS2V5fSR7c3RhdGUgPT09IFwic3RhbGVcIiA/IFwiIChzdGFsZSB0YWcpXCIgOiBcIlwifWApO1xuICAgICAgLy8gYHJldmFsaWRhdGU6IC0xYCBpcyBob3cgdGhlIGJ1aWx0LWluIGhhbmRsZXIgcmVwb3J0cyBhIHN0YWxlIHRhZzogdGhlXG4gICAgICAvLyB3cmFwcGVyIHNlcnZlcyB0aGUgZW50cnkgYW5kIHJlZ2VuZXJhdGVzIGl0IGluIHRoZSBiYWNrZ3JvdW5kLlxuICAgICAgcmV0dXJuIGNhY2hlRW50cnlPZihzdG9yZWQsIHN0YXRlID09PSBcInN0YWxlXCIgPyAtMSA6IHN0b3JlZC5yZXZhbGlkYXRlKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgc2V0KFxuICAgICAgY2FjaGVLZXk6IHN0cmluZyxcbiAgICAgIHBlbmRpbmdFbnRyeTogUHJvbWlzZTxDYWNoZUVudHJ5PixcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGNvbnN0IGRvbmUgPSBwZW5kaW5nLmJlZ2luKGNhY2hlS2V5KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHN0b3JlZCA9IGF3YWl0IHN0b3JlZEVudHJ5T2YocGVuZGluZ0VudHJ5KTtcbiAgICAgICAgaWYgKGlzRHluYW1pY0VudHJ5KHN0b3JlZCkpIHtcbiAgICAgICAgICBkZWJ1ZyhgU0tJUCBkeW5hbWljIGVudHJ5ICR7Y2FjaGVLZXl9YCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIG1lbW9yeS5zZXQoY2FjaGVLZXksIHN0b3JlZCk7XG4gICAgICAgIC8vIEluIHRoZSBiYWNrZ3JvdW5kLCBub3cgcmF0aGVyIHRoYW4gYXQgdGhlIGZpcnN0IGBnZXRgOiBhXG4gICAgICAgIC8vIHJldmFsaWRhdGlvbiBmcm9tIGJlZm9yZSB0aGUgbG9nJ3MgZmlyc3QgbG9va2JhY2sgd2l0aCBhbiBgZXhwaXJlYFxuICAgICAgICAvLyBzdGlsbCB0byBjb21lIGV4cGlyZXMgdGhpcyBlbnRyeSB3aGVuIGl0IGNvbWVzLCBhbmQgb25seSB0aGUgbWFya2VyXG4gICAgICAgIC8vIHNheXMgc28uIFNlZSBgY29tcGxldGVTaW5jZWAuXG4gICAgICAgIHZvaWQgZW5zdXJlVGFncyhmYWxzZSwgc3RvcmVkLnRhZ3MpO1xuICAgICAgICBkZWJ1ZyhgU0VUICR7Y2FjaGVLZXl9YCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBUaGUgc3RyZWFtIGVycm9yZWQ6IHN0b3JlIG5vdGhpbmcgcmF0aGVyIHRoYW4gYSBwYXJ0aWFsIGVudHJ5LlxuICAgICAgICBkZWJ1ZyhgU0VUIEZBSUxFRCAke2NhY2hlS2V5fWAsIGVycm9yKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLi4udGFnTWV0aG9kcyh0YWdzKSxcblxuICAgIC8vIGBJbmZpbml0eWAgaGFzIE5leHQuanMgcGFzcyB0aGUgaW1wbGljaXQgdGFncyB0byBgZ2V0YCBpbnN0ZWFkLCBzbyB0aGV5XG4gICAgLy8gYXJlIGp1ZGdlZCBhZ2FpbnN0IHRoZSBlbnRyeSByZWFkOiB3aGV0aGVyIGFuc3dlcmluZyBuZWVkcyBhIG1hcmtlclxuICAgIC8vIHJlYWQgZGVwZW5kcyBvbiB0aGF0IGVudHJ5J3MgYHRpbWVzdGFtcGAsIHdoaWNoIHRoaXMgZG9lcyBub3Qga25vdy5cbiAgICBnZXRFeHBpcmF0aW9uOiBhc3luYyAoKSA9PiBJbmZpbml0eSxcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgbGF6eUhhbmRsZXIoKCkgPT4gY3JlYXRlRGVmYXVsdFVzZUNhY2hlSGFuZGxlcigpKTtcbiJdfQ==