@rooted-adapters/azure-static-webapp 1.0.0-alpha.7 → 1.0.0-alpha.8

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.
@@ -1,6 +1,6 @@
1
1
  import { AdapterRoutes } from "@rooted/adapter";
2
2
  import { Plugin } from "vite";
3
- //#region src/index.d.mts
3
+ //#region src/adapter.d.mts
4
4
  /**
5
5
  * Options for {@link azureStaticWebappAdapter}.
6
6
  */
@@ -20,6 +20,13 @@ type AzureStaticWebappAdapterOptions = {
20
20
  * - Everything else returns a `404` response that serves `404.html`, matching the
21
21
  * standard SPA behaviour: the shell loads and the client-side router takes over.
22
22
  *
23
+ * "Everything else" includes your `:param` routes, so `/recipe/42/` renders but
24
+ * answers `404`. That's why this adapter leaves `dynamicRoutes` at its default.
25
+ * Azure only supports a wildcard at the end of a route and has no per-segment
26
+ * match, so a `/recipe/*` rule would also claim `/recipe/42/extra/`, trading a
27
+ * wrong `404` on a real page for a wrong `200` on a path that isn't one. See
28
+ * [issue #311](https://github.com/Marvin-Brouwer/rooted/issues/311).
29
+ *
23
30
  * @example `vite.config.ts`
24
31
  * ```ts
25
32
  * import { rootedManifest } from '@rooted/application'
@@ -34,7 +41,7 @@ type AzureStaticWebappAdapterOptions = {
34
41
  * })
35
42
  * ```
36
43
  */
37
- declare function azureStaticWebappAdapter(options?: AzureStaticWebappAdapterOptions): Plugin;
44
+ declare function azureStaticWebappAdapter(options?: AzureStaticWebappAdapterOptions): Plugin[];
38
45
  //#endregion
39
46
  export { AzureStaticWebappAdapterOptions, azureStaticWebappAdapter };
40
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC5tdHMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vc3JjL2luZGV4Lm10cyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0tBV1k7Ozs7O0VBS1gsU0FBUzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztpQkEwQk0seUJBQXlCLFVBQVUsa0NBQWtDIn0=
47
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXp1cmUtc3RhdGljLXdlYmFwcC5kLm10cyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi9zcmMvYWRhcHRlci5tdHMiXSwibWFwcGluZ3MiOiI7Ozs7OztLQVdZOzs7OztFQUtYLFNBQVM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O2lCQWlDTSx5QkFBeUIsVUFBVSxrQ0FBa0MifQ==
@@ -0,0 +1,59 @@
1
+ import { writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { staticAdapter } from "@rooted/adapter";
4
+ //#region src/adapter.mts
5
+ /**
6
+ * Adapter for Azure Static Web Apps.
7
+ *
8
+ * Writes `staticwebapp.config.json` to the output directory with routing rules
9
+ * built from the route manifest and/or manual `routes` option:
10
+ * - Pre-rendered routes get explicit `200` entries so Azure serves their HTML directly.
11
+ * - Everything else returns a `404` response that serves `404.html`, matching the
12
+ * standard SPA behaviour: the shell loads and the client-side router takes over.
13
+ *
14
+ * "Everything else" includes your `:param` routes, so `/recipe/42/` renders but
15
+ * answers `404`. That's why this adapter leaves `dynamicRoutes` at its default.
16
+ * Azure only supports a wildcard at the end of a route and has no per-segment
17
+ * match, so a `/recipe/*` rule would also claim `/recipe/42/extra/`, trading a
18
+ * wrong `404` on a real page for a wrong `200` on a path that isn't one. See
19
+ * [issue #311](https://github.com/Marvin-Brouwer/rooted/issues/311).
20
+ *
21
+ * @example `vite.config.ts`
22
+ * ```ts
23
+ * import { rootedManifest } from '@rooted/application'
24
+ * import { generateRouteManifest } from '@rooted/router/manifest'
25
+ * import { azureStaticWebappAdapter } from '@rooted-adapters/azure-static-webapp'
26
+ *
27
+ * export default rootedManifest({
28
+ * plugins: [
29
+ * generateRouteManifest({ glob: './src/**\/_routes.mts', root: './src/_routes.g.mts' }),
30
+ * azureStaticWebappAdapter(),
31
+ * ],
32
+ * })
33
+ * ```
34
+ */
35
+ function azureStaticWebappAdapter(options) {
36
+ return staticAdapter({
37
+ name: "rooted:azure-static-webapp",
38
+ routes: options?.routes,
39
+ async setup({ outputDirectory, resolvedRoutes }) {
40
+ const config = {
41
+ routes: resolvedRoutes.staticPaths.filter((p) => p.split("/").filter(Boolean).length > 0).map((p) => ({
42
+ route: p,
43
+ serve: `/${p.split("/").filter(Boolean).join("/")}/index.html`,
44
+ statusCode: 200
45
+ })),
46
+ trailingSlash: "auto",
47
+ responseOverrides: { 404: {
48
+ rewrite: "/404.html",
49
+ statusCode: 404
50
+ } }
51
+ };
52
+ await writeFile(path.join(outputDirectory, "staticwebapp.config.json"), JSON.stringify(config, void 0, 2), "utf8");
53
+ }
54
+ });
55
+ }
56
+ //#endregion
57
+ export { azureStaticWebappAdapter };
58
+
59
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXp1cmUtc3RhdGljLXdlYmFwcC5tanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vc3JjL2FkYXB0ZXIubXRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHdyaXRlRmlsZSB9IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnXG5pbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnXG5cbmltcG9ydCB7IHN0YXRpY0FkYXB0ZXIgfSBmcm9tICdAcm9vdGVkL2FkYXB0ZXInXG5cbmltcG9ydCB0eXBlIHsgQWRhcHRlclJvdXRlcyB9IGZyb20gJ0Byb290ZWQvYWRhcHRlcidcbmltcG9ydCB0eXBlIHsgUGx1Z2luIH0gZnJvbSAndml0ZSdcblxuLyoqXG4gKiBPcHRpb25zIGZvciB7QGxpbmsgYXp1cmVTdGF0aWNXZWJhcHBBZGFwdGVyfS5cbiAqL1xuZXhwb3J0IHR5cGUgQXp1cmVTdGF0aWNXZWJhcHBBZGFwdGVyT3B0aW9ucyA9IHtcblx0LyoqXG5cdCAqIE1hbnVhbCByb3V0ZSBsaXN0IGZvciBwcm9qZWN0cyB0aGF0IGRvbid0IHVzZSBgZ2VuZXJhdGVSb3V0ZU1hbmlmZXN0YC5cblx0ICogU2VlIHtAbGluayBBZGFwdGVyUm91dGVzfS5cblx0ICovXG5cdHJvdXRlcz86IEFkYXB0ZXJSb3V0ZXNcbn1cblxuLyoqXG4gKiBBZGFwdGVyIGZvciBBenVyZSBTdGF0aWMgV2ViIEFwcHMuXG4gKlxuICogV3JpdGVzIGBzdGF0aWN3ZWJhcHAuY29uZmlnLmpzb25gIHRvIHRoZSBvdXRwdXQgZGlyZWN0b3J5IHdpdGggcm91dGluZyBydWxlc1xuICogYnVpbHQgZnJvbSB0aGUgcm91dGUgbWFuaWZlc3QgYW5kL29yIG1hbnVhbCBgcm91dGVzYCBvcHRpb246XG4gKiAtIFByZS1yZW5kZXJlZCByb3V0ZXMgZ2V0IGV4cGxpY2l0IGAyMDBgIGVudHJpZXMgc28gQXp1cmUgc2VydmVzIHRoZWlyIEhUTUwgZGlyZWN0bHkuXG4gKiAtIEV2ZXJ5dGhpbmcgZWxzZSByZXR1cm5zIGEgYDQwNGAgcmVzcG9uc2UgdGhhdCBzZXJ2ZXMgYDQwNC5odG1sYCwgbWF0Y2hpbmcgdGhlXG4gKiAgIHN0YW5kYXJkIFNQQSBiZWhhdmlvdXI6IHRoZSBzaGVsbCBsb2FkcyBhbmQgdGhlIGNsaWVudC1zaWRlIHJvdXRlciB0YWtlcyBvdmVyLlxuICpcbiAqIFwiRXZlcnl0aGluZyBlbHNlXCIgaW5jbHVkZXMgeW91ciBgOnBhcmFtYCByb3V0ZXMsIHNvIGAvcmVjaXBlLzQyL2AgcmVuZGVycyBidXRcbiAqIGFuc3dlcnMgYDQwNGAuIFRoYXQncyB3aHkgdGhpcyBhZGFwdGVyIGxlYXZlcyBgZHluYW1pY1JvdXRlc2AgYXQgaXRzIGRlZmF1bHQuXG4gKiBBenVyZSBvbmx5IHN1cHBvcnRzIGEgd2lsZGNhcmQgYXQgdGhlIGVuZCBvZiBhIHJvdXRlIGFuZCBoYXMgbm8gcGVyLXNlZ21lbnRcbiAqIG1hdGNoLCBzbyBhIGAvcmVjaXBlLypgIHJ1bGUgd291bGQgYWxzbyBjbGFpbSBgL3JlY2lwZS80Mi9leHRyYS9gLCB0cmFkaW5nIGFcbiAqIHdyb25nIGA0MDRgIG9uIGEgcmVhbCBwYWdlIGZvciBhIHdyb25nIGAyMDBgIG9uIGEgcGF0aCB0aGF0IGlzbid0IG9uZS4gU2VlXG4gKiBbaXNzdWUgIzMxMV0oaHR0cHM6Ly9naXRodWIuY29tL01hcnZpbi1Ccm91d2VyL3Jvb3RlZC9pc3N1ZXMvMzExKS5cbiAqXG4gKiBAZXhhbXBsZSBgdml0ZS5jb25maWcudHNgXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgcm9vdGVkTWFuaWZlc3QgfSBmcm9tICdAcm9vdGVkL2FwcGxpY2F0aW9uJ1xuICogaW1wb3J0IHsgZ2VuZXJhdGVSb3V0ZU1hbmlmZXN0IH0gZnJvbSAnQHJvb3RlZC9yb3V0ZXIvbWFuaWZlc3QnXG4gKiBpbXBvcnQgeyBhenVyZVN0YXRpY1dlYmFwcEFkYXB0ZXIgfSBmcm9tICdAcm9vdGVkLWFkYXB0ZXJzL2F6dXJlLXN0YXRpYy13ZWJhcHAnXG4gKlxuICogZXhwb3J0IGRlZmF1bHQgcm9vdGVkTWFuaWZlc3Qoe1xuICogICBwbHVnaW5zOiBbXG4gKiAgICAgZ2VuZXJhdGVSb3V0ZU1hbmlmZXN0KHsgZ2xvYjogJy4vc3JjLyoqXFwvX3JvdXRlcy5tdHMnLCByb290OiAnLi9zcmMvX3JvdXRlcy5nLm10cycgfSksXG4gKiAgICAgYXp1cmVTdGF0aWNXZWJhcHBBZGFwdGVyKCksXG4gKiAgIF0sXG4gKiB9KVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhenVyZVN0YXRpY1dlYmFwcEFkYXB0ZXIob3B0aW9ucz86IEF6dXJlU3RhdGljV2ViYXBwQWRhcHRlck9wdGlvbnMpOiBQbHVnaW5bXSB7XG5cdHJldHVybiBzdGF0aWNBZGFwdGVyKHtcblx0XHRuYW1lOiAncm9vdGVkOmF6dXJlLXN0YXRpYy13ZWJhcHAnLFxuXHRcdHJvdXRlczogb3B0aW9ucz8ucm91dGVzLFxuXHRcdGFzeW5jIHNldHVwKHsgb3V0cHV0RGlyZWN0b3J5LCByZXNvbHZlZFJvdXRlcyB9KSB7XG5cdFx0XHRjb25zdCBzdGF0aWNSb3V0ZXM6IEF6dXJlUm91dGVbXSA9IHJlc29sdmVkUm91dGVzLnN0YXRpY1BhdGhzXG5cdFx0XHRcdC5maWx0ZXIocCA9PiBwLnNwbGl0KCcvJykuZmlsdGVyKEJvb2xlYW4pLmxlbmd0aCA+IDApXG5cdFx0XHRcdC5tYXAocCA9PiAoe1xuXHRcdFx0XHRcdHJvdXRlOiBwLFxuXHRcdFx0XHRcdHNlcnZlOiBgLyR7cC5zcGxpdCgnLycpLmZpbHRlcihCb29sZWFuKS5qb2luKCcvJyl9L2luZGV4Lmh0bWxgLFxuXHRcdFx0XHRcdHN0YXR1c0NvZGU6IDIwMCBhcyBjb25zdCxcblx0XHRcdFx0fSkpXG5cblx0XHRcdGNvbnN0IGNvbmZpZzogQXp1cmVTdGF0aWNXZWJBcHBDb25maWcgPSB7XG5cdFx0XHRcdHJvdXRlczogc3RhdGljUm91dGVzLFxuXHRcdFx0XHR0cmFpbGluZ1NsYXNoOiAnYXV0bycsXG5cdFx0XHRcdHJlc3BvbnNlT3ZlcnJpZGVzOiB7XG5cdFx0XHRcdFx0NDA0OiB7IHJld3JpdGU6ICcvNDA0Lmh0bWwnLCBzdGF0dXNDb2RlOiA0MDQgfSxcblx0XHRcdFx0fSxcblx0XHRcdH1cblxuXHRcdFx0YXdhaXQgd3JpdGVGaWxlKFxuXHRcdFx0XHRwYXRoLmpvaW4ob3V0cHV0RGlyZWN0b3J5LCAnc3RhdGljd2ViYXBwLmNvbmZpZy5qc29uJyksXG5cdFx0XHRcdEpTT04uc3RyaW5naWZ5KGNvbmZpZywgdW5kZWZpbmVkLCAyKSxcblx0XHRcdFx0J3V0ZjgnLFxuXHRcdFx0KVxuXHRcdH0sXG5cdH0pXG59XG5cbnR5cGUgQXp1cmVSb3V0ZSA9IHsgcm91dGU6IHN0cmluZzsgc2VydmU6IHN0cmluZzsgc3RhdHVzQ29kZTogMjAwIH1cblxudHlwZSBBenVyZVN0YXRpY1dlYkFwcENvbmZpZyA9IHtcblx0cm91dGVzOiBBenVyZVJvdXRlW11cblx0dHJhaWxpbmdTbGFzaDogJ2Fsd2F5cycgfCAnbmV2ZXInIHwgJ2F1dG8nXG5cdHJlc3BvbnNlT3ZlcnJpZGVzOiB7IDQwNDogeyByZXdyaXRlOiBzdHJpbmc7IHN0YXR1c0NvZGU6IDQwNCB9IH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWlEQSxTQUFnQix5QkFBeUIsU0FBcUQ7Q0FDN0YsT0FBTyxjQUFjO0VBQ3BCLE1BQU07RUFDTixRQUFRLFNBQVM7RUFDakIsTUFBTSxNQUFNLEVBQUUsaUJBQWlCLGtCQUFrQjtHQVNoRCxNQUFNLFNBQWtDO0lBQ3ZDLFFBVGtDLGVBQWUsWUFDaEQsUUFBTyxNQUFLLEVBQUUsTUFBTSxHQUFHLENBQUMsQ0FBQyxPQUFPLE9BQU8sQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQ3BELEtBQUksT0FBTTtLQUNWLE9BQU87S0FDUCxPQUFPLElBQUksRUFBRSxNQUFNLEdBQUcsQ0FBQyxDQUFDLE9BQU8sT0FBTyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUU7S0FDbEQsWUFBWTtJQUNiLEVBR21CO0lBQ25CLGVBQWU7SUFDZixtQkFBbUIsRUFDbEIsS0FBSztLQUFFLFNBQVM7S0FBYSxZQUFZO0lBQUksRUFDOUM7R0FDRDtHQUVBLE1BQU0sVUFDTCxLQUFLLEtBQUssaUJBQWlCLDBCQUEwQixHQUNyRCxLQUFLLFVBQVUsUUFBUSxLQUFBLEdBQVcsQ0FBQyxHQUNuQyxNQUNEO0VBQ0Q7Q0FDRCxDQUFDO0FBQ0YifQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rooted-adapters/azure-static-webapp",
3
- "version": "1.0.0-alpha.7",
3
+ "version": "1.0.0-alpha.8",
4
4
  "description": "Adapter for Azure Static Web Apps",
5
5
  "keywords": [
6
6
  "web-components",
@@ -31,20 +31,20 @@
31
31
  },
32
32
  "exports": {
33
33
  ".": {
34
- "import": "./dist/index.mjs",
35
- "types": "./dist/index.d.mts"
34
+ "import": "./dist/azure-static-webapp.mjs",
35
+ "types": "./dist/azure-static-webapp.d.mts"
36
36
  }
37
37
  },
38
38
  "peerDependencies": {
39
- "@rooted/adapter": "1.0.0-alpha.6",
39
+ "@rooted/adapter": "1.0.0-alpha.7",
40
40
  "vite": ">= 8.0.1"
41
41
  },
42
42
  "devDependencies": {
43
- "@rooted/adapter": "1.0.0-alpha.6",
43
+ "@rooted/adapter": "1.0.0-alpha.7",
44
44
  "@rooted/development": "workspace:*",
45
45
  "@rooted/tsdown": "workspace:^",
46
- "@types/node": "^26.4.0",
47
- "tsx": "^4.23.12",
46
+ "@types/node": "^26.4.1",
47
+ "tsx": "^4.23.13",
48
48
  "typescript": "^6.0.3",
49
49
  "vite": "^8.2.2"
50
50
  },
package/dist/index.mjs DELETED
@@ -1,52 +0,0 @@
1
- import { writeFile } from "node:fs/promises";
2
- import path from "node:path";
3
- import { staticAdapter } from "@rooted/adapter";
4
- //#region src/index.mts
5
- /**
6
- * Adapter for Azure Static Web Apps.
7
- *
8
- * Writes `staticwebapp.config.json` to the output directory with routing rules
9
- * built from the route manifest and/or manual `routes` option:
10
- * - Pre-rendered routes get explicit `200` entries so Azure serves their HTML directly.
11
- * - Everything else returns a `404` response that serves `404.html`, matching the
12
- * standard SPA behaviour: the shell loads and the client-side router takes over.
13
- *
14
- * @example `vite.config.ts`
15
- * ```ts
16
- * import { rootedManifest } from '@rooted/application'
17
- * import { generateRouteManifest } from '@rooted/router/manifest'
18
- * import { azureStaticWebappAdapter } from '@rooted-adapters/azure-static-webapp'
19
- *
20
- * export default rootedManifest({
21
- * plugins: [
22
- * generateRouteManifest({ glob: './src/**\/_routes.mts', root: './src/_routes.g.mts' }),
23
- * azureStaticWebappAdapter(),
24
- * ],
25
- * })
26
- * ```
27
- */
28
- function azureStaticWebappAdapter(options) {
29
- return staticAdapter({
30
- name: "rooted:azure-static-webapp",
31
- routes: options?.routes,
32
- async setup({ outputDirectory, resolvedRoutes }) {
33
- const config = {
34
- routes: resolvedRoutes.staticPaths.filter((p) => p.split("/").filter(Boolean).length > 0).map((p) => ({
35
- route: p,
36
- serve: `/${p.split("/").filter(Boolean).join("/")}/index.html`,
37
- statusCode: 200
38
- })),
39
- trailingSlash: "auto",
40
- responseOverrides: { 404: {
41
- rewrite: "/404.html",
42
- statusCode: 404
43
- } }
44
- };
45
- await writeFile(path.join(outputDirectory, "staticwebapp.config.json"), JSON.stringify(config, void 0, 2), "utf8");
46
- }
47
- });
48
- }
49
- //#endregion
50
- export { azureStaticWebappAdapter };
51
-
52
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXgubWpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5tdHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgd3JpdGVGaWxlIH0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcydcbmltcG9ydCBwYXRoIGZyb20gJ25vZGU6cGF0aCdcblxuaW1wb3J0IHsgc3RhdGljQWRhcHRlciB9IGZyb20gJ0Byb290ZWQvYWRhcHRlcidcblxuaW1wb3J0IHR5cGUgeyBBZGFwdGVyUm91dGVzIH0gZnJvbSAnQHJvb3RlZC9hZGFwdGVyJ1xuaW1wb3J0IHR5cGUgeyBQbHVnaW4gfSBmcm9tICd2aXRlJ1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBhenVyZVN0YXRpY1dlYmFwcEFkYXB0ZXJ9LlxuICovXG5leHBvcnQgdHlwZSBBenVyZVN0YXRpY1dlYmFwcEFkYXB0ZXJPcHRpb25zID0ge1xuXHQvKipcblx0ICogTWFudWFsIHJvdXRlIGxpc3QgZm9yIHByb2plY3RzIHRoYXQgZG9uJ3QgdXNlIGBnZW5lcmF0ZVJvdXRlTWFuaWZlc3RgLlxuXHQgKiBTZWUge0BsaW5rIEFkYXB0ZXJSb3V0ZXN9LlxuXHQgKi9cblx0cm91dGVzPzogQWRhcHRlclJvdXRlc1xufVxuXG4vKipcbiAqIEFkYXB0ZXIgZm9yIEF6dXJlIFN0YXRpYyBXZWIgQXBwcy5cbiAqXG4gKiBXcml0ZXMgYHN0YXRpY3dlYmFwcC5jb25maWcuanNvbmAgdG8gdGhlIG91dHB1dCBkaXJlY3Rvcnkgd2l0aCByb3V0aW5nIHJ1bGVzXG4gKiBidWlsdCBmcm9tIHRoZSByb3V0ZSBtYW5pZmVzdCBhbmQvb3IgbWFudWFsIGByb3V0ZXNgIG9wdGlvbjpcbiAqIC0gUHJlLXJlbmRlcmVkIHJvdXRlcyBnZXQgZXhwbGljaXQgYDIwMGAgZW50cmllcyBzbyBBenVyZSBzZXJ2ZXMgdGhlaXIgSFRNTCBkaXJlY3RseS5cbiAqIC0gRXZlcnl0aGluZyBlbHNlIHJldHVybnMgYSBgNDA0YCByZXNwb25zZSB0aGF0IHNlcnZlcyBgNDA0Lmh0bWxgLCBtYXRjaGluZyB0aGVcbiAqICAgc3RhbmRhcmQgU1BBIGJlaGF2aW91cjogdGhlIHNoZWxsIGxvYWRzIGFuZCB0aGUgY2xpZW50LXNpZGUgcm91dGVyIHRha2VzIG92ZXIuXG4gKlxuICogQGV4YW1wbGUgYHZpdGUuY29uZmlnLnRzYFxuICogYGBgdHNcbiAqIGltcG9ydCB7IHJvb3RlZE1hbmlmZXN0IH0gZnJvbSAnQHJvb3RlZC9hcHBsaWNhdGlvbidcbiAqIGltcG9ydCB7IGdlbmVyYXRlUm91dGVNYW5pZmVzdCB9IGZyb20gJ0Byb290ZWQvcm91dGVyL21hbmlmZXN0J1xuICogaW1wb3J0IHsgYXp1cmVTdGF0aWNXZWJhcHBBZGFwdGVyIH0gZnJvbSAnQHJvb3RlZC1hZGFwdGVycy9henVyZS1zdGF0aWMtd2ViYXBwJ1xuICpcbiAqIGV4cG9ydCBkZWZhdWx0IHJvb3RlZE1hbmlmZXN0KHtcbiAqICAgcGx1Z2luczogW1xuICogICAgIGdlbmVyYXRlUm91dGVNYW5pZmVzdCh7IGdsb2I6ICcuL3NyYy8qKlxcL19yb3V0ZXMubXRzJywgcm9vdDogJy4vc3JjL19yb3V0ZXMuZy5tdHMnIH0pLFxuICogICAgIGF6dXJlU3RhdGljV2ViYXBwQWRhcHRlcigpLFxuICogICBdLFxuICogfSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXp1cmVTdGF0aWNXZWJhcHBBZGFwdGVyKG9wdGlvbnM/OiBBenVyZVN0YXRpY1dlYmFwcEFkYXB0ZXJPcHRpb25zKTogUGx1Z2luIHtcblx0cmV0dXJuIHN0YXRpY0FkYXB0ZXIoe1xuXHRcdG5hbWU6ICdyb290ZWQ6YXp1cmUtc3RhdGljLXdlYmFwcCcsXG5cdFx0cm91dGVzOiBvcHRpb25zPy5yb3V0ZXMsXG5cdFx0YXN5bmMgc2V0dXAoeyBvdXRwdXREaXJlY3RvcnksIHJlc29sdmVkUm91dGVzIH0pIHtcblx0XHRcdGNvbnN0IHN0YXRpY1JvdXRlczogQXp1cmVSb3V0ZVtdID0gcmVzb2x2ZWRSb3V0ZXMuc3RhdGljUGF0aHNcblx0XHRcdFx0LmZpbHRlcihwID0+IHAuc3BsaXQoJy8nKS5maWx0ZXIoQm9vbGVhbikubGVuZ3RoID4gMClcblx0XHRcdFx0Lm1hcChwID0+ICh7XG5cdFx0XHRcdFx0cm91dGU6IHAsXG5cdFx0XHRcdFx0c2VydmU6IGAvJHtwLnNwbGl0KCcvJykuZmlsdGVyKEJvb2xlYW4pLmpvaW4oJy8nKX0vaW5kZXguaHRtbGAsXG5cdFx0XHRcdFx0c3RhdHVzQ29kZTogMjAwIGFzIGNvbnN0LFxuXHRcdFx0XHR9KSlcblxuXHRcdFx0Y29uc3QgY29uZmlnOiBBenVyZVN0YXRpY1dlYkFwcENvbmZpZyA9IHtcblx0XHRcdFx0cm91dGVzOiBzdGF0aWNSb3V0ZXMsXG5cdFx0XHRcdHRyYWlsaW5nU2xhc2g6ICdhdXRvJyxcblx0XHRcdFx0cmVzcG9uc2VPdmVycmlkZXM6IHtcblx0XHRcdFx0XHQ0MDQ6IHsgcmV3cml0ZTogJy80MDQuaHRtbCcsIHN0YXR1c0NvZGU6IDQwNCB9LFxuXHRcdFx0XHR9LFxuXHRcdFx0fVxuXG5cdFx0XHRhd2FpdCB3cml0ZUZpbGUoXG5cdFx0XHRcdHBhdGguam9pbihvdXRwdXREaXJlY3RvcnksICdzdGF0aWN3ZWJhcHAuY29uZmlnLmpzb24nKSxcblx0XHRcdFx0SlNPTi5zdHJpbmdpZnkoY29uZmlnLCB1bmRlZmluZWQsIDIpLFxuXHRcdFx0XHQndXRmOCcsXG5cdFx0XHQpXG5cdFx0fSxcblx0fSlcbn1cblxudHlwZSBBenVyZVJvdXRlID0geyByb3V0ZTogc3RyaW5nOyBzZXJ2ZTogc3RyaW5nOyBzdGF0dXNDb2RlOiAyMDAgfVxuXG50eXBlIEF6dXJlU3RhdGljV2ViQXBwQ29uZmlnID0ge1xuXHRyb3V0ZXM6IEF6dXJlUm91dGVbXVxuXHR0cmFpbGluZ1NsYXNoOiAnYWx3YXlzJyB8ICduZXZlcicgfCAnYXV0bydcblx0cmVzcG9uc2VPdmVycmlkZXM6IHsgNDA0OiB7IHJld3JpdGU6IHN0cmluZzsgc3RhdHVzQ29kZTogNDA0IH0gfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUEwQ0EsU0FBZ0IseUJBQXlCLFNBQW1EO0NBQzNGLE9BQU8sY0FBYztFQUNwQixNQUFNO0VBQ04sUUFBUSxTQUFTO0VBQ2pCLE1BQU0sTUFBTSxFQUFFLGlCQUFpQixrQkFBa0I7R0FTaEQsTUFBTSxTQUFrQztJQUN2QyxRQVRrQyxlQUFlLFlBQ2hELFFBQU8sTUFBSyxFQUFFLE1BQU0sR0FBRyxDQUFDLENBQUMsT0FBTyxPQUFPLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUNwRCxLQUFJLE9BQU07S0FDVixPQUFPO0tBQ1AsT0FBTyxJQUFJLEVBQUUsTUFBTSxHQUFHLENBQUMsQ0FBQyxPQUFPLE9BQU8sQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFO0tBQ2xELFlBQVk7SUFDYixFQUdtQjtJQUNuQixlQUFlO0lBQ2YsbUJBQW1CLEVBQ2xCLEtBQUs7S0FBRSxTQUFTO0tBQWEsWUFBWTtJQUFJLEVBQzlDO0dBQ0Q7R0FFQSxNQUFNLFVBQ0wsS0FBSyxLQUFLLGlCQUFpQiwwQkFBMEIsR0FDckQsS0FBSyxVQUFVLFFBQVEsS0FBQSxHQUFXLENBQUMsR0FDbkMsTUFDRDtFQUNEO0NBQ0QsQ0FBQztBQUNGIn0=