UNPKG

@aws-cdk/aws-iam

Version:

CDK routines for easily assigning correct and minimal IAM permissions

2,142 lines 471 kB
"use strict";
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CfnVirtualMFADevice = exports.CfnUserToGroupAddition = exports.CfnUser = exports.CfnServiceLinkedRole = exports.CfnServerCertificate = exports.CfnSAMLProvider = exports.CfnRole = exports.CfnPolicy = exports.CfnOIDCProvider = exports.CfnManagedPolicy = exports.CfnInstanceProfile = exports.CfnGroup = exports.CfnAccessKey = void 0;
const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
// Copyright 2012-2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// Generated from the AWS CloudFormation Resource Specification
// See: docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html
// @cfn2ts:meta@ {"generated":"2023-06-19T15:13:00.875Z","fingerprint":"1qNJvlNlMUi/xqMxsjOr5NoHZ43ouKpsGuyRnZhbItI="}
/* eslint-disable max-len */ // This is generated code - line lengths are difficult to control
const cdk = require("@aws-cdk/core");
const cfn_parse = require("@aws-cdk/core/lib/helpers-internal");
/**
 * Determine whether the given properties match those of a `CfnAccessKeyProps`
 *
 * @param properties - the TypeScript properties of a `CfnAccessKeyProps`
 *
 * @returns the result of the validation.
 */
function CfnAccessKeyPropsValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('serial', cdk.validateNumber)(properties.serial));
    errors.collect(cdk.propertyValidator('status', cdk.validateString)(properties.status));
    errors.collect(cdk.propertyValidator('userName', cdk.requiredValidator)(properties.userName));
    errors.collect(cdk.propertyValidator('userName', cdk.validateString)(properties.userName));
    return errors.wrap('supplied properties not correct for "CfnAccessKeyProps"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::AccessKey` resource
 *
 * @param properties - the TypeScript properties of a `CfnAccessKeyProps`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::AccessKey` resource.
 */
// @ts-ignore TS6133
function cfnAccessKeyPropsToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnAccessKeyPropsValidator(properties).assertSuccess();
    return {
        UserName: cdk.stringToCloudFormation(properties.userName),
        Serial: cdk.numberToCloudFormation(properties.serial),
        Status: cdk.stringToCloudFormation(properties.status),
    };
}
// @ts-ignore TS6133
function CfnAccessKeyPropsFromCloudFormation(properties) {
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('userName', 'UserName', cfn_parse.FromCloudFormation.getString(properties.UserName));
    ret.addPropertyResult('serial', 'Serial', properties.Serial != null ? cfn_parse.FromCloudFormation.getNumber(properties.Serial) : undefined);
    ret.addPropertyResult('status', 'Status', properties.Status != null ? cfn_parse.FromCloudFormation.getString(properties.Status) : undefined);
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * A CloudFormation `AWS::IAM::AccessKey`
 *
 * Creates a new AWS secret access key and corresponding AWS access key ID for the specified user. The default status for new keys is `Active` .
 *
 * For information about quotas on the number of keys you can create, see [IAM and AWS STS quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) in the *IAM User Guide* .
 *
 * > To ensure the security of your AWS account , the secret access key is accessible only during key and user creation. You must save the key (for example, in a text file) if you want to be able to access it again. If a secret key is lost, you can rotate access keys by increasing the value of the `serial` property.
 *
 * @cloudformationResource AWS::IAM::AccessKey
 * @stability external
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-accesskey.html
 */
class CfnAccessKey extends cdk.CfnResource {
    /**
     * Create a new `AWS::IAM::AccessKey`.
     *
     * @param scope - scope in which this resource is defined
     * @param id    - scoped id of the resource
     * @param props - resource properties
     */
    constructor(scope, id, props) {
        super(scope, id, { type: CfnAccessKey.CFN_RESOURCE_TYPE_NAME, properties: props });
        try {
            jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnAccessKeyProps(props);
        }
        catch (error) {
            if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
                Error.captureStackTrace(error, CfnAccessKey);
            }
            throw error;
        }
        cdk.requireProperty(props, 'userName', this);
        this.attrSecretAccessKey = cdk.Token.asString(this.getAtt('SecretAccessKey'));
        this.userName = props.userName;
        this.serial = props.serial;
        this.status = props.status;
    }
    /**
     * A factory method that creates a new instance of this class from an object
     * containing the CloudFormation properties of this resource.
     * Used in the @aws-cdk/cloudformation-include module.
     *
     * @internal
     */
    static _fromCloudFormation(scope, id, resourceAttributes, options) {
        resourceAttributes = resourceAttributes || {};
        const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
        const propsResult = CfnAccessKeyPropsFromCloudFormation(resourceProperties);
        const ret = new CfnAccessKey(scope, id, propsResult.value);
        for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
            ret.addPropertyOverride(propKey, propVal);
        }
        options.parser.handleAttributes(ret, resourceAttributes, id);
        return ret;
    }
    /**
     * Examines the CloudFormation resource and discloses attributes.
     *
     * @param inspector - tree inspector to collect and process attributes
     *
     */
    inspect(inspector) {
        inspector.addAttribute("aws:cdk:cloudformation:type", CfnAccessKey.CFN_RESOURCE_TYPE_NAME);
        inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
    }
    get cfnProperties() {
        return {
            userName: this.userName,
            serial: this.serial,
            status: this.status,
        };
    }
    renderProperties(props) {
        return cfnAccessKeyPropsToCloudFormation(props);
    }
}
exports.CfnAccessKey = CfnAccessKey;
_a = JSII_RTTI_SYMBOL_1;
CfnAccessKey[_a] = { fqn: "@aws-cdk/aws-iam.CfnAccessKey", version: "1.204.0" };
/**
 * The CloudFormation resource type name for this resource class.
 */
CfnAccessKey.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::AccessKey";
/**
 * Determine whether the given properties match those of a `CfnGroupProps`
 *
 * @param properties - the TypeScript properties of a `CfnGroupProps`
 *
 * @returns the result of the validation.
 */
function CfnGroupPropsValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('groupName', cdk.validateString)(properties.groupName));
    errors.collect(cdk.propertyValidator('managedPolicyArns', cdk.listValidator(cdk.validateString))(properties.managedPolicyArns));
    errors.collect(cdk.propertyValidator('path', cdk.validateString)(properties.path));
    errors.collect(cdk.propertyValidator('policies', cdk.listValidator(CfnGroup_PolicyPropertyValidator))(properties.policies));
    return errors.wrap('supplied properties not correct for "CfnGroupProps"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::Group` resource
 *
 * @param properties - the TypeScript properties of a `CfnGroupProps`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::Group` resource.
 */
// @ts-ignore TS6133
function cfnGroupPropsToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnGroupPropsValidator(properties).assertSuccess();
    return {
        GroupName: cdk.stringToCloudFormation(properties.groupName),
        ManagedPolicyArns: cdk.listMapper(cdk.stringToCloudFormation)(properties.managedPolicyArns),
        Path: cdk.stringToCloudFormation(properties.path),
        Policies: cdk.listMapper(cfnGroupPolicyPropertyToCloudFormation)(properties.policies),
    };
}
// @ts-ignore TS6133
function CfnGroupPropsFromCloudFormation(properties) {
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('groupName', 'GroupName', properties.GroupName != null ? cfn_parse.FromCloudFormation.getString(properties.GroupName) : undefined);
    ret.addPropertyResult('managedPolicyArns', 'ManagedPolicyArns', properties.ManagedPolicyArns != null ? cfn_parse.FromCloudFormation.getStringArray(properties.ManagedPolicyArns) : undefined);
    ret.addPropertyResult('path', 'Path', properties.Path != null ? cfn_parse.FromCloudFormation.getString(properties.Path) : undefined);
    ret.addPropertyResult('policies', 'Policies', properties.Policies != null ? cfn_parse.FromCloudFormation.getArray(CfnGroupPolicyPropertyFromCloudFormation)(properties.Policies) : undefined);
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * A CloudFormation `AWS::IAM::Group`
 *
 * Creates a new group.
 *
 * For information about the number of groups you can create, see [Limitations on IAM Entities](https://docs.aws.amazon.com/IAM/latest/UserGuide/LimitationsOnEntities.html) in the *IAM User Guide* .
 *
 * @cloudformationResource AWS::IAM::Group
 * @stability external
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-group.html
 */
class CfnGroup extends cdk.CfnResource {
    /**
     * Create a new `AWS::IAM::Group`.
     *
     * @param scope - scope in which this resource is defined
     * @param id    - scoped id of the resource
     * @param props - resource properties
     */
    constructor(scope, id, props = {}) {
        super(scope, id, { type: CfnGroup.CFN_RESOURCE_TYPE_NAME, properties: props });
        try {
            jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnGroupProps(props);
        }
        catch (error) {
            if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
                Error.captureStackTrace(error, CfnGroup);
            }
            throw error;
        }
        this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
        this.groupName = props.groupName;
        this.managedPolicyArns = props.managedPolicyArns;
        this.path = props.path;
        this.policies = props.policies;
    }
    /**
     * A factory method that creates a new instance of this class from an object
     * containing the CloudFormation properties of this resource.
     * Used in the @aws-cdk/cloudformation-include module.
     *
     * @internal
     */
    static _fromCloudFormation(scope, id, resourceAttributes, options) {
        resourceAttributes = resourceAttributes || {};
        const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
        const propsResult = CfnGroupPropsFromCloudFormation(resourceProperties);
        const ret = new CfnGroup(scope, id, propsResult.value);
        for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
            ret.addPropertyOverride(propKey, propVal);
        }
        options.parser.handleAttributes(ret, resourceAttributes, id);
        return ret;
    }
    /**
     * Examines the CloudFormation resource and discloses attributes.
     *
     * @param inspector - tree inspector to collect and process attributes
     *
     */
    inspect(inspector) {
        inspector.addAttribute("aws:cdk:cloudformation:type", CfnGroup.CFN_RESOURCE_TYPE_NAME);
        inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
    }
    get cfnProperties() {
        return {
            groupName: this.groupName,
            managedPolicyArns: this.managedPolicyArns,
            path: this.path,
            policies: this.policies,
        };
    }
    renderProperties(props) {
        return cfnGroupPropsToCloudFormation(props);
    }
}
exports.CfnGroup = CfnGroup;
_b = JSII_RTTI_SYMBOL_1;
CfnGroup[_b] = { fqn: "@aws-cdk/aws-iam.CfnGroup", version: "1.204.0" };
/**
 * The CloudFormation resource type name for this resource class.
 */
CfnGroup.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::Group";
/**
 * Determine whether the given properties match those of a `PolicyProperty`
 *
 * @param properties - the TypeScript properties of a `PolicyProperty`
 *
 * @returns the result of the validation.
 */
function CfnGroup_PolicyPropertyValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('policyDocument', cdk.requiredValidator)(properties.policyDocument));
    errors.collect(cdk.propertyValidator('policyDocument', cdk.validateObject)(properties.policyDocument));
    errors.collect(cdk.propertyValidator('policyName', cdk.requiredValidator)(properties.policyName));
    errors.collect(cdk.propertyValidator('policyName', cdk.validateString)(properties.policyName));
    return errors.wrap('supplied properties not correct for "PolicyProperty"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::Group.Policy` resource
 *
 * @param properties - the TypeScript properties of a `PolicyProperty`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::Group.Policy` resource.
 */
// @ts-ignore TS6133
function cfnGroupPolicyPropertyToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnGroup_PolicyPropertyValidator(properties).assertSuccess();
    return {
        PolicyDocument: cdk.objectToCloudFormation(properties.policyDocument),
        PolicyName: cdk.stringToCloudFormation(properties.policyName),
    };
}
// @ts-ignore TS6133
function CfnGroupPolicyPropertyFromCloudFormation(properties) {
    if (cdk.isResolvableObject(properties)) {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('policyDocument', 'PolicyDocument', cfn_parse.FromCloudFormation.getAny(properties.PolicyDocument));
    ret.addPropertyResult('policyName', 'PolicyName', cfn_parse.FromCloudFormation.getString(properties.PolicyName));
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * Determine whether the given properties match those of a `CfnInstanceProfileProps`
 *
 * @param properties - the TypeScript properties of a `CfnInstanceProfileProps`
 *
 * @returns the result of the validation.
 */
function CfnInstanceProfilePropsValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('instanceProfileName', cdk.validateString)(properties.instanceProfileName));
    errors.collect(cdk.propertyValidator('path', cdk.validateString)(properties.path));
    errors.collect(cdk.propertyValidator('roles', cdk.requiredValidator)(properties.roles));
    errors.collect(cdk.propertyValidator('roles', cdk.listValidator(cdk.validateString))(properties.roles));
    return errors.wrap('supplied properties not correct for "CfnInstanceProfileProps"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::InstanceProfile` resource
 *
 * @param properties - the TypeScript properties of a `CfnInstanceProfileProps`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::InstanceProfile` resource.
 */
// @ts-ignore TS6133
function cfnInstanceProfilePropsToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnInstanceProfilePropsValidator(properties).assertSuccess();
    return {
        Roles: cdk.listMapper(cdk.stringToCloudFormation)(properties.roles),
        InstanceProfileName: cdk.stringToCloudFormation(properties.instanceProfileName),
        Path: cdk.stringToCloudFormation(properties.path),
    };
}
// @ts-ignore TS6133
function CfnInstanceProfilePropsFromCloudFormation(properties) {
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('roles', 'Roles', cfn_parse.FromCloudFormation.getStringArray(properties.Roles));
    ret.addPropertyResult('instanceProfileName', 'InstanceProfileName', properties.InstanceProfileName != null ? cfn_parse.FromCloudFormation.getString(properties.InstanceProfileName) : undefined);
    ret.addPropertyResult('path', 'Path', properties.Path != null ? cfn_parse.FromCloudFormation.getString(properties.Path) : undefined);
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * A CloudFormation `AWS::IAM::InstanceProfile`
 *
 * Creates a new instance profile. For information about instance profiles, see [Using instance profiles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html) .
 *
 * For information about the number of instance profiles you can create, see [IAM object quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) in the *IAM User Guide* .
 *
 * @cloudformationResource AWS::IAM::InstanceProfile
 * @stability external
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-instanceprofile.html
 */
class CfnInstanceProfile extends cdk.CfnResource {
    /**
     * Create a new `AWS::IAM::InstanceProfile`.
     *
     * @param scope - scope in which this resource is defined
     * @param id    - scoped id of the resource
     * @param props - resource properties
     */
    constructor(scope, id, props) {
        super(scope, id, { type: CfnInstanceProfile.CFN_RESOURCE_TYPE_NAME, properties: props });
        try {
            jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnInstanceProfileProps(props);
        }
        catch (error) {
            if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
                Error.captureStackTrace(error, CfnInstanceProfile);
            }
            throw error;
        }
        cdk.requireProperty(props, 'roles', this);
        this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
        this.roles = props.roles;
        this.instanceProfileName = props.instanceProfileName;
        this.path = props.path;
    }
    /**
     * A factory method that creates a new instance of this class from an object
     * containing the CloudFormation properties of this resource.
     * Used in the @aws-cdk/cloudformation-include module.
     *
     * @internal
     */
    static _fromCloudFormation(scope, id, resourceAttributes, options) {
        resourceAttributes = resourceAttributes || {};
        const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
        const propsResult = CfnInstanceProfilePropsFromCloudFormation(resourceProperties);
        const ret = new CfnInstanceProfile(scope, id, propsResult.value);
        for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
            ret.addPropertyOverride(propKey, propVal);
        }
        options.parser.handleAttributes(ret, resourceAttributes, id);
        return ret;
    }
    /**
     * Examines the CloudFormation resource and discloses attributes.
     *
     * @param inspector - tree inspector to collect and process attributes
     *
     */
    inspect(inspector) {
        inspector.addAttribute("aws:cdk:cloudformation:type", CfnInstanceProfile.CFN_RESOURCE_TYPE_NAME);
        inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
    }
    get cfnProperties() {
        return {
            roles: this.roles,
            instanceProfileName: this.instanceProfileName,
            path: this.path,
        };
    }
    renderProperties(props) {
        return cfnInstanceProfilePropsToCloudFormation(props);
    }
}
exports.CfnInstanceProfile = CfnInstanceProfile;
_c = JSII_RTTI_SYMBOL_1;
CfnInstanceProfile[_c] = { fqn: "@aws-cdk/aws-iam.CfnInstanceProfile", version: "1.204.0" };
/**
 * The CloudFormation resource type name for this resource class.
 */
CfnInstanceProfile.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::InstanceProfile";
/**
 * Determine whether the given properties match those of a `CfnManagedPolicyProps`
 *
 * @param properties - the TypeScript properties of a `CfnManagedPolicyProps`
 *
 * @returns the result of the validation.
 */
function CfnManagedPolicyPropsValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('description', cdk.validateString)(properties.description));
    errors.collect(cdk.propertyValidator('groups', cdk.listValidator(cdk.validateString))(properties.groups));
    errors.collect(cdk.propertyValidator('managedPolicyName', cdk.validateString)(properties.managedPolicyName));
    errors.collect(cdk.propertyValidator('path', cdk.validateString)(properties.path));
    errors.collect(cdk.propertyValidator('policyDocument', cdk.requiredValidator)(properties.policyDocument));
    errors.collect(cdk.propertyValidator('policyDocument', cdk.validateObject)(properties.policyDocument));
    errors.collect(cdk.propertyValidator('roles', cdk.listValidator(cdk.validateString))(properties.roles));
    errors.collect(cdk.propertyValidator('users', cdk.listValidator(cdk.validateString))(properties.users));
    return errors.wrap('supplied properties not correct for "CfnManagedPolicyProps"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::ManagedPolicy` resource
 *
 * @param properties - the TypeScript properties of a `CfnManagedPolicyProps`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::ManagedPolicy` resource.
 */
// @ts-ignore TS6133
function cfnManagedPolicyPropsToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnManagedPolicyPropsValidator(properties).assertSuccess();
    return {
        PolicyDocument: cdk.objectToCloudFormation(properties.policyDocument),
        Description: cdk.stringToCloudFormation(properties.description),
        Groups: cdk.listMapper(cdk.stringToCloudFormation)(properties.groups),
        ManagedPolicyName: cdk.stringToCloudFormation(properties.managedPolicyName),
        Path: cdk.stringToCloudFormation(properties.path),
        Roles: cdk.listMapper(cdk.stringToCloudFormation)(properties.roles),
        Users: cdk.listMapper(cdk.stringToCloudFormation)(properties.users),
    };
}
// @ts-ignore TS6133
function CfnManagedPolicyPropsFromCloudFormation(properties) {
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('policyDocument', 'PolicyDocument', cfn_parse.FromCloudFormation.getAny(properties.PolicyDocument));
    ret.addPropertyResult('description', 'Description', properties.Description != null ? cfn_parse.FromCloudFormation.getString(properties.Description) : undefined);
    ret.addPropertyResult('groups', 'Groups', properties.Groups != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Groups) : undefined);
    ret.addPropertyResult('managedPolicyName', 'ManagedPolicyName', properties.ManagedPolicyName != null ? cfn_parse.FromCloudFormation.getString(properties.ManagedPolicyName) : undefined);
    ret.addPropertyResult('path', 'Path', properties.Path != null ? cfn_parse.FromCloudFormation.getString(properties.Path) : undefined);
    ret.addPropertyResult('roles', 'Roles', properties.Roles != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Roles) : undefined);
    ret.addPropertyResult('users', 'Users', properties.Users != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Users) : undefined);
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * A CloudFormation `AWS::IAM::ManagedPolicy`
 *
 * Creates a new managed policy for your AWS account .
 *
 * This operation creates a policy version with a version identifier of `v1` and sets v1 as the policy's default version. For more information about policy versions, see [Versioning for managed policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/policies-managed-versions.html) in the *IAM User Guide* .
 *
 * As a best practice, you can validate your IAM policies. To learn more, see [Validating IAM policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_policy-validator.html) in the *IAM User Guide* .
 *
 * For more information about managed policies in general, see [Managed policies and inline policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/policies-managed-vs-inline.html) in the *IAM User Guide* .
 *
 * @cloudformationResource AWS::IAM::ManagedPolicy
 * @stability external
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-managedpolicy.html
 */
class CfnManagedPolicy extends cdk.CfnResource {
    /**
     * Create a new `AWS::IAM::ManagedPolicy`.
     *
     * @param scope - scope in which this resource is defined
     * @param id    - scoped id of the resource
     * @param props - resource properties
     */
    constructor(scope, id, props) {
        super(scope, id, { type: CfnManagedPolicy.CFN_RESOURCE_TYPE_NAME, properties: props });
        try {
            jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnManagedPolicyProps(props);
        }
        catch (error) {
            if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
                Error.captureStackTrace(error, CfnManagedPolicy);
            }
            throw error;
        }
        cdk.requireProperty(props, 'policyDocument', this);
        this.policyDocument = props.policyDocument;
        this.description = props.description;
        this.groups = props.groups;
        this.managedPolicyName = props.managedPolicyName;
        this.path = props.path;
        this.roles = props.roles;
        this.users = props.users;
    }
    /**
     * A factory method that creates a new instance of this class from an object
     * containing the CloudFormation properties of this resource.
     * Used in the @aws-cdk/cloudformation-include module.
     *
     * @internal
     */
    static _fromCloudFormation(scope, id, resourceAttributes, options) {
        resourceAttributes = resourceAttributes || {};
        const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
        const propsResult = CfnManagedPolicyPropsFromCloudFormation(resourceProperties);
        const ret = new CfnManagedPolicy(scope, id, propsResult.value);
        for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
            ret.addPropertyOverride(propKey, propVal);
        }
        options.parser.handleAttributes(ret, resourceAttributes, id);
        return ret;
    }
    /**
     * Examines the CloudFormation resource and discloses attributes.
     *
     * @param inspector - tree inspector to collect and process attributes
     *
     */
    inspect(inspector) {
        inspector.addAttribute("aws:cdk:cloudformation:type", CfnManagedPolicy.CFN_RESOURCE_TYPE_NAME);
        inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
    }
    get cfnProperties() {
        return {
            policyDocument: this.policyDocument,
            description: this.description,
            groups: this.groups,
            managedPolicyName: this.managedPolicyName,
            path: this.path,
            roles: this.roles,
            users: this.users,
        };
    }
    renderProperties(props) {
        return cfnManagedPolicyPropsToCloudFormation(props);
    }
}
exports.CfnManagedPolicy = CfnManagedPolicy;
_d = JSII_RTTI_SYMBOL_1;
CfnManagedPolicy[_d] = { fqn: "@aws-cdk/aws-iam.CfnManagedPolicy", version: "1.204.0" };
/**
 * The CloudFormation resource type name for this resource class.
 */
CfnManagedPolicy.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::ManagedPolicy";
/**
 * Determine whether the given properties match those of a `CfnOIDCProviderProps`
 *
 * @param properties - the TypeScript properties of a `CfnOIDCProviderProps`
 *
 * @returns the result of the validation.
 */
function CfnOIDCProviderPropsValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('clientIdList', cdk.listValidator(cdk.validateString))(properties.clientIdList));
    errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
    errors.collect(cdk.propertyValidator('thumbprintList', cdk.requiredValidator)(properties.thumbprintList));
    errors.collect(cdk.propertyValidator('thumbprintList', cdk.listValidator(cdk.validateString))(properties.thumbprintList));
    errors.collect(cdk.propertyValidator('url', cdk.validateString)(properties.url));
    return errors.wrap('supplied properties not correct for "CfnOIDCProviderProps"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::OIDCProvider` resource
 *
 * @param properties - the TypeScript properties of a `CfnOIDCProviderProps`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::OIDCProvider` resource.
 */
// @ts-ignore TS6133
function cfnOIDCProviderPropsToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnOIDCProviderPropsValidator(properties).assertSuccess();
    return {
        ThumbprintList: cdk.listMapper(cdk.stringToCloudFormation)(properties.thumbprintList),
        ClientIdList: cdk.listMapper(cdk.stringToCloudFormation)(properties.clientIdList),
        Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
        Url: cdk.stringToCloudFormation(properties.url),
    };
}
// @ts-ignore TS6133
function CfnOIDCProviderPropsFromCloudFormation(properties) {
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('thumbprintList', 'ThumbprintList', cfn_parse.FromCloudFormation.getStringArray(properties.ThumbprintList));
    ret.addPropertyResult('clientIdList', 'ClientIdList', properties.ClientIdList != null ? cfn_parse.FromCloudFormation.getStringArray(properties.ClientIdList) : undefined);
    ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
    ret.addPropertyResult('url', 'Url', properties.Url != null ? cfn_parse.FromCloudFormation.getString(properties.Url) : undefined);
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * A CloudFormation `AWS::IAM::OIDCProvider`
 *
 * Creates or updates an IAM entity to describe an identity provider (IdP) that supports [OpenID Connect (OIDC)](https://docs.aws.amazon.com/http://openid.net/connect/) .
 *
 * The OIDC provider that you create with this operation can be used as a principal in a role's trust policy. Such a policy establishes a trust relationship between AWS and the OIDC provider.
 *
 * When you create the IAM OIDC provider, you specify the following:
 *
 * - The URL of the OIDC identity provider (IdP) to trust
 * - A list of client IDs (also known as audiences) that identify the application or applications that are allowed to authenticate using the OIDC provider
 * - A list of tags that are attached to the specified IAM OIDC provider
 * - A list of thumbprints of one or more server certificates that the IdP uses
 *
 * You get all of this information from the OIDC IdP that you want to use to access AWS .
 *
 * When you update the IAM OIDC provider, you specify the following:
 *
 * - The URL of the OIDC identity provider (IdP) to trust
 * - A list of client IDs (also known as audiences) that replaces the existing list of client IDs associated with the OIDC IdP
 * - A list of tags that replaces the existing list of tags attached to the specified IAM OIDC provider
 * - A list of thumbprints that replaces the existing list of server certificates thumbprints that the IdP uses
 *
 * > The trust for the OIDC provider is derived from the IAM provider that this operation creates. Therefore, it is best to limit access to the [CreateOpenIDConnectProvider](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateOpenIDConnectProvider.html) operation to highly privileged users.
 *
 * @cloudformationResource AWS::IAM::OIDCProvider
 * @stability external
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-oidcprovider.html
 */
class CfnOIDCProvider extends cdk.CfnResource {
    /**
     * Create a new `AWS::IAM::OIDCProvider`.
     *
     * @param scope - scope in which this resource is defined
     * @param id    - scoped id of the resource
     * @param props - resource properties
     */
    constructor(scope, id, props) {
        super(scope, id, { type: CfnOIDCProvider.CFN_RESOURCE_TYPE_NAME, properties: props });
        try {
            jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnOIDCProviderProps(props);
        }
        catch (error) {
            if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
                Error.captureStackTrace(error, CfnOIDCProvider);
            }
            throw error;
        }
        cdk.requireProperty(props, 'thumbprintList', this);
        this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
        this.thumbprintList = props.thumbprintList;
        this.clientIdList = props.clientIdList;
        this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::IAM::OIDCProvider", props.tags, { tagPropertyName: 'tags' });
        this.url = props.url;
    }
    /**
     * A factory method that creates a new instance of this class from an object
     * containing the CloudFormation properties of this resource.
     * Used in the @aws-cdk/cloudformation-include module.
     *
     * @internal
     */
    static _fromCloudFormation(scope, id, resourceAttributes, options) {
        resourceAttributes = resourceAttributes || {};
        const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
        const propsResult = CfnOIDCProviderPropsFromCloudFormation(resourceProperties);
        const ret = new CfnOIDCProvider(scope, id, propsResult.value);
        for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
            ret.addPropertyOverride(propKey, propVal);
        }
        options.parser.handleAttributes(ret, resourceAttributes, id);
        return ret;
    }
    /**
     * Examines the CloudFormation resource and discloses attributes.
     *
     * @param inspector - tree inspector to collect and process attributes
     *
     */
    inspect(inspector) {
        inspector.addAttribute("aws:cdk:cloudformation:type", CfnOIDCProvider.CFN_RESOURCE_TYPE_NAME);
        inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
    }
    get cfnProperties() {
        return {
            thumbprintList: this.thumbprintList,
            clientIdList: this.clientIdList,
            tags: this.tags.renderTags(),
            url: this.url,
        };
    }
    renderProperties(props) {
        return cfnOIDCProviderPropsToCloudFormation(props);
    }
}
exports.CfnOIDCProvider = CfnOIDCProvider;
_e = JSII_RTTI_SYMBOL_1;
CfnOIDCProvider[_e] = { fqn: "@aws-cdk/aws-iam.CfnOIDCProvider", version: "1.204.0" };
/**
 * The CloudFormation resource type name for this resource class.
 */
CfnOIDCProvider.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::OIDCProvider";
/**
 * Determine whether the given properties match those of a `CfnPolicyProps`
 *
 * @param properties - the TypeScript properties of a `CfnPolicyProps`
 *
 * @returns the result of the validation.
 */
function CfnPolicyPropsValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('groups', cdk.listValidator(cdk.validateString))(properties.groups));
    errors.collect(cdk.propertyValidator('policyDocument', cdk.requiredValidator)(properties.policyDocument));
    errors.collect(cdk.propertyValidator('policyDocument', cdk.validateObject)(properties.policyDocument));
    errors.collect(cdk.propertyValidator('policyName', cdk.requiredValidator)(properties.policyName));
    errors.collect(cdk.propertyValidator('policyName', cdk.validateString)(properties.policyName));
    errors.collect(cdk.propertyValidator('roles', cdk.listValidator(cdk.validateString))(properties.roles));
    errors.collect(cdk.propertyValidator('users', cdk.listValidator(cdk.validateString))(properties.users));
    return errors.wrap('supplied properties not correct for "CfnPolicyProps"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::Policy` resource
 *
 * @param properties - the TypeScript properties of a `CfnPolicyProps`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::Policy` resource.
 */
// @ts-ignore TS6133
function cfnPolicyPropsToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnPolicyPropsValidator(properties).assertSuccess();
    return {
        PolicyDocument: cdk.objectToCloudFormation(properties.policyDocument),
        PolicyName: cdk.stringToCloudFormation(properties.policyName),
        Groups: cdk.listMapper(cdk.stringToCloudFormation)(properties.groups),
        Roles: cdk.listMapper(cdk.stringToCloudFormation)(properties.roles),
        Users: cdk.listMapper(cdk.stringToCloudFormation)(properties.users),
    };
}
// @ts-ignore TS6133
function CfnPolicyPropsFromCloudFormation(properties) {
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('policyDocument', 'PolicyDocument', cfn_parse.FromCloudFormation.getAny(properties.PolicyDocument));
    ret.addPropertyResult('policyName', 'PolicyName', cfn_parse.FromCloudFormation.getString(properties.PolicyName));
    ret.addPropertyResult('groups', 'Groups', properties.Groups != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Groups) : undefined);
    ret.addPropertyResult('roles', 'Roles', properties.Roles != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Roles) : undefined);
    ret.addPropertyResult('users', 'Users', properties.Users != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Users) : undefined);
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * A CloudFormation `AWS::IAM::Policy`
 *
 * Adds or updates an inline policy document that is embedded in the specified IAM user, group, or role.
 *
 * An IAM user can also have a managed policy attached to it. For information about policies, see [Managed Policies and Inline Policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/policies-managed-vs-inline.html) in the *IAM User Guide* .
 *
 * The Groups, Roles, and Users properties are optional. However, you must specify at least one of these properties.
 *
 * For information about policy documents see [Creating IAM policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html) in the *IAM User Guide* .
 *
 * For information about limits on the number of inline policies that you can embed in an identity, see [Limitations on IAM Entities](https://docs.aws.amazon.com/IAM/latest/UserGuide/LimitationsOnEntities.html) in the *IAM User Guide* .
 *
 * @cloudformationResource AWS::IAM::Policy
 * @stability external
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html
 */
class CfnPolicy extends cdk.CfnResource {
    /**
     * Create a new `AWS::IAM::Policy`.
     *
     * @param scope - scope in which this resource is defined
     * @param id    - scoped id of the resource
     * @param props - resource properties
     */
    constructor(scope, id, props) {
        super(scope, id, { type: CfnPolicy.CFN_RESOURCE_TYPE_NAME, properties: props });
        try {
            jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnPolicyProps(props);
        }
        catch (error) {
            if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
                Error.captureStackTrace(error, CfnPolicy);
            }
            throw error;
        }
        cdk.requireProperty(props, 'policyDocument', this);
        cdk.requireProperty(props, 'policyName', this);
        this.policyDocument = props.policyDocument;
        this.policyName = props.policyName;
        this.groups = props.groups;
        this.roles = props.roles;
        this.users = props.users;
    }
    /**
     * A factory method that creates a new instance of this class from an object
     * containing the CloudFormation properties of this resource.
     * Used in the @aws-cdk/cloudformation-include module.
     *
     * @internal
     */
    static _fromCloudFormation(scope, id, resourceAttributes, options) {
        resourceAttributes = resourceAttributes || {};
        const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
        const propsResult = CfnPolicyPropsFromCloudFormation(resourceProperties);
        const ret = new CfnPolicy(scope, id, propsResult.value);
        for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
            ret.addPropertyOverride(propKey, propVal);
        }
        options.parser.handleAttributes(ret, resourceAttributes, id);
        return ret;
    }
    /**
     * Examines the CloudFormation resource and discloses attributes.
     *
     * @param inspector - tree inspector to collect and process attributes
     *
     */
    inspect(inspector) {
        inspector.addAttribute("aws:cdk:cloudformation:type", CfnPolicy.CFN_RESOURCE_TYPE_NAME);
        inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
    }
    get cfnProperties() {
        return {
            policyDocument: this.policyDocument,
            policyName: this.policyName,
            groups: this.groups,
            roles: this.roles,
            users: this.users,
        };
    }
    renderProperties(props) {
        return cfnPolicyPropsToCloudFormation(props);
    }
}
exports.CfnPolicy = CfnPolicy;
_f = JSII_RTTI_SYMBOL_1;
CfnPolicy[_f] = { fqn: "@aws-cdk/aws-iam.CfnPolicy", version: "1.204.0" };
/**
 * The CloudFormation resource type name for this resource class.
 */
CfnPolicy.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::Policy";
/**
 * Determine whether the given properties match those of a `CfnRoleProps`
 *
 * @param properties - the TypeScript properties of a `CfnRoleProps`
 *
 * @returns the result of the validation.
 */
function CfnRolePropsValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('assumeRolePolicyDocument', cdk.requiredValidator)(properties.assumeRolePolicyDocument));
    errors.collect(cdk.propertyValidator('assumeRolePolicyDocument', cdk.validateObject)(properties.assumeRolePolicyDocument));
    errors.collect(cdk.propertyValidator('description', cdk.validateString)(properties.description));
    errors.collect(cdk.propertyValidator('managedPolicyArns', cdk.listValidator(cdk.validateString))(properties.managedPolicyArns));
    errors.collect(cdk.propertyValidator('maxSessionDuration', cdk.validateNumber)(properties.maxSessionDuration));
    errors.collect(cdk.propertyValidator('path', cdk.validateString)(properties.path));
    errors.collect(cdk.propertyValidator('permissionsBoundary', cdk.validateString)(properties.permissionsBoundary));
    errors.collect(cdk.propertyValidator('policies', cdk.listValidator(CfnRole_PolicyPropertyValidator))(properties.policies));
    errors.collect(cdk.propertyValidator('roleName', cdk.validateString)(properties.roleName));
    errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
    return errors.wrap('supplied properties not correct for "CfnRoleProps"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::Role` resource
 *
 * @param properties - the TypeScript properties of a `CfnRoleProps`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::Role` resource.
 */
// @ts-ignore TS6133
function cfnRolePropsToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnRolePropsValidator(properties).assertSuccess();
    return {
        AssumeRolePolicyDocument: cdk.objectToCloudFormation(properties.assumeRolePolicyDocument),
        Description: cdk.stringToCloudFormation(properties.description),
        ManagedPolicyArns: cdk.listMapper(cdk.stringToCloudFormation)(properties.managedPolicyArns),
        MaxSessionDuration: cdk.numberToCloudFormation(properties.maxSessionDuration),
        Path: cdk.stringToCloudFormation(properties.path),
        PermissionsBoundary: cdk.stringToCloudFormation(properties.permissionsBoundary),
        Policies: cdk.listMapper(cfnRolePolicyPropertyToCloudFormation)(properties.policies),
        RoleName: cdk.stringToCloudFormation(properties.roleName),
        Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
    };
}
// @ts-ignore TS6133
function CfnRolePropsFromCloudFormation(properties) {
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('assumeRolePolicyDocument', 'AssumeRolePolicyDocument', cfn_parse.FromCloudFormation.getAny(properties.AssumeRolePolicyDocument));
    ret.addPropertyResult('description', 'Description', properties.Description != null ? cfn_parse.FromCloudFormation.getString(properties.Description) : undefined);
    ret.addPropertyResult('managedPolicyArns', 'ManagedPolicyArns', properties.ManagedPolicyArns != null ? cfn_parse.FromCloudFormation.getStringArray(properties.ManagedPolicyArns) : undefined);
    ret.addPropertyResult('maxSessionDuration', 'MaxSessionDuration', properties.MaxSessionDuration != null ? cfn_parse.FromCloudFormation.getNumber(properties.MaxSessionDuration) : undefined);
    ret.addPropertyResult('path', 'Path', properties.Path != null ? cfn_parse.FromCloudFormation.getString(properties.Path) : undefined);
    ret.addPropertyResult('permissionsBoundary', 'PermissionsBoundary', properties.PermissionsBoundary != null ? cfn_parse.FromCloudFormation.getString(properties.PermissionsBoundary) : undefined);
    ret.addPropertyResult('policies', 'Policies', properties.Policies != null ? cfn_parse.FromCloudFormation.getArray(CfnRolePolicyPropertyFromCloudFormation)(properties.Policies) : undefined);
    ret.addPropertyResult('roleName', 'RoleName', properties.RoleName != null ? cfn_parse.FromCloudFormation.getString(properties.RoleName) : undefined);
    ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * A CloudFormation `AWS::IAM::Role`
 *
 * Creates a new role for your AWS account . For more information about roles, see [IAM roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/WorkingWithRoles.html) . For information about quotas for role names and the number of roles you can create, see [IAM and AWS STS quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) in the *IAM User Guide* .
 *
 * @cloudformationResource AWS::IAM::Role
 * @stability external
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html
 */
class CfnRole extends cdk.CfnResource {
    /**
     * Create a new `AWS::IAM::Role`.
     *
     * @param scope - scope in which this resource is defined
     * @param id    - scoped id of the resource
     * @param props - resource properties
     */
    constructor(scope, id, props) {
        super(scope, id, { type: CfnRole.CFN_RESOURCE_TYPE_NAME, properties: props });
        try {
            jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnRoleProps(props);
        }
        catch (error) {
            if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
                Error.captureStackTrace(error, CfnRole);
            }
            throw error;
        }
        cdk.requireProperty(props, 'assumeRolePolicyDocument', this);
        this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
        this.attrRoleId = cdk.Token.asString(this.getAtt('RoleId'));
        this.assumeRolePolicyDocument = props.assumeRolePolicyDocument;
        this.description = props.description;
        this.managedPolicyArns = props.managedPolicyArns;
        this.maxSessionDuration = props.maxSessionDuration;
        this.path = props.path;
        this.permissionsBoundary = props.permissionsBoundary;
        this.policies = props.policies;
        this.roleName = props.roleName;
        this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::IAM::Role", props.tags, { tagPropertyName: 'tags' });
    }
    /**
     * A factory method that creates a new instance of this class from an object
     * containing the CloudFormation properties of this resource.
     * Used in the @aws-cdk/cloudformation-include module.
     *
     * @internal
     */
    static _fromCloudFormation(scope, id, resourceAttributes, options) {
        resourceAttributes = resourceAttributes || {};
        const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
        const propsResult = CfnRolePropsFromCloudFormation(resourceProperties);
        const ret = new CfnRole(scope, id, propsResult.value);
        for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
            ret.addPropertyOverride(propKey, propVal);
        }
        options.parser.handleAttributes(ret, resourceAttributes, id);
        return ret;
    }
    /**
     * Examines the CloudFormation resource and discloses attributes.
     *
     * @param inspector - tree inspector to collect and process attributes
     *
     */
    inspect(inspector) {
        inspector.addAttribute("aws:cdk:cloudformation:type", CfnRole.CFN_RESOURCE_TYPE_NAME);
        inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
    }
    get cfnProperties() {
        return {
            assumeRolePolicyDocument: this.assumeRolePolicyDocument,
            description: this.description,
            managedPolicyArns: this.managedPolicyArns,
            maxSessionDuration: this.maxSessionDuration,
            path: this.path,
            permissionsBoundary: this.permissionsBoundary,
            policies: this.policies,
            roleName: this.roleName,
            tags: this.tags.renderTags(),
        };
    }
    renderProperties(props) {
        return cfnRolePropsToCloudFormation(props);
    }
}
exports.CfnRole = CfnRole;
_g = JSII_RTTI_SYMBOL_1;
CfnRole[_g] = { fqn: "@aws-cdk/aws-iam.CfnRole", version: "1.204.0" };
/**
 * The CloudFormation resource type name for this resource class.
 */
CfnRole.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::Role";
/**
 * Determine whether the given properties match those of a `PolicyProperty`
 *
 * @param properties - the TypeScript properties of a `PolicyProperty`
 *
 * @returns the result of the validation.
 */
function CfnRole_PolicyPropertyValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('policyDocument', cdk.requiredValidator)(properties.policyDocument));
    errors.collect(cdk.propertyValidator('policyDocument', cdk.validateObject)(properties.policyDocument));
    errors.collect(cdk.propertyValidator('policyName', cdk.requiredValidator)(properties.policyName));
    errors.collect(cdk.propertyValidator('policyName', cdk.validateString)(properties.policyName));
    return errors.wrap('supplied properties not correct for "PolicyProperty"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::Role.Policy` resource
 *
 * @param properties - the TypeScript properties of a `PolicyProperty`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::Role.Policy` resource.
 */
// @ts-ignore TS6133
function cfnRolePolicyPropertyToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnRole_PolicyPropertyValidator(properties).assertSuccess();
    return {
        PolicyDocument: cdk.objectToCloudFormation(properties.policyDocument),
        PolicyName: cdk.stringToCloudFormation(properties.policyName),
    };
}
// @ts-ignore TS6133
function CfnRolePolicyPropertyFromCloudFormation(properties) {
    if (cdk.isResolvableObject(properties)) {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('policyDocument', 'PolicyDocument', cfn_parse.FromCloudFormation.getAny(properties.PolicyDocument));
    ret.addPropertyResult('policyName', 'PolicyName', cfn_parse.FromCloudFormation.getString(properties.PolicyName));
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * Determine whether the given properties match those of a `CfnSAMLProviderProps`
 *
 * @param properties - the TypeScript properties of a `CfnSAMLProviderProps`
 *
 * @returns the result of the validation.
 */
function CfnSAMLProviderPropsValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('name', cdk.validateString)(properties.name));
    errors.collect(cdk.propertyValidator('samlMetadataDocument', cdk.requiredValidator)(properties.samlMetadataDocument));
    errors.collect(cdk.propertyValidator('samlMetadataDocument', cdk.validateString)(properties.samlMetadataDocument));
    errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
    return errors.wrap('supplied properties not correct for "CfnSAMLProviderProps"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::SAMLProvider` resource
 *
 * @param properties - the TypeScript properties of a `CfnSAMLProviderProps`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::SAMLProvider` resource.
 */
// @ts-ignore TS6133
function cfnSAMLProviderPropsToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnSAMLProviderPropsValidator(properties).assertSuccess();
    return {
        SamlMetadataDocument: cdk.stringToCloudFormation(properties.samlMetadataDocument),
        Name: cdk.stringToCloudFormation(properties.name),
        Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
    };
}
// @ts-ignore TS6133
function CfnSAMLProviderPropsFromCloudFormation(properties) {
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('samlMetadataDocument', 'SamlMetadataDocument', cfn_parse.FromCloudFormation.getString(properties.SamlMetadataDocument));
    ret.addPropertyResult('name', 'Name', properties.Name != null ? cfn_parse.FromCloudFormation.getString(properties.Name) : undefined);
    ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * A CloudFormation `AWS::IAM::SAMLProvider`
 *
 * Creates an IAM resource that describes an identity provider (IdP) that supports SAML 2.0.
 *
 * The SAML provider resource that you create with this operation can be used as a principal in an IAM role's trust policy. Such a policy can enable federated users who sign in using the SAML IdP to assume the role. You can create an IAM role that supports Web-based single sign-on (SSO) to the AWS Management Console or one that supports API access to AWS .
 *
 * When you create the SAML provider resource, you upload a SAML metadata document that you get from your IdP. That document includes the issuer's name, expiration information, and keys that can be used to validate the SAML authentication response (assertions) that the IdP sends. You must generate the metadata document using the identity management software that is used as your organization's IdP.
 *
 * > This operation requires [Signature Version 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) .
 *
 * For more information, see [Enabling SAML 2.0 federated users to access the AWS Management Console](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-saml.html) and [About SAML 2.0-based federation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html) in the *IAM User Guide* .
 *
 * @cloudformationResource AWS::IAM::SAMLProvider
 * @stability external
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-samlprovider.html
 */
class CfnSAMLProvider extends cdk.CfnResource {
    /**
     * Create a new `AWS::IAM::SAMLProvider`.
     *
     * @param scope - scope in which this resource is defined
     * @param id    - scoped id of the resource
     * @param props - resource properties
     */
    constructor(scope, id, props) {
        super(scope, id, { type: CfnSAMLProvider.CFN_RESOURCE_TYPE_NAME, properties: props });
        try {
            jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnSAMLProviderProps(props);
        }
        catch (error) {
            if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
                Error.captureStackTrace(error, CfnSAMLProvider);
            }
            throw error;
        }
        cdk.requireProperty(props, 'samlMetadataDocument', this);
        this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
        this.samlMetadataDocument = props.samlMetadataDocument;
        this.name = props.name;
        this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::IAM::SAMLProvider", props.tags, { tagPropertyName: 'tags' });
    }
    /**
     * A factory method that creates a new instance of this class from an object
     * containing the CloudFormation properties of this resource.
     * Used in the @aws-cdk/cloudformation-include module.
     *
     * @internal
     */
    static _fromCloudFormation(scope, id, resourceAttributes, options) {
        resourceAttributes = resourceAttributes || {};
        const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
        const propsResult = CfnSAMLProviderPropsFromCloudFormation(resourceProperties);
        const ret = new CfnSAMLProvider(scope, id, propsResult.value);
        for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
            ret.addPropertyOverride(propKey, propVal);
        }
        options.parser.handleAttributes(ret, resourceAttributes, id);
        return ret;
    }
    /**
     * Examines the CloudFormation resource and discloses attributes.
     *
     * @param inspector - tree inspector to collect and process attributes
     *
     */
    inspect(inspector) {
        inspector.addAttribute("aws:cdk:cloudformation:type", CfnSAMLProvider.CFN_RESOURCE_TYPE_NAME);
        inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
    }
    get cfnProperties() {
        return {
            samlMetadataDocument: this.samlMetadataDocument,
            name: this.name,
            tags: this.tags.renderTags(),
        };
    }
    renderProperties(props) {
        return cfnSAMLProviderPropsToCloudFormation(props);
    }
}
exports.CfnSAMLProvider = CfnSAMLProvider;
_h = JSII_RTTI_SYMBOL_1;
CfnSAMLProvider[_h] = { fqn: "@aws-cdk/aws-iam.CfnSAMLProvider", version: "1.204.0" };
/**
 * The CloudFormation resource type name for this resource class.
 */
CfnSAMLProvider.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::SAMLProvider";
/**
 * Determine whether the given properties match those of a `CfnServerCertificateProps`
 *
 * @param properties - the TypeScript properties of a `CfnServerCertificateProps`
 *
 * @returns the result of the validation.
 */
function CfnServerCertificatePropsValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('certificateBody', cdk.validateString)(properties.certificateBody));
    errors.collect(cdk.propertyValidator('certificateChain', cdk.validateString)(properties.certificateChain));
    errors.collect(cdk.propertyValidator('path', cdk.validateString)(properties.path));
    errors.collect(cdk.propertyValidator('privateKey', cdk.validateString)(properties.privateKey));
    errors.collect(cdk.propertyValidator('serverCertificateName', cdk.validateString)(properties.serverCertificateName));
    errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
    return errors.wrap('supplied properties not correct for "CfnServerCertificateProps"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::ServerCertificate` resource
 *
 * @param properties - the TypeScript properties of a `CfnServerCertificateProps`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::ServerCertificate` resource.
 */
// @ts-ignore TS6133
function cfnServerCertificatePropsToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnServerCertificatePropsValidator(properties).assertSuccess();
    return {
        CertificateBody: cdk.stringToCloudFormation(properties.certificateBody),
        CertificateChain: cdk.stringToCloudFormation(properties.certificateChain),
        Path: cdk.stringToCloudFormation(properties.path),
        PrivateKey: cdk.stringToCloudFormation(properties.privateKey),
        ServerCertificateName: cdk.stringToCloudFormation(properties.serverCertificateName),
        Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
    };
}
// @ts-ignore TS6133
function CfnServerCertificatePropsFromCloudFormation(properties) {
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('certificateBody', 'CertificateBody', properties.CertificateBody != null ? cfn_parse.FromCloudFormation.getString(properties.CertificateBody) : undefined);
    ret.addPropertyResult('certificateChain', 'CertificateChain', properties.CertificateChain != null ? cfn_parse.FromCloudFormation.getString(properties.CertificateChain) : undefined);
    ret.addPropertyResult('path', 'Path', properties.Path != null ? cfn_parse.FromCloudFormation.getString(properties.Path) : undefined);
    ret.addPropertyResult('privateKey', 'PrivateKey', properties.PrivateKey != null ? cfn_parse.FromCloudFormation.getString(properties.PrivateKey) : undefined);
    ret.addPropertyResult('serverCertificateName', 'ServerCertificateName', properties.ServerCertificateName != null ? cfn_parse.FromCloudFormation.getString(properties.ServerCertificateName) : undefined);
    ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * A CloudFormation `AWS::IAM::ServerCertificate`
 *
 * Uploads a server certificate entity for the AWS account . The server certificate entity includes a public key certificate, a private key, and an optional certificate chain, which should all be PEM-encoded.
 *
 * We recommend that you use [AWS Certificate Manager](https://docs.aws.amazon.com/acm/) to provision, manage, and deploy your server certificates. With ACM you can request a certificate, deploy it to AWS resources, and let ACM handle certificate renewals for you. Certificates provided by ACM are free. For more information about using ACM, see the [AWS Certificate Manager User Guide](https://docs.aws.amazon.com/acm/latest/userguide/) .
 *
 * For more information about working with server certificates, see [Working with server certificates](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_server-certs.html) in the *IAM User Guide* . This topic includes a list of AWS services that can use the server certificates that you manage with IAM.
 *
 * For information about the number of server certificates you can upload, see [IAM and AWS STS quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) in the *IAM User Guide* .
 *
 * > Because the body of the public key certificate, private key, and the certificate chain can be large, you should use POST rather than GET when calling `UploadServerCertificate` . For information about setting up signatures and authorization through the API, see [Signing AWS API requests](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) in the *AWS General Reference* . For general information about using the Query API with IAM, see [Calling the API by making HTTP query requests](https://docs.aws.amazon.com/IAM/latest/UserGuide/programming.html) in the *IAM User Guide* .
 *
 * @cloudformationResource AWS::IAM::ServerCertificate
 * @stability external
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-servercertificate.html
 */
class CfnServerCertificate extends cdk.CfnResource {
    /**
     * Create a new `AWS::IAM::ServerCertificate`.
     *
     * @param scope - scope in which this resource is defined
     * @param id    - scoped id of the resource
     * @param props - resource properties
     */
    constructor(scope, id, props = {}) {
        super(scope, id, { type: CfnServerCertificate.CFN_RESOURCE_TYPE_NAME, properties: props });
        try {
            jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnServerCertificateProps(props);
        }
        catch (error) {
            if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
                Error.captureStackTrace(error, CfnServerCertificate);
            }
            throw error;
        }
        this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
        this.certificateBody = props.certificateBody;
        this.certificateChain = props.certificateChain;
        this.path = props.path;
        this.privateKey = props.privateKey;
        this.serverCertificateName = props.serverCertificateName;
        this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::IAM::ServerCertificate", props.tags, { tagPropertyName: 'tags' });
    }
    /**
     * A factory method that creates a new instance of this class from an object
     * containing the CloudFormation properties of this resource.
     * Used in the @aws-cdk/cloudformation-include module.
     *
     * @internal
     */
    static _fromCloudFormation(scope, id, resourceAttributes, options) {
        resourceAttributes = resourceAttributes || {};
        const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
        const propsResult = CfnServerCertificatePropsFromCloudFormation(resourceProperties);
        const ret = new CfnServerCertificate(scope, id, propsResult.value);
        for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
            ret.addPropertyOverride(propKey, propVal);
        }
        options.parser.handleAttributes(ret, resourceAttributes, id);
        return ret;
    }
    /**
     * Examines the CloudFormation resource and discloses attributes.
     *
     * @param inspector - tree inspector to collect and process attributes
     *
     */
    inspect(inspector) {
        inspector.addAttribute("aws:cdk:cloudformation:type", CfnServerCertificate.CFN_RESOURCE_TYPE_NAME);
        inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
    }
    get cfnProperties() {
        return {
            certificateBody: this.certificateBody,
            certificateChain: this.certificateChain,
            path: this.path,
            privateKey: this.privateKey,
            serverCertificateName: this.serverCertificateName,
            tags: this.tags.renderTags(),
        };
    }
    renderProperties(props) {
        return cfnServerCertificatePropsToCloudFormation(props);
    }
}
exports.CfnServerCertificate = CfnServerCertificate;
_j = JSII_RTTI_SYMBOL_1;
CfnServerCertificate[_j] = { fqn: "@aws-cdk/aws-iam.CfnServerCertificate", version: "1.204.0" };
/**
 * The CloudFormation resource type name for this resource class.
 */
CfnServerCertificate.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::ServerCertificate";
/**
 * Determine whether the given properties match those of a `CfnServiceLinkedRoleProps`
 *
 * @param properties - the TypeScript properties of a `CfnServiceLinkedRoleProps`
 *
 * @returns the result of the validation.
 */
function CfnServiceLinkedRolePropsValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('awsServiceName', cdk.requiredValidator)(properties.awsServiceName));
    errors.collect(cdk.propertyValidator('awsServiceName', cdk.validateString)(properties.awsServiceName));
    errors.collect(cdk.propertyValidator('customSuffix', cdk.validateString)(properties.customSuffix));
    errors.collect(cdk.propertyValidator('description', cdk.validateString)(properties.description));
    return errors.wrap('supplied properties not correct for "CfnServiceLinkedRoleProps"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::ServiceLinkedRole` resource
 *
 * @param properties - the TypeScript properties of a `CfnServiceLinkedRoleProps`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::ServiceLinkedRole` resource.
 */
// @ts-ignore TS6133
function cfnServiceLinkedRolePropsToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnServiceLinkedRolePropsValidator(properties).assertSuccess();
    return {
        AWSServiceName: cdk.stringToCloudFormation(properties.awsServiceName),
        CustomSuffix: cdk.stringToCloudFormation(properties.customSuffix),
        Description: cdk.stringToCloudFormation(properties.description),
    };
}
// @ts-ignore TS6133
function CfnServiceLinkedRolePropsFromCloudFormation(properties) {
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('awsServiceName', 'AWSServiceName', cfn_parse.FromCloudFormation.getString(properties.AWSServiceName));
    ret.addPropertyResult('customSuffix', 'CustomSuffix', properties.CustomSuffix != null ? cfn_parse.FromCloudFormation.getString(properties.CustomSuffix) : undefined);
    ret.addPropertyResult('description', 'Description', properties.Description != null ? cfn_parse.FromCloudFormation.getString(properties.Description) : undefined);
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * A CloudFormation `AWS::IAM::ServiceLinkedRole`
 *
 * Creates an IAM role that is linked to a specific AWS service. The service controls the attached policies and when the role can be deleted. This helps ensure that the service is not broken by an unexpectedly changed or deleted role, which could put your AWS resources into an unknown state. Allowing the service to control the role helps improve service stability and proper cleanup when a service and its role are no longer needed. For more information, see [Using service-linked roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html) in the *IAM User Guide* .
 *
 * To attach a policy to this service-linked role, you must make the request using the AWS service that depends on this role.
 *
 * @cloudformationResource AWS::IAM::ServiceLinkedRole
 * @stability external
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-servicelinkedrole.html
 */
class CfnServiceLinkedRole extends cdk.CfnResource {
    /**
     * Create a new `AWS::IAM::ServiceLinkedRole`.
     *
     * @param scope - scope in which this resource is defined
     * @param id    - scoped id of the resource
     * @param props - resource properties
     */
    constructor(scope, id, props) {
        super(scope, id, { type: CfnServiceLinkedRole.CFN_RESOURCE_TYPE_NAME, properties: props });
        try {
            jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnServiceLinkedRoleProps(props);
        }
        catch (error) {
            if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
                Error.captureStackTrace(error, CfnServiceLinkedRole);
            }
            throw error;
        }
        cdk.requireProperty(props, 'awsServiceName', this);
        this.awsServiceName = props.awsServiceName;
        this.customSuffix = props.customSuffix;
        this.description = props.description;
    }
    /**
     * A factory method that creates a new instance of this class from an object
     * containing the CloudFormation properties of this resource.
     * Used in the @aws-cdk/cloudformation-include module.
     *
     * @internal
     */
    static _fromCloudFormation(scope, id, resourceAttributes, options) {
        resourceAttributes = resourceAttributes || {};
        const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
        const propsResult = CfnServiceLinkedRolePropsFromCloudFormation(resourceProperties);
        const ret = new CfnServiceLinkedRole(scope, id, propsResult.value);
        for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
            ret.addPropertyOverride(propKey, propVal);
        }
        options.parser.handleAttributes(ret, resourceAttributes, id);
        return ret;
    }
    /**
     * Examines the CloudFormation resource and discloses attributes.
     *
     * @param inspector - tree inspector to collect and process attributes
     *
     */
    inspect(inspector) {
        inspector.addAttribute("aws:cdk:cloudformation:type", CfnServiceLinkedRole.CFN_RESOURCE_TYPE_NAME);
        inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
    }
    get cfnProperties() {
        return {
            awsServiceName: this.awsServiceName,
            customSuffix: this.customSuffix,
            description: this.description,
        };
    }
    renderProperties(props) {
        return cfnServiceLinkedRolePropsToCloudFormation(props);
    }
}
exports.CfnServiceLinkedRole = CfnServiceLinkedRole;
_k = JSII_RTTI_SYMBOL_1;
CfnServiceLinkedRole[_k] = { fqn: "@aws-cdk/aws-iam.CfnServiceLinkedRole", version: "1.204.0" };
/**
 * The CloudFormation resource type name for this resource class.
 */
CfnServiceLinkedRole.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::ServiceLinkedRole";
/**
 * Determine whether the given properties match those of a `CfnUserProps`
 *
 * @param properties - the TypeScript properties of a `CfnUserProps`
 *
 * @returns the result of the validation.
 */
function CfnUserPropsValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('groups', cdk.listValidator(cdk.validateString))(properties.groups));
    errors.collect(cdk.propertyValidator('loginProfile', CfnUser_LoginProfilePropertyValidator)(properties.loginProfile));
    errors.collect(cdk.propertyValidator('managedPolicyArns', cdk.listValidator(cdk.validateString))(properties.managedPolicyArns));
    errors.collect(cdk.propertyValidator('path', cdk.validateString)(properties.path));
    errors.collect(cdk.propertyValidator('permissionsBoundary', cdk.validateString)(properties.permissionsBoundary));
    errors.collect(cdk.propertyValidator('policies', cdk.listValidator(CfnUser_PolicyPropertyValidator))(properties.policies));
    errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
    errors.collect(cdk.propertyValidator('userName', cdk.validateString)(properties.userName));
    return errors.wrap('supplied properties not correct for "CfnUserProps"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::User` resource
 *
 * @param properties - the TypeScript properties of a `CfnUserProps`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::User` resource.
 */
// @ts-ignore TS6133
function cfnUserPropsToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnUserPropsValidator(properties).assertSuccess();
    return {
        Groups: cdk.listMapper(cdk.stringToCloudFormation)(properties.groups),
        LoginProfile: cfnUserLoginProfilePropertyToCloudFormation(properties.loginProfile),
        ManagedPolicyArns: cdk.listMapper(cdk.stringToCloudFormation)(properties.managedPolicyArns),
        Path: cdk.stringToCloudFormation(properties.path),
        PermissionsBoundary: cdk.stringToCloudFormation(properties.permissionsBoundary),
        Policies: cdk.listMapper(cfnUserPolicyPropertyToCloudFormation)(properties.policies),
        Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
        UserName: cdk.stringToCloudFormation(properties.userName),
    };
}
// @ts-ignore TS6133
function CfnUserPropsFromCloudFormation(properties) {
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('groups', 'Groups', properties.Groups != null ? cfn_parse.FromCloudFormation.getStringArray(properties.Groups) : undefined);
    ret.addPropertyResult('loginProfile', 'LoginProfile', properties.LoginProfile != null ? CfnUserLoginProfilePropertyFromCloudFormation(properties.LoginProfile) : undefined);
    ret.addPropertyResult('managedPolicyArns', 'ManagedPolicyArns', properties.ManagedPolicyArns != null ? cfn_parse.FromCloudFormation.getStringArray(properties.ManagedPolicyArns) : undefined);
    ret.addPropertyResult('path', 'Path', properties.Path != null ? cfn_parse.FromCloudFormation.getString(properties.Path) : undefined);
    ret.addPropertyResult('permissionsBoundary', 'PermissionsBoundary', properties.PermissionsBoundary != null ? cfn_parse.FromCloudFormation.getString(properties.PermissionsBoundary) : undefined);
    ret.addPropertyResult('policies', 'Policies', properties.Policies != null ? cfn_parse.FromCloudFormation.getArray(CfnUserPolicyPropertyFromCloudFormation)(properties.Policies) : undefined);
    ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
    ret.addPropertyResult('userName', 'UserName', properties.UserName != null ? cfn_parse.FromCloudFormation.getString(properties.UserName) : undefined);
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * A CloudFormation `AWS::IAM::User`
 *
 * Creates a new IAM user for your AWS account .
 *
 * For information about quotas for the number of IAM users you can create, see [IAM and AWS STS quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) in the *IAM User Guide* .
 *
 * @cloudformationResource AWS::IAM::User
 * @stability external
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-user.html
 */
class CfnUser extends cdk.CfnResource {
    /**
     * Create a new `AWS::IAM::User`.
     *
     * @param scope - scope in which this resource is defined
     * @param id    - scoped id of the resource
     * @param props - resource properties
     */
    constructor(scope, id, props = {}) {
        super(scope, id, { type: CfnUser.CFN_RESOURCE_TYPE_NAME, properties: props });
        try {
            jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnUserProps(props);
        }
        catch (error) {
            if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
                Error.captureStackTrace(error, CfnUser);
            }
            throw error;
        }
        this.attrArn = cdk.Token.asString(this.getAtt('Arn'));
        this.groups = props.groups;
        this.loginProfile = props.loginProfile;
        this.managedPolicyArns = props.managedPolicyArns;
        this.path = props.path;
        this.permissionsBoundary = props.permissionsBoundary;
        this.policies = props.policies;
        this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::IAM::User", props.tags, { tagPropertyName: 'tags' });
        this.userName = props.userName;
    }
    /**
     * A factory method that creates a new instance of this class from an object
     * containing the CloudFormation properties of this resource.
     * Used in the @aws-cdk/cloudformation-include module.
     *
     * @internal
     */
    static _fromCloudFormation(scope, id, resourceAttributes, options) {
        resourceAttributes = resourceAttributes || {};
        const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
        const propsResult = CfnUserPropsFromCloudFormation(resourceProperties);
        const ret = new CfnUser(scope, id, propsResult.value);
        for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
            ret.addPropertyOverride(propKey, propVal);
        }
        options.parser.handleAttributes(ret, resourceAttributes, id);
        return ret;
    }
    /**
     * Examines the CloudFormation resource and discloses attributes.
     *
     * @param inspector - tree inspector to collect and process attributes
     *
     */
    inspect(inspector) {
        inspector.addAttribute("aws:cdk:cloudformation:type", CfnUser.CFN_RESOURCE_TYPE_NAME);
        inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
    }
    get cfnProperties() {
        return {
            groups: this.groups,
            loginProfile: this.loginProfile,
            managedPolicyArns: this.managedPolicyArns,
            path: this.path,
            permissionsBoundary: this.permissionsBoundary,
            policies: this.policies,
            tags: this.tags.renderTags(),
            userName: this.userName,
        };
    }
    renderProperties(props) {
        return cfnUserPropsToCloudFormation(props);
    }
}
exports.CfnUser = CfnUser;
_l = JSII_RTTI_SYMBOL_1;
CfnUser[_l] = { fqn: "@aws-cdk/aws-iam.CfnUser", version: "1.204.0" };
/**
 * The CloudFormation resource type name for this resource class.
 */
CfnUser.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::User";
/**
 * Determine whether the given properties match those of a `LoginProfileProperty`
 *
 * @param properties - the TypeScript properties of a `LoginProfileProperty`
 *
 * @returns the result of the validation.
 */
function CfnUser_LoginProfilePropertyValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('password', cdk.requiredValidator)(properties.password));
    errors.collect(cdk.propertyValidator('password', cdk.validateString)(properties.password));
    errors.collect(cdk.propertyValidator('passwordResetRequired', cdk.validateBoolean)(properties.passwordResetRequired));
    return errors.wrap('supplied properties not correct for "LoginProfileProperty"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::User.LoginProfile` resource
 *
 * @param properties - the TypeScript properties of a `LoginProfileProperty`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::User.LoginProfile` resource.
 */
// @ts-ignore TS6133
function cfnUserLoginProfilePropertyToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnUser_LoginProfilePropertyValidator(properties).assertSuccess();
    return {
        Password: cdk.stringToCloudFormation(properties.password),
        PasswordResetRequired: cdk.booleanToCloudFormation(properties.passwordResetRequired),
    };
}
// @ts-ignore TS6133
function CfnUserLoginProfilePropertyFromCloudFormation(properties) {
    if (cdk.isResolvableObject(properties)) {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('password', 'Password', cfn_parse.FromCloudFormation.getString(properties.Password));
    ret.addPropertyResult('passwordResetRequired', 'PasswordResetRequired', properties.PasswordResetRequired != null ? cfn_parse.FromCloudFormation.getBoolean(properties.PasswordResetRequired) : undefined);
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * Determine whether the given properties match those of a `PolicyProperty`
 *
 * @param properties - the TypeScript properties of a `PolicyProperty`
 *
 * @returns the result of the validation.
 */
function CfnUser_PolicyPropertyValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('policyDocument', cdk.requiredValidator)(properties.policyDocument));
    errors.collect(cdk.propertyValidator('policyDocument', cdk.validateObject)(properties.policyDocument));
    errors.collect(cdk.propertyValidator('policyName', cdk.requiredValidator)(properties.policyName));
    errors.collect(cdk.propertyValidator('policyName', cdk.validateString)(properties.policyName));
    return errors.wrap('supplied properties not correct for "PolicyProperty"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::User.Policy` resource
 *
 * @param properties - the TypeScript properties of a `PolicyProperty`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::User.Policy` resource.
 */
// @ts-ignore TS6133
function cfnUserPolicyPropertyToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnUser_PolicyPropertyValidator(properties).assertSuccess();
    return {
        PolicyDocument: cdk.objectToCloudFormation(properties.policyDocument),
        PolicyName: cdk.stringToCloudFormation(properties.policyName),
    };
}
// @ts-ignore TS6133
function CfnUserPolicyPropertyFromCloudFormation(properties) {
    if (cdk.isResolvableObject(properties)) {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('policyDocument', 'PolicyDocument', cfn_parse.FromCloudFormation.getAny(properties.PolicyDocument));
    ret.addPropertyResult('policyName', 'PolicyName', cfn_parse.FromCloudFormation.getString(properties.PolicyName));
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * Determine whether the given properties match those of a `CfnUserToGroupAdditionProps`
 *
 * @param properties - the TypeScript properties of a `CfnUserToGroupAdditionProps`
 *
 * @returns the result of the validation.
 */
function CfnUserToGroupAdditionPropsValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('groupName', cdk.requiredValidator)(properties.groupName));
    errors.collect(cdk.propertyValidator('groupName', cdk.validateString)(properties.groupName));
    errors.collect(cdk.propertyValidator('users', cdk.requiredValidator)(properties.users));
    errors.collect(cdk.propertyValidator('users', cdk.listValidator(cdk.validateString))(properties.users));
    return errors.wrap('supplied properties not correct for "CfnUserToGroupAdditionProps"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::UserToGroupAddition` resource
 *
 * @param properties - the TypeScript properties of a `CfnUserToGroupAdditionProps`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::UserToGroupAddition` resource.
 */
// @ts-ignore TS6133
function cfnUserToGroupAdditionPropsToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnUserToGroupAdditionPropsValidator(properties).assertSuccess();
    return {
        GroupName: cdk.stringToCloudFormation(properties.groupName),
        Users: cdk.listMapper(cdk.stringToCloudFormation)(properties.users),
    };
}
// @ts-ignore TS6133
function CfnUserToGroupAdditionPropsFromCloudFormation(properties) {
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('groupName', 'GroupName', cfn_parse.FromCloudFormation.getString(properties.GroupName));
    ret.addPropertyResult('users', 'Users', cfn_parse.FromCloudFormation.getStringArray(properties.Users));
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * A CloudFormation `AWS::IAM::UserToGroupAddition`
 *
 * Adds the specified user to the specified group.
 *
 * @cloudformationResource AWS::IAM::UserToGroupAddition
 * @stability external
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-addusertogroup.html
 */
class CfnUserToGroupAddition extends cdk.CfnResource {
    /**
     * Create a new `AWS::IAM::UserToGroupAddition`.
     *
     * @param scope - scope in which this resource is defined
     * @param id    - scoped id of the resource
     * @param props - resource properties
     */
    constructor(scope, id, props) {
        super(scope, id, { type: CfnUserToGroupAddition.CFN_RESOURCE_TYPE_NAME, properties: props });
        try {
            jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnUserToGroupAdditionProps(props);
        }
        catch (error) {
            if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
                Error.captureStackTrace(error, CfnUserToGroupAddition);
            }
            throw error;
        }
        cdk.requireProperty(props, 'groupName', this);
        cdk.requireProperty(props, 'users', this);
        this.groupName = props.groupName;
        this.users = props.users;
    }
    /**
     * A factory method that creates a new instance of this class from an object
     * containing the CloudFormation properties of this resource.
     * Used in the @aws-cdk/cloudformation-include module.
     *
     * @internal
     */
    static _fromCloudFormation(scope, id, resourceAttributes, options) {
        resourceAttributes = resourceAttributes || {};
        const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
        const propsResult = CfnUserToGroupAdditionPropsFromCloudFormation(resourceProperties);
        const ret = new CfnUserToGroupAddition(scope, id, propsResult.value);
        for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
            ret.addPropertyOverride(propKey, propVal);
        }
        options.parser.handleAttributes(ret, resourceAttributes, id);
        return ret;
    }
    /**
     * Examines the CloudFormation resource and discloses attributes.
     *
     * @param inspector - tree inspector to collect and process attributes
     *
     */
    inspect(inspector) {
        inspector.addAttribute("aws:cdk:cloudformation:type", CfnUserToGroupAddition.CFN_RESOURCE_TYPE_NAME);
        inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
    }
    get cfnProperties() {
        return {
            groupName: this.groupName,
            users: this.users,
        };
    }
    renderProperties(props) {
        return cfnUserToGroupAdditionPropsToCloudFormation(props);
    }
}
exports.CfnUserToGroupAddition = CfnUserToGroupAddition;
_m = JSII_RTTI_SYMBOL_1;
CfnUserToGroupAddition[_m] = { fqn: "@aws-cdk/aws-iam.CfnUserToGroupAddition", version: "1.204.0" };
/**
 * The CloudFormation resource type name for this resource class.
 */
CfnUserToGroupAddition.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::UserToGroupAddition";
/**
 * Determine whether the given properties match those of a `CfnVirtualMFADeviceProps`
 *
 * @param properties - the TypeScript properties of a `CfnVirtualMFADeviceProps`
 *
 * @returns the result of the validation.
 */
function CfnVirtualMFADevicePropsValidator(properties) {
    if (!cdk.canInspect(properties)) {
        return cdk.VALIDATION_SUCCESS;
    }
    const errors = new cdk.ValidationResults();
    if (typeof properties !== 'object') {
        errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));
    }
    errors.collect(cdk.propertyValidator('path', cdk.validateString)(properties.path));
    errors.collect(cdk.propertyValidator('tags', cdk.listValidator(cdk.validateCfnTag))(properties.tags));
    errors.collect(cdk.propertyValidator('users', cdk.requiredValidator)(properties.users));
    errors.collect(cdk.propertyValidator('users', cdk.listValidator(cdk.validateString))(properties.users));
    errors.collect(cdk.propertyValidator('virtualMfaDeviceName', cdk.validateString)(properties.virtualMfaDeviceName));
    return errors.wrap('supplied properties not correct for "CfnVirtualMFADeviceProps"');
}
/**
 * Renders the AWS CloudFormation properties of an `AWS::IAM::VirtualMFADevice` resource
 *
 * @param properties - the TypeScript properties of a `CfnVirtualMFADeviceProps`
 *
 * @returns the AWS CloudFormation properties of an `AWS::IAM::VirtualMFADevice` resource.
 */
// @ts-ignore TS6133
function cfnVirtualMFADevicePropsToCloudFormation(properties) {
    if (!cdk.canInspect(properties)) {
        return properties;
    }
    CfnVirtualMFADevicePropsValidator(properties).assertSuccess();
    return {
        Users: cdk.listMapper(cdk.stringToCloudFormation)(properties.users),
        Path: cdk.stringToCloudFormation(properties.path),
        Tags: cdk.listMapper(cdk.cfnTagToCloudFormation)(properties.tags),
        VirtualMfaDeviceName: cdk.stringToCloudFormation(properties.virtualMfaDeviceName),
    };
}
// @ts-ignore TS6133
function CfnVirtualMFADevicePropsFromCloudFormation(properties) {
    properties = properties == null ? {} : properties;
    if (typeof properties !== 'object') {
        return new cfn_parse.FromCloudFormationResult(properties);
    }
    const ret = new cfn_parse.FromCloudFormationPropertyObject();
    ret.addPropertyResult('users', 'Users', cfn_parse.FromCloudFormation.getStringArray(properties.Users));
    ret.addPropertyResult('path', 'Path', properties.Path != null ? cfn_parse.FromCloudFormation.getString(properties.Path) : undefined);
    ret.addPropertyResult('tags', 'Tags', properties.Tags != null ? cfn_parse.FromCloudFormation.getArray(cfn_parse.FromCloudFormation.getCfnTag)(properties.Tags) : undefined);
    ret.addPropertyResult('virtualMfaDeviceName', 'VirtualMfaDeviceName', properties.VirtualMfaDeviceName != null ? cfn_parse.FromCloudFormation.getString(properties.VirtualMfaDeviceName) : undefined);
    ret.addUnrecognizedPropertiesAsExtra(properties);
    return ret;
}
/**
 * A CloudFormation `AWS::IAM::VirtualMFADevice`
 *
 * Creates a new virtual MFA device for the AWS account . After creating the virtual MFA, use [EnableMFADevice](https://docs.aws.amazon.com/IAM/latest/APIReference/API_EnableMFADevice.html) to attach the MFA device to an IAM user. For more information about creating and working with virtual MFA devices, see [Using a virtual MFA device](https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_VirtualMFA.html) in the *IAM User Guide* .
 *
 * For information about the maximum number of MFA devices you can create, see [IAM and AWS STS quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) in the *IAM User Guide* .
 *
 * > The seed information contained in the QR code and the Base32 string should be treated like any other secret access information. In other words, protect the seed information as you would your AWS access keys or your passwords. After you provision your virtual device, you should ensure that the information is destroyed following secure procedures.
 *
 * @cloudformationResource AWS::IAM::VirtualMFADevice
 * @stability external
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-virtualmfadevice.html
 */
class CfnVirtualMFADevice extends cdk.CfnResource {
    /**
     * Create a new `AWS::IAM::VirtualMFADevice`.
     *
     * @param scope - scope in which this resource is defined
     * @param id    - scoped id of the resource
     * @param props - resource properties
     */
    constructor(scope, id, props) {
        super(scope, id, { type: CfnVirtualMFADevice.CFN_RESOURCE_TYPE_NAME, properties: props });
        try {
            jsiiDeprecationWarnings._aws_cdk_aws_iam_CfnVirtualMFADeviceProps(props);
        }
        catch (error) {
            if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
                Error.captureStackTrace(error, CfnVirtualMFADevice);
            }
            throw error;
        }
        cdk.requireProperty(props, 'users', this);
        this.attrSerialNumber = cdk.Token.asString(this.getAtt('SerialNumber'));
        this.users = props.users;
        this.path = props.path;
        this.tags = new cdk.TagManager(cdk.TagType.STANDARD, "AWS::IAM::VirtualMFADevice", props.tags, { tagPropertyName: 'tags' });
        this.virtualMfaDeviceName = props.virtualMfaDeviceName;
    }
    /**
     * A factory method that creates a new instance of this class from an object
     * containing the CloudFormation properties of this resource.
     * Used in the @aws-cdk/cloudformation-include module.
     *
     * @internal
     */
    static _fromCloudFormation(scope, id, resourceAttributes, options) {
        resourceAttributes = resourceAttributes || {};
        const resourceProperties = options.parser.parseValue(resourceAttributes.Properties);
        const propsResult = CfnVirtualMFADevicePropsFromCloudFormation(resourceProperties);
        const ret = new CfnVirtualMFADevice(scope, id, propsResult.value);
        for (const [propKey, propVal] of Object.entries(propsResult.extraProperties)) {
            ret.addPropertyOverride(propKey, propVal);
        }
        options.parser.handleAttributes(ret, resourceAttributes, id);
        return ret;
    }
    /**
     * Examines the CloudFormation resource and discloses attributes.
     *
     * @param inspector - tree inspector to collect and process attributes
     *
     */
    inspect(inspector) {
        inspector.addAttribute("aws:cdk:cloudformation:type", CfnVirtualMFADevice.CFN_RESOURCE_TYPE_NAME);
        inspector.addAttribute("aws:cdk:cloudformation:props", this.cfnProperties);
    }
    get cfnProperties() {
        return {
            users: this.users,
            path: this.path,
            tags: this.tags.renderTags(),
            virtualMfaDeviceName: this.virtualMfaDeviceName,
        };
    }
    renderProperties(props) {
        return cfnVirtualMFADevicePropsToCloudFormation(props);
    }
}
exports.CfnVirtualMFADevice = CfnVirtualMFADevice;
_o = JSII_RTTI_SYMBOL_1;
CfnVirtualMFADevice[_o] = { fqn: "@aws-cdk/aws-iam.CfnVirtualMFADevice", version: "1.204.0" };
/**
 * The CloudFormation resource type name for this resource class.
 */
CfnVirtualMFADevice.CFN_RESOURCE_TYPE_NAME = "AWS::IAM::VirtualMFADevice";
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWFtLmdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImlhbS5nZW5lcmF0ZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsK0VBQStFO0FBQy9FLCtEQUErRDtBQUMvRCw4RkFBOEY7QUFDOUYsc0hBQXNIO0FBRXRILDRCQUE0QixDQUFDLGlFQUFpRTtBQUU5RixxQ0FBcUM7QUFDckMsZ0VBQWdFO0FBb0NoRTs7Ozs7O0dBTUc7QUFDSCxTQUFTLDBCQUEwQixDQUFDLFVBQWU7SUFDL0MsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLEVBQUU7UUFBRSxPQUFPLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQztLQUFFO0lBQ25FLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDM0MsSUFBSSxPQUFPLFVBQVUsS0FBSyxRQUFRLEVBQUU7UUFDaEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxvQ0FBb0MsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUMvRztJQUNELE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDdkYsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUN2RixNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLEVBQUUsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDOUYs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QUM7UUFDN0QsT0FBTyxHQUFHLENBQUM7S0FDZDtJQThERDs7Ozs7T0FLRztJQUNJLE9BQU8sQ0FBQyxTQUE0QjtRQUN2QyxTQUFTLENBQUMsWUFBWSxDQUFDLDZCQUE2QixFQUFFLG1CQUFtQixDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDbEcsU0FBUyxDQUFDLFlBQVksQ0FBQyw4QkFBOEIsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7S0FDOUU7SUFFRCxJQUFjLGFBQWE7UUFDdkIsT0FBTztZQUNILEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztZQUNqQixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDZixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDNUIsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLG9CQUFvQjtTQUNsRCxDQUFDO0tBQ0w7SUFFUyxnQkFBZ0IsQ0FBQyxLQUEyQjtRQUNsRCxPQUFPLHdDQUF3QyxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQzFEOztBQTNHTCxrREE0R0M7OztBQTNHRzs7R0FFRztBQUNvQiwwQ0FBc0IsR0FBRyw0QkFBNEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDEyLTIwMjMgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbi8vIEdlbmVyYXRlZCBmcm9tIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gUmVzb3VyY2UgU3BlY2lmaWNhdGlvblxuLy8gU2VlOiBkb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvY2ZuLXJlc291cmNlLXNwZWNpZmljYXRpb24uaHRtbFxuLy8gQGNmbjJ0czptZXRhQCB7XCJnZW5lcmF0ZWRcIjpcIjIwMjMtMDYtMTlUMTU6MTM6MDAuODc1WlwiLFwiZmluZ2VycHJpbnRcIjpcIjFxTkp2bE5sTVVpL3hxTXhzak9yNU5vSFo0M291S3BzR3V5Um5aaGJJdEk9XCJ9XG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi8gLy8gVGhpcyBpcyBnZW5lcmF0ZWQgY29kZSAtIGxpbmUgbGVuZ3RocyBhcmUgZGlmZmljdWx0IHRvIGNvbnRyb2xcblxuaW1wb3J0ICogYXMgY2RrIGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1xuaW1wb3J0ICogYXMgY2ZuX3BhcnNlIGZyb20gJ0Bhd3MtY2RrL2NvcmUvbGliL2hlbHBlcnMtaW50ZXJuYWwnO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmbkFjY2Vzc0tleWBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tYWNjZXNza2V5Lmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5BY2Nlc3NLZXlQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgSUFNIHVzZXIgdGhhdCB0aGUgbmV3IGtleSB3aWxsIGJlbG9uZyB0by5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1hY2Nlc3NrZXkuaHRtbCNjZm4taWFtLWFjY2Vzc2tleS11c2VybmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IHVzZXJOYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIHZhbHVlIGlzIHNwZWNpZmljIHRvIENsb3VkRm9ybWF0aW9uIGFuZCBjYW4gb25seSBiZSAqaW5jcmVtZW50ZWQqIC4gSW5jcmVtZW50aW5nIHRoaXMgdmFsdWUgbm90aWZpZXMgQ2xvdWRGb3JtYXRpb24gdGhhdCB5b3Ugd2FudCB0byByb3RhdGUgeW91ciBhY2Nlc3Mga2V5LiBXaGVuIHlvdSB1cGRhdGUgeW91ciBzdGFjaywgQ2xvdWRGb3JtYXRpb24gd2lsbCByZXBsYWNlIHRoZSBleGlzdGluZyBhY2Nlc3Mga2V5IHdpdGggYSBuZXcga2V5LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tYWNjZXNza2V5Lmh0bWwjY2ZuLWlhbS1hY2Nlc3NrZXktc2VyaWFsXG4gICAgICovXG4gICAgcmVhZG9ubHkgc2VyaWFsPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHN0YXR1cyBvZiB0aGUgYWNjZXNzIGtleS4gYEFjdGl2ZWAgbWVhbnMgdGhhdCB0aGUga2V5IGlzIHZhbGlkIGZvciBBUEkgY2FsbHMsIHdoaWxlIGBJbmFjdGl2ZWAgbWVhbnMgaXQgaXMgbm90LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tYWNjZXNza2V5Lmh0bWwjY2ZuLWlhbS1hY2Nlc3NrZXktc3RhdHVzXG4gICAgICovXG4gICAgcmVhZG9ubHkgc3RhdHVzPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbkFjY2Vzc0tleVByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5BY2Nlc3NLZXlQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5BY2Nlc3NLZXlQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3NlcmlhbCcsIGNkay52YWxpZGF0ZU51bWJlcikocHJvcGVydGllcy5zZXJpYWwpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3N0YXR1cycsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5zdGF0dXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3VzZXJOYW1lJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnVzZXJOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd1c2VyTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy51c2VyTmFtZSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5BY2Nlc3NLZXlQcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpBY2Nlc3NLZXlgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkFjY2Vzc0tleVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OkFjY2Vzc0tleWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5BY2Nlc3NLZXlQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuQWNjZXNzS2V5UHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFVzZXJOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnVzZXJOYW1lKSxcbiAgICAgICAgU2VyaWFsOiBjZGsubnVtYmVyVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnNlcmlhbCksXG4gICAgICAgIFN0YXR1czogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zdGF0dXMpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5BY2Nlc3NLZXlQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbkFjY2Vzc0tleVByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5BY2Nlc3NLZXlQcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3VzZXJOYW1lJywgJ1VzZXJOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Vc2VyTmFtZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc2VyaWFsJywgJ1NlcmlhbCcsIHByb3BlcnRpZXMuU2VyaWFsICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLlNlcmlhbCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnc3RhdHVzJywgJ1N0YXR1cycsIHByb3BlcnRpZXMuU3RhdHVzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlN0YXR1cykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6SUFNOjpBY2Nlc3NLZXlgXG4gKlxuICogQ3JlYXRlcyBhIG5ldyBBV1Mgc2VjcmV0IGFjY2VzcyBrZXkgYW5kIGNvcnJlc3BvbmRpbmcgQVdTIGFjY2VzcyBrZXkgSUQgZm9yIHRoZSBzcGVjaWZpZWQgdXNlci4gVGhlIGRlZmF1bHQgc3RhdHVzIGZvciBuZXcga2V5cyBpcyBgQWN0aXZlYCAuXG4gKlxuICogRm9yIGluZm9ybWF0aW9uIGFib3V0IHF1b3RhcyBvbiB0aGUgbnVtYmVyIG9mIGtleXMgeW91IGNhbiBjcmVhdGUsIHNlZSBbSUFNIGFuZCBBV1MgU1RTIHF1b3Rhc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9pYW0tcXVvdGFzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAqXG4gKiA+IFRvIGVuc3VyZSB0aGUgc2VjdXJpdHkgb2YgeW91ciBBV1MgYWNjb3VudCAsIHRoZSBzZWNyZXQgYWNjZXNzIGtleSBpcyBhY2Nlc3NpYmxlIG9ubHkgZHVyaW5nIGtleSBhbmQgdXNlciBjcmVhdGlvbi4gWW91IG11c3Qgc2F2ZSB0aGUga2V5IChmb3IgZXhhbXBsZSwgaW4gYSB0ZXh0IGZpbGUpIGlmIHlvdSB3YW50IHRvIGJlIGFibGUgdG8gYWNjZXNzIGl0IGFnYWluLiBJZiBhIHNlY3JldCBrZXkgaXMgbG9zdCwgeW91IGNhbiByb3RhdGUgYWNjZXNzIGtleXMgYnkgaW5jcmVhc2luZyB0aGUgdmFsdWUgb2YgdGhlIGBzZXJpYWxgIHByb3BlcnR5LlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6SUFNOjpBY2Nlc3NLZXlcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1hY2Nlc3NrZXkuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuQWNjZXNzS2V5IGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6SUFNOjpBY2Nlc3NLZXlcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmbkFjY2Vzc0tleSB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuQWNjZXNzS2V5UHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmbkFjY2Vzc0tleShzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzZWNyZXQgYWNjZXNzIGtleSBmb3IgdGhlIHNwZWNpZmllZCBBV1M6OklBTTo6QWNjZXNzS2V5IHJlc291cmNlLiBGb3IgZXhhbXBsZTogd0phbHJYVXRuRkVNSS9LN01ERU5HL2JQeFJmaUNZekVYQU1QTEVLRVkuXG4gICAgICogQGNsb3VkZm9ybWF0aW9uQXR0cmlidXRlIFNlY3JldEFjY2Vzc0tleVxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBhdHRyU2VjcmV0QWNjZXNzS2V5OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgSUFNIHVzZXIgdGhhdCB0aGUgbmV3IGtleSB3aWxsIGJlbG9uZyB0by5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1hY2Nlc3NrZXkuaHRtbCNjZm4taWFtLWFjY2Vzc2tleS11c2VybmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyB1c2VyTmFtZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyB2YWx1ZSBpcyBzcGVjaWZpYyB0byBDbG91ZEZvcm1hdGlvbiBhbmQgY2FuIG9ubHkgYmUgKmluY3JlbWVudGVkKiAuIEluY3JlbWVudGluZyB0aGlzIHZhbHVlIG5vdGlmaWVzIENsb3VkRm9ybWF0aW9uIHRoYXQgeW91IHdhbnQgdG8gcm90YXRlIHlvdXIgYWNjZXNzIGtleS4gV2hlbiB5b3UgdXBkYXRlIHlvdXIgc3RhY2ssIENsb3VkRm9ybWF0aW9uIHdpbGwgcmVwbGFjZSB0aGUgZXhpc3RpbmcgYWNjZXNzIGtleSB3aXRoIGEgbmV3IGtleS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLWFjY2Vzc2tleS5odG1sI2Nmbi1pYW0tYWNjZXNza2V5LXNlcmlhbFxuICAgICAqL1xuICAgIHB1YmxpYyBzZXJpYWw6IG51bWJlciB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBzdGF0dXMgb2YgdGhlIGFjY2VzcyBrZXkuIGBBY3RpdmVgIG1lYW5zIHRoYXQgdGhlIGtleSBpcyB2YWxpZCBmb3IgQVBJIGNhbGxzLCB3aGlsZSBgSW5hY3RpdmVgIG1lYW5zIGl0IGlzIG5vdC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLWFjY2Vzc2tleS5odG1sI2Nmbi1pYW0tYWNjZXNza2V5LXN0YXR1c1xuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0dXM6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpJQU06OkFjY2Vzc0tleWAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuQWNjZXNzS2V5UHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmbkFjY2Vzc0tleS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ3VzZXJOYW1lJywgdGhpcyk7XG4gICAgICAgIHRoaXMuYXR0clNlY3JldEFjY2Vzc0tleSA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnU2VjcmV0QWNjZXNzS2V5JykpO1xuXG4gICAgICAgIHRoaXMudXNlck5hbWUgPSBwcm9wcy51c2VyTmFtZTtcbiAgICAgICAgdGhpcy5zZXJpYWwgPSBwcm9wcy5zZXJpYWw7XG4gICAgICAgIHRoaXMuc3RhdHVzID0gcHJvcHMuc3RhdHVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuQWNjZXNzS2V5LkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB1c2VyTmFtZTogdGhpcy51c2VyTmFtZSxcbiAgICAgICAgICAgIHNlcmlhbDogdGhpcy5zZXJpYWwsXG4gICAgICAgICAgICBzdGF0dXM6IHRoaXMuc3RhdHVzLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmbkFjY2Vzc0tleVByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmbkdyb3VwYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1ncm91cC5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuR3JvdXBQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgZ3JvdXAgdG8gY3JlYXRlLiBEbyBub3QgaW5jbHVkZSB0aGUgcGF0aCBpbiB0aGlzIHZhbHVlLlxuICAgICAqXG4gICAgICogVGhlIGdyb3VwIG5hbWUgbXVzdCBiZSB1bmlxdWUgd2l0aGluIHRoZSBhY2NvdW50LiBHcm91cCBuYW1lcyBhcmUgbm90IGRpc3Rpbmd1aXNoZWQgYnkgY2FzZS4gRm9yIGV4YW1wbGUsIHlvdSBjYW5ub3QgY3JlYXRlIGdyb3VwcyBuYW1lZCBib3RoIFwiQURNSU5TXCIgYW5kIFwiYWRtaW5zXCIuIElmIHlvdSBkb24ndCBzcGVjaWZ5IGEgbmFtZSwgQVdTIENsb3VkRm9ybWF0aW9uIGdlbmVyYXRlcyBhIHVuaXF1ZSBwaHlzaWNhbCBJRCBhbmQgdXNlcyB0aGF0IElEIGZvciB0aGUgZ3JvdXAgbmFtZS5cbiAgICAgKlxuICAgICAqID4gSWYgeW91IHNwZWNpZnkgYSBuYW1lLCB5b3UgY2Fubm90IHBlcmZvcm0gdXBkYXRlcyB0aGF0IHJlcXVpcmUgcmVwbGFjZW1lbnQgb2YgdGhpcyByZXNvdXJjZS4gWW91IGNhbiBwZXJmb3JtIHVwZGF0ZXMgdGhhdCByZXF1aXJlIG5vIG9yIHNvbWUgaW50ZXJydXB0aW9uLiBJZiB5b3UgbXVzdCByZXBsYWNlIHRoZSByZXNvdXJjZSwgc3BlY2lmeSBhIG5ldyBuYW1lLlxuICAgICAqXG4gICAgICogSWYgeW91IHNwZWNpZnkgYSBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBgQ0FQQUJJTElUWV9OQU1FRF9JQU1gIHZhbHVlIHRvIGFja25vd2xlZGdlIHlvdXIgdGVtcGxhdGUncyBjYXBhYmlsaXRpZXMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0Fja25vd2xlZGdpbmcgSUFNIFJlc291cmNlcyBpbiBBV1MgQ2xvdWRGb3JtYXRpb24gVGVtcGxhdGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS91c2luZy1pYW0tdGVtcGxhdGUuaHRtbCN1c2luZy1pYW0tY2FwYWJpbGl0aWVzKSAuXG4gICAgICpcbiAgICAgKiA+IE5hbWluZyBhbiBJQU0gcmVzb3VyY2UgY2FuIGNhdXNlIGFuIHVucmVjb3ZlcmFibGUgZXJyb3IgaWYgeW91IHJldXNlIHRoZSBzYW1lIHRlbXBsYXRlIGluIG11bHRpcGxlIFJlZ2lvbnMuIFRvIHByZXZlbnQgdGhpcywgd2UgcmVjb21tZW5kIHVzaW5nIGBGbjo6Sm9pbmAgYW5kIGBBV1M6OlJlZ2lvbmAgdG8gY3JlYXRlIGEgUmVnaW9uLXNwZWNpZmljIG5hbWUsIGFzIGluIHRoZSBmb2xsb3dpbmcgZXhhbXBsZTogYHtcIkZuOjpKb2luXCI6IFtcIlwiLCBbe1wiUmVmXCI6IFwiQVdTOjpSZWdpb25cIn0sIHtcIlJlZlwiOiBcIk15UmVzb3VyY2VOYW1lXCJ9XV19YCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1ncm91cC5odG1sI2Nmbi1pYW0tZ3JvdXAtZ3JvdXBuYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgZ3JvdXBOYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIG9mIHRoZSBJQU0gcG9saWN5IHlvdSB3YW50IHRvIGF0dGFjaC5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IEFSTnMsIHNlZSBbQW1hem9uIFJlc291cmNlIE5hbWVzIChBUk5zKV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dlbmVyYWwvbGF0ZXN0L2dyL2F3cy1hcm5zLWFuZC1uYW1lc3BhY2VzLmh0bWwpIGluIHRoZSAqQVdTIEdlbmVyYWwgUmVmZXJlbmNlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1ncm91cC5odG1sI2Nmbi1pYW0tZ3JvdXAtbWFuYWdlcG9saWN5YXJuc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IG1hbmFnZWRQb2xpY3lBcm5zPzogc3RyaW5nW107XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGF0aCB0byB0aGUgZ3JvdXAuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHBhdGhzLCBzZWUgW0lBTSBpZGVudGlmaWVyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL1VzaW5nX0lkZW50aWZpZXJzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGlzIG9wdGlvbmFsLiBJZiBpdCBpcyBub3QgaW5jbHVkZWQsIGl0IGRlZmF1bHRzIHRvIGEgc2xhc2ggKC8pLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIGVpdGhlciBhIGZvcndhcmQgc2xhc2ggKC8pIGJ5IGl0c2VsZiBvciBhIHN0cmluZyB0aGF0IG11c3QgYmVnaW4gYW5kIGVuZCB3aXRoIGZvcndhcmQgc2xhc2hlcy4gSW4gYWRkaXRpb24sIGl0IGNhbiBjb250YWluIGFueSBBU0NJSSBjaGFyYWN0ZXIgZnJvbSB0aGUgISAoIGBcXCB1MDAyMWAgKSB0aHJvdWdoIHRoZSBERUwgY2hhcmFjdGVyICggYFxcIHUwMDdGYCApLCBpbmNsdWRpbmcgbW9zdCBwdW5jdHVhdGlvbiBjaGFyYWN0ZXJzLCBkaWdpdHMsIGFuZCB1cHBlciBhbmQgbG93ZXJjYXNlZCBsZXR0ZXJzLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tZ3JvdXAuaHRtbCNjZm4taWFtLWdyb3VwLXBhdGhcbiAgICAgKi9cbiAgICByZWFkb25seSBwYXRoPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBvciB1cGRhdGVzIGFuIGlubGluZSBwb2xpY3kgZG9jdW1lbnQgdGhhdCBpcyBlbWJlZGRlZCBpbiB0aGUgc3BlY2lmaWVkIElBTSBncm91cC4gVG8gdmlldyBBV1M6OklBTTo6R3JvdXAgc25pcHBldHMsIHNlZSBbRGVjbGFyaW5nIGFuIElBTSBHcm91cCBSZXNvdXJjZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvcXVpY2tyZWYtaWFtLmh0bWwjc2NlbmFyaW8taWFtLWdyb3VwKSAuXG4gICAgICpcbiAgICAgKiA+IFRoZSBuYW1lIG9mIGVhY2ggaW5saW5lIHBvbGljeSBmb3IgYSByb2xlLCB1c2VyLCBvciBncm91cCBtdXN0IGJlIHVuaXF1ZS4gSWYgeW91IGRvbid0IGNob29zZSB1bmlxdWUgbmFtZXMsIHVwZGF0ZXMgdG8gdGhlIElBTSBpZGVudGl0eSB3aWxsIGZhaWwuXG4gICAgICpcbiAgICAgKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgbGltaXRzIG9uIHRoZSBudW1iZXIgb2YgaW5saW5lIHBvbGljaWVzIHRoYXQgeW91IGNhbiBlbWJlZCBpbiBhIGdyb3VwLCBzZWUgW0xpbWl0YXRpb25zIG9uIElBTSBFbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL0xpbWl0YXRpb25zT25FbnRpdGllcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1ncm91cC5odG1sI2Nmbi1pYW0tZ3JvdXAtcG9saWNpZXNcbiAgICAgKi9cbiAgICByZWFkb25seSBwb2xpY2llcz86IEFycmF5PENmbkdyb3VwLlBvbGljeVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDZm5Hcm91cFByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5Hcm91cFByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbkdyb3VwUHJvcHNWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdncm91cE5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuZ3JvdXBOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdtYW5hZ2VkUG9saWN5QXJucycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMubWFuYWdlZFBvbGljeUFybnMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BhdGgnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucGF0aCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWNpZXMnLCBjZGsubGlzdFZhbGlkYXRvcihDZm5Hcm91cF9Qb2xpY3lQcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMucG9saWNpZXMpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuR3JvdXBQcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpHcm91cGAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuR3JvdXBQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpHcm91cGAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5Hcm91cFByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5Hcm91cFByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBHcm91cE5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZ3JvdXBOYW1lKSxcbiAgICAgICAgTWFuYWdlZFBvbGljeUFybnM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLm1hbmFnZWRQb2xpY3lBcm5zKSxcbiAgICAgICAgUGF0aDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wYXRoKSxcbiAgICAgICAgUG9saWNpZXM6IGNkay5saXN0TWFwcGVyKGNmbkdyb3VwUG9saWN5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnBvbGljaWVzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuR3JvdXBQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmbkdyb3VwUHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkdyb3VwUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdncm91cE5hbWUnLCAnR3JvdXBOYW1lJywgcHJvcGVydGllcy5Hcm91cE5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuR3JvdXBOYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtYW5hZ2VkUG9saWN5QXJucycsICdNYW5hZ2VkUG9saWN5QXJucycsIHByb3BlcnRpZXMuTWFuYWdlZFBvbGljeUFybnMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5NYW5hZ2VkUG9saWN5QXJucykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncGF0aCcsICdQYXRoJywgcHJvcGVydGllcy5QYXRoICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlBhdGgpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BvbGljaWVzJywgJ1BvbGljaWVzJywgcHJvcGVydGllcy5Qb2xpY2llcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShDZm5Hcm91cFBvbGljeVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLlBvbGljaWVzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpJQU06Okdyb3VwYFxuICpcbiAqIENyZWF0ZXMgYSBuZXcgZ3JvdXAuXG4gKlxuICogRm9yIGluZm9ybWF0aW9uIGFib3V0IHRoZSBudW1iZXIgb2YgZ3JvdXBzIHlvdSBjYW4gY3JlYXRlLCBzZWUgW0xpbWl0YXRpb25zIG9uIElBTSBFbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL0xpbWl0YXRpb25zT25FbnRpdGllcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpJQU06Okdyb3VwXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tZ3JvdXAuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuR3JvdXAgZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpJQU06Okdyb3VwXCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5Hcm91cCB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuR3JvdXBQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuR3JvdXAoc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgZm9yIHRoZSBzcGVjaWZpZWQgYEFXUzo6SUFNOjpHcm91cGAgcmVzb3VyY2UuIEZvciBleGFtcGxlOiBgYXJuOmF3czppYW06OjEyMzQ1Njc4OTAxMjpncm91cC9teXN0YWNrLW15Z3JvdXAtMURaRVRJVE9XRUtWT2AgLlxuICAgICAqIEBjbG91ZGZvcm1hdGlvbkF0dHJpYnV0ZSBBcm5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgYXR0ckFybjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGdyb3VwIHRvIGNyZWF0ZS4gRG8gbm90IGluY2x1ZGUgdGhlIHBhdGggaW4gdGhpcyB2YWx1ZS5cbiAgICAgKlxuICAgICAqIFRoZSBncm91cCBuYW1lIG11c3QgYmUgdW5pcXVlIHdpdGhpbiB0aGUgYWNjb3VudC4gR3JvdXAgbmFtZXMgYXJlIG5vdCBkaXN0aW5ndWlzaGVkIGJ5IGNhc2UuIEZvciBleGFtcGxlLCB5b3UgY2Fubm90IGNyZWF0ZSBncm91cHMgbmFtZWQgYm90aCBcIkFETUlOU1wiIGFuZCBcImFkbWluc1wiLiBJZiB5b3UgZG9uJ3Qgc3BlY2lmeSBhIG5hbWUsIEFXUyBDbG91ZEZvcm1hdGlvbiBnZW5lcmF0ZXMgYSB1bmlxdWUgcGh5c2ljYWwgSUQgYW5kIHVzZXMgdGhhdCBJRCBmb3IgdGhlIGdyb3VwIG5hbWUuXG4gICAgICpcbiAgICAgKiA+IElmIHlvdSBzcGVjaWZ5IGEgbmFtZSwgeW91IGNhbm5vdCBwZXJmb3JtIHVwZGF0ZXMgdGhhdCByZXF1aXJlIHJlcGxhY2VtZW50IG9mIHRoaXMgcmVzb3VyY2UuIFlvdSBjYW4gcGVyZm9ybSB1cGRhdGVzIHRoYXQgcmVxdWlyZSBubyBvciBzb21lIGludGVycnVwdGlvbi4gSWYgeW91IG11c3QgcmVwbGFjZSB0aGUgcmVzb3VyY2UsIHNwZWNpZnkgYSBuZXcgbmFtZS5cbiAgICAgKlxuICAgICAqIElmIHlvdSBzcGVjaWZ5IGEgbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgYENBUEFCSUxJVFlfTkFNRURfSUFNYCB2YWx1ZSB0byBhY2tub3dsZWRnZSB5b3VyIHRlbXBsYXRlJ3MgY2FwYWJpbGl0aWVzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBY2tub3dsZWRnaW5nIElBTSBSZXNvdXJjZXMgaW4gQVdTIENsb3VkRm9ybWF0aW9uIFRlbXBsYXRlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvdXNpbmctaWFtLXRlbXBsYXRlLmh0bWwjdXNpbmctaWFtLWNhcGFiaWxpdGllcykgLlxuICAgICAqXG4gICAgICogPiBOYW1pbmcgYW4gSUFNIHJlc291cmNlIGNhbiBjYXVzZSBhbiB1bnJlY292ZXJhYmxlIGVycm9yIGlmIHlvdSByZXVzZSB0aGUgc2FtZSB0ZW1wbGF0ZSBpbiBtdWx0aXBsZSBSZWdpb25zLiBUbyBwcmV2ZW50IHRoaXMsIHdlIHJlY29tbWVuZCB1c2luZyBgRm46OkpvaW5gIGFuZCBgQVdTOjpSZWdpb25gIHRvIGNyZWF0ZSBhIFJlZ2lvbi1zcGVjaWZpYyBuYW1lLCBhcyBpbiB0aGUgZm9sbG93aW5nIGV4YW1wbGU6IGB7XCJGbjo6Sm9pblwiOiBbXCJcIiwgW3tcIlJlZlwiOiBcIkFXUzo6UmVnaW9uXCJ9LCB7XCJSZWZcIjogXCJNeVJlc291cmNlTmFtZVwifV1dfWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tZ3JvdXAuaHRtbCNjZm4taWFtLWdyb3VwLWdyb3VwbmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyBncm91cE5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgSUFNIHBvbGljeSB5b3Ugd2FudCB0byBhdHRhY2guXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBBUk5zLCBzZWUgW0FtYXpvbiBSZXNvdXJjZSBOYW1lcyAoQVJOcyldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nZW5lcmFsL2xhdGVzdC9nci9hd3MtYXJucy1hbmQtbmFtZXNwYWNlcy5odG1sKSBpbiB0aGUgKkFXUyBHZW5lcmFsIFJlZmVyZW5jZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tZ3JvdXAuaHRtbCNjZm4taWFtLWdyb3VwLW1hbmFnZXBvbGljeWFybnNcbiAgICAgKi9cbiAgICBwdWJsaWMgbWFuYWdlZFBvbGljeUFybnM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBhdGggdG8gdGhlIGdyb3VwLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gaWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiBlaXRoZXIgYSBmb3J3YXJkIHNsYXNoICgvKSBieSBpdHNlbGYgb3IgYSBzdHJpbmcgdGhhdCBtdXN0IGJlZ2luIGFuZCBlbmQgd2l0aCBmb3J3YXJkIHNsYXNoZXMuIEluIGFkZGl0aW9uLCBpdCBjYW4gY29udGFpbiBhbnkgQVNDSUkgY2hhcmFjdGVyIGZyb20gdGhlICEgKCBgXFwgdTAwMjFgICkgdGhyb3VnaCB0aGUgREVMIGNoYXJhY3RlciAoIGBcXCB1MDA3RmAgKSwgaW5jbHVkaW5nIG1vc3QgcHVuY3R1YXRpb24gY2hhcmFjdGVycywgZGlnaXRzLCBhbmQgdXBwZXIgYW5kIGxvd2VyY2FzZWQgbGV0dGVycy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLWdyb3VwLmh0bWwjY2ZuLWlhbS1ncm91cC1wYXRoXG4gICAgICovXG4gICAgcHVibGljIHBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgb3IgdXBkYXRlcyBhbiBpbmxpbmUgcG9saWN5IGRvY3VtZW50IHRoYXQgaXMgZW1iZWRkZWQgaW4gdGhlIHNwZWNpZmllZCBJQU0gZ3JvdXAuIFRvIHZpZXcgQVdTOjpJQU06Okdyb3VwIHNuaXBwZXRzLCBzZWUgW0RlY2xhcmluZyBhbiBJQU0gR3JvdXAgUmVzb3VyY2VdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL3F1aWNrcmVmLWlhbS5odG1sI3NjZW5hcmlvLWlhbS1ncm91cCkgLlxuICAgICAqXG4gICAgICogPiBUaGUgbmFtZSBvZiBlYWNoIGlubGluZSBwb2xpY3kgZm9yIGEgcm9sZSwgdXNlciwgb3IgZ3JvdXAgbXVzdCBiZSB1bmlxdWUuIElmIHlvdSBkb24ndCBjaG9vc2UgdW5pcXVlIG5hbWVzLCB1cGRhdGVzIHRvIHRoZSBJQU0gaWRlbnRpdHkgd2lsbCBmYWlsLlxuICAgICAqXG4gICAgICogRm9yIGluZm9ybWF0aW9uIGFib3V0IGxpbWl0cyBvbiB0aGUgbnVtYmVyIG9mIGlubGluZSBwb2xpY2llcyB0aGF0IHlvdSBjYW4gZW1iZWQgaW4gYSBncm91cCwgc2VlIFtMaW1pdGF0aW9ucyBvbiBJQU0gRW50aXRpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9MaW1pdGF0aW9uc09uRW50aXRpZXMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tZ3JvdXAuaHRtbCNjZm4taWFtLWdyb3VwLXBvbGljaWVzXG4gICAgICovXG4gICAgcHVibGljIHBvbGljaWVzOiBBcnJheTxDZm5Hcm91cC5Qb2xpY3lQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6SUFNOjpHcm91cGAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuR3JvdXBQcm9wcyA9IHt9KSB7XG4gICAgICAgIHN1cGVyKHNjb3BlLCBpZCwgeyB0eXBlOiBDZm5Hcm91cC5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgdGhpcy5hdHRyQXJuID0gY2RrLlRva2VuLmFzU3RyaW5nKHRoaXMuZ2V0QXR0KCdBcm4nKSk7XG5cbiAgICAgICAgdGhpcy5ncm91cE5hbWUgPSBwcm9wcy5ncm91cE5hbWU7XG4gICAgICAgIHRoaXMubWFuYWdlZFBvbGljeUFybnMgPSBwcm9wcy5tYW5hZ2VkUG9saWN5QXJucztcbiAgICAgICAgdGhpcy5wYXRoID0gcHJvcHMucGF0aDtcbiAgICAgICAgdGhpcy5wb2xpY2llcyA9IHByb3BzLnBvbGljaWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuR3JvdXAuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGdyb3VwTmFtZTogdGhpcy5ncm91cE5hbWUsXG4gICAgICAgICAgICBtYW5hZ2VkUG9saWN5QXJuczogdGhpcy5tYW5hZ2VkUG9saWN5QXJucyxcbiAgICAgICAgICAgIHBhdGg6IHRoaXMucGF0aCxcbiAgICAgICAgICAgIHBvbGljaWVzOiB0aGlzLnBvbGljaWVzLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmbkdyb3VwUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgQ2ZuR3JvdXAge1xuICAgIC8qKlxuICAgICAqIENvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGFuIGF0dGFjaGVkIHBvbGljeS5cbiAgICAgKlxuICAgICAqIEFuIGF0dGFjaGVkIHBvbGljeSBpcyBhIG1hbmFnZWQgcG9saWN5IHRoYXQgaGFzIGJlZW4gYXR0YWNoZWQgdG8gYSB1c2VyLCBncm91cCwgb3Igcm9sZS5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IG1hbmFnZWQgcG9saWNpZXMsIHNlZSBbTWFuYWdlZCBQb2xpY2llcyBhbmQgSW5saW5lIFBvbGljaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcG9saWNpZXMtbWFuYWdlZC12cy1pbmxpbmUuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXBvbGljeS5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBQb2xpY3lQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcG9saWN5IGRvY3VtZW50LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1wb2xpY3kuaHRtbCNjZm4taWFtLXBvbGljaWVzLXBvbGljeWRvY3VtZW50XG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBwb2xpY3lEb2N1bWVudDogYW55IHwgY2RrLklSZXNvbHZhYmxlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGZyaWVuZGx5IG5hbWUgKG5vdCBBUk4pIGlkZW50aWZ5aW5nIHRoZSBwb2xpY3kuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXBvbGljeS5odG1sI2Nmbi1pYW0tcG9saWNpZXMtcG9saWN5bmFtZVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcG9saWN5TmFtZTogc3RyaW5nO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBQb2xpY3lQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgUG9saWN5UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuR3JvdXBfUG9saWN5UHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb2xpY3lEb2N1bWVudCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5wb2xpY3lEb2N1bWVudCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5RG9jdW1lbnQnLCBjZGsudmFsaWRhdGVPYmplY3QpKHByb3BlcnRpZXMucG9saWN5RG9jdW1lbnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvbGljeU5hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMucG9saWN5TmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5TmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5wb2xpY3lOYW1lKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIlBvbGljeVByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06Okdyb3VwLlBvbGljeWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgUG9saWN5UHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6R3JvdXAuUG9saWN5YCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmbkdyb3VwUG9saWN5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmbkdyb3VwX1BvbGljeVByb3BlcnR5VmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBQb2xpY3lEb2N1bWVudDogY2RrLm9iamVjdFRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wb2xpY3lEb2N1bWVudCksXG4gICAgICAgIFBvbGljeU5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucG9saWN5TmFtZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkdyb3VwUG9saWN5UHJvcGVydHlGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5Hcm91cC5Qb2xpY3lQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5Hcm91cC5Qb2xpY3lQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BvbGljeURvY3VtZW50JywgJ1BvbGljeURvY3VtZW50JywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBbnkocHJvcGVydGllcy5Qb2xpY3lEb2N1bWVudCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncG9saWN5TmFtZScsICdQb2xpY3lOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Qb2xpY3lOYW1lKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuSW5zdGFuY2VQcm9maWxlYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0taW5zdGFuY2Vwcm9maWxlLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5JbnN0YW5jZVByb2ZpbGVQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcm9sZSB0byBhc3NvY2lhdGUgd2l0aCB0aGUgaW5zdGFuY2UgcHJvZmlsZS4gT25seSBvbmUgcm9sZSBjYW4gYmUgYXNzaWduZWQgdG8gYW4gRUMyIGluc3RhbmNlIGF0IGEgdGltZSwgYW5kIGFsbCBhcHBsaWNhdGlvbnMgb24gdGhlIGluc3RhbmNlIHNoYXJlIHRoZSBzYW1lIHJvbGUgYW5kIHBlcm1pc3Npb25zLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLWluc3RhbmNlcHJvZmlsZS5odG1sI2Nmbi1pYW0taW5zdGFuY2Vwcm9maWxlLXJvbGVzXG4gICAgICovXG4gICAgcmVhZG9ubHkgcm9sZXM6IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGluc3RhbmNlIHByb2ZpbGUgdG8gY3JlYXRlLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1pbnN0YW5jZXByb2ZpbGUuaHRtbCNjZm4taWFtLWluc3RhbmNlcHJvZmlsZS1pbnN0YW5jZXByb2ZpbGVuYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgaW5zdGFuY2VQcm9maWxlTmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBwYXRoIHRvIHRoZSBpbnN0YW5jZSBwcm9maWxlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gSWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiBlaXRoZXIgYSBmb3J3YXJkIHNsYXNoICgvKSBieSBpdHNlbGYgb3IgYSBzdHJpbmcgdGhhdCBtdXN0IGJlZ2luIGFuZCBlbmQgd2l0aCBmb3J3YXJkIHNsYXNoZXMuIEluIGFkZGl0aW9uLCBpdCBjYW4gY29udGFpbiBhbnkgQVNDSUkgY2hhcmFjdGVyIGZyb20gdGhlICEgKCBgXFwgdTAwMjFgICkgdGhyb3VnaCB0aGUgREVMIGNoYXJhY3RlciAoIGBcXCB1MDA3RmAgKSwgaW5jbHVkaW5nIG1vc3QgcHVuY3R1YXRpb24gY2hhcmFjdGVycywgZGlnaXRzLCBhbmQgdXBwZXIgYW5kIGxvd2VyY2FzZWQgbGV0dGVycy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1pbnN0YW5jZXByb2ZpbGUuaHRtbCNjZm4taWFtLWluc3RhbmNlcHJvZmlsZS1wYXRoXG4gICAgICovXG4gICAgcmVhZG9ubHkgcGF0aD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDZm5JbnN0YW5jZVByb2ZpbGVQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuSW5zdGFuY2VQcm9maWxlUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuSW5zdGFuY2VQcm9maWxlUHJvcHNWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdpbnN0YW5jZVByb2ZpbGVOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmluc3RhbmNlUHJvZmlsZU5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BhdGgnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucGF0aCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncm9sZXMnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMucm9sZXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3JvbGVzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5yb2xlcykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5JbnN0YW5jZVByb2ZpbGVQcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpJbnN0YW5jZVByb2ZpbGVgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmbkluc3RhbmNlUHJvZmlsZVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06Okluc3RhbmNlUHJvZmlsZWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5JbnN0YW5jZVByb2ZpbGVQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuSW5zdGFuY2VQcm9maWxlUHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFJvbGVzOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5yb2xlcyksXG4gICAgICAgIEluc3RhbmNlUHJvZmlsZU5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuaW5zdGFuY2VQcm9maWxlTmFtZSksXG4gICAgICAgIFBhdGg6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucGF0aCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbkluc3RhbmNlUHJvZmlsZVByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuSW5zdGFuY2VQcm9maWxlUHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbkluc3RhbmNlUHJvZmlsZVByb3BzPigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncm9sZXMnLCAnUm9sZXMnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuUm9sZXMpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2luc3RhbmNlUHJvZmlsZU5hbWUnLCAnSW5zdGFuY2VQcm9maWxlTmFtZScsIHByb3BlcnRpZXMuSW5zdGFuY2VQcm9maWxlTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5JbnN0YW5jZVByb2ZpbGVOYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwYXRoJywgJ1BhdGgnLCBwcm9wZXJ0aWVzLlBhdGggIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUGF0aCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6SUFNOjpJbnN0YW5jZVByb2ZpbGVgXG4gKlxuICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBwcm9maWxlLiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgaW5zdGFuY2UgcHJvZmlsZXMsIHNlZSBbVXNpbmcgaW5zdGFuY2UgcHJvZmlsZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF9yb2xlc191c2Vfc3dpdGNoLXJvbGUtZWMyX2luc3RhbmNlLXByb2ZpbGVzLmh0bWwpIC5cbiAqXG4gKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG51bWJlciBvZiBpbnN0YW5jZSBwcm9maWxlcyB5b3UgY2FuIGNyZWF0ZSwgc2VlIFtJQU0gb2JqZWN0IHF1b3Rhc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9pYW0tcXVvdGFzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAqXG4gKiBAY2xvdWRmb3JtYXRpb25SZXNvdXJjZSBBV1M6OklBTTo6SW5zdGFuY2VQcm9maWxlXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLWluc3RhbmNlcHJvZmlsZS5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5JbnN0YW5jZVByb2ZpbGUgZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpJQU06Okluc3RhbmNlUHJvZmlsZVwiO1xuXG4gICAgLyoqXG4gICAgICogQSBmYWN0b3J5IG1ldGhvZCB0aGF0IGNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmcm9tIGFuIG9iamVjdFxuICAgICAqIGNvbnRhaW5pbmcgdGhlIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgdGhpcyByZXNvdXJjZS5cbiAgICAgKiBVc2VkIGluIHRoZSBAYXdzLWNkay9jbG91ZGZvcm1hdGlvbi1pbmNsdWRlIG1vZHVsZS5cbiAgICAgKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgX2Zyb21DbG91ZEZvcm1hdGlvbihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcmVzb3VyY2VBdHRyaWJ1dGVzOiBhbnksIG9wdGlvbnM6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25PcHRpb25zKTogQ2ZuSW5zdGFuY2VQcm9maWxlIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5JbnN0YW5jZVByb2ZpbGVQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuSW5zdGFuY2VQcm9maWxlKHNjb3BlLCBpZCwgcHJvcHNSZXN1bHQudmFsdWUpO1xuICAgICAgICBmb3IgKGNvbnN0IFtwcm9wS2V5LCBwcm9wVmFsXSBvZiBPYmplY3QuZW50cmllcyhwcm9wc1Jlc3VsdC5leHRyYVByb3BlcnRpZXMpKSAge1xuICAgICAgICAgICAgcmV0LmFkZFByb3BlcnR5T3ZlcnJpZGUocHJvcEtleSwgcHJvcFZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5wYXJzZXIuaGFuZGxlQXR0cmlidXRlcyhyZXQsIHJlc291cmNlQXR0cmlidXRlcywgaWQpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIGZvciB0aGUgaW5zdGFuY2UgcHJvZmlsZS4gRm9yIGV4YW1wbGU6XG4gICAgICpcbiAgICAgKiBge1wiRm46OkdldEF0dFwiIDogW1wiTXlQcm9maWxlXCIsIFwiQXJuXCJdIH1gXG4gICAgICpcbiAgICAgKiBUaGlzIHJldHVybnMgYSB2YWx1ZSBzdWNoIGFzIGBhcm46YXdzOmlhbTo6MTIzNDU2Nzg5MDppbnN0YW5jZS1wcm9maWxlL015UHJvZmlsZS1BU0ROU0RMS0pgIC5cbiAgICAgKiBAY2xvdWRmb3JtYXRpb25BdHRyaWJ1dGUgQXJuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJBcm46IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSByb2xlIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBpbnN0YW5jZSBwcm9maWxlLiBPbmx5IG9uZSByb2xlIGNhbiBiZSBhc3NpZ25lZCB0byBhbiBFQzIgaW5zdGFuY2UgYXQgYSB0aW1lLCBhbmQgYWxsIGFwcGxpY2F0aW9ucyBvbiB0aGUgaW5zdGFuY2Ugc2hhcmUgdGhlIHNhbWUgcm9sZSBhbmQgcGVybWlzc2lvbnMuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0taW5zdGFuY2Vwcm9maWxlLmh0bWwjY2ZuLWlhbS1pbnN0YW5jZXByb2ZpbGUtcm9sZXNcbiAgICAgKi9cbiAgICBwdWJsaWMgcm9sZXM6IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGluc3RhbmNlIHByb2ZpbGUgdG8gY3JlYXRlLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1pbnN0YW5jZXByb2ZpbGUuaHRtbCNjZm4taWFtLWluc3RhbmNlcHJvZmlsZS1pbnN0YW5jZXByb2ZpbGVuYW1lXG4gICAgICovXG4gICAgcHVibGljIGluc3RhbmNlUHJvZmlsZU5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwYXRoIHRvIHRoZSBpbnN0YW5jZSBwcm9maWxlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gSWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiBlaXRoZXIgYSBmb3J3YXJkIHNsYXNoICgvKSBieSBpdHNlbGYgb3IgYSBzdHJpbmcgdGhhdCBtdXN0IGJlZ2luIGFuZCBlbmQgd2l0aCBmb3J3YXJkIHNsYXNoZXMuIEluIGFkZGl0aW9uLCBpdCBjYW4gY29udGFpbiBhbnkgQVNDSUkgY2hhcmFjdGVyIGZyb20gdGhlICEgKCBgXFwgdTAwMjFgICkgdGhyb3VnaCB0aGUgREVMIGNoYXJhY3RlciAoIGBcXCB1MDA3RmAgKSwgaW5jbHVkaW5nIG1vc3QgcHVuY3R1YXRpb24gY2hhcmFjdGVycywgZGlnaXRzLCBhbmQgdXBwZXIgYW5kIGxvd2VyY2FzZWQgbGV0dGVycy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1pbnN0YW5jZXByb2ZpbGUuaHRtbCNjZm4taWFtLWluc3RhbmNlcHJvZmlsZS1wYXRoXG4gICAgICovXG4gICAgcHVibGljIHBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpJQU06Okluc3RhbmNlUHJvZmlsZWAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuSW5zdGFuY2VQcm9maWxlUHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmbkluc3RhbmNlUHJvZmlsZS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ3JvbGVzJywgdGhpcyk7XG4gICAgICAgIHRoaXMuYXR0ckFybiA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnQXJuJykpO1xuXG4gICAgICAgIHRoaXMucm9sZXMgPSBwcm9wcy5yb2xlcztcbiAgICAgICAgdGhpcy5pbnN0YW5jZVByb2ZpbGVOYW1lID0gcHJvcHMuaW5zdGFuY2VQcm9maWxlTmFtZTtcbiAgICAgICAgdGhpcy5wYXRoID0gcHJvcHMucGF0aDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmbkluc3RhbmNlUHJvZmlsZS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcm9sZXM6IHRoaXMucm9sZXMsXG4gICAgICAgICAgICBpbnN0YW5jZVByb2ZpbGVOYW1lOiB0aGlzLmluc3RhbmNlUHJvZmlsZU5hbWUsXG4gICAgICAgICAgICBwYXRoOiB0aGlzLnBhdGgsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuSW5zdGFuY2VQcm9maWxlUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuTWFuYWdlZFBvbGljeWBcbiAqXG4gKiBAc3RydWN0XG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW1hbmFnZWRwb2xpY3kuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmbk1hbmFnZWRQb2xpY3lQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgSlNPTiBwb2xpY3kgZG9jdW1lbnQgdGhhdCB5b3Ugd2FudCB0byB1c2UgYXMgdGhlIGNvbnRlbnQgZm9yIHRoZSBuZXcgcG9saWN5LlxuICAgICAqXG4gICAgICogWW91IG11c3QgcHJvdmlkZSBwb2xpY2llcyBpbiBKU09OIGZvcm1hdCBpbiBJQU0uIEhvd2V2ZXIsIGZvciBBV1MgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGVzIGZvcm1hdHRlZCBpbiBZQU1MLCB5b3UgY2FuIHByb3ZpZGUgdGhlIHBvbGljeSBpbiBKU09OIG9yIFlBTUwgZm9ybWF0LiBBV1MgQ2xvdWRGb3JtYXRpb24gYWx3YXlzIGNvbnZlcnRzIGEgWUFNTCBwb2xpY3kgdG8gSlNPTiBmb3JtYXQgYmVmb3JlIHN1Ym1pdHRpbmcgaXQgdG8gSUFNLlxuICAgICAqXG4gICAgICogVGhlIG1heGltdW0gbGVuZ3RoIG9mIHRoZSBwb2xpY3kgZG9jdW1lbnQgdGhhdCB5b3UgY2FuIHBhc3MgaW4gdGhpcyBvcGVyYXRpb24sIGluY2x1ZGluZyB3aGl0ZXNwYWNlLCBpcyBsaXN0ZWQgYmVsb3cuIFRvIHZpZXcgdGhlIG1heGltdW0gY2hhcmFjdGVyIGNvdW50cyBvZiBhIG1hbmFnZWQgcG9saWN5IHdpdGggbm8gd2hpdGVzcGFjZXMsIHNlZSBbSUFNIGFuZCBBV1MgU1RTIGNoYXJhY3RlciBxdW90YXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfaWFtLXF1b3Rhcy5odG1sI3JlZmVyZW5jZV9pYW0tcXVvdGFzLWVudGl0eS1sZW5ndGgpIC5cbiAgICAgKlxuICAgICAqIFRvIGxlYXJuIG1vcmUgYWJvdXQgSlNPTiBwb2xpY3kgZ3JhbW1hciwgc2VlIFtHcmFtbWFyIG9mIHRoZSBJQU0gSlNPTiBwb2xpY3kgbGFuZ3VhZ2VdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZ3JhbW1hci5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGUgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSB1c2VkIHRvIHZhbGlkYXRlIHRoaXMgcGFyYW1ldGVyIGlzIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBBbnkgcHJpbnRhYmxlIEFTQ0lJIGNoYXJhY3RlciByYW5naW5nIGZyb20gdGhlIHNwYWNlIGNoYXJhY3RlciAoIGBcXCB1MDAyMGAgKSB0aHJvdWdoIHRoZSBlbmQgb2YgdGhlIEFTQ0lJIGNoYXJhY3RlciByYW5nZVxuICAgICAqIC0gVGhlIHByaW50YWJsZSBjaGFyYWN0ZXJzIGluIHRoZSBCYXNpYyBMYXRpbiBhbmQgTGF0aW4tMSBTdXBwbGVtZW50IGNoYXJhY3RlciBzZXQgKHRocm91Z2ggYFxcIHUwMEZGYCApXG4gICAgICogLSBUaGUgc3BlY2lhbCBjaGFyYWN0ZXJzIHRhYiAoIGBcXCB1MDAwOWAgKSwgbGluZSBmZWVkICggYFxcIHUwMDBBYCApLCBhbmQgY2FycmlhZ2UgcmV0dXJuICggYFxcIHUwMDBEYCApXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tbWFuYWdlZHBvbGljeS5odG1sI2Nmbi1pYW0tbWFuYWdlZHBvbGljeS1wb2xpY3lkb2N1bWVudFxuICAgICAqL1xuICAgIHJlYWRvbmx5IHBvbGljeURvY3VtZW50OiBhbnkgfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBBIGZyaWVuZGx5IGRlc2NyaXB0aW9uIG9mIHRoZSBwb2xpY3kuXG4gICAgICpcbiAgICAgKiBUeXBpY2FsbHkgdXNlZCB0byBzdG9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGVybWlzc2lvbnMgZGVmaW5lZCBpbiB0aGUgcG9saWN5LiBGb3IgZXhhbXBsZSwgXCJHcmFudHMgYWNjZXNzIHRvIHByb2R1Y3Rpb24gRHluYW1vREIgdGFibGVzLlwiXG4gICAgICpcbiAgICAgKiBUaGUgcG9saWN5IGRlc2NyaXB0aW9uIGlzIGltbXV0YWJsZS4gQWZ0ZXIgYSB2YWx1ZSBpcyBhc3NpZ25lZCwgaXQgY2Fubm90IGJlIGNoYW5nZWQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tbWFuYWdlZHBvbGljeS5odG1sI2Nmbi1pYW0tbWFuYWdlZHBvbGljeS1kZXNjcmlwdGlvblxuICAgICAqL1xuICAgIHJlYWRvbmx5IGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgKGZyaWVuZGx5IG5hbWUsIG5vdCBBUk4pIG9mIHRoZSBncm91cCB0byBhdHRhY2ggdGhlIHBvbGljeSB0by5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tbWFuYWdlZHBvbGljeS5odG1sI2Nmbi1pYW0tbWFuYWdlZHBvbGljeS1ncm91cHNcbiAgICAgKi9cbiAgICByZWFkb25seSBncm91cHM/OiBzdHJpbmdbXTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBmcmllbmRseSBuYW1lIG9mIHRoZSBwb2xpY3kuXG4gICAgICpcbiAgICAgKiA+IElmIHlvdSBzcGVjaWZ5IGEgbmFtZSwgeW91IGNhbm5vdCBwZXJmb3JtIHVwZGF0ZXMgdGhhdCByZXF1aXJlIHJlcGxhY2VtZW50IG9mIHRoaXMgcmVzb3VyY2UuIFlvdSBjYW4gcGVyZm9ybSB1cGRhdGVzIHRoYXQgcmVxdWlyZSBubyBvciBzb21lIGludGVycnVwdGlvbi4gSWYgeW91IG11c3QgcmVwbGFjZSB0aGUgcmVzb3VyY2UsIHNwZWNpZnkgYSBuZXcgbmFtZS5cbiAgICAgKlxuICAgICAqIElmIHlvdSBzcGVjaWZ5IGEgbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgYENBUEFCSUxJVFlfTkFNRURfSUFNYCB2YWx1ZSB0byBhY2tub3dsZWRnZSB5b3VyIHRlbXBsYXRlJ3MgY2FwYWJpbGl0aWVzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBY2tub3dsZWRnaW5nIElBTSBSZXNvdXJjZXMgaW4gQVdTIENsb3VkRm9ybWF0aW9uIFRlbXBsYXRlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvdXNpbmctaWFtLXRlbXBsYXRlLmh0bWwjdXNpbmctaWFtLWNhcGFiaWxpdGllcykgLlxuICAgICAqXG4gICAgICogPiBOYW1pbmcgYW4gSUFNIHJlc291cmNlIGNhbiBjYXVzZSBhbiB1bnJlY292ZXJhYmxlIGVycm9yIGlmIHlvdSByZXVzZSB0aGUgc2FtZSB0ZW1wbGF0ZSBpbiBtdWx0aXBsZSBSZWdpb25zLiBUbyBwcmV2ZW50IHRoaXMsIHdlIHJlY29tbWVuZCB1c2luZyBgRm46OkpvaW5gIGFuZCBgQVdTOjpSZWdpb25gIHRvIGNyZWF0ZSBhIFJlZ2lvbi1zcGVjaWZpYyBuYW1lLCBhcyBpbiB0aGUgZm9sbG93aW5nIGV4YW1wbGU6IGB7XCJGbjo6Sm9pblwiOiBbXCJcIiwgW3tcIlJlZlwiOiBcIkFXUzo6UmVnaW9uXCJ9LCB7XCJSZWZcIjogXCJNeVJlc291cmNlTmFtZVwifV1dfWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW1hbmFnZWRwb2xpY3kuaHRtbCNjZm4taWFtLW1hbmFnZWRwb2xpY3ktbWFuYWdlZHBvbGljeW5hbWVcbiAgICAgKi9cbiAgICByZWFkb25seSBtYW5hZ2VkUG9saWN5TmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBwYXRoIGZvciB0aGUgcG9saWN5LlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgcGF0aHMsIHNlZSBbSUFNIGlkZW50aWZpZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvVXNpbmdfSWRlbnRpZmllcnMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgaXMgb3B0aW9uYWwuIElmIGl0IGlzIG5vdCBpbmNsdWRlZCwgaXQgZGVmYXVsdHMgdG8gYSBzbGFzaCAoLykuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgZWl0aGVyIGEgZm9yd2FyZCBzbGFzaCAoLykgYnkgaXRzZWxmIG9yIGEgc3RyaW5nIHRoYXQgbXVzdCBiZWdpbiBhbmQgZW5kIHdpdGggZm9yd2FyZCBzbGFzaGVzLiBJbiBhZGRpdGlvbiwgaXQgY2FuIGNvbnRhaW4gYW55IEFTQ0lJIGNoYXJhY3RlciBmcm9tIHRoZSAhICggYFxcIHUwMDIxYCApIHRocm91Z2ggdGhlIERFTCBjaGFyYWN0ZXIgKCBgXFwgdTAwN0ZgICksIGluY2x1ZGluZyBtb3N0IHB1bmN0dWF0aW9uIGNoYXJhY3RlcnMsIGRpZ2l0cywgYW5kIHVwcGVyIGFuZCBsb3dlcmNhc2VkIGxldHRlcnMuXG4gICAgICpcbiAgICAgKiA+IFlvdSBjYW5ub3QgdXNlIGFuIGFzdGVyaXNrICgqKSBpbiB0aGUgcGF0aCBuYW1lLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW1hbmFnZWRwb2xpY3kuaHRtbCNjZm4tZWMyLWRoY3BvcHRpb25zLXBhdGhcbiAgICAgKi9cbiAgICByZWFkb25seSBwYXRoPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgKGZyaWVuZGx5IG5hbWUsIG5vdCBBUk4pIG9mIHRoZSByb2xlIHRvIGF0dGFjaCB0aGUgcG9saWN5IHRvLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzIChwZXIgaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdXBwZXIgYW5kIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyB3aXRoIG5vIHNwYWNlcy4gWW91IGNhbiBhbHNvIGluY2x1ZGUgYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogXys9LC5ALVxuICAgICAqXG4gICAgICogPiBJZiBhbiBleHRlcm5hbCBwb2xpY3kgKHN1Y2ggYXMgYEFXUzo6SUFNOjpQb2xpY3lgIG9yIGBBV1M6OklBTTo6TWFuYWdlZFBvbGljeWAgKSBoYXMgYSBgUmVmYCB0byBhIHJvbGUgYW5kIGlmIGEgcmVzb3VyY2UgKHN1Y2ggYXMgYEFXUzo6RUNTOjpTZXJ2aWNlYCApIGFsc28gaGFzIGEgYFJlZmAgdG8gdGhlIHNhbWUgcm9sZSwgYWRkIGEgYERlcGVuZHNPbmAgYXR0cmlidXRlIHRvIHRoZSByZXNvdXJjZSB0byBtYWtlIHRoZSByZXNvdXJjZSBkZXBlbmQgb24gdGhlIGV4dGVybmFsIHBvbGljeS4gVGhpcyBkZXBlbmRlbmN5IGVuc3VyZXMgdGhhdCB0aGUgcm9sZSdzIHBvbGljeSBpcyBhdmFpbGFibGUgdGhyb3VnaG91dCB0aGUgcmVzb3VyY2UncyBsaWZlY3ljbGUuIEZvciBleGFtcGxlLCB3aGVuIHlvdSBkZWxldGUgYSBzdGFjayB3aXRoIGFuIGBBV1M6OkVDUzo6U2VydmljZWAgcmVzb3VyY2UsIHRoZSBgRGVwZW5kc09uYCBhdHRyaWJ1dGUgZW5zdXJlcyB0aGF0IEFXUyBDbG91ZEZvcm1hdGlvbiBkZWxldGVzIHRoZSBgQVdTOjpFQ1M6OlNlcnZpY2VgIHJlc291cmNlIGJlZm9yZSBkZWxldGluZyBpdHMgcm9sZSdzIHBvbGljeS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1tYW5hZ2VkcG9saWN5Lmh0bWwjY2ZuLWlhbS1tYW5hZ2VkcG9saWN5LXJvbGVzXG4gICAgICovXG4gICAgcmVhZG9ubHkgcm9sZXM/OiBzdHJpbmdbXTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIChmcmllbmRseSBuYW1lLCBub3QgQVJOKSBvZiB0aGUgSUFNIHVzZXIgdG8gYXR0YWNoIHRoZSBwb2xpY3kgdG8uXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdXBwZXIgYW5kIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyB3aXRoIG5vIHNwYWNlcy4gWW91IGNhbiBhbHNvIGluY2x1ZGUgYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogXys9LC5ALVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW1hbmFnZWRwb2xpY3kuaHRtbCNjZm4taWFtLW1hbmFnZWRwb2xpY3ktdXNlcnNcbiAgICAgKi9cbiAgICByZWFkb25seSB1c2Vycz86IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbk1hbmFnZWRQb2xpY3lQcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuTWFuYWdlZFBvbGljeVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmbk1hbmFnZWRQb2xpY3lQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Rlc2NyaXB0aW9uJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmRlc2NyaXB0aW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdncm91cHMnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLmdyb3VwcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbWFuYWdlZFBvbGljeU5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMubWFuYWdlZFBvbGljeU5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BhdGgnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucGF0aCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5RG9jdW1lbnQnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMucG9saWN5RG9jdW1lbnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvbGljeURvY3VtZW50JywgY2RrLnZhbGlkYXRlT2JqZWN0KShwcm9wZXJ0aWVzLnBvbGljeURvY3VtZW50KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyb2xlcycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMucm9sZXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3VzZXJzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy51c2VycykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5NYW5hZ2VkUG9saWN5UHJvcHNcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6TWFuYWdlZFBvbGljeWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuTWFuYWdlZFBvbGljeVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06Ok1hbmFnZWRQb2xpY3lgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuTWFuYWdlZFBvbGljeVByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5NYW5hZ2VkUG9saWN5UHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFBvbGljeURvY3VtZW50OiBjZGsub2JqZWN0VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBvbGljeURvY3VtZW50KSxcbiAgICAgICAgRGVzY3JpcHRpb246IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZGVzY3JpcHRpb24pLFxuICAgICAgICBHcm91cHM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLmdyb3VwcyksXG4gICAgICAgIE1hbmFnZWRQb2xpY3lOYW1lOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLm1hbmFnZWRQb2xpY3lOYW1lKSxcbiAgICAgICAgUGF0aDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wYXRoKSxcbiAgICAgICAgUm9sZXM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnJvbGVzKSxcbiAgICAgICAgVXNlcnM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnVzZXJzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuTWFuYWdlZFBvbGljeVByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuTWFuYWdlZFBvbGljeVByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5NYW5hZ2VkUG9saWN5UHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwb2xpY3lEb2N1bWVudCcsICdQb2xpY3lEb2N1bWVudCcsIGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QW55KHByb3BlcnRpZXMuUG9saWN5RG9jdW1lbnQpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Rlc2NyaXB0aW9uJywgJ0Rlc2NyaXB0aW9uJywgcHJvcGVydGllcy5EZXNjcmlwdGlvbiAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5EZXNjcmlwdGlvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZ3JvdXBzJywgJ0dyb3VwcycsIHByb3BlcnRpZXMuR3JvdXBzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuR3JvdXBzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtYW5hZ2VkUG9saWN5TmFtZScsICdNYW5hZ2VkUG9saWN5TmFtZScsIHByb3BlcnRpZXMuTWFuYWdlZFBvbGljeU5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuTWFuYWdlZFBvbGljeU5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BhdGgnLCAnUGF0aCcsIHByb3BlcnRpZXMuUGF0aCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5QYXRoKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdyb2xlcycsICdSb2xlcycsIHByb3BlcnRpZXMuUm9sZXMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5Sb2xlcykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndXNlcnMnLCAnVXNlcnMnLCBwcm9wZXJ0aWVzLlVzZXJzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuVXNlcnMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBBIENsb3VkRm9ybWF0aW9uIGBBV1M6OklBTTo6TWFuYWdlZFBvbGljeWBcbiAqXG4gKiBDcmVhdGVzIGEgbmV3IG1hbmFnZWQgcG9saWN5IGZvciB5b3VyIEFXUyBhY2NvdW50IC5cbiAqXG4gKiBUaGlzIG9wZXJhdGlvbiBjcmVhdGVzIGEgcG9saWN5IHZlcnNpb24gd2l0aCBhIHZlcnNpb24gaWRlbnRpZmllciBvZiBgdjFgIGFuZCBzZXRzIHYxIGFzIHRoZSBwb2xpY3kncyBkZWZhdWx0IHZlcnNpb24uIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHBvbGljeSB2ZXJzaW9ucywgc2VlIFtWZXJzaW9uaW5nIGZvciBtYW5hZ2VkIHBvbGljaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcG9saWNpZXMtbWFuYWdlZC12ZXJzaW9ucy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gKlxuICogQXMgYSBiZXN0IHByYWN0aWNlLCB5b3UgY2FuIHZhbGlkYXRlIHlvdXIgSUFNIHBvbGljaWVzLiBUbyBsZWFybiBtb3JlLCBzZWUgW1ZhbGlkYXRpbmcgSUFNIHBvbGljaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvYWNjZXNzX3BvbGljaWVzX3BvbGljeS12YWxpZGF0b3IuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICpcbiAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IG1hbmFnZWQgcG9saWNpZXMgaW4gZ2VuZXJhbCwgc2VlIFtNYW5hZ2VkIHBvbGljaWVzIGFuZCBpbmxpbmUgcG9saWNpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9wb2xpY2llcy1tYW5hZ2VkLXZzLWlubGluZS5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpJQU06Ok1hbmFnZWRQb2xpY3lcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tbWFuYWdlZHBvbGljeS5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5NYW5hZ2VkUG9saWN5IGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6SUFNOjpNYW5hZ2VkUG9saWN5XCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5NYW5hZ2VkUG9saWN5IHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5NYW5hZ2VkUG9saWN5UHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmbk1hbmFnZWRQb2xpY3koc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIEpTT04gcG9saWN5IGRvY3VtZW50IHRoYXQgeW91IHdhbnQgdG8gdXNlIGFzIHRoZSBjb250ZW50IGZvciB0aGUgbmV3IHBvbGljeS5cbiAgICAgKlxuICAgICAqIFlvdSBtdXN0IHByb3ZpZGUgcG9saWNpZXMgaW4gSlNPTiBmb3JtYXQgaW4gSUFNLiBIb3dldmVyLCBmb3IgQVdTIENsb3VkRm9ybWF0aW9uIHRlbXBsYXRlcyBmb3JtYXR0ZWQgaW4gWUFNTCwgeW91IGNhbiBwcm92aWRlIHRoZSBwb2xpY3kgaW4gSlNPTiBvciBZQU1MIGZvcm1hdC4gQVdTIENsb3VkRm9ybWF0aW9uIGFsd2F5cyBjb252ZXJ0cyBhIFlBTUwgcG9saWN5IHRvIEpTT04gZm9ybWF0IGJlZm9yZSBzdWJtaXR0aW5nIGl0IHRvIElBTS5cbiAgICAgKlxuICAgICAqIFRoZSBtYXhpbXVtIGxlbmd0aCBvZiB0aGUgcG9saWN5IGRvY3VtZW50IHRoYXQgeW91IGNhbiBwYXNzIGluIHRoaXMgb3BlcmF0aW9uLCBpbmNsdWRpbmcgd2hpdGVzcGFjZSwgaXMgbGlzdGVkIGJlbG93LiBUbyB2aWV3IHRoZSBtYXhpbXVtIGNoYXJhY3RlciBjb3VudHMgb2YgYSBtYW5hZ2VkIHBvbGljeSB3aXRoIG5vIHdoaXRlc3BhY2VzLCBzZWUgW0lBTSBhbmQgQVdTIFNUUyBjaGFyYWN0ZXIgcXVvdGFzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX2lhbS1xdW90YXMuaHRtbCNyZWZlcmVuY2VfaWFtLXF1b3Rhcy1lbnRpdHktbGVuZ3RoKSAuXG4gICAgICpcbiAgICAgKiBUbyBsZWFybiBtb3JlIGFib3V0IEpTT04gcG9saWN5IGdyYW1tYXIsIHNlZSBbR3JhbW1hciBvZiB0aGUgSUFNIEpTT04gcG9saWN5IGxhbmd1YWdlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2dyYW1tYXIuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogVGhlIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgdXNlZCB0byB2YWxpZGF0ZSB0aGlzIHBhcmFtZXRlciBpcyBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gQW55IHByaW50YWJsZSBBU0NJSSBjaGFyYWN0ZXIgcmFuZ2luZyBmcm9tIHRoZSBzcGFjZSBjaGFyYWN0ZXIgKCBgXFwgdTAwMjBgICkgdGhyb3VnaCB0aGUgZW5kIG9mIHRoZSBBU0NJSSBjaGFyYWN0ZXIgcmFuZ2VcbiAgICAgKiAtIFRoZSBwcmludGFibGUgY2hhcmFjdGVycyBpbiB0aGUgQmFzaWMgTGF0aW4gYW5kIExhdGluLTEgU3VwcGxlbWVudCBjaGFyYWN0ZXIgc2V0ICh0aHJvdWdoIGBcXCB1MDBGRmAgKVxuICAgICAqIC0gVGhlIHNwZWNpYWwgY2hhcmFjdGVycyB0YWIgKCBgXFwgdTAwMDlgICksIGxpbmUgZmVlZCAoIGBcXCB1MDAwQWAgKSwgYW5kIGNhcnJpYWdlIHJldHVybiAoIGBcXCB1MDAwRGAgKVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW1hbmFnZWRwb2xpY3kuaHRtbCNjZm4taWFtLW1hbmFnZWRwb2xpY3ktcG9saWN5ZG9jdW1lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgcG9saWN5RG9jdW1lbnQ6IGFueSB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIEEgZnJpZW5kbHkgZGVzY3JpcHRpb24gb2YgdGhlIHBvbGljeS5cbiAgICAgKlxuICAgICAqIFR5cGljYWxseSB1c2VkIHRvIHN0b3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBwZXJtaXNzaW9ucyBkZWZpbmVkIGluIHRoZSBwb2xpY3kuIEZvciBleGFtcGxlLCBcIkdyYW50cyBhY2Nlc3MgdG8gcHJvZHVjdGlvbiBEeW5hbW9EQiB0YWJsZXMuXCJcbiAgICAgKlxuICAgICAqIFRoZSBwb2xpY3kgZGVzY3JpcHRpb24gaXMgaW1tdXRhYmxlLiBBZnRlciBhIHZhbHVlIGlzIGFzc2lnbmVkLCBpdCBjYW5ub3QgYmUgY2hhbmdlZC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1tYW5hZ2VkcG9saWN5Lmh0bWwjY2ZuLWlhbS1tYW5hZ2VkcG9saWN5LWRlc2NyaXB0aW9uXG4gICAgICovXG4gICAgcHVibGljIGRlc2NyaXB0aW9uOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSAoZnJpZW5kbHkgbmFtZSwgbm90IEFSTikgb2YgdGhlIGdyb3VwIHRvIGF0dGFjaCB0aGUgcG9saWN5IHRvLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1tYW5hZ2VkcG9saWN5Lmh0bWwjY2ZuLWlhbS1tYW5hZ2VkcG9saWN5LWdyb3Vwc1xuICAgICAqL1xuICAgIHB1YmxpYyBncm91cHM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGZyaWVuZGx5IG5hbWUgb2YgdGhlIHBvbGljeS5cbiAgICAgKlxuICAgICAqID4gSWYgeW91IHNwZWNpZnkgYSBuYW1lLCB5b3UgY2Fubm90IHBlcmZvcm0gdXBkYXRlcyB0aGF0IHJlcXVpcmUgcmVwbGFjZW1lbnQgb2YgdGhpcyByZXNvdXJjZS4gWW91IGNhbiBwZXJmb3JtIHVwZGF0ZXMgdGhhdCByZXF1aXJlIG5vIG9yIHNvbWUgaW50ZXJydXB0aW9uLiBJZiB5b3UgbXVzdCByZXBsYWNlIHRoZSByZXNvdXJjZSwgc3BlY2lmeSBhIG5ldyBuYW1lLlxuICAgICAqXG4gICAgICogSWYgeW91IHNwZWNpZnkgYSBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBgQ0FQQUJJTElUWV9OQU1FRF9JQU1gIHZhbHVlIHRvIGFja25vd2xlZGdlIHlvdXIgdGVtcGxhdGUncyBjYXBhYmlsaXRpZXMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0Fja25vd2xlZGdpbmcgSUFNIFJlc291cmNlcyBpbiBBV1MgQ2xvdWRGb3JtYXRpb24gVGVtcGxhdGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS91c2luZy1pYW0tdGVtcGxhdGUuaHRtbCN1c2luZy1pYW0tY2FwYWJpbGl0aWVzKSAuXG4gICAgICpcbiAgICAgKiA+IE5hbWluZyBhbiBJQU0gcmVzb3VyY2UgY2FuIGNhdXNlIGFuIHVucmVjb3ZlcmFibGUgZXJyb3IgaWYgeW91IHJldXNlIHRoZSBzYW1lIHRlbXBsYXRlIGluIG11bHRpcGxlIFJlZ2lvbnMuIFRvIHByZXZlbnQgdGhpcywgd2UgcmVjb21tZW5kIHVzaW5nIGBGbjo6Sm9pbmAgYW5kIGBBV1M6OlJlZ2lvbmAgdG8gY3JlYXRlIGEgUmVnaW9uLXNwZWNpZmljIG5hbWUsIGFzIGluIHRoZSBmb2xsb3dpbmcgZXhhbXBsZTogYHtcIkZuOjpKb2luXCI6IFtcIlwiLCBbe1wiUmVmXCI6IFwiQVdTOjpSZWdpb25cIn0sIHtcIlJlZlwiOiBcIk15UmVzb3VyY2VOYW1lXCJ9XV19YCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tbWFuYWdlZHBvbGljeS5odG1sI2Nmbi1pYW0tbWFuYWdlZHBvbGljeS1tYW5hZ2VkcG9saWN5bmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyBtYW5hZ2VkUG9saWN5TmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBhdGggZm9yIHRoZSBwb2xpY3kuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gaWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiBlaXRoZXIgYSBmb3J3YXJkIHNsYXNoICgvKSBieSBpdHNlbGYgb3IgYSBzdHJpbmcgdGhhdCBtdXN0IGJlZ2luIGFuZCBlbmQgd2l0aCBmb3J3YXJkIHNsYXNoZXMuIEluIGFkZGl0aW9uLCBpdCBjYW4gY29udGFpbiBhbnkgQVNDSUkgY2hhcmFjdGVyIGZyb20gdGhlICEgKCBgXFwgdTAwMjFgICkgdGhyb3VnaCB0aGUgREVMIGNoYXJhY3RlciAoIGBcXCB1MDA3RmAgKSwgaW5jbHVkaW5nIG1vc3QgcHVuY3R1YXRpb24gY2hhcmFjdGVycywgZGlnaXRzLCBhbmQgdXBwZXIgYW5kIGxvd2VyY2FzZWQgbGV0dGVycy5cbiAgICAgKlxuICAgICAqID4gWW91IGNhbm5vdCB1c2UgYW4gYXN0ZXJpc2sgKCopIGluIHRoZSBwYXRoIG5hbWUuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tbWFuYWdlZHBvbGljeS5odG1sI2Nmbi1lYzItZGhjcG9wdGlvbnMtcGF0aFxuICAgICAqL1xuICAgIHB1YmxpYyBwYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSAoZnJpZW5kbHkgbmFtZSwgbm90IEFSTikgb2YgdGhlIHJvbGUgdG8gYXR0YWNoIHRoZSBwb2xpY3kgdG8uXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHBlciBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiA+IElmIGFuIGV4dGVybmFsIHBvbGljeSAoc3VjaCBhcyBgQVdTOjpJQU06OlBvbGljeWAgb3IgYEFXUzo6SUFNOjpNYW5hZ2VkUG9saWN5YCApIGhhcyBhIGBSZWZgIHRvIGEgcm9sZSBhbmQgaWYgYSByZXNvdXJjZSAoc3VjaCBhcyBgQVdTOjpFQ1M6OlNlcnZpY2VgICkgYWxzbyBoYXMgYSBgUmVmYCB0byB0aGUgc2FtZSByb2xlLCBhZGQgYSBgRGVwZW5kc09uYCBhdHRyaWJ1dGUgdG8gdGhlIHJlc291cmNlIHRvIG1ha2UgdGhlIHJlc291cmNlIGRlcGVuZCBvbiB0aGUgZXh0ZXJuYWwgcG9saWN5LiBUaGlzIGRlcGVuZGVuY3kgZW5zdXJlcyB0aGF0IHRoZSByb2xlJ3MgcG9saWN5IGlzIGF2YWlsYWJsZSB0aHJvdWdob3V0IHRoZSByZXNvdXJjZSdzIGxpZmVjeWNsZS4gRm9yIGV4YW1wbGUsIHdoZW4geW91IGRlbGV0ZSBhIHN0YWNrIHdpdGggYW4gYEFXUzo6RUNTOjpTZXJ2aWNlYCByZXNvdXJjZSwgdGhlIGBEZXBlbmRzT25gIGF0dHJpYnV0ZSBlbnN1cmVzIHRoYXQgQVdTIENsb3VkRm9ybWF0aW9uIGRlbGV0ZXMgdGhlIGBBV1M6OkVDUzo6U2VydmljZWAgcmVzb3VyY2UgYmVmb3JlIGRlbGV0aW5nIGl0cyByb2xlJ3MgcG9saWN5LlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW1hbmFnZWRwb2xpY3kuaHRtbCNjZm4taWFtLW1hbmFnZWRwb2xpY3ktcm9sZXNcbiAgICAgKi9cbiAgICBwdWJsaWMgcm9sZXM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgKGZyaWVuZGx5IG5hbWUsIG5vdCBBUk4pIG9mIHRoZSBJQU0gdXNlciB0byBhdHRhY2ggdGhlIHBvbGljeSB0by5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tbWFuYWdlZHBvbGljeS5odG1sI2Nmbi1pYW0tbWFuYWdlZHBvbGljeS11c2Vyc1xuICAgICAqL1xuICAgIHB1YmxpYyB1c2Vyczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6SUFNOjpNYW5hZ2VkUG9saWN5YC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5NYW5hZ2VkUG9saWN5UHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmbk1hbmFnZWRQb2xpY3kuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICdwb2xpY3lEb2N1bWVudCcsIHRoaXMpO1xuXG4gICAgICAgIHRoaXMucG9saWN5RG9jdW1lbnQgPSBwcm9wcy5wb2xpY3lEb2N1bWVudDtcbiAgICAgICAgdGhpcy5kZXNjcmlwdGlvbiA9IHByb3BzLmRlc2NyaXB0aW9uO1xuICAgICAgICB0aGlzLmdyb3VwcyA9IHByb3BzLmdyb3VwcztcbiAgICAgICAgdGhpcy5tYW5hZ2VkUG9saWN5TmFtZSA9IHByb3BzLm1hbmFnZWRQb2xpY3lOYW1lO1xuICAgICAgICB0aGlzLnBhdGggPSBwcm9wcy5wYXRoO1xuICAgICAgICB0aGlzLnJvbGVzID0gcHJvcHMucm9sZXM7XG4gICAgICAgIHRoaXMudXNlcnMgPSBwcm9wcy51c2VycztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmbk1hbmFnZWRQb2xpY3kuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHBvbGljeURvY3VtZW50OiB0aGlzLnBvbGljeURvY3VtZW50LFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHRoaXMuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBncm91cHM6IHRoaXMuZ3JvdXBzLFxuICAgICAgICAgICAgbWFuYWdlZFBvbGljeU5hbWU6IHRoaXMubWFuYWdlZFBvbGljeU5hbWUsXG4gICAgICAgICAgICBwYXRoOiB0aGlzLnBhdGgsXG4gICAgICAgICAgICByb2xlczogdGhpcy5yb2xlcyxcbiAgICAgICAgICAgIHVzZXJzOiB0aGlzLnVzZXJzLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmbk1hbmFnZWRQb2xpY3lQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5PSURDUHJvdmlkZXJgXG4gKlxuICogQHN0cnVjdFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1vaWRjcHJvdmlkZXIuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmbk9JRENQcm92aWRlclByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiBjZXJ0aWZpY2F0ZSB0aHVtYnByaW50cyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBJQU0gT0lEQyBwcm92aWRlciByZXNvdXJjZSBvYmplY3QuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0NyZWF0ZU9wZW5JRENvbm5lY3RQcm92aWRlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVPcGVuSURDb25uZWN0UHJvdmlkZXIuaHRtbCkgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW9pZGNwcm92aWRlci5odG1sI2Nmbi1pYW0tb2lkY3Byb3ZpZGVyLXRodW1icHJpbnRsaXN0XG4gICAgICovXG4gICAgcmVhZG9ubHkgdGh1bWJwcmludExpc3Q6IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIGNsaWVudCBJRHMgKGFsc28ga25vd24gYXMgYXVkaWVuY2VzKSB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBJQU0gT0lEQyBwcm92aWRlciByZXNvdXJjZSBvYmplY3QuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0NyZWF0ZU9wZW5JRENvbm5lY3RQcm92aWRlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVPcGVuSURDb25uZWN0UHJvdmlkZXIuaHRtbCkgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW9pZGNwcm92aWRlci5odG1sI2Nmbi1pYW0tb2lkY3Byb3ZpZGVyLWNsaWVudGlkbGlzdFxuICAgICAqL1xuICAgIHJlYWRvbmx5IGNsaWVudElkTGlzdD86IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIHRhZ3MgdGhhdCBhcmUgYXR0YWNoZWQgdG8gdGhlIHNwZWNpZmllZCBJQU0gT0lEQyBwcm92aWRlci4gVGhlIHJldHVybmVkIGxpc3Qgb2YgdGFncyBpcyBzb3J0ZWQgYnkgdGFnIGtleS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGFnZ2luZywgc2VlIFtUYWdnaW5nIElBTSByZXNvdXJjZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF90YWdzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1vaWRjcHJvdmlkZXIuaHRtbCNjZm4taWFtLW9pZGNwcm92aWRlci10YWdzXG4gICAgICovXG4gICAgcmVhZG9ubHkgdGFncz86IGNkay5DZm5UYWdbXTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBVUkwgdGhhdCB0aGUgSUFNIE9JREMgcHJvdmlkZXIgcmVzb3VyY2Ugb2JqZWN0IGlzIGFzc29jaWF0ZWQgd2l0aC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQ3JlYXRlT3BlbklEQ29ubmVjdFByb3ZpZGVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZU9wZW5JRENvbm5lY3RQcm92aWRlci5odG1sKSAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tb2lkY3Byb3ZpZGVyLmh0bWwjY2ZuLWlhbS1vaWRjcHJvdmlkZXItdXJsXG4gICAgICovXG4gICAgcmVhZG9ubHkgdXJsPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmbk9JRENQcm92aWRlclByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5PSURDUHJvdmlkZXJQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5PSURDUHJvdmlkZXJQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2NsaWVudElkTGlzdCcsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMuY2xpZW50SWRMaXN0KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0YWdzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlQ2ZuVGFnKSkocHJvcGVydGllcy50YWdzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0aHVtYnByaW50TGlzdCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy50aHVtYnByaW50TGlzdCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndGh1bWJwcmludExpc3QnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLnRodW1icHJpbnRMaXN0KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd1cmwnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMudXJsKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmbk9JRENQcm92aWRlclByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06Ok9JRENQcm92aWRlcmAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuT0lEQ1Byb3ZpZGVyUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6T0lEQ1Byb3ZpZGVyYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmbk9JRENQcm92aWRlclByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5PSURDUHJvdmlkZXJQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgVGh1bWJwcmludExpc3Q6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnRodW1icHJpbnRMaXN0KSxcbiAgICAgICAgQ2xpZW50SWRMaXN0OiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5jbGllbnRJZExpc3QpLFxuICAgICAgICBUYWdzOiBjZGsubGlzdE1hcHBlcihjZGsuY2ZuVGFnVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy50YWdzKSxcbiAgICAgICAgVXJsOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnVybCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmbk9JRENQcm92aWRlclByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuT0lEQ1Byb3ZpZGVyUHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmbk9JRENQcm92aWRlclByb3BzPigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndGh1bWJwcmludExpc3QnLCAnVGh1bWJwcmludExpc3QnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuVGh1bWJwcmludExpc3QpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2NsaWVudElkTGlzdCcsICdDbGllbnRJZExpc3QnLCBwcm9wZXJ0aWVzLkNsaWVudElkTGlzdCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmdBcnJheShwcm9wZXJ0aWVzLkNsaWVudElkTGlzdCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndGFncycsICdUYWdzJywgcHJvcGVydGllcy5UYWdzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Q2ZuVGFnKShwcm9wZXJ0aWVzLlRhZ3MpIDogdW5kZWZpbmVkIGFzIGFueSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd1cmwnLCAnVXJsJywgcHJvcGVydGllcy5VcmwgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVXJsKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpJQU06Ok9JRENQcm92aWRlcmBcbiAqXG4gKiBDcmVhdGVzIG9yIHVwZGF0ZXMgYW4gSUFNIGVudGl0eSB0byBkZXNjcmliZSBhbiBpZGVudGl0eSBwcm92aWRlciAoSWRQKSB0aGF0IHN1cHBvcnRzIFtPcGVuSUQgQ29ubmVjdCAoT0lEQyldKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vb3BlbmlkLm5ldC9jb25uZWN0LykgLlxuICpcbiAqIFRoZSBPSURDIHByb3ZpZGVyIHRoYXQgeW91IGNyZWF0ZSB3aXRoIHRoaXMgb3BlcmF0aW9uIGNhbiBiZSB1c2VkIGFzIGEgcHJpbmNpcGFsIGluIGEgcm9sZSdzIHRydXN0IHBvbGljeS4gU3VjaCBhIHBvbGljeSBlc3RhYmxpc2hlcyBhIHRydXN0IHJlbGF0aW9uc2hpcCBiZXR3ZWVuIEFXUyBhbmQgdGhlIE9JREMgcHJvdmlkZXIuXG4gKlxuICogV2hlbiB5b3UgY3JlYXRlIHRoZSBJQU0gT0lEQyBwcm92aWRlciwgeW91IHNwZWNpZnkgdGhlIGZvbGxvd2luZzpcbiAqXG4gKiAtIFRoZSBVUkwgb2YgdGhlIE9JREMgaWRlbnRpdHkgcHJvdmlkZXIgKElkUCkgdG8gdHJ1c3RcbiAqIC0gQSBsaXN0IG9mIGNsaWVudCBJRHMgKGFsc28ga25vd24gYXMgYXVkaWVuY2VzKSB0aGF0IGlkZW50aWZ5IHRoZSBhcHBsaWNhdGlvbiBvciBhcHBsaWNhdGlvbnMgdGhhdCBhcmUgYWxsb3dlZCB0byBhdXRoZW50aWNhdGUgdXNpbmcgdGhlIE9JREMgcHJvdmlkZXJcbiAqIC0gQSBsaXN0IG9mIHRhZ3MgdGhhdCBhcmUgYXR0YWNoZWQgdG8gdGhlIHNwZWNpZmllZCBJQU0gT0lEQyBwcm92aWRlclxuICogLSBBIGxpc3Qgb2YgdGh1bWJwcmludHMgb2Ygb25lIG9yIG1vcmUgc2VydmVyIGNlcnRpZmljYXRlcyB0aGF0IHRoZSBJZFAgdXNlc1xuICpcbiAqIFlvdSBnZXQgYWxsIG9mIHRoaXMgaW5mb3JtYXRpb24gZnJvbSB0aGUgT0lEQyBJZFAgdGhhdCB5b3Ugd2FudCB0byB1c2UgdG8gYWNjZXNzIEFXUyAuXG4gKlxuICogV2hlbiB5b3UgdXBkYXRlIHRoZSBJQU0gT0lEQyBwcm92aWRlciwgeW91IHNwZWNpZnkgdGhlIGZvbGxvd2luZzpcbiAqXG4gKiAtIFRoZSBVUkwgb2YgdGhlIE9JREMgaWRlbnRpdHkgcHJvdmlkZXIgKElkUCkgdG8gdHJ1c3RcbiAqIC0gQSBsaXN0IG9mIGNsaWVudCBJRHMgKGFsc28ga25vd24gYXMgYXVkaWVuY2VzKSB0aGF0IHJlcGxhY2VzIHRoZSBleGlzdGluZyBsaXN0IG9mIGNsaWVudCBJRHMgYXNzb2NpYXRlZCB3aXRoIHRoZSBPSURDIElkUFxuICogLSBBIGxpc3Qgb2YgdGFncyB0aGF0IHJlcGxhY2VzIHRoZSBleGlzdGluZyBsaXN0IG9mIHRhZ3MgYXR0YWNoZWQgdG8gdGhlIHNwZWNpZmllZCBJQU0gT0lEQyBwcm92aWRlclxuICogLSBBIGxpc3Qgb2YgdGh1bWJwcmludHMgdGhhdCByZXBsYWNlcyB0aGUgZXhpc3RpbmcgbGlzdCBvZiBzZXJ2ZXIgY2VydGlmaWNhdGVzIHRodW1icHJpbnRzIHRoYXQgdGhlIElkUCB1c2VzXG4gKlxuICogPiBUaGUgdHJ1c3QgZm9yIHRoZSBPSURDIHByb3ZpZGVyIGlzIGRlcml2ZWQgZnJvbSB0aGUgSUFNIHByb3ZpZGVyIHRoYXQgdGhpcyBvcGVyYXRpb24gY3JlYXRlcy4gVGhlcmVmb3JlLCBpdCBpcyBiZXN0IHRvIGxpbWl0IGFjY2VzcyB0byB0aGUgW0NyZWF0ZU9wZW5JRENvbm5lY3RQcm92aWRlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVPcGVuSURDb25uZWN0UHJvdmlkZXIuaHRtbCkgb3BlcmF0aW9uIHRvIGhpZ2hseSBwcml2aWxlZ2VkIHVzZXJzLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6SUFNOjpPSURDUHJvdmlkZXJcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tb2lkY3Byb3ZpZGVyLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmbk9JRENQcm92aWRlciBleHRlbmRzIGNkay5DZm5SZXNvdXJjZSBpbXBsZW1lbnRzIGNkay5JSW5zcGVjdGFibGUge1xuICAgIC8qKlxuICAgICAqIFRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIG5hbWUgZm9yIHRoaXMgcmVzb3VyY2UgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBDRk5fUkVTT1VSQ0VfVFlQRV9OQU1FID0gXCJBV1M6OklBTTo6T0lEQ1Byb3ZpZGVyXCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5PSURDUHJvdmlkZXIge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmbk9JRENQcm92aWRlclByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5PSURDUHJvdmlkZXIoc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgZm9yIHRoZSBzcGVjaWZpZWQgYEFXUzo6SUFNOjpPSURDUHJvdmlkZXJgIHJlc291cmNlLlxuICAgICAqIEBjbG91ZGZvcm1hdGlvbkF0dHJpYnV0ZSBBcm5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgYXR0ckFybjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIGNlcnRpZmljYXRlIHRodW1icHJpbnRzIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIElBTSBPSURDIHByb3ZpZGVyIHJlc291cmNlIG9iamVjdC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQ3JlYXRlT3BlbklEQ29ubmVjdFByb3ZpZGVyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZU9wZW5JRENvbm5lY3RQcm92aWRlci5odG1sKSAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tb2lkY3Byb3ZpZGVyLmh0bWwjY2ZuLWlhbS1vaWRjcHJvdmlkZXItdGh1bWJwcmludGxpc3RcbiAgICAgKi9cbiAgICBwdWJsaWMgdGh1bWJwcmludExpc3Q6IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIGNsaWVudCBJRHMgKGFsc28ga25vd24gYXMgYXVkaWVuY2VzKSB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBJQU0gT0lEQyBwcm92aWRlciByZXNvdXJjZSBvYmplY3QuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0NyZWF0ZU9wZW5JRENvbm5lY3RQcm92aWRlcl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVPcGVuSURDb25uZWN0UHJvdmlkZXIuaHRtbCkgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLW9pZGNwcm92aWRlci5odG1sI2Nmbi1pYW0tb2lkY3Byb3ZpZGVyLWNsaWVudGlkbGlzdFxuICAgICAqL1xuICAgIHB1YmxpYyBjbGllbnRJZExpc3Q6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIHRhZ3MgdGhhdCBhcmUgYXR0YWNoZWQgdG8gdGhlIHNwZWNpZmllZCBJQU0gT0lEQyBwcm92aWRlci4gVGhlIHJldHVybmVkIGxpc3Qgb2YgdGFncyBpcyBzb3J0ZWQgYnkgdGFnIGtleS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGFnZ2luZywgc2VlIFtUYWdnaW5nIElBTSByZXNvdXJjZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF90YWdzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1vaWRjcHJvdmlkZXIuaHRtbCNjZm4taWFtLW9pZGNwcm92aWRlci10YWdzXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHRhZ3M6IGNkay5UYWdNYW5hZ2VyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIFVSTCB0aGF0IHRoZSBJQU0gT0lEQyBwcm92aWRlciByZXNvdXJjZSBvYmplY3QgaXMgYXNzb2NpYXRlZCB3aXRoLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtDcmVhdGVPcGVuSURDb25uZWN0UHJvdmlkZXJdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlT3BlbklEQ29ubmVjdFByb3ZpZGVyLmh0bWwpIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1vaWRjcHJvdmlkZXIuaHRtbCNjZm4taWFtLW9pZGNwcm92aWRlci11cmxcbiAgICAgKi9cbiAgICBwdWJsaWMgdXJsOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6SUFNOjpPSURDUHJvdmlkZXJgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmbk9JRENQcm92aWRlclByb3BzKSB7XG4gICAgICAgIHN1cGVyKHNjb3BlLCBpZCwgeyB0eXBlOiBDZm5PSURDUHJvdmlkZXIuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICd0aHVtYnByaW50TGlzdCcsIHRoaXMpO1xuICAgICAgICB0aGlzLmF0dHJBcm4gPSBjZGsuVG9rZW4uYXNTdHJpbmcodGhpcy5nZXRBdHQoJ0FybicpKTtcblxuICAgICAgICB0aGlzLnRodW1icHJpbnRMaXN0ID0gcHJvcHMudGh1bWJwcmludExpc3Q7XG4gICAgICAgIHRoaXMuY2xpZW50SWRMaXN0ID0gcHJvcHMuY2xpZW50SWRMaXN0O1xuICAgICAgICB0aGlzLnRhZ3MgPSBuZXcgY2RrLlRhZ01hbmFnZXIoY2RrLlRhZ1R5cGUuU1RBTkRBUkQsIFwiQVdTOjpJQU06Ok9JRENQcm92aWRlclwiLCBwcm9wcy50YWdzLCB7IHRhZ1Byb3BlcnR5TmFtZTogJ3RhZ3MnIH0pO1xuICAgICAgICB0aGlzLnVybCA9IHByb3BzLnVybDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmbk9JRENQcm92aWRlci5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGh1bWJwcmludExpc3Q6IHRoaXMudGh1bWJwcmludExpc3QsXG4gICAgICAgICAgICBjbGllbnRJZExpc3Q6IHRoaXMuY2xpZW50SWRMaXN0LFxuICAgICAgICAgICAgdGFnczogdGhpcy50YWdzLnJlbmRlclRhZ3MoKSxcbiAgICAgICAgICAgIHVybDogdGhpcy51cmwsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuT0lEQ1Byb3ZpZGVyUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYSBgQ2ZuUG9saWN5YFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcG9saWN5Lmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5Qb2xpY3lQcm9wcyB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcG9saWN5IGRvY3VtZW50LlxuICAgICAqXG4gICAgICogWW91IG11c3QgcHJvdmlkZSBwb2xpY2llcyBpbiBKU09OIGZvcm1hdCBpbiBJQU0uIEhvd2V2ZXIsIGZvciBBV1MgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGVzIGZvcm1hdHRlZCBpbiBZQU1MLCB5b3UgY2FuIHByb3ZpZGUgdGhlIHBvbGljeSBpbiBKU09OIG9yIFlBTUwgZm9ybWF0LiBBV1MgQ2xvdWRGb3JtYXRpb24gYWx3YXlzIGNvbnZlcnRzIGEgWUFNTCBwb2xpY3kgdG8gSlNPTiBmb3JtYXQgYmVmb3JlIHN1Ym1pdHRpbmcgaXQgdG8gSUFNLlxuICAgICAqXG4gICAgICogVGhlIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgdXNlZCB0byB2YWxpZGF0ZSB0aGlzIHBhcmFtZXRlciBpcyBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gQW55IHByaW50YWJsZSBBU0NJSSBjaGFyYWN0ZXIgcmFuZ2luZyBmcm9tIHRoZSBzcGFjZSBjaGFyYWN0ZXIgKCBgXFwgdTAwMjBgICkgdGhyb3VnaCB0aGUgZW5kIG9mIHRoZSBBU0NJSSBjaGFyYWN0ZXIgcmFuZ2VcbiAgICAgKiAtIFRoZSBwcmludGFibGUgY2hhcmFjdGVycyBpbiB0aGUgQmFzaWMgTGF0aW4gYW5kIExhdGluLTEgU3VwcGxlbWVudCBjaGFyYWN0ZXIgc2V0ICh0aHJvdWdoIGBcXCB1MDBGRmAgKVxuICAgICAqIC0gVGhlIHNwZWNpYWwgY2hhcmFjdGVycyB0YWIgKCBgXFwgdTAwMDlgICksIGxpbmUgZmVlZCAoIGBcXCB1MDAwQWAgKSwgYW5kIGNhcnJpYWdlIHJldHVybiAoIGBcXCB1MDAwRGAgKVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXBvbGljeS5odG1sI2Nmbi1pYW0tcG9saWN5LXBvbGljeWRvY3VtZW50XG4gICAgICovXG4gICAgcmVhZG9ubHkgcG9saWN5RG9jdW1lbnQ6IGFueSB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBwb2xpY3kgZG9jdW1lbnQuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdXBwZXIgYW5kIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyB3aXRoIG5vIHNwYWNlcy4gWW91IGNhbiBhbHNvIGluY2x1ZGUgYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogXys9LC5ALVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXBvbGljeS5odG1sI2Nmbi1pYW0tcG9saWN5LXBvbGljeW5hbWVcbiAgICAgKi9cbiAgICByZWFkb25seSBwb2xpY3lOYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgZ3JvdXAgdG8gYXNzb2NpYXRlIHRoZSBwb2xpY3kgd2l0aC5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXBvbGljeS5odG1sI2Nmbi1pYW0tcG9saWN5LWdyb3Vwc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IGdyb3Vwcz86IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHJvbGUgdG8gYXNzb2NpYXRlIHRoZSBwb2xpY3kgd2l0aC5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAocGVyIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqID4gSWYgYW4gZXh0ZXJuYWwgcG9saWN5IChzdWNoIGFzIGBBV1M6OklBTTo6UG9saWN5YCBvciBgQVdTOjpJQU06Ok1hbmFnZWRQb2xpY3lgICkgaGFzIGEgYFJlZmAgdG8gYSByb2xlIGFuZCBpZiBhIHJlc291cmNlIChzdWNoIGFzIGBBV1M6OkVDUzo6U2VydmljZWAgKSBhbHNvIGhhcyBhIGBSZWZgIHRvIHRoZSBzYW1lIHJvbGUsIGFkZCBhIGBEZXBlbmRzT25gIGF0dHJpYnV0ZSB0byB0aGUgcmVzb3VyY2UgdG8gbWFrZSB0aGUgcmVzb3VyY2UgZGVwZW5kIG9uIHRoZSBleHRlcm5hbCBwb2xpY3kuIFRoaXMgZGVwZW5kZW5jeSBlbnN1cmVzIHRoYXQgdGhlIHJvbGUncyBwb2xpY3kgaXMgYXZhaWxhYmxlIHRocm91Z2hvdXQgdGhlIHJlc291cmNlJ3MgbGlmZWN5Y2xlLiBGb3IgZXhhbXBsZSwgd2hlbiB5b3UgZGVsZXRlIGEgc3RhY2sgd2l0aCBhbiBgQVdTOjpFQ1M6OlNlcnZpY2VgIHJlc291cmNlLCB0aGUgYERlcGVuZHNPbmAgYXR0cmlidXRlIGVuc3VyZXMgdGhhdCBBV1MgQ2xvdWRGb3JtYXRpb24gZGVsZXRlcyB0aGUgYEFXUzo6RUNTOjpTZXJ2aWNlYCByZXNvdXJjZSBiZWZvcmUgZGVsZXRpbmcgaXRzIHJvbGUncyBwb2xpY3kuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcG9saWN5Lmh0bWwjY2ZuLWlhbS1wb2xpY3ktcm9sZXNcbiAgICAgKi9cbiAgICByZWFkb25seSByb2xlcz86IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHVzZXIgdG8gYXNzb2NpYXRlIHRoZSBwb2xpY3kgd2l0aC5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcG9saWN5Lmh0bWwjY2ZuLWlhbS1wb2xpY3ktdXNlcnNcbiAgICAgKi9cbiAgICByZWFkb25seSB1c2Vycz86IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmblBvbGljeVByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5Qb2xpY3lQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5Qb2xpY3lQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2dyb3VwcycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMuZ3JvdXBzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb2xpY3lEb2N1bWVudCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5wb2xpY3lEb2N1bWVudCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5RG9jdW1lbnQnLCBjZGsudmFsaWRhdGVPYmplY3QpKHByb3BlcnRpZXMucG9saWN5RG9jdW1lbnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvbGljeU5hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMucG9saWN5TmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5TmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5wb2xpY3lOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdyb2xlcycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMucm9sZXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3VzZXJzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy51c2VycykpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5Qb2xpY3lQcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpQb2xpY3lgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblBvbGljeVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlBvbGljeWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5Qb2xpY3lQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuUG9saWN5UHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFBvbGljeURvY3VtZW50OiBjZGsub2JqZWN0VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBvbGljeURvY3VtZW50KSxcbiAgICAgICAgUG9saWN5TmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wb2xpY3lOYW1lKSxcbiAgICAgICAgR3JvdXBzOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5ncm91cHMpLFxuICAgICAgICBSb2xlczogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMucm9sZXMpLFxuICAgICAgICBVc2VyczogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMudXNlcnMpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5Qb2xpY3lQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblBvbGljeVByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5Qb2xpY3lQcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BvbGljeURvY3VtZW50JywgJ1BvbGljeURvY3VtZW50JywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBbnkocHJvcGVydGllcy5Qb2xpY3lEb2N1bWVudCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncG9saWN5TmFtZScsICdQb2xpY3lOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Qb2xpY3lOYW1lKSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdncm91cHMnLCAnR3JvdXBzJywgcHJvcGVydGllcy5Hcm91cHMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5Hcm91cHMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3JvbGVzJywgJ1JvbGVzJywgcHJvcGVydGllcy5Sb2xlcyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmdBcnJheShwcm9wZXJ0aWVzLlJvbGVzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd1c2VycycsICdVc2VycycsIHByb3BlcnRpZXMuVXNlcnMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5Vc2VycykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6SUFNOjpQb2xpY3lgXG4gKlxuICogQWRkcyBvciB1cGRhdGVzIGFuIGlubGluZSBwb2xpY3kgZG9jdW1lbnQgdGhhdCBpcyBlbWJlZGRlZCBpbiB0aGUgc3BlY2lmaWVkIElBTSB1c2VyLCBncm91cCwgb3Igcm9sZS5cbiAqXG4gKiBBbiBJQU0gdXNlciBjYW4gYWxzbyBoYXZlIGEgbWFuYWdlZCBwb2xpY3kgYXR0YWNoZWQgdG8gaXQuIEZvciBpbmZvcm1hdGlvbiBhYm91dCBwb2xpY2llcywgc2VlIFtNYW5hZ2VkIFBvbGljaWVzIGFuZCBJbmxpbmUgUG9saWNpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9wb2xpY2llcy1tYW5hZ2VkLXZzLWlubGluZS5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gKlxuICogVGhlIEdyb3VwcywgUm9sZXMsIGFuZCBVc2VycyBwcm9wZXJ0aWVzIGFyZSBvcHRpb25hbC4gSG93ZXZlciwgeW91IG11c3Qgc3BlY2lmeSBhdCBsZWFzdCBvbmUgb2YgdGhlc2UgcHJvcGVydGllcy5cbiAqXG4gKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgcG9saWN5IGRvY3VtZW50cyBzZWUgW0NyZWF0aW5nIElBTSBwb2xpY2llc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2FjY2Vzc19wb2xpY2llc19jcmVhdGUuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICpcbiAqIEZvciBpbmZvcm1hdGlvbiBhYm91dCBsaW1pdHMgb24gdGhlIG51bWJlciBvZiBpbmxpbmUgcG9saWNpZXMgdGhhdCB5b3UgY2FuIGVtYmVkIGluIGFuIGlkZW50aXR5LCBzZWUgW0xpbWl0YXRpb25zIG9uIElBTSBFbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL0xpbWl0YXRpb25zT25FbnRpdGllcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpJQU06OlBvbGljeVxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1wb2xpY3kuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQ2ZuUG9saWN5IGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6SUFNOjpQb2xpY3lcIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmblBvbGljeSB7XG4gICAgICAgIHJlc291cmNlQXR0cmlidXRlcyA9IHJlc291cmNlQXR0cmlidXRlcyB8fCB7fTtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VQcm9wZXJ0aWVzID0gb3B0aW9ucy5wYXJzZXIucGFyc2VWYWx1ZShyZXNvdXJjZUF0dHJpYnV0ZXMuUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHByb3BzUmVzdWx0ID0gQ2ZuUG9saWN5UHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmblBvbGljeShzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcG9saWN5IGRvY3VtZW50LlxuICAgICAqXG4gICAgICogWW91IG11c3QgcHJvdmlkZSBwb2xpY2llcyBpbiBKU09OIGZvcm1hdCBpbiBJQU0uIEhvd2V2ZXIsIGZvciBBV1MgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGVzIGZvcm1hdHRlZCBpbiBZQU1MLCB5b3UgY2FuIHByb3ZpZGUgdGhlIHBvbGljeSBpbiBKU09OIG9yIFlBTUwgZm9ybWF0LiBBV1MgQ2xvdWRGb3JtYXRpb24gYWx3YXlzIGNvbnZlcnRzIGEgWUFNTCBwb2xpY3kgdG8gSlNPTiBmb3JtYXQgYmVmb3JlIHN1Ym1pdHRpbmcgaXQgdG8gSUFNLlxuICAgICAqXG4gICAgICogVGhlIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgdXNlZCB0byB2YWxpZGF0ZSB0aGlzIHBhcmFtZXRlciBpcyBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdGhlIGZvbGxvd2luZzpcbiAgICAgKlxuICAgICAqIC0gQW55IHByaW50YWJsZSBBU0NJSSBjaGFyYWN0ZXIgcmFuZ2luZyBmcm9tIHRoZSBzcGFjZSBjaGFyYWN0ZXIgKCBgXFwgdTAwMjBgICkgdGhyb3VnaCB0aGUgZW5kIG9mIHRoZSBBU0NJSSBjaGFyYWN0ZXIgcmFuZ2VcbiAgICAgKiAtIFRoZSBwcmludGFibGUgY2hhcmFjdGVycyBpbiB0aGUgQmFzaWMgTGF0aW4gYW5kIExhdGluLTEgU3VwcGxlbWVudCBjaGFyYWN0ZXIgc2V0ICh0aHJvdWdoIGBcXCB1MDBGRmAgKVxuICAgICAqIC0gVGhlIHNwZWNpYWwgY2hhcmFjdGVycyB0YWIgKCBgXFwgdTAwMDlgICksIGxpbmUgZmVlZCAoIGBcXCB1MDAwQWAgKSwgYW5kIGNhcnJpYWdlIHJldHVybiAoIGBcXCB1MDAwRGAgKVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXBvbGljeS5odG1sI2Nmbi1pYW0tcG9saWN5LXBvbGljeWRvY3VtZW50XG4gICAgICovXG4gICAgcHVibGljIHBvbGljeURvY3VtZW50OiBhbnkgfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcG9saWN5IGRvY3VtZW50LlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1wb2xpY3kuaHRtbCNjZm4taWFtLXBvbGljeS1wb2xpY3luYW1lXG4gICAgICovXG4gICAgcHVibGljIHBvbGljeU5hbWU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBncm91cCB0byBhc3NvY2lhdGUgdGhlIHBvbGljeSB3aXRoLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC0uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcG9saWN5Lmh0bWwjY2ZuLWlhbS1wb2xpY3ktZ3JvdXBzXG4gICAgICovXG4gICAgcHVibGljIGdyb3Vwczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcm9sZSB0byBhc3NvY2lhdGUgdGhlIHBvbGljeSB3aXRoLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzIChwZXIgaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdXBwZXIgYW5kIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyB3aXRoIG5vIHNwYWNlcy4gWW91IGNhbiBhbHNvIGluY2x1ZGUgYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogXys9LC5ALVxuICAgICAqXG4gICAgICogPiBJZiBhbiBleHRlcm5hbCBwb2xpY3kgKHN1Y2ggYXMgYEFXUzo6SUFNOjpQb2xpY3lgIG9yIGBBV1M6OklBTTo6TWFuYWdlZFBvbGljeWAgKSBoYXMgYSBgUmVmYCB0byBhIHJvbGUgYW5kIGlmIGEgcmVzb3VyY2UgKHN1Y2ggYXMgYEFXUzo6RUNTOjpTZXJ2aWNlYCApIGFsc28gaGFzIGEgYFJlZmAgdG8gdGhlIHNhbWUgcm9sZSwgYWRkIGEgYERlcGVuZHNPbmAgYXR0cmlidXRlIHRvIHRoZSByZXNvdXJjZSB0byBtYWtlIHRoZSByZXNvdXJjZSBkZXBlbmQgb24gdGhlIGV4dGVybmFsIHBvbGljeS4gVGhpcyBkZXBlbmRlbmN5IGVuc3VyZXMgdGhhdCB0aGUgcm9sZSdzIHBvbGljeSBpcyBhdmFpbGFibGUgdGhyb3VnaG91dCB0aGUgcmVzb3VyY2UncyBsaWZlY3ljbGUuIEZvciBleGFtcGxlLCB3aGVuIHlvdSBkZWxldGUgYSBzdGFjayB3aXRoIGFuIGBBV1M6OkVDUzo6U2VydmljZWAgcmVzb3VyY2UsIHRoZSBgRGVwZW5kc09uYCBhdHRyaWJ1dGUgZW5zdXJlcyB0aGF0IEFXUyBDbG91ZEZvcm1hdGlvbiBkZWxldGVzIHRoZSBgQVdTOjpFQ1M6OlNlcnZpY2VgIHJlc291cmNlIGJlZm9yZSBkZWxldGluZyBpdHMgcm9sZSdzIHBvbGljeS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1wb2xpY3kuaHRtbCNjZm4taWFtLXBvbGljeS1yb2xlc1xuICAgICAqL1xuICAgIHB1YmxpYyByb2xlczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgdXNlciB0byBhc3NvY2lhdGUgdGhlIHBvbGljeSB3aXRoLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1wb2xpY3kuaHRtbCNjZm4taWFtLXBvbGljeS11c2Vyc1xuICAgICAqL1xuICAgIHB1YmxpYyB1c2Vyczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6SUFNOjpQb2xpY3lgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmblBvbGljeVByb3BzKSB7XG4gICAgICAgIHN1cGVyKHNjb3BlLCBpZCwgeyB0eXBlOiBDZm5Qb2xpY3kuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICdwb2xpY3lEb2N1bWVudCcsIHRoaXMpO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAncG9saWN5TmFtZScsIHRoaXMpO1xuXG4gICAgICAgIHRoaXMucG9saWN5RG9jdW1lbnQgPSBwcm9wcy5wb2xpY3lEb2N1bWVudDtcbiAgICAgICAgdGhpcy5wb2xpY3lOYW1lID0gcHJvcHMucG9saWN5TmFtZTtcbiAgICAgICAgdGhpcy5ncm91cHMgPSBwcm9wcy5ncm91cHM7XG4gICAgICAgIHRoaXMucm9sZXMgPSBwcm9wcy5yb2xlcztcbiAgICAgICAgdGhpcy51c2VycyA9IHByb3BzLnVzZXJzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuUG9saWN5LkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwb2xpY3lEb2N1bWVudDogdGhpcy5wb2xpY3lEb2N1bWVudCxcbiAgICAgICAgICAgIHBvbGljeU5hbWU6IHRoaXMucG9saWN5TmFtZSxcbiAgICAgICAgICAgIGdyb3VwczogdGhpcy5ncm91cHMsXG4gICAgICAgICAgICByb2xlczogdGhpcy5yb2xlcyxcbiAgICAgICAgICAgIHVzZXJzOiB0aGlzLnVzZXJzLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmblBvbGljeVByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmblJvbGVgXG4gKlxuICogQHN0cnVjdFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5Sb2xlUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogVGhlIHRydXN0IHBvbGljeSB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHJvbGUuIFRydXN0IHBvbGljaWVzIGRlZmluZSB3aGljaCBlbnRpdGllcyBjYW4gYXNzdW1lIHRoZSByb2xlLiBZb3UgY2FuIGFzc29jaWF0ZSBvbmx5IG9uZSB0cnVzdCBwb2xpY3kgd2l0aCBhIHJvbGUuIEZvciBhbiBleGFtcGxlIG9mIGEgcG9saWN5IHRoYXQgY2FuIGJlIHVzZWQgdG8gYXNzdW1lIGEgcm9sZSwgc2VlIFtUZW1wbGF0ZSBFeGFtcGxlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWwjYXdzLXJlc291cmNlLWlhbS1yb2xlLS1leGFtcGxlcykgLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZWxlbWVudHMgdGhhdCB5b3UgY2FuIHVzZSBpbiBhbiBJQU0gcG9saWN5LCBzZWUgW0lBTSBQb2xpY3kgRWxlbWVudHMgUmVmZXJlbmNlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWwjY2ZuLWlhbS1yb2xlLWFzc3VtZXJvbGVwb2xpY3lkb2N1bWVudFxuICAgICAqL1xuICAgIHJlYWRvbmx5IGFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudDogYW55IHwgY2RrLklSZXNvbHZhYmxlO1xuXG4gICAgLyoqXG4gICAgICogQSBkZXNjcmlwdGlvbiBvZiB0aGUgcm9sZSB0aGF0IHlvdSBwcm92aWRlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNjZm4taWFtLXJvbGUtZGVzY3JpcHRpb25cbiAgICAgKi9cbiAgICByZWFkb25seSBkZXNjcmlwdGlvbj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiBBbWF6b24gUmVzb3VyY2UgTmFtZXMgKEFSTnMpIG9mIHRoZSBJQU0gbWFuYWdlZCBwb2xpY2llcyB0aGF0IHlvdSB3YW50IHRvIGF0dGFjaCB0byB0aGUgcm9sZS5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IEFSTnMsIHNlZSBbQW1hem9uIFJlc291cmNlIE5hbWVzIChBUk5zKSBhbmQgQVdTIFNlcnZpY2UgTmFtZXNwYWNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2dlbmVyYWwvbGF0ZXN0L2dyL2F3cy1hcm5zLWFuZC1uYW1lc3BhY2VzLmh0bWwpIGluIHRoZSAqQVdTIEdlbmVyYWwgUmVmZXJlbmNlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcm9sZS5odG1sI2Nmbi1pYW0tcm9sZS1tYW5hZ2Vwb2xpY3lhcm5zXG4gICAgICovXG4gICAgcmVhZG9ubHkgbWFuYWdlZFBvbGljeUFybnM/OiBzdHJpbmdbXTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIHNlc3Npb24gZHVyYXRpb24gKGluIHNlY29uZHMpIHRoYXQgeW91IHdhbnQgdG8gc2V0IGZvciB0aGUgc3BlY2lmaWVkIHJvbGUuIElmIHlvdSBkbyBub3Qgc3BlY2lmeSBhIHZhbHVlIGZvciB0aGlzIHNldHRpbmcsIHRoZSBkZWZhdWx0IHZhbHVlIG9mIG9uZSBob3VyIGlzIGFwcGxpZWQuIFRoaXMgc2V0dGluZyBjYW4gaGF2ZSBhIHZhbHVlIGZyb20gMSBob3VyIHRvIDEyIGhvdXJzLlxuICAgICAqXG4gICAgICogQW55b25lIHdobyBhc3N1bWVzIHRoZSByb2xlIGZyb20gdGhlIEFXUyBDTEkgb3IgQVBJIGNhbiB1c2UgdGhlIGBEdXJhdGlvblNlY29uZHNgIEFQSSBwYXJhbWV0ZXIgb3IgdGhlIGBkdXJhdGlvbi1zZWNvbmRzYCBBV1MgQ0xJIHBhcmFtZXRlciB0byByZXF1ZXN0IGEgbG9uZ2VyIHNlc3Npb24uIFRoZSBgTWF4U2Vzc2lvbkR1cmF0aW9uYCBzZXR0aW5nIGRldGVybWluZXMgdGhlIG1heGltdW0gZHVyYXRpb24gdGhhdCBjYW4gYmUgcmVxdWVzdGVkIHVzaW5nIHRoZSBgRHVyYXRpb25TZWNvbmRzYCBwYXJhbWV0ZXIuIElmIHVzZXJzIGRvbid0IHNwZWNpZnkgYSB2YWx1ZSBmb3IgdGhlIGBEdXJhdGlvblNlY29uZHNgIHBhcmFtZXRlciwgdGhlaXIgc2VjdXJpdHkgY3JlZGVudGlhbHMgYXJlIHZhbGlkIGZvciBvbmUgaG91ciBieSBkZWZhdWx0LiBUaGlzIGFwcGxpZXMgd2hlbiB5b3UgdXNlIHRoZSBgQXNzdW1lUm9sZSpgIEFQSSBvcGVyYXRpb25zIG9yIHRoZSBgYXNzdW1lLXJvbGUqYCBBV1MgQ0xJIG9wZXJhdGlvbnMgYnV0IGRvZXMgbm90IGFwcGx5IHdoZW4geW91IHVzZSB0aG9zZSBvcGVyYXRpb25zIHRvIGNyZWF0ZSBhIGNvbnNvbGUgVVJMLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtVc2luZyBJQU0gcm9sZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF9yb2xlc191c2UuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNjZm4taWFtLXJvbGUtbWF4c2Vzc2lvbmR1cmF0aW9uXG4gICAgICovXG4gICAgcmVhZG9ubHkgbWF4U2Vzc2lvbkR1cmF0aW9uPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBhdGggdG8gdGhlIHJvbGUuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHBhdGhzLCBzZWUgW0lBTSBJZGVudGlmaWVyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL1VzaW5nX0lkZW50aWZpZXJzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGlzIG9wdGlvbmFsLiBJZiBpdCBpcyBub3QgaW5jbHVkZWQsIGl0IGRlZmF1bHRzIHRvIGEgc2xhc2ggKC8pLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIGVpdGhlciBhIGZvcndhcmQgc2xhc2ggKC8pIGJ5IGl0c2VsZiBvciBhIHN0cmluZyB0aGF0IG11c3QgYmVnaW4gYW5kIGVuZCB3aXRoIGZvcndhcmQgc2xhc2hlcy4gSW4gYWRkaXRpb24sIGl0IGNhbiBjb250YWluIGFueSBBU0NJSSBjaGFyYWN0ZXIgZnJvbSB0aGUgISAoIGBcXCB1MDAyMWAgKSB0aHJvdWdoIHRoZSBERUwgY2hhcmFjdGVyICggYFxcIHUwMDdGYCApLCBpbmNsdWRpbmcgbW9zdCBwdW5jdHVhdGlvbiBjaGFyYWN0ZXJzLCBkaWdpdHMsIGFuZCB1cHBlciBhbmQgbG93ZXJjYXNlZCBsZXR0ZXJzLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXJvbGUuaHRtbCNjZm4taWFtLXJvbGUtcGF0aFxuICAgICAqL1xuICAgIHJlYWRvbmx5IHBhdGg/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQVJOIG9mIHRoZSBwb2xpY3kgdXNlZCB0byBzZXQgdGhlIHBlcm1pc3Npb25zIGJvdW5kYXJ5IGZvciB0aGUgcm9sZS5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHBlcm1pc3Npb25zIGJvdW5kYXJpZXMsIHNlZSBbUGVybWlzc2lvbnMgYm91bmRhcmllcyBmb3IgSUFNIGlkZW50aXRpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9hY2Nlc3NfcG9saWNpZXNfYm91bmRhcmllcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcm9sZS5odG1sI2Nmbi1pYW0tcm9sZS1wZXJtaXNzaW9uc2JvdW5kYXJ5XG4gICAgICovXG4gICAgcmVhZG9ubHkgcGVybWlzc2lvbnNCb3VuZGFyeT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEFkZHMgb3IgdXBkYXRlcyBhbiBpbmxpbmUgcG9saWN5IGRvY3VtZW50IHRoYXQgaXMgZW1iZWRkZWQgaW4gdGhlIHNwZWNpZmllZCBJQU0gcm9sZS5cbiAgICAgKlxuICAgICAqIFdoZW4geW91IGVtYmVkIGFuIGlubGluZSBwb2xpY3kgaW4gYSByb2xlLCB0aGUgaW5saW5lIHBvbGljeSBpcyB1c2VkIGFzIHBhcnQgb2YgdGhlIHJvbGUncyBhY2Nlc3MgKHBlcm1pc3Npb25zKSBwb2xpY3kuIFRoZSByb2xlJ3MgdHJ1c3QgcG9saWN5IGlzIGNyZWF0ZWQgYXQgdGhlIHNhbWUgdGltZSBhcyB0aGUgcm9sZS4gWW91IGNhbiB1cGRhdGUgYSByb2xlJ3MgdHJ1c3QgcG9saWN5IGxhdGVyLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBJQU0gcm9sZXMsIGdvIHRvIFtVc2luZyBSb2xlcyB0byBEZWxlZ2F0ZSBQZXJtaXNzaW9ucyBhbmQgRmVkZXJhdGUgSWRlbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JvbGVzLXRvcGxldmVsLmh0bWwpIC5cbiAgICAgKlxuICAgICAqIEEgcm9sZSBjYW4gYWxzbyBoYXZlIGFuIGF0dGFjaGVkIG1hbmFnZWQgcG9saWN5LiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgcG9saWNpZXMsIHNlZSBbTWFuYWdlZCBQb2xpY2llcyBhbmQgSW5saW5lIFBvbGljaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcG9saWNpZXMtbWFuYWdlZC12cy1pbmxpbmUuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogRm9yIGluZm9ybWF0aW9uIGFib3V0IGxpbWl0cyBvbiB0aGUgbnVtYmVyIG9mIGlubGluZSBwb2xpY2llcyB0aGF0IHlvdSBjYW4gZW1iZWQgd2l0aCBhIHJvbGUsIHNlZSBbTGltaXRhdGlvbnMgb24gSUFNIEVudGl0aWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvTGltaXRhdGlvbnNPbkVudGl0aWVzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqID4gSWYgYW4gZXh0ZXJuYWwgcG9saWN5IChzdWNoIGFzIGBBV1M6OklBTTo6UG9saWN5YCBvciBgQVdTOjpJQU06Ok1hbmFnZWRQb2xpY3lgICkgaGFzIGEgYFJlZmAgdG8gYSByb2xlIGFuZCBpZiBhIHJlc291cmNlIChzdWNoIGFzIGBBV1M6OkVDUzo6U2VydmljZWAgKSBhbHNvIGhhcyBhIGBSZWZgIHRvIHRoZSBzYW1lIHJvbGUsIGFkZCBhIGBEZXBlbmRzT25gIGF0dHJpYnV0ZSB0byB0aGUgcmVzb3VyY2UgdG8gbWFrZSB0aGUgcmVzb3VyY2UgZGVwZW5kIG9uIHRoZSBleHRlcm5hbCBwb2xpY3kuIFRoaXMgZGVwZW5kZW5jeSBlbnN1cmVzIHRoYXQgdGhlIHJvbGUncyBwb2xpY3kgaXMgYXZhaWxhYmxlIHRocm91Z2hvdXQgdGhlIHJlc291cmNlJ3MgbGlmZWN5Y2xlLiBGb3IgZXhhbXBsZSwgd2hlbiB5b3UgZGVsZXRlIGEgc3RhY2sgd2l0aCBhbiBgQVdTOjpFQ1M6OlNlcnZpY2VgIHJlc291cmNlLCB0aGUgYERlcGVuZHNPbmAgYXR0cmlidXRlIGVuc3VyZXMgdGhhdCBBV1MgQ2xvdWRGb3JtYXRpb24gZGVsZXRlcyB0aGUgYEFXUzo6RUNTOjpTZXJ2aWNlYCByZXNvdXJjZSBiZWZvcmUgZGVsZXRpbmcgaXRzIHJvbGUncyBwb2xpY3kuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcm9sZS5odG1sI2Nmbi1pYW0tcm9sZS1wb2xpY2llc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IHBvbGljaWVzPzogQXJyYXk8Q2ZuUm9sZS5Qb2xpY3lQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4gfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBBIG5hbWUgZm9yIHRoZSBJQU0gcm9sZSwgdXAgdG8gNjQgY2hhcmFjdGVycyBpbiBsZW5ndGguIEZvciB2YWxpZCB2YWx1ZXMsIHNlZSB0aGUgYFJvbGVOYW1lYCBwYXJhbWV0ZXIgZm9yIHRoZSBbYENyZWF0ZVJvbGVgXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVJvbGUuaHRtbCkgYWN0aW9uIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAocGVyIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC0uIFRoZSByb2xlIG5hbWUgbXVzdCBiZSB1bmlxdWUgd2l0aGluIHRoZSBhY2NvdW50LiBSb2xlIG5hbWVzIGFyZSBub3QgZGlzdGluZ3Vpc2hlZCBieSBjYXNlLiBGb3IgZXhhbXBsZSwgeW91IGNhbm5vdCBjcmVhdGUgcm9sZXMgbmFtZWQgYm90aCBcIlJvbGUxXCIgYW5kIFwicm9sZTFcIi5cbiAgICAgKlxuICAgICAqIElmIHlvdSBkb24ndCBzcGVjaWZ5IGEgbmFtZSwgQVdTIENsb3VkRm9ybWF0aW9uIGdlbmVyYXRlcyBhIHVuaXF1ZSBwaHlzaWNhbCBJRCBhbmQgdXNlcyB0aGF0IElEIGZvciB0aGUgcm9sZSBuYW1lLlxuICAgICAqXG4gICAgICogSWYgeW91IHNwZWNpZnkgYSBuYW1lLCB5b3UgbXVzdCBzcGVjaWZ5IHRoZSBgQ0FQQUJJTElUWV9OQU1FRF9JQU1gIHZhbHVlIHRvIGFja25vd2xlZGdlIHlvdXIgdGVtcGxhdGUncyBjYXBhYmlsaXRpZXMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0Fja25vd2xlZGdpbmcgSUFNIFJlc291cmNlcyBpbiBBV1MgQ2xvdWRGb3JtYXRpb24gVGVtcGxhdGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS91c2luZy1pYW0tdGVtcGxhdGUuaHRtbCN1c2luZy1pYW0tY2FwYWJpbGl0aWVzKSAuXG4gICAgICpcbiAgICAgKiA+IE5hbWluZyBhbiBJQU0gcmVzb3VyY2UgY2FuIGNhdXNlIGFuIHVucmVjb3ZlcmFibGUgZXJyb3IgaWYgeW91IHJldXNlIHRoZSBzYW1lIHRlbXBsYXRlIGluIG11bHRpcGxlIFJlZ2lvbnMuIFRvIHByZXZlbnQgdGhpcywgd2UgcmVjb21tZW5kIHVzaW5nIGBGbjo6Sm9pbmAgYW5kIGBBV1M6OlJlZ2lvbmAgdG8gY3JlYXRlIGEgUmVnaW9uLXNwZWNpZmljIG5hbWUsIGFzIGluIHRoZSBmb2xsb3dpbmcgZXhhbXBsZTogYHtcIkZuOjpKb2luXCI6IFtcIlwiLCBbe1wiUmVmXCI6IFwiQVdTOjpSZWdpb25cIn0sIHtcIlJlZlwiOiBcIk15UmVzb3VyY2VOYW1lXCJ9XV19YCAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcm9sZS5odG1sI2Nmbi1pYW0tcm9sZS1yb2xlbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IHJvbGVOYW1lPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIHRhZ3MgdGhhdCBhcmUgYXR0YWNoZWQgdG8gdGhlIHJvbGUuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRhZ2dpbmcsIHNlZSBbVGFnZ2luZyBJQU0gcmVzb3VyY2VzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvaWRfdGFncy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcm9sZS5odG1sI2Nmbi1pYW0tcm9sZS10YWdzXG4gICAgICovXG4gICAgcmVhZG9ubHkgdGFncz86IGNkay5DZm5UYWdbXTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDZm5Sb2xlUHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblJvbGVQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5Sb2xlUHJvcHNWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdhc3N1bWVSb2xlUG9saWN5RG9jdW1lbnQnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMuYXNzdW1lUm9sZVBvbGljeURvY3VtZW50KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdhc3N1bWVSb2xlUG9saWN5RG9jdW1lbnQnLCBjZGsudmFsaWRhdGVPYmplY3QpKHByb3BlcnRpZXMuYXNzdW1lUm9sZVBvbGljeURvY3VtZW50KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdkZXNjcmlwdGlvbicsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5kZXNjcmlwdGlvbikpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbWFuYWdlZFBvbGljeUFybnMnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLm1hbmFnZWRQb2xpY3lBcm5zKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdtYXhTZXNzaW9uRHVyYXRpb24nLCBjZGsudmFsaWRhdGVOdW1iZXIpKHByb3BlcnRpZXMubWF4U2Vzc2lvbkR1cmF0aW9uKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwYXRoJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnBhdGgpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3Blcm1pc3Npb25zQm91bmRhcnknLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucGVybWlzc2lvbnNCb3VuZGFyeSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWNpZXMnLCBjZGsubGlzdFZhbGlkYXRvcihDZm5Sb2xlX1BvbGljeVByb3BlcnR5VmFsaWRhdG9yKSkocHJvcGVydGllcy5wb2xpY2llcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncm9sZU5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucm9sZU5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3RhZ3MnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVDZm5UYWcpKShwcm9wZXJ0aWVzLnRhZ3MpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuUm9sZVByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlJvbGVgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblJvbGVQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpSb2xlYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblJvbGVQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuUm9sZVByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBBc3N1bWVSb2xlUG9saWN5RG9jdW1lbnQ6IGNkay5vYmplY3RUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuYXNzdW1lUm9sZVBvbGljeURvY3VtZW50KSxcbiAgICAgICAgRGVzY3JpcHRpb246IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZGVzY3JpcHRpb24pLFxuICAgICAgICBNYW5hZ2VkUG9saWN5QXJuczogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMubWFuYWdlZFBvbGljeUFybnMpLFxuICAgICAgICBNYXhTZXNzaW9uRHVyYXRpb246IGNkay5udW1iZXJUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubWF4U2Vzc2lvbkR1cmF0aW9uKSxcbiAgICAgICAgUGF0aDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wYXRoKSxcbiAgICAgICAgUGVybWlzc2lvbnNCb3VuZGFyeTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wZXJtaXNzaW9uc0JvdW5kYXJ5KSxcbiAgICAgICAgUG9saWNpZXM6IGNkay5saXN0TWFwcGVyKGNmblJvbGVQb2xpY3lQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMucG9saWNpZXMpLFxuICAgICAgICBSb2xlTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5yb2xlTmFtZSksXG4gICAgICAgIFRhZ3M6IGNkay5saXN0TWFwcGVyKGNkay5jZm5UYWdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnRhZ3MpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5Sb2xlUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdDxDZm5Sb2xlUHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblJvbGVQcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2Fzc3VtZVJvbGVQb2xpY3lEb2N1bWVudCcsICdBc3N1bWVSb2xlUG9saWN5RG9jdW1lbnQnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFueShwcm9wZXJ0aWVzLkFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZGVzY3JpcHRpb24nLCAnRGVzY3JpcHRpb24nLCBwcm9wZXJ0aWVzLkRlc2NyaXB0aW9uICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkRlc2NyaXB0aW9uKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdtYW5hZ2VkUG9saWN5QXJucycsICdNYW5hZ2VkUG9saWN5QXJucycsIHByb3BlcnRpZXMuTWFuYWdlZFBvbGljeUFybnMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nQXJyYXkocHJvcGVydGllcy5NYW5hZ2VkUG9saWN5QXJucykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbWF4U2Vzc2lvbkR1cmF0aW9uJywgJ01heFNlc3Npb25EdXJhdGlvbicsIHByb3BlcnRpZXMuTWF4U2Vzc2lvbkR1cmF0aW9uICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldE51bWJlcihwcm9wZXJ0aWVzLk1heFNlc3Npb25EdXJhdGlvbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncGF0aCcsICdQYXRoJywgcHJvcGVydGllcy5QYXRoICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlBhdGgpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3Blcm1pc3Npb25zQm91bmRhcnknLCAnUGVybWlzc2lvbnNCb3VuZGFyeScsIHByb3BlcnRpZXMuUGVybWlzc2lvbnNCb3VuZGFyeSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5QZXJtaXNzaW9uc0JvdW5kYXJ5KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwb2xpY2llcycsICdQb2xpY2llcycsIHByb3BlcnRpZXMuUG9saWNpZXMgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoQ2ZuUm9sZVBvbGljeVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLlBvbGljaWVzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdyb2xlTmFtZScsICdSb2xlTmFtZScsIHByb3BlcnRpZXMuUm9sZU5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUm9sZU5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3RhZ3MnLCAnVGFncycsIHByb3BlcnRpZXMuVGFncyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldENmblRhZykocHJvcGVydGllcy5UYWdzKSA6IHVuZGVmaW5lZCBhcyBhbnkpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6SUFNOjpSb2xlYFxuICpcbiAqIENyZWF0ZXMgYSBuZXcgcm9sZSBmb3IgeW91ciBBV1MgYWNjb3VudCAuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHJvbGVzLCBzZWUgW0lBTSByb2xlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL1dvcmtpbmdXaXRoUm9sZXMuaHRtbCkgLiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgcXVvdGFzIGZvciByb2xlIG5hbWVzIGFuZCB0aGUgbnVtYmVyIG9mIHJvbGVzIHlvdSBjYW4gY3JlYXRlLCBzZWUgW0lBTSBhbmQgQVdTIFNUUyBxdW90YXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfaWFtLXF1b3Rhcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpJQU06OlJvbGVcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcm9sZS5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5Sb2xlIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6SUFNOjpSb2xlXCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5Sb2xlIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5Sb2xlUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmblJvbGUoc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgZm9yIHRoZSByb2xlLiBGb3IgZXhhbXBsZTpcbiAgICAgKlxuICAgICAqIGB7XCJGbjo6R2V0QXR0XCIgOiBbXCJNeVJvbGVcIiwgXCJBcm5cIl0gfWBcbiAgICAgKlxuICAgICAqIFRoaXMgd2lsbCByZXR1cm4gYSB2YWx1ZSBzdWNoIGFzIGBhcm46YXdzOmlhbTo6MTIzNDU2Nzg5MDpyb2xlL015Um9sZS1BSkpIRFNLU0RGYCAuXG4gICAgICogQGNsb3VkZm9ybWF0aW9uQXR0cmlidXRlIEFyblxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBhdHRyQXJuOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzdGFibGUgYW5kIHVuaXF1ZSBzdHJpbmcgaWRlbnRpZnlpbmcgdGhlIHJvbGUuIEZvciBleGFtcGxlLCBgQUlEQUpRQUJMWlM0QTNRRFU1NzZRYCAuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBJRHMsIHNlZSBbSUFNIElkZW50aWZpZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX2lkZW50aWZpZXJzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKiBAY2xvdWRmb3JtYXRpb25BdHRyaWJ1dGUgUm9sZUlkXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGF0dHJSb2xlSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSB0cnVzdCBwb2xpY3kgdGhhdCBpcyBhc3NvY2lhdGVkIHdpdGggdGhpcyByb2xlLiBUcnVzdCBwb2xpY2llcyBkZWZpbmUgd2hpY2ggZW50aXRpZXMgY2FuIGFzc3VtZSB0aGUgcm9sZS4gWW91IGNhbiBhc3NvY2lhdGUgb25seSBvbmUgdHJ1c3QgcG9saWN5IHdpdGggYSByb2xlLiBGb3IgYW4gZXhhbXBsZSBvZiBhIHBvbGljeSB0aGF0IGNhbiBiZSB1c2VkIHRvIGFzc3VtZSBhIHJvbGUsIHNlZSBbVGVtcGxhdGUgRXhhbXBsZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcm9sZS5odG1sI2F3cy1yZXNvdXJjZS1pYW0tcm9sZS0tZXhhbXBsZXMpIC4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGVsZW1lbnRzIHRoYXQgeW91IGNhbiB1c2UgaW4gYW4gSUFNIHBvbGljeSwgc2VlIFtJQU0gUG9saWN5IEVsZW1lbnRzIFJlZmVyZW5jZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50cy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcm9sZS5odG1sI2Nmbi1pYW0tcm9sZS1hc3N1bWVyb2xlcG9saWN5ZG9jdW1lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgYXNzdW1lUm9sZVBvbGljeURvY3VtZW50OiBhbnkgfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBBIGRlc2NyaXB0aW9uIG9mIHRoZSByb2xlIHRoYXQgeW91IHByb3ZpZGUuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcm9sZS5odG1sI2Nmbi1pYW0tcm9sZS1kZXNjcmlwdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBkZXNjcmlwdGlvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIEFtYXpvbiBSZXNvdXJjZSBOYW1lcyAoQVJOcykgb2YgdGhlIElBTSBtYW5hZ2VkIHBvbGljaWVzIHRoYXQgeW91IHdhbnQgdG8gYXR0YWNoIHRvIHRoZSByb2xlLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgQVJOcywgc2VlIFtBbWF6b24gUmVzb3VyY2UgTmFtZXMgKEFSTnMpIGFuZCBBV1MgU2VydmljZSBOYW1lc3BhY2VzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZ2VuZXJhbC9sYXRlc3QvZ3IvYXdzLWFybnMtYW5kLW5hbWVzcGFjZXMuaHRtbCkgaW4gdGhlICpBV1MgR2VuZXJhbCBSZWZlcmVuY2UqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWwjY2ZuLWlhbS1yb2xlLW1hbmFnZXBvbGljeWFybnNcbiAgICAgKi9cbiAgICBwdWJsaWMgbWFuYWdlZFBvbGljeUFybnM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gc2Vzc2lvbiBkdXJhdGlvbiAoaW4gc2Vjb25kcykgdGhhdCB5b3Ugd2FudCB0byBzZXQgZm9yIHRoZSBzcGVjaWZpZWQgcm9sZS4gSWYgeW91IGRvIG5vdCBzcGVjaWZ5IGEgdmFsdWUgZm9yIHRoaXMgc2V0dGluZywgdGhlIGRlZmF1bHQgdmFsdWUgb2Ygb25lIGhvdXIgaXMgYXBwbGllZC4gVGhpcyBzZXR0aW5nIGNhbiBoYXZlIGEgdmFsdWUgZnJvbSAxIGhvdXIgdG8gMTIgaG91cnMuXG4gICAgICpcbiAgICAgKiBBbnlvbmUgd2hvIGFzc3VtZXMgdGhlIHJvbGUgZnJvbSB0aGUgQVdTIENMSSBvciBBUEkgY2FuIHVzZSB0aGUgYER1cmF0aW9uU2Vjb25kc2AgQVBJIHBhcmFtZXRlciBvciB0aGUgYGR1cmF0aW9uLXNlY29uZHNgIEFXUyBDTEkgcGFyYW1ldGVyIHRvIHJlcXVlc3QgYSBsb25nZXIgc2Vzc2lvbi4gVGhlIGBNYXhTZXNzaW9uRHVyYXRpb25gIHNldHRpbmcgZGV0ZXJtaW5lcyB0aGUgbWF4aW11bSBkdXJhdGlvbiB0aGF0IGNhbiBiZSByZXF1ZXN0ZWQgdXNpbmcgdGhlIGBEdXJhdGlvblNlY29uZHNgIHBhcmFtZXRlci4gSWYgdXNlcnMgZG9uJ3Qgc3BlY2lmeSBhIHZhbHVlIGZvciB0aGUgYER1cmF0aW9uU2Vjb25kc2AgcGFyYW1ldGVyLCB0aGVpciBzZWN1cml0eSBjcmVkZW50aWFscyBhcmUgdmFsaWQgZm9yIG9uZSBob3VyIGJ5IGRlZmF1bHQuIFRoaXMgYXBwbGllcyB3aGVuIHlvdSB1c2UgdGhlIGBBc3N1bWVSb2xlKmAgQVBJIG9wZXJhdGlvbnMgb3IgdGhlIGBhc3N1bWUtcm9sZSpgIEFXUyBDTEkgb3BlcmF0aW9ucyBidXQgZG9lcyBub3QgYXBwbHkgd2hlbiB5b3UgdXNlIHRob3NlIG9wZXJhdGlvbnMgdG8gY3JlYXRlIGEgY29uc29sZSBVUkwuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1VzaW5nIElBTSByb2xlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX3JvbGVzX3VzZS5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcm9sZS5odG1sI2Nmbi1pYW0tcm9sZS1tYXhzZXNzaW9uZHVyYXRpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgbWF4U2Vzc2lvbkR1cmF0aW9uOiBudW1iZXIgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGF0aCB0byB0aGUgcm9sZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgcGF0aHMsIHNlZSBbSUFNIElkZW50aWZpZXJzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvVXNpbmdfSWRlbnRpZmllcnMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgaXMgb3B0aW9uYWwuIElmIGl0IGlzIG5vdCBpbmNsdWRlZCwgaXQgZGVmYXVsdHMgdG8gYSBzbGFzaCAoLykuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgZWl0aGVyIGEgZm9yd2FyZCBzbGFzaCAoLykgYnkgaXRzZWxmIG9yIGEgc3RyaW5nIHRoYXQgbXVzdCBiZWdpbiBhbmQgZW5kIHdpdGggZm9yd2FyZCBzbGFzaGVzLiBJbiBhZGRpdGlvbiwgaXQgY2FuIGNvbnRhaW4gYW55IEFTQ0lJIGNoYXJhY3RlciBmcm9tIHRoZSAhICggYFxcIHUwMDIxYCApIHRocm91Z2ggdGhlIERFTCBjaGFyYWN0ZXIgKCBgXFwgdTAwN0ZgICksIGluY2x1ZGluZyBtb3N0IHB1bmN0dWF0aW9uIGNoYXJhY3RlcnMsIGRpZ2l0cywgYW5kIHVwcGVyIGFuZCBsb3dlcmNhc2VkIGxldHRlcnMuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tcm9sZS5odG1sI2Nmbi1pYW0tcm9sZS1wYXRoXG4gICAgICovXG4gICAgcHVibGljIHBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBBUk4gb2YgdGhlIHBvbGljeSB1c2VkIHRvIHNldCB0aGUgcGVybWlzc2lvbnMgYm91bmRhcnkgZm9yIHRoZSByb2xlLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgcGVybWlzc2lvbnMgYm91bmRhcmllcywgc2VlIFtQZXJtaXNzaW9ucyBib3VuZGFyaWVzIGZvciBJQU0gaWRlbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2FjY2Vzc19wb2xpY2llc19ib3VuZGFyaWVzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWwjY2ZuLWlhbS1yb2xlLXBlcm1pc3Npb25zYm91bmRhcnlcbiAgICAgKi9cbiAgICBwdWJsaWMgcGVybWlzc2lvbnNCb3VuZGFyeTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBvciB1cGRhdGVzIGFuIGlubGluZSBwb2xpY3kgZG9jdW1lbnQgdGhhdCBpcyBlbWJlZGRlZCBpbiB0aGUgc3BlY2lmaWVkIElBTSByb2xlLlxuICAgICAqXG4gICAgICogV2hlbiB5b3UgZW1iZWQgYW4gaW5saW5lIHBvbGljeSBpbiBhIHJvbGUsIHRoZSBpbmxpbmUgcG9saWN5IGlzIHVzZWQgYXMgcGFydCBvZiB0aGUgcm9sZSdzIGFjY2VzcyAocGVybWlzc2lvbnMpIHBvbGljeS4gVGhlIHJvbGUncyB0cnVzdCBwb2xpY3kgaXMgY3JlYXRlZCBhdCB0aGUgc2FtZSB0aW1lIGFzIHRoZSByb2xlLiBZb3UgY2FuIHVwZGF0ZSBhIHJvbGUncyB0cnVzdCBwb2xpY3kgbGF0ZXIuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IElBTSByb2xlcywgZ28gdG8gW1VzaW5nIFJvbGVzIHRvIERlbGVnYXRlIFBlcm1pc3Npb25zIGFuZCBGZWRlcmF0ZSBJZGVudGl0aWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcm9sZXMtdG9wbGV2ZWwuaHRtbCkgLlxuICAgICAqXG4gICAgICogQSByb2xlIGNhbiBhbHNvIGhhdmUgYW4gYXR0YWNoZWQgbWFuYWdlZCBwb2xpY3kuIEZvciBpbmZvcm1hdGlvbiBhYm91dCBwb2xpY2llcywgc2VlIFtNYW5hZ2VkIFBvbGljaWVzIGFuZCBJbmxpbmUgUG9saWNpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9wb2xpY2llcy1tYW5hZ2VkLXZzLWlubGluZS5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgbGltaXRzIG9uIHRoZSBudW1iZXIgb2YgaW5saW5lIHBvbGljaWVzIHRoYXQgeW91IGNhbiBlbWJlZCB3aXRoIGEgcm9sZSwgc2VlIFtMaW1pdGF0aW9ucyBvbiBJQU0gRW50aXRpZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9MaW1pdGF0aW9uc09uRW50aXRpZXMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogPiBJZiBhbiBleHRlcm5hbCBwb2xpY3kgKHN1Y2ggYXMgYEFXUzo6SUFNOjpQb2xpY3lgIG9yIGBBV1M6OklBTTo6TWFuYWdlZFBvbGljeWAgKSBoYXMgYSBgUmVmYCB0byBhIHJvbGUgYW5kIGlmIGEgcmVzb3VyY2UgKHN1Y2ggYXMgYEFXUzo6RUNTOjpTZXJ2aWNlYCApIGFsc28gaGFzIGEgYFJlZmAgdG8gdGhlIHNhbWUgcm9sZSwgYWRkIGEgYERlcGVuZHNPbmAgYXR0cmlidXRlIHRvIHRoZSByZXNvdXJjZSB0byBtYWtlIHRoZSByZXNvdXJjZSBkZXBlbmQgb24gdGhlIGV4dGVybmFsIHBvbGljeS4gVGhpcyBkZXBlbmRlbmN5IGVuc3VyZXMgdGhhdCB0aGUgcm9sZSdzIHBvbGljeSBpcyBhdmFpbGFibGUgdGhyb3VnaG91dCB0aGUgcmVzb3VyY2UncyBsaWZlY3ljbGUuIEZvciBleGFtcGxlLCB3aGVuIHlvdSBkZWxldGUgYSBzdGFjayB3aXRoIGFuIGBBV1M6OkVDUzo6U2VydmljZWAgcmVzb3VyY2UsIHRoZSBgRGVwZW5kc09uYCBhdHRyaWJ1dGUgZW5zdXJlcyB0aGF0IEFXUyBDbG91ZEZvcm1hdGlvbiBkZWxldGVzIHRoZSBgQVdTOjpFQ1M6OlNlcnZpY2VgIHJlc291cmNlIGJlZm9yZSBkZWxldGluZyBpdHMgcm9sZSdzIHBvbGljeS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWwjY2ZuLWlhbS1yb2xlLXBvbGljaWVzXG4gICAgICovXG4gICAgcHVibGljIHBvbGljaWVzOiBBcnJheTxDZm5Sb2xlLlBvbGljeVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEEgbmFtZSBmb3IgdGhlIElBTSByb2xlLCB1cCB0byA2NCBjaGFyYWN0ZXJzIGluIGxlbmd0aC4gRm9yIHZhbGlkIHZhbHVlcywgc2VlIHRoZSBgUm9sZU5hbWVgIHBhcmFtZXRlciBmb3IgdGhlIFtgQ3JlYXRlUm9sZWBdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlUm9sZS5odG1sKSBhY3Rpb24gaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzIChwZXIgaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdXBwZXIgYW5kIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyB3aXRoIG5vIHNwYWNlcy4gWW91IGNhbiBhbHNvIGluY2x1ZGUgYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogXys9LC5ALS4gVGhlIHJvbGUgbmFtZSBtdXN0IGJlIHVuaXF1ZSB3aXRoaW4gdGhlIGFjY291bnQuIFJvbGUgbmFtZXMgYXJlIG5vdCBkaXN0aW5ndWlzaGVkIGJ5IGNhc2UuIEZvciBleGFtcGxlLCB5b3UgY2Fubm90IGNyZWF0ZSByb2xlcyBuYW1lZCBib3RoIFwiUm9sZTFcIiBhbmQgXCJyb2xlMVwiLlxuICAgICAqXG4gICAgICogSWYgeW91IGRvbid0IHNwZWNpZnkgYSBuYW1lLCBBV1MgQ2xvdWRGb3JtYXRpb24gZ2VuZXJhdGVzIGEgdW5pcXVlIHBoeXNpY2FsIElEIGFuZCB1c2VzIHRoYXQgSUQgZm9yIHRoZSByb2xlIG5hbWUuXG4gICAgICpcbiAgICAgKiBJZiB5b3Ugc3BlY2lmeSBhIG5hbWUsIHlvdSBtdXN0IHNwZWNpZnkgdGhlIGBDQVBBQklMSVRZX05BTUVEX0lBTWAgdmFsdWUgdG8gYWNrbm93bGVkZ2UgeW91ciB0ZW1wbGF0ZSdzIGNhcGFiaWxpdGllcy4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQWNrbm93bGVkZ2luZyBJQU0gUmVzb3VyY2VzIGluIEFXUyBDbG91ZEZvcm1hdGlvbiBUZW1wbGF0ZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL3VzaW5nLWlhbS10ZW1wbGF0ZS5odG1sI3VzaW5nLWlhbS1jYXBhYmlsaXRpZXMpIC5cbiAgICAgKlxuICAgICAqID4gTmFtaW5nIGFuIElBTSByZXNvdXJjZSBjYW4gY2F1c2UgYW4gdW5yZWNvdmVyYWJsZSBlcnJvciBpZiB5b3UgcmV1c2UgdGhlIHNhbWUgdGVtcGxhdGUgaW4gbXVsdGlwbGUgUmVnaW9ucy4gVG8gcHJldmVudCB0aGlzLCB3ZSByZWNvbW1lbmQgdXNpbmcgYEZuOjpKb2luYCBhbmQgYEFXUzo6UmVnaW9uYCB0byBjcmVhdGUgYSBSZWdpb24tc3BlY2lmaWMgbmFtZSwgYXMgaW4gdGhlIGZvbGxvd2luZyBleGFtcGxlOiBge1wiRm46OkpvaW5cIjogW1wiXCIsIFt7XCJSZWZcIjogXCJBV1M6OlJlZ2lvblwifSwge1wiUmVmXCI6IFwiTXlSZXNvdXJjZU5hbWVcIn1dXX1gIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWwjY2ZuLWlhbS1yb2xlLXJvbGVuYW1lXG4gICAgICovXG4gICAgcHVibGljIHJvbGVOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgdGFncyB0aGF0IGFyZSBhdHRhY2hlZCB0byB0aGUgcm9sZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGFnZ2luZywgc2VlIFtUYWdnaW5nIElBTSByZXNvdXJjZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF90YWdzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1yb2xlLmh0bWwjY2ZuLWlhbS1yb2xlLXRhZ3NcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgdGFnczogY2RrLlRhZ01hbmFnZXI7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6SUFNOjpSb2xlYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5Sb2xlUHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmblJvbGUuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICdhc3N1bWVSb2xlUG9saWN5RG9jdW1lbnQnLCB0aGlzKTtcbiAgICAgICAgdGhpcy5hdHRyQXJuID0gY2RrLlRva2VuLmFzU3RyaW5nKHRoaXMuZ2V0QXR0KCdBcm4nKSk7XG4gICAgICAgIHRoaXMuYXR0clJvbGVJZCA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnUm9sZUlkJykpO1xuXG4gICAgICAgIHRoaXMuYXNzdW1lUm9sZVBvbGljeURvY3VtZW50ID0gcHJvcHMuYXNzdW1lUm9sZVBvbGljeURvY3VtZW50O1xuICAgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gcHJvcHMuZGVzY3JpcHRpb247XG4gICAgICAgIHRoaXMubWFuYWdlZFBvbGljeUFybnMgPSBwcm9wcy5tYW5hZ2VkUG9saWN5QXJucztcbiAgICAgICAgdGhpcy5tYXhTZXNzaW9uRHVyYXRpb24gPSBwcm9wcy5tYXhTZXNzaW9uRHVyYXRpb247XG4gICAgICAgIHRoaXMucGF0aCA9IHByb3BzLnBhdGg7XG4gICAgICAgIHRoaXMucGVybWlzc2lvbnNCb3VuZGFyeSA9IHByb3BzLnBlcm1pc3Npb25zQm91bmRhcnk7XG4gICAgICAgIHRoaXMucG9saWNpZXMgPSBwcm9wcy5wb2xpY2llcztcbiAgICAgICAgdGhpcy5yb2xlTmFtZSA9IHByb3BzLnJvbGVOYW1lO1xuICAgICAgICB0aGlzLnRhZ3MgPSBuZXcgY2RrLlRhZ01hbmFnZXIoY2RrLlRhZ1R5cGUuU1RBTkRBUkQsIFwiQVdTOjpJQU06OlJvbGVcIiwgcHJvcHMudGFncywgeyB0YWdQcm9wZXJ0eU5hbWU6ICd0YWdzJyB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmblJvbGUuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudDogdGhpcy5hc3N1bWVSb2xlUG9saWN5RG9jdW1lbnQsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogdGhpcy5kZXNjcmlwdGlvbixcbiAgICAgICAgICAgIG1hbmFnZWRQb2xpY3lBcm5zOiB0aGlzLm1hbmFnZWRQb2xpY3lBcm5zLFxuICAgICAgICAgICAgbWF4U2Vzc2lvbkR1cmF0aW9uOiB0aGlzLm1heFNlc3Npb25EdXJhdGlvbixcbiAgICAgICAgICAgIHBhdGg6IHRoaXMucGF0aCxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zQm91bmRhcnk6IHRoaXMucGVybWlzc2lvbnNCb3VuZGFyeSxcbiAgICAgICAgICAgIHBvbGljaWVzOiB0aGlzLnBvbGljaWVzLFxuICAgICAgICAgICAgcm9sZU5hbWU6IHRoaXMucm9sZU5hbWUsXG4gICAgICAgICAgICB0YWdzOiB0aGlzLnRhZ3MucmVuZGVyVGFncygpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmblJvbGVQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5Sb2xlIHtcbiAgICAvKipcbiAgICAgKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBhbiBhdHRhY2hlZCBwb2xpY3kuXG4gICAgICpcbiAgICAgKiBBbiBhdHRhY2hlZCBwb2xpY3kgaXMgYSBtYW5hZ2VkIHBvbGljeSB0aGF0IGhhcyBiZWVuIGF0dGFjaGVkIHRvIGEgdXNlciwgZ3JvdXAsIG9yIHJvbGUuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBtYW5hZ2VkIHBvbGljaWVzLCByZWZlciB0byBbTWFuYWdlZCBQb2xpY2llcyBhbmQgSW5saW5lIFBvbGljaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcG9saWNpZXMtbWFuYWdlZC12cy1pbmxpbmUuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXBvbGljeS5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBQb2xpY3lQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZW50aXJlIGNvbnRlbnRzIG9mIHRoZSBwb2xpY3kgdGhhdCBkZWZpbmVzIHBlcm1pc3Npb25zLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtPdmVydmlldyBvZiBKU09OIHBvbGljaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvYWNjZXNzX3BvbGljaWVzLmh0bWwjYWNjZXNzX3BvbGljaWVzLWpzb24pIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tcG9saWN5Lmh0bWwjY2ZuLWlhbS1wb2xpY2llcy1wb2xpY3lkb2N1bWVudFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcG9saWN5RG9jdW1lbnQ6IGFueSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBmcmllbmRseSBuYW1lIChub3QgQVJOKSBpZGVudGlmeWluZyB0aGUgcG9saWN5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1wb2xpY3kuaHRtbCNjZm4taWFtLXBvbGljaWVzLXBvbGljeW5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHBvbGljeU5hbWU6IHN0cmluZztcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgUG9saWN5UHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFBvbGljeVByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblJvbGVfUG9saWN5UHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb2xpY3lEb2N1bWVudCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5wb2xpY3lEb2N1bWVudCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5RG9jdW1lbnQnLCBjZGsudmFsaWRhdGVPYmplY3QpKHByb3BlcnRpZXMucG9saWN5RG9jdW1lbnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvbGljeU5hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMucG9saWN5TmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5TmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5wb2xpY3lOYW1lKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIlBvbGljeVByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlJvbGUuUG9saWN5YCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBQb2xpY3lQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpSb2xlLlBvbGljeWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5Sb2xlUG9saWN5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblJvbGVfUG9saWN5UHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFBvbGljeURvY3VtZW50OiBjZGsub2JqZWN0VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBvbGljeURvY3VtZW50KSxcbiAgICAgICAgUG9saWN5TmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wb2xpY3lOYW1lKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuUm9sZVBvbGljeVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuUm9sZS5Qb2xpY3lQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5Sb2xlLlBvbGljeVByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncG9saWN5RG9jdW1lbnQnLCAnUG9saWN5RG9jdW1lbnQnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFueShwcm9wZXJ0aWVzLlBvbGljeURvY3VtZW50KSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwb2xpY3lOYW1lJywgJ1BvbGljeU5hbWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlBvbGljeU5hbWUpKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5TQU1MUHJvdmlkZXJgXG4gKlxuICogQHN0cnVjdFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zYW1scHJvdmlkZXIuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmblNBTUxQcm92aWRlclByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIEFuIFhNTCBkb2N1bWVudCBnZW5lcmF0ZWQgYnkgYW4gaWRlbnRpdHkgcHJvdmlkZXIgKElkUCkgdGhhdCBzdXBwb3J0cyBTQU1MIDIuMC4gVGhlIGRvY3VtZW50IGluY2x1ZGVzIHRoZSBpc3N1ZXIncyBuYW1lLCBleHBpcmF0aW9uIGluZm9ybWF0aW9uLCBhbmQga2V5cyB0aGF0IGNhbiBiZSB1c2VkIHRvIHZhbGlkYXRlIHRoZSBTQU1MIGF1dGhlbnRpY2F0aW9uIHJlc3BvbnNlIChhc3NlcnRpb25zKSB0aGF0IGFyZSByZWNlaXZlZCBmcm9tIHRoZSBJZFAuIFlvdSBtdXN0IGdlbmVyYXRlIHRoZSBtZXRhZGF0YSBkb2N1bWVudCB1c2luZyB0aGUgaWRlbnRpdHkgbWFuYWdlbWVudCBzb2Z0d2FyZSB0aGF0IGlzIHVzZWQgYXMgeW91ciBvcmdhbml6YXRpb24ncyBJZFAuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBYm91dCBTQU1MIDIuMC1iYXNlZCBmZWRlcmF0aW9uXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvaWRfcm9sZXNfcHJvdmlkZXJzX3NhbWwuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSpcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zYW1scHJvdmlkZXIuaHRtbCNjZm4taWFtLXNhbWxwcm92aWRlci1zYW1sbWV0YWRhdGFkb2N1bWVudFxuICAgICAqL1xuICAgIHJlYWRvbmx5IHNhbWxNZXRhZGF0YURvY3VtZW50OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcHJvdmlkZXIgdG8gY3JlYXRlLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zYW1scHJvdmlkZXIuaHRtbCNjZm4taWFtLXNhbWxwcm92aWRlci1uYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgbmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiB0YWdzIHRoYXQgeW91IHdhbnQgdG8gYXR0YWNoIHRvIHRoZSBuZXcgSUFNIFNBTUwgcHJvdmlkZXIuIEVhY2ggdGFnIGNvbnNpc3RzIG9mIGEga2V5IG5hbWUgYW5kIGFuIGFzc29jaWF0ZWQgdmFsdWUuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRhZ2dpbmcsIHNlZSBbVGFnZ2luZyBJQU0gcmVzb3VyY2VzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvaWRfdGFncy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiA+IElmIGFueSBvbmUgb2YgdGhlIHRhZ3MgaXMgaW52YWxpZCBvciBpZiB5b3UgZXhjZWVkIHRoZSBhbGxvd2VkIG1heGltdW0gbnVtYmVyIG9mIHRhZ3MsIHRoZW4gdGhlIGVudGlyZSByZXF1ZXN0IGZhaWxzIGFuZCB0aGUgcmVzb3VyY2UgaXMgbm90IGNyZWF0ZWQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2FtbHByb3ZpZGVyLmh0bWwjY2ZuLWlhbS1zYW1scHJvdmlkZXItdGFnc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IHRhZ3M/OiBjZGsuQ2ZuVGFnW107XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2ZuU0FNTFByb3ZpZGVyUHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblNBTUxQcm92aWRlclByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblNBTUxQcm92aWRlclByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5uYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzYW1sTWV0YWRhdGFEb2N1bWVudCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5zYW1sTWV0YWRhdGFEb2N1bWVudCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignc2FtbE1ldGFkYXRhRG9jdW1lbnQnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuc2FtbE1ldGFkYXRhRG9jdW1lbnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3RhZ3MnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVDZm5UYWcpKShwcm9wZXJ0aWVzLnRhZ3MpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuU0FNTFByb3ZpZGVyUHJvcHNcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6U0FNTFByb3ZpZGVyYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5TQU1MUHJvdmlkZXJQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpTQU1MUHJvdmlkZXJgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuU0FNTFByb3ZpZGVyUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblNBTUxQcm92aWRlclByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBTYW1sTWV0YWRhdGFEb2N1bWVudDogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zYW1sTWV0YWRhdGFEb2N1bWVudCksXG4gICAgICAgIE5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMubmFtZSksXG4gICAgICAgIFRhZ3M6IGNkay5saXN0TWFwcGVyKGNkay5jZm5UYWdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnRhZ3MpLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5TQU1MUHJvdmlkZXJQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblNBTUxQcm92aWRlclByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5TQU1MUHJvdmlkZXJQcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3NhbWxNZXRhZGF0YURvY3VtZW50JywgJ1NhbWxNZXRhZGF0YURvY3VtZW50JywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5TYW1sTWV0YWRhdGFEb2N1bWVudCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbmFtZScsICdOYW1lJywgcHJvcGVydGllcy5OYW1lICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLk5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3RhZ3MnLCAnVGFncycsIHByb3BlcnRpZXMuVGFncyAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRBcnJheShjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldENmblRhZykocHJvcGVydGllcy5UYWdzKSA6IHVuZGVmaW5lZCBhcyBhbnkpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6SUFNOjpTQU1MUHJvdmlkZXJgXG4gKlxuICogQ3JlYXRlcyBhbiBJQU0gcmVzb3VyY2UgdGhhdCBkZXNjcmliZXMgYW4gaWRlbnRpdHkgcHJvdmlkZXIgKElkUCkgdGhhdCBzdXBwb3J0cyBTQU1MIDIuMC5cbiAqXG4gKiBUaGUgU0FNTCBwcm92aWRlciByZXNvdXJjZSB0aGF0IHlvdSBjcmVhdGUgd2l0aCB0aGlzIG9wZXJhdGlvbiBjYW4gYmUgdXNlZCBhcyBhIHByaW5jaXBhbCBpbiBhbiBJQU0gcm9sZSdzIHRydXN0IHBvbGljeS4gU3VjaCBhIHBvbGljeSBjYW4gZW5hYmxlIGZlZGVyYXRlZCB1c2VycyB3aG8gc2lnbiBpbiB1c2luZyB0aGUgU0FNTCBJZFAgdG8gYXNzdW1lIHRoZSByb2xlLiBZb3UgY2FuIGNyZWF0ZSBhbiBJQU0gcm9sZSB0aGF0IHN1cHBvcnRzIFdlYi1iYXNlZCBzaW5nbGUgc2lnbi1vbiAoU1NPKSB0byB0aGUgQVdTIE1hbmFnZW1lbnQgQ29uc29sZSBvciBvbmUgdGhhdCBzdXBwb3J0cyBBUEkgYWNjZXNzIHRvIEFXUyAuXG4gKlxuICogV2hlbiB5b3UgY3JlYXRlIHRoZSBTQU1MIHByb3ZpZGVyIHJlc291cmNlLCB5b3UgdXBsb2FkIGEgU0FNTCBtZXRhZGF0YSBkb2N1bWVudCB0aGF0IHlvdSBnZXQgZnJvbSB5b3VyIElkUC4gVGhhdCBkb2N1bWVudCBpbmNsdWRlcyB0aGUgaXNzdWVyJ3MgbmFtZSwgZXhwaXJhdGlvbiBpbmZvcm1hdGlvbiwgYW5kIGtleXMgdGhhdCBjYW4gYmUgdXNlZCB0byB2YWxpZGF0ZSB0aGUgU0FNTCBhdXRoZW50aWNhdGlvbiByZXNwb25zZSAoYXNzZXJ0aW9ucykgdGhhdCB0aGUgSWRQIHNlbmRzLiBZb3UgbXVzdCBnZW5lcmF0ZSB0aGUgbWV0YWRhdGEgZG9jdW1lbnQgdXNpbmcgdGhlIGlkZW50aXR5IG1hbmFnZW1lbnQgc29mdHdhcmUgdGhhdCBpcyB1c2VkIGFzIHlvdXIgb3JnYW5pemF0aW9uJ3MgSWRQLlxuICpcbiAqID4gVGhpcyBvcGVyYXRpb24gcmVxdWlyZXMgW1NpZ25hdHVyZSBWZXJzaW9uIDRdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nZW5lcmFsL2xhdGVzdC9nci9zaWduYXR1cmUtdmVyc2lvbi00Lmh0bWwpIC5cbiAqXG4gKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtFbmFibGluZyBTQU1MIDIuMCBmZWRlcmF0ZWQgdXNlcnMgdG8gYWNjZXNzIHRoZSBBV1MgTWFuYWdlbWVudCBDb25zb2xlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvaWRfcm9sZXNfcHJvdmlkZXJzX2VuYWJsZS1jb25zb2xlLXNhbWwuaHRtbCkgYW5kIFtBYm91dCBTQU1MIDIuMC1iYXNlZCBmZWRlcmF0aW9uXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvaWRfcm9sZXNfcHJvdmlkZXJzX3NhbWwuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6SUFNOjpTQU1MUHJvdmlkZXJcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2FtbHByb3ZpZGVyLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmblNBTUxQcm92aWRlciBleHRlbmRzIGNkay5DZm5SZXNvdXJjZSBpbXBsZW1lbnRzIGNkay5JSW5zcGVjdGFibGUge1xuICAgIC8qKlxuICAgICAqIFRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSB0eXBlIG5hbWUgZm9yIHRoaXMgcmVzb3VyY2UgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBDRk5fUkVTT1VSQ0VfVFlQRV9OQU1FID0gXCJBV1M6OklBTTo6U0FNTFByb3ZpZGVyXCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5TQU1MUHJvdmlkZXIge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmblNBTUxQcm92aWRlclByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHJlc291cmNlUHJvcGVydGllcyk7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBDZm5TQU1MUHJvdmlkZXIoc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgZm9yIHRoZSBzcGVjaWZpZWQgYEFXUzo6SUFNOjpTQU1MUHJvdmlkZXJgIHJlc291cmNlLlxuICAgICAqIEBjbG91ZGZvcm1hdGlvbkF0dHJpYnV0ZSBBcm5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgYXR0ckFybjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQW4gWE1MIGRvY3VtZW50IGdlbmVyYXRlZCBieSBhbiBpZGVudGl0eSBwcm92aWRlciAoSWRQKSB0aGF0IHN1cHBvcnRzIFNBTUwgMi4wLiBUaGUgZG9jdW1lbnQgaW5jbHVkZXMgdGhlIGlzc3VlcidzIG5hbWUsIGV4cGlyYXRpb24gaW5mb3JtYXRpb24sIGFuZCBrZXlzIHRoYXQgY2FuIGJlIHVzZWQgdG8gdmFsaWRhdGUgdGhlIFNBTUwgYXV0aGVudGljYXRpb24gcmVzcG9uc2UgKGFzc2VydGlvbnMpIHRoYXQgYXJlIHJlY2VpdmVkIGZyb20gdGhlIElkUC4gWW91IG11c3QgZ2VuZXJhdGUgdGhlIG1ldGFkYXRhIGRvY3VtZW50IHVzaW5nIHRoZSBpZGVudGl0eSBtYW5hZ2VtZW50IHNvZnR3YXJlIHRoYXQgaXMgdXNlZCBhcyB5b3VyIG9yZ2FuaXphdGlvbidzIElkUC5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0Fib3V0IFNBTUwgMi4wLWJhc2VkIGZlZGVyYXRpb25dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF9yb2xlc19wcm92aWRlcnNfc2FtbC5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNhbWxwcm92aWRlci5odG1sI2Nmbi1pYW0tc2FtbHByb3ZpZGVyLXNhbWxtZXRhZGF0YWRvY3VtZW50XG4gICAgICovXG4gICAgcHVibGljIHNhbWxNZXRhZGF0YURvY3VtZW50OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcHJvdmlkZXIgdG8gY3JlYXRlLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zYW1scHJvdmlkZXIuaHRtbCNjZm4taWFtLXNhbWxwcm92aWRlci1uYW1lXG4gICAgICovXG4gICAgcHVibGljIG5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiB0YWdzIHRoYXQgeW91IHdhbnQgdG8gYXR0YWNoIHRvIHRoZSBuZXcgSUFNIFNBTUwgcHJvdmlkZXIuIEVhY2ggdGFnIGNvbnNpc3RzIG9mIGEga2V5IG5hbWUgYW5kIGFuIGFzc29jaWF0ZWQgdmFsdWUuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRhZ2dpbmcsIHNlZSBbVGFnZ2luZyBJQU0gcmVzb3VyY2VzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvaWRfdGFncy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiA+IElmIGFueSBvbmUgb2YgdGhlIHRhZ3MgaXMgaW52YWxpZCBvciBpZiB5b3UgZXhjZWVkIHRoZSBhbGxvd2VkIG1heGltdW0gbnVtYmVyIG9mIHRhZ3MsIHRoZW4gdGhlIGVudGlyZSByZXF1ZXN0IGZhaWxzIGFuZCB0aGUgcmVzb3VyY2UgaXMgbm90IGNyZWF0ZWQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2FtbHByb3ZpZGVyLmh0bWwjY2ZuLWlhbS1zYW1scHJvdmlkZXItdGFnc1xuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB0YWdzOiBjZGsuVGFnTWFuYWdlcjtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBgQVdTOjpJQU06OlNBTUxQcm92aWRlcmAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuU0FNTFByb3ZpZGVyUHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmblNBTUxQcm92aWRlci5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FLCBwcm9wZXJ0aWVzOiBwcm9wcyB9KTtcbiAgICAgICAgY2RrLnJlcXVpcmVQcm9wZXJ0eShwcm9wcywgJ3NhbWxNZXRhZGF0YURvY3VtZW50JywgdGhpcyk7XG4gICAgICAgIHRoaXMuYXR0ckFybiA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnQXJuJykpO1xuXG4gICAgICAgIHRoaXMuc2FtbE1ldGFkYXRhRG9jdW1lbnQgPSBwcm9wcy5zYW1sTWV0YWRhdGFEb2N1bWVudDtcbiAgICAgICAgdGhpcy5uYW1lID0gcHJvcHMubmFtZTtcbiAgICAgICAgdGhpcy50YWdzID0gbmV3IGNkay5UYWdNYW5hZ2VyKGNkay5UYWdUeXBlLlNUQU5EQVJELCBcIkFXUzo6SUFNOjpTQU1MUHJvdmlkZXJcIiwgcHJvcHMudGFncywgeyB0YWdQcm9wZXJ0eU5hbWU6ICd0YWdzJyB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGFtaW5lcyB0aGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgYW5kIGRpc2Nsb3NlcyBhdHRyaWJ1dGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluc3BlY3RvciAtIHRyZWUgaW5zcGVjdG9yIHRvIGNvbGxlY3QgYW5kIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAqXG4gICAgICovXG4gICAgcHVibGljIGluc3BlY3QoaW5zcGVjdG9yOiBjZGsuVHJlZUluc3BlY3Rvcikge1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjp0eXBlXCIsIENmblNBTUxQcm92aWRlci5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2FtbE1ldGFkYXRhRG9jdW1lbnQ6IHRoaXMuc2FtbE1ldGFkYXRhRG9jdW1lbnQsXG4gICAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgICAgICB0YWdzOiB0aGlzLnRhZ3MucmVuZGVyVGFncygpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCByZW5kZXJQcm9wZXJ0aWVzKHByb3BzOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIGNmblNBTUxQcm92aWRlclByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmblNlcnZlckNlcnRpZmljYXRlYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2VydmVyY2VydGlmaWNhdGUuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmblNlcnZlckNlcnRpZmljYXRlUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNvbnRlbnRzIG9mIHRoZSBwdWJsaWMga2V5IGNlcnRpZmljYXRlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZlcmNlcnRpZmljYXRlLmh0bWwjY2ZuLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS1jZXJ0aWZpY2F0ZWJvZHlcbiAgICAgKi9cbiAgICByZWFkb25seSBjZXJ0aWZpY2F0ZUJvZHk/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY29udGVudHMgb2YgdGhlIHB1YmxpYyBrZXkgY2VydGlmaWNhdGUgY2hhaW4uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2VydmVyY2VydGlmaWNhdGUuaHRtbCNjZm4taWFtLXNlcnZlcmNlcnRpZmljYXRlLWNlcnRpZmljYXRlY2hhaW5cbiAgICAgKi9cbiAgICByZWFkb25seSBjZXJ0aWZpY2F0ZUNoYWluPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBhdGggZm9yIHRoZSBzZXJ2ZXIgY2VydGlmaWNhdGUuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHBhdGhzLCBzZWUgW0lBTSBpZGVudGlmaWVyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL1VzaW5nX0lkZW50aWZpZXJzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGlzIG9wdGlvbmFsLiBJZiBpdCBpcyBub3QgaW5jbHVkZWQsIGl0IGRlZmF1bHRzIHRvIGEgc2xhc2ggKC8pLiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgZWl0aGVyIGEgZm9yd2FyZCBzbGFzaCAoLykgYnkgaXRzZWxmIG9yIGEgc3RyaW5nIHRoYXQgbXVzdCBiZWdpbiBhbmQgZW5kIHdpdGggZm9yd2FyZCBzbGFzaGVzLiBJbiBhZGRpdGlvbiwgaXQgY2FuIGNvbnRhaW4gYW55IEFTQ0lJIGNoYXJhY3RlciBmcm9tIHRoZSAhICggYFxcIHUwMDIxYCApIHRocm91Z2ggdGhlIERFTCBjaGFyYWN0ZXIgKCBgXFwgdTAwN0ZgICksIGluY2x1ZGluZyBtb3N0IHB1bmN0dWF0aW9uIGNoYXJhY3RlcnMsIGRpZ2l0cywgYW5kIHVwcGVyIGFuZCBsb3dlcmNhc2VkIGxldHRlcnMuXG4gICAgICpcbiAgICAgKiA+IElmIHlvdSBhcmUgdXBsb2FkaW5nIGEgc2VydmVyIGNlcnRpZmljYXRlIHNwZWNpZmljYWxseSBmb3IgdXNlIHdpdGggQW1hem9uIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9ucywgeW91IG11c3Qgc3BlY2lmeSBhIHBhdGggdXNpbmcgdGhlIGBwYXRoYCBwYXJhbWV0ZXIuIFRoZSBwYXRoIG11c3QgYmVnaW4gd2l0aCBgL2Nsb3VkZnJvbnRgIGFuZCBtdXN0IGluY2x1ZGUgYSB0cmFpbGluZyBzbGFzaCAoZm9yIGV4YW1wbGUsIGAvY2xvdWRmcm9udC90ZXN0L2AgKS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS5odG1sI2Nmbi1pYW0tc2VydmVyY2VydGlmaWNhdGUtcGF0aFxuICAgICAqL1xuICAgIHJlYWRvbmx5IHBhdGg/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY29udGVudHMgb2YgdGhlIHByaXZhdGUga2V5IGluIFBFTS1lbmNvZGVkIGZvcm1hdC5cbiAgICAgKlxuICAgICAqIFRoZSBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpIHVzZWQgdG8gdmFsaWRhdGUgdGhpcyBwYXJhbWV0ZXIgaXMgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIEFueSBwcmludGFibGUgQVNDSUkgY2hhcmFjdGVyIHJhbmdpbmcgZnJvbSB0aGUgc3BhY2UgY2hhcmFjdGVyICggYFxcIHUwMDIwYCApIHRocm91Z2ggdGhlIGVuZCBvZiB0aGUgQVNDSUkgY2hhcmFjdGVyIHJhbmdlXG4gICAgICogLSBUaGUgcHJpbnRhYmxlIGNoYXJhY3RlcnMgaW4gdGhlIEJhc2ljIExhdGluIGFuZCBMYXRpbi0xIFN1cHBsZW1lbnQgY2hhcmFjdGVyIHNldCAodGhyb3VnaCBgXFwgdTAwRkZgIClcbiAgICAgKiAtIFRoZSBzcGVjaWFsIGNoYXJhY3RlcnMgdGFiICggYFxcIHUwMDA5YCApLCBsaW5lIGZlZWQgKCBgXFwgdTAwMEFgICksIGFuZCBjYXJyaWFnZSByZXR1cm4gKCBgXFwgdTAwMERgIClcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS5odG1sI2Nmbi1pYW0tc2VydmVyY2VydGlmaWNhdGUtcHJpdmF0ZWtleVxuICAgICAqL1xuICAgIHJlYWRvbmx5IHByaXZhdGVLZXk/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBmb3IgdGhlIHNlcnZlciBjZXJ0aWZpY2F0ZS4gRG8gbm90IGluY2x1ZGUgdGhlIHBhdGggaW4gdGhpcyB2YWx1ZS4gVGhlIG5hbWUgb2YgdGhlIGNlcnRpZmljYXRlIGNhbm5vdCBjb250YWluIGFueSBzcGFjZXMuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdXBwZXIgYW5kIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyB3aXRoIG5vIHNwYWNlcy4gWW91IGNhbiBhbHNvIGluY2x1ZGUgYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogXys9LC5ALVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZlcmNlcnRpZmljYXRlLmh0bWwjY2ZuLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS1zZXJ2ZXJjZXJ0aWZpY2F0ZW5hbWVcbiAgICAgKi9cbiAgICByZWFkb25seSBzZXJ2ZXJDZXJ0aWZpY2F0ZU5hbWU/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgdGFncyB0aGF0IGFyZSBhdHRhY2hlZCB0byB0aGUgc2VydmVyIGNlcnRpZmljYXRlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0YWdnaW5nLCBzZWUgW1RhZ2dpbmcgSUFNIHJlc291cmNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX3RhZ3MuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZlcmNlcnRpZmljYXRlLmh0bWwjY2ZuLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS10YWdzXG4gICAgICovXG4gICAgcmVhZG9ubHkgdGFncz86IGNkay5DZm5UYWdbXTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDZm5TZXJ2ZXJDZXJ0aWZpY2F0ZVByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5TZXJ2ZXJDZXJ0aWZpY2F0ZVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblNlcnZlckNlcnRpZmljYXRlUHJvcHNWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjZXJ0aWZpY2F0ZUJvZHknLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuY2VydGlmaWNhdGVCb2R5KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdjZXJ0aWZpY2F0ZUNoYWluJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmNlcnRpZmljYXRlQ2hhaW4pKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BhdGgnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMucGF0aCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncHJpdmF0ZUtleScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5wcml2YXRlS2V5KSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdzZXJ2ZXJDZXJ0aWZpY2F0ZU5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuc2VydmVyQ2VydGlmaWNhdGVOYW1lKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0YWdzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlQ2ZuVGFnKSkocHJvcGVydGllcy50YWdzKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmblNlcnZlckNlcnRpZmljYXRlUHJvcHNcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6U2VydmVyQ2VydGlmaWNhdGVgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblNlcnZlckNlcnRpZmljYXRlUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6U2VydmVyQ2VydGlmaWNhdGVgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuU2VydmVyQ2VydGlmaWNhdGVQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuU2VydmVyQ2VydGlmaWNhdGVQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQ2VydGlmaWNhdGVCb2R5OiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLmNlcnRpZmljYXRlQm9keSksXG4gICAgICAgIENlcnRpZmljYXRlQ2hhaW46IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY2VydGlmaWNhdGVDaGFpbiksXG4gICAgICAgIFBhdGg6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucGF0aCksXG4gICAgICAgIFByaXZhdGVLZXk6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucHJpdmF0ZUtleSksXG4gICAgICAgIFNlcnZlckNlcnRpZmljYXRlTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5zZXJ2ZXJDZXJ0aWZpY2F0ZU5hbWUpLFxuICAgICAgICBUYWdzOiBjZGsubGlzdE1hcHBlcihjZGsuY2ZuVGFnVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy50YWdzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuU2VydmVyQ2VydGlmaWNhdGVQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblNlcnZlckNlcnRpZmljYXRlUHJvcHM+IHtcbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyA9PSBudWxsID8ge30gOiBwcm9wZXJ0aWVzO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0KHByb3BlcnRpZXMpO1xuICAgIH1cbiAgICBjb25zdCByZXQgPSBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblByb3BlcnR5T2JqZWN0PENmblNlcnZlckNlcnRpZmljYXRlUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjZXJ0aWZpY2F0ZUJvZHknLCAnQ2VydGlmaWNhdGVCb2R5JywgcHJvcGVydGllcy5DZXJ0aWZpY2F0ZUJvZHkgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ2VydGlmaWNhdGVCb2R5KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdjZXJ0aWZpY2F0ZUNoYWluJywgJ0NlcnRpZmljYXRlQ2hhaW4nLCBwcm9wZXJ0aWVzLkNlcnRpZmljYXRlQ2hhaW4gIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuQ2VydGlmaWNhdGVDaGFpbikgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncGF0aCcsICdQYXRoJywgcHJvcGVydGllcy5QYXRoICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlBhdGgpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3ByaXZhdGVLZXknLCAnUHJpdmF0ZUtleScsIHByb3BlcnRpZXMuUHJpdmF0ZUtleSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Qcml2YXRlS2V5KSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdzZXJ2ZXJDZXJ0aWZpY2F0ZU5hbWUnLCAnU2VydmVyQ2VydGlmaWNhdGVOYW1lJywgcHJvcGVydGllcy5TZXJ2ZXJDZXJ0aWZpY2F0ZU5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuU2VydmVyQ2VydGlmaWNhdGVOYW1lKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0YWdzJywgJ1RhZ3MnLCBwcm9wZXJ0aWVzLlRhZ3MgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRDZm5UYWcpKHByb3BlcnRpZXMuVGFncykgOiB1bmRlZmluZWQgYXMgYW55KTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBBIENsb3VkRm9ybWF0aW9uIGBBV1M6OklBTTo6U2VydmVyQ2VydGlmaWNhdGVgXG4gKlxuICogVXBsb2FkcyBhIHNlcnZlciBjZXJ0aWZpY2F0ZSBlbnRpdHkgZm9yIHRoZSBBV1MgYWNjb3VudCAuIFRoZSBzZXJ2ZXIgY2VydGlmaWNhdGUgZW50aXR5IGluY2x1ZGVzIGEgcHVibGljIGtleSBjZXJ0aWZpY2F0ZSwgYSBwcml2YXRlIGtleSwgYW5kIGFuIG9wdGlvbmFsIGNlcnRpZmljYXRlIGNoYWluLCB3aGljaCBzaG91bGQgYWxsIGJlIFBFTS1lbmNvZGVkLlxuICpcbiAqIFdlIHJlY29tbWVuZCB0aGF0IHlvdSB1c2UgW0FXUyBDZXJ0aWZpY2F0ZSBNYW5hZ2VyXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYWNtLykgdG8gcHJvdmlzaW9uLCBtYW5hZ2UsIGFuZCBkZXBsb3kgeW91ciBzZXJ2ZXIgY2VydGlmaWNhdGVzLiBXaXRoIEFDTSB5b3UgY2FuIHJlcXVlc3QgYSBjZXJ0aWZpY2F0ZSwgZGVwbG95IGl0IHRvIEFXUyByZXNvdXJjZXMsIGFuZCBsZXQgQUNNIGhhbmRsZSBjZXJ0aWZpY2F0ZSByZW5ld2FscyBmb3IgeW91LiBDZXJ0aWZpY2F0ZXMgcHJvdmlkZWQgYnkgQUNNIGFyZSBmcmVlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB1c2luZyBBQ00sIHNlZSB0aGUgW0FXUyBDZXJ0aWZpY2F0ZSBNYW5hZ2VyIFVzZXIgR3VpZGVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hY20vbGF0ZXN0L3VzZXJndWlkZS8pIC5cbiAqXG4gKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB3b3JraW5nIHdpdGggc2VydmVyIGNlcnRpZmljYXRlcywgc2VlIFtXb3JraW5nIHdpdGggc2VydmVyIGNlcnRpZmljYXRlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX2NyZWRlbnRpYWxzX3NlcnZlci1jZXJ0cy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuIFRoaXMgdG9waWMgaW5jbHVkZXMgYSBsaXN0IG9mIEFXUyBzZXJ2aWNlcyB0aGF0IGNhbiB1c2UgdGhlIHNlcnZlciBjZXJ0aWZpY2F0ZXMgdGhhdCB5b3UgbWFuYWdlIHdpdGggSUFNLlxuICpcbiAqIEZvciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbnVtYmVyIG9mIHNlcnZlciBjZXJ0aWZpY2F0ZXMgeW91IGNhbiB1cGxvYWQsIHNlZSBbSUFNIGFuZCBBV1MgU1RTIHF1b3Rhc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9pYW0tcXVvdGFzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAqXG4gKiA+IEJlY2F1c2UgdGhlIGJvZHkgb2YgdGhlIHB1YmxpYyBrZXkgY2VydGlmaWNhdGUsIHByaXZhdGUga2V5LCBhbmQgdGhlIGNlcnRpZmljYXRlIGNoYWluIGNhbiBiZSBsYXJnZSwgeW91IHNob3VsZCB1c2UgUE9TVCByYXRoZXIgdGhhbiBHRVQgd2hlbiBjYWxsaW5nIGBVcGxvYWRTZXJ2ZXJDZXJ0aWZpY2F0ZWAgLiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgc2V0dGluZyB1cCBzaWduYXR1cmVzIGFuZCBhdXRob3JpemF0aW9uIHRocm91Z2ggdGhlIEFQSSwgc2VlIFtTaWduaW5nIEFXUyBBUEkgcmVxdWVzdHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nZW5lcmFsL2xhdGVzdC9nci9zaWduaW5nX2F3c19hcGlfcmVxdWVzdHMuaHRtbCkgaW4gdGhlICpBV1MgR2VuZXJhbCBSZWZlcmVuY2UqIC4gRm9yIGdlbmVyYWwgaW5mb3JtYXRpb24gYWJvdXQgdXNpbmcgdGhlIFF1ZXJ5IEFQSSB3aXRoIElBTSwgc2VlIFtDYWxsaW5nIHRoZSBBUEkgYnkgbWFraW5nIEhUVFAgcXVlcnkgcmVxdWVzdHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9wcm9ncmFtbWluZy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpJQU06OlNlcnZlckNlcnRpZmljYXRlXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZlcmNlcnRpZmljYXRlLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmblNlcnZlckNlcnRpZmljYXRlIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6SUFNOjpTZXJ2ZXJDZXJ0aWZpY2F0ZVwiO1xuXG4gICAgLyoqXG4gICAgICogQSBmYWN0b3J5IG1ldGhvZCB0aGF0IGNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmcm9tIGFuIG9iamVjdFxuICAgICAqIGNvbnRhaW5pbmcgdGhlIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgdGhpcyByZXNvdXJjZS5cbiAgICAgKiBVc2VkIGluIHRoZSBAYXdzLWNkay9jbG91ZGZvcm1hdGlvbi1pbmNsdWRlIG1vZHVsZS5cbiAgICAgKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgX2Zyb21DbG91ZEZvcm1hdGlvbihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcmVzb3VyY2VBdHRyaWJ1dGVzOiBhbnksIG9wdGlvbnM6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25PcHRpb25zKTogQ2ZuU2VydmVyQ2VydGlmaWNhdGUge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmblNlcnZlckNlcnRpZmljYXRlUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmblNlcnZlckNlcnRpZmljYXRlKHNjb3BlLCBpZCwgcHJvcHNSZXN1bHQudmFsdWUpO1xuICAgICAgICBmb3IgKGNvbnN0IFtwcm9wS2V5LCBwcm9wVmFsXSBvZiBPYmplY3QuZW50cmllcyhwcm9wc1Jlc3VsdC5leHRyYVByb3BlcnRpZXMpKSAge1xuICAgICAgICAgICAgcmV0LmFkZFByb3BlcnR5T3ZlcnJpZGUocHJvcEtleSwgcHJvcFZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5wYXJzZXIuaGFuZGxlQXR0cmlidXRlcyhyZXQsIHJlc291cmNlQXR0cmlidXRlcywgaWQpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIGZvciB0aGUgc3BlY2lmaWVkIGBBV1M6OklBTTo6U2VydmVyQ2VydGlmaWNhdGVgIHJlc291cmNlLlxuICAgICAqIEBjbG91ZGZvcm1hdGlvbkF0dHJpYnV0ZSBBcm5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgYXR0ckFybjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNvbnRlbnRzIG9mIHRoZSBwdWJsaWMga2V5IGNlcnRpZmljYXRlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZlcmNlcnRpZmljYXRlLmh0bWwjY2ZuLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS1jZXJ0aWZpY2F0ZWJvZHlcbiAgICAgKi9cbiAgICBwdWJsaWMgY2VydGlmaWNhdGVCb2R5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY29udGVudHMgb2YgdGhlIHB1YmxpYyBrZXkgY2VydGlmaWNhdGUgY2hhaW4uXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2VydmVyY2VydGlmaWNhdGUuaHRtbCNjZm4taWFtLXNlcnZlcmNlcnRpZmljYXRlLWNlcnRpZmljYXRlY2hhaW5cbiAgICAgKi9cbiAgICBwdWJsaWMgY2VydGlmaWNhdGVDaGFpbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBhdGggZm9yIHRoZSBzZXJ2ZXIgY2VydGlmaWNhdGUuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHBhdGhzLCBzZWUgW0lBTSBpZGVudGlmaWVyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL1VzaW5nX0lkZW50aWZpZXJzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGlzIG9wdGlvbmFsLiBJZiBpdCBpcyBub3QgaW5jbHVkZWQsIGl0IGRlZmF1bHRzIHRvIGEgc2xhc2ggKC8pLiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgZWl0aGVyIGEgZm9yd2FyZCBzbGFzaCAoLykgYnkgaXRzZWxmIG9yIGEgc3RyaW5nIHRoYXQgbXVzdCBiZWdpbiBhbmQgZW5kIHdpdGggZm9yd2FyZCBzbGFzaGVzLiBJbiBhZGRpdGlvbiwgaXQgY2FuIGNvbnRhaW4gYW55IEFTQ0lJIGNoYXJhY3RlciBmcm9tIHRoZSAhICggYFxcIHUwMDIxYCApIHRocm91Z2ggdGhlIERFTCBjaGFyYWN0ZXIgKCBgXFwgdTAwN0ZgICksIGluY2x1ZGluZyBtb3N0IHB1bmN0dWF0aW9uIGNoYXJhY3RlcnMsIGRpZ2l0cywgYW5kIHVwcGVyIGFuZCBsb3dlcmNhc2VkIGxldHRlcnMuXG4gICAgICpcbiAgICAgKiA+IElmIHlvdSBhcmUgdXBsb2FkaW5nIGEgc2VydmVyIGNlcnRpZmljYXRlIHNwZWNpZmljYWxseSBmb3IgdXNlIHdpdGggQW1hem9uIENsb3VkRnJvbnQgZGlzdHJpYnV0aW9ucywgeW91IG11c3Qgc3BlY2lmeSBhIHBhdGggdXNpbmcgdGhlIGBwYXRoYCBwYXJhbWV0ZXIuIFRoZSBwYXRoIG11c3QgYmVnaW4gd2l0aCBgL2Nsb3VkZnJvbnRgIGFuZCBtdXN0IGluY2x1ZGUgYSB0cmFpbGluZyBzbGFzaCAoZm9yIGV4YW1wbGUsIGAvY2xvdWRmcm9udC90ZXN0L2AgKS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS5odG1sI2Nmbi1pYW0tc2VydmVyY2VydGlmaWNhdGUtcGF0aFxuICAgICAqL1xuICAgIHB1YmxpYyBwYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgY29udGVudHMgb2YgdGhlIHByaXZhdGUga2V5IGluIFBFTS1lbmNvZGVkIGZvcm1hdC5cbiAgICAgKlxuICAgICAqIFRoZSBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpIHVzZWQgdG8gdmFsaWRhdGUgdGhpcyBwYXJhbWV0ZXIgaXMgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIEFueSBwcmludGFibGUgQVNDSUkgY2hhcmFjdGVyIHJhbmdpbmcgZnJvbSB0aGUgc3BhY2UgY2hhcmFjdGVyICggYFxcIHUwMDIwYCApIHRocm91Z2ggdGhlIGVuZCBvZiB0aGUgQVNDSUkgY2hhcmFjdGVyIHJhbmdlXG4gICAgICogLSBUaGUgcHJpbnRhYmxlIGNoYXJhY3RlcnMgaW4gdGhlIEJhc2ljIExhdGluIGFuZCBMYXRpbi0xIFN1cHBsZW1lbnQgY2hhcmFjdGVyIHNldCAodGhyb3VnaCBgXFwgdTAwRkZgIClcbiAgICAgKiAtIFRoZSBzcGVjaWFsIGNoYXJhY3RlcnMgdGFiICggYFxcIHUwMDA5YCApLCBsaW5lIGZlZWQgKCBgXFwgdTAwMEFgICksIGFuZCBjYXJyaWFnZSByZXR1cm4gKCBgXFwgdTAwMERgIClcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS5odG1sI2Nmbi1pYW0tc2VydmVyY2VydGlmaWNhdGUtcHJpdmF0ZWtleVxuICAgICAqL1xuICAgIHB1YmxpYyBwcml2YXRlS2V5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBmb3IgdGhlIHNlcnZlciBjZXJ0aWZpY2F0ZS4gRG8gbm90IGluY2x1ZGUgdGhlIHBhdGggaW4gdGhpcyB2YWx1ZS4gVGhlIG5hbWUgb2YgdGhlIGNlcnRpZmljYXRlIGNhbm5vdCBjb250YWluIGFueSBzcGFjZXMuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdXBwZXIgYW5kIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyB3aXRoIG5vIHNwYWNlcy4gWW91IGNhbiBhbHNvIGluY2x1ZGUgYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogXys9LC5ALVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZlcmNlcnRpZmljYXRlLmh0bWwjY2ZuLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS1zZXJ2ZXJjZXJ0aWZpY2F0ZW5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgc2VydmVyQ2VydGlmaWNhdGVOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgdGFncyB0aGF0IGFyZSBhdHRhY2hlZCB0byB0aGUgc2VydmVyIGNlcnRpZmljYXRlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0YWdnaW5nLCBzZWUgW1RhZ2dpbmcgSUFNIHJlc291cmNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX3RhZ3MuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZlcmNlcnRpZmljYXRlLmh0bWwjY2ZuLWlhbS1zZXJ2ZXJjZXJ0aWZpY2F0ZS10YWdzXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHRhZ3M6IGNkay5UYWdNYW5hZ2VyO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGBBV1M6OklBTTo6U2VydmVyQ2VydGlmaWNhdGVgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmblNlcnZlckNlcnRpZmljYXRlUHJvcHMgPSB7fSkge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIHsgdHlwZTogQ2ZuU2VydmVyQ2VydGlmaWNhdGUuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIHRoaXMuYXR0ckFybiA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnQXJuJykpO1xuXG4gICAgICAgIHRoaXMuY2VydGlmaWNhdGVCb2R5ID0gcHJvcHMuY2VydGlmaWNhdGVCb2R5O1xuICAgICAgICB0aGlzLmNlcnRpZmljYXRlQ2hhaW4gPSBwcm9wcy5jZXJ0aWZpY2F0ZUNoYWluO1xuICAgICAgICB0aGlzLnBhdGggPSBwcm9wcy5wYXRoO1xuICAgICAgICB0aGlzLnByaXZhdGVLZXkgPSBwcm9wcy5wcml2YXRlS2V5O1xuICAgICAgICB0aGlzLnNlcnZlckNlcnRpZmljYXRlTmFtZSA9IHByb3BzLnNlcnZlckNlcnRpZmljYXRlTmFtZTtcbiAgICAgICAgdGhpcy50YWdzID0gbmV3IGNkay5UYWdNYW5hZ2VyKGNkay5UYWdUeXBlLlNUQU5EQVJELCBcIkFXUzo6SUFNOjpTZXJ2ZXJDZXJ0aWZpY2F0ZVwiLCBwcm9wcy50YWdzLCB7IHRhZ1Byb3BlcnR5TmFtZTogJ3RhZ3MnIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4YW1pbmVzIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBhbmQgZGlzY2xvc2VzIGF0dHJpYnV0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5zcGVjdG9yIC0gdHJlZSBpbnNwZWN0b3IgdG8gY29sbGVjdCBhbmQgcHJvY2VzcyBhdHRyaWJ1dGVzXG4gICAgICpcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5zcGVjdChpbnNwZWN0b3I6IGNkay5UcmVlSW5zcGVjdG9yKSB7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnR5cGVcIiwgQ2ZuU2VydmVyQ2VydGlmaWNhdGUuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSk7XG4gICAgICAgIGluc3BlY3Rvci5hZGRBdHRyaWJ1dGUoXCJhd3M6Y2RrOmNsb3VkZm9ybWF0aW9uOnByb3BzXCIsIHRoaXMuY2ZuUHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBjZm5Qcm9wZXJ0aWVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0gIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNlcnRpZmljYXRlQm9keTogdGhpcy5jZXJ0aWZpY2F0ZUJvZHksXG4gICAgICAgICAgICBjZXJ0aWZpY2F0ZUNoYWluOiB0aGlzLmNlcnRpZmljYXRlQ2hhaW4sXG4gICAgICAgICAgICBwYXRoOiB0aGlzLnBhdGgsXG4gICAgICAgICAgICBwcml2YXRlS2V5OiB0aGlzLnByaXZhdGVLZXksXG4gICAgICAgICAgICBzZXJ2ZXJDZXJ0aWZpY2F0ZU5hbWU6IHRoaXMuc2VydmVyQ2VydGlmaWNhdGVOYW1lLFxuICAgICAgICAgICAgdGFnczogdGhpcy50YWdzLnJlbmRlclRhZ3MoKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5TZXJ2ZXJDZXJ0aWZpY2F0ZVByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmblNlcnZpY2VMaW5rZWRSb2xlYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2VydmljZWxpbmtlZHJvbGUuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENmblNlcnZpY2VMaW5rZWRSb2xlUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogVGhlIHNlcnZpY2UgcHJpbmNpcGFsIGZvciB0aGUgQVdTIHNlcnZpY2UgdG8gd2hpY2ggdGhpcyByb2xlIGlzIGF0dGFjaGVkLiBZb3UgdXNlIGEgc3RyaW5nIHNpbWlsYXIgdG8gYSBVUkwgYnV0IHdpdGhvdXQgdGhlIGh0dHA6Ly8gaW4gZnJvbnQuIEZvciBleGFtcGxlOiBgZWxhc3RpY2JlYW5zdGFsay5hbWF6b25hd3MuY29tYCAuXG4gICAgICpcbiAgICAgKiBTZXJ2aWNlIHByaW5jaXBhbHMgYXJlIHVuaXF1ZSBhbmQgY2FzZS1zZW5zaXRpdmUuIFRvIGZpbmQgdGhlIGV4YWN0IHNlcnZpY2UgcHJpbmNpcGFsIGZvciB5b3VyIHNlcnZpY2UtbGlua2VkIHJvbGUsIHNlZSBbQVdTIHNlcnZpY2VzIHRoYXQgd29yayB3aXRoIElBTV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9hd3Mtc2VydmljZXMtdGhhdC13b3JrLXdpdGgtaWFtLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC4gTG9vayBmb3IgdGhlIHNlcnZpY2VzIHRoYXQgaGF2ZSAqWWVzKiBpbiB0aGUgKlNlcnZpY2UtTGlua2VkIFJvbGUqIGNvbHVtbi4gQ2hvb3NlIHRoZSAqWWVzKiBsaW5rIHRvIHZpZXcgdGhlIHNlcnZpY2UtbGlua2VkIHJvbGUgZG9jdW1lbnRhdGlvbiBmb3IgdGhhdCBzZXJ2aWNlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZpY2VsaW5rZWRyb2xlLmh0bWwjY2ZuLWlhbS1zZXJ2aWNlbGlua2Vkcm9sZS1hd3NzZXJ2aWNlbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IGF3c1NlcnZpY2VOYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBIHN0cmluZyB0aGF0IHlvdSBwcm92aWRlLCB3aGljaCBpcyBjb21iaW5lZCB3aXRoIHRoZSBzZXJ2aWNlLXByb3ZpZGVkIHByZWZpeCB0byBmb3JtIHRoZSBjb21wbGV0ZSByb2xlIG5hbWUuIElmIHlvdSBtYWtlIG11bHRpcGxlIHJlcXVlc3RzIGZvciB0aGUgc2FtZSBzZXJ2aWNlLCB0aGVuIHlvdSBtdXN0IHN1cHBseSBhIGRpZmZlcmVudCBgQ3VzdG9tU3VmZml4YCBmb3IgZWFjaCByZXF1ZXN0LiBPdGhlcndpc2UgdGhlIHJlcXVlc3QgZmFpbHMgd2l0aCBhIGR1cGxpY2F0ZSByb2xlIG5hbWUgZXJyb3IuIEZvciBleGFtcGxlLCB5b3UgY291bGQgYWRkIGAtMWAgb3IgYC1kZWJ1Z2AgdG8gdGhlIHN1ZmZpeC5cbiAgICAgKlxuICAgICAqIFNvbWUgc2VydmljZXMgZG8gbm90IHN1cHBvcnQgdGhlIGBDdXN0b21TdWZmaXhgIHBhcmFtZXRlci4gSWYgeW91IHByb3ZpZGUgYW4gb3B0aW9uYWwgc3VmZml4IGFuZCB0aGUgb3BlcmF0aW9uIGZhaWxzLCB0cnkgdGhlIG9wZXJhdGlvbiBhZ2FpbiB3aXRob3V0IHRoZSBzdWZmaXguXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tc2VydmljZWxpbmtlZHJvbGUuaHRtbCNjZm4taWFtLXNlcnZpY2VsaW5rZWRyb2xlLWN1c3RvbXN1ZmZpeFxuICAgICAqL1xuICAgIHJlYWRvbmx5IGN1c3RvbVN1ZmZpeD86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgcm9sZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2aWNlbGlua2Vkcm9sZS5odG1sI2Nmbi1pYW0tc2VydmljZWxpbmtlZHJvbGUtZGVzY3JpcHRpb25cbiAgICAgKi9cbiAgICByZWFkb25seSBkZXNjcmlwdGlvbj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDZm5TZXJ2aWNlTGlua2VkUm9sZVByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5TZXJ2aWNlTGlua2VkUm9sZVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblNlcnZpY2VMaW5rZWRSb2xlUHJvcHNWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdhd3NTZXJ2aWNlTmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5hd3NTZXJ2aWNlTmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignYXdzU2VydmljZU5hbWUnLCBjZGsudmFsaWRhdGVTdHJpbmcpKHByb3BlcnRpZXMuYXdzU2VydmljZU5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2N1c3RvbVN1ZmZpeCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5jdXN0b21TdWZmaXgpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2Rlc2NyaXB0aW9uJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLmRlc2NyaXB0aW9uKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmblNlcnZpY2VMaW5rZWRSb2xlUHJvcHNcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6U2VydmljZUxpbmtlZFJvbGVgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblNlcnZpY2VMaW5rZWRSb2xlUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6U2VydmljZUxpbmtlZFJvbGVgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuU2VydmljZUxpbmtlZFJvbGVQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuU2VydmljZUxpbmtlZFJvbGVQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgQVdTU2VydmljZU5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuYXdzU2VydmljZU5hbWUpLFxuICAgICAgICBDdXN0b21TdWZmaXg6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuY3VzdG9tU3VmZml4KSxcbiAgICAgICAgRGVzY3JpcHRpb246IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZGVzY3JpcHRpb24pLFxuICAgIH07XG59XG5cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBDZm5TZXJ2aWNlTGlua2VkUm9sZVByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuU2VydmljZUxpbmtlZFJvbGVQcm9wcz4ge1xuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuU2VydmljZUxpbmtlZFJvbGVQcm9wcz4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ2F3c1NlcnZpY2VOYW1lJywgJ0FXU1NlcnZpY2VOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5BV1NTZXJ2aWNlTmFtZSkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnY3VzdG9tU3VmZml4JywgJ0N1c3RvbVN1ZmZpeCcsIHByb3BlcnRpZXMuQ3VzdG9tU3VmZml4ICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkN1c3RvbVN1ZmZpeCkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZGVzY3JpcHRpb24nLCAnRGVzY3JpcHRpb24nLCBwcm9wZXJ0aWVzLkRlc2NyaXB0aW9uICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLkRlc2NyaXB0aW9uKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpJQU06OlNlcnZpY2VMaW5rZWRSb2xlYFxuICpcbiAqIENyZWF0ZXMgYW4gSUFNIHJvbGUgdGhhdCBpcyBsaW5rZWQgdG8gYSBzcGVjaWZpYyBBV1Mgc2VydmljZS4gVGhlIHNlcnZpY2UgY29udHJvbHMgdGhlIGF0dGFjaGVkIHBvbGljaWVzIGFuZCB3aGVuIHRoZSByb2xlIGNhbiBiZSBkZWxldGVkLiBUaGlzIGhlbHBzIGVuc3VyZSB0aGF0IHRoZSBzZXJ2aWNlIGlzIG5vdCBicm9rZW4gYnkgYW4gdW5leHBlY3RlZGx5IGNoYW5nZWQgb3IgZGVsZXRlZCByb2xlLCB3aGljaCBjb3VsZCBwdXQgeW91ciBBV1MgcmVzb3VyY2VzIGludG8gYW4gdW5rbm93biBzdGF0ZS4gQWxsb3dpbmcgdGhlIHNlcnZpY2UgdG8gY29udHJvbCB0aGUgcm9sZSBoZWxwcyBpbXByb3ZlIHNlcnZpY2Ugc3RhYmlsaXR5IGFuZCBwcm9wZXIgY2xlYW51cCB3aGVuIGEgc2VydmljZSBhbmQgaXRzIHJvbGUgYXJlIG5vIGxvbmdlciBuZWVkZWQuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW1VzaW5nIHNlcnZpY2UtbGlua2VkIHJvbGVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvdXNpbmctc2VydmljZS1saW5rZWQtcm9sZXMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICpcbiAqIFRvIGF0dGFjaCBhIHBvbGljeSB0byB0aGlzIHNlcnZpY2UtbGlua2VkIHJvbGUsIHlvdSBtdXN0IG1ha2UgdGhlIHJlcXVlc3QgdXNpbmcgdGhlIEFXUyBzZXJ2aWNlIHRoYXQgZGVwZW5kcyBvbiB0aGlzIHJvbGUuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpJQU06OlNlcnZpY2VMaW5rZWRSb2xlXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZpY2VsaW5rZWRyb2xlLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmblNlcnZpY2VMaW5rZWRSb2xlIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6SUFNOjpTZXJ2aWNlTGlua2VkUm9sZVwiO1xuXG4gICAgLyoqXG4gICAgICogQSBmYWN0b3J5IG1ldGhvZCB0aGF0IGNyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBmcm9tIGFuIG9iamVjdFxuICAgICAqIGNvbnRhaW5pbmcgdGhlIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgdGhpcyByZXNvdXJjZS5cbiAgICAgKiBVc2VkIGluIHRoZSBAYXdzLWNkay9jbG91ZGZvcm1hdGlvbi1pbmNsdWRlIG1vZHVsZS5cbiAgICAgKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgX2Zyb21DbG91ZEZvcm1hdGlvbihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcmVzb3VyY2VBdHRyaWJ1dGVzOiBhbnksIG9wdGlvbnM6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25PcHRpb25zKTogQ2ZuU2VydmljZUxpbmtlZFJvbGUge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmblNlcnZpY2VMaW5rZWRSb2xlUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmblNlcnZpY2VMaW5rZWRSb2xlKHNjb3BlLCBpZCwgcHJvcHNSZXN1bHQudmFsdWUpO1xuICAgICAgICBmb3IgKGNvbnN0IFtwcm9wS2V5LCBwcm9wVmFsXSBvZiBPYmplY3QuZW50cmllcyhwcm9wc1Jlc3VsdC5leHRyYVByb3BlcnRpZXMpKSAge1xuICAgICAgICAgICAgcmV0LmFkZFByb3BlcnR5T3ZlcnJpZGUocHJvcEtleSwgcHJvcFZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucy5wYXJzZXIuaGFuZGxlQXR0cmlidXRlcyhyZXQsIHJlc291cmNlQXR0cmlidXRlcywgaWQpO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzZXJ2aWNlIHByaW5jaXBhbCBmb3IgdGhlIEFXUyBzZXJ2aWNlIHRvIHdoaWNoIHRoaXMgcm9sZSBpcyBhdHRhY2hlZC4gWW91IHVzZSBhIHN0cmluZyBzaW1pbGFyIHRvIGEgVVJMIGJ1dCB3aXRob3V0IHRoZSBodHRwOi8vIGluIGZyb250LiBGb3IgZXhhbXBsZTogYGVsYXN0aWNiZWFuc3RhbGsuYW1hem9uYXdzLmNvbWAgLlxuICAgICAqXG4gICAgICogU2VydmljZSBwcmluY2lwYWxzIGFyZSB1bmlxdWUgYW5kIGNhc2Utc2Vuc2l0aXZlLiBUbyBmaW5kIHRoZSBleGFjdCBzZXJ2aWNlIHByaW5jaXBhbCBmb3IgeW91ciBzZXJ2aWNlLWxpbmtlZCByb2xlLCBzZWUgW0FXUyBzZXJ2aWNlcyB0aGF0IHdvcmsgd2l0aCBJQU1dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfYXdzLXNlcnZpY2VzLXRoYXQtd29yay13aXRoLWlhbS5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuIExvb2sgZm9yIHRoZSBzZXJ2aWNlcyB0aGF0IGhhdmUgKlllcyogaW4gdGhlICpTZXJ2aWNlLUxpbmtlZCBSb2xlKiBjb2x1bW4uIENob29zZSB0aGUgKlllcyogbGluayB0byB2aWV3IHRoZSBzZXJ2aWNlLWxpbmtlZCByb2xlIGRvY3VtZW50YXRpb24gZm9yIHRoYXQgc2VydmljZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2aWNlbGlua2Vkcm9sZS5odG1sI2Nmbi1pYW0tc2VydmljZWxpbmtlZHJvbGUtYXdzc2VydmljZW5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgYXdzU2VydmljZU5hbWU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEEgc3RyaW5nIHRoYXQgeW91IHByb3ZpZGUsIHdoaWNoIGlzIGNvbWJpbmVkIHdpdGggdGhlIHNlcnZpY2UtcHJvdmlkZWQgcHJlZml4IHRvIGZvcm0gdGhlIGNvbXBsZXRlIHJvbGUgbmFtZS4gSWYgeW91IG1ha2UgbXVsdGlwbGUgcmVxdWVzdHMgZm9yIHRoZSBzYW1lIHNlcnZpY2UsIHRoZW4geW91IG11c3Qgc3VwcGx5IGEgZGlmZmVyZW50IGBDdXN0b21TdWZmaXhgIGZvciBlYWNoIHJlcXVlc3QuIE90aGVyd2lzZSB0aGUgcmVxdWVzdCBmYWlscyB3aXRoIGEgZHVwbGljYXRlIHJvbGUgbmFtZSBlcnJvci4gRm9yIGV4YW1wbGUsIHlvdSBjb3VsZCBhZGQgYC0xYCBvciBgLWRlYnVnYCB0byB0aGUgc3VmZml4LlxuICAgICAqXG4gICAgICogU29tZSBzZXJ2aWNlcyBkbyBub3Qgc3VwcG9ydCB0aGUgYEN1c3RvbVN1ZmZpeGAgcGFyYW1ldGVyLiBJZiB5b3UgcHJvdmlkZSBhbiBvcHRpb25hbCBzdWZmaXggYW5kIHRoZSBvcGVyYXRpb24gZmFpbHMsIHRyeSB0aGUgb3BlcmF0aW9uIGFnYWluIHdpdGhvdXQgdGhlIHN1ZmZpeC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS1zZXJ2aWNlbGlua2Vkcm9sZS5odG1sI2Nmbi1pYW0tc2VydmljZWxpbmtlZHJvbGUtY3VzdG9tc3VmZml4XG4gICAgICovXG4gICAgcHVibGljIGN1c3RvbVN1ZmZpeDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGRlc2NyaXB0aW9uIG9mIHRoZSByb2xlLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXNlcnZpY2VsaW5rZWRyb2xlLmh0bWwjY2ZuLWlhbS1zZXJ2aWNlbGlua2Vkcm9sZS1kZXNjcmlwdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBkZXNjcmlwdGlvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGBBV1M6OklBTTo6U2VydmljZUxpbmtlZFJvbGVgLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNjb3BlIC0gc2NvcGUgaW4gd2hpY2ggdGhpcyByZXNvdXJjZSBpcyBkZWZpbmVkXG4gICAgICogQHBhcmFtIGlkICAgIC0gc2NvcGVkIGlkIG9mIHRoZSByZXNvdXJjZVxuICAgICAqIEBwYXJhbSBwcm9wcyAtIHJlc291cmNlIHByb3BlcnRpZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENmblNlcnZpY2VMaW5rZWRSb2xlUHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmblNlcnZpY2VMaW5rZWRSb2xlLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUsIHByb3BlcnRpZXM6IHByb3BzIH0pO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAnYXdzU2VydmljZU5hbWUnLCB0aGlzKTtcblxuICAgICAgICB0aGlzLmF3c1NlcnZpY2VOYW1lID0gcHJvcHMuYXdzU2VydmljZU5hbWU7XG4gICAgICAgIHRoaXMuY3VzdG9tU3VmZml4ID0gcHJvcHMuY3VzdG9tU3VmZml4O1xuICAgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gcHJvcHMuZGVzY3JpcHRpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5TZXJ2aWNlTGlua2VkUm9sZS5DRk5fUkVTT1VSQ0VfVFlQRV9OQU1FKTtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246cHJvcHNcIiwgdGhpcy5jZm5Qcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGNmblByb3BlcnRpZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYXdzU2VydmljZU5hbWU6IHRoaXMuYXdzU2VydmljZU5hbWUsXG4gICAgICAgICAgICBjdXN0b21TdWZmaXg6IHRoaXMuY3VzdG9tU3VmZml4LFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHRoaXMuZGVzY3JpcHRpb24sXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuU2VydmljZUxpbmtlZFJvbGVQcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcHMpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5Vc2VyYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5Vc2VyUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIGdyb3VwIG5hbWVzIHRvIHdoaWNoIHlvdSB3YW50IHRvIGFkZCB0aGUgdXNlci5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXVzZXIuaHRtbCNjZm4taWFtLXVzZXItZ3JvdXBzXG4gICAgICovXG4gICAgcmVhZG9ubHkgZ3JvdXBzPzogc3RyaW5nW107XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGFzc3dvcmQgZm9yIHRoZSBzcGVjaWZpZWQgSUFNIHVzZXIuIEEgcGFzc3dvcmQgYWxsb3dzIGFuIElBTSB1c2VyIHRvIGFjY2VzcyBBV1Mgc2VydmljZXMgdGhyb3VnaCB0aGUgQVdTIE1hbmFnZW1lbnQgQ29uc29sZSAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGUgQVdTIENMSSAsIHRoZSBBV1MgQVBJLCBvciB0aGUgKlVzZXJzKiBwYWdlIGluIHRoZSBJQU0gY29uc29sZSB0byBjcmVhdGUgYSBwYXNzd29yZCBmb3IgYW55IElBTSB1c2VyLiBVc2UgW0NoYW5nZVBhc3N3b3JkXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NoYW5nZVBhc3N3b3JkLmh0bWwpIHRvIHVwZGF0ZSB5b3VyIG93biBleGlzdGluZyBwYXNzd29yZCBpbiB0aGUgKk15IFNlY3VyaXR5IENyZWRlbnRpYWxzKiBwYWdlIGluIHRoZSBBV1MgTWFuYWdlbWVudCBDb25zb2xlIC5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IG1hbmFnaW5nIHBhc3N3b3Jkcywgc2VlIFtNYW5hZ2luZyBwYXNzd29yZHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19NYW5hZ2luZ0xvZ2lucy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLmh0bWwjY2ZuLWlhbS11c2VyLWxvZ2lucHJvZmlsZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IGxvZ2luUHJvZmlsZT86IENmblVzZXIuTG9naW5Qcm9maWxlUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU7XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgQW1hem9uIFJlc291cmNlIE5hbWVzIChBUk5zKSBvZiB0aGUgSUFNIG1hbmFnZWQgcG9saWNpZXMgdGhhdCB5b3Ugd2FudCB0byBhdHRhY2ggdG8gdGhlIHVzZXIuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBBUk5zLCBzZWUgW0FtYXpvbiBSZXNvdXJjZSBOYW1lcyAoQVJOcykgYW5kIEFXUyBTZXJ2aWNlIE5hbWVzcGFjZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nZW5lcmFsL2xhdGVzdC9nci9hd3MtYXJucy1hbmQtbmFtZXNwYWNlcy5odG1sKSBpbiB0aGUgKkFXUyBHZW5lcmFsIFJlZmVyZW5jZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tdXNlci5odG1sI2Nmbi1pYW0tdXNlci1tYW5hZ2Vwb2xpY3lhcm5zXG4gICAgICovXG4gICAgcmVhZG9ubHkgbWFuYWdlZFBvbGljeUFybnM/OiBzdHJpbmdbXTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwYXRoIGZvciB0aGUgdXNlciBuYW1lLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gaWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiBlaXRoZXIgYSBmb3J3YXJkIHNsYXNoICgvKSBieSBpdHNlbGYgb3IgYSBzdHJpbmcgdGhhdCBtdXN0IGJlZ2luIGFuZCBlbmQgd2l0aCBmb3J3YXJkIHNsYXNoZXMuIEluIGFkZGl0aW9uLCBpdCBjYW4gY29udGFpbiBhbnkgQVNDSUkgY2hhcmFjdGVyIGZyb20gdGhlICEgKCBgXFwgdTAwMjFgICkgdGhyb3VnaCB0aGUgREVMIGNoYXJhY3RlciAoIGBcXCB1MDA3RmAgKSwgaW5jbHVkaW5nIG1vc3QgcHVuY3R1YXRpb24gY2hhcmFjdGVycywgZGlnaXRzLCBhbmQgdXBwZXIgYW5kIGxvd2VyY2FzZWQgbGV0dGVycy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXVzZXIuaHRtbCNjZm4taWFtLXVzZXItcGF0aFxuICAgICAqL1xuICAgIHJlYWRvbmx5IHBhdGg/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQVJOIG9mIHRoZSBtYW5hZ2VkIHBvbGljeSB0aGF0IGlzIHVzZWQgdG8gc2V0IHRoZSBwZXJtaXNzaW9ucyBib3VuZGFyeSBmb3IgdGhlIHVzZXIuXG4gICAgICpcbiAgICAgKiBBIHBlcm1pc3Npb25zIGJvdW5kYXJ5IHBvbGljeSBkZWZpbmVzIHRoZSBtYXhpbXVtIHBlcm1pc3Npb25zIHRoYXQgaWRlbnRpdHktYmFzZWQgcG9saWNpZXMgY2FuIGdyYW50IHRvIGFuIGVudGl0eSwgYnV0IGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb25zLiBQZXJtaXNzaW9ucyBib3VuZGFyaWVzIGRvIG5vdCBkZWZpbmUgdGhlIG1heGltdW0gcGVybWlzc2lvbnMgdGhhdCBhIHJlc291cmNlLWJhc2VkIHBvbGljeSBjYW4gZ3JhbnQgdG8gYW4gZW50aXR5LiBUbyBsZWFybiBtb3JlLCBzZWUgW1Blcm1pc3Npb25zIGJvdW5kYXJpZXMgZm9yIElBTSBlbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2FjY2Vzc19wb2xpY2llc19ib3VuZGFyaWVzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHBvbGljeSB0eXBlcywgc2VlIFtQb2xpY3kgdHlwZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9hY2Nlc3NfcG9saWNpZXMuaHRtbCNhY2Nlc3NfcG9saWN5LXR5cGVzKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLmh0bWwjY2ZuLWlhbS11c2VyLXBlcm1pc3Npb25zYm91bmRhcnlcbiAgICAgKi9cbiAgICByZWFkb25seSBwZXJtaXNzaW9uc0JvdW5kYXJ5Pzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBvciB1cGRhdGVzIGFuIGlubGluZSBwb2xpY3kgZG9jdW1lbnQgdGhhdCBpcyBlbWJlZGRlZCBpbiB0aGUgc3BlY2lmaWVkIElBTSB1c2VyLiBUbyB2aWV3IEFXUzo6SUFNOjpVc2VyIHNuaXBwZXRzLCBzZWUgW0RlY2xhcmluZyBhbiBJQU0gVXNlciBSZXNvdXJjZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvcXVpY2tyZWYtaWFtLmh0bWwjc2NlbmFyaW8taWFtLXVzZXIpIC5cbiAgICAgKlxuICAgICAqID4gVGhlIG5hbWUgb2YgZWFjaCBwb2xpY3kgZm9yIGEgcm9sZSwgdXNlciwgb3IgZ3JvdXAgbXVzdCBiZSB1bmlxdWUuIElmIHlvdSBkb24ndCBjaG9vc2UgdW5pcXVlIG5hbWVzLCB1cGRhdGVzIHRvIHRoZSBJQU0gaWRlbnRpdHkgd2lsbCBmYWlsLlxuICAgICAqXG4gICAgICogRm9yIGluZm9ybWF0aW9uIGFib3V0IGxpbWl0cyBvbiB0aGUgbnVtYmVyIG9mIGlubGluZSBwb2xpY2llcyB0aGF0IHlvdSBjYW4gZW1iZWQgaW4gYSB1c2VyLCBzZWUgW0xpbWl0YXRpb25zIG9uIElBTSBFbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL0xpbWl0YXRpb25zT25FbnRpdGllcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLmh0bWwjY2ZuLWlhbS11c2VyLXBvbGljaWVzXG4gICAgICovXG4gICAgcmVhZG9ubHkgcG9saWNpZXM/OiBBcnJheTxDZm5Vc2VyLlBvbGljeVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZTtcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiB0YWdzIHRoYXQgeW91IHdhbnQgdG8gYXR0YWNoIHRvIHRoZSBuZXcgdXNlci4gRWFjaCB0YWcgY29uc2lzdHMgb2YgYSBrZXkgbmFtZSBhbmQgYW4gYXNzb2NpYXRlZCB2YWx1ZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGFnZ2luZywgc2VlIFtUYWdnaW5nIElBTSByZXNvdXJjZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF90YWdzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqID4gSWYgYW55IG9uZSBvZiB0aGUgdGFncyBpcyBpbnZhbGlkIG9yIGlmIHlvdSBleGNlZWQgdGhlIGFsbG93ZWQgbWF4aW11bSBudW1iZXIgb2YgdGFncywgdGhlbiB0aGUgZW50aXJlIHJlcXVlc3QgZmFpbHMgYW5kIHRoZSByZXNvdXJjZSBpcyBub3QgY3JlYXRlZC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXVzZXIuaHRtbCNjZm4taWFtLXVzZXItdGFnc1xuICAgICAqL1xuICAgIHJlYWRvbmx5IHRhZ3M/OiBjZGsuQ2ZuVGFnW107XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgdXNlciB0byBjcmVhdGUuIERvIG5vdCBpbmNsdWRlIHRoZSBwYXRoIGluIHRoaXMgdmFsdWUuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHBlciBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiB1cHBlciBhbmQgbG93ZXJjYXNlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIHdpdGggbm8gc3BhY2VzLiBZb3UgY2FuIGFsc28gaW5jbHVkZSBhbnkgb2YgdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBfKz0sLkAtLiBUaGUgdXNlciBuYW1lIG11c3QgYmUgdW5pcXVlIHdpdGhpbiB0aGUgYWNjb3VudC4gVXNlciBuYW1lcyBhcmUgbm90IGRpc3Rpbmd1aXNoZWQgYnkgY2FzZS4gRm9yIGV4YW1wbGUsIHlvdSBjYW5ub3QgY3JlYXRlIHVzZXJzIG5hbWVkIGJvdGggXCJKb2huXCIgYW5kIFwiam9oblwiLlxuICAgICAqXG4gICAgICogSWYgeW91IGRvbid0IHNwZWNpZnkgYSBuYW1lLCBBV1MgQ2xvdWRGb3JtYXRpb24gZ2VuZXJhdGVzIGEgdW5pcXVlIHBoeXNpY2FsIElEIGFuZCB1c2VzIHRoYXQgSUQgZm9yIHRoZSB1c2VyIG5hbWUuXG4gICAgICpcbiAgICAgKiBJZiB5b3Ugc3BlY2lmeSBhIG5hbWUsIHlvdSBtdXN0IHNwZWNpZnkgdGhlIGBDQVBBQklMSVRZX05BTUVEX0lBTWAgdmFsdWUgdG8gYWNrbm93bGVkZ2UgeW91ciB0ZW1wbGF0ZSdzIGNhcGFiaWxpdGllcy4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQWNrbm93bGVkZ2luZyBJQU0gUmVzb3VyY2VzIGluIEFXUyBDbG91ZEZvcm1hdGlvbiBUZW1wbGF0ZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL3VzaW5nLWlhbS10ZW1wbGF0ZS5odG1sI3VzaW5nLWlhbS1jYXBhYmlsaXRpZXMpIC5cbiAgICAgKlxuICAgICAqID4gTmFtaW5nIGFuIElBTSByZXNvdXJjZSBjYW4gY2F1c2UgYW4gdW5yZWNvdmVyYWJsZSBlcnJvciBpZiB5b3UgcmV1c2UgdGhlIHNhbWUgdGVtcGxhdGUgaW4gbXVsdGlwbGUgUmVnaW9ucy4gVG8gcHJldmVudCB0aGlzLCB3ZSByZWNvbW1lbmQgdXNpbmcgYEZuOjpKb2luYCBhbmQgYEFXUzo6UmVnaW9uYCB0byBjcmVhdGUgYSBSZWdpb24tc3BlY2lmaWMgbmFtZSwgYXMgaW4gdGhlIGZvbGxvd2luZyBleGFtcGxlOiBge1wiRm46OkpvaW5cIjogW1wiXCIsIFt7XCJSZWZcIjogXCJBV1M6OlJlZ2lvblwifSwge1wiUmVmXCI6IFwiTXlSZXNvdXJjZU5hbWVcIn1dXX1gIC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXVzZXIuaHRtbCNjZm4taWFtLXVzZXItdXNlcm5hbWVcbiAgICAgKi9cbiAgICByZWFkb25seSB1c2VyTmFtZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBDZm5Vc2VyUHJvcHNgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblVzZXJQcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB2YWxpZGF0aW9uLlxuICovXG5mdW5jdGlvbiBDZm5Vc2VyUHJvcHNWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdncm91cHMnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLmdyb3VwcykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcignbG9naW5Qcm9maWxlJywgQ2ZuVXNlcl9Mb2dpblByb2ZpbGVQcm9wZXJ0eVZhbGlkYXRvcikocHJvcGVydGllcy5sb2dpblByb2ZpbGUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ21hbmFnZWRQb2xpY3lBcm5zJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlU3RyaW5nKSkocHJvcGVydGllcy5tYW5hZ2VkUG9saWN5QXJucykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncGF0aCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5wYXRoKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwZXJtaXNzaW9uc0JvdW5kYXJ5JywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnBlcm1pc3Npb25zQm91bmRhcnkpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvbGljaWVzJywgY2RrLmxpc3RWYWxpZGF0b3IoQ2ZuVXNlcl9Qb2xpY3lQcm9wZXJ0eVZhbGlkYXRvcikpKHByb3BlcnRpZXMucG9saWNpZXMpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3RhZ3MnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVDZm5UYWcpKShwcm9wZXJ0aWVzLnRhZ3MpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3VzZXJOYW1lJywgY2RrLnZhbGlkYXRlU3RyaW5nKShwcm9wZXJ0aWVzLnVzZXJOYW1lKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIkNmblVzZXJQcm9wc1wiJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpVc2VyYCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5Vc2VyUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6VXNlcmAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5Vc2VyUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblVzZXJQcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgR3JvdXBzOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5ncm91cHMpLFxuICAgICAgICBMb2dpblByb2ZpbGU6IGNmblVzZXJMb2dpblByb2ZpbGVQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5sb2dpblByb2ZpbGUpLFxuICAgICAgICBNYW5hZ2VkUG9saWN5QXJuczogY2RrLmxpc3RNYXBwZXIoY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24pKHByb3BlcnRpZXMubWFuYWdlZFBvbGljeUFybnMpLFxuICAgICAgICBQYXRoOiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBhdGgpLFxuICAgICAgICBQZXJtaXNzaW9uc0JvdW5kYXJ5OiBjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBlcm1pc3Npb25zQm91bmRhcnkpLFxuICAgICAgICBQb2xpY2llczogY2RrLmxpc3RNYXBwZXIoY2ZuVXNlclBvbGljeVByb3BlcnR5VG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5wb2xpY2llcyksXG4gICAgICAgIFRhZ3M6IGNkay5saXN0TWFwcGVyKGNkay5jZm5UYWdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnRhZ3MpLFxuICAgICAgICBVc2VyTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy51c2VyTmFtZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblVzZXJQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblVzZXJQcm9wcz4ge1xuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVXNlclByb3BzPigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnZ3JvdXBzJywgJ0dyb3VwcycsIHByb3BlcnRpZXMuR3JvdXBzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuR3JvdXBzKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdsb2dpblByb2ZpbGUnLCAnTG9naW5Qcm9maWxlJywgcHJvcGVydGllcy5Mb2dpblByb2ZpbGUgIT0gbnVsbCA/IENmblVzZXJMb2dpblByb2ZpbGVQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLkxvZ2luUHJvZmlsZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgnbWFuYWdlZFBvbGljeUFybnMnLCAnTWFuYWdlZFBvbGljeUFybnMnLCBwcm9wZXJ0aWVzLk1hbmFnZWRQb2xpY3lBcm5zICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuTWFuYWdlZFBvbGljeUFybnMpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BhdGgnLCAnUGF0aCcsIHByb3BlcnRpZXMuUGF0aCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5QYXRoKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwZXJtaXNzaW9uc0JvdW5kYXJ5JywgJ1Blcm1pc3Npb25zQm91bmRhcnknLCBwcm9wZXJ0aWVzLlBlcm1pc3Npb25zQm91bmRhcnkgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuUGVybWlzc2lvbnNCb3VuZGFyeSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncG9saWNpZXMnLCAnUG9saWNpZXMnLCBwcm9wZXJ0aWVzLlBvbGljaWVzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KENmblVzZXJQb2xpY3lQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy5Qb2xpY2llcykgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndGFncycsICdUYWdzJywgcHJvcGVydGllcy5UYWdzICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFycmF5KGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0Q2ZuVGFnKShwcm9wZXJ0aWVzLlRhZ3MpIDogdW5kZWZpbmVkIGFzIGFueSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd1c2VyTmFtZScsICdVc2VyTmFtZScsIHByb3BlcnRpZXMuVXNlck5hbWUgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0U3RyaW5nKHByb3BlcnRpZXMuVXNlck5hbWUpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBBIENsb3VkRm9ybWF0aW9uIGBBV1M6OklBTTo6VXNlcmBcbiAqXG4gKiBDcmVhdGVzIGEgbmV3IElBTSB1c2VyIGZvciB5b3VyIEFXUyBhY2NvdW50IC5cbiAqXG4gKiBGb3IgaW5mb3JtYXRpb24gYWJvdXQgcXVvdGFzIGZvciB0aGUgbnVtYmVyIG9mIElBTSB1c2VycyB5b3UgY2FuIGNyZWF0ZSwgc2VlIFtJQU0gYW5kIEFXUyBTVFMgcXVvdGFzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX2lhbS1xdW90YXMuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICpcbiAqIEBjbG91ZGZvcm1hdGlvblJlc291cmNlIEFXUzo6SUFNOjpVc2VyXG4gKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gKlxuICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tdXNlci5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5Vc2VyIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6SUFNOjpVc2VyXCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5Vc2VyIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5Vc2VyUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmblVzZXIoc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgZm9yIHRoZSBzcGVjaWZpZWQgYEFXUzo6SUFNOjpVc2VyYCByZXNvdXJjZS4gRm9yIGV4YW1wbGU6IGBhcm46YXdzOmlhbTo6MTIzNDU2Nzg5MDEyOnVzZXIvbXlzdGFjay1teXVzZXItMUNDWEFGRzJIMlU0RGAgLlxuICAgICAqIEBjbG91ZGZvcm1hdGlvbkF0dHJpYnV0ZSBBcm5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgYXR0ckFybjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIGdyb3VwIG5hbWVzIHRvIHdoaWNoIHlvdSB3YW50IHRvIGFkZCB0aGUgdXNlci5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXVzZXIuaHRtbCNjZm4taWFtLXVzZXItZ3JvdXBzXG4gICAgICovXG4gICAgcHVibGljIGdyb3Vwczogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgcGFzc3dvcmQgZm9yIHRoZSBzcGVjaWZpZWQgSUFNIHVzZXIuIEEgcGFzc3dvcmQgYWxsb3dzIGFuIElBTSB1c2VyIHRvIGFjY2VzcyBBV1Mgc2VydmljZXMgdGhyb3VnaCB0aGUgQVdTIE1hbmFnZW1lbnQgQ29uc29sZSAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIHVzZSB0aGUgQVdTIENMSSAsIHRoZSBBV1MgQVBJLCBvciB0aGUgKlVzZXJzKiBwYWdlIGluIHRoZSBJQU0gY29uc29sZSB0byBjcmVhdGUgYSBwYXNzd29yZCBmb3IgYW55IElBTSB1c2VyLiBVc2UgW0NoYW5nZVBhc3N3b3JkXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NoYW5nZVBhc3N3b3JkLmh0bWwpIHRvIHVwZGF0ZSB5b3VyIG93biBleGlzdGluZyBwYXNzd29yZCBpbiB0aGUgKk15IFNlY3VyaXR5IENyZWRlbnRpYWxzKiBwYWdlIGluIHRoZSBBV1MgTWFuYWdlbWVudCBDb25zb2xlIC5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IG1hbmFnaW5nIHBhc3N3b3Jkcywgc2VlIFtNYW5hZ2luZyBwYXNzd29yZHNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19NYW5hZ2luZ0xvZ2lucy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLmh0bWwjY2ZuLWlhbS11c2VyLWxvZ2lucHJvZmlsZVxuICAgICAqL1xuICAgIHB1YmxpYyBsb2dpblByb2ZpbGU6IENmblVzZXIuTG9naW5Qcm9maWxlUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGUgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgQW1hem9uIFJlc291cmNlIE5hbWVzIChBUk5zKSBvZiB0aGUgSUFNIG1hbmFnZWQgcG9saWNpZXMgdGhhdCB5b3Ugd2FudCB0byBhdHRhY2ggdG8gdGhlIHVzZXIuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBBUk5zLCBzZWUgW0FtYXpvbiBSZXNvdXJjZSBOYW1lcyAoQVJOcykgYW5kIEFXUyBTZXJ2aWNlIE5hbWVzcGFjZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nZW5lcmFsL2xhdGVzdC9nci9hd3MtYXJucy1hbmQtbmFtZXNwYWNlcy5odG1sKSBpbiB0aGUgKkFXUyBHZW5lcmFsIFJlZmVyZW5jZSogLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tdXNlci5odG1sI2Nmbi1pYW0tdXNlci1tYW5hZ2Vwb2xpY3lhcm5zXG4gICAgICovXG4gICAgcHVibGljIG1hbmFnZWRQb2xpY3lBcm5zOiBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwYXRoIGZvciB0aGUgdXNlciBuYW1lLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gaWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiBlaXRoZXIgYSBmb3J3YXJkIHNsYXNoICgvKSBieSBpdHNlbGYgb3IgYSBzdHJpbmcgdGhhdCBtdXN0IGJlZ2luIGFuZCBlbmQgd2l0aCBmb3J3YXJkIHNsYXNoZXMuIEluIGFkZGl0aW9uLCBpdCBjYW4gY29udGFpbiBhbnkgQVNDSUkgY2hhcmFjdGVyIGZyb20gdGhlICEgKCBgXFwgdTAwMjFgICkgdGhyb3VnaCB0aGUgREVMIGNoYXJhY3RlciAoIGBcXCB1MDA3RmAgKSwgaW5jbHVkaW5nIG1vc3QgcHVuY3R1YXRpb24gY2hhcmFjdGVycywgZGlnaXRzLCBhbmQgdXBwZXIgYW5kIGxvd2VyY2FzZWQgbGV0dGVycy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXVzZXIuaHRtbCNjZm4taWFtLXVzZXItcGF0aFxuICAgICAqL1xuICAgIHB1YmxpYyBwYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgQVJOIG9mIHRoZSBtYW5hZ2VkIHBvbGljeSB0aGF0IGlzIHVzZWQgdG8gc2V0IHRoZSBwZXJtaXNzaW9ucyBib3VuZGFyeSBmb3IgdGhlIHVzZXIuXG4gICAgICpcbiAgICAgKiBBIHBlcm1pc3Npb25zIGJvdW5kYXJ5IHBvbGljeSBkZWZpbmVzIHRoZSBtYXhpbXVtIHBlcm1pc3Npb25zIHRoYXQgaWRlbnRpdHktYmFzZWQgcG9saWNpZXMgY2FuIGdyYW50IHRvIGFuIGVudGl0eSwgYnV0IGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb25zLiBQZXJtaXNzaW9ucyBib3VuZGFyaWVzIGRvIG5vdCBkZWZpbmUgdGhlIG1heGltdW0gcGVybWlzc2lvbnMgdGhhdCBhIHJlc291cmNlLWJhc2VkIHBvbGljeSBjYW4gZ3JhbnQgdG8gYW4gZW50aXR5LiBUbyBsZWFybiBtb3JlLCBzZWUgW1Blcm1pc3Npb25zIGJvdW5kYXJpZXMgZm9yIElBTSBlbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2FjY2Vzc19wb2xpY2llc19ib3VuZGFyaWVzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHBvbGljeSB0eXBlcywgc2VlIFtQb2xpY3kgdHlwZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9hY2Nlc3NfcG9saWNpZXMuaHRtbCNhY2Nlc3NfcG9saWN5LXR5cGVzKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLmh0bWwjY2ZuLWlhbS11c2VyLXBlcm1pc3Npb25zYm91bmRhcnlcbiAgICAgKi9cbiAgICBwdWJsaWMgcGVybWlzc2lvbnNCb3VuZGFyeTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBvciB1cGRhdGVzIGFuIGlubGluZSBwb2xpY3kgZG9jdW1lbnQgdGhhdCBpcyBlbWJlZGRlZCBpbiB0aGUgc3BlY2lmaWVkIElBTSB1c2VyLiBUbyB2aWV3IEFXUzo6SUFNOjpVc2VyIHNuaXBwZXRzLCBzZWUgW0RlY2xhcmluZyBhbiBJQU0gVXNlciBSZXNvdXJjZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvcXVpY2tyZWYtaWFtLmh0bWwjc2NlbmFyaW8taWFtLXVzZXIpIC5cbiAgICAgKlxuICAgICAqID4gVGhlIG5hbWUgb2YgZWFjaCBwb2xpY3kgZm9yIGEgcm9sZSwgdXNlciwgb3IgZ3JvdXAgbXVzdCBiZSB1bmlxdWUuIElmIHlvdSBkb24ndCBjaG9vc2UgdW5pcXVlIG5hbWVzLCB1cGRhdGVzIHRvIHRoZSBJQU0gaWRlbnRpdHkgd2lsbCBmYWlsLlxuICAgICAqXG4gICAgICogRm9yIGluZm9ybWF0aW9uIGFib3V0IGxpbWl0cyBvbiB0aGUgbnVtYmVyIG9mIGlubGluZSBwb2xpY2llcyB0aGF0IHlvdSBjYW4gZW1iZWQgaW4gYSB1c2VyLCBzZWUgW0xpbWl0YXRpb25zIG9uIElBTSBFbnRpdGllc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL0xpbWl0YXRpb25zT25FbnRpdGllcy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLmh0bWwjY2ZuLWlhbS11c2VyLXBvbGljaWVzXG4gICAgICovXG4gICAgcHVibGljIHBvbGljaWVzOiBBcnJheTxDZm5Vc2VyLlBvbGljeVByb3BlcnR5IHwgY2RrLklSZXNvbHZhYmxlPiB8IGNkay5JUmVzb2x2YWJsZSB8IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEEgbGlzdCBvZiB0YWdzIHRoYXQgeW91IHdhbnQgdG8gYXR0YWNoIHRvIHRoZSBuZXcgdXNlci4gRWFjaCB0YWcgY29uc2lzdHMgb2YgYSBrZXkgbmFtZSBhbmQgYW4gYXNzb2NpYXRlZCB2YWx1ZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGFnZ2luZywgc2VlIFtUYWdnaW5nIElBTSByZXNvdXJjZXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF90YWdzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqID4gSWYgYW55IG9uZSBvZiB0aGUgdGFncyBpcyBpbnZhbGlkIG9yIGlmIHlvdSBleGNlZWQgdGhlIGFsbG93ZWQgbWF4aW11bSBudW1iZXIgb2YgdGFncywgdGhlbiB0aGUgZW50aXJlIHJlcXVlc3QgZmFpbHMgYW5kIHRoZSByZXNvdXJjZSBpcyBub3QgY3JlYXRlZC5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXVzZXIuaHRtbCNjZm4taWFtLXVzZXItdGFnc1xuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB0YWdzOiBjZGsuVGFnTWFuYWdlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSB1c2VyIHRvIGNyZWF0ZS4gRG8gbm90IGluY2x1ZGUgdGhlIHBhdGggaW4gdGhpcyB2YWx1ZS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAocGVyIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC0uIFRoZSB1c2VyIG5hbWUgbXVzdCBiZSB1bmlxdWUgd2l0aGluIHRoZSBhY2NvdW50LiBVc2VyIG5hbWVzIGFyZSBub3QgZGlzdGluZ3Vpc2hlZCBieSBjYXNlLiBGb3IgZXhhbXBsZSwgeW91IGNhbm5vdCBjcmVhdGUgdXNlcnMgbmFtZWQgYm90aCBcIkpvaG5cIiBhbmQgXCJqb2huXCIuXG4gICAgICpcbiAgICAgKiBJZiB5b3UgZG9uJ3Qgc3BlY2lmeSBhIG5hbWUsIEFXUyBDbG91ZEZvcm1hdGlvbiBnZW5lcmF0ZXMgYSB1bmlxdWUgcGh5c2ljYWwgSUQgYW5kIHVzZXMgdGhhdCBJRCBmb3IgdGhlIHVzZXIgbmFtZS5cbiAgICAgKlxuICAgICAqIElmIHlvdSBzcGVjaWZ5IGEgbmFtZSwgeW91IG11c3Qgc3BlY2lmeSB0aGUgYENBUEFCSUxJVFlfTkFNRURfSUFNYCB2YWx1ZSB0byBhY2tub3dsZWRnZSB5b3VyIHRlbXBsYXRlJ3MgY2FwYWJpbGl0aWVzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtBY2tub3dsZWRnaW5nIElBTSBSZXNvdXJjZXMgaW4gQVdTIENsb3VkRm9ybWF0aW9uIFRlbXBsYXRlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvdXNpbmctaWFtLXRlbXBsYXRlLmh0bWwjdXNpbmctaWFtLWNhcGFiaWxpdGllcykgLlxuICAgICAqXG4gICAgICogPiBOYW1pbmcgYW4gSUFNIHJlc291cmNlIGNhbiBjYXVzZSBhbiB1bnJlY292ZXJhYmxlIGVycm9yIGlmIHlvdSByZXVzZSB0aGUgc2FtZSB0ZW1wbGF0ZSBpbiBtdWx0aXBsZSBSZWdpb25zLiBUbyBwcmV2ZW50IHRoaXMsIHdlIHJlY29tbWVuZCB1c2luZyBgRm46OkpvaW5gIGFuZCBgQVdTOjpSZWdpb25gIHRvIGNyZWF0ZSBhIFJlZ2lvbi1zcGVjaWZpYyBuYW1lLCBhcyBpbiB0aGUgZm9sbG93aW5nIGV4YW1wbGU6IGB7XCJGbjo6Sm9pblwiOiBbXCJcIiwgW3tcIlJlZlwiOiBcIkFXUzo6UmVnaW9uXCJ9LCB7XCJSZWZcIjogXCJNeVJlc291cmNlTmFtZVwifV1dfWAgLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tdXNlci5odG1sI2Nmbi1pYW0tdXNlci11c2VybmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyB1c2VyTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGBBV1M6OklBTTo6VXNlcmAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuVXNlclByb3BzID0ge30pIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmblVzZXIuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIHRoaXMuYXR0ckFybiA9IGNkay5Ub2tlbi5hc1N0cmluZyh0aGlzLmdldEF0dCgnQXJuJykpO1xuXG4gICAgICAgIHRoaXMuZ3JvdXBzID0gcHJvcHMuZ3JvdXBzO1xuICAgICAgICB0aGlzLmxvZ2luUHJvZmlsZSA9IHByb3BzLmxvZ2luUHJvZmlsZTtcbiAgICAgICAgdGhpcy5tYW5hZ2VkUG9saWN5QXJucyA9IHByb3BzLm1hbmFnZWRQb2xpY3lBcm5zO1xuICAgICAgICB0aGlzLnBhdGggPSBwcm9wcy5wYXRoO1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25zQm91bmRhcnkgPSBwcm9wcy5wZXJtaXNzaW9uc0JvdW5kYXJ5O1xuICAgICAgICB0aGlzLnBvbGljaWVzID0gcHJvcHMucG9saWNpZXM7XG4gICAgICAgIHRoaXMudGFncyA9IG5ldyBjZGsuVGFnTWFuYWdlcihjZGsuVGFnVHlwZS5TVEFOREFSRCwgXCJBV1M6OklBTTo6VXNlclwiLCBwcm9wcy50YWdzLCB7IHRhZ1Byb3BlcnR5TmFtZTogJ3RhZ3MnIH0pO1xuICAgICAgICB0aGlzLnVzZXJOYW1lID0gcHJvcHMudXNlck5hbWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5Vc2VyLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBncm91cHM6IHRoaXMuZ3JvdXBzLFxuICAgICAgICAgICAgbG9naW5Qcm9maWxlOiB0aGlzLmxvZ2luUHJvZmlsZSxcbiAgICAgICAgICAgIG1hbmFnZWRQb2xpY3lBcm5zOiB0aGlzLm1hbmFnZWRQb2xpY3lBcm5zLFxuICAgICAgICAgICAgcGF0aDogdGhpcy5wYXRoLFxuICAgICAgICAgICAgcGVybWlzc2lvbnNCb3VuZGFyeTogdGhpcy5wZXJtaXNzaW9uc0JvdW5kYXJ5LFxuICAgICAgICAgICAgcG9saWNpZXM6IHRoaXMucG9saWNpZXMsXG4gICAgICAgICAgICB0YWdzOiB0aGlzLnRhZ3MucmVuZGVyVGFncygpLFxuICAgICAgICAgICAgdXNlck5hbWU6IHRoaXMudXNlck5hbWUsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuVXNlclByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuXG5leHBvcnQgbmFtZXNwYWNlIENmblVzZXIge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBwYXNzd29yZCBmb3IgdGhlIHNwZWNpZmllZCB1c2VyLCBnaXZpbmcgdGhlIHVzZXIgdGhlIGFiaWxpdHkgdG8gYWNjZXNzIEFXUyBzZXJ2aWNlcyB0aHJvdWdoIHRoZSBBV1MgTWFuYWdlbWVudCBDb25zb2xlIC4gRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgbWFuYWdpbmcgcGFzc3dvcmRzLCBzZWUgW01hbmFnaW5nIFBhc3N3b3Jkc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL1VzaW5nX01hbmFnaW5nTG9naW5zLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIEBzdHJ1Y3RcbiAgICAgKiBAc3RhYmlsaXR5IGV4dGVybmFsXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLWxvZ2lucHJvZmlsZS5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBMb2dpblByb2ZpbGVQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdXNlcidzIHBhc3N3b3JkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLWxvZ2lucHJvZmlsZS5odG1sI2Nmbi1pYW0tdXNlci1sb2dpbnByb2ZpbGUtcGFzc3dvcmRcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHBhc3N3b3JkOiBzdHJpbmc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTcGVjaWZpZXMgd2hldGhlciB0aGUgdXNlciBpcyByZXF1aXJlZCB0byBzZXQgYSBuZXcgcGFzc3dvcmQgb24gbmV4dCBzaWduLWluLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS11c2VyLWxvZ2lucHJvZmlsZS5odG1sI2Nmbi1pYW0tdXNlci1sb2dpbnByb2ZpbGUtcGFzc3dvcmRyZXNldHJlcXVpcmVkXG4gICAgICAgICAqL1xuICAgICAgICByZWFkb25seSBwYXNzd29yZFJlc2V0UmVxdWlyZWQ/OiBib29sZWFuIHwgY2RrLklSZXNvbHZhYmxlO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgZ2l2ZW4gcHJvcGVydGllcyBtYXRjaCB0aG9zZSBvZiBhIGBMb2dpblByb2ZpbGVQcm9wZXJ0eWBcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgTG9naW5Qcm9maWxlUHJvcGVydHlgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVXNlcl9Mb2dpblByb2ZpbGVQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3Bhc3N3b3JkJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnBhc3N3b3JkKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwYXNzd29yZCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5wYXNzd29yZCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncGFzc3dvcmRSZXNldFJlcXVpcmVkJywgY2RrLnZhbGlkYXRlQm9vbGVhbikocHJvcGVydGllcy5wYXNzd29yZFJlc2V0UmVxdWlyZWQpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiTG9naW5Qcm9maWxlUHJvcGVydHlcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6VXNlci5Mb2dpblByb2ZpbGVgIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYExvZ2luUHJvZmlsZVByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlVzZXIuTG9naW5Qcm9maWxlYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblVzZXJMb2dpblByb2ZpbGVQcm9wZXJ0eVRvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVXNlcl9Mb2dpblByb2ZpbGVQcm9wZXJ0eVZhbGlkYXRvcihwcm9wZXJ0aWVzKS5hc3NlcnRTdWNjZXNzKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgUGFzc3dvcmQ6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucGFzc3dvcmQpLFxuICAgICAgICBQYXNzd29yZFJlc2V0UmVxdWlyZWQ6IGNkay5ib29sZWFuVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBhc3N3b3JkUmVzZXRSZXF1aXJlZCksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblVzZXJMb2dpblByb2ZpbGVQcm9wZXJ0eUZyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblVzZXIuTG9naW5Qcm9maWxlUHJvcGVydHkgfCBjZGsuSVJlc29sdmFibGU+IHtcbiAgICBpZiAoY2RrLmlzUmVzb2x2YWJsZU9iamVjdChwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVXNlci5Mb2dpblByb2ZpbGVQcm9wZXJ0eT4oKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3Bhc3N3b3JkJywgJ1Bhc3N3b3JkJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5QYXNzd29yZCkpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncGFzc3dvcmRSZXNldFJlcXVpcmVkJywgJ1Bhc3N3b3JkUmVzZXRSZXF1aXJlZCcsIHByb3BlcnRpZXMuUGFzc3dvcmRSZXNldFJlcXVpcmVkICE9IG51bGwgPyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEJvb2xlYW4ocHJvcGVydGllcy5QYXNzd29yZFJlc2V0UmVxdWlyZWQpIDogdW5kZWZpbmVkKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IG5hbWVzcGFjZSBDZm5Vc2VyIHtcbiAgICAvKipcbiAgICAgKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCBhbiBhdHRhY2hlZCBwb2xpY3kuXG4gICAgICpcbiAgICAgKiBBbiBhdHRhY2hlZCBwb2xpY3kgaXMgYSBtYW5hZ2VkIHBvbGljeSB0aGF0IGhhcyBiZWVuIGF0dGFjaGVkIHRvIGEgdXNlciwgZ3JvdXAsIG9yIHJvbGUuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBtYW5hZ2VkIHBvbGljaWVzLCByZWZlciB0byBbTWFuYWdlZCBQb2xpY2llcyBhbmQgSW5saW5lIFBvbGljaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcG9saWNpZXMtbWFuYWdlZC12cy1pbmxpbmUuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogQHN0cnVjdFxuICAgICAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLXBvbGljeS5odG1sXG4gICAgICovXG4gICAgZXhwb3J0IGludGVyZmFjZSBQb2xpY3lQcm9wZXJ0eSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZW50aXJlIGNvbnRlbnRzIG9mIHRoZSBwb2xpY3kgdGhhdCBkZWZpbmVzIHBlcm1pc3Npb25zLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtPdmVydmlldyBvZiBKU09OIHBvbGljaWVzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvYWNjZXNzX3BvbGljaWVzLmh0bWwjYWNjZXNzX3BvbGljaWVzLWpzb24pIC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tcG9saWN5Lmh0bWwjY2ZuLWlhbS1wb2xpY2llcy1wb2xpY3lkb2N1bWVudFxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgcG9saWN5RG9jdW1lbnQ6IGFueSB8IGNkay5JUmVzb2x2YWJsZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBmcmllbmRseSBuYW1lIChub3QgQVJOKSBpZGVudGlmeWluZyB0aGUgcG9saWN5LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1wb2xpY3kuaHRtbCNjZm4taWFtLXBvbGljaWVzLXBvbGljeW5hbWVcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHBvbGljeU5hbWU6IHN0cmluZztcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgUG9saWN5UHJvcGVydHlgXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYFBvbGljeVByb3BlcnR5YFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblVzZXJfUG9saWN5UHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllczogYW55KTogY2RrLlZhbGlkYXRpb25SZXN1bHQge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIGNkay5WQUxJREFUSU9OX1NVQ0NFU1M7IH1cbiAgICBjb25zdCBlcnJvcnMgPSBuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHRzKCk7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICBlcnJvcnMuY29sbGVjdChuZXcgY2RrLlZhbGlkYXRpb25SZXN1bHQoJ0V4cGVjdGVkIGFuIG9iamVjdCwgYnV0IHJlY2VpdmVkOiAnICsgSlNPTi5zdHJpbmdpZnkocHJvcGVydGllcykpKTtcbiAgICB9XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCdwb2xpY3lEb2N1bWVudCcsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5wb2xpY3lEb2N1bWVudCkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5RG9jdW1lbnQnLCBjZGsudmFsaWRhdGVPYmplY3QpKHByb3BlcnRpZXMucG9saWN5RG9jdW1lbnQpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3BvbGljeU5hbWUnLCBjZGsucmVxdWlyZWRWYWxpZGF0b3IpKHByb3BlcnRpZXMucG9saWN5TmFtZSkpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncG9saWN5TmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5wb2xpY3lOYW1lKSk7XG4gICAgcmV0dXJuIGVycm9ycy53cmFwKCdzdXBwbGllZCBwcm9wZXJ0aWVzIG5vdCBjb3JyZWN0IGZvciBcIlBvbGljeVByb3BlcnR5XCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlVzZXIuUG9saWN5YCByZXNvdXJjZVxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBQb2xpY3lQcm9wZXJ0eWBcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpVc2VyLlBvbGljeWAgcmVzb3VyY2UuXG4gKi9cbi8vIEB0cy1pZ25vcmUgVFM2MTMzXG5mdW5jdGlvbiBjZm5Vc2VyUG9saWN5UHJvcGVydHlUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGFueSB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gcHJvcGVydGllczsgfVxuICAgIENmblVzZXJfUG9saWN5UHJvcGVydHlWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFBvbGljeURvY3VtZW50OiBjZGsub2JqZWN0VG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzLnBvbGljeURvY3VtZW50KSxcbiAgICAgICAgUG9saWN5TmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy5wb2xpY3lOYW1lKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuVXNlclBvbGljeVByb3BlcnR5RnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVXNlci5Qb2xpY3lQcm9wZXJ0eSB8IGNkay5JUmVzb2x2YWJsZT4ge1xuICAgIGlmIChjZGsuaXNSZXNvbHZhYmxlT2JqZWN0KHByb3BlcnRpZXMpKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5Vc2VyLlBvbGljeVByb3BlcnR5PigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgncG9saWN5RG9jdW1lbnQnLCAnUG9saWN5RG9jdW1lbnQnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldEFueShwcm9wZXJ0aWVzLlBvbGljeURvY3VtZW50KSk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdwb2xpY3lOYW1lJywgJ1BvbGljeU5hbWUnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZyhwcm9wZXJ0aWVzLlBvbGljeU5hbWUpKTtcbiAgICByZXQuYWRkVW5yZWNvZ25pemVkUHJvcGVydGllc0FzRXh0cmEocHJvcGVydGllcyk7XG4gICAgcmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhIGBDZm5Vc2VyVG9Hcm91cEFkZGl0aW9uYFxuICpcbiAqIEBzdHJ1Y3RcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1hZGR1c2VydG9ncm91cC5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2ZuVXNlclRvR3JvdXBBZGRpdGlvblByb3BzIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBncm91cCB0byB1cGRhdGUuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBhbGxvd3MgKHRocm91Z2ggaXRzIFtyZWdleCBwYXR0ZXJuXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vaHR0cDovL3dpa2lwZWRpYS5vcmcvd2lraS9yZWdleCkgKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzIGNvbnNpc3Rpbmcgb2YgdXBwZXIgYW5kIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyB3aXRoIG5vIHNwYWNlcy4gWW91IGNhbiBhbHNvIGluY2x1ZGUgYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogXys9LC5ALVxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tYWRkdXNlcnRvZ3JvdXAuaHRtbCNjZm4taWFtLWFkZHVzZXJ0b2dyb3VwLWdyb3VwbmFtZVxuICAgICAqL1xuICAgIHJlYWRvbmx5IGdyb3VwTmFtZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIHRoZSBuYW1lcyBvZiB0aGUgdXNlcnMgdGhhdCB5b3Ugd2FudCB0byBhZGQgdG8gdGhlIGdyb3VwLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcHJvcGVydGllcy1pYW0tYWRkdXNlcnRvZ3JvdXAuaHRtbCNjZm4taWFtLWFkZHVzZXJ0b2dyb3VwLXVzZXJzXG4gICAgICovXG4gICAgcmVhZG9ubHkgdXNlcnM6IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBwcm9wZXJ0aWVzIG1hdGNoIHRob3NlIG9mIGEgYENmblVzZXJUb0dyb3VwQWRkaXRpb25Qcm9wc2BcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuVXNlclRvR3JvdXBBZGRpdGlvblByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIHZhbGlkYXRpb24uXG4gKi9cbmZ1bmN0aW9uIENmblVzZXJUb0dyb3VwQWRkaXRpb25Qcm9wc1ZhbGlkYXRvcihwcm9wZXJ0aWVzOiBhbnkpOiBjZGsuVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgaWYgKCFjZGsuY2FuSW5zcGVjdChwcm9wZXJ0aWVzKSkgeyByZXR1cm4gY2RrLlZBTElEQVRJT05fU1VDQ0VTUzsgfVxuICAgIGNvbnN0IGVycm9ycyA9IG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdHMoKTtcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIGVycm9ycy5jb2xsZWN0KG5ldyBjZGsuVmFsaWRhdGlvblJlc3VsdCgnRXhwZWN0ZWQgYW4gb2JqZWN0LCBidXQgcmVjZWl2ZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSkpO1xuICAgIH1cbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2dyb3VwTmFtZScsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy5ncm91cE5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ2dyb3VwTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5ncm91cE5hbWUpKTtcbiAgICBlcnJvcnMuY29sbGVjdChjZGsucHJvcGVydHlWYWxpZGF0b3IoJ3VzZXJzJywgY2RrLnJlcXVpcmVkVmFsaWRhdG9yKShwcm9wZXJ0aWVzLnVzZXJzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd1c2VycycsIGNkay5saXN0VmFsaWRhdG9yKGNkay52YWxpZGF0ZVN0cmluZykpKHByb3BlcnRpZXMudXNlcnMpKTtcbiAgICByZXR1cm4gZXJyb3JzLndyYXAoJ3N1cHBsaWVkIHByb3BlcnRpZXMgbm90IGNvcnJlY3QgZm9yIFwiQ2ZuVXNlclRvR3JvdXBBZGRpdGlvblByb3BzXCInKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlVzZXJUb0dyb3VwQWRkaXRpb25gIHJlc291cmNlXG4gKlxuICogQHBhcmFtIHByb3BlcnRpZXMgLSB0aGUgVHlwZVNjcmlwdCBwcm9wZXJ0aWVzIG9mIGEgYENmblVzZXJUb0dyb3VwQWRkaXRpb25Qcm9wc2BcbiAqXG4gKiBAcmV0dXJucyB0aGUgQVdTIENsb3VkRm9ybWF0aW9uIHByb3BlcnRpZXMgb2YgYW4gYEFXUzo6SUFNOjpVc2VyVG9Hcm91cEFkZGl0aW9uYCByZXNvdXJjZS5cbiAqL1xuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIGNmblVzZXJUb0dyb3VwQWRkaXRpb25Qcm9wc1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllczogYW55KTogYW55IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBwcm9wZXJ0aWVzOyB9XG4gICAgQ2ZuVXNlclRvR3JvdXBBZGRpdGlvblByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXMpLmFzc2VydFN1Y2Nlc3MoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBHcm91cE5hbWU6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMuZ3JvdXBOYW1lKSxcbiAgICAgICAgVXNlcnM6IGNkay5saXN0TWFwcGVyKGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnVzZXJzKSxcbiAgICB9O1xufVxuXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gQ2ZuVXNlclRvR3JvdXBBZGRpdGlvblByb3BzRnJvbUNsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXM6IGFueSk6IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQ8Q2ZuVXNlclRvR3JvdXBBZGRpdGlvblByb3BzPiB7XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogcHJvcGVydGllcztcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvblJlc3VsdChwcm9wZXJ0aWVzKTtcbiAgICB9XG4gICAgY29uc3QgcmV0ID0gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25Qcm9wZXJ0eU9iamVjdDxDZm5Vc2VyVG9Hcm91cEFkZGl0aW9uUHJvcHM+KCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCdncm91cE5hbWUnLCAnR3JvdXBOYW1lJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5Hcm91cE5hbWUpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3VzZXJzJywgJ1VzZXJzJywgY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmdBcnJheShwcm9wZXJ0aWVzLlVzZXJzKSk7XG4gICAgcmV0LmFkZFVucmVjb2duaXplZFByb3BlcnRpZXNBc0V4dHJhKHByb3BlcnRpZXMpO1xuICAgIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBDbG91ZEZvcm1hdGlvbiBgQVdTOjpJQU06OlVzZXJUb0dyb3VwQWRkaXRpb25gXG4gKlxuICogQWRkcyB0aGUgc3BlY2lmaWVkIHVzZXIgdG8gdGhlIHNwZWNpZmllZCBncm91cC5cbiAqXG4gKiBAY2xvdWRmb3JtYXRpb25SZXNvdXJjZSBBV1M6OklBTTo6VXNlclRvR3JvdXBBZGRpdGlvblxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLWFkZHVzZXJ0b2dyb3VwLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIENmblVzZXJUb0dyb3VwQWRkaXRpb24gZXh0ZW5kcyBjZGsuQ2ZuUmVzb3VyY2UgaW1wbGVtZW50cyBjZGsuSUluc3BlY3RhYmxlIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ2xvdWRGb3JtYXRpb24gcmVzb3VyY2UgdHlwZSBuYW1lIGZvciB0aGlzIHJlc291cmNlIGNsYXNzLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSA9IFwiQVdTOjpJQU06OlVzZXJUb0dyb3VwQWRkaXRpb25cIjtcblxuICAgIC8qKlxuICAgICAqIEEgZmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZnJvbSBhbiBvYmplY3RcbiAgICAgKiBjb250YWluaW5nIHRoZSBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAgICogVXNlZCBpbiB0aGUgQGF3cy1jZGsvY2xvdWRmb3JtYXRpb24taW5jbHVkZSBtb2R1bGUuXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIF9mcm9tQ2xvdWRGb3JtYXRpb24oc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlczogYW55LCBvcHRpb25zOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uT3B0aW9ucyk6IENmblVzZXJUb0dyb3VwQWRkaXRpb24ge1xuICAgICAgICByZXNvdXJjZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUF0dHJpYnV0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJlc291cmNlUHJvcGVydGllcyA9IG9wdGlvbnMucGFyc2VyLnBhcnNlVmFsdWUocmVzb3VyY2VBdHRyaWJ1dGVzLlByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCBwcm9wc1Jlc3VsdCA9IENmblVzZXJUb0dyb3VwQWRkaXRpb25Qcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihyZXNvdXJjZVByb3BlcnRpZXMpO1xuICAgICAgICBjb25zdCByZXQgPSBuZXcgQ2ZuVXNlclRvR3JvdXBBZGRpdGlvbihzY29wZSwgaWQsIHByb3BzUmVzdWx0LnZhbHVlKTtcbiAgICAgICAgZm9yIChjb25zdCBbcHJvcEtleSwgcHJvcFZhbF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcHNSZXN1bHQuZXh0cmFQcm9wZXJ0aWVzKSkgIHtcbiAgICAgICAgICAgIHJldC5hZGRQcm9wZXJ0eU92ZXJyaWRlKHByb3BLZXksIHByb3BWYWwpO1xuICAgICAgICB9XG4gICAgICAgIG9wdGlvbnMucGFyc2VyLmhhbmRsZUF0dHJpYnV0ZXMocmV0LCByZXNvdXJjZUF0dHJpYnV0ZXMsIGlkKTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgZ3JvdXAgdG8gdXBkYXRlLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtaWFtLWFkZHVzZXJ0b2dyb3VwLmh0bWwjY2ZuLWlhbS1hZGR1c2VydG9ncm91cC1ncm91cG5hbWVcbiAgICAgKi9cbiAgICBwdWJsaWMgZ3JvdXBOYW1lOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgdGhlIG5hbWVzIG9mIHRoZSB1c2VycyB0aGF0IHlvdSB3YW50IHRvIGFkZCB0byB0aGUgZ3JvdXAuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1wcm9wZXJ0aWVzLWlhbS1hZGR1c2VydG9ncm91cC5odG1sI2Nmbi1pYW0tYWRkdXNlcnRvZ3JvdXAtdXNlcnNcbiAgICAgKi9cbiAgICBwdWJsaWMgdXNlcnM6IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGBBV1M6OklBTTo6VXNlclRvR3JvdXBBZGRpdGlvbmAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2NvcGUgLSBzY29wZSBpbiB3aGljaCB0aGlzIHJlc291cmNlIGlzIGRlZmluZWRcbiAgICAgKiBAcGFyYW0gaWQgICAgLSBzY29wZWQgaWQgb2YgdGhlIHJlc291cmNlXG4gICAgICogQHBhcmFtIHByb3BzIC0gcmVzb3VyY2UgcHJvcGVydGllc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ2ZuVXNlclRvR3JvdXBBZGRpdGlvblByb3BzKSB7XG4gICAgICAgIHN1cGVyKHNjb3BlLCBpZCwgeyB0eXBlOiBDZm5Vc2VyVG9Hcm91cEFkZGl0aW9uLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUsIHByb3BlcnRpZXM6IHByb3BzIH0pO1xuICAgICAgICBjZGsucmVxdWlyZVByb3BlcnR5KHByb3BzLCAnZ3JvdXBOYW1lJywgdGhpcyk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICd1c2VycycsIHRoaXMpO1xuXG4gICAgICAgIHRoaXMuZ3JvdXBOYW1lID0gcHJvcHMuZ3JvdXBOYW1lO1xuICAgICAgICB0aGlzLnVzZXJzID0gcHJvcHMudXNlcnM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5Vc2VyVG9Hcm91cEFkZGl0aW9uLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBncm91cE5hbWU6IHRoaXMuZ3JvdXBOYW1lLFxuICAgICAgICAgICAgdXNlcnM6IHRoaXMudXNlcnMsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHJlbmRlclByb3BlcnRpZXMocHJvcHM6IHtba2V5OiBzdHJpbmddOiBhbnl9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSAge1xuICAgICAgICByZXR1cm4gY2ZuVXNlclRvR3JvdXBBZGRpdGlvblByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wcyk7XG4gICAgfVxufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGEgYENmblZpcnR1YWxNRkFEZXZpY2VgXG4gKlxuICogQHN0cnVjdFxuICogQHN0YWJpbGl0eSBleHRlcm5hbFxuICpcbiAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS12aXJ0dWFsbWZhZGV2aWNlLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZm5WaXJ0dWFsTUZBRGV2aWNlUHJvcHMge1xuXG4gICAgLyoqXG4gICAgICogVGhlIElBTSB1c2VyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHZpcnR1YWwgTUZBIGRldmljZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS12aXJ0dWFsbWZhZGV2aWNlLmh0bWwjY2ZuLWlhbS12aXJ0dWFsbWZhZGV2aWNlLXVzZXJzXG4gICAgICovXG4gICAgcmVhZG9ubHkgdXNlcnM6IHN0cmluZ1tdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBhdGggZm9yIHRoZSB2aXJ0dWFsIE1GQSBkZXZpY2UuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHBhdGhzLCBzZWUgW0lBTSBpZGVudGlmaWVyc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL1VzaW5nX0lkZW50aWZpZXJzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGlzIG9wdGlvbmFsLiBJZiBpdCBpcyBub3QgaW5jbHVkZWQsIGl0IGRlZmF1bHRzIHRvIGEgc2xhc2ggKC8pLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIGVpdGhlciBhIGZvcndhcmQgc2xhc2ggKC8pIGJ5IGl0c2VsZiBvciBhIHN0cmluZyB0aGF0IG11c3QgYmVnaW4gYW5kIGVuZCB3aXRoIGZvcndhcmQgc2xhc2hlcy4gSW4gYWRkaXRpb24sIGl0IGNhbiBjb250YWluIGFueSBBU0NJSSBjaGFyYWN0ZXIgZnJvbSB0aGUgISAoIGBcXCB1MDAyMWAgKSB0aHJvdWdoIHRoZSBERUwgY2hhcmFjdGVyICggYFxcIHUwMDdGYCApLCBpbmNsdWRpbmcgbW9zdCBwdW5jdHVhdGlvbiBjaGFyYWN0ZXJzLCBkaWdpdHMsIGFuZCB1cHBlciBhbmQgbG93ZXJjYXNlZCBsZXR0ZXJzLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXZpcnR1YWxtZmFkZXZpY2UuaHRtbCNjZm4taWFtLXZpcnR1YWxtZmFkZXZpY2UtcGF0aFxuICAgICAqL1xuICAgIHJlYWRvbmx5IHBhdGg/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgdGFncyB0aGF0IHlvdSB3YW50IHRvIGF0dGFjaCB0byB0aGUgbmV3IElBTSB2aXJ0dWFsIE1GQSBkZXZpY2UuIEVhY2ggdGFnIGNvbnNpc3RzIG9mIGEga2V5IG5hbWUgYW5kIGFuIGFzc29jaWF0ZWQgdmFsdWUuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRhZ2dpbmcsIHNlZSBbVGFnZ2luZyBJQU0gcmVzb3VyY2VzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvaWRfdGFncy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiA+IElmIGFueSBvbmUgb2YgdGhlIHRhZ3MgaXMgaW52YWxpZCBvciBpZiB5b3UgZXhjZWVkIHRoZSBhbGxvd2VkIG1heGltdW0gbnVtYmVyIG9mIHRhZ3MsIHRoZW4gdGhlIGVudGlyZSByZXF1ZXN0IGZhaWxzIGFuZCB0aGUgcmVzb3VyY2UgaXMgbm90IGNyZWF0ZWQuXG4gICAgICpcbiAgICAgKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tdmlydHVhbG1mYWRldmljZS5odG1sI2Nmbi1pYW0tdmlydHVhbG1mYWRldmljZS10YWdzXG4gICAgICovXG4gICAgcmVhZG9ubHkgdGFncz86IGNkay5DZm5UYWdbXTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSB2aXJ0dWFsIE1GQSBkZXZpY2UsIHdoaWNoIG11c3QgYmUgdW5pcXVlLiBVc2Ugd2l0aCBwYXRoIHRvIHVuaXF1ZWx5IGlkZW50aWZ5IGEgdmlydHVhbCBNRkEgZGV2aWNlLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS12aXJ0dWFsbWZhZGV2aWNlLmh0bWwjY2ZuLWlhbS12aXJ0dWFsbWZhZGV2aWNlLXZpcnR1YWxtZmFkZXZpY2VuYW1lXG4gICAgICovXG4gICAgcmVhZG9ubHkgdmlydHVhbE1mYURldmljZU5hbWU/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdpdmVuIHByb3BlcnRpZXMgbWF0Y2ggdGhvc2Ugb2YgYSBgQ2ZuVmlydHVhbE1GQURldmljZVByb3BzYFxuICpcbiAqIEBwYXJhbSBwcm9wZXJ0aWVzIC0gdGhlIFR5cGVTY3JpcHQgcHJvcGVydGllcyBvZiBhIGBDZm5WaXJ0dWFsTUZBRGV2aWNlUHJvcHNgXG4gKlxuICogQHJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgdmFsaWRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gQ2ZuVmlydHVhbE1GQURldmljZVByb3BzVmFsaWRhdG9yKHByb3BlcnRpZXM6IGFueSk6IGNkay5WYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBpZiAoIWNkay5jYW5JbnNwZWN0KHByb3BlcnRpZXMpKSB7IHJldHVybiBjZGsuVkFMSURBVElPTl9TVUNDRVNTOyB9XG4gICAgY29uc3QgZXJyb3JzID0gbmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0cygpO1xuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgZXJyb3JzLmNvbGxlY3QobmV3IGNkay5WYWxpZGF0aW9uUmVzdWx0KCdFeHBlY3RlZCBhbiBvYmplY3QsIGJ1dCByZWNlaXZlZDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BlcnRpZXMpKSk7XG4gICAgfVxuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigncGF0aCcsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy5wYXRoKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd0YWdzJywgY2RrLmxpc3RWYWxpZGF0b3IoY2RrLnZhbGlkYXRlQ2ZuVGFnKSkocHJvcGVydGllcy50YWdzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd1c2VycycsIGNkay5yZXF1aXJlZFZhbGlkYXRvcikocHJvcGVydGllcy51c2VycykpO1xuICAgIGVycm9ycy5jb2xsZWN0KGNkay5wcm9wZXJ0eVZhbGlkYXRvcigndXNlcnMnLCBjZGsubGlzdFZhbGlkYXRvcihjZGsudmFsaWRhdGVTdHJpbmcpKShwcm9wZXJ0aWVzLnVzZXJzKSk7XG4gICAgZXJyb3JzLmNvbGxlY3QoY2RrLnByb3BlcnR5VmFsaWRhdG9yKCd2aXJ0dWFsTWZhRGV2aWNlTmFtZScsIGNkay52YWxpZGF0ZVN0cmluZykocHJvcGVydGllcy52aXJ0dWFsTWZhRGV2aWNlTmFtZSkpO1xuICAgIHJldHVybiBlcnJvcnMud3JhcCgnc3VwcGxpZWQgcHJvcGVydGllcyBub3QgY29ycmVjdCBmb3IgXCJDZm5WaXJ0dWFsTUZBRGV2aWNlUHJvcHNcIicpO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIEFXUyBDbG91ZEZvcm1hdGlvbiBwcm9wZXJ0aWVzIG9mIGFuIGBBV1M6OklBTTo6VmlydHVhbE1GQURldmljZWAgcmVzb3VyY2VcbiAqXG4gKiBAcGFyYW0gcHJvcGVydGllcyAtIHRoZSBUeXBlU2NyaXB0IHByb3BlcnRpZXMgb2YgYSBgQ2ZuVmlydHVhbE1GQURldmljZVByb3BzYFxuICpcbiAqIEByZXR1cm5zIHRoZSBBV1MgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiBhbiBgQVdTOjpJQU06OlZpcnR1YWxNRkFEZXZpY2VgIHJlc291cmNlLlxuICovXG4vLyBAdHMtaWdub3JlIFRTNjEzM1xuZnVuY3Rpb24gY2ZuVmlydHVhbE1GQURldmljZVByb3BzVG9DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBhbnkge1xuICAgIGlmICghY2RrLmNhbkluc3BlY3QocHJvcGVydGllcykpIHsgcmV0dXJuIHByb3BlcnRpZXM7IH1cbiAgICBDZm5WaXJ0dWFsTUZBRGV2aWNlUHJvcHNWYWxpZGF0b3IocHJvcGVydGllcykuYXNzZXJ0U3VjY2VzcygpO1xuICAgIHJldHVybiB7XG4gICAgICAgIFVzZXJzOiBjZGsubGlzdE1hcHBlcihjZGsuc3RyaW5nVG9DbG91ZEZvcm1hdGlvbikocHJvcGVydGllcy51c2VycyksXG4gICAgICAgIFBhdGg6IGNkay5zdHJpbmdUb0Nsb3VkRm9ybWF0aW9uKHByb3BlcnRpZXMucGF0aCksXG4gICAgICAgIFRhZ3M6IGNkay5saXN0TWFwcGVyKGNkay5jZm5UYWdUb0Nsb3VkRm9ybWF0aW9uKShwcm9wZXJ0aWVzLnRhZ3MpLFxuICAgICAgICBWaXJ0dWFsTWZhRGV2aWNlTmFtZTogY2RrLnN0cmluZ1RvQ2xvdWRGb3JtYXRpb24ocHJvcGVydGllcy52aXJ0dWFsTWZhRGV2aWNlTmFtZSksXG4gICAgfTtcbn1cblxuLy8gQHRzLWlnbm9yZSBUUzYxMzNcbmZ1bmN0aW9uIENmblZpcnR1YWxNRkFEZXZpY2VQcm9wc0Zyb21DbG91ZEZvcm1hdGlvbihwcm9wZXJ0aWVzOiBhbnkpOiBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUmVzdWx0PENmblZpcnR1YWxNRkFEZXZpY2VQcm9wcz4ge1xuICAgIHByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzID09IG51bGwgPyB7fSA6IHByb3BlcnRpZXM7XG4gICAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb25SZXN1bHQocHJvcGVydGllcyk7XG4gICAgfVxuICAgIGNvbnN0IHJldCA9IG5ldyBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uUHJvcGVydHlPYmplY3Q8Q2ZuVmlydHVhbE1GQURldmljZVByb3BzPigpO1xuICAgIHJldC5hZGRQcm9wZXJ0eVJlc3VsdCgndXNlcnMnLCAnVXNlcnMnLCBjZm5fcGFyc2UuRnJvbUNsb3VkRm9ybWF0aW9uLmdldFN0cmluZ0FycmF5KHByb3BlcnRpZXMuVXNlcnMpKTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3BhdGgnLCAnUGF0aCcsIHByb3BlcnRpZXMuUGF0aCAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5QYXRoKSA6IHVuZGVmaW5lZCk7XG4gICAgcmV0LmFkZFByb3BlcnR5UmVzdWx0KCd0YWdzJywgJ1RhZ3MnLCBwcm9wZXJ0aWVzLlRhZ3MgIT0gbnVsbCA/IGNmbl9wYXJzZS5Gcm9tQ2xvdWRGb3JtYXRpb24uZ2V0QXJyYXkoY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRDZm5UYWcpKHByb3BlcnRpZXMuVGFncykgOiB1bmRlZmluZWQgYXMgYW55KTtcbiAgICByZXQuYWRkUHJvcGVydHlSZXN1bHQoJ3ZpcnR1YWxNZmFEZXZpY2VOYW1lJywgJ1ZpcnR1YWxNZmFEZXZpY2VOYW1lJywgcHJvcGVydGllcy5WaXJ0dWFsTWZhRGV2aWNlTmFtZSAhPSBudWxsID8gY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbi5nZXRTdHJpbmcocHJvcGVydGllcy5WaXJ0dWFsTWZhRGV2aWNlTmFtZSkgOiB1bmRlZmluZWQpO1xuICAgIHJldC5hZGRVbnJlY29nbml6ZWRQcm9wZXJ0aWVzQXNFeHRyYShwcm9wZXJ0aWVzKTtcbiAgICByZXR1cm4gcmV0O1xufVxuXG4vKipcbiAqIEEgQ2xvdWRGb3JtYXRpb24gYEFXUzo6SUFNOjpWaXJ0dWFsTUZBRGV2aWNlYFxuICpcbiAqIENyZWF0ZXMgYSBuZXcgdmlydHVhbCBNRkEgZGV2aWNlIGZvciB0aGUgQVdTIGFjY291bnQgLiBBZnRlciBjcmVhdGluZyB0aGUgdmlydHVhbCBNRkEsIHVzZSBbRW5hYmxlTUZBRGV2aWNlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0VuYWJsZU1GQURldmljZS5odG1sKSB0byBhdHRhY2ggdGhlIE1GQSBkZXZpY2UgdG8gYW4gSUFNIHVzZXIuIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGNyZWF0aW5nIGFuZCB3b3JraW5nIHdpdGggdmlydHVhbCBNRkEgZGV2aWNlcywgc2VlIFtVc2luZyBhIHZpcnR1YWwgTUZBIGRldmljZV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL1VzaW5nX1ZpcnR1YWxNRkEuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICpcbiAqIEZvciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbWF4aW11bSBudW1iZXIgb2YgTUZBIGRldmljZXMgeW91IGNhbiBjcmVhdGUsIHNlZSBbSUFNIGFuZCBBV1MgU1RTIHF1b3Rhc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9pYW0tcXVvdGFzLmh0bWwpIGluIHRoZSAqSUFNIFVzZXIgR3VpZGUqIC5cbiAqXG4gKiA+IFRoZSBzZWVkIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBpbiB0aGUgUVIgY29kZSBhbmQgdGhlIEJhc2UzMiBzdHJpbmcgc2hvdWxkIGJlIHRyZWF0ZWQgbGlrZSBhbnkgb3RoZXIgc2VjcmV0IGFjY2VzcyBpbmZvcm1hdGlvbi4gSW4gb3RoZXIgd29yZHMsIHByb3RlY3QgdGhlIHNlZWQgaW5mb3JtYXRpb24gYXMgeW91IHdvdWxkIHlvdXIgQVdTIGFjY2VzcyBrZXlzIG9yIHlvdXIgcGFzc3dvcmRzLiBBZnRlciB5b3UgcHJvdmlzaW9uIHlvdXIgdmlydHVhbCBkZXZpY2UsIHlvdSBzaG91bGQgZW5zdXJlIHRoYXQgdGhlIGluZm9ybWF0aW9uIGlzIGRlc3Ryb3llZCBmb2xsb3dpbmcgc2VjdXJlIHByb2NlZHVyZXMuXG4gKlxuICogQGNsb3VkZm9ybWF0aW9uUmVzb3VyY2UgQVdTOjpJQU06OlZpcnR1YWxNRkFEZXZpY2VcbiAqIEBzdGFiaWxpdHkgZXh0ZXJuYWxcbiAqXG4gKiBAbGluayBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1pYW0tdmlydHVhbG1mYWRldmljZS5odG1sXG4gKi9cbmV4cG9ydCBjbGFzcyBDZm5WaXJ0dWFsTUZBRGV2aWNlIGV4dGVuZHMgY2RrLkNmblJlc291cmNlIGltcGxlbWVudHMgY2RrLklJbnNwZWN0YWJsZSB7XG4gICAgLyoqXG4gICAgICogVGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGUgbmFtZSBmb3IgdGhpcyByZXNvdXJjZSBjbGFzcy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IENGTl9SRVNPVVJDRV9UWVBFX05BTUUgPSBcIkFXUzo6SUFNOjpWaXJ0dWFsTUZBRGV2aWNlXCI7XG5cbiAgICAvKipcbiAgICAgKiBBIGZhY3RvcnkgbWV0aG9kIHRoYXQgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGZyb20gYW4gb2JqZWN0XG4gICAgICogY29udGFpbmluZyB0aGUgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllcyBvZiB0aGlzIHJlc291cmNlLlxuICAgICAqIFVzZWQgaW4gdGhlIEBhd3MtY2RrL2Nsb3VkZm9ybWF0aW9uLWluY2x1ZGUgbW9kdWxlLlxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBfZnJvbUNsb3VkRm9ybWF0aW9uKHNjb3BlOiBjZGsuQ29uc3RydWN0LCBpZDogc3RyaW5nLCByZXNvdXJjZUF0dHJpYnV0ZXM6IGFueSwgb3B0aW9uczogY2ZuX3BhcnNlLkZyb21DbG91ZEZvcm1hdGlvbk9wdGlvbnMpOiBDZm5WaXJ0dWFsTUZBRGV2aWNlIHtcbiAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzID0gcmVzb3VyY2VBdHRyaWJ1dGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByZXNvdXJjZVByb3BlcnRpZXMgPSBvcHRpb25zLnBhcnNlci5wYXJzZVZhbHVlKHJlc291cmNlQXR0cmlidXRlcy5Qcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcHJvcHNSZXN1bHQgPSBDZm5WaXJ0dWFsTUZBRGV2aWNlUHJvcHNGcm9tQ2xvdWRGb3JtYXRpb24ocmVzb3VyY2VQcm9wZXJ0aWVzKTtcbiAgICAgICAgY29uc3QgcmV0ID0gbmV3IENmblZpcnR1YWxNRkFEZXZpY2Uoc2NvcGUsIGlkLCBwcm9wc1Jlc3VsdC52YWx1ZSk7XG4gICAgICAgIGZvciAoY29uc3QgW3Byb3BLZXksIHByb3BWYWxdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzUmVzdWx0LmV4dHJhUHJvcGVydGllcykpICB7XG4gICAgICAgICAgICByZXQuYWRkUHJvcGVydHlPdmVycmlkZShwcm9wS2V5LCBwcm9wVmFsKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnBhcnNlci5oYW5kbGVBdHRyaWJ1dGVzKHJldCwgcmVzb3VyY2VBdHRyaWJ1dGVzLCBpZCk7XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgc2VyaWFsIG51bWJlciBmb3IgdGhlIHNwZWNpZmllZCBgQVdTOjpJQU06OlZpcnR1YWxNRkFEZXZpY2VgIHJlc291cmNlLlxuICAgICAqIEBjbG91ZGZvcm1hdGlvbkF0dHJpYnV0ZSBTZXJpYWxOdW1iZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgYXR0clNlcmlhbE51bWJlcjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIElBTSB1c2VyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHZpcnR1YWwgTUZBIGRldmljZS5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS12aXJ0dWFsbWZhZGV2aWNlLmh0bWwjY2ZuLWlhbS12aXJ0dWFsbWZhZGV2aWNlLXVzZXJzXG4gICAgICovXG4gICAgcHVibGljIHVzZXJzOiBzdHJpbmdbXTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwYXRoIGZvciB0aGUgdmlydHVhbCBNRkEgZGV2aWNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBwYXRocywgc2VlIFtJQU0gaWRlbnRpZmllcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9Vc2luZ19JZGVudGlmaWVycy5odG1sKSBpbiB0aGUgKklBTSBVc2VyIEd1aWRlKiAuXG4gICAgICpcbiAgICAgKiBUaGlzIHBhcmFtZXRlciBpcyBvcHRpb25hbC4gSWYgaXQgaXMgbm90IGluY2x1ZGVkLCBpdCBkZWZhdWx0cyB0byBhIHNsYXNoICgvKS5cbiAgICAgKlxuICAgICAqIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgW3JlZ2V4IHBhdHRlcm5dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9odHRwOi8vd2lraXBlZGlhLm9yZy93aWtpL3JlZ2V4KSApIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgY29uc2lzdGluZyBvZiBlaXRoZXIgYSBmb3J3YXJkIHNsYXNoICgvKSBieSBpdHNlbGYgb3IgYSBzdHJpbmcgdGhhdCBtdXN0IGJlZ2luIGFuZCBlbmQgd2l0aCBmb3J3YXJkIHNsYXNoZXMuIEluIGFkZGl0aW9uLCBpdCBjYW4gY29udGFpbiBhbnkgQVNDSUkgY2hhcmFjdGVyIGZyb20gdGhlICEgKCBgXFwgdTAwMjFgICkgdGhyb3VnaCB0aGUgREVMIGNoYXJhY3RlciAoIGBcXCB1MDA3RmAgKSwgaW5jbHVkaW5nIG1vc3QgcHVuY3R1YXRpb24gY2hhcmFjdGVycywgZGlnaXRzLCBhbmQgdXBwZXIgYW5kIGxvd2VyY2FzZWQgbGV0dGVycy5cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS12aXJ0dWFsbWZhZGV2aWNlLmh0bWwjY2ZuLWlhbS12aXJ0dWFsbWZhZGV2aWNlLXBhdGhcbiAgICAgKi9cbiAgICBwdWJsaWMgcGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIHRhZ3MgdGhhdCB5b3Ugd2FudCB0byBhdHRhY2ggdG8gdGhlIG5ldyBJQU0gdmlydHVhbCBNRkEgZGV2aWNlLiBFYWNoIHRhZyBjb25zaXN0cyBvZiBhIGtleSBuYW1lIGFuZCBhbiBhc3NvY2lhdGVkIHZhbHVlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0YWdnaW5nLCBzZWUgW1RhZ2dpbmcgSUFNIHJlc291cmNlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL2lkX3RhZ3MuaHRtbCkgaW4gdGhlICpJQU0gVXNlciBHdWlkZSogLlxuICAgICAqXG4gICAgICogPiBJZiBhbnkgb25lIG9mIHRoZSB0YWdzIGlzIGludmFsaWQgb3IgaWYgeW91IGV4Y2VlZCB0aGUgYWxsb3dlZCBtYXhpbXVtIG51bWJlciBvZiB0YWdzLCB0aGVuIHRoZSBlbnRpcmUgcmVxdWVzdCBmYWlscyBhbmQgdGhlIHJlc291cmNlIGlzIG5vdCBjcmVhdGVkLlxuICAgICAqXG4gICAgICogQGxpbmsgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaWFtLXZpcnR1YWxtZmFkZXZpY2UuaHRtbCNjZm4taWFtLXZpcnR1YWxtZmFkZXZpY2UtdGFnc1xuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB0YWdzOiBjZGsuVGFnTWFuYWdlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSB2aXJ0dWFsIE1GQSBkZXZpY2UsIHdoaWNoIG11c3QgYmUgdW5pcXVlLiBVc2Ugd2l0aCBwYXRoIHRvIHVuaXF1ZWx5IGlkZW50aWZ5IGEgdmlydHVhbCBNRkEgZGV2aWNlLlxuICAgICAqXG4gICAgICogVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyBbcmVnZXggcGF0dGVybl0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2h0dHA6Ly93aWtpcGVkaWEub3JnL3dpa2kvcmVnZXgpICkgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyBjb25zaXN0aW5nIG9mIHVwcGVyIGFuZCBsb3dlcmNhc2UgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCBubyBzcGFjZXMuIFlvdSBjYW4gYWxzbyBpbmNsdWRlIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6IF8rPSwuQC1cbiAgICAgKlxuICAgICAqIEBsaW5rIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWlhbS12aXJ0dWFsbWZhZGV2aWNlLmh0bWwjY2ZuLWlhbS12aXJ0dWFsbWZhZGV2aWNlLXZpcnR1YWxtZmFkZXZpY2VuYW1lXG4gICAgICovXG4gICAgcHVibGljIHZpcnR1YWxNZmFEZXZpY2VOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgYEFXUzo6SUFNOjpWaXJ0dWFsTUZBRGV2aWNlYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzY29wZSAtIHNjb3BlIGluIHdoaWNoIHRoaXMgcmVzb3VyY2UgaXMgZGVmaW5lZFxuICAgICAqIEBwYXJhbSBpZCAgICAtIHNjb3BlZCBpZCBvZiB0aGUgcmVzb3VyY2VcbiAgICAgKiBAcGFyYW0gcHJvcHMgLSByZXNvdXJjZSBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IGNkay5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDZm5WaXJ0dWFsTUZBRGV2aWNlUHJvcHMpIHtcbiAgICAgICAgc3VwZXIoc2NvcGUsIGlkLCB7IHR5cGU6IENmblZpcnR1YWxNRkFEZXZpY2UuQ0ZOX1JFU09VUkNFX1RZUEVfTkFNRSwgcHJvcGVydGllczogcHJvcHMgfSk7XG4gICAgICAgIGNkay5yZXF1aXJlUHJvcGVydHkocHJvcHMsICd1c2VycycsIHRoaXMpO1xuICAgICAgICB0aGlzLmF0dHJTZXJpYWxOdW1iZXIgPSBjZGsuVG9rZW4uYXNTdHJpbmcodGhpcy5nZXRBdHQoJ1NlcmlhbE51bWJlcicpKTtcblxuICAgICAgICB0aGlzLnVzZXJzID0gcHJvcHMudXNlcnM7XG4gICAgICAgIHRoaXMucGF0aCA9IHByb3BzLnBhdGg7XG4gICAgICAgIHRoaXMudGFncyA9IG5ldyBjZGsuVGFnTWFuYWdlcihjZGsuVGFnVHlwZS5TVEFOREFSRCwgXCJBV1M6OklBTTo6VmlydHVhbE1GQURldmljZVwiLCBwcm9wcy50YWdzLCB7IHRhZ1Byb3BlcnR5TmFtZTogJ3RhZ3MnIH0pO1xuICAgICAgICB0aGlzLnZpcnR1YWxNZmFEZXZpY2VOYW1lID0gcHJvcHMudmlydHVhbE1mYURldmljZU5hbWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhhbWluZXMgdGhlIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIGFuZCBkaXNjbG9zZXMgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnNwZWN0b3IgLSB0cmVlIGluc3BlY3RvciB0byBjb2xsZWN0IGFuZCBwcm9jZXNzIGF0dHJpYnV0ZXNcbiAgICAgKlxuICAgICAqL1xuICAgIHB1YmxpYyBpbnNwZWN0KGluc3BlY3RvcjogY2RrLlRyZWVJbnNwZWN0b3IpIHtcbiAgICAgICAgaW5zcGVjdG9yLmFkZEF0dHJpYnV0ZShcImF3czpjZGs6Y2xvdWRmb3JtYXRpb246dHlwZVwiLCBDZm5WaXJ0dWFsTUZBRGV2aWNlLkNGTl9SRVNPVVJDRV9UWVBFX05BTUUpO1xuICAgICAgICBpbnNwZWN0b3IuYWRkQXR0cmlidXRlKFwiYXdzOmNkazpjbG91ZGZvcm1hdGlvbjpwcm9wc1wiLCB0aGlzLmNmblByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY2ZuUHJvcGVydGllcygpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB1c2VyczogdGhpcy51c2VycyxcbiAgICAgICAgICAgIHBhdGg6IHRoaXMucGF0aCxcbiAgICAgICAgICAgIHRhZ3M6IHRoaXMudGFncy5yZW5kZXJUYWdzKCksXG4gICAgICAgICAgICB2aXJ0dWFsTWZhRGV2aWNlTmFtZTogdGhpcy52aXJ0dWFsTWZhRGV2aWNlTmFtZSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgcmVuZGVyUHJvcGVydGllcyhwcm9wczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ICB7XG4gICAgICAgIHJldHVybiBjZm5WaXJ0dWFsTUZBRGV2aWNlUHJvcHNUb0Nsb3VkRm9ybWF0aW9uKHByb3BzKTtcbiAgICB9XG59XG4iXX0=