cdk-nextjs 0.6.2 → 0.7.1

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 (263) hide show
  1. package/.jsii +2404 -2723
  2. package/.jsii.tabl.json +1 -1
  3. package/API.md +1681 -1930
  4. package/CLAUDE.md +2 -1
  5. package/README.md +429 -130
  6. package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +148 -169
  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 +667 -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 +1551 -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 +857 -0
  28. package/lib/adapter/build-outputs.test.d.ts +1 -0
  29. package/lib/adapter/build-outputs.test.js +863 -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 +8 -0
  79. package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
  80. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +6 -4
  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/prune-cache-bucket.d.ts +7 -3
  85. package/lib/lambdas/post-deploy/prune-cache-bucket.js +57 -71
  86. package/lib/lambdas/post-deploy/prune-cache-bucket.test.d.ts +1 -0
  87. package/lib/lambdas/post-deploy/prune-cache-bucket.test.js +114 -0
  88. package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +1 -0
  89. package/lib/lambdas/post-deploy/prune-revalidation-table.js +23 -31
  90. package/lib/lambdas/post-deploy/prune-revalidation-table.test.d.ts +1 -0
  91. package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +71 -0
  92. package/lib/lambdas/post-deploy/prune-s3.d.ts +14 -5
  93. package/lib/lambdas/post-deploy/prune-s3.js +41 -12
  94. package/lib/lambdas/post-deploy/prune-s3.test.js +97 -18
  95. package/lib/lambdas/redeploy-stage/redeploy-stage-function.d.ts +13 -0
  96. package/lib/lambdas/redeploy-stage/redeploy-stage-function.js +55 -0
  97. package/lib/lambdas/redeploy-stage/redeploy-stage.d.ts +24 -0
  98. package/lib/lambdas/redeploy-stage/redeploy-stage.js +68 -0
  99. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.d.ts +20 -0
  100. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.js +24 -0
  101. package/lib/lambdas/redeploy-stage/redeploy-stage.test.d.ts +1 -0
  102. package/lib/lambdas/redeploy-stage/redeploy-stage.test.js +93 -0
  103. package/lib/nextjs-api.d.ts +102 -18
  104. package/lib/nextjs-api.js +338 -38
  105. package/lib/nextjs-api.test.js +537 -1
  106. package/lib/nextjs-build/global-containers.Dockerfile +15 -10
  107. package/lib/nextjs-build/nextjs-build.d.ts +339 -63
  108. package/lib/nextjs-build/nextjs-build.js +684 -327
  109. package/lib/nextjs-build/nextjs-build.test.d.ts +1 -0
  110. package/lib/nextjs-build/nextjs-build.test.js +412 -0
  111. package/lib/nextjs-build/patch-fetch.js +1 -1
  112. package/lib/nextjs-build/patch-fetch.test.js +166 -11
  113. package/lib/nextjs-build/regional-containers.Dockerfile +17 -10
  114. package/lib/nextjs-cache.d.ts +82 -4
  115. package/lib/nextjs-cache.js +186 -10
  116. package/lib/nextjs-cache.test.js +176 -1
  117. package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +21 -8
  118. package/lib/nextjs-compute/nextjs-compute-base-props.js +41 -1
  119. package/lib/nextjs-compute/nextjs-compute-base-props.test.d.ts +1 -0
  120. package/lib/nextjs-compute/nextjs-compute-base-props.test.js +44 -0
  121. package/lib/nextjs-compute/nextjs-containers.d.ts +19 -0
  122. package/lib/nextjs-compute/nextjs-containers.js +57 -20
  123. package/lib/nextjs-compute/nextjs-functions.d.ts +122 -7
  124. package/lib/nextjs-compute/nextjs-functions.js +113 -67
  125. package/lib/nextjs-compute/nextjs-functions.test.d.ts +1 -0
  126. package/lib/nextjs-compute/nextjs-functions.test.js +99 -0
  127. package/lib/nextjs-distribution.d.ts +194 -23
  128. package/lib/nextjs-distribution.js +535 -62
  129. package/lib/nextjs-distribution.test.d.ts +1 -0
  130. package/lib/nextjs-distribution.test.js +697 -0
  131. package/lib/nextjs-post-deploy.d.ts +13 -5
  132. package/lib/nextjs-post-deploy.js +13 -10
  133. package/lib/nextjs-post-deploy.test.d.ts +1 -0
  134. package/lib/nextjs-post-deploy.test.js +34 -0
  135. package/lib/nextjs-static-assets.d.ts +17 -4
  136. package/lib/nextjs-static-assets.js +22 -5
  137. package/lib/root-constructs/nextjs-base-construct.d.ts +102 -58
  138. package/lib/root-constructs/nextjs-base-construct.js +139 -47
  139. package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
  140. package/lib/root-constructs/nextjs-global-containers.js +20 -71
  141. package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
  142. package/lib/root-constructs/nextjs-global-functions.js +52 -70
  143. package/lib/root-constructs/nextjs-regional-containers.d.ts +18 -5
  144. package/lib/root-constructs/nextjs-regional-containers.js +8 -15
  145. package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
  146. package/lib/root-constructs/nextjs-regional-functions.js +8 -26
  147. package/lib/runtime/api-gateway-path.d.ts +34 -0
  148. package/lib/runtime/api-gateway-path.js +71 -0
  149. package/lib/runtime/api-gateway-path.test.d.ts +1 -0
  150. package/lib/runtime/api-gateway-path.test.js +65 -0
  151. package/lib/runtime/case-redirect.d.ts +22 -0
  152. package/lib/runtime/case-redirect.js +63 -0
  153. package/lib/runtime/case-redirect.test.d.ts +1 -0
  154. package/lib/runtime/case-redirect.test.js +32 -0
  155. package/lib/runtime/core.d.ts +234 -0
  156. package/lib/runtime/core.js +1216 -0
  157. package/lib/runtime/core.test.d.ts +1 -0
  158. package/lib/runtime/core.test.js +1686 -0
  159. package/lib/runtime/deployment-root.d.ts +13 -0
  160. package/lib/runtime/deployment-root.js +29 -0
  161. package/lib/runtime/dispatch.d.ts +331 -0
  162. package/lib/runtime/dispatch.js +751 -0
  163. package/lib/runtime/dispatch.test.d.ts +1 -0
  164. package/lib/runtime/dispatch.test.js +853 -0
  165. package/lib/runtime/entrypoints.d.ts +57 -0
  166. package/lib/runtime/entrypoints.js +115 -0
  167. package/lib/runtime/http/abort-signal.d.ts +6 -0
  168. package/lib/runtime/http/abort-signal.js +19 -0
  169. package/lib/runtime/http/abort-signal.test.d.ts +1 -0
  170. package/lib/runtime/http/abort-signal.test.js +49 -0
  171. package/lib/runtime/http/node-server.d.ts +38 -0
  172. package/lib/runtime/http/node-server.js +99 -0
  173. package/lib/runtime/http/node-server.test.d.ts +1 -0
  174. package/lib/runtime/http/node-server.test.js +96 -0
  175. package/lib/runtime/http/node-sink.d.ts +16 -0
  176. package/lib/runtime/http/node-sink.js +48 -0
  177. package/lib/runtime/http/node-sink.test.d.ts +1 -0
  178. package/lib/runtime/http/node-sink.test.js +66 -0
  179. package/lib/runtime/http/request.d.ts +62 -0
  180. package/lib/runtime/http/request.js +134 -0
  181. package/lib/runtime/http/request.test.d.ts +1 -0
  182. package/lib/runtime/http/request.test.js +103 -0
  183. package/lib/runtime/http/response.d.ts +77 -0
  184. package/lib/runtime/http/response.js +229 -0
  185. package/lib/runtime/http/response.test.d.ts +1 -0
  186. package/lib/runtime/http/response.test.js +178 -0
  187. package/lib/runtime/http/sink.d.ts +73 -0
  188. package/lib/runtime/http/sink.js +188 -0
  189. package/lib/runtime/http/sink.test.d.ts +1 -0
  190. package/lib/runtime/http/sink.test.js +257 -0
  191. package/lib/runtime/image-utils.d.ts +78 -0
  192. package/lib/runtime/image-utils.js +129 -0
  193. package/lib/runtime/image-utils.test.d.ts +1 -0
  194. package/lib/runtime/image-utils.test.js +237 -0
  195. package/lib/runtime/image.d.ts +76 -0
  196. package/lib/runtime/image.js +296 -0
  197. package/lib/runtime/image.test.d.ts +1 -0
  198. package/lib/runtime/image.test.js +405 -0
  199. package/lib/runtime/lambda-event.d.ts +4 -0
  200. package/lib/runtime/lambda-event.js +113 -0
  201. package/lib/runtime/lambda-event.test.d.ts +1 -0
  202. package/lib/runtime/lambda-event.test.js +119 -0
  203. package/lib/runtime/lambda.mjs +41600 -0
  204. package/lib/runtime/load-module.d.ts +8 -0
  205. package/lib/runtime/load-module.js +35 -0
  206. package/lib/runtime/manifest.d.ts +215 -0
  207. package/lib/runtime/manifest.js +118 -0
  208. package/lib/runtime/middleware.d.ts +43 -0
  209. package/lib/runtime/middleware.js +113 -0
  210. package/lib/runtime/middleware.test.d.ts +1 -0
  211. package/lib/runtime/middleware.test.js +259 -0
  212. package/lib/runtime/next-modules.d.ts +71 -0
  213. package/lib/runtime/next-modules.js +144 -0
  214. package/lib/runtime/next-modules.test.d.ts +1 -0
  215. package/lib/runtime/next-modules.test.js +34 -0
  216. package/lib/runtime/public-files.d.ts +32 -0
  217. package/lib/runtime/public-files.js +117 -0
  218. package/lib/runtime/public-files.test.d.ts +1 -0
  219. package/lib/runtime/public-files.test.js +97 -0
  220. package/lib/runtime/server.mjs +41593 -0
  221. package/lib/runtime/static-files.d.ts +50 -0
  222. package/lib/runtime/static-files.js +266 -0
  223. package/lib/runtime/static-files.test.d.ts +1 -0
  224. package/lib/runtime/static-files.test.js +118 -0
  225. package/lib/runtime/util.d.ts +28 -0
  226. package/lib/runtime/util.js +79 -0
  227. package/lib/utils/base-path.d.ts +106 -13
  228. package/lib/utils/base-path.js +254 -41
  229. package/lib/utils/base-path.test.js +219 -51
  230. package/lib/utils/get-architecture.d.ts +7 -8
  231. package/lib/utils/get-architecture.js +12 -13
  232. package/lib/utils/zip-directory.d.ts +14 -0
  233. package/lib/utils/zip-directory.js +121 -0
  234. package/lib/utils/zip-directory.test.d.ts +1 -0
  235. package/lib/utils/zip-directory.test.js +99 -0
  236. package/package.json +22 -3
  237. package/scripts/capture-adapter-fixture.mjs +325 -0
  238. package/scripts/e2e-deploy.sh +398 -0
  239. package/scripts/e2e-harness/README.md +707 -0
  240. package/scripts/e2e-harness/app.js +370 -0
  241. package/scripts/e2e-harness/common.sh +249 -0
  242. package/scripts/e2e-harness/screen.mjs +302 -0
  243. package/scripts/e2e-harness/stage-proxy.mjs +145 -0
  244. package/scripts/e2e-harness/type-filters.mjs +47 -0
  245. package/scripts/e2e-logs.sh +75 -0
  246. package/scripts/e2e-offline.sh +91 -0
  247. package/scripts/e2e-sweep.sh +370 -0
  248. package/scripts/e2e-warm.sh +114 -0
  249. package/scripts/zero-config-build.mjs +418 -0
  250. package/docs/1k-concurrent-users-executions.png +0 -0
  251. package/docs/plans/adapter-runtime-release.md +0 -362
  252. package/docs/plans/phase-0-image-function-opt-in.md +0 -295
  253. package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +0 -425
  254. package/lib/generated-structs/OptionalDockerImageFunctionProps.js +0 -3
  255. package/lib/image-optimization/handler-utils.d.ts +0 -34
  256. package/lib/image-optimization/handler-utils.js +0 -83
  257. package/lib/image-optimization/handler-utils.test.js +0 -178
  258. package/lib/nextjs-build/functions.Dockerfile +0 -31
  259. package/lib/nextjs-compute/nextjs-image-function.d.ts +0 -53
  260. package/lib/nextjs-compute/nextjs-image-function.js +0 -59
  261. package/lib/utils/experimental-flags.d.ts +0 -24
  262. package/lib/utils/experimental-flags.js +0 -30
  263. /package/lib/{image-optimization/handler-utils.test.d.ts → adapter/adapter.test.d.ts} +0 -0
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Pure `basePath` and URL path helpers. Nothing here imports `aws-cdk-lib` or
3
+ * touches the filesystem, so the adapter and runtime bundles can import it as
4
+ * well as the constructs.
5
+ */
1
6
  import { NextjsType } from "../constants";
2
7
  /**
3
8
  * Reduces a `basePath` to a bare path segment so values that address the same
@@ -5,6 +10,31 @@ import { NextjsType } from "../constants";
5
10
  * without doubling separators.
6
11
  */
7
12
  export declare function normalizeBasePath(basePath?: string): string;
13
+ /**
14
+ * Whether `path` is `prefix` or under it on a segment boundary, so `/docsearch`
15
+ * is not under `/docs`. An empty `prefix` matches nothing. Both sides must be in
16
+ * the same form (both with or both without the leading `/`).
17
+ */
18
+ export declare function hasPathPrefix(path: string, prefix: string): boolean;
19
+ /**
20
+ * A `basePath` as Next.js spells it and URLs start with it: one leading slash,
21
+ * no trailing one ("/base"), `""` for none. Accepts any spelling
22
+ * {@link normalizeBasePath} does.
23
+ */
24
+ export declare function basePathPrefix(basePath?: string): string;
25
+ /**
26
+ * Invalidation paths covering every URI of the app: what a deploy invalidates,
27
+ * and what the cache handler's oversized batches, retries after a quota error,
28
+ * and tags whose routes could not all be named fall back to.
29
+ *
30
+ * `/*` is the whole app only without a `basePath`. `/base/*` matches neither the
31
+ * app's root, `/base`, nor its RSC payload, `/base?_rsc=…` - the same root the
32
+ * `revalidatePath("/")` that overflowed may have named - so those are spelled
33
+ * out. `/base*` would cover them for one wildcard, but also every sibling
34
+ * prefix (`/base2`, `/basement`), which may be another app on the same
35
+ * distribution.
36
+ */
37
+ export declare function wholeAppInvalidationPaths(basePath?: string): string[];
8
38
  /**
9
39
  * Joins path parts with a single "/", normalizing each (so no leading or
10
40
  * trailing slash survives, including on the result) and dropping the empty
@@ -19,8 +49,8 @@ export declare function joinPath(...parts: (string | undefined)[]): string;
19
49
  * answers "/api/health" and "/api/health/" differently.
20
50
  *
21
51
  * Use this for paths handed to something that talks to the app directly — an ALB
22
- * target group health check, the Lambda Web Adapter readiness check — since the
23
- * app only answers under its own `basePath`.
52
+ * target group health check, the container's own health probe — since the app
53
+ * only answers under its own `basePath`.
24
54
  *
25
55
  * Prefixes unconditionally, so `path` has to arrive as the app routes it,
26
56
  * without `basePath`: for an app based at "/base", "/base/api/health" becomes
@@ -31,18 +61,78 @@ export declare function joinPath(...parts: (string | undefined)[]): string;
31
61
  */
32
62
  export declare function prefixWithBasePath(basePath: string | undefined, path: string): string;
33
63
  /**
34
- * Read the Next.js app's own `basePath` out of `required-server-files.json`,
35
- * which `next build` writes into `.next` with the fully resolved config (so
36
- * this picks up a `basePath` computed in `next.config.js`, not only a literal
37
- * one). Normalized, empty when the app sets none.
64
+ * The app's own `assetPrefix` as a path with a leading and no trailing slash
65
+ * ("/cdn"), or `""` when the app sets none.
38
66
  *
39
- * Degrades to `""` rather than throwing, since an unreadable file shouldn't
40
- * fail a deployment that would otherwise work. It warns because `""` is
41
- * indistinguishable from an app that genuinely sets no `basePath`: the
42
- * `NextjsType`s that derive `basePath` from the app would quietly not derive
43
- * it and 404 every static asset.
67
+ * Returns `""` for an absolute `assetPrefix` ("https://cdn.example.com", or the
68
+ * protocol-relative "//cdn.example.com") too: that names an origin cdk-nextjs
69
+ * does not control, and it is the supported way to serve assets from elsewhere,
70
+ * so nothing about it is worth warning about. Use {@link assetPrefixPath} for
71
+ * what the *distribution* has to answer on, which includes the path an absolute
72
+ * prefix carries.
73
+ *
74
+ * Next.js applies `assetPrefix` on top of, not under, `basePath`, so the result
75
+ * is the whole prefix of a `_next/static` URL and must not be joined with
76
+ * `basePath`.
44
77
  */
45
- export declare function readNextConfigBasePath(dotNextPath: string): string;
78
+ export declare function relativeAssetPrefix(assetPrefix: string): string;
79
+ /**
80
+ * Whether a path-style `assetPrefix` would go unanswered on this `NextjsType`,
81
+ * i.e. whether every bundle would 404.
82
+ *
83
+ * `assetPrefix` moves every bundle URL to `<assetPrefix>/_next/static/...` while
84
+ * the objects keep their `<basePath>/_next/static/...` S3 keys. The Global
85
+ * `NextjsType`s answer that with a cache behavior of their own
86
+ * (`NextjsDistribution`); the regional ones have nothing that maps the prefix
87
+ * back — API Gateway's `_next/static` resource and the container's own files are
88
+ * both under the unprefixed path.
89
+ *
90
+ * A prefix equal to the app's own `basePath` is **not** unserved, because that is
91
+ * the value Next.js resolves `assetPrefix` to when `basePath` is set and
92
+ * `assetPrefix` is not: `.next/required-server-files.json` comes back as
93
+ * `{"assetPrefix":"/prod","basePath":"/prod"}` for an app that only ever set
94
+ * `basePath`. Without that exemption the warning fired on every regional
95
+ * deployment that sets a `basePath` at all — including `examples/regional-functions`
96
+ * — telling users their bundles would 404 at the one path that does serve them.
97
+ * `NextjsDistribution.resolveAssetPrefix` drops the prefix for the same reason.
98
+ *
99
+ * Both sides go through `normalizeBasePath` because they arrive in different
100
+ * shapes: `nextConfigAssetPrefix` carries a leading slash (`"/prod"`),
101
+ * `nextConfigBasePath` does not (`"prod"`).
102
+ */
103
+ export declare function isAssetPrefixUnserved(nextjsType: NextjsType, nextConfigAssetPrefix: string, nextConfigBasePath?: string): boolean;
104
+ /**
105
+ * The *path* every bundle URL carries, whichever form `assetPrefix` takes: "/cdn"
106
+ * for `assetPrefix: "/cdn"` and for `assetPrefix:
107
+ * "https://cdn.example.com/cdn"` alike, `""` when there is none (an absolute
108
+ * prefix with no path, or no prefix at all).
109
+ *
110
+ * An absolute prefix's path counts because `next build` compiles a `beforeFiles`
111
+ * rewrite of its own for it — `/cdn/_next/:path+ → /_next/:path+` — so `next
112
+ * start` serves every bundle under that path as well as under `/_next`. A CDN
113
+ * fronting this deployment at that path therefore has to be answered, and the
114
+ * distribution's `assetPrefix` behavior is what answers it. Measured against
115
+ * `test/e2e/app-dir/asset-prefix-absolute`; see `docs/harness-coverage.md`.
116
+ * Shared with `NextjsDistribution`, whose `assetPrefix` prop a user can also
117
+ * set by hand.
118
+ */
119
+ export declare function assetPrefixPath(assetPrefix: string): string;
120
+ /**
121
+ * The path prefix API Gateway strips before matching resources, as far as synth
122
+ * can tell. Only read by `resolveBasePath` for `REGIONAL_FUNCTIONS`.
123
+ */
124
+ export interface ApiGatewayPrefix {
125
+ /**
126
+ * The stage name on the execute-api endpoint, or the base path mapping on a
127
+ * custom domain (`""` when mapped at the root). `undefined` when it is not
128
+ * known at synth — a token — in which case nothing is derived.
129
+ */
130
+ readonly strippedPrefix?: string;
131
+ /** Whether a custom domain is configured through `restApiProps.domainName`. */
132
+ readonly customDomain: boolean;
133
+ }
134
+ /** `RestApi`'s own defaults: the `prod` stage, no custom domain. */
135
+ export declare const DEFAULT_API_GATEWAY_PREFIX: ApiGatewayPrefix;
46
136
  /**
47
137
  * Settles on the single `basePath` the infrastructure should be built around,
48
138
  * given the CDK `basePath` prop and the Next.js app's own `basePath`
@@ -55,5 +145,8 @@ export declare function readNextConfigBasePath(dotNextPath: string): string;
55
145
  * land under), the config is the prefix the app emits its own links and asset
56
146
  * hrefs under — so how strictly they have to line up, and whether one can stand
57
147
  * in for the other, depends on how the `NextjsType` routes static requests.
148
+ *
149
+ * `apiGateway` is only read for `REGIONAL_FUNCTIONS`, and only when the prop is
150
+ * unset: see `deriveApiGatewayBasePath`.
58
151
  */
59
- export declare function resolveBasePath(nextjsType: NextjsType, propBasePath?: string, nextConfigBasePath?: string): string | undefined;
152
+ export declare function resolveBasePath(nextjsType: NextjsType, propBasePath?: string, nextConfigBasePath?: string, apiGateway?: ApiGatewayPrefix): string | undefined;
@@ -1,12 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_API_GATEWAY_PREFIX = void 0;
3
4
  exports.normalizeBasePath = normalizeBasePath;
5
+ exports.hasPathPrefix = hasPathPrefix;
6
+ exports.basePathPrefix = basePathPrefix;
7
+ exports.wholeAppInvalidationPaths = wholeAppInvalidationPaths;
4
8
  exports.joinPath = joinPath;
5
9
  exports.prefixWithBasePath = prefixWithBasePath;
6
- exports.readNextConfigBasePath = readNextConfigBasePath;
10
+ exports.relativeAssetPrefix = relativeAssetPrefix;
11
+ exports.isAssetPrefixUnserved = isAssetPrefixUnserved;
12
+ exports.assetPrefixPath = assetPrefixPath;
7
13
  exports.resolveBasePath = resolveBasePath;
8
- const node_fs_1 = require("node:fs");
9
- const node_path_1 = require("node:path");
14
+ /**
15
+ * Pure `basePath` and URL path helpers. Nothing here imports `aws-cdk-lib` or
16
+ * touches the filesystem, so the adapter and runtime bundles can import it as
17
+ * well as the constructs.
18
+ */
10
19
  const constants_1 = require("../constants");
11
20
  /**
12
21
  * Reduces a `basePath` to a bare path segment so values that address the same
@@ -16,6 +25,39 @@ const constants_1 = require("../constants");
16
25
  function normalizeBasePath(basePath) {
17
26
  return (basePath || "").replace(/^\/+/, "").replace(/\/+$/, "");
18
27
  }
28
+ /**
29
+ * Whether `path` is `prefix` or under it on a segment boundary, so `/docsearch`
30
+ * is not under `/docs`. An empty `prefix` matches nothing. Both sides must be in
31
+ * the same form (both with or both without the leading `/`).
32
+ */
33
+ function hasPathPrefix(path, prefix) {
34
+ return !!prefix && (path === prefix || path.startsWith(`${prefix}/`));
35
+ }
36
+ /**
37
+ * A `basePath` as Next.js spells it and URLs start with it: one leading slash,
38
+ * no trailing one ("/base"), `""` for none. Accepts any spelling
39
+ * {@link normalizeBasePath} does.
40
+ */
41
+ function basePathPrefix(basePath) {
42
+ const bare = normalizeBasePath(basePath);
43
+ return bare ? `/${bare}` : "";
44
+ }
45
+ /**
46
+ * Invalidation paths covering every URI of the app: what a deploy invalidates,
47
+ * and what the cache handler's oversized batches, retries after a quota error,
48
+ * and tags whose routes could not all be named fall back to.
49
+ *
50
+ * `/*` is the whole app only without a `basePath`. `/base/*` matches neither the
51
+ * app's root, `/base`, nor its RSC payload, `/base?_rsc=…` - the same root the
52
+ * `revalidatePath("/")` that overflowed may have named - so those are spelled
53
+ * out. `/base*` would cover them for one wildcard, but also every sibling
54
+ * prefix (`/base2`, `/basement`), which may be another app on the same
55
+ * distribution.
56
+ */
57
+ function wholeAppInvalidationPaths(basePath) {
58
+ const prefix = basePathPrefix(basePath);
59
+ return prefix ? [prefix, `${prefix}?*`, `${prefix}/*`] : ["/*"];
60
+ }
19
61
  /**
20
62
  * Joins path parts with a single "/", normalizing each (so no leading or
21
63
  * trailing slash survives, including on the result) and dropping the empty
@@ -32,8 +74,8 @@ function joinPath(...parts) {
32
74
  * answers "/api/health" and "/api/health/" differently.
33
75
  *
34
76
  * Use this for paths handed to something that talks to the app directly — an ALB
35
- * target group health check, the Lambda Web Adapter readiness check — since the
36
- * app only answers under its own `basePath`.
77
+ * target group health check, the container's own health probe — since the app
78
+ * only answers under its own `basePath`.
37
79
  *
38
80
  * Prefixes unconditionally, so `path` has to arrive as the app routes it,
39
81
  * without `basePath`: for an app based at "/base", "/base/api/health" becomes
@@ -47,37 +89,159 @@ function prefixWithBasePath(basePath, path) {
47
89
  const absolute = path.startsWith("/") ? path : `/${path}`;
48
90
  return normalized ? `/${normalized}${absolute}` : absolute;
49
91
  }
92
+ /** Whether an `assetPrefix` names an origin rather than a path on this one. */
93
+ function isAbsoluteAssetPrefix(assetPrefix) {
94
+ return /^([a-z][a-z0-9+.-]*:)?\/\//i.test(assetPrefix);
95
+ }
96
+ /**
97
+ * The app's own `assetPrefix` as a path with a leading and no trailing slash
98
+ * ("/cdn"), or `""` when the app sets none.
99
+ *
100
+ * Returns `""` for an absolute `assetPrefix` ("https://cdn.example.com", or the
101
+ * protocol-relative "//cdn.example.com") too: that names an origin cdk-nextjs
102
+ * does not control, and it is the supported way to serve assets from elsewhere,
103
+ * so nothing about it is worth warning about. Use {@link assetPrefixPath} for
104
+ * what the *distribution* has to answer on, which includes the path an absolute
105
+ * prefix carries.
106
+ *
107
+ * Next.js applies `assetPrefix` on top of, not under, `basePath`, so the result
108
+ * is the whole prefix of a `_next/static` URL and must not be joined with
109
+ * `basePath`.
110
+ */
111
+ function relativeAssetPrefix(assetPrefix) {
112
+ return isAbsoluteAssetPrefix(assetPrefix) ? "" : basePathPrefix(assetPrefix);
113
+ }
114
+ /**
115
+ * Whether a path-style `assetPrefix` would go unanswered on this `NextjsType`,
116
+ * i.e. whether every bundle would 404.
117
+ *
118
+ * `assetPrefix` moves every bundle URL to `<assetPrefix>/_next/static/...` while
119
+ * the objects keep their `<basePath>/_next/static/...` S3 keys. The Global
120
+ * `NextjsType`s answer that with a cache behavior of their own
121
+ * (`NextjsDistribution`); the regional ones have nothing that maps the prefix
122
+ * back — API Gateway's `_next/static` resource and the container's own files are
123
+ * both under the unprefixed path.
124
+ *
125
+ * A prefix equal to the app's own `basePath` is **not** unserved, because that is
126
+ * the value Next.js resolves `assetPrefix` to when `basePath` is set and
127
+ * `assetPrefix` is not: `.next/required-server-files.json` comes back as
128
+ * `{"assetPrefix":"/prod","basePath":"/prod"}` for an app that only ever set
129
+ * `basePath`. Without that exemption the warning fired on every regional
130
+ * deployment that sets a `basePath` at all — including `examples/regional-functions`
131
+ * — telling users their bundles would 404 at the one path that does serve them.
132
+ * `NextjsDistribution.resolveAssetPrefix` drops the prefix for the same reason.
133
+ *
134
+ * Both sides go through `normalizeBasePath` because they arrive in different
135
+ * shapes: `nextConfigAssetPrefix` carries a leading slash (`"/prod"`),
136
+ * `nextConfigBasePath` does not (`"prod"`).
137
+ */
138
+ function isAssetPrefixUnserved(nextjsType, nextConfigAssetPrefix, nextConfigBasePath) {
139
+ if (!nextConfigAssetPrefix)
140
+ return false;
141
+ if (nextjsType === constants_1.NextjsType.GLOBAL_FUNCTIONS ||
142
+ nextjsType === constants_1.NextjsType.GLOBAL_CONTAINERS) {
143
+ return false;
144
+ }
145
+ return (normalizeBasePath(nextConfigAssetPrefix) !==
146
+ normalizeBasePath(nextConfigBasePath));
147
+ }
50
148
  /**
51
- * Read the Next.js app's own `basePath` out of `required-server-files.json`,
52
- * which `next build` writes into `.next` with the fully resolved config (so
53
- * this picks up a `basePath` computed in `next.config.js`, not only a literal
54
- * one). Normalized, empty when the app sets none.
149
+ * The *path* every bundle URL carries, whichever form `assetPrefix` takes: "/cdn"
150
+ * for `assetPrefix: "/cdn"` and for `assetPrefix:
151
+ * "https://cdn.example.com/cdn"` alike, `""` when there is none (an absolute
152
+ * prefix with no path, or no prefix at all).
55
153
  *
56
- * Degrades to `""` rather than throwing, since an unreadable file shouldn't
57
- * fail a deployment that would otherwise work. It warns because `""` is
58
- * indistinguishable from an app that genuinely sets no `basePath`: the
59
- * `NextjsType`s that derive `basePath` from the app would quietly not derive
60
- * it and 404 every static asset.
154
+ * An absolute prefix's path counts because `next build` compiles a `beforeFiles`
155
+ * rewrite of its own for it — `/cdn/_next/:path+ → /_next/:path+` — so `next
156
+ * start` serves every bundle under that path as well as under `/_next`. A CDN
157
+ * fronting this deployment at that path therefore has to be answered, and the
158
+ * distribution's `assetPrefix` behavior is what answers it. Measured against
159
+ * `test/e2e/app-dir/asset-prefix-absolute`; see `docs/harness-coverage.md`.
160
+ * Shared with `NextjsDistribution`, whose `assetPrefix` prop a user can also
161
+ * set by hand.
61
162
  */
62
- function readNextConfigBasePath(dotNextPath) {
63
- const requiredServerFiles = (0, node_path_1.join)(dotNextPath, "required-server-files.json");
64
- const fallback = (reason) => {
65
- console.warn(`${constants_1.LOG_PREFIX} ${reason}. Assuming your Next.js app sets no \`basePath\`: ` +
66
- "if it does set one, static assets will 404 and any `basePath` prop " +
67
- "mismatch reported at synth will name the wrong value.");
163
+ function assetPrefixPath(assetPrefix) {
164
+ if (!assetPrefix)
68
165
  return "";
69
- };
70
- if (!(0, node_fs_1.existsSync)(requiredServerFiles)) {
71
- return fallback(`"required-server-files.json" not found at ${requiredServerFiles}`);
166
+ let path = assetPrefix;
167
+ if (isAbsoluteAssetPrefix(assetPrefix)) {
168
+ try {
169
+ // `//cdn.example.com/cdn` is protocol-relative, which `URL` only parses
170
+ // with a base — any base, since only the path is read off it.
171
+ path = new URL(assetPrefix, "https://asset-prefix.invalid").pathname;
172
+ }
173
+ catch {
174
+ return "";
175
+ }
176
+ }
177
+ return basePathPrefix(path);
178
+ }
179
+ /** `RestApi`'s own defaults: the `prod` stage, no custom domain. */
180
+ exports.DEFAULT_API_GATEWAY_PREFIX = {
181
+ strippedPrefix: "prod",
182
+ customDomain: false,
183
+ };
184
+ /**
185
+ * The resource path an app's `basePath` needs on `REGIONAL_FUNCTIONS` when the
186
+ * `basePath` prop is unset: the app's `basePath` with the prefix API Gateway
187
+ * strips taken off the front, or the whole of it when it does not start with
188
+ * that prefix.
189
+ *
190
+ * An app at the `prod` stage emits `/prod/...` and API Gateway strips `/prod`
191
+ * before matching, so `basePath: "/prod"` needs resources at the root and
192
+ * `basePath: "/prod/base"` needs them under `base`. An app whose `basePath` API
193
+ * Gateway does not strip — a custom domain mapped at the root, serving
194
+ * `basePath: "/docs"` — needs them under `docs`. Leaving that one at the root is
195
+ * what used to happen: `_next/static` and `public/` fell through to the
196
+ * `{proxy+}` catch-all, and every bundle 404'd with nothing said at synth.
197
+ */
198
+ function deriveApiGatewayBasePath(config, { strippedPrefix, customDomain }) {
199
+ if (!config || strippedPrefix === undefined) {
200
+ return undefined;
201
+ }
202
+ const stripped = normalizeBasePath(strippedPrefix);
203
+ if (hasPathPrefix(config, stripped)) {
204
+ return config.slice(stripped.length + 1) || undefined;
205
+ }
206
+ warnUnstrippedBasePath(config, { strippedPrefix, customDomain });
207
+ return config;
208
+ }
209
+ /**
210
+ * Warn that an app mounted under its whole `basePath` is served somewhere its
211
+ * own links don't reach, when API Gateway strips a prefix that `basePath` lacks.
212
+ * Both ways of arriving there warn: the prop left unset (derived to the whole
213
+ * `basePath`) and the prop set to the same value.
214
+ */
215
+ function warnUnstrippedBasePath(config, { strippedPrefix, customDomain }) {
216
+ const stripped = normalizeBasePath(strippedPrefix);
217
+ if (strippedPrefix === undefined || !stripped) {
218
+ // A token, or a custom domain mapped at the root: nothing is stripped that
219
+ // the app's links could miss.
220
+ return;
72
221
  }
73
- try {
74
- const { config } = JSON.parse((0, node_fs_1.readFileSync)(requiredServerFiles, "utf-8"));
75
- return normalizeBasePath(config?.basePath);
222
+ if (customDomain) {
223
+ // The same miss through a custom domain's base path mapping: served at
224
+ // `/<mapping>/<basePath>`, linking to `/<basePath>/...`, which no mapping
225
+ // covers.
226
+ console.warn(`${constants_1.LOG_PREFIX} your Next.js app's \`basePath\` is ${quote(config)}, which does not start with the custom domain's base path mapping "/${stripped}". ` +
227
+ "Its links and bundle URLs will be requested without the mapping, which the custom domain answers with 403. " +
228
+ `Set \`basePath: "/${joinPath(stripped, config)}"\` in your next.config, or map the domain at the root.`);
76
229
  }
77
- catch (error) {
78
- return fallback(`Could not read basePath from ${requiredServerFiles}: ${error}`);
230
+ else {
231
+ // Resources under the app's basePath serve it at `/<stage>/<basePath>`, but
232
+ // the app's own links are `/<basePath>/...`, which misses the stage. A
233
+ // warning, not an error: a domain attached after synth (`addDomainName`)
234
+ // makes it right, and synth cannot see that.
235
+ console.warn(`${constants_1.LOG_PREFIX} your Next.js app's \`basePath\` is ${quote(config)}, which does not start with the API Gateway stage "/${stripped}". ` +
236
+ "Its links and bundle URLs will be requested without the stage, which the execute-api endpoint answers with 403. " +
237
+ `Set \`basePath: "/${joinPath(stripped, config)}"\` in your next.config, or serve the app from a custom domain mapped at the root.`);
79
238
  }
80
239
  }
240
+ /** Whether API Gateway strips the front of `basePath` before matching resources. */
241
+ function startsWithStrippedPrefix(basePath, { strippedPrefix }) {
242
+ const stripped = normalizeBasePath(strippedPrefix);
243
+ return !!basePath && hasPathPrefix(basePath, stripped);
244
+ }
81
245
  function quote(basePath) {
82
246
  return basePath ? `"/${basePath}"` : "unset";
83
247
  }
@@ -93,15 +257,43 @@ function quote(basePath) {
93
257
  * land under), the config is the prefix the app emits its own links and asset
94
258
  * hrefs under — so how strictly they have to line up, and whether one can stand
95
259
  * in for the other, depends on how the `NextjsType` routes static requests.
260
+ *
261
+ * `apiGateway` is only read for `REGIONAL_FUNCTIONS`, and only when the prop is
262
+ * unset: see `deriveApiGatewayBasePath`.
96
263
  */
97
- function resolveBasePath(nextjsType, propBasePath, nextConfigBasePath) {
264
+ function resolveBasePath(nextjsType, propBasePath, nextConfigBasePath, apiGateway = exports.DEFAULT_API_GATEWAY_PREFIX) {
98
265
  const prop = normalizeBasePath(propBasePath);
99
266
  const config = normalizeBasePath(nextConfigBasePath);
267
+ const mismatch = `${constants_1.LOG_PREFIX} basePath mismatch for NextjsType.${nextjsType}: the \`basePath\` prop is ${quote(prop)} ` +
268
+ `but your Next.js app's config sets \`basePath\` to ${quote(config)}. `;
100
269
  if (prop === config) {
270
+ if (nextjsType === constants_1.NextjsType.REGIONAL_FUNCTIONS &&
271
+ startsWithStrippedPrefix(prop, apiGateway)) {
272
+ // Agreeing is not enough here: API Gateway strips the stage (or base path
273
+ // mapping) before matching, so resources under the prop's "prod" are only
274
+ // reached at `/prod/prod/...`, and every link the app emits 403s.
275
+ const problem = `API Gateway strips "/${normalizeBasePath(apiGateway.strippedPrefix)}" before matching resources, so a prop that repeats it nests every resource under a path no request reaches. ` +
276
+ "Leave the prop unset: it is derived from your app's `basePath` with that prefix taken off.";
277
+ if (apiGateway.customDomain) {
278
+ throw new Error(mismatch + problem);
279
+ }
280
+ // On the execute-api endpoint that is certain, but an explicit prop wins:
281
+ // a domain attached with `addDomainName()`, invisible here, can map the
282
+ // stage at its root, and then `/prod/...` does reach resources under
283
+ // "prod".
284
+ console.warn(mismatch +
285
+ problem +
286
+ " (Ignore this if a domain attached with `addDomainName()` serves the app without stripping that prefix.)");
287
+ return prop;
288
+ }
289
+ if (nextjsType === constants_1.NextjsType.REGIONAL_FUNCTIONS && prop) {
290
+ // Agreeing the other way round has the unset case's problem: resources
291
+ // under "docs" are reached at `/prod/docs/...`, the app links to
292
+ // `/docs/...`.
293
+ warnUnstrippedBasePath(config, apiGateway);
294
+ }
101
295
  return prop || undefined;
102
296
  }
103
- const mismatch = `${constants_1.LOG_PREFIX} basePath mismatch for NextjsType.${nextjsType}: the \`basePath\` prop is ${quote(prop)} ` +
104
- `but your Next.js app's config sets \`basePath\` to ${quote(config)}. `;
105
297
  switch (nextjsType) {
106
298
  case constants_1.NextjsType.GLOBAL_FUNCTIONS:
107
299
  case constants_1.NextjsType.GLOBAL_CONTAINERS:
@@ -117,26 +309,47 @@ function resolveBasePath(nextjsType, propBasePath, nextConfigBasePath) {
117
309
  "CloudFront serves static assets straight from S3 using the request path as the object key, so a mismatch means every `_next/static` and `public/` request 404s. " +
118
310
  "Either set both to the same value, or drop the prop — left unset, it follows your app's `basePath`.");
119
311
  case constants_1.NextjsType.REGIONAL_FUNCTIONS:
120
- // Deliberately not derived: API Gateway mounts resources below the stage
121
- // and strips it before invoking the app, so an app whose basePath is the
122
- // stage name (or a custom domain base path mapping that gets stripped the
123
- // same way) is correct precisely because the prop stays unset.
124
312
  if (!prop) {
125
- return undefined;
313
+ // A prop that is set but names no path ("/") is an explicit root
314
+ // mount, not "unset": it is how an app says the prefix is stripped by
315
+ // something synth can't see — a domain attached later with
316
+ // `addDomainName({ basePath })`, say — so deriving here would nest the
317
+ // resources under a path the stripped requests never reach.
318
+ if (propBasePath !== undefined) {
319
+ return undefined;
320
+ }
321
+ return deriveApiGatewayBasePath(config, apiGateway);
126
322
  }
127
323
  // The prop only has to be the tail of what the app emits, not all of it,
128
324
  // because the stripped prefix is part of the app's `basePath` but never
129
325
  // part of the resource path: an app at the `prod` stage nested under
130
- // "/base" sets `basePath: "/prod/base"` and the prop to "/base". Checked
131
- // on a path boundary so "/prod/base" doesn't accept a prop of "se".
132
- if (config.endsWith(`/${prop}`)) {
326
+ // "/base" sets `basePath: "/prod/base"` and the prop to "/base". Exactly
327
+ // the stripped prefix and then the prop, not any tail: with a prop of
328
+ // "/base" an app at "/foo/base" is served at `/prod/base/...` and links
329
+ // to `/foo/base/...`, which 403s. Only a token stage, which synth can't
330
+ // read, falls back to a tail on a path boundary.
331
+ if (apiGateway.strippedPrefix === undefined
332
+ ? config.endsWith(`/${prop}`)
333
+ : config === joinPath(apiGateway.strippedPrefix, prop)) {
334
+ return prop;
335
+ }
336
+ // Any tail on a path boundary is also what a domain attached with
337
+ // `addDomainName({ basePath: "v1" })` needs for an app at "/v1/base":
338
+ // synth only sees the stage, so it can't tell that setup from a mistake.
339
+ // An explicit prop wins, so that warns; a custom domain configured in
340
+ // `restApiProps.domainName` is visible, so there it still throws below.
341
+ if (!apiGateway.customDomain && config.endsWith(`/${prop}`)) {
342
+ const leading = config.slice(0, -prop.length - 1);
343
+ console.warn(`${constants_1.LOG_PREFIX} the \`basePath\` prop is ${quote(prop)} and your Next.js app's \`basePath\` is ${quote(config)}, ` +
344
+ `so the app is served at "/${joinPath(normalizeBasePath(apiGateway.strippedPrefix), prop)}" on the execute-api endpoint and links to "/${config}". ` +
345
+ `That only works through a custom domain whose base path mapping strips "/${leading}" (\`addDomainName({ basePath: "${leading}" })\`); otherwise every request 403s.`);
133
346
  return prop;
134
347
  }
135
348
  // Anything else never works: the prop moves every resource, including the
136
349
  // `ANY` catch-all, under a path the app never links to.
137
350
  throw new Error(mismatch +
138
351
  "The `basePath` prop nests every API Gateway resource under that path, including the catch-all, so the app has to emit its links under the same prefix or every request 404s. " +
139
- 'Either set your app\'s `basePath` to end with the prop (optionally prefixed by the stage or base path mapping API Gateway strips, e.g. `basePath: "/prod/base"` with a prop of "/base"), or leave the prop unset — unset is what you want when the app\'s `basePath` is the API Gateway stage name, since the stage isn\'t part of the resource path.');
352
+ 'Either set your app\'s `basePath` to the prop, or to the prop prefixed by the stage or base path mapping API Gateway strips (e.g. `basePath: "/prod/base"` with a prop of "/base"), or leave the prop unset — unset is what you want when the app\'s `basePath` is the API Gateway stage name, since the stage isn\'t part of the resource path.');
140
353
  case constants_1.NextjsType.REGIONAL_CONTAINERS:
141
354
  // The ALB forwards every path to the container, which serves its own
142
355
  // static assets, so here `basePath` only namespaces the S3 bucket and has
@@ -144,4 +357,4 @@ function resolveBasePath(nextjsType, propBasePath, nextConfigBasePath) {
144
357
  return prop || undefined;
145
358
  }
146
359
  }
147
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1wYXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL2Jhc2UtcGF0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVNBLDhDQUVDO0FBT0QsNEJBRUM7QUFvQkQsZ0RBT0M7QUFjRCx3REF1QkM7QUFtQkQsMENBNERDO0FBbktELHFDQUFtRDtBQUNuRCx5Q0FBaUM7QUFDakMsNENBQXNEO0FBRXREOzs7O0dBSUc7QUFDSCxTQUFnQixpQkFBaUIsQ0FBQyxRQUFpQjtJQUNqRCxPQUFPLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNsRSxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQWdCLFFBQVEsQ0FBQyxHQUFHLEtBQTZCO0lBQ3ZELE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDaEUsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILFNBQWdCLGtCQUFrQixDQUNoQyxRQUE0QixFQUM1QixJQUFZO0lBRVosTUFBTSxVQUFVLEdBQUcsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDL0MsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO0lBQzFELE9BQU8sVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLFVBQVUsR0FBRyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO0FBQzdELENBQUM7QUFFRDs7Ozs7Ozs7Ozs7R0FXRztBQUNILFNBQWdCLHNCQUFzQixDQUFDLFdBQW1CO0lB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QUFtQjtZQUNqQyxxRUFBcUU7WUFDckUsMEVBQTBFO1lBQzFFLHVEQUF1RDtZQUN2RCxPQUFPLElBQUksSUFBSSxTQUFTLENBQUM7SUFDN0IsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBleGlzdHNTeW5jLCByZWFkRmlsZVN5bmMgfSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IExPR19QUkVGSVgsIE5leHRqc1R5cGUgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogUmVkdWNlcyBhIGBiYXNlUGF0aGAgdG8gYSBiYXJlIHBhdGggc2VnbWVudCBzbyB2YWx1ZXMgdGhhdCBhZGRyZXNzIHRoZSBzYW1lXG4gKiBwYXRoIChcIi9iYXNlXCIsIFwiYmFzZVwiLCBcIi9iYXNlL1wiKSBjb21wYXJlIGVxdWFsIGFuZCBjYW4gYmUgY29uY2F0ZW5hdGVkXG4gKiB3aXRob3V0IGRvdWJsaW5nIHNlcGFyYXRvcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVCYXNlUGF0aChiYXNlUGF0aD86IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiAoYmFzZVBhdGggfHwgXCJcIikucmVwbGFjZSgvXlxcLysvLCBcIlwiKS5yZXBsYWNlKC9cXC8rJC8sIFwiXCIpO1xufVxuXG4vKipcbiAqIEpvaW5zIHBhdGggcGFydHMgd2l0aCBhIHNpbmdsZSBcIi9cIiwgbm9ybWFsaXppbmcgZWFjaCAoc28gbm8gbGVhZGluZyBvclxuICogdHJhaWxpbmcgc2xhc2ggc3Vydml2ZXMsIGluY2x1ZGluZyBvbiB0aGUgcmVzdWx0KSBhbmQgZHJvcHBpbmcgdGhlIGVtcHR5XG4gKiBvbmVzLCBzbyBhbiB1bnNldCBgYmFzZVBhdGhgIG9yIGtleSBwcmVmaXggbGVhdmVzIHRoZSByZXN0IHVudG91Y2hlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGpvaW5QYXRoKC4uLnBhcnRzOiAoc3RyaW5nIHwgdW5kZWZpbmVkKVtdKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhcnRzLm1hcChub3JtYWxpemVCYXNlUGF0aCkuZmlsdGVyKEJvb2xlYW4pLmpvaW4oXCIvXCIpO1xufVxuXG4vKipcbiAqIFByZWZpeGVzIGFuIGFic29sdXRlIGFwcCBwYXRoIChhIGhlYWx0aCBjaGVjayBwYXRoLCBzYXkpIHdpdGggYGJhc2VQYXRoYCxcbiAqIGFsd2F5cyByZXR1cm5pbmcgYSBsZWFkaW5nIHNsYXNoLiBBbiBlbXB0eSBvciB1bnNldCBgYmFzZVBhdGhgIG9ubHlcbiAqIG5vcm1hbGl6ZXMgdGhhdCBsZWFkaW5nIHNsYXNoLiBBbnl0aGluZyBhZnRlciB0aGUgZmlyc3Qgc2VnbWVudCBpcyBwYXNzZWRcbiAqIHRocm91Z2ggYXMgZ2l2ZW4sIHRyYWlsaW5nIHNsYXNoIGluY2x1ZGVkLCBzaW5jZSBhIGB0cmFpbGluZ1NsYXNoYCBhcHBcbiAqIGFuc3dlcnMgXCIvYXBpL2hlYWx0aFwiIGFuZCBcIi9hcGkvaGVhbHRoL1wiIGRpZmZlcmVudGx5LlxuICpcbiAqIFVzZSB0aGlzIGZvciBwYXRocyBoYW5kZWQgdG8gc29tZXRoaW5nIHRoYXQgdGFsa3MgdG8gdGhlIGFwcCBkaXJlY3RseSDigJQgYW4gQUxCXG4gKiB0YXJnZXQgZ3JvdXAgaGVhbHRoIGNoZWNrLCB0aGUgTGFtYmRhIFdlYiBBZGFwdGVyIHJlYWRpbmVzcyBjaGVjayDigJQgc2luY2UgdGhlXG4gKiBhcHAgb25seSBhbnN3ZXJzIHVuZGVyIGl0cyBvd24gYGJhc2VQYXRoYC5cbiAqXG4gKiBQcmVmaXhlcyB1bmNvbmRpdGlvbmFsbHksIHNvIGBwYXRoYCBoYXMgdG8gYXJyaXZlIGFzIHRoZSBhcHAgcm91dGVzIGl0LFxuICogd2l0aG91dCBgYmFzZVBhdGhgOiBmb3IgYW4gYXBwIGJhc2VkIGF0IFwiL2Jhc2VcIiwgXCIvYmFzZS9hcGkvaGVhbHRoXCIgYmVjb21lc1xuICogXCIvYmFzZS9iYXNlL2FwaS9oZWFsdGhcIi4gRGVsaWJlcmF0ZWx5IG5vdCBzcGVjaWFsLWNhc2VkIOKAlCBhbiBhcHAgY2FuIHJvdXRlXG4gKiBcIi9iYXNlL2Jhc2UvLi4uXCIgbGVnaXRpbWF0ZWx5LCBhbmQgYWNjZXB0aW5nIGJvdGggc3BlbGxpbmdzIHdvdWxkIGdpdmUgdGhlXG4gKiBwYXRoIHR3byBtZWFuaW5ncy4gU2VlIGBkb2NzL2JyZWFraW5nLWNoYW5nZXMubWRgICgwLjYuMCksIHdoaWNoIHRlbGxzIHVzZXJzXG4gKiB3aG8gcHJlZml4ZWQgYGhlYWx0aENoZWNrUGF0aGAgYnkgaGFuZCB0byBkcm9wIHRoZSBwcmVmaXguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmVmaXhXaXRoQmFzZVBhdGgoXG4gIGJhc2VQYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIHBhdGg6IHN0cmluZyxcbik6IHN0cmluZyB7XG4gIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVCYXNlUGF0aChiYXNlUGF0aCk7XG4gIGNvbnN0IGFic29sdXRlID0gcGF0aC5zdGFydHNXaXRoKFwiL1wiKSA/IHBhdGggOiBgLyR7cGF0aH1gO1xuICByZXR1cm4gbm9ybWFsaXplZCA/IGAvJHtub3JtYWxpemVkfSR7YWJzb2x1dGV9YCA6IGFic29sdXRlO1xufVxuXG4vKipcbiAqIFJlYWQgdGhlIE5leHQuanMgYXBwJ3Mgb3duIGBiYXNlUGF0aGAgb3V0IG9mIGByZXF1aXJlZC1zZXJ2ZXItZmlsZXMuanNvbmAsXG4gKiB3aGljaCBgbmV4dCBidWlsZGAgd3JpdGVzIGludG8gYC5uZXh0YCB3aXRoIHRoZSBmdWxseSByZXNvbHZlZCBjb25maWcgKHNvXG4gKiB0aGlzIHBpY2tzIHVwIGEgYGJhc2VQYXRoYCBjb21wdXRlZCBpbiBgbmV4dC5jb25maWcuanNgLCBub3Qgb25seSBhIGxpdGVyYWxcbiAqIG9uZSkuIE5vcm1hbGl6ZWQsIGVtcHR5IHdoZW4gdGhlIGFwcCBzZXRzIG5vbmUuXG4gKlxuICogRGVncmFkZXMgdG8gYFwiXCJgIHJhdGhlciB0aGFuIHRocm93aW5nLCBzaW5jZSBhbiB1bnJlYWRhYmxlIGZpbGUgc2hvdWxkbid0XG4gKiBmYWlsIGEgZGVwbG95bWVudCB0aGF0IHdvdWxkIG90aGVyd2lzZSB3b3JrLiBJdCB3YXJucyBiZWNhdXNlIGBcIlwiYCBpc1xuICogaW5kaXN0aW5ndWlzaGFibGUgZnJvbSBhbiBhcHAgdGhhdCBnZW51aW5lbHkgc2V0cyBubyBgYmFzZVBhdGhgOiB0aGVcbiAqIGBOZXh0anNUeXBlYHMgdGhhdCBkZXJpdmUgYGJhc2VQYXRoYCBmcm9tIHRoZSBhcHAgd291bGQgcXVpZXRseSBub3QgZGVyaXZlXG4gKiBpdCBhbmQgNDA0IGV2ZXJ5IHN0YXRpYyBhc3NldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWROZXh0Q29uZmlnQmFzZVBhdGgoZG90TmV4dFBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHJlcXVpcmVkU2VydmVyRmlsZXMgPSBqb2luKGRvdE5leHRQYXRoLCBcInJlcXVpcmVkLXNlcnZlci1maWxlcy5qc29uXCIpO1xuICBjb25zdCBmYWxsYmFjayA9IChyZWFzb246IHN0cmluZykgPT4ge1xuICAgIGNvbnNvbGUud2FybihcbiAgICAgIGAke0xPR19QUkVGSVh9ICR7cmVhc29ufS4gQXNzdW1pbmcgeW91ciBOZXh0LmpzIGFwcCBzZXRzIG5vIFxcYGJhc2VQYXRoXFxgOiBgICtcbiAgICAgICAgXCJpZiBpdCBkb2VzIHNldCBvbmUsIHN0YXRpYyBhc3NldHMgd2lsbCA0MDQgYW5kIGFueSBgYmFzZVBhdGhgIHByb3AgXCIgK1xuICAgICAgICBcIm1pc21hdGNoIHJlcG9ydGVkIGF0IHN5bnRoIHdpbGwgbmFtZSB0aGUgd3JvbmcgdmFsdWUuXCIsXG4gICAgKTtcbiAgICByZXR1cm4gXCJcIjtcbiAgfTtcbiAgaWYgKCFleGlzdHNTeW5jKHJlcXVpcmVkU2VydmVyRmlsZXMpKSB7XG4gICAgcmV0dXJuIGZhbGxiYWNrKFxuICAgICAgYFwicmVxdWlyZWQtc2VydmVyLWZpbGVzLmpzb25cIiBub3QgZm91bmQgYXQgJHtyZXF1aXJlZFNlcnZlckZpbGVzfWAsXG4gICAgKTtcbiAgfVxuICB0cnkge1xuICAgIGNvbnN0IHsgY29uZmlnIH0gPSBKU09OLnBhcnNlKHJlYWRGaWxlU3luYyhyZXF1aXJlZFNlcnZlckZpbGVzLCBcInV0Zi04XCIpKTtcbiAgICByZXR1cm4gbm9ybWFsaXplQmFzZVBhdGgoY29uZmlnPy5iYXNlUGF0aCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIGZhbGxiYWNrKFxuICAgICAgYENvdWxkIG5vdCByZWFkIGJhc2VQYXRoIGZyb20gJHtyZXF1aXJlZFNlcnZlckZpbGVzfTogJHtlcnJvcn1gLFxuICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcXVvdGUoYmFzZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBiYXNlUGF0aCA/IGBcIi8ke2Jhc2VQYXRofVwiYCA6IFwidW5zZXRcIjtcbn1cblxuLyoqXG4gKiBTZXR0bGVzIG9uIHRoZSBzaW5nbGUgYGJhc2VQYXRoYCB0aGUgaW5mcmFzdHJ1Y3R1cmUgc2hvdWxkIGJlIGJ1aWx0IGFyb3VuZCxcbiAqIGdpdmVuIHRoZSBDREsgYGJhc2VQYXRoYCBwcm9wIGFuZCB0aGUgTmV4dC5qcyBhcHAncyBvd24gYGJhc2VQYXRoYFxuICogKGBOZXh0anNCdWlsZC5uZXh0Q29uZmlnQmFzZVBhdGhgKSwgdGhyb3dpbmcgYXQgc3ludGggaWYgdGhlIHR3byBjYW4ndCBzZXJ2ZVxuICogdGhlIGFwcCB0b2dldGhlci4gUmV0dXJucyBhIG5vcm1hbGl6ZWQgdmFsdWUsIG9yIGB1bmRlZmluZWRgIGZvciBub1xuICogYGJhc2VQYXRoYCBhdCBhbGw7IGNvbnN1bWVycyB0aGF0IG5lZWQgYSBsZWFkaW5nIHNsYXNoIGFkZCB0aGVpciBvd24uXG4gKlxuICogVGhlIHR3byBpbnB1dHMgYXJlIGdlbnVpbmVseSBkaWZmZXJlbnQgdGhpbmdzIOKAlCB0aGUgcHJvcCBpcyB3aGVyZSB0aGVcbiAqIGluZnJhc3RydWN0dXJlIHNlcnZlcyB0aGUgYXBwIGZyb20gKGFuZCB3aGljaCBTMyBrZXkgcHJlZml4IHRoZSBzdGF0aWMgYXNzZXRzXG4gKiBsYW5kIHVuZGVyKSwgdGhlIGNvbmZpZyBpcyB0aGUgcHJlZml4IHRoZSBhcHAgZW1pdHMgaXRzIG93biBsaW5rcyBhbmQgYXNzZXRcbiAqIGhyZWZzIHVuZGVyIOKAlCBzbyBob3cgc3RyaWN0bHkgdGhleSBoYXZlIHRvIGxpbmUgdXAsIGFuZCB3aGV0aGVyIG9uZSBjYW4gc3RhbmRcbiAqIGluIGZvciB0aGUgb3RoZXIsIGRlcGVuZHMgb24gaG93IHRoZSBgTmV4dGpzVHlwZWAgcm91dGVzIHN0YXRpYyByZXF1ZXN0cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVCYXNlUGF0aChcbiAgbmV4dGpzVHlwZTogTmV4dGpzVHlwZSxcbiAgcHJvcEJhc2VQYXRoPzogc3RyaW5nLFxuICBuZXh0Q29uZmlnQmFzZVBhdGg/OiBzdHJpbmcsXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBwcm9wID0gbm9ybWFsaXplQmFzZVBhdGgocHJvcEJhc2VQYXRoKTtcbiAgY29uc3QgY29uZmlnID0gbm9ybWFsaXplQmFzZVBhdGgobmV4dENvbmZpZ0Jhc2VQYXRoKTtcbiAgaWYgKHByb3AgPT09IGNvbmZpZykge1xuICAgIHJldHVybiBwcm9wIHx8IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IG1pc21hdGNoID1cbiAgICBgJHtMT0dfUFJFRklYfSBiYXNlUGF0aCBtaXNtYXRjaCBmb3IgTmV4dGpzVHlwZS4ke25leHRqc1R5cGV9OiB0aGUgXFxgYmFzZVBhdGhcXGAgcHJvcCBpcyAke3F1b3RlKHByb3ApfSBgICtcbiAgICBgYnV0IHlvdXIgTmV4dC5qcyBhcHAncyBjb25maWcgc2V0cyBcXGBiYXNlUGF0aFxcYCB0byAke3F1b3RlKGNvbmZpZyl9LiBgO1xuXG4gIHN3aXRjaCAobmV4dGpzVHlwZSkge1xuICAgIGNhc2UgTmV4dGpzVHlwZS5HTE9CQUxfRlVOQ1RJT05TOlxuICAgIGNhc2UgTmV4dGpzVHlwZS5HTE9CQUxfQ09OVEFJTkVSUzpcbiAgICAgIC8vIGBOZXh0anNEaXN0cmlidXRpb25gIGJ1aWxkcyBpdHMgYmVoYXZpb3JzIGFzIGAvJHtiYXNlUGF0aH0vX25leHQvc3RhdGljKmBcbiAgICAgIC8vIGFuZCBDbG91ZEZyb250IGhhbmRzIGFuIFMzIG9yaWdpbiB0aGUgcmVxdWVzdCBwYXRoIHZlcmJhdGltIGFzIHRoZVxuICAgICAgLy8gb2JqZWN0IGtleSwgc28gdGhlIG9ubHkgdmFsdWUgdGhhdCBjYW4gc2VydmUgdGhlIGFwcCBpcyB0aGUgcHJlZml4IHRoZVxuICAgICAgLy8gYXBwIGl0c2VsZiBlbWl0cy4gVGhhdCBsZWF2ZXMgdGhlIHByb3Agbm8gcm9vbSB0byBkaWZmZXIsIHdoaWNoIG1ha2VzXG4gICAgICAvLyB0aGUgYXBwJ3MgY29uZmlnIHRoZSBzaW5nbGUgc291cmNlIG9mIHRydXRoIHdvcnRoIGRlcml2aW5nIGZyb20uXG4gICAgICBpZiAoIXByb3ApIHtcbiAgICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgbWlzbWF0Y2ggK1xuICAgICAgICAgIFwiQ2xvdWRGcm9udCBzZXJ2ZXMgc3RhdGljIGFzc2V0cyBzdHJhaWdodCBmcm9tIFMzIHVzaW5nIHRoZSByZXF1ZXN0IHBhdGggYXMgdGhlIG9iamVjdCBrZXksIHNvIGEgbWlzbWF0Y2ggbWVhbnMgZXZlcnkgYF9uZXh0L3N0YXRpY2AgYW5kIGBwdWJsaWMvYCByZXF1ZXN0IDQwNHMuIFwiICtcbiAgICAgICAgICBcIkVpdGhlciBzZXQgYm90aCB0byB0aGUgc2FtZSB2YWx1ZSwgb3IgZHJvcCB0aGUgcHJvcCDigJQgbGVmdCB1bnNldCwgaXQgZm9sbG93cyB5b3VyIGFwcCdzIGBiYXNlUGF0aGAuXCIsXG4gICAgICApO1xuICAgIGNhc2UgTmV4dGpzVHlwZS5SRUdJT05BTF9GVU5DVElPTlM6XG4gICAgICAvLyBEZWxpYmVyYXRlbHkgbm90IGRlcml2ZWQ6IEFQSSBHYXRld2F5IG1vdW50cyByZXNvdXJjZXMgYmVsb3cgdGhlIHN0YWdlXG4gICAgICAvLyBhbmQgc3RyaXBzIGl0IGJlZm9yZSBpbnZva2luZyB0aGUgYXBwLCBzbyBhbiBhcHAgd2hvc2UgYmFzZVBhdGggaXMgdGhlXG4gICAgICAvLyBzdGFnZSBuYW1lIChvciBhIGN1c3RvbSBkb21haW4gYmFzZSBwYXRoIG1hcHBpbmcgdGhhdCBnZXRzIHN0cmlwcGVkIHRoZVxuICAgICAgLy8gc2FtZSB3YXkpIGlzIGNvcnJlY3QgcHJlY2lzZWx5IGJlY2F1c2UgdGhlIHByb3Agc3RheXMgdW5zZXQuXG4gICAgICBpZiAoIXByb3ApIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIC8vIFRoZSBwcm9wIG9ubHkgaGFzIHRvIGJlIHRoZSB0YWlsIG9mIHdoYXQgdGhlIGFwcCBlbWl0cywgbm90IGFsbCBvZiBpdCxcbiAgICAgIC8vIGJlY2F1c2UgdGhlIHN0cmlwcGVkIHByZWZpeCBpcyBwYXJ0IG9mIHRoZSBhcHAncyBgYmFzZVBhdGhgIGJ1dCBuZXZlclxuICAgICAgLy8gcGFydCBvZiB0aGUgcmVzb3VyY2UgcGF0aDogYW4gYXBwIGF0IHRoZSBgcHJvZGAgc3RhZ2UgbmVzdGVkIHVuZGVyXG4gICAgICAvLyBcIi9iYXNlXCIgc2V0cyBgYmFzZVBhdGg6IFwiL3Byb2QvYmFzZVwiYCBhbmQgdGhlIHByb3AgdG8gXCIvYmFzZVwiLiBDaGVja2VkXG4gICAgICAvLyBvbiBhIHBhdGggYm91bmRhcnkgc28gXCIvcHJvZC9iYXNlXCIgZG9lc24ndCBhY2NlcHQgYSBwcm9wIG9mIFwic2VcIi5cbiAgICAgIGlmIChjb25maWcuZW5kc1dpdGgoYC8ke3Byb3B9YCkpIHtcbiAgICAgICAgcmV0dXJuIHByb3A7XG4gICAgICB9XG4gICAgICAvLyBBbnl0aGluZyBlbHNlIG5ldmVyIHdvcmtzOiB0aGUgcHJvcCBtb3ZlcyBldmVyeSByZXNvdXJjZSwgaW5jbHVkaW5nIHRoZVxuICAgICAgLy8gYEFOWWAgY2F0Y2gtYWxsLCB1bmRlciBhIHBhdGggdGhlIGFwcCBuZXZlciBsaW5rcyB0by5cbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgbWlzbWF0Y2ggK1xuICAgICAgICAgIFwiVGhlIGBiYXNlUGF0aGAgcHJvcCBuZXN0cyBldmVyeSBBUEkgR2F0ZXdheSByZXNvdXJjZSB1bmRlciB0aGF0IHBhdGgsIGluY2x1ZGluZyB0aGUgY2F0Y2gtYWxsLCBzbyB0aGUgYXBwIGhhcyB0byBlbWl0IGl0cyBsaW5rcyB1bmRlciB0aGUgc2FtZSBwcmVmaXggb3IgZXZlcnkgcmVxdWVzdCA0MDRzLiBcIiArXG4gICAgICAgICAgJ0VpdGhlciBzZXQgeW91ciBhcHBcXCdzIGBiYXNlUGF0aGAgdG8gZW5kIHdpdGggdGhlIHByb3AgKG9wdGlvbmFsbHkgcHJlZml4ZWQgYnkgdGhlIHN0YWdlIG9yIGJhc2UgcGF0aCBtYXBwaW5nIEFQSSBHYXRld2F5IHN0cmlwcywgZS5nLiBgYmFzZVBhdGg6IFwiL3Byb2QvYmFzZVwiYCB3aXRoIGEgcHJvcCBvZiBcIi9iYXNlXCIpLCBvciBsZWF2ZSB0aGUgcHJvcCB1bnNldCDigJQgdW5zZXQgaXMgd2hhdCB5b3Ugd2FudCB3aGVuIHRoZSBhcHBcXCdzIGBiYXNlUGF0aGAgaXMgdGhlIEFQSSBHYXRld2F5IHN0YWdlIG5hbWUsIHNpbmNlIHRoZSBzdGFnZSBpc25cXCd0IHBhcnQgb2YgdGhlIHJlc291cmNlIHBhdGguJyxcbiAgICAgICk7XG4gICAgY2FzZSBOZXh0anNUeXBlLlJFR0lPTkFMX0NPTlRBSU5FUlM6XG4gICAgICAvLyBUaGUgQUxCIGZvcndhcmRzIGV2ZXJ5IHBhdGggdG8gdGhlIGNvbnRhaW5lciwgd2hpY2ggc2VydmVzIGl0cyBvd25cbiAgICAgIC8vIHN0YXRpYyBhc3NldHMsIHNvIGhlcmUgYGJhc2VQYXRoYCBvbmx5IG5hbWVzcGFjZXMgdGhlIFMzIGJ1Y2tldCBhbmQgaGFzXG4gICAgICAvLyBubyByb3V0aW5nIG1lYW5pbmcgdGhhdCBjb3VsZCBkaXNhZ3JlZSB3aXRoIHRoZSBhcHAuXG4gICAgICByZXR1cm4gcHJvcCB8fCB1bmRlZmluZWQ7XG4gIH1cbn1cbiJdfQ==
360
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1wYXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL2Jhc2UtcGF0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFZQSw4Q0FFQztBQU9ELHNDQUVDO0FBT0Qsd0NBR0M7QUFjRCw4REFHQztBQU9ELDRCQUVDO0FBb0JELGdEQU9DO0FBc0JELGtEQUVDO0FBMEJELHNEQWdCQztBQWlCRCwwQ0FhQztBQXVIRCwwQ0FtSEM7QUFoYUQ7Ozs7R0FJRztBQUNILDRDQUFzRDtBQUV0RDs7OztHQUlHO0FBQ0gsU0FBZ0IsaUJBQWlCLENBQUMsUUFBaUI7SUFDakQsT0FBTyxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDbEUsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixhQUFhLENBQUMsSUFBWSxFQUFFLE1BQWM7SUFDeEQsT0FBTyxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxLQUFLLE1BQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3hFLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBZ0IsY0FBYyxDQUFDLFFBQWlCO0lBQzlDLE1BQU0sSUFBSSxHQUFHLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3pDLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDaEMsQ0FBQztBQUVEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsU0FBZ0IseUJBQXlCLENBQUMsUUFBaUI7SUFDekQsTUFBTSxNQUFNLEdBQUcsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3hDLE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0s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RUFBMEU7WUFDMUUsd0RBQXdEO1lBQ3hELE1BQU0sSUFBSSxLQUFLLENBQ2IsUUFBUTtnQkFDTiwrS0FBK0s7Z0JBQy9LLGtWQUFrVixDQUNyVixDQUFDO1FBQ0osS0FBSyxzQkFBVSxDQUFDLG1CQUFtQjtZQUNqQyxxRUFBcUU7WUFDckUsMEVBQTBFO1lBQzFFLHVEQUF1RDtZQUN2RCxPQUFPLElBQUksSUFBSSxTQUFTLENBQUM7SUFDN0IsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFB1cmUgYGJhc2VQYXRoYCBhbmQgVVJMIHBhdGggaGVscGVycy4gTm90aGluZyBoZXJlIGltcG9ydHMgYGF3cy1jZGstbGliYCBvclxuICogdG91Y2hlcyB0aGUgZmlsZXN5c3RlbSwgc28gdGhlIGFkYXB0ZXIgYW5kIHJ1bnRpbWUgYnVuZGxlcyBjYW4gaW1wb3J0IGl0IGFzXG4gKiB3ZWxsIGFzIHRoZSBjb25zdHJ1Y3RzLlxuICovXG5pbXBvcnQgeyBMT0dfUFJFRklYLCBOZXh0anNUeXBlIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIFJlZHVjZXMgYSBgYmFzZVBhdGhgIHRvIGEgYmFyZSBwYXRoIHNlZ21lbnQgc28gdmFsdWVzIHRoYXQgYWRkcmVzcyB0aGUgc2FtZVxuICogcGF0aCAoXCIvYmFzZVwiLCBcImJhc2VcIiwgXCIvYmFzZS9cIikgY29tcGFyZSBlcXVhbCBhbmQgY2FuIGJlIGNvbmNhdGVuYXRlZFxuICogd2l0aG91dCBkb3VibGluZyBzZXBhcmF0b3JzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplQmFzZVBhdGgoYmFzZVBhdGg/OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gKGJhc2VQYXRoIHx8IFwiXCIpLnJlcGxhY2UoL15cXC8rLywgXCJcIikucmVwbGFjZSgvXFwvKyQvLCBcIlwiKTtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGBwYXRoYCBpcyBgcHJlZml4YCBvciB1bmRlciBpdCBvbiBhIHNlZ21lbnQgYm91bmRhcnksIHNvIGAvZG9jc2VhcmNoYFxuICogaXMgbm90IHVuZGVyIGAvZG9jc2AuIEFuIGVtcHR5IGBwcmVmaXhgIG1hdGNoZXMgbm90aGluZy4gQm90aCBzaWRlcyBtdXN0IGJlIGluXG4gKiB0aGUgc2FtZSBmb3JtIChib3RoIHdpdGggb3IgYm90aCB3aXRob3V0IHRoZSBsZWFkaW5nIGAvYCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNQYXRoUHJlZml4KHBhdGg6IHN0cmluZywgcHJlZml4OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuICEhcHJlZml4ICYmIChwYXRoID09PSBwcmVmaXggfHwgcGF0aC5zdGFydHNXaXRoKGAke3ByZWZpeH0vYCkpO1xufVxuXG4vKipcbiAqIEEgYGJhc2VQYXRoYCBhcyBOZXh0LmpzIHNwZWxscyBpdCBhbmQgVVJMcyBzdGFydCB3aXRoIGl0OiBvbmUgbGVhZGluZyBzbGFzaCxcbiAqIG5vIHRyYWlsaW5nIG9uZSAoXCIvYmFzZVwiKSwgYFwiXCJgIGZvciBub25lLiBBY2NlcHRzIGFueSBzcGVsbGluZ1xuICoge0BsaW5rIG5vcm1hbGl6ZUJhc2VQYXRofSBkb2VzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYmFzZVBhdGhQcmVmaXgoYmFzZVBhdGg/OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBiYXJlID0gbm9ybWFsaXplQmFzZVBhdGgoYmFzZVBhdGgpO1xuICByZXR1cm4gYmFyZSA/IGAvJHtiYXJlfWAgOiBcIlwiO1xufVxuXG4vKipcbiAqIEludmFsaWRhdGlvbiBwYXRocyBjb3ZlcmluZyBldmVyeSBVUkkgb2YgdGhlIGFwcDogd2hhdCBhIGRlcGxveSBpbnZhbGlkYXRlcyxcbiAqIGFuZCB3aGF0IHRoZSBjYWNoZSBoYW5kbGVyJ3Mgb3ZlcnNpemVkIGJhdGNoZXMsIHJldHJpZXMgYWZ0ZXIgYSBxdW90YSBlcnJvcixcbiAqIGFuZCB0YWdzIHdob3NlIHJvdXRlcyBjb3VsZCBub3QgYWxsIGJlIG5hbWVkIGZhbGwgYmFjayB0by5cbiAqXG4gKiBgLypgIGlzIHRoZSB3aG9sZSBhcHAgb25seSB3aXRob3V0IGEgYGJhc2VQYXRoYC4gYC9iYXNlLypgIG1hdGNoZXMgbmVpdGhlciB0aGVcbiAqIGFwcCdzIHJvb3QsIGAvYmFzZWAsIG5vciBpdHMgUlNDIHBheWxvYWQsIGAvYmFzZT9fcnNjPeKApmAgLSB0aGUgc2FtZSByb290IHRoZVxuICogYHJldmFsaWRhdGVQYXRoKFwiL1wiKWAgdGhhdCBvdmVyZmxvd2VkIG1heSBoYXZlIG5hbWVkIC0gc28gdGhvc2UgYXJlIHNwZWxsZWRcbiAqIG91dC4gYC9iYXNlKmAgd291bGQgY292ZXIgdGhlbSBmb3Igb25lIHdpbGRjYXJkLCBidXQgYWxzbyBldmVyeSBzaWJsaW5nXG4gKiBwcmVmaXggKGAvYmFzZTJgLCBgL2Jhc2VtZW50YCksIHdoaWNoIG1heSBiZSBhbm90aGVyIGFwcCBvbiB0aGUgc2FtZVxuICogZGlzdHJpYnV0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2hvbGVBcHBJbnZhbGlkYXRpb25QYXRocyhiYXNlUGF0aD86IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgY29uc3QgcHJlZml4ID0gYmFzZVBhdGhQcmVmaXgoYmFzZVBhdGgpO1xuICByZXR1cm4gcHJlZml4ID8gW3ByZWZpeCwgYCR7cHJlZml4fT8qYCwgYCR7cHJlZml4fS8qYF0gOiBbXCIvKlwiXTtcbn1cblxuLyoqXG4gKiBKb2lucyBwYXRoIHBhcnRzIHdpdGggYSBzaW5nbGUgXCIvXCIsIG5vcm1hbGl6aW5nIGVhY2ggKHNvIG5vIGxlYWRpbmcgb3JcbiAqIHRyYWlsaW5nIHNsYXNoIHN1cnZpdmVzLCBpbmNsdWRpbmcgb24gdGhlIHJlc3VsdCkgYW5kIGRyb3BwaW5nIHRoZSBlbXB0eVxuICogb25lcywgc28gYW4gdW5zZXQgYGJhc2VQYXRoYCBvciBrZXkgcHJlZml4IGxlYXZlcyB0aGUgcmVzdCB1bnRvdWNoZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBqb2luUGF0aCguLi5wYXJ0czogKHN0cmluZyB8IHVuZGVmaW5lZClbXSk6IHN0cmluZyB7XG4gIHJldHVybiBwYXJ0cy5tYXAobm9ybWFsaXplQmFzZVBhdGgpLmZpbHRlcihCb29sZWFuKS5qb2luKFwiL1wiKTtcbn1cblxuLyoqXG4gKiBQcmVmaXhlcyBhbiBhYnNvbHV0ZSBhcHAgcGF0aCAoYSBoZWFsdGggY2hlY2sgcGF0aCwgc2F5KSB3aXRoIGBiYXNlUGF0aGAsXG4gKiBhbHdheXMgcmV0dXJuaW5nIGEgbGVhZGluZyBzbGFzaC4gQW4gZW1wdHkgb3IgdW5zZXQgYGJhc2VQYXRoYCBvbmx5XG4gKiBub3JtYWxpemVzIHRoYXQgbGVhZGluZyBzbGFzaC4gQW55dGhpbmcgYWZ0ZXIgdGhlIGZpcnN0IHNlZ21lbnQgaXMgcGFzc2VkXG4gKiB0aHJvdWdoIGFzIGdpdmVuLCB0cmFpbGluZyBzbGFzaCBpbmNsdWRlZCwgc2luY2UgYSBgdHJhaWxpbmdTbGFzaGAgYXBwXG4gKiBhbnN3ZXJzIFwiL2FwaS9oZWFsdGhcIiBhbmQgXCIvYXBpL2hlYWx0aC9cIiBkaWZmZXJlbnRseS5cbiAqXG4gKiBVc2UgdGhpcyBmb3IgcGF0aHMgaGFuZGVkIHRvIHNvbWV0aGluZyB0aGF0IHRhbGtzIHRvIHRoZSBhcHAgZGlyZWN0bHkg4oCUIGFuIEFMQlxuICogdGFyZ2V0IGdyb3VwIGhlYWx0aCBjaGVjaywgdGhlIGNvbnRhaW5lcidzIG93biBoZWFsdGggcHJvYmUg4oCUIHNpbmNlIHRoZSBhcHBcbiAqIG9ubHkgYW5zd2VycyB1bmRlciBpdHMgb3duIGBiYXNlUGF0aGAuXG4gKlxuICogUHJlZml4ZXMgdW5jb25kaXRpb25hbGx5LCBzbyBgcGF0aGAgaGFzIHRvIGFycml2ZSBhcyB0aGUgYXBwIHJvdXRlcyBpdCxcbiAqIHdpdGhvdXQgYGJhc2VQYXRoYDogZm9yIGFuIGFwcCBiYXNlZCBhdCBcIi9iYXNlXCIsIFwiL2Jhc2UvYXBpL2hlYWx0aFwiIGJlY29tZXNcbiAqIFwiL2Jhc2UvYmFzZS9hcGkvaGVhbHRoXCIuIERlbGliZXJhdGVseSBub3Qgc3BlY2lhbC1jYXNlZCDigJQgYW4gYXBwIGNhbiByb3V0ZVxuICogXCIvYmFzZS9iYXNlLy4uLlwiIGxlZ2l0aW1hdGVseSwgYW5kIGFjY2VwdGluZyBib3RoIHNwZWxsaW5ncyB3b3VsZCBnaXZlIHRoZVxuICogcGF0aCB0d28gbWVhbmluZ3MuIFNlZSBgZG9jcy9icmVha2luZy1jaGFuZ2VzLm1kYCAoMC42LjApLCB3aGljaCB0ZWxscyB1c2Vyc1xuICogd2hvIHByZWZpeGVkIGBoZWFsdGhDaGVja1BhdGhgIGJ5IGhhbmQgdG8gZHJvcCB0aGUgcHJlZml4LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJlZml4V2l0aEJhc2VQYXRoKFxuICBiYXNlUGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICBwYXRoOiBzdHJpbmcsXG4pOiBzdHJpbmcge1xuICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplQmFzZVBhdGgoYmFzZVBhdGgpO1xuICBjb25zdCBhYnNvbHV0ZSA9IHBhdGguc3RhcnRzV2l0aChcIi9cIikgPyBwYXRoIDogYC8ke3BhdGh9YDtcbiAgcmV0dXJuIG5vcm1hbGl6ZWQgPyBgLyR7bm9ybWFsaXplZH0ke2Fic29sdXRlfWAgOiBhYnNvbHV0ZTtcbn1cblxuLyoqIFdoZXRoZXIgYW4gYGFzc2V0UHJlZml4YCBuYW1lcyBhbiBvcmlnaW4gcmF0aGVyIHRoYW4gYSBwYXRoIG9uIHRoaXMgb25lLiAqL1xuZnVuY3Rpb24gaXNBYnNvbHV0ZUFzc2V0UHJlZml4KGFzc2V0UHJlZml4OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIC9eKFthLXpdW2EtejAtOSsuLV0qOik/XFwvXFwvL2kudGVzdChhc3NldFByZWZpeCk7XG59XG5cbi8qKlxuICogVGhlIGFwcCdzIG93biBgYXNzZXRQcmVmaXhgIGFzIGEgcGF0aCB3aXRoIGEgbGVhZGluZyBhbmQgbm8gdHJhaWxpbmcgc2xhc2hcbiAqIChcIi9jZG5cIiksIG9yIGBcIlwiYCB3aGVuIHRoZSBhcHAgc2V0cyBub25lLlxuICpcbiAqIFJldHVybnMgYFwiXCJgIGZvciBhbiBhYnNvbHV0ZSBgYXNzZXRQcmVmaXhgIChcImh0dHBzOi8vY2RuLmV4YW1wbGUuY29tXCIsIG9yIHRoZVxuICogcHJvdG9jb2wtcmVsYXRpdmUgXCIvL2Nkbi5leGFtcGxlLmNvbVwiKSB0b286IHRoYXQgbmFtZXMgYW4gb3JpZ2luIGNkay1uZXh0anNcbiAqIGRvZXMgbm90IGNvbnRyb2wsIGFuZCBpdCBpcyB0aGUgc3VwcG9ydGVkIHdheSB0byBzZXJ2ZSBhc3NldHMgZnJvbSBlbHNld2hlcmUsXG4gKiBzbyBub3RoaW5nIGFib3V0IGl0IGlzIHdvcnRoIHdhcm5pbmcgYWJvdXQuIFVzZSB7QGxpbmsgYXNzZXRQcmVmaXhQYXRofSBmb3JcbiAqIHdoYXQgdGhlICpkaXN0cmlidXRpb24qIGhhcyB0byBhbnN3ZXIgb24sIHdoaWNoIGluY2x1ZGVzIHRoZSBwYXRoIGFuIGFic29sdXRlXG4gKiBwcmVmaXggY2Fycmllcy5cbiAqXG4gKiBOZXh0LmpzIGFwcGxpZXMgYGFzc2V0UHJlZml4YCBvbiB0b3Agb2YsIG5vdCB1bmRlciwgYGJhc2VQYXRoYCwgc28gdGhlIHJlc3VsdFxuICogaXMgdGhlIHdob2xlIHByZWZpeCBvZiBhIGBfbmV4dC9zdGF0aWNgIFVSTCBhbmQgbXVzdCBub3QgYmUgam9pbmVkIHdpdGhcbiAqIGBiYXNlUGF0aGAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWxhdGl2ZUFzc2V0UHJlZml4KGFzc2V0UHJlZml4OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gaXNBYnNvbHV0ZUFzc2V0UHJlZml4KGFzc2V0UHJlZml4KSA/IFwiXCIgOiBiYXNlUGF0aFByZWZpeChhc3NldFByZWZpeCk7XG59XG5cbi8qKlxuICogV2hldGhlciBhIHBhdGgtc3R5bGUgYGFzc2V0UHJlZml4YCB3b3VsZCBnbyB1bmFuc3dlcmVkIG9uIHRoaXMgYE5leHRqc1R5cGVgLFxuICogaS5lLiB3aGV0aGVyIGV2ZXJ5IGJ1bmRsZSB3b3VsZCA0MDQuXG4gKlxuICogYGFzc2V0UHJlZml4YCBtb3ZlcyBldmVyeSBidW5kbGUgVVJMIHRvIGA8YXNzZXRQcmVmaXg+L19uZXh0L3N0YXRpYy8uLi5gIHdoaWxlXG4gKiB0aGUgb2JqZWN0cyBrZWVwIHRoZWlyIGA8YmFzZVBhdGg+L19uZXh0L3N0YXRpYy8uLi5gIFMzIGtleXMuIFRoZSBHbG9iYWxcbiAqIGBOZXh0anNUeXBlYHMgYW5zd2VyIHRoYXQgd2l0aCBhIGNhY2hlIGJlaGF2aW9yIG9mIHRoZWlyIG93blxuICogKGBOZXh0anNEaXN0cmlidXRpb25gKTsgdGhlIHJlZ2lvbmFsIG9uZXMgaGF2ZSBub3RoaW5nIHRoYXQgbWFwcyB0aGUgcHJlZml4XG4gKiBiYWNrIOKAlCBBUEkgR2F0ZXdheSdzIGBfbmV4dC9zdGF0aWNgIHJlc291cmNlIGFuZCB0aGUgY29udGFpbmVyJ3Mgb3duIGZpbGVzIGFyZVxuICogYm90aCB1bmRlciB0aGUgdW5wcmVmaXhlZCBwYXRoLlxuICpcbiAqIEEgcHJlZml4IGVxdWFsIHRvIHRoZSBhcHAncyBvd24gYGJhc2VQYXRoYCBpcyAqKm5vdCoqIHVuc2VydmVkLCBiZWNhdXNlIHRoYXQgaXNcbiAqIHRoZSB2YWx1ZSBOZXh0LmpzIHJlc29sdmVzIGBhc3NldFByZWZpeGAgdG8gd2hlbiBgYmFzZVBhdGhgIGlzIHNldCBhbmRcbiAqIGBhc3NldFByZWZpeGAgaXMgbm90OiBgLm5leHQvcmVxdWlyZWQtc2VydmVyLWZpbGVzLmpzb25gIGNvbWVzIGJhY2sgYXNcbiAqIGB7XCJhc3NldFByZWZpeFwiOlwiL3Byb2RcIixcImJhc2VQYXRoXCI6XCIvcHJvZFwifWAgZm9yIGFuIGFwcCB0aGF0IG9ubHkgZXZlciBzZXRcbiAqIGBiYXNlUGF0aGAuIFdpdGhvdXQgdGhhdCBleGVtcHRpb24gdGhlIHdhcm5pbmcgZmlyZWQgb24gZXZlcnkgcmVnaW9uYWxcbiAqIGRlcGxveW1lbnQgdGhhdCBzZXRzIGEgYGJhc2VQYXRoYCBhdCBhbGwg4oCUIGluY2x1ZGluZyBgZXhhbXBsZXMvcmVnaW9uYWwtZnVuY3Rpb25zYFxuICog4oCUIHRlbGxpbmcgdXNlcnMgdGhlaXIgYnVuZGxlcyB3b3VsZCA0MDQgYXQgdGhlIG9uZSBwYXRoIHRoYXQgZG9lcyBzZXJ2ZSB0aGVtLlxuICogYE5leHRqc0Rpc3RyaWJ1dGlvbi5yZXNvbHZlQXNzZXRQcmVmaXhgIGRyb3BzIHRoZSBwcmVmaXggZm9yIHRoZSBzYW1lIHJlYXNvbi5cbiAqXG4gKiBCb3RoIHNpZGVzIGdvIHRocm91Z2ggYG5vcm1hbGl6ZUJhc2VQYXRoYCBiZWNhdXNlIHRoZXkgYXJyaXZlIGluIGRpZmZlcmVudFxuICogc2hhcGVzOiBgbmV4dENvbmZpZ0Fzc2V0UHJlZml4YCBjYXJyaWVzIGEgbGVhZGluZyBzbGFzaCAoYFwiL3Byb2RcImApLFxuICogYG5leHRDb25maWdCYXNlUGF0aGAgZG9lcyBub3QgKGBcInByb2RcImApLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBc3NldFByZWZpeFVuc2VydmVkKFxuICBuZXh0anNUeXBlOiBOZXh0anNUeXBlLFxuICBuZXh0Q29uZmlnQXNzZXRQcmVmaXg6IHN0cmluZyxcbiAgbmV4dENvbmZpZ0Jhc2VQYXRoPzogc3RyaW5nLFxuKTogYm9vbGVhbiB7XG4gIGlmICghbmV4dENvbmZpZ0Fzc2V0UHJlZml4KSByZXR1cm4gZmFsc2U7XG4gIGlmIChcbiAgICBuZXh0anNUeXBlID09PSBOZXh0anNUeXBlLkdMT0JBTF9GVU5DVElPTlMgfHxcbiAgICBuZXh0anNUeXBlID09PSBOZXh0anNUeXBlLkdMT0JBTF9DT05UQUlORVJTXG4gICkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gKFxuICAgIG5vcm1hbGl6ZUJhc2VQYXRoKG5leHRDb25maWdBc3NldFByZWZpeCkgIT09XG4gICAgbm9ybWFsaXplQmFzZVBhdGgobmV4dENvbmZpZ0Jhc2VQYXRoKVxuICApO1xufVxuXG4vKipcbiAqIFRoZSAqcGF0aCogZXZlcnkgYnVuZGxlIFVSTCBjYXJyaWVzLCB3aGljaGV2ZXIgZm9ybSBgYXNzZXRQcmVmaXhgIHRha2VzOiBcIi9jZG5cIlxuICogZm9yIGBhc3NldFByZWZpeDogXCIvY2RuXCJgIGFuZCBmb3IgYGFzc2V0UHJlZml4OlxuICogXCJodHRwczovL2Nkbi5leGFtcGxlLmNvbS9jZG5cImAgYWxpa2UsIGBcIlwiYCB3aGVuIHRoZXJlIGlzIG5vbmUgKGFuIGFic29sdXRlXG4gKiBwcmVmaXggd2l0aCBubyBwYXRoLCBvciBubyBwcmVmaXggYXQgYWxsKS5cbiAqXG4gKiBBbiBhYnNvbHV0ZSBwcmVmaXgncyBwYXRoIGNvdW50cyBiZWNhdXNlIGBuZXh0IGJ1aWxkYCBjb21waWxlcyBhIGBiZWZvcmVGaWxlc2BcbiAqIHJld3JpdGUgb2YgaXRzIG93biBmb3IgaXQg4oCUIGAvY2RuL19uZXh0LzpwYXRoKyDihpIgL19uZXh0LzpwYXRoK2Ag4oCUIHNvIGBuZXh0XG4gKiBzdGFydGAgc2VydmVzIGV2ZXJ5IGJ1bmRsZSB1bmRlciB0aGF0IHBhdGggYXMgd2VsbCBhcyB1bmRlciBgL19uZXh0YC4gQSBDRE5cbiAqIGZyb250aW5nIHRoaXMgZGVwbG95bWVudCBhdCB0aGF0IHBhdGggdGhlcmVmb3JlIGhhcyB0byBiZSBhbnN3ZXJlZCwgYW5kIHRoZVxuICogZGlzdHJpYnV0aW9uJ3MgYGFzc2V0UHJlZml4YCBiZWhhdmlvciBpcyB3aGF0IGFuc3dlcnMgaXQuIE1lYXN1cmVkIGFnYWluc3RcbiAqIGB0ZXN0L2UyZS9hcHAtZGlyL2Fzc2V0LXByZWZpeC1hYnNvbHV0ZWA7IHNlZSBgZG9jcy9oYXJuZXNzLWNvdmVyYWdlLm1kYC5cbiAqIFNoYXJlZCB3aXRoIGBOZXh0anNEaXN0cmlidXRpb25gLCB3aG9zZSBgYXNzZXRQcmVmaXhgIHByb3AgYSB1c2VyIGNhbiBhbHNvXG4gKiBzZXQgYnkgaGFuZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2V0UHJlZml4UGF0aChhc3NldFByZWZpeDogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKCFhc3NldFByZWZpeCkgcmV0dXJuIFwiXCI7XG4gIGxldCBwYXRoID0gYXNzZXRQcmVmaXg7XG4gIGlmIChpc0Fic29sdXRlQXNzZXRQcmVmaXgoYXNzZXRQcmVmaXgpKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIGAvL2Nkbi5leGFtcGxlLmNvbS9jZG5gIGlzIHByb3RvY29sLXJlbGF0aXZlLCB3aGljaCBgVVJMYCBvbmx5IHBhcnNlc1xuICAgICAgLy8gd2l0aCBhIGJhc2Ug4oCUIGFueSBiYXNlLCBzaW5jZSBvbmx5IHRoZSBwYXRoIGlzIHJlYWQgb2ZmIGl0LlxuICAgICAgcGF0aCA9IG5ldyBVUkwoYXNzZXRQcmVmaXgsIFwiaHR0cHM6Ly9hc3NldC1wcmVmaXguaW52YWxpZFwiKS5wYXRobmFtZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBcIlwiO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYmFzZVBhdGhQcmVmaXgocGF0aCk7XG59XG5cbi8qKlxuICogVGhlIHBhdGggcHJlZml4IEFQSSBHYXRld2F5IHN0cmlwcyBiZWZvcmUgbWF0Y2hpbmcgcmVzb3VyY2VzLCBhcyBmYXIgYXMgc3ludGhcbiAqIGNhbiB0ZWxsLiBPbmx5IHJlYWQgYnkgYHJlc29sdmVCYXNlUGF0aGAgZm9yIGBSRUdJT05BTF9GVU5DVElPTlNgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwaUdhdGV3YXlQcmVmaXgge1xuICAvKipcbiAgICogVGhlIHN0YWdlIG5hbWUgb24gdGhlIGV4ZWN1dGUtYXBpIGVuZHBvaW50LCBvciB0aGUgYmFzZSBwYXRoIG1hcHBpbmcgb24gYVxuICAgKiBjdXN0b20gZG9tYWluIChgXCJcImAgd2hlbiBtYXBwZWQgYXQgdGhlIHJvb3QpLiBgdW5kZWZpbmVkYCB3aGVuIGl0IGlzIG5vdFxuICAgKiBrbm93biBhdCBzeW50aCDigJQgYSB0b2tlbiDigJQgaW4gd2hpY2ggY2FzZSBub3RoaW5nIGlzIGRlcml2ZWQuXG4gICAqL1xuICByZWFkb25seSBzdHJpcHBlZFByZWZpeD86IHN0cmluZztcbiAgLyoqIFdoZXRoZXIgYSBjdXN0b20gZG9tYWluIGlzIGNvbmZpZ3VyZWQgdGhyb3VnaCBgcmVzdEFwaVByb3BzLmRvbWFpbk5hbWVgLiAqL1xuICByZWFkb25seSBjdXN0b21Eb21haW46IGJvb2xlYW47XG59XG5cbi8qKiBgUmVzdEFwaWAncyBvd24gZGVmYXVsdHM6IHRoZSBgcHJvZGAgc3RhZ2UsIG5vIGN1c3RvbSBkb21haW4uICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9BUElfR0FURVdBWV9QUkVGSVg6IEFwaUdhdGV3YXlQcmVmaXggPSB7XG4gIHN0cmlwcGVkUHJlZml4OiBcInByb2RcIixcbiAgY3VzdG9tRG9tYWluOiBmYWxzZSxcbn07XG5cbi8qKlxuICogVGhlIHJlc291cmNlIHBhdGggYW4gYXBwJ3MgYGJhc2VQYXRoYCBuZWVkcyBvbiBgUkVHSU9OQUxfRlVOQ1RJT05TYCB3aGVuIHRoZVxuICogYGJhc2VQYXRoYCBwcm9wIGlzIHVuc2V0OiB0aGUgYXBwJ3MgYGJhc2VQYXRoYCB3aXRoIHRoZSBwcmVmaXggQVBJIEdhdGV3YXlcbiAqIHN0cmlwcyB0YWtlbiBvZmYgdGhlIGZyb250LCBvciB0aGUgd2hvbGUgb2YgaXQgd2hlbiBpdCBkb2VzIG5vdCBzdGFydCB3aXRoXG4gKiB0aGF0IHByZWZpeC5cbiAqXG4gKiBBbiBhcHAgYXQgdGhlIGBwcm9kYCBzdGFnZSBlbWl0cyBgL3Byb2QvLi4uYCBhbmQgQVBJIEdhdGV3YXkgc3RyaXBzIGAvcHJvZGBcbiAqIGJlZm9yZSBtYXRjaGluZywgc28gYGJhc2VQYXRoOiBcIi9wcm9kXCJgIG5lZWRzIHJlc291cmNlcyBhdCB0aGUgcm9vdCBhbmRcbiAqIGBiYXNlUGF0aDogXCIvcHJvZC9iYXNlXCJgIG5lZWRzIHRoZW0gdW5kZXIgYGJhc2VgLiBBbiBhcHAgd2hvc2UgYGJhc2VQYXRoYCBBUElcbiAqIEdhdGV3YXkgZG9lcyBub3Qgc3RyaXAg4oCUIGEgY3VzdG9tIGRvbWFpbiBtYXBwZWQgYXQgdGhlIHJvb3QsIHNlcnZpbmdcbiAqIGBiYXNlUGF0aDogXCIvZG9jc1wiYCDigJQgbmVlZHMgdGhlbSB1bmRlciBgZG9jc2AuIExlYXZpbmcgdGhhdCBvbmUgYXQgdGhlIHJvb3QgaXNcbiAqIHdoYXQgdXNlZCB0byBoYXBwZW46IGBfbmV4dC9zdGF0aWNgIGFuZCBgcHVibGljL2AgZmVsbCB0aHJvdWdoIHRvIHRoZVxuICogYHtwcm94eSt9YCBjYXRjaC1hbGwsIGFuZCBldmVyeSBidW5kbGUgNDA0J2Qgd2l0aCBub3RoaW5nIHNhaWQgYXQgc3ludGguXG4gKi9cbmZ1bmN0aW9uIGRlcml2ZUFwaUdhdGV3YXlCYXNlUGF0aChcbiAgY29uZmlnOiBzdHJpbmcsXG4gIHsgc3RyaXBwZWRQcmVmaXgsIGN1c3RvbURvbWFpbiB9OiBBcGlHYXRld2F5UHJlZml4LFxuKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKCFjb25maWcgfHwgc3RyaXBwZWRQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3Qgc3RyaXBwZWQgPSBub3JtYWxpemVCYXNlUGF0aChzdHJpcHBlZFByZWZpeCk7XG4gIGlmIChoYXNQYXRoUHJlZml4KGNvbmZpZywgc3RyaXBwZWQpKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5zbGljZShzdHJpcHBlZC5sZW5ndGggKyAxKSB8fCB1bmRlZmluZWQ7XG4gIH1cbiAgd2FyblVuc3RyaXBwZWRCYXNlUGF0aChjb25maWcsIHsgc3RyaXBwZWRQcmVmaXgsIGN1c3RvbURvbWFpbiB9KTtcbiAgcmV0dXJuIGNvbmZpZztcbn1cblxuLyoqXG4gKiBXYXJuIHRoYXQgYW4gYXBwIG1vdW50ZWQgdW5kZXIgaXRzIHdob2xlIGBiYXNlUGF0aGAgaXMgc2VydmVkIHNvbWV3aGVyZSBpdHNcbiAqIG93biBsaW5rcyBkb24ndCByZWFjaCwgd2hlbiBBUEkgR2F0ZXdheSBzdHJpcHMgYSBwcmVmaXggdGhhdCBgYmFzZVBhdGhgIGxhY2tzLlxuICogQm90aCB3YXlzIG9mIGFycml2aW5nIHRoZXJlIHdhcm46IHRoZSBwcm9wIGxlZnQgdW5zZXQgKGRlcml2ZWQgdG8gdGhlIHdob2xlXG4gKiBgYmFzZVBhdGhgKSBhbmQgdGhlIHByb3Agc2V0IHRvIHRoZSBzYW1lIHZhbHVlLlxuICovXG5mdW5jdGlvbiB3YXJuVW5zdHJpcHBlZEJhc2VQYXRoKFxuICBjb25maWc6IHN0cmluZyxcbiAgeyBzdHJpcHBlZFByZWZpeCwgY3VzdG9tRG9tYWluIH06IEFwaUdhdGV3YXlQcmVmaXgsXG4pOiB2b2lkIHtcbiAgY29uc3Qgc3RyaXBwZWQgPSBub3JtYWxpemVCYXNlUGF0aChzdHJpcHBlZFByZWZpeCk7XG4gIGlmIChzdHJpcHBlZFByZWZpeCA9PT0gdW5kZWZpbmVkIHx8ICFzdHJpcHBlZCkge1xuICAgIC8vIEEgdG9rZW4sIG9yIGEgY3VzdG9tIGRvbWFpbiBtYXBwZWQgYXQgdGhlIHJvb3Q6IG5vdGhpbmcgaXMgc3RyaXBwZWQgdGhhdFxuICAgIC8vIHRoZSBhcHAncyBsaW5rcyBjb3VsZCBtaXNzLlxuICAgIHJldHVybjtcbiAgfVxuICBpZiAoY3VzdG9tRG9tYWluKSB7XG4gICAgLy8gVGhlIHNhbWUgbWlzcyB0aHJvdWdoIGEgY3VzdG9tIGRvbWFpbidzIGJhc2UgcGF0aCBtYXBwaW5nOiBzZXJ2ZWQgYXRcbiAgICAvLyBgLzxtYXBwaW5nPi88YmFzZVBhdGg+YCwgbGlua2luZyB0byBgLzxiYXNlUGF0aD4vLi4uYCwgd2hpY2ggbm8gbWFwcGluZ1xuICAgIC8vIGNvdmVycy5cbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBgJHtMT0dfUFJFRklYfSB5b3VyIE5leHQuanMgYXBwJ3MgXFxgYmFzZVBhdGhcXGAgaXMgJHtxdW90ZShjb25maWcpfSwgd2hpY2ggZG9lcyBub3Qgc3RhcnQgd2l0aCB0aGUgY3VzdG9tIGRvbWFpbidzIGJhc2UgcGF0aCBtYXBwaW5nIFwiLyR7c3RyaXBwZWR9XCIuIGAgK1xuICAgICAgICBcIkl0cyBsaW5rcyBhbmQgYnVuZGxlIFVSTHMgd2lsbCBiZSByZXF1ZXN0ZWQgd2l0aG91dCB0aGUgbWFwcGluZywgd2hpY2ggdGhlIGN1c3RvbSBkb21haW4gYW5zd2VycyB3aXRoIDQwMy4gXCIgK1xuICAgICAgICBgU2V0IFxcYGJhc2VQYXRoOiBcIi8ke2pvaW5QYXRoKHN0cmlwcGVkLCBjb25maWcpfVwiXFxgIGluIHlvdXIgbmV4dC5jb25maWcsIG9yIG1hcCB0aGUgZG9tYWluIGF0IHRoZSByb290LmAsXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBSZXNvdXJjZXMgdW5kZXIgdGhlIGFwcCdzIGJhc2VQYXRoIHNlcnZlIGl0IGF0IGAvPHN0YWdlPi88YmFzZVBhdGg+YCwgYnV0XG4gICAgLy8gdGhlIGFwcCdzIG93biBsaW5rcyBhcmUgYC88YmFzZVBhdGg+Ly4uLmAsIHdoaWNoIG1pc3NlcyB0aGUgc3RhZ2UuIEFcbiAgICAvLyB3YXJuaW5nLCBub3QgYW4gZXJyb3I6IGEgZG9tYWluIGF0dGFjaGVkIGFmdGVyIHN5bnRoIChgYWRkRG9tYWluTmFtZWApXG4gICAgLy8gbWFrZXMgaXQgcmlnaHQsIGFuZCBzeW50aCBjYW5ub3Qgc2VlIHRoYXQuXG4gICAgY29uc29sZS53YXJuKFxuICAgICAgYCR7TE9HX1BSRUZJWH0geW91ciBOZXh0LmpzIGFwcCdzIFxcYGJhc2VQYXRoXFxgIGlzICR7cXVvdGUoY29uZmlnKX0sIHdoaWNoIGRvZXMgbm90IHN0YXJ0IHdpdGggdGhlIEFQSSBHYXRld2F5IHN0YWdlIFwiLyR7c3RyaXBwZWR9XCIuIGAgK1xuICAgICAgICBcIkl0cyBsaW5rcyBhbmQgYnVuZGxlIFVSTHMgd2lsbCBiZSByZXF1ZXN0ZWQgd2l0aG91dCB0aGUgc3RhZ2UsIHdoaWNoIHRoZSBleGVjdXRlLWFwaSBlbmRwb2ludCBhbnN3ZXJzIHdpdGggNDAzLiBcIiArXG4gICAgICAgIGBTZXQgXFxgYmFzZVBhdGg6IFwiLyR7am9pblBhdGgoc3RyaXBwZWQsIGNvbmZpZyl9XCJcXGAgaW4geW91ciBuZXh0LmNvbmZpZywgb3Igc2VydmUgdGhlIGFwcCBmcm9tIGEgY3VzdG9tIGRvbWFpbiBtYXBwZWQgYXQgdGhlIHJvb3QuYCxcbiAgICApO1xuICB9XG59XG5cbi8qKiBXaGV0aGVyIEFQSSBHYXRld2F5IHN0cmlwcyB0aGUgZnJvbnQgb2YgYGJhc2VQYXRoYCBiZWZvcmUgbWF0Y2hpbmcgcmVzb3VyY2VzLiAqL1xuZnVuY3Rpb24gc3RhcnRzV2l0aFN0cmlwcGVkUHJlZml4KFxuICBiYXNlUGF0aDogc3RyaW5nLFxuICB7IHN0cmlwcGVkUHJlZml4IH06IEFwaUdhdGV3YXlQcmVmaXgsXG4pOiBib29sZWFuIHtcbiAgY29uc3Qgc3RyaXBwZWQgPSBub3JtYWxpemVCYXNlUGF0aChzdHJpcHBlZFByZWZpeCk7XG4gIHJldHVybiAhIWJhc2VQYXRoICYmIGhhc1BhdGhQcmVmaXgoYmFzZVBhdGgsIHN0cmlwcGVkKTtcbn1cblxuZnVuY3Rpb24gcXVvdGUoYmFzZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBiYXNlUGF0aCA/IGBcIi8ke2Jhc2VQYXRofVwiYCA6IFwidW5zZXRcIjtcbn1cblxuLyoqXG4gKiBTZXR0bGVzIG9uIHRoZSBzaW5nbGUgYGJhc2VQYXRoYCB0aGUgaW5mcmFzdHJ1Y3R1cmUgc2hvdWxkIGJlIGJ1aWx0IGFyb3VuZCxcbiAqIGdpdmVuIHRoZSBDREsgYGJhc2VQYXRoYCBwcm9wIGFuZCB0aGUgTmV4dC5qcyBhcHAncyBvd24gYGJhc2VQYXRoYFxuICogKGBOZXh0anNCdWlsZC5uZXh0Q29uZmlnQmFzZVBhdGhgKSwgdGhyb3dpbmcgYXQgc3ludGggaWYgdGhlIHR3byBjYW4ndCBzZXJ2ZVxuICogdGhlIGFwcCB0b2dldGhlci4gUmV0dXJucyBhIG5vcm1hbGl6ZWQgdmFsdWUsIG9yIGB1bmRlZmluZWRgIGZvciBub1xuICogYGJhc2VQYXRoYCBhdCBhbGw7IGNvbnN1bWVycyB0aGF0IG5lZWQgYSBsZWFkaW5nIHNsYXNoIGFkZCB0aGVpciBvd24uXG4gKlxuICogVGhlIHR3byBpbnB1dHMgYXJlIGdlbnVpbmVseSBkaWZmZXJlbnQgdGhpbmdzIOKAlCB0aGUgcHJvcCBpcyB3aGVyZSB0aGVcbiAqIGluZnJhc3RydWN0dXJlIHNlcnZlcyB0aGUgYXBwIGZyb20gKGFuZCB3aGljaCBTMyBrZXkgcHJlZml4IHRoZSBzdGF0aWMgYXNzZXRzXG4gKiBsYW5kIHVuZGVyKSwgdGhlIGNvbmZpZyBpcyB0aGUgcHJlZml4IHRoZSBhcHAgZW1pdHMgaXRzIG93biBsaW5rcyBhbmQgYXNzZXRcbiAqIGhyZWZzIHVuZGVyIOKAlCBzbyBob3cgc3RyaWN0bHkgdGhleSBoYXZlIHRvIGxpbmUgdXAsIGFuZCB3aGV0aGVyIG9uZSBjYW4gc3RhbmRcbiAqIGluIGZvciB0aGUgb3RoZXIsIGRlcGVuZHMgb24gaG93IHRoZSBgTmV4dGpzVHlwZWAgcm91dGVzIHN0YXRpYyByZXF1ZXN0cy5cbiAqXG4gKiBgYXBpR2F0ZXdheWAgaXMgb25seSByZWFkIGZvciBgUkVHSU9OQUxfRlVOQ1RJT05TYCwgYW5kIG9ubHkgd2hlbiB0aGUgcHJvcCBpc1xuICogdW5zZXQ6IHNlZSBgZGVyaXZlQXBpR2F0ZXdheUJhc2VQYXRoYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVCYXNlUGF0aChcbiAgbmV4dGpzVHlwZTogTmV4dGpzVHlwZSxcbiAgcHJvcEJhc2VQYXRoPzogc3RyaW5nLFxuICBuZXh0Q29uZmlnQmFzZVBhdGg/OiBzdHJpbmcsXG4gIGFwaUdhdGV3YXk6IEFwaUdhdGV3YXlQcmVmaXggPSBERUZBVUxUX0FQSV9HQVRFV0FZX1BSRUZJWCxcbik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHByb3AgPSBub3JtYWxpemVCYXNlUGF0aChwcm9wQmFzZVBhdGgpO1xuICBjb25zdCBjb25maWcgPSBub3JtYWxpemVCYXNlUGF0aChuZXh0Q29uZmlnQmFzZVBhdGgpO1xuICBjb25zdCBtaXNtYXRjaCA9XG4gICAgYCR7TE9HX1BSRUZJWH0gYmFzZVBhdGggbWlzbWF0Y2ggZm9yIE5leHRqc1R5cGUuJHtuZXh0anNUeXBlfTogdGhlIFxcYGJhc2VQYXRoXFxgIHByb3AgaXMgJHtxdW90ZShwcm9wKX0gYCArXG4gICAgYGJ1dCB5b3VyIE5leHQuanMgYXBwJ3MgY29uZmlnIHNldHMgXFxgYmFzZVBhdGhcXGAgdG8gJHtxdW90ZShjb25maWcpfS4gYDtcbiAgaWYgKHByb3AgPT09IGNvbmZpZykge1xuICAgIGlmIChcbiAgICAgIG5leHRqc1R5cGUgPT09IE5leHRqc1R5cGUuUkVHSU9OQUxfRlVOQ1RJT05TICYmXG4gICAgICBzdGFydHNXaXRoU3RyaXBwZWRQcmVmaXgocHJvcCwgYXBpR2F0ZXdheSlcbiAgICApIHtcbiAgICAgIC8vIEFncmVlaW5nIGlzIG5vdCBlbm91Z2ggaGVyZTogQVBJIEdhdGV3YXkgc3RyaXBzIHRoZSBzdGFnZSAob3IgYmFzZSBwYXRoXG4gICAgICAvLyBtYXBwaW5nKSBiZWZvcmUgbWF0Y2hpbmcsIHNvIHJlc291cmNlcyB1bmRlciB0aGUgcHJvcCdzIFwicHJvZFwiIGFyZSBvbmx5XG4gICAgICAvLyByZWFjaGVkIGF0IGAvcHJvZC9wcm9kLy4uLmAsIGFuZCBldmVyeSBsaW5rIHRoZSBhcHAgZW1pdHMgNDAzcy5cbiAgICAgIGNvbnN0IHByb2JsZW0gPVxuICAgICAgICBgQVBJIEdhdGV3YXkgc3RyaXBzIFwiLyR7bm9ybWFsaXplQmFzZVBhdGgoYXBpR2F0ZXdheS5zdHJpcHBlZFByZWZpeCl9XCIgYmVmb3JlIG1hdGNoaW5nIHJlc291cmNlcywgc28gYSBwcm9wIHRoYXQgcmVwZWF0cyBpdCBuZXN0cyBldmVyeSByZXNvdXJjZSB1bmRlciBhIHBhdGggbm8gcmVxdWVzdCByZWFjaGVzLiBgICtcbiAgICAgICAgXCJMZWF2ZSB0aGUgcHJvcCB1bnNldDogaXQgaXMgZGVyaXZlZCBmcm9tIHlvdXIgYXBwJ3MgYGJhc2VQYXRoYCB3aXRoIHRoYXQgcHJlZml4IHRha2VuIG9mZi5cIjtcbiAgICAgIGlmIChhcGlHYXRld2F5LmN1c3RvbURvbWFpbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWlzbWF0Y2ggKyBwcm9ibGVtKTtcbiAgICAgIH1cbiAgICAgIC8vIE9uIHRoZSBleGVjdXRlLWFwaSBlbmRwb2ludCB0aGF0IGlzIGNlcnRhaW4sIGJ1dCBhbiBleHBsaWNpdCBwcm9wIHdpbnM6XG4gICAgICAvLyBhIGRvbWFpbiBhdHRhY2hlZCB3aXRoIGBhZGREb21haW5OYW1lKClgLCBpbnZpc2libGUgaGVyZSwgY2FuIG1hcCB0aGVcbiAgICAgIC8vIHN0YWdlIGF0IGl0cyByb290LCBhbmQgdGhlbiBgL3Byb2QvLi4uYCBkb2VzIHJlYWNoIHJlc291cmNlcyB1bmRlclxuICAgICAgLy8gXCJwcm9kXCIuXG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIG1pc21hdGNoICtcbiAgICAgICAgICBwcm9ibGVtICtcbiAgICAgICAgICBcIiAoSWdub3JlIHRoaXMgaWYgYSBkb21haW4gYXR0YWNoZWQgd2l0aCBgYWRkRG9tYWluTmFtZSgpYCBzZXJ2ZXMgdGhlIGFwcCB3aXRob3V0IHN0cmlwcGluZyB0aGF0IHByZWZpeC4pXCIsXG4gICAgICApO1xuICAgICAgcmV0dXJuIHByb3A7XG4gICAgfVxuICAgIGlmIChuZXh0anNUeXBlID09PSBOZXh0anNUeXBlLlJFR0lPTkFMX0ZVTkNUSU9OUyAmJiBwcm9wKSB7XG4gICAgICAvLyBBZ3JlZWluZyB0aGUgb3RoZXIgd2F5IHJvdW5kIGhhcyB0aGUgdW5zZXQgY2FzZSdzIHByb2JsZW06IHJlc291cmNlc1xuICAgICAgLy8gdW5kZXIgXCJkb2NzXCIgYXJlIHJlYWNoZWQgYXQgYC9wcm9kL2RvY3MvLi4uYCwgdGhlIGFwcCBsaW5rcyB0b1xuICAgICAgLy8gYC9kb2NzLy4uLmAuXG4gICAgICB3YXJuVW5zdHJpcHBlZEJhc2VQYXRoKGNvbmZpZywgYXBpR2F0ZXdheSk7XG4gICAgfVxuICAgIHJldHVybiBwcm9wIHx8IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHN3aXRjaCAobmV4dGpzVHlwZSkge1xuICAgIGNhc2UgTmV4dGpzVHlwZS5HTE9CQUxfRlVOQ1RJT05TOlxuICAgIGNhc2UgTmV4dGpzVHlwZS5HTE9CQUxfQ09OVEFJTkVSUzpcbiAgICAgIC8vIGBOZXh0anNEaXN0cmlidXRpb25gIGJ1aWxkcyBpdHMgYmVoYXZpb3JzIGFzIGAvJHtiYXNlUGF0aH0vX25leHQvc3RhdGljKmBcbiAgICAgIC8vIGFuZCBDbG91ZEZyb250IGhhbmRzIGFuIFMzIG9yaWdpbiB0aGUgcmVxdWVzdCBwYXRoIHZlcmJhdGltIGFzIHRoZVxuICAgICAgLy8gb2JqZWN0IGtleSwgc28gdGhlIG9ubHkgdmFsdWUgdGhhdCBjYW4gc2VydmUgdGhlIGFwcCBpcyB0aGUgcHJlZml4IHRoZVxuICAgICAgLy8gYXBwIGl0c2VsZiBlbWl0cy4gVGhhdCBsZWF2ZXMgdGhlIHByb3Agbm8gcm9vbSB0byBkaWZmZXIsIHdoaWNoIG1ha2VzXG4gICAgICAvLyB0aGUgYXBwJ3MgY29uZmlnIHRoZSBzaW5nbGUgc291cmNlIG9mIHRydXRoIHdvcnRoIGRlcml2aW5nIGZyb20uXG4gICAgICBpZiAoIXByb3ApIHtcbiAgICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgbWlzbWF0Y2ggK1xuICAgICAgICAgIFwiQ2xvdWRGcm9udCBzZXJ2ZXMgc3RhdGljIGFzc2V0cyBzdHJhaWdodCBmcm9tIFMzIHVzaW5nIHRoZSByZXF1ZXN0IHBhdGggYXMgdGhlIG9iamVjdCBrZXksIHNvIGEgbWlzbWF0Y2ggbWVhbnMgZXZlcnkgYF9uZXh0L3N0YXRpY2AgYW5kIGBwdWJsaWMvYCByZXF1ZXN0IDQwNHMuIFwiICtcbiAgICAgICAgICBcIkVpdGhlciBzZXQgYm90aCB0byB0aGUgc2FtZSB2YWx1ZSwgb3IgZHJvcCB0aGUgcHJvcCDigJQgbGVmdCB1bnNldCwgaXQgZm9sbG93cyB5b3VyIGFwcCdzIGBiYXNlUGF0aGAuXCIsXG4gICAgICApO1xuICAgIGNhc2UgTmV4dGpzVHlwZS5SRUdJT05BTF9GVU5DVElPTlM6XG4gICAgICBpZiAoIXByb3ApIHtcbiAgICAgICAgLy8gQSBwcm9wIHRoYXQgaXMgc2V0IGJ1dCBuYW1lcyBubyBwYXRoIChcIi9cIikgaXMgYW4gZXhwbGljaXQgcm9vdFxuICAgICAgICAvLyBtb3VudCwgbm90IFwidW5zZXRcIjogaXQgaXMgaG93IGFuIGFwcCBzYXlzIHRoZSBwcmVmaXggaXMgc3RyaXBwZWQgYnlcbiAgICAgICAgLy8gc29tZXRoaW5nIHN5bnRoIGNhbid0IHNlZSDigJQgYSBkb21haW4gYXR0YWNoZWQgbGF0ZXIgd2l0aFxuICAgICAgICAvLyBgYWRkRG9tYWluTmFtZSh7IGJhc2VQYXRoIH0pYCwgc2F5IOKAlCBzbyBkZXJpdmluZyBoZXJlIHdvdWxkIG5lc3QgdGhlXG4gICAgICAgIC8vIHJlc291cmNlcyB1bmRlciBhIHBhdGggdGhlIHN0cmlwcGVkIHJlcXVlc3RzIG5ldmVyIHJlYWNoLlxuICAgICAgICBpZiAocHJvcEJhc2VQYXRoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZXJpdmVBcGlHYXRld2F5QmFzZVBhdGgoY29uZmlnLCBhcGlHYXRld2F5KTtcbiAgICAgIH1cbiAgICAgIC8vIFRoZSBwcm9wIG9ubHkgaGFzIHRvIGJlIHRoZSB0YWlsIG9mIHdoYXQgdGhlIGFwcCBlbWl0cywgbm90IGFsbCBvZiBpdCxcbiAgICAgIC8vIGJlY2F1c2UgdGhlIHN0cmlwcGVkIHByZWZpeCBpcyBwYXJ0IG9mIHRoZSBhcHAncyBgYmFzZVBhdGhgIGJ1dCBuZXZlclxuICAgICAgLy8gcGFydCBvZiB0aGUgcmVzb3VyY2UgcGF0aDogYW4gYXBwIGF0IHRoZSBgcHJvZGAgc3RhZ2UgbmVzdGVkIHVuZGVyXG4gICAgICAvLyBcIi9iYXNlXCIgc2V0cyBgYmFzZVBhdGg6IFwiL3Byb2QvYmFzZVwiYCBhbmQgdGhlIHByb3AgdG8gXCIvYmFzZVwiLiBFeGFjdGx5XG4gICAgICAvLyB0aGUgc3RyaXBwZWQgcHJlZml4IGFuZCB0aGVuIHRoZSBwcm9wLCBub3QgYW55IHRhaWw6IHdpdGggYSBwcm9wIG9mXG4gICAgICAvLyBcIi9iYXNlXCIgYW4gYXBwIGF0IFwiL2Zvby9iYXNlXCIgaXMgc2VydmVkIGF0IGAvcHJvZC9iYXNlLy4uLmAgYW5kIGxpbmtzXG4gICAgICAvLyB0byBgL2Zvby9iYXNlLy4uLmAsIHdoaWNoIDQwM3MuIE9ubHkgYSB0b2tlbiBzdGFnZSwgd2hpY2ggc3ludGggY2FuJ3RcbiAgICAgIC8vIHJlYWQsIGZhbGxzIGJhY2sgdG8gYSB0YWlsIG9uIGEgcGF0aCBib3VuZGFyeS5cbiAgICAgIGlmIChcbiAgICAgICAgYXBpR2F0ZXdheS5zdHJpcHBlZFByZWZpeCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyBjb25maWcuZW5kc1dpdGgoYC8ke3Byb3B9YClcbiAgICAgICAgICA6IGNvbmZpZyA9PT0gam9pblBhdGgoYXBpR2F0ZXdheS5zdHJpcHBlZFByZWZpeCwgcHJvcClcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gcHJvcDtcbiAgICAgIH1cbiAgICAgIC8vIEFueSB0YWlsIG9uIGEgcGF0aCBib3VuZGFyeSBpcyBhbHNvIHdoYXQgYSBkb21haW4gYXR0YWNoZWQgd2l0aFxuICAgICAgLy8gYGFkZERvbWFpbk5hbWUoeyBiYXNlUGF0aDogXCJ2MVwiIH0pYCBuZWVkcyBmb3IgYW4gYXBwIGF0IFwiL3YxL2Jhc2VcIjpcbiAgICAgIC8vIHN5bnRoIG9ubHkgc2VlcyB0aGUgc3RhZ2UsIHNvIGl0IGNhbid0IHRlbGwgdGhhdCBzZXR1cCBmcm9tIGEgbWlzdGFrZS5cbiAgICAgIC8vIEFuIGV4cGxpY2l0IHByb3Agd2lucywgc28gdGhhdCB3YXJuczsgYSBjdXN0b20gZG9tYWluIGNvbmZpZ3VyZWQgaW5cbiAgICAgIC8vIGByZXN0QXBpUHJvcHMuZG9tYWluTmFtZWAgaXMgdmlzaWJsZSwgc28gdGhlcmUgaXQgc3RpbGwgdGhyb3dzIGJlbG93LlxuICAgICAgaWYgKCFhcGlHYXRld2F5LmN1c3RvbURvbWFpbiAmJiBjb25maWcuZW5kc1dpdGgoYC8ke3Byb3B9YCkpIHtcbiAgICAgICAgY29uc3QgbGVhZGluZyA9IGNvbmZpZy5zbGljZSgwLCAtcHJvcC5sZW5ndGggLSAxKTtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIGAke0xPR19QUkVGSVh9IHRoZSBcXGBiYXNlUGF0aFxcYCBwcm9wIGlzICR7cXVvdGUocHJvcCl9IGFuZCB5b3VyIE5leHQuanMgYXBwJ3MgXFxgYmFzZVBhdGhcXGAgaXMgJHtxdW90ZShjb25maWcpfSwgYCArXG4gICAgICAgICAgICBgc28gdGhlIGFwcCBpcyBzZXJ2ZWQgYXQgXCIvJHtqb2luUGF0aChub3JtYWxpemVCYXNlUGF0aChhcGlHYXRld2F5LnN0cmlwcGVkUHJlZml4KSwgcHJvcCl9XCIgb24gdGhlIGV4ZWN1dGUtYXBpIGVuZHBvaW50IGFuZCBsaW5rcyB0byBcIi8ke2NvbmZpZ31cIi4gYCArXG4gICAgICAgICAgICBgVGhhdCBvbmx5IHdvcmtzIHRocm91Z2ggYSBjdXN0b20gZG9tYWluIHdob3NlIGJhc2UgcGF0aCBtYXBwaW5nIHN0cmlwcyBcIi8ke2xlYWRpbmd9XCIgKFxcYGFkZERvbWFpbk5hbWUoeyBiYXNlUGF0aDogXCIke2xlYWRpbmd9XCIgfSlcXGApOyBvdGhlcndpc2UgZXZlcnkgcmVxdWVzdCA0MDNzLmAsXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBwcm9wO1xuICAgICAgfVxuICAgICAgLy8gQW55dGhpbmcgZWxzZSBuZXZlciB3b3JrczogdGhlIHByb3AgbW92ZXMgZXZlcnkgcmVzb3VyY2UsIGluY2x1ZGluZyB0aGVcbiAgICAgIC8vIGBBTllgIGNhdGNoLWFsbCwgdW5kZXIgYSBwYXRoIHRoZSBhcHAgbmV2ZXIgbGlua3MgdG8uXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIG1pc21hdGNoICtcbiAgICAgICAgICBcIlRoZSBgYmFzZVBhdGhgIHByb3AgbmVzdHMgZXZlcnkgQVBJIEdhdGV3YXkgcmVzb3VyY2UgdW5kZXIgdGhhdCBwYXRoLCBpbmNsdWRpbmcgdGhlIGNhdGNoLWFsbCwgc28gdGhlIGFwcCBoYXMgdG8gZW1pdCBpdHMgbGlua3MgdW5kZXIgdGhlIHNhbWUgcHJlZml4IG9yIGV2ZXJ5IHJlcXVlc3QgNDA0cy4gXCIgK1xuICAgICAgICAgICdFaXRoZXIgc2V0IHlvdXIgYXBwXFwncyBgYmFzZVBhdGhgIHRvIHRoZSBwcm9wLCBvciB0byB0aGUgcHJvcCBwcmVmaXhlZCBieSB0aGUgc3RhZ2Ugb3IgYmFzZSBwYXRoIG1hcHBpbmcgQVBJIEdhdGV3YXkgc3RyaXBzIChlLmcuIGBiYXNlUGF0aDogXCIvcHJvZC9iYXNlXCJgIHdpdGggYSBwcm9wIG9mIFwiL2Jhc2VcIiksIG9yIGxlYXZlIHRoZSBwcm9wIHVuc2V0IOKAlCB1bnNldCBpcyB3aGF0IHlvdSB3YW50IHdoZW4gdGhlIGFwcFxcJ3MgYGJhc2VQYXRoYCBpcyB0aGUgQVBJIEdhdGV3YXkgc3RhZ2UgbmFtZSwgc2luY2UgdGhlIHN0YWdlIGlzblxcJ3QgcGFydCBvZiB0aGUgcmVzb3VyY2UgcGF0aC4nLFxuICAgICAgKTtcbiAgICBjYXNlIE5leHRqc1R5cGUuUkVHSU9OQUxfQ09OVEFJTkVSUzpcbiAgICAgIC8vIFRoZSBBTEIgZm9yd2FyZHMgZXZlcnkgcGF0aCB0byB0aGUgY29udGFpbmVyLCB3aGljaCBzZXJ2ZXMgaXRzIG93blxuICAgICAgLy8gc3RhdGljIGFzc2V0cywgc28gaGVyZSBgYmFzZVBhdGhgIG9ubHkgbmFtZXNwYWNlcyB0aGUgUzMgYnVja2V0IGFuZCBoYXNcbiAgICAgIC8vIG5vIHJvdXRpbmcgbWVhbmluZyB0aGF0IGNvdWxkIGRpc2FncmVlIHdpdGggdGhlIGFwcC5cbiAgICAgIHJldHVybiBwcm9wIHx8IHVuZGVmaW5lZDtcbiAgfVxufVxuIl19