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
@@ -3,6 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ /* eslint-disable import/no-extraneous-dependencies */
7
+ const fs_1 = require("fs");
8
+ const os_1 = require("os");
9
+ const path_1 = require("path");
6
10
  const cache_handler_1 = __importDefault(require("./cache-handler"));
7
11
  // Mock AWS SDK clients
8
12
  jest.mock("@aws-sdk/client-s3");
@@ -30,12 +34,6 @@ describe("CdkNextjsCacheHandler - Orchestrator Pattern", () => {
30
34
  cache_handler_1.default.sharedMemoryHandler = null;
31
35
  cache_handler_1.default.sharedS3DynamoHandler = null;
32
36
  });
33
- describe("Orchestrator Pattern & Initialization", () => {
34
- it("should initialize as orchestrator with runtime handlers", () => {
35
- expect(cacheHandler).toBeDefined();
36
- // Runtime mode - memory and S3/DynamoDB handlers should be available
37
- });
38
- });
39
37
  describe("Orchestrator: Memory + S3/DynamoDB", () => {
40
38
  it("should write to both memory and S3/DynamoDB on set", async () => {
41
39
  const testData = {
@@ -47,18 +45,81 @@ describe("CdkNextjsCacheHandler - Orchestrator Pattern", () => {
47
45
  segmentData: undefined,
48
46
  status: undefined,
49
47
  };
48
+ const s3 = {
49
+ set: jest.fn().mockResolvedValue(undefined),
50
+ get: jest.fn().mockResolvedValue(null),
51
+ isRevalidated: jest.fn().mockResolvedValue(false),
52
+ };
53
+ cacheHandler.s3DynamoHandler = s3;
54
+ const setCtx = { fetchCache: true, tags: [] };
50
55
  // Set cache entry
51
- await cacheHandler.set("test-key", testData, {
52
- fetchCache: true,
53
- tags: [],
54
- });
55
- // Get should return from memory
56
+ await cacheHandler.set("test-key", testData, setCtx);
57
+ // S3/DynamoDB got the write, with the context it needs for tags.
58
+ expect(s3.set).toHaveBeenCalledWith("test-key", testData, setCtx);
59
+ // Get should return from memory, without asking S3.
56
60
  const result = await cacheHandler.get("test-key", {
57
61
  kind: "APP_PAGE" /* IncrementalCacheKind.APP_PAGE */,
58
62
  isFallback: false,
59
63
  });
60
64
  expect(result).not.toBeNull();
61
65
  expect(result?.value).toEqual(testData);
66
+ expect(s3.get).not.toHaveBeenCalled();
67
+ });
68
+ it("deletes from both layers on set(key, null)", async () => {
69
+ const testData = {
70
+ kind: "APP_PAGE" /* CachedRouteKind.APP_PAGE */,
71
+ html: "<html>gone</html>",
72
+ rscData: undefined,
73
+ headers: undefined,
74
+ postponed: undefined,
75
+ segmentData: undefined,
76
+ status: undefined,
77
+ };
78
+ const s3 = {
79
+ set: jest.fn().mockResolvedValue(undefined),
80
+ get: jest.fn().mockResolvedValue(null),
81
+ isRevalidated: jest.fn().mockResolvedValue(false),
82
+ };
83
+ cacheHandler.s3DynamoHandler = s3;
84
+ const setCtx = { fetchCache: true, tags: [] };
85
+ await cacheHandler.set("gone-key", testData, setCtx);
86
+ await cacheHandler.set("gone-key", null, setCtx);
87
+ // The S3 layer is told to delete, not skipped.
88
+ expect(s3.set).toHaveBeenLastCalledWith("gone-key", null, setCtx);
89
+ // And memory no longer answers: the read falls through to S3.
90
+ expect(await cacheHandler.get("gone-key", {
91
+ kind: "APP_PAGE" /* IncrementalCacheKind.APP_PAGE */,
92
+ isFallback: false,
93
+ })).toBeNull();
94
+ expect(s3.get).toHaveBeenCalledTimes(1);
95
+ });
96
+ it("revalidates a tag in S3/DynamoDB, passing the durations through", async () => {
97
+ const testData = {
98
+ kind: "APP_PAGE" /* CachedRouteKind.APP_PAGE */,
99
+ html: "<html>tagged</html>",
100
+ rscData: undefined,
101
+ headers: { "x-next-cache-tags": "posts" },
102
+ postponed: undefined,
103
+ segmentData: undefined,
104
+ status: undefined,
105
+ };
106
+ const s3 = {
107
+ set: jest.fn().mockResolvedValue(undefined),
108
+ get: jest.fn().mockResolvedValue(null),
109
+ isRevalidated: jest.fn().mockResolvedValue(false),
110
+ revalidateTag: jest.fn().mockResolvedValue(undefined),
111
+ };
112
+ cacheHandler.s3DynamoHandler = s3;
113
+ await cacheHandler.set("tagged-key", testData, {
114
+ fetchCache: true,
115
+ tags: ["posts"],
116
+ });
117
+ // `revalidateTag(tag, profile)`: the durations decide stale vs expired,
118
+ // so dropping them turns every soft revalidation into a hard one.
119
+ await cacheHandler.revalidateTag(["posts"], { expire: 60 });
120
+ expect(s3.revalidateTag).toHaveBeenCalledWith(["posts"], { expire: 60 });
121
+ await cacheHandler.revalidateTag("posts");
122
+ expect(s3.revalidateTag).toHaveBeenLastCalledWith("posts", undefined);
62
123
  });
63
124
  it("should handle cache misses gracefully", async () => {
64
125
  // Get non-existent key
@@ -69,7 +130,137 @@ describe("CdkNextjsCacheHandler - Orchestrator Pattern", () => {
69
130
  // Should return null (both memory and S3 miss)
70
131
  expect(result).toBeNull();
71
132
  });
72
- it("should propagate resetRequestCache to memory layer", async () => {
133
+ it("does not copy a tag-expired S3 entry into memory", async () => {
134
+ // `lastModified: -1` is the S3 layer saying "a tag revalidation expired
135
+ // this, re-render before answering". Copied into memory, the expired body
136
+ // would be answered from there instead of from the re-render.
137
+ const value = {
138
+ kind: "APP_PAGE" /* CachedRouteKind.APP_PAGE */,
139
+ html: "<html>expired</html>",
140
+ rscData: undefined,
141
+ headers: undefined,
142
+ postponed: undefined,
143
+ segmentData: undefined,
144
+ status: undefined,
145
+ };
146
+ const getCtx = {
147
+ kind: "APP_PAGE" /* IncrementalCacheKind.APP_PAGE */,
148
+ isFallback: false,
149
+ };
150
+ cacheHandler.s3DynamoHandler = {
151
+ get: jest.fn().mockResolvedValue({ lastModified: -1, value }),
152
+ };
153
+ expect(await cacheHandler.get("isr/1", getCtx)).toEqual({
154
+ lastModified: -1,
155
+ value,
156
+ });
157
+ // With the S3 layer now silent, a memory copy would answer this as a hit.
158
+ cacheHandler.s3DynamoHandler = {
159
+ get: jest.fn().mockResolvedValue(null),
160
+ };
161
+ expect(await cacheHandler.get("isr/1", getCtx)).toBeNull();
162
+ });
163
+ it("copies a live S3 entry into memory", async () => {
164
+ const value = {
165
+ kind: "APP_PAGE" /* CachedRouteKind.APP_PAGE */,
166
+ html: "<html>live</html>",
167
+ rscData: undefined,
168
+ headers: undefined,
169
+ postponed: undefined,
170
+ segmentData: undefined,
171
+ status: undefined,
172
+ };
173
+ const getCtx = {
174
+ kind: "APP_PAGE" /* IncrementalCacheKind.APP_PAGE */,
175
+ isFallback: false,
176
+ };
177
+ cacheHandler.s3DynamoHandler = {
178
+ get: jest.fn().mockResolvedValue({ lastModified: Date.now(), value }),
179
+ };
180
+ await cacheHandler.get("isr/2", getCtx);
181
+ const s3 = {
182
+ get: jest.fn().mockResolvedValue(null),
183
+ isRevalidated: jest.fn().mockResolvedValue(false),
184
+ };
185
+ cacheHandler.s3DynamoHandler = s3;
186
+ expect(await cacheHandler.get("isr/2", getCtx)).toMatchObject({ value });
187
+ expect(s3.get).not.toHaveBeenCalled();
188
+ });
189
+ it("keeps the S3 entry's lastModified when copying it into memory", async () => {
190
+ // Next.js ages the entry from `lastModified`, and the tag markers are
191
+ // compared against it. Stamping the time of the copy made a page a soft
192
+ // `revalidateTag` had made stale look newer than the stale mark.
193
+ const value = {
194
+ kind: "APP_PAGE" /* CachedRouteKind.APP_PAGE */,
195
+ html: "<html>old</html>",
196
+ rscData: undefined,
197
+ headers: undefined,
198
+ postponed: undefined,
199
+ segmentData: undefined,
200
+ status: undefined,
201
+ };
202
+ const getCtx = {
203
+ kind: "APP_PAGE" /* IncrementalCacheKind.APP_PAGE */,
204
+ isFallback: false,
205
+ };
206
+ const renderedAt = Date.now() - 60_000;
207
+ cacheHandler.s3DynamoHandler = {
208
+ get: jest.fn().mockResolvedValue({ lastModified: renderedAt, value }),
209
+ };
210
+ await cacheHandler.get("isr/3", getCtx);
211
+ const s3 = {
212
+ get: jest.fn().mockResolvedValue(null),
213
+ isRevalidated: jest.fn().mockResolvedValue(false),
214
+ };
215
+ cacheHandler.s3DynamoHandler = s3;
216
+ expect(await cacheHandler.get("isr/3", getCtx)).toEqual({
217
+ lastModified: renderedAt,
218
+ value,
219
+ });
220
+ expect(s3.isRevalidated).toHaveBeenCalledWith({ lastModified: renderedAt, value }, getCtx, "isr/3");
221
+ });
222
+ it("does not serve a memory hit another instance's revalidateTag expired", async () => {
223
+ // `revalidateTag` clears only the memory of the instance that ran it. Any
224
+ // other instance holding the page in memory answered from it for the
225
+ // whole memory TTL, and CloudFront - just invalidated - cached the stale
226
+ // page again. So a memory hit is checked against the tag markers too.
227
+ const value = {
228
+ kind: "APP_PAGE" /* CachedRouteKind.APP_PAGE */,
229
+ html: "<html>stale</html>",
230
+ rscData: undefined,
231
+ headers: { "x-next-cache-tags": "_N_T_/blog" },
232
+ postponed: undefined,
233
+ segmentData: undefined,
234
+ status: undefined,
235
+ };
236
+ const getCtx = {
237
+ kind: "APP_PAGE" /* IncrementalCacheKind.APP_PAGE */,
238
+ isFallback: false,
239
+ };
240
+ cacheHandler.s3DynamoHandler = {
241
+ get: jest.fn().mockResolvedValue({ lastModified: Date.now(), value }),
242
+ };
243
+ await cacheHandler.get("blog", getCtx);
244
+ // Another instance revalidated `_N_T_/blog`: the marker is newer than the
245
+ // memory copy, and S3 now answers with the entry expired.
246
+ const s3 = {
247
+ get: jest.fn().mockResolvedValue({ lastModified: -1, value }),
248
+ isRevalidated: jest.fn().mockResolvedValue(true),
249
+ };
250
+ cacheHandler.s3DynamoHandler = s3;
251
+ expect(await cacheHandler.get("blog", getCtx)).toEqual({
252
+ lastModified: -1,
253
+ value,
254
+ });
255
+ expect(s3.isRevalidated).toHaveBeenCalledWith(expect.objectContaining({ value }), getCtx, "blog");
256
+ expect(s3.get).toHaveBeenCalledTimes(1);
257
+ // And the memory copy is gone rather than checked again next time.
258
+ s3.get.mockResolvedValue(null);
259
+ expect(await cacheHandler.get("blog", getCtx)).toBeNull();
260
+ });
261
+ it("keeps memory entries across resetRequestCache", async () => {
262
+ // Next.js calls it at the start of every request; clearing the shared
263
+ // memory cache there sent every read to S3.
73
264
  const testData = {
74
265
  kind: "APP_PAGE" /* CachedRouteKind.APP_PAGE */,
75
266
  html: "<html>reset</html>",
@@ -86,33 +277,74 @@ describe("CdkNextjsCacheHandler - Orchestrator Pattern", () => {
86
277
  });
87
278
  // Reset
88
279
  await cacheHandler.resetRequestCache();
89
- // Verify entry is gone from memory
280
+ // Still answered from memory, without asking S3.
281
+ const s3 = {
282
+ get: jest.fn().mockResolvedValue(null),
283
+ isRevalidated: jest.fn().mockResolvedValue(false),
284
+ };
285
+ cacheHandler.s3DynamoHandler = s3;
90
286
  const result = await cacheHandler.get("reset-key", {
91
287
  kind: "APP_PAGE" /* IncrementalCacheKind.APP_PAGE */,
92
288
  isFallback: false,
93
289
  });
94
- expect(result).toBeNull();
290
+ expect(result?.value).toEqual(testData);
291
+ expect(s3.get).not.toHaveBeenCalled();
95
292
  });
96
293
  });
97
294
  describe("Build-time behavior", () => {
98
- it("should initialize local file cache handler during build", () => {
99
- // Set build-time environment
295
+ it("reads back a fetch entry it wrote, from memory and from disk", async () => {
296
+ // `cacheComponents` prerenders each page twice: the first pass runs the
297
+ // `fetch` and `set`s it, the second must find it already cached or Next.js
298
+ // fails the build with "encountered uncached or runtime data during
299
+ // prerendering". A write-only build-time handler therefore makes
300
+ // `cache: 'force-cache'` unbuildable - measured against next.js's
301
+ // `test/e2e/app-dir/resume-data-cache`.
100
302
  process.env.NEXT_PHASE = "phase-production-build";
101
- process.env.CDK_NEXTJS_BUILD_ID = "test-build-123";
102
- const mockContext = createMockContext();
103
- const buildHandler = new cache_handler_1.default(mockContext);
104
- expect(buildHandler).toBeDefined();
105
- // Clean up
106
- delete process.env.NEXT_PHASE;
107
- delete process.env.CDK_NEXTJS_BUILD_ID;
108
- });
109
- it("should initialize runtime handlers when not in build mode", () => {
110
- // Runtime environment (NEXT_PHASE not set or different value)
111
- delete process.env.NEXT_PHASE;
112
- const mockContext = createMockContext();
113
- const runtimeHandler = new cache_handler_1.default(mockContext);
114
- expect(runtimeHandler).toBeDefined();
303
+ process.env.CDK_NEXTJS_INIT_CACHE_DIR = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), "cdk-nextjs-init-cache-"));
304
+ try {
305
+ const data = {
306
+ kind: "FETCH" /* CachedRouteKind.FETCH */,
307
+ data: {
308
+ headers: {},
309
+ body: "eyJyYW5kb20iOjF9",
310
+ status: 200,
311
+ url: "https://example.test/api/random",
312
+ },
313
+ revalidate: 31536000,
314
+ };
315
+ const fetchUrl = "https://example.test/api/random";
316
+ const setCtx = {
317
+ fetchCache: true,
318
+ tags: ["test"],
319
+ fetchUrl,
320
+ fetchIdx: 1,
321
+ };
322
+ const getCtx = {
323
+ kind: "FETCH" /* IncrementalCacheKind.FETCH */,
324
+ revalidate: 31536000,
325
+ fetchUrl,
326
+ fetchIdx: 1,
327
+ tags: ["test"],
328
+ };
329
+ const buildHandler = new cache_handler_1.default(createMockContext());
330
+ await buildHandler.set("fetch-key", data, setCtx);
331
+ expect(await buildHandler.get("fetch-key", getCtx)).toMatchObject({
332
+ value: data,
333
+ });
334
+ // A second instance reads the file rather than the map: `next build`
335
+ // renders pages in worker processes, so the pass that writes and the
336
+ // pass that reads are not always the same process.
337
+ const otherWorker = new cache_handler_1.default(createMockContext());
338
+ expect(await otherWorker.get("fetch-key", getCtx)).toMatchObject({
339
+ value: data,
340
+ });
341
+ expect(await otherWorker.get("never-written", getCtx)).toBeNull();
342
+ }
343
+ finally {
344
+ delete process.env.NEXT_PHASE;
345
+ delete process.env.CDK_NEXTJS_INIT_CACHE_DIR;
346
+ }
115
347
  });
116
348
  });
117
349
  });
118
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtaGFuZGxlci50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXIvY2FjaGUtaGFuZGxlci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBT0Esb0VBQW9EO0FBRXBELHVCQUF1QjtBQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7QUFDaEMsSUFBSSxDQUFDLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO0FBRXRDLFFBQVEsQ0FBQyw4Q0FBOEMsRUFBRSxHQUFHLEVBQUU7SUFDNUQsSUFBSSxZQUFtQyxDQUFDO0lBRXhDLE1BQU0saUJBQWlCLEdBQUcsR0FBd0IsRUFBRSxDQUFDLENBQUM7UUFDcEQsR0FBRyxFQUFFLEtBQUs7UUFDVixlQUFlLEVBQUUsRUFBRTtRQUNuQixlQUFlLEVBQUUsRUFBRTtLQUNwQixDQUFDLENBQUM7SUFFSCxVQUFVLENBQUMsR0FBRyxFQUFFO1FBQ2QsdURBQXVEO1FBQ3ZELElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQyxDQUFDO1FBRXpELE1BQU0sV0FBVyxHQUFHLGlCQUFpQixFQUFFLENBQUM7UUFDeEMsWUFBWSxHQUFHLElBQUksdUJBQXFCLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDeEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxTQUFTLENBQUMsR0FBRyxFQUFFO1FBQ2IsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2QixvQkFBb0I7UUFDcEIsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLDhCQUE4QixDQUFDO1FBQ2xELHNFQUFzRTtRQUN0RSw2Q0FBNkM7UUFDNUMsdUJBQTZCLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDO1FBQ3pELHVCQUE2QixDQUFDLHFC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R0FBRyxFQUFFO1lBQ2pFLDZCQUE2QjtZQUM3QixPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsR0FBRyx3QkFBd0IsQ0FBQztZQUNsRCxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixHQUFHLGdCQUFnQixDQUFDO1lBRW5ELE1BQU0sV0FBVyxHQUFHLGlCQUFpQixFQUFFLENBQUM7WUFDeEMsTUFBTSxZQUFZLEdBQUcsSUFBSSx1QkFBcUIsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUU1RCxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7WUFFbkMsV0FBVztZQUNYLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUM7WUFDOUIsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDO1FBQ3pDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDJEQUEyRCxFQUFFLEdBQUcsRUFBRTtZQUNuRSw4REFBOEQ7WUFDOUQsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQztZQUU5QixNQUFNLFdBQVcsR0FBRyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3hDLE1BQU0sY0FBYyxHQUFHLElBQUksdUJBQXFCLENBQUMsV0FBVyxDQUFDLENBQUM7WUFFOUQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3ZDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IHsgQ2FjaGVIYW5kbGVyQ29udGV4dCB9IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL2xpYi9pbmNyZW1lbnRhbC1jYWNoZVwiO1xuaW1wb3J0IHtcbiAgSW5jcmVtZW50YWxDYWNoZVZhbHVlLFxuICBDYWNoZWRSb3V0ZUtpbmQsXG4gIEluY3JlbWVudGFsQ2FjaGVLaW5kLFxufSBmcm9tIFwibmV4dC9kaXN0L3NlcnZlci9yZXNwb25zZS1jYWNoZVwiO1xuaW1wb3J0IENka05leHRqc0NhY2hlSGFuZGxlciBmcm9tIFwiLi9jYWNoZS1oYW5kbGVyXCI7XG5cbi8vIE1vY2sgQVdTIFNESyBjbGllbnRzXG5qZXN0Lm1vY2soXCJAYXdzLXNkay9jbGllbnQtczNcIik7XG5qZXN0Lm1vY2soXCJAYXdzLXNkay9jbGllbnQtZHluYW1vZGJcIik7XG5cbmRlc2NyaWJlKFwiQ2RrTmV4dGpzQ2FjaGVIYW5kbGVyIC0gT3JjaGVzdHJhdG9yIFBhdHRlcm5cIiwgKCkgPT4ge1xuICBsZXQgY2FjaGVIYW5kbGVyOiBDZGtOZXh0anNDYWNoZUhhbmRsZXI7XG5cbiAgY29uc3QgY3JlYXRlTW9ja0NvbnRleHQgPSAoKTogQ2FjaGVIYW5kbGVyQ29udGV4dCA9PiAoe1xuICAgIGRldjogZmFsc2UsXG4gICAgcmV2YWxpZGF0ZWRUYWdzOiBbXSxcbiAgICBfcmVxdWVzdEhlYWRlcnM6IHt9LFxuICB9KTtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAvLyBTdXBwcmVzcyBleHBlY3RlZCB3YXJuaW5ncyB3aGVuIGVudiB2YXJzIGFyZSBub3Qgc2V0XG4gICAgamVzdC5zcHlPbihjb25zb2xlLCBcIndhcm5cIikubW9ja0ltcGxlbWVudGF0aW9uKCgpID0+IHt9KTtcblxuICAgIGNvbnN0IG1vY2tDb250ZXh0ID0gY3JlYXRlTW9ja0NvbnRleHQoKTtcbiAgICBjYWNoZUhhbmRsZXIgPSBuZXcgQ2RrTmV4dGpzQ2FjaGVIYW5kbGVyKG1vY2tDb250ZXh0KTtcbiAgfSk7XG5cbiAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICBqZXN0LmNsZWFyQWxsTW9ja3MoKTtcbiAgICBqZXN0LnJlc3RvcmVBbGxNb2NrcygpO1xuICAgIC8vIENsZWFuIHVwIGVudiB2YXJzXG4gICAgZGVsZXRlIHByb2Nlc3MuZW52LkNES19ORVhUSlNfTUVNT1JZX0NBQ0hFX1RUTF9NUztcbiAgICAvLyBSZXNldCBzaW5nbGV0b24gaGFuZGxlcnMgYnkgYWNjZXNzaW5nIHRoZSBjbGFzcydzIHN0YXRpYyBwcm9wZXJ0aWVzXG4gICAgLy8gVGhpcyBlbnN1cmVzIGVhY2ggdGVzdCBnZXRzIGZyZXNoIGhhbmRsZXJzXG4gICAgKENka05leHRqc0NhY2hlSGFuZGxlciBhcyBhbnkpLnNoYXJlZE1lbW9yeUhhbmRsZXIgPSBudWxsO1xuICAgIChDZGtOZXh0anNDYWNoZUhhbmRsZXIgYXMgYW55KS5zaGFyZWRTM0R5bmFtb0hhbmRsZXIgPSBudWxsO1xuICB9KTtcblxuICBkZXNjcmliZShcIk9yY2hlc3RyYXRvciBQYXR0ZXJuICYgSW5pdGlhbGl6YXRpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGluaXRpYWxpemUgYXMgb3JjaGVzdHJhdG9yIHdpdGggcnVudGltZSBoYW5kbGVyc1wiLCAoKSA9PiB7XG4gICAgICBleHBlY3QoY2FjaGVIYW5kbGVyKS50b0JlRGVmaW5lZCgpO1xuICAgICAgLy8gUnVudGltZSBtb2RlIC0gbWVtb3J5IGFuZCBTMy9EeW5hbW9EQiBoYW5kbGVycyBzaG91bGQgYmUgYXZhaWxhYmxlXG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiT3JjaGVzdHJhdG9yOiBNZW1vcnkgKyBTMy9EeW5hbW9EQlwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgd3JpdGUgdG8gYm90aCBtZW1vcnkgYW5kIFMzL0R5bmFtb0RCIG9uIHNldFwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0RGF0YTogSW5jcmVtZW50YWxDYWNoZVZhbHVlID0ge1xuICAgICAgICBraW5kOiBDYWNoZWRSb3V0ZUtpbmQuQVBQX1BBR0UsXG4gICAgICAgIGh0bWw6IFwiPGh0bWw+dGVzdDwvaHRtbD5cIixcbiAgICAgICAgcnNjRGF0YTogdW5kZWZpbmVkLFxuICAgICAgICBoZWFkZXJzOiB1bmRlZmluZWQsXG4gICAgICAgIHBvc3Rwb25lZDogdW5kZWZpbmVkLFxuICAgICAgICBzZWdtZW50RGF0YTogdW5kZWZpbmVkLFxuICAgICAgICBzdGF0dXM6IHVuZGVmaW5lZCxcbiAgICAgIH07XG5cbiAgICAgIC8vIFNldCBjYWNoZSBlbnRyeVxuICAgICAgYXdhaXQgY2FjaGVIYW5kbGVyLnNldChcInRlc3Qta2V5XCIsIHRlc3REYXRhLCB7XG4gICAgICAgIGZldGNoQ2FjaGU6IHRydWUgYXMgY29uc3QsXG4gICAgICAgIHRhZ3M6IFtdLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIEdldCBzaG91bGQgcmV0dXJuIGZyb20gbWVtb3J5XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjYWNoZUhhbmRsZXIuZ2V0KFwidGVzdC1rZXlcIiwge1xuICAgICAgICBraW5kOiBJbmNyZW1lbnRhbENhY2hlS2luZC5BUFBfUEFHRSxcbiAgICAgICAgaXNGYWxsYmFjazogZmFsc2UsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHJlc3VsdCkubm90LnRvQmVOdWxsKCk7XG4gICAgICBleHBlY3QocmVzdWx0Py52YWx1ZSkudG9FcXVhbCh0ZXN0RGF0YSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYW5kbGUgY2FjaGUgbWlzc2VzIGdyYWNlZnVsbHlcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gR2V0IG5vbi1leGlzdGVudCBrZXlcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNhY2hlSGFuZGxlci5nZXQoXCJtaXNzaW5nLWtleVwiLCB7XG4gICAgICAgIGtpbmQ6IEluY3JlbWVudGFsQ2FjaGVLaW5kLkFQUF9QQUdFLFxuICAgICAgICBpc0ZhbGxiYWNrOiBmYWxzZSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBTaG91bGQgcmV0dXJuIG51bGwgKGJvdGggbWVtb3J5IGFuZCBTMyBtaXNzKVxuICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZU51bGwoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHByb3BhZ2F0ZSByZXNldFJlcXVlc3RDYWNoZSB0byBtZW1vcnkgbGF5ZXJcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdERhdGE6IEluY3JlbWVudGFsQ2FjaGVWYWx1ZSA9IHtcbiAgICAgICAga2luZDogQ2FjaGVkUm91dGVLaW5kLkFQUF9QQUdFLFxuICAgICAgICBodG1sOiBcIjxodG1sPnJlc2V0PC9odG1sPlwiLFxuICAgICAgICByc2NEYXRhOiB1bmRlZmluZWQsXG4gICAgICAgIGhlYWRlcnM6IHVuZGVmaW5lZCxcbiAgICAgICAgcG9zdHBvbmVkOiB1bmRlZmluZWQsXG4gICAgICAgIHNlZ21lbnREYXRhOiB1bmRlZmluZWQsXG4gICAgICAgIHN0YXR1czogdW5kZWZpbmVkLFxuICAgICAgfTtcblxuICAgICAgLy8gQWRkIGVudHJ5XG4gICAgICBhd2FpdCBjYWNoZUhhbmRsZXIuc2V0KFwicmVzZXQta2V5XCIsIHRlc3REYXRhLCB7XG4gICAgICAgIGZldGNoQ2FjaGU6IHRydWUgYXMgY29uc3QsXG4gICAgICAgIHRhZ3M6IFtcInJlc2V0LXRhZ1wiXSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBSZXNldFxuICAgICAgYXdhaXQgY2FjaGVIYW5kbGVyLnJlc2V0UmVxdWVzdENhY2hlKCk7XG5cbiAgICAgIC8vIFZlcmlmeSBlbnRyeSBpcyBnb25lIGZyb20gbWVtb3J5XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjYWNoZUhhbmRsZXIuZ2V0KFwicmVzZXQta2V5XCIsIHtcbiAgICAgICAga2luZDogSW5jcmVtZW50YWxDYWNoZUtpbmQuQVBQX1BBR0UsXG4gICAgICAgIGlzRmFsbGJhY2s6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgICBleHBlY3QocmVzdWx0KS50b0JlTnVsbCgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkJ1aWxkLXRpbWUgYmVoYXZpb3JcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGluaXRpYWxpemUgbG9jYWwgZmlsZSBjYWNoZSBoYW5kbGVyIGR1cmluZyBidWlsZFwiLCAoKSA9PiB7XG4gICAgICAvLyBTZXQgYnVpbGQtdGltZSBlbnZpcm9ubWVudFxuICAgICAgcHJvY2Vzcy5lbnYuTkVYVF9QSEFTRSA9IFwicGhhc2UtcHJvZHVjdGlvbi1idWlsZFwiO1xuICAgICAgcHJvY2Vzcy5lbnYuQ0RLX05FWFRKU19CVUlMRF9JRCA9IFwidGVzdC1idWlsZC0xMjNcIjtcblxuICAgICAgY29uc3QgbW9ja0NvbnRleHQgPSBjcmVhdGVNb2NrQ29udGV4dCgpO1xuICAgICAgY29uc3QgYnVpbGRIYW5kbGVyID0gbmV3IENka05leHRqc0NhY2hlSGFuZGxlcihtb2NrQ29udGV4dCk7XG5cbiAgICAgIGV4cGVjdChidWlsZEhhbmRsZXIpLnRvQmVEZWZpbmVkKCk7XG5cbiAgICAgIC8vIENsZWFuIHVwXG4gICAgICBkZWxldGUgcHJvY2Vzcy5lbnYuTkVYVF9QSEFTRTtcbiAgICAgIGRlbGV0ZSBwcm9jZXNzLmVudi5DREtfTkVYVEpTX0JVSUxEX0lEO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaW5pdGlhbGl6ZSBydW50aW1lIGhhbmRsZXJzIHdoZW4gbm90IGluIGJ1aWxkIG1vZGVcIiwgKCkgPT4ge1xuICAgICAgLy8gUnVudGltZSBlbnZpcm9ubWVudCAoTkVYVF9QSEFTRSBub3Qgc2V0IG9yIGRpZmZlcmVudCB2YWx1ZSlcbiAgICAgIGRlbGV0ZSBwcm9jZXNzLmVudi5ORVhUX1BIQVNFO1xuXG4gICAgICBjb25zdCBtb2NrQ29udGV4dCA9IGNyZWF0ZU1vY2tDb250ZXh0KCk7XG4gICAgICBjb25zdCBydW50aW1lSGFuZGxlciA9IG5ldyBDZGtOZXh0anNDYWNoZUhhbmRsZXIobW9ja0NvbnRleHQpO1xuXG4gICAgICBleHBlY3QocnVudGltZUhhbmRsZXIpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
350
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtaGFuZGxlci50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXIvY2FjaGUtaGFuZGxlci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsc0RBQXNEO0FBQ3RELDJCQUFpQztBQUNqQywyQkFBNEI7QUFDNUIsK0JBQTRCO0FBUTVCLG9FQUFvRDtBQUVwRCx1QkFBdUI7QUFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBQ2hDLElBQUksQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsQ0FBQztBQUV0QyxRQUFRLENBQUMsOENBQThDLEVBQUUsR0FBRyxFQUFFO0lBQzVELElBQUksWUFBbUMsQ0FBQztJQUV4QyxNQUFNLGlCQUFpQixHQUFHLEdBQXdCLEVBQUUsQ0FBQyxDQUFDO1FBQ3BELEdBQUcsRUFBRSxLQUFLO1FBQ1YsZUFBZSxFQUFFLEVBQUU7UUFDbkIsZUFBZSxFQUFFLEVBQUU7S0FDcEIsQ0FBQyxDQUFDO0lBRUgsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLHVEQUF1RDtRQUN2RCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsR0FBRSxDQUFDLENBQUMsQ0FBQztRQUV6RCxNQUFNLFdBQVcsR0FBRyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3hDLFlBQVksR0FBRyxJQUFJLHVCQUFxQixDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3hELENBQUMsQ0FBQyxDQUFDO0lBRUgsU0FBUyxDQUFDLEdBQUcsRUFBRTtRQUNiLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsb0JBQW9CO1FBQ3BCLE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyw4QkFBOEIsQ0FBQztRQUNsRCxzRUFBc0U7UUFDdEUsNkNBQTZDO1FBQzVDLHVC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RSxDQUFDO1lBQ3BFLENBQUM7b0JBQVMsQ0FBQztnQkFDVCxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDO2dCQUM5QixPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCLENBQUM7WUFDL0MsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IHsgbWtkdGVtcFN5bmMgfSBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gXCJvc1wiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBDYWNoZUhhbmRsZXJDb250ZXh0IH0gZnJvbSBcIm5leHQvZGlzdC9zZXJ2ZXIvbGliL2luY3JlbWVudGFsLWNhY2hlXCI7XG5pbXBvcnQge1xuICBJbmNyZW1lbnRhbENhY2hlVmFsdWUsXG4gIENhY2hlZFJvdXRlS2luZCxcbiAgSW5jcmVtZW50YWxDYWNoZUtpbmQsXG59IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL3Jlc3BvbnNlLWNhY2hlXCI7XG5pbXBvcnQgdHlwZSB7IEdldEluY3JlbWVudGFsRmV0Y2hDYWNoZUNvbnRleHQgfSBmcm9tIFwibmV4dC9kaXN0L3NlcnZlci9yZXNwb25zZS1jYWNoZVwiO1xuaW1wb3J0IENka05leHRqc0NhY2hlSGFuZGxlciBmcm9tIFwiLi9jYWNoZS1oYW5kbGVyXCI7XG5cbi8vIE1vY2sgQVdTIFNESyBjbGllbnRzXG5qZXN0Lm1vY2soXCJAYXdzLXNkay9jbGllbnQtczNcIik7XG5qZXN0Lm1vY2soXCJAYXdzLXNkay9jbGllbnQtZHluYW1vZGJcIik7XG5cbmRlc2NyaWJlKFwiQ2RrTmV4dGpzQ2FjaGVIYW5kbGVyIC0gT3JjaGVzdHJhdG9yIFBhdHRlcm5cIiwgKCkgPT4ge1xuICBsZXQgY2FjaGVIYW5kbGVyOiBDZGtOZXh0anNDYWNoZUhhbmRsZXI7XG5cbiAgY29uc3QgY3JlYXRlTW9ja0NvbnRleHQgPSAoKTogQ2FjaGVIYW5kbGVyQ29udGV4dCA9PiAoe1xuICAgIGRldjogZmFsc2UsXG4gICAgcmV2YWxpZGF0ZWRUYWdzOiBbXSxcbiAgICBfcmVxdWVzdEhlYWRlcnM6IHt9LFxuICB9KTtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAvLyBTdXBwcmVzcyBleHBlY3RlZCB3YXJuaW5ncyB3aGVuIGVudiB2YXJzIGFyZSBub3Qgc2V0XG4gICAgamVzdC5zcHlPbihjb25zb2xlLCBcIndhcm5cIikubW9ja0ltcGxlbWVudGF0aW9uKCgpID0+IHt9KTtcblxuICAgIGNvbnN0IG1vY2tDb250ZXh0ID0gY3JlYXRlTW9ja0NvbnRleHQoKTtcbiAgICBjYWNoZUhhbmRsZXIgPSBuZXcgQ2RrTmV4dGpzQ2FjaGVIYW5kbGVyKG1vY2tDb250ZXh0KTtcbiAgfSk7XG5cbiAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICBqZXN0LmNsZWFyQWxsTW9ja3MoKTtcbiAgICBqZXN0LnJlc3RvcmVBbGxNb2NrcygpO1xuICAgIC8vIENsZWFuIHVwIGVudiB2YXJzXG4gICAgZGVsZXRlIHByb2Nlc3MuZW52LkNES19ORVhUSlNfTUVNT1JZX0NBQ0hFX1RUTF9NUztcbiAgICAvLyBSZXNldCBzaW5nbGV0b24gaGFuZGxlcnMgYnkgYWNjZXNzaW5nIHRoZSBjbGFzcydzIHN0YXRpYyBwcm9wZXJ0aWVzXG4gICAgLy8gVGhpcyBlbnN1cmVzIGVhY2ggdGVzdCBnZXRzIGZyZXNoIGhhbmRsZXJzXG4gICAgKENka05leHRqc0NhY2hlSGFuZGxlciBhcyBhbnkpLnNoYXJlZE1lbW9yeUhhbmRsZXIgPSBudWxsO1xuICAgIChDZGtOZXh0anNDYWNoZUhhbmRsZXIgYXMgYW55KS5zaGFyZWRTM0R5bmFtb0hhbmRsZXIgPSBudWxsO1xuICB9KTtcblxuICBkZXNjcmliZShcIk9yY2hlc3RyYXRvcjogTWVtb3J5ICsgUzMvRHluYW1vREJcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHdyaXRlIHRvIGJvdGggbWVtb3J5IGFuZCBTMy9EeW5hbW9EQiBvbiBzZXRcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdERhdGE6IEluY3JlbWVudGFsQ2FjaGVWYWx1ZSA9IHtcbiAgICAgICAga2luZDogQ2FjaGVkUm91dGVLaW5kLkFQUF9QQUdFLFxuICAgICAgICBodG1sOiBcIjxodG1sPnRlc3Q8L2h0bWw+XCIsXG4gICAgICAgIHJzY0RhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgaGVhZGVyczogdW5kZWZpbmVkLFxuICAgICAgICBwb3N0cG9uZWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgc2VnbWVudERhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgc3RhdHVzOiB1bmRlZmluZWQsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzMyA9IHtcbiAgICAgICAgc2V0OiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUodW5kZWZpbmVkKSxcbiAgICAgICAgZ2V0OiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUobnVsbCksXG4gICAgICAgIGlzUmV2YWxpZGF0ZWQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZShmYWxzZSksXG4gICAgICB9O1xuICAgICAgKGNhY2hlSGFuZGxlciBhcyBhbnkpLnMzRHluYW1vSGFuZGxlciA9IHMzO1xuICAgICAgY29uc3Qgc2V0Q3R4ID0geyBmZXRjaENhY2hlOiB0cnVlIGFzIGNvbnN0LCB0YWdzOiBbXSB9O1xuXG4gICAgICAvLyBTZXQgY2FjaGUgZW50cnlcbiAgICAgIGF3YWl0IGNhY2hlSGFuZGxlci5zZXQoXCJ0ZXN0LWtleVwiLCB0ZXN0RGF0YSwgc2V0Q3R4KTtcblxuICAgICAgLy8gUzMvRHluYW1vREIgZ290IHRoZSB3cml0ZSwgd2l0aCB0aGUgY29udGV4dCBpdCBuZWVkcyBmb3IgdGFncy5cbiAgICAgIGV4cGVjdChzMy5zZXQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFwidGVzdC1rZXlcIiwgdGVzdERhdGEsIHNldEN0eCk7XG5cbiAgICAgIC8vIEdldCBzaG91bGQgcmV0dXJuIGZyb20gbWVtb3J5LCB3aXRob3V0IGFza2luZyBTMy5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNhY2hlSGFuZGxlci5nZXQoXCJ0ZXN0LWtleVwiLCB7XG4gICAgICAgIGtpbmQ6IEluY3JlbWVudGFsQ2FjaGVLaW5kLkFQUF9QQUdFLFxuICAgICAgICBpc0ZhbGxiYWNrOiBmYWxzZSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QocmVzdWx0KS5ub3QudG9CZU51bGwoKTtcbiAgICAgIGV4cGVjdChyZXN1bHQ/LnZhbHVlKS50b0VxdWFsKHRlc3REYXRhKTtcbiAgICAgIGV4cGVjdChzMy5nZXQpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgfSk7XG5cbiAgICBpdChcImRlbGV0ZXMgZnJvbSBib3RoIGxheWVycyBvbiBzZXQoa2V5LCBudWxsKVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0RGF0YTogSW5jcmVtZW50YWxDYWNoZVZhbHVlID0ge1xuICAgICAgICBraW5kOiBDYWNoZWRSb3V0ZUtpbmQuQVBQX1BBR0UsXG4gICAgICAgIGh0bWw6IFwiPGh0bWw+Z29uZTwvaHRtbD5cIixcbiAgICAgICAgcnNjRGF0YTogdW5kZWZpbmVkLFxuICAgICAgICBoZWFkZXJzOiB1bmRlZmluZWQsXG4gICAgICAgIHBvc3Rwb25lZDogdW5kZWZpbmVkLFxuICAgICAgICBzZWdtZW50RGF0YTogdW5kZWZpbmVkLFxuICAgICAgICBzdGF0dXM6IHVuZGVmaW5lZCxcbiAgICAgIH07XG4gICAgICBjb25zdCBzMyA9IHtcbiAgICAgICAgc2V0OiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUodW5kZWZpbmVkKSxcbiAgICAgICAgZ2V0OiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUobnVsbCksXG4gICAgICAgIGlzUmV2YWxpZGF0ZWQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZShmYWxzZSksXG4gICAgICB9O1xuICAgICAgKGNhY2hlSGFuZGxlciBhcyBhbnkpLnMzRHluYW1vSGFuZGxlciA9IHMzO1xuICAgICAgY29uc3Qgc2V0Q3R4ID0geyBmZXRjaENhY2hlOiB0cnVlIGFzIGNvbnN0LCB0YWdzOiBbXSB9O1xuICAgICAgYXdhaXQgY2FjaGVIYW5kbGVyLnNldChcImdvbmUta2V5XCIsIHRlc3REYXRhLCBzZXRDdHgpO1xuXG4gICAgICBhd2FpdCBjYWNoZUhhbmRsZXIuc2V0KFwiZ29uZS1rZXlcIiwgbnVsbCwgc2V0Q3R4KTtcblxuICAgICAgLy8gVGhlIFMzIGxheWVyIGlzIHRvbGQgdG8gZGVsZXRlLCBub3Qgc2tpcHBlZC5cbiAgICAgIGV4cGVjdChzMy5zZXQpLnRvSGF2ZUJlZW5MYXN0Q2FsbGVkV2l0aChcImdvbmUta2V5XCIsIG51bGwsIHNldEN0eCk7XG4gICAgICAvLyBBbmQgbWVtb3J5IG5vIGxvbmdlciBhbnN3ZXJzOiB0aGUgcmVhZCBmYWxscyB0aHJvdWdoIHRvIFMzLlxuICAgICAgZXhwZWN0KFxuICAgICAgICBhd2FpdCBjYWNoZUhhbmRsZXIuZ2V0KFwiZ29uZS1rZXlcIiwge1xuICAgICAgICAgIGtpbmQ6IEluY3JlbWVudGFsQ2FjaGVLaW5kLkFQUF9QQUdFLFxuICAgICAgICAgIGlzRmFsbGJhY2s6IGZhbHNlLFxuICAgICAgICB9KSxcbiAgICAgICkudG9CZU51bGwoKTtcbiAgICAgIGV4cGVjdChzMy5nZXQpLnRvSGF2ZUJlZW5DYWxsZWRUaW1lcygxKTtcbiAgICB9KTtcblxuICAgIGl0KFwicmV2YWxpZGF0ZXMgYSB0YWcgaW4gUzMvRHluYW1vREIsIHBhc3NpbmcgdGhlIGR1cmF0aW9ucyB0aHJvdWdoXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3REYXRhOiBJbmNyZW1lbnRhbENhY2hlVmFsdWUgPSB7XG4gICAgICAgIGtpbmQ6IENhY2hlZFJvdXRlS2luZC5BUFBfUEFHRSxcbiAgICAgICAgaHRtbDogXCI8aHRtbD50YWdnZWQ8L2h0bWw+XCIsXG4gICAgICAgIHJzY0RhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgaGVhZGVyczogeyBcIngtbmV4dC1jYWNoZS10YWdzXCI6IFwicG9zdHNcIiB9LFxuICAgICAgICBwb3N0cG9uZWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgc2VnbWVudERhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgc3RhdHVzOiB1bmRlZmluZWQsXG4gICAgICB9O1xuICAgICAgY29uc3QgczMgPSB7XG4gICAgICAgIHNldDogamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKHVuZGVmaW5lZCksXG4gICAgICAgIGdldDogamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKG51bGwpLFxuICAgICAgICBpc1JldmFsaWRhdGVkOiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUoZmFsc2UpLFxuICAgICAgICByZXZhbGlkYXRlVGFnOiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUodW5kZWZpbmVkKSxcbiAgICAgIH07XG4gICAgICAoY2FjaGVIYW5kbGVyIGFzIGFueSkuczNEeW5hbW9IYW5kbGVyID0gczM7XG5cbiAgICAgIGF3YWl0IGNhY2hlSGFuZGxlci5zZXQoXCJ0YWdnZWQta2V5XCIsIHRlc3REYXRhLCB7XG4gICAgICAgIGZldGNoQ2FjaGU6IHRydWUgYXMgY29uc3QsXG4gICAgICAgIHRhZ3M6IFtcInBvc3RzXCJdLFxuICAgICAgfSk7XG4gICAgICAvLyBgcmV2YWxpZGF0ZVRhZyh0YWcsIHByb2ZpbGUpYDogdGhlIGR1cmF0aW9ucyBkZWNpZGUgc3RhbGUgdnMgZXhwaXJlZCxcbiAgICAgIC8vIHNvIGRyb3BwaW5nIHRoZW0gdHVybnMgZXZlcnkgc29mdCByZXZhbGlkYXRpb24gaW50byBhIGhhcmQgb25lLlxuICAgICAgYXdhaXQgY2FjaGVIYW5kbGVyLnJldmFsaWRhdGVUYWcoW1wicG9zdHNcIl0sIHsgZXhwaXJlOiA2MCB9KTtcblxuICAgICAgZXhwZWN0KHMzLnJldmFsaWRhdGVUYWcpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFtcInBvc3RzXCJdLCB7IGV4cGlyZTogNjAgfSk7XG5cbiAgICAgIGF3YWl0IGNhY2hlSGFuZGxlci5yZXZhbGlkYXRlVGFnKFwicG9zdHNcIik7XG4gICAgICBleHBlY3QoczMucmV2YWxpZGF0ZVRhZykudG9IYXZlQmVlbkxhc3RDYWxsZWRXaXRoKFwicG9zdHNcIiwgdW5kZWZpbmVkKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhbmRsZSBjYWNoZSBtaXNzZXMgZ3JhY2VmdWxseVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBHZXQgbm9uLWV4aXN0ZW50IGtleVxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY2FjaGVIYW5kbGVyLmdldChcIm1pc3Npbmcta2V5XCIsIHtcbiAgICAgICAga2luZDogSW5jcmVtZW50YWxDYWNoZUtpbmQuQVBQX1BBR0UsXG4gICAgICAgIGlzRmFsbGJhY2s6IGZhbHNlLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFNob3VsZCByZXR1cm4gbnVsbCAoYm90aCBtZW1vcnkgYW5kIFMzIG1pc3MpXG4gICAgICBleHBlY3QocmVzdWx0KS50b0JlTnVsbCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJkb2VzIG5vdCBjb3B5IGEgdGFnLWV4cGlyZWQgUzMgZW50cnkgaW50byBtZW1vcnlcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gYGxhc3RNb2RpZmllZDogLTFgIGlzIHRoZSBTMyBsYXllciBzYXlpbmcgXCJhIHRhZyByZXZhbGlkYXRpb24gZXhwaXJlZFxuICAgICAgLy8gdGhpcywgcmUtcmVuZGVyIGJlZm9yZSBhbnN3ZXJpbmdcIi4gQ29waWVkIGludG8gbWVtb3J5LCB0aGUgZXhwaXJlZCBib2R5XG4gICAgICAvLyB3b3VsZCBiZSBhbnN3ZXJlZCBmcm9tIHRoZXJlIGluc3RlYWQgb2YgZnJvbSB0aGUgcmUtcmVuZGVyLlxuICAgICAgY29uc3QgdmFsdWU6IEluY3JlbWVudGFsQ2FjaGVWYWx1ZSA9IHtcbiAgICAgICAga2luZDogQ2FjaGVkUm91dGVLaW5kLkFQUF9QQUdFLFxuICAgICAgICBodG1sOiBcIjxodG1sPmV4cGlyZWQ8L2h0bWw+XCIsXG4gICAgICAgIHJzY0RhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgaGVhZGVyczogdW5kZWZpbmVkLFxuICAgICAgICBwb3N0cG9uZWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgc2VnbWVudERhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgc3RhdHVzOiB1bmRlZmluZWQsXG4gICAgICB9O1xuICAgICAgY29uc3QgZ2V0Q3R4ID0ge1xuICAgICAgICBraW5kOiBJbmNyZW1lbnRhbENhY2hlS2luZC5BUFBfUEFHRSxcbiAgICAgICAgaXNGYWxsYmFjazogZmFsc2UsXG4gICAgICB9IGFzIGNvbnN0O1xuXG4gICAgICAoY2FjaGVIYW5kbGVyIGFzIGFueSkuczNEeW5hbW9IYW5kbGVyID0ge1xuICAgICAgICBnZXQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7IGxhc3RNb2RpZmllZDogLTEsIHZhbHVlIH0pLFxuICAgICAgfTtcbiAgICAgIGV4cGVjdChhd2FpdCBjYWNoZUhhbmRsZXIuZ2V0KFwiaXNyLzFcIiwgZ2V0Q3R4KSkudG9FcXVhbCh7XG4gICAgICAgIGxhc3RNb2RpZmllZDogLTEsXG4gICAgICAgIHZhbHVlLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFdpdGggdGhlIFMzIGxheWVyIG5vdyBzaWxlbnQsIGEgbWVtb3J5IGNvcHkgd291bGQgYW5zd2VyIHRoaXMgYXMgYSBoaXQuXG4gICAgICAoY2FjaGVIYW5kbGVyIGFzIGFueSkuczNEeW5hbW9IYW5kbGVyID0ge1xuICAgICAgICBnZXQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZShudWxsKSxcbiAgICAgIH07XG4gICAgICBleHBlY3QoYXdhaXQgY2FjaGVIYW5kbGVyLmdldChcImlzci8xXCIsIGdldEN0eCkpLnRvQmVOdWxsKCk7XG4gICAgfSk7XG5cbiAgICBpdChcImNvcGllcyBhIGxpdmUgUzMgZW50cnkgaW50byBtZW1vcnlcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsdWU6IEluY3JlbWVudGFsQ2FjaGVWYWx1ZSA9IHtcbiAgICAgICAga2luZDogQ2FjaGVkUm91dGVLaW5kLkFQUF9QQUdFLFxuICAgICAgICBodG1sOiBcIjxodG1sPmxpdmU8L2h0bWw+XCIsXG4gICAgICAgIHJzY0RhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgaGVhZGVyczogdW5kZWZpbmVkLFxuICAgICAgICBwb3N0cG9uZWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgc2VnbWVudERhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgc3RhdHVzOiB1bmRlZmluZWQsXG4gICAgICB9O1xuICAgICAgY29uc3QgZ2V0Q3R4ID0ge1xuICAgICAgICBraW5kOiBJbmNyZW1lbnRhbENhY2hlS2luZC5BUFBfUEFHRSxcbiAgICAgICAgaXNGYWxsYmFjazogZmFsc2UsXG4gICAgICB9IGFzIGNvbnN0O1xuXG4gICAgICAoY2FjaGVIYW5kbGVyIGFzIGFueSkuczNEeW5hbW9IYW5kbGVyID0ge1xuICAgICAgICBnZXQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7IGxhc3RNb2RpZmllZDogRGF0ZS5ub3coKSwgdmFsdWUgfSksXG4gICAgICB9O1xuICAgICAgYXdhaXQgY2FjaGVIYW5kbGVyLmdldChcImlzci8yXCIsIGdldEN0eCk7XG5cbiAgICAgIGNvbnN0IHMzID0ge1xuICAgICAgICBnZXQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZShudWxsKSxcbiAgICAgICAgaXNSZXZhbGlkYXRlZDogamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKGZhbHNlKSxcbiAgICAgIH07XG4gICAgICAoY2FjaGVIYW5kbGVyIGFzIGFueSkuczNEeW5hbW9IYW5kbGVyID0gczM7XG4gICAgICBleHBlY3QoYXdhaXQgY2FjaGVIYW5kbGVyLmdldChcImlzci8yXCIsIGdldEN0eCkpLnRvTWF0Y2hPYmplY3QoeyB2YWx1ZSB9KTtcbiAgICAgIGV4cGVjdChzMy5nZXQpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgfSk7XG5cbiAgICBpdChcImtlZXBzIHRoZSBTMyBlbnRyeSdzIGxhc3RNb2RpZmllZCB3aGVuIGNvcHlpbmcgaXQgaW50byBtZW1vcnlcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gTmV4dC5qcyBhZ2VzIHRoZSBlbnRyeSBmcm9tIGBsYXN0TW9kaWZpZWRgLCBhbmQgdGhlIHRhZyBtYXJrZXJzIGFyZVxuICAgICAgLy8gY29tcGFyZWQgYWdhaW5zdCBpdC4gU3RhbXBpbmcgdGhlIHRpbWUgb2YgdGhlIGNvcHkgbWFkZSBhIHBhZ2UgYSBzb2Z0XG4gICAgICAvLyBgcmV2YWxpZGF0ZVRhZ2AgaGFkIG1hZGUgc3RhbGUgbG9vayBuZXdlciB0aGFuIHRoZSBzdGFsZSBtYXJrLlxuICAgICAgY29uc3QgdmFsdWU6IEluY3JlbWVudGFsQ2FjaGVWYWx1ZSA9IHtcbiAgICAgICAga2luZDogQ2FjaGVkUm91dGVLaW5kLkFQUF9QQUdFLFxuICAgICAgICBodG1sOiBcIjxodG1sPm9sZDwvaHRtbD5cIixcbiAgICAgICAgcnNjRGF0YTogdW5kZWZpbmVkLFxuICAgICAgICBoZWFkZXJzOiB1bmRlZmluZWQsXG4gICAgICAgIHBvc3Rwb25lZDogdW5kZWZpbmVkLFxuICAgICAgICBzZWdtZW50RGF0YTogdW5kZWZpbmVkLFxuICAgICAgICBzdGF0dXM6IHVuZGVmaW5lZCxcbiAgICAgIH07XG4gICAgICBjb25zdCBnZXRDdHggPSB7XG4gICAgICAgIGtpbmQ6IEluY3JlbWVudGFsQ2FjaGVLaW5kLkFQUF9QQUdFLFxuICAgICAgICBpc0ZhbGxiYWNrOiBmYWxzZSxcbiAgICAgIH0gYXMgY29uc3Q7XG4gICAgICBjb25zdCByZW5kZXJlZEF0ID0gRGF0ZS5ub3coKSAtIDYwXzAwMDtcblxuICAgICAgKGNhY2hlSGFuZGxlciBhcyBhbnkpLnMzRHluYW1vSGFuZGxlciA9IHtcbiAgICAgICAgZ2V0OiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUoeyBsYXN0TW9kaWZpZWQ6IHJlbmRlcmVkQXQsIHZhbHVlIH0pLFxuICAgICAgfTtcbiAgICAgIGF3YWl0IGNhY2hlSGFuZGxlci5nZXQoXCJpc3IvM1wiLCBnZXRDdHgpO1xuXG4gICAgICBjb25zdCBzMyA9IHtcbiAgICAgICAgZ2V0OiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUobnVsbCksXG4gICAgICAgIGlzUmV2YWxpZGF0ZWQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZShmYWxzZSksXG4gICAgICB9O1xuICAgICAgKGNhY2hlSGFuZGxlciBhcyBhbnkpLnMzRHluYW1vSGFuZGxlciA9IHMzO1xuICAgICAgZXhwZWN0KGF3YWl0IGNhY2hlSGFuZGxlci5nZXQoXCJpc3IvM1wiLCBnZXRDdHgpKS50b0VxdWFsKHtcbiAgICAgICAgbGFzdE1vZGlmaWVkOiByZW5kZXJlZEF0LFxuICAgICAgICB2YWx1ZSxcbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KHMzLmlzUmV2YWxpZGF0ZWQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgICB7IGxhc3RNb2RpZmllZDogcmVuZGVyZWRBdCwgdmFsdWUgfSxcbiAgICAgICAgZ2V0Q3R4LFxuICAgICAgICBcImlzci8zXCIsXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoXCJkb2VzIG5vdCBzZXJ2ZSBhIG1lbW9yeSBoaXQgYW5vdGhlciBpbnN0YW5jZSdzIHJldmFsaWRhdGVUYWcgZXhwaXJlZFwiLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBgcmV2YWxpZGF0ZVRhZ2AgY2xlYXJzIG9ubHkgdGhlIG1lbW9yeSBvZiB0aGUgaW5zdGFuY2UgdGhhdCByYW4gaXQuIEFueVxuICAgICAgLy8gb3RoZXIgaW5zdGFuY2UgaG9sZGluZyB0aGUgcGFnZSBpbiBtZW1vcnkgYW5zd2VyZWQgZnJvbSBpdCBmb3IgdGhlXG4gICAgICAvLyB3aG9sZSBtZW1vcnkgVFRMLCBhbmQgQ2xvdWRGcm9udCAtIGp1c3QgaW52YWxpZGF0ZWQgLSBjYWNoZWQgdGhlIHN0YWxlXG4gICAgICAvLyBwYWdlIGFnYWluLiBTbyBhIG1lbW9yeSBoaXQgaXMgY2hlY2tlZCBhZ2FpbnN0IHRoZSB0YWcgbWFya2VycyB0b28uXG4gICAgICBjb25zdCB2YWx1ZTogSW5jcmVtZW50YWxDYWNoZVZhbHVlID0ge1xuICAgICAgICBraW5kOiBDYWNoZWRSb3V0ZUtpbmQuQVBQX1BBR0UsXG4gICAgICAgIGh0bWw6IFwiPGh0bWw+c3RhbGU8L2h0bWw+XCIsXG4gICAgICAgIHJzY0RhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgaGVhZGVyczogeyBcIngtbmV4dC1jYWNoZS10YWdzXCI6IFwiX05fVF8vYmxvZ1wiIH0sXG4gICAgICAgIHBvc3Rwb25lZDogdW5kZWZpbmVkLFxuICAgICAgICBzZWdtZW50RGF0YTogdW5kZWZpbmVkLFxuICAgICAgICBzdGF0dXM6IHVuZGVmaW5lZCxcbiAgICAgIH07XG4gICAgICBjb25zdCBnZXRDdHggPSB7XG4gICAgICAgIGtpbmQ6IEluY3JlbWVudGFsQ2FjaGVLaW5kLkFQUF9QQUdFLFxuICAgICAgICBpc0ZhbGxiYWNrOiBmYWxzZSxcbiAgICAgIH0gYXMgY29uc3Q7XG5cbiAgICAgIChjYWNoZUhhbmRsZXIgYXMgYW55KS5zM0R5bmFtb0hhbmRsZXIgPSB7XG4gICAgICAgIGdldDogamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKHsgbGFzdE1vZGlmaWVkOiBEYXRlLm5vdygpLCB2YWx1ZSB9KSxcbiAgICAgIH07XG4gICAgICBhd2FpdCBjYWNoZUhhbmRsZXIuZ2V0KFwiYmxvZ1wiLCBnZXRDdHgpO1xuXG4gICAgICAvLyBBbm90aGVyIGluc3RhbmNlIHJldmFsaWRhdGVkIGBfTl9UXy9ibG9nYDogdGhlIG1hcmtlciBpcyBuZXdlciB0aGFuIHRoZVxuICAgICAgLy8gbWVtb3J5IGNvcHksIGFuZCBTMyBub3cgYW5zd2VycyB3aXRoIHRoZSBlbnRyeSBleHBpcmVkLlxuICAgICAgY29uc3QgczMgPSB7XG4gICAgICAgIGdldDogamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKHsgbGFzdE1vZGlmaWVkOiAtMSwgdmFsdWUgfSksXG4gICAgICAgIGlzUmV2YWxpZGF0ZWQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZSh0cnVlKSxcbiAgICAgIH07XG4gICAgICAoY2FjaGVIYW5kbGVyIGFzIGFueSkuczNEeW5hbW9IYW5kbGVyID0gczM7XG4gICAgICBleHBlY3QoYXdhaXQgY2FjaGVIYW5kbGVyLmdldChcImJsb2dcIiwgZ2V0Q3R4KSkudG9FcXVhbCh7XG4gICAgICAgIGxhc3RNb2RpZmllZDogLTEsXG4gICAgICAgIHZhbHVlLFxuICAgICAgfSk7XG4gICAgICBleHBlY3QoczMuaXNSZXZhbGlkYXRlZCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHsgdmFsdWUgfSksXG4gICAgICAgIGdldEN0eCxcbiAgICAgICAgXCJibG9nXCIsXG4gICAgICApO1xuICAgICAgZXhwZWN0KHMzLmdldCkudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDEpO1xuXG4gICAgICAvLyBBbmQgdGhlIG1lbW9yeSBjb3B5IGlzIGdvbmUgcmF0aGVyIHRoYW4gY2hlY2tlZCBhZ2FpbiBuZXh0IHRpbWUuXG4gICAgICBzMy5nZXQubW9ja1Jlc29sdmVkVmFsdWUobnVsbCk7XG4gICAgICBleHBlY3QoYXdhaXQgY2FjaGVIYW5kbGVyLmdldChcImJsb2dcIiwgZ2V0Q3R4KSkudG9CZU51bGwoKTtcbiAgICB9KTtcblxuICAgIGl0KFwia2VlcHMgbWVtb3J5IGVudHJpZXMgYWNyb3NzIHJlc2V0UmVxdWVzdENhY2hlXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIE5leHQuanMgY2FsbHMgaXQgYXQgdGhlIHN0YXJ0IG9mIGV2ZXJ5IHJlcXVlc3Q7IGNsZWFyaW5nIHRoZSBzaGFyZWRcbiAgICAgIC8vIG1lbW9yeSBjYWNoZSB0aGVyZSBzZW50IGV2ZXJ5IHJlYWQgdG8gUzMuXG4gICAgICBjb25zdCB0ZXN0RGF0YTogSW5jcmVtZW50YWxDYWNoZVZhbHVlID0ge1xuICAgICAgICBraW5kOiBDYWNoZWRSb3V0ZUtpbmQuQVBQX1BBR0UsXG4gICAgICAgIGh0bWw6IFwiPGh0bWw+cmVzZXQ8L2h0bWw+XCIsXG4gICAgICAgIHJzY0RhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgaGVhZGVyczogdW5kZWZpbmVkLFxuICAgICAgICBwb3N0cG9uZWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgc2VnbWVudERhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgc3RhdHVzOiB1bmRlZmluZWQsXG4gICAgICB9O1xuXG4gICAgICAvLyBBZGQgZW50cnlcbiAgICAgIGF3YWl0IGNhY2hlSGFuZGxlci5zZXQoXCJyZXNldC1rZXlcIiwgdGVzdERhdGEsIHtcbiAgICAgICAgZmV0Y2hDYWNoZTogdHJ1ZSBhcyBjb25zdCxcbiAgICAgICAgdGFnczogW1wicmVzZXQtdGFnXCJdLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFJlc2V0XG4gICAgICBhd2FpdCBjYWNoZUhhbmRsZXIucmVzZXRSZXF1ZXN0Q2FjaGUoKTtcblxuICAgICAgLy8gU3RpbGwgYW5zd2VyZWQgZnJvbSBtZW1vcnksIHdpdGhvdXQgYXNraW5nIFMzLlxuICAgICAgY29uc3QgczMgPSB7XG4gICAgICAgIGdldDogamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKG51bGwpLFxuICAgICAgICBpc1JldmFsaWRhdGVkOiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUoZmFsc2UpLFxuICAgICAgfTtcbiAgICAgIChjYWNoZUhhbmRsZXIgYXMgYW55KS5zM0R5bmFtb0hhbmRsZXIgPSBzMztcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNhY2hlSGFuZGxlci5nZXQoXCJyZXNldC1rZXlcIiwge1xuICAgICAgICBraW5kOiBJbmNyZW1lbnRhbENhY2hlS2luZC5BUFBfUEFHRSxcbiAgICAgICAgaXNGYWxsYmFjazogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChyZXN1bHQ/LnZhbHVlKS50b0VxdWFsKHRlc3REYXRhKTtcbiAgICAgIGV4cGVjdChzMy5nZXQpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiQnVpbGQtdGltZSBiZWhhdmlvclwiLCAoKSA9PiB7XG4gICAgaXQoXCJyZWFkcyBiYWNrIGEgZmV0Y2ggZW50cnkgaXQgd3JvdGUsIGZyb20gbWVtb3J5IGFuZCBmcm9tIGRpc2tcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gYGNhY2hlQ29tcG9uZW50c2AgcHJlcmVuZGVycyBlYWNoIHBhZ2UgdHdpY2U6IHRoZSBmaXJzdCBwYXNzIHJ1bnMgdGhlXG4gICAgICAvLyBgZmV0Y2hgIGFuZCBgc2V0YHMgaXQsIHRoZSBzZWNvbmQgbXVzdCBmaW5kIGl0IGFscmVhZHkgY2FjaGVkIG9yIE5leHQuanNcbiAgICAgIC8vIGZhaWxzIHRoZSBidWlsZCB3aXRoIFwiZW5jb3VudGVyZWQgdW5jYWNoZWQgb3IgcnVudGltZSBkYXRhIGR1cmluZ1xuICAgICAgLy8gcHJlcmVuZGVyaW5nXCIuIEEgd3JpdGUtb25seSBidWlsZC10aW1lIGhhbmRsZXIgdGhlcmVmb3JlIG1ha2VzXG4gICAgICAvLyBgY2FjaGU6ICdmb3JjZS1jYWNoZSdgIHVuYnVpbGRhYmxlIC0gbWVhc3VyZWQgYWdhaW5zdCBuZXh0LmpzJ3NcbiAgICAgIC8vIGB0ZXN0L2UyZS9hcHAtZGlyL3Jlc3VtZS1kYXRhLWNhY2hlYC5cbiAgICAgIHByb2Nlc3MuZW52Lk5FWFRfUEhBU0UgPSBcInBoYXNlLXByb2R1Y3Rpb24tYnVpbGRcIjtcbiAgICAgIHByb2Nlc3MuZW52LkNES19ORVhUSlNfSU5JVF9DQUNIRV9ESVIgPSBta2R0ZW1wU3luYyhcbiAgICAgICAgam9pbih0bXBkaXIoKSwgXCJjZGstbmV4dGpzLWluaXQtY2FjaGUtXCIpLFxuICAgICAgKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGRhdGE6IEluY3JlbWVudGFsQ2FjaGVWYWx1ZSA9IHtcbiAgICAgICAgICBraW5kOiBDYWNoZWRSb3V0ZUtpbmQuRkVUQ0gsXG4gICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgaGVhZGVyczoge30sXG4gICAgICAgICAgICBib2R5OiBcImV5SnlZVzVrYjIwaU9qRjlcIixcbiAgICAgICAgICAgIHN0YXR1czogMjAwLFxuICAgICAgICAgICAgdXJsOiBcImh0dHBzOi8vZXhhbXBsZS50ZXN0L2FwaS9yYW5kb21cIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJldmFsaWRhdGU6IDMxNTM2MDAwLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBmZXRjaFVybCA9IFwiaHR0cHM6Ly9leGFtcGxlLnRlc3QvYXBpL3JhbmRvbVwiO1xuICAgICAgICBjb25zdCBzZXRDdHggPSB7XG4gICAgICAgICAgZmV0Y2hDYWNoZTogdHJ1ZSBhcyBjb25zdCxcbiAgICAgICAgICB0YWdzOiBbXCJ0ZXN0XCJdLFxuICAgICAgICAgIGZldGNoVXJsLFxuICAgICAgICAgIGZldGNoSWR4OiAxLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBnZXRDdHg6IEdldEluY3JlbWVudGFsRmV0Y2hDYWNoZUNvbnRleHQgPSB7XG4gICAgICAgICAga2luZDogSW5jcmVtZW50YWxDYWNoZUtpbmQuRkVUQ0gsXG4gICAgICAgICAgcmV2YWxpZGF0ZTogMzE1MzYwMDAsXG4gICAgICAgICAgZmV0Y2hVcmwsXG4gICAgICAgICAgZmV0Y2hJZHg6IDEsXG4gICAgICAgICAgdGFnczogW1widGVzdFwiXSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgYnVpbGRIYW5kbGVyID0gbmV3IENka05leHRqc0NhY2hlSGFuZGxlcihjcmVhdGVNb2NrQ29udGV4dCgpKTtcbiAgICAgICAgYXdhaXQgYnVpbGRIYW5kbGVyLnNldChcImZldGNoLWtleVwiLCBkYXRhLCBzZXRDdHgpO1xuICAgICAgICBleHBlY3QoYXdhaXQgYnVpbGRIYW5kbGVyLmdldChcImZldGNoLWtleVwiLCBnZXRDdHgpKS50b01hdGNoT2JqZWN0KHtcbiAgICAgICAgICB2YWx1ZTogZGF0YSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQSBzZWNvbmQgaW5zdGFuY2UgcmVhZHMgdGhlIGZpbGUgcmF0aGVyIHRoYW4gdGhlIG1hcDogYG5leHQgYnVpbGRgXG4gICAgICAgIC8vIHJlbmRlcnMgcGFnZXMgaW4gd29ya2VyIHByb2Nlc3Nlcywgc28gdGhlIHBhc3MgdGhhdCB3cml0ZXMgYW5kIHRoZVxuICAgICAgICAvLyBwYXNzIHRoYXQgcmVhZHMgYXJlIG5vdCBhbHdheXMgdGhlIHNhbWUgcHJvY2Vzcy5cbiAgICAgICAgY29uc3Qgb3RoZXJXb3JrZXIgPSBuZXcgQ2RrTmV4dGpzQ2FjaGVIYW5kbGVyKGNyZWF0ZU1vY2tDb250ZXh0KCkpO1xuICAgICAgICBleHBlY3QoYXdhaXQgb3RoZXJXb3JrZXIuZ2V0KFwiZmV0Y2gta2V5XCIsIGdldEN0eCkpLnRvTWF0Y2hPYmplY3Qoe1xuICAgICAgICAgIHZhbHVlOiBkYXRhLFxuICAgICAgICB9KTtcbiAgICAgICAgZXhwZWN0KGF3YWl0IG90aGVyV29ya2VyLmdldChcIm5ldmVyLXdyaXR0ZW5cIiwgZ2V0Q3R4KSkudG9CZU51bGwoKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGRlbGV0ZSBwcm9jZXNzLmVudi5ORVhUX1BIQVNFO1xuICAgICAgICBkZWxldGUgcHJvY2Vzcy5lbnYuQ0RLX05FWFRKU19JTklUX0NBQ0hFX0RJUjtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
@@ -0,0 +1,32 @@
1
+ import { CachedRouteKind } from "next/dist/server/response-cache/index.js";
2
+ import type { PrerenderVariants } from "./cache-utils";
3
+ /** The fields of `ctx.outputs` a cache kind is read from. */
4
+ export interface CacheKindOutputs {
5
+ readonly pages: ReadonlyArray<{
6
+ id: string;
7
+ }>;
8
+ readonly appPages: ReadonlyArray<{
9
+ id: string;
10
+ }>;
11
+ readonly appRoutes: ReadonlyArray<{
12
+ id: string;
13
+ }>;
14
+ }
15
+ /**
16
+ * Returns which kind of cache entry to seed for one prerendered route, or
17
+ * `undefined` for a route whose owner writes no response-cache entry.
18
+ *
19
+ * Read from the prerender's `parentOutputId`, which `next build` sets to the
20
+ * `id` of the output that renders it — not by matching the pathname against
21
+ * route templates. Matching had to reimplement Next's dynamic-segment grammar
22
+ * and got it wrong twice: it required as many segments as the template had, so
23
+ * no `[...slug]` or `[[...rest]]` prerender ever got a kind and every one was a
24
+ * MISS on first request; and it knew the Pages Router home page only as the
25
+ * `/index` its output reports, while its HTML prerender is grouped under `/`, so
26
+ * that page was never seeded either. The parent link has neither problem, and it
27
+ * cannot hand a prerender to the wrong one of two templates that both match its
28
+ * pathname (`/about` against an app route `/[slug]`).
29
+ */
30
+ export declare function cacheKindResolver(outputs: CacheKindOutputs): (variants: PrerenderVariants<{
31
+ parentOutputId: string;
32
+ }>) => CachedRouteKind | undefined;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cacheKindResolver = cacheKindResolver;
4
+ /**
5
+ * Returns which kind of cache entry to seed for one prerendered route, or
6
+ * `undefined` for a route whose owner writes no response-cache entry.
7
+ *
8
+ * Read from the prerender's `parentOutputId`, which `next build` sets to the
9
+ * `id` of the output that renders it — not by matching the pathname against
10
+ * route templates. Matching had to reimplement Next's dynamic-segment grammar
11
+ * and got it wrong twice: it required as many segments as the template had, so
12
+ * no `[...slug]` or `[[...rest]]` prerender ever got a kind and every one was a
13
+ * MISS on first request; and it knew the Pages Router home page only as the
14
+ * `/index` its output reports, while its HTML prerender is grouped under `/`, so
15
+ * that page was never seeded either. The parent link has neither problem, and it
16
+ * cannot hand a prerender to the wrong one of two templates that both match its
17
+ * pathname (`/about` against an app route `/[slug]`).
18
+ */
19
+ function cacheKindResolver(outputs) {
20
+ const kindById = new Map();
21
+ for (const { id } of outputs.pages) {
22
+ kindById.set(id, "PAGES" /* CachedRouteKind.PAGES */);
23
+ }
24
+ for (const { id } of outputs.appPages) {
25
+ kindById.set(id, "APP_PAGE" /* CachedRouteKind.APP_PAGE */);
26
+ }
27
+ for (const { id } of outputs.appRoutes) {
28
+ kindById.set(id, "APP_ROUTE" /* CachedRouteKind.APP_ROUTE */);
29
+ }
30
+ return (variants) => {
31
+ const source = variants.html ?? variants.rsc ?? variants.data ?? variants.segments[0];
32
+ return source ? kindById.get(source.parentOutputId) : undefined;
33
+ };
34
+ }
35
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUta2luZHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlci9jYWNoZS1raW5kcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTBCQSw4Q0FvQkM7QUFuQ0Q7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxTQUFnQixpQkFBaUIsQ0FDL0IsT0FBeUI7SUFJekIsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLEVBQTJCLENBQUM7SUFDcEQsS0FBSyxNQUFNLEVBQUUsRUFBRSxFQUFFLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ25DLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxzQ0FBd0IsQ0FBQztJQUMxQyxDQUFDO0lBQ0QsS0FBSyxNQUFNLEVBQUUsRUFBRSxFQUFFLElBQUksT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3RDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSw0Q0FBMkIsQ0FBQztJQUM3QyxDQUFDO0lBQ0QsS0FBSyxNQUFNLEVBQUUsRUFBRSxFQUFFLElBQUksT0FBTyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ3ZDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSw4Q0FBNEIsQ0FBQztJQUM5QyxDQUFDO0lBQ0QsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFO1FBQ2xCLE1BQU0sTUFBTSxHQUNWLFFBQVEsQ0FBQyxJQUFJLElBQUksUUFBUSxDQUFDLEdBQUcsSUFBSSxRQUFRLENBQUMsSUFBSSxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekUsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDbEUsQ0FBQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IHsgQ2FjaGVkUm91dGVLaW5kIH0gZnJvbSBcIm5leHQvZGlzdC9zZXJ2ZXIvcmVzcG9uc2UtY2FjaGUvaW5kZXguanNcIjtcbmltcG9ydCB0eXBlIHsgUHJlcmVuZGVyVmFyaWFudHMgfSBmcm9tIFwiLi9jYWNoZS11dGlsc1wiO1xuXG4vKiogVGhlIGZpZWxkcyBvZiBgY3R4Lm91dHB1dHNgIGEgY2FjaGUga2luZCBpcyByZWFkIGZyb20uICovXG5leHBvcnQgaW50ZXJmYWNlIENhY2hlS2luZE91dHB1dHMge1xuICByZWFkb25seSBwYWdlczogUmVhZG9ubHlBcnJheTx7IGlkOiBzdHJpbmcgfT47XG4gIHJlYWRvbmx5IGFwcFBhZ2VzOiBSZWFkb25seUFycmF5PHsgaWQ6IHN0cmluZyB9PjtcbiAgcmVhZG9ubHkgYXBwUm91dGVzOiBSZWFkb25seUFycmF5PHsgaWQ6IHN0cmluZyB9Pjtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHdoaWNoIGtpbmQgb2YgY2FjaGUgZW50cnkgdG8gc2VlZCBmb3Igb25lIHByZXJlbmRlcmVkIHJvdXRlLCBvclxuICogYHVuZGVmaW5lZGAgZm9yIGEgcm91dGUgd2hvc2Ugb3duZXIgd3JpdGVzIG5vIHJlc3BvbnNlLWNhY2hlIGVudHJ5LlxuICpcbiAqIFJlYWQgZnJvbSB0aGUgcHJlcmVuZGVyJ3MgYHBhcmVudE91dHB1dElkYCwgd2hpY2ggYG5leHQgYnVpbGRgIHNldHMgdG8gdGhlXG4gKiBgaWRgIG9mIHRoZSBvdXRwdXQgdGhhdCByZW5kZXJzIGl0IOKAlCBub3QgYnkgbWF0Y2hpbmcgdGhlIHBhdGhuYW1lIGFnYWluc3RcbiAqIHJvdXRlIHRlbXBsYXRlcy4gTWF0Y2hpbmcgaGFkIHRvIHJlaW1wbGVtZW50IE5leHQncyBkeW5hbWljLXNlZ21lbnQgZ3JhbW1hclxuICogYW5kIGdvdCBpdCB3cm9uZyB0d2ljZTogaXQgcmVxdWlyZWQgYXMgbWFueSBzZWdtZW50cyBhcyB0aGUgdGVtcGxhdGUgaGFkLCBzb1xuICogbm8gYFsuLi5zbHVnXWAgb3IgYFtbLi4ucmVzdF1dYCBwcmVyZW5kZXIgZXZlciBnb3QgYSBraW5kIGFuZCBldmVyeSBvbmUgd2FzIGFcbiAqIE1JU1Mgb24gZmlyc3QgcmVxdWVzdDsgYW5kIGl0IGtuZXcgdGhlIFBhZ2VzIFJvdXRlciBob21lIHBhZ2Ugb25seSBhcyB0aGVcbiAqIGAvaW5kZXhgIGl0cyBvdXRwdXQgcmVwb3J0cywgd2hpbGUgaXRzIEhUTUwgcHJlcmVuZGVyIGlzIGdyb3VwZWQgdW5kZXIgYC9gLCBzb1xuICogdGhhdCBwYWdlIHdhcyBuZXZlciBzZWVkZWQgZWl0aGVyLiBUaGUgcGFyZW50IGxpbmsgaGFzIG5laXRoZXIgcHJvYmxlbSwgYW5kIGl0XG4gKiBjYW5ub3QgaGFuZCBhIHByZXJlbmRlciB0byB0aGUgd3Jvbmcgb25lIG9mIHR3byB0ZW1wbGF0ZXMgdGhhdCBib3RoIG1hdGNoIGl0c1xuICogcGF0aG5hbWUgKGAvYWJvdXRgIGFnYWluc3QgYW4gYXBwIHJvdXRlIGAvW3NsdWddYCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWNoZUtpbmRSZXNvbHZlcihcbiAgb3V0cHV0czogQ2FjaGVLaW5kT3V0cHV0cyxcbik6IChcbiAgdmFyaWFudHM6IFByZXJlbmRlclZhcmlhbnRzPHsgcGFyZW50T3V0cHV0SWQ6IHN0cmluZyB9PixcbikgPT4gQ2FjaGVkUm91dGVLaW5kIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qga2luZEJ5SWQgPSBuZXcgTWFwPHN0cmluZywgQ2FjaGVkUm91dGVLaW5kPigpO1xuICBmb3IgKGNvbnN0IHsgaWQgfSBvZiBvdXRwdXRzLnBhZ2VzKSB7XG4gICAga2luZEJ5SWQuc2V0KGlkLCBDYWNoZWRSb3V0ZUtpbmQuUEFHRVMpO1xuICB9XG4gIGZvciAoY29uc3QgeyBpZCB9IG9mIG91dHB1dHMuYXBwUGFnZXMpIHtcbiAgICBraW5kQnlJZC5zZXQoaWQsIENhY2hlZFJvdXRlS2luZC5BUFBfUEFHRSk7XG4gIH1cbiAgZm9yIChjb25zdCB7IGlkIH0gb2Ygb3V0cHV0cy5hcHBSb3V0ZXMpIHtcbiAgICBraW5kQnlJZC5zZXQoaWQsIENhY2hlZFJvdXRlS2luZC5BUFBfUk9VVEUpO1xuICB9XG4gIHJldHVybiAodmFyaWFudHMpID0+IHtcbiAgICBjb25zdCBzb3VyY2UgPVxuICAgICAgdmFyaWFudHMuaHRtbCA/PyB2YXJpYW50cy5yc2MgPz8gdmFyaWFudHMuZGF0YSA/PyB2YXJpYW50cy5zZWdtZW50c1swXTtcbiAgICByZXR1cm4gc291cmNlID8ga2luZEJ5SWQuZ2V0KHNvdXJjZS5wYXJlbnRPdXRwdXRJZCkgOiB1bmRlZmluZWQ7XG4gIH07XG59XG4iXX0=
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const app_playground_json_1 = __importDefault(require("./__fixtures__/app-playground.json"));
7
+ const pages_i18n_json_1 = __importDefault(require("./__fixtures__/pages-i18n.json"));
8
+ const cache_kinds_1 = require("./cache-kinds");
9
+ const cache_utils_1 = require("./cache-utils");
10
+ const prerender = (pathname, parentOutputId) => ({
11
+ pathname,
12
+ parentOutputId,
13
+ });
14
+ describe("cacheKindResolver", () => {
15
+ it.each([
16
+ ["app-playground", app_playground_json_1.default],
17
+ ["pages-i18n", pages_i18n_json_1.default],
18
+ ])("gives every prerendered route in %s a kind", (_, fixture) => {
19
+ const kindOf = (0, cache_kinds_1.cacheKindResolver)(fixture.outputs);
20
+ const groups = (0, cache_utils_1.groupPrerenders)(fixture.outputs.prerenders);
21
+ const unkinded = [...groups]
22
+ .filter(([, variants]) => kindOf(variants) === undefined)
23
+ .map(([route]) => route);
24
+ expect(unkinded).toEqual([]);
25
+ });
26
+ it("seeds catch-all and optional catch-all prerenders", () => {
27
+ const kindOf = (0, cache_kinds_1.cacheKindResolver)({
28
+ pages: [{ id: "/docs/[...slug]" }],
29
+ appPages: [{ id: "/shop/[[...rest]]" }],
30
+ appRoutes: [],
31
+ });
32
+ const groups = (0, cache_utils_1.groupPrerenders)([
33
+ prerender("/docs/a/b", "/docs/[...slug]"),
34
+ prerender("/shop", "/shop/[[...rest]]"),
35
+ prerender("/shop/x/y/z", "/shop/[[...rest]]"),
36
+ prerender("/shop/x/y/z.rsc", "/shop/[[...rest]]"),
37
+ ]);
38
+ expect(kindOf(groups.get("/docs/a/b"))).toBe("PAGES" /* CachedRouteKind.PAGES */);
39
+ expect(kindOf(groups.get("/shop"))).toBe("APP_PAGE" /* CachedRouteKind.APP_PAGE */);
40
+ expect(kindOf(groups.get("/shop/x/y/z"))).toBe("APP_PAGE" /* CachedRouteKind.APP_PAGE */);
41
+ });
42
+ it("seeds a Pages Router SSG home page, which its output reports as /index", () => {
43
+ const kindOf = (0, cache_kinds_1.cacheKindResolver)({
44
+ pages: [{ id: "/index" }],
45
+ appPages: [],
46
+ appRoutes: [],
47
+ });
48
+ const groups = (0, cache_utils_1.groupPrerenders)([
49
+ prerender("/", "/index"),
50
+ prerender("/_next/data/b/index.json", "/index"),
51
+ ]);
52
+ expect([...groups.keys()]).toEqual(["/"]);
53
+ expect(kindOf(groups.get("/"))).toBe("PAGES" /* CachedRouteKind.PAGES */);
54
+ });
55
+ it("takes the kind from the owning output, not from a template the path also matches", () => {
56
+ const kindOf = (0, cache_kinds_1.cacheKindResolver)({
57
+ pages: [],
58
+ appPages: [{ id: "/about" }],
59
+ appRoutes: [{ id: "/[slug]" }],
60
+ });
61
+ const groups = (0, cache_utils_1.groupPrerenders)([
62
+ prerender("/about", "/about"),
63
+ prerender("/feed", "/[slug]"),
64
+ ]);
65
+ expect(kindOf(groups.get("/about"))).toBe("APP_PAGE" /* CachedRouteKind.APP_PAGE */);
66
+ expect(kindOf(groups.get("/feed"))).toBe("APP_ROUTE" /* CachedRouteKind.APP_ROUTE */);
67
+ });
68
+ });
69
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUta2luZHMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVyL2NhY2hlLWtpbmRzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFFQSw2RkFBK0Q7QUFDL0QscUZBQXVEO0FBQ3ZELCtDQUFrRDtBQUNsRCwrQ0FBZ0Q7QUFJaEQsTUFBTSxTQUFTLEdBQUcsQ0FBQyxRQUFnQixFQUFFLGNBQXNCLEVBQWEsRUFBRSxDQUFDLENBQUM7SUFDMUUsUUFBUTtJQUNSLGNBQWM7Q0FDZixDQUFDLENBQUM7QUFFSCxRQUFRLENBQUMsbUJBQW1CLEVBQUUsR0FBRyxFQUFFO0lBQ2pDLEVBQUUsQ0FBQyxJQUFJLENBQUM7UUFDTixDQUFDLGdCQUFnQixFQUFFLDZCQUFhLENBQUM7UUFDakMsQ0FBQyxZQUFZLEVBQUUseUJBQVMsQ0FBQztLQUMxQixDQUFDLENBQUMsNENBQTRDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLEVBQUU7UUFDOUQsTUFBTSxNQUFNLEdBQUcsSUFBQSwrQkFBaUIsRUFBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDbEQsTUFBTSxNQUFNLEdBQUcsSUFBQSw2QkFBZSxFQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBeUIsQ0FBQyxDQUFDO1FBQzFFLE1BQU0sUUFBUSxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUM7YUFDekIsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssU0FBUyxDQUFDO2FBQ3hELEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNCLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDL0IsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMs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dC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IHsgQ2FjaGVkUm91dGVLaW5kIH0gZnJvbSBcIm5leHQvZGlzdC9zZXJ2ZXIvcmVzcG9uc2UtY2FjaGUvaW5kZXguanNcIjtcbmltcG9ydCBhcHBQbGF5Z3JvdW5kIGZyb20gXCIuL19fZml4dHVyZXNfXy9hcHAtcGxheWdyb3VuZC5qc29uXCI7XG5pbXBvcnQgcGFnZXNJMThuIGZyb20gXCIuL19fZml4dHVyZXNfXy9wYWdlcy1pMThuLmpzb25cIjtcbmltcG9ydCB7IGNhY2hlS2luZFJlc29sdmVyIH0gZnJvbSBcIi4vY2FjaGUta2luZHNcIjtcbmltcG9ydCB7IGdyb3VwUHJlcmVuZGVycyB9IGZyb20gXCIuL2NhY2hlLXV0aWxzXCI7XG5cbnR5cGUgUHJlcmVuZGVyID0geyBwYXRobmFtZTogc3RyaW5nOyBwYXJlbnRPdXRwdXRJZDogc3RyaW5nIH07XG5cbmNvbnN0IHByZXJlbmRlciA9IChwYXRobmFtZTogc3RyaW5nLCBwYXJlbnRPdXRwdXRJZDogc3RyaW5nKTogUHJlcmVuZGVyID0+ICh7XG4gIHBhdGhuYW1lLFxuICBwYXJlbnRPdXRwdXRJZCxcbn0pO1xuXG5kZXNjcmliZShcImNhY2hlS2luZFJlc29sdmVyXCIsICgpID0+IHtcbiAgaXQuZWFjaChbXG4gICAgW1wiYXBwLXBsYXlncm91bmRcIiwgYXBwUGxheWdyb3VuZF0sXG4gICAgW1wicGFnZXMtaTE4blwiLCBwYWdlc0kxOG5dLFxuICBdKShcImdpdmVzIGV2ZXJ5IHByZXJlbmRlcmVkIHJvdXRlIGluICVzIGEga2luZFwiLCAoXywgZml4dHVyZSkgPT4ge1xuICAgIGNvbnN0IGtpbmRPZiA9IGNhY2hlS2luZFJlc29sdmVyKGZpeHR1cmUub3V0cHV0cyk7XG4gICAgY29uc3QgZ3JvdXBzID0gZ3JvdXBQcmVyZW5kZXJzKGZpeHR1cmUub3V0cHV0cy5wcmVyZW5kZXJzIGFzIFByZXJlbmRlcltdKTtcbiAgICBjb25zdCB1bmtpbmRlZCA9IFsuLi5ncm91cHNdXG4gICAgICAuZmlsdGVyKChbLCB2YXJpYW50c10pID0+IGtpbmRPZih2YXJpYW50cykgPT09IHVuZGVmaW5lZClcbiAgICAgIC5tYXAoKFtyb3V0ZV0pID0+IHJvdXRlKTtcbiAgICBleHBlY3QodW5raW5kZWQpLnRvRXF1YWwoW10pO1xuICB9KTtcblxuICBpdChcInNlZWRzIGNhdGNoLWFsbCBhbmQgb3B0aW9uYWwgY2F0Y2gtYWxsIHByZXJlbmRlcnNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGtpbmRPZiA9IGNhY2hlS2luZFJlc29sdmVyKHtcbiAgICAgIHBhZ2VzOiBbeyBpZDogXCIvZG9jcy9bLi4uc2x1Z11cIiB9XSxcbiAgICAgIGFwcFBhZ2VzOiBbeyBpZDogXCIvc2hvcC9bWy4uLnJlc3RdXVwiIH1dLFxuICAgICAgYXBwUm91dGVzOiBbXSxcbiAgICB9KTtcbiAgICBjb25zdCBncm91cHMgPSBncm91cFByZXJlbmRlcnMoW1xuICAgICAgcHJlcmVuZGVyKFwiL2RvY3MvYS9iXCIsIFwiL2RvY3MvWy4uLnNsdWddXCIpLFxuICAgICAgcHJlcmVuZGVyKFwiL3Nob3BcIiwgXCIvc2hvcC9bWy4uLnJlc3RdXVwiKSxcbiAgICAgIHByZXJlbmRlcihcIi9zaG9wL3gveS96XCIsIFwiL3Nob3AvW1suLi5yZXN0XV1cIiksXG4gICAgICBwcmVyZW5kZXIoXCIvc2hvcC94L3kvei5yc2NcIiwgXCIvc2hvcC9bWy4uLnJlc3RdXVwiKSxcbiAgICBdKTtcbiAgICBleHBlY3Qoa2luZE9mKGdyb3Vwcy5nZXQoXCIvZG9jcy9hL2JcIikhKSkudG9CZShDYWNoZWRSb3V0ZUtpbmQuUEFHRVMpO1xuICAgIGV4cGVjdChraW5kT2YoZ3JvdXBzLmdldChcIi9zaG9wXCIpISkpLnRvQmUoQ2FjaGVkUm91dGVLaW5kLkFQUF9QQUdFKTtcbiAgICBleHBlY3Qoa2luZE9mKGdyb3Vwcy5nZXQoXCIvc2hvcC94L3kvelwiKSEpKS50b0JlKENhY2hlZFJvdXRlS2luZC5BUFBfUEFHRSk7XG4gIH0pO1xuXG4gIGl0KFwic2VlZHMgYSBQYWdlcyBSb3V0ZXIgU1NHIGhvbWUgcGFnZSwgd2hpY2ggaXRzIG91dHB1dCByZXBvcnRzIGFzIC9pbmRleFwiLCAoKSA9PiB7XG4gICAgY29uc3Qga2luZE9mID0gY2FjaGVLaW5kUmVzb2x2ZXIoe1xuICAgICAgcGFnZXM6IFt7IGlkOiBcIi9pbmRleFwiIH1dLFxuICAgICAgYXBwUGFnZXM6IFtdLFxuICAgICAgYXBwUm91dGVzOiBbXSxcbiAgICB9KTtcbiAgICBjb25zdCBncm91cHMgPSBncm91cFByZXJlbmRlcnMoW1xuICAgICAgcHJlcmVuZGVyKFwiL1wiLCBcIi9pbmRleFwiKSxcbiAgICAgIHByZXJlbmRlcihcIi9fbmV4dC9kYXRhL2IvaW5kZXguanNvblwiLCBcIi9pbmRleFwiKSxcbiAgICBdKTtcbiAgICBleHBlY3QoWy4uLmdyb3Vwcy5rZXlzKCldKS50b0VxdWFsKFtcIi9cIl0pO1xuICAgIGV4cGVjdChraW5kT2YoZ3JvdXBzLmdldChcIi9cIikhKSkudG9CZShDYWNoZWRSb3V0ZUtpbmQuUEFHRVMpO1xuICB9KTtcblxuICBpdChcInRha2VzIHRoZSBraW5kIGZyb20gdGhlIG93bmluZyBvdXRwdXQsIG5vdCBmcm9tIGEgdGVtcGxhdGUgdGhlIHBhdGggYWxzbyBtYXRjaGVzXCIsICgpID0+IHtcbiAgICBjb25zdCBraW5kT2YgPSBjYWNoZUtpbmRSZXNvbHZlcih7XG4gICAgICBwYWdlczogW10sXG4gICAgICBhcHBQYWdlczogW3sgaWQ6IFwiL2Fib3V0XCIgfV0sXG4gICAgICBhcHBSb3V0ZXM6IFt7IGlkOiBcIi9bc2x1Z11cIiB9XSxcbiAgICB9KTtcbiAgICBjb25zdCBncm91cHMgPSBncm91cFByZXJlbmRlcnMoW1xuICAgICAgcHJlcmVuZGVyKFwiL2Fib3V0XCIsIFwiL2Fib3V0XCIpLFxuICAgICAgcHJlcmVuZGVyKFwiL2ZlZWRcIiwgXCIvW3NsdWddXCIpLFxuICAgIF0pO1xuICAgIGV4cGVjdChraW5kT2YoZ3JvdXBzLmdldChcIi9hYm91dFwiKSEpKS50b0JlKENhY2hlZFJvdXRlS2luZC5BUFBfUEFHRSk7XG4gICAgZXhwZWN0KGtpbmRPZihncm91cHMuZ2V0KFwiL2ZlZWRcIikhKSkudG9CZShDYWNoZWRSb3V0ZUtpbmQuQVBQX1JPVVRFKTtcbiAgfSk7XG59KTtcbiJdfQ==