@sitblueprint/website-construct 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sitblueprint/website-construct",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "A reusable AWS CDK construct for deploying static websites with optional custom domain support.",
5
5
  "author": "Miguel Merlin <mmerlin@stevens.edu>",
6
6
  "license": "MIT",
@@ -31,16 +31,16 @@
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/jest": "^29.5.14",
34
- "@types/node": "22.7.9",
35
- "aws-cdk-lib": "2.208.0",
34
+ "@types/node": "24.10.1",
35
+ "aws-cdk-lib": "2.237.1",
36
36
  "constructs": "^10.0.0",
37
37
  "jest": "^29.7.0",
38
38
  "prettier": "^3.6.2",
39
39
  "ts-jest": "^29.2.5",
40
- "typescript": "~5.6.3"
40
+ "typescript": "~5.9.3"
41
41
  },
42
42
  "peerDependencies": {
43
- "aws-cdk-lib": "2.208.0",
43
+ "aws-cdk-lib": "2.237.1",
44
44
  "constructs": "^10.0.0"
45
45
  }
46
46
  }
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  Object.defineProperty(exports, "__esModule", { value: true });
26
36
  const assertions_1 = require("aws-cdk-lib/assertions");
27
37
  const cdk = __importStar(require("aws-cdk-lib"));
@@ -226,6 +236,74 @@ describe("Website", () => {
226
236
  Name: "example.com.",
227
237
  });
228
238
  });
239
+ test("configures CloudFront with both subdomain and root domain aliases when includeRootDomain is true", () => {
240
+ const dualDomainConfig = {
241
+ domainName: "example.com",
242
+ subdomainName: "www",
243
+ certificateArn: "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012",
244
+ includeRootDomain: true,
245
+ };
246
+ const props = {
247
+ bucketName: "test-website-bucket",
248
+ indexFile: "index.html",
249
+ errorFile: "error.html",
250
+ domainConfig: dualDomainConfig,
251
+ };
252
+ new lib_1.Website(stack, "TestWebsite", props);
253
+ const template = assertions_1.Template.fromStack(stack);
254
+ template.hasResourceProperties("AWS::CloudFront::Distribution", {
255
+ DistributionConfig: {
256
+ Aliases: ["www.example.com", "example.com"],
257
+ },
258
+ });
259
+ });
260
+ test("creates two Route53 A records when includeRootDomain is true", () => {
261
+ const dualDomainConfig = {
262
+ domainName: "example.com",
263
+ subdomainName: "www",
264
+ certificateArn: "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012",
265
+ includeRootDomain: true,
266
+ };
267
+ const props = {
268
+ bucketName: "test-website-bucket",
269
+ indexFile: "index.html",
270
+ errorFile: "error.html",
271
+ domainConfig: dualDomainConfig,
272
+ };
273
+ new lib_1.Website(stack, "TestWebsite", props);
274
+ const template = assertions_1.Template.fromStack(stack);
275
+ template.resourceCountIs("AWS::Route53::RecordSet", 2);
276
+ template.hasResourceProperties("AWS::Route53::RecordSet", {
277
+ Name: "www.example.com.",
278
+ Type: "A",
279
+ });
280
+ template.hasResourceProperties("AWS::Route53::RecordSet", {
281
+ Name: "example.com.",
282
+ Type: "A",
283
+ });
284
+ });
285
+ test("ignores includeRootDomain if subdomain is empty to avoid duplicates", () => {
286
+ const domainConfigWithoutSub = {
287
+ domainName: "example.com",
288
+ subdomainName: "",
289
+ certificateArn: "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012",
290
+ includeRootDomain: true,
291
+ };
292
+ const props = {
293
+ bucketName: "test-website-bucket",
294
+ indexFile: "index.html",
295
+ errorFile: "error.html",
296
+ domainConfig: domainConfigWithoutSub,
297
+ };
298
+ new lib_1.Website(stack, "TestWebsite", props);
299
+ const template = assertions_1.Template.fromStack(stack);
300
+ template.resourceCountIs("AWS::Route53::RecordSet", 1);
301
+ template.hasResourceProperties("AWS::CloudFront::Distribution", {
302
+ DistributionConfig: {
303
+ Aliases: ["example.com"],
304
+ },
305
+ });
306
+ });
229
307
  });
230
308
  describe("Private methods", () => {
231
309
  test("_getFullDomainName returns correct domain with subdomain", () => {
@@ -289,4 +367,130 @@ describe("Website", () => {
289
367
  });
290
368
  });
291
369
  });
292
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic2l0ZS1jb25zdHJ1Y3QudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIndlYnNpdGUtY29uc3RydWN0LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVEQUF5RDtBQUN6RCxpREFBbUM7QUFDbkMsZ0NBQTZEO0FBRTdELFFBQVEsQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFO0lBQ3ZCLElBQUksR0FBWSxDQUFDO0lBQ2pCLElBQUksS0FBZ0IsQ0FBQztJQUVyQixVQUFVLENBQUMsR0FBRyxFQUFFO1FBQ2QsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3BCLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLFdBQVcsRUFBRTtZQUN0QyxHQUFHLEVBQUUsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUU7U0FDdEQsQ0FBQyxDQUFDO1FBQ0gsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQ25CLDBFQUEwRSxFQUMxRTtZQUNFLEVBQUUsRUFBRSwyQkFBMkI7WUFDL0IsSUFBSSxFQUFFLGNBQWM7U0FDckIsQ0FDRixDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMscUJBQXFCLEVBQUUsR0FBRyxFQUFFO1FBQ25DLElBQUksQ0FBQyw0Q0FBNEMsRUFBRSxHQUFHLEVBQUU7WUFDdEQsTUFBTSxLQUFLLEdBQWlCO2dCQUMxQixVQUFVLEVBQUUscUJBQXFCO2dCQUNqQyxTQUFTLEVBQUUsWUFBWTtnQkFDdkIsU0FBUyxFQUFFLFlBQVk7YUFDeEIsQ0FBQztZQUVGLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFekMsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFM0Ms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O2dCQUMxQixVQUFVLEVBQUUsZ0JBQWdCO2dCQUM1QixTQUFTLEVBQUUsWUFBWTtnQkFDdkIsU0FBUyxFQUFFLFlBQVk7YUFDeEIsQ0FBQztZQUVGLE1BQU0sQ0FBQyxHQUFHLEVBQUU7Z0JBQ1YsSUFBSSxhQUFPLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMzQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUM7WUFFakIsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDM0MsUUFBUSxDQUFDLGVBQWUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUMvQyxRQUFRLENBQUMsZUFBZSxDQUFDLCtCQUErQixFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzdELFFBQVEsQ0FBQyxlQUFlLENBQ3RCLGlEQUFpRCxFQUNqRCxDQUFDLENBQ0YsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLHNFQUFzRSxFQUFFLEdBQUcsRUFBRTtZQUNoRixNQUFNLEtBQUssR0FBaUI7Z0JBQzFCLFVBQVUsRUFBRSxhQUFhO2dCQUN6QixTQUFTLEVBQUUsWUFBWTtnQkFDdkIsU0FBUyxFQUFFLFlBQVk7YUFDeEIsQ0FBQztZQUVGLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFekMsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDM0MsUUFBUSxDQUFDLGVBQWUsQ0FBQyx5QkFBeUIsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN6RCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUZW1wbGF0ZSwgTWF0Y2ggfSBmcm9tIFwiYXdzLWNkay1saWIvYXNzZXJ0aW9uc1wiO1xuaW1wb3J0ICogYXMgY2RrIGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgV2Vic2l0ZSwgV2Vic2l0ZVByb3BzLCBEb21haW5Db25maWcgfSBmcm9tIFwiLi4vbGliXCI7XG5cbmRlc2NyaWJlKFwiV2Vic2l0ZVwiLCAoKSA9PiB7XG4gIGxldCBhcHA6IGNkay5BcHA7XG4gIGxldCBzdGFjazogY2RrLlN0YWNrO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGFwcCA9IG5ldyBjZGsuQXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgY2RrLlN0YWNrKGFwcCwgXCJUZXN0U3RhY2tcIiwge1xuICAgICAgZW52OiB7IGFjY291bnQ6IFwiMTIzNDU2Nzg5MDEyXCIsIHJlZ2lvbjogXCJ1cy1lYXN0LTFcIiB9LFxuICAgIH0pO1xuICAgIHN0YWNrLm5vZGUuc2V0Q29udGV4dChcbiAgICAgIFwiaG9zdGVkLXpvbmU6YWNjb3VudD0xMjM0NTY3ODkwMTI6ZG9tYWluTmFtZT1leGFtcGxlLmNvbTpyZWdpb249dXMtZWFzdC0xXCIsXG4gICAgICB7XG4gICAgICAgIElkOiBcIi9ob3N0ZWR6b25lL1oxMjM0NTY3ODkwMTJcIixcbiAgICAgICAgTmFtZTogXCJleGFtcGxlLmNvbS5cIixcbiAgICAgIH0sXG4gICAgKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJCYXNpYyBmdW5jdGlvbmFsaXR5XCIsICgpID0+IHtcbiAgICB0ZXN0KFwiY3JlYXRlcyBTMyBidWNrZXQgd2l0aCBiYXNpYyBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC13ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6UzM6OkJ1Y2tldFwiLCB7XG4gICAgICAgIFdlYnNpdGVDb25maWd1cmF0aW9uOiB7XG4gICAgICAgICAgSW5kZXhEb2N1bWVudDogXCJpbmRleC5odG1sXCIsXG4gICAgICAgICAgRXJyb3JEb2N1bWVudDogXCJlcnJvci5odG1sXCIsXG4gICAgICAgIH0sXG4gICAgICAgIEJ1Y2tldEVuY3J5cHRpb246IHtcbiAgICAgICAgICBTZXJ2ZXJTaWRlRW5jcnlwdGlvbkNvbmZpZ3VyYXRpb246IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgU2VydmVyU2lkZUVuY3J5cHRpb25CeURlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICBTU0VBbGdvcml0aG06IFwiQUVTMjU2XCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJjcmVhdGVzIENsb3VkRnJvbnQgT3JpZ2luIEFjY2VzcyBJZGVudGl0eVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXG4gICAgICAgIFwiQVdTOjpDbG91ZEZyb250OjpDbG91ZEZyb250T3JpZ2luQWNjZXNzSWRlbnRpdHlcIixcbiAgICAgICAge1xuICAgICAgICAgIENsb3VkRnJvbnRPcmlnaW5BY2Nlc3NJZGVudGl0eUNvbmZpZzoge1xuICAgICAgICAgICAgQ29tbWVudDogTWF0Y2guYW55VmFsdWUoKSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJjcmVhdGVzIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uIHdpdGggY29ycmVjdCBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC13ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6Q2xvdWRGcm9udDo6RGlzdHJpYnV0aW9uXCIsIHtcbiAgICAgICAgRGlzdHJpYnV0aW9uQ29uZmlnOiB7XG4gICAgICAgICAgRGVmYXVsdENhY2hlQmVoYXZpb3I6IHtcbiAgICAgICAgICAgIFZpZXdlclByb3RvY29sUG9saWN5OiBcInJlZGlyZWN0LXRvLWh0dHBzXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBDdXN0b21FcnJvclJlc3BvbnNlczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBFcnJvckNvZGU6IDQwNCxcbiAgICAgICAgICAgICAgUmVzcG9uc2VDb2RlOiA0MDQsXG4gICAgICAgICAgICAgIFJlc3BvbnNlUGFnZVBhdGg6IFwiLzQwNC5odG1sXCIsXG4gICAgICAgICAgICAgIEVycm9yQ2FjaGluZ01pblRUTDogMTgwMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBQcmljZUNsYXNzOiBcIlByaWNlQ2xhc3NfMTAwXCIsXG4gICAgICAgICAgRW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImV4cG9zZXMgQ2xvdWRGcm9udCBkaXN0cmlidXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB3ZWJzaXRlID0gbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3Qod2Vic2l0ZS5kaXN0cmlidXRpb24pLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiQ3VzdG9tIGVycm9yIHBhZ2UgY29uZmlndXJhdGlvblwiLCAoKSA9PiB7XG4gICAgdGVzdChcInVzZXMgY3VzdG9tIG5vdCBmb3VuZCByZXNwb25zZSBwYWdlIHBhdGhcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICAgIG5vdEZvdW5kUmVzcG9uc2VQYWdlUGF0aDogXCIvY3VzdG9tLTQwNC5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIiwge1xuICAgICAgICBEaXN0cmlidXRpb25Db25maWc6IHtcbiAgICAgICAgICBDdXN0b21FcnJvclJlc3BvbnNlczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBFcnJvckNvZGU6IDQwNCxcbiAgICAgICAgICAgICAgUmVzcG9uc2VDb2RlOiA0MDQsXG4gICAgICAgICAgICAgIFJlc3BvbnNlUGFnZVBhdGg6IFwiL2N1c3RvbS00MDQuaHRtbFwiLFxuICAgICAgICAgICAgICBFcnJvckNhY2hpbmdNaW5UVEw6IDE4MDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJ1c2VzIGRlZmF1bHQgNDA0Lmh0bWwgd2hlbiBub3RGb3VuZFJlc3BvbnNlUGFnZVBhdGggaXMgbm90IHByb3ZpZGVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC13ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6Q2xvdWRGcm9udDo6RGlzdHJpYnV0aW9uXCIsIHtcbiAgICAgICAgRGlzdHJpYnV0aW9uQ29uZmlnOiB7XG4gICAgICAgICAgQ3VzdG9tRXJyb3JSZXNwb25zZXM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgRXJyb3JDb2RlOiA0MDQsXG4gICAgICAgICAgICAgIFJlc3BvbnNlQ29kZTogNDA0LFxuICAgICAgICAgICAgICBSZXNwb25zZVBhZ2VQYXRoOiBcIi80MDQuaHRtbFwiLFxuICAgICAgICAgICAgICBFcnJvckNhY2hpbmdNaW5UVEw6IDE4MDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJEb21haW4gY29uZmlndXJhdGlvblwiLCAoKSA9PiB7XG4gICAgY29uc3QgZG9tYWluQ29uZmlnOiBEb21haW5Db25maWcgPSB7XG4gICAgICBkb21haW5OYW1lOiBcImV4YW1wbGUuY29tXCIsXG4gICAgICBzdWJkb21haW5OYW1lOiBcInd3d1wiLFxuICAgICAgY2VydGlmaWNhdGVBcm46XG4gICAgICAgIFwiYXJuOmF3czphY206dXMtZWFzdC0xOjEyMzQ1Njc4OTAxMjpjZXJ0aWZpY2F0ZS8xMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTJcIixcbiAgICB9O1xuXG4gICAgdGVzdChcImNvbmZpZ3VyZXMgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24gd2l0aCBjdXN0b20gZG9tYWluXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC13ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgICBkb21haW5Db25maWcsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIiwge1xuICAgICAgICBEaXN0cmlidXRpb25Db25maWc6IHtcbiAgICAgICAgICBBbGlhc2VzOiBbXCJ3d3cuZXhhbXBsZS5jb21cIl0sXG4gICAgICAgICAgVmlld2VyQ2VydGlmaWNhdGU6IHtcbiAgICAgICAgICAgIEFjbUNlcnRpZmljYXRlQXJuOiBkb21haW5Db25maWcuY2VydGlmaWNhdGVBcm4sXG4gICAgICAgICAgICBTc2xTdXBwb3J0TWV0aG9kOiBcInNuaS1vbmx5XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImNyZWF0ZXMgUm91dGU1MyBBIHJlY29yZCB3aGVuIGRvbWFpbiBjb25maWcgaXMgcHJvdmlkZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICAgIGRvbWFpbkNvbmZpZyxcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OlJvdXRlNTM6OlJlY29yZFNldFwiLCB7XG4gICAgICAgIFR5cGU6IFwiQVwiLFxuICAgICAgICBOYW1lOiBcInd3dy5leGFtcGxlLmNvbS5cIixcbiAgICAgICAgQWxpYXNUYXJnZXQ6IHtcbiAgICAgICAgICBETlNOYW1lOiBNYXRjaC5hbnlWYWx1ZSgpLFxuICAgICAgICAgIEhvc3RlZFpvbmVJZDogTWF0Y2guYW55VmFsdWUoKSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImhhbmRsZXMgZG9tYWluIHdpdGhvdXQgc3ViZG9tYWluXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGRvbWFpbkNvbmZpZ1dpdGhvdXRTdWI6IERvbWFpbkNvbmZpZyA9IHtcbiAgICAgICAgZG9tYWluTmFtZTogXCJleGFtcGxlLmNvbVwiLFxuICAgICAgICBzdWJkb21haW5OYW1lOiBcIlwiLFxuICAgICAgICBjZXJ0aWZpY2F0ZUFybjpcbiAgICAgICAgICBcImFybjphd3M6YWNtOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6Y2VydGlmaWNhdGUvMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyXCIsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgZG9tYWluQ29uZmlnOiBkb21haW5Db25maWdXaXRob3V0U3ViLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6Q2xvdWRGcm9udDo6RGlzdHJpYnV0aW9uXCIsIHtcbiAgICAgICAgRGlzdHJpYnV0aW9uQ29uZmlnOiB7XG4gICAgICAgICAgQWxpYXNlczogW1wiZXhhbXBsZS5jb21cIl0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRcIiwge1xuICAgICAgICBUeXBlOiBcIkFcIixcbiAgICAgICAgTmFtZTogXCJleGFtcGxlLmNvbS5cIixcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlByaXZhdGUgbWV0aG9kc1wiLCAoKSA9PiB7XG4gICAgdGVzdChcIl9nZXRGdWxsRG9tYWluTmFtZSByZXR1cm5zIGNvcnJlY3QgZG9tYWluIHdpdGggc3ViZG9tYWluXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGNvbnN0cnVjdCA9IG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgLy8gQWNjZXNzIHByaXZhdGUgbWV0aG9kIHRocm91Z2ggYnJhY2tldCBub3RhdGlvbiBmb3IgdGVzdGluZ1xuICAgICAgY29uc3QgZ2V0RnVsbERvbWFpbk5hbWUgPSAoY29uc3RydWN0IGFzIGFueSkuX2dldEZ1bGxEb21haW5OYW1lO1xuXG4gICAgICBjb25zdCBkb21haW5Db25maWc6IERvbWFpbkNvbmZpZyA9IHtcbiAgICAgICAgZG9tYWluTmFtZTogXCJleGFtcGxlLmNvbVwiLFxuICAgICAgICBzdWJkb21haW5OYW1lOiBcImJsb2dcIixcbiAgICAgICAgY2VydGlmaWNhdGVBcm46IFwiYXJuOnRlc3RcIixcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGdldEZ1bGxEb21haW5OYW1lKGRvbWFpbkNvbmZpZyk7XG4gICAgICBleHBlY3QocmVzdWx0KS50b0JlKFwiYmxvZy5leGFtcGxlLmNvbVwiKTtcbiAgICB9KTtcblxuICAgIHRlc3QoXCJfZ2V0RnVsbERvbWFpbk5hbWUgcmV0dXJucyByb290IGRvbWFpbiB3aGVuIHN1YmRvbWFpbiBpcyBlbXB0eVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3QtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjb25zdHJ1Y3QgPSBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IGdldEZ1bGxEb21haW5OYW1lID0gKGNvbnN0cnVjdCBhcyBhbnkpLl9nZXRGdWxsRG9tYWluTmFtZTtcblxuICAgICAgY29uc3QgZG9tYWluQ29uZmlnOiBEb21haW5Db25maWcgPSB7XG4gICAgICAgIGRvbWFpbk5hbWU6IFwiZXhhbXBsZS5jb21cIixcbiAgICAgICAgc3ViZG9tYWluTmFtZTogXCJcIixcbiAgICAgICAgY2VydGlmaWNhdGVBcm46IFwiYXJuOnRlc3RcIixcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGdldEZ1bGxEb21haW5OYW1lKGRvbWFpbkNvbmZpZyk7XG4gICAgICBleHBlY3QocmVzdWx0KS50b0JlKFwiZXhhbXBsZS5jb21cIik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiRWRnZSBjYXNlc1wiLCAoKSA9PiB7XG4gICAgdGVzdChcImhhbmRsZXMgbWluaW1hbCBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwibWluaW1hbC1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcbiAgICAgIH0pLm5vdC50b1Rocm93KCk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICAgIHRlbXBsYXRlLnJlc291cmNlQ291bnRJcyhcIkFXUzo6UzM6OkJ1Y2tldFwiLCAxKTtcbiAgICAgIHRlbXBsYXRlLnJlc291cmNlQ291bnRJcyhcIkFXUzo6Q2xvdWRGcm9udDo6RGlzdHJpYnV0aW9uXCIsIDEpO1xuICAgICAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKFxuICAgICAgICBcIkFXUzo6Q2xvdWRGcm9udDo6Q2xvdWRGcm9udE9yaWdpbkFjY2Vzc0lkZW50aXR5XCIsXG4gICAgICAgIDEsXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImRvZXMgbm90IGNyZWF0ZSBSb3V0ZTUzIHJlc291cmNlcyB3aGVuIGRvbWFpbiBjb25maWcgaXMgbm90IHByb3ZpZGVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgICAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKFwiQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRcIiwgMCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
370
+ describe("Preview config on Website", () => {
371
+ let app;
372
+ let stack;
373
+ beforeEach(() => {
374
+ app = new cdk.App();
375
+ stack = new cdk.Stack(app, "PreviewTestStack", {
376
+ env: { account: "123456789012", region: "us-east-1" },
377
+ });
378
+ });
379
+ test("creates two preview buckets by default when previewConfig is enabled", () => {
380
+ const website = new lib_1.Website(stack, "PreviewEnabledWebsite", {
381
+ bucketName: "website-bucket",
382
+ indexFile: "index.html",
383
+ errorFile: "error.html",
384
+ previewConfig: {
385
+ bucketPrefix: "preview-bucket",
386
+ },
387
+ });
388
+ const template = assertions_1.Template.fromStack(stack);
389
+ template.resourceCountIs("AWS::S3::Bucket", 3);
390
+ expect(website.previewEnvironment).toBeDefined();
391
+ });
392
+ test("creates requested number of preview buckets from previewConfig", () => {
393
+ new lib_1.Website(stack, "PreviewEnabledWebsite", {
394
+ bucketName: "website-bucket",
395
+ indexFile: "index.html",
396
+ errorFile: "error.html",
397
+ previewConfig: {
398
+ bucketPrefix: "preview-bucket",
399
+ bucketCount: 3,
400
+ },
401
+ });
402
+ const template = assertions_1.Template.fromStack(stack);
403
+ template.resourceCountIs("AWS::S3::Bucket", 4);
404
+ });
405
+ test("reuses website index and error files for preview buckets", () => {
406
+ new lib_1.Website(stack, "PreviewEnabledWebsite", {
407
+ bucketName: "website-bucket",
408
+ indexFile: "app.html",
409
+ errorFile: "fallback.html",
410
+ previewConfig: {
411
+ bucketPrefix: "preview-bucket",
412
+ },
413
+ });
414
+ const template = assertions_1.Template.fromStack(stack);
415
+ template.hasResourceProperties("AWS::S3::Bucket", {
416
+ BucketName: "preview-bucket-0",
417
+ WebsiteConfiguration: {
418
+ IndexDocument: "app.html",
419
+ ErrorDocument: "fallback.html",
420
+ },
421
+ });
422
+ template.hasResourceProperties("AWS::S3::Bucket", {
423
+ BucketName: "preview-bucket-1",
424
+ WebsiteConfiguration: {
425
+ IndexDocument: "app.html",
426
+ ErrorDocument: "fallback.html",
427
+ },
428
+ });
429
+ });
430
+ test("creates lease table with repo-pr lookup index when preview is enabled", () => {
431
+ new lib_1.Website(stack, "PreviewEnabledWebsite", {
432
+ bucketName: "website-bucket",
433
+ indexFile: "index.html",
434
+ errorFile: "error.html",
435
+ previewConfig: {
436
+ bucketPrefix: "preview-bucket",
437
+ },
438
+ });
439
+ const template = assertions_1.Template.fromStack(stack);
440
+ template.hasResourceProperties("AWS::DynamoDB::Table", {
441
+ KeySchema: [
442
+ {
443
+ AttributeName: "slotId",
444
+ KeyType: "HASH",
445
+ },
446
+ ],
447
+ GlobalSecondaryIndexes: [
448
+ {
449
+ IndexName: "RepoPrKeyIndex",
450
+ KeySchema: [
451
+ {
452
+ AttributeName: "repoPrKey",
453
+ KeyType: "HASH",
454
+ },
455
+ ],
456
+ Projection: {
457
+ ProjectionType: "ALL",
458
+ },
459
+ },
460
+ ],
461
+ });
462
+ });
463
+ test("creates lease API routes when preview is enabled", () => {
464
+ new lib_1.Website(stack, "PreviewEnabledWebsite", {
465
+ bucketName: "website-bucket",
466
+ indexFile: "index.html",
467
+ errorFile: "error.html",
468
+ previewConfig: {
469
+ bucketPrefix: "preview-bucket",
470
+ },
471
+ });
472
+ const template = assertions_1.Template.fromStack(stack);
473
+ template.hasResourceProperties("AWS::ApiGateway::Resource", {
474
+ PathPart: "claim",
475
+ });
476
+ template.hasResourceProperties("AWS::ApiGateway::Resource", {
477
+ PathPart: "heartbeat",
478
+ });
479
+ template.hasResourceProperties("AWS::ApiGateway::Resource", {
480
+ PathPart: "release",
481
+ });
482
+ template.resourceCountIs("AWS::ApiGateway::Method", 3);
483
+ });
484
+ test("does not create preview resources when previewConfig is omitted", () => {
485
+ const website = new lib_1.Website(stack, "WebsiteWithoutPreview", {
486
+ bucketName: "website-bucket",
487
+ indexFile: "index.html",
488
+ errorFile: "error.html",
489
+ });
490
+ const template = assertions_1.Template.fromStack(stack);
491
+ template.resourceCountIs("AWS::DynamoDB::Table", 0);
492
+ template.resourceCountIs("AWS::ApiGateway::RestApi", 0);
493
+ expect(website.previewEnvironment).toBeUndefined();
494
+ });
495
+ });
496
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic2l0ZS1jb25zdHJ1Y3QudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIndlYnNpdGUtY29uc3RydWN0LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1REFBeUQ7QUFDekQsaURBQW1DO0FBQ25DLGdDQUE2RDtBQUU3RCxRQUFRLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRTtJQUN2QixJQUFJLEdBQVksQ0FBQztJQUNqQixJQUFJLEtBQWdCLENBQUM7SUFFckIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNwQixLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxXQUFXLEVBQUU7WUFDdEMsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFO1NBQ3RELENBQUMsQ0FBQztRQUNILEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUNuQiwwRUFBMEUsRUFDMUU7WUFDRSxFQUFFLEVBQUUsMkJBQTJCO1lBQy9CLElBQUksRUFBRSxjQUFjO1NBQ3JCLENBQ0YsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLHFCQUFxQixFQUFFLEdBQUcsRUFBRTtRQUNuQyxJQUFJLENBQUMsNENBQTRDLEVBQUUsR0FBRyxFQUFFO1lBQ3RELE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxpQkFBaUIsRUFBRTtnQkFDaEQsb0JBQW9CLEVBQUU7b0JBQ3BCLGFBQWEsRUFBRSxZQUFZO29CQUMzQixhQUFhLEVBQUUsWUFBWTtpQkFDNUI7Z0JBQ0QsZ0JBQWdCLEVBQUU7b0JBQ2hCLGlDQUFpQyxFQUFFO3dCQUNqQzs0QkFDRSw2QkFBNkIsRUFBRTtnQ0FDN0IsWUFBWSxFQUFFLFFBQVE7NkJBQ3ZCO3lCQUNGO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsMkNBQTJDLEVBQUUsR0FBRyxFQUFFO1lBQ3JELE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FDNUIsaURBQWlELEVBQ2pEO2dCQUNFLG9DQUFvQyxFQUFFO29CQUNwQyxPQUFPLEVBQUUsa0JBQUssQ0FBQyxRQUFRLEVBQUU7aUJBQzFCO2FBQ0YsQ0FDRixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsNERBQTRELEVBQUUsR0FBRyxFQUFFO1lBQ3RFLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQywrQkFBK0IsRUFBRTtnQkFDOUQsa0JBQWtCLEVBQUU7b0JBQ2xCLG9CQUFvQixFQUFFO3dCQUNwQixvQkFBb0IsRUFBRSxtQkFBbUI7cUJBQzFDO29CQUNELG9CQUFvQixFQUFFO3dCQUNwQjs0QkFDRSxTQUFTLEVBQUUsR0FBRzs0QkFDZCxZQUFZLEVBQUUsR0FBRzs0QkFDakIsZ0JBQWdCLEVBQUUsV0FBVzs0QkFDN0Isa0JBQWtCLEVBQUUsSUFBSTt5QkFDekI7cUJBQ0Y7b0JBQ0QsVUFBVSxFQUFFLGdCQUFnQjtvQkFDNUIsT0FBTyxFQUFFLElBQUk7aUJBQ2Q7YUFDRixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxpQ0FBaUMsRUFBRSxHQUFHLEVBQUU7WUFDM0MsTUFBTSxLQUFLLEdBQWlCO2dCQUMxQixVQUFVLEVBQUUscUJBQXFCO2dCQUNqQyxTQUFTLEVBQUUsWUFBWTtnQkFDdkIsU0FBUyxFQUFFLFlBQVk7YUFDeEIsQ0FBQztZQUVGLE1BQU0sT0FBTyxHQUFHLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFekQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGlDQUFpQyxFQUFFLEdBQUcsRUFBRTtRQUMvQyxJQUFJLENBQUMsMENBQTBDLEVBQUUsR0FBRyxFQUFFO1lBQ3BELE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2Qix3QkFBd0IsRUFBRSxrQkFBa0I7YUFDN0MsQ0FBQztZQUVGLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFekMsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFM0MsUUFBUSxDQUFDLHFCQUFxQixDQUFDLCtCQUErQixFQUFFO2dCQUM5RCxrQkFBa0IsRUFBRTtvQkFDbEIsb0JBQW9CLEVBQUU7d0JBQ3BCOzRCQUNFLFNBQVMsRUFBRSxHQUFHOzRCQUNkLFlBQVksRUFBRSxHQUFHOzRCQUNqQixnQkFBZ0IsRUFBRSxrQkFBa0I7NEJBQ3BDLGtCQUFrQixFQUFFLElBQUk7eUJBQ3pCO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMscUVBQXFFLEVBQUUsR0FBRyxFQUFFO1lBQy9FLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQywrQkFBK0IsRUFBRTtnQkFDOUQsa0JBQWtCLEVBQUU7b0JBQ2xCLG9CQUFvQixFQUFFO3dCQUNwQjs0QkFDRSxTQUFTLEVBQUUsR0FBRzs0QkFDZCxZQUFZLEVBQUUsR0FBRzs0QkFDakIsZ0JBQWdCLEVBQUUsV0FBVzs0QkFDN0Isa0JBQWtCLEVBQUUsSUFBSTt5QkFDekI7cUJBQ0Y7aUJBQ0Y7YUFDRixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLHNCQUFzQixFQUFFLEdBQUcsRUFBRTtRQUNwQyxNQUFNLFlBQVksR0FBaUI7WUFDakMsVUFBVSxFQUFFLGFBQWE7WUFDekIsYUFBYSxFQUFFLEtBQUs7WUFDcEIsY0FBYyxFQUNaLHFGQUFxRjtTQUN4RixDQUFDO1FBRUYsSUFBSSxDQUFDLHVEQUF1RCxFQUFFLEdBQUcsRUFBRTtZQUNqRSxNQUFNLEtBQUssR0FBaUI7Z0JBQzFCLFVBQVUsRUFBRSxxQkFBcUI7Z0JBQ2pDLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixTQUFTLEVBQUUsWUFBWTtnQkFDdkIsWUFBWTthQUNiLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQywrQkFBK0IsRUFBRTtnQkFDOUQsa0JBQWtCLEVBQUU7b0JBQ2xCLE9BQU8sRUFBRSxDQUFDLGlCQUFpQixDQUFDO29CQUM1QixpQkFBaUIsRUFBRTt3QkFDakIsaUJBQWlCLEVBQUUsWUFBWSxDQUFDLGNBQWM7d0JBQzlDLGdCQUFnQixFQUFFLFVBQVU7cUJBQzdCO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMseURBQXlELEVBQUUsR0FBRyxFQUFFO1lBQ25FLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixZQUFZO2FBQ2IsQ0FBQztZQUVGLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFekMsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFM0MsUUFBUSxDQUFDLHFCQUFxQixDQUFDLHlCQUF5QixFQUFFO2dCQUN4RCxJQUFJLEVBQUUsR0FBRztnQkFDVCxJQUFJLEVBQUUsa0JBQWtCO2dCQUN4QixXQUFXLEVBQUU7b0JBQ1gsT0FBTyxFQUFFLGtCQUFLLENBQUMsUUFBUSxFQUFFO29CQUN6QixZQUFZLEVBQUUsa0JBQUssQ0FBQyxRQUFRLEVBQUU7aUJBQy9CO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsa0NBQWtDLEVBQUUsR0FBRyxFQUFFO1lBQzVDLE1BQU0sc0JBQXNCLEdBQWlCO2dCQUMzQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLEVBQUU7Z0JBQ2pCLGNBQWMsRUFDWixxRkFBcUY7YUFDeEYsQ0FBQztZQUVGLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixZQUFZLEVBQUUsc0JBQXNCO2FBQ3JDLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQywrQkFBK0IsRUFBRTtnQkFDOUQsa0JBQWtCLEVBQUU7b0JBQ2xCLE9BQU8sRUFBRSxDQUFDLGFBQWEsQ0FBQztpQkFDekI7YUFDRixDQUFDLENBQUM7WUFFSCxRQUFRLENBQUMscUJBQXFCLENBQUMseUJBQXlCLEVBQUU7Z0JBQ3hELElBQUksRUFBRSxHQUFHO2dCQUNULElBQUksRUFBRSxjQUFjO2FBQ3JCLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGtHQUFrRyxFQUFFLEdBQUcsRUFBRTtZQUM1RyxNQUFNLGdCQUFnQixHQUFpQjtnQkFDckMsVUFBVSxFQUFFLGFBQWE7Z0JBQ3pCLGFBQWEsRUFBRSxLQUFLO2dCQUNwQixjQUFjLEVBQ1oscUZBQXFGO2dCQUN2RixpQkFBaUIsRUFBRSxJQUFJO2FBQ3hCLENBQUM7WUFFRixNQUFNLEtBQUssR0FBaUI7Z0JBQzFCLFVBQVUsRUFBRSxxQkFBcUI7Z0JBQ2pDLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixTQUFTLEVBQUUsWUFBWTtnQkFDdkIsWUFBWSxFQUFFLGdCQUFnQjthQUMvQixDQUFDO1lBRUYsSUFBSSxhQUFPLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUV6QyxNQUFNLFFBQVEsR0FBRyxxQkFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUUzQyxRQUFRLENBQUMscUJBQXFCLENBQUMsK0JBQStCLEVBQUU7Z0JBQzlELGtCQUFrQixFQUFFO29CQUNsQixPQUFPLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxhQUFhLENBQUM7aUJBQzVDO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsOERBQThELEVBQUUsR0FBRyxFQUFFO1lBQ3hFLE1BQU0sZ0JBQWdCLEdBQWlCO2dCQUNyQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLEtBQUs7Z0JBQ3BCLGNBQWMsRUFDWixxRkFBcUY7Z0JBQ3ZGLGlCQUFpQixFQUFFLElBQUk7YUFDeEIsQ0FBQztZQUVGLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixZQUFZLEVBQUUsZ0JBQWdCO2FBQy9CLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxlQUFlLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFdkQsUUFBUSxDQUFDLHFCQUFxQixDQUFDLHlCQUF5QixFQUFFO2dCQUN4RCxJQUFJLEVBQUUsa0JBQWtCO2dCQUN4QixJQUFJLEVBQUUsR0FBRzthQUNWLENBQUMsQ0FBQztZQUVILFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyx5QkFBeUIsRUFBRTtnQkFDeEQsSUFBSSxFQUFFLGNBQWM7Z0JBQ3BCLElBQUksRUFBRSxHQUFHO2FBQ1YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMscUVBQXFFLEVBQUUsR0FBRyxFQUFFO1lBQy9FLE1BQU0sc0JBQXNCLEdBQWlCO2dCQUMzQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLEVBQUU7Z0JBQ2pCLGNBQWMsRUFDWixxRkFBcUY7Z0JBQ3ZGLGlCQUFpQixFQUFFLElBQUk7YUFDeEIsQ0FBQztZQUVGLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLHFCQUFxQjtnQkFDakMsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixZQUFZLEVBQUUsc0JBQXNCO2FBQ3JDLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxlQUFlLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFdkQsUUFBUSxDQUFDLHFCQUFxQixDQUFDLCtCQUErQixFQUFFO2dCQUM5RCxrQkFBa0IsRUFBRTtvQkFDbEIsT0FBTyxFQUFFLENBQUMsYUFBYSxDQUFDO2lCQUN6QjthQUNGLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxFQUFFO1FBQy9CLElBQUksQ0FBQywwREFBMEQsRUFBRSxHQUFHLEVBQUU7WUFDcEUsTUFBTSxLQUFLLEdBQWlCO2dCQUMxQixVQUFVLEVBQUUsYUFBYTtnQkFDekIsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixNQUFNLFNBQVMsR0FBRyxJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRTNELDZEQUE2RDtZQUM3RCxNQUFNLGlCQUFpQixHQUFJLFNBQWlCLENBQUMsa0JBQWtCLENBQUM7WUFFaEUsTUFBTSxZQUFZLEdBQWlCO2dCQUNqQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLE1BQU07Z0JBQ3JCLGNBQWMsRUFBRSxVQUFVO2FBQzNCLENBQUM7WUFFRixNQUFNLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsZ0VBQWdFLEVBQUUsR0FBRyxFQUFFO1lBQzFFLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLGFBQWE7Z0JBQ3pCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixTQUFTLEVBQUUsWUFBWTthQUN4QixDQUFDO1lBRUYsTUFBTSxTQUFTLEdBQUcsSUFBSSxhQUFPLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUUzRCxNQUFNLGlCQUFpQixHQUFJLFNBQWlCLENBQUMsa0JBQWtCLENBQUM7WUFFaEUsTUFBTSxZQUFZLEdBQWlCO2dCQUNqQyxVQUFVLEVBQUUsYUFBYTtnQkFDekIsYUFBYSxFQUFFLEVBQUU7Z0JBQ2pCLGNBQWMsRUFBRSxVQUFVO2FBQzNCLENBQUM7WUFFRixNQUFNLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3JDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRTtRQUMxQixJQUFJLENBQUMsK0JBQStCLEVBQUUsR0FBRyxFQUFFO1lBQ3pDLE1BQU0sS0FBSyxHQUFpQjtnQkFDMUIsVUFBVSxFQUFFLGdCQUFnQjtnQkFDNUIsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixNQUFNLENBQUMsR0FBRyxFQUFFO2dCQUNWLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDM0MsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBRWpCLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzNDLFFBQVEsQ0FBQyxlQUFlLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDL0MsUUFBUSxDQUFDLGVBQWUsQ0FBQywrQkFBK0IsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM3RCxRQUFRLENBQUMsZUFBZSxDQUN0QixpREFBaUQsRUFDakQsQ0FBQyxDQUNGLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxzRUFBc0UsRUFBRSxHQUFHLEVBQUU7WUFDaEYsTUFBTSxLQUFLLEdBQWlCO2dCQUMxQixVQUFVLEVBQUUsYUFBYTtnQkFDekIsU0FBUyxFQUFFLFlBQVk7Z0JBQ3ZCLFNBQVMsRUFBRSxZQUFZO2FBQ3hCLENBQUM7WUFFRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzNDLFFBQVEsQ0FBQyxlQUFlLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDekQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUgsUUFBUSxDQUFDLDJCQUEyQixFQUFFLEdBQUcsRUFBRTtJQUN6QyxJQUFJLEdBQVksQ0FBQztJQUNqQixJQUFJLEtBQWdCLENBQUM7SUFFckIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNwQixLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxrQkFBa0IsRUFBRTtZQUM3QyxHQUFHLEVBQUUsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUU7U0FDdEQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsc0VBQXNFLEVBQUUsR0FBRyxFQUFFO1FBQ2hGLE1BQU0sT0FBTyxHQUFHLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSx1QkFBdUIsRUFBRTtZQUMxRCxVQUFVLEVBQUUsZ0JBQWdCO1lBQzVCLFNBQVMsRUFBRSxZQUFZO1lBQ3ZCLFNBQVMsRUFBRSxZQUFZO1lBQ3ZCLGFBQWEsRUFBRTtnQkFDYixZQUFZLEVBQUUsZ0JBQWdCO2FBQy9CO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0MsUUFBUSxDQUFDLGVBQWUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMvQyxNQUFNLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDbkQsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsZ0VBQWdFLEVBQUUsR0FBRyxFQUFFO1FBQzFFLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSx1QkFBdUIsRUFBRTtZQUMxQyxVQUFVLEVBQUUsZ0JBQWdCO1lBQzVCLFNBQVMsRUFBRSxZQUFZO1lBQ3ZCLFNBQVMsRUFBRSxZQUFZO1lBQ3ZCLGFBQWEsRUFBRTtnQkFDYixZQUFZLEVBQUUsZ0JBQWdCO2dCQUM5QixXQUFXLEVBQUUsQ0FBQzthQUNmO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0MsUUFBUSxDQUFDLGVBQWUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNqRCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQywwREFBMEQsRUFBRSxHQUFHLEVBQUU7UUFDcEUsSUFBSSxhQUFPLENBQUMsS0FBSyxFQUFFLHVCQUF1QixFQUFFO1lBQzFDLFVBQVUsRUFBRSxnQkFBZ0I7WUFDNUIsU0FBUyxFQUFFLFVBQVU7WUFDckIsU0FBUyxFQUFFLGVBQWU7WUFDMUIsYUFBYSxFQUFFO2dCQUNiLFlBQVksRUFBRSxnQkFBZ0I7YUFDL0I7U0FDRixDQUFDLENBQUM7UUFFSCxNQUFNLFFBQVEsR0FBRyxxQkFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQyxRQUFRLENBQUMscUJBQXFCLENBQUMsaUJBQWlCLEVBQUU7WUFDaEQsVUFBVSxFQUFFLGtCQUFrQjtZQUM5QixvQkFBb0IsRUFBRTtnQkFDcEIsYUFBYSxFQUFFLFVBQVU7Z0JBQ3pCLGFBQWEsRUFBRSxlQUFlO2FBQy9CO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsUUFBUSxDQUFDLHFCQUFxQixDQUFDLGlCQUFpQixFQUFFO1lBQ2hELFVBQVUsRUFBRSxrQkFBa0I7WUFDOUIsb0JBQW9CLEVBQUU7Z0JBQ3BCLGFBQWEsRUFBRSxVQUFVO2dCQUN6QixhQUFhLEVBQUUsZUFBZTthQUMvQjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLHVFQUF1RSxFQUFFLEdBQUcsRUFBRTtRQUNqRixJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsdUJBQXVCLEVBQUU7WUFDMUMsVUFBVSxFQUFFLGdCQUFnQjtZQUM1QixTQUFTLEVBQUUsWUFBWTtZQUN2QixTQUFTLEVBQUUsWUFBWTtZQUN2QixhQUFhLEVBQUU7Z0JBQ2IsWUFBWSxFQUFFLGdCQUFnQjthQUMvQjtTQUNGLENBQUMsQ0FBQztRQUVILE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxzQkFBc0IsRUFBRTtZQUNyRCxTQUFTLEVBQUU7Z0JBQ1Q7b0JBQ0UsYUFBYSxFQUFFLFFBQVE7b0JBQ3ZCLE9BQU8sRUFBRSxNQUFNO2lCQUNoQjthQUNGO1lBQ0Qsc0JBQXNCLEVBQUU7Z0JBQ3RCO29CQUNFLFNBQVMsRUFBRSxnQkFBZ0I7b0JBQzNCLFNBQVMsRUFBRTt3QkFDVDs0QkFDRSxhQUFhLEVBQUUsV0FBVzs0QkFDMUIsT0FBTyxFQUFFLE1BQU07eUJBQ2hCO3FCQUNGO29CQUNELFVBQVUsRUFBRTt3QkFDVixjQUFjLEVBQUUsS0FBSztxQkFDdEI7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLGtEQUFrRCxFQUFFLEdBQUcsRUFBRTtRQUM1RCxJQUFJLGFBQU8sQ0FBQyxLQUFLLEVBQUUsdUJBQXVCLEVBQUU7WUFDMUMsVUFBVSxFQUFFLGdCQUFnQjtZQUM1QixTQUFTLEVBQUUsWUFBWTtZQUN2QixTQUFTLEVBQUUsWUFBWTtZQUN2QixhQUFhLEVBQUU7Z0JBQ2IsWUFBWSxFQUFFLGdCQUFnQjthQUMvQjtTQUNGLENBQUMsQ0FBQztRQUVILE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQywyQkFBMkIsRUFBRTtZQUMxRCxRQUFRLEVBQUUsT0FBTztTQUNsQixDQUFDLENBQUM7UUFDSCxRQUFRLENBQUMscUJBQXFCLENBQUMsMkJBQTJCLEVBQUU7WUFDMUQsUUFBUSxFQUFFLFdBQVc7U0FDdEIsQ0FBQyxDQUFDO1FBQ0gsUUFBUSxDQUFDLHFCQUFxQixDQUFDLDJCQUEyQixFQUFFO1lBQzFELFFBQVEsRUFBRSxTQUFTO1NBQ3BCLENBQUMsQ0FBQztRQUNILFFBQVEsQ0FBQyxlQUFlLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDekQsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsaUVBQWlFLEVBQUUsR0FBRyxFQUFFO1FBQzNFLE1BQU0sT0FBTyxHQUFHLElBQUksYUFBTyxDQUFDLEtBQUssRUFBRSx1QkFBdUIsRUFBRTtZQUMxRCxVQUFVLEVBQUUsZ0JBQWdCO1lBQzVCLFNBQVMsRUFBRSxZQUFZO1lBQ3ZCLFNBQVMsRUFBRSxZQUFZO1NBQ3hCLENBQUMsQ0FBQztRQUVILE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLFFBQVEsQ0FBQyxlQUFlLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDcEQsUUFBUSxDQUFDLGVBQWUsQ0FBQywwQkFBMEIsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN4RCxNQUFNLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDckQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRlbXBsYXRlLCBNYXRjaCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hc3NlcnRpb25zXCI7XG5pbXBvcnQgKiBhcyBjZGsgZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBXZWJzaXRlLCBXZWJzaXRlUHJvcHMsIERvbWFpbkNvbmZpZyB9IGZyb20gXCIuLi9saWJcIjtcblxuZGVzY3JpYmUoXCJXZWJzaXRlXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrLkFwcDtcbiAgbGV0IHN0YWNrOiBjZGsuU3RhY2s7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgYXBwID0gbmV3IGNkay5BcHAoKTtcbiAgICBzdGFjayA9IG5ldyBjZGsuU3RhY2soYXBwLCBcIlRlc3RTdGFja1wiLCB7XG4gICAgICBlbnY6IHsgYWNjb3VudDogXCIxMjM0NTY3ODkwMTJcIiwgcmVnaW9uOiBcInVzLWVhc3QtMVwiIH0sXG4gICAgfSk7XG4gICAgc3RhY2subm9kZS5zZXRDb250ZXh0KFxuICAgICAgXCJob3N0ZWQtem9uZTphY2NvdW50PTEyMzQ1Njc4OTAxMjpkb21haW5OYW1lPWV4YW1wbGUuY29tOnJlZ2lvbj11cy1lYXN0LTFcIixcbiAgICAgIHtcbiAgICAgICAgSWQ6IFwiL2hvc3RlZHpvbmUvWjEyMzQ1Njc4OTAxMlwiLFxuICAgICAgICBOYW1lOiBcImV4YW1wbGUuY29tLlwiLFxuICAgICAgfSxcbiAgICApO1xuICB9KTtcblxuICBkZXNjcmliZShcIkJhc2ljIGZ1bmN0aW9uYWxpdHlcIiwgKCkgPT4ge1xuICAgIHRlc3QoXCJjcmVhdGVzIFMzIGJ1Y2tldCB3aXRoIGJhc2ljIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpTMzo6QnVja2V0XCIsIHtcbiAgICAgICAgV2Vic2l0ZUNvbmZpZ3VyYXRpb246IHtcbiAgICAgICAgICBJbmRleERvY3VtZW50OiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgICBFcnJvckRvY3VtZW50OiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgfSxcbiAgICAgICAgQnVja2V0RW5jcnlwdGlvbjoge1xuICAgICAgICAgIFNlcnZlclNpZGVFbmNyeXB0aW9uQ29uZmlndXJhdGlvbjogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBTZXJ2ZXJTaWRlRW5jcnlwdGlvbkJ5RGVmYXVsdDoge1xuICAgICAgICAgICAgICAgIFNTRUFsZ29yaXRobTogXCJBRVMyNTZcIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImNyZWF0ZXMgQ2xvdWRGcm9udCBPcmlnaW4gQWNjZXNzIElkZW50aXR5XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC13ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcbiAgICAgICAgXCJBV1M6OkNsb3VkRnJvbnQ6OkNsb3VkRnJvbnRPcmlnaW5BY2Nlc3NJZGVudGl0eVwiLFxuICAgICAgICB7XG4gICAgICAgICAgQ2xvdWRGcm9udE9yaWdpbkFjY2Vzc0lkZW50aXR5Q29uZmlnOiB7XG4gICAgICAgICAgICBDb21tZW50OiBNYXRjaC5hbnlWYWx1ZSgpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImNyZWF0ZXMgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24gd2l0aCBjb3JyZWN0IGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIiwge1xuICAgICAgICBEaXN0cmlidXRpb25Db25maWc6IHtcbiAgICAgICAgICBEZWZhdWx0Q2FjaGVCZWhhdmlvcjoge1xuICAgICAgICAgICAgVmlld2VyUHJvdG9jb2xQb2xpY3k6IFwicmVkaXJlY3QtdG8taHR0cHNcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIEN1c3RvbUVycm9yUmVzcG9uc2VzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIEVycm9yQ29kZTogNDA0LFxuICAgICAgICAgICAgICBSZXNwb25zZUNvZGU6IDQwNCxcbiAgICAgICAgICAgICAgUmVzcG9uc2VQYWdlUGF0aDogXCIvNDA0Lmh0bWxcIixcbiAgICAgICAgICAgICAgRXJyb3JDYWNoaW5nTWluVFRMOiAxODAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIFByaWNlQ2xhc3M6IFwiUHJpY2VDbGFzc18xMDBcIixcbiAgICAgICAgICBFbmFibGVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiZXhwb3NlcyBDbG91ZEZyb250IGRpc3RyaWJ1dGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHdlYnNpdGUgPSBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdCh3ZWJzaXRlLmRpc3RyaWJ1dGlvbikudG9CZURlZmluZWQoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDdXN0b20gZXJyb3IgcGFnZSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICB0ZXN0KFwidXNlcyBjdXN0b20gbm90IGZvdW5kIHJlc3BvbnNlIHBhZ2UgcGF0aFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgbm90Rm91bmRSZXNwb25zZVBhZ2VQYXRoOiBcIi9jdXN0b20tNDA0Lmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIEN1c3RvbUVycm9yUmVzcG9uc2VzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIEVycm9yQ29kZTogNDA0LFxuICAgICAgICAgICAgICBSZXNwb25zZUNvZGU6IDQwNCxcbiAgICAgICAgICAgICAgUmVzcG9uc2VQYWdlUGF0aDogXCIvY3VzdG9tLTQwNC5odG1sXCIsXG4gICAgICAgICAgICAgIEVycm9yQ2FjaGluZ01pblRUTDogMTgwMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdChcInVzZXMgZGVmYXVsdCA0MDQuaHRtbCB3aGVuIG5vdEZvdW5kUmVzcG9uc2VQYWdlUGF0aCBpcyBub3QgcHJvdmlkZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIiwge1xuICAgICAgICBEaXN0cmlidXRpb25Db25maWc6IHtcbiAgICAgICAgICBDdXN0b21FcnJvclJlc3BvbnNlczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBFcnJvckNvZGU6IDQwNCxcbiAgICAgICAgICAgICAgUmVzcG9uc2VDb2RlOiA0MDQsXG4gICAgICAgICAgICAgIFJlc3BvbnNlUGFnZVBhdGg6IFwiLzQwNC5odG1sXCIsXG4gICAgICAgICAgICAgIEVycm9yQ2FjaGluZ01pblRUTDogMTgwMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkRvbWFpbiBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICBjb25zdCBkb21haW5Db25maWc6IERvbWFpbkNvbmZpZyA9IHtcbiAgICAgIGRvbWFpbk5hbWU6IFwiZXhhbXBsZS5jb21cIixcbiAgICAgIHN1YmRvbWFpbk5hbWU6IFwid3d3XCIsXG4gICAgICBjZXJ0aWZpY2F0ZUFybjpcbiAgICAgICAgXCJhcm46YXdzOmFjbTp1cy1lYXN0LTE6MTIzNDU2Nzg5MDEyOmNlcnRpZmljYXRlLzEyMzQ1Njc4LTEyMzQtMTIzNC0xMjM0LTEyMzQ1Njc4OTAxMlwiLFxuICAgIH07XG5cbiAgICB0ZXN0KFwiY29uZmlndXJlcyBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiB3aXRoIGN1c3RvbSBkb21haW5cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICAgIGRvbWFpbkNvbmZpZyxcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIEFsaWFzZXM6IFtcInd3dy5leGFtcGxlLmNvbVwiXSxcbiAgICAgICAgICBWaWV3ZXJDZXJ0aWZpY2F0ZToge1xuICAgICAgICAgICAgQWNtQ2VydGlmaWNhdGVBcm46IGRvbWFpbkNvbmZpZy5jZXJ0aWZpY2F0ZUFybixcbiAgICAgICAgICAgIFNzbFN1cHBvcnRNZXRob2Q6IFwic25pLW9ubHlcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiY3JlYXRlcyBSb3V0ZTUzIEEgcmVjb3JkIHdoZW4gZG9tYWluIGNvbmZpZyBpcyBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgZG9tYWluQ29uZmlnLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0XCIsIHtcbiAgICAgICAgVHlwZTogXCJBXCIsXG4gICAgICAgIE5hbWU6IFwid3d3LmV4YW1wbGUuY29tLlwiLFxuICAgICAgICBBbGlhc1RhcmdldDoge1xuICAgICAgICAgIEROU05hbWU6IE1hdGNoLmFueVZhbHVlKCksXG4gICAgICAgICAgSG9zdGVkWm9uZUlkOiBNYXRjaC5hbnlWYWx1ZSgpLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiaGFuZGxlcyBkb21haW4gd2l0aG91dCBzdWJkb21haW5cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZG9tYWluQ29uZmlnV2l0aG91dFN1YjogRG9tYWluQ29uZmlnID0ge1xuICAgICAgICBkb21haW5OYW1lOiBcImV4YW1wbGUuY29tXCIsXG4gICAgICAgIHN1YmRvbWFpbk5hbWU6IFwiXCIsXG4gICAgICAgIGNlcnRpZmljYXRlQXJuOlxuICAgICAgICAgIFwiYXJuOmF3czphY206dXMtZWFzdC0xOjEyMzQ1Njc4OTAxMjpjZXJ0aWZpY2F0ZS8xMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTJcIixcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC13ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgICBkb21haW5Db25maWc6IGRvbWFpbkNvbmZpZ1dpdGhvdXRTdWIsXG4gICAgICB9O1xuXG4gICAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJUZXN0V2Vic2l0ZVwiLCBwcm9wcyk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIiwge1xuICAgICAgICBEaXN0cmlidXRpb25Db25maWc6IHtcbiAgICAgICAgICBBbGlhc2VzOiBbXCJleGFtcGxlLmNvbVwiXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OlJvdXRlNTM6OlJlY29yZFNldFwiLCB7XG4gICAgICAgIFR5cGU6IFwiQVwiLFxuICAgICAgICBOYW1lOiBcImV4YW1wbGUuY29tLlwiLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiY29uZmlndXJlcyBDbG91ZEZyb250IHdpdGggYm90aCBzdWJkb21haW4gYW5kIHJvb3QgZG9tYWluIGFsaWFzZXMgd2hlbiBpbmNsdWRlUm9vdERvbWFpbiBpcyB0cnVlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGR1YWxEb21haW5Db25maWc6IERvbWFpbkNvbmZpZyA9IHtcbiAgICAgICAgZG9tYWluTmFtZTogXCJleGFtcGxlLmNvbVwiLFxuICAgICAgICBzdWJkb21haW5OYW1lOiBcInd3d1wiLFxuICAgICAgICBjZXJ0aWZpY2F0ZUFybjpcbiAgICAgICAgICBcImFybjphd3M6YWNtOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6Y2VydGlmaWNhdGUvMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyXCIsXG4gICAgICAgIGluY2x1ZGVSb290RG9tYWluOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICAgIGRvbWFpbkNvbmZpZzogZHVhbERvbWFpbkNvbmZpZyxcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIEFsaWFzZXM6IFtcInd3dy5leGFtcGxlLmNvbVwiLCBcImV4YW1wbGUuY29tXCJdLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiY3JlYXRlcyB0d28gUm91dGU1MyBBIHJlY29yZHMgd2hlbiBpbmNsdWRlUm9vdERvbWFpbiBpcyB0cnVlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGR1YWxEb21haW5Db25maWc6IERvbWFpbkNvbmZpZyA9IHtcbiAgICAgICAgZG9tYWluTmFtZTogXCJleGFtcGxlLmNvbVwiLFxuICAgICAgICBzdWJkb21haW5OYW1lOiBcInd3d1wiLFxuICAgICAgICBjZXJ0aWZpY2F0ZUFybjpcbiAgICAgICAgICBcImFybjphd3M6YWNtOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6Y2VydGlmaWNhdGUvMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5MDEyXCIsXG4gICAgICAgIGluY2x1ZGVSb290RG9tYWluOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LXdlYnNpdGUtYnVja2V0XCIsXG4gICAgICAgIGluZGV4RmlsZTogXCJpbmRleC5odG1sXCIsXG4gICAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICAgIGRvbWFpbkNvbmZpZzogZHVhbERvbWFpbkNvbmZpZyxcbiAgICAgIH07XG5cbiAgICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuXG4gICAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OlJvdXRlNTM6OlJlY29yZFNldFwiLCAyKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRcIiwge1xuICAgICAgICBOYW1lOiBcInd3dy5leGFtcGxlLmNvbS5cIixcbiAgICAgICAgVHlwZTogXCJBXCIsXG4gICAgICB9KTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRcIiwge1xuICAgICAgICBOYW1lOiBcImV4YW1wbGUuY29tLlwiLFxuICAgICAgICBUeXBlOiBcIkFcIixcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImlnbm9yZXMgaW5jbHVkZVJvb3REb21haW4gaWYgc3ViZG9tYWluIGlzIGVtcHR5IHRvIGF2b2lkIGR1cGxpY2F0ZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZG9tYWluQ29uZmlnV2l0aG91dFN1YjogRG9tYWluQ29uZmlnID0ge1xuICAgICAgICBkb21haW5OYW1lOiBcImV4YW1wbGUuY29tXCIsXG4gICAgICAgIHN1YmRvbWFpbk5hbWU6IFwiXCIsXG4gICAgICAgIGNlcnRpZmljYXRlQXJuOlxuICAgICAgICAgIFwiYXJuOmF3czphY206dXMtZWFzdC0xOjEyMzQ1Njc4OTAxMjpjZXJ0aWZpY2F0ZS8xMjM0NTY3OC0xMjM0LTEyMzQtMTIzNC0xMjM0NTY3ODkwMTJcIixcbiAgICAgICAgaW5jbHVkZVJvb3REb21haW46IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwcm9wczogV2Vic2l0ZVByb3BzID0ge1xuICAgICAgICBidWNrZXROYW1lOiBcInRlc3Qtd2Vic2l0ZS1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgICAgZG9tYWluQ29uZmlnOiBkb21haW5Db25maWdXaXRob3V0U3ViLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLnJlc291cmNlQ291bnRJcyhcIkFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0XCIsIDEpO1xuXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICAgIERpc3RyaWJ1dGlvbkNvbmZpZzoge1xuICAgICAgICAgIEFsaWFzZXM6IFtcImV4YW1wbGUuY29tXCJdLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUHJpdmF0ZSBtZXRob2RzXCIsICgpID0+IHtcbiAgICB0ZXN0KFwiX2dldEZ1bGxEb21haW5OYW1lIHJldHVybnMgY29ycmVjdCBkb21haW4gd2l0aCBzdWJkb21haW5cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgY29uc3RydWN0ID0gbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICAvLyBBY2Nlc3MgcHJpdmF0ZSBtZXRob2QgdGhyb3VnaCBicmFja2V0IG5vdGF0aW9uIGZvciB0ZXN0aW5nXG4gICAgICBjb25zdCBnZXRGdWxsRG9tYWluTmFtZSA9IChjb25zdHJ1Y3QgYXMgYW55KS5fZ2V0RnVsbERvbWFpbk5hbWU7XG5cbiAgICAgIGNvbnN0IGRvbWFpbkNvbmZpZzogRG9tYWluQ29uZmlnID0ge1xuICAgICAgICBkb21haW5OYW1lOiBcImV4YW1wbGUuY29tXCIsXG4gICAgICAgIHN1YmRvbWFpbk5hbWU6IFwiYmxvZ1wiLFxuICAgICAgICBjZXJ0aWZpY2F0ZUFybjogXCJhcm46dGVzdFwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gZ2V0RnVsbERvbWFpbk5hbWUoZG9tYWluQ29uZmlnKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoXCJibG9nLmV4YW1wbGUuY29tXCIpO1xuICAgIH0pO1xuXG4gICAgdGVzdChcIl9nZXRGdWxsRG9tYWluTmFtZSByZXR1cm5zIHJvb3QgZG9tYWluIHdoZW4gc3ViZG9tYWluIGlzIGVtcHR5XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBXZWJzaXRlUHJvcHMgPSB7XG4gICAgICAgIGJ1Y2tldE5hbWU6IFwidGVzdC1idWNrZXRcIixcbiAgICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGNvbnN0cnVjdCA9IG5ldyBXZWJzaXRlKHN0YWNrLCBcIlRlc3RXZWJzaXRlXCIsIHByb3BzKTtcblxuICAgICAgY29uc3QgZ2V0RnVsbERvbWFpbk5hbWUgPSAoY29uc3RydWN0IGFzIGFueSkuX2dldEZ1bGxEb21haW5OYW1lO1xuXG4gICAgICBjb25zdCBkb21haW5Db25maWc6IERvbWFpbkNvbmZpZyA9IHtcbiAgICAgICAgZG9tYWluTmFtZTogXCJleGFtcGxlLmNvbVwiLFxuICAgICAgICBzdWJkb21haW5OYW1lOiBcIlwiLFxuICAgICAgICBjZXJ0aWZpY2F0ZUFybjogXCJhcm46dGVzdFwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gZ2V0RnVsbERvbWFpbk5hbWUoZG9tYWluQ29uZmlnKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoXCJleGFtcGxlLmNvbVwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJFZGdlIGNhc2VzXCIsICgpID0+IHtcbiAgICB0ZXN0KFwiaGFuZGxlcyBtaW5pbWFsIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJtaW5pbWFsLWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuICAgICAgfSkubm90LnRvVGhyb3coKTtcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgICAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKFwiQVdTOjpTMzo6QnVja2V0XCIsIDEpO1xuICAgICAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIiwgMSk7XG4gICAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXG4gICAgICAgIFwiQVdTOjpDbG91ZEZyb250OjpDbG91ZEZyb250T3JpZ2luQWNjZXNzSWRlbnRpdHlcIixcbiAgICAgICAgMSxcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KFwiZG9lcyBub3QgY3JlYXRlIFJvdXRlNTMgcmVzb3VyY2VzIHdoZW4gZG9tYWluIGNvbmZpZyBpcyBub3QgcHJvdmlkZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFdlYnNpdGVQcm9wcyA9IHtcbiAgICAgICAgYnVja2V0TmFtZTogXCJ0ZXN0LWJ1Y2tldFwiLFxuICAgICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgICBlcnJvckZpbGU6IFwiZXJyb3IuaHRtbFwiLFxuICAgICAgfTtcblxuICAgICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiVGVzdFdlYnNpdGVcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG4gICAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OlJvdXRlNTM6OlJlY29yZFNldFwiLCAwKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoXCJQcmV2aWV3IGNvbmZpZyBvbiBXZWJzaXRlXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrLkFwcDtcbiAgbGV0IHN0YWNrOiBjZGsuU3RhY2s7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgYXBwID0gbmV3IGNkay5BcHAoKTtcbiAgICBzdGFjayA9IG5ldyBjZGsuU3RhY2soYXBwLCBcIlByZXZpZXdUZXN0U3RhY2tcIiwge1xuICAgICAgZW52OiB7IGFjY291bnQ6IFwiMTIzNDU2Nzg5MDEyXCIsIHJlZ2lvbjogXCJ1cy1lYXN0LTFcIiB9LFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KFwiY3JlYXRlcyB0d28gcHJldmlldyBidWNrZXRzIGJ5IGRlZmF1bHQgd2hlbiBwcmV2aWV3Q29uZmlnIGlzIGVuYWJsZWRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHdlYnNpdGUgPSBuZXcgV2Vic2l0ZShzdGFjaywgXCJQcmV2aWV3RW5hYmxlZFdlYnNpdGVcIiwge1xuICAgICAgYnVja2V0TmFtZTogXCJ3ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICBwcmV2aWV3Q29uZmlnOiB7XG4gICAgICAgIGJ1Y2tldFByZWZpeDogXCJwcmV2aWV3LWJ1Y2tldFwiLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwgMyk7XG4gICAgZXhwZWN0KHdlYnNpdGUucHJldmlld0Vudmlyb25tZW50KS50b0JlRGVmaW5lZCgpO1xuICB9KTtcblxuICB0ZXN0KFwiY3JlYXRlcyByZXF1ZXN0ZWQgbnVtYmVyIG9mIHByZXZpZXcgYnVja2V0cyBmcm9tIHByZXZpZXdDb25maWdcIiwgKCkgPT4ge1xuICAgIG5ldyBXZWJzaXRlKHN0YWNrLCBcIlByZXZpZXdFbmFibGVkV2Vic2l0ZVwiLCB7XG4gICAgICBidWNrZXROYW1lOiBcIndlYnNpdGUtYnVja2V0XCIsXG4gICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICAgIHByZXZpZXdDb25maWc6IHtcbiAgICAgICAgYnVja2V0UHJlZml4OiBcInByZXZpZXctYnVja2V0XCIsXG4gICAgICAgIGJ1Y2tldENvdW50OiAzLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwgNCk7XG4gIH0pO1xuXG4gIHRlc3QoXCJyZXVzZXMgd2Vic2l0ZSBpbmRleCBhbmQgZXJyb3IgZmlsZXMgZm9yIHByZXZpZXcgYnVja2V0c1wiLCAoKSA9PiB7XG4gICAgbmV3IFdlYnNpdGUoc3RhY2ssIFwiUHJldmlld0VuYWJsZWRXZWJzaXRlXCIsIHtcbiAgICAgIGJ1Y2tldE5hbWU6IFwid2Vic2l0ZS1idWNrZXRcIixcbiAgICAgIGluZGV4RmlsZTogXCJhcHAuaHRtbFwiLFxuICAgICAgZXJyb3JGaWxlOiBcImZhbGxiYWNrLmh0bWxcIixcbiAgICAgIHByZXZpZXdDb25maWc6IHtcbiAgICAgICAgYnVja2V0UHJlZml4OiBcInByZXZpZXctYnVja2V0XCIsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6UzM6OkJ1Y2tldFwiLCB7XG4gICAgICBCdWNrZXROYW1lOiBcInByZXZpZXctYnVja2V0LTBcIixcbiAgICAgIFdlYnNpdGVDb25maWd1cmF0aW9uOiB7XG4gICAgICAgIEluZGV4RG9jdW1lbnQ6IFwiYXBwLmh0bWxcIixcbiAgICAgICAgRXJyb3JEb2N1bWVudDogXCJmYWxsYmFjay5odG1sXCIsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6UzM6OkJ1Y2tldFwiLCB7XG4gICAgICBCdWNrZXROYW1lOiBcInByZXZpZXctYnVja2V0LTFcIixcbiAgICAgIFdlYnNpdGVDb25maWd1cmF0aW9uOiB7XG4gICAgICAgIEluZGV4RG9jdW1lbnQ6IFwiYXBwLmh0bWxcIixcbiAgICAgICAgRXJyb3JEb2N1bWVudDogXCJmYWxsYmFjay5odG1sXCIsXG4gICAgICB9LFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KFwiY3JlYXRlcyBsZWFzZSB0YWJsZSB3aXRoIHJlcG8tcHIgbG9va3VwIGluZGV4IHdoZW4gcHJldmlldyBpcyBlbmFibGVkXCIsICgpID0+IHtcbiAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJQcmV2aWV3RW5hYmxlZFdlYnNpdGVcIiwge1xuICAgICAgYnVja2V0TmFtZTogXCJ3ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICBwcmV2aWV3Q29uZmlnOiB7XG4gICAgICAgIGJ1Y2tldFByZWZpeDogXCJwcmV2aWV3LWJ1Y2tldFwiLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkR5bmFtb0RCOjpUYWJsZVwiLCB7XG4gICAgICBLZXlTY2hlbWE6IFtcbiAgICAgICAge1xuICAgICAgICAgIEF0dHJpYnV0ZU5hbWU6IFwic2xvdElkXCIsXG4gICAgICAgICAgS2V5VHlwZTogXCJIQVNIXCIsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgR2xvYmFsU2Vjb25kYXJ5SW5kZXhlczogW1xuICAgICAgICB7XG4gICAgICAgICAgSW5kZXhOYW1lOiBcIlJlcG9QcktleUluZGV4XCIsXG4gICAgICAgICAgS2V5U2NoZW1hOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIEF0dHJpYnV0ZU5hbWU6IFwicmVwb1ByS2V5XCIsXG4gICAgICAgICAgICAgIEtleVR5cGU6IFwiSEFTSFwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIFByb2plY3Rpb246IHtcbiAgICAgICAgICAgIFByb2plY3Rpb25UeXBlOiBcIkFMTFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KFwiY3JlYXRlcyBsZWFzZSBBUEkgcm91dGVzIHdoZW4gcHJldmlldyBpcyBlbmFibGVkXCIsICgpID0+IHtcbiAgICBuZXcgV2Vic2l0ZShzdGFjaywgXCJQcmV2aWV3RW5hYmxlZFdlYnNpdGVcIiwge1xuICAgICAgYnVja2V0TmFtZTogXCJ3ZWJzaXRlLWJ1Y2tldFwiLFxuICAgICAgaW5kZXhGaWxlOiBcImluZGV4Lmh0bWxcIixcbiAgICAgIGVycm9yRmlsZTogXCJlcnJvci5odG1sXCIsXG4gICAgICBwcmV2aWV3Q29uZmlnOiB7XG4gICAgICAgIGJ1Y2tldFByZWZpeDogXCJwcmV2aWV3LWJ1Y2tldFwiLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkFwaUdhdGV3YXk6OlJlc291cmNlXCIsIHtcbiAgICAgIFBhdGhQYXJ0OiBcImNsYWltXCIsXG4gICAgfSk7XG4gICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpBcGlHYXRld2F5OjpSZXNvdXJjZVwiLCB7XG4gICAgICBQYXRoUGFydDogXCJoZWFydGJlYXRcIixcbiAgICB9KTtcbiAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OkFwaUdhdGV3YXk6OlJlc291cmNlXCIsIHtcbiAgICAgIFBhdGhQYXJ0OiBcInJlbGVhc2VcIixcbiAgICB9KTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OkFwaUdhdGV3YXk6Ok1ldGhvZFwiLCAzKTtcbiAgfSk7XG5cbiAgdGVzdChcImRvZXMgbm90IGNyZWF0ZSBwcmV2aWV3IHJlc291cmNlcyB3aGVuIHByZXZpZXdDb25maWcgaXMgb21pdHRlZFwiLCAoKSA9PiB7XG4gICAgY29uc3Qgd2Vic2l0ZSA9IG5ldyBXZWJzaXRlKHN0YWNrLCBcIldlYnNpdGVXaXRob3V0UHJldmlld1wiLCB7XG4gICAgICBidWNrZXROYW1lOiBcIndlYnNpdGUtYnVja2V0XCIsXG4gICAgICBpbmRleEZpbGU6IFwiaW5kZXguaHRtbFwiLFxuICAgICAgZXJyb3JGaWxlOiBcImVycm9yLmh0bWxcIixcbiAgICB9KTtcblxuICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OkR5bmFtb0RCOjpUYWJsZVwiLCAwKTtcbiAgICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoXCJBV1M6OkFwaUdhdGV3YXk6OlJlc3RBcGlcIiwgMCk7XG4gICAgZXhwZWN0KHdlYnNpdGUucHJldmlld0Vudmlyb25tZW50KS50b0JlVW5kZWZpbmVkKCk7XG4gIH0pO1xufSk7XG4iXX0=
@@ -249,6 +249,95 @@ describe("Website", () => {
249
249
  Name: "example.com.",
250
250
  });
251
251
  });
252
+
253
+ test("configures CloudFront with both subdomain and root domain aliases when includeRootDomain is true", () => {
254
+ const dualDomainConfig: DomainConfig = {
255
+ domainName: "example.com",
256
+ subdomainName: "www",
257
+ certificateArn:
258
+ "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012",
259
+ includeRootDomain: true,
260
+ };
261
+
262
+ const props: WebsiteProps = {
263
+ bucketName: "test-website-bucket",
264
+ indexFile: "index.html",
265
+ errorFile: "error.html",
266
+ domainConfig: dualDomainConfig,
267
+ };
268
+
269
+ new Website(stack, "TestWebsite", props);
270
+
271
+ const template = Template.fromStack(stack);
272
+
273
+ template.hasResourceProperties("AWS::CloudFront::Distribution", {
274
+ DistributionConfig: {
275
+ Aliases: ["www.example.com", "example.com"],
276
+ },
277
+ });
278
+ });
279
+
280
+ test("creates two Route53 A records when includeRootDomain is true", () => {
281
+ const dualDomainConfig: DomainConfig = {
282
+ domainName: "example.com",
283
+ subdomainName: "www",
284
+ certificateArn:
285
+ "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012",
286
+ includeRootDomain: true,
287
+ };
288
+
289
+ const props: WebsiteProps = {
290
+ bucketName: "test-website-bucket",
291
+ indexFile: "index.html",
292
+ errorFile: "error.html",
293
+ domainConfig: dualDomainConfig,
294
+ };
295
+
296
+ new Website(stack, "TestWebsite", props);
297
+
298
+ const template = Template.fromStack(stack);
299
+
300
+ template.resourceCountIs("AWS::Route53::RecordSet", 2);
301
+
302
+ template.hasResourceProperties("AWS::Route53::RecordSet", {
303
+ Name: "www.example.com.",
304
+ Type: "A",
305
+ });
306
+
307
+ template.hasResourceProperties("AWS::Route53::RecordSet", {
308
+ Name: "example.com.",
309
+ Type: "A",
310
+ });
311
+ });
312
+
313
+ test("ignores includeRootDomain if subdomain is empty to avoid duplicates", () => {
314
+ const domainConfigWithoutSub: DomainConfig = {
315
+ domainName: "example.com",
316
+ subdomainName: "",
317
+ certificateArn:
318
+ "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012",
319
+ includeRootDomain: true,
320
+ };
321
+
322
+ const props: WebsiteProps = {
323
+ bucketName: "test-website-bucket",
324
+ indexFile: "index.html",
325
+ errorFile: "error.html",
326
+ domainConfig: domainConfigWithoutSub,
327
+ };
328
+
329
+ new Website(stack, "TestWebsite", props);
330
+
331
+ const template = Template.fromStack(stack);
332
+
333
+ template.resourceCountIs("AWS::Route53::RecordSet", 1);
334
+
335
+ template.hasResourceProperties("AWS::CloudFront::Distribution", {
336
+ DistributionConfig: {
337
+ Aliases: ["example.com"],
338
+ },
339
+ });
340
+ });
252
341
  });
253
342
 
254
343
  describe("Private methods", () => {
@@ -331,3 +420,143 @@ describe("Website", () => {
331
420
  });
332
421
  });
333
422
  });
423
+
424
+ describe("Preview config on Website", () => {
425
+ let app: cdk.App;
426
+ let stack: cdk.Stack;
427
+
428
+ beforeEach(() => {
429
+ app = new cdk.App();
430
+ stack = new cdk.Stack(app, "PreviewTestStack", {
431
+ env: { account: "123456789012", region: "us-east-1" },
432
+ });
433
+ });
434
+
435
+ test("creates two preview buckets by default when previewConfig is enabled", () => {
436
+ const website = new Website(stack, "PreviewEnabledWebsite", {
437
+ bucketName: "website-bucket",
438
+ indexFile: "index.html",
439
+ errorFile: "error.html",
440
+ previewConfig: {
441
+ bucketPrefix: "preview-bucket",
442
+ },
443
+ });
444
+
445
+ const template = Template.fromStack(stack);
446
+ template.resourceCountIs("AWS::S3::Bucket", 3);
447
+ expect(website.previewEnvironment).toBeDefined();
448
+ });
449
+
450
+ test("creates requested number of preview buckets from previewConfig", () => {
451
+ new Website(stack, "PreviewEnabledWebsite", {
452
+ bucketName: "website-bucket",
453
+ indexFile: "index.html",
454
+ errorFile: "error.html",
455
+ previewConfig: {
456
+ bucketPrefix: "preview-bucket",
457
+ bucketCount: 3,
458
+ },
459
+ });
460
+
461
+ const template = Template.fromStack(stack);
462
+ template.resourceCountIs("AWS::S3::Bucket", 4);
463
+ });
464
+
465
+ test("reuses website index and error files for preview buckets", () => {
466
+ new Website(stack, "PreviewEnabledWebsite", {
467
+ bucketName: "website-bucket",
468
+ indexFile: "app.html",
469
+ errorFile: "fallback.html",
470
+ previewConfig: {
471
+ bucketPrefix: "preview-bucket",
472
+ },
473
+ });
474
+
475
+ const template = Template.fromStack(stack);
476
+ template.hasResourceProperties("AWS::S3::Bucket", {
477
+ BucketName: "preview-bucket-0",
478
+ WebsiteConfiguration: {
479
+ IndexDocument: "app.html",
480
+ ErrorDocument: "fallback.html",
481
+ },
482
+ });
483
+ template.hasResourceProperties("AWS::S3::Bucket", {
484
+ BucketName: "preview-bucket-1",
485
+ WebsiteConfiguration: {
486
+ IndexDocument: "app.html",
487
+ ErrorDocument: "fallback.html",
488
+ },
489
+ });
490
+ });
491
+
492
+ test("creates lease table with repo-pr lookup index when preview is enabled", () => {
493
+ new Website(stack, "PreviewEnabledWebsite", {
494
+ bucketName: "website-bucket",
495
+ indexFile: "index.html",
496
+ errorFile: "error.html",
497
+ previewConfig: {
498
+ bucketPrefix: "preview-bucket",
499
+ },
500
+ });
501
+
502
+ const template = Template.fromStack(stack);
503
+ template.hasResourceProperties("AWS::DynamoDB::Table", {
504
+ KeySchema: [
505
+ {
506
+ AttributeName: "slotId",
507
+ KeyType: "HASH",
508
+ },
509
+ ],
510
+ GlobalSecondaryIndexes: [
511
+ {
512
+ IndexName: "RepoPrKeyIndex",
513
+ KeySchema: [
514
+ {
515
+ AttributeName: "repoPrKey",
516
+ KeyType: "HASH",
517
+ },
518
+ ],
519
+ Projection: {
520
+ ProjectionType: "ALL",
521
+ },
522
+ },
523
+ ],
524
+ });
525
+ });
526
+
527
+ test("creates lease API routes when preview is enabled", () => {
528
+ new Website(stack, "PreviewEnabledWebsite", {
529
+ bucketName: "website-bucket",
530
+ indexFile: "index.html",
531
+ errorFile: "error.html",
532
+ previewConfig: {
533
+ bucketPrefix: "preview-bucket",
534
+ },
535
+ });
536
+
537
+ const template = Template.fromStack(stack);
538
+ template.hasResourceProperties("AWS::ApiGateway::Resource", {
539
+ PathPart: "claim",
540
+ });
541
+ template.hasResourceProperties("AWS::ApiGateway::Resource", {
542
+ PathPart: "heartbeat",
543
+ });
544
+ template.hasResourceProperties("AWS::ApiGateway::Resource", {
545
+ PathPart: "release",
546
+ });
547
+ template.resourceCountIs("AWS::ApiGateway::Method", 3);
548
+ });
549
+
550
+ test("does not create preview resources when previewConfig is omitted", () => {
551
+ const website = new Website(stack, "WebsiteWithoutPreview", {
552
+ bucketName: "website-bucket",
553
+ indexFile: "index.html",
554
+ errorFile: "error.html",
555
+ });
556
+
557
+ const template = Template.fromStack(stack);
558
+ template.resourceCountIs("AWS::DynamoDB::Table", 0);
559
+ template.resourceCountIs("AWS::ApiGateway::RestApi", 0);
560
+ expect(website.previewEnvironment).toBeUndefined();
561
+ });
562
+ });