cdk-nuxt 0.2.8 → 0.3.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.
@@ -2,44 +2,184 @@ import { Stack } from 'aws-cdk-lib';
2
2
  import { Construct } from 'constructs';
3
3
  import { IBucket } from "aws-cdk-lib/aws-s3";
4
4
  import { AppStackProps } from "./app-stack-props";
5
+ import { NuxtConfig } from "./nuxt-config";
6
+ /**
7
+ * Defines the props required for the {@see NuxtAppStack}.
8
+ */
5
9
  export interface NuxtAppStackProps extends AppStackProps {
10
+ /**
11
+ * The domain (without the protocol) at which the Nuxt app shall be publicly available.
12
+ * A DNS record will be automatically created in Route53 for the domain.
13
+ * This also supports subdomains.
14
+ * Examples: "example.com", "sub.example.com"
15
+ */
6
16
  readonly domain: string;
7
- readonly globalTlsCertificateArn: string;
17
+ /**
18
+ * The id of the hosted zone to create a DNS record for the specified domain.
19
+ */
8
20
  readonly hostedZoneId: string;
21
+ /**
22
+ * The ARN of the certificate to use for the Nuxt app to make it accessible via HTTPS.
23
+ * The certificate must be issued for the specified domain in us-east-1 (global) regardless of the
24
+ * region used for the Nuxt app itself.
25
+ */
26
+ readonly globalTlsCertificateArn: string;
27
+ /**
28
+ * The nuxt.config.js of the Nuxt app.
29
+ */
30
+ readonly nuxtConfig: NuxtConfig;
9
31
  }
32
+ /**
33
+ * Creates a lambda function that renders the Nuxt app and is publicly reachable via a specified domain.
34
+ */
10
35
  export declare class NuxtAppStack extends Stack {
36
+ /**
37
+ * The identifier prefix of the resources created by the stack.
38
+ *
39
+ * @private
40
+ */
11
41
  private readonly resourceIdPrefix;
42
+ /**
43
+ * The identifier for the current deployment that is used as S3 folder name
44
+ * to store the static assets of the Nuxt app.
45
+ *
46
+ * @private
47
+ */
12
48
  private readonly deploymentRevision;
49
+ /**
50
+ * The certificate to use for the Nuxt app to make it accessible via HTTPS.
51
+ *
52
+ * @private
53
+ */
13
54
  private readonly tlsCertificate;
55
+ /**
56
+ * The identity to use for accessing the deployment assets on S3.
57
+ *
58
+ * @private
59
+ */
14
60
  private readonly cdnAccessIdentity;
61
+ /**
62
+ * The S3 bucket where the deployment assets gets stored.
63
+ */
15
64
  staticAssetsBucket: IBucket;
16
- private readonly layer;
65
+ /**
66
+ * The lambda function to render the Nuxt app on the server side.
67
+ *
68
+ * @private
69
+ */
17
70
  private readonly lambdaFunction;
71
+ /**
72
+ * The API gateway to make the lambda function to render the Nuxt app publicly available.
73
+ *
74
+ * @private
75
+ */
18
76
  private apiGateway;
19
- private readonly httpsForwardingBehavior;
77
+ /**
78
+ * The configs for the static assets of the Nuxt app that shall be publicly available.
79
+ *
80
+ * @private
81
+ */
82
+ private staticAssetConfigs;
83
+ /**
84
+ * The cloudfront distribution to route incoming requests to the Nuxt lambda function (via the API gateway)
85
+ * or the S3 assets folder (with caching).
86
+ *
87
+ * @private
88
+ */
20
89
  private readonly cdn;
21
- private readonly hostedZone;
22
90
  constructor(scope: Construct, id: string, props: NuxtAppStackProps);
91
+ /**
92
+ * Finds the certificate to use for providing HTTPS requests to our Nuxt app.
93
+ *
94
+ * @param props
95
+ * @private
96
+ */
23
97
  private findTlsCertificate;
98
+ /**
99
+ * Creates the identity to access our S3 deployment asset files via the cloudfront distribution.
100
+ *
101
+ * @private
102
+ */
24
103
  private createCdnAccessIdentity;
104
+ /**
105
+ * Creates the bucket to store the static deployment asset files of the Nuxt app.
106
+ *
107
+ * @private
108
+ */
25
109
  private createStaticAssetsBucket;
110
+ /**
111
+ * Creates a lambda layer with the node_modules required to render the Nuxt app on the server side.
112
+ *
113
+ * @private
114
+ */
26
115
  private createSsrLambdaLayer;
116
+ /**
117
+ * Creates the lambda function to render the Nuxt app.
118
+ *
119
+ * @private
120
+ */
27
121
  private createLambdaFunction;
122
+ /**
123
+ * Creates the API gateway to make the Nuxt app render lambda function publicly available.
124
+ *
125
+ * @private
126
+ */
28
127
  private createApiGateway;
29
- private createHttpsForwardingBehavior;
30
128
  /**
31
- * Eventhough we don't want to cache SSR requests, we still have to create a cache policy, in order to
129
+ * Creates the cloudfront distribution that routes incoming requests to the Nuxt lambda function (via the API gateway)
130
+ * or the S3 assets folder (with caching).
131
+ *
132
+ * @param props
133
+ * @private
134
+ */
135
+ private createCloudFrontDistribution;
136
+ /**
137
+ * Creates a behavior for the cloudfront distribution to route incoming requests to the Nuxt render lambda function (via API gateway).
138
+ * Additionally, this automatically redirects HTTP requests to HTTPS.
139
+ *
140
+ * @private
141
+ */
142
+ private createNuxtAppRouteBehavior;
143
+ /**
144
+ * Creates a cache policy for the Nuxt app route behavior of our cloudfront distribution.
145
+ * Eventhough we don't want to cache SSR requests, we still have to create this cache policy in order to
32
146
  * forward required cookies, query params and headers. This doesn't make any sense, because if nothing
33
147
  * is cached, one would expect, that anything would/could be forwarded, but anyway...
34
148
  */
35
149
  private createSsrCachePolicy;
36
- private createCloudFrontDistribution;
37
- private createStaticAssetBehaviors;
38
150
  /**
151
+ * Creates a behavior for the cloudfront distribution to route matching incoming requests for our static assets
152
+ * to the S3 bucket that holds these static assets.
153
+ *
154
+ * @private
155
+ */
156
+ private createStaticAssetsRouteBehavior;
157
+ /**
158
+ * Uploads the static assets of the Nuxt app as defined in {@see getNuxtAppStaticAssetConfigs} to the static assets S3 bucket.
39
159
  * In order to enable a zero-downtime deployment, we use a new subdirectory (revision) for every deployment.
40
- * The previous versions are retained to allow clients to continue to work with an older revision.
160
+ * The previous versions are retained to allow clients to continue to work with an older revision but gets cleaned up
161
+ * after a specified period of time via the lambda function in the {@see NuxtAppAssetsCleanupStack}.
41
162
  */
42
163
  private configureDeployments;
164
+ /**
165
+ * Resolves the hosted zone at which the DNS records shall be created to access our Nuxt app on the internet.
166
+ *
167
+ * @param props
168
+ * @private
169
+ */
43
170
  private findHostedZone;
171
+ /**
172
+ * Creates the DNS records to access our Nuxt app on the internet via our custom domain.
173
+ *
174
+ * @param props
175
+ * @private
176
+ */
44
177
  private createDnsRecords;
178
+ /**
179
+ * Creates a scheduled rule to ping our Nuxt app lambda function every 5 minutes in order to keep it warm
180
+ * and speed up initial SSR requests.
181
+ *
182
+ * @private
183
+ */
184
+ private createPingRule;
45
185
  }
@@ -16,59 +16,90 @@ const aws_apigatewayv2_integrations_alpha_1 = require("@aws-cdk/aws-apigatewayv2
16
16
  const aws_apigatewayv2_alpha_1 = require("@aws-cdk/aws-apigatewayv2-alpha");
17
17
  const nuxt_app_static_assets_1 = require("./nuxt-app-static-assets");
18
18
  const fs = require("fs");
19
+ const aws_events_1 = require("aws-cdk-lib/aws-events");
20
+ const aws_events_targets_1 = require("aws-cdk-lib/aws-events-targets");
21
+ /**
22
+ * Creates a lambda function that renders the Nuxt app and is publicly reachable via a specified domain.
23
+ */
19
24
  class NuxtAppStack extends aws_cdk_lib_1.Stack {
20
25
  constructor(scope, id, props) {
21
26
  super(scope, id, props);
22
27
  this.resourceIdPrefix = `${props.project}-${props.service}-${props.environment}`;
23
28
  this.deploymentRevision = new Date().toISOString();
29
+ this.staticAssetConfigs = (0, nuxt_app_static_assets_1.getNuxtAppStaticAssetConfigs)(props.nuxtConfig);
24
30
  this.tlsCertificate = this.findTlsCertificate(props);
25
31
  this.cdnAccessIdentity = this.createCdnAccessIdentity();
26
32
  this.staticAssetsBucket = this.createStaticAssetsBucket();
27
- this.layer = this.createSsrLambdaLayer();
28
33
  this.lambdaFunction = this.createLambdaFunction();
29
34
  this.apiGateway = this.createApiGateway();
30
- this.httpsForwardingBehavior = this.createHttpsForwardingBehavior();
31
35
  this.cdn = this.createCloudFrontDistribution(props);
32
36
  this.configureDeployments();
33
- this.hostedZone = this.findHostedZone(props);
34
37
  this.createDnsRecords(props);
38
+ this.createPingRule();
35
39
  }
40
+ /**
41
+ * Finds the certificate to use for providing HTTPS requests to our Nuxt app.
42
+ *
43
+ * @param props
44
+ * @private
45
+ */
36
46
  findTlsCertificate(props) {
37
47
  return aws_certificatemanager_1.Certificate.fromCertificateArn(this, `${this.resourceIdPrefix}-tls-certificate`, props.globalTlsCertificateArn);
38
48
  }
49
+ /**
50
+ * Creates the identity to access our S3 deployment asset files via the cloudfront distribution.
51
+ *
52
+ * @private
53
+ */
39
54
  createCdnAccessIdentity() {
40
55
  const originAccessIdentityName = `${this.resourceIdPrefix}-cdn-s3-access`;
41
56
  return new aws_cloudfront_1.OriginAccessIdentity(this, originAccessIdentityName);
42
57
  }
58
+ /**
59
+ * Creates the bucket to store the static deployment asset files of the Nuxt app.
60
+ *
61
+ * @private
62
+ */
43
63
  createStaticAssetsBucket() {
44
64
  const bucketName = `${this.resourceIdPrefix}-assets`;
45
65
  const bucket = new aws_s3_1.Bucket(this, bucketName, {
46
66
  accessControl: aws_s3_1.BucketAccessControl.AUTHENTICATED_READ,
47
67
  blockPublicAccess: aws_s3_1.BlockPublicAccess.BLOCK_ALL,
48
68
  bucketName,
49
- // the bucket and all of its objects can be deleted, because all the content is managed in this project
69
+ // The bucket and all of its objects can be deleted, because all the content is managed in this project
50
70
  removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
51
71
  autoDeleteObjects: true,
52
72
  });
53
73
  bucket.grantReadWrite(this.cdnAccessIdentity);
54
74
  return bucket;
55
75
  }
76
+ /**
77
+ * Creates a lambda layer with the node_modules required to render the Nuxt app on the server side.
78
+ *
79
+ * @private
80
+ */
56
81
  createSsrLambdaLayer() {
57
82
  const layerName = `${this.resourceIdPrefix}-ssr-layer`;
58
83
  return new aws_lambda_1.LayerVersion(this, layerName, {
59
84
  layerVersionName: layerName,
60
85
  code: aws_lambda_1.Code.fromAsset('.nuxt/cdk-deployment/layer'),
61
86
  compatibleRuntimes: [aws_lambda_1.Runtime.NODEJS_12_X],
62
- description: `Contains node_modules required for server-side of ${this.resourceIdPrefix}.`,
87
+ description: `Provides the node_modules required for SSR of ${this.resourceIdPrefix}.`,
63
88
  });
64
89
  }
90
+ /**
91
+ * Creates the lambda function to render the Nuxt app.
92
+ *
93
+ * @private
94
+ */
65
95
  createLambdaFunction() {
66
96
  const funcName = `${this.resourceIdPrefix}-function`;
67
97
  return new aws_lambda_1.Function(this, funcName, {
68
98
  functionName: funcName,
99
+ description: `Renders the ${this.resourceIdPrefix} Nuxt app.`,
69
100
  runtime: aws_lambda_1.Runtime.NODEJS_12_X,
70
101
  architecture: aws_lambda_1.Architecture.ARM_64,
71
- layers: [this.layer],
102
+ layers: [this.createSsrLambdaLayer()],
72
103
  handler: 'index.handler',
73
104
  code: aws_lambda_1.Code.fromAsset('.nuxt/cdk-deployment/src', {
74
105
  exclude: ['**.svg', '**.ico', '**.png', '**.jpg', 'chunk.*.js*', 'bundle.*.js*', 'bundle.*.js*', 'sw.js*'],
@@ -76,15 +107,20 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
76
107
  timeout: aws_cdk_lib_1.Duration.seconds(10),
77
108
  memorySize: 512,
78
109
  logRetention: aws_logs_1.RetentionDays.ONE_MONTH,
79
- environment: {},
80
110
  allowPublicSubnet: false
81
111
  });
82
112
  }
113
+ /**
114
+ * Creates the API gateway to make the Nuxt app render lambda function publicly available.
115
+ *
116
+ * @private
117
+ */
83
118
  createApiGateway() {
84
119
  const lambdaIntegration = new aws_apigatewayv2_integrations_alpha_1.HttpLambdaIntegration(`${this.resourceIdPrefix}-lambda-integration`, this.lambdaFunction);
85
120
  const apiName = `${this.resourceIdPrefix}-api`;
86
121
  const apiGateway = new aws_apigatewayv2_alpha_1.HttpApi(this, apiName, {
87
122
  apiName,
123
+ description: `Connects the ${this.resourceIdPrefix} cloudfront distribution with the ${this.resourceIdPrefix} lambda function to make it publicly available.`,
88
124
  // The app does not allow any cross-origin access by purpose: the app should not be embeddable anywhere
89
125
  corsPreflight: undefined,
90
126
  defaultIntegration: lambdaIntegration,
@@ -96,7 +132,32 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
96
132
  });
97
133
  return apiGateway;
98
134
  }
99
- createHttpsForwardingBehavior() {
135
+ /**
136
+ * Creates the cloudfront distribution that routes incoming requests to the Nuxt lambda function (via the API gateway)
137
+ * or the S3 assets folder (with caching).
138
+ *
139
+ * @param props
140
+ * @private
141
+ */
142
+ createCloudFrontDistribution(props) {
143
+ const cdnName = `${this.resourceIdPrefix}-cdn`;
144
+ return new aws_cloudfront_1.Distribution(this, cdnName, {
145
+ domainNames: [props.domain],
146
+ comment: `${this.resourceIdPrefix}-redirect`,
147
+ minimumProtocolVersion: aws_cloudfront_1.SecurityPolicyProtocol.TLS_V1_2_2018,
148
+ certificate: this.tlsCertificate,
149
+ defaultBehavior: this.createNuxtAppRouteBehavior(),
150
+ additionalBehaviors: this.createStaticAssetsRouteBehavior(),
151
+ priceClass: aws_cloudfront_1.PriceClass.PRICE_CLASS_100, // Use only North America and Europe
152
+ });
153
+ }
154
+ /**
155
+ * Creates a behavior for the cloudfront distribution to route incoming requests to the Nuxt render lambda function (via API gateway).
156
+ * Additionally, this automatically redirects HTTP requests to HTTPS.
157
+ *
158
+ * @private
159
+ */
160
+ createNuxtAppRouteBehavior() {
100
161
  return {
101
162
  origin: new aws_cloudfront_origins_1.HttpOrigin(`${this.apiGateway.httpApiId}.execute-api.${this.region}.amazonaws.com`, {
102
163
  connectionAttempts: 2,
@@ -112,15 +173,16 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
112
173
  };
113
174
  }
114
175
  /**
115
- * Eventhough we don't want to cache SSR requests, we still have to create a cache policy, in order to
176
+ * Creates a cache policy for the Nuxt app route behavior of our cloudfront distribution.
177
+ * Eventhough we don't want to cache SSR requests, we still have to create this cache policy in order to
116
178
  * forward required cookies, query params and headers. This doesn't make any sense, because if nothing
117
179
  * is cached, one would expect, that anything would/could be forwarded, but anyway...
118
180
  */
119
181
  createSsrCachePolicy() {
120
- // The headers to pass to the app
182
+ // The headers to make accessible in our Nuxt app code
121
183
  const headers = [
122
184
  'User-Agent',
123
- 'Authorization',
185
+ 'Authorization', // For authorization
124
186
  ];
125
187
  return new aws_cloudfront_1.CachePolicy(this, `${this.resourceIdPrefix}-cache-policy`, {
126
188
  cachePolicyName: `${this.resourceIdPrefix}-cdn-cache-policy`,
@@ -135,19 +197,13 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
135
197
  enableAcceptEncodingGzip: true,
136
198
  });
137
199
  }
138
- createCloudFrontDistribution(props) {
139
- const cdnName = `${this.resourceIdPrefix}-cdn`;
140
- return new aws_cloudfront_1.Distribution(this, cdnName, {
141
- domainNames: [props.domain],
142
- comment: `${this.resourceIdPrefix}-redirect`,
143
- minimumProtocolVersion: aws_cloudfront_1.SecurityPolicyProtocol.TLS_V1_2_2018,
144
- certificate: this.tlsCertificate,
145
- defaultBehavior: this.httpsForwardingBehavior,
146
- additionalBehaviors: this.createStaticAssetBehaviors(),
147
- priceClass: aws_cloudfront_1.PriceClass.PRICE_CLASS_100,
148
- });
149
- }
150
- createStaticAssetBehaviors() {
200
+ /**
201
+ * Creates a behavior for the cloudfront distribution to route matching incoming requests for our static assets
202
+ * to the S3 bucket that holds these static assets.
203
+ *
204
+ * @private
205
+ */
206
+ createStaticAssetsRouteBehavior() {
151
207
  const staticAssetsCacheConfig = {
152
208
  origin: new aws_cloudfront_origins_1.S3Origin(this.staticAssetsBucket, {
153
209
  connectionAttempts: 2,
@@ -162,14 +218,16 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
162
218
  viewerProtocolPolicy: aws_cloudfront_1.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
163
219
  };
164
220
  const rules = {};
165
- nuxt_app_static_assets_1.NuxtAppStaticAssets.forEach(asset => {
221
+ this.staticAssetConfigs.forEach(asset => {
166
222
  rules[`${asset.target}${asset.pattern}`] = staticAssetsCacheConfig;
167
223
  });
168
224
  return rules;
169
225
  }
170
226
  /**
227
+ * Uploads the static assets of the Nuxt app as defined in {@see getNuxtAppStaticAssetConfigs} to the static assets S3 bucket.
171
228
  * In order to enable a zero-downtime deployment, we use a new subdirectory (revision) for every deployment.
172
- * The previous versions are retained to allow clients to continue to work with an older revision.
229
+ * The previous versions are retained to allow clients to continue to work with an older revision but gets cleaned up
230
+ * after a specified period of time via the lambda function in the {@see NuxtAppAssetsCleanupStack}.
173
231
  */
174
232
  configureDeployments() {
175
233
  const defaultCacheConfig = [
@@ -178,7 +236,7 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
178
236
  aws_s3_deployment_1.CacheControl.fromString('immutable'),
179
237
  ];
180
238
  // Returns a deployment for every configured static asset type to respect the different cache settings
181
- return nuxt_app_static_assets_1.NuxtAppStaticAssets.filter(asset => fs.existsSync(asset.source)).map((asset, assetIndex) => {
239
+ return this.staticAssetConfigs.filter(asset => fs.existsSync(asset.source)).map((asset, assetIndex) => {
182
240
  var _a;
183
241
  return new aws_s3_deployment_1.BucketDeployment(this, `${this.resourceIdPrefix}-assets-deployment-${assetIndex}`, {
184
242
  sources: [aws_s3_deployment_1.Source.asset(asset.source)],
@@ -193,28 +251,56 @@ class NuxtAppStack extends aws_cdk_lib_1.Stack {
193
251
  });
194
252
  });
195
253
  }
254
+ /**
255
+ * Resolves the hosted zone at which the DNS records shall be created to access our Nuxt app on the internet.
256
+ *
257
+ * @param props
258
+ * @private
259
+ */
196
260
  findHostedZone(props) {
197
261
  const domainParts = props.domain.split('.');
198
262
  return aws_route53_1.HostedZone.fromHostedZoneAttributes(this, `${this.resourceIdPrefix}-hosted-zone`, {
199
263
  hostedZoneId: props.hostedZoneId,
200
- zoneName: domainParts[domainParts.length - 1],
264
+ zoneName: domainParts[domainParts.length - 1], // Support subdomains
201
265
  });
202
266
  }
267
+ /**
268
+ * Creates the DNS records to access our Nuxt app on the internet via our custom domain.
269
+ *
270
+ * @param props
271
+ * @private
272
+ */
203
273
  createDnsRecords(props) {
274
+ const hostedZone = this.findHostedZone(props);
204
275
  const dnsTarget = aws_route53_1.RecordTarget.fromAlias(new aws_route53_targets_1.CloudFrontTarget(this.cdn));
205
276
  // Create a record for IPv4
206
277
  new aws_route53_1.ARecord(this, `${this.resourceIdPrefix}-ipv4-record`, {
207
278
  recordName: props.domain,
208
- zone: this.hostedZone,
279
+ zone: hostedZone,
209
280
  target: dnsTarget,
210
281
  });
211
282
  // Create a record for IPv6
212
283
  new aws_route53_1.AaaaRecord(this, `${this.resourceIdPrefix}-ipv6-record`, {
213
284
  recordName: props.domain,
214
- zone: this.hostedZone,
285
+ zone: hostedZone,
215
286
  target: dnsTarget,
216
287
  });
217
288
  }
289
+ /**
290
+ * Creates a scheduled rule to ping our Nuxt app lambda function every 5 minutes in order to keep it warm
291
+ * and speed up initial SSR requests.
292
+ *
293
+ * @private
294
+ */
295
+ createPingRule() {
296
+ new aws_events_1.Rule(this, `${this.resourceIdPrefix}-pinger-rule`, {
297
+ ruleName: `${this.resourceIdPrefix}-pinger`,
298
+ description: `Pings the lambda function of the ${this.resourceIdPrefix} app every 5 minutes to keep it warm.`,
299
+ enabled: true,
300
+ schedule: aws_events_1.Schedule.rate(aws_cdk_lib_1.Duration.minutes(5)),
301
+ targets: [new aws_events_targets_1.LambdaFunction(this.lambdaFunction)],
302
+ });
303
+ }
218
304
  }
219
305
  exports.NuxtAppStack = NuxtAppStack;
220
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnV4dC1hcHAtc3RhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJudXh0LWFwcC1zdGFjay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBaUU7QUFFakUsK0VBQTZFO0FBQzdFLCtEQVNvQztBQUNwQyx1REFBMkY7QUFDM0YsK0NBQTJGO0FBQzNGLHlEQUFtRztBQUNuRyxxRUFBbUc7QUFDbkcsK0VBQXdFO0FBQ3hFLHlFQUFpRTtBQUNqRSxpRkFBK0Q7QUFDL0QsbURBQW1EO0FBQ25ELHNHQUFxRjtBQUNyRiw0RUFBd0Q7QUFDeEQscUVBQTZEO0FBRTdELHlCQUF5QjtBQVd6QixNQUFhLFlBQWEsU0FBUSxtQkFBSztJQWFyQyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXdCO1FBQ2hFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXhCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxHQUFHLEtBQUssQ0FBQyxPQUFPLElBQUksS0FBSyxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDakYsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkQsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQ3hELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztRQUMxRCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQ3pDLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDbEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMs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Q2hDLFFBQVEsRUFBRSxXQUFXLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7U0FDOUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLGdCQUFnQixDQUFDLEtBQXdCO1FBQy9DLE1BQU0sU0FBUyxHQUFHLDBCQUFZLENBQUMsU0FBUyxDQUFDLElBQUksc0NBQWdCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFekUsMkJBQTJCO1FBQzNCLElBQUkscUJBQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLGNBQWMsRUFBRTtZQUN4RCxVQUFVLEVBQUUsS0FBSyxDQUFDLE1BQU07WUFDeEIsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQ3JCLE1BQU0sRUFBRSxTQUFTO1NBQ2xCLENBQUMsQ0FBQztRQUVILDJCQUEyQjtRQUMzQixJQUFJLHdCQUFVLENBQUMsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixjQUFjLEVBQUU7WUFDM0QsVUFBVSxFQUFFLEtBQUssQ0FBQyxNQUFNO1lBQ3hCLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVTtZQUNyQixNQUFNLEVBQUUsU0FBUztTQUNsQixDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUE3T0Qsb0NBNk9DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtEdXJhdGlvbiwgUmVtb3ZhbFBvbGljeSwgU3RhY2ssIFRhZ3N9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHtDZXJ0aWZpY2F0ZSwgSUNlcnRpZmljYXRlfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNlcnRpZmljYXRlbWFuYWdlclwiO1xuaW1wb3J0IHtcbiAgQWxsb3dlZE1ldGhvZHMsXG4gIEJlaGF2aW9yT3B0aW9ucywgQ2FjaGVDb29raWVCZWhhdmlvcixcbiAgQ2FjaGVkTWV0aG9kcywgQ2FjaGVIZWFkZXJCZWhhdmlvcixcbiAgQ2FjaGVQb2xpY3ksIENhY2hlUXVlcnlTdHJpbmdCZWhhdmlvcixcbiAgRGlzdHJpYnV0aW9uLCBJQ2FjaGVQb2xpY3ksXG4gIElPcmlnaW5BY2Nlc3NJZGVudGl0eSwgT3JpZ2luQWNjZXNzSWRlbnRpdHksIE9yaWdpblByb3RvY29sUG9saWN5LCBQcmljZUNsYXNzLFxuICBTZWN1cml0eVBvbGljeVByb3RvY29sLFxuICBWaWV3ZXJQcm90b2NvbFBvbGljeVxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3VkZnJvbnRcIjtcbmltcG9ydCB7QXJjaGl0ZWN0dXJlLCBDb2RlLCBMYXllclZlcnNpb24sIFJ1bnRpbWUsIEZ1bmN0aW9ufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYVwiO1xuaW1wb3J0IHtCbG9ja1B1YmxpY0FjY2VzcywgQnVja2V0LCBCdWNrZXRBY2Nlc3NDb250cm9sLCBJQnVja2V0fSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzXCI7XG5pbXBvcnQge0FSZWNvcmQsIEFhYWFSZWNvcmQsIEhvc3RlZFpvbmUsIElIb3N0ZWRab25lLCBSZWNvcmRUYXJnZXR9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtcm91dGU1M1wiO1xuaW1wb3J0IHtCdWNrZXREZXBsb3ltZW50LCBDYWNoZUNvbnRyb2wsIFNvdXJjZSwgU3RvcmFnZUNsYXNzfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzLWRlcGxveW1lbnRcIjtcbmltcG9ydCB7SHR0cE9yaWdpbiwgUzNPcmlnaW59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWRmcm9udC1vcmlnaW5zXCI7XG5pbXBvcnQge0Nsb3VkRnJvbnRUYXJnZXR9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtcm91dGU1My10YXJnZXRzXCI7XG5pbXBvcnQge0h0dHBNZXRob2R9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtc3RlcGZ1bmN0aW9ucy10YXNrc1wiO1xuaW1wb3J0IHtSZXRlbnRpb25EYXlzfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxvZ3NcIjtcbmltcG9ydCB7IEh0dHBMYW1iZGFJbnRlZ3JhdGlvbiB9IGZyb20gJ0Bhd3MtY2RrL2F3cy1hcGlnYXRld2F5djItaW50ZWdyYXRpb25zLWFscGhhJztcbmltcG9ydCB7SHR0cEFwaX0gZnJvbSBcIkBhd3MtY2RrL2F3cy1hcGlnYXRld2F5djItYWxwaGFcIjtcbmltcG9ydCB7TnV4dEFwcFN0YXRpY0Fzc2V0c30gZnJvbSBcIi4vbnV4dC1hcHAtc3RhdGljLWFzc2V0c1wiO1xuaW1wb3J0IHtBcHBTdGFja1Byb3BzfSBmcm9tIFwiLi9hcHAtc3RhY2stcHJvcHNcIjtcbmltcG9ydCAqIGFzIGZzIGZyb20gXCJmc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIE51eHRBcHBTdGFja1Byb3BzIGV4dGVuZHMgQXBwU3RhY2tQcm9wcyB7XG4gIHJlYWRvbmx5IGRvbWFpbjogc3RyaW5nO1xuXG4gIC8vIFVzZWQgYnkgdGhlIENETiwgbXVzdCBiZSBpc3N1ZWQgaW4gdXMtZWFzdC0xIChnbG9iYWwpXG4gIHJlYWRvbmx5IGdsb2JhbFRsc0NlcnRpZmljYXRlQXJuOiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkgaG9zdGVkWm9uZUlkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBOdXh0QXBwU3RhY2sgZXh0ZW5kcyBTdGFjayB7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVzb3VyY2VJZFByZWZpeDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlcGxveW1lbnRSZXZpc2lvbjogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IHRsc0NlcnRpZmljYXRlOiBJQ2VydGlmaWNhdGU7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2RuQWNjZXNzSWRlbnRpdHk6IElPcmlnaW5BY2Nlc3NJZGVudGl0eTtcbiAgcHVibGljIHN0YXRpY0Fzc2V0c0J1Y2tldDogSUJ1Y2tldDtcbiAgcHJpdmF0ZSByZWFkb25seSBsYXllcjogTGF5ZXJWZXJzaW9uO1xuICBwcml2YXRlIHJlYWRvbmx5IGxhbWJkYUZ1bmN0aW9uOiBGdW5jdGlvbjtcbiAgcHJpdmF0ZSBhcGlHYXRld2F5OiBIdHRwQXBpO1xuICBwcml2YXRlIHJlYWRvbmx5IGh0dHBzRm9yd2FyZGluZ0JlaGF2aW9yOiBCZWhhdmlvck9wdGlvbnM7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2RuOiBEaXN0cmlidXRpb247XG4gIHByaXZhdGUgcmVhZG9ubHkgaG9zdGVkWm9uZTogSUhvc3RlZFpvbmU7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE51eHRBcHBTdGFja1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCBwcm9wcyk7XG5cbiAgICB0aGlzLnJlc291cmNlSWRQcmVmaXggPSBgJHtwcm9wcy5wcm9qZWN0fS0ke3Byb3BzLnNlcnZpY2V9LSR7cHJvcHMuZW52aXJvbm1lbnR9YDtcbiAgICB0aGlzLmRlcGxveW1lbnRSZXZpc2lvbiA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICB0aGlzLnRsc0NlcnRpZmljYXRlID0gdGhpcy5maW5kVGxzQ2VydGlmaWNhdGUocHJvcHMpO1xuICAgIHRoaXMuY2RuQWNjZXNzSWRlbnRpdHkgPSB0aGlzLmNyZWF0ZUNkbkFjY2Vzc0lkZW50aXR5KCk7XG4gICAgdGhpcy5zdGF0aWNBc3NldHNCdWNrZXQgPSB0aGlzLmNyZWF0ZVN0YXRpY0Fzc2V0c0J1Y2tldCgpO1xuICAgIHRoaXMubGF5ZXIgPSB0aGlzLmNyZWF0ZVNzckxhbWJkYUxheWVyKCk7XG4gICAgdGhpcy5sYW1iZGFGdW5jdGlvbiA9IHRoaXMuY3JlYXRlTGFtYmRhRnVuY3Rpb24oKTtcbiAgICB0aGlzLmFwaUdhdGV3YXkgPSB0aGlzLmNyZWF0ZUFwaUdhdGV3YXkoKTtcbiAgICB0aGlzLmh0dHBzRm9yd2FyZGluZ0JlaGF2aW9yID0gdGhpcy5jcmVhdGVIdHRwc0ZvcndhcmRpbmdCZWhhdmlvcigpO1xuICAgIHRoaXMuY2RuID0gdGhpcy5jcmVhdGVDbG91ZEZyb250RGlzdHJpYnV0aW9uKHByb3BzKTtcbiAgICB0aGlzLmNvbmZpZ3VyZURlcGxveW1lbnRzKCk7XG4gICAgdGhpcy5ob3N0ZWRab25lID0gdGhpcy5maW5kSG9zdGVkWm9uZShwcm9wcyk7XG4gICAgdGhpcy5jcmVhdGVEbnNSZWNvcmRzKHByb3BzKTtcbiAgfVxuXG4gIHByaXZhdGUgZmluZFRsc0NlcnRpZmljYXRlKHByb3BzOiBOdXh0QXBwU3RhY2tQcm9wcyk6IElDZXJ0aWZpY2F0ZSB7XG4gICAgcmV0dXJuIENlcnRpZmljYXRlLmZyb21DZXJ0aWZpY2F0ZUFybih0aGlzLCBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LXRscy1jZXJ0aWZpY2F0ZWAsIHByb3BzLmdsb2JhbFRsc0NlcnRpZmljYXRlQXJuKTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQ2RuQWNjZXNzSWRlbnRpdHkoKTogSU9yaWdpbkFjY2Vzc0lkZW50aXR5IHtcbiAgICBjb25zdCBvcmlnaW5BY2Nlc3NJZGVudGl0eU5hbWUgPSBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWNkbi1zMy1hY2Nlc3NgO1xuICAgIHJldHVybiBuZXcgT3JpZ2luQWNjZXNzSWRlbnRpdHkodGhpcywgb3JpZ2luQWNjZXNzSWRlbnRpdHlOYW1lKTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlU3RhdGljQXNzZXRzQnVja2V0KCk6IElCdWNrZXQge1xuICAgIGNvbnN0IGJ1Y2tldE5hbWUgPSBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWFzc2V0c2A7XG4gICAgY29uc3QgYnVja2V0ID0gbmV3IEJ1Y2tldCh0aGlzLCBidWNrZXROYW1lLCB7XG4gICAgICBhY2Nlc3NDb250cm9sOiBCdWNrZXRBY2Nlc3NDb250cm9sLkFVVEhFTlRJQ0FURURfUkVBRCxcbiAgICAgIGJsb2NrUHVibGljQWNjZXNzOiBCbG9ja1B1YmxpY0FjY2Vzcy5CTE9DS19BTEwsXG4gICAgICBidWNrZXROYW1lLFxuICAgICAgLy8gdGhlIGJ1Y2tldCBhbmQgYWxsIG9mIGl0cyBvYmplY3RzIGNhbiBiZSBkZWxldGVkLCBiZWNhdXNlIGFsbCB0aGUgY29udGVudCBpcyBtYW5hZ2VkIGluIHRoaXMgcHJvamVjdFxuICAgICAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgICAgYXV0b0RlbGV0ZU9iamVjdHM6IHRydWUsXG4gICAgfSk7XG5cbiAgICBidWNrZXQuZ3JhbnRSZWFkV3JpdGUodGhpcy5jZG5BY2Nlc3NJZGVudGl0eSk7XG5cbiAgICByZXR1cm4gYnVja2V0O1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVTc3JMYW1iZGFMYXllcigpOiBMYXllclZlcnNpb24ge1xuICAgIGNvbnN0IGxheWVyTmFtZSA9IGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tc3NyLWxheWVyYDtcbiAgICByZXR1cm4gbmV3IExheWVyVmVyc2lvbih0aGlzLCBsYXllck5hbWUsIHtcbiAgICAgIGxheWVyVmVyc2lvbk5hbWU6IGxheWVyTmFtZSxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUFzc2V0KCcubnV4dC9jZGstZGVwbG95bWVudC9sYXllcicpLFxuICAgICAgY29tcGF0aWJsZVJ1bnRpbWVzOiBbUnVudGltZS5OT0RFSlNfMTJfWF0sXG4gICAgICBkZXNjcmlwdGlvbjogYENvbnRhaW5zIG5vZGVfbW9kdWxlcyByZXF1aXJlZCBmb3Igc2VydmVyLXNpZGUgb2YgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LmAsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUxhbWJkYUZ1bmN0aW9uKCk6IEZ1bmN0aW9uIHtcbiAgICBjb25zdCBmdW5jTmFtZSA9IGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tZnVuY3Rpb25gO1xuXG4gICAgcmV0dXJuIG5ldyBGdW5jdGlvbih0aGlzLCBmdW5jTmFtZSwge1xuICAgICAgZnVuY3Rpb25OYW1lOiBmdW5jTmFtZSxcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzEyX1gsXG4gICAgICBhcmNoaXRlY3R1cmU6IEFyY2hpdGVjdHVyZS5BUk1fNjQsXG4gICAgICBsYXllcnM6IFt0aGlzLmxheWVyXSxcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUFzc2V0KCcubnV4dC9jZGstZGVwbG95bWVudC9zcmMnLCB7XG4gICAgICAgIGV4Y2x1ZGU6IFsnKiouc3ZnJywgJyoqLmljbycsICcqKi5wbmcnLCAnKiouanBnJywgJ2NodW5rLiouanMqJywgJ2J1bmRsZS4qLmpzKicsICdidW5kbGUuKi5qcyonLCAnc3cuanMqJ10sXG4gICAgICB9KSxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoMTApLFxuICAgICAgbWVtb3J5U2l6ZTogNTEyLFxuICAgICAgbG9nUmV0ZW50aW9uOiBSZXRlbnRpb25EYXlzLk9ORV9NT05USCxcbiAgICAgIGVudmlyb25tZW50OiB7fSxcbiAgICAgIGFsbG93UHVibGljU3VibmV0OiBmYWxzZVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVBcGlHYXRld2F5KCk6IEh0dHBBcGkge1xuICAgIGNvbnN0IGxhbWJkYUludGVncmF0aW9uID0gbmV3IEh0dHBMYW1iZGFJbnRlZ3JhdGlvbihgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWxhbWJkYS1pbnRlZ3JhdGlvbmAsIHRoaXMubGFtYmRhRnVuY3Rpb24pO1xuICAgIGNvbnN0IGFwaU5hbWUgPSBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWFwaWA7XG4gICAgY29uc3QgYXBpR2F0ZXdheSA9IG5ldyBIdHRwQXBpKHRoaXMsIGFwaU5hbWUsIHtcbiAgICAgIGFwaU5hbWUsXG4gICAgICAvLyBUaGUgYXBwIGRvZXMgbm90IGFsbG93IGFueSBjcm9zcy1vcmlnaW4gYWNjZXNzIGJ5IHB1cnBvc2U6IHRoZSBhcHAgc2hvdWxkIG5vdCBiZSBlbWJlZGRhYmxlIGFueXdoZXJlXG4gICAgICBjb3JzUHJlZmxpZ2h0OiB1bmRlZmluZWQsXG4gICAgICBkZWZhdWx0SW50ZWdyYXRpb246IGxhbWJkYUludGVncmF0aW9uLFxuICAgIH0pO1xuXG4gICAgYXBpR2F0ZXdheS5hZGRSb3V0ZXMoe1xuICAgICAgaW50ZWdyYXRpb246IGxhbWJkYUludGVncmF0aW9uLFxuICAgICAgcGF0aDogJy97cHJveHkrfScsXG4gICAgICBtZXRob2RzOiBbSHR0cE1ldGhvZC5HRVQsIEh0dHBNZXRob2QuSEVBRF0sXG4gICAgfSk7XG4gICAgcmV0dXJuIGFwaUdhdGV3YXk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUh0dHBzRm9yd2FyZGluZ0JlaGF2aW9yKCk6IEJlaGF2aW9yT3B0aW9ucyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9yaWdpbjogbmV3IEh0dHBPcmlnaW4oYCR7dGhpcy5hcGlHYXRld2F5Lmh0dHBBcGlJZH0uZXhlY3V0ZS1hcGkuJHt0aGlzLnJlZ2lvbn0uYW1hem9uYXdzLmNvbWAsIHtcbiAgICAgICAgY29ubmVjdGlvbkF0dGVtcHRzOiAyLFxuICAgICAgICBjb25uZWN0aW9uVGltZW91dDogRHVyYXRpb24uc2Vjb25kcygyKSxcbiAgICAgICAgcmVhZFRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoMTApLFxuICAgICAgICBwcm90b2NvbFBvbGljeTogT3JpZ2luUHJvdG9jb2xQb2xpY3kuSFRUUFNfT05MWSxcbiAgICAgIH0pLFxuICAgICAgYWxsb3dlZE1ldGhvZHM6IEFsbG93ZWRNZXRob2RzLkFMTE9XX0dFVF9IRUFELFxuICAgICAgY29tcHJlc3M6IHRydWUsXG4gICAgICB2aWV3ZXJQcm90b2NvbFBvbGljeTogVmlld2VyUHJvdG9jb2xQb2xpY3kuUkVESVJFQ1RfVE9fSFRUUFMsXG4gICAgICBvcmlnaW5SZXF1ZXN0UG9saWN5OiB1bmRlZmluZWQsXG4gICAgICBjYWNoZVBvbGljeTogdGhpcy5jcmVhdGVTc3JDYWNoZVBvbGljeSgpLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogRXZlbnRob3VnaCB3ZSBkb24ndCB3YW50IHRvIGNhY2hlIFNTUiByZXF1ZXN0cywgd2Ugc3RpbGwgaGF2ZSB0byBjcmVhdGUgYSBjYWNoZSBwb2xpY3ksIGluIG9yZGVyIHRvXG4gICAqIGZvcndhcmQgcmVxdWlyZWQgY29va2llcywgcXVlcnkgcGFyYW1zIGFuZCBoZWFkZXJzLiBUaGlzIGRvZXNuJ3QgbWFrZSBhbnkgc2Vuc2UsIGJlY2F1c2UgaWYgbm90aGluZ1xuICAgKiBpcyBjYWNoZWQsIG9uZSB3b3VsZCBleHBlY3QsIHRoYXQgYW55dGhpbmcgd291bGQvY291bGQgYmUgZm9yd2FyZGVkLCBidXQgYW55d2F5Li4uXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZVNzckNhY2hlUG9saWN5KCk6IElDYWNoZVBvbGljeSB7XG5cbiAgICAvLyBUaGUgaGVhZGVycyB0byBwYXNzIHRvIHRoZSBhcHBcbiAgICBjb25zdCBoZWFkZXJzID0gW1xuICAgICAgJ1VzZXItQWdlbnQnLCAvLyBSZXF1aXJlZCB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIG1vYmlsZSBhbmQgZGVza3RvcCB0ZW1wbGF0ZVxuICAgICAgJ0F1dGhvcml6YXRpb24nLCAvLyBGb3IgYXV0aG9yaXphdGlvblxuICAgIF07XG5cbiAgICByZXR1cm4gbmV3IENhY2hlUG9saWN5KHRoaXMsIGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tY2FjaGUtcG9saWN5YCwge1xuICAgICAgY2FjaGVQb2xpY3lOYW1lOiBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWNkbi1jYWNoZS1wb2xpY3lgLFxuICAgICAgY29tbWVudDogYFBhc3NlcyBhbGwgcmVxdWlyZWQgcmVxdWVzdCBkYXRhIHRvIHRoZSAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0gb3JpZ2luLmAsXG4gICAgICBkZWZhdWx0VHRsOiBEdXJhdGlvbi5zZWNvbmRzKDApLFxuICAgICAgbWluVHRsOiBEdXJhdGlvbi5zZWNvbmRzKDApLFxuICAgICAgbWF4VHRsOiBEdXJhdGlvbi5zZWNvbmRzKDEpLCAvLyB0aGUgbWF4IFRUTCBtdXN0IG5vdCBiZSAwIGZvciBhIGNhY2hlIHBvbGljeVxuICAgICAgcXVlcnlTdHJpbmdCZWhhdmlvcjogQ2FjaGVRdWVyeVN0cmluZ0JlaGF2aW9yLmFsbCgpLFxuICAgICAgaGVhZGVyQmVoYXZpb3I6IENhY2hlSGVhZGVyQmVoYXZpb3IuYWxsb3dMaXN0KC4uLmhlYWRlcnMpLFxuICAgICAgY29va2llQmVoYXZpb3I6IENhY2hlQ29va2llQmVoYXZpb3IuYWxsKCksXG4gICAgICBlbmFibGVBY2NlcHRFbmNvZGluZ0Jyb3RsaTogdHJ1ZSxcbiAgICAgIGVuYWJsZUFjY2VwdEVuY29kaW5nR3ppcDogdHJ1ZSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQ2xvdWRGcm9udERpc3RyaWJ1dGlvbihwcm9wczogTnV4dEFwcFN0YWNrUHJvcHMpOiBEaXN0cmlidXRpb24ge1xuICAgIGNvbnN0IGNkbk5hbWUgPSBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWNkbmA7XG5cbiAgICByZXR1cm4gbmV3IERpc3RyaWJ1dGlvbih0aGlzLCBjZG5OYW1lLCB7XG4gICAgICBkb21haW5OYW1lczogW3Byb3BzLmRvbWFpbl0sXG4gICAgICBjb21tZW50OiBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LXJlZGlyZWN0YCxcbiAgICAgIG1pbmltdW1Qcm90b2NvbFZlcnNpb246IFNlY3VyaXR5UG9saWN5UHJvdG9jb2wuVExTX1YxXzJfMjAxOCxcbiAgICAgIGNlcnRpZmljYXRlOiB0aGlzLnRsc0NlcnRpZmljYXRlLFxuICAgICAgZGVmYXVsdEJlaGF2aW9yOiB0aGlzLmh0dHBzRm9yd2FyZGluZ0JlaGF2aW9yLFxuICAgICAgYWRkaXRpb25hbEJlaGF2aW9yczogdGhpcy5jcmVhdGVTdGF0aWNBc3NldEJlaGF2aW9ycygpLFxuICAgICAgcHJpY2VDbGFzczogUHJpY2VDbGFzcy5QUklDRV9DTEFTU18xMDAsIC8vIFVzZSBvbmx5IE5vcnRoIEFtZXJpY2EgYW5kIEV1cm9wZVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVTdGF0aWNBc3NldEJlaGF2aW9ycygpOiBSZWNvcmQ8c3RyaW5nLCBCZWhhdmlvck9wdGlvbnM+IHtcbiAgICBjb25zdCBzdGF0aWNBc3NldHNDYWNoZUNvbmZpZzogQmVoYXZpb3JPcHRpb25zID0ge1xuICAgICAgb3JpZ2luOiBuZXcgUzNPcmlnaW4odGhpcy5zdGF0aWNBc3NldHNCdWNrZXQsIHtcbiAgICAgICAgY29ubmVjdGlvbkF0dGVtcHRzOiAyLFxuICAgICAgICBjb25uZWN0aW9uVGltZW91dDogRHVyYXRpb24uc2Vjb25kcygzKSxcbiAgICAgICAgb3JpZ2luQWNjZXNzSWRlbnRpdHk6IHRoaXMuY2RuQWNjZXNzSWRlbnRpdHksXG4gICAgICAgIG9yaWdpblBhdGg6IHRoaXMuZGVwbG95bWVudFJldmlzaW9uLFxuICAgICAgfSksXG4gICAgICBjb21wcmVzczogdHJ1ZSxcbiAgICAgIGFsbG93ZWRNZXRob2RzOiBBbGxvd2VkTWV0aG9kcy5BTExPV19HRVRfSEVBRF9PUFRJT05TLFxuICAgICAgY2FjaGVkTWV0aG9kczogQ2FjaGVkTWV0aG9kcy5DQUNIRV9HRVRfSEVBRF9PUFRJT05TLFxuICAgICAgY2FjaGVQb2xpY3k6IENhY2hlUG9saWN5LkNBQ0hJTkdfT1BUSU1JWkVELFxuICAgICAgdmlld2VyUHJvdG9jb2xQb2xpY3k6IFZpZXdlclByb3RvY29sUG9saWN5LlJFRElSRUNUX1RPX0hUVFBTLFxuICAgIH07XG5cbiAgICBjb25zdCBydWxlczogUmVjb3JkPHN0cmluZywgQmVoYXZpb3JPcHRpb25zPiA9IHt9O1xuICAgIE51eHRBcHBTdGF0aWNBc3NldHMuZm9yRWFjaChhc3NldCA9PiB7XG4gICAgICBydWxlc1tgJHthc3NldC50YXJnZXR9JHthc3NldC5wYXR0ZXJufWBdID0gc3RhdGljQXNzZXRzQ2FjaGVDb25maWdcbiAgICB9KVxuXG4gICAgcmV0dXJuIHJ1bGVzXG4gIH1cblxuICAvKipcbiAgICogSW4gb3JkZXIgdG8gZW5hYmxlIGEgemVyby1kb3dudGltZSBkZXBsb3ltZW50LCB3ZSB1c2UgYSBuZXcgc3ViZGlyZWN0b3J5IChyZXZpc2lvbikgZm9yIGV2ZXJ5IGRlcGxveW1lbnQuXG4gICAqIFRoZSBwcmV2aW91cyB2ZXJzaW9ucyBhcmUgcmV0YWluZWQgdG8gYWxsb3cgY2xpZW50cyB0byBjb250aW51ZSB0byB3b3JrIHdpdGggYW4gb2xkZXIgcmV2aXNpb24uXG4gICAqL1xuICBwcml2YXRlIGNvbmZpZ3VyZURlcGxveW1lbnRzKCk6IEJ1Y2tldERlcGxveW1lbnRbXSB7XG4gICAgY29uc3QgZGVmYXVsdENhY2hlQ29uZmlnID0gW1xuICAgICAgQ2FjaGVDb250cm9sLnNldFB1YmxpYygpLFxuICAgICAgQ2FjaGVDb250cm9sLm1heEFnZShEdXJhdGlvbi5kYXlzKDM2NSkpLFxuICAgICAgQ2FjaGVDb250cm9sLmZyb21TdHJpbmcoJ2ltbXV0YWJsZScpLFxuICAgIF07XG5cbiAgICAvLyBSZXR1cm5zIGEgZGVwbG95bWVudCBmb3IgZXZlcnkgY29uZmlndXJlZCBzdGF0aWMgYXNzZXQgdHlwZSB0byByZXNwZWN0IHRoZSBkaWZmZXJlbnQgY2FjaGUgc2V0dGluZ3NcbiAgICByZXR1cm4gTnV4dEFwcFN0YXRpY0Fzc2V0cy5maWx0ZXIoYXNzZXQgPT4gZnMuZXhpc3RzU3luYyhhc3NldC5zb3VyY2UpKS5tYXAoKGFzc2V0LCBhc3NldEluZGV4KSA9PiB7XG4gICAgICByZXR1cm4gbmV3IEJ1Y2tldERlcGxveW1lbnQodGhpcywgYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1hc3NldHMtZGVwbG95bWVudC0ke2Fzc2V0SW5kZXh9YCwge1xuICAgICAgICBzb3VyY2VzOiBbU291cmNlLmFzc2V0KGFzc2V0LnNvdXJjZSldLFxuICAgICAgICBkZXN0aW5hdGlvbkJ1Y2tldDogdGhpcy5zdGF0aWNBc3NldHNCdWNrZXQsXG4gICAgICAgIGRlc3RpbmF0aW9uS2V5UHJlZml4OiB0aGlzLmRlcGxveW1lbnRSZXZpc2lvbiArIGFzc2V0LnRhcmdldCxcbiAgICAgICAgcHJ1bmU6IGZhbHNlLFxuICAgICAgICBzdG9yYWdlQ2xhc3M6IFN0b3JhZ2VDbGFzcy5TVEFOREFSRCxcbiAgICAgICAgZXhjbHVkZTogWycqJ10sXG4gICAgICAgIGluY2x1ZGU6IFthc3NldC5wYXR0ZXJuXSxcbiAgICAgICAgY2FjaGVDb250cm9sOiBhc3NldC5jYWNoZUNvbnRyb2wgPz8gZGVmYXVsdENhY2hlQ29uZmlnLFxuICAgICAgICBjb250ZW50VHlwZTogYXNzZXQuY29udGVudFR5cGUsXG4gICAgICB9KVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kSG9zdGVkWm9uZShwcm9wczogTnV4dEFwcFN0YWNrUHJvcHMpOiBJSG9zdGVkWm9uZSB7XG4gICAgY29uc3QgZG9tYWluUGFydHMgPSBwcm9wcy5kb21haW4uc3BsaXQoJy4nKTtcblxuICAgIHJldHVybiBIb3N0ZWRab25lLmZyb21Ib3N0ZWRab25lQXR0cmlidXRlcyh0aGlzLCBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWhvc3RlZC16b25lYCwge1xuICAgICAgaG9zdGVkWm9uZUlkOiBwcm9wcy5ob3N0ZWRab25lSWQsXG4gICAgICB6b25lTmFtZTogZG9tYWluUGFydHNbZG9tYWluUGFydHMubGVuZ3RoIC0gMV0sIC8vIFN1cHBvcnQgc3ViZG9tYWluc1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVEbnNSZWNvcmRzKHByb3BzOiBOdXh0QXBwU3RhY2tQcm9wcyk6IHZvaWQge1xuICAgIGNvbnN0IGRuc1RhcmdldCA9IFJlY29yZFRhcmdldC5mcm9tQWxpYXMobmV3IENsb3VkRnJvbnRUYXJnZXQodGhpcy5jZG4pKTtcblxuICAgIC8vIENyZWF0ZSBhIHJlY29yZCBmb3IgSVB2NFxuICAgIG5ldyBBUmVjb3JkKHRoaXMsIGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0taXB2NC1yZWNvcmRgLCB7XG4gICAgICByZWNvcmROYW1lOiBwcm9wcy5kb21haW4sXG4gICAgICB6b25lOiB0aGlzLmhvc3RlZFpvbmUsXG4gICAgICB0YXJnZXQ6IGRuc1RhcmdldCxcbiAgICB9KTtcblxuICAgIC8vIENyZWF0ZSBhIHJlY29yZCBmb3IgSVB2NlxuICAgIG5ldyBBYWFhUmVjb3JkKHRoaXMsIGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0taXB2Ni1yZWNvcmRgLCB7XG4gICAgICByZWNvcmROYW1lOiBwcm9wcy5kb21haW4sXG4gICAgICB6b25lOiB0aGlzLmhvc3RlZFpvbmUsXG4gICAgICB0YXJnZXQ6IGRuc1RhcmdldCxcbiAgICB9KTtcbiAgfVxufVxuIl19
306
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnV4dC1hcHAtc3RhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJudXh0LWFwcC1zdGFjay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBMkQ7QUFFM0QsK0VBQTZFO0FBQzdFLCtEQVNvQztBQUNwQyx1REFBMkY7QUFDM0YsK0NBQTJGO0FBQzNGLHlEQUFtRztBQUNuRyxxRUFBbUc7QUFDbkcsK0VBQXdFO0FBQ3hFLHlFQUFpRTtBQUNqRSxpRkFBK0Q7QUFDL0QsbURBQW1EO0FBQ25ELHNHQUFxRjtBQUNyRiw0RUFBd0Q7QUFDeEQscUVBQXlGO0FBRXpGLHlCQUF5QjtBQUN6Qix1REFBc0Q7QUFDdEQsdUVBQThEO0FBaUM5RDs7R0FFRztBQUNILE1BQWEsWUFBYSxTQUFRLG1CQUFLO0lBaUVyQyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXdCO1FBQ2hFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXhCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxHQUFHLEtBQUssQ0FBQyxPQUFPLElBQUksS0FBSyxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDakYsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUEscURBQTRCLEVBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3pFLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUN4RCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFDMUQsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENB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QUFjO1FBQ3BCLElBQUksaUJBQUksQ0FBQyxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLGNBQWMsRUFBRTtZQUNyRCxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLFNBQVM7WUFDM0MsV0FBVyxFQUFFLG9DQUFvQyxJQUFJLENBQUMsZ0JBQWdCLHVDQUF1QztZQUM3RyxPQUFPLEVBQUUsSUFBSTtZQUNiLFFBQVEsRUFBRSxxQkFBUSxDQUFDLElBQUksQ0FBQyxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM1QyxPQUFPLEVBQUUsQ0FBQyxJQUFJLG1DQUFjLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1NBQ25ELENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQW5YRCxvQ0FtWEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0R1cmF0aW9uLCBSZW1vdmFsUG9saWN5LCBTdGFja30gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQge0NlcnRpZmljYXRlLCBJQ2VydGlmaWNhdGV9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2VydGlmaWNhdGVtYW5hZ2VyXCI7XG5pbXBvcnQge1xuICBBbGxvd2VkTWV0aG9kcyxcbiAgQmVoYXZpb3JPcHRpb25zLCBDYWNoZUNvb2tpZUJlaGF2aW9yLFxuICBDYWNoZWRNZXRob2RzLCBDYWNoZUhlYWRlckJlaGF2aW9yLFxuICBDYWNoZVBvbGljeSwgQ2FjaGVRdWVyeVN0cmluZ0JlaGF2aW9yLFxuICBEaXN0cmlidXRpb24sIElDYWNoZVBvbGljeSxcbiAgSU9yaWdpbkFjY2Vzc0lkZW50aXR5LCBPcmlnaW5BY2Nlc3NJZGVudGl0eSwgT3JpZ2luUHJvdG9jb2xQb2xpY3ksIFByaWNlQ2xhc3MsXG4gIFNlY3VyaXR5UG9saWN5UHJvdG9jb2wsXG4gIFZpZXdlclByb3RvY29sUG9saWN5XG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWRmcm9udFwiO1xuaW1wb3J0IHtBcmNoaXRlY3R1cmUsIENvZGUsIExheWVyVmVyc2lvbiwgUnVudGltZSwgRnVuY3Rpb259IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhXCI7XG5pbXBvcnQge0Jsb2NrUHVibGljQWNjZXNzLCBCdWNrZXQsIEJ1Y2tldEFjY2Vzc0NvbnRyb2wsIElCdWNrZXR9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7QVJlY29yZCwgQWFhYVJlY29yZCwgSG9zdGVkWm9uZSwgSUhvc3RlZFpvbmUsIFJlY29yZFRhcmdldH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1yb3V0ZTUzXCI7XG5pbXBvcnQge0J1Y2tldERlcGxveW1lbnQsIENhY2hlQ29udHJvbCwgU291cmNlLCBTdG9yYWdlQ2xhc3N9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczMtZGVwbG95bWVudFwiO1xuaW1wb3J0IHtIdHRwT3JpZ2luLCBTM09yaWdpbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZGZyb250LW9yaWdpbnNcIjtcbmltcG9ydCB7Q2xvdWRGcm9udFRhcmdldH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1yb3V0ZTUzLXRhcmdldHNcIjtcbmltcG9ydCB7SHR0cE1ldGhvZH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zdGVwZnVuY3Rpb25zLXRhc2tzXCI7XG5pbXBvcnQge1JldGVudGlvbkRheXN9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbG9nc1wiO1xuaW1wb3J0IHsgSHR0cExhbWJkYUludGVncmF0aW9uIH0gZnJvbSAnQGF3cy1jZGsvYXdzLWFwaWdhdGV3YXl2Mi1pbnRlZ3JhdGlvbnMtYWxwaGEnO1xuaW1wb3J0IHtIdHRwQXBpfSBmcm9tIFwiQGF3cy1jZGsvYXdzLWFwaWdhdGV3YXl2Mi1hbHBoYVwiO1xuaW1wb3J0IHtnZXROdXh0QXBwU3RhdGljQXNzZXRDb25maWdzLCBTdGF0aWNBc3NldENvbmZpZ30gZnJvbSBcIi4vbnV4dC1hcHAtc3RhdGljLWFzc2V0c1wiO1xuaW1wb3J0IHtBcHBTdGFja1Byb3BzfSBmcm9tIFwiLi9hcHAtc3RhY2stcHJvcHNcIjtcbmltcG9ydCAqIGFzIGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHtSdWxlLCBTY2hlZHVsZX0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1ldmVudHNcIjtcbmltcG9ydCB7TGFtYmRhRnVuY3Rpb259IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZXZlbnRzLXRhcmdldHNcIjtcbmltcG9ydCB7TnV4dENvbmZpZ30gZnJvbSBcIi4vbnV4dC1jb25maWdcIjtcblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBwcm9wcyByZXF1aXJlZCBmb3IgdGhlIHtAc2VlIE51eHRBcHBTdGFja30uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTnV4dEFwcFN0YWNrUHJvcHMgZXh0ZW5kcyBBcHBTdGFja1Byb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBkb21haW4gKHdpdGhvdXQgdGhlIHByb3RvY29sKSBhdCB3aGljaCB0aGUgTnV4dCBhcHAgc2hhbGwgYmUgcHVibGljbHkgYXZhaWxhYmxlLlxuICAgKiBBIEROUyByZWNvcmQgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGNyZWF0ZWQgaW4gUm91dGU1MyBmb3IgdGhlIGRvbWFpbi5cbiAgICogVGhpcyBhbHNvIHN1cHBvcnRzIHN1YmRvbWFpbnMuXG4gICAqIEV4YW1wbGVzOiBcImV4YW1wbGUuY29tXCIsIFwic3ViLmV4YW1wbGUuY29tXCJcbiAgICovXG4gIHJlYWRvbmx5IGRvbWFpbjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgaWQgb2YgdGhlIGhvc3RlZCB6b25lIHRvIGNyZWF0ZSBhIEROUyByZWNvcmQgZm9yIHRoZSBzcGVjaWZpZWQgZG9tYWluLlxuICAgKi9cbiAgcmVhZG9ubHkgaG9zdGVkWm9uZUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBBUk4gb2YgdGhlIGNlcnRpZmljYXRlIHRvIHVzZSBmb3IgdGhlIE51eHQgYXBwIHRvIG1ha2UgaXQgYWNjZXNzaWJsZSB2aWEgSFRUUFMuXG4gICAqIFRoZSBjZXJ0aWZpY2F0ZSBtdXN0IGJlIGlzc3VlZCBmb3IgdGhlIHNwZWNpZmllZCBkb21haW4gaW4gdXMtZWFzdC0xIChnbG9iYWwpIHJlZ2FyZGxlc3Mgb2YgdGhlXG4gICAqIHJlZ2lvbiB1c2VkIGZvciB0aGUgTnV4dCBhcHAgaXRzZWxmLlxuICAgKi9cbiAgcmVhZG9ubHkgZ2xvYmFsVGxzQ2VydGlmaWNhdGVBcm46IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG51eHQuY29uZmlnLmpzIG9mIHRoZSBOdXh0IGFwcC5cbiAgICovXG4gIHJlYWRvbmx5IG51eHRDb25maWc6IE51eHRDb25maWc7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGxhbWJkYSBmdW5jdGlvbiB0aGF0IHJlbmRlcnMgdGhlIE51eHQgYXBwIGFuZCBpcyBwdWJsaWNseSByZWFjaGFibGUgdmlhIGEgc3BlY2lmaWVkIGRvbWFpbi5cbiAqL1xuZXhwb3J0IGNsYXNzIE51eHRBcHBTdGFjayBleHRlbmRzIFN0YWNrIHtcblxuICAvKipcbiAgICogVGhlIGlkZW50aWZpZXIgcHJlZml4IG9mIHRoZSByZXNvdXJjZXMgY3JlYXRlZCBieSB0aGUgc3RhY2suXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHJlc291cmNlSWRQcmVmaXg6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGlkZW50aWZpZXIgZm9yIHRoZSBjdXJyZW50IGRlcGxveW1lbnQgdGhhdCBpcyB1c2VkIGFzIFMzIGZvbGRlciBuYW1lXG4gICAqIHRvIHN0b3JlIHRoZSBzdGF0aWMgYXNzZXRzIG9mIHRoZSBOdXh0IGFwcC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZGVwbG95bWVudFJldmlzaW9uOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBjZXJ0aWZpY2F0ZSB0byB1c2UgZm9yIHRoZSBOdXh0IGFwcCB0byBtYWtlIGl0IGFjY2Vzc2libGUgdmlhIEhUVFBTLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSB0bHNDZXJ0aWZpY2F0ZTogSUNlcnRpZmljYXRlO1xuXG4gIC8qKlxuICAgKiBUaGUgaWRlbnRpdHkgdG8gdXNlIGZvciBhY2Nlc3NpbmcgdGhlIGRlcGxveW1lbnQgYXNzZXRzIG9uIFMzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjZG5BY2Nlc3NJZGVudGl0eTogSU9yaWdpbkFjY2Vzc0lkZW50aXR5O1xuXG4gIC8qKlxuICAgKiBUaGUgUzMgYnVja2V0IHdoZXJlIHRoZSBkZXBsb3ltZW50IGFzc2V0cyBnZXRzIHN0b3JlZC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWNBc3NldHNCdWNrZXQ6IElCdWNrZXQ7XG5cbiAgLyoqXG4gICAqIFRoZSBsYW1iZGEgZnVuY3Rpb24gdG8gcmVuZGVyIHRoZSBOdXh0IGFwcCBvbiB0aGUgc2VydmVyIHNpZGUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGxhbWJkYUZ1bmN0aW9uOiBGdW5jdGlvbjtcblxuICAvKipcbiAgICogVGhlIEFQSSBnYXRld2F5IHRvIG1ha2UgdGhlIGxhbWJkYSBmdW5jdGlvbiB0byByZW5kZXIgdGhlIE51eHQgYXBwIHB1YmxpY2x5IGF2YWlsYWJsZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgYXBpR2F0ZXdheTogSHR0cEFwaTtcblxuICAvKipcbiAgICogVGhlIGNvbmZpZ3MgZm9yIHRoZSBzdGF0aWMgYXNzZXRzIG9mIHRoZSBOdXh0IGFwcCB0aGF0IHNoYWxsIGJlIHB1YmxpY2x5IGF2YWlsYWJsZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgc3RhdGljQXNzZXRDb25maWdzOiBTdGF0aWNBc3NldENvbmZpZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgY2xvdWRmcm9udCBkaXN0cmlidXRpb24gdG8gcm91dGUgaW5jb21pbmcgcmVxdWVzdHMgdG8gdGhlIE51eHQgbGFtYmRhIGZ1bmN0aW9uICh2aWEgdGhlIEFQSSBnYXRld2F5KVxuICAgKiBvciB0aGUgUzMgYXNzZXRzIGZvbGRlciAod2l0aCBjYWNoaW5nKS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgY2RuOiBEaXN0cmlidXRpb247XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE51eHRBcHBTdGFja1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCBwcm9wcyk7XG5cbiAgICB0aGlzLnJlc291cmNlSWRQcmVmaXggPSBgJHtwcm9wcy5wcm9qZWN0fS0ke3Byb3BzLnNlcnZpY2V9LSR7cHJvcHMuZW52aXJvbm1lbnR9YDtcbiAgICB0aGlzLmRlcGxveW1lbnRSZXZpc2lvbiA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICB0aGlzLnN0YXRpY0Fzc2V0Q29uZmlncyA9IGdldE51eHRBcHBTdGF0aWNBc3NldENvbmZpZ3MocHJvcHMubnV4dENvbmZpZyk7XG4gICAgdGhpcy50bHNDZXJ0aWZpY2F0ZSA9IHRoaXMuZmluZFRsc0NlcnRpZmljYXRlKHByb3BzKTtcbiAgICB0aGlzLmNkbkFjY2Vzc0lkZW50aXR5ID0gdGhpcy5jcmVhdGVDZG5BY2Nlc3NJZGVudGl0eSgpO1xuICAgIHRoaXMuc3RhdGljQXNzZXRzQnVja2V0ID0gdGhpcy5jcmVhdGVTdGF0aWNBc3NldHNCdWNrZXQoKTtcbiAgICB0aGlzLmxhbWJkYUZ1bmN0aW9uID0gdGhpcy5jcmVhdGVMYW1iZGFGdW5jdGlvbigpO1xuICAgIHRoaXMuYXBpR2F0ZXdheSA9IHRoaXMuY3JlYXRlQXBpR2F0ZXdheSgpO1xuICAgIHRoaXMuY2RuID0gdGhpcy5jcmVhdGVDbG91ZEZyb250RGlzdHJpYnV0aW9uKHByb3BzKTtcbiAgICB0aGlzLmNvbmZpZ3VyZURlcGxveW1lbnRzKCk7XG4gICAgdGhpcy5jcmVhdGVEbnNSZWNvcmRzKHByb3BzKTtcbiAgICB0aGlzLmNyZWF0ZVBpbmdSdWxlKCk7XG4gIH1cblxuICAvKipcbiAgICogRmluZHMgdGhlIGNlcnRpZmljYXRlIHRvIHVzZSBmb3IgcHJvdmlkaW5nIEhUVFBTIHJlcXVlc3RzIHRvIG91ciBOdXh0IGFwcC5cbiAgICpcbiAgICogQHBhcmFtIHByb3BzXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGZpbmRUbHNDZXJ0aWZpY2F0ZShwcm9wczogTnV4dEFwcFN0YWNrUHJvcHMpOiBJQ2VydGlmaWNhdGUge1xuICAgIHJldHVybiBDZXJ0aWZpY2F0ZS5mcm9tQ2VydGlmaWNhdGVBcm4odGhpcywgYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS10bHMtY2VydGlmaWNhdGVgLCBwcm9wcy5nbG9iYWxUbHNDZXJ0aWZpY2F0ZUFybik7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgaWRlbnRpdHkgdG8gYWNjZXNzIG91ciBTMyBkZXBsb3ltZW50IGFzc2V0IGZpbGVzIHZpYSB0aGUgY2xvdWRmcm9udCBkaXN0cmlidXRpb24uXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZUNkbkFjY2Vzc0lkZW50aXR5KCk6IElPcmlnaW5BY2Nlc3NJZGVudGl0eSB7XG4gICAgY29uc3Qgb3JpZ2luQWNjZXNzSWRlbnRpdHlOYW1lID0gYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1jZG4tczMtYWNjZXNzYDtcbiAgICByZXR1cm4gbmV3IE9yaWdpbkFjY2Vzc0lkZW50aXR5KHRoaXMsIG9yaWdpbkFjY2Vzc0lkZW50aXR5TmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgYnVja2V0IHRvIHN0b3JlIHRoZSBzdGF0aWMgZGVwbG95bWVudCBhc3NldCBmaWxlcyBvZiB0aGUgTnV4dCBhcHAuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZVN0YXRpY0Fzc2V0c0J1Y2tldCgpOiBJQnVja2V0IHtcbiAgICBjb25zdCBidWNrZXROYW1lID0gYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1hc3NldHNgO1xuICAgIGNvbnN0IGJ1Y2tldCA9IG5ldyBCdWNrZXQodGhpcywgYnVja2V0TmFtZSwge1xuICAgICAgYWNjZXNzQ29udHJvbDogQnVja2V0QWNjZXNzQ29udHJvbC5BVVRIRU5USUNBVEVEX1JFQUQsXG4gICAgICBibG9ja1B1YmxpY0FjY2VzczogQmxvY2tQdWJsaWNBY2Nlc3MuQkxPQ0tfQUxMLFxuICAgICAgYnVja2V0TmFtZSxcbiAgICAgIC8vIFRoZSBidWNrZXQgYW5kIGFsbCBvZiBpdHMgb2JqZWN0cyBjYW4gYmUgZGVsZXRlZCwgYmVjYXVzZSBhbGwgdGhlIGNvbnRlbnQgaXMgbWFuYWdlZCBpbiB0aGlzIHByb2plY3RcbiAgICAgIHJlbW92YWxQb2xpY3k6IFJlbW92YWxQb2xpY3kuREVTVFJPWSxcbiAgICAgIGF1dG9EZWxldGVPYmplY3RzOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgYnVja2V0LmdyYW50UmVhZFdyaXRlKHRoaXMuY2RuQWNjZXNzSWRlbnRpdHkpO1xuXG4gICAgcmV0dXJuIGJ1Y2tldDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbGFtYmRhIGxheWVyIHdpdGggdGhlIG5vZGVfbW9kdWxlcyByZXF1aXJlZCB0byByZW5kZXIgdGhlIE51eHQgYXBwIG9uIHRoZSBzZXJ2ZXIgc2lkZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgY3JlYXRlU3NyTGFtYmRhTGF5ZXIoKTogTGF5ZXJWZXJzaW9uIHtcbiAgICBjb25zdCBsYXllck5hbWUgPSBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LXNzci1sYXllcmA7XG4gICAgcmV0dXJuIG5ldyBMYXllclZlcnNpb24odGhpcywgbGF5ZXJOYW1lLCB7XG4gICAgICBsYXllclZlcnNpb25OYW1lOiBsYXllck5hbWUsXG4gICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldCgnLm51eHQvY2RrLWRlcGxveW1lbnQvbGF5ZXInKSxcbiAgICAgIGNvbXBhdGlibGVSdW50aW1lczogW1J1bnRpbWUuTk9ERUpTXzEyX1hdLFxuICAgICAgZGVzY3JpcHRpb246IGBQcm92aWRlcyB0aGUgbm9kZV9tb2R1bGVzIHJlcXVpcmVkIGZvciBTU1Igb2YgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LmAsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgbGFtYmRhIGZ1bmN0aW9uIHRvIHJlbmRlciB0aGUgTnV4dCBhcHAuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZUxhbWJkYUZ1bmN0aW9uKCk6IEZ1bmN0aW9uIHtcbiAgICBjb25zdCBmdW5jTmFtZSA9IGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tZnVuY3Rpb25gO1xuXG4gICAgcmV0dXJuIG5ldyBGdW5jdGlvbih0aGlzLCBmdW5jTmFtZSwge1xuICAgICAgZnVuY3Rpb25OYW1lOiBmdW5jTmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBgUmVuZGVycyB0aGUgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9IE51eHQgYXBwLmAsXG4gICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18xMl9YLFxuICAgICAgYXJjaGl0ZWN0dXJlOiBBcmNoaXRlY3R1cmUuQVJNXzY0LFxuICAgICAgbGF5ZXJzOiBbdGhpcy5jcmVhdGVTc3JMYW1iZGFMYXllcigpXSxcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUFzc2V0KCcubnV4dC9jZGstZGVwbG95bWVudC9zcmMnLCB7XG4gICAgICAgIGV4Y2x1ZGU6IFsnKiouc3ZnJywgJyoqLmljbycsICcqKi5wbmcnLCAnKiouanBnJywgJ2NodW5rLiouanMqJywgJ2J1bmRsZS4qLmpzKicsICdidW5kbGUuKi5qcyonLCAnc3cuanMqJ10sXG4gICAgICB9KSxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoMTApLFxuICAgICAgbWVtb3J5U2l6ZTogNTEyLFxuICAgICAgbG9nUmV0ZW50aW9uOiBSZXRlbnRpb25EYXlzLk9ORV9NT05USCxcbiAgICAgIGFsbG93UHVibGljU3VibmV0OiBmYWxzZVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgdGhlIEFQSSBnYXRld2F5IHRvIG1ha2UgdGhlIE51eHQgYXBwIHJlbmRlciBsYW1iZGEgZnVuY3Rpb24gcHVibGljbHkgYXZhaWxhYmxlLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVBcGlHYXRld2F5KCk6IEh0dHBBcGkge1xuICAgIGNvbnN0IGxhbWJkYUludGVncmF0aW9uID0gbmV3IEh0dHBMYW1iZGFJbnRlZ3JhdGlvbihgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWxhbWJkYS1pbnRlZ3JhdGlvbmAsIHRoaXMubGFtYmRhRnVuY3Rpb24pO1xuICAgIGNvbnN0IGFwaU5hbWUgPSBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWFwaWA7XG4gICAgY29uc3QgYXBpR2F0ZXdheSA9IG5ldyBIdHRwQXBpKHRoaXMsIGFwaU5hbWUsIHtcbiAgICAgIGFwaU5hbWUsXG4gICAgICBkZXNjcmlwdGlvbjogYENvbm5lY3RzIHRoZSAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0gY2xvdWRmcm9udCBkaXN0cmlidXRpb24gd2l0aCB0aGUgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9IGxhbWJkYSBmdW5jdGlvbiB0byBtYWtlIGl0IHB1YmxpY2x5IGF2YWlsYWJsZS5gLFxuICAgICAgLy8gVGhlIGFwcCBkb2VzIG5vdCBhbGxvdyBhbnkgY3Jvc3Mtb3JpZ2luIGFjY2VzcyBieSBwdXJwb3NlOiB0aGUgYXBwIHNob3VsZCBub3QgYmUgZW1iZWRkYWJsZSBhbnl3aGVyZVxuICAgICAgY29yc1ByZWZsaWdodDogdW5kZWZpbmVkLFxuICAgICAgZGVmYXVsdEludGVncmF0aW9uOiBsYW1iZGFJbnRlZ3JhdGlvbixcbiAgICB9KTtcblxuICAgIGFwaUdhdGV3YXkuYWRkUm91dGVzKHtcbiAgICAgIGludGVncmF0aW9uOiBsYW1iZGFJbnRlZ3JhdGlvbixcbiAgICAgIHBhdGg6ICcve3Byb3h5K30nLFxuICAgICAgbWV0aG9kczogW0h0dHBNZXRob2QuR0VULCBIdHRwTWV0aG9kLkhFQURdLFxuICAgIH0pO1xuICAgIHJldHVybiBhcGlHYXRld2F5O1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgdGhlIGNsb3VkZnJvbnQgZGlzdHJpYnV0aW9uIHRoYXQgcm91dGVzIGluY29taW5nIHJlcXVlc3RzIHRvIHRoZSBOdXh0IGxhbWJkYSBmdW5jdGlvbiAodmlhIHRoZSBBUEkgZ2F0ZXdheSlcbiAgICogb3IgdGhlIFMzIGFzc2V0cyBmb2xkZXIgKHdpdGggY2FjaGluZykuXG4gICAqXG4gICAqIEBwYXJhbSBwcm9wc1xuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVDbG91ZEZyb250RGlzdHJpYnV0aW9uKHByb3BzOiBOdXh0QXBwU3RhY2tQcm9wcyk6IERpc3RyaWJ1dGlvbiB7XG4gICAgY29uc3QgY2RuTmFtZSA9IGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tY2RuYDtcblxuICAgIHJldHVybiBuZXcgRGlzdHJpYnV0aW9uKHRoaXMsIGNkbk5hbWUsIHtcbiAgICAgIGRvbWFpbk5hbWVzOiBbcHJvcHMuZG9tYWluXSxcbiAgICAgIGNvbW1lbnQ6IGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tcmVkaXJlY3RgLFxuICAgICAgbWluaW11bVByb3RvY29sVmVyc2lvbjogU2VjdXJpdHlQb2xpY3lQcm90b2NvbC5UTFNfVjFfMl8yMDE4LFxuICAgICAgY2VydGlmaWNhdGU6IHRoaXMudGxzQ2VydGlmaWNhdGUsXG4gICAgICBkZWZhdWx0QmVoYXZpb3I6IHRoaXMuY3JlYXRlTnV4dEFwcFJvdXRlQmVoYXZpb3IoKSxcbiAgICAgIGFkZGl0aW9uYWxCZWhhdmlvcnM6IHRoaXMuY3JlYXRlU3RhdGljQXNzZXRzUm91dGVCZWhhdmlvcigpLFxuICAgICAgcHJpY2VDbGFzczogUHJpY2VDbGFzcy5QUklDRV9DTEFTU18xMDAsIC8vIFVzZSBvbmx5IE5vcnRoIEFtZXJpY2EgYW5kIEV1cm9wZVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBiZWhhdmlvciBmb3IgdGhlIGNsb3VkZnJvbnQgZGlzdHJpYnV0aW9uIHRvIHJvdXRlIGluY29taW5nIHJlcXVlc3RzIHRvIHRoZSBOdXh0IHJlbmRlciBsYW1iZGEgZnVuY3Rpb24gKHZpYSBBUEkgZ2F0ZXdheSkuXG4gICAqIEFkZGl0aW9uYWxseSwgdGhpcyBhdXRvbWF0aWNhbGx5IHJlZGlyZWN0cyBIVFRQIHJlcXVlc3RzIHRvIEhUVFBTLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVOdXh0QXBwUm91dGVCZWhhdmlvcigpOiBCZWhhdmlvck9wdGlvbnMge1xuICAgIHJldHVybiB7XG4gICAgICBvcmlnaW46IG5ldyBIdHRwT3JpZ2luKGAke3RoaXMuYXBpR2F0ZXdheS5odHRwQXBpSWR9LmV4ZWN1dGUtYXBpLiR7dGhpcy5yZWdpb259LmFtYXpvbmF3cy5jb21gLCB7XG4gICAgICAgIGNvbm5lY3Rpb25BdHRlbXB0czogMixcbiAgICAgICAgY29ubmVjdGlvblRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoMiksXG4gICAgICAgIHJlYWRUaW1lb3V0OiBEdXJhdGlvbi5zZWNvbmRzKDEwKSxcbiAgICAgICAgcHJvdG9jb2xQb2xpY3k6IE9yaWdpblByb3RvY29sUG9saWN5LkhUVFBTX09OTFksXG4gICAgICB9KSxcbiAgICAgIGFsbG93ZWRNZXRob2RzOiBBbGxvd2VkTWV0aG9kcy5BTExPV19HRVRfSEVBRCxcbiAgICAgIGNvbXByZXNzOiB0cnVlLFxuICAgICAgdmlld2VyUHJvdG9jb2xQb2xpY3k6IFZpZXdlclByb3RvY29sUG9saWN5LlJFRElSRUNUX1RPX0hUVFBTLFxuICAgICAgb3JpZ2luUmVxdWVzdFBvbGljeTogdW5kZWZpbmVkLFxuICAgICAgY2FjaGVQb2xpY3k6IHRoaXMuY3JlYXRlU3NyQ2FjaGVQb2xpY3koKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBjYWNoZSBwb2xpY3kgZm9yIHRoZSBOdXh0IGFwcCByb3V0ZSBiZWhhdmlvciBvZiBvdXIgY2xvdWRmcm9udCBkaXN0cmlidXRpb24uXG4gICAqIEV2ZW50aG91Z2ggd2UgZG9uJ3Qgd2FudCB0byBjYWNoZSBTU1IgcmVxdWVzdHMsIHdlIHN0aWxsIGhhdmUgdG8gY3JlYXRlIHRoaXMgY2FjaGUgcG9saWN5IGluIG9yZGVyIHRvXG4gICAqIGZvcndhcmQgcmVxdWlyZWQgY29va2llcywgcXVlcnkgcGFyYW1zIGFuZCBoZWFkZXJzLiBUaGlzIGRvZXNuJ3QgbWFrZSBhbnkgc2Vuc2UsIGJlY2F1c2UgaWYgbm90aGluZ1xuICAgKiBpcyBjYWNoZWQsIG9uZSB3b3VsZCBleHBlY3QsIHRoYXQgYW55dGhpbmcgd291bGQvY291bGQgYmUgZm9yd2FyZGVkLCBidXQgYW55d2F5Li4uXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZVNzckNhY2hlUG9saWN5KCk6IElDYWNoZVBvbGljeSB7XG5cbiAgICAvLyBUaGUgaGVhZGVycyB0byBtYWtlIGFjY2Vzc2libGUgaW4gb3VyIE51eHQgYXBwIGNvZGVcbiAgICBjb25zdCBoZWFkZXJzID0gW1xuICAgICAgJ1VzZXItQWdlbnQnLCAvLyBSZXF1aXJlZCB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIG1vYmlsZSBhbmQgZGVza3RvcCB0ZW1wbGF0ZVxuICAgICAgJ0F1dGhvcml6YXRpb24nLCAvLyBGb3IgYXV0aG9yaXphdGlvblxuICAgIF07XG5cbiAgICByZXR1cm4gbmV3IENhY2hlUG9saWN5KHRoaXMsIGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tY2FjaGUtcG9saWN5YCwge1xuICAgICAgY2FjaGVQb2xpY3lOYW1lOiBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWNkbi1jYWNoZS1wb2xpY3lgLFxuICAgICAgY29tbWVudDogYFBhc3NlcyBhbGwgcmVxdWlyZWQgcmVxdWVzdCBkYXRhIHRvIHRoZSAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0gb3JpZ2luLmAsXG4gICAgICBkZWZhdWx0VHRsOiBEdXJhdGlvbi5zZWNvbmRzKDApLFxuICAgICAgbWluVHRsOiBEdXJhdGlvbi5zZWNvbmRzKDApLFxuICAgICAgbWF4VHRsOiBEdXJhdGlvbi5zZWNvbmRzKDEpLCAvLyBUaGUgbWF4IFRUTCBtdXN0IG5vdCBiZSAwIGZvciBhIGNhY2hlIHBvbGljeVxuICAgICAgcXVlcnlTdHJpbmdCZWhhdmlvcjogQ2FjaGVRdWVyeVN0cmluZ0JlaGF2aW9yLmFsbCgpLFxuICAgICAgaGVhZGVyQmVoYXZpb3I6IENhY2hlSGVhZGVyQmVoYXZpb3IuYWxsb3dMaXN0KC4uLmhlYWRlcnMpLFxuICAgICAgY29va2llQmVoYXZpb3I6IENhY2hlQ29va2llQmVoYXZpb3IuYWxsKCksXG4gICAgICBlbmFibGVBY2NlcHRFbmNvZGluZ0Jyb3RsaTogdHJ1ZSxcbiAgICAgIGVuYWJsZUFjY2VwdEVuY29kaW5nR3ppcDogdHJ1ZSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgYmVoYXZpb3IgZm9yIHRoZSBjbG91ZGZyb250IGRpc3RyaWJ1dGlvbiB0byByb3V0ZSBtYXRjaGluZyBpbmNvbWluZyByZXF1ZXN0cyBmb3Igb3VyIHN0YXRpYyBhc3NldHNcbiAgICogdG8gdGhlIFMzIGJ1Y2tldCB0aGF0IGhvbGRzIHRoZXNlIHN0YXRpYyBhc3NldHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZVN0YXRpY0Fzc2V0c1JvdXRlQmVoYXZpb3IoKTogUmVjb3JkPHN0cmluZywgQmVoYXZpb3JPcHRpb25zPiB7XG4gICAgY29uc3Qgc3RhdGljQXNzZXRzQ2FjaGVDb25maWc6IEJlaGF2aW9yT3B0aW9ucyA9IHtcbiAgICAgIG9yaWdpbjogbmV3IFMzT3JpZ2luKHRoaXMuc3RhdGljQXNzZXRzQnVja2V0LCB7XG4gICAgICAgIGNvbm5lY3Rpb25BdHRlbXB0czogMixcbiAgICAgICAgY29ubmVjdGlvblRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoMyksXG4gICAgICAgIG9yaWdpbkFjY2Vzc0lkZW50aXR5OiB0aGlzLmNkbkFjY2Vzc0lkZW50aXR5LFxuICAgICAgICBvcmlnaW5QYXRoOiB0aGlzLmRlcGxveW1lbnRSZXZpc2lvbixcbiAgICAgIH0pLFxuICAgICAgY29tcHJlc3M6IHRydWUsXG4gICAgICBhbGxvd2VkTWV0aG9kczogQWxsb3dlZE1ldGhvZHMuQUxMT1dfR0VUX0hFQURfT1BUSU9OUyxcbiAgICAgIGNhY2hlZE1ldGhvZHM6IENhY2hlZE1ldGhvZHMuQ0FDSEVfR0VUX0hFQURfT1BUSU9OUyxcbiAgICAgIGNhY2hlUG9saWN5OiBDYWNoZVBvbGljeS5DQUNISU5HX09QVElNSVpFRCxcbiAgICAgIHZpZXdlclByb3RvY29sUG9saWN5OiBWaWV3ZXJQcm90b2NvbFBvbGljeS5SRURJUkVDVF9UT19IVFRQUyxcbiAgICB9O1xuXG4gICAgY29uc3QgcnVsZXM6IFJlY29yZDxzdHJpbmcsIEJlaGF2aW9yT3B0aW9ucz4gPSB7fTtcbiAgICB0aGlzLnN0YXRpY0Fzc2V0Q29uZmlncy5mb3JFYWNoKGFzc2V0ID0+IHtcbiAgICAgIHJ1bGVzW2Ake2Fzc2V0LnRhcmdldH0ke2Fzc2V0LnBhdHRlcm59YF0gPSBzdGF0aWNBc3NldHNDYWNoZUNvbmZpZ1xuICAgIH0pXG5cbiAgICByZXR1cm4gcnVsZXNcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGxvYWRzIHRoZSBzdGF0aWMgYXNzZXRzIG9mIHRoZSBOdXh0IGFwcCBhcyBkZWZpbmVkIGluIHtAc2VlIGdldE51eHRBcHBTdGF0aWNBc3NldENvbmZpZ3N9IHRvIHRoZSBzdGF0aWMgYXNzZXRzIFMzIGJ1Y2tldC5cbiAgICogSW4gb3JkZXIgdG8gZW5hYmxlIGEgemVyby1kb3dudGltZSBkZXBsb3ltZW50LCB3ZSB1c2UgYSBuZXcgc3ViZGlyZWN0b3J5IChyZXZpc2lvbikgZm9yIGV2ZXJ5IGRlcGxveW1lbnQuXG4gICAqIFRoZSBwcmV2aW91cyB2ZXJzaW9ucyBhcmUgcmV0YWluZWQgdG8gYWxsb3cgY2xpZW50cyB0byBjb250aW51ZSB0byB3b3JrIHdpdGggYW4gb2xkZXIgcmV2aXNpb24gYnV0IGdldHMgY2xlYW5lZCB1cFxuICAgKiBhZnRlciBhIHNwZWNpZmllZCBwZXJpb2Qgb2YgdGltZSB2aWEgdGhlIGxhbWJkYSBmdW5jdGlvbiBpbiB0aGUge0BzZWUgTnV4dEFwcEFzc2V0c0NsZWFudXBTdGFja30uXG4gICAqL1xuICBwcml2YXRlIGNvbmZpZ3VyZURlcGxveW1lbnRzKCk6IEJ1Y2tldERlcGxveW1lbnRbXSB7XG4gICAgY29uc3QgZGVmYXVsdENhY2hlQ29uZmlnID0gW1xuICAgICAgQ2FjaGVDb250cm9sLnNldFB1YmxpYygpLFxuICAgICAgQ2FjaGVDb250cm9sLm1heEFnZShEdXJhdGlvbi5kYXlzKDM2NSkpLFxuICAgICAgQ2FjaGVDb250cm9sLmZyb21TdHJpbmcoJ2ltbXV0YWJsZScpLFxuICAgIF07XG5cbiAgICAvLyBSZXR1cm5zIGEgZGVwbG95bWVudCBmb3IgZXZlcnkgY29uZmlndXJlZCBzdGF0aWMgYXNzZXQgdHlwZSB0byByZXNwZWN0IHRoZSBkaWZmZXJlbnQgY2FjaGUgc2V0dGluZ3NcbiAgICByZXR1cm4gdGhpcy5zdGF0aWNBc3NldENvbmZpZ3MuZmlsdGVyKGFzc2V0ID0+IGZzLmV4aXN0c1N5bmMoYXNzZXQuc291cmNlKSkubWFwKChhc3NldCwgYXNzZXRJbmRleCkgPT4ge1xuICAgICAgcmV0dXJuIG5ldyBCdWNrZXREZXBsb3ltZW50KHRoaXMsIGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tYXNzZXRzLWRlcGxveW1lbnQtJHthc3NldEluZGV4fWAsIHtcbiAgICAgICAgc291cmNlczogW1NvdXJjZS5hc3NldChhc3NldC5zb3VyY2UpXSxcbiAgICAgICAgZGVzdGluYXRpb25CdWNrZXQ6IHRoaXMuc3RhdGljQXNzZXRzQnVja2V0LFxuICAgICAgICBkZXN0aW5hdGlvbktleVByZWZpeDogdGhpcy5kZXBsb3ltZW50UmV2aXNpb24gKyBhc3NldC50YXJnZXQsXG4gICAgICAgIHBydW5lOiBmYWxzZSxcbiAgICAgICAgc3RvcmFnZUNsYXNzOiBTdG9yYWdlQ2xhc3MuU1RBTkRBUkQsXG4gICAgICAgIGV4Y2x1ZGU6IFsnKiddLFxuICAgICAgICBpbmNsdWRlOiBbYXNzZXQucGF0dGVybl0sXG4gICAgICAgIGNhY2hlQ29udHJvbDogYXNzZXQuY2FjaGVDb250cm9sID8/IGRlZmF1bHRDYWNoZUNvbmZpZyxcbiAgICAgICAgY29udGVudFR5cGU6IGFzc2V0LmNvbnRlbnRUeXBlLFxuICAgICAgfSlcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgaG9zdGVkIHpvbmUgYXQgd2hpY2ggdGhlIEROUyByZWNvcmRzIHNoYWxsIGJlIGNyZWF0ZWQgdG8gYWNjZXNzIG91ciBOdXh0IGFwcCBvbiB0aGUgaW50ZXJuZXQuXG4gICAqXG4gICAqIEBwYXJhbSBwcm9wc1xuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBmaW5kSG9zdGVkWm9uZShwcm9wczogTnV4dEFwcFN0YWNrUHJvcHMpOiBJSG9zdGVkWm9uZSB7XG4gICAgY29uc3QgZG9tYWluUGFydHMgPSBwcm9wcy5kb21haW4uc3BsaXQoJy4nKTtcblxuICAgIHJldHVybiBIb3N0ZWRab25lLmZyb21Ib3N0ZWRab25lQXR0cmlidXRlcyh0aGlzLCBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWhvc3RlZC16b25lYCwge1xuICAgICAgaG9zdGVkWm9uZUlkOiBwcm9wcy5ob3N0ZWRab25lSWQsXG4gICAgICB6b25lTmFtZTogZG9tYWluUGFydHNbZG9tYWluUGFydHMubGVuZ3RoIC0gMV0sIC8vIFN1cHBvcnQgc3ViZG9tYWluc1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgdGhlIEROUyByZWNvcmRzIHRvIGFjY2VzcyBvdXIgTnV4dCBhcHAgb24gdGhlIGludGVybmV0IHZpYSBvdXIgY3VzdG9tIGRvbWFpbi5cbiAgICpcbiAgICogQHBhcmFtIHByb3BzXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZURuc1JlY29yZHMocHJvcHM6IE51eHRBcHBTdGFja1Byb3BzKTogdm9pZCB7XG4gICAgY29uc3QgaG9zdGVkWm9uZSA9IHRoaXMuZmluZEhvc3RlZFpvbmUocHJvcHMpO1xuICAgIGNvbnN0IGRuc1RhcmdldCA9IFJlY29yZFRhcmdldC5mcm9tQWxpYXMobmV3IENsb3VkRnJvbnRUYXJnZXQodGhpcy5jZG4pKTtcblxuICAgIC8vIENyZWF0ZSBhIHJlY29yZCBmb3IgSVB2NFxuICAgIG5ldyBBUmVjb3JkKHRoaXMsIGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0taXB2NC1yZWNvcmRgLCB7XG4gICAgICByZWNvcmROYW1lOiBwcm9wcy5kb21haW4sXG4gICAgICB6b25lOiBob3N0ZWRab25lLFxuICAgICAgdGFyZ2V0OiBkbnNUYXJnZXQsXG4gICAgfSk7XG5cbiAgICAvLyBDcmVhdGUgYSByZWNvcmQgZm9yIElQdjZcbiAgICBuZXcgQWFhYVJlY29yZCh0aGlzLCBgJHt0aGlzLnJlc291cmNlSWRQcmVmaXh9LWlwdjYtcmVjb3JkYCwge1xuICAgICAgcmVjb3JkTmFtZTogcHJvcHMuZG9tYWluLFxuICAgICAgem9uZTogaG9zdGVkWm9uZSxcbiAgICAgIHRhcmdldDogZG5zVGFyZ2V0LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBzY2hlZHVsZWQgcnVsZSB0byBwaW5nIG91ciBOdXh0IGFwcCBsYW1iZGEgZnVuY3Rpb24gZXZlcnkgNSBtaW51dGVzIGluIG9yZGVyIHRvIGtlZXAgaXQgd2FybVxuICAgKiBhbmQgc3BlZWQgdXAgaW5pdGlhbCBTU1IgcmVxdWVzdHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZVBpbmdSdWxlKCk6IHZvaWQge1xuICAgIG5ldyBSdWxlKHRoaXMsIGAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0tcGluZ2VyLXJ1bGVgLCB7XG4gICAgICBydWxlTmFtZTogYCR7dGhpcy5yZXNvdXJjZUlkUHJlZml4fS1waW5nZXJgLFxuICAgICAgZGVzY3JpcHRpb246IGBQaW5ncyB0aGUgbGFtYmRhIGZ1bmN0aW9uIG9mIHRoZSAke3RoaXMucmVzb3VyY2VJZFByZWZpeH0gYXBwIGV2ZXJ5IDUgbWludXRlcyB0byBrZWVwIGl0IHdhcm0uYCxcbiAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICBzY2hlZHVsZTogU2NoZWR1bGUucmF0ZShEdXJhdGlvbi5taW51dGVzKDUpKSxcbiAgICAgIHRhcmdldHM6IFtuZXcgTGFtYmRhRnVuY3Rpb24odGhpcy5sYW1iZGFGdW5jdGlvbildLFxuICAgIH0pO1xuICB9XG59XG4iXX0=