iam-floyd
Version:
AWS IAM policy statement generator with fluent interface
1,307 lines • 131 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Autoscaling = void 0;
const shared_1 = require("../../shared");
/**
* Statement provider for service [autoscaling](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2autoscaling.html).
*
* @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
*/
class Autoscaling extends shared_1.PolicyStatement {
/**
* Statement provider for service [autoscaling](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2autoscaling.html).
*
* @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
*/
constructor(sid) {
super(sid);
this.servicePrefix = 'autoscaling';
this.accessLevelList = {
Write: [
'AttachInstances',
'AttachLoadBalancerTargetGroups',
'AttachLoadBalancers',
'AttachTrafficSources',
'BatchDeleteScheduledAction',
'BatchPutScheduledUpdateGroupAction',
'CancelInstanceRefresh',
'CompleteLifecycleAction',
'CreateAutoScalingGroup',
'CreateLaunchConfiguration',
'DeleteAutoScalingGroup',
'DeleteLaunchConfiguration',
'DeleteLifecycleHook',
'DeleteNotificationConfiguration',
'DeletePolicy',
'DeleteScheduledAction',
'DeleteWarmPool',
'DetachInstances',
'DetachLoadBalancerTargetGroups',
'DetachLoadBalancers',
'DetachTrafficSources',
'DisableMetricsCollection',
'EnableMetricsCollection',
'EnterStandby',
'ExecutePolicy',
'ExitStandby',
'LaunchInstances',
'PutAccountSetting',
'PutLifecycleHook',
'PutNotificationConfiguration',
'PutScalingPolicy',
'PutScheduledUpdateGroupAction',
'PutWarmPool',
'RecordLifecycleActionHeartbeat',
'ResumeProcesses',
'RollbackInstanceRefresh',
'SetDesiredCapacity',
'SetInstanceHealth',
'SetInstanceProtection',
'StartInstanceRefresh',
'SuspendProcesses',
'TerminateInstanceInAutoScalingGroup',
'UpdateAutoScalingGroup'
],
Tagging: [
'CreateOrUpdateTags',
'DeleteTags'
],
List: [
'DescribeAccountLimits',
'DescribeAccountSettings',
'DescribeAdjustmentTypes',
'DescribeAutoScalingGroups',
'DescribeAutoScalingInstances',
'DescribeAutoScalingNotificationTypes',
'DescribeInstanceRefreshes',
'DescribeLaunchConfigurations',
'DescribeLifecycleHookTypes',
'DescribeLifecycleHooks',
'DescribeLoadBalancerTargetGroups',
'DescribeLoadBalancers',
'DescribeMetricCollectionTypes',
'DescribeNotificationConfigurations',
'DescribePolicies',
'DescribeScalingActivities',
'DescribeScalingProcessTypes',
'DescribeScheduledActions',
'DescribeTerminationPolicyTypes',
'DescribeTrafficSources',
'DescribeWarmPool',
'GetPredictiveScalingForecast'
],
Read: [
'DescribeTags'
]
};
}
/**
* Grants permission to attach one or more EC2 instances to the specified Auto Scaling group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_AttachInstances.html
*/
toAttachInstances() {
return this.to('AttachInstances');
}
/**
* Grants permission to attach one or more target groups to the specified Auto Scaling group
*
* Access Level: Write
*
* Possible conditions:
* - .ifTargetGroupARNs()
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_AttachLoadBalancerTargetGroups.html
*/
toAttachLoadBalancerTargetGroups() {
return this.to('AttachLoadBalancerTargetGroups');
}
/**
* Grants permission to attach one or more load balancers to the specified Auto Scaling group
*
* Access Level: Write
*
* Possible conditions:
* - .ifLoadBalancerNames()
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_AttachLoadBalancers.html
*/
toAttachLoadBalancers() {
return this.to('AttachLoadBalancers');
}
/**
* Grants permission to attach one or more traffic sources to an Auto Scaling group
*
* Access Level: Write
*
* Possible conditions:
* - .ifTrafficSourceIdentifiers()
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_AttachTrafficSources.html
*/
toAttachTrafficSources() {
return this.to('AttachTrafficSources');
}
/**
* Grants permission to delete the specified scheduled actions
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_BatchDeleteScheduledAction.html
*/
toBatchDeleteScheduledAction() {
return this.to('BatchDeleteScheduledAction');
}
/**
* Grants permission to create or update multiple scheduled scaling actions for an Auto Scaling group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_BatchPutScheduledUpdateGroupAction.html
*/
toBatchPutScheduledUpdateGroupAction() {
return this.to('BatchPutScheduledUpdateGroupAction');
}
/**
* Grants permission to cancel an instance refresh operation in progress
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_CancelInstanceRefresh.html
*/
toCancelInstanceRefresh() {
return this.to('CancelInstanceRefresh');
}
/**
* Grants permission to complete the lifecycle action for the specified token or instance with the specified result
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_CompleteLifecycleAction.html
*/
toCompleteLifecycleAction() {
return this.to('CompleteLifecycleAction');
}
/**
* Grants permission to create an Auto Scaling group with the specified name and attributes
*
* Access Level: Write
*
* Possible conditions:
* - .ifImageId()
* - .ifCapacityReservationIds()
* - .ifCapacityReservationResourceGroupArns()
* - .ifInstanceTypes()
* - .ifLaunchConfigurationName()
* - .ifLaunchTemplateVersionSpecified()
* - .ifLoadBalancerNames()
* - .ifMaxSize()
* - .ifMinSize()
* - .ifTargetGroupARNs()
* - .ifTrafficSourceIdentifiers()
* - .ifVPCZoneIdentifiers()
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* Dependent actions:
* - iam:CreateServiceLinkedRole
* - iam:PassRole
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_CreateAutoScalingGroup.html
*/
toCreateAutoScalingGroup() {
return this.to('CreateAutoScalingGroup');
}
/**
* Grants permission to create a launch configuration
*
* Access Level: Write
*
* Possible conditions:
* - .ifImageId()
* - .ifInstanceType()
* - .ifSpotPrice()
* - .ifMetadataHttpTokens()
* - .ifMetadataHttpPutResponseHopLimit()
* - .ifMetadataHttpEndpoint()
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_CreateLaunchConfiguration.html
*/
toCreateLaunchConfiguration() {
return this.to('CreateLaunchConfiguration');
}
/**
* Grants permission to create or update tags for the specified Auto Scaling group
*
* Access Level: Tagging
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_CreateOrUpdateTags.html
*/
toCreateOrUpdateTags() {
return this.to('CreateOrUpdateTags');
}
/**
* Grants permission to delete the specified Auto Scaling group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DeleteAutoScalingGroup.html
*/
toDeleteAutoScalingGroup() {
return this.to('DeleteAutoScalingGroup');
}
/**
* Grants permission to delete the specified launch configuration
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DeleteLaunchConfiguration.html
*/
toDeleteLaunchConfiguration() {
return this.to('DeleteLaunchConfiguration');
}
/**
* Grants permission to deletes the specified lifecycle hook
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DeleteLifecycleHook.html
*/
toDeleteLifecycleHook() {
return this.to('DeleteLifecycleHook');
}
/**
* Grants permission to delete the specified notification
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DeleteNotificationConfiguration.html
*/
toDeleteNotificationConfiguration() {
return this.to('DeleteNotificationConfiguration');
}
/**
* Grants permission to delete the specified Auto Scaling policy
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DeletePolicy.html
*/
toDeletePolicy() {
return this.to('DeletePolicy');
}
/**
* Grants permission to delete the specified scheduled action
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DeleteScheduledAction.html
*/
toDeleteScheduledAction() {
return this.to('DeleteScheduledAction');
}
/**
* Grants permission to delete the specified tags
*
* Access Level: Tagging
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DeleteTags.html
*/
toDeleteTags() {
return this.to('DeleteTags');
}
/**
* Grants permission to delete the warm pool associated with the Auto Scaling group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DeleteWarmPool.html
*/
toDeleteWarmPool() {
return this.to('DeleteWarmPool');
}
/**
* Grants permission to describe the current Auto Scaling resource limits for your AWS account
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeAccountLimits.html
*/
toDescribeAccountLimits() {
return this.to('DescribeAccountLimits');
}
/**
* Grants permission to describe the current Amazon EC2 Auto Scaling account settings for your account
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeAccountSettings.html
*/
toDescribeAccountSettings() {
return this.to('DescribeAccountSettings');
}
/**
* Grants permission to describe the policy adjustment types for use with PutScalingPolicy
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeAdjustmentTypes.html
*/
toDescribeAdjustmentTypes() {
return this.to('DescribeAdjustmentTypes');
}
/**
* Grants permission to describe one or more Auto Scaling groups. If a list of names is not provided, the call describes all Auto Scaling groups
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeAutoScalingGroups.html
*/
toDescribeAutoScalingGroups() {
return this.to('DescribeAutoScalingGroups');
}
/**
* Grants permission to describe one or more Auto Scaling instances. If a list is not provided, the call describes all instances
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeAutoScalingInstances.html
*/
toDescribeAutoScalingInstances() {
return this.to('DescribeAutoScalingInstances');
}
/**
* Grants permission to describe the notification types that are supported by Auto Scaling
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeAutoScalingNotificationTypes.html
*/
toDescribeAutoScalingNotificationTypes() {
return this.to('DescribeAutoScalingNotificationTypes');
}
/**
* Grants permission to describe one or more instance refreshes for an Auto Scaling group
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeInstanceRefreshes.html
*/
toDescribeInstanceRefreshes() {
return this.to('DescribeInstanceRefreshes');
}
/**
* Grants permission to describe one or more launch configurations. If you omit the list of names, then the call describes all launch configurations
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeLaunchConfigurations.html
*/
toDescribeLaunchConfigurations() {
return this.to('DescribeLaunchConfigurations');
}
/**
* Grants permission to describe the available types of lifecycle hooks
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeLifecycleHookTypes.html
*/
toDescribeLifecycleHookTypes() {
return this.to('DescribeLifecycleHookTypes');
}
/**
* Grants permission to describe the lifecycle hooks for the specified Auto Scaling group
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeLifecycleHooks.html
*/
toDescribeLifecycleHooks() {
return this.to('DescribeLifecycleHooks');
}
/**
* Grants permission to describe the target groups for the specified Auto Scaling group
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeLoadBalancerTargetGroups.html
*/
toDescribeLoadBalancerTargetGroups() {
return this.to('DescribeLoadBalancerTargetGroups');
}
/**
* Grants permission to describe the load balancers for the specified Auto Scaling group
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeLoadBalancers.html
*/
toDescribeLoadBalancers() {
return this.to('DescribeLoadBalancers');
}
/**
* Grants permission to describe the available CloudWatch metrics for Auto Scaling
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeMetricCollectionTypes.html
*/
toDescribeMetricCollectionTypes() {
return this.to('DescribeMetricCollectionTypes');
}
/**
* Grants permission to describe the notification actions associated with the specified Auto Scaling group
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeNotificationConfigurations.html
*/
toDescribeNotificationConfigurations() {
return this.to('DescribeNotificationConfigurations');
}
/**
* Grants permission to describe the policies for the specified Auto Scaling group
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribePolicies.html
*/
toDescribePolicies() {
return this.to('DescribePolicies');
}
/**
* Grants permission to describe one or more scaling activities for the specified Auto Scaling group
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeScalingActivities.html
*/
toDescribeScalingActivities() {
return this.to('DescribeScalingActivities');
}
/**
* Grants permission to describe the scaling process types for use with ResumeProcesses and SuspendProcesses
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeScalingProcessTypes.html
*/
toDescribeScalingProcessTypes() {
return this.to('DescribeScalingProcessTypes');
}
/**
* Grants permission to describe the actions scheduled for your Auto Scaling group that haven't run
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeScheduledActions.html
*/
toDescribeScheduledActions() {
return this.to('DescribeScheduledActions');
}
/**
* Grants permission to describe the specified tags
*
* Access Level: Read
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeTags.html
*/
toDescribeTags() {
return this.to('DescribeTags');
}
/**
* Grants permission to describe the termination policies supported by Auto Scaling
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeTerminationPolicyTypes.html
*/
toDescribeTerminationPolicyTypes() {
return this.to('DescribeTerminationPolicyTypes');
}
/**
* Grants permission to describe the target groups for the specified Auto Scaling group
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeTrafficSources.html
*/
toDescribeTrafficSources() {
return this.to('DescribeTrafficSources');
}
/**
* Grants permission to describe the warm pool associated with the Auto Scaling group
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DescribeWarmPool.html
*/
toDescribeWarmPool() {
return this.to('DescribeWarmPool');
}
/**
* Grants permission to remove one or more instances from the specified Auto Scaling group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DetachInstances.html
*/
toDetachInstances() {
return this.to('DetachInstances');
}
/**
* Grants permission to detach one or more target groups from the specified Auto Scaling group
*
* Access Level: Write
*
* Possible conditions:
* - .ifTargetGroupARNs()
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DetachLoadBalancerTargetGroups.html
*/
toDetachLoadBalancerTargetGroups() {
return this.to('DetachLoadBalancerTargetGroups');
}
/**
* Grants permission to remove one or more load balancers from the specified Auto Scaling group
*
* Access Level: Write
*
* Possible conditions:
* - .ifLoadBalancerNames()
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DetachLoadBalancers.html
*/
toDetachLoadBalancers() {
return this.to('DetachLoadBalancers');
}
/**
* Grants permission to detach one or more traffic sources from an Auto Scaling group
*
* Access Level: Write
*
* Possible conditions:
* - .ifTrafficSourceIdentifiers()
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DetachTrafficSources.html
*/
toDetachTrafficSources() {
return this.to('DetachTrafficSources');
}
/**
* Grants permission to disable monitoring of the specified metrics for the specified Auto Scaling group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_DisableMetricsCollection.html
*/
toDisableMetricsCollection() {
return this.to('DisableMetricsCollection');
}
/**
* Grants permission to enable monitoring of the specified metrics for the specified Auto Scaling group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_EnableMetricsCollection.html
*/
toEnableMetricsCollection() {
return this.to('EnableMetricsCollection');
}
/**
* Grants permission to move the specified instances into Standby mode
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_EnterStandby.html
*/
toEnterStandby() {
return this.to('EnterStandby');
}
/**
* Grants permission to execute the specified policy
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_ExecutePolicy.html
*/
toExecutePolicy() {
return this.to('ExecutePolicy');
}
/**
* Grants permission to move the specified instances out of Standby mode
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_ExitStandby.html
*/
toExitStandby() {
return this.to('ExitStandby');
}
/**
* Grants permission to retrieve the forecast data for a predictive scaling policy
*
* Access Level: List
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_GetPredictiveScalingForecast.html
*/
toGetPredictiveScalingForecast() {
return this.to('GetPredictiveScalingForecast');
}
/**
* Grants permission to launch one or more EC2 instances in the specified Auto Scaling group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_LaunchInstances.html
*/
toLaunchInstances() {
return this.to('LaunchInstances');
}
/**
* Grants permission to modify an account setting for your account
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_PutAccountSetting.html
*/
toPutAccountSetting() {
return this.to('PutAccountSetting');
}
/**
* Grants permission to create or update a lifecycle hook for the specified Auto Scaling Group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_PutLifecycleHook.html
*/
toPutLifecycleHook() {
return this.to('PutLifecycleHook');
}
/**
* Grants permission to configure an Auto Scaling group to send notifications when specified events take place
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_PutNotificationConfiguration.html
*/
toPutNotificationConfiguration() {
return this.to('PutNotificationConfiguration');
}
/**
* Grants permission to create or update a policy for an Auto Scaling group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_PutScalingPolicy.html
*/
toPutScalingPolicy() {
return this.to('PutScalingPolicy');
}
/**
* Grants permission to create or update a scheduled scaling action for an Auto Scaling group
*
* Access Level: Write
*
* Possible conditions:
* - .ifMaxSize()
* - .ifMinSize()
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_PutScheduledUpdateGroupAction.html
*/
toPutScheduledUpdateGroupAction() {
return this.to('PutScheduledUpdateGroupAction');
}
/**
* Grants permission to create or update the warm pool associated with the specified Auto Scaling group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_PutWarmPool.html
*/
toPutWarmPool() {
return this.to('PutWarmPool');
}
/**
* Grants permission to record a heartbeat for the lifecycle action associated with the specified token or instance
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_RecordLifecycleActionHeartbeat.html
*/
toRecordLifecycleActionHeartbeat() {
return this.to('RecordLifecycleActionHeartbeat');
}
/**
* Grants permission to resume the specified suspended Auto Scaling processes, or all suspended process, for the specified Auto Scaling group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_ResumeProcesses.html
*/
toResumeProcesses() {
return this.to('ResumeProcesses');
}
/**
* Grants permission to rollback an instance refresh operation in progress
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_RollbackInstanceRefresh.html
*/
toRollbackInstanceRefresh() {
return this.to('RollbackInstanceRefresh');
}
/**
* Grants permission to set the size of the specified Auto Scaling group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_SetDesiredCapacity.html
*/
toSetDesiredCapacity() {
return this.to('SetDesiredCapacity');
}
/**
* Grants permission to set the health status of the specified instance
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_SetInstanceHealth.html
*/
toSetInstanceHealth() {
return this.to('SetInstanceHealth');
}
/**
* Grants permission to update the instance protection settings of the specified instances
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_SetInstanceProtection.html
*/
toSetInstanceProtection() {
return this.to('SetInstanceProtection');
}
/**
* Grants permission to start a new instance refresh operation
*
* Access Level: Write
*
* Possible conditions:
* - .ifImageId()
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_StartInstanceRefresh.html
*/
toStartInstanceRefresh() {
return this.to('StartInstanceRefresh');
}
/**
* Grants permission to suspend the specified Auto Scaling processes, or all processes, for the specified Auto Scaling group
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_SuspendProcesses.html
*/
toSuspendProcesses() {
return this.to('SuspendProcesses');
}
/**
* Grants permission to terminate the specified instance and optionally adjust the desired group size
*
* Access Level: Write
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_TerminateInstanceInAutoScalingGroup.html
*/
toTerminateInstanceInAutoScalingGroup() {
return this.to('TerminateInstanceInAutoScalingGroup');
}
/**
* Grants permission to update the configuration for the specified Auto Scaling group
*
* Access Level: Write
*
* Possible conditions:
* - .ifImageId()
* - .ifCapacityReservationIds()
* - .ifCapacityReservationResourceGroupArns()
* - .ifInstanceTypes()
* - .ifLaunchConfigurationName()
* - .ifLaunchTemplateVersionSpecified()
* - .ifMaxSize()
* - .ifMinSize()
* - .ifVPCZoneIdentifiers()
*
* Dependent actions:
* - iam:PassRole
*
* https://docs.aws.amazon.com/AutoScaling/latest/APIReference/API_UpdateAutoScalingGroup.html
*/
toUpdateAutoScalingGroup() {
return this.to('UpdateAutoScalingGroup');
}
/**
* Adds a resource of type autoScalingGroup to the statement
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-resources
*
* @param groupId - Identifier for the groupId.
* @param groupFriendlyName - Identifier for the groupFriendlyName.
* @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:
* - .ifResourceTag()
* - .ifAwsResourceTag()
*/
onAutoScalingGroup(groupId, groupFriendlyName, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:autoscaling:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:autoScalingGroup:${groupId}:autoScalingGroupName/${groupFriendlyName}`);
}
/**
* Adds a resource of type launchConfiguration to the statement
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-resources
*
* @param id - Identifier for the id.
* @param launchConfigurationName - Identifier for the launchConfigurationName.
* @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.
*/
onLaunchConfiguration(id, launchConfigurationName, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:autoscaling:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:launchConfiguration:${id}:launchConfigurationName/${launchConfigurationName}`);
}
/**
* Filters access based on the Capacity Reservation IDs
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateAutoScalingGroup()
* - .toUpdateAutoScalingGroup()
*
* @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`
*/
ifCapacityReservationIds(value, operator) {
return this.if(`CapacityReservationIds`, value, operator ?? 'StringLike');
}
/**
* Filters access based on the ARN of a Capacity Reservation resource group
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateAutoScalingGroup()
* - .toUpdateAutoScalingGroup()
*
* @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`
*/
ifCapacityReservationResourceGroupArns(value, operator) {
return this.if(`CapacityReservationResourceGroupArns`, value, operator ?? 'StringLike');
}
/**
* Filters access based on whether the force delete option is specified when deleting an Auto Scaling group
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toDeleteAutoScalingGroup()
*
* @param value `true` or `false`. **Default:** `true`
*/
ifForceDelete(value) {
return this.if(`ForceDelete`, (typeof value !== 'undefined' ? value : true), 'Bool');
}
/**
* Filters access based on the AMI ID for the launch configuration
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateAutoScalingGroup()
* - .toCreateLaunchConfiguration()
* - .toStartInstanceRefresh()
* - .toUpdateAutoScalingGroup()
*
* @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`
*/
ifImageId(value, operator) {
return this.if(`ImageId`, value, operator ?? 'StringLike');
}
/**
* Filters access based on the instance type for the launch configuration
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateLaunchConfiguration()
*
* @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`
*/
ifInstanceType(value, operator) {
return this.if(`InstanceType`, value, operator ?? 'StringLike');
}
/**
* Filters access based on the instance types present as overrides to a launch template for a mixed instances policy. Use it to qualify which instance types can be explicitly defined in the policy
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateAutoScalingGroup()
* - .toUpdateAutoScalingGroup()
*
* @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`
*/
ifInstanceTypes(value, operator) {
return this.if(`InstanceTypes`, value, operator ?? 'StringLike');
}
/**
* Filters access based on the name of a launch configuration
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateAutoScalingGroup()
* - .toUpdateAutoScalingGroup()
*
* @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`
*/
ifLaunchConfigurationName(value, operator) {
return this.if(`LaunchConfigurationName`, value, operator ?? 'StringLike');
}
/**
* Filters access based on whether users can specify any version of a launch template or only the Latest or Default version
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateAutoScalingGroup()
* - .toUpdateAutoScalingGroup()
*
* @param value `true` or `false`. **Default:** `true`
*/
ifLaunchTemplateVersionSpecified(value) {
return this.if(`LaunchTemplateVersionSpecified`, (typeof value !== 'undefined' ? value : true), 'Bool');
}
/**
* Filters access based on the name of the load balancer
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toAttachLoadBalancers()
* - .toCreateAutoScalingGroup()
* - .toDetachLoadBalancers()
*
* @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`
*/
ifLoadBalancerNames(value, operator) {
return this.if(`LoadBalancerNames`, value, operator ?? 'StringLike');
}
/**
* Filters access based on the maximum scaling size in the request
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateAutoScalingGroup()
* - .toPutScheduledUpdateGroupAction()
* - .toUpdateAutoScalingGroup()
*
* @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`
*/
ifMaxSize(value, operator) {
return this.if(`MaxSize`, value, operator ?? 'NumericEquals');
}
/**
* Filters access based on whether the HTTP endpoint is enabled for the instance metadata service
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateLaunchConfiguration()
*
* @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`
*/
ifMetadataHttpEndpoint(value, operator) {
return this.if(`MetadataHttpEndpoint`, value, operator ?? 'StringLike');
}
/**
* Filters access based on the allowed number of hops when calling the instance metadata service
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateLaunchConfiguration()
*
* @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`
*/
ifMetadataHttpPutResponseHopLimit(value, operator) {
return this.if(`MetadataHttpPutResponseHopLimit`, value, operator ?? 'NumericEquals');
}
/**
* Filters access based on whether tokens are required when calling the instance metadata service (optional or required)
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateLaunchConfiguration()
*
* @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`
*/
ifMetadataHttpTokens(value, operator) {
return this.if(`MetadataHttpTokens`, value, operator ?? 'StringLike');
}
/**
* Filters access based on the minimum scaling size in the request
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateAutoScalingGroup()
* - .toPutScheduledUpdateGroupAction()
* - .toUpdateAutoScalingGroup()
*
* @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`
*/
ifMinSize(value, operator) {
return this.if(`MinSize`, value, operator ?? 'NumericEquals');
}
/**
* Filters access based on the tags associated with the resource
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toAttachInstances()
* - .toAttachLoadBalancerTargetGroups()
* - .toAttachLoadBalancers()
* - .toAttachTrafficSources()
* - .toBatchDeleteScheduledAction()
* - .toBatchPutScheduledUpdateGroupAction()
* - .toCancelInstanceRefresh()
* - .toCompleteLifecycleAction()
* - .toCreateAutoScalingGroup()
* - .toCreateOrUpdateTags()
* - .toDeleteAutoScalingGroup()
* - .toDeleteLifecycleHook()
* - .toDeleteNotificationConfiguration()
* - .toDeletePolicy()
* - .toDeleteScheduledAction()
* - .toDeleteTags()
* - .toDeleteWarmPool()
* - .toDetachInstances()
* - .toDetachLoadBalancerTargetGroups()
* - .toDetachLoadBalancers()
* - .toDetachTrafficSources()
* - .toDisableMetricsCollection()
* - .toEnableMetricsCollection()
* - .toEnterStandby()
* - .toExecutePolicy()
* - .toExitStandby()
* - .toLaunchInstances()
* - .toPutLifecycleHook()
* - .toPutNotificationConfiguration()
* - .toPutScalingPolicy()
* - .toPutScheduledUpdateGroupAction()
* - .toPutWarmPool()
* - .toRecordLifecycleActionHeartbeat()
* - .toResumeProcesses()
* - .toRollbackInstanceRefresh()
* - .toSetDesiredCapacity()
* - .toSetInstanceHealth()
* - .toSetInstanceProtection()
* - .toStartInstanceRefresh()
* - .toSuspendProcesses()
* - .toTerminateInstanceInAutoScalingGroup()
* - .toUpdateAutoScalingGroup()
*
* Applies to resource types:
* - autoScalingGroup
*
* @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`
*/
ifResourceTag(tagKey, value, operator) {
return this.if(`ResourceTag/${tagKey}`, value, operator ?? 'StringLike');
}
/**
* Filters access based on the price for Spot Instances for the launch configuration
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateLaunchConfiguration()
*
* @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`
*/
ifSpotPrice(value, operator) {
return this.if(`SpotPrice`, value, operator ?? 'NumericEquals');
}
/**
* Filters access based on the ARN of a target group
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toAttachLoadBalancerTargetGroups()
* - .toCreateAutoScalingGroup()
* - .toDetachLoadBalancerTargetGroups()
*
* @param value The value(s) to check
* @param operator Works with [arn operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_ARN). **Default:** `ArnLike`
*/
ifTargetGroupARNs(value, operator) {
return this.if(`TargetGroupARNs`, value, operator ?? 'ArnLike');
}
/**
* Filters access based on the identifiers of the traffic sources
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toAttachTrafficSources()
* - .toCreateAutoScalingGroup()
* - .toDetachTrafficSources()
*
* @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`
*/
ifTrafficSourceIdentifiers(value, operator) {
return this.if(`TrafficSourceIdentifiers`, value, operator ?? 'StringLike');
}
/**
* Filters access based on the identifier of a VPC zone
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateAutoScalingGroup()
* - .toUpdateAutoScalingGroup()
*
* @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`
*/
ifVPCZoneIdentifiers(value, operator) {
return this.if(`VPCZoneIdentifiers`, value, operator ?? 'StringLike');
}
/**
* Filters access based on the tags that are passed in the request
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateAutoScalingGroup()
* - .toCreateOrUpdateTags()
* - .toDeleteTags()
*
* @param tagKey The tag key to check
* @param value The value(s) to check
* @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike`
*/
ifAwsRequestTag(tagKey, value, operator) {
return this.if(`aws:RequestTag/${tagKey}`, value, operator ?? 'StringLike');
}
/**
* Filters access based on the tags associated with the resource
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toAttachInstances()
* - .toAttachLoadBalancerTargetGroups()
* - .toAttachLoadBalancers()
* - .toAttachTrafficSources()
* - .toBatchDeleteScheduledAction()
* - .toBatchPutScheduledUpdateGroupAction()
* - .toCancelInstanceRefresh()
* - .toCompleteLifecycleAction()
* - .toCreateAutoScalingGroup()
* - .toCreateOrUpdateTags()
* - .toDeleteAutoScalingGroup()
* - .toDeleteLifecycleHook()
* - .toDeleteNotificationConfiguration()
* - .toDeletePolicy()
* - .toDeleteScheduledAction()
* - .toDeleteTags()
* - .toDeleteWarmPool()
* - .toDetachInstances()
* - .toDetachLoadBalancerTargetGroups()
* - .toDetachLoadBalancers()
* - .toDetachTrafficSources()
* - .toDisableMetricsCollection()
* - .toEnableMetricsCollection()
* - .toEnterStandby()
* - .toExecutePolicy()
* - .toExitStandby()
* - .toLaunchInstances()
* - .toPutLifecycleHook()
* - .toPutNotificationConfiguration()
* - .toPutScalingPolicy()
* - .toPutScheduledUpdateGroupAction()
* - .toPutWarmPool()
* - .toRecordLifecycleActionHeartbeat()
* - .toResumeProcesses()
* - .toRollbackInstanceRefresh()
* - .toSetDesiredCapacity()
* - .toSetInstanceHealth()
* - .toSetInstanceProtection()
* - .toStartInstanceRefresh()
* - .toSuspendProcesses()
* - .toTerminateInstanceInAutoScalingGroup()
* - .toUpdateAutoScalingGroup()
*
* Applies to resource types:
* - autoScalingGroup
*
* @param tagKey The tag key to check
* @param value The value(s) to check
* @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike`
*/
ifAwsResourceTag(tagKey, value, operator) {
return this.if(`aws:ResourceTag/${tagKey}`, value, operator ?? 'StringLike');
}
/**
* Filters access based on the tag keys that are passed in the request
*
* https://docs.aws.amazon.com/autoscaling/latest/userguide/control-access-using-iam.html#policy-auto-scaling-condition-keys
*
* Applies to actions:
* - .toCreateAutoScalingGroup()
* - .toCreateOrUpdateTags()
* - .toDeleteTags()
*
* @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');
}
}
exports.Autoscaling = Autoscaling;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWMyYXV0b3NjYWxpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJlYzJhdXRvc2NhbGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSx5Q0FBeUQ7QUFFekQ7Ozs7R0FJRztBQUNILE1BQWEsV0FBWSxTQUFRLHdCQUFlO0lBRzlDOzs7O09BSUc7SUFDSCxZQUFZLEdBQVk7UUFDdEIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBUk4sa0JBQWEsR0FBRyxhQUFhLENBQUM7UUFrMEIzQixvQkFBZSxHQUFvQjtZQUMzQyxLQUFLLEVBQUU7Z0JBQ0wsaUJBQWlCO2dCQUNqQixnQ0FBZ0M7Z0JBQ2hDLHFCQUFxQjtnQkFDckIsc0JBQXNCO2dCQUN0Qiw0QkFBNEI7Z0JBQzVCLG9DQUFvQztnQkFDcEMsdUJBQXVCO2dCQUN2Qix5QkFBeUI7Z0JBQ3pCLHdCQUF3QjtnQkFDeEIsMkJBQTJCO2dCQUMzQix3QkFBd0I7Z0JBQ3hCLDJCQUEyQjtnQkFDM0IscUJBQXFCO2dCQUNyQixpQ0FBaUM7Z0JBQ2pDLGNBQWM7Z0JBQ2QsdUJBQXVCO2dCQUN2QixnQkFBZ0I7Z0JBQ2hCLGlCQUFpQjtnQkFDakIsZ0NBQWdDO2dCQUNoQyxxQkFBcUI7Z0JBQ3JCLHNCQUFzQjtnQkFDdEIsMEJBQTBCO2dCQUMxQix5QkFBeUI7Z0JBQ3pCLGNBQWM7Z0JBQ2QsZUFBZTtnQkFDZixhQUFhO2dCQUNiLGlCQUFpQjtnQkFDakIsbUJBQW1CO2dCQUNuQixrQkFBa0I7Z0JBQ2xCLDhCQUE4QjtnQkFDOUIsa0JBQWtCO2dCQUNsQiwrQkFBK0I7Z0JBQy9CLGFBQWE7Z0JBQ2IsZ0NBQWdDO2dCQUNoQyxpQkFBaUI7Z0JBQ2pCLHlCQUF5QjtnQkFDekIsb0JBQW9CO2dCQUNwQixtQkFBbUI7Z0JBQ25CLHVCQUF1QjtnQkFDdkIsc0JBQXNCO2dCQUN0QixrQkFBa0I7Z0JBQ2xCLHFDQUFxQztnQkFDckMsd0JBQXdCO2FBQ3pCO1lBQ0QsT0FBTyxFQUFFO2dCQUNQ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LGdCQUFnQixDQUFDLE1BQWMsRUFBRSxLQUF3QixFQUFFLFFBQTRCO1FBQzVGLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxtQkFBb0IsTUFBTyxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsSUFBSSxZQUFZLENBQUMsQ0FBQztJQUNqRixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0ksWUFBWSxDQUFDLEtBQXdCLEVBQUUsUUFBNEI7UUFDeEUsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxLQUFLLEVBQUUsUUFBUSxJQUFJLFlBQVksQ0FBQyxDQUFDO0lBQ2pFLENBQUM7Q0FDRjtBQTcyQ0Qsa0NBNjJDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFjY2Vzc0xldmVsTGlzdCB9IGZyb20gJy4uLy4uL3NoYXJlZC9hY2Nlc3MtbGV2ZWwnO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50LCBPcGVyYXRvciB9IGZyb20gJy4uLy4uL3NoYXJlZCc7XG5cbi8qKlxuICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFthdXRvc2NhbGluZ10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYW1hem9uZWMyYXV0b3NjYWxpbmcuaHRtbCkuXG4gKlxuICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBBdXRvc2NhbGluZyBleHRlbmRzIFBvbGljeVN0YXRlbWVudCB7XG4gIHB1YmxpYyBzZXJ2aWNlUHJlZml4ID0gJ2F1dG9zY2FsaW5nJztcblxuICAvKipcbiAgICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFthdXRvc2NhbGluZ10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYW1hem9uZWMyYXV0b3NjYWxpbmcuaHRtbCkuXG4gICAqXG4gICAqIEBwYXJhbSBzaWQgW1NJRF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19zaWQuaHRtbCkgb2YgdGhlIHN0YXRlbWVudFxuICAgKi9cbiAgY29uc3RydWN0b3Ioc2lkPzogc3RyaW5nKSB7XG4gICAgc3VwZXIoc2lkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhdHRhY2ggb25lIG9yIG1vcmUgRUMyIGluc3RhbmNlcyB0byB0aGUgc3BlY2lmaWVkIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9BdHRhY2hJbnN0YW5jZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQXR0YWNoSW5zdGFuY2VzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdBdHRhY2hJbnN0YW5jZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhdHRhY2ggb25lIG9yIG1vcmUgdGFyZ2V0IGdyb3VwcyB0byB0aGUgc3BlY2lmaWVkIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmVGFyZ2V0R3JvdXBBUk5zKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0F0dGFjaExvYWRCYWxhbmNlclRhcmdldEdyb3Vwcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9BdHRhY2hMb2FkQmFsYW5jZXJUYXJnZXRHcm91cHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0F0dGFjaExvYWRCYWxhbmNlclRhcmdldEdyb3VwcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGF0dGFjaCBvbmUgb3IgbW9yZSBsb2FkIGJhbGFuY2VycyB0byB0aGUgc3BlY2lmaWVkIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmTG9hZEJhbGFuY2VyTmFtZXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQXR0YWNoTG9hZEJhbGFuY2Vycy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9BdHRhY2hMb2FkQmFsYW5jZXJzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdBdHRhY2hMb2FkQmFsYW5jZXJzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYXR0YWNoIG9uZSBvciBtb3JlIHRyYWZmaWMgc291cmNlcyB0byBhbiBBdXRvIFNjYWxpbmcgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlRyYWZmaWNTb3VyY2VJZGVudGlmaWVycygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9BdHRhY2hUcmFmZmljU291cmNlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9BdHRhY2hUcmFmZmljU291cmNlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQXR0YWNoVHJhZmZpY1NvdXJjZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgdGhlIHNwZWNpZmllZCBzY2hlZHVsZWQgYWN0aW9uc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9CYXRjaERlbGV0ZVNjaGVkdWxlZEFjdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9CYXRjaERlbGV0ZVNjaGVkdWxlZEFjdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQmF0Y2hEZWxldGVTY2hlZHVsZWRBY3Rpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgb3IgdXBkYXRlIG11bHRpcGxlIHNjaGVkdWxlZCBzY2FsaW5nIGFjdGlvbnMgZm9yIGFuIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9CYXRjaFB1dFNjaGVkdWxlZFVwZGF0ZUdyb3VwQWN0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0JhdGNoUHV0U2NoZWR1bGVkVXBkYXRlR3JvdXBBY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0JhdGNoUHV0U2NoZWR1bGVkVXBkYXRlR3JvdXBBY3Rpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjYW5jZWwgYW4gaW5zdGFuY2UgcmVmcmVzaCBvcGVyYXRpb24gaW4gcHJvZ3Jlc3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ2FuY2VsSW5zdGFuY2VSZWZyZXNoLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NhbmNlbEluc3RhbmNlUmVmcmVzaCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ2FuY2VsSW5zdGFuY2VSZWZyZXNoJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY29tcGxldGUgdGhlIGxpZmVjeWNsZSBhY3Rpb24gZm9yIHRoZSBzcGVjaWZpZWQgdG9rZW4gb3IgaW5zdGFuY2Ugd2l0aCB0aGUgc3BlY2lmaWVkIHJlc3VsdFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9Db21wbGV0ZUxpZmVjeWNsZUFjdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9Db21wbGV0ZUxpZmVjeWNsZUFjdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ29tcGxldGVMaWZlY3ljbGVBY3Rpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYW4gQXV0byBTY2FsaW5nIGdyb3VwIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIGFuZCBhdHRyaWJ1dGVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZJbWFnZUlkKClcbiAgICogLSAuaWZDYXBhY2l0eVJlc2VydmF0aW9uSWRzKClcbiAgICogLSAuaWZDYXBhY2l0eVJlc2VydmF0aW9uUmVzb3VyY2VHcm91cEFybnMoKVxuICAgKiAtIC5pZkluc3RhbmNlVHlwZXMoKVxuICAgKiAtIC5pZkxhdW5jaENvbmZpZ3VyYXRpb25OYW1lKClcbiAgICogLSAuaWZMYXVuY2hUZW1wbGF0ZVZlcnNpb25TcGVjaWZpZWQoKVxuICAgKiAtIC5pZkxvYWRCYWxhbmNlck5hbWVzKClcbiAgICogLSAuaWZNYXhTaXplKClcbiAgICogLSAuaWZNaW5TaXplKClcbiAgICogLSAuaWZUYXJnZXRHcm91cEFSTnMoKVxuICAgKiAtIC5pZlRyYWZmaWNTb3VyY2VJZGVudGlmaWVycygpXG4gICAqIC0gLmlmVlBDWm9uZUlkZW50aWZpZXJzKClcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gaWFtOkNyZWF0ZVNlcnZpY2VMaW5rZWRSb2xlXG4gICAqIC0gaWFtOlBhc3NSb2xlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVBdXRvU2NhbGluZ0dyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZUF1dG9TY2FsaW5nR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZUF1dG9TY2FsaW5nR3JvdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBsYXVuY2ggY29uZmlndXJhdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmSW1hZ2VJZCgpXG4gICAqIC0gLmlmSW5zdGFuY2VUeXBlKClcbiAgICogLSAuaWZTcG90UHJpY2UoKVxuICAgKiAtIC5pZk1ldGFkYXRhSHR0cFRva2VucygpXG4gICAqIC0gLmlmTWV0YWRhdGFIdHRwUHV0UmVzcG9uc2VIb3BMaW1pdCgpXG4gICAqIC0gLmlmTWV0YWRhdGFIdHRwRW5kcG9pbnQoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlTGF1bmNoQ29uZmlndXJhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVMYXVuY2hDb25maWd1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVMYXVuY2hDb25maWd1cmF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIG9yIHVwZGF0ZSB0YWdzIGZvciB0aGUgc3BlY2lmaWVkIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZU9yVXBkYXRlVGFncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVPclVwZGF0ZVRhZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZU9yVXBkYXRlVGFncycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSB0aGUgc3BlY2lmaWVkIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVBdXRvU2NhbGluZ0dyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZUF1dG9TY2FsaW5nR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZUF1dG9TY2FsaW5nR3JvdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgdGhlIHNwZWNpZmllZCBsYXVuY2ggY29uZmlndXJhdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVMYXVuY2hDb25maWd1cmF0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZUxhdW5jaENvbmZpZ3VyYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZUxhdW5jaENvbmZpZ3VyYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGVzIHRoZSBzcGVjaWZpZWQgbGlmZWN5Y2xlIGhvb2tcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlTGlmZWN5Y2xlSG9vay5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVMaWZlY3ljbGVIb29rKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVMaWZlY3ljbGVIb29rJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIHRoZSBzcGVjaWZpZWQgbm90aWZpY2F0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZU5vdGlmaWNhdGlvbkNvbmZpZ3VyYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlTm90aWZpY2F0aW9uQ29uZmlndXJhdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlTm90aWZpY2F0aW9uQ29uZmlndXJhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSB0aGUgc3BlY2lmaWVkIEF1dG8gU2NhbGluZyBwb2xpY3lcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlUG9saWN5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVBvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlUG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIHRoZSBzcGVjaWZpZWQgc2NoZWR1bGVkIGFjdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVTY2hlZHVsZWRBY3Rpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlU2NoZWR1bGVkQWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVTY2hlZHVsZWRBY3Rpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgdGhlIHNwZWNpZmllZCB0YWdzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlVGFncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVUYWdzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVUYWdzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIHRoZSB3YXJtIHBvb2wgYXNzb2NpYXRlZCB3aXRoIHRoZSBBdXRvIFNjYWxpbmcgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlV2FybVBvb2wuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlV2FybVBvb2woKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVdhcm1Qb29sJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIGN1cnJlbnQgQXV0byBTY2FsaW5nIHJlc291cmNlIGxpbWl0cyBmb3IgeW91ciBBV1MgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlQWNjb3VudExpbWl0cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUFjY291bnRMaW1pdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlQWNjb3VudExpbWl0cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSBjdXJyZW50IEFtYXpvbiBFQzIgQXV0byBTY2FsaW5nIGFjY291bnQgc2V0dGluZ3MgZm9yIHlvdXIgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlQWNjb3VudFNldHRpbmdzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlQWNjb3VudFNldHRpbmdzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUFjY291bnRTZXR0aW5ncycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSBwb2xpY3kgYWRqdXN0bWVudCB0eXBlcyBmb3IgdXNlIHdpdGggUHV0U2NhbGluZ1BvbGljeVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlQWRqdXN0bWVudFR5cGVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlQWRqdXN0bWVudFR5cGVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUFkanVzdG1lbnRUeXBlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIG9uZSBvciBtb3JlIEF1dG8gU2NhbGluZyBncm91cHMuIElmIGEgbGlzdCBvZiBuYW1lcyBpcyBub3QgcHJvdmlkZWQsIHRoZSBjYWxsIGRlc2NyaWJlcyBhbGwgQXV0byBTY2FsaW5nIGdyb3Vwc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlQXV0b1NjYWxpbmdHcm91cHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVBdXRvU2NhbGluZ0dyb3VwcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVBdXRvU2NhbGluZ0dyb3VwcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIG9uZSBvciBtb3JlIEF1dG8gU2NhbGluZyBpbnN0YW5jZXMuIElmIGEgbGlzdCBpcyBub3QgcHJvdmlkZWQsIHRoZSBjYWxsIGRlc2NyaWJlcyBhbGwgaW5zdGFuY2VzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVBdXRvU2NhbGluZ0luc3RhbmNlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUF1dG9TY2FsaW5nSW5zdGFuY2VzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUF1dG9TY2FsaW5nSW5zdGFuY2VzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIG5vdGlmaWNhdGlvbiB0eXBlcyB0aGF0IGFyZSBzdXBwb3J0ZWQgYnkgQXV0byBTY2FsaW5nXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVBdXRvU2NhbGluZ05vdGlmaWNhdGlvblR5cGVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlQXV0b1NjYWxpbmdOb3RpZmljYXRpb25UeXBlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVBdXRvU2NhbGluZ05vdGlmaWNhdGlvblR5cGVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgb25lIG9yIG1vcmUgaW5zdGFuY2UgcmVmcmVzaGVzIGZvciBhbiBBdXRvIFNjYWxpbmcgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUluc3RhbmNlUmVmcmVzaGVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlSW5zdGFuY2VSZWZyZXNoZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlSW5zdGFuY2VSZWZyZXNoZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSBvbmUgb3IgbW9yZSBsYXVuY2ggY29uZmlndXJhdGlvbnMuIElmIHlvdSBvbWl0IHRoZSBsaXN0IG9mIG5hbWVzLCB0aGVuIHRoZSBjYWxsIGRlc2NyaWJlcyBhbGwgbGF1bmNoIGNvbmZpZ3VyYXRpb25zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVMYXVuY2hDb25maWd1cmF0aW9ucy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUxhdW5jaENvbmZpZ3VyYXRpb25zKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUxhdW5jaENvbmZpZ3VyYXRpb25zJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIGF2YWlsYWJsZSB0eXBlcyBvZiBsaWZlY3ljbGUgaG9va3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUxpZmVjeWNsZUhvb2tUeXBlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUxpZmVjeWNsZUhvb2tUeXBlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVMaWZlY3ljbGVIb29rVHlwZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgbGlmZWN5Y2xlIGhvb2tzIGZvciB0aGUgc3BlY2lmaWVkIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlTGlmZWN5Y2xlSG9va3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVMaWZlY3ljbGVIb29rcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVMaWZlY3ljbGVIb29rcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSB0YXJnZXQgZ3JvdXBzIGZvciB0aGUgc3BlY2lmaWVkIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlTG9hZEJhbGFuY2VyVGFyZ2V0R3JvdXBzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlTG9hZEJhbGFuY2VyVGFyZ2V0R3JvdXBzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUxvYWRCYWxhbmNlclRhcmdldEdyb3VwcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSBsb2FkIGJhbGFuY2VycyBmb3IgdGhlIHNwZWNpZmllZCBBdXRvIFNjYWxpbmcgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUxvYWRCYWxhbmNlcnMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVMb2FkQmFsYW5jZXJzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUxvYWRCYWxhbmNlcnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgYXZhaWxhYmxlIENsb3VkV2F0Y2ggbWV0cmljcyBmb3IgQXV0byBTY2FsaW5nXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVNZXRyaWNDb2xsZWN0aW9uVHlwZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVNZXRyaWNDb2xsZWN0aW9uVHlwZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlTWV0cmljQ29sbGVjdGlvblR5cGVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIG5vdGlmaWNhdGlvbiBhY3Rpb25zIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlTm90aWZpY2F0aW9uQ29uZmlndXJhdGlvbnMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVOb3RpZmljYXRpb25Db25maWd1cmF0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVOb3RpZmljYXRpb25Db25maWd1cmF0aW9ucycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSBwb2xpY2llcyBmb3IgdGhlIHNwZWNpZmllZCBBdXRvIFNjYWxpbmcgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVBvbGljaWVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlUG9saWNpZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlUG9saWNpZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSBvbmUgb3IgbW9yZSBzY2FsaW5nIGFjdGl2aXRpZXMgZm9yIHRoZSBzcGVjaWZpZWQgQXV0byBTY2FsaW5nIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVTY2FsaW5nQWN0aXZpdGllcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVNjYWxpbmdBY3Rpdml0aWVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVNjYWxpbmdBY3Rpdml0aWVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIHNjYWxpbmcgcHJvY2VzcyB0eXBlcyBmb3IgdXNlIHdpdGggUmVzdW1lUHJvY2Vzc2VzIGFuZCBTdXNwZW5kUHJvY2Vzc2VzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVTY2FsaW5nUHJvY2Vzc1R5cGVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlU2NhbGluZ1Byb2Nlc3NUeXBlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVTY2FsaW5nUHJvY2Vzc1R5cGVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIGFjdGlvbnMgc2NoZWR1bGVkIGZvciB5b3VyIEF1dG8gU2NhbGluZyBncm91cCB0aGF0IGhhdmVuJ3QgcnVuXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVTY2hlZHVsZWRBY3Rpb25zLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlU2NoZWR1bGVkQWN0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVTY2hlZHVsZWRBY3Rpb25zJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIHNwZWNpZmllZCB0YWdzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVUYWdzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlVGFncygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVUYWdzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIHRlcm1pbmF0aW9uIHBvbGljaWVzIHN1cHBvcnRlZCBieSBBdXRvIFNjYWxpbmdcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVRlcm1pbmF0aW9uUG9saWN5VHlwZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVUZXJtaW5hdGlvblBvbGljeVR5cGVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVRlcm1pbmF0aW9uUG9saWN5VHlwZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgdGFyZ2V0IGdyb3VwcyBmb3IgdGhlIHNwZWNpZmllZCBBdXRvIFNjYWxpbmcgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVRyYWZmaWNTb3VyY2VzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlVHJhZmZpY1NvdXJjZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlVHJhZmZpY1NvdXJjZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgd2FybSBwb29sIGFzc29jaWF0ZWQgd2l0aCB0aGUgQXV0byBTY2FsaW5nIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVXYXJtUG9vbC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVdhcm1Qb29sKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVdhcm1Qb29sJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIG9uZSBvciBtb3JlIGluc3RhbmNlcyBmcm9tIHRoZSBzcGVjaWZpZWQgQXV0byBTY2FsaW5nIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RldGFjaEluc3RhbmNlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXRhY2hJbnN0YW5jZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RldGFjaEluc3RhbmNlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRldGFjaCBvbmUgb3IgbW9yZSB0YXJnZXQgZ3JvdXBzIGZyb20gdGhlIHNwZWNpZmllZCBBdXRvIFNjYWxpbmcgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZlRhcmdldEdyb3VwQVJOcygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXRhY2hMb2FkQmFsYW5jZXJUYXJnZXRHcm91cHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGV0YWNoTG9hZEJhbGFuY2VyVGFyZ2V0R3JvdXBzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXRhY2hMb2FkQmFsYW5jZXJUYXJnZXRHcm91cHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgb25lIG9yIG1vcmUgbG9hZCBiYWxhbmNlcnMgZnJvbSB0aGUgc3BlY2lmaWVkIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmTG9hZEJhbGFuY2VyTmFtZXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGV0YWNoTG9hZEJhbGFuY2Vycy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXRhY2hMb2FkQmFsYW5jZXJzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXRhY2hMb2FkQmFsYW5jZXJzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGV0YWNoIG9uZSBvciBtb3JlIHRyYWZmaWMgc291cmNlcyBmcm9tIGFuIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmVHJhZmZpY1NvdXJjZUlkZW50aWZpZXJzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RldGFjaFRyYWZmaWNTb3VyY2VzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RldGFjaFRyYWZmaWNTb3VyY2VzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXRhY2hUcmFmZmljU291cmNlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRpc2FibGUgbW9uaXRvcmluZyBvZiB0aGUgc3BlY2lmaWVkIG1ldHJpY3MgZm9yIHRoZSBzcGVjaWZpZWQgQXV0byBTY2FsaW5nIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rpc2FibGVNZXRyaWNzQ29sbGVjdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EaXNhYmxlTWV0cmljc0NvbGxlY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rpc2FibGVNZXRyaWNzQ29sbGVjdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGVuYWJsZSBtb25pdG9yaW5nIG9mIHRoZSBzcGVjaWZpZWQgbWV0cmljcyBmb3IgdGhlIHNwZWNpZmllZCBBdXRvIFNjYWxpbmcgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRW5hYmxlTWV0cmljc0NvbGxlY3Rpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRW5hYmxlTWV0cmljc0NvbGxlY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0VuYWJsZU1ldHJpY3NDb2xsZWN0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbW92ZSB0aGUgc3BlY2lmaWVkIGluc3RhbmNlcyBpbnRvIFN0YW5kYnkgbW9kZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9FbnRlclN0YW5kYnkuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRW50ZXJTdGFuZGJ5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdFbnRlclN0YW5kYnknKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBleGVjdXRlIHRoZSBzcGVjaWZpZWQgcG9saWN5XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0V4ZWN1dGVQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRXhlY3V0ZVBvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRXhlY3V0ZVBvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIG1vdmUgdGhlIHNwZWNpZmllZCBpbnN0YW5jZXMgb3V0IG9mIFN0YW5kYnkgbW9kZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9FeGl0U3RhbmRieS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9FeGl0U3RhbmRieSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRXhpdFN0YW5kYnknKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXRyaWV2ZSB0aGUgZm9yZWNhc3QgZGF0YSBmb3IgYSBwcmVkaWN0aXZlIHNjYWxpbmcgcG9saWN5XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0UHJlZGljdGl2ZVNjYWxpbmdGb3JlY2FzdC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRQcmVkaWN0aXZlU2NhbGluZ0ZvcmVjYXN0KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRQcmVkaWN0aXZlU2NhbGluZ0ZvcmVjYXN0Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGF1bmNoIG9uZSBvciBtb3JlIEVDMiBpbnN0YW5jZXMgaW4gdGhlIHNwZWNpZmllZCBBdXRvIFNjYWxpbmcgZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGF1bmNoSW5zdGFuY2VzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xhdW5jaEluc3RhbmNlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGF1bmNoSW5zdGFuY2VzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbW9kaWZ5IGFuIGFjY291bnQgc2V0dGluZyBmb3IgeW91ciBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1B1dEFjY291bnRTZXR0aW5nLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1B1dEFjY291bnRTZXR0aW5nKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdQdXRBY2NvdW50U2V0dGluZycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBvciB1cGRhdGUgYSBsaWZlY3ljbGUgaG9vayBmb3IgdGhlIHNwZWNpZmllZCBBdXRvIFNjYWxpbmcgR3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUHV0TGlmZWN5Y2xlSG9vay5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9QdXRMaWZlY3ljbGVIb29rKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdQdXRMaWZlY3ljbGVIb29rJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY29uZmlndXJlIGFuIEF1dG8gU2NhbGluZyBncm91cCB0byBzZW5kIG5vdGlmaWNhdGlvbnMgd2hlbiBzcGVjaWZpZWQgZXZlbnRzIHRha2UgcGxhY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUHV0Tm90aWZpY2F0aW9uQ29uZmlndXJhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9QdXROb3RpZmljYXRpb25Db25maWd1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdQdXROb3RpZmljYXRpb25Db25maWd1cmF0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIG9yIHVwZGF0ZSBhIHBvbGljeSBmb3IgYW4gQXV0byBTY2FsaW5nIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1B1dFNjYWxpbmdQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUHV0U2NhbGluZ1BvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUHV0U2NhbGluZ1BvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBvciB1cGRhdGUgYSBzY2hlZHVsZWQgc2NhbGluZyBhY3Rpb24gZm9yIGFuIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmTWF4U2l6ZSgpXG4gICAqIC0gLmlmTWluU2l6ZSgpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9QdXRTY2hlZHVsZWRVcGRhdGVHcm91cEFjdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9QdXRTY2hlZHVsZWRVcGRhdGVHcm91cEFjdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUHV0U2NoZWR1bGVkVXBkYXRlR3JvdXBBY3Rpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgb3IgdXBkYXRlIHRoZSB3YXJtIHBvb2wgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgQXV0byBTY2FsaW5nIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1B1dFdhcm1Qb29sLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1B1dFdhcm1Qb29sKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdQdXRXYXJtUG9vbCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlY29yZCBhIGhlYXJ0YmVhdCBmb3IgdGhlIGxpZmVjeWNsZSBhY3Rpb24gYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgdG9rZW4gb3IgaW5zdGFuY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUmVjb3JkTGlmZWN5Y2xlQWN0aW9uSGVhcnRiZWF0Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlY29yZExpZmVjeWNsZUFjdGlvbkhlYXJ0YmVhdCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUmVjb3JkTGlmZWN5Y2xlQWN0aW9uSGVhcnRiZWF0Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVzdW1lIHRoZSBzcGVjaWZpZWQgc3VzcGVuZGVkIEF1dG8gU2NhbGluZyBwcm9jZXNzZXMsIG9yIGFsbCBzdXNwZW5kZWQgcHJvY2VzcywgZm9yIHRoZSBzcGVjaWZpZWQgQXV0byBTY2FsaW5nIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1Jlc3VtZVByb2Nlc3Nlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9SZXN1bWVQcm9jZXNzZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1Jlc3VtZVByb2Nlc3NlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJvbGxiYWNrIGFuIGluc3RhbmNlIHJlZnJlc2ggb3BlcmF0aW9uIGluIHByb2dyZXNzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0F1dG9TY2FsaW5nL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1JvbGxiYWNrSW5zdGFuY2VSZWZyZXNoLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JvbGxiYWNrSW5zdGFuY2VSZWZyZXNoKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdSb2xsYmFja0luc3RhbmNlUmVmcmVzaCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHNldCB0aGUgc2l6ZSBvZiB0aGUgc3BlY2lmaWVkIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9TZXREZXNpcmVkQ2FwYWNpdHkuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvU2V0RGVzaXJlZENhcGFjaXR5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTZXREZXNpcmVkQ2FwYWNpdHknKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBzZXQgdGhlIGhlYWx0aCBzdGF0dXMgb2YgdGhlIHNwZWNpZmllZCBpbnN0YW5jZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9TZXRJbnN0YW5jZUhlYWx0aC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9TZXRJbnN0YW5jZUhlYWx0aCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnU2V0SW5zdGFuY2VIZWFsdGgnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgdGhlIGluc3RhbmNlIHByb3RlY3Rpb24gc2V0dGluZ3Mgb2YgdGhlIHNwZWNpZmllZCBpbnN0YW5jZXNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfU2V0SW5zdGFuY2VQcm90ZWN0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1NldEluc3RhbmNlUHJvdGVjdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnU2V0SW5zdGFuY2VQcm90ZWN0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gc3RhcnQgYSBuZXcgaW5zdGFuY2UgcmVmcmVzaCBvcGVyYXRpb25cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkltYWdlSWQoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfU3RhcnRJbnN0YW5jZVJlZnJlc2guaHRtbFxuICAgKi9cbiAgcHVibGljIHRvU3RhcnRJbnN0YW5jZVJlZnJlc2goKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1N0YXJ0SW5zdGFuY2VSZWZyZXNoJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gc3VzcGVuZCB0aGUgc3BlY2lmaWVkIEF1dG8gU2NhbGluZyBwcm9jZXNzZXMsIG9yIGFsbCBwcm9jZXNzZXMsIGZvciB0aGUgc3BlY2lmaWVkIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9TdXNwZW5kUHJvY2Vzc2VzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1N1c3BlbmRQcm9jZXNzZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1N1c3BlbmRQcm9jZXNzZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB0ZXJtaW5hdGUgdGhlIHNwZWNpZmllZCBpbnN0YW5jZSBhbmQgb3B0aW9uYWxseSBhZGp1c3QgdGhlIGRlc2lyZWQgZ3JvdXAgc2l6ZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BdXRvU2NhbGluZy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9UZXJtaW5hdGVJbnN0YW5jZUluQXV0b1NjYWxpbmdHcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9UZXJtaW5hdGVJbnN0YW5jZUluQXV0b1NjYWxpbmdHcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVGVybWluYXRlSW5zdGFuY2VJbkF1dG9TY2FsaW5nR3JvdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgdGhlIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBzcGVjaWZpZWQgQXV0byBTY2FsaW5nIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZJbWFnZUlkKClcbiAgICogLSAuaWZDYXBhY2l0eVJlc2VydmF0aW9uSWRzKClcbiAgICogLSAuaWZDYXBhY2l0eVJlc2VydmF0aW9uUmVzb3VyY2VHcm91cEFybnMoKVxuICAgKiAtIC5pZkluc3RhbmNlVHlwZXMoKVxuICAgKiAtIC5pZkxhdW5jaENvbmZpZ3VyYXRpb25OYW1lKClcbiAgICogLSAuaWZMYXVuY2hUZW1wbGF0ZVZlcnNpb25TcGVjaWZpZWQoKVxuICAgKiAtIC5pZk1heFNpemUoKVxuICAgKiAtIC5pZk1pblNpemUoKVxuICAgKiAtIC5pZlZQQ1pvbmVJZGVudGlmaWVycygpXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIGlhbTpQYXNzUm9sZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQXV0b1NjYWxpbmcvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlQXV0b1NjYWxpbmdHcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVBdXRvU2NhbGluZ0dyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVBdXRvU2NhbGluZ0dyb3VwJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWNjZXNzTGV2ZWxMaXN0OiBBY2Nlc3NMZXZlbExpc3QgPSB7XG4gICAgV3JpdGU6IFtcbiAgICAgICdBdHRhY2hJbnN0YW5jZXMnLFxuICAgICAgJ0F0dGFjaExvYWRCYWxhbmNlclRhcmdldEdyb3VwcycsXG4gICAgICAnQXR0YWNoTG9hZEJhbGFuY2VycycsXG4gICAgICAnQXR0YWNoVHJhZmZpY1NvdXJjZXMnLFxuICAgICAgJ0JhdGNoRGVsZXRlU2NoZWR1bGVkQWN0aW9uJyxcbiAgICAgICdCYXRjaFB1dFNjaGVkdWxlZFVwZGF0ZUdyb3VwQWN0aW9uJyxcbiAgICAgICdDYW5jZWxJbnN0YW5jZVJlZnJlc2gnLFxuICAgICAgJ0NvbXBsZXRlTGlmZWN5Y2xlQWN0aW9uJyxcbiAgICAgICdDcmVhdGVBdXRvU2NhbGluZ0dyb3VwJyxcbiAgICAgICdDcmVhdGVMYXVuY2hDb25maWd1cmF0aW9uJyxcbiAgICAgICdEZWxldGVBdXRvU2NhbGluZ0dyb3VwJyxcbiAgICAgICdEZWxldGVMYXVuY2hDb25maWd1cmF0aW9uJyxcbiAgICAgICdEZWxldGVMaWZlY3ljbGVIb29rJyxcbiAgICAgICdEZWxldGVOb3RpZmljYXRpb25Db25maWd1cmF0aW9uJyxcbiAgICAgICdEZWxldGVQb2xpY3knLFxuICAgICAgJ0RlbGV0ZVNjaGVkdWxlZEFjdGlvbicsXG4gICAgICAnRGVsZXRlV2FybVBvb2wnLFxuICAgICAgJ0RldGFjaEluc3RhbmNlcycsXG4gICAgICAnRGV0YWNoTG9hZEJhbGFuY2VyVGFyZ2V0R3JvdXBzJyxcbiAgICAgICdEZXRhY2hMb2FkQmFsYW5jZXJzJyxcbiAgICAgICdEZXRhY2hUcmFmZmljU291cmNlcycsXG4gICAgICAnRGlzYWJsZU1ldHJpY3NDb2xsZWN0aW9uJyxcbiAgICAgICdFbmFibGVNZXRyaWNzQ29sbGVjdGlvbicsXG4gICAgICAnRW50ZXJTdGFuZGJ5JyxcbiAgICAgICdFeGVjdXRlUG9saWN5JyxcbiAgICAgICdFeGl0U3RhbmRieScsXG4gICAgICAnTGF1bmNoSW5zdGFuY2VzJyxcbiAgICAgICdQdXRBY2NvdW50U2V0dGluZycsXG4gICAgICAnUHV0TGlmZWN5Y2xlSG9vaycsXG4gICAgICAnUHV0Tm90aWZpY2F0aW9uQ29uZmlndXJhdGlvbicsXG4gICAgICAnUHV0U2NhbGluZ1BvbGljeScsXG4gICAgICAnUHV0U2NoZWR1bGVkVXBkYXRlR3JvdXBBY3Rpb24nLFxuICAgICAgJ1B1dFdhcm1Qb29sJyxcbiAgICAgICdSZWNvcmRMaWZlY3ljbGVBY3Rpb25IZWFydGJlYXQnLFxuICAgICAgJ1Jlc3VtZVByb2Nlc3NlcycsXG4gICAgICAnUm9sbGJhY2tJbnN0YW5jZVJlZnJlc2gnLFxuICAgICAgJ1NldERlc2lyZWRDYXBhY2l0eScsXG4gICAgICAnU2V0SW5zdGFuY2VIZWFsdGgnLFxuICAgICAgJ1NldEluc3RhbmNlUHJvdGVjdGlvbicsXG4gICAgICAnU3RhcnRJbnN0YW5jZVJlZnJlc2gnLFxuICAgICAgJ1N1c3BlbmRQcm9jZXNzZXMnLFxuICAgICAgJ1Rlcm1pbmF0ZUluc3RhbmNlSW5BdXRvU2NhbGluZ0dyb3VwJyxcbiAgICAgICdVcGRhdGVBdXRvU2NhbGluZ0dyb3VwJ1xuICAgIF0sXG4gICAgVGFnZ2luZzogW1xuICAgICAgJ0NyZWF0ZU9yVXBkYXRlVGFncycsXG4gICAgICAnRGVsZXRlVGFncydcbiAgICBdLFxuICAgIExpc3Q6IFtcbiAgICAgICdEZXNjcmliZUFjY291bnRMaW1pdHMnLFxuICAgICAgJ0Rlc2NyaWJlQWNjb3VudFNldHRpbmdzJyxcbiAgICAgICdEZXNjcmliZUFkanVzdG1lbnRUeXBlcycsXG4gICAgICAnRGVzY3JpYmVBdXRvU2NhbGluZ0dyb3VwcycsXG4gICAgICAnRGVzY3JpYmVBdXRvU2NhbGluZ0luc3RhbmNlcycsXG4gICAgICAnRGVzY3JpYmVBdXRvU2NhbGluZ05vdGlmaWNhdGlvblR5cGVzJyxcbiAgICAgICdEZXNjcmliZUluc3RhbmNlUmVmcmVzaGVzJyxcbiAgICAgICdEZXNjcmliZUxhdW5jaENvbmZpZ3VyYXRpb25zJyxcbiAgICAgICdEZXNjcmliZUxpZmVjeWNsZUhvb2tUeXBlcycsXG4gICAgICAnRGVzY3JpYmVMaWZlY3ljbGVIb29rcycsXG4gICAgICAnRGVzY3JpYmVMb2FkQmFsYW5jZXJUYXJnZXRHcm91cHMnLFxuICAgICAgJ0Rlc2NyaWJlTG9hZEJhbGFuY2VycycsXG4gICAgICAnRGVzY3JpYmVNZXRyaWNDb2xsZWN0aW9uVHlwZXMnLFxuICAgICAgJ0Rlc2NyaWJlTm90aWZpY2F0aW9uQ29uZmlndXJhdGlvbnMnLFxuICAgICAgJ0Rlc2NyaWJlUG9saWNpZXMnLFxuICAgICAgJ0Rlc2NyaWJlU2NhbGluZ0FjdGl2aXRpZXMnLFxuICAgICAgJ0Rlc2NyaWJlU2NhbGluZ1Byb2Nlc3NUeXBlcycsXG4gICAgICAnRGVzY3JpYmVTY2hlZHVsZWRBY3Rpb25zJyxcbiAgICAgICdEZXNjcmliZVRlcm1pbmF0aW9uUG9saWN5VHlwZXMnLFxuICAgICAgJ0Rlc2NyaWJlVHJhZmZpY1NvdXJjZXMnLFxuICAgICAgJ0Rlc2NyaWJlV2FybVBvb2wnLFxuICAgICAgJ0dldFByZWRpY3RpdmVTY2FsaW5nRm9yZWNhc3QnXG4gICAgXSxcbiAgICBSZWFkOiBbXG4gICAgICAnRGVzY3JpYmVUYWdzJ1xuICAgIF1cbiAgfTtcblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgYXV0b1NjYWxpbmdHcm91cCB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctcmVzb3VyY2VzXG4gICAqXG4gICAqIEBwYXJhbSBncm91cElkIC0gSWRlbnRpZmllciBmb3IgdGhlIGdyb3VwSWQuXG4gICAqIEBwYXJhbSBncm91cEZyaWVuZGx5TmFtZSAtIElkZW50aWZpZXIgZm9yIHRoZSBncm91cEZyaWVuZGx5TmFtZS5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmUmVzb3VyY2VUYWcoKVxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvbkF1dG9TY2FsaW5nR3JvdXAoZ3JvdXBJZDogc3RyaW5nLCBncm91cEZyaWVuZGx5TmFtZTogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OmF1dG9zY2FsaW5nOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTphdXRvU2NhbGluZ0dyb3VwOiR7IGdyb3VwSWQgfTphdXRvU2NhbGluZ0dyb3VwTmFtZS8keyBncm91cEZyaWVuZGx5TmFtZSB9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgbGF1bmNoQ29uZmlndXJhdGlvbiB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctcmVzb3VyY2VzXG4gICAqXG4gICAqIEBwYXJhbSBpZCAtIElkZW50aWZpZXIgZm9yIHRoZSBpZC5cbiAgICogQHBhcmFtIGxhdW5jaENvbmZpZ3VyYXRpb25OYW1lIC0gSWRlbnRpZmllciBmb3IgdGhlIGxhdW5jaENvbmZpZ3VyYXRpb25OYW1lLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICovXG4gIHB1YmxpYyBvbkxhdW5jaENvbmZpZ3VyYXRpb24oaWQ6IHN0cmluZywgbGF1bmNoQ29uZmlndXJhdGlvbk5hbWU6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTphdXRvc2NhbGluZzokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06bGF1bmNoQ29uZmlndXJhdGlvbjokeyBpZCB9OmxhdW5jaENvbmZpZ3VyYXRpb25OYW1lLyR7IGxhdW5jaENvbmZpZ3VyYXRpb25OYW1lIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBiYXNlZCBvbiB0aGUgQ2FwYWNpdHkgUmVzZXJ2YXRpb24gSURzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctY29uZGl0aW9uLWtleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NyZWF0ZUF1dG9TY2FsaW5nR3JvdXAoKVxuICAgKiAtIC50b1VwZGF0ZUF1dG9TY2FsaW5nR3JvdXAoKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkNhcGFjaXR5UmVzZXJ2YXRpb25JZHModmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYENhcGFjaXR5UmVzZXJ2YXRpb25JZHNgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBiYXNlZCBvbiB0aGUgQVJOIG9mIGEgQ2FwYWNpdHkgUmVzZXJ2YXRpb24gcmVzb3VyY2UgZ3JvdXBcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2F1dG9zY2FsaW5nL2xhdGVzdC91c2VyZ3VpZGUvY29udHJvbC1hY2Nlc3MtdXNpbmctaWFtLmh0bWwjcG9saWN5LWF1dG8tc2NhbGluZy1jb25kaXRpb24ta2V5c1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ3JlYXRlQXV0b1NjYWxpbmdHcm91cCgpXG4gICAqIC0gLnRvVXBkYXRlQXV0b1NjYWxpbmdHcm91cCgpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQ2FwYWNpdHlSZXNlcnZhdGlvblJlc291cmNlR3JvdXBBcm5zKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBDYXBhY2l0eVJlc2VydmF0aW9uUmVzb3VyY2VHcm91cEFybnNgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBiYXNlZCBvbiB3aGV0aGVyIHRoZSBmb3JjZSBkZWxldGUgb3B0aW9uIGlzIHNwZWNpZmllZCB3aGVuIGRlbGV0aW5nIGFuIEF1dG8gU2NhbGluZyBncm91cFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXV0b3NjYWxpbmcvbGF0ZXN0L3VzZXJndWlkZS9jb250cm9sLWFjY2Vzcy11c2luZy1pYW0uaHRtbCNwb2xpY3ktYXV0by1zY2FsaW5nLWNvbmRpdGlvbi1rZXlzXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9EZWxldGVBdXRvU2NhbGluZ0dyb3VwKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgLiAqKkRlZmF1bHQ6KiogYHRydWVgXG4gICAqL1xuICBwdWJsaWMgaWZGb3JjZURlbGV0ZSh2YWx1ZT86IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gdGhpcy5pZihgRm9yY2VEZWxldGVgLCAodHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJyA/IHZhbHVlIDogdHJ1ZSksICdCb29sJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYmFzZWQgb24gdGhlIEFNSSBJRCBmb3IgdGhlIGxhdW5jaCBjb25maWd1cmF0aW9uXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctY29uZGl0aW9uLWtleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NyZWF0ZUF1dG9TY2FsaW5nR3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZUxhdW5jaENvbmZpZ3VyYXRpb24oKVxuICAgKiAtIC50b1N0YXJ0SW5zdGFuY2VSZWZyZXNoKClcbiAgICogLSAudG9VcGRhdGVBdXRvU2NhbGluZ0dyb3VwKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZJbWFnZUlkKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBJbWFnZUlkYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYmFzZWQgb24gdGhlIGluc3RhbmNlIHR5cGUgZm9yIHRoZSBsYXVuY2ggY29uZmlndXJhdGlvblxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXV0b3NjYWxpbmcvbGF0ZXN0L3VzZXJndWlkZS9jb250cm9sLWFjY2Vzcy11c2luZy1pYW0uaHRtbCNwb2xpY3ktYXV0by1zY2FsaW5nLWNvbmRpdGlvbi1rZXlzXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVMYXVuY2hDb25maWd1cmF0aW9uKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZJbnN0YW5jZVR5cGUodmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYEluc3RhbmNlVHlwZWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJhc2VkIG9uIHRoZSBpbnN0YW5jZSB0eXBlcyBwcmVzZW50IGFzIG92ZXJyaWRlcyB0byBhIGxhdW5jaCB0ZW1wbGF0ZSBmb3IgYSBtaXhlZCBpbnN0YW5jZXMgcG9saWN5LiBVc2UgaXQgdG8gcXVhbGlmeSB3aGljaCBpbnN0YW5jZSB0eXBlcyBjYW4gYmUgZXhwbGljaXRseSBkZWZpbmVkIGluIHRoZSBwb2xpY3lcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2F1dG9zY2FsaW5nL2xhdGVzdC91c2VyZ3VpZGUvY29udHJvbC1hY2Nlc3MtdXNpbmctaWFtLmh0bWwjcG9saWN5LWF1dG8tc2NhbGluZy1jb25kaXRpb24ta2V5c1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ3JlYXRlQXV0b1NjYWxpbmdHcm91cCgpXG4gICAqIC0gLnRvVXBkYXRlQXV0b1NjYWxpbmdHcm91cCgpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmSW5zdGFuY2VUeXBlcyh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgSW5zdGFuY2VUeXBlc2AsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJhc2VkIG9uIHRoZSBuYW1lIG9mIGEgbGF1bmNoIGNvbmZpZ3VyYXRpb25cbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2F1dG9zY2FsaW5nL2xhdGVzdC91c2VyZ3VpZGUvY29udHJvbC1hY2Nlc3MtdXNpbmctaWFtLmh0bWwjcG9saWN5LWF1dG8tc2NhbGluZy1jb25kaXRpb24ta2V5c1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ3JlYXRlQXV0b1NjYWxpbmdHcm91cCgpXG4gICAqIC0gLnRvVXBkYXRlQXV0b1NjYWxpbmdHcm91cCgpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmTGF1bmNoQ29uZmlndXJhdGlvbk5hbWUodmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYExhdW5jaENvbmZpZ3VyYXRpb25OYW1lYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYmFzZWQgb24gd2hldGhlciB1c2VycyBjYW4gc3BlY2lmeSBhbnkgdmVyc2lvbiBvZiBhIGxhdW5jaCB0ZW1wbGF0ZSBvciBvbmx5IHRoZSBMYXRlc3Qgb3IgRGVmYXVsdCB2ZXJzaW9uXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctY29uZGl0aW9uLWtleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NyZWF0ZUF1dG9TY2FsaW5nR3JvdXAoKVxuICAgKiAtIC50b1VwZGF0ZUF1dG9TY2FsaW5nR3JvdXAoKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIG9yIGBmYWxzZWAuICoqRGVmYXVsdDoqKiBgdHJ1ZWBcbiAgICovXG4gIHB1YmxpYyBpZkxhdW5jaFRlbXBsYXRlVmVyc2lvblNwZWNpZmllZCh2YWx1ZT86IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gdGhpcy5pZihgTGF1bmNoVGVtcGxhdGVWZXJzaW9uU3BlY2lmaWVkYCwgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcgPyB2YWx1ZSA6IHRydWUpLCAnQm9vbCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJhc2VkIG9uIHRoZSBuYW1lIG9mIHRoZSBsb2FkIGJhbGFuY2VyXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctY29uZGl0aW9uLWtleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0F0dGFjaExvYWRCYWxhbmNlcnMoKVxuICAgKiAtIC50b0NyZWF0ZUF1dG9TY2FsaW5nR3JvdXAoKVxuICAgKiAtIC50b0RldGFjaExvYWRCYWxhbmNlcnMoKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkxvYWRCYWxhbmNlck5hbWVzKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBMb2FkQmFsYW5jZXJOYW1lc2AsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJhc2VkIG9uIHRoZSBtYXhpbXVtIHNjYWxpbmcgc2l6ZSBpbiB0aGUgcmVxdWVzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXV0b3NjYWxpbmcvbGF0ZXN0L3VzZXJndWlkZS9jb250cm9sLWFjY2Vzcy11c2luZy1pYW0uaHRtbCNwb2xpY3ktYXV0by1zY2FsaW5nLWNvbmRpdGlvbi1rZXlzXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVBdXRvU2NhbGluZ0dyb3VwKClcbiAgICogLSAudG9QdXRTY2hlZHVsZWRVcGRhdGVHcm91cEFjdGlvbigpXG4gICAqIC0gLnRvVXBkYXRlQXV0b1NjYWxpbmdHcm91cCgpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW251bWVyaWMgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX051bWVyaWMpLiAqKkRlZmF1bHQ6KiogYE51bWVyaWNFcXVhbHNgXG4gICAqL1xuICBwdWJsaWMgaWZNYXhTaXplKHZhbHVlOiBudW1iZXIgfCBudW1iZXJbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBNYXhTaXplYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdOdW1lcmljRXF1YWxzJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYmFzZWQgb24gd2hldGhlciB0aGUgSFRUUCBlbmRwb2ludCBpcyBlbmFibGVkIGZvciB0aGUgaW5zdGFuY2UgbWV0YWRhdGEgc2VydmljZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vYXV0b3NjYWxpbmcvbGF0ZXN0L3VzZXJndWlkZS9jb250cm9sLWFjY2Vzcy11c2luZy1pYW0uaHRtbCNwb2xpY3ktYXV0by1zY2FsaW5nLWNvbmRpdGlvbi1rZXlzXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVMYXVuY2hDb25maWd1cmF0aW9uKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZNZXRhZGF0YUh0dHBFbmRwb2ludCh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgTWV0YWRhdGFIdHRwRW5kcG9pbnRgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBiYXNlZCBvbiB0aGUgYWxsb3dlZCBudW1iZXIgb2YgaG9wcyB3aGVuIGNhbGxpbmcgdGhlIGluc3RhbmNlIG1ldGFkYXRhIHNlcnZpY2VcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2F1dG9zY2FsaW5nL2xhdGVzdC91c2VyZ3VpZGUvY29udHJvbC1hY2Nlc3MtdXNpbmctaWFtLmh0bWwjcG9saWN5LWF1dG8tc2NhbGluZy1jb25kaXRpb24ta2V5c1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ3JlYXRlTGF1bmNoQ29uZmlndXJhdGlvbigpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW251bWVyaWMgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX051bWVyaWMpLiAqKkRlZmF1bHQ6KiogYE51bWVyaWNFcXVhbHNgXG4gICAqL1xuICBwdWJsaWMgaWZNZXRhZGF0YUh0dHBQdXRSZXNwb25zZUhvcExpbWl0KHZhbHVlOiBudW1iZXIgfCBudW1iZXJbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBNZXRhZGF0YUh0dHBQdXRSZXNwb25zZUhvcExpbWl0YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdOdW1lcmljRXF1YWxzJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYmFzZWQgb24gd2hldGhlciB0b2tlbnMgYXJlIHJlcXVpcmVkIHdoZW4gY2FsbGluZyB0aGUgaW5zdGFuY2UgbWV0YWRhdGEgc2VydmljZSAob3B0aW9uYWwgb3IgcmVxdWlyZWQpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctY29uZGl0aW9uLWtleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NyZWF0ZUxhdW5jaENvbmZpZ3VyYXRpb24oKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZk1ldGFkYXRhSHR0cFRva2Vucyh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgTWV0YWRhdGFIdHRwVG9rZW5zYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYmFzZWQgb24gdGhlIG1pbmltdW0gc2NhbGluZyBzaXplIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctY29uZGl0aW9uLWtleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NyZWF0ZUF1dG9TY2FsaW5nR3JvdXAoKVxuICAgKiAtIC50b1B1dFNjaGVkdWxlZFVwZGF0ZUdyb3VwQWN0aW9uKClcbiAgICogLSAudG9VcGRhdGVBdXRvU2NhbGluZ0dyb3VwKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbbnVtZXJpYyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfTnVtZXJpYykuICoqRGVmYXVsdDoqKiBgTnVtZXJpY0VxdWFsc2BcbiAgICovXG4gIHB1YmxpYyBpZk1pblNpemUodmFsdWU6IG51bWJlciB8IG51bWJlcltdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYE1pblNpemVgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ051bWVyaWNFcXVhbHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBiYXNlZCBvbiB0aGUgdGFncyBhc3NvY2lhdGVkIHdpdGggdGhlIHJlc291cmNlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctY29uZGl0aW9uLWtleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0F0dGFjaEluc3RhbmNlcygpXG4gICAqIC0gLnRvQXR0YWNoTG9hZEJhbGFuY2VyVGFyZ2V0R3JvdXBzKClcbiAgICogLSAudG9BdHRhY2hMb2FkQmFsYW5jZXJzKClcbiAgICogLSAudG9BdHRhY2hUcmFmZmljU291cmNlcygpXG4gICAqIC0gLnRvQmF0Y2hEZWxldGVTY2hlZHVsZWRBY3Rpb24oKVxuICAgKiAtIC50b0JhdGNoUHV0U2NoZWR1bGVkVXBkYXRlR3JvdXBBY3Rpb24oKVxuICAgKiAtIC50b0NhbmNlbEluc3RhbmNlUmVmcmVzaCgpXG4gICAqIC0gLnRvQ29tcGxldGVMaWZlY3ljbGVBY3Rpb24oKVxuICAgKiAtIC50b0NyZWF0ZUF1dG9TY2FsaW5nR3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZU9yVXBkYXRlVGFncygpXG4gICAqIC0gLnRvRGVsZXRlQXV0b1NjYWxpbmdHcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlTGlmZWN5Y2xlSG9vaygpXG4gICAqIC0gLnRvRGVsZXRlTm90aWZpY2F0aW9uQ29uZmlndXJhdGlvbigpXG4gICAqIC0gLnRvRGVsZXRlUG9saWN5KClcbiAgICogLSAudG9EZWxldGVTY2hlZHVsZWRBY3Rpb24oKVxuICAgKiAtIC50b0RlbGV0ZVRhZ3MoKVxuICAgKiAtIC50b0RlbGV0ZVdhcm1Qb29sKClcbiAgICogLSAudG9EZXRhY2hJbnN0YW5jZXMoKVxuICAgKiAtIC50b0RldGFjaExvYWRCYWxhbmNlclRhcmdldEdyb3VwcygpXG4gICAqIC0gLnRvRGV0YWNoTG9hZEJhbGFuY2VycygpXG4gICAqIC0gLnRvRGV0YWNoVHJhZmZpY1NvdXJjZXMoKVxuICAgKiAtIC50b0Rpc2FibGVNZXRyaWNzQ29sbGVjdGlvbigpXG4gICAqIC0gLnRvRW5hYmxlTWV0cmljc0NvbGxlY3Rpb24oKVxuICAgKiAtIC50b0VudGVyU3RhbmRieSgpXG4gICAqIC0gLnRvRXhlY3V0ZVBvbGljeSgpXG4gICAqIC0gLnRvRXhpdFN0YW5kYnkoKVxuICAgKiAtIC50b0xhdW5jaEluc3RhbmNlcygpXG4gICAqIC0gLnRvUHV0TGlmZWN5Y2xlSG9vaygpXG4gICAqIC0gLnRvUHV0Tm90aWZpY2F0aW9uQ29uZmlndXJhdGlvbigpXG4gICAqIC0gLnRvUHV0U2NhbGluZ1BvbGljeSgpXG4gICAqIC0gLnRvUHV0U2NoZWR1bGVkVXBkYXRlR3JvdXBBY3Rpb24oKVxuICAgKiAtIC50b1B1dFdhcm1Qb29sKClcbiAgICogLSAudG9SZWNvcmRMaWZlY3ljbGVBY3Rpb25IZWFydGJlYXQoKVxuICAgKiAtIC50b1Jlc3VtZVByb2Nlc3NlcygpXG4gICAqIC0gLnRvUm9sbGJhY2tJbnN0YW5jZVJlZnJlc2goKVxuICAgKiAtIC50b1NldERlc2lyZWRDYXBhY2l0eSgpXG4gICAqIC0gLnRvU2V0SW5zdGFuY2VIZWFsdGgoKVxuICAgKiAtIC50b1NldEluc3RhbmNlUHJvdGVjdGlvbigpXG4gICAqIC0gLnRvU3RhcnRJbnN0YW5jZVJlZnJlc2goKVxuICAgKiAtIC50b1N1c3BlbmRQcm9jZXNzZXMoKVxuICAgKiAtIC50b1Rlcm1pbmF0ZUluc3RhbmNlSW5BdXRvU2NhbGluZ0dyb3VwKClcbiAgICogLSAudG9VcGRhdGVBdXRvU2NhbGluZ0dyb3VwKClcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSBhdXRvU2NhbGluZ0dyb3VwXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZSZXNvdXJjZVRhZyh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYFJlc291cmNlVGFnLyR7IHRhZ0tleSB9YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYmFzZWQgb24gdGhlIHByaWNlIGZvciBTcG90IEluc3RhbmNlcyBmb3IgdGhlIGxhdW5jaCBjb25maWd1cmF0aW9uXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctY29uZGl0aW9uLWtleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NyZWF0ZUxhdW5jaENvbmZpZ3VyYXRpb24oKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtudW1lcmljIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19OdW1lcmljKS4gKipEZWZhdWx0OioqIGBOdW1lcmljRXF1YWxzYFxuICAgKi9cbiAgcHVibGljIGlmU3BvdFByaWNlKHZhbHVlOiBudW1iZXIgfCBudW1iZXJbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBTcG90UHJpY2VgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ051bWVyaWNFcXVhbHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBiYXNlZCBvbiB0aGUgQVJOIG9mIGEgdGFyZ2V0IGdyb3VwXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctY29uZGl0aW9uLWtleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0F0dGFjaExvYWRCYWxhbmNlclRhcmdldEdyb3VwcygpXG4gICAqIC0gLnRvQ3JlYXRlQXV0b1NjYWxpbmdHcm91cCgpXG4gICAqIC0gLnRvRGV0YWNoTG9hZEJhbGFuY2VyVGFyZ2V0R3JvdXBzKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbYXJuIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19BUk4pLiAqKkRlZmF1bHQ6KiogYEFybkxpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZUYXJnZXRHcm91cEFSTnModmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYFRhcmdldEdyb3VwQVJOc2AsIHZhbHVlLCBvcGVyYXRvciA/PyAnQXJuTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJhc2VkIG9uIHRoZSBpZGVudGlmaWVycyBvZiB0aGUgdHJhZmZpYyBzb3VyY2VzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctY29uZGl0aW9uLWtleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0F0dGFjaFRyYWZmaWNTb3VyY2VzKClcbiAgICogLSAudG9DcmVhdGVBdXRvU2NhbGluZ0dyb3VwKClcbiAgICogLSAudG9EZXRhY2hUcmFmZmljU291cmNlcygpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmVHJhZmZpY1NvdXJjZUlkZW50aWZpZXJzKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBUcmFmZmljU291cmNlSWRlbnRpZmllcnNgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBiYXNlZCBvbiB0aGUgaWRlbnRpZmllciBvZiBhIFZQQyB6b25lXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctY29uZGl0aW9uLWtleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NyZWF0ZUF1dG9TY2FsaW5nR3JvdXAoKVxuICAgKiAtIC50b1VwZGF0ZUF1dG9TY2FsaW5nR3JvdXAoKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZlZQQ1pvbmVJZGVudGlmaWVycyh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgVlBDWm9uZUlkZW50aWZpZXJzYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYmFzZWQgb24gdGhlIHRhZ3MgdGhhdCBhcmUgcGFzc2VkIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctY29uZGl0aW9uLWtleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NyZWF0ZUF1dG9TY2FsaW5nR3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZU9yVXBkYXRlVGFncygpXG4gICAqIC0gLnRvRGVsZXRlVGFncygpXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXF1ZXN0VGFnKHRhZ0tleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlJlcXVlc3RUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBiYXNlZCBvbiB0aGUgdGFncyBhc3NvY2lhdGVkIHdpdGggdGhlIHJlc291cmNlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9hdXRvc2NhbGluZy9sYXRlc3QvdXNlcmd1aWRlL2NvbnRyb2wtYWNjZXNzLXVzaW5nLWlhbS5odG1sI3BvbGljeS1hdXRvLXNjYWxpbmctY29uZGl0aW9uLWtleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0F0dGFjaEluc3RhbmNlcygpXG4gICAqIC0gLnRvQXR0YWNoTG9hZEJhbGFuY2VyVGFyZ2V0R3JvdXBzKClcbiAgICogLSAudG9BdHRhY2hMb2FkQmFsYW5jZXJzKClcbiAgICogLSAudG9BdHRhY2hUcmFmZmljU291cmNlcygpXG4gICAqIC0gLnRvQmF0Y2hEZWxldGVTY2hlZHVsZWRBY3Rpb24oKVxuICAgKiAtIC50b0JhdGNoUHV0U2NoZWR1bGVkVXBkYXRlR3JvdXBBY3Rpb24oKVxuICAgKiAtIC50b0NhbmNlbEluc3RhbmNlUmVmcmVzaCgpXG4gICAqIC0gLnRvQ29tcGxldGVMaWZlY3ljbGVBY3Rpb24oKVxuICAgKiAtIC50b0NyZWF0ZUF1dG9TY2FsaW5nR3JvdXAoKVxuICAgKiAtIC50b0NyZWF0ZU9yVXBkYXRlVGFncygpXG4gICAqIC0gLnRvRGVsZXRlQXV0b1NjYWxpbmdHcm91cCgpXG4gICAqIC0gLnRvRGVsZXRlTGlmZWN5Y2xlSG9vaygpXG4gICAqIC0gLnRvRGVsZXRlTm90aWZpY2F0aW9uQ29uZmlndXJhdGlvbigpXG4gICAqIC0gLnRvRGVsZXRlUG9saWN5KClcbiAgICogLSAudG9EZWxldGVTY2hlZHVsZWRBY3Rpb24oKVxuICAgKiAtIC50b0RlbGV0ZVRhZ3MoKVxuICAgKiAtIC50b0RlbGV0ZVdhcm1Qb29sKClcbiAgICogLSAudG9EZXRhY2hJbnN0YW5jZXMoKVxuICAgKiAtIC50b0RldGFjaExvYWRCYWxhbmNlclRhcmdldEdyb3VwcygpXG4gICAqIC0gLnRvRGV0YWNoTG9hZEJhbGFuY2VycygpXG4gICAqIC0gLnRvRGV0YWNoVHJhZmZpY1NvdXJjZXMoKVxuICAgKiAtIC50b0Rpc2FibGVNZXRyaWNzQ29sbGVjdGlvbigpXG4gICAqIC0gLnRvRW5hYmxlTWV0cmljc0NvbGxlY3Rpb24oKVxuICAgKiAtIC50b0VudGVyU3RhbmRieSgpXG4gICAqIC0gLnRvRXhlY3V0ZVBvbGljeSgpXG4gICAqIC0gLnRvRXhpdFN0YW5kYnkoKVxuICAgKiAtIC50b0xhdW5jaEluc3RhbmNlcygpXG4gICAqIC0gLnRvUHV0TGlmZWN5Y2xlSG9vaygpXG4gICAqIC0gLnRvUHV0Tm90aWZpY2F0aW9uQ29uZmlndXJhdGlvbigpXG4gICAqIC0gLnRvUHV0U2NhbGluZ1BvbGljeSgpXG4gICAqIC0gLnRvUHV0U2NoZWR1bGVkVXBkYXRlR3JvdXBBY3Rpb24oKVxuICAgKiAtIC50b1B1dFdhcm1Qb29sKClcbiAgICogLSAudG9SZWNvcmRMaWZlY3ljbGVBY3Rpb25IZWFydGJlYXQoKVxuICAgKiAtIC50b1Jlc3VtZVByb2Nlc3NlcygpXG4gICAqIC0gLnRvUm9sbGJhY2tJbnN0YW5jZVJlZnJlc2goKVxuICAgKiAtIC50b1NldERlc2lyZWRDYXBhY2l0eSgpXG4gICAqIC0gLnRvU2V0SW5zdGFuY2VIZWFsdGgoKVxuICAgKiAtIC50b1NldEluc3RhbmNlUHJvdGVjdGlvbigpXG4gICAqIC0gLnRvU3RhcnRJbnN0YW5jZVJlZnJlc2goKVxuICAgKiAtIC50b1N1c3BlbmRQcm9jZXNzZXMoKVxuICAgKiAtIC50b1Rlcm1pbmF0ZUluc3RhbmNlSW5BdXRvU2NhbGluZ0dyb3VwKClcbiAgICogLSAudG9VcGRhdGVBdXRvU2NhbGluZ0dyb3VwKClcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSBhdXRvU2NhbGluZ0dyb3VwXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXNvdXJjZVRhZyh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpSZXNvdXJjZVRhZy8keyB0YWdLZXkgfWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJhc2VkIG9uIHRoZSB0YWcga2V5cyB0aGF0IGFyZSBwYXNzZWQgaW4gdGhlIHJlcXVlc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2F1dG9zY2FsaW5nL2xhdGVzdC91c2VyZ3VpZGUvY29udHJvbC1hY2Nlc3MtdXNpbmctaWFtLmh0bWwjcG9saWN5LWF1dG8tc2NhbGluZy1jb25kaXRpb24ta2V5c1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ3JlYXRlQXV0b1NjYWxpbmdHcm91cCgpXG4gICAqIC0gLnRvQ3JlYXRlT3JVcGRhdGVUYWdzKClcbiAgICogLSAudG9EZWxldGVUYWdzKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NUYWdLZXlzKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6VGFnS2V5c2AsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG59XG4iXX0=