UNPKG

iam-floyd

Version:

AWS IAM policy statement generator with fluent interface

632 lines 58.8 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 { /** * 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 */ constructor(sid) { super(sid); 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' ] }; } /** * 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 * * 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'); } } exports.Shield = Shield; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hpZWxkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic2hpZWxkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHlDQUF5RDtBQUV6RDs7OztHQUlHO0FBQ0gsTUFBYSxNQUFPLFNBQVEsd0JBQWU7SUFHekM7Ozs7T0FJRztJQUNILFlBQVksR0FBWTtRQUN0QixLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFSTixrQkFBYSxHQUFHLFFBQVEsQ0FBQztRQThmdEIsb0JBQWUsR0FBb0I7WUFDM0MsS0FBSyxFQUFFO2dCQUNMLHVCQUF1QjtnQkFDdkIsa0JBQWtCO2dCQUNsQixzQkFBc0I7Z0JBQ3RCLHFDQUFxQztnQkFDckMsa0JBQWtCO2dCQUNsQix1QkFBdUI7Z0JBQ3ZCLG9CQUFvQjtnQkFDcEIsa0JBQWtCO2dCQUNsQix1QkFBdUI7Z0JBQ3ZCLG9CQUFvQjtnQkFDcEIsMENBQTBDO2dCQUMxQyw0QkFBNEI7Z0JBQzVCLDBCQUEwQjtnQkFDMUIscUJBQXFCO2dCQUNyQix5QkFBeUI7Z0JBQ3pCLHlDQUF5QztnQkFDekMsMkJBQTJCO2dCQUMzQix5Q0FBeUM7Z0JBQ3pDLGdDQUFnQztnQkFDaEMsdUJBQXVCO2dCQUN2QixvQkFBb0I7YUFDckI7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osZ0JBQWdCO2dCQUNoQiw0QkFBNEI7Z0JBQzVCLDBCQUEwQjtnQkFDMUIsbUJBQW1CO2dCQUNuQixrQ0FBa0M7Z0JBQ2xDLG9CQUFvQjtnQkFDcEIseUJBQXlCO2dCQUN6QixzQkFBc0I7Z0JBQ3RCLHFCQUFxQjtnQkFDckIsc0JBQXNCO2dCQUN0QixxQkFBcUI7YUFDdEI7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osYUFBYTtnQkFDYixpQkFBaUI7Z0JBQ2pCLHNCQUFzQjtnQkFDdEIsaUJBQWlCO2dCQUNqQixnQ0FBZ0M7YUFDakM7WUFDRCxPQUFPLEVBQUU7Z0JBQ1AsYUFBYTtnQkFDYixlQUFlO2FBQ2hCO1NBQ0YsQ0FBQztJQXJpQkYsQ0FBQztJQUVE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OlsiaW1wb3J0IHsgQWNjZXNzTGV2ZWxMaXN0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FjY2Vzcy1sZXZlbCc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQsIE9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcblxuLyoqXG4gKiBTdGF0ZW1lbnQgcHJvdmlkZXIgZm9yIHNlcnZpY2UgW3NoaWVsZF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYXdzc2hpZWxkLmh0bWwpLlxuICpcbiAqIEBwYXJhbSBzaWQgW1NJRF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19zaWQuaHRtbCkgb2YgdGhlIHN0YXRlbWVudFxuICovXG5leHBvcnQgY2xhc3MgU2hpZWxkIGV4dGVuZHMgUG9saWN5U3RhdGVtZW50IHtcbiAgcHVibGljIHNlcnZpY2VQcmVmaXggPSAnc2hpZWxkJztcblxuICAvKipcbiAgICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFtzaGllbGRdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXJ2aWNlLWF1dGhvcml6YXRpb24vbGF0ZXN0L3JlZmVyZW5jZS9saXN0X2F3c3NoaWVsZC5odG1sKS5cbiAgICpcbiAgICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gICAqL1xuICBjb25zdHJ1Y3RvcihzaWQ/OiBzdHJpbmcpIHtcbiAgICBzdXBlcihzaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGF1dGhvcml6ZSB0aGUgRERvUyBSZXNwb25zZSB0ZWFtIHRvIGFjY2VzcyB0aGUgc3BlY2lmaWVkIEFtYXpvbiBTMyBidWNrZXQgY29udGFpbmluZyB5b3VyIGZsb3cgbG9nc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHMzOkdldEJ1Y2tldFBvbGljeVxuICAgKiAtIHMzOlB1dEJ1Y2tldFBvbGljeVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9Bc3NvY2lhdGVEUlRMb2dCdWNrZXQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQXNzb2NpYXRlRFJUTG9nQnVja2V0KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdBc3NvY2lhdGVEUlRMb2dCdWNrZXQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhdXRob3JpemUgdGhlIEREb1MgUmVzcG9uc2UgdGVhbSB1c2luZyB0aGUgc3BlY2lmaWVkIHJvbGUsIHRvIGFjY2VzcyB5b3VyIEFXUyBhY2NvdW50IHRvIGFzc2lzdCB3aXRoIEREb1MgYXR0YWNrIG1pdGlnYXRpb24gZHVyaW5nIHBvdGVudGlhbCBhdHRhY2tzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gaWFtOkdldFJvbGVcbiAgICogLSBpYW06TGlzdEF0dGFjaGVkUm9sZVBvbGljaWVzXG4gICAqIC0gaWFtOlBhc3NSb2xlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Fzc29jaWF0ZURSVFJvbGUuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQXNzb2NpYXRlRFJUUm9sZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQXNzb2NpYXRlRFJUUm9sZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFkZCBoZWFsdGgtYmFzZWQgZGV0ZWN0aW9uIHRvIHRoZSBTaGllbGQgQWR2YW5jZWQgcHJvdGVjdGlvbiBmb3IgYSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSByb3V0ZTUzOkdldEhlYWx0aENoZWNrXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Fzc29jaWF0ZUhlYWx0aENoZWNrLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Fzc29jaWF0ZUhlYWx0aENoZWNrKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdBc3NvY2lhdGVIZWFsdGhDaGVjaycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGluaXRpYWxpemUgcHJvYWN0aXZlIGVuZ2FnZW1lbnQgYW5kIHNldCB0aGUgbGlzdCBvZiBjb250YWN0cyBmb3IgdGhlIEREb1MgUmVzcG9uc2UgVGVhbSAoRFJUKSB0byB1c2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9Bc3NvY2lhdGVQcm9hY3RpdmVFbmdhZ2VtZW50RGV0YWlscy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9Bc3NvY2lhdGVQcm9hY3RpdmVFbmdhZ2VtZW50RGV0YWlscygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQXNzb2NpYXRlUHJvYWN0aXZlRW5nYWdlbWVudERldGFpbHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBhY3RpdmF0ZSBERG9TIHByb3RlY3Rpb24gc2VydmljZSBmb3IgYSBnaXZlbiByZXNvdXJjZSBBUk5cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVQcm90ZWN0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVByb3RlY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZVByb3RlY3Rpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBncm91cGluZyBvZiBwcm90ZWN0ZWQgcmVzb3VyY2VzIHNvIHRoZXkgY2FuIGJlIGhhbmRsZWQgYXMgYSBjb2xsZWN0aXZlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlUHJvdGVjdGlvbkdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVByb3RlY3Rpb25Hcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlUHJvdGVjdGlvbkdyb3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWN0aXZhdGUgc3Vic2NyaXB0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlU3Vic2NyaXB0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVN1YnNjcmlwdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlU3Vic2NyaXB0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGFuIGV4aXN0aW5nIHByb3RlY3Rpb25cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlUHJvdGVjdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVQcm90ZWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVQcm90ZWN0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIHRoZSBzcGVjaWZpZWQgcHJvdGVjdGlvbiBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVQcm90ZWN0aW9uR3JvdXAuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlUHJvdGVjdGlvbkdyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVQcm90ZWN0aW9uR3JvdXAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWFjdGl2YXRlIHN1YnNjcmlwdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVN1YnNjcmlwdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVTdWJzY3JpcHRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVN1YnNjcmlwdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBhdHRhY2sgZGV0YWlsc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVBdHRhY2suaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVBdHRhY2soKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlQXR0YWNrJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjb250cmlidXRvcnMgdG8gYSBzcGVjaWZpYyBERG9TIGF0dGFja1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYXdzc2hpZWxkLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlQXR0YWNrQ29udHJpYnV0b3JzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUF0dGFja0NvbnRyaWJ1dG9ycycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBudW1iZXIgYW5kIHR5cGUgb2YgYXR0YWNrcyBBV1MgU2hpZWxkIGhhcyBkZXRlY3RlZCBpbiB0aGUgbGFzdCB5ZWFyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUF0dGFja1N0YXRpc3RpY3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVBdHRhY2tTdGF0aXN0aWNzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUF0dGFja1N0YXRpc3RpY3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgY3VycmVudCByb2xlIGFuZCBsaXN0IG9mIEFtYXpvbiBTMyBsb2cgYnVja2V0cyB1c2VkIGJ5IHRoZSBERG9TIFJlc3BvbnNlIHRlYW0gdG8gYWNjZXNzIHlvdXIgQVdTIGFjY291bnQgd2hpbGUgYXNzaXN0aW5nIHdpdGggYXR0YWNrIG1pdGlnYXRpb25cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlRFJUQWNjZXNzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlRFJUQWNjZXNzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZURSVEFjY2VzcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgdGhlIGVtYWlsIGFkZHJlc3NlcyB0aGF0IHRoZSBEUlQgY2FuIHVzZSB0byBjb250YWN0IHlvdSBkdXJpbmcgYSBzdXNwZWN0ZWQgYXR0YWNrXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUVtZXJnZW5jeUNvbnRhY3RTZXR0aW5ncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUVtZXJnZW5jeUNvbnRhY3RTZXR0aW5ncygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVFbWVyZ2VuY3lDb250YWN0U2V0dGluZ3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgcHJvdGVjdGlvbiBkZXRhaWxzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGVzY3JpYmVQcm90ZWN0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlUHJvdGVjdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVQcm90ZWN0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgdGhlIHNwZWNpZmljYXRpb24gZm9yIHRoZSBzcGVjaWZpZWQgcHJvdGVjdGlvbiBncm91cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlUHJvdGVjdGlvbkdyb3VwLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlUHJvdGVjdGlvbkdyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVByb3RlY3Rpb25Hcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBzdWJzY3JpcHRpb24gZGV0YWlscywgc3VjaCBhcyBzdGFydCB0aW1lXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVN1YnNjcmlwdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVN1YnNjcmlwdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVTdWJzY3JpcHRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkaXNhYmxlIGFwcGxpY2F0aW9uIGxheWVyIGF1dG9tYXRpYyByZXNwb25zZSBmb3IgU2hpZWxkIEFkdmFuY2VkIHByb3RlY3Rpb24gZm9yIGEgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9EaXNhYmxlQXBwbGljYXRpb25MYXllckF1dG9tYXRpY1Jlc3BvbnNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rpc2FibGVBcHBsaWNhdGlvbkxheWVyQXV0b21hdGljUmVzcG9uc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rpc2FibGVBcHBsaWNhdGlvbkxheWVyQXV0b21hdGljUmVzcG9uc2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgYXV0aG9yaXphdGlvbiBmcm9tIHRoZSBERG9TIFJlc3BvbnNlIFRlYW0gKERSVCkgdG8gbm90aWZ5IGNvbnRhY3RzIGFib3V0IGVzY2FsYXRpb25zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGlzYWJsZVByb2FjdGl2ZUVuZ2FnZW1lbnQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGlzYWJsZVByb2FjdGl2ZUVuZ2FnZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rpc2FibGVQcm9hY3RpdmVFbmdhZ2VtZW50Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIHRoZSBERG9TIFJlc3BvbnNlIHRlYW0ncyBhY2Nlc3MgdG8gdGhlIHNwZWNpZmllZCBBbWF6b24gUzMgYnVja2V0IGNvbnRhaW5pbmcgeW91ciBmbG93IGxvZ3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBzMzpEZWxldGVCdWNrZXRQb2xpY3lcbiAgICogLSBzMzpHZXRCdWNrZXRQb2xpY3lcbiAgICogLSBzMzpQdXRCdWNrZXRQb2xpY3lcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRGlzYXNzb2NpYXRlRFJUTG9nQnVja2V0Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rpc2Fzc29jaWF0ZURSVExvZ0J1Y2tldCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGlzYXNzb2NpYXRlRFJUTG9nQnVja2V0Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIHRoZSBERG9TIFJlc3BvbnNlIHRlYW0ncyBhY2Nlc3MgdG8geW91ciBBV1MgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rpc2Fzc29jaWF0ZURSVFJvbGUuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGlzYXNzb2NpYXRlRFJUUm9sZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGlzYXNzb2NpYXRlRFJUUm9sZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSBoZWFsdGgtYmFzZWQgZGV0ZWN0aW9uIGZyb20gdGhlIFNoaWVsZCBBZHZhbmNlZCBwcm90ZWN0aW9uIGZvciBhIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0Rpc2Fzc29jaWF0ZUhlYWx0aENoZWNrLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rpc2Fzc29jaWF0ZUhlYWx0aENoZWNrKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEaXNhc3NvY2lhdGVIZWFsdGhDaGVjaycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGVuYWJsZSBhcHBsaWNhdGlvbiBsYXllciBhdXRvbWF0aWMgcmVzcG9uc2UgZm9yIFNoaWVsZCBBZHZhbmNlZCBwcm90ZWN0aW9uIGZvciBhIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gYXBwcnVubmVyOkRlc2NyaWJlV2ViQWNsRm9yU2VydmljZVxuICAgKiAtIGNsb3VkZnJvbnQ6R2V0RGlzdHJpYnV0aW9uXG4gICAqIC0gY29nbml0by1pZHA6R2V0V2ViQUNMRm9yUmVzb3VyY2VcbiAgICogLSBlYzI6R2V0VmVyaWZpZWRBY2Nlc3NJbnN0YW5jZVdlYkFjbFxuICAgKiAtIGlhbTpDcmVhdGVTZXJ2aWNlTGlua2VkUm9sZVxuICAgKiAtIGlhbTpHZXRSb2xlXG4gICAqIC0gd2FmdjI6R2V0V2ViQUNMXG4gICAqIC0gd2FmdjI6R2V0V2ViQUNMRm9yUmVzb3VyY2VcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfRW5hYmxlQXBwbGljYXRpb25MYXllckF1dG9tYXRpY1Jlc3BvbnNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0VuYWJsZUFwcGxpY2F0aW9uTGF5ZXJBdXRvbWF0aWNSZXNwb25zZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRW5hYmxlQXBwbGljYXRpb25MYXllckF1dG9tYXRpY1Jlc3BvbnNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYXV0aG9yaXplIHRoZSBERG9TIFJlc3BvbnNlIFRlYW0gKERSVCkgdG8gdXNlIGVtYWlsIGFuZCBwaG9uZSB0byBub3RpZnkgY29udGFjdHMgYWJvdXQgZXNjYWxhdGlvbnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9FbmFibGVQcm9hY3RpdmVFbmdhZ2VtZW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0VuYWJsZVByb2FjdGl2ZUVuZ2FnZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0VuYWJsZVByb2FjdGl2ZUVuZ2FnZW1lbnQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXRyaWV2ZSBnbG9iYWwgdGhyZWF0IGludGVsbGlnZW5jZSBkYXRhIGFuZCB0cmVuZHMgZnJvbSBBV1MgU2hpZWxkJ3MgdGhyZWF0IG1vbml0b3Jpbmcgc3lzdGVtc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYXdzc2hpZWxkLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldEdsb2JhbFRocmVhdERhdGEoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldEdsb2JhbFRocmVhdERhdGEnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgc3Vic2NyaXB0aW9uIHN0YXRlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9HZXRTdWJzY3JpcHRpb25TdGF0ZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRTdWJzY3JpcHRpb25TdGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0U3Vic2NyaXB0aW9uU3RhdGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGFsbCBleGlzdGluZyBhdHRhY2tzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9MaXN0QXR0YWNrcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0QXR0YWNrcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdEF0dGFja3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXRyaWV2ZSBhIGxpc3Qgb2YgbWl0aWdhdGlvbiBhY3Rpb25zIHRoYXQgaGF2ZSBiZWVuIGFwcGxpZWQgZHVyaW5nIEREb1MgYXR0YWNrc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYXdzc2hpZWxkLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RNaXRpZ2F0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdE1pdGlnYXRpb25zJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmV0cmlldmUgdGhlIHByb3RlY3Rpb24gZ3JvdXBzIGZvciB0aGUgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfTGlzdFByb3RlY3Rpb25Hcm91cHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFByb3RlY3Rpb25Hcm91cHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RQcm90ZWN0aW9uR3JvdXBzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBhbGwgZXhpc3RpbmcgcHJvdGVjdGlvbnNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0xpc3RQcm90ZWN0aW9ucy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0UHJvdGVjdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RQcm90ZWN0aW9ucycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHJpZXZlIHRoZSByZXNvdXJjZXMgdGhhdCBhcmUgaW5jbHVkZWQgaW4gdGhlIHByb3RlY3Rpb24gZ3JvdXBcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX0xpc3RSZXNvdXJjZXNJblByb3RlY3Rpb25Hcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0UmVzb3VyY2VzSW5Qcm90ZWN0aW9uR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RSZXNvdXJjZXNJblByb3RlY3Rpb25Hcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBpbmZvcm1hdGlvbiBhYm91dCBBV1MgdGFncyBmb3IgYSBzcGVjaWZpZWQgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgaW4gQVdTIFNoaWVsZFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfTGlzdFRhZ3NGb3JSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0VGFnc0ZvclJlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0VGFnc0ZvclJlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWRkIG9yIHVwZGF0ZXMgdGFncyBmb3IgYSByZXNvdXJjZSBpbiBBV1MgU2hpZWxkXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vd2FmL2xhdGVzdC9ERE9TQVBJUmVmZXJlbmNlL0FQSV9UYWdSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9UYWdSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZW1vdmUgdGFncyBmcm9tIGEgcmVzb3VyY2UgaW4gQVdTIFNoaWVsZFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3dhZi9sYXRlc3QvRERPU0FQSVJlZmVyZW5jZS9BUElfVW50YWdSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VbnRhZ1Jlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVbnRhZ1Jlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIGFwcGxpY2F0aW9uIGxheWVyIGF1dG9tYXRpYyByZXNwb25zZSBmb3IgU2hpZWxkIEFkdmFuY2VkIHByb3RlY3Rpb24gZm9yIGEgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBhcHBydW5uZXI6RGVzY3JpYmVXZWJBY2xGb3JTZXJ2aWNlXG4gICAqIC0gY29nbml0by1pZHA6R2V0V2ViQUNMRm9yUmVzb3VyY2VcbiAgICogLSBlYzI6R2V0VmVyaWZpZWRBY2Nlc3NJbnN0YW5jZVdlYkFjbFxuICAgKiAtIHdhZnYyOkdldFdlYkFDTFxuICAgKiAtIHdhZnYyOkdldFdlYkFDTEZvclJlc291cmNlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX1VwZGF0ZUFwcGxpY2F0aW9uTGF5ZXJBdXRvbWF0aWNSZXNwb25zZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVBcHBsaWNhdGlvbkxheWVyQXV0b21hdGljUmVzcG9uc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZUFwcGxpY2F0aW9uTGF5ZXJBdXRvbWF0aWNSZXNwb25zZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgZGV0YWlscyBvZiB0aGUgbGlzdCBvZiBlbWFpbCBhZGRyZXNzZXMgdGhhdCB0aGUgRFJUIGNhbiB1c2UgdG8gY29udGFjdCB5b3UgZHVyaW5nIGEgc3VzcGVjdGVkIGF0dGFja1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX1VwZGF0ZUVtZXJnZW5jeUNvbnRhY3RTZXR0aW5ncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVFbWVyZ2VuY3lDb250YWN0U2V0dGluZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZUVtZXJnZW5jeUNvbnRhY3RTZXR0aW5ncycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSBhbiBleGlzdGluZyBwcm90ZWN0aW9uIGdyb3VwXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS93YWYvbGF0ZXN0L0RET1NBUElSZWZlcmVuY2UvQVBJX1VwZGF0ZVByb3RlY3Rpb25Hcm91cC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVQcm90ZWN0aW9uR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZVByb3RlY3Rpb25Hcm91cCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgZGV0YWlscyBvZiBhbiBleGlzdGluZyBzdWJzY3JpcHRpb25cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwc