UNPKG

585 kBJavaScriptView Raw
1"use strict";
2var _a, _b, _c, _d, _e, _f, _g;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.CfnRecordSetGroup = exports.CfnRecordSet = exports.CfnKeySigningKey = exports.CfnHostedZone = exports.CfnHealthCheck = exports.CfnDNSSEC = exports.CfnCidrCollection = void 0;
5const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
6const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
7// Copyright 2012-2023 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":"2023-06-19T15:18:57.225Z","fingerprint":"x98R1RtiROkQoFQjK4PPRmmdTN3P6bDRRv9wpM95yXg="}
11/* eslint-disable max-len */ // This is generated code - line lengths are difficult to control
12const cdk = require("@aws-cdk/core");
13const cfn_parse = require("@aws-cdk/core/lib/helpers-internal");
14/**
15 * Determine whether the given properties match those of a `CfnCidrCollectionProps`
16 *
17 * @param properties - the TypeScript properties of a `CfnCidrCollectionProps`
18 *
19 * @returns the result of the validation.
20 */
21function CfnCidrCollectionPropsValidator(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('locations', cdk.listValidator(CfnCidrCollection_LocationPropertyValidator))(properties.locations));
30 errors.collect(cdk.propertyValidator('name', cdk.requiredValidator)(properties.name));
31 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
32 return errors.wrap('supplied properties not correct for "CfnCidrCollectionProps"');
33}
34/**
35 * Renders the AWS CloudFormation properties of an `AWS::Route53::CidrCollection` resource
36 *
37 * @param properties - the TypeScript properties of a `CfnCidrCollectionProps`
38 *
39 * @returns the AWS CloudFormation properties of an `AWS::Route53::CidrCollection` resource.
40 */
41// @ts-ignore TS6133
42function cfnCidrCollectionPropsToCloudFormation(properties) {
43 if (!cdk.canInspect(properties)) {
44 return properties;
45 }
46 CfnCidrCollectionPropsValidator(properties).assertSuccess();
47 return {
48 Name: cdk.stringToCloudFormation(properties.name),
49 Locations: cdk.listMapper(cfnCidrCollectionLocationPropertyToCloudFormation)(properties.locations),
50 };
51}
52// @ts-ignore TS6133
53function CfnCidrCollectionPropsFromCloudFormation(properties) {
54 properties = properties == null ? {} : properties;
55 if (typeof properties !== 'object') {
56 return new cfn_parse.FromCloudFormationResult(properties);
57 }
58 const ret = new cfn_parse.FromCloudFormationPropertyObject();
59 ret.addPropertyResult('name', 'Name', cfn_parse.FromCloudFormation.getString(properties.Name));
60 ret.addPropertyResult('locations', 'Locations', properties.Locations != null ? cfn_parse.FromCloudFormation.getArray(CfnCidrCollectionLocationPropertyFromCloudFormation)(properties.Locations) : undefined);
61 ret.addUnrecognizedPropertiesAsExtra(properties);
62 return ret;
63}
64/**
65 * A CloudFormation `AWS::Route53::CidrCollection`
66 *
67 * Creates a CIDR collection in the current AWS account.
68 *
69 * @cloudformationResource AWS::Route53::CidrCollection
70 * @stability external
71 *
72 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-cidrcollection.html
73 */
74class CfnCidrCollection extends cdk.CfnResource {
75 /**
76 * Create a new `AWS::Route53::CidrCollection`.
77 *
78 * @param scope - scope in which this resource is defined
79 * @param id - scoped id of the resource
80 * @param props - resource properties
81 */
82 constructor(scope, id, props) {
83 super(scope, id, { type: CfnCidrCollection.CFN_RESOURCE_TYPE_NAME, properties: props });
84 try {
85 jsiiDeprecationWarnings._aws_cdk_aws_route53_CfnCidrCollectionProps(props);
86 }
87 catch (error) {
88 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
89 Error.captureStackTrace(error, CfnCidrCollection);
90 }
91 throw error;
92 }
93 cdk.requireProperty(props, 'name', this);
94 this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
95 this.attrId = cdk.Token.asString(this.getAtt('Id'));
96 this.name = props.name;
97 this.locations = props.locations;
98 }
99 /**
100 * A factory method that creates a new instance of this class from an object
101 * containing the CloudFormation properties of this resource.
102 * Used in the @aws-cdk/cloudformation-include module.
103 *
104 * @internal
105 */
106 static _fromCloudFormation(scope, id, resourceAttributes, options) {
107 resourceAttributes = resourceAttributes || {};
108 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
109 const propsResult = CfnCidrCollectionPropsFromCloudFormation(resourceProperties);
110 const ret = new CfnCidrCollection(scope, id, propsResult.value);
111 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
112 ret.addPropertyOverride(propKey, propVal);
113 }
114 options.parser.handleAttributes(ret, resourceAttributes, id);
115 return ret;
116 }
117 /**
118 * Examines the CloudFormation resource and discloses attributes.
119 *
120 * @param inspector - tree inspector to collect and process attributes
121 *
122 */
123 inspect(inspector) {
124 inspector.addAttribute("aws:cdk:cloudformation:type", CfnCidrCollection.CFN_RESOURCE_TYPE_NAME);
125 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
126 }
127 get cfnProperties() {
128 return {
129 name: this.name,
130 locations: this.locations,
131 };
132 }
133 renderProperties(props) {
134 return cfnCidrCollectionPropsToCloudFormation(props);
135 }
136}
137exports.CfnCidrCollection = CfnCidrCollection;
138_a = JSII_RTTI_SYMBOL_1;
139CfnCidrCollection[_a] = { fqn: "@aws-cdk/aws-route53.CfnCidrCollection", version: "1.204.0" };
140/**
141 * The CloudFormation resource type name for this resource class.
142 */
143CfnCidrCollection.CFN_RESOURCE_TYPE_NAME = "AWS::Route53::CidrCollection";
144/**
145 * Determine whether the given properties match those of a `LocationProperty`
146 *
147 * @param properties - the TypeScript properties of a `LocationProperty`
148 *
149 * @returns the result of the validation.
150 */
151function CfnCidrCollection_LocationPropertyValidator(properties) {
152 if (!cdk.canInspect(properties)) {
153 return cdk.VALIDATION_SUCCESS;
154 }
155 const errors = new cdk.ValidationResults();
156 if (typeof properties !== 'object') {
157 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
158 }
159 errors.collect(cdk.propertyValidator('cidrList', cdk.requiredValidator)(properties.cidrList));
160 errors.collect(cdk.propertyValidator('cidrList', cdk.listValidator(cdk.validateString))(properties.cidrList));
161 errors.collect(cdk.propertyValidator('locationName', cdk.requiredValidator)(properties.locationName));
162 errors.collect(cdk.propertyValidator('locationName', cdk.validateString)(properties.locationName));
163 return errors.wrap('supplied properties not correct for "LocationProperty"');
164}
165/**
166 * Renders the AWS CloudFormation properties of an `AWS::Route53::CidrCollection.Location` resource
167 *
168 * @param properties - the TypeScript properties of a `LocationProperty`
169 *
170 * @returns the AWS CloudFormation properties of an `AWS::Route53::CidrCollection.Location` resource.
171 */
172// @ts-ignore TS6133
173function cfnCidrCollectionLocationPropertyToCloudFormation(properties) {
174 if (!cdk.canInspect(properties)) {
175 return properties;
176 }
177 CfnCidrCollection_LocationPropertyValidator(properties).assertSuccess();
178 return {
179 CidrList: cdk.listMapper(cdk.stringToCloudFormation)(properties.cidrList),
180 LocationName: cdk.stringToCloudFormation(properties.locationName),
181 };
182}
183// @ts-ignore TS6133
184function CfnCidrCollectionLocationPropertyFromCloudFormation(properties) {
185 if (cdk.isResolvableObject(properties)) {
186 return new cfn_parse.FromCloudFormationResult(properties);
187 }
188 properties = properties == null ? {} : properties;
189 if (typeof properties !== 'object') {
190 return new cfn_parse.FromCloudFormationResult(properties);
191 }
192 const ret = new cfn_parse.FromCloudFormationPropertyObject();
193 ret.addPropertyResult('cidrList', 'CidrList', cfn_parse.FromCloudFormation.getStringArray(properties.CidrList));
194 ret.addPropertyResult('locationName', 'LocationName', cfn_parse.FromCloudFormation.getString(properties.LocationName));
195 ret.addUnrecognizedPropertiesAsExtra(properties);
196 return ret;
197}
198/**
199 * Determine whether the given properties match those of a `CfnDNSSECProps`
200 *
201 * @param properties - the TypeScript properties of a `CfnDNSSECProps`
202 *
203 * @returns the result of the validation.
204 */
205function CfnDNSSECPropsValidator(properties) {
206 if (!cdk.canInspect(properties)) {
207 return cdk.VALIDATION_SUCCESS;
208 }
209 const errors = new cdk.ValidationResults();
210 if (typeof properties !== 'object') {
211 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
212 }
213 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.requiredValidator)(properties.hostedZoneId));
214 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.validateString)(properties.hostedZoneId));
215 return errors.wrap('supplied properties not correct for "CfnDNSSECProps"');
216}
217/**
218 * Renders the AWS CloudFormation properties of an `AWS::Route53::DNSSEC` resource
219 *
220 * @param properties - the TypeScript properties of a `CfnDNSSECProps`
221 *
222 * @returns the AWS CloudFormation properties of an `AWS::Route53::DNSSEC` resource.
223 */
224// @ts-ignore TS6133
225function cfnDNSSECPropsToCloudFormation(properties) {
226 if (!cdk.canInspect(properties)) {
227 return properties;
228 }
229 CfnDNSSECPropsValidator(properties).assertSuccess();
230 return {
231 HostedZoneId: cdk.stringToCloudFormation(properties.hostedZoneId),
232 };
233}
234// @ts-ignore TS6133
235function CfnDNSSECPropsFromCloudFormation(properties) {
236 properties = properties == null ? {} : properties;
237 if (typeof properties !== 'object') {
238 return new cfn_parse.FromCloudFormationResult(properties);
239 }
240 const ret = new cfn_parse.FromCloudFormationPropertyObject();
241 ret.addPropertyResult('hostedZoneId', 'HostedZoneId', cfn_parse.FromCloudFormation.getString(properties.HostedZoneId));
242 ret.addUnrecognizedPropertiesAsExtra(properties);
243 return ret;
244}
245/**
246 * A CloudFormation `AWS::Route53::DNSSEC`
247 *
248 * The `AWS::Route53::DNSSEC` resource is used to enable DNSSEC signing in a hosted zone.
249 *
250 * @cloudformationResource AWS::Route53::DNSSEC
251 * @stability external
252 *
253 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-dnssec.html
254 */
255class CfnDNSSEC extends cdk.CfnResource {
256 /**
257 * Create a new `AWS::Route53::DNSSEC`.
258 *
259 * @param scope - scope in which this resource is defined
260 * @param id - scoped id of the resource
261 * @param props - resource properties
262 */
263 constructor(scope, id, props) {
264 super(scope, id, { type: CfnDNSSEC.CFN_RESOURCE_TYPE_NAME, properties: props });
265 try {
266 jsiiDeprecationWarnings._aws_cdk_aws_route53_CfnDNSSECProps(props);
267 }
268 catch (error) {
269 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
270 Error.captureStackTrace(error, CfnDNSSEC);
271 }
272 throw error;
273 }
274 cdk.requireProperty(props, 'hostedZoneId', this);
275 this.hostedZoneId = props.hostedZoneId;
276 }
277 /**
278 * A factory method that creates a new instance of this class from an object
279 * containing the CloudFormation properties of this resource.
280 * Used in the @aws-cdk/cloudformation-include module.
281 *
282 * @internal
283 */
284 static _fromCloudFormation(scope, id, resourceAttributes, options) {
285 resourceAttributes = resourceAttributes || {};
286 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
287 const propsResult = CfnDNSSECPropsFromCloudFormation(resourceProperties);
288 const ret = new CfnDNSSEC(scope, id, propsResult.value);
289 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
290 ret.addPropertyOverride(propKey, propVal);
291 }
292 options.parser.handleAttributes(ret, resourceAttributes, id);
293 return ret;
294 }
295 /**
296 * Examines the CloudFormation resource and discloses attributes.
297 *
298 * @param inspector - tree inspector to collect and process attributes
299 *
300 */
301 inspect(inspector) {
302 inspector.addAttribute("aws:cdk:cloudformation:type", CfnDNSSEC.CFN_RESOURCE_TYPE_NAME);
303 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
304 }
305 get cfnProperties() {
306 return {
307 hostedZoneId: this.hostedZoneId,
308 };
309 }
310 renderProperties(props) {
311 return cfnDNSSECPropsToCloudFormation(props);
312 }
313}
314exports.CfnDNSSEC = CfnDNSSEC;
315_b = JSII_RTTI_SYMBOL_1;
316CfnDNSSEC[_b] = { fqn: "@aws-cdk/aws-route53.CfnDNSSEC", version: "1.204.0" };
317/**
318 * The CloudFormation resource type name for this resource class.
319 */
320CfnDNSSEC.CFN_RESOURCE_TYPE_NAME = "AWS::Route53::DNSSEC";
321/**
322 * Determine whether the given properties match those of a `CfnHealthCheckProps`
323 *
324 * @param properties - the TypeScript properties of a `CfnHealthCheckProps`
325 *
326 * @returns the result of the validation.
327 */
328function CfnHealthCheckPropsValidator(properties) {
329 if (!cdk.canInspect(properties)) {
330 return cdk.VALIDATION_SUCCESS;
331 }
332 const errors = new cdk.ValidationResults();
333 if (typeof properties !== 'object') {
334 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
335 }
336 errors.collect(cdk.propertyValidator('healthCheckConfig', cdk.requiredValidator)(properties.healthCheckConfig));
337 errors.collect(cdk.propertyValidator('healthCheckConfig', CfnHealthCheck_HealthCheckConfigPropertyValidator)(properties.healthCheckConfig));
338 errors.collect(cdk.propertyValidator('healthCheckTags', cdk.listValidator(CfnHealthCheck_HealthCheckTagPropertyValidator))(properties.healthCheckTags));
339 return errors.wrap('supplied properties not correct for "CfnHealthCheckProps"');
340}
341/**
342 * Renders the AWS CloudFormation properties of an `AWS::Route53::HealthCheck` resource
343 *
344 * @param properties - the TypeScript properties of a `CfnHealthCheckProps`
345 *
346 * @returns the AWS CloudFormation properties of an `AWS::Route53::HealthCheck` resource.
347 */
348// @ts-ignore TS6133
349function cfnHealthCheckPropsToCloudFormation(properties) {
350 if (!cdk.canInspect(properties)) {
351 return properties;
352 }
353 CfnHealthCheckPropsValidator(properties).assertSuccess();
354 return {
355 HealthCheckConfig: cfnHealthCheckHealthCheckConfigPropertyToCloudFormation(properties.healthCheckConfig),
356 HealthCheckTags: cdk.listMapper(cfnHealthCheckHealthCheckTagPropertyToCloudFormation)(properties.healthCheckTags),
357 };
358}
359// @ts-ignore TS6133
360function CfnHealthCheckPropsFromCloudFormation(properties) {
361 properties = properties == null ? {} : properties;
362 if (typeof properties !== 'object') {
363 return new cfn_parse.FromCloudFormationResult(properties);
364 }
365 const ret = new cfn_parse.FromCloudFormationPropertyObject();
366 ret.addPropertyResult('healthCheckConfig', 'HealthCheckConfig', CfnHealthCheckHealthCheckConfigPropertyFromCloudFormation(properties.HealthCheckConfig));
367 ret.addPropertyResult('healthCheckTags', 'HealthCheckTags', properties.HealthCheckTags != null ? cfn_parse.FromCloudFormation.getArray(CfnHealthCheckHealthCheckTagPropertyFromCloudFormation)(properties.HealthCheckTags) : undefined);
368 ret.addUnrecognizedPropertiesAsExtra(properties);
369 return ret;
370}
371/**
372 * A CloudFormation `AWS::Route53::HealthCheck`
373 *
374 * The `AWS::Route53::HealthCheck` resource is a Route 53 resource type that contains settings for a Route 53 health check.
375 *
376 * For information about associating health checks with records, see [HealthCheckId](https://docs.aws.amazon.com/Route53/latest/APIReference/API_ResourceRecordSet.html#Route53-Type-ResourceRecordSet-HealthCheckId) in [ChangeResourceRecordSets](https://docs.aws.amazon.com/Route53/latest/APIReference/API_ChangeResourceRecordSets.html) .
377 *
378 * > You can't create a health check with simple routing.
379 *
380 * *ELB Load Balancers*
381 *
382 * If you're registering EC2 instances with an Elastic Load Balancing (ELB) load balancer, do not create Amazon Route 53 health checks for the EC2 instances. When you register an EC2 instance with a load balancer, you configure settings for an ELB health check, which performs a similar function to a Route 53 health check.
383 *
384 * *Private Hosted Zones*
385 *
386 * You can associate health checks with failover records in a private hosted zone. Note the following:
387 *
388 * - Route 53 health checkers are outside the VPC. To check the health of an endpoint within a VPC by IP address, you must assign a public IP address to the instance in the VPC.
389 * - You can configure a health checker to check the health of an external resource that the instance relies on, such as a database server.
390 * - You can create a CloudWatch metric, associate an alarm with the metric, and then create a health check that is based on the state of the alarm. For example, you might create a CloudWatch metric that checks the status of the Amazon EC2 `StatusCheckFailed` metric, add an alarm to the metric, and then create a health check that is based on the state of the alarm. For information about creating CloudWatch metrics and alarms by using the CloudWatch console, see the [Amazon CloudWatch User Guide](https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/WhatIsCloudWatch.html) .
391 *
392 * @cloudformationResource AWS::Route53::HealthCheck
393 * @stability external
394 *
395 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-healthcheck.html
396 */
397class CfnHealthCheck extends cdk.CfnResource {
398 /**
399 * Create a new `AWS::Route53::HealthCheck`.
400 *
401 * @param scope - scope in which this resource is defined
402 * @param id - scoped id of the resource
403 * @param props - resource properties
404 */
405 constructor(scope, id, props) {
406 super(scope, id, { type: CfnHealthCheck.CFN_RESOURCE_TYPE_NAME, properties: props });
407 try {
408 jsiiDeprecationWarnings._aws_cdk_aws_route53_CfnHealthCheckProps(props);
409 }
410 catch (error) {
411 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
412 Error.captureStackTrace(error, CfnHealthCheck);
413 }
414 throw error;
415 }
416 cdk.requireProperty(props, 'healthCheckConfig', this);
417 this.attrHealthCheckId = cdk.Token.asString(this.getAtt('HealthCheckId'));
418 this.healthCheckConfig = props.healthCheckConfig;
419 this.healthCheckTags = props.healthCheckTags;
420 }
421 /**
422 * A factory method that creates a new instance of this class from an object
423 * containing the CloudFormation properties of this resource.
424 * Used in the @aws-cdk/cloudformation-include module.
425 *
426 * @internal
427 */
428 static _fromCloudFormation(scope, id, resourceAttributes, options) {
429 resourceAttributes = resourceAttributes || {};
430 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
431 const propsResult = CfnHealthCheckPropsFromCloudFormation(resourceProperties);
432 const ret = new CfnHealthCheck(scope, id, propsResult.value);
433 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
434 ret.addPropertyOverride(propKey, propVal);
435 }
436 options.parser.handleAttributes(ret, resourceAttributes, id);
437 return ret;
438 }
439 /**
440 * Examines the CloudFormation resource and discloses attributes.
441 *
442 * @param inspector - tree inspector to collect and process attributes
443 *
444 */
445 inspect(inspector) {
446 inspector.addAttribute("aws:cdk:cloudformation:type", CfnHealthCheck.CFN_RESOURCE_TYPE_NAME);
447 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
448 }
449 get cfnProperties() {
450 return {
451 healthCheckConfig: this.healthCheckConfig,
452 healthCheckTags: this.healthCheckTags,
453 };
454 }
455 renderProperties(props) {
456 return cfnHealthCheckPropsToCloudFormation(props);
457 }
458}
459exports.CfnHealthCheck = CfnHealthCheck;
460_c = JSII_RTTI_SYMBOL_1;
461CfnHealthCheck[_c] = { fqn: "@aws-cdk/aws-route53.CfnHealthCheck", version: "1.204.0" };
462/**
463 * The CloudFormation resource type name for this resource class.
464 */
465CfnHealthCheck.CFN_RESOURCE_TYPE_NAME = "AWS::Route53::HealthCheck";
466/**
467 * Determine whether the given properties match those of a `AlarmIdentifierProperty`
468 *
469 * @param properties - the TypeScript properties of a `AlarmIdentifierProperty`
470 *
471 * @returns the result of the validation.
472 */
473function CfnHealthCheck_AlarmIdentifierPropertyValidator(properties) {
474 if (!cdk.canInspect(properties)) {
475 return cdk.VALIDATION_SUCCESS;
476 }
477 const errors = new cdk.ValidationResults();
478 if (typeof properties !== 'object') {
479 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
480 }
481 errors.collect(cdk.propertyValidator('name', cdk.requiredValidator)(properties.name));
482 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
483 errors.collect(cdk.propertyValidator('region', cdk.requiredValidator)(properties.region));
484 errors.collect(cdk.propertyValidator('region', cdk.validateString)(properties.region));
485 return errors.wrap('supplied properties not correct for "AlarmIdentifierProperty"');
486}
487/**
488 * Renders the AWS CloudFormation properties of an `AWS::Route53::HealthCheck.AlarmIdentifier` resource
489 *
490 * @param properties - the TypeScript properties of a `AlarmIdentifierProperty`
491 *
492 * @returns the AWS CloudFormation properties of an `AWS::Route53::HealthCheck.AlarmIdentifier` resource.
493 */
494// @ts-ignore TS6133
495function cfnHealthCheckAlarmIdentifierPropertyToCloudFormation(properties) {
496 if (!cdk.canInspect(properties)) {
497 return properties;
498 }
499 CfnHealthCheck_AlarmIdentifierPropertyValidator(properties).assertSuccess();
500 return {
501 Name: cdk.stringToCloudFormation(properties.name),
502 Region: cdk.stringToCloudFormation(properties.region),
503 };
504}
505// @ts-ignore TS6133
506function CfnHealthCheckAlarmIdentifierPropertyFromCloudFormation(properties) {
507 if (cdk.isResolvableObject(properties)) {
508 return new cfn_parse.FromCloudFormationResult(properties);
509 }
510 properties = properties == null ? {} : properties;
511 if (typeof properties !== 'object') {
512 return new cfn_parse.FromCloudFormationResult(properties);
513 }
514 const ret = new cfn_parse.FromCloudFormationPropertyObject();
515 ret.addPropertyResult('name', 'Name', cfn_parse.FromCloudFormation.getString(properties.Name));
516 ret.addPropertyResult('region', 'Region', cfn_parse.FromCloudFormation.getString(properties.Region));
517 ret.addUnrecognizedPropertiesAsExtra(properties);
518 return ret;
519}
520/**
521 * Determine whether the given properties match those of a `HealthCheckConfigProperty`
522 *
523 * @param properties - the TypeScript properties of a `HealthCheckConfigProperty`
524 *
525 * @returns the result of the validation.
526 */
527function CfnHealthCheck_HealthCheckConfigPropertyValidator(properties) {
528 if (!cdk.canInspect(properties)) {
529 return cdk.VALIDATION_SUCCESS;
530 }
531 const errors = new cdk.ValidationResults();
532 if (typeof properties !== 'object') {
533 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
534 }
535 errors.collect(cdk.propertyValidator('alarmIdentifier', CfnHealthCheck_AlarmIdentifierPropertyValidator)(properties.alarmIdentifier));
536 errors.collect(cdk.propertyValidator('childHealthChecks', cdk.listValidator(cdk.validateString))(properties.childHealthChecks));
537 errors.collect(cdk.propertyValidator('enableSni', cdk.validateBoolean)(properties.enableSni));
538 errors.collect(cdk.propertyValidator('failureThreshold', cdk.validateNumber)(properties.failureThreshold));
539 errors.collect(cdk.propertyValidator('fullyQualifiedDomainName', cdk.validateString)(properties.fullyQualifiedDomainName));
540 errors.collect(cdk.propertyValidator('healthThreshold', cdk.validateNumber)(properties.healthThreshold));
541 errors.collect(cdk.propertyValidator('ipAddress', cdk.validateString)(properties.ipAddress));
542 errors.collect(cdk.propertyValidator('insufficientDataHealthStatus', cdk.validateString)(properties.insufficientDataHealthStatus));
543 errors.collect(cdk.propertyValidator('inverted', cdk.validateBoolean)(properties.inverted));
544 errors.collect(cdk.propertyValidator('measureLatency', cdk.validateBoolean)(properties.measureLatency));
545 errors.collect(cdk.propertyValidator('port', cdk.validateNumber)(properties.port));
546 errors.collect(cdk.propertyValidator('regions', cdk.listValidator(cdk.validateString))(properties.regions));
547 errors.collect(cdk.propertyValidator('requestInterval', cdk.validateNumber)(properties.requestInterval));
548 errors.collect(cdk.propertyValidator('resourcePath', cdk.validateString)(properties.resourcePath));
549 errors.collect(cdk.propertyValidator('routingControlArn', cdk.validateString)(properties.routingControlArn));
550 errors.collect(cdk.propertyValidator('searchString', cdk.validateString)(properties.searchString));
551 errors.collect(cdk.propertyValidator('type', cdk.requiredValidator)(properties.type));
552 errors.collect(cdk.propertyValidator('type', cdk.validateString)(properties.type));
553 return errors.wrap('supplied properties not correct for "HealthCheckConfigProperty"');
554}
555/**
556 * Renders the AWS CloudFormation properties of an `AWS::Route53::HealthCheck.HealthCheckConfig` resource
557 *
558 * @param properties - the TypeScript properties of a `HealthCheckConfigProperty`
559 *
560 * @returns the AWS CloudFormation properties of an `AWS::Route53::HealthCheck.HealthCheckConfig` resource.
561 */
562// @ts-ignore TS6133
563function cfnHealthCheckHealthCheckConfigPropertyToCloudFormation(properties) {
564 if (!cdk.canInspect(properties)) {
565 return properties;
566 }
567 CfnHealthCheck_HealthCheckConfigPropertyValidator(properties).assertSuccess();
568 return {
569 AlarmIdentifier: cfnHealthCheckAlarmIdentifierPropertyToCloudFormation(properties.alarmIdentifier),
570 ChildHealthChecks: cdk.listMapper(cdk.stringToCloudFormation)(properties.childHealthChecks),
571 EnableSNI: cdk.booleanToCloudFormation(properties.enableSni),
572 FailureThreshold: cdk.numberToCloudFormation(properties.failureThreshold),
573 FullyQualifiedDomainName: cdk.stringToCloudFormation(properties.fullyQualifiedDomainName),
574 HealthThreshold: cdk.numberToCloudFormation(properties.healthThreshold),
575 IPAddress: cdk.stringToCloudFormation(properties.ipAddress),
576 InsufficientDataHealthStatus: cdk.stringToCloudFormation(properties.insufficientDataHealthStatus),
577 Inverted: cdk.booleanToCloudFormation(properties.inverted),
578 MeasureLatency: cdk.booleanToCloudFormation(properties.measureLatency),
579 Port: cdk.numberToCloudFormation(properties.port),
580 Regions: cdk.listMapper(cdk.stringToCloudFormation)(properties.regions),
581 RequestInterval: cdk.numberToCloudFormation(properties.requestInterval),
582 ResourcePath: cdk.stringToCloudFormation(properties.resourcePath),
583 RoutingControlArn: cdk.stringToCloudFormation(properties.routingControlArn),
584 SearchString: cdk.stringToCloudFormation(properties.searchString),
585 Type: cdk.stringToCloudFormation(properties.type),
586 };
587}
588// @ts-ignore TS6133
589function CfnHealthCheckHealthCheckConfigPropertyFromCloudFormation(properties) {
590 if (cdk.isResolvableObject(properties)) {
591 return new cfn_parse.FromCloudFormationResult(properties);
592 }
593 properties = properties == null ? {} : properties;
594 if (typeof properties !== 'object') {
595 return new cfn_parse.FromCloudFormationResult(properties);
596 }
597 const ret = new cfn_parse.FromCloudFormationPropertyObject();
598 ret.addPropertyResult('alarmIdentifier', 'AlarmIdentifier', properties.AlarmIdentifier != null ? CfnHealthCheckAlarmIdentifierPropertyFromCloudFormation(properties.AlarmIdentifier) : undefined);
599 ret.addPropertyResult('childHealthChecks', 'ChildHealthChecks', properties.ChildHealthChecks != null ? cfn_parse.FromCloudFormation.getStringArray(properties.ChildHealthChecks) : undefined);
600 ret.addPropertyResult('enableSni', 'EnableSNI', properties.EnableSNI != null ? cfn_parse.FromCloudFormation.getBoolean(properties.EnableSNI) : undefined);
601 ret.addPropertyResult('failureThreshold', 'FailureThreshold', properties.FailureThreshold != null ? cfn_parse.FromCloudFormation.getNumber(properties.FailureThreshold) : undefined);
602 ret.addPropertyResult('fullyQualifiedDomainName', 'FullyQualifiedDomainName', properties.FullyQualifiedDomainName != null ? cfn_parse.FromCloudFormation.getString(properties.FullyQualifiedDomainName) : undefined);
603 ret.addPropertyResult('healthThreshold', 'HealthThreshold', properties.HealthThreshold != null ? cfn_parse.FromCloudFormation.getNumber(properties.HealthThreshold) : undefined);
604 ret.addPropertyResult('ipAddress', 'IPAddress', properties.IPAddress != null ? cfn_parse.FromCloudFormation.getString(properties.IPAddress) : undefined);
605 ret.addPropertyResult('insufficientDataHealthStatus', 'InsufficientDataHealthStatus', properties.InsufficientDataHealthStatus != null ? cfn_parse.FromCloudFormation.getString(properties.InsufficientDataHealthStatus) : undefined);
606 ret.addPropertyResult('inverted', 'Inverted', properties.Inverted != null ? cfn_parse.FromCloudFormation.getBoolean(properties.Inverted) : undefined);
607 ret.addPropertyResult('measureLatency', 'MeasureLatency', properties.MeasureLatency != null ? cfn_parse.FromCloudFormation.getBoolean(properties.MeasureLatency) : undefined);
608 ret.addPropertyResult('port', 'Port', properties.Port != null ? cfn_parse.FromCloudFormation.getNumber(properties.Port) : undefined);
609 ret.addPropertyResult('regions', 'Regions', properties.Regions != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Regions) : undefined);
610 ret.addPropertyResult('requestInterval', 'RequestInterval', properties.RequestInterval != null ? cfn_parse.FromCloudFormation.getNumber(properties.RequestInterval) : undefined);
611 ret.addPropertyResult('resourcePath', 'ResourcePath', properties.ResourcePath != null ? cfn_parse.FromCloudFormation.getString(properties.ResourcePath) : undefined);
612 ret.addPropertyResult('routingControlArn', 'RoutingControlArn', properties.RoutingControlArn != null ? cfn_parse.FromCloudFormation.getString(properties.RoutingControlArn) : undefined);
613 ret.addPropertyResult('searchString', 'SearchString', properties.SearchString != null ? cfn_parse.FromCloudFormation.getString(properties.SearchString) : undefined);
614 ret.addPropertyResult('type', 'Type', cfn_parse.FromCloudFormation.getString(properties.Type));
615 ret.addUnrecognizedPropertiesAsExtra(properties);
616 return ret;
617}
618/**
619 * Determine whether the given properties match those of a `HealthCheckTagProperty`
620 *
621 * @param properties - the TypeScript properties of a `HealthCheckTagProperty`
622 *
623 * @returns the result of the validation.
624 */
625function CfnHealthCheck_HealthCheckTagPropertyValidator(properties) {
626 if (!cdk.canInspect(properties)) {
627 return cdk.VALIDATION_SUCCESS;
628 }
629 const errors = new cdk.ValidationResults();
630 if (typeof properties !== 'object') {
631 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
632 }
633 errors.collect(cdk.propertyValidator('key', cdk.requiredValidator)(properties.key));
634 errors.collect(cdk.propertyValidator('key', cdk.validateString)(properties.key));
635 errors.collect(cdk.propertyValidator('value', cdk.requiredValidator)(properties.value));
636 errors.collect(cdk.propertyValidator('value', cdk.validateString)(properties.value));
637 return errors.wrap('supplied properties not correct for "HealthCheckTagProperty"');
638}
639/**
640 * Renders the AWS CloudFormation properties of an `AWS::Route53::HealthCheck.HealthCheckTag` resource
641 *
642 * @param properties - the TypeScript properties of a `HealthCheckTagProperty`
643 *
644 * @returns the AWS CloudFormation properties of an `AWS::Route53::HealthCheck.HealthCheckTag` resource.
645 */
646// @ts-ignore TS6133
647function cfnHealthCheckHealthCheckTagPropertyToCloudFormation(properties) {
648 if (!cdk.canInspect(properties)) {
649 return properties;
650 }
651 CfnHealthCheck_HealthCheckTagPropertyValidator(properties).assertSuccess();
652 return {
653 Key: cdk.stringToCloudFormation(properties.key),
654 Value: cdk.stringToCloudFormation(properties.value),
655 };
656}
657// @ts-ignore TS6133
658function CfnHealthCheckHealthCheckTagPropertyFromCloudFormation(properties) {
659 if (cdk.isResolvableObject(properties)) {
660 return new cfn_parse.FromCloudFormationResult(properties);
661 }
662 properties = properties == null ? {} : properties;
663 if (typeof properties !== 'object') {
664 return new cfn_parse.FromCloudFormationResult(properties);
665 }
666 const ret = new cfn_parse.FromCloudFormationPropertyObject();
667 ret.addPropertyResult('key', 'Key', cfn_parse.FromCloudFormation.getString(properties.Key));
668 ret.addPropertyResult('value', 'Value', cfn_parse.FromCloudFormation.getString(properties.Value));
669 ret.addUnrecognizedPropertiesAsExtra(properties);
670 return ret;
671}
672/**
673 * Determine whether the given properties match those of a `CfnHostedZoneProps`
674 *
675 * @param properties - the TypeScript properties of a `CfnHostedZoneProps`
676 *
677 * @returns the result of the validation.
678 */
679function CfnHostedZonePropsValidator(properties) {
680 if (!cdk.canInspect(properties)) {
681 return cdk.VALIDATION_SUCCESS;
682 }
683 const errors = new cdk.ValidationResults();
684 if (typeof properties !== 'object') {
685 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
686 }
687 errors.collect(cdk.propertyValidator('hostedZoneConfig', CfnHostedZone_HostedZoneConfigPropertyValidator)(properties.hostedZoneConfig));
688 errors.collect(cdk.propertyValidator('hostedZoneTags', cdk.listValidator(CfnHostedZone_HostedZoneTagPropertyValidator))(properties.hostedZoneTags));
689 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
690 errors.collect(cdk.propertyValidator('queryLoggingConfig', CfnHostedZone_QueryLoggingConfigPropertyValidator)(properties.queryLoggingConfig));
691 errors.collect(cdk.propertyValidator('vpcs', cdk.listValidator(CfnHostedZone_VPCPropertyValidator))(properties.vpcs));
692 return errors.wrap('supplied properties not correct for "CfnHostedZoneProps"');
693}
694/**
695 * Renders the AWS CloudFormation properties of an `AWS::Route53::HostedZone` resource
696 *
697 * @param properties - the TypeScript properties of a `CfnHostedZoneProps`
698 *
699 * @returns the AWS CloudFormation properties of an `AWS::Route53::HostedZone` resource.
700 */
701// @ts-ignore TS6133
702function cfnHostedZonePropsToCloudFormation(properties) {
703 if (!cdk.canInspect(properties)) {
704 return properties;
705 }
706 CfnHostedZonePropsValidator(properties).assertSuccess();
707 return {
708 HostedZoneConfig: cfnHostedZoneHostedZoneConfigPropertyToCloudFormation(properties.hostedZoneConfig),
709 HostedZoneTags: cdk.listMapper(cfnHostedZoneHostedZoneTagPropertyToCloudFormation)(properties.hostedZoneTags),
710 Name: cdk.stringToCloudFormation(properties.name),
711 QueryLoggingConfig: cfnHostedZoneQueryLoggingConfigPropertyToCloudFormation(properties.queryLoggingConfig),
712 VPCs: cdk.listMapper(cfnHostedZoneVPCPropertyToCloudFormation)(properties.vpcs),
713 };
714}
715// @ts-ignore TS6133
716function CfnHostedZonePropsFromCloudFormation(properties) {
717 properties = properties == null ? {} : properties;
718 if (typeof properties !== 'object') {
719 return new cfn_parse.FromCloudFormationResult(properties);
720 }
721 const ret = new cfn_parse.FromCloudFormationPropertyObject();
722 ret.addPropertyResult('hostedZoneConfig', 'HostedZoneConfig', properties.HostedZoneConfig != null ? CfnHostedZoneHostedZoneConfigPropertyFromCloudFormation(properties.HostedZoneConfig) : undefined);
723 ret.addPropertyResult('hostedZoneTags', 'HostedZoneTags', properties.HostedZoneTags != null ? cfn_parse.FromCloudFormation.getArray(CfnHostedZoneHostedZoneTagPropertyFromCloudFormation)(properties.HostedZoneTags) : undefined);
724 ret.addPropertyResult('name', 'Name', properties.Name != null ? cfn_parse.FromCloudFormation.getString(properties.Name) : undefined);
725 ret.addPropertyResult('queryLoggingConfig', 'QueryLoggingConfig', properties.QueryLoggingConfig != null ? CfnHostedZoneQueryLoggingConfigPropertyFromCloudFormation(properties.QueryLoggingConfig) : undefined);
726 ret.addPropertyResult('vpcs', 'VPCs', properties.VPCs != null ? cfn_parse.FromCloudFormation.getArray(CfnHostedZoneVPCPropertyFromCloudFormation)(properties.VPCs) : undefined);
727 ret.addUnrecognizedPropertiesAsExtra(properties);
728 return ret;
729}
730/**
731 * A CloudFormation `AWS::Route53::HostedZone`
732 *
733 * Creates a new public or private hosted zone. You create records in a public hosted zone to define how you want to route traffic on the internet for a domain, such as example.com, and its subdomains (apex.example.com, acme.example.com). You create records in a private hosted zone to define how you want to route traffic for a domain and its subdomains within one or more Amazon Virtual Private Clouds (Amazon VPCs).
734 *
735 * > You can't convert a public hosted zone to a private hosted zone or vice versa. Instead, you must create a new hosted zone with the same name and create new resource record sets.
736 *
737 * For more information about charges for hosted zones, see [Amazon Route 53 Pricing](https://docs.aws.amazon.com/route53/pricing/) .
738 *
739 * Note the following:
740 *
741 * - You can't create a hosted zone for a top-level domain (TLD) such as .com.
742 * - If your domain is registered with a registrar other than Route 53, you must update the name servers with your registrar to make Route 53 the DNS service for the domain. For more information, see [Migrating DNS Service for an Existing Domain to Amazon Route 53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/MigratingDNS.html) in the *Amazon Route 53 Developer Guide* .
743 *
744 * When you submit a `CreateHostedZone` request, the initial status of the hosted zone is `PENDING` . For public hosted zones, this means that the NS and SOA records are not yet available on all Route 53 DNS servers. When the NS and SOA records are available, the status of the zone changes to `INSYNC` .
745 *
746 * The `CreateHostedZone` request requires the caller to have an `ec2:DescribeVpcs` permission.
747 *
748 * > When creating private hosted zones, the Amazon VPC must belong to the same partition where the hosted zone is created. A partition is a group of AWS Regions . Each AWS account is scoped to one partition.
749 * >
750 * > The following are the supported partitions:
751 * >
752 * > - `aws` - AWS Regions
753 * > - `aws-cn` - China Regions
754 * > - `aws-us-gov` - AWS GovCloud (US) Region
755 * >
756 * > For more information, see [Access Management](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) in the *AWS General Reference* .
757 *
758 * @cloudformationResource AWS::Route53::HostedZone
759 * @stability external
760 *
761 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-hostedzone.html
762 */
763class CfnHostedZone extends cdk.CfnResource {
764 /**
765 * Create a new `AWS::Route53::HostedZone`.
766 *
767 * @param scope - scope in which this resource is defined
768 * @param id - scoped id of the resource
769 * @param props - resource properties
770 */
771 constructor(scope, id, props = {}) {
772 super(scope, id, { type: CfnHostedZone.CFN_RESOURCE_TYPE_NAME, properties: props });
773 try {
774 jsiiDeprecationWarnings._aws_cdk_aws_route53_CfnHostedZoneProps(props);
775 }
776 catch (error) {
777 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
778 Error.captureStackTrace(error, CfnHostedZone);
779 }
780 throw error;
781 }
782 this.attrId = cdk.Token.asString(this.getAtt('Id'));
783 this.attrNameServers = cdk.Token.asList(this.getAtt('NameServers'));
784 this.hostedZoneConfig = props.hostedZoneConfig;
785 this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::Route53::HostedZone", props.hostedZoneTags, { tagPropertyName: 'hostedZoneTags' });
786 this.name = props.name;
787 this.queryLoggingConfig = props.queryLoggingConfig;
788 this.vpcs = props.vpcs;
789 }
790 /**
791 * A factory method that creates a new instance of this class from an object
792 * containing the CloudFormation properties of this resource.
793 * Used in the @aws-cdk/cloudformation-include module.
794 *
795 * @internal
796 */
797 static _fromCloudFormation(scope, id, resourceAttributes, options) {
798 resourceAttributes = resourceAttributes || {};
799 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
800 const propsResult = CfnHostedZonePropsFromCloudFormation(resourceProperties);
801 const ret = new CfnHostedZone(scope, id, propsResult.value);
802 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
803 ret.addPropertyOverride(propKey, propVal);
804 }
805 options.parser.handleAttributes(ret, resourceAttributes, id);
806 return ret;
807 }
808 /**
809 * Examines the CloudFormation resource and discloses attributes.
810 *
811 * @param inspector - tree inspector to collect and process attributes
812 *
813 */
814 inspect(inspector) {
815 inspector.addAttribute("aws:cdk:cloudformation:type", CfnHostedZone.CFN_RESOURCE_TYPE_NAME);
816 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
817 }
818 get cfnProperties() {
819 return {
820 hostedZoneConfig: this.hostedZoneConfig,
821 hostedZoneTags: this.tags.renderTags(),
822 name: this.name,
823 queryLoggingConfig: this.queryLoggingConfig,
824 vpcs: this.vpcs,
825 };
826 }
827 renderProperties(props) {
828 return cfnHostedZonePropsToCloudFormation(props);
829 }
830}
831exports.CfnHostedZone = CfnHostedZone;
832_d = JSII_RTTI_SYMBOL_1;
833CfnHostedZone[_d] = { fqn: "@aws-cdk/aws-route53.CfnHostedZone", version: "1.204.0" };
834/**
835 * The CloudFormation resource type name for this resource class.
836 */
837CfnHostedZone.CFN_RESOURCE_TYPE_NAME = "AWS::Route53::HostedZone";
838/**
839 * Determine whether the given properties match those of a `HostedZoneConfigProperty`
840 *
841 * @param properties - the TypeScript properties of a `HostedZoneConfigProperty`
842 *
843 * @returns the result of the validation.
844 */
845function CfnHostedZone_HostedZoneConfigPropertyValidator(properties) {
846 if (!cdk.canInspect(properties)) {
847 return cdk.VALIDATION_SUCCESS;
848 }
849 const errors = new cdk.ValidationResults();
850 if (typeof properties !== 'object') {
851 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
852 }
853 errors.collect(cdk.propertyValidator('comment', cdk.validateString)(properties.comment));
854 return errors.wrap('supplied properties not correct for "HostedZoneConfigProperty"');
855}
856/**
857 * Renders the AWS CloudFormation properties of an `AWS::Route53::HostedZone.HostedZoneConfig` resource
858 *
859 * @param properties - the TypeScript properties of a `HostedZoneConfigProperty`
860 *
861 * @returns the AWS CloudFormation properties of an `AWS::Route53::HostedZone.HostedZoneConfig` resource.
862 */
863// @ts-ignore TS6133
864function cfnHostedZoneHostedZoneConfigPropertyToCloudFormation(properties) {
865 if (!cdk.canInspect(properties)) {
866 return properties;
867 }
868 CfnHostedZone_HostedZoneConfigPropertyValidator(properties).assertSuccess();
869 return {
870 Comment: cdk.stringToCloudFormation(properties.comment),
871 };
872}
873// @ts-ignore TS6133
874function CfnHostedZoneHostedZoneConfigPropertyFromCloudFormation(properties) {
875 if (cdk.isResolvableObject(properties)) {
876 return new cfn_parse.FromCloudFormationResult(properties);
877 }
878 properties = properties == null ? {} : properties;
879 if (typeof properties !== 'object') {
880 return new cfn_parse.FromCloudFormationResult(properties);
881 }
882 const ret = new cfn_parse.FromCloudFormationPropertyObject();
883 ret.addPropertyResult('comment', 'Comment', properties.Comment != null ? cfn_parse.FromCloudFormation.getString(properties.Comment) : undefined);
884 ret.addUnrecognizedPropertiesAsExtra(properties);
885 return ret;
886}
887/**
888 * Determine whether the given properties match those of a `HostedZoneTagProperty`
889 *
890 * @param properties - the TypeScript properties of a `HostedZoneTagProperty`
891 *
892 * @returns the result of the validation.
893 */
894function CfnHostedZone_HostedZoneTagPropertyValidator(properties) {
895 if (!cdk.canInspect(properties)) {
896 return cdk.VALIDATION_SUCCESS;
897 }
898 const errors = new cdk.ValidationResults();
899 if (typeof properties !== 'object') {
900 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
901 }
902 errors.collect(cdk.propertyValidator('key', cdk.requiredValidator)(properties.key));
903 errors.collect(cdk.propertyValidator('key', cdk.validateString)(properties.key));
904 errors.collect(cdk.propertyValidator('value', cdk.requiredValidator)(properties.value));
905 errors.collect(cdk.propertyValidator('value', cdk.validateString)(properties.value));
906 return errors.wrap('supplied properties not correct for "HostedZoneTagProperty"');
907}
908/**
909 * Renders the AWS CloudFormation properties of an `AWS::Route53::HostedZone.HostedZoneTag` resource
910 *
911 * @param properties - the TypeScript properties of a `HostedZoneTagProperty`
912 *
913 * @returns the AWS CloudFormation properties of an `AWS::Route53::HostedZone.HostedZoneTag` resource.
914 */
915// @ts-ignore TS6133
916function cfnHostedZoneHostedZoneTagPropertyToCloudFormation(properties) {
917 if (!cdk.canInspect(properties)) {
918 return properties;
919 }
920 CfnHostedZone_HostedZoneTagPropertyValidator(properties).assertSuccess();
921 return {
922 Key: cdk.stringToCloudFormation(properties.key),
923 Value: cdk.stringToCloudFormation(properties.value),
924 };
925}
926// @ts-ignore TS6133
927function CfnHostedZoneHostedZoneTagPropertyFromCloudFormation(properties) {
928 if (cdk.isResolvableObject(properties)) {
929 return new cfn_parse.FromCloudFormationResult(properties);
930 }
931 properties = properties == null ? {} : properties;
932 if (typeof properties !== 'object') {
933 return new cfn_parse.FromCloudFormationResult(properties);
934 }
935 const ret = new cfn_parse.FromCloudFormationPropertyObject();
936 ret.addPropertyResult('key', 'Key', cfn_parse.FromCloudFormation.getString(properties.Key));
937 ret.addPropertyResult('value', 'Value', cfn_parse.FromCloudFormation.getString(properties.Value));
938 ret.addUnrecognizedPropertiesAsExtra(properties);
939 return ret;
940}
941/**
942 * Determine whether the given properties match those of a `QueryLoggingConfigProperty`
943 *
944 * @param properties - the TypeScript properties of a `QueryLoggingConfigProperty`
945 *
946 * @returns the result of the validation.
947 */
948function CfnHostedZone_QueryLoggingConfigPropertyValidator(properties) {
949 if (!cdk.canInspect(properties)) {
950 return cdk.VALIDATION_SUCCESS;
951 }
952 const errors = new cdk.ValidationResults();
953 if (typeof properties !== 'object') {
954 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
955 }
956 errors.collect(cdk.propertyValidator('cloudWatchLogsLogGroupArn', cdk.requiredValidator)(properties.cloudWatchLogsLogGroupArn));
957 errors.collect(cdk.propertyValidator('cloudWatchLogsLogGroupArn', cdk.validateString)(properties.cloudWatchLogsLogGroupArn));
958 return errors.wrap('supplied properties not correct for "QueryLoggingConfigProperty"');
959}
960/**
961 * Renders the AWS CloudFormation properties of an `AWS::Route53::HostedZone.QueryLoggingConfig` resource
962 *
963 * @param properties - the TypeScript properties of a `QueryLoggingConfigProperty`
964 *
965 * @returns the AWS CloudFormation properties of an `AWS::Route53::HostedZone.QueryLoggingConfig` resource.
966 */
967// @ts-ignore TS6133
968function cfnHostedZoneQueryLoggingConfigPropertyToCloudFormation(properties) {
969 if (!cdk.canInspect(properties)) {
970 return properties;
971 }
972 CfnHostedZone_QueryLoggingConfigPropertyValidator(properties).assertSuccess();
973 return {
974 CloudWatchLogsLogGroupArn: cdk.stringToCloudFormation(properties.cloudWatchLogsLogGroupArn),
975 };
976}
977// @ts-ignore TS6133
978function CfnHostedZoneQueryLoggingConfigPropertyFromCloudFormation(properties) {
979 if (cdk.isResolvableObject(properties)) {
980 return new cfn_parse.FromCloudFormationResult(properties);
981 }
982 properties = properties == null ? {} : properties;
983 if (typeof properties !== 'object') {
984 return new cfn_parse.FromCloudFormationResult(properties);
985 }
986 const ret = new cfn_parse.FromCloudFormationPropertyObject();
987 ret.addPropertyResult('cloudWatchLogsLogGroupArn', 'CloudWatchLogsLogGroupArn', cfn_parse.FromCloudFormation.getString(properties.CloudWatchLogsLogGroupArn));
988 ret.addUnrecognizedPropertiesAsExtra(properties);
989 return ret;
990}
991/**
992 * Determine whether the given properties match those of a `VPCProperty`
993 *
994 * @param properties - the TypeScript properties of a `VPCProperty`
995 *
996 * @returns the result of the validation.
997 */
998function CfnHostedZone_VPCPropertyValidator(properties) {
999 if (!cdk.canInspect(properties)) {
1000 return cdk.VALIDATION_SUCCESS;
1001 }
1002 const errors = new cdk.ValidationResults();
1003 if (typeof properties !== 'object') {
1004 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1005 }
1006 errors.collect(cdk.propertyValidator('vpcId', cdk.requiredValidator)(properties.vpcId));
1007 errors.collect(cdk.propertyValidator('vpcId', cdk.validateString)(properties.vpcId));
1008 errors.collect(cdk.propertyValidator('vpcRegion', cdk.requiredValidator)(properties.vpcRegion));
1009 errors.collect(cdk.propertyValidator('vpcRegion', cdk.validateString)(properties.vpcRegion));
1010 return errors.wrap('supplied properties not correct for "VPCProperty"');
1011}
1012/**
1013 * Renders the AWS CloudFormation properties of an `AWS::Route53::HostedZone.VPC` resource
1014 *
1015 * @param properties - the TypeScript properties of a `VPCProperty`
1016 *
1017 * @returns the AWS CloudFormation properties of an `AWS::Route53::HostedZone.VPC` resource.
1018 */
1019// @ts-ignore TS6133
1020function cfnHostedZoneVPCPropertyToCloudFormation(properties) {
1021 if (!cdk.canInspect(properties)) {
1022 return properties;
1023 }
1024 CfnHostedZone_VPCPropertyValidator(properties).assertSuccess();
1025 return {
1026 VPCId: cdk.stringToCloudFormation(properties.vpcId),
1027 VPCRegion: cdk.stringToCloudFormation(properties.vpcRegion),
1028 };
1029}
1030// @ts-ignore TS6133
1031function CfnHostedZoneVPCPropertyFromCloudFormation(properties) {
1032 if (cdk.isResolvableObject(properties)) {
1033 return new cfn_parse.FromCloudFormationResult(properties);
1034 }
1035 properties = properties == null ? {} : properties;
1036 if (typeof properties !== 'object') {
1037 return new cfn_parse.FromCloudFormationResult(properties);
1038 }
1039 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1040 ret.addPropertyResult('vpcId', 'VPCId', cfn_parse.FromCloudFormation.getString(properties.VPCId));
1041 ret.addPropertyResult('vpcRegion', 'VPCRegion', cfn_parse.FromCloudFormation.getString(properties.VPCRegion));
1042 ret.addUnrecognizedPropertiesAsExtra(properties);
1043 return ret;
1044}
1045/**
1046 * Determine whether the given properties match those of a `CfnKeySigningKeyProps`
1047 *
1048 * @param properties - the TypeScript properties of a `CfnKeySigningKeyProps`
1049 *
1050 * @returns the result of the validation.
1051 */
1052function CfnKeySigningKeyPropsValidator(properties) {
1053 if (!cdk.canInspect(properties)) {
1054 return cdk.VALIDATION_SUCCESS;
1055 }
1056 const errors = new cdk.ValidationResults();
1057 if (typeof properties !== 'object') {
1058 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1059 }
1060 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.requiredValidator)(properties.hostedZoneId));
1061 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.validateString)(properties.hostedZoneId));
1062 errors.collect(cdk.propertyValidator('keyManagementServiceArn', cdk.requiredValidator)(properties.keyManagementServiceArn));
1063 errors.collect(cdk.propertyValidator('keyManagementServiceArn', cdk.validateString)(properties.keyManagementServiceArn));
1064 errors.collect(cdk.propertyValidator('name', cdk.requiredValidator)(properties.name));
1065 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
1066 errors.collect(cdk.propertyValidator('status', cdk.requiredValidator)(properties.status));
1067 errors.collect(cdk.propertyValidator('status', cdk.validateString)(properties.status));
1068 return errors.wrap('supplied properties not correct for "CfnKeySigningKeyProps"');
1069}
1070/**
1071 * Renders the AWS CloudFormation properties of an `AWS::Route53::KeySigningKey` resource
1072 *
1073 * @param properties - the TypeScript properties of a `CfnKeySigningKeyProps`
1074 *
1075 * @returns the AWS CloudFormation properties of an `AWS::Route53::KeySigningKey` resource.
1076 */
1077// @ts-ignore TS6133
1078function cfnKeySigningKeyPropsToCloudFormation(properties) {
1079 if (!cdk.canInspect(properties)) {
1080 return properties;
1081 }
1082 CfnKeySigningKeyPropsValidator(properties).assertSuccess();
1083 return {
1084 HostedZoneId: cdk.stringToCloudFormation(properties.hostedZoneId),
1085 KeyManagementServiceArn: cdk.stringToCloudFormation(properties.keyManagementServiceArn),
1086 Name: cdk.stringToCloudFormation(properties.name),
1087 Status: cdk.stringToCloudFormation(properties.status),
1088 };
1089}
1090// @ts-ignore TS6133
1091function CfnKeySigningKeyPropsFromCloudFormation(properties) {
1092 properties = properties == null ? {} : properties;
1093 if (typeof properties !== 'object') {
1094 return new cfn_parse.FromCloudFormationResult(properties);
1095 }
1096 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1097 ret.addPropertyResult('hostedZoneId', 'HostedZoneId', cfn_parse.FromCloudFormation.getString(properties.HostedZoneId));
1098 ret.addPropertyResult('keyManagementServiceArn', 'KeyManagementServiceArn', cfn_parse.FromCloudFormation.getString(properties.KeyManagementServiceArn));
1099 ret.addPropertyResult('name', 'Name', cfn_parse.FromCloudFormation.getString(properties.Name));
1100 ret.addPropertyResult('status', 'Status', cfn_parse.FromCloudFormation.getString(properties.Status));
1101 ret.addUnrecognizedPropertiesAsExtra(properties);
1102 return ret;
1103}
1104/**
1105 * A CloudFormation `AWS::Route53::KeySigningKey`
1106 *
1107 * The `AWS::Route53::KeySigningKey` resource creates a new key-signing key (KSK) in a hosted zone. The hosted zone ID is passed as a parameter in the KSK properties. You can specify the properties of this KSK using the `Name` , `Status` , and `KeyManagementServiceArn` properties of the resource.
1108 *
1109 * @cloudformationResource AWS::Route53::KeySigningKey
1110 * @stability external
1111 *
1112 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-keysigningkey.html
1113 */
1114class CfnKeySigningKey extends cdk.CfnResource {
1115 /**
1116 * Create a new `AWS::Route53::KeySigningKey`.
1117 *
1118 * @param scope - scope in which this resource is defined
1119 * @param id - scoped id of the resource
1120 * @param props - resource properties
1121 */
1122 constructor(scope, id, props) {
1123 super(scope, id, { type: CfnKeySigningKey.CFN_RESOURCE_TYPE_NAME, properties: props });
1124 try {
1125 jsiiDeprecationWarnings._aws_cdk_aws_route53_CfnKeySigningKeyProps(props);
1126 }
1127 catch (error) {
1128 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1129 Error.captureStackTrace(error, CfnKeySigningKey);
1130 }
1131 throw error;
1132 }
1133 cdk.requireProperty(props, 'hostedZoneId', this);
1134 cdk.requireProperty(props, 'keyManagementServiceArn', this);
1135 cdk.requireProperty(props, 'name', this);
1136 cdk.requireProperty(props, 'status', this);
1137 this.hostedZoneId = props.hostedZoneId;
1138 this.keyManagementServiceArn = props.keyManagementServiceArn;
1139 this.name = props.name;
1140 this.status = props.status;
1141 }
1142 /**
1143 * A factory method that creates a new instance of this class from an object
1144 * containing the CloudFormation properties of this resource.
1145 * Used in the @aws-cdk/cloudformation-include module.
1146 *
1147 * @internal
1148 */
1149 static _fromCloudFormation(scope, id, resourceAttributes, options) {
1150 resourceAttributes = resourceAttributes || {};
1151 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
1152 const propsResult = CfnKeySigningKeyPropsFromCloudFormation(resourceProperties);
1153 const ret = new CfnKeySigningKey(scope, id, propsResult.value);
1154 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
1155 ret.addPropertyOverride(propKey, propVal);
1156 }
1157 options.parser.handleAttributes(ret, resourceAttributes, id);
1158 return ret;
1159 }
1160 /**
1161 * Examines the CloudFormation resource and discloses attributes.
1162 *
1163 * @param inspector - tree inspector to collect and process attributes
1164 *
1165 */
1166 inspect(inspector) {
1167 inspector.addAttribute("aws:cdk:cloudformation:type", CfnKeySigningKey.CFN_RESOURCE_TYPE_NAME);
1168 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
1169 }
1170 get cfnProperties() {
1171 return {
1172 hostedZoneId: this.hostedZoneId,
1173 keyManagementServiceArn: this.keyManagementServiceArn,
1174 name: this.name,
1175 status: this.status,
1176 };
1177 }
1178 renderProperties(props) {
1179 return cfnKeySigningKeyPropsToCloudFormation(props);
1180 }
1181}
1182exports.CfnKeySigningKey = CfnKeySigningKey;
1183_e = JSII_RTTI_SYMBOL_1;
1184CfnKeySigningKey[_e] = { fqn: "@aws-cdk/aws-route53.CfnKeySigningKey", version: "1.204.0" };
1185/**
1186 * The CloudFormation resource type name for this resource class.
1187 */
1188CfnKeySigningKey.CFN_RESOURCE_TYPE_NAME = "AWS::Route53::KeySigningKey";
1189/**
1190 * Determine whether the given properties match those of a `CfnRecordSetProps`
1191 *
1192 * @param properties - the TypeScript properties of a `CfnRecordSetProps`
1193 *
1194 * @returns the result of the validation.
1195 */
1196function CfnRecordSetPropsValidator(properties) {
1197 if (!cdk.canInspect(properties)) {
1198 return cdk.VALIDATION_SUCCESS;
1199 }
1200 const errors = new cdk.ValidationResults();
1201 if (typeof properties !== 'object') {
1202 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1203 }
1204 errors.collect(cdk.propertyValidator('aliasTarget', CfnRecordSet_AliasTargetPropertyValidator)(properties.aliasTarget));
1205 errors.collect(cdk.propertyValidator('cidrRoutingConfig', CfnRecordSet_CidrRoutingConfigPropertyValidator)(properties.cidrRoutingConfig));
1206 errors.collect(cdk.propertyValidator('comment', cdk.validateString)(properties.comment));
1207 errors.collect(cdk.propertyValidator('failover', cdk.validateString)(properties.failover));
1208 errors.collect(cdk.propertyValidator('geoLocation', CfnRecordSet_GeoLocationPropertyValidator)(properties.geoLocation));
1209 errors.collect(cdk.propertyValidator('healthCheckId', cdk.validateString)(properties.healthCheckId));
1210 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.validateString)(properties.hostedZoneId));
1211 errors.collect(cdk.propertyValidator('hostedZoneName', cdk.validateString)(properties.hostedZoneName));
1212 errors.collect(cdk.propertyValidator('multiValueAnswer', cdk.validateBoolean)(properties.multiValueAnswer));
1213 errors.collect(cdk.propertyValidator('name', cdk.requiredValidator)(properties.name));
1214 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
1215 errors.collect(cdk.propertyValidator('region', cdk.validateString)(properties.region));
1216 errors.collect(cdk.propertyValidator('resourceRecords', cdk.listValidator(cdk.validateString))(properties.resourceRecords));
1217 errors.collect(cdk.propertyValidator('setIdentifier', cdk.validateString)(properties.setIdentifier));
1218 errors.collect(cdk.propertyValidator('ttl', cdk.validateString)(properties.ttl));
1219 errors.collect(cdk.propertyValidator('type', cdk.requiredValidator)(properties.type));
1220 errors.collect(cdk.propertyValidator('type', cdk.validateString)(properties.type));
1221 errors.collect(cdk.propertyValidator('weight', cdk.validateNumber)(properties.weight));
1222 return errors.wrap('supplied properties not correct for "CfnRecordSetProps"');
1223}
1224/**
1225 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSet` resource
1226 *
1227 * @param properties - the TypeScript properties of a `CfnRecordSetProps`
1228 *
1229 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSet` resource.
1230 */
1231// @ts-ignore TS6133
1232function cfnRecordSetPropsToCloudFormation(properties) {
1233 if (!cdk.canInspect(properties)) {
1234 return properties;
1235 }
1236 CfnRecordSetPropsValidator(properties).assertSuccess();
1237 return {
1238 Name: cdk.stringToCloudFormation(properties.name),
1239 Type: cdk.stringToCloudFormation(properties.type),
1240 AliasTarget: cfnRecordSetAliasTargetPropertyToCloudFormation(properties.aliasTarget),
1241 CidrRoutingConfig: cfnRecordSetCidrRoutingConfigPropertyToCloudFormation(properties.cidrRoutingConfig),
1242 Comment: cdk.stringToCloudFormation(properties.comment),
1243 Failover: cdk.stringToCloudFormation(properties.failover),
1244 GeoLocation: cfnRecordSetGeoLocationPropertyToCloudFormation(properties.geoLocation),
1245 HealthCheckId: cdk.stringToCloudFormation(properties.healthCheckId),
1246 HostedZoneId: cdk.stringToCloudFormation(properties.hostedZoneId),
1247 HostedZoneName: cdk.stringToCloudFormation(properties.hostedZoneName),
1248 MultiValueAnswer: cdk.booleanToCloudFormation(properties.multiValueAnswer),
1249 Region: cdk.stringToCloudFormation(properties.region),
1250 ResourceRecords: cdk.listMapper(cdk.stringToCloudFormation)(properties.resourceRecords),
1251 SetIdentifier: cdk.stringToCloudFormation(properties.setIdentifier),
1252 TTL: cdk.stringToCloudFormation(properties.ttl),
1253 Weight: cdk.numberToCloudFormation(properties.weight),
1254 };
1255}
1256// @ts-ignore TS6133
1257function CfnRecordSetPropsFromCloudFormation(properties) {
1258 properties = properties == null ? {} : properties;
1259 if (typeof properties !== 'object') {
1260 return new cfn_parse.FromCloudFormationResult(properties);
1261 }
1262 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1263 ret.addPropertyResult('name', 'Name', cfn_parse.FromCloudFormation.getString(properties.Name));
1264 ret.addPropertyResult('type', 'Type', cfn_parse.FromCloudFormation.getString(properties.Type));
1265 ret.addPropertyResult('aliasTarget', 'AliasTarget', properties.AliasTarget != null ? CfnRecordSetAliasTargetPropertyFromCloudFormation(properties.AliasTarget) : undefined);
1266 ret.addPropertyResult('cidrRoutingConfig', 'CidrRoutingConfig', properties.CidrRoutingConfig != null ? CfnRecordSetCidrRoutingConfigPropertyFromCloudFormation(properties.CidrRoutingConfig) : undefined);
1267 ret.addPropertyResult('comment', 'Comment', properties.Comment != null ? cfn_parse.FromCloudFormation.getString(properties.Comment) : undefined);
1268 ret.addPropertyResult('failover', 'Failover', properties.Failover != null ? cfn_parse.FromCloudFormation.getString(properties.Failover) : undefined);
1269 ret.addPropertyResult('geoLocation', 'GeoLocation', properties.GeoLocation != null ? CfnRecordSetGeoLocationPropertyFromCloudFormation(properties.GeoLocation) : undefined);
1270 ret.addPropertyResult('healthCheckId', 'HealthCheckId', properties.HealthCheckId != null ? cfn_parse.FromCloudFormation.getString(properties.HealthCheckId) : undefined);
1271 ret.addPropertyResult('hostedZoneId', 'HostedZoneId', properties.HostedZoneId != null ? cfn_parse.FromCloudFormation.getString(properties.HostedZoneId) : undefined);
1272 ret.addPropertyResult('hostedZoneName', 'HostedZoneName', properties.HostedZoneName != null ? cfn_parse.FromCloudFormation.getString(properties.HostedZoneName) : undefined);
1273 ret.addPropertyResult('multiValueAnswer', 'MultiValueAnswer', properties.MultiValueAnswer != null ? cfn_parse.FromCloudFormation.getBoolean(properties.MultiValueAnswer) : undefined);
1274 ret.addPropertyResult('region', 'Region', properties.Region != null ? cfn_parse.FromCloudFormation.getString(properties.Region) : undefined);
1275 ret.addPropertyResult('resourceRecords', 'ResourceRecords', properties.ResourceRecords != null ? cfn_parse.FromCloudFormation.getStringArray(properties.ResourceRecords) : undefined);
1276 ret.addPropertyResult('setIdentifier', 'SetIdentifier', properties.SetIdentifier != null ? cfn_parse.FromCloudFormation.getString(properties.SetIdentifier) : undefined);
1277 ret.addPropertyResult('ttl', 'TTL', properties.TTL != null ? cfn_parse.FromCloudFormation.getString(properties.TTL) : undefined);
1278 ret.addPropertyResult('weight', 'Weight', properties.Weight != null ? cfn_parse.FromCloudFormation.getNumber(properties.Weight) : undefined);
1279 ret.addUnrecognizedPropertiesAsExtra(properties);
1280 return ret;
1281}
1282/**
1283 * A CloudFormation `AWS::Route53::RecordSet`
1284 *
1285 * Information about the record that you want to create.
1286 *
1287 * The `AWS::Route53::RecordSet` type can be used as a standalone resource or as an embedded property in the `AWS::Route53::RecordSetGroup` type. Note that some `AWS::Route53::RecordSet` properties are valid only when used within `AWS::Route53::RecordSetGroup` .
1288 *
1289 * For more information, see [ChangeResourceRecordSets](https://docs.aws.amazon.com/Route53/latest/APIReference/API_ChangeResourceRecordSets.html) in the *Amazon Route 53 API Reference* .
1290 *
1291 * @cloudformationResource AWS::Route53::RecordSet
1292 * @stability external
1293 *
1294 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-recordset.html
1295 */
1296class CfnRecordSet extends cdk.CfnResource {
1297 /**
1298 * Create a new `AWS::Route53::RecordSet`.
1299 *
1300 * @param scope - scope in which this resource is defined
1301 * @param id - scoped id of the resource
1302 * @param props - resource properties
1303 */
1304 constructor(scope, id, props) {
1305 super(scope, id, { type: CfnRecordSet.CFN_RESOURCE_TYPE_NAME, properties: props });
1306 try {
1307 jsiiDeprecationWarnings._aws_cdk_aws_route53_CfnRecordSetProps(props);
1308 }
1309 catch (error) {
1310 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1311 Error.captureStackTrace(error, CfnRecordSet);
1312 }
1313 throw error;
1314 }
1315 cdk.requireProperty(props, 'name', this);
1316 cdk.requireProperty(props, 'type', this);
1317 this.name = props.name;
1318 this.type = props.type;
1319 this.aliasTarget = props.aliasTarget;
1320 this.cidrRoutingConfig = props.cidrRoutingConfig;
1321 this.comment = props.comment;
1322 this.failover = props.failover;
1323 this.geoLocation = props.geoLocation;
1324 this.healthCheckId = props.healthCheckId;
1325 this.hostedZoneId = props.hostedZoneId;
1326 this.hostedZoneName = props.hostedZoneName;
1327 this.multiValueAnswer = props.multiValueAnswer;
1328 this.region = props.region;
1329 this.resourceRecords = props.resourceRecords;
1330 this.setIdentifier = props.setIdentifier;
1331 this.ttl = props.ttl;
1332 this.weight = props.weight;
1333 }
1334 /**
1335 * A factory method that creates a new instance of this class from an object
1336 * containing the CloudFormation properties of this resource.
1337 * Used in the @aws-cdk/cloudformation-include module.
1338 *
1339 * @internal
1340 */
1341 static _fromCloudFormation(scope, id, resourceAttributes, options) {
1342 resourceAttributes = resourceAttributes || {};
1343 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
1344 const propsResult = CfnRecordSetPropsFromCloudFormation(resourceProperties);
1345 const ret = new CfnRecordSet(scope, id, propsResult.value);
1346 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
1347 ret.addPropertyOverride(propKey, propVal);
1348 }
1349 options.parser.handleAttributes(ret, resourceAttributes, id);
1350 return ret;
1351 }
1352 /**
1353 * Examines the CloudFormation resource and discloses attributes.
1354 *
1355 * @param inspector - tree inspector to collect and process attributes
1356 *
1357 */
1358 inspect(inspector) {
1359 inspector.addAttribute("aws:cdk:cloudformation:type", CfnRecordSet.CFN_RESOURCE_TYPE_NAME);
1360 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
1361 }
1362 get cfnProperties() {
1363 return {
1364 name: this.name,
1365 type: this.type,
1366 aliasTarget: this.aliasTarget,
1367 cidrRoutingConfig: this.cidrRoutingConfig,
1368 comment: this.comment,
1369 failover: this.failover,
1370 geoLocation: this.geoLocation,
1371 healthCheckId: this.healthCheckId,
1372 hostedZoneId: this.hostedZoneId,
1373 hostedZoneName: this.hostedZoneName,
1374 multiValueAnswer: this.multiValueAnswer,
1375 region: this.region,
1376 resourceRecords: this.resourceRecords,
1377 setIdentifier: this.setIdentifier,
1378 ttl: this.ttl,
1379 weight: this.weight,
1380 };
1381 }
1382 renderProperties(props) {
1383 return cfnRecordSetPropsToCloudFormation(props);
1384 }
1385}
1386exports.CfnRecordSet = CfnRecordSet;
1387_f = JSII_RTTI_SYMBOL_1;
1388CfnRecordSet[_f] = { fqn: "@aws-cdk/aws-route53.CfnRecordSet", version: "1.204.0" };
1389/**
1390 * The CloudFormation resource type name for this resource class.
1391 */
1392CfnRecordSet.CFN_RESOURCE_TYPE_NAME = "AWS::Route53::RecordSet";
1393/**
1394 * Determine whether the given properties match those of a `AliasTargetProperty`
1395 *
1396 * @param properties - the TypeScript properties of a `AliasTargetProperty`
1397 *
1398 * @returns the result of the validation.
1399 */
1400function CfnRecordSet_AliasTargetPropertyValidator(properties) {
1401 if (!cdk.canInspect(properties)) {
1402 return cdk.VALIDATION_SUCCESS;
1403 }
1404 const errors = new cdk.ValidationResults();
1405 if (typeof properties !== 'object') {
1406 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1407 }
1408 errors.collect(cdk.propertyValidator('dnsName', cdk.requiredValidator)(properties.dnsName));
1409 errors.collect(cdk.propertyValidator('dnsName', cdk.validateString)(properties.dnsName));
1410 errors.collect(cdk.propertyValidator('evaluateTargetHealth', cdk.validateBoolean)(properties.evaluateTargetHealth));
1411 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.requiredValidator)(properties.hostedZoneId));
1412 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.validateString)(properties.hostedZoneId));
1413 return errors.wrap('supplied properties not correct for "AliasTargetProperty"');
1414}
1415/**
1416 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSet.AliasTarget` resource
1417 *
1418 * @param properties - the TypeScript properties of a `AliasTargetProperty`
1419 *
1420 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSet.AliasTarget` resource.
1421 */
1422// @ts-ignore TS6133
1423function cfnRecordSetAliasTargetPropertyToCloudFormation(properties) {
1424 if (!cdk.canInspect(properties)) {
1425 return properties;
1426 }
1427 CfnRecordSet_AliasTargetPropertyValidator(properties).assertSuccess();
1428 return {
1429 DNSName: cdk.stringToCloudFormation(properties.dnsName),
1430 EvaluateTargetHealth: cdk.booleanToCloudFormation(properties.evaluateTargetHealth),
1431 HostedZoneId: cdk.stringToCloudFormation(properties.hostedZoneId),
1432 };
1433}
1434// @ts-ignore TS6133
1435function CfnRecordSetAliasTargetPropertyFromCloudFormation(properties) {
1436 if (cdk.isResolvableObject(properties)) {
1437 return new cfn_parse.FromCloudFormationResult(properties);
1438 }
1439 properties = properties == null ? {} : properties;
1440 if (typeof properties !== 'object') {
1441 return new cfn_parse.FromCloudFormationResult(properties);
1442 }
1443 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1444 ret.addPropertyResult('dnsName', 'DNSName', cfn_parse.FromCloudFormation.getString(properties.DNSName));
1445 ret.addPropertyResult('evaluateTargetHealth', 'EvaluateTargetHealth', properties.EvaluateTargetHealth != null ? cfn_parse.FromCloudFormation.getBoolean(properties.EvaluateTargetHealth) : undefined);
1446 ret.addPropertyResult('hostedZoneId', 'HostedZoneId', cfn_parse.FromCloudFormation.getString(properties.HostedZoneId));
1447 ret.addUnrecognizedPropertiesAsExtra(properties);
1448 return ret;
1449}
1450/**
1451 * Determine whether the given properties match those of a `CidrRoutingConfigProperty`
1452 *
1453 * @param properties - the TypeScript properties of a `CidrRoutingConfigProperty`
1454 *
1455 * @returns the result of the validation.
1456 */
1457function CfnRecordSet_CidrRoutingConfigPropertyValidator(properties) {
1458 if (!cdk.canInspect(properties)) {
1459 return cdk.VALIDATION_SUCCESS;
1460 }
1461 const errors = new cdk.ValidationResults();
1462 if (typeof properties !== 'object') {
1463 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1464 }
1465 errors.collect(cdk.propertyValidator('collectionId', cdk.requiredValidator)(properties.collectionId));
1466 errors.collect(cdk.propertyValidator('collectionId', cdk.validateString)(properties.collectionId));
1467 errors.collect(cdk.propertyValidator('locationName', cdk.requiredValidator)(properties.locationName));
1468 errors.collect(cdk.propertyValidator('locationName', cdk.validateString)(properties.locationName));
1469 return errors.wrap('supplied properties not correct for "CidrRoutingConfigProperty"');
1470}
1471/**
1472 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSet.CidrRoutingConfig` resource
1473 *
1474 * @param properties - the TypeScript properties of a `CidrRoutingConfigProperty`
1475 *
1476 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSet.CidrRoutingConfig` resource.
1477 */
1478// @ts-ignore TS6133
1479function cfnRecordSetCidrRoutingConfigPropertyToCloudFormation(properties) {
1480 if (!cdk.canInspect(properties)) {
1481 return properties;
1482 }
1483 CfnRecordSet_CidrRoutingConfigPropertyValidator(properties).assertSuccess();
1484 return {
1485 CollectionId: cdk.stringToCloudFormation(properties.collectionId),
1486 LocationName: cdk.stringToCloudFormation(properties.locationName),
1487 };
1488}
1489// @ts-ignore TS6133
1490function CfnRecordSetCidrRoutingConfigPropertyFromCloudFormation(properties) {
1491 if (cdk.isResolvableObject(properties)) {
1492 return new cfn_parse.FromCloudFormationResult(properties);
1493 }
1494 properties = properties == null ? {} : properties;
1495 if (typeof properties !== 'object') {
1496 return new cfn_parse.FromCloudFormationResult(properties);
1497 }
1498 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1499 ret.addPropertyResult('collectionId', 'CollectionId', cfn_parse.FromCloudFormation.getString(properties.CollectionId));
1500 ret.addPropertyResult('locationName', 'LocationName', cfn_parse.FromCloudFormation.getString(properties.LocationName));
1501 ret.addUnrecognizedPropertiesAsExtra(properties);
1502 return ret;
1503}
1504/**
1505 * Determine whether the given properties match those of a `GeoLocationProperty`
1506 *
1507 * @param properties - the TypeScript properties of a `GeoLocationProperty`
1508 *
1509 * @returns the result of the validation.
1510 */
1511function CfnRecordSet_GeoLocationPropertyValidator(properties) {
1512 if (!cdk.canInspect(properties)) {
1513 return cdk.VALIDATION_SUCCESS;
1514 }
1515 const errors = new cdk.ValidationResults();
1516 if (typeof properties !== 'object') {
1517 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1518 }
1519 errors.collect(cdk.propertyValidator('continentCode', cdk.validateString)(properties.continentCode));
1520 errors.collect(cdk.propertyValidator('countryCode', cdk.validateString)(properties.countryCode));
1521 errors.collect(cdk.propertyValidator('subdivisionCode', cdk.validateString)(properties.subdivisionCode));
1522 return errors.wrap('supplied properties not correct for "GeoLocationProperty"');
1523}
1524/**
1525 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSet.GeoLocation` resource
1526 *
1527 * @param properties - the TypeScript properties of a `GeoLocationProperty`
1528 *
1529 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSet.GeoLocation` resource.
1530 */
1531// @ts-ignore TS6133
1532function cfnRecordSetGeoLocationPropertyToCloudFormation(properties) {
1533 if (!cdk.canInspect(properties)) {
1534 return properties;
1535 }
1536 CfnRecordSet_GeoLocationPropertyValidator(properties).assertSuccess();
1537 return {
1538 ContinentCode: cdk.stringToCloudFormation(properties.continentCode),
1539 CountryCode: cdk.stringToCloudFormation(properties.countryCode),
1540 SubdivisionCode: cdk.stringToCloudFormation(properties.subdivisionCode),
1541 };
1542}
1543// @ts-ignore TS6133
1544function CfnRecordSetGeoLocationPropertyFromCloudFormation(properties) {
1545 if (cdk.isResolvableObject(properties)) {
1546 return new cfn_parse.FromCloudFormationResult(properties);
1547 }
1548 properties = properties == null ? {} : properties;
1549 if (typeof properties !== 'object') {
1550 return new cfn_parse.FromCloudFormationResult(properties);
1551 }
1552 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1553 ret.addPropertyResult('continentCode', 'ContinentCode', properties.ContinentCode != null ? cfn_parse.FromCloudFormation.getString(properties.ContinentCode) : undefined);
1554 ret.addPropertyResult('countryCode', 'CountryCode', properties.CountryCode != null ? cfn_parse.FromCloudFormation.getString(properties.CountryCode) : undefined);
1555 ret.addPropertyResult('subdivisionCode', 'SubdivisionCode', properties.SubdivisionCode != null ? cfn_parse.FromCloudFormation.getString(properties.SubdivisionCode) : undefined);
1556 ret.addUnrecognizedPropertiesAsExtra(properties);
1557 return ret;
1558}
1559/**
1560 * Determine whether the given properties match those of a `CfnRecordSetGroupProps`
1561 *
1562 * @param properties - the TypeScript properties of a `CfnRecordSetGroupProps`
1563 *
1564 * @returns the result of the validation.
1565 */
1566function CfnRecordSetGroupPropsValidator(properties) {
1567 if (!cdk.canInspect(properties)) {
1568 return cdk.VALIDATION_SUCCESS;
1569 }
1570 const errors = new cdk.ValidationResults();
1571 if (typeof properties !== 'object') {
1572 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1573 }
1574 errors.collect(cdk.propertyValidator('comment', cdk.validateString)(properties.comment));
1575 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.validateString)(properties.hostedZoneId));
1576 errors.collect(cdk.propertyValidator('hostedZoneName', cdk.validateString)(properties.hostedZoneName));
1577 errors.collect(cdk.propertyValidator('recordSets', cdk.listValidator(CfnRecordSetGroup_RecordSetPropertyValidator))(properties.recordSets));
1578 return errors.wrap('supplied properties not correct for "CfnRecordSetGroupProps"');
1579}
1580/**
1581 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup` resource
1582 *
1583 * @param properties - the TypeScript properties of a `CfnRecordSetGroupProps`
1584 *
1585 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup` resource.
1586 */
1587// @ts-ignore TS6133
1588function cfnRecordSetGroupPropsToCloudFormation(properties) {
1589 if (!cdk.canInspect(properties)) {
1590 return properties;
1591 }
1592 CfnRecordSetGroupPropsValidator(properties).assertSuccess();
1593 return {
1594 Comment: cdk.stringToCloudFormation(properties.comment),
1595 HostedZoneId: cdk.stringToCloudFormation(properties.hostedZoneId),
1596 HostedZoneName: cdk.stringToCloudFormation(properties.hostedZoneName),
1597 RecordSets: cdk.listMapper(cfnRecordSetGroupRecordSetPropertyToCloudFormation)(properties.recordSets),
1598 };
1599}
1600// @ts-ignore TS6133
1601function CfnRecordSetGroupPropsFromCloudFormation(properties) {
1602 properties = properties == null ? {} : properties;
1603 if (typeof properties !== 'object') {
1604 return new cfn_parse.FromCloudFormationResult(properties);
1605 }
1606 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1607 ret.addPropertyResult('comment', 'Comment', properties.Comment != null ? cfn_parse.FromCloudFormation.getString(properties.Comment) : undefined);
1608 ret.addPropertyResult('hostedZoneId', 'HostedZoneId', properties.HostedZoneId != null ? cfn_parse.FromCloudFormation.getString(properties.HostedZoneId) : undefined);
1609 ret.addPropertyResult('hostedZoneName', 'HostedZoneName', properties.HostedZoneName != null ? cfn_parse.FromCloudFormation.getString(properties.HostedZoneName) : undefined);
1610 ret.addPropertyResult('recordSets', 'RecordSets', properties.RecordSets != null ? cfn_parse.FromCloudFormation.getArray(CfnRecordSetGroupRecordSetPropertyFromCloudFormation)(properties.RecordSets) : undefined);
1611 ret.addUnrecognizedPropertiesAsExtra(properties);
1612 return ret;
1613}
1614/**
1615 * A CloudFormation `AWS::Route53::RecordSetGroup`
1616 *
1617 * A complex type that contains an optional comment, the name and ID of the hosted zone that you want to make changes in, and values for the records that you want to create.
1618 *
1619 * @cloudformationResource AWS::Route53::RecordSetGroup
1620 * @stability external
1621 *
1622 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-recordsetgroup.html
1623 */
1624class CfnRecordSetGroup extends cdk.CfnResource {
1625 /**
1626 * Create a new `AWS::Route53::RecordSetGroup`.
1627 *
1628 * @param scope - scope in which this resource is defined
1629 * @param id - scoped id of the resource
1630 * @param props - resource properties
1631 */
1632 constructor(scope, id, props = {}) {
1633 super(scope, id, { type: CfnRecordSetGroup.CFN_RESOURCE_TYPE_NAME, properties: props });
1634 try {
1635 jsiiDeprecationWarnings._aws_cdk_aws_route53_CfnRecordSetGroupProps(props);
1636 }
1637 catch (error) {
1638 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1639 Error.captureStackTrace(error, CfnRecordSetGroup);
1640 }
1641 throw error;
1642 }
1643 this.comment = props.comment;
1644 this.hostedZoneId = props.hostedZoneId;
1645 this.hostedZoneName = props.hostedZoneName;
1646 this.recordSets = props.recordSets;
1647 }
1648 /**
1649 * A factory method that creates a new instance of this class from an object
1650 * containing the CloudFormation properties of this resource.
1651 * Used in the @aws-cdk/cloudformation-include module.
1652 *
1653 * @internal
1654 */
1655 static _fromCloudFormation(scope, id, resourceAttributes, options) {
1656 resourceAttributes = resourceAttributes || {};
1657 const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
1658 const propsResult = CfnRecordSetGroupPropsFromCloudFormation(resourceProperties);
1659 const ret = new CfnRecordSetGroup(scope, id, propsResult.value);
1660 for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
1661 ret.addPropertyOverride(propKey, propVal);
1662 }
1663 options.parser.handleAttributes(ret, resourceAttributes, id);
1664 return ret;
1665 }
1666 /**
1667 * Examines the CloudFormation resource and discloses attributes.
1668 *
1669 * @param inspector - tree inspector to collect and process attributes
1670 *
1671 */
1672 inspect(inspector) {
1673 inspector.addAttribute("aws:cdk:cloudformation:type", CfnRecordSetGroup.CFN_RESOURCE_TYPE_NAME);
1674 inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
1675 }
1676 get cfnProperties() {
1677 return {
1678 comment: this.comment,
1679 hostedZoneId: this.hostedZoneId,
1680 hostedZoneName: this.hostedZoneName,
1681 recordSets: this.recordSets,
1682 };
1683 }
1684 renderProperties(props) {
1685 return cfnRecordSetGroupPropsToCloudFormation(props);
1686 }
1687}
1688exports.CfnRecordSetGroup = CfnRecordSetGroup;
1689_g = JSII_RTTI_SYMBOL_1;
1690CfnRecordSetGroup[_g] = { fqn: "@aws-cdk/aws-route53.CfnRecordSetGroup", version: "1.204.0" };
1691/**
1692 * The CloudFormation resource type name for this resource class.
1693 */
1694CfnRecordSetGroup.CFN_RESOURCE_TYPE_NAME = "AWS::Route53::RecordSetGroup";
1695/**
1696 * Determine whether the given properties match those of a `AliasTargetProperty`
1697 *
1698 * @param properties - the TypeScript properties of a `AliasTargetProperty`
1699 *
1700 * @returns the result of the validation.
1701 */
1702function CfnRecordSetGroup_AliasTargetPropertyValidator(properties) {
1703 if (!cdk.canInspect(properties)) {
1704 return cdk.VALIDATION_SUCCESS;
1705 }
1706 const errors = new cdk.ValidationResults();
1707 if (typeof properties !== 'object') {
1708 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1709 }
1710 errors.collect(cdk.propertyValidator('dnsName', cdk.requiredValidator)(properties.dnsName));
1711 errors.collect(cdk.propertyValidator('dnsName', cdk.validateString)(properties.dnsName));
1712 errors.collect(cdk.propertyValidator('evaluateTargetHealth', cdk.validateBoolean)(properties.evaluateTargetHealth));
1713 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.requiredValidator)(properties.hostedZoneId));
1714 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.validateString)(properties.hostedZoneId));
1715 return errors.wrap('supplied properties not correct for "AliasTargetProperty"');
1716}
1717/**
1718 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup.AliasTarget` resource
1719 *
1720 * @param properties - the TypeScript properties of a `AliasTargetProperty`
1721 *
1722 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup.AliasTarget` resource.
1723 */
1724// @ts-ignore TS6133
1725function cfnRecordSetGroupAliasTargetPropertyToCloudFormation(properties) {
1726 if (!cdk.canInspect(properties)) {
1727 return properties;
1728 }
1729 CfnRecordSetGroup_AliasTargetPropertyValidator(properties).assertSuccess();
1730 return {
1731 DNSName: cdk.stringToCloudFormation(properties.dnsName),
1732 EvaluateTargetHealth: cdk.booleanToCloudFormation(properties.evaluateTargetHealth),
1733 HostedZoneId: cdk.stringToCloudFormation(properties.hostedZoneId),
1734 };
1735}
1736// @ts-ignore TS6133
1737function CfnRecordSetGroupAliasTargetPropertyFromCloudFormation(properties) {
1738 if (cdk.isResolvableObject(properties)) {
1739 return new cfn_parse.FromCloudFormationResult(properties);
1740 }
1741 properties = properties == null ? {} : properties;
1742 if (typeof properties !== 'object') {
1743 return new cfn_parse.FromCloudFormationResult(properties);
1744 }
1745 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1746 ret.addPropertyResult('dnsName', 'DNSName', cfn_parse.FromCloudFormation.getString(properties.DNSName));
1747 ret.addPropertyResult('evaluateTargetHealth', 'EvaluateTargetHealth', properties.EvaluateTargetHealth != null ? cfn_parse.FromCloudFormation.getBoolean(properties.EvaluateTargetHealth) : undefined);
1748 ret.addPropertyResult('hostedZoneId', 'HostedZoneId', cfn_parse.FromCloudFormation.getString(properties.HostedZoneId));
1749 ret.addUnrecognizedPropertiesAsExtra(properties);
1750 return ret;
1751}
1752/**
1753 * Determine whether the given properties match those of a `CidrRoutingConfigProperty`
1754 *
1755 * @param properties - the TypeScript properties of a `CidrRoutingConfigProperty`
1756 *
1757 * @returns the result of the validation.
1758 */
1759function CfnRecordSetGroup_CidrRoutingConfigPropertyValidator(properties) {
1760 if (!cdk.canInspect(properties)) {
1761 return cdk.VALIDATION_SUCCESS;
1762 }
1763 const errors = new cdk.ValidationResults();
1764 if (typeof properties !== 'object') {
1765 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1766 }
1767 errors.collect(cdk.propertyValidator('collectionId', cdk.requiredValidator)(properties.collectionId));
1768 errors.collect(cdk.propertyValidator('collectionId', cdk.validateString)(properties.collectionId));
1769 errors.collect(cdk.propertyValidator('locationName', cdk.requiredValidator)(properties.locationName));
1770 errors.collect(cdk.propertyValidator('locationName', cdk.validateString)(properties.locationName));
1771 return errors.wrap('supplied properties not correct for "CidrRoutingConfigProperty"');
1772}
1773/**
1774 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup.CidrRoutingConfig` resource
1775 *
1776 * @param properties - the TypeScript properties of a `CidrRoutingConfigProperty`
1777 *
1778 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup.CidrRoutingConfig` resource.
1779 */
1780// @ts-ignore TS6133
1781function cfnRecordSetGroupCidrRoutingConfigPropertyToCloudFormation(properties) {
1782 if (!cdk.canInspect(properties)) {
1783 return properties;
1784 }
1785 CfnRecordSetGroup_CidrRoutingConfigPropertyValidator(properties).assertSuccess();
1786 return {
1787 CollectionId: cdk.stringToCloudFormation(properties.collectionId),
1788 LocationName: cdk.stringToCloudFormation(properties.locationName),
1789 };
1790}
1791// @ts-ignore TS6133
1792function CfnRecordSetGroupCidrRoutingConfigPropertyFromCloudFormation(properties) {
1793 if (cdk.isResolvableObject(properties)) {
1794 return new cfn_parse.FromCloudFormationResult(properties);
1795 }
1796 properties = properties == null ? {} : properties;
1797 if (typeof properties !== 'object') {
1798 return new cfn_parse.FromCloudFormationResult(properties);
1799 }
1800 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1801 ret.addPropertyResult('collectionId', 'CollectionId', cfn_parse.FromCloudFormation.getString(properties.CollectionId));
1802 ret.addPropertyResult('locationName', 'LocationName', cfn_parse.FromCloudFormation.getString(properties.LocationName));
1803 ret.addUnrecognizedPropertiesAsExtra(properties);
1804 return ret;
1805}
1806/**
1807 * Determine whether the given properties match those of a `GeoLocationProperty`
1808 *
1809 * @param properties - the TypeScript properties of a `GeoLocationProperty`
1810 *
1811 * @returns the result of the validation.
1812 */
1813function CfnRecordSetGroup_GeoLocationPropertyValidator(properties) {
1814 if (!cdk.canInspect(properties)) {
1815 return cdk.VALIDATION_SUCCESS;
1816 }
1817 const errors = new cdk.ValidationResults();
1818 if (typeof properties !== 'object') {
1819 errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
1820 }
1821 errors.collect(cdk.propertyValidator('continentCode', cdk.validateString)(properties.continentCode));
1822 errors.collect(cdk.propertyValidator('countryCode', cdk.validateString)(properties.countryCode));
1823 errors.collect(cdk.propertyValidator('subdivisionCode', cdk.validateString)(properties.subdivisionCode));
1824 return errors.wrap('supplied properties not correct for "GeoLocationProperty"');
1825}
1826/**
1827 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup.GeoLocation` resource
1828 *
1829 * @param properties - the TypeScript properties of a `GeoLocationProperty`
1830 *
1831 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup.GeoLocation` resource.
1832 */
1833// @ts-ignore TS6133
1834function cfnRecordSetGroupGeoLocationPropertyToCloudFormation(properties) {
1835 if (!cdk.canInspect(properties)) {
1836 return properties;
1837 }
1838 CfnRecordSetGroup_GeoLocationPropertyValidator(properties).assertSuccess();
1839 return {
1840 ContinentCode: cdk.stringToCloudFormation(properties.continentCode),
1841 CountryCode: cdk.stringToCloudFormation(properties.countryCode),
1842 SubdivisionCode: cdk.stringToCloudFormation(properties.subdivisionCode),
1843 };
1844}
1845// @ts-ignore TS6133
1846function CfnRecordSetGroupGeoLocationPropertyFromCloudFormation(properties) {
1847 if (cdk.isResolvableObject(properties)) {
1848 return new cfn_parse.FromCloudFormationResult(properties);
1849 }
1850 properties = properties == null ? {} : properties;
1851 if (typeof properties !== 'object') {
1852 return new cfn_parse.FromCloudFormationResult(properties);
1853 }
1854 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1855 ret.addPropertyResult('continentCode', 'ContinentCode', properties.ContinentCode != null ? cfn_parse.FromCloudFormation.getString(properties.ContinentCode) : undefined);
1856 ret.addPropertyResult('countryCode', 'CountryCode', properties.CountryCode != null ? cfn_parse.FromCloudFormation.getString(properties.CountryCode) : undefined);
1857 ret.addPropertyResult('subdivisionCode', 'SubdivisionCode', properties.SubdivisionCode != null ? cfn_parse.FromCloudFormation.getString(properties.SubdivisionCode) : undefined);
1858 ret.addUnrecognizedPropertiesAsExtra(properties);
1859 return ret;
1860}
1861/**
1862 * Determine whether the given properties match those of a `RecordSetProperty`
1863 *
1864 * @param properties - the TypeScript properties of a `RecordSetProperty`
1865 *
1866 * @returns the result of the validation.
1867 */
1868function CfnRecordSetGroup_RecordSetPropertyValidator(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('aliasTarget', CfnRecordSetGroup_AliasTargetPropertyValidator)(properties.aliasTarget));
1877 errors.collect(cdk.propertyValidator('cidrRoutingConfig', CfnRecordSetGroup_CidrRoutingConfigPropertyValidator)(properties.cidrRoutingConfig));
1878 errors.collect(cdk.propertyValidator('failover', cdk.validateString)(properties.failover));
1879 errors.collect(cdk.propertyValidator('geoLocation', CfnRecordSetGroup_GeoLocationPropertyValidator)(properties.geoLocation));
1880 errors.collect(cdk.propertyValidator('healthCheckId', cdk.validateString)(properties.healthCheckId));
1881 errors.collect(cdk.propertyValidator('hostedZoneId', cdk.validateString)(properties.hostedZoneId));
1882 errors.collect(cdk.propertyValidator('hostedZoneName', cdk.validateString)(properties.hostedZoneName));
1883 errors.collect(cdk.propertyValidator('multiValueAnswer', cdk.validateBoolean)(properties.multiValueAnswer));
1884 errors.collect(cdk.propertyValidator('name', cdk.requiredValidator)(properties.name));
1885 errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
1886 errors.collect(cdk.propertyValidator('region', cdk.validateString)(properties.region));
1887 errors.collect(cdk.propertyValidator('resourceRecords', cdk.listValidator(cdk.validateString))(properties.resourceRecords));
1888 errors.collect(cdk.propertyValidator('setIdentifier', cdk.validateString)(properties.setIdentifier));
1889 errors.collect(cdk.propertyValidator('ttl', cdk.validateString)(properties.ttl));
1890 errors.collect(cdk.propertyValidator('type', cdk.requiredValidator)(properties.type));
1891 errors.collect(cdk.propertyValidator('type', cdk.validateString)(properties.type));
1892 errors.collect(cdk.propertyValidator('weight', cdk.validateNumber)(properties.weight));
1893 return errors.wrap('supplied properties not correct for "RecordSetProperty"');
1894}
1895/**
1896 * Renders the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup.RecordSet` resource
1897 *
1898 * @param properties - the TypeScript properties of a `RecordSetProperty`
1899 *
1900 * @returns the AWS CloudFormation properties of an `AWS::Route53::RecordSetGroup.RecordSet` resource.
1901 */
1902// @ts-ignore TS6133
1903function cfnRecordSetGroupRecordSetPropertyToCloudFormation(properties) {
1904 if (!cdk.canInspect(properties)) {
1905 return properties;
1906 }
1907 CfnRecordSetGroup_RecordSetPropertyValidator(properties).assertSuccess();
1908 return {
1909 AliasTarget: cfnRecordSetGroupAliasTargetPropertyToCloudFormation(properties.aliasTarget),
1910 CidrRoutingConfig: cfnRecordSetGroupCidrRoutingConfigPropertyToCloudFormation(properties.cidrRoutingConfig),
1911 Failover: cdk.stringToCloudFormation(properties.failover),
1912 GeoLocation: cfnRecordSetGroupGeoLocationPropertyToCloudFormation(properties.geoLocation),
1913 HealthCheckId: cdk.stringToCloudFormation(properties.healthCheckId),
1914 HostedZoneId: cdk.stringToCloudFormation(properties.hostedZoneId),
1915 HostedZoneName: cdk.stringToCloudFormation(properties.hostedZoneName),
1916 MultiValueAnswer: cdk.booleanToCloudFormation(properties.multiValueAnswer),
1917 Name: cdk.stringToCloudFormation(properties.name),
1918 Region: cdk.stringToCloudFormation(properties.region),
1919 ResourceRecords: cdk.listMapper(cdk.stringToCloudFormation)(properties.resourceRecords),
1920 SetIdentifier: cdk.stringToCloudFormation(properties.setIdentifier),
1921 TTL: cdk.stringToCloudFormation(properties.ttl),
1922 Type: cdk.stringToCloudFormation(properties.type),
1923 Weight: cdk.numberToCloudFormation(properties.weight),
1924 };
1925}
1926// @ts-ignore TS6133
1927function CfnRecordSetGroupRecordSetPropertyFromCloudFormation(properties) {
1928 if (cdk.isResolvableObject(properties)) {
1929 return new cfn_parse.FromCloudFormationResult(properties);
1930 }
1931 properties = properties == null ? {} : properties;
1932 if (typeof properties !== 'object') {
1933 return new cfn_parse.FromCloudFormationResult(properties);
1934 }
1935 const ret = new cfn_parse.FromCloudFormationPropertyObject();
1936 ret.addPropertyResult('aliasTarget', 'AliasTarget', properties.AliasTarget != null ? CfnRecordSetGroupAliasTargetPropertyFromCloudFormation(properties.AliasTarget) : undefined);
1937 ret.addPropertyResult('cidrRoutingConfig', 'CidrRoutingConfig', properties.CidrRoutingConfig != null ? CfnRecordSetGroupCidrRoutingConfigPropertyFromCloudFormation(properties.CidrRoutingConfig) : undefined);
1938 ret.addPropertyResult('failover', 'Failover', properties.Failover != null ? cfn_parse.FromCloudFormation.getString(properties.Failover) : undefined);
1939 ret.addPropertyResult('geoLocation', 'GeoLocation', properties.GeoLocation != null ? CfnRecordSetGroupGeoLocationPropertyFromCloudFormation(properties.GeoLocation) : undefined);
1940 ret.addPropertyResult('healthCheckId', 'HealthCheckId', properties.HealthCheckId != null ? cfn_parse.FromCloudFormation.getString(properties.HealthCheckId) : undefined);
1941 ret.addPropertyResult('hostedZoneId', 'HostedZoneId', properties.HostedZoneId != null ? cfn_parse.FromCloudFormation.getString(properties.HostedZoneId) : undefined);
1942 ret.addPropertyResult('hostedZoneName', 'HostedZoneName', properties.HostedZoneName != null ? cfn_parse.FromCloudFormation.getString(properties.HostedZoneName) : undefined);
1943 ret.addPropertyResult('multiValueAnswer', 'MultiValueAnswer', properties.MultiValueAnswer != null ? cfn_parse.FromCloudFormation.getBoolean(properties.MultiValueAnswer) : undefined);
1944 ret.addPropertyResult('name', 'Name', cfn_parse.FromCloudFormation.getString(properties.Name));
1945 ret.addPropertyResult('region', 'Region', properties.Region != null ? cfn_parse.FromCloudFormation.getString(properties.Region) : undefined);
1946 ret.addPropertyResult('resourceRecords', 'ResourceRecords', properties.ResourceRecords != null ? cfn_parse.FromCloudFormation.getStringArray(properties.ResourceRecords) : undefined);
1947 ret.addPropertyResult('setIdentifier', 'SetIdentifier', properties.SetIdentifier != null ? cfn_parse.FromCloudFormation.getString(properties.SetIdentifier) : undefined);
1948 ret.addPropertyResult('ttl', 'TTL', properties.TTL != null ? cfn_parse.FromCloudFormation.getString(properties.TTL) : undefined);
1949 ret.addPropertyResult('type', 'Type', cfn_parse.FromCloudFormation.getString(properties.Type));
1950 ret.addPropertyResult('weight', 'Weight', properties.Weight != null ? cfn_parse.FromCloudFormation.getNumber(properties.Weight) : undefined);
1951 ret.addUnrecognizedPropertiesAsExtra(properties);
1952 return ret;
1953}
1954//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGU1My5nZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJyb3V0ZTUzLmdlbmVyYXRlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSwrRUFBK0U7QUFDL0UsK0RBQStEO0FBQy9ELDhGQUE4RjtBQUM5RixzSEFBc0g7QUFFdEgsNEJBQTRCLENBQUMsaUVBQWlFO0FBRTlGLHFDQUFxQztBQUNyQyxnRUFBZ0U7QUEyQmhFOzs7Ozs7R0FNRztBQUNILFNBQVMsK0JBQStCLENBQUMsVUFBZTtJQUNwRCxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsRUFBRTtRQUFFLE9BQU8sR0FBRyxDQUFDLGtCQUFrQixDQUFDO0tBQUU7SUFDbkUsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUMzQyxJQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVEsRUFBRTtRQUNoQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLG9DQUFvQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQy9HO0lBQ0QsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxhQUFhLENBQUMsMkNBQTJDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO0lBQ3pJLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUN0RixNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJ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QUMsaUJBQWlCLENBQUMsZUFBZSxFQUFFLGVBQWUsRUFBRSxVQUFVLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3pLLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjLEVBQUUsY0FBYyxFQUFFLFVBQVUsQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDckssR0FBRyxDQUFDLGlCQUFpQixDQUFDLGdCQUFnQixFQUFFLGdCQUFnQixFQUFFLFVBQVUsQ0FBQyxjQUFjLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0ssR0FBRyxDQUFDLGlCQUFpQixDQUFDLGtCQUFrQixFQUFFLGtCQUFrQixFQUFFLFVBQVUsQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3RMLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0ksR0FBRyxDQUFDLGlCQUFpQixDQUFDLGlCQUFpQixFQUFFLGlCQUFpQixFQUFF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Q0FBQztJQUNqSSxHQUFHLENBQUMsaUJBQWlCLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQy9GLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0ksR0FBRyxDQUFDLGdDQUFnQyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2pELE9BQU8sR0FBRyxDQUFDO0FBQ2YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDEyLTIwMjMgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbi8vIEdlbmVyYXRlZCBmcm9tIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gUmVzb3VyY2UgU3BlY2lmaWNhdGlvblxuLy8gU2VlOiBkb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvY2ZuLXJlc291cmNlLXNwZWNpZmljYXRpb24uaHRtbFxuLy8gQGNmbjJ0czptZXRhQCB7XCJnZW5lcmF0ZWRcIjpcIjIwMjMtMDYtMTlUMTU6MTg6NTcuMjI1WlwiLFwiZmluZ2VycHJpbnRcIjpcIng5OFIxUnRpUk9rUW9GUWpLNFBQUm1tZFROM1A2YkRSUnY5d3BNOTV5WGc9XCJ9XG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi8gLy8gVGhpcyBpcyBnZW5lcmF0ZWQgY29kZSAtIGxpbmUgbGVuZ3RocyBhcmUgZGlmZmljdWx0IHRvIGNvbnRyb2xcblxuaW1wb3J0ICogYXMgY2RrIGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1xuaW1wb3J0ICogYXMgY2ZuX3BhcnNlIGZyb20gJ0Bhd3MtY2RrL2NvcmUvbGliL2hlbHBlcnMtaW50ZXJuYWwnO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmbkNpZHJDb2xsZWN0aW9uYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWNpZHJjb2xsZWN0aW9uLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5DaWRyQ29sbGVjdGlvblByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIGEgQ0lEUiBjb2xsZWN0aW9uLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1jaWRyY29sbGVjdGlvbi5odG1sI2Nmbi1yb3V0ZTUzLWNpZHJjb2xsZWN0aW9uLW5hbWVcbiAgICAgKi9cbiAgICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBIGNvbXBsZXggdHlwZSB0aGF0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBsaXN0IG9mIENJRFIgbG9jYXRpb25zLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1jaWRyY29sbGVjdGlvbi5odG1sI2Nmbi1yb3V0ZTUzLWNpZHJjb2xsZWN0aW9uLWxvY2F0aW9uc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IGxvY2F0aW9ucz86IEFycmF5PENmbkNpZHJDb2xsZWN0aW9uLkxvY2F0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbkNpZHJDb2xsZWN0aW9uUHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkNpZHJDb2xsZWN0aW9uUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuQ2lkckNvbGxlY3Rpb25Qcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2xvY2F0aW9ucycsIGNkay5saXN0VmFsaWRhdG9yKENmbkNpZHJDb2xsZWN0aW9uX0xvY2F0aW9uUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLmxvY2F0aW9ucykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLm5hbWUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuQ2lkckNvbGxlY3Rpb25Qcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6Q2lkckNvbGxlY3Rpb25gIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkNpZHJDb2xsZWN0aW9uUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OkNpZHJDb2xsZWN0aW9uYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmbkNpZHJDb2xsZWN0aW9uUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkNpZHJDb2xsZWN0aW9uUHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIE5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubmFtZSksXG4gICAgICAgIExvY2F0aW9uczogY2RrLmxpc3RNYXBwZXIoY2ZuQ2lkckNvbGxlY3Rpb25Mb2NhdGlvblByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5sb2NhdGlvbnMpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5DaWRyQ29sbGVjdGlvblByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuQ2lkckNvbGxlY3Rpb25Qcm9wcz4ge1xuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuQ2lkckNvbGxlY3Rpb25Qcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ25hbWUnLCAnTmFtZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTmFtZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbG9jYXRpb25zJywgJ0xvY2F0aW9ucycsIHByb3BlcnRpZXMuTG9jYXRpb25zICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmbkNpZHJDb2xsZWN0aW9uTG9jYXRpb25Qcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5Mb2NhdGlvbnMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBBIENsb3VkRm9ybWF0aW9uIGBBV1M6OlJvdXRlNTM6OkNpZHJDb2xsZWN0aW9uYFxuICpcbiAqIENyZWF0ZXMgYSBDSURSIGNvbGxlY3Rpb24gaW4gdGhlIGN1cnJlbnQgQVdTIGFjY291bnQuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpSb3V0ZTUzOjpDaWRyQ29sbGVjdGlvblxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtY2lkcmNvbGxlY3Rpb24uaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuQ2lkckNvbGxlY3Rpb24gZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpSb3V0ZTUzOjpDaWRyQ29sbGVjdGlvblwiO1xuXG4gICAgLyoqXG4gICAgICogQSBmYWN0b3J5IG1ldGhvZCB0aGF0IGNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmcm9tIGFuIG9iamVjdFxuICAgICAqIGNvbnRhaW5pbmcgdGhlIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgdGhpcyByZXNvdXJjZS5cbiAgICAgKiBVc2VkIGluIHRoZSBAYXdzLWNkay9jbG91ZGZvcm1hdGlvbi1pbmNsdWRlIG1vZHVsZS5cbiAgICAgKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgX2Zyb21DbG91ZEZvcm1hdGlvbihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcmVzb3VyY2VBdHRyaWJ1dGVzOiBhbnksIG9wdGlvbnM6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25PcHRpb25zKTogQ2ZuQ2lkckNvbGxlY3Rpb24ge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmbkNpZHJDb2xsZWN0aW9uUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmbkNpZHJDb2xsZWN0aW9uKHNjb3BlLCBpZCwgcHJvcHNSZXN1bHQudmFsdWUpO1xuICAgICAgICBmb3IgKGNvbnN0IFtwcm9wS2V5LCBwcm9wVmFsXSBvZiBPYmplY3QuZW50cmllcyhwcm9wc1Jlc3VsdC5leHRyYVByb3BlcnRpZXMpKSAge1xuICAgICAgICAgICAgcmV0LmFkZFByb3BlcnR5T3ZlcnJpZGUocHJvcEtleSwgcHJvcFZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5wYXJzZXIuaGFuZGxlQXR0cmlidXRlcyhyZXQsIHJlc291cmNlQXR0cmlidXRlcywgaWQpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFwiVGhlIEFtYXpvbiByZXNvdXJjZSBuYW1lIChBUk4pIHRvIHVuaXF1ZWx5IGlkZW50aWZ5IHRoZSBBV1MgcmVzb3VyY2UuXG4gICAgICogQGNsb3VkZm9ybWF0aW9uQXR0cmlidXRlIEFyblxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBhdHRyQXJuOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgVVVJRCBvZiB0aGUgQ0lEUiBjb2xsZWN0aW9uLlxuICAgICAqIEBjbG91ZGZvcm1hdGlvbkF0dHJpYnV0ZSBJZFxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBhdHRySWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIGEgQ0lEUiBjb2xsZWN0aW9uLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1jaWRyY29sbGVjdGlvbi5odG1sI2Nmbi1yb3V0ZTUzLWNpZHJjb2xsZWN0aW9uLW5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbGlzdCBvZiBDSURSIGxvY2F0aW9ucy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtY2lkcmNvbGxlY3Rpb24uaHRtbCNjZm4tcm91dGU1My1jaWRyY29sbGVjdGlvbi1sb2NhdGlvbnNcbiAgICAgKi9cbiAgICBwdWJsaWMgbG9jYXRpb25zOiBBcnJheTxDZm5DaWRyQ29sbGVjdGlvbi5Mb2NhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpSb3V0ZTUzOjpDaWRyQ29sbGVjdGlvbmAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuQ2lkckNvbGxlY3Rpb25Qcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuQ2lkckNvbGxlY3Rpb24uQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICduYW1lJywgdGhpcyk7XG4gICAgICAgIHRoaXMuYXR0ckFybiA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnQXJuJykpO1xuICAgICAgICB0aGlzLmF0dHJJZCA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnSWQnKSk7XG5cbiAgICAgICAgdGhpcy5uYW1lID0gcHJvcHMubmFtZTtcbiAgICAgICAgdGhpcy5sb2NhdGlvbnMgPSBwcm9wcy5sb2NhdGlvbnM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5DaWRyQ29sbGVjdGlvbi5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgbG9jYXRpb25zOiB0aGlzLmxvY2F0aW9ucyxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5DaWRyQ29sbGVjdGlvblByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmbkNpZHJDb2xsZWN0aW9uIHtcbiAgICAvKipcbiAgICAgKiBTcGVjaWZpZXMgdGhlIGxpc3Qgb2YgQ0lEUiBibG9ja3MgZm9yIGEgQ0lEUiBsb2NhdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtY2lkcmNvbGxlY3Rpb24tbG9jYXRpb24uaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgTG9jYXRpb25Qcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBMaXN0IG9mIENJRFIgYmxvY2tzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtY2lkcmNvbGxlY3Rpb24tbG9jYXRpb24uaHRtbCNjZm4tcm91dGU1My1jaWRyY29sbGVjdGlvbi1sb2NhdGlvbi1jaWRybGlzdFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY2lkckxpc3Q6IHN0cmluZ1tdO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIENJRFIgY29sbGVjdGlvbiBsb2NhdGlvbiBuYW1lLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtY2lkcmNvbGxlY3Rpb24tbG9jYXRpb24uaHRtbCNjZm4tcm91dGU1My1jaWRyY29sbGVjdGlvbi1sb2NhdGlvbi1sb2NhdGlvbm5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGxvY2F0aW9uTmFtZTogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBMb2NhdGlvblByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBMb2NhdGlvblByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbkNpZHJDb2xsZWN0aW9uX0xvY2F0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjaWRyTGlzdCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5jaWRyTGlzdCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2lkckxpc3QnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLmNpZHJMaXN0KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdsb2NhdGlvbk5hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMubG9jYXRpb25OYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdsb2NhdGlvbk5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubG9jYXRpb25OYW1lKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkxvY2F0aW9uUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OkNpZHJDb2xsZWN0aW9uLkxvY2F0aW9uYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBMb2NhdGlvblByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpDaWRyQ29sbGVjdGlvbi5Mb2NhdGlvbmAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5DaWRyQ29sbGVjdGlvbkxvY2F0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkNpZHJDb2xsZWN0aW9uX0xvY2F0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIENpZHJMaXN0OiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5jaWRyTGlzdCksXG4gICAgICAgIExvY2F0aW9uTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5sb2NhdGlvbk5hbWUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5DaWRyQ29sbGVjdGlvbkxvY2F0aW9uUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5DaWRyQ29sbGVjdGlvbi5Mb2NhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkNpZHJDb2xsZWN0aW9uLkxvY2F0aW9uUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjaWRyTGlzdCcsICdDaWRyTGlzdCcsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5DaWRyTGlzdCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbG9jYXRpb25OYW1lJywgJ0xvY2F0aW9uTmFtZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTG9jYXRpb25OYW1lKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuRE5TU0VDYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWRuc3NlYy5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuRE5TU0VDUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogQSB1bmlxdWUgc3RyaW5nIChJRCkgdGhhdCBpcyB1c2VkIHRvIGlkZW50aWZ5IGEgaG9zdGVkIHpvbmUuIEZvciBleGFtcGxlOiBgWjAwMDAxMTExQTFBQkNhYUFCQzExYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWRuc3NlYy5odG1sI2Nmbi1yb3V0ZTUzLWRuc3NlYy1ob3N0ZWR6b25laWRcbiAgICAgKi9cbiAgICByZWFkb25seSBob3N0ZWRab25lSWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDZm5ETlNTRUNQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuRE5TU0VDUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuRE5TU0VDUHJvcHNWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdob3N0ZWRab25lSWQnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuaG9zdGVkWm9uZUlkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdob3N0ZWRab25lSWQnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuaG9zdGVkWm9uZUlkKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmbkROU1NFQ1Byb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpETlNTRUNgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkROU1NFQ1Byb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpETlNTRUNgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuRE5TU0VDUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkROU1NFQ1Byb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBIb3N0ZWRab25lSWQ6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaG9zdGVkWm9uZUlkKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuRE5TU0VDUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5ETlNTRUNQcm9wcz4ge1xuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuRE5TU0VDUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdob3N0ZWRab25lSWQnLCAnSG9zdGVkWm9uZUlkJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Ib3N0ZWRab25lSWQpKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBBIENsb3VkRm9ybWF0aW9uIGBBV1M6OlJvdXRlNTM6OkROU1NFQ2BcbiAqXG4gKiBUaGUgYEFXUzo6Um91dGU1Mzo6RE5TU0VDYCByZXNvdXJjZSBpcyB1c2VkIHRvIGVuYWJsZSBETlNTRUMgc2lnbmluZyBpbiBhIGhvc3RlZCB6b25lLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6Um91dGU1Mzo6RE5TU0VDXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1kbnNzZWMuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuRE5TU0VDIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6Um91dGU1Mzo6RE5TU0VDXCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5ETlNTRUMge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmbkROU1NFQ1Byb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5ETlNTRUMoc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSB1bmlxdWUgc3RyaW5nIChJRCkgdGhhdCBpcyB1c2VkIHRvIGlkZW50aWZ5IGEgaG9zdGVkIHpvbmUuIEZvciBleGFtcGxlOiBgWjAwMDAxMTExQTFBQkNhYUFCQzExYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWRuc3NlYy5odG1sI2Nmbi1yb3V0ZTUzLWRuc3NlYy1ob3N0ZWR6b25laWRcbiAgICAgKi9cbiAgICBwdWJsaWMgaG9zdGVkWm9uZUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6Um91dGU1Mzo6RE5TU0VDYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5ETlNTRUNQcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuRE5TU0VDLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUsIHByb3BlcnRpZXM6IHByb3BzIH0pO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAnaG9zdGVkWm9uZUlkJywgdGhpcyk7XG5cbiAgICAgICAgdGhpcy5ob3N0ZWRab25lSWQgPSBwcm9wcy5ob3N0ZWRab25lSWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5ETlNTRUMuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGhvc3RlZFpvbmVJZDogdGhpcy5ob3N0ZWRab25lSWQsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuRE5TU0VDUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuSGVhbHRoQ2hlY2tgXG4gKlxuICogQHN0cnVjdFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtaGVhbHRoY2hlY2suaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmbkhlYWx0aENoZWNrUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCBvbmUgaGVhbHRoIGNoZWNrLlxuICAgICAqXG4gICAgICogRm9yIHRoZSB2YWx1ZXMgdG8gZW50ZXIgZm9yIGBIZWFsdGhDaGVja0NvbmZpZ2AgLCBzZWUgW0hlYWx0aENoZWNrQ29uZmlnXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9IZWFsdGhDaGVja0NvbmZpZy5odG1sKVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1oZWFsdGhjaGVjay5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnXG4gICAgICovXG4gICAgcmVhZG9ubHkgaGVhbHRoQ2hlY2tDb25maWc6IENmbkhlYWx0aENoZWNrLkhlYWx0aENoZWNrQ29uZmlnUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYEhlYWx0aENoZWNrVGFnc2AgcHJvcGVydHkgZGVzY3JpYmVzIGtleS12YWx1ZSBwYWlycyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggYW4gYEFXUzo6Um91dGU1Mzo6SGVhbHRoQ2hlY2tgIHJlc291cmNlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1oZWFsdGhjaGVjay5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrdGFnc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IGhlYWx0aENoZWNrVGFncz86IEFycmF5PENmbkhlYWx0aENoZWNrLkhlYWx0aENoZWNrVGFnUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbkhlYWx0aENoZWNrUHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkhlYWx0aENoZWNrUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuSGVhbHRoQ2hlY2tQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hlYWx0aENoZWNrQ29uZmlnJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmhlYWx0aENoZWNrQ29uZmlnKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdoZWFsdGhDaGVja0NvbmZpZycsIENmbkhlYWx0aENoZWNrX0hlYWx0aENoZWNrQ29uZmlnUHJvcGVydHlWYWxpZGF0b3IpKHByb3BlcnRpZXMuaGVhbHRoQ2hlY2tDb25maWcpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hlYWx0aENoZWNrVGFncycsIGNkay5saXN0VmFsaWRhdG9yKENmbkhlYWx0aENoZWNrX0hlYWx0aENoZWNrVGFnUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLmhlYWx0aENoZWNrVGFncykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5IZWFsdGhDaGVja1Byb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpIZWFsdGhDaGVja2AgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuSGVhbHRoQ2hlY2tQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6SGVhbHRoQ2hlY2tgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuSGVhbHRoQ2hlY2tQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuSGVhbHRoQ2hlY2tQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgSGVhbHRoQ2hlY2tDb25maWc6IGNmbkhlYWx0aENoZWNrSGVhbHRoQ2hlY2tDb25maWdQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5oZWFsdGhDaGVja0NvbmZpZyksXG4gICAgICAgIEhlYWx0aENoZWNrVGFnczogY2RrLmxpc3RNYXBwZXIoY2ZuSGVhbHRoQ2hlY2tIZWFsdGhDaGVja1RhZ1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5oZWFsdGhDaGVja1RhZ3MpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5IZWFsdGhDaGVja1Byb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuSGVhbHRoQ2hlY2tQcm9wcz4ge1xuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuSGVhbHRoQ2hlY2tQcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hlYWx0aENoZWNrQ29uZmlnJywgJ0hlYWx0aENoZWNrQ29uZmlnJywgQ2ZuSGVhbHRoQ2hlY2tIZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuSGVhbHRoQ2hlY2tDb25maWcpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hlYWx0aENoZWNrVGFncycsICdIZWFsdGhDaGVja1RhZ3MnLCBwcm9wZXJ0aWVzLkhlYWx0aENoZWNrVGFncyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5IZWFsdGhDaGVja0hlYWx0aENoZWNrVGFnUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuSGVhbHRoQ2hlY2tUYWdzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpSb3V0ZTUzOjpIZWFsdGhDaGVja2BcbiAqXG4gKiBUaGUgYEFXUzo6Um91dGU1Mzo6SGVhbHRoQ2hlY2tgIHJlc291cmNlIGlzIGEgUm91dGUgNTMgcmVzb3VyY2UgdHlwZSB0aGF0IGNvbnRhaW5zIHNldHRpbmdzIGZvciBhIFJvdXRlIDUzIGhlYWx0aCBjaGVjay5cbiAqXG4gKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgYXNzb2NpYXRpbmcgaGVhbHRoIGNoZWNrcyB3aXRoIHJlY29yZHMsIHNlZSBbSGVhbHRoQ2hlY2tJZF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUmVzb3VyY2VSZWNvcmRTZXQuaHRtbCNSb3V0ZTUzLVR5cGUtUmVzb3VyY2VSZWNvcmRTZXQtSGVhbHRoQ2hlY2tJZCkgaW4gW0NoYW5nZVJlc291cmNlUmVjb3JkU2V0c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ2hhbmdlUmVzb3VyY2VSZWNvcmRTZXRzLmh0bWwpIC5cbiAqXG4gKiA+IFlvdSBjYW4ndCBjcmVhdGUgYSBoZWFsdGggY2hlY2sgd2l0aCBzaW1wbGUgcm91dGluZy5cbiAqXG4gKiAqRUxCIExvYWQgQmFsYW5jZXJzKlxuICpcbiAqIElmIHlvdSdyZSByZWdpc3RlcmluZyBFQzIgaW5zdGFuY2VzIHdpdGggYW4gRWxhc3RpYyBMb2FkIEJhbGFuY2luZyAoRUxCKSBsb2FkIGJhbGFuY2VyLCBkbyBub3QgY3JlYXRlIEFtYXpvbiBSb3V0ZSA1MyBoZWFsdGggY2hlY2tzIGZvciB0aGUgRUMyIGluc3RhbmNlcy4gV2hlbiB5b3UgcmVnaXN0ZXIgYW4gRUMyIGluc3RhbmNlIHdpdGggYSBsb2FkIGJhbGFuY2VyLCB5b3UgY29uZmlndXJlIHNldHRpbmdzIGZvciBhbiBFTEIgaGVhbHRoIGNoZWNrLCB3aGljaCBwZXJmb3JtcyBhIHNpbWlsYXIgZnVuY3Rpb24gdG8gYSBSb3V0ZSA1MyBoZWFsdGggY2hlY2suXG4gKlxuICogKlByaXZhdGUgSG9zdGVkIFpvbmVzKlxuICpcbiAqIFlvdSBjYW4gYXNzb2NpYXRlIGhlYWx0aCBjaGVja3Mgd2l0aCBmYWlsb3ZlciByZWNvcmRzIGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZS4gTm90ZSB0aGUgZm9sbG93aW5nOlxuICpcbiAqIC0gUm91dGUgNTMgaGVhbHRoIGNoZWNrZXJzIGFyZSBvdXRzaWRlIHRoZSBWUEMuIFRvIGNoZWNrIHRoZSBoZWFsdGggb2YgYW4gZW5kcG9pbnQgd2l0aGluIGEgVlBDIGJ5IElQIGFkZHJlc3MsIHlvdSBtdXN0IGFzc2lnbiBhIHB1YmxpYyBJUCBhZGRyZXNzIHRvIHRoZSBpbnN0YW5jZSBpbiB0aGUgVlBDLlxuICogLSBZb3UgY2FuIGNvbmZpZ3VyZSBhIGhlYWx0aCBjaGVja2VyIHRvIGNoZWNrIHRoZSBoZWFsdGggb2YgYW4gZXh0ZXJuYWwgcmVzb3VyY2UgdGhhdCB0aGUgaW5zdGFuY2UgcmVsaWVzIG9uLCBzdWNoIGFzIGEgZGF0YWJhc2Ugc2VydmVyLlxuICogLSBZb3UgY2FuIGNyZWF0ZSBhIENsb3VkV2F0Y2ggbWV0cmljLCBhc3NvY2lhdGUgYW4gYWxhcm0gd2l0aCB0aGUgbWV0cmljLCBhbmQgdGhlbiBjcmVhdGUgYSBoZWFsdGggY2hlY2sgdGhhdCBpcyBiYXNlZCBvbiB0aGUgc3RhdGUgb2YgdGhlIGFsYXJtLiBGb3IgZXhhbXBsZSwgeW91IG1pZ2h0IGNyZWF0ZSBhIENsb3VkV2F0Y2ggbWV0cmljIHRoYXQgY2hlY2tzIHRoZSBzdGF0dXMgb2YgdGhlIEFtYXpvbiBFQzIgYFN0YXR1c0NoZWNrRmFpbGVkYCBtZXRyaWMsIGFkZCBhbiBhbGFybSB0byB0aGUgbWV0cmljLCBhbmQgdGhlbiBjcmVhdGUgYSBoZWFsdGggY2hlY2sgdGhhdCBpcyBiYXNlZCBvbiB0aGUgc3RhdGUgb2YgdGhlIGFsYXJtLiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgY3JlYXRpbmcgQ2xvdWRXYXRjaCBtZXRyaWNzIGFuZCBhbGFybXMgYnkgdXNpbmcgdGhlIENsb3VkV2F0Y2ggY29uc29sZSwgc2VlIHRoZSBbQW1hem9uIENsb3VkV2F0Y2ggVXNlciBHdWlkZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L0RldmVsb3Blckd1aWRlL1doYXRJc0Nsb3VkV2F0Y2guaHRtbCkgLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6Um91dGU1Mzo6SGVhbHRoQ2hlY2tcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWhlYWx0aGNoZWNrLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmbkhlYWx0aENoZWNrIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6Um91dGU1Mzo6SGVhbHRoQ2hlY2tcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmbkhlYWx0aENoZWNrIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5IZWFsdGhDaGVja1Byb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5IZWFsdGhDaGVjayhzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgaWRlbnRpZmllciB0aGF0IEFtYXpvbiBSb3V0ZSA1MyBhc3NpZ25lZCB0byB0aGUgaGVhbHRoIGNoZWNrIHdoZW4geW91IGNyZWF0ZWQgaXQuIFdoZW4geW91IGFkZCBvciB1cGRhdGUgYSByZXNvdXJjZSByZWNvcmQgc2V0LCB5b3UgdXNlIHRoaXMgdmFsdWUgdG8gc3BlY2lmeSB3aGljaCBoZWFsdGggY2hlY2sgdG8gdXNlLiBUaGUgdmFsdWUgY2FuIGJlIHVwIHRvIDY0IGNoYXJhY3RlcnMgbG9uZy5cbiAgICAgKiBAY2xvdWRmb3JtYXRpb25BdHRyaWJ1dGUgSGVhbHRoQ2hlY2tJZFxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBhdHRySGVhbHRoQ2hlY2tJZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBkZXRhaWxlZCBpbmZvcm1hdGlvbiBhYm91dCBvbmUgaGVhbHRoIGNoZWNrLlxuICAgICAqXG4gICAgICogRm9yIHRoZSB2YWx1ZXMgdG8gZW50ZXIgZm9yIGBIZWFsdGhDaGVja0NvbmZpZ2AgLCBzZWUgW0hlYWx0aENoZWNrQ29uZmlnXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9IZWFsdGhDaGVja0NvbmZpZy5odG1sKVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1oZWFsdGhjaGVjay5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnXG4gICAgICovXG4gICAgcHVibGljIGhlYWx0aENoZWNrQ29uZmlnOiBDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGBIZWFsdGhDaGVja1RhZ3NgIHByb3BlcnR5IGRlc2NyaWJlcyBrZXktdmFsdWUgcGFpcnMgdGhhdCBhcmUgYXNzb2NpYXRlZCB3aXRoIGFuIGBBV1M6OlJvdXRlNTM6OkhlYWx0aENoZWNrYCByZXNvdXJjZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtaGVhbHRoY2hlY2suaHRtbCNjZm4tcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja3RhZ3NcbiAgICAgKi9cbiAgICBwdWJsaWMgaGVhbHRoQ2hlY2tUYWdzOiBBcnJheTxDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja1RhZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpSb3V0ZTUzOjpIZWFsdGhDaGVja2AuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuSGVhbHRoQ2hlY2tQcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuSGVhbHRoQ2hlY2suQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICdoZWFsdGhDaGVja0NvbmZpZycsIHRoaXMpO1xuICAgICAgICB0aGlzLmF0dHJIZWFsdGhDaGVja0lkID0gY2RrLlRva2VuLmFzU3RyaW5nKHRoaXMuZ2V0QXR0KCdIZWFsdGhDaGVja0lkJykpO1xuXG4gICAgICAgIHRoaXMuaGVhbHRoQ2hlY2tDb25maWcgPSBwcm9wcy5oZWFsdGhDaGVja0NvbmZpZztcbiAgICAgICAgdGhpcy5oZWFsdGhDaGVja1RhZ3MgPSBwcm9wcy5oZWFsdGhDaGVja1RhZ3M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5IZWFsdGhDaGVjay5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaGVhbHRoQ2hlY2tDb25maWc6IHRoaXMuaGVhbHRoQ2hlY2tDb25maWcsXG4gICAgICAgICAgICBoZWFsdGhDaGVja1RhZ3M6IHRoaXMuaGVhbHRoQ2hlY2tUYWdzLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmbkhlYWx0aENoZWNrUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuSGVhbHRoQ2hlY2sge1xuICAgIC8qKlxuICAgICAqIEEgY29tcGxleCB0eXBlIHRoYXQgaWRlbnRpZmllcyB0aGUgQ2xvdWRXYXRjaCBhbGFybSB0aGF0IHlvdSB3YW50IEFtYXpvbiBSb3V0ZSA1MyBoZWFsdGggY2hlY2tlcnMgdG8gdXNlIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgaGVhbHRoIGNoZWNrIGlzIGhlYWx0aHkuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWFsYXJtaWRlbnRpZmllci5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBBbGFybUlkZW50aWZpZXJQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbmFtZSBvZiB0aGUgQ2xvdWRXYXRjaCBhbGFybSB0aGF0IHlvdSB3YW50IEFtYXpvbiBSb3V0ZSA1MyBoZWFsdGggY2hlY2tlcnMgdG8gdXNlIHRvIGRldGVybWluZSB3aGV0aGVyIHRoaXMgaGVhbHRoIGNoZWNrIGlzIGhlYWx0aHkuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gUm91dGUgNTMgc3VwcG9ydHMgQ2xvdWRXYXRjaCBhbGFybXMgd2l0aCB0aGUgZm9sbG93aW5nIGZlYXR1cmVzOlxuICAgICAgICAgKiA+XG4gICAgICAgICAqID4gLSBTdGFuZGFyZC1yZXNvbHV0aW9uIG1ldHJpY3MuIEhpZ2gtcmVzb2x1dGlvbiBtZXRyaWNzIGFyZW4ndCBzdXBwb3J0ZWQuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0hpZ2gtUmVzb2x1dGlvbiBNZXRyaWNzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvcHVibGlzaGluZ01ldHJpY3MuaHRtbCNoaWdoLXJlc29sdXRpb24tbWV0cmljcykgaW4gdGhlICpBbWF6b24gQ2xvdWRXYXRjaCBVc2VyIEd1aWRlKiAuXG4gICAgICAgICAqID4gLSBTdGF0aXN0aWNzOiBBdmVyYWdlLCBNaW5pbXVtLCBNYXhpbXVtLCBTdW0sIGFuZCBTYW1wbGVDb3VudC4gRXh0ZW5kZWQgc3RhdGlzdGljcyBhcmVuJ3Qgc3VwcG9ydGVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaGVhbHRoY2hlY2stYWxhcm1pZGVudGlmaWVyLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2stYWxhcm1pZGVudGlmaWVyLW5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEZvciB0aGUgQ2xvdWRXYXRjaCBhbGFybSB0aGF0IHlvdSB3YW50IFJvdXRlIDUzIGhlYWx0aCBjaGVja2VycyB0byB1c2UgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyBoZWFsdGggY2hlY2sgaXMgaGVhbHRoeSwgdGhlIHJlZ2lvbiB0aGF0IHRoZSBhbGFybSB3YXMgY3JlYXRlZCBpbi5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIHRoZSBjdXJyZW50IGxpc3Qgb2YgQ2xvdWRXYXRjaCByZWdpb25zLCBzZWUgW0FtYXpvbiBDbG91ZFdhdGNoIGVuZHBvaW50cyBhbmQgcXVvdGFzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2VuZXJhbC9sYXRlc3QvZ3IvY3dfcmVnaW9uLmh0bWwpIGluIHRoZSAqQW1hem9uIFdlYiBTZXJ2aWNlcyBHZW5lcmFsIFJlZmVyZW5jZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaGVhbHRoY2hlY2stYWxhcm1pZGVudGlmaWVyLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2stYWxhcm1pZGVudGlmaWVyLXJlZ2lvblxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcmVnaW9uOiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYEFsYXJtSWRlbnRpZmllclByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBBbGFybUlkZW50aWZpZXJQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5IZWFsdGhDaGVja19BbGFybUlkZW50aWZpZXJQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ25hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMubmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyZWdpb24nLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMucmVnaW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyZWdpb24nLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucmVnaW9uKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkFsYXJtSWRlbnRpZmllclByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpIZWFsdGhDaGVjay5BbGFybUlkZW50aWZpZXJgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEFsYXJtSWRlbnRpZmllclByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpIZWFsdGhDaGVjay5BbGFybUlkZW50aWZpZXJgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuSGVhbHRoQ2hlY2tBbGFybUlkZW50aWZpZXJQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuSGVhbHRoQ2hlY2tfQWxhcm1JZGVudGlmaWVyUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIE5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubmFtZSksXG4gICAgICAgIFJlZ2lvbjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5yZWdpb24pLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5IZWFsdGhDaGVja0FsYXJtSWRlbnRpZmllclByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuSGVhbHRoQ2hlY2suQWxhcm1JZGVudGlmaWVyUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuSGVhbHRoQ2hlY2suQWxhcm1JZGVudGlmaWVyUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCduYW1lJywgJ05hbWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLk5hbWUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3JlZ2lvbicsICdSZWdpb24nLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlJlZ2lvbikpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmbkhlYWx0aENoZWNrIHtcbiAgICAvKipcbiAgICAgKiBBIGNvbXBsZXggdHlwZSB0aGF0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBoZWFsdGggY2hlY2suXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIEhlYWx0aENoZWNrQ29uZmlnUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogQSBjb21wbGV4IHR5cGUgdGhhdCBpZGVudGlmaWVzIHRoZSBDbG91ZFdhdGNoIGFsYXJtIHRoYXQgeW91IHdhbnQgQW1hem9uIFJvdXRlIDUzIGhlYWx0aCBjaGVja2VycyB0byB1c2UgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBoZWFsdGggY2hlY2sgaXMgaGVhbHRoeS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctYWxhcm1pZGVudGlmaWVyXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBhbGFybUlkZW50aWZpZXI/OiBDZm5IZWFsdGhDaGVjay5BbGFybUlkZW50aWZpZXJQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIChDQUxDVUxBVEVEIEhlYWx0aCBDaGVja3MgT25seSkgQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBvbmUgYENoaWxkSGVhbHRoQ2hlY2tgIGVsZW1lbnQgZm9yIGVhY2ggaGVhbHRoIGNoZWNrIHRoYXQgeW91IHdhbnQgdG8gYXNzb2NpYXRlIHdpdGggYSBgQ0FMQ1VMQVRFRGAgaGVhbHRoIGNoZWNrLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWcuaHRtbCNjZm4tcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy1jaGlsZGhlYWx0aGNoZWNrc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY2hpbGRIZWFsdGhDaGVja3M/OiBzdHJpbmdbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNwZWNpZnkgd2hldGhlciB5b3Ugd2FudCBBbWF6b24gUm91dGUgNTMgdG8gc2VuZCB0aGUgdmFsdWUgb2YgYEZ1bGx5UXVhbGlmaWVkRG9tYWluTmFtZWAgdG8gdGhlIGVuZHBvaW50IGluIHRoZSBgY2xpZW50X2hlbGxvYCBtZXNzYWdlIGR1cmluZyBUTFMgbmVnb3RpYXRpb24uIFRoaXMgYWxsb3dzIHRoZSBlbmRwb2ludCB0byByZXNwb25kIHRvIGBIVFRQU2AgaGVhbHRoIGNoZWNrIHJlcXVlc3RzIHdpdGggdGhlIGFwcGxpY2FibGUgU1NML1RMUyBjZXJ0aWZpY2F0ZS5cbiAgICAgICAgICpcbiAgICAgICAgICogU29tZSBlbmRwb2ludHMgcmVxdWlyZSB0aGF0IGBIVFRQU2AgcmVxdWVzdHMgaW5jbHVkZSB0aGUgaG9zdCBuYW1lIGluIHRoZSBgY2xpZW50X2hlbGxvYCBtZXNzYWdlLiBJZiB5b3UgZG9uJ3QgZW5hYmxlIFNOSSwgdGhlIHN0YXR1cyBvZiB0aGUgaGVhbHRoIGNoZWNrIHdpbGwgYmUgYFNTTCBhbGVydCBoYW5kc2hha2VfZmFpbHVyZWAgLiBBIGhlYWx0aCBjaGVjayBjYW4gYWxzbyBoYXZlIHRoYXQgc3RhdHVzIGZvciBvdGhlciByZWFzb25zLiBJZiBTTkkgaXMgZW5hYmxlZCBhbmQgeW91J3JlIHN0aWxsIGdldHRpbmcgdGhlIGVycm9yLCBjaGVjayB0aGUgU1NML1RMUyBjb25maWd1cmF0aW9uIG9uIHlvdXIgZW5kcG9pbnQgYW5kIGNvbmZpcm0gdGhhdCB5b3VyIGNlcnRpZmljYXRlIGlzIHZhbGlkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBUaGUgU1NML1RMUyBjZXJ0aWZpY2F0ZSBvbiB5b3VyIGVuZHBvaW50IGluY2x1ZGVzIGEgZG9tYWluIG5hbWUgaW4gdGhlIGBDb21tb24gTmFtZWAgZmllbGQgYW5kIHBvc3NpYmx5IHNldmVyYWwgbW9yZSBpbiB0aGUgYFN1YmplY3QgQWx0ZXJuYXRpdmUgTmFtZXNgIGZpZWxkLiBPbmUgb2YgdGhlIGRvbWFpbiBuYW1lcyBpbiB0aGUgY2VydGlmaWNhdGUgc2hvdWxkIG1hdGNoIHRoZSB2YWx1ZSB0aGF0IHlvdSBzcGVjaWZ5IGZvciBgRnVsbHlRdWFsaWZpZWREb21haW5OYW1lYCAuIElmIHRoZSBlbmRwb2ludCByZXNwb25kcyB0byB0aGUgYGNsaWVudF9oZWxsb2AgbWVzc2FnZSB3aXRoIGEgY2VydGlmaWNhdGUgdGhhdCBkb2VzIG5vdCBpbmNsdWRlIHRoZSBkb21haW4gbmFtZSB0aGF0IHlvdSBzcGVjaWZpZWQgaW4gYEZ1bGx5UXVhbGlmaWVkRG9tYWluTmFtZWAgLCBhIGhlYWx0aCBjaGVja2VyIHdpbGwgcmV0cnkgdGhlIGhhbmRzaGFrZS4gSW4gdGhlIHNlY29uZCBhdHRlbXB0LCB0aGUgaGVhbHRoIGNoZWNrZXIgd2lsbCBvbWl0IGBGdWxseVF1YWxpZmllZERvbWFpbk5hbWVgIGZyb20gdGhlIGBjbGllbnRfaGVsbG9gIG1lc3NhZ2UuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLWVuYWJsZXNuaVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZW5hYmxlU25pPzogYm9vbGVhbiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBudW1iZXIgb2YgY29uc2VjdXRpdmUgaGVhbHRoIGNoZWNrcyB0aGF0IGFuIGVuZHBvaW50IG11c3QgcGFzcyBvciBmYWlsIGZvciBBbWF6b24gUm91dGUgNTMgdG8gY2hhbmdlIHRoZSBjdXJyZW50IHN0YXR1cyBvZiB0aGUgZW5kcG9pbnQgZnJvbSB1bmhlYWx0aHkgdG8gaGVhbHRoeSBvciB2aWNlIHZlcnNhLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtIb3cgQW1hem9uIFJvdXRlIDUzIERldGVybWluZXMgV2hldGhlciBhbiBFbmRwb2ludCBJcyBIZWFsdGh5XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLWRldGVybWluaW5nLWhlYWx0aC1vZi1lbmRwb2ludHMuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSBkb24ndCBzcGVjaWZ5IGEgdmFsdWUgZm9yIGBGYWlsdXJlVGhyZXNob2xkYCAsIHRoZSBkZWZhdWx0IHZhbHVlIGlzIHRocmVlIGhlYWx0aCBjaGVja3MuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLWZhaWx1cmV0aHJlc2hvbGRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGZhaWx1cmVUaHJlc2hvbGQ/OiBudW1iZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbWF6b24gUm91dGUgNTMgYmVoYXZpb3IgZGVwZW5kcyBvbiB3aGV0aGVyIHlvdSBzcGVjaWZ5IGEgdmFsdWUgZm9yIGBJUEFkZHJlc3NgIC5cbiAgICAgICAgICpcbiAgICAgICAgICogKklmIHlvdSBzcGVjaWZ5IGEgdmFsdWUgZm9yKiBgSVBBZGRyZXNzYCA6XG4gICAgICAgICAqXG4gICAgICAgICAqIEFtYXpvbiBSb3V0ZSA1MyBzZW5kcyBoZWFsdGggY2hlY2sgcmVxdWVzdHMgdG8gdGhlIHNwZWNpZmllZCBJUHY0IG9yIElQdjYgYWRkcmVzcyBhbmQgcGFzc2VzIHRoZSB2YWx1ZSBvZiBgRnVsbHlRdWFsaWZpZWREb21haW5OYW1lYCBpbiB0aGUgYEhvc3RgIGhlYWRlciBmb3IgYWxsIGhlYWx0aCBjaGVja3MgZXhjZXB0IFRDUCBoZWFsdGggY2hlY2tzLiBUaGlzIGlzIHR5cGljYWxseSB0aGUgZnVsbHkgcXVhbGlmaWVkIEROUyBuYW1lIG9mIHRoZSBlbmRwb2ludCBvbiB3aGljaCB5b3Ugd2FudCBSb3V0ZSA1MyB0byBwZXJmb3JtIGhlYWx0aCBjaGVja3MuXG4gICAgICAgICAqXG4gICAgICAgICAqIFdoZW4gUm91dGUgNTMgY2hlY2tzIHRoZSBoZWFsdGggb2YgYW4gZW5kcG9pbnQsIGhlcmUgaXMgaG93IGl0IGNvbnN0cnVjdHMgdGhlIGBIb3N0YCBoZWFkZXI6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gSWYgeW91IHNwZWNpZnkgYSB2YWx1ZSBvZiBgODBgIGZvciBgUG9ydGAgYW5kIGBIVFRQYCBvciBgSFRUUF9TVFJfTUFUQ0hgIGZvciBgVHlwZWAgLCBSb3V0ZSA1MyBwYXNzZXMgdGhlIHZhbHVlIG9mIGBGdWxseVF1YWxpZmllZERvbWFpbk5hbWVgIHRvIHRoZSBlbmRwb2ludCBpbiB0aGUgSG9zdCBoZWFkZXIuXG4gICAgICAgICAqIC0gSWYgeW91IHNwZWNpZnkgYSB2YWx1ZSBvZiBgNDQzYCBmb3IgYFBvcnRgIGFuZCBgSFRUUFNgIG9yIGBIVFRQU19TVFJfTUFUQ0hgIGZvciBgVHlwZWAgLCBSb3V0ZSA1MyBwYXNzZXMgdGhlIHZhbHVlIG9mIGBGdWxseVF1YWxpZmllZERvbWFpbk5hbWVgIHRvIHRoZSBlbmRwb2ludCBpbiB0aGUgYEhvc3RgIGhlYWRlci5cbiAgICAgICAgICogLSBJZiB5b3Ugc3BlY2lmeSBhbm90aGVyIHZhbHVlIGZvciBgUG9ydGAgYW5kIGFueSB2YWx1ZSBleGNlcHQgYFRDUGAgZm9yIGBUeXBlYCAsIFJvdXRlIDUzIHBhc3NlcyBgRnVsbHlRdWFsaWZpZWREb21haW5OYW1lOlBvcnRgIHRvIHRoZSBlbmRwb2ludCBpbiB0aGUgYEhvc3RgIGhlYWRlci5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgeW91IGRvbid0IHNwZWNpZnkgYSB2YWx1ZSBmb3IgYEZ1bGx5UXVhbGlmaWVkRG9tYWluTmFtZWAgLCBSb3V0ZSA1MyBzdWJzdGl0dXRlcyB0aGUgdmFsdWUgb2YgYElQQWRkcmVzc2AgaW4gdGhlIGBIb3N0YCBoZWFkZXIgaW4gZWFjaCBvZiB0aGUgcHJlY2VkaW5nIGNhc2VzLlxuICAgICAgICAgKlxuICAgICAgICAgKiAqSWYgeW91IGRvbid0IHNwZWNpZnkgYSB2YWx1ZSBmb3IgYElQQWRkcmVzc2AqIDpcbiAgICAgICAgICpcbiAgICAgICAgICogUm91dGUgNTMgc2VuZHMgYSBETlMgcmVxdWVzdCB0byB0aGUgZG9tYWluIHRoYXQgeW91IHNwZWNpZnkgZm9yIGBGdWxseVF1YWxpZmllZERvbWFpbk5hbWVgIGF0IHRoZSBpbnRlcnZhbCB0aGF0IHlvdSBzcGVjaWZ5IGZvciBgUmVxdWVzdEludGVydmFsYCAuIFVzaW5nIGFuIElQdjQgYWRkcmVzcyB0aGF0IEROUyByZXR1cm5zLCBSb3V0ZSA1MyB0aGVuIGNoZWNrcyB0aGUgaGVhbHRoIG9mIHRoZSBlbmRwb2ludC5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBJZiB5b3UgZG9uJ3Qgc3BlY2lmeSBhIHZhbHVlIGZvciBgSVBBZGRyZXNzYCAsIFJvdXRlIDUzIHVzZXMgb25seSBJUHY0IHRvIHNlbmQgaGVhbHRoIGNoZWNrcyB0byB0aGUgZW5kcG9pbnQuIElmIHRoZXJlJ3Mgbm8gcmVjb3JkIHdpdGggYSB0eXBlIG9mIEEgZm9yIHRoZSBuYW1lIHRoYXQgeW91IHNwZWNpZnkgZm9yIGBGdWxseVF1YWxpZmllZERvbWFpbk5hbWVgICwgdGhlIGhlYWx0aCBjaGVjayBmYWlscyB3aXRoIGEgXCJETlMgcmVzb2x1dGlvbiBmYWlsZWRcIiBlcnJvci5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgeW91IHdhbnQgdG8gY2hlY2sgdGhlIGhlYWx0aCBvZiBtdWx0aXBsZSByZWNvcmRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBuYW1lIGFuZCB0eXBlLCBzdWNoIGFzIG11bHRpcGxlIHdlaWdodGVkIHJlY29yZHMsIGFuZCBpZiB5b3UgY2hvb3NlIHRvIHNwZWNpZnkgdGhlIGVuZHBvaW50IG9ubHkgYnkgYEZ1bGx5UXVhbGlmaWVkRG9tYWluTmFtZWAgLCB3ZSByZWNvbW1lbmQgdGhhdCB5b3UgY3JlYXRlIGEgc2VwYXJhdGUgaGVhbHRoIGNoZWNrIGZvciBlYWNoIGVuZHBvaW50LiBGb3IgZXhhbXBsZSwgY3JlYXRlIGEgaGVhbHRoIGNoZWNrIGZvciBlYWNoIEhUVFAgc2VydmVyIHRoYXQgaXMgc2VydmluZyBjb250ZW50IGZvciB3d3cuZXhhbXBsZS5jb20uIEZvciB0aGUgdmFsdWUgb2YgYEZ1bGx5UXVhbGlmaWVkRG9tYWluTmFtZWAgLCBzcGVjaWZ5IHRoZSBkb21haW4gbmFtZSBvZiB0aGUgc2VydmVyIChzdWNoIGFzIHVzLWVhc3QtMi13d3cuZXhhbXBsZS5jb20pLCBub3QgdGhlIG5hbWUgb2YgdGhlIHJlY29yZHMgKHd3dy5leGFtcGxlLmNvbSkuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gSW4gdGhpcyBjb25maWd1cmF0aW9uLCBpZiB5b3UgY3JlYXRlIGEgaGVhbHRoIGNoZWNrIGZvciB3aGljaCB0aGUgdmFsdWUgb2YgYEZ1bGx5UXVhbGlmaWVkRG9tYWluTmFtZWAgbWF0Y2hlcyB0aGUgbmFtZSBvZiB0aGUgcmVjb3JkcyBhbmQgeW91IHRoZW4gYXNzb2NpYXRlIHRoZSBoZWFsdGggY2hlY2sgd2l0aCB0aG9zZSByZWNvcmRzLCBoZWFsdGggY2hlY2sgcmVzdWx0cyB3aWxsIGJlIHVucHJlZGljdGFibGUuXG4gICAgICAgICAqXG4gICAgICAgICAqIEluIGFkZGl0aW9uLCBpZiB0aGUgdmFsdWUgdGhhdCB5b3Ugc3BlY2lmeSBmb3IgYFR5cGVgIGlzIGBIVFRQYCAsIGBIVFRQU2AgLCBgSFRUUF9TVFJfTUFUQ0hgICwgb3IgYEhUVFBTX1NUUl9NQVRDSGAgLCBSb3V0ZSA1MyBwYXNzZXMgdGhlIHZhbHVlIG9mIGBGdWxseVF1YWxpZmllZERvbWFpbk5hbWVgIGluIHRoZSBgSG9zdGAgaGVhZGVyLCBhcyBpdCBkb2VzIHdoZW4geW91IHNwZWNpZnkgYSB2YWx1ZSBmb3IgYElQQWRkcmVzc2AgLiBJZiB0aGUgdmFsdWUgb2YgYFR5cGVgIGlzIGBUQ1BgICwgUm91dGUgNTMgZG9lc24ndCBwYXNzIGEgYEhvc3RgIGhlYWRlci5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctZnVsbHlxdWFsaWZpZWRkb21haW5uYW1lXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBmdWxseVF1YWxpZmllZERvbWFpbk5hbWU/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbnVtYmVyIG9mIGNoaWxkIGhlYWx0aCBjaGVja3MgdGhhdCBhcmUgYXNzb2NpYXRlZCB3aXRoIGEgYENBTENVTEFURURgIGhlYWx0aCBjaGVjayB0aGF0IEFtYXpvbiBSb3V0ZSA1MyBtdXN0IGNvbnNpZGVyIGhlYWx0aHkgZm9yIHRoZSBgQ0FMQ1VMQVRFRGAgaGVhbHRoIGNoZWNrIHRvIGJlIGNvbnNpZGVyZWQgaGVhbHRoeS4gVG8gc3BlY2lmeSB0aGUgY2hpbGQgaGVhbHRoIGNoZWNrcyB0aGF0IHlvdSB3YW50IHRvIGFzc29jaWF0ZSB3aXRoIGEgYENBTENVTEFURURgIGhlYWx0aCBjaGVjaywgdXNlIHRoZSBbQ2hpbGRIZWFsdGhDaGVja3NdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1VwZGF0ZUhlYWx0aENoZWNrLmh0bWwjUm91dGU1My1VcGRhdGVIZWFsdGhDaGVjay1yZXF1ZXN0LUNoaWxkSGVhbHRoQ2hlY2tzKSBlbGVtZW50LlxuICAgICAgICAgKlxuICAgICAgICAgKiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gSWYgeW91IHNwZWNpZnkgYSBudW1iZXIgZ3JlYXRlciB0aGFuIHRoZSBudW1iZXIgb2YgY2hpbGQgaGVhbHRoIGNoZWNrcywgUm91dGUgNTMgYWx3YXlzIGNvbnNpZGVycyB0aGlzIGhlYWx0aCBjaGVjayB0byBiZSB1bmhlYWx0aHkuXG4gICAgICAgICAqIC0gSWYgeW91IHNwZWNpZnkgYDBgICwgUm91dGUgNTMgYWx3YXlzIGNvbnNpZGVycyB0aGlzIGhlYWx0aCBjaGVjayB0byBiZSBoZWFsdGh5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWcuaHRtbCNjZm4tcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy1oZWFsdGh0aHJlc2hvbGRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGhlYWx0aFRocmVzaG9sZD86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBJUHY0IG9yIElQdjYgSVAgYWRkcmVzcyBvZiB0aGUgZW5kcG9pbnQgdGhhdCB5b3Ugd2FudCBBbWF6b24gUm91dGUgNTMgdG8gcGVyZm9ybSBoZWFsdGggY2hlY2tzIG9uLiBJZiB5b3UgZG9uJ3Qgc3BlY2lmeSBhIHZhbHVlIGZvciBgSVBBZGRyZXNzYCAsIFJvdXRlIDUzIHNlbmRzIGEgRE5TIHJlcXVlc3QgdG8gcmVzb2x2ZSB0aGUgZG9tYWluIG5hbWUgdGhhdCB5b3Ugc3BlY2lmeSBpbiBgRnVsbHlRdWFsaWZpZWREb21haW5OYW1lYCBhdCB0aGUgaW50ZXJ2YWwgdGhhdCB5b3Ugc3BlY2lmeSBpbiBgUmVxdWVzdEludGVydmFsYCAuIFVzaW5nIGFuIElQIGFkZHJlc3MgcmV0dXJuZWQgYnkgRE5TLCBSb3V0ZSA1MyB0aGVuIGNoZWNrcyB0aGUgaGVhbHRoIG9mIHRoZSBlbmRwb2ludC5cbiAgICAgICAgICpcbiAgICAgICAgICogVXNlIG9uZSBvZiB0aGUgZm9sbG93aW5nIGZvcm1hdHMgZm9yIHRoZSB2YWx1ZSBvZiBgSVBBZGRyZXNzYCA6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKklQdjQgYWRkcmVzcyogOiBmb3VyIHZhbHVlcyBiZXR3ZWVuIDAgYW5kIDI1NSwgc2VwYXJhdGVkIGJ5IHBlcmlvZHMgKC4pLCBmb3IgZXhhbXBsZSwgYDE5Mi4wLjIuNDRgIC5cbiAgICAgICAgICogLSAqSVB2NiBhZGRyZXNzKiA6IGVpZ2h0IGdyb3VwcyBvZiBmb3VyIGhleGFkZWNpbWFsIHZhbHVlcywgc2VwYXJhdGVkIGJ5IGNvbG9ucyAoOiksIGZvciBleGFtcGxlLCBgMjAwMTowZGI4Ojg1YTM6MDAwMDowMDAwOmFiY2Q6MDAwMToyMzQ1YCAuIFlvdSBjYW4gYWxzbyBzaG9ydGVuIElQdjYgYWRkcmVzc2VzIGFzIGRlc2NyaWJlZCBpbiBSRkMgNTk1MiwgZm9yIGV4YW1wbGUsIGAyMDAxOmRiODo4NWEzOjphYmNkOjE6MjM0NWAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB0aGUgZW5kcG9pbnQgaXMgYW4gRUMyIGluc3RhbmNlLCB3ZSByZWNvbW1lbmQgdGhhdCB5b3UgY3JlYXRlIGFuIEVsYXN0aWMgSVAgYWRkcmVzcywgYXNzb2NpYXRlIGl0IHdpdGggeW91ciBFQzIgaW5zdGFuY2UsIGFuZCBzcGVjaWZ5IHRoZSBFbGFzdGljIElQIGFkZHJlc3MgZm9yIGBJUEFkZHJlc3NgIC4gVGhpcyBlbnN1cmVzIHRoYXQgdGhlIElQIGFkZHJlc3Mgb2YgeW91ciBpbnN0YW5jZSB3aWxsIG5ldmVyIGNoYW5nZS5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbRnVsbHlRdWFsaWZpZWREb21haW5OYW1lXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9VcGRhdGVIZWFsdGhDaGVjay5odG1sI1JvdXRlNTMtVXBkYXRlSGVhbHRoQ2hlY2stcmVxdWVzdC1GdWxseVF1YWxpZmllZERvbWFpbk5hbWUpIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQ29uc3RyYWludHM6IFJvdXRlIDUzIGNhbid0IGNoZWNrIHRoZSBoZWFsdGggb2YgZW5kcG9pbnRzIGZvciB3aGljaCB0aGUgSVAgYWRkcmVzcyBpcyBpbiBsb2NhbCwgcHJpdmF0ZSwgbm9uLXJvdXRhYmxlLCBvciBtdWx0aWNhc3QgcmFuZ2VzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBJUCBhZGRyZXNzZXMgZm9yIHdoaWNoIHlvdSBjYW4ndCBjcmVhdGUgaGVhbHRoIGNoZWNrcywgc2VlIHRoZSBmb2xsb3dpbmcgZG9jdW1lbnRzOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIFtSRkMgNTczNSwgU3BlY2lhbCBVc2UgSVB2NCBBZGRyZXNzZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNTczNSlcbiAgICAgICAgICogLSBbUkZDIDY1OTgsIElBTkEtUmVzZXJ2ZWQgSVB2NCBQcmVmaXggZm9yIFNoYXJlZCBBZGRyZXNzIFNwYWNlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzY1OTgpXG4gICAgICAgICAqIC0gW1JGQyA1MTU2LCBTcGVjaWFsLVVzZSBJUHY2IEFkZHJlc3Nlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM1MTU2KVxuICAgICAgICAgKlxuICAgICAgICAgKiBXaGVuIHRoZSB2YWx1ZSBvZiBgVHlwZWAgaXMgYENBTENVTEFURURgIG9yIGBDTE9VRFdBVENIX01FVFJJQ2AgLCBvbWl0IGBJUEFkZHJlc3NgIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctaXBhZGRyZXNzXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBpcEFkZHJlc3M/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaGVuIENsb3VkV2F0Y2ggaGFzIGluc3VmZmljaWVudCBkYXRhIGFib3V0IHRoZSBtZXRyaWMgdG8gZGV0ZXJtaW5lIHRoZSBhbGFybSBzdGF0ZSwgdGhlIHN0YXR1cyB0aGF0IHlvdSB3YW50IEFtYXpvbiBSb3V0ZSA1MyB0byBhc3NpZ24gdG8gdGhlIGhlYWx0aCBjaGVjazpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBgSGVhbHRoeWAgOiBSb3V0ZSA1MyBjb25zaWRlcnMgdGhlIGhlYWx0aCBjaGVjayB0byBiZSBoZWFsdGh5LlxuICAgICAgICAgKiAtIGBVbmhlYWx0aHlgIDogUm91dGUgNTMgY29uc2lkZXJzIHRoZSBoZWFsdGggY2hlY2sgdG8gYmUgdW5oZWFsdGh5LlxuICAgICAgICAgKiAtIGBMYXN0S25vd25TdGF0dXNgIDogUm91dGUgNTMgdXNlcyB0aGUgc3RhdHVzIG9mIHRoZSBoZWFsdGggY2hlY2sgZnJvbSB0aGUgbGFzdCB0aW1lIHRoYXQgQ2xvdWRXYXRjaCBoYWQgc3VmZmljaWVudCBkYXRhIHRvIGRldGVybWluZSB0aGUgYWxhcm0gc3RhdGUuIEZvciBuZXcgaGVhbHRoIGNoZWNrcyB0aGF0IGhhdmUgbm8gbGFzdCBrbm93biBzdGF0dXMsIHRoZSBkZWZhdWx0IHN0YXR1cyBmb3IgdGhlIGhlYWx0aCBjaGVjayBpcyBoZWFsdGh5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWcuaHRtbCNjZm4tcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy1pbnN1ZmZpY2llbnRkYXRhaGVhbHRoc3RhdHVzXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBpbnN1ZmZpY2llbnREYXRhSGVhbHRoU3RhdHVzPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogU3BlY2lmeSB3aGV0aGVyIHlvdSB3YW50IEFtYXpvbiBSb3V0ZSA1MyB0byBpbnZlcnQgdGhlIHN0YXR1cyBvZiBhIGhlYWx0aCBjaGVjaywgZm9yIGV4YW1wbGUsIHRvIGNvbnNpZGVyIGEgaGVhbHRoIGNoZWNrIHVuaGVhbHRoeSB3aGVuIGl0IG90aGVyd2lzZSB3b3VsZCBiZSBjb25zaWRlcmVkIGhlYWx0aHkuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLWludmVydGVkXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBpbnZlcnRlZD86IGJvb2xlYW4gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTcGVjaWZ5IHdoZXRoZXIgeW91IHdhbnQgQW1hem9uIFJvdXRlIDUzIHRvIG1lYXN1cmUgdGhlIGxhdGVuY3kgYmV0d2VlbiBoZWFsdGggY2hlY2tlcnMgaW4gbXVsdGlwbGUgQVdTIHJlZ2lvbnMgYW5kIHlvdXIgZW5kcG9pbnQsIGFuZCB0byBkaXNwbGF5IENsb3VkV2F0Y2ggbGF0ZW5jeSBncmFwaHMgb24gdGhlICpIZWFsdGggQ2hlY2tzKiBwYWdlIGluIHRoZSBSb3V0ZSA1MyBjb25zb2xlLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFlvdSBjYW4ndCBjaGFuZ2UgdGhlIHZhbHVlIG9mIGBNZWFzdXJlTGF0ZW5jeWAgYWZ0ZXIgeW91IGNyZWF0ZSBhIGhlYWx0aCBjaGVjay5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctbWVhc3VyZWxhdGVuY3lcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IG1lYXN1cmVMYXRlbmN5PzogYm9vbGVhbiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwb3J0IG9uIHRoZSBlbmRwb2ludCB0aGF0IHlvdSB3YW50IEFtYXpvbiBSb3V0ZSA1MyB0byBwZXJmb3JtIGhlYWx0aCBjaGVja3Mgb24uXG4gICAgICAgICAqXG4gICAgICAgICAqID4gRG9uJ3Qgc3BlY2lmeSBhIHZhbHVlIGZvciBgUG9ydGAgd2hlbiB5b3Ugc3BlY2lmeSBhIHZhbHVlIGZvciBbVHlwZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLXR5cGUpIG9mIGBDTE9VRFdBVENIX01FVFJJQ2Agb3IgYENBTENVTEFURURgIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctcG9ydFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcG9ydD86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgY29tcGxleCB0eXBlIHRoYXQgY29udGFpbnMgb25lIGBSZWdpb25gIGVsZW1lbnQgZm9yIGVhY2ggcmVnaW9uIGZyb20gd2hpY2ggeW91IHdhbnQgQW1hem9uIFJvdXRlIDUzIGhlYWx0aCBjaGVja2VycyB0byBjaGVjayB0aGUgc3BlY2lmaWVkIGVuZHBvaW50LlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB5b3UgZG9uJ3Qgc3BlY2lmeSBhbnkgcmVnaW9ucywgUm91dGUgNTMgaGVhbHRoIGNoZWNrZXJzIGF1dG9tYXRpY2FsbHkgcGVyZm9ybXMgY2hlY2tzIGZyb20gYWxsIG9mIHRoZSByZWdpb25zIHRoYXQgYXJlIGxpc3RlZCB1bmRlciAqVmFsaWQgVmFsdWVzKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSB1cGRhdGUgYSBoZWFsdGggY2hlY2sgdG8gcmVtb3ZlIGEgcmVnaW9uIHRoYXQgaGFzIGJlZW4gcGVyZm9ybWluZyBoZWFsdGggY2hlY2tzLCBSb3V0ZSA1MyB3aWxsIGJyaWVmbHkgY29udGludWUgdG8gcGVyZm9ybSBjaGVja3MgZnJvbSB0aGF0IHJlZ2lvbiB0byBlbnN1cmUgdGhhdCBzb21lIGhlYWx0aCBjaGVja2VycyBhcmUgYWx3YXlzIGNoZWNraW5nIHRoZSBlbmRwb2ludCAoZm9yIGV4YW1wbGUsIGlmIHlvdSByZXBsYWNlIHRocmVlIHJlZ2lvbnMgd2l0aCBmb3VyIGRpZmZlcmVudCByZWdpb25zKS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctcmVnaW9uc1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcmVnaW9ucz86IHN0cmluZ1tdO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG51bWJlciBvZiBzZWNvbmRzIGJldHdlZW4gdGhlIHRpbWUgdGhhdCBBbWF6b24gUm91dGUgNTMgZ2V0cyBhIHJlc3BvbnNlIGZyb20geW91ciBlbmRwb2ludCBhbmQgdGhlIHRpbWUgdGhhdCBpdCBzZW5kcyB0aGUgbmV4dCBoZWFsdGggY2hlY2sgcmVxdWVzdC4gRWFjaCBSb3V0ZSA1MyBoZWFsdGggY2hlY2tlciBtYWtlcyByZXF1ZXN0cyBhdCB0aGlzIGludGVydmFsLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFlvdSBjYW4ndCBjaGFuZ2UgdGhlIHZhbHVlIG9mIGBSZXF1ZXN0SW50ZXJ2YWxgIGFmdGVyIHlvdSBjcmVhdGUgYSBoZWFsdGggY2hlY2suXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSBkb24ndCBzcGVjaWZ5IGEgdmFsdWUgZm9yIGBSZXF1ZXN0SW50ZXJ2YWxgICwgdGhlIGRlZmF1bHQgdmFsdWUgaXMgYDMwYCBzZWNvbmRzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWcuaHRtbCNjZm4tcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy1yZXF1ZXN0aW50ZXJ2YWxcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHJlcXVlc3RJbnRlcnZhbD86IG51bWJlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwYXRoLCBpZiBhbnksIHRoYXQgeW91IHdhbnQgQW1hem9uIFJvdXRlIDUzIHRvIHJlcXVlc3Qgd2hlbiBwZXJmb3JtaW5nIGhlYWx0aCBjaGVja3MuIFRoZSBwYXRoIGNhbiBiZSBhbnkgdmFsdWUgZm9yIHdoaWNoIHlvdXIgZW5kcG9pbnQgd2lsbCByZXR1cm4gYW4gSFRUUCBzdGF0dXMgY29kZSBvZiAyeHggb3IgM3h4IHdoZW4gdGhlIGVuZHBvaW50IGlzIGhlYWx0aHksIGZvciBleGFtcGxlLCB0aGUgZmlsZSAvZG9jcy9yb3V0ZTUzLWhlYWx0aC1jaGVjay5odG1sLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBxdWVyeSBzdHJpbmcgcGFyYW1ldGVycywgZm9yIGV4YW1wbGUsIGAvd2VsY29tZS5odG1sP2xhbmd1YWdlPWpwJmxvZ2luPXlgIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctcmVzb3VyY2VwYXRoXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSByZXNvdXJjZVBhdGg/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBgQ2ZuSGVhbHRoQ2hlY2suSGVhbHRoQ2hlY2tDb25maWdQcm9wZXJ0eS5Sb3V0aW5nQ29udHJvbEFybmBcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctcm91dGluZ2NvbnRyb2xhcm5cbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHJvdXRpbmdDb250cm9sQXJuPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogSWYgdGhlIHZhbHVlIG9mIFR5cGUgaXMgYEhUVFBfU1RSX01BVENIYCBvciBgSFRUUFNfU1RSX01BVENIYCAsIHRoZSBzdHJpbmcgdGhhdCB5b3Ugd2FudCBBbWF6b24gUm91dGUgNTMgdG8gc2VhcmNoIGZvciBpbiB0aGUgcmVzcG9uc2UgYm9keSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVzb3VyY2UuIElmIHRoZSBzdHJpbmcgYXBwZWFycyBpbiB0aGUgcmVzcG9uc2UgYm9keSwgUm91dGUgNTMgY29uc2lkZXJzIHRoZSByZXNvdXJjZSBoZWFsdGh5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBSb3V0ZSA1MyBjb25zaWRlcnMgY2FzZSB3aGVuIHNlYXJjaGluZyBmb3IgYFNlYXJjaFN0cmluZ2AgaW4gdGhlIHJlc3BvbnNlIGJvZHkuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja2NvbmZpZy5odG1sI2Nmbi1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLXNlYXJjaHN0cmluZ1xuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgc2VhcmNoU3RyaW5nPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHR5cGUgb2YgaGVhbHRoIGNoZWNrIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlLCB3aGljaCBpbmRpY2F0ZXMgaG93IEFtYXpvbiBSb3V0ZSA1MyBkZXRlcm1pbmVzIHdoZXRoZXIgYW4gZW5kcG9pbnQgaXMgaGVhbHRoeS5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBZb3UgY2FuJ3QgY2hhbmdlIHRoZSB2YWx1ZSBvZiBgVHlwZWAgYWZ0ZXIgeW91IGNyZWF0ZSBhIGhlYWx0aCBjaGVjay5cbiAgICAgICAgICpcbiAgICAgICAgICogWW91IGNhbiBjcmVhdGUgdGhlIGZvbGxvd2luZyB0eXBlcyBvZiBoZWFsdGggY2hlY2tzOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpIVFRQKiA6IFJvdXRlIDUzIHRyaWVzIHRvIGVzdGFibGlzaCBhIFRDUCBjb25uZWN0aW9uLiBJZiBzdWNjZXNzZnVsLCBSb3V0ZSA1MyBzdWJtaXRzIGFuIEhUVFAgcmVxdWVzdCBhbmQgd2FpdHMgZm9yIGFuIEhUVFAgc3RhdHVzIGNvZGUgb2YgMjAwIG9yIGdyZWF0ZXIgYW5kIGxlc3MgdGhhbiA0MDAuXG4gICAgICAgICAqIC0gKkhUVFBTKiA6IFJvdXRlIDUzIHRyaWVzIHRvIGVzdGFibGlzaCBhIFRDUCBjb25uZWN0aW9uLiBJZiBzdWNjZXNzZnVsLCBSb3V0ZSA1MyBzdWJtaXRzIGFuIEhUVFBTIHJlcXVlc3QgYW5kIHdhaXRzIGZvciBhbiBIVFRQIHN0YXR1cyBjb2RlIG9mIDIwMCBvciBncmVhdGVyIGFuZCBsZXNzIHRoYW4gNDAwLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IElmIHlvdSBzcGVjaWZ5IGBIVFRQU2AgZm9yIHRoZSB2YWx1ZSBvZiBgVHlwZWAgLCB0aGUgZW5kcG9pbnQgbXVzdCBzdXBwb3J0IFRMUyB2MS4wIG9yIGxhdGVyLlxuICAgICAgICAgKiAtICpIVFRQX1NUUl9NQVRDSCogOiBSb3V0ZSA1MyB0cmllcyB0byBlc3RhYmxpc2ggYSBUQ1AgY29ubmVjdGlvbi4gSWYgc3VjY2Vzc2Z1bCwgUm91dGUgNTMgc3VibWl0cyBhbiBIVFRQIHJlcXVlc3QgYW5kIHNlYXJjaGVzIHRoZSBmaXJzdCA1LDEyMCBieXRlcyBvZiB0aGUgcmVzcG9uc2UgYm9keSBmb3IgdGhlIHN0cmluZyB0aGF0IHlvdSBzcGVjaWZ5IGluIGBTZWFyY2hTdHJpbmdgIC5cbiAgICAgICAgICogLSAqSFRUUFNfU1RSX01BVENIKiA6IFJvdXRlIDUzIHRyaWVzIHRvIGVzdGFibGlzaCBhIFRDUCBjb25uZWN0aW9uLiBJZiBzdWNjZXNzZnVsLCBSb3V0ZSA1MyBzdWJtaXRzIGFuIGBIVFRQU2AgcmVxdWVzdCBhbmQgc2VhcmNoZXMgdGhlIGZpcnN0IDUsMTIwIGJ5dGVzIG9mIHRoZSByZXNwb25zZSBib2R5IGZvciB0aGUgc3RyaW5nIHRoYXQgeW91IHNwZWNpZnkgaW4gYFNlYXJjaFN0cmluZ2AgLlxuICAgICAgICAgKiAtICpUQ1AqIDogUm91dGUgNTMgdHJpZXMgdG8gZXN0YWJsaXNoIGEgVENQIGNvbm5lY3Rpb24uXG4gICAgICAgICAqIC0gKkNMT1VEV0FUQ0hfTUVUUklDKiA6IFRoZSBoZWFsdGggY2hlY2sgaXMgYXNzb2NpYXRlZCB3aXRoIGEgQ2xvdWRXYXRjaCBhbGFybS4gSWYgdGhlIHN0YXRlIG9mIHRoZSBhbGFybSBpcyBgT0tgICwgdGhlIGhlYWx0aCBjaGVjayBpcyBjb25zaWRlcmVkIGhlYWx0aHkuIElmIHRoZSBzdGF0ZSBpcyBgQUxBUk1gICwgdGhlIGhlYWx0aCBjaGVjayBpcyBjb25zaWRlcmVkIHVuaGVhbHRoeS4gSWYgQ2xvdWRXYXRjaCBkb2Vzbid0IGhhdmUgc3VmZmljaWVudCBkYXRhIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZSBzdGF0ZSBpcyBgT0tgIG9yIGBBTEFSTWAgLCB0aGUgaGVhbHRoIGNoZWNrIHN0YXR1cyBkZXBlbmRzIG9uIHRoZSBzZXR0aW5nIGZvciBgSW5zdWZmaWNpZW50RGF0YUhlYWx0aFN0YXR1c2AgOiBgSGVhbHRoeWAgLCBgVW5oZWFsdGh5YCAsIG9yIGBMYXN0S25vd25TdGF0dXNgIC5cbiAgICAgICAgICogLSAqQ0FMQ1VMQVRFRCogOiBGb3IgaGVhbHRoIGNoZWNrcyB0aGF0IG1vbml0b3IgdGhlIHN0YXR1cyBvZiBvdGhlciBoZWFsdGggY2hlY2tzLCBSb3V0ZSA1MyBhZGRzIHVwIHRoZSBudW1iZXIgb2YgaGVhbHRoIGNoZWNrcyB0aGF0IFJvdXRlIDUzIGhlYWx0aCBjaGVja2VycyBjb25zaWRlciB0byBiZSBoZWFsdGh5IGFuZCBjb21wYXJlcyB0aGF0IG51bWJlciB3aXRoIHRoZSB2YWx1ZSBvZiBgSGVhbHRoVGhyZXNob2xkYCAuXG4gICAgICAgICAqIC0gKlJFQ09WRVJZX0NPTlRST0wqIDogVGhlIGhlYWx0aCBjaGVjayBpcyBhc3NvY2F0ZWQgd2l0aCBhIFJvdXRlNTMgQXBwbGljYXRpb24gUmVjb3ZlcnkgQ29udHJvbGxlciByb3V0aW5nIGNvbnRyb2wuIElmIHRoZSByb3V0aW5nIGNvbnRyb2wgc3RhdGUgaXMgYE9OYCAsIHRoZSBoZWFsdGggY2hlY2sgaXMgY29uc2lkZXJlZCBoZWFsdGh5LiBJZiB0aGUgc3RhdGUgaXMgYE9GRmAgLCB0aGUgaGVhbHRoIGNoZWNrIGlzIGNvbnNpZGVyZWQgdW5oZWFsdGh5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtIb3cgUm91dGUgNTMgRGV0ZXJtaW5lcyBXaGV0aGVyIGFuIEVuZHBvaW50IElzIEhlYWx0aHldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kbnMtZmFpbG92ZXItZGV0ZXJtaW5pbmctaGVhbHRoLW9mLWVuZHBvaW50cy5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2tjb25maWctdHlwZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgdHlwZTogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBIZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBIZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbkhlYWx0aENoZWNrX0hlYWx0aENoZWNrQ29uZmlnUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdhbGFybUlkZW50aWZpZXInLCBDZm5IZWFsdGhDaGVja19BbGFybUlkZW50aWZpZXJQcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5hbGFybUlkZW50aWZpZXIpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NoaWxkSGVhbHRoQ2hlY2tzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5jaGlsZEhlYWx0aENoZWNrcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZW5hYmxlU25pJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5lbmFibGVTbmkpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2ZhaWx1cmVUaHJlc2hvbGQnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMuZmFpbHVyZVRocmVzaG9sZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZnVsbHlRdWFsaWZpZWREb21haW5OYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmZ1bGx5UXVhbGlmaWVkRG9tYWluTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaGVhbHRoVGhyZXNob2xkJywgY2RrLnZhbGlkYXRlTnVtYmVyKShwcm9wZXJ0aWVzLmhlYWx0aFRocmVzaG9sZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaXBBZGRyZXNzJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmlwQWRkcmVzcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaW5zdWZmaWNpZW50RGF0YUhlYWx0aFN0YXR1cycsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5pbnN1ZmZpY2llbnREYXRhSGVhbHRoU3RhdHVzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdpbnZlcnRlZCcsIGNkay52YWxpZGF0ZUJvb2xlYW4pKHByb3BlcnRpZXMuaW52ZXJ0ZWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ21lYXN1cmVMYXRlbmN5JywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5tZWFzdXJlTGF0ZW5jeSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9ydCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5wb3J0KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyZWdpb25zJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5yZWdpb25zKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyZXF1ZXN0SW50ZXJ2YWwnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMucmVxdWVzdEludGVydmFsKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyZXNvdXJjZVBhdGgnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucmVzb3VyY2VQYXRoKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyb3V0aW5nQ29udHJvbEFybicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5yb3V0aW5nQ29udHJvbEFybikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc2VhcmNoU3RyaW5nJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnNlYXJjaFN0cmluZykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndHlwZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy50eXBlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0eXBlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnR5cGUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiSGVhbHRoQ2hlY2tDb25maWdQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6SGVhbHRoQ2hlY2suSGVhbHRoQ2hlY2tDb25maWdgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEhlYWx0aENoZWNrQ29uZmlnUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OkhlYWx0aENoZWNrLkhlYWx0aENoZWNrQ29uZmlnYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmbkhlYWx0aENoZWNrSGVhbHRoQ2hlY2tDb25maWdQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuSGVhbHRoQ2hlY2tfSGVhbHRoQ2hlY2tDb25maWdQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQWxhcm1JZGVudGlmaWVyOiBjZm5IZWFsdGhDaGVja0FsYXJtSWRlbnRpZmllclByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmFsYXJtSWRlbnRpZmllciksXG4gICAgICAgIENoaWxkSGVhbHRoQ2hlY2tzOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5jaGlsZEhlYWx0aENoZWNrcyksXG4gICAgICAgIEVuYWJsZVNOSTogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZW5hYmxlU25pKSxcbiAgICAgICAgRmFpbHVyZVRocmVzaG9sZDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5mYWlsdXJlVGhyZXNob2xkKSxcbiAgICAgICAgRnVsbHlRdWFsaWZpZWREb21haW5OYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmZ1bGx5UXVhbGlmaWVkRG9tYWluTmFtZSksXG4gICAgICAgIEhlYWx0aFRocmVzaG9sZDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5oZWFsdGhUaHJlc2hvbGQpLFxuICAgICAgICBJUEFkZHJlc3M6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaXBBZGRyZXNzKSxcbiAgICAgICAgSW5zdWZmaWNpZW50RGF0YUhlYWx0aFN0YXR1czogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5pbnN1ZmZpY2llbnREYXRhSGVhbHRoU3RhdHVzKSxcbiAgICAgICAgSW52ZXJ0ZWQ6IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmludmVydGVkKSxcbiAgICAgICAgTWVhc3VyZUxhdGVuY3k6IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm1lYXN1cmVMYXRlbmN5KSxcbiAgICAgICAgUG9ydDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wb3J0KSxcbiAgICAgICAgUmVnaW9uczogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMucmVnaW9ucyksXG4gICAgICAgIFJlcXVlc3RJbnRlcnZhbDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5yZXF1ZXN0SW50ZXJ2YWwpLFxuICAgICAgICBSZXNvdXJjZVBhdGg6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucmVzb3VyY2VQYXRoKSxcbiAgICAgICAgUm91dGluZ0NvbnRyb2xBcm46IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucm91dGluZ0NvbnRyb2xBcm4pLFxuICAgICAgICBTZWFyY2hTdHJpbmc6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuc2VhcmNoU3RyaW5nKSxcbiAgICAgICAgVHlwZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy50eXBlKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuSGVhbHRoQ2hlY2tIZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuSGVhbHRoQ2hlY2suSGVhbHRoQ2hlY2tDb25maWdQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja0NvbmZpZ1Byb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnYWxhcm1JZGVudGlmaWVyJywgJ0FsYXJtSWRlbnRpZmllcicsIHByb3BlcnRpZXMuQWxhcm1JZGVudGlmaWVyICE9IG51bGwgPyBDZm5IZWFsdGhDaGVja0FsYXJtSWRlbnRpZmllclByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuQWxhcm1JZGVudGlmaWVyKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjaGlsZEhlYWx0aENoZWNrcycsICdDaGlsZEhlYWx0aENoZWNrcycsIHByb3BlcnRpZXMuQ2hpbGRIZWFsdGhDaGVja3MgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5DaGlsZEhlYWx0aENoZWNrcykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZW5hYmxlU25pJywgJ0VuYWJsZVNOSScsIHByb3BlcnRpZXMuRW5hYmxlU05JICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5FbmFibGVTTkkpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2ZhaWx1cmVUaHJlc2hvbGQnLCAnRmFpbHVyZVRocmVzaG9sZCcsIHByb3BlcnRpZXMuRmFpbHVyZVRocmVzaG9sZCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5GYWlsdXJlVGhyZXNob2xkKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdmdWxseVF1YWxpZmllZERvbWFpbk5hbWUnLCAnRnVsbHlRdWFsaWZpZWREb21haW5OYW1lJywgcHJvcGVydGllcy5GdWxseVF1YWxpZmllZERvbWFpbk5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuRnVsbHlRdWFsaWZpZWREb21haW5OYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdoZWFsdGhUaHJlc2hvbGQnLCAnSGVhbHRoVGhyZXNob2xkJywgcHJvcGVydGllcy5IZWFsdGhUaHJlc2hvbGQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0TnVtYmVyKHByb3BlcnRpZXMuSGVhbHRoVGhyZXNob2xkKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdpcEFkZHJlc3MnLCAnSVBBZGRyZXNzJywgcHJvcGVydGllcy5JUEFkZHJlc3MgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuSVBBZGRyZXNzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdpbnN1ZmZpY2llbnREYXRhSGVhbHRoU3RhdHVzJywgJ0luc3VmZmljaWVudERhdGFIZWFsdGhTdGF0dXMnLCBwcm9wZXJ0aWVzLkluc3VmZmljaWVudERhdGFIZWFsdGhTdGF0dXMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuSW5zdWZmaWNpZW50RGF0YUhlYWx0aFN0YXR1cykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaW52ZXJ0ZWQnLCAnSW52ZXJ0ZWQnLCBwcm9wZXJ0aWVzLkludmVydGVkICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5JbnZlcnRlZCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbWVhc3VyZUxhdGVuY3knLCAnTWVhc3VyZUxhdGVuY3knLCBwcm9wZXJ0aWVzLk1lYXN1cmVMYXRlbmN5ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5NZWFzdXJlTGF0ZW5jeSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncG9ydCcsICdQb3J0JywgcHJvcGVydGllcy5Qb3J0ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLlBvcnQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3JlZ2lvbnMnLCAnUmVnaW9ucycsIHByb3BlcnRpZXMuUmVnaW9ucyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmdBcnJheShwcm9wZXJ0aWVzLlJlZ2lvbnMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3JlcXVlc3RJbnRlcnZhbCcsICdSZXF1ZXN0SW50ZXJ2YWwnLCBwcm9wZXJ0aWVzLlJlcXVlc3RJbnRlcnZhbCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5SZXF1ZXN0SW50ZXJ2YWwpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3Jlc291cmNlUGF0aCcsICdSZXNvdXJjZVBhdGgnLCBwcm9wZXJ0aWVzLlJlc291cmNlUGF0aCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5SZXNvdXJjZVBhdGgpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3JvdXRpbmdDb250cm9sQXJuJywgJ1JvdXRpbmdDb250cm9sQXJuJywgcHJvcGVydGllcy5Sb3V0aW5nQ29udHJvbEFybiAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Sb3V0aW5nQ29udHJvbEFybikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc2VhcmNoU3RyaW5nJywgJ1NlYXJjaFN0cmluZycsIHByb3BlcnRpZXMuU2VhcmNoU3RyaW5nICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlNlYXJjaFN0cmluZykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndHlwZScsICdUeXBlJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5UeXBlKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuSGVhbHRoQ2hlY2sge1xuICAgIC8qKlxuICAgICAqIFRoZSBgSGVhbHRoQ2hlY2tUYWdgIHByb3BlcnR5IGRlc2NyaWJlcyBvbmUga2V5LXZhbHVlIHBhaXIgdGhhdCBpcyBhc3NvY2lhdGVkIHdpdGggYW4gYEFXUzo6Um91dGU1Mzo6SGVhbHRoQ2hlY2tgIHJlc291cmNlLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja3RhZy5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBIZWFsdGhDaGVja1RhZ1Byb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSBvZiBgS2V5YCBkZXBlbmRzIG9uIHRoZSBvcGVyYXRpb24gdGhhdCB5b3Ugd2FudCB0byBwZXJmb3JtOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpBZGQgYSB0YWcgdG8gYSBoZWFsdGggY2hlY2sgb3IgaG9zdGVkIHpvbmUqIDogYEtleWAgaXMgdGhlIG5hbWUgdGhhdCB5b3Ugd2FudCB0byBnaXZlIHRoZSBuZXcgdGFnLlxuICAgICAgICAgKiAtICpFZGl0IGEgdGFnKiA6IGBLZXlgIGlzIHRoZSBuYW1lIG9mIHRoZSB0YWcgdGhhdCB5b3Ugd2FudCB0byBjaGFuZ2UgdGhlIGBWYWx1ZWAgZm9yLlxuICAgICAgICAgKiAtICpEZWxldGUgYSBrZXkqIDogYEtleWAgaXMgdGhlIG5hbWUgb2YgdGhlIHRhZyB5b3Ugd2FudCB0byByZW1vdmUuXG4gICAgICAgICAqIC0gKkdpdmUgYSBuYW1lIHRvIGEgaGVhbHRoIGNoZWNrKiA6IEVkaXQgdGhlIGRlZmF1bHQgYE5hbWVgIHRhZy4gSW4gdGhlIEFtYXpvbiBSb3V0ZSA1MyBjb25zb2xlLCB0aGUgbGlzdCBvZiB5b3VyIGhlYWx0aCBjaGVja3MgaW5jbHVkZXMgYSAqTmFtZSogY29sdW1uIHRoYXQgbGV0cyB5b3Ugc2VlIHRoZSBuYW1lIHRoYXQgeW91J3ZlIGdpdmVuIHRvIGVhY2ggaGVhbHRoIGNoZWNrLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2t0YWcuaHRtbCNjZm4tcm91dGU1My1oZWFsdGhjaGVjay1oZWFsdGhjaGVja3RhZy1rZXlcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGtleTogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHZhbHVlIG9mIGBWYWx1ZWAgZGVwZW5kcyBvbiB0aGUgb3BlcmF0aW9uIHRoYXQgeW91IHdhbnQgdG8gcGVyZm9ybTpcbiAgICAgICAgICpcbiAgICAgICAgICogLSAqQWRkIGEgdGFnIHRvIGEgaGVhbHRoIGNoZWNrIG9yIGhvc3RlZCB6b25lKiA6IGBWYWx1ZWAgaXMgdGhlIHZhbHVlIHRoYXQgeW91IHdhbnQgdG8gZ2l2ZSB0aGUgbmV3IHRhZy5cbiAgICAgICAgICogLSAqRWRpdCBhIHRhZyogOiBgVmFsdWVgIGlzIHRoZSBuZXcgdmFsdWUgdGhhdCB5b3Ugd2FudCB0byBhc3NpZ24gdGhlIHRhZy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhlYWx0aGNoZWNrLWhlYWx0aGNoZWNrdGFnLmh0bWwjY2ZuLXJvdXRlNTMtaGVhbHRoY2hlY2staGVhbHRoY2hlY2t0YWctdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHZhbHVlOiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYEhlYWx0aENoZWNrVGFnUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEhlYWx0aENoZWNrVGFnUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuSGVhbHRoQ2hlY2tfSGVhbHRoQ2hlY2tUYWdQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2tleScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5rZXkpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2tleScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5rZXkpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3ZhbHVlJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnZhbHVlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd2YWx1ZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy52YWx1ZSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJIZWFsdGhDaGVja1RhZ1Byb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpIZWFsdGhDaGVjay5IZWFsdGhDaGVja1RhZ2AgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgSGVhbHRoQ2hlY2tUYWdQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6SGVhbHRoQ2hlY2suSGVhbHRoQ2hlY2tUYWdgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuSGVhbHRoQ2hlY2tIZWFsdGhDaGVja1RhZ1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5IZWFsdGhDaGVja19IZWFsdGhDaGVja1RhZ1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBLZXk6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMua2V5KSxcbiAgICAgICAgVmFsdWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudmFsdWUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5IZWFsdGhDaGVja0hlYWx0aENoZWNrVGFnUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5IZWFsdGhDaGVjay5IZWFsdGhDaGVja1RhZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkhlYWx0aENoZWNrLkhlYWx0aENoZWNrVGFnUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdrZXknLCAnS2V5JywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5LZXkpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3ZhbHVlJywgJ1ZhbHVlJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5WYWx1ZSkpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmbkhvc3RlZFpvbmVgXG4gKlxuICogQHN0cnVjdFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtaG9zdGVkem9uZS5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuSG9zdGVkWm9uZVByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIEEgY29tcGxleCB0eXBlIHRoYXQgY29udGFpbnMgYW4gb3B0aW9uYWwgY29tbWVudC5cbiAgICAgKlxuICAgICAqIElmIHlvdSBkb24ndCB3YW50IHRvIHNwZWNpZnkgYSBjb21tZW50LCBvbWl0IHRoZSBgSG9zdGVkWm9uZUNvbmZpZ2AgYW5kIGBDb21tZW50YCBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtaG9zdGVkem9uZS5odG1sI2Nmbi1yb3V0ZTUzLWhvc3RlZHpvbmUtaG9zdGVkem9uZWNvbmZpZ1xuICAgICAqL1xuICAgIHJlYWRvbmx5IGhvc3RlZFpvbmVDb25maWc/OiBDZm5Ib3N0ZWRab25lLkhvc3RlZFpvbmVDb25maWdQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIEFkZHMsIGVkaXRzLCBvciBkZWxldGVzIHRhZ3MgZm9yIGEgaGVhbHRoIGNoZWNrIG9yIGEgaG9zdGVkIHpvbmUuXG4gICAgICpcbiAgICAgKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgdXNpbmcgdGFncyBmb3IgY29zdCBhbGxvY2F0aW9uLCBzZWUgW1VzaW5nIENvc3QgQWxsb2NhdGlvbiBUYWdzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXdzYWNjb3VudGJpbGxpbmcvbGF0ZXN0L2Fib3V0djIvY29zdC1hbGxvYy10YWdzLmh0bWwpIGluIHRoZSAqQVdTIEJpbGxpbmcgYW5kIENvc3QgTWFuYWdlbWVudCBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWhvc3RlZHpvbmUuaHRtbCNjZm4tcm91dGU1My1ob3N0ZWR6b25lLWhvc3RlZHpvbmV0YWdzXG4gICAgICovXG4gICAgcmVhZG9ubHkgaG9zdGVkWm9uZVRhZ3M/OiBDZm5Ib3N0ZWRab25lLkhvc3RlZFpvbmVUYWdQcm9wZXJ0eVtdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGRvbWFpbi4gU3BlY2lmeSBhIGZ1bGx5IHF1YWxpZmllZCBkb21haW4gbmFtZSwgZm9yIGV4YW1wbGUsICp3d3cuZXhhbXBsZS5jb20qIC4gVGhlIHRyYWlsaW5nIGRvdCBpcyBvcHRpb25hbDsgQW1hem9uIFJvdXRlIDUzIGFzc3VtZXMgdGhhdCB0aGUgZG9tYWluIG5hbWUgaXMgZnVsbHkgcXVhbGlmaWVkLiBUaGlzIG1lYW5zIHRoYXQgUm91dGUgNTMgdHJlYXRzICp3d3cuZXhhbXBsZS5jb20qICh3aXRob3V0IGEgdHJhaWxpbmcgZG90KSBhbmQgKnd3dy5leGFtcGxlLmNvbS4qICh3aXRoIGEgdHJhaWxpbmcgZG90KSBhcyBpZGVudGljYWwuXG4gICAgICpcbiAgICAgKiBJZiB5b3UncmUgY3JlYXRpbmcgYSBwdWJsaWMgaG9zdGVkIHpvbmUsIHRoaXMgaXMgdGhlIG5hbWUgeW91IGhhdmUgcmVnaXN0ZXJlZCB3aXRoIHlvdXIgRE5TIHJlZ2lzdHJhci4gSWYgeW91ciBkb21haW4gbmFtZSBpcyByZWdpc3RlcmVkIHdpdGggYSByZWdpc3RyYXIgb3RoZXIgdGhhbiBSb3V0ZSA1MywgY2hhbmdlIHRoZSBuYW1lIHNlcnZlcnMgZm9yIHlvdXIgZG9tYWluIHRvIHRoZSBzZXQgb2YgYE5hbWVTZXJ2ZXJzYCB0aGF0IGFyZSByZXR1cm5lZCBieSB0aGUgYEZuOjpHZXRBdHRgIGludHJpbnNpYyBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtaG9zdGVkem9uZS5odG1sI2Nmbi1yb3V0ZTUzLWhvc3RlZHpvbmUtbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IG5hbWU/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY29uZmlndXJhdGlvbiBmb3IgRE5TIHF1ZXJ5IGxvZ2dpbmcuIEFmdGVyIHlvdSBjcmVhdGUgYSBxdWVyeSBsb2dnaW5nIGNvbmZpZ3VyYXRpb24sIEFtYXpvbiBSb3V0ZSA1MyBiZWdpbnMgdG8gcHVibGlzaCBsb2cgZGF0YSB0byBhbiBBbWF6b24gQ2xvdWRXYXRjaCBMb2dzIGxvZyBncm91cC5cbiAgICAgKlxuICAgICAqIEROUyBxdWVyeSBsb2dzIGNvbnRhaW4gaW5mb3JtYXRpb24gYWJvdXQgdGhlIHF1ZXJpZXMgdGhhdCBSb3V0ZSA1MyByZWNlaXZlcyBmb3IgYSBzcGVjaWZpZWQgcHVibGljIGhvc3RlZCB6b25lLCBzdWNoIGFzIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIFJvdXRlIDUzIGVkZ2UgbG9jYXRpb24gdGhhdCByZXNwb25kZWQgdG8gdGhlIEROUyBxdWVyeVxuICAgICAqIC0gRG9tYWluIG9yIHN1YmRvbWFpbiB0aGF0IHdhcyByZXF1ZXN0ZWRcbiAgICAgKiAtIEROUyByZWNvcmQgdHlwZSwgc3VjaCBhcyBBIG9yIEFBQUFcbiAgICAgKiAtIEROUyByZXNwb25zZSBjb2RlLCBzdWNoIGFzIGBOb0Vycm9yYCBvciBgU2VydkZhaWxgXG4gICAgICpcbiAgICAgKiAtICoqTG9nIEdyb3VwIGFuZCBSZXNvdXJjZSBQb2xpY3kqKiAtIEJlZm9yZSB5b3UgY3JlYXRlIGEgcXVlcnkgbG9nZ2luZyBjb25maWd1cmF0aW9uLCBwZXJmb3JtIHRoZSBmb2xsb3dpbmcgb3BlcmF0aW9ucy5cbiAgICAgKlxuICAgICAqID4gSWYgeW91IGNyZWF0ZSBhIHF1ZXJ5IGxvZ2dpbmcgY29uZmlndXJhdGlvbiB1c2luZyB0aGUgUm91dGUgNTMgY29uc29sZSwgUm91dGUgNTMgcGVyZm9ybXMgdGhlc2Ugb3BlcmF0aW9ucyBhdXRvbWF0aWNhbGx5LlxuICAgICAqXG4gICAgICogLSBDcmVhdGUgYSBDbG91ZFdhdGNoIExvZ3MgbG9nIGdyb3VwLCBhbmQgbWFrZSBub3RlIG9mIHRoZSBBUk4sIHdoaWNoIHlvdSBzcGVjaWZ5IHdoZW4geW91IGNyZWF0ZSBhIHF1ZXJ5IGxvZ2dpbmcgY29uZmlndXJhdGlvbi4gTm90ZSB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBZb3UgbXVzdCBjcmVhdGUgdGhlIGxvZyBncm91cCBpbiB0aGUgdXMtZWFzdC0xIHJlZ2lvbi5cbiAgICAgKiAtIFlvdSBtdXN0IHVzZSB0aGUgc2FtZSBBV1MgYWNjb3VudCB0byBjcmVhdGUgdGhlIGxvZyBncm91cCBhbmQgdGhlIGhvc3RlZCB6b25lIHRoYXQgeW91IHdhbnQgdG8gY29uZmlndXJlIHF1ZXJ5IGxvZ2dpbmcgZm9yLlxuICAgICAqIC0gV2hlbiB5b3UgY3JlYXRlIGxvZyBncm91cHMgZm9yIHF1ZXJ5IGxvZ2dpbmcsIHdlIHJlY29tbWVuZCB0aGF0IHlvdSB1c2UgYSBjb25zaXN0ZW50IHByZWZpeCwgZm9yIGV4YW1wbGU6XG4gICAgICpcbiAgICAgKiBgL2F3cy9yb3V0ZTUzLyAqaG9zdGVkIHpvbmUgbmFtZSpgXG4gICAgICpcbiAgICAgKiBJbiB0aGUgbmV4dCBzdGVwLCB5b3UnbGwgY3JlYXRlIGEgcmVzb3VyY2UgcG9saWN5LCB3aGljaCBjb250cm9scyBhY2Nlc3MgdG8gb25lIG9yIG1vcmUgbG9nIGdyb3VwcyBhbmQgdGhlIGFzc29jaWF0ZWQgQVdTIHJlc291cmNlcywgc3VjaCBhcyBSb3V0ZSA1MyBob3N0ZWQgem9uZXMuIFRoZXJlJ3MgYSBsaW1pdCBvbiB0aGUgbnVtYmVyIG9mIHJlc291cmNlIHBvbGljaWVzIHRoYXQgeW91IGNhbiBjcmVhdGUsIHNvIHdlIHJlY29tbWVuZCB0aGF0IHlvdSB1c2UgYSBjb25zaXN0ZW50IHByZWZpeCBzbyB5b3UgY2FuIHVzZSB0aGUgc2FtZSByZXNvdXJjZSBwb2xpY3kgZm9yIGFsbCB0aGUgbG9nIGdyb3VwcyB0aGF0IHlvdSBjcmVhdGUgZm9yIHF1ZXJ5IGxvZ2dpbmcuXG4gICAgICogLSBDcmVhdGUgYSBDbG91ZFdhdGNoIExvZ3MgcmVzb3VyY2UgcG9saWN5LCBhbmQgZ2l2ZSBpdCB0aGUgcGVybWlzc2lvbnMgdGhhdCBSb3V0ZSA1MyBuZWVkcyB0byBjcmVhdGUgbG9nIHN0cmVhbXMgYW5kIHRvIHNlbmQgcXVlcnkgbG9ncyB0byBsb2cgc3RyZWFtcy4gRm9yIHRoZSB2YWx1ZSBvZiBgUmVzb3VyY2VgICwgc3BlY2lmeSB0aGUgQVJOIGZvciB0aGUgbG9nIGdyb3VwIHRoYXQgeW91IGNyZWF0ZWQgaW4gdGhlIHByZXZpb3VzIHN0ZXAuIFRvIHVzZSB0aGUgc2FtZSByZXNvdXJjZSBwb2xpY3kgZm9yIGFsbCB0aGUgQ2xvdWRXYXRjaCBMb2dzIGxvZyBncm91cHMgdGhhdCB5b3UgY3JlYXRlZCBmb3IgcXVlcnkgbG9nZ2luZyBjb25maWd1cmF0aW9ucywgcmVwbGFjZSB0aGUgaG9zdGVkIHpvbmUgbmFtZSB3aXRoIGAqYCAsIGZvciBleGFtcGxlOlxuICAgICAqXG4gICAgICogYGFybjphd3M6bG9nczp1cy1lYXN0LTE6MTIzNDEyMzQxMjM0OmxvZy1ncm91cDovYXdzL3JvdXRlNTMvKmBcbiAgICAgKlxuICAgICAqIFRvIGF2b2lkIHRoZSBjb25mdXNlZCBkZXB1dHkgcHJvYmxlbSwgYSBzZWN1cml0eSBpc3N1ZSB3aGVyZSBhbiBlbnRpdHkgd2l0aG91dCBhIHBlcm1pc3Npb24gZm9yIGFuIGFjdGlvbiBjYW4gY29lcmNlIGEgbW9yZS1wcml2aWxlZ2VkIGVudGl0eSB0byBwZXJmb3JtIGl0LCB5b3UgY2FuIG9wdGlvbmFsbHkgbGltaXQgdGhlIHBlcm1pc3Npb25zIHRoYXQgYSBzZXJ2aWNlIGhhcyB0byBhIHJlc291cmNlIGluIGEgcmVzb3VyY2UtYmFzZWQgcG9saWN5IGJ5IHN1cHBseWluZyB0aGUgZm9sbG93aW5nIHZhbHVlczpcbiAgICAgKlxuICAgICAqIC0gRm9yIGBhd3M6U291cmNlQXJuYCAsIHN1cHBseSB0aGUgaG9zdGVkIHpvbmUgQVJOIHVzZWQgaW4gY3JlYXRpbmcgdGhlIHF1ZXJ5IGxvZ2dpbmcgY29uZmlndXJhdGlvbi4gRm9yIGV4YW1wbGUsIGBhd3M6U291cmNlQXJuOiBhcm46YXdzOnJvdXRlNTM6Ojpob3N0ZWR6b25lL2hvc3RlZCB6b25lIElEYCAuXG4gICAgICogLSBGb3IgYGF3czpTb3VyY2VBY2NvdW50YCAsIHN1cHBseSB0aGUgYWNjb3VudCBJRCBmb3IgdGhlIGFjY291bnQgdGhhdCBjcmVhdGVzIHRoZSBxdWVyeSBsb2dnaW5nIGNvbmZpZ3VyYXRpb24uIEZvciBleGFtcGxlLCBgYXdzOlNvdXJjZUFjY291bnQ6MTExMTExMTExMTExYCAuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtUaGUgY29uZnVzZWQgZGVwdXR5IHByb2JsZW1dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9jb25mdXNlZC1kZXB1dHkuaHRtbCkgaW4gdGhlICpBV1MgSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqID4gWW91IGNhbid0IHVzZSB0aGUgQ2xvdWRXYXRjaCBjb25zb2xlIHRvIGNyZWF0ZSBvciBlZGl0IGEgcmVzb3VyY2UgcG9saWN5LiBZb3UgbXVzdCB1c2UgdGhlIENsb3VkV2F0Y2ggQVBJLCBvbmUgb2YgdGhlIEFXUyBTREtzLCBvciB0aGUgQVdTIENMSSAuXG4gICAgICogLSAqKkxvZyBTdHJlYW1zIGFuZCBFZGdlIExvY2F0aW9ucyoqIC0gV2hlbiBSb3V0ZSA1MyBmaW5pc2hlcyBjcmVhdGluZyB0aGUgY29uZmlndXJhdGlvbiBmb3IgRE5TIHF1ZXJ5IGxvZ2dpbmcsIGl0IGRvZXMgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gQ3JlYXRlcyBhIGxvZyBzdHJlYW0gZm9yIGFuIGVkZ2UgbG9jYXRpb24gdGhlIGZpcnN0IHRpbWUgdGhhdCB0aGUgZWRnZSBsb2NhdGlvbiByZXNwb25kcyB0byBETlMgcXVlcmllcyBmb3IgdGhlIHNwZWNpZmllZCBob3N0ZWQgem9uZS4gVGhhdCBsb2cgc3RyZWFtIGlzIHVzZWQgdG8gbG9nIGFsbCBxdWVyaWVzIHRoYXQgUm91dGUgNTMgcmVzcG9uZHMgdG8gZm9yIHRoYXQgZWRnZSBsb2NhdGlvbi5cbiAgICAgKiAtIEJlZ2lucyB0byBzZW5kIHF1ZXJ5IGxvZ3MgdG8gdGhlIGFwcGxpY2FibGUgbG9nIHN0cmVhbS5cbiAgICAgKlxuICAgICAqIFRoZSBuYW1lIG9mIGVhY2ggbG9nIHN0cmVhbSBpcyBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDpcbiAgICAgKlxuICAgICAqIGAqaG9zdGVkIHpvbmUgSUQqIC8gKmVkZ2UgbG9jYXRpb24gY29kZSpgXG4gICAgICpcbiAgICAgKiBUaGUgZWRnZSBsb2NhdGlvbiBjb2RlIGlzIGEgdGhyZWUtbGV0dGVyIGNvZGUgYW5kIGFuIGFyYml0cmFyaWx5IGFzc2lnbmVkIG51bWJlciwgZm9yIGV4YW1wbGUsIERGVzMuIFRoZSB0aHJlZS1sZXR0ZXIgY29kZSB0eXBpY2FsbHkgY29ycmVzcG9uZHMgd2l0aCB0aGUgSW50ZXJuYXRpb25hbCBBaXIgVHJhbnNwb3J0IEFzc29jaWF0aW9uIGFpcnBvcnQgY29kZSBmb3IgYW4gYWlycG9ydCBuZWFyIHRoZSBlZGdlIGxvY2F0aW9uLiAoVGhlc2UgYWJicmV2aWF0aW9ucyBtaWdodCBjaGFuZ2UgaW4gdGhlIGZ1dHVyZS4pIEZvciBhIGxpc3Qgb2YgZWRnZSBsb2NhdGlvbnMsIHNlZSBcIlRoZSBSb3V0ZSA1MyBHbG9iYWwgTmV0d29ya1wiIG9uIHRoZSBbUm91dGUgNTMgUHJvZHVjdCBEZXRhaWxzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcm91dGU1My9kZXRhaWxzLykgcGFnZS5cbiAgICAgKiAtICoqUXVlcmllcyBUaGF0IEFyZSBMb2dnZWQqKiAtIFF1ZXJ5IGxvZ3MgY29udGFpbiBvbmx5IHRoZSBxdWVyaWVzIHRoYXQgRE5TIHJlc29sdmVycyBmb3J3YXJkIHRvIFJvdXRlIDUzLiBJZiBhIEROUyByZXNvbHZlciBoYXMgYWxyZWFkeSBjYWNoZWQgdGhlIHJlc3BvbnNlIHRvIGEgcXVlcnkgKHN1Y2ggYXMgdGhlIElQIGFkZHJlc3MgZm9yIGEgbG9hZCBiYWxhbmNlciBmb3IgZXhhbXBsZS5jb20pLCB0aGUgcmVzb2x2ZXIgd2lsbCBjb250aW51ZSB0byByZXR1cm4gdGhlIGNhY2hlZCByZXNwb25zZS4gSXQgZG9lc24ndCBmb3J3YXJkIGFub3RoZXIgcXVlcnkgdG8gUm91dGUgNTMgdW50aWwgdGhlIFRUTCBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgcmVzb3VyY2UgcmVjb3JkIHNldCBleHBpcmVzLiBEZXBlbmRpbmcgb24gaG93IG1hbnkgRE5TIHF1ZXJpZXMgYXJlIHN1Ym1pdHRlZCBmb3IgYSByZXNvdXJjZSByZWNvcmQgc2V0LCBhbmQgZGVwZW5kaW5nIG9uIHRoZSBUVEwgZm9yIHRoYXQgcmVzb3VyY2UgcmVjb3JkIHNldCwgcXVlcnkgbG9ncyBtaWdodCBjb250YWluIGluZm9ybWF0aW9uIGFib3V0IG9ubHkgb25lIHF1ZXJ5IG91dCBvZiBldmVyeSBzZXZlcmFsIHRob3VzYW5kIHF1ZXJpZXMgdGhhdCBhcmUgc3VibWl0dGVkIHRvIEROUy4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgaG93IEROUyB3b3Jrcywgc2VlIFtSb3V0aW5nIEludGVybmV0IFRyYWZmaWMgdG8gWW91ciBXZWJzaXRlIG9yIFdlYiBBcHBsaWNhdGlvbl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL3dlbGNvbWUtZG5zLXNlcnZpY2UuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICogLSAqKkxvZyBGaWxlIEZvcm1hdCoqIC0gRm9yIGEgbGlzdCBvZiB0aGUgdmFsdWVzIGluIGVhY2ggcXVlcnkgbG9nIGFuZCB0aGUgZm9ybWF0IG9mIGVhY2ggdmFsdWUsIHNlZSBbTG9nZ2luZyBETlMgUXVlcmllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL3F1ZXJ5LWxvZ3MuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICogLSAqKlByaWNpbmcqKiAtIEZvciBpbmZvcm1hdGlvbiBhYm91dCBjaGFyZ2VzIGZvciBxdWVyeSBsb2dzLCBzZWUgW0FtYXpvbiBDbG91ZFdhdGNoIFByaWNpbmddKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbG91ZHdhdGNoL3ByaWNpbmcvKSAuXG4gICAgICogLSAqKkhvdyB0byBTdG9wIExvZ2dpbmcqKiAtIElmIHlvdSB3YW50IFJvdXRlIDUzIHRvIHN0b3Agc2VuZGluZyBxdWVyeSBsb2dzIHRvIENsb3VkV2F0Y2ggTG9ncywgZGVsZXRlIHRoZSBxdWVyeSBsb2dnaW5nIGNvbmZpZ3VyYXRpb24uIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0RlbGV0ZVF1ZXJ5TG9nZ2luZ0NvbmZpZ10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlUXVlcnlMb2dnaW5nQ29uZmlnLmh0bWwpIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtaG9zdGVkem9uZS5odG1sI2Nmbi1yb3V0ZTUzLWhvc3RlZHpvbmUtcXVlcnlsb2dnaW5nY29uZmlnXG4gICAgICovXG4gICAgcmVhZG9ubHkgcXVlcnlMb2dnaW5nQ29uZmlnPzogQ2ZuSG9zdGVkWm9uZS5RdWVyeUxvZ2dpbmdDb25maWdQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqICpQcml2YXRlIGhvc3RlZCB6b25lczoqIEEgY29tcGxleCB0eXBlIHRoYXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIFZQQ3MgdGhhdCBhcmUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgaG9zdGVkIHpvbmUuXG4gICAgICpcbiAgICAgKiA+IEZvciBwdWJsaWMgaG9zdGVkIHpvbmVzLCBvbWl0IGBWUENzYCAsIGBWUENJZGAgLCBhbmQgYFZQQ1JlZ2lvbmAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1ob3N0ZWR6b25lLmh0bWwjY2ZuLXJvdXRlNTMtaG9zdGVkem9uZS12cGNzXG4gICAgICovXG4gICAgcmVhZG9ubHkgdnBjcz86IEFycmF5PENmbkhvc3RlZFpvbmUuVlBDUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHwgY2RrLklSZXNvbHZhYmxlO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbkhvc3RlZFpvbmVQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuSG9zdGVkWm9uZVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbkhvc3RlZFpvbmVQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hvc3RlZFpvbmVDb25maWcnLCBDZm5Ib3N0ZWRab25lX0hvc3RlZFpvbmVDb25maWdQcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5ob3N0ZWRab25lQ29uZmlnKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdob3N0ZWRab25lVGFncycsIGNkay5saXN0VmFsaWRhdG9yKENmbkhvc3RlZFpvbmVfSG9zdGVkWm9uZVRhZ1Byb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy5ob3N0ZWRab25lVGFncykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdxdWVyeUxvZ2dpbmdDb25maWcnLCBDZm5Ib3N0ZWRab25lX1F1ZXJ5TG9nZ2luZ0NvbmZpZ1Byb3BlcnR5VmFsaWRhdG9yKShwcm9wZXJ0aWVzLnF1ZXJ5TG9nZ2luZ0NvbmZpZykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndnBjcycsIGNkay5saXN0VmFsaWRhdG9yKENmbkhvc3RlZFpvbmVfVlBDUHJvcGVydHlWYWxpZGF0b3IpKShwcm9wZXJ0aWVzLnZwY3MpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuSG9zdGVkWm9uZVByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpIb3N0ZWRab25lYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5Ib3N0ZWRab25lUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6Okhvc3RlZFpvbmVgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuSG9zdGVkWm9uZVByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5Ib3N0ZWRab25lUHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEhvc3RlZFpvbmVDb25maWc6IGNmbkhvc3RlZFpvbmVIb3N0ZWRab25lQ29uZmlnUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaG9zdGVkWm9uZUNvbmZpZyksXG4gICAgICAgIEhvc3RlZFpvbmVUYWdzOiBjZGsubGlzdE1hcHBlcihjZm5Ib3N0ZWRab25lSG9zdGVkWm9uZVRhZ1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5ob3N0ZWRab25lVGFncyksXG4gICAgICAgIE5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubmFtZSksXG4gICAgICAgIFF1ZXJ5TG9nZ2luZ0NvbmZpZzogY2ZuSG9zdGVkWm9uZVF1ZXJ5TG9nZ2luZ0NvbmZpZ1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnF1ZXJ5TG9nZ2luZ0NvbmZpZyksXG4gICAgICAgIFZQQ3M6IGNkay5saXN0TWFwcGVyKGNmbkhvc3RlZFpvbmVWUENQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMudnBjcyksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkhvc3RlZFpvbmVQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbkhvc3RlZFpvbmVQcm9wcz4ge1xuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuSG9zdGVkWm9uZVByb3BzPigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaG9zdGVkWm9uZUNvbmZpZycsICdIb3N0ZWRab25lQ29uZmlnJywgcHJvcGVydGllcy5Ib3N0ZWRab25lQ29uZmlnICE9IG51bGwgPyBDZm5Ib3N0ZWRab25lSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuSG9zdGVkWm9uZUNvbmZpZykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaG9zdGVkWm9uZVRhZ3MnLCAnSG9zdGVkWm9uZVRhZ3MnLCBwcm9wZXJ0aWVzLkhvc3RlZFpvbmVUYWdzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmbkhvc3RlZFpvbmVIb3N0ZWRab25lVGFnUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuSG9zdGVkWm9uZVRhZ3MpIDogdW5kZWZpbmVkIGFzIGFueSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCduYW1lJywgJ05hbWUnLCBwcm9wZXJ0aWVzLk5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTmFtZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncXVlcnlMb2dnaW5nQ29uZmlnJywgJ1F1ZXJ5TG9nZ2luZ0NvbmZpZycsIHByb3BlcnRpZXMuUXVlcnlMb2dnaW5nQ29uZmlnICE9IG51bGwgPyBDZm5Ib3N0ZWRab25lUXVlcnlMb2dnaW5nQ29uZmlnUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5RdWVyeUxvZ2dpbmdDb25maWcpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3ZwY3MnLCAnVlBDcycsIHByb3BlcnRpZXMuVlBDcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5Ib3N0ZWRab25lVlBDUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMuVlBDcykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6Um91dGU1Mzo6SG9zdGVkWm9uZWBcbiAqXG4gKiBDcmVhdGVzIGEgbmV3IHB1YmxpYyBvciBwcml2YXRlIGhvc3RlZCB6b25lLiBZb3UgY3JlYXRlIHJlY29yZHMgaW4gYSBwdWJsaWMgaG9zdGVkIHpvbmUgdG8gZGVmaW5lIGhvdyB5b3Ugd2FudCB0byByb3V0ZSB0cmFmZmljIG9uIHRoZSBpbnRlcm5ldCBmb3IgYSBkb21haW4sIHN1Y2ggYXMgZXhhbXBsZS5jb20sIGFuZCBpdHMgc3ViZG9tYWlucyAoYXBleC5leGFtcGxlLmNvbSwgYWNtZS5leGFtcGxlLmNvbSkuIFlvdSBjcmVhdGUgcmVjb3JkcyBpbiBhIHByaXZhdGUgaG9zdGVkIHpvbmUgdG8gZGVmaW5lIGhvdyB5b3Ugd2FudCB0byByb3V0ZSB0cmFmZmljIGZvciBhIGRvbWFpbiBhbmQgaXRzIHN1YmRvbWFpbnMgd2l0aGluIG9uZSBvciBtb3JlIEFtYXpvbiBWaXJ0dWFsIFByaXZhdGUgQ2xvdWRzIChBbWF6b24gVlBDcykuXG4gKlxuICogPiBZb3UgY2FuJ3QgY29udmVydCBhIHB1YmxpYyBob3N0ZWQgem9uZSB0byBhIHByaXZhdGUgaG9zdGVkIHpvbmUgb3IgdmljZSB2ZXJzYS4gSW5zdGVhZCwgeW91IG11c3QgY3JlYXRlIGEgbmV3IGhvc3RlZCB6b25lIHdpdGggdGhlIHNhbWUgbmFtZSBhbmQgY3JlYXRlIG5ldyByZXNvdXJjZSByZWNvcmQgc2V0cy5cbiAqXG4gKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBjaGFyZ2VzIGZvciBob3N0ZWQgem9uZXMsIHNlZSBbQW1hem9uIFJvdXRlwqA1MyBQcmljaW5nXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vcm91dGU1My9wcmljaW5nLykgLlxuICpcbiAqIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAqXG4gKiAtIFlvdSBjYW4ndCBjcmVhdGUgYSBob3N0ZWQgem9uZSBmb3IgYSB0b3AtbGV2ZWwgZG9tYWluIChUTEQpIHN1Y2ggYXMgLmNvbS5cbiAqIC0gSWYgeW91ciBkb21haW4gaXMgcmVnaXN0ZXJlZCB3aXRoIGEgcmVnaXN0cmFyIG90aGVyIHRoYW4gUm91dGXCoDUzLCB5b3UgbXVzdCB1cGRhdGUgdGhlIG5hbWUgc2VydmVycyB3aXRoIHlvdXIgcmVnaXN0cmFyIHRvIG1ha2UgUm91dGUgNTMgdGhlIEROUyBzZXJ2aWNlIGZvciB0aGUgZG9tYWluLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtNaWdyYXRpbmcgRE5TIFNlcnZpY2UgZm9yIGFuIEV4aXN0aW5nIERvbWFpbiB0byBBbWF6b24gUm91dGXCoDUzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvTWlncmF0aW5nRE5TLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICpcbiAqIFdoZW4geW91IHN1Ym1pdCBhIGBDcmVhdGVIb3N0ZWRab25lYCByZXF1ZXN0LCB0aGUgaW5pdGlhbCBzdGF0dXMgb2YgdGhlIGhvc3RlZCB6b25lIGlzIGBQRU5ESU5HYCAuIEZvciBwdWJsaWMgaG9zdGVkIHpvbmVzLCB0aGlzIG1lYW5zIHRoYXQgdGhlIE5TIGFuZCBTT0EgcmVjb3JkcyBhcmUgbm90IHlldCBhdmFpbGFibGUgb24gYWxsIFJvdXRlwqA1MyBETlMgc2VydmVycy4gV2hlbiB0aGUgTlMgYW5kIFNPQSByZWNvcmRzIGFyZSBhdmFpbGFibGUsIHRoZSBzdGF0dXMgb2YgdGhlIHpvbmUgY2hhbmdlcyB0byBgSU5TWU5DYCAuXG4gKlxuICogVGhlIGBDcmVhdGVIb3N0ZWRab25lYCByZXF1ZXN0IHJlcXVpcmVzIHRoZSBjYWxsZXIgdG8gaGF2ZSBhbiBgZWMyOkRlc2NyaWJlVnBjc2AgcGVybWlzc2lvbi5cbiAqXG4gKiA+IFdoZW4gY3JlYXRpbmcgcHJpdmF0ZSBob3N0ZWQgem9uZXMsIHRoZSBBbWF6b24gVlBDIG11c3QgYmVsb25nIHRvIHRoZSBzYW1lIHBhcnRpdGlvbiB3aGVyZSB0aGUgaG9zdGVkIHpvbmUgaXMgY3JlYXRlZC4gQSBwYXJ0aXRpb24gaXMgYSBncm91cCBvZiBBV1MgUmVnaW9ucyAuIEVhY2ggQVdTIGFjY291bnQgaXMgc2NvcGVkIHRvIG9uZSBwYXJ0aXRpb24uXG4gKiA+XG4gKiA+IFRoZSBmb2xsb3dpbmcgYXJlIHRoZSBzdXBwb3J0ZWQgcGFydGl0aW9uczpcbiAqID5cbiAqID4gLSBgYXdzYCAtIEFXUyBSZWdpb25zXG4gKiA+IC0gYGF3cy1jbmAgLSBDaGluYSBSZWdpb25zXG4gKiA+IC0gYGF3cy11cy1nb3ZgIC0gQVdTIEdvdkNsb3VkIChVUykgUmVnaW9uXG4gKiA+XG4gKiA+IEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0FjY2VzcyBNYW5hZ2VtZW50XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2VuZXJhbC9sYXRlc3QvZ3IvYXdzLWFybnMtYW5kLW5hbWVzcGFjZXMuaHRtbCkgaW4gdGhlICpBV1MgR2VuZXJhbCBSZWZlcmVuY2UqIC5cbiAqXG4gKiBAY2xvdWRmb3JtYXRpb25SZXNvdXJjZSBBV1M6OlJvdXRlNTM6Okhvc3RlZFpvbmVcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWhvc3RlZHpvbmUuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuSG9zdGVkWm9uZSBleHRlbmRzIGNkay5DZm5SZXNvdXJjZSBpbXBsZW1lbnRzIGNkay5JSW5zcGVjdGFibGUge1xuICAgIC8qKlxuICAgICAqIFRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIG5hbWUgZm9yIHRoaXMgcmVzb3VyY2UgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBDRk5fUkVTT1VSQ0VfVFlQRV9OQU1FID0gXCJBV1M6OlJvdXRlNTM6Okhvc3RlZFpvbmVcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmbkhvc3RlZFpvbmUge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmbkhvc3RlZFpvbmVQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuSG9zdGVkWm9uZShzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgSUQgdGhhdCBBbWF6b24gUm91dGUgNTMgYXNzaWduZWQgdG8gdGhlIGhvc3RlZCB6b25lIHdoZW4geW91IGNyZWF0ZWQgaXQuXG4gICAgICogQGNsb3VkZm9ybWF0aW9uQXR0cmlidXRlIElkXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJJZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgc2V0IG9mIG5hbWUgc2VydmVycyBmb3IgdGhlIHNwZWNpZmljIGhvc3RlZCB6b25lLiBGb3IgZXhhbXBsZTogYG5zMS5leGFtcGxlLmNvbWAgLlxuICAgICAqXG4gICAgICogVGhpcyBhdHRyaWJ1dGUgaXMgbm90IHN1cHBvcnRlZCBmb3IgcHJpdmF0ZSBob3N0ZWQgem9uZXMuXG4gICAgICogQGNsb3VkZm9ybWF0aW9uQXR0cmlidXRlIE5hbWVTZXJ2ZXJzXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJOYW1lU2VydmVyczogc3RyaW5nW107XG5cbiAgICAvKipcbiAgICAgKiBBIGNvbXBsZXggdHlwZSB0aGF0IGNvbnRhaW5zIGFuIG9wdGlvbmFsIGNvbW1lbnQuXG4gICAgICpcbiAgICAgKiBJZiB5b3UgZG9uJ3Qgd2FudCB0byBzcGVjaWZ5IGEgY29tbWVudCwgb21pdCB0aGUgYEhvc3RlZFpvbmVDb25maWdgIGFuZCBgQ29tbWVudGAgZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWhvc3RlZHpvbmUuaHRtbCNjZm4tcm91dGU1My1ob3N0ZWR6b25lLWhvc3RlZHpvbmVjb25maWdcbiAgICAgKi9cbiAgICBwdWJsaWMgaG9zdGVkWm9uZUNvbmZpZzogQ2ZuSG9zdGVkWm9uZS5Ib3N0ZWRab25lQ29uZmlnUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzLCBlZGl0cywgb3IgZGVsZXRlcyB0YWdzIGZvciBhIGhlYWx0aCBjaGVjayBvciBhIGhvc3RlZCB6b25lLlxuICAgICAqXG4gICAgICogRm9yIGluZm9ybWF0aW9uIGFib3V0IHVzaW5nIHRhZ3MgZm9yIGNvc3QgYWxsb2NhdGlvbiwgc2VlIFtVc2luZyBDb3N0IEFsbG9jYXRpb24gVGFnc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2F3c2FjY291bnRiaWxsaW5nL2xhdGVzdC9hYm91dHYyL2Nvc3QtYWxsb2MtdGFncy5odG1sKSBpbiB0aGUgKkFXUyBCaWxsaW5nIGFuZCBDb3N0IE1hbmFnZW1lbnQgVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1ob3N0ZWR6b25lLmh0bWwjY2ZuLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25ldGFnc1xuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB0YWdzOiBjZGsuVGFnTWFuYWdlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBkb21haW4uIFNwZWNpZnkgYSBmdWxseSBxdWFsaWZpZWQgZG9tYWluIG5hbWUsIGZvciBleGFtcGxlLCAqd3d3LmV4YW1wbGUuY29tKiAuIFRoZSB0cmFpbGluZyBkb3QgaXMgb3B0aW9uYWw7IEFtYXpvbiBSb3V0ZSA1MyBhc3N1bWVzIHRoYXQgdGhlIGRvbWFpbiBuYW1lIGlzIGZ1bGx5IHF1YWxpZmllZC4gVGhpcyBtZWFucyB0aGF0IFJvdXRlIDUzIHRyZWF0cyAqd3d3LmV4YW1wbGUuY29tKiAod2l0aG91dCBhIHRyYWlsaW5nIGRvdCkgYW5kICp3d3cuZXhhbXBsZS5jb20uKiAod2l0aCBhIHRyYWlsaW5nIGRvdCkgYXMgaWRlbnRpY2FsLlxuICAgICAqXG4gICAgICogSWYgeW91J3JlIGNyZWF0aW5nIGEgcHVibGljIGhvc3RlZCB6b25lLCB0aGlzIGlzIHRoZSBuYW1lIHlvdSBoYXZlIHJlZ2lzdGVyZWQgd2l0aCB5b3VyIEROUyByZWdpc3RyYXIuIElmIHlvdXIgZG9tYWluIG5hbWUgaXMgcmVnaXN0ZXJlZCB3aXRoIGEgcmVnaXN0cmFyIG90aGVyIHRoYW4gUm91dGUgNTMsIGNoYW5nZSB0aGUgbmFtZSBzZXJ2ZXJzIGZvciB5b3VyIGRvbWFpbiB0byB0aGUgc2V0IG9mIGBOYW1lU2VydmVyc2AgdGhhdCBhcmUgcmV0dXJuZWQgYnkgdGhlIGBGbjo6R2V0QXR0YCBpbnRyaW5zaWMgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWhvc3RlZHpvbmUuaHRtbCNjZm4tcm91dGU1My1ob3N0ZWR6b25lLW5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNvbmZpZ3VyYXRpb24gZm9yIEROUyBxdWVyeSBsb2dnaW5nLiBBZnRlciB5b3UgY3JlYXRlIGEgcXVlcnkgbG9nZ2luZyBjb25maWd1cmF0aW9uLCBBbWF6b24gUm91dGUgNTMgYmVnaW5zIHRvIHB1Ymxpc2ggbG9nIGRhdGEgdG8gYW4gQW1hem9uIENsb3VkV2F0Y2ggTG9ncyBsb2cgZ3JvdXAuXG4gICAgICpcbiAgICAgKiBETlMgcXVlcnkgbG9ncyBjb250YWluIGluZm9ybWF0aW9uIGFib3V0IHRoZSBxdWVyaWVzIHRoYXQgUm91dGUgNTMgcmVjZWl2ZXMgZm9yIGEgc3BlY2lmaWVkIHB1YmxpYyBob3N0ZWQgem9uZSwgc3VjaCBhcyB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBSb3V0ZSA1MyBlZGdlIGxvY2F0aW9uIHRoYXQgcmVzcG9uZGVkIHRvIHRoZSBETlMgcXVlcnlcbiAgICAgKiAtIERvbWFpbiBvciBzdWJkb21haW4gdGhhdCB3YXMgcmVxdWVzdGVkXG4gICAgICogLSBETlMgcmVjb3JkIHR5cGUsIHN1Y2ggYXMgQSBvciBBQUFBXG4gICAgICogLSBETlMgcmVzcG9uc2UgY29kZSwgc3VjaCBhcyBgTm9FcnJvcmAgb3IgYFNlcnZGYWlsYFxuICAgICAqXG4gICAgICogLSAqKkxvZyBHcm91cCBhbmQgUmVzb3VyY2UgUG9saWN5KiogLSBCZWZvcmUgeW91IGNyZWF0ZSBhIHF1ZXJ5IGxvZ2dpbmcgY29uZmlndXJhdGlvbiwgcGVyZm9ybSB0aGUgZm9sbG93aW5nIG9wZXJhdGlvbnMuXG4gICAgICpcbiAgICAgKiA+IElmIHlvdSBjcmVhdGUgYSBxdWVyeSBsb2dnaW5nIGNvbmZpZ3VyYXRpb24gdXNpbmcgdGhlIFJvdXRlIDUzIGNvbnNvbGUsIFJvdXRlIDUzIHBlcmZvcm1zIHRoZXNlIG9wZXJhdGlvbnMgYXV0b21hdGljYWxseS5cbiAgICAgKlxuICAgICAqIC0gQ3JlYXRlIGEgQ2xvdWRXYXRjaCBMb2dzIGxvZyBncm91cCwgYW5kIG1ha2Ugbm90ZSBvZiB0aGUgQVJOLCB3aGljaCB5b3Ugc3BlY2lmeSB3aGVuIHlvdSBjcmVhdGUgYSBxdWVyeSBsb2dnaW5nIGNvbmZpZ3VyYXRpb24uIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gWW91IG11c3QgY3JlYXRlIHRoZSBsb2cgZ3JvdXAgaW4gdGhlIHVzLWVhc3QtMSByZWdpb24uXG4gICAgICogLSBZb3UgbXVzdCB1c2UgdGhlIHNhbWUgQVdTIGFjY291bnQgdG8gY3JlYXRlIHRoZSBsb2cgZ3JvdXAgYW5kIHRoZSBob3N0ZWQgem9uZSB0aGF0IHlvdSB3YW50IHRvIGNvbmZpZ3VyZSBxdWVyeSBsb2dnaW5nIGZvci5cbiAgICAgKiAtIFdoZW4geW91IGNyZWF0ZSBsb2cgZ3JvdXBzIGZvciBxdWVyeSBsb2dnaW5nLCB3ZSByZWNvbW1lbmQgdGhhdCB5b3UgdXNlIGEgY29uc2lzdGVudCBwcmVmaXgsIGZvciBleGFtcGxlOlxuICAgICAqXG4gICAgICogYC9hd3Mvcm91dGU1My8gKmhvc3RlZCB6b25lIG5hbWUqYFxuICAgICAqXG4gICAgICogSW4gdGhlIG5leHQgc3RlcCwgeW91J2xsIGNyZWF0ZSBhIHJlc291cmNlIHBvbGljeSwgd2hpY2ggY29udHJvbHMgYWNjZXNzIHRvIG9uZSBvciBtb3JlIGxvZyBncm91cHMgYW5kIHRoZSBhc3NvY2lhdGVkIEFXUyByZXNvdXJjZXMsIHN1Y2ggYXMgUm91dGUgNTMgaG9zdGVkIHpvbmVzLiBUaGVyZSdzIGEgbGltaXQgb24gdGhlIG51bWJlciBvZiByZXNvdXJjZSBwb2xpY2llcyB0aGF0IHlvdSBjYW4gY3JlYXRlLCBzbyB3ZSByZWNvbW1lbmQgdGhhdCB5b3UgdXNlIGEgY29uc2lzdGVudCBwcmVmaXggc28geW91IGNhbiB1c2UgdGhlIHNhbWUgcmVzb3VyY2UgcG9saWN5IGZvciBhbGwgdGhlIGxvZyBncm91cHMgdGhhdCB5b3UgY3JlYXRlIGZvciBxdWVyeSBsb2dnaW5nLlxuICAgICAqIC0gQ3JlYXRlIGEgQ2xvdWRXYXRjaCBMb2dzIHJlc291cmNlIHBvbGljeSwgYW5kIGdpdmUgaXQgdGhlIHBlcm1pc3Npb25zIHRoYXQgUm91dGUgNTMgbmVlZHMgdG8gY3JlYXRlIGxvZyBzdHJlYW1zIGFuZCB0byBzZW5kIHF1ZXJ5IGxvZ3MgdG8gbG9nIHN0cmVhbXMuIEZvciB0aGUgdmFsdWUgb2YgYFJlc291cmNlYCAsIHNwZWNpZnkgdGhlIEFSTiBmb3IgdGhlIGxvZyBncm91cCB0aGF0IHlvdSBjcmVhdGVkIGluIHRoZSBwcmV2aW91cyBzdGVwLiBUbyB1c2UgdGhlIHNhbWUgcmVzb3VyY2UgcG9saWN5IGZvciBhbGwgdGhlIENsb3VkV2F0Y2ggTG9ncyBsb2cgZ3JvdXBzIHRoYXQgeW91IGNyZWF0ZWQgZm9yIHF1ZXJ5IGxvZ2dpbmcgY29uZmlndXJhdGlvbnMsIHJlcGxhY2UgdGhlIGhvc3RlZCB6b25lIG5hbWUgd2l0aCBgKmAgLCBmb3IgZXhhbXBsZTpcbiAgICAgKlxuICAgICAqIGBhcm46YXdzOmxvZ3M6dXMtZWFzdC0xOjEyMzQxMjM0MTIzNDpsb2ctZ3JvdXA6L2F3cy9yb3V0ZTUzLypgXG4gICAgICpcbiAgICAgKiBUbyBhdm9pZCB0aGUgY29uZnVzZWQgZGVwdXR5IHByb2JsZW0sIGEgc2VjdXJpdHkgaXNzdWUgd2hlcmUgYW4gZW50aXR5IHdpdGhvdXQgYSBwZXJtaXNzaW9uIGZvciBhbiBhY3Rpb24gY2FuIGNvZXJjZSBhIG1vcmUtcHJpdmlsZWdlZCBlbnRpdHkgdG8gcGVyZm9ybSBpdCwgeW91IGNhbiBvcHRpb25hbGx5IGxpbWl0IHRoZSBwZXJtaXNzaW9ucyB0aGF0IGEgc2VydmljZSBoYXMgdG8gYSByZXNvdXJjZSBpbiBhIHJlc291cmNlLWJhc2VkIHBvbGljeSBieSBzdXBwbHlpbmcgdGhlIGZvbGxvd2luZyB2YWx1ZXM6XG4gICAgICpcbiAgICAgKiAtIEZvciBgYXdzOlNvdXJjZUFybmAgLCBzdXBwbHkgdGhlIGhvc3RlZCB6b25lIEFSTiB1c2VkIGluIGNyZWF0aW5nIHRoZSBxdWVyeSBsb2dnaW5nIGNvbmZpZ3VyYXRpb24uIEZvciBleGFtcGxlLCBgYXdzOlNvdXJjZUFybjogYXJuOmF3czpyb3V0ZTUzOjo6aG9zdGVkem9uZS9ob3N0ZWQgem9uZSBJRGAgLlxuICAgICAqIC0gRm9yIGBhd3M6U291cmNlQWNjb3VudGAgLCBzdXBwbHkgdGhlIGFjY291bnQgSUQgZm9yIHRoZSBhY2NvdW50IHRoYXQgY3JlYXRlcyB0aGUgcXVlcnkgbG9nZ2luZyBjb25maWd1cmF0aW9uLiBGb3IgZXhhbXBsZSwgYGF3czpTb3VyY2VBY2NvdW50OjExMTExMTExMTExMWAgLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbVGhlIGNvbmZ1c2VkIGRlcHV0eSBwcm9ibGVtXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvY29uZnVzZWQtZGVwdXR5Lmh0bWwpIGluIHRoZSAqQVdTIElBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiA+IFlvdSBjYW4ndCB1c2UgdGhlIENsb3VkV2F0Y2ggY29uc29sZSB0byBjcmVhdGUgb3IgZWRpdCBhIHJlc291cmNlIHBvbGljeS4gWW91IG11c3QgdXNlIHRoZSBDbG91ZFdhdGNoIEFQSSwgb25lIG9mIHRoZSBBV1MgU0RLcywgb3IgdGhlIEFXUyBDTEkgLlxuICAgICAqIC0gKipMb2cgU3RyZWFtcyBhbmQgRWRnZSBMb2NhdGlvbnMqKiAtIFdoZW4gUm91dGUgNTMgZmluaXNoZXMgY3JlYXRpbmcgdGhlIGNvbmZpZ3VyYXRpb24gZm9yIEROUyBxdWVyeSBsb2dnaW5nLCBpdCBkb2VzIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIENyZWF0ZXMgYSBsb2cgc3RyZWFtIGZvciBhbiBlZGdlIGxvY2F0aW9uIHRoZSBmaXJzdCB0aW1lIHRoYXQgdGhlIGVkZ2UgbG9jYXRpb24gcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgZm9yIHRoZSBzcGVjaWZpZWQgaG9zdGVkIHpvbmUuIFRoYXQgbG9nIHN0cmVhbSBpcyB1c2VkIHRvIGxvZyBhbGwgcXVlcmllcyB0aGF0IFJvdXRlIDUzIHJlc3BvbmRzIHRvIGZvciB0aGF0IGVkZ2UgbG9jYXRpb24uXG4gICAgICogLSBCZWdpbnMgdG8gc2VuZCBxdWVyeSBsb2dzIHRvIHRoZSBhcHBsaWNhYmxlIGxvZyBzdHJlYW0uXG4gICAgICpcbiAgICAgKiBUaGUgbmFtZSBvZiBlYWNoIGxvZyBzdHJlYW0gaXMgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6XG4gICAgICpcbiAgICAgKiBgKmhvc3RlZCB6b25lIElEKiAvICplZGdlIGxvY2F0aW9uIGNvZGUqYFxuICAgICAqXG4gICAgICogVGhlIGVkZ2UgbG9jYXRpb24gY29kZSBpcyBhIHRocmVlLWxldHRlciBjb2RlIGFuZCBhbiBhcmJpdHJhcmlseSBhc3NpZ25lZCBudW1iZXIsIGZvciBleGFtcGxlLCBERlczLiBUaGUgdGhyZWUtbGV0dGVyIGNvZGUgdHlwaWNhbGx5IGNvcnJlc3BvbmRzIHdpdGggdGhlIEludGVybmF0aW9uYWwgQWlyIFRyYW5zcG9ydCBBc3NvY2lhdGlvbiBhaXJwb3J0IGNvZGUgZm9yIGFuIGFpcnBvcnQgbmVhciB0aGUgZWRnZSBsb2NhdGlvbi4gKFRoZXNlIGFiYnJldmlhdGlvbnMgbWlnaHQgY2hhbmdlIGluIHRoZSBmdXR1cmUuKSBGb3IgYSBsaXN0IG9mIGVkZ2UgbG9jYXRpb25zLCBzZWUgXCJUaGUgUm91dGUgNTMgR2xvYmFsIE5ldHdvcmtcIiBvbiB0aGUgW1JvdXRlIDUzIFByb2R1Y3QgRGV0YWlsc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3JvdXRlNTMvZGV0YWlscy8pIHBhZ2UuXG4gICAgICogLSAqKlF1ZXJpZXMgVGhhdCBBcmUgTG9nZ2VkKiogLSBRdWVyeSBsb2dzIGNvbnRhaW4gb25seSB0aGUgcXVlcmllcyB0aGF0IEROUyByZXNvbHZlcnMgZm9yd2FyZCB0byBSb3V0ZSA1My4gSWYgYSBETlMgcmVzb2x2ZXIgaGFzIGFscmVhZHkgY2FjaGVkIHRoZSByZXNwb25zZSB0byBhIHF1ZXJ5IChzdWNoIGFzIHRoZSBJUCBhZGRyZXNzIGZvciBhIGxvYWQgYmFsYW5jZXIgZm9yIGV4YW1wbGUuY29tKSwgdGhlIHJlc29sdmVyIHdpbGwgY29udGludWUgdG8gcmV0dXJuIHRoZSBjYWNoZWQgcmVzcG9uc2UuIEl0IGRvZXNuJ3QgZm9yd2FyZCBhbm90aGVyIHF1ZXJ5IHRvIFJvdXRlIDUzIHVudGlsIHRoZSBUVEwgZm9yIHRoZSBjb3JyZXNwb25kaW5nIHJlc291cmNlIHJlY29yZCBzZXQgZXhwaXJlcy4gRGVwZW5kaW5nIG9uIGhvdyBtYW55IEROUyBxdWVyaWVzIGFyZSBzdWJtaXR0ZWQgZm9yIGEgcmVzb3VyY2UgcmVjb3JkIHNldCwgYW5kIGRlcGVuZGluZyBvbiB0aGUgVFRMIGZvciB0aGF0IHJlc291cmNlIHJlY29yZCBzZXQsIHF1ZXJ5IGxvZ3MgbWlnaHQgY29udGFpbiBpbmZvcm1hdGlvbiBhYm91dCBvbmx5IG9uZSBxdWVyeSBvdXQgb2YgZXZlcnkgc2V2ZXJhbCB0aG91c2FuZCBxdWVyaWVzIHRoYXQgYXJlIHN1Ym1pdHRlZCB0byBETlMuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGhvdyBETlMgd29ya3MsIHNlZSBbUm91dGluZyBJbnRlcm5ldCBUcmFmZmljIHRvIFlvdXIgV2Vic2l0ZSBvciBXZWIgQXBwbGljYXRpb25dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS93ZWxjb21lLWRucy1zZXJ2aWNlLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqIC0gKipMb2cgRmlsZSBGb3JtYXQqKiAtIEZvciBhIGxpc3Qgb2YgdGhlIHZhbHVlcyBpbiBlYWNoIHF1ZXJ5IGxvZyBhbmQgdGhlIGZvcm1hdCBvZiBlYWNoIHZhbHVlLCBzZWUgW0xvZ2dpbmcgRE5TIFF1ZXJpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9xdWVyeS1sb2dzLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqIC0gKipQcmljaW5nKiogLSBGb3IgaW5mb3JtYXRpb24gYWJvdXQgY2hhcmdlcyBmb3IgcXVlcnkgbG9ncywgc2VlIFtBbWF6b24gQ2xvdWRXYXRjaCBQcmljaW5nXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xvdWR3YXRjaC9wcmljaW5nLykgLlxuICAgICAqIC0gKipIb3cgdG8gU3RvcCBMb2dnaW5nKiogLSBJZiB5b3Ugd2FudCBSb3V0ZSA1MyB0byBzdG9wIHNlbmRpbmcgcXVlcnkgbG9ncyB0byBDbG91ZFdhdGNoIExvZ3MsIGRlbGV0ZSB0aGUgcXVlcnkgbG9nZ2luZyBjb25maWd1cmF0aW9uLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtEZWxldGVRdWVyeUxvZ2dpbmdDb25maWddKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVF1ZXJ5TG9nZ2luZ0NvbmZpZy5odG1sKSAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWhvc3RlZHpvbmUuaHRtbCNjZm4tcm91dGU1My1ob3N0ZWR6b25lLXF1ZXJ5bG9nZ2luZ2NvbmZpZ1xuICAgICAqL1xuICAgIHB1YmxpYyBxdWVyeUxvZ2dpbmdDb25maWc6IENmbkhvc3RlZFpvbmUuUXVlcnlMb2dnaW5nQ29uZmlnUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiAqUHJpdmF0ZSBob3N0ZWQgem9uZXM6KiBBIGNvbXBsZXggdHlwZSB0aGF0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBWUENzIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGhvc3RlZCB6b25lLlxuICAgICAqXG4gICAgICogPiBGb3IgcHVibGljIGhvc3RlZCB6b25lcywgb21pdCBgVlBDc2AgLCBgVlBDSWRgICwgYW5kIGBWUENSZWdpb25gIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtaG9zdGVkem9uZS5odG1sI2Nmbi1yb3V0ZTUzLWhvc3RlZHpvbmUtdnBjc1xuICAgICAqL1xuICAgIHB1YmxpYyB2cGNzOiBBcnJheTxDZm5Ib3N0ZWRab25lLlZQQ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpSb3V0ZTUzOjpIb3N0ZWRab25lYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5Ib3N0ZWRab25lUHJvcHMgPSB7fSkge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuSG9zdGVkWm9uZS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgdGhpcy5hdHRySWQgPSBjZGsuVG9rZW4uYXNTdHJpbmcodGhpcy5nZXRBdHQoJ0lkJykpO1xuICAgICAgICB0aGlzLmF0dHJOYW1lU2VydmVycyA9IGNkay5Ub2tlbi5hc0xpc3QodGhpcy5nZXRBdHQoJ05hbWVTZXJ2ZXJzJykpO1xuXG4gICAgICAgIHRoaXMuaG9zdGVkWm9uZUNvbmZpZyA9IHByb3BzLmhvc3RlZFpvbmVDb25maWc7XG4gICAgICAgIHRoaXMudGFncyA9IG5ldyBjZGsuVGFnTWFuYWdlcihjZGsuVGFnVHlwZS5TVEFOREFSRCwgXCJBV1M6OlJvdXRlNTM6Okhvc3RlZFpvbmVcIiwgcHJvcHMuaG9zdGVkWm9uZVRhZ3MsIHsgdGFnUHJvcGVydHlOYW1lOiAnaG9zdGVkWm9uZVRhZ3MnIH0pO1xuICAgICAgICB0aGlzLm5hbWUgPSBwcm9wcy5uYW1lO1xuICAgICAgICB0aGlzLnF1ZXJ5TG9nZ2luZ0NvbmZpZyA9IHByb3BzLnF1ZXJ5TG9nZ2luZ0NvbmZpZztcbiAgICAgICAgdGhpcy52cGNzID0gcHJvcHMudnBjcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmbkhvc3RlZFpvbmUuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGhvc3RlZFpvbmVDb25maWc6IHRoaXMuaG9zdGVkWm9uZUNvbmZpZyxcbiAgICAgICAgICAgIGhvc3RlZFpvbmVUYWdzOiB0aGlzLnRhZ3MucmVuZGVyVGFncygpLFxuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgcXVlcnlMb2dnaW5nQ29uZmlnOiB0aGlzLnF1ZXJ5TG9nZ2luZ0NvbmZpZyxcbiAgICAgICAgICAgIHZwY3M6IHRoaXMudnBjcyxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5Ib3N0ZWRab25lUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuSG9zdGVkWm9uZSB7XG4gICAgLyoqXG4gICAgICogQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBhbiBvcHRpb25hbCBjb21tZW50IGFib3V0IHlvdXIgaG9zdGVkIHpvbmUuIElmIHlvdSBkb24ndCB3YW50IHRvIHNwZWNpZnkgYSBjb21tZW50LCBvbWl0IGJvdGggdGhlIGBIb3N0ZWRab25lQ29uZmlnYCBhbmQgYENvbW1lbnRgIGVsZW1lbnRzLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1ob3N0ZWR6b25lLWhvc3RlZHpvbmVjb25maWcuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFueSBjb21tZW50cyB0aGF0IHlvdSB3YW50IHRvIGluY2x1ZGUgYWJvdXQgdGhlIGhvc3RlZCB6b25lLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25lY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25lY29uZmlnLWNvbW1lbnRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNvbW1lbnQ/OiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYEhvc3RlZFpvbmVDb25maWdQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbkhvc3RlZFpvbmVfSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY29tbWVudCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jb21tZW50KSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkhvc3RlZFpvbmVDb25maWdQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6SG9zdGVkWm9uZS5Ib3N0ZWRab25lQ29uZmlnYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBIb3N0ZWRab25lQ29uZmlnUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6Okhvc3RlZFpvbmUuSG9zdGVkWm9uZUNvbmZpZ2AgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5Ib3N0ZWRab25lSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5Ib3N0ZWRab25lX0hvc3RlZFpvbmVDb25maWdQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQ29tbWVudDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jb21tZW50KSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuSG9zdGVkWm9uZUhvc3RlZFpvbmVDb25maWdQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbkhvc3RlZFpvbmUuSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkhvc3RlZFpvbmUuSG9zdGVkWm9uZUNvbmZpZ1Byb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY29tbWVudCcsICdDb21tZW50JywgcHJvcGVydGllcy5Db21tZW50ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNvbW1lbnQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5Ib3N0ZWRab25lIHtcbiAgICAvKipcbiAgICAgKiBBIGNvbXBsZXggdHlwZSB0aGF0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGEgdGFnIHRoYXQgeW91IHdhbnQgdG8gYWRkIG9yIGVkaXQgZm9yIHRoZSBzcGVjaWZpZWQgaGVhbHRoIGNoZWNrIG9yIGhvc3RlZCB6b25lLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1ob3N0ZWR6b25lLWhvc3RlZHpvbmV0YWcuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgSG9zdGVkWm9uZVRhZ1Byb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSBvZiBgS2V5YCBkZXBlbmRzIG9uIHRoZSBvcGVyYXRpb24gdGhhdCB5b3Ugd2FudCB0byBwZXJmb3JtOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpBZGQgYSB0YWcgdG8gYSBoZWFsdGggY2hlY2sgb3IgaG9zdGVkIHpvbmUqIDogYEtleWAgaXMgdGhlIG5hbWUgdGhhdCB5b3Ugd2FudCB0byBnaXZlIHRoZSBuZXcgdGFnLlxuICAgICAgICAgKiAtICpFZGl0IGEgdGFnKiA6IGBLZXlgIGlzIHRoZSBuYW1lIG9mIHRoZSB0YWcgdGhhdCB5b3Ugd2FudCB0byBjaGFuZ2UgdGhlIGBWYWx1ZWAgZm9yLlxuICAgICAgICAgKiAtICpEZWxldGUgYSBrZXkqIDogYEtleWAgaXMgdGhlIG5hbWUgb2YgdGhlIHRhZyB5b3Ugd2FudCB0byByZW1vdmUuXG4gICAgICAgICAqIC0gKkdpdmUgYSBuYW1lIHRvIGEgaGVhbHRoIGNoZWNrKiA6IEVkaXQgdGhlIGRlZmF1bHQgYE5hbWVgIHRhZy4gSW4gdGhlIEFtYXpvbiBSb3V0ZSA1MyBjb25zb2xlLCB0aGUgbGlzdCBvZiB5b3VyIGhlYWx0aCBjaGVja3MgaW5jbHVkZXMgYSAqTmFtZSogY29sdW1uIHRoYXQgbGV0cyB5b3Ugc2VlIHRoZSBuYW1lIHRoYXQgeW91J3ZlIGdpdmVuIHRvIGVhY2ggaGVhbHRoIGNoZWNrLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25ldGFnLmh0bWwjY2ZuLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25ldGFnLWtleVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkga2V5OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdmFsdWUgb2YgYFZhbHVlYCBkZXBlbmRzIG9uIHRoZSBvcGVyYXRpb24gdGhhdCB5b3Ugd2FudCB0byBwZXJmb3JtOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpBZGQgYSB0YWcgdG8gYSBoZWFsdGggY2hlY2sgb3IgaG9zdGVkIHpvbmUqIDogYFZhbHVlYCBpcyB0aGUgdmFsdWUgdGhhdCB5b3Ugd2FudCB0byBnaXZlIHRoZSBuZXcgdGFnLlxuICAgICAgICAgKiAtICpFZGl0IGEgdGFnKiA6IGBWYWx1ZWAgaXMgdGhlIG5ldyB2YWx1ZSB0aGF0IHlvdSB3YW50IHRvIGFzc2lnbiB0aGUgdGFnLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25ldGFnLmh0bWwjY2ZuLXJvdXRlNTMtaG9zdGVkem9uZS1ob3N0ZWR6b25ldGFnLXZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB2YWx1ZTogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBIb3N0ZWRab25lVGFnUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEhvc3RlZFpvbmVUYWdQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5Ib3N0ZWRab25lX0hvc3RlZFpvbmVUYWdQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2tleScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5rZXkpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2tleScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5rZXkpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3ZhbHVlJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnZhbHVlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd2YWx1ZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy52YWx1ZSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJIb3N0ZWRab25lVGFnUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6Okhvc3RlZFpvbmUuSG9zdGVkWm9uZVRhZ2AgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgSG9zdGVkWm9uZVRhZ1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpIb3N0ZWRab25lLkhvc3RlZFpvbmVUYWdgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuSG9zdGVkWm9uZUhvc3RlZFpvbmVUYWdQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuSG9zdGVkWm9uZV9Ib3N0ZWRab25lVGFnUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEtleTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5rZXkpLFxuICAgICAgICBWYWx1ZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy52YWx1ZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkhvc3RlZFpvbmVIb3N0ZWRab25lVGFnUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5Ib3N0ZWRab25lLkhvc3RlZFpvbmVUYWdQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5Ib3N0ZWRab25lLkhvc3RlZFpvbmVUYWdQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2tleScsICdLZXknLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLktleSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndmFsdWUnLCAnVmFsdWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlZhbHVlKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuSG9zdGVkWm9uZSB7XG4gICAgLyoqXG4gICAgICogQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBhIGNvbmZpZ3VyYXRpb24gZm9yIEROUyBxdWVyeSBsb2dnaW5nLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1ob3N0ZWR6b25lLXF1ZXJ5bG9nZ2luZ2NvbmZpZy5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBRdWVyeUxvZ2dpbmdDb25maWdQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIENsb3VkV2F0Y2ggTG9ncyBsb2cgZ3JvdXAgdGhhdCBBbWF6b24gUm91dGUgNTMgaXMgcHVibGlzaGluZyBsb2dzIHRvLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaG9zdGVkem9uZS1xdWVyeWxvZ2dpbmdjb25maWcuaHRtbCNjZm4tcm91dGU1My1ob3N0ZWR6b25lLXF1ZXJ5bG9nZ2luZ2NvbmZpZy1jbG91ZHdhdGNobG9nc2xvZ2dyb3VwYXJuXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBjbG91ZFdhdGNoTG9nc0xvZ0dyb3VwQXJuOiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYFF1ZXJ5TG9nZ2luZ0NvbmZpZ1Byb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBRdWVyeUxvZ2dpbmdDb25maWdQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5Ib3N0ZWRab25lX1F1ZXJ5TG9nZ2luZ0NvbmZpZ1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2xvdWRXYXRjaExvZ3NMb2dHcm91cEFybicsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5jbG91ZFdhdGNoTG9nc0xvZ0dyb3VwQXJuKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjbG91ZFdhdGNoTG9nc0xvZ0dyb3VwQXJuJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmNsb3VkV2F0Y2hMb2dzTG9nR3JvdXBBcm4pKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiUXVlcnlMb2dnaW5nQ29uZmlnUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6Okhvc3RlZFpvbmUuUXVlcnlMb2dnaW5nQ29uZmlnYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBRdWVyeUxvZ2dpbmdDb25maWdQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6SG9zdGVkWm9uZS5RdWVyeUxvZ2dpbmdDb25maWdgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuSG9zdGVkWm9uZVF1ZXJ5TG9nZ2luZ0NvbmZpZ1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5Ib3N0ZWRab25lX1F1ZXJ5TG9nZ2luZ0NvbmZpZ1Byb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBDbG91ZFdhdGNoTG9nc0xvZ0dyb3VwQXJuOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNsb3VkV2F0Y2hMb2dzTG9nR3JvdXBBcm4pLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5Ib3N0ZWRab25lUXVlcnlMb2dnaW5nQ29uZmlnUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5Ib3N0ZWRab25lLlF1ZXJ5TG9nZ2luZ0NvbmZpZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkhvc3RlZFpvbmUuUXVlcnlMb2dnaW5nQ29uZmlnUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjbG91ZFdhdGNoTG9nc0xvZ0dyb3VwQXJuJywgJ0Nsb3VkV2F0Y2hMb2dzTG9nR3JvdXBBcm4nLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNsb3VkV2F0Y2hMb2dzTG9nR3JvdXBBcm4pKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5Ib3N0ZWRab25lIHtcbiAgICAvKipcbiAgICAgKiAqUHJpdmF0ZSBob3N0ZWQgem9uZXMgb25seToqIEEgY29tcGxleCB0eXBlIHRoYXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgYW4gQW1hem9uIFZQQy4gUm91dGUgNTMgUmVzb2x2ZXIgdXNlcyB0aGUgcmVjb3JkcyBpbiB0aGUgcHJpdmF0ZSBob3N0ZWQgem9uZSB0byByb3V0ZSB0cmFmZmljIGluIHRoYXQgVlBDLlxuICAgICAqXG4gICAgICogPiBGb3IgcHVibGljIGhvc3RlZCB6b25lcywgb21pdCBgVlBDc2AgLCBgVlBDSWRgICwgYW5kIGBWUENSZWdpb25gIC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaG9zdGVkem9uZS12cGMuaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgVlBDUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogKlByaXZhdGUgaG9zdGVkIHpvbmVzIG9ubHk6KiBUaGUgSUQgb2YgYW4gQW1hem9uIFZQQy5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBGb3IgcHVibGljIGhvc3RlZCB6b25lcywgb21pdCBgVlBDc2AgLCBgVlBDSWRgICwgYW5kIGBWUENSZWdpb25gIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWhvc3RlZHpvbmUtdnBjLmh0bWwjY2ZuLXJvdXRlNTMtaG9zdGVkem9uZS12cGMtdnBjaWRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHZwY0lkOiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiAqUHJpdmF0ZSBob3N0ZWQgem9uZXMgb25seToqIFRoZSByZWdpb24gdGhhdCBhbiBBbWF6b24gVlBDIHdhcyBjcmVhdGVkIGluLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IEZvciBwdWJsaWMgaG9zdGVkIHpvbmVzLCBvbWl0IGBWUENzYCAsIGBWUENJZGAgLCBhbmQgYFZQQ1JlZ2lvbmAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtaG9zdGVkem9uZS12cGMuaHRtbCNjZm4tcm91dGU1My1ob3N0ZWR6b25lLXZwYy12cGNyZWdpb25cbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHZwY1JlZ2lvbjogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBWUENQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgVlBDUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuSG9zdGVkWm9uZV9WUENQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3ZwY0lkJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnZwY0lkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd2cGNJZCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy52cGNJZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndnBjUmVnaW9uJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnZwY1JlZ2lvbikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndnBjUmVnaW9uJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnZwY1JlZ2lvbikpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJWUENQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6SG9zdGVkWm9uZS5WUENgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFZQQ1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpIb3N0ZWRab25lLlZQQ2AgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5Ib3N0ZWRab25lVlBDUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkhvc3RlZFpvbmVfVlBDUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFZQQ0lkOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnZwY0lkKSxcbiAgICAgICAgVlBDUmVnaW9uOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnZwY1JlZ2lvbiksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkhvc3RlZFpvbmVWUENQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbkhvc3RlZFpvbmUuVlBDUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuSG9zdGVkWm9uZS5WUENQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3ZwY0lkJywgJ1ZQQ0lkJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5WUENJZCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndnBjUmVnaW9uJywgJ1ZQQ1JlZ2lvbicsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVlBDUmVnaW9uKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuS2V5U2lnbmluZ0tleWBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1rZXlzaWduaW5na2V5Lmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5LZXlTaWduaW5nS2V5UHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogVGhlIHVuaXF1ZSBzdHJpbmcgKElEKSB0aGF0IGlzIHVzZWQgdG8gaWRlbnRpZnkgYSBob3N0ZWQgem9uZS4gRm9yIGV4YW1wbGU6IGBaMDAwMDExMTFBMUFCQ2FhQUJDMTFgIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMta2V5c2lnbmluZ2tleS5odG1sI2Nmbi1yb3V0ZTUzLWtleXNpZ25pbmdrZXktaG9zdGVkem9uZWlkXG4gICAgICovXG4gICAgcmVhZG9ubHkgaG9zdGVkWm9uZUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQW1hem9uIHJlc291cmNlIG5hbWUgKEFSTikgZm9yIGEgY3VzdG9tZXIgbWFuYWdlZCBjdXN0b21lciBtYXN0ZXIga2V5IChDTUspIGluIEFXUyBLZXkgTWFuYWdlbWVudCBTZXJ2aWNlICggQVdTIEtNUyApLiBUaGUgYEtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuYCBtdXN0IGJlIHVuaXF1ZSBmb3IgZWFjaCBrZXktc2lnbmluZyBrZXkgKEtTSykgaW4gYSBzaW5nbGUgaG9zdGVkIHpvbmUuIEZvciBleGFtcGxlOiBgYXJuOmF3czprbXM6dXMtZWFzdC0xOjExMTEyMjIyMzMzMzprZXkvMTExYTIyMjItYTExYi0xYWIxLTJhYjItMWFiMjFhMmIzYTExMWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1rZXlzaWduaW5na2V5Lmh0bWwjY2ZuLXJvdXRlNTMta2V5c2lnbmluZ2tleS1rZXltYW5hZ2VtZW50c2VydmljZWFyblxuICAgICAqL1xuICAgIHJlYWRvbmx5IGtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBIHN0cmluZyB1c2VkIHRvIGlkZW50aWZ5IGEga2V5LXNpZ25pbmcga2V5IChLU0spLiBgTmFtZWAgY2FuIGluY2x1ZGUgbnVtYmVycywgbGV0dGVycywgYW5kIHVuZGVyc2NvcmVzIChfKS4gYE5hbWVgIG11c3QgYmUgdW5pcXVlIGZvciBlYWNoIGtleS1zaWduaW5nIGtleSBpbiB0aGUgc2FtZSBob3N0ZWQgem9uZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMta2V5c2lnbmluZ2tleS5odG1sI2Nmbi1yb3V0ZTUzLWtleXNpZ25pbmdrZXktbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgc3RyaW5nIHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBrZXktc2lnbmluZyBrZXkgKEtTSykgc3RhdHVzLlxuICAgICAqXG4gICAgICogU3RhdHVzIGNhbiBoYXZlIG9uZSBvZiB0aGUgZm9sbG93aW5nIHZhbHVlczpcbiAgICAgKlxuICAgICAqIC0gKipBQ1RJVkUqKiAtIFRoZSBLU0sgaXMgYmVpbmcgdXNlZCBmb3Igc2lnbmluZy5cbiAgICAgKiAtICoqSU5BQ1RJVkUqKiAtIFRoZSBLU0sgaXMgbm90IGJlaW5nIHVzZWQgZm9yIHNpZ25pbmcuXG4gICAgICogLSAqKkRFTEVUSU5HKiogLSBUaGUgS1NLIGlzIGluIHRoZSBwcm9jZXNzIG9mIGJlaW5nIGRlbGV0ZWQuXG4gICAgICogLSAqKkFDVElPTl9ORUVERUQqKiAtIFRoZXJlIGlzIGEgcHJvYmxlbSB3aXRoIHRoZSBLU0sgdGhhdCByZXF1aXJlcyB5b3UgdG8gdGFrZSBhY3Rpb24gdG8gcmVzb2x2ZS4gRm9yIGV4YW1wbGUsIHRoZSBjdXN0b21lciBtYW5hZ2VkIGtleSBtaWdodCBoYXZlIGJlZW4gZGVsZXRlZCwgb3IgdGhlIHBlcm1pc3Npb25zIGZvciB0aGUgY3VzdG9tZXIgbWFuYWdlZCBrZXkgbWlnaHQgaGF2ZSBiZWVuIGNoYW5nZWQuXG4gICAgICogLSAqKklOVEVSTkFMX0ZBSUxVUkUqKiAtIFRoZXJlIHdhcyBhbiBlcnJvciBkdXJpbmcgYSByZXF1ZXN0LiBCZWZvcmUgeW91IGNhbiBjb250aW51ZSB0byB3b3JrIHdpdGggRE5TU0VDIHNpZ25pbmcsIGluY2x1ZGluZyBhY3Rpb25zIHRoYXQgaW52b2x2ZSB0aGlzIEtTSywgeW91IG11c3QgY29ycmVjdCB0aGUgcHJvYmxlbS4gRm9yIGV4YW1wbGUsIHlvdSBtYXkgbmVlZCB0byBhY3RpdmF0ZSBvciBkZWFjdGl2YXRlIHRoZSBLU0suXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWtleXNpZ25pbmdrZXkuaHRtbCNjZm4tcm91dGU1My1rZXlzaWduaW5na2V5LXN0YXR1c1xuICAgICAqL1xuICAgIHJlYWRvbmx5IHN0YXR1czogc3RyaW5nO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbktleVNpZ25pbmdLZXlQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuS2V5U2lnbmluZ0tleVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbktleVNpZ25pbmdLZXlQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hvc3RlZFpvbmVJZCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5ob3N0ZWRab25lSWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hvc3RlZFpvbmVJZCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5ob3N0ZWRab25lSWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2tleU1hbmFnZW1lbnRTZXJ2aWNlQXJuJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdrZXlNYW5hZ2VtZW50U2VydmljZUFybicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5rZXlNYW5hZ2VtZW50U2VydmljZUFybikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLm5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3N0YXR1cycsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5zdGF0dXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3N0YXR1cycsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5zdGF0dXMpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuS2V5U2lnbmluZ0tleVByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpLZXlTaWduaW5nS2V5YCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5LZXlTaWduaW5nS2V5UHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OktleVNpZ25pbmdLZXlgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuS2V5U2lnbmluZ0tleVByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5LZXlTaWduaW5nS2V5UHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIEhvc3RlZFpvbmVJZDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5ob3N0ZWRab25lSWQpLFxuICAgICAgICBLZXlNYW5hZ2VtZW50U2VydmljZUFybjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5rZXlNYW5hZ2VtZW50U2VydmljZUFybiksXG4gICAgICAgIE5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubmFtZSksXG4gICAgICAgIFN0YXR1czogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zdGF0dXMpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5LZXlTaWduaW5nS2V5UHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5LZXlTaWduaW5nS2V5UHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbktleVNpZ25pbmdLZXlQcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hvc3RlZFpvbmVJZCcsICdIb3N0ZWRab25lSWQnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkhvc3RlZFpvbmVJZCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgna2V5TWFuYWdlbWVudFNlcnZpY2VBcm4nLCAnS2V5TWFuYWdlbWVudFNlcnZpY2VBcm4nLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLktleU1hbmFnZW1lbnRTZXJ2aWNlQXJuKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCduYW1lJywgJ05hbWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLk5hbWUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3N0YXR1cycsICdTdGF0dXMnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlN0YXR1cykpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6Um91dGU1Mzo6S2V5U2lnbmluZ0tleWBcbiAqXG4gKiBUaGUgYEFXUzo6Um91dGU1Mzo6S2V5U2lnbmluZ0tleWAgcmVzb3VyY2UgY3JlYXRlcyBhIG5ldyBrZXktc2lnbmluZyBrZXkgKEtTSykgaW4gYSBob3N0ZWQgem9uZS4gVGhlIGhvc3RlZCB6b25lIElEIGlzIHBhc3NlZCBhcyBhIHBhcmFtZXRlciBpbiB0aGUgS1NLIHByb3BlcnRpZXMuIFlvdSBjYW4gc3BlY2lmeSB0aGUgcHJvcGVydGllcyBvZiB0aGlzIEtTSyB1c2luZyB0aGUgYE5hbWVgICwgYFN0YXR1c2AgLCBhbmQgYEtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuYCBwcm9wZXJ0aWVzIG9mIHRoZSByZXNvdXJjZS5cbiAqXG4gKiBAY2xvdWRmb3JtYXRpb25SZXNvdXJjZSBBV1M6OlJvdXRlNTM6OktleVNpZ25pbmdLZXlcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWtleXNpZ25pbmdrZXkuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuS2V5U2lnbmluZ0tleSBleHRlbmRzIGNkay5DZm5SZXNvdXJjZSBpbXBsZW1lbnRzIGNkay5JSW5zcGVjdGFibGUge1xuICAgIC8qKlxuICAgICAqIFRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIG5hbWUgZm9yIHRoaXMgcmVzb3VyY2UgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBDRk5fUkVTT1VSQ0VfVFlQRV9OQU1FID0gXCJBV1M6OlJvdXRlNTM6OktleVNpZ25pbmdLZXlcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmbktleVNpZ25pbmdLZXkge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmbktleVNpZ25pbmdLZXlQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuS2V5U2lnbmluZ0tleShzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdW5pcXVlIHN0cmluZyAoSUQpIHRoYXQgaXMgdXNlZCB0byBpZGVudGlmeSBhIGhvc3RlZCB6b25lLiBGb3IgZXhhbXBsZTogYFowMDAwMTExMUExQUJDYWFBQkMxMWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1rZXlzaWduaW5na2V5Lmh0bWwjY2ZuLXJvdXRlNTMta2V5c2lnbmluZ2tleS1ob3N0ZWR6b25laWRcbiAgICAgKi9cbiAgICBwdWJsaWMgaG9zdGVkWm9uZUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQW1hem9uIHJlc291cmNlIG5hbWUgKEFSTikgZm9yIGEgY3VzdG9tZXIgbWFuYWdlZCBjdXN0b21lciBtYXN0ZXIga2V5IChDTUspIGluIEFXUyBLZXkgTWFuYWdlbWVudCBTZXJ2aWNlICggQVdTIEtNUyApLiBUaGUgYEtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuYCBtdXN0IGJlIHVuaXF1ZSBmb3IgZWFjaCBrZXktc2lnbmluZyBrZXkgKEtTSykgaW4gYSBzaW5nbGUgaG9zdGVkIHpvbmUuIEZvciBleGFtcGxlOiBgYXJuOmF3czprbXM6dXMtZWFzdC0xOjExMTEyMjIyMzMzMzprZXkvMTExYTIyMjItYTExYi0xYWIxLTJhYjItMWFiMjFhMmIzYTExMWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1rZXlzaWduaW5na2V5Lmh0bWwjY2ZuLXJvdXRlNTMta2V5c2lnbmluZ2tleS1rZXltYW5hZ2VtZW50c2VydmljZWFyblxuICAgICAqL1xuICAgIHB1YmxpYyBrZXlNYW5hZ2VtZW50U2VydmljZUFybjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBzdHJpbmcgdXNlZCB0byBpZGVudGlmeSBhIGtleS1zaWduaW5nIGtleSAoS1NLKS4gYE5hbWVgIGNhbiBpbmNsdWRlIG51bWJlcnMsIGxldHRlcnMsIGFuZCB1bmRlcnNjb3JlcyAoXykuIGBOYW1lYCBtdXN0IGJlIHVuaXF1ZSBmb3IgZWFjaCBrZXktc2lnbmluZyBrZXkgaW4gdGhlIHNhbWUgaG9zdGVkIHpvbmUuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLWtleXNpZ25pbmdrZXkuaHRtbCNjZm4tcm91dGU1My1rZXlzaWduaW5na2V5LW5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBzdHJpbmcgdGhhdCByZXByZXNlbnRzIHRoZSBjdXJyZW50IGtleS1zaWduaW5nIGtleSAoS1NLKSBzdGF0dXMuXG4gICAgICpcbiAgICAgKiBTdGF0dXMgY2FuIGhhdmUgb25lIG9mIHRoZSBmb2xsb3dpbmcgdmFsdWVzOlxuICAgICAqXG4gICAgICogLSAqKkFDVElWRSoqIC0gVGhlIEtTSyBpcyBiZWluZyB1c2VkIGZvciBzaWduaW5nLlxuICAgICAqIC0gKipJTkFDVElWRSoqIC0gVGhlIEtTSyBpcyBub3QgYmVpbmcgdXNlZCBmb3Igc2lnbmluZy5cbiAgICAgKiAtICoqREVMRVRJTkcqKiAtIFRoZSBLU0sgaXMgaW4gdGhlIHByb2Nlc3Mgb2YgYmVpbmcgZGVsZXRlZC5cbiAgICAgKiAtICoqQUNUSU9OX05FRURFRCoqIC0gVGhlcmUgaXMgYSBwcm9ibGVtIHdpdGggdGhlIEtTSyB0aGF0IHJlcXVpcmVzIHlvdSB0byB0YWtlIGFjdGlvbiB0byByZXNvbHZlLiBGb3IgZXhhbXBsZSwgdGhlIGN1c3RvbWVyIG1hbmFnZWQga2V5IG1pZ2h0IGhhdmUgYmVlbiBkZWxldGVkLCBvciB0aGUgcGVybWlzc2lvbnMgZm9yIHRoZSBjdXN0b21lciBtYW5hZ2VkIGtleSBtaWdodCBoYXZlIGJlZW4gY2hhbmdlZC5cbiAgICAgKiAtICoqSU5URVJOQUxfRkFJTFVSRSoqIC0gVGhlcmUgd2FzIGFuIGVycm9yIGR1cmluZyBhIHJlcXVlc3QuIEJlZm9yZSB5b3UgY2FuIGNvbnRpbnVlIHRvIHdvcmsgd2l0aCBETlNTRUMgc2lnbmluZywgaW5jbHVkaW5nIGFjdGlvbnMgdGhhdCBpbnZvbHZlIHRoaXMgS1NLLCB5b3UgbXVzdCBjb3JyZWN0IHRoZSBwcm9ibGVtLiBGb3IgZXhhbXBsZSwgeW91IG1heSBuZWVkIHRvIGFjdGl2YXRlIG9yIGRlYWN0aXZhdGUgdGhlIEtTSy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMta2V5c2lnbmluZ2tleS5odG1sI2Nmbi1yb3V0ZTUzLWtleXNpZ25pbmdrZXktc3RhdHVzXG4gICAgICovXG4gICAgcHVibGljIHN0YXR1czogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGBBV1M6OlJvdXRlNTM6OktleVNpZ25pbmdLZXlgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmbktleVNpZ25pbmdLZXlQcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuS2V5U2lnbmluZ0tleS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ2hvc3RlZFpvbmVJZCcsIHRoaXMpO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAna2V5TWFuYWdlbWVudFNlcnZpY2VBcm4nLCB0aGlzKTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ25hbWUnLCB0aGlzKTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ3N0YXR1cycsIHRoaXMpO1xuXG4gICAgICAgIHRoaXMuaG9zdGVkWm9uZUlkID0gcHJvcHMuaG9zdGVkWm9uZUlkO1xuICAgICAgICB0aGlzLmtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuID0gcHJvcHMua2V5TWFuYWdlbWVudFNlcnZpY2VBcm47XG4gICAgICAgIHRoaXMubmFtZSA9IHByb3BzLm5hbWU7XG4gICAgICAgIHRoaXMuc3RhdHVzID0gcHJvcHMuc3RhdHVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuS2V5U2lnbmluZ0tleS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaG9zdGVkWm9uZUlkOiB0aGlzLmhvc3RlZFpvbmVJZCxcbiAgICAgICAgICAgIGtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuOiB0aGlzLmtleU1hbmFnZW1lbnRTZXJ2aWNlQXJuLFxuICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgc3RhdHVzOiB0aGlzLnN0YXR1cyxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5LZXlTaWduaW5nS2V5UHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuUmVjb3JkU2V0YFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5SZWNvcmRTZXRQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYENoYW5nZVJlc291cmNlUmVjb3JkU2V0c2AgcmVxdWVzdHMsIHRoZSBuYW1lIG9mIHRoZSByZWNvcmQgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUsIHVwZGF0ZSwgb3IgZGVsZXRlLiBGb3IgYExpc3RSZXNvdXJjZVJlY29yZFNldHNgIHJlc3BvbnNlcywgdGhlIG5hbWUgb2YgYSByZWNvcmQgaW4gdGhlIHNwZWNpZmllZCBob3N0ZWQgem9uZS5cbiAgICAgKlxuICAgICAqICpDaGFuZ2VSZXNvdXJjZVJlY29yZFNldHMgT25seSpcbiAgICAgKlxuICAgICAqIEVudGVyIGEgZnVsbHkgcXVhbGlmaWVkIGRvbWFpbiBuYW1lLCBmb3IgZXhhbXBsZSwgYHd3dy5leGFtcGxlLmNvbWAgLiBZb3UgY2FuIG9wdGlvbmFsbHkgaW5jbHVkZSBhIHRyYWlsaW5nIGRvdC4gSWYgeW91IG9taXQgdGhlIHRyYWlsaW5nIGRvdCwgQW1hem9uIFJvdXRlIDUzIGFzc3VtZXMgdGhhdCB0aGUgZG9tYWluIG5hbWUgdGhhdCB5b3Ugc3BlY2lmeSBpcyBmdWxseSBxdWFsaWZpZWQuIFRoaXMgbWVhbnMgdGhhdCBSb3V0ZSA1MyB0cmVhdHMgYHd3dy5leGFtcGxlLmNvbWAgKHdpdGhvdXQgYSB0cmFpbGluZyBkb3QpIGFuZCBgd3d3LmV4YW1wbGUuY29tLmAgKHdpdGggYSB0cmFpbGluZyBkb3QpIGFzIGlkZW50aWNhbC5cbiAgICAgKlxuICAgICAqIEZvciBpbmZvcm1hdGlvbiBhYm91dCBob3cgdG8gc3BlY2lmeSBjaGFyYWN0ZXJzIG90aGVyIHRoYW4gYGEtemAgLCBgMC05YCAsIGFuZCBgLWAgKGh5cGhlbikgYW5kIGhvdyB0byBzcGVjaWZ5IGludGVybmF0aW9uYWxpemVkIGRvbWFpbiBuYW1lcywgc2VlIFtETlMgRG9tYWluIE5hbWUgRm9ybWF0XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvRG9tYWluTmFtZUZvcm1hdC5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4gdXNlIHRoZSBhc3RlcmlzayAoKikgd2lsZGNhcmQgdG8gcmVwbGFjZSB0aGUgbGVmdG1vc3QgbGFiZWwgaW4gYSBkb21haW4gbmFtZSwgZm9yIGV4YW1wbGUsIGAqLmV4YW1wbGUuY29tYCAuIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gVGhlICogbXVzdCByZXBsYWNlIHRoZSBlbnRpcmUgbGFiZWwuIEZvciBleGFtcGxlLCB5b3UgY2FuJ3Qgc3BlY2lmeSBgKnByb2QuZXhhbXBsZS5jb21gIG9yIGBwcm9kKi5leGFtcGxlLmNvbWAgLlxuICAgICAqIC0gVGhlICogY2FuJ3QgcmVwbGFjZSBhbnkgb2YgdGhlIG1pZGRsZSBsYWJlbHMsIGZvciBleGFtcGxlLCBtYXJrZXRpbmcuKi5leGFtcGxlLmNvbS5cbiAgICAgKiAtIElmIHlvdSBpbmNsdWRlICogaW4gYW55IHBvc2l0aW9uIG90aGVyIHRoYW4gdGhlIGxlZnRtb3N0IGxhYmVsIGluIGEgZG9tYWluIG5hbWUsIEROUyB0cmVhdHMgaXQgYXMgYW4gKiBjaGFyYWN0ZXIgKEFTQ0lJIDQyKSwgbm90IGFzIGEgd2lsZGNhcmQuXG4gICAgICpcbiAgICAgKiA+IFlvdSBjYW4ndCB1c2UgdGhlICogd2lsZGNhcmQgZm9yIHJlc291cmNlIHJlY29yZHMgc2V0cyB0aGF0IGhhdmUgYSB0eXBlIG9mIE5TLlxuICAgICAqXG4gICAgICogWW91IGNhbiB1c2UgdGhlICogd2lsZGNhcmQgYXMgdGhlIGxlZnRtb3N0IGxhYmVsIGluIGEgZG9tYWluIG5hbWUsIGZvciBleGFtcGxlLCBgKi5leGFtcGxlLmNvbWAgLiBZb3UgY2FuJ3QgdXNlIGFuICogZm9yIG9uZSBvZiB0aGUgbWlkZGxlIGxhYmVscywgZm9yIGV4YW1wbGUsIGBtYXJrZXRpbmcuKi5leGFtcGxlLmNvbWAgLiBJbiBhZGRpdGlvbiwgdGhlICogbXVzdCByZXBsYWNlIHRoZSBlbnRpcmUgbGFiZWw7IGZvciBleGFtcGxlLCB5b3UgY2FuJ3Qgc3BlY2lmeSBgcHJvZCouZXhhbXBsZS5jb21gIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBETlMgcmVjb3JkIHR5cGUuIEZvciBpbmZvcm1hdGlvbiBhYm91dCBkaWZmZXJlbnQgcmVjb3JkIHR5cGVzIGFuZCBob3cgZGF0YSBpcyBlbmNvZGVkIGZvciB0aGVtLCBzZWUgW1N1cHBvcnRlZCBETlMgUmVzb3VyY2UgUmVjb3JkIFR5cGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvUmVzb3VyY2VSZWNvcmRUeXBlcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFZhbGlkIHZhbHVlcyBmb3IgYmFzaWMgcmVzb3VyY2UgcmVjb3JkIHNldHM6IGBBYCB8IGBBQUFBYCB8IGBDQUFgIHwgYENOQU1FYCB8IGBEU2AgfCBgTVhgIHwgYE5BUFRSYCB8IGBOU2AgfCBgUFRSYCB8IGBTT0FgIHwgYFNQRmAgfCBgU1JWYCB8IGBUWFRgXG4gICAgICpcbiAgICAgKiBWYWx1ZXMgZm9yIHdlaWdodGVkLCBsYXRlbmN5LCBnZW9sb2NhdGlvbiwgYW5kIGZhaWxvdmVyIHJlc291cmNlIHJlY29yZCBzZXRzOiBgQWAgfCBgQUFBQWAgfCBgQ0FBYCB8IGBDTkFNRWAgfCBgTVhgIHwgYE5BUFRSYCB8IGBQVFJgIHwgYFNQRmAgfCBgU1JWYCB8IGBUWFRgIC4gV2hlbiBjcmVhdGluZyBhIGdyb3VwIG9mIHdlaWdodGVkLCBsYXRlbmN5LCBnZW9sb2NhdGlvbiwgb3IgZmFpbG92ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHMsIHNwZWNpZnkgdGhlIHNhbWUgdmFsdWUgZm9yIGFsbCBvZiB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gdGhlIGdyb3VwLlxuICAgICAqXG4gICAgICogVmFsaWQgdmFsdWVzIGZvciBtdWx0aXZhbHVlIGFuc3dlciByZXNvdXJjZSByZWNvcmQgc2V0czogYEFgIHwgYEFBQUFgIHwgYE1YYCB8IGBOQVBUUmAgfCBgUFRSYCB8IGBTUEZgIHwgYFNSVmAgfCBgVFhUYFxuICAgICAqXG4gICAgICogPiBTUEYgcmVjb3JkcyB3ZXJlIGZvcm1lcmx5IHVzZWQgdG8gdmVyaWZ5IHRoZSBpZGVudGl0eSBvZiB0aGUgc2VuZGVyIG9mIGVtYWlsIG1lc3NhZ2VzLiBIb3dldmVyLCB3ZSBubyBsb25nZXIgcmVjb21tZW5kIHRoYXQgeW91IGNyZWF0ZSByZXNvdXJjZSByZWNvcmQgc2V0cyBmb3Igd2hpY2ggdGhlIHZhbHVlIG9mIGBUeXBlYCBpcyBgU1BGYCAuIFJGQyA3MjA4LCAqU2VuZGVyIFBvbGljeSBGcmFtZXdvcmsgKFNQRikgZm9yIEF1dGhvcml6aW5nIFVzZSBvZiBEb21haW5zIGluIEVtYWlsLCBWZXJzaW9uIDEqICwgaGFzIGJlZW4gdXBkYXRlZCB0byBzYXksIFwiLi4uW0lddHMgZXhpc3RlbmNlIGFuZCBtZWNoYW5pc20gZGVmaW5lZCBpbiBbUkZDNDQwOF0gaGF2ZSBsZWQgdG8gc29tZSBpbnRlcm9wZXJhYmlsaXR5IGlzc3Vlcy4gQWNjb3JkaW5nbHksIGl0cyB1c2UgaXMgbm8gbG9uZ2VyIGFwcHJvcHJpYXRlIGZvciBTUEYgdmVyc2lvbiAxOyBpbXBsZW1lbnRhdGlvbnMgYXJlIG5vdCB0byB1c2UgaXQuXCIgSW4gUkZDIDcyMDgsIHNlZSBzZWN0aW9uIDE0LjEsIFtUaGUgU1BGIEROUyBSZWNvcmQgVHlwZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzcyMDgjc2VjdGlvbi0xNC4xKSAuXG4gICAgICpcbiAgICAgKiBWYWx1ZXMgZm9yIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzOlxuICAgICAqXG4gICAgICogLSAqQW1hem9uIEFQSSBHYXRld2F5IGN1c3RvbSByZWdpb25hbCBBUElzIGFuZCBlZGdlLW9wdGltaXplZCBBUElzOiogYEFgXG4gICAgICogLSAqQ2xvdWRGcm9udCBkaXN0cmlidXRpb25zOiogYEFgXG4gICAgICpcbiAgICAgKiBJZiBJUHY2IGlzIGVuYWJsZWQgZm9yIHRoZSBkaXN0cmlidXRpb24sIGNyZWF0ZSB0d28gcmVzb3VyY2UgcmVjb3JkIHNldHMgdG8gcm91dGUgdHJhZmZpYyB0byB5b3VyIGRpc3RyaWJ1dGlvbiwgb25lIHdpdGggYSB2YWx1ZSBvZiBgQWAgYW5kIG9uZSB3aXRoIGEgdmFsdWUgb2YgYEFBQUFgIC5cbiAgICAgKiAtICpBbWF6b24gQVBJIEdhdGV3YXkgZW52aXJvbm1lbnQgdGhhdCBoYXMgYSByZWdpb25hbGl6ZWQgc3ViZG9tYWluKiA6IGBBYFxuICAgICAqIC0gKkVMQiBsb2FkIGJhbGFuY2VyczoqIGBBYCB8IGBBQUFBYFxuICAgICAqIC0gKkFtYXpvbiBTMyBidWNrZXRzOiogYEFgXG4gICAgICogLSAqQW1hem9uIFZpcnR1YWwgUHJpdmF0ZSBDbG91ZCBpbnRlcmZhY2UgVlBDIGVuZHBvaW50cyogYEFgXG4gICAgICogLSAqQW5vdGhlciByZXNvdXJjZSByZWNvcmQgc2V0IGluIHRoaXMgaG9zdGVkIHpvbmU6KiBTcGVjaWZ5IHRoZSB0eXBlIG9mIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0IHRoYXQgeW91J3JlIGNyZWF0aW5nIHRoZSBhbGlhcyBmb3IuIEFsbCB2YWx1ZXMgYXJlIHN1cHBvcnRlZCBleGNlcHQgYE5TYCBhbmQgYFNPQWAgLlxuICAgICAqXG4gICAgICogPiBJZiB5b3UncmUgY3JlYXRpbmcgYW4gYWxpYXMgcmVjb3JkIHRoYXQgaGFzIHRoZSBzYW1lIG5hbWUgYXMgdGhlIGhvc3RlZCB6b25lIChrbm93biBhcyB0aGUgem9uZSBhcGV4KSwgeW91IGNhbid0IHJvdXRlIHRyYWZmaWMgdG8gYSByZWNvcmQgZm9yIHdoaWNoIHRoZSB2YWx1ZSBvZiBgVHlwZWAgaXMgYENOQU1FYCAuIFRoaXMgaXMgYmVjYXVzZSB0aGUgYWxpYXMgcmVjb3JkIG11c3QgaGF2ZSB0aGUgc2FtZSB0eXBlIGFzIHRoZSByZWNvcmQgeW91J3JlIHJvdXRpbmcgdHJhZmZpYyB0bywgYW5kIGNyZWF0aW5nIGEgQ05BTUUgcmVjb3JkIGZvciB0aGUgem9uZSBhcGV4IGlzbid0IHN1cHBvcnRlZCBldmVuIGZvciBhbiBhbGlhcyByZWNvcmQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LXR5cGVcbiAgICAgKi9cbiAgICByZWFkb25seSB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiAqQWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgb25seToqIEluZm9ybWF0aW9uIGFib3V0IHRoZSBBV1MgcmVzb3VyY2UsIHN1Y2ggYXMgYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiBvciBhbiBBbWF6b24gUzMgYnVja2V0LCB0aGF0IHlvdSB3YW50IHRvIHJvdXRlIHRyYWZmaWMgdG8uXG4gICAgICpcbiAgICAgKiBJZiB5b3UncmUgY3JlYXRpbmcgcmVzb3VyY2UgcmVjb3JkcyBzZXRzIGZvciBhIHByaXZhdGUgaG9zdGVkIHpvbmUsIG5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gWW91IGNhbid0IGNyZWF0ZSBhbiBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSB0byByb3V0ZSB0cmFmZmljIHRvIGEgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24uXG4gICAgICogLSBGb3IgaW5mb3JtYXRpb24gYWJvdXQgY3JlYXRpbmcgZmFpbG92ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gYSBwcml2YXRlIGhvc3RlZCB6b25lLCBzZWUgW0NvbmZpZ3VyaW5nIEZhaWxvdmVyIGluIGEgUHJpdmF0ZSBIb3N0ZWQgWm9uZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1wcml2YXRlLWhvc3RlZC16b25lcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtYWxpYXN0YXJnZXRcbiAgICAgKi9cbiAgICByZWFkb25seSBhbGlhc1RhcmdldD86IENmblJlY29yZFNldC5BbGlhc1RhcmdldFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9iamVjdCB0aGF0IGlzIHNwZWNpZmllZCBpbiByZXNvdXJjZSByZWNvcmQgc2V0IG9iamVjdCB3aGVuIHlvdSBhcmUgbGlua2luZyBhIHJlc291cmNlIHJlY29yZCBzZXQgdG8gYSBDSURSIGxvY2F0aW9uLlxuICAgICAqXG4gICAgICogQSBgTG9jYXRpb25OYW1lYCB3aXRoIGFuIGFzdGVyaXNrIOKAnCrigJ0gY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGEgZGVmYXVsdCBDSURSIHJlY29yZC4gYENvbGxlY3Rpb25JZGAgaXMgc3RpbGwgcmVxdWlyZWQgZm9yIGRlZmF1bHQgcmVjb3JkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1jaWRycm91dGluZ2NvbmZpZ1xuICAgICAqL1xuICAgIHJlYWRvbmx5IGNpZHJSb3V0aW5nQ29uZmlnPzogQ2ZuUmVjb3JkU2V0LkNpZHJSb3V0aW5nQ29uZmlnUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiAqT3B0aW9uYWw6KiBBbnkgY29tbWVudHMgeW91IHdhbnQgdG8gaW5jbHVkZSBhYm91dCBhIGNoYW5nZSBiYXRjaCByZXF1ZXN0LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1jb21tZW50XG4gICAgICovXG4gICAgcmVhZG9ubHkgY29tbWVudD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqICpGYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cyBvbmx5OiogVG8gY29uZmlndXJlIGZhaWxvdmVyLCB5b3UgYWRkIHRoZSBgRmFpbG92ZXJgIGVsZW1lbnQgdG8gdHdvIHJlc291cmNlIHJlY29yZCBzZXRzLiBGb3Igb25lIHJlc291cmNlIHJlY29yZCBzZXQsIHlvdSBzcGVjaWZ5IGBQUklNQVJZYCBhcyB0aGUgdmFsdWUgZm9yIGBGYWlsb3ZlcmAgOyBmb3IgdGhlIG90aGVyIHJlc291cmNlIHJlY29yZCBzZXQsIHlvdSBzcGVjaWZ5IGBTRUNPTkRBUllgIC4gSW4gYWRkaXRpb24sIHlvdSBpbmNsdWRlIHRoZSBgSGVhbHRoQ2hlY2tJZGAgZWxlbWVudCBhbmQgc3BlY2lmeSB0aGUgaGVhbHRoIGNoZWNrIHRoYXQgeW91IHdhbnQgQW1hem9uIFJvdXRlIDUzIHRvIHBlcmZvcm0gZm9yIGVhY2ggcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqIEV4Y2VwdCB3aGVyZSBub3RlZCwgdGhlIGZvbGxvd2luZyBmYWlsb3ZlciBiZWhhdmlvcnMgYXNzdW1lIHRoYXQgeW91IGhhdmUgaW5jbHVkZWQgdGhlIGBIZWFsdGhDaGVja0lkYCBlbGVtZW50IGluIGJvdGggcmVzb3VyY2UgcmVjb3JkIHNldHM6XG4gICAgICpcbiAgICAgKiAtIFdoZW4gdGhlIHByaW1hcnkgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyBoZWFsdGh5LCBSb3V0ZSA1MyByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoIHRoZSBhcHBsaWNhYmxlIHZhbHVlIGZyb20gdGhlIHByaW1hcnkgcmVzb3VyY2UgcmVjb3JkIHNldCByZWdhcmRsZXNzIG9mIHRoZSBoZWFsdGggb2YgdGhlIHNlY29uZGFyeSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqIC0gV2hlbiB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIHVuaGVhbHRoeSBhbmQgdGhlIHNlY29uZGFyeSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIGhlYWx0aHksIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGFwcGxpY2FibGUgdmFsdWUgZnJvbSB0aGUgc2Vjb25kYXJ5IHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICogLSBXaGVuIHRoZSBzZWNvbmRhcnkgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGFwcGxpY2FibGUgdmFsdWUgZnJvbSB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0IHJlZ2FyZGxlc3Mgb2YgdGhlIGhlYWx0aCBvZiB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqIC0gSWYgeW91IG9taXQgdGhlIGBIZWFsdGhDaGVja0lkYCBlbGVtZW50IGZvciB0aGUgc2Vjb25kYXJ5IHJlc291cmNlIHJlY29yZCBzZXQsIGFuZCBpZiB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgYWx3YXlzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGFwcGxpY2FibGUgdmFsdWUgZnJvbSB0aGUgc2Vjb25kYXJ5IHJlc291cmNlIHJlY29yZCBzZXQuIFRoaXMgaXMgdHJ1ZSByZWdhcmRsZXNzIG9mIHRoZSBoZWFsdGggb2YgdGhlIGFzc29jaWF0ZWQgZW5kcG9pbnQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuJ3QgY3JlYXRlIG5vbi1mYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgdmFsdWVzIGZvciB0aGUgYE5hbWVgIGFuZCBgVHlwZWAgZWxlbWVudHMgYXMgZmFpbG92ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICpcbiAgICAgKiBGb3IgZmFpbG92ZXIgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMsIHlvdSBtdXN0IGFsc28gaW5jbHVkZSB0aGUgYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCBlbGVtZW50IGFuZCBzZXQgdGhlIHZhbHVlIHRvIHRydWUuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBjb25maWd1cmluZyBmYWlsb3ZlciBmb3IgUm91dGUgNTMsIHNlZSB0aGUgZm9sbG93aW5nIHRvcGljcyBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIDpcbiAgICAgKlxuICAgICAqIC0gW1JvdXRlIDUzIEhlYWx0aCBDaGVja3MgYW5kIEROUyBGYWlsb3Zlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci5odG1sKVxuICAgICAqIC0gW0NvbmZpZ3VyaW5nIEZhaWxvdmVyIGluIGEgUHJpdmF0ZSBIb3N0ZWQgWm9uZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1wcml2YXRlLWhvc3RlZC16b25lcy5odG1sKVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1mYWlsb3ZlclxuICAgICAqL1xuICAgIHJlYWRvbmx5IGZhaWxvdmVyPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogKkdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzIG9ubHk6KiBBIGNvbXBsZXggdHlwZSB0aGF0IGxldHMgeW91IGNvbnRyb2wgaG93IEFtYXpvbiBSb3V0ZSA1MyByZXNwb25kcyB0byBETlMgcXVlcmllcyBiYXNlZCBvbiB0aGUgZ2VvZ3JhcGhpYyBvcmlnaW4gb2YgdGhlIHF1ZXJ5LiBGb3IgZXhhbXBsZSwgaWYgeW91IHdhbnQgYWxsIHF1ZXJpZXMgZnJvbSBBZnJpY2EgdG8gYmUgcm91dGVkIHRvIGEgd2ViIHNlcnZlciB3aXRoIGFuIElQIGFkZHJlc3Mgb2YgYDE5Mi4wLjIuMTExYCAsIGNyZWF0ZSBhIHJlc291cmNlIHJlY29yZCBzZXQgd2l0aCBhIGBUeXBlYCBvZiBgQWAgYW5kIGEgYENvbnRpbmVudENvZGVgIG9mIGBBRmAgLlxuICAgICAqXG4gICAgICogPiBBbHRob3VnaCBjcmVhdGluZyBnZW9sb2NhdGlvbiBhbmQgZ2VvbG9jYXRpb24gYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gYSBwcml2YXRlIGhvc3RlZCB6b25lIGlzIGFsbG93ZWQsIGl0J3Mgbm90IHN1cHBvcnRlZC5cbiAgICAgKlxuICAgICAqIElmIHlvdSBjcmVhdGUgc2VwYXJhdGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yIG92ZXJsYXBwaW5nIGdlb2dyYXBoaWMgcmVnaW9ucyAoZm9yIGV4YW1wbGUsIG9uZSByZXNvdXJjZSByZWNvcmQgc2V0IGZvciBhIGNvbnRpbmVudCBhbmQgb25lIGZvciBhIGNvdW50cnkgb24gdGhlIHNhbWUgY29udGluZW50KSwgcHJpb3JpdHkgZ29lcyB0byB0aGUgc21hbGxlc3QgZ2VvZ3JhcGhpYyByZWdpb24uIFRoaXMgYWxsb3dzIHlvdSB0byByb3V0ZSBtb3N0IHF1ZXJpZXMgZm9yIGEgY29udGluZW50IHRvIG9uZSByZXNvdXJjZSBhbmQgdG8gcm91dGUgcXVlcmllcyBmb3IgYSBjb3VudHJ5IG9uIHRoYXQgY29udGluZW50IHRvIGEgZGlmZmVyZW50IHJlc291cmNlLlxuICAgICAqXG4gICAgICogWW91IGNhbid0IGNyZWF0ZSB0d28gZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBzcGVjaWZ5IHRoZSBzYW1lIGdlb2dyYXBoaWMgbG9jYXRpb24uXG4gICAgICpcbiAgICAgKiBUaGUgdmFsdWUgYCpgIGluIHRoZSBgQ291bnRyeUNvZGVgIGVsZW1lbnQgbWF0Y2hlcyBhbGwgZ2VvZ3JhcGhpYyBsb2NhdGlvbnMgdGhhdCBhcmVuJ3Qgc3BlY2lmaWVkIGluIG90aGVyIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSB2YWx1ZXMgZm9yIHRoZSBgTmFtZWAgYW5kIGBUeXBlYCBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqID4gR2VvbG9jYXRpb24gd29ya3MgYnkgbWFwcGluZyBJUCBhZGRyZXNzZXMgdG8gbG9jYXRpb25zLiBIb3dldmVyLCBzb21lIElQIGFkZHJlc3NlcyBhcmVuJ3QgbWFwcGVkIHRvIGdlb2dyYXBoaWMgbG9jYXRpb25zLCBzbyBldmVuIGlmIHlvdSBjcmVhdGUgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBjb3ZlciBhbGwgc2V2ZW4gY29udGluZW50cywgUm91dGUgNTMgd2lsbCByZWNlaXZlIHNvbWUgRE5TIHF1ZXJpZXMgZnJvbSBsb2NhdGlvbnMgdGhhdCBpdCBjYW4ndCBpZGVudGlmeS4gV2UgcmVjb21tZW5kIHRoYXQgeW91IGNyZWF0ZSBhIHJlc291cmNlIHJlY29yZCBzZXQgZm9yIHdoaWNoIHRoZSB2YWx1ZSBvZiBgQ291bnRyeUNvZGVgIGlzIGAqYCAuIFR3byBncm91cHMgb2YgcXVlcmllcyBhcmUgcm91dGVkIHRvIHRoZSByZXNvdXJjZSB0aGF0IHlvdSBzcGVjaWZ5IGluIHRoaXMgcmVjb3JkOiBxdWVyaWVzIHRoYXQgY29tZSBmcm9tIGxvY2F0aW9ucyBmb3Igd2hpY2ggeW91IGhhdmVuJ3QgY3JlYXRlZCBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cyBhbmQgcXVlcmllcyBmcm9tIElQIGFkZHJlc3NlcyB0aGF0IGFyZW4ndCBtYXBwZWQgdG8gYSBsb2NhdGlvbi4gSWYgeW91IGRvbid0IGNyZWF0ZSBhIGAqYCByZXNvdXJjZSByZWNvcmQgc2V0LCBSb3V0ZSA1MyByZXR1cm5zIGEgXCJubyBhbnN3ZXJcIiByZXNwb25zZSBmb3IgcXVlcmllcyBmcm9tIHRob3NlIGxvY2F0aW9ucy5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4ndCBjcmVhdGUgbm9uLWdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSB2YWx1ZXMgZm9yIHRoZSBgTmFtZWAgYW5kIGBUeXBlYCBlbGVtZW50cyBhcyBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtZ2VvbG9jYXRpb25cbiAgICAgKi9cbiAgICByZWFkb25seSBnZW9Mb2NhdGlvbj86IENmblJlY29yZFNldC5HZW9Mb2NhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogSWYgeW91IHdhbnQgQW1hem9uIFJvdXRlIDUzIHRvIHJldHVybiB0aGlzIHJlc291cmNlIHJlY29yZCBzZXQgaW4gcmVzcG9uc2UgdG8gYSBETlMgcXVlcnkgb25seSB3aGVuIHRoZSBzdGF0dXMgb2YgYSBoZWFsdGggY2hlY2sgaXMgaGVhbHRoeSwgaW5jbHVkZSB0aGUgYEhlYWx0aENoZWNrSWRgIGVsZW1lbnQgYW5kIHNwZWNpZnkgdGhlIElEIG9mIHRoZSBhcHBsaWNhYmxlIGhlYWx0aCBjaGVjay5cbiAgICAgKlxuICAgICAqIFJvdXRlIDUzIGRldGVybWluZXMgd2hldGhlciBhIHJlc291cmNlIHJlY29yZCBzZXQgaXMgaGVhbHRoeSBiYXNlZCBvbiBvbmUgb2YgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gQnkgcGVyaW9kaWNhbGx5IHNlbmRpbmcgYSByZXF1ZXN0IHRvIHRoZSBlbmRwb2ludCB0aGF0IGlzIHNwZWNpZmllZCBpbiB0aGUgaGVhbHRoIGNoZWNrXG4gICAgICogLSBCeSBhZ2dyZWdhdGluZyB0aGUgc3RhdHVzIG9mIGEgc3BlY2lmaWVkIGdyb3VwIG9mIGhlYWx0aCBjaGVja3MgKGNhbGN1bGF0ZWQgaGVhbHRoIGNoZWNrcylcbiAgICAgKiAtIEJ5IGRldGVybWluaW5nIHRoZSBjdXJyZW50IHN0YXRlIG9mIGEgQ2xvdWRXYXRjaCBhbGFybSAoQ2xvdWRXYXRjaCBtZXRyaWMgaGVhbHRoIGNoZWNrcylcbiAgICAgKlxuICAgICAqID4gUm91dGUgNTMgZG9lc24ndCBjaGVjayB0aGUgaGVhbHRoIG9mIHRoZSBlbmRwb2ludCB0aGF0IGlzIHNwZWNpZmllZCBpbiB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldCwgZm9yIGV4YW1wbGUsIHRoZSBlbmRwb2ludCBzcGVjaWZpZWQgYnkgdGhlIElQIGFkZHJlc3MgaW4gdGhlIGBWYWx1ZWAgZWxlbWVudC4gV2hlbiB5b3UgYWRkIGEgYEhlYWx0aENoZWNrSWRgIGVsZW1lbnQgdG8gYSByZXNvdXJjZSByZWNvcmQgc2V0LCBSb3V0ZSA1MyBjaGVja3MgdGhlIGhlYWx0aCBvZiB0aGUgZW5kcG9pbnQgdGhhdCB5b3Ugc3BlY2lmaWVkIGluIHRoZSBoZWFsdGggY2hlY2suXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIHRoZSBmb2xsb3dpbmcgdG9waWNzIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogOlxuICAgICAqXG4gICAgICogLSBbSG93IEFtYXpvbiBSb3V0ZSA1MyBEZXRlcm1pbmVzIFdoZXRoZXIgYW4gRW5kcG9pbnQgSXMgSGVhbHRoeV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1kZXRlcm1pbmluZy1oZWFsdGgtb2YtZW5kcG9pbnRzLmh0bWwpXG4gICAgICogLSBbUm91dGUgNTMgSGVhbHRoIENoZWNrcyBhbmQgRE5TIEZhaWxvdmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLmh0bWwpXG4gICAgICogLSBbQ29uZmlndXJpbmcgRmFpbG92ZXIgaW4gYSBQcml2YXRlIEhvc3RlZCBab25lXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLXByaXZhdGUtaG9zdGVkLXpvbmVzLmh0bWwpXG4gICAgICpcbiAgICAgKiAqV2hlbiB0byBTcGVjaWZ5IEhlYWx0aENoZWNrSWQqXG4gICAgICpcbiAgICAgKiBTcGVjaWZ5aW5nIGEgdmFsdWUgZm9yIGBIZWFsdGhDaGVja0lkYCBpcyB1c2VmdWwgb25seSB3aGVuIFJvdXRlIDUzIGlzIGNob29zaW5nIGJldHdlZW4gdHdvIG9yIG1vcmUgcmVzb3VyY2UgcmVjb3JkIHNldHMgdG8gcmVzcG9uZCB0byBhIEROUyBxdWVyeSwgYW5kIHlvdSB3YW50IFJvdXRlIDUzIHRvIGJhc2UgdGhlIGNob2ljZSBpbiBwYXJ0IG9uIHRoZSBzdGF0dXMgb2YgYSBoZWFsdGggY2hlY2suIENvbmZpZ3VyaW5nIGhlYWx0aCBjaGVja3MgbWFrZXMgc2Vuc2Ugb25seSBpbiB0aGUgZm9sbG93aW5nIGNvbmZpZ3VyYXRpb25zOlxuICAgICAqXG4gICAgICogLSAqTm9uLWFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzKiA6IFlvdSdyZSBjaGVja2luZyB0aGUgaGVhbHRoIG9mIGEgZ3JvdXAgb2Ygbm9uLWFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSByb3V0aW5nIHBvbGljeSwgbmFtZSwgYW5kIHR5cGUgKHN1Y2ggYXMgbXVsdGlwbGUgd2VpZ2h0ZWQgcmVjb3JkcyBuYW1lZCB3d3cuZXhhbXBsZS5jb20gd2l0aCBhIHR5cGUgb2YgQSkgYW5kIHlvdSBzcGVjaWZ5IGhlYWx0aCBjaGVjayBJRHMgZm9yIGFsbCB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgaGVhbHRoIGNoZWNrIHN0YXR1cyBmb3IgYSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIGhlYWx0aHksIFJvdXRlIDUzIGluY2x1ZGVzIHRoZSByZWNvcmQgYW1vbmcgdGhlIHJlY29yZHMgdGhhdCBpdCByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoLlxuICAgICAqXG4gICAgICogSWYgdGhlIGhlYWx0aCBjaGVjayBzdGF0dXMgZm9yIGEgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIHN0b3BzIHJlc3BvbmRpbmcgdG8gRE5TIHF1ZXJpZXMgdXNpbmcgdGhlIHZhbHVlIGZvciB0aGF0IHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgaGVhbHRoIGNoZWNrIHN0YXR1cyBmb3IgYWxsIHJlc291cmNlIHJlY29yZCBzZXRzIGluIHRoZSBncm91cCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIGNvbnNpZGVycyBhbGwgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gdGhlIGdyb3VwIGhlYWx0aHkgYW5kIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIGFjY29yZGluZ2x5LlxuICAgICAqIC0gKkFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzKiA6IFlvdSBzcGVjaWZ5IHRoZSBmb2xsb3dpbmcgc2V0dGluZ3M6XG4gICAgICpcbiAgICAgKiAtIFlvdSBzZXQgYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCB0byB0cnVlIGZvciBhbiBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IGluIGEgZ3JvdXAgb2YgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHJvdXRpbmcgcG9saWN5LCBuYW1lLCBhbmQgdHlwZSAoc3VjaCBhcyBtdWx0aXBsZSB3ZWlnaHRlZCByZWNvcmRzIG5hbWVkIHd3dy5leGFtcGxlLmNvbSB3aXRoIGEgdHlwZSBvZiBBKS5cbiAgICAgKiAtIFlvdSBjb25maWd1cmUgdGhlIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQgdG8gcm91dGUgdHJhZmZpYyB0byBhIG5vbi1hbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IGluIHRoZSBzYW1lIGhvc3RlZCB6b25lLlxuICAgICAqIC0gWW91IHNwZWNpZnkgYSBoZWFsdGggY2hlY2sgSUQgZm9yIHRoZSBub24tYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqIElmIHRoZSBoZWFsdGggY2hlY2sgc3RhdHVzIGlzIGhlYWx0aHksIFJvdXRlIDUzIGNvbnNpZGVycyB0aGUgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldCB0byBiZSBoZWFsdGh5IGFuZCBpbmNsdWRlcyB0aGUgYWxpYXMgcmVjb3JkIGFtb25nIHRoZSByZWNvcmRzIHRoYXQgaXQgcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgd2l0aC5cbiAgICAgKlxuICAgICAqIElmIHRoZSBoZWFsdGggY2hlY2sgc3RhdHVzIGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgc3RvcHMgcmVzcG9uZGluZyB0byBETlMgcXVlcmllcyB1c2luZyB0aGUgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqID4gVGhlIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQgY2FuIGFsc28gcm91dGUgdHJhZmZpYyB0byBhICpncm91cCogb2Ygbm9uLWFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSByb3V0aW5nIHBvbGljeSwgbmFtZSwgYW5kIHR5cGUuIEluIHRoYXQgY29uZmlndXJhdGlvbiwgYXNzb2NpYXRlIGhlYWx0aCBjaGVja3Mgd2l0aCBhbGwgb2YgdGhlIHJlc291cmNlIHJlY29yZCBzZXRzIGluIHRoZSBncm91cCBvZiBub24tYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICpcbiAgICAgKiAqR2VvbG9jYXRpb24gUm91dGluZypcbiAgICAgKlxuICAgICAqIEZvciBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cywgaWYgYW4gZW5kcG9pbnQgaXMgdW5oZWFsdGh5LCBSb3V0ZSA1MyBsb29rcyBmb3IgYSByZXNvdXJjZSByZWNvcmQgc2V0IGZvciB0aGUgbGFyZ2VyLCBhc3NvY2lhdGVkIGdlb2dyYXBoaWMgcmVnaW9uLiBGb3IgZXhhbXBsZSwgc3VwcG9zZSB5b3UgaGF2ZSByZXNvdXJjZSByZWNvcmQgc2V0cyBmb3IgYSBzdGF0ZSBpbiB0aGUgVW5pdGVkIFN0YXRlcywgZm9yIHRoZSBlbnRpcmUgVW5pdGVkIFN0YXRlcywgZm9yIE5vcnRoIEFtZXJpY2EsIGFuZCBhIHJlc291cmNlIHJlY29yZCBzZXQgdGhhdCBoYXMgYCpgIGZvciBgQ291bnRyeUNvZGVgIGlzIGAqYCAsIHdoaWNoIGFwcGxpZXMgdG8gYWxsIGxvY2F0aW9ucy4gSWYgdGhlIGVuZHBvaW50IGZvciB0aGUgc3RhdGUgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIGNoZWNrcyBmb3IgaGVhbHRoeSByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiB0aGUgZm9sbG93aW5nIG9yZGVyIHVudGlsIGl0IGZpbmRzIGEgcmVzb3VyY2UgcmVjb3JkIHNldCBmb3Igd2hpY2ggdGhlIGVuZHBvaW50IGlzIGhlYWx0aHk6XG4gICAgICpcbiAgICAgKiAtIFRoZSBVbml0ZWQgU3RhdGVzXG4gICAgICogLSBOb3J0aCBBbWVyaWNhXG4gICAgICogLSBUaGUgZGVmYXVsdCByZXNvdXJjZSByZWNvcmQgc2V0XG4gICAgICpcbiAgICAgKiAqU3BlY2lmeWluZyB0aGUgSGVhbHRoIENoZWNrIEVuZHBvaW50IGJ5IERvbWFpbiBOYW1lKlxuICAgICAqXG4gICAgICogSWYgeW91ciBoZWFsdGggY2hlY2tzIHNwZWNpZnkgdGhlIGVuZHBvaW50IG9ubHkgYnkgZG9tYWluIG5hbWUsIHdlIHJlY29tbWVuZCB0aGF0IHlvdSBjcmVhdGUgYSBzZXBhcmF0ZSBoZWFsdGggY2hlY2sgZm9yIGVhY2ggZW5kcG9pbnQuIEZvciBleGFtcGxlLCBjcmVhdGUgYSBoZWFsdGggY2hlY2sgZm9yIGVhY2ggYEhUVFBgIHNlcnZlciB0aGF0IGlzIHNlcnZpbmcgY29udGVudCBmb3IgYHd3dy5leGFtcGxlLmNvbWAgLiBGb3IgdGhlIHZhbHVlIG9mIGBGdWxseVF1YWxpZmllZERvbWFpbk5hbWVgICwgc3BlY2lmeSB0aGUgZG9tYWluIG5hbWUgb2YgdGhlIHNlcnZlciAoc3VjaCBhcyBgdXMtZWFzdC0yLXd3dy5leGFtcGxlLmNvbWAgKSwgbm90IHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0cyAoIGB3d3cuZXhhbXBsZS5jb21gICkuXG4gICAgICpcbiAgICAgKiA+IEhlYWx0aCBjaGVjayByZXN1bHRzIHdpbGwgYmUgdW5wcmVkaWN0YWJsZSBpZiB5b3UgZG8gdGhlIGZvbGxvd2luZzpcbiAgICAgKiA+XG4gICAgICogPiAtIENyZWF0ZSBhIGhlYWx0aCBjaGVjayB0aGF0IGhhcyB0aGUgc2FtZSB2YWx1ZSBmb3IgYEZ1bGx5UXVhbGlmaWVkRG9tYWluTmFtZWAgYXMgdGhlIG5hbWUgb2YgYSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqID4gLSBBc3NvY2lhdGUgdGhhdCBoZWFsdGggY2hlY2sgd2l0aCB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtaGVhbHRoY2hlY2tpZFxuICAgICAqL1xuICAgIHJlYWRvbmx5IGhlYWx0aENoZWNrSWQ/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgSUQgb2YgdGhlIGhvc3RlZCB6b25lIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlIHJlY29yZHMgaW4uXG4gICAgICpcbiAgICAgKiBTcGVjaWZ5IGVpdGhlciBgSG9zdGVkWm9uZU5hbWVgIG9yIGBIb3N0ZWRab25lSWRgICwgYnV0IG5vdCBib3RoLiBJZiB5b3UgaGF2ZSBtdWx0aXBsZSBob3N0ZWQgem9uZXMgd2l0aCB0aGUgc2FtZSBkb21haW4gbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgaG9zdGVkIHpvbmUgdXNpbmcgYEhvc3RlZFpvbmVJZGAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1ob3N0ZWR6b25laWRcbiAgICAgKi9cbiAgICByZWFkb25seSBob3N0ZWRab25lSWQ/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgaG9zdGVkIHpvbmUgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUgcmVjb3JkcyBpbi4gWW91IG11c3QgaW5jbHVkZSBhIHRyYWlsaW5nIGRvdCAoZm9yIGV4YW1wbGUsIGB3d3cuZXhhbXBsZS5jb20uYCApIGFzIHBhcnQgb2YgdGhlIGBIb3N0ZWRab25lTmFtZWAgLlxuICAgICAqXG4gICAgICogV2hlbiB5b3UgY3JlYXRlIGEgc3RhY2sgdXNpbmcgYW4gQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXQgdGhhdCBzcGVjaWZpZXMgYEhvc3RlZFpvbmVOYW1lYCAsIEFXUyBDbG91ZEZvcm1hdGlvbiBhdHRlbXB0cyB0byBmaW5kIGEgaG9zdGVkIHpvbmUgd2hvc2UgbmFtZSBtYXRjaGVzIHRoZSBIb3N0ZWRab25lTmFtZS4gSWYgQVdTIENsb3VkRm9ybWF0aW9uIGNhbm5vdCBmaW5kIGEgaG9zdGVkIHpvbmUgd2l0aCBhIG1hdGNoaW5nIGRvbWFpbiBuYW1lLCBvciBpZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIGhvc3RlZCB6b25lIHdpdGggdGhlIHNwZWNpZmllZCBkb21haW4gbmFtZSwgQVdTIENsb3VkRm9ybWF0aW9uIHdpbGwgbm90IGNyZWF0ZSB0aGUgc3RhY2suXG4gICAgICpcbiAgICAgKiBTcGVjaWZ5IGVpdGhlciBgSG9zdGVkWm9uZU5hbWVgIG9yIGBIb3N0ZWRab25lSWRgICwgYnV0IG5vdCBib3RoLiBJZiB5b3UgaGF2ZSBtdWx0aXBsZSBob3N0ZWQgem9uZXMgd2l0aCB0aGUgc2FtZSBkb21haW4gbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgaG9zdGVkIHpvbmUgdXNpbmcgYEhvc3RlZFpvbmVJZGAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1ob3N0ZWR6b25lbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IGhvc3RlZFpvbmVOYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogKk11bHRpdmFsdWUgYW5zd2VyIHJlc291cmNlIHJlY29yZCBzZXRzIG9ubHkqIDogVG8gcm91dGUgdHJhZmZpYyBhcHByb3hpbWF0ZWx5IHJhbmRvbWx5IHRvIG11bHRpcGxlIHJlc291cmNlcywgc3VjaCBhcyB3ZWIgc2VydmVycywgY3JlYXRlIG9uZSBtdWx0aXZhbHVlIGFuc3dlciByZWNvcmQgZm9yIGVhY2ggcmVzb3VyY2UgYW5kIHNwZWNpZnkgYHRydWVgIGZvciBgTXVsdGlWYWx1ZUFuc3dlcmAgLiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIElmIHlvdSBhc3NvY2lhdGUgYSBoZWFsdGggY2hlY2sgd2l0aCBhIG11bHRpdmFsdWUgYW5zd2VyIHJlc291cmNlIHJlY29yZCBzZXQsIEFtYXpvbiBSb3V0ZSA1MyByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIElQIGFkZHJlc3Mgb25seSB3aGVuIHRoZSBoZWFsdGggY2hlY2sgaXMgaGVhbHRoeS5cbiAgICAgKiAtIElmIHlvdSBkb24ndCBhc3NvY2lhdGUgYSBoZWFsdGggY2hlY2sgd2l0aCBhIG11bHRpdmFsdWUgYW5zd2VyIHJlY29yZCwgUm91dGUgNTMgYWx3YXlzIGNvbnNpZGVycyB0aGUgcmVjb3JkIHRvIGJlIGhlYWx0aHkuXG4gICAgICogLSBSb3V0ZSA1MyByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoIHVwIHRvIGVpZ2h0IGhlYWx0aHkgcmVjb3JkczsgaWYgeW91IGhhdmUgZWlnaHQgb3IgZmV3ZXIgaGVhbHRoeSByZWNvcmRzLCBSb3V0ZSA1MyByZXNwb25kcyB0byBhbGwgRE5TIHF1ZXJpZXMgd2l0aCBhbGwgdGhlIGhlYWx0aHkgcmVjb3Jkcy5cbiAgICAgKiAtIElmIHlvdSBoYXZlIG1vcmUgdGhhbiBlaWdodCBoZWFsdGh5IHJlY29yZHMsIFJvdXRlIDUzIHJlc3BvbmRzIHRvIGRpZmZlcmVudCBETlMgcmVzb2x2ZXJzIHdpdGggZGlmZmVyZW50IGNvbWJpbmF0aW9ucyBvZiBoZWFsdGh5IHJlY29yZHMuXG4gICAgICogLSBXaGVuIGFsbCByZWNvcmRzIGFyZSB1bmhlYWx0aHksIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdXAgdG8gZWlnaHQgdW5oZWFsdGh5IHJlY29yZHMuXG4gICAgICogLSBJZiBhIHJlc291cmNlIGJlY29tZXMgdW5hdmFpbGFibGUgYWZ0ZXIgYSByZXNvbHZlciBjYWNoZXMgYSByZXNwb25zZSwgY2xpZW50IHNvZnR3YXJlIHR5cGljYWxseSB0cmllcyBhbm90aGVyIG9mIHRoZSBJUCBhZGRyZXNzZXMgaW4gdGhlIHJlc3BvbnNlLlxuICAgICAqXG4gICAgICogWW91IGNhbid0IGNyZWF0ZSBtdWx0aXZhbHVlIGFuc3dlciBhbGlhcyByZWNvcmRzLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1tdWx0aXZhbHVlYW5zd2VyXG4gICAgICovXG4gICAgcmVhZG9ubHkgbXVsdGlWYWx1ZUFuc3dlcj86IGJvb2xlYW4gfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiAqTGF0ZW5jeS1iYXNlZCByZXNvdXJjZSByZWNvcmQgc2V0cyBvbmx5OiogVGhlIEFtYXpvbiBFQzIgUmVnaW9uIHdoZXJlIHlvdSBjcmVhdGVkIHRoZSByZXNvdXJjZSB0aGF0IHRoaXMgcmVzb3VyY2UgcmVjb3JkIHNldCByZWZlcnMgdG8uIFRoZSByZXNvdXJjZSB0eXBpY2FsbHkgaXMgYW4gQVdTIHJlc291cmNlLCBzdWNoIGFzIGFuIEVDMiBpbnN0YW5jZSBvciBhbiBFTEIgbG9hZCBiYWxhbmNlciwgYW5kIGlzIHJlZmVycmVkIHRvIGJ5IGFuIElQIGFkZHJlc3Mgb3IgYSBETlMgZG9tYWluIG5hbWUsIGRlcGVuZGluZyBvbiB0aGUgcmVjb3JkIHR5cGUuXG4gICAgICpcbiAgICAgKiBXaGVuIEFtYXpvbiBSb3V0ZSA1MyByZWNlaXZlcyBhIEROUyBxdWVyeSBmb3IgYSBkb21haW4gbmFtZSBhbmQgdHlwZSBmb3Igd2hpY2ggeW91IGhhdmUgY3JlYXRlZCBsYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXRzLCBSb3V0ZSA1MyBzZWxlY3RzIHRoZSBsYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXQgdGhhdCBoYXMgdGhlIGxvd2VzdCBsYXRlbmN5IGJldHdlZW4gdGhlIGVuZCB1c2VyIGFuZCB0aGUgYXNzb2NpYXRlZCBBbWF6b24gRUMyIFJlZ2lvbi4gUm91dGUgNTMgdGhlbiByZXR1cm5zIHRoZSB2YWx1ZSB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgc2VsZWN0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gWW91IGNhbiBvbmx5IHNwZWNpZnkgb25lIGBSZXNvdXJjZVJlY29yZGAgcGVyIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKiAtIFlvdSBjYW4gb25seSBjcmVhdGUgb25lIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldCBmb3IgZWFjaCBBbWF6b24gRUMyIFJlZ2lvbi5cbiAgICAgKiAtIFlvdSBhcmVuJ3QgcmVxdWlyZWQgdG8gY3JlYXRlIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yIGFsbCBBbWF6b24gRUMyIFJlZ2lvbnMuIFJvdXRlIDUzIHdpbGwgY2hvb3NlIHRoZSByZWdpb24gd2l0aCB0aGUgYmVzdCBsYXRlbmN5IGZyb20gYW1vbmcgdGhlIHJlZ2lvbnMgdGhhdCB5b3UgY3JlYXRlIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yLlxuICAgICAqIC0gWW91IGNhbid0IGNyZWF0ZSBub24tbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgdmFsdWVzIGZvciB0aGUgYE5hbWVgIGFuZCBgVHlwZWAgZWxlbWVudHMgYXMgbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0cy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtcmVnaW9uXG4gICAgICovXG4gICAgcmVhZG9ubHkgcmVnaW9uPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogT25lIG9yIG1vcmUgdmFsdWVzIHRoYXQgY29ycmVzcG9uZCB3aXRoIHRoZSB2YWx1ZSB0aGF0IHlvdSBzcGVjaWZpZWQgZm9yIHRoZSBgVHlwZWAgcHJvcGVydHkuIEZvciBleGFtcGxlLCBpZiB5b3Ugc3BlY2lmaWVkIGBBYCBmb3IgYFR5cGVgICwgeW91IHNwZWNpZnkgb25lIG9yIG1vcmUgSVAgYWRkcmVzc2VzIGluIElQdjQgZm9ybWF0IGZvciBgUmVzb3VyY2VSZWNvcmRzYCAuIEZvciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZm9ybWF0IG9mIHZhbHVlcyBmb3IgZWFjaCByZWNvcmQgdHlwZSwgc2VlIFtTdXBwb3J0ZWQgRE5TIFJlc291cmNlIFJlY29yZCBUeXBlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL1Jlc291cmNlUmVjb3JkVHlwZXMuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIFlvdSBjYW4gc3BlY2lmeSBtb3JlIHRoYW4gb25lIHZhbHVlIGZvciBhbGwgcmVjb3JkIHR5cGVzIGV4Y2VwdCBDTkFNRSBhbmQgU09BLlxuICAgICAqIC0gVGhlIG1heGltdW0gbGVuZ3RoIG9mIGEgdmFsdWUgaXMgNDAwMCBjaGFyYWN0ZXJzLlxuICAgICAqIC0gSWYgeW91J3JlIGNyZWF0aW5nIGFuIGFsaWFzIHJlY29yZCwgb21pdCBgUmVzb3VyY2VSZWNvcmRzYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LXJlc291cmNlcmVjb3Jkc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IHJlc291cmNlUmVjb3Jkcz86IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogKlJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSBhIHJvdXRpbmcgcG9saWN5IG90aGVyIHRoYW4gc2ltcGxlOiogQW4gaWRlbnRpZmllciB0aGF0IGRpZmZlcmVudGlhdGVzIGFtb25nIG11bHRpcGxlIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBjb21iaW5hdGlvbiBvZiBuYW1lIGFuZCB0eXBlLCBzdWNoIGFzIG11bHRpcGxlIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzIG5hbWVkIGFjbWUuZXhhbXBsZS5jb20gdGhhdCBoYXZlIGEgdHlwZSBvZiBBLiBJbiBhIGdyb3VwIG9mIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBuYW1lIGFuZCB0eXBlLCB0aGUgdmFsdWUgb2YgYFNldElkZW50aWZpZXJgIG11c3QgYmUgdW5pcXVlIGZvciBlYWNoIHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICpcbiAgICAgKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgcm91dGluZyBwb2xpY2llcywgc2VlIFtDaG9vc2luZyBhIFJvdXRpbmcgUG9saWN5XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvcm91dGluZy1wb2xpY3kuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LXNldGlkZW50aWZpZXJcbiAgICAgKi9cbiAgICByZWFkb25seSBzZXRJZGVudGlmaWVyPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlc291cmNlIHJlY29yZCBjYWNoZSB0aW1lIHRvIGxpdmUgKFRUTCksIGluIHNlY29uZHMuIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gSWYgeW91J3JlIGNyZWF0aW5nIG9yIHVwZGF0aW5nIGFuIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQsIG9taXQgYFRUTGAgLiBBbWF6b24gUm91dGUgNTMgdXNlcyB0aGUgdmFsdWUgb2YgYFRUTGAgZm9yIHRoZSBhbGlhcyB0YXJnZXQuXG4gICAgICogLSBJZiB5b3UncmUgYXNzb2NpYXRpbmcgdGhpcyByZXNvdXJjZSByZWNvcmQgc2V0IHdpdGggYSBoZWFsdGggY2hlY2sgKGlmIHlvdSdyZSBhZGRpbmcgYSBgSGVhbHRoQ2hlY2tJZGAgZWxlbWVudCksIHdlIHJlY29tbWVuZCB0aGF0IHlvdSBzcGVjaWZ5IGEgYFRUTGAgb2YgNjAgc2Vjb25kcyBvciBsZXNzIHNvIGNsaWVudHMgcmVzcG9uZCBxdWlja2x5IHRvIGNoYW5nZXMgaW4gaGVhbHRoIHN0YXR1cy5cbiAgICAgKiAtIEFsbCBvZiB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gYSBncm91cCBvZiB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0cyBtdXN0IGhhdmUgdGhlIHNhbWUgdmFsdWUgZm9yIGBUVExgIC5cbiAgICAgKiAtIElmIGEgZ3JvdXAgb2Ygd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW5jbHVkZXMgb25lIG9yIG1vcmUgd2VpZ2h0ZWQgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yIHdoaWNoIHRoZSBhbGlhcyB0YXJnZXQgaXMgYW4gRUxCIGxvYWQgYmFsYW5jZXIsIHdlIHJlY29tbWVuZCB0aGF0IHlvdSBzcGVjaWZ5IGEgYFRUTGAgb2YgNjAgc2Vjb25kcyBmb3IgYWxsIG9mIHRoZSBub24tYWxpYXMgd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIG5hbWUgYW5kIHR5cGUuIFZhbHVlcyBvdGhlciB0aGFuIDYwIHNlY29uZHMgKHRoZSBUVEwgZm9yIGxvYWQgYmFsYW5jZXJzKSB3aWxsIGNoYW5nZSB0aGUgZWZmZWN0IG9mIHRoZSB2YWx1ZXMgdGhhdCB5b3Ugc3BlY2lmeSBmb3IgYFdlaWdodGAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC10dGxcbiAgICAgKi9cbiAgICByZWFkb25seSB0dGw/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiAqV2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgb25seToqIEFtb25nIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBjb21iaW5hdGlvbiBvZiBETlMgbmFtZSBhbmQgdHlwZSwgYSB2YWx1ZSB0aGF0IGRldGVybWluZXMgdGhlIHByb3BvcnRpb24gb2YgRE5TIHF1ZXJpZXMgdGhhdCBBbWF6b24gUm91dGUgNTMgcmVzcG9uZHMgdG8gdXNpbmcgdGhlIGN1cnJlbnQgcmVzb3VyY2UgcmVjb3JkIHNldC4gUm91dGUgNTMgY2FsY3VsYXRlcyB0aGUgc3VtIG9mIHRoZSB3ZWlnaHRzIGZvciB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIGNvbWJpbmF0aW9uIG9mIEROUyBuYW1lIGFuZCB0eXBlLiBSb3V0ZSA1MyB0aGVuIHJlc3BvbmRzIHRvIHF1ZXJpZXMgYmFzZWQgb24gdGhlIHJhdGlvIG9mIGEgcmVzb3VyY2UncyB3ZWlnaHQgdG8gdGhlIHRvdGFsLiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIFlvdSBtdXN0IHNwZWNpZnkgYSB2YWx1ZSBmb3IgdGhlIGBXZWlnaHRgIGVsZW1lbnQgZm9yIGV2ZXJ5IHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICogLSBZb3UgY2FuIG9ubHkgc3BlY2lmeSBvbmUgYFJlc291cmNlUmVjb3JkYCBwZXIgd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKiAtIFlvdSBjYW4ndCBjcmVhdGUgbGF0ZW5jeSwgZmFpbG92ZXIsIG9yIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSB2YWx1ZXMgZm9yIHRoZSBgTmFtZWAgYW5kIGBUeXBlYCBlbGVtZW50cyBhcyB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0cy5cbiAgICAgKiAtIFlvdSBjYW4gY3JlYXRlIGEgbWF4aW11bSBvZiAxMDAgd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHZhbHVlcyBmb3IgdGhlIGBOYW1lYCBhbmQgYFR5cGVgIGVsZW1lbnRzLlxuICAgICAqIC0gRm9yIHdlaWdodGVkIChidXQgbm90IHdlaWdodGVkIGFsaWFzKSByZXNvdXJjZSByZWNvcmQgc2V0cywgaWYgeW91IHNldCBgV2VpZ2h0YCB0byBgMGAgZm9yIGEgcmVzb3VyY2UgcmVjb3JkIHNldCwgUm91dGUgNTMgbmV2ZXIgcmVzcG9uZHMgdG8gcXVlcmllcyB3aXRoIHRoZSBhcHBsaWNhYmxlIHZhbHVlIGZvciB0aGF0IHJlc291cmNlIHJlY29yZCBzZXQuIEhvd2V2ZXIsIGlmIHlvdSBzZXQgYFdlaWdodGAgdG8gYDBgIGZvciBhbGwgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIGNvbWJpbmF0aW9uIG9mIEROUyBuYW1lIGFuZCB0eXBlLCB0cmFmZmljIGlzIHJvdXRlZCB0byBhbGwgcmVzb3VyY2VzIHdpdGggZXF1YWwgcHJvYmFiaWxpdHkuXG4gICAgICpcbiAgICAgKiBUaGUgZWZmZWN0IG9mIHNldHRpbmcgYFdlaWdodGAgdG8gYDBgIGlzIGRpZmZlcmVudCB3aGVuIHlvdSBhc3NvY2lhdGUgaGVhbHRoIGNoZWNrcyB3aXRoIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtPcHRpb25zIGZvciBDb25maWd1cmluZyBSb3V0ZSA1MyBBY3RpdmUtQWN0aXZlIGFuZCBBY3RpdmUtUGFzc2l2ZSBGYWlsb3Zlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1jb25maWd1cmluZy1vcHRpb25zLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC13ZWlnaHRcbiAgICAgKi9cbiAgICByZWFkb25seSB3ZWlnaHQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2ZuUmVjb3JkU2V0UHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblJlY29yZFNldFByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblJlY29yZFNldFByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignYWxpYXNUYXJnZXQnLCBDZm5SZWNvcmRTZXRfQWxpYXNUYXJnZXRQcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5hbGlhc1RhcmdldCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2lkclJvdXRpbmdDb25maWcnLCBDZm5SZWNvcmRTZXRfQ2lkclJvdXRpbmdDb25maWdQcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5jaWRyUm91dGluZ0NvbmZpZykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY29tbWVudCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jb21tZW50KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdmYWlsb3ZlcicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5mYWlsb3ZlcikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZ2VvTG9jYXRpb24nLCBDZm5SZWNvcmRTZXRfR2VvTG9jYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5nZW9Mb2NhdGlvbikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaGVhbHRoQ2hlY2tJZCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5oZWFsdGhDaGVja0lkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdob3N0ZWRab25lSWQnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuaG9zdGVkWm9uZUlkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdob3N0ZWRab25lTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5ob3N0ZWRab25lTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbXVsdGlWYWx1ZUFuc3dlcicsIGNkay52YWxpZGF0ZUJvb2xlYW4pKHByb3BlcnRpZXMubXVsdGlWYWx1ZUFuc3dlcikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLm5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3JlZ2lvbicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5yZWdpb24pKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3Jlc291cmNlUmVjb3JkcycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMucmVzb3VyY2VSZWNvcmRzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzZXRJZGVudGlmaWVyJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnNldElkZW50aWZpZXIpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3R0bCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy50dGwpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3R5cGUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMudHlwZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndHlwZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy50eXBlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd3ZWlnaHQnLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMud2VpZ2h0KSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmblJlY29yZFNldFByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblJlY29yZFNldFByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuUmVjb3JkU2V0UHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblJlY29yZFNldFByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm5hbWUpLFxuICAgICAgICBUeXBlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnR5cGUpLFxuICAgICAgICBBbGlhc1RhcmdldDogY2ZuUmVjb3JkU2V0QWxpYXNUYXJnZXRQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5hbGlhc1RhcmdldCksXG4gICAgICAgIENpZHJSb3V0aW5nQ29uZmlnOiBjZm5SZWNvcmRTZXRDaWRyUm91dGluZ0NvbmZpZ1Byb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNpZHJSb3V0aW5nQ29uZmlnKSxcbiAgICAgICAgQ29tbWVudDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jb21tZW50KSxcbiAgICAgICAgRmFpbG92ZXI6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZmFpbG92ZXIpLFxuICAgICAgICBHZW9Mb2NhdGlvbjogY2ZuUmVjb3JkU2V0R2VvTG9jYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5nZW9Mb2NhdGlvbiksXG4gICAgICAgIEhlYWx0aENoZWNrSWQ6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaGVhbHRoQ2hlY2tJZCksXG4gICAgICAgIEhvc3RlZFpvbmVJZDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5ob3N0ZWRab25lSWQpLFxuICAgICAgICBIb3N0ZWRab25lTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5ob3N0ZWRab25lTmFtZSksXG4gICAgICAgIE11bHRpVmFsdWVBbnN3ZXI6IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm11bHRpVmFsdWVBbnN3ZXIpLFxuICAgICAgICBSZWdpb246IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucmVnaW9uKSxcbiAgICAgICAgUmVzb3VyY2VSZWNvcmRzOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5yZXNvdXJjZVJlY29yZHMpLFxuICAgICAgICBTZXRJZGVudGlmaWVyOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnNldElkZW50aWZpZXIpLFxuICAgICAgICBUVEw6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudHRsKSxcbiAgICAgICAgV2VpZ2h0OiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLndlaWdodCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblJlY29yZFNldFByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuUmVjb3JkU2V0UHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblJlY29yZFNldFByb3BzPigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbmFtZScsICdOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5OYW1lKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0eXBlJywgJ1R5cGUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlR5cGUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2FsaWFzVGFyZ2V0JywgJ0FsaWFzVGFyZ2V0JywgcHJvcGVydGllcy5BbGlhc1RhcmdldCAhPSBudWxsID8gQ2ZuUmVjb3JkU2V0QWxpYXNUYXJnZXRQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLkFsaWFzVGFyZ2V0KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjaWRyUm91dGluZ0NvbmZpZycsICdDaWRyUm91dGluZ0NvbmZpZycsIHByb3BlcnRpZXMuQ2lkclJvdXRpbmdDb25maWcgIT0gbnVsbCA/IENmblJlY29yZFNldENpZHJSb3V0aW5nQ29uZmlnUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5DaWRyUm91dGluZ0NvbmZpZykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY29tbWVudCcsICdDb21tZW50JywgcHJvcGVydGllcy5Db21tZW50ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNvbW1lbnQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2ZhaWxvdmVyJywgJ0ZhaWxvdmVyJywgcHJvcGVydGllcy5GYWlsb3ZlciAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5GYWlsb3ZlcikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZ2VvTG9jYXRpb24nLCAnR2VvTG9jYXRpb24nLCBwcm9wZXJ0aWVzLkdlb0xvY2F0aW9uICE9IG51bGwgPyBDZm5SZWNvcmRTZXRHZW9Mb2NhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuR2VvTG9jYXRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hlYWx0aENoZWNrSWQnLCAnSGVhbHRoQ2hlY2tJZCcsIHByb3BlcnRpZXMuSGVhbHRoQ2hlY2tJZCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5IZWFsdGhDaGVja0lkKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdob3N0ZWRab25lSWQnLCAnSG9zdGVkWm9uZUlkJywgcHJvcGVydGllcy5Ib3N0ZWRab25lSWQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuSG9zdGVkWm9uZUlkKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdob3N0ZWRab25lTmFtZScsICdIb3N0ZWRab25lTmFtZScsIHByb3BlcnRpZXMuSG9zdGVkWm9uZU5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuSG9zdGVkWm9uZU5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ211bHRpVmFsdWVBbnN3ZXInLCAnTXVsdGlWYWx1ZUFuc3dlcicsIHByb3BlcnRpZXMuTXVsdGlWYWx1ZUFuc3dlciAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRCb29sZWFuKHByb3BlcnRpZXMuTXVsdGlWYWx1ZUFuc3dlcikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncmVnaW9uJywgJ1JlZ2lvbicsIHByb3BlcnRpZXMuUmVnaW9uICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlJlZ2lvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncmVzb3VyY2VSZWNvcmRzJywgJ1Jlc291cmNlUmVjb3JkcycsIHByb3BlcnRpZXMuUmVzb3VyY2VSZWNvcmRzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuUmVzb3VyY2VSZWNvcmRzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzZXRJZGVudGlmaWVyJywgJ1NldElkZW50aWZpZXInLCBwcm9wZXJ0aWVzLlNldElkZW50aWZpZXIgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuU2V0SWRlbnRpZmllcikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndHRsJywgJ1RUTCcsIHByb3BlcnRpZXMuVFRMICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlRUTCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnd2VpZ2h0JywgJ1dlaWdodCcsIHByb3BlcnRpZXMuV2VpZ2h0ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLldlaWdodCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0YFxuICpcbiAqIEluZm9ybWF0aW9uIGFib3V0IHRoZSByZWNvcmQgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUuXG4gKlxuICogVGhlIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldGAgdHlwZSBjYW4gYmUgdXNlZCBhcyBhIHN0YW5kYWxvbmUgcmVzb3VyY2Ugb3IgYXMgYW4gZW1iZWRkZWQgcHJvcGVydHkgaW4gdGhlIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldEdyb3VwYCB0eXBlLiBOb3RlIHRoYXQgc29tZSBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRgIHByb3BlcnRpZXMgYXJlIHZhbGlkIG9ubHkgd2hlbiB1c2VkIHdpdGhpbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRHcm91cGAgLlxuICpcbiAqIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0NoYW5nZVJlc291cmNlUmVjb3JkU2V0c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ2hhbmdlUmVzb3VyY2VSZWNvcmRTZXRzLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIEFQSSBSZWZlcmVuY2UqIC5cbiAqXG4gKiBAY2xvdWRmb3JtYXRpb25SZXNvdXJjZSBBV1M6OlJvdXRlNTM6OlJlY29yZFNldFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuUmVjb3JkU2V0IGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0XCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5SZWNvcmRTZXQge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmblJlY29yZFNldFByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5SZWNvcmRTZXQoc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9yIGBDaGFuZ2VSZXNvdXJjZVJlY29yZFNldHNgIHJlcXVlc3RzLCB0aGUgbmFtZSBvZiB0aGUgcmVjb3JkIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlLCB1cGRhdGUsIG9yIGRlbGV0ZS4gRm9yIGBMaXN0UmVzb3VyY2VSZWNvcmRTZXRzYCByZXNwb25zZXMsIHRoZSBuYW1lIG9mIGEgcmVjb3JkIGluIHRoZSBzcGVjaWZpZWQgaG9zdGVkIHpvbmUuXG4gICAgICpcbiAgICAgKiAqQ2hhbmdlUmVzb3VyY2VSZWNvcmRTZXRzIE9ubHkqXG4gICAgICpcbiAgICAgKiBFbnRlciBhIGZ1bGx5IHF1YWxpZmllZCBkb21haW4gbmFtZSwgZm9yIGV4YW1wbGUsIGB3d3cuZXhhbXBsZS5jb21gIC4gWW91IGNhbiBvcHRpb25hbGx5IGluY2x1ZGUgYSB0cmFpbGluZyBkb3QuIElmIHlvdSBvbWl0IHRoZSB0cmFpbGluZyBkb3QsIEFtYXpvbiBSb3V0ZSA1MyBhc3N1bWVzIHRoYXQgdGhlIGRvbWFpbiBuYW1lIHRoYXQgeW91IHNwZWNpZnkgaXMgZnVsbHkgcXVhbGlmaWVkLiBUaGlzIG1lYW5zIHRoYXQgUm91dGUgNTMgdHJlYXRzIGB3d3cuZXhhbXBsZS5jb21gICh3aXRob3V0IGEgdHJhaWxpbmcgZG90KSBhbmQgYHd3dy5leGFtcGxlLmNvbS5gICh3aXRoIGEgdHJhaWxpbmcgZG90KSBhcyBpZGVudGljYWwuXG4gICAgICpcbiAgICAgKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgaG93IHRvIHNwZWNpZnkgY2hhcmFjdGVycyBvdGhlciB0aGFuIGBhLXpgICwgYDAtOWAgLCBhbmQgYC1gIChoeXBoZW4pIGFuZCBob3cgdG8gc3BlY2lmeSBpbnRlcm5hdGlvbmFsaXplZCBkb21haW4gbmFtZXMsIHNlZSBbRE5TIERvbWFpbiBOYW1lIEZvcm1hdF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL0RvbWFpbk5hbWVGb3JtYXQuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGUgYXN0ZXJpc2sgKCopIHdpbGRjYXJkIHRvIHJlcGxhY2UgdGhlIGxlZnRtb3N0IGxhYmVsIGluIGEgZG9tYWluIG5hbWUsIGZvciBleGFtcGxlLCBgKi5leGFtcGxlLmNvbWAgLiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIFRoZSAqIG11c3QgcmVwbGFjZSB0aGUgZW50aXJlIGxhYmVsLiBGb3IgZXhhbXBsZSwgeW91IGNhbid0IHNwZWNpZnkgYCpwcm9kLmV4YW1wbGUuY29tYCBvciBgcHJvZCouZXhhbXBsZS5jb21gIC5cbiAgICAgKiAtIFRoZSAqIGNhbid0IHJlcGxhY2UgYW55IG9mIHRoZSBtaWRkbGUgbGFiZWxzLCBmb3IgZXhhbXBsZSwgbWFya2V0aW5nLiouZXhhbXBsZS5jb20uXG4gICAgICogLSBJZiB5b3UgaW5jbHVkZSAqIGluIGFueSBwb3NpdGlvbiBvdGhlciB0aGFuIHRoZSBsZWZ0bW9zdCBsYWJlbCBpbiBhIGRvbWFpbiBuYW1lLCBETlMgdHJlYXRzIGl0IGFzIGFuICogY2hhcmFjdGVyIChBU0NJSSA0MiksIG5vdCBhcyBhIHdpbGRjYXJkLlxuICAgICAqXG4gICAgICogPiBZb3UgY2FuJ3QgdXNlIHRoZSAqIHdpbGRjYXJkIGZvciByZXNvdXJjZSByZWNvcmRzIHNldHMgdGhhdCBoYXZlIGEgdHlwZSBvZiBOUy5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4gdXNlIHRoZSAqIHdpbGRjYXJkIGFzIHRoZSBsZWZ0bW9zdCBsYWJlbCBpbiBhIGRvbWFpbiBuYW1lLCBmb3IgZXhhbXBsZSwgYCouZXhhbXBsZS5jb21gIC4gWW91IGNhbid0IHVzZSBhbiAqIGZvciBvbmUgb2YgdGhlIG1pZGRsZSBsYWJlbHMsIGZvciBleGFtcGxlLCBgbWFya2V0aW5nLiouZXhhbXBsZS5jb21gIC4gSW4gYWRkaXRpb24sIHRoZSAqIG11c3QgcmVwbGFjZSB0aGUgZW50aXJlIGxhYmVsOyBmb3IgZXhhbXBsZSwgeW91IGNhbid0IHNwZWNpZnkgYHByb2QqLmV4YW1wbGUuY29tYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LW5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIEROUyByZWNvcmQgdHlwZS4gRm9yIGluZm9ybWF0aW9uIGFib3V0IGRpZmZlcmVudCByZWNvcmQgdHlwZXMgYW5kIGhvdyBkYXRhIGlzIGVuY29kZWQgZm9yIHRoZW0sIHNlZSBbU3VwcG9ydGVkIEROUyBSZXNvdXJjZSBSZWNvcmQgVHlwZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9SZXNvdXJjZVJlY29yZFR5cGVzLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogVmFsaWQgdmFsdWVzIGZvciBiYXNpYyByZXNvdXJjZSByZWNvcmQgc2V0czogYEFgIHwgYEFBQUFgIHwgYENBQWAgfCBgQ05BTUVgIHwgYERTYCB8IGBNWGAgfCBgTkFQVFJgIHwgYE5TYCB8IGBQVFJgIHwgYFNPQWAgfCBgU1BGYCB8IGBTUlZgIHwgYFRYVGBcbiAgICAgKlxuICAgICAqIFZhbHVlcyBmb3Igd2VpZ2h0ZWQsIGxhdGVuY3ksIGdlb2xvY2F0aW9uLCBhbmQgZmFpbG92ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHM6IGBBYCB8IGBBQUFBYCB8IGBDQUFgIHwgYENOQU1FYCB8IGBNWGAgfCBgTkFQVFJgIHwgYFBUUmAgfCBgU1BGYCB8IGBTUlZgIHwgYFRYVGAgLiBXaGVuIGNyZWF0aW5nIGEgZ3JvdXAgb2Ygd2VpZ2h0ZWQsIGxhdGVuY3ksIGdlb2xvY2F0aW9uLCBvciBmYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cywgc3BlY2lmeSB0aGUgc2FtZSB2YWx1ZSBmb3IgYWxsIG9mIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiB0aGUgZ3JvdXAuXG4gICAgICpcbiAgICAgKiBWYWxpZCB2YWx1ZXMgZm9yIG11bHRpdmFsdWUgYW5zd2VyIHJlc291cmNlIHJlY29yZCBzZXRzOiBgQWAgfCBgQUFBQWAgfCBgTVhgIHwgYE5BUFRSYCB8IGBQVFJgIHwgYFNQRmAgfCBgU1JWYCB8IGBUWFRgXG4gICAgICpcbiAgICAgKiA+IFNQRiByZWNvcmRzIHdlcmUgZm9ybWVybHkgdXNlZCB0byB2ZXJpZnkgdGhlIGlkZW50aXR5IG9mIHRoZSBzZW5kZXIgb2YgZW1haWwgbWVzc2FnZXMuIEhvd2V2ZXIsIHdlIG5vIGxvbmdlciByZWNvbW1lbmQgdGhhdCB5b3UgY3JlYXRlIHJlc291cmNlIHJlY29yZCBzZXRzIGZvciB3aGljaCB0aGUgdmFsdWUgb2YgYFR5cGVgIGlzIGBTUEZgIC4gUkZDIDcyMDgsICpTZW5kZXIgUG9saWN5IEZyYW1ld29yayAoU1BGKSBmb3IgQXV0aG9yaXppbmcgVXNlIG9mIERvbWFpbnMgaW4gRW1haWwsIFZlcnNpb24gMSogLCBoYXMgYmVlbiB1cGRhdGVkIHRvIHNheSwgXCIuLi5bSV10cyBleGlzdGVuY2UgYW5kIG1lY2hhbmlzbSBkZWZpbmVkIGluIFtSRkM0NDA4XSBoYXZlIGxlZCB0byBzb21lIGludGVyb3BlcmFiaWxpdHkgaXNzdWVzLiBBY2NvcmRpbmdseSwgaXRzIHVzZSBpcyBubyBsb25nZXIgYXBwcm9wcmlhdGUgZm9yIFNQRiB2ZXJzaW9uIDE7IGltcGxlbWVudGF0aW9ucyBhcmUgbm90IHRvIHVzZSBpdC5cIiBJbiBSRkMgNzIwOCwgc2VlIHNlY3Rpb24gMTQuMSwgW1RoZSBTUEYgRE5TIFJlY29yZCBUeXBlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNzIwOCNzZWN0aW9uLTE0LjEpIC5cbiAgICAgKlxuICAgICAqIFZhbHVlcyBmb3IgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHM6XG4gICAgICpcbiAgICAgKiAtICpBbWF6b24gQVBJIEdhdGV3YXkgY3VzdG9tIHJlZ2lvbmFsIEFQSXMgYW5kIGVkZ2Utb3B0aW1pemVkIEFQSXM6KiBgQWBcbiAgICAgKiAtICpDbG91ZEZyb250IGRpc3RyaWJ1dGlvbnM6KiBgQWBcbiAgICAgKlxuICAgICAqIElmIElQdjYgaXMgZW5hYmxlZCBmb3IgdGhlIGRpc3RyaWJ1dGlvbiwgY3JlYXRlIHR3byByZXNvdXJjZSByZWNvcmQgc2V0cyB0byByb3V0ZSB0cmFmZmljIHRvIHlvdXIgZGlzdHJpYnV0aW9uLCBvbmUgd2l0aCBhIHZhbHVlIG9mIGBBYCBhbmQgb25lIHdpdGggYSB2YWx1ZSBvZiBgQUFBQWAgLlxuICAgICAqIC0gKkFtYXpvbiBBUEkgR2F0ZXdheSBlbnZpcm9ubWVudCB0aGF0IGhhcyBhIHJlZ2lvbmFsaXplZCBzdWJkb21haW4qIDogYEFgXG4gICAgICogLSAqRUxCIGxvYWQgYmFsYW5jZXJzOiogYEFgIHwgYEFBQUFgXG4gICAgICogLSAqQW1hem9uIFMzIGJ1Y2tldHM6KiBgQWBcbiAgICAgKiAtICpBbWF6b24gVmlydHVhbCBQcml2YXRlIENsb3VkIGludGVyZmFjZSBWUEMgZW5kcG9pbnRzKiBgQWBcbiAgICAgKiAtICpBbm90aGVyIHJlc291cmNlIHJlY29yZCBzZXQgaW4gdGhpcyBob3N0ZWQgem9uZToqIFNwZWNpZnkgdGhlIHR5cGUgb2YgdGhlIHJlc291cmNlIHJlY29yZCBzZXQgdGhhdCB5b3UncmUgY3JlYXRpbmcgdGhlIGFsaWFzIGZvci4gQWxsIHZhbHVlcyBhcmUgc3VwcG9ydGVkIGV4Y2VwdCBgTlNgIGFuZCBgU09BYCAuXG4gICAgICpcbiAgICAgKiA+IElmIHlvdSdyZSBjcmVhdGluZyBhbiBhbGlhcyByZWNvcmQgdGhhdCBoYXMgdGhlIHNhbWUgbmFtZSBhcyB0aGUgaG9zdGVkIHpvbmUgKGtub3duIGFzIHRoZSB6b25lIGFwZXgpLCB5b3UgY2FuJ3Qgcm91dGUgdHJhZmZpYyB0byBhIHJlY29yZCBmb3Igd2hpY2ggdGhlIHZhbHVlIG9mIGBUeXBlYCBpcyBgQ05BTUVgIC4gVGhpcyBpcyBiZWNhdXNlIHRoZSBhbGlhcyByZWNvcmQgbXVzdCBoYXZlIHRoZSBzYW1lIHR5cGUgYXMgdGhlIHJlY29yZCB5b3UncmUgcm91dGluZyB0cmFmZmljIHRvLCBhbmQgY3JlYXRpbmcgYSBDTkFNRSByZWNvcmQgZm9yIHRoZSB6b25lIGFwZXggaXNuJ3Qgc3VwcG9ydGVkIGV2ZW4gZm9yIGFuIGFsaWFzIHJlY29yZC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtdHlwZVxuICAgICAqL1xuICAgIHB1YmxpYyB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiAqQWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgb25seToqIEluZm9ybWF0aW9uIGFib3V0IHRoZSBBV1MgcmVzb3VyY2UsIHN1Y2ggYXMgYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiBvciBhbiBBbWF6b24gUzMgYnVja2V0LCB0aGF0IHlvdSB3YW50IHRvIHJvdXRlIHRyYWZmaWMgdG8uXG4gICAgICpcbiAgICAgKiBJZiB5b3UncmUgY3JlYXRpbmcgcmVzb3VyY2UgcmVjb3JkcyBzZXRzIGZvciBhIHByaXZhdGUgaG9zdGVkIHpvbmUsIG5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gWW91IGNhbid0IGNyZWF0ZSBhbiBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSB0byByb3V0ZSB0cmFmZmljIHRvIGEgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24uXG4gICAgICogLSBGb3IgaW5mb3JtYXRpb24gYWJvdXQgY3JlYXRpbmcgZmFpbG92ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gYSBwcml2YXRlIGhvc3RlZCB6b25lLCBzZWUgW0NvbmZpZ3VyaW5nIEZhaWxvdmVyIGluIGEgUHJpdmF0ZSBIb3N0ZWQgWm9uZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1wcml2YXRlLWhvc3RlZC16b25lcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtYWxpYXN0YXJnZXRcbiAgICAgKi9cbiAgICBwdWJsaWMgYWxpYXNUYXJnZXQ6IENmblJlY29yZFNldC5BbGlhc1RhcmdldFByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9iamVjdCB0aGF0IGlzIHNwZWNpZmllZCBpbiByZXNvdXJjZSByZWNvcmQgc2V0IG9iamVjdCB3aGVuIHlvdSBhcmUgbGlua2luZyBhIHJlc291cmNlIHJlY29yZCBzZXQgdG8gYSBDSURSIGxvY2F0aW9uLlxuICAgICAqXG4gICAgICogQSBgTG9jYXRpb25OYW1lYCB3aXRoIGFuIGFzdGVyaXNrIOKAnCrigJ0gY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGEgZGVmYXVsdCBDSURSIHJlY29yZC4gYENvbGxlY3Rpb25JZGAgaXMgc3RpbGwgcmVxdWlyZWQgZm9yIGRlZmF1bHQgcmVjb3JkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1jaWRycm91dGluZ2NvbmZpZ1xuICAgICAqL1xuICAgIHB1YmxpYyBjaWRyUm91dGluZ0NvbmZpZzogQ2ZuUmVjb3JkU2V0LkNpZHJSb3V0aW5nQ29uZmlnUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiAqT3B0aW9uYWw6KiBBbnkgY29tbWVudHMgeW91IHdhbnQgdG8gaW5jbHVkZSBhYm91dCBhIGNoYW5nZSBiYXRjaCByZXF1ZXN0LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1jb21tZW50XG4gICAgICovXG4gICAgcHVibGljIGNvbW1lbnQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqICpGYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cyBvbmx5OiogVG8gY29uZmlndXJlIGZhaWxvdmVyLCB5b3UgYWRkIHRoZSBgRmFpbG92ZXJgIGVsZW1lbnQgdG8gdHdvIHJlc291cmNlIHJlY29yZCBzZXRzLiBGb3Igb25lIHJlc291cmNlIHJlY29yZCBzZXQsIHlvdSBzcGVjaWZ5IGBQUklNQVJZYCBhcyB0aGUgdmFsdWUgZm9yIGBGYWlsb3ZlcmAgOyBmb3IgdGhlIG90aGVyIHJlc291cmNlIHJlY29yZCBzZXQsIHlvdSBzcGVjaWZ5IGBTRUNPTkRBUllgIC4gSW4gYWRkaXRpb24sIHlvdSBpbmNsdWRlIHRoZSBgSGVhbHRoQ2hlY2tJZGAgZWxlbWVudCBhbmQgc3BlY2lmeSB0aGUgaGVhbHRoIGNoZWNrIHRoYXQgeW91IHdhbnQgQW1hem9uIFJvdXRlIDUzIHRvIHBlcmZvcm0gZm9yIGVhY2ggcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqIEV4Y2VwdCB3aGVyZSBub3RlZCwgdGhlIGZvbGxvd2luZyBmYWlsb3ZlciBiZWhhdmlvcnMgYXNzdW1lIHRoYXQgeW91IGhhdmUgaW5jbHVkZWQgdGhlIGBIZWFsdGhDaGVja0lkYCBlbGVtZW50IGluIGJvdGggcmVzb3VyY2UgcmVjb3JkIHNldHM6XG4gICAgICpcbiAgICAgKiAtIFdoZW4gdGhlIHByaW1hcnkgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyBoZWFsdGh5LCBSb3V0ZSA1MyByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoIHRoZSBhcHBsaWNhYmxlIHZhbHVlIGZyb20gdGhlIHByaW1hcnkgcmVzb3VyY2UgcmVjb3JkIHNldCByZWdhcmRsZXNzIG9mIHRoZSBoZWFsdGggb2YgdGhlIHNlY29uZGFyeSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqIC0gV2hlbiB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIHVuaGVhbHRoeSBhbmQgdGhlIHNlY29uZGFyeSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIGhlYWx0aHksIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGFwcGxpY2FibGUgdmFsdWUgZnJvbSB0aGUgc2Vjb25kYXJ5IHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICogLSBXaGVuIHRoZSBzZWNvbmRhcnkgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGFwcGxpY2FibGUgdmFsdWUgZnJvbSB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0IHJlZ2FyZGxlc3Mgb2YgdGhlIGhlYWx0aCBvZiB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqIC0gSWYgeW91IG9taXQgdGhlIGBIZWFsdGhDaGVja0lkYCBlbGVtZW50IGZvciB0aGUgc2Vjb25kYXJ5IHJlc291cmNlIHJlY29yZCBzZXQsIGFuZCBpZiB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgYWx3YXlzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGFwcGxpY2FibGUgdmFsdWUgZnJvbSB0aGUgc2Vjb25kYXJ5IHJlc291cmNlIHJlY29yZCBzZXQuIFRoaXMgaXMgdHJ1ZSByZWdhcmRsZXNzIG9mIHRoZSBoZWFsdGggb2YgdGhlIGFzc29jaWF0ZWQgZW5kcG9pbnQuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuJ3QgY3JlYXRlIG5vbi1mYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgdmFsdWVzIGZvciB0aGUgYE5hbWVgIGFuZCBgVHlwZWAgZWxlbWVudHMgYXMgZmFpbG92ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICpcbiAgICAgKiBGb3IgZmFpbG92ZXIgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMsIHlvdSBtdXN0IGFsc28gaW5jbHVkZSB0aGUgYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCBlbGVtZW50IGFuZCBzZXQgdGhlIHZhbHVlIHRvIHRydWUuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBjb25maWd1cmluZyBmYWlsb3ZlciBmb3IgUm91dGUgNTMsIHNlZSB0aGUgZm9sbG93aW5nIHRvcGljcyBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIDpcbiAgICAgKlxuICAgICAqIC0gW1JvdXRlIDUzIEhlYWx0aCBDaGVja3MgYW5kIEROUyBGYWlsb3Zlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci5odG1sKVxuICAgICAqIC0gW0NvbmZpZ3VyaW5nIEZhaWxvdmVyIGluIGEgUHJpdmF0ZSBIb3N0ZWQgWm9uZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1wcml2YXRlLWhvc3RlZC16b25lcy5odG1sKVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1mYWlsb3ZlclxuICAgICAqL1xuICAgIHB1YmxpYyBmYWlsb3Zlcjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogKkdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzIG9ubHk6KiBBIGNvbXBsZXggdHlwZSB0aGF0IGxldHMgeW91IGNvbnRyb2wgaG93IEFtYXpvbiBSb3V0ZSA1MyByZXNwb25kcyB0byBETlMgcXVlcmllcyBiYXNlZCBvbiB0aGUgZ2VvZ3JhcGhpYyBvcmlnaW4gb2YgdGhlIHF1ZXJ5LiBGb3IgZXhhbXBsZSwgaWYgeW91IHdhbnQgYWxsIHF1ZXJpZXMgZnJvbSBBZnJpY2EgdG8gYmUgcm91dGVkIHRvIGEgd2ViIHNlcnZlciB3aXRoIGFuIElQIGFkZHJlc3Mgb2YgYDE5Mi4wLjIuMTExYCAsIGNyZWF0ZSBhIHJlc291cmNlIHJlY29yZCBzZXQgd2l0aCBhIGBUeXBlYCBvZiBgQWAgYW5kIGEgYENvbnRpbmVudENvZGVgIG9mIGBBRmAgLlxuICAgICAqXG4gICAgICogPiBBbHRob3VnaCBjcmVhdGluZyBnZW9sb2NhdGlvbiBhbmQgZ2VvbG9jYXRpb24gYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gYSBwcml2YXRlIGhvc3RlZCB6b25lIGlzIGFsbG93ZWQsIGl0J3Mgbm90IHN1cHBvcnRlZC5cbiAgICAgKlxuICAgICAqIElmIHlvdSBjcmVhdGUgc2VwYXJhdGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yIG92ZXJsYXBwaW5nIGdlb2dyYXBoaWMgcmVnaW9ucyAoZm9yIGV4YW1wbGUsIG9uZSByZXNvdXJjZSByZWNvcmQgc2V0IGZvciBhIGNvbnRpbmVudCBhbmQgb25lIGZvciBhIGNvdW50cnkgb24gdGhlIHNhbWUgY29udGluZW50KSwgcHJpb3JpdHkgZ29lcyB0byB0aGUgc21hbGxlc3QgZ2VvZ3JhcGhpYyByZWdpb24uIFRoaXMgYWxsb3dzIHlvdSB0byByb3V0ZSBtb3N0IHF1ZXJpZXMgZm9yIGEgY29udGluZW50IHRvIG9uZSByZXNvdXJjZSBhbmQgdG8gcm91dGUgcXVlcmllcyBmb3IgYSBjb3VudHJ5IG9uIHRoYXQgY29udGluZW50IHRvIGEgZGlmZmVyZW50IHJlc291cmNlLlxuICAgICAqXG4gICAgICogWW91IGNhbid0IGNyZWF0ZSB0d28gZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBzcGVjaWZ5IHRoZSBzYW1lIGdlb2dyYXBoaWMgbG9jYXRpb24uXG4gICAgICpcbiAgICAgKiBUaGUgdmFsdWUgYCpgIGluIHRoZSBgQ291bnRyeUNvZGVgIGVsZW1lbnQgbWF0Y2hlcyBhbGwgZ2VvZ3JhcGhpYyBsb2NhdGlvbnMgdGhhdCBhcmVuJ3Qgc3BlY2lmaWVkIGluIG90aGVyIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSB2YWx1ZXMgZm9yIHRoZSBgTmFtZWAgYW5kIGBUeXBlYCBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqID4gR2VvbG9jYXRpb24gd29ya3MgYnkgbWFwcGluZyBJUCBhZGRyZXNzZXMgdG8gbG9jYXRpb25zLiBIb3dldmVyLCBzb21lIElQIGFkZHJlc3NlcyBhcmVuJ3QgbWFwcGVkIHRvIGdlb2dyYXBoaWMgbG9jYXRpb25zLCBzbyBldmVuIGlmIHlvdSBjcmVhdGUgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBjb3ZlciBhbGwgc2V2ZW4gY29udGluZW50cywgUm91dGUgNTMgd2lsbCByZWNlaXZlIHNvbWUgRE5TIHF1ZXJpZXMgZnJvbSBsb2NhdGlvbnMgdGhhdCBpdCBjYW4ndCBpZGVudGlmeS4gV2UgcmVjb21tZW5kIHRoYXQgeW91IGNyZWF0ZSBhIHJlc291cmNlIHJlY29yZCBzZXQgZm9yIHdoaWNoIHRoZSB2YWx1ZSBvZiBgQ291bnRyeUNvZGVgIGlzIGAqYCAuIFR3byBncm91cHMgb2YgcXVlcmllcyBhcmUgcm91dGVkIHRvIHRoZSByZXNvdXJjZSB0aGF0IHlvdSBzcGVjaWZ5IGluIHRoaXMgcmVjb3JkOiBxdWVyaWVzIHRoYXQgY29tZSBmcm9tIGxvY2F0aW9ucyBmb3Igd2hpY2ggeW91IGhhdmVuJ3QgY3JlYXRlZCBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cyBhbmQgcXVlcmllcyBmcm9tIElQIGFkZHJlc3NlcyB0aGF0IGFyZW4ndCBtYXBwZWQgdG8gYSBsb2NhdGlvbi4gSWYgeW91IGRvbid0IGNyZWF0ZSBhIGAqYCByZXNvdXJjZSByZWNvcmQgc2V0LCBSb3V0ZSA1MyByZXR1cm5zIGEgXCJubyBhbnN3ZXJcIiByZXNwb25zZSBmb3IgcXVlcmllcyBmcm9tIHRob3NlIGxvY2F0aW9ucy5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4ndCBjcmVhdGUgbm9uLWdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSB2YWx1ZXMgZm9yIHRoZSBgTmFtZWAgYW5kIGBUeXBlYCBlbGVtZW50cyBhcyBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtZ2VvbG9jYXRpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2VvTG9jYXRpb246IENmblJlY29yZFNldC5HZW9Mb2NhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogSWYgeW91IHdhbnQgQW1hem9uIFJvdXRlIDUzIHRvIHJldHVybiB0aGlzIHJlc291cmNlIHJlY29yZCBzZXQgaW4gcmVzcG9uc2UgdG8gYSBETlMgcXVlcnkgb25seSB3aGVuIHRoZSBzdGF0dXMgb2YgYSBoZWFsdGggY2hlY2sgaXMgaGVhbHRoeSwgaW5jbHVkZSB0aGUgYEhlYWx0aENoZWNrSWRgIGVsZW1lbnQgYW5kIHNwZWNpZnkgdGhlIElEIG9mIHRoZSBhcHBsaWNhYmxlIGhlYWx0aCBjaGVjay5cbiAgICAgKlxuICAgICAqIFJvdXRlIDUzIGRldGVybWluZXMgd2hldGhlciBhIHJlc291cmNlIHJlY29yZCBzZXQgaXMgaGVhbHRoeSBiYXNlZCBvbiBvbmUgb2YgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gQnkgcGVyaW9kaWNhbGx5IHNlbmRpbmcgYSByZXF1ZXN0IHRvIHRoZSBlbmRwb2ludCB0aGF0IGlzIHNwZWNpZmllZCBpbiB0aGUgaGVhbHRoIGNoZWNrXG4gICAgICogLSBCeSBhZ2dyZWdhdGluZyB0aGUgc3RhdHVzIG9mIGEgc3BlY2lmaWVkIGdyb3VwIG9mIGhlYWx0aCBjaGVja3MgKGNhbGN1bGF0ZWQgaGVhbHRoIGNoZWNrcylcbiAgICAgKiAtIEJ5IGRldGVybWluaW5nIHRoZSBjdXJyZW50IHN0YXRlIG9mIGEgQ2xvdWRXYXRjaCBhbGFybSAoQ2xvdWRXYXRjaCBtZXRyaWMgaGVhbHRoIGNoZWNrcylcbiAgICAgKlxuICAgICAqID4gUm91dGUgNTMgZG9lc24ndCBjaGVjayB0aGUgaGVhbHRoIG9mIHRoZSBlbmRwb2ludCB0aGF0IGlzIHNwZWNpZmllZCBpbiB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldCwgZm9yIGV4YW1wbGUsIHRoZSBlbmRwb2ludCBzcGVjaWZpZWQgYnkgdGhlIElQIGFkZHJlc3MgaW4gdGhlIGBWYWx1ZWAgZWxlbWVudC4gV2hlbiB5b3UgYWRkIGEgYEhlYWx0aENoZWNrSWRgIGVsZW1lbnQgdG8gYSByZXNvdXJjZSByZWNvcmQgc2V0LCBSb3V0ZSA1MyBjaGVja3MgdGhlIGhlYWx0aCBvZiB0aGUgZW5kcG9pbnQgdGhhdCB5b3Ugc3BlY2lmaWVkIGluIHRoZSBoZWFsdGggY2hlY2suXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIHRoZSBmb2xsb3dpbmcgdG9waWNzIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogOlxuICAgICAqXG4gICAgICogLSBbSG93IEFtYXpvbiBSb3V0ZSA1MyBEZXRlcm1pbmVzIFdoZXRoZXIgYW4gRW5kcG9pbnQgSXMgSGVhbHRoeV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1kZXRlcm1pbmluZy1oZWFsdGgtb2YtZW5kcG9pbnRzLmh0bWwpXG4gICAgICogLSBbUm91dGUgNTMgSGVhbHRoIENoZWNrcyBhbmQgRE5TIEZhaWxvdmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLmh0bWwpXG4gICAgICogLSBbQ29uZmlndXJpbmcgRmFpbG92ZXIgaW4gYSBQcml2YXRlIEhvc3RlZCBab25lXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLXByaXZhdGUtaG9zdGVkLXpvbmVzLmh0bWwpXG4gICAgICpcbiAgICAgKiAqV2hlbiB0byBTcGVjaWZ5IEhlYWx0aENoZWNrSWQqXG4gICAgICpcbiAgICAgKiBTcGVjaWZ5aW5nIGEgdmFsdWUgZm9yIGBIZWFsdGhDaGVja0lkYCBpcyB1c2VmdWwgb25seSB3aGVuIFJvdXRlIDUzIGlzIGNob29zaW5nIGJldHdlZW4gdHdvIG9yIG1vcmUgcmVzb3VyY2UgcmVjb3JkIHNldHMgdG8gcmVzcG9uZCB0byBhIEROUyBxdWVyeSwgYW5kIHlvdSB3YW50IFJvdXRlIDUzIHRvIGJhc2UgdGhlIGNob2ljZSBpbiBwYXJ0IG9uIHRoZSBzdGF0dXMgb2YgYSBoZWFsdGggY2hlY2suIENvbmZpZ3VyaW5nIGhlYWx0aCBjaGVja3MgbWFrZXMgc2Vuc2Ugb25seSBpbiB0aGUgZm9sbG93aW5nIGNvbmZpZ3VyYXRpb25zOlxuICAgICAqXG4gICAgICogLSAqTm9uLWFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzKiA6IFlvdSdyZSBjaGVja2luZyB0aGUgaGVhbHRoIG9mIGEgZ3JvdXAgb2Ygbm9uLWFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSByb3V0aW5nIHBvbGljeSwgbmFtZSwgYW5kIHR5cGUgKHN1Y2ggYXMgbXVsdGlwbGUgd2VpZ2h0ZWQgcmVjb3JkcyBuYW1lZCB3d3cuZXhhbXBsZS5jb20gd2l0aCBhIHR5cGUgb2YgQSkgYW5kIHlvdSBzcGVjaWZ5IGhlYWx0aCBjaGVjayBJRHMgZm9yIGFsbCB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgaGVhbHRoIGNoZWNrIHN0YXR1cyBmb3IgYSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIGhlYWx0aHksIFJvdXRlIDUzIGluY2x1ZGVzIHRoZSByZWNvcmQgYW1vbmcgdGhlIHJlY29yZHMgdGhhdCBpdCByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoLlxuICAgICAqXG4gICAgICogSWYgdGhlIGhlYWx0aCBjaGVjayBzdGF0dXMgZm9yIGEgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIHN0b3BzIHJlc3BvbmRpbmcgdG8gRE5TIHF1ZXJpZXMgdXNpbmcgdGhlIHZhbHVlIGZvciB0aGF0IHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgaGVhbHRoIGNoZWNrIHN0YXR1cyBmb3IgYWxsIHJlc291cmNlIHJlY29yZCBzZXRzIGluIHRoZSBncm91cCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIGNvbnNpZGVycyBhbGwgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gdGhlIGdyb3VwIGhlYWx0aHkgYW5kIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIGFjY29yZGluZ2x5LlxuICAgICAqIC0gKkFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzKiA6IFlvdSBzcGVjaWZ5IHRoZSBmb2xsb3dpbmcgc2V0dGluZ3M6XG4gICAgICpcbiAgICAgKiAtIFlvdSBzZXQgYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCB0byB0cnVlIGZvciBhbiBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IGluIGEgZ3JvdXAgb2YgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHJvdXRpbmcgcG9saWN5LCBuYW1lLCBhbmQgdHlwZSAoc3VjaCBhcyBtdWx0aXBsZSB3ZWlnaHRlZCByZWNvcmRzIG5hbWVkIHd3dy5leGFtcGxlLmNvbSB3aXRoIGEgdHlwZSBvZiBBKS5cbiAgICAgKiAtIFlvdSBjb25maWd1cmUgdGhlIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQgdG8gcm91dGUgdHJhZmZpYyB0byBhIG5vbi1hbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IGluIHRoZSBzYW1lIGhvc3RlZCB6b25lLlxuICAgICAqIC0gWW91IHNwZWNpZnkgYSBoZWFsdGggY2hlY2sgSUQgZm9yIHRoZSBub24tYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqIElmIHRoZSBoZWFsdGggY2hlY2sgc3RhdHVzIGlzIGhlYWx0aHksIFJvdXRlIDUzIGNvbnNpZGVycyB0aGUgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldCB0byBiZSBoZWFsdGh5IGFuZCBpbmNsdWRlcyB0aGUgYWxpYXMgcmVjb3JkIGFtb25nIHRoZSByZWNvcmRzIHRoYXQgaXQgcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgd2l0aC5cbiAgICAgKlxuICAgICAqIElmIHRoZSBoZWFsdGggY2hlY2sgc3RhdHVzIGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgc3RvcHMgcmVzcG9uZGluZyB0byBETlMgcXVlcmllcyB1c2luZyB0aGUgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqID4gVGhlIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQgY2FuIGFsc28gcm91dGUgdHJhZmZpYyB0byBhICpncm91cCogb2Ygbm9uLWFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSByb3V0aW5nIHBvbGljeSwgbmFtZSwgYW5kIHR5cGUuIEluIHRoYXQgY29uZmlndXJhdGlvbiwgYXNzb2NpYXRlIGhlYWx0aCBjaGVja3Mgd2l0aCBhbGwgb2YgdGhlIHJlc291cmNlIHJlY29yZCBzZXRzIGluIHRoZSBncm91cCBvZiBub24tYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICpcbiAgICAgKiAqR2VvbG9jYXRpb24gUm91dGluZypcbiAgICAgKlxuICAgICAqIEZvciBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cywgaWYgYW4gZW5kcG9pbnQgaXMgdW5oZWFsdGh5LCBSb3V0ZSA1MyBsb29rcyBmb3IgYSByZXNvdXJjZSByZWNvcmQgc2V0IGZvciB0aGUgbGFyZ2VyLCBhc3NvY2lhdGVkIGdlb2dyYXBoaWMgcmVnaW9uLiBGb3IgZXhhbXBsZSwgc3VwcG9zZSB5b3UgaGF2ZSByZXNvdXJjZSByZWNvcmQgc2V0cyBmb3IgYSBzdGF0ZSBpbiB0aGUgVW5pdGVkIFN0YXRlcywgZm9yIHRoZSBlbnRpcmUgVW5pdGVkIFN0YXRlcywgZm9yIE5vcnRoIEFtZXJpY2EsIGFuZCBhIHJlc291cmNlIHJlY29yZCBzZXQgdGhhdCBoYXMgYCpgIGZvciBgQ291bnRyeUNvZGVgIGlzIGAqYCAsIHdoaWNoIGFwcGxpZXMgdG8gYWxsIGxvY2F0aW9ucy4gSWYgdGhlIGVuZHBvaW50IGZvciB0aGUgc3RhdGUgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIGNoZWNrcyBmb3IgaGVhbHRoeSByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiB0aGUgZm9sbG93aW5nIG9yZGVyIHVudGlsIGl0IGZpbmRzIGEgcmVzb3VyY2UgcmVjb3JkIHNldCBmb3Igd2hpY2ggdGhlIGVuZHBvaW50IGlzIGhlYWx0aHk6XG4gICAgICpcbiAgICAgKiAtIFRoZSBVbml0ZWQgU3RhdGVzXG4gICAgICogLSBOb3J0aCBBbWVyaWNhXG4gICAgICogLSBUaGUgZGVmYXVsdCByZXNvdXJjZSByZWNvcmQgc2V0XG4gICAgICpcbiAgICAgKiAqU3BlY2lmeWluZyB0aGUgSGVhbHRoIENoZWNrIEVuZHBvaW50IGJ5IERvbWFpbiBOYW1lKlxuICAgICAqXG4gICAgICogSWYgeW91ciBoZWFsdGggY2hlY2tzIHNwZWNpZnkgdGhlIGVuZHBvaW50IG9ubHkgYnkgZG9tYWluIG5hbWUsIHdlIHJlY29tbWVuZCB0aGF0IHlvdSBjcmVhdGUgYSBzZXBhcmF0ZSBoZWFsdGggY2hlY2sgZm9yIGVhY2ggZW5kcG9pbnQuIEZvciBleGFtcGxlLCBjcmVhdGUgYSBoZWFsdGggY2hlY2sgZm9yIGVhY2ggYEhUVFBgIHNlcnZlciB0aGF0IGlzIHNlcnZpbmcgY29udGVudCBmb3IgYHd3dy5leGFtcGxlLmNvbWAgLiBGb3IgdGhlIHZhbHVlIG9mIGBGdWxseVF1YWxpZmllZERvbWFpbk5hbWVgICwgc3BlY2lmeSB0aGUgZG9tYWluIG5hbWUgb2YgdGhlIHNlcnZlciAoc3VjaCBhcyBgdXMtZWFzdC0yLXd3dy5leGFtcGxlLmNvbWAgKSwgbm90IHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0cyAoIGB3d3cuZXhhbXBsZS5jb21gICkuXG4gICAgICpcbiAgICAgKiA+IEhlYWx0aCBjaGVjayByZXN1bHRzIHdpbGwgYmUgdW5wcmVkaWN0YWJsZSBpZiB5b3UgZG8gdGhlIGZvbGxvd2luZzpcbiAgICAgKiA+XG4gICAgICogPiAtIENyZWF0ZSBhIGhlYWx0aCBjaGVjayB0aGF0IGhhcyB0aGUgc2FtZSB2YWx1ZSBmb3IgYEZ1bGx5UXVhbGlmaWVkRG9tYWluTmFtZWAgYXMgdGhlIG5hbWUgb2YgYSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAqID4gLSBBc3NvY2lhdGUgdGhhdCBoZWFsdGggY2hlY2sgd2l0aCB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtaGVhbHRoY2hlY2tpZFxuICAgICAqL1xuICAgIHB1YmxpYyBoZWFsdGhDaGVja0lkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgSUQgb2YgdGhlIGhvc3RlZCB6b25lIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlIHJlY29yZHMgaW4uXG4gICAgICpcbiAgICAgKiBTcGVjaWZ5IGVpdGhlciBgSG9zdGVkWm9uZU5hbWVgIG9yIGBIb3N0ZWRab25lSWRgICwgYnV0IG5vdCBib3RoLiBJZiB5b3UgaGF2ZSBtdWx0aXBsZSBob3N0ZWQgem9uZXMgd2l0aCB0aGUgc2FtZSBkb21haW4gbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgaG9zdGVkIHpvbmUgdXNpbmcgYEhvc3RlZFpvbmVJZGAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1ob3N0ZWR6b25laWRcbiAgICAgKi9cbiAgICBwdWJsaWMgaG9zdGVkWm9uZUlkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgaG9zdGVkIHpvbmUgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUgcmVjb3JkcyBpbi4gWW91IG11c3QgaW5jbHVkZSBhIHRyYWlsaW5nIGRvdCAoZm9yIGV4YW1wbGUsIGB3d3cuZXhhbXBsZS5jb20uYCApIGFzIHBhcnQgb2YgdGhlIGBIb3N0ZWRab25lTmFtZWAgLlxuICAgICAqXG4gICAgICogV2hlbiB5b3UgY3JlYXRlIGEgc3RhY2sgdXNpbmcgYW4gQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXQgdGhhdCBzcGVjaWZpZXMgYEhvc3RlZFpvbmVOYW1lYCAsIEFXUyBDbG91ZEZvcm1hdGlvbiBhdHRlbXB0cyB0byBmaW5kIGEgaG9zdGVkIHpvbmUgd2hvc2UgbmFtZSBtYXRjaGVzIHRoZSBIb3N0ZWRab25lTmFtZS4gSWYgQVdTIENsb3VkRm9ybWF0aW9uIGNhbm5vdCBmaW5kIGEgaG9zdGVkIHpvbmUgd2l0aCBhIG1hdGNoaW5nIGRvbWFpbiBuYW1lLCBvciBpZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIGhvc3RlZCB6b25lIHdpdGggdGhlIHNwZWNpZmllZCBkb21haW4gbmFtZSwgQVdTIENsb3VkRm9ybWF0aW9uIHdpbGwgbm90IGNyZWF0ZSB0aGUgc3RhY2suXG4gICAgICpcbiAgICAgKiBTcGVjaWZ5IGVpdGhlciBgSG9zdGVkWm9uZU5hbWVgIG9yIGBIb3N0ZWRab25lSWRgICwgYnV0IG5vdCBib3RoLiBJZiB5b3UgaGF2ZSBtdWx0aXBsZSBob3N0ZWQgem9uZXMgd2l0aCB0aGUgc2FtZSBkb21haW4gbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgaG9zdGVkIHpvbmUgdXNpbmcgYEhvc3RlZFpvbmVJZGAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1ob3N0ZWR6b25lbmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyBob3N0ZWRab25lTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogKk11bHRpdmFsdWUgYW5zd2VyIHJlc291cmNlIHJlY29yZCBzZXRzIG9ubHkqIDogVG8gcm91dGUgdHJhZmZpYyBhcHByb3hpbWF0ZWx5IHJhbmRvbWx5IHRvIG11bHRpcGxlIHJlc291cmNlcywgc3VjaCBhcyB3ZWIgc2VydmVycywgY3JlYXRlIG9uZSBtdWx0aXZhbHVlIGFuc3dlciByZWNvcmQgZm9yIGVhY2ggcmVzb3VyY2UgYW5kIHNwZWNpZnkgYHRydWVgIGZvciBgTXVsdGlWYWx1ZUFuc3dlcmAgLiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIElmIHlvdSBhc3NvY2lhdGUgYSBoZWFsdGggY2hlY2sgd2l0aCBhIG11bHRpdmFsdWUgYW5zd2VyIHJlc291cmNlIHJlY29yZCBzZXQsIEFtYXpvbiBSb3V0ZSA1MyByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIElQIGFkZHJlc3Mgb25seSB3aGVuIHRoZSBoZWFsdGggY2hlY2sgaXMgaGVhbHRoeS5cbiAgICAgKiAtIElmIHlvdSBkb24ndCBhc3NvY2lhdGUgYSBoZWFsdGggY2hlY2sgd2l0aCBhIG11bHRpdmFsdWUgYW5zd2VyIHJlY29yZCwgUm91dGUgNTMgYWx3YXlzIGNvbnNpZGVycyB0aGUgcmVjb3JkIHRvIGJlIGhlYWx0aHkuXG4gICAgICogLSBSb3V0ZSA1MyByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoIHVwIHRvIGVpZ2h0IGhlYWx0aHkgcmVjb3JkczsgaWYgeW91IGhhdmUgZWlnaHQgb3IgZmV3ZXIgaGVhbHRoeSByZWNvcmRzLCBSb3V0ZSA1MyByZXNwb25kcyB0byBhbGwgRE5TIHF1ZXJpZXMgd2l0aCBhbGwgdGhlIGhlYWx0aHkgcmVjb3Jkcy5cbiAgICAgKiAtIElmIHlvdSBoYXZlIG1vcmUgdGhhbiBlaWdodCBoZWFsdGh5IHJlY29yZHMsIFJvdXRlIDUzIHJlc3BvbmRzIHRvIGRpZmZlcmVudCBETlMgcmVzb2x2ZXJzIHdpdGggZGlmZmVyZW50IGNvbWJpbmF0aW9ucyBvZiBoZWFsdGh5IHJlY29yZHMuXG4gICAgICogLSBXaGVuIGFsbCByZWNvcmRzIGFyZSB1bmhlYWx0aHksIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdXAgdG8gZWlnaHQgdW5oZWFsdGh5IHJlY29yZHMuXG4gICAgICogLSBJZiBhIHJlc291cmNlIGJlY29tZXMgdW5hdmFpbGFibGUgYWZ0ZXIgYSByZXNvbHZlciBjYWNoZXMgYSByZXNwb25zZSwgY2xpZW50IHNvZnR3YXJlIHR5cGljYWxseSB0cmllcyBhbm90aGVyIG9mIHRoZSBJUCBhZGRyZXNzZXMgaW4gdGhlIHJlc3BvbnNlLlxuICAgICAqXG4gICAgICogWW91IGNhbid0IGNyZWF0ZSBtdWx0aXZhbHVlIGFuc3dlciBhbGlhcyByZWNvcmRzLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1tdWx0aXZhbHVlYW5zd2VyXG4gICAgICovXG4gICAgcHVibGljIG11bHRpVmFsdWVBbnN3ZXI6IGJvb2xlYW4gfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiAqTGF0ZW5jeS1iYXNlZCByZXNvdXJjZSByZWNvcmQgc2V0cyBvbmx5OiogVGhlIEFtYXpvbiBFQzIgUmVnaW9uIHdoZXJlIHlvdSBjcmVhdGVkIHRoZSByZXNvdXJjZSB0aGF0IHRoaXMgcmVzb3VyY2UgcmVjb3JkIHNldCByZWZlcnMgdG8uIFRoZSByZXNvdXJjZSB0eXBpY2FsbHkgaXMgYW4gQVdTIHJlc291cmNlLCBzdWNoIGFzIGFuIEVDMiBpbnN0YW5jZSBvciBhbiBFTEIgbG9hZCBiYWxhbmNlciwgYW5kIGlzIHJlZmVycmVkIHRvIGJ5IGFuIElQIGFkZHJlc3Mgb3IgYSBETlMgZG9tYWluIG5hbWUsIGRlcGVuZGluZyBvbiB0aGUgcmVjb3JkIHR5cGUuXG4gICAgICpcbiAgICAgKiBXaGVuIEFtYXpvbiBSb3V0ZSA1MyByZWNlaXZlcyBhIEROUyBxdWVyeSBmb3IgYSBkb21haW4gbmFtZSBhbmQgdHlwZSBmb3Igd2hpY2ggeW91IGhhdmUgY3JlYXRlZCBsYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXRzLCBSb3V0ZSA1MyBzZWxlY3RzIHRoZSBsYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXQgdGhhdCBoYXMgdGhlIGxvd2VzdCBsYXRlbmN5IGJldHdlZW4gdGhlIGVuZCB1c2VyIGFuZCB0aGUgYXNzb2NpYXRlZCBBbWF6b24gRUMyIFJlZ2lvbi4gUm91dGUgNTMgdGhlbiByZXR1cm5zIHRoZSB2YWx1ZSB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgc2VsZWN0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKlxuICAgICAqIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gWW91IGNhbiBvbmx5IHNwZWNpZnkgb25lIGBSZXNvdXJjZVJlY29yZGAgcGVyIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKiAtIFlvdSBjYW4gb25seSBjcmVhdGUgb25lIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldCBmb3IgZWFjaCBBbWF6b24gRUMyIFJlZ2lvbi5cbiAgICAgKiAtIFlvdSBhcmVuJ3QgcmVxdWlyZWQgdG8gY3JlYXRlIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yIGFsbCBBbWF6b24gRUMyIFJlZ2lvbnMuIFJvdXRlIDUzIHdpbGwgY2hvb3NlIHRoZSByZWdpb24gd2l0aCB0aGUgYmVzdCBsYXRlbmN5IGZyb20gYW1vbmcgdGhlIHJlZ2lvbnMgdGhhdCB5b3UgY3JlYXRlIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yLlxuICAgICAqIC0gWW91IGNhbid0IGNyZWF0ZSBub24tbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgdmFsdWVzIGZvciB0aGUgYE5hbWVgIGFuZCBgVHlwZWAgZWxlbWVudHMgYXMgbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0cy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtcmVnaW9uXG4gICAgICovXG4gICAgcHVibGljIHJlZ2lvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogT25lIG9yIG1vcmUgdmFsdWVzIHRoYXQgY29ycmVzcG9uZCB3aXRoIHRoZSB2YWx1ZSB0aGF0IHlvdSBzcGVjaWZpZWQgZm9yIHRoZSBgVHlwZWAgcHJvcGVydHkuIEZvciBleGFtcGxlLCBpZiB5b3Ugc3BlY2lmaWVkIGBBYCBmb3IgYFR5cGVgICwgeW91IHNwZWNpZnkgb25lIG9yIG1vcmUgSVAgYWRkcmVzc2VzIGluIElQdjQgZm9ybWF0IGZvciBgUmVzb3VyY2VSZWNvcmRzYCAuIEZvciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZm9ybWF0IG9mIHZhbHVlcyBmb3IgZWFjaCByZWNvcmQgdHlwZSwgc2VlIFtTdXBwb3J0ZWQgRE5TIFJlc291cmNlIFJlY29yZCBUeXBlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL1Jlc291cmNlUmVjb3JkVHlwZXMuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIFlvdSBjYW4gc3BlY2lmeSBtb3JlIHRoYW4gb25lIHZhbHVlIGZvciBhbGwgcmVjb3JkIHR5cGVzIGV4Y2VwdCBDTkFNRSBhbmQgU09BLlxuICAgICAqIC0gVGhlIG1heGltdW0gbGVuZ3RoIG9mIGEgdmFsdWUgaXMgNDAwMCBjaGFyYWN0ZXJzLlxuICAgICAqIC0gSWYgeW91J3JlIGNyZWF0aW5nIGFuIGFsaWFzIHJlY29yZCwgb21pdCBgUmVzb3VyY2VSZWNvcmRzYCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LXJlc291cmNlcmVjb3Jkc1xuICAgICAqL1xuICAgIHB1YmxpYyByZXNvdXJjZVJlY29yZHM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogKlJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSBhIHJvdXRpbmcgcG9saWN5IG90aGVyIHRoYW4gc2ltcGxlOiogQW4gaWRlbnRpZmllciB0aGF0IGRpZmZlcmVudGlhdGVzIGFtb25nIG11bHRpcGxlIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBjb21iaW5hdGlvbiBvZiBuYW1lIGFuZCB0eXBlLCBzdWNoIGFzIG11bHRpcGxlIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzIG5hbWVkIGFjbWUuZXhhbXBsZS5jb20gdGhhdCBoYXZlIGEgdHlwZSBvZiBBLiBJbiBhIGdyb3VwIG9mIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBuYW1lIGFuZCB0eXBlLCB0aGUgdmFsdWUgb2YgYFNldElkZW50aWZpZXJgIG11c3QgYmUgdW5pcXVlIGZvciBlYWNoIHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICpcbiAgICAgKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgcm91dGluZyBwb2xpY2llcywgc2VlIFtDaG9vc2luZyBhIFJvdXRpbmcgUG9saWN5XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvcm91dGluZy1wb2xpY3kuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LXNldGlkZW50aWZpZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0SWRlbnRpZmllcjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlc291cmNlIHJlY29yZCBjYWNoZSB0aW1lIHRvIGxpdmUgKFRUTCksIGluIHNlY29uZHMuIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gSWYgeW91J3JlIGNyZWF0aW5nIG9yIHVwZGF0aW5nIGFuIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQsIG9taXQgYFRUTGAgLiBBbWF6b24gUm91dGUgNTMgdXNlcyB0aGUgdmFsdWUgb2YgYFRUTGAgZm9yIHRoZSBhbGlhcyB0YXJnZXQuXG4gICAgICogLSBJZiB5b3UncmUgYXNzb2NpYXRpbmcgdGhpcyByZXNvdXJjZSByZWNvcmQgc2V0IHdpdGggYSBoZWFsdGggY2hlY2sgKGlmIHlvdSdyZSBhZGRpbmcgYSBgSGVhbHRoQ2hlY2tJZGAgZWxlbWVudCksIHdlIHJlY29tbWVuZCB0aGF0IHlvdSBzcGVjaWZ5IGEgYFRUTGAgb2YgNjAgc2Vjb25kcyBvciBsZXNzIHNvIGNsaWVudHMgcmVzcG9uZCBxdWlja2x5IHRvIGNoYW5nZXMgaW4gaGVhbHRoIHN0YXR1cy5cbiAgICAgKiAtIEFsbCBvZiB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gYSBncm91cCBvZiB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0cyBtdXN0IGhhdmUgdGhlIHNhbWUgdmFsdWUgZm9yIGBUVExgIC5cbiAgICAgKiAtIElmIGEgZ3JvdXAgb2Ygd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW5jbHVkZXMgb25lIG9yIG1vcmUgd2VpZ2h0ZWQgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yIHdoaWNoIHRoZSBhbGlhcyB0YXJnZXQgaXMgYW4gRUxCIGxvYWQgYmFsYW5jZXIsIHdlIHJlY29tbWVuZCB0aGF0IHlvdSBzcGVjaWZ5IGEgYFRUTGAgb2YgNjAgc2Vjb25kcyBmb3IgYWxsIG9mIHRoZSBub24tYWxpYXMgd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIG5hbWUgYW5kIHR5cGUuIFZhbHVlcyBvdGhlciB0aGFuIDYwIHNlY29uZHMgKHRoZSBUVEwgZm9yIGxvYWQgYmFsYW5jZXJzKSB3aWxsIGNoYW5nZSB0aGUgZWZmZWN0IG9mIHRoZSB2YWx1ZXMgdGhhdCB5b3Ugc3BlY2lmeSBmb3IgYFdlaWdodGAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC10dGxcbiAgICAgKi9cbiAgICBwdWJsaWMgdHRsOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiAqV2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgb25seToqIEFtb25nIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBjb21iaW5hdGlvbiBvZiBETlMgbmFtZSBhbmQgdHlwZSwgYSB2YWx1ZSB0aGF0IGRldGVybWluZXMgdGhlIHByb3BvcnRpb24gb2YgRE5TIHF1ZXJpZXMgdGhhdCBBbWF6b24gUm91dGUgNTMgcmVzcG9uZHMgdG8gdXNpbmcgdGhlIGN1cnJlbnQgcmVzb3VyY2UgcmVjb3JkIHNldC4gUm91dGUgNTMgY2FsY3VsYXRlcyB0aGUgc3VtIG9mIHRoZSB3ZWlnaHRzIGZvciB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIGNvbWJpbmF0aW9uIG9mIEROUyBuYW1lIGFuZCB0eXBlLiBSb3V0ZSA1MyB0aGVuIHJlc3BvbmRzIHRvIHF1ZXJpZXMgYmFzZWQgb24gdGhlIHJhdGlvIG9mIGEgcmVzb3VyY2UncyB3ZWlnaHQgdG8gdGhlIHRvdGFsLiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIFlvdSBtdXN0IHNwZWNpZnkgYSB2YWx1ZSBmb3IgdGhlIGBXZWlnaHRgIGVsZW1lbnQgZm9yIGV2ZXJ5IHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICogLSBZb3UgY2FuIG9ubHkgc3BlY2lmeSBvbmUgYFJlc291cmNlUmVjb3JkYCBwZXIgd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgKiAtIFlvdSBjYW4ndCBjcmVhdGUgbGF0ZW5jeSwgZmFpbG92ZXIsIG9yIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSB2YWx1ZXMgZm9yIHRoZSBgTmFtZWAgYW5kIGBUeXBlYCBlbGVtZW50cyBhcyB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0cy5cbiAgICAgKiAtIFlvdSBjYW4gY3JlYXRlIGEgbWF4aW11bSBvZiAxMDAgd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHZhbHVlcyBmb3IgdGhlIGBOYW1lYCBhbmQgYFR5cGVgIGVsZW1lbnRzLlxuICAgICAqIC0gRm9yIHdlaWdodGVkIChidXQgbm90IHdlaWdodGVkIGFsaWFzKSByZXNvdXJjZSByZWNvcmQgc2V0cywgaWYgeW91IHNldCBgV2VpZ2h0YCB0byBgMGAgZm9yIGEgcmVzb3VyY2UgcmVjb3JkIHNldCwgUm91dGUgNTMgbmV2ZXIgcmVzcG9uZHMgdG8gcXVlcmllcyB3aXRoIHRoZSBhcHBsaWNhYmxlIHZhbHVlIGZvciB0aGF0IHJlc291cmNlIHJlY29yZCBzZXQuIEhvd2V2ZXIsIGlmIHlvdSBzZXQgYFdlaWdodGAgdG8gYDBgIGZvciBhbGwgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIGNvbWJpbmF0aW9uIG9mIEROUyBuYW1lIGFuZCB0eXBlLCB0cmFmZmljIGlzIHJvdXRlZCB0byBhbGwgcmVzb3VyY2VzIHdpdGggZXF1YWwgcHJvYmFiaWxpdHkuXG4gICAgICpcbiAgICAgKiBUaGUgZWZmZWN0IG9mIHNldHRpbmcgYFdlaWdodGAgdG8gYDBgIGlzIGRpZmZlcmVudCB3aGVuIHlvdSBhc3NvY2lhdGUgaGVhbHRoIGNoZWNrcyB3aXRoIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtPcHRpb25zIGZvciBDb25maWd1cmluZyBSb3V0ZSA1MyBBY3RpdmUtQWN0aXZlIGFuZCBBY3RpdmUtUGFzc2l2ZSBGYWlsb3Zlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1jb25maWd1cmluZy1vcHRpb25zLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC13ZWlnaHRcbiAgICAgKi9cbiAgICBwdWJsaWMgd2VpZ2h0OiBudW1iZXIgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0YC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5SZWNvcmRTZXRQcm9wcykge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuUmVjb3JkU2V0LkNGTl9SRVNPVVJDRV9UWVBFX05BTUUsIHByb3BlcnRpZXM6IHByb3BzIH0pO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAnbmFtZScsIHRoaXMpO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAndHlwZScsIHRoaXMpO1xuXG4gICAgICAgIHRoaXMubmFtZSA9IHByb3BzLm5hbWU7XG4gICAgICAgIHRoaXMudHlwZSA9IHByb3BzLnR5cGU7XG4gICAgICAgIHRoaXMuYWxpYXNUYXJnZXQgPSBwcm9wcy5hbGlhc1RhcmdldDtcbiAgICAgICAgdGhpcy5jaWRyUm91dGluZ0NvbmZpZyA9IHByb3BzLmNpZHJSb3V0aW5nQ29uZmlnO1xuICAgICAgICB0aGlzLmNvbW1lbnQgPSBwcm9wcy5jb21tZW50O1xuICAgICAgICB0aGlzLmZhaWxvdmVyID0gcHJvcHMuZmFpbG92ZXI7XG4gICAgICAgIHRoaXMuZ2VvTG9jYXRpb24gPSBwcm9wcy5nZW9Mb2NhdGlvbjtcbiAgICAgICAgdGhpcy5oZWFsdGhDaGVja0lkID0gcHJvcHMuaGVhbHRoQ2hlY2tJZDtcbiAgICAgICAgdGhpcy5ob3N0ZWRab25lSWQgPSBwcm9wcy5ob3N0ZWRab25lSWQ7XG4gICAgICAgIHRoaXMuaG9zdGVkWm9uZU5hbWUgPSBwcm9wcy5ob3N0ZWRab25lTmFtZTtcbiAgICAgICAgdGhpcy5tdWx0aVZhbHVlQW5zd2VyID0gcHJvcHMubXVsdGlWYWx1ZUFuc3dlcjtcbiAgICAgICAgdGhpcy5yZWdpb24gPSBwcm9wcy5yZWdpb247XG4gICAgICAgIHRoaXMucmVzb3VyY2VSZWNvcmRzID0gcHJvcHMucmVzb3VyY2VSZWNvcmRzO1xuICAgICAgICB0aGlzLnNldElkZW50aWZpZXIgPSBwcm9wcy5zZXRJZGVudGlmaWVyO1xuICAgICAgICB0aGlzLnR0bCA9IHByb3BzLnR0bDtcbiAgICAgICAgdGhpcy53ZWlnaHQgPSBwcm9wcy53ZWlnaHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5SZWNvcmRTZXQuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgICAgICAgIGFsaWFzVGFyZ2V0OiB0aGlzLmFsaWFzVGFyZ2V0LFxuICAgICAgICAgICAgY2lkclJvdXRpbmdDb25maWc6IHRoaXMuY2lkclJvdXRpbmdDb25maWcsXG4gICAgICAgICAgICBjb21tZW50OiB0aGlzLmNvbW1lbnQsXG4gICAgICAgICAgICBmYWlsb3ZlcjogdGhpcy5mYWlsb3ZlcixcbiAgICAgICAgICAgIGdlb0xvY2F0aW9uOiB0aGlzLmdlb0xvY2F0aW9uLFxuICAgICAgICAgICAgaGVhbHRoQ2hlY2tJZDogdGhpcy5oZWFsdGhDaGVja0lkLFxuICAgICAgICAgICAgaG9zdGVkWm9uZUlkOiB0aGlzLmhvc3RlZFpvbmVJZCxcbiAgICAgICAgICAgIGhvc3RlZFpvbmVOYW1lOiB0aGlzLmhvc3RlZFpvbmVOYW1lLFxuICAgICAgICAgICAgbXVsdGlWYWx1ZUFuc3dlcjogdGhpcy5tdWx0aVZhbHVlQW5zd2VyLFxuICAgICAgICAgICAgcmVnaW9uOiB0aGlzLnJlZ2lvbixcbiAgICAgICAgICAgIHJlc291cmNlUmVjb3JkczogdGhpcy5yZXNvdXJjZVJlY29yZHMsXG4gICAgICAgICAgICBzZXRJZGVudGlmaWVyOiB0aGlzLnNldElkZW50aWZpZXIsXG4gICAgICAgICAgICB0dGw6IHRoaXMudHRsLFxuICAgICAgICAgICAgd2VpZ2h0OiB0aGlzLndlaWdodCxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5SZWNvcmRTZXRQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5SZWNvcmRTZXQge1xuICAgIC8qKlxuICAgICAqICpBbGlhcyByZWNvcmRzIG9ubHk6KiBJbmZvcm1hdGlvbiBhYm91dCB0aGUgQVdTIHJlc291cmNlLCBzdWNoIGFzIGEgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24gb3IgYW4gQW1hem9uIFMzIGJ1Y2tldCwgdGhhdCB5b3Ugd2FudCB0byByb3V0ZSB0cmFmZmljIHRvLlxuICAgICAqXG4gICAgICogV2hlbiBjcmVhdGluZyByZWNvcmRzIGZvciBhIHByaXZhdGUgaG9zdGVkIHpvbmUsIG5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gQ3JlYXRpbmcgZ2VvbG9jYXRpb24gYWxpYXMgYW5kIGxhdGVuY3kgYWxpYXMgcmVjb3JkcyBpbiBhIHByaXZhdGUgaG9zdGVkIHpvbmUgaXMgYWxsb3dlZCBidXQgbm90IHN1cHBvcnRlZC5cbiAgICAgKiAtIEZvciBpbmZvcm1hdGlvbiBhYm91dCBjcmVhdGluZyBmYWlsb3ZlciByZWNvcmRzIGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSwgc2VlIFtDb25maWd1cmluZyBGYWlsb3ZlciBpbiBhIFByaXZhdGUgSG9zdGVkIFpvbmVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kbnMtZmFpbG92ZXItcHJpdmF0ZS1ob3N0ZWQtem9uZXMuaHRtbCkgLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1hbGlhc3RhcmdldC5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBBbGlhc1RhcmdldFByb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqICpBbGlhcyByZWNvcmRzIG9ubHk6KiBUaGUgdmFsdWUgdGhhdCB5b3Ugc3BlY2lmeSBkZXBlbmRzIG9uIHdoZXJlIHlvdSB3YW50IHRvIHJvdXRlIHF1ZXJpZXM6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKipBbWF6b24gQVBJIEdhdGV3YXkgY3VzdG9tIHJlZ2lvbmFsIEFQSXMgYW5kIGVkZ2Utb3B0aW1pemVkIEFQSXMqKiAtIFNwZWNpZnkgdGhlIGFwcGxpY2FibGUgZG9tYWluIG5hbWUgZm9yIHlvdXIgQVBJLiBZb3UgY2FuIGdldCB0aGUgYXBwbGljYWJsZSB2YWx1ZSB1c2luZyB0aGUgQVdTIENMSSBjb21tYW5kIFtnZXQtZG9tYWluLW5hbWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvYXBpZ2F0ZXdheS9nZXQtZG9tYWluLW5hbWVzLmh0bWwpIDpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBGb3IgcmVnaW9uYWwgQVBJcywgc3BlY2lmeSB0aGUgdmFsdWUgb2YgYHJlZ2lvbmFsRG9tYWluTmFtZWAgLlxuICAgICAgICAgKiAtIEZvciBlZGdlLW9wdGltaXplZCBBUElzLCBzcGVjaWZ5IHRoZSB2YWx1ZSBvZiBgZGlzdHJpYnV0aW9uRG9tYWluTmFtZWAgLiBUaGlzIGlzIHRoZSBuYW1lIG9mIHRoZSBhc3NvY2lhdGVkIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uLCBzdWNoIGFzIGBkYTFiMmMzZDRlNS5jbG91ZGZyb250Lm5ldGAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFRoZSBuYW1lIG9mIHRoZSByZWNvcmQgdGhhdCB5b3UncmUgY3JlYXRpbmcgbXVzdCBtYXRjaCBhIGN1c3RvbSBkb21haW4gbmFtZSBmb3IgeW91ciBBUEksIHN1Y2ggYXMgYGFwaS5leGFtcGxlLmNvbWAgLlxuICAgICAgICAgKiAtICoqQW1hem9uIFZpcnR1YWwgUHJpdmF0ZSBDbG91ZCBpbnRlcmZhY2UgVlBDIGVuZHBvaW50KiogLSBFbnRlciB0aGUgQVBJIGVuZHBvaW50IGZvciB0aGUgaW50ZXJmYWNlIGVuZHBvaW50LCBzdWNoIGFzIGB2cGNlLTEyMzQ1Njc4OWFiY2RlZjAxLWV4YW1wbGUtdXMtZWFzdC0xYS5lbGFzdGljbG9hZGJhbGFuY2luZy51cy1lYXN0LTEudnBjZS5hbWF6b25hd3MuY29tYCAuIEZvciBlZGdlLW9wdGltaXplZCBBUElzLCB0aGlzIGlzIHRoZSBkb21haW4gbmFtZSBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24uIFlvdSBjYW4gZ2V0IHRoZSB2YWx1ZSBvZiBgRG5zTmFtZWAgdXNpbmcgdGhlIEFXUyBDTEkgY29tbWFuZCBbZGVzY3JpYmUtdnBjLWVuZHBvaW50c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2VjMi9kZXNjcmliZS12cGMtZW5kcG9pbnRzLmh0bWwpIC5cbiAgICAgICAgICogLSAqKkNsb3VkRnJvbnQgZGlzdHJpYnV0aW9uKiogLSBTcGVjaWZ5IHRoZSBkb21haW4gbmFtZSB0aGF0IENsb3VkRnJvbnQgYXNzaWduZWQgd2hlbiB5b3UgY3JlYXRlZCB5b3VyIGRpc3RyaWJ1dGlvbi5cbiAgICAgICAgICpcbiAgICAgICAgICogWW91ciBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiBtdXN0IGluY2x1ZGUgYW4gYWx0ZXJuYXRlIGRvbWFpbiBuYW1lIHRoYXQgbWF0Y2hlcyB0aGUgbmFtZSBvZiB0aGUgcmVjb3JkLiBGb3IgZXhhbXBsZSwgaWYgdGhlIG5hbWUgb2YgdGhlIHJlY29yZCBpcyAqYWNtZS5leGFtcGxlLmNvbSogLCB5b3VyIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uIG11c3QgaW5jbHVkZSAqYWNtZS5leGFtcGxlLmNvbSogYXMgb25lIG9mIHRoZSBhbHRlcm5hdGUgZG9tYWluIG5hbWVzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtVc2luZyBBbHRlcm5hdGUgRG9tYWluIE5hbWVzIChDTkFNRXMpXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRGcm9udC9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvQ05BTUVzLmh0bWwpIGluIHRoZSAqQW1hem9uIENsb3VkRnJvbnQgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIFlvdSBjYW4ndCBjcmVhdGUgYSByZWNvcmQgaW4gYSBwcml2YXRlIGhvc3RlZCB6b25lIHRvIHJvdXRlIHRyYWZmaWMgdG8gYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbi5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBGb3IgZmFpbG92ZXIgYWxpYXMgcmVjb3JkcywgeW91IGNhbid0IHNwZWNpZnkgYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiBmb3IgYm90aCB0aGUgcHJpbWFyeSBhbmQgc2Vjb25kYXJ5IHJlY29yZHMuIEEgZGlzdHJpYnV0aW9uIG11c3QgaW5jbHVkZSBhbiBhbHRlcm5hdGUgZG9tYWluIG5hbWUgdGhhdCBtYXRjaGVzIHRoZSBuYW1lIG9mIHRoZSByZWNvcmQuIEhvd2V2ZXIsIHRoZSBwcmltYXJ5IGFuZCBzZWNvbmRhcnkgcmVjb3JkcyBoYXZlIHRoZSBzYW1lIG5hbWUsIGFuZCB5b3UgY2FuJ3QgaW5jbHVkZSB0aGUgc2FtZSBhbHRlcm5hdGUgZG9tYWluIG5hbWUgaW4gbW9yZSB0aGFuIG9uZSBkaXN0cmlidXRpb24uXG4gICAgICAgICAqIC0gKipFbGFzdGljIEJlYW5zdGFsayBlbnZpcm9ubWVudCoqIC0gSWYgdGhlIGRvbWFpbiBuYW1lIGZvciB5b3VyIEVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50IGluY2x1ZGVzIHRoZSByZWdpb24gdGhhdCB5b3UgZGVwbG95ZWQgdGhlIGVudmlyb25tZW50IGluLCB5b3UgY2FuIGNyZWF0ZSBhbiBhbGlhcyByZWNvcmQgdGhhdCByb3V0ZXMgdHJhZmZpYyB0byB0aGUgZW52aXJvbm1lbnQuIEZvciBleGFtcGxlLCB0aGUgZG9tYWluIG5hbWUgYG15LWVudmlyb25tZW50LiAqdXMtd2VzdC0yKiAuZWxhc3RpY2JlYW5zdGFsay5jb21gIGlzIGEgcmVnaW9uYWxpemVkIGRvbWFpbiBuYW1lLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IEZvciBlbnZpcm9ubWVudHMgdGhhdCB3ZXJlIGNyZWF0ZWQgYmVmb3JlIGVhcmx5IDIwMTYsIHRoZSBkb21haW4gbmFtZSBkb2Vzbid0IGluY2x1ZGUgdGhlIHJlZ2lvbi4gVG8gcm91dGUgdHJhZmZpYyB0byB0aGVzZSBlbnZpcm9ubWVudHMsIHlvdSBtdXN0IGNyZWF0ZSBhIENOQU1FIHJlY29yZCBpbnN0ZWFkIG9mIGFuIGFsaWFzIHJlY29yZC4gTm90ZSB0aGF0IHlvdSBjYW4ndCBjcmVhdGUgYSBDTkFNRSByZWNvcmQgZm9yIHRoZSByb290IGRvbWFpbiBuYW1lLiBGb3IgZXhhbXBsZSwgaWYgeW91ciBkb21haW4gbmFtZSBpcyBleGFtcGxlLmNvbSwgeW91IGNhbiBjcmVhdGUgYSByZWNvcmQgdGhhdCByb3V0ZXMgdHJhZmZpYyBmb3IgYWNtZS5leGFtcGxlLmNvbSB0byB5b3VyIEVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50LCBidXQgeW91IGNhbid0IGNyZWF0ZSBhIHJlY29yZCB0aGF0IHJvdXRlcyB0cmFmZmljIGZvciBleGFtcGxlLmNvbSB0byB5b3VyIEVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50LlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgRWxhc3RpYyBCZWFuc3RhbGsgZW52aXJvbm1lbnRzIHRoYXQgaGF2ZSByZWdpb25hbGl6ZWQgc3ViZG9tYWlucywgc3BlY2lmeSB0aGUgYENOQU1FYCBhdHRyaWJ1dGUgZm9yIHRoZSBlbnZpcm9ubWVudC4gWW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyBtZXRob2RzIHRvIGdldCB0aGUgdmFsdWUgb2YgdGhlIENOQU1FIGF0dHJpYnV0ZTpcbiAgICAgICAgICpcbiAgICAgICAgICogLSAqQVdTIE1hbmFnZW1lbnQgQ29uc29sZSogOiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgaG93IHRvIGdldCB0aGUgdmFsdWUgYnkgdXNpbmcgdGhlIGNvbnNvbGUsIHNlZSBbVXNpbmcgQ3VzdG9tIERvbWFpbnMgd2l0aCBBV1MgRWxhc3RpYyBCZWFuc3RhbGtdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljYmVhbnN0YWxrL2xhdGVzdC9kZy9jdXN0b21kb21haW5zLmh0bWwpIGluIHRoZSAqQVdTIEVsYXN0aWMgQmVhbnN0YWxrIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKiAtICpFbGFzdGljIEJlYW5zdGFsayBBUEkqIDogVXNlIHRoZSBgRGVzY3JpYmVFbnZpcm9ubWVudHNgIGFjdGlvbiB0byBnZXQgdGhlIHZhbHVlIG9mIHRoZSBgQ05BTUVgIGF0dHJpYnV0ZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbRGVzY3JpYmVFbnZpcm9ubWVudHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljYmVhbnN0YWxrL2xhdGVzdC9hcGkvQVBJX0Rlc2NyaWJlRW52aXJvbm1lbnRzLmh0bWwpIGluIHRoZSAqQVdTIEVsYXN0aWMgQmVhbnN0YWxrIEFQSSBSZWZlcmVuY2UqIC5cbiAgICAgICAgICogLSAqQVdTIENMSSogOiBVc2UgdGhlIGBkZXNjcmliZS1lbnZpcm9ubWVudHNgIGNvbW1hbmQgdG8gZ2V0IHRoZSB2YWx1ZSBvZiB0aGUgYENOQU1FYCBhdHRyaWJ1dGUuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW2Rlc2NyaWJlLWVudmlyb25tZW50c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2VsYXN0aWNiZWFuc3RhbGsvZGVzY3JpYmUtZW52aXJvbm1lbnRzLmh0bWwpIGluIHRoZSAqQVdTIENMSSogLlxuICAgICAgICAgKiAtICoqRUxCIGxvYWQgYmFsYW5jZXIqKiAtIFNwZWNpZnkgdGhlIEROUyBuYW1lIHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBsb2FkIGJhbGFuY2VyLiBHZXQgdGhlIEROUyBuYW1lIGJ5IHVzaW5nIHRoZSBBV1MgTWFuYWdlbWVudCBDb25zb2xlICwgdGhlIEVMQiBBUEksIG9yIHRoZSBBV1MgQ0xJIC5cbiAgICAgICAgICpcbiAgICAgICAgICogLSAqQVdTIE1hbmFnZW1lbnQgQ29uc29sZSogOiBHbyB0byB0aGUgRUMyIHBhZ2UsIGNob29zZSAqTG9hZCBCYWxhbmNlcnMqIGluIHRoZSBuYXZpZ2F0aW9uIHBhbmUsIGNob29zZSB0aGUgbG9hZCBiYWxhbmNlciwgY2hvb3NlIHRoZSAqRGVzY3JpcHRpb24qIHRhYiwgYW5kIGdldCB0aGUgdmFsdWUgb2YgdGhlICpETlMgbmFtZSogZmllbGQuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSdyZSByb3V0aW5nIHRyYWZmaWMgdG8gYSBDbGFzc2ljIExvYWQgQmFsYW5jZXIsIGdldCB0aGUgdmFsdWUgdGhhdCBiZWdpbnMgd2l0aCAqZHVhbHN0YWNrKiAuIElmIHlvdSdyZSByb3V0aW5nIHRyYWZmaWMgdG8gYW5vdGhlciB0eXBlIG9mIGxvYWQgYmFsYW5jZXIsIGdldCB0aGUgdmFsdWUgdGhhdCBhcHBsaWVzIHRvIHRoZSByZWNvcmQgdHlwZSwgQSBvciBBQUFBLlxuICAgICAgICAgKiAtICpFbGFzdGljIExvYWQgQmFsYW5jaW5nIEFQSSogOiBVc2UgYERlc2NyaWJlTG9hZEJhbGFuY2Vyc2AgdG8gZ2V0IHRoZSB2YWx1ZSBvZiBgRE5TTmFtZWAgLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIHRoZSBhcHBsaWNhYmxlIGd1aWRlOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIENsYXNzaWMgTG9hZCBCYWxhbmNlcnM6IFtEZXNjcmliZUxvYWRCYWxhbmNlcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVMb2FkQmFsYW5jZXJzLmh0bWwpXG4gICAgICAgICAqIC0gQXBwbGljYXRpb24gYW5kIE5ldHdvcmsgTG9hZCBCYWxhbmNlcnM6IFtEZXNjcmliZUxvYWRCYWxhbmNlcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUxvYWRCYWxhbmNlcnMuaHRtbClcbiAgICAgICAgICogLSAqQ2xvdWRGb3JtYXRpb24gRm46OkdldEF0dCBpbnRyaW5zaWMgZnVuY3Rpb24qIDogVXNlIHRoZSBbRm46OkdldEF0dF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvaW50cmluc2ljLWZ1bmN0aW9uLXJlZmVyZW5jZS1nZXRhdHQuaHRtbCkgaW50cmluc2ljIGZ1bmN0aW9uIHRvIGdldCB0aGUgdmFsdWUgb2YgYEROU05hbWVgIDpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBbQ2xhc3NpYyBMb2FkIEJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWMyLWVsYi5odG1sI2F3cy1wcm9wZXJ0aWVzLWVjMi1lbGItcmV0dXJuLXZhbHVlcykgLlxuICAgICAgICAgKiAtIFtBcHBsaWNhdGlvbiBhbmQgTmV0d29yayBMb2FkIEJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjItbG9hZGJhbGFuY2VyLmh0bWwjYXdzLXJlc291cmNlLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjItbG9hZGJhbGFuY2VyLXJldHVybi12YWx1ZXMpIC5cbiAgICAgICAgICogLSAqQVdTIENMSSogOiBVc2UgYGRlc2NyaWJlLWxvYWQtYmFsYW5jZXJzYCB0byBnZXQgdGhlIHZhbHVlIG9mIGBETlNOYW1lYCAuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgdGhlIGFwcGxpY2FibGUgZ3VpZGU6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gQ2xhc3NpYyBMb2FkIEJhbGFuY2VyczogW2Rlc2NyaWJlLWxvYWQtYmFsYW5jZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvZWxiL2Rlc2NyaWJlLWxvYWQtYmFsYW5jZXJzLmh0bWwpXG4gICAgICAgICAqIC0gQXBwbGljYXRpb24gYW5kIE5ldHdvcmsgTG9hZCBCYWxhbmNlcnM6IFtkZXNjcmliZS1sb2FkLWJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2VsYnYyL2Rlc2NyaWJlLWxvYWQtYmFsYW5jZXJzLmh0bWwpXG4gICAgICAgICAqIC0gKipHbG9iYWwgQWNjZWxlcmF0b3IgYWNjZWxlcmF0b3IqKiAtIFNwZWNpZnkgdGhlIEROUyBuYW1lIGZvciB5b3VyIGFjY2VsZXJhdG9yOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpHbG9iYWwgQWNjZWxlcmF0b3IgQVBJKiA6IFRvIGdldCB0aGUgRE5TIG5hbWUsIHVzZSBbRGVzY3JpYmVBY2NlbGVyYXRvcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dsb2JhbC1hY2NlbGVyYXRvci9sYXRlc3QvYXBpL0FQSV9EZXNjcmliZUFjY2VsZXJhdG9yLmh0bWwpIC5cbiAgICAgICAgICogLSAqQVdTIENMSSogOiBUbyBnZXQgdGhlIEROUyBuYW1lLCB1c2UgW2Rlc2NyaWJlLWFjY2VsZXJhdG9yXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvZ2xvYmFsYWNjZWxlcmF0b3IvZGVzY3JpYmUtYWNjZWxlcmF0b3IuaHRtbCkgLlxuICAgICAgICAgKiAtICoqQW1hem9uIFMzIGJ1Y2tldCB0aGF0IGlzIGNvbmZpZ3VyZWQgYXMgYSBzdGF0aWMgd2Vic2l0ZSoqIC0gU3BlY2lmeSB0aGUgZG9tYWluIG5hbWUgb2YgdGhlIEFtYXpvbiBTMyB3ZWJzaXRlIGVuZHBvaW50IHRoYXQgeW91IGNyZWF0ZWQgdGhlIGJ1Y2tldCBpbiwgZm9yIGV4YW1wbGUsIGBzMy13ZWJzaXRlLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tYCAuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHZhbGlkIHZhbHVlcywgc2VlIHRoZSB0YWJsZSBbQW1hem9uIFMzIFdlYnNpdGUgRW5kcG9pbnRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2VuZXJhbC9sYXRlc3QvZ3IvczMuaHRtbCNzM193ZWJzaXRlX3JlZ2lvbl9lbmRwb2ludHMpIGluIHRoZSAqQW1hem9uIFdlYiBTZXJ2aWNlcyBHZW5lcmFsIFJlZmVyZW5jZSogLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB1c2luZyBTMyBidWNrZXRzIGZvciB3ZWJzaXRlcywgc2VlIFtHZXR0aW5nIFN0YXJ0ZWQgd2l0aCBBbWF6b24gUm91dGUgNTNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9nZXR0aW5nLXN0YXJ0ZWQuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlLipcbiAgICAgICAgICogLSAqKkFub3RoZXIgUm91dGUgNTMgcmVjb3JkKiogLSBTcGVjaWZ5IHRoZSB2YWx1ZSBvZiB0aGUgYE5hbWVgIGVsZW1lbnQgZm9yIGEgcmVjb3JkIGluIHRoZSBjdXJyZW50IGhvc3RlZCB6b25lLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IElmIHlvdSdyZSBjcmVhdGluZyBhbiBhbGlhcyByZWNvcmQgdGhhdCBoYXMgdGhlIHNhbWUgbmFtZSBhcyB0aGUgaG9zdGVkIHpvbmUgKGtub3duIGFzIHRoZSB6b25lIGFwZXgpLCB5b3UgY2FuJ3Qgc3BlY2lmeSB0aGUgZG9tYWluIG5hbWUgZm9yIGEgcmVjb3JkIGZvciB3aGljaCB0aGUgdmFsdWUgb2YgYFR5cGVgIGlzIGBDTkFNRWAgLiBUaGlzIGlzIGJlY2F1c2UgdGhlIGFsaWFzIHJlY29yZCBtdXN0IGhhdmUgdGhlIHNhbWUgdHlwZSBhcyB0aGUgcmVjb3JkIHRoYXQgeW91J3JlIHJvdXRpbmcgdHJhZmZpYyB0bywgYW5kIGNyZWF0aW5nIGEgQ05BTUUgcmVjb3JkIGZvciB0aGUgem9uZSBhcGV4IGlzbid0IHN1cHBvcnRlZCBldmVuIGZvciBhbiBhbGlhcyByZWNvcmQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1hbGlhc3RhcmdldC5odG1sI2Nmbi1yb3V0ZTUzLWFsaWFzdGFyZ2V0LWRuc2hvc3RuYW1lXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBkbnNOYW1lOiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiAqQXBwbGllcyBvbmx5IHRvIGFsaWFzLCBmYWlsb3ZlciBhbGlhcywgZ2VvbG9jYXRpb24gYWxpYXMsIGxhdGVuY3kgYWxpYXMsIGFuZCB3ZWlnaHRlZCBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0czoqIFdoZW4gYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCBpcyBgdHJ1ZWAgLCBhbiBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IGluaGVyaXRzIHRoZSBoZWFsdGggb2YgdGhlIHJlZmVyZW5jZWQgQVdTIHJlc291cmNlLCBzdWNoIGFzIGFuIEVMQiBsb2FkIGJhbGFuY2VyIG9yIGFub3RoZXIgcmVzb3VyY2UgcmVjb3JkIHNldCBpbiB0aGUgaG9zdGVkIHpvbmUuXG4gICAgICAgICAqXG4gICAgICAgICAqIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgICAgICpcbiAgICAgICAgICogLSAqKkNsb3VkRnJvbnQgZGlzdHJpYnV0aW9ucyoqIC0gWW91IGNhbid0IHNldCBgRXZhbHVhdGVUYXJnZXRIZWFsdGhgIHRvIGB0cnVlYCB3aGVuIHRoZSBhbGlhcyB0YXJnZXQgaXMgYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbi5cbiAgICAgICAgICogLSAqKkVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50cyB0aGF0IGhhdmUgcmVnaW9uYWxpemVkIHN1YmRvbWFpbnMqKiAtIElmIHlvdSBzcGVjaWZ5IGFuIEVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50IGluIGBETlNOYW1lYCBhbmQgdGhlIGVudmlyb25tZW50IGNvbnRhaW5zIGFuIEVMQiBsb2FkIGJhbGFuY2VyLCBFbGFzdGljIExvYWQgQmFsYW5jaW5nIHJvdXRlcyBxdWVyaWVzIG9ubHkgdG8gdGhlIGhlYWx0aHkgQW1hem9uIEVDMiBpbnN0YW5jZXMgdGhhdCBhcmUgcmVnaXN0ZXJlZCB3aXRoIHRoZSBsb2FkIGJhbGFuY2VyLiAoQW4gZW52aXJvbm1lbnQgYXV0b21hdGljYWxseSBjb250YWlucyBhbiBFTEIgbG9hZCBiYWxhbmNlciBpZiBpdCBpbmNsdWRlcyBtb3JlIHRoYW4gb25lIEFtYXpvbiBFQzIgaW5zdGFuY2UuKSBJZiB5b3Ugc2V0IGBFdmFsdWF0ZVRhcmdldEhlYWx0aGAgdG8gYHRydWVgIGFuZCBlaXRoZXIgbm8gQW1hem9uIEVDMiBpbnN0YW5jZXMgYXJlIGhlYWx0aHkgb3IgdGhlIGxvYWQgYmFsYW5jZXIgaXRzZWxmIGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgcm91dGVzIHF1ZXJpZXMgdG8gb3RoZXIgYXZhaWxhYmxlIHJlc291cmNlcyB0aGF0IGFyZSBoZWFsdGh5LCBpZiBhbnkuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHRoZSBlbnZpcm9ubWVudCBjb250YWlucyBhIHNpbmdsZSBBbWF6b24gRUMyIGluc3RhbmNlLCB0aGVyZSBhcmUgbm8gc3BlY2lhbCByZXF1aXJlbWVudHMuXG4gICAgICAgICAqIC0gKipFTEIgbG9hZCBiYWxhbmNlcnMqKiAtIEhlYWx0aCBjaGVja2luZyBiZWhhdmlvciBkZXBlbmRzIG9uIHRoZSB0eXBlIG9mIGxvYWQgYmFsYW5jZXI6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKkNsYXNzaWMgTG9hZCBCYWxhbmNlcnMqIDogSWYgeW91IHNwZWNpZnkgYW4gRUxCIENsYXNzaWMgTG9hZCBCYWxhbmNlciBpbiBgRE5TTmFtZWAgLCBFbGFzdGljIExvYWQgQmFsYW5jaW5nIHJvdXRlcyBxdWVyaWVzIG9ubHkgdG8gdGhlIGhlYWx0aHkgQW1hem9uIEVDMiBpbnN0YW5jZXMgdGhhdCBhcmUgcmVnaXN0ZXJlZCB3aXRoIHRoZSBsb2FkIGJhbGFuY2VyLiBJZiB5b3Ugc2V0IGBFdmFsdWF0ZVRhcmdldEhlYWx0aGAgdG8gYHRydWVgIGFuZCBlaXRoZXIgbm8gRUMyIGluc3RhbmNlcyBhcmUgaGVhbHRoeSBvciB0aGUgbG9hZCBiYWxhbmNlciBpdHNlbGYgaXMgdW5oZWFsdGh5LCBSb3V0ZSA1MyByb3V0ZXMgcXVlcmllcyB0byBvdGhlciByZXNvdXJjZXMuXG4gICAgICAgICAqIC0gKkFwcGxpY2F0aW9uIGFuZCBOZXR3b3JrIExvYWQgQmFsYW5jZXJzKiA6IElmIHlvdSBzcGVjaWZ5IGFuIEVMQiBBcHBsaWNhdGlvbiBvciBOZXR3b3JrIExvYWQgQmFsYW5jZXIgYW5kIHlvdSBzZXQgYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCB0byBgdHJ1ZWAgLCBSb3V0ZSA1MyByb3V0ZXMgcXVlcmllcyB0byB0aGUgbG9hZCBiYWxhbmNlciBiYXNlZCBvbiB0aGUgaGVhbHRoIG9mIHRoZSB0YXJnZXQgZ3JvdXBzIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgbG9hZCBiYWxhbmNlcjpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBGb3IgYW4gQXBwbGljYXRpb24gb3IgTmV0d29yayBMb2FkIEJhbGFuY2VyIHRvIGJlIGNvbnNpZGVyZWQgaGVhbHRoeSwgZXZlcnkgdGFyZ2V0IGdyb3VwIHRoYXQgY29udGFpbnMgdGFyZ2V0cyBtdXN0IGNvbnRhaW4gYXQgbGVhc3Qgb25lIGhlYWx0aHkgdGFyZ2V0LiBJZiBhbnkgdGFyZ2V0IGdyb3VwIGNvbnRhaW5zIG9ubHkgdW5oZWFsdGh5IHRhcmdldHMsIHRoZSBsb2FkIGJhbGFuY2VyIGlzIGNvbnNpZGVyZWQgdW5oZWFsdGh5LCBhbmQgUm91dGUgNTMgcm91dGVzIHF1ZXJpZXMgdG8gb3RoZXIgcmVzb3VyY2VzLlxuICAgICAgICAgKiAtIEEgdGFyZ2V0IGdyb3VwIHRoYXQgaGFzIG5vIHJlZ2lzdGVyZWQgdGFyZ2V0cyBpcyBjb25zaWRlcmVkIHVuaGVhbHRoeS5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBXaGVuIHlvdSBjcmVhdGUgYSBsb2FkIGJhbGFuY2VyLCB5b3UgY29uZmlndXJlIHNldHRpbmdzIGZvciBFbGFzdGljIExvYWQgQmFsYW5jaW5nIGhlYWx0aCBjaGVja3M7IHRoZXkncmUgbm90IFJvdXRlIDUzIGhlYWx0aCBjaGVja3MsIGJ1dCB0aGV5IHBlcmZvcm0gYSBzaW1pbGFyIGZ1bmN0aW9uLiBEbyBub3QgY3JlYXRlIFJvdXRlIDUzIGhlYWx0aCBjaGVja3MgZm9yIHRoZSBFQzIgaW5zdGFuY2VzIHRoYXQgeW91IHJlZ2lzdGVyIHdpdGggYW4gRUxCIGxvYWQgYmFsYW5jZXIuXG4gICAgICAgICAqIC0gKipTMyBidWNrZXRzKiogLSBUaGVyZSBhcmUgbm8gc3BlY2lhbCByZXF1aXJlbWVudHMgZm9yIHNldHRpbmcgYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCB0byBgdHJ1ZWAgd2hlbiB0aGUgYWxpYXMgdGFyZ2V0IGlzIGFuIFMzIGJ1Y2tldC5cbiAgICAgICAgICogLSAqKk90aGVyIHJlY29yZHMgaW4gdGhlIHNhbWUgaG9zdGVkIHpvbmUqKiAtIElmIHRoZSBBV1MgcmVzb3VyY2UgdGhhdCB5b3Ugc3BlY2lmeSBpbiBgRE5TTmFtZWAgaXMgYSByZWNvcmQgb3IgYSBncm91cCBvZiByZWNvcmRzIChmb3IgZXhhbXBsZSwgYSBncm91cCBvZiB3ZWlnaHRlZCByZWNvcmRzKSBidXQgaXMgbm90IGFub3RoZXIgYWxpYXMgcmVjb3JkLCB3ZSByZWNvbW1lbmQgdGhhdCB5b3UgYXNzb2NpYXRlIGEgaGVhbHRoIGNoZWNrIHdpdGggYWxsIG9mIHRoZSByZWNvcmRzIGluIHRoZSBhbGlhcyB0YXJnZXQuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1doYXQgSGFwcGVucyBXaGVuIFlvdSBPbWl0IEhlYWx0aCBDaGVja3M/XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLWNvbXBsZXgtY29uZmlncy5odG1sI2Rucy1mYWlsb3Zlci1jb21wbGV4LWNvbmZpZ3MtaGMtb21pdHRpbmcpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhbmQgZXhhbXBsZXMsIHNlZSBbQW1hem9uIFJvdXRlIDUzIEhlYWx0aCBDaGVja3MgYW5kIEROUyBGYWlsb3Zlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWFsaWFzdGFyZ2V0Lmh0bWwjY2ZuLXJvdXRlNTMtYWxpYXN0YXJnZXQtZXZhbHVhdGV0YXJnZXRoZWFsdGhcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGV2YWx1YXRlVGFyZ2V0SGVhbHRoPzogYm9vbGVhbiB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqICpBbGlhcyByZXNvdXJjZSByZWNvcmRzIHNldHMgb25seSogOiBUaGUgdmFsdWUgdXNlZCBkZXBlbmRzIG9uIHdoZXJlIHlvdSB3YW50IHRvIHJvdXRlIHRyYWZmaWM6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKipBbWF6b24gQVBJIEdhdGV3YXkgY3VzdG9tIHJlZ2lvbmFsIEFQSXMgYW5kIGVkZ2Utb3B0aW1pemVkIEFQSXMqKiAtIFNwZWNpZnkgdGhlIGhvc3RlZCB6b25lIElEIGZvciB5b3VyIEFQSS4gWW91IGNhbiBnZXQgdGhlIGFwcGxpY2FibGUgdmFsdWUgdXNpbmcgdGhlIEFXUyBDTEkgY29tbWFuZCBbZ2V0LWRvbWFpbi1uYW1lc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2FwaWdhdGV3YXkvZ2V0LWRvbWFpbi1uYW1lcy5odG1sKSA6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gRm9yIHJlZ2lvbmFsIEFQSXMsIHNwZWNpZnkgdGhlIHZhbHVlIG9mIGByZWdpb25hbEhvc3RlZFpvbmVJZGAgLlxuICAgICAgICAgKiAtIEZvciBlZGdlLW9wdGltaXplZCBBUElzLCBzcGVjaWZ5IHRoZSB2YWx1ZSBvZiBgZGlzdHJpYnV0aW9uSG9zdGVkWm9uZUlkYCAuXG4gICAgICAgICAqIC0gKipBbWF6b24gVmlydHVhbCBQcml2YXRlIENsb3VkIGludGVyZmFjZSBWUEMgZW5kcG9pbnQqKiAtIFNwZWNpZnkgdGhlIGhvc3RlZCB6b25lIElEIGZvciB5b3VyIGludGVyZmFjZSBlbmRwb2ludC4gWW91IGNhbiBnZXQgdGhlIHZhbHVlIG9mIGBIb3N0ZWRab25lSWRgIHVzaW5nIHRoZSBBV1MgQ0xJIGNvbW1hbmQgW2Rlc2NyaWJlLXZwYy1lbmRwb2ludHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGkvbGF0ZXN0L3JlZmVyZW5jZS9lYzIvZGVzY3JpYmUtdnBjLWVuZHBvaW50cy5odG1sKSAuXG4gICAgICAgICAqIC0gKipDbG91ZEZyb250IGRpc3RyaWJ1dGlvbioqIC0gU3BlY2lmeSBgWjJGRFROREFUQVFZVzJgIC4gVGhpcyBpcyBhbHdheXMgdGhlIGhvc3RlZCB6b25lIElEIHdoZW4geW91IGNyZWF0ZSBhbiBhbGlhcyByZWNvcmQgdGhhdCByb3V0ZXMgdHJhZmZpYyB0byBhIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IEFsaWFzIHJlY29yZHMgZm9yIENsb3VkRnJvbnQgY2FuJ3QgYmUgY3JlYXRlZCBpbiBhIHByaXZhdGUgem9uZS5cbiAgICAgICAgICogLSAqKkVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50KiogLSBTcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSBJRCBmb3IgdGhlIHJlZ2lvbiB0aGF0IHlvdSBjcmVhdGVkIHRoZSBlbnZpcm9ubWVudCBpbi4gVGhlIGVudmlyb25tZW50IG11c3QgaGF2ZSBhIHJlZ2lvbmFsaXplZCBzdWJkb21haW4uIEZvciBhIGxpc3Qgb2YgcmVnaW9ucyBhbmQgdGhlIGNvcnJlc3BvbmRpbmcgaG9zdGVkIHpvbmUgSURzLCBzZWUgW0FXUyBFbGFzdGljIEJlYW5zdGFsayBlbmRwb2ludHMgYW5kIHF1b3Rhc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dlbmVyYWwvbGF0ZXN0L2dyL2VsYXN0aWNiZWFuc3RhbGsuaHRtbCkgaW4gdGhlICpBbWF6b24gV2ViIFNlcnZpY2VzIEdlbmVyYWwgUmVmZXJlbmNlKiAuXG4gICAgICAgICAqIC0gKipFTEIgbG9hZCBiYWxhbmNlcioqIC0gU3BlY2lmeSB0aGUgdmFsdWUgb2YgdGhlIGhvc3RlZCB6b25lIElEIGZvciB0aGUgbG9hZCBiYWxhbmNlci4gVXNlIHRoZSBmb2xsb3dpbmcgbWV0aG9kcyB0byBnZXQgdGhlIGhvc3RlZCB6b25lIElEOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIFtTZXJ2aWNlIEVuZHBvaW50c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dlbmVyYWwvbGF0ZXN0L2dyL2VsYi5odG1sKSB0YWJsZSBpbiB0aGUgXCJFbGFzdGljIExvYWQgQmFsYW5jaW5nIEVuZHBvaW50cyBhbmQgUXVvdGFzXCIgdG9waWMgaW4gdGhlICpBbWF6b24gV2ViIFNlcnZpY2VzIEdlbmVyYWwgUmVmZXJlbmNlKiA6IFVzZSB0aGUgdmFsdWUgdGhhdCBjb3JyZXNwb25kcyB3aXRoIHRoZSByZWdpb24gdGhhdCB5b3UgY3JlYXRlZCB5b3VyIGxvYWQgYmFsYW5jZXIgaW4uIE5vdGUgdGhhdCB0aGVyZSBhcmUgc2VwYXJhdGUgY29sdW1ucyBmb3IgQXBwbGljYXRpb24gYW5kIENsYXNzaWMgTG9hZCBCYWxhbmNlcnMgYW5kIGZvciBOZXR3b3JrIExvYWQgQmFsYW5jZXJzLlxuICAgICAgICAgKiAtICpBV1MgTWFuYWdlbWVudCBDb25zb2xlKiA6IEdvIHRvIHRoZSBBbWF6b24gRUMyIHBhZ2UsIGNob29zZSAqTG9hZCBCYWxhbmNlcnMqIGluIHRoZSBuYXZpZ2F0aW9uIHBhbmUsIHNlbGVjdCB0aGUgbG9hZCBiYWxhbmNlciwgYW5kIGdldCB0aGUgdmFsdWUgb2YgdGhlICpIb3N0ZWQgem9uZSogZmllbGQgb24gdGhlICpEZXNjcmlwdGlvbiogdGFiLlxuICAgICAgICAgKiAtICpFbGFzdGljIExvYWQgQmFsYW5jaW5nIEFQSSogOiBVc2UgYERlc2NyaWJlTG9hZEJhbGFuY2Vyc2AgdG8gZ2V0IHRoZSBhcHBsaWNhYmxlIHZhbHVlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIHRoZSBhcHBsaWNhYmxlIGd1aWRlOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIENsYXNzaWMgTG9hZCBCYWxhbmNlcnM6IFVzZSBbRGVzY3JpYmVMb2FkQmFsYW5jZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlTG9hZEJhbGFuY2Vycy5odG1sKSB0byBnZXQgdGhlIHZhbHVlIG9mIGBDYW5vbmljYWxIb3N0ZWRab25lTmFtZUlEYCAuXG4gICAgICAgICAqIC0gQXBwbGljYXRpb24gYW5kIE5ldHdvcmsgTG9hZCBCYWxhbmNlcnM6IFVzZSBbRGVzY3JpYmVMb2FkQmFsYW5jZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVMb2FkQmFsYW5jZXJzLmh0bWwpIHRvIGdldCB0aGUgdmFsdWUgb2YgYENhbm9uaWNhbEhvc3RlZFpvbmVJRGAgLlxuICAgICAgICAgKiAtICpDbG91ZEZvcm1hdGlvbiBGbjo6R2V0QXR0IGludHJpbnNpYyBmdW5jdGlvbiogOiBVc2UgdGhlIFtGbjo6R2V0QXR0XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9pbnRyaW5zaWMtZnVuY3Rpb24tcmVmZXJlbmNlLWdldGF0dC5odG1sKSBpbnRyaW5zaWMgZnVuY3Rpb24gdG8gZ2V0IHRoZSBhcHBsaWNhYmxlIHZhbHVlOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIENsYXNzaWMgTG9hZCBCYWxhbmNlcnM6IEdldCBbQ2Fub25pY2FsSG9zdGVkWm9uZU5hbWVJRF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWMyLWVsYi5odG1sI2F3cy1wcm9wZXJ0aWVzLWVjMi1lbGItcmV0dXJuLXZhbHVlcykgLlxuICAgICAgICAgKiAtIEFwcGxpY2F0aW9uIGFuZCBOZXR3b3JrIExvYWQgQmFsYW5jZXJzOiBHZXQgW0Nhbm9uaWNhbEhvc3RlZFpvbmVJRF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjItbG9hZGJhbGFuY2VyLmh0bWwjYXdzLXJlc291cmNlLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjItbG9hZGJhbGFuY2VyLXJldHVybi12YWx1ZXMpIC5cbiAgICAgICAgICogLSAqQVdTIENMSSogOiBVc2UgYGRlc2NyaWJlLWxvYWQtYmFsYW5jZXJzYCB0byBnZXQgdGhlIGFwcGxpY2FibGUgdmFsdWUuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgdGhlIGFwcGxpY2FibGUgZ3VpZGU6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gQ2xhc3NpYyBMb2FkIEJhbGFuY2VyczogVXNlIFtkZXNjcmliZS1sb2FkLWJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsaS9sYXRlc3QvcmVmZXJlbmNlL2VsYi9kZXNjcmliZS1sb2FkLWJhbGFuY2Vycy5odG1sKSB0byBnZXQgdGhlIHZhbHVlIG9mIGBDYW5vbmljYWxIb3N0ZWRab25lTmFtZUlEYCAuXG4gICAgICAgICAqIC0gQXBwbGljYXRpb24gYW5kIE5ldHdvcmsgTG9hZCBCYWxhbmNlcnM6IFVzZSBbZGVzY3JpYmUtbG9hZC1iYWxhbmNlcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGkvbGF0ZXN0L3JlZmVyZW5jZS9lbGJ2Mi9kZXNjcmliZS1sb2FkLWJhbGFuY2Vycy5odG1sKSB0byBnZXQgdGhlIHZhbHVlIG9mIGBDYW5vbmljYWxIb3N0ZWRab25lSURgIC5cbiAgICAgICAgICogLSAqKkdsb2JhbCBBY2NlbGVyYXRvciBhY2NlbGVyYXRvcioqIC0gU3BlY2lmeSBgWjJCSjZYUTVGSzdVNEhgIC5cbiAgICAgICAgICogLSAqKkFuIEFtYXpvbiBTMyBidWNrZXQgY29uZmlndXJlZCBhcyBhIHN0YXRpYyB3ZWJzaXRlKiogLSBTcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSBJRCBmb3IgdGhlIHJlZ2lvbiB0aGF0IHlvdSBjcmVhdGVkIHRoZSBidWNrZXQgaW4uIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHZhbGlkIHZhbHVlcywgc2VlIHRoZSB0YWJsZSBbQW1hem9uIFMzIFdlYnNpdGUgRW5kcG9pbnRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2VuZXJhbC9sYXRlc3QvZ3IvczMuaHRtbCNzM193ZWJzaXRlX3JlZ2lvbl9lbmRwb2ludHMpIGluIHRoZSAqQW1hem9uIFdlYiBTZXJ2aWNlcyBHZW5lcmFsIFJlZmVyZW5jZSogLlxuICAgICAgICAgKiAtICoqQW5vdGhlciBSb3V0ZSA1MyByZWNvcmQgaW4geW91ciBob3N0ZWQgem9uZSoqIC0gU3BlY2lmeSB0aGUgaG9zdGVkIHpvbmUgSUQgb2YgeW91ciBob3N0ZWQgem9uZS4gKEFuIGFsaWFzIHJlY29yZCBjYW4ndCByZWZlcmVuY2UgYSByZWNvcmQgaW4gYSBkaWZmZXJlbnQgaG9zdGVkIHpvbmUuKVxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtYWxpYXN0YXJnZXQuaHRtbCNjZm4tcm91dGU1My1hbGlhc3RhcmdldC1ob3N0ZWR6b25laWRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGhvc3RlZFpvbmVJZDogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBBbGlhc1RhcmdldFByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBBbGlhc1RhcmdldFByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblJlY29yZFNldF9BbGlhc1RhcmdldFByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZG5zTmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5kbnNOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkbnNOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmRuc05hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2V2YWx1YXRlVGFyZ2V0SGVhbHRoJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5ldmFsdWF0ZVRhcmdldEhlYWx0aCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaG9zdGVkWm9uZUlkJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmhvc3RlZFpvbmVJZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaG9zdGVkWm9uZUlkJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmhvc3RlZFpvbmVJZCkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJBbGlhc1RhcmdldFByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXQuQWxpYXNUYXJnZXRgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYEFsaWFzVGFyZ2V0UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldC5BbGlhc1RhcmdldGAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5SZWNvcmRTZXRBbGlhc1RhcmdldFByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5SZWNvcmRTZXRfQWxpYXNUYXJnZXRQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgRE5TTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5kbnNOYW1lKSxcbiAgICAgICAgRXZhbHVhdGVUYXJnZXRIZWFsdGg6IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmV2YWx1YXRlVGFyZ2V0SGVhbHRoKSxcbiAgICAgICAgSG9zdGVkWm9uZUlkOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmhvc3RlZFpvbmVJZCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblJlY29yZFNldEFsaWFzVGFyZ2V0UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5SZWNvcmRTZXQuQWxpYXNUYXJnZXRQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5SZWNvcmRTZXQuQWxpYXNUYXJnZXRQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Ruc05hbWUnLCAnRE5TTmFtZScsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuRE5TTmFtZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZXZhbHVhdGVUYXJnZXRIZWFsdGgnLCAnRXZhbHVhdGVUYXJnZXRIZWFsdGgnLCBwcm9wZXJ0aWVzLkV2YWx1YXRlVGFyZ2V0SGVhbHRoICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5FdmFsdWF0ZVRhcmdldEhlYWx0aCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaG9zdGVkWm9uZUlkJywgJ0hvc3RlZFpvbmVJZCcsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuSG9zdGVkWm9uZUlkKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuUmVjb3JkU2V0IHtcbiAgICAvKipcbiAgICAgKiBUaGUgb2JqZWN0IHRoYXQgaXMgc3BlY2lmaWVkIGluIHJlc291cmNlIHJlY29yZCBzZXQgb2JqZWN0IHdoZW4geW91IGFyZSBsaW5raW5nIGEgcmVzb3VyY2UgcmVjb3JkIHNldCB0byBhIENJRFIgbG9jYXRpb24uXG4gICAgICpcbiAgICAgKiBBIGBMb2NhdGlvbk5hbWVgIHdpdGggYW4gYXN0ZXJpc2sg4oCcKuKAnSBjYW4gYmUgdXNlZCB0byBjcmVhdGUgYSBkZWZhdWx0IENJRFIgcmVjb3JkLiBgQ29sbGVjdGlvbklkYCBpcyBzdGlsbCByZXF1aXJlZCBmb3IgZGVmYXVsdCByZWNvcmQuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWNpZHJyb3V0aW5nY29uZmlnLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIENpZHJSb3V0aW5nQ29uZmlnUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIENJRFIgY29sbGVjdGlvbiBJRC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWNpZHJyb3V0aW5nY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtY2lkcnJvdXRpbmdjb25maWctY29sbGVjdGlvbmlkXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBjb2xsZWN0aW9uSWQ6IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBDSURSIGNvbGxlY3Rpb24gbG9jYXRpb24gbmFtZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWNpZHJyb3V0aW5nY29uZmlnLmh0bWwjY2ZuLXJvdXRlNTMtY2lkcnJvdXRpbmdjb25maWctbG9jYXRpb25uYW1lXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBsb2NhdGlvbk5hbWU6IHN0cmluZztcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2lkclJvdXRpbmdDb25maWdQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2lkclJvdXRpbmdDb25maWdQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5SZWNvcmRTZXRfQ2lkclJvdXRpbmdDb25maWdQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbGxlY3Rpb25JZCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5jb2xsZWN0aW9uSWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbGxlY3Rpb25JZCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jb2xsZWN0aW9uSWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2xvY2F0aW9uTmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5sb2NhdGlvbk5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2xvY2F0aW9uTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5sb2NhdGlvbk5hbWUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2lkclJvdXRpbmdDb25maWdQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0LkNpZHJSb3V0aW5nQ29uZmlnYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDaWRyUm91dGluZ0NvbmZpZ1Byb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXQuQ2lkclJvdXRpbmdDb25maWdgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuUmVjb3JkU2V0Q2lkclJvdXRpbmdDb25maWdQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuUmVjb3JkU2V0X0NpZHJSb3V0aW5nQ29uZmlnUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIENvbGxlY3Rpb25JZDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jb2xsZWN0aW9uSWQpLFxuICAgICAgICBMb2NhdGlvbk5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubG9jYXRpb25OYW1lKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuUmVjb3JkU2V0Q2lkclJvdXRpbmdDb25maWdQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblJlY29yZFNldC5DaWRyUm91dGluZ0NvbmZpZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblJlY29yZFNldC5DaWRyUm91dGluZ0NvbmZpZ1Byb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY29sbGVjdGlvbklkJywgJ0NvbGxlY3Rpb25JZCcsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ29sbGVjdGlvbklkKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdsb2NhdGlvbk5hbWUnLCAnTG9jYXRpb25OYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Mb2NhdGlvbk5hbWUpKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5SZWNvcmRTZXQge1xuICAgIC8qKlxuICAgICAqIEEgY29tcGxleCB0eXBlIHRoYXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgYSBnZW9ncmFwaGljIGxvY2F0aW9uLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQtZ2VvbG9jYXRpb24uaHRtbFxuICAgICAqL1xuICAgIGV4cG9ydCBpbnRlcmZhY2UgR2VvTG9jYXRpb25Qcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGb3IgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMsIGEgdHdvLWxldHRlciBhYmJyZXZpYXRpb24gdGhhdCBpZGVudGlmaWVzIGEgY29udGluZW50LiBSb3V0ZSA1MyBzdXBwb3J0cyB0aGUgZm9sbG93aW5nIGNvbnRpbmVudCBjb2RlczpcbiAgICAgICAgICpcbiAgICAgICAgICogLSAqQUYqIDogQWZyaWNhXG4gICAgICAgICAqIC0gKkFOKiA6IEFudGFyY3RpY2FcbiAgICAgICAgICogLSAqQVMqIDogQXNpYVxuICAgICAgICAgKiAtICpFVSogOiBFdXJvcGVcbiAgICAgICAgICogLSAqT0MqIDogT2NlYW5pYVxuICAgICAgICAgKiAtICpOQSogOiBOb3J0aCBBbWVyaWNhXG4gICAgICAgICAqIC0gKlNBKiA6IFNvdXRoIEFtZXJpY2FcbiAgICAgICAgICpcbiAgICAgICAgICogQ29uc3RyYWludDogU3BlY2lmeWluZyBgQ29udGluZW50Q29kZWAgd2l0aCBlaXRoZXIgYENvdW50cnlDb2RlYCBvciBgU3ViZGl2aXNpb25Db2RlYCByZXR1cm5zIGFuIGBJbnZhbGlkSW5wdXRgIGVycm9yLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0LWdlb2xvY2F0aW9uLmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LWdlb2xvY2F0aW9uLWNvbnRpbmVudGNvZGVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNvbnRpbmVudENvZGU/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGb3IgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMsIHRoZSB0d28tbGV0dGVyIGNvZGUgZm9yIGEgY291bnRyeS5cbiAgICAgICAgICpcbiAgICAgICAgICogUm91dGUgNTMgdXNlcyB0aGUgdHdvLWxldHRlciBjb3VudHJ5IGNvZGVzIHRoYXQgYXJlIHNwZWNpZmllZCBpbiBbSVNPIHN0YW5kYXJkIDMxNjYtMSBhbHBoYS0yXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPXzMxNjYtMV9hbHBoYS0yKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQtZ2VvbG9jYXRpb24uaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtZ2VvbG9jYXRpb24tY291bnRyeWNvZGVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNvdW50cnlDb2RlPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogRm9yIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzLCB0aGUgdHdvLWxldHRlciBjb2RlIGZvciBhIHN0YXRlIG9mIHRoZSBVbml0ZWQgU3RhdGVzLiBSb3V0ZSA1MyBkb2Vzbid0IHN1cHBvcnQgYW55IG90aGVyIHZhbHVlcyBmb3IgYFN1YmRpdmlzaW9uQ29kZWAgLiBGb3IgYSBsaXN0IG9mIHN0YXRlIGFiYnJldmlhdGlvbnMsIHNlZSBbQXBwZW5kaXggQjogVHdv4oCTTGV0dGVyIFN0YXRlIGFuZCBQb3NzZXNzaW9uIEFiYnJldmlhdGlvbnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL3BlLnVzcHMuY29tL3RleHQvcHViMjgvMjhhcGIuaHRtKSBvbiB0aGUgVW5pdGVkIFN0YXRlcyBQb3N0YWwgU2VydmljZSB3ZWJzaXRlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB5b3Ugc3BlY2lmeSBgc3ViZGl2aXNpb25jb2RlYCAsIHlvdSBtdXN0IGFsc28gc3BlY2lmeSBgVVNgIGZvciBgQ291bnRyeUNvZGVgIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC1nZW9sb2NhdGlvbi5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1nZW9sb2NhdGlvbi1zdWJkaXZpc2lvbmNvZGVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHN1YmRpdmlzaW9uQ29kZT86IHN0cmluZztcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgR2VvTG9jYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgR2VvTG9jYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5SZWNvcmRTZXRfR2VvTG9jYXRpb25Qcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbnRpbmVudENvZGUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY29udGluZW50Q29kZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY291bnRyeUNvZGUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY291bnRyeUNvZGUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3N1YmRpdmlzaW9uQ29kZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5zdWJkaXZpc2lvbkNvZGUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiR2VvTG9jYXRpb25Qcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0Lkdlb0xvY2F0aW9uYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBHZW9Mb2NhdGlvblByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXQuR2VvTG9jYXRpb25gIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuUmVjb3JkU2V0R2VvTG9jYXRpb25Qcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuUmVjb3JkU2V0X0dlb0xvY2F0aW9uUHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIENvbnRpbmVudENvZGU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY29udGluZW50Q29kZSksXG4gICAgICAgIENvdW50cnlDb2RlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNvdW50cnlDb2RlKSxcbiAgICAgICAgU3ViZGl2aXNpb25Db2RlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnN1YmRpdmlzaW9uQ29kZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblJlY29yZFNldEdlb0xvY2F0aW9uUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5SZWNvcmRTZXQuR2VvTG9jYXRpb25Qcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5SZWNvcmRTZXQuR2VvTG9jYXRpb25Qcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NvbnRpbmVudENvZGUnLCAnQ29udGluZW50Q29kZScsIHByb3BlcnRpZXMuQ29udGluZW50Q29kZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Db250aW5lbnRDb2RlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjb3VudHJ5Q29kZScsICdDb3VudHJ5Q29kZScsIHByb3BlcnRpZXMuQ291bnRyeUNvZGUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ291bnRyeUNvZGUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3N1YmRpdmlzaW9uQ29kZScsICdTdWJkaXZpc2lvbkNvZGUnLCBwcm9wZXJ0aWVzLlN1YmRpdmlzaW9uQ29kZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5TdWJkaXZpc2lvbkNvZGUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5SZWNvcmRTZXRHcm91cGBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1yZWNvcmRzZXRncm91cC5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuUmVjb3JkU2V0R3JvdXBQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiAqT3B0aW9uYWw6KiBBbnkgY29tbWVudHMgeW91IHdhbnQgdG8gaW5jbHVkZSBhYm91dCBhIGNoYW5nZSBiYXRjaCByZXF1ZXN0LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1yZWNvcmRzZXRncm91cC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldGdyb3VwLWNvbW1lbnRcbiAgICAgKi9cbiAgICByZWFkb25seSBjb21tZW50Pzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIElEIG9mIHRoZSBob3N0ZWQgem9uZSB0aGF0IHlvdSB3YW50IHRvIGNyZWF0ZSByZWNvcmRzIGluLlxuICAgICAqXG4gICAgICogU3BlY2lmeSBlaXRoZXIgYEhvc3RlZFpvbmVOYW1lYCBvciBgSG9zdGVkWm9uZUlkYCAsIGJ1dCBub3QgYm90aC4gSWYgeW91IGhhdmUgbXVsdGlwbGUgaG9zdGVkIHpvbmVzIHdpdGggdGhlIHNhbWUgZG9tYWluIG5hbWUsIHlvdSBtdXN0IHNwZWNpZnkgdGhlIGhvc3RlZCB6b25lIHVzaW5nIGBIb3N0ZWRab25lSWRgIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtcmVjb3Jkc2V0Z3JvdXAuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXRncm91cC1ob3N0ZWR6b25laWRcbiAgICAgKi9cbiAgICByZWFkb25seSBob3N0ZWRab25lSWQ/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgaG9zdGVkIHpvbmUgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUgcmVjb3JkcyBpbi4gWW91IG11c3QgaW5jbHVkZSBhIHRyYWlsaW5nIGRvdCAoZm9yIGV4YW1wbGUsIGB3d3cuZXhhbXBsZS5jb20uYCApIGFzIHBhcnQgb2YgdGhlIGBIb3N0ZWRab25lTmFtZWAgLlxuICAgICAqXG4gICAgICogV2hlbiB5b3UgY3JlYXRlIGEgc3RhY2sgdXNpbmcgYW4gYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0YCB0aGF0IHNwZWNpZmllcyBgSG9zdGVkWm9uZU5hbWVgICwgQVdTIENsb3VkRm9ybWF0aW9uIGF0dGVtcHRzIHRvIGZpbmQgYSBob3N0ZWQgem9uZSB3aG9zZSBuYW1lIG1hdGNoZXMgdGhlIGBIb3N0ZWRab25lTmFtZWAgLiBJZiBBV1MgQ2xvdWRGb3JtYXRpb24gY2FuJ3QgZmluZCBhIGhvc3RlZCB6b25lIHdpdGggYSBtYXRjaGluZyBkb21haW4gbmFtZSwgb3IgaWYgdGhlcmUgaXMgbW9yZSB0aGFuIG9uZSBob3N0ZWQgem9uZSB3aXRoIHRoZSBzcGVjaWZpZWQgZG9tYWluIG5hbWUsIEFXUyBDbG91ZEZvcm1hdGlvbiB3aWxsIG5vdCBjcmVhdGUgdGhlIHN0YWNrLlxuICAgICAqXG4gICAgICogU3BlY2lmeSBlaXRoZXIgYEhvc3RlZFpvbmVOYW1lYCBvciBgSG9zdGVkWm9uZUlkYCAsIGJ1dCBub3QgYm90aC4gSWYgeW91IGhhdmUgbXVsdGlwbGUgaG9zdGVkIHpvbmVzIHdpdGggdGhlIHNhbWUgZG9tYWluIG5hbWUsIHlvdSBtdXN0IHNwZWNpZnkgdGhlIGhvc3RlZCB6b25lIHVzaW5nIGBIb3N0ZWRab25lSWRgIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtcmVjb3Jkc2V0Z3JvdXAuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXRncm91cC1ob3N0ZWR6b25lbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IGhvc3RlZFpvbmVOYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBvbmUgYFJlY29yZFNldGAgZWxlbWVudCBmb3IgZWFjaCByZWNvcmQgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLXJlY29yZHNldGdyb3VwLmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0Z3JvdXAtcmVjb3Jkc2V0c1xuICAgICAqL1xuICAgIHJlYWRvbmx5IHJlY29yZFNldHM/OiBBcnJheTxDZm5SZWNvcmRTZXRHcm91cC5SZWNvcmRTZXRQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGU7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2ZuUmVjb3JkU2V0R3JvdXBQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuUmVjb3JkU2V0R3JvdXBQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5SZWNvcmRTZXRHcm91cFByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY29tbWVudCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jb21tZW50KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdob3N0ZWRab25lSWQnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuaG9zdGVkWm9uZUlkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdob3N0ZWRab25lTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5ob3N0ZWRab25lTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncmVjb3JkU2V0cycsIGNkay5saXN0VmFsaWRhdG9yKENmblJlY29yZFNldEdyb3VwX1JlY29yZFNldFByb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy5yZWNvcmRTZXRzKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmblJlY29yZFNldEdyb3VwUHJvcHNcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldEdyb3VwYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5SZWNvcmRTZXRHcm91cFByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRHcm91cGAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5SZWNvcmRTZXRHcm91cFByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5SZWNvcmRTZXRHcm91cFByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBDb21tZW50OiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNvbW1lbnQpLFxuICAgICAgICBIb3N0ZWRab25lSWQ6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaG9zdGVkWm9uZUlkKSxcbiAgICAgICAgSG9zdGVkWm9uZU5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaG9zdGVkWm9uZU5hbWUpLFxuICAgICAgICBSZWNvcmRTZXRzOiBjZGsubGlzdE1hcHBlcihjZm5SZWNvcmRTZXRHcm91cFJlY29yZFNldFByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5yZWNvcmRTZXRzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuUmVjb3JkU2V0R3JvdXBQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblJlY29yZFNldEdyb3VwUHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblJlY29yZFNldEdyb3VwUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjb21tZW50JywgJ0NvbW1lbnQnLCBwcm9wZXJ0aWVzLkNvbW1lbnQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ29tbWVudCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaG9zdGVkWm9uZUlkJywgJ0hvc3RlZFpvbmVJZCcsIHByb3BlcnRpZXMuSG9zdGVkWm9uZUlkICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkhvc3RlZFpvbmVJZCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnaG9zdGVkWm9uZU5hbWUnLCAnSG9zdGVkWm9uZU5hbWUnLCBwcm9wZXJ0aWVzLkhvc3RlZFpvbmVOYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkhvc3RlZFpvbmVOYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdyZWNvcmRTZXRzJywgJ1JlY29yZFNldHMnLCBwcm9wZXJ0aWVzLlJlY29yZFNldHMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuUmVjb3JkU2V0R3JvdXBSZWNvcmRTZXRQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5SZWNvcmRTZXRzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRHcm91cGBcbiAqXG4gKiBBIGNvbXBsZXggdHlwZSB0aGF0IGNvbnRhaW5zIGFuIG9wdGlvbmFsIGNvbW1lbnQsIHRoZSBuYW1lIGFuZCBJRCBvZiB0aGUgaG9zdGVkIHpvbmUgdGhhdCB5b3Ugd2FudCB0byBtYWtlIGNoYW5nZXMgaW4sIGFuZCB2YWx1ZXMgZm9yIHRoZSByZWNvcmRzIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0R3JvdXBcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLXJlY29yZHNldGdyb3VwLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmblJlY29yZFNldEdyb3VwIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0R3JvdXBcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmblJlY29yZFNldEdyb3VwIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5SZWNvcmRTZXRHcm91cFByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5SZWNvcmRTZXRHcm91cChzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAqT3B0aW9uYWw6KiBBbnkgY29tbWVudHMgeW91IHdhbnQgdG8gaW5jbHVkZSBhYm91dCBhIGNoYW5nZSBiYXRjaCByZXF1ZXN0LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2Utcm91dGU1My1yZWNvcmRzZXRncm91cC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldGdyb3VwLWNvbW1lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgY29tbWVudDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIElEIG9mIHRoZSBob3N0ZWQgem9uZSB0aGF0IHlvdSB3YW50IHRvIGNyZWF0ZSByZWNvcmRzIGluLlxuICAgICAqXG4gICAgICogU3BlY2lmeSBlaXRoZXIgYEhvc3RlZFpvbmVOYW1lYCBvciBgSG9zdGVkWm9uZUlkYCAsIGJ1dCBub3QgYm90aC4gSWYgeW91IGhhdmUgbXVsdGlwbGUgaG9zdGVkIHpvbmVzIHdpdGggdGhlIHNhbWUgZG9tYWluIG5hbWUsIHlvdSBtdXN0IHNwZWNpZnkgdGhlIGhvc3RlZCB6b25lIHVzaW5nIGBIb3N0ZWRab25lSWRgIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtcmVjb3Jkc2V0Z3JvdXAuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXRncm91cC1ob3N0ZWR6b25laWRcbiAgICAgKi9cbiAgICBwdWJsaWMgaG9zdGVkWm9uZUlkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgaG9zdGVkIHpvbmUgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUgcmVjb3JkcyBpbi4gWW91IG11c3QgaW5jbHVkZSBhIHRyYWlsaW5nIGRvdCAoZm9yIGV4YW1wbGUsIGB3d3cuZXhhbXBsZS5jb20uYCApIGFzIHBhcnQgb2YgdGhlIGBIb3N0ZWRab25lTmFtZWAgLlxuICAgICAqXG4gICAgICogV2hlbiB5b3UgY3JlYXRlIGEgc3RhY2sgdXNpbmcgYW4gYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0YCB0aGF0IHNwZWNpZmllcyBgSG9zdGVkWm9uZU5hbWVgICwgQVdTIENsb3VkRm9ybWF0aW9uIGF0dGVtcHRzIHRvIGZpbmQgYSBob3N0ZWQgem9uZSB3aG9zZSBuYW1lIG1hdGNoZXMgdGhlIGBIb3N0ZWRab25lTmFtZWAgLiBJZiBBV1MgQ2xvdWRGb3JtYXRpb24gY2FuJ3QgZmluZCBhIGhvc3RlZCB6b25lIHdpdGggYSBtYXRjaGluZyBkb21haW4gbmFtZSwgb3IgaWYgdGhlcmUgaXMgbW9yZSB0aGFuIG9uZSBob3N0ZWQgem9uZSB3aXRoIHRoZSBzcGVjaWZpZWQgZG9tYWluIG5hbWUsIEFXUyBDbG91ZEZvcm1hdGlvbiB3aWxsIG5vdCBjcmVhdGUgdGhlIHN0YWNrLlxuICAgICAqXG4gICAgICogU3BlY2lmeSBlaXRoZXIgYEhvc3RlZFpvbmVOYW1lYCBvciBgSG9zdGVkWm9uZUlkYCAsIGJ1dCBub3QgYm90aC4gSWYgeW91IGhhdmUgbXVsdGlwbGUgaG9zdGVkIHpvbmVzIHdpdGggdGhlIHNhbWUgZG9tYWluIG5hbWUsIHlvdSBtdXN0IHNwZWNpZnkgdGhlIGhvc3RlZCB6b25lIHVzaW5nIGBIb3N0ZWRab25lSWRgIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLXJvdXRlNTMtcmVjb3Jkc2V0Z3JvdXAuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXRncm91cC1ob3N0ZWR6b25lbmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyBob3N0ZWRab25lTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQSBjb21wbGV4IHR5cGUgdGhhdCBjb250YWlucyBvbmUgYFJlY29yZFNldGAgZWxlbWVudCBmb3IgZWFjaCByZWNvcmQgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1yb3V0ZTUzLXJlY29yZHNldGdyb3VwLmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0Z3JvdXAtcmVjb3Jkc2V0c1xuICAgICAqL1xuICAgIHB1YmxpYyByZWNvcmRTZXRzOiBBcnJheTxDZm5SZWNvcmRTZXRHcm91cC5SZWNvcmRTZXRQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0R3JvdXBgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmblJlY29yZFNldEdyb3VwUHJvcHMgPSB7fSkge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuUmVjb3JkU2V0R3JvdXAuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG5cbiAgICAgICAgdGhpcy5jb21tZW50ID0gcHJvcHMuY29tbWVudDtcbiAgICAgICAgdGhpcy5ob3N0ZWRab25lSWQgPSBwcm9wcy5ob3N0ZWRab25lSWQ7XG4gICAgICAgIHRoaXMuaG9zdGVkWm9uZU5hbWUgPSBwcm9wcy5ob3N0ZWRab25lTmFtZTtcbiAgICAgICAgdGhpcy5yZWNvcmRTZXRzID0gcHJvcHMucmVjb3JkU2V0cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmblJlY29yZFNldEdyb3VwLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb21tZW50OiB0aGlzLmNvbW1lbnQsXG4gICAgICAgICAgICBob3N0ZWRab25lSWQ6IHRoaXMuaG9zdGVkWm9uZUlkLFxuICAgICAgICAgICAgaG9zdGVkWm9uZU5hbWU6IHRoaXMuaG9zdGVkWm9uZU5hbWUsXG4gICAgICAgICAgICByZWNvcmRTZXRzOiB0aGlzLnJlY29yZFNldHMsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuUmVjb3JkU2V0R3JvdXBQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5SZWNvcmRTZXRHcm91cCB7XG4gICAgLyoqXG4gICAgICogKkFsaWFzIHJlY29yZHMgb25seToqIEluZm9ybWF0aW9uIGFib3V0IHRoZSBBV1MgcmVzb3VyY2UsIHN1Y2ggYXMgYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiBvciBhbiBBbWF6b24gUzMgYnVja2V0LCB0aGF0IHlvdSB3YW50IHRvIHJvdXRlIHRyYWZmaWMgdG8uXG4gICAgICpcbiAgICAgKiBXaGVuIGNyZWF0aW5nIHJlY29yZHMgZm9yIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSwgbm90ZSB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBDcmVhdGluZyBnZW9sb2NhdGlvbiBhbGlhcyBhbmQgbGF0ZW5jeSBhbGlhcyByZWNvcmRzIGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSBpcyBhbGxvd2VkIGJ1dCBub3Qgc3VwcG9ydGVkLlxuICAgICAqIC0gRm9yIGluZm9ybWF0aW9uIGFib3V0IGNyZWF0aW5nIGZhaWxvdmVyIHJlY29yZHMgaW4gYSBwcml2YXRlIGhvc3RlZCB6b25lLCBzZWUgW0NvbmZpZ3VyaW5nIEZhaWxvdmVyIGluIGEgUHJpdmF0ZSBIb3N0ZWQgWm9uZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1wcml2YXRlLWhvc3RlZC16b25lcy5odG1sKSAuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWFsaWFzdGFyZ2V0Lmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIEFsaWFzVGFyZ2V0UHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogKkFsaWFzIHJlY29yZHMgb25seToqIFRoZSB2YWx1ZSB0aGF0IHlvdSBzcGVjaWZ5IGRlcGVuZHMgb24gd2hlcmUgeW91IHdhbnQgdG8gcm91dGUgcXVlcmllczpcbiAgICAgICAgICpcbiAgICAgICAgICogLSAqKkFtYXpvbiBBUEkgR2F0ZXdheSBjdXN0b20gcmVnaW9uYWwgQVBJcyBhbmQgZWRnZS1vcHRpbWl6ZWQgQVBJcyoqIC0gU3BlY2lmeSB0aGUgYXBwbGljYWJsZSBkb21haW4gbmFtZSBmb3IgeW91ciBBUEkuIFlvdSBjYW4gZ2V0IHRoZSBhcHBsaWNhYmxlIHZhbHVlIHVzaW5nIHRoZSBBV1MgQ0xJIGNvbW1hbmQgW2dldC1kb21haW4tbmFtZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGkvbGF0ZXN0L3JlZmVyZW5jZS9hcGlnYXRld2F5L2dldC1kb21haW4tbmFtZXMuaHRtbCkgOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIEZvciByZWdpb25hbCBBUElzLCBzcGVjaWZ5IHRoZSB2YWx1ZSBvZiBgcmVnaW9uYWxEb21haW5OYW1lYCAuXG4gICAgICAgICAqIC0gRm9yIGVkZ2Utb3B0aW1pemVkIEFQSXMsIHNwZWNpZnkgdGhlIHZhbHVlIG9mIGBkaXN0cmlidXRpb25Eb21haW5OYW1lYCAuIFRoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIGFzc29jaWF0ZWQgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24sIHN1Y2ggYXMgYGRhMWIyYzNkNGU1LmNsb3VkZnJvbnQubmV0YCAuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gVGhlIG5hbWUgb2YgdGhlIHJlY29yZCB0aGF0IHlvdSdyZSBjcmVhdGluZyBtdXN0IG1hdGNoIGEgY3VzdG9tIGRvbWFpbiBuYW1lIGZvciB5b3VyIEFQSSwgc3VjaCBhcyBgYXBpLmV4YW1wbGUuY29tYCAuXG4gICAgICAgICAqIC0gKipBbWF6b24gVmlydHVhbCBQcml2YXRlIENsb3VkIGludGVyZmFjZSBWUEMgZW5kcG9pbnQqKiAtIEVudGVyIHRoZSBBUEkgZW5kcG9pbnQgZm9yIHRoZSBpbnRlcmZhY2UgZW5kcG9pbnQsIHN1Y2ggYXMgYHZwY2UtMTIzNDU2Nzg5YWJjZGVmMDEtZXhhbXBsZS11cy1lYXN0LTFhLmVsYXN0aWNsb2FkYmFsYW5jaW5nLnVzLWVhc3QtMS52cGNlLmFtYXpvbmF3cy5jb21gIC4gRm9yIGVkZ2Utb3B0aW1pemVkIEFQSXMsIHRoaXMgaXMgdGhlIGRvbWFpbiBuYW1lIGZvciB0aGUgY29ycmVzcG9uZGluZyBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbi4gWW91IGNhbiBnZXQgdGhlIHZhbHVlIG9mIGBEbnNOYW1lYCB1c2luZyB0aGUgQVdTIENMSSBjb21tYW5kIFtkZXNjcmliZS12cGMtZW5kcG9pbnRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvZWMyL2Rlc2NyaWJlLXZwYy1lbmRwb2ludHMuaHRtbCkgLlxuICAgICAgICAgKiAtICoqQ2xvdWRGcm9udCBkaXN0cmlidXRpb24qKiAtIFNwZWNpZnkgdGhlIGRvbWFpbiBuYW1lIHRoYXQgQ2xvdWRGcm9udCBhc3NpZ25lZCB3aGVuIHlvdSBjcmVhdGVkIHlvdXIgZGlzdHJpYnV0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBZb3VyIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uIG11c3QgaW5jbHVkZSBhbiBhbHRlcm5hdGUgZG9tYWluIG5hbWUgdGhhdCBtYXRjaGVzIHRoZSBuYW1lIG9mIHRoZSByZWNvcmQuIEZvciBleGFtcGxlLCBpZiB0aGUgbmFtZSBvZiB0aGUgcmVjb3JkIGlzICphY21lLmV4YW1wbGUuY29tKiAsIHlvdXIgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24gbXVzdCBpbmNsdWRlICphY21lLmV4YW1wbGUuY29tKiBhcyBvbmUgb2YgdGhlIGFsdGVybmF0ZSBkb21haW4gbmFtZXMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1VzaW5nIEFsdGVybmF0ZSBEb21haW4gTmFtZXMgKENOQU1FcyldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZEZyb250L2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9DTkFNRXMuaHRtbCkgaW4gdGhlICpBbWF6b24gQ2xvdWRGcm9udCBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogWW91IGNhbid0IGNyZWF0ZSBhIHJlY29yZCBpbiBhIHByaXZhdGUgaG9zdGVkIHpvbmUgdG8gcm91dGUgdHJhZmZpYyB0byBhIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IEZvciBmYWlsb3ZlciBhbGlhcyByZWNvcmRzLCB5b3UgY2FuJ3Qgc3BlY2lmeSBhIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uIGZvciBib3RoIHRoZSBwcmltYXJ5IGFuZCBzZWNvbmRhcnkgcmVjb3Jkcy4gQSBkaXN0cmlidXRpb24gbXVzdCBpbmNsdWRlIGFuIGFsdGVybmF0ZSBkb21haW4gbmFtZSB0aGF0IG1hdGNoZXMgdGhlIG5hbWUgb2YgdGhlIHJlY29yZC4gSG93ZXZlciwgdGhlIHByaW1hcnkgYW5kIHNlY29uZGFyeSByZWNvcmRzIGhhdmUgdGhlIHNhbWUgbmFtZSwgYW5kIHlvdSBjYW4ndCBpbmNsdWRlIHRoZSBzYW1lIGFsdGVybmF0ZSBkb21haW4gbmFtZSBpbiBtb3JlIHRoYW4gb25lIGRpc3RyaWJ1dGlvbi5cbiAgICAgICAgICogLSAqKkVsYXN0aWMgQmVhbnN0YWxrIGVudmlyb25tZW50KiogLSBJZiB0aGUgZG9tYWluIG5hbWUgZm9yIHlvdXIgRWxhc3RpYyBCZWFuc3RhbGsgZW52aXJvbm1lbnQgaW5jbHVkZXMgdGhlIHJlZ2lvbiB0aGF0IHlvdSBkZXBsb3llZCB0aGUgZW52aXJvbm1lbnQgaW4sIHlvdSBjYW4gY3JlYXRlIGFuIGFsaWFzIHJlY29yZCB0aGF0IHJvdXRlcyB0cmFmZmljIHRvIHRoZSBlbnZpcm9ubWVudC4gRm9yIGV4YW1wbGUsIHRoZSBkb21haW4gbmFtZSBgbXktZW52aXJvbm1lbnQuICp1cy13ZXN0LTIqIC5lbGFzdGljYmVhbnN0YWxrLmNvbWAgaXMgYSByZWdpb25hbGl6ZWQgZG9tYWluIG5hbWUuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gRm9yIGVudmlyb25tZW50cyB0aGF0IHdlcmUgY3JlYXRlZCBiZWZvcmUgZWFybHkgMjAxNiwgdGhlIGRvbWFpbiBuYW1lIGRvZXNuJ3QgaW5jbHVkZSB0aGUgcmVnaW9uLiBUbyByb3V0ZSB0cmFmZmljIHRvIHRoZXNlIGVudmlyb25tZW50cywgeW91IG11c3QgY3JlYXRlIGEgQ05BTUUgcmVjb3JkIGluc3RlYWQgb2YgYW4gYWxpYXMgcmVjb3JkLiBOb3RlIHRoYXQgeW91IGNhbid0IGNyZWF0ZSBhIENOQU1FIHJlY29yZCBmb3IgdGhlIHJvb3QgZG9tYWluIG5hbWUuIEZvciBleGFtcGxlLCBpZiB5b3VyIGRvbWFpbiBuYW1lIGlzIGV4YW1wbGUuY29tLCB5b3UgY2FuIGNyZWF0ZSBhIHJlY29yZCB0aGF0IHJvdXRlcyB0cmFmZmljIGZvciBhY21lLmV4YW1wbGUuY29tIHRvIHlvdXIgRWxhc3RpYyBCZWFuc3RhbGsgZW52aXJvbm1lbnQsIGJ1dCB5b3UgY2FuJ3QgY3JlYXRlIGEgcmVjb3JkIHRoYXQgcm91dGVzIHRyYWZmaWMgZm9yIGV4YW1wbGUuY29tIHRvIHlvdXIgRWxhc3RpYyBCZWFuc3RhbGsgZW52aXJvbm1lbnQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciBFbGFzdGljIEJlYW5zdGFsayBlbnZpcm9ubWVudHMgdGhhdCBoYXZlIHJlZ2lvbmFsaXplZCBzdWJkb21haW5zLCBzcGVjaWZ5IHRoZSBgQ05BTUVgIGF0dHJpYnV0ZSBmb3IgdGhlIGVudmlyb25tZW50LiBZb3UgY2FuIHVzZSB0aGUgZm9sbG93aW5nIG1ldGhvZHMgdG8gZ2V0IHRoZSB2YWx1ZSBvZiB0aGUgQ05BTUUgYXR0cmlidXRlOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpBV1MgTWFuYWdlbWVudCBDb25zb2xlKiA6IEZvciBpbmZvcm1hdGlvbiBhYm91dCBob3cgdG8gZ2V0IHRoZSB2YWx1ZSBieSB1c2luZyB0aGUgY29uc29sZSwgc2VlIFtVc2luZyBDdXN0b20gRG9tYWlucyB3aXRoIEFXUyBFbGFzdGljIEJlYW5zdGFsa10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNiZWFuc3RhbGsvbGF0ZXN0L2RnL2N1c3RvbWRvbWFpbnMuaHRtbCkgaW4gdGhlICpBV1MgRWxhc3RpYyBCZWFuc3RhbGsgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqIC0gKkVsYXN0aWMgQmVhbnN0YWxrIEFQSSogOiBVc2UgdGhlIGBEZXNjcmliZUVudmlyb25tZW50c2AgYWN0aW9uIHRvIGdldCB0aGUgdmFsdWUgb2YgdGhlIGBDTkFNRWAgYXR0cmlidXRlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtEZXNjcmliZUVudmlyb25tZW50c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNiZWFuc3RhbGsvbGF0ZXN0L2FwaS9BUElfRGVzY3JpYmVFbnZpcm9ubWVudHMuaHRtbCkgaW4gdGhlICpBV1MgRWxhc3RpYyBCZWFuc3RhbGsgQVBJIFJlZmVyZW5jZSogLlxuICAgICAgICAgKiAtICpBV1MgQ0xJKiA6IFVzZSB0aGUgYGRlc2NyaWJlLWVudmlyb25tZW50c2AgY29tbWFuZCB0byBnZXQgdGhlIHZhbHVlIG9mIHRoZSBgQ05BTUVgIGF0dHJpYnV0ZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbZGVzY3JpYmUtZW52aXJvbm1lbnRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvZWxhc3RpY2JlYW5zdGFsay9kZXNjcmliZS1lbnZpcm9ubWVudHMuaHRtbCkgaW4gdGhlICpBV1MgQ0xJKiAuXG4gICAgICAgICAqIC0gKipFTEIgbG9hZCBiYWxhbmNlcioqIC0gU3BlY2lmeSB0aGUgRE5TIG5hbWUgdGhhdCBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIGxvYWQgYmFsYW5jZXIuIEdldCB0aGUgRE5TIG5hbWUgYnkgdXNpbmcgdGhlIEFXUyBNYW5hZ2VtZW50IENvbnNvbGUgLCB0aGUgRUxCIEFQSSwgb3IgdGhlIEFXUyBDTEkgLlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpBV1MgTWFuYWdlbWVudCBDb25zb2xlKiA6IEdvIHRvIHRoZSBFQzIgcGFnZSwgY2hvb3NlICpMb2FkIEJhbGFuY2VycyogaW4gdGhlIG5hdmlnYXRpb24gcGFuZSwgY2hvb3NlIHRoZSBsb2FkIGJhbGFuY2VyLCBjaG9vc2UgdGhlICpEZXNjcmlwdGlvbiogdGFiLCBhbmQgZ2V0IHRoZSB2YWx1ZSBvZiB0aGUgKkROUyBuYW1lKiBmaWVsZC5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgeW91J3JlIHJvdXRpbmcgdHJhZmZpYyB0byBhIENsYXNzaWMgTG9hZCBCYWxhbmNlciwgZ2V0IHRoZSB2YWx1ZSB0aGF0IGJlZ2lucyB3aXRoICpkdWFsc3RhY2sqIC4gSWYgeW91J3JlIHJvdXRpbmcgdHJhZmZpYyB0byBhbm90aGVyIHR5cGUgb2YgbG9hZCBiYWxhbmNlciwgZ2V0IHRoZSB2YWx1ZSB0aGF0IGFwcGxpZXMgdG8gdGhlIHJlY29yZCB0eXBlLCBBIG9yIEFBQUEuXG4gICAgICAgICAqIC0gKkVsYXN0aWMgTG9hZCBCYWxhbmNpbmcgQVBJKiA6IFVzZSBgRGVzY3JpYmVMb2FkQmFsYW5jZXJzYCB0byBnZXQgdGhlIHZhbHVlIG9mIGBETlNOYW1lYCAuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgdGhlIGFwcGxpY2FibGUgZ3VpZGU6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gQ2xhc3NpYyBMb2FkIEJhbGFuY2VyczogW0Rlc2NyaWJlTG9hZEJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUxvYWRCYWxhbmNlcnMuaHRtbClcbiAgICAgICAgICogLSBBcHBsaWNhdGlvbiBhbmQgTmV0d29yayBMb2FkIEJhbGFuY2VyczogW0Rlc2NyaWJlTG9hZEJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlTG9hZEJhbGFuY2Vycy5odG1sKVxuICAgICAgICAgKiAtICpDbG91ZEZvcm1hdGlvbiBGbjo6R2V0QXR0IGludHJpbnNpYyBmdW5jdGlvbiogOiBVc2UgdGhlIFtGbjo6R2V0QXR0XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9pbnRyaW5zaWMtZnVuY3Rpb24tcmVmZXJlbmNlLWdldGF0dC5odG1sKSBpbnRyaW5zaWMgZnVuY3Rpb24gdG8gZ2V0IHRoZSB2YWx1ZSBvZiBgRE5TTmFtZWAgOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIFtDbGFzc2ljIExvYWQgQmFsYW5jZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1lYzItZWxiLmh0bWwjYXdzLXByb3BlcnRpZXMtZWMyLWVsYi1yZXR1cm4tdmFsdWVzKSAuXG4gICAgICAgICAqIC0gW0FwcGxpY2F0aW9uIGFuZCBOZXR3b3JrIExvYWQgQmFsYW5jZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWxhc3RpY2xvYWRiYWxhbmNpbmd2Mi1sb2FkYmFsYW5jZXIuaHRtbCNhd3MtcmVzb3VyY2UtZWxhc3RpY2xvYWRiYWxhbmNpbmd2Mi1sb2FkYmFsYW5jZXItcmV0dXJuLXZhbHVlcykgLlxuICAgICAgICAgKiAtICpBV1MgQ0xJKiA6IFVzZSBgZGVzY3JpYmUtbG9hZC1iYWxhbmNlcnNgIHRvIGdldCB0aGUgdmFsdWUgb2YgYEROU05hbWVgIC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSB0aGUgYXBwbGljYWJsZSBndWlkZTpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBDbGFzc2ljIExvYWQgQmFsYW5jZXJzOiBbZGVzY3JpYmUtbG9hZC1iYWxhbmNlcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGkvbGF0ZXN0L3JlZmVyZW5jZS9lbGIvZGVzY3JpYmUtbG9hZC1iYWxhbmNlcnMuaHRtbClcbiAgICAgICAgICogLSBBcHBsaWNhdGlvbiBhbmQgTmV0d29yayBMb2FkIEJhbGFuY2VyczogW2Rlc2NyaWJlLWxvYWQtYmFsYW5jZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvZWxidjIvZGVzY3JpYmUtbG9hZC1iYWxhbmNlcnMuaHRtbClcbiAgICAgICAgICogLSAqKkdsb2JhbCBBY2NlbGVyYXRvciBhY2NlbGVyYXRvcioqIC0gU3BlY2lmeSB0aGUgRE5TIG5hbWUgZm9yIHlvdXIgYWNjZWxlcmF0b3I6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKkdsb2JhbCBBY2NlbGVyYXRvciBBUEkqIDogVG8gZ2V0IHRoZSBETlMgbmFtZSwgdXNlIFtEZXNjcmliZUFjY2VsZXJhdG9yXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2xvYmFsLWFjY2VsZXJhdG9yL2xhdGVzdC9hcGkvQVBJX0Rlc2NyaWJlQWNjZWxlcmF0b3IuaHRtbCkgLlxuICAgICAgICAgKiAtICpBV1MgQ0xJKiA6IFRvIGdldCB0aGUgRE5TIG5hbWUsIHVzZSBbZGVzY3JpYmUtYWNjZWxlcmF0b3JdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGkvbGF0ZXN0L3JlZmVyZW5jZS9nbG9iYWxhY2NlbGVyYXRvci9kZXNjcmliZS1hY2NlbGVyYXRvci5odG1sKSAuXG4gICAgICAgICAqIC0gKipBbWF6b24gUzMgYnVja2V0IHRoYXQgaXMgY29uZmlndXJlZCBhcyBhIHN0YXRpYyB3ZWJzaXRlKiogLSBTcGVjaWZ5IHRoZSBkb21haW4gbmFtZSBvZiB0aGUgQW1hem9uIFMzIHdlYnNpdGUgZW5kcG9pbnQgdGhhdCB5b3UgY3JlYXRlZCB0aGUgYnVja2V0IGluLCBmb3IgZXhhbXBsZSwgYHMzLXdlYnNpdGUudXMtZWFzdC0yLmFtYXpvbmF3cy5jb21gIC4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdmFsaWQgdmFsdWVzLCBzZWUgdGhlIHRhYmxlIFtBbWF6b24gUzMgV2Vic2l0ZSBFbmRwb2ludHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nZW5lcmFsL2xhdGVzdC9nci9zMy5odG1sI3MzX3dlYnNpdGVfcmVnaW9uX2VuZHBvaW50cykgaW4gdGhlICpBbWF6b24gV2ViIFNlcnZpY2VzIEdlbmVyYWwgUmVmZXJlbmNlKiAuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHVzaW5nIFMzIGJ1Y2tldHMgZm9yIHdlYnNpdGVzLCBzZWUgW0dldHRpbmcgU3RhcnRlZCB3aXRoIEFtYXpvbiBSb3V0ZSA1M10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2dldHRpbmctc3RhcnRlZC5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUuKlxuICAgICAgICAgKiAtICoqQW5vdGhlciBSb3V0ZSA1MyByZWNvcmQqKiAtIFNwZWNpZnkgdGhlIHZhbHVlIG9mIHRoZSBgTmFtZWAgZWxlbWVudCBmb3IgYSByZWNvcmQgaW4gdGhlIGN1cnJlbnQgaG9zdGVkIHpvbmUuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gSWYgeW91J3JlIGNyZWF0aW5nIGFuIGFsaWFzIHJlY29yZCB0aGF0IGhhcyB0aGUgc2FtZSBuYW1lIGFzIHRoZSBob3N0ZWQgem9uZSAoa25vd24gYXMgdGhlIHpvbmUgYXBleCksIHlvdSBjYW4ndCBzcGVjaWZ5IHRoZSBkb21haW4gbmFtZSBmb3IgYSByZWNvcmQgZm9yIHdoaWNoIHRoZSB2YWx1ZSBvZiBgVHlwZWAgaXMgYENOQU1FYCAuIFRoaXMgaXMgYmVjYXVzZSB0aGUgYWxpYXMgcmVjb3JkIG11c3QgaGF2ZSB0aGUgc2FtZSB0eXBlIGFzIHRoZSByZWNvcmQgdGhhdCB5b3UncmUgcm91dGluZyB0cmFmZmljIHRvLCBhbmQgY3JlYXRpbmcgYSBDTkFNRSByZWNvcmQgZm9yIHRoZSB6b25lIGFwZXggaXNuJ3Qgc3VwcG9ydGVkIGV2ZW4gZm9yIGFuIGFsaWFzIHJlY29yZC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWFsaWFzdGFyZ2V0Lmh0bWwjY2ZuLXJvdXRlNTMtYWxpYXN0YXJnZXQtZG5zaG9zdG5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGRuc05hbWU6IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqICpBcHBsaWVzIG9ubHkgdG8gYWxpYXMgcmVjb3JkcyB3aXRoIGFueSByb3V0aW5nIHBvbGljeToqIFdoZW4gYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCBpcyBgdHJ1ZWAgLCBhbiBhbGlhcyByZWNvcmQgaW5oZXJpdHMgdGhlIGhlYWx0aCBvZiB0aGUgcmVmZXJlbmNlZCBBV1MgcmVzb3VyY2UsIHN1Y2ggYXMgYW4gRUxCIGxvYWQgYmFsYW5jZXIgb3IgYW5vdGhlciByZWNvcmQgaW4gdGhlIGhvc3RlZCB6b25lLlxuICAgICAgICAgKlxuICAgICAgICAgKiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKipDbG91ZEZyb250IGRpc3RyaWJ1dGlvbnMqKiAtIFlvdSBjYW4ndCBzZXQgYEV2YWx1YXRlVGFyZ2V0SGVhbHRoYCB0byBgdHJ1ZWAgd2hlbiB0aGUgYWxpYXMgdGFyZ2V0IGlzIGEgQ2xvdWRGcm9udCBkaXN0cmlidXRpb24uXG4gICAgICAgICAqIC0gKipFbGFzdGljIEJlYW5zdGFsayBlbnZpcm9ubWVudHMgdGhhdCBoYXZlIHJlZ2lvbmFsaXplZCBzdWJkb21haW5zKiogLSBJZiB5b3Ugc3BlY2lmeSBhbiBFbGFzdGljIEJlYW5zdGFsayBlbnZpcm9ubWVudCBpbiBgRE5TTmFtZWAgYW5kIHRoZSBlbnZpcm9ubWVudCBjb250YWlucyBhbiBFTEIgbG9hZCBiYWxhbmNlciwgRWxhc3RpYyBMb2FkIEJhbGFuY2luZyByb3V0ZXMgcXVlcmllcyBvbmx5IHRvIHRoZSBoZWFsdGh5IEFtYXpvbiBFQzIgaW5zdGFuY2VzIHRoYXQgYXJlIHJlZ2lzdGVyZWQgd2l0aCB0aGUgbG9hZCBiYWxhbmNlci4gKEFuIGVudmlyb25tZW50IGF1dG9tYXRpY2FsbHkgY29udGFpbnMgYW4gRUxCIGxvYWQgYmFsYW5jZXIgaWYgaXQgaW5jbHVkZXMgbW9yZSB0aGFuIG9uZSBBbWF6b24gRUMyIGluc3RhbmNlLikgSWYgeW91IHNldCBgRXZhbHVhdGVUYXJnZXRIZWFsdGhgIHRvIGB0cnVlYCBhbmQgZWl0aGVyIG5vIEFtYXpvbiBFQzIgaW5zdGFuY2VzIGFyZSBoZWFsdGh5IG9yIHRoZSBsb2FkIGJhbGFuY2VyIGl0c2VsZiBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIHJvdXRlcyBxdWVyaWVzIHRvIG90aGVyIGF2YWlsYWJsZSByZXNvdXJjZXMgdGhhdCBhcmUgaGVhbHRoeSwgaWYgYW55LlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB0aGUgZW52aXJvbm1lbnQgY29udGFpbnMgYSBzaW5nbGUgQW1hem9uIEVDMiBpbnN0YW5jZSwgdGhlcmUgYXJlIG5vIHNwZWNpYWwgcmVxdWlyZW1lbnRzLlxuICAgICAgICAgKiAtICoqRUxCIGxvYWQgYmFsYW5jZXJzKiogLSBIZWFsdGggY2hlY2tpbmcgYmVoYXZpb3IgZGVwZW5kcyBvbiB0aGUgdHlwZSBvZiBsb2FkIGJhbGFuY2VyOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICpDbGFzc2ljIExvYWQgQmFsYW5jZXJzKiA6IElmIHlvdSBzcGVjaWZ5IGFuIEVMQiBDbGFzc2ljIExvYWQgQmFsYW5jZXIgaW4gYEROU05hbWVgICwgRWxhc3RpYyBMb2FkIEJhbGFuY2luZyByb3V0ZXMgcXVlcmllcyBvbmx5IHRvIHRoZSBoZWFsdGh5IEFtYXpvbiBFQzIgaW5zdGFuY2VzIHRoYXQgYXJlIHJlZ2lzdGVyZWQgd2l0aCB0aGUgbG9hZCBiYWxhbmNlci4gSWYgeW91IHNldCBgRXZhbHVhdGVUYXJnZXRIZWFsdGhgIHRvIGB0cnVlYCBhbmQgZWl0aGVyIG5vIEVDMiBpbnN0YW5jZXMgYXJlIGhlYWx0aHkgb3IgdGhlIGxvYWQgYmFsYW5jZXIgaXRzZWxmIGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgcm91dGVzIHF1ZXJpZXMgdG8gb3RoZXIgcmVzb3VyY2VzLlxuICAgICAgICAgKiAtICpBcHBsaWNhdGlvbiBhbmQgTmV0d29yayBMb2FkIEJhbGFuY2VycyogOiBJZiB5b3Ugc3BlY2lmeSBhbiBFTEIgQXBwbGljYXRpb24gb3IgTmV0d29yayBMb2FkIEJhbGFuY2VyIGFuZCB5b3Ugc2V0IGBFdmFsdWF0ZVRhcmdldEhlYWx0aGAgdG8gYHRydWVgICwgUm91dGUgNTMgcm91dGVzIHF1ZXJpZXMgdG8gdGhlIGxvYWQgYmFsYW5jZXIgYmFzZWQgb24gdGhlIGhlYWx0aCBvZiB0aGUgdGFyZ2V0IGdyb3VwcyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggdGhlIGxvYWQgYmFsYW5jZXI6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gRm9yIGFuIEFwcGxpY2F0aW9uIG9yIE5ldHdvcmsgTG9hZCBCYWxhbmNlciB0byBiZSBjb25zaWRlcmVkIGhlYWx0aHksIGV2ZXJ5IHRhcmdldCBncm91cCB0aGF0IGNvbnRhaW5zIHRhcmdldHMgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSBoZWFsdGh5IHRhcmdldC4gSWYgYW55IHRhcmdldCBncm91cCBjb250YWlucyBvbmx5IHVuaGVhbHRoeSB0YXJnZXRzLCB0aGUgbG9hZCBiYWxhbmNlciBpcyBjb25zaWRlcmVkIHVuaGVhbHRoeSwgYW5kIFJvdXRlIDUzIHJvdXRlcyBxdWVyaWVzIHRvIG90aGVyIHJlc291cmNlcy5cbiAgICAgICAgICogLSBBIHRhcmdldCBncm91cCB0aGF0IGhhcyBubyByZWdpc3RlcmVkIHRhcmdldHMgaXMgY29uc2lkZXJlZCB1bmhlYWx0aHkuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gV2hlbiB5b3UgY3JlYXRlIGEgbG9hZCBiYWxhbmNlciwgeW91IGNvbmZpZ3VyZSBzZXR0aW5ncyBmb3IgRWxhc3RpYyBMb2FkIEJhbGFuY2luZyBoZWFsdGggY2hlY2tzOyB0aGV5J3JlIG5vdCBSb3V0ZSA1MyBoZWFsdGggY2hlY2tzLCBidXQgdGhleSBwZXJmb3JtIGEgc2ltaWxhciBmdW5jdGlvbi4gRG8gbm90IGNyZWF0ZSBSb3V0ZSA1MyBoZWFsdGggY2hlY2tzIGZvciB0aGUgRUMyIGluc3RhbmNlcyB0aGF0IHlvdSByZWdpc3RlciB3aXRoIGFuIEVMQiBsb2FkIGJhbGFuY2VyLlxuICAgICAgICAgKiAtICoqUzMgYnVja2V0cyoqIC0gVGhlcmUgYXJlIG5vIHNwZWNpYWwgcmVxdWlyZW1lbnRzIGZvciBzZXR0aW5nIGBFdmFsdWF0ZVRhcmdldEhlYWx0aGAgdG8gYHRydWVgIHdoZW4gdGhlIGFsaWFzIHRhcmdldCBpcyBhbiBTMyBidWNrZXQuXG4gICAgICAgICAqIC0gKipPdGhlciByZWNvcmRzIGluIHRoZSBzYW1lIGhvc3RlZCB6b25lKiogLSBJZiB0aGUgQVdTIHJlc291cmNlIHRoYXQgeW91IHNwZWNpZnkgaW4gYEROU05hbWVgIGlzIGEgcmVjb3JkIG9yIGEgZ3JvdXAgb2YgcmVjb3JkcyAoZm9yIGV4YW1wbGUsIGEgZ3JvdXAgb2Ygd2VpZ2h0ZWQgcmVjb3JkcykgYnV0IGlzIG5vdCBhbm90aGVyIGFsaWFzIHJlY29yZCwgd2UgcmVjb21tZW5kIHRoYXQgeW91IGFzc29jaWF0ZSBhIGhlYWx0aCBjaGVjayB3aXRoIGFsbCBvZiB0aGUgcmVjb3JkcyBpbiB0aGUgYWxpYXMgdGFyZ2V0LiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtXaGF0IEhhcHBlbnMgV2hlbiBZb3UgT21pdCBIZWFsdGggQ2hlY2tzP10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1jb21wbGV4LWNvbmZpZ3MuaHRtbCNkbnMtZmFpbG92ZXItY29tcGxleC1jb25maWdzLWhjLW9taXR0aW5nKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYW5kIGV4YW1wbGVzLCBzZWUgW0FtYXpvbiBSb3V0ZSA1MyBIZWFsdGggQ2hlY2tzIGFuZCBETlMgRmFpbG92ZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kbnMtZmFpbG92ZXIuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1hbGlhc3RhcmdldC5odG1sI2Nmbi1yb3V0ZTUzLWFsaWFzdGFyZ2V0LWV2YWx1YXRldGFyZ2V0aGVhbHRoXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBldmFsdWF0ZVRhcmdldEhlYWx0aD86IGJvb2xlYW4gfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiAqQWxpYXMgcmVzb3VyY2UgcmVjb3JkcyBzZXRzIG9ubHkqIDogVGhlIHZhbHVlIHVzZWQgZGVwZW5kcyBvbiB3aGVyZSB5b3Ugd2FudCB0byByb3V0ZSB0cmFmZmljOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtICoqQW1hem9uIEFQSSBHYXRld2F5IGN1c3RvbSByZWdpb25hbCBBUElzIGFuZCBlZGdlLW9wdGltaXplZCBBUElzKiogLSBTcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSBJRCBmb3IgeW91ciBBUEkuIFlvdSBjYW4gZ2V0IHRoZSBhcHBsaWNhYmxlIHZhbHVlIHVzaW5nIHRoZSBBV1MgQ0xJIGNvbW1hbmQgW2dldC1kb21haW4tbmFtZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGkvbGF0ZXN0L3JlZmVyZW5jZS9hcGlnYXRld2F5L2dldC1kb21haW4tbmFtZXMuaHRtbCkgOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIEZvciByZWdpb25hbCBBUElzLCBzcGVjaWZ5IHRoZSB2YWx1ZSBvZiBgcmVnaW9uYWxIb3N0ZWRab25lSWRgIC5cbiAgICAgICAgICogLSBGb3IgZWRnZS1vcHRpbWl6ZWQgQVBJcywgc3BlY2lmeSB0aGUgdmFsdWUgb2YgYGRpc3RyaWJ1dGlvbkhvc3RlZFpvbmVJZGAgLlxuICAgICAgICAgKiAtICoqQW1hem9uIFZpcnR1YWwgUHJpdmF0ZSBDbG91ZCBpbnRlcmZhY2UgVlBDIGVuZHBvaW50KiogLSBTcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSBJRCBmb3IgeW91ciBpbnRlcmZhY2UgZW5kcG9pbnQuIFlvdSBjYW4gZ2V0IHRoZSB2YWx1ZSBvZiBgSG9zdGVkWm9uZUlkYCB1c2luZyB0aGUgQVdTIENMSSBjb21tYW5kIFtkZXNjcmliZS12cGMtZW5kcG9pbnRzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvZWMyL2Rlc2NyaWJlLXZwYy1lbmRwb2ludHMuaHRtbCkgLlxuICAgICAgICAgKiAtICoqQ2xvdWRGcm9udCBkaXN0cmlidXRpb24qKiAtIFNwZWNpZnkgYFoyRkRUTkRBVEFRWVcyYCAuIFRoaXMgaXMgYWx3YXlzIHRoZSBob3N0ZWQgem9uZSBJRCB3aGVuIHlvdSBjcmVhdGUgYW4gYWxpYXMgcmVjb3JkIHRoYXQgcm91dGVzIHRyYWZmaWMgdG8gYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbi5cbiAgICAgICAgICpcbiAgICAgICAgICogPiBBbGlhcyByZWNvcmRzIGZvciBDbG91ZEZyb250IGNhbid0IGJlIGNyZWF0ZWQgaW4gYSBwcml2YXRlIHpvbmUuXG4gICAgICAgICAqIC0gKipFbGFzdGljIEJlYW5zdGFsayBlbnZpcm9ubWVudCoqIC0gU3BlY2lmeSB0aGUgaG9zdGVkIHpvbmUgSUQgZm9yIHRoZSByZWdpb24gdGhhdCB5b3UgY3JlYXRlZCB0aGUgZW52aXJvbm1lbnQgaW4uIFRoZSBlbnZpcm9ubWVudCBtdXN0IGhhdmUgYSByZWdpb25hbGl6ZWQgc3ViZG9tYWluLiBGb3IgYSBsaXN0IG9mIHJlZ2lvbnMgYW5kIHRoZSBjb3JyZXNwb25kaW5nIGhvc3RlZCB6b25lIElEcywgc2VlIFtBV1MgRWxhc3RpYyBCZWFuc3RhbGsgZW5kcG9pbnRzIGFuZCBxdW90YXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nZW5lcmFsL2xhdGVzdC9nci9lbGFzdGljYmVhbnN0YWxrLmh0bWwpIGluIHRoZSAqQW1hem9uIFdlYiBTZXJ2aWNlcyBHZW5lcmFsIFJlZmVyZW5jZSogLlxuICAgICAgICAgKiAtICoqRUxCIGxvYWQgYmFsYW5jZXIqKiAtIFNwZWNpZnkgdGhlIHZhbHVlIG9mIHRoZSBob3N0ZWQgem9uZSBJRCBmb3IgdGhlIGxvYWQgYmFsYW5jZXIuIFVzZSB0aGUgZm9sbG93aW5nIG1ldGhvZHMgdG8gZ2V0IHRoZSBob3N0ZWQgem9uZSBJRDpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBbU2VydmljZSBFbmRwb2ludHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nZW5lcmFsL2xhdGVzdC9nci9lbGIuaHRtbCkgdGFibGUgaW4gdGhlIFwiRWxhc3RpYyBMb2FkIEJhbGFuY2luZyBlbmRwb2ludHMgYW5kIHF1b3Rhc1wiIHRvcGljIGluIHRoZSAqQW1hem9uIFdlYiBTZXJ2aWNlcyBHZW5lcmFsIFJlZmVyZW5jZSogOiBVc2UgdGhlIHZhbHVlIHRoYXQgY29ycmVzcG9uZHMgd2l0aCB0aGUgcmVnaW9uIHRoYXQgeW91IGNyZWF0ZWQgeW91ciBsb2FkIGJhbGFuY2VyIGluLiBOb3RlIHRoYXQgdGhlcmUgYXJlIHNlcGFyYXRlIGNvbHVtbnMgZm9yIEFwcGxpY2F0aW9uIGFuZCBDbGFzc2ljIExvYWQgQmFsYW5jZXJzIGFuZCBmb3IgTmV0d29yayBMb2FkIEJhbGFuY2Vycy5cbiAgICAgICAgICogLSAqQVdTIE1hbmFnZW1lbnQgQ29uc29sZSogOiBHbyB0byB0aGUgQW1hem9uIEVDMiBwYWdlLCBjaG9vc2UgKkxvYWQgQmFsYW5jZXJzKiBpbiB0aGUgbmF2aWdhdGlvbiBwYW5lLCBzZWxlY3QgdGhlIGxvYWQgYmFsYW5jZXIsIGFuZCBnZXQgdGhlIHZhbHVlIG9mIHRoZSAqSG9zdGVkIHpvbmUqIGZpZWxkIG9uIHRoZSAqRGVzY3JpcHRpb24qIHRhYi5cbiAgICAgICAgICogLSAqRWxhc3RpYyBMb2FkIEJhbGFuY2luZyBBUEkqIDogVXNlIGBEZXNjcmliZUxvYWRCYWxhbmNlcnNgIHRvIGdldCB0aGUgYXBwbGljYWJsZSB2YWx1ZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSB0aGUgYXBwbGljYWJsZSBndWlkZTpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBDbGFzc2ljIExvYWQgQmFsYW5jZXJzOiBVc2UgW0Rlc2NyaWJlTG9hZEJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUxvYWRCYWxhbmNlcnMuaHRtbCkgdG8gZ2V0IHRoZSB2YWx1ZSBvZiBgQ2Fub25pY2FsSG9zdGVkWm9uZU5hbWVJRGAgLlxuICAgICAgICAgKiAtIEFwcGxpY2F0aW9uIGFuZCBOZXR3b3JrIExvYWQgQmFsYW5jZXJzOiBVc2UgW0Rlc2NyaWJlTG9hZEJhbGFuY2Vyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlTG9hZEJhbGFuY2Vycy5odG1sKSB0byBnZXQgdGhlIHZhbHVlIG9mIGBDYW5vbmljYWxIb3N0ZWRab25lSURgIC5cbiAgICAgICAgICogLSAqQ2xvdWRGb3JtYXRpb24gRm46OkdldEF0dCBpbnRyaW5zaWMgZnVuY3Rpb24qIDogVXNlIHRoZSBbRm46OkdldEF0dF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvaW50cmluc2ljLWZ1bmN0aW9uLXJlZmVyZW5jZS1nZXRhdHQuaHRtbCkgaW50cmluc2ljIGZ1bmN0aW9uIHRvIGdldCB0aGUgYXBwbGljYWJsZSB2YWx1ZTpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBDbGFzc2ljIExvYWQgQmFsYW5jZXJzOiBHZXQgW0Nhbm9uaWNhbEhvc3RlZFpvbmVOYW1lSURdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWVjMi1lbGIuaHRtbCNhd3MtcHJvcGVydGllcy1lYzItZWxiLXJldHVybi12YWx1ZXMpIC5cbiAgICAgICAgICogLSBBcHBsaWNhdGlvbiBhbmQgTmV0d29yayBMb2FkIEJhbGFuY2VyczogR2V0IFtDYW5vbmljYWxIb3N0ZWRab25lSURdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lbGFzdGljbG9hZGJhbGFuY2luZ3YyLWxvYWRiYWxhbmNlci5odG1sI2F3cy1yZXNvdXJjZS1lbGFzdGljbG9hZGJhbGFuY2luZ3YyLWxvYWRiYWxhbmNlci1yZXR1cm4tdmFsdWVzKSAuXG4gICAgICAgICAqIC0gKkFXUyBDTEkqIDogVXNlIGBkZXNjcmliZS1sb2FkLWJhbGFuY2Vyc2AgdG8gZ2V0IHRoZSBhcHBsaWNhYmxlIHZhbHVlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIHRoZSBhcHBsaWNhYmxlIGd1aWRlOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIENsYXNzaWMgTG9hZCBCYWxhbmNlcnM6IFVzZSBbZGVzY3JpYmUtbG9hZC1iYWxhbmNlcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGkvbGF0ZXN0L3JlZmVyZW5jZS9lbGIvZGVzY3JpYmUtbG9hZC1iYWxhbmNlcnMuaHRtbCkgdG8gZ2V0IHRoZSB2YWx1ZSBvZiBgQ2Fub25pY2FsSG9zdGVkWm9uZU5hbWVJRGAgLlxuICAgICAgICAgKiAtIEFwcGxpY2F0aW9uIGFuZCBOZXR3b3JrIExvYWQgQmFsYW5jZXJzOiBVc2UgW2Rlc2NyaWJlLWxvYWQtYmFsYW5jZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xpL2xhdGVzdC9yZWZlcmVuY2UvZWxidjIvZGVzY3JpYmUtbG9hZC1iYWxhbmNlcnMuaHRtbCkgdG8gZ2V0IHRoZSB2YWx1ZSBvZiBgQ2Fub25pY2FsSG9zdGVkWm9uZUlEYCAuXG4gICAgICAgICAqIC0gKipHbG9iYWwgQWNjZWxlcmF0b3IgYWNjZWxlcmF0b3IqKiAtIFNwZWNpZnkgYFoyQko2WFE1Rks3VTRIYCAuXG4gICAgICAgICAqIC0gKipBbiBBbWF6b24gUzMgYnVja2V0IGNvbmZpZ3VyZWQgYXMgYSBzdGF0aWMgd2Vic2l0ZSoqIC0gU3BlY2lmeSB0aGUgaG9zdGVkIHpvbmUgSUQgZm9yIHRoZSByZWdpb24gdGhhdCB5b3UgY3JlYXRlZCB0aGUgYnVja2V0IGluLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB2YWxpZCB2YWx1ZXMsIHNlZSB0aGUgdGFibGUgW0FtYXpvbiBTMyBXZWJzaXRlIEVuZHBvaW50c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dlbmVyYWwvbGF0ZXN0L2dyL3MzLmh0bWwjczNfd2Vic2l0ZV9yZWdpb25fZW5kcG9pbnRzKSBpbiB0aGUgKkFtYXpvbiBXZWIgU2VydmljZXMgR2VuZXJhbCBSZWZlcmVuY2UqIC5cbiAgICAgICAgICogLSAqKkFub3RoZXIgUm91dGUgNTMgcmVjb3JkIGluIHlvdXIgaG9zdGVkIHpvbmUqKiAtIFNwZWNpZnkgdGhlIGhvc3RlZCB6b25lIElEIG9mIHlvdXIgaG9zdGVkIHpvbmUuIChBbiBhbGlhcyByZWNvcmQgY2FuJ3QgcmVmZXJlbmNlIGEgcmVjb3JkIGluIGEgZGlmZmVyZW50IGhvc3RlZCB6b25lLilcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLWFsaWFzdGFyZ2V0Lmh0bWwjY2ZuLXJvdXRlNTMtYWxpYXN0YXJnZXQtaG9zdGVkem9uZWlkXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBob3N0ZWRab25lSWQ6IHN0cmluZztcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQWxpYXNUYXJnZXRQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQWxpYXNUYXJnZXRQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5SZWNvcmRTZXRHcm91cF9BbGlhc1RhcmdldFByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZG5zTmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5kbnNOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkbnNOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmRuc05hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2V2YWx1YXRlVGFyZ2V0SGVhbHRoJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5ldmFsdWF0ZVRhcmdldEhlYWx0aCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaG9zdGVkWm9uZUlkJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLmhvc3RlZFpvbmVJZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignaG9zdGVkWm9uZUlkJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmhvc3RlZFpvbmVJZCkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJBbGlhc1RhcmdldFByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRHcm91cC5BbGlhc1RhcmdldGAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQWxpYXNUYXJnZXRQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0R3JvdXAuQWxpYXNUYXJnZXRgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuUmVjb3JkU2V0R3JvdXBBbGlhc1RhcmdldFByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5SZWNvcmRTZXRHcm91cF9BbGlhc1RhcmdldFByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBETlNOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmRuc05hbWUpLFxuICAgICAgICBFdmFsdWF0ZVRhcmdldEhlYWx0aDogY2RrLmJvb2xlYW5Ub0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZXZhbHVhdGVUYXJnZXRIZWFsdGgpLFxuICAgICAgICBIb3N0ZWRab25lSWQ6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaG9zdGVkWm9uZUlkKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuUmVjb3JkU2V0R3JvdXBBbGlhc1RhcmdldFByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuUmVjb3JkU2V0R3JvdXAuQWxpYXNUYXJnZXRQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5SZWNvcmRTZXRHcm91cC5BbGlhc1RhcmdldFByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZG5zTmFtZScsICdETlNOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5ETlNOYW1lKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdldmFsdWF0ZVRhcmdldEhlYWx0aCcsICdFdmFsdWF0ZVRhcmdldEhlYWx0aCcsIHByb3BlcnRpZXMuRXZhbHVhdGVUYXJnZXRIZWFsdGggIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Qm9vbGVhbihwcm9wZXJ0aWVzLkV2YWx1YXRlVGFyZ2V0SGVhbHRoKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdob3N0ZWRab25lSWQnLCAnSG9zdGVkWm9uZUlkJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Ib3N0ZWRab25lSWQpKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5SZWNvcmRTZXRHcm91cCB7XG4gICAgLyoqXG4gICAgICogVGhlIG9iamVjdCB0aGF0IGlzIHNwZWNpZmllZCBpbiByZXNvdXJjZSByZWNvcmQgc2V0IG9iamVjdCB3aGVuIHlvdSBhcmUgbGlua2luZyBhIHJlc291cmNlIHJlY29yZCBzZXQgdG8gYSBDSURSIGxvY2F0aW9uLlxuICAgICAqXG4gICAgICogQSBgTG9jYXRpb25OYW1lYCB3aXRoIGFuIGFzdGVyaXNrIOKAnCrigJ0gY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGEgZGVmYXVsdCBDSURSIHJlY29yZC4gYENvbGxlY3Rpb25JZGAgaXMgc3RpbGwgcmVxdWlyZWQgZm9yIGRlZmF1bHQgcmVjb3JkLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1jaWRycm91dGluZ2NvbmZpZy5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBDaWRyUm91dGluZ0NvbmZpZ1Byb3BlcnR5IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBDSURSIGNvbGxlY3Rpb24gSUQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1jaWRycm91dGluZ2NvbmZpZy5odG1sI2Nmbi1yb3V0ZTUzLWNpZHJyb3V0aW5nY29uZmlnLWNvbGxlY3Rpb25pZFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgY29sbGVjdGlvbklkOiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgQ0lEUiBjb2xsZWN0aW9uIGxvY2F0aW9uIG5hbWUuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1jaWRycm91dGluZ2NvbmZpZy5odG1sI2Nmbi1yb3V0ZTUzLWNpZHJyb3V0aW5nY29uZmlnLWxvY2F0aW9ubmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgbG9jYXRpb25OYW1lOiBzdHJpbmc7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENpZHJSb3V0aW5nQ29uZmlnUHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENpZHJSb3V0aW5nQ29uZmlnUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuUmVjb3JkU2V0R3JvdXBfQ2lkclJvdXRpbmdDb25maWdQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbGxlY3Rpb25JZCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5jb2xsZWN0aW9uSWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NvbGxlY3Rpb25JZCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jb2xsZWN0aW9uSWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2xvY2F0aW9uTmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5sb2NhdGlvbk5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2xvY2F0aW9uTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5sb2NhdGlvbk5hbWUpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2lkclJvdXRpbmdDb25maWdQcm9wZXJ0eVwiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0R3JvdXAuQ2lkclJvdXRpbmdDb25maWdgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENpZHJSb3V0aW5nQ29uZmlnUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldEdyb3VwLkNpZHJSb3V0aW5nQ29uZmlnYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblJlY29yZFNldEdyb3VwQ2lkclJvdXRpbmdDb25maWdQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuUmVjb3JkU2V0R3JvdXBfQ2lkclJvdXRpbmdDb25maWdQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQ29sbGVjdGlvbklkOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNvbGxlY3Rpb25JZCksXG4gICAgICAgIExvY2F0aW9uTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5sb2NhdGlvbk5hbWUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5SZWNvcmRTZXRHcm91cENpZHJSb3V0aW5nQ29uZmlnUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5SZWNvcmRTZXRHcm91cC5DaWRyUm91dGluZ0NvbmZpZ1Byb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblJlY29yZFNldEdyb3VwLkNpZHJSb3V0aW5nQ29uZmlnUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjb2xsZWN0aW9uSWQnLCAnQ29sbGVjdGlvbklkJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Db2xsZWN0aW9uSWQpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2xvY2F0aW9uTmFtZScsICdMb2NhdGlvbk5hbWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkxvY2F0aW9uTmFtZSkpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblJlY29yZFNldEdyb3VwIHtcbiAgICAvKipcbiAgICAgKiBBIGNvbXBsZXggdHlwZSB0aGF0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGEgZ2VvZ3JhcGhpYyBsb2NhdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0LWdlb2xvY2F0aW9uLmh0bWxcbiAgICAgKi9cbiAgICBleHBvcnQgaW50ZXJmYWNlIEdlb0xvY2F0aW9uUHJvcGVydHkge1xuICAgICAgICAvKipcbiAgICAgICAgICogRm9yIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzLCBhIHR3by1sZXR0ZXIgYWJicmV2aWF0aW9uIHRoYXQgaWRlbnRpZmllcyBhIGNvbnRpbmVudC4gUm91dGUgNTMgc3VwcG9ydHMgdGhlIGZvbGxvd2luZyBjb250aW5lbnQgY29kZXM6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKkFGKiA6IEFmcmljYVxuICAgICAgICAgKiAtICpBTiogOiBBbnRhcmN0aWNhXG4gICAgICAgICAqIC0gKkFTKiA6IEFzaWFcbiAgICAgICAgICogLSAqRVUqIDogRXVyb3BlXG4gICAgICAgICAqIC0gKk9DKiA6IE9jZWFuaWFcbiAgICAgICAgICogLSAqTkEqIDogTm9ydGggQW1lcmljYVxuICAgICAgICAgKiAtICpTQSogOiBTb3V0aCBBbWVyaWNhXG4gICAgICAgICAqXG4gICAgICAgICAqIENvbnN0cmFpbnQ6IFNwZWNpZnlpbmcgYENvbnRpbmVudENvZGVgIHdpdGggZWl0aGVyIGBDb3VudHJ5Q29kZWAgb3IgYFN1YmRpdmlzaW9uQ29kZWAgcmV0dXJucyBhbiBgSW52YWxpZElucHV0YCBlcnJvci5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC1nZW9sb2NhdGlvbi5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldGdyb3VwLWdlb2xvY2F0aW9uLWNvbnRpbmVudGNvZGVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNvbnRpbmVudENvZGU/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGb3IgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMsIHRoZSB0d28tbGV0dGVyIGNvZGUgZm9yIGEgY291bnRyeS5cbiAgICAgICAgICpcbiAgICAgICAgICogUm91dGUgNTMgdXNlcyB0aGUgdHdvLWxldHRlciBjb3VudHJ5IGNvZGVzIHRoYXQgYXJlIHNwZWNpZmllZCBpbiBbSVNPIHN0YW5kYXJkIDMxNjYtMSBhbHBoYS0yXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPXzMxNjYtMV9hbHBoYS0yKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQtZ2VvbG9jYXRpb24uaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtZ2VvbG9jYXRpb24tY291bnRyeWNvZGVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNvdW50cnlDb2RlPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogRm9yIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzLCB0aGUgdHdvLWxldHRlciBjb2RlIGZvciBhIHN0YXRlIG9mIHRoZSBVbml0ZWQgU3RhdGVzLiBSb3V0ZSA1MyBkb2Vzbid0IHN1cHBvcnQgYW55IG90aGVyIHZhbHVlcyBmb3IgYFN1YmRpdmlzaW9uQ29kZWAgLiBGb3IgYSBsaXN0IG9mIHN0YXRlIGFiYnJldmlhdGlvbnMsIHNlZSBbQXBwZW5kaXggQjogVHdv4oCTTGV0dGVyIFN0YXRlIGFuZCBQb3NzZXNzaW9uIEFiYnJldmlhdGlvbnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwczovL3BlLnVzcHMuY29tL3RleHQvcHViMjgvMjhhcGIuaHRtKSBvbiB0aGUgVW5pdGVkIFN0YXRlcyBQb3N0YWwgU2VydmljZSB3ZWJzaXRlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB5b3Ugc3BlY2lmeSBgc3ViZGl2aXNpb25jb2RlYCAsIHlvdSBtdXN0IGFsc28gc3BlY2lmeSBgVVNgIGZvciBgQ291bnRyeUNvZGVgIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC1nZW9sb2NhdGlvbi5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1nZW9sb2NhdGlvbi1zdWJkaXZpc2lvbmNvZGVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHN1YmRpdmlzaW9uQ29kZT86IHN0cmluZztcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgR2VvTG9jYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgR2VvTG9jYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5SZWNvcmRTZXRHcm91cF9HZW9Mb2NhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY29udGluZW50Q29kZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jb250aW5lbnRDb2RlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjb3VudHJ5Q29kZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jb3VudHJ5Q29kZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc3ViZGl2aXNpb25Db2RlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnN1YmRpdmlzaW9uQ29kZSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJHZW9Mb2NhdGlvblByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRHcm91cC5HZW9Mb2NhdGlvbmAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgR2VvTG9jYXRpb25Qcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6Um91dGU1Mzo6UmVjb3JkU2V0R3JvdXAuR2VvTG9jYXRpb25gIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuUmVjb3JkU2V0R3JvdXBHZW9Mb2NhdGlvblByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5SZWNvcmRTZXRHcm91cF9HZW9Mb2NhdGlvblByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBDb250aW5lbnRDb2RlOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNvbnRpbmVudENvZGUpLFxuICAgICAgICBDb3VudHJ5Q29kZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5jb3VudHJ5Q29kZSksXG4gICAgICAgIFN1YmRpdmlzaW9uQ29kZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zdWJkaXZpc2lvbkNvZGUpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5SZWNvcmRTZXRHcm91cEdlb0xvY2F0aW9uUHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5SZWNvcmRTZXRHcm91cC5HZW9Mb2NhdGlvblByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB7XG4gICAgaWYgKGNkay5pc1Jlc29sdmFibGVPYmplY3QocHJvcGVydGllcykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblJlY29yZFNldEdyb3VwLkdlb0xvY2F0aW9uUHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjb250aW5lbnRDb2RlJywgJ0NvbnRpbmVudENvZGUnLCBwcm9wZXJ0aWVzLkNvbnRpbmVudENvZGUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ29udGluZW50Q29kZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY291bnRyeUNvZGUnLCAnQ291bnRyeUNvZGUnLCBwcm9wZXJ0aWVzLkNvdW50cnlDb2RlICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkNvdW50cnlDb2RlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzdWJkaXZpc2lvbkNvZGUnLCAnU3ViZGl2aXNpb25Db2RlJywgcHJvcGVydGllcy5TdWJkaXZpc2lvbkNvZGUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuU3ViZGl2aXNpb25Db2RlKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuUmVjb3JkU2V0R3JvdXAge1xuICAgIC8qKlxuICAgICAqIEluZm9ybWF0aW9uIGFib3V0IG9uZSByZWNvcmQgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUuXG4gICAgICpcbiAgICAgKiBAc3RydWN0XG4gICAgICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBSZWNvcmRTZXRQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiAqQWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMgb25seToqIEluZm9ybWF0aW9uIGFib3V0IHRoZSBBV1MgcmVzb3VyY2UsIHN1Y2ggYXMgYSBDbG91ZEZyb250IGRpc3RyaWJ1dGlvbiBvciBhbiBBbWF6b24gUzMgYnVja2V0LCB0aGF0IHlvdSB3YW50IHRvIHJvdXRlIHRyYWZmaWMgdG8uXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSdyZSBjcmVhdGluZyByZXNvdXJjZSByZWNvcmRzIHNldHMgZm9yIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSwgbm90ZSB0aGUgZm9sbG93aW5nOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIFlvdSBjYW4ndCBjcmVhdGUgYW4gYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldCBpbiBhIHByaXZhdGUgaG9zdGVkIHpvbmUgdG8gcm91dGUgdHJhZmZpYyB0byBhIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9uLlxuICAgICAgICAgKiAtIEZvciBpbmZvcm1hdGlvbiBhYm91dCBjcmVhdGluZyBmYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiBhIHByaXZhdGUgaG9zdGVkIHpvbmUsIHNlZSBbQ29uZmlndXJpbmcgRmFpbG92ZXIgaW4gYSBQcml2YXRlIEhvc3RlZCBab25lXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLXByaXZhdGUtaG9zdGVkLXpvbmVzLmh0bWwpIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LWFsaWFzdGFyZ2V0XG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBhbGlhc1RhcmdldD86IENmblJlY29yZFNldEdyb3VwLkFsaWFzVGFyZ2V0UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBgQ2ZuUmVjb3JkU2V0R3JvdXAuUmVjb3JkU2V0UHJvcGVydHkuQ2lkclJvdXRpbmdDb25maWdgXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtY2lkcnJvdXRpbmdjb25maWdcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGNpZHJSb3V0aW5nQ29uZmlnPzogQ2ZuUmVjb3JkU2V0R3JvdXAuQ2lkclJvdXRpbmdDb25maWdQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqICpGYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cyBvbmx5OiogVG8gY29uZmlndXJlIGZhaWxvdmVyLCB5b3UgYWRkIHRoZSBgRmFpbG92ZXJgIGVsZW1lbnQgdG8gdHdvIHJlc291cmNlIHJlY29yZCBzZXRzLiBGb3Igb25lIHJlc291cmNlIHJlY29yZCBzZXQsIHlvdSBzcGVjaWZ5IGBQUklNQVJZYCBhcyB0aGUgdmFsdWUgZm9yIGBGYWlsb3ZlcmAgOyBmb3IgdGhlIG90aGVyIHJlc291cmNlIHJlY29yZCBzZXQsIHlvdSBzcGVjaWZ5IGBTRUNPTkRBUllgIC4gSW4gYWRkaXRpb24sIHlvdSBpbmNsdWRlIHRoZSBgSGVhbHRoQ2hlY2tJZGAgZWxlbWVudCBhbmQgc3BlY2lmeSB0aGUgaGVhbHRoIGNoZWNrIHRoYXQgeW91IHdhbnQgQW1hem9uIFJvdXRlIDUzIHRvIHBlcmZvcm0gZm9yIGVhY2ggcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICpcbiAgICAgICAgICogRXhjZXB0IHdoZXJlIG5vdGVkLCB0aGUgZm9sbG93aW5nIGZhaWxvdmVyIGJlaGF2aW9ycyBhc3N1bWUgdGhhdCB5b3UgaGF2ZSBpbmNsdWRlZCB0aGUgYEhlYWx0aENoZWNrSWRgIGVsZW1lbnQgaW4gYm90aCByZXNvdXJjZSByZWNvcmQgc2V0czpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBXaGVuIHRoZSBwcmltYXJ5IHJlc291cmNlIHJlY29yZCBzZXQgaXMgaGVhbHRoeSwgUm91dGUgNTMgcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgd2l0aCB0aGUgYXBwbGljYWJsZSB2YWx1ZSBmcm9tIHRoZSBwcmltYXJ5IHJlc291cmNlIHJlY29yZCBzZXQgcmVnYXJkbGVzcyBvZiB0aGUgaGVhbHRoIG9mIHRoZSBzZWNvbmRhcnkgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICogLSBXaGVuIHRoZSBwcmltYXJ5IHJlc291cmNlIHJlY29yZCBzZXQgaXMgdW5oZWFsdGh5IGFuZCB0aGUgc2Vjb25kYXJ5IHJlc291cmNlIHJlY29yZCBzZXQgaXMgaGVhbHRoeSwgUm91dGUgNTMgcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgd2l0aCB0aGUgYXBwbGljYWJsZSB2YWx1ZSBmcm9tIHRoZSBzZWNvbmRhcnkgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICogLSBXaGVuIHRoZSBzZWNvbmRhcnkgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGFwcGxpY2FibGUgdmFsdWUgZnJvbSB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0IHJlZ2FyZGxlc3Mgb2YgdGhlIGhlYWx0aCBvZiB0aGUgcHJpbWFyeSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAgICAgKiAtIElmIHlvdSBvbWl0IHRoZSBgSGVhbHRoQ2hlY2tJZGAgZWxlbWVudCBmb3IgdGhlIHNlY29uZGFyeSByZXNvdXJjZSByZWNvcmQgc2V0LCBhbmQgaWYgdGhlIHByaW1hcnkgcmVzb3VyY2UgcmVjb3JkIHNldCBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIGFsd2F5cyByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoIHRoZSBhcHBsaWNhYmxlIHZhbHVlIGZyb20gdGhlIHNlY29uZGFyeSByZXNvdXJjZSByZWNvcmQgc2V0LiBUaGlzIGlzIHRydWUgcmVnYXJkbGVzcyBvZiB0aGUgaGVhbHRoIG9mIHRoZSBhc3NvY2lhdGVkIGVuZHBvaW50LlxuICAgICAgICAgKlxuICAgICAgICAgKiBZb3UgY2FuJ3QgY3JlYXRlIG5vbi1mYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgdmFsdWVzIGZvciB0aGUgYE5hbWVgIGFuZCBgVHlwZWAgZWxlbWVudHMgYXMgZmFpbG92ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciBmYWlsb3ZlciBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cywgeW91IG11c3QgYWxzbyBpbmNsdWRlIHRoZSBgRXZhbHVhdGVUYXJnZXRIZWFsdGhgIGVsZW1lbnQgYW5kIHNldCB0aGUgdmFsdWUgdG8gdHJ1ZS5cbiAgICAgICAgICpcbiAgICAgICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgY29uZmlndXJpbmcgZmFpbG92ZXIgZm9yIFJvdXRlIDUzLCBzZWUgdGhlIGZvbGxvd2luZyB0b3BpY3MgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiA6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gW1JvdXRlIDUzIEhlYWx0aCBDaGVja3MgYW5kIEROUyBGYWlsb3Zlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci5odG1sKVxuICAgICAgICAgKiAtIFtDb25maWd1cmluZyBGYWlsb3ZlciBpbiBhIFByaXZhdGUgSG9zdGVkIFpvbmVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9kbnMtZmFpbG92ZXItcHJpdmF0ZS1ob3N0ZWQtem9uZXMuaHRtbClcbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1mYWlsb3ZlclxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZmFpbG92ZXI/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiAqR2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgb25seToqIEEgY29tcGxleCB0eXBlIHRoYXQgbGV0cyB5b3UgY29udHJvbCBob3cgQW1hem9uIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIGJhc2VkIG9uIHRoZSBnZW9ncmFwaGljIG9yaWdpbiBvZiB0aGUgcXVlcnkuIEZvciBleGFtcGxlLCBpZiB5b3Ugd2FudCBhbGwgcXVlcmllcyBmcm9tIEFmcmljYSB0byBiZSByb3V0ZWQgdG8gYSB3ZWIgc2VydmVyIHdpdGggYW4gSVAgYWRkcmVzcyBvZiBgMTkyLjAuMi4xMTFgICwgY3JlYXRlIGEgcmVzb3VyY2UgcmVjb3JkIHNldCB3aXRoIGEgYFR5cGVgIG9mIGBBYCBhbmQgYSBgQ29udGluZW50Q29kZWAgb2YgYEFGYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gQWx0aG91Z2ggY3JlYXRpbmcgZ2VvbG9jYXRpb24gYW5kIGdlb2xvY2F0aW9uIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzIGluIGEgcHJpdmF0ZSBob3N0ZWQgem9uZSBpcyBhbGxvd2VkLCBpdCdzIG5vdCBzdXBwb3J0ZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIElmIHlvdSBjcmVhdGUgc2VwYXJhdGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yIG92ZXJsYXBwaW5nIGdlb2dyYXBoaWMgcmVnaW9ucyAoZm9yIGV4YW1wbGUsIG9uZSByZXNvdXJjZSByZWNvcmQgc2V0IGZvciBhIGNvbnRpbmVudCBhbmQgb25lIGZvciBhIGNvdW50cnkgb24gdGhlIHNhbWUgY29udGluZW50KSwgcHJpb3JpdHkgZ29lcyB0byB0aGUgc21hbGxlc3QgZ2VvZ3JhcGhpYyByZWdpb24uIFRoaXMgYWxsb3dzIHlvdSB0byByb3V0ZSBtb3N0IHF1ZXJpZXMgZm9yIGEgY29udGluZW50IHRvIG9uZSByZXNvdXJjZSBhbmQgdG8gcm91dGUgcXVlcmllcyBmb3IgYSBjb3VudHJ5IG9uIHRoYXQgY29udGluZW50IHRvIGEgZGlmZmVyZW50IHJlc291cmNlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBZb3UgY2FuJ3QgY3JlYXRlIHR3byBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IHNwZWNpZnkgdGhlIHNhbWUgZ2VvZ3JhcGhpYyBsb2NhdGlvbi5cbiAgICAgICAgICpcbiAgICAgICAgICogVGhlIHZhbHVlIGAqYCBpbiB0aGUgYENvdW50cnlDb2RlYCBlbGVtZW50IG1hdGNoZXMgYWxsIGdlb2dyYXBoaWMgbG9jYXRpb25zIHRoYXQgYXJlbid0IHNwZWNpZmllZCBpbiBvdGhlciBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgdmFsdWVzIGZvciB0aGUgYE5hbWVgIGFuZCBgVHlwZWAgZWxlbWVudHMuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gR2VvbG9jYXRpb24gd29ya3MgYnkgbWFwcGluZyBJUCBhZGRyZXNzZXMgdG8gbG9jYXRpb25zLiBIb3dldmVyLCBzb21lIElQIGFkZHJlc3NlcyBhcmVuJ3QgbWFwcGVkIHRvIGdlb2dyYXBoaWMgbG9jYXRpb25zLCBzbyBldmVuIGlmIHlvdSBjcmVhdGUgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBjb3ZlciBhbGwgc2V2ZW4gY29udGluZW50cywgUm91dGUgNTMgd2lsbCByZWNlaXZlIHNvbWUgRE5TIHF1ZXJpZXMgZnJvbSBsb2NhdGlvbnMgdGhhdCBpdCBjYW4ndCBpZGVudGlmeS4gV2UgcmVjb21tZW5kIHRoYXQgeW91IGNyZWF0ZSBhIHJlc291cmNlIHJlY29yZCBzZXQgZm9yIHdoaWNoIHRoZSB2YWx1ZSBvZiBgQ291bnRyeUNvZGVgIGlzIGAqYCAuIFR3byBncm91cHMgb2YgcXVlcmllcyBhcmUgcm91dGVkIHRvIHRoZSByZXNvdXJjZSB0aGF0IHlvdSBzcGVjaWZ5IGluIHRoaXMgcmVjb3JkOiBxdWVyaWVzIHRoYXQgY29tZSBmcm9tIGxvY2F0aW9ucyBmb3Igd2hpY2ggeW91IGhhdmVuJ3QgY3JlYXRlZCBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cyBhbmQgcXVlcmllcyBmcm9tIElQIGFkZHJlc3NlcyB0aGF0IGFyZW4ndCBtYXBwZWQgdG8gYSBsb2NhdGlvbi4gSWYgeW91IGRvbid0IGNyZWF0ZSBhIGAqYCByZXNvdXJjZSByZWNvcmQgc2V0LCBSb3V0ZSA1MyByZXR1cm5zIGEgXCJubyBhbnN3ZXJcIiByZXNwb25zZSBmb3IgcXVlcmllcyBmcm9tIHRob3NlIGxvY2F0aW9ucy5cbiAgICAgICAgICpcbiAgICAgICAgICogWW91IGNhbid0IGNyZWF0ZSBub24tZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIHZhbHVlcyBmb3IgdGhlIGBOYW1lYCBhbmQgYFR5cGVgIGVsZW1lbnRzIGFzIGdlb2xvY2F0aW9uIHJlc291cmNlIHJlY29yZCBzZXRzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LWdlb2xvY2F0aW9uXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBnZW9Mb2NhdGlvbj86IENmblJlY29yZFNldEdyb3VwLkdlb0xvY2F0aW9uUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB5b3Ugd2FudCBBbWF6b24gUm91dGUgNTMgdG8gcmV0dXJuIHRoaXMgcmVzb3VyY2UgcmVjb3JkIHNldCBpbiByZXNwb25zZSB0byBhIEROUyBxdWVyeSBvbmx5IHdoZW4gdGhlIHN0YXR1cyBvZiBhIGhlYWx0aCBjaGVjayBpcyBoZWFsdGh5LCBpbmNsdWRlIHRoZSBgSGVhbHRoQ2hlY2tJZGAgZWxlbWVudCBhbmQgc3BlY2lmeSB0aGUgSUQgb2YgdGhlIGFwcGxpY2FibGUgaGVhbHRoIGNoZWNrLlxuICAgICAgICAgKlxuICAgICAgICAgKiBSb3V0ZSA1MyBkZXRlcm1pbmVzIHdoZXRoZXIgYSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIGhlYWx0aHkgYmFzZWQgb24gb25lIG9mIHRoZSBmb2xsb3dpbmc6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gQnkgcGVyaW9kaWNhbGx5IHNlbmRpbmcgYSByZXF1ZXN0IHRvIHRoZSBlbmRwb2ludCB0aGF0IGlzIHNwZWNpZmllZCBpbiB0aGUgaGVhbHRoIGNoZWNrXG4gICAgICAgICAqIC0gQnkgYWdncmVnYXRpbmcgdGhlIHN0YXR1cyBvZiBhIHNwZWNpZmllZCBncm91cCBvZiBoZWFsdGggY2hlY2tzIChjYWxjdWxhdGVkIGhlYWx0aCBjaGVja3MpXG4gICAgICAgICAqIC0gQnkgZGV0ZXJtaW5pbmcgdGhlIGN1cnJlbnQgc3RhdGUgb2YgYSBDbG91ZFdhdGNoIGFsYXJtIChDbG91ZFdhdGNoIG1ldHJpYyBoZWFsdGggY2hlY2tzKVxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFJvdXRlIDUzIGRvZXNuJ3QgY2hlY2sgdGhlIGhlYWx0aCBvZiB0aGUgZW5kcG9pbnQgdGhhdCBpcyBzcGVjaWZpZWQgaW4gdGhlIHJlc291cmNlIHJlY29yZCBzZXQsIGZvciBleGFtcGxlLCB0aGUgZW5kcG9pbnQgc3BlY2lmaWVkIGJ5IHRoZSBJUCBhZGRyZXNzIGluIHRoZSBgVmFsdWVgIGVsZW1lbnQuIFdoZW4geW91IGFkZCBhIGBIZWFsdGhDaGVja0lkYCBlbGVtZW50IHRvIGEgcmVzb3VyY2UgcmVjb3JkIHNldCwgUm91dGUgNTMgY2hlY2tzIHRoZSBoZWFsdGggb2YgdGhlIGVuZHBvaW50IHRoYXQgeW91IHNwZWNpZmllZCBpbiB0aGUgaGVhbHRoIGNoZWNrLlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIHRoZSBmb2xsb3dpbmcgdG9waWNzIGluIHRoZSAqQW1hem9uIFJvdXRlIDUzIERldmVsb3BlciBHdWlkZSogOlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIFtIb3cgQW1hem9uIFJvdXRlIDUzIERldGVybWluZXMgV2hldGhlciBhbiBFbmRwb2ludCBJcyBIZWFsdGh5XShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLWRldGVybWluaW5nLWhlYWx0aC1vZi1lbmRwb2ludHMuaHRtbClcbiAgICAgICAgICogLSBbUm91dGUgNTMgSGVhbHRoIENoZWNrcyBhbmQgRE5TIEZhaWxvdmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLmh0bWwpXG4gICAgICAgICAqIC0gW0NvbmZpZ3VyaW5nIEZhaWxvdmVyIGluIGEgUHJpdmF0ZSBIb3N0ZWQgWm9uZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL2Rucy1mYWlsb3Zlci1wcml2YXRlLWhvc3RlZC16b25lcy5odG1sKVxuICAgICAgICAgKlxuICAgICAgICAgKiAqV2hlbiB0byBTcGVjaWZ5IEhlYWx0aENoZWNrSWQqXG4gICAgICAgICAqXG4gICAgICAgICAqIFNwZWNpZnlpbmcgYSB2YWx1ZSBmb3IgYEhlYWx0aENoZWNrSWRgIGlzIHVzZWZ1bCBvbmx5IHdoZW4gUm91dGUgNTMgaXMgY2hvb3NpbmcgYmV0d2VlbiB0d28gb3IgbW9yZSByZXNvdXJjZSByZWNvcmQgc2V0cyB0byByZXNwb25kIHRvIGEgRE5TIHF1ZXJ5LCBhbmQgeW91IHdhbnQgUm91dGUgNTMgdG8gYmFzZSB0aGUgY2hvaWNlIGluIHBhcnQgb24gdGhlIHN0YXR1cyBvZiBhIGhlYWx0aCBjaGVjay4gQ29uZmlndXJpbmcgaGVhbHRoIGNoZWNrcyBtYWtlcyBzZW5zZSBvbmx5IGluIHRoZSBmb2xsb3dpbmcgY29uZmlndXJhdGlvbnM6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKk5vbi1hbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cyogOiBZb3UncmUgY2hlY2tpbmcgdGhlIGhlYWx0aCBvZiBhIGdyb3VwIG9mIG5vbi1hbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgcm91dGluZyBwb2xpY3ksIG5hbWUsIGFuZCB0eXBlIChzdWNoIGFzIG11bHRpcGxlIHdlaWdodGVkIHJlY29yZHMgbmFtZWQgd3d3LmV4YW1wbGUuY29tIHdpdGggYSB0eXBlIG9mIEEpIGFuZCB5b3Ugc3BlY2lmeSBoZWFsdGggY2hlY2sgSURzIGZvciBhbGwgdGhlIHJlc291cmNlIHJlY29yZCBzZXRzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB0aGUgaGVhbHRoIGNoZWNrIHN0YXR1cyBmb3IgYSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIGhlYWx0aHksIFJvdXRlIDUzIGluY2x1ZGVzIHRoZSByZWNvcmQgYW1vbmcgdGhlIHJlY29yZHMgdGhhdCBpdCByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB0aGUgaGVhbHRoIGNoZWNrIHN0YXR1cyBmb3IgYSByZXNvdXJjZSByZWNvcmQgc2V0IGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgc3RvcHMgcmVzcG9uZGluZyB0byBETlMgcXVlcmllcyB1c2luZyB0aGUgdmFsdWUgZm9yIHRoYXQgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgdGhlIGhlYWx0aCBjaGVjayBzdGF0dXMgZm9yIGFsbCByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiB0aGUgZ3JvdXAgaXMgdW5oZWFsdGh5LCBSb3V0ZSA1MyBjb25zaWRlcnMgYWxsIHJlc291cmNlIHJlY29yZCBzZXRzIGluIHRoZSBncm91cCBoZWFsdGh5IGFuZCByZXNwb25kcyB0byBETlMgcXVlcmllcyBhY2NvcmRpbmdseS5cbiAgICAgICAgICogLSAqQWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMqIDogWW91IHNwZWNpZnkgdGhlIGZvbGxvd2luZyBzZXR0aW5nczpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBZb3Ugc2V0IGBFdmFsdWF0ZVRhcmdldEhlYWx0aGAgdG8gdHJ1ZSBmb3IgYW4gYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldCBpbiBhIGdyb3VwIG9mIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSByb3V0aW5nIHBvbGljeSwgbmFtZSwgYW5kIHR5cGUgKHN1Y2ggYXMgbXVsdGlwbGUgd2VpZ2h0ZWQgcmVjb3JkcyBuYW1lZCB3d3cuZXhhbXBsZS5jb20gd2l0aCBhIHR5cGUgb2YgQSkuXG4gICAgICAgICAqIC0gWW91IGNvbmZpZ3VyZSB0aGUgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldCB0byByb3V0ZSB0cmFmZmljIHRvIGEgbm9uLWFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQgaW4gdGhlIHNhbWUgaG9zdGVkIHpvbmUuXG4gICAgICAgICAqIC0gWW91IHNwZWNpZnkgYSBoZWFsdGggY2hlY2sgSUQgZm9yIHRoZSBub24tYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICpcbiAgICAgICAgICogSWYgdGhlIGhlYWx0aCBjaGVjayBzdGF0dXMgaXMgaGVhbHRoeSwgUm91dGUgNTMgY29uc2lkZXJzIHRoZSBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0IHRvIGJlIGhlYWx0aHkgYW5kIGluY2x1ZGVzIHRoZSBhbGlhcyByZWNvcmQgYW1vbmcgdGhlIHJlY29yZHMgdGhhdCBpdCByZXNwb25kcyB0byBETlMgcXVlcmllcyB3aXRoLlxuICAgICAgICAgKlxuICAgICAgICAgKiBJZiB0aGUgaGVhbHRoIGNoZWNrIHN0YXR1cyBpcyB1bmhlYWx0aHksIFJvdXRlIDUzIHN0b3BzIHJlc3BvbmRpbmcgdG8gRE5TIHF1ZXJpZXMgdXNpbmcgdGhlIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gVGhlIGFsaWFzIHJlc291cmNlIHJlY29yZCBzZXQgY2FuIGFsc28gcm91dGUgdHJhZmZpYyB0byBhICpncm91cCogb2Ygbm9uLWFsaWFzIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSByb3V0aW5nIHBvbGljeSwgbmFtZSwgYW5kIHR5cGUuIEluIHRoYXQgY29uZmlndXJhdGlvbiwgYXNzb2NpYXRlIGhlYWx0aCBjaGVja3Mgd2l0aCBhbGwgb2YgdGhlIHJlc291cmNlIHJlY29yZCBzZXRzIGluIHRoZSBncm91cCBvZiBub24tYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICAgICAqXG4gICAgICAgICAqICpHZW9sb2NhdGlvbiBSb3V0aW5nKlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgZ2VvbG9jYXRpb24gcmVzb3VyY2UgcmVjb3JkIHNldHMsIGlmIGFuIGVuZHBvaW50IGlzIHVuaGVhbHRoeSwgUm91dGUgNTMgbG9va3MgZm9yIGEgcmVzb3VyY2UgcmVjb3JkIHNldCBmb3IgdGhlIGxhcmdlciwgYXNzb2NpYXRlZCBnZW9ncmFwaGljIHJlZ2lvbi4gRm9yIGV4YW1wbGUsIHN1cHBvc2UgeW91IGhhdmUgcmVzb3VyY2UgcmVjb3JkIHNldHMgZm9yIGEgc3RhdGUgaW4gdGhlIFVuaXRlZCBTdGF0ZXMsIGZvciB0aGUgZW50aXJlIFVuaXRlZCBTdGF0ZXMsIGZvciBOb3J0aCBBbWVyaWNhLCBhbmQgYSByZXNvdXJjZSByZWNvcmQgc2V0IHRoYXQgaGFzIGAqYCBmb3IgYENvdW50cnlDb2RlYCBpcyBgKmAgLCB3aGljaCBhcHBsaWVzIHRvIGFsbCBsb2NhdGlvbnMuIElmIHRoZSBlbmRwb2ludCBmb3IgdGhlIHN0YXRlIHJlc291cmNlIHJlY29yZCBzZXQgaXMgdW5oZWFsdGh5LCBSb3V0ZSA1MyBjaGVja3MgZm9yIGhlYWx0aHkgcmVzb3VyY2UgcmVjb3JkIHNldHMgaW4gdGhlIGZvbGxvd2luZyBvcmRlciB1bnRpbCBpdCBmaW5kcyBhIHJlc291cmNlIHJlY29yZCBzZXQgZm9yIHdoaWNoIHRoZSBlbmRwb2ludCBpcyBoZWFsdGh5OlxuICAgICAgICAgKlxuICAgICAgICAgKiAtIFRoZSBVbml0ZWQgU3RhdGVzXG4gICAgICAgICAqIC0gTm9ydGggQW1lcmljYVxuICAgICAgICAgKiAtIFRoZSBkZWZhdWx0IHJlc291cmNlIHJlY29yZCBzZXRcbiAgICAgICAgICpcbiAgICAgICAgICogKlNwZWNpZnlpbmcgdGhlIEhlYWx0aCBDaGVjayBFbmRwb2ludCBieSBEb21haW4gTmFtZSpcbiAgICAgICAgICpcbiAgICAgICAgICogSWYgeW91ciBoZWFsdGggY2hlY2tzIHNwZWNpZnkgdGhlIGVuZHBvaW50IG9ubHkgYnkgZG9tYWluIG5hbWUsIHdlIHJlY29tbWVuZCB0aGF0IHlvdSBjcmVhdGUgYSBzZXBhcmF0ZSBoZWFsdGggY2hlY2sgZm9yIGVhY2ggZW5kcG9pbnQuIEZvciBleGFtcGxlLCBjcmVhdGUgYSBoZWFsdGggY2hlY2sgZm9yIGVhY2ggYEhUVFBgIHNlcnZlciB0aGF0IGlzIHNlcnZpbmcgY29udGVudCBmb3IgYHd3dy5leGFtcGxlLmNvbWAgLiBGb3IgdGhlIHZhbHVlIG9mIGBGdWxseVF1YWxpZmllZERvbWFpbk5hbWVgICwgc3BlY2lmeSB0aGUgZG9tYWluIG5hbWUgb2YgdGhlIHNlcnZlciAoc3VjaCBhcyBgdXMtZWFzdC0yLXd3dy5leGFtcGxlLmNvbWAgKSwgbm90IHRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0cyAoIGB3d3cuZXhhbXBsZS5jb21gICkuXG4gICAgICAgICAqXG4gICAgICAgICAqID4gSGVhbHRoIGNoZWNrIHJlc3VsdHMgd2lsbCBiZSB1bnByZWRpY3RhYmxlIGlmIHlvdSBkbyB0aGUgZm9sbG93aW5nOlxuICAgICAgICAgKiA+XG4gICAgICAgICAqID4gLSBDcmVhdGUgYSBoZWFsdGggY2hlY2sgdGhhdCBoYXMgdGhlIHNhbWUgdmFsdWUgZm9yIGBGdWxseVF1YWxpZmllZERvbWFpbk5hbWVgIGFzIHRoZSBuYW1lIG9mIGEgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICogPiAtIEFzc29jaWF0ZSB0aGF0IGhlYWx0aCBjaGVjayB3aXRoIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LWhlYWx0aGNoZWNraWRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGhlYWx0aENoZWNrSWQ/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgSUQgb2YgdGhlIGhvc3RlZCB6b25lIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlIHJlY29yZHMgaW4uXG4gICAgICAgICAqXG4gICAgICAgICAqIFNwZWNpZnkgZWl0aGVyIGBIb3N0ZWRab25lTmFtZWAgb3IgYEhvc3RlZFpvbmVJZGAgLCBidXQgbm90IGJvdGguIElmIHlvdSBoYXZlIG11bHRpcGxlIGhvc3RlZCB6b25lcyB3aXRoIHRoZSBzYW1lIGRvbWFpbiBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSB1c2luZyBgSG9zdGVkWm9uZUlkYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtaG9zdGVkem9uZWlkXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBob3N0ZWRab25lSWQ/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbmFtZSBvZiB0aGUgaG9zdGVkIHpvbmUgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUgcmVjb3JkcyBpbi4gWW91IG11c3QgaW5jbHVkZSBhIHRyYWlsaW5nIGRvdCAoZm9yIGV4YW1wbGUsIGB3d3cuZXhhbXBsZS5jb20uYCApIGFzIHBhcnQgb2YgdGhlIGBIb3N0ZWRab25lTmFtZWAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBXaGVuIHlvdSBjcmVhdGUgYSBzdGFjayB1c2luZyBhbiBgQVdTOjpSb3V0ZTUzOjpSZWNvcmRTZXRgIHRoYXQgc3BlY2lmaWVzIGBIb3N0ZWRab25lTmFtZWAgLCBBV1MgQ2xvdWRGb3JtYXRpb24gYXR0ZW1wdHMgdG8gZmluZCBhIGhvc3RlZCB6b25lIHdob3NlIG5hbWUgbWF0Y2hlcyB0aGUgYEhvc3RlZFpvbmVOYW1lYCAuIElmIEFXUyBDbG91ZEZvcm1hdGlvbiBjYW4ndCBmaW5kIGEgaG9zdGVkIHpvbmUgd2l0aCBhIG1hdGNoaW5nIGRvbWFpbiBuYW1lLCBvciBpZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIGhvc3RlZCB6b25lIHdpdGggdGhlIHNwZWNpZmllZCBkb21haW4gbmFtZSwgQVdTIENsb3VkRm9ybWF0aW9uIHdpbGwgbm90IGNyZWF0ZSB0aGUgc3RhY2suXG4gICAgICAgICAqXG4gICAgICAgICAqIFNwZWNpZnkgZWl0aGVyIGBIb3N0ZWRab25lTmFtZWAgb3IgYEhvc3RlZFpvbmVJZGAgLCBidXQgbm90IGJvdGguIElmIHlvdSBoYXZlIG11bHRpcGxlIGhvc3RlZCB6b25lcyB3aXRoIHRoZSBzYW1lIGRvbWFpbiBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBob3N0ZWQgem9uZSB1c2luZyBgSG9zdGVkWm9uZUlkYCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtaG9zdGVkem9uZW5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IGhvc3RlZFpvbmVOYW1lPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogKk11bHRpdmFsdWUgYW5zd2VyIHJlc291cmNlIHJlY29yZCBzZXRzIG9ubHkqIDogVG8gcm91dGUgdHJhZmZpYyBhcHByb3hpbWF0ZWx5IHJhbmRvbWx5IHRvIG11bHRpcGxlIHJlc291cmNlcywgc3VjaCBhcyB3ZWIgc2VydmVycywgY3JlYXRlIG9uZSBtdWx0aXZhbHVlIGFuc3dlciByZWNvcmQgZm9yIGVhY2ggcmVzb3VyY2UgYW5kIHNwZWNpZnkgYHRydWVgIGZvciBgTXVsdGlWYWx1ZUFuc3dlcmAgLiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gSWYgeW91IGFzc29jaWF0ZSBhIGhlYWx0aCBjaGVjayB3aXRoIGEgbXVsdGl2YWx1ZSBhbnN3ZXIgcmVzb3VyY2UgcmVjb3JkIHNldCwgQW1hem9uIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgSVAgYWRkcmVzcyBvbmx5IHdoZW4gdGhlIGhlYWx0aCBjaGVjayBpcyBoZWFsdGh5LlxuICAgICAgICAgKiAtIElmIHlvdSBkb24ndCBhc3NvY2lhdGUgYSBoZWFsdGggY2hlY2sgd2l0aCBhIG11bHRpdmFsdWUgYW5zd2VyIHJlY29yZCwgUm91dGUgNTMgYWx3YXlzIGNvbnNpZGVycyB0aGUgcmVjb3JkIHRvIGJlIGhlYWx0aHkuXG4gICAgICAgICAqIC0gUm91dGUgNTMgcmVzcG9uZHMgdG8gRE5TIHF1ZXJpZXMgd2l0aCB1cCB0byBlaWdodCBoZWFsdGh5IHJlY29yZHM7IGlmIHlvdSBoYXZlIGVpZ2h0IG9yIGZld2VyIGhlYWx0aHkgcmVjb3JkcywgUm91dGUgNTMgcmVzcG9uZHMgdG8gYWxsIEROUyBxdWVyaWVzIHdpdGggYWxsIHRoZSBoZWFsdGh5IHJlY29yZHMuXG4gICAgICAgICAqIC0gSWYgeW91IGhhdmUgbW9yZSB0aGFuIGVpZ2h0IGhlYWx0aHkgcmVjb3JkcywgUm91dGUgNTMgcmVzcG9uZHMgdG8gZGlmZmVyZW50IEROUyByZXNvbHZlcnMgd2l0aCBkaWZmZXJlbnQgY29tYmluYXRpb25zIG9mIGhlYWx0aHkgcmVjb3Jkcy5cbiAgICAgICAgICogLSBXaGVuIGFsbCByZWNvcmRzIGFyZSB1bmhlYWx0aHksIFJvdXRlIDUzIHJlc3BvbmRzIHRvIEROUyBxdWVyaWVzIHdpdGggdXAgdG8gZWlnaHQgdW5oZWFsdGh5IHJlY29yZHMuXG4gICAgICAgICAqIC0gSWYgYSByZXNvdXJjZSBiZWNvbWVzIHVuYXZhaWxhYmxlIGFmdGVyIGEgcmVzb2x2ZXIgY2FjaGVzIGEgcmVzcG9uc2UsIGNsaWVudCBzb2Z0d2FyZSB0eXBpY2FsbHkgdHJpZXMgYW5vdGhlciBvZiB0aGUgSVAgYWRkcmVzc2VzIGluIHRoZSByZXNwb25zZS5cbiAgICAgICAgICpcbiAgICAgICAgICogWW91IGNhbid0IGNyZWF0ZSBtdWx0aXZhbHVlIGFuc3dlciBhbGlhcyByZWNvcmRzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LW11bHRpdmFsdWVhbnN3ZXJcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IG11bHRpVmFsdWVBbnN3ZXI/OiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogRm9yIGBDaGFuZ2VSZXNvdXJjZVJlY29yZFNldHNgIHJlcXVlc3RzLCB0aGUgbmFtZSBvZiB0aGUgcmVjb3JkIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlLCB1cGRhdGUsIG9yIGRlbGV0ZS4gRm9yIGBMaXN0UmVzb3VyY2VSZWNvcmRTZXRzYCByZXNwb25zZXMsIHRoZSBuYW1lIG9mIGEgcmVjb3JkIGluIHRoZSBzcGVjaWZpZWQgaG9zdGVkIHpvbmUuXG4gICAgICAgICAqXG4gICAgICAgICAqICpDaGFuZ2VSZXNvdXJjZVJlY29yZFNldHMgT25seSpcbiAgICAgICAgICpcbiAgICAgICAgICogRW50ZXIgYSBmdWxseSBxdWFsaWZpZWQgZG9tYWluIG5hbWUsIGZvciBleGFtcGxlLCBgd3d3LmV4YW1wbGUuY29tYCAuIFlvdSBjYW4gb3B0aW9uYWxseSBpbmNsdWRlIGEgdHJhaWxpbmcgZG90LiBJZiB5b3Ugb21pdCB0aGUgdHJhaWxpbmcgZG90LCBBbWF6b24gUm91dGUgNTMgYXNzdW1lcyB0aGF0IHRoZSBkb21haW4gbmFtZSB0aGF0IHlvdSBzcGVjaWZ5IGlzIGZ1bGx5IHF1YWxpZmllZC4gVGhpcyBtZWFucyB0aGF0IFJvdXRlIDUzIHRyZWF0cyBgd3d3LmV4YW1wbGUuY29tYCAod2l0aG91dCBhIHRyYWlsaW5nIGRvdCkgYW5kIGB3d3cuZXhhbXBsZS5jb20uYCAod2l0aCBhIHRyYWlsaW5nIGRvdCkgYXMgaWRlbnRpY2FsLlxuICAgICAgICAgKlxuICAgICAgICAgKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgaG93IHRvIHNwZWNpZnkgY2hhcmFjdGVycyBvdGhlciB0aGFuIGBhLXpgICwgYDAtOWAgLCBhbmQgYC1gIChoeXBoZW4pIGFuZCBob3cgdG8gc3BlY2lmeSBpbnRlcm5hdGlvbmFsaXplZCBkb21haW4gbmFtZXMsIHNlZSBbRE5TIERvbWFpbiBOYW1lIEZvcm1hdF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL0RvbWFpbk5hbWVGb3JtYXQuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIFlvdSBjYW4gdXNlIHRoZSBhc3RlcmlzayAoKikgd2lsZGNhcmQgdG8gcmVwbGFjZSB0aGUgbGVmdG1vc3QgbGFiZWwgaW4gYSBkb21haW4gbmFtZSwgZm9yIGV4YW1wbGUsIGAqLmV4YW1wbGUuY29tYCAuIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBUaGUgKiBtdXN0IHJlcGxhY2UgdGhlIGVudGlyZSBsYWJlbC4gRm9yIGV4YW1wbGUsIHlvdSBjYW4ndCBzcGVjaWZ5IGAqcHJvZC5leGFtcGxlLmNvbWAgb3IgYHByb2QqLmV4YW1wbGUuY29tYCAuXG4gICAgICAgICAqIC0gVGhlICogY2FuJ3QgcmVwbGFjZSBhbnkgb2YgdGhlIG1pZGRsZSBsYWJlbHMsIGZvciBleGFtcGxlLCBtYXJrZXRpbmcuKi5leGFtcGxlLmNvbS5cbiAgICAgICAgICogLSBJZiB5b3UgaW5jbHVkZSAqIGluIGFueSBwb3NpdGlvbiBvdGhlciB0aGFuIHRoZSBsZWZ0bW9zdCBsYWJlbCBpbiBhIGRvbWFpbiBuYW1lLCBETlMgdHJlYXRzIGl0IGFzIGFuICogY2hhcmFjdGVyIChBU0NJSSA0MiksIG5vdCBhcyBhIHdpbGRjYXJkLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IFlvdSBjYW4ndCB1c2UgdGhlICogd2lsZGNhcmQgZm9yIHJlc291cmNlIHJlY29yZHMgc2V0cyB0aGF0IGhhdmUgYSB0eXBlIG9mIE5TLlxuICAgICAgICAgKlxuICAgICAgICAgKiBZb3UgY2FuIHVzZSB0aGUgKiB3aWxkY2FyZCBhcyB0aGUgbGVmdG1vc3QgbGFiZWwgaW4gYSBkb21haW4gbmFtZSwgZm9yIGV4YW1wbGUsIGAqLmV4YW1wbGUuY29tYCAuIFlvdSBjYW4ndCB1c2UgYW4gKiBmb3Igb25lIG9mIHRoZSBtaWRkbGUgbGFiZWxzLCBmb3IgZXhhbXBsZSwgYG1hcmtldGluZy4qLmV4YW1wbGUuY29tYCAuIEluIGFkZGl0aW9uLCB0aGUgKiBtdXN0IHJlcGxhY2UgdGhlIGVudGlyZSBsYWJlbDsgZm9yIGV4YW1wbGUsIHlvdSBjYW4ndCBzcGVjaWZ5IGBwcm9kKi5leGFtcGxlLmNvbWAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LW5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqICpMYXRlbmN5LWJhc2VkIHJlc291cmNlIHJlY29yZCBzZXRzIG9ubHk6KiBUaGUgQW1hem9uIEVDMiBSZWdpb24gd2hlcmUgeW91IGNyZWF0ZWQgdGhlIHJlc291cmNlIHRoYXQgdGhpcyByZXNvdXJjZSByZWNvcmQgc2V0IHJlZmVycyB0by4gVGhlIHJlc291cmNlIHR5cGljYWxseSBpcyBhbiBBV1MgcmVzb3VyY2UsIHN1Y2ggYXMgYW4gRUMyIGluc3RhbmNlIG9yIGFuIEVMQiBsb2FkIGJhbGFuY2VyLCBhbmQgaXMgcmVmZXJyZWQgdG8gYnkgYW4gSVAgYWRkcmVzcyBvciBhIEROUyBkb21haW4gbmFtZSwgZGVwZW5kaW5nIG9uIHRoZSByZWNvcmQgdHlwZS5cbiAgICAgICAgICpcbiAgICAgICAgICogV2hlbiBBbWF6b24gUm91dGUgNTMgcmVjZWl2ZXMgYSBETlMgcXVlcnkgZm9yIGEgZG9tYWluIG5hbWUgYW5kIHR5cGUgZm9yIHdoaWNoIHlvdSBoYXZlIGNyZWF0ZWQgbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0cywgUm91dGUgNTMgc2VsZWN0cyB0aGUgbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0IHRoYXQgaGFzIHRoZSBsb3dlc3QgbGF0ZW5jeSBiZXR3ZWVuIHRoZSBlbmQgdXNlciBhbmQgdGhlIGFzc29jaWF0ZWQgQW1hem9uIEVDMiBSZWdpb24uIFJvdXRlIDUzIHRoZW4gcmV0dXJucyB0aGUgdmFsdWUgdGhhdCBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIHNlbGVjdGVkIHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICAgICAqXG4gICAgICAgICAqIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBZb3UgY2FuIG9ubHkgc3BlY2lmeSBvbmUgYFJlc291cmNlUmVjb3JkYCBwZXIgbGF0ZW5jeSByZXNvdXJjZSByZWNvcmQgc2V0LlxuICAgICAgICAgKiAtIFlvdSBjYW4gb25seSBjcmVhdGUgb25lIGxhdGVuY3kgcmVzb3VyY2UgcmVjb3JkIHNldCBmb3IgZWFjaCBBbWF6b24gRUMyIFJlZ2lvbi5cbiAgICAgICAgICogLSBZb3UgYXJlbid0IHJlcXVpcmVkIHRvIGNyZWF0ZSBsYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXRzIGZvciBhbGwgQW1hem9uIEVDMiBSZWdpb25zLiBSb3V0ZSA1MyB3aWxsIGNob29zZSB0aGUgcmVnaW9uIHdpdGggdGhlIGJlc3QgbGF0ZW5jeSBmcm9tIGFtb25nIHRoZSByZWdpb25zIHRoYXQgeW91IGNyZWF0ZSBsYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXRzIGZvci5cbiAgICAgICAgICogLSBZb3UgY2FuJ3QgY3JlYXRlIG5vbi1sYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSB2YWx1ZXMgZm9yIHRoZSBgTmFtZWAgYW5kIGBUeXBlYCBlbGVtZW50cyBhcyBsYXRlbmN5IHJlc291cmNlIHJlY29yZCBzZXRzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLXJvdXRlNTMtcmVjb3Jkc2V0Lmh0bWwjY2ZuLXJvdXRlNTMtcmVjb3Jkc2V0LXJlZ2lvblxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcmVnaW9uPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogSW5mb3JtYXRpb24gYWJvdXQgdGhlIHJlY29yZHMgdGhhdCB5b3Ugd2FudCB0byBjcmVhdGUuIEVhY2ggcmVjb3JkIHNob3VsZCBiZSBpbiB0aGUgZm9ybWF0IGFwcHJvcHJpYXRlIGZvciB0aGUgcmVjb3JkIHR5cGUgc3BlY2lmaWVkIGJ5IHRoZSBgVHlwZWAgcHJvcGVydHkuIEZvciBpbmZvcm1hdGlvbiBhYm91dCBkaWZmZXJlbnQgcmVjb3JkIHR5cGVzIGFuZCB0aGVpciByZWNvcmQgZm9ybWF0cywgc2VlIFtWYWx1ZXMgVGhhdCBZb3UgU3BlY2lmeSBXaGVuIFlvdSBDcmVhdGUgb3IgRWRpdCBBbWF6b24gUm91dGUgNTMgUmVjb3Jkc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL3Jlc291cmNlLXJlY29yZC1zZXRzLXZhbHVlcy5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1yZXNvdXJjZXJlY29yZHNcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHJlc291cmNlUmVjb3Jkcz86IHN0cmluZ1tdO1xuICAgICAgICAvKipcbiAgICAgICAgICogKlJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSBhIHJvdXRpbmcgcG9saWN5IG90aGVyIHRoYW4gc2ltcGxlOiogQW4gaWRlbnRpZmllciB0aGF0IGRpZmZlcmVudGlhdGVzIGFtb25nIG11bHRpcGxlIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBjb21iaW5hdGlvbiBvZiBuYW1lIGFuZCB0eXBlLCBzdWNoIGFzIG11bHRpcGxlIHdlaWdodGVkIHJlc291cmNlIHJlY29yZCBzZXRzIG5hbWVkIGFjbWUuZXhhbXBsZS5jb20gdGhhdCBoYXZlIGEgdHlwZSBvZiBBLiBJbiBhIGdyb3VwIG9mIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBuYW1lIGFuZCB0eXBlLCB0aGUgdmFsdWUgb2YgYFNldElkZW50aWZpZXJgIG11c3QgYmUgdW5pcXVlIGZvciBlYWNoIHJlc291cmNlIHJlY29yZCBzZXQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEZvciBpbmZvcm1hdGlvbiBhYm91dCByb3V0aW5nIHBvbGljaWVzLCBzZWUgW0Nob29zaW5nIGEgUm91dGluZyBQb2xpY3ldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9yb3V0aW5nLXBvbGljeS5odG1sKSBpbiB0aGUgKkFtYXpvbiBSb3V0ZSA1MyBEZXZlbG9wZXIgR3VpZGUqIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC1zZXRpZGVudGlmaWVyXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBzZXRJZGVudGlmaWVyPzogc3RyaW5nO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHJlc291cmNlIHJlY29yZCBjYWNoZSB0aW1lIHRvIGxpdmUgKFRUTCksIGluIHNlY29uZHMuIE5vdGUgdGhlIGZvbGxvd2luZzpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBJZiB5b3UncmUgY3JlYXRpbmcgb3IgdXBkYXRpbmcgYW4gYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldCwgb21pdCBgVFRMYCAuIEFtYXpvbiBSb3V0ZSA1MyB1c2VzIHRoZSB2YWx1ZSBvZiBgVFRMYCBmb3IgdGhlIGFsaWFzIHRhcmdldC5cbiAgICAgICAgICogLSBJZiB5b3UncmUgYXNzb2NpYXRpbmcgdGhpcyByZXNvdXJjZSByZWNvcmQgc2V0IHdpdGggYSBoZWFsdGggY2hlY2sgKGlmIHlvdSdyZSBhZGRpbmcgYSBgSGVhbHRoQ2hlY2tJZGAgZWxlbWVudCksIHdlIHJlY29tbWVuZCB0aGF0IHlvdSBzcGVjaWZ5IGEgYFRUTGAgb2YgNjAgc2Vjb25kcyBvciBsZXNzIHNvIGNsaWVudHMgcmVzcG9uZCBxdWlja2x5IHRvIGNoYW5nZXMgaW4gaGVhbHRoIHN0YXR1cy5cbiAgICAgICAgICogLSBBbGwgb2YgdGhlIHJlc291cmNlIHJlY29yZCBzZXRzIGluIGEgZ3JvdXAgb2Ygd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgbXVzdCBoYXZlIHRoZSBzYW1lIHZhbHVlIGZvciBgVFRMYCAuXG4gICAgICAgICAqIC0gSWYgYSBncm91cCBvZiB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0cyBpbmNsdWRlcyBvbmUgb3IgbW9yZSB3ZWlnaHRlZCBhbGlhcyByZXNvdXJjZSByZWNvcmQgc2V0cyBmb3Igd2hpY2ggdGhlIGFsaWFzIHRhcmdldCBpcyBhbiBFTEIgbG9hZCBiYWxhbmNlciwgd2UgcmVjb21tZW5kIHRoYXQgeW91IHNwZWNpZnkgYSBgVFRMYCBvZiA2MCBzZWNvbmRzIGZvciBhbGwgb2YgdGhlIG5vbi1hbGlhcyB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgbmFtZSBhbmQgdHlwZS4gVmFsdWVzIG90aGVyIHRoYW4gNjAgc2Vjb25kcyAodGhlIFRUTCBmb3IgbG9hZCBiYWxhbmNlcnMpIHdpbGwgY2hhbmdlIHRoZSBlZmZlY3Qgb2YgdGhlIHZhbHVlcyB0aGF0IHlvdSBzcGVjaWZ5IGZvciBgV2VpZ2h0YCAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtdHRsXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB0dGw/OiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgRE5TIHJlY29yZCB0eXBlLiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgZGlmZmVyZW50IHJlY29yZCB0eXBlcyBhbmQgaG93IGRhdGEgaXMgZW5jb2RlZCBmb3IgdGhlbSwgc2VlIFtTdXBwb3J0ZWQgRE5TIFJlc291cmNlIFJlY29yZCBUeXBlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL1JvdXRlNTMvbGF0ZXN0L0RldmVsb3Blckd1aWRlL1Jlc291cmNlUmVjb3JkVHlwZXMuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIFZhbGlkIHZhbHVlcyBmb3IgYmFzaWMgcmVzb3VyY2UgcmVjb3JkIHNldHM6IGBBYCB8IGBBQUFBYCB8IGBDQUFgIHwgYENOQU1FYCB8IGBEU2AgfCBgTVhgIHwgYE5BUFRSYCB8IGBOU2AgfCBgUFRSYCB8IGBTT0FgIHwgYFNQRmAgfCBgU1JWYCB8IGBUWFRgXG4gICAgICAgICAqXG4gICAgICAgICAqIFZhbHVlcyBmb3Igd2VpZ2h0ZWQsIGxhdGVuY3ksIGdlb2xvY2F0aW9uLCBhbmQgZmFpbG92ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHM6IGBBYCB8IGBBQUFBYCB8IGBDQUFgIHwgYENOQU1FYCB8IGBNWGAgfCBgTkFQVFJgIHwgYFBUUmAgfCBgU1BGYCB8IGBTUlZgIHwgYFRYVGAgLiBXaGVuIGNyZWF0aW5nIGEgZ3JvdXAgb2Ygd2VpZ2h0ZWQsIGxhdGVuY3ksIGdlb2xvY2F0aW9uLCBvciBmYWlsb3ZlciByZXNvdXJjZSByZWNvcmQgc2V0cywgc3BlY2lmeSB0aGUgc2FtZSB2YWx1ZSBmb3IgYWxsIG9mIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0cyBpbiB0aGUgZ3JvdXAuXG4gICAgICAgICAqXG4gICAgICAgICAqIFZhbGlkIHZhbHVlcyBmb3IgbXVsdGl2YWx1ZSBhbnN3ZXIgcmVzb3VyY2UgcmVjb3JkIHNldHM6IGBBYCB8IGBBQUFBYCB8IGBNWGAgfCBgTkFQVFJgIHwgYFBUUmAgfCBgU1BGYCB8IGBTUlZgIHwgYFRYVGBcbiAgICAgICAgICpcbiAgICAgICAgICogPiBTUEYgcmVjb3JkcyB3ZXJlIGZvcm1lcmx5IHVzZWQgdG8gdmVyaWZ5IHRoZSBpZGVudGl0eSBvZiB0aGUgc2VuZGVyIG9mIGVtYWlsIG1lc3NhZ2VzLiBIb3dldmVyLCB3ZSBubyBsb25nZXIgcmVjb21tZW5kIHRoYXQgeW91IGNyZWF0ZSByZXNvdXJjZSByZWNvcmQgc2V0cyBmb3Igd2hpY2ggdGhlIHZhbHVlIG9mIGBUeXBlYCBpcyBgU1BGYCAuIFJGQyA3MjA4LCAqU2VuZGVyIFBvbGljeSBGcmFtZXdvcmsgKFNQRikgZm9yIEF1dGhvcml6aW5nIFVzZSBvZiBEb21haW5zIGluIEVtYWlsLCBWZXJzaW9uIDEqICwgaGFzIGJlZW4gdXBkYXRlZCB0byBzYXksIFwiLi4uW0lddHMgZXhpc3RlbmNlIGFuZCBtZWNoYW5pc20gZGVmaW5lZCBpbiBbUkZDNDQwOF0gaGF2ZSBsZWQgdG8gc29tZSBpbnRlcm9wZXJhYmlsaXR5IGlzc3Vlcy4gQWNjb3JkaW5nbHksIGl0cyB1c2UgaXMgbm8gbG9uZ2VyIGFwcHJvcHJpYXRlIGZvciBTUEYgdmVyc2lvbiAxOyBpbXBsZW1lbnRhdGlvbnMgYXJlIG5vdCB0byB1c2UgaXQuXCIgSW4gUkZDIDcyMDgsIHNlZSBzZWN0aW9uIDE0LjEsIFtUaGUgU1BGIEROUyBSZWNvcmQgVHlwZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzcyMDgjc2VjdGlvbi0xNC4xKSAuXG4gICAgICAgICAqXG4gICAgICAgICAqIFZhbHVlcyBmb3IgYWxpYXMgcmVzb3VyY2UgcmVjb3JkIHNldHM6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gKkFtYXpvbiBBUEkgR2F0ZXdheSBjdXN0b20gcmVnaW9uYWwgQVBJcyBhbmQgZWRnZS1vcHRpbWl6ZWQgQVBJczoqIGBBYFxuICAgICAgICAgKiAtICpDbG91ZEZyb250IGRpc3RyaWJ1dGlvbnM6KiBgQWBcbiAgICAgICAgICpcbiAgICAgICAgICogSWYgSVB2NiBpcyBlbmFibGVkIGZvciB0aGUgZGlzdHJpYnV0aW9uLCBjcmVhdGUgdHdvIHJlc291cmNlIHJlY29yZCBzZXRzIHRvIHJvdXRlIHRyYWZmaWMgdG8geW91ciBkaXN0cmlidXRpb24sIG9uZSB3aXRoIGEgdmFsdWUgb2YgYEFgIGFuZCBvbmUgd2l0aCBhIHZhbHVlIG9mIGBBQUFBYCAuXG4gICAgICAgICAqIC0gKkFtYXpvbiBBUEkgR2F0ZXdheSBlbnZpcm9ubWVudCB0aGF0IGhhcyBhIHJlZ2lvbmFsaXplZCBzdWJkb21haW4qIDogYEFgXG4gICAgICAgICAqIC0gKkVMQiBsb2FkIGJhbGFuY2VyczoqIGBBYCB8IGBBQUFBYFxuICAgICAgICAgKiAtICpBbWF6b24gUzMgYnVja2V0czoqIGBBYFxuICAgICAgICAgKiAtICpBbWF6b24gVmlydHVhbCBQcml2YXRlIENsb3VkIGludGVyZmFjZSBWUEMgZW5kcG9pbnRzKiBgQWBcbiAgICAgICAgICogLSAqQW5vdGhlciByZXNvdXJjZSByZWNvcmQgc2V0IGluIHRoaXMgaG9zdGVkIHpvbmU6KiBTcGVjaWZ5IHRoZSB0eXBlIG9mIHRoZSByZXNvdXJjZSByZWNvcmQgc2V0IHRoYXQgeW91J3JlIGNyZWF0aW5nIHRoZSBhbGlhcyBmb3IuIEFsbCB2YWx1ZXMgYXJlIHN1cHBvcnRlZCBleGNlcHQgYE5TYCBhbmQgYFNPQWAgLlxuICAgICAgICAgKlxuICAgICAgICAgKiA+IElmIHlvdSdyZSBjcmVhdGluZyBhbiBhbGlhcyByZWNvcmQgdGhhdCBoYXMgdGhlIHNhbWUgbmFtZSBhcyB0aGUgaG9zdGVkIHpvbmUgKGtub3duIGFzIHRoZSB6b25lIGFwZXgpLCB5b3UgY2FuJ3Qgcm91dGUgdHJhZmZpYyB0byBhIHJlY29yZCBmb3Igd2hpY2ggdGhlIHZhbHVlIG9mIGBUeXBlYCBpcyBgQ05BTUVgIC4gVGhpcyBpcyBiZWNhdXNlIHRoZSBhbGlhcyByZWNvcmQgbXVzdCBoYXZlIHRoZSBzYW1lIHR5cGUgYXMgdGhlIHJlY29yZCB5b3UncmUgcm91dGluZyB0cmFmZmljIHRvLCBhbmQgY3JlYXRpbmcgYSBDTkFNRSByZWNvcmQgZm9yIHRoZSB6b25lIGFwZXggaXNuJ3Qgc3VwcG9ydGVkIGV2ZW4gZm9yIGFuIGFsaWFzIHJlY29yZC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1yb3V0ZTUzLXJlY29yZHNldC5odG1sI2Nmbi1yb3V0ZTUzLXJlY29yZHNldC10eXBlXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB0eXBlOiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiAqV2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMgb25seToqIEFtb25nIHJlc291cmNlIHJlY29yZCBzZXRzIHRoYXQgaGF2ZSB0aGUgc2FtZSBjb21iaW5hdGlvbiBvZiBETlMgbmFtZSBhbmQgdHlwZSwgYSB2YWx1ZSB0aGF0IGRldGVybWluZXMgdGhlIHByb3BvcnRpb24gb2YgRE5TIHF1ZXJpZXMgdGhhdCBBbWF6b24gUm91dGUgNTMgcmVzcG9uZHMgdG8gdXNpbmcgdGhlIGN1cnJlbnQgcmVzb3VyY2UgcmVjb3JkIHNldC4gUm91dGUgNTMgY2FsY3VsYXRlcyB0aGUgc3VtIG9mIHRoZSB3ZWlnaHRzIGZvciB0aGUgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIGNvbWJpbmF0aW9uIG9mIEROUyBuYW1lIGFuZCB0eXBlLiBSb3V0ZSA1MyB0aGVuIHJlc3BvbmRzIHRvIHF1ZXJpZXMgYmFzZWQgb24gdGhlIHJhdGlvIG9mIGEgcmVzb3VyY2UncyB3ZWlnaHQgdG8gdGhlIHRvdGFsLiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICAgICAqXG4gICAgICAgICAqIC0gWW91IG11c3Qgc3BlY2lmeSBhIHZhbHVlIGZvciB0aGUgYFdlaWdodGAgZWxlbWVudCBmb3IgZXZlcnkgd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICogLSBZb3UgY2FuIG9ubHkgc3BlY2lmeSBvbmUgYFJlc291cmNlUmVjb3JkYCBwZXIgd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldC5cbiAgICAgICAgICogLSBZb3UgY2FuJ3QgY3JlYXRlIGxhdGVuY3ksIGZhaWxvdmVyLCBvciBnZW9sb2NhdGlvbiByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgdmFsdWVzIGZvciB0aGUgYE5hbWVgIGFuZCBgVHlwZWAgZWxlbWVudHMgYXMgd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMuXG4gICAgICAgICAqIC0gWW91IGNhbiBjcmVhdGUgYSBtYXhpbXVtIG9mIDEwMCB3ZWlnaHRlZCByZXNvdXJjZSByZWNvcmQgc2V0cyB0aGF0IGhhdmUgdGhlIHNhbWUgdmFsdWVzIGZvciB0aGUgYE5hbWVgIGFuZCBgVHlwZWAgZWxlbWVudHMuXG4gICAgICAgICAqIC0gRm9yIHdlaWdodGVkIChidXQgbm90IHdlaWdodGVkIGFsaWFzKSByZXNvdXJjZSByZWNvcmQgc2V0cywgaWYgeW91IHNldCBgV2VpZ2h0YCB0byBgMGAgZm9yIGEgcmVzb3VyY2UgcmVjb3JkIHNldCwgUm91dGUgNTMgbmV2ZXIgcmVzcG9uZHMgdG8gcXVlcmllcyB3aXRoIHRoZSBhcHBsaWNhYmxlIHZhbHVlIGZvciB0aGF0IHJlc291cmNlIHJlY29yZCBzZXQuIEhvd2V2ZXIsIGlmIHlvdSBzZXQgYFdlaWdodGAgdG8gYDBgIGZvciBhbGwgcmVzb3VyY2UgcmVjb3JkIHNldHMgdGhhdCBoYXZlIHRoZSBzYW1lIGNvbWJpbmF0aW9uIG9mIEROUyBuYW1lIGFuZCB0eXBlLCB0cmFmZmljIGlzIHJvdXRlZCB0byBhbGwgcmVzb3VyY2VzIHdpdGggZXF1YWwgcHJvYmFiaWxpdHkuXG4gICAgICAgICAqXG4gICAgICAgICAqIFRoZSBlZmZlY3Qgb2Ygc2V0dGluZyBgV2VpZ2h0YCB0byBgMGAgaXMgZGlmZmVyZW50IHdoZW4geW91IGFzc29jaWF0ZSBoZWFsdGggY2hlY2tzIHdpdGggd2VpZ2h0ZWQgcmVzb3VyY2UgcmVjb3JkIHNldHMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW09wdGlvbnMgZm9yIENvbmZpZ3VyaW5nIFJvdXRlIDUzIEFjdGl2ZS1BY3RpdmUgYW5kIEFjdGl2ZS1QYXNzaXZlIEZhaWxvdmVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vUm91dGU1My9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvZG5zLWZhaWxvdmVyLWNvbmZpZ3VyaW5nLW9wdGlvbnMuaHRtbCkgaW4gdGhlICpBbWF6b24gUm91dGUgNTMgRGV2ZWxvcGVyIEd1aWRlKiAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtcm91dGU1My1yZWNvcmRzZXQuaHRtbCNjZm4tcm91dGU1My1yZWNvcmRzZXQtd2VpZ2h0XG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSB3ZWlnaHQ/OiBudW1iZXI7XG4gICAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYFJlY29yZFNldFByb3BlcnR5YFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBSZWNvcmRTZXRQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5SZWNvcmRTZXRHcm91cF9SZWNvcmRTZXRQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2FsaWFzVGFyZ2V0JywgQ2ZuUmVjb3JkU2V0R3JvdXBfQWxpYXNUYXJnZXRQcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5hbGlhc1RhcmdldCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignY2lkclJvdXRpbmdDb25maWcnLCBDZm5SZWNvcmRTZXRHcm91cF9DaWRyUm91dGluZ0NvbmZpZ1Byb3BlcnR5VmFsaWRhdG9yKShwcm9wZXJ0aWVzLmNpZHJSb3V0aW5nQ29uZmlnKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdmYWlsb3ZlcicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5mYWlsb3ZlcikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignZ2VvTG9jYXRpb24nLCBDZm5SZWNvcmRTZXRHcm91cF9HZW9Mb2NhdGlvblByb3BlcnR5VmFsaWRhdG9yKShwcm9wZXJ0aWVzLmdlb0xvY2F0aW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdoZWFsdGhDaGVja0lkJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmhlYWx0aENoZWNrSWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hvc3RlZFpvbmVJZCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5ob3N0ZWRab25lSWQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2hvc3RlZFpvbmVOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmhvc3RlZFpvbmVOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdtdWx0aVZhbHVlQW5zd2VyJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5tdWx0aVZhbHVlQW5zd2VyKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCduYW1lJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLm5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ25hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncmVnaW9uJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnJlZ2lvbikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncmVzb3VyY2VSZWNvcmRzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5yZXNvdXJjZVJlY29yZHMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3NldElkZW50aWZpZXInLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuc2V0SWRlbnRpZmllcikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndHRsJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnR0bCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndHlwZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy50eXBlKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0eXBlJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnR5cGUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3dlaWdodCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy53ZWlnaHQpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiUmVjb3JkU2V0UHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldEdyb3VwLlJlY29yZFNldGAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgUmVjb3JkU2V0UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OlJvdXRlNTM6OlJlY29yZFNldEdyb3VwLlJlY29yZFNldGAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5SZWNvcmRTZXRHcm91cFJlY29yZFNldFByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5SZWNvcmRTZXRHcm91cF9SZWNvcmRTZXRQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQWxpYXNUYXJnZXQ6IGNmblJlY29yZFNldEdyb3VwQWxpYXNUYXJnZXRQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5hbGlhc1RhcmdldCksXG4gICAgICAgIENpZHJSb3V0aW5nQ29uZmlnOiBjZm5SZWNvcmRTZXRHcm91cENpZHJSb3V0aW5nQ29uZmlnUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY2lkclJvdXRpbmdDb25maWcpLFxuICAgICAgICBGYWlsb3ZlcjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5mYWlsb3ZlciksXG4gICAgICAgIEdlb0xvY2F0aW9uOiBjZm5SZWNvcmRTZXRHcm91cEdlb0xvY2F0aW9uUHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZ2VvTG9jYXRpb24pLFxuICAgICAgICBIZWFsdGhDaGVja0lkOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmhlYWx0aENoZWNrSWQpLFxuICAgICAgICBIb3N0ZWRab25lSWQ6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaG9zdGVkWm9uZUlkKSxcbiAgICAgICAgSG9zdGVkWm9uZU5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaG9zdGVkWm9uZU5hbWUpLFxuICAgICAgICBNdWx0aVZhbHVlQW5zd2VyOiBjZGsuYm9vbGVhblRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5tdWx0aVZhbHVlQW5zd2VyKSxcbiAgICAgICAgTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5uYW1lKSxcbiAgICAgICAgUmVnaW9uOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnJlZ2lvbiksXG4gICAgICAgIFJlc291cmNlUmVjb3JkczogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMucmVzb3VyY2VSZWNvcmRzKSxcbiAgICAgICAgU2V0SWRlbnRpZmllcjogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zZXRJZGVudGlmaWVyKSxcbiAgICAgICAgVFRMOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnR0bCksXG4gICAgICAgIFR5cGU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMudHlwZSksXG4gICAgICAgIFdlaWdodDogY2RrLm51bWJlclRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy53ZWlnaHQpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5SZWNvcmRTZXRHcm91cFJlY29yZFNldFByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuUmVjb3JkU2V0R3JvdXAuUmVjb3JkU2V0UHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuUmVjb3JkU2V0R3JvdXAuUmVjb3JkU2V0UHJvcGVydHk+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdhbGlhc1RhcmdldCcsICdBbGlhc1RhcmdldCcsIHByb3BlcnRpZXMuQWxpYXNUYXJnZXQgIT0gbnVsbCA/IENmblJlY29yZFNldEdyb3VwQWxpYXNUYXJnZXRQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLkFsaWFzVGFyZ2V0KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjaWRyUm91dGluZ0NvbmZpZycsICdDaWRyUm91dGluZ0NvbmZpZycsIHByb3BlcnRpZXMuQ2lkclJvdXRpbmdDb25maWcgIT0gbnVsbCA/IENmblJlY29yZFNldEdyb3VwQ2lkclJvdXRpbmdDb25maWdQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLkNpZHJSb3V0aW5nQ29uZmlnKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdmYWlsb3ZlcicsICdGYWlsb3ZlcicsIHByb3BlcnRpZXMuRmFpbG92ZXIgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuRmFpbG92ZXIpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2dlb0xvY2F0aW9uJywgJ0dlb0xvY2F0aW9uJywgcHJvcGVydGllcy5HZW9Mb2NhdGlvbiAhPSBudWxsID8gQ2ZuUmVjb3JkU2V0R3JvdXBHZW9Mb2NhdGlvblByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuR2VvTG9jYXRpb24pIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2hlYWx0aENoZWNrSWQnLCAnSGVhbHRoQ2hlY2tJZCcsIHByb3BlcnRpZXMuSGVhbHRoQ2hlY2tJZCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5IZWFsdGhDaGVja0lkKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdob3N0ZWRab25lSWQnLCAnSG9zdGVkWm9uZUlkJywgcHJvcGVydGllcy5Ib3N0ZWRab25lSWQgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuSG9zdGVkWm9uZUlkKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdob3N0ZWRab25lTmFtZScsICdIb3N0ZWRab25lTmFtZScsIHByb3BlcnRpZXMuSG9zdGVkWm9uZU5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuSG9zdGVkWm9uZU5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ211bHRpVmFsdWVBbnN3ZXInLCAnTXVsdGlWYWx1ZUFuc3dlcicsIHByb3BlcnRpZXMuTXVsdGlWYWx1ZUFuc3dlciAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRCb29sZWFuKHByb3BlcnRpZXMuTXVsdGlWYWx1ZUFuc3dlcikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbmFtZScsICdOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5OYW1lKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdyZWdpb24nLCAnUmVnaW9uJywgcHJvcGVydGllcy5SZWdpb24gIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUmVnaW9uKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdyZXNvdXJjZVJlY29yZHMnLCAnUmVzb3VyY2VSZWNvcmRzJywgcHJvcGVydGllcy5SZXNvdXJjZVJlY29yZHMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5SZXNvdXJjZVJlY29yZHMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3NldElkZW50aWZpZXInLCAnU2V0SWRlbnRpZmllcicsIHByb3BlcnRpZXMuU2V0SWRlbnRpZmllciAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5TZXRJZGVudGlmaWVyKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0dGwnLCAnVFRMJywgcHJvcGVydGllcy5UVEwgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVFRMKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0eXBlJywgJ1R5cGUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlR5cGUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3dlaWdodCcsICdXZWlnaHQnLCBwcm9wZXJ0aWVzLldlaWdodCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXROdW1iZXIocHJvcGVydGllcy5XZWlnaHQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cbiJdfQ==
\No newline at end of file