cdk-iam-floyd
Version:
AWS IAM policy statement generator with fluent interface for AWS CDK
2,353 lines • 235 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Elasticache = void 0;
const shared_1 = require("../../shared");
/**
* Statement provider for service [elasticache](https://docs.aws.amazon.com/service-authorization/latest/reference/list_elasticache.html).
*
* @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
*/
class Elasticache extends shared_1.PolicyStatement {
/**
* Grants permission to add tags to an ElastiCache resource
*
* Access Level: Tagging, Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_AddTagsToResource.html
*/
toAddTagsToResource() {
return this.to('AddTagsToResource');
}
/**
* Grants permission to authorize an EC2 security group on a ElastiCache security group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_AuthorizeCacheSecurityGroupIngress.html
*/
toAuthorizeCacheSecurityGroupIngress() {
return this.to('AuthorizeCacheSecurityGroupIngress');
}
/**
* Grants permission to apply ElastiCache service updates to sets of clusters and replication groups
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_BatchApplyUpdateAction.html
*/
toBatchApplyUpdateAction() {
return this.to('BatchApplyUpdateAction');
}
/**
* Grants permission to stop ElastiCache service updates from being executed on a set of clusters
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_BatchStopUpdateAction.html
*/
toBatchStopUpdateAction() {
return this.to('BatchStopUpdateAction');
}
/**
* Grants permission to complete an online migration of data from hosted Redis on Amazon EC2 to ElastiCache
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CompleteMigration.html
*/
toCompleteMigration() {
return this.to('CompleteMigration');
}
/**
* Grants permission to connect as a specified ElastiCache user to an ElastiCache Replication Group or ElastiCache serverless cache
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/auth-iam.html
*/
toConnect() {
return this.to('Connect');
}
/**
* Grants permission to make a copy of an existing serverless cache snapshot
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CopyServerlessCacheSnapshot.html
*/
toCopyServerlessCacheSnapshot() {
return this.to('CopyServerlessCacheSnapshot');
}
/**
* Grants permission to make a copy of an existing snapshot
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CopySnapshot.html
*/
toCopySnapshot() {
return this.to('CopySnapshot');
}
/**
* Grants permission to create a cache cluster
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CreateCacheCluster.html
*/
toCreateCacheCluster() {
return this.to('CreateCacheCluster');
}
/**
* Grants permission to create a parameter group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CreateCacheParameterGroup.html
*/
toCreateCacheParameterGroup() {
return this.to('CreateCacheParameterGroup');
}
/**
* Grants permission to create a cache security group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CreateCacheSecurityGroup.html
*/
toCreateCacheSecurityGroup() {
return this.to('CreateCacheSecurityGroup');
}
/**
* Grants permission to create a cache subnet group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CreateCacheSubnetGroup.html
*/
toCreateCacheSubnetGroup() {
return this.to('CreateCacheSubnetGroup');
}
/**
* Grants permission to create a global replication group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CreateGlobalReplicationGroup.html
*/
toCreateGlobalReplicationGroup() {
return this.to('CreateGlobalReplicationGroup');
}
/**
* Grants permission to create a replication group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CreateReplicationGroup.html
*/
toCreateReplicationGroup() {
return this.to('CreateReplicationGroup');
}
/**
* Grants permission to create a serverless cache
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CreateServerlessCache.html
*/
toCreateServerlessCache() {
return this.to('CreateServerlessCache');
}
/**
* Grants permission to create a copy of a serverless cache at a specific moment in time
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CreateServerlessCacheSnapshot.html
*/
toCreateServerlessCacheSnapshot() {
return this.to('CreateServerlessCacheSnapshot');
}
/**
* Grants permission to create a copy of an entire Redis cluster at a specific moment in time
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CreateSnapshot.html
*/
toCreateSnapshot() {
return this.to('CreateSnapshot');
}
/**
* Grants permission to create a user for Redis. Users are supported from Redis 6.0 onwards
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CreateUser.html
*/
toCreateUser() {
return this.to('CreateUser');
}
/**
* Grants permission to create a user group for Redis. Groups are supported from Redis 6.0 onwards
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CreateUserGroup.html
*/
toCreateUserGroup() {
return this.to('CreateUserGroup');
}
/**
* Grants permission to decrease the number of node groups in global replication groups
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DecreaseNodeGroupsInGlobalReplicationGroup.html
*/
toDecreaseNodeGroupsInGlobalReplicationGroup() {
return this.to('DecreaseNodeGroupsInGlobalReplicationGroup');
}
/**
* Grants permission to decrease the number of replicas in a Redis (cluster mode disabled) replication group or the number of replica nodes in one or more node groups (shards) of a Redis (cluster mode enabled) replication group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DecreaseReplicaCount.html
*/
toDecreaseReplicaCount() {
return this.to('DecreaseReplicaCount');
}
/**
* Grants permission to delete a previously provisioned cluster
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DeleteCacheCluster.html
*/
toDeleteCacheCluster() {
return this.to('DeleteCacheCluster');
}
/**
* Grants permission to delete the specified cache parameter group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DeleteCacheParameterGroup.html
*/
toDeleteCacheParameterGroup() {
return this.to('DeleteCacheParameterGroup');
}
/**
* Grants permission to delete a cache security group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DeleteCacheSecurityGroup.html
*/
toDeleteCacheSecurityGroup() {
return this.to('DeleteCacheSecurityGroup');
}
/**
* Grants permission to delete a cache subnet group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DeleteCacheSubnetGroup.html
*/
toDeleteCacheSubnetGroup() {
return this.to('DeleteCacheSubnetGroup');
}
/**
* Grants permission to delete an existing global replication group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DeleteGlobalReplicationGroup.html
*/
toDeleteGlobalReplicationGroup() {
return this.to('DeleteGlobalReplicationGroup');
}
/**
* Grants permission to delete an existing replication group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DeleteReplicationGroup.html
*/
toDeleteReplicationGroup() {
return this.to('DeleteReplicationGroup');
}
/**
* Grants permission to delete a serverless cache
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DeleteServerlessCache.html
*/
toDeleteServerlessCache() {
return this.to('DeleteServerlessCache');
}
/**
* Grants permission to delete a serverless cache snapshot
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DeleteServerlessCacheSnapshot.html
*/
toDeleteServerlessCacheSnapshot() {
return this.to('DeleteServerlessCacheSnapshot');
}
/**
* Grants permission to delete an existing snapshot
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DeleteSnapshot.html
*/
toDeleteSnapshot() {
return this.to('DeleteSnapshot');
}
/**
* Grants permission to delete an existing user and thus remove it from all user groups and replication groups where it was assigned
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DeleteUser.html
*/
toDeleteUser() {
return this.to('DeleteUser');
}
/**
* Grants permission to delete an existing user group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DeleteUserGroup.html
*/
toDeleteUserGroup() {
return this.to('DeleteUserGroup');
}
/**
* Grants permission to list information about provisioned cache clusters
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeCacheClusters.html
*/
toDescribeCacheClusters() {
return this.to('DescribeCacheClusters');
}
/**
* Grants permission to list available cache engines and their versions
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeCacheEngineVersions.html
*/
toDescribeCacheEngineVersions() {
return this.to('DescribeCacheEngineVersions');
}
/**
* Grants permission to list cache parameter group descriptions
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeCacheParameterGroups.html
*/
toDescribeCacheParameterGroups() {
return this.to('DescribeCacheParameterGroups');
}
/**
* Grants permission to retrieve the detailed parameter list for a particular cache parameter group
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeCacheParameters.html
*/
toDescribeCacheParameters() {
return this.to('DescribeCacheParameters');
}
/**
* Grants permission to list cache security group descriptions
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeCacheSecurityGroups.html
*/
toDescribeCacheSecurityGroups() {
return this.to('DescribeCacheSecurityGroups');
}
/**
* Grants permission to list cache subnet group descriptions
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeCacheSubnetGroups.html
*/
toDescribeCacheSubnetGroups() {
return this.to('DescribeCacheSubnetGroups');
}
/**
* Grants permission to retrieve the default engine and system parameter information for the specified cache engine
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeEngineDefaultParameters.html
*/
toDescribeEngineDefaultParameters() {
return this.to('DescribeEngineDefaultParameters');
}
/**
* Grants permission to list events related to clusters, cache security groups, and cache parameter groups
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeEvents.html
*/
toDescribeEvents() {
return this.to('DescribeEvents');
}
/**
* Grants permission to list information about global replication groups
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeGlobalReplicationGroups.html
*/
toDescribeGlobalReplicationGroups() {
return this.to('DescribeGlobalReplicationGroups');
}
/**
* Grants permission to list information about provisioned replication groups
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeReplicationGroups.html
*/
toDescribeReplicationGroups() {
return this.to('DescribeReplicationGroups');
}
/**
* Grants permission to list information about purchased reserved cache nodes
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeReservedCacheNodes.html
*/
toDescribeReservedCacheNodes() {
return this.to('DescribeReservedCacheNodes');
}
/**
* Grants permission to list available reserved cache node offerings
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeReservedCacheNodesOfferings.html
*/
toDescribeReservedCacheNodesOfferings() {
return this.to('DescribeReservedCacheNodesOfferings');
}
/**
* Grants permission to list information about serverless cache snapshots
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeServerlessCacheSnapshots.html
*/
toDescribeServerlessCacheSnapshots() {
return this.to('DescribeServerlessCacheSnapshots');
}
/**
* Grants permission to list serverless caches
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeServerlessCaches.html
*/
toDescribeServerlessCaches() {
return this.to('DescribeServerlessCaches');
}
/**
* Grants permission to list details of the service updates
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeServiceUpdates.html
*/
toDescribeServiceUpdates() {
return this.to('DescribeServiceUpdates');
}
/**
* Grants permission to list information about cluster or replication group snapshots
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeSnapshots.html
*/
toDescribeSnapshots() {
return this.to('DescribeSnapshots');
}
/**
* Grants permission to list details of the update actions for a set of clusters or replication groups
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeUpdateActions.html
*/
toDescribeUpdateActions() {
return this.to('DescribeUpdateActions');
}
/**
* Grants permission to list information about Redis user groups
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeUserGroups.html
*/
toDescribeUserGroups() {
return this.to('DescribeUserGroups');
}
/**
* Grants permission to list information about Redis users
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DescribeUsers.html
*/
toDescribeUsers() {
return this.to('DescribeUsers');
}
/**
* Grants permission to remove a secondary replication group from the global replication group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_DisassociateGlobalReplicationGroup.html
*/
toDisassociateGlobalReplicationGroup() {
return this.to('DisassociateGlobalReplicationGroup');
}
/**
* Grants permission to export a copy of a serverless cache at a specific moment in time to s3 bucket
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_ExportServerlessCacheSnapshot.html
*/
toExportServerlessCacheSnapshot() {
return this.to('ExportServerlessCacheSnapshot');
}
/**
* Grants permission to failover the primary region to a selected secondary region of a global replication group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_FailoverGlobalReplicationGroup.html
*/
toFailoverGlobalReplicationGroup() {
return this.to('FailoverGlobalReplicationGroup');
}
/**
* Grants permission to increase the number of node groups in a global replication group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_IncreaseNodeGroupsInGlobalReplicationGroup.html
*/
toIncreaseNodeGroupsInGlobalReplicationGroup() {
return this.to('IncreaseNodeGroupsInGlobalReplicationGroup');
}
/**
* Grants permission to increase the number of replicas in a Redis (cluster mode disabled) replication group or the number of replica nodes in one or more node groups (shards) of a Redis (cluster mode enabled) replication group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_IncreaseReplicaCount.html
*/
toIncreaseReplicaCount() {
return this.to('IncreaseReplicaCount');
}
/**
* Grants permission to list available node type that can be used to scale a particular Redis cluster or replication group
*
* Access Level: List
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_ListAllowedNodeTypeModifications.html
*/
toListAllowedNodeTypeModifications() {
return this.to('ListAllowedNodeTypeModifications');
}
/**
* Grants permission to list tags for an ElastiCache resource
*
* Access Level: Read
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_ListTagsForResource.html
*/
toListTagsForResource() {
return this.to('ListTagsForResource');
}
/**
* Grants permission to modify settings for a cluster
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_ModifyCacheCluster.html
*/
toModifyCacheCluster() {
return this.to('ModifyCacheCluster');
}
/**
* Grants permission to modify parameters of a cache parameter group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_ModifyCacheParameterGroup.html
*/
toModifyCacheParameterGroup() {
return this.to('ModifyCacheParameterGroup');
}
/**
* Grants permission to modify an existing cache subnet group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_ModifyCacheSubnetGroup.html
*/
toModifyCacheSubnetGroup() {
return this.to('ModifyCacheSubnetGroup');
}
/**
* Grants permission to modify settings for a global replication group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_ModifyGlobalReplicationGroup.html
*/
toModifyGlobalReplicationGroup() {
return this.to('ModifyGlobalReplicationGroup');
}
/**
* Grants permission to modify the settings for a replication group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_ModifyReplicationGroup.html
*/
toModifyReplicationGroup() {
return this.to('ModifyReplicationGroup');
}
/**
* Grants permission to add shards, remove shards, or rebalance the keyspaces among existing shards of a replication group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_ModifyReplicationGroupShardConfiguration.html
*/
toModifyReplicationGroupShardConfiguration() {
return this.to('ModifyReplicationGroupShardConfiguration');
}
/**
* Grants permission to modify parameters for a serverless cache
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_ModifyServerlessCache.html
*/
toModifyServerlessCache() {
return this.to('ModifyServerlessCache');
}
/**
* Grants permission to change Redis user password(s) and/or access string
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_ModifyUser.html
*/
toModifyUser() {
return this.to('ModifyUser');
}
/**
* Grants permission to change list of users that belong to the user group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_ModifyUserGroup.html
*/
toModifyUserGroup() {
return this.to('ModifyUserGroup');
}
/**
* Grants permission to purchase a reserved cache node offering
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_PurchaseReservedCacheNodesOffering.html
*/
toPurchaseReservedCacheNodesOffering() {
return this.to('PurchaseReservedCacheNodesOffering');
}
/**
* Grants permission to perform a key space rebalance operation to redistribute slots and ensure uniform key distribution across existing shards in a global replication group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_RebalanceSlotsInGlobalReplicationGroup.html
*/
toRebalanceSlotsInGlobalReplicationGroup() {
return this.to('RebalanceSlotsInGlobalReplicationGroup');
}
/**
* Grants permission to reboot some, or all, of the cache nodes within a provisioned cache cluster or replication group (cluster mode disabled)
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_RebootCacheCluster.html
*/
toRebootCacheCluster() {
return this.to('RebootCacheCluster');
}
/**
* Grants permission to remove tags from a ElastiCache resource
*
* Access Level: Tagging, Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_RemoveTagsFromResource.html
*/
toRemoveTagsFromResource() {
return this.to('RemoveTagsFromResource');
}
/**
* Grants permission to modify parameters of a cache parameter group back to their default values
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_ResetCacheParameterGroup.html
*/
toResetCacheParameterGroup() {
return this.to('ResetCacheParameterGroup');
}
/**
* Grants permission to remove an EC2 security group ingress from a ElastiCache security group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_RevokeCacheSecurityGroupIngress.html
*/
toRevokeCacheSecurityGroupIngress() {
return this.to('RevokeCacheSecurityGroupIngress');
}
/**
* Grants permission to start a migration of data from hosted Redis on Amazon EC2 to ElastiCache for Redis
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_StartMigration.html
*/
toStartMigration() {
return this.to('StartMigration');
}
/**
* Grants permission to test automatic failover on a specified node group in a replication group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_TestFailover.html
*/
toTestFailover() {
return this.to('TestFailover');
}
/**
* Grants permission to test a migration of data from hosted Redis on Amazon EC2 to ElastiCache for Redis
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_TestMigration.html
*/
toTestMigration() {
return this.to('TestMigration');
}
/**
* Grants permission to test an AZ power interruption for an ElastiCache resource
*
* Access Level: Write
*
* https://docs.aws.amazon.com/fis/latest/userguide/fis-actions-reference.html#elasticache-actions-reference
*/
toInterruptClusterAzPower() {
return this.to('InterruptClusterAzPower');
}
/**
* Adds a resource of type cluster to the statement
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.Components.html#WhatIs.Components.Clusters
*
* @param cacheClusterId - Identifier for the cacheClusterId.
* @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:
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
* - .ifAwsTagKeys()
* - .ifAuthTokenEnabled()
* - .ifCacheNodeType()
* - .ifCacheParameterGroupName()
* - .ifEngineType()
* - .ifEngineVersion()
* - .ifMultiAZEnabled()
* - .ifSnapshotRetentionLimit()
*/
onCluster(cacheClusterId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:elasticache:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:cluster:${cacheClusterId}`);
}
/**
* Adds a resource of type globalreplicationgroup to the statement
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/Redis-Global-Datastore.html
*
* @param globalReplicationGroupId - Identifier for the globalReplicationGroupId.
* @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account.
* @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:
* - .ifAtRestEncryptionEnabled()
* - .ifAuthTokenEnabled()
* - .ifAutomaticFailoverEnabled()
* - .ifCacheNodeType()
* - .ifCacheParameterGroupName()
* - .ifClusterModeEnabled()
* - .ifEngineType()
* - .ifEngineVersion()
* - .ifKmsKeyId()
* - .ifMultiAZEnabled()
* - .ifNumNodeGroups()
* - .ifReplicasPerNodeGroup()
* - .ifSnapshotRetentionLimit()
* - .ifTransitEncryptionEnabled()
*/
onGlobalreplicationgroup(globalReplicationGroupId, account, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:elasticache::${account ?? this.defaultAccount}:globalreplicationgroup:${globalReplicationGroupId}`);
}
/**
* Adds a resource of type parametergroup to the statement
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.Components.html#WhatIs.Components.ParameterGroups
*
* @param cacheParameterGroupName - Identifier for the cacheParameterGroupName.
* @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:
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
* - .ifAwsTagKeys()
* - .ifCacheParameterGroupName()
*/
onParametergroup(cacheParameterGroupName, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:elasticache:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:parametergroup:${cacheParameterGroupName}`);
}
/**
* Adds a resource of type replicationgroup to the statement
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.Components.html#WhatIs.Components.ReplicationGroups
*
* @param replicationGroupId - Identifier for the replicationGroupId.
* @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:
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
* - .ifAwsTagKeys()
* - .ifAtRestEncryptionEnabled()
* - .ifAuthTokenEnabled()
* - .ifAutomaticFailoverEnabled()
* - .ifCacheNodeType()
* - .ifCacheParameterGroupName()
* - .ifClusterModeEnabled()
* - .ifDurability()
* - .ifEngineType()
* - .ifEngineVersion()
* - .ifKmsKeyId()
* - .ifMultiAZEnabled()
* - .ifNumNodeGroups()
* - .ifReplicasPerNodeGroup()
* - .ifSnapshotRetentionLimit()
* - .ifTransitEncryptionEnabled()
*/
onReplicationgroup(replicationGroupId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:elasticache:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:replicationgroup:${replicationGroupId}`);
}
/**
* Adds a resource of type reserved-instance to the statement
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/reserved-nodes.html
*
* @param reservedCacheNodeId - Identifier for the reservedCacheNodeId.
* @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:
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
* - .ifAwsTagKeys()
*/
onReservedInstance(reservedCacheNodeId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:elasticache:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:reserved-instance:${reservedCacheNodeId}`);
}
/**
* Adds a resource of type securitygroup to the statement
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.Components.html#WhatIs.Components.SecurityGroups
*
* @param cacheSecurityGroupName - Identifier for the cacheSecurityGroupName.
* @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:
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
* - .ifAwsTagKeys()
*/
onSecuritygroup(cacheSecurityGroupName, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:elasticache:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:securitygroup:${cacheSecurityGroupName}`);
}
/**
* Adds a resource of type serverlesscache to the statement
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html
*
* @param serverlessCacheName - Identifier for the serverlessCacheName.
* @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:
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
* - .ifAwsTagKeys()
* - .ifDataStorageUnit()
* - .ifEngineType()
* - .ifEngineVersion()
* - .ifKmsKeyId()
* - .ifMaximumDataStorage()
* - .ifMaximumECPUPerSecond()
* - .ifMinimumDataStorage()
* - .ifMinimumECPUPerSecond()
* - .ifSnapshotRetentionLimit()
*/
onServerlesscache(serverlessCacheName, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:elasticache:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:serverlesscache:${serverlessCacheName}`);
}
/**
* Adds a resource of type serverlesscachesnapshot to the statement
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html
*
* @param serverlessCacheSnapshotName - Identifier for the serverlessCacheSnapshotName.
* @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:
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
* - .ifAwsTagKeys()
* - .ifKmsKeyId()
*/
onServerlesscachesnapshot(serverlessCacheSnapshotName, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:elasticache:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:serverlesscachesnapshot:${serverlessCacheSnapshotName}`);
}
/**
* Adds a resource of type snapshot to the statement
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.Components.html#WhatIs.Components.Snapshots
*
* @param snapshotName - Identifier for the snapshotName.
* @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:
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
* - .ifAwsTagKeys()
* - .ifKmsKeyId()
*/
onSnapshot(snapshotName, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:elasticache:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:snapshot:${snapshotName}`);
}
/**
* Adds a resource of type subnetgroup to the statement
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.Components.html#WhatIs.Components.SubnetGroups
*
* @param cacheSubnetGroupName - Identifier for the cacheSubnetGroupName.
* @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:
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
* - .ifAwsTagKeys()
*/
onSubnetgroup(cacheSubnetGroupName, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:elasticache:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:subnetgroup:${cacheSubnetGroupName}`);
}
/**
* Adds a resource of type user to the statement
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/Clusters.RBAC.html
*
* @param userId - Identifier for the userId.
* @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:
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
* - .ifAwsTagKeys()
* - .ifUserAuthenticationMode()
*/
onUser(userId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:elasticache:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:user:${userId}`);
}
/**
* Adds a resource of type usergroup to the statement
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/Clusters.RBAC.html
*
* @param userGroupId - Identifier for the userGroupId.
* @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:
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
* - .ifAwsTagKeys()
*/
onUsergroup(userGroupId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:elasticache:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:usergroup:${userGroupId}`);
}
/**
* Filters actions based on the tags that are passed in the request
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toAuthorizeCacheSecurityGroupIngress()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCopyServerlessCacheSnapshot()
* - .toCopySnapshot()
* - .toCreateCacheCluster()
* - .toCreateCacheParameterGroup()
* - .toCreateCacheSecurityGroup()
* - .toCreateCacheSubnetGroup()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateServerlessCache()
* - .toCreateServerlessCacheSnapshot()
* - .toCreateSnapshot()
* - .toCreateUser()
* - .toCreateUserGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteCacheCluster()
* - .toDeleteCacheParameterGroup()
* - .toDeleteCacheSecurityGroup()
* - .toDeleteCacheSubnetGroup()
* - .toDeleteReplicationGroup()
* - .toDeleteServerlessCache()
* - .toDeleteServerlessCacheSnapshot()
* - .toDeleteSnapshot()
* - .toDeleteUser()
* - .toDeleteUserGroup()
* - .toDescribeCacheClusters()
* - .toDescribeCacheParameterGroups()
* - .toDescribeCacheParameters()
* - .toDescribeCacheSecurityGroups()
* - .toDescribeCacheSubnetGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeReservedCacheNodes()
* - .toDescribeServerlessCacheSnapshots()
* - .toDescribeServerlessCaches()
* - .toDescribeSnapshots()
* - .toDescribeUpdateActions()
* - .toDescribeUserGroups()
* - .toDescribeUsers()
* - .toExportServerlessCacheSnapshot()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyCacheCluster()
* - .toModifyCacheParameterGroup()
* - .toModifyCacheSubnetGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toModifyServerlessCache()
* - .toModifyUser()
* - .toModifyUserGroup()
* - .toPurchaseReservedCacheNodesOffering()
* - .toRebootCacheCluster()
* - .toRemoveTagsFromResource()
* - .toResetCacheParameterGroup()
* - .toRevokeCacheSecurityGroupIngress()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - cluster
* - parametergroup
* - replicationgroup
* - reserved-instance
* - securitygroup
* - serverlesscache
* - serverlesscachesnapshot
* - snapshot
* - subnetgroup
* - user
* - usergroup
*
* @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 actions based on the tags associated with the resource
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toAuthorizeCacheSecurityGroupIngress()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCopyServerlessCacheSnapshot()
* - .toCopySnapshot()
* - .toCreateCacheCluster()
* - .toCreateCacheParameterGroup()
* - .toCreateCacheSecurityGroup()
* - .toCreateCacheSubnetGroup()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateServerlessCache()
* - .toCreateServerlessCacheSnapshot()
* - .toCreateSnapshot()
* - .toCreateUser()
* - .toCreateUserGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteCacheCluster()
* - .toDeleteCacheParameterGroup()
* - .toDeleteCacheSecurityGroup()
* - .toDeleteCacheSubnetGroup()
* - .toDeleteReplicationGroup()
* - .toDeleteServerlessCache()
* - .toDeleteServerlessCacheSnapshot()
* - .toDeleteSnapshot()
* - .toDeleteUser()
* - .toDeleteUserGroup()
* - .toDescribeCacheClusters()
* - .toDescribeCacheParameterGroups()
* - .toDescribeCacheParameters()
* - .toDescribeCacheSecurityGroups()
* - .toDescribeCacheSubnetGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeReservedCacheNodes()
* - .toDescribeServerlessCacheSnapshots()
* - .toDescribeServerlessCaches()
* - .toDescribeSnapshots()
* - .toDescribeUpdateActions()
* - .toDescribeUserGroups()
* - .toDescribeUsers()
* - .toExportServerlessCacheSnapshot()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyCacheCluster()
* - .toModifyCacheParameterGroup()
* - .toModifyCacheSubnetGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toModifyServerlessCache()
* - .toModifyUser()
* - .toModifyUserGroup()
* - .toPurchaseReservedCacheNodesOffering()
* - .toRebootCacheCluster()
* - .toRemoveTagsFromResource()
* - .toResetCacheParameterGroup()
* - .toRevokeCacheSecurityGroupIngress()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - cluster
* - parametergroup
* - replicationgroup
* - reserved-instance
* - securitygroup
* - serverlesscache
* - serverlesscachesnapshot
* - snapshot
* - subnetgroup
* - user
* - usergroup
*
* @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 actions based on the tag keys that are passed in the request
*
* https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toAuthorizeCacheSecurityGroupIngress()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCopyServerlessCacheSnapshot()
* - .toCopySnapshot()
* - .toCreateCacheCluster()
* - .toCreateCacheParameterGroup()
* - .toCreateCacheSecurityGroup()
* - .toCreateCacheSubnetGroup()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateServerlessCache()
* - .toCreateServerlessCacheSnapshot()
* - .toCreateSnapshot()
* - .toCreateUser()
* - .toCreateUserGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteCacheCluster()
* - .toDeleteCacheParameterGroup()
* - .toDeleteCacheSecurityGroup()
* - .toDeleteCacheSubnetGroup()
* - .toDeleteReplicationGroup()
* - .toDeleteServerlessCache()
* - .toDeleteServerlessCacheSnapshot()
* - .toDeleteSnapshot()
* - .toDeleteUser()
* - .toDeleteUserGroup()
* - .toDescribeCacheClusters()
* - .toDescribeCacheParameterGroups()
* - .toDescribeCacheParameters()
* - .toDescribeCacheSecurityGroups()
* - .toDescribeCacheSubnetGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeReservedCacheNodes()
* - .toDescribeServerlessCacheSnapshots()
* - .toDescribeServerlessCaches()
* - .toDescribeSnapshots()
* - .toDescribeUpdateActions()
* - .toDescribeUserGroups()
* - .toDescribeUsers()
* - .toExportServerlessCacheSnapshot()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyCacheCluster()
* - .toModifyCacheParameterGroup()
* - .toModifyCacheSubnetGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toModifyServerlessCache()
* - .toModifyUser()
* - .toModifyUserGroup()
* - .toPurchaseReservedCacheNodesOffering()
* - .toRebootCacheCluster()
* - .toRemoveTagsFromResource()
* - .toResetCacheParameterGroup()
* - .toRevokeCacheSecurityGroupIngress()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - cluster
* - parametergroup
* - replicationgroup
* - reserved-instance
* - securitygroup
* - serverlesscache
* - serverlesscachesnapshot
* - snapshot
* - subnetgroup
* - user
* - usergroup
*
* @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 AtRestEncryptionEnabled parameter present in the request or default false value if parameter is not present
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCreateCacheCluster()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateSnapshot()
* - .toDecreaseNodeGroupsInGlobalReplicationGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteGlobalReplicationGroup()
* - .toDeleteReplicationGroup()
* - .toDescribeGlobalReplicationGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeUpdateActions()
* - .toDisassociateGlobalReplicationGroup()
* - .toFailoverGlobalReplicationGroup()
* - .toIncreaseNodeGroupsInGlobalReplicationGroup()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyGlobalReplicationGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toRebalanceSlotsInGlobalReplicationGroup()
* - .toRemoveTagsFromResource()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - globalreplicationgroup
* - replicationgroup
*
* @param value `true` or `false`. **Default:** `true`
*/
ifAtRestEncryptionEnabled(value) {
return this.if(`AtRestEncryptionEnabled`, (typeof value !== 'undefined' ? value : true), 'Bool');
}
/**
* Filters access by the presence of non empty AuthToken parameter in the request
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCreateCacheCluster()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateSnapshot()
* - .toDecreaseNodeGroupsInGlobalReplicationGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteCacheCluster()
* - .toDeleteGlobalReplicationGroup()
* - .toDeleteReplicationGroup()
* - .toDescribeCacheClusters()
* - .toDescribeGlobalReplicationGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeUpdateActions()
* - .toDisassociateGlobalReplicationGroup()
* - .toFailoverGlobalReplicationGroup()
* - .toIncreaseNodeGroupsInGlobalReplicationGroup()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyCacheCluster()
* - .toModifyGlobalReplicationGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toRebalanceSlotsInGlobalReplicationGroup()
* - .toRebootCacheCluster()
* - .toRemoveTagsFromResource()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - cluster
* - globalreplicationgroup
* - replicationgroup
*
* @param value `true` or `false`. **Default:** `true`
*/
ifAuthTokenEnabled(value) {
return this.if(`AuthTokenEnabled`, (typeof value !== 'undefined' ? value : true), 'Bool');
}
/**
* Filters access by the AutomaticFailoverEnabled parameter in the request
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCreateCacheCluster()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateSnapshot()
* - .toDecreaseNodeGroupsInGlobalReplicationGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteGlobalReplicationGroup()
* - .toDeleteReplicationGroup()
* - .toDescribeGlobalReplicationGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeUpdateActions()
* - .toDisassociateGlobalReplicationGroup()
* - .toFailoverGlobalReplicationGroup()
* - .toIncreaseNodeGroupsInGlobalReplicationGroup()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyGlobalReplicationGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toRebalanceSlotsInGlobalReplicationGroup()
* - .toRemoveTagsFromResource()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - globalreplicationgroup
* - replicationgroup
*
* @param value `true` or `false`. **Default:** `true`
*/
ifAutomaticFailoverEnabled(value) {
return this.if(`AutomaticFailoverEnabled`, (typeof value !== 'undefined' ? value : true), 'Bool');
}
/**
* Filters access by the cacheNodeType parameter present in the request. This key can be used to restrict which cache node types can be used on cluster creation or scaling operations
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCreateCacheCluster()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateSnapshot()
* - .toDecreaseNodeGroupsInGlobalReplicationGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteCacheCluster()
* - .toDeleteGlobalReplicationGroup()
* - .toDeleteReplicationGroup()
* - .toDescribeCacheClusters()
* - .toDescribeGlobalReplicationGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeUpdateActions()
* - .toDisassociateGlobalReplicationGroup()
* - .toFailoverGlobalReplicationGroup()
* - .toIncreaseNodeGroupsInGlobalReplicationGroup()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyCacheCluster()
* - .toModifyGlobalReplicationGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toRebalanceSlotsInGlobalReplicationGroup()
* - .toRebootCacheCluster()
* - .toRemoveTagsFromResource()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - cluster
* - globalreplicationgroup
* - replicationgroup
*
* @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`
*/
ifCacheNodeType(value, operator) {
return this.if(`CacheNodeType`, value, operator ?? 'StringLike');
}
/**
* Filters access by the CacheParameterGroupName parameter in the request
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCreateCacheCluster()
* - .toCreateCacheParameterGroup()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateSnapshot()
* - .toDecreaseNodeGroupsInGlobalReplicationGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteCacheCluster()
* - .toDeleteCacheParameterGroup()
* - .toDeleteGlobalReplicationGroup()
* - .toDeleteReplicationGroup()
* - .toDescribeCacheClusters()
* - .toDescribeCacheParameterGroups()
* - .toDescribeCacheParameters()
* - .toDescribeGlobalReplicationGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeUpdateActions()
* - .toDisassociateGlobalReplicationGroup()
* - .toFailoverGlobalReplicationGroup()
* - .toIncreaseNodeGroupsInGlobalReplicationGroup()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyCacheCluster()
* - .toModifyCacheParameterGroup()
* - .toModifyGlobalReplicationGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toRebalanceSlotsInGlobalReplicationGroup()
* - .toRebootCacheCluster()
* - .toRemoveTagsFromResource()
* - .toResetCacheParameterGroup()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - cluster
* - globalreplicationgroup
* - parametergroup
* - replicationgroup
*
* @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`
*/
ifCacheParameterGroupName(value, operator) {
return this.if(`CacheParameterGroupName`, value, operator ?? 'StringLike');
}
/**
* Filters access by the cluster mode parameter present in the request. Default value for single node group (shard) creations is false
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCreateCacheCluster()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateSnapshot()
* - .toDecreaseNodeGroupsInGlobalReplicationGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteGlobalReplicationGroup()
* - .toDeleteReplicationGroup()
* - .toDescribeGlobalReplicationGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeUpdateActions()
* - .toDisassociateGlobalReplicationGroup()
* - .toFailoverGlobalReplicationGroup()
* - .toIncreaseNodeGroupsInGlobalReplicationGroup()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyGlobalReplicationGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toRebalanceSlotsInGlobalReplicationGroup()
* - .toRemoveTagsFromResource()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - globalreplicationgroup
* - replicationgroup
*
* @param value `true` or `false`. **Default:** `true`
*/
ifClusterModeEnabled(value) {
return this.if(`ClusterModeEnabled`, (typeof value !== 'undefined' ? value : true), 'Bool');
}
/**
* Filters access by the CacheUsageLimits.DataStorage.Unit parameter in the CreateServerlessCache and ModifyServerlessCache request
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toConnect()
* - .toCreateServerlessCache()
* - .toCreateServerlessCacheSnapshot()
* - .toDeleteServerlessCache()
* - .toDescribeServerlessCacheSnapshots()
* - .toDescribeServerlessCaches()
* - .toListTagsForResource()
* - .toModifyServerlessCache()
* - .toRemoveTagsFromResource()
*
* Applies to resource types:
* - serverlesscache
*
* @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`
*/
ifDataStorageUnit(value, operator) {
return this.if(`DataStorageUnit`, value, operator ?? 'StringLike');
}
/**
* Filters access by the Durability parameter in the request. Valid values are default, async, sync, or disabled
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCreateCacheCluster()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateSnapshot()
* - .toDecreaseReplicaCount()
* - .toDeleteReplicationGroup()
* - .toDescribeReplicationGroups()
* - .toDescribeUpdateActions()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toRemoveTagsFromResource()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - replicationgroup
*
* @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`
*/
ifDurability(value, operator) {
return this.if(`Durability`, value, operator ?? 'StringLike');
}
/**
* Filters access by the engine type present in creation requests. For replication group creations, default engine 'redis' is used as key if parameter is not present
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCreateCacheCluster()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateServerlessCache()
* - .toCreateServerlessCacheSnapshot()
* - .toCreateSnapshot()
* - .toDecreaseNodeGroupsInGlobalReplicationGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteCacheCluster()
* - .toDeleteGlobalReplicationGroup()
* - .toDeleteReplicationGroup()
* - .toDeleteServerlessCache()
* - .toDescribeCacheClusters()
* - .toDescribeGlobalReplicationGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeServerlessCacheSnapshots()
* - .toDescribeServerlessCaches()
* - .toDescribeUpdateActions()
* - .toDisassociateGlobalReplicationGroup()
* - .toFailoverGlobalReplicationGroup()
* - .toIncreaseNodeGroupsInGlobalReplicationGroup()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyCacheCluster()
* - .toModifyGlobalReplicationGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toModifyServerlessCache()
* - .toRebalanceSlotsInGlobalReplicationGroup()
* - .toRebootCacheCluster()
* - .toRemoveTagsFromResource()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - cluster
* - globalreplicationgroup
* - replicationgroup
* - serverlesscache
*
* @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`
*/
ifEngineType(value, operator) {
return this.if(`EngineType`, value, operator ?? 'StringLike');
}
/**
* Filters access by the engineVersion parameter present in creation or cluster modification requests
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCreateCacheCluster()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateServerlessCache()
* - .toCreateServerlessCacheSnapshot()
* - .toCreateSnapshot()
* - .toDecreaseNodeGroupsInGlobalReplicationGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteCacheCluster()
* - .toDeleteGlobalReplicationGroup()
* - .toDeleteReplicationGroup()
* - .toDeleteServerlessCache()
* - .toDescribeCacheClusters()
* - .toDescribeGlobalReplicationGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeServerlessCacheSnapshots()
* - .toDescribeServerlessCaches()
* - .toDescribeUpdateActions()
* - .toDisassociateGlobalReplicationGroup()
* - .toFailoverGlobalReplicationGroup()
* - .toIncreaseNodeGroupsInGlobalReplicationGroup()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyCacheCluster()
* - .toModifyGlobalReplicationGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toModifyServerlessCache()
* - .toRebalanceSlotsInGlobalReplicationGroup()
* - .toRebootCacheCluster()
* - .toRemoveTagsFromResource()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - cluster
* - globalreplicationgroup
* - replicationgroup
* - serverlesscache
*
* @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`
*/
ifEngineVersion(value, operator) {
return this.if(`EngineVersion`, value, operator ?? 'StringLike');
}
/**
* Filters access by the Key ID of the KMS key
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCopyServerlessCacheSnapshot()
* - .toCopySnapshot()
* - .toCreateCacheCluster()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateServerlessCache()
* - .toCreateServerlessCacheSnapshot()
* - .toCreateSnapshot()
* - .toDecreaseNodeGroupsInGlobalReplicationGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteCacheCluster()
* - .toDeleteGlobalReplicationGroup()
* - .toDeleteReplicationGroup()
* - .toDeleteServerlessCache()
* - .toDeleteServerlessCacheSnapshot()
* - .toDeleteSnapshot()
* - .toDescribeGlobalReplicationGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeServerlessCacheSnapshots()
* - .toDescribeServerlessCaches()
* - .toDescribeSnapshots()
* - .toDescribeUpdateActions()
* - .toDisassociateGlobalReplicationGroup()
* - .toExportServerlessCacheSnapshot()
* - .toFailoverGlobalReplicationGroup()
* - .toIncreaseNodeGroupsInGlobalReplicationGroup()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyGlobalReplicationGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toModifyServerlessCache()
* - .toRebalanceSlotsInGlobalReplicationGroup()
* - .toRemoveTagsFromResource()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - globalreplicationgroup
* - replicationgroup
* - serverlesscache
* - serverlesscachesnapshot
* - snapshot
*
* @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`
*/
ifKmsKeyId(value, operator) {
return this.if(`KmsKeyId`, value, operator ?? 'StringLike');
}
/**
* Filters access by the CacheUsageLimits.DataStorage.Maximum parameter in the CreateServerlessCache and ModifyServerlessCache request
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toConnect()
* - .toCreateServerlessCache()
* - .toCreateServerlessCacheSnapshot()
* - .toDeleteServerlessCache()
* - .toDescribeServerlessCacheSnapshots()
* - .toDescribeServerlessCaches()
* - .toListTagsForResource()
* - .toModifyServerlessCache()
* - .toRemoveTagsFromResource()
*
* Applies to resource types:
* - serverlesscache
*
* @param value The value(s) to check
* @param operator Works with [numeric operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Numeric). **Default:** `NumericEquals`
*/
ifMaximumDataStorage(value, operator) {
return this.if(`MaximumDataStorage`, value, operator ?? 'NumericEquals');
}
/**
* Filters access by the CacheUsageLimits.ECPUPerSecond.Maximum parameter in the CreateServerlessCache and ModifyServerlessCache request
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toConnect()
* - .toCreateServerlessCache()
* - .toCreateServerlessCacheSnapshot()
* - .toDeleteServerlessCache()
* - .toDescribeServerlessCacheSnapshots()
* - .toDescribeServerlessCaches()
* - .toListTagsForResource()
* - .toModifyServerlessCache()
* - .toRemoveTagsFromResource()
*
* Applies to resource types:
* - serverlesscache
*
* @param value The value(s) to check
* @param operator Works with [numeric operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Numeric). **Default:** `NumericEquals`
*/
ifMaximumECPUPerSecond(value, operator) {
return this.if(`MaximumECPUPerSecond`, value, operator ?? 'NumericEquals');
}
/**
* Filters access by the CacheUsageLimits.DataStorage.Minimum parameter in the CreateServerlessCache and ModifyServerlessCache request
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toConnect()
* - .toCreateServerlessCache()
* - .toCreateServerlessCacheSnapshot()
* - .toDeleteServerlessCache()
* - .toDescribeServerlessCacheSnapshots()
* - .toDescribeServerlessCaches()
* - .toListTagsForResource()
* - .toModifyServerlessCache()
* - .toRemoveTagsFromResource()
*
* Applies to resource types:
* - serverlesscache
*
* @param value The value(s) to check
* @param operator Works with [numeric operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Numeric). **Default:** `NumericEquals`
*/
ifMinimumDataStorage(value, operator) {
return this.if(`MinimumDataStorage`, value, operator ?? 'NumericEquals');
}
/**
* Filters access by the CacheUsageLimits.ECPUPerSecond.Minimum parameter in the CreateServerlessCache and ModifyServerlessCache request
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toConnect()
* - .toCreateServerlessCache()
* - .toCreateServerlessCacheSnapshot()
* - .toDeleteServerlessCache()
* - .toDescribeServerlessCacheSnapshots()
* - .toDescribeServerlessCaches()
* - .toListTagsForResource()
* - .toModifyServerlessCache()
* - .toRemoveTagsFromResource()
*
* Applies to resource types:
* - serverlesscache
*
* @param value The value(s) to check
* @param operator Works with [numeric operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Numeric). **Default:** `NumericEquals`
*/
ifMinimumECPUPerSecond(value, operator) {
return this.if(`MinimumECPUPerSecond`, value, operator ?? 'NumericEquals');
}
/**
* Filters access by the AZMode parameter, MultiAZEnabled parameter or the number of availability zones that the cluster or replication group can be placed in
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCreateCacheCluster()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateSnapshot()
* - .toDecreaseNodeGroupsInGlobalReplicationGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteCacheCluster()
* - .toDeleteGlobalReplicationGroup()
* - .toDeleteReplicationGroup()
* - .toDescribeCacheClusters()
* - .toDescribeGlobalReplicationGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeUpdateActions()
* - .toDisassociateGlobalReplicationGroup()
* - .toFailoverGlobalReplicationGroup()
* - .toIncreaseNodeGroupsInGlobalReplicationGroup()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyCacheCluster()
* - .toModifyGlobalReplicationGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toRebalanceSlotsInGlobalReplicationGroup()
* - .toRebootCacheCluster()
* - .toRemoveTagsFromResource()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - cluster
* - globalreplicationgroup
* - replicationgroup
*
* @param value `true` or `false`. **Default:** `true`
*/
ifMultiAZEnabled(value) {
return this.if(`MultiAZEnabled`, (typeof value !== 'undefined' ? value : true), 'Bool');
}
/**
* Filters access by the NumNodeGroups or NodeGroupCount parameter specified in the request. This key can be used to restrict the number of node groups (shards) clusters can have after creation or scaling operations
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCreateCacheCluster()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateSnapshot()
* - .toDecreaseNodeGroupsInGlobalReplicationGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteGlobalReplicationGroup()
* - .toDeleteReplicationGroup()
* - .toDescribeGlobalReplicationGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeUpdateActions()
* - .toDisassociateGlobalReplicationGroup()
* - .toFailoverGlobalReplicationGroup()
* - .toIncreaseNodeGroupsInGlobalReplicationGroup()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyGlobalReplicationGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toRebalanceSlotsInGlobalReplicationGroup()
* - .toRemoveTagsFromResource()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - globalreplicationgroup
* - replicationgroup
*
* @param value The value(s) to check
* @param operator Works with [numeric operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Numeric). **Default:** `NumericEquals`
*/
ifNumNodeGroups(value, operator) {
return this.if(`NumNodeGroups`, value, operator ?? 'NumericEquals');
}
/**
* Filters access by the number of replicas per node group (shards) specified in creations or scaling requests
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCreateCacheCluster()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateSnapshot()
* - .toDecreaseNodeGroupsInGlobalReplicationGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteGlobalReplicationGroup()
* - .toDeleteReplicationGroup()
* - .toDescribeGlobalReplicationGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeUpdateActions()
* - .toDisassociateGlobalReplicationGroup()
* - .toFailoverGlobalReplicationGroup()
* - .toIncreaseNodeGroupsInGlobalReplicationGroup()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyGlobalReplicationGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toRebalanceSlotsInGlobalReplicationGroup()
* - .toRemoveTagsFromResource()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - globalreplicationgroup
* - replicationgroup
*
* @param value The value(s) to check
* @param operator Works with [numeric operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Numeric). **Default:** `NumericEquals`
*/
ifReplicasPerNodeGroup(value, operator) {
return this.if(`ReplicasPerNodeGroup`, value, operator ?? 'NumericEquals');
}
/**
* Filters access by the SnapshotRetentionLimit parameter in the request
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCreateCacheCluster()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateServerlessCache()
* - .toCreateServerlessCacheSnapshot()
* - .toCreateSnapshot()
* - .toDecreaseNodeGroupsInGlobalReplicationGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteCacheCluster()
* - .toDeleteGlobalReplicationGroup()
* - .toDeleteReplicationGroup()
* - .toDeleteServerlessCache()
* - .toDescribeCacheClusters()
* - .toDescribeGlobalReplicationGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeServerlessCacheSnapshots()
* - .toDescribeServerlessCaches()
* - .toDescribeUpdateActions()
* - .toDisassociateGlobalReplicationGroup()
* - .toFailoverGlobalReplicationGroup()
* - .toIncreaseNodeGroupsInGlobalReplicationGroup()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyCacheCluster()
* - .toModifyGlobalReplicationGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toModifyServerlessCache()
* - .toRebalanceSlotsInGlobalReplicationGroup()
* - .toRebootCacheCluster()
* - .toRemoveTagsFromResource()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - cluster
* - globalreplicationgroup
* - replicationgroup
* - serverlesscache
*
* @param value The value(s) to check
* @param operator Works with [numeric operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Numeric). **Default:** `NumericEquals`
*/
ifSnapshotRetentionLimit(value, operator) {
return this.if(`SnapshotRetentionLimit`, value, operator ?? 'NumericEquals');
}
/**
* Filters access by the TransitEncryptionEnabled parameter present in the request. For replication group creations, default value 'false' is used as key if parameter is not present
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toBatchApplyUpdateAction()
* - .toBatchStopUpdateAction()
* - .toCompleteMigration()
* - .toConnect()
* - .toCreateCacheCluster()
* - .toCreateGlobalReplicationGroup()
* - .toCreateReplicationGroup()
* - .toCreateSnapshot()
* - .toDecreaseNodeGroupsInGlobalReplicationGroup()
* - .toDecreaseReplicaCount()
* - .toDeleteGlobalReplicationGroup()
* - .toDeleteReplicationGroup()
* - .toDescribeGlobalReplicationGroups()
* - .toDescribeReplicationGroups()
* - .toDescribeUpdateActions()
* - .toDisassociateGlobalReplicationGroup()
* - .toFailoverGlobalReplicationGroup()
* - .toIncreaseNodeGroupsInGlobalReplicationGroup()
* - .toIncreaseReplicaCount()
* - .toListAllowedNodeTypeModifications()
* - .toListTagsForResource()
* - .toModifyGlobalReplicationGroup()
* - .toModifyReplicationGroup()
* - .toModifyReplicationGroupShardConfiguration()
* - .toRebalanceSlotsInGlobalReplicationGroup()
* - .toRemoveTagsFromResource()
* - .toStartMigration()
* - .toTestFailover()
* - .toTestMigration()
* - .toInterruptClusterAzPower()
*
* Applies to resource types:
* - globalreplicationgroup
* - replicationgroup
*
* @param value `true` or `false`. **Default:** `true`
*/
ifTransitEncryptionEnabled(value) {
return this.if(`TransitEncryptionEnabled`, (typeof value !== 'undefined' ? value : true), 'Bool');
}
/**
* Filters access by the UserAuthenticationMode parameter in the request
*
* https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/IAM.ConditionKeys.html#IAM.SpecifyingConditions
*
* Applies to actions:
* - .toAddTagsToResource()
* - .toConnect()
* - .toCreateUser()
* - .toCreateUserGroup()
* - .toDeleteUser()
* - .toDescribeUsers()
* - .toListTagsForResource()
* - .toModifyUser()
* - .toModifyUserGroup()
* - .toRemoveTagsFromResource()
*
* Applies to resource types:
* - user
*
* @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`
*/
ifUserAuthenticationMode(value, operator) {
return this.if(`UserAuthenticationMode`, value, operator ?? 'StringLike');
}
/**
* Statement provider for service [elasticache](https://docs.aws.amazon.com/service-authorization/latest/reference/list_elasticache.html).
*
*/
constructor(props) {
super(props);
this.servicePrefix = 'elasticache';
this.accessLevelList = {
Tagging: [
'AddTagsToResource',
'RemoveTagsFromResource'
],
Write: [
'AddTagsToResource',
'AuthorizeCacheSecurityGroupIngress',
'BatchApplyUpdateAction',
'BatchStopUpdateAction',
'CompleteMigration',
'Connect',
'CopyServerlessCacheSnapshot',
'CopySnapshot',
'CreateCacheCluster',
'CreateCacheParameterGroup',
'CreateCacheSecurityGroup',
'CreateCacheSubnetGroup',
'CreateGlobalReplicationGroup',
'CreateReplicationGroup',
'CreateServerlessCache',
'CreateServerlessCacheSnapshot',
'CreateSnapshot',
'CreateUser',
'CreateUserGroup',
'DecreaseNodeGroupsInGlobalReplicationGroup',
'DecreaseReplicaCount',
'DeleteCacheCluster',
'DeleteCacheParameterGroup',
'DeleteCacheSecurityGroup',
'DeleteCacheSubnetGroup',
'DeleteGlobalReplicationGroup',
'DeleteReplicationGroup',
'DeleteServerlessCache',
'DeleteServerlessCacheSnapshot',
'DeleteSnapshot',
'DeleteUser',
'DeleteUserGroup',
'DisassociateGlobalReplicationGroup',
'ExportServerlessCacheSnapshot',
'FailoverGlobalReplicationGroup',
'IncreaseNodeGroupsInGlobalReplicationGroup',
'IncreaseReplicaCount',
'ModifyCacheCluster',
'ModifyCacheParameterGroup',
'ModifyCacheSubnetGroup',
'ModifyGlobalReplicationGroup',
'ModifyReplicationGroup',
'ModifyReplicationGroupShardConfiguration',
'ModifyServerlessCache',
'ModifyUser',
'ModifyUserGroup',
'PurchaseReservedCacheNodesOffering',
'RebalanceSlotsInGlobalReplicationGroup',
'RebootCacheCluster',
'RemoveTagsFromResource',
'ResetCacheParameterGroup',
'RevokeCacheSecurityGroupIngress',
'StartMigration',
'TestFailover',
'TestMigration',
'InterruptClusterAzPower'
],
List: [
'DescribeCacheClusters',
'DescribeCacheEngineVersions',
'DescribeCacheParameterGroups',
'DescribeCacheParameters',
'DescribeCacheSecurityGroups',
'DescribeCacheSubnetGroups',
'DescribeEngineDefaultParameters',
'DescribeEvents',
'DescribeGlobalReplicationGroups',
'DescribeReplicationGroups',
'DescribeReservedCacheNodes',
'DescribeReservedCacheNodesOfferings',
'DescribeServerlessCacheSnapshots',
'DescribeServerlessCaches',
'DescribeServiceUpdates',
'DescribeSnapshots',
'DescribeUpdateActions',
'DescribeUserGroups',
'DescribeUsers',
'ListAllowedNodeTypeModifications'
],
Read: [
'ListTagsForResource'
]
};
}
}
exports.Elasticache = Elasticache;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxhc3RpY2FjaGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJlbGFzdGljYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSx5Q0FBeUQ7QUFHekQ7Ozs7R0FJRztBQUNILE1BQWEsV0FBWSxTQUFRLHdCQUFlO0lBRzlDOzs7Ozs7T0FNRztJQUNJLG1CQUFtQjtRQUN4QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksb0NBQW9DO1FBQ3pDLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSx3QkFBd0I7UUFDN0IsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLHVCQUF1QjtRQUM1QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksbUJBQW1CO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxTQUFTO1FBQ2QsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSw2QkFBNkI7UUFDbEMsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLDZCQUE2QixDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGNBQWM7UUFDbkIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxvQkFBb0I7UUFDekIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG9C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aEIsaUNBQWlDO2dCQUNqQywyQkFBMkI7Z0JBQzNCLDRCQUE0QjtnQkFDNUIscUNBQXFDO2dCQUNyQyxrQ0FBa0M7Z0JBQ2xDLDBCQUEwQjtnQkFDMUIsd0JBQXdCO2dCQUN4QixtQkFBbUI7Z0JBQ25CLHVCQUF1QjtnQkFDdkIsb0JBQW9CO2dCQUNwQixlQUFlO2dCQUNmLGtDQUFrQzthQUNuQztZQUNELElBQUksRUFBRTtnQkFDSixxQkFBcUI7YUFDdEI7U0FDRixDQUFDO0lBNitDRixDQUFDO0NBQ0Y7QUF4NUVELGtDQXc1RUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBY2Nlc3NMZXZlbExpc3QgfSBmcm9tICcuLi8uLi9zaGFyZWQvYWNjZXNzLWxldmVsJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCwgT3BlcmF0b3IgfSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuaW1wb3J0IHsgYXdzX2lhbSBhcyBpYW0gfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcblxuLyoqXG4gKiBTdGF0ZW1lbnQgcHJvdmlkZXIgZm9yIHNlcnZpY2UgW2VsYXN0aWNhY2hlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9lbGFzdGljYWNoZS5odG1sKS5cbiAqXG4gKiBAcGFyYW0gc2lkIFtTSURdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfc2lkLmh0bWwpIG9mIHRoZSBzdGF0ZW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEVsYXN0aWNhY2hlIGV4dGVuZHMgUG9saWN5U3RhdGVtZW50IHtcbiAgcHVibGljIHNlcnZpY2VQcmVmaXggPSAnZWxhc3RpY2FjaGUnO1xuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhZGQgdGFncyB0byBhbiBFbGFzdGlDYWNoZSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmcsIFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9BZGRUYWdzVG9SZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9BZGRUYWdzVG9SZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQWRkVGFnc1RvUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhdXRob3JpemUgYW4gRUMyIHNlY3VyaXR5IGdyb3VwIG9uIGEgRWxhc3RpQ2FjaGUgc2VjdXJpdHkgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQXV0aG9yaXplQ2FjaGVTZWN1cml0eUdyb3VwSW5ncmVzcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9BdXRob3JpemVDYWNoZVNlY3VyaXR5R3JvdXBJbmdyZXNzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdBdXRob3JpemVDYWNoZVNlY3VyaXR5R3JvdXBJbmdyZXNzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYXBwbHkgRWxhc3RpQ2FjaGUgc2VydmljZSB1cGRhdGVzIHRvIHNldHMgb2YgY2x1c3RlcnMgYW5kIHJlcGxpY2F0aW9uIGdyb3Vwc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9CYXRjaEFwcGx5VXBkYXRlQWN0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0JhdGNoQXBwbHlVcGRhdGVBY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0JhdGNoQXBwbHlVcGRhdGVBY3Rpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBzdG9wIEVsYXN0aUNhY2hlIHNlcnZpY2UgdXBkYXRlcyBmcm9tIGJlaW5nIGV4ZWN1dGVkIG9uIGEgc2V0IG9mIGNsdXN0ZXJzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0JhdGNoU3RvcFVwZGF0ZUFjdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9CYXRjaFN0b3BVcGRhdGVBY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0JhdGNoU3RvcFVwZGF0ZUFjdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNvbXBsZXRlIGFuIG9ubGluZSBtaWdyYXRpb24gb2YgZGF0YSBmcm9tIGhvc3RlZCBSZWRpcyBvbiBBbWF6b24gRUMyIHRvIEVsYXN0aUNhY2hlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NvbXBsZXRlTWlncmF0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NvbXBsZXRlTWlncmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDb21wbGV0ZU1pZ3JhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNvbm5lY3QgYXMgYSBzcGVjaWZpZWQgRWxhc3RpQ2FjaGUgdXNlciB0byBhbiBFbGFzdGlDYWNoZSBSZXBsaWNhdGlvbiBHcm91cCBvciBFbGFzdGlDYWNoZSBzZXJ2ZXJsZXNzIGNhY2hlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9yZWQtdWcvYXV0aC1pYW0uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ29ubmVjdCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ29ubmVjdCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIG1ha2UgYSBjb3B5IG9mIGFuIGV4aXN0aW5nIHNlcnZlcmxlc3MgY2FjaGUgc25hcHNob3RcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ29weVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NvcHlTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ29weVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbWFrZSBhIGNvcHkgb2YgYW4gZXhpc3Rpbmcgc25hcHNob3RcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ29weVNuYXBzaG90Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NvcHlTbmFwc2hvdCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ29weVNuYXBzaG90Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgY2FjaGUgY2x1c3RlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVDYWNoZUNsdXN0ZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlQ2FjaGVDbHVzdGVyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVDYWNoZUNsdXN0ZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBwYXJhbWV0ZXIgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlQ2FjaGVQYXJhbWV0ZXJHcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVDYWNoZVBhcmFtZXRlckdyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVDYWNoZVBhcmFtZXRlckdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgY2FjaGUgc2VjdXJpdHkgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlQ2FjaGVTZWN1cml0eUdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZUNhY2hlU2VjdXJpdHlHcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlQ2FjaGVTZWN1cml0eUdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgY2FjaGUgc3VibmV0IGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZUNhY2hlU3VibmV0R3JvdXAuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlQ2FjaGVTdWJuZXRHcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlQ2FjaGVTdWJuZXRHcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIGdsb2JhbCByZXBsaWNhdGlvbiBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSByZXBsaWNhdGlvbiBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVSZXBsaWNhdGlvbkdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVJlcGxpY2F0aW9uR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZVJlcGxpY2F0aW9uR3JvdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBzZXJ2ZXJsZXNzIGNhY2hlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVNlcnZlcmxlc3NDYWNoZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVTZXJ2ZXJsZXNzQ2FjaGUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZVNlcnZlcmxlc3NDYWNoZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIGNvcHkgb2YgYSBzZXJ2ZXJsZXNzIGNhY2hlIGF0IGEgc3BlY2lmaWMgbW9tZW50IGluIHRpbWVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlU2VydmVybGVzc0NhY2hlU25hcHNob3QuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlU2VydmVybGVzc0NhY2hlU25hcHNob3QoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgY29weSBvZiBhbiBlbnRpcmUgUmVkaXMgY2x1c3RlciBhdCBhIHNwZWNpZmljIG1vbWVudCBpbiB0aW1lXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVNuYXBzaG90Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVNuYXBzaG90KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVTbmFwc2hvdCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIHVzZXIgZm9yIFJlZGlzLiBVc2VycyBhcmUgc3VwcG9ydGVkIGZyb20gUmVkaXMgNi4wIG9ud2FyZHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlVXNlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVVc2VyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVVc2VyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgdXNlciBncm91cCBmb3IgUmVkaXMuIEdyb3VwcyBhcmUgc3VwcG9ydGVkIGZyb20gUmVkaXMgNi4wIG9ud2FyZHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlVXNlckdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVVzZXJHcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlVXNlckdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVjcmVhc2UgdGhlIG51bWJlciBvZiBub2RlIGdyb3VwcyBpbiBnbG9iYWwgcmVwbGljYXRpb24gZ3JvdXBzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlY3JlYXNlTm9kZUdyb3Vwc0luR2xvYmFsUmVwbGljYXRpb25Hcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWNyZWFzZU5vZGVHcm91cHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlY3JlYXNlTm9kZUdyb3Vwc0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlY3JlYXNlIHRoZSBudW1iZXIgb2YgcmVwbGljYXMgaW4gYSBSZWRpcyAoY2x1c3RlciBtb2RlIGRpc2FibGVkKSByZXBsaWNhdGlvbiBncm91cCBvciB0aGUgbnVtYmVyIG9mIHJlcGxpY2Egbm9kZXMgaW4gb25lIG9yIG1vcmUgbm9kZSBncm91cHMgKHNoYXJkcykgb2YgYSBSZWRpcyAoY2x1c3RlciBtb2RlIGVuYWJsZWQpIHJlcGxpY2F0aW9uIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlY3JlYXNlUmVwbGljYUNvdW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlY3JlYXNlUmVwbGljYUNvdW50KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWNyZWFzZVJlcGxpY2FDb3VudCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhIHByZXZpb3VzbHkgcHJvdmlzaW9uZWQgY2x1c3RlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVDYWNoZUNsdXN0ZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlQ2FjaGVDbHVzdGVyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVDYWNoZUNsdXN0ZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgdGhlIHNwZWNpZmllZCBjYWNoZSBwYXJhbWV0ZXIgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlQ2FjaGVQYXJhbWV0ZXJHcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVDYWNoZVBhcmFtZXRlckdyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVDYWNoZVBhcmFtZXRlckdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGEgY2FjaGUgc2VjdXJpdHkgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlQ2FjaGVTZWN1cml0eUdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZUNhY2hlU2VjdXJpdHlHcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlQ2FjaGVTZWN1cml0eUdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGEgY2FjaGUgc3VibmV0IGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZUNhY2hlU3VibmV0R3JvdXAuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlQ2FjaGVTdWJuZXRHcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlQ2FjaGVTdWJuZXRHcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhbiBleGlzdGluZyBnbG9iYWwgcmVwbGljYXRpb24gZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGFuIGV4aXN0aW5nIHJlcGxpY2F0aW9uIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVJlcGxpY2F0aW9uR3JvdXAuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlUmVwbGljYXRpb25Hcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlUmVwbGljYXRpb25Hcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhIHNlcnZlcmxlc3MgY2FjaGVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlU2VydmVybGVzc0NhY2hlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVNlcnZlcmxlc3NDYWNoZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlU2VydmVybGVzc0NhY2hlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGEgc2VydmVybGVzcyBjYWNoZSBzbmFwc2hvdFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlU2VydmVybGVzc0NhY2hlU25hcHNob3QnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgYW4gZXhpc3Rpbmcgc25hcHNob3RcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlU25hcHNob3QuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlU25hcHNob3QoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVNuYXBzaG90Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGFuIGV4aXN0aW5nIHVzZXIgYW5kIHRodXMgcmVtb3ZlIGl0IGZyb20gYWxsIHVzZXIgZ3JvdXBzIGFuZCByZXBsaWNhdGlvbiBncm91cHMgd2hlcmUgaXQgd2FzIGFzc2lnbmVkXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVVzZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlVXNlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlVXNlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhbiBleGlzdGluZyB1c2VyIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVVzZXJHcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVVc2VyR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVVzZXJHcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgaW5mb3JtYXRpb24gYWJvdXQgcHJvdmlzaW9uZWQgY2FjaGUgY2x1c3RlcnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUNhY2hlQ2x1c3RlcnMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVDYWNoZUNsdXN0ZXJzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUNhY2hlQ2x1c3RlcnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGF2YWlsYWJsZSBjYWNoZSBlbmdpbmVzIGFuZCB0aGVpciB2ZXJzaW9uc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlQ2FjaGVFbmdpbmVWZXJzaW9ucy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUNhY2hlRW5naW5lVmVyc2lvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlQ2FjaGVFbmdpbmVWZXJzaW9ucycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgY2FjaGUgcGFyYW1ldGVyIGdyb3VwIGRlc2NyaXB0aW9uc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlQ2FjaGVQYXJhbWV0ZXJHcm91cHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVDYWNoZVBhcmFtZXRlckdyb3VwcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVDYWNoZVBhcmFtZXRlckdyb3VwcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHJpZXZlIHRoZSBkZXRhaWxlZCBwYXJhbWV0ZXIgbGlzdCBmb3IgYSBwYXJ0aWN1bGFyIGNhY2hlIHBhcmFtZXRlciBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlQ2FjaGVQYXJhbWV0ZXJzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlQ2FjaGVQYXJhbWV0ZXJzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUNhY2hlUGFyYW1ldGVycycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgY2FjaGUgc2VjdXJpdHkgZ3JvdXAgZGVzY3JpcHRpb25zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVDYWNoZVNlY3VyaXR5R3JvdXBzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlQ2FjaGVTZWN1cml0eUdyb3VwcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVDYWNoZVNlY3VyaXR5R3JvdXBzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBjYWNoZSBzdWJuZXQgZ3JvdXAgZGVzY3JpcHRpb25zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVDYWNoZVN1Ym5ldEdyb3Vwcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUNhY2hlU3VibmV0R3JvdXBzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUNhY2hlU3VibmV0R3JvdXBzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmV0cmlldmUgdGhlIGRlZmF1bHQgZW5naW5lIGFuZCBzeXN0ZW0gcGFyYW1ldGVyIGluZm9ybWF0aW9uIGZvciB0aGUgc3BlY2lmaWVkIGNhY2hlIGVuZ2luZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlRW5naW5lRGVmYXVsdFBhcmFtZXRlcnMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVFbmdpbmVEZWZhdWx0UGFyYW1ldGVycygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVFbmdpbmVEZWZhdWx0UGFyYW1ldGVycycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgZXZlbnRzIHJlbGF0ZWQgdG8gY2x1c3RlcnMsIGNhY2hlIHNlY3VyaXR5IGdyb3VwcywgYW5kIGNhY2hlIHBhcmFtZXRlciBncm91cHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUV2ZW50cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUV2ZW50cygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVFdmVudHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGluZm9ybWF0aW9uIGFib3V0IGdsb2JhbCByZXBsaWNhdGlvbiBncm91cHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXBzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlR2xvYmFsUmVwbGljYXRpb25Hcm91cHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlR2xvYmFsUmVwbGljYXRpb25Hcm91cHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGluZm9ybWF0aW9uIGFib3V0IHByb3Zpc2lvbmVkIHJlcGxpY2F0aW9uIGdyb3Vwc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlUmVwbGljYXRpb25Hcm91cHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVSZXBsaWNhdGlvbkdyb3VwcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVSZXBsaWNhdGlvbkdyb3VwcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgaW5mb3JtYXRpb24gYWJvdXQgcHVyY2hhc2VkIHJlc2VydmVkIGNhY2hlIG5vZGVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVSZXNlcnZlZENhY2hlTm9kZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVSZXNlcnZlZENhY2hlTm9kZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlUmVzZXJ2ZWRDYWNoZU5vZGVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBhdmFpbGFibGUgcmVzZXJ2ZWQgY2FjaGUgbm9kZSBvZmZlcmluZ3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVJlc2VydmVkQ2FjaGVOb2Rlc09mZmVyaW5ncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVJlc2VydmVkQ2FjaGVOb2Rlc09mZmVyaW5ncygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVSZXNlcnZlZENhY2hlTm9kZXNPZmZlcmluZ3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGluZm9ybWF0aW9uIGFib3V0IHNlcnZlcmxlc3MgY2FjaGUgc25hcHNob3RzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlU2VydmVybGVzc0NhY2hlU25hcHNob3RzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBzZXJ2ZXJsZXNzIGNhY2hlc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlU2VydmVybGVzc0NhY2hlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVNlcnZlcmxlc3NDYWNoZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlU2VydmVybGVzc0NhY2hlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgZGV0YWlscyBvZiB0aGUgc2VydmljZSB1cGRhdGVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVTZXJ2aWNlVXBkYXRlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVNlcnZpY2VVcGRhdGVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVNlcnZpY2VVcGRhdGVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBpbmZvcm1hdGlvbiBhYm91dCBjbHVzdGVyIG9yIHJlcGxpY2F0aW9uIGdyb3VwIHNuYXBzaG90c1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlU25hcHNob3RzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlU25hcHNob3RzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVNuYXBzaG90cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgZGV0YWlscyBvZiB0aGUgdXBkYXRlIGFjdGlvbnMgZm9yIGEgc2V0IG9mIGNsdXN0ZXJzIG9yIHJlcGxpY2F0aW9uIGdyb3Vwc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlVXBkYXRlQWN0aW9ucy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVVwZGF0ZUFjdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlVXBkYXRlQWN0aW9ucycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgaW5mb3JtYXRpb24gYWJvdXQgUmVkaXMgdXNlciBncm91cHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVVzZXJHcm91cHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVVc2VyR3JvdXBzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVVzZXJHcm91cHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGluZm9ybWF0aW9uIGFib3V0IFJlZGlzIHVzZXJzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVVc2Vycy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVVzZXJzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVVzZXJzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIGEgc2Vjb25kYXJ5IHJlcGxpY2F0aW9uIGdyb3VwIGZyb20gdGhlIGdsb2JhbCByZXBsaWNhdGlvbiBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EaXNhc3NvY2lhdGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rpc2Fzc29jaWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rpc2Fzc29jaWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBleHBvcnQgYSBjb3B5IG9mIGEgc2VydmVybGVzcyBjYWNoZSBhdCBhIHNwZWNpZmljIG1vbWVudCBpbiB0aW1lIHRvIHMzIGJ1Y2tldFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9FeHBvcnRTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9FeHBvcnRTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRXhwb3J0U2VydmVybGVzc0NhY2hlU25hcHNob3QnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBmYWlsb3ZlciB0aGUgcHJpbWFyeSByZWdpb24gdG8gYSBzZWxlY3RlZCBzZWNvbmRhcnkgcmVnaW9uIG9mIGEgZ2xvYmFsIHJlcGxpY2F0aW9uIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0ZhaWxvdmVyR2xvYmFsUmVwbGljYXRpb25Hcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9GYWlsb3Zlckdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0ZhaWxvdmVyR2xvYmFsUmVwbGljYXRpb25Hcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGluY3JlYXNlIHRoZSBudW1iZXIgb2Ygbm9kZSBncm91cHMgaW4gYSBnbG9iYWwgcmVwbGljYXRpb24gZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfSW5jcmVhc2VOb2RlR3JvdXBzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0luY3JlYXNlTm9kZUdyb3Vwc0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnSW5jcmVhc2VOb2RlR3JvdXBzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gaW5jcmVhc2UgdGhlIG51bWJlciBvZiByZXBsaWNhcyBpbiBhIFJlZGlzIChjbHVzdGVyIG1vZGUgZGlzYWJsZWQpIHJlcGxpY2F0aW9uIGdyb3VwIG9yIHRoZSBudW1iZXIgb2YgcmVwbGljYSBub2RlcyBpbiBvbmUgb3IgbW9yZSBub2RlIGdyb3VwcyAoc2hhcmRzKSBvZiBhIFJlZGlzIChjbHVzdGVyIG1vZGUgZW5hYmxlZCkgcmVwbGljYXRpb24gZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfSW5jcmVhc2VSZXBsaWNhQ291bnQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvSW5jcmVhc2VSZXBsaWNhQ291bnQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0luY3JlYXNlUmVwbGljYUNvdW50Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBhdmFpbGFibGUgbm9kZSB0eXBlIHRoYXQgY2FuIGJlIHVzZWQgdG8gc2NhbGUgYSBwYXJ0aWN1bGFyIFJlZGlzIGNsdXN0ZXIgb3IgcmVwbGljYXRpb24gZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0QWxsb3dlZE5vZGVUeXBlTW9kaWZpY2F0aW9ucy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0QWxsb3dlZE5vZGVUeXBlTW9kaWZpY2F0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdEFsbG93ZWROb2RlVHlwZU1vZGlmaWNhdGlvbnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHRhZ3MgZm9yIGFuIEVsYXN0aUNhY2hlIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdFRhZ3NGb3JSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0VGFnc0ZvclJlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0VGFnc0ZvclJlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbW9kaWZ5IHNldHRpbmdzIGZvciBhIGNsdXN0ZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTW9kaWZ5Q2FjaGVDbHVzdGVyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b01vZGlmeUNhY2hlQ2x1c3RlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTW9kaWZ5Q2FjaGVDbHVzdGVyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbW9kaWZ5IHBhcmFtZXRlcnMgb2YgYSBjYWNoZSBwYXJhbWV0ZXIgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTW9kaWZ5Q2FjaGVQYXJhbWV0ZXJHcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9Nb2RpZnlDYWNoZVBhcmFtZXRlckdyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdNb2RpZnlDYWNoZVBhcmFtZXRlckdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbW9kaWZ5IGFuIGV4aXN0aW5nIGNhY2hlIHN1Ym5ldCBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9Nb2RpZnlDYWNoZVN1Ym5ldEdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b01vZGlmeUNhY2hlU3VibmV0R3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ01vZGlmeUNhY2hlU3VibmV0R3JvdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBtb2RpZnkgc2V0dGluZ3MgZm9yIGEgZ2xvYmFsIHJlcGxpY2F0aW9uIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX01vZGlmeUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTW9kaWZ5R2xvYmFsUmVwbGljYXRpb25Hcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTW9kaWZ5R2xvYmFsUmVwbGljYXRpb25Hcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIG1vZGlmeSB0aGUgc2V0dGluZ3MgZm9yIGEgcmVwbGljYXRpb24gZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTW9kaWZ5UmVwbGljYXRpb25Hcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9Nb2RpZnlSZXBsaWNhdGlvbkdyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdNb2RpZnlSZXBsaWNhdGlvbkdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWRkIHNoYXJkcywgcmVtb3ZlIHNoYXJkcywgb3IgcmViYWxhbmNlIHRoZSBrZXlzcGFjZXMgYW1vbmcgZXhpc3Rpbmcgc2hhcmRzIG9mIGEgcmVwbGljYXRpb24gZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTW9kaWZ5UmVwbGljYXRpb25Hcm91cFNoYXJkQ29uZmlndXJhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9Nb2RpZnlSZXBsaWNhdGlvbkdyb3VwU2hhcmRDb25maWd1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdNb2RpZnlSZXBsaWNhdGlvbkdyb3VwU2hhcmRDb25maWd1cmF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbW9kaWZ5IHBhcmFtZXRlcnMgZm9yIGEgc2VydmVybGVzcyBjYWNoZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9Nb2RpZnlTZXJ2ZXJsZXNzQ2FjaGUuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTW9kaWZ5U2VydmVybGVzc0NhY2hlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdNb2RpZnlTZXJ2ZXJsZXNzQ2FjaGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjaGFuZ2UgUmVkaXMgdXNlciBwYXNzd29yZChzKSBhbmQvb3IgYWNjZXNzIHN0cmluZ1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9Nb2RpZnlVc2VyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b01vZGlmeVVzZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ01vZGlmeVVzZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjaGFuZ2UgbGlzdCBvZiB1c2VycyB0aGF0IGJlbG9uZyB0byB0aGUgdXNlciBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9Nb2RpZnlVc2VyR3JvdXAuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTW9kaWZ5VXNlckdyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdNb2RpZnlVc2VyR3JvdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBwdXJjaGFzZSBhIHJlc2VydmVkIGNhY2hlIG5vZGUgb2ZmZXJpbmdcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUHVyY2hhc2VSZXNlcnZlZENhY2hlTm9kZXNPZmZlcmluZy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9QdXJjaGFzZVJlc2VydmVkQ2FjaGVOb2Rlc09mZmVyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdQdXJjaGFzZVJlc2VydmVkQ2FjaGVOb2Rlc09mZmVyaW5nJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcGVyZm9ybSBhIGtleSBzcGFjZSByZWJhbGFuY2Ugb3BlcmF0aW9uIHRvIHJlZGlzdHJpYnV0ZSBzbG90cyBhbmQgZW5zdXJlIHVuaWZvcm0ga2V5IGRpc3RyaWJ1dGlvbiBhY3Jvc3MgZXhpc3Rpbmcgc2hhcmRzIGluIGEgZ2xvYmFsIHJlcGxpY2F0aW9uIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1JlYmFsYW5jZVNsb3RzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlYmFsYW5jZVNsb3RzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdSZWJhbGFuY2VTbG90c0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlYm9vdCBzb21lLCBvciBhbGwsIG9mIHRoZSBjYWNoZSBub2RlcyB3aXRoaW4gYSBwcm92aXNpb25lZCBjYWNoZSBjbHVzdGVyIG9yIHJlcGxpY2F0aW9uIGdyb3VwIChjbHVzdGVyIG1vZGUgZGlzYWJsZWQpXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1JlYm9vdENhY2hlQ2x1c3Rlci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9SZWJvb3RDYWNoZUNsdXN0ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1JlYm9vdENhY2hlQ2x1c3RlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSB0YWdzIGZyb20gYSBFbGFzdGlDYWNoZSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmcsIFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9SZW1vdmVUYWdzRnJvbVJlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlbW92ZVRhZ3NGcm9tUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1JlbW92ZVRhZ3NGcm9tUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBtb2RpZnkgcGFyYW1ldGVycyBvZiBhIGNhY2hlIHBhcmFtZXRlciBncm91cCBiYWNrIHRvIHRoZWlyIGRlZmF1bHQgdmFsdWVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1Jlc2V0Q2FjaGVQYXJhbWV0ZXJHcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9SZXNldENhY2hlUGFyYW1ldGVyR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1Jlc2V0Q2FjaGVQYXJhbWV0ZXJHcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSBhbiBFQzIgc2VjdXJpdHkgZ3JvdXAgaW5ncmVzcyBmcm9tIGEgRWxhc3RpQ2FjaGUgc2VjdXJpdHkgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUmV2b2tlQ2FjaGVTZWN1cml0eUdyb3VwSW5ncmVzcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9SZXZva2VDYWNoZVNlY3VyaXR5R3JvdXBJbmdyZXNzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdSZXZva2VDYWNoZVNlY3VyaXR5R3JvdXBJbmdyZXNzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gc3RhcnQgYSBtaWdyYXRpb24gb2YgZGF0YSBmcm9tIGhvc3RlZCBSZWRpcyBvbiBBbWF6b24gRUMyIHRvIEVsYXN0aUNhY2hlIGZvciBSZWRpc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9TdGFydE1pZ3JhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9TdGFydE1pZ3JhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnU3RhcnRNaWdyYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB0ZXN0IGF1dG9tYXRpYyBmYWlsb3ZlciBvbiBhIHNwZWNpZmllZCBub2RlIGdyb3VwIGluIGEgcmVwbGljYXRpb24gZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVGVzdEZhaWxvdmVyLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1Rlc3RGYWlsb3ZlcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVGVzdEZhaWxvdmVyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdGVzdCBhIG1pZ3JhdGlvbiBvZiBkYXRhIGZyb20gaG9zdGVkIFJlZGlzIG9uIEFtYXpvbiBFQzIgdG8gRWxhc3RpQ2FjaGUgZm9yIFJlZGlzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1Rlc3RNaWdyYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVGVzdE1pZ3JhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVGVzdE1pZ3JhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHRlc3QgYW4gQVogcG93ZXIgaW50ZXJydXB0aW9uIGZvciBhbiBFbGFzdGlDYWNoZSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9maXMvbGF0ZXN0L3VzZXJndWlkZS9maXMtYWN0aW9ucy1yZWZlcmVuY2UuaHRtbCNlbGFzdGljYWNoZS1hY3Rpb25zLXJlZmVyZW5jZVxuICAgKi9cbiAgcHVibGljIHRvSW50ZXJydXB0Q2x1c3RlckF6UG93ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0ludGVycnVwdENsdXN0ZXJBelBvd2VyJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWNjZXNzTGV2ZWxMaXN0OiBBY2Nlc3NMZXZlbExpc3QgPSB7XG4gICAgVGFnZ2luZzogW1xuICAgICAgJ0FkZFRhZ3NUb1Jlc291cmNlJyxcbiAgICAgICdSZW1vdmVUYWdzRnJvbVJlc291cmNlJ1xuICAgIF0sXG4gICAgV3JpdGU6IFtcbiAgICAgICdBZGRUYWdzVG9SZXNvdXJjZScsXG4gICAgICAnQXV0aG9yaXplQ2FjaGVTZWN1cml0eUdyb3VwSW5ncmVzcycsXG4gICAgICAnQmF0Y2hBcHBseVVwZGF0ZUFjdGlvbicsXG4gICAgICAnQmF0Y2hTdG9wVXBkYXRlQWN0aW9uJyxcbiAgICAgICdDb21wbGV0ZU1pZ3JhdGlvbicsXG4gICAgICAnQ29ubmVjdCcsXG4gICAgICAnQ29weVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90JyxcbiAgICAgICdDb3B5U25hcHNob3QnLFxuICAgICAgJ0NyZWF0ZUNhY2hlQ2x1c3RlcicsXG4gICAgICAnQ3JlYXRlQ2FjaGVQYXJhbWV0ZXJHcm91cCcsXG4gICAgICAnQ3JlYXRlQ2FjaGVTZWN1cml0eUdyb3VwJyxcbiAgICAgICdDcmVhdGVDYWNoZVN1Ym5ldEdyb3VwJyxcbiAgICAgICdDcmVhdGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwJyxcbiAgICAgICdDcmVhdGVSZXBsaWNhdGlvbkdyb3VwJyxcbiAgICAgICdDcmVhdGVTZXJ2ZXJsZXNzQ2FjaGUnLFxuICAgICAgJ0NyZWF0ZVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90JyxcbiAgICAgICdDcmVhdGVTbmFwc2hvdCcsXG4gICAgICAnQ3JlYXRlVXNlcicsXG4gICAgICAnQ3JlYXRlVXNlckdyb3VwJyxcbiAgICAgICdEZWNyZWFzZU5vZGVHcm91cHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAnLFxuICAgICAgJ0RlY3JlYXNlUmVwbGljYUNvdW50JyxcbiAgICAgICdEZWxldGVDYWNoZUNsdXN0ZXInLFxuICAgICAgJ0RlbGV0ZUNhY2hlUGFyYW1ldGVyR3JvdXAnLFxuICAgICAgJ0RlbGV0ZUNhY2hlU2VjdXJpdHlHcm91cCcsXG4gICAgICAnRGVsZXRlQ2FjaGVTdWJuZXRHcm91cCcsXG4gICAgICAnRGVsZXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCcsXG4gICAgICAnRGVsZXRlUmVwbGljYXRpb25Hcm91cCcsXG4gICAgICAnRGVsZXRlU2VydmVybGVzc0NhY2hlJyxcbiAgICAgICdEZWxldGVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdCcsXG4gICAgICAnRGVsZXRlU25hcHNob3QnLFxuICAgICAgJ0RlbGV0ZVVzZXInLFxuICAgICAgJ0RlbGV0ZVVzZXJHcm91cCcsXG4gICAgICAnRGlzYXNzb2NpYXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCcsXG4gICAgICAnRXhwb3J0U2VydmVybGVzc0NhY2hlU25hcHNob3QnLFxuICAgICAgJ0ZhaWxvdmVyR2xvYmFsUmVwbGljYXRpb25Hcm91cCcsXG4gICAgICAnSW5jcmVhc2VOb2RlR3JvdXBzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwJyxcbiAgICAgICdJbmNyZWFzZVJlcGxpY2FDb3VudCcsXG4gICAgICAnTW9kaWZ5Q2FjaGVDbHVzdGVyJyxcbiAgICAgICdNb2RpZnlDYWNoZVBhcmFtZXRlckdyb3VwJyxcbiAgICAgICdNb2RpZnlDYWNoZVN1Ym5ldEdyb3VwJyxcbiAgICAgICdNb2RpZnlHbG9iYWxSZXBsaWNhdGlvbkdyb3VwJyxcbiAgICAgICdNb2RpZnlSZXBsaWNhdGlvbkdyb3VwJyxcbiAgICAgICdNb2RpZnlSZXBsaWNhdGlvbkdyb3VwU2hhcmRDb25maWd1cmF0aW9uJyxcbiAgICAgICdNb2RpZnlTZXJ2ZXJsZXNzQ2FjaGUnLFxuICAgICAgJ01vZGlmeVVzZXInLFxuICAgICAgJ01vZGlmeVVzZXJHcm91cCcsXG4gICAgICAnUHVyY2hhc2VSZXNlcnZlZENhY2hlTm9kZXNPZmZlcmluZycsXG4gICAgICAnUmViYWxhbmNlU2xvdHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAnLFxuICAgICAgJ1JlYm9vdENhY2hlQ2x1c3RlcicsXG4gICAgICAnUmVtb3ZlVGFnc0Zyb21SZXNvdXJjZScsXG4gICAgICAnUmVzZXRDYWNoZVBhcmFtZXRlckdyb3VwJyxcbiAgICAgICdSZXZva2VDYWNoZVNlY3VyaXR5R3JvdXBJbmdyZXNzJyxcbiAgICAgICdTdGFydE1pZ3JhdGlvbicsXG4gICAgICAnVGVzdEZhaWxvdmVyJyxcbiAgICAgICdUZXN0TWlncmF0aW9uJyxcbiAgICAgICdJbnRlcnJ1cHRDbHVzdGVyQXpQb3dlcidcbiAgICBdLFxuICAgIExpc3Q6IFtcbiAgICAgICdEZXNjcmliZUNhY2hlQ2x1c3RlcnMnLFxuICAgICAgJ0Rlc2NyaWJlQ2FjaGVFbmdpbmVWZXJzaW9ucycsXG4gICAgICAnRGVzY3JpYmVDYWNoZVBhcmFtZXRlckdyb3VwcycsXG4gICAgICAnRGVzY3JpYmVDYWNoZVBhcmFtZXRlcnMnLFxuICAgICAgJ0Rlc2NyaWJlQ2FjaGVTZWN1cml0eUdyb3VwcycsXG4gICAgICAnRGVzY3JpYmVDYWNoZVN1Ym5ldEdyb3VwcycsXG4gICAgICAnRGVzY3JpYmVFbmdpbmVEZWZhdWx0UGFyYW1ldGVycycsXG4gICAgICAnRGVzY3JpYmVFdmVudHMnLFxuICAgICAgJ0Rlc2NyaWJlR2xvYmFsUmVwbGljYXRpb25Hcm91cHMnLFxuICAgICAgJ0Rlc2NyaWJlUmVwbGljYXRpb25Hcm91cHMnLFxuICAgICAgJ0Rlc2NyaWJlUmVzZXJ2ZWRDYWNoZU5vZGVzJyxcbiAgICAgICdEZXNjcmliZVJlc2VydmVkQ2FjaGVOb2Rlc09mZmVyaW5ncycsXG4gICAgICAnRGVzY3JpYmVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdHMnLFxuICAgICAgJ0Rlc2NyaWJlU2VydmVybGVzc0NhY2hlcycsXG4gICAgICAnRGVzY3JpYmVTZXJ2aWNlVXBkYXRlcycsXG4gICAgICAnRGVzY3JpYmVTbmFwc2hvdHMnLFxuICAgICAgJ0Rlc2NyaWJlVXBkYXRlQWN0aW9ucycsXG4gICAgICAnRGVzY3JpYmVVc2VyR3JvdXBzJyxcbiAgICAgICdEZXNjcmliZVVzZXJzJyxcbiAgICAgICdMaXN0QWxsb3dlZE5vZGVUeXBlTW9kaWZpY2F0aW9ucydcbiAgICBdLFxuICAgIFJlYWQ6IFtcbiAgICAgICdMaXN0VGFnc0ZvclJlc291cmNlJ1xuICAgIF1cbiAgfTtcblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgY2x1c3RlciB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvcmVkLXVnL1doYXRJcy5Db21wb25lbnRzLmh0bWwjV2hhdElzLkNvbXBvbmVudHMuQ2x1c3RlcnNcbiAgICpcbiAgICogQHBhcmFtIGNhY2hlQ2x1c3RlcklkIC0gSWRlbnRpZmllciBmb3IgdGhlIGNhY2hlQ2x1c3RlcklkLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqIC0gLmlmQXV0aFRva2VuRW5hYmxlZCgpXG4gICAqIC0gLmlmQ2FjaGVOb2RlVHlwZSgpXG4gICAqIC0gLmlmQ2FjaGVQYXJhbWV0ZXJHcm91cE5hbWUoKVxuICAgKiAtIC5pZkVuZ2luZVR5cGUoKVxuICAgKiAtIC5pZkVuZ2luZVZlcnNpb24oKVxuICAgKiAtIC5pZk11bHRpQVpFbmFibGVkKClcbiAgICogLSAuaWZTbmFwc2hvdFJldGVudGlvbkxpbWl0KClcbiAgICovXG4gIHB1YmxpYyBvbkNsdXN0ZXIoY2FjaGVDbHVzdGVySWQ6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTplbGFzdGljYWNoZTokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06Y2x1c3RlcjokeyBjYWNoZUNsdXN0ZXJJZCB9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgZ2xvYmFscmVwbGljYXRpb25ncm91cCB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvcmVkLXVnL1JlZGlzLUdsb2JhbC1EYXRhc3RvcmUuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gZ2xvYmFsUmVwbGljYXRpb25Hcm91cElkIC0gSWRlbnRpZmllciBmb3IgdGhlIGdsb2JhbFJlcGxpY2F0aW9uR3JvdXBJZC5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF0UmVzdEVuY3J5cHRpb25FbmFibGVkKClcbiAgICogLSAuaWZBdXRoVG9rZW5FbmFibGVkKClcbiAgICogLSAuaWZBdXRvbWF0aWNGYWlsb3ZlckVuYWJsZWQoKVxuICAgKiAtIC5pZkNhY2hlTm9kZVR5cGUoKVxuICAgKiAtIC5pZkNhY2hlUGFyYW1ldGVyR3JvdXBOYW1lKClcbiAgICogLSAuaWZDbHVzdGVyTW9kZUVuYWJsZWQoKVxuICAgKiAtIC5pZkVuZ2luZVR5cGUoKVxuICAgKiAtIC5pZkVuZ2luZVZlcnNpb24oKVxuICAgKiAtIC5pZkttc0tleUlkKClcbiAgICogLSAuaWZNdWx0aUFaRW5hYmxlZCgpXG4gICAqIC0gLmlmTnVtTm9kZUdyb3VwcygpXG4gICAqIC0gLmlmUmVwbGljYXNQZXJOb2RlR3JvdXAoKVxuICAgKiAtIC5pZlNuYXBzaG90UmV0ZW50aW9uTGltaXQoKVxuICAgKiAtIC5pZlRyYW5zaXRFbmNyeXB0aW9uRW5hYmxlZCgpXG4gICAqL1xuICBwdWJsaWMgb25HbG9iYWxyZXBsaWNhdGlvbmdyb3VwKGdsb2JhbFJlcGxpY2F0aW9uR3JvdXBJZDogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTplbGFzdGljYWNoZTo6JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06Z2xvYmFscmVwbGljYXRpb25ncm91cDokeyBnbG9iYWxSZXBsaWNhdGlvbkdyb3VwSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIHBhcmFtZXRlcmdyb3VwIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9yZWQtdWcvV2hhdElzLkNvbXBvbmVudHMuaHRtbCNXaGF0SXMuQ29tcG9uZW50cy5QYXJhbWV0ZXJHcm91cHNcbiAgICpcbiAgICogQHBhcmFtIGNhY2hlUGFyYW1ldGVyR3JvdXBOYW1lIC0gSWRlbnRpZmllciBmb3IgdGhlIGNhY2hlUGFyYW1ldGVyR3JvdXBOYW1lLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqIC0gLmlmQ2FjaGVQYXJhbWV0ZXJHcm91cE5hbWUoKVxuICAgKi9cbiAgcHVibGljIG9uUGFyYW1ldGVyZ3JvdXAoY2FjaGVQYXJhbWV0ZXJHcm91cE5hbWU6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTplbGFzdGljYWNoZTokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06cGFyYW1ldGVyZ3JvdXA6JHsgY2FjaGVQYXJhbWV0ZXJHcm91cE5hbWUgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIHJlcGxpY2F0aW9uZ3JvdXAgdG8gdGhlIHN0YXRlbWVudFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L3JlZC11Zy9XaGF0SXMuQ29tcG9uZW50cy5odG1sI1doYXRJcy5Db21wb25lbnRzLlJlcGxpY2F0aW9uR3JvdXBzXG4gICAqXG4gICAqIEBwYXJhbSByZXBsaWNhdGlvbkdyb3VwSWQgLSBJZGVudGlmaWVyIGZvciB0aGUgcmVwbGljYXRpb25Hcm91cElkLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqIC0gLmlmQXRSZXN0RW5jcnlwdGlvbkVuYWJsZWQoKVxuICAgKiAtIC5pZkF1dGhUb2tlbkVuYWJsZWQoKVxuICAgKiAtIC5pZkF1dG9tYXRpY0ZhaWxvdmVyRW5hYmxlZCgpXG4gICAqIC0gLmlmQ2FjaGVOb2RlVHlwZSgpXG4gICAqIC0gLmlmQ2FjaGVQYXJhbWV0ZXJHcm91cE5hbWUoKVxuICAgKiAtIC5pZkNsdXN0ZXJNb2RlRW5hYmxlZCgpXG4gICAqIC0gLmlmRHVyYWJpbGl0eSgpXG4gICAqIC0gLmlmRW5naW5lVHlwZSgpXG4gICAqIC0gLmlmRW5naW5lVmVyc2lvbigpXG4gICAqIC0gLmlmS21zS2V5SWQoKVxuICAgKiAtIC5pZk11bHRpQVpFbmFibGVkKClcbiAgICogLSAuaWZOdW1Ob2RlR3JvdXBzKClcbiAgICogLSAuaWZSZXBsaWNhc1Blck5vZGVHcm91cCgpXG4gICAqIC0gLmlmU25hcHNob3RSZXRlbnRpb25MaW1pdCgpXG4gICAqIC0gLmlmVHJhbnNpdEVuY3J5cHRpb25FbmFibGVkKClcbiAgICovXG4gIHB1YmxpYyBvblJlcGxpY2F0aW9uZ3JvdXAocmVwbGljYXRpb25Hcm91cElkOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06ZWxhc3RpY2FjaGU6JHsgcmVnaW9uID8/IHRoaXMuZGVmYXVsdFJlZ2lvbiB9OiR7IGFjY291bnQgPz8gdGhpcy5kZWZhdWx0QWNjb3VudCB9OnJlcGxpY2F0aW9uZ3JvdXA6JHsgcmVwbGljYXRpb25Hcm91cElkIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgcmVzb3VyY2Ugb2YgdHlwZSByZXNlcnZlZC1pbnN0YW5jZSB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvcmVkLXVnL3Jlc2VydmVkLW5vZGVzLmh0bWxcbiAgICpcbiAgICogQHBhcmFtIHJlc2VydmVkQ2FjaGVOb2RlSWQgLSBJZGVudGlmaWVyIGZvciB0aGUgcmVzZXJ2ZWRDYWNoZU5vZGVJZC5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKi9cbiAgcHVibGljIG9uUmVzZXJ2ZWRJbnN0YW5jZShyZXNlcnZlZENhY2hlTm9kZUlkOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06ZWxhc3RpY2FjaGU6JHsgcmVnaW9uID8/IHRoaXMuZGVmYXVsdFJlZ2lvbiB9OiR7IGFjY291bnQgPz8gdGhpcy5kZWZhdWx0QWNjb3VudCB9OnJlc2VydmVkLWluc3RhbmNlOiR7IHJlc2VydmVkQ2FjaGVOb2RlSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIHNlY3VyaXR5Z3JvdXAgdG8gdGhlIHN0YXRlbWVudFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L3JlZC11Zy9XaGF0SXMuQ29tcG9uZW50cy5odG1sI1doYXRJcy5Db21wb25lbnRzLlNlY3VyaXR5R3JvdXBzXG4gICAqXG4gICAqIEBwYXJhbSBjYWNoZVNlY3VyaXR5R3JvdXBOYW1lIC0gSWRlbnRpZmllciBmb3IgdGhlIGNhY2hlU2VjdXJpdHlHcm91cE5hbWUuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICovXG4gIHB1YmxpYyBvblNlY3VyaXR5Z3JvdXAoY2FjaGVTZWN1cml0eUdyb3VwTmFtZTogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OmVsYXN0aWNhY2hlOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpzZWN1cml0eWdyb3VwOiR7IGNhY2hlU2VjdXJpdHlHcm91cE5hbWUgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIHNlcnZlcmxlc3NjYWNoZSB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvcmVkLXVnL1doYXRJcy5odG1sXG4gICAqXG4gICAqIEBwYXJhbSBzZXJ2ZXJsZXNzQ2FjaGVOYW1lIC0gSWRlbnRpZmllciBmb3IgdGhlIHNlcnZlcmxlc3NDYWNoZU5hbWUuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICogLSAuaWZEYXRhU3RvcmFnZVVuaXQoKVxuICAgKiAtIC5pZkVuZ2luZVR5cGUoKVxuICAgKiAtIC5pZkVuZ2luZVZlcnNpb24oKVxuICAgKiAtIC5pZkttc0tleUlkKClcbiAgICogLSAuaWZNYXhpbXVtRGF0YVN0b3JhZ2UoKVxuICAgKiAtIC5pZk1heGltdW1FQ1BVUGVyU2Vjb25kKClcbiAgICogLSAuaWZNaW5pbXVtRGF0YVN0b3JhZ2UoKVxuICAgKiAtIC5pZk1pbmltdW1FQ1BVUGVyU2Vjb25kKClcbiAgICogLSAuaWZTbmFwc2hvdFJldGVudGlvbkxpbWl0KClcbiAgICovXG4gIHB1YmxpYyBvblNlcnZlcmxlc3NjYWNoZShzZXJ2ZXJsZXNzQ2FjaGVOYW1lOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06ZWxhc3RpY2FjaGU6JHsgcmVnaW9uID8/IHRoaXMuZGVmYXVsdFJlZ2lvbiB9OiR7IGFjY291bnQgPz8gdGhpcy5kZWZhdWx0QWNjb3VudCB9OnNlcnZlcmxlc3NjYWNoZTokeyBzZXJ2ZXJsZXNzQ2FjaGVOYW1lIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgcmVzb3VyY2Ugb2YgdHlwZSBzZXJ2ZXJsZXNzY2FjaGVzbmFwc2hvdCB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvcmVkLXVnL1doYXRJcy5odG1sXG4gICAqXG4gICAqIEBwYXJhbSBzZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdE5hbWUgLSBJZGVudGlmaWVyIGZvciB0aGUgc2VydmVybGVzc0NhY2hlU25hcHNob3ROYW1lLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqIC0gLmlmS21zS2V5SWQoKVxuICAgKi9cbiAgcHVibGljIG9uU2VydmVybGVzc2NhY2hlc25hcHNob3Qoc2VydmVybGVzc0NhY2hlU25hcHNob3ROYW1lOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06ZWxhc3RpY2FjaGU6JHsgcmVnaW9uID8/IHRoaXMuZGVmYXVsdFJlZ2lvbiB9OiR7IGFjY291bnQgPz8gdGhpcy5kZWZhdWx0QWNjb3VudCB9OnNlcnZlcmxlc3NjYWNoZXNuYXBzaG90OiR7IHNlcnZlcmxlc3NDYWNoZVNuYXBzaG90TmFtZSB9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgc25hcHNob3QgdG8gdGhlIHN0YXRlbWVudFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L3JlZC11Zy9XaGF0SXMuQ29tcG9uZW50cy5odG1sI1doYXRJcy5Db21wb25lbnRzLlNuYXBzaG90c1xuICAgKlxuICAgKiBAcGFyYW0gc25hcHNob3ROYW1lIC0gSWRlbnRpZmllciBmb3IgdGhlIHNuYXBzaG90TmFtZS5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKiAtIC5pZkttc0tleUlkKClcbiAgICovXG4gIHB1YmxpYyBvblNuYXBzaG90KHNuYXBzaG90TmFtZTogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OmVsYXN0aWNhY2hlOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpzbmFwc2hvdDokeyBzbmFwc2hvdE5hbWUgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIHN1Ym5ldGdyb3VwIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9yZWQtdWcvV2hhdElzLkNvbXBvbmVudHMuaHRtbCNXaGF0SXMuQ29tcG9uZW50cy5TdWJuZXRHcm91cHNcbiAgICpcbiAgICogQHBhcmFtIGNhY2hlU3VibmV0R3JvdXBOYW1lIC0gSWRlbnRpZmllciBmb3IgdGhlIGNhY2hlU3VibmV0R3JvdXBOYW1lLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqL1xuICBwdWJsaWMgb25TdWJuZXRncm91cChjYWNoZVN1Ym5ldEdyb3VwTmFtZTogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OmVsYXN0aWNhY2hlOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpzdWJuZXRncm91cDokeyBjYWNoZVN1Ym5ldEdyb3VwTmFtZSB9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgdXNlciB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvcmVkLXVnL0NsdXN0ZXJzLlJCQUMuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gdXNlcklkIC0gSWRlbnRpZmllciBmb3IgdGhlIHVzZXJJZC5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKiAtIC5pZlVzZXJBdXRoZW50aWNhdGlvbk1vZGUoKVxuICAgKi9cbiAgcHVibGljIG9uVXNlcih1c2VySWQ6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTplbGFzdGljYWNoZTokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06dXNlcjokeyB1c2VySWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIHVzZXJncm91cCB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvcmVkLXVnL0NsdXN0ZXJzLlJCQUMuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gdXNlckdyb3VwSWQgLSBJZGVudGlmaWVyIGZvciB0aGUgdXNlckdyb3VwSWQuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICovXG4gIHB1YmxpYyBvblVzZXJncm91cCh1c2VyR3JvdXBJZDogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OmVsYXN0aWNhY2hlOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTp1c2VyZ3JvdXA6JHsgdXNlckdyb3VwSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWN0aW9ucyBiYXNlZCBvbiB0aGUgdGFncyB0aGF0IGFyZSBwYXNzZWQgaW4gdGhlIHJlcXVlc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19jb25kaXRpb24ta2V5cy5odG1sI2NvbmRpdGlvbi1rZXlzLXJlcXVlc3R0YWdcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0FkZFRhZ3NUb1Jlc291cmNlKClcbiAgICogLSAudG9BdXRob3JpemVDYWNoZVNlY3VyaXR5R3JvdXBJbmdyZXNzKClcbiAgICogLSAudG9CYXRjaEFwcGx5VXBkYXRlQWN0aW9uKClcbiAgICogLSAudG9CYXRjaFN0b3BVcGRhdGVBY3Rpb24oKVxuICAgKiAtIC50b0NvbXBsZXRlTWlncmF0aW9uKClcbiAgICogLSAudG9Db25uZWN0KClcbiAgICogLSAudG9Db3B5U2VydmVybGVzc0NhY2hlU25hcHNob3QoKVxuICAgKiAtIC50b0NvcHlTbmFwc2hvdCgpXG4gICAqIC0gLnRvQ3JlYXRlQ2FjaGVDbHVzdGVyKClcbiAgICogLSAudG9DcmVhdGVDYWNoZVBhcmFtZXRlckdyb3VwKClcbiAgICogLSAudG9DcmVhdGVDYWNoZVNlY3VyaXR5R3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZUNhY2hlU3VibmV0R3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZVNlcnZlcmxlc3NDYWNoZSgpXG4gICAqIC0gLnRvQ3JlYXRlU2VydmVybGVzc0NhY2hlU25hcHNob3QoKVxuICAgKiAtIC50b0NyZWF0ZVNuYXBzaG90KClcbiAgICogLSAudG9DcmVhdGVVc2VyKClcbiAgICogLSAudG9DcmVhdGVVc2VyR3JvdXAoKVxuICAgKiAtIC50b0RlY3JlYXNlUmVwbGljYUNvdW50KClcbiAgICogLSAudG9EZWxldGVDYWNoZUNsdXN0ZXIoKVxuICAgKiAtIC50b0RlbGV0ZUNhY2hlUGFyYW1ldGVyR3JvdXAoKVxuICAgKiAtIC50b0RlbGV0ZUNhY2hlU2VjdXJpdHlHcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlQ2FjaGVTdWJuZXRHcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlU2VydmVybGVzc0NhY2hlKClcbiAgICogLSAudG9EZWxldGVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvRGVsZXRlU25hcHNob3QoKVxuICAgKiAtIC50b0RlbGV0ZVVzZXIoKVxuICAgKiAtIC50b0RlbGV0ZVVzZXJHcm91cCgpXG4gICAqIC0gLnRvRGVzY3JpYmVDYWNoZUNsdXN0ZXJzKClcbiAgICogLSAudG9EZXNjcmliZUNhY2hlUGFyYW1ldGVyR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZUNhY2hlUGFyYW1ldGVycygpXG4gICAqIC0gLnRvRGVzY3JpYmVDYWNoZVNlY3VyaXR5R3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZUNhY2hlU3VibmV0R3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVJlc2VydmVkQ2FjaGVOb2RlcygpXG4gICAqIC0gLnRvRGVzY3JpYmVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlU2VydmVybGVzc0NhY2hlcygpXG4gICAqIC0gLnRvRGVzY3JpYmVTbmFwc2hvdHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlVXBkYXRlQWN0aW9ucygpXG4gICAqIC0gLnRvRGVzY3JpYmVVc2VyR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVVzZXJzKClcbiAgICogLSAudG9FeHBvcnRTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvSW5jcmVhc2VSZXBsaWNhQ291bnQoKVxuICAgKiAtIC50b0xpc3RBbGxvd2VkTm9kZVR5cGVNb2RpZmljYXRpb25zKClcbiAgICogLSAudG9MaXN0VGFnc0ZvclJlc291cmNlKClcbiAgICogLSAudG9Nb2RpZnlDYWNoZUNsdXN0ZXIoKVxuICAgKiAtIC50b01vZGlmeUNhY2hlUGFyYW1ldGVyR3JvdXAoKVxuICAgKiAtIC50b01vZGlmeUNhY2hlU3VibmV0R3JvdXAoKVxuICAgKiAtIC50b01vZGlmeVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b01vZGlmeVJlcGxpY2F0aW9uR3JvdXBTaGFyZENvbmZpZ3VyYXRpb24oKVxuICAgKiAtIC50b01vZGlmeVNlcnZlcmxlc3NDYWNoZSgpXG4gICAqIC0gLnRvTW9kaWZ5VXNlcigpXG4gICAqIC0gLnRvTW9kaWZ5VXNlckdyb3VwKClcbiAgICogLSAudG9QdXJjaGFzZVJlc2VydmVkQ2FjaGVOb2Rlc09mZmVyaW5nKClcbiAgICogLSAudG9SZWJvb3RDYWNoZUNsdXN0ZXIoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3NGcm9tUmVzb3VyY2UoKVxuICAgKiAtIC50b1Jlc2V0Q2FjaGVQYXJhbWV0ZXJHcm91cCgpXG4gICAqIC0gLnRvUmV2b2tlQ2FjaGVTZWN1cml0eUdyb3VwSW5ncmVzcygpXG4gICAqIC0gLnRvU3RhcnRNaWdyYXRpb24oKVxuICAgKiAtIC50b1Rlc3RGYWlsb3ZlcigpXG4gICAqIC0gLnRvVGVzdE1pZ3JhdGlvbigpXG4gICAqIC0gLnRvSW50ZXJydXB0Q2x1c3RlckF6UG93ZXIoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIGNsdXN0ZXJcbiAgICogLSBwYXJhbWV0ZXJncm91cFxuICAgKiAtIHJlcGxpY2F0aW9uZ3JvdXBcbiAgICogLSByZXNlcnZlZC1pbnN0YW5jZVxuICAgKiAtIHNlY3VyaXR5Z3JvdXBcbiAgICogLSBzZXJ2ZXJsZXNzY2FjaGVcbiAgICogLSBzZXJ2ZXJsZXNzY2FjaGVzbmFwc2hvdFxuICAgKiAtIHNuYXBzaG90XG4gICAqIC0gc3VibmV0Z3JvdXBcbiAgICogLSB1c2VyXG4gICAqIC0gdXNlcmdyb3VwXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXF1ZXN0VGFnKHRhZ0tleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlJlcXVlc3RUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjdGlvbnMgYmFzZWQgb24gdGhlIHRhZ3MgYXNzb2NpYXRlZCB3aXRoIHRoZSByZXNvdXJjZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2NvbmRpdGlvbi1rZXlzLmh0bWwjY29uZGl0aW9uLWtleXMtcmVzb3VyY2V0YWdcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0FkZFRhZ3NUb1Jlc291cmNlKClcbiAgICogLSAudG9BdXRob3JpemVDYWNoZVNlY3VyaXR5R3JvdXBJbmdyZXNzKClcbiAgICogLSAudG9CYXRjaEFwcGx5VXBkYXRlQWN0aW9uKClcbiAgICogLSAudG9CYXRjaFN0b3BVcGRhdGVBY3Rpb24oKVxuICAgKiAtIC50b0NvbXBsZXRlTWlncmF0aW9uKClcbiAgICogLSAudG9Db25uZWN0KClcbiAgICogLSAudG9Db3B5U2VydmVybGVzc0NhY2hlU25hcHNob3QoKVxuICAgKiAtIC50b0NvcHlTbmFwc2hvdCgpXG4gICAqIC0gLnRvQ3JlYXRlQ2FjaGVDbHVzdGVyKClcbiAgICogLSAudG9DcmVhdGVDYWNoZVBhcmFtZXRlckdyb3VwKClcbiAgICogLSAudG9DcmVhdGVDYWNoZVNlY3VyaXR5R3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZUNhY2hlU3VibmV0R3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZVNlcnZlcmxlc3NDYWNoZSgpXG4gICAqIC0gLnRvQ3JlYXRlU2VydmVybGVzc0NhY2hlU25hcHNob3QoKVxuICAgKiAtIC50b0NyZWF0ZVNuYXBzaG90KClcbiAgICogLSAudG9DcmVhdGVVc2VyKClcbiAgICogLSAudG9DcmVhdGVVc2VyR3JvdXAoKVxuICAgKiAtIC50b0RlY3JlYXNlUmVwbGljYUNvdW50KClcbiAgICogLSAudG9EZWxldGVDYWNoZUNsdXN0ZXIoKVxuICAgKiAtIC50b0RlbGV0ZUNhY2hlUGFyYW1ldGVyR3JvdXAoKVxuICAgKiAtIC50b0RlbGV0ZUNhY2hlU2VjdXJpdHlHcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlQ2FjaGVTdWJuZXRHcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlU2VydmVybGVzc0NhY2hlKClcbiAgICogLSAudG9EZWxldGVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvRGVsZXRlU25hcHNob3QoKVxuICAgKiAtIC50b0RlbGV0ZVVzZXIoKVxuICAgKiAtIC50b0RlbGV0ZVVzZXJHcm91cCgpXG4gICAqIC0gLnRvRGVzY3JpYmVDYWNoZUNsdXN0ZXJzKClcbiAgICogLSAudG9EZXNjcmliZUNhY2hlUGFyYW1ldGVyR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZUNhY2hlUGFyYW1ldGVycygpXG4gICAqIC0gLnRvRGVzY3JpYmVDYWNoZVNlY3VyaXR5R3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZUNhY2hlU3VibmV0R3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVJlc2VydmVkQ2FjaGVOb2RlcygpXG4gICAqIC0gLnRvRGVzY3JpYmVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlU2VydmVybGVzc0NhY2hlcygpXG4gICAqIC0gLnRvRGVzY3JpYmVTbmFwc2hvdHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlVXBkYXRlQWN0aW9ucygpXG4gICAqIC0gLnRvRGVzY3JpYmVVc2VyR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVVzZXJzKClcbiAgICogLSAudG9FeHBvcnRTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvSW5jcmVhc2VSZXBsaWNhQ291bnQoKVxuICAgKiAtIC50b0xpc3RBbGxvd2VkTm9kZVR5cGVNb2RpZmljYXRpb25zKClcbiAgICogLSAudG9MaXN0VGFnc0ZvclJlc291cmNlKClcbiAgICogLSAudG9Nb2RpZnlDYWNoZUNsdXN0ZXIoKVxuICAgKiAtIC50b01vZGlmeUNhY2hlUGFyYW1ldGVyR3JvdXAoKVxuICAgKiAtIC50b01vZGlmeUNhY2hlU3VibmV0R3JvdXAoKVxuICAgKiAtIC50b01vZGlmeVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b01vZGlmeVJlcGxpY2F0aW9uR3JvdXBTaGFyZENvbmZpZ3VyYXRpb24oKVxuICAgKiAtIC50b01vZGlmeVNlcnZlcmxlc3NDYWNoZSgpXG4gICAqIC0gLnRvTW9kaWZ5VXNlcigpXG4gICAqIC0gLnRvTW9kaWZ5VXNlckdyb3VwKClcbiAgICogLSAudG9QdXJjaGFzZVJlc2VydmVkQ2FjaGVOb2Rlc09mZmVyaW5nKClcbiAgICogLSAudG9SZWJvb3RDYWNoZUNsdXN0ZXIoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3NGcm9tUmVzb3VyY2UoKVxuICAgKiAtIC50b1Jlc2V0Q2FjaGVQYXJhbWV0ZXJHcm91cCgpXG4gICAqIC0gLnRvUmV2b2tlQ2FjaGVTZWN1cml0eUdyb3VwSW5ncmVzcygpXG4gICAqIC0gLnRvU3RhcnRNaWdyYXRpb24oKVxuICAgKiAtIC50b1Rlc3RGYWlsb3ZlcigpXG4gICAqIC0gLnRvVGVzdE1pZ3JhdGlvbigpXG4gICAqIC0gLnRvSW50ZXJydXB0Q2x1c3RlckF6UG93ZXIoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIGNsdXN0ZXJcbiAgICogLSBwYXJhbWV0ZXJncm91cFxuICAgKiAtIHJlcGxpY2F0aW9uZ3JvdXBcbiAgICogLSByZXNlcnZlZC1pbnN0YW5jZVxuICAgKiAtIHNlY3VyaXR5Z3JvdXBcbiAgICogLSBzZXJ2ZXJsZXNzY2FjaGVcbiAgICogLSBzZXJ2ZXJsZXNzY2FjaGVzbmFwc2hvdFxuICAgKiAtIHNuYXBzaG90XG4gICAqIC0gc3VibmV0Z3JvdXBcbiAgICogLSB1c2VyXG4gICAqIC0gdXNlcmdyb3VwXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXNvdXJjZVRhZyh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpSZXNvdXJjZVRhZy8keyB0YWdLZXkgfWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWN0aW9ucyBiYXNlZCBvbiB0aGUgdGFnIGtleXMgdGhhdCBhcmUgcGFzc2VkIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy10YWdrZXlzXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BZGRUYWdzVG9SZXNvdXJjZSgpXG4gICAqIC0gLnRvQXV0aG9yaXplQ2FjaGVTZWN1cml0eUdyb3VwSW5ncmVzcygpXG4gICAqIC0gLnRvQmF0Y2hBcHBseVVwZGF0ZUFjdGlvbigpXG4gICAqIC0gLnRvQmF0Y2hTdG9wVXBkYXRlQWN0aW9uKClcbiAgICogLSAudG9Db21wbGV0ZU1pZ3JhdGlvbigpXG4gICAqIC0gLnRvQ29ubmVjdCgpXG4gICAqIC0gLnRvQ29weVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90KClcbiAgICogLSAudG9Db3B5U25hcHNob3QoKVxuICAgKiAtIC50b0NyZWF0ZUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvQ3JlYXRlQ2FjaGVQYXJhbWV0ZXJHcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlQ2FjaGVTZWN1cml0eUdyb3VwKClcbiAgICogLSAudG9DcmVhdGVDYWNoZVN1Ym5ldEdyb3VwKClcbiAgICogLSAudG9DcmVhdGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9DcmVhdGVSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9DcmVhdGVTZXJ2ZXJsZXNzQ2FjaGUoKVxuICAgKiAtIC50b0NyZWF0ZVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90KClcbiAgICogLSAudG9DcmVhdGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvQ3JlYXRlVXNlcigpXG4gICAqIC0gLnRvQ3JlYXRlVXNlckdyb3VwKClcbiAgICogLSAudG9EZWNyZWFzZVJlcGxpY2FDb3VudCgpXG4gICAqIC0gLnRvRGVsZXRlQ2FjaGVDbHVzdGVyKClcbiAgICogLSAudG9EZWxldGVDYWNoZVBhcmFtZXRlckdyb3VwKClcbiAgICogLSAudG9EZWxldGVDYWNoZVNlY3VyaXR5R3JvdXAoKVxuICAgKiAtIC50b0RlbGV0ZUNhY2hlU3VibmV0R3JvdXAoKVxuICAgKiAtIC50b0RlbGV0ZVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0RlbGV0ZVNlcnZlcmxlc3NDYWNoZSgpXG4gICAqIC0gLnRvRGVsZXRlU2VydmVybGVzc0NhY2hlU25hcHNob3QoKVxuICAgKiAtIC50b0RlbGV0ZVNuYXBzaG90KClcbiAgICogLSAudG9EZWxldGVVc2VyKClcbiAgICogLSAudG9EZWxldGVVc2VyR3JvdXAoKVxuICAgKiAtIC50b0Rlc2NyaWJlQ2FjaGVDbHVzdGVycygpXG4gICAqIC0gLnRvRGVzY3JpYmVDYWNoZVBhcmFtZXRlckdyb3VwcygpXG4gICAqIC0gLnRvRGVzY3JpYmVDYWNoZVBhcmFtZXRlcnMoKVxuICAgKiAtIC50b0Rlc2NyaWJlQ2FjaGVTZWN1cml0eUdyb3VwcygpXG4gICAqIC0gLnRvRGVzY3JpYmVDYWNoZVN1Ym5ldEdyb3VwcygpXG4gICAqIC0gLnRvRGVzY3JpYmVSZXBsaWNhdGlvbkdyb3VwcygpXG4gICAqIC0gLnRvRGVzY3JpYmVSZXNlcnZlZENhY2hlTm9kZXMoKVxuICAgKiAtIC50b0Rlc2NyaWJlU2VydmVybGVzc0NhY2hlU25hcHNob3RzKClcbiAgICogLSAudG9EZXNjcmliZVNlcnZlcmxlc3NDYWNoZXMoKVxuICAgKiAtIC50b0Rlc2NyaWJlU25hcHNob3RzKClcbiAgICogLSAudG9EZXNjcmliZVVwZGF0ZUFjdGlvbnMoKVxuICAgKiAtIC50b0Rlc2NyaWJlVXNlckdyb3VwcygpXG4gICAqIC0gLnRvRGVzY3JpYmVVc2VycygpXG4gICAqIC0gLnRvRXhwb3J0U2VydmVybGVzc0NhY2hlU25hcHNob3QoKVxuICAgKiAtIC50b0luY3JlYXNlUmVwbGljYUNvdW50KClcbiAgICogLSAudG9MaXN0QWxsb3dlZE5vZGVUeXBlTW9kaWZpY2F0aW9ucygpXG4gICAqIC0gLnRvTGlzdFRhZ3NGb3JSZXNvdXJjZSgpXG4gICAqIC0gLnRvTW9kaWZ5Q2FjaGVDbHVzdGVyKClcbiAgICogLSAudG9Nb2RpZnlDYWNoZVBhcmFtZXRlckdyb3VwKClcbiAgICogLSAudG9Nb2RpZnlDYWNoZVN1Ym5ldEdyb3VwKClcbiAgICogLSAudG9Nb2RpZnlSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9Nb2RpZnlSZXBsaWNhdGlvbkdyb3VwU2hhcmRDb25maWd1cmF0aW9uKClcbiAgICogLSAudG9Nb2RpZnlTZXJ2ZXJsZXNzQ2FjaGUoKVxuICAgKiAtIC50b01vZGlmeVVzZXIoKVxuICAgKiAtIC50b01vZGlmeVVzZXJHcm91cCgpXG4gICAqIC0gLnRvUHVyY2hhc2VSZXNlcnZlZENhY2hlTm9kZXNPZmZlcmluZygpXG4gICAqIC0gLnRvUmVib290Q2FjaGVDbHVzdGVyKClcbiAgICogLSAudG9SZW1vdmVUYWdzRnJvbVJlc291cmNlKClcbiAgICogLSAudG9SZXNldENhY2hlUGFyYW1ldGVyR3JvdXAoKVxuICAgKiAtIC50b1Jldm9rZUNhY2hlU2VjdXJpdHlHcm91cEluZ3Jlc3MoKVxuICAgKiAtIC50b1N0YXJ0TWlncmF0aW9uKClcbiAgICogLSAudG9UZXN0RmFpbG92ZXIoKVxuICAgKiAtIC50b1Rlc3RNaWdyYXRpb24oKVxuICAgKiAtIC50b0ludGVycnVwdENsdXN0ZXJBelBvd2VyKClcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSBjbHVzdGVyXG4gICAqIC0gcGFyYW1ldGVyZ3JvdXBcbiAgICogLSByZXBsaWNhdGlvbmdyb3VwXG4gICAqIC0gcmVzZXJ2ZWQtaW5zdGFuY2VcbiAgICogLSBzZWN1cml0eWdyb3VwXG4gICAqIC0gc2VydmVybGVzc2NhY2hlXG4gICAqIC0gc2VydmVybGVzc2NhY2hlc25hcHNob3RcbiAgICogLSBzbmFwc2hvdFxuICAgKiAtIHN1Ym5ldGdyb3VwXG4gICAqIC0gdXNlclxuICAgKiAtIHVzZXJncm91cFxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkF3c1RhZ0tleXModmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpUYWdLZXlzYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIEF0UmVzdEVuY3J5cHRpb25FbmFibGVkIHBhcmFtZXRlciBwcmVzZW50IGluIHRoZSByZXF1ZXN0IG9yIGRlZmF1bHQgZmFsc2UgdmFsdWUgaWYgcGFyYW1ldGVyIGlzIG5vdCBwcmVzZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvcmVkLXVnL0lBTS5Db25kaXRpb25LZXlzLmh0bWwjSUFNLlNwZWNpZnlpbmdDb25kaXRpb25zXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BZGRUYWdzVG9SZXNvdXJjZSgpXG4gICAqIC0gLnRvQmF0Y2hBcHBseVVwZGF0ZUFjdGlvbigpXG4gICAqIC0gLnRvQmF0Y2hTdG9wVXBkYXRlQWN0aW9uKClcbiAgICogLSAudG9Db21wbGV0ZU1pZ3JhdGlvbigpXG4gICAqIC0gLnRvQ29ubmVjdCgpXG4gICAqIC0gLnRvQ3JlYXRlQ2FjaGVDbHVzdGVyKClcbiAgICogLSAudG9DcmVhdGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9DcmVhdGVSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9DcmVhdGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvRGVjcmVhc2VOb2RlR3JvdXBzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9EZWNyZWFzZVJlcGxpY2FDb3VudCgpXG4gICAqIC0gLnRvRGVsZXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVzY3JpYmVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwcygpXG4gICAqIC0gLnRvRGVzY3JpYmVSZXBsaWNhdGlvbkdyb3VwcygpXG4gICAqIC0gLnRvRGVzY3JpYmVVcGRhdGVBY3Rpb25zKClcbiAgICogLSAudG9EaXNhc3NvY2lhdGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9GYWlsb3Zlckdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0luY3JlYXNlTm9kZUdyb3Vwc0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvSW5jcmVhc2VSZXBsaWNhQ291bnQoKVxuICAgKiAtIC50b0xpc3RBbGxvd2VkTm9kZVR5cGVNb2RpZmljYXRpb25zKClcbiAgICogLSAudG9MaXN0VGFnc0ZvclJlc291cmNlKClcbiAgICogLSAudG9Nb2RpZnlHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9Nb2RpZnlSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9Nb2RpZnlSZXBsaWNhdGlvbkdyb3VwU2hhcmRDb25maWd1cmF0aW9uKClcbiAgICogLSAudG9SZWJhbGFuY2VTbG90c0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvUmVtb3ZlVGFnc0Zyb21SZXNvdXJjZSgpXG4gICAqIC0gLnRvU3RhcnRNaWdyYXRpb24oKVxuICAgKiAtIC50b1Rlc3RGYWlsb3ZlcigpXG4gICAqIC0gLnRvVGVzdE1pZ3JhdGlvbigpXG4gICAqIC0gLnRvSW50ZXJydXB0Q2x1c3RlckF6UG93ZXIoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIGdsb2JhbHJlcGxpY2F0aW9uZ3JvdXBcbiAgICogLSByZXBsaWNhdGlvbmdyb3VwXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBgdHJ1ZWAgb3IgYGZhbHNlYC4gKipEZWZhdWx0OioqIGB0cnVlYFxuICAgKi9cbiAgcHVibGljIGlmQXRSZXN0RW5jcnlwdGlvbkVuYWJsZWQodmFsdWU/OiBib29sZWFuKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYEF0UmVzdEVuY3J5cHRpb25FbmFibGVkYCwgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcgPyB2YWx1ZSA6IHRydWUpLCAnQm9vbCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBwcmVzZW5jZSBvZiBub24gZW1wdHkgQXV0aFRva2VuIHBhcmFtZXRlciBpbiB0aGUgcmVxdWVzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L3JlZC11Zy9JQU0uQ29uZGl0aW9uS2V5cy5odG1sI0lBTS5TcGVjaWZ5aW5nQ29uZGl0aW9uc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFnc1RvUmVzb3VyY2UoKVxuICAgKiAtIC50b0JhdGNoQXBwbHlVcGRhdGVBY3Rpb24oKVxuICAgKiAtIC50b0JhdGNoU3RvcFVwZGF0ZUFjdGlvbigpXG4gICAqIC0gLnRvQ29tcGxldGVNaWdyYXRpb24oKVxuICAgKiAtIC50b0Nvbm5lY3QoKVxuICAgKiAtIC50b0NyZWF0ZUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvQ3JlYXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlU25hcHNob3QoKVxuICAgKiAtIC50b0RlY3JlYXNlTm9kZUdyb3Vwc0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVjcmVhc2VSZXBsaWNhQ291bnQoKVxuICAgKiAtIC50b0RlbGV0ZUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvRGVsZXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVzY3JpYmVDYWNoZUNsdXN0ZXJzKClcbiAgICogLSAudG9EZXNjcmliZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVVwZGF0ZUFjdGlvbnMoKVxuICAgKiAtIC50b0Rpc2Fzc29jaWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0ZhaWxvdmVyR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvSW5jcmVhc2VOb2RlR3JvdXBzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9JbmNyZWFzZVJlcGxpY2FDb3VudCgpXG4gICAqIC0gLnRvTGlzdEFsbG93ZWROb2RlVHlwZU1vZGlmaWNhdGlvbnMoKVxuICAgKiAtIC50b0xpc3RUYWdzRm9yUmVzb3VyY2UoKVxuICAgKiAtIC50b01vZGlmeUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvTW9kaWZ5R2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cFNoYXJkQ29uZmlndXJhdGlvbigpXG4gICAqIC0gLnRvUmViYWxhbmNlU2xvdHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b1JlYm9vdENhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvUmVtb3ZlVGFnc0Zyb21SZXNvdXJjZSgpXG4gICAqIC0gLnRvU3RhcnRNaWdyYXRpb24oKVxuICAgKiAtIC50b1Rlc3RGYWlsb3ZlcigpXG4gICAqIC0gLnRvVGVzdE1pZ3JhdGlvbigpXG4gICAqIC0gLnRvSW50ZXJydXB0Q2x1c3RlckF6UG93ZXIoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIGNsdXN0ZXJcbiAgICogLSBnbG9iYWxyZXBsaWNhdGlvbmdyb3VwXG4gICAqIC0gcmVwbGljYXRpb25ncm91cFxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIG9yIGBmYWxzZWAuICoqRGVmYXVsdDoqKiBgdHJ1ZWBcbiAgICovXG4gIHB1YmxpYyBpZkF1dGhUb2tlbkVuYWJsZWQodmFsdWU/OiBib29sZWFuKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYEF1dGhUb2tlbkVuYWJsZWRgLCAodHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJyA/IHZhbHVlIDogdHJ1ZSksICdCb29sJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIEF1dG9tYXRpY0ZhaWxvdmVyRW5hYmxlZCBwYXJhbWV0ZXIgaW4gdGhlIHJlcXVlc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9yZWQtdWcvSUFNLkNvbmRpdGlvbktleXMuaHRtbCNJQU0uU3BlY2lmeWluZ0NvbmRpdGlvbnNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0FkZFRhZ3NUb1Jlc291cmNlKClcbiAgICogLSAudG9CYXRjaEFwcGx5VXBkYXRlQWN0aW9uKClcbiAgICogLSAudG9CYXRjaFN0b3BVcGRhdGVBY3Rpb24oKVxuICAgKiAtIC50b0NvbXBsZXRlTWlncmF0aW9uKClcbiAgICogLSAudG9Db25uZWN0KClcbiAgICogLSAudG9DcmVhdGVDYWNoZUNsdXN0ZXIoKVxuICAgKiAtIC50b0NyZWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZVNuYXBzaG90KClcbiAgICogLSAudG9EZWNyZWFzZU5vZGVHcm91cHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0RlY3JlYXNlUmVwbGljYUNvdW50KClcbiAgICogLSAudG9EZWxldGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9EZWxldGVSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9EZXNjcmliZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVVwZGF0ZUFjdGlvbnMoKVxuICAgKiAtIC50b0Rpc2Fzc29jaWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0ZhaWxvdmVyR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvSW5jcmVhc2VOb2RlR3JvdXBzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9JbmNyZWFzZVJlcGxpY2FDb3VudCgpXG4gICAqIC0gLnRvTGlzdEFsbG93ZWROb2RlVHlwZU1vZGlmaWNhdGlvbnMoKVxuICAgKiAtIC50b0xpc3RUYWdzRm9yUmVzb3VyY2UoKVxuICAgKiAtIC50b01vZGlmeUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b01vZGlmeVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b01vZGlmeVJlcGxpY2F0aW9uR3JvdXBTaGFyZENvbmZpZ3VyYXRpb24oKVxuICAgKiAtIC50b1JlYmFsYW5jZVNsb3RzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9SZW1vdmVUYWdzRnJvbVJlc291cmNlKClcbiAgICogLSAudG9TdGFydE1pZ3JhdGlvbigpXG4gICAqIC0gLnRvVGVzdEZhaWxvdmVyKClcbiAgICogLSAudG9UZXN0TWlncmF0aW9uKClcbiAgICogLSAudG9JbnRlcnJ1cHRDbHVzdGVyQXpQb3dlcigpXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gcmVzb3VyY2UgdHlwZXM6XG4gICAqIC0gZ2xvYmFscmVwbGljYXRpb25ncm91cFxuICAgKiAtIHJlcGxpY2F0aW9uZ3JvdXBcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgLiAqKkRlZmF1bHQ6KiogYHRydWVgXG4gICAqL1xuICBwdWJsaWMgaWZBdXRvbWF0aWNGYWlsb3ZlckVuYWJsZWQodmFsdWU/OiBib29sZWFuKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYEF1dG9tYXRpY0ZhaWxvdmVyRW5hYmxlZGAsICh0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnID8gdmFsdWUgOiB0cnVlKSwgJ0Jvb2wnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgY2FjaGVOb2RlVHlwZSBwYXJhbWV0ZXIgcHJlc2VudCBpbiB0aGUgcmVxdWVzdC4gVGhpcyBrZXkgY2FuIGJlIHVzZWQgdG8gcmVzdHJpY3Qgd2hpY2ggY2FjaGUgbm9kZSB0eXBlcyBjYW4gYmUgdXNlZCBvbiBjbHVzdGVyIGNyZWF0aW9uIG9yIHNjYWxpbmcgb3BlcmF0aW9uc1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L3JlZC11Zy9JQU0uQ29uZGl0aW9uS2V5cy5odG1sI0lBTS5TcGVjaWZ5aW5nQ29uZGl0aW9uc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFnc1RvUmVzb3VyY2UoKVxuICAgKiAtIC50b0JhdGNoQXBwbHlVcGRhdGVBY3Rpb24oKVxuICAgKiAtIC50b0JhdGNoU3RvcFVwZGF0ZUFjdGlvbigpXG4gICAqIC0gLnRvQ29tcGxldGVNaWdyYXRpb24oKVxuICAgKiAtIC50b0Nvbm5lY3QoKVxuICAgKiAtIC50b0NyZWF0ZUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvQ3JlYXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlU25hcHNob3QoKVxuICAgKiAtIC50b0RlY3JlYXNlTm9kZUdyb3Vwc0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVjcmVhc2VSZXBsaWNhQ291bnQoKVxuICAgKiAtIC50b0RlbGV0ZUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvRGVsZXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVzY3JpYmVDYWNoZUNsdXN0ZXJzKClcbiAgICogLSAudG9EZXNjcmliZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVVwZGF0ZUFjdGlvbnMoKVxuICAgKiAtIC50b0Rpc2Fzc29jaWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0ZhaWxvdmVyR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvSW5jcmVhc2VOb2RlR3JvdXBzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9JbmNyZWFzZVJlcGxpY2FDb3VudCgpXG4gICAqIC0gLnRvTGlzdEFsbG93ZWROb2RlVHlwZU1vZGlmaWNhdGlvbnMoKVxuICAgKiAtIC50b0xpc3RUYWdzRm9yUmVzb3VyY2UoKVxuICAgKiAtIC50b01vZGlmeUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvTW9kaWZ5R2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cFNoYXJkQ29uZmlndXJhdGlvbigpXG4gICAqIC0gLnRvUmViYWxhbmNlU2xvdHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b1JlYm9vdENhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvUmVtb3ZlVGFnc0Zyb21SZXNvdXJjZSgpXG4gICAqIC0gLnRvU3RhcnRNaWdyYXRpb24oKVxuICAgKiAtIC50b1Rlc3RGYWlsb3ZlcigpXG4gICAqIC0gLnRvVGVzdE1pZ3JhdGlvbigpXG4gICAqIC0gLnRvSW50ZXJydXB0Q2x1c3RlckF6UG93ZXIoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIGNsdXN0ZXJcbiAgICogLSBnbG9iYWxyZXBsaWNhdGlvbmdyb3VwXG4gICAqIC0gcmVwbGljYXRpb25ncm91cFxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkNhY2hlTm9kZVR5cGUodmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYENhY2hlTm9kZVR5cGVgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgQ2FjaGVQYXJhbWV0ZXJHcm91cE5hbWUgcGFyYW1ldGVyIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvcmVkLXVnL0lBTS5Db25kaXRpb25LZXlzLmh0bWwjSUFNLlNwZWNpZnlpbmdDb25kaXRpb25zXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BZGRUYWdzVG9SZXNvdXJjZSgpXG4gICAqIC0gLnRvQmF0Y2hBcHBseVVwZGF0ZUFjdGlvbigpXG4gICAqIC0gLnRvQmF0Y2hTdG9wVXBkYXRlQWN0aW9uKClcbiAgICogLSAudG9Db21wbGV0ZU1pZ3JhdGlvbigpXG4gICAqIC0gLnRvQ29ubmVjdCgpXG4gICAqIC0gLnRvQ3JlYXRlQ2FjaGVDbHVzdGVyKClcbiAgICogLSAudG9DcmVhdGVDYWNoZVBhcmFtZXRlckdyb3VwKClcbiAgICogLSAudG9DcmVhdGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9DcmVhdGVSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9DcmVhdGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvRGVjcmVhc2VOb2RlR3JvdXBzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9EZWNyZWFzZVJlcGxpY2FDb3VudCgpXG4gICAqIC0gLnRvRGVsZXRlQ2FjaGVDbHVzdGVyKClcbiAgICogLSAudG9EZWxldGVDYWNoZVBhcmFtZXRlckdyb3VwKClcbiAgICogLSAudG9EZWxldGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9EZWxldGVSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9EZXNjcmliZUNhY2hlQ2x1c3RlcnMoKVxuICAgKiAtIC50b0Rlc2NyaWJlQ2FjaGVQYXJhbWV0ZXJHcm91cHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlQ2FjaGVQYXJhbWV0ZXJzKClcbiAgICogLSAudG9EZXNjcmliZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVVwZGF0ZUFjdGlvbnMoKVxuICAgKiAtIC50b0Rpc2Fzc29jaWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0ZhaWxvdmVyR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvSW5jcmVhc2VOb2RlR3JvdXBzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9JbmNyZWFzZVJlcGxpY2FDb3VudCgpXG4gICAqIC0gLnRvTGlzdEFsbG93ZWROb2RlVHlwZU1vZGlmaWNhdGlvbnMoKVxuICAgKiAtIC50b0xpc3RUYWdzRm9yUmVzb3VyY2UoKVxuICAgKiAtIC50b01vZGlmeUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvTW9kaWZ5Q2FjaGVQYXJhbWV0ZXJHcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5R2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cFNoYXJkQ29uZmlndXJhdGlvbigpXG4gICAqIC0gLnRvUmViYWxhbmNlU2xvdHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b1JlYm9vdENhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvUmVtb3ZlVGFnc0Zyb21SZXNvdXJjZSgpXG4gICAqIC0gLnRvUmVzZXRDYWNoZVBhcmFtZXRlckdyb3VwKClcbiAgICogLSAudG9TdGFydE1pZ3JhdGlvbigpXG4gICAqIC0gLnRvVGVzdEZhaWxvdmVyKClcbiAgICogLSAudG9UZXN0TWlncmF0aW9uKClcbiAgICogLSAudG9JbnRlcnJ1cHRDbHVzdGVyQXpQb3dlcigpXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gcmVzb3VyY2UgdHlwZXM6XG4gICAqIC0gY2x1c3RlclxuICAgKiAtIGdsb2JhbHJlcGxpY2F0aW9uZ3JvdXBcbiAgICogLSBwYXJhbWV0ZXJncm91cFxuICAgKiAtIHJlcGxpY2F0aW9uZ3JvdXBcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZDYWNoZVBhcmFtZXRlckdyb3VwTmFtZSh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgQ2FjaGVQYXJhbWV0ZXJHcm91cE5hbWVgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgY2x1c3RlciBtb2RlIHBhcmFtZXRlciBwcmVzZW50IGluIHRoZSByZXF1ZXN0LiBEZWZhdWx0IHZhbHVlIGZvciBzaW5nbGUgbm9kZSBncm91cCAoc2hhcmQpIGNyZWF0aW9ucyBpcyBmYWxzZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L3JlZC11Zy9JQU0uQ29uZGl0aW9uS2V5cy5odG1sI0lBTS5TcGVjaWZ5aW5nQ29uZGl0aW9uc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFnc1RvUmVzb3VyY2UoKVxuICAgKiAtIC50b0JhdGNoQXBwbHlVcGRhdGVBY3Rpb24oKVxuICAgKiAtIC50b0JhdGNoU3RvcFVwZGF0ZUFjdGlvbigpXG4gICAqIC0gLnRvQ29tcGxldGVNaWdyYXRpb24oKVxuICAgKiAtIC50b0Nvbm5lY3QoKVxuICAgKiAtIC50b0NyZWF0ZUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvQ3JlYXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlU25hcHNob3QoKVxuICAgKiAtIC50b0RlY3JlYXNlTm9kZUdyb3Vwc0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVjcmVhc2VSZXBsaWNhQ291bnQoKVxuICAgKiAtIC50b0RlbGV0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0RlbGV0ZVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0Rlc2NyaWJlR2xvYmFsUmVwbGljYXRpb25Hcm91cHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlUmVwbGljYXRpb25Hcm91cHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlVXBkYXRlQWN0aW9ucygpXG4gICAqIC0gLnRvRGlzYXNzb2NpYXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRmFpbG92ZXJHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9JbmNyZWFzZU5vZGVHcm91cHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0luY3JlYXNlUmVwbGljYUNvdW50KClcbiAgICogLSAudG9MaXN0QWxsb3dlZE5vZGVUeXBlTW9kaWZpY2F0aW9ucygpXG4gICAqIC0gLnRvTGlzdFRhZ3NGb3JSZXNvdXJjZSgpXG4gICAqIC0gLnRvTW9kaWZ5R2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cFNoYXJkQ29uZmlndXJhdGlvbigpXG4gICAqIC0gLnRvUmViYWxhbmNlU2xvdHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3NGcm9tUmVzb3VyY2UoKVxuICAgKiAtIC50b1N0YXJ0TWlncmF0aW9uKClcbiAgICogLSAudG9UZXN0RmFpbG92ZXIoKVxuICAgKiAtIC50b1Rlc3RNaWdyYXRpb24oKVxuICAgKiAtIC50b0ludGVycnVwdENsdXN0ZXJBelBvd2VyKClcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSBnbG9iYWxyZXBsaWNhdGlvbmdyb3VwXG4gICAqIC0gcmVwbGljYXRpb25ncm91cFxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIG9yIGBmYWxzZWAuICoqRGVmYXVsdDoqKiBgdHJ1ZWBcbiAgICovXG4gIHB1YmxpYyBpZkNsdXN0ZXJNb2RlRW5hYmxlZCh2YWx1ZT86IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gdGhpcy5pZihgQ2x1c3Rlck1vZGVFbmFibGVkYCwgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcgPyB2YWx1ZSA6IHRydWUpLCAnQm9vbCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBDYWNoZVVzYWdlTGltaXRzLkRhdGFTdG9yYWdlLlVuaXQgcGFyYW1ldGVyIGluIHRoZSBDcmVhdGVTZXJ2ZXJsZXNzQ2FjaGUgYW5kIE1vZGlmeVNlcnZlcmxlc3NDYWNoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvcmVkLXVnL0lBTS5Db25kaXRpb25LZXlzLmh0bWwjSUFNLlNwZWNpZnlpbmdDb25kaXRpb25zXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BZGRUYWdzVG9SZXNvdXJjZSgpXG4gICAqIC0gLnRvQ29ubmVjdCgpXG4gICAqIC0gLnRvQ3JlYXRlU2VydmVybGVzc0NhY2hlKClcbiAgICogLSAudG9DcmVhdGVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvRGVsZXRlU2VydmVybGVzc0NhY2hlKClcbiAgICogLSAudG9EZXNjcmliZVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90cygpXG4gICAqIC0gLnRvRGVzY3JpYmVTZXJ2ZXJsZXNzQ2FjaGVzKClcbiAgICogLSAudG9MaXN0VGFnc0ZvclJlc291cmNlKClcbiAgICogLSAudG9Nb2RpZnlTZXJ2ZXJsZXNzQ2FjaGUoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3NGcm9tUmVzb3VyY2UoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIHNlcnZlcmxlc3NjYWNoZVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkRhdGFTdG9yYWdlVW5pdCh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgRGF0YVN0b3JhZ2VVbml0YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIER1cmFiaWxpdHkgcGFyYW1ldGVyIGluIHRoZSByZXF1ZXN0LiBWYWxpZCB2YWx1ZXMgYXJlIGRlZmF1bHQsIGFzeW5jLCBzeW5jLCBvciBkaXNhYmxlZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L3JlZC11Zy9JQU0uQ29uZGl0aW9uS2V5cy5odG1sI0lBTS5TcGVjaWZ5aW5nQ29uZGl0aW9uc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFnc1RvUmVzb3VyY2UoKVxuICAgKiAtIC50b0JhdGNoQXBwbHlVcGRhdGVBY3Rpb24oKVxuICAgKiAtIC50b0JhdGNoU3RvcFVwZGF0ZUFjdGlvbigpXG4gICAqIC0gLnRvQ29tcGxldGVNaWdyYXRpb24oKVxuICAgKiAtIC50b0Nvbm5lY3QoKVxuICAgKiAtIC50b0NyZWF0ZUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvQ3JlYXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlU25hcHNob3QoKVxuICAgKiAtIC50b0RlY3JlYXNlUmVwbGljYUNvdW50KClcbiAgICogLSAudG9EZWxldGVSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9EZXNjcmliZVJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVVwZGF0ZUFjdGlvbnMoKVxuICAgKiAtIC50b0luY3JlYXNlUmVwbGljYUNvdW50KClcbiAgICogLSAudG9MaXN0QWxsb3dlZE5vZGVUeXBlTW9kaWZpY2F0aW9ucygpXG4gICAqIC0gLnRvTGlzdFRhZ3NGb3JSZXNvdXJjZSgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cFNoYXJkQ29uZmlndXJhdGlvbigpXG4gICAqIC0gLnRvUmVtb3ZlVGFnc0Zyb21SZXNvdXJjZSgpXG4gICAqIC0gLnRvU3RhcnRNaWdyYXRpb24oKVxuICAgKiAtIC50b1Rlc3RGYWlsb3ZlcigpXG4gICAqIC0gLnRvVGVzdE1pZ3JhdGlvbigpXG4gICAqIC0gLnRvSW50ZXJydXB0Q2x1c3RlckF6UG93ZXIoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIHJlcGxpY2F0aW9uZ3JvdXBcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZEdXJhYmlsaXR5KHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBEdXJhYmlsaXR5YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIGVuZ2luZSB0eXBlIHByZXNlbnQgaW4gY3JlYXRpb24gcmVxdWVzdHMuIEZvciByZXBsaWNhdGlvbiBncm91cCBjcmVhdGlvbnMsIGRlZmF1bHQgZW5naW5lICdyZWRpcycgaXMgdXNlZCBhcyBrZXkgaWYgcGFyYW1ldGVyIGlzIG5vdCBwcmVzZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvcmVkLXVnL0lBTS5Db25kaXRpb25LZXlzLmh0bWwjSUFNLlNwZWNpZnlpbmdDb25kaXRpb25zXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BZGRUYWdzVG9SZXNvdXJjZSgpXG4gICAqIC0gLnRvQmF0Y2hBcHBseVVwZGF0ZUFjdGlvbigpXG4gICAqIC0gLnRvQmF0Y2hTdG9wVXBkYXRlQWN0aW9uKClcbiAgICogLSAudG9Db21wbGV0ZU1pZ3JhdGlvbigpXG4gICAqIC0gLnRvQ29ubmVjdCgpXG4gICAqIC0gLnRvQ3JlYXRlQ2FjaGVDbHVzdGVyKClcbiAgICogLSAudG9DcmVhdGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9DcmVhdGVSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9DcmVhdGVTZXJ2ZXJsZXNzQ2FjaGUoKVxuICAgKiAtIC50b0NyZWF0ZVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90KClcbiAgICogLSAudG9DcmVhdGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvRGVjcmVhc2VOb2RlR3JvdXBzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9EZWNyZWFzZVJlcGxpY2FDb3VudCgpXG4gICAqIC0gLnRvRGVsZXRlQ2FjaGVDbHVzdGVyKClcbiAgICogLSAudG9EZWxldGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9EZWxldGVSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9EZWxldGVTZXJ2ZXJsZXNzQ2FjaGUoKVxuICAgKiAtIC50b0Rlc2NyaWJlQ2FjaGVDbHVzdGVycygpXG4gICAqIC0gLnRvRGVzY3JpYmVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwcygpXG4gICAqIC0gLnRvRGVzY3JpYmVSZXBsaWNhdGlvbkdyb3VwcygpXG4gICAqIC0gLnRvRGVzY3JpYmVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlU2VydmVybGVzc0NhY2hlcygpXG4gICAqIC0gLnRvRGVzY3JpYmVVcGRhdGVBY3Rpb25zKClcbiAgICogLSAudG9EaXNhc3NvY2lhdGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9GYWlsb3Zlckdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0luY3JlYXNlTm9kZUdyb3Vwc0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvSW5jcmVhc2VSZXBsaWNhQ291bnQoKVxuICAgKiAtIC50b0xpc3RBbGxvd2VkTm9kZVR5cGVNb2RpZmljYXRpb25zKClcbiAgICogLSAudG9MaXN0VGFnc0ZvclJlc291cmNlKClcbiAgICogLSAudG9Nb2RpZnlDYWNoZUNsdXN0ZXIoKVxuICAgKiAtIC50b01vZGlmeUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b01vZGlmeVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b01vZGlmeVJlcGxpY2F0aW9uR3JvdXBTaGFyZENvbmZpZ3VyYXRpb24oKVxuICAgKiAtIC50b01vZGlmeVNlcnZlcmxlc3NDYWNoZSgpXG4gICAqIC0gLnRvUmViYWxhbmNlU2xvdHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b1JlYm9vdENhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvUmVtb3ZlVGFnc0Zyb21SZXNvdXJjZSgpXG4gICAqIC0gLnRvU3RhcnRNaWdyYXRpb24oKVxuICAgKiAtIC50b1Rlc3RGYWlsb3ZlcigpXG4gICAqIC0gLnRvVGVzdE1pZ3JhdGlvbigpXG4gICAqIC0gLnRvSW50ZXJydXB0Q2x1c3RlckF6UG93ZXIoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIGNsdXN0ZXJcbiAgICogLSBnbG9iYWxyZXBsaWNhdGlvbmdyb3VwXG4gICAqIC0gcmVwbGljYXRpb25ncm91cFxuICAgKiAtIHNlcnZlcmxlc3NjYWNoZVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkVuZ2luZVR5cGUodmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYEVuZ2luZVR5cGVgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgZW5naW5lVmVyc2lvbiBwYXJhbWV0ZXIgcHJlc2VudCBpbiBjcmVhdGlvbiBvciBjbHVzdGVyIG1vZGlmaWNhdGlvbiByZXF1ZXN0c1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L3JlZC11Zy9JQU0uQ29uZGl0aW9uS2V5cy5odG1sI0lBTS5TcGVjaWZ5aW5nQ29uZGl0aW9uc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFnc1RvUmVzb3VyY2UoKVxuICAgKiAtIC50b0JhdGNoQXBwbHlVcGRhdGVBY3Rpb24oKVxuICAgKiAtIC50b0JhdGNoU3RvcFVwZGF0ZUFjdGlvbigpXG4gICAqIC0gLnRvQ29tcGxldGVNaWdyYXRpb24oKVxuICAgKiAtIC50b0Nvbm5lY3QoKVxuICAgKiAtIC50b0NyZWF0ZUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvQ3JlYXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlU2VydmVybGVzc0NhY2hlKClcbiAgICogLSAudG9DcmVhdGVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvQ3JlYXRlU25hcHNob3QoKVxuICAgKiAtIC50b0RlY3JlYXNlTm9kZUdyb3Vwc0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVjcmVhc2VSZXBsaWNhQ291bnQoKVxuICAgKiAtIC50b0RlbGV0ZUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvRGVsZXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlU2VydmVybGVzc0NhY2hlKClcbiAgICogLSAudG9EZXNjcmliZUNhY2hlQ2x1c3RlcnMoKVxuICAgKiAtIC50b0Rlc2NyaWJlR2xvYmFsUmVwbGljYXRpb25Hcm91cHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlUmVwbGljYXRpb25Hcm91cHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlU2VydmVybGVzc0NhY2hlU25hcHNob3RzKClcbiAgICogLSAudG9EZXNjcmliZVNlcnZlcmxlc3NDYWNoZXMoKVxuICAgKiAtIC50b0Rlc2NyaWJlVXBkYXRlQWN0aW9ucygpXG4gICAqIC0gLnRvRGlzYXNzb2NpYXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRmFpbG92ZXJHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9JbmNyZWFzZU5vZGVHcm91cHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0luY3JlYXNlUmVwbGljYUNvdW50KClcbiAgICogLSAudG9MaXN0QWxsb3dlZE5vZGVUeXBlTW9kaWZpY2F0aW9ucygpXG4gICAqIC0gLnRvTGlzdFRhZ3NGb3JSZXNvdXJjZSgpXG4gICAqIC0gLnRvTW9kaWZ5Q2FjaGVDbHVzdGVyKClcbiAgICogLSAudG9Nb2RpZnlHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9Nb2RpZnlSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9Nb2RpZnlSZXBsaWNhdGlvbkdyb3VwU2hhcmRDb25maWd1cmF0aW9uKClcbiAgICogLSAudG9Nb2RpZnlTZXJ2ZXJsZXNzQ2FjaGUoKVxuICAgKiAtIC50b1JlYmFsYW5jZVNsb3RzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9SZWJvb3RDYWNoZUNsdXN0ZXIoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3NGcm9tUmVzb3VyY2UoKVxuICAgKiAtIC50b1N0YXJ0TWlncmF0aW9uKClcbiAgICogLSAudG9UZXN0RmFpbG92ZXIoKVxuICAgKiAtIC50b1Rlc3RNaWdyYXRpb24oKVxuICAgKiAtIC50b0ludGVycnVwdENsdXN0ZXJBelBvd2VyKClcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSBjbHVzdGVyXG4gICAqIC0gZ2xvYmFscmVwbGljYXRpb25ncm91cFxuICAgKiAtIHJlcGxpY2F0aW9uZ3JvdXBcbiAgICogLSBzZXJ2ZXJsZXNzY2FjaGVcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZFbmdpbmVWZXJzaW9uKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBFbmdpbmVWZXJzaW9uYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIEtleSBJRCBvZiB0aGUgS01TIGtleVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L3JlZC11Zy9JQU0uQ29uZGl0aW9uS2V5cy5odG1sI0lBTS5TcGVjaWZ5aW5nQ29uZGl0aW9uc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFnc1RvUmVzb3VyY2UoKVxuICAgKiAtIC50b0JhdGNoQXBwbHlVcGRhdGVBY3Rpb24oKVxuICAgKiAtIC50b0JhdGNoU3RvcFVwZGF0ZUFjdGlvbigpXG4gICAqIC0gLnRvQ29tcGxldGVNaWdyYXRpb24oKVxuICAgKiAtIC50b0Nvbm5lY3QoKVxuICAgKiAtIC50b0NvcHlTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvQ29weVNuYXBzaG90KClcbiAgICogLSAudG9DcmVhdGVDYWNoZUNsdXN0ZXIoKVxuICAgKiAtIC50b0NyZWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZVNlcnZlcmxlc3NDYWNoZSgpXG4gICAqIC0gLnRvQ3JlYXRlU2VydmVybGVzc0NhY2hlU25hcHNob3QoKVxuICAgKiAtIC50b0NyZWF0ZVNuYXBzaG90KClcbiAgICogLSAudG9EZWNyZWFzZU5vZGVHcm91cHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0RlY3JlYXNlUmVwbGljYUNvdW50KClcbiAgICogLSAudG9EZWxldGVDYWNoZUNsdXN0ZXIoKVxuICAgKiAtIC50b0RlbGV0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0RlbGV0ZVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0RlbGV0ZVNlcnZlcmxlc3NDYWNoZSgpXG4gICAqIC0gLnRvRGVsZXRlU2VydmVybGVzc0NhY2hlU25hcHNob3QoKVxuICAgKiAtIC50b0RlbGV0ZVNuYXBzaG90KClcbiAgICogLSAudG9EZXNjcmliZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90cygpXG4gICAqIC0gLnRvRGVzY3JpYmVTZXJ2ZXJsZXNzQ2FjaGVzKClcbiAgICogLSAudG9EZXNjcmliZVNuYXBzaG90cygpXG4gICAqIC0gLnRvRGVzY3JpYmVVcGRhdGVBY3Rpb25zKClcbiAgICogLSAudG9EaXNhc3NvY2lhdGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9FeHBvcnRTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvRmFpbG92ZXJHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9JbmNyZWFzZU5vZGVHcm91cHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0luY3JlYXNlUmVwbGljYUNvdW50KClcbiAgICogLSAudG9MaXN0QWxsb3dlZE5vZGVUeXBlTW9kaWZpY2F0aW9ucygpXG4gICAqIC0gLnRvTGlzdFRhZ3NGb3JSZXNvdXJjZSgpXG4gICAqIC0gLnRvTW9kaWZ5R2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cFNoYXJkQ29uZmlndXJhdGlvbigpXG4gICAqIC0gLnRvTW9kaWZ5U2VydmVybGVzc0NhY2hlKClcbiAgICogLSAudG9SZWJhbGFuY2VTbG90c0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvUmVtb3ZlVGFnc0Zyb21SZXNvdXJjZSgpXG4gICAqIC0gLnRvU3RhcnRNaWdyYXRpb24oKVxuICAgKiAtIC50b1Rlc3RGYWlsb3ZlcigpXG4gICAqIC0gLnRvVGVzdE1pZ3JhdGlvbigpXG4gICAqIC0gLnRvSW50ZXJydXB0Q2x1c3RlckF6UG93ZXIoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIGdsb2JhbHJlcGxpY2F0aW9uZ3JvdXBcbiAgICogLSByZXBsaWNhdGlvbmdyb3VwXG4gICAqIC0gc2VydmVybGVzc2NhY2hlXG4gICAqIC0gc2VydmVybGVzc2NhY2hlc25hcHNob3RcbiAgICogLSBzbmFwc2hvdFxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkttc0tleUlkKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBLbXNLZXlJZGAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBDYWNoZVVzYWdlTGltaXRzLkRhdGFTdG9yYWdlLk1heGltdW0gcGFyYW1ldGVyIGluIHRoZSBDcmVhdGVTZXJ2ZXJsZXNzQ2FjaGUgYW5kIE1vZGlmeVNlcnZlcmxlc3NDYWNoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvcmVkLXVnL0lBTS5Db25kaXRpb25LZXlzLmh0bWwjSUFNLlNwZWNpZnlpbmdDb25kaXRpb25zXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BZGRUYWdzVG9SZXNvdXJjZSgpXG4gICAqIC0gLnRvQ29ubmVjdCgpXG4gICAqIC0gLnRvQ3JlYXRlU2VydmVybGVzc0NhY2hlKClcbiAgICogLSAudG9DcmVhdGVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvRGVsZXRlU2VydmVybGVzc0NhY2hlKClcbiAgICogLSAudG9EZXNjcmliZVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90cygpXG4gICAqIC0gLnRvRGVzY3JpYmVTZXJ2ZXJsZXNzQ2FjaGVzKClcbiAgICogLSAudG9MaXN0VGFnc0ZvclJlc291cmNlKClcbiAgICogLSAudG9Nb2RpZnlTZXJ2ZXJsZXNzQ2FjaGUoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3NGcm9tUmVzb3VyY2UoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIHNlcnZlcmxlc3NjYWNoZVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtudW1lcmljIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19OdW1lcmljKS4gKipEZWZhdWx0OioqIGBOdW1lcmljRXF1YWxzYFxuICAgKi9cbiAgcHVibGljIGlmTWF4aW11bURhdGFTdG9yYWdlKHZhbHVlOiBudW1iZXIgfCBudW1iZXJbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBNYXhpbXVtRGF0YVN0b3JhZ2VgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ051bWVyaWNFcXVhbHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgQ2FjaGVVc2FnZUxpbWl0cy5FQ1BVUGVyU2Vjb25kLk1heGltdW0gcGFyYW1ldGVyIGluIHRoZSBDcmVhdGVTZXJ2ZXJsZXNzQ2FjaGUgYW5kIE1vZGlmeVNlcnZlcmxlc3NDYWNoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvcmVkLXVnL0lBTS5Db25kaXRpb25LZXlzLmh0bWwjSUFNLlNwZWNpZnlpbmdDb25kaXRpb25zXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BZGRUYWdzVG9SZXNvdXJjZSgpXG4gICAqIC0gLnRvQ29ubmVjdCgpXG4gICAqIC0gLnRvQ3JlYXRlU2VydmVybGVzc0NhY2hlKClcbiAgICogLSAudG9DcmVhdGVTZXJ2ZXJsZXNzQ2FjaGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvRGVsZXRlU2VydmVybGVzc0NhY2hlKClcbiAgICogLSAudG9EZXNjcmliZVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90cygpXG4gICAqIC0gLnRvRGVzY3JpYmVTZXJ2ZXJsZXNzQ2FjaGVzKClcbiAgICogLSAudG9MaXN0VGFnc0ZvclJlc291cmNlKClcbiAgICogLSAudG9Nb2RpZnlTZXJ2ZXJsZXNzQ2FjaGUoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3NGcm9tUmVzb3VyY2UoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIHNlcnZlcmxlc3NjYWNoZVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtudW1lcmljIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19OdW1lcmljKS4gKipEZWZhdWx0OioqIGBOdW1lcmljRXF1YWxzYFxuICAgKi9cbiAgcHVibGljIGlmTWF4aW11bUVDUFVQZXJTZWNvbmQodmFsdWU6IG51bWJlciB8IG51bWJlcltdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYE1heGltdW1FQ1BVUGVyU2Vjb25kYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdOdW1lcmljRXF1YWxzJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIENhY2hlVXNhZ2VMaW1pdHMuRGF0YVN0b3JhZ2UuTWluaW11bSBwYXJhbWV0ZXIgaW4gdGhlIENyZWF0ZVNlcnZlcmxlc3NDYWNoZSBhbmQgTW9kaWZ5U2VydmVybGVzc0NhY2hlIHJlcXVlc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9yZWQtdWcvSUFNLkNvbmRpdGlvbktleXMuaHRtbCNJQU0uU3BlY2lmeWluZ0NvbmRpdGlvbnNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0FkZFRhZ3NUb1Jlc291cmNlKClcbiAgICogLSAudG9Db25uZWN0KClcbiAgICogLSAudG9DcmVhdGVTZXJ2ZXJsZXNzQ2FjaGUoKVxuICAgKiAtIC50b0NyZWF0ZVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90KClcbiAgICogLSAudG9EZWxldGVTZXJ2ZXJsZXNzQ2FjaGUoKVxuICAgKiAtIC50b0Rlc2NyaWJlU2VydmVybGVzc0NhY2hlU25hcHNob3RzKClcbiAgICogLSAudG9EZXNjcmliZVNlcnZlcmxlc3NDYWNoZXMoKVxuICAgKiAtIC50b0xpc3RUYWdzRm9yUmVzb3VyY2UoKVxuICAgKiAtIC50b01vZGlmeVNlcnZlcmxlc3NDYWNoZSgpXG4gICAqIC0gLnRvUmVtb3ZlVGFnc0Zyb21SZXNvdXJjZSgpXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gcmVzb3VyY2UgdHlwZXM6XG4gICAqIC0gc2VydmVybGVzc2NhY2hlXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW251bWVyaWMgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX051bWVyaWMpLiAqKkRlZmF1bHQ6KiogYE51bWVyaWNFcXVhbHNgXG4gICAqL1xuICBwdWJsaWMgaWZNaW5pbXVtRGF0YVN0b3JhZ2UodmFsdWU6IG51bWJlciB8IG51bWJlcltdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYE1pbmltdW1EYXRhU3RvcmFnZWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnTnVtZXJpY0VxdWFscycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBDYWNoZVVzYWdlTGltaXRzLkVDUFVQZXJTZWNvbmQuTWluaW11bSBwYXJhbWV0ZXIgaW4gdGhlIENyZWF0ZVNlcnZlcmxlc3NDYWNoZSBhbmQgTW9kaWZ5U2VydmVybGVzc0NhY2hlIHJlcXVlc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9yZWQtdWcvSUFNLkNvbmRpdGlvbktleXMuaHRtbCNJQU0uU3BlY2lmeWluZ0NvbmRpdGlvbnNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0FkZFRhZ3NUb1Jlc291cmNlKClcbiAgICogLSAudG9Db25uZWN0KClcbiAgICogLSAudG9DcmVhdGVTZXJ2ZXJsZXNzQ2FjaGUoKVxuICAgKiAtIC50b0NyZWF0ZVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90KClcbiAgICogLSAudG9EZWxldGVTZXJ2ZXJsZXNzQ2FjaGUoKVxuICAgKiAtIC50b0Rlc2NyaWJlU2VydmVybGVzc0NhY2hlU25hcHNob3RzKClcbiAgICogLSAudG9EZXNjcmliZVNlcnZlcmxlc3NDYWNoZXMoKVxuICAgKiAtIC50b0xpc3RUYWdzRm9yUmVzb3VyY2UoKVxuICAgKiAtIC50b01vZGlmeVNlcnZlcmxlc3NDYWNoZSgpXG4gICAqIC0gLnRvUmVtb3ZlVGFnc0Zyb21SZXNvdXJjZSgpXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gcmVzb3VyY2UgdHlwZXM6XG4gICAqIC0gc2VydmVybGVzc2NhY2hlXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW251bWVyaWMgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX051bWVyaWMpLiAqKkRlZmF1bHQ6KiogYE51bWVyaWNFcXVhbHNgXG4gICAqL1xuICBwdWJsaWMgaWZNaW5pbXVtRUNQVVBlclNlY29uZCh2YWx1ZTogbnVtYmVyIHwgbnVtYmVyW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgTWluaW11bUVDUFVQZXJTZWNvbmRgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ051bWVyaWNFcXVhbHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgQVpNb2RlIHBhcmFtZXRlciwgTXVsdGlBWkVuYWJsZWQgcGFyYW1ldGVyIG9yIHRoZSBudW1iZXIgb2YgYXZhaWxhYmlsaXR5IHpvbmVzIHRoYXQgdGhlIGNsdXN0ZXIgb3IgcmVwbGljYXRpb24gZ3JvdXAgY2FuIGJlIHBsYWNlZCBpblxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L3JlZC11Zy9JQU0uQ29uZGl0aW9uS2V5cy5odG1sI0lBTS5TcGVjaWZ5aW5nQ29uZGl0aW9uc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFnc1RvUmVzb3VyY2UoKVxuICAgKiAtIC50b0JhdGNoQXBwbHlVcGRhdGVBY3Rpb24oKVxuICAgKiAtIC50b0JhdGNoU3RvcFVwZGF0ZUFjdGlvbigpXG4gICAqIC0gLnRvQ29tcGxldGVNaWdyYXRpb24oKVxuICAgKiAtIC50b0Nvbm5lY3QoKVxuICAgKiAtIC50b0NyZWF0ZUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvQ3JlYXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlU25hcHNob3QoKVxuICAgKiAtIC50b0RlY3JlYXNlTm9kZUdyb3Vwc0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVjcmVhc2VSZXBsaWNhQ291bnQoKVxuICAgKiAtIC50b0RlbGV0ZUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvRGVsZXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVzY3JpYmVDYWNoZUNsdXN0ZXJzKClcbiAgICogLSAudG9EZXNjcmliZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVVwZGF0ZUFjdGlvbnMoKVxuICAgKiAtIC50b0Rpc2Fzc29jaWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0ZhaWxvdmVyR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvSW5jcmVhc2VOb2RlR3JvdXBzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9JbmNyZWFzZVJlcGxpY2FDb3VudCgpXG4gICAqIC0gLnRvTGlzdEFsbG93ZWROb2RlVHlwZU1vZGlmaWNhdGlvbnMoKVxuICAgKiAtIC50b0xpc3RUYWdzRm9yUmVzb3VyY2UoKVxuICAgKiAtIC50b01vZGlmeUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvTW9kaWZ5R2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cFNoYXJkQ29uZmlndXJhdGlvbigpXG4gICAqIC0gLnRvUmViYWxhbmNlU2xvdHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b1JlYm9vdENhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvUmVtb3ZlVGFnc0Zyb21SZXNvdXJjZSgpXG4gICAqIC0gLnRvU3RhcnRNaWdyYXRpb24oKVxuICAgKiAtIC50b1Rlc3RGYWlsb3ZlcigpXG4gICAqIC0gLnRvVGVzdE1pZ3JhdGlvbigpXG4gICAqIC0gLnRvSW50ZXJydXB0Q2x1c3RlckF6UG93ZXIoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIGNsdXN0ZXJcbiAgICogLSBnbG9iYWxyZXBsaWNhdGlvbmdyb3VwXG4gICAqIC0gcmVwbGljYXRpb25ncm91cFxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIG9yIGBmYWxzZWAuICoqRGVmYXVsdDoqKiBgdHJ1ZWBcbiAgICovXG4gIHB1YmxpYyBpZk11bHRpQVpFbmFibGVkKHZhbHVlPzogYm9vbGVhbikge1xuICAgIHJldHVybiB0aGlzLmlmKGBNdWx0aUFaRW5hYmxlZGAsICh0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnID8gdmFsdWUgOiB0cnVlKSwgJ0Jvb2wnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgTnVtTm9kZUdyb3VwcyBvciBOb2RlR3JvdXBDb3VudCBwYXJhbWV0ZXIgc3BlY2lmaWVkIGluIHRoZSByZXF1ZXN0LiBUaGlzIGtleSBjYW4gYmUgdXNlZCB0byByZXN0cmljdCB0aGUgbnVtYmVyIG9mIG5vZGUgZ3JvdXBzIChzaGFyZHMpIGNsdXN0ZXJzIGNhbiBoYXZlIGFmdGVyIGNyZWF0aW9uIG9yIHNjYWxpbmcgb3BlcmF0aW9uc1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L3JlZC11Zy9JQU0uQ29uZGl0aW9uS2V5cy5odG1sI0lBTS5TcGVjaWZ5aW5nQ29uZGl0aW9uc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFnc1RvUmVzb3VyY2UoKVxuICAgKiAtIC50b0JhdGNoQXBwbHlVcGRhdGVBY3Rpb24oKVxuICAgKiAtIC50b0JhdGNoU3RvcFVwZGF0ZUFjdGlvbigpXG4gICAqIC0gLnRvQ29tcGxldGVNaWdyYXRpb24oKVxuICAgKiAtIC50b0Nvbm5lY3QoKVxuICAgKiAtIC50b0NyZWF0ZUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvQ3JlYXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlU25hcHNob3QoKVxuICAgKiAtIC50b0RlY3JlYXNlTm9kZUdyb3Vwc0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVjcmVhc2VSZXBsaWNhQ291bnQoKVxuICAgKiAtIC50b0RlbGV0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0RlbGV0ZVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0Rlc2NyaWJlR2xvYmFsUmVwbGljYXRpb25Hcm91cHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlUmVwbGljYXRpb25Hcm91cHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlVXBkYXRlQWN0aW9ucygpXG4gICAqIC0gLnRvRGlzYXNzb2NpYXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRmFpbG92ZXJHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9JbmNyZWFzZU5vZGVHcm91cHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0luY3JlYXNlUmVwbGljYUNvdW50KClcbiAgICogLSAudG9MaXN0QWxsb3dlZE5vZGVUeXBlTW9kaWZpY2F0aW9ucygpXG4gICAqIC0gLnRvTGlzdFRhZ3NGb3JSZXNvdXJjZSgpXG4gICAqIC0gLnRvTW9kaWZ5R2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cFNoYXJkQ29uZmlndXJhdGlvbigpXG4gICAqIC0gLnRvUmViYWxhbmNlU2xvdHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3NGcm9tUmVzb3VyY2UoKVxuICAgKiAtIC50b1N0YXJ0TWlncmF0aW9uKClcbiAgICogLSAudG9UZXN0RmFpbG92ZXIoKVxuICAgKiAtIC50b1Rlc3RNaWdyYXRpb24oKVxuICAgKiAtIC50b0ludGVycnVwdENsdXN0ZXJBelBvd2VyKClcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSBnbG9iYWxyZXBsaWNhdGlvbmdyb3VwXG4gICAqIC0gcmVwbGljYXRpb25ncm91cFxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtudW1lcmljIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19OdW1lcmljKS4gKipEZWZhdWx0OioqIGBOdW1lcmljRXF1YWxzYFxuICAgKi9cbiAgcHVibGljIGlmTnVtTm9kZUdyb3Vwcyh2YWx1ZTogbnVtYmVyIHwgbnVtYmVyW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgTnVtTm9kZUdyb3Vwc2AsIHZhbHVlLCBvcGVyYXRvciA/PyAnTnVtZXJpY0VxdWFscycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBudW1iZXIgb2YgcmVwbGljYXMgcGVyIG5vZGUgZ3JvdXAgKHNoYXJkcykgc3BlY2lmaWVkIGluIGNyZWF0aW9ucyBvciBzY2FsaW5nIHJlcXVlc3RzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FbGFzdGlDYWNoZS9sYXRlc3QvcmVkLXVnL0lBTS5Db25kaXRpb25LZXlzLmh0bWwjSUFNLlNwZWNpZnlpbmdDb25kaXRpb25zXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9BZGRUYWdzVG9SZXNvdXJjZSgpXG4gICAqIC0gLnRvQmF0Y2hBcHBseVVwZGF0ZUFjdGlvbigpXG4gICAqIC0gLnRvQmF0Y2hTdG9wVXBkYXRlQWN0aW9uKClcbiAgICogLSAudG9Db21wbGV0ZU1pZ3JhdGlvbigpXG4gICAqIC0gLnRvQ29ubmVjdCgpXG4gICAqIC0gLnRvQ3JlYXRlQ2FjaGVDbHVzdGVyKClcbiAgICogLSAudG9DcmVhdGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9DcmVhdGVSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9DcmVhdGVTbmFwc2hvdCgpXG4gICAqIC0gLnRvRGVjcmVhc2VOb2RlR3JvdXBzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9EZWNyZWFzZVJlcGxpY2FDb3VudCgpXG4gICAqIC0gLnRvRGVsZXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVzY3JpYmVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwcygpXG4gICAqIC0gLnRvRGVzY3JpYmVSZXBsaWNhdGlvbkdyb3VwcygpXG4gICAqIC0gLnRvRGVzY3JpYmVVcGRhdGVBY3Rpb25zKClcbiAgICogLSAudG9EaXNhc3NvY2lhdGVHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9GYWlsb3Zlckdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0luY3JlYXNlTm9kZUdyb3Vwc0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvSW5jcmVhc2VSZXBsaWNhQ291bnQoKVxuICAgKiAtIC50b0xpc3RBbGxvd2VkTm9kZVR5cGVNb2RpZmljYXRpb25zKClcbiAgICogLSAudG9MaXN0VGFnc0ZvclJlc291cmNlKClcbiAgICogLSAudG9Nb2RpZnlHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9Nb2RpZnlSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9Nb2RpZnlSZXBsaWNhdGlvbkdyb3VwU2hhcmRDb25maWd1cmF0aW9uKClcbiAgICogLSAudG9SZWJhbGFuY2VTbG90c0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvUmVtb3ZlVGFnc0Zyb21SZXNvdXJjZSgpXG4gICAqIC0gLnRvU3RhcnRNaWdyYXRpb24oKVxuICAgKiAtIC50b1Rlc3RGYWlsb3ZlcigpXG4gICAqIC0gLnRvVGVzdE1pZ3JhdGlvbigpXG4gICAqIC0gLnRvSW50ZXJydXB0Q2x1c3RlckF6UG93ZXIoKVxuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIGdsb2JhbHJlcGxpY2F0aW9uZ3JvdXBcbiAgICogLSByZXBsaWNhdGlvbmdyb3VwXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW251bWVyaWMgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX051bWVyaWMpLiAqKkRlZmF1bHQ6KiogYE51bWVyaWNFcXVhbHNgXG4gICAqL1xuICBwdWJsaWMgaWZSZXBsaWNhc1Blck5vZGVHcm91cCh2YWx1ZTogbnVtYmVyIHwgbnVtYmVyW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgUmVwbGljYXNQZXJOb2RlR3JvdXBgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ051bWVyaWNFcXVhbHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgU25hcHNob3RSZXRlbnRpb25MaW1pdCBwYXJhbWV0ZXIgaW4gdGhlIHJlcXVlc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkVsYXN0aUNhY2hlL2xhdGVzdC9yZWQtdWcvSUFNLkNvbmRpdGlvbktleXMuaHRtbCNJQU0uU3BlY2lmeWluZ0NvbmRpdGlvbnNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0FkZFRhZ3NUb1Jlc291cmNlKClcbiAgICogLSAudG9CYXRjaEFwcGx5VXBkYXRlQWN0aW9uKClcbiAgICogLSAudG9CYXRjaFN0b3BVcGRhdGVBY3Rpb24oKVxuICAgKiAtIC50b0NvbXBsZXRlTWlncmF0aW9uKClcbiAgICogLSAudG9Db25uZWN0KClcbiAgICogLSAudG9DcmVhdGVDYWNoZUNsdXN0ZXIoKVxuICAgKiAtIC50b0NyZWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZVNlcnZlcmxlc3NDYWNoZSgpXG4gICAqIC0gLnRvQ3JlYXRlU2VydmVybGVzc0NhY2hlU25hcHNob3QoKVxuICAgKiAtIC50b0NyZWF0ZVNuYXBzaG90KClcbiAgICogLSAudG9EZWNyZWFzZU5vZGVHcm91cHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0RlY3JlYXNlUmVwbGljYUNvdW50KClcbiAgICogLSAudG9EZWxldGVDYWNoZUNsdXN0ZXIoKVxuICAgKiAtIC50b0RlbGV0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0RlbGV0ZVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0RlbGV0ZVNlcnZlcmxlc3NDYWNoZSgpXG4gICAqIC0gLnRvRGVzY3JpYmVDYWNoZUNsdXN0ZXJzKClcbiAgICogLSAudG9EZXNjcmliZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVJlcGxpY2F0aW9uR3JvdXBzKClcbiAgICogLSAudG9EZXNjcmliZVNlcnZlcmxlc3NDYWNoZVNuYXBzaG90cygpXG4gICAqIC0gLnRvRGVzY3JpYmVTZXJ2ZXJsZXNzQ2FjaGVzKClcbiAgICogLSAudG9EZXNjcmliZVVwZGF0ZUFjdGlvbnMoKVxuICAgKiAtIC50b0Rpc2Fzc29jaWF0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0ZhaWxvdmVyR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvSW5jcmVhc2VOb2RlR3JvdXBzSW5HbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9JbmNyZWFzZVJlcGxpY2FDb3VudCgpXG4gICAqIC0gLnRvTGlzdEFsbG93ZWROb2RlVHlwZU1vZGlmaWNhdGlvbnMoKVxuICAgKiAtIC50b0xpc3RUYWdzRm9yUmVzb3VyY2UoKVxuICAgKiAtIC50b01vZGlmeUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvTW9kaWZ5R2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cFNoYXJkQ29uZmlndXJhdGlvbigpXG4gICAqIC0gLnRvTW9kaWZ5U2VydmVybGVzc0NhY2hlKClcbiAgICogLSAudG9SZWJhbGFuY2VTbG90c0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvUmVib290Q2FjaGVDbHVzdGVyKClcbiAgICogLSAudG9SZW1vdmVUYWdzRnJvbVJlc291cmNlKClcbiAgICogLSAudG9TdGFydE1pZ3JhdGlvbigpXG4gICAqIC0gLnRvVGVzdEZhaWxvdmVyKClcbiAgICogLSAudG9UZXN0TWlncmF0aW9uKClcbiAgICogLSAudG9JbnRlcnJ1cHRDbHVzdGVyQXpQb3dlcigpXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gcmVzb3VyY2UgdHlwZXM6XG4gICAqIC0gY2x1c3RlclxuICAgKiAtIGdsb2JhbHJlcGxpY2F0aW9uZ3JvdXBcbiAgICogLSByZXBsaWNhdGlvbmdyb3VwXG4gICAqIC0gc2VydmVybGVzc2NhY2hlXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW251bWVyaWMgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX051bWVyaWMpLiAqKkRlZmF1bHQ6KiogYE51bWVyaWNFcXVhbHNgXG4gICAqL1xuICBwdWJsaWMgaWZTbmFwc2hvdFJldGVudGlvbkxpbWl0KHZhbHVlOiBudW1iZXIgfCBudW1iZXJbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBTbmFwc2hvdFJldGVudGlvbkxpbWl0YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdOdW1lcmljRXF1YWxzJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIFRyYW5zaXRFbmNyeXB0aW9uRW5hYmxlZCBwYXJhbWV0ZXIgcHJlc2VudCBpbiB0aGUgcmVxdWVzdC4gRm9yIHJlcGxpY2F0aW9uIGdyb3VwIGNyZWF0aW9ucywgZGVmYXVsdCB2YWx1ZSAnZmFsc2UnIGlzIHVzZWQgYXMga2V5IGlmIHBhcmFtZXRlciBpcyBub3QgcHJlc2VudFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L3JlZC11Zy9JQU0uQ29uZGl0aW9uS2V5cy5odG1sI0lBTS5TcGVjaWZ5aW5nQ29uZGl0aW9uc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFnc1RvUmVzb3VyY2UoKVxuICAgKiAtIC50b0JhdGNoQXBwbHlVcGRhdGVBY3Rpb24oKVxuICAgKiAtIC50b0JhdGNoU3RvcFVwZGF0ZUFjdGlvbigpXG4gICAqIC0gLnRvQ29tcGxldGVNaWdyYXRpb24oKVxuICAgKiAtIC50b0Nvbm5lY3QoKVxuICAgKiAtIC50b0NyZWF0ZUNhY2hlQ2x1c3RlcigpXG4gICAqIC0gLnRvQ3JlYXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlU25hcHNob3QoKVxuICAgKiAtIC50b0RlY3JlYXNlTm9kZUdyb3Vwc0luR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRGVjcmVhc2VSZXBsaWNhQ291bnQoKVxuICAgKiAtIC50b0RlbGV0ZUdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0RlbGV0ZVJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0Rlc2NyaWJlR2xvYmFsUmVwbGljYXRpb25Hcm91cHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlUmVwbGljYXRpb25Hcm91cHMoKVxuICAgKiAtIC50b0Rlc2NyaWJlVXBkYXRlQWN0aW9ucygpXG4gICAqIC0gLnRvRGlzYXNzb2NpYXRlR2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvRmFpbG92ZXJHbG9iYWxSZXBsaWNhdGlvbkdyb3VwKClcbiAgICogLSAudG9JbmNyZWFzZU5vZGVHcm91cHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b0luY3JlYXNlUmVwbGljYUNvdW50KClcbiAgICogLSAudG9MaXN0QWxsb3dlZE5vZGVUeXBlTW9kaWZpY2F0aW9ucygpXG4gICAqIC0gLnRvTGlzdFRhZ3NGb3JSZXNvdXJjZSgpXG4gICAqIC0gLnRvTW9kaWZ5R2xvYmFsUmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cCgpXG4gICAqIC0gLnRvTW9kaWZ5UmVwbGljYXRpb25Hcm91cFNoYXJkQ29uZmlndXJhdGlvbigpXG4gICAqIC0gLnRvUmViYWxhbmNlU2xvdHNJbkdsb2JhbFJlcGxpY2F0aW9uR3JvdXAoKVxuICAgKiAtIC50b1JlbW92ZVRhZ3NGcm9tUmVzb3VyY2UoKVxuICAgKiAtIC50b1N0YXJ0TWlncmF0aW9uKClcbiAgICogLSAudG9UZXN0RmFpbG92ZXIoKVxuICAgKiAtIC50b1Rlc3RNaWdyYXRpb24oKVxuICAgKiAtIC50b0ludGVycnVwdENsdXN0ZXJBelBvd2VyKClcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSBnbG9iYWxyZXBsaWNhdGlvbmdyb3VwXG4gICAqIC0gcmVwbGljYXRpb25ncm91cFxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIG9yIGBmYWxzZWAuICoqRGVmYXVsdDoqKiBgdHJ1ZWBcbiAgICovXG4gIHB1YmxpYyBpZlRyYW5zaXRFbmNyeXB0aW9uRW5hYmxlZCh2YWx1ZT86IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gdGhpcy5pZihgVHJhbnNpdEVuY3J5cHRpb25FbmFibGVkYCwgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcgPyB2YWx1ZSA6IHRydWUpLCAnQm9vbCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBVc2VyQXV0aGVudGljYXRpb25Nb2RlIHBhcmFtZXRlciBpbiB0aGUgcmVxdWVzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRWxhc3RpQ2FjaGUvbGF0ZXN0L3JlZC11Zy9JQU0uQ29uZGl0aW9uS2V5cy5odG1sI0lBTS5TcGVjaWZ5aW5nQ29uZGl0aW9uc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQWRkVGFnc1RvUmVzb3VyY2UoKVxuICAgKiAtIC50b0Nvbm5lY3QoKVxuICAgKiAtIC50b0NyZWF0ZVVzZXIoKVxuICAgKiAtIC50b0NyZWF0ZVVzZXJHcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlVXNlcigpXG4gICAqIC0gLnRvRGVzY3JpYmVVc2VycygpXG4gICAqIC0gLnRvTGlzdFRhZ3NGb3JSZXNvdXJjZSgpXG4gICAqIC0gLnRvTW9kaWZ5VXNlcigpXG4gICAqIC0gLnRvTW9kaWZ5VXNlckdyb3VwKClcbiAgICogLSAudG9SZW1vdmVUYWdzRnJvbVJlc291cmNlKClcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSB1c2VyXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmVXNlckF1dGhlbnRpY2F0aW9uTW9kZSh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgVXNlckF1dGhlbnRpY2F0aW9uTW9kZWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbZWxhc3RpY2FjaGVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXJ2aWNlLWF1dGhvcml6YXRpb24vbGF0ZXN0L3JlZmVyZW5jZS9saXN0X2VsYXN0aWNhY2hlLmh0bWwpLlxuICAgKlxuICAgKi9cbiAgY29uc3RydWN0b3IocHJvcHM/OiBpYW0uUG9saWN5U3RhdGVtZW50UHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gIH1cbn1cbiJdfQ==