UNPKG

468 kBJavaScriptView Raw
1"use strict";
2var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.CfnVirtualMFADevice = exports.CfnUserToGroupAddition = exports.CfnUser = exports.CfnServiceLinkedRole = exports.CfnServerCertificate = exports.CfnSAMLProvider = exports.CfnRole = exports.CfnPolicy = exports.CfnOIDCProvider = exports.CfnManagedPolicy = exports.CfnInstanceProfile = exports.CfnGroup = exports.CfnAccessKey = void 0;
5const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
6const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
7// Copyright 2012-2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
8// Generated from the AWS CloudFormation Resource Specification
9// See: docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html
10// @cfn2ts:meta@ {"generated":"2022-06-22T22:41:39.477Z","fingerprint":"xsN/3SSmuqVfs/ngiaF1EQgLd0n8YVi2WYm2dq1o00c="}
11/* eslint-disable max-len */ // This is generated code - line lengths are difficult to control
12const cdk = require("@aws-cdk/core");
13const cfn_parse = require("@aws-cdk/core/lib/helpers-internal");
14/**
15 * Determine whether the given properties match those of a `CfnAccessKeyProps`
16 *
17 * @param properties - the TypeScript properties of a `CfnAccessKeyProps`
18 *
19 * @returns the result of the validation.
20 */
21function CfnAccessKeyPropsValidator(properties) {
22 if (!cdk.canInspect(properties)) {
23 return cdk.VALIDATION_SUCCESS;
24 }
25 const errors = new cdk.ValidationResults();
26 if (typeof properties !== 'object') {
27 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
28 }
29 errors.collect(cdk.propertyValidator('serial', cdk.validateNumber)(properties.serial));
30 errors.collect(cdk.propertyValidator('status', cdk.validateString)(properties.status));
31 errors.collect(cdk.propertyValidator('userName', cdk.requiredValidator)(properties.userName));
32 errors.collect(cdk.propertyValidator('userName', cdk.validateString)(properties.userName));
33 return errors.wrap('supplied properties not correct for "CfnAccessKeyProps"');
34}
35/**
36 * Renders the AWS CloudFormation properties of an `AWS::IAM::AccessKey` resource
37 *
38 * @param properties - the TypeScript properties of a `CfnAccessKeyProps`
39 *
40 * @returns the AWS CloudFormation properties of an `AWS::IAM::AccessKey` resource.
41 */
42// @ts-ignore TS6133
43function cfnAccessKeyPropsToCloudFormation(properties) {
44 if (!cdk.canInspect(properties)) {
45 return properties;
46 }
47 CfnAccessKeyPropsValidator(properties).assertSuccess();
48 return {
49 UserName: cdk.stringToCloudFormation(properties.userName),
50 Serial: cdk.numberToCloudFormation(properties.serial),
51 Status: cdk.stringToCloudFormation(properties.status),
52 };
53}
54// @ts-ignore TS6133
55function CfnAccessKeyPropsFromCloudFormation(properties) {
56 properties = properties == null ? {} : properties;
57 if (typeof properties !== 'object') {
58 return new cfn_parse.FromCloudFormationResult(properties);
59 }
60 const ret = new cfn_parse.FromCloudFormationPropertyObject();
61 ret.addPropertyResult('userName', 'UserName', cfn_parse.FromCloudFormation.getString(properties.UserName));
62 ret.addPropertyResult('serial', 'Serial', properties.Serial != null ? cfn_parse.FromCloudFormation.getNumber(properties.Serial) : undefined);
63 ret.addPropertyResult('status', 'Status', properties.Status != null ? cfn_parse.FromCloudFormation.getString(properties.Status) : undefined);
64 ret.addUnrecognizedPropertiesAsExtra(properties);
65 return ret;
66}
67/**
68 * A CloudFormation `AWS::IAM::AccessKey`
69 *
70 * Creates a new AWS secret access key and corresponding AWS access key ID for the specified user. The default status for new keys is `Active` .
71 *
72 * If you do not specify a user name, IAM determines the user name implicitly based on the AWS access key ID signing the request. This operation works for access keys under the AWS account . Consequently, you can use this operation to manage AWS account root user credentials. This is true even if the AWS account has no associated users.
73 *
74 * For information about quotas on the number of keys you can create, see [IAM and AWS STS quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) in the *IAM User Guide* .
75 *
76 * > To ensure the security of your AWS account , the secret access key is accessible only during key and user creation. You must save the key (for example, in a text file) if you want to be able to access it again. If a secret key is lost, you can delete the access keys for the associated user and then create new keys.
77 *
78 * @cloudformationResource AWS::IAM::AccessKey
79 * @stability external
80 *
81 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-accesskey.html
82 */
83class CfnAccessKey extends cdk.CfnResource {
84 /**
85 * Create a new `AWS::IAM::AccessKey`.
86 *
87 * @param scope - scope in which this resource is defined
88 * @param id - scoped id of the resource
89 * @param props - resource properties
90 */
91 constructor(scope, id, props) {
92 super(scope, id, { type: CfnAccessKey.CFN_RESOURCE_TYPE_NAME, properties: props });
93 try {
94 jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnAccessKeyProps(props);
95 }
96 catch (error) {
97 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
98 Error.captureStackTrace(error, CfnAccessKey);
99 }
100 throw error;
101 }
102 cdk.requireProperty(props, 'userName', this);
103 this.attrSecretAccessKey = cdk.Token.asString(this.getAtt('SecretAccessKey'));
104 this.userName = props.userName;
105 this.serial = props.serial;
106 this.status = props.status;
107 }
108 /**
109 * A factory method that creates a new instance of this class from an object
110 * containing the CloudFormation properties of this resource.
111 * Used in the @aws-cdk/cloudformation-include module.
112 *
113 * @internal
114 */
115 static _fromCloudFormation(scope, id, resourceAttributes, options) {
116 resourceAttributes = resourceAttributes || {};
117 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
118 const propsResult = CfnAccessKeyPropsFromCloudFormation(resourceProperties);
119 const ret = new CfnAccessKey(scope, id, propsResult.value);
120 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
121 ret.addPropertyOverride(propKey, propVal);
122 }
123 options.parser.handleAttributes(ret, resourceAttributes, id);
124 return ret;
125 }
126 /**
127 * Examines the CloudFormation resource and discloses attributes.
128 *
129 * @param inspector - tree inspector to collect and process attributes
130 *
131 */
132 inspect(inspector) {
133 inspector.addAttribute("aws:cdk:cloudformation:type", CfnAccessKey.CFN_RESOURCE_TYPE_NAME);
134 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
135 }
136 get cfnProperties() {
137 return {
138 userName: this.userName,
139 serial: this.serial,
140 status: this.status,
141 };
142 }
143 renderProperties(props) {
144 return cfnAccessKeyPropsToCloudFormation(props);
145 }
146}
147exports.CfnAccessKey = CfnAccessKey;
148_a = JSII_RTTI_SYMBOL_1;
149CfnAccessKey[_a] = { fqn: "@aws-cdk/aws-iam.CfnAccessKey", version: "1.161.0" };
150/**
151 * The CloudFormation resource type name for this resource class.
152 */
153CfnAccessKey.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::AccessKey";
154/**
155 * Determine whether the given properties match those of a `CfnGroupProps`
156 *
157 * @param properties - the TypeScript properties of a `CfnGroupProps`
158 *
159 * @returns the result of the validation.
160 */
161function CfnGroupPropsValidator(properties) {
162 if (!cdk.canInspect(properties)) {
163 return cdk.VALIDATION_SUCCESS;
164 }
165 const errors = new cdk.ValidationResults();
166 if (typeof properties !== 'object') {
167 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
168 }
169 errors.collect(cdk.propertyValidator('groupName', cdk.validateString)(properties.groupName));
170 errors.collect(cdk.propertyValidator('managedPolicyArns', cdk.listValidator(cdk.validateString))(properties.managedPolicyArns));
171 errors.collect(cdk.propertyValidator('path', cdk.validateString)(properties.path));
172 errors.collect(cdk.propertyValidator('policies', cdk.listValidator(CfnGroup_PolicyPropertyValidator))(properties.policies));
173 return errors.wrap('supplied properties not correct for "CfnGroupProps"');
174}
175/**
176 * Renders the AWS CloudFormation properties of an `AWS::IAM::Group` resource
177 *
178 * @param properties - the TypeScript properties of a `CfnGroupProps`
179 *
180 * @returns the AWS CloudFormation properties of an `AWS::IAM::Group` resource.
181 */
182// @ts-ignore TS6133
183function cfnGroupPropsToCloudFormation(properties) {
184 if (!cdk.canInspect(properties)) {
185 return properties;
186 }
187 CfnGroupPropsValidator(properties).assertSuccess();
188 return {
189 GroupName: cdk.stringToCloudFormation(properties.groupName),
190 ManagedPolicyArns: cdk.listMapper(cdk.stringToCloudFormation)(properties.managedPolicyArns),
191 Path: cdk.stringToCloudFormation(properties.path),
192 Policies: cdk.listMapper(cfnGroupPolicyPropertyToCloudFormation)(properties.policies),
193 };
194}
195// @ts-ignore TS6133
196function CfnGroupPropsFromCloudFormation(properties) {
197 properties = properties == null ? {} : properties;
198 if (typeof properties !== 'object') {
199 return new cfn_parse.FromCloudFormationResult(properties);
200 }
201 const ret = new cfn_parse.FromCloudFormationPropertyObject();
202 ret.addPropertyResult('groupName', 'GroupName', properties.GroupName != null ? cfn_parse.FromCloudFormation.getString(properties.GroupName) : undefined);
203 ret.addPropertyResult('managedPolicyArns', 'ManagedPolicyArns', properties.ManagedPolicyArns != null ? cfn_parse.FromCloudFormation.getStringArray(properties.ManagedPolicyArns) : undefined);
204 ret.addPropertyResult('path', 'Path', properties.Path != null ? cfn_parse.FromCloudFormation.getString(properties.Path) : undefined);
205 ret.addPropertyResult('policies', 'Policies', properties.Policies != null ? cfn_parse.FromCloudFormation.getArray(CfnGroupPolicyPropertyFromCloudFormation)(properties.Policies) : undefined);
206 ret.addUnrecognizedPropertiesAsExtra(properties);
207 return ret;
208}
209/**
210 * A CloudFormation `AWS::IAM::Group`
211 *
212 * Creates a new group.
213 *
214 * For information about the number of groups you can create, see [Limitations on IAM Entities](https://docs.aws.amazon.com/IAM/latest/UserGuide/LimitationsOnEntities.html) in the *IAM User Guide* .
215 *
216 * @cloudformationResource AWS::IAM::Group
217 * @stability external
218 *
219 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-group.html
220 */
221class CfnGroup extends cdk.CfnResource {
222 /**
223 * Create a new `AWS::IAM::Group`.
224 *
225 * @param scope - scope in which this resource is defined
226 * @param id - scoped id of the resource
227 * @param props - resource properties
228 */
229 constructor(scope, id, props = {}) {
230 super(scope, id, { type: CfnGroup.CFN_RESOURCE_TYPE_NAME, properties: props });
231 try {
232 jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnGroupProps(props);
233 }
234 catch (error) {
235 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
236 Error.captureStackTrace(error, CfnGroup);
237 }
238 throw error;
239 }
240 this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
241 this.groupName = props.groupName;
242 this.managedPolicyArns = props.managedPolicyArns;
243 this.path = props.path;
244 this.policies = props.policies;
245 }
246 /**
247 * A factory method that creates a new instance of this class from an object
248 * containing the CloudFormation properties of this resource.
249 * Used in the @aws-cdk/cloudformation-include module.
250 *
251 * @internal
252 */
253 static _fromCloudFormation(scope, id, resourceAttributes, options) {
254 resourceAttributes = resourceAttributes || {};
255 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
256 const propsResult = CfnGroupPropsFromCloudFormation(resourceProperties);
257 const ret = new CfnGroup(scope, id, propsResult.value);
258 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
259 ret.addPropertyOverride(propKey, propVal);
260 }
261 options.parser.handleAttributes(ret, resourceAttributes, id);
262 return ret;
263 }
264 /**
265 * Examines the CloudFormation resource and discloses attributes.
266 *
267 * @param inspector - tree inspector to collect and process attributes
268 *
269 */
270 inspect(inspector) {
271 inspector.addAttribute("aws:cdk:cloudformation:type", CfnGroup.CFN_RESOURCE_TYPE_NAME);
272 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
273 }
274 get cfnProperties() {
275 return {
276 groupName: this.groupName,
277 managedPolicyArns: this.managedPolicyArns,
278 path: this.path,
279 policies: this.policies,
280 };
281 }
282 renderProperties(props) {
283 return cfnGroupPropsToCloudFormation(props);
284 }
285}
286exports.CfnGroup = CfnGroup;
287_b = JSII_RTTI_SYMBOL_1;
288CfnGroup[_b] = { fqn: "@aws-cdk/aws-iam.CfnGroup", version: "1.161.0" };
289/**
290 * The CloudFormation resource type name for this resource class.
291 */
292CfnGroup.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::Group";
293/**
294 * Determine whether the given properties match those of a `PolicyProperty`
295 *
296 * @param properties - the TypeScript properties of a `PolicyProperty`
297 *
298 * @returns the result of the validation.
299 */
300function CfnGroup_PolicyPropertyValidator(properties) {
301 if (!cdk.canInspect(properties)) {
302 return cdk.VALIDATION_SUCCESS;
303 }
304 const errors = new cdk.ValidationResults();
305 if (typeof properties !== 'object') {
306 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
307 }
308 errors.collect(cdk.propertyValidator('policyDocument', cdk.requiredValidator)(properties.policyDocument));
309 errors.collect(cdk.propertyValidator('policyDocument', cdk.validateObject)(properties.policyDocument));
310 errors.collect(cdk.propertyValidator('policyName', cdk.requiredValidator)(properties.policyName));
311 errors.collect(cdk.propertyValidator('policyName', cdk.validateString)(properties.policyName));
312 return errors.wrap('supplied properties not correct for "PolicyProperty"');
313}
314/**
315 * Renders the AWS CloudFormation properties of an `AWS::IAM::Group.Policy` resource
316 *
317 * @param properties - the TypeScript properties of a `PolicyProperty`
318 *
319 * @returns the AWS CloudFormation properties of an `AWS::IAM::Group.Policy` resource.
320 */
321// @ts-ignore TS6133
322function cfnGroupPolicyPropertyToCloudFormation(properties) {
323 if (!cdk.canInspect(properties)) {
324 return properties;
325 }
326 CfnGroup_PolicyPropertyValidator(properties).assertSuccess();
327 return {
328 PolicyDocument: cdk.objectToCloudFormation(properties.policyDocument),
329 PolicyName: cdk.stringToCloudFormation(properties.policyName),
330 };
331}
332// @ts-ignore TS6133
333function CfnGroupPolicyPropertyFromCloudFormation(properties) {
334 if (cdk.isResolvableObject(properties)) {
335 return new cfn_parse.FromCloudFormationResult(properties);
336 }
337 properties = properties == null ? {} : properties;
338 if (typeof properties !== 'object') {
339 return new cfn_parse.FromCloudFormationResult(properties);
340 }
341 const ret = new cfn_parse.FromCloudFormationPropertyObject();
342 ret.addPropertyResult('policyDocument', 'PolicyDocument', cfn_parse.FromCloudFormation.getAny(properties.PolicyDocument));
343 ret.addPropertyResult('policyName', 'PolicyName', cfn_parse.FromCloudFormation.getString(properties.PolicyName));
344 ret.addUnrecognizedPropertiesAsExtra(properties);
345 return ret;
346}
347/**
348 * Determine whether the given properties match those of a `CfnInstanceProfileProps`
349 *
350 * @param properties - the TypeScript properties of a `CfnInstanceProfileProps`
351 *
352 * @returns the result of the validation.
353 */
354function CfnInstanceProfilePropsValidator(properties) {
355 if (!cdk.canInspect(properties)) {
356 return cdk.VALIDATION_SUCCESS;
357 }
358 const errors = new cdk.ValidationResults();
359 if (typeof properties !== 'object') {
360 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
361 }
362 errors.collect(cdk.propertyValidator('instanceProfileName', cdk.validateString)(properties.instanceProfileName));
363 errors.collect(cdk.propertyValidator('path', cdk.validateString)(properties.path));
364 errors.collect(cdk.propertyValidator('roles', cdk.requiredValidator)(properties.roles));
365 errors.collect(cdk.propertyValidator('roles', cdk.listValidator(cdk.validateString))(properties.roles));
366 return errors.wrap('supplied properties not correct for "CfnInstanceProfileProps"');
367}
368/**
369 * Renders the AWS CloudFormation properties of an `AWS::IAM::InstanceProfile` resource
370 *
371 * @param properties - the TypeScript properties of a `CfnInstanceProfileProps`
372 *
373 * @returns the AWS CloudFormation properties of an `AWS::IAM::InstanceProfile` resource.
374 */
375// @ts-ignore TS6133
376function cfnInstanceProfilePropsToCloudFormation(properties) {
377 if (!cdk.canInspect(properties)) {
378 return properties;
379 }
380 CfnInstanceProfilePropsValidator(properties).assertSuccess();
381 return {
382 Roles: cdk.listMapper(cdk.stringToCloudFormation)(properties.roles),
383 InstanceProfileName: cdk.stringToCloudFormation(properties.instanceProfileName),
384 Path: cdk.stringToCloudFormation(properties.path),
385 };
386}
387// @ts-ignore TS6133
388function CfnInstanceProfilePropsFromCloudFormation(properties) {
389 properties = properties == null ? {} : properties;
390 if (typeof properties !== 'object') {
391 return new cfn_parse.FromCloudFormationResult(properties);
392 }
393 const ret = new cfn_parse.FromCloudFormationPropertyObject();
394 ret.addPropertyResult('roles', 'Roles', cfn_parse.FromCloudFormation.getStringArray(properties.Roles));
395 ret.addPropertyResult('instanceProfileName', 'InstanceProfileName', properties.InstanceProfileName != null ? cfn_parse.FromCloudFormation.getString(properties.InstanceProfileName) : undefined);
396 ret.addPropertyResult('path', 'Path', properties.Path != null ? cfn_parse.FromCloudFormation.getString(properties.Path) : undefined);
397 ret.addUnrecognizedPropertiesAsExtra(properties);
398 return ret;
399}
400/**
401 * A CloudFormation `AWS::IAM::InstanceProfile`
402 *
403 * Creates a new instance profile. For information about instance profiles, see [Using instance profiles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html) .
404 *
405 * For information about the number of instance profiles you can create, see [IAM object quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) in the *IAM User Guide* .
406 *
407 * @cloudformationResource AWS::IAM::InstanceProfile
408 * @stability external
409 *
410 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-instanceprofile.html
411 */
412class CfnInstanceProfile extends cdk.CfnResource {
413 /**
414 * Create a new `AWS::IAM::InstanceProfile`.
415 *
416 * @param scope - scope in which this resource is defined
417 * @param id - scoped id of the resource
418 * @param props - resource properties
419 */
420 constructor(scope, id, props) {
421 super(scope, id, { type: CfnInstanceProfile.CFN_RESOURCE_TYPE_NAME, properties: props });
422 try {
423 jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnInstanceProfileProps(props);
424 }
425 catch (error) {
426 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
427 Error.captureStackTrace(error, CfnInstanceProfile);
428 }
429 throw error;
430 }
431 cdk.requireProperty(props, 'roles', this);
432 this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
433 this.roles = props.roles;
434 this.instanceProfileName = props.instanceProfileName;
435 this.path = props.path;
436 }
437 /**
438 * A factory method that creates a new instance of this class from an object
439 * containing the CloudFormation properties of this resource.
440 * Used in the @aws-cdk/cloudformation-include module.
441 *
442 * @internal
443 */
444 static _fromCloudFormation(scope, id, resourceAttributes, options) {
445 resourceAttributes = resourceAttributes || {};
446 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
447 const propsResult = CfnInstanceProfilePropsFromCloudFormation(resourceProperties);
448 const ret = new CfnInstanceProfile(scope, id, propsResult.value);
449 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
450 ret.addPropertyOverride(propKey, propVal);
451 }
452 options.parser.handleAttributes(ret, resourceAttributes, id);
453 return ret;
454 }
455 /**
456 * Examines the CloudFormation resource and discloses attributes.
457 *
458 * @param inspector - tree inspector to collect and process attributes
459 *
460 */
461 inspect(inspector) {
462 inspector.addAttribute("aws:cdk:cloudformation:type", CfnInstanceProfile.CFN_RESOURCE_TYPE_NAME);
463 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
464 }
465 get cfnProperties() {
466 return {
467 roles: this.roles,
468 instanceProfileName: this.instanceProfileName,
469 path: this.path,
470 };
471 }
472 renderProperties(props) {
473 return cfnInstanceProfilePropsToCloudFormation(props);
474 }
475}
476exports.CfnInstanceProfile = CfnInstanceProfile;
477_c = JSII_RTTI_SYMBOL_1;
478CfnInstanceProfile[_c] = { fqn: "@aws-cdk/aws-iam.CfnInstanceProfile", version: "1.161.0" };
479/**
480 * The CloudFormation resource type name for this resource class.
481 */
482CfnInstanceProfile.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::InstanceProfile";
483/**
484 * Determine whether the given properties match those of a `CfnManagedPolicyProps`
485 *
486 * @param properties - the TypeScript properties of a `CfnManagedPolicyProps`
487 *
488 * @returns the result of the validation.
489 */
490function CfnManagedPolicyPropsValidator(properties) {
491 if (!cdk.canInspect(properties)) {
492 return cdk.VALIDATION_SUCCESS;
493 }
494 const errors = new cdk.ValidationResults();
495 if (typeof properties !== 'object') {
496 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
497 }
498 errors.collect(cdk.propertyValidator('description', cdk.validateString)(properties.description));
499 errors.collect(cdk.propertyValidator('groups', cdk.listValidator(cdk.validateString))(properties.groups));
500 errors.collect(cdk.propertyValidator('managedPolicyName', cdk.validateString)(properties.managedPolicyName));
501 errors.collect(cdk.propertyValidator('path', cdk.validateString)(properties.path));
502 errors.collect(cdk.propertyValidator('policyDocument', cdk.requiredValidator)(properties.policyDocument));
503 errors.collect(cdk.propertyValidator('policyDocument', cdk.validateObject)(properties.policyDocument));
504 errors.collect(cdk.propertyValidator('roles', cdk.listValidator(cdk.validateString))(properties.roles));
505 errors.collect(cdk.propertyValidator('users', cdk.listValidator(cdk.validateString))(properties.users));
506 return errors.wrap('supplied properties not correct for "CfnManagedPolicyProps"');
507}
508/**
509 * Renders the AWS CloudFormation properties of an `AWS::IAM::ManagedPolicy` resource
510 *
511 * @param properties - the TypeScript properties of a `CfnManagedPolicyProps`
512 *
513 * @returns the AWS CloudFormation properties of an `AWS::IAM::ManagedPolicy` resource.
514 */
515// @ts-ignore TS6133
516function cfnManagedPolicyPropsToCloudFormation(properties) {
517 if (!cdk.canInspect(properties)) {
518 return properties;
519 }
520 CfnManagedPolicyPropsValidator(properties).assertSuccess();
521 return {
522 PolicyDocument: cdk.objectToCloudFormation(properties.policyDocument),
523 Description: cdk.stringToCloudFormation(properties.description),
524 Groups: cdk.listMapper(cdk.stringToCloudFormation)(properties.groups),
525 ManagedPolicyName: cdk.stringToCloudFormation(properties.managedPolicyName),
526 Path: cdk.stringToCloudFormation(properties.path),
527 Roles: cdk.listMapper(cdk.stringToCloudFormation)(properties.roles),
528 Users: cdk.listMapper(cdk.stringToCloudFormation)(properties.users),
529 };
530}
531// @ts-ignore TS6133
532function CfnManagedPolicyPropsFromCloudFormation(properties) {
533 properties = properties == null ? {} : properties;
534 if (typeof properties !== 'object') {
535 return new cfn_parse.FromCloudFormationResult(properties);
536 }
537 const ret = new cfn_parse.FromCloudFormationPropertyObject();
538 ret.addPropertyResult('policyDocument', 'PolicyDocument', cfn_parse.FromCloudFormation.getAny(properties.PolicyDocument));
539 ret.addPropertyResult('description', 'Description', properties.Description != null ? cfn_parse.FromCloudFormation.getString(properties.Description) : undefined);
540 ret.addPropertyResult('groups', 'Groups', properties.Groups != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Groups) : undefined);
541 ret.addPropertyResult('managedPolicyName', 'ManagedPolicyName', properties.ManagedPolicyName != null ? cfn_parse.FromCloudFormation.getString(properties.ManagedPolicyName) : undefined);
542 ret.addPropertyResult('path', 'Path', properties.Path != null ? cfn_parse.FromCloudFormation.getString(properties.Path) : undefined);
543 ret.addPropertyResult('roles', 'Roles', properties.Roles != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Roles) : undefined);
544 ret.addPropertyResult('users', 'Users', properties.Users != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Users) : undefined);
545 ret.addUnrecognizedPropertiesAsExtra(properties);
546 return ret;
547}
548/**
549 * A CloudFormation `AWS::IAM::ManagedPolicy`
550 *
551 * Creates a new managed policy for your AWS account .
552 *
553 * This operation creates a policy version with a version identifier of `v1` and sets v1 as the policy's default version. For more information about policy versions, see [Versioning for managed policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/policies-managed-versions.html) in the *IAM User Guide* .
554 *
555 * As a best practice, you can validate your IAM policies. To learn more, see [Validating IAM policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_policy-validator.html) in the *IAM User Guide* .
556 *
557 * For more information about managed policies in general, see [Managed policies and inline policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/policies-managed-vs-inline.html) in the *IAM User Guide* .
558 *
559 * @cloudformationResource AWS::IAM::ManagedPolicy
560 * @stability external
561 *
562 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-managedpolicy.html
563 */
564class CfnManagedPolicy extends cdk.CfnResource {
565 /**
566 * Create a new `AWS::IAM::ManagedPolicy`.
567 *
568 * @param scope - scope in which this resource is defined
569 * @param id - scoped id of the resource
570 * @param props - resource properties
571 */
572 constructor(scope, id, props) {
573 super(scope, id, { type: CfnManagedPolicy.CFN_RESOURCE_TYPE_NAME, properties: props });
574 try {
575 jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnManagedPolicyProps(props);
576 }
577 catch (error) {
578 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
579 Error.captureStackTrace(error, CfnManagedPolicy);
580 }
581 throw error;
582 }
583 cdk.requireProperty(props, 'policyDocument', this);
584 this.policyDocument = props.policyDocument;
585 this.description = props.description;
586 this.groups = props.groups;
587 this.managedPolicyName = props.managedPolicyName;
588 this.path = props.path;
589 this.roles = props.roles;
590 this.users = props.users;
591 }
592 /**
593 * A factory method that creates a new instance of this class from an object
594 * containing the CloudFormation properties of this resource.
595 * Used in the @aws-cdk/cloudformation-include module.
596 *
597 * @internal
598 */
599 static _fromCloudFormation(scope, id, resourceAttributes, options) {
600 resourceAttributes = resourceAttributes || {};
601 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
602 const propsResult = CfnManagedPolicyPropsFromCloudFormation(resourceProperties);
603 const ret = new CfnManagedPolicy(scope, id, propsResult.value);
604 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
605 ret.addPropertyOverride(propKey, propVal);
606 }
607 options.parser.handleAttributes(ret, resourceAttributes, id);
608 return ret;
609 }
610 /**
611 * Examines the CloudFormation resource and discloses attributes.
612 *
613 * @param inspector - tree inspector to collect and process attributes
614 *
615 */
616 inspect(inspector) {
617 inspector.addAttribute("aws:cdk:cloudformation:type", CfnManagedPolicy.CFN_RESOURCE_TYPE_NAME);
618 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
619 }
620 get cfnProperties() {
621 return {
622 policyDocument: this.policyDocument,
623 description: this.description,
624 groups: this.groups,
625 managedPolicyName: this.managedPolicyName,
626 path: this.path,
627 roles: this.roles,
628 users: this.users,
629 };
630 }
631 renderProperties(props) {
632 return cfnManagedPolicyPropsToCloudFormation(props);
633 }
634}
635exports.CfnManagedPolicy = CfnManagedPolicy;
636_d = JSII_RTTI_SYMBOL_1;
637CfnManagedPolicy[_d] = { fqn: "@aws-cdk/aws-iam.CfnManagedPolicy", version: "1.161.0" };
638/**
639 * The CloudFormation resource type name for this resource class.
640 */
641CfnManagedPolicy.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::ManagedPolicy";
642/**
643 * Determine whether the given properties match those of a `CfnOIDCProviderProps`
644 *
645 * @param properties - the TypeScript properties of a `CfnOIDCProviderProps`
646 *
647 * @returns the result of the validation.
648 */
649function CfnOIDCProviderPropsValidator(properties) {
650 if (!cdk.canInspect(properties)) {
651 return cdk.VALIDATION_SUCCESS;
652 }
653 const errors = new cdk.ValidationResults();
654 if (typeof properties !== 'object') {
655 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
656 }
657 errors.collect(cdk.propertyValidator('clientIdList', cdk.listValidator(cdk.validateString))(properties.clientIdList));
658 errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
659 errors.collect(cdk.propertyValidator('thumbprintList', cdk.requiredValidator)(properties.thumbprintList));
660 errors.collect(cdk.propertyValidator('thumbprintList', cdk.listValidator(cdk.validateString))(properties.thumbprintList));
661 errors.collect(cdk.propertyValidator('url', cdk.validateString)(properties.url));
662 return errors.wrap('supplied properties not correct for "CfnOIDCProviderProps"');
663}
664/**
665 * Renders the AWS CloudFormation properties of an `AWS::IAM::OIDCProvider` resource
666 *
667 * @param properties - the TypeScript properties of a `CfnOIDCProviderProps`
668 *
669 * @returns the AWS CloudFormation properties of an `AWS::IAM::OIDCProvider` resource.
670 */
671// @ts-ignore TS6133
672function cfnOIDCProviderPropsToCloudFormation(properties) {
673 if (!cdk.canInspect(properties)) {
674 return properties;
675 }
676 CfnOIDCProviderPropsValidator(properties).assertSuccess();
677 return {
678 ThumbprintList: cdk.listMapper(cdk.stringToCloudFormation)(properties.thumbprintList),
679 ClientIdList: cdk.listMapper(cdk.stringToCloudFormation)(properties.clientIdList),
680 Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
681 Url: cdk.stringToCloudFormation(properties.url),
682 };
683}
684// @ts-ignore TS6133
685function CfnOIDCProviderPropsFromCloudFormation(properties) {
686 properties = properties == null ? {} : properties;
687 if (typeof properties !== 'object') {
688 return new cfn_parse.FromCloudFormationResult(properties);
689 }
690 const ret = new cfn_parse.FromCloudFormationPropertyObject();
691 ret.addPropertyResult('thumbprintList', 'ThumbprintList', cfn_parse.FromCloudFormation.getStringArray(properties.ThumbprintList));
692 ret.addPropertyResult('clientIdList', 'ClientIdList', properties.ClientIdList != null ? cfn_parse.FromCloudFormation.getStringArray(properties.ClientIdList) : undefined);
693 ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
694 ret.addPropertyResult('url', 'Url', properties.Url != null ? cfn_parse.FromCloudFormation.getString(properties.Url) : undefined);
695 ret.addUnrecognizedPropertiesAsExtra(properties);
696 return ret;
697}
698/**
699 * A CloudFormation `AWS::IAM::OIDCProvider`
700 *
701 * Creates an IAM entity to describe an identity provider (IdP) that supports [OpenID Connect (OIDC)](https://docs.aws.amazon.com/http://openid.net/connect/) .
702 *
703 * The OIDC provider that you create with this operation can be used as a principal in a role's trust policy. Such a policy establishes a trust relationship between AWS and the OIDC provider.
704 *
705 * When you create the IAM OIDC provider, you specify the following:
706 *
707 * - The URL of the OIDC identity provider (IdP) to trust
708 * - A list of client IDs (also known as audiences) that identify the application or applications that are allowed to authenticate using the OIDC provider
709 * - A list of thumbprints of one or more server certificates that the IdP uses
710 *
711 * You get all of this information from the OIDC IdP that you want to use to access AWS .
712 *
713 * > The trust for the OIDC provider is derived from the IAM provider that this operation creates. Therefore, it is best to limit access to the [CreateOpenIDConnectProvider](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateOpenIDConnectProvider.html) operation to highly privileged users.
714 *
715 * @cloudformationResource AWS::IAM::OIDCProvider
716 * @stability external
717 *
718 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-oidcprovider.html
719 */
720class CfnOIDCProvider extends cdk.CfnResource {
721 /**
722 * Create a new `AWS::IAM::OIDCProvider`.
723 *
724 * @param scope - scope in which this resource is defined
725 * @param id - scoped id of the resource
726 * @param props - resource properties
727 */
728 constructor(scope, id, props) {
729 super(scope, id, { type: CfnOIDCProvider.CFN_RESOURCE_TYPE_NAME, properties: props });
730 try {
731 jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnOIDCProviderProps(props);
732 }
733 catch (error) {
734 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
735 Error.captureStackTrace(error, CfnOIDCProvider);
736 }
737 throw error;
738 }
739 cdk.requireProperty(props, 'thumbprintList', this);
740 this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
741 this.thumbprintList = props.thumbprintList;
742 this.clientIdList = props.clientIdList;
743 this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::IAM::OIDCProvider", props.tags, { tagPropertyName: 'tags' });
744 this.url = props.url;
745 }
746 /**
747 * A factory method that creates a new instance of this class from an object
748 * containing the CloudFormation properties of this resource.
749 * Used in the @aws-cdk/cloudformation-include module.
750 *
751 * @internal
752 */
753 static _fromCloudFormation(scope, id, resourceAttributes, options) {
754 resourceAttributes = resourceAttributes || {};
755 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
756 const propsResult = CfnOIDCProviderPropsFromCloudFormation(resourceProperties);
757 const ret = new CfnOIDCProvider(scope, id, propsResult.value);
758 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
759 ret.addPropertyOverride(propKey, propVal);
760 }
761 options.parser.handleAttributes(ret, resourceAttributes, id);
762 return ret;
763 }
764 /**
765 * Examines the CloudFormation resource and discloses attributes.
766 *
767 * @param inspector - tree inspector to collect and process attributes
768 *
769 */
770 inspect(inspector) {
771 inspector.addAttribute("aws:cdk:cloudformation:type", CfnOIDCProvider.CFN_RESOURCE_TYPE_NAME);
772 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
773 }
774 get cfnProperties() {
775 return {
776 thumbprintList: this.thumbprintList,
777 clientIdList: this.clientIdList,
778 tags: this.tags.renderTags(),
779 url: this.url,
780 };
781 }
782 renderProperties(props) {
783 return cfnOIDCProviderPropsToCloudFormation(props);
784 }
785}
786exports.CfnOIDCProvider = CfnOIDCProvider;
787_e = JSII_RTTI_SYMBOL_1;
788CfnOIDCProvider[_e] = { fqn: "@aws-cdk/aws-iam.CfnOIDCProvider", version: "1.161.0" };
789/**
790 * The CloudFormation resource type name for this resource class.
791 */
792CfnOIDCProvider.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::OIDCProvider";
793/**
794 * Determine whether the given properties match those of a `CfnPolicyProps`
795 *
796 * @param properties - the TypeScript properties of a `CfnPolicyProps`
797 *
798 * @returns the result of the validation.
799 */
800function CfnPolicyPropsValidator(properties) {
801 if (!cdk.canInspect(properties)) {
802 return cdk.VALIDATION_SUCCESS;
803 }
804 const errors = new cdk.ValidationResults();
805 if (typeof properties !== 'object') {
806 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
807 }
808 errors.collect(cdk.propertyValidator('groups', cdk.listValidator(cdk.validateString))(properties.groups));
809 errors.collect(cdk.propertyValidator('policyDocument', cdk.requiredValidator)(properties.policyDocument));
810 errors.collect(cdk.propertyValidator('policyDocument', cdk.validateObject)(properties.policyDocument));
811 errors.collect(cdk.propertyValidator('policyName', cdk.requiredValidator)(properties.policyName));
812 errors.collect(cdk.propertyValidator('policyName', cdk.validateString)(properties.policyName));
813 errors.collect(cdk.propertyValidator('roles', cdk.listValidator(cdk.validateString))(properties.roles));
814 errors.collect(cdk.propertyValidator('users', cdk.listValidator(cdk.validateString))(properties.users));
815 return errors.wrap('supplied properties not correct for "CfnPolicyProps"');
816}
817/**
818 * Renders the AWS CloudFormation properties of an `AWS::IAM::Policy` resource
819 *
820 * @param properties - the TypeScript properties of a `CfnPolicyProps`
821 *
822 * @returns the AWS CloudFormation properties of an `AWS::IAM::Policy` resource.
823 */
824// @ts-ignore TS6133
825function cfnPolicyPropsToCloudFormation(properties) {
826 if (!cdk.canInspect(properties)) {
827 return properties;
828 }
829 CfnPolicyPropsValidator(properties).assertSuccess();
830 return {
831 PolicyDocument: cdk.objectToCloudFormation(properties.policyDocument),
832 PolicyName: cdk.stringToCloudFormation(properties.policyName),
833 Groups: cdk.listMapper(cdk.stringToCloudFormation)(properties.groups),
834 Roles: cdk.listMapper(cdk.stringToCloudFormation)(properties.roles),
835 Users: cdk.listMapper(cdk.stringToCloudFormation)(properties.users),
836 };
837}
838// @ts-ignore TS6133
839function CfnPolicyPropsFromCloudFormation(properties) {
840 properties = properties == null ? {} : properties;
841 if (typeof properties !== 'object') {
842 return new cfn_parse.FromCloudFormationResult(properties);
843 }
844 const ret = new cfn_parse.FromCloudFormationPropertyObject();
845 ret.addPropertyResult('policyDocument', 'PolicyDocument', cfn_parse.FromCloudFormation.getAny(properties.PolicyDocument));
846 ret.addPropertyResult('policyName', 'PolicyName', cfn_parse.FromCloudFormation.getString(properties.PolicyName));
847 ret.addPropertyResult('groups', 'Groups', properties.Groups != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Groups) : undefined);
848 ret.addPropertyResult('roles', 'Roles', properties.Roles != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Roles) : undefined);
849 ret.addPropertyResult('users', 'Users', properties.Users != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Users) : undefined);
850 ret.addUnrecognizedPropertiesAsExtra(properties);
851 return ret;
852}
853/**
854 * A CloudFormation `AWS::IAM::Policy`
855 *
856 * Adds or updates an inline policy document that is embedded in the specified IAM user, group, or role.
857 *
858 * An IAM user can also have a managed policy attached to it. For information about policies, see [Managed Policies and Inline Policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/policies-managed-vs-inline.html) in the *IAM User Guide* .
859 *
860 * The Groups, Roles, and Users properties are optional. However, you must specify at least one of these properties.
861 *
862 * For information about limits on the number of inline policies that you can embed in an identity, see [Limitations on IAM Entities](https://docs.aws.amazon.com/IAM/latest/UserGuide/LimitationsOnEntities.html) in the *IAM User Guide* .
863 *
864 * @cloudformationResource AWS::IAM::Policy
865 * @stability external
866 *
867 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html
868 */
869class CfnPolicy extends cdk.CfnResource {
870 /**
871 * Create a new `AWS::IAM::Policy`.
872 *
873 * @param scope - scope in which this resource is defined
874 * @param id - scoped id of the resource
875 * @param props - resource properties
876 */
877 constructor(scope, id, props) {
878 super(scope, id, { type: CfnPolicy.CFN_RESOURCE_TYPE_NAME, properties: props });
879 try {
880 jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnPolicyProps(props);
881 }
882 catch (error) {
883 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
884 Error.captureStackTrace(error, CfnPolicy);
885 }
886 throw error;
887 }
888 cdk.requireProperty(props, 'policyDocument', this);
889 cdk.requireProperty(props, 'policyName', this);
890 this.policyDocument = props.policyDocument;
891 this.policyName = props.policyName;
892 this.groups = props.groups;
893 this.roles = props.roles;
894 this.users = props.users;
895 }
896 /**
897 * A factory method that creates a new instance of this class from an object
898 * containing the CloudFormation properties of this resource.
899 * Used in the @aws-cdk/cloudformation-include module.
900 *
901 * @internal
902 */
903 static _fromCloudFormation(scope, id, resourceAttributes, options) {
904 resourceAttributes = resourceAttributes || {};
905 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
906 const propsResult = CfnPolicyPropsFromCloudFormation(resourceProperties);
907 const ret = new CfnPolicy(scope, id, propsResult.value);
908 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
909 ret.addPropertyOverride(propKey, propVal);
910 }
911 options.parser.handleAttributes(ret, resourceAttributes, id);
912 return ret;
913 }
914 /**
915 * Examines the CloudFormation resource and discloses attributes.
916 *
917 * @param inspector - tree inspector to collect and process attributes
918 *
919 */
920 inspect(inspector) {
921 inspector.addAttribute("aws:cdk:cloudformation:type", CfnPolicy.CFN_RESOURCE_TYPE_NAME);
922 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
923 }
924 get cfnProperties() {
925 return {
926 policyDocument: this.policyDocument,
927 policyName: this.policyName,
928 groups: this.groups,
929 roles: this.roles,
930 users: this.users,
931 };
932 }
933 renderProperties(props) {
934 return cfnPolicyPropsToCloudFormation(props);
935 }
936}
937exports.CfnPolicy = CfnPolicy;
938_f = JSII_RTTI_SYMBOL_1;
939CfnPolicy[_f] = { fqn: "@aws-cdk/aws-iam.CfnPolicy", version: "1.161.0" };
940/**
941 * The CloudFormation resource type name for this resource class.
942 */
943CfnPolicy.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::Policy";
944/**
945 * Determine whether the given properties match those of a `CfnRoleProps`
946 *
947 * @param properties - the TypeScript properties of a `CfnRoleProps`
948 *
949 * @returns the result of the validation.
950 */
951function CfnRolePropsValidator(properties) {
952 if (!cdk.canInspect(properties)) {
953 return cdk.VALIDATION_SUCCESS;
954 }
955 const errors = new cdk.ValidationResults();
956 if (typeof properties !== 'object') {
957 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
958 }
959 errors.collect(cdk.propertyValidator('assumeRolePolicyDocument', cdk.requiredValidator)(properties.assumeRolePolicyDocument));
960 errors.collect(cdk.propertyValidator('assumeRolePolicyDocument', cdk.validateObject)(properties.assumeRolePolicyDocument));
961 errors.collect(cdk.propertyValidator('description', cdk.validateString)(properties.description));
962 errors.collect(cdk.propertyValidator('managedPolicyArns', cdk.listValidator(cdk.validateString))(properties.managedPolicyArns));
963 errors.collect(cdk.propertyValidator('maxSessionDuration', cdk.validateNumber)(properties.maxSessionDuration));
964 errors.collect(cdk.propertyValidator('path', cdk.validateString)(properties.path));
965 errors.collect(cdk.propertyValidator('permissionsBoundary', cdk.validateString)(properties.permissionsBoundary));
966 errors.collect(cdk.propertyValidator('policies', cdk.listValidator(CfnRole_PolicyPropertyValidator))(properties.policies));
967 errors.collect(cdk.propertyValidator('roleName', cdk.validateString)(properties.roleName));
968 errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
969 return errors.wrap('supplied properties not correct for "CfnRoleProps"');
970}
971/**
972 * Renders the AWS CloudFormation properties of an `AWS::IAM::Role` resource
973 *
974 * @param properties - the TypeScript properties of a `CfnRoleProps`
975 *
976 * @returns the AWS CloudFormation properties of an `AWS::IAM::Role` resource.
977 */
978// @ts-ignore TS6133
979function cfnRolePropsToCloudFormation(properties) {
980 if (!cdk.canInspect(properties)) {
981 return properties;
982 }
983 CfnRolePropsValidator(properties).assertSuccess();
984 return {
985 AssumeRolePolicyDocument: cdk.objectToCloudFormation(properties.assumeRolePolicyDocument),
986 Description: cdk.stringToCloudFormation(properties.description),
987 ManagedPolicyArns: cdk.listMapper(cdk.stringToCloudFormation)(properties.managedPolicyArns),
988 MaxSessionDuration: cdk.numberToCloudFormation(properties.maxSessionDuration),
989 Path: cdk.stringToCloudFormation(properties.path),
990 PermissionsBoundary: cdk.stringToCloudFormation(properties.permissionsBoundary),
991 Policies: cdk.listMapper(cfnRolePolicyPropertyToCloudFormation)(properties.policies),
992 RoleName: cdk.stringToCloudFormation(properties.roleName),
993 Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
994 };
995}
996// @ts-ignore TS6133
997function CfnRolePropsFromCloudFormation(properties) {
998 properties = properties == null ? {} : properties;
999 if (typeof properties !== 'object') {
1000 return new cfn_parse.FromCloudFormationResult(properties);
1001 }
1002 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1003 ret.addPropertyResult('assumeRolePolicyDocument', 'AssumeRolePolicyDocument', cfn_parse.FromCloudFormation.getAny(properties.AssumeRolePolicyDocument));
1004 ret.addPropertyResult('description', 'Description', properties.Description != null ? cfn_parse.FromCloudFormation.getString(properties.Description) : undefined);
1005 ret.addPropertyResult('managedPolicyArns', 'ManagedPolicyArns', properties.ManagedPolicyArns != null ? cfn_parse.FromCloudFormation.getStringArray(properties.ManagedPolicyArns) : undefined);
1006 ret.addPropertyResult('maxSessionDuration', 'MaxSessionDuration', properties.MaxSessionDuration != null ? cfn_parse.FromCloudFormation.getNumber(properties.MaxSessionDuration) : undefined);
1007 ret.addPropertyResult('path', 'Path', properties.Path != null ? cfn_parse.FromCloudFormation.getString(properties.Path) : undefined);
1008 ret.addPropertyResult('permissionsBoundary', 'PermissionsBoundary', properties.PermissionsBoundary != null ? cfn_parse.FromCloudFormation.getString(properties.PermissionsBoundary) : undefined);
1009 ret.addPropertyResult('policies', 'Policies', properties.Policies != null ? cfn_parse.FromCloudFormation.getArray(CfnRolePolicyPropertyFromCloudFormation)(properties.Policies) : undefined);
1010 ret.addPropertyResult('roleName', 'RoleName', properties.RoleName != null ? cfn_parse.FromCloudFormation.getString(properties.RoleName) : undefined);
1011 ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
1012 ret.addUnrecognizedPropertiesAsExtra(properties);
1013 return ret;
1014}
1015/**
1016 * A CloudFormation `AWS::IAM::Role`
1017 *
1018 * Creates a new role for your AWS account . For more information about roles, see [IAM roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/WorkingWithRoles.html) . For information about quotas for role names and the number of roles you can create, see [IAM and AWS STS quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) in the *IAM User Guide* .
1019 *
1020 * @cloudformationResource AWS::IAM::Role
1021 * @stability external
1022 *
1023 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html
1024 */
1025class CfnRole extends cdk.CfnResource {
1026 /**
1027 * Create a new `AWS::IAM::Role`.
1028 *
1029 * @param scope - scope in which this resource is defined
1030 * @param id - scoped id of the resource
1031 * @param props - resource properties
1032 */
1033 constructor(scope, id, props) {
1034 super(scope, id, { type: CfnRole.CFN_RESOURCE_TYPE_NAME, properties: props });
1035 try {
1036 jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnRoleProps(props);
1037 }
1038 catch (error) {
1039 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1040 Error.captureStackTrace(error, CfnRole);
1041 }
1042 throw error;
1043 }
1044 cdk.requireProperty(props, 'assumeRolePolicyDocument', this);
1045 this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
1046 this.attrRoleId = cdk.Token.asString(this.getAtt('RoleId'));
1047 this.assumeRolePolicyDocument = props.assumeRolePolicyDocument;
1048 this.description = props.description;
1049 this.managedPolicyArns = props.managedPolicyArns;
1050 this.maxSessionDuration = props.maxSessionDuration;
1051 this.path = props.path;
1052 this.permissionsBoundary = props.permissionsBoundary;
1053 this.policies = props.policies;
1054 this.roleName = props.roleName;
1055 this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::IAM::Role", props.tags, { tagPropertyName: 'tags' });
1056 }
1057 /**
1058 * A factory method that creates a new instance of this class from an object
1059 * containing the CloudFormation properties of this resource.
1060 * Used in the @aws-cdk/cloudformation-include module.
1061 *
1062 * @internal
1063 */
1064 static _fromCloudFormation(scope, id, resourceAttributes, options) {
1065 resourceAttributes = resourceAttributes || {};
1066 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
1067 const propsResult = CfnRolePropsFromCloudFormation(resourceProperties);
1068 const ret = new CfnRole(scope, id, propsResult.value);
1069 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
1070 ret.addPropertyOverride(propKey, propVal);
1071 }
1072 options.parser.handleAttributes(ret, resourceAttributes, id);
1073 return ret;
1074 }
1075 /**
1076 * Examines the CloudFormation resource and discloses attributes.
1077 *
1078 * @param inspector - tree inspector to collect and process attributes
1079 *
1080 */
1081 inspect(inspector) {
1082 inspector.addAttribute("aws:cdk:cloudformation:type", CfnRole.CFN_RESOURCE_TYPE_NAME);
1083 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
1084 }
1085 get cfnProperties() {
1086 return {
1087 assumeRolePolicyDocument: this.assumeRolePolicyDocument,
1088 description: this.description,
1089 managedPolicyArns: this.managedPolicyArns,
1090 maxSessionDuration: this.maxSessionDuration,
1091 path: this.path,
1092 permissionsBoundary: this.permissionsBoundary,
1093 policies: this.policies,
1094 roleName: this.roleName,
1095 tags: this.tags.renderTags(),
1096 };
1097 }
1098 renderProperties(props) {
1099 return cfnRolePropsToCloudFormation(props);
1100 }
1101}
1102exports.CfnRole = CfnRole;
1103_g = JSII_RTTI_SYMBOL_1;
1104CfnRole[_g] = { fqn: "@aws-cdk/aws-iam.CfnRole", version: "1.161.0" };
1105/**
1106 * The CloudFormation resource type name for this resource class.
1107 */
1108CfnRole.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::Role";
1109/**
1110 * Determine whether the given properties match those of a `PolicyProperty`
1111 *
1112 * @param properties - the TypeScript properties of a `PolicyProperty`
1113 *
1114 * @returns the result of the validation.
1115 */
1116function CfnRole_PolicyPropertyValidator(properties) {
1117 if (!cdk.canInspect(properties)) {
1118 return cdk.VALIDATION_SUCCESS;
1119 }
1120 const errors = new cdk.ValidationResults();
1121 if (typeof properties !== 'object') {
1122 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1123 }
1124 errors.collect(cdk.propertyValidator('policyDocument', cdk.requiredValidator)(properties.policyDocument));
1125 errors.collect(cdk.propertyValidator('policyDocument', cdk.validateObject)(properties.policyDocument));
1126 errors.collect(cdk.propertyValidator('policyName', cdk.requiredValidator)(properties.policyName));
1127 errors.collect(cdk.propertyValidator('policyName', cdk.validateString)(properties.policyName));
1128 return errors.wrap('supplied properties not correct for "PolicyProperty"');
1129}
1130/**
1131 * Renders the AWS CloudFormation properties of an `AWS::IAM::Role.Policy` resource
1132 *
1133 * @param properties - the TypeScript properties of a `PolicyProperty`
1134 *
1135 * @returns the AWS CloudFormation properties of an `AWS::IAM::Role.Policy` resource.
1136 */
1137// @ts-ignore TS6133
1138function cfnRolePolicyPropertyToCloudFormation(properties) {
1139 if (!cdk.canInspect(properties)) {
1140 return properties;
1141 }
1142 CfnRole_PolicyPropertyValidator(properties).assertSuccess();
1143 return {
1144 PolicyDocument: cdk.objectToCloudFormation(properties.policyDocument),
1145 PolicyName: cdk.stringToCloudFormation(properties.policyName),
1146 };
1147}
1148// @ts-ignore TS6133
1149function CfnRolePolicyPropertyFromCloudFormation(properties) {
1150 if (cdk.isResolvableObject(properties)) {
1151 return new cfn_parse.FromCloudFormationResult(properties);
1152 }
1153 properties = properties == null ? {} : properties;
1154 if (typeof properties !== 'object') {
1155 return new cfn_parse.FromCloudFormationResult(properties);
1156 }
1157 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1158 ret.addPropertyResult('policyDocument', 'PolicyDocument', cfn_parse.FromCloudFormation.getAny(properties.PolicyDocument));
1159 ret.addPropertyResult('policyName', 'PolicyName', cfn_parse.FromCloudFormation.getString(properties.PolicyName));
1160 ret.addUnrecognizedPropertiesAsExtra(properties);
1161 return ret;
1162}
1163/**
1164 * Determine whether the given properties match those of a `CfnSAMLProviderProps`
1165 *
1166 * @param properties - the TypeScript properties of a `CfnSAMLProviderProps`
1167 *
1168 * @returns the result of the validation.
1169 */
1170function CfnSAMLProviderPropsValidator(properties) {
1171 if (!cdk.canInspect(properties)) {
1172 return cdk.VALIDATION_SUCCESS;
1173 }
1174 const errors = new cdk.ValidationResults();
1175 if (typeof properties !== 'object') {
1176 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1177 }
1178 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
1179 errors.collect(cdk.propertyValidator('samlMetadataDocument', cdk.requiredValidator)(properties.samlMetadataDocument));
1180 errors.collect(cdk.propertyValidator('samlMetadataDocument', cdk.validateString)(properties.samlMetadataDocument));
1181 errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
1182 return errors.wrap('supplied properties not correct for "CfnSAMLProviderProps"');
1183}
1184/**
1185 * Renders the AWS CloudFormation properties of an `AWS::IAM::SAMLProvider` resource
1186 *
1187 * @param properties - the TypeScript properties of a `CfnSAMLProviderProps`
1188 *
1189 * @returns the AWS CloudFormation properties of an `AWS::IAM::SAMLProvider` resource.
1190 */
1191// @ts-ignore TS6133
1192function cfnSAMLProviderPropsToCloudFormation(properties) {
1193 if (!cdk.canInspect(properties)) {
1194 return properties;
1195 }
1196 CfnSAMLProviderPropsValidator(properties).assertSuccess();
1197 return {
1198 SamlMetadataDocument: cdk.stringToCloudFormation(properties.samlMetadataDocument),
1199 Name: cdk.stringToCloudFormation(properties.name),
1200 Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
1201 };
1202}
1203// @ts-ignore TS6133
1204function CfnSAMLProviderPropsFromCloudFormation(properties) {
1205 properties = properties == null ? {} : properties;
1206 if (typeof properties !== 'object') {
1207 return new cfn_parse.FromCloudFormationResult(properties);
1208 }
1209 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1210 ret.addPropertyResult('samlMetadataDocument', 'SamlMetadataDocument', cfn_parse.FromCloudFormation.getString(properties.SamlMetadataDocument));
1211 ret.addPropertyResult('name', 'Name', properties.Name != null ? cfn_parse.FromCloudFormation.getString(properties.Name) : undefined);
1212 ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
1213 ret.addUnrecognizedPropertiesAsExtra(properties);
1214 return ret;
1215}
1216/**
1217 * A CloudFormation `AWS::IAM::SAMLProvider`
1218 *
1219 * Creates an IAM resource that describes an identity provider (IdP) that supports SAML 2.0.
1220 *
1221 * The SAML provider resource that you create with this operation can be used as a principal in an IAM role's trust policy. Such a policy can enable federated users who sign in using the SAML IdP to assume the role. You can create an IAM role that supports Web-based single sign-on (SSO) to the AWS Management Console or one that supports API access to AWS .
1222 *
1223 * When you create the SAML provider resource, you upload a SAML metadata document that you get from your IdP. That document includes the issuer's name, expiration information, and keys that can be used to validate the SAML authentication response (assertions) that the IdP sends. You must generate the metadata document using the identity management software that is used as your organization's IdP.
1224 *
1225 * > This operation requires [Signature Version 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) .
1226 *
1227 * For more information, see [Enabling SAML 2.0 federated users to access the AWS Management Console](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-saml.html) and [About SAML 2.0-based federation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html) in the *IAM User Guide* .
1228 *
1229 * @cloudformationResource AWS::IAM::SAMLProvider
1230 * @stability external
1231 *
1232 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-samlprovider.html
1233 */
1234class CfnSAMLProvider extends cdk.CfnResource {
1235 /**
1236 * Create a new `AWS::IAM::SAMLProvider`.
1237 *
1238 * @param scope - scope in which this resource is defined
1239 * @param id - scoped id of the resource
1240 * @param props - resource properties
1241 */
1242 constructor(scope, id, props) {
1243 super(scope, id, { type: CfnSAMLProvider.CFN_RESOURCE_TYPE_NAME, properties: props });
1244 try {
1245 jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnSAMLProviderProps(props);
1246 }
1247 catch (error) {
1248 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1249 Error.captureStackTrace(error, CfnSAMLProvider);
1250 }
1251 throw error;
1252 }
1253 cdk.requireProperty(props, 'samlMetadataDocument', this);
1254 this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
1255 this.samlMetadataDocument = props.samlMetadataDocument;
1256 this.name = props.name;
1257 this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::IAM::SAMLProvider", props.tags, { tagPropertyName: 'tags' });
1258 }
1259 /**
1260 * A factory method that creates a new instance of this class from an object
1261 * containing the CloudFormation properties of this resource.
1262 * Used in the @aws-cdk/cloudformation-include module.
1263 *
1264 * @internal
1265 */
1266 static _fromCloudFormation(scope, id, resourceAttributes, options) {
1267 resourceAttributes = resourceAttributes || {};
1268 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
1269 const propsResult = CfnSAMLProviderPropsFromCloudFormation(resourceProperties);
1270 const ret = new CfnSAMLProvider(scope, id, propsResult.value);
1271 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
1272 ret.addPropertyOverride(propKey, propVal);
1273 }
1274 options.parser.handleAttributes(ret, resourceAttributes, id);
1275 return ret;
1276 }
1277 /**
1278 * Examines the CloudFormation resource and discloses attributes.
1279 *
1280 * @param inspector - tree inspector to collect and process attributes
1281 *
1282 */
1283 inspect(inspector) {
1284 inspector.addAttribute("aws:cdk:cloudformation:type", CfnSAMLProvider.CFN_RESOURCE_TYPE_NAME);
1285 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
1286 }
1287 get cfnProperties() {
1288 return {
1289 samlMetadataDocument: this.samlMetadataDocument,
1290 name: this.name,
1291 tags: this.tags.renderTags(),
1292 };
1293 }
1294 renderProperties(props) {
1295 return cfnSAMLProviderPropsToCloudFormation(props);
1296 }
1297}
1298exports.CfnSAMLProvider = CfnSAMLProvider;
1299_h = JSII_RTTI_SYMBOL_1;
1300CfnSAMLProvider[_h] = { fqn: "@aws-cdk/aws-iam.CfnSAMLProvider", version: "1.161.0" };
1301/**
1302 * The CloudFormation resource type name for this resource class.
1303 */
1304CfnSAMLProvider.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::SAMLProvider";
1305/**
1306 * Determine whether the given properties match those of a `CfnServerCertificateProps`
1307 *
1308 * @param properties - the TypeScript properties of a `CfnServerCertificateProps`
1309 *
1310 * @returns the result of the validation.
1311 */
1312function CfnServerCertificatePropsValidator(properties) {
1313 if (!cdk.canInspect(properties)) {
1314 return cdk.VALIDATION_SUCCESS;
1315 }
1316 const errors = new cdk.ValidationResults();
1317 if (typeof properties !== 'object') {
1318 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1319 }
1320 errors.collect(cdk.propertyValidator('certificateBody', cdk.validateString)(properties.certificateBody));
1321 errors.collect(cdk.propertyValidator('certificateChain', cdk.validateString)(properties.certificateChain));
1322 errors.collect(cdk.propertyValidator('path', cdk.validateString)(properties.path));
1323 errors.collect(cdk.propertyValidator('privateKey', cdk.validateString)(properties.privateKey));
1324 errors.collect(cdk.propertyValidator('serverCertificateName', cdk.validateString)(properties.serverCertificateName));
1325 errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
1326 return errors.wrap('supplied properties not correct for "CfnServerCertificateProps"');
1327}
1328/**
1329 * Renders the AWS CloudFormation properties of an `AWS::IAM::ServerCertificate` resource
1330 *
1331 * @param properties - the TypeScript properties of a `CfnServerCertificateProps`
1332 *
1333 * @returns the AWS CloudFormation properties of an `AWS::IAM::ServerCertificate` resource.
1334 */
1335// @ts-ignore TS6133
1336function cfnServerCertificatePropsToCloudFormation(properties) {
1337 if (!cdk.canInspect(properties)) {
1338 return properties;
1339 }
1340 CfnServerCertificatePropsValidator(properties).assertSuccess();
1341 return {
1342 CertificateBody: cdk.stringToCloudFormation(properties.certificateBody),
1343 CertificateChain: cdk.stringToCloudFormation(properties.certificateChain),
1344 Path: cdk.stringToCloudFormation(properties.path),
1345 PrivateKey: cdk.stringToCloudFormation(properties.privateKey),
1346 ServerCertificateName: cdk.stringToCloudFormation(properties.serverCertificateName),
1347 Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
1348 };
1349}
1350// @ts-ignore TS6133
1351function CfnServerCertificatePropsFromCloudFormation(properties) {
1352 properties = properties == null ? {} : properties;
1353 if (typeof properties !== 'object') {
1354 return new cfn_parse.FromCloudFormationResult(properties);
1355 }
1356 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1357 ret.addPropertyResult('certificateBody', 'CertificateBody', properties.CertificateBody != null ? cfn_parse.FromCloudFormation.getString(properties.CertificateBody) : undefined);
1358 ret.addPropertyResult('certificateChain', 'CertificateChain', properties.CertificateChain != null ? cfn_parse.FromCloudFormation.getString(properties.CertificateChain) : undefined);
1359 ret.addPropertyResult('path', 'Path', properties.Path != null ? cfn_parse.FromCloudFormation.getString(properties.Path) : undefined);
1360 ret.addPropertyResult('privateKey', 'PrivateKey', properties.PrivateKey != null ? cfn_parse.FromCloudFormation.getString(properties.PrivateKey) : undefined);
1361 ret.addPropertyResult('serverCertificateName', 'ServerCertificateName', properties.ServerCertificateName != null ? cfn_parse.FromCloudFormation.getString(properties.ServerCertificateName) : undefined);
1362 ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
1363 ret.addUnrecognizedPropertiesAsExtra(properties);
1364 return ret;
1365}
1366/**
1367 * A CloudFormation `AWS::IAM::ServerCertificate`
1368 *
1369 * Uploads a server certificate entity for the AWS account . The server certificate entity includes a public key certificate, a private key, and an optional certificate chain, which should all be PEM-encoded.
1370 *
1371 * We recommend that you use [AWS Certificate Manager](https://docs.aws.amazon.com/acm/) to provision, manage, and deploy your server certificates. With ACM you can request a certificate, deploy it to AWS resources, and let ACM handle certificate renewals for you. Certificates provided by ACM are free. For more information about using ACM, see the [AWS Certificate Manager User Guide](https://docs.aws.amazon.com/acm/latest/userguide/) .
1372 *
1373 * For more information about working with server certificates, see [Working with server certificates](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_server-certs.html) in the *IAM User Guide* . This topic includes a list of AWS services that can use the server certificates that you manage with IAM.
1374 *
1375 * For information about the number of server certificates you can upload, see [IAM and AWS STS quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) in the *IAM User Guide* .
1376 *
1377 * > Because the body of the public key certificate, private key, and the certificate chain can be large, you should use POST rather than GET when calling `UploadServerCertificate` . For information about setting up signatures and authorization through the API, see [Signing AWS API requests](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) in the *AWS General Reference* . For general information about using the Query API with IAM, see [Calling the API by making HTTP query requests](https://docs.aws.amazon.com/IAM/latest/UserGuide/programming.html) in the *IAM User Guide* .
1378 *
1379 * @cloudformationResource AWS::IAM::ServerCertificate
1380 * @stability external
1381 *
1382 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-servercertificate.html
1383 */
1384class CfnServerCertificate extends cdk.CfnResource {
1385 /**
1386 * Create a new `AWS::IAM::ServerCertificate`.
1387 *
1388 * @param scope - scope in which this resource is defined
1389 * @param id - scoped id of the resource
1390 * @param props - resource properties
1391 */
1392 constructor(scope, id, props = {}) {
1393 super(scope, id, { type: CfnServerCertificate.CFN_RESOURCE_TYPE_NAME, properties: props });
1394 try {
1395 jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnServerCertificateProps(props);
1396 }
1397 catch (error) {
1398 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1399 Error.captureStackTrace(error, CfnServerCertificate);
1400 }
1401 throw error;
1402 }
1403 this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
1404 this.certificateBody = props.certificateBody;
1405 this.certificateChain = props.certificateChain;
1406 this.path = props.path;
1407 this.privateKey = props.privateKey;
1408 this.serverCertificateName = props.serverCertificateName;
1409 this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::IAM::ServerCertificate", props.tags, { tagPropertyName: 'tags' });
1410 }
1411 /**
1412 * A factory method that creates a new instance of this class from an object
1413 * containing the CloudFormation properties of this resource.
1414 * Used in the @aws-cdk/cloudformation-include module.
1415 *
1416 * @internal
1417 */
1418 static _fromCloudFormation(scope, id, resourceAttributes, options) {
1419 resourceAttributes = resourceAttributes || {};
1420 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
1421 const propsResult = CfnServerCertificatePropsFromCloudFormation(resourceProperties);
1422 const ret = new CfnServerCertificate(scope, id, propsResult.value);
1423 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
1424 ret.addPropertyOverride(propKey, propVal);
1425 }
1426 options.parser.handleAttributes(ret, resourceAttributes, id);
1427 return ret;
1428 }
1429 /**
1430 * Examines the CloudFormation resource and discloses attributes.
1431 *
1432 * @param inspector - tree inspector to collect and process attributes
1433 *
1434 */
1435 inspect(inspector) {
1436 inspector.addAttribute("aws:cdk:cloudformation:type", CfnServerCertificate.CFN_RESOURCE_TYPE_NAME);
1437 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
1438 }
1439 get cfnProperties() {
1440 return {
1441 certificateBody: this.certificateBody,
1442 certificateChain: this.certificateChain,
1443 path: this.path,
1444 privateKey: this.privateKey,
1445 serverCertificateName: this.serverCertificateName,
1446 tags: this.tags.renderTags(),
1447 };
1448 }
1449 renderProperties(props) {
1450 return cfnServerCertificatePropsToCloudFormation(props);
1451 }
1452}
1453exports.CfnServerCertificate = CfnServerCertificate;
1454_j = JSII_RTTI_SYMBOL_1;
1455CfnServerCertificate[_j] = { fqn: "@aws-cdk/aws-iam.CfnServerCertificate", version: "1.161.0" };
1456/**
1457 * The CloudFormation resource type name for this resource class.
1458 */
1459CfnServerCertificate.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::ServerCertificate";
1460/**
1461 * Determine whether the given properties match those of a `CfnServiceLinkedRoleProps`
1462 *
1463 * @param properties - the TypeScript properties of a `CfnServiceLinkedRoleProps`
1464 *
1465 * @returns the result of the validation.
1466 */
1467function CfnServiceLinkedRolePropsValidator(properties) {
1468 if (!cdk.canInspect(properties)) {
1469 return cdk.VALIDATION_SUCCESS;
1470 }
1471 const errors = new cdk.ValidationResults();
1472 if (typeof properties !== 'object') {
1473 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1474 }
1475 errors.collect(cdk.propertyValidator('awsServiceName', cdk.requiredValidator)(properties.awsServiceName));
1476 errors.collect(cdk.propertyValidator('awsServiceName', cdk.validateString)(properties.awsServiceName));
1477 errors.collect(cdk.propertyValidator('customSuffix', cdk.validateString)(properties.customSuffix));
1478 errors.collect(cdk.propertyValidator('description', cdk.validateString)(properties.description));
1479 return errors.wrap('supplied properties not correct for "CfnServiceLinkedRoleProps"');
1480}
1481/**
1482 * Renders the AWS CloudFormation properties of an `AWS::IAM::ServiceLinkedRole` resource
1483 *
1484 * @param properties - the TypeScript properties of a `CfnServiceLinkedRoleProps`
1485 *
1486 * @returns the AWS CloudFormation properties of an `AWS::IAM::ServiceLinkedRole` resource.
1487 */
1488// @ts-ignore TS6133
1489function cfnServiceLinkedRolePropsToCloudFormation(properties) {
1490 if (!cdk.canInspect(properties)) {
1491 return properties;
1492 }
1493 CfnServiceLinkedRolePropsValidator(properties).assertSuccess();
1494 return {
1495 AWSServiceName: cdk.stringToCloudFormation(properties.awsServiceName),
1496 CustomSuffix: cdk.stringToCloudFormation(properties.customSuffix),
1497 Description: cdk.stringToCloudFormation(properties.description),
1498 };
1499}
1500// @ts-ignore TS6133
1501function CfnServiceLinkedRolePropsFromCloudFormation(properties) {
1502 properties = properties == null ? {} : properties;
1503 if (typeof properties !== 'object') {
1504 return new cfn_parse.FromCloudFormationResult(properties);
1505 }
1506 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1507 ret.addPropertyResult('awsServiceName', 'AWSServiceName', cfn_parse.FromCloudFormation.getString(properties.AWSServiceName));
1508 ret.addPropertyResult('customSuffix', 'CustomSuffix', properties.CustomSuffix != null ? cfn_parse.FromCloudFormation.getString(properties.CustomSuffix) : undefined);
1509 ret.addPropertyResult('description', 'Description', properties.Description != null ? cfn_parse.FromCloudFormation.getString(properties.Description) : undefined);
1510 ret.addUnrecognizedPropertiesAsExtra(properties);
1511 return ret;
1512}
1513/**
1514 * A CloudFormation `AWS::IAM::ServiceLinkedRole`
1515 *
1516 * Creates an IAM role that is linked to a specific AWS service. The service controls the attached policies and when the role can be deleted. This helps ensure that the service is not broken by an unexpectedly changed or deleted role, which could put your AWS resources into an unknown state. Allowing the service to control the role helps improve service stability and proper cleanup when a service and its role are no longer needed. For more information, see [Using service-linked roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html) in the *IAM User Guide* .
1517 *
1518 * To attach a policy to this service-linked role, you must make the request using the AWS service that depends on this role.
1519 *
1520 * @cloudformationResource AWS::IAM::ServiceLinkedRole
1521 * @stability external
1522 *
1523 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-servicelinkedrole.html
1524 */
1525class CfnServiceLinkedRole extends cdk.CfnResource {
1526 /**
1527 * Create a new `AWS::IAM::ServiceLinkedRole`.
1528 *
1529 * @param scope - scope in which this resource is defined
1530 * @param id - scoped id of the resource
1531 * @param props - resource properties
1532 */
1533 constructor(scope, id, props) {
1534 super(scope, id, { type: CfnServiceLinkedRole.CFN_RESOURCE_TYPE_NAME, properties: props });
1535 try {
1536 jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnServiceLinkedRoleProps(props);
1537 }
1538 catch (error) {
1539 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1540 Error.captureStackTrace(error, CfnServiceLinkedRole);
1541 }
1542 throw error;
1543 }
1544 cdk.requireProperty(props, 'awsServiceName', this);
1545 this.awsServiceName = props.awsServiceName;
1546 this.customSuffix = props.customSuffix;
1547 this.description = props.description;
1548 }
1549 /**
1550 * A factory method that creates a new instance of this class from an object
1551 * containing the CloudFormation properties of this resource.
1552 * Used in the @aws-cdk/cloudformation-include module.
1553 *
1554 * @internal
1555 */
1556 static _fromCloudFormation(scope, id, resourceAttributes, options) {
1557 resourceAttributes = resourceAttributes || {};
1558 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
1559 const propsResult = CfnServiceLinkedRolePropsFromCloudFormation(resourceProperties);
1560 const ret = new CfnServiceLinkedRole(scope, id, propsResult.value);
1561 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
1562 ret.addPropertyOverride(propKey, propVal);
1563 }
1564 options.parser.handleAttributes(ret, resourceAttributes, id);
1565 return ret;
1566 }
1567 /**
1568 * Examines the CloudFormation resource and discloses attributes.
1569 *
1570 * @param inspector - tree inspector to collect and process attributes
1571 *
1572 */
1573 inspect(inspector) {
1574 inspector.addAttribute("aws:cdk:cloudformation:type", CfnServiceLinkedRole.CFN_RESOURCE_TYPE_NAME);
1575 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
1576 }
1577 get cfnProperties() {
1578 return {
1579 awsServiceName: this.awsServiceName,
1580 customSuffix: this.customSuffix,
1581 description: this.description,
1582 };
1583 }
1584 renderProperties(props) {
1585 return cfnServiceLinkedRolePropsToCloudFormation(props);
1586 }
1587}
1588exports.CfnServiceLinkedRole = CfnServiceLinkedRole;
1589_k = JSII_RTTI_SYMBOL_1;
1590CfnServiceLinkedRole[_k] = { fqn: "@aws-cdk/aws-iam.CfnServiceLinkedRole", version: "1.161.0" };
1591/**
1592 * The CloudFormation resource type name for this resource class.
1593 */
1594CfnServiceLinkedRole.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::ServiceLinkedRole";
1595/**
1596 * Determine whether the given properties match those of a `CfnUserProps`
1597 *
1598 * @param properties - the TypeScript properties of a `CfnUserProps`
1599 *
1600 * @returns the result of the validation.
1601 */
1602function CfnUserPropsValidator(properties) {
1603 if (!cdk.canInspect(properties)) {
1604 return cdk.VALIDATION_SUCCESS;
1605 }
1606 const errors = new cdk.ValidationResults();
1607 if (typeof properties !== 'object') {
1608 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1609 }
1610 errors.collect(cdk.propertyValidator('groups', cdk.listValidator(cdk.validateString))(properties.groups));
1611 errors.collect(cdk.propertyValidator('loginProfile', CfnUser_LoginProfilePropertyValidator)(properties.loginProfile));
1612 errors.collect(cdk.propertyValidator('managedPolicyArns', cdk.listValidator(cdk.validateString))(properties.managedPolicyArns));
1613 errors.collect(cdk.propertyValidator('path', cdk.validateString)(properties.path));
1614 errors.collect(cdk.propertyValidator('permissionsBoundary', cdk.validateString)(properties.permissionsBoundary));
1615 errors.collect(cdk.propertyValidator('policies', cdk.listValidator(CfnUser_PolicyPropertyValidator))(properties.policies));
1616 errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
1617 errors.collect(cdk.propertyValidator('userName', cdk.validateString)(properties.userName));
1618 return errors.wrap('supplied properties not correct for "CfnUserProps"');
1619}
1620/**
1621 * Renders the AWS CloudFormation properties of an `AWS::IAM::User` resource
1622 *
1623 * @param properties - the TypeScript properties of a `CfnUserProps`
1624 *
1625 * @returns the AWS CloudFormation properties of an `AWS::IAM::User` resource.
1626 */
1627// @ts-ignore TS6133
1628function cfnUserPropsToCloudFormation(properties) {
1629 if (!cdk.canInspect(properties)) {
1630 return properties;
1631 }
1632 CfnUserPropsValidator(properties).assertSuccess();
1633 return {
1634 Groups: cdk.listMapper(cdk.stringToCloudFormation)(properties.groups),
1635 LoginProfile: cfnUserLoginProfilePropertyToCloudFormation(properties.loginProfile),
1636 ManagedPolicyArns: cdk.listMapper(cdk.stringToCloudFormation)(properties.managedPolicyArns),
1637 Path: cdk.stringToCloudFormation(properties.path),
1638 PermissionsBoundary: cdk.stringToCloudFormation(properties.permissionsBoundary),
1639 Policies: cdk.listMapper(cfnUserPolicyPropertyToCloudFormation)(properties.policies),
1640 Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
1641 UserName: cdk.stringToCloudFormation(properties.userName),
1642 };
1643}
1644// @ts-ignore TS6133
1645function CfnUserPropsFromCloudFormation(properties) {
1646 properties = properties == null ? {} : properties;
1647 if (typeof properties !== 'object') {
1648 return new cfn_parse.FromCloudFormationResult(properties);
1649 }
1650 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1651 ret.addPropertyResult('groups', 'Groups', properties.Groups != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Groups) : undefined);
1652 ret.addPropertyResult('loginProfile', 'LoginProfile', properties.LoginProfile != null ? CfnUserLoginProfilePropertyFromCloudFormation(properties.LoginProfile) : undefined);
1653 ret.addPropertyResult('managedPolicyArns', 'ManagedPolicyArns', properties.ManagedPolicyArns != null ? cfn_parse.FromCloudFormation.getStringArray(properties.ManagedPolicyArns) : undefined);
1654 ret.addPropertyResult('path', 'Path', properties.Path != null ? cfn_parse.FromCloudFormation.getString(properties.Path) : undefined);
1655 ret.addPropertyResult('permissionsBoundary', 'PermissionsBoundary', properties.PermissionsBoundary != null ? cfn_parse.FromCloudFormation.getString(properties.PermissionsBoundary) : undefined);
1656 ret.addPropertyResult('policies', 'Policies', properties.Policies != null ? cfn_parse.FromCloudFormation.getArray(CfnUserPolicyPropertyFromCloudFormation)(properties.Policies) : undefined);
1657 ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
1658 ret.addPropertyResult('userName', 'UserName', properties.UserName != null ? cfn_parse.FromCloudFormation.getString(properties.UserName) : undefined);
1659 ret.addUnrecognizedPropertiesAsExtra(properties);
1660 return ret;
1661}
1662/**
1663 * A CloudFormation `AWS::IAM::User`
1664 *
1665 * Creates a new IAM user for your AWS account .
1666 *
1667 * For information about quotas for the number of IAM users you can create, see [IAM and AWS STS quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) in the *IAM User Guide* .
1668 *
1669 * @cloudformationResource AWS::IAM::User
1670 * @stability external
1671 *
1672 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-user.html
1673 */
1674class CfnUser extends cdk.CfnResource {
1675 /**
1676 * Create a new `AWS::IAM::User`.
1677 *
1678 * @param scope - scope in which this resource is defined
1679 * @param id - scoped id of the resource
1680 * @param props - resource properties
1681 */
1682 constructor(scope, id, props = {}) {
1683 super(scope, id, { type: CfnUser.CFN_RESOURCE_TYPE_NAME, properties: props });
1684 try {
1685 jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnUserProps(props);
1686 }
1687 catch (error) {
1688 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1689 Error.captureStackTrace(error, CfnUser);
1690 }
1691 throw error;
1692 }
1693 this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
1694 this.groups = props.groups;
1695 this.loginProfile = props.loginProfile;
1696 this.managedPolicyArns = props.managedPolicyArns;
1697 this.path = props.path;
1698 this.permissionsBoundary = props.permissionsBoundary;
1699 this.policies = props.policies;
1700 this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::IAM::User", props.tags, { tagPropertyName: 'tags' });
1701 this.userName = props.userName;
1702 }
1703 /**
1704 * A factory method that creates a new instance of this class from an object
1705 * containing the CloudFormation properties of this resource.
1706 * Used in the @aws-cdk/cloudformation-include module.
1707 *
1708 * @internal
1709 */
1710 static _fromCloudFormation(scope, id, resourceAttributes, options) {
1711 resourceAttributes = resourceAttributes || {};
1712 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
1713 const propsResult = CfnUserPropsFromCloudFormation(resourceProperties);
1714 const ret = new CfnUser(scope, id, propsResult.value);
1715 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
1716 ret.addPropertyOverride(propKey, propVal);
1717 }
1718 options.parser.handleAttributes(ret, resourceAttributes, id);
1719 return ret;
1720 }
1721 /**
1722 * Examines the CloudFormation resource and discloses attributes.
1723 *
1724 * @param inspector - tree inspector to collect and process attributes
1725 *
1726 */
1727 inspect(inspector) {
1728 inspector.addAttribute("aws:cdk:cloudformation:type", CfnUser.CFN_RESOURCE_TYPE_NAME);
1729 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
1730 }
1731 get cfnProperties() {
1732 return {
1733 groups: this.groups,
1734 loginProfile: this.loginProfile,
1735 managedPolicyArns: this.managedPolicyArns,
1736 path: this.path,
1737 permissionsBoundary: this.permissionsBoundary,
1738 policies: this.policies,
1739 tags: this.tags.renderTags(),
1740 userName: this.userName,
1741 };
1742 }
1743 renderProperties(props) {
1744 return cfnUserPropsToCloudFormation(props);
1745 }
1746}
1747exports.CfnUser = CfnUser;
1748_l = JSII_RTTI_SYMBOL_1;
1749CfnUser[_l] = { fqn: "@aws-cdk/aws-iam.CfnUser", version: "1.161.0" };
1750/**
1751 * The CloudFormation resource type name for this resource class.
1752 */
1753CfnUser.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::User";
1754/**
1755 * Determine whether the given properties match those of a `LoginProfileProperty`
1756 *
1757 * @param properties - the TypeScript properties of a `LoginProfileProperty`
1758 *
1759 * @returns the result of the validation.
1760 */
1761function CfnUser_LoginProfilePropertyValidator(properties) {
1762 if (!cdk.canInspect(properties)) {
1763 return cdk.VALIDATION_SUCCESS;
1764 }
1765 const errors = new cdk.ValidationResults();
1766 if (typeof properties !== 'object') {
1767 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1768 }
1769 errors.collect(cdk.propertyValidator('password', cdk.requiredValidator)(properties.password));
1770 errors.collect(cdk.propertyValidator('password', cdk.validateString)(properties.password));
1771 errors.collect(cdk.propertyValidator('passwordResetRequired', cdk.validateBoolean)(properties.passwordResetRequired));
1772 return errors.wrap('supplied properties not correct for "LoginProfileProperty"');
1773}
1774/**
1775 * Renders the AWS CloudFormation properties of an `AWS::IAM::User.LoginProfile` resource
1776 *
1777 * @param properties - the TypeScript properties of a `LoginProfileProperty`
1778 *
1779 * @returns the AWS CloudFormation properties of an `AWS::IAM::User.LoginProfile` resource.
1780 */
1781// @ts-ignore TS6133
1782function cfnUserLoginProfilePropertyToCloudFormation(properties) {
1783 if (!cdk.canInspect(properties)) {
1784 return properties;
1785 }
1786 CfnUser_LoginProfilePropertyValidator(properties).assertSuccess();
1787 return {
1788 Password: cdk.stringToCloudFormation(properties.password),
1789 PasswordResetRequired: cdk.booleanToCloudFormation(properties.passwordResetRequired),
1790 };
1791}
1792// @ts-ignore TS6133
1793function CfnUserLoginProfilePropertyFromCloudFormation(properties) {
1794 if (cdk.isResolvableObject(properties)) {
1795 return new cfn_parse.FromCloudFormationResult(properties);
1796 }
1797 properties = properties == null ? {} : properties;
1798 if (typeof properties !== 'object') {
1799 return new cfn_parse.FromCloudFormationResult(properties);
1800 }
1801 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1802 ret.addPropertyResult('password', 'Password', cfn_parse.FromCloudFormation.getString(properties.Password));
1803 ret.addPropertyResult('passwordResetRequired', 'PasswordResetRequired', properties.PasswordResetRequired != null ? cfn_parse.FromCloudFormation.getBoolean(properties.PasswordResetRequired) : undefined);
1804 ret.addUnrecognizedPropertiesAsExtra(properties);
1805 return ret;
1806}
1807/**
1808 * Determine whether the given properties match those of a `PolicyProperty`
1809 *
1810 * @param properties - the TypeScript properties of a `PolicyProperty`
1811 *
1812 * @returns the result of the validation.
1813 */
1814function CfnUser_PolicyPropertyValidator(properties) {
1815 if (!cdk.canInspect(properties)) {
1816 return cdk.VALIDATION_SUCCESS;
1817 }
1818 const errors = new cdk.ValidationResults();
1819 if (typeof properties !== 'object') {
1820 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1821 }
1822 errors.collect(cdk.propertyValidator('policyDocument', cdk.requiredValidator)(properties.policyDocument));
1823 errors.collect(cdk.propertyValidator('policyDocument', cdk.validateObject)(properties.policyDocument));
1824 errors.collect(cdk.propertyValidator('policyName', cdk.requiredValidator)(properties.policyName));
1825 errors.collect(cdk.propertyValidator('policyName', cdk.validateString)(properties.policyName));
1826 return errors.wrap('supplied properties not correct for "PolicyProperty"');
1827}
1828/**
1829 * Renders the AWS CloudFormation properties of an `AWS::IAM::User.Policy` resource
1830 *
1831 * @param properties - the TypeScript properties of a `PolicyProperty`
1832 *
1833 * @returns the AWS CloudFormation properties of an `AWS::IAM::User.Policy` resource.
1834 */
1835// @ts-ignore TS6133
1836function cfnUserPolicyPropertyToCloudFormation(properties) {
1837 if (!cdk.canInspect(properties)) {
1838 return properties;
1839 }
1840 CfnUser_PolicyPropertyValidator(properties).assertSuccess();
1841 return {
1842 PolicyDocument: cdk.objectToCloudFormation(properties.policyDocument),
1843 PolicyName: cdk.stringToCloudFormation(properties.policyName),
1844 };
1845}
1846// @ts-ignore TS6133
1847function CfnUserPolicyPropertyFromCloudFormation(properties) {
1848 if (cdk.isResolvableObject(properties)) {
1849 return new cfn_parse.FromCloudFormationResult(properties);
1850 }
1851 properties = properties == null ? {} : properties;
1852 if (typeof properties !== 'object') {
1853 return new cfn_parse.FromCloudFormationResult(properties);
1854 }
1855 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1856 ret.addPropertyResult('policyDocument', 'PolicyDocument', cfn_parse.FromCloudFormation.getAny(properties.PolicyDocument));
1857 ret.addPropertyResult('policyName', 'PolicyName', cfn_parse.FromCloudFormation.getString(properties.PolicyName));
1858 ret.addUnrecognizedPropertiesAsExtra(properties);
1859 return ret;
1860}
1861/**
1862 * Determine whether the given properties match those of a `CfnUserToGroupAdditionProps`
1863 *
1864 * @param properties - the TypeScript properties of a `CfnUserToGroupAdditionProps`
1865 *
1866 * @returns the result of the validation.
1867 */
1868function CfnUserToGroupAdditionPropsValidator(properties) {
1869 if (!cdk.canInspect(properties)) {
1870 return cdk.VALIDATION_SUCCESS;
1871 }
1872 const errors = new cdk.ValidationResults();
1873 if (typeof properties !== 'object') {
1874 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1875 }
1876 errors.collect(cdk.propertyValidator('groupName', cdk.requiredValidator)(properties.groupName));
1877 errors.collect(cdk.propertyValidator('groupName', cdk.validateString)(properties.groupName));
1878 errors.collect(cdk.propertyValidator('users', cdk.requiredValidator)(properties.users));
1879 errors.collect(cdk.propertyValidator('users', cdk.listValidator(cdk.validateString))(properties.users));
1880 return errors.wrap('supplied properties not correct for "CfnUserToGroupAdditionProps"');
1881}
1882/**
1883 * Renders the AWS CloudFormation properties of an `AWS::IAM::UserToGroupAddition` resource
1884 *
1885 * @param properties - the TypeScript properties of a `CfnUserToGroupAdditionProps`
1886 *
1887 * @returns the AWS CloudFormation properties of an `AWS::IAM::UserToGroupAddition` resource.
1888 */
1889// @ts-ignore TS6133
1890function cfnUserToGroupAdditionPropsToCloudFormation(properties) {
1891 if (!cdk.canInspect(properties)) {
1892 return properties;
1893 }
1894 CfnUserToGroupAdditionPropsValidator(properties).assertSuccess();
1895 return {
1896 GroupName: cdk.stringToCloudFormation(properties.groupName),
1897 Users: cdk.listMapper(cdk.stringToCloudFormation)(properties.users),
1898 };
1899}
1900// @ts-ignore TS6133
1901function CfnUserToGroupAdditionPropsFromCloudFormation(properties) {
1902 properties = properties == null ? {} : properties;
1903 if (typeof properties !== 'object') {
1904 return new cfn_parse.FromCloudFormationResult(properties);
1905 }
1906 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1907 ret.addPropertyResult('groupName', 'GroupName', cfn_parse.FromCloudFormation.getString(properties.GroupName));
1908 ret.addPropertyResult('users', 'Users', cfn_parse.FromCloudFormation.getStringArray(properties.Users));
1909 ret.addUnrecognizedPropertiesAsExtra(properties);
1910 return ret;
1911}
1912/**
1913 * A CloudFormation `AWS::IAM::UserToGroupAddition`
1914 *
1915 * Adds the specified user to the specified group.
1916 *
1917 * @cloudformationResource AWS::IAM::UserToGroupAddition
1918 * @stability external
1919 *
1920 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-addusertogroup.html
1921 */
1922class CfnUserToGroupAddition extends cdk.CfnResource {
1923 /**
1924 * Create a new `AWS::IAM::UserToGroupAddition`.
1925 *
1926 * @param scope - scope in which this resource is defined
1927 * @param id - scoped id of the resource
1928 * @param props - resource properties
1929 */
1930 constructor(scope, id, props) {
1931 super(scope, id, { type: CfnUserToGroupAddition.CFN_RESOURCE_TYPE_NAME, properties: props });
1932 try {
1933 jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnUserToGroupAdditionProps(props);
1934 }
1935 catch (error) {
1936 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1937 Error.captureStackTrace(error, CfnUserToGroupAddition);
1938 }
1939 throw error;
1940 }
1941 cdk.requireProperty(props, 'groupName', this);
1942 cdk.requireProperty(props, 'users', this);
1943 this.groupName = props.groupName;
1944 this.users = props.users;
1945 }
1946 /**
1947 * A factory method that creates a new instance of this class from an object
1948 * containing the CloudFormation properties of this resource.
1949 * Used in the @aws-cdk/cloudformation-include module.
1950 *
1951 * @internal
1952 */
1953 static _fromCloudFormation(scope, id, resourceAttributes, options) {
1954 resourceAttributes = resourceAttributes || {};
1955 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
1956 const propsResult = CfnUserToGroupAdditionPropsFromCloudFormation(resourceProperties);
1957 const ret = new CfnUserToGroupAddition(scope, id, propsResult.value);
1958 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
1959 ret.addPropertyOverride(propKey, propVal);
1960 }
1961 options.parser.handleAttributes(ret, resourceAttributes, id);
1962 return ret;
1963 }
1964 /**
1965 * Examines the CloudFormation resource and discloses attributes.
1966 *
1967 * @param inspector - tree inspector to collect and process attributes
1968 *
1969 */
1970 inspect(inspector) {
1971 inspector.addAttribute("aws:cdk:cloudformation:type", CfnUserToGroupAddition.CFN_RESOURCE_TYPE_NAME);
1972 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
1973 }
1974 get cfnProperties() {
1975 return {
1976 groupName: this.groupName,
1977 users: this.users,
1978 };
1979 }
1980 renderProperties(props) {
1981 return cfnUserToGroupAdditionPropsToCloudFormation(props);
1982 }
1983}
1984exports.CfnUserToGroupAddition = CfnUserToGroupAddition;
1985_m = JSII_RTTI_SYMBOL_1;
1986CfnUserToGroupAddition[_m] = { fqn: "@aws-cdk/aws-iam.CfnUserToGroupAddition", version: "1.161.0" };
1987/**
1988 * The CloudFormation resource type name for this resource class.
1989 */
1990CfnUserToGroupAddition.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::UserToGroupAddition";
1991/**
1992 * Determine whether the given properties match those of a `CfnVirtualMFADeviceProps`
1993 *
1994 * @param properties - the TypeScript properties of a `CfnVirtualMFADeviceProps`
1995 *
1996 * @returns the result of the validation.
1997 */
1998function CfnVirtualMFADevicePropsValidator(properties) {
1999 if (!cdk.canInspect(properties)) {
2000 return cdk.VALIDATION_SUCCESS;
2001 }
2002 const errors = new cdk.ValidationResults();
2003 if (typeof properties !== 'object') {
2004 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
2005 }
2006 errors.collect(cdk.propertyValidator('path', cdk.validateString)(properties.path));
2007 errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
2008 errors.collect(cdk.propertyValidator('users', cdk.requiredValidator)(properties.users));
2009 errors.collect(cdk.propertyValidator('users', cdk.listValidator(cdk.validateString))(properties.users));
2010 errors.collect(cdk.propertyValidator('virtualMfaDeviceName', cdk.validateString)(properties.virtualMfaDeviceName));
2011 return errors.wrap('supplied properties not correct for "CfnVirtualMFADeviceProps"');
2012}
2013/**
2014 * Renders the AWS CloudFormation properties of an `AWS::IAM::VirtualMFADevice` resource
2015 *
2016 * @param properties - the TypeScript properties of a `CfnVirtualMFADeviceProps`
2017 *
2018 * @returns the AWS CloudFormation properties of an `AWS::IAM::VirtualMFADevice` resource.
2019 */
2020// @ts-ignore TS6133
2021function cfnVirtualMFADevicePropsToCloudFormation(properties) {
2022 if (!cdk.canInspect(properties)) {
2023 return properties;
2024 }
2025 CfnVirtualMFADevicePropsValidator(properties).assertSuccess();
2026 return {
2027 Users: cdk.listMapper(cdk.stringToCloudFormation)(properties.users),
2028 Path: cdk.stringToCloudFormation(properties.path),
2029 Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
2030 VirtualMfaDeviceName: cdk.stringToCloudFormation(properties.virtualMfaDeviceName),
2031 };
2032}
2033// @ts-ignore TS6133
2034function CfnVirtualMFADevicePropsFromCloudFormation(properties) {
2035 properties = properties == null ? {} : properties;
2036 if (typeof properties !== 'object') {
2037 return new cfn_parse.FromCloudFormationResult(properties);
2038 }
2039 const ret = new cfn_parse.FromCloudFormationPropertyObject();
2040 ret.addPropertyResult('users', 'Users', cfn_parse.FromCloudFormation.getStringArray(properties.Users));
2041 ret.addPropertyResult('path', 'Path', properties.Path != null ? cfn_parse.FromCloudFormation.getString(properties.Path) : undefined);
2042 ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
2043 ret.addPropertyResult('virtualMfaDeviceName', 'VirtualMfaDeviceName', properties.VirtualMfaDeviceName != null ? cfn_parse.FromCloudFormation.getString(properties.VirtualMfaDeviceName) : undefined);
2044 ret.addUnrecognizedPropertiesAsExtra(properties);
2045 return ret;
2046}
2047/**
2048 * A CloudFormation `AWS::IAM::VirtualMFADevice`
2049 *
2050 * Creates a new virtual MFA device for the AWS account . After creating the virtual MFA, use [EnableMFADevice](https://docs.aws.amazon.com/IAM/latest/APIReference/API_EnableMFADevice.html) to attach the MFA device to an IAM user. For more information about creating and working with virtual MFA devices, see [Using a virtual MFA device](https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_VirtualMFA.html) in the *IAM User Guide* .
2051 *
2052 * For information about the maximum number of MFA devices you can create, see [IAM and AWS STS quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) in the *IAM User Guide* .
2053 *
2054 * > The seed information contained in the QR code and the Base32 string should be treated like any other secret access information. In other words, protect the seed information as you would your AWS access keys or your passwords. After you provision your virtual device, you should ensure that the information is destroyed following secure procedures.
2055 *
2056 * @cloudformationResource AWS::IAM::VirtualMFADevice
2057 * @stability external
2058 *
2059 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-virtualmfadevice.html
2060 */
2061class CfnVirtualMFADevice extends cdk.CfnResource {
2062 /**
2063 * Create a new `AWS::IAM::VirtualMFADevice`.
2064 *
2065 * @param scope - scope in which this resource is defined
2066 * @param id - scoped id of the resource
2067 * @param props - resource properties
2068 */
2069 constructor(scope, id, props) {
2070 super(scope, id, { type: CfnVirtualMFADevice.CFN_RESOURCE_TYPE_NAME, properties: props });
2071 try {
2072 jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnVirtualMFADeviceProps(props);
2073 }
2074 catch (error) {
2075 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
2076 Error.captureStackTrace(error, CfnVirtualMFADevice);
2077 }
2078 throw error;
2079 }
2080 cdk.requireProperty(props, 'users', this);
2081 this.attrSerialNumber = cdk.Token.asString(this.getAtt('SerialNumber'));
2082 this.users = props.users;
2083 this.path = props.path;
2084 this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::IAM::VirtualMFADevice", props.tags, { tagPropertyName: 'tags' });
2085 this.virtualMfaDeviceName = props.virtualMfaDeviceName;
2086 }
2087 /**
2088 * A factory method that creates a new instance of this class from an object
2089 * containing the CloudFormation properties of this resource.
2090 * Used in the @aws-cdk/cloudformation-include module.
2091 *
2092 * @internal
2093 */
2094 static _fromCloudFormation(scope, id, resourceAttributes, options) {
2095 resourceAttributes = resourceAttributes || {};
2096 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
2097 const propsResult = CfnVirtualMFADevicePropsFromCloudFormation(resourceProperties);
2098 const ret = new CfnVirtualMFADevice(scope, id, propsResult.value);
2099 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
2100 ret.addPropertyOverride(propKey, propVal);
2101 }
2102 options.parser.handleAttributes(ret, resourceAttributes, id);
2103 return ret;
2104 }
2105 /**
2106 * Examines the CloudFormation resource and discloses attributes.
2107 *
2108 * @param inspector - tree inspector to collect and process attributes
2109 *
2110 */
2111 inspect(inspector) {
2112 inspector.addAttribute("aws:cdk:cloudformation:type", CfnVirtualMFADevice.CFN_RESOURCE_TYPE_NAME);
2113 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
2114 }
2115 get cfnProperties() {
2116 return {
2117 users: this.users,
2118 path: this.path,
2119 tags: this.tags.renderTags(),
2120 virtualMfaDeviceName: this.virtualMfaDeviceName,
2121 };
2122 }
2123 renderProperties(props) {
2124 return cfnVirtualMFADevicePropsToCloudFormation(props);
2125 }
2126}
2127exports.CfnVirtualMFADevice = CfnVirtualMFADevice;
2128_o = JSII_RTTI_SYMBOL_1;
2129CfnVirtualMFADevice[_o] = { fqn: "@aws-cdk/aws-iam.CfnVirtualMFADevice", version: "1.161.0" };
2130/**
2131 * The CloudFormation resource type name for this resource class.
2132 */
2133CfnVirtualMFADevice.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::VirtualMFADevice";
2134//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWFtLmdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImlhbS5nZW5lcmF0ZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsK0VBQStFO0FBQy9FLCtEQUErRDtBQUMvRCw4RkFBOEY7QUFDOUYsc0hBQXNIO0FBRXRILDRCQUE0QixDQUFDLGlFQUFpRTtBQUU5RixxQ0FBcUM7QUFDckMsZ0VBQWdFO0FBb0NoRTs7Ozs7O0dBTUc7QUFDSCxTQUFTLDBCQUEwQixDQUFDLFVBQWU7SUFDL0MsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLEVBQUU7UUFBRSxPQUFPLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQztLQUFFO0lBQ25FLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDM0MsSUFBSSxPQUFPLFVBQVUsS0FBSyxRQUFRLEVBQUU7UUFDaEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxvQ0FBb0MsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUMvRztJQUNELE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDdkYsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUN2RixNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLEVBQUUsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDOUYs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T0FBTyxHQUFHLENBQUM7S0FDZDtJQThERDs7Ozs7T0FLRztJQUNJLE9BQU8sQ0FBQyxTQUE0QjtRQUN2QyxTQUFTLENBQUMsWUFBWSxDQUFDLDZCQUE2QixFQUFFLG1CQUFtQixDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDbEcsU0FBUyxDQUFDLFlBQVksQ0FBQyw4QkFBOEIsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7S0FDOUU7SUFFRCxJQUFjLGFBQWE7UUFDdkIsT0FBTztZQUNILEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztZQUNqQixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDZixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDNUIsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLG9CQUFvQjtTQUNsRCxDQUFDO0tBQ0w7SUFFUyxnQkFBZ0IsQ0FBQyxLQUEyQjtRQUNsRCxPQUFPLHdDQUF3QyxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQzFEOztBQTNHTCxrREE0R0M7OztBQTNHRzs7R0FFRztBQUNvQiwwQ0FBc0IsR0FBRyw0QkFBNEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDEyLTIwMjIgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbi8vIEdlbmVyYXRlZCBmcm9tIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gUmVzb3VyY2UgU3BlY2lmaWNhdGlvblxuLy8gU2VlOiBkb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvY2ZuLXJlc291cmNlLXNwZWNpZmljYXRpb24uaHRtbFxuLy8gQGNmbjJ0czptZXRhQCB7XCJnZW5lcmF0ZWRcIjpcIjIwMjItMDYtMjJUMjI6NDE6MzkuNDc3WlwiLFwiZmluZ2VycHJpbnRcIjpcInhzTi8zU1NtdXFWZnMvbmdpYUYxRVFnTGQwbjhZVmkyV1ltMmRxMW8wMGM9XCJ9XG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi8gLy8gVGhpcyBpcyBnZW5lcmF0ZWQgY29kZSAtIGxpbmUgbGVuZ3RocyBhcmUgZGlmZmljdWx0IHRvIGNvbnRyb2xcblxuaW1wb3J0ICogYXMgY2RrIGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1xuaW1wb3J0ICogYXMgY2ZuX3BhcnNlIGZyb20gJ0Bhd3MtY2RrL2NvcmUvbGliL2hlbHBlcnMtaW50ZXJuYWwnO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmbkFjY2Vzc0tleWBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tYWNjZXNza2V5Lmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5BY2Nlc3NLZXlQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgSUFNIHVzZXIgdGhhdCB0aGUgbmV3IGtleSB3aWxsIGJlbG9uZyB0by5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1hY2Nlc3NrZXkuaHRtbCNjZm4taWFtLWFjY2Vzc2tleS11c2VybmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IHVzZXJOYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIHZhbHVlIGlzIHNwZWNpZmljIHRvIENsb3VkRm9ybWF0aW9uIGFuZCBjYW4gb25seSBiZSAqaW5jcmVtZW50ZWQqIC4gSW5jcmVtZW50aW5nIHRoaXMgdmFsdWUgbm90aWZpZXMgQ2xvdWRGb3JtYXRpb24gdGhhdCB5b3Ugd2FudCB0byByb3RhdGUgeW91ciBhY2Nlc3Mga2V5LiBXaGVuIHlvdSB1cGRhdGUgeW91ciBzdGFjaywgQ2xvdWRGb3JtYXRpb24gd2lsbCByZXBsYWNlIHRoZSBleGlzdGluZyBhY2Nlc3Mga2V5IHdpdGggYSBuZXcga2V5LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tYWNjZXNza2V5Lmh0bWwjY2ZuLWlhbS1hY2Nlc3NrZXktc2VyaWFsXG4gICAgICovXG4gICAgcmVhZG9ubHkgc2VyaWFsPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHN0YXR1cyBvZiB0aGUgYWNjZXNzIGtleS4gYEFjdGl2ZWAgbWVhbnMgdGhhdCB0aGUga2V5IGlzIHZhbGlkIGZvciBBUEkgY2FsbHMsIHdoaWxlIGBJbmFjdGl2ZWAgbWVhbnMgaXQgaXMgbm90LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tYWNjZXNza2V5Lmh0bWwjY2ZuLWlhbS1hY2Nlc3NrZXktc3RhdHVzXG4gICAgICovXG4gICAgcmVhZG9ubHkgc3RhdHVzPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbkFjY2Vzc0tleVByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5BY2Nlc3NLZXlQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5BY2Nlc3NLZXlQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3NlcmlhbCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5zZXJpYWwpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3N0YXR1cycsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5zdGF0dXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3VzZXJOYW1lJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnVzZXJOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd1c2VyTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy51c2VyTmFtZSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5BY2Nlc3NLZXlQcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpBY2Nlc3NLZXlgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkFjY2Vzc0tleVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OkFjY2Vzc0tleWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5BY2Nlc3NLZXlQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuQWNjZXNzS2V5UHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFVzZXJOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnVzZXJOYW1lKSxcbiAgICAgICAgU2VyaWFsOiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnNlcmlhbCksXG4gICAgICAgIFN0YXR1czogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zdGF0dXMpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5BY2Nlc3NLZXlQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbkFjY2Vzc0tleVByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5BY2Nlc3NLZXlQcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3VzZXJOYW1lJywgJ1VzZXJOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Vc2VyTmFtZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc2VyaWFsJywgJ1NlcmlhbCcsIHByb3BlcnRpZXMuU2VyaWFsICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLlNlcmlhbCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc3RhdHVzJywgJ1N0YXR1cycsIHByb3BlcnRpZXMuU3RhdHVzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlN0YXR1cykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6SUFNOjpBY2Nlc3NLZXlgXG4gKlxuICogQ3JlYXRlcyBhIG5ldyBBV1Mgc2VjcmV0IGFjY2VzcyBrZXkgYW5kIGNvcnJlc3BvbmRpbmcgQVdTIGFjY2VzcyBrZXkgSUQgZm9yIHRoZSBzcGVjaWZpZWQgdXNlci4gVGhlIGRlZmF1bHQgc3RhdHVzIGZvciBuZXcga2V5cyBpcyBgQWN0aXZlYCAuXG4gKlxuICogSWYgeW91IGRvIG5vdCBzcGVjaWZ5IGEgdXNlciBuYW1lLCBJQU0gZGV0ZXJtaW5lcyB0aGUgdXNlciBuYW1lIGltcGxpY2l0bHkgYmFzZWQgb24gdGhlIEFXUyBhY2Nlc3Mga2V5IElEIHNpZ25pbmcgdGhlIHJlcXVlc3QuIFRoaXMgb3BlcmF0aW9uIHdvcmtzIGZvciBhY2Nlc3Mga2V5cyB1bmRlciB0aGUgQVdTIGFjY291bnQgLiBDb25zZXF1ZW50bHksIHlvdSBjYW4gdXNlIHRoaXMgb3BlcmF0aW9uIHRvIG1hbmFnZSBBV1MgYWNjb3VudCByb290IHVzZXIgY3JlZGVudGlhbHMuIFRoaXMgaXMgdHJ1ZSBldmVuIGlmIHRoZSBBV1MgYWNjb3VudCBoYXMgbm8gYXNzb2NpYXRlZCB1c2Vycy5cbiAqXG4gKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgcXVvdGFzIG9uIHRoZSBudW1iZXIgb2Yga2V5cyB5b3UgY2FuIGNyZWF0ZSwgc2VlIFtJQU0gYW5kIEFXUyBTVFMgcXVvdGFzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX2lhbS1xdW90YXMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICpcbiAqID4gVG8gZW5zdXJlIHRoZSBzZWN1cml0eSBvZiB5b3VyIEFXUyBhY2NvdW50ICwgdGhlIHNlY3JldCBhY2Nlc3Mga2V5IGlzIGFjY2Vzc2libGUgb25seSBkdXJpbmcga2V5IGFuZCB1c2VyIGNyZWF0aW9uLiBZb3UgbXVzdCBzYXZlIHRoZSBrZXkgKGZvciBleGFtcGxlLCBpbiBhIHRleHQgZmlsZSkgaWYgeW91IHdhbnQgdG8gYmUgYWJsZSB0byBhY2Nlc3MgaXQgYWdhaW4uIElmIGEgc2VjcmV0IGtleSBpcyBsb3N0LCB5b3UgY2FuIGRlbGV0ZSB0aGUgYWNjZXNzIGtleXMgZm9yIHRoZSBhc3NvY2lhdGVkIHVzZXIgYW5kIHRoZW4gY3JlYXRlIG5ldyBrZXlzLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6SUFNOjpBY2Nlc3NLZXlcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1hY2Nlc3NrZXkuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuQWNjZXNzS2V5IGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6SUFNOjpBY2Nlc3NLZXlcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmbkFjY2Vzc0tleSB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuQWNjZXNzS2V5UHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmbkFjY2Vzc0tleShzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzZWNyZXQgYWNjZXNzIGtleSBmb3IgdGhlIHNwZWNpZmllZCBBV1M6OklBTTo6QWNjZXNzS2V5IHJlc291cmNlLiBGb3IgZXhhbXBsZTogd0phbHJYVXRuRkVNSS9LN01ERU5HL2JQeFJmaUNZekVYQU1QTEVLRVkuXG4gICAgICogQGNsb3VkZm9ybWF0aW9uQXR0cmlidXRlIFNlY3JldEFjY2Vzc0tleVxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBhdHRyU2VjcmV0QWNjZXNzS2V5OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgSUFNIHVzZXIgdGhhdCB0aGUgbmV3IGtleSB3aWxsIGJlbG9uZyB0by5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1hY2Nlc3NrZXkuaHRtbCNjZm4taWFtLWFjY2Vzc2tleS11c2VybmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyB1c2VyTmFtZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyB2YWx1ZSBpcyBzcGVjaWZpYyB0byBDbG91ZEZvcm1hdGlvbiBhbmQgY2FuIG9ubHkgYmUgKmluY3JlbWVudGVkKiAuIEluY3JlbWVudGluZyB0aGlzIHZhbHVlIG5vdGlmaWVzIENsb3VkRm9ybWF0aW9uIHRoYXQgeW91IHdhbnQgdG8gcm90YXRlIHlvdXIgYWNjZXNzIGtleS4gV2hlbiB5b3UgdXBkYXRlIHlvdXIgc3RhY2ssIENsb3VkRm9ybWF0aW9uIHdpbGwgcmVwbGFjZSB0aGUgZXhpc3RpbmcgYWNjZXNzIGtleSB3aXRoIGEgbmV3IGtleS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLWFjY2Vzc2tleS5odG1sI2Nmbi1pYW0tYWNjZXNza2V5LXNlcmlhbFxuICAgICAqL1xuICAgIHB1YmxpYyBzZXJpYWw6IG51bWJlciB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBzdGF0dXMgb2YgdGhlIGFjY2VzcyBrZXkuIGBBY3RpdmVgIG1lYW5zIHRoYXQgdGhlIGtleSBpcyB2YWxpZCBmb3IgQVBJIGNhbGxzLCB3aGlsZSBgSW5hY3RpdmVgIG1lYW5zIGl0IGlzIG5vdC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLWFjY2Vzc2tleS5odG1sI2Nmbi1pYW0tYWNjZXNza2V5LXN0YXR1c1xuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0dXM6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpJQU06OkFjY2Vzc0tleWAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuQWNjZXNzS2V5UHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmbkFjY2Vzc0tleS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ3VzZXJOYW1lJywgdGhpcyk7XG4gICAgICAgIHRoaXMuYXR0clNlY3JldEFjY2Vzc0tleSA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnU2VjcmV0QWNjZXNzS2V5JykpO1xuXG4gICAgICAgIHRoaXMudXNlck5hbWUgPSBwcm9wcy51c2VyTmFtZTtcbiAgICAgICAgdGhpcy5zZXJpYWwgPSBwcm9wcy5zZXJpYWw7XG4gICAgICAgIHRoaXMuc3RhdHVzID0gcHJvcHMuc3RhdHVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuQWNjZXNzS2V5LkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB1c2VyTmFtZTogdGhpcy51c2VyTmFtZSxcbiAgICAgICAgICAgIHNlcmlhbDogdGhpcy5zZXJpYWwsXG4gICAgICAgICAgICBzdGF0dXM6IHRoaXMuc3RhdHVzLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmbkFjY2Vzc0tleVByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmbkdyb3VwYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1ncm91cC5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuR3JvdXBQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgZ3JvdXAgdG8gY3JlYXRlLiBEbyBub3QgaW5jbHVkZSB0aGUgcGF0aCBpbiB0aGlzIHZhbHVlLlxuICAgICAqXG4gICAgICogVGhlIGdyb3VwIG5hbWUgbXVzdCBiZSB1bmlxdWUgd2l0aGluIHRoZSBhY2NvdW50LiBHcm91cCBuYW1lcyBhcmUgbm90IGRpc3Rpbmd1aXNoZWQgYnkgY2FzZS4gRm9yIGV4YW1wbGUsIHlvdSBjYW5ub3QgY3JlYXRlIGdyb3VwcyBuYW1lZCBib3RoIFwiQURNSU5TXCIgYW5kIFwiYWRtaW5zXCIuIElmIHlvdSBkb24ndCBzcGVjaWZ5IGEgbmFtZSwgQVdTIENsb3VkRm9ybWF0aW9uIGdlbmVyYXRlcyBhIHVuaXF1ZSBwaHlzaWNhbCBJRCBhbmQgdXNlcyB0aGF0IElEIGZvciB0aGUgZ3JvdXAgbmFtZS5cbiAgICAgKlxuICAgICAqID4gSWYgeW91IHNwZWNpZnkgYSBuYW1lLCB5b3UgY2Fubm90IHBlcmZvcm0gdXBkYXRlcyB0aGF0IHJlcXVpcmUgcmVwbGFjZW1lbnQgb2YgdGhpcyByZXNvdXJjZS4gWW91IGNhbiBwZXJmb3JtIHVwZGF0ZXMgdGhhdCByZXF1aXJlIG5vIG9yIHNvbWUgaW50ZXJydXB0aW9uLiBJZiB5b3UgbXVzdCByZXBsYWNlIHRoZSByZXNvdXJjZSwgc3BlY2lmeSBhIG5ldyBuYW1lLlxuICAgICAqXG4gICAgICogSWYgeW91IHNwZWNpZnkgYSBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBgQ0FQQUJJTElUWV9OQU1FRF9JQU1gIHZhbHVlIHRvIGFja25vd2xlZGdlIHlvdXIgdGVtcGxhdGUncyBjYXBhYmlsaXRpZXMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0Fja25vd2xlZGdpbmcgSUFNIFJlc291cmNlcyBpbiBBV1MgQ2xvdWRGb3JtYXRpb24gVGVtcGxhdGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS91c2luZy1pYW0tdGVtcGxhdGUuaHRtbCN1c2luZy1pYW0tY2FwYWJpbGl0aWVzKSAuXG4gICAgICpcbiAgICAgKiA+IE5hbWluZyBhbiBJQU0gcmVzb3VyY2UgY2FuIGNhdXNlIGFuIHVucmVjb3ZlcmFibGUgZXJyb3IgaWYgeW91IHJldXNlIHRoZSBzYW1lIHRlbXBsYXRlIGluIG11bHRpcGxlIFJlZ2lvbnMuIFRvIHByZXZlbnQgdGhpcywgd2UgcmVjb21tZW5kIHVzaW5nIGBGbjo6Sm9pbmAgYW5kIGBBV1M6OlJlZ2lvbmAgdG8gY3JlYXRlIGEgUmVnaW9uLXNwZWNpZmljIG5hbWUsIGFzIGluIHRoZSBmb2xsb3dpbmcgZXhhbXBsZTogYHtcIkZuOjpKb2luXCI6IFtcIlwiLCBbe1wiUmVmXCI6IFwiQVdTOjpSZWdpb25cIn0sIHtcIlJlZlwiOiBcIk15UmVzb3VyY2VOYW1lXCJ9XV19YCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1ncm91cC5odG1sI2Nmbi1pYW0tZ3JvdXAtZ3JvdXBuYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgZ3JvdXBOYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIG9mIHRoZSBJQU0gcG9saWN5IHlvdSB3YW50IHRvIGF0dGFjaC5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IEFSTnMsIHNlZSBbQW1hem9uIFJlc291cmNlIE5hbWVzIChBUk5zKV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dlbmVyYWwvbGF0ZXN0L2dyL2F3cy1hcm5zLWFuZC1uYW1lc3BhY2VzLmh0bWwpIGluIHRoZSAqQVdTIEdlbmVyYWwgUmVmZXJlbmNlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1ncm91cC5odG1sI2Nmbi1pYW0tZ3JvdXAtbWFuYWdlcG9saWN5YXJuc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IG1hbmFnZWRQb2xpY3lBcm5zPzogc3RyaW5nW107XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGF0aCB0byB0aGUgZ3JvdXAuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHBhdGhzLCBzZWUgW0lBTSBpZGVudGlmaWVyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL1VzaW5nX0lkZW50aWZpZXJzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGlzIG9wdGlvbmFsLiBJZiBpdCBpcyBub3QgaW5jbHVkZWQsIGl0IGRlZmF1bHRzIHRvIGEgc2xhc2ggKC8pLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIGVpdGhlciBhIGZvcndhcmQgc2xhc2ggKC8pIGJ5IGl0c2VsZiBvciBhIHN0cmluZyB0aGF0IG11c3QgYmVnaW4gYW5kIGVuZCB3aXRoIGZvcndhcmQgc2xhc2hlcy4gSW4gYWRkaXRpb24sIGl0IGNhbiBjb250YWluIGFueSBBU0NJSSBjaGFyYWN0ZXIgZnJvbSB0aGUgISAoIGBcXCB1MDAyMWAgKSB0aHJvdWdoIHRoZSBERUwgY2hhcmFjdGVyICggYFxcIHUwMDdGYCApLCBpbmNsdWRpbmcgbW9zdCBwdW5jdHVhdGlvbiBjaGFyYWN0ZXJzLCBkaWdpdHMsIGFuZCB1cHBlciBhbmQgbG93ZXJjYXNlZCBsZXR0ZXJzLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tZ3JvdXAuaHRtbCNjZm4taWFtLWdyb3VwLXBhdGhcbiAgICAgKi9cbiAgICByZWFkb25seSBwYXRoPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBvciB1cGRhdGVzIGFuIGlubGluZSBwb2xpY3kgZG9jdW1lbnQgdGhhdCBpcyBlbWJlZGRlZCBpbiB0aGUgc3BlY2lmaWVkIElBTSBncm91cC4gVG8gdmlldyBBV1M6OklBTTo6R3JvdXAgc25pcHBldHMsIHNlZSBbRGVjbGFyaW5nIGFuIElBTSBHcm91cCBSZXNvdXJjZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvcXVpY2tyZWYtaWFtLmh0bWwjc2NlbmFyaW8taWFtLWdyb3VwKSAuXG4gICAgICpcbiAgICAgKiA+IFRoZSBuYW1lIG9mIGVhY2ggaW5saW5lIHBvbGljeSBmb3IgYSByb2xlLCB1c2VyLCBvciBncm91cCBtdXN0IGJlIHVuaXF1ZS4gSWYgeW91IGRvbid0IGNob29zZSB1bmlxdWUgbmFtZXMsIHVwZGF0ZXMgdG8gdGhlIElBTSBpZGVudGl0eSB3aWxsIGZhaWwuXG4gICAgICpcbiAgICAgKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgbGltaXRzIG9uIHRoZSBudW1iZXIgb2YgaW5saW5lIHBvbGljaWVzIHRoYXQgeW91IGNhbiBlbWJlZCBpbiBhIGdyb3VwLCBzZWUgW0xpbWl0YXRpb25zIG9uIElBTSBFbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL0xpbWl0YXRpb25zT25FbnRpdGllcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1ncm91cC5odG1sI2Nmbi1pYW0tZ3JvdXAtcG9saWNpZXNcbiAgICAgKi9cbiAgICByZWFkb25seSBwb2xpY2llcz86IEFycmF5PENmbkdyb3VwLlBvbGljeVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDZm5Hcm91cFByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5Hcm91cFByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbkdyb3VwUHJvcHNWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdncm91cE5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuZ3JvdXBOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdtYW5hZ2VkUG9saWN5QXJucycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMubWFuYWdlZFBvbGljeUFybnMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BhdGgnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucGF0aCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWNpZXMnLCBjZGsubGlzdFZhbGlkYXRvcihDZm5Hcm91cF9Qb2xpY3lQcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMucG9saWNpZXMpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuR3JvdXBQcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpHcm91cGAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuR3JvdXBQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpHcm91cGAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5Hcm91cFByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5Hcm91cFByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBHcm91cE5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZ3JvdXBOYW1lKSxcbiAgICAgICAgTWFuYWdlZFBvbGljeUFybnM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLm1hbmFnZWRQb2xpY3lBcm5zKSxcbiAgICAgICAgUGF0aDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wYXRoKSxcbiAgICAgICAgUG9saWNpZXM6IGNkay5saXN0TWFwcGVyKGNmbkdyb3VwUG9saWN5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnBvbGljaWVzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuR3JvdXBQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbkdyb3VwUHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkdyb3VwUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdncm91cE5hbWUnLCAnR3JvdXBOYW1lJywgcHJvcGVydGllcy5Hcm91cE5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuR3JvdXBOYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtYW5hZ2VkUG9saWN5QXJucycsICdNYW5hZ2VkUG9saWN5QXJucycsIHByb3BlcnRpZXMuTWFuYWdlZFBvbGljeUFybnMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5NYW5hZ2VkUG9saWN5QXJucykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncGF0aCcsICdQYXRoJywgcHJvcGVydGllcy5QYXRoICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlBhdGgpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BvbGljaWVzJywgJ1BvbGljaWVzJywgcHJvcGVydGllcy5Qb2xpY2llcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5Hcm91cFBvbGljeVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLlBvbGljaWVzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpJQU06Okdyb3VwYFxuICpcbiAqIENyZWF0ZXMgYSBuZXcgZ3JvdXAuXG4gKlxuICogRm9yIGluZm9ybWF0aW9uIGFib3V0IHRoZSBudW1iZXIgb2YgZ3JvdXBzIHlvdSBjYW4gY3JlYXRlLCBzZWUgW0xpbWl0YXRpb25zIG9uIElBTSBFbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL0xpbWl0YXRpb25zT25FbnRpdGllcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpJQU06Okdyb3VwXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tZ3JvdXAuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuR3JvdXAgZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpJQU06Okdyb3VwXCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5Hcm91cCB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuR3JvdXBQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuR3JvdXAoc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgZm9yIHRoZSBzcGVjaWZpZWQgYEFXUzo6SUFNOjpHcm91cGAgcmVzb3VyY2UuIEZvciBleGFtcGxlOiBgYXJuOmF3czppYW06OjEyMzQ1Njc4OTAxMjpncm91cC9teXN0YWNrLW15Z3JvdXAtMURaRVRJVE9XRUtWT2AgLlxuICAgICAqIEBjbG91ZGZvcm1hdGlvbkF0dHJpYnV0ZSBBcm5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgYXR0ckFybjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGdyb3VwIHRvIGNyZWF0ZS4gRG8gbm90IGluY2x1ZGUgdGhlIHBhdGggaW4gdGhpcyB2YWx1ZS5cbiAgICAgKlxuICAgICAqIFRoZSBncm91cCBuYW1lIG11c3QgYmUgdW5pcXVlIHdpdGhpbiB0aGUgYWNjb3VudC4gR3JvdXAgbmFtZXMgYXJlIG5vdCBkaXN0aW5ndWlzaGVkIGJ5IGNhc2UuIEZvciBleGFtcGxlLCB5b3UgY2Fubm90IGNyZWF0ZSBncm91cHMgbmFtZWQgYm90aCBcIkFETUlOU1wiIGFuZCBcImFkbWluc1wiLiBJZiB5b3UgZG9uJ3Qgc3BlY2lmeSBhIG5hbWUsIEFXUyBDbG91ZEZvcm1hdGlvbiBnZW5lcmF0ZXMgYSB1bmlxdWUgcGh5c2ljYWwgSUQgYW5kIHVzZXMgdGhhdCBJRCBmb3IgdGhlIGdyb3VwIG5hbWUuXG4gICAgICpcbiAgICAgKiA+IElmIHlvdSBzcGVjaWZ5IGEgbmFtZSwgeW91IGNhbm5vdCBwZXJmb3JtIHVwZGF0ZXMgdGhhdCByZXF1aXJlIHJlcGxhY2VtZW50IG9mIHRoaXMgcmVzb3VyY2UuIFlvdSBjYW4gcGVyZm9ybSB1cGRhdGVzIHRoYXQgcmVxdWlyZSBubyBvciBzb21lIGludGVycnVwdGlvbi4gSWYgeW91IG11c3QgcmVwbGFjZSB0aGUgcmVzb3VyY2UsIHNwZWNpZnkgYSBuZXcgbmFtZS5cbiAgICAgKlxuICAgICAqIElmIHlvdSBzcGVjaWZ5IGEgbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgYENBUEFCSUxJVFlfTkFNRURfSUFNYCB2YWx1ZSB0byBhY2tub3dsZWRnZSB5b3VyIHRlbXBsYXRlJ3MgY2FwYWJpbGl0aWVzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBY2tub3dsZWRnaW5nIElBTSBSZXNvdXJjZXMgaW4gQVdTIENsb3VkRm9ybWF0aW9uIFRlbXBsYXRlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvdXNpbmctaWFtLXRlbXBsYXRlLmh0bWwjdXNpbmctaWFtLWNhcGFiaWxpdGllcykgLlxuICAgICAqXG4gICAgICogPiBOYW1pbmcgYW4gSUFNIHJlc291cmNlIGNhbiBjYXVzZSBhbiB1bnJlY292ZXJhYmxlIGVycm9yIGlmIHlvdSByZXVzZSB0aGUgc2FtZSB0ZW1wbGF0ZSBpbiBtdWx0aXBsZSBSZWdpb25zLiBUbyBwcmV2ZW50IHRoaXMsIHdlIHJlY29tbWVuZCB1c2luZyBgRm46OkpvaW5gIGFuZCBgQVdTOjpSZWdpb25gIHRvIGNyZWF0ZSBhIFJlZ2lvbi1zcGVjaWZpYyBuYW1lLCBhcyBpbiB0aGUgZm9sbG93aW5nIGV4YW1wbGU6IGB7XCJGbjo6Sm9pblwiOiBbXCJcIiwgW3tcIlJlZlwiOiBcIkFXUzo6UmVnaW9uXCJ9LCB7XCJSZWZcIjogXCJNeVJlc291cmNlTmFtZVwifV1dfWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tZ3JvdXAuaHRtbCNjZm4taWFtLWdyb3VwLWdyb3VwbmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyBncm91cE5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgSUFNIHBvbGljeSB5b3Ugd2FudCB0byBhdHRhY2guXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBBUk5zLCBzZWUgW0FtYXpvbiBSZXNvdXJjZSBOYW1lcyAoQVJOcyldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nZW5lcmFsL2xhdGVzdC9nci9hd3MtYXJucy1hbmQtbmFtZXNwYWNlcy5odG1sKSBpbiB0aGUgKkFXUyBHZW5lcmFsIFJlZmVyZW5jZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tZ3JvdXAuaHRtbCNjZm4taWFtLWdyb3VwLW1hbmFnZXBvbGljeWFybnNcbiAgICAgKi9cbiAgICBwdWJsaWMgbWFuYWdlZFBvbGljeUFybnM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBhdGggdG8gdGhlIGdyb3VwLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gaWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiBlaXRoZXIgYSBmb3J3YXJkIHNsYXNoICgvKSBieSBpdHNlbGYgb3IgYSBzdHJpbmcgdGhhdCBtdXN0IGJlZ2luIGFuZCBlbmQgd2l0aCBmb3J3YXJkIHNsYXNoZXMuIEluIGFkZGl0aW9uLCBpdCBjYW4gY29udGFpbiBhbnkgQVNDSUkgY2hhcmFjdGVyIGZyb20gdGhlICEgKCBgXFwgdTAwMjFgICkgdGhyb3VnaCB0aGUgREVMIGNoYXJhY3RlciAoIGBcXCB1MDA3RmAgKSwgaW5jbHVkaW5nIG1vc3QgcHVuY3R1YXRpb24gY2hhcmFjdGVycywgZGlnaXRzLCBhbmQgdXBwZXIgYW5kIGxvd2VyY2FzZWQgbGV0dGVycy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLWdyb3VwLmh0bWwjY2ZuLWlhbS1ncm91cC1wYXRoXG4gICAgICovXG4gICAgcHVibGljIHBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgb3IgdXBkYXRlcyBhbiBpbmxpbmUgcG9saWN5IGRvY3VtZW50IHRoYXQgaXMgZW1iZWRkZWQgaW4gdGhlIHNwZWNpZmllZCBJQU0gZ3JvdXAuIFRvIHZpZXcgQVdTOjpJQU06Okdyb3VwIHNuaXBwZXRzLCBzZWUgW0RlY2xhcmluZyBhbiBJQU0gR3JvdXAgUmVzb3VyY2VdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL3F1aWNrcmVmLWlhbS5odG1sI3NjZW5hcmlvLWlhbS1ncm91cCkgLlxuICAgICAqXG4gICAgICogPiBUaGUgbmFtZSBvZiBlYWNoIGlubGluZSBwb2xpY3kgZm9yIGEgcm9sZSwgdXNlciwgb3IgZ3JvdXAgbXVzdCBiZSB1bmlxdWUuIElmIHlvdSBkb24ndCBjaG9vc2UgdW5pcXVlIG5hbWVzLCB1cGRhdGVzIHRvIHRoZSBJQU0gaWRlbnRpdHkgd2lsbCBmYWlsLlxuICAgICAqXG4gICAgICogRm9yIGluZm9ybWF0aW9uIGFib3V0IGxpbWl0cyBvbiB0aGUgbnVtYmVyIG9mIGlubGluZSBwb2xpY2llcyB0aGF0IHlvdSBjYW4gZW1iZWQgaW4gYSBncm91cCwgc2VlIFtMaW1pdGF0aW9ucyBvbiBJQU0gRW50aXRpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9MaW1pdGF0aW9uc09uRW50aXRpZXMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tZ3JvdXAuaHRtbCNjZm4taWFtLWdyb3VwLXBvbGljaWVzXG4gICAgICovXG4gICAgcHVibGljIHBvbGljaWVzOiBBcnJheTxDZm5Hcm91cC5Qb2xpY3lQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6SUFNOjpHcm91cGAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuR3JvdXBQcm9wcyA9IHt9KSB7XG4gICAgICAgIHN1cGVyKHNjb3BlLCBpZCwgeyB0eXBlOiBDZm5Hcm91cC5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgdGhpcy5hdHRyQXJuID0gY2RrLlRva2VuLmFzU3RyaW5nKHRoaXMuZ2V0QXR0KCdBcm4nKSk7XG5cbiAgICAgICAgdGhpcy5ncm91cE5hbWUgPSBwcm9wcy5ncm91cE5hbWU7XG4gICAgICAgIHRoaXMubWFuYWdlZFBvbGljeUFybnMgPSBwcm9wcy5tYW5hZ2VkUG9saWN5QXJucztcbiAgICAgICAgdGhpcy5wYXRoID0gcHJvcHMucGF0aDtcbiAgICAgICAgdGhpcy5wb2xpY2llcyA9IHByb3BzLnBvbGljaWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuR3JvdXAuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGdyb3VwTmFtZTogdGhpcy5ncm91cE5hbWUsXG4gICAgICAgICAgICBtYW5hZ2VkUG9saWN5QXJuczogdGhpcy5tYW5hZ2VkUG9saWN5QXJucyxcbiAgICAgICAgICAgIHBhdGg6IHRoaXMucGF0aCxcbiAgICAgICAgICAgIHBvbGljaWVzOiB0aGlzLnBvbGljaWVzLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmbkdyb3VwUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuR3JvdXAge1xuICAgIC8qKlxuICAgICAqIENvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGFuIGF0dGFjaGVkIHBvbGljeS5cbiAgICAgKlxuICAgICAqIEFuIGF0dGFjaGVkIHBvbGljeSBpcyBhIG1hbmFnZWQgcG9saWN5IHRoYXQgaGFzIGJlZW4gYXR0YWNoZWQgdG8gYSB1c2VyLCBncm91cCwgb3Igcm9sZS5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IG1hbmFnZWQgcG9saWNpZXMsIHNlZSBbTWFuYWdlZCBQb2xpY2llcyBhbmQgSW5saW5lIFBvbGljaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcG9saWNpZXMtbWFuYWdlZC12cy1pbmxpbmUuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXBvbGljeS5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBQb2xpY3lQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcG9saWN5IGRvY3VtZW50LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1wb2xpY3kuaHRtbCNjZm4taWFtLXBvbGljaWVzLXBvbGljeWRvY3VtZW50XG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBwb2xpY3lEb2N1bWVudDogYW55IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGZyaWVuZGx5IG5hbWUgKG5vdCBBUk4pIGlkZW50aWZ5aW5nIHRoZSBwb2xpY3kuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXBvbGljeS5odG1sI2Nmbi1pYW0tcG9saWNpZXMtcG9saWN5bmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcG9saWN5TmFtZTogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBQb2xpY3lQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgUG9saWN5UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuR3JvdXBfUG9saWN5UHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb2xpY3lEb2N1bWVudCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5wb2xpY3lEb2N1bWVudCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5RG9jdW1lbnQnLCBjZGsudmFsaWRhdGVPYmplY3QpKHByb3BlcnRpZXMucG9saWN5RG9jdW1lbnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvbGljeU5hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMucG9saWN5TmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5TmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5wb2xpY3lOYW1lKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIlBvbGljeVByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06Okdyb3VwLlBvbGljeWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgUG9saWN5UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6R3JvdXAuUG9saWN5YCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmbkdyb3VwUG9saWN5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkdyb3VwX1BvbGljeVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBQb2xpY3lEb2N1bWVudDogY2RrLm9iamVjdFRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wb2xpY3lEb2N1bWVudCksXG4gICAgICAgIFBvbGljeU5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucG9saWN5TmFtZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkdyb3VwUG9saWN5UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5Hcm91cC5Qb2xpY3lQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5Hcm91cC5Qb2xpY3lQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BvbGljeURvY3VtZW50JywgJ1BvbGljeURvY3VtZW50JywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBbnkocHJvcGVydGllcy5Qb2xpY3lEb2N1bWVudCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncG9saWN5TmFtZScsICdQb2xpY3lOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Qb2xpY3lOYW1lKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuSW5zdGFuY2VQcm9maWxlYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0taW5zdGFuY2Vwcm9maWxlLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5JbnN0YW5jZVByb2ZpbGVQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcm9sZSB0byBhc3NvY2lhdGUgd2l0aCB0aGUgaW5zdGFuY2UgcHJvZmlsZS4gT25seSBvbmUgcm9sZSBjYW4gYmUgYXNzaWduZWQgdG8gYW4gRUMyIGluc3RhbmNlIGF0IGEgdGltZSwgYW5kIGFsbCBhcHBsaWNhdGlvbnMgb24gdGhlIGluc3RhbmNlIHNoYXJlIHRoZSBzYW1lIHJvbGUgYW5kIHBlcm1pc3Npb25zLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLWluc3RhbmNlcHJvZmlsZS5odG1sI2Nmbi1pYW0taW5zdGFuY2Vwcm9maWxlLXJvbGVzXG4gICAgICovXG4gICAgcmVhZG9ubHkgcm9sZXM6IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGluc3RhbmNlIHByb2ZpbGUgdG8gY3JlYXRlLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1pbnN0YW5jZXByb2ZpbGUuaHRtbCNjZm4taWFtLWluc3RhbmNlcHJvZmlsZS1pbnN0YW5jZXByb2ZpbGVuYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgaW5zdGFuY2VQcm9maWxlTmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBwYXRoIHRvIHRoZSBpbnN0YW5jZSBwcm9maWxlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gSWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiBlaXRoZXIgYSBmb3J3YXJkIHNsYXNoICgvKSBieSBpdHNlbGYgb3IgYSBzdHJpbmcgdGhhdCBtdXN0IGJlZ2luIGFuZCBlbmQgd2l0aCBmb3J3YXJkIHNsYXNoZXMuIEluIGFkZGl0aW9uLCBpdCBjYW4gY29udGFpbiBhbnkgQVNDSUkgY2hhcmFjdGVyIGZyb20gdGhlICEgKCBgXFwgdTAwMjFgICkgdGhyb3VnaCB0aGUgREVMIGNoYXJhY3RlciAoIGBcXCB1MDA3RmAgKSwgaW5jbHVkaW5nIG1vc3QgcHVuY3R1YXRpb24gY2hhcmFjdGVycywgZGlnaXRzLCBhbmQgdXBwZXIgYW5kIGxvd2VyY2FzZWQgbGV0dGVycy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1pbnN0YW5jZXByb2ZpbGUuaHRtbCNjZm4taWFtLWluc3RhbmNlcHJvZmlsZS1wYXRoXG4gICAgICovXG4gICAgcmVhZG9ubHkgcGF0aD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDZm5JbnN0YW5jZVByb2ZpbGVQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuSW5zdGFuY2VQcm9maWxlUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuSW5zdGFuY2VQcm9maWxlUHJvcHNWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdpbnN0YW5jZVByb2ZpbGVOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmluc3RhbmNlUHJvZmlsZU5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BhdGgnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucGF0aCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncm9sZXMnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMucm9sZXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3JvbGVzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5yb2xlcykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5JbnN0YW5jZVByb2ZpbGVQcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpJbnN0YW5jZVByb2ZpbGVgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkluc3RhbmNlUHJvZmlsZVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06Okluc3RhbmNlUHJvZmlsZWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5JbnN0YW5jZVByb2ZpbGVQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuSW5zdGFuY2VQcm9maWxlUHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFJvbGVzOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5yb2xlcyksXG4gICAgICAgIEluc3RhbmNlUHJvZmlsZU5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaW5zdGFuY2VQcm9maWxlTmFtZSksXG4gICAgICAgIFBhdGg6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucGF0aCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkluc3RhbmNlUHJvZmlsZVByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuSW5zdGFuY2VQcm9maWxlUHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkluc3RhbmNlUHJvZmlsZVByb3BzPigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncm9sZXMnLCAnUm9sZXMnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuUm9sZXMpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2luc3RhbmNlUHJvZmlsZU5hbWUnLCAnSW5zdGFuY2VQcm9maWxlTmFtZScsIHByb3BlcnRpZXMuSW5zdGFuY2VQcm9maWxlTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5JbnN0YW5jZVByb2ZpbGVOYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwYXRoJywgJ1BhdGgnLCBwcm9wZXJ0aWVzLlBhdGggIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUGF0aCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6SUFNOjpJbnN0YW5jZVByb2ZpbGVgXG4gKlxuICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBwcm9maWxlLiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgaW5zdGFuY2UgcHJvZmlsZXMsIHNlZSBbVXNpbmcgaW5zdGFuY2UgcHJvZmlsZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF9yb2xlc191c2Vfc3dpdGNoLXJvbGUtZWMyX2luc3RhbmNlLXByb2ZpbGVzLmh0bWwpIC5cbiAqXG4gKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG51bWJlciBvZiBpbnN0YW5jZSBwcm9maWxlcyB5b3UgY2FuIGNyZWF0ZSwgc2VlIFtJQU0gb2JqZWN0IHF1b3Rhc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9pYW0tcXVvdGFzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAqXG4gKiBAY2xvdWRmb3JtYXRpb25SZXNvdXJjZSBBV1M6OklBTTo6SW5zdGFuY2VQcm9maWxlXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLWluc3RhbmNlcHJvZmlsZS5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5JbnN0YW5jZVByb2ZpbGUgZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpJQU06Okluc3RhbmNlUHJvZmlsZVwiO1xuXG4gICAgLyoqXG4gICAgICogQSBmYWN0b3J5IG1ldGhvZCB0aGF0IGNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmcm9tIGFuIG9iamVjdFxuICAgICAqIGNvbnRhaW5pbmcgdGhlIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgdGhpcyByZXNvdXJjZS5cbiAgICAgKiBVc2VkIGluIHRoZSBAYXdzLWNkay9jbG91ZGZvcm1hdGlvbi1pbmNsdWRlIG1vZHVsZS5cbiAgICAgKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgX2Zyb21DbG91ZEZvcm1hdGlvbihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcmVzb3VyY2VBdHRyaWJ1dGVzOiBhbnksIG9wdGlvbnM6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25PcHRpb25zKTogQ2ZuSW5zdGFuY2VQcm9maWxlIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5JbnN0YW5jZVByb2ZpbGVQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuSW5zdGFuY2VQcm9maWxlKHNjb3BlLCBpZCwgcHJvcHNSZXN1bHQudmFsdWUpO1xuICAgICAgICBmb3IgKGNvbnN0IFtwcm9wS2V5LCBwcm9wVmFsXSBvZiBPYmplY3QuZW50cmllcyhwcm9wc1Jlc3VsdC5leHRyYVByb3BlcnRpZXMpKSAge1xuICAgICAgICAgICAgcmV0LmFkZFByb3BlcnR5T3ZlcnJpZGUocHJvcEtleSwgcHJvcFZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5wYXJzZXIuaGFuZGxlQXR0cmlidXRlcyhyZXQsIHJlc291cmNlQXR0cmlidXRlcywgaWQpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIGZvciB0aGUgaW5zdGFuY2UgcHJvZmlsZS4gRm9yIGV4YW1wbGU6XG4gICAgICpcbiAgICAgKiBge1wiRm46OkdldEF0dFwiIDogW1wiTXlQcm9maWxlXCIsIFwiQXJuXCJdIH1gXG4gICAgICpcbiAgICAgKiBUaGlzIHJldHVybnMgYSB2YWx1ZSBzdWNoIGFzIGBhcm46YXdzOmlhbTo6MTIzNDU2Nzg5MDppbnN0YW5jZS1wcm9maWxlL015UHJvZmlsZS1BU0ROU0RMS0pgIC5cbiAgICAgKiBAY2xvdWRmb3JtYXRpb25BdHRyaWJ1dGUgQXJuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJBcm46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSByb2xlIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBpbnN0YW5jZSBwcm9maWxlLiBPbmx5IG9uZSByb2xlIGNhbiBiZSBhc3NpZ25lZCB0byBhbiBFQzIgaW5zdGFuY2UgYXQgYSB0aW1lLCBhbmQgYWxsIGFwcGxpY2F0aW9ucyBvbiB0aGUgaW5zdGFuY2Ugc2hhcmUgdGhlIHNhbWUgcm9sZSBhbmQgcGVybWlzc2lvbnMuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0taW5zdGFuY2Vwcm9maWxlLmh0bWwjY2ZuLWlhbS1pbnN0YW5jZXByb2ZpbGUtcm9sZXNcbiAgICAgKi9cbiAgICBwdWJsaWMgcm9sZXM6IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGluc3RhbmNlIHByb2ZpbGUgdG8gY3JlYXRlLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1pbnN0YW5jZXByb2ZpbGUuaHRtbCNjZm4taWFtLWluc3RhbmNlcHJvZmlsZS1pbnN0YW5jZXByb2ZpbGVuYW1lXG4gICAgICovXG4gICAgcHVibGljIGluc3RhbmNlUHJvZmlsZU5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwYXRoIHRvIHRoZSBpbnN0YW5jZSBwcm9maWxlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gSWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiBlaXRoZXIgYSBmb3J3YXJkIHNsYXNoICgvKSBieSBpdHNlbGYgb3IgYSBzdHJpbmcgdGhhdCBtdXN0IGJlZ2luIGFuZCBlbmQgd2l0aCBmb3J3YXJkIHNsYXNoZXMuIEluIGFkZGl0aW9uLCBpdCBjYW4gY29udGFpbiBhbnkgQVNDSUkgY2hhcmFjdGVyIGZyb20gdGhlICEgKCBgXFwgdTAwMjFgICkgdGhyb3VnaCB0aGUgREVMIGNoYXJhY3RlciAoIGBcXCB1MDA3RmAgKSwgaW5jbHVkaW5nIG1vc3QgcHVuY3R1YXRpb24gY2hhcmFjdGVycywgZGlnaXRzLCBhbmQgdXBwZXIgYW5kIGxvd2VyY2FzZWQgbGV0dGVycy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1pbnN0YW5jZXByb2ZpbGUuaHRtbCNjZm4taWFtLWluc3RhbmNlcHJvZmlsZS1wYXRoXG4gICAgICovXG4gICAgcHVibGljIHBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpJQU06Okluc3RhbmNlUHJvZmlsZWAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuSW5zdGFuY2VQcm9maWxlUHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmbkluc3RhbmNlUHJvZmlsZS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ3JvbGVzJywgdGhpcyk7XG4gICAgICAgIHRoaXMuYXR0ckFybiA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnQXJuJykpO1xuXG4gICAgICAgIHRoaXMucm9sZXMgPSBwcm9wcy5yb2xlcztcbiAgICAgICAgdGhpcy5pbnN0YW5jZVByb2ZpbGVOYW1lID0gcHJvcHMuaW5zdGFuY2VQcm9maWxlTmFtZTtcbiAgICAgICAgdGhpcy5wYXRoID0gcHJvcHMucGF0aDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmbkluc3RhbmNlUHJvZmlsZS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcm9sZXM6IHRoaXMucm9sZXMsXG4gICAgICAgICAgICBpbnN0YW5jZVByb2ZpbGVOYW1lOiB0aGlzLmluc3RhbmNlUHJvZmlsZU5hbWUsXG4gICAgICAgICAgICBwYXRoOiB0aGlzLnBhdGgsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuSW5zdGFuY2VQcm9maWxlUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuTWFuYWdlZFBvbGljeWBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW1hbmFnZWRwb2xpY3kuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmbk1hbmFnZWRQb2xpY3lQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgSlNPTiBwb2xpY3kgZG9jdW1lbnQgdGhhdCB5b3Ugd2FudCB0byB1c2UgYXMgdGhlIGNvbnRlbnQgZm9yIHRoZSBuZXcgcG9saWN5LlxuICAgICAqXG4gICAgICogWW91IG11c3QgcHJvdmlkZSBwb2xpY2llcyBpbiBKU09OIGZvcm1hdCBpbiBJQU0uIEhvd2V2ZXIsIGZvciBBV1MgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGVzIGZvcm1hdHRlZCBpbiBZQU1MLCB5b3UgY2FuIHByb3ZpZGUgdGhlIHBvbGljeSBpbiBKU09OIG9yIFlBTUwgZm9ybWF0LiBBV1MgQ2xvdWRGb3JtYXRpb24gYWx3YXlzIGNvbnZlcnRzIGEgWUFNTCBwb2xpY3kgdG8gSlNPTiBmb3JtYXQgYmVmb3JlIHN1Ym1pdHRpbmcgaXQgdG8gSUFNLlxuICAgICAqXG4gICAgICogVGhlIG1heGltdW0gbGVuZ3RoIG9mIHRoZSBwb2xpY3kgZG9jdW1lbnQgdGhhdCB5b3UgY2FuIHBhc3MgaW4gdGhpcyBvcGVyYXRpb24sIGluY2x1ZGluZyB3aGl0ZXNwYWNlLCBpcyBsaXN0ZWQgYmVsb3cuIFRvIHZpZXcgdGhlIG1heGltdW0gY2hhcmFjdGVyIGNvdW50cyBvZiBhIG1hbmFnZWQgcG9saWN5IHdpdGggbm8gd2hpdGVzcGFjZXMsIHNlZSBbSUFNIGFuZCBBV1MgU1RTIGNoYXJhY3RlciBxdW90YXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfaWFtLXF1b3Rhcy5odG1sI3JlZmVyZW5jZV9pYW0tcXVvdGFzLWVudGl0eS1sZW5ndGgpIC5cbiAgICAgKlxuICAgICAqIFRvIGxlYXJuIG1vcmUgYWJvdXQgSlNPTiBwb2xpY3kgZ3JhbW1hciwgc2VlIFtHcmFtbWFyIG9mIHRoZSBJQU0gSlNPTiBwb2xpY3kgbGFuZ3VhZ2VdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZ3JhbW1hci5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGUgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSB1c2VkIHRvIHZhbGlkYXRlIHRoaXMgcGFyYW1ldGVyIGlzIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBBbnkgcHJpbnRhYmxlIEFTQ0lJIGNoYXJhY3RlciByYW5naW5nIGZyb20gdGhlIHNwYWNlIGNoYXJhY3RlciAoIGBcXCB1MDAyMGAgKSB0aHJvdWdoIHRoZSBlbmQgb2YgdGhlIEFTQ0lJIGNoYXJhY3RlciByYW5nZVxuICAgICAqIC0gVGhlIHByaW50YWJsZSBjaGFyYWN0ZXJzIGluIHRoZSBCYXNpYyBMYXRpbiBhbmQgTGF0aW4tMSBTdXBwbGVtZW50IGNoYXJhY3RlciBzZXQgKHRocm91Z2ggYFxcIHUwMEZGYCApXG4gICAgICogLSBUaGUgc3BlY2lhbCBjaGFyYWN0ZXJzIHRhYiAoIGBcXCB1MDAwOWAgKSwgbGluZSBmZWVkICggYFxcIHUwMDBBYCApLCBhbmQgY2FycmlhZ2UgcmV0dXJuICggYFxcIHUwMDBEYCApXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tbWFuYWdlZHBvbGljeS5odG1sI2Nmbi1pYW0tbWFuYWdlZHBvbGljeS1wb2xpY3lkb2N1bWVudFxuICAgICAqL1xuICAgIHJlYWRvbmx5IHBvbGljeURvY3VtZW50OiBhbnkgfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBBIGZyaWVuZGx5IGRlc2NyaXB0aW9uIG9mIHRoZSBwb2xpY3kuXG4gICAgICpcbiAgICAgKiBUeXBpY2FsbHkgdXNlZCB0byBzdG9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGVybWlzc2lvbnMgZGVmaW5lZCBpbiB0aGUgcG9saWN5LiBGb3IgZXhhbXBsZSwgXCJHcmFudHMgYWNjZXNzIHRvIHByb2R1Y3Rpb24gRHluYW1vREIgdGFibGVzLlwiXG4gICAgICpcbiAgICAgKiBUaGUgcG9saWN5IGRlc2NyaXB0aW9uIGlzIGltbXV0YWJsZS4gQWZ0ZXIgYSB2YWx1ZSBpcyBhc3NpZ25lZCwgaXQgY2Fubm90IGJlIGNoYW5nZWQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tbWFuYWdlZHBvbGljeS5odG1sI2Nmbi1pYW0tbWFuYWdlZHBvbGljeS1kZXNjcmlwdGlvblxuICAgICAqL1xuICAgIHJlYWRvbmx5IGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgKGZyaWVuZGx5IG5hbWUsIG5vdCBBUk4pIG9mIHRoZSBncm91cCB0byBhdHRhY2ggdGhlIHBvbGljeSB0by5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tbWFuYWdlZHBvbGljeS5odG1sI2Nmbi1pYW0tbWFuYWdlZHBvbGljeS1ncm91cHNcbiAgICAgKi9cbiAgICByZWFkb25seSBncm91cHM/OiBzdHJpbmdbXTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBmcmllbmRseSBuYW1lIG9mIHRoZSBwb2xpY3kuXG4gICAgICpcbiAgICAgKiA+IElmIHlvdSBzcGVjaWZ5IGEgbmFtZSwgeW91IGNhbm5vdCBwZXJmb3JtIHVwZGF0ZXMgdGhhdCByZXF1aXJlIHJlcGxhY2VtZW50IG9mIHRoaXMgcmVzb3VyY2UuIFlvdSBjYW4gcGVyZm9ybSB1cGRhdGVzIHRoYXQgcmVxdWlyZSBubyBvciBzb21lIGludGVycnVwdGlvbi4gSWYgeW91IG11c3QgcmVwbGFjZSB0aGUgcmVzb3VyY2UsIHNwZWNpZnkgYSBuZXcgbmFtZS5cbiAgICAgKlxuICAgICAqIElmIHlvdSBzcGVjaWZ5IGEgbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgYENBUEFCSUxJVFlfTkFNRURfSUFNYCB2YWx1ZSB0byBhY2tub3dsZWRnZSB5b3VyIHRlbXBsYXRlJ3MgY2FwYWJpbGl0aWVzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBY2tub3dsZWRnaW5nIElBTSBSZXNvdXJjZXMgaW4gQVdTIENsb3VkRm9ybWF0aW9uIFRlbXBsYXRlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvdXNpbmctaWFtLXRlbXBsYXRlLmh0bWwjdXNpbmctaWFtLWNhcGFiaWxpdGllcykgLlxuICAgICAqXG4gICAgICogPiBOYW1pbmcgYW4gSUFNIHJlc291cmNlIGNhbiBjYXVzZSBhbiB1bnJlY292ZXJhYmxlIGVycm9yIGlmIHlvdSByZXVzZSB0aGUgc2FtZSB0ZW1wbGF0ZSBpbiBtdWx0aXBsZSBSZWdpb25zLiBUbyBwcmV2ZW50IHRoaXMsIHdlIHJlY29tbWVuZCB1c2luZyBgRm46OkpvaW5gIGFuZCBgQVdTOjpSZWdpb25gIHRvIGNyZWF0ZSBhIFJlZ2lvbi1zcGVjaWZpYyBuYW1lLCBhcyBpbiB0aGUgZm9sbG93aW5nIGV4YW1wbGU6IGB7XCJGbjo6Sm9pblwiOiBbXCJcIiwgW3tcIlJlZlwiOiBcIkFXUzo6UmVnaW9uXCJ9LCB7XCJSZWZcIjogXCJNeVJlc291cmNlTmFtZVwifV1dfWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW1hbmFnZWRwb2xpY3kuaHRtbCNjZm4taWFtLW1hbmFnZWRwb2xpY3ktbWFuYWdlZHBvbGljeW5hbWVcbiAgICAgKi9cbiAgICByZWFkb25seSBtYW5hZ2VkUG9saWN5TmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBwYXRoIGZvciB0aGUgcG9saWN5LlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgcGF0aHMsIHNlZSBbSUFNIGlkZW50aWZpZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvVXNpbmdfSWRlbnRpZmllcnMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgaXMgb3B0aW9uYWwuIElmIGl0IGlzIG5vdCBpbmNsdWRlZCwgaXQgZGVmYXVsdHMgdG8gYSBzbGFzaCAoLykuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgZWl0aGVyIGEgZm9yd2FyZCBzbGFzaCAoLykgYnkgaXRzZWxmIG9yIGEgc3RyaW5nIHRoYXQgbXVzdCBiZWdpbiBhbmQgZW5kIHdpdGggZm9yd2FyZCBzbGFzaGVzLiBJbiBhZGRpdGlvbiwgaXQgY2FuIGNvbnRhaW4gYW55IEFTQ0lJIGNoYXJhY3RlciBmcm9tIHRoZSAhICggYFxcIHUwMDIxYCApIHRocm91Z2ggdGhlIERFTCBjaGFyYWN0ZXIgKCBgXFwgdTAwN0ZgICksIGluY2x1ZGluZyBtb3N0IHB1bmN0dWF0aW9uIGNoYXJhY3RlcnMsIGRpZ2l0cywgYW5kIHVwcGVyIGFuZCBsb3dlcmNhc2VkIGxldHRlcnMuXG4gICAgICpcbiAgICAgKiA+IFlvdSBjYW5ub3QgdXNlIGFuIGFzdGVyaXNrICgqKSBpbiB0aGUgcGF0aCBuYW1lLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW1hbmFnZWRwb2xpY3kuaHRtbCNjZm4tZWMyLWRoY3BvcHRpb25zLXBhdGhcbiAgICAgKi9cbiAgICByZWFkb25seSBwYXRoPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgKGZyaWVuZGx5IG5hbWUsIG5vdCBBUk4pIG9mIHRoZSByb2xlIHRvIGF0dGFjaCB0aGUgcG9saWN5IHRvLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzIChwZXIgaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdXBwZXIgYW5kIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyB3aXRoIG5vIHNwYWNlcy4gWW91IGNhbiBhbHNvIGluY2x1ZGUgYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogXys9LC5ALVxuICAgICAqXG4gICAgICogPiBJZiBhbiBleHRlcm5hbCBwb2xpY3kgKHN1Y2ggYXMgYEFXUzo6SUFNOjpQb2xpY3lgIG9yIGBBV1M6OklBTTo6TWFuYWdlZFBvbGljeWAgKSBoYXMgYSBgUmVmYCB0byBhIHJvbGUgYW5kIGlmIGEgcmVzb3VyY2UgKHN1Y2ggYXMgYEFXUzo6RUNTOjpTZXJ2aWNlYCApIGFsc28gaGFzIGEgYFJlZmAgdG8gdGhlIHNhbWUgcm9sZSwgYWRkIGEgYERlcGVuZHNPbmAgYXR0cmlidXRlIHRvIHRoZSByZXNvdXJjZSB0byBtYWtlIHRoZSByZXNvdXJjZSBkZXBlbmQgb24gdGhlIGV4dGVybmFsIHBvbGljeS4gVGhpcyBkZXBlbmRlbmN5IGVuc3VyZXMgdGhhdCB0aGUgcm9sZSdzIHBvbGljeSBpcyBhdmFpbGFibGUgdGhyb3VnaG91dCB0aGUgcmVzb3VyY2UncyBsaWZlY3ljbGUuIEZvciBleGFtcGxlLCB3aGVuIHlvdSBkZWxldGUgYSBzdGFjayB3aXRoIGFuIGBBV1M6OkVDUzo6U2VydmljZWAgcmVzb3VyY2UsIHRoZSBgRGVwZW5kc09uYCBhdHRyaWJ1dGUgZW5zdXJlcyB0aGF0IEFXUyBDbG91ZEZvcm1hdGlvbiBkZWxldGVzIHRoZSBgQVdTOjpFQ1M6OlNlcnZpY2VgIHJlc291cmNlIGJlZm9yZSBkZWxldGluZyBpdHMgcm9sZSdzIHBvbGljeS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1tYW5hZ2VkcG9saWN5Lmh0bWwjY2ZuLWlhbS1tYW5hZ2VkcG9saWN5LXJvbGVzXG4gICAgICovXG4gICAgcmVhZG9ubHkgcm9sZXM/OiBzdHJpbmdbXTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIChmcmllbmRseSBuYW1lLCBub3QgQVJOKSBvZiB0aGUgSUFNIHVzZXIgdG8gYXR0YWNoIHRoZSBwb2xpY3kgdG8uXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdXBwZXIgYW5kIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyB3aXRoIG5vIHNwYWNlcy4gWW91IGNhbiBhbHNvIGluY2x1ZGUgYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogXys9LC5ALVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW1hbmFnZWRwb2xpY3kuaHRtbCNjZm4taWFtLW1hbmFnZWRwb2xpY3ktdXNlcnNcbiAgICAgKi9cbiAgICByZWFkb25seSB1c2Vycz86IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbk1hbmFnZWRQb2xpY3lQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuTWFuYWdlZFBvbGljeVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbk1hbmFnZWRQb2xpY3lQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Rlc2NyaXB0aW9uJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmRlc2NyaXB0aW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdncm91cHMnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLmdyb3VwcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbWFuYWdlZFBvbGljeU5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubWFuYWdlZFBvbGljeU5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BhdGgnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucGF0aCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5RG9jdW1lbnQnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMucG9saWN5RG9jdW1lbnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvbGljeURvY3VtZW50JywgY2RrLnZhbGlkYXRlT2JqZWN0KShwcm9wZXJ0aWVzLnBvbGljeURvY3VtZW50KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyb2xlcycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMucm9sZXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3VzZXJzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy51c2VycykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5NYW5hZ2VkUG9saWN5UHJvcHNcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6TWFuYWdlZFBvbGljeWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuTWFuYWdlZFBvbGljeVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06Ok1hbmFnZWRQb2xpY3lgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuTWFuYWdlZFBvbGljeVByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5NYW5hZ2VkUG9saWN5UHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFBvbGljeURvY3VtZW50OiBjZGsub2JqZWN0VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBvbGljeURvY3VtZW50KSxcbiAgICAgICAgRGVzY3JpcHRpb246IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZGVzY3JpcHRpb24pLFxuICAgICAgICBHcm91cHM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmdyb3VwcyksXG4gICAgICAgIE1hbmFnZWRQb2xpY3lOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm1hbmFnZWRQb2xpY3lOYW1lKSxcbiAgICAgICAgUGF0aDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wYXRoKSxcbiAgICAgICAgUm9sZXM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnJvbGVzKSxcbiAgICAgICAgVXNlcnM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnVzZXJzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuTWFuYWdlZFBvbGljeVByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuTWFuYWdlZFBvbGljeVByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5NYW5hZ2VkUG9saWN5UHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwb2xpY3lEb2N1bWVudCcsICdQb2xpY3lEb2N1bWVudCcsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QW55KHByb3BlcnRpZXMuUG9saWN5RG9jdW1lbnQpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Rlc2NyaXB0aW9uJywgJ0Rlc2NyaXB0aW9uJywgcHJvcGVydGllcy5EZXNjcmlwdGlvbiAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5EZXNjcmlwdGlvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZ3JvdXBzJywgJ0dyb3VwcycsIHByb3BlcnRpZXMuR3JvdXBzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuR3JvdXBzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtYW5hZ2VkUG9saWN5TmFtZScsICdNYW5hZ2VkUG9saWN5TmFtZScsIHByb3BlcnRpZXMuTWFuYWdlZFBvbGljeU5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTWFuYWdlZFBvbGljeU5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BhdGgnLCAnUGF0aCcsIHByb3BlcnRpZXMuUGF0aCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5QYXRoKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdyb2xlcycsICdSb2xlcycsIHByb3BlcnRpZXMuUm9sZXMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5Sb2xlcykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndXNlcnMnLCAnVXNlcnMnLCBwcm9wZXJ0aWVzLlVzZXJzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuVXNlcnMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBBIENsb3VkRm9ybWF0aW9uIGBBV1M6OklBTTo6TWFuYWdlZFBvbGljeWBcbiAqXG4gKiBDcmVhdGVzIGEgbmV3IG1hbmFnZWQgcG9saWN5IGZvciB5b3VyIEFXUyBhY2NvdW50IC5cbiAqXG4gKiBUaGlzIG9wZXJhdGlvbiBjcmVhdGVzIGEgcG9saWN5IHZlcnNpb24gd2l0aCBhIHZlcnNpb24gaWRlbnRpZmllciBvZiBgdjFgIGFuZCBzZXRzIHYxIGFzIHRoZSBwb2xpY3kncyBkZWZhdWx0IHZlcnNpb24uIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHBvbGljeSB2ZXJzaW9ucywgc2VlIFtWZXJzaW9uaW5nIGZvciBtYW5hZ2VkIHBvbGljaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcG9saWNpZXMtbWFuYWdlZC12ZXJzaW9ucy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gKlxuICogQXMgYSBiZXN0IHByYWN0aWNlLCB5b3UgY2FuIHZhbGlkYXRlIHlvdXIgSUFNIHBvbGljaWVzLiBUbyBsZWFybiBtb3JlLCBzZWUgW1ZhbGlkYXRpbmcgSUFNIHBvbGljaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvYWNjZXNzX3BvbGljaWVzX3BvbGljeS12YWxpZGF0b3IuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICpcbiAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IG1hbmFnZWQgcG9saWNpZXMgaW4gZ2VuZXJhbCwgc2VlIFtNYW5hZ2VkIHBvbGljaWVzIGFuZCBpbmxpbmUgcG9saWNpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9wb2xpY2llcy1tYW5hZ2VkLXZzLWlubGluZS5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpJQU06Ok1hbmFnZWRQb2xpY3lcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tbWFuYWdlZHBvbGljeS5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5NYW5hZ2VkUG9saWN5IGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6SUFNOjpNYW5hZ2VkUG9saWN5XCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5NYW5hZ2VkUG9saWN5IHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5NYW5hZ2VkUG9saWN5UHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmbk1hbmFnZWRQb2xpY3koc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIEpTT04gcG9saWN5IGRvY3VtZW50IHRoYXQgeW91IHdhbnQgdG8gdXNlIGFzIHRoZSBjb250ZW50IGZvciB0aGUgbmV3IHBvbGljeS5cbiAgICAgKlxuICAgICAqIFlvdSBtdXN0IHByb3ZpZGUgcG9saWNpZXMgaW4gSlNPTiBmb3JtYXQgaW4gSUFNLiBIb3dldmVyLCBmb3IgQVdTIENsb3VkRm9ybWF0aW9uIHRlbXBsYXRlcyBmb3JtYXR0ZWQgaW4gWUFNTCwgeW91IGNhbiBwcm92aWRlIHRoZSBwb2xpY3kgaW4gSlNPTiBvciBZQU1MIGZvcm1hdC4gQVdTIENsb3VkRm9ybWF0aW9uIGFsd2F5cyBjb252ZXJ0cyBhIFlBTUwgcG9saWN5IHRvIEpTT04gZm9ybWF0IGJlZm9yZSBzdWJtaXR0aW5nIGl0IHRvIElBTS5cbiAgICAgKlxuICAgICAqIFRoZSBtYXhpbXVtIGxlbmd0aCBvZiB0aGUgcG9saWN5IGRvY3VtZW50IHRoYXQgeW91IGNhbiBwYXNzIGluIHRoaXMgb3BlcmF0aW9uLCBpbmNsdWRpbmcgd2hpdGVzcGFjZSwgaXMgbGlzdGVkIGJlbG93LiBUbyB2aWV3IHRoZSBtYXhpbXVtIGNoYXJhY3RlciBjb3VudHMgb2YgYSBtYW5hZ2VkIHBvbGljeSB3aXRoIG5vIHdoaXRlc3BhY2VzLCBzZWUgW0lBTSBhbmQgQVdTIFNUUyBjaGFyYWN0ZXIgcXVvdGFzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX2lhbS1xdW90YXMuaHRtbCNyZWZlcmVuY2VfaWFtLXF1b3Rhcy1lbnRpdHktbGVuZ3RoKSAuXG4gICAgICpcbiAgICAgKiBUbyBsZWFybiBtb3JlIGFib3V0IEpTT04gcG9saWN5IGdyYW1tYXIsIHNlZSBbR3JhbW1hciBvZiB0aGUgSUFNIEpTT04gcG9saWN5IGxhbmd1YWdlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2dyYW1tYXIuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogVGhlIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgdXNlZCB0byB2YWxpZGF0ZSB0aGlzIHBhcmFtZXRlciBpcyBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gQW55IHByaW50YWJsZSBBU0NJSSBjaGFyYWN0ZXIgcmFuZ2luZyBmcm9tIHRoZSBzcGFjZSBjaGFyYWN0ZXIgKCBgXFwgdTAwMjBgICkgdGhyb3VnaCB0aGUgZW5kIG9mIHRoZSBBU0NJSSBjaGFyYWN0ZXIgcmFuZ2VcbiAgICAgKiAtIFRoZSBwcmludGFibGUgY2hhcmFjdGVycyBpbiB0aGUgQmFzaWMgTGF0aW4gYW5kIExhdGluLTEgU3VwcGxlbWVudCBjaGFyYWN0ZXIgc2V0ICh0aHJvdWdoIGBcXCB1MDBGRmAgKVxuICAgICAqIC0gVGhlIHNwZWNpYWwgY2hhcmFjdGVycyB0YWIgKCBgXFwgdTAwMDlgICksIGxpbmUgZmVlZCAoIGBcXCB1MDAwQWAgKSwgYW5kIGNhcnJpYWdlIHJldHVybiAoIGBcXCB1MDAwRGAgKVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW1hbmFnZWRwb2xpY3kuaHRtbCNjZm4taWFtLW1hbmFnZWRwb2xpY3ktcG9saWN5ZG9jdW1lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgcG9saWN5RG9jdW1lbnQ6IGFueSB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIEEgZnJpZW5kbHkgZGVzY3JpcHRpb24gb2YgdGhlIHBvbGljeS5cbiAgICAgKlxuICAgICAqIFR5cGljYWxseSB1c2VkIHRvIHN0b3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBwZXJtaXNzaW9ucyBkZWZpbmVkIGluIHRoZSBwb2xpY3kuIEZvciBleGFtcGxlLCBcIkdyYW50cyBhY2Nlc3MgdG8gcHJvZHVjdGlvbiBEeW5hbW9EQiB0YWJsZXMuXCJcbiAgICAgKlxuICAgICAqIFRoZSBwb2xpY3kgZGVzY3JpcHRpb24gaXMgaW1tdXRhYmxlLiBBZnRlciBhIHZhbHVlIGlzIGFzc2lnbmVkLCBpdCBjYW5ub3QgYmUgY2hhbmdlZC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1tYW5hZ2VkcG9saWN5Lmh0bWwjY2ZuLWlhbS1tYW5hZ2VkcG9saWN5LWRlc2NyaXB0aW9uXG4gICAgICovXG4gICAgcHVibGljIGRlc2NyaXB0aW9uOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSAoZnJpZW5kbHkgbmFtZSwgbm90IEFSTikgb2YgdGhlIGdyb3VwIHRvIGF0dGFjaCB0aGUgcG9saWN5IHRvLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1tYW5hZ2VkcG9saWN5Lmh0bWwjY2ZuLWlhbS1tYW5hZ2VkcG9saWN5LWdyb3Vwc1xuICAgICAqL1xuICAgIHB1YmxpYyBncm91cHM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGZyaWVuZGx5IG5hbWUgb2YgdGhlIHBvbGljeS5cbiAgICAgKlxuICAgICAqID4gSWYgeW91IHNwZWNpZnkgYSBuYW1lLCB5b3UgY2Fubm90IHBlcmZvcm0gdXBkYXRlcyB0aGF0IHJlcXVpcmUgcmVwbGFjZW1lbnQgb2YgdGhpcyByZXNvdXJjZS4gWW91IGNhbiBwZXJmb3JtIHVwZGF0ZXMgdGhhdCByZXF1aXJlIG5vIG9yIHNvbWUgaW50ZXJydXB0aW9uLiBJZiB5b3UgbXVzdCByZXBsYWNlIHRoZSByZXNvdXJjZSwgc3BlY2lmeSBhIG5ldyBuYW1lLlxuICAgICAqXG4gICAgICogSWYgeW91IHNwZWNpZnkgYSBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBgQ0FQQUJJTElUWV9OQU1FRF9JQU1gIHZhbHVlIHRvIGFja25vd2xlZGdlIHlvdXIgdGVtcGxhdGUncyBjYXBhYmlsaXRpZXMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0Fja25vd2xlZGdpbmcgSUFNIFJlc291cmNlcyBpbiBBV1MgQ2xvdWRGb3JtYXRpb24gVGVtcGxhdGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS91c2luZy1pYW0tdGVtcGxhdGUuaHRtbCN1c2luZy1pYW0tY2FwYWJpbGl0aWVzKSAuXG4gICAgICpcbiAgICAgKiA+IE5hbWluZyBhbiBJQU0gcmVzb3VyY2UgY2FuIGNhdXNlIGFuIHVucmVjb3ZlcmFibGUgZXJyb3IgaWYgeW91IHJldXNlIHRoZSBzYW1lIHRlbXBsYXRlIGluIG11bHRpcGxlIFJlZ2lvbnMuIFRvIHByZXZlbnQgdGhpcywgd2UgcmVjb21tZW5kIHVzaW5nIGBGbjo6Sm9pbmAgYW5kIGBBV1M6OlJlZ2lvbmAgdG8gY3JlYXRlIGEgUmVnaW9uLXNwZWNpZmljIG5hbWUsIGFzIGluIHRoZSBmb2xsb3dpbmcgZXhhbXBsZTogYHtcIkZuOjpKb2luXCI6IFtcIlwiLCBbe1wiUmVmXCI6IFwiQVdTOjpSZWdpb25cIn0sIHtcIlJlZlwiOiBcIk15UmVzb3VyY2VOYW1lXCJ9XV19YCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tbWFuYWdlZHBvbGljeS5odG1sI2Nmbi1pYW0tbWFuYWdlZHBvbGljeS1tYW5hZ2VkcG9saWN5bmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyBtYW5hZ2VkUG9saWN5TmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBhdGggZm9yIHRoZSBwb2xpY3kuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gaWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiBlaXRoZXIgYSBmb3J3YXJkIHNsYXNoICgvKSBieSBpdHNlbGYgb3IgYSBzdHJpbmcgdGhhdCBtdXN0IGJlZ2luIGFuZCBlbmQgd2l0aCBmb3J3YXJkIHNsYXNoZXMuIEluIGFkZGl0aW9uLCBpdCBjYW4gY29udGFpbiBhbnkgQVNDSUkgY2hhcmFjdGVyIGZyb20gdGhlICEgKCBgXFwgdTAwMjFgICkgdGhyb3VnaCB0aGUgREVMIGNoYXJhY3RlciAoIGBcXCB1MDA3RmAgKSwgaW5jbHVkaW5nIG1vc3QgcHVuY3R1YXRpb24gY2hhcmFjdGVycywgZGlnaXRzLCBhbmQgdXBwZXIgYW5kIGxvd2VyY2FzZWQgbGV0dGVycy5cbiAgICAgKlxuICAgICAqID4gWW91IGNhbm5vdCB1c2UgYW4gYXN0ZXJpc2sgKCopIGluIHRoZSBwYXRoIG5hbWUuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tbWFuYWdlZHBvbGljeS5odG1sI2Nmbi1lYzItZGhjcG9wdGlvbnMtcGF0aFxuICAgICAqL1xuICAgIHB1YmxpYyBwYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSAoZnJpZW5kbHkgbmFtZSwgbm90IEFSTikgb2YgdGhlIHJvbGUgdG8gYXR0YWNoIHRoZSBwb2xpY3kgdG8uXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHBlciBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiA+IElmIGFuIGV4dGVybmFsIHBvbGljeSAoc3VjaCBhcyBgQVdTOjpJQU06OlBvbGljeWAgb3IgYEFXUzo6SUFNOjpNYW5hZ2VkUG9saWN5YCApIGhhcyBhIGBSZWZgIHRvIGEgcm9sZSBhbmQgaWYgYSByZXNvdXJjZSAoc3VjaCBhcyBgQVdTOjpFQ1M6OlNlcnZpY2VgICkgYWxzbyBoYXMgYSBgUmVmYCB0byB0aGUgc2FtZSByb2xlLCBhZGQgYSBgRGVwZW5kc09uYCBhdHRyaWJ1dGUgdG8gdGhlIHJlc291cmNlIHRvIG1ha2UgdGhlIHJlc291cmNlIGRlcGVuZCBvbiB0aGUgZXh0ZXJuYWwgcG9saWN5LiBUaGlzIGRlcGVuZGVuY3kgZW5zdXJlcyB0aGF0IHRoZSByb2xlJ3MgcG9saWN5IGlzIGF2YWlsYWJsZSB0aHJvdWdob3V0IHRoZSByZXNvdXJjZSdzIGxpZmVjeWNsZS4gRm9yIGV4YW1wbGUsIHdoZW4geW91IGRlbGV0ZSBhIHN0YWNrIHdpdGggYW4gYEFXUzo6RUNTOjpTZXJ2aWNlYCByZXNvdXJjZSwgdGhlIGBEZXBlbmRzT25gIGF0dHJpYnV0ZSBlbnN1cmVzIHRoYXQgQVdTIENsb3VkRm9ybWF0aW9uIGRlbGV0ZXMgdGhlIGBBV1M6OkVDUzo6U2VydmljZWAgcmVzb3VyY2UgYmVmb3JlIGRlbGV0aW5nIGl0cyByb2xlJ3MgcG9saWN5LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW1hbmFnZWRwb2xpY3kuaHRtbCNjZm4taWFtLW1hbmFnZWRwb2xpY3ktcm9sZXNcbiAgICAgKi9cbiAgICBwdWJsaWMgcm9sZXM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgKGZyaWVuZGx5IG5hbWUsIG5vdCBBUk4pIG9mIHRoZSBJQU0gdXNlciB0byBhdHRhY2ggdGhlIHBvbGljeSB0by5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tbWFuYWdlZHBvbGljeS5odG1sI2Nmbi1pYW0tbWFuYWdlZHBvbGljeS11c2Vyc1xuICAgICAqL1xuICAgIHB1YmxpYyB1c2Vyczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6SUFNOjpNYW5hZ2VkUG9saWN5YC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5NYW5hZ2VkUG9saWN5UHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmbk1hbmFnZWRQb2xpY3kuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICdwb2xpY3lEb2N1bWVudCcsIHRoaXMpO1xuXG4gICAgICAgIHRoaXMucG9saWN5RG9jdW1lbnQgPSBwcm9wcy5wb2xpY3lEb2N1bWVudDtcbiAgICAgICAgdGhpcy5kZXNjcmlwdGlvbiA9IHByb3BzLmRlc2NyaXB0aW9uO1xuICAgICAgICB0aGlzLmdyb3VwcyA9IHByb3BzLmdyb3VwcztcbiAgICAgICAgdGhpcy5tYW5hZ2VkUG9saWN5TmFtZSA9IHByb3BzLm1hbmFnZWRQb2xpY3lOYW1lO1xuICAgICAgICB0aGlzLnBhdGggPSBwcm9wcy5wYXRoO1xuICAgICAgICB0aGlzLnJvbGVzID0gcHJvcHMucm9sZXM7XG4gICAgICAgIHRoaXMudXNlcnMgPSBwcm9wcy51c2VycztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmbk1hbmFnZWRQb2xpY3kuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHBvbGljeURvY3VtZW50OiB0aGlzLnBvbGljeURvY3VtZW50LFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHRoaXMuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBncm91cHM6IHRoaXMuZ3JvdXBzLFxuICAgICAgICAgICAgbWFuYWdlZFBvbGljeU5hbWU6IHRoaXMubWFuYWdlZFBvbGljeU5hbWUsXG4gICAgICAgICAgICBwYXRoOiB0aGlzLnBhdGgsXG4gICAgICAgICAgICByb2xlczogdGhpcy5yb2xlcyxcbiAgICAgICAgICAgIHVzZXJzOiB0aGlzLnVzZXJzLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmbk1hbmFnZWRQb2xpY3lQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5PSURDUHJvdmlkZXJgXG4gKlxuICogQHN0cnVjdFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1vaWRjcHJvdmlkZXIuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmbk9JRENQcm92aWRlclByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiBjZXJ0aWZpY2F0ZSB0aHVtYnByaW50cyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBJQU0gT0lEQyBwcm92aWRlciByZXNvdXJjZSBvYmplY3QuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0NyZWF0ZU9wZW5JRENvbm5lY3RQcm92aWRlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVPcGVuSURDb25uZWN0UHJvdmlkZXIuaHRtbCkgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW9pZGNwcm92aWRlci5odG1sI2Nmbi1pYW0tb2lkY3Byb3ZpZGVyLXRodW1icHJpbnRsaXN0XG4gICAgICovXG4gICAgcmVhZG9ubHkgdGh1bWJwcmludExpc3Q6IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIGNsaWVudCBJRHMgKGFsc28ga25vd24gYXMgYXVkaWVuY2VzKSB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBJQU0gT0lEQyBwcm92aWRlciByZXNvdXJjZSBvYmplY3QuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0NyZWF0ZU9wZW5JRENvbm5lY3RQcm92aWRlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVPcGVuSURDb25uZWN0UHJvdmlkZXIuaHRtbCkgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW9pZGNwcm92aWRlci5odG1sI2Nmbi1pYW0tb2lkY3Byb3ZpZGVyLWNsaWVudGlkbGlzdFxuICAgICAqL1xuICAgIHJlYWRvbmx5IGNsaWVudElkTGlzdD86IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIHRhZ3MgdGhhdCBhcmUgYXR0YWNoZWQgdG8gdGhlIHNwZWNpZmllZCBJQU0gT0lEQyBwcm92aWRlci4gVGhlIHJldHVybmVkIGxpc3Qgb2YgdGFncyBpcyBzb3J0ZWQgYnkgdGFnIGtleS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGFnZ2luZywgc2VlIFtUYWdnaW5nIElBTSByZXNvdXJjZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF90YWdzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1vaWRjcHJvdmlkZXIuaHRtbCNjZm4taWFtLW9pZGNwcm92aWRlci10YWdzXG4gICAgICovXG4gICAgcmVhZG9ubHkgdGFncz86IGNkay5DZm5UYWdbXTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBVUkwgdGhhdCB0aGUgSUFNIE9JREMgcHJvdmlkZXIgcmVzb3VyY2Ugb2JqZWN0IGlzIGFzc29jaWF0ZWQgd2l0aC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQ3JlYXRlT3BlbklEQ29ubmVjdFByb3ZpZGVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZU9wZW5JRENvbm5lY3RQcm92aWRlci5odG1sKSAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tb2lkY3Byb3ZpZGVyLmh0bWwjY2ZuLWlhbS1vaWRjcHJvdmlkZXItdXJsXG4gICAgICovXG4gICAgcmVhZG9ubHkgdXJsPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbk9JRENQcm92aWRlclByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5PSURDUHJvdmlkZXJQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5PSURDUHJvdmlkZXJQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NsaWVudElkTGlzdCcsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMuY2xpZW50SWRMaXN0KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0YWdzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlQ2ZuVGFnKSkocHJvcGVydGllcy50YWdzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0aHVtYnByaW50TGlzdCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy50aHVtYnByaW50TGlzdCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndGh1bWJwcmludExpc3QnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLnRodW1icHJpbnRMaXN0KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd1cmwnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMudXJsKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmbk9JRENQcm92aWRlclByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06Ok9JRENQcm92aWRlcmAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuT0lEQ1Byb3ZpZGVyUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6T0lEQ1Byb3ZpZGVyYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmbk9JRENQcm92aWRlclByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5PSURDUHJvdmlkZXJQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgVGh1bWJwcmludExpc3Q6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnRodW1icHJpbnRMaXN0KSxcbiAgICAgICAgQ2xpZW50SWRMaXN0OiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5jbGllbnRJZExpc3QpLFxuICAgICAgICBUYWdzOiBjZGsubGlzdE1hcHBlcihjZGsuY2ZuVGFnVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy50YWdzKSxcbiAgICAgICAgVXJsOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnVybCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbk9JRENQcm92aWRlclByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuT0lEQ1Byb3ZpZGVyUHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbk9JRENQcm92aWRlclByb3BzPigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndGh1bWJwcmludExpc3QnLCAnVGh1bWJwcmludExpc3QnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuVGh1bWJwcmludExpc3QpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NsaWVudElkTGlzdCcsICdDbGllbnRJZExpc3QnLCBwcm9wZXJ0aWVzLkNsaWVudElkTGlzdCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmdBcnJheShwcm9wZXJ0aWVzLkNsaWVudElkTGlzdCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndGFncycsICdUYWdzJywgcHJvcGVydGllcy5UYWdzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Q2ZuVGFnKShwcm9wZXJ0aWVzLlRhZ3MpIDogdW5kZWZpbmVkIGFzIGFueSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd1cmwnLCAnVXJsJywgcHJvcGVydGllcy5VcmwgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVXJsKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpJQU06Ok9JRENQcm92aWRlcmBcbiAqXG4gKiBDcmVhdGVzIGFuIElBTSBlbnRpdHkgdG8gZGVzY3JpYmUgYW4gaWRlbnRpdHkgcHJvdmlkZXIgKElkUCkgdGhhdCBzdXBwb3J0cyBbT3BlbklEIENvbm5lY3QgKE9JREMpXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL29wZW5pZC5uZXQvY29ubmVjdC8pIC5cbiAqXG4gKiBUaGUgT0lEQyBwcm92aWRlciB0aGF0IHlvdSBjcmVhdGUgd2l0aCB0aGlzIG9wZXJhdGlvbiBjYW4gYmUgdXNlZCBhcyBhIHByaW5jaXBhbCBpbiBhIHJvbGUncyB0cnVzdCBwb2xpY3kuIFN1Y2ggYSBwb2xpY3kgZXN0YWJsaXNoZXMgYSB0cnVzdCByZWxhdGlvbnNoaXAgYmV0d2VlbiBBV1MgYW5kIHRoZSBPSURDIHByb3ZpZGVyLlxuICpcbiAqIFdoZW4geW91IGNyZWF0ZSB0aGUgSUFNIE9JREMgcHJvdmlkZXIsIHlvdSBzcGVjaWZ5IHRoZSBmb2xsb3dpbmc6XG4gKlxuICogLSBUaGUgVVJMIG9mIHRoZSBPSURDIGlkZW50aXR5IHByb3ZpZGVyIChJZFApIHRvIHRydXN0XG4gKiAtIEEgbGlzdCBvZiBjbGllbnQgSURzIChhbHNvIGtub3duIGFzIGF1ZGllbmNlcykgdGhhdCBpZGVudGlmeSB0aGUgYXBwbGljYXRpb24gb3IgYXBwbGljYXRpb25zIHRoYXQgYXJlIGFsbG93ZWQgdG8gYXV0aGVudGljYXRlIHVzaW5nIHRoZSBPSURDIHByb3ZpZGVyXG4gKiAtIEEgbGlzdCBvZiB0aHVtYnByaW50cyBvZiBvbmUgb3IgbW9yZSBzZXJ2ZXIgY2VydGlmaWNhdGVzIHRoYXQgdGhlIElkUCB1c2VzXG4gKlxuICogWW91IGdldCBhbGwgb2YgdGhpcyBpbmZvcm1hdGlvbiBmcm9tIHRoZSBPSURDIElkUCB0aGF0IHlvdSB3YW50IHRvIHVzZSB0byBhY2Nlc3MgQVdTIC5cbiAqXG4gKiA+IFRoZSB0cnVzdCBmb3IgdGhlIE9JREMgcHJvdmlkZXIgaXMgZGVyaXZlZCBmcm9tIHRoZSBJQU0gcHJvdmlkZXIgdGhhdCB0aGlzIG9wZXJhdGlvbiBjcmVhdGVzLiBUaGVyZWZvcmUsIGl0IGlzIGJlc3QgdG8gbGltaXQgYWNjZXNzIHRvIHRoZSBbQ3JlYXRlT3BlbklEQ29ubmVjdFByb3ZpZGVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZU9wZW5JRENvbm5lY3RQcm92aWRlci5odG1sKSBvcGVyYXRpb24gdG8gaGlnaGx5IHByaXZpbGVnZWQgdXNlcnMuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpJQU06Ok9JRENQcm92aWRlclxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1vaWRjcHJvdmlkZXIuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuT0lEQ1Byb3ZpZGVyIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6SUFNOjpPSURDUHJvdmlkZXJcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmbk9JRENQcm92aWRlciB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuT0lEQ1Byb3ZpZGVyUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmbk9JRENQcm92aWRlcihzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBmb3IgdGhlIHNwZWNpZmllZCBgQVdTOjpJQU06Ok9JRENQcm92aWRlcmAgcmVzb3VyY2UuXG4gICAgICogQGNsb3VkZm9ybWF0aW9uQXR0cmlidXRlIEFyblxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBhdHRyQXJuOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgY2VydGlmaWNhdGUgdGh1bWJwcmludHMgdGhhdCBhcmUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgSUFNIE9JREMgcHJvdmlkZXIgcmVzb3VyY2Ugb2JqZWN0LiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtDcmVhdGVPcGVuSURDb25uZWN0UHJvdmlkZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlT3BlbklEQ29ubmVjdFByb3ZpZGVyLmh0bWwpIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1vaWRjcHJvdmlkZXIuaHRtbCNjZm4taWFtLW9pZGNwcm92aWRlci10aHVtYnByaW50bGlzdFxuICAgICAqL1xuICAgIHB1YmxpYyB0aHVtYnByaW50TGlzdDogc3RyaW5nW107XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgY2xpZW50IElEcyAoYWxzbyBrbm93biBhcyBhdWRpZW5jZXMpIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIElBTSBPSURDIHByb3ZpZGVyIHJlc291cmNlIG9iamVjdC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQ3JlYXRlT3BlbklEQ29ubmVjdFByb3ZpZGVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZU9wZW5JRENvbm5lY3RQcm92aWRlci5odG1sKSAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tb2lkY3Byb3ZpZGVyLmh0bWwjY2ZuLWlhbS1vaWRjcHJvdmlkZXItY2xpZW50aWRsaXN0XG4gICAgICovXG4gICAgcHVibGljIGNsaWVudElkTGlzdDogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgdGFncyB0aGF0IGFyZSBhdHRhY2hlZCB0byB0aGUgc3BlY2lmaWVkIElBTSBPSURDIHByb3ZpZGVyLiBUaGUgcmV0dXJuZWQgbGlzdCBvZiB0YWdzIGlzIHNvcnRlZCBieSB0YWcga2V5LiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0YWdnaW5nLCBzZWUgW1RhZ2dpbmcgSUFNIHJlc291cmNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX3RhZ3MuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW9pZGNwcm92aWRlci5odG1sI2Nmbi1pYW0tb2lkY3Byb3ZpZGVyLXRhZ3NcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgdGFnczogY2RrLlRhZ01hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgVVJMIHRoYXQgdGhlIElBTSBPSURDIHByb3ZpZGVyIHJlc291cmNlIG9iamVjdCBpcyBhc3NvY2lhdGVkIHdpdGguIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0NyZWF0ZU9wZW5JRENvbm5lY3RQcm92aWRlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVPcGVuSURDb25uZWN0UHJvdmlkZXIuaHRtbCkgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW9pZGNwcm92aWRlci5odG1sI2Nmbi1pYW0tb2lkY3Byb3ZpZGVyLXVybFxuICAgICAqL1xuICAgIHB1YmxpYyB1cmw6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpJQU06Ok9JRENQcm92aWRlcmAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuT0lEQ1Byb3ZpZGVyUHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmbk9JRENQcm92aWRlci5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ3RodW1icHJpbnRMaXN0JywgdGhpcyk7XG4gICAgICAgIHRoaXMuYXR0ckFybiA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnQXJuJykpO1xuXG4gICAgICAgIHRoaXMudGh1bWJwcmludExpc3QgPSBwcm9wcy50aHVtYnByaW50TGlzdDtcbiAgICAgICAgdGhpcy5jbGllbnRJZExpc3QgPSBwcm9wcy5jbGllbnRJZExpc3Q7XG4gICAgICAgIHRoaXMudGFncyA9IG5ldyBjZGsuVGFnTWFuYWdlcihjZGsuVGFnVHlwZS5TVEFOREFSRCwgXCJBV1M6OklBTTo6T0lEQ1Byb3ZpZGVyXCIsIHByb3BzLnRhZ3MsIHsgdGFnUHJvcGVydHlOYW1lOiAndGFncycgfSk7XG4gICAgICAgIHRoaXMudXJsID0gcHJvcHMudXJsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuT0lEQ1Byb3ZpZGVyLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0aHVtYnByaW50TGlzdDogdGhpcy50aHVtYnByaW50TGlzdCxcbiAgICAgICAgICAgIGNsaWVudElkTGlzdDogdGhpcy5jbGllbnRJZExpc3QsXG4gICAgICAgICAgICB0YWdzOiB0aGlzLnRhZ3MucmVuZGVyVGFncygpLFxuICAgICAgICAgICAgdXJsOiB0aGlzLnVybCxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5PSURDUHJvdmlkZXJQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5Qb2xpY3lgXG4gKlxuICogQHN0cnVjdFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1wb2xpY3kuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmblBvbGljeVByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwb2xpY3kgZG9jdW1lbnQuXG4gICAgICpcbiAgICAgKiBZb3UgbXVzdCBwcm92aWRlIHBvbGljaWVzIGluIEpTT04gZm9ybWF0IGluIElBTS4gSG93ZXZlciwgZm9yIEFXUyBDbG91ZEZvcm1hdGlvbiB0ZW1wbGF0ZXMgZm9ybWF0dGVkIGluIFlBTUwsIHlvdSBjYW4gcHJvdmlkZSB0aGUgcG9saWN5IGluIEpTT04gb3IgWUFNTCBmb3JtYXQuIEFXUyBDbG91ZEZvcm1hdGlvbiBhbHdheXMgY29udmVydHMgYSBZQU1MIHBvbGljeSB0byBKU09OIGZvcm1hdCBiZWZvcmUgc3VibWl0dGluZyBpdCB0byBJQU0uXG4gICAgICpcbiAgICAgKiBUaGUgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSB1c2VkIHRvIHZhbGlkYXRlIHRoaXMgcGFyYW1ldGVyIGlzIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBBbnkgcHJpbnRhYmxlIEFTQ0lJIGNoYXJhY3RlciByYW5naW5nIGZyb20gdGhlIHNwYWNlIGNoYXJhY3RlciAoIGBcXCB1MDAyMGAgKSB0aHJvdWdoIHRoZSBlbmQgb2YgdGhlIEFTQ0lJIGNoYXJhY3RlciByYW5nZVxuICAgICAqIC0gVGhlIHByaW50YWJsZSBjaGFyYWN0ZXJzIGluIHRoZSBCYXNpYyBMYXRpbiBhbmQgTGF0aW4tMSBTdXBwbGVtZW50IGNoYXJhY3RlciBzZXQgKHRocm91Z2ggYFxcIHUwMEZGYCApXG4gICAgICogLSBUaGUgc3BlY2lhbCBjaGFyYWN0ZXJzIHRhYiAoIGBcXCB1MDAwOWAgKSwgbGluZSBmZWVkICggYFxcIHUwMDBBYCApLCBhbmQgY2FycmlhZ2UgcmV0dXJuICggYFxcIHUwMDBEYCApXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcG9saWN5Lmh0bWwjY2ZuLWlhbS1wb2xpY3ktcG9saWN5ZG9jdW1lbnRcbiAgICAgKi9cbiAgICByZWFkb25seSBwb2xpY3lEb2N1bWVudDogYW55IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHBvbGljeSBkb2N1bWVudC5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcG9saWN5Lmh0bWwjY2ZuLWlhbS1wb2xpY3ktcG9saWN5bmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IHBvbGljeU5hbWU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBncm91cCB0byBhc3NvY2lhdGUgdGhlIHBvbGljeSB3aXRoLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC0uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcG9saWN5Lmh0bWwjY2ZuLWlhbS1wb2xpY3ktZ3JvdXBzXG4gICAgICovXG4gICAgcmVhZG9ubHkgZ3JvdXBzPzogc3RyaW5nW107XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcm9sZSB0byBhc3NvY2lhdGUgdGhlIHBvbGljeSB3aXRoLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzIChwZXIgaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdXBwZXIgYW5kIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyB3aXRoIG5vIHNwYWNlcy4gWW91IGNhbiBhbHNvIGluY2x1ZGUgYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogXys9LC5ALVxuICAgICAqXG4gICAgICogPiBJZiBhbiBleHRlcm5hbCBwb2xpY3kgKHN1Y2ggYXMgYEFXUzo6SUFNOjpQb2xpY3lgIG9yIGBBV1M6OklBTTo6TWFuYWdlZFBvbGljeWAgKSBoYXMgYSBgUmVmYCB0byBhIHJvbGUgYW5kIGlmIGEgcmVzb3VyY2UgKHN1Y2ggYXMgYEFXUzo6RUNTOjpTZXJ2aWNlYCApIGFsc28gaGFzIGEgYFJlZmAgdG8gdGhlIHNhbWUgcm9sZSwgYWRkIGEgYERlcGVuZHNPbmAgYXR0cmlidXRlIHRvIHRoZSByZXNvdXJjZSB0byBtYWtlIHRoZSByZXNvdXJjZSBkZXBlbmQgb24gdGhlIGV4dGVybmFsIHBvbGljeS4gVGhpcyBkZXBlbmRlbmN5IGVuc3VyZXMgdGhhdCB0aGUgcm9sZSdzIHBvbGljeSBpcyBhdmFpbGFibGUgdGhyb3VnaG91dCB0aGUgcmVzb3VyY2UncyBsaWZlY3ljbGUuIEZvciBleGFtcGxlLCB3aGVuIHlvdSBkZWxldGUgYSBzdGFjayB3aXRoIGFuIGBBV1M6OkVDUzo6U2VydmljZWAgcmVzb3VyY2UsIHRoZSBgRGVwZW5kc09uYCBhdHRyaWJ1dGUgZW5zdXJlcyB0aGF0IEFXUyBDbG91ZEZvcm1hdGlvbiBkZWxldGVzIHRoZSBgQVdTOjpFQ1M6OlNlcnZpY2VgIHJlc291cmNlIGJlZm9yZSBkZWxldGluZyBpdHMgcm9sZSdzIHBvbGljeS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1wb2xpY3kuaHRtbCNjZm4taWFtLXBvbGljeS1yb2xlc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IHJvbGVzPzogc3RyaW5nW107XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgdXNlciB0byBhc3NvY2lhdGUgdGhlIHBvbGljeSB3aXRoLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1wb2xpY3kuaHRtbCNjZm4taWFtLXBvbGljeS11c2Vyc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IHVzZXJzPzogc3RyaW5nW107XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2ZuUG9saWN5UHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblBvbGljeVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblBvbGljeVByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZ3JvdXBzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5ncm91cHMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvbGljeURvY3VtZW50JywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnBvbGljeURvY3VtZW50KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb2xpY3lEb2N1bWVudCcsIGNkay52YWxpZGF0ZU9iamVjdCkocHJvcGVydGllcy5wb2xpY3lEb2N1bWVudCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5TmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5wb2xpY3lOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb2xpY3lOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnBvbGljeU5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3JvbGVzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5yb2xlcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndXNlcnMnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLnVzZXJzKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmblBvbGljeVByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlBvbGljeWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuUG9saWN5UHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6UG9saWN5YCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblBvbGljeVByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5Qb2xpY3lQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgUG9saWN5RG9jdW1lbnQ6IGNkay5vYmplY3RUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucG9saWN5RG9jdW1lbnQpLFxuICAgICAgICBQb2xpY3lOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBvbGljeU5hbWUpLFxuICAgICAgICBHcm91cHM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmdyb3VwcyksXG4gICAgICAgIFJvbGVzOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5yb2xlcyksXG4gICAgICAgIFVzZXJzOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy51c2VycyksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblBvbGljeVByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuUG9saWN5UHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblBvbGljeVByb3BzPigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncG9saWN5RG9jdW1lbnQnLCAnUG9saWN5RG9jdW1lbnQnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFueShwcm9wZXJ0aWVzLlBvbGljeURvY3VtZW50KSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwb2xpY3lOYW1lJywgJ1BvbGljeU5hbWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlBvbGljeU5hbWUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2dyb3VwcycsICdHcm91cHMnLCBwcm9wZXJ0aWVzLkdyb3VwcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmdBcnJheShwcm9wZXJ0aWVzLkdyb3VwcykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncm9sZXMnLCAnUm9sZXMnLCBwcm9wZXJ0aWVzLlJvbGVzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuUm9sZXMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3VzZXJzJywgJ1VzZXJzJywgcHJvcGVydGllcy5Vc2VycyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmdBcnJheShwcm9wZXJ0aWVzLlVzZXJzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpJQU06OlBvbGljeWBcbiAqXG4gKiBBZGRzIG9yIHVwZGF0ZXMgYW4gaW5saW5lIHBvbGljeSBkb2N1bWVudCB0aGF0IGlzIGVtYmVkZGVkIGluIHRoZSBzcGVjaWZpZWQgSUFNIHVzZXIsIGdyb3VwLCBvciByb2xlLlxuICpcbiAqIEFuIElBTSB1c2VyIGNhbiBhbHNvIGhhdmUgYSBtYW5hZ2VkIHBvbGljeSBhdHRhY2hlZCB0byBpdC4gRm9yIGluZm9ybWF0aW9uIGFib3V0IHBvbGljaWVzLCBzZWUgW01hbmFnZWQgUG9saWNpZXMgYW5kIElubGluZSBQb2xpY2llc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3BvbGljaWVzLW1hbmFnZWQtdnMtaW5saW5lLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAqXG4gKiBUaGUgR3JvdXBzLCBSb2xlcywgYW5kIFVzZXJzIHByb3BlcnRpZXMgYXJlIG9wdGlvbmFsLiBIb3dldmVyLCB5b3UgbXVzdCBzcGVjaWZ5IGF0IGxlYXN0IG9uZSBvZiB0aGVzZSBwcm9wZXJ0aWVzLlxuICpcbiAqIEZvciBpbmZvcm1hdGlvbiBhYm91dCBsaW1pdHMgb24gdGhlIG51bWJlciBvZiBpbmxpbmUgcG9saWNpZXMgdGhhdCB5b3UgY2FuIGVtYmVkIGluIGFuIGlkZW50aXR5LCBzZWUgW0xpbWl0YXRpb25zIG9uIElBTSBFbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL0xpbWl0YXRpb25zT25FbnRpdGllcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpJQU06OlBvbGljeVxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1wb2xpY3kuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuUG9saWN5IGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6SUFNOjpQb2xpY3lcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmblBvbGljeSB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuUG9saWN5UHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmblBvbGljeShzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcG9saWN5IGRvY3VtZW50LlxuICAgICAqXG4gICAgICogWW91IG11c3QgcHJvdmlkZSBwb2xpY2llcyBpbiBKU09OIGZvcm1hdCBpbiBJQU0uIEhvd2V2ZXIsIGZvciBBV1MgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGVzIGZvcm1hdHRlZCBpbiBZQU1MLCB5b3UgY2FuIHByb3ZpZGUgdGhlIHBvbGljeSBpbiBKU09OIG9yIFlBTUwgZm9ybWF0LiBBV1MgQ2xvdWRGb3JtYXRpb24gYWx3YXlzIGNvbnZlcnRzIGEgWUFNTCBwb2xpY3kgdG8gSlNPTiBmb3JtYXQgYmVmb3JlIHN1Ym1pdHRpbmcgaXQgdG8gSUFNLlxuICAgICAqXG4gICAgICogVGhlIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgdXNlZCB0byB2YWxpZGF0ZSB0aGlzIHBhcmFtZXRlciBpcyBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gQW55IHByaW50YWJsZSBBU0NJSSBjaGFyYWN0ZXIgcmFuZ2luZyBmcm9tIHRoZSBzcGFjZSBjaGFyYWN0ZXIgKCBgXFwgdTAwMjBgICkgdGhyb3VnaCB0aGUgZW5kIG9mIHRoZSBBU0NJSSBjaGFyYWN0ZXIgcmFuZ2VcbiAgICAgKiAtIFRoZSBwcmludGFibGUgY2hhcmFjdGVycyBpbiB0aGUgQmFzaWMgTGF0aW4gYW5kIExhdGluLTEgU3VwcGxlbWVudCBjaGFyYWN0ZXIgc2V0ICh0aHJvdWdoIGBcXCB1MDBGRmAgKVxuICAgICAqIC0gVGhlIHNwZWNpYWwgY2hhcmFjdGVycyB0YWIgKCBgXFwgdTAwMDlgICksIGxpbmUgZmVlZCAoIGBcXCB1MDAwQWAgKSwgYW5kIGNhcnJpYWdlIHJldHVybiAoIGBcXCB1MDAwRGAgKVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXBvbGljeS5odG1sI2Nmbi1pYW0tcG9saWN5LXBvbGljeWRvY3VtZW50XG4gICAgICovXG4gICAgcHVibGljIHBvbGljeURvY3VtZW50OiBhbnkgfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcG9saWN5IGRvY3VtZW50LlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1wb2xpY3kuaHRtbCNjZm4taWFtLXBvbGljeS1wb2xpY3luYW1lXG4gICAgICovXG4gICAgcHVibGljIHBvbGljeU5hbWU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBncm91cCB0byBhc3NvY2lhdGUgdGhlIHBvbGljeSB3aXRoLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC0uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcG9saWN5Lmh0bWwjY2ZuLWlhbS1wb2xpY3ktZ3JvdXBzXG4gICAgICovXG4gICAgcHVibGljIGdyb3Vwczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcm9sZSB0byBhc3NvY2lhdGUgdGhlIHBvbGljeSB3aXRoLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzIChwZXIgaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdXBwZXIgYW5kIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyB3aXRoIG5vIHNwYWNlcy4gWW91IGNhbiBhbHNvIGluY2x1ZGUgYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogXys9LC5ALVxuICAgICAqXG4gICAgICogPiBJZiBhbiBleHRlcm5hbCBwb2xpY3kgKHN1Y2ggYXMgYEFXUzo6SUFNOjpQb2xpY3lgIG9yIGBBV1M6OklBTTo6TWFuYWdlZFBvbGljeWAgKSBoYXMgYSBgUmVmYCB0byBhIHJvbGUgYW5kIGlmIGEgcmVzb3VyY2UgKHN1Y2ggYXMgYEFXUzo6RUNTOjpTZXJ2aWNlYCApIGFsc28gaGFzIGEgYFJlZmAgdG8gdGhlIHNhbWUgcm9sZSwgYWRkIGEgYERlcGVuZHNPbmAgYXR0cmlidXRlIHRvIHRoZSByZXNvdXJjZSB0byBtYWtlIHRoZSByZXNvdXJjZSBkZXBlbmQgb24gdGhlIGV4dGVybmFsIHBvbGljeS4gVGhpcyBkZXBlbmRlbmN5IGVuc3VyZXMgdGhhdCB0aGUgcm9sZSdzIHBvbGljeSBpcyBhdmFpbGFibGUgdGhyb3VnaG91dCB0aGUgcmVzb3VyY2UncyBsaWZlY3ljbGUuIEZvciBleGFtcGxlLCB3aGVuIHlvdSBkZWxldGUgYSBzdGFjayB3aXRoIGFuIGBBV1M6OkVDUzo6U2VydmljZWAgcmVzb3VyY2UsIHRoZSBgRGVwZW5kc09uYCBhdHRyaWJ1dGUgZW5zdXJlcyB0aGF0IEFXUyBDbG91ZEZvcm1hdGlvbiBkZWxldGVzIHRoZSBgQVdTOjpFQ1M6OlNlcnZpY2VgIHJlc291cmNlIGJlZm9yZSBkZWxldGluZyBpdHMgcm9sZSdzIHBvbGljeS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1wb2xpY3kuaHRtbCNjZm4taWFtLXBvbGljeS1yb2xlc1xuICAgICAqL1xuICAgIHB1YmxpYyByb2xlczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgdXNlciB0byBhc3NvY2lhdGUgdGhlIHBvbGljeSB3aXRoLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1wb2xpY3kuaHRtbCNjZm4taWFtLXBvbGljeS11c2Vyc1xuICAgICAqL1xuICAgIHB1YmxpYyB1c2Vyczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6SUFNOjpQb2xpY3lgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmblBvbGljeVByb3BzKSB7XG4gICAgICAgIHN1cGVyKHNjb3BlLCBpZCwgeyB0eXBlOiBDZm5Qb2xpY3kuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICdwb2xpY3lEb2N1bWVudCcsIHRoaXMpO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAncG9saWN5TmFtZScsIHRoaXMpO1xuXG4gICAgICAgIHRoaXMucG9saWN5RG9jdW1lbnQgPSBwcm9wcy5wb2xpY3lEb2N1bWVudDtcbiAgICAgICAgdGhpcy5wb2xpY3lOYW1lID0gcHJvcHMucG9saWN5TmFtZTtcbiAgICAgICAgdGhpcy5ncm91cHMgPSBwcm9wcy5ncm91cHM7XG4gICAgICAgIHRoaXMucm9sZXMgPSBwcm9wcy5yb2xlcztcbiAgICAgICAgdGhpcy51c2VycyA9IHByb3BzLnVzZXJzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuUG9saWN5LkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwb2xpY3lEb2N1bWVudDogdGhpcy5wb2xpY3lEb2N1bWVudCxcbiAgICAgICAgICAgIHBvbGljeU5hbWU6IHRoaXMucG9saWN5TmFtZSxcbiAgICAgICAgICAgIGdyb3VwczogdGhpcy5ncm91cHMsXG4gICAgICAgICAgICByb2xlczogdGhpcy5yb2xlcyxcbiAgICAgICAgICAgIHVzZXJzOiB0aGlzLnVzZXJzLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmblBvbGljeVByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmblJvbGVgXG4gKlxuICogQHN0cnVjdFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5Sb2xlUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogVGhlIHRydXN0IHBvbGljeSB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHJvbGUuIFRydXN0IHBvbGljaWVzIGRlZmluZSB3aGljaCBlbnRpdGllcyBjYW4gYXNzdW1lIHRoZSByb2xlLiBZb3UgY2FuIGFzc29jaWF0ZSBvbmx5IG9uZSB0cnVzdCBwb2xpY3kgd2l0aCBhIHJvbGUuIEZvciBhbiBleGFtcGxlIG9mIGEgcG9saWN5IHRoYXQgY2FuIGJlIHVzZWQgdG8gYXNzdW1lIGEgcm9sZSwgc2VlIFtUZW1wbGF0ZSBFeGFtcGxlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWwjYXdzLXJlc291cmNlLWlhbS1yb2xlLS1leGFtcGxlcykgLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZWxlbWVudHMgdGhhdCB5b3UgY2FuIHVzZSBpbiBhbiBJQU0gcG9saWN5LCBzZWUgW0lBTSBQb2xpY3kgRWxlbWVudHMgUmVmZXJlbmNlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWwjY2ZuLWlhbS1yb2xlLWFzc3VtZXJvbGVwb2xpY3lkb2N1bWVudFxuICAgICAqL1xuICAgIHJlYWRvbmx5IGFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudDogYW55IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogQSBkZXNjcmlwdGlvbiBvZiB0aGUgcm9sZSB0aGF0IHlvdSBwcm92aWRlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNjZm4taWFtLXJvbGUtZGVzY3JpcHRpb25cbiAgICAgKi9cbiAgICByZWFkb25seSBkZXNjcmlwdGlvbj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiBBbWF6b24gUmVzb3VyY2UgTmFtZXMgKEFSTnMpIG9mIHRoZSBJQU0gbWFuYWdlZCBwb2xpY2llcyB0aGF0IHlvdSB3YW50IHRvIGF0dGFjaCB0byB0aGUgcm9sZS5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IEFSTnMsIHNlZSBbQW1hem9uIFJlc291cmNlIE5hbWVzIChBUk5zKSBhbmQgQVdTIFNlcnZpY2UgTmFtZXNwYWNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dlbmVyYWwvbGF0ZXN0L2dyL2F3cy1hcm5zLWFuZC1uYW1lc3BhY2VzLmh0bWwpIGluIHRoZSAqQVdTIEdlbmVyYWwgUmVmZXJlbmNlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcm9sZS5odG1sI2Nmbi1pYW0tcm9sZS1tYW5hZ2Vwb2xpY3lhcm5zXG4gICAgICovXG4gICAgcmVhZG9ubHkgbWFuYWdlZFBvbGljeUFybnM/OiBzdHJpbmdbXTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIHNlc3Npb24gZHVyYXRpb24gKGluIHNlY29uZHMpIHRoYXQgeW91IHdhbnQgdG8gc2V0IGZvciB0aGUgc3BlY2lmaWVkIHJvbGUuIElmIHlvdSBkbyBub3Qgc3BlY2lmeSBhIHZhbHVlIGZvciB0aGlzIHNldHRpbmcsIHRoZSBkZWZhdWx0IG1heGltdW0gb2Ygb25lIGhvdXIgaXMgYXBwbGllZC4gVGhpcyBzZXR0aW5nIGNhbiBoYXZlIGEgdmFsdWUgZnJvbSAxIGhvdXIgdG8gMTIgaG91cnMuXG4gICAgICpcbiAgICAgKiBBbnlvbmUgd2hvIGFzc3VtZXMgdGhlIHJvbGUgZnJvbSB0aGUgb3IgQVBJIGNhbiB1c2UgdGhlIGBEdXJhdGlvblNlY29uZHNgIEFQSSBwYXJhbWV0ZXIgb3IgdGhlIGBkdXJhdGlvbi1zZWNvbmRzYCBDTEkgcGFyYW1ldGVyIHRvIHJlcXVlc3QgYSBsb25nZXIgc2Vzc2lvbi4gVGhlIGBNYXhTZXNzaW9uRHVyYXRpb25gIHNldHRpbmcgZGV0ZXJtaW5lcyB0aGUgbWF4aW11bSBkdXJhdGlvbiB0aGF0IGNhbiBiZSByZXF1ZXN0ZWQgdXNpbmcgdGhlIGBEdXJhdGlvblNlY29uZHNgIHBhcmFtZXRlci4gSWYgdXNlcnMgZG9uJ3Qgc3BlY2lmeSBhIHZhbHVlIGZvciB0aGUgYER1cmF0aW9uU2Vjb25kc2AgcGFyYW1ldGVyLCB0aGVpciBzZWN1cml0eSBjcmVkZW50aWFscyBhcmUgdmFsaWQgZm9yIG9uZSBob3VyIGJ5IGRlZmF1bHQuIFRoaXMgYXBwbGllcyB3aGVuIHlvdSB1c2UgdGhlIGBBc3N1bWVSb2xlKmAgQVBJIG9wZXJhdGlvbnMgb3IgdGhlIGBhc3N1bWUtcm9sZSpgIENMSSBvcGVyYXRpb25zIGJ1dCBkb2VzIG5vdCBhcHBseSB3aGVuIHlvdSB1c2UgdGhvc2Ugb3BlcmF0aW9ucyB0byBjcmVhdGUgYSBjb25zb2xlIFVSTC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbVXNpbmcgSUFNIHJvbGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvaWRfcm9sZXNfdXNlLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWwjY2ZuLWlhbS1yb2xlLW1heHNlc3Npb25kdXJhdGlvblxuICAgICAqL1xuICAgIHJlYWRvbmx5IG1heFNlc3Npb25EdXJhdGlvbj86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwYXRoIHRvIHRoZSByb2xlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gSWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiBlaXRoZXIgYSBmb3J3YXJkIHNsYXNoICgvKSBieSBpdHNlbGYgb3IgYSBzdHJpbmcgdGhhdCBtdXN0IGJlZ2luIGFuZCBlbmQgd2l0aCBmb3J3YXJkIHNsYXNoZXMuIEluIGFkZGl0aW9uLCBpdCBjYW4gY29udGFpbiBhbnkgQVNDSUkgY2hhcmFjdGVyIGZyb20gdGhlICEgKCBgXFwgdTAwMjFgICkgdGhyb3VnaCB0aGUgREVMIGNoYXJhY3RlciAoIGBcXCB1MDA3RmAgKSwgaW5jbHVkaW5nIG1vc3QgcHVuY3R1YXRpb24gY2hhcmFjdGVycywgZGlnaXRzLCBhbmQgdXBwZXIgYW5kIGxvd2VyY2FzZWQgbGV0dGVycy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWwjY2ZuLWlhbS1yb2xlLXBhdGhcbiAgICAgKi9cbiAgICByZWFkb25seSBwYXRoPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIEFSTiBvZiB0aGUgcG9saWN5IHVzZWQgdG8gc2V0IHRoZSBwZXJtaXNzaW9ucyBib3VuZGFyeSBmb3IgdGhlIHJvbGUuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwZXJtaXNzaW9ucyBib3VuZGFyaWVzLCBzZWUgW1Blcm1pc3Npb25zIGJvdW5kYXJpZXMgZm9yIElBTSBpZGVudGl0aWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvYWNjZXNzX3BvbGljaWVzX2JvdW5kYXJpZXMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNjZm4taWFtLXJvbGUtcGVybWlzc2lvbnNib3VuZGFyeVxuICAgICAqL1xuICAgIHJlYWRvbmx5IHBlcm1pc3Npb25zQm91bmRhcnk/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIG9yIHVwZGF0ZXMgYW4gaW5saW5lIHBvbGljeSBkb2N1bWVudCB0aGF0IGlzIGVtYmVkZGVkIGluIHRoZSBzcGVjaWZpZWQgSUFNIHJvbGUuXG4gICAgICpcbiAgICAgKiBXaGVuIHlvdSBlbWJlZCBhbiBpbmxpbmUgcG9saWN5IGluIGEgcm9sZSwgdGhlIGlubGluZSBwb2xpY3kgaXMgdXNlZCBhcyBwYXJ0IG9mIHRoZSByb2xlJ3MgYWNjZXNzIChwZXJtaXNzaW9ucykgcG9saWN5LiBUaGUgcm9sZSdzIHRydXN0IHBvbGljeSBpcyBjcmVhdGVkIGF0IHRoZSBzYW1lIHRpbWUgYXMgdGhlIHJvbGUuIFlvdSBjYW4gdXBkYXRlIGEgcm9sZSdzIHRydXN0IHBvbGljeSBsYXRlci4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgSUFNIHJvbGVzLCBnbyB0byBbVXNpbmcgUm9sZXMgdG8gRGVsZWdhdGUgUGVybWlzc2lvbnMgYW5kIEZlZGVyYXRlIElkZW50aXRpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yb2xlcy10b3BsZXZlbC5odG1sKSAuXG4gICAgICpcbiAgICAgKiBBIHJvbGUgY2FuIGFsc28gaGF2ZSBhbiBhdHRhY2hlZCBtYW5hZ2VkIHBvbGljeS4gRm9yIGluZm9ybWF0aW9uIGFib3V0IHBvbGljaWVzLCBzZWUgW01hbmFnZWQgUG9saWNpZXMgYW5kIElubGluZSBQb2xpY2llc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3BvbGljaWVzLW1hbmFnZWQtdnMtaW5saW5lLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEZvciBpbmZvcm1hdGlvbiBhYm91dCBsaW1pdHMgb24gdGhlIG51bWJlciBvZiBpbmxpbmUgcG9saWNpZXMgdGhhdCB5b3UgY2FuIGVtYmVkIHdpdGggYSByb2xlLCBzZWUgW0xpbWl0YXRpb25zIG9uIElBTSBFbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL0xpbWl0YXRpb25zT25FbnRpdGllcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiA+IElmIGFuIGV4dGVybmFsIHBvbGljeSAoc3VjaCBhcyBgQVdTOjpJQU06OlBvbGljeWAgb3IgYEFXUzo6SUFNOjpNYW5hZ2VkUG9saWN5YCApIGhhcyBhIGBSZWZgIHRvIGEgcm9sZSBhbmQgaWYgYSByZXNvdXJjZSAoc3VjaCBhcyBgQVdTOjpFQ1M6OlNlcnZpY2VgICkgYWxzbyBoYXMgYSBgUmVmYCB0byB0aGUgc2FtZSByb2xlLCBhZGQgYSBgRGVwZW5kc09uYCBhdHRyaWJ1dGUgdG8gdGhlIHJlc291cmNlIHRvIG1ha2UgdGhlIHJlc291cmNlIGRlcGVuZCBvbiB0aGUgZXh0ZXJuYWwgcG9saWN5LiBUaGlzIGRlcGVuZGVuY3kgZW5zdXJlcyB0aGF0IHRoZSByb2xlJ3MgcG9saWN5IGlzIGF2YWlsYWJsZSB0aHJvdWdob3V0IHRoZSByZXNvdXJjZSdzIGxpZmVjeWNsZS4gRm9yIGV4YW1wbGUsIHdoZW4geW91IGRlbGV0ZSBhIHN0YWNrIHdpdGggYW4gYEFXUzo6RUNTOjpTZXJ2aWNlYCByZXNvdXJjZSwgdGhlIGBEZXBlbmRzT25gIGF0dHJpYnV0ZSBlbnN1cmVzIHRoYXQgQVdTIENsb3VkRm9ybWF0aW9uIGRlbGV0ZXMgdGhlIGBBV1M6OkVDUzo6U2VydmljZWAgcmVzb3VyY2UgYmVmb3JlIGRlbGV0aW5nIGl0cyByb2xlJ3MgcG9saWN5LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNjZm4taWFtLXJvbGUtcG9saWNpZXNcbiAgICAgKi9cbiAgICByZWFkb25seSBwb2xpY2llcz86IEFycmF5PENmblJvbGUuUG9saWN5UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogQSBuYW1lIGZvciB0aGUgSUFNIHJvbGUsIHVwIHRvIDY0IGNoYXJhY3RlcnMgaW4gbGVuZ3RoLiBGb3IgdmFsaWQgdmFsdWVzLCBzZWUgdGhlIGBSb2xlTmFtZWAgcGFyYW1ldGVyIGZvciB0aGUgW2BDcmVhdGVSb2xlYF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVSb2xlLmh0bWwpIGFjdGlvbiBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHBlciBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtLiBUaGUgcm9sZSBuYW1lIG11c3QgYmUgdW5pcXVlIHdpdGhpbiB0aGUgYWNjb3VudC4gUm9sZSBuYW1lcyBhcmUgbm90IGRpc3Rpbmd1aXNoZWQgYnkgY2FzZS4gRm9yIGV4YW1wbGUsIHlvdSBjYW5ub3QgY3JlYXRlIHJvbGVzIG5hbWVkIGJvdGggXCJSb2xlMVwiIGFuZCBcInJvbGUxXCIuXG4gICAgICpcbiAgICAgKiBJZiB5b3UgZG9uJ3Qgc3BlY2lmeSBhIG5hbWUsIEFXUyBDbG91ZEZvcm1hdGlvbiBnZW5lcmF0ZXMgYSB1bmlxdWUgcGh5c2ljYWwgSUQgYW5kIHVzZXMgdGhhdCBJRCBmb3IgdGhlIHJvbGUgbmFtZS5cbiAgICAgKlxuICAgICAqIElmIHlvdSBzcGVjaWZ5IGEgbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgYENBUEFCSUxJVFlfTkFNRURfSUFNYCB2YWx1ZSB0byBhY2tub3dsZWRnZSB5b3VyIHRlbXBsYXRlJ3MgY2FwYWJpbGl0aWVzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBY2tub3dsZWRnaW5nIElBTSBSZXNvdXJjZXMgaW4gQVdTIENsb3VkRm9ybWF0aW9uIFRlbXBsYXRlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvdXNpbmctaWFtLXRlbXBsYXRlLmh0bWwjdXNpbmctaWFtLWNhcGFiaWxpdGllcykgLlxuICAgICAqXG4gICAgICogPiBOYW1pbmcgYW4gSUFNIHJlc291cmNlIGNhbiBjYXVzZSBhbiB1bnJlY292ZXJhYmxlIGVycm9yIGlmIHlvdSByZXVzZSB0aGUgc2FtZSB0ZW1wbGF0ZSBpbiBtdWx0aXBsZSBSZWdpb25zLiBUbyBwcmV2ZW50IHRoaXMsIHdlIHJlY29tbWVuZCB1c2luZyBgRm46OkpvaW5gIGFuZCBgQVdTOjpSZWdpb25gIHRvIGNyZWF0ZSBhIFJlZ2lvbi1zcGVjaWZpYyBuYW1lLCBhcyBpbiB0aGUgZm9sbG93aW5nIGV4YW1wbGU6IGB7XCJGbjo6Sm9pblwiOiBbXCJcIiwgW3tcIlJlZlwiOiBcIkFXUzo6UmVnaW9uXCJ9LCB7XCJSZWZcIjogXCJNeVJlc291cmNlTmFtZVwifV1dfWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNjZm4taWFtLXJvbGUtcm9sZW5hbWVcbiAgICAgKi9cbiAgICByZWFkb25seSByb2xlTmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiB0YWdzIHRoYXQgYXJlIGF0dGFjaGVkIHRvIHRoZSByb2xlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0YWdnaW5nLCBzZWUgW1RhZ2dpbmcgSUFNIHJlc291cmNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX3RhZ3MuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNjZm4taWFtLXJvbGUtdGFnc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IHRhZ3M/OiBjZGsuQ2ZuVGFnW107XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2ZuUm9sZVByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5Sb2xlUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuUm9sZVByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignYXNzdW1lUm9sZVBvbGljeURvY3VtZW50JywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignYXNzdW1lUm9sZVBvbGljeURvY3VtZW50JywgY2RrLnZhbGlkYXRlT2JqZWN0KShwcm9wZXJ0aWVzLmFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZGVzY3JpcHRpb24nLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuZGVzY3JpcHRpb24pKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ21hbmFnZWRQb2xpY3lBcm5zJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5tYW5hZ2VkUG9saWN5QXJucykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbWF4U2Vzc2lvbkR1cmF0aW9uJywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLm1heFNlc3Npb25EdXJhdGlvbikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncGF0aCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5wYXRoKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwZXJtaXNzaW9uc0JvdW5kYXJ5JywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnBlcm1pc3Npb25zQm91bmRhcnkpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvbGljaWVzJywgY2RrLmxpc3RWYWxpZGF0b3IoQ2ZuUm9sZV9Qb2xpY3lQcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMucG9saWNpZXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3JvbGVOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnJvbGVOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0YWdzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlQ2ZuVGFnKSkocHJvcGVydGllcy50YWdzKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmblJvbGVQcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpSb2xlYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5Sb2xlUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6Um9sZWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5Sb2xlUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblJvbGVQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQXNzdW1lUm9sZVBvbGljeURvY3VtZW50OiBjZGsub2JqZWN0VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudCksXG4gICAgICAgIERlc2NyaXB0aW9uOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmRlc2NyaXB0aW9uKSxcbiAgICAgICAgTWFuYWdlZFBvbGljeUFybnM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLm1hbmFnZWRQb2xpY3lBcm5zKSxcbiAgICAgICAgTWF4U2Vzc2lvbkR1cmF0aW9uOiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm1heFNlc3Npb25EdXJhdGlvbiksXG4gICAgICAgIFBhdGg6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucGF0aCksXG4gICAgICAgIFBlcm1pc3Npb25zQm91bmRhcnk6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucGVybWlzc2lvbnNCb3VuZGFyeSksXG4gICAgICAgIFBvbGljaWVzOiBjZGsubGlzdE1hcHBlcihjZm5Sb2xlUG9saWN5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnBvbGljaWVzKSxcbiAgICAgICAgUm9sZU5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucm9sZU5hbWUpLFxuICAgICAgICBUYWdzOiBjZGsubGlzdE1hcHBlcihjZGsuY2ZuVGFnVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy50YWdzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuUm9sZVByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuUm9sZVByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5Sb2xlUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdhc3N1bWVSb2xlUG9saWN5RG9jdW1lbnQnLCAnQXNzdW1lUm9sZVBvbGljeURvY3VtZW50JywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBbnkocHJvcGVydGllcy5Bc3N1bWVSb2xlUG9saWN5RG9jdW1lbnQpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Rlc2NyaXB0aW9uJywgJ0Rlc2NyaXB0aW9uJywgcHJvcGVydGllcy5EZXNjcmlwdGlvbiAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5EZXNjcmlwdGlvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbWFuYWdlZFBvbGljeUFybnMnLCAnTWFuYWdlZFBvbGljeUFybnMnLCBwcm9wZXJ0aWVzLk1hbmFnZWRQb2xpY3lBcm5zICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuTWFuYWdlZFBvbGljeUFybnMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ21heFNlc3Npb25EdXJhdGlvbicsICdNYXhTZXNzaW9uRHVyYXRpb24nLCBwcm9wZXJ0aWVzLk1heFNlc3Npb25EdXJhdGlvbiAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5NYXhTZXNzaW9uRHVyYXRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BhdGgnLCAnUGF0aCcsIHByb3BlcnRpZXMuUGF0aCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5QYXRoKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwZXJtaXNzaW9uc0JvdW5kYXJ5JywgJ1Blcm1pc3Npb25zQm91bmRhcnknLCBwcm9wZXJ0aWVzLlBlcm1pc3Npb25zQm91bmRhcnkgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUGVybWlzc2lvbnNCb3VuZGFyeSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncG9saWNpZXMnLCAnUG9saWNpZXMnLCBwcm9wZXJ0aWVzLlBvbGljaWVzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmblJvbGVQb2xpY3lQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5Qb2xpY2llcykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncm9sZU5hbWUnLCAnUm9sZU5hbWUnLCBwcm9wZXJ0aWVzLlJvbGVOYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlJvbGVOYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0YWdzJywgJ1RhZ3MnLCBwcm9wZXJ0aWVzLlRhZ3MgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRDZm5UYWcpKHByb3BlcnRpZXMuVGFncykgOiB1bmRlZmluZWQgYXMgYW55KTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBBIENsb3VkRm9ybWF0aW9uIGBBV1M6OklBTTo6Um9sZWBcbiAqXG4gKiBDcmVhdGVzIGEgbmV3IHJvbGUgZm9yIHlvdXIgQVdTIGFjY291bnQgLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCByb2xlcywgc2VlIFtJQU0gcm9sZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Xb3JraW5nV2l0aFJvbGVzLmh0bWwpIC4gRm9yIGluZm9ybWF0aW9uIGFib3V0IHF1b3RhcyBmb3Igcm9sZSBuYW1lcyBhbmQgdGhlIG51bWJlciBvZiByb2xlcyB5b3UgY2FuIGNyZWF0ZSwgc2VlIFtJQU0gYW5kIEFXUyBTVFMgcXVvdGFzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX2lhbS1xdW90YXMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6SUFNOjpSb2xlXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuUm9sZSBleHRlbmRzIGNkay5DZm5SZXNvdXJjZSBpbXBsZW1lbnRzIGNkay5JSW5zcGVjdGFibGUge1xuICAgIC8qKlxuICAgICAqIFRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIG5hbWUgZm9yIHRoaXMgcmVzb3VyY2UgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBDRk5fUkVTT1VSQ0VfVFlQRV9OQU1FID0gXCJBV1M6OklBTTo6Um9sZVwiO1xuXG4gICAgLyoqXG4gICAgICogQSBmYWN0b3J5IG1ldGhvZCB0aGF0IGNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmcm9tIGFuIG9iamVjdFxuICAgICAqIGNvbnRhaW5pbmcgdGhlIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgdGhpcyByZXNvdXJjZS5cbiAgICAgKiBVc2VkIGluIHRoZSBAYXdzLWNkay9jbG91ZGZvcm1hdGlvbi1pbmNsdWRlIG1vZHVsZS5cbiAgICAgKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgX2Zyb21DbG91ZEZvcm1hdGlvbihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcmVzb3VyY2VBdHRyaWJ1dGVzOiBhbnksIG9wdGlvbnM6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25PcHRpb25zKTogQ2ZuUm9sZSB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuUm9sZVByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5Sb2xlKHNjb3BlLCBpZCwgcHJvcHNSZXN1bHQudmFsdWUpO1xuICAgICAgICBmb3IgKGNvbnN0IFtwcm9wS2V5LCBwcm9wVmFsXSBvZiBPYmplY3QuZW50cmllcyhwcm9wc1Jlc3VsdC5leHRyYVByb3BlcnRpZXMpKSAge1xuICAgICAgICAgICAgcmV0LmFkZFByb3BlcnR5T3ZlcnJpZGUocHJvcEtleSwgcHJvcFZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5wYXJzZXIuaGFuZGxlQXR0cmlidXRlcyhyZXQsIHJlc291cmNlQXR0cmlidXRlcywgaWQpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIGZvciB0aGUgcm9sZS4gRm9yIGV4YW1wbGU6XG4gICAgICpcbiAgICAgKiBge1wiRm46OkdldEF0dFwiIDogW1wiTXlSb2xlXCIsIFwiQXJuXCJdIH1gXG4gICAgICpcbiAgICAgKiBUaGlzIHdpbGwgcmV0dXJuIGEgdmFsdWUgc3VjaCBhcyBgYXJuOmF3czppYW06OjEyMzQ1Njc4OTA6cm9sZS9NeVJvbGUtQUpKSERTS1NERmAgLlxuICAgICAqIEBjbG91ZGZvcm1hdGlvbkF0dHJpYnV0ZSBBcm5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgYXR0ckFybjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgc3RhYmxlIGFuZCB1bmlxdWUgc3RyaW5nIGlkZW50aWZ5aW5nIHRoZSByb2xlLiBGb3IgZXhhbXBsZSwgYEFJREFKUUFCTFpTNEEzUURVNTc2UWAgLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgSURzLCBzZWUgW0lBTSBJZGVudGlmaWVyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9pZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICogQGNsb3VkZm9ybWF0aW9uQXR0cmlidXRlIFJvbGVJZFxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBhdHRyUm9sZUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdHJ1c3QgcG9saWN5IHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgcm9sZS4gVHJ1c3QgcG9saWNpZXMgZGVmaW5lIHdoaWNoIGVudGl0aWVzIGNhbiBhc3N1bWUgdGhlIHJvbGUuIFlvdSBjYW4gYXNzb2NpYXRlIG9ubHkgb25lIHRydXN0IHBvbGljeSB3aXRoIGEgcm9sZS4gRm9yIGFuIGV4YW1wbGUgb2YgYSBwb2xpY3kgdGhhdCBjYW4gYmUgdXNlZCB0byBhc3N1bWUgYSByb2xlLCBzZWUgW1RlbXBsYXRlIEV4YW1wbGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNhd3MtcmVzb3VyY2UtaWFtLXJvbGUtLWV4YW1wbGVzKSAuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBlbGVtZW50cyB0aGF0IHlvdSBjYW4gdXNlIGluIGFuIElBTSBwb2xpY3ksIHNlZSBbSUFNIFBvbGljeSBFbGVtZW50cyBSZWZlcmVuY2VdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNjZm4taWFtLXJvbGUtYXNzdW1lcm9sZXBvbGljeWRvY3VtZW50XG4gICAgICovXG4gICAgcHVibGljIGFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudDogYW55IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogQSBkZXNjcmlwdGlvbiBvZiB0aGUgcm9sZSB0aGF0IHlvdSBwcm92aWRlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNjZm4taWFtLXJvbGUtZGVzY3JpcHRpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgZGVzY3JpcHRpb246IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiBBbWF6b24gUmVzb3VyY2UgTmFtZXMgKEFSTnMpIG9mIHRoZSBJQU0gbWFuYWdlZCBwb2xpY2llcyB0aGF0IHlvdSB3YW50IHRvIGF0dGFjaCB0byB0aGUgcm9sZS5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IEFSTnMsIHNlZSBbQW1hem9uIFJlc291cmNlIE5hbWVzIChBUk5zKSBhbmQgQVdTIFNlcnZpY2UgTmFtZXNwYWNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dlbmVyYWwvbGF0ZXN0L2dyL2F3cy1hcm5zLWFuZC1uYW1lc3BhY2VzLmh0bWwpIGluIHRoZSAqQVdTIEdlbmVyYWwgUmVmZXJlbmNlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcm9sZS5odG1sI2Nmbi1pYW0tcm9sZS1tYW5hZ2Vwb2xpY3lhcm5zXG4gICAgICovXG4gICAgcHVibGljIG1hbmFnZWRQb2xpY3lBcm5zOiBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIHNlc3Npb24gZHVyYXRpb24gKGluIHNlY29uZHMpIHRoYXQgeW91IHdhbnQgdG8gc2V0IGZvciB0aGUgc3BlY2lmaWVkIHJvbGUuIElmIHlvdSBkbyBub3Qgc3BlY2lmeSBhIHZhbHVlIGZvciB0aGlzIHNldHRpbmcsIHRoZSBkZWZhdWx0IG1heGltdW0gb2Ygb25lIGhvdXIgaXMgYXBwbGllZC4gVGhpcyBzZXR0aW5nIGNhbiBoYXZlIGEgdmFsdWUgZnJvbSAxIGhvdXIgdG8gMTIgaG91cnMuXG4gICAgICpcbiAgICAgKiBBbnlvbmUgd2hvIGFzc3VtZXMgdGhlIHJvbGUgZnJvbSB0aGUgb3IgQVBJIGNhbiB1c2UgdGhlIGBEdXJhdGlvblNlY29uZHNgIEFQSSBwYXJhbWV0ZXIgb3IgdGhlIGBkdXJhdGlvbi1zZWNvbmRzYCBDTEkgcGFyYW1ldGVyIHRvIHJlcXVlc3QgYSBsb25nZXIgc2Vzc2lvbi4gVGhlIGBNYXhTZXNzaW9uRHVyYXRpb25gIHNldHRpbmcgZGV0ZXJtaW5lcyB0aGUgbWF4aW11bSBkdXJhdGlvbiB0aGF0IGNhbiBiZSByZXF1ZXN0ZWQgdXNpbmcgdGhlIGBEdXJhdGlvblNlY29uZHNgIHBhcmFtZXRlci4gSWYgdXNlcnMgZG9uJ3Qgc3BlY2lmeSBhIHZhbHVlIGZvciB0aGUgYER1cmF0aW9uU2Vjb25kc2AgcGFyYW1ldGVyLCB0aGVpciBzZWN1cml0eSBjcmVkZW50aWFscyBhcmUgdmFsaWQgZm9yIG9uZSBob3VyIGJ5IGRlZmF1bHQuIFRoaXMgYXBwbGllcyB3aGVuIHlvdSB1c2UgdGhlIGBBc3N1bWVSb2xlKmAgQVBJIG9wZXJhdGlvbnMgb3IgdGhlIGBhc3N1bWUtcm9sZSpgIENMSSBvcGVyYXRpb25zIGJ1dCBkb2VzIG5vdCBhcHBseSB3aGVuIHlvdSB1c2UgdGhvc2Ugb3BlcmF0aW9ucyB0byBjcmVhdGUgYSBjb25zb2xlIFVSTC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbVXNpbmcgSUFNIHJvbGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvaWRfcm9sZXNfdXNlLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWwjY2ZuLWlhbS1yb2xlLW1heHNlc3Npb25kdXJhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBtYXhTZXNzaW9uRHVyYXRpb246IG51bWJlciB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwYXRoIHRvIHRoZSByb2xlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gSWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiBlaXRoZXIgYSBmb3J3YXJkIHNsYXNoICgvKSBieSBpdHNlbGYgb3IgYSBzdHJpbmcgdGhhdCBtdXN0IGJlZ2luIGFuZCBlbmQgd2l0aCBmb3J3YXJkIHNsYXNoZXMuIEluIGFkZGl0aW9uLCBpdCBjYW4gY29udGFpbiBhbnkgQVNDSUkgY2hhcmFjdGVyIGZyb20gdGhlICEgKCBgXFwgdTAwMjFgICkgdGhyb3VnaCB0aGUgREVMIGNoYXJhY3RlciAoIGBcXCB1MDA3RmAgKSwgaW5jbHVkaW5nIG1vc3QgcHVuY3R1YXRpb24gY2hhcmFjdGVycywgZGlnaXRzLCBhbmQgdXBwZXIgYW5kIGxvd2VyY2FzZWQgbGV0dGVycy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWwjY2ZuLWlhbS1yb2xlLXBhdGhcbiAgICAgKi9cbiAgICBwdWJsaWMgcGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIEFSTiBvZiB0aGUgcG9saWN5IHVzZWQgdG8gc2V0IHRoZSBwZXJtaXNzaW9ucyBib3VuZGFyeSBmb3IgdGhlIHJvbGUuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwZXJtaXNzaW9ucyBib3VuZGFyaWVzLCBzZWUgW1Blcm1pc3Npb25zIGJvdW5kYXJpZXMgZm9yIElBTSBpZGVudGl0aWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvYWNjZXNzX3BvbGljaWVzX2JvdW5kYXJpZXMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNjZm4taWFtLXJvbGUtcGVybWlzc2lvbnNib3VuZGFyeVxuICAgICAqL1xuICAgIHB1YmxpYyBwZXJtaXNzaW9uc0JvdW5kYXJ5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIG9yIHVwZGF0ZXMgYW4gaW5saW5lIHBvbGljeSBkb2N1bWVudCB0aGF0IGlzIGVtYmVkZGVkIGluIHRoZSBzcGVjaWZpZWQgSUFNIHJvbGUuXG4gICAgICpcbiAgICAgKiBXaGVuIHlvdSBlbWJlZCBhbiBpbmxpbmUgcG9saWN5IGluIGEgcm9sZSwgdGhlIGlubGluZSBwb2xpY3kgaXMgdXNlZCBhcyBwYXJ0IG9mIHRoZSByb2xlJ3MgYWNjZXNzIChwZXJtaXNzaW9ucykgcG9saWN5LiBUaGUgcm9sZSdzIHRydXN0IHBvbGljeSBpcyBjcmVhdGVkIGF0IHRoZSBzYW1lIHRpbWUgYXMgdGhlIHJvbGUuIFlvdSBjYW4gdXBkYXRlIGEgcm9sZSdzIHRydXN0IHBvbGljeSBsYXRlci4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgSUFNIHJvbGVzLCBnbyB0byBbVXNpbmcgUm9sZXMgdG8gRGVsZWdhdGUgUGVybWlzc2lvbnMgYW5kIEZlZGVyYXRlIElkZW50aXRpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yb2xlcy10b3BsZXZlbC5odG1sKSAuXG4gICAgICpcbiAgICAgKiBBIHJvbGUgY2FuIGFsc28gaGF2ZSBhbiBhdHRhY2hlZCBtYW5hZ2VkIHBvbGljeS4gRm9yIGluZm9ybWF0aW9uIGFib3V0IHBvbGljaWVzLCBzZWUgW01hbmFnZWQgUG9saWNpZXMgYW5kIElubGluZSBQb2xpY2llc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3BvbGljaWVzLW1hbmFnZWQtdnMtaW5saW5lLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEZvciBpbmZvcm1hdGlvbiBhYm91dCBsaW1pdHMgb24gdGhlIG51bWJlciBvZiBpbmxpbmUgcG9saWNpZXMgdGhhdCB5b3UgY2FuIGVtYmVkIHdpdGggYSByb2xlLCBzZWUgW0xpbWl0YXRpb25zIG9uIElBTSBFbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL0xpbWl0YXRpb25zT25FbnRpdGllcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiA+IElmIGFuIGV4dGVybmFsIHBvbGljeSAoc3VjaCBhcyBgQVdTOjpJQU06OlBvbGljeWAgb3IgYEFXUzo6SUFNOjpNYW5hZ2VkUG9saWN5YCApIGhhcyBhIGBSZWZgIHRvIGEgcm9sZSBhbmQgaWYgYSByZXNvdXJjZSAoc3VjaCBhcyBgQVdTOjpFQ1M6OlNlcnZpY2VgICkgYWxzbyBoYXMgYSBgUmVmYCB0byB0aGUgc2FtZSByb2xlLCBhZGQgYSBgRGVwZW5kc09uYCBhdHRyaWJ1dGUgdG8gdGhlIHJlc291cmNlIHRvIG1ha2UgdGhlIHJlc291cmNlIGRlcGVuZCBvbiB0aGUgZXh0ZXJuYWwgcG9saWN5LiBUaGlzIGRlcGVuZGVuY3kgZW5zdXJlcyB0aGF0IHRoZSByb2xlJ3MgcG9saWN5IGlzIGF2YWlsYWJsZSB0aHJvdWdob3V0IHRoZSByZXNvdXJjZSdzIGxpZmVjeWNsZS4gRm9yIGV4YW1wbGUsIHdoZW4geW91IGRlbGV0ZSBhIHN0YWNrIHdpdGggYW4gYEFXUzo6RUNTOjpTZXJ2aWNlYCByZXNvdXJjZSwgdGhlIGBEZXBlbmRzT25gIGF0dHJpYnV0ZSBlbnN1cmVzIHRoYXQgQVdTIENsb3VkRm9ybWF0aW9uIGRlbGV0ZXMgdGhlIGBBV1M6OkVDUzo6U2VydmljZWAgcmVzb3VyY2UgYmVmb3JlIGRlbGV0aW5nIGl0cyByb2xlJ3MgcG9saWN5LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNjZm4taWFtLXJvbGUtcG9saWNpZXNcbiAgICAgKi9cbiAgICBwdWJsaWMgcG9saWNpZXM6IEFycmF5PENmblJvbGUuUG9saWN5UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQSBuYW1lIGZvciB0aGUgSUFNIHJvbGUsIHVwIHRvIDY0IGNoYXJhY3RlcnMgaW4gbGVuZ3RoLiBGb3IgdmFsaWQgdmFsdWVzLCBzZWUgdGhlIGBSb2xlTmFtZWAgcGFyYW1ldGVyIGZvciB0aGUgW2BDcmVhdGVSb2xlYF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVSb2xlLmh0bWwpIGFjdGlvbiBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHBlciBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtLiBUaGUgcm9sZSBuYW1lIG11c3QgYmUgdW5pcXVlIHdpdGhpbiB0aGUgYWNjb3VudC4gUm9sZSBuYW1lcyBhcmUgbm90IGRpc3Rpbmd1aXNoZWQgYnkgY2FzZS4gRm9yIGV4YW1wbGUsIHlvdSBjYW5ub3QgY3JlYXRlIHJvbGVzIG5hbWVkIGJvdGggXCJSb2xlMVwiIGFuZCBcInJvbGUxXCIuXG4gICAgICpcbiAgICAgKiBJZiB5b3UgZG9uJ3Qgc3BlY2lmeSBhIG5hbWUsIEFXUyBDbG91ZEZvcm1hdGlvbiBnZW5lcmF0ZXMgYSB1bmlxdWUgcGh5c2ljYWwgSUQgYW5kIHVzZXMgdGhhdCBJRCBmb3IgdGhlIHJvbGUgbmFtZS5cbiAgICAgKlxuICAgICAqIElmIHlvdSBzcGVjaWZ5IGEgbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgYENBUEFCSUxJVFlfTkFNRURfSUFNYCB2YWx1ZSB0byBhY2tub3dsZWRnZSB5b3VyIHRlbXBsYXRlJ3MgY2FwYWJpbGl0aWVzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBY2tub3dsZWRnaW5nIElBTSBSZXNvdXJjZXMgaW4gQVdTIENsb3VkRm9ybWF0aW9uIFRlbXBsYXRlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvdXNpbmctaWFtLXRlbXBsYXRlLmh0bWwjdXNpbmctaWFtLWNhcGFiaWxpdGllcykgLlxuICAgICAqXG4gICAgICogPiBOYW1pbmcgYW4gSUFNIHJlc291cmNlIGNhbiBjYXVzZSBhbiB1bnJlY292ZXJhYmxlIGVycm9yIGlmIHlvdSByZXVzZSB0aGUgc2FtZSB0ZW1wbGF0ZSBpbiBtdWx0aXBsZSBSZWdpb25zLiBUbyBwcmV2ZW50IHRoaXMsIHdlIHJlY29tbWVuZCB1c2luZyBgRm46OkpvaW5gIGFuZCBgQVdTOjpSZWdpb25gIHRvIGNyZWF0ZSBhIFJlZ2lvbi1zcGVjaWZpYyBuYW1lLCBhcyBpbiB0aGUgZm9sbG93aW5nIGV4YW1wbGU6IGB7XCJGbjo6Sm9pblwiOiBbXCJcIiwgW3tcIlJlZlwiOiBcIkFXUzo6UmVnaW9uXCJ9LCB7XCJSZWZcIjogXCJNeVJlc291cmNlTmFtZVwifV1dfWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNjZm4taWFtLXJvbGUtcm9sZW5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgcm9sZU5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiB0YWdzIHRoYXQgYXJlIGF0dGFjaGVkIHRvIHRoZSByb2xlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0YWdnaW5nLCBzZWUgW1RhZ2dpbmcgSUFNIHJlc291cmNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX3RhZ3MuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNjZm4taWFtLXJvbGUtdGFnc1xuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB0YWdzOiBjZGsuVGFnTWFuYWdlcjtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpJQU06OlJvbGVgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmblJvbGVQcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuUm9sZS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ2Fzc3VtZVJvbGVQb2xpY3lEb2N1bWVudCcsIHRoaXMpO1xuICAgICAgICB0aGlzLmF0dHJBcm4gPSBjZGsuVG9rZW4uYXNTdHJpbmcodGhpcy5nZXRBdHQoJ0FybicpKTtcbiAgICAgICAgdGhpcy5hdHRyUm9sZUlkID0gY2RrLlRva2VuLmFzU3RyaW5nKHRoaXMuZ2V0QXR0KCdSb2xlSWQnKSk7XG5cbiAgICAgICAgdGhpcy5hc3N1bWVSb2xlUG9saWN5RG9jdW1lbnQgPSBwcm9wcy5hc3N1bWVSb2xlUG9saWN5RG9jdW1lbnQ7XG4gICAgICAgIHRoaXMuZGVzY3JpcHRpb24gPSBwcm9wcy5kZXNjcmlwdGlvbjtcbiAgICAgICAgdGhpcy5tYW5hZ2VkUG9saWN5QXJucyA9IHByb3BzLm1hbmFnZWRQb2xpY3lBcm5zO1xuICAgICAgICB0aGlzLm1heFNlc3Npb25EdXJhdGlvbiA9IHByb3BzLm1heFNlc3Npb25EdXJhdGlvbjtcbiAgICAgICAgdGhpcy5wYXRoID0gcHJvcHMucGF0aDtcbiAgICAgICAgdGhpcy5wZXJtaXNzaW9uc0JvdW5kYXJ5ID0gcHJvcHMucGVybWlzc2lvbnNCb3VuZGFyeTtcbiAgICAgICAgdGhpcy5wb2xpY2llcyA9IHByb3BzLnBvbGljaWVzO1xuICAgICAgICB0aGlzLnJvbGVOYW1lID0gcHJvcHMucm9sZU5hbWU7XG4gICAgICAgIHRoaXMudGFncyA9IG5ldyBjZGsuVGFnTWFuYWdlcihjZGsuVGFnVHlwZS5TVEFOREFSRCwgXCJBV1M6OklBTTo6Um9sZVwiLCBwcm9wcy50YWdzLCB7IHRhZ1Byb3BlcnR5TmFtZTogJ3RhZ3MnIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuUm9sZS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYXNzdW1lUm9sZVBvbGljeURvY3VtZW50OiB0aGlzLmFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudCxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiB0aGlzLmRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgbWFuYWdlZFBvbGljeUFybnM6IHRoaXMubWFuYWdlZFBvbGljeUFybnMsXG4gICAgICAgICAgICBtYXhTZXNzaW9uRHVyYXRpb246IHRoaXMubWF4U2Vzc2lvbkR1cmF0aW9uLFxuICAgICAgICAgICAgcGF0aDogdGhpcy5wYXRoLFxuICAgICAgICAgICAgcGVybWlzc2lvbnNCb3VuZGFyeTogdGhpcy5wZXJtaXNzaW9uc0JvdW5kYXJ5LFxuICAgICAgICAgICAgcG9saWNpZXM6IHRoaXMucG9saWNpZXMsXG4gICAgICAgICAgICByb2xlTmFtZTogdGhpcy5yb2xlTmFtZSxcbiAgICAgICAgICAgIHRhZ3M6IHRoaXMudGFncy5yZW5kZXJUYWdzKCksXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuUm9sZVByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblJvbGUge1xuICAgIC8qKlxuICAgICAqIENvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGFuIGF0dGFjaGVkIHBvbGljeS5cbiAgICAgKlxuICAgICAqIEFuIGF0dGFjaGVkIHBvbGljeSBpcyBhIG1hbmFnZWQgcG9saWN5IHRoYXQgaGFzIGJlZW4gYXR0YWNoZWQgdG8gYSB1c2VyLCBncm91cCwgb3Igcm9sZS5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IG1hbmFnZWQgcG9saWNpZXMsIHJlZmVyIHRvIFtNYW5hZ2VkIFBvbGljaWVzIGFuZCBJbmxpbmUgUG9saWNpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9wb2xpY2llcy1tYW5hZ2VkLXZzLWlubGluZS5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tcG9saWN5Lmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIFBvbGljeVByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwb2xpY3kgZG9jdW1lbnQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXBvbGljeS5odG1sI2Nmbi1pYW0tcG9saWNpZXMtcG9saWN5ZG9jdW1lbnRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHBvbGljeURvY3VtZW50OiBhbnkgfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZnJpZW5kbHkgbmFtZSAobm90IEFSTikgaWRlbnRpZnlpbmcgdGhlIHBvbGljeS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tcG9saWN5Lmh0bWwjY2ZuLWlhbS1wb2xpY2llcy1wb2xpY3luYW1lXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBwb2xpY3lOYW1lOiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYFBvbGljeVByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBQb2xpY3lQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5Sb2xlX1BvbGljeVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5RG9jdW1lbnQnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMucG9saWN5RG9jdW1lbnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvbGljeURvY3VtZW50JywgY2RrLnZhbGlkYXRlT2JqZWN0KShwcm9wZXJ0aWVzLnBvbGljeURvY3VtZW50KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb2xpY3lOYW1lJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnBvbGljeU5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvbGljeU5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucG9saWN5TmFtZSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJQb2xpY3lQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpSb2xlLlBvbGljeWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgUG9saWN5UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6Um9sZS5Qb2xpY3lgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuUm9sZVBvbGljeVByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5Sb2xlX1BvbGljeVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBQb2xpY3lEb2N1bWVudDogY2RrLm9iamVjdFRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wb2xpY3lEb2N1bWVudCksXG4gICAgICAgIFBvbGljeU5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucG9saWN5TmFtZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblJvbGVQb2xpY3lQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblJvbGUuUG9saWN5UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuUm9sZS5Qb2xpY3lQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BvbGljeURvY3VtZW50JywgJ1BvbGljeURvY3VtZW50JywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBbnkocHJvcGVydGllcy5Qb2xpY3lEb2N1bWVudCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncG9saWN5TmFtZScsICdQb2xpY3lOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Qb2xpY3lOYW1lKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuU0FNTFByb3ZpZGVyYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2FtbHByb3ZpZGVyLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5TQU1MUHJvdmlkZXJQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBBbiBYTUwgZG9jdW1lbnQgZ2VuZXJhdGVkIGJ5IGFuIGlkZW50aXR5IHByb3ZpZGVyIChJZFApIHRoYXQgc3VwcG9ydHMgU0FNTCAyLjAuIFRoZSBkb2N1bWVudCBpbmNsdWRlcyB0aGUgaXNzdWVyJ3MgbmFtZSwgZXhwaXJhdGlvbiBpbmZvcm1hdGlvbiwgYW5kIGtleXMgdGhhdCBjYW4gYmUgdXNlZCB0byB2YWxpZGF0ZSB0aGUgU0FNTCBhdXRoZW50aWNhdGlvbiByZXNwb25zZSAoYXNzZXJ0aW9ucykgdGhhdCBhcmUgcmVjZWl2ZWQgZnJvbSB0aGUgSWRQLiBZb3UgbXVzdCBnZW5lcmF0ZSB0aGUgbWV0YWRhdGEgZG9jdW1lbnQgdXNpbmcgdGhlIGlkZW50aXR5IG1hbmFnZW1lbnQgc29mdHdhcmUgdGhhdCBpcyB1c2VkIGFzIHlvdXIgb3JnYW5pemF0aW9uJ3MgSWRQLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQWJvdXQgU0FNTCAyLjAtYmFzZWQgZmVkZXJhdGlvbl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX3JvbGVzX3Byb3ZpZGVyc19zYW1sLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2FtbHByb3ZpZGVyLmh0bWwjY2ZuLWlhbS1zYW1scHJvdmlkZXItc2FtbG1ldGFkYXRhZG9jdW1lbnRcbiAgICAgKi9cbiAgICByZWFkb25seSBzYW1sTWV0YWRhdGFEb2N1bWVudDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIHRvIGNyZWF0ZS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2FtbHByb3ZpZGVyLmh0bWwjY2ZuLWlhbS1zYW1scHJvdmlkZXItbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IG5hbWU/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgdGFncyB0aGF0IHlvdSB3YW50IHRvIGF0dGFjaCB0byB0aGUgbmV3IElBTSBTQU1MIHByb3ZpZGVyLiBFYWNoIHRhZyBjb25zaXN0cyBvZiBhIGtleSBuYW1lIGFuZCBhbiBhc3NvY2lhdGVkIHZhbHVlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0YWdnaW5nLCBzZWUgW1RhZ2dpbmcgSUFNIHJlc291cmNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX3RhZ3MuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogPiBJZiBhbnkgb25lIG9mIHRoZSB0YWdzIGlzIGludmFsaWQgb3IgaWYgeW91IGV4Y2VlZCB0aGUgYWxsb3dlZCBtYXhpbXVtIG51bWJlciBvZiB0YWdzLCB0aGVuIHRoZSBlbnRpcmUgcmVxdWVzdCBmYWlscyBhbmQgdGhlIHJlc291cmNlIGlzIG5vdCBjcmVhdGVkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNhbWxwcm92aWRlci5odG1sI2Nmbi1pYW0tc2FtbHByb3ZpZGVyLXRhZ3NcbiAgICAgKi9cbiAgICByZWFkb25seSB0YWdzPzogY2RrLkNmblRhZ1tdO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmblNBTUxQcm92aWRlclByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5TQU1MUHJvdmlkZXJQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5TQU1MUHJvdmlkZXJQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ25hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc2FtbE1ldGFkYXRhRG9jdW1lbnQnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuc2FtbE1ldGFkYXRhRG9jdW1lbnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3NhbWxNZXRhZGF0YURvY3VtZW50JywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnNhbWxNZXRhZGF0YURvY3VtZW50KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0YWdzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlQ2ZuVGFnKSkocHJvcGVydGllcy50YWdzKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmblNBTUxQcm92aWRlclByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlNBTUxQcm92aWRlcmAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuU0FNTFByb3ZpZGVyUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6U0FNTFByb3ZpZGVyYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblNBTUxQcm92aWRlclByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5TQU1MUHJvdmlkZXJQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgU2FtbE1ldGFkYXRhRG9jdW1lbnQ6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuc2FtbE1ldGFkYXRhRG9jdW1lbnQpLFxuICAgICAgICBOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm5hbWUpLFxuICAgICAgICBUYWdzOiBjZGsubGlzdE1hcHBlcihjZGsuY2ZuVGFnVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy50YWdzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuU0FNTFByb3ZpZGVyUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5TQU1MUHJvdmlkZXJQcm9wcz4ge1xuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuU0FNTFByb3ZpZGVyUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzYW1sTWV0YWRhdGFEb2N1bWVudCcsICdTYW1sTWV0YWRhdGFEb2N1bWVudCcsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuU2FtbE1ldGFkYXRhRG9jdW1lbnQpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ25hbWUnLCAnTmFtZScsIHByb3BlcnRpZXMuTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5OYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0YWdzJywgJ1RhZ3MnLCBwcm9wZXJ0aWVzLlRhZ3MgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRDZm5UYWcpKHByb3BlcnRpZXMuVGFncykgOiB1bmRlZmluZWQgYXMgYW55KTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBBIENsb3VkRm9ybWF0aW9uIGBBV1M6OklBTTo6U0FNTFByb3ZpZGVyYFxuICpcbiAqIENyZWF0ZXMgYW4gSUFNIHJlc291cmNlIHRoYXQgZGVzY3JpYmVzIGFuIGlkZW50aXR5IHByb3ZpZGVyIChJZFApIHRoYXQgc3VwcG9ydHMgU0FNTCAyLjAuXG4gKlxuICogVGhlIFNBTUwgcHJvdmlkZXIgcmVzb3VyY2UgdGhhdCB5b3UgY3JlYXRlIHdpdGggdGhpcyBvcGVyYXRpb24gY2FuIGJlIHVzZWQgYXMgYSBwcmluY2lwYWwgaW4gYW4gSUFNIHJvbGUncyB0cnVzdCBwb2xpY3kuIFN1Y2ggYSBwb2xpY3kgY2FuIGVuYWJsZSBmZWRlcmF0ZWQgdXNlcnMgd2hvIHNpZ24gaW4gdXNpbmcgdGhlIFNBTUwgSWRQIHRvIGFzc3VtZSB0aGUgcm9sZS4gWW91IGNhbiBjcmVhdGUgYW4gSUFNIHJvbGUgdGhhdCBzdXBwb3J0cyBXZWItYmFzZWQgc2luZ2xlIHNpZ24tb24gKFNTTykgdG8gdGhlIEFXUyBNYW5hZ2VtZW50IENvbnNvbGUgb3Igb25lIHRoYXQgc3VwcG9ydHMgQVBJIGFjY2VzcyB0byBBV1MgLlxuICpcbiAqIFdoZW4geW91IGNyZWF0ZSB0aGUgU0FNTCBwcm92aWRlciByZXNvdXJjZSwgeW91IHVwbG9hZCBhIFNBTUwgbWV0YWRhdGEgZG9jdW1lbnQgdGhhdCB5b3UgZ2V0IGZyb20geW91ciBJZFAuIFRoYXQgZG9jdW1lbnQgaW5jbHVkZXMgdGhlIGlzc3VlcidzIG5hbWUsIGV4cGlyYXRpb24gaW5mb3JtYXRpb24sIGFuZCBrZXlzIHRoYXQgY2FuIGJlIHVzZWQgdG8gdmFsaWRhdGUgdGhlIFNBTUwgYXV0aGVudGljYXRpb24gcmVzcG9uc2UgKGFzc2VydGlvbnMpIHRoYXQgdGhlIElkUCBzZW5kcy4gWW91IG11c3QgZ2VuZXJhdGUgdGhlIG1ldGFkYXRhIGRvY3VtZW50IHVzaW5nIHRoZSBpZGVudGl0eSBtYW5hZ2VtZW50IHNvZnR3YXJlIHRoYXQgaXMgdXNlZCBhcyB5b3VyIG9yZ2FuaXphdGlvbidzIElkUC5cbiAqXG4gKiA+IFRoaXMgb3BlcmF0aW9uIHJlcXVpcmVzIFtTaWduYXR1cmUgVmVyc2lvbiA0XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2VuZXJhbC9sYXRlc3QvZ3Ivc2lnbmF0dXJlLXZlcnNpb24tNC5odG1sKSAuXG4gKlxuICogRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbRW5hYmxpbmcgU0FNTCAyLjAgZmVkZXJhdGVkIHVzZXJzIHRvIGFjY2VzcyB0aGUgQVdTIE1hbmFnZW1lbnQgQ29uc29sZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX3JvbGVzX3Byb3ZpZGVyc19lbmFibGUtY29uc29sZS1zYW1sLmh0bWwpIGFuZCBbQWJvdXQgU0FNTCAyLjAtYmFzZWQgZmVkZXJhdGlvbl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX3JvbGVzX3Byb3ZpZGVyc19zYW1sLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAqXG4gKiBAY2xvdWRmb3JtYXRpb25SZXNvdXJjZSBBV1M6OklBTTo6U0FNTFByb3ZpZGVyXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNhbWxwcm92aWRlci5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5TQU1MUHJvdmlkZXIgZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpJQU06OlNBTUxQcm92aWRlclwiO1xuXG4gICAgLyoqXG4gICAgICogQSBmYWN0b3J5IG1ldGhvZCB0aGF0IGNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmcm9tIGFuIG9iamVjdFxuICAgICAqIGNvbnRhaW5pbmcgdGhlIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgdGhpcyByZXNvdXJjZS5cbiAgICAgKiBVc2VkIGluIHRoZSBAYXdzLWNkay9jbG91ZGZvcm1hdGlvbi1pbmNsdWRlIG1vZHVsZS5cbiAgICAgKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgX2Zyb21DbG91ZEZvcm1hdGlvbihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcmVzb3VyY2VBdHRyaWJ1dGVzOiBhbnksIG9wdGlvbnM6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25PcHRpb25zKTogQ2ZuU0FNTFByb3ZpZGVyIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5TQU1MUHJvdmlkZXJQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuU0FNTFByb3ZpZGVyKHNjb3BlLCBpZCwgcHJvcHNSZXN1bHQudmFsdWUpO1xuICAgICAgICBmb3IgKGNvbnN0IFtwcm9wS2V5LCBwcm9wVmFsXSBvZiBPYmplY3QuZW50cmllcyhwcm9wc1Jlc3VsdC5leHRyYVByb3BlcnRpZXMpKSAge1xuICAgICAgICAgICAgcmV0LmFkZFByb3BlcnR5T3ZlcnJpZGUocHJvcEtleSwgcHJvcFZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5wYXJzZXIuaGFuZGxlQXR0cmlidXRlcyhyZXQsIHJlc291cmNlQXR0cmlidXRlcywgaWQpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIGZvciB0aGUgc3BlY2lmaWVkIGBBV1M6OklBTTo6U0FNTFByb3ZpZGVyYCByZXNvdXJjZS5cbiAgICAgKiBAY2xvdWRmb3JtYXRpb25BdHRyaWJ1dGUgQXJuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJBcm46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEFuIFhNTCBkb2N1bWVudCBnZW5lcmF0ZWQgYnkgYW4gaWRlbnRpdHkgcHJvdmlkZXIgKElkUCkgdGhhdCBzdXBwb3J0cyBTQU1MIDIuMC4gVGhlIGRvY3VtZW50IGluY2x1ZGVzIHRoZSBpc3N1ZXIncyBuYW1lLCBleHBpcmF0aW9uIGluZm9ybWF0aW9uLCBhbmQga2V5cyB0aGF0IGNhbiBiZSB1c2VkIHRvIHZhbGlkYXRlIHRoZSBTQU1MIGF1dGhlbnRpY2F0aW9uIHJlc3BvbnNlIChhc3NlcnRpb25zKSB0aGF0IGFyZSByZWNlaXZlZCBmcm9tIHRoZSBJZFAuIFlvdSBtdXN0IGdlbmVyYXRlIHRoZSBtZXRhZGF0YSBkb2N1bWVudCB1c2luZyB0aGUgaWRlbnRpdHkgbWFuYWdlbWVudCBzb2Z0d2FyZSB0aGF0IGlzIHVzZWQgYXMgeW91ciBvcmdhbml6YXRpb24ncyBJZFAuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBYm91dCBTQU1MIDIuMC1iYXNlZCBmZWRlcmF0aW9uXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvaWRfcm9sZXNfcHJvdmlkZXJzX3NhbWwuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSpcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zYW1scHJvdmlkZXIuaHRtbCNjZm4taWFtLXNhbWxwcm92aWRlci1zYW1sbWV0YWRhdGFkb2N1bWVudFxuICAgICAqL1xuICAgIHB1YmxpYyBzYW1sTWV0YWRhdGFEb2N1bWVudDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIHRvIGNyZWF0ZS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2FtbHByb3ZpZGVyLmh0bWwjY2ZuLWlhbS1zYW1scHJvdmlkZXItbmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyBuYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgdGFncyB0aGF0IHlvdSB3YW50IHRvIGF0dGFjaCB0byB0aGUgbmV3IElBTSBTQU1MIHByb3ZpZGVyLiBFYWNoIHRhZyBjb25zaXN0cyBvZiBhIGtleSBuYW1lIGFuZCBhbiBhc3NvY2lhdGVkIHZhbHVlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0YWdnaW5nLCBzZWUgW1RhZ2dpbmcgSUFNIHJlc291cmNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX3RhZ3MuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogPiBJZiBhbnkgb25lIG9mIHRoZSB0YWdzIGlzIGludmFsaWQgb3IgaWYgeW91IGV4Y2VlZCB0aGUgYWxsb3dlZCBtYXhpbXVtIG51bWJlciBvZiB0YWdzLCB0aGVuIHRoZSBlbnRpcmUgcmVxdWVzdCBmYWlscyBhbmQgdGhlIHJlc291cmNlIGlzIG5vdCBjcmVhdGVkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNhbWxwcm92aWRlci5odG1sI2Nmbi1pYW0tc2FtbHByb3ZpZGVyLXRhZ3NcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgdGFnczogY2RrLlRhZ01hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6SUFNOjpTQU1MUHJvdmlkZXJgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmblNBTUxQcm92aWRlclByb3BzKSB7XG4gICAgICAgIHN1cGVyKHNjb3BlLCBpZCwgeyB0eXBlOiBDZm5TQU1MUHJvdmlkZXIuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICdzYW1sTWV0YWRhdGFEb2N1bWVudCcsIHRoaXMpO1xuICAgICAgICB0aGlzLmF0dHJBcm4gPSBjZGsuVG9rZW4uYXNTdHJpbmcodGhpcy5nZXRBdHQoJ0FybicpKTtcblxuICAgICAgICB0aGlzLnNhbWxNZXRhZGF0YURvY3VtZW50ID0gcHJvcHMuc2FtbE1ldGFkYXRhRG9jdW1lbnQ7XG4gICAgICAgIHRoaXMubmFtZSA9IHByb3BzLm5hbWU7XG4gICAgICAgIHRoaXMudGFncyA9IG5ldyBjZGsuVGFnTWFuYWdlcihjZGsuVGFnVHlwZS5TVEFOREFSRCwgXCJBV1M6OklBTTo6U0FNTFByb3ZpZGVyXCIsIHByb3BzLnRhZ3MsIHsgdGFnUHJvcGVydHlOYW1lOiAndGFncycgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5TQU1MUHJvdmlkZXIuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNhbWxNZXRhZGF0YURvY3VtZW50OiB0aGlzLnNhbWxNZXRhZGF0YURvY3VtZW50LFxuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgdGFnczogdGhpcy50YWdzLnJlbmRlclRhZ3MoKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5TQU1MUHJvdmlkZXJQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5TZXJ2ZXJDZXJ0aWZpY2F0ZWBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZlcmNlcnRpZmljYXRlLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5TZXJ2ZXJDZXJ0aWZpY2F0ZVByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBjb250ZW50cyBvZiB0aGUgcHVibGljIGtleSBjZXJ0aWZpY2F0ZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS5odG1sI2Nmbi1pYW0tc2VydmVyY2VydGlmaWNhdGUtY2VydGlmaWNhdGVib2R5XG4gICAgICovXG4gICAgcmVhZG9ubHkgY2VydGlmaWNhdGVCb2R5Pzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNvbnRlbnRzIG9mIHRoZSBwdWJsaWMga2V5IGNlcnRpZmljYXRlIGNoYWluLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZlcmNlcnRpZmljYXRlLmh0bWwjY2ZuLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS1jZXJ0aWZpY2F0ZWNoYWluXG4gICAgICovXG4gICAgcmVhZG9ubHkgY2VydGlmaWNhdGVDaGFpbj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBwYXRoIGZvciB0aGUgc2VydmVyIGNlcnRpZmljYXRlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gaWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS4gVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIGVpdGhlciBhIGZvcndhcmQgc2xhc2ggKC8pIGJ5IGl0c2VsZiBvciBhIHN0cmluZyB0aGF0IG11c3QgYmVnaW4gYW5kIGVuZCB3aXRoIGZvcndhcmQgc2xhc2hlcy4gSW4gYWRkaXRpb24sIGl0IGNhbiBjb250YWluIGFueSBBU0NJSSBjaGFyYWN0ZXIgZnJvbSB0aGUgISAoIGBcXCB1MDAyMWAgKSB0aHJvdWdoIHRoZSBERUwgY2hhcmFjdGVyICggYFxcIHUwMDdGYCApLCBpbmNsdWRpbmcgbW9zdCBwdW5jdHVhdGlvbiBjaGFyYWN0ZXJzLCBkaWdpdHMsIGFuZCB1cHBlciBhbmQgbG93ZXJjYXNlZCBsZXR0ZXJzLlxuICAgICAqXG4gICAgICogPiBJZiB5b3UgYXJlIHVwbG9hZGluZyBhIHNlcnZlciBjZXJ0aWZpY2F0ZSBzcGVjaWZpY2FsbHkgZm9yIHVzZSB3aXRoIEFtYXpvbiBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbnMsIHlvdSBtdXN0IHNwZWNpZnkgYSBwYXRoIHVzaW5nIHRoZSBgcGF0aGAgcGFyYW1ldGVyLiBUaGUgcGF0aCBtdXN0IGJlZ2luIHdpdGggYC9jbG91ZGZyb250YCBhbmQgbXVzdCBpbmNsdWRlIGEgdHJhaWxpbmcgc2xhc2ggKGZvciBleGFtcGxlLCBgL2Nsb3VkZnJvbnQvdGVzdC9gICkuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2VydmVyY2VydGlmaWNhdGUuaHRtbCNjZm4taWFtLXNlcnZlcmNlcnRpZmljYXRlLXBhdGhcbiAgICAgKi9cbiAgICByZWFkb25seSBwYXRoPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNvbnRlbnRzIG9mIHRoZSBwcml2YXRlIGtleSBpbiBQRU0tZW5jb2RlZCBmb3JtYXQuXG4gICAgICpcbiAgICAgKiBUaGUgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSB1c2VkIHRvIHZhbGlkYXRlIHRoaXMgcGFyYW1ldGVyIGlzIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBBbnkgcHJpbnRhYmxlIEFTQ0lJIGNoYXJhY3RlciByYW5naW5nIGZyb20gdGhlIHNwYWNlIGNoYXJhY3RlciAoIGBcXCB1MDAyMGAgKSB0aHJvdWdoIHRoZSBlbmQgb2YgdGhlIEFTQ0lJIGNoYXJhY3RlciByYW5nZVxuICAgICAqIC0gVGhlIHByaW50YWJsZSBjaGFyYWN0ZXJzIGluIHRoZSBCYXNpYyBMYXRpbiBhbmQgTGF0aW4tMSBTdXBwbGVtZW50IGNoYXJhY3RlciBzZXQgKHRocm91Z2ggYFxcIHUwMEZGYCApXG4gICAgICogLSBUaGUgc3BlY2lhbCBjaGFyYWN0ZXJzIHRhYiAoIGBcXCB1MDAwOWAgKSwgbGluZSBmZWVkICggYFxcIHUwMDBBYCApLCBhbmQgY2FycmlhZ2UgcmV0dXJuICggYFxcIHUwMDBEYCApXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2VydmVyY2VydGlmaWNhdGUuaHRtbCNjZm4taWFtLXNlcnZlcmNlcnRpZmljYXRlLXByaXZhdGVrZXlcbiAgICAgKi9cbiAgICByZWFkb25seSBwcml2YXRlS2V5Pzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgZm9yIHRoZSBzZXJ2ZXIgY2VydGlmaWNhdGUuIERvIG5vdCBpbmNsdWRlIHRoZSBwYXRoIGluIHRoaXMgdmFsdWUuIFRoZSBuYW1lIG9mIHRoZSBjZXJ0aWZpY2F0ZSBjYW5ub3QgY29udGFpbiBhbnkgc3BhY2VzLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS5odG1sI2Nmbi1pYW0tc2VydmVyY2VydGlmaWNhdGUtc2VydmVyY2VydGlmaWNhdGVuYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgc2VydmVyQ2VydGlmaWNhdGVOYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIHRhZ3MgdGhhdCBhcmUgYXR0YWNoZWQgdG8gdGhlIHNlcnZlciBjZXJ0aWZpY2F0ZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGFnZ2luZywgc2VlIFtUYWdnaW5nIElBTSByZXNvdXJjZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF90YWdzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS5odG1sI2Nmbi1pYW0tc2VydmVyY2VydGlmaWNhdGUtdGFnc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IHRhZ3M/OiBjZGsuQ2ZuVGFnW107XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2ZuU2VydmVyQ2VydGlmaWNhdGVQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuU2VydmVyQ2VydGlmaWNhdGVQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5TZXJ2ZXJDZXJ0aWZpY2F0ZVByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2VydGlmaWNhdGVCb2R5JywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmNlcnRpZmljYXRlQm9keSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2VydGlmaWNhdGVDaGFpbicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jZXJ0aWZpY2F0ZUNoYWluKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwYXRoJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnBhdGgpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3ByaXZhdGVLZXknLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucHJpdmF0ZUtleSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc2VydmVyQ2VydGlmaWNhdGVOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnNlcnZlckNlcnRpZmljYXRlTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndGFncycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZUNmblRhZykpKHByb3BlcnRpZXMudGFncykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5TZXJ2ZXJDZXJ0aWZpY2F0ZVByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlNlcnZlckNlcnRpZmljYXRlYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5TZXJ2ZXJDZXJ0aWZpY2F0ZVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlNlcnZlckNlcnRpZmljYXRlYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblNlcnZlckNlcnRpZmljYXRlUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblNlcnZlckNlcnRpZmljYXRlUHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIENlcnRpZmljYXRlQm9keTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jZXJ0aWZpY2F0ZUJvZHkpLFxuICAgICAgICBDZXJ0aWZpY2F0ZUNoYWluOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNlcnRpZmljYXRlQ2hhaW4pLFxuICAgICAgICBQYXRoOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBhdGgpLFxuICAgICAgICBQcml2YXRlS2V5OiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnByaXZhdGVLZXkpLFxuICAgICAgICBTZXJ2ZXJDZXJ0aWZpY2F0ZU5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuc2VydmVyQ2VydGlmaWNhdGVOYW1lKSxcbiAgICAgICAgVGFnczogY2RrLmxpc3RNYXBwZXIoY2RrLmNmblRhZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMudGFncyksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblNlcnZlckNlcnRpZmljYXRlUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5TZXJ2ZXJDZXJ0aWZpY2F0ZVByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5TZXJ2ZXJDZXJ0aWZpY2F0ZVByb3BzPigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY2VydGlmaWNhdGVCb2R5JywgJ0NlcnRpZmljYXRlQm9keScsIHByb3BlcnRpZXMuQ2VydGlmaWNhdGVCb2R5ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNlcnRpZmljYXRlQm9keSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY2VydGlmaWNhdGVDaGFpbicsICdDZXJ0aWZpY2F0ZUNoYWluJywgcHJvcGVydGllcy5DZXJ0aWZpY2F0ZUNoYWluICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNlcnRpZmljYXRlQ2hhaW4pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BhdGgnLCAnUGF0aCcsIHByb3BlcnRpZXMuUGF0aCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5QYXRoKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwcml2YXRlS2V5JywgJ1ByaXZhdGVLZXknLCBwcm9wZXJ0aWVzLlByaXZhdGVLZXkgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUHJpdmF0ZUtleSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc2VydmVyQ2VydGlmaWNhdGVOYW1lJywgJ1NlcnZlckNlcnRpZmljYXRlTmFtZScsIHByb3BlcnRpZXMuU2VydmVyQ2VydGlmaWNhdGVOYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlNlcnZlckNlcnRpZmljYXRlTmFtZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndGFncycsICdUYWdzJywgcHJvcGVydGllcy5UYWdzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Q2ZuVGFnKShwcm9wZXJ0aWVzLlRhZ3MpIDogdW5kZWZpbmVkIGFzIGFueSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpJQU06OlNlcnZlckNlcnRpZmljYXRlYFxuICpcbiAqIFVwbG9hZHMgYSBzZXJ2ZXIgY2VydGlmaWNhdGUgZW50aXR5IGZvciB0aGUgQVdTIGFjY291bnQgLiBUaGUgc2VydmVyIGNlcnRpZmljYXRlIGVudGl0eSBpbmNsdWRlcyBhIHB1YmxpYyBrZXkgY2VydGlmaWNhdGUsIGEgcHJpdmF0ZSBrZXksIGFuZCBhbiBvcHRpb25hbCBjZXJ0aWZpY2F0ZSBjaGFpbiwgd2hpY2ggc2hvdWxkIGFsbCBiZSBQRU0tZW5jb2RlZC5cbiAqXG4gKiBXZSByZWNvbW1lbmQgdGhhdCB5b3UgdXNlIFtBV1MgQ2VydGlmaWNhdGUgTWFuYWdlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2FjbS8pIHRvIHByb3Zpc2lvbiwgbWFuYWdlLCBhbmQgZGVwbG95IHlvdXIgc2VydmVyIGNlcnRpZmljYXRlcy4gV2l0aCBBQ00geW91IGNhbiByZXF1ZXN0IGEgY2VydGlmaWNhdGUsIGRlcGxveSBpdCB0byBBV1MgcmVzb3VyY2VzLCBhbmQgbGV0IEFDTSBoYW5kbGUgY2VydGlmaWNhdGUgcmVuZXdhbHMgZm9yIHlvdS4gQ2VydGlmaWNhdGVzIHByb3ZpZGVkIGJ5IEFDTSBhcmUgZnJlZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdXNpbmcgQUNNLCBzZWUgdGhlIFtBV1MgQ2VydGlmaWNhdGUgTWFuYWdlciBVc2VyIEd1aWRlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYWNtL2xhdGVzdC91c2VyZ3VpZGUvKSAuXG4gKlxuICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgd29ya2luZyB3aXRoIHNlcnZlciBjZXJ0aWZpY2F0ZXMsIHNlZSBbV29ya2luZyB3aXRoIHNlcnZlciBjZXJ0aWZpY2F0ZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF9jcmVkZW50aWFsc19zZXJ2ZXItY2VydHMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLiBUaGlzIHRvcGljIGluY2x1ZGVzIGEgbGlzdCBvZiBBV1Mgc2VydmljZXMgdGhhdCBjYW4gdXNlIHRoZSBzZXJ2ZXIgY2VydGlmaWNhdGVzIHRoYXQgeW91IG1hbmFnZSB3aXRoIElBTS5cbiAqXG4gKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG51bWJlciBvZiBzZXJ2ZXIgY2VydGlmaWNhdGVzIHlvdSBjYW4gdXBsb2FkLCBzZWUgW0lBTSBhbmQgQVdTIFNUUyBxdW90YXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfaWFtLXF1b3Rhcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gKlxuICogPiBCZWNhdXNlIHRoZSBib2R5IG9mIHRoZSBwdWJsaWMga2V5IGNlcnRpZmljYXRlLCBwcml2YXRlIGtleSwgYW5kIHRoZSBjZXJ0aWZpY2F0ZSBjaGFpbiBjYW4gYmUgbGFyZ2UsIHlvdSBzaG91bGQgdXNlIFBPU1QgcmF0aGVyIHRoYW4gR0VUIHdoZW4gY2FsbGluZyBgVXBsb2FkU2VydmVyQ2VydGlmaWNhdGVgIC4gRm9yIGluZm9ybWF0aW9uIGFib3V0IHNldHRpbmcgdXAgc2lnbmF0dXJlcyBhbmQgYXV0aG9yaXphdGlvbiB0aHJvdWdoIHRoZSBBUEksIHNlZSBbU2lnbmluZyBBV1MgQVBJIHJlcXVlc3RzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2VuZXJhbC9sYXRlc3QvZ3Ivc2lnbmluZ19hd3NfYXBpX3JlcXVlc3RzLmh0bWwpIGluIHRoZSAqQVdTIEdlbmVyYWwgUmVmZXJlbmNlKiAuIEZvciBnZW5lcmFsIGluZm9ybWF0aW9uIGFib3V0IHVzaW5nIHRoZSBRdWVyeSBBUEkgd2l0aCBJQU0sIHNlZSBbQ2FsbGluZyB0aGUgQVBJIGJ5IG1ha2luZyBIVFRQIHF1ZXJ5IHJlcXVlc3RzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcHJvZ3JhbW1pbmcuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6SUFNOjpTZXJ2ZXJDZXJ0aWZpY2F0ZVxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5TZXJ2ZXJDZXJ0aWZpY2F0ZSBleHRlbmRzIGNkay5DZm5SZXNvdXJjZSBpbXBsZW1lbnRzIGNkay5JSW5zcGVjdGFibGUge1xuICAgIC8qKlxuICAgICAqIFRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIG5hbWUgZm9yIHRoaXMgcmVzb3VyY2UgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBDRk5fUkVTT1VSQ0VfVFlQRV9OQU1FID0gXCJBV1M6OklBTTo6U2VydmVyQ2VydGlmaWNhdGVcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmblNlcnZlckNlcnRpZmljYXRlIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5TZXJ2ZXJDZXJ0aWZpY2F0ZVByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5TZXJ2ZXJDZXJ0aWZpY2F0ZShzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBmb3IgdGhlIHNwZWNpZmllZCBgQVdTOjpJQU06OlNlcnZlckNlcnRpZmljYXRlYCByZXNvdXJjZS5cbiAgICAgKiBAY2xvdWRmb3JtYXRpb25BdHRyaWJ1dGUgQXJuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJBcm46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBjb250ZW50cyBvZiB0aGUgcHVibGljIGtleSBjZXJ0aWZpY2F0ZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS5odG1sI2Nmbi1pYW0tc2VydmVyY2VydGlmaWNhdGUtY2VydGlmaWNhdGVib2R5XG4gICAgICovXG4gICAgcHVibGljIGNlcnRpZmljYXRlQm9keTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNvbnRlbnRzIG9mIHRoZSBwdWJsaWMga2V5IGNlcnRpZmljYXRlIGNoYWluLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZlcmNlcnRpZmljYXRlLmh0bWwjY2ZuLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS1jZXJ0aWZpY2F0ZWNoYWluXG4gICAgICovXG4gICAgcHVibGljIGNlcnRpZmljYXRlQ2hhaW46IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwYXRoIGZvciB0aGUgc2VydmVyIGNlcnRpZmljYXRlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gaWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS4gVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIGVpdGhlciBhIGZvcndhcmQgc2xhc2ggKC8pIGJ5IGl0c2VsZiBvciBhIHN0cmluZyB0aGF0IG11c3QgYmVnaW4gYW5kIGVuZCB3aXRoIGZvcndhcmQgc2xhc2hlcy4gSW4gYWRkaXRpb24sIGl0IGNhbiBjb250YWluIGFueSBBU0NJSSBjaGFyYWN0ZXIgZnJvbSB0aGUgISAoIGBcXCB1MDAyMWAgKSB0aHJvdWdoIHRoZSBERUwgY2hhcmFjdGVyICggYFxcIHUwMDdGYCApLCBpbmNsdWRpbmcgbW9zdCBwdW5jdHVhdGlvbiBjaGFyYWN0ZXJzLCBkaWdpdHMsIGFuZCB1cHBlciBhbmQgbG93ZXJjYXNlZCBsZXR0ZXJzLlxuICAgICAqXG4gICAgICogPiBJZiB5b3UgYXJlIHVwbG9hZGluZyBhIHNlcnZlciBjZXJ0aWZpY2F0ZSBzcGVjaWZpY2FsbHkgZm9yIHVzZSB3aXRoIEFtYXpvbiBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbnMsIHlvdSBtdXN0IHNwZWNpZnkgYSBwYXRoIHVzaW5nIHRoZSBgcGF0aGAgcGFyYW1ldGVyLiBUaGUgcGF0aCBtdXN0IGJlZ2luIHdpdGggYC9jbG91ZGZyb250YCBhbmQgbXVzdCBpbmNsdWRlIGEgdHJhaWxpbmcgc2xhc2ggKGZvciBleGFtcGxlLCBgL2Nsb3VkZnJvbnQvdGVzdC9gICkuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2VydmVyY2VydGlmaWNhdGUuaHRtbCNjZm4taWFtLXNlcnZlcmNlcnRpZmljYXRlLXBhdGhcbiAgICAgKi9cbiAgICBwdWJsaWMgcGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNvbnRlbnRzIG9mIHRoZSBwcml2YXRlIGtleSBpbiBQRU0tZW5jb2RlZCBmb3JtYXQuXG4gICAgICpcbiAgICAgKiBUaGUgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSB1c2VkIHRvIHZhbGlkYXRlIHRoaXMgcGFyYW1ldGVyIGlzIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBBbnkgcHJpbnRhYmxlIEFTQ0lJIGNoYXJhY3RlciByYW5naW5nIGZyb20gdGhlIHNwYWNlIGNoYXJhY3RlciAoIGBcXCB1MDAyMGAgKSB0aHJvdWdoIHRoZSBlbmQgb2YgdGhlIEFTQ0lJIGNoYXJhY3RlciByYW5nZVxuICAgICAqIC0gVGhlIHByaW50YWJsZSBjaGFyYWN0ZXJzIGluIHRoZSBCYXNpYyBMYXRpbiBhbmQgTGF0aW4tMSBTdXBwbGVtZW50IGNoYXJhY3RlciBzZXQgKHRocm91Z2ggYFxcIHUwMEZGYCApXG4gICAgICogLSBUaGUgc3BlY2lhbCBjaGFyYWN0ZXJzIHRhYiAoIGBcXCB1MDAwOWAgKSwgbGluZSBmZWVkICggYFxcIHUwMDBBYCApLCBhbmQgY2FycmlhZ2UgcmV0dXJuICggYFxcIHUwMDBEYCApXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2VydmVyY2VydGlmaWNhdGUuaHRtbCNjZm4taWFtLXNlcnZlcmNlcnRpZmljYXRlLXByaXZhdGVrZXlcbiAgICAgKi9cbiAgICBwdWJsaWMgcHJpdmF0ZUtleTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgZm9yIHRoZSBzZXJ2ZXIgY2VydGlmaWNhdGUuIERvIG5vdCBpbmNsdWRlIHRoZSBwYXRoIGluIHRoaXMgdmFsdWUuIFRoZSBuYW1lIG9mIHRoZSBjZXJ0aWZpY2F0ZSBjYW5ub3QgY29udGFpbiBhbnkgc3BhY2VzLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS5odG1sI2Nmbi1pYW0tc2VydmVyY2VydGlmaWNhdGUtc2VydmVyY2VydGlmaWNhdGVuYW1lXG4gICAgICovXG4gICAgcHVibGljIHNlcnZlckNlcnRpZmljYXRlTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIHRhZ3MgdGhhdCBhcmUgYXR0YWNoZWQgdG8gdGhlIHNlcnZlciBjZXJ0aWZpY2F0ZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGFnZ2luZywgc2VlIFtUYWdnaW5nIElBTSByZXNvdXJjZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF90YWdzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS5odG1sI2Nmbi1pYW0tc2VydmVyY2VydGlmaWNhdGUtdGFnc1xuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB0YWdzOiBjZGsuVGFnTWFuYWdlcjtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpJQU06OlNlcnZlckNlcnRpZmljYXRlYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5TZXJ2ZXJDZXJ0aWZpY2F0ZVByb3BzID0ge30pIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmblNlcnZlckNlcnRpZmljYXRlLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUsIHByb3BlcnRpZXM6IHByb3BzIH0pO1xuICAgICAgICB0aGlzLmF0dHJBcm4gPSBjZGsuVG9rZW4uYXNTdHJpbmcodGhpcy5nZXRBdHQoJ0FybicpKTtcblxuICAgICAgICB0aGlzLmNlcnRpZmljYXRlQm9keSA9IHByb3BzLmNlcnRpZmljYXRlQm9keTtcbiAgICAgICAgdGhpcy5jZXJ0aWZpY2F0ZUNoYWluID0gcHJvcHMuY2VydGlmaWNhdGVDaGFpbjtcbiAgICAgICAgdGhpcy5wYXRoID0gcHJvcHMucGF0aDtcbiAgICAgICAgdGhpcy5wcml2YXRlS2V5ID0gcHJvcHMucHJpdmF0ZUtleTtcbiAgICAgICAgdGhpcy5zZXJ2ZXJDZXJ0aWZpY2F0ZU5hbWUgPSBwcm9wcy5zZXJ2ZXJDZXJ0aWZpY2F0ZU5hbWU7XG4gICAgICAgIHRoaXMudGFncyA9IG5ldyBjZGsuVGFnTWFuYWdlcihjZGsuVGFnVHlwZS5TVEFOREFSRCwgXCJBV1M6OklBTTo6U2VydmVyQ2VydGlmaWNhdGVcIiwgcHJvcHMudGFncywgeyB0YWdQcm9wZXJ0eU5hbWU6ICd0YWdzJyB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmblNlcnZlckNlcnRpZmljYXRlLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjZXJ0aWZpY2F0ZUJvZHk6IHRoaXMuY2VydGlmaWNhdGVCb2R5LFxuICAgICAgICAgICAgY2VydGlmaWNhdGVDaGFpbjogdGhpcy5jZXJ0aWZpY2F0ZUNoYWluLFxuICAgICAgICAgICAgcGF0aDogdGhpcy5wYXRoLFxuICAgICAgICAgICAgcHJpdmF0ZUtleTogdGhpcy5wcml2YXRlS2V5LFxuICAgICAgICAgICAgc2VydmVyQ2VydGlmaWNhdGVOYW1lOiB0aGlzLnNlcnZlckNlcnRpZmljYXRlTmFtZSxcbiAgICAgICAgICAgIHRhZ3M6IHRoaXMudGFncy5yZW5kZXJUYWdzKCksXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuU2VydmVyQ2VydGlmaWNhdGVQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5TZXJ2aWNlTGlua2VkUm9sZWBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZpY2VsaW5rZWRyb2xlLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5TZXJ2aWNlTGlua2VkUm9sZVByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBzZXJ2aWNlIHByaW5jaXBhbCBmb3IgdGhlIEFXUyBzZXJ2aWNlIHRvIHdoaWNoIHRoaXMgcm9sZSBpcyBhdHRhY2hlZC4gWW91IHVzZSBhIHN0cmluZyBzaW1pbGFyIHRvIGEgVVJMIGJ1dCB3aXRob3V0IHRoZSBodHRwOi8vIGluIGZyb250LiBGb3IgZXhhbXBsZTogYGVsYXN0aWNiZWFuc3RhbGsuYW1hem9uYXdzLmNvbWAgLlxuICAgICAqXG4gICAgICogU2VydmljZSBwcmluY2lwYWxzIGFyZSB1bmlxdWUgYW5kIGNhc2Utc2Vuc2l0aXZlLiBUbyBmaW5kIHRoZSBleGFjdCBzZXJ2aWNlIHByaW5jaXBhbCBmb3IgeW91ciBzZXJ2aWNlLWxpbmtlZCByb2xlLCBzZWUgW0FXUyBzZXJ2aWNlcyB0aGF0IHdvcmsgd2l0aCBJQU1dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfYXdzLXNlcnZpY2VzLXRoYXQtd29yay13aXRoLWlhbS5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuIExvb2sgZm9yIHRoZSBzZXJ2aWNlcyB0aGF0IGhhdmUgKlllcyogaW4gdGhlICpTZXJ2aWNlLUxpbmtlZCBSb2xlKiBjb2x1bW4uIENob29zZSB0aGUgKlllcyogbGluayB0byB2aWV3IHRoZSBzZXJ2aWNlLWxpbmtlZCByb2xlIGRvY3VtZW50YXRpb24gZm9yIHRoYXQgc2VydmljZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2aWNlbGlua2Vkcm9sZS5odG1sI2Nmbi1pYW0tc2VydmljZWxpbmtlZHJvbGUtYXdzc2VydmljZW5hbWVcbiAgICAgKi9cbiAgICByZWFkb25seSBhd3NTZXJ2aWNlTmFtZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBzdHJpbmcgdGhhdCB5b3UgcHJvdmlkZSwgd2hpY2ggaXMgY29tYmluZWQgd2l0aCB0aGUgc2VydmljZS1wcm92aWRlZCBwcmVmaXggdG8gZm9ybSB0aGUgY29tcGxldGUgcm9sZSBuYW1lLiBJZiB5b3UgbWFrZSBtdWx0aXBsZSByZXF1ZXN0cyBmb3IgdGhlIHNhbWUgc2VydmljZSwgdGhlbiB5b3UgbXVzdCBzdXBwbHkgYSBkaWZmZXJlbnQgYEN1c3RvbVN1ZmZpeGAgZm9yIGVhY2ggcmVxdWVzdC4gT3RoZXJ3aXNlIHRoZSByZXF1ZXN0IGZhaWxzIHdpdGggYSBkdXBsaWNhdGUgcm9sZSBuYW1lIGVycm9yLiBGb3IgZXhhbXBsZSwgeW91IGNvdWxkIGFkZCBgLTFgIG9yIGAtZGVidWdgIHRvIHRoZSBzdWZmaXguXG4gICAgICpcbiAgICAgKiBTb21lIHNlcnZpY2VzIGRvIG5vdCBzdXBwb3J0IHRoZSBgQ3VzdG9tU3VmZml4YCBwYXJhbWV0ZXIuIElmIHlvdSBwcm92aWRlIGFuIG9wdGlvbmFsIHN1ZmZpeCBhbmQgdGhlIG9wZXJhdGlvbiBmYWlscywgdHJ5IHRoZSBvcGVyYXRpb24gYWdhaW4gd2l0aG91dCB0aGUgc3VmZml4LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZpY2VsaW5rZWRyb2xlLmh0bWwjY2ZuLWlhbS1zZXJ2aWNlbGlua2Vkcm9sZS1jdXN0b21zdWZmaXhcbiAgICAgKi9cbiAgICByZWFkb25seSBjdXN0b21TdWZmaXg/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZGVzY3JpcHRpb24gb2YgdGhlIHJvbGUuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2VydmljZWxpbmtlZHJvbGUuaHRtbCNjZm4taWFtLXNlcnZpY2VsaW5rZWRyb2xlLWRlc2NyaXB0aW9uXG4gICAgICovXG4gICAgcmVhZG9ubHkgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2ZuU2VydmljZUxpbmtlZFJvbGVQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuU2VydmljZUxpbmtlZFJvbGVQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5TZXJ2aWNlTGlua2VkUm9sZVByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignYXdzU2VydmljZU5hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuYXdzU2VydmljZU5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2F3c1NlcnZpY2VOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmF3c1NlcnZpY2VOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjdXN0b21TdWZmaXgnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY3VzdG9tU3VmZml4KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkZXNjcmlwdGlvbicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5kZXNjcmlwdGlvbikpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5TZXJ2aWNlTGlua2VkUm9sZVByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlNlcnZpY2VMaW5rZWRSb2xlYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5TZXJ2aWNlTGlua2VkUm9sZVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlNlcnZpY2VMaW5rZWRSb2xlYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblNlcnZpY2VMaW5rZWRSb2xlUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblNlcnZpY2VMaW5rZWRSb2xlUHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEFXU1NlcnZpY2VOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmF3c1NlcnZpY2VOYW1lKSxcbiAgICAgICAgQ3VzdG9tU3VmZml4OiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmN1c3RvbVN1ZmZpeCksXG4gICAgICAgIERlc2NyaXB0aW9uOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmRlc2NyaXB0aW9uKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuU2VydmljZUxpbmtlZFJvbGVQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblNlcnZpY2VMaW5rZWRSb2xlUHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblNlcnZpY2VMaW5rZWRSb2xlUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdhd3NTZXJ2aWNlTmFtZScsICdBV1NTZXJ2aWNlTmFtZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQVdTU2VydmljZU5hbWUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2N1c3RvbVN1ZmZpeCcsICdDdXN0b21TdWZmaXgnLCBwcm9wZXJ0aWVzLkN1c3RvbVN1ZmZpeCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5DdXN0b21TdWZmaXgpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Rlc2NyaXB0aW9uJywgJ0Rlc2NyaXB0aW9uJywgcHJvcGVydGllcy5EZXNjcmlwdGlvbiAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5EZXNjcmlwdGlvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6SUFNOjpTZXJ2aWNlTGlua2VkUm9sZWBcbiAqXG4gKiBDcmVhdGVzIGFuIElBTSByb2xlIHRoYXQgaXMgbGlua2VkIHRvIGEgc3BlY2lmaWMgQVdTIHNlcnZpY2UuIFRoZSBzZXJ2aWNlIGNvbnRyb2xzIHRoZSBhdHRhY2hlZCBwb2xpY2llcyBhbmQgd2hlbiB0aGUgcm9sZSBjYW4gYmUgZGVsZXRlZC4gVGhpcyBoZWxwcyBlbnN1cmUgdGhhdCB0aGUgc2VydmljZSBpcyBub3QgYnJva2VuIGJ5IGFuIHVuZXhwZWN0ZWRseSBjaGFuZ2VkIG9yIGRlbGV0ZWQgcm9sZSwgd2hpY2ggY291bGQgcHV0IHlvdXIgQVdTIHJlc291cmNlcyBpbnRvIGFuIHVua25vd24gc3RhdGUuIEFsbG93aW5nIHRoZSBzZXJ2aWNlIHRvIGNvbnRyb2wgdGhlIHJvbGUgaGVscHMgaW1wcm92ZSBzZXJ2aWNlIHN0YWJpbGl0eSBhbmQgcHJvcGVyIGNsZWFudXAgd2hlbiBhIHNlcnZpY2UgYW5kIGl0cyByb2xlIGFyZSBubyBsb25nZXIgbmVlZGVkLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtVc2luZyBzZXJ2aWNlLWxpbmtlZCByb2xlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3VzaW5nLXNlcnZpY2UtbGlua2VkLXJvbGVzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAqXG4gKiBUbyBhdHRhY2ggYSBwb2xpY3kgdG8gdGhpcyBzZXJ2aWNlLWxpbmtlZCByb2xlLCB5b3UgbXVzdCBtYWtlIHRoZSByZXF1ZXN0IHVzaW5nIHRoZSBBV1Mgc2VydmljZSB0aGF0IGRlcGVuZHMgb24gdGhpcyByb2xlLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6SUFNOjpTZXJ2aWNlTGlua2VkUm9sZVxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2aWNlbGlua2Vkcm9sZS5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5TZXJ2aWNlTGlua2VkUm9sZSBleHRlbmRzIGNkay5DZm5SZXNvdXJjZSBpbXBsZW1lbnRzIGNkay5JSW5zcGVjdGFibGUge1xuICAgIC8qKlxuICAgICAqIFRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIG5hbWUgZm9yIHRoaXMgcmVzb3VyY2UgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBDRk5fUkVTT1VSQ0VfVFlQRV9OQU1FID0gXCJBV1M6OklBTTo6U2VydmljZUxpbmtlZFJvbGVcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmblNlcnZpY2VMaW5rZWRSb2xlIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5TZXJ2aWNlTGlua2VkUm9sZVByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5TZXJ2aWNlTGlua2VkUm9sZShzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc2VydmljZSBwcmluY2lwYWwgZm9yIHRoZSBBV1Mgc2VydmljZSB0byB3aGljaCB0aGlzIHJvbGUgaXMgYXR0YWNoZWQuIFlvdSB1c2UgYSBzdHJpbmcgc2ltaWxhciB0byBhIFVSTCBidXQgd2l0aG91dCB0aGUgaHR0cDovLyBpbiBmcm9udC4gRm9yIGV4YW1wbGU6IGBlbGFzdGljYmVhbnN0YWxrLmFtYXpvbmF3cy5jb21gIC5cbiAgICAgKlxuICAgICAqIFNlcnZpY2UgcHJpbmNpcGFscyBhcmUgdW5pcXVlIGFuZCBjYXNlLXNlbnNpdGl2ZS4gVG8gZmluZCB0aGUgZXhhY3Qgc2VydmljZSBwcmluY2lwYWwgZm9yIHlvdXIgc2VydmljZS1saW5rZWQgcm9sZSwgc2VlIFtBV1Mgc2VydmljZXMgdGhhdCB3b3JrIHdpdGggSUFNXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX2F3cy1zZXJ2aWNlcy10aGF0LXdvcmstd2l0aC1pYW0uaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLiBMb29rIGZvciB0aGUgc2VydmljZXMgdGhhdCBoYXZlICpZZXMqIGluIHRoZSAqU2VydmljZS1MaW5rZWQgUm9sZSogY29sdW1uLiBDaG9vc2UgdGhlICpZZXMqIGxpbmsgdG8gdmlldyB0aGUgc2VydmljZS1saW5rZWQgcm9sZSBkb2N1bWVudGF0aW9uIGZvciB0aGF0IHNlcnZpY2UuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2VydmljZWxpbmtlZHJvbGUuaHRtbCNjZm4taWFtLXNlcnZpY2VsaW5rZWRyb2xlLWF3c3NlcnZpY2VuYW1lXG4gICAgICovXG4gICAgcHVibGljIGF3c1NlcnZpY2VOYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBIHN0cmluZyB0aGF0IHlvdSBwcm92aWRlLCB3aGljaCBpcyBjb21iaW5lZCB3aXRoIHRoZSBzZXJ2aWNlLXByb3ZpZGVkIHByZWZpeCB0byBmb3JtIHRoZSBjb21wbGV0ZSByb2xlIG5hbWUuIElmIHlvdSBtYWtlIG11bHRpcGxlIHJlcXVlc3RzIGZvciB0aGUgc2FtZSBzZXJ2aWNlLCB0aGVuIHlvdSBtdXN0IHN1cHBseSBhIGRpZmZlcmVudCBgQ3VzdG9tU3VmZml4YCBmb3IgZWFjaCByZXF1ZXN0LiBPdGhlcndpc2UgdGhlIHJlcXVlc3QgZmFpbHMgd2l0aCBhIGR1cGxpY2F0ZSByb2xlIG5hbWUgZXJyb3IuIEZvciBleGFtcGxlLCB5b3UgY291bGQgYWRkIGAtMWAgb3IgYC1kZWJ1Z2AgdG8gdGhlIHN1ZmZpeC5cbiAgICAgKlxuICAgICAqIFNvbWUgc2VydmljZXMgZG8gbm90IHN1cHBvcnQgdGhlIGBDdXN0b21TdWZmaXhgIHBhcmFtZXRlci4gSWYgeW91IHByb3ZpZGUgYW4gb3B0aW9uYWwgc3VmZml4IGFuZCB0aGUgb3BlcmF0aW9uIGZhaWxzLCB0cnkgdGhlIG9wZXJhdGlvbiBhZ2FpbiB3aXRob3V0IHRoZSBzdWZmaXguXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2VydmljZWxpbmtlZHJvbGUuaHRtbCNjZm4taWFtLXNlcnZpY2VsaW5rZWRyb2xlLWN1c3RvbXN1ZmZpeFxuICAgICAqL1xuICAgIHB1YmxpYyBjdXN0b21TdWZmaXg6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgcm9sZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2aWNlbGlua2Vkcm9sZS5odG1sI2Nmbi1pYW0tc2VydmljZWxpbmtlZHJvbGUtZGVzY3JpcHRpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgZGVzY3JpcHRpb246IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpJQU06OlNlcnZpY2VMaW5rZWRSb2xlYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5TZXJ2aWNlTGlua2VkUm9sZVByb3BzKSB7XG4gICAgICAgIHN1cGVyKHNjb3BlLCBpZCwgeyB0eXBlOiBDZm5TZXJ2aWNlTGlua2VkUm9sZS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ2F3c1NlcnZpY2VOYW1lJywgdGhpcyk7XG5cbiAgICAgICAgdGhpcy5hd3NTZXJ2aWNlTmFtZSA9IHByb3BzLmF3c1NlcnZpY2VOYW1lO1xuICAgICAgICB0aGlzLmN1c3RvbVN1ZmZpeCA9IHByb3BzLmN1c3RvbVN1ZmZpeDtcbiAgICAgICAgdGhpcy5kZXNjcmlwdGlvbiA9IHByb3BzLmRlc2NyaXB0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuU2VydmljZUxpbmtlZFJvbGUuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGF3c1NlcnZpY2VOYW1lOiB0aGlzLmF3c1NlcnZpY2VOYW1lLFxuICAgICAgICAgICAgY3VzdG9tU3VmZml4OiB0aGlzLmN1c3RvbVN1ZmZpeCxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiB0aGlzLmRlc2NyaXB0aW9uLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmblNlcnZpY2VMaW5rZWRSb2xlUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuVXNlcmBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tdXNlci5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuVXNlclByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiBncm91cCBuYW1lcyB0byB3aGljaCB5b3Ugd2FudCB0byBhZGQgdGhlIHVzZXIuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLmh0bWwjY2ZuLWlhbS11c2VyLWdyb3Vwc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IGdyb3Vwcz86IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHBhc3N3b3JkIGZvciB0aGUgc3BlY2lmaWVkIElBTSB1c2VyLiBBIHBhc3N3b3JkIGFsbG93cyBhbiBJQU0gdXNlciB0byBhY2Nlc3MgQVdTIHNlcnZpY2VzIHRocm91Z2ggdGhlIEFXUyBNYW5hZ2VtZW50IENvbnNvbGUgLlxuICAgICAqXG4gICAgICogWW91IGNhbiB1c2UgdGhlIEFXUyBDTEkgLCB0aGUgQVdTIEFQSSwgb3IgdGhlICpVc2VycyogcGFnZSBpbiB0aGUgSUFNIGNvbnNvbGUgdG8gY3JlYXRlIGEgcGFzc3dvcmQgZm9yIGFueSBJQU0gdXNlci4gVXNlIFtDaGFuZ2VQYXNzd29yZF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DaGFuZ2VQYXNzd29yZC5odG1sKSB0byB1cGRhdGUgeW91ciBvd24gZXhpc3RpbmcgcGFzc3dvcmQgaW4gdGhlICpNeSBTZWN1cml0eSBDcmVkZW50aWFscyogcGFnZSBpbiB0aGUgQVdTIE1hbmFnZW1lbnQgQ29uc29sZSAuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBtYW5hZ2luZyBwYXNzd29yZHMsIHNlZSBbTWFuYWdpbmcgcGFzc3dvcmRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvVXNpbmdfTWFuYWdpbmdMb2dpbnMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tdXNlci5odG1sI2Nmbi1pYW0tdXNlci1sb2dpbnByb2ZpbGVcbiAgICAgKi9cbiAgICByZWFkb25seSBsb2dpblByb2ZpbGU/OiBDZm5Vc2VyLkxvZ2luUHJvZmlsZVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIEFtYXpvbiBSZXNvdXJjZSBOYW1lcyAoQVJOcykgb2YgdGhlIElBTSBtYW5hZ2VkIHBvbGljaWVzIHRoYXQgeW91IHdhbnQgdG8gYXR0YWNoIHRvIHRoZSB1c2VyLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgQVJOcywgc2VlIFtBbWF6b24gUmVzb3VyY2UgTmFtZXMgKEFSTnMpIGFuZCBBV1MgU2VydmljZSBOYW1lc3BhY2VzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2VuZXJhbC9sYXRlc3QvZ3IvYXdzLWFybnMtYW5kLW5hbWVzcGFjZXMuaHRtbCkgaW4gdGhlICpBV1MgR2VuZXJhbCBSZWZlcmVuY2UqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXVzZXIuaHRtbCNjZm4taWFtLXVzZXItbWFuYWdlcG9saWN5YXJuc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IG1hbmFnZWRQb2xpY3lBcm5zPzogc3RyaW5nW107XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGF0aCBmb3IgdGhlIHVzZXIgbmFtZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgcGF0aHMsIHNlZSBbSUFNIGlkZW50aWZpZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvVXNpbmdfSWRlbnRpZmllcnMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgaXMgb3B0aW9uYWwuIElmIGl0IGlzIG5vdCBpbmNsdWRlZCwgaXQgZGVmYXVsdHMgdG8gYSBzbGFzaCAoLykuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgZWl0aGVyIGEgZm9yd2FyZCBzbGFzaCAoLykgYnkgaXRzZWxmIG9yIGEgc3RyaW5nIHRoYXQgbXVzdCBiZWdpbiBhbmQgZW5kIHdpdGggZm9yd2FyZCBzbGFzaGVzLiBJbiBhZGRpdGlvbiwgaXQgY2FuIGNvbnRhaW4gYW55IEFTQ0lJIGNoYXJhY3RlciBmcm9tIHRoZSAhICggYFxcIHUwMDIxYCApIHRocm91Z2ggdGhlIERFTCBjaGFyYWN0ZXIgKCBgXFwgdTAwN0ZgICksIGluY2x1ZGluZyBtb3N0IHB1bmN0dWF0aW9uIGNoYXJhY3RlcnMsIGRpZ2l0cywgYW5kIHVwcGVyIGFuZCBsb3dlcmNhc2VkIGxldHRlcnMuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLmh0bWwjY2ZuLWlhbS11c2VyLXBhdGhcbiAgICAgKi9cbiAgICByZWFkb25seSBwYXRoPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIEFSTiBvZiB0aGUgcG9saWN5IHRoYXQgaXMgdXNlZCB0byBzZXQgdGhlIHBlcm1pc3Npb25zIGJvdW5kYXJ5IGZvciB0aGUgdXNlci5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXVzZXIuaHRtbCNjZm4taWFtLXVzZXItcGVybWlzc2lvbnNib3VuZGFyeVxuICAgICAqL1xuICAgIHJlYWRvbmx5IHBlcm1pc3Npb25zQm91bmRhcnk/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIG9yIHVwZGF0ZXMgYW4gaW5saW5lIHBvbGljeSBkb2N1bWVudCB0aGF0IGlzIGVtYmVkZGVkIGluIHRoZSBzcGVjaWZpZWQgSUFNIHVzZXIuIFRvIHZpZXcgQVdTOjpJQU06OlVzZXIgc25pcHBldHMsIHNlZSBbRGVjbGFyaW5nIGFuIElBTSBVc2VyIFJlc291cmNlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9xdWlja3JlZi1pYW0uaHRtbCNzY2VuYXJpby1pYW0tdXNlcikgLlxuICAgICAqXG4gICAgICogPiBUaGUgbmFtZSBvZiBlYWNoIHBvbGljeSBmb3IgYSByb2xlLCB1c2VyLCBvciBncm91cCBtdXN0IGJlIHVuaXF1ZS4gSWYgeW91IGRvbid0IGNob29zZSB1bmlxdWUgbmFtZXMsIHVwZGF0ZXMgdG8gdGhlIElBTSBpZGVudGl0eSB3aWxsIGZhaWwuXG4gICAgICpcbiAgICAgKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgbGltaXRzIG9uIHRoZSBudW1iZXIgb2YgaW5saW5lIHBvbGljaWVzIHRoYXQgeW91IGNhbiBlbWJlZCBpbiBhIHVzZXIsIHNlZSBbTGltaXRhdGlvbnMgb24gSUFNIEVudGl0aWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvTGltaXRhdGlvbnNPbkVudGl0aWVzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXVzZXIuaHRtbCNjZm4taWFtLXVzZXItcG9saWNpZXNcbiAgICAgKi9cbiAgICByZWFkb25seSBwb2xpY2llcz86IEFycmF5PENmblVzZXIuUG9saWN5UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIHRhZ3MgdGhhdCB5b3Ugd2FudCB0byBhdHRhY2ggdG8gdGhlIG5ldyB1c2VyLiBFYWNoIHRhZyBjb25zaXN0cyBvZiBhIGtleSBuYW1lIGFuZCBhbiBhc3NvY2lhdGVkIHZhbHVlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0YWdnaW5nLCBzZWUgW1RhZ2dpbmcgSUFNIHJlc291cmNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX3RhZ3MuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogPiBJZiBhbnkgb25lIG9mIHRoZSB0YWdzIGlzIGludmFsaWQgb3IgaWYgeW91IGV4Y2VlZCB0aGUgYWxsb3dlZCBtYXhpbXVtIG51bWJlciBvZiB0YWdzLCB0aGVuIHRoZSBlbnRpcmUgcmVxdWVzdCBmYWlscyBhbmQgdGhlIHJlc291cmNlIGlzIG5vdCBjcmVhdGVkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tdXNlci5odG1sI2Nmbi1pYW0tdXNlci10YWdzXG4gICAgICovXG4gICAgcmVhZG9ubHkgdGFncz86IGNkay5DZm5UYWdbXTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSB1c2VyIHRvIGNyZWF0ZS4gRG8gbm90IGluY2x1ZGUgdGhlIHBhdGggaW4gdGhpcyB2YWx1ZS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAocGVyIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC0uIFRoZSB1c2VyIG5hbWUgbXVzdCBiZSB1bmlxdWUgd2l0aGluIHRoZSBhY2NvdW50LiBVc2VyIG5hbWVzIGFyZSBub3QgZGlzdGluZ3Vpc2hlZCBieSBjYXNlLiBGb3IgZXhhbXBsZSwgeW91IGNhbm5vdCBjcmVhdGUgdXNlcnMgbmFtZWQgYm90aCBcIkpvaG5cIiBhbmQgXCJqb2huXCIuXG4gICAgICpcbiAgICAgKiBJZiB5b3UgZG9uJ3Qgc3BlY2lmeSBhIG5hbWUsIEFXUyBDbG91ZEZvcm1hdGlvbiBnZW5lcmF0ZXMgYSB1bmlxdWUgcGh5c2ljYWwgSUQgYW5kIHVzZXMgdGhhdCBJRCBmb3IgdGhlIHVzZXIgbmFtZS5cbiAgICAgKlxuICAgICAqIElmIHlvdSBzcGVjaWZ5IGEgbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgYENBUEFCSUxJVFlfTkFNRURfSUFNYCB2YWx1ZSB0byBhY2tub3dsZWRnZSB5b3VyIHRlbXBsYXRlJ3MgY2FwYWJpbGl0aWVzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBY2tub3dsZWRnaW5nIElBTSBSZXNvdXJjZXMgaW4gQVdTIENsb3VkRm9ybWF0aW9uIFRlbXBsYXRlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvdXNpbmctaWFtLXRlbXBsYXRlLmh0bWwjdXNpbmctaWFtLWNhcGFiaWxpdGllcykgLlxuICAgICAqXG4gICAgICogPiBOYW1pbmcgYW4gSUFNIHJlc291cmNlIGNhbiBjYXVzZSBhbiB1bnJlY292ZXJhYmxlIGVycm9yIGlmIHlvdSByZXVzZSB0aGUgc2FtZSB0ZW1wbGF0ZSBpbiBtdWx0aXBsZSBSZWdpb25zLiBUbyBwcmV2ZW50IHRoaXMsIHdlIHJlY29tbWVuZCB1c2luZyBgRm46OkpvaW5gIGFuZCBgQVdTOjpSZWdpb25gIHRvIGNyZWF0ZSBhIFJlZ2lvbi1zcGVjaWZpYyBuYW1lLCBhcyBpbiB0aGUgZm9sbG93aW5nIGV4YW1wbGU6IGB7XCJGbjo6Sm9pblwiOiBbXCJcIiwgW3tcIlJlZlwiOiBcIkFXUzo6UmVnaW9uXCJ9LCB7XCJSZWZcIjogXCJNeVJlc291cmNlTmFtZVwifV1dfWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tdXNlci5odG1sI2Nmbi1pYW0tdXNlci11c2VybmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IHVzZXJOYW1lPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmblVzZXJQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuVXNlclByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblVzZXJQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2dyb3VwcycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMuZ3JvdXBzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdsb2dpblByb2ZpbGUnLCBDZm5Vc2VyX0xvZ2luUHJvZmlsZVByb3BlcnR5VmFsaWRhdG9yKShwcm9wZXJ0aWVzLmxvZ2luUHJvZmlsZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbWFuYWdlZFBvbGljeUFybnMnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLm1hbmFnZWRQb2xpY3lBcm5zKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwYXRoJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnBhdGgpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3Blcm1pc3Npb25zQm91bmRhcnknLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucGVybWlzc2lvbnNCb3VuZGFyeSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWNpZXMnLCBjZGsubGlzdFZhbGlkYXRvcihDZm5Vc2VyX1BvbGljeVByb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy5wb2xpY2llcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndGFncycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZUNmblRhZykpKHByb3BlcnRpZXMudGFncykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndXNlck5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMudXNlck5hbWUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuVXNlclByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlVzZXJgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblVzZXJQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpVc2VyYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblVzZXJQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVXNlclByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBHcm91cHM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmdyb3VwcyksXG4gICAgICAgIExvZ2luUHJvZmlsZTogY2ZuVXNlckxvZ2luUHJvZmlsZVByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmxvZ2luUHJvZmlsZSksXG4gICAgICAgIE1hbmFnZWRQb2xpY3lBcm5zOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5tYW5hZ2VkUG9saWN5QXJucyksXG4gICAgICAgIFBhdGg6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucGF0aCksXG4gICAgICAgIFBlcm1pc3Npb25zQm91bmRhcnk6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucGVybWlzc2lvbnNCb3VuZGFyeSksXG4gICAgICAgIFBvbGljaWVzOiBjZGsubGlzdE1hcHBlcihjZm5Vc2VyUG9saWN5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnBvbGljaWVzKSxcbiAgICAgICAgVGFnczogY2RrLmxpc3RNYXBwZXIoY2RrLmNmblRhZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMudGFncyksXG4gICAgICAgIFVzZXJOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnVzZXJOYW1lKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuVXNlclByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVXNlclByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5Vc2VyUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdncm91cHMnLCAnR3JvdXBzJywgcHJvcGVydGllcy5Hcm91cHMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5Hcm91cHMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2xvZ2luUHJvZmlsZScsICdMb2dpblByb2ZpbGUnLCBwcm9wZXJ0aWVzLkxvZ2luUHJvZmlsZSAhPSBudWxsID8gQ2ZuVXNlckxvZ2luUHJvZmlsZVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuTG9naW5Qcm9maWxlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtYW5hZ2VkUG9saWN5QXJucycsICdNYW5hZ2VkUG9saWN5QXJucycsIHByb3BlcnRpZXMuTWFuYWdlZFBvbGljeUFybnMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5NYW5hZ2VkUG9saWN5QXJucykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncGF0aCcsICdQYXRoJywgcHJvcGVydGllcy5QYXRoICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlBhdGgpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3Blcm1pc3Npb25zQm91bmRhcnknLCAnUGVybWlzc2lvbnNCb3VuZGFyeScsIHByb3BlcnRpZXMuUGVybWlzc2lvbnNCb3VuZGFyeSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5QZXJtaXNzaW9uc0JvdW5kYXJ5KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwb2xpY2llcycsICdQb2xpY2llcycsIHByb3BlcnRpZXMuUG9saWNpZXMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuVXNlclBvbGljeVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLlBvbGljaWVzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0YWdzJywgJ1RhZ3MnLCBwcm9wZXJ0aWVzLlRhZ3MgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRDZm5UYWcpKHByb3BlcnRpZXMuVGFncykgOiB1bmRlZmluZWQgYXMgYW55KTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3VzZXJOYW1lJywgJ1VzZXJOYW1lJywgcHJvcGVydGllcy5Vc2VyTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Vc2VyTmFtZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6SUFNOjpVc2VyYFxuICpcbiAqIENyZWF0ZXMgYSBuZXcgSUFNIHVzZXIgZm9yIHlvdXIgQVdTIGFjY291bnQgLlxuICpcbiAqIEZvciBpbmZvcm1hdGlvbiBhYm91dCBxdW90YXMgZm9yIHRoZSBudW1iZXIgb2YgSUFNIHVzZXJzIHlvdSBjYW4gY3JlYXRlLCBzZWUgW0lBTSBhbmQgQVdTIFNUUyBxdW90YXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfaWFtLXF1b3Rhcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpJQU06OlVzZXJcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmblVzZXIgZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpJQU06OlVzZXJcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmblVzZXIge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmblVzZXJQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuVXNlcihzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBmb3IgdGhlIHNwZWNpZmllZCBgQVdTOjpJQU06OlVzZXJgIHJlc291cmNlLiBGb3IgZXhhbXBsZTogYGFybjphd3M6aWFtOjoxMjM0NTY3ODkwMTI6dXNlci9teXN0YWNrLW15dXNlci0xQ0NYQUZHMkgyVTREYCAuXG4gICAgICogQGNsb3VkZm9ybWF0aW9uQXR0cmlidXRlIEFyblxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBhdHRyQXJuOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgZ3JvdXAgbmFtZXMgdG8gd2hpY2ggeW91IHdhbnQgdG8gYWRkIHRoZSB1c2VyLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tdXNlci5odG1sI2Nmbi1pYW0tdXNlci1ncm91cHNcbiAgICAgKi9cbiAgICBwdWJsaWMgZ3JvdXBzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwYXNzd29yZCBmb3IgdGhlIHNwZWNpZmllZCBJQU0gdXNlci4gQSBwYXNzd29yZCBhbGxvd3MgYW4gSUFNIHVzZXIgdG8gYWNjZXNzIEFXUyBzZXJ2aWNlcyB0aHJvdWdoIHRoZSBBV1MgTWFuYWdlbWVudCBDb25zb2xlIC5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4gdXNlIHRoZSBBV1MgQ0xJICwgdGhlIEFXUyBBUEksIG9yIHRoZSAqVXNlcnMqIHBhZ2UgaW4gdGhlIElBTSBjb25zb2xlIHRvIGNyZWF0ZSBhIHBhc3N3b3JkIGZvciBhbnkgSUFNIHVzZXIuIFVzZSBbQ2hhbmdlUGFzc3dvcmRdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ2hhbmdlUGFzc3dvcmQuaHRtbCkgdG8gdXBkYXRlIHlvdXIgb3duIGV4aXN0aW5nIHBhc3N3b3JkIGluIHRoZSAqTXkgU2VjdXJpdHkgQ3JlZGVudGlhbHMqIHBhZ2UgaW4gdGhlIEFXUyBNYW5hZ2VtZW50IENvbnNvbGUgLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgbWFuYWdpbmcgcGFzc3dvcmRzLCBzZWUgW01hbmFnaW5nIHBhc3N3b3Jkc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL1VzaW5nX01hbmFnaW5nTG9naW5zLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXVzZXIuaHRtbCNjZm4taWFtLXVzZXItbG9naW5wcm9maWxlXG4gICAgICovXG4gICAgcHVibGljIGxvZ2luUHJvZmlsZTogQ2ZuVXNlci5Mb2dpblByb2ZpbGVQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiBBbWF6b24gUmVzb3VyY2UgTmFtZXMgKEFSTnMpIG9mIHRoZSBJQU0gbWFuYWdlZCBwb2xpY2llcyB0aGF0IHlvdSB3YW50IHRvIGF0dGFjaCB0byB0aGUgdXNlci5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IEFSTnMsIHNlZSBbQW1hem9uIFJlc291cmNlIE5hbWVzIChBUk5zKSBhbmQgQVdTIFNlcnZpY2UgTmFtZXNwYWNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dlbmVyYWwvbGF0ZXN0L2dyL2F3cy1hcm5zLWFuZC1uYW1lc3BhY2VzLmh0bWwpIGluIHRoZSAqQVdTIEdlbmVyYWwgUmVmZXJlbmNlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLmh0bWwjY2ZuLWlhbS11c2VyLW1hbmFnZXBvbGljeWFybnNcbiAgICAgKi9cbiAgICBwdWJsaWMgbWFuYWdlZFBvbGljeUFybnM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBhdGggZm9yIHRoZSB1c2VyIG5hbWUuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHBhdGhzLCBzZWUgW0lBTSBpZGVudGlmaWVyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL1VzaW5nX0lkZW50aWZpZXJzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGlzIG9wdGlvbmFsLiBJZiBpdCBpcyBub3QgaW5jbHVkZWQsIGl0IGRlZmF1bHRzIHRvIGEgc2xhc2ggKC8pLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIGVpdGhlciBhIGZvcndhcmQgc2xhc2ggKC8pIGJ5IGl0c2VsZiBvciBhIHN0cmluZyB0aGF0IG11c3QgYmVnaW4gYW5kIGVuZCB3aXRoIGZvcndhcmQgc2xhc2hlcy4gSW4gYWRkaXRpb24sIGl0IGNhbiBjb250YWluIGFueSBBU0NJSSBjaGFyYWN0ZXIgZnJvbSB0aGUgISAoIGBcXCB1MDAyMWAgKSB0aHJvdWdoIHRoZSBERUwgY2hhcmFjdGVyICggYFxcIHUwMDdGYCApLCBpbmNsdWRpbmcgbW9zdCBwdW5jdHVhdGlvbiBjaGFyYWN0ZXJzLCBkaWdpdHMsIGFuZCB1cHBlciBhbmQgbG93ZXJjYXNlZCBsZXR0ZXJzLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tdXNlci5odG1sI2Nmbi1pYW0tdXNlci1wYXRoXG4gICAgICovXG4gICAgcHVibGljIHBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBBUk4gb2YgdGhlIHBvbGljeSB0aGF0IGlzIHVzZWQgdG8gc2V0IHRoZSBwZXJtaXNzaW9ucyBib3VuZGFyeSBmb3IgdGhlIHVzZXIuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLmh0bWwjY2ZuLWlhbS11c2VyLXBlcm1pc3Npb25zYm91bmRhcnlcbiAgICAgKi9cbiAgICBwdWJsaWMgcGVybWlzc2lvbnNCb3VuZGFyeTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBvciB1cGRhdGVzIGFuIGlubGluZSBwb2xpY3kgZG9jdW1lbnQgdGhhdCBpcyBlbWJlZGRlZCBpbiB0aGUgc3BlY2lmaWVkIElBTSB1c2VyLiBUbyB2aWV3IEFXUzo6SUFNOjpVc2VyIHNuaXBwZXRzLCBzZWUgW0RlY2xhcmluZyBhbiBJQU0gVXNlciBSZXNvdXJjZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvcXVpY2tyZWYtaWFtLmh0bWwjc2NlbmFyaW8taWFtLXVzZXIpIC5cbiAgICAgKlxuICAgICAqID4gVGhlIG5hbWUgb2YgZWFjaCBwb2xpY3kgZm9yIGEgcm9sZSwgdXNlciwgb3IgZ3JvdXAgbXVzdCBiZSB1bmlxdWUuIElmIHlvdSBkb24ndCBjaG9vc2UgdW5pcXVlIG5hbWVzLCB1cGRhdGVzIHRvIHRoZSBJQU0gaWRlbnRpdHkgd2lsbCBmYWlsLlxuICAgICAqXG4gICAgICogRm9yIGluZm9ybWF0aW9uIGFib3V0IGxpbWl0cyBvbiB0aGUgbnVtYmVyIG9mIGlubGluZSBwb2xpY2llcyB0aGF0IHlvdSBjYW4gZW1iZWQgaW4gYSB1c2VyLCBzZWUgW0xpbWl0YXRpb25zIG9uIElBTSBFbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL0xpbWl0YXRpb25zT25FbnRpdGllcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLmh0bWwjY2ZuLWlhbS11c2VyLXBvbGljaWVzXG4gICAgICovXG4gICAgcHVibGljIHBvbGljaWVzOiBBcnJheTxDZm5Vc2VyLlBvbGljeVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiB0YWdzIHRoYXQgeW91IHdhbnQgdG8gYXR0YWNoIHRvIHRoZSBuZXcgdXNlci4gRWFjaCB0YWcgY29uc2lzdHMgb2YgYSBrZXkgbmFtZSBhbmQgYW4gYXNzb2NpYXRlZCB2YWx1ZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGFnZ2luZywgc2VlIFtUYWdnaW5nIElBTSByZXNvdXJjZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF90YWdzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqID4gSWYgYW55IG9uZSBvZiB0aGUgdGFncyBpcyBpbnZhbGlkIG9yIGlmIHlvdSBleGNlZWQgdGhlIGFsbG93ZWQgbWF4aW11bSBudW1iZXIgb2YgdGFncywgdGhlbiB0aGUgZW50aXJlIHJlcXVlc3QgZmFpbHMgYW5kIHRoZSByZXNvdXJjZSBpcyBub3QgY3JlYXRlZC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXVzZXIuaHRtbCNjZm4taWFtLXVzZXItdGFnc1xuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB0YWdzOiBjZGsuVGFnTWFuYWdlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSB1c2VyIHRvIGNyZWF0ZS4gRG8gbm90IGluY2x1ZGUgdGhlIHBhdGggaW4gdGhpcyB2YWx1ZS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAocGVyIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC0uIFRoZSB1c2VyIG5hbWUgbXVzdCBiZSB1bmlxdWUgd2l0aGluIHRoZSBhY2NvdW50LiBVc2VyIG5hbWVzIGFyZSBub3QgZGlzdGluZ3Vpc2hlZCBieSBjYXNlLiBGb3IgZXhhbXBsZSwgeW91IGNhbm5vdCBjcmVhdGUgdXNlcnMgbmFtZWQgYm90aCBcIkpvaG5cIiBhbmQgXCJqb2huXCIuXG4gICAgICpcbiAgICAgKiBJZiB5b3UgZG9uJ3Qgc3BlY2lmeSBhIG5hbWUsIEFXUyBDbG91ZEZvcm1hdGlvbiBnZW5lcmF0ZXMgYSB1bmlxdWUgcGh5c2ljYWwgSUQgYW5kIHVzZXMgdGhhdCBJRCBmb3IgdGhlIHVzZXIgbmFtZS5cbiAgICAgKlxuICAgICAqIElmIHlvdSBzcGVjaWZ5IGEgbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgYENBUEFCSUxJVFlfTkFNRURfSUFNYCB2YWx1ZSB0byBhY2tub3dsZWRnZSB5b3VyIHRlbXBsYXRlJ3MgY2FwYWJpbGl0aWVzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBY2tub3dsZWRnaW5nIElBTSBSZXNvdXJjZXMgaW4gQVdTIENsb3VkRm9ybWF0aW9uIFRlbXBsYXRlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvdXNpbmctaWFtLXRlbXBsYXRlLmh0bWwjdXNpbmctaWFtLWNhcGFiaWxpdGllcykgLlxuICAgICAqXG4gICAgICogPiBOYW1pbmcgYW4gSUFNIHJlc291cmNlIGNhbiBjYXVzZSBhbiB1bnJlY292ZXJhYmxlIGVycm9yIGlmIHlvdSByZXVzZSB0aGUgc2FtZSB0ZW1wbGF0ZSBpbiBtdWx0aXBsZSBSZWdpb25zLiBUbyBwcmV2ZW50IHRoaXMsIHdlIHJlY29tbWVuZCB1c2luZyBgRm46OkpvaW5gIGFuZCBgQVdTOjpSZWdpb25gIHRvIGNyZWF0ZSBhIFJlZ2lvbi1zcGVjaWZpYyBuYW1lLCBhcyBpbiB0aGUgZm9sbG93aW5nIGV4YW1wbGU6IGB7XCJGbjo6Sm9pblwiOiBbXCJcIiwgW3tcIlJlZlwiOiBcIkFXUzo6UmVnaW9uXCJ9LCB7XCJSZWZcIjogXCJNeVJlc291cmNlTmFtZVwifV1dfWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tdXNlci5odG1sI2Nmbi1pYW0tdXNlci11c2VybmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyB1c2VyTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGBBV1M6OklBTTo6VXNlcmAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuVXNlclByb3BzID0ge30pIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmblVzZXIuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIHRoaXMuYXR0ckFybiA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnQXJuJykpO1xuXG4gICAgICAgIHRoaXMuZ3JvdXBzID0gcHJvcHMuZ3JvdXBzO1xuICAgICAgICB0aGlzLmxvZ2luUHJvZmlsZSA9IHByb3BzLmxvZ2luUHJvZmlsZTtcbiAgICAgICAgdGhpcy5tYW5hZ2VkUG9saWN5QXJucyA9IHByb3BzLm1hbmFnZWRQb2xpY3lBcm5zO1xuICAgICAgICB0aGlzLnBhdGggPSBwcm9wcy5wYXRoO1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25zQm91bmRhcnkgPSBwcm9wcy5wZXJtaXNzaW9uc0JvdW5kYXJ5O1xuICAgICAgICB0aGlzLnBvbGljaWVzID0gcHJvcHMucG9saWNpZXM7XG4gICAgICAgIHRoaXMudGFncyA9IG5ldyBjZGsuVGFnTWFuYWdlcihjZGsuVGFnVHlwZS5TVEFOREFSRCwgXCJBV1M6OklBTTo6VXNlclwiLCBwcm9wcy50YWdzLCB7IHRhZ1Byb3BlcnR5TmFtZTogJ3RhZ3MnIH0pO1xuICAgICAgICB0aGlzLnVzZXJOYW1lID0gcHJvcHMudXNlck5hbWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5Vc2VyLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBncm91cHM6IHRoaXMuZ3JvdXBzLFxuICAgICAgICAgICAgbG9naW5Qcm9maWxlOiB0aGlzLmxvZ2luUHJvZmlsZSxcbiAgICAgICAgICAgIG1hbmFnZWRQb2xpY3lBcm5zOiB0aGlzLm1hbmFnZWRQb2xpY3lBcm5zLFxuICAgICAgICAgICAgcGF0aDogdGhpcy5wYXRoLFxuICAgICAgICAgICAgcGVybWlzc2lvbnNCb3VuZGFyeTogdGhpcy5wZXJtaXNzaW9uc0JvdW5kYXJ5LFxuICAgICAgICAgICAgcG9saWNpZXM6IHRoaXMucG9saWNpZXMsXG4gICAgICAgICAgICB0YWdzOiB0aGlzLnRhZ3MucmVuZGVyVGFncygpLFxuICAgICAgICAgICAgdXNlck5hbWU6IHRoaXMudXNlck5hbWUsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuVXNlclByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblVzZXIge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwYXNzd29yZCBmb3IgdGhlIHNwZWNpZmllZCB1c2VyLCBnaXZpbmcgdGhlIHVzZXIgdGhlIGFiaWxpdHkgdG8gYWNjZXNzIEFXUyBzZXJ2aWNlcyB0aHJvdWdoIHRoZSBBV1MgTWFuYWdlbWVudCBDb25zb2xlIC4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgbWFuYWdpbmcgcGFzc3dvcmRzLCBzZWUgW01hbmFnaW5nIFBhc3N3b3Jkc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL1VzaW5nX01hbmFnaW5nTG9naW5zLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLWxvZ2lucHJvZmlsZS5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBMb2dpblByb2ZpbGVQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdXNlcidzIHBhc3N3b3JkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLWxvZ2lucHJvZmlsZS5odG1sI2Nmbi1pYW0tdXNlci1sb2dpbnByb2ZpbGUtcGFzc3dvcmRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHBhc3N3b3JkOiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTcGVjaWZpZXMgd2hldGhlciB0aGUgdXNlciBpcyByZXF1aXJlZCB0byBzZXQgYSBuZXcgcGFzc3dvcmQgb24gbmV4dCBzaWduLWluLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLWxvZ2lucHJvZmlsZS5odG1sI2Nmbi1pYW0tdXNlci1sb2dpbnByb2ZpbGUtcGFzc3dvcmRyZXNldHJlcXVpcmVkXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBwYXNzd29yZFJlc2V0UmVxdWlyZWQ/OiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBMb2dpblByb2ZpbGVQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgTG9naW5Qcm9maWxlUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVXNlcl9Mb2dpblByb2ZpbGVQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3Bhc3N3b3JkJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnBhc3N3b3JkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwYXNzd29yZCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5wYXNzd29yZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncGFzc3dvcmRSZXNldFJlcXVpcmVkJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5wYXNzd29yZFJlc2V0UmVxdWlyZWQpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiTG9naW5Qcm9maWxlUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6VXNlci5Mb2dpblByb2ZpbGVgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYExvZ2luUHJvZmlsZVByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlVzZXIuTG9naW5Qcm9maWxlYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblVzZXJMb2dpblByb2ZpbGVQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVXNlcl9Mb2dpblByb2ZpbGVQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgUGFzc3dvcmQ6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucGFzc3dvcmQpLFxuICAgICAgICBQYXNzd29yZFJlc2V0UmVxdWlyZWQ6IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBhc3N3b3JkUmVzZXRSZXF1aXJlZCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblVzZXJMb2dpblByb2ZpbGVQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblVzZXIuTG9naW5Qcm9maWxlUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVXNlci5Mb2dpblByb2ZpbGVQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3Bhc3N3b3JkJywgJ1Bhc3N3b3JkJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5QYXNzd29yZCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncGFzc3dvcmRSZXNldFJlcXVpcmVkJywgJ1Bhc3N3b3JkUmVzZXRSZXF1aXJlZCcsIHByb3BlcnRpZXMuUGFzc3dvcmRSZXNldFJlcXVpcmVkICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5QYXNzd29yZFJlc2V0UmVxdWlyZWQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5Vc2VyIHtcbiAgICAvKipcbiAgICAgKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBhbiBhdHRhY2hlZCBwb2xpY3kuXG4gICAgICpcbiAgICAgKiBBbiBhdHRhY2hlZCBwb2xpY3kgaXMgYSBtYW5hZ2VkIHBvbGljeSB0aGF0IGhhcyBiZWVuIGF0dGFjaGVkIHRvIGEgdXNlciwgZ3JvdXAsIG9yIHJvbGUuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBtYW5hZ2VkIHBvbGljaWVzLCByZWZlciB0byBbTWFuYWdlZCBQb2xpY2llcyBhbmQgSW5saW5lIFBvbGljaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcG9saWNpZXMtbWFuYWdlZC12cy1pbmxpbmUuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXBvbGljeS5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBQb2xpY3lQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcG9saWN5IGRvY3VtZW50LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1wb2xpY3kuaHRtbCNjZm4taWFtLXBvbGljaWVzLXBvbGljeWRvY3VtZW50XG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBwb2xpY3lEb2N1bWVudDogYW55IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGZyaWVuZGx5IG5hbWUgKG5vdCBBUk4pIGlkZW50aWZ5aW5nIHRoZSBwb2xpY3kuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXBvbGljeS5odG1sI2Nmbi1pYW0tcG9saWNpZXMtcG9saWN5bmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcG9saWN5TmFtZTogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBQb2xpY3lQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgUG9saWN5UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVXNlcl9Qb2xpY3lQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvbGljeURvY3VtZW50JywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnBvbGljeURvY3VtZW50KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb2xpY3lEb2N1bWVudCcsIGNkay52YWxpZGF0ZU9iamVjdCkocHJvcGVydGllcy5wb2xpY3lEb2N1bWVudCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5TmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5wb2xpY3lOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb2xpY3lOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnBvbGljeU5hbWUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiUG9saWN5UHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6VXNlci5Qb2xpY3lgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFBvbGljeVByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlVzZXIuUG9saWN5YCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblVzZXJQb2xpY3lQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVXNlcl9Qb2xpY3lQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgUG9saWN5RG9jdW1lbnQ6IGNkay5vYmplY3RUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucG9saWN5RG9jdW1lbnQpLFxuICAgICAgICBQb2xpY3lOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBvbGljeU5hbWUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5Vc2VyUG9saWN5UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5Vc2VyLlBvbGljeVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblVzZXIuUG9saWN5UHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwb2xpY3lEb2N1bWVudCcsICdQb2xpY3lEb2N1bWVudCcsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QW55KHByb3BlcnRpZXMuUG9saWN5RG9jdW1lbnQpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BvbGljeU5hbWUnLCAnUG9saWN5TmFtZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUG9saWN5TmFtZSkpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmblVzZXJUb0dyb3VwQWRkaXRpb25gXG4gKlxuICogQHN0cnVjdFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLWFkZHVzZXJ0b2dyb3VwLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5Vc2VyVG9Hcm91cEFkZGl0aW9uUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGdyb3VwIHRvIHVwZGF0ZS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1hZGR1c2VydG9ncm91cC5odG1sI2Nmbi1pYW0tYWRkdXNlcnRvZ3JvdXAtZ3JvdXBuYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgZ3JvdXBOYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgdGhlIG5hbWVzIG9mIHRoZSB1c2VycyB0aGF0IHlvdSB3YW50IHRvIGFkZCB0byB0aGUgZ3JvdXAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1hZGR1c2VydG9ncm91cC5odG1sI2Nmbi1pYW0tYWRkdXNlcnRvZ3JvdXAtdXNlcnNcbiAgICAgKi9cbiAgICByZWFkb25seSB1c2Vyczogc3RyaW5nW107XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2ZuVXNlclRvR3JvdXBBZGRpdGlvblByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5Vc2VyVG9Hcm91cEFkZGl0aW9uUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVXNlclRvR3JvdXBBZGRpdGlvblByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZ3JvdXBOYW1lJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmdyb3VwTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZ3JvdXBOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmdyb3VwTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndXNlcnMnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMudXNlcnMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3VzZXJzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy51c2VycykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5Vc2VyVG9Hcm91cEFkZGl0aW9uUHJvcHNcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6VXNlclRvR3JvdXBBZGRpdGlvbmAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuVXNlclRvR3JvdXBBZGRpdGlvblByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlVzZXJUb0dyb3VwQWRkaXRpb25gIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVXNlclRvR3JvdXBBZGRpdGlvblByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5Vc2VyVG9Hcm91cEFkZGl0aW9uUHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEdyb3VwTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5ncm91cE5hbWUpLFxuICAgICAgICBVc2VyczogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMudXNlcnMpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5Vc2VyVG9Hcm91cEFkZGl0aW9uUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5Vc2VyVG9Hcm91cEFkZGl0aW9uUHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblVzZXJUb0dyb3VwQWRkaXRpb25Qcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2dyb3VwTmFtZScsICdHcm91cE5hbWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkdyb3VwTmFtZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndXNlcnMnLCAnVXNlcnMnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuVXNlcnMpKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBBIENsb3VkRm9ybWF0aW9uIGBBV1M6OklBTTo6VXNlclRvR3JvdXBBZGRpdGlvbmBcbiAqXG4gKiBBZGRzIHRoZSBzcGVjaWZpZWQgdXNlciB0byB0aGUgc3BlY2lmaWVkIGdyb3VwLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6SUFNOjpVc2VyVG9Hcm91cEFkZGl0aW9uXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tYWRkdXNlcnRvZ3JvdXAuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuVXNlclRvR3JvdXBBZGRpdGlvbiBleHRlbmRzIGNkay5DZm5SZXNvdXJjZSBpbXBsZW1lbnRzIGNkay5JSW5zcGVjdGFibGUge1xuICAgIC8qKlxuICAgICAqIFRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIG5hbWUgZm9yIHRoaXMgcmVzb3VyY2UgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBDRk5fUkVTT1VSQ0VfVFlQRV9OQU1FID0gXCJBV1M6OklBTTo6VXNlclRvR3JvdXBBZGRpdGlvblwiO1xuXG4gICAgLyoqXG4gICAgICogQSBmYWN0b3J5IG1ldGhvZCB0aGF0IGNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmcm9tIGFuIG9iamVjdFxuICAgICAqIGNvbnRhaW5pbmcgdGhlIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgdGhpcyByZXNvdXJjZS5cbiAgICAgKiBVc2VkIGluIHRoZSBAYXdzLWNkay9jbG91ZGZvcm1hdGlvbi1pbmNsdWRlIG1vZHVsZS5cbiAgICAgKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgX2Zyb21DbG91ZEZvcm1hdGlvbihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcmVzb3VyY2VBdHRyaWJ1dGVzOiBhbnksIG9wdGlvbnM6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25PcHRpb25zKTogQ2ZuVXNlclRvR3JvdXBBZGRpdGlvbiB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuVXNlclRvR3JvdXBBZGRpdGlvblByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5Vc2VyVG9Hcm91cEFkZGl0aW9uKHNjb3BlLCBpZCwgcHJvcHNSZXN1bHQudmFsdWUpO1xuICAgICAgICBmb3IgKGNvbnN0IFtwcm9wS2V5LCBwcm9wVmFsXSBvZiBPYmplY3QuZW50cmllcyhwcm9wc1Jlc3VsdC5leHRyYVByb3BlcnRpZXMpKSAge1xuICAgICAgICAgICAgcmV0LmFkZFByb3BlcnR5T3ZlcnJpZGUocHJvcEtleSwgcHJvcFZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5wYXJzZXIuaGFuZGxlQXR0cmlidXRlcyhyZXQsIHJlc291cmNlQXR0cmlidXRlcywgaWQpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBncm91cCB0byB1cGRhdGUuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdXBwZXIgYW5kIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyB3aXRoIG5vIHNwYWNlcy4gWW91IGNhbiBhbHNvIGluY2x1ZGUgYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogXys9LC5ALVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tYWRkdXNlcnRvZ3JvdXAuaHRtbCNjZm4taWFtLWFkZHVzZXJ0b2dyb3VwLWdyb3VwbmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyBncm91cE5hbWU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiB0aGUgbmFtZXMgb2YgdGhlIHVzZXJzIHRoYXQgeW91IHdhbnQgdG8gYWRkIHRvIHRoZSBncm91cC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLWFkZHVzZXJ0b2dyb3VwLmh0bWwjY2ZuLWlhbS1hZGR1c2VydG9ncm91cC11c2Vyc1xuICAgICAqL1xuICAgIHB1YmxpYyB1c2Vyczogc3RyaW5nW107XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6SUFNOjpVc2VyVG9Hcm91cEFkZGl0aW9uYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5Vc2VyVG9Hcm91cEFkZGl0aW9uUHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmblVzZXJUb0dyb3VwQWRkaXRpb24uQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICdncm91cE5hbWUnLCB0aGlzKTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ3VzZXJzJywgdGhpcyk7XG5cbiAgICAgICAgdGhpcy5ncm91cE5hbWUgPSBwcm9wcy5ncm91cE5hbWU7XG4gICAgICAgIHRoaXMudXNlcnMgPSBwcm9wcy51c2VycztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmblVzZXJUb0dyb3VwQWRkaXRpb24uQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGdyb3VwTmFtZTogdGhpcy5ncm91cE5hbWUsXG4gICAgICAgICAgICB1c2VyczogdGhpcy51c2VycyxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5Vc2VyVG9Hcm91cEFkZGl0aW9uUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuVmlydHVhbE1GQURldmljZWBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXZpcnR1YWxtZmFkZXZpY2UuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmblZpcnR1YWxNRkFEZXZpY2VQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgSUFNIHVzZXIgYXNzb2NpYXRlZCB3aXRoIHRoaXMgdmlydHVhbCBNRkEgZGV2aWNlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXZpcnR1YWxtZmFkZXZpY2UuaHRtbCNjZm4taWFtLXZpcnR1YWxtZmFkZXZpY2UtdXNlcnNcbiAgICAgKi9cbiAgICByZWFkb25seSB1c2Vyczogc3RyaW5nW107XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGF0aCBmb3IgdGhlIHZpcnR1YWwgTUZBIGRldmljZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgcGF0aHMsIHNlZSBbSUFNIGlkZW50aWZpZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvVXNpbmdfSWRlbnRpZmllcnMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgaXMgb3B0aW9uYWwuIElmIGl0IGlzIG5vdCBpbmNsdWRlZCwgaXQgZGVmYXVsdHMgdG8gYSBzbGFzaCAoLykuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgZWl0aGVyIGEgZm9yd2FyZCBzbGFzaCAoLykgYnkgaXRzZWxmIG9yIGEgc3RyaW5nIHRoYXQgbXVzdCBiZWdpbiBhbmQgZW5kIHdpdGggZm9yd2FyZCBzbGFzaGVzLiBJbiBhZGRpdGlvbiwgaXQgY2FuIGNvbnRhaW4gYW55IEFTQ0lJIGNoYXJhY3RlciBmcm9tIHRoZSAhICggYFxcIHUwMDIxYCApIHRocm91Z2ggdGhlIERFTCBjaGFyYWN0ZXIgKCBgXFwgdTAwN0ZgICksIGluY2x1ZGluZyBtb3N0IHB1bmN0dWF0aW9uIGNoYXJhY3RlcnMsIGRpZ2l0cywgYW5kIHVwcGVyIGFuZCBsb3dlcmNhc2VkIGxldHRlcnMuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tdmlydHVhbG1mYWRldmljZS5odG1sI2Nmbi1pYW0tdmlydHVhbG1mYWRldmljZS1wYXRoXG4gICAgICovXG4gICAgcmVhZG9ubHkgcGF0aD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiB0YWdzIHRoYXQgeW91IHdhbnQgdG8gYXR0YWNoIHRvIHRoZSBuZXcgSUFNIHZpcnR1YWwgTUZBIGRldmljZS4gRWFjaCB0YWcgY29uc2lzdHMgb2YgYSBrZXkgbmFtZSBhbmQgYW4gYXNzb2NpYXRlZCB2YWx1ZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGFnZ2luZywgc2VlIFtUYWdnaW5nIElBTSByZXNvdXJjZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF90YWdzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqID4gSWYgYW55IG9uZSBvZiB0aGUgdGFncyBpcyBpbnZhbGlkIG9yIGlmIHlvdSBleGNlZWQgdGhlIGFsbG93ZWQgbWF4aW11bSBudW1iZXIgb2YgdGFncywgdGhlbiB0aGUgZW50aXJlIHJlcXVlc3QgZmFpbHMgYW5kIHRoZSByZXNvdXJjZSBpcyBub3QgY3JlYXRlZC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS12aXJ0dWFsbWZhZGV2aWNlLmh0bWwjY2ZuLWlhbS12aXJ0dWFsbWZhZGV2aWNlLXRhZ3NcbiAgICAgKi9cbiAgICByZWFkb25seSB0YWdzPzogY2RrLkNmblRhZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHZpcnR1YWwgTUZBIGRldmljZS4gVXNlIHdpdGggcGF0aCB0byB1bmlxdWVseSBpZGVudGlmeSBhIHZpcnR1YWwgTUZBIGRldmljZS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tdmlydHVhbG1mYWRldmljZS5odG1sI2Nmbi1pYW0tdmlydHVhbG1mYWRldmljZS12aXJ0dWFsbWZhZGV2aWNlbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IHZpcnR1YWxNZmFEZXZpY2VOYW1lPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmblZpcnR1YWxNRkFEZXZpY2VQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuVmlydHVhbE1GQURldmljZVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblZpcnR1YWxNRkFEZXZpY2VQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BhdGgnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucGF0aCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndGFncycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZUNmblRhZykpKHByb3BlcnRpZXMudGFncykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndXNlcnMnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMudXNlcnMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3VzZXJzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy51c2VycykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndmlydHVhbE1mYURldmljZU5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMudmlydHVhbE1mYURldmljZU5hbWUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuVmlydHVhbE1GQURldmljZVByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlZpcnR1YWxNRkFEZXZpY2VgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblZpcnR1YWxNRkFEZXZpY2VQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpWaXJ0dWFsTUZBRGV2aWNlYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblZpcnR1YWxNRkFEZXZpY2VQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVmlydHVhbE1GQURldmljZVByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBVc2VyczogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMudXNlcnMpLFxuICAgICAgICBQYXRoOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBhdGgpLFxuICAgICAgICBUYWdzOiBjZGsubGlzdE1hcHBlcihjZGsuY2ZuVGFnVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy50YWdzKSxcbiAgICAgICAgVmlydHVhbE1mYURldmljZU5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudmlydHVhbE1mYURldmljZU5hbWUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5WaXJ0dWFsTUZBRGV2aWNlUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5WaXJ0dWFsTUZBRGV2aWNlUHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblZpcnR1YWxNRkFEZXZpY2VQcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3VzZXJzJywgJ1VzZXJzJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmdBcnJheShwcm9wZXJ0aWVzLlVzZXJzKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwYXRoJywgJ1BhdGgnLCBwcm9wZXJ0aWVzLlBhdGggIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUGF0aCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndGFncycsICdUYWdzJywgcHJvcGVydGllcy5UYWdzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Q2ZuVGFnKShwcm9wZXJ0aWVzLlRhZ3MpIDogdW5kZWZpbmVkIGFzIGFueSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd2aXJ0dWFsTWZhRGV2aWNlTmFtZScsICdWaXJ0dWFsTWZhRGV2aWNlTmFtZScsIHByb3BlcnRpZXMuVmlydHVhbE1mYURldmljZU5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVmlydHVhbE1mYURldmljZU5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBBIENsb3VkRm9ybWF0aW9uIGBBV1M6OklBTTo6VmlydHVhbE1GQURldmljZWBcbiAqXG4gKiBDcmVhdGVzIGEgbmV3IHZpcnR1YWwgTUZBIGRldmljZSBmb3IgdGhlIEFXUyBhY2NvdW50IC4gQWZ0ZXIgY3JlYXRpbmcgdGhlIHZpcnR1YWwgTUZBLCB1c2UgW0VuYWJsZU1GQURldmljZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9FbmFibGVNRkFEZXZpY2UuaHRtbCkgdG8gYXR0YWNoIHRoZSBNRkEgZGV2aWNlIHRvIGFuIElBTSB1c2VyLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBjcmVhdGluZyBhbmQgd29ya2luZyB3aXRoIHZpcnR1YWwgTUZBIGRldmljZXMsIHNlZSBbVXNpbmcgYSB2aXJ0dWFsIE1GQSBkZXZpY2VdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19WaXJ0dWFsTUZBLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAqXG4gKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG1heGltdW0gbnVtYmVyIG9mIE1GQSBkZXZpY2VzIHlvdSBjYW4gY3JlYXRlLCBzZWUgW0lBTSBhbmQgQVdTIFNUUyBxdW90YXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfaWFtLXF1b3Rhcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gKlxuICogPiBUaGUgc2VlZCBpbmZvcm1hdGlvbiBjb250YWluZWQgaW4gdGhlIFFSIGNvZGUgYW5kIHRoZSBCYXNlMzIgc3RyaW5nIHNob3VsZCBiZSB0cmVhdGVkIGxpa2UgYW55IG90aGVyIHNlY3JldCBhY2Nlc3MgaW5mb3JtYXRpb24uIEluIG90aGVyIHdvcmRzLCBwcm90ZWN0IHRoZSBzZWVkIGluZm9ybWF0aW9uIGFzIHlvdSB3b3VsZCB5b3VyIEFXUyBhY2Nlc3Mga2V5cyBvciB5b3VyIHBhc3N3b3Jkcy4gQWZ0ZXIgeW91IHByb3Zpc2lvbiB5b3VyIHZpcnR1YWwgZGV2aWNlLCB5b3Ugc2hvdWxkIGVuc3VyZSB0aGF0IHRoZSBpbmZvcm1hdGlvbiBpcyBkZXN0cm95ZWQgZm9sbG93aW5nIHNlY3VyZSBwcm9jZWR1cmVzLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6SUFNOjpWaXJ0dWFsTUZBRGV2aWNlXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXZpcnR1YWxtZmFkZXZpY2UuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuVmlydHVhbE1GQURldmljZSBleHRlbmRzIGNkay5DZm5SZXNvdXJjZSBpbXBsZW1lbnRzIGNkay5JSW5zcGVjdGFibGUge1xuICAgIC8qKlxuICAgICAqIFRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIG5hbWUgZm9yIHRoaXMgcmVzb3VyY2UgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBDRk5fUkVTT1VSQ0VfVFlQRV9OQU1FID0gXCJBV1M6OklBTTo6VmlydHVhbE1GQURldmljZVwiO1xuXG4gICAgLyoqXG4gICAgICogQSBmYWN0b3J5IG1ldGhvZCB0aGF0IGNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmcm9tIGFuIG9iamVjdFxuICAgICAqIGNvbnRhaW5pbmcgdGhlIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgdGhpcyByZXNvdXJjZS5cbiAgICAgKiBVc2VkIGluIHRoZSBAYXdzLWNkay9jbG91ZGZvcm1hdGlvbi1pbmNsdWRlIG1vZHVsZS5cbiAgICAgKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgX2Zyb21DbG91ZEZvcm1hdGlvbihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcmVzb3VyY2VBdHRyaWJ1dGVzOiBhbnksIG9wdGlvbnM6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25PcHRpb25zKTogQ2ZuVmlydHVhbE1GQURldmljZSB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuVmlydHVhbE1GQURldmljZVByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5WaXJ0dWFsTUZBRGV2aWNlKHNjb3BlLCBpZCwgcHJvcHNSZXN1bHQudmFsdWUpO1xuICAgICAgICBmb3IgKGNvbnN0IFtwcm9wS2V5LCBwcm9wVmFsXSBvZiBPYmplY3QuZW50cmllcyhwcm9wc1Jlc3VsdC5leHRyYVByb3BlcnRpZXMpKSAge1xuICAgICAgICAgICAgcmV0LmFkZFByb3BlcnR5T3ZlcnJpZGUocHJvcEtleSwgcHJvcFZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5wYXJzZXIuaGFuZGxlQXR0cmlidXRlcyhyZXQsIHJlc291cmNlQXR0cmlidXRlcywgaWQpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHNlcmlhbCBudW1iZXIgZm9yIHRoZSBzcGVjaWZpZWQgYEFXUzo6SUFNOjpWaXJ0dWFsTUZBRGV2aWNlYCByZXNvdXJjZS5cbiAgICAgKiBAY2xvdWRmb3JtYXRpb25BdHRyaWJ1dGUgU2VyaWFsTnVtYmVyXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJTZXJpYWxOdW1iZXI6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBJQU0gdXNlciBhc3NvY2lhdGVkIHdpdGggdGhpcyB2aXJ0dWFsIE1GQSBkZXZpY2UuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tdmlydHVhbG1mYWRldmljZS5odG1sI2Nmbi1pYW0tdmlydHVhbG1mYWRldmljZS11c2Vyc1xuICAgICAqL1xuICAgIHB1YmxpYyB1c2Vyczogc3RyaW5nW107XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGF0aCBmb3IgdGhlIHZpcnR1YWwgTUZBIGRldmljZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgcGF0aHMsIHNlZSBbSUFNIGlkZW50aWZpZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvVXNpbmdfSWRlbnRpZmllcnMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgaXMgb3B0aW9uYWwuIElmIGl0IGlzIG5vdCBpbmNsdWRlZCwgaXQgZGVmYXVsdHMgdG8gYSBzbGFzaCAoLykuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgZWl0aGVyIGEgZm9yd2FyZCBzbGFzaCAoLykgYnkgaXRzZWxmIG9yIGEgc3RyaW5nIHRoYXQgbXVzdCBiZWdpbiBhbmQgZW5kIHdpdGggZm9yd2FyZCBzbGFzaGVzLiBJbiBhZGRpdGlvbiwgaXQgY2FuIGNvbnRhaW4gYW55IEFTQ0lJIGNoYXJhY3RlciBmcm9tIHRoZSAhICggYFxcIHUwMDIxYCApIHRocm91Z2ggdGhlIERFTCBjaGFyYWN0ZXIgKCBgXFwgdTAwN0ZgICksIGluY2x1ZGluZyBtb3N0IHB1bmN0dWF0aW9uIGNoYXJhY3RlcnMsIGRpZ2l0cywgYW5kIHVwcGVyIGFuZCBsb3dlcmNhc2VkIGxldHRlcnMuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tdmlydHVhbG1mYWRldmljZS5odG1sI2Nmbi1pYW0tdmlydHVhbG1mYWRldmljZS1wYXRoXG4gICAgICovXG4gICAgcHVibGljIHBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiB0YWdzIHRoYXQgeW91IHdhbnQgdG8gYXR0YWNoIHRvIHRoZSBuZXcgSUFNIHZpcnR1YWwgTUZBIGRldmljZS4gRWFjaCB0YWcgY29uc2lzdHMgb2YgYSBrZXkgbmFtZSBhbmQgYW4gYXNzb2NpYXRlZCB2YWx1ZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGFnZ2luZywgc2VlIFtUYWdnaW5nIElBTSByZXNvdXJjZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF90YWdzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqID4gSWYgYW55IG9uZSBvZiB0aGUgdGFncyBpcyBpbnZhbGlkIG9yIGlmIHlvdSBleGNlZWQgdGhlIGFsbG93ZWQgbWF4aW11bSBudW1iZXIgb2YgdGFncywgdGhlbiB0aGUgZW50aXJlIHJlcXVlc3QgZmFpbHMgYW5kIHRoZSByZXNvdXJjZSBpcyBub3QgY3JlYXRlZC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS12aXJ0dWFsbWZhZGV2aWNlLmh0bWwjY2ZuLWlhbS12aXJ0dWFsbWZhZGV2aWNlLXRhZ3NcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgdGFnczogY2RrLlRhZ01hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgdmlydHVhbCBNRkEgZGV2aWNlLiBVc2Ugd2l0aCBwYXRoIHRvIHVuaXF1ZWx5IGlkZW50aWZ5IGEgdmlydHVhbCBNRkEgZGV2aWNlLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS12aXJ0dWFsbWZhZGV2aWNlLmh0bWwjY2ZuLWlhbS12aXJ0dWFsbWZhZGV2aWNlLXZpcnR1YWxtZmFkZXZpY2VuYW1lXG4gICAgICovXG4gICAgcHVibGljIHZpcnR1YWxNZmFEZXZpY2VOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6SUFNOjpWaXJ0dWFsTUZBRGV2aWNlYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5WaXJ0dWFsTUZBRGV2aWNlUHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmblZpcnR1YWxNRkFEZXZpY2UuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICd1c2VycycsIHRoaXMpO1xuICAgICAgICB0aGlzLmF0dHJTZXJpYWxOdW1iZXIgPSBjZGsuVG9rZW4uYXNTdHJpbmcodGhpcy5nZXRBdHQoJ1NlcmlhbE51bWJlcicpKTtcblxuICAgICAgICB0aGlzLnVzZXJzID0gcHJvcHMudXNlcnM7XG4gICAgICAgIHRoaXMucGF0aCA9IHByb3BzLnBhdGg7XG4gICAgICAgIHRoaXMudGFncyA9IG5ldyBjZGsuVGFnTWFuYWdlcihjZGsuVGFnVHlwZS5TVEFOREFSRCwgXCJBV1M6OklBTTo6VmlydHVhbE1GQURldmljZVwiLCBwcm9wcy50YWdzLCB7IHRhZ1Byb3BlcnR5TmFtZTogJ3RhZ3MnIH0pO1xuICAgICAgICB0aGlzLnZpcnR1YWxNZmFEZXZpY2VOYW1lID0gcHJvcHMudmlydHVhbE1mYURldmljZU5hbWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5WaXJ0dWFsTUZBRGV2aWNlLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB1c2VyczogdGhpcy51c2VycyxcbiAgICAgICAgICAgIHBhdGg6IHRoaXMucGF0aCxcbiAgICAgICAgICAgIHRhZ3M6IHRoaXMudGFncy5yZW5kZXJUYWdzKCksXG4gICAgICAgICAgICB2aXJ0dWFsTWZhRGV2aWNlTmFtZTogdGhpcy52aXJ0dWFsTWZhRGV2aWNlTmFtZSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5WaXJ0dWFsTUZBRGV2aWNlUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG4iXX0=
\No newline at end of file