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.
- package/.jsii +2467 -2714
- package/.jsii.tabl.json +1 -1
- package/API.md +1725 -1909
- package/CLAUDE.md +2 -1
- package/README.md +429 -130
- package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +152 -170
- package/assets/lambdas/redeploy-stage/redeploy-stage.lambda/index.js +875 -0
- package/docs/adapter-runtime.md +185 -0
- package/docs/breaking-changes.md +687 -4
- package/docs/caching-guide.md +156 -112
- package/docs/cdk-nextjs-cfn-exec-policy.json +2 -1
- package/docs/development-guide.md +1 -1
- package/docs/harness-coverage.md +598 -0
- package/docs/init-cache-deployment.md +32 -1
- package/docs/next-build-output-guide.md +30 -20
- package/examples/README.md +5 -1
- package/lib/adapter/__fixtures__/app-playground-base-path.json +4926 -0
- package/lib/adapter/__fixtures__/app-playground.json +4917 -0
- package/lib/adapter/__fixtures__/pages-i18n.json +1728 -0
- package/lib/adapter/adapter.mjs +1548 -185
- package/lib/adapter/adapter.test.js +106 -0
- package/lib/adapter/aws-cache-store.d.ts +489 -0
- package/lib/adapter/aws-cache-store.js +1004 -0
- package/lib/adapter/aws-cache-store.test.d.ts +1 -0
- package/lib/adapter/aws-cache-store.test.js +361 -0
- package/lib/adapter/build-outputs.d.ts +80 -0
- package/lib/adapter/build-outputs.js +852 -0
- package/lib/adapter/build-outputs.test.d.ts +1 -0
- package/lib/adapter/build-outputs.test.js +861 -0
- package/lib/adapter/cache-handler.d.ts +9 -2
- package/lib/adapter/cache-handler.js +72 -96
- package/lib/adapter/cache-handler.mjs +18956 -17774
- package/lib/adapter/cache-handler.test.js +263 -31
- package/lib/adapter/cache-kinds.d.ts +32 -0
- package/lib/adapter/cache-kinds.js +35 -0
- package/lib/adapter/cache-kinds.test.d.ts +1 -0
- package/lib/adapter/cache-kinds.test.js +69 -0
- package/lib/adapter/cache-utils.d.ts +90 -0
- package/lib/adapter/cache-utils.js +199 -4
- package/lib/adapter/cache-utils.test.d.ts +1 -0
- package/lib/adapter/cache-utils.test.js +179 -0
- package/lib/adapter/function-groups.d.ts +215 -0
- package/lib/adapter/function-groups.js +1099 -0
- package/lib/adapter/function-groups.test.d.ts +1 -0
- package/lib/adapter/function-groups.test.js +743 -0
- package/lib/adapter/init-cache.d.ts +6 -0
- package/lib/adapter/init-cache.js +245 -0
- package/lib/adapter/init-cache.test.d.ts +1 -0
- package/lib/adapter/init-cache.test.js +137 -0
- package/lib/adapter/local-file-cache-handler.d.ts +23 -0
- package/lib/adapter/local-file-cache-handler.js +52 -1
- package/lib/adapter/memory-cache-handler.d.ts +26 -17
- package/lib/adapter/memory-cache-handler.js +32 -50
- package/lib/adapter/memory-cache-handler.test.js +105 -85
- package/lib/adapter/s3-cache-handler.d.ts +179 -40
- package/lib/adapter/s3-cache-handler.js +807 -277
- package/lib/adapter/s3-cache-handler.test.js +1186 -31
- package/lib/adapter/use-cache-common.d.ts +90 -0
- package/lib/adapter/use-cache-common.js +250 -0
- package/lib/adapter/use-cache-common.test.d.ts +1 -0
- package/lib/adapter/use-cache-common.test.js +646 -0
- package/lib/adapter/use-cache-default-handler.d.ts +24 -0
- package/lib/adapter/use-cache-default-handler.js +90 -0
- package/lib/adapter/use-cache-default-handler.mjs +38645 -0
- package/lib/adapter/use-cache-handlers.test.d.ts +1 -0
- package/lib/adapter/use-cache-handlers.test.js +349 -0
- package/lib/adapter/use-cache-remote-handler.d.ts +26 -0
- package/lib/adapter/use-cache-remote-handler.js +186 -0
- package/lib/{image-optimization/handler.mjs → adapter/use-cache-remote-handler.mjs} +33572 -38798
- package/lib/generated-structs/OptionalNextjsApiProps.d.ts +59 -0
- package/lib/generated-structs/OptionalNextjsApiProps.js +3 -0
- package/lib/generated-structs/OptionalNextjsCacheProps.d.ts +15 -6
- package/lib/generated-structs/OptionalNextjsCacheProps.js +1 -1
- package/lib/generated-structs/OptionalNextjsContainersProps.d.ts +25 -11
- package/lib/generated-structs/OptionalNextjsContainersProps.js +1 -1
- package/lib/generated-structs/OptionalNextjsDistributionProps.d.ts +31 -9
- package/lib/generated-structs/OptionalNextjsDistributionProps.js +1 -1
- package/lib/generated-structs/OptionalNextjsPostDeployProps.d.ts +13 -0
- package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
- package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +11 -2
- package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.js +1 -1
- package/lib/index.d.ts +6 -7
- package/lib/index.js +2 -4
- package/lib/lambdas/post-deploy/post-deploy.lambda.js +3 -2
- package/lib/lambdas/post-deploy/prune-cache-bucket.d.ts +7 -3
- package/lib/lambdas/post-deploy/prune-cache-bucket.js +57 -71
- package/lib/lambdas/post-deploy/prune-cache-bucket.test.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-cache-bucket.test.js +114 -0
- package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-revalidation-table.js +23 -31
- package/lib/lambdas/post-deploy/prune-revalidation-table.test.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +71 -0
- package/lib/lambdas/post-deploy/prune-s3.d.ts +19 -3
- package/lib/lambdas/post-deploy/prune-s3.js +54 -15
- package/lib/lambdas/post-deploy/prune-s3.test.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-s3.test.js +255 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage-function.d.ts +13 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage-function.js +55 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.d.ts +24 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.js +68 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.d.ts +20 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.js +24 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.test.d.ts +1 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.test.js +93 -0
- package/lib/nextjs-api.d.ts +107 -18
- package/lib/nextjs-api.js +349 -39
- package/lib/nextjs-api.test.js +582 -1
- package/lib/nextjs-build/global-containers.Dockerfile +15 -10
- package/lib/nextjs-build/nextjs-build.d.ts +339 -63
- package/lib/nextjs-build/nextjs-build.js +684 -327
- package/lib/nextjs-build/nextjs-build.test.d.ts +1 -0
- package/lib/nextjs-build/nextjs-build.test.js +412 -0
- package/lib/nextjs-build/patch-fetch.js +1 -1
- package/lib/nextjs-build/patch-fetch.test.js +166 -11
- package/lib/nextjs-build/regional-containers.Dockerfile +17 -10
- package/lib/nextjs-cache.d.ts +82 -4
- package/lib/nextjs-cache.js +186 -10
- package/lib/nextjs-cache.test.js +176 -1
- package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +21 -8
- package/lib/nextjs-compute/nextjs-compute-base-props.js +41 -1
- package/lib/nextjs-compute/nextjs-compute-base-props.test.d.ts +1 -0
- package/lib/nextjs-compute/nextjs-compute-base-props.test.js +44 -0
- package/lib/nextjs-compute/nextjs-containers.d.ts +19 -0
- package/lib/nextjs-compute/nextjs-containers.js +57 -20
- package/lib/nextjs-compute/nextjs-functions.d.ts +122 -7
- package/lib/nextjs-compute/nextjs-functions.js +113 -67
- package/lib/nextjs-compute/nextjs-functions.test.d.ts +1 -0
- package/lib/nextjs-compute/nextjs-functions.test.js +99 -0
- package/lib/nextjs-distribution.d.ts +194 -23
- package/lib/nextjs-distribution.js +535 -62
- package/lib/nextjs-distribution.test.d.ts +1 -0
- package/lib/nextjs-distribution.test.js +697 -0
- package/lib/nextjs-post-deploy.d.ts +23 -3
- package/lib/nextjs-post-deploy.js +14 -10
- package/lib/nextjs-post-deploy.test.d.ts +1 -0
- package/lib/nextjs-post-deploy.test.js +34 -0
- package/lib/nextjs-static-assets.d.ts +23 -4
- package/lib/nextjs-static-assets.js +29 -6
- package/lib/nextjs-static-assets.test.js +20 -1
- package/lib/root-constructs/nextjs-base-construct.d.ts +105 -45
- package/lib/root-constructs/nextjs-base-construct.js +144 -34
- package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
- package/lib/root-constructs/nextjs-global-containers.js +20 -70
- package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
- package/lib/root-constructs/nextjs-global-functions.js +52 -69
- package/lib/root-constructs/nextjs-regional-containers.d.ts +25 -5
- package/lib/root-constructs/nextjs-regional-containers.js +17 -15
- package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
- package/lib/root-constructs/nextjs-regional-functions.js +8 -25
- package/lib/runtime/api-gateway-path.d.ts +34 -0
- package/lib/runtime/api-gateway-path.js +71 -0
- package/lib/runtime/api-gateway-path.test.d.ts +1 -0
- package/lib/runtime/api-gateway-path.test.js +65 -0
- package/lib/runtime/case-redirect.d.ts +22 -0
- package/lib/runtime/case-redirect.js +63 -0
- package/lib/runtime/case-redirect.test.d.ts +1 -0
- package/lib/runtime/case-redirect.test.js +32 -0
- package/lib/runtime/core.d.ts +234 -0
- package/lib/runtime/core.js +1213 -0
- package/lib/runtime/core.test.d.ts +1 -0
- package/lib/runtime/core.test.js +1678 -0
- package/lib/runtime/deployment-root.d.ts +13 -0
- package/lib/runtime/deployment-root.js +29 -0
- package/lib/runtime/dispatch.d.ts +331 -0
- package/lib/runtime/dispatch.js +751 -0
- package/lib/runtime/dispatch.test.d.ts +1 -0
- package/lib/runtime/dispatch.test.js +853 -0
- package/lib/runtime/entrypoints.d.ts +57 -0
- package/lib/runtime/entrypoints.js +115 -0
- package/lib/runtime/http/abort-signal.d.ts +6 -0
- package/lib/runtime/http/abort-signal.js +19 -0
- package/lib/runtime/http/abort-signal.test.d.ts +1 -0
- package/lib/runtime/http/abort-signal.test.js +49 -0
- package/lib/runtime/http/node-server.d.ts +38 -0
- package/lib/runtime/http/node-server.js +99 -0
- package/lib/runtime/http/node-server.test.d.ts +1 -0
- package/lib/runtime/http/node-server.test.js +96 -0
- package/lib/runtime/http/node-sink.d.ts +16 -0
- package/lib/runtime/http/node-sink.js +48 -0
- package/lib/runtime/http/node-sink.test.d.ts +1 -0
- package/lib/runtime/http/node-sink.test.js +66 -0
- package/lib/runtime/http/request.d.ts +62 -0
- package/lib/runtime/http/request.js +134 -0
- package/lib/runtime/http/request.test.d.ts +1 -0
- package/lib/runtime/http/request.test.js +103 -0
- package/lib/runtime/http/response.d.ts +77 -0
- package/lib/runtime/http/response.js +229 -0
- package/lib/runtime/http/response.test.d.ts +1 -0
- package/lib/runtime/http/response.test.js +178 -0
- package/lib/runtime/http/sink.d.ts +73 -0
- package/lib/runtime/http/sink.js +188 -0
- package/lib/runtime/http/sink.test.d.ts +1 -0
- package/lib/runtime/http/sink.test.js +257 -0
- package/lib/runtime/image-utils.d.ts +78 -0
- package/lib/runtime/image-utils.js +129 -0
- package/lib/runtime/image-utils.test.d.ts +1 -0
- package/lib/runtime/image-utils.test.js +237 -0
- package/lib/runtime/image.d.ts +76 -0
- package/lib/runtime/image.js +296 -0
- package/lib/runtime/image.test.d.ts +1 -0
- package/lib/runtime/image.test.js +405 -0
- package/lib/runtime/lambda-event.d.ts +4 -0
- package/lib/runtime/lambda-event.js +113 -0
- package/lib/runtime/lambda-event.test.d.ts +1 -0
- package/lib/runtime/lambda-event.test.js +119 -0
- package/lib/runtime/lambda.mjs +41595 -0
- package/lib/runtime/load-module.d.ts +8 -0
- package/lib/runtime/load-module.js +35 -0
- package/lib/runtime/manifest.d.ts +215 -0
- package/lib/runtime/manifest.js +118 -0
- package/lib/runtime/middleware.d.ts +43 -0
- package/lib/runtime/middleware.js +113 -0
- package/lib/runtime/middleware.test.d.ts +1 -0
- package/lib/runtime/middleware.test.js +259 -0
- package/lib/runtime/next-modules.d.ts +55 -0
- package/lib/runtime/next-modules.js +124 -0
- package/lib/runtime/next-modules.test.d.ts +1 -0
- package/lib/runtime/next-modules.test.js +34 -0
- package/lib/runtime/public-files.d.ts +32 -0
- package/lib/runtime/public-files.js +117 -0
- package/lib/runtime/public-files.test.d.ts +1 -0
- package/lib/runtime/public-files.test.js +97 -0
- package/lib/runtime/server.mjs +41588 -0
- package/lib/runtime/static-files.d.ts +50 -0
- package/lib/runtime/static-files.js +266 -0
- package/lib/runtime/static-files.test.d.ts +1 -0
- package/lib/runtime/static-files.test.js +118 -0
- package/lib/runtime/util.d.ts +28 -0
- package/lib/runtime/util.js +79 -0
- package/lib/utils/base-path.d.ts +123 -11
- package/lib/utils/base-path.js +276 -39
- package/lib/utils/base-path.test.js +275 -50
- package/lib/utils/get-architecture.d.ts +7 -8
- package/lib/utils/get-architecture.js +12 -13
- package/lib/utils/zip-directory.d.ts +14 -0
- package/lib/utils/zip-directory.js +121 -0
- package/lib/utils/zip-directory.test.d.ts +1 -0
- package/lib/utils/zip-directory.test.js +99 -0
- package/package.json +22 -3
- package/scripts/capture-adapter-fixture.mjs +325 -0
- package/scripts/e2e-deploy.sh +398 -0
- package/scripts/e2e-harness/README.md +707 -0
- package/scripts/e2e-harness/app.js +370 -0
- package/scripts/e2e-harness/common.sh +249 -0
- package/scripts/e2e-harness/screen.mjs +302 -0
- package/scripts/e2e-harness/stage-proxy.mjs +145 -0
- package/scripts/e2e-harness/type-filters.mjs +47 -0
- package/scripts/e2e-logs.sh +75 -0
- package/scripts/e2e-offline.sh +91 -0
- package/scripts/e2e-sweep.sh +370 -0
- package/scripts/e2e-warm.sh +114 -0
- package/scripts/zero-config-build.mjs +418 -0
- package/docs/1k-concurrent-users-executions.png +0 -0
- package/docs/plans/adapter-runtime-release.md +0 -362
- package/docs/plans/phase-0-image-function-opt-in.md +0 -295
- package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +0 -425
- package/lib/generated-structs/OptionalDockerImageFunctionProps.js +0 -3
- package/lib/image-optimization/handler-utils.d.ts +0 -34
- package/lib/image-optimization/handler-utils.js +0 -83
- package/lib/image-optimization/handler-utils.test.js +0 -178
- package/lib/nextjs-build/functions.Dockerfile +0 -31
- package/lib/nextjs-compute/nextjs-image-function.d.ts +0 -53
- package/lib/nextjs-compute/nextjs-image-function.js +0 -59
- package/lib/utils/experimental-flags.d.ts +0 -24
- package/lib/utils/experimental-flags.js +0 -30
- /package/lib/{image-optimization/handler-utils.test.d.ts → adapter/adapter.test.d.ts} +0 -0
|
@@ -5,8 +5,98 @@ import type { SetIncrementalFetchCacheContext, SetIncrementalResponseCacheContex
|
|
|
5
5
|
export declare function serializeCacheValue(value: any): string;
|
|
6
6
|
/**
|
|
7
7
|
* Parse cache value with custom handling for Map and Buffer objects
|
|
8
|
+
*
|
|
9
|
+
* Buffers are read back from base64 when that is how they were written, and from
|
|
10
|
+
* an array of per-byte integers when they were not. That array is the format
|
|
11
|
+
* `Buffer.toJSON()` produces and the one this code used to write, and it is
|
|
12
|
+
* ruinous for a page with a large payload: a 1 MiB prerender became ~3 MiB of
|
|
13
|
+
* JSON text, an 11.6 MiB cache entry once html and the per-segment copies are
|
|
14
|
+
* counted, and — because `JSON.parse`'s reviver runs for *every array element* —
|
|
15
|
+
* upwards of three million reviver calls to read one page. Measured against a
|
|
16
|
+
* deployment: 4.8s of Lambda time to answer a 1 MiB segment prefetch, against
|
|
17
|
+
* 45ms for a small one from the same cache. base64 is 4/3 the bytes rather than
|
|
18
|
+
* ~3x, and `Buffer.from(str, "base64")` is one native call.
|
|
8
19
|
*/
|
|
9
20
|
export declare function parseCacheValue(jsonString: string): any;
|
|
21
|
+
/**
|
|
22
|
+
* The cache key a prerendered route's seeded entry has to be written under.
|
|
23
|
+
*
|
|
24
|
+
* `ctx.outputs.prerenders[].pathname` is the *URL* the page is served at, so it
|
|
25
|
+
* carries the app's `basePath`. The key the server later looks entries up under
|
|
26
|
+
* is the route, which does not — Next.js strips `basePath` before routing, so the
|
|
27
|
+
* cache handler never sees it at request time. Seeding `/prod/ssg/1` verbatim
|
|
28
|
+
* therefore writes `<buildId>/prod/ssg/1.json` while the server asks for
|
|
29
|
+
* `<buildId>/ssg/1.json`: every build-time prerender is a MISS that re-renders on
|
|
30
|
+
* first request, and the page is only "static" from the second visit onwards.
|
|
31
|
+
*/
|
|
32
|
+
export declare function prerenderPathToCacheKey(pathname: string, basePath: string): string;
|
|
33
|
+
/** The outputs one route contributes to `ctx.outputs.prerenders`. */
|
|
34
|
+
export interface PrerenderVariants<T> {
|
|
35
|
+
/** The HTML render. Its pathname is the route, with no suffix. */
|
|
36
|
+
html?: T;
|
|
37
|
+
/** The flight payload, built as `<route>.rsc` — but see {@link groupPrerenders}. */
|
|
38
|
+
rsc?: T;
|
|
39
|
+
/** Per-segment flight payloads, under `<route>.segments/`. */
|
|
40
|
+
segments: T[];
|
|
41
|
+
/** A Pages Router route's `pageData`, built as its `/_next/data/` route. */
|
|
42
|
+
data?: T;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Collect `ctx.outputs.prerenders` into one entry per route.
|
|
46
|
+
*
|
|
47
|
+
* Next.js emits up to three shapes per prerendered App Router route — `/blog/hello`,
|
|
48
|
+
* `/blog/hello.rsc`, and `/blog/hello.segments/*.segment.rsc` — and a cache entry
|
|
49
|
+
* needs all of them together, so they have to be grouped by route before anything
|
|
50
|
+
* can be seeded. A Pages Router route emits two: the HTML, and its `pageData` at
|
|
51
|
+
* the route's `/_next/data/<buildId>/<page>.json` pathname
|
|
52
|
+
* ({@link PAGES_DATA_PATHNAME}). That one is not a suffix of the page's own
|
|
53
|
+
* pathname, so it is matched rather than stripped.
|
|
54
|
+
*
|
|
55
|
+
* The one case that is not a suffix strip is the **root route**, which cannot be
|
|
56
|
+
* named `/.rsc`: its payloads are emitted under `/index.rsc` and
|
|
57
|
+
* `/index.segments/` while its HTML stays at `/` (or at the `basePath`, e.g.
|
|
58
|
+
* `/prod` and `/prod/index.rsc`). Reconstructing names by concatenation therefore
|
|
59
|
+
* silently loses the home page's `rscData` — and with a `basePath` also its
|
|
60
|
+
* `segmentData`, because `/prod` and `/prod/index` group apart. That is not a
|
|
61
|
+
* cosmetic gap: `app-page-runtime.js` answers an RSC request for an entry with no
|
|
62
|
+
* `rscData` by checking `cachedData.html.contentType`, and under `cacheComponents`
|
|
63
|
+
* sends an empty `404`. Every client-side navigation to `/` breaks.
|
|
64
|
+
*
|
|
65
|
+
* The remap is conditional rather than unconditional so that an app with a real
|
|
66
|
+
* page at `app/index/page.tsx` — whose HTML prerender genuinely is `/index` — keeps
|
|
67
|
+
* its own group.
|
|
68
|
+
*/
|
|
69
|
+
export declare function groupPrerenders<T extends {
|
|
70
|
+
pathname: string;
|
|
71
|
+
}>(prerenders: T[]): Map<string, PrerenderVariants<T>>;
|
|
72
|
+
/** See {@link NON_CACHEABLE_APP_PAGE_HEADERS}. */
|
|
73
|
+
export declare function appPageCacheHeaders<T>(initialHeaders: Record<string, T>): Record<string, T>;
|
|
74
|
+
/**
|
|
75
|
+
* The tags a cache value's render was tagged with, as Next.js records them: in
|
|
76
|
+
* its `x-next-cache-tags` header, comma separated, including the implicit
|
|
77
|
+
* `_N_T_/…` path chain `revalidatePath` uses. One parser for the build's tag
|
|
78
|
+
* manifest and the runtime's mapping rows, which have to agree.
|
|
79
|
+
*
|
|
80
|
+
* `value` is `unknown` because it arrives both as a stored entry read back from
|
|
81
|
+
* S3 and as the `IncrementalCacheValue` union; only some members have headers.
|
|
82
|
+
*/
|
|
83
|
+
export declare function headerTags(value: unknown): string[];
|
|
84
|
+
/**
|
|
85
|
+
* Name of the file the adapter writes into the init cache directory mapping each
|
|
86
|
+
* cache tag to the cache keys of the build-time prerenders carrying it.
|
|
87
|
+
*
|
|
88
|
+
* It rides to S3 with the rest of the init cache, and `S3CacheHandler`'s
|
|
89
|
+
* `revalidateTag` reads it alongside the `tag#cacheKey` rows a runtime `set`
|
|
90
|
+
* writes. Without it `revalidateTag` knows a prerender is stale (see
|
|
91
|
+
* `checkIfRevalidated`) but not which CloudFront paths to invalidate, so the CDN
|
|
92
|
+
* keeps serving the old response until its TTL expires - a year, for a
|
|
93
|
+
* prerender.
|
|
94
|
+
*
|
|
95
|
+
* The leading underscore keeps it clear of cache keys, which are route paths.
|
|
96
|
+
*/
|
|
97
|
+
export declare const INIT_CACHE_TAG_MANIFEST = "_cdk-nextjs-tag-manifest.json";
|
|
98
|
+
/** Contents of {@link INIT_CACHE_TAG_MANIFEST}: tag -> init cache keys. */
|
|
99
|
+
export type InitCacheTagManifest = Record<string, string[]>;
|
|
10
100
|
/**
|
|
11
101
|
* Helper to safely extract tags from context
|
|
12
102
|
*/
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.INIT_CACHE_TAG_MANIFEST = void 0;
|
|
3
4
|
exports.serializeCacheValue = serializeCacheValue;
|
|
4
5
|
exports.parseCacheValue = parseCacheValue;
|
|
6
|
+
exports.prerenderPathToCacheKey = prerenderPathToCacheKey;
|
|
7
|
+
exports.groupPrerenders = groupPrerenders;
|
|
8
|
+
exports.appPageCacheHeaders = appPageCacheHeaders;
|
|
9
|
+
exports.headerTags = headerTags;
|
|
5
10
|
exports.getTags = getTags;
|
|
11
|
+
const base_path_1 = require("../utils/base-path");
|
|
6
12
|
/**
|
|
7
13
|
* Pre-process value to convert Buffers and Maps before JSON.stringify
|
|
8
14
|
* This is necessary because Buffer.toJSON() is called before replacer functions
|
|
@@ -12,11 +18,13 @@ function preprocessValue(value) {
|
|
|
12
18
|
if (value == null) {
|
|
13
19
|
return value;
|
|
14
20
|
}
|
|
15
|
-
// Convert Buffer to our custom format
|
|
21
|
+
// Convert Buffer to our custom format. base64, not the array of per-byte
|
|
22
|
+
// integers this used to write (and that `Buffer.toJSON()` writes) — see
|
|
23
|
+
// {@link parseCacheValue} for why that mattered so much.
|
|
16
24
|
if (Buffer.isBuffer(value)) {
|
|
17
25
|
return {
|
|
18
26
|
__type: "Buffer",
|
|
19
|
-
|
|
27
|
+
base64: value.toString("base64"),
|
|
20
28
|
};
|
|
21
29
|
}
|
|
22
30
|
// Convert Map to our custom format
|
|
@@ -56,6 +64,17 @@ function serializeCacheValue(value) {
|
|
|
56
64
|
}
|
|
57
65
|
/**
|
|
58
66
|
* Parse cache value with custom handling for Map and Buffer objects
|
|
67
|
+
*
|
|
68
|
+
* Buffers are read back from base64 when that is how they were written, and from
|
|
69
|
+
* an array of per-byte integers when they were not. That array is the format
|
|
70
|
+
* `Buffer.toJSON()` produces and the one this code used to write, and it is
|
|
71
|
+
* ruinous for a page with a large payload: a 1 MiB prerender became ~3 MiB of
|
|
72
|
+
* JSON text, an 11.6 MiB cache entry once html and the per-segment copies are
|
|
73
|
+
* counted, and — because `JSON.parse`'s reviver runs for *every array element* —
|
|
74
|
+
* upwards of three million reviver calls to read one page. Measured against a
|
|
75
|
+
* deployment: 4.8s of Lambda time to answer a 1 MiB segment prefetch, against
|
|
76
|
+
* 45ms for a small one from the same cache. base64 is 4/3 the bytes rather than
|
|
77
|
+
* ~3x, and `Buffer.from(str, "base64")` is one native call.
|
|
59
78
|
*/
|
|
60
79
|
function parseCacheValue(jsonString) {
|
|
61
80
|
return JSON.parse(jsonString, (_key, val) => {
|
|
@@ -65,7 +84,9 @@ function parseCacheValue(jsonString) {
|
|
|
65
84
|
}
|
|
66
85
|
// Restore Buffer objects that were serialized with __type marker (our custom format)
|
|
67
86
|
if (val && typeof val === "object" && val.__type === "Buffer") {
|
|
68
|
-
return
|
|
87
|
+
return typeof val.base64 === "string"
|
|
88
|
+
? Buffer.from(val.base64, "base64")
|
|
89
|
+
: Buffer.from(val.data);
|
|
69
90
|
}
|
|
70
91
|
// Restore Buffer objects that were serialized with Node.js default Buffer.toJSON() format
|
|
71
92
|
// This handles legacy cache entries or runtime-generated entries
|
|
@@ -78,10 +99,184 @@ function parseCacheValue(jsonString) {
|
|
|
78
99
|
return val;
|
|
79
100
|
});
|
|
80
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* The cache key a prerendered route's seeded entry has to be written under.
|
|
104
|
+
*
|
|
105
|
+
* `ctx.outputs.prerenders[].pathname` is the *URL* the page is served at, so it
|
|
106
|
+
* carries the app's `basePath`. The key the server later looks entries up under
|
|
107
|
+
* is the route, which does not — Next.js strips `basePath` before routing, so the
|
|
108
|
+
* cache handler never sees it at request time. Seeding `/prod/ssg/1` verbatim
|
|
109
|
+
* therefore writes `<buildId>/prod/ssg/1.json` while the server asks for
|
|
110
|
+
* `<buildId>/ssg/1.json`: every build-time prerender is a MISS that re-renders on
|
|
111
|
+
* first request, and the page is only "static" from the second visit onwards.
|
|
112
|
+
*/
|
|
113
|
+
function prerenderPathToCacheKey(pathname, basePath) {
|
|
114
|
+
// Matching on a path boundary so a sibling route like `/production` is not
|
|
115
|
+
// read as basePath `/prod` plus `uction`.
|
|
116
|
+
const route = ((0, base_path_1.hasPathPrefix)(pathname, basePath)
|
|
117
|
+
? pathname.slice(basePath.length)
|
|
118
|
+
: pathname)
|
|
119
|
+
// Leading slashes would make an S3 key with an empty first segment.
|
|
120
|
+
.replace(/^\/+/, "");
|
|
121
|
+
return route === "" ? "index" : route;
|
|
122
|
+
}
|
|
123
|
+
const INDEX_SUFFIX = "/index";
|
|
124
|
+
/**
|
|
125
|
+
* A Pages Router data route: `/_next/data/<buildId>/<page>.json`, optionally
|
|
126
|
+
* behind a `basePath` (`normalizePathname` in Next.js's `build-complete` prefixes
|
|
127
|
+
* every output pathname, this one included).
|
|
128
|
+
*
|
|
129
|
+
* Capture 1 is that prefix and capture 2 the page path without its `.json`, so
|
|
130
|
+
* `/prod/_next/data/abc123/blog/hello.json` recomposes to `/prod/blog/hello`.
|
|
131
|
+
*/
|
|
132
|
+
const PAGES_DATA_PATHNAME = /^(.*)\/_next\/data\/[^/]+\/(.+)\.json$/;
|
|
133
|
+
/**
|
|
134
|
+
* Collect `ctx.outputs.prerenders` into one entry per route.
|
|
135
|
+
*
|
|
136
|
+
* Next.js emits up to three shapes per prerendered App Router route — `/blog/hello`,
|
|
137
|
+
* `/blog/hello.rsc`, and `/blog/hello.segments/*.segment.rsc` — and a cache entry
|
|
138
|
+
* needs all of them together, so they have to be grouped by route before anything
|
|
139
|
+
* can be seeded. A Pages Router route emits two: the HTML, and its `pageData` at
|
|
140
|
+
* the route's `/_next/data/<buildId>/<page>.json` pathname
|
|
141
|
+
* ({@link PAGES_DATA_PATHNAME}). That one is not a suffix of the page's own
|
|
142
|
+
* pathname, so it is matched rather than stripped.
|
|
143
|
+
*
|
|
144
|
+
* The one case that is not a suffix strip is the **root route**, which cannot be
|
|
145
|
+
* named `/.rsc`: its payloads are emitted under `/index.rsc` and
|
|
146
|
+
* `/index.segments/` while its HTML stays at `/` (or at the `basePath`, e.g.
|
|
147
|
+
* `/prod` and `/prod/index.rsc`). Reconstructing names by concatenation therefore
|
|
148
|
+
* silently loses the home page's `rscData` — and with a `basePath` also its
|
|
149
|
+
* `segmentData`, because `/prod` and `/prod/index` group apart. That is not a
|
|
150
|
+
* cosmetic gap: `app-page-runtime.js` answers an RSC request for an entry with no
|
|
151
|
+
* `rscData` by checking `cachedData.html.contentType`, and under `cacheComponents`
|
|
152
|
+
* sends an empty `404`. Every client-side navigation to `/` breaks.
|
|
153
|
+
*
|
|
154
|
+
* The remap is conditional rather than unconditional so that an app with a real
|
|
155
|
+
* page at `app/index/page.tsx` — whose HTML prerender genuinely is `/index` — keeps
|
|
156
|
+
* its own group.
|
|
157
|
+
*/
|
|
158
|
+
function groupPrerenders(prerenders) {
|
|
159
|
+
const htmlPathnames = new Set(prerenders
|
|
160
|
+
.map((p) => p.pathname)
|
|
161
|
+
.filter((p) => !p.endsWith(".rsc") &&
|
|
162
|
+
!p.includes(".segments/") &&
|
|
163
|
+
!PAGES_DATA_PATHNAME.test(p)));
|
|
164
|
+
const groups = new Map();
|
|
165
|
+
const variantsFor = (base) => {
|
|
166
|
+
let variants = groups.get(base);
|
|
167
|
+
if (!variants) {
|
|
168
|
+
variants = { segments: [] };
|
|
169
|
+
groups.set(base, variants);
|
|
170
|
+
}
|
|
171
|
+
return variants;
|
|
172
|
+
};
|
|
173
|
+
/** `/index.rsc` belongs to `/`, `/prod/index.rsc` to `/prod`. */
|
|
174
|
+
const routeOf = (base) => {
|
|
175
|
+
if (base.endsWith(INDEX_SUFFIX) && !htmlPathnames.has(base)) {
|
|
176
|
+
const parent = base.slice(0, -INDEX_SUFFIX.length) || "/";
|
|
177
|
+
if (htmlPathnames.has(parent)) {
|
|
178
|
+
return parent;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return base;
|
|
182
|
+
};
|
|
183
|
+
for (const prerender of prerenders) {
|
|
184
|
+
const { pathname } = prerender;
|
|
185
|
+
const dataRoute = PAGES_DATA_PATHNAME.exec(pathname);
|
|
186
|
+
if (dataRoute) {
|
|
187
|
+
variantsFor(routeOf(`${dataRoute[1]}/${dataRoute[2]}`)).data = prerender;
|
|
188
|
+
}
|
|
189
|
+
else if (pathname.includes(".segments/")) {
|
|
190
|
+
variantsFor(routeOf(pathname.split(".segments/")[0])).segments.push(prerender);
|
|
191
|
+
}
|
|
192
|
+
else if (pathname.endsWith(".rsc")) {
|
|
193
|
+
variantsFor(routeOf(pathname.slice(0, -".rsc".length))).rsc = prerender;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
variantsFor(pathname).html = prerender;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return groups;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Headers that must not be seeded into an `APP_PAGE` cache entry, even though the
|
|
203
|
+
* adapter output lists them in `fallback.initialHeaders`.
|
|
204
|
+
*
|
|
205
|
+
* `initialHeaders` describes how a platform should serve the prerendered *file*
|
|
206
|
+
* straight off a CDN. A cache entry is a different thing: `app-page-runtime.js`
|
|
207
|
+
* `appendHeader`s `cachedData.headers` onto the response and *then* serves the
|
|
208
|
+
* variant the request actually asked for, so anything presentational in there is
|
|
209
|
+
* either wrong or doubled. At request time Next.js stores only what the render
|
|
210
|
+
* put in `metadata.headers` — `x-nextjs-stale-time`, `x-next-cache-tags`, and
|
|
211
|
+
* whatever the app set through `headers()`/`cookies()` — and never these four.
|
|
212
|
+
*
|
|
213
|
+
* `content-type` is the one that actually breaks. `send-payload.js` sets the type
|
|
214
|
+
* only when the response does not already have one
|
|
215
|
+
* (`if (!res.getHeader('Content-Type') && result.contentType)`), so a seeded
|
|
216
|
+
* `text/html; charset=utf-8` makes every RSC request to a prerendered page answer
|
|
217
|
+
* the flight payload labeled as HTML. The client router rejects that, and so does
|
|
218
|
+
* Next.js itself: `createRedirectRenderResult` checks the content type of the
|
|
219
|
+
* sub-response it fetches to stream an action `redirect()`, and on a mismatch
|
|
220
|
+
* cancels the body and returns an empty result.
|
|
221
|
+
*
|
|
222
|
+
* `vary`, `x-nextjs-prerender`, and `x-nextjs-postponed` are all set by the
|
|
223
|
+
* entrypoint itself, so seeding them only produces two of each.
|
|
224
|
+
*
|
|
225
|
+
* `APP_ROUTE` entries are deliberately *not* filtered: a route handler's
|
|
226
|
+
* `content-type` is part of its cached response, and `app-route.js` replays those
|
|
227
|
+
* headers verbatim.
|
|
228
|
+
*/
|
|
229
|
+
const NON_CACHEABLE_APP_PAGE_HEADERS = new Set([
|
|
230
|
+
"content-type",
|
|
231
|
+
"vary",
|
|
232
|
+
"x-nextjs-prerender",
|
|
233
|
+
"x-nextjs-postponed",
|
|
234
|
+
]);
|
|
235
|
+
/** See {@link NON_CACHEABLE_APP_PAGE_HEADERS}. */
|
|
236
|
+
function appPageCacheHeaders(initialHeaders) {
|
|
237
|
+
const headers = {};
|
|
238
|
+
for (const [name, value] of Object.entries(initialHeaders)) {
|
|
239
|
+
if (!NON_CACHEABLE_APP_PAGE_HEADERS.has(name.toLowerCase())) {
|
|
240
|
+
headers[name] = value;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return headers;
|
|
244
|
+
}
|
|
245
|
+
/** `NEXT_CACHE_TAGS_HEADER`, inlined so this file imports no Next.js internals. */
|
|
246
|
+
const NEXT_CACHE_TAGS_HEADER = "x-next-cache-tags";
|
|
247
|
+
/**
|
|
248
|
+
* The tags a cache value's render was tagged with, as Next.js records them: in
|
|
249
|
+
* its `x-next-cache-tags` header, comma separated, including the implicit
|
|
250
|
+
* `_N_T_/…` path chain `revalidatePath` uses. One parser for the build's tag
|
|
251
|
+
* manifest and the runtime's mapping rows, which have to agree.
|
|
252
|
+
*
|
|
253
|
+
* `value` is `unknown` because it arrives both as a stored entry read back from
|
|
254
|
+
* S3 and as the `IncrementalCacheValue` union; only some members have headers.
|
|
255
|
+
*/
|
|
256
|
+
function headerTags(value) {
|
|
257
|
+
const headers = value
|
|
258
|
+
?.headers;
|
|
259
|
+
const header = headers?.[NEXT_CACHE_TAGS_HEADER];
|
|
260
|
+
return typeof header === "string" ? header.split(",").filter(Boolean) : [];
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Name of the file the adapter writes into the init cache directory mapping each
|
|
264
|
+
* cache tag to the cache keys of the build-time prerenders carrying it.
|
|
265
|
+
*
|
|
266
|
+
* It rides to S3 with the rest of the init cache, and `S3CacheHandler`'s
|
|
267
|
+
* `revalidateTag` reads it alongside the `tag#cacheKey` rows a runtime `set`
|
|
268
|
+
* writes. Without it `revalidateTag` knows a prerender is stale (see
|
|
269
|
+
* `checkIfRevalidated`) but not which CloudFront paths to invalidate, so the CDN
|
|
270
|
+
* keeps serving the old response until its TTL expires - a year, for a
|
|
271
|
+
* prerender.
|
|
272
|
+
*
|
|
273
|
+
* The leading underscore keeps it clear of cache keys, which are route paths.
|
|
274
|
+
*/
|
|
275
|
+
exports.INIT_CACHE_TAG_MANIFEST = "_cdk-nextjs-tag-manifest.json";
|
|
81
276
|
/**
|
|
82
277
|
* Helper to safely extract tags from context
|
|
83
278
|
*/
|
|
84
279
|
function getTags(ctx) {
|
|
85
280
|
return "tags" in ctx ? ctx.tags : undefined;
|
|
86
281
|
}
|
|
87
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtdXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlci9jYWNoZS11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTJEQSxrREFLQztBQUtELDBDQXNCQztBQUtELDBCQUlDO0FBNUZEOzs7R0FHRztBQUNILFNBQVMsZUFBZSxDQUFDLEtBQVU7SUFDakMsd0JBQXdCO0lBQ3hCLElBQUksS0FBSyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ2xCLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELHNDQUFzQztJQUN0QyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUMzQixPQUFPO1lBQ0wsTUFBTSxFQUFFLFFBQVE7WUFDaEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1NBQ3hCLENBQUM7SUFDSixDQUFDO0lBRUQsbUNBQW1DO0lBQ25DLElBQUksS0FBSyxZQUFZLEdBQUcsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sT0FBTyxHQUF3QixFQUFFLENBQUM7UUFDeEMsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO1lBQ3pDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEMsQ0FBQztRQUNELE9BQU87WUFDTCxNQUFNLEVBQUUsS0FBSztZQUNiLElBQUksRUFBRSxPQUFPO1NBQ2QsQ0FBQztJQUNKLENBQUM7SUFFRCw2QkFBNkI7SUFDN0IsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDekIsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQsOEJBQThCO0lBQzlCLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDOUIsTUFBTSxTQUFTLEdBQXdCLEVBQUUsQ0FBQztRQUMxQyxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQy9DLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEMsQ0FBQztRQUNELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRCwwQkFBMEI7SUFDMUIsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixtQkFBbUIsQ0FBQyxLQUFVO0lBQzVDLGdFQUFnRTtJQUNoRSxpREFBaUQ7SUFDakQsTUFBTSxTQUFTLEdBQUcsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3pDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixlQUFlLENBQUMsVUFBa0I7SUFDaEQsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUMxQyw4REFBOEQ7UUFDOUQsSUFBSSxHQUFHLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDM0QsT0FBTyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQzNDLENBQUM7UUFDRCxxRkFBcUY7UUFDckYsSUFBSSxHQUFHLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDOUQsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMvQixDQUFDO1FBQ0QsMEZBQTBGO1FBQzFGLGlFQUFpRTtRQUNqRSxJQUNFLEdBQUc7WUFDSCxPQUFPLEdBQUcsS0FBSyxRQUFRO1lBQ3ZCLEdBQUcsQ0FBQyxJQUFJLEtBQUssUUFBUTtZQUNyQixLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFDdkIsQ0FBQztZQUNELE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDL0IsQ0FBQztRQUNELE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixPQUFPLENBQ3JCLEdBQXlFO0lBRXpFLE9BQU8sTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQzlDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICBTaGFyZWQgY2FjaGUgdXRpbGl0eSBmdW5jdGlvbnNcbiovXG5pbXBvcnQgdHlwZSB7XG4gIFNldEluY3JlbWVudGFsRmV0Y2hDYWNoZUNvbnRleHQsXG4gIFNldEluY3JlbWVudGFsUmVzcG9uc2VDYWNoZUNvbnRleHQsXG59IGZyb20gXCJuZXh0L2Rpc3Qvc2VydmVyL3Jlc3BvbnNlLWNhY2hlXCI7XG5cbi8qKlxuICogUHJlLXByb2Nlc3MgdmFsdWUgdG8gY29udmVydCBCdWZmZXJzIGFuZCBNYXBzIGJlZm9yZSBKU09OLnN0cmluZ2lmeVxuICogVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSBCdWZmZXIudG9KU09OKCkgaXMgY2FsbGVkIGJlZm9yZSByZXBsYWNlciBmdW5jdGlvbnNcbiAqL1xuZnVuY3Rpb24gcHJlcHJvY2Vzc1ZhbHVlKHZhbHVlOiBhbnkpOiBhbnkge1xuICAvLyBIYW5kbGUgbnVsbC91bmRlZmluZWRcbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvLyBDb252ZXJ0IEJ1ZmZlciB0byBvdXIgY3VzdG9tIGZvcm1hdFxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbHVlKSkge1xuICAgIHJldHVybiB7XG4gICAgICBfX3R5cGU6IFwiQnVmZmVyXCIsXG4gICAgICBkYXRhOiBBcnJheS5mcm9tKHZhbHVlKSxcbiAgICB9O1xuICB9XG5cbiAgLy8gQ29udmVydCBNYXAgdG8gb3VyIGN1c3RvbSBmb3JtYXRcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgY29uc3QgZW50cmllczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsXSBvZiB2YWx1ZS5lbnRyaWVzKCkpIHtcbiAgICAgIGVudHJpZXNba2V5XSA9IHByZXByb2Nlc3NWYWx1ZSh2YWwpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiBcIk1hcFwiLFxuICAgICAgZGF0YTogZW50cmllcyxcbiAgICB9O1xuICB9XG5cbiAgLy8gUmVjdXJzaXZlbHkgcHJvY2VzcyBhcnJheXNcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlLm1hcCgoaXRlbSkgPT4gcHJlcHJvY2Vzc1ZhbHVlKGl0ZW0pKTtcbiAgfVxuXG4gIC8vIFJlY3Vyc2l2ZWx5IHByb2Nlc3Mgb2JqZWN0c1xuICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiKSB7XG4gICAgY29uc3QgcHJvY2Vzc2VkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWxdIG9mIE9iamVjdC5lbnRyaWVzKHZhbHVlKSkge1xuICAgICAgcHJvY2Vzc2VkW2tleV0gPSBwcmVwcm9jZXNzVmFsdWUodmFsKTtcbiAgICB9XG4gICAgcmV0dXJuIHByb2Nlc3NlZDtcbiAgfVxuXG4gIC8vIFJldHVybiBwcmltaXRpdmVzIGFzLWlzXG4gIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBTZXJpYWxpemUgY2FjaGUgdmFsdWUgd2l0aCBjdXN0b20gaGFuZGxpbmcgZm9yIE1hcCBhbmQgQnVmZmVyIG9iamVjdHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcmlhbGl6ZUNhY2hlVmFsdWUodmFsdWU6IGFueSk6IHN0cmluZyB7XG4gIC8vIFByZS1wcm9jZXNzIHRvIGNvbnZlcnQgQnVmZmVycyBhbmQgTWFwcyBiZWZvcmUgSlNPTi5zdHJpbmdpZnlcbiAgLy8gVGhpcyBlbnN1cmVzIEJ1ZmZlci50b0pTT04oKSBkb2Vzbid0IGludGVyZmVyZVxuICBjb25zdCBwcm9jZXNzZWQgPSBwcmVwcm9jZXNzVmFsdWUodmFsdWUpO1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocHJvY2Vzc2VkKTtcbn1cblxuLyoqXG4gKiBQYXJzZSBjYWNoZSB2YWx1ZSB3aXRoIGN1c3RvbSBoYW5kbGluZyBmb3IgTWFwIGFuZCBCdWZmZXIgb2JqZWN0c1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VDYWNoZVZhbHVlKGpzb25TdHJpbmc6IHN0cmluZyk6IGFueSB7XG4gIHJldHVybiBKU09OLnBhcnNlKGpzb25TdHJpbmcsIChfa2V5LCB2YWwpID0+IHtcbiAgICAvLyBSZXN0b3JlIE1hcCBvYmplY3RzIHRoYXQgd2VyZSBzZXJpYWxpemVkIHdpdGggX190eXBlIG1hcmtlclxuICAgIGlmICh2YWwgJiYgdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIiAmJiB2YWwuX190eXBlID09PSBcIk1hcFwiKSB7XG4gICAgICByZXR1cm4gbmV3IE1hcChPYmplY3QuZW50cmllcyh2YWwuZGF0YSkpO1xuICAgIH1cbiAgICAvLyBSZXN0b3JlIEJ1ZmZlciBvYmplY3RzIHRoYXQgd2VyZSBzZXJpYWxpemVkIHdpdGggX190eXBlIG1hcmtlciAob3VyIGN1c3RvbSBmb3JtYXQpXG4gICAgaWYgKHZhbCAmJiB0eXBlb2YgdmFsID09PSBcIm9iamVjdFwiICYmIHZhbC5fX3R5cGUgPT09IFwiQnVmZmVyXCIpIHtcbiAgICAgIHJldHVybiBCdWZmZXIuZnJvbSh2YWwuZGF0YSk7XG4gICAgfVxuICAgIC8vIFJlc3RvcmUgQnVmZmVyIG9iamVjdHMgdGhhdCB3ZXJlIHNlcmlhbGl6ZWQgd2l0aCBOb2RlLmpzIGRlZmF1bHQgQnVmZmVyLnRvSlNPTigpIGZvcm1hdFxuICAgIC8vIFRoaXMgaGFuZGxlcyBsZWdhY3kgY2FjaGUgZW50cmllcyBvciBydW50aW1lLWdlbmVyYXRlZCBlbnRyaWVzXG4gICAgaWYgKFxuICAgICAgdmFsICYmXG4gICAgICB0eXBlb2YgdmFsID09PSBcIm9iamVjdFwiICYmXG4gICAgICB2YWwudHlwZSA9PT0gXCJCdWZmZXJcIiAmJlxuICAgICAgQXJyYXkuaXNBcnJheSh2YWwuZGF0YSlcbiAgICApIHtcbiAgICAgIHJldHVybiBCdWZmZXIuZnJvbSh2YWwuZGF0YSk7XG4gICAgfVxuICAgIHJldHVybiB2YWw7XG4gIH0pO1xufVxuXG4vKipcbiAqIEhlbHBlciB0byBzYWZlbHkgZXh0cmFjdCB0YWdzIGZyb20gY29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGFncyhcbiAgY3R4OiBTZXRJbmNyZW1lbnRhbEZldGNoQ2FjaGVDb250ZXh0IHwgU2V0SW5jcmVtZW50YWxSZXNwb25zZUNhY2hlQ29udGV4dCxcbik6IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIFwidGFnc1wiIGluIGN0eCA/IGN0eC50YWdzIDogdW5kZWZpbmVkO1xufVxuIl19
|
|
282
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtdXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWRhcHRlci9jYWNoZS11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUE4REEsa0RBS0M7QUFnQkQsMENBd0JDO0FBYUQsMERBY0M7QUFtREQsMENBb0RDO0FBc0NELGtEQVVDO0FBY0QsZ0NBS0M7QUF1QkQsMEJBSUM7QUFwVUQsa0RBQW1EO0FBRW5EOzs7R0FHRztBQUNILFNBQVMsZUFBZSxDQUFDLEtBQVU7SUFDakMsd0JBQXdCO0lBQ3hCLElBQUksS0FBSyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ2xCLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELHlFQUF5RTtJQUN6RSx3RUFBd0U7SUFDeEUseURBQXlEO0lBQ3pELElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzNCLE9BQU87WUFDTCxNQUFNLEVBQUUsUUFBUTtZQUNoQixNQUFNLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7U0FDakMsQ0FBQztJQUNKLENBQUM7SUFFRCxtQ0FBbUM7SUFDbkMsSUFBSSxLQUFLLFlBQVksR0FBRyxFQUFFLENBQUM7UUFDekIsTUFBTSxPQUFPLEdBQXdCLEVBQUUsQ0FBQztRQUN4QyxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDekMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBQ0QsT0FBTztZQUNMLE1BQU0sRUFBRSxLQUFLO1lBQ2IsSUFBSSxFQUFFLE9BQU87U0FDZCxDQUFDO0lBQ0osQ0FBQztJQUVELDZCQUE2QjtJQUM3QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN6QixPQUFPLEtBQUss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T0FBTyxDQUNyQixHQUF5RTtJQUV6RSxPQUFPLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUM5QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgU2hhcmVkIGNhY2hlIHV0aWxpdHkgZnVuY3Rpb25zXG4qL1xuaW1wb3J0IHR5cGUge1xuICBTZXRJbmNyZW1lbnRhbEZldGNoQ2FjaGVDb250ZXh0LFxuICBTZXRJbmNyZW1lbnRhbFJlc3BvbnNlQ2FjaGVDb250ZXh0LFxufSBmcm9tIFwibmV4dC9kaXN0L3NlcnZlci9yZXNwb25zZS1jYWNoZVwiO1xuaW1wb3J0IHsgaGFzUGF0aFByZWZpeCB9IGZyb20gXCIuLi91dGlscy9iYXNlLXBhdGhcIjtcblxuLyoqXG4gKiBQcmUtcHJvY2VzcyB2YWx1ZSB0byBjb252ZXJ0IEJ1ZmZlcnMgYW5kIE1hcHMgYmVmb3JlIEpTT04uc3RyaW5naWZ5XG4gKiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIEJ1ZmZlci50b0pTT04oKSBpcyBjYWxsZWQgYmVmb3JlIHJlcGxhY2VyIGZ1bmN0aW9uc1xuICovXG5mdW5jdGlvbiBwcmVwcm9jZXNzVmFsdWUodmFsdWU6IGFueSk6IGFueSB7XG4gIC8vIEhhbmRsZSBudWxsL3VuZGVmaW5lZFxuICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8vIENvbnZlcnQgQnVmZmVyIHRvIG91ciBjdXN0b20gZm9ybWF0LiBiYXNlNjQsIG5vdCB0aGUgYXJyYXkgb2YgcGVyLWJ5dGVcbiAgLy8gaW50ZWdlcnMgdGhpcyB1c2VkIHRvIHdyaXRlIChhbmQgdGhhdCBgQnVmZmVyLnRvSlNPTigpYCB3cml0ZXMpIOKAlCBzZWVcbiAgLy8ge0BsaW5rIHBhcnNlQ2FjaGVWYWx1ZX0gZm9yIHdoeSB0aGF0IG1hdHRlcmVkIHNvIG11Y2guXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsdWUpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF9fdHlwZTogXCJCdWZmZXJcIixcbiAgICAgIGJhc2U2NDogdmFsdWUudG9TdHJpbmcoXCJiYXNlNjRcIiksXG4gICAgfTtcbiAgfVxuXG4gIC8vIENvbnZlcnQgTWFwIHRvIG91ciBjdXN0b20gZm9ybWF0XG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE1hcCkge1xuICAgIGNvbnN0IGVudHJpZXM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbF0gb2YgdmFsdWUuZW50cmllcygpKSB7XG4gICAgICBlbnRyaWVzW2tleV0gPSBwcmVwcm9jZXNzVmFsdWUodmFsKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIF9fdHlwZTogXCJNYXBcIixcbiAgICAgIGRhdGE6IGVudHJpZXMsXG4gICAgfTtcbiAgfVxuXG4gIC8vIFJlY3Vyc2l2ZWx5IHByb2Nlc3MgYXJyYXlzXG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZS5tYXAoKGl0ZW0pID0+IHByZXByb2Nlc3NWYWx1ZShpdGVtKSk7XG4gIH1cblxuICAvLyBSZWN1cnNpdmVseSBwcm9jZXNzIG9iamVjdHNcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIikge1xuICAgIGNvbnN0IHByb2Nlc3NlZDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsXSBvZiBPYmplY3QuZW50cmllcyh2YWx1ZSkpIHtcbiAgICAgIHByb2Nlc3NlZFtrZXldID0gcHJlcHJvY2Vzc1ZhbHVlKHZhbCk7XG4gICAgfVxuICAgIHJldHVybiBwcm9jZXNzZWQ7XG4gIH1cblxuICAvLyBSZXR1cm4gcHJpbWl0aXZlcyBhcy1pc1xuICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogU2VyaWFsaXplIGNhY2hlIHZhbHVlIHdpdGggY3VzdG9tIGhhbmRsaW5nIGZvciBNYXAgYW5kIEJ1ZmZlciBvYmplY3RzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVDYWNoZVZhbHVlKHZhbHVlOiBhbnkpOiBzdHJpbmcge1xuICAvLyBQcmUtcHJvY2VzcyB0byBjb252ZXJ0IEJ1ZmZlcnMgYW5kIE1hcHMgYmVmb3JlIEpTT04uc3RyaW5naWZ5XG4gIC8vIFRoaXMgZW5zdXJlcyBCdWZmZXIudG9KU09OKCkgZG9lc24ndCBpbnRlcmZlcmVcbiAgY29uc3QgcHJvY2Vzc2VkID0gcHJlcHJvY2Vzc1ZhbHVlKHZhbHVlKTtcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHByb2Nlc3NlZCk7XG59XG5cbi8qKlxuICogUGFyc2UgY2FjaGUgdmFsdWUgd2l0aCBjdXN0b20gaGFuZGxpbmcgZm9yIE1hcCBhbmQgQnVmZmVyIG9iamVjdHNcbiAqXG4gKiBCdWZmZXJzIGFyZSByZWFkIGJhY2sgZnJvbSBiYXNlNjQgd2hlbiB0aGF0IGlzIGhvdyB0aGV5IHdlcmUgd3JpdHRlbiwgYW5kIGZyb21cbiAqIGFuIGFycmF5IG9mIHBlci1ieXRlIGludGVnZXJzIHdoZW4gdGhleSB3ZXJlIG5vdC4gVGhhdCBhcnJheSBpcyB0aGUgZm9ybWF0XG4gKiBgQnVmZmVyLnRvSlNPTigpYCBwcm9kdWNlcyBhbmQgdGhlIG9uZSB0aGlzIGNvZGUgdXNlZCB0byB3cml0ZSwgYW5kIGl0IGlzXG4gKiBydWlub3VzIGZvciBhIHBhZ2Ugd2l0aCBhIGxhcmdlIHBheWxvYWQ6IGEgMSBNaUIgcHJlcmVuZGVyIGJlY2FtZSB+MyBNaUIgb2ZcbiAqIEpTT04gdGV4dCwgYW4gMTEuNiBNaUIgY2FjaGUgZW50cnkgb25jZSBodG1sIGFuZCB0aGUgcGVyLXNlZ21lbnQgY29waWVzIGFyZVxuICogY291bnRlZCwgYW5kIOKAlCBiZWNhdXNlIGBKU09OLnBhcnNlYCdzIHJldml2ZXIgcnVucyBmb3IgKmV2ZXJ5IGFycmF5IGVsZW1lbnQqIOKAlFxuICogdXB3YXJkcyBvZiB0aHJlZSBtaWxsaW9uIHJldml2ZXIgY2FsbHMgdG8gcmVhZCBvbmUgcGFnZS4gTWVhc3VyZWQgYWdhaW5zdCBhXG4gKiBkZXBsb3ltZW50OiA0LjhzIG9mIExhbWJkYSB0aW1lIHRvIGFuc3dlciBhIDEgTWlCIHNlZ21lbnQgcHJlZmV0Y2gsIGFnYWluc3RcbiAqIDQ1bXMgZm9yIGEgc21hbGwgb25lIGZyb20gdGhlIHNhbWUgY2FjaGUuIGJhc2U2NCBpcyA0LzMgdGhlIGJ5dGVzIHJhdGhlciB0aGFuXG4gKiB+M3gsIGFuZCBgQnVmZmVyLmZyb20oc3RyLCBcImJhc2U2NFwiKWAgaXMgb25lIG5hdGl2ZSBjYWxsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VDYWNoZVZhbHVlKGpzb25TdHJpbmc6IHN0cmluZyk6IGFueSB7XG4gIHJldHVybiBKU09OLnBhcnNlKGpzb25TdHJpbmcsIChfa2V5LCB2YWwpID0+IHtcbiAgICAvLyBSZXN0b3JlIE1hcCBvYmplY3RzIHRoYXQgd2VyZSBzZXJpYWxpemVkIHdpdGggX190eXBlIG1hcmtlclxuICAgIGlmICh2YWwgJiYgdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIiAmJiB2YWwuX190eXBlID09PSBcIk1hcFwiKSB7XG4gICAgICByZXR1cm4gbmV3IE1hcChPYmplY3QuZW50cmllcyh2YWwuZGF0YSkpO1xuICAgIH1cbiAgICAvLyBSZXN0b3JlIEJ1ZmZlciBvYmplY3RzIHRoYXQgd2VyZSBzZXJpYWxpemVkIHdpdGggX190eXBlIG1hcmtlciAob3VyIGN1c3RvbSBmb3JtYXQpXG4gICAgaWYgKHZhbCAmJiB0eXBlb2YgdmFsID09PSBcIm9iamVjdFwiICYmIHZhbC5fX3R5cGUgPT09IFwiQnVmZmVyXCIpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsLmJhc2U2NCA9PT0gXCJzdHJpbmdcIlxuICAgICAgICA/IEJ1ZmZlci5mcm9tKHZhbC5iYXNlNjQsIFwiYmFzZTY0XCIpXG4gICAgICAgIDogQnVmZmVyLmZyb20odmFsLmRhdGEpO1xuICAgIH1cbiAgICAvLyBSZXN0b3JlIEJ1ZmZlciBvYmplY3RzIHRoYXQgd2VyZSBzZXJpYWxpemVkIHdpdGggTm9kZS5qcyBkZWZhdWx0IEJ1ZmZlci50b0pTT04oKSBmb3JtYXRcbiAgICAvLyBUaGlzIGhhbmRsZXMgbGVnYWN5IGNhY2hlIGVudHJpZXMgb3IgcnVudGltZS1nZW5lcmF0ZWQgZW50cmllc1xuICAgIGlmIChcbiAgICAgIHZhbCAmJlxuICAgICAgdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgdmFsLnR5cGUgPT09IFwiQnVmZmVyXCIgJiZcbiAgICAgIEFycmF5LmlzQXJyYXkodmFsLmRhdGEpXG4gICAgKSB7XG4gICAgICByZXR1cm4gQnVmZmVyLmZyb20odmFsLmRhdGEpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsO1xuICB9KTtcbn1cblxuLyoqXG4gKiBUaGUgY2FjaGUga2V5IGEgcHJlcmVuZGVyZWQgcm91dGUncyBzZWVkZWQgZW50cnkgaGFzIHRvIGJlIHdyaXR0ZW4gdW5kZXIuXG4gKlxuICogYGN0eC5vdXRwdXRzLnByZXJlbmRlcnNbXS5wYXRobmFtZWAgaXMgdGhlICpVUkwqIHRoZSBwYWdlIGlzIHNlcnZlZCBhdCwgc28gaXRcbiAqIGNhcnJpZXMgdGhlIGFwcCdzIGBiYXNlUGF0aGAuIFRoZSBrZXkgdGhlIHNlcnZlciBsYXRlciBsb29rcyBlbnRyaWVzIHVwIHVuZGVyXG4gKiBpcyB0aGUgcm91dGUsIHdoaWNoIGRvZXMgbm90IOKAlCBOZXh0LmpzIHN0cmlwcyBgYmFzZVBhdGhgIGJlZm9yZSByb3V0aW5nLCBzbyB0aGVcbiAqIGNhY2hlIGhhbmRsZXIgbmV2ZXIgc2VlcyBpdCBhdCByZXF1ZXN0IHRpbWUuIFNlZWRpbmcgYC9wcm9kL3NzZy8xYCB2ZXJiYXRpbVxuICogdGhlcmVmb3JlIHdyaXRlcyBgPGJ1aWxkSWQ+L3Byb2Qvc3NnLzEuanNvbmAgd2hpbGUgdGhlIHNlcnZlciBhc2tzIGZvclxuICogYDxidWlsZElkPi9zc2cvMS5qc29uYDogZXZlcnkgYnVpbGQtdGltZSBwcmVyZW5kZXIgaXMgYSBNSVNTIHRoYXQgcmUtcmVuZGVycyBvblxuICogZmlyc3QgcmVxdWVzdCwgYW5kIHRoZSBwYWdlIGlzIG9ubHkgXCJzdGF0aWNcIiBmcm9tIHRoZSBzZWNvbmQgdmlzaXQgb253YXJkcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByZXJlbmRlclBhdGhUb0NhY2hlS2V5KFxuICBwYXRobmFtZTogc3RyaW5nLFxuICBiYXNlUGF0aDogc3RyaW5nLFxuKTogc3RyaW5nIHtcbiAgLy8gTWF0Y2hpbmcgb24gYSBwYXRoIGJvdW5kYXJ5IHNvIGEgc2libGluZyByb3V0ZSBsaWtlIGAvcHJvZHVjdGlvbmAgaXMgbm90XG4gIC8vIHJlYWQgYXMgYmFzZVBhdGggYC9wcm9kYCBwbHVzIGB1Y3Rpb25gLlxuICBjb25zdCByb3V0ZSA9IChcbiAgICBoYXNQYXRoUHJlZml4KHBhdGhuYW1lLCBiYXNlUGF0aClcbiAgICAgID8gcGF0aG5hbWUuc2xpY2UoYmFzZVBhdGgubGVuZ3RoKVxuICAgICAgOiBwYXRobmFtZVxuICApXG4gICAgLy8gTGVhZGluZyBzbGFzaGVzIHdvdWxkIG1ha2UgYW4gUzMga2V5IHdpdGggYW4gZW1wdHkgZmlyc3Qgc2VnbWVudC5cbiAgICAucmVwbGFjZSgvXlxcLysvLCBcIlwiKTtcbiAgcmV0dXJuIHJvdXRlID09PSBcIlwiID8gXCJpbmRleFwiIDogcm91dGU7XG59XG5cbi8qKiBUaGUgb3V0cHV0cyBvbmUgcm91dGUgY29udHJpYnV0ZXMgdG8gYGN0eC5vdXRwdXRzLnByZXJlbmRlcnNgLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcmVyZW5kZXJWYXJpYW50czxUPiB7XG4gIC8qKiBUaGUgSFRNTCByZW5kZXIuIEl0cyBwYXRobmFtZSBpcyB0aGUgcm91dGUsIHdpdGggbm8gc3VmZml4LiAqL1xuICBodG1sPzogVDtcbiAgLyoqIFRoZSBmbGlnaHQgcGF5bG9hZCwgYnVpbHQgYXMgYDxyb3V0ZT4ucnNjYCDigJQgYnV0IHNlZSB7QGxpbmsgZ3JvdXBQcmVyZW5kZXJzfS4gKi9cbiAgcnNjPzogVDtcbiAgLyoqIFBlci1zZWdtZW50IGZsaWdodCBwYXlsb2FkcywgdW5kZXIgYDxyb3V0ZT4uc2VnbWVudHMvYC4gKi9cbiAgc2VnbWVudHM6IFRbXTtcbiAgLyoqIEEgUGFnZXMgUm91dGVyIHJvdXRlJ3MgYHBhZ2VEYXRhYCwgYnVpbHQgYXMgaXRzIGAvX25leHQvZGF0YS9gIHJvdXRlLiAqL1xuICBkYXRhPzogVDtcbn1cblxuY29uc3QgSU5ERVhfU1VGRklYID0gXCIvaW5kZXhcIjtcblxuLyoqXG4gKiBBIFBhZ2VzIFJvdXRlciBkYXRhIHJvdXRlOiBgL19uZXh0L2RhdGEvPGJ1aWxkSWQ+LzxwYWdlPi5qc29uYCwgb3B0aW9uYWxseVxuICogYmVoaW5kIGEgYGJhc2VQYXRoYCAoYG5vcm1hbGl6ZVBhdGhuYW1lYCBpbiBOZXh0LmpzJ3MgYGJ1aWxkLWNvbXBsZXRlYCBwcmVmaXhlc1xuICogZXZlcnkgb3V0cHV0IHBhdGhuYW1lLCB0aGlzIG9uZSBpbmNsdWRlZCkuXG4gKlxuICogQ2FwdHVyZSAxIGlzIHRoYXQgcHJlZml4IGFuZCBjYXB0dXJlIDIgdGhlIHBhZ2UgcGF0aCB3aXRob3V0IGl0cyBgLmpzb25gLCBzb1xuICogYC9wcm9kL19uZXh0L2RhdGEvYWJjMTIzL2Jsb2cvaGVsbG8uanNvbmAgcmVjb21wb3NlcyB0byBgL3Byb2QvYmxvZy9oZWxsb2AuXG4gKi9cbmNvbnN0IFBBR0VTX0RBVEFfUEFUSE5BTUUgPSAvXiguKilcXC9fbmV4dFxcL2RhdGFcXC9bXi9dK1xcLyguKylcXC5qc29uJC87XG5cbi8qKlxuICogQ29sbGVjdCBgY3R4Lm91dHB1dHMucHJlcmVuZGVyc2AgaW50byBvbmUgZW50cnkgcGVyIHJvdXRlLlxuICpcbiAqIE5leHQuanMgZW1pdHMgdXAgdG8gdGhyZWUgc2hhcGVzIHBlciBwcmVyZW5kZXJlZCBBcHAgUm91dGVyIHJvdXRlIOKAlCBgL2Jsb2cvaGVsbG9gLFxuICogYC9ibG9nL2hlbGxvLnJzY2AsIGFuZCBgL2Jsb2cvaGVsbG8uc2VnbWVudHMvKi5zZWdtZW50LnJzY2Ag4oCUIGFuZCBhIGNhY2hlIGVudHJ5XG4gKiBuZWVkcyBhbGwgb2YgdGhlbSB0b2dldGhlciwgc28gdGhleSBoYXZlIHRvIGJlIGdyb3VwZWQgYnkgcm91dGUgYmVmb3JlIGFueXRoaW5nXG4gKiBjYW4gYmUgc2VlZGVkLiBBIFBhZ2VzIFJvdXRlciByb3V0ZSBlbWl0cyB0d286IHRoZSBIVE1MLCBhbmQgaXRzIGBwYWdlRGF0YWAgYXRcbiAqIHRoZSByb3V0ZSdzIGAvX25leHQvZGF0YS88YnVpbGRJZD4vPHBhZ2U+Lmpzb25gIHBhdGhuYW1lXG4gKiAoe0BsaW5rIFBBR0VTX0RBVEFfUEFUSE5BTUV9KS4gVGhhdCBvbmUgaXMgbm90IGEgc3VmZml4IG9mIHRoZSBwYWdlJ3Mgb3duXG4gKiBwYXRobmFtZSwgc28gaXQgaXMgbWF0Y2hlZCByYXRoZXIgdGhhbiBzdHJpcHBlZC5cbiAqXG4gKiBUaGUgb25lIGNhc2UgdGhhdCBpcyBub3QgYSBzdWZmaXggc3RyaXAgaXMgdGhlICoqcm9vdCByb3V0ZSoqLCB3aGljaCBjYW5ub3QgYmVcbiAqIG5hbWVkIGAvLnJzY2A6IGl0cyBwYXlsb2FkcyBhcmUgZW1pdHRlZCB1bmRlciBgL2luZGV4LnJzY2AgYW5kXG4gKiBgL2luZGV4LnNlZ21lbnRzL2Agd2hpbGUgaXRzIEhUTUwgc3RheXMgYXQgYC9gIChvciBhdCB0aGUgYGJhc2VQYXRoYCwgZS5nLlxuICogYC9wcm9kYCBhbmQgYC9wcm9kL2luZGV4LnJzY2ApLiBSZWNvbnN0cnVjdGluZyBuYW1lcyBieSBjb25jYXRlbmF0aW9uIHRoZXJlZm9yZVxuICogc2lsZW50bHkgbG9zZXMgdGhlIGhvbWUgcGFnZSdzIGByc2NEYXRhYCDigJQgYW5kIHdpdGggYSBgYmFzZVBhdGhgIGFsc28gaXRzXG4gKiBgc2VnbWVudERhdGFgLCBiZWNhdXNlIGAvcHJvZGAgYW5kIGAvcHJvZC9pbmRleGAgZ3JvdXAgYXBhcnQuIFRoYXQgaXMgbm90IGFcbiAqIGNvc21ldGljIGdhcDogYGFwcC1wYWdlLXJ1bnRpbWUuanNgIGFuc3dlcnMgYW4gUlNDIHJlcXVlc3QgZm9yIGFuIGVudHJ5IHdpdGggbm9cbiAqIGByc2NEYXRhYCBieSBjaGVja2luZyBgY2FjaGVkRGF0YS5odG1sLmNvbnRlbnRUeXBlYCwgYW5kIHVuZGVyIGBjYWNoZUNvbXBvbmVudHNgXG4gKiBzZW5kcyBhbiBlbXB0eSBgNDA0YC4gRXZlcnkgY2xpZW50LXNpZGUgbmF2aWdhdGlvbiB0byBgL2AgYnJlYWtzLlxuICpcbiAqIFRoZSByZW1hcCBpcyBjb25kaXRpb25hbCByYXRoZXIgdGhhbiB1bmNvbmRpdGlvbmFsIHNvIHRoYXQgYW4gYXBwIHdpdGggYSByZWFsXG4gKiBwYWdlIGF0IGBhcHAvaW5kZXgvcGFnZS50c3hgIOKAlCB3aG9zZSBIVE1MIHByZXJlbmRlciBnZW51aW5lbHkgaXMgYC9pbmRleGAg4oCUIGtlZXBzXG4gKiBpdHMgb3duIGdyb3VwLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JvdXBQcmVyZW5kZXJzPFQgZXh0ZW5kcyB7IHBhdGhuYW1lOiBzdHJpbmcgfT4oXG4gIHByZXJlbmRlcnM6IFRbXSxcbik6IE1hcDxzdHJpbmcsIFByZXJlbmRlclZhcmlhbnRzPFQ+PiB7XG4gIGNvbnN0IGh0bWxQYXRobmFtZXMgPSBuZXcgU2V0KFxuICAgIHByZXJlbmRlcnNcbiAgICAgIC5tYXAoKHApID0+IHAucGF0aG5hbWUpXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAocCkgPT5cbiAgICAgICAgICAhcC5lbmRzV2l0aChcIi5yc2NcIikgJiZcbiAgICAgICAgICAhcC5pbmNsdWRlcyhcIi5zZWdtZW50cy9cIikgJiZcbiAgICAgICAgICAhUEFHRVNfREFUQV9QQVRITkFNRS50ZXN0KHApLFxuICAgICAgKSxcbiAgKTtcbiAgY29uc3QgZ3JvdXBzID0gbmV3IE1hcDxzdHJpbmcsIFByZXJlbmRlclZhcmlhbnRzPFQ+PigpO1xuXG4gIGNvbnN0IHZhcmlhbnRzRm9yID0gKGJhc2U6IHN0cmluZyk6IFByZXJlbmRlclZhcmlhbnRzPFQ+ID0+IHtcbiAgICBsZXQgdmFyaWFudHMgPSBncm91cHMuZ2V0KGJhc2UpO1xuICAgIGlmICghdmFyaWFudHMpIHtcbiAgICAgIHZhcmlhbnRzID0geyBzZWdtZW50czogW10gfTtcbiAgICAgIGdyb3Vwcy5zZXQoYmFzZSwgdmFyaWFudHMpO1xuICAgIH1cbiAgICByZXR1cm4gdmFyaWFudHM7XG4gIH07XG5cbiAgLyoqIGAvaW5kZXgucnNjYCBiZWxvbmdzIHRvIGAvYCwgYC9wcm9kL2luZGV4LnJzY2AgdG8gYC9wcm9kYC4gKi9cbiAgY29uc3Qgcm91dGVPZiA9IChiYXNlOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgIGlmIChiYXNlLmVuZHNXaXRoKElOREVYX1NVRkZJWCkgJiYgIWh0bWxQYXRobmFtZXMuaGFzKGJhc2UpKSB7XG4gICAgICBjb25zdCBwYXJlbnQgPSBiYXNlLnNsaWNlKDAsIC1JTkRFWF9TVUZGSVgubGVuZ3RoKSB8fCBcIi9cIjtcbiAgICAgIGlmIChodG1sUGF0aG5hbWVzLmhhcyhwYXJlbnQpKSB7XG4gICAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBiYXNlO1xuICB9O1xuXG4gIGZvciAoY29uc3QgcHJlcmVuZGVyIG9mIHByZXJlbmRlcnMpIHtcbiAgICBjb25zdCB7IHBhdGhuYW1lIH0gPSBwcmVyZW5kZXI7XG4gICAgY29uc3QgZGF0YVJvdXRlID0gUEFHRVNfREFUQV9QQVRITkFNRS5leGVjKHBhdGhuYW1lKTtcbiAgICBpZiAoZGF0YVJvdXRlKSB7XG4gICAgICB2YXJpYW50c0Zvcihyb3V0ZU9mKGAke2RhdGFSb3V0ZVsxXX0vJHtkYXRhUm91dGVbMl19YCkpLmRhdGEgPSBwcmVyZW5kZXI7XG4gICAgfSBlbHNlIGlmIChwYXRobmFtZS5pbmNsdWRlcyhcIi5zZWdtZW50cy9cIikpIHtcbiAgICAgIHZhcmlhbnRzRm9yKHJvdXRlT2YocGF0aG5hbWUuc3BsaXQoXCIuc2VnbWVudHMvXCIpWzBdKSkuc2VnbWVudHMucHVzaChcbiAgICAgICAgcHJlcmVuZGVyLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHBhdGhuYW1lLmVuZHNXaXRoKFwiLnJzY1wiKSkge1xuICAgICAgdmFyaWFudHNGb3Iocm91dGVPZihwYXRobmFtZS5zbGljZSgwLCAtXCIucnNjXCIubGVuZ3RoKSkpLnJzYyA9IHByZXJlbmRlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyaWFudHNGb3IocGF0aG5hbWUpLmh0bWwgPSBwcmVyZW5kZXI7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGdyb3Vwcztcbn1cblxuLyoqXG4gKiBIZWFkZXJzIHRoYXQgbXVzdCBub3QgYmUgc2VlZGVkIGludG8gYW4gYEFQUF9QQUdFYCBjYWNoZSBlbnRyeSwgZXZlbiB0aG91Z2ggdGhlXG4gKiBhZGFwdGVyIG91dHB1dCBsaXN0cyB0aGVtIGluIGBmYWxsYmFjay5pbml0aWFsSGVhZGVyc2AuXG4gKlxuICogYGluaXRpYWxIZWFkZXJzYCBkZXNjcmliZXMgaG93IGEgcGxhdGZvcm0gc2hvdWxkIHNlcnZlIHRoZSBwcmVyZW5kZXJlZCAqZmlsZSpcbiAqIHN0cmFpZ2h0IG9mZiBhIENETi4gQSBjYWNoZSBlbnRyeSBpcyBhIGRpZmZlcmVudCB0aGluZzogYGFwcC1wYWdlLXJ1bnRpbWUuanNgXG4gKiBgYXBwZW5kSGVhZGVyYHMgYGNhY2hlZERhdGEuaGVhZGVyc2Agb250byB0aGUgcmVzcG9uc2UgYW5kICp0aGVuKiBzZXJ2ZXMgdGhlXG4gKiB2YXJpYW50IHRoZSByZXF1ZXN0IGFjdHVhbGx5IGFza2VkIGZvciwgc28gYW55dGhpbmcgcHJlc2VudGF0aW9uYWwgaW4gdGhlcmUgaXNcbiAqIGVpdGhlciB3cm9uZyBvciBkb3VibGVkLiBBdCByZXF1ZXN0IHRpbWUgTmV4dC5qcyBzdG9yZXMgb25seSB3aGF0IHRoZSByZW5kZXJcbiAqIHB1dCBpbiBgbWV0YWRhdGEuaGVhZGVyc2Ag4oCUIGB4LW5leHRqcy1zdGFsZS10aW1lYCwgYHgtbmV4dC1jYWNoZS10YWdzYCwgYW5kXG4gKiB3aGF0ZXZlciB0aGUgYXBwIHNldCB0aHJvdWdoIGBoZWFkZXJzKClgL2Bjb29raWVzKClgIOKAlCBhbmQgbmV2ZXIgdGhlc2UgZm91ci5cbiAqXG4gKiBgY29udGVudC10eXBlYCBpcyB0aGUgb25lIHRoYXQgYWN0dWFsbHkgYnJlYWtzLiBgc2VuZC1wYXlsb2FkLmpzYCBzZXRzIHRoZSB0eXBlXG4gKiBvbmx5IHdoZW4gdGhlIHJlc3BvbnNlIGRvZXMgbm90IGFscmVhZHkgaGF2ZSBvbmVcbiAqIChgaWYgKCFyZXMuZ2V0SGVhZGVyKCdDb250ZW50LVR5cGUnKSAmJiByZXN1bHQuY29udGVudFR5cGUpYCksIHNvIGEgc2VlZGVkXG4gKiBgdGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04YCBtYWtlcyBldmVyeSBSU0MgcmVxdWVzdCB0byBhIHByZXJlbmRlcmVkIHBhZ2UgYW5zd2VyXG4gKiB0aGUgZmxpZ2h0IHBheWxvYWQgbGFiZWxlZCBhcyBIVE1MLiBUaGUgY2xpZW50IHJvdXRlciByZWplY3RzIHRoYXQsIGFuZCBzbyBkb2VzXG4gKiBOZXh0LmpzIGl0c2VsZjogYGNyZWF0ZVJlZGlyZWN0UmVuZGVyUmVzdWx0YCBjaGVja3MgdGhlIGNvbnRlbnQgdHlwZSBvZiB0aGVcbiAqIHN1Yi1yZXNwb25zZSBpdCBmZXRjaGVzIHRvIHN0cmVhbSBhbiBhY3Rpb24gYHJlZGlyZWN0KClgLCBhbmQgb24gYSBtaXNtYXRjaFxuICogY2FuY2VscyB0aGUgYm9keSBhbmQgcmV0dXJucyBhbiBlbXB0eSByZXN1bHQuXG4gKlxuICogYHZhcnlgLCBgeC1uZXh0anMtcHJlcmVuZGVyYCwgYW5kIGB4LW5leHRqcy1wb3N0cG9uZWRgIGFyZSBhbGwgc2V0IGJ5IHRoZVxuICogZW50cnlwb2ludCBpdHNlbGYsIHNvIHNlZWRpbmcgdGhlbSBvbmx5IHByb2R1Y2VzIHR3byBvZiBlYWNoLlxuICpcbiAqIGBBUFBfUk9VVEVgIGVudHJpZXMgYXJlIGRlbGliZXJhdGVseSAqbm90KiBmaWx0ZXJlZDogYSByb3V0ZSBoYW5kbGVyJ3NcbiAqIGBjb250ZW50LXR5cGVgIGlzIHBhcnQgb2YgaXRzIGNhY2hlZCByZXNwb25zZSwgYW5kIGBhcHAtcm91dGUuanNgIHJlcGxheXMgdGhvc2VcbiAqIGhlYWRlcnMgdmVyYmF0aW0uXG4gKi9cbmNvbnN0IE5PTl9DQUNIRUFCTEVfQVBQX1BBR0VfSEVBREVSUyA9IG5ldyBTZXQoW1xuICBcImNvbnRlbnQtdHlwZVwiLFxuICBcInZhcnlcIixcbiAgXCJ4LW5leHRqcy1wcmVyZW5kZXJcIixcbiAgXCJ4LW5leHRqcy1wb3N0cG9uZWRcIixcbl0pO1xuXG4vKiogU2VlIHtAbGluayBOT05fQ0FDSEVBQkxFX0FQUF9QQUdFX0hFQURFUlN9LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcFBhZ2VDYWNoZUhlYWRlcnM8VD4oXG4gIGluaXRpYWxIZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBUPixcbik6IFJlY29yZDxzdHJpbmcsIFQ+IHtcbiAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgVD4gPSB7fTtcbiAgZm9yIChjb25zdCBbbmFtZSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGluaXRpYWxIZWFkZXJzKSkge1xuICAgIGlmICghTk9OX0NBQ0hFQUJMRV9BUFBfUEFHRV9IRUFERVJTLmhhcyhuYW1lLnRvTG93ZXJDYXNlKCkpKSB7XG4gICAgICBoZWFkZXJzW25hbWVdID0gdmFsdWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBoZWFkZXJzO1xufVxuXG4vKiogYE5FWFRfQ0FDSEVfVEFHU19IRUFERVJgLCBpbmxpbmVkIHNvIHRoaXMgZmlsZSBpbXBvcnRzIG5vIE5leHQuanMgaW50ZXJuYWxzLiAqL1xuY29uc3QgTkVYVF9DQUNIRV9UQUdTX0hFQURFUiA9IFwieC1uZXh0LWNhY2hlLXRhZ3NcIjtcblxuLyoqXG4gKiBUaGUgdGFncyBhIGNhY2hlIHZhbHVlJ3MgcmVuZGVyIHdhcyB0YWdnZWQgd2l0aCwgYXMgTmV4dC5qcyByZWNvcmRzIHRoZW06IGluXG4gKiBpdHMgYHgtbmV4dC1jYWNoZS10YWdzYCBoZWFkZXIsIGNvbW1hIHNlcGFyYXRlZCwgaW5jbHVkaW5nIHRoZSBpbXBsaWNpdFxuICogYF9OX1RfL+KApmAgcGF0aCBjaGFpbiBgcmV2YWxpZGF0ZVBhdGhgIHVzZXMuIE9uZSBwYXJzZXIgZm9yIHRoZSBidWlsZCdzIHRhZ1xuICogbWFuaWZlc3QgYW5kIHRoZSBydW50aW1lJ3MgbWFwcGluZyByb3dzLCB3aGljaCBoYXZlIHRvIGFncmVlLlxuICpcbiAqIGB2YWx1ZWAgaXMgYHVua25vd25gIGJlY2F1c2UgaXQgYXJyaXZlcyBib3RoIGFzIGEgc3RvcmVkIGVudHJ5IHJlYWQgYmFjayBmcm9tXG4gKiBTMyBhbmQgYXMgdGhlIGBJbmNyZW1lbnRhbENhY2hlVmFsdWVgIHVuaW9uOyBvbmx5IHNvbWUgbWVtYmVycyBoYXZlIGhlYWRlcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoZWFkZXJUYWdzKHZhbHVlOiB1bmtub3duKTogc3RyaW5nW10ge1xuICBjb25zdCBoZWFkZXJzID0gKHZhbHVlIGFzIHsgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+IH0gfCBudWxsKVxuICAgID8uaGVhZGVycztcbiAgY29uc3QgaGVhZGVyID0gaGVhZGVycz8uW05FWFRfQ0FDSEVfVEFHU19IRUFERVJdO1xuICByZXR1cm4gdHlwZW9mIGhlYWRlciA9PT0gXCJzdHJpbmdcIiA/IGhlYWRlci5zcGxpdChcIixcIikuZmlsdGVyKEJvb2xlYW4pIDogW107XG59XG5cbi8qKlxuICogTmFtZSBvZiB0aGUgZmlsZSB0aGUgYWRhcHRlciB3cml0ZXMgaW50byB0aGUgaW5pdCBjYWNoZSBkaXJlY3RvcnkgbWFwcGluZyBlYWNoXG4gKiBjYWNoZSB0YWcgdG8gdGhlIGNhY2hlIGtleXMgb2YgdGhlIGJ1aWxkLXRpbWUgcHJlcmVuZGVycyBjYXJyeWluZyBpdC5cbiAqXG4gKiBJdCByaWRlcyB0byBTMyB3aXRoIHRoZSByZXN0IG9mIHRoZSBpbml0IGNhY2hlLCBhbmQgYFMzQ2FjaGVIYW5kbGVyYCdzXG4gKiBgcmV2YWxpZGF0ZVRhZ2AgcmVhZHMgaXQgYWxvbmdzaWRlIHRoZSBgdGFnI2NhY2hlS2V5YCByb3dzIGEgcnVudGltZSBgc2V0YFxuICogd3JpdGVzLiBXaXRob3V0IGl0IGByZXZhbGlkYXRlVGFnYCBrbm93cyBhIHByZXJlbmRlciBpcyBzdGFsZSAoc2VlXG4gKiBgY2hlY2tJZlJldmFsaWRhdGVkYCkgYnV0IG5vdCB3aGljaCBDbG91ZEZyb250IHBhdGhzIHRvIGludmFsaWRhdGUsIHNvIHRoZSBDRE5cbiAqIGtlZXBzIHNlcnZpbmcgdGhlIG9sZCByZXNwb25zZSB1bnRpbCBpdHMgVFRMIGV4cGlyZXMgLSBhIHllYXIsIGZvciBhXG4gKiBwcmVyZW5kZXIuXG4gKlxuICogVGhlIGxlYWRpbmcgdW5kZXJzY29yZSBrZWVwcyBpdCBjbGVhciBvZiBjYWNoZSBrZXlzLCB3aGljaCBhcmUgcm91dGUgcGF0aHMuXG4gKi9cbmV4cG9ydCBjb25zdCBJTklUX0NBQ0hFX1RBR19NQU5JRkVTVCA9IFwiX2Nkay1uZXh0anMtdGFnLW1hbmlmZXN0Lmpzb25cIjtcblxuLyoqIENvbnRlbnRzIG9mIHtAbGluayBJTklUX0NBQ0hFX1RBR19NQU5JRkVTVH06IHRhZyAtPiBpbml0IGNhY2hlIGtleXMuICovXG5leHBvcnQgdHlwZSBJbml0Q2FjaGVUYWdNYW5pZmVzdCA9IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPjtcblxuLyoqXG4gKiBIZWxwZXIgdG8gc2FmZWx5IGV4dHJhY3QgdGFncyBmcm9tIGNvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRhZ3MoXG4gIGN0eDogU2V0SW5jcmVtZW50YWxGZXRjaENhY2hlQ29udGV4dCB8IFNldEluY3JlbWVudGFsUmVzcG9uc2VDYWNoZUNvbnRleHQsXG4pOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBcInRhZ3NcIiBpbiBjdHggPyBjdHgudGFncyA6IHVuZGVmaW5lZDtcbn1cbiJdfQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const cache_utils_1 = require("./cache-utils");
|
|
4
|
+
describe("prerenderPathToCacheKey", () => {
|
|
5
|
+
it("drops the leading slash", () => {
|
|
6
|
+
expect((0, cache_utils_1.prerenderPathToCacheKey)("/ssg/1", "")).toBe("ssg/1");
|
|
7
|
+
});
|
|
8
|
+
it("maps the root route to index", () => {
|
|
9
|
+
expect((0, cache_utils_1.prerenderPathToCacheKey)("/", "")).toBe("index");
|
|
10
|
+
});
|
|
11
|
+
/**
|
|
12
|
+
* The regression that made every prerender a MISS on a deployment with a
|
|
13
|
+
* `basePath`: the seed wrote `prod/ssg/1.json` while the server, which sees the
|
|
14
|
+
* path only after Next.js has stripped `basePath`, asked for `ssg/1.json`.
|
|
15
|
+
*/
|
|
16
|
+
it("strips the app's basePath", () => {
|
|
17
|
+
expect((0, cache_utils_1.prerenderPathToCacheKey)("/prod/ssg/1", "/prod")).toBe("ssg/1");
|
|
18
|
+
});
|
|
19
|
+
it("maps the basePath root to index", () => {
|
|
20
|
+
expect((0, cache_utils_1.prerenderPathToCacheKey)("/prod", "/prod")).toBe("index");
|
|
21
|
+
});
|
|
22
|
+
it("only strips basePath on a path boundary", () => {
|
|
23
|
+
expect((0, cache_utils_1.prerenderPathToCacheKey)("/production/1", "/prod")).toBe("production/1");
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
describe("groupPrerenders", () => {
|
|
27
|
+
const at = (...pathnames) => pathnames.map((pathname) => ({
|
|
28
|
+
pathname,
|
|
29
|
+
}));
|
|
30
|
+
it("groups a route's html, rsc and segment outputs together", () => {
|
|
31
|
+
const groups = (0, cache_utils_1.groupPrerenders)(at("/blog/hello", "/blog/hello.rsc", "/blog/hello.segments/$c$.segment.rsc", "/blog/hello.segments/$c$/__PAGE__.segment.rsc"));
|
|
32
|
+
expect(groups.size).toBe(1);
|
|
33
|
+
const variants = groups.get("/blog/hello");
|
|
34
|
+
expect(variants?.html?.pathname).toBe("/blog/hello");
|
|
35
|
+
expect(variants?.rsc?.pathname).toBe("/blog/hello.rsc");
|
|
36
|
+
expect(variants?.segments).toHaveLength(2);
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* The regression: the root route's HTML is emitted as `/` but its flight payload
|
|
40
|
+
* as `/index.rsc`, so grouping by a reconstructed `${route}.rsc` left `/` with no
|
|
41
|
+
* `rscData` and every client-side navigation to the home page 404'd.
|
|
42
|
+
*/
|
|
43
|
+
it("gives the root route the /index.rsc payload", () => {
|
|
44
|
+
const groups = (0, cache_utils_1.groupPrerenders)(at("/", "/index.rsc", "/index.segments/$c$.segment.rsc"));
|
|
45
|
+
expect(Array.from(groups.keys())).toEqual(["/"]);
|
|
46
|
+
expect(groups.get("/")?.rsc?.pathname).toBe("/index.rsc");
|
|
47
|
+
expect(groups.get("/")?.segments).toHaveLength(1);
|
|
48
|
+
});
|
|
49
|
+
/** With a `basePath` the split is `/prod` vs `/prod/index`. */
|
|
50
|
+
it("gives the basePath root its /index.rsc payload", () => {
|
|
51
|
+
const groups = (0, cache_utils_1.groupPrerenders)(at("/prod", "/prod/index.rsc", "/prod/index.segments/$c$.segment.rsc"));
|
|
52
|
+
expect(Array.from(groups.keys())).toEqual(["/prod"]);
|
|
53
|
+
expect(groups.get("/prod")?.rsc?.pathname).toBe("/prod/index.rsc");
|
|
54
|
+
expect(groups.get("/prod")?.segments).toHaveLength(1);
|
|
55
|
+
});
|
|
56
|
+
/** An app with a real `app/index/page.tsx` keeps its own group. */
|
|
57
|
+
it("leaves a genuine /index route alone", () => {
|
|
58
|
+
const groups = (0, cache_utils_1.groupPrerenders)(at("/", "/index", "/index.rsc"));
|
|
59
|
+
expect(Array.from(groups.keys()).sort()).toEqual(["/", "/index"]);
|
|
60
|
+
expect(groups.get("/")?.rsc).toBeUndefined();
|
|
61
|
+
expect(groups.get("/index")?.rsc?.pathname).toBe("/index.rsc");
|
|
62
|
+
});
|
|
63
|
+
/** `/nested/index.rsc` with no `/nested` HTML is its own route, not a remap. */
|
|
64
|
+
it("only remaps when the parent really is a prerendered route", () => {
|
|
65
|
+
const groups = (0, cache_utils_1.groupPrerenders)(at("/nested/index.rsc"));
|
|
66
|
+
expect(Array.from(groups.keys())).toEqual(["/nested/index"]);
|
|
67
|
+
});
|
|
68
|
+
it("keeps segments whose route has no other output", () => {
|
|
69
|
+
const groups = (0, cache_utils_1.groupPrerenders)(at("/ppr.segments/$c$.segment.rsc"));
|
|
70
|
+
expect(groups.get("/ppr")?.segments).toHaveLength(1);
|
|
71
|
+
expect(groups.get("/ppr")?.html).toBeUndefined();
|
|
72
|
+
});
|
|
73
|
+
/**
|
|
74
|
+
* A Pages Router route's `pageData` lives at a pathname of its own rather than
|
|
75
|
+
* at a suffix of the page's, so an unmatched one would become a group named
|
|
76
|
+
* `/_next/data/...` - which gets no cache kind, and so silently drops the data
|
|
77
|
+
* every seeded entry needs.
|
|
78
|
+
*/
|
|
79
|
+
it("attaches a Pages Router route's /_next/data output", () => {
|
|
80
|
+
const groups = (0, cache_utils_1.groupPrerenders)(at("/blog/hello", "/_next/data/build-abc123/blog/hello.json"));
|
|
81
|
+
expect(Array.from(groups.keys())).toEqual(["/blog/hello"]);
|
|
82
|
+
expect(groups.get("/blog/hello")?.data?.pathname).toBe("/_next/data/build-abc123/blog/hello.json");
|
|
83
|
+
});
|
|
84
|
+
/** The `fallback: true` template, whose data route has no file behind it. */
|
|
85
|
+
it("attaches the data output of a dynamic route's fallback template", () => {
|
|
86
|
+
const groups = (0, cache_utils_1.groupPrerenders)(at("/[slug]", "/_next/data/build-abc123/[slug].json"));
|
|
87
|
+
expect(Array.from(groups.keys())).toEqual(["/[slug]"]);
|
|
88
|
+
expect(groups.get("/[slug]")?.data?.pathname).toBe("/_next/data/build-abc123/[slug].json");
|
|
89
|
+
});
|
|
90
|
+
/** `/index.json` is the root page's data route, the same remap as `/index.rsc`. */
|
|
91
|
+
it("gives the root route its /index.json data output", () => {
|
|
92
|
+
const groups = (0, cache_utils_1.groupPrerenders)(at("/prod", "/prod/_next/data/build-abc123/index.json"));
|
|
93
|
+
expect(Array.from(groups.keys())).toEqual(["/prod"]);
|
|
94
|
+
expect(groups.get("/prod")?.data?.pathname).toBe("/prod/_next/data/build-abc123/index.json");
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
describe("appPageCacheHeaders", () => {
|
|
98
|
+
/** Exactly what `onBuildComplete` is handed for a prerendered app page. */
|
|
99
|
+
const initialHeaders = {
|
|
100
|
+
vary: "rsc, next-router-state-tree, next-router-prefetch, next-router-segment-prefetch",
|
|
101
|
+
"content-type": "text/html; charset=utf-8",
|
|
102
|
+
"x-nextjs-stale-time": "300",
|
|
103
|
+
"x-nextjs-prerender": "1",
|
|
104
|
+
"x-next-cache-tags": "_N_T_/layout,_N_T_/page,_N_T_/,_N_T_/index",
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* The regression: a seeded `content-type: text/html` survives into the response
|
|
108
|
+
* and `send-payload.js` will not overwrite it, so an RSC request to a
|
|
109
|
+
* prerendered page gets the flight payload labeled as HTML.
|
|
110
|
+
*/
|
|
111
|
+
it("drops content-type, which would mislabel every RSC response", () => {
|
|
112
|
+
expect((0, cache_utils_1.appPageCacheHeaders)(initialHeaders)).not.toHaveProperty("content-type");
|
|
113
|
+
});
|
|
114
|
+
it("keeps the headers a render would really have stored", () => {
|
|
115
|
+
expect((0, cache_utils_1.appPageCacheHeaders)(initialHeaders)).toEqual({
|
|
116
|
+
"x-nextjs-stale-time": "300",
|
|
117
|
+
"x-next-cache-tags": "_N_T_/layout,_N_T_/page,_N_T_/,_N_T_/index",
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
it("drops the headers the entrypoint sets itself, which would double up", () => {
|
|
121
|
+
const headers = (0, cache_utils_1.appPageCacheHeaders)({
|
|
122
|
+
...initialHeaders,
|
|
123
|
+
"x-nextjs-postponed": "1",
|
|
124
|
+
});
|
|
125
|
+
expect(Object.keys(headers)).not.toContain("vary");
|
|
126
|
+
expect(Object.keys(headers)).not.toContain("x-nextjs-prerender");
|
|
127
|
+
expect(Object.keys(headers)).not.toContain("x-nextjs-postponed");
|
|
128
|
+
});
|
|
129
|
+
it("matches case-insensitively", () => {
|
|
130
|
+
expect((0, cache_utils_1.appPageCacheHeaders)({ "Content-Type": "text/html" })).toEqual({});
|
|
131
|
+
});
|
|
132
|
+
it("passes through anything the app set itself", () => {
|
|
133
|
+
expect((0, cache_utils_1.appPageCacheHeaders)({ "x-custom": "1", "set-cookie": "a=b" })).toEqual({ "x-custom": "1", "set-cookie": "a=b" });
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe("serializeCacheValue / parseCacheValue", () => {
|
|
137
|
+
it("round-trips a Buffer", () => {
|
|
138
|
+
const value = { rscData: Buffer.from("hello, cache") };
|
|
139
|
+
const restored = (0, cache_utils_1.parseCacheValue)((0, cache_utils_1.serializeCacheValue)(value));
|
|
140
|
+
expect(Buffer.isBuffer(restored.rscData)).toBe(true);
|
|
141
|
+
expect(restored.rscData.toString()).toBe("hello, cache");
|
|
142
|
+
});
|
|
143
|
+
it("round-trips bytes that are not valid UTF-8", () => {
|
|
144
|
+
const value = Buffer.from([0x00, 0xff, 0xfe, 0x80, 0x7f]);
|
|
145
|
+
const restored = (0, cache_utils_1.parseCacheValue)((0, cache_utils_1.serializeCacheValue)({ value })).value;
|
|
146
|
+
expect(restored.equals(value)).toBe(true);
|
|
147
|
+
});
|
|
148
|
+
it("round-trips a Map, including Buffers inside it", () => {
|
|
149
|
+
const value = new Map([["/_index", Buffer.from("segment")]]);
|
|
150
|
+
const restored = (0, cache_utils_1.parseCacheValue)((0, cache_utils_1.serializeCacheValue)({ value })).value;
|
|
151
|
+
expect(restored).toBeInstanceOf(Map);
|
|
152
|
+
expect(restored.get("/_index").toString()).toBe("segment");
|
|
153
|
+
});
|
|
154
|
+
/**
|
|
155
|
+
* base64, not the array of per-byte integers `Buffer.toJSON()` produces: that
|
|
156
|
+
* array is ~3 bytes of JSON per byte of payload *and* makes `JSON.parse`'s
|
|
157
|
+
* reviver run once per element, which cost 4.8s of Lambda time to answer a
|
|
158
|
+
* single 1 MiB segment prefetch on a real deployment.
|
|
159
|
+
*/
|
|
160
|
+
it("writes a Buffer as base64 rather than an array of bytes", () => {
|
|
161
|
+
const json = (0, cache_utils_1.serializeCacheValue)({ rscData: Buffer.from("hello") });
|
|
162
|
+
expect(JSON.parse(json).rscData).toEqual({
|
|
163
|
+
__type: "Buffer",
|
|
164
|
+
base64: "aGVsbG8=",
|
|
165
|
+
});
|
|
166
|
+
// Comfortably under the ~5 bytes per payload byte an integer array costs.
|
|
167
|
+
expect(json.length).toBeLessThan(60);
|
|
168
|
+
});
|
|
169
|
+
it("still reads the integer-array format an older build wrote", () => {
|
|
170
|
+
const legacy = JSON.stringify({
|
|
171
|
+
ours: { __type: "Buffer", data: [104, 105] },
|
|
172
|
+
nodes: { type: "Buffer", data: [104, 105] },
|
|
173
|
+
});
|
|
174
|
+
const restored = (0, cache_utils_1.parseCacheValue)(legacy);
|
|
175
|
+
expect(restored.ours.toString()).toBe("hi");
|
|
176
|
+
expect(restored.nodes.toString()).toBe("hi");
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtdXRpbHMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVyL2NhY2hlLXV0aWxzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwrQ0FNdUI7QUFFdkIsUUFBUSxDQUFDLHlCQUF5QixFQUFFLEdBQUcsRUFBRTtJQUN2QyxFQUFFLENBQUMseUJBQXlCLEVBQUUsR0FBRyxFQUFFO1FBQ2pDLE1BQU0sQ0FBQyxJQUFBLHFDQUF1QixFQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM5RCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyw4QkFBOEIsRUFBRSxHQUFHLEVBQUU7UUFDdEMsTUFBTSxDQUFDLElBQUEscUNBQXVCLEVBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3pELENBQUMsQ0FBQyxDQUFDO0lBRUg7Ozs7T0FJRztJQUNILEVBQUUsQ0FBQywyQkFBMkIsRUFBRSxHQUFHLEVBQUU7UUFDbkMsTUFBTSxDQUFDLElBQUEscUNBQXVCLEVBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3hFLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLGlDQUFpQyxFQUFFLEdBQUcsRUFBRTtRQUN6QyxNQUFNLENBQUMsSUFBQSxxQ0FBdUIsRUFBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbEUsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMseUNBQXlDLEVBQUUsR0FBRyxFQUFFO1FBQ2pELE1BQU0sQ0FBQyxJQUFBLHFDQUF1QixFQUFDLGVBQWUsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDNUQsY0FBYyxD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bnRlbnQiOlsiaW1wb3J0IHtcbiAgYXBwUGFnZUNhY2hlSGVhZGVycyxcbiAgZ3JvdXBQcmVyZW5kZXJzLFxuICBwYXJzZUNhY2hlVmFsdWUsXG4gIHByZXJlbmRlclBhdGhUb0NhY2hlS2V5LFxuICBzZXJpYWxpemVDYWNoZVZhbHVlLFxufSBmcm9tIFwiLi9jYWNoZS11dGlsc1wiO1xuXG5kZXNjcmliZShcInByZXJlbmRlclBhdGhUb0NhY2hlS2V5XCIsICgpID0+IHtcbiAgaXQoXCJkcm9wcyB0aGUgbGVhZGluZyBzbGFzaFwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KHByZXJlbmRlclBhdGhUb0NhY2hlS2V5KFwiL3NzZy8xXCIsIFwiXCIpKS50b0JlKFwic3NnLzFcIik7XG4gIH0pO1xuXG4gIGl0KFwibWFwcyB0aGUgcm9vdCByb3V0ZSB0byBpbmRleFwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KHByZXJlbmRlclBhdGhUb0NhY2hlS2V5KFwiL1wiLCBcIlwiKSkudG9CZShcImluZGV4XCIpO1xuICB9KTtcblxuICAvKipcbiAgICogVGhlIHJlZ3Jlc3Npb24gdGhhdCBtYWRlIGV2ZXJ5IHByZXJlbmRlciBhIE1JU1Mgb24gYSBkZXBsb3ltZW50IHdpdGggYVxuICAgKiBgYmFzZVBhdGhgOiB0aGUgc2VlZCB3cm90ZSBgcHJvZC9zc2cvMS5qc29uYCB3aGlsZSB0aGUgc2VydmVyLCB3aGljaCBzZWVzIHRoZVxuICAgKiBwYXRoIG9ubHkgYWZ0ZXIgTmV4dC5qcyBoYXMgc3RyaXBwZWQgYGJhc2VQYXRoYCwgYXNrZWQgZm9yIGBzc2cvMS5qc29uYC5cbiAgICovXG4gIGl0KFwic3RyaXBzIHRoZSBhcHAncyBiYXNlUGF0aFwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KHByZXJlbmRlclBhdGhUb0NhY2hlS2V5KFwiL3Byb2Qvc3NnLzFcIiwgXCIvcHJvZFwiKSkudG9CZShcInNzZy8xXCIpO1xuICB9KTtcblxuICBpdChcIm1hcHMgdGhlIGJhc2VQYXRoIHJvb3QgdG8gaW5kZXhcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChwcmVyZW5kZXJQYXRoVG9DYWNoZUtleShcIi9wcm9kXCIsIFwiL3Byb2RcIikpLnRvQmUoXCJpbmRleFwiKTtcbiAgfSk7XG5cbiAgaXQoXCJvbmx5IHN0cmlwcyBiYXNlUGF0aCBvbiBhIHBhdGggYm91bmRhcnlcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChwcmVyZW5kZXJQYXRoVG9DYWNoZUtleShcIi9wcm9kdWN0aW9uLzFcIiwgXCIvcHJvZFwiKSkudG9CZShcbiAgICAgIFwicHJvZHVjdGlvbi8xXCIsXG4gICAgKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoXCJncm91cFByZXJlbmRlcnNcIiwgKCkgPT4ge1xuICBjb25zdCBhdCA9ICguLi5wYXRobmFtZXM6IHN0cmluZ1tdKSA9PlxuICAgIHBhdGhuYW1lcy5tYXAoKHBhdGhuYW1lKSA9PiAoe1xuICAgICAgcGF0aG5hbWUsXG4gICAgfSkpO1xuXG4gIGl0KFwiZ3JvdXBzIGEgcm91dGUncyBodG1sLCByc2MgYW5kIHNlZ21lbnQgb3V0cHV0cyB0b2dldGhlclwiLCAoKSA9PiB7XG4gICAgY29uc3QgZ3JvdXBzID0gZ3JvdXBQcmVyZW5kZXJzKFxuICAgICAgYXQoXG4gICAgICAgIFwiL2Jsb2cvaGVsbG9cIixcbiAgICAgICAgXCIvYmxvZy9oZWxsby5yc2NcIixcbiAgICAgICAgXCIvYmxvZy9oZWxsby5zZWdtZW50cy8kYyQuc2VnbWVudC5yc2NcIixcbiAgICAgICAgXCIvYmxvZy9oZWxsby5zZWdtZW50cy8kYyQvX19QQUdFX18uc2VnbWVudC5yc2NcIixcbiAgICAgICksXG4gICAgKTtcbiAgICBleHBlY3QoZ3JvdXBzLnNpemUpLnRvQmUoMSk7XG4gICAgY29uc3QgdmFyaWFudHMgPSBncm91cHMuZ2V0KFwiL2Jsb2cvaGVsbG9cIik7XG4gICAgZXhwZWN0KHZhcmlhbnRzPy5odG1sPy5wYXRobmFtZSkudG9CZShcIi9ibG9nL2hlbGxvXCIpO1xuICAgIGV4cGVjdCh2YXJpYW50cz8ucnNjPy5wYXRobmFtZSkudG9CZShcIi9ibG9nL2hlbGxvLnJzY1wiKTtcbiAgICBleHBlY3QodmFyaWFudHM/LnNlZ21lbnRzKS50b0hhdmVMZW5ndGgoMik7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVncmVzc2lvbjogdGhlIHJvb3Qgcm91dGUncyBIVE1MIGlzIGVtaXR0ZWQgYXMgYC9gIGJ1dCBpdHMgZmxpZ2h0IHBheWxvYWRcbiAgICogYXMgYC9pbmRleC5yc2NgLCBzbyBncm91cGluZyBieSBhIHJlY29uc3RydWN0ZWQgYCR7cm91dGV9LnJzY2AgbGVmdCBgL2Agd2l0aCBub1xuICAgKiBgcnNjRGF0YWAgYW5kIGV2ZXJ5IGNsaWVudC1zaWRlIG5hdmlnYXRpb24gdG8gdGhlIGhvbWUgcGFnZSA0MDQnZC5cbiAgICovXG4gIGl0KFwiZ2l2ZXMgdGhlIHJvb3Qgcm91dGUgdGhlIC9pbmRleC5yc2MgcGF5bG9hZFwiLCAoKSA9PiB7XG4gICAgY29uc3QgZ3JvdXBzID0gZ3JvdXBQcmVyZW5kZXJzKFxuICAgICAgYXQoXCIvXCIsIFwiL2luZGV4LnJzY1wiLCBcIi9pbmRleC5zZWdtZW50cy8kYyQuc2VnbWVudC5yc2NcIiksXG4gICAgKTtcbiAgICBleHBlY3QoQXJyYXkuZnJvbShncm91cHMua2V5cygpKSkudG9FcXVhbChbXCIvXCJdKTtcbiAgICBleHBlY3QoZ3JvdXBzLmdldChcIi9cIik/LnJzYz8ucGF0aG5hbWUpLnRvQmUoXCIvaW5kZXgucnNjXCIpO1xuICAgIGV4cGVjdChncm91cHMuZ2V0KFwiL1wiKT8uc2VnbWVudHMpLnRvSGF2ZUxlbmd0aCgxKTtcbiAgfSk7XG5cbiAgLyoqIFdpdGggYSBgYmFzZVBhdGhgIHRoZSBzcGxpdCBpcyBgL3Byb2RgIHZzIGAvcHJvZC9pbmRleGAuICovXG4gIGl0KFwiZ2l2ZXMgdGhlIGJhc2VQYXRoIHJvb3QgaXRzIC9pbmRleC5yc2MgcGF5bG9hZFwiLCAoKSA9PiB7XG4gICAgY29uc3QgZ3JvdXBzID0gZ3JvdXBQcmVyZW5kZXJzKFxuICAgICAgYXQoXCIvcHJvZFwiLCBcIi9wcm9kL2luZGV4LnJzY1wiLCBcIi9wcm9kL2luZGV4LnNlZ21lbnRzLyRjJC5zZWdtZW50LnJzY1wiKSxcbiAgICApO1xuICAgIGV4cGVjdChBcnJheS5mcm9tKGdyb3Vwcy5rZXlzKCkpKS50b0VxdWFsKFtcIi9wcm9kXCJdKTtcbiAgICBleHBlY3QoZ3JvdXBzLmdldChcIi9wcm9kXCIpPy5yc2M/LnBhdGhuYW1lKS50b0JlKFwiL3Byb2QvaW5kZXgucnNjXCIpO1xuICAgIGV4cGVjdChncm91cHMuZ2V0KFwiL3Byb2RcIik/LnNlZ21lbnRzKS50b0hhdmVMZW5ndGgoMSk7XG4gIH0pO1xuXG4gIC8qKiBBbiBhcHAgd2l0aCBhIHJlYWwgYGFwcC9pbmRleC9wYWdlLnRzeGAga2VlcHMgaXRzIG93biBncm91cC4gKi9cbiAgaXQoXCJsZWF2ZXMgYSBnZW51aW5lIC9pbmRleCByb3V0ZSBhbG9uZVwiLCAoKSA9PiB7XG4gICAgY29uc3QgZ3JvdXBzID0gZ3JvdXBQcmVyZW5kZXJzKGF0KFwiL1wiLCBcIi9pbmRleFwiLCBcIi9pbmRleC5yc2NcIikpO1xuICAgIGV4cGVjdChBcnJheS5mcm9tKGdyb3Vwcy5rZXlzKCkpLnNvcnQoKSkudG9FcXVhbChbXCIvXCIsIFwiL2luZGV4XCJdKTtcbiAgICBleHBlY3QoZ3JvdXBzLmdldChcIi9cIik/LnJzYykudG9CZVVuZGVmaW5lZCgpO1xuICAgIGV4cGVjdChncm91cHMuZ2V0KFwiL2luZGV4XCIpPy5yc2M/LnBhdGhuYW1lKS50b0JlKFwiL2luZGV4LnJzY1wiKTtcbiAgfSk7XG5cbiAgLyoqIGAvbmVzdGVkL2luZGV4LnJzY2Agd2l0aCBubyBgL25lc3RlZGAgSFRNTCBpcyBpdHMgb3duIHJvdXRlLCBub3QgYSByZW1hcC4gKi9cbiAgaXQoXCJvbmx5IHJlbWFwcyB3aGVuIHRoZSBwYXJlbnQgcmVhbGx5IGlzIGEgcHJlcmVuZGVyZWQgcm91dGVcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGdyb3VwcyA9IGdyb3VwUHJlcmVuZGVycyhhdChcIi9uZXN0ZWQvaW5kZXgucnNjXCIpKTtcbiAgICBleHBlY3QoQXJyYXkuZnJvbShncm91cHMua2V5cygpKSkudG9FcXVhbChbXCIvbmVzdGVkL2luZGV4XCJdKTtcbiAgfSk7XG5cbiAgaXQoXCJrZWVwcyBzZWdtZW50cyB3aG9zZSByb3V0ZSBoYXMgbm8gb3RoZXIgb3V0cHV0XCIsICgpID0+IHtcbiAgICBjb25zdCBncm91cHMgPSBncm91cFByZXJlbmRlcnMoYXQoXCIvcHByLnNlZ21lbnRzLyRjJC5zZWdtZW50LnJzY1wiKSk7XG4gICAgZXhwZWN0KGdyb3Vwcy5nZXQoXCIvcHByXCIpPy5zZWdtZW50cykudG9IYXZlTGVuZ3RoKDEpO1xuICAgIGV4cGVjdChncm91cHMuZ2V0KFwiL3BwclwiKT8uaHRtbCkudG9CZVVuZGVmaW5lZCgpO1xuICB9KTtcblxuICAvKipcbiAgICogQSBQYWdlcyBSb3V0ZXIgcm91dGUncyBgcGFnZURhdGFgIGxpdmVzIGF0IGEgcGF0aG5hbWUgb2YgaXRzIG93biByYXRoZXIgdGhhblxuICAgKiBhdCBhIHN1ZmZpeCBvZiB0aGUgcGFnZSdzLCBzbyBhbiB1bm1hdGNoZWQgb25lIHdvdWxkIGJlY29tZSBhIGdyb3VwIG5hbWVkXG4gICAqIGAvX25leHQvZGF0YS8uLi5gIC0gd2hpY2ggZ2V0cyBubyBjYWNoZSBraW5kLCBhbmQgc28gc2lsZW50bHkgZHJvcHMgdGhlIGRhdGFcbiAgICogZXZlcnkgc2VlZGVkIGVudHJ5IG5lZWRzLlxuICAgKi9cbiAgaXQoXCJhdHRhY2hlcyBhIFBhZ2VzIFJvdXRlciByb3V0ZSdzIC9fbmV4dC9kYXRhIG91dHB1dFwiLCAoKSA9PiB7XG4gICAgY29uc3QgZ3JvdXBzID0gZ3JvdXBQcmVyZW5kZXJzKFxuICAgICAgYXQoXCIvYmxvZy9oZWxsb1wiLCBcIi9fbmV4dC9kYXRhL2J1aWxkLWFiYzEyMy9ibG9nL2hlbGxvLmpzb25cIiksXG4gICAgKTtcbiAgICBleHBlY3QoQXJyYXkuZnJvbShncm91cHMua2V5cygpKSkudG9FcXVhbChbXCIvYmxvZy9oZWxsb1wiXSk7XG4gICAgZXhwZWN0KGdyb3Vwcy5nZXQoXCIvYmxvZy9oZWxsb1wiKT8uZGF0YT8ucGF0aG5hbWUpLnRvQmUoXG4gICAgICBcIi9fbmV4dC9kYXRhL2J1aWxkLWFiYzEyMy9ibG9nL2hlbGxvLmpzb25cIixcbiAgICApO1xuICB9KTtcblxuICAvKiogVGhlIGBmYWxsYmFjazogdHJ1ZWAgdGVtcGxhdGUsIHdob3NlIGRhdGEgcm91dGUgaGFzIG5vIGZpbGUgYmVoaW5kIGl0LiAqL1xuICBpdChcImF0dGFjaGVzIHRoZSBkYXRhIG91dHB1dCBvZiBhIGR5bmFtaWMgcm91dGUncyBmYWxsYmFjayB0ZW1wbGF0ZVwiLCAoKSA9PiB7XG4gICAgY29uc3QgZ3JvdXBzID0gZ3JvdXBQcmVyZW5kZXJzKFxuICAgICAgYXQoXCIvW3NsdWddXCIsIFwiL19uZXh0L2RhdGEvYnVpbGQtYWJjMTIzL1tzbHVnXS5qc29uXCIpLFxuICAgICk7XG4gICAgZXhwZWN0KEFycmF5LmZyb20oZ3JvdXBzLmtleXMoKSkpLnRvRXF1YWwoW1wiL1tzbHVnXVwiXSk7XG4gICAgZXhwZWN0KGdyb3Vwcy5nZXQoXCIvW3NsdWddXCIpPy5kYXRhPy5wYXRobmFtZSkudG9CZShcbiAgICAgIFwiL19uZXh0L2RhdGEvYnVpbGQtYWJjMTIzL1tzbHVnXS5qc29uXCIsXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqIGAvaW5kZXguanNvbmAgaXMgdGhlIHJvb3QgcGFnZSdzIGRhdGEgcm91dGUsIHRoZSBzYW1lIHJlbWFwIGFzIGAvaW5kZXgucnNjYC4gKi9cbiAgaXQoXCJnaXZlcyB0aGUgcm9vdCByb3V0ZSBpdHMgL2luZGV4Lmpzb24gZGF0YSBvdXRwdXRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGdyb3VwcyA9IGdyb3VwUHJlcmVuZGVycyhcbiAgICAgIGF0KFwiL3Byb2RcIiwgXCIvcHJvZC9fbmV4dC9kYXRhL2J1aWxkLWFiYzEyMy9pbmRleC5qc29uXCIpLFxuICAgICk7XG4gICAgZXhwZWN0KEFycmF5LmZyb20oZ3JvdXBzLmtleXMoKSkpLnRvRXF1YWwoW1wiL3Byb2RcIl0pO1xuICAgIGV4cGVjdChncm91cHMuZ2V0KFwiL3Byb2RcIik/LmRhdGE/LnBhdGhuYW1lKS50b0JlKFxuICAgICAgXCIvcHJvZC9fbmV4dC9kYXRhL2J1aWxkLWFiYzEyMy9pbmRleC5qc29uXCIsXG4gICAgKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoXCJhcHBQYWdlQ2FjaGVIZWFkZXJzXCIsICgpID0+IHtcbiAgLyoqIEV4YWN0bHkgd2hhdCBgb25CdWlsZENvbXBsZXRlYCBpcyBoYW5kZWQgZm9yIGEgcHJlcmVuZGVyZWQgYXBwIHBhZ2UuICovXG4gIGNvbnN0IGluaXRpYWxIZWFkZXJzID0ge1xuICAgIHZhcnk6IFwicnNjLCBuZXh0LXJvdXRlci1zdGF0ZS10cmVlLCBuZXh0LXJvdXRlci1wcmVmZXRjaCwgbmV4dC1yb3V0ZXItc2VnbWVudC1wcmVmZXRjaFwiLFxuICAgIFwiY29udGVudC10eXBlXCI6IFwidGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04XCIsXG4gICAgXCJ4LW5leHRqcy1zdGFsZS10aW1lXCI6IFwiMzAwXCIsXG4gICAgXCJ4LW5leHRqcy1wcmVyZW5kZXJcIjogXCIxXCIsXG4gICAgXCJ4LW5leHQtY2FjaGUtdGFnc1wiOiBcIl9OX1RfL2xheW91dCxfTl9UXy9wYWdlLF9OX1RfLyxfTl9UXy9pbmRleFwiLFxuICB9O1xuXG4gIC8qKlxuICAgKiBUaGUgcmVncmVzc2lvbjogYSBzZWVkZWQgYGNvbnRlbnQtdHlwZTogdGV4dC9odG1sYCBzdXJ2aXZlcyBpbnRvIHRoZSByZXNwb25zZVxuICAgKiBhbmQgYHNlbmQtcGF5bG9hZC5qc2Agd2lsbCBub3Qgb3ZlcndyaXRlIGl0LCBzbyBhbiBSU0MgcmVxdWVzdCB0byBhXG4gICAqIHByZXJlbmRlcmVkIHBhZ2UgZ2V0cyB0aGUgZmxpZ2h0IHBheWxvYWQgbGFiZWxlZCBhcyBIVE1MLlxuICAgKi9cbiAgaXQoXCJkcm9wcyBjb250ZW50LXR5cGUsIHdoaWNoIHdvdWxkIG1pc2xhYmVsIGV2ZXJ5IFJTQyByZXNwb25zZVwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KGFwcFBhZ2VDYWNoZUhlYWRlcnMoaW5pdGlhbEhlYWRlcnMpKS5ub3QudG9IYXZlUHJvcGVydHkoXG4gICAgICBcImNvbnRlbnQtdHlwZVwiLFxuICAgICk7XG4gIH0pO1xuXG4gIGl0KFwia2VlcHMgdGhlIGhlYWRlcnMgYSByZW5kZXIgd291bGQgcmVhbGx5IGhhdmUgc3RvcmVkXCIsICgpID0+IHtcbiAgICBleHBlY3QoYXBwUGFnZUNhY2hlSGVhZGVycyhpbml0aWFsSGVhZGVycykpLnRvRXF1YWwoe1xuICAgICAgXCJ4LW5leHRqcy1zdGFsZS10aW1lXCI6IFwiMzAwXCIsXG4gICAgICBcIngtbmV4dC1jYWNoZS10YWdzXCI6IFwiX05fVF8vbGF5b3V0LF9OX1RfL3BhZ2UsX05fVF8vLF9OX1RfL2luZGV4XCIsXG4gICAgfSk7XG4gIH0pO1xuXG4gIGl0KFwiZHJvcHMgdGhlIGhlYWRlcnMgdGhlIGVudHJ5cG9pbnQgc2V0cyBpdHNlbGYsIHdoaWNoIHdvdWxkIGRvdWJsZSB1cFwiLCAoKSA9PiB7XG4gICAgY29uc3QgaGVhZGVycyA9IGFwcFBhZ2VDYWNoZUhlYWRlcnMoe1xuICAgICAgLi4uaW5pdGlhbEhlYWRlcnMsXG4gICAgICBcIngtbmV4dGpzLXBvc3Rwb25lZFwiOiBcIjFcIixcbiAgICB9KTtcbiAgICBleHBlY3QoT2JqZWN0LmtleXMoaGVhZGVycykpLm5vdC50b0NvbnRhaW4oXCJ2YXJ5XCIpO1xuICAgIGV4cGVjdChPYmplY3Qua2V5cyhoZWFkZXJzKSkubm90LnRvQ29udGFpbihcIngtbmV4dGpzLXByZXJlbmRlclwiKTtcbiAgICBleHBlY3QoT2JqZWN0LmtleXMoaGVhZGVycykpLm5vdC50b0NvbnRhaW4oXCJ4LW5leHRqcy1wb3N0cG9uZWRcIik7XG4gIH0pO1xuXG4gIGl0KFwibWF0Y2hlcyBjYXNlLWluc2Vuc2l0aXZlbHlcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChhcHBQYWdlQ2FjaGVIZWFkZXJzKHsgXCJDb250ZW50LVR5cGVcIjogXCJ0ZXh0L2h0bWxcIiB9KSkudG9FcXVhbCh7fSk7XG4gIH0pO1xuXG4gIGl0KFwicGFzc2VzIHRocm91Z2ggYW55dGhpbmcgdGhlIGFwcCBzZXQgaXRzZWxmXCIsICgpID0+IHtcbiAgICBleHBlY3QoXG4gICAgICBhcHBQYWdlQ2FjaGVIZWFkZXJzKHsgXCJ4LWN1c3RvbVwiOiBcIjFcIiwgXCJzZXQtY29va2llXCI6IFwiYT1iXCIgfSksXG4gICAgKS50b0VxdWFsKHsgXCJ4LWN1c3RvbVwiOiBcIjFcIiwgXCJzZXQtY29va2llXCI6IFwiYT1iXCIgfSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKFwic2VyaWFsaXplQ2FjaGVWYWx1ZSAvIHBhcnNlQ2FjaGVWYWx1ZVwiLCAoKSA9PiB7XG4gIGl0KFwicm91bmQtdHJpcHMgYSBCdWZmZXJcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0geyByc2NEYXRhOiBCdWZmZXIuZnJvbShcImhlbGxvLCBjYWNoZVwiKSB9O1xuXG4gICAgY29uc3QgcmVzdG9yZWQgPSBwYXJzZUNhY2hlVmFsdWUoc2VyaWFsaXplQ2FjaGVWYWx1ZSh2YWx1ZSkpO1xuXG4gICAgZXhwZWN0KEJ1ZmZlci5pc0J1ZmZlcihyZXN0b3JlZC5yc2NEYXRhKSkudG9CZSh0cnVlKTtcbiAgICBleHBlY3QocmVzdG9yZWQucnNjRGF0YS50b1N0cmluZygpKS50b0JlKFwiaGVsbG8sIGNhY2hlXCIpO1xuICB9KTtcblxuICBpdChcInJvdW5kLXRyaXBzIGJ5dGVzIHRoYXQgYXJlIG5vdCB2YWxpZCBVVEYtOFwiLCAoKSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBCdWZmZXIuZnJvbShbMHgwMCwgMHhmZiwgMHhmZSwgMHg4MCwgMHg3Zl0pO1xuXG4gICAgY29uc3QgcmVzdG9yZWQgPSBwYXJzZUNhY2hlVmFsdWUoc2VyaWFsaXplQ2FjaGVWYWx1ZSh7IHZhbHVlIH0pKS52YWx1ZTtcblxuICAgIGV4cGVjdChyZXN0b3JlZC5lcXVhbHModmFsdWUpKS50b0JlKHRydWUpO1xuICB9KTtcblxuICBpdChcInJvdW5kLXRyaXBzIGEgTWFwLCBpbmNsdWRpbmcgQnVmZmVycyBpbnNpZGUgaXRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gbmV3IE1hcChbW1wiL19pbmRleFwiLCBCdWZmZXIuZnJvbShcInNlZ21lbnRcIildXSk7XG5cbiAgICBjb25zdCByZXN0b3JlZCA9IHBhcnNlQ2FjaGVWYWx1ZShzZXJpYWxpemVDYWNoZVZhbHVlKHsgdmFsdWUgfSkpLnZhbHVlO1xuXG4gICAgZXhwZWN0KHJlc3RvcmVkKS50b0JlSW5zdGFuY2VPZihNYXApO1xuICAgIGV4cGVjdChyZXN0b3JlZC5nZXQoXCIvX2luZGV4XCIpLnRvU3RyaW5nKCkpLnRvQmUoXCJzZWdtZW50XCIpO1xuICB9KTtcblxuICAvKipcbiAgICogYmFzZTY0LCBub3QgdGhlIGFycmF5IG9mIHBlci1ieXRlIGludGVnZXJzIGBCdWZmZXIudG9KU09OKClgIHByb2R1Y2VzOiB0aGF0XG4gICAqIGFycmF5IGlzIH4zIGJ5dGVzIG9mIEpTT04gcGVyIGJ5dGUgb2YgcGF5bG9hZCAqYW5kKiBtYWtlcyBgSlNPTi5wYXJzZWAnc1xuICAgKiByZXZpdmVyIHJ1biBvbmNlIHBlciBlbGVtZW50LCB3aGljaCBjb3N0IDQuOHMgb2YgTGFtYmRhIHRpbWUgdG8gYW5zd2VyIGFcbiAgICogc2luZ2xlIDEgTWlCIHNlZ21lbnQgcHJlZmV0Y2ggb24gYSByZWFsIGRlcGxveW1lbnQuXG4gICAqL1xuICBpdChcIndyaXRlcyBhIEJ1ZmZlciBhcyBiYXNlNjQgcmF0aGVyIHRoYW4gYW4gYXJyYXkgb2YgYnl0ZXNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGpzb24gPSBzZXJpYWxpemVDYWNoZVZhbHVlKHsgcnNjRGF0YTogQnVmZmVyLmZyb20oXCJoZWxsb1wiKSB9KTtcblxuICAgIGV4cGVjdChKU09OLnBhcnNlKGpzb24pLnJzY0RhdGEpLnRvRXF1YWwoe1xuICAgICAgX190eXBlOiBcIkJ1ZmZlclwiLFxuICAgICAgYmFzZTY0OiBcImFHVnNiRzg9XCIsXG4gICAgfSk7XG4gICAgLy8gQ29tZm9ydGFibHkgdW5kZXIgdGhlIH41IGJ5dGVzIHBlciBwYXlsb2FkIGJ5dGUgYW4gaW50ZWdlciBhcnJheSBjb3N0cy5cbiAgICBleHBlY3QoanNvbi5sZW5ndGgpLnRvQmVMZXNzVGhhbig2MCk7XG4gIH0pO1xuXG4gIGl0KFwic3RpbGwgcmVhZHMgdGhlIGludGVnZXItYXJyYXkgZm9ybWF0IGFuIG9sZGVyIGJ1aWxkIHdyb3RlXCIsICgpID0+IHtcbiAgICBjb25zdCBsZWdhY3kgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBvdXJzOiB7IF9fdHlwZTogXCJCdWZmZXJcIiwgZGF0YTogWzEwNCwgMTA1XSB9LFxuICAgICAgbm9kZXM6IHsgdHlwZTogXCJCdWZmZXJcIiwgZGF0YTogWzEwNCwgMTA1XSB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzdG9yZWQgPSBwYXJzZUNhY2hlVmFsdWUobGVnYWN5KTtcblxuICAgIGV4cGVjdChyZXN0b3JlZC5vdXJzLnRvU3RyaW5nKCkpLnRvQmUoXCJoaVwiKTtcbiAgICBleHBlY3QocmVzdG9yZWQubm9kZXMudG9TdHJpbmcoKSkudG9CZShcImhpXCIpO1xuICB9KTtcbn0pO1xuIl19
|