@aws-solutions-constructs/core 2.0.0-rc.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/.jsii +444 -1163
  2. package/index.d.ts +5 -1
  3. package/index.js +6 -2
  4. package/lib/alb-defaults.d.ts +14 -0
  5. package/lib/alb-defaults.js +24 -0
  6. package/lib/alb-helper.d.ts +24 -0
  7. package/lib/alb-helper.js +188 -0
  8. package/lib/apigateway-defaults.d.ts +1 -1
  9. package/lib/apigateway-defaults.js +2 -2
  10. package/lib/apigateway-helper.d.ts +5 -5
  11. package/lib/apigateway-helper.js +24 -16
  12. package/lib/cloudfront-distribution-defaults.d.ts +2 -2
  13. package/lib/cloudfront-distribution-defaults.js +11 -4
  14. package/lib/cloudfront-distribution-helper.d.ts +3 -3
  15. package/lib/cloudfront-distribution-helper.js +7 -7
  16. package/lib/cloudwatch-log-group-defaults.d.ts +1 -1
  17. package/lib/cloudwatch-log-group-defaults.js +2 -2
  18. package/lib/cloudwatch-log-group-helper.d.ts +1 -1
  19. package/lib/cloudwatch-log-group-helper.js +2 -2
  20. package/lib/cognito-defaults.d.ts +1 -1
  21. package/lib/cognito-defaults.js +2 -2
  22. package/lib/cognito-helper.d.ts +1 -1
  23. package/lib/cognito-helper.js +2 -2
  24. package/lib/dynamodb-table-defaults.d.ts +1 -1
  25. package/lib/dynamodb-table-defaults.js +2 -2
  26. package/lib/dynamodb-table-helper.d.ts +1 -1
  27. package/lib/dynamodb-table-helper.js +2 -2
  28. package/lib/elasticsearch-defaults.d.ts +1 -1
  29. package/lib/elasticsearch-defaults.js +2 -2
  30. package/lib/elasticsearch-helper.d.ts +1 -1
  31. package/lib/elasticsearch-helper.js +2 -2
  32. package/lib/eventbridge-helper.d.ts +1 -1
  33. package/lib/eventbridge-helper.js +2 -2
  34. package/lib/events-rule-defaults.d.ts +1 -1
  35. package/lib/events-rule-defaults.js +2 -2
  36. package/lib/fargate-defaults.d.ts +26 -0
  37. package/lib/fargate-defaults.js +57 -0
  38. package/lib/fargate-helper.d.ts +17 -0
  39. package/lib/fargate-helper.js +158 -0
  40. package/lib/glue-database-defaults.d.ts +1 -1
  41. package/lib/glue-database-defaults.js +2 -2
  42. package/lib/glue-database-helper.d.ts +2 -2
  43. package/lib/glue-database-helper.js +2 -2
  44. package/lib/glue-job-defaults.d.ts +1 -1
  45. package/lib/glue-job-defaults.js +2 -2
  46. package/lib/glue-job-helper.d.ts +4 -4
  47. package/lib/glue-job-helper.js +3 -3
  48. package/lib/glue-table-defaults.d.ts +1 -1
  49. package/lib/glue-table-defaults.js +2 -2
  50. package/lib/glue-table-helper.d.ts +2 -2
  51. package/lib/glue-table-helper.js +2 -2
  52. package/lib/input-validation.d.ts +9 -1
  53. package/lib/input-validation.js +22 -3
  54. package/lib/iot-topic-rule-defaults.d.ts +1 -1
  55. package/lib/iot-topic-rule-defaults.js +2 -2
  56. package/lib/kinesis-analytics-defaults.d.ts +1 -1
  57. package/lib/kinesis-analytics-defaults.js +2 -2
  58. package/lib/kinesis-analytics-helper.d.ts +1 -1
  59. package/lib/kinesis-analytics-helper.js +2 -2
  60. package/lib/kinesis-firehose-s3-defaults.d.ts +1 -1
  61. package/lib/kinesis-firehose-s3-defaults.js +2 -2
  62. package/lib/kinesis-streams-defaults.d.ts +1 -1
  63. package/lib/kinesis-streams-defaults.js +2 -2
  64. package/lib/kinesis-streams-helper.d.ts +1 -1
  65. package/lib/kinesis-streams-helper.js +2 -2
  66. package/lib/kms-defaults.d.ts +1 -1
  67. package/lib/kms-defaults.js +2 -2
  68. package/lib/kms-helper.d.ts +1 -1
  69. package/lib/kms-helper.js +2 -2
  70. package/lib/lambda-defaults.d.ts +1 -1
  71. package/lib/lambda-defaults.js +2 -2
  72. package/lib/lambda-event-source-mapping-defaults.d.ts +2 -2
  73. package/lib/lambda-event-source-mapping-defaults.js +2 -2
  74. package/lib/lambda-helper.d.ts +1 -1
  75. package/lib/lambda-helper.js +4 -4
  76. package/lib/mediastore-defaults.d.ts +1 -1
  77. package/lib/mediastore-defaults.js +2 -2
  78. package/lib/mediastore-helper.d.ts +1 -1
  79. package/lib/mediastore-helper.js +2 -2
  80. package/lib/override-warning-service.d.ts +1 -1
  81. package/lib/override-warning-service.js +2 -2
  82. package/lib/s3-bucket-defaults.d.ts +2 -1
  83. package/lib/s3-bucket-defaults.js +14 -3
  84. package/lib/s3-bucket-helper.d.ts +12 -3
  85. package/lib/s3-bucket-helper.js +39 -59
  86. package/lib/sagemaker-defaults.d.ts +1 -1
  87. package/lib/sagemaker-defaults.js +2 -2
  88. package/lib/sagemaker-helper.d.ts +1 -1
  89. package/lib/sagemaker-helper.js +2 -2
  90. package/lib/secretsmanager-defaults.d.ts +1 -1
  91. package/lib/secretsmanager-defaults.js +2 -2
  92. package/lib/secretsmanager-helper.d.ts +1 -1
  93. package/lib/secretsmanager-helper.js +2 -2
  94. package/lib/security-group-helper.d.ts +2 -2
  95. package/lib/security-group-helper.js +2 -2
  96. package/lib/sns-defaults.d.ts +1 -1
  97. package/lib/sns-defaults.js +2 -2
  98. package/lib/sns-helper.d.ts +1 -1
  99. package/lib/sns-helper.js +2 -2
  100. package/lib/sqs-defaults.d.ts +1 -1
  101. package/lib/sqs-defaults.js +2 -2
  102. package/lib/sqs-helper.d.ts +1 -1
  103. package/lib/sqs-helper.js +2 -2
  104. package/lib/ssm-string-parameter-helper.d.ts +1 -1
  105. package/lib/ssm-string-parameter-helper.js +2 -2
  106. package/lib/step-function-defaults.d.ts +1 -1
  107. package/lib/step-function-defaults.js +2 -2
  108. package/lib/step-function-helper.d.ts +1 -1
  109. package/lib/step-function-helper.js +2 -2
  110. package/lib/utils.d.ts +13 -1
  111. package/lib/utils.js +25 -3
  112. package/lib/vpc-defaults.d.ts +5 -1
  113. package/lib/vpc-defaults.js +19 -3
  114. package/lib/vpc-helper.d.ts +4 -2
  115. package/lib/vpc-helper.js +14 -2
  116. package/lib/waf-defaults.d.ts +1 -1
  117. package/lib/waf-defaults.js +2 -2
  118. package/lib/waf-helper.d.ts +2 -2
  119. package/lib/waf-helper.js +2 -2
  120. package/node_modules/emoji-regex/LICENSE-MIT.txt +20 -0
  121. package/node_modules/emoji-regex/README.md +73 -0
  122. package/node_modules/emoji-regex/es2015/index.js +6 -0
  123. package/node_modules/emoji-regex/es2015/text.js +6 -0
  124. package/node_modules/emoji-regex/index.d.ts +23 -0
  125. package/node_modules/emoji-regex/index.js +6 -0
  126. package/node_modules/emoji-regex/package.json +50 -0
  127. package/node_modules/emoji-regex/text.js +6 -0
  128. package/node_modules/signal-exit/index.js +30 -8
  129. package/node_modules/signal-exit/package.json +7 -5
  130. package/node_modules/wide-align/LICENSE +0 -0
  131. package/node_modules/wide-align/README.md +0 -0
  132. package/node_modules/wide-align/align.js +0 -0
  133. package/node_modules/wide-align/node_modules/ansi-regex/index.d.ts +37 -0
  134. package/node_modules/wide-align/node_modules/ansi-regex/index.js +4 -4
  135. package/node_modules/wide-align/node_modules/ansi-regex/package.json +53 -51
  136. package/node_modules/wide-align/node_modules/ansi-regex/readme.md +35 -3
  137. package/node_modules/wide-align/node_modules/is-fullwidth-code-point/index.d.ts +17 -0
  138. package/node_modules/wide-align/node_modules/is-fullwidth-code-point/index.js +25 -21
  139. package/node_modules/wide-align/node_modules/is-fullwidth-code-point/license +4 -16
  140. package/node_modules/wide-align/node_modules/is-fullwidth-code-point/package.json +40 -43
  141. package/node_modules/wide-align/node_modules/is-fullwidth-code-point/readme.md +6 -6
  142. package/node_modules/wide-align/node_modules/string-width/index.d.ts +29 -0
  143. package/node_modules/wide-align/node_modules/string-width/index.js +16 -5
  144. package/node_modules/wide-align/node_modules/string-width/package.json +11 -10
  145. package/node_modules/wide-align/node_modules/string-width/readme.md +15 -7
  146. package/node_modules/wide-align/node_modules/strip-ansi/index.d.ts +17 -0
  147. package/node_modules/wide-align/node_modules/strip-ansi/index.js +1 -1
  148. package/node_modules/wide-align/node_modules/strip-ansi/package.json +52 -50
  149. package/node_modules/wide-align/node_modules/strip-ansi/readme.md +12 -5
  150. package/node_modules/wide-align/package.json +5 -5
  151. package/package.json +8 -10
  152. package/test/alb-helper.test.d.ts +13 -0
  153. package/test/alb-helper.test.js +407 -0
  154. package/test/apigateway-helper.test.d.ts +1 -1
  155. package/test/apigateway-helper.test.js +16 -9
  156. package/test/cloudfront-distribution-api-gateway-helper.test.d.ts +1 -1
  157. package/test/cloudfront-distribution-api-gateway-helper.test.js +5 -5
  158. package/test/cloudfront-distribution-mediastore-helper.test.d.ts +1 -1
  159. package/test/cloudfront-distribution-mediastore-helper.test.js +2 -2
  160. package/test/cloudfront-distribution-s3-helper.test.d.ts +1 -1
  161. package/test/cloudfront-distribution-s3-helper.test.js +45 -15
  162. package/test/cloudwatch-log-group-helper.test.d.ts +1 -1
  163. package/test/cloudwatch-log-group-helper.test.js +2 -2
  164. package/test/congnito-helper.test.d.ts +1 -1
  165. package/test/congnito-helper.test.js +2 -2
  166. package/test/dynamo-table.test.d.ts +1 -1
  167. package/test/dynamo-table.test.js +2 -2
  168. package/test/elasticsearch-helper.test.d.ts +1 -1
  169. package/test/elasticsearch-helper.test.js +2 -2
  170. package/test/eventbridge-helper.test.d.ts +1 -1
  171. package/test/eventbridge-helper.test.js +9 -5
  172. package/test/events-rule.test.d.ts +1 -1
  173. package/test/events-rule.test.js +2 -2
  174. package/test/fargate-helper.test.d.ts +13 -0
  175. package/test/fargate-helper.test.js +316 -0
  176. package/test/glue-job-helper.test.d.ts +1 -1
  177. package/test/glue-job-helper.test.js +12 -8
  178. package/test/glue-table-helper.test.d.ts +1 -1
  179. package/test/glue-table-helper.test.js +2 -2
  180. package/test/input-validation.test.d.ts +1 -1
  181. package/test/input-validation.test.js +55 -2
  182. package/test/iot-rule.test.d.ts +1 -1
  183. package/test/iot-rule.test.js +2 -2
  184. package/test/kinesis-analytics.test.d.ts +1 -1
  185. package/test/kinesis-analytics.test.js +2 -2
  186. package/test/kinesis-firehose-s3-defaults.test.d.ts +1 -1
  187. package/test/kinesis-firehose-s3-defaults.test.js +2 -2
  188. package/test/kinesis-streams-defaults.test.d.ts +1 -1
  189. package/test/kinesis-streams-defaults.test.js +2 -2
  190. package/test/kinesis-streams-helper.test.d.ts +1 -1
  191. package/test/kinesis-streams-helper.test.js +2 -2
  192. package/test/kms-helper.test.d.ts +1 -1
  193. package/test/kms-helper.test.js +2 -2
  194. package/test/lambda-event-source.test.d.ts +1 -1
  195. package/test/lambda-event-source.test.js +2 -2
  196. package/test/lambda-helper.test.d.ts +1 -1
  197. package/test/lambda-helper.test.js +15 -15
  198. package/test/mediastore-helper.test.d.ts +1 -1
  199. package/test/mediastore-helper.test.js +2 -2
  200. package/test/override-warning-service.test.d.ts +1 -1
  201. package/test/override-warning-service.test.js +2 -2
  202. package/test/s3-bucket-helper.test.d.ts +1 -1
  203. package/test/s3-bucket-helper.test.js +31 -13
  204. package/test/s3-bucket.test.d.ts +1 -1
  205. package/test/s3-bucket.test.js +204 -2
  206. package/test/sagemaker-helper.test.d.ts +1 -1
  207. package/test/sagemaker-helper.test.js +2 -2
  208. package/test/secretsmanager-helper.test.d.ts +1 -1
  209. package/test/secretsmanager-helper.test.js +2 -2
  210. package/test/security-group-helper.test.d.ts +1 -1
  211. package/test/security-group-helper.test.js +2 -2
  212. package/test/sns-helper.test.d.ts +1 -1
  213. package/test/sns-helper.test.js +2 -2
  214. package/test/sqs-helper.test.d.ts +1 -1
  215. package/test/sqs-helper.test.js +2 -2
  216. package/test/ssm-string-parameter-helper.test.d.ts +1 -1
  217. package/test/ssm-string-parameter-helper.test.js +2 -2
  218. package/test/step-function-helper.test.d.ts +1 -1
  219. package/test/step-function-helper.test.js +2 -2
  220. package/test/test-helper.d.ts +7 -2
  221. package/test/test-helper.js +25 -4
  222. package/test/utils.test.d.ts +1 -1
  223. package/test/utils.test.js +64 -2
  224. package/test/vpc-helper.test.d.ts +1 -1
  225. package/test/vpc-helper.test.js +9 -16
  226. package/test/waf-helper.test.d.ts +1 -1
  227. package/test/waf-helper.test.js +2 -2
  228. package/node_modules/@types/deep-diff/LICENSE +0 -21
  229. package/node_modules/@types/deep-diff/README.md +0 -16
  230. package/node_modules/@types/deep-diff/index.d.ts +0 -60
  231. package/node_modules/@types/deep-diff/package.json +0 -25
  232. package/node_modules/@types/npmlog/LICENSE +0 -21
  233. package/node_modules/@types/npmlog/README.md +0 -16
  234. package/node_modules/@types/npmlog/index.d.ts +0 -78
  235. package/node_modules/@types/npmlog/package.json +0 -35
@@ -0,0 +1,407 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
6
+ * with the License. A copy of the License is located at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
11
+ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
12
+ * and limitations under the License.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
16
+ const elb = require("aws-cdk-lib/aws-elasticloadbalancingv2");
17
+ const lambda = require("aws-cdk-lib/aws-lambda");
18
+ const defaults = require("../index");
19
+ require("@aws-cdk/assert/jest");
20
+ test('Test ObtainAlb with existing ALB', () => {
21
+ const stack = new aws_cdk_lib_1.Stack();
22
+ // Build VPC
23
+ const vpc = defaults.buildVpc(stack, {
24
+ defaultVpcProps: defaults.DefaultPublicPrivateVpcProps(),
25
+ });
26
+ const existingLoadBalancer = new elb.ApplicationLoadBalancer(stack, 'load-balancer', {
27
+ vpc,
28
+ internetFacing: true,
29
+ loadBalancerName: 'unique-name'
30
+ });
31
+ defaults.ObtainAlb(stack, 'test', vpc, true, existingLoadBalancer);
32
+ expect(stack).toHaveResourceLike('AWS::ElasticLoadBalancingV2::LoadBalancer', {
33
+ Name: "unique-name",
34
+ });
35
+ });
36
+ test('Test ObtainAlb for new ALB with provided props', () => {
37
+ const stack = new aws_cdk_lib_1.Stack(undefined, undefined, {
38
+ env: { account: "123456789012", region: 'us-east-1' },
39
+ });
40
+ // Build VPC
41
+ const vpc = defaults.buildVpc(stack, {
42
+ defaultVpcProps: defaults.DefaultPublicPrivateVpcProps(),
43
+ });
44
+ defaults.ObtainAlb(stack, 'test', vpc, true, undefined, {
45
+ loadBalancerName: 'new-loadbalancer',
46
+ vpc,
47
+ internetFacing: true
48
+ });
49
+ expect(stack).toHaveResourceLike('AWS::ElasticLoadBalancingV2::LoadBalancer', {
50
+ Name: "new-loadbalancer",
51
+ Scheme: "internet-facing",
52
+ });
53
+ });
54
+ test('Test ObtainAlb for new ALB with default props', () => {
55
+ const stack = new aws_cdk_lib_1.Stack(undefined, undefined, {
56
+ env: { account: "123456789012", region: 'us-east-1' },
57
+ });
58
+ // Build VPC
59
+ const vpc = defaults.buildVpc(stack, {
60
+ defaultVpcProps: defaults.DefaultPublicPrivateVpcProps(),
61
+ });
62
+ defaults.ObtainAlb(stack, 'test', vpc, false);
63
+ expect(stack).toHaveResourceLike('AWS::ElasticLoadBalancingV2::LoadBalancer', {
64
+ Scheme: "internal",
65
+ });
66
+ });
67
+ test('Test with custom logging bucket props', () => {
68
+ // Creating ALB logging requires a region and account (but
69
+ // these can be fake in unit tests)
70
+ const stack = new aws_cdk_lib_1.Stack(undefined, undefined, {
71
+ env: { account: "123456789012", region: 'us-east-1' },
72
+ });
73
+ // Build VPC
74
+ const vpc = defaults.buildVpc(stack, {
75
+ defaultVpcProps: defaults.DefaultPublicPrivateVpcProps(),
76
+ });
77
+ const testName = 'test-name';
78
+ defaults.ObtainAlb(stack, 'test', vpc, false, undefined, undefined, true, { bucketName: testName });
79
+ expect(stack).toHaveResourceLike('AWS::S3::Bucket', {
80
+ BucketName: testName
81
+ });
82
+ });
83
+ test('Test with no logging', () => {
84
+ const stack = new aws_cdk_lib_1.Stack();
85
+ // Build VPC
86
+ const vpc = defaults.buildVpc(stack, {
87
+ defaultVpcProps: defaults.DefaultPublicPrivateVpcProps(),
88
+ });
89
+ defaults.ObtainAlb(stack, 'test', vpc, false, undefined, undefined, false);
90
+ expect(stack).not.toHaveResourceLike('AWS::S3::Bucket', {});
91
+ });
92
+ test('Test add single lambda target group with no customization', () => {
93
+ const stack = new aws_cdk_lib_1.Stack();
94
+ // Set up test framework independent of our code for unit testing
95
+ const testFunction = CreateTestFunction(stack, 'test-function');
96
+ const testVpc = defaults.getTestVpc(stack);
97
+ const testAlb = CreateTestLoadBalancer(stack, testVpc);
98
+ const testListener = CreateTestListener(stack, 'test-listener', testAlb);
99
+ // This is the code we're testing
100
+ defaults.AddLambdaTarget(stack, 'test-lambda-target', testListener, testFunction);
101
+ expect(stack).toHaveResourceLike('AWS::ElasticLoadBalancingV2::Listener', {
102
+ DefaultActions: [
103
+ {
104
+ TargetGroupArn: {
105
+ Ref: "testlambdatargettg7E5C32F4"
106
+ },
107
+ Type: "forward"
108
+ }
109
+ ],
110
+ });
111
+ expect(stack).toHaveResourceLike('AWS::ElasticLoadBalancingV2::TargetGroup', {
112
+ TargetType: "lambda",
113
+ });
114
+ });
115
+ test('Test add single lambda target group with target group props', () => {
116
+ const stack = new aws_cdk_lib_1.Stack();
117
+ // Set up test framework independent of our code for unit testing
118
+ const testFunction = CreateTestFunction(stack, 'test-function');
119
+ const testVpc = defaults.getTestVpc(stack);
120
+ const testAlb = CreateTestLoadBalancer(stack, testVpc);
121
+ const testListener = CreateTestListener(stack, 'test-listener', testAlb);
122
+ const targetGroupName = 'test-group';
123
+ // This is the code we're testing
124
+ defaults.AddLambdaTarget(stack, 'test-lambda-target', testListener, testFunction, undefined, { targetGroupName });
125
+ expect(stack).toHaveResourceLike('AWS::ElasticLoadBalancingV2::TargetGroup', {
126
+ TargetType: "lambda",
127
+ Name: targetGroupName,
128
+ });
129
+ });
130
+ test('Test add rule props for second lambda target group', () => {
131
+ const stack = new aws_cdk_lib_1.Stack();
132
+ // Set up test framework independent of our code for unit testing
133
+ const testFunction = CreateTestFunction(stack, 'test-function');
134
+ const testVpc = defaults.getTestVpc(stack);
135
+ const testAlb = CreateTestLoadBalancer(stack, testVpc);
136
+ const testListener = CreateTestListener(stack, 'test-listener', testAlb);
137
+ const targetGroupName = 'test-group';
138
+ const pathPattern = '*admin*';
139
+ defaults.AddLambdaTarget(stack, 'test-lambda-target', testListener, testFunction, undefined, { targetGroupName });
140
+ // This is the code we're testing
141
+ const ruleProps = {
142
+ conditions: [elb.ListenerCondition.pathPatterns([pathPattern])],
143
+ priority: 10
144
+ };
145
+ defaults.AddLambdaTarget(stack, 'test-second-lambda-target', testListener, testFunction, ruleProps, { targetGroupName });
146
+ expect(stack).toCountResources('AWS::ElasticLoadBalancingV2::TargetGroup', 2);
147
+ expect(stack).toHaveResourceLike('AWS::ElasticLoadBalancingV2::ListenerRule', {
148
+ Conditions: [
149
+ {
150
+ Field: "path-pattern",
151
+ PathPatternConfig: {
152
+ Values: [
153
+ pathPattern
154
+ ]
155
+ }
156
+ }
157
+ ]
158
+ });
159
+ });
160
+ test('Test add single fargate target with no customization', () => {
161
+ const stack = new aws_cdk_lib_1.Stack();
162
+ // Set up test framework independent of our code for unit testing
163
+ const testVpc = defaults.getTestVpc(stack);
164
+ const testService = CreateTestFargateService(stack, 'test-service', testVpc);
165
+ const testAlb = CreateTestLoadBalancer(stack, testVpc);
166
+ const testListener = CreateTestListener(stack, 'test-listener', testAlb);
167
+ // This is the code we're testing
168
+ defaults.AddFargateTarget(stack, 'test-fargate-target', testListener, testService, undefined, {
169
+ vpc: testVpc,
170
+ protocol: elb.ApplicationProtocol.HTTP
171
+ });
172
+ expect(stack).toHaveResourceLike('AWS::ElasticLoadBalancingV2::Listener', {
173
+ DefaultActions: [
174
+ {
175
+ TargetGroupArn: {
176
+ Ref: "testfargatetargettg01FF5AA3"
177
+ },
178
+ Type: "forward"
179
+ }
180
+ ],
181
+ });
182
+ expect(stack).toHaveResourceLike('AWS::ElasticLoadBalancingV2::TargetGroup', {
183
+ TargetType: "ip",
184
+ });
185
+ });
186
+ test('Test add two fargate targets with rules', () => {
187
+ const stack = new aws_cdk_lib_1.Stack();
188
+ // Set up test framework independent of our code for unit testing
189
+ const testVpc = defaults.getTestVpc(stack);
190
+ const testService = CreateTestFargateService(stack, 'test-service', testVpc);
191
+ const testAlb = CreateTestLoadBalancer(stack, testVpc);
192
+ const testListener = CreateTestListener(stack, 'test-listener', testAlb);
193
+ const pathPattern = '*admin*';
194
+ defaults.AddFargateTarget(stack, 'test-fargate-target', testListener, testService, undefined, {
195
+ vpc: testVpc,
196
+ protocol: elb.ApplicationProtocol.HTTP
197
+ });
198
+ // This is the code we're testing
199
+ const ruleProps = {
200
+ conditions: [elb.ListenerCondition.pathPatterns([pathPattern])],
201
+ priority: 10
202
+ };
203
+ defaults.AddFargateTarget(stack, 'test-second-fargate-target', testListener, testService, ruleProps, {
204
+ vpc: testVpc,
205
+ protocol: elb.ApplicationProtocol.HTTP
206
+ });
207
+ expect(stack).toCountResources('AWS::ElasticLoadBalancingV2::TargetGroup', 2);
208
+ expect(stack).toHaveResourceLike('AWS::ElasticLoadBalancingV2::ListenerRule', {
209
+ Conditions: [
210
+ {
211
+ Field: "path-pattern",
212
+ PathPatternConfig: {
213
+ Values: [
214
+ pathPattern
215
+ ]
216
+ }
217
+ }
218
+ ]
219
+ });
220
+ });
221
+ test('Test adding a listener with defaults', () => {
222
+ const stack = new aws_cdk_lib_1.Stack();
223
+ // Set up test framework independent of our code for unit testing
224
+ const testVpc = defaults.getTestVpc(stack);
225
+ const testAlb = CreateTestLoadBalancer(stack, testVpc);
226
+ const testCert = defaults.getFakeCertificate(stack, 'not-really-a-cert');
227
+ const listener = defaults.AddListener(stack, 'test', testAlb, { certificates: [testCert] });
228
+ // Need to add a target because a listener is not allowed to exist without a target or action
229
+ defaults.AddLambdaTarget(stack, 'dummy-target', listener, CreateTestFunction(stack, 'dummy-function'));
230
+ // This should create 2 listeners, HTTPS plus redirect of HTTP
231
+ expect(stack).toHaveResourceLike('AWS::ElasticLoadBalancingV2::Listener', {
232
+ Protocol: 'HTTPS',
233
+ });
234
+ expect(stack).toHaveResourceLike('AWS::ElasticLoadBalancingV2::Listener', {
235
+ Protocol: 'HTTP',
236
+ });
237
+ });
238
+ test('Test adding an HTTPS listener with no cert (error)', () => {
239
+ const stack = new aws_cdk_lib_1.Stack();
240
+ // Set up test framework independent of our code for unit testing
241
+ const testVpc = defaults.getTestVpc(stack);
242
+ const testAlb = CreateTestLoadBalancer(stack, testVpc);
243
+ const app = () => {
244
+ defaults.AddListener(stack, 'test', testAlb, {});
245
+ };
246
+ expect(app).toThrowError('A listener using HTTPS protocol requires a certificate');
247
+ });
248
+ test('Test adding an HTTP listener with a cert (error)', () => {
249
+ const stack = new aws_cdk_lib_1.Stack();
250
+ // Set up test framework independent of our code for unit testing
251
+ const testVpc = defaults.getTestVpc(stack);
252
+ const testAlb = CreateTestLoadBalancer(stack, testVpc);
253
+ const testCert = defaults.getFakeCertificate(stack, 'not-really-a-cert');
254
+ const app = () => {
255
+ defaults.AddListener(stack, 'test', testAlb, { protocol: 'HTTP', certificates: [testCert] });
256
+ };
257
+ expect(app).toThrowError('HTTP listeners cannot use a certificate');
258
+ });
259
+ test('Test adding a HTTP listener', () => {
260
+ const stack = new aws_cdk_lib_1.Stack();
261
+ // Set up test framework independent of our code for unit testing
262
+ const testVpc = defaults.getTestVpc(stack);
263
+ const testAlb = CreateTestLoadBalancer(stack, testVpc);
264
+ const listener = defaults.AddListener(stack, 'test', testAlb, { protocol: 'HTTP' });
265
+ // Need to add a target because a listener is not allowed to exist without a target or action
266
+ defaults.AddLambdaTarget(stack, 'dummy-target', listener, CreateTestFunction(stack, 'dummy-function'));
267
+ expect(stack).toHaveResourceLike('AWS::ElasticLoadBalancingV2::Listener', {
268
+ Protocol: 'HTTP',
269
+ });
270
+ expect(stack).toCountResources('AWS::ElasticLoadBalancingV2::Listener', 1);
271
+ });
272
+ test('Test sending custom logging bucket props', () => {
273
+ const stack = new aws_cdk_lib_1.Stack();
274
+ // Set up test framework independent of our code for unit testing
275
+ const testVpc = defaults.getTestVpc(stack);
276
+ const testAlb = CreateTestLoadBalancer(stack, testVpc);
277
+ const listener = defaults.AddListener(stack, 'test', testAlb, { protocol: 'HTTP' });
278
+ // Need to add a target because a listener is not allowed to exist without a target or action
279
+ defaults.AddLambdaTarget(stack, 'dummy-target', listener, CreateTestFunction(stack, 'dummy-function'));
280
+ });
281
+ test('Test GetActiveListener with 0 listeners', () => {
282
+ const stack = new aws_cdk_lib_1.Stack();
283
+ // Set up test framework independent of our code for unit testing
284
+ const testVpc = defaults.getTestVpc(stack);
285
+ const testAlb = CreateTestLoadBalancer(stack, testVpc);
286
+ const app = () => {
287
+ defaults.GetActiveListener(testAlb.listeners);
288
+ };
289
+ expect(app).toThrowError('There are no listeners in the ALB');
290
+ });
291
+ test('Test GetActiveListener with 1 listener', () => {
292
+ const stack = new aws_cdk_lib_1.Stack();
293
+ // Set up test framework independent of our code for unit testing
294
+ const testVpc = defaults.getTestVpc(stack);
295
+ const testAlb = CreateTestLoadBalancer(stack, testVpc);
296
+ defaults.AddListener(stack, 'test', testAlb, { protocol: 'HTTP' });
297
+ const listener = defaults.GetActiveListener(testAlb.listeners);
298
+ expect(listener.node.defaultChild.protocol).toBe('HTTP');
299
+ });
300
+ test('Test GetActiveListener with 2 listeners', () => {
301
+ const stack = new aws_cdk_lib_1.Stack();
302
+ // Set up test framework independent of our code for unit testing
303
+ const testVpc = defaults.getTestVpc(stack);
304
+ const testAlb = CreateTestLoadBalancer(stack, testVpc);
305
+ const testCert = defaults.getFakeCertificate(stack, 'not-really-a-cert');
306
+ defaults.AddListener(stack, 'test', testAlb, { certificates: [testCert] });
307
+ const listener = defaults.GetActiveListener(testAlb.listeners);
308
+ expect(listener.node.defaultChild.protocol).toBe('HTTPS');
309
+ });
310
+ test('Test use of certificateArns error', () => {
311
+ const props = {
312
+ listenerProps: {
313
+ certificateArns: ['arn1'],
314
+ }
315
+ };
316
+ const app = () => {
317
+ defaults.CheckAlbProps(props);
318
+ };
319
+ expect(app).toThrowError("certificateArns is deprecated. Please supply certificates using props.listenerProps.certificates\n");
320
+ });
321
+ test('Test bad first listener error', () => {
322
+ const props = {
323
+ existingLoadBalancerObj: {
324
+ listeners: [],
325
+ }
326
+ };
327
+ const app = () => {
328
+ defaults.CheckAlbProps(props);
329
+ };
330
+ expect(app).toThrowError("When adding the first listener and target to a load balancer, listenerProps must be specified and include at least a certificate or protocol: HTTP\n");
331
+ const app2 = () => {
332
+ defaults.CheckAlbProps({});
333
+ };
334
+ expect(app2).toThrowError("When adding the first listener and target to a load balancer, listenerProps must be specified and include at least a certificate or protocol: HTTP\n");
335
+ });
336
+ test('Test second target with no rules error', () => {
337
+ const props = {
338
+ existingLoadBalancerObj: {
339
+ listeners: ['fake listener'],
340
+ },
341
+ existingVpc: { fake: 'vpc' }
342
+ };
343
+ const app = () => {
344
+ defaults.CheckAlbProps(props);
345
+ };
346
+ expect(app).toThrowError("When adding a second target to an existing listener, there must be rules provided\n");
347
+ });
348
+ test('Test existing Load Balancer with no VPC provided error', () => {
349
+ const props = {
350
+ existingLoadBalancerObj: {
351
+ name: 'placeholder',
352
+ listeners: []
353
+ }
354
+ };
355
+ const app = () => {
356
+ defaults.CheckAlbProps(props);
357
+ };
358
+ expect(app).toThrowError("An existing ALB is already in a VPC, that VPC must be provided in props.existingVpc for the rest of the construct to use.\n");
359
+ });
360
+ test('Test sending listenerProps to existingListener error', () => {
361
+ const props = {
362
+ existingLoadBalancerObj: {
363
+ listeners: ['placeholder']
364
+ },
365
+ listenerProps: { val: 'placeholder' }
366
+ };
367
+ const app = () => {
368
+ defaults.CheckAlbProps(props);
369
+ };
370
+ expect(app).toThrowError("This load balancer already has a listener, listenerProps may not be specified\n");
371
+ });
372
+ test('Test sending VPC in loadBalancerProps error', () => {
373
+ const props = {
374
+ loadBalancerProps: {
375
+ vpc: { val: 'placeholder' }
376
+ }
377
+ };
378
+ const app = () => {
379
+ defaults.CheckAlbProps(props);
380
+ };
381
+ expect(app).toThrowError('Specify any existing VPC at the construct level, not within loadBalancerProps.\n');
382
+ });
383
+ function CreateTestLoadBalancer(stack, vpc) {
384
+ return new elb.ApplicationLoadBalancer(stack, 'load-balancer', {
385
+ vpc,
386
+ internetFacing: true,
387
+ loadBalancerName: 'unique-name'
388
+ });
389
+ }
390
+ function CreateTestFunction(stack, id) {
391
+ return new lambda.Function(stack, id, {
392
+ code: lambda.Code.fromAsset(`${__dirname}/lambda`),
393
+ runtime: lambda.Runtime.NODEJS_14_X,
394
+ handler: "index.handler",
395
+ });
396
+ }
397
+ function CreateTestFargateService(stack, id, vpc) {
398
+ const [svc] = defaults.CreateFargateService(stack, `${id}-fg-svc`, vpc, undefined, 'arn:aws:ecr:us-east-1:123456789012:repository/fake-repo', 'latest');
399
+ return svc;
400
+ }
401
+ function CreateTestListener(stack, id, alb) {
402
+ return new elb.ApplicationListener(stack, id, {
403
+ loadBalancer: alb,
404
+ protocol: elb.ApplicationProtocol.HTTP
405
+ });
406
+ }
407
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxiLWhlbHBlci50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYWxiLWhlbHBlci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7R0FXRzs7QUFFSCw2Q0FBb0M7QUFDcEMsOERBQThEO0FBQzlELGlEQUFpRDtBQUNqRCxxQ0FBcUM7QUFHckMsZ0NBQThCO0FBRTlCLElBQUksQ0FBQyxrQ0FBa0MsRUFBRSxHQUFHLEVBQUU7SUFDNUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxtQkFBSyxFQUFFLENBQUM7SUFDMUIsWUFBWTtJQUNaLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFO1FBQ25DLGVBQWUsRUFBRSxRQUFRLENBQUMsNEJBQTRCLEVBQUU7S0FDekQsQ0FBQyxDQUFDO0lBRUgsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLEVBQUUsZUFBZSxFQUFFO1FBQ25GLEdBQUc7UUFDSCxjQUFjLEVBQUUsSUFBSTtRQUNwQixnQkFBZ0IsRUFBRSxhQUFhO0tBQ2hDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLG9CQUFvQixDQUFDLENBQUM7SUFDbkUsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLGtCQUFrQixDQUFDLDJDQUEyQyxFQUFFO1FBQzVFLElBQUksRUFBRSxhQUFhO0tBQ3BCLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLGdEQUFnRCxFQUFFLEdBQUcsRUFBRTtJQUMxRCxNQUFNLEtBQUssR0FBRyxJQUFJLG1CQUFLLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRTtRQUM1QyxHQUFHLEVBQUUsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUU7S0FDdEQsQ0FBQyxDQUFDO0lBQ0gsWUFBWTtJQUNaLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFO1FBQ25DLGVBQWUsRUFBRSxRQUFRLENBQUMsNEJBQTRCLEVBQUU7S0FDekQsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFO1FBQ3RELGdCQUFnQixFQUFFLGtCQUFrQjtRQUNwQyxHQUFHO1FBQ0gsY0FBYyxFQUFFLElBQUk7S0FDckIsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLGtCQUFrQixDQUFDLDJDQUEyQyxFQUFFO1FBQzVFLElBQUksRUFBRSxrQkFBa0I7UUFDeEIsTUFBTSxFQUFFLGlCQUFpQjtLQUMxQixDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQztBQUVILElBQUksQ0FBQywrQ0FBK0MsRUFBRSxHQUFHLEVBQUU7SUFDekQsTUFBTSxLQUFLLEdBQUcsSUFBSSxtQkFBSyxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUU7UUFDNUMsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFO0tBQ3RELENBQUMsQ0FBQztJQUNILFlBQVk7SUFDWixNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRTtRQUNuQyxlQUFlLEVBQUUsUUFBUSxDQUFDLDRCQUE0QixFQUFFO0tBQ3pELENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDOUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLGtCQUFrQixDQUFDLDJDQUEyQyxFQUFFO1FBQzVFLE1BQU0sRUFBRSxVQUFVO0tBQ25CLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLHVDQUF1QyxFQUFFLEdBQUcsRUFBRTtJQUNqRCwwREFBMEQ7SUFDMUQsbUNBQW1DO0lBQ25DLE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQUssQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFO1FBQzVDLEdBQUcsRUFBRSxFQUFFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRTtLQUN0RCxDQUFDLENBQUM7SUFDSCxZQUFZO0lBQ1osTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUU7UUFDbkMsZUFBZSxFQUFFLFFBQVEsQ0FBQyw0QkFBNEIsRUFBRTtLQUN6RCxDQUFDLENBQUM7SUFFSCxNQUFNLFFBQVEsR0FBRyxXQUFXLENBQUM7SUFFN0IsUUFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUNwRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsa0JBQWtCLENBQUMsaUJBQWlCLEVBQUU7UUFDbEQsVUFBVSxFQUFFLFFBQVE7S0FDckIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUM7QUFFSCxJQUFJLENBQUMsc0JBQXNCLEVBQUUsR0FBRyxFQUFFO0lBQ2hDLE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO0lBQzFCLFlBQVk7SUFDWixNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRTtRQUNuQyxlQUFlLEVBQUUsUUFBUSxDQUFDLDRCQUE0QixFQUFFO0tBQ3pELENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDM0UsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUM5RCxDQUFDLENBQUMsQ0FBQztBQUVILElBQUksQ0FBQywyREFBMkQsRUFBRSxHQUFHLEVBQUU7SUFDckUsTUFBTSxLQUFLLEdBQUcsSUFBSSxtQkFBSyxFQUFFLENBQUM7SUFFMUIsaUVBQWlFO0lBQ2pFLE1BQU0sWUFBWSxHQUFHLGtCQUFrQixDQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsQ0FBQztJQUNoRSxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNDLE1BQU0sT0FBTyxHQUFHLHNCQUFzQixDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN2RCxNQUFNLFlBQVksR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsZUFBZSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBRXpFLGlDQUFpQztJQUNqQyxRQUFRLENBQUMsZUFBZSxDQUN0QixLQUFLLEVBQ0wsb0JBQW9CLEVBQ3BCLFlBQVksRUFDWixZQUFZLENBQ2IsQ0FBQztJQUVGLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyx1Q0FBdUMsRUFBRTtRQUN4RSxjQUFjLEVBQUU7WUFDZDtnQkFDRSxjQUFjLEVBQUU7b0JBQ2QsR0FBRyxFQUFFLDRCQUE0QjtpQkFDbEM7Z0JBQ0QsSUFBSSxFQUFFLFNBQVM7YUFDaEI7U0FDRjtLQUNGLENBQUMsQ0FBQztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQywwQ0FBMEMsRUFBRTtRQUMzRSxVQUFVLEVBQUUsUUFBUTtLQUNyQixDQUFDLENBQUM7QUFFTCxDQUFDLENBQUMsQ0FBQztBQUVILElBQUksQ0FBQyw2REFBNkQsRUFBRSxHQUFHLEVBQUU7SUFDdkUsTUFBTSxLQUFLLEdBQUcsSUFBSSxtQkFBSyxFQUFFLENBQUM7SUFFMUIsaUVBQWlFO0lBQ2pFLE1BQU0sWUFBWSxHQUFHLGtCQUFrQixDQUFDLEtBQUssRUFBRSxlQUFlLENBQUMsQ0FBQztJQUNoRSxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNDLE1BQU0sT0FBTyxHQUFHLHNCQUFzQixDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN2RCxNQUFNLFlBQVksR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsZUFBZSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3pFLE1BQU0sZUFBZSxHQUFHLFlBQVksQ0FBQztJQUVyQyxpQ0FBaUM7SUFDakMsUUFBUSxDQUFDLGVBQWUsQ0FDdEIsS0FBSyxFQUNMLG9CQUFvQixFQUNwQixZQUFZLEVBQ1osWUFBWSxFQUNaLFNBQVMsRUFDVCxFQUFFLGVBQWUsRUFBRSxDQUNwQixDQUFDO0lBRUYsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLGtCQUFrQixDQUFDLDBDQUEwQyxFQUFFO1FBQzNFLFVBQVUsRUFBRSxRQUFRO1FBQ3BCLElBQUksRUFBRSxlQUFlO0tBQ3RCLENBQUMsQ0FBQztBQUVMLENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLG9EQUFvRCxFQUFFLEdBQUcsRUFBRTtJQUM5RCxNQUFNLEtBQUssR0FBRyxJQUFJLG1CQUFLLEVBQUUsQ0FBQztJQUUxQixpRUFBaUU7SUFDakUsTUFBTSxZQUFZLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxDQUFDO0lBQ2hFLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0MsTUFBTSxPQUFPLEdBQUcsc0JBQXNCLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZELE1BQU0sWUFBWSxHQUFHLGtCQUFrQixDQUFDLEtBQUssRUFBRSxlQUFlLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDekUsTUFBTSxlQUFlLEdBQUcsWUFBWSxDQUFDO0lBQ3JDLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQztJQUU5QixRQUFRLENBQUMsZUFBZSxDQUN0QixLQUFLLEVBQ0wsb0JBQW9CLEVBQ3BCLFlBQVksRUFDWixZQUFZLEVBQ1osU0FBUyxFQUNULEVBQUUsZUFBZSxFQUFFLENBQ3BCLENBQUM7SUFFRixpQ0FBaUM7SUFDakMsTUFBTSxTQUFTLEdBQUc7UUFDaEIsVUFBVSxFQUFFLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDL0QsUUFBUSxFQUFFLEVBQUU7S0FDYixDQUFDO0lBQ0YsUUFBUSxDQUFDLGVBQWUsQ0FDdEIsS0FBSyxFQUNMLDJCQUEyQixFQUMzQixZQUFZLEVBQ1osWUFBWSxFQUNaLFNBQVMsRUFDVCxFQUFFLGVBQWUsRUFBRSxDQUNwQixDQUFDO0lBRUYsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLGdCQUFnQixDQUFDLDBDQUEwQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzlFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQywyQ0FBMkMsRUFBRTtRQUM1RSxVQUFVLEVBQUU7WUFDVjtnQkFDRSxLQUFLLEVBQUUsY0FBYztnQkFDckIsaUJBQWlCLEVBQUU7b0JBQ2pCLE1BQU0sRUFBRTt3QkFDTixXQUFXO3FCQUNaO2lCQUNGO2FBQ0Y7U0FDRjtLQUNGLENBQUMsQ0FBQztBQUVMLENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLHNEQUFzRCxFQUFFLEdBQUcsRUFBRTtJQUNoRSxNQUFNLEtBQUssR0FBRyxJQUFJLG1CQUFLLEVBQUUsQ0FBQztJQUUxQixpRUFBaUU7SUFDakUsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzQyxNQUFNLFdBQVcsR0FBRyx3QkFBd0IsQ0FBQyxLQUFLLEVBQUUsY0FBYyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzdFLE1BQU0sT0FBTyxHQUFHLHNCQUFzQixDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN2RCxNQUFNLFlBQVksR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsZUFBZSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBRXpFLGlDQUFpQztJQUNqQyxRQUFRLENBQUMsZ0JBQWdCLENBQ3ZCLEtBQUssRUFDTCxxQkFBcUIsRUFDckIsWUFBWSxFQUNaLFdBQVcsRUFDWCxTQUFTLEVBQ1Q7UUFDRSxHQUFHLEVBQUUsT0FBTztRQUNaLFFBQVEsRUFBRSxHQUFHLENBQUMsbUJBQW1CLENBQUMsSUFBSTtLQUN2QyxDQUNGLENBQUM7SUFFRixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsa0JBQWtCLENBQUMsdUNBQXVDLEVBQUU7UUFDeEUsY0FBYyxFQUFFO1lBQ2Q7Z0JBQ0UsY0FBYyxFQUFFO29CQUNkLEdBQUcsRUFBRSw2QkFBNkI7aUJBQ25DO2dCQUNELElBQUksRUFBRSxTQUFTO2FBQ2hCO1NBQ0Y7S0FDRixDQUFDLENBQUM7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsa0JBQWtCLENBQUMsMENBQTBDLEVBQUU7UUFDM0UsVUFBVSxFQUFFLElBQUk7S0FDakIsQ0FBQyxDQUFDO0FBRUwsQ0FBQyxDQUFDLENBQUM7QUFFSCxJQUFJLENBQUMseUNBQXlDLEVBQUUsR0FBRyxFQUFFO0lBQ25ELE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO0lBRTFCLGlFQUFpRTtJQUNqRSxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNDLE1BQU0sV0FBVyxHQUFHLHdCQUF3QixDQUFDLEtBQUssRUFBRSxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDN0UsTUFBTSxPQUFPLEdBQUcsc0JBQXNCLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZELE1BQU0sWUFBWSxHQUFHLGtCQUFrQixDQUFDLEtBQUssRUFBRSxlQUFlLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDekUsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDO0lBRTlCLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FDdkIsS0FBSyxFQUNMLHFCQUFxQixFQUNyQixZQUFZLEVBQ1osV0FBVyxFQUNYLFNBQVMsRUFDVDtRQUNFLEdBQUcsRUFBRSxPQUFPO1FBQ1osUUFBUSxFQUFFLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJO0tBQ3ZDLENBQ0YsQ0FBQztJQUVGLGlDQUFpQztJQUNqQyxNQUFNLFNBQVMsR0FBRztRQUNoQixVQUFVLEVBQUUsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsWUFBWSxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUMvRCxRQUFRLEVBQUUsRUFBRTtLQUNiLENBQUM7SUFDRixRQUFRLENBQUMsZ0JBQWdCLENBQ3ZCLEtBQUssRUFDTCw0QkFBNEIsRUFDNUIsWUFBWSxFQUNaLFdBQVcsRUFDWCxTQUFTLEVBQ1Q7UUFDRSxHQUFHLEVBQUUsT0FBTztRQUNaLFFBQVEsRUFBRSxHQUFHLENBQUMsbUJBQW1CLENBQUMsSUFBSTtLQUN2QyxDQUNGLENBQUM7SUFFRixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsMENBQTBDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDOUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLGtCQUFrQixDQUFDLDJDQUEyQyxFQUFFO1FBQzVFLFVBQVUsRUFBRTtZQUNWO2dCQUNFLEtBQUssRUFBRSxjQUFjO2dCQUNyQixpQkFBaUIsRUFBRTtvQkFDakIsTUFBTSxFQUFFO3dCQUNOLFdBQVc7cUJBQ1o7aUJBQ0Y7YUFDRjtTQUNGO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUM7QUFFSCxJQUFJLENBQUMsc0NBQXNDLEVBQUUsR0FBRyxFQUFFO0lBQ2hELE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO0lBRTFCLGlFQUFpRTtJQUNqRSxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNDLE1BQU0sT0FBTyxHQUFHLHNCQUFzQixDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN2RCxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFLG1CQUFtQixDQUFDLENBQUM7SUFFekUsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxFQUFFLFlBQVksRUFBRSxDQUFFLFFBQVEsQ0FBRSxFQUFFLENBQUMsQ0FBQztJQUU5Riw4RkFBOEY7SUFDOUYsUUFBUSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO0lBRXZHLDhEQUE4RDtJQUM5RCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsa0JBQWtCLENBQUMsdUNBQXVDLEVBQUU7UUFDeEUsUUFBUSxFQUFFLE9BQU87S0FDbEIsQ0FBQyxDQUFDO0lBRUgsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLGtCQUFrQixDQUFDLHVDQUF1QyxFQUFFO1FBQ3hFLFFBQVEsRUFBRSxNQUFNO0tBQ2pCLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLG9EQUFvRCxFQUFFLEdBQUcsRUFBRTtJQUM5RCxNQUFNLEtBQUssR0FBRyxJQUFJLG1CQUFLLEVBQUUsQ0FBQztJQUUxQixpRUFBaUU7SUFDakUsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzQyxNQUFNLE9BQU8sR0FBRyxzQkFBc0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFFdkQsTUFBTSxHQUFHLEdBQUcsR0FBRyxFQUFFO1FBQ2YsUUFBUSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxFQUFHLENBQUMsQ0FBQztJQUNwRCxDQUFDLENBQUM7SUFFRixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsWUFBWSxDQUFDLHdEQUF3RCxDQUFDLENBQUM7QUFDckYsQ0FBQyxDQUFDLENBQUM7QUFFSCxJQUFJLENBQUMsa0RBQWtELEVBQUUsR0FBRyxFQUFFO0lBQzVELE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO0lBRTFCLGlFQUFpRTtJQUNqRSxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNDLE1BQU0sT0FBTyxHQUFHLHNCQUFzQixDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN2RCxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFLG1CQUFtQixDQUFDLENBQUM7SUFFekUsTUFBTSxHQUFHLEdBQUcsR0FBRyxFQUFFO1FBQ2YsUUFBUSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLENBQUUsUUFBUSxDQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ2pHLENBQUMsQ0FBQztJQUVGLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxZQUFZLENBQUMseUNBQXlDLENBQUMsQ0FBQztBQUN0RSxDQUFDLENBQUMsQ0FBQztBQUVILElBQUksQ0FBQyw2QkFBNkIsRUFBRSxHQUFHLEVBQUU7SUFDdkMsTUFBTSxLQUFLLEdBQUcsSUFBSSxtQkFBSyxFQUFFLENBQUM7SUFFMUIsaUVBQWlFO0lBQ2pFLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0MsTUFBTSxPQUFPLEdBQUcsc0JBQXNCLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBRXZELE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUVwRiw4RkFBOEY7SUFDOUYsUUFBUSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO0lBRXZHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyx1Q0FBdUMsRUFBRTtRQUN4RSxRQUFRLEVBQUUsTUFBTTtLQUNqQixDQUFDLENBQUM7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsdUNBQXVDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDN0UsQ0FBQyxDQUFDLENBQUM7QUFFSCxJQUFJLENBQUMsMENBQTBDLEVBQUUsR0FBRyxFQUFFO0lBQ3BELE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO0lBRTFCLGlFQUFpRTtJQUNqRSxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNDLE1BQU0sT0FBTyxHQUFHLHNCQUFzQixDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztJQUV2RCxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFFcEYsOEZBQThGO0lBQzlGLFFBQVEsQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsa0JBQWtCLENBQUMsS0FBSyxFQUFFLGdCQUFnQixDQUFDLENBQUMsQ0FBQztBQUV6RyxDQUFDLENBQUMsQ0FBQztBQUVILElBQUksQ0FBQyx5Q0FBeUMsRUFBRSxHQUFHLEVBQUU7SUFDbkQsTUFBTSxLQUFLLEdBQUcsSUFBSSxtQkFBSyxFQUFFLENBQUM7SUFFMUIsaUVBQWlFO0lBQ2pFLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0MsTUFBTSxPQUFPLEdBQUcsc0JBQXNCLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBRXZELE1BQU0sR0FBRyxHQUFHLEdBQUcsRUFBRTtRQUNmLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDaEQsQ0FBQyxDQUFDO0lBRUYsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFlBQVksQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO0FBRWhFLENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLHdDQUF3QyxFQUFFLEdBQUcsRUFBRTtJQUNsRCxNQUFNLEtBQUssR0FBRyxJQUFJLG1CQUFLLEVBQUUsQ0FBQztJQUUxQixpRUFBaUU7SUFDakUsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzQyxNQUFNLE9BQU8sR0FBRyxzQkFBc0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFFdkQsUUFBUSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ25FLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFL0QsTUFBTSxDQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBZ0MsQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFFaEYsQ0FBQyxDQUFDLENBQUM7QUFFSCxJQUFJLENBQUMseUNBQXlDLEVBQUUsR0FBRyxFQUFFO0lBQ25ELE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO0lBRTFCLGlFQUFpRTtJQUNqRSxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNDLE1BQU0sT0FBTyxHQUFHLHNCQUFzQixDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN2RCxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFLG1CQUFtQixDQUFDLENBQUM7SUFFekUsUUFBUSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxFQUFFLFlBQVksRUFBRSxDQUFFLFFBQVEsQ0FBRSxFQUFFLENBQUMsQ0FBQztJQUM3RSxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBRS9ELE1BQU0sQ0FBRSxRQUFRLENBQUMsSUFBSSxDQUFDLFlBQWdDLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBRWpGLENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLG1DQUFtQyxFQUFFLEdBQUcsRUFBRTtJQUM3QyxNQUFNLEtBQUssR0FBRztRQUNaLGFBQWEsRUFBRTtZQUNiLGVBQWUsRUFBRSxDQUFFLE1BQU0sQ0FBQztTQUMzQjtLQUNGLENBQUM7SUFFRixNQUFNLEdBQUcsR0FBRyxHQUFHLEVBQUU7UUFDZixRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLENBQUMsQ0FBQztJQUVGLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxZQUFZLENBQUMsb0dBQW9HLENBQUMsQ0FBQztBQUNqSSxDQUFDLENBQUMsQ0FBQztBQUVILElBQUksQ0FBQywrQkFBK0IsRUFBRSxHQUFHLEVBQUU7SUFDekMsTUFBTSxLQUFLLEdBQUc7UUFDWix1QkFBdUIsRUFBRTtZQUN2QixTQUFTLEVBQUUsRUFBRTtTQUNkO0tBQ0YsQ0FBQztJQUVGLE1BQU0sR0FBRyxHQUFHLEdBQUcsRUFBRTtRQUNmLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEMsQ0FBQyxDQUFDO0lBRUYsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFlBQVksQ0FBQyxzSkFBc0osQ0FBQyxDQUFDO0lBRWpMLE1BQU0sSUFBSSxHQUFHLEdBQUcsRUFBRTtRQUNoQixRQUFRLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzdCLENBQUMsQ0FBQztJQUVGLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxZQUFZLENBQUMsc0pBQXNKLENBQUMsQ0FBQztBQUNwTCxDQUFDLENBQUMsQ0FBQztBQUVILElBQUksQ0FBQyx3Q0FBd0MsRUFBRSxHQUFHLEVBQUU7SUFDbEQsTUFBTSxLQUFLLEdBQUc7UUFDWix1QkFBdUIsRUFBRTtZQUN2QixTQUFTLEVBQUUsQ0FBRSxlQUFlLENBQUM7U0FDOUI7UUFDRCxXQUFXLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFO0tBQzdCLENBQUM7SUFFRixNQUFNLEdBQUcsR0FBRyxHQUFHLEVBQUU7UUFDZixRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLENBQUMsQ0FBQztJQUVGLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxZQUFZLENBQUMscUZBQXFGLENBQUMsQ0FBQztBQUNsSCxDQUFDLENBQUMsQ0FBQztBQUVILElBQUksQ0FBQyx3REFBd0QsRUFBRSxHQUFHLEVBQUU7SUFDbEUsTUFBTSxLQUFLLEdBQUc7UUFDWix1QkFBdUIsRUFBRTtZQUN2QixJQUFJLEVBQUUsYUFBYTtZQUNuQixTQUFTLEVBQUUsRUFBRztTQUNmO0tBQ0YsQ0FBQztJQUVGLE1BQU0sR0FBRyxHQUFHLEdBQUcsRUFBRTtRQUNmLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEMsQ0FBQyxDQUFDO0lBRUYsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFlBQVksQ0FBQyw2SEFBNkgsQ0FBQyxDQUFDO0FBQzFKLENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLHNEQUFzRCxFQUFFLEdBQUcsRUFBRTtJQUNoRSxNQUFNLEtBQUssR0FBRztRQUNaLHVCQUF1QixFQUFFO1lBQ3ZCLFNBQVMsRUFBRSxDQUFFLGFBQWEsQ0FBRTtTQUM3QjtRQUNELGFBQWEsRUFBRSxFQUFFLEdBQUcsRUFBRSxhQUFhLEVBQUU7S0FDdEMsQ0FBQztJQUVGLE1BQU0sR0FBRyxHQUFHLEdBQUcsRUFBRTtRQUNmLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEMsQ0FBQyxDQUFDO0lBRUYsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFlBQVksQ0FBQyxpRkFBaUYsQ0FBQyxDQUFDO0FBQzlHLENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLDZDQUE2QyxFQUFFLEdBQUcsRUFBRTtJQUN2RCxNQUFNLEtBQUssR0FBRztRQUNaLGlCQUFpQixFQUFFO1lBQ2pCLEdBQUcsRUFBRSxFQUFFLEdBQUcsRUFBRSxhQUFhLEVBQUU7U0FDNUI7S0FDRixDQUFDO0lBRUYsTUFBTSxHQUFHLEdBQUcsR0FBRyxFQUFFO1FBQ2YsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoQyxDQUFDLENBQUM7SUFFRixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsWUFBWSxDQUFDLGtGQUFrRixDQUFDLENBQUM7QUFDL0csQ0FBQyxDQUFDLENBQUM7QUFFSCxTQUFTLHNCQUFzQixDQUFDLEtBQVksRUFBRSxHQUFhO0lBQ3pELE9BQU8sSUFBSSxHQUFHLENBQUMsdUJBQXVCLENBQUMsS0FBSyxFQUFFLGVBQWUsRUFBRTtRQUM3RCxHQUFHO1FBQ0gsY0FBYyxFQUFFLElBQUk7UUFDcEIsZ0JBQWdCLEVBQUUsYUFBYTtLQUNoQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxLQUFZLEVBQUUsRUFBVTtJQUNsRCxPQUFPLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1FBQ3BDLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLFNBQVMsU0FBUyxDQUFDO1FBQ2xELE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVc7UUFDbkMsT0FBTyxFQUFFLGVBQWU7S0FDekIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsd0JBQXdCLENBQUMsS0FBWSxFQUFFLEVBQVUsRUFBRSxHQUFhO0lBQ3ZFLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUMsb0JBQW9CLENBQUMsS0FBSyxFQUMvQyxHQUFHLEVBQUUsU0FBUyxFQUNkLEdBQUcsRUFDSCxTQUFTLEVBQ1QseURBQXlELEVBQ3pELFFBQVEsQ0FBQyxDQUFDO0lBQ1osT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxLQUFZLEVBQUUsRUFBVSxFQUFFLEdBQWdDO0lBQ3BGLE9BQU8sSUFBSSxHQUFHLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtRQUM1QyxZQUFZLEVBQUUsR0FBRztRQUNqQixRQUFRLEVBQUUsR0FBRyxDQUFDLG1CQUFtQixDQUFDLElBQUk7S0FDdkMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogIENvcHlyaWdodCAyMDIyIEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIikuIFlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcbiAqICB3aXRoIHRoZSBMaWNlbnNlLiBBIGNvcHkgb2YgdGhlIExpY2Vuc2UgaXMgbG9jYXRlZCBhdFxuICpcbiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogIG9yIGluIHRoZSAnbGljZW5zZScgZmlsZSBhY2NvbXBhbnlpbmcgdGhpcyBmaWxlLiBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgb24gYW4gJ0FTIElTJyBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTXG4gKiAgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnNcbiAqICBhbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgU3RhY2sgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBlbGIgZnJvbSBcImF3cy1jZGstbGliL2F3cy1lbGFzdGljbG9hZGJhbGFuY2luZ3YyXCI7XG5pbXBvcnQgKiBhcyBsYW1iZGEgZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGFcIjtcbmltcG9ydCAqIGFzIGRlZmF1bHRzIGZyb20gJy4uL2luZGV4JztcbmltcG9ydCAqIGFzIGVjMiBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWMyJztcbmltcG9ydCAqIGFzIGVjcyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWNzJztcbmltcG9ydCAnQGF3cy1jZGsvYXNzZXJ0L2plc3QnO1xuXG50ZXN0KCdUZXN0IE9idGFpbkFsYiB3aXRoIGV4aXN0aW5nIEFMQicsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgLy8gQnVpbGQgVlBDXG4gIGNvbnN0IHZwYyA9IGRlZmF1bHRzLmJ1aWxkVnBjKHN0YWNrLCB7XG4gICAgZGVmYXVsdFZwY1Byb3BzOiBkZWZhdWx0cy5EZWZhdWx0UHVibGljUHJpdmF0ZVZwY1Byb3BzKCksXG4gIH0pO1xuXG4gIGNvbnN0IGV4aXN0aW5nTG9hZEJhbGFuY2VyID0gbmV3IGVsYi5BcHBsaWNhdGlvbkxvYWRCYWxhbmNlcihzdGFjaywgJ2xvYWQtYmFsYW5jZXInLCB7XG4gICAgdnBjLFxuICAgIGludGVybmV0RmFjaW5nOiB0cnVlLFxuICAgIGxvYWRCYWxhbmNlck5hbWU6ICd1bmlxdWUtbmFtZSdcbiAgfSk7XG5cbiAgZGVmYXVsdHMuT2J0YWluQWxiKHN0YWNrLCAndGVzdCcsIHZwYywgdHJ1ZSwgZXhpc3RpbmdMb2FkQmFsYW5jZXIpO1xuICBleHBlY3Qoc3RhY2spLnRvSGF2ZVJlc291cmNlTGlrZSgnQVdTOjpFbGFzdGljTG9hZEJhbGFuY2luZ1YyOjpMb2FkQmFsYW5jZXInLCB7XG4gICAgTmFtZTogXCJ1bmlxdWUtbmFtZVwiLFxuICB9KTtcbn0pO1xuXG50ZXN0KCdUZXN0IE9idGFpbkFsYiBmb3IgbmV3IEFMQiB3aXRoIHByb3ZpZGVkIHByb3BzJywgKCkgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayh1bmRlZmluZWQsIHVuZGVmaW5lZCwge1xuICAgIGVudjogeyBhY2NvdW50OiBcIjEyMzQ1Njc4OTAxMlwiLCByZWdpb246ICd1cy1lYXN0LTEnIH0sXG4gIH0pO1xuICAvLyBCdWlsZCBWUENcbiAgY29uc3QgdnBjID0gZGVmYXVsdHMuYnVpbGRWcGMoc3RhY2ssIHtcbiAgICBkZWZhdWx0VnBjUHJvcHM6IGRlZmF1bHRzLkRlZmF1bHRQdWJsaWNQcml2YXRlVnBjUHJvcHMoKSxcbiAgfSk7XG5cbiAgZGVmYXVsdHMuT2J0YWluQWxiKHN0YWNrLCAndGVzdCcsIHZwYywgdHJ1ZSwgdW5kZWZpbmVkLCB7XG4gICAgbG9hZEJhbGFuY2VyTmFtZTogJ25ldy1sb2FkYmFsYW5jZXInLFxuICAgIHZwYyxcbiAgICBpbnRlcm5ldEZhY2luZzogdHJ1ZVxuICB9KTtcbiAgZXhwZWN0KHN0YWNrKS50b0hhdmVSZXNvdXJjZUxpa2UoJ0FXUzo6RWxhc3RpY0xvYWRCYWxhbmNpbmdWMjo6TG9hZEJhbGFuY2VyJywge1xuICAgIE5hbWU6IFwibmV3LWxvYWRiYWxhbmNlclwiLFxuICAgIFNjaGVtZTogXCJpbnRlcm5ldC1mYWNpbmdcIixcbiAgfSk7XG59KTtcblxudGVzdCgnVGVzdCBPYnRhaW5BbGIgZm9yIG5ldyBBTEIgd2l0aCBkZWZhdWx0IHByb3BzJywgKCkgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayh1bmRlZmluZWQsIHVuZGVmaW5lZCwge1xuICAgIGVudjogeyBhY2NvdW50OiBcIjEyMzQ1Njc4OTAxMlwiLCByZWdpb246ICd1cy1lYXN0LTEnIH0sXG4gIH0pO1xuICAvLyBCdWlsZCBWUENcbiAgY29uc3QgdnBjID0gZGVmYXVsdHMuYnVpbGRWcGMoc3RhY2ssIHtcbiAgICBkZWZhdWx0VnBjUHJvcHM6IGRlZmF1bHRzLkRlZmF1bHRQdWJsaWNQcml2YXRlVnBjUHJvcHMoKSxcbiAgfSk7XG5cbiAgZGVmYXVsdHMuT2J0YWluQWxiKHN0YWNrLCAndGVzdCcsIHZwYywgZmFsc2UpO1xuICBleHBlY3Qoc3RhY2spLnRvSGF2ZVJlc291cmNlTGlrZSgnQVdTOjpFbGFzdGljTG9hZEJhbGFuY2luZ1YyOjpMb2FkQmFsYW5jZXInLCB7XG4gICAgU2NoZW1lOiBcImludGVybmFsXCIsXG4gIH0pO1xufSk7XG5cbnRlc3QoJ1Rlc3Qgd2l0aCBjdXN0b20gbG9nZ2luZyBidWNrZXQgcHJvcHMnLCAoKSA9PiB7XG4gIC8vIENyZWF0aW5nIEFMQiBsb2dnaW5nIHJlcXVpcmVzIGEgcmVnaW9uIGFuZCBhY2NvdW50IChidXRcbiAgLy8gdGhlc2UgY2FuIGJlIGZha2UgaW4gdW5pdCB0ZXN0cylcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sodW5kZWZpbmVkLCB1bmRlZmluZWQsIHtcbiAgICBlbnY6IHsgYWNjb3VudDogXCIxMjM0NTY3ODkwMTJcIiwgcmVnaW9uOiAndXMtZWFzdC0xJyB9LFxuICB9KTtcbiAgLy8gQnVpbGQgVlBDXG4gIGNvbnN0IHZwYyA9IGRlZmF1bHRzLmJ1aWxkVnBjKHN0YWNrLCB7XG4gICAgZGVmYXVsdFZwY1Byb3BzOiBkZWZhdWx0cy5EZWZhdWx0UHVibGljUHJpdmF0ZVZwY1Byb3BzKCksXG4gIH0pO1xuXG4gIGNvbnN0IHRlc3ROYW1lID0gJ3Rlc3QtbmFtZSc7XG5cbiAgZGVmYXVsdHMuT2J0YWluQWxiKHN0YWNrLCAndGVzdCcsIHZwYywgZmFsc2UsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0cnVlLCB7IGJ1Y2tldE5hbWU6IHRlc3ROYW1lIH0pO1xuICBleHBlY3Qoc3RhY2spLnRvSGF2ZVJlc291cmNlTGlrZSgnQVdTOjpTMzo6QnVja2V0Jywge1xuICAgIEJ1Y2tldE5hbWU6IHRlc3ROYW1lXG4gIH0pO1xufSk7XG5cbnRlc3QoJ1Rlc3Qgd2l0aCBubyBsb2dnaW5nJywgKCkgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAvLyBCdWlsZCBWUENcbiAgY29uc3QgdnBjID0gZGVmYXVsdHMuYnVpbGRWcGMoc3RhY2ssIHtcbiAgICBkZWZhdWx0VnBjUHJvcHM6IGRlZmF1bHRzLkRlZmF1bHRQdWJsaWNQcml2YXRlVnBjUHJvcHMoKSxcbiAgfSk7XG5cbiAgZGVmYXVsdHMuT2J0YWluQWxiKHN0YWNrLCAndGVzdCcsIHZwYywgZmFsc2UsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBmYWxzZSk7XG4gIGV4cGVjdChzdGFjaykubm90LnRvSGF2ZVJlc291cmNlTGlrZSgnQVdTOjpTMzo6QnVja2V0Jywge30pO1xufSk7XG5cbnRlc3QoJ1Rlc3QgYWRkIHNpbmdsZSBsYW1iZGEgdGFyZ2V0IGdyb3VwIHdpdGggbm8gY3VzdG9taXphdGlvbicsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcblxuICAvLyBTZXQgdXAgdGVzdCBmcmFtZXdvcmsgaW5kZXBlbmRlbnQgb2Ygb3VyIGNvZGUgZm9yIHVuaXQgdGVzdGluZ1xuICBjb25zdCB0ZXN0RnVuY3Rpb24gPSBDcmVhdGVUZXN0RnVuY3Rpb24oc3RhY2ssICd0ZXN0LWZ1bmN0aW9uJyk7XG4gIGNvbnN0IHRlc3RWcGMgPSBkZWZhdWx0cy5nZXRUZXN0VnBjKHN0YWNrKTtcbiAgY29uc3QgdGVzdEFsYiA9IENyZWF0ZVRlc3RMb2FkQmFsYW5jZXIoc3RhY2ssIHRlc3RWcGMpO1xuICBjb25zdCB0ZXN0TGlzdGVuZXIgPSBDcmVhdGVUZXN0TGlzdGVuZXIoc3RhY2ssICd0ZXN0LWxpc3RlbmVyJywgdGVzdEFsYik7XG5cbiAgLy8gVGhpcyBpcyB0aGUgY29kZSB3ZSdyZSB0ZXN0aW5nXG4gIGRlZmF1bHRzLkFkZExhbWJkYVRhcmdldChcbiAgICBzdGFjayxcbiAgICAndGVzdC1sYW1iZGEtdGFyZ2V0JyxcbiAgICB0ZXN0TGlzdGVuZXIsXG4gICAgdGVzdEZ1bmN0aW9uLFxuICApO1xuXG4gIGV4cGVjdChzdGFjaykudG9IYXZlUmVzb3VyY2VMaWtlKCdBV1M6OkVsYXN0aWNMb2FkQmFsYW5jaW5nVjI6Okxpc3RlbmVyJywge1xuICAgIERlZmF1bHRBY3Rpb25zOiBbXG4gICAgICB7XG4gICAgICAgIFRhcmdldEdyb3VwQXJuOiB7XG4gICAgICAgICAgUmVmOiBcInRlc3RsYW1iZGF0YXJnZXR0ZzdFNUMzMkY0XCJcbiAgICAgICAgfSxcbiAgICAgICAgVHlwZTogXCJmb3J3YXJkXCJcbiAgICAgIH1cbiAgICBdLFxuICB9KTtcbiAgZXhwZWN0KHN0YWNrKS50b0hhdmVSZXNvdXJjZUxpa2UoJ0FXUzo6RWxhc3RpY0xvYWRCYWxhbmNpbmdWMjo6VGFyZ2V0R3JvdXAnLCB7XG4gICAgVGFyZ2V0VHlwZTogXCJsYW1iZGFcIixcbiAgfSk7XG5cbn0pO1xuXG50ZXN0KCdUZXN0IGFkZCBzaW5nbGUgbGFtYmRhIHRhcmdldCBncm91cCB3aXRoIHRhcmdldCBncm91cCBwcm9wcycsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcblxuICAvLyBTZXQgdXAgdGVzdCBmcmFtZXdvcmsgaW5kZXBlbmRlbnQgb2Ygb3VyIGNvZGUgZm9yIHVuaXQgdGVzdGluZ1xuICBjb25zdCB0ZXN0RnVuY3Rpb24gPSBDcmVhdGVUZXN0RnVuY3Rpb24oc3RhY2ssICd0ZXN0LWZ1bmN0aW9uJyk7XG4gIGNvbnN0IHRlc3RWcGMgPSBkZWZhdWx0cy5nZXRUZXN0VnBjKHN0YWNrKTtcbiAgY29uc3QgdGVzdEFsYiA9IENyZWF0ZVRlc3RMb2FkQmFsYW5jZXIoc3RhY2ssIHRlc3RWcGMpO1xuICBjb25zdCB0ZXN0TGlzdGVuZXIgPSBDcmVhdGVUZXN0TGlzdGVuZXIoc3RhY2ssICd0ZXN0LWxpc3RlbmVyJywgdGVzdEFsYik7XG4gIGNvbnN0IHRhcmdldEdyb3VwTmFtZSA9ICd0ZXN0LWdyb3VwJztcblxuICAvLyBUaGlzIGlzIHRoZSBjb2RlIHdlJ3JlIHRlc3RpbmdcbiAgZGVmYXVsdHMuQWRkTGFtYmRhVGFyZ2V0KFxuICAgIHN0YWNrLFxuICAgICd0ZXN0LWxhbWJkYS10YXJnZXQnLFxuICAgIHRlc3RMaXN0ZW5lcixcbiAgICB0ZXN0RnVuY3Rpb24sXG4gICAgdW5kZWZpbmVkLFxuICAgIHsgdGFyZ2V0R3JvdXBOYW1lIH0sXG4gICk7XG5cbiAgZXhwZWN0KHN0YWNrKS50b0hhdmVSZXNvdXJjZUxpa2UoJ0FXUzo6RWxhc3RpY0xvYWRCYWxhbmNpbmdWMjo6VGFyZ2V0R3JvdXAnLCB7XG4gICAgVGFyZ2V0VHlwZTogXCJsYW1iZGFcIixcbiAgICBOYW1lOiB0YXJnZXRHcm91cE5hbWUsXG4gIH0pO1xuXG59KTtcblxudGVzdCgnVGVzdCBhZGQgcnVsZSBwcm9wcyBmb3Igc2Vjb25kIGxhbWJkYSB0YXJnZXQgZ3JvdXAnLCAoKSA9PiB7XG4gIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG5cbiAgLy8gU2V0IHVwIHRlc3QgZnJhbWV3b3JrIGluZGVwZW5kZW50IG9mIG91ciBjb2RlIGZvciB1bml0IHRlc3RpbmdcbiAgY29uc3QgdGVzdEZ1bmN0aW9uID0gQ3JlYXRlVGVzdEZ1bmN0aW9uKHN0YWNrLCAndGVzdC1mdW5jdGlvbicpO1xuICBjb25zdCB0ZXN0VnBjID0gZGVmYXVsdHMuZ2V0VGVzdFZwYyhzdGFjayk7XG4gIGNvbnN0IHRlc3RBbGIgPSBDcmVhdGVUZXN0TG9hZEJhbGFuY2VyKHN0YWNrLCB0ZXN0VnBjKTtcbiAgY29uc3QgdGVzdExpc3RlbmVyID0gQ3JlYXRlVGVzdExpc3RlbmVyKHN0YWNrLCAndGVzdC1saXN0ZW5lcicsIHRlc3RBbGIpO1xuICBjb25zdCB0YXJnZXRHcm91cE5hbWUgPSAndGVzdC1ncm91cCc7XG4gIGNvbnN0IHBhdGhQYXR0ZXJuID0gJyphZG1pbionO1xuXG4gIGRlZmF1bHRzLkFkZExhbWJkYVRhcmdldChcbiAgICBzdGFjayxcbiAgICAndGVzdC1sYW1iZGEtdGFyZ2V0JyxcbiAgICB0ZXN0TGlzdGVuZXIsXG4gICAgdGVzdEZ1bmN0aW9uLFxuICAgIHVuZGVmaW5lZCxcbiAgICB7IHRhcmdldEdyb3VwTmFtZSB9LFxuICApO1xuXG4gIC8vIFRoaXMgaXMgdGhlIGNvZGUgd2UncmUgdGVzdGluZ1xuICBjb25zdCBydWxlUHJvcHMgPSB7XG4gICAgY29uZGl0aW9uczogW2VsYi5MaXN0ZW5lckNvbmRpdGlvbi5wYXRoUGF0dGVybnMoW3BhdGhQYXR0ZXJuXSldLFxuICAgIHByaW9yaXR5OiAxMFxuICB9O1xuICBkZWZhdWx0cy5BZGRMYW1iZGFUYXJnZXQoXG4gICAgc3RhY2ssXG4gICAgJ3Rlc3Qtc2Vjb25kLWxhbWJkYS10YXJnZXQnLFxuICAgIHRlc3RMaXN0ZW5lcixcbiAgICB0ZXN0RnVuY3Rpb24sXG4gICAgcnVsZVByb3BzLFxuICAgIHsgdGFyZ2V0R3JvdXBOYW1lIH0sXG4gICk7XG5cbiAgZXhwZWN0KHN0YWNrKS50b0NvdW50UmVzb3VyY2VzKCdBV1M6OkVsYXN0aWNMb2FkQmFsYW5jaW5nVjI6OlRhcmdldEdyb3VwJywgMik7XG4gIGV4cGVjdChzdGFjaykudG9IYXZlUmVzb3VyY2VMaWtlKCdBV1M6OkVsYXN0aWNMb2FkQmFsYW5jaW5nVjI6Okxpc3RlbmVyUnVsZScsIHtcbiAgICBDb25kaXRpb25zOiBbXG4gICAgICB7XG4gICAgICAgIEZpZWxkOiBcInBhdGgtcGF0dGVyblwiLFxuICAgICAgICBQYXRoUGF0dGVybkNvbmZpZzoge1xuICAgICAgICAgIFZhbHVlczogW1xuICAgICAgICAgICAgcGF0aFBhdHRlcm5cbiAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICBdXG4gIH0pO1xuXG59KTtcblxudGVzdCgnVGVzdCBhZGQgc2luZ2xlIGZhcmdhdGUgdGFyZ2V0IHdpdGggbm8gY3VzdG9taXphdGlvbicsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcblxuICAvLyBTZXQgdXAgdGVzdCBmcmFtZXdvcmsgaW5kZXBlbmRlbnQgb2Ygb3VyIGNvZGUgZm9yIHVuaXQgdGVzdGluZ1xuICBjb25zdCB0ZXN0VnBjID0gZGVmYXVsdHMuZ2V0VGVzdFZwYyhzdGFjayk7XG4gIGNvbnN0IHRlc3RTZXJ2aWNlID0gQ3JlYXRlVGVzdEZhcmdhdGVTZXJ2aWNlKHN0YWNrLCAndGVzdC1zZXJ2aWNlJywgdGVzdFZwYyk7XG4gIGNvbnN0IHRlc3RBbGIgPSBDcmVhdGVUZXN0TG9hZEJhbGFuY2VyKHN0YWNrLCB0ZXN0VnBjKTtcbiAgY29uc3QgdGVzdExpc3RlbmVyID0gQ3JlYXRlVGVzdExpc3RlbmVyKHN0YWNrLCAndGVzdC1saXN0ZW5lcicsIHRlc3RBbGIpO1xuXG4gIC8vIFRoaXMgaXMgdGhlIGNvZGUgd2UncmUgdGVzdGluZ1xuICBkZWZhdWx0cy5BZGRGYXJnYXRlVGFyZ2V0KFxuICAgIHN0YWNrLFxuICAgICd0ZXN0LWZhcmdhdGUtdGFyZ2V0JyxcbiAgICB0ZXN0TGlzdGVuZXIsXG4gICAgdGVzdFNlcnZpY2UsXG4gICAgdW5kZWZpbmVkLFxuICAgIHtcbiAgICAgIHZwYzogdGVzdFZwYyxcbiAgICAgIHByb3RvY29sOiBlbGIuQXBwbGljYXRpb25Qcm90b2NvbC5IVFRQXG4gICAgfVxuICApO1xuXG4gIGV4cGVjdChzdGFjaykudG9IYXZlUmVzb3VyY2VMaWtlKCdBV1M6OkVsYXN0aWNMb2FkQmFsYW5jaW5nVjI6Okxpc3RlbmVyJywge1xuICAgIERlZmF1bHRBY3Rpb25zOiBbXG4gICAgICB7XG4gICAgICAgIFRhcmdldEdyb3VwQXJuOiB7XG4gICAgICAgICAgUmVmOiBcInRlc3RmYXJnYXRldGFyZ2V0dGcwMUZGNUFBM1wiXG4gICAgICAgIH0sXG4gICAgICAgIFR5cGU6IFwiZm9yd2FyZFwiXG4gICAgICB9XG4gICAgXSxcbiAgfSk7XG4gIGV4cGVjdChzdGFjaykudG9IYXZlUmVzb3VyY2VMaWtlKCdBV1M6OkVsYXN0aWNMb2FkQmFsYW5jaW5nVjI6OlRhcmdldEdyb3VwJywge1xuICAgIFRhcmdldFR5cGU6IFwiaXBcIixcbiAgfSk7XG5cbn0pO1xuXG50ZXN0KCdUZXN0IGFkZCB0d28gZmFyZ2F0ZSB0YXJnZXRzIHdpdGggcnVsZXMnLCAoKSA9PiB7XG4gIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG5cbiAgLy8gU2V0IHVwIHRlc3QgZnJhbWV3b3JrIGluZGVwZW5kZW50IG9mIG91ciBjb2RlIGZvciB1bml0IHRlc3RpbmdcbiAgY29uc3QgdGVzdFZwYyA9IGRlZmF1bHRzLmdldFRlc3RWcGMoc3RhY2spO1xuICBjb25zdCB0ZXN0U2VydmljZSA9IENyZWF0ZVRlc3RGYXJnYXRlU2VydmljZShzdGFjaywgJ3Rlc3Qtc2VydmljZScsIHRlc3RWcGMpO1xuICBjb25zdCB0ZXN0QWxiID0gQ3JlYXRlVGVzdExvYWRCYWxhbmNlcihzdGFjaywgdGVzdFZwYyk7XG4gIGNvbnN0IHRlc3RMaXN0ZW5lciA9IENyZWF0ZVRlc3RMaXN0ZW5lcihzdGFjaywgJ3Rlc3QtbGlzdGVuZXInLCB0ZXN0QWxiKTtcbiAgY29uc3QgcGF0aFBhdHRlcm4gPSAnKmFkbWluKic7XG5cbiAgZGVmYXVsdHMuQWRkRmFyZ2F0ZVRhcmdldChcbiAgICBzdGFjayxcbiAgICAndGVzdC1mYXJnYXRlLXRhcmdldCcsXG4gICAgdGVzdExpc3RlbmVyLFxuICAgIHRlc3RTZXJ2aWNlLFxuICAgIHVuZGVmaW5lZCxcbiAgICB7XG4gICAgICB2cGM6IHRlc3RWcGMsXG4gICAgICBwcm90b2NvbDogZWxiLkFwcGxpY2F0aW9uUHJvdG9jb2wuSFRUUFxuICAgIH1cbiAgKTtcblxuICAvLyBUaGlzIGlzIHRoZSBjb2RlIHdlJ3JlIHRlc3RpbmdcbiAgY29uc3QgcnVsZVByb3BzID0ge1xuICAgIGNvbmRpdGlvbnM6IFtlbGIuTGlzdGVuZXJDb25kaXRpb24ucGF0aFBhdHRlcm5zKFtwYXRoUGF0dGVybl0pXSxcbiAgICBwcmlvcml0eTogMTBcbiAgfTtcbiAgZGVmYXVsdHMuQWRkRmFyZ2F0ZVRhcmdldChcbiAgICBzdGFjayxcbiAgICAndGVzdC1zZWNvbmQtZmFyZ2F0ZS10YXJnZXQnLFxuICAgIHRlc3RMaXN0ZW5lcixcbiAgICB0ZXN0U2VydmljZSxcbiAgICBydWxlUHJvcHMsXG4gICAge1xuICAgICAgdnBjOiB0ZXN0VnBjLFxuICAgICAgcHJvdG9jb2w6IGVsYi5BcHBsaWNhdGlvblByb3RvY29sLkhUVFBcbiAgICB9XG4gICk7XG5cbiAgZXhwZWN0KHN0YWNrKS50b0NvdW50UmVzb3VyY2VzKCdBV1M6OkVsYXN0aWNMb2FkQmFsYW5jaW5nVjI6OlRhcmdldEdyb3VwJywgMik7XG4gIGV4cGVjdChzdGFjaykudG9IYXZlUmVzb3VyY2VMaWtlKCdBV1M6OkVsYXN0aWNMb2FkQmFsYW5jaW5nVjI6Okxpc3RlbmVyUnVsZScsIHtcbiAgICBDb25kaXRpb25zOiBbXG4gICAgICB7XG4gICAgICAgIEZpZWxkOiBcInBhdGgtcGF0dGVyblwiLFxuICAgICAgICBQYXRoUGF0dGVybkNvbmZpZzoge1xuICAgICAgICAgIFZhbHVlczogW1xuICAgICAgICAgICAgcGF0aFBhdHRlcm5cbiAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICBdXG4gIH0pO1xufSk7XG5cbnRlc3QoJ1Rlc3QgYWRkaW5nIGEgbGlzdGVuZXIgd2l0aCBkZWZhdWx0cycsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcblxuICAvLyBTZXQgdXAgdGVzdCBmcmFtZXdvcmsgaW5kZXBlbmRlbnQgb2Ygb3VyIGNvZGUgZm9yIHVuaXQgdGVzdGluZ1xuICBjb25zdCB0ZXN0VnBjID0gZGVmYXVsdHMuZ2V0VGVzdFZwYyhzdGFjayk7XG4gIGNvbnN0IHRlc3RBbGIgPSBDcmVhdGVUZXN0TG9hZEJhbGFuY2VyKHN0YWNrLCB0ZXN0VnBjKTtcbiAgY29uc3QgdGVzdENlcnQgPSBkZWZhdWx0cy5nZXRGYWtlQ2VydGlmaWNhdGUoc3RhY2ssICdub3QtcmVhbGx5LWEtY2VydCcpO1xuXG4gIGNvbnN0IGxpc3RlbmVyID0gZGVmYXVsdHMuQWRkTGlzdGVuZXIoc3RhY2ssICd0ZXN0JywgdGVzdEFsYiwgeyBjZXJ0aWZpY2F0ZXM6IFsgdGVzdENlcnQgXSB9KTtcblxuICAvLyAgTmVlZCB0byBhZGQgYSB0YXJnZXQgYmVjYXVzZSBhIGxpc3RlbmVyIGlzIG5vdCBhbGxvd2VkIHRvIGV4aXN0IHdpdGhvdXQgYSB0YXJnZXQgb3IgYWN0aW9uXG4gIGRlZmF1bHRzLkFkZExhbWJkYVRhcmdldChzdGFjaywgJ2R1bW15LXRhcmdldCcsIGxpc3RlbmVyLCBDcmVhdGVUZXN0RnVuY3Rpb24oc3RhY2ssICdkdW1teS1mdW5jdGlvbicpKTtcblxuICAvLyBUaGlzIHNob3VsZCBjcmVhdGUgMiBsaXN0ZW5lcnMsIEhUVFBTIHBsdXMgcmVkaXJlY3Qgb2YgSFRUUFxuICBleHBlY3Qoc3RhY2spLnRvSGF2ZVJlc291cmNlTGlrZSgnQVdTOjpFbGFzdGljTG9hZEJhbGFuY2luZ1YyOjpMaXN0ZW5lcicsIHtcbiAgICBQcm90b2NvbDogJ0hUVFBTJyxcbiAgfSk7XG5cbiAgZXhwZWN0KHN0YWNrKS50b0hhdmVSZXNvdXJjZUxpa2UoJ0FXUzo6RWxhc3RpY0xvYWRCYWxhbmNpbmdWMjo6TGlzdGVuZXInLCB7XG4gICAgUHJvdG9jb2w6ICdIVFRQJyxcbiAgfSk7XG59KTtcblxudGVzdCgnVGVzdCBhZGRpbmcgYW4gSFRUUFMgbGlzdGVuZXIgd2l0aCBubyBjZXJ0IChlcnJvciknLCAoKSA9PiB7XG4gIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG5cbiAgLy8gU2V0IHVwIHRlc3QgZnJhbWV3b3JrIGluZGVwZW5kZW50IG9mIG91ciBjb2RlIGZvciB1bml0IHRlc3RpbmdcbiAgY29uc3QgdGVzdFZwYyA9IGRlZmF1bHRzLmdldFRlc3RWcGMoc3RhY2spO1xuICBjb25zdCB0ZXN0QWxiID0gQ3JlYXRlVGVzdExvYWRCYWxhbmNlcihzdGFjaywgdGVzdFZwYyk7XG5cbiAgY29uc3QgYXBwID0gKCkgPT4ge1xuICAgIGRlZmF1bHRzLkFkZExpc3RlbmVyKHN0YWNrLCAndGVzdCcsIHRlc3RBbGIsIHsgfSk7XG4gIH07XG5cbiAgZXhwZWN0KGFwcCkudG9UaHJvd0Vycm9yKCdBIGxpc3RlbmVyIHVzaW5nIEhUVFBTIHByb3RvY29sIHJlcXVpcmVzIGEgY2VydGlmaWNhdGUnKTtcbn0pO1xuXG50ZXN0KCdUZXN0IGFkZGluZyBhbiBIVFRQIGxpc3RlbmVyIHdpdGggYSBjZXJ0IChlcnJvciknLCAoKSA9PiB7XG4gIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG5cbiAgLy8gU2V0IHVwIHRlc3QgZnJhbWV3b3JrIGluZGVwZW5kZW50IG9mIG91ciBjb2RlIGZvciB1bml0IHRlc3RpbmdcbiAgY29uc3QgdGVzdFZwYyA9IGRlZmF1bHRzLmdldFRlc3RWcGMoc3RhY2spO1xuICBjb25zdCB0ZXN0QWxiID0gQ3JlYXRlVGVzdExvYWRCYWxhbmNlcihzdGFjaywgdGVzdFZwYyk7XG4gIGNvbnN0IHRlc3RDZXJ0ID0gZGVmYXVsdHMuZ2V0RmFrZUNlcnRpZmljYXRlKHN0YWNrLCAnbm90LXJlYWxseS1hLWNlcnQnKTtcblxuICBjb25zdCBhcHAgPSAoKSA9PiB7XG4gICAgZGVmYXVsdHMuQWRkTGlzdGVuZXIoc3RhY2ssICd0ZXN0JywgdGVzdEFsYiwgeyBwcm90b2NvbDogJ0hUVFAnLCBjZXJ0aWZpY2F0ZXM6IFsgdGVzdENlcnQgXSB9KTtcbiAgfTtcblxuICBleHBlY3QoYXBwKS50b1Rocm93RXJyb3IoJ0hUVFAgbGlzdGVuZXJzIGNhbm5vdCB1c2UgYSBjZXJ0aWZpY2F0ZScpO1xufSk7XG5cbnRlc3QoJ1Rlc3QgYWRkaW5nIGEgSFRUUCBsaXN0ZW5lcicsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcblxuICAvLyBTZXQgdXAgdGVzdCBmcmFtZXdvcmsgaW5kZXBlbmRlbnQgb2Ygb3VyIGNvZGUgZm9yIHVuaXQgdGVzdGluZ1xuICBjb25zdCB0ZXN0VnBjID0gZGVmYXVsdHMuZ2V0VGVzdFZwYyhzdGFjayk7XG4gIGNvbnN0IHRlc3RBbGIgPSBDcmVhdGVUZXN0TG9hZEJhbGFuY2VyKHN0YWNrLCB0ZXN0VnBjKTtcblxuICBjb25zdCBsaXN0ZW5lciA9IGRlZmF1bHRzLkFkZExpc3RlbmVyKHN0YWNrLCAndGVzdCcsIHRlc3RBbGIsIHsgcHJvdG9jb2w6ICdIVFRQJyB9KTtcblxuICAvLyAgTmVlZCB0byBhZGQgYSB0YXJnZXQgYmVjYXVzZSBhIGxpc3RlbmVyIGlzIG5vdCBhbGxvd2VkIHRvIGV4aXN0IHdpdGhvdXQgYSB0YXJnZXQgb3IgYWN0aW9uXG4gIGRlZmF1bHRzLkFkZExhbWJkYVRhcmdldChzdGFjaywgJ2R1bW15LXRhcmdldCcsIGxpc3RlbmVyLCBDcmVhdGVUZXN0RnVuY3Rpb24oc3RhY2ssICdkdW1teS1mdW5jdGlvbicpKTtcblxuICBleHBlY3Qoc3RhY2spLnRvSGF2ZVJlc291cmNlTGlrZSgnQVdTOjpFbGFzdGljTG9hZEJhbGFuY2luZ1YyOjpMaXN0ZW5lcicsIHtcbiAgICBQcm90b2NvbDogJ0hUVFAnLFxuICB9KTtcbiAgZXhwZWN0KHN0YWNrKS50b0NvdW50UmVzb3VyY2VzKCdBV1M6OkVsYXN0aWNMb2FkQmFsYW5jaW5nVjI6Okxpc3RlbmVyJywgMSk7XG59KTtcblxudGVzdCgnVGVzdCBzZW5kaW5nIGN1c3RvbSBsb2dnaW5nIGJ1Y2tldCBwcm9wcycsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcblxuICAvLyBTZXQgdXAgdGVzdCBmcmFtZXdvcmsgaW5kZXBlbmRlbnQgb2Ygb3VyIGNvZGUgZm9yIHVuaXQgdGVzdGluZ1xuICBjb25zdCB0ZXN0VnBjID0gZGVmYXVsdHMuZ2V0VGVzdFZwYyhzdGFjayk7XG4gIGNvbnN0IHRlc3RBbGIgPSBDcmVhdGVUZXN0TG9hZEJhbGFuY2VyKHN0YWNrLCB0ZXN0VnBjKTtcblxuICBjb25zdCBsaXN0ZW5lciA9IGRlZmF1bHRzLkFkZExpc3RlbmVyKHN0YWNrLCAndGVzdCcsIHRlc3RBbGIsIHsgcHJvdG9jb2w6ICdIVFRQJyB9KTtcblxuICAvLyAgTmVlZCB0byBhZGQgYSB0YXJnZXQgYmVjYXVzZSBhIGxpc3RlbmVyIGlzIG5vdCBhbGxvd2VkIHRvIGV4aXN0IHdpdGhvdXQgYSB0YXJnZXQgb3IgYWN0aW9uXG4gIGRlZmF1bHRzLkFkZExhbWJkYVRhcmdldChzdGFjaywgJ2R1bW15LXRhcmdldCcsIGxpc3RlbmVyLCBDcmVhdGVUZXN0RnVuY3Rpb24oc3RhY2ssICdkdW1teS1mdW5jdGlvbicpKTtcblxufSk7XG5cbnRlc3QoJ1Rlc3QgR2V0QWN0aXZlTGlzdGVuZXIgd2l0aCAwIGxpc3RlbmVycycsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcblxuICAvLyBTZXQgdXAgdGVzdCBmcmFtZXdvcmsgaW5kZXBlbmRlbnQgb2Ygb3VyIGNvZGUgZm9yIHVuaXQgdGVzdGluZ1xuICBjb25zdCB0ZXN0VnBjID0gZGVmYXVsdHMuZ2V0VGVzdFZwYyhzdGFjayk7XG4gIGNvbnN0IHRlc3RBbGIgPSBDcmVhdGVUZXN0TG9hZEJhbGFuY2VyKHN0YWNrLCB0ZXN0VnBjKTtcblxuICBjb25zdCBhcHAgPSAoKSA9PiB7XG4gICAgZGVmYXVsdHMuR2V0QWN0aXZlTGlzdGVuZXIodGVzdEFsYi5saXN0ZW5lcnMpO1xuICB9O1xuXG4gIGV4cGVjdChhcHApLnRvVGhyb3dFcnJvcignVGhlcmUgYXJlIG5vIGxpc3RlbmVycyBpbiB0aGUgQUxCJyk7XG5cbn0pO1xuXG50ZXN0KCdUZXN0IEdldEFjdGl2ZUxpc3RlbmVyIHdpdGggMSBsaXN0ZW5lcicsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcblxuICAvLyBTZXQgdXAgdGVzdCBmcmFtZXdvcmsgaW5kZXBlbmRlbnQgb2Ygb3VyIGNvZGUgZm9yIHVuaXQgdGVzdGluZ1xuICBjb25zdCB0ZXN0VnBjID0gZGVmYXVsdHMuZ2V0VGVzdFZwYyhzdGFjayk7XG4gIGNvbnN0IHRlc3RBbGIgPSBDcmVhdGVUZXN0TG9hZEJhbGFuY2VyKHN0YWNrLCB0ZXN0VnBjKTtcblxuICBkZWZhdWx0cy5BZGRMaXN0ZW5lcihzdGFjaywgJ3Rlc3QnLCB0ZXN0QWxiLCB7IHByb3RvY29sOiAnSFRUUCcgfSk7XG4gIGNvbnN0IGxpc3RlbmVyID0gZGVmYXVsdHMuR2V0QWN0aXZlTGlzdGVuZXIodGVzdEFsYi5saXN0ZW5lcnMpO1xuXG4gIGV4cGVjdCgobGlzdGVuZXIubm9kZS5kZWZhdWx0Q2hpbGQgYXMgZWxiLkNmbkxpc3RlbmVyKS5wcm90b2NvbCkudG9CZSgnSFRUUCcpO1xuXG59KTtcblxudGVzdCgnVGVzdCBHZXRBY3RpdmVMaXN0ZW5lciB3aXRoIDIgbGlzdGVuZXJzJywgKCkgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuXG4gIC8vIFNldCB1cCB0ZXN0IGZyYW1ld29yayBpbmRlcGVuZGVudCBvZiBvdXIgY29kZSBmb3IgdW5pdCB0ZXN0aW5nXG4gIGNvbnN0IHRlc3RWcGMgPSBkZWZhdWx0cy5nZXRUZXN0VnBjKHN0YWNrKTtcbiAgY29uc3QgdGVzdEFsYiA9IENyZWF0ZVRlc3RMb2FkQmFsYW5jZXIoc3RhY2ssIHRlc3RWcGMpO1xuICBjb25zdCB0ZXN0Q2VydCA9IGRlZmF1bHRzLmdldEZha2VDZXJ0aWZpY2F0ZShzdGFjaywgJ25vdC1yZWFsbHktYS1jZXJ0Jyk7XG5cbiAgZGVmYXVsdHMuQWRkTGlzdGVuZXIoc3RhY2ssICd0ZXN0JywgdGVzdEFsYiwgeyBjZXJ0aWZpY2F0ZXM6IFsgdGVzdENlcnQgXSB9KTtcbiAgY29uc3QgbGlzdGVuZXIgPSBkZWZhdWx0cy5HZXRBY3RpdmVMaXN0ZW5lcih0ZXN0QWxiLmxpc3RlbmVycyk7XG5cbiAgZXhwZWN0KChsaXN0ZW5lci5ub2RlLmRlZmF1bHRDaGlsZCBhcyBlbGIuQ2ZuTGlzdGVuZXIpLnByb3RvY29sKS50b0JlKCdIVFRQUycpO1xuXG59KTtcblxudGVzdCgnVGVzdCB1c2Ugb2YgY2VydGlmaWNhdGVBcm5zIGVycm9yJywgKCkgPT4ge1xuICBjb25zdCBwcm9wcyA9IHtcbiAgICBsaXN0ZW5lclByb3BzOiB7XG4gICAgICBjZXJ0aWZpY2F0ZUFybnM6IFsgJ2FybjEnXSxcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgYXBwID0gKCkgPT4ge1xuICAgIGRlZmF1bHRzLkNoZWNrQWxiUHJvcHMocHJvcHMpO1xuICB9O1xuXG4gIGV4cGVjdChhcHApLnRvVGhyb3dFcnJvcihcImNlcnRpZmljYXRlQXJucyBpcyBkZXByZWNhdGVkLiBQbGVhc2Ugc3VwcGx5IGNlcnRpZmljYXRlcyB1c2luZyBwcm9wcy5saXN0ZW5lclByb3BzLmNlcnRpZmljYXRlc1xcblwiKTtcbn0pO1xuXG50ZXN0KCdUZXN0IGJhZCBmaXJzdCBsaXN0ZW5lciBlcnJvcicsICgpID0+IHtcbiAgY29uc3QgcHJvcHMgPSB7XG4gICAgZXhpc3RpbmdMb2FkQmFsYW5jZXJPYmo6IHtcbiAgICAgIGxpc3RlbmVyczogW10sXG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGFwcCA9ICgpID0+IHtcbiAgICBkZWZhdWx0cy5DaGVja0FsYlByb3BzKHByb3BzKTtcbiAgfTtcblxuICBleHBlY3QoYXBwKS50b1Rocm93RXJyb3IoXCJXaGVuIGFkZGluZyB0aGUgZmlyc3QgbGlzdGVuZXIgYW5kIHRhcmdldCB0byBhIGxvYWQgYmFsYW5jZXIsIGxpc3RlbmVyUHJvcHMgbXVzdCBiZSBzcGVjaWZpZWQgYW5kIGluY2x1ZGUgYXQgbGVhc3QgYSBjZXJ0aWZpY2F0ZSBvciBwcm90b2NvbDogSFRUUFxcblwiKTtcblxuICBjb25zdCBhcHAyID0gKCkgPT4ge1xuICAgIGRlZmF1bHRzLkNoZWNrQWxiUHJvcHMoe30pO1xuICB9O1xuXG4gIGV4cGVjdChhcHAyKS50b1Rocm93RXJyb3IoXCJXaGVuIGFkZGluZyB0aGUgZmlyc3QgbGlzdGVuZXIgYW5kIHRhcmdldCB0byBhIGxvYWQgYmFsYW5jZXIsIGxpc3RlbmVyUHJvcHMgbXVzdCBiZSBzcGVjaWZpZWQgYW5kIGluY2x1ZGUgYXQgbGVhc3QgYSBjZXJ0aWZpY2F0ZSBvciBwcm90b2NvbDogSFRUUFxcblwiKTtcbn0pO1xuXG50ZXN0KCdUZXN0IHNlY29uZCB0YXJnZXQgd2l0aCBubyBydWxlcyBlcnJvcicsICgpID0+IHtcbiAgY29uc3QgcHJvcHMgPSB7XG4gICAgZXhpc3RpbmdMb2FkQmFsYW5jZXJPYmo6IHtcbiAgICAgIGxpc3RlbmVyczogWyAnZmFrZSBsaXN0ZW5lciddLFxuICAgIH0sXG4gICAgZXhpc3RpbmdWcGM6IHsgZmFrZTogJ3ZwYycgfVxuICB9O1xuXG4gIGNvbnN0IGFwcCA9ICgpID0+IHtcbiAgICBkZWZhdWx0cy5DaGVja0FsYlByb3BzKHByb3BzKTtcbiAgfTtcblxuICBleHBlY3QoYXBwKS50b1Rocm93RXJyb3IoXCJXaGVuIGFkZGluZyBhIHNlY29uZCB0YXJnZXQgdG8gYW4gZXhpc3RpbmcgbGlzdGVuZXIsIHRoZXJlIG11c3QgYmUgcnVsZXMgcHJvdmlkZWRcXG5cIik7XG59KTtcblxudGVzdCgnVGVzdCBleGlzdGluZyBMb2FkIEJhbGFuY2VyIHdpdGggbm8gVlBDIHByb3ZpZGVkIGVycm9yJywgKCkgPT4ge1xuICBjb25zdCBwcm9wcyA9IHtcbiAgICBleGlzdGluZ0xvYWRCYWxhbmNlck9iajoge1xuICAgICAgbmFtZTogJ3BsYWNlaG9sZGVyJyxcbiAgICAgIGxpc3RlbmVyczogWyBdXG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGFwcCA9ICgpID0+IHtcbiAgICBkZWZhdWx0cy5DaGVja0FsYlByb3BzKHByb3BzKTtcbiAgfTtcblxuICBleHBlY3QoYXBwKS50b1Rocm93RXJyb3IoXCJBbiBleGlzdGluZyBBTEIgaXMgYWxyZWFkeSBpbiBhIFZQQywgdGhhdCBWUEMgbXVzdCBiZSBwcm92aWRlZCBpbiBwcm9wcy5leGlzdGluZ1ZwYyBmb3IgdGhlIHJlc3Qgb2YgdGhlIGNvbnN0cnVjdCB0byB1c2UuXFxuXCIpO1xufSk7XG5cbnRlc3QoJ1Rlc3Qgc2VuZGluZyBsaXN0ZW5lclByb3BzIHRvIGV4aXN0aW5nTGlzdGVuZXIgZXJyb3InLCAoKSA9PiB7XG4gIGNvbnN0IHByb3BzID0ge1xuICAgIGV4aXN0aW5nTG9hZEJhbGFuY2VyT2JqOiB7XG4gICAgICBsaXN0ZW5lcnM6IFsgJ3BsYWNlaG9sZGVyJyBdXG4gICAgfSxcbiAgICBsaXN0ZW5lclByb3BzOiB7IHZhbDogJ3BsYWNlaG9sZGVyJyB9XG4gIH07XG5cbiAgY29uc3QgYXBwID0gKCkgPT4ge1xuICAgIGRlZmF1bHRzLkNoZWNrQWxiUHJvcHMocHJvcHMpO1xuICB9O1xuXG4gIGV4cGVjdChhcHApLnRvVGhyb3dFcnJvcihcIlRoaXMgbG9hZCBiYWxhbmNlciBhbHJlYWR5IGhhcyBhIGxpc3RlbmVyLCBsaXN0ZW5lclByb3BzIG1heSBub3QgYmUgc3BlY2lmaWVkXFxuXCIpO1xufSk7XG5cbnRlc3QoJ1Rlc3Qgc2VuZGluZyBWUEMgaW4gbG9hZEJhbGFuY2VyUHJvcHMgZXJyb3InLCAoKSA9PiB7XG4gIGNvbnN0IHByb3BzID0ge1xuICAgIGxvYWRCYWxhbmNlclByb3BzOiB7XG4gICAgICB2cGM6IHsgdmFsOiAncGxhY2Vob2xkZXInIH1cbiAgICB9XG4gIH07XG5cbiAgY29uc3QgYXBwID0gKCkgPT4ge1xuICAgIGRlZmF1bHRzLkNoZWNrQWxiUHJvcHMocHJvcHMpO1xuICB9O1xuXG4gIGV4cGVjdChhcHApLnRvVGhyb3dFcnJvcignU3BlY2lmeSBhbnkgZXhpc3RpbmcgVlBDIGF0IHRoZSBjb25zdHJ1Y3QgbGV2ZWwsIG5vdCB3aXRoaW4gbG9hZEJhbGFuY2VyUHJvcHMuXFxuJyk7XG59KTtcblxuZnVuY3Rpb24gQ3JlYXRlVGVzdExvYWRCYWxhbmNlcihzdGFjazogU3RhY2ssIHZwYzogZWMyLklWcGMpOiBlbGIuQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIge1xuICByZXR1cm4gbmV3IGVsYi5BcHBsaWNhdGlvbkxvYWRCYWxhbmNlcihzdGFjaywgJ2xvYWQtYmFsYW5jZXInLCB7XG4gICAgdnBjLFxuICAgIGludGVybmV0RmFjaW5nOiB0cnVlLFxuICAgIGxvYWRCYWxhbmNlck5hbWU6ICd1bmlxdWUtbmFtZSdcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIENyZWF0ZVRlc3RGdW5jdGlvbihzdGFjazogU3RhY2ssIGlkOiBzdHJpbmcpOiBsYW1iZGEuRnVuY3Rpb24ge1xuICByZXR1cm4gbmV3IGxhbWJkYS5GdW5jdGlvbihzdGFjaywgaWQsIHtcbiAgICBjb2RlOiBsYW1iZGEuQ29kZS5mcm9tQXNzZXQoYCR7X19kaXJuYW1lfS9sYW1iZGFgKSxcbiAgICBydW50aW1lOiBsYW1iZGEuUnVudGltZS5OT0RFSlNfMTRfWCxcbiAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIENyZWF0ZVRlc3RGYXJnYXRlU2VydmljZShzdGFjazogU3RhY2ssIGlkOiBzdHJpbmcsIHZwYzogZWMyLklWcGMpOiBlY3MuRmFyZ2F0ZVNlcnZpY2Uge1xuICBjb25zdCBbc3ZjXSA9IGRlZmF1bHRzLkNyZWF0ZUZhcmdhdGVTZXJ2aWNlKHN0YWNrLFxuICAgIGAke2lkfS1mZy1zdmNgLFxuICAgIHZwYyxcbiAgICB1bmRlZmluZWQsXG4gICAgJ2Fybjphd3M6ZWNyOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6cmVwb3NpdG9yeS9mYWtlLXJlcG8nLFxuICAgICdsYXRlc3QnKTtcbiAgcmV0dXJuIHN2Yztcbn1cblxuZnVuY3Rpb24gQ3JlYXRlVGVzdExpc3RlbmVyKHN0YWNrOiBTdGFjaywgaWQ6IHN0cmluZywgYWxiOiBlbGIuQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIpIHtcbiAgcmV0dXJuIG5ldyBlbGIuQXBwbGljYXRpb25MaXN0ZW5lcihzdGFjaywgaWQsIHtcbiAgICBsb2FkQmFsYW5jZXI6IGFsYixcbiAgICBwcm90b2NvbDogZWxiLkFwcGxpY2F0aW9uUHJvdG9jb2wuSFRUUFxuICB9KTtcbn1cbiJdfQ==
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
5
5
  * with the License. A copy of the License is located at