1 | ;
|
2 | var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
3 | Object.defineProperty(exports, "__esModule", { value: true });
|
4 | exports.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;
|
5 | const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
|
6 | const 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
|
12 | const cdk = require("@aws-cdk/core");
|
13 | const 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 | */
|
21 | function 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
|
43 | function 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
|
55 | function 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 | */
|
83 | class 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 | }
|
147 | exports.CfnAccessKey = CfnAccessKey;
|
148 | _a = JSII_RTTI_SYMBOL_1;
|
149 | CfnAccessKey[_a] = { fqn: "@aws-cdk/aws-iam.CfnAccessKey", version: "1.161.0" };
|
150 | /**
|
151 | * The CloudFormation resource type name for this resource class.
|
152 | */
|
153 | CfnAccessKey.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 | */
|
161 | function 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
|
183 | function 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
|
196 | function 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 | */
|
221 | class 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 | }
|
286 | exports.CfnGroup = CfnGroup;
|
287 | _b = JSII_RTTI_SYMBOL_1;
|
288 | CfnGroup[_b] = { fqn: "@aws-cdk/aws-iam.CfnGroup", version: "1.161.0" };
|
289 | /**
|
290 | * The CloudFormation resource type name for this resource class.
|
291 | */
|
292 | CfnGroup.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 | */
|
300 | function 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
|
322 | function 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
|
333 | function 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 | */
|
354 | function 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
|
376 | function 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
|
388 | function 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 | */
|
412 | class 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 | }
|
476 | exports.CfnInstanceProfile = CfnInstanceProfile;
|
477 | _c = JSII_RTTI_SYMBOL_1;
|
478 | CfnInstanceProfile[_c] = { fqn: "@aws-cdk/aws-iam.CfnInstanceProfile", version: "1.161.0" };
|
479 | /**
|
480 | * The CloudFormation resource type name for this resource class.
|
481 | */
|
482 | CfnInstanceProfile.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 | */
|
490 | function 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
|
516 | function 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
|
532 | function 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 | */
|
564 | class 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 | }
|
635 | exports.CfnManagedPolicy = CfnManagedPolicy;
|
636 | _d = JSII_RTTI_SYMBOL_1;
|
637 | CfnManagedPolicy[_d] = { fqn: "@aws-cdk/aws-iam.CfnManagedPolicy", version: "1.161.0" };
|
638 | /**
|
639 | * The CloudFormation resource type name for this resource class.
|
640 | */
|
641 | CfnManagedPolicy.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 | */
|
649 | function 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
|
672 | function 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
|
685 | function 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 | */
|
720 | class 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 | }
|
786 | exports.CfnOIDCProvider = CfnOIDCProvider;
|
787 | _e = JSII_RTTI_SYMBOL_1;
|
788 | CfnOIDCProvider[_e] = { fqn: "@aws-cdk/aws-iam.CfnOIDCProvider", version: "1.161.0" };
|
789 | /**
|
790 | * The CloudFormation resource type name for this resource class.
|
791 | */
|
792 | CfnOIDCProvider.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 | */
|
800 | function 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
|
825 | function 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
|
839 | function 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 | */
|
869 | class 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 | }
|
937 | exports.CfnPolicy = CfnPolicy;
|
938 | _f = JSII_RTTI_SYMBOL_1;
|
939 | CfnPolicy[_f] = { fqn: "@aws-cdk/aws-iam.CfnPolicy", version: "1.161.0" };
|
940 | /**
|
941 | * The CloudFormation resource type name for this resource class.
|
942 | */
|
943 | CfnPolicy.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 | */
|
951 | function 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
|
979 | function 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
|
997 | function 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 | */
|
1025 | class 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 | }
|
1102 | exports.CfnRole = CfnRole;
|
1103 | _g = JSII_RTTI_SYMBOL_1;
|
1104 | CfnRole[_g] = { fqn: "@aws-cdk/aws-iam.CfnRole", version: "1.161.0" };
|
1105 | /**
|
1106 | * The CloudFormation resource type name for this resource class.
|
1107 | */
|
1108 | CfnRole.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 | */
|
1116 | function 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
|
1138 | function 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
|
1149 | function 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 | */
|
1170 | function 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
|
1192 | function 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
|
1204 | function 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 | */
|
1234 | class 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 | }
|
1298 | exports.CfnSAMLProvider = CfnSAMLProvider;
|
1299 | _h = JSII_RTTI_SYMBOL_1;
|
1300 | CfnSAMLProvider[_h] = { fqn: "@aws-cdk/aws-iam.CfnSAMLProvider", version: "1.161.0" };
|
1301 | /**
|
1302 | * The CloudFormation resource type name for this resource class.
|
1303 | */
|
1304 | CfnSAMLProvider.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 | */
|
1312 | function 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
|
1336 | function 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
|
1351 | function 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 | */
|
1384 | class 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 | }
|
1453 | exports.CfnServerCertificate = CfnServerCertificate;
|
1454 | _j = JSII_RTTI_SYMBOL_1;
|
1455 | CfnServerCertificate[_j] = { fqn: "@aws-cdk/aws-iam.CfnServerCertificate", version: "1.161.0" };
|
1456 | /**
|
1457 | * The CloudFormation resource type name for this resource class.
|
1458 | */
|
1459 | CfnServerCertificate.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 | */
|
1467 | function 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
|
1489 | function 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
|
1501 | function 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 | */
|
1525 | class 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 | }
|
1588 | exports.CfnServiceLinkedRole = CfnServiceLinkedRole;
|
1589 | _k = JSII_RTTI_SYMBOL_1;
|
1590 | CfnServiceLinkedRole[_k] = { fqn: "@aws-cdk/aws-iam.CfnServiceLinkedRole", version: "1.161.0" };
|
1591 | /**
|
1592 | * The CloudFormation resource type name for this resource class.
|
1593 | */
|
1594 | CfnServiceLinkedRole.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 | */
|
1602 | function 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
|
1628 | function 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
|
1645 | function 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 | */
|
1674 | class 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 | }
|
1747 | exports.CfnUser = CfnUser;
|
1748 | _l = JSII_RTTI_SYMBOL_1;
|
1749 | CfnUser[_l] = { fqn: "@aws-cdk/aws-iam.CfnUser", version: "1.161.0" };
|
1750 | /**
|
1751 | * The CloudFormation resource type name for this resource class.
|
1752 | */
|
1753 | CfnUser.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 | */
|
1761 | function 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
|
1782 | function 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
|
1793 | function 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 | */
|
1814 | function 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
|
1836 | function 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
|
1847 | function 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 | */
|
1868 | function 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
|
1890 | function 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
|
1901 | function 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 | */
|
1922 | class 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 | }
|
1984 | exports.CfnUserToGroupAddition = CfnUserToGroupAddition;
|
1985 | _m = JSII_RTTI_SYMBOL_1;
|
1986 | CfnUserToGroupAddition[_m] = { fqn: "@aws-cdk/aws-iam.CfnUserToGroupAddition", version: "1.161.0" };
|
1987 | /**
|
1988 | * The CloudFormation resource type name for this resource class.
|
1989 | */
|
1990 | CfnUserToGroupAddition.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 | */
|
1998 | function 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
|
2021 | function 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
|
2034 | function 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 | */
|
2061 | class 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 | }
|
2127 | exports.CfnVirtualMFADevice = CfnVirtualMFADevice;
|
2128 | _o = JSII_RTTI_SYMBOL_1;
|
2129 | CfnVirtualMFADevice[_o] = { fqn: "@aws-cdk/aws-iam.CfnVirtualMFADevice", version: "1.161.0" };
|
2130 | /**
|
2131 | * The CloudFormation resource type name for this resource class.
|
2132 | */
|
2133 | CfnVirtualMFADevice.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 |