UNPKG

iam-floyd

Version:

AWS IAM policy statement generator with fluent interface

674 lines 68.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Elasticloadbalancing = void 0; const shared_1 = require("../../shared"); /** * Statement provider for service [elasticloadbalancing](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awselasticloadbalancing.html). * * @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement */ class Elasticloadbalancing extends shared_1.PolicyStatement { /** * Statement provider for service [elasticloadbalancing](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awselasticloadbalancing.html). * * @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement */ constructor(sid) { super(sid); this.servicePrefix = 'elasticloadbalancing'; this.accessLevelList = { Tagging: [ 'AddTags', 'RemoveTags' ], Write: [ 'ApplySecurityGroupsToLoadBalancer', 'AttachLoadBalancerToSubnets', 'ConfigureHealthCheck', 'CreateAppCookieStickinessPolicy', 'CreateLBCookieStickinessPolicy', 'CreateLoadBalancer', 'CreateLoadBalancerListeners', 'CreateLoadBalancerPolicy', 'DeleteLoadBalancer', 'DeleteLoadBalancerListeners', 'DeleteLoadBalancerPolicy', 'DeregisterInstancesFromLoadBalancer', 'DetachLoadBalancerFromSubnets', 'DisableAvailabilityZonesForLoadBalancer', 'EnableAvailabilityZonesForLoadBalancer', 'ModifyLoadBalancerAttributes', 'RegisterInstancesWithLoadBalancer', 'SetLoadBalancerListenerSSLCertificate', 'SetLoadBalancerPoliciesForBackendServer', 'SetLoadBalancerPoliciesOfListener' ], Read: [ 'DescribeInstanceHealth', 'DescribeLoadBalancerAttributes', 'DescribeLoadBalancerPolicies', 'DescribeLoadBalancerPolicyTypes', 'DescribeTags' ], List: [ 'DescribeLoadBalancers' ] }; } /** * Grants permission to add the specified tags to the specified load balancer. Each load balancer can have a maximum of 10 tags * * Access Level: Tagging * * Possible conditions: * - .ifAwsRequestTag() * - .ifAwsTagKeys() * - .ifAwsResourceTag() * - .ifResourceTag() * - .ifCreateAction() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_AddTags.html */ toAddTags() { return this.to('AddTags'); } /** * Grants permission to associate one or more security groups with your load balancer in a virtual private cloud (VPC) * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * - .ifSecurityGroup() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_ApplySecurityGroupsToLoadBalancer.html */ toApplySecurityGroupsToLoadBalancer() { return this.to('ApplySecurityGroupsToLoadBalancer'); } /** * Grants permission to add one or more subnets to the set of configured subnets for the specified load balancer * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * - .ifSubnet() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_AttachLoadBalancerToSubnets.html */ toAttachLoadBalancerToSubnets() { return this.to('AttachLoadBalancerToSubnets'); } /** * Grants permission to specify the health check settings to use when evaluating the health state of your back-end instances * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_ConfigureHealthCheck.html */ toConfigureHealthCheck() { return this.to('ConfigureHealthCheck'); } /** * Grants permission to generate a stickiness policy with sticky session lifetimes that follow that of an application-generated cookie * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_CreateAppCookieStickinessPolicy.html */ toCreateAppCookieStickinessPolicy() { return this.to('CreateAppCookieStickinessPolicy'); } /** * Grants permission to generate a stickiness policy with sticky session lifetimes controlled by the lifetime of the browser (user-agent) or a specified expiration period * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_CreateLBCookieStickinessPolicy.html */ toCreateLBCookieStickinessPolicy() { return this.to('CreateLBCookieStickinessPolicy'); } /** * Grants permission to create a load balancer * * Access Level: Write * * Possible conditions: * - .ifAwsRequestTag() * - .ifAwsTagKeys() * - .ifAwsResourceTag() * - .ifResourceTag() * - .ifSecurityGroup() * - .ifSubnet() * - .ifScheme() * - .ifListenerProtocol() * * Dependent actions: * - elasticloadbalancing:AddTags * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_CreateLoadBalancer.html */ toCreateLoadBalancer() { return this.to('CreateLoadBalancer'); } /** * Grants permission to create one or more listeners for the specified load balancer * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * - .ifListenerProtocol() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_CreateLoadBalancerListeners.html */ toCreateLoadBalancerListeners() { return this.to('CreateLoadBalancerListeners'); } /** * Grants permission to create a policy with the specified attributes for the specified load balancer * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * - .ifSecurityPolicy() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_CreateLoadBalancerPolicy.html */ toCreateLoadBalancerPolicy() { return this.to('CreateLoadBalancerPolicy'); } /** * Grants permission to delete the specified load balancer * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DeleteLoadBalancer.html */ toDeleteLoadBalancer() { return this.to('DeleteLoadBalancer'); } /** * Grants permission to delete the specified listeners from the specified load balancer * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DeleteLoadBalancerListeners.html */ toDeleteLoadBalancerListeners() { return this.to('DeleteLoadBalancerListeners'); } /** * Grants permission to delete the specified policy from the specified load balancer. This policy must not be enabled for any listeners * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DeleteLoadBalancerPolicy.html */ toDeleteLoadBalancerPolicy() { return this.to('DeleteLoadBalancerPolicy'); } /** * Grants permission to deregister the specified instances from the specified load balancer * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DeregisterInstancesFromLoadBalancer.html */ toDeregisterInstancesFromLoadBalancer() { return this.to('DeregisterInstancesFromLoadBalancer'); } /** * Grants permission to describe the state of the specified instances with respect to the specified load balancer * * Access Level: Read * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeInstanceHealth.html */ toDescribeInstanceHealth() { return this.to('DescribeInstanceHealth'); } /** * Grants permission to describe the attributes for the specified load balancer * * Access Level: Read * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeLoadBalancerAttributes.html */ toDescribeLoadBalancerAttributes() { return this.to('DescribeLoadBalancerAttributes'); } /** * Grants permission to describe the specified policies * * Access Level: Read * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeLoadBalancerPolicies.html */ toDescribeLoadBalancerPolicies() { return this.to('DescribeLoadBalancerPolicies'); } /** * Grants permission to describe the specified load balancer policy types * * Access Level: Read * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeLoadBalancerPolicyTypes.html */ toDescribeLoadBalancerPolicyTypes() { return this.to('DescribeLoadBalancerPolicyTypes'); } /** * Grants permission to describe the specified the load balancers. If no load balancers are specified, the call describes all of your load balancers * * Access Level: List * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeLoadBalancers.html */ toDescribeLoadBalancers() { return this.to('DescribeLoadBalancers'); } /** * Grants permission to describe the tags associated with the specified load balancers * * Access Level: Read * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeTags.html */ toDescribeTags() { return this.to('DescribeTags'); } /** * Grants permission to remove the specified subnets from the set of configured subnets for the load balancer * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DetachLoadBalancerFromSubnets.html */ toDetachLoadBalancerFromSubnets() { return this.to('DetachLoadBalancerFromSubnets'); } /** * Grants permission to remove the specified Availability Zones from the set of Availability Zones for the specified load balancer * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DisableAvailabilityZonesForLoadBalancer.html */ toDisableAvailabilityZonesForLoadBalancer() { return this.to('DisableAvailabilityZonesForLoadBalancer'); } /** * Grants permission to add the specified Availability Zones to the set of Availability Zones for the specified load balancer * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_EnableAvailabilityZonesForLoadBalancer.html */ toEnableAvailabilityZonesForLoadBalancer() { return this.to('EnableAvailabilityZonesForLoadBalancer'); } /** * Grants permission to modify the attributes of the specified load balancer * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_ModifyLoadBalancerAttributes.html */ toModifyLoadBalancerAttributes() { return this.to('ModifyLoadBalancerAttributes'); } /** * Grants permission to add the specified instances to the specified load balancer * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_RegisterInstancesWithLoadBalancer.html */ toRegisterInstancesWithLoadBalancer() { return this.to('RegisterInstancesWithLoadBalancer'); } /** * Grants permission to remove one or more tags from the specified load balancer * * Access Level: Tagging * * Possible conditions: * - .ifAwsRequestTag() * - .ifAwsTagKeys() * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_RemoveTags.html */ toRemoveTags() { return this.to('RemoveTags'); } /** * Grants permission to set the certificate that terminates the specified listener's SSL connections * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_SetLoadBalancerListenerSSLCertificate.html */ toSetLoadBalancerListenerSSLCertificate() { return this.to('SetLoadBalancerListenerSSLCertificate'); } /** * Grants permission to replace the set of policies associated with the specified port on which the back-end server is listening with a new set of policies * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_SetLoadBalancerPoliciesForBackendServer.html */ toSetLoadBalancerPoliciesForBackendServer() { return this.to('SetLoadBalancerPoliciesForBackendServer'); } /** * Grants permission to replace the current set of policies for the specified load balancer port with the specified set of policies * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() * - .ifSecurityPolicy() * * https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_SetLoadBalancerPoliciesOfListener.html */ toSetLoadBalancerPoliciesOfListener() { return this.to('SetLoadBalancerPoliciesOfListener'); } /** * Adds a resource of type loadbalancer to the statement * * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/what-is-load-balancing.html * * @param loadBalancerName - Identifier for the loadBalancerName. * @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account. * @param region - Region of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's region. * @param partition - Partition of the AWS account [aws, aws-cn, aws-us-gov]; defaults to `aws`, unless using the CDK, where the default is the current Stack's partition. * * Possible conditions: * - .ifAwsResourceTag() * - .ifResourceTag() */ onLoadbalancer(loadBalancerName, account, region, partition) { return this.on(`arn:${partition ?? this.defaultPartition}:elasticloadbalancing:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:loadbalancer/${loadBalancerName}`); } /** * Filters access by a tag key and value pair that is allowed in the request * * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag * * Applies to actions: * - .toAddTags() * - .toCreateLoadBalancer() * - .toRemoveTags() * * @param tagKey The tag key to check * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifAwsRequestTag(tagKey, value, operator) { return this.if(`aws:RequestTag/${tagKey}`, value, operator ?? 'StringLike'); } /** * Filters access by a tag key and value pair of a resource * * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag * * Applies to actions: * - .toAddTags() * - .toApplySecurityGroupsToLoadBalancer() * - .toAttachLoadBalancerToSubnets() * - .toConfigureHealthCheck() * - .toCreateAppCookieStickinessPolicy() * - .toCreateLBCookieStickinessPolicy() * - .toCreateLoadBalancer() * - .toCreateLoadBalancerListeners() * - .toCreateLoadBalancerPolicy() * - .toDeleteLoadBalancer() * - .toDeleteLoadBalancerListeners() * - .toDeleteLoadBalancerPolicy() * - .toDeregisterInstancesFromLoadBalancer() * - .toDetachLoadBalancerFromSubnets() * - .toDisableAvailabilityZonesForLoadBalancer() * - .toEnableAvailabilityZonesForLoadBalancer() * - .toModifyLoadBalancerAttributes() * - .toRegisterInstancesWithLoadBalancer() * - .toRemoveTags() * - .toSetLoadBalancerListenerSSLCertificate() * - .toSetLoadBalancerPoliciesForBackendServer() * - .toSetLoadBalancerPoliciesOfListener() * * Applies to resource types: * - loadbalancer * * @param tagKey The tag key to check * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifAwsResourceTag(tagKey, value, operator) { return this.if(`aws:ResourceTag/${tagKey}`, value, operator ?? 'StringLike'); } /** * Filters access by a list of tag keys that are allowed in the request * * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys * * Applies to actions: * - .toAddTags() * - .toCreateLoadBalancer() * - .toRemoveTags() * * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifAwsTagKeys(value, operator) { return this.if(`aws:TagKeys`, value, operator ?? 'StringLike'); } /** * Filters access by the name of a resource-creating API action * * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/tagging-resources-during-creation.html * * Applies to actions: * - .toAddTags() * * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifCreateAction(value, operator) { return this.if(`CreateAction`, value, operator ?? 'StringLike'); } /** * Filters access by the listener protocols that are allowed in the request * * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/security_iam_service-with-iam.html#listenerprotocol-condition * * Applies to actions: * - .toCreateLoadBalancer() * - .toCreateLoadBalancerListeners() * * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifListenerProtocol(value, operator) { return this.if(`ListenerProtocol`, value, operator ?? 'StringLike'); } /** * Filters access by the preface string for a tag key and value pair that are attached to a resource * * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag * * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifResourceTagExists(value, operator) { return this.if(`ResourceTag/`, value, operator ?? 'StringLike'); } /** * Filters access by the preface string for a tag key and value pair that are attached to a resource * * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag * * Applies to actions: * - .toAddTags() * - .toApplySecurityGroupsToLoadBalancer() * - .toAttachLoadBalancerToSubnets() * - .toConfigureHealthCheck() * - .toCreateAppCookieStickinessPolicy() * - .toCreateLBCookieStickinessPolicy() * - .toCreateLoadBalancer() * - .toCreateLoadBalancerListeners() * - .toCreateLoadBalancerPolicy() * - .toDeleteLoadBalancer() * - .toDeleteLoadBalancerListeners() * - .toDeleteLoadBalancerPolicy() * - .toDeregisterInstancesFromLoadBalancer() * - .toDetachLoadBalancerFromSubnets() * - .toDisableAvailabilityZonesForLoadBalancer() * - .toEnableAvailabilityZonesForLoadBalancer() * - .toModifyLoadBalancerAttributes() * - .toRegisterInstancesWithLoadBalancer() * - .toRemoveTags() * - .toSetLoadBalancerListenerSSLCertificate() * - .toSetLoadBalancerPoliciesForBackendServer() * - .toSetLoadBalancerPoliciesOfListener() * * Applies to resource types: * - loadbalancer * * @param tagKey The tag key to check * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifResourceTagTagKey(tagKey, value, operator) { return this.if(`ResourceTag/${tagKey}`, value, operator ?? 'StringLike'); } /** * Filters access by the load balancer scheme that are allowed in the request * * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/security_iam_service-with-iam.html#scheme-condition * * Applies to actions: * - .toCreateLoadBalancer() * * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifScheme(value, operator) { return this.if(`Scheme`, value, operator ?? 'StringLike'); } /** * Filters access by the security-group IDs that are allowed in the request * * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/security_iam_service-with-iam.html#securitygroup-condition * * Applies to actions: * - .toApplySecurityGroupsToLoadBalancer() * - .toCreateLoadBalancer() * * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifSecurityGroup(value, operator) { return this.if(`SecurityGroup`, value, operator ?? 'StringLike'); } /** * Filters access by the SSL Security Policies that are allowed in the request * * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/security_iam_service-with-iam.html#securitypolicy-condition * * Applies to actions: * - .toCreateLoadBalancerPolicy() * - .toSetLoadBalancerPoliciesOfListener() * * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifSecurityPolicy(value, operator) { return this.if(`SecurityPolicy`, value, operator ?? 'StringLike'); } /** * Filters access by the subnet IDs that are allowed in the request * * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/security_iam_service-with-iam.html#subnet-condition * * Applies to actions: * - .toAttachLoadBalancerToSubnets() * - .toCreateLoadBalancer() * * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifSubnet(value, operator) { return this.if(`Subnet`, value, operator ?? 'StringLike'); } } exports.Elasticloadbalancing = Elasticloadbalancing; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxhc3RpY2xvYWRiYWxhbmNpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJlbGFzdGljbG9hZGJhbGFuY2luZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSx5Q0FBeUQ7QUFFekQ7Ozs7R0FJRztBQUNILE1BQWEsb0JBQXFCLFNBQVEsd0JBQWU7SUFHdkQ7Ozs7T0FJRztJQUNILFlBQVksR0FBWTtRQUN0QixLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFSTixrQkFBYSxHQUFHLHNCQUFzQixDQUFDO1FBMGFwQyxvQkFBZSxHQUFvQjtZQUMzQyxPQUFPLEVBQUU7Z0JBQ1AsU0FBUztnQkFDVCxZQUFZO2FBQ2I7WUFDRCxLQUFLLEVBQUU7Z0JBQ0wsbUNBQW1DO2dCQUNuQyw2QkFBNkI7Z0JBQzdCLHNCQUFzQjtnQkFDdEIsaUNBQWlDO2dCQUNqQyxnQ0FBZ0M7Z0JBQ2hDLG9CQUFvQjtnQkFDcEIsNkJBQTZCO2dCQUM3QiwwQkFBMEI7Z0JBQzFCLG9CQUFvQjtnQkFDcEIsNkJBQTZCO2dCQUM3QiwwQkFBMEI7Z0JBQzFCLHFDQUFxQztnQkFDckMsK0JBQStCO2dCQUMvQix5Q0FBeUM7Z0JBQ3pDLHdDQUF3QztnQkFDeEMsOEJBQThCO2dCQUM5QixtQ0FBbUM7Z0JBQ25DLHVDQUF1QztnQkFDdkMseUNBQXlDO2dCQUN6QyxtQ0FBbUM7YUFDcEM7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osd0JBQXdCO2dCQUN4QixnQ0FBZ0M7Z0JBQ2hDLDhCQUE4QjtnQkFDOUIsaUNBQWlDO2dCQUNqQyxjQUFjO2FBQ2Y7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osdUJBQXVCO2FBQ3hCO1NBQ0YsQ0FBQztJQXRjRixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNJLFNBQVM7UUFDZCxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVEOzs7Ozs7Ozs7OztPQVdHO0lBQ0ksbUNBQW1DO1FBQ3hDLE9B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QXdCLEVBQUUsUUFBNEI7UUFDL0YsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGVBQWdCLE1BQU8sRUFBRSxFQUFFLEtBQUssRUFBRSxRQUFRLElBQUksWUFBWSxDQUFDLENBQUM7SUFDN0UsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSxRQUFRLENBQUMsS0FBd0IsRUFBRSxRQUE0QjtRQUNwRSxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxRQUFRLElBQUksWUFBWSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVEOzs7Ozs7Ozs7OztPQVdHO0lBQ0ksZUFBZSxDQUFDLEtBQXdCLEVBQUUsUUFBNEI7UUFDM0UsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGVBQWUsRUFBRSxLQUFLLEVBQUUsUUFBUSxJQUFJLFlBQVksQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7T0FXRztJQUNJLGdCQUFnQixDQUFDLEtBQXdCLEVBQUUsUUFBNEI7UUFDNUUsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGdCQUFnQixFQUFFLEtBQUssRUFBRSxRQUFRLElBQUksWUFBWSxDQUFDLENBQUM7SUFDcEUsQ0FBQztJQUVEOzs7Ozs7Ozs7OztPQVdHO0lBQ0ksUUFBUSxDQUFDLEtBQXdCLEVBQUUsUUFBNEI7UUFDcEUsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxJQUFJLFlBQVksQ0FBQyxDQUFDO0lBQzVELENBQUM7Q0FDRjtBQWhzQkQsb0RBZ3NCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFjY2Vzc0xldmVsTGlzdCB9IGZyb20gJy4uLy4uL3NoYXJlZC9hY2Nlc3MtbGV2ZWwnO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50LCBPcGVyYXRvciB9IGZyb20gJy4uLy4uL3NoYXJlZCc7XG5cbi8qKlxuICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFtlbGFzdGljbG9hZGJhbGFuY2luZ10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYXdzZWxhc3RpY2xvYWRiYWxhbmNpbmcuaHRtbCkuXG4gKlxuICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBFbGFzdGljbG9hZGJhbGFuY2luZyBleHRlbmRzIFBvbGljeVN0YXRlbWVudCB7XG4gIHB1YmxpYyBzZXJ2aWNlUHJlZml4ID0gJ2VsYXN0aWNsb2FkYmFsYW5jaW5nJztcblxuICAvKipcbiAgICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFtlbGFzdGljbG9hZGJhbGFuY2luZ10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYXdzZWxhc3RpY2xvYWRiYWxhbmNpbmcuaHRtbCkuXG4gICAqXG4gICAqIEBwYXJhbSBzaWQgW1NJRF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19zaWQuaHRtbCkgb2YgdGhlIHN0YXRlbWVudFxuICAgKi9cbiAgY29uc3RydWN0b3Ioc2lkPzogc3RyaW5nKSB7XG4gICAgc3VwZXIoc2lkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhZGQgdGhlIHNwZWNpZmllZCB0YWdzIHRvIHRoZSBzcGVjaWZpZWQgbG9hZCBiYWxhbmNlci4gRWFjaCBsb2FkIGJhbGFuY2VyIGNhbiBoYXZlIGEgbWF4aW11bSBvZiAxMCB0YWdzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICogLSAuaWZSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmQ3JlYXRlQWN0aW9uKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9BZGRUYWdzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0FkZFRhZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0FkZFRhZ3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhc3NvY2lhdGUgb25lIG9yIG1vcmUgc2VjdXJpdHkgZ3JvdXBzIHdpdGggeW91ciBsb2FkIGJhbGFuY2VyIGluIGEgdmlydHVhbCBwcml2YXRlIGNsb3VkIChWUEMpXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmUmVzb3VyY2VUYWcoKVxuICAgKiAtIC5pZlNlY3VyaXR5R3JvdXAoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0FwcGx5U2VjdXJpdHlHcm91cHNUb0xvYWRCYWxhbmNlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9BcHBseVNlY3VyaXR5R3JvdXBzVG9Mb2FkQmFsYW5jZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0FwcGx5U2VjdXJpdHlHcm91cHNUb0xvYWRCYWxhbmNlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFkZCBvbmUgb3IgbW9yZSBzdWJuZXRzIHRvIHRoZSBzZXQgb2YgY29uZmlndXJlZCBzdWJuZXRzIGZvciB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICogLSAuaWZSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmU3VibmV0KClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9BdHRhY2hMb2FkQmFsYW5jZXJUb1N1Ym5ldHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQXR0YWNoTG9hZEJhbGFuY2VyVG9TdWJuZXRzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdBdHRhY2hMb2FkQmFsYW5jZXJUb1N1Ym5ldHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBzcGVjaWZ5IHRoZSBoZWFsdGggY2hlY2sgc2V0dGluZ3MgdG8gdXNlIHdoZW4gZXZhbHVhdGluZyB0aGUgaGVhbHRoIHN0YXRlIG9mIHlvdXIgYmFjay1lbmQgaW5zdGFuY2VzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0NvbmZpZ3VyZUhlYWx0aENoZWNrLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NvbmZpZ3VyZUhlYWx0aENoZWNrKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDb25maWd1cmVIZWFsdGhDaGVjaycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdlbmVyYXRlIGEgc3RpY2tpbmVzcyBwb2xpY3kgd2l0aCBzdGlja3kgc2Vzc2lvbiBsaWZldGltZXMgdGhhdCBmb2xsb3cgdGhhdCBvZiBhbiBhcHBsaWNhdGlvbi1nZW5lcmF0ZWQgY29va2llXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZUFwcENvb2tpZVN0aWNraW5lc3NQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlQXBwQ29va2llU3RpY2tpbmVzc1BvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlQXBwQ29va2llU3RpY2tpbmVzc1BvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdlbmVyYXRlIGEgc3RpY2tpbmVzcyBwb2xpY3kgd2l0aCBzdGlja3kgc2Vzc2lvbiBsaWZldGltZXMgY29udHJvbGxlZCBieSB0aGUgbGlmZXRpbWUgb2YgdGhlIGJyb3dzZXIgKHVzZXItYWdlbnQpIG9yIGEgc3BlY2lmaWVkIGV4cGlyYXRpb24gcGVyaW9kXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZUxCQ29va2llU3RpY2tpbmVzc1BvbGljeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVMQkNvb2tpZVN0aWNraW5lc3NQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZUxCQ29va2llU3RpY2tpbmVzc1BvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICogLSAuaWZSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmU2VjdXJpdHlHcm91cCgpXG4gICAqIC0gLmlmU3VibmV0KClcbiAgICogLSAuaWZTY2hlbWUoKVxuICAgKiAtIC5pZkxpc3RlbmVyUHJvdG9jb2woKVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBlbGFzdGljbG9hZGJhbGFuY2luZzpBZGRUYWdzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlTG9hZEJhbGFuY2VyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZUxvYWRCYWxhbmNlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlTG9hZEJhbGFuY2VyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIG9uZSBvciBtb3JlIGxpc3RlbmVycyBmb3IgdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmUmVzb3VyY2VUYWcoKVxuICAgKiAtIC5pZkxpc3RlbmVyUHJvdG9jb2woKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZUxvYWRCYWxhbmNlckxpc3RlbmVycy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVMb2FkQmFsYW5jZXJMaXN0ZW5lcnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZUxvYWRCYWxhbmNlckxpc3RlbmVycycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIHBvbGljeSB3aXRoIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlcyBmb3IgdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmUmVzb3VyY2VUYWcoKVxuICAgKiAtIC5pZlNlY3VyaXR5UG9saWN5KClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVMb2FkQmFsYW5jZXJQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlTG9hZEJhbGFuY2VyUG9saWN5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVMb2FkQmFsYW5jZXJQb2xpY3knKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZUxvYWRCYWxhbmNlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVMb2FkQmFsYW5jZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZUxvYWRCYWxhbmNlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSB0aGUgc3BlY2lmaWVkIGxpc3RlbmVycyBmcm9tIHRoZSBzcGVjaWZpZWQgbG9hZCBiYWxhbmNlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKiAtIC5pZlJlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVMb2FkQmFsYW5jZXJMaXN0ZW5lcnMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlTG9hZEJhbGFuY2VyTGlzdGVuZXJzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVMb2FkQmFsYW5jZXJMaXN0ZW5lcnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgdGhlIHNwZWNpZmllZCBwb2xpY3kgZnJvbSB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXIuIFRoaXMgcG9saWN5IG11c3Qgbm90IGJlIGVuYWJsZWQgZm9yIGFueSBsaXN0ZW5lcnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICogLSAuaWZSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlTG9hZEJhbGFuY2VyUG9saWN5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZUxvYWRCYWxhbmNlclBvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlTG9hZEJhbGFuY2VyUG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVyZWdpc3RlciB0aGUgc3BlY2lmaWVkIGluc3RhbmNlcyBmcm9tIHRoZSBzcGVjaWZpZWQgbG9hZCBiYWxhbmNlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKiAtIC5pZlJlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9EZXJlZ2lzdGVySW5zdGFuY2VzRnJvbUxvYWRCYWxhbmNlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXJlZ2lzdGVySW5zdGFuY2VzRnJvbUxvYWRCYWxhbmNlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVyZWdpc3Rlckluc3RhbmNlc0Zyb21Mb2FkQmFsYW5jZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgc3RhdGUgb2YgdGhlIHNwZWNpZmllZCBpbnN0YW5jZXMgd2l0aCByZXNwZWN0IHRvIHRoZSBzcGVjaWZpZWQgbG9hZCBiYWxhbmNlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUluc3RhbmNlSGVhbHRoLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlSW5zdGFuY2VIZWFsdGgoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlSW5zdGFuY2VIZWFsdGgnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgYXR0cmlidXRlcyBmb3IgdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlTG9hZEJhbGFuY2VyQXR0cmlidXRlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUxvYWRCYWxhbmNlckF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlTG9hZEJhbGFuY2VyQXR0cmlidXRlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSBzcGVjaWZpZWQgcG9saWNpZXNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVMb2FkQmFsYW5jZXJQb2xpY2llcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUxvYWRCYWxhbmNlclBvbGljaWVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUxvYWRCYWxhbmNlclBvbGljaWVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyIHBvbGljeSB0eXBlc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUxvYWRCYWxhbmNlclBvbGljeVR5cGVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlTG9hZEJhbGFuY2VyUG9saWN5VHlwZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlTG9hZEJhbGFuY2VyUG9saWN5VHlwZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgc3BlY2lmaWVkIHRoZSBsb2FkIGJhbGFuY2Vycy4gSWYgbm8gbG9hZCBiYWxhbmNlcnMgYXJlIHNwZWNpZmllZCwgdGhlIGNhbGwgZGVzY3JpYmVzIGFsbCBvZiB5b3VyIGxvYWQgYmFsYW5jZXJzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlTG9hZEJhbGFuY2Vycy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUxvYWRCYWxhbmNlcnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlTG9hZEJhbGFuY2VycycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSB0YWdzIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlVGFncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVRhZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlVGFncycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSB0aGUgc3BlY2lmaWVkIHN1Ym5ldHMgZnJvbSB0aGUgc2V0IG9mIGNvbmZpZ3VyZWQgc3VibmV0cyBmb3IgdGhlIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICogLSAuaWZSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfRGV0YWNoTG9hZEJhbGFuY2VyRnJvbVN1Ym5ldHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGV0YWNoTG9hZEJhbGFuY2VyRnJvbVN1Ym5ldHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RldGFjaExvYWRCYWxhbmNlckZyb21TdWJuZXRzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIHRoZSBzcGVjaWZpZWQgQXZhaWxhYmlsaXR5IFpvbmVzIGZyb20gdGhlIHNldCBvZiBBdmFpbGFiaWxpdHkgWm9uZXMgZm9yIHRoZSBzcGVjaWZpZWQgbG9hZCBiYWxhbmNlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKiAtIC5pZlJlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9EaXNhYmxlQXZhaWxhYmlsaXR5Wm9uZXNGb3JMb2FkQmFsYW5jZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGlzYWJsZUF2YWlsYWJpbGl0eVpvbmVzRm9yTG9hZEJhbGFuY2VyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEaXNhYmxlQXZhaWxhYmlsaXR5Wm9uZXNGb3JMb2FkQmFsYW5jZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhZGQgdGhlIHNwZWNpZmllZCBBdmFpbGFiaWxpdHkgWm9uZXMgdG8gdGhlIHNldCBvZiBBdmFpbGFiaWxpdHkgWm9uZXMgZm9yIHRoZSBzcGVjaWZpZWQgbG9hZCBiYWxhbmNlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKiAtIC5pZlJlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9FbmFibGVBdmFpbGFiaWxpdHlab25lc0ZvckxvYWRCYWxhbmNlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9FbmFibGVBdmFpbGFiaWxpdHlab25lc0ZvckxvYWRCYWxhbmNlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRW5hYmxlQXZhaWxhYmlsaXR5Wm9uZXNGb3JMb2FkQmFsYW5jZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBtb2RpZnkgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIHNwZWNpZmllZCBsb2FkIGJhbGFuY2VyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvMjAxMi0wNi0wMS9BUElSZWZlcmVuY2UvQVBJX01vZGlmeUxvYWRCYWxhbmNlckF0dHJpYnV0ZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTW9kaWZ5TG9hZEJhbGFuY2VyQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTW9kaWZ5TG9hZEJhbGFuY2VyQXR0cmlidXRlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFkZCB0aGUgc3BlY2lmaWVkIGluc3RhbmNlcyB0byB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICogLSAuaWZSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lbGFzdGljbG9hZGJhbGFuY2luZy8yMDEyLTA2LTAxL0FQSVJlZmVyZW5jZS9BUElfUmVnaXN0ZXJJbnN0YW5jZXNXaXRoTG9hZEJhbGFuY2VyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlZ2lzdGVySW5zdGFuY2VzV2l0aExvYWRCYWxhbmNlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUmVnaXN0ZXJJbnN0YW5jZXNXaXRoTG9hZEJhbGFuY2VyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIG9uZSBvciBtb3JlIHRhZ3MgZnJvbSB0aGUgc3BlY2lmaWVkIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKiAtIC5pZlJlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nLzIwMTItMDYtMDEvQVBJUmVmZXJlbmNlL0FQSV9SZW1vdmVUYWdzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlbW92ZVRhZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1JlbW92ZVRhZ3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBzZXQgdGhlIGNlcnRpZmljYXRlIHRoYXQgdGVybWluYXRlcyB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyJ3MgU1NMIGNvbm5lY3Rpb25zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gI