cdk-nextjs 0.6.1 → 0.7.0

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 (266) hide show
  1. package/.jsii +2467 -2714
  2. package/.jsii.tabl.json +1 -1
  3. package/API.md +1725 -1909
  4. package/CLAUDE.md +2 -1
  5. package/README.md +429 -130
  6. package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +152 -170
  7. package/assets/lambdas/redeploy-stage/redeploy-stage.lambda/index.js +875 -0
  8. package/docs/adapter-runtime.md +185 -0
  9. package/docs/breaking-changes.md +687 -4
  10. package/docs/caching-guide.md +156 -112
  11. package/docs/cdk-nextjs-cfn-exec-policy.json +2 -1
  12. package/docs/development-guide.md +1 -1
  13. package/docs/harness-coverage.md +598 -0
  14. package/docs/init-cache-deployment.md +32 -1
  15. package/docs/next-build-output-guide.md +30 -20
  16. package/examples/README.md +5 -1
  17. package/lib/adapter/__fixtures__/app-playground-base-path.json +4926 -0
  18. package/lib/adapter/__fixtures__/app-playground.json +4917 -0
  19. package/lib/adapter/__fixtures__/pages-i18n.json +1728 -0
  20. package/lib/adapter/adapter.mjs +1548 -185
  21. package/lib/adapter/adapter.test.js +106 -0
  22. package/lib/adapter/aws-cache-store.d.ts +489 -0
  23. package/lib/adapter/aws-cache-store.js +1004 -0
  24. package/lib/adapter/aws-cache-store.test.d.ts +1 -0
  25. package/lib/adapter/aws-cache-store.test.js +361 -0
  26. package/lib/adapter/build-outputs.d.ts +80 -0
  27. package/lib/adapter/build-outputs.js +852 -0
  28. package/lib/adapter/build-outputs.test.d.ts +1 -0
  29. package/lib/adapter/build-outputs.test.js +861 -0
  30. package/lib/adapter/cache-handler.d.ts +9 -2
  31. package/lib/adapter/cache-handler.js +72 -96
  32. package/lib/adapter/cache-handler.mjs +18956 -17774
  33. package/lib/adapter/cache-handler.test.js +263 -31
  34. package/lib/adapter/cache-kinds.d.ts +32 -0
  35. package/lib/adapter/cache-kinds.js +35 -0
  36. package/lib/adapter/cache-kinds.test.d.ts +1 -0
  37. package/lib/adapter/cache-kinds.test.js +69 -0
  38. package/lib/adapter/cache-utils.d.ts +90 -0
  39. package/lib/adapter/cache-utils.js +199 -4
  40. package/lib/adapter/cache-utils.test.d.ts +1 -0
  41. package/lib/adapter/cache-utils.test.js +179 -0
  42. package/lib/adapter/function-groups.d.ts +215 -0
  43. package/lib/adapter/function-groups.js +1099 -0
  44. package/lib/adapter/function-groups.test.d.ts +1 -0
  45. package/lib/adapter/function-groups.test.js +743 -0
  46. package/lib/adapter/init-cache.d.ts +6 -0
  47. package/lib/adapter/init-cache.js +245 -0
  48. package/lib/adapter/init-cache.test.d.ts +1 -0
  49. package/lib/adapter/init-cache.test.js +137 -0
  50. package/lib/adapter/local-file-cache-handler.d.ts +23 -0
  51. package/lib/adapter/local-file-cache-handler.js +52 -1
  52. package/lib/adapter/memory-cache-handler.d.ts +26 -17
  53. package/lib/adapter/memory-cache-handler.js +32 -50
  54. package/lib/adapter/memory-cache-handler.test.js +105 -85
  55. package/lib/adapter/s3-cache-handler.d.ts +179 -40
  56. package/lib/adapter/s3-cache-handler.js +807 -277
  57. package/lib/adapter/s3-cache-handler.test.js +1186 -31
  58. package/lib/adapter/use-cache-common.d.ts +90 -0
  59. package/lib/adapter/use-cache-common.js +250 -0
  60. package/lib/adapter/use-cache-common.test.d.ts +1 -0
  61. package/lib/adapter/use-cache-common.test.js +646 -0
  62. package/lib/adapter/use-cache-default-handler.d.ts +24 -0
  63. package/lib/adapter/use-cache-default-handler.js +90 -0
  64. package/lib/adapter/use-cache-default-handler.mjs +38645 -0
  65. package/lib/adapter/use-cache-handlers.test.d.ts +1 -0
  66. package/lib/adapter/use-cache-handlers.test.js +349 -0
  67. package/lib/adapter/use-cache-remote-handler.d.ts +26 -0
  68. package/lib/adapter/use-cache-remote-handler.js +186 -0
  69. package/lib/{image-optimization/handler.mjs → adapter/use-cache-remote-handler.mjs} +33572 -38798
  70. package/lib/generated-structs/OptionalNextjsApiProps.d.ts +59 -0
  71. package/lib/generated-structs/OptionalNextjsApiProps.js +3 -0
  72. package/lib/generated-structs/OptionalNextjsCacheProps.d.ts +15 -6
  73. package/lib/generated-structs/OptionalNextjsCacheProps.js +1 -1
  74. package/lib/generated-structs/OptionalNextjsContainersProps.d.ts +25 -11
  75. package/lib/generated-structs/OptionalNextjsContainersProps.js +1 -1
  76. package/lib/generated-structs/OptionalNextjsDistributionProps.d.ts +31 -9
  77. package/lib/generated-structs/OptionalNextjsDistributionProps.js +1 -1
  78. package/lib/generated-structs/OptionalNextjsPostDeployProps.d.ts +13 -0
  79. package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
  80. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +11 -2
  81. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.js +1 -1
  82. package/lib/index.d.ts +6 -7
  83. package/lib/index.js +2 -4
  84. package/lib/lambdas/post-deploy/post-deploy.lambda.js +3 -2
  85. package/lib/lambdas/post-deploy/prune-cache-bucket.d.ts +7 -3
  86. package/lib/lambdas/post-deploy/prune-cache-bucket.js +57 -71
  87. package/lib/lambdas/post-deploy/prune-cache-bucket.test.d.ts +1 -0
  88. package/lib/lambdas/post-deploy/prune-cache-bucket.test.js +114 -0
  89. package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +1 -0
  90. package/lib/lambdas/post-deploy/prune-revalidation-table.js +23 -31
  91. package/lib/lambdas/post-deploy/prune-revalidation-table.test.d.ts +1 -0
  92. package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +71 -0
  93. package/lib/lambdas/post-deploy/prune-s3.d.ts +19 -3
  94. package/lib/lambdas/post-deploy/prune-s3.js +54 -15
  95. package/lib/lambdas/post-deploy/prune-s3.test.d.ts +1 -0
  96. package/lib/lambdas/post-deploy/prune-s3.test.js +255 -0
  97. package/lib/lambdas/redeploy-stage/redeploy-stage-function.d.ts +13 -0
  98. package/lib/lambdas/redeploy-stage/redeploy-stage-function.js +55 -0
  99. package/lib/lambdas/redeploy-stage/redeploy-stage.d.ts +24 -0
  100. package/lib/lambdas/redeploy-stage/redeploy-stage.js +68 -0
  101. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.d.ts +20 -0
  102. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.js +24 -0
  103. package/lib/lambdas/redeploy-stage/redeploy-stage.test.d.ts +1 -0
  104. package/lib/lambdas/redeploy-stage/redeploy-stage.test.js +93 -0
  105. package/lib/nextjs-api.d.ts +107 -18
  106. package/lib/nextjs-api.js +349 -39
  107. package/lib/nextjs-api.test.js +582 -1
  108. package/lib/nextjs-build/global-containers.Dockerfile +15 -10
  109. package/lib/nextjs-build/nextjs-build.d.ts +339 -63
  110. package/lib/nextjs-build/nextjs-build.js +684 -327
  111. package/lib/nextjs-build/nextjs-build.test.d.ts +1 -0
  112. package/lib/nextjs-build/nextjs-build.test.js +412 -0
  113. package/lib/nextjs-build/patch-fetch.js +1 -1
  114. package/lib/nextjs-build/patch-fetch.test.js +166 -11
  115. package/lib/nextjs-build/regional-containers.Dockerfile +17 -10
  116. package/lib/nextjs-cache.d.ts +82 -4
  117. package/lib/nextjs-cache.js +186 -10
  118. package/lib/nextjs-cache.test.js +176 -1
  119. package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +21 -8
  120. package/lib/nextjs-compute/nextjs-compute-base-props.js +41 -1
  121. package/lib/nextjs-compute/nextjs-compute-base-props.test.d.ts +1 -0
  122. package/lib/nextjs-compute/nextjs-compute-base-props.test.js +44 -0
  123. package/lib/nextjs-compute/nextjs-containers.d.ts +19 -0
  124. package/lib/nextjs-compute/nextjs-containers.js +57 -20
  125. package/lib/nextjs-compute/nextjs-functions.d.ts +122 -7
  126. package/lib/nextjs-compute/nextjs-functions.js +113 -67
  127. package/lib/nextjs-compute/nextjs-functions.test.d.ts +1 -0
  128. package/lib/nextjs-compute/nextjs-functions.test.js +99 -0
  129. package/lib/nextjs-distribution.d.ts +194 -23
  130. package/lib/nextjs-distribution.js +535 -62
  131. package/lib/nextjs-distribution.test.d.ts +1 -0
  132. package/lib/nextjs-distribution.test.js +697 -0
  133. package/lib/nextjs-post-deploy.d.ts +23 -3
  134. package/lib/nextjs-post-deploy.js +14 -10
  135. package/lib/nextjs-post-deploy.test.d.ts +1 -0
  136. package/lib/nextjs-post-deploy.test.js +34 -0
  137. package/lib/nextjs-static-assets.d.ts +23 -4
  138. package/lib/nextjs-static-assets.js +29 -6
  139. package/lib/nextjs-static-assets.test.js +20 -1
  140. package/lib/root-constructs/nextjs-base-construct.d.ts +105 -45
  141. package/lib/root-constructs/nextjs-base-construct.js +144 -34
  142. package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
  143. package/lib/root-constructs/nextjs-global-containers.js +20 -70
  144. package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
  145. package/lib/root-constructs/nextjs-global-functions.js +52 -69
  146. package/lib/root-constructs/nextjs-regional-containers.d.ts +25 -5
  147. package/lib/root-constructs/nextjs-regional-containers.js +17 -15
  148. package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
  149. package/lib/root-constructs/nextjs-regional-functions.js +8 -25
  150. package/lib/runtime/api-gateway-path.d.ts +34 -0
  151. package/lib/runtime/api-gateway-path.js +71 -0
  152. package/lib/runtime/api-gateway-path.test.d.ts +1 -0
  153. package/lib/runtime/api-gateway-path.test.js +65 -0
  154. package/lib/runtime/case-redirect.d.ts +22 -0
  155. package/lib/runtime/case-redirect.js +63 -0
  156. package/lib/runtime/case-redirect.test.d.ts +1 -0
  157. package/lib/runtime/case-redirect.test.js +32 -0
  158. package/lib/runtime/core.d.ts +234 -0
  159. package/lib/runtime/core.js +1213 -0
  160. package/lib/runtime/core.test.d.ts +1 -0
  161. package/lib/runtime/core.test.js +1678 -0
  162. package/lib/runtime/deployment-root.d.ts +13 -0
  163. package/lib/runtime/deployment-root.js +29 -0
  164. package/lib/runtime/dispatch.d.ts +331 -0
  165. package/lib/runtime/dispatch.js +751 -0
  166. package/lib/runtime/dispatch.test.d.ts +1 -0
  167. package/lib/runtime/dispatch.test.js +853 -0
  168. package/lib/runtime/entrypoints.d.ts +57 -0
  169. package/lib/runtime/entrypoints.js +115 -0
  170. package/lib/runtime/http/abort-signal.d.ts +6 -0
  171. package/lib/runtime/http/abort-signal.js +19 -0
  172. package/lib/runtime/http/abort-signal.test.d.ts +1 -0
  173. package/lib/runtime/http/abort-signal.test.js +49 -0
  174. package/lib/runtime/http/node-server.d.ts +38 -0
  175. package/lib/runtime/http/node-server.js +99 -0
  176. package/lib/runtime/http/node-server.test.d.ts +1 -0
  177. package/lib/runtime/http/node-server.test.js +96 -0
  178. package/lib/runtime/http/node-sink.d.ts +16 -0
  179. package/lib/runtime/http/node-sink.js +48 -0
  180. package/lib/runtime/http/node-sink.test.d.ts +1 -0
  181. package/lib/runtime/http/node-sink.test.js +66 -0
  182. package/lib/runtime/http/request.d.ts +62 -0
  183. package/lib/runtime/http/request.js +134 -0
  184. package/lib/runtime/http/request.test.d.ts +1 -0
  185. package/lib/runtime/http/request.test.js +103 -0
  186. package/lib/runtime/http/response.d.ts +77 -0
  187. package/lib/runtime/http/response.js +229 -0
  188. package/lib/runtime/http/response.test.d.ts +1 -0
  189. package/lib/runtime/http/response.test.js +178 -0
  190. package/lib/runtime/http/sink.d.ts +73 -0
  191. package/lib/runtime/http/sink.js +188 -0
  192. package/lib/runtime/http/sink.test.d.ts +1 -0
  193. package/lib/runtime/http/sink.test.js +257 -0
  194. package/lib/runtime/image-utils.d.ts +78 -0
  195. package/lib/runtime/image-utils.js +129 -0
  196. package/lib/runtime/image-utils.test.d.ts +1 -0
  197. package/lib/runtime/image-utils.test.js +237 -0
  198. package/lib/runtime/image.d.ts +76 -0
  199. package/lib/runtime/image.js +296 -0
  200. package/lib/runtime/image.test.d.ts +1 -0
  201. package/lib/runtime/image.test.js +405 -0
  202. package/lib/runtime/lambda-event.d.ts +4 -0
  203. package/lib/runtime/lambda-event.js +113 -0
  204. package/lib/runtime/lambda-event.test.d.ts +1 -0
  205. package/lib/runtime/lambda-event.test.js +119 -0
  206. package/lib/runtime/lambda.mjs +41595 -0
  207. package/lib/runtime/load-module.d.ts +8 -0
  208. package/lib/runtime/load-module.js +35 -0
  209. package/lib/runtime/manifest.d.ts +215 -0
  210. package/lib/runtime/manifest.js +118 -0
  211. package/lib/runtime/middleware.d.ts +43 -0
  212. package/lib/runtime/middleware.js +113 -0
  213. package/lib/runtime/middleware.test.d.ts +1 -0
  214. package/lib/runtime/middleware.test.js +259 -0
  215. package/lib/runtime/next-modules.d.ts +55 -0
  216. package/lib/runtime/next-modules.js +124 -0
  217. package/lib/runtime/next-modules.test.d.ts +1 -0
  218. package/lib/runtime/next-modules.test.js +34 -0
  219. package/lib/runtime/public-files.d.ts +32 -0
  220. package/lib/runtime/public-files.js +117 -0
  221. package/lib/runtime/public-files.test.d.ts +1 -0
  222. package/lib/runtime/public-files.test.js +97 -0
  223. package/lib/runtime/server.mjs +41588 -0
  224. package/lib/runtime/static-files.d.ts +50 -0
  225. package/lib/runtime/static-files.js +266 -0
  226. package/lib/runtime/static-files.test.d.ts +1 -0
  227. package/lib/runtime/static-files.test.js +118 -0
  228. package/lib/runtime/util.d.ts +28 -0
  229. package/lib/runtime/util.js +79 -0
  230. package/lib/utils/base-path.d.ts +123 -11
  231. package/lib/utils/base-path.js +276 -39
  232. package/lib/utils/base-path.test.js +275 -50
  233. package/lib/utils/get-architecture.d.ts +7 -8
  234. package/lib/utils/get-architecture.js +12 -13
  235. package/lib/utils/zip-directory.d.ts +14 -0
  236. package/lib/utils/zip-directory.js +121 -0
  237. package/lib/utils/zip-directory.test.d.ts +1 -0
  238. package/lib/utils/zip-directory.test.js +99 -0
  239. package/package.json +22 -3
  240. package/scripts/capture-adapter-fixture.mjs +325 -0
  241. package/scripts/e2e-deploy.sh +398 -0
  242. package/scripts/e2e-harness/README.md +707 -0
  243. package/scripts/e2e-harness/app.js +370 -0
  244. package/scripts/e2e-harness/common.sh +249 -0
  245. package/scripts/e2e-harness/screen.mjs +302 -0
  246. package/scripts/e2e-harness/stage-proxy.mjs +145 -0
  247. package/scripts/e2e-harness/type-filters.mjs +47 -0
  248. package/scripts/e2e-logs.sh +75 -0
  249. package/scripts/e2e-offline.sh +91 -0
  250. package/scripts/e2e-sweep.sh +370 -0
  251. package/scripts/e2e-warm.sh +114 -0
  252. package/scripts/zero-config-build.mjs +418 -0
  253. package/docs/1k-concurrent-users-executions.png +0 -0
  254. package/docs/plans/adapter-runtime-release.md +0 -362
  255. package/docs/plans/phase-0-image-function-opt-in.md +0 -295
  256. package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +0 -425
  257. package/lib/generated-structs/OptionalDockerImageFunctionProps.js +0 -3
  258. package/lib/image-optimization/handler-utils.d.ts +0 -34
  259. package/lib/image-optimization/handler-utils.js +0 -83
  260. package/lib/image-optimization/handler-utils.test.js +0 -178
  261. package/lib/nextjs-build/functions.Dockerfile +0 -31
  262. package/lib/nextjs-compute/nextjs-image-function.d.ts +0 -53
  263. package/lib/nextjs-compute/nextjs-image-function.js +0 -59
  264. package/lib/utils/experimental-flags.d.ts +0 -24
  265. package/lib/utils/experimental-flags.js +0 -30
  266. /package/lib/{image-optimization/handler-utils.test.d.ts → adapter/adapter.test.d.ts} +0 -0
@@ -1,19 +1,21 @@
1
- import { CacheHandler, CacheHandlerValue, CacheHandlerContext } from "next/dist/server/lib/incremental-cache";
2
- import { IncrementalCacheValue, GetIncrementalFetchCacheContext, GetIncrementalResponseCacheContext, SetIncrementalResponseCacheContext, SetIncrementalFetchCacheContext } from "next/dist/server/response-cache";
3
- export interface MemoryCacheHandlerOptions {
4
- context: CacheHandlerContext;
5
- }
6
- export declare class MemoryCacheHandler implements CacheHandler {
1
+ import { CacheHandlerValue } from "next/dist/server/lib/incremental-cache";
2
+ import { IncrementalCacheValue } from "next/dist/server/response-cache";
3
+ /**
4
+ * The in-memory layer the orchestrating handler puts in front of
5
+ * `S3CacheHandler`. Not a `CacheHandler` of its own: it has no tags, since
6
+ * every hit is checked against the tag markers before it is served.
7
+ */
8
+ export declare class MemoryCacheHandler {
7
9
  private inMemoryCache;
8
10
  private debug;
9
11
  /**
10
12
  * Time to live in milliseconds for cache entries.
11
13
  * After this duration, entries expire and are removed from the cache.
12
14
  *
13
- * **Important**: Due to the distributed nature of compute instances (Lambda functions,
14
- * ECS Fargate containers, etc.), this cache only provides eventual consistency across
15
- * instances. Tag revalidations will clear the cache on the instance that processes
16
- * the revalidation, but other instances may serve stale data until their cache entries expire.
15
+ * Tag revalidations never clear this cache: the orchestrating handler checks
16
+ * each memory hit against the tag markers before serving it
17
+ * (`S3CacheHandler.isRevalidated`), so a revalidated entry is not served from
18
+ * memory anywhere.
17
19
  *
18
20
  * @example
19
21
  * // Short TTL (5 minutes) - for frequently changing data
@@ -28,8 +30,8 @@ export declare class MemoryCacheHandler implements CacheHandler {
28
30
  * ttlMs = 24 * 60 * 60 * 1000;
29
31
  *
30
32
  * **Why adjust this?**
31
- * - Lower values: More cache misses, fresher data, higher S3/DynamoDB costs
32
- * - Higher values: Fewer cache misses, better performance, but longer stale data windows
33
+ * - Lower values: More cache misses, higher S3 costs
34
+ * - Higher values: Fewer cache misses, more memory held
33
35
  *
34
36
  * Set via environment variable: `CDK_NEXTJS_MEMORY_CACHE_TTL_MS`
35
37
  */
@@ -62,11 +64,18 @@ export declare class MemoryCacheHandler implements CacheHandler {
62
64
  * Set via environment variable: `CDK_NEXTJS_MEMORY_CACHE_MAX_ENTRIES`
63
65
  */
64
66
  private readonly maxEntries;
65
- constructor(options: MemoryCacheHandlerOptions);
66
- get(cacheKey: string, ctx: GetIncrementalFetchCacheContext | GetIncrementalResponseCacheContext): Promise<CacheHandlerValue | null>;
67
- set(cacheKey: string, data: IncrementalCacheValue | null, ctx: SetIncrementalFetchCacheContext | SetIncrementalResponseCacheContext): Promise<void>;
68
- revalidateTag(tag: string | string[]): Promise<void>;
69
- resetRequestCache(): Promise<void>;
67
+ constructor();
68
+ get(cacheKey: string): Promise<CacheHandlerValue | null>;
69
+ /**
70
+ * `lastModified` is the time the entry was rendered, for an entry copied in
71
+ * from a slower layer; a fresh render leaves it out and is stamped now - on
72
+ * {@link markerClock}, like the S3 copy of the same render. A memory hit is
73
+ * checked against the tag markers, which are stamped on that clock, and
74
+ * `Date.now()` drifts from it for as long as the process lives: an entry
75
+ * stamped ahead of it looked newer than a `revalidateTag` run within the
76
+ * drift, and was served for the whole memory TTL.
77
+ */
78
+ set(cacheKey: string, data: IncrementalCacheValue | null, lastModified?: number): Promise<void>;
70
79
  /**
71
80
  * Remove all expired cache entries
72
81
  */
@@ -5,11 +5,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.MemoryCacheHandler = void 0;
7
7
  /*
8
- In-memory cache handler with tag management
8
+ In-memory cache handler
9
9
  */
10
10
  /* eslint-disable import/no-extraneous-dependencies */
11
11
  const debug_1 = __importDefault(require("debug"));
12
- const cache_utils_1 = require("./cache-utils");
12
+ const aws_cache_store_1 = require("./aws-cache-store");
13
+ const use_cache_common_1 = require("./use-cache-common");
14
+ /**
15
+ * The in-memory layer the orchestrating handler puts in front of
16
+ * `S3CacheHandler`. Not a `CacheHandler` of its own: it has no tags, since
17
+ * every hit is checked against the tag markers before it is served.
18
+ */
13
19
  class MemoryCacheHandler {
14
20
  inMemoryCache = new Map();
15
21
  debug = (0, debug_1.default)("cdk-nextjs:cache-handler:memory");
@@ -17,10 +23,10 @@ class MemoryCacheHandler {
17
23
  * Time to live in milliseconds for cache entries.
18
24
  * After this duration, entries expire and are removed from the cache.
19
25
  *
20
- * **Important**: Due to the distributed nature of compute instances (Lambda functions,
21
- * ECS Fargate containers, etc.), this cache only provides eventual consistency across
22
- * instances. Tag revalidations will clear the cache on the instance that processes
23
- * the revalidation, but other instances may serve stale data until their cache entries expire.
26
+ * Tag revalidations never clear this cache: the orchestrating handler checks
27
+ * each memory hit against the tag markers before serving it
28
+ * (`S3CacheHandler.isRevalidated`), so a revalidated entry is not served from
29
+ * memory anywhere.
24
30
  *
25
31
  * @example
26
32
  * // Short TTL (5 minutes) - for frequently changing data
@@ -35,8 +41,8 @@ class MemoryCacheHandler {
35
41
  * ttlMs = 24 * 60 * 60 * 1000;
36
42
  *
37
43
  * **Why adjust this?**
38
- * - Lower values: More cache misses, fresher data, higher S3/DynamoDB costs
39
- * - Higher values: Fewer cache misses, better performance, but longer stale data windows
44
+ * - Lower values: More cache misses, higher S3 costs
45
+ * - Higher values: Fewer cache misses, more memory held
40
46
  *
41
47
  * Set via environment variable: `CDK_NEXTJS_MEMORY_CACHE_TTL_MS`
42
48
  */
@@ -69,26 +75,14 @@ class MemoryCacheHandler {
69
75
  * Set via environment variable: `CDK_NEXTJS_MEMORY_CACHE_MAX_ENTRIES`
70
76
  */
71
77
  maxEntries;
72
- constructor(options) {
73
- // Read configuration from environment variables with fallback defaults
74
- const ttlFromEnv = process.env.CDK_NEXTJS_MEMORY_CACHE_TTL_MS;
75
- const maxEntriesFromEnv = process.env.CDK_NEXTJS_MEMORY_CACHE_MAX_ENTRIES;
76
- // Default to 1 hour TTL and 1000 max entries
77
- this.ttlMs = ttlFromEnv ? parseInt(ttlFromEnv, 10) : 60 * 60 * 1000; // 1 hour
78
- this.maxEntries = maxEntriesFromEnv
79
- ? parseInt(maxEntriesFromEnv, 10)
80
- : 1000;
81
- // Log the options for debugging (optional usage to avoid unused parameter warning)
82
- if (options.context.dev) {
83
- this.debug("MemoryCacheHandler initialized in development mode");
84
- }
78
+ constructor() {
79
+ // Default to 1 hour TTL and 1000 max entries. A value that is not a
80
+ // number falls back too: as NaN, nothing would ever expire or be evicted.
81
+ this.ttlMs = (0, use_cache_common_1.numberFromEnv)("CDK_NEXTJS_MEMORY_CACHE_TTL_MS", 60 * 60 * 1000);
82
+ this.maxEntries = (0, use_cache_common_1.numberFromEnv)("CDK_NEXTJS_MEMORY_CACHE_MAX_ENTRIES", 1000);
85
83
  this.debug(`TTL: ${this.ttlMs / 1000}s, Max entries: ${this.maxEntries}`);
86
84
  }
87
- async get(cacheKey, ctx) {
88
- // Log context for debugging (optional usage to avoid unused parameter warning)
89
- if (ctx.kind) {
90
- this.debug(`Memory cache get operation for ${cacheKey} with kind: ${ctx.kind}`);
91
- }
85
+ async get(cacheKey) {
92
86
  // Check in-memory cache
93
87
  const memoryEntry = this.inMemoryCache.get(cacheKey);
94
88
  if (memoryEntry) {
@@ -107,7 +101,16 @@ class MemoryCacheHandler {
107
101
  this.debug(`MEMORY CACHE MISS: ${cacheKey}`);
108
102
  return null;
109
103
  }
110
- async set(cacheKey, data, ctx) {
104
+ /**
105
+ * `lastModified` is the time the entry was rendered, for an entry copied in
106
+ * from a slower layer; a fresh render leaves it out and is stamped now - on
107
+ * {@link markerClock}, like the S3 copy of the same render. A memory hit is
108
+ * checked against the tag markers, which are stamped on that clock, and
109
+ * `Date.now()` drifts from it for as long as the process lives: an entry
110
+ * stamped ahead of it looked newer than a `revalidateTag` run within the
111
+ * drift, and was served for the whole memory TTL.
112
+ */
113
+ async set(cacheKey, data, lastModified) {
111
114
  if (!data) {
112
115
  // Delete from memory cache
113
116
  this.debug(`MEMORY CACHE DELETE: ${cacheKey}`);
@@ -118,13 +121,12 @@ class MemoryCacheHandler {
118
121
  this.debug(`MEMORY CACHE SET: ${cacheKey} (${data.kind})`);
119
122
  // Store in memory cache with proper CacheHandlerValue structure
120
123
  const cacheHandlerValue = {
121
- lastModified: Date.now(),
124
+ lastModified: lastModified ?? (0, aws_cache_store_1.markerClock)(),
122
125
  value: data,
123
126
  };
124
127
  const entry = {
125
128
  value: cacheHandlerValue,
126
129
  expiresAt: Date.now() + this.ttlMs,
127
- tags: (0, cache_utils_1.getTags)(ctx) || [],
128
130
  };
129
131
  // Clean up expired entries before adding new one
130
132
  this.cleanupExpired();
@@ -136,26 +138,6 @@ class MemoryCacheHandler {
136
138
  this.inMemoryCache.set(cacheKey, entry);
137
139
  this.debug(`Cache entries: ${this.inMemoryCache.size}/${this.maxEntries}`);
138
140
  }
139
- async revalidateTag(tag) {
140
- const tags = Array.isArray(tag) ? tag : [tag];
141
- let invalidatedCount = 0;
142
- for (const [key, entry] of this.inMemoryCache.entries()) {
143
- if (entry.tags.some((entryTag) => tags.includes(entryTag))) {
144
- this.inMemoryCache.delete(key);
145
- invalidatedCount++;
146
- }
147
- }
148
- this.debug(`MEMORY REVALIDATE TAGS: [${tags.join(", ")}] removed ${invalidatedCount} entries`);
149
- // Note: this only clears the cache on the instance handling this request.
150
- // In distributed environments (multiple Lambda functions or Fargate containers),
151
- // other instances continue serving their own memory-cached entries until those
152
- // entries expire (ttlMs). Set CDK_NEXTJS_MEMORY_CACHE_TTL_MS=0 to disable the
153
- // memory cache entirely if strong cross-instance consistency is required.
154
- }
155
- async resetRequestCache() {
156
- // Clear in-memory cache
157
- this.inMemoryCache.clear();
158
- }
159
141
  /**
160
142
  * Remove all expired cache entries
161
143
  */
@@ -192,4 +174,4 @@ class MemoryCacheHandler {
192
174
  }
193
175
  }
194
176
  exports.MemoryCacheHandler = MemoryCacheHandler;
195
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LWNhY2hlLWhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlci9tZW1vcnktY2FjaGUtaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7RUFFRTtBQUNGLHNEQUFzRDtBQUN0RCxrREFBNkI7QUFhN0IsK0NBQXdDO0FBWXhDLE1BQWEsa0JBQWtCO0lBQ3JCLGFBQWEsR0FBa0MsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUN6RCxLQUFLLEdBQUcsSUFBQSxlQUFRLEVBQUMsaUNBQWlDLENBQUMsQ0FBQztJQUU1RDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0EwQkc7SUFDYyxLQUFLLENBQVM7SUFFL0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BMEJHO0lBQ2MsVUFBVSxDQUFTO0lBRXBDLFlBQVksT0FBa0M7UUFDNUMsdUVBQXVFO1FBQ3ZFLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsOEJBQThCLENBQUM7UUFDOUQsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLG1DQUFtQyxDQUFDO1FBRTFFLDZDQUE2QztRQUM3QyxJQUFJLENBQUMsS0FBSyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxTQUFTO1FBQzlFLElBQUksQ0FBQyxVQUFVLEdBQUcsaUJBQWlCO1lBQ2pDLENBQUMsQ0FBQyxRQUFRLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxDQUFDO1lBQ2pDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFFVCxtRkFBbUY7UUFDbkYsSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztRQUNuRSxD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LEVBQUUsRUFBRSxDQUFDO1lBQ3hELElBQUksR0FBRyxHQUFHLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDMUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQy9CLFlBQVksRUFBRSxDQUFDO1lBQ2pCLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxZQUFZLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLFlBQVksa0JBQWtCLENBQUMsQ0FBQztRQUMzRCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNLLFdBQVc7UUFDakIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUM7UUFDeEQsSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxLQUFLLENBQUMsNkJBQTZCLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDcEQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdEMsQ0FBQztJQUNILENBQUM7SUFFRCw0Q0FBNEM7SUFDckMsWUFBWTtRQUNqQixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDO0lBQ2pDLENBQUM7SUFFTSxVQUFVO1FBQ2YsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUM3QixDQUFDO0NBQ0Y7QUE1TkQsZ0RBNE5DIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgSW4tbWVtb3J5IGNhY2hlIGhhbmRsZXIgd2l0aCB0YWcgbWFuYWdlbWVudFxuKi9cbi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IGdldERlYnVnIGZyb20gXCJkZWJ1Z1wiO1xuaW1wb3J0IHtcbiAgQ2FjaGVIYW5kbGVyLFxuICBDYWNoZUhhbmRsZXJWYWx1ZSxcbiAgQ2FjaGVIYW5kbGVyQ29udGV4dCxcbn0gZnJvbSBcIm5leHQvZGlzdC9zZXJ2ZXIvbGliL2luY3JlbWVudGFsLWNhY2hlXCI7XG5pbXBvcnQge1xuICBJbmNyZW1lbnRhbENhY2hlVmFsdWUsXG4gIEdldEluY3JlbWVudGFsRmV0Y2hDYWNoZUNvbnRleHQsXG4gIEdldEluY3JlbWVudGFsUmVzcG9uc2VDYWNoZUNvbnRleHQsXG4gIFNldEluY3JlbWVudGFsUmVzcG9uc2VDYWNoZUNvbnRleHQsXG4gIFNldEluY3JlbWVudGFsRmV0Y2hDYWNoZUNvbnRleHQsXG59IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL3Jlc3BvbnNlLWNhY2hlXCI7XG5pbXBvcnQgeyBnZXRUYWdzIH0gZnJvbSBcIi4vY2FjaGUtdXRpbHNcIjtcblxuaW50ZXJmYWNlIE1lbW9yeUNhY2hlRW50cnkge1xuICB2YWx1ZTogQ2FjaGVIYW5kbGVyVmFsdWU7XG4gIGV4cGlyZXNBdDogbnVtYmVyOyAvLyBUaW1lc3RhbXAgaW4gbWlsbGlzZWNvbmRzXG4gIHRhZ3M6IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1lbW9yeUNhY2hlSGFuZGxlck9wdGlvbnMge1xuICBjb250ZXh0OiBDYWNoZUhhbmRsZXJDb250ZXh0O1xufVxuXG5leHBvcnQgY2xhc3MgTWVtb3J5Q2FjaGVIYW5kbGVyIGltcGxlbWVudHMgQ2FjaGVIYW5kbGVyIHtcbiAgcHJpdmF0ZSBpbk1lbW9yeUNhY2hlOiBNYXA8c3RyaW5nLCBNZW1vcnlDYWNoZUVudHJ5PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBkZWJ1ZyA9IGdldERlYnVnKFwiY2RrLW5leHRqczpjYWNoZS1oYW5kbGVyOm1lbW9yeVwiKTtcblxuICAvKipcbiAgICogVGltZSB0byBsaXZlIGluIG1pbGxpc2Vjb25kcyBmb3IgY2FjaGUgZW50cmllcy5cbiAgICogQWZ0ZXIgdGhpcyBkdXJhdGlvbiwgZW50cmllcyBleHBpcmUgYW5kIGFyZSByZW1vdmVkIGZyb20gdGhlIGNhY2hlLlxuICAgKlxuICAgKiAqKkltcG9ydGFudCoqOiBEdWUgdG8gdGhlIGRpc3RyaWJ1dGVkIG5hdHVyZSBvZiBjb21wdXRlIGluc3RhbmNlcyAoTGFtYmRhIGZ1bmN0aW9ucyxcbiAgICogRUNTIEZhcmdhdGUgY29udGFpbmVycywgZXRjLiksIHRoaXMgY2FjaGUgb25seSBwcm92aWRlcyBldmVudHVhbCBjb25zaXN0ZW5jeSBhY3Jvc3NcbiAgICogaW5zdGFuY2VzLiBUYWcgcmV2YWxpZGF0aW9ucyB3aWxsIGNsZWFyIHRoZSBjYWNoZSBvbiB0aGUgaW5zdGFuY2UgdGhhdCBwcm9jZXNzZXNcbiAgICogdGhlIHJldmFsaWRhdGlvbiwgYnV0IG90aGVyIGluc3RhbmNlcyBtYXkgc2VydmUgc3RhbGUgZGF0YSB1bnRpbCB0aGVpciBjYWNoZSBlbnRyaWVzIGV4cGlyZS5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogLy8gU2hvcnQgVFRMICg1IG1pbnV0ZXMpIC0gZm9yIGZyZXF1ZW50bHkgY2hhbmdpbmcgZGF0YVxuICAgKiB0dGxNcyA9IDUgKiA2MCAqIDEwMDA7XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIE1lZGl1bSBUVEwgKDEgaG91cikgLSBiYWxhbmNlZCBiZXR3ZWVuIGZyZXNobmVzcyBhbmQgcGVyZm9ybWFuY2VcbiAgICogdHRsTXMgPSA2MCAqIDYwICogMTAwMDtcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogLy8gTG9uZyBUVEwgKDI0IGhvdXJzKSAtIGZvciBtb3N0bHkgc3RhdGljIGNvbnRlbnRcbiAgICogdHRsTXMgPSAyNCAqIDYwICogNjAgKiAxMDAwO1xuICAgKlxuICAgKiAqKldoeSBhZGp1c3QgdGhpcz8qKlxuICAgKiAtIExvd2VyIHZhbHVlczogTW9yZSBjYWNoZSBtaXNzZXMsIGZyZXNoZXIgZGF0YSwgaGlnaGVyIFMzL0R5bmFtb0RCIGNvc3RzXG4gICAqIC0gSGlnaGVyIHZhbHVlczogRmV3ZXIgY2FjaGUgbWlzc2VzLCBiZXR0ZXIgcGVyZm9ybWFuY2UsIGJ1dCBsb25nZXIgc3RhbGUgZGF0YSB3aW5kb3dzXG4gICAqXG4gICAqIFNldCB2aWEgZW52aXJvbm1lbnQgdmFyaWFibGU6IGBDREtfTkVYVEpTX01FTU9SWV9DQUNIRV9UVExfTVNgXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHR0bE1zOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIE1heGltdW0gbnVtYmVyIG9mIGNhY2hlIGVudHJpZXMgdG8gc3RvcmUgaW4gbWVtb3J5LlxuICAgKiBXaGVuIHRoaXMgbGltaXQgaXMgcmVhY2hlZCwgdGhlIGxlYXN0IHJlY2VudGx5IHVzZWQgKExSVSkgZW50cnkgaXMgZXZpY3RlZC5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogLy8gU21hbGwgY2FjaGUgKDEwMCBlbnRyaWVzKSAtIG1pbmltYWwgbWVtb3J5IGZvb3RwcmludCBmb3Igc2ltcGxlIGFwcHNcbiAgICogbWF4RW50cmllcyA9IDEwMDtcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogLy8gTWVkaXVtIGNhY2hlICgxMDAwIGVudHJpZXMpIC0gZ29vZCBiYWxhbmNlIGZvciB0eXBpY2FsIGFwcGxpY2F0aW9uc1xuICAgKiBtYXhFbnRyaWVzID0gMTAwMDtcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogLy8gTGFyZ2UgY2FjaGUgKDEwMDAwIGVudHJpZXMpIC0gZm9yIGhpZ2gtdHJhZmZpYyBhcHBzIHdpdGggbWFueSB1bmlxdWUgcGFnZXNcbiAgICogbWF4RW50cmllcyA9IDEwMDAwO1xuICAgKlxuICAgKiAqKldoeSBhZGp1c3QgdGhpcz8qKlxuICAgKiAtIExvd2VyIHZhbHVlczogTGVzcyBtZW1vcnkgdXNhZ2UsIG1vcmUgY2FjaGUgZXZpY3Rpb25zXG4gICAqIC0gSGlnaGVyIHZhbHVlczogTW9yZSBtZW1vcnkgdXNhZ2UsIGZld2VyIGNhY2hlIGV2aWN0aW9ucywgYmV0dGVyIGhpdCByYXRlc1xuICAgKlxuICAgKiAqKk1lbW9yeSBjb25zaWRlcmF0aW9ucyoqOiBFYWNoIGVudHJ5IHN0b3JlcyB0aGUgZnVsbCBjYWNoZSB2YWx1ZSAoSFRNTCwgSlNPTiwgZXRjLilcbiAgICogQSB0eXBpY2FsIHBhZ2UgY2FjaGUgbWlnaHQgYmUgMTAtMTAwS0IsIHNvIDEwMDAgZW50cmllcyDiiYggMTAtMTAwTUIgb2YgbWVtb3J5LlxuICAgKiBDb25zaWRlciB5b3VyIGNvbXB1dGUgZW52aXJvbm1lbnQncyBtZW1vcnkgbGltaXRzIChMYW1iZGE6IDEyOE1CLTEwR0IsIEZhcmdhdGU6IDUxMk1CLTMwR0IpXG4gICAqIGFuZCBzaXplIGFjY29yZGluZ2x5LlxuICAgKlxuICAgKiBTZXQgdmlhIGVudmlyb25tZW50IHZhcmlhYmxlOiBgQ0RLX05FWFRKU19NRU1PUllfQ0FDSEVfTUFYX0VOVFJJRVNgXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IG1heEVudHJpZXM6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBNZW1vcnlDYWNoZUhhbmRsZXJPcHRpb25zKSB7XG4gICAgLy8gUmVhZCBjb25maWd1cmF0aW9uIGZyb20gZW52aXJvbm1lbnQgdmFyaWFibGVzIHdpdGggZmFsbGJhY2sgZGVmYXVsdHNcbiAgICBjb25zdCB0dGxGcm9tRW52ID0gcHJvY2Vzcy5lbnYuQ0RLX05FWFRKU19NRU1PUllfQ0FDSEVfVFRMX01TO1xuICAgIGNvbnN0IG1heEVudHJpZXNGcm9tRW52ID0gcHJvY2Vzcy5lbnYuQ0RLX05FWFRKU19NRU1PUllfQ0FDSEVfTUFYX0VOVFJJRVM7XG5cbiAgICAvLyBEZWZhdWx0IHRvIDEgaG91ciBUVEwgYW5kIDEwMDAgbWF4IGVudHJpZXNcbiAgICB0aGlzLnR0bE1zID0gdHRsRnJvbUVudiA/IHBhcnNlSW50KHR0bEZyb21FbnYsIDEwKSA6IDYwICogNjAgKiAxMDAwOyAvLyAxIGhvdXJcbiAgICB0aGlzLm1heEVudHJpZXMgPSBtYXhFbnRyaWVzRnJvbUVudlxuICAgICAgPyBwYXJzZUludChtYXhFbnRyaWVzRnJvbUVudiwgMTApXG4gICAgICA6IDEwMDA7XG5cbiAgICAvLyBMb2cgdGhlIG9wdGlvbnMgZm9yIGRlYnVnZ2luZyAob3B0aW9uYWwgdXNhZ2UgdG8gYXZvaWQgdW51c2VkIHBhcmFtZXRlciB3YXJuaW5nKVxuICAgIGlmIChvcHRpb25zLmNvbnRleHQuZGV2KSB7XG4gICAgICB0aGlzLmRlYnVnKFwiTWVtb3J5Q2FjaGVIYW5kbGVyIGluaXRpYWxpemVkIGluIGRldmVsb3BtZW50IG1vZGVcIik7XG4gICAgfVxuICAgIHRoaXMuZGVidWcoYFRUTDogJHt0aGlzLnR0bE1zIC8gMTAwMH1zLCBNYXggZW50cmllczogJHt0aGlzLm1heEVudHJpZXN9YCk7XG4gIH1cblxuICBhc3luYyBnZXQoXG4gICAgY2FjaGVLZXk6IHN0cmluZyxcbiAgICBjdHg6IEdldEluY3JlbWVudGFsRmV0Y2hDYWNoZUNvbnRleHQgfCBHZXRJbmNyZW1lbnRhbFJlc3BvbnNlQ2FjaGVDb250ZXh0LFxuICApOiBQcm9taXNlPENhY2hlSGFuZGxlclZhbHVlIHwgbnVsbD4ge1xuICAgIC8vIExvZyBjb250ZXh0IGZvciBkZWJ1Z2dpbmcgKG9wdGlvbmFsIHVzYWdlIHRvIGF2b2lkIHVudXNlZCBwYXJhbWV0ZXIgd2FybmluZylcbiAgICBpZiAoY3R4LmtpbmQpIHtcbiAgICAgIHRoaXMuZGVidWcoXG4gICAgICAgIGBNZW1vcnkgY2FjaGUgZ2V0IG9wZXJhdGlvbiBmb3IgJHtjYWNoZUtleX0gd2l0aCBraW5kOiAke2N0eC5raW5kfWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGluLW1lbW9yeSBjYWNoZVxuICAgIGNvbnN0IG1lbW9yeUVudHJ5ID0gdGhpcy5pbk1lbW9yeUNhY2hlLmdldChjYWNoZUtleSk7XG4gICAgaWYgKG1lbW9yeUVudHJ5KSB7XG4gICAgICAvLyBDaGVjayBpZiBleHBpcmVkXG4gICAgICBpZiAoRGF0ZS5ub3coKSA+IG1lbW9yeUVudHJ5LmV4cGlyZXNBdCkge1xuICAgICAgICB0aGlzLmRlYnVnKGBNRU1PUlkgQ0FDSEUgRVhQSVJFRDogJHtjYWNoZUtleX1gKTtcbiAgICAgICAgdGhpcy5pbk1lbW9yeUNhY2hlLmRlbGV0ZShjYWNoZUtleSk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICAvLyBNb3ZlIHRvIGVuZCAobW9zdCByZWNlbnRseSB1c2VkKSBieSBkZWxldGluZyBhbmQgcmUtaW5zZXJ0aW5nXG4gICAgICB0aGlzLmluTWVtb3J5Q2FjaGUuZGVsZXRlKGNhY2hlS2V5KTtcbiAgICAgIHRoaXMuaW5NZW1vcnlDYWNoZS5zZXQoY2FjaGVLZXksIG1lbW9yeUVudHJ5KTtcblxuICAgICAgdGhpcy5kZWJ1ZyhgTUVNT1JZIENBQ0hFIEhJVDogJHtjYWNoZUtleX1gKTtcbiAgICAgIHJldHVybiBtZW1vcnlFbnRyeS52YWx1ZTtcbiAgICB9XG5cbiAgICB0aGlzLmRlYnVnKGBNRU1PUlkgQ0FDSEUgTUlTUzogJHtjYWNoZUtleX1gKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGFzeW5jIHNldChcbiAgICBjYWNoZUtleTogc3RyaW5nLFxuICAgIGRhdGE6IEluY3JlbWVudGFsQ2FjaGVWYWx1ZSB8IG51bGwsXG4gICAgY3R4OiBTZXRJbmNyZW1lbnRhbEZldGNoQ2FjaGVDb250ZXh0IHwgU2V0SW5jcmVtZW50YWxSZXNwb25zZUNhY2hlQ29udGV4dCxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCFkYXRhKSB7XG4gICAgICAvLyBEZWxldGUgZnJvbSBtZW1vcnkgY2FjaGVcbiAgICAgIHRoaXMuZGVidWcoYE1FTU9SWSBDQUNIRSBERUxFVEU6ICR7Y2FjaGVLZXl9YCk7XG4gICAgICB0aGlzLmluTWVtb3J5Q2FjaGUuZGVsZXRlKGNhY2hlS2V5KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBEZWJ1ZyBsb2dnaW5nIGZvciBtZW1vcnkgY2FjaGUgc2V0XG4gICAgdGhpcy5kZWJ1ZyhgTUVNT1JZIENBQ0hFIFNFVDogJHtjYWNoZUtleX0gKCR7ZGF0YS5raW5kfSlgKTtcblxuICAgIC8vIFN0b3JlIGluIG1lbW9yeSBjYWNoZSB3aXRoIHByb3BlciBDYWNoZUhhbmRsZXJWYWx1ZSBzdHJ1Y3R1cmVcbiAgICBjb25zdCBjYWNoZUhhbmRsZXJWYWx1ZTogQ2FjaGVIYW5kbGVyVmFsdWUgPSB7XG4gICAgICBsYXN0TW9kaWZpZWQ6IERhdGUubm93KCksXG4gICAgICB2YWx1ZTogZGF0YSxcbiAgICB9O1xuXG4gICAgY29uc3QgZW50cnk6IE1lbW9yeUNhY2hlRW50cnkgPSB7XG4gICAgICB2YWx1ZTogY2FjaGVIYW5kbGVyVmFsdWUsXG4gICAgICBleHBpcmVzQXQ6IERhdGUubm93KCkgKyB0aGlzLnR0bE1zLFxuICAgICAgdGFnczogZ2V0VGFncyhjdHgpIHx8IFtdLFxuICAgIH07XG5cbiAgICAvLyBDbGVhbiB1cCBleHBpcmVkIGVudHJpZXMgYmVmb3JlIGFkZGluZyBuZXcgb25lXG4gICAgdGhpcy5jbGVhbnVwRXhwaXJlZCgpO1xuXG4gICAgLy8gSWYgd2UncmUgYXQgbWF4IGNhcGFjaXR5LCBldmljdCBvbGRlc3QgZW50cnlcbiAgICBpZiAodGhpcy5pbk1lbW9yeUNhY2hlLnNpemUgPj0gdGhpcy5tYXhFbnRyaWVzKSB7XG4gICAgICB0aGlzLmV2aWN0T2xkZXN0KCk7XG4gICAgfVxuXG4gICAgLy8gQWRkIG5ldyBlbnRyeVxuICAgIHRoaXMuaW5NZW1vcnlDYWNoZS5zZXQoY2FjaGVLZXksIGVudHJ5KTtcblxuICAgIHRoaXMuZGVidWcoYENhY2hlIGVudHJpZXM6ICR7dGhpcy5pbk1lbW9yeUNhY2hlLnNpemV9LyR7dGhpcy5tYXhFbnRyaWVzfWApO1xuICB9XG5cbiAgYXN5bmMgcmV2YWxpZGF0ZVRhZyh0YWc6IHN0cmluZyB8IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdGFncyA9IEFycmF5LmlzQXJyYXkodGFnKSA/IHRhZyA6IFt0YWddO1xuICAgIGxldCBpbnZhbGlkYXRlZENvdW50ID0gMDtcblxuICAgIGZvciAoY29uc3QgW2tleSwgZW50cnldIG9mIHRoaXMuaW5NZW1vcnlDYWNoZS5lbnRyaWVzKCkpIHtcbiAgICAgIGlmIChlbnRyeS50YWdzLnNvbWUoKGVudHJ5VGFnKSA9PiB0YWdzLmluY2x1ZGVzKGVudHJ5VGFnKSkpIHtcbiAgICAgICAgdGhpcy5pbk1lbW9yeUNhY2hlLmRlbGV0ZShrZXkpO1xuICAgICAgICBpbnZhbGlkYXRlZENvdW50Kys7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5kZWJ1ZyhcbiAgICAgIGBNRU1PUlkgUkVWQUxJREFURSBUQUdTOiBbJHt0YWdzLmpvaW4oXCIsIFwiKX1dIHJlbW92ZWQgJHtpbnZhbGlkYXRlZENvdW50fSBlbnRyaWVzYCxcbiAgICApO1xuXG4gICAgLy8gTm90ZTogdGhpcyBvbmx5IGNsZWFycyB0aGUgY2FjaGUgb24gdGhlIGluc3RhbmNlIGhhbmRsaW5nIHRoaXMgcmVxdWVzdC5cbiAgICAvLyBJbiBkaXN0cmlidXRlZCBlbnZpcm9ubWVudHMgKG11bHRpcGxlIExhbWJkYSBmdW5jdGlvbnMgb3IgRmFyZ2F0ZSBjb250YWluZXJzKSxcbiAgICAvLyBvdGhlciBpbnN0YW5jZXMgY29udGludWUgc2VydmluZyB0aGVpciBvd24gbWVtb3J5LWNhY2hlZCBlbnRyaWVzIHVudGlsIHRob3NlXG4gICAgLy8gZW50cmllcyBleHBpcmUgKHR0bE1zKS4gU2V0IENES19ORVhUSlNfTUVNT1JZX0NBQ0hFX1RUTF9NUz0wIHRvIGRpc2FibGUgdGhlXG4gICAgLy8gbWVtb3J5IGNhY2hlIGVudGlyZWx5IGlmIHN0cm9uZyBjcm9zcy1pbnN0YW5jZSBjb25zaXN0ZW5jeSBpcyByZXF1aXJlZC5cbiAgfVxuXG4gIGFzeW5jIHJlc2V0UmVxdWVzdENhY2hlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIENsZWFyIGluLW1lbW9yeSBjYWNoZVxuICAgIHRoaXMuaW5NZW1vcnlDYWNoZS5jbGVhcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhbGwgZXhwaXJlZCBjYWNoZSBlbnRyaWVzXG4gICAqL1xuICBwcml2YXRlIGNsZWFudXBFeHBpcmVkKCk6IHZvaWQge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgbGV0IGV4cGlyZWRDb3VudCA9IDA7XG5cbiAgICBmb3IgKGNvbnN0IFtrZXksIGVudHJ5XSBvZiB0aGlzLmluTWVtb3J5Q2FjaGUuZW50cmllcygpKSB7XG4gICAgICBpZiAobm93ID4gZW50cnkuZXhwaXJlc0F0KSB7XG4gICAgICAgIHRoaXMuaW5NZW1vcnlDYWNoZS5kZWxldGUoa2V5KTtcbiAgICAgICAgZXhwaXJlZENvdW50Kys7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGV4cGlyZWRDb3VudCA+IDApIHtcbiAgICAgIHRoaXMuZGVidWcoYENsZWFuZWQgdXAgJHtleHBpcmVkQ291bnR9IGV4cGlyZWQgZW50cmllc2ApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFdmljdCB0aGUgb2xkZXN0IChsZWFzdCByZWNlbnRseSB1c2VkKSBjYWNoZSBlbnRyeVxuICAgKiBNYXAgbWFpbnRhaW5zIGluc2VydGlvbiBvcmRlciwgc28gZmlyc3QgZW50cnkgaXMgb2xkZXN0XG4gICAqL1xuICBwcml2YXRlIGV2aWN0T2xkZXN0KCk6IHZvaWQge1xuICAgIGNvbnN0IGZpcnN0S2V5ID0gdGhpcy5pbk1lbW9yeUNhY2hlLmtleXMoKS5uZXh0KCkudmFsdWU7XG4gICAgaWYgKGZpcnN0S2V5KSB7XG4gICAgICB0aGlzLmRlYnVnKGBNQVggQ0FQQUNJVFkgRVZJQ1QgKExSVSk6ICR7Zmlyc3RLZXl9YCk7XG4gICAgICB0aGlzLmluTWVtb3J5Q2FjaGUuZGVsZXRlKGZpcnN0S2V5KTtcbiAgICB9XG4gIH1cblxuICAvLyBQdWJsaWMgbWV0aG9kcyBmb3IgdGVzdGluZyBhbmQgbW9uaXRvcmluZ1xuICBwdWJsaWMgZ2V0Q2FjaGVTaXplKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuaW5NZW1vcnlDYWNoZS5zaXplO1xuICB9XG5cbiAgcHVibGljIGNsZWFyQ2FjaGUoKTogdm9pZCB7XG4gICAgdGhpcy5pbk1lbW9yeUNhY2hlLmNsZWFyKCk7XG4gIH1cbn1cbiJdfQ==
177
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LWNhY2hlLWhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlci9tZW1vcnktY2FjaGUtaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7RUFFRTtBQUNGLHNEQUFzRDtBQUN0RCxrREFBNkI7QUFHN0IsdURBQWdEO0FBQ2hELHlEQUFtRDtBQU9uRDs7OztHQUlHO0FBQ0gsTUFBYSxrQkFBa0I7SUFDckIsYUFBYSxHQUFrQyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ3pELEtBQUssR0FBRyxJQUFBLGVBQVEsRUFBQyxpQ0FBaUMsQ0FBQyxDQUFDO0lBRTVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQTBCRztJQUNjLEtBQUssQ0FBUztJQUUvQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0EwQkc7SUFDYyxVQUFVLENBQVM7SUFFcEM7UUFDRSxvRUFBb0U7UUFDcEUsMEVBQTBFO1FBQzFFLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBQSxnQ0FBYSxFQUN4QixnQ0FBZ0MsRUFDaEMsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQ2YsQ0FBQztRQUNGLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBQSxnQ0FBYSxFQUM3QixxQ0FBcUMsRUFDckMsSUFBSSxDQUNMLENBQUM7UUFFRixJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLG1CQUFtQixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztJQUM1RSxDQUFDO0lBRUQsS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFnQjtRQUN4Qix3QkFBd0I7UUFDeEIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDckQsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNoQixtQkFBbUI7WUFDbkIsSUFBSSxJQUFJLENBQUMsR0FBRyxF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OztPQUdHO0lBQ0ssV0FBVztRQUNqQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQztRQUN4RCxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQ2IsSUFBSSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsUUFBUSxFQUFFLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN0QyxDQUFDO0lBQ0gsQ0FBQztJQUVELDRDQUE0QztJQUNyQyxZQUFZO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUM7SUFDakMsQ0FBQztJQUVNLFVBQVU7UUFDZixJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQzdCLENBQUM7Q0FDRjtBQTVMRCxnREE0TEMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICBJbi1tZW1vcnkgY2FjaGUgaGFuZGxlclxuKi9cbi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IGdldERlYnVnIGZyb20gXCJkZWJ1Z1wiO1xuaW1wb3J0IHsgQ2FjaGVIYW5kbGVyVmFsdWUgfSBmcm9tIFwibmV4dC9kaXN0L3NlcnZlci9saWIvaW5jcmVtZW50YWwtY2FjaGVcIjtcbmltcG9ydCB7IEluY3JlbWVudGFsQ2FjaGVWYWx1ZSB9IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL3Jlc3BvbnNlLWNhY2hlXCI7XG5pbXBvcnQgeyBtYXJrZXJDbG9jayB9IGZyb20gXCIuL2F3cy1jYWNoZS1zdG9yZVwiO1xuaW1wb3J0IHsgbnVtYmVyRnJvbUVudiB9IGZyb20gXCIuL3VzZS1jYWNoZS1jb21tb25cIjtcblxuaW50ZXJmYWNlIE1lbW9yeUNhY2hlRW50cnkge1xuICB2YWx1ZTogQ2FjaGVIYW5kbGVyVmFsdWU7XG4gIGV4cGlyZXNBdDogbnVtYmVyOyAvLyBUaW1lc3RhbXAgaW4gbWlsbGlzZWNvbmRzXG59XG5cbi8qKlxuICogVGhlIGluLW1lbW9yeSBsYXllciB0aGUgb3JjaGVzdHJhdGluZyBoYW5kbGVyIHB1dHMgaW4gZnJvbnQgb2ZcbiAqIGBTM0NhY2hlSGFuZGxlcmAuIE5vdCBhIGBDYWNoZUhhbmRsZXJgIG9mIGl0cyBvd246IGl0IGhhcyBubyB0YWdzLCBzaW5jZVxuICogZXZlcnkgaGl0IGlzIGNoZWNrZWQgYWdhaW5zdCB0aGUgdGFnIG1hcmtlcnMgYmVmb3JlIGl0IGlzIHNlcnZlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIE1lbW9yeUNhY2hlSGFuZGxlciB7XG4gIHByaXZhdGUgaW5NZW1vcnlDYWNoZTogTWFwPHN0cmluZywgTWVtb3J5Q2FjaGVFbnRyeT4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgZGVidWcgPSBnZXREZWJ1ZyhcImNkay1uZXh0anM6Y2FjaGUtaGFuZGxlcjptZW1vcnlcIik7XG5cbiAgLyoqXG4gICAqIFRpbWUgdG8gbGl2ZSBpbiBtaWxsaXNlY29uZHMgZm9yIGNhY2hlIGVudHJpZXMuXG4gICAqIEFmdGVyIHRoaXMgZHVyYXRpb24sIGVudHJpZXMgZXhwaXJlIGFuZCBhcmUgcmVtb3ZlZCBmcm9tIHRoZSBjYWNoZS5cbiAgICpcbiAgICogVGFnIHJldmFsaWRhdGlvbnMgbmV2ZXIgY2xlYXIgdGhpcyBjYWNoZTogdGhlIG9yY2hlc3RyYXRpbmcgaGFuZGxlciBjaGVja3NcbiAgICogZWFjaCBtZW1vcnkgaGl0IGFnYWluc3QgdGhlIHRhZyBtYXJrZXJzIGJlZm9yZSBzZXJ2aW5nIGl0XG4gICAqIChgUzNDYWNoZUhhbmRsZXIuaXNSZXZhbGlkYXRlZGApLCBzbyBhIHJldmFsaWRhdGVkIGVudHJ5IGlzIG5vdCBzZXJ2ZWQgZnJvbVxuICAgKiBtZW1vcnkgYW55d2hlcmUuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIFNob3J0IFRUTCAoNSBtaW51dGVzKSAtIGZvciBmcmVxdWVudGx5IGNoYW5naW5nIGRhdGFcbiAgICogdHRsTXMgPSA1ICogNjAgKiAxMDAwO1xuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBNZWRpdW0gVFRMICgxIGhvdXIpIC0gYmFsYW5jZWQgYmV0d2VlbiBmcmVzaG5lc3MgYW5kIHBlcmZvcm1hbmNlXG4gICAqIHR0bE1zID0gNjAgKiA2MCAqIDEwMDA7XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIExvbmcgVFRMICgyNCBob3VycykgLSBmb3IgbW9zdGx5IHN0YXRpYyBjb250ZW50XG4gICAqIHR0bE1zID0gMjQgKiA2MCAqIDYwICogMTAwMDtcbiAgICpcbiAgICogKipXaHkgYWRqdXN0IHRoaXM/KipcbiAgICogLSBMb3dlciB2YWx1ZXM6IE1vcmUgY2FjaGUgbWlzc2VzLCBoaWdoZXIgUzMgY29zdHNcbiAgICogLSBIaWdoZXIgdmFsdWVzOiBGZXdlciBjYWNoZSBtaXNzZXMsIG1vcmUgbWVtb3J5IGhlbGRcbiAgICpcbiAgICogU2V0IHZpYSBlbnZpcm9ubWVudCB2YXJpYWJsZTogYENES19ORVhUSlNfTUVNT1JZX0NBQ0hFX1RUTF9NU2BcbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgdHRsTXM6IG51bWJlcjtcblxuICAvKipcbiAgICogTWF4aW11bSBudW1iZXIgb2YgY2FjaGUgZW50cmllcyB0byBzdG9yZSBpbiBtZW1vcnkuXG4gICAqIFdoZW4gdGhpcyBsaW1pdCBpcyByZWFjaGVkLCB0aGUgbGVhc3QgcmVjZW50bHkgdXNlZCAoTFJVKSBlbnRyeSBpcyBldmljdGVkLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBTbWFsbCBjYWNoZSAoMTAwIGVudHJpZXMpIC0gbWluaW1hbCBtZW1vcnkgZm9vdHByaW50IGZvciBzaW1wbGUgYXBwc1xuICAgKiBtYXhFbnRyaWVzID0gMTAwO1xuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBNZWRpdW0gY2FjaGUgKDEwMDAgZW50cmllcykgLSBnb29kIGJhbGFuY2UgZm9yIHR5cGljYWwgYXBwbGljYXRpb25zXG4gICAqIG1heEVudHJpZXMgPSAxMDAwO1xuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBMYXJnZSBjYWNoZSAoMTAwMDAgZW50cmllcykgLSBmb3IgaGlnaC10cmFmZmljIGFwcHMgd2l0aCBtYW55IHVuaXF1ZSBwYWdlc1xuICAgKiBtYXhFbnRyaWVzID0gMTAwMDA7XG4gICAqXG4gICAqICoqV2h5IGFkanVzdCB0aGlzPyoqXG4gICAqIC0gTG93ZXIgdmFsdWVzOiBMZXNzIG1lbW9yeSB1c2FnZSwgbW9yZSBjYWNoZSBldmljdGlvbnNcbiAgICogLSBIaWdoZXIgdmFsdWVzOiBNb3JlIG1lbW9yeSB1c2FnZSwgZmV3ZXIgY2FjaGUgZXZpY3Rpb25zLCBiZXR0ZXIgaGl0IHJhdGVzXG4gICAqXG4gICAqICoqTWVtb3J5IGNvbnNpZGVyYXRpb25zKio6IEVhY2ggZW50cnkgc3RvcmVzIHRoZSBmdWxsIGNhY2hlIHZhbHVlIChIVE1MLCBKU09OLCBldGMuKVxuICAgKiBBIHR5cGljYWwgcGFnZSBjYWNoZSBtaWdodCBiZSAxMC0xMDBLQiwgc28gMTAwMCBlbnRyaWVzIOKJiCAxMC0xMDBNQiBvZiBtZW1vcnkuXG4gICAqIENvbnNpZGVyIHlvdXIgY29tcHV0ZSBlbnZpcm9ubWVudCdzIG1lbW9yeSBsaW1pdHMgKExhbWJkYTogMTI4TUItMTBHQiwgRmFyZ2F0ZTogNTEyTUItMzBHQilcbiAgICogYW5kIHNpemUgYWNjb3JkaW5nbHkuXG4gICAqXG4gICAqIFNldCB2aWEgZW52aXJvbm1lbnQgdmFyaWFibGU6IGBDREtfTkVYVEpTX01FTU9SWV9DQUNIRV9NQVhfRU5UUklFU2BcbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4RW50cmllczogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8vIERlZmF1bHQgdG8gMSBob3VyIFRUTCBhbmQgMTAwMCBtYXggZW50cmllcy4gQSB2YWx1ZSB0aGF0IGlzIG5vdCBhXG4gICAgLy8gbnVtYmVyIGZhbGxzIGJhY2sgdG9vOiBhcyBOYU4sIG5vdGhpbmcgd291bGQgZXZlciBleHBpcmUgb3IgYmUgZXZpY3RlZC5cbiAgICB0aGlzLnR0bE1zID0gbnVtYmVyRnJvbUVudihcbiAgICAgIFwiQ0RLX05FWFRKU19NRU1PUllfQ0FDSEVfVFRMX01TXCIsXG4gICAgICA2MCAqIDYwICogMTAwMCxcbiAgICApO1xuICAgIHRoaXMubWF4RW50cmllcyA9IG51bWJlckZyb21FbnYoXG4gICAgICBcIkNES19ORVhUSlNfTUVNT1JZX0NBQ0hFX01BWF9FTlRSSUVTXCIsXG4gICAgICAxMDAwLFxuICAgICk7XG5cbiAgICB0aGlzLmRlYnVnKGBUVEw6ICR7dGhpcy50dGxNcyAvIDEwMDB9cywgTWF4IGVudHJpZXM6ICR7dGhpcy5tYXhFbnRyaWVzfWApO1xuICB9XG5cbiAgYXN5bmMgZ2V0KGNhY2hlS2V5OiBzdHJpbmcpOiBQcm9taXNlPENhY2hlSGFuZGxlclZhbHVlIHwgbnVsbD4ge1xuICAgIC8vIENoZWNrIGluLW1lbW9yeSBjYWNoZVxuICAgIGNvbnN0IG1lbW9yeUVudHJ5ID0gdGhpcy5pbk1lbW9yeUNhY2hlLmdldChjYWNoZUtleSk7XG4gICAgaWYgKG1lbW9yeUVudHJ5KSB7XG4gICAgICAvLyBDaGVjayBpZiBleHBpcmVkXG4gICAgICBpZiAoRGF0ZS5ub3coKSA+IG1lbW9yeUVudHJ5LmV4cGlyZXNBdCkge1xuICAgICAgICB0aGlzLmRlYnVnKGBNRU1PUlkgQ0FDSEUgRVhQSVJFRDogJHtjYWNoZUtleX1gKTtcbiAgICAgICAgdGhpcy5pbk1lbW9yeUNhY2hlLmRlbGV0ZShjYWNoZUtleSk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICAvLyBNb3ZlIHRvIGVuZCAobW9zdCByZWNlbnRseSB1c2VkKSBieSBkZWxldGluZyBhbmQgcmUtaW5zZXJ0aW5nXG4gICAgICB0aGlzLmluTWVtb3J5Q2FjaGUuZGVsZXRlKGNhY2hlS2V5KTtcbiAgICAgIHRoaXMuaW5NZW1vcnlDYWNoZS5zZXQoY2FjaGVLZXksIG1lbW9yeUVudHJ5KTtcblxuICAgICAgdGhpcy5kZWJ1ZyhgTUVNT1JZIENBQ0hFIEhJVDogJHtjYWNoZUtleX1gKTtcbiAgICAgIHJldHVybiBtZW1vcnlFbnRyeS52YWx1ZTtcbiAgICB9XG5cbiAgICB0aGlzLmRlYnVnKGBNRU1PUlkgQ0FDSEUgTUlTUzogJHtjYWNoZUtleX1gKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBgbGFzdE1vZGlmaWVkYCBpcyB0aGUgdGltZSB0aGUgZW50cnkgd2FzIHJlbmRlcmVkLCBmb3IgYW4gZW50cnkgY29waWVkIGluXG4gICAqIGZyb20gYSBzbG93ZXIgbGF5ZXI7IGEgZnJlc2ggcmVuZGVyIGxlYXZlcyBpdCBvdXQgYW5kIGlzIHN0YW1wZWQgbm93IC0gb25cbiAgICoge0BsaW5rIG1hcmtlckNsb2NrfSwgbGlrZSB0aGUgUzMgY29weSBvZiB0aGUgc2FtZSByZW5kZXIuIEEgbWVtb3J5IGhpdCBpc1xuICAgKiBjaGVja2VkIGFnYWluc3QgdGhlIHRhZyBtYXJrZXJzLCB3aGljaCBhcmUgc3RhbXBlZCBvbiB0aGF0IGNsb2NrLCBhbmRcbiAgICogYERhdGUubm93KClgIGRyaWZ0cyBmcm9tIGl0IGZvciBhcyBsb25nIGFzIHRoZSBwcm9jZXNzIGxpdmVzOiBhbiBlbnRyeVxuICAgKiBzdGFtcGVkIGFoZWFkIG9mIGl0IGxvb2tlZCBuZXdlciB0aGFuIGEgYHJldmFsaWRhdGVUYWdgIHJ1biB3aXRoaW4gdGhlXG4gICAqIGRyaWZ0LCBhbmQgd2FzIHNlcnZlZCBmb3IgdGhlIHdob2xlIG1lbW9yeSBUVEwuXG4gICAqL1xuICBhc3luYyBzZXQoXG4gICAgY2FjaGVLZXk6IHN0cmluZyxcbiAgICBkYXRhOiBJbmNyZW1lbnRhbENhY2hlVmFsdWUgfCBudWxsLFxuICAgIGxhc3RNb2RpZmllZD86IG51bWJlcixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCFkYXRhKSB7XG4gICAgICAvLyBEZWxldGUgZnJvbSBtZW1vcnkgY2FjaGVcbiAgICAgIHRoaXMuZGVidWcoYE1FTU9SWSBDQUNIRSBERUxFVEU6ICR7Y2FjaGVLZXl9YCk7XG4gICAgICB0aGlzLmluTWVtb3J5Q2FjaGUuZGVsZXRlKGNhY2hlS2V5KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBEZWJ1ZyBsb2dnaW5nIGZvciBtZW1vcnkgY2FjaGUgc2V0XG4gICAgdGhpcy5kZWJ1ZyhgTUVNT1JZIENBQ0hFIFNFVDogJHtjYWNoZUtleX0gKCR7ZGF0YS5raW5kfSlgKTtcblxuICAgIC8vIFN0b3JlIGluIG1lbW9yeSBjYWNoZSB3aXRoIHByb3BlciBDYWNoZUhhbmRsZXJWYWx1ZSBzdHJ1Y3R1cmVcbiAgICBjb25zdCBjYWNoZUhhbmRsZXJWYWx1ZTogQ2FjaGVIYW5kbGVyVmFsdWUgPSB7XG4gICAgICBsYXN0TW9kaWZpZWQ6IGxhc3RNb2RpZmllZCA/PyBtYXJrZXJDbG9jaygpLFxuICAgICAgdmFsdWU6IGRhdGEsXG4gICAgfTtcblxuICAgIGNvbnN0IGVudHJ5OiBNZW1vcnlDYWNoZUVudHJ5ID0ge1xuICAgICAgdmFsdWU6IGNhY2hlSGFuZGxlclZhbHVlLFxuICAgICAgZXhwaXJlc0F0OiBEYXRlLm5vdygpICsgdGhpcy50dGxNcyxcbiAgICB9O1xuXG4gICAgLy8gQ2xlYW4gdXAgZXhwaXJlZCBlbnRyaWVzIGJlZm9yZSBhZGRpbmcgbmV3IG9uZVxuICAgIHRoaXMuY2xlYW51cEV4cGlyZWQoKTtcblxuICAgIC8vIElmIHdlJ3JlIGF0IG1heCBjYXBhY2l0eSwgZXZpY3Qgb2xkZXN0IGVudHJ5XG4gICAgaWYgKHRoaXMuaW5NZW1vcnlDYWNoZS5zaXplID49IHRoaXMubWF4RW50cmllcykge1xuICAgICAgdGhpcy5ldmljdE9sZGVzdCgpO1xuICAgIH1cblxuICAgIC8vIEFkZCBuZXcgZW50cnlcbiAgICB0aGlzLmluTWVtb3J5Q2FjaGUuc2V0KGNhY2hlS2V5LCBlbnRyeSk7XG5cbiAgICB0aGlzLmRlYnVnKGBDYWNoZSBlbnRyaWVzOiAke3RoaXMuaW5NZW1vcnlDYWNoZS5zaXplfS8ke3RoaXMubWF4RW50cmllc31gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYWxsIGV4cGlyZWQgY2FjaGUgZW50cmllc1xuICAgKi9cbiAgcHJpdmF0ZSBjbGVhbnVwRXhwaXJlZCgpOiB2b2lkIHtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGxldCBleHBpcmVkQ291bnQgPSAwO1xuXG4gICAgZm9yIChjb25zdCBba2V5LCBlbnRyeV0gb2YgdGhpcy5pbk1lbW9yeUNhY2hlLmVudHJpZXMoKSkge1xuICAgICAgaWYgKG5vdyA+IGVudHJ5LmV4cGlyZXNBdCkge1xuICAgICAgICB0aGlzLmluTWVtb3J5Q2FjaGUuZGVsZXRlKGtleSk7XG4gICAgICAgIGV4cGlyZWRDb3VudCsrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChleHBpcmVkQ291bnQgPiAwKSB7XG4gICAgICB0aGlzLmRlYnVnKGBDbGVhbmVkIHVwICR7ZXhwaXJlZENvdW50fSBleHBpcmVkIGVudHJpZXNgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXZpY3QgdGhlIG9sZGVzdCAobGVhc3QgcmVjZW50bHkgdXNlZCkgY2FjaGUgZW50cnlcbiAgICogTWFwIG1haW50YWlucyBpbnNlcnRpb24gb3JkZXIsIHNvIGZpcnN0IGVudHJ5IGlzIG9sZGVzdFxuICAgKi9cbiAgcHJpdmF0ZSBldmljdE9sZGVzdCgpOiB2b2lkIHtcbiAgICBjb25zdCBmaXJzdEtleSA9IHRoaXMuaW5NZW1vcnlDYWNoZS5rZXlzKCkubmV4dCgpLnZhbHVlO1xuICAgIGlmIChmaXJzdEtleSkge1xuICAgICAgdGhpcy5kZWJ1ZyhgTUFYIENBUEFDSVRZIEVWSUNUIChMUlUpOiAke2ZpcnN0S2V5fWApO1xuICAgICAgdGhpcy5pbk1lbW9yeUNhY2hlLmRlbGV0ZShmaXJzdEtleSk7XG4gICAgfVxuICB9XG5cbiAgLy8gUHVibGljIG1ldGhvZHMgZm9yIHRlc3RpbmcgYW5kIG1vbml0b3JpbmdcbiAgcHVibGljIGdldENhY2hlU2l6ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmluTWVtb3J5Q2FjaGUuc2l6ZTtcbiAgfVxuXG4gIHB1YmxpYyBjbGVhckNhY2hlKCk6IHZvaWQge1xuICAgIHRoaXMuaW5NZW1vcnlDYWNoZS5jbGVhcigpO1xuICB9XG59XG4iXX0=
@@ -3,22 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const memory_cache_handler_1 = require("./memory-cache-handler");
4
4
  describe("MemoryCacheHandler", () => {
5
5
  let handler;
6
- let mockContext;
7
6
  beforeEach(() => {
8
- mockContext = { dev: false };
9
- handler = new memory_cache_handler_1.MemoryCacheHandler({
10
- context: mockContext,
11
- });
7
+ handler = new memory_cache_handler_1.MemoryCacheHandler();
12
8
  });
13
9
  afterEach(() => {
14
10
  handler.clearCache();
15
11
  });
16
12
  describe("get", () => {
17
13
  it("should return null for non-existent cache key", async () => {
18
- const result = await handler.get("non-existent", {
19
- kind: "APP_PAGE" /* IncrementalCacheKind.APP_PAGE */,
20
- isFallback: false,
21
- });
14
+ const result = await handler.get("non-existent");
22
15
  expect(result).toBeNull();
23
16
  });
24
17
  it("should return cached value from memory", async () => {
@@ -31,13 +24,8 @@ describe("MemoryCacheHandler", () => {
31
24
  segmentData: undefined,
32
25
  status: undefined,
33
26
  };
34
- await handler.set("test-key", testData, {
35
- fetchCache: true,
36
- });
37
- const result = await handler.get("test-key", {
38
- kind: "APP_PAGE" /* IncrementalCacheKind.APP_PAGE */,
39
- isFallback: false,
40
- });
27
+ await handler.set("test-key", testData);
28
+ const result = await handler.get("test-key");
41
29
  expect(result).not.toBeNull();
42
30
  expect(result?.value).toEqual(testData);
43
31
  });
@@ -53,91 +41,123 @@ describe("MemoryCacheHandler", () => {
53
41
  segmentData: undefined,
54
42
  status: undefined,
55
43
  };
56
- await handler.set("set-key", testData, {
57
- fetchCache: true,
58
- });
44
+ await handler.set("set-key", testData);
59
45
  expect(handler.getCacheSize()).toBe(1);
60
- const result = await handler.get("set-key", {
61
- kind: "APP_PAGE" /* IncrementalCacheKind.APP_PAGE */,
62
- isFallback: false,
63
- });
46
+ const result = await handler.get("set-key");
64
47
  expect(result?.value).toEqual(testData);
65
48
  });
49
+ it("keeps the lastModified an entry copied from a slower layer was rendered at", async () => {
50
+ // Stamping the time of the copy made an entry due for regeneration, or
51
+ // one a soft `revalidateTag` had made stale, look freshly rendered.
52
+ const testData = {
53
+ kind: "APP_PAGE" /* CachedRouteKind.APP_PAGE */,
54
+ html: "<html>promoted</html>",
55
+ rscData: undefined,
56
+ headers: undefined,
57
+ postponed: undefined,
58
+ segmentData: undefined,
59
+ status: undefined,
60
+ };
61
+ const renderedAt = Date.now() - 60_000;
62
+ await handler.set("promoted", testData, renderedAt);
63
+ expect(await handler.get("promoted")).toEqual({
64
+ lastModified: renderedAt,
65
+ value: testData,
66
+ });
67
+ });
68
+ it("stamps a fresh render on the tag markers' clock, not Date.now()", async () => {
69
+ // A memory hit is judged against tag markers stamped with `markerClock`.
70
+ // With `Date.now()` running ahead of it, a `revalidateTag` inside the
71
+ // drift left the entry looking newer than the marker, and it was served
72
+ // for the whole memory TTL.
73
+ const markerNow = 1_000_000;
74
+ jest.spyOn(performance, "now").mockReturnValue(markerNow);
75
+ jest
76
+ .spyOn(Date, "now")
77
+ .mockReturnValue(performance.timeOrigin + 5 * 60_000 + markerNow);
78
+ try {
79
+ await handler.set("fresh", {
80
+ kind: "APP_PAGE" /* CachedRouteKind.APP_PAGE */,
81
+ html: "<html>fresh</html>",
82
+ rscData: undefined,
83
+ headers: undefined,
84
+ postponed: undefined,
85
+ segmentData: undefined,
86
+ status: undefined,
87
+ });
88
+ const entry = await handler.get("fresh");
89
+ expect(entry?.lastModified).toBe(performance.timeOrigin + markerNow);
90
+ }
91
+ finally {
92
+ jest.restoreAllMocks();
93
+ }
94
+ });
66
95
  });
67
- describe("revalidateTag", () => {
68
- const testData = {
96
+ describe("bounds", () => {
97
+ const page = (html) => ({
69
98
  kind: "APP_PAGE" /* CachedRouteKind.APP_PAGE */,
70
- html: "<html>tagged</html>",
99
+ html,
71
100
  rscData: undefined,
72
101
  headers: undefined,
73
102
  postponed: undefined,
74
103
  segmentData: undefined,
75
104
  status: undefined,
76
- };
77
- it("should remove entries tagged with the revalidated tag", async () => {
78
- await handler.set("tagged-key", testData, {
79
- fetchCache: true,
80
- tags: ["collection"],
81
- });
82
- await handler.revalidateTag("collection");
83
- const result = await handler.get("tagged-key", {
84
- kind: "APP_PAGE" /* IncrementalCacheKind.APP_PAGE */,
85
- isFallback: false,
86
- });
87
- expect(result).toBeNull();
88
- expect(handler.getCacheSize()).toBe(0);
89
105
  });
90
- it("should not remove entries with unrelated tags", async () => {
91
- await handler.set("unrelated-key", testData, {
92
- fetchCache: true,
93
- tags: ["other-tag"],
94
- });
95
- await handler.revalidateTag("collection");
96
- const result = await handler.get("unrelated-key", {
97
- kind: "APP_PAGE" /* IncrementalCacheKind.APP_PAGE */,
98
- isFallback: false,
99
- });
100
- expect(result).not.toBeNull();
101
- expect(handler.getCacheSize()).toBe(1);
106
+ const env = process.env;
107
+ beforeEach(() => {
108
+ process.env = { ...env };
102
109
  });
103
- it("should accept an array of tags and remove any matching entries", async () => {
104
- await handler.set("key-a", testData, {
105
- fetchCache: true,
106
- tags: ["tag-a"],
107
- });
108
- await handler.set("key-b", testData, {
109
- fetchCache: true,
110
- tags: ["tag-b"],
111
- });
112
- await handler.revalidateTag(["tag-a", "tag-b"]);
110
+ afterEach(() => {
111
+ process.env = env;
112
+ jest.restoreAllMocks();
113
+ });
114
+ it("drops an entry past its TTL on read", async () => {
115
+ process.env.CDK_NEXTJS_MEMORY_CACHE_TTL_MS = "1000";
116
+ const clock = jest.spyOn(Date, "now").mockReturnValue(1_000_000);
117
+ handler = new memory_cache_handler_1.MemoryCacheHandler();
118
+ await handler.set("a", page("a"));
119
+ clock.mockReturnValue(1_001_000);
120
+ expect(await handler.get("a")).not.toBeNull();
121
+ clock.mockReturnValue(1_001_001);
122
+ expect(await handler.get("a")).toBeNull();
113
123
  expect(handler.getCacheSize()).toBe(0);
114
124
  });
115
- it("should be a no-op when no entries match the tag", async () => {
116
- await handler.set("untagged-key", testData, {
117
- fetchCache: true,
118
- });
119
- await expect(handler.revalidateTag("nonexistent-tag")).resolves.not.toThrow();
125
+ it("clears every expired entry on the next write", async () => {
126
+ process.env.CDK_NEXTJS_MEMORY_CACHE_TTL_MS = "1000";
127
+ const clock = jest.spyOn(Date, "now").mockReturnValue(1_000_000);
128
+ handler = new memory_cache_handler_1.MemoryCacheHandler();
129
+ await handler.set("a", page("a"));
130
+ await handler.set("b", page("b"));
131
+ clock.mockReturnValue(1_002_000);
132
+ await handler.set("c", page("c"));
120
133
  expect(handler.getCacheSize()).toBe(1);
121
134
  });
122
- });
123
- describe("resetRequestCache", () => {
124
- it("should clear all caches", async () => {
125
- const testData = {
126
- kind: "APP_PAGE" /* CachedRouteKind.APP_PAGE */,
127
- html: "<html>reset test</html>",
128
- rscData: undefined,
129
- headers: undefined,
130
- postponed: undefined,
131
- segmentData: undefined,
132
- status: undefined,
133
- };
134
- await handler.set("reset-key", testData, {
135
- fetchCache: true,
136
- });
137
- expect(handler.getCacheSize()).toBe(1);
138
- await handler.resetRequestCache();
139
- expect(handler.getCacheSize()).toBe(0);
135
+ it("evicts the least recently used entry at the limit", async () => {
136
+ process.env.CDK_NEXTJS_MEMORY_CACHE_MAX_ENTRIES = "2";
137
+ handler = new memory_cache_handler_1.MemoryCacheHandler();
138
+ await handler.set("a", page("a"));
139
+ await handler.set("b", page("b"));
140
+ // A read makes `a` the most recently used.
141
+ await handler.get("a");
142
+ await handler.set("c", page("c"));
143
+ expect(handler.getCacheSize()).toBe(2);
144
+ expect(await handler.get("b")).toBeNull();
145
+ expect(await handler.get("a")).not.toBeNull();
146
+ expect(await handler.get("c")).not.toBeNull();
147
+ });
148
+ it("falls back to the defaults for values that are not numbers", async () => {
149
+ // As NaN, nothing expired and nothing was evicted: an unbounded map.
150
+ process.env.CDK_NEXTJS_MEMORY_CACHE_TTL_MS = "abc";
151
+ process.env.CDK_NEXTJS_MEMORY_CACHE_MAX_ENTRIES = "abc";
152
+ const clock = jest.spyOn(Date, "now").mockReturnValue(1_000_000);
153
+ handler = new memory_cache_handler_1.MemoryCacheHandler();
154
+ for (let i = 0; i <= 1000; i++) {
155
+ await handler.set(`k${i}`, page("x"));
156
+ }
157
+ expect(handler.getCacheSize()).toBe(1000);
158
+ clock.mockReturnValue(1_000_000 + 60 * 60 * 1000 + 1);
159
+ expect(await handler.get("k1000")).toBeNull();
140
160
  });
141
161
  });
142
162
  });
143
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LWNhY2hlLWhhbmRsZXIudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVyL21lbW9yeS1jYWNoZS1oYW5kbGVyLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFPQSxpRUFBNEQ7QUFFNUQsUUFBUSxDQUFDLG9CQUFvQixFQUFFLEdBQUcsRUFBRTtJQUNsQyxJQUFJLE9BQTJCLENBQUM7SUFDaEMsSUFBSSxXQUFnQyxDQUFDO0lBRXJDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7UUFDZCxXQUFXLEdBQUcsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUF5QixDQUFDO1FBRXBELE9BQU8sR0FBRyxJQUFJLHlDQUFrQixDQUFDO1lBQy9CLE9BQU8sRUFBRSxXQUFXO1NBQ3JCLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsU0FBUyxDQUFDLEdBQUcsRUFBRTtRQUNiLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUN2QixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFO1FBQ25CLEVBQUUsQ0FBQywrQ0FBK0MsRUFBRSxLQUFLLElBQUksRUFBRTtZQUM3RCxNQUFNLE1BQU0sR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxFQUFFO2dCQUMvQyxJQUFJLGdEQUErQjtnQkFDbkMsVUFBVSxFQUFFLEtBQUs7YUFDbEIsQ0FBQyxDQUFDO1lBQ0gsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzVCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHdDQUF3QyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3RELE1BQU0sUUFBUSxHQUEwQjtnQkFDdEMsSUFBSSwyQ0FBMEI7Z0JBQzlCLElBQUksRUFBRSxtQkFBbUI7Z0JBQ3pCLE9BQU8sRUFBRSxTQUFTO2dCQUNsQixPQUFPLEVBQUUsU0FBUztnQkFDbEIs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dGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXMgKi9cbmltcG9ydCB7IENhY2hlSGFuZGxlckNvbnRleHQgfSBmcm9tIFwibmV4dC9kaXN0L3NlcnZlci9saWIvaW5jcmVtZW50YWwtY2FjaGVcIjtcbmltcG9ydCB7XG4gIEluY3JlbWVudGFsQ2FjaGVWYWx1ZSxcbiAgQ2FjaGVkUm91dGVLaW5kLFxuICBJbmNyZW1lbnRhbENhY2hlS2luZCxcbn0gZnJvbSBcIm5leHQvZGlzdC9zZXJ2ZXIvcmVzcG9uc2UtY2FjaGVcIjtcbmltcG9ydCB7IE1lbW9yeUNhY2hlSGFuZGxlciB9IGZyb20gXCIuL21lbW9yeS1jYWNoZS1oYW5kbGVyXCI7XG5cbmRlc2NyaWJlKFwiTWVtb3J5Q2FjaGVIYW5kbGVyXCIsICgpID0+IHtcbiAgbGV0IGhhbmRsZXI6IE1lbW9yeUNhY2hlSGFuZGxlcjtcbiAgbGV0IG1vY2tDb250ZXh0OiBDYWNoZUhhbmRsZXJDb250ZXh0O1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIG1vY2tDb250ZXh0ID0geyBkZXY6IGZhbHNlIH0gYXMgQ2FjaGVIYW5kbGVyQ29udGV4dDtcblxuICAgIGhhbmRsZXIgPSBuZXcgTWVtb3J5Q2FjaGVIYW5kbGVyKHtcbiAgICAgIGNvbnRleHQ6IG1vY2tDb250ZXh0LFxuICAgIH0pO1xuICB9KTtcblxuICBhZnRlckVhY2goKCkgPT4ge1xuICAgIGhhbmRsZXIuY2xlYXJDYWNoZSgpO1xuICB9KTtcblxuICBkZXNjcmliZShcImdldFwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgcmV0dXJuIG51bGwgZm9yIG5vbi1leGlzdGVudCBjYWNoZSBrZXlcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaGFuZGxlci5nZXQoXCJub24tZXhpc3RlbnRcIiwge1xuICAgICAgICBraW5kOiBJbmNyZW1lbnRhbENhY2hlS2luZC5BUFBfUEFHRSxcbiAgICAgICAgaXNGYWxsYmFjazogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmVOdWxsKCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCByZXR1cm4gY2FjaGVkIHZhbHVlIGZyb20gbWVtb3J5XCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3REYXRhOiBJbmNyZW1lbnRhbENhY2hlVmFsdWUgPSB7XG4gICAgICAgIGtpbmQ6IENhY2hlZFJvdXRlS2luZC5BUFBfUEFHRSxcbiAgICAgICAgaHRtbDogXCI8aHRtbD50ZXN0PC9odG1sPlwiLFxuICAgICAgICByc2NEYXRhOiB1bmRlZmluZWQsXG4gICAgICAgIGhlYWRlcnM6IHVuZGVmaW5lZCxcbiAgICAgICAgcG9zdHBvbmVkOiB1bmRlZmluZWQsXG4gICAgICAgIHNlZ21lbnREYXRhOiB1bmRlZmluZWQsXG4gICAgICAgIHN0YXR1czogdW5kZWZpbmVkLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgaGFuZGxlci5zZXQoXCJ0ZXN0LWtleVwiLCB0ZXN0RGF0YSwge1xuICAgICAgICBmZXRjaENhY2hlOiB0cnVlIGFzIGNvbnN0LFxuICAgICAgfSk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBoYW5kbGVyLmdldChcInRlc3Qta2V5XCIsIHtcbiAgICAgICAga2luZDogSW5jcmVtZW50YWxDYWNoZUtpbmQuQVBQX1BBR0UsXG4gICAgICAgIGlzRmFsbGJhY2s6IGZhbHNlLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChyZXN1bHQpLm5vdC50b0JlTnVsbCgpO1xuICAgICAgZXhwZWN0KHJlc3VsdD8udmFsdWUpLnRvRXF1YWwodGVzdERhdGEpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcInNldFwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgc3RvcmUgdmFsdWUgaW4gbWVtb3J5IGNhY2hlXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3REYXRhOiBJbmNyZW1lbnRhbENhY2hlVmFsdWUgPSB7XG4gICAgICAgIGtpbmQ6IENhY2hlZFJvdXRlS2luZC5BUFBfUEFHRSxcbiAgICAgICAgaHRtbDogXCI8aHRtbD5zZXQgdGVzdDwvaHRtbD5cIixcbiAgICAgICAgcnNjRGF0YTogdW5kZWZpbmVkLFxuICAgICAgICBoZWFkZXJzOiB1bmRlZmluZWQsXG4gICAgICAgIHBvc3Rwb25lZDogdW5kZWZpbmVkLFxuICAgICAgICBzZWdtZW50RGF0YTogdW5kZWZpbmVkLFxuICAgICAgICBzdGF0dXM6IHVuZGVmaW5lZCxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IGhhbmRsZXIuc2V0KFwic2V0LWtleVwiLCB0ZXN0RGF0YSwge1xuICAgICAgICBmZXRjaENhY2hlOiB0cnVlIGFzIGNvbnN0LFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChoYW5kbGVyLmdldENhY2hlU2l6ZSgpKS50b0JlKDEpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBoYW5kbGVyLmdldChcInNldC1rZXlcIiwge1xuICAgICAgICBraW5kOiBJbmNyZW1lbnRhbENhY2hlS2luZC5BUFBfUEFHRSxcbiAgICAgICAgaXNGYWxsYmFjazogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChyZXN1bHQ/LnZhbHVlKS50b0VxdWFsKHRlc3REYXRhKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJyZXZhbGlkYXRlVGFnXCIsICgpID0+IHtcbiAgICBjb25zdCB0ZXN0RGF0YTogSW5jcmVtZW50YWxDYWNoZVZhbHVlID0ge1xuICAgICAga2luZDogQ2FjaGVkUm91dGVLaW5kLkFQUF9QQUdFLFxuICAgICAgaHRtbDogXCI8aHRtbD50YWdnZWQ8L2h0bWw+XCIsXG4gICAgICByc2NEYXRhOiB1bmRlZmluZWQsXG4gICAgICBoZWFkZXJzOiB1bmRlZmluZWQsXG4gICAgICBwb3N0cG9uZWQ6IHVuZGVmaW5lZCxcbiAgICAgIHNlZ21lbnREYXRhOiB1bmRlZmluZWQsXG4gICAgICBzdGF0dXM6IHVuZGVmaW5lZCxcbiAgICB9O1xuXG4gICAgaXQoXCJzaG91bGQgcmVtb3ZlIGVudHJpZXMgdGFnZ2VkIHdpdGggdGhlIHJldmFsaWRhdGVkIHRhZ1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBoYW5kbGVyLnNldChcInRhZ2dlZC1rZXlcIiwgdGVzdERhdGEsIHtcbiAgICAgICAgZmV0Y2hDYWNoZTogdHJ1ZSBhcyBjb25zdCxcbiAgICAgICAgdGFnczogW1wiY29sbGVjdGlvblwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBhd2FpdCBoYW5kbGVyLnJldmFsaWRhdGVUYWcoXCJjb2xsZWN0aW9uXCIpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBoYW5kbGVyLmdldChcInRhZ2dlZC1rZXlcIiwge1xuICAgICAgICBraW5kOiBJbmNyZW1lbnRhbENhY2hlS2luZC5BUFBfUEFHRSxcbiAgICAgICAgaXNGYWxsYmFjazogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmVOdWxsKCk7XG4gICAgICBleHBlY3QoaGFuZGxlci5nZXRDYWNoZVNpemUoKSkudG9CZSgwKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIG5vdCByZW1vdmUgZW50cmllcyB3aXRoIHVucmVsYXRlZCB0YWdzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IGhhbmRsZXIuc2V0KFwidW5yZWxhdGVkLWtleVwiLCB0ZXN0RGF0YSwge1xuICAgICAgICBmZXRjaENhY2hlOiB0cnVlIGFzIGNvbnN0LFxuICAgICAgICB0YWdzOiBbXCJvdGhlci10YWdcIl0sXG4gICAgICB9KTtcblxuICAgICAgYXdhaXQgaGFuZGxlci5yZXZhbGlkYXRlVGFnKFwiY29sbGVjdGlvblwiKTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaGFuZGxlci5nZXQoXCJ1bnJlbGF0ZWQta2V5XCIsIHtcbiAgICAgICAga2luZDogSW5jcmVtZW50YWxDYWNoZUtpbmQuQVBQX1BBR0UsXG4gICAgICAgIGlzRmFsbGJhY2s6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgICBleHBlY3QocmVzdWx0KS5ub3QudG9CZU51bGwoKTtcbiAgICAgIGV4cGVjdChoYW5kbGVyLmdldENhY2hlU2l6ZSgpKS50b0JlKDEpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgYWNjZXB0IGFuIGFycmF5IG9mIHRhZ3MgYW5kIHJlbW92ZSBhbnkgbWF0Y2hpbmcgZW50cmllc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBoYW5kbGVyLnNldChcImtleS1hXCIsIHRlc3REYXRhLCB7XG4gICAgICAgIGZldGNoQ2FjaGU6IHRydWUgYXMgY29uc3QsXG4gICAgICAgIHRhZ3M6IFtcInRhZy1hXCJdLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCBoYW5kbGVyLnNldChcImtleS1iXCIsIHRlc3REYXRhLCB7XG4gICAgICAgIGZldGNoQ2FjaGU6IHRydWUgYXMgY29uc3QsXG4gICAgICAgIHRhZ3M6IFtcInRhZy1iXCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGhhbmRsZXIucmV2YWxpZGF0ZVRhZyhbXCJ0YWctYVwiLCBcInRhZy1iXCJdKTtcblxuICAgICAgZXhwZWN0KGhhbmRsZXIuZ2V0Q2FjaGVTaXplKCkpLnRvQmUoMCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBiZSBhIG5vLW9wIHdoZW4gbm8gZW50cmllcyBtYXRjaCB0aGUgdGFnXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IGhhbmRsZXIuc2V0KFwidW50YWdnZWQta2V5XCIsIHRlc3REYXRhLCB7XG4gICAgICAgIGZldGNoQ2FjaGU6IHRydWUgYXMgY29uc3QsXG4gICAgICB9KTtcblxuICAgICAgYXdhaXQgZXhwZWN0KFxuICAgICAgICBoYW5kbGVyLnJldmFsaWRhdGVUYWcoXCJub25leGlzdGVudC10YWdcIiksXG4gICAgICApLnJlc29sdmVzLm5vdC50b1Rocm93KCk7XG4gICAgICBleHBlY3QoaGFuZGxlci5nZXRDYWNoZVNpemUoKSkudG9CZSgxKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJyZXNldFJlcXVlc3RDYWNoZVwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY2xlYXIgYWxsIGNhY2hlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0RGF0YTogSW5jcmVtZW50YWxDYWNoZVZhbHVlID0ge1xuICAgICAgICBraW5kOiBDYWNoZWRSb3V0ZUtpbmQuQVBQX1BBR0UsXG4gICAgICAgIGh0bWw6IFwiPGh0bWw+cmVzZXQgdGVzdDwvaHRtbD5cIixcbiAgICAgICAgcnNjRGF0YTogdW5kZWZpbmVkLFxuICAgICAgICBoZWFkZXJzOiB1bmRlZmluZWQsXG4gICAgICAgIHBvc3Rwb25lZDogdW5kZWZpbmVkLFxuICAgICAgICBzZWdtZW50RGF0YTogdW5kZWZpbmVkLFxuICAgICAgICBzdGF0dXM6IHVuZGVmaW5lZCxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IGhhbmRsZXIuc2V0KFwicmVzZXQta2V5XCIsIHRlc3REYXRhLCB7XG4gICAgICAgIGZldGNoQ2FjaGU6IHRydWUgYXMgY29uc3QsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGhhbmRsZXIuZ2V0Q2FjaGVTaXplKCkpLnRvQmUoMSk7XG5cbiAgICAgIGF3YWl0IGhhbmRsZXIucmVzZXRSZXF1ZXN0Q2FjaGUoKTtcblxuICAgICAgZXhwZWN0KGhhbmRsZXIuZ2V0Q2FjaGVTaXplKCkpLnRvQmUoMCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
163
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LWNhY2hlLWhhbmRsZXIudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVyL21lbW9yeS1jYWNoZS1oYW5kbGVyLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFLQSxpRUFBNEQ7QUFFNUQsUUFBUSxDQUFDLG9CQUFvQixFQUFFLEdBQUcsRUFBRTtJQUNsQyxJQUFJLE9BQTJCLENBQUM7SUFFaEMsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLE9BQU8sR0FBRyxJQUFJLHlDQUFrQixFQUFFLENBQUM7SUFDckMsQ0FBQyxDQUFDLENBQUM7SUFFSCxTQUFTLENBQUMsR0FBRyxFQUFFO1FBQ2IsT0FBTyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3ZCLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUU7UUFDbkIsRUFBRSxDQUFDLCtDQUErQyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzdELE1BQU0sTUFBTSxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUNqRCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsd0NBQXdDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDdEQsTUFBTSxRQUFRLEdBQTBCO2dCQUN0QyxJQUFJLDJDQUEwQjtnQkFDOUIsSUFBSSxFQUFFLG1CQUFtQjtnQkFDekIsT0FBTyxFQUFFLFNBQVM7Z0JBQ2xCLE9BQU8sRUFBRSxTQUFTO2dCQUNsQixTQUFTLEVBQUUsU0FBUztnQkFDcEIsV0FBVyxFQUFFLFNBQVM7Z0JBQ3RCLE1BQU0sRUFBRSxTQUFTO2FBQ2xCLENBQUM7WUFFRixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3hDLE1BQU0sTUFBTSxHQUFHLE1BQU0s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QUFFLEtBQUssSUFBSSxFQUFFO1lBQzFFLHFFQUFxRTtZQUNyRSxPQUFPLENBQUMsR0FBRyxDQUFDLDhCQUE4QixHQUFHLEtBQUssQ0FBQztZQUNuRCxPQUFPLENBQUMsR0FBRyxDQUFDLG1DQUFtQyxHQUFHLEtBQUssQ0FBQztZQUN4RCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDakUsT0FBTyxHQUFHLElBQUkseUNBQWtCLEVBQUUsQ0FBQztZQUNuQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQy9CLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLENBQUM7WUFDRCxNQUFNLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRTFDLEtBQUssQ0FBQyxlQUFlLENBQUMsU0FBUyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3RELE1BQU0sQ0FBQyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNoRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXMgKi9cbmltcG9ydCB7XG4gIEluY3JlbWVudGFsQ2FjaGVWYWx1ZSxcbiAgQ2FjaGVkUm91dGVLaW5kLFxufSBmcm9tIFwibmV4dC9kaXN0L3NlcnZlci9yZXNwb25zZS1jYWNoZVwiO1xuaW1wb3J0IHsgTWVtb3J5Q2FjaGVIYW5kbGVyIH0gZnJvbSBcIi4vbWVtb3J5LWNhY2hlLWhhbmRsZXJcIjtcblxuZGVzY3JpYmUoXCJNZW1vcnlDYWNoZUhhbmRsZXJcIiwgKCkgPT4ge1xuICBsZXQgaGFuZGxlcjogTWVtb3J5Q2FjaGVIYW5kbGVyO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGhhbmRsZXIgPSBuZXcgTWVtb3J5Q2FjaGVIYW5kbGVyKCk7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgaGFuZGxlci5jbGVhckNhY2hlKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiZ2V0XCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCByZXR1cm4gbnVsbCBmb3Igbm9uLWV4aXN0ZW50IGNhY2hlIGtleVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBoYW5kbGVyLmdldChcIm5vbi1leGlzdGVudFwiKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmVOdWxsKCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCByZXR1cm4gY2FjaGVkIHZhbHVlIGZyb20gbWVtb3J5XCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3REYXRhOiBJbmNyZW1lbnRhbENhY2hlVmFsdWUgPSB7XG4gICAgICAgIGtpbmQ6IENhY2hlZFJvdXRlS2luZC5BUFBfUEFHRSxcbiAgICAgICAgaHRtbDogXCI8aHRtbD50ZXN0PC9odG1sPlwiLFxuICAgICAgICByc2NEYXRhOiB1bmRlZmluZWQsXG4gICAgICAgIGhlYWRlcnM6IHVuZGVmaW5lZCxcbiAgICAgICAgcG9zdHBvbmVkOiB1bmRlZmluZWQsXG4gICAgICAgIHNlZ21lbnREYXRhOiB1bmRlZmluZWQsXG4gICAgICAgIHN0YXR1czogdW5kZWZpbmVkLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgaGFuZGxlci5zZXQoXCJ0ZXN0LWtleVwiLCB0ZXN0RGF0YSk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBoYW5kbGVyLmdldChcInRlc3Qta2V5XCIpO1xuXG4gICAgICBleHBlY3QocmVzdWx0KS5ub3QudG9CZU51bGwoKTtcbiAgICAgIGV4cGVjdChyZXN1bHQ/LnZhbHVlKS50b0VxdWFsKHRlc3REYXRhKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJzZXRcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHN0b3JlIHZhbHVlIGluIG1lbW9yeSBjYWNoZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0RGF0YTogSW5jcmVtZW50YWxDYWNoZVZhbHVlID0ge1xuICAgICAgICBraW5kOiBDYWNoZWRSb3V0ZUtpbmQuQVBQX1BBR0UsXG4gICAgICAgIGh0bWw6IFwiPGh0bWw+c2V0IHRlc3Q8L2h0bWw+XCIsXG4gICAgICAgIHJzY0RhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgaGVhZGVyczogdW5kZWZpbmVkLFxuICAgICAgICBwb3N0cG9uZWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgc2VnbWVudERhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgc3RhdHVzOiB1bmRlZmluZWQsXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCBoYW5kbGVyLnNldChcInNldC1rZXlcIiwgdGVzdERhdGEpO1xuXG4gICAgICBleHBlY3QoaGFuZGxlci5nZXRDYWNoZVNpemUoKSkudG9CZSgxKTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaGFuZGxlci5nZXQoXCJzZXQta2V5XCIpO1xuICAgICAgZXhwZWN0KHJlc3VsdD8udmFsdWUpLnRvRXF1YWwodGVzdERhdGEpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJrZWVwcyB0aGUgbGFzdE1vZGlmaWVkIGFuIGVudHJ5IGNvcGllZCBmcm9tIGEgc2xvd2VyIGxheWVyIHdhcyByZW5kZXJlZCBhdFwiLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBTdGFtcGluZyB0aGUgdGltZSBvZiB0aGUgY29weSBtYWRlIGFuIGVudHJ5IGR1ZSBmb3IgcmVnZW5lcmF0aW9uLCBvclxuICAgICAgLy8gb25lIGEgc29mdCBgcmV2YWxpZGF0ZVRhZ2AgaGFkIG1hZGUgc3RhbGUsIGxvb2sgZnJlc2hseSByZW5kZXJlZC5cbiAgICAgIGNvbnN0IHRlc3REYXRhOiBJbmNyZW1lbnRhbENhY2hlVmFsdWUgPSB7XG4gICAgICAgIGtpbmQ6IENhY2hlZFJvdXRlS2luZC5BUFBfUEFHRSxcbiAgICAgICAgaHRtbDogXCI8aHRtbD5wcm9tb3RlZDwvaHRtbD5cIixcbiAgICAgICAgcnNjRGF0YTogdW5kZWZpbmVkLFxuICAgICAgICBoZWFkZXJzOiB1bmRlZmluZWQsXG4gICAgICAgIHBvc3Rwb25lZDogdW5kZWZpbmVkLFxuICAgICAgICBzZWdtZW50RGF0YTogdW5kZWZpbmVkLFxuICAgICAgICBzdGF0dXM6IHVuZGVmaW5lZCxcbiAgICAgIH07XG4gICAgICBjb25zdCByZW5kZXJlZEF0ID0gRGF0ZS5ub3coKSAtIDYwXzAwMDtcblxuICAgICAgYXdhaXQgaGFuZGxlci5zZXQoXCJwcm9tb3RlZFwiLCB0ZXN0RGF0YSwgcmVuZGVyZWRBdCk7XG5cbiAgICAgIGV4cGVjdChhd2FpdCBoYW5kbGVyLmdldChcInByb21vdGVkXCIpKS50b0VxdWFsKHtcbiAgICAgICAgbGFzdE1vZGlmaWVkOiByZW5kZXJlZEF0LFxuICAgICAgICB2YWx1ZTogdGVzdERhdGEsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KFwic3RhbXBzIGEgZnJlc2ggcmVuZGVyIG9uIHRoZSB0YWcgbWFya2VycycgY2xvY2ssIG5vdCBEYXRlLm5vdygpXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIEEgbWVtb3J5IGhpdCBpcyBqdWRnZWQgYWdhaW5zdCB0YWcgbWFya2VycyBzdGFtcGVkIHdpdGggYG1hcmtlckNsb2NrYC5cbiAgICAgIC8vIFdpdGggYERhdGUubm93KClgIHJ1bm5pbmcgYWhlYWQgb2YgaXQsIGEgYHJldmFsaWRhdGVUYWdgIGluc2lkZSB0aGVcbiAgICAgIC8vIGRyaWZ0IGxlZnQgdGhlIGVudHJ5IGxvb2tpbmcgbmV3ZXIgdGhhbiB0aGUgbWFya2VyLCBhbmQgaXQgd2FzIHNlcnZlZFxuICAgICAgLy8gZm9yIHRoZSB3aG9sZSBtZW1vcnkgVFRMLlxuICAgICAgY29uc3QgbWFya2VyTm93ID0gMV8wMDBfMDAwO1xuICAgICAgamVzdC5zcHlPbihwZXJmb3JtYW5jZSwgXCJub3dcIikubW9ja1JldHVyblZhbHVlKG1hcmtlck5vdyk7XG4gICAgICBqZXN0XG4gICAgICAgIC5zcHlPbihEYXRlLCBcIm5vd1wiKVxuICAgICAgICAubW9ja1JldHVyblZhbHVlKHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4gKyA1ICogNjBfMDAwICsgbWFya2VyTm93KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGhhbmRsZXIuc2V0KFwiZnJlc2hcIiwge1xuICAgICAgICAgIGtpbmQ6IENhY2hlZFJvdXRlS2luZC5BUFBfUEFHRSxcbiAgICAgICAgICBodG1sOiBcIjxodG1sPmZyZXNoPC9odG1sPlwiLFxuICAgICAgICAgIHJzY0RhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgICBoZWFkZXJzOiB1bmRlZmluZWQsXG4gICAgICAgICAgcG9zdHBvbmVkOiB1bmRlZmluZWQsXG4gICAgICAgICAgc2VnbWVudERhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgICBzdGF0dXM6IHVuZGVmaW5lZCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgZW50cnkgPSBhd2FpdCBoYW5kbGVyLmdldChcImZyZXNoXCIpO1xuICAgICAgICBleHBlY3QoZW50cnk/Lmxhc3RNb2RpZmllZCkudG9CZShwZXJmb3JtYW5jZS50aW1lT3JpZ2luICsgbWFya2VyTm93KTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGplc3QucmVzdG9yZUFsbE1vY2tzKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiYm91bmRzXCIsICgpID0+IHtcbiAgICBjb25zdCBwYWdlID0gKGh0bWw6IHN0cmluZyk6IEluY3JlbWVudGFsQ2FjaGVWYWx1ZSA9PiAoe1xuICAgICAga2luZDogQ2FjaGVkUm91dGVLaW5kLkFQUF9QQUdFLFxuICAgICAgaHRtbCxcbiAgICAgIHJzY0RhdGE6IHVuZGVmaW5lZCxcbiAgICAgIGhlYWRlcnM6IHVuZGVmaW5lZCxcbiAgICAgIHBvc3Rwb25lZDogdW5kZWZpbmVkLFxuICAgICAgc2VnbWVudERhdGE6IHVuZGVmaW5lZCxcbiAgICAgIHN0YXR1czogdW5kZWZpbmVkLFxuICAgIH0pO1xuICAgIGNvbnN0IGVudiA9IHByb2Nlc3MuZW52O1xuXG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICBwcm9jZXNzLmVudiA9IHsgLi4uZW52IH07XG4gICAgfSk7XG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgIHByb2Nlc3MuZW52ID0gZW52O1xuICAgICAgamVzdC5yZXN0b3JlQWxsTW9ja3MoKTtcbiAgICB9KTtcblxuICAgIGl0KFwiZHJvcHMgYW4gZW50cnkgcGFzdCBpdHMgVFRMIG9uIHJlYWRcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgcHJvY2Vzcy5lbnYuQ0RLX05FWFRKU19NRU1PUllfQ0FDSEVfVFRMX01TID0gXCIxMDAwXCI7XG4gICAgICBjb25zdCBjbG9jayA9IGplc3Quc3B5T24oRGF0ZSwgXCJub3dcIikubW9ja1JldHVyblZhbHVlKDFfMDAwXzAwMCk7XG4gICAgICBoYW5kbGVyID0gbmV3IE1lbW9yeUNhY2hlSGFuZGxlcigpO1xuICAgICAgYXdhaXQgaGFuZGxlci5zZXQoXCJhXCIsIHBhZ2UoXCJhXCIpKTtcblxuICAgICAgY2xvY2subW9ja1JldHVyblZhbHVlKDFfMDAxXzAwMCk7XG4gICAgICBleHBlY3QoYXdhaXQgaGFuZGxlci5nZXQoXCJhXCIpKS5ub3QudG9CZU51bGwoKTtcbiAgICAgIGNsb2NrLm1vY2tSZXR1cm5WYWx1ZSgxXzAwMV8wMDEpO1xuICAgICAgZXhwZWN0KGF3YWl0IGhhbmRsZXIuZ2V0KFwiYVwiKSkudG9CZU51bGwoKTtcbiAgICAgIGV4cGVjdChoYW5kbGVyLmdldENhY2hlU2l6ZSgpKS50b0JlKDApO1xuICAgIH0pO1xuXG4gICAgaXQoXCJjbGVhcnMgZXZlcnkgZXhwaXJlZCBlbnRyeSBvbiB0aGUgbmV4dCB3cml0ZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBwcm9jZXNzLmVudi5DREtfTkVYVEpTX01FTU9SWV9DQUNIRV9UVExfTVMgPSBcIjEwMDBcIjtcbiAgICAgIGNvbnN0IGNsb2NrID0gamVzdC5zcHlPbihEYXRlLCBcIm5vd1wiKS5tb2NrUmV0dXJuVmFsdWUoMV8wMDBfMDAwKTtcbiAgICAgIGhhbmRsZXIgPSBuZXcgTWVtb3J5Q2FjaGVIYW5kbGVyKCk7XG4gICAgICBhd2FpdCBoYW5kbGVyLnNldChcImFcIiwgcGFnZShcImFcIikpO1xuICAgICAgYXdhaXQgaGFuZGxlci5zZXQoXCJiXCIsIHBhZ2UoXCJiXCIpKTtcblxuICAgICAgY2xvY2subW9ja1JldHVyblZhbHVlKDFfMDAyXzAwMCk7XG4gICAgICBhd2FpdCBoYW5kbGVyLnNldChcImNcIiwgcGFnZShcImNcIikpO1xuICAgICAgZXhwZWN0KGhhbmRsZXIuZ2V0Q2FjaGVTaXplKCkpLnRvQmUoMSk7XG4gICAgfSk7XG5cbiAgICBpdChcImV2aWN0cyB0aGUgbGVhc3QgcmVjZW50bHkgdXNlZCBlbnRyeSBhdCB0aGUgbGltaXRcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgcHJvY2Vzcy5lbnYuQ0RLX05FWFRKU19NRU1PUllfQ0FDSEVfTUFYX0VOVFJJRVMgPSBcIjJcIjtcbiAgICAgIGhhbmRsZXIgPSBuZXcgTWVtb3J5Q2FjaGVIYW5kbGVyKCk7XG4gICAgICBhd2FpdCBoYW5kbGVyLnNldChcImFcIiwgcGFnZShcImFcIikpO1xuICAgICAgYXdhaXQgaGFuZGxlci5zZXQoXCJiXCIsIHBhZ2UoXCJiXCIpKTtcbiAgICAgIC8vIEEgcmVhZCBtYWtlcyBgYWAgdGhlIG1vc3QgcmVjZW50bHkgdXNlZC5cbiAgICAgIGF3YWl0IGhhbmRsZXIuZ2V0KFwiYVwiKTtcbiAgICAgIGF3YWl0IGhhbmRsZXIuc2V0KFwiY1wiLCBwYWdlKFwiY1wiKSk7XG5cbiAgICAgIGV4cGVjdChoYW5kbGVyLmdldENhY2hlU2l6ZSgpKS50b0JlKDIpO1xuICAgICAgZXhwZWN0KGF3YWl0IGhhbmRsZXIuZ2V0KFwiYlwiKSkudG9CZU51bGwoKTtcbiAgICAgIGV4cGVjdChhd2FpdCBoYW5kbGVyLmdldChcImFcIikpLm5vdC50b0JlTnVsbCgpO1xuICAgICAgZXhwZWN0KGF3YWl0IGhhbmRsZXIuZ2V0KFwiY1wiKSkubm90LnRvQmVOdWxsKCk7XG4gICAgfSk7XG5cbiAgICBpdChcImZhbGxzIGJhY2sgdG8gdGhlIGRlZmF1bHRzIGZvciB2YWx1ZXMgdGhhdCBhcmUgbm90IG51bWJlcnNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gQXMgTmFOLCBub3RoaW5nIGV4cGlyZWQgYW5kIG5vdGhpbmcgd2FzIGV2aWN0ZWQ6IGFuIHVuYm91bmRlZCBtYXAuXG4gICAgICBwcm9jZXNzLmVudi5DREtfTkVYVEpTX01FTU9SWV9DQUNIRV9UVExfTVMgPSBcImFiY1wiO1xuICAgICAgcHJvY2Vzcy5lbnYuQ0RLX05FWFRKU19NRU1PUllfQ0FDSEVfTUFYX0VOVFJJRVMgPSBcImFiY1wiO1xuICAgICAgY29uc3QgY2xvY2sgPSBqZXN0LnNweU9uKERhdGUsIFwibm93XCIpLm1vY2tSZXR1cm5WYWx1ZSgxXzAwMF8wMDApO1xuICAgICAgaGFuZGxlciA9IG5ldyBNZW1vcnlDYWNoZUhhbmRsZXIoKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IDEwMDA7IGkrKykge1xuICAgICAgICBhd2FpdCBoYW5kbGVyLnNldChgayR7aX1gLCBwYWdlKFwieFwiKSk7XG4gICAgICB9XG4gICAgICBleHBlY3QoaGFuZGxlci5nZXRDYWNoZVNpemUoKSkudG9CZSgxMDAwKTtcblxuICAgICAgY2xvY2subW9ja1JldHVyblZhbHVlKDFfMDAwXzAwMCArIDYwICogNjAgKiAxMDAwICsgMSk7XG4gICAgICBleHBlY3QoYXdhaXQgaGFuZGxlci5nZXQoXCJrMTAwMFwiKSkudG9CZU51bGwoKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==