UNPKG

cdk-iam-floyd

Version:

AWS IAM policy statement generator with fluent interface for AWS CDK

631 lines 59.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Shield = void 0; const shared_1 = require("../../shared"); /** * Statement provider for service [shield](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsshield.html). * * @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement */ class Shield extends shared_1.PolicyStatement { /** * Grants permission to authorize the DDoS Response team to access the specified Amazon S3 bucket containing your flow logs * * Access Level: Write * * Dependent actions: * - s3:GetBucketPolicy * - s3:PutBucketPolicy * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_AssociateDRTLogBucket.html */ toAssociateDRTLogBucket() { return this.to('AssociateDRTLogBucket'); } /** * Grants permission to authorize the DDoS Response team using the specified role, to access your AWS account to assist with DDoS attack mitigation during potential attacks * * Access Level: Write * * Dependent actions: * - iam:GetRole * - iam:ListAttachedRolePolicies * - iam:PassRole * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_AssociateDRTRole.html */ toAssociateDRTRole() { return this.to('AssociateDRTRole'); } /** * Grants permission to add health-based detection to the Shield Advanced protection for a resource * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * * Dependent actions: * - route53:GetHealthCheck * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_AssociateHealthCheck.html */ toAssociateHealthCheck() { return this.to('AssociateHealthCheck'); } /** * Grants permission to initialize proactive engagement and set the list of contacts for the DDoS Response Team (DRT) to use * * Access Level: Write * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_AssociateProactiveEngagementDetails.html */ toAssociateProactiveEngagementDetails() { return this.to('AssociateProactiveEngagementDetails'); } /** * Grants permission to activate DDoS protection service for a given resource ARN * * Access Level: Write * * Possible conditions: * - .ifAwsRequestTag() * - .ifAwsTagKeys() * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_CreateProtection.html */ toCreateProtection() { return this.to('CreateProtection'); } /** * Grants permission to create a grouping of protected resources so they can be handled as a collective * * Access Level: Write * * Possible conditions: * - .ifAwsRequestTag() * - .ifAwsTagKeys() * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_CreateProtectionGroup.html */ toCreateProtectionGroup() { return this.to('CreateProtectionGroup'); } /** * Grants permission to activate subscription * * Access Level: Write * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_CreateSubscription.html */ toCreateSubscription() { return this.to('CreateSubscription'); } /** * Grants permission to delete an existing protection * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DeleteProtection.html */ toDeleteProtection() { return this.to('DeleteProtection'); } /** * Grants permission to remove the specified protection group * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DeleteProtectionGroup.html */ toDeleteProtectionGroup() { return this.to('DeleteProtectionGroup'); } /** * Grants permission to deactivate subscription * * Access Level: Write * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DeleteSubscription.html */ toDeleteSubscription() { return this.to('DeleteSubscription'); } /** * Grants permission to get attack details. For getting attack details protected by AWS WAF anti-DDoS managed rule group, this action additionally calls wafv2:DescribeTopContributorsByEvent to retrieve application layer attack contributors, which requires to have wafv2:DescribeTopContributorsByEvent permission in IAM policy * * Access Level: Read * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeAttack.html */ toDescribeAttack() { return this.to('DescribeAttack'); } /** * Grants permission to get detailed information about the contributors to a specific DDoS attack * * Access Level: Read * * https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsshield.html */ toDescribeAttackContributors() { return this.to('DescribeAttackContributors'); } /** * Grants permission to describe information about the number and type of attacks AWS Shield has detected in the last year * * Access Level: Read * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeAttackStatistics.html */ toDescribeAttackStatistics() { return this.to('DescribeAttackStatistics'); } /** * Grants permission to describe the current role and list of Amazon S3 log buckets used by the DDoS Response team to access your AWS account while assisting with attack mitigation * * Access Level: Read * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeDRTAccess.html */ toDescribeDRTAccess() { return this.to('DescribeDRTAccess'); } /** * Grants permission to list the email addresses that the DRT can use to contact you during a suspected attack * * Access Level: Read * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeEmergencyContactSettings.html */ toDescribeEmergencyContactSettings() { return this.to('DescribeEmergencyContactSettings'); } /** * Grants permission to get protection details * * Access Level: Read * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeProtection.html */ toDescribeProtection() { return this.to('DescribeProtection'); } /** * Grants permission to describe the specification for the specified protection group * * Access Level: Read * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeProtectionGroup.html */ toDescribeProtectionGroup() { return this.to('DescribeProtectionGroup'); } /** * Grants permission to get subscription details, such as start time * * Access Level: Read * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DescribeSubscription.html */ toDescribeSubscription() { return this.to('DescribeSubscription'); } /** * Grants permission to disable application layer automatic response for Shield Advanced protection for a resource * * Access Level: Write * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DisableApplicationLayerAutomaticResponse.html */ toDisableApplicationLayerAutomaticResponse() { return this.to('DisableApplicationLayerAutomaticResponse'); } /** * Grants permission to remove authorization from the DDoS Response Team (DRT) to notify contacts about escalations * * Access Level: Write * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DisableProactiveEngagement.html */ toDisableProactiveEngagement() { return this.to('DisableProactiveEngagement'); } /** * Grants permission to remove the DDoS Response team's access to the specified Amazon S3 bucket containing your flow logs * * Access Level: Write * * Dependent actions: * - s3:DeleteBucketPolicy * - s3:GetBucketPolicy * - s3:PutBucketPolicy * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DisassociateDRTLogBucket.html */ toDisassociateDRTLogBucket() { return this.to('DisassociateDRTLogBucket'); } /** * Grants permission to remove the DDoS Response team's access to your AWS account * * Access Level: Write * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DisassociateDRTRole.html */ toDisassociateDRTRole() { return this.to('DisassociateDRTRole'); } /** * Grants permission to remove health-based detection from the Shield Advanced protection for a resource * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_DisassociateHealthCheck.html */ toDisassociateHealthCheck() { return this.to('DisassociateHealthCheck'); } /** * Grants permission to enable application layer automatic response for Shield Advanced protection for a resource * * Access Level: Write * * Dependent actions: * - apprunner:DescribeWebAclForService * - cloudfront:GetDistribution * - cognito-idp:GetWebACLForResource * - ec2:GetVerifiedAccessInstanceWebAcl * - iam:CreateServiceLinkedRole * - iam:GetRole * - wafv2:GetWebACL * - wafv2:GetWebACLForResource * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_EnableApplicationLayerAutomaticResponse.html */ toEnableApplicationLayerAutomaticResponse() { return this.to('EnableApplicationLayerAutomaticResponse'); } /** * Grants permission to authorize the DDoS Response Team (DRT) to use email and phone to notify contacts about escalations * * Access Level: Write * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_EnableProactiveEngagement.html */ toEnableProactiveEngagement() { return this.to('EnableProactiveEngagement'); } /** * Grants permission to retrieve global threat intelligence data and trends from AWS Shield's threat monitoring systems * * Access Level: Read * * https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsshield.html */ toGetGlobalThreatData() { return this.to('GetGlobalThreatData'); } /** * Grants permission to get subscription state * * Access Level: Read * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_GetSubscriptionState.html */ toGetSubscriptionState() { return this.to('GetSubscriptionState'); } /** * Grants permission to list all existing attacks * * Access Level: List * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_ListAttacks.html */ toListAttacks() { return this.to('ListAttacks'); } /** * Grants permission to retrieve a list of mitigation actions that have been applied during DDoS attacks * * Access Level: List * * https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsshield.html */ toListMitigations() { return this.to('ListMitigations'); } /** * Grants permission to retrieve the protection groups for the account * * Access Level: List * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_ListProtectionGroups.html */ toListProtectionGroups() { return this.to('ListProtectionGroups'); } /** * Grants permission to list all existing protections * * Access Level: List * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_ListProtections.html */ toListProtections() { return this.to('ListProtections'); } /** * Grants permission to retrieve the resources that are included in the protection group * * Access Level: List * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_ListResourcesInProtectionGroup.html */ toListResourcesInProtectionGroup() { return this.to('ListResourcesInProtectionGroup'); } /** * Grants permission to get information about AWS tags for a specified Amazon Resource Name (ARN) in AWS Shield * * Access Level: Read * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_ListTagsForResource.html */ toListTagsForResource() { return this.to('ListTagsForResource'); } /** * Grants permission to add or updates tags for a resource in AWS Shield * * Access Level: Tagging * * Possible conditions: * - .ifAwsRequestTag() * - .ifAwsTagKeys() * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_TagResource.html */ toTagResource() { return this.to('TagResource'); } /** * Grants permission to remove tags from a resource in AWS Shield * * Access Level: Tagging * * Possible conditions: * - .ifAwsTagKeys() * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_UntagResource.html */ toUntagResource() { return this.to('UntagResource'); } /** * Grants permission to update application layer automatic response for Shield Advanced protection for a resource * * Access Level: Write * * Dependent actions: * - apprunner:DescribeWebAclForService * - cognito-idp:GetWebACLForResource * - ec2:GetVerifiedAccessInstanceWebAcl * - wafv2:GetWebACL * - wafv2:GetWebACLForResource * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_UpdateApplicationLayerAutomaticResponse.html */ toUpdateApplicationLayerAutomaticResponse() { return this.to('UpdateApplicationLayerAutomaticResponse'); } /** * Grants permission to update the details of the list of email addresses that the DRT can use to contact you during a suspected attack * * Access Level: Write * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_UpdateEmergencyContactSettings.html */ toUpdateEmergencyContactSettings() { return this.to('UpdateEmergencyContactSettings'); } /** * Grants permission to update an existing protection group * * Access Level: Write * * Possible conditions: * - .ifAwsResourceTag() * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_UpdateProtectionGroup.html */ toUpdateProtectionGroup() { return this.to('UpdateProtectionGroup'); } /** * Grants permission to update the details of an existing subscription * * Access Level: Write * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_UpdateSubscription.html */ toUpdateSubscription() { return this.to('UpdateSubscription'); } /** * Adds a resource of type attack to the statement * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_AttackDetail.html * * @param id - Identifier for the id. * @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account. * @param partition - Partition of the AWS account [aws, aws-cn, aws-us-gov]; defaults to `aws`, unless using the CDK, where the default is the current Stack's partition. */ onAttack(id, account, partition) { return this.on(`arn:${partition ?? this.defaultPartition}:shield::${account ?? this.defaultAccount}:attack/${id}`); } /** * Adds a resource of type protection to the statement * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_Protection.html * * @param id - Identifier for the id. * @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account. * @param partition - Partition of the AWS account [aws, aws-cn, aws-us-gov]; defaults to `aws`, unless using the CDK, where the default is the current Stack's partition. * * Possible conditions: * - .ifAwsResourceTag() */ onProtection(id, account, partition) { return this.on(`arn:${partition ?? this.defaultPartition}:shield::${account ?? this.defaultAccount}:protection/${id}`); } /** * Adds a resource of type protection-group to the statement * * https://docs.aws.amazon.com/waf/latest/DDOSAPIReference/API_ProtectionGroup.html * * @param id - Identifier for the id. * @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account. * @param partition - Partition of the AWS account [aws, aws-cn, aws-us-gov]; defaults to `aws`, unless using the CDK, where the default is the current Stack's partition. * * Possible conditions: * - .ifAwsResourceTag() */ onProtectionGroup(id, account, partition) { return this.on(`arn:${partition ?? this.defaultPartition}:shield::${account ?? this.defaultAccount}:protection-group/${id}`); } /** * Filters actions based on the presence of tag key-value pairs in the request * * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag * * Applies to actions: * - .toCreateProtection() * - .toCreateProtectionGroup() * - .toTagResource() * * @param tagKey The tag key to check * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifAwsRequestTag(tagKey, value, operator) { return this.if(`aws:RequestTag/${tagKey}`, value, operator ?? 'StringLike'); } /** * Filters actions based on tag key-value pairs attached to the resource * * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag * * Applies to actions: * - .toAssociateHealthCheck() * - .toDeleteProtection() * - .toDeleteProtectionGroup() * - .toDescribeProtection() * - .toDescribeProtectionGroup() * - .toDisassociateHealthCheck() * - .toUpdateProtectionGroup() * * Applies to resource types: * - protection * - protection-group * * @param tagKey The tag key to check * @param value The value(s) to check * @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike` */ ifAwsResourceTag(tagKey, value, operator) { return this.if(`aws:ResourceTag/${tagKey}`, value, operator ?? 'StringLike'); } /** * Filters actions based on the presence of tag keys in the request * * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys * * Applies to actions: * - .toCreateProtection() * - .toCreateProtectionGroup() * - .toTagResource() * - .toUntagResource() * * @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'); } /** * Statement provider for service [shield](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsshield.html). * */ constructor(props) { super(props); this.servicePrefix = 'shield'; this.accessLevelList = { Write: [ 'AssociateDRTLogBucket', 'AssociateDRTRole', 'AssociateHealthCheck', 'AssociateProactiveEngagementDetails', 'CreateProtection', 'CreateProtectionGroup', 'CreateSubscription', 'DeleteProtection', 'DeleteProtectionGroup', 'DeleteSubscription', 'DisableApplicationLayerAutomaticResponse', 'DisableProactiveEngagement', 'DisassociateDRTLogBucket', 'DisassociateDRTRole', 'DisassociateHealthCheck', 'EnableApplicationLayerAutomaticResponse', 'EnableProactiveEngagement', 'UpdateApplicationLayerAutomaticResponse', 'UpdateEmergencyContactSettings', 'UpdateProtectionGroup', 'UpdateSubscription' ], Read: [ 'DescribeAttack', 'DescribeAttackContributors', 'DescribeAttackStatistics', 'DescribeDRTAccess', 'DescribeEmergencyContactSettings', 'DescribeProtection', 'DescribeProtectionGroup', 'DescribeSubscription', 'GetGlobalThreatData', 'GetSubscriptionState', 'ListTagsForResource' ], List: [ 'ListAttacks', 'ListMitigations', 'ListProtectionGroups', 'ListProtections', 'ListResourcesInProtectionGroup' ], Tagging: [ 'TagResource', 'UntagResource' ] }; } } exports.Shield = Shield; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hpZWxkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic2hpZWxkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHlDQUF5RDtBQUd6RDs7OztHQUlHO0FBQ0gsTUFBYSxNQUFPLFNBQVEsd0JBQWU7SUFHekM7Ozs7Ozs7Ozs7T0FVRztJQUNJLHVCQUF1QjtRQUM1QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDSSxrQkFBa0I7UUFDdkIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNJLHNCQUFzQjtRQUMzQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsc0JBQXNCLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0kscUNBQXFDO1FBQzFDLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksa0JBQWtCO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksdUJBQXVCO1FBQzVCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxvQkFBb0I7UUFDekIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLGtCQUFrQjtRQUN2QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksdUJBQXVCO1FBQzVC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IjpbImltcG9ydCB7IEFjY2Vzc0xldmVsTGlzdCB9IGZyb20gJy4uLy4uL3NoYXJlZC9hY2Nlc3MtbGV2ZWwnO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50LCBPcGVyYXRvciB9IGZyb20gJy4uLy4uL3NoYXJlZCc7XG5pbXBvcnQgeyBhd3NfaWFtIGFzIGlhbSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuXG4vKipcbiAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbc2hpZWxkXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hd3NzaGllbGQuaHRtbCkuXG4gKlxuICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTaGllbGQgZXh0ZW5kcyBQb2xpY3lTdGF0ZW1lbnQge1xuICBwdWJsaWMgc2VydmljZVByZWZpeCA9ICdzaGllbGQnO1xuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhdXRob3JpemUgdGhlIEREb1MgUmVzcG9uc2UgdGVhbSB0byBhY2Nlc3MgdGhlIHNwZWNpZmllZCBBbWF6b24gUzMgYnVja2V0IGNvbnRhaW5pbmcgeW91ciBmbG93IGxvZ3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBzMzpHZXRCdWNrZXRQb2xpY3lcbiAgICogLSBzMzpQdXRCdWNrZXRQb2xpY3lcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfQXNzb2NpYXRlRFJUTG9nQnVja2V0Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Fzc29jaWF0ZURSVExvZ0J1Y2tldCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQXNzb2NpYXRlRFJUTG9nQnVja2V0Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYXV0aG9yaXplIHRoZSBERG9TIFJlc3BvbnNlIHRlYW0gdXNpbmcgdGhlIHNwZWNpZmllZCByb2xlLCB0byBhY2Nlc3MgeW91ciBBV1MgYWNjb3VudCB0byBhc3Npc3Qgd2l0aCBERG9TIGF0dGFjayBtaXRpZ2F0aW9uIGR1cmluZyBwb3RlbnRpYWwgYXR0YWNrc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIGlhbTpHZXRSb2xlXG4gICAqIC0gaWFtOkxpc3RBdHRhY2hlZFJvbGVQb2xpY2llc1xuICAgKiAtIGlhbTpQYXNzUm9sZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9Bc3NvY2lhdGVEUlRSb2xlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Fzc29jaWF0ZURSVFJvbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Fzc29jaWF0ZURSVFJvbGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhZGQgaGVhbHRoLWJhc2VkIGRldGVjdGlvbiB0byB0aGUgU2hpZWxkIEFkdmFuY2VkIHByb3RlY3Rpb24gZm9yIGEgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gcm91dGU1MzpHZXRIZWFsdGhDaGVja1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9Bc3NvY2lhdGVIZWFsdGhDaGVjay5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9Bc3NvY2lhdGVIZWFsdGhDaGVjaygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQXNzb2NpYXRlSGVhbHRoQ2hlY2snKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBpbml0aWFsaXplIHByb2FjdGl2ZSBlbmdhZ2VtZW50IGFuZCBzZXQgdGhlIGxpc3Qgb2YgY29udGFjdHMgZm9yIHRoZSBERG9TIFJlc3BvbnNlIFRlYW0gKERSVCkgdG8gdXNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfQXNzb2NpYXRlUHJvYWN0aXZlRW5nYWdlbWVudERldGFpbHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQXNzb2NpYXRlUHJvYWN0aXZlRW5nYWdlbWVudERldGFpbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Fzc29jaWF0ZVByb2FjdGl2ZUVuZ2FnZW1lbnREZXRhaWxzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWN0aXZhdGUgRERvUyBwcm90ZWN0aW9uIHNlcnZpY2UgZm9yIGEgZ2l2ZW4gcmVzb3VyY2UgQVJOXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlUHJvdGVjdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVQcm90ZWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVQcm90ZWN0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgZ3JvdXBpbmcgb2YgcHJvdGVjdGVkIHJlc291cmNlcyBzbyB0aGV5IGNhbiBiZSBoYW5kbGVkIGFzIGEgY29sbGVjdGl2ZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVByb3RlY3Rpb25Hcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVQcm90ZWN0aW9uR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZVByb3RlY3Rpb25Hcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFjdGl2YXRlIHN1YnNjcmlwdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVN1YnNjcmlwdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVTdWJzY3JpcHRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZVN1YnNjcmlwdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhbiBleGlzdGluZyBwcm90ZWN0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVByb3RlY3Rpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlUHJvdGVjdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlUHJvdGVjdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSB0aGUgc3BlY2lmaWVkIHByb3RlY3Rpb24gZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlUHJvdGVjdGlvbkdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZVByb3RlY3Rpb25Hcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlUHJvdGVjdGlvbkdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVhY3RpdmF0ZSBzdWJzY3JpcHRpb25cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVTdWJzY3JpcHRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlU3Vic2NyaXB0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVTdWJzY3JpcHRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgYXR0YWNrIGRldGFpbHMuIEZvciBnZXR0aW5nIGF0dGFjayBkZXRhaWxzIHByb3RlY3RlZCBieSBBV1MgV0FGIGFudGktRERvUyBtYW5hZ2VkIHJ1bGUgZ3JvdXAsIHRoaXMgYWN0aW9uIGFkZGl0aW9uYWxseSBjYWxscyB3YWZ2MjpEZXNjcmliZVRvcENvbnRyaWJ1dG9yc0J5RXZlbnQgdG8gcmV0cmlldmUgYXBwbGljYXRpb24gbGF5ZXIgYXR0YWNrIGNvbnRyaWJ1dG9ycywgd2hpY2ggcmVxdWlyZXMgdG8gaGF2ZSB3YWZ2MjpEZXNjcmliZVRvcENvbnRyaWJ1dG9yc0J5RXZlbnQgcGVybWlzc2lvbiBpbiBJQU0gcG9saWN5XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUF0dGFjay5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUF0dGFjaygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVBdHRhY2snKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNvbnRyaWJ1dG9ycyB0byBhIHNwZWNpZmljIEREb1MgYXR0YWNrXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hd3NzaGllbGQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVBdHRhY2tDb250cmlidXRvcnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlQXR0YWNrQ29udHJpYnV0b3JzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG51bWJlciBhbmQgdHlwZSBvZiBhdHRhY2tzIEFXUyBTaGllbGQgaGFzIGRldGVjdGVkIGluIHRoZSBsYXN0IHllYXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlQXR0YWNrU3RhdGlzdGljcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUF0dGFja1N0YXRpc3RpY3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlQXR0YWNrU3RhdGlzdGljcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSBjdXJyZW50IHJvbGUgYW5kIGxpc3Qgb2YgQW1hem9uIFMzIGxvZyBidWNrZXRzIHVzZWQgYnkgdGhlIEREb1MgUmVzcG9uc2UgdGVhbSB0byBhY2Nlc3MgeW91ciBBV1MgYWNjb3VudCB3aGlsZSBhc3Npc3Rpbmcgd2l0aCBhdHRhY2sgbWl0aWdhdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVEUlRBY2Nlc3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVEUlRBY2Nlc3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlRFJUQWNjZXNzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCB0aGUgZW1haWwgYWRkcmVzc2VzIHRoYXQgdGhlIERSVCBjYW4gdXNlIHRvIGNvbnRhY3QgeW91IGR1cmluZyBhIHN1c3BlY3RlZCBhdHRhY2tcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlRW1lcmdlbmN5Q29udGFjdFNldHRpbmdzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlRW1lcmdlbmN5Q29udGFjdFNldHRpbmdzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUVtZXJnZW5jeUNvbnRhY3RTZXR0aW5ncycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBwcm90ZWN0aW9uIGRldGFpbHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVByb3RlY3Rpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVQcm90ZWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVByb3RlY3Rpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgc3BlY2lmaWNhdGlvbiBmb3IgdGhlIHNwZWNpZmllZCBwcm90ZWN0aW9uIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVQcm90ZWN0aW9uR3JvdXAuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVQcm90ZWN0aW9uR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlUHJvdGVjdGlvbkdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IHN1YnNjcmlwdGlvbiBkZXRhaWxzLCBzdWNoIGFzIHN0YXJ0IHRpbWVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlU3Vic2NyaXB0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlU3Vic2NyaXB0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVN1YnNjcmlwdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRpc2FibGUgYXBwbGljYXRpb24gbGF5ZXIgYXV0b21hdGljIHJlc3BvbnNlIGZvciBTaGllbGQgQWR2YW5jZWQgcHJvdGVjdGlvbiBmb3IgYSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rpc2FibGVBcHBsaWNhdGlvbkxheWVyQXV0b21hdGljUmVzcG9uc2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGlzYWJsZUFwcGxpY2F0aW9uTGF5ZXJBdXRvbWF0aWNSZXNwb25zZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGlzYWJsZUFwcGxpY2F0aW9uTGF5ZXJBdXRvbWF0aWNSZXNwb25zZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSBhdXRob3JpemF0aW9uIGZyb20gdGhlIEREb1MgUmVzcG9uc2UgVGVhbSAoRFJUKSB0byBub3RpZnkgY29udGFjdHMgYWJvdXQgZXNjYWxhdGlvbnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EaXNhYmxlUHJvYWN0aXZlRW5nYWdlbWVudC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EaXNhYmxlUHJvYWN0aXZlRW5nYWdlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGlzYWJsZVByb2FjdGl2ZUVuZ2FnZW1lbnQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgdGhlIEREb1MgUmVzcG9uc2UgdGVhbSdzIGFjY2VzcyB0byB0aGUgc3BlY2lmaWVkIEFtYXpvbiBTMyBidWNrZXQgY29udGFpbmluZyB5b3VyIGZsb3cgbG9nc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHMzOkRlbGV0ZUJ1Y2tldFBvbGljeVxuICAgKiAtIHMzOkdldEJ1Y2tldFBvbGljeVxuICAgKiAtIHMzOlB1dEJ1Y2tldFBvbGljeVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EaXNhc3NvY2lhdGVEUlRMb2dCdWNrZXQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGlzYXNzb2NpYXRlRFJUTG9nQnVja2V0KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEaXNhc3NvY2lhdGVEUlRMb2dCdWNrZXQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgdGhlIEREb1MgUmVzcG9uc2UgdGVhbSdzIGFjY2VzcyB0byB5b3VyIEFXUyBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGlzYXNzb2NpYXRlRFJUUm9sZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EaXNhc3NvY2lhdGVEUlRSb2xlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEaXNhc3NvY2lhdGVEUlRSb2xlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIGhlYWx0aC1iYXNlZCBkZXRlY3Rpb24gZnJvbSB0aGUgU2hpZWxkIEFkdmFuY2VkIHByb3RlY3Rpb24gZm9yIGEgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGlzYXNzb2NpYXRlSGVhbHRoQ2hlY2suaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGlzYXNzb2NpYXRlSGVhbHRoQ2hlY2soKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rpc2Fzc29jaWF0ZUhlYWx0aENoZWNrJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZW5hYmxlIGFwcGxpY2F0aW9uIGxheWVyIGF1dG9tYXRpYyByZXNwb25zZSBmb3IgU2hpZWxkIEFkdmFuY2VkIHByb3RlY3Rpb24gZm9yIGEgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBhcHBydW5uZXI6RGVzY3JpYmVXZWJBY2xGb3JTZXJ2aWNlXG4gICAqIC0gY2xvdWRmcm9udDpHZXREaXN0cmlidXRpb25cbiAgICogLSBjb2duaXRvLWlkcDpHZXRXZWJBQ0xGb3JSZXNvdXJjZVxuICAgKiAtIGVjMjpHZXRWZXJpZmllZEFjY2Vzc0luc3RhbmNlV2ViQWNsXG4gICAqIC0gaWFtOkNyZWF0ZVNlcnZpY2VMaW5rZWRSb2xlXG4gICAqIC0gaWFtOkdldFJvbGVcbiAgICogLSB3YWZ2MjpHZXRXZWJBQ0xcbiAgICogLSB3YWZ2MjpHZXRXZWJBQ0xGb3JSZXNvdXJjZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9FbmFibGVBcHBsaWNhdGlvbkxheWVyQXV0b21hdGljUmVzcG9uc2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRW5hYmxlQXBwbGljYXRpb25MYXllckF1dG9tYXRpY1Jlc3BvbnNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdFbmFibGVBcHBsaWNhdGlvbkxheWVyQXV0b21hdGljUmVzcG9uc2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhdXRob3JpemUgdGhlIEREb1MgUmVzcG9uc2UgVGVhbSAoRFJUKSB0byB1c2UgZW1haWwgYW5kIHBob25lIHRvIG5vdGlmeSBjb250YWN0cyBhYm91dCBlc2NhbGF0aW9uc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0VuYWJsZVByb2FjdGl2ZUVuZ2FnZW1lbnQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRW5hYmxlUHJvYWN0aXZlRW5nYWdlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRW5hYmxlUHJvYWN0aXZlRW5nYWdlbWVudCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHJpZXZlIGdsb2JhbCB0aHJlYXQgaW50ZWxsaWdlbmNlIGRhdGEgYW5kIHRyZW5kcyBmcm9tIEFXUyBTaGllbGQncyB0aHJlYXQgbW9uaXRvcmluZyBzeXN0ZW1zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hd3NzaGllbGQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0R2xvYmFsVGhyZWF0RGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0R2xvYmFsVGhyZWF0RGF0YScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBzdWJzY3JpcHRpb24gc3RhdGVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0dldFN1YnNjcmlwdGlvblN0YXRlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldFN1YnNjcmlwdGlvblN0YXRlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRTdWJzY3JpcHRpb25TdGF0ZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgYWxsIGV4aXN0aW5nIGF0dGFja3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0xpc3RBdHRhY2tzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RBdHRhY2tzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0QXR0YWNrcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHJpZXZlIGEgbGlzdCBvZiBtaXRpZ2F0aW9uIGFjdGlvbnMgdGhhdCBoYXZlIGJlZW4gYXBwbGllZCBkdXJpbmcgRERvUyBhdHRhY2tzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hd3NzaGllbGQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdE1pdGlnYXRpb25zKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0TWl0aWdhdGlvbnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXRyaWV2ZSB0aGUgcHJvdGVjdGlvbiBncm91cHMgZm9yIHRoZSBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9MaXN0UHJvdGVjdGlvbkdyb3Vwcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0UHJvdGVjdGlvbkdyb3VwcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFByb3RlY3Rpb25Hcm91cHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGFsbCBleGlzdGluZyBwcm90ZWN0aW9uc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfTGlzdFByb3RlY3Rpb25zLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RQcm90ZWN0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFByb3RlY3Rpb25zJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmV0cmlldmUgdGhlIHJlc291cmNlcyB0aGF0IGFyZSBpbmNsdWRlZCBpbiB0aGUgcHJvdGVjdGlvbiBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfTGlzdFJlc291cmNlc0luUHJvdGVjdGlvbkdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RSZXNvdXJjZXNJblByb3RlY3Rpb25Hcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFJlc291cmNlc0luUHJvdGVjdGlvbkdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IEFXUyB0YWdzIGZvciBhIHNwZWNpZmllZCBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBpbiBBV1MgU2hpZWxkXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9MaXN0VGFnc0ZvclJlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RUYWdzRm9yUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RUYWdzRm9yUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhZGQgb3IgdXBkYXRlcyB0YWdzIGZvciBhIHJlc291cmNlIGluIEFXUyBTaGllbGRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX1RhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1RhZ1Jlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdUYWdSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSB0YWdzIGZyb20gYSByZXNvdXJjZSBpbiBBV1MgU2hpZWxkXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9VbnRhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VudGFnUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VudGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgYXBwbGljYXRpb24gbGF5ZXIgYXV0b21hdGljIHJlc3BvbnNlIGZvciBTaGllbGQgQWR2YW5jZWQgcHJvdGVjdGlvbiBmb3IgYSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIGFwcHJ1bm5lcjpEZXNjcmliZVdlYkFjbEZvclNlcnZpY2VcbiAgICogLSBjb2duaXRvLWlkcDpHZXRXZWJBQ0xGb3JSZXNvdXJjZVxuICAgKiAtIGVjMjpHZXRWZXJpZmllZEFjY2Vzc0luc3RhbmNlV2ViQWNsXG4gICAqIC0gd2FmdjI6R2V0V2ViQUNMXG4gICAqIC0gd2FmdjI6R2V0V2ViQUNMRm9yUmVzb3VyY2VcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlQXBwbGljYXRpb25MYXllckF1dG9tYXRpY1Jlc3BvbnNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZUFwcGxpY2F0aW9uTGF5ZXJBdXRvbWF0aWNSZXNwb25zZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlQXBwbGljYXRpb25MYXllckF1dG9tYXRpY1Jlc3BvbnNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIHRoZSBkZXRhaWxzIG9mIHRoZSBsaXN0IG9mIGVtYWlsIGFkZHJlc3NlcyB0aGF0IHRoZSBEUlQgY2FuIHVzZSB0byBjb250YWN0IHlvdSBkdXJpbmcgYSBzdXNwZWN0ZWQgYXR0YWNrXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlRW1lcmdlbmN5Q29udGFjdFNldHRpbmdzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZUVtZXJnZW5jeUNvbnRhY3RTZXR0aW5ncygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlRW1lcmdlbmN5Q29udGFjdFNldHRpbmdzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIGFuIGV4aXN0aW5nIHByb3RlY3Rpb24gZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlUHJvdGVjdGlvbkdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZVByb3RlY3Rpb25Hcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlUHJvdGVjdGlvbkdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3