cdk-iam-floyd
Version:
AWS IAM policy statement generator with fluent interface for AWS CDK
651 lines • 59 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Aoss = void 0;
const shared_1 = require("../../shared");
/**
* Statement provider for service [aoss](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonopensearchserverless.html).
*
* @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
*/
class Aoss extends shared_1.PolicyStatement {
/**
* Grant permission to all the supported Opensearch APIs
*
* Access Level: Write
*
* Possible conditions:
* - .ifCollection()
* - .ifCollectionId()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_APIAccessAll.html
*/
toAPIAccessAll() {
return this.to('APIAccessAll');
}
/**
* Grants permission to get attributes for one or more collections
*
* Access Level: Read
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_BatchGetCollection.html
*/
toBatchGetCollection() {
return this.to('BatchGetCollection');
}
/**
* Grants permission to get the information about a lifecycle policy applied to one or more AOSS resources
*
* Access Level: Read
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_BatchGetEffectiveLifecyclePolicy.html
*/
toBatchGetEffectiveLifecyclePolicy() {
return this.to('BatchGetEffectiveLifecyclePolicy');
}
/**
* Grants permission to get information about one or more lifecycle policies
*
* Access Level: Read
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_BatchGetLifecyclePolicy.html
*/
toBatchGetLifecyclePolicy() {
return this.to('BatchGetLifecyclePolicy');
}
/**
* Grants permission to get attributes for one or more VPC endpoints
*
* Access Level: Read
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_BatchGetVpcEndpoint.html
*/
toBatchGetVpcEndpoint() {
return this.to('BatchGetVpcEndpoint');
}
/**
* Grants permission to create a data access policy
*
* Access Level: Write
*
* Possible conditions:
* - .ifCollection()
* - .ifIndex()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_CreateAccessPolicy.html
*/
toCreateAccessPolicy() {
return this.to('CreateAccessPolicy');
}
/**
* Grants permission to create a serverless collection
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_CreateCollection.html
*/
toCreateCollection() {
return this.to('CreateCollection');
}
/**
* Grants permission to create a lifecycle policy
*
* Access Level: Write
*
* Possible conditions:
* - .ifCollection()
* - .ifIndex()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_CreateLifecyclePolicy.html
*/
toCreateLifecyclePolicy() {
return this.to('CreateLifecyclePolicy');
}
/**
* Grants permission to create a serverless security configuration
*
* Access Level: Write
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_CreateSecurityConfig.html
*/
toCreateSecurityConfig() {
return this.to('CreateSecurityConfig');
}
/**
* Grants permission to create a network or encryption policy
*
* Access Level: Write
*
* Possible conditions:
* - .ifCollection()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_CreateSecurityPolicy.html
*/
toCreateSecurityPolicy() {
return this.to('CreateSecurityPolicy');
}
/**
* Grants permission to create an OpenSearch-Serverless-managed interface VPC endpoint
*
* Access Level: Write
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_CreateVpcEndpoint.html
*/
toCreateVpcEndpoint() {
return this.to('CreateVpcEndpoint');
}
/**
* Grants permission to Opensearch Serverless Dashboards
*
* Access Level: Write
*
* Possible conditions:
* - .ifCollection()
* - .ifCollectionId()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_DashboardsAccessAll.html
*/
toDashboardsAccessAll() {
return this.to('DashboardsAccessAll');
}
/**
* Grants permission to delete a data access policy
*
* Access Level: Write
*
* Possible conditions:
* - .ifCollection()
* - .ifIndex()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_DeleteAccessPolicy.html
*/
toDeleteAccessPolicy() {
return this.to('DeleteAccessPolicy');
}
/**
* Grants permission to delete a serverless collection
*
* Access Level: Write
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_DeleteCollection.html
*/
toDeleteCollection() {
return this.to('DeleteCollection');
}
/**
* Grants permission to delete a lifecycle policy
*
* Access Level: Write
*
* Possible conditions:
* - .ifCollection()
* - .ifIndex()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_DeleteLifecyclePolicy.html
*/
toDeleteLifecyclePolicy() {
return this.to('DeleteLifecyclePolicy');
}
/**
* Grants permission to delete a security configuration
*
* Access Level: Write
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_DeleteSecurityConfig.html
*/
toDeleteSecurityConfig() {
return this.to('DeleteSecurityConfig');
}
/**
* Grants permission to delete a security policy
*
* Access Level: Write
*
* Possible conditions:
* - .ifCollection()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_DeleteSecurityPolicy.html
*/
toDeleteSecurityPolicy() {
return this.to('DeleteSecurityPolicy');
}
/**
* Grants permission to delete an OpenSearch Serverless-managed interface VPC endpoint
*
* Access Level: Write
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_DeleteVpcEndpoint.html
*/
toDeleteVpcEndpoint() {
return this.to('DeleteVpcEndpoint');
}
/**
* Grants permission to get information about a data access policy
*
* Access Level: Read
*
* Possible conditions:
* - .ifCollection()
* - .ifIndex()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_GetAccessPolicy.html
*/
toGetAccessPolicy() {
return this.to('GetAccessPolicy');
}
/**
* Grants permission to get account settings, including capacity settings
*
* Access Level: Read
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_GetAccountSettings.html
*/
toGetAccountSettings() {
return this.to('GetAccountSettings');
}
/**
* Grants permission to get statistis about the security policies in your account
*
* Access Level: Read
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_GetPoliciesStats.html
*/
toGetPoliciesStats() {
return this.to('GetPoliciesStats');
}
/**
* Grants permission to get information about a serverless security configuration
*
* Access Level: Read
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_GetSecurityConfig.html
*/
toGetSecurityConfig() {
return this.to('GetSecurityConfig');
}
/**
* Grants permission to get information about a security policy
*
* Access Level: Read
*
* Possible conditions:
* - .ifCollection()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_GetSecurityPolicy.html
*/
toGetSecurityPolicy() {
return this.to('GetSecurityPolicy');
}
/**
* Grants permission to list data access policies
*
* Access Level: List
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_ListAccessPolicies.html
*/
toListAccessPolicies() {
return this.to('ListAccessPolicies');
}
/**
* Grants permission to list collections
*
* Access Level: List
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_ListCollections.html
*/
toListCollections() {
return this.to('ListCollections');
}
/**
* Grants permission to list lifecycle policies
*
* Access Level: List
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_ListLifecyclePolicies.html
*/
toListLifecyclePolicies() {
return this.to('ListLifecyclePolicies');
}
/**
* Grants permission to list security configurations
*
* Access Level: List
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_ListSecurityConfigs.html
*/
toListSecurityConfigs() {
return this.to('ListSecurityConfigs');
}
/**
* Grants permission to list security policies
*
* Access Level: List
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_ListSecurityPolicies.html
*/
toListSecurityPolicies() {
return this.to('ListSecurityPolicies');
}
/**
* Grants permission to list tags for a collection
*
* Access Level: List
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_ListTagsForResource.html
*/
toListTagsForResource() {
return this.to('ListTagsForResource');
}
/**
* Grants permission to list OpenSearch Serverless-managed VPC endpoints
*
* Access Level: List
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_ListVpcEndpoints.html
*/
toListVpcEndpoints() {
return this.to('ListVpcEndpoints');
}
/**
* Grants permission to tag a serverless collection
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsResourceTag()
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_TagResource.html
*/
toTagResource() {
return this.to('TagResource');
}
/**
* Grants permission to remove tags from a collection
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_UntagResource.html
*/
toUntagResource() {
return this.to('UntagResource');
}
/**
* Grants permission to update a data access policy
*
* Access Level: Write
*
* Possible conditions:
* - .ifCollection()
* - .ifIndex()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_UpdateAccessPolicy.html
*/
toUpdateAccessPolicy() {
return this.to('UpdateAccessPolicy');
}
/**
* Grants permission to update account settings, including capacity settings
*
* Access Level: Write
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_UpdateAccountSettings.html
*/
toUpdateAccountSettings() {
return this.to('UpdateAccountSettings');
}
/**
* Grants permission to update a collection
*
* Access Level: Write
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_UpdateCollection.html
*/
toUpdateCollection() {
return this.to('UpdateCollection');
}
/**
* Grants permission to update a lifecycle policy
*
* Access Level: Write
*
* Possible conditions:
* - .ifCollection()
* - .ifIndex()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_UpdateLifecyclePolicy.html
*/
toUpdateLifecyclePolicy() {
return this.to('UpdateLifecyclePolicy');
}
/**
* Grants permission to update a security configuration
*
* Access Level: Write
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_UpdateSecurityConfig.html
*/
toUpdateSecurityConfig() {
return this.to('UpdateSecurityConfig');
}
/**
* Grants permission to update a security policy
*
* Access Level: Write
*
* Possible conditions:
* - .ifCollection()
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_UpdateSecurityPolicy.html
*/
toUpdateSecurityPolicy() {
return this.to('UpdateSecurityPolicy');
}
/**
* Grants permission to update an OpenSearch Serverless-managed VPC endpoint
*
* Access Level: Write
*
* https://docs.aws.amazon.com/opensearch-service/latest/ServerlessAPIReference/API_UpdateVpcEndpoint.html
*/
toUpdateVpcEndpoint() {
return this.to('UpdateVpcEndpoint');
}
/**
* Adds a resource of type Collection to the statement
*
* https://docs.aws.amazon.com/opensearch-service/latest/developerguide/serverless-overview.html
*
* @param collectionId - Identifier for the collectionId.
* @param account - Account of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's account.
* @param region - Region of the resource; defaults to `*`, unless using the CDK, where the default is the current Stack's region.
* @param partition - Partition of the AWS account [aws, aws-cn, aws-us-gov]; defaults to `aws`, unless using the CDK, where the default is the current Stack's partition.
*
* Possible conditions:
* - .ifAwsResourceTag()
*/
onCollection(collectionId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:aoss:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:collection/${collectionId}`);
}
/**
* Adds a resource of type Dashboards to the statement
*
* https://docs.aws.amazon.com/opensearch-service/latest/developerguide/serverless-overview.html
*
* @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.
*/
onDashboards(account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:aoss:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:dashboards/default`);
}
/**
* Filters access by the identifier of the collection
*
* https://docs.aws.amazon.com/opensearch-service/latest/developerguide/security-iam-serverless.html#security_iam_serverless-conditionkeys
*
* Applies to actions:
* - .toAPIAccessAll()
* - .toDashboardsAccessAll()
*
* @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`
*/
ifCollectionId(value, operator) {
return this.if(`CollectionId`, value, operator ?? 'StringLike');
}
/**
* Filters access by the collection name
*
* https://docs.aws.amazon.com/opensearch-service/latest/developerguide/security-iam-serverless.html#security_iam_serverless-conditionkeys
*
* Applies to actions:
* - .toAPIAccessAll()
* - .toCreateAccessPolicy()
* - .toCreateLifecyclePolicy()
* - .toCreateSecurityPolicy()
* - .toDashboardsAccessAll()
* - .toDeleteAccessPolicy()
* - .toDeleteLifecyclePolicy()
* - .toDeleteSecurityPolicy()
* - .toGetAccessPolicy()
* - .toGetSecurityPolicy()
* - .toUpdateAccessPolicy()
* - .toUpdateLifecyclePolicy()
* - .toUpdateSecurityPolicy()
*
* @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`
*/
ifCollection(value, operator) {
return this.if(`collection`, value, operator ?? 'StringLike');
}
/**
* Filters access by the index
*
* https://docs.aws.amazon.com/opensearch-service/latest/developerguide/security-iam-serverless.html#security_iam_serverless-conditionkeys
*
* Applies to actions:
* - .toCreateAccessPolicy()
* - .toCreateLifecyclePolicy()
* - .toDeleteAccessPolicy()
* - .toDeleteLifecyclePolicy()
* - .toGetAccessPolicy()
* - .toUpdateAccessPolicy()
* - .toUpdateLifecyclePolicy()
*
* @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`
*/
ifIndex(value, operator) {
return this.if(`index`, value, operator ?? 'StringLike');
}
/**
* Filters access based on the tags that are passed in the request
*
* Applies to actions:
* - .toCreateCollection()
* - .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 access based on the tags associated with the resource
*
* Applies to actions:
* - .toTagResource()
*
* Applies to resource types:
* - Collection
*
* @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
*
* Applies to actions:
* - .toCreateCollection()
* - .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 [aoss](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonopensearchserverless.html).
*
*/
constructor(props) {
super(props);
this.servicePrefix = 'aoss';
this.accessLevelList = {
Write: [
'APIAccessAll',
'CreateAccessPolicy',
'CreateCollection',
'CreateLifecyclePolicy',
'CreateSecurityConfig',
'CreateSecurityPolicy',
'CreateVpcEndpoint',
'DashboardsAccessAll',
'DeleteAccessPolicy',
'DeleteCollection',
'DeleteLifecyclePolicy',
'DeleteSecurityConfig',
'DeleteSecurityPolicy',
'DeleteVpcEndpoint',
'TagResource',
'UntagResource',
'UpdateAccessPolicy',
'UpdateAccountSettings',
'UpdateCollection',
'UpdateLifecyclePolicy',
'UpdateSecurityConfig',
'UpdateSecurityPolicy',
'UpdateVpcEndpoint'
],
Read: [
'BatchGetCollection',
'BatchGetEffectiveLifecyclePolicy',
'BatchGetLifecyclePolicy',
'BatchGetVpcEndpoint',
'GetAccessPolicy',
'GetAccountSettings',
'GetPoliciesStats',
'GetSecurityConfig',
'GetSecurityPolicy'
],
List: [
'ListAccessPolicies',
'ListCollections',
'ListLifecyclePolicies',
'ListSecurityConfigs',
'ListSecurityPolicies',
'ListTagsForResource',
'ListVpcEndpoints'
]
};
}
}
exports.Aoss = Aoss;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbnNlYXJjaHNlcnZlcmxlc3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJvcGVuc2VhcmNoc2VydmVybGVzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSx5Q0FBeUQ7QUFHekQ7Ozs7R0FJRztBQUNILE1BQWEsSUFBSyxTQUFRLHdCQUFlO0lBR3ZDOzs7Ozs7Ozs7O09BVUc7SUFDSSxjQUFjO1FBQ25CLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksb0JBQW9CO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxrQ0FBa0M7UUFDdkMsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGtDQUFrQyxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLHlCQUF5QjtRQUM5QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMseUJBQXlCLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0kscUJBQXFCO1FBQzFCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksb0JBQW9CO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksa0JBQWtCO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksdUJBQXVCO1FBQzVCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxz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QUFrQztnQkFDbEMseUJBQXlCO2dCQUN6QixxQkFBcUI7Z0JBQ3JCLGlCQUFpQjtnQkFDakIsb0JBQW9CO2dCQUNwQixrQkFBa0I7Z0JBQ2xCLG1CQUFtQjtnQkFDbkIsbUJBQW1CO2FBQ3BCO1lBQ0QsSUFBSSxFQUFFO2dCQUNKLG9CQUFvQjtnQkFDcEIsaUJBQWlCO2dCQUNqQix1QkFBdUI7Z0JBQ3ZCLHFCQUFxQjtnQkFDckIsc0JBQXNCO2dCQUN0QixxQkFBcUI7Z0JBQ3JCLGtCQUFrQjthQUNuQjtTQUNGLENBQUM7SUFxSkYsQ0FBQztDQUNGO0FBaHJCRCxvQkFnckJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWNjZXNzTGV2ZWxMaXN0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FjY2Vzcy1sZXZlbCc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQsIE9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcbmltcG9ydCB7IGF3c19pYW0gYXMgaWFtIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5cbi8qKlxuICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFthb3NzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hbWF6b25vcGVuc2VhcmNoc2VydmVybGVzcy5odG1sKS5cbiAqXG4gKiBAcGFyYW0gc2lkIFtTSURdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfc2lkLmh0bWwpIG9mIHRoZSBzdGF0ZW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEFvc3MgZXh0ZW5kcyBQb2xpY3lTdGF0ZW1lbnQge1xuICBwdWJsaWMgc2VydmljZVByZWZpeCA9ICdhb3NzJztcblxuICAvKipcbiAgICogR3JhbnQgcGVybWlzc2lvbiB0byBhbGwgdGhlIHN1cHBvcnRlZCBPcGVuc2VhcmNoIEFQSXNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkNvbGxlY3Rpb24oKVxuICAgKiAtIC5pZkNvbGxlY3Rpb25JZCgpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcGVuc2VhcmNoLXNlcnZpY2UvbGF0ZXN0L1NlcnZlcmxlc3NBUElSZWZlcmVuY2UvQVBJX0FQSUFjY2Vzc0FsbC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9BUElBY2Nlc3NBbGwoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0FQSUFjY2Vzc0FsbCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBhdHRyaWJ1dGVzIGZvciBvbmUgb3IgbW9yZSBjb2xsZWN0aW9uc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfQmF0Y2hHZXRDb2xsZWN0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0JhdGNoR2V0Q29sbGVjdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQmF0Y2hHZXRDb2xsZWN0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IHRoZSBpbmZvcm1hdGlvbiBhYm91dCBhIGxpZmVjeWNsZSBwb2xpY3kgYXBwbGllZCB0byBvbmUgb3IgbW9yZSBBT1NTIHJlc291cmNlc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfQmF0Y2hHZXRFZmZlY3RpdmVMaWZlY3ljbGVQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQmF0Y2hHZXRFZmZlY3RpdmVMaWZlY3ljbGVQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0JhdGNoR2V0RWZmZWN0aXZlTGlmZWN5Y2xlUG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IG9uZSBvciBtb3JlIGxpZmVjeWNsZSBwb2xpY2llc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfQmF0Y2hHZXRMaWZlY3ljbGVQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQmF0Y2hHZXRMaWZlY3ljbGVQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0JhdGNoR2V0TGlmZWN5Y2xlUG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGF0dHJpYnV0ZXMgZm9yIG9uZSBvciBtb3JlIFZQQyBlbmRwb2ludHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcGVuc2VhcmNoLXNlcnZpY2UvbGF0ZXN0L1NlcnZlcmxlc3NBUElSZWZlcmVuY2UvQVBJX0JhdGNoR2V0VnBjRW5kcG9pbnQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQmF0Y2hHZXRWcGNFbmRwb2ludCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQmF0Y2hHZXRWcGNFbmRwb2ludCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIGRhdGEgYWNjZXNzIHBvbGljeVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQ29sbGVjdGlvbigpXG4gICAqIC0gLmlmSW5kZXgoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3BlbnNlYXJjaC1zZXJ2aWNlL2xhdGVzdC9TZXJ2ZXJsZXNzQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVBY2Nlc3NQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlQWNjZXNzUG9saWN5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVBY2Nlc3NQb2xpY3knKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBzZXJ2ZXJsZXNzIGNvbGxlY3Rpb25cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3BlbnNlYXJjaC1zZXJ2aWNlL2xhdGVzdC9TZXJ2ZXJsZXNzQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVDb2xsZWN0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZUNvbGxlY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZUNvbGxlY3Rpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBsaWZlY3ljbGUgcG9saWN5XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZDb2xsZWN0aW9uKClcbiAgICogLSAuaWZJbmRleCgpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcGVuc2VhcmNoLXNlcnZpY2UvbGF0ZXN0L1NlcnZlcmxlc3NBUElSZWZlcmVuY2UvQVBJX0NyZWF0ZUxpZmVjeWNsZVBvbGljeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVMaWZlY3ljbGVQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZUxpZmVjeWNsZVBvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIHNlcnZlcmxlc3Mgc2VjdXJpdHkgY29uZmlndXJhdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcGVuc2VhcmNoLXNlcnZpY2UvbGF0ZXN0L1NlcnZlcmxlc3NBUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVNlY3VyaXR5Q29uZmlnLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVNlY3VyaXR5Q29uZmlnKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVTZWN1cml0eUNvbmZpZycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIG5ldHdvcmsgb3IgZW5jcnlwdGlvbiBwb2xpY3lcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkNvbGxlY3Rpb24oKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3BlbnNlYXJjaC1zZXJ2aWNlL2xhdGVzdC9TZXJ2ZXJsZXNzQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVTZWN1cml0eVBvbGljeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVTZWN1cml0eVBvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlU2VjdXJpdHlQb2xpY3knKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYW4gT3BlblNlYXJjaC1TZXJ2ZXJsZXNzLW1hbmFnZWQgaW50ZXJmYWNlIFZQQyBlbmRwb2ludFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcGVuc2VhcmNoLXNlcnZpY2UvbGF0ZXN0L1NlcnZlcmxlc3NBUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVZwY0VuZHBvaW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVZwY0VuZHBvaW50KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVWcGNFbmRwb2ludCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIE9wZW5zZWFyY2ggU2VydmVybGVzcyBEYXNoYm9hcmRzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZDb2xsZWN0aW9uKClcbiAgICogLSAuaWZDb2xsZWN0aW9uSWQoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3BlbnNlYXJjaC1zZXJ2aWNlL2xhdGVzdC9TZXJ2ZXJsZXNzQVBJUmVmZXJlbmNlL0FQSV9EYXNoYm9hcmRzQWNjZXNzQWxsLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rhc2hib2FyZHNBY2Nlc3NBbGwoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rhc2hib2FyZHNBY2Nlc3NBbGwnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgYSBkYXRhIGFjY2VzcyBwb2xpY3lcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkNvbGxlY3Rpb24oKVxuICAgKiAtIC5pZkluZGV4KClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlQWNjZXNzUG9saWN5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZUFjY2Vzc1BvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlQWNjZXNzUG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGEgc2VydmVybGVzcyBjb2xsZWN0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlQ29sbGVjdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVDb2xsZWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVDb2xsZWN0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGEgbGlmZWN5Y2xlIHBvbGljeVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQ29sbGVjdGlvbigpXG4gICAqIC0gLmlmSW5kZXgoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3BlbnNlYXJjaC1zZXJ2aWNlL2xhdGVzdC9TZXJ2ZXJsZXNzQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVMaWZlY3ljbGVQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlTGlmZWN5Y2xlUG9saWN5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVMaWZlY3ljbGVQb2xpY3knKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgYSBzZWN1cml0eSBjb25maWd1cmF0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlU2VjdXJpdHlDb25maWcuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlU2VjdXJpdHlDb25maWcoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVNlY3VyaXR5Q29uZmlnJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGEgc2VjdXJpdHkgcG9saWN5XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZDb2xsZWN0aW9uKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlU2VjdXJpdHlQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlU2VjdXJpdHlQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVNlY3VyaXR5UG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGFuIE9wZW5TZWFyY2ggU2VydmVybGVzcy1tYW5hZ2VkIGludGVyZmFjZSBWUEMgZW5kcG9pbnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3BlbnNlYXJjaC1zZXJ2aWNlL2xhdGVzdC9TZXJ2ZXJsZXNzQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVWcGNFbmRwb2ludC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVWcGNFbmRwb2ludCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlVnBjRW5kcG9pbnQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgaW5mb3JtYXRpb24gYWJvdXQgYSBkYXRhIGFjY2VzcyBwb2xpY3lcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQ29sbGVjdGlvbigpXG4gICAqIC0gLmlmSW5kZXgoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3BlbnNlYXJjaC1zZXJ2aWNlL2xhdGVzdC9TZXJ2ZXJsZXNzQVBJUmVmZXJlbmNlL0FQSV9HZXRBY2Nlc3NQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0QWNjZXNzUG9saWN5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRBY2Nlc3NQb2xpY3knKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgYWNjb3VudCBzZXR0aW5ncywgaW5jbHVkaW5nIGNhcGFjaXR5IHNldHRpbmdzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3BlbnNlYXJjaC1zZXJ2aWNlL2xhdGVzdC9TZXJ2ZXJsZXNzQVBJUmVmZXJlbmNlL0FQSV9HZXRBY2NvdW50U2V0dGluZ3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0QWNjb3VudFNldHRpbmdzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRBY2NvdW50U2V0dGluZ3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgc3RhdGlzdGlzIGFib3V0IHRoZSBzZWN1cml0eSBwb2xpY2llcyBpbiB5b3VyIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcGVuc2VhcmNoLXNlcnZpY2UvbGF0ZXN0L1NlcnZlcmxlc3NBUElSZWZlcmVuY2UvQVBJX0dldFBvbGljaWVzU3RhdHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0UG9saWNpZXNTdGF0cygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0UG9saWNpZXNTdGF0cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBpbmZvcm1hdGlvbiBhYm91dCBhIHNlcnZlcmxlc3Mgc2VjdXJpdHkgY29uZmlndXJhdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfR2V0U2VjdXJpdHlDb25maWcuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0U2VjdXJpdHlDb25maWcoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldFNlY3VyaXR5Q29uZmlnJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IGEgc2VjdXJpdHkgcG9saWN5XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkNvbGxlY3Rpb24oKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3BlbnNlYXJjaC1zZXJ2aWNlL2xhdGVzdC9TZXJ2ZXJsZXNzQVBJUmVmZXJlbmNlL0FQSV9HZXRTZWN1cml0eVBvbGljeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRTZWN1cml0eVBvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0U2VjdXJpdHlQb2xpY3knKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGRhdGEgYWNjZXNzIHBvbGljaWVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3BlbnNlYXJjaC1zZXJ2aWNlL2xhdGVzdC9TZXJ2ZXJsZXNzQVBJUmVmZXJlbmNlL0FQSV9MaXN0QWNjZXNzUG9saWNpZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdEFjY2Vzc1BvbGljaWVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0QWNjZXNzUG9saWNpZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGNvbGxlY3Rpb25zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3BlbnNlYXJjaC1zZXJ2aWNlL2xhdGVzdC9TZXJ2ZXJsZXNzQVBJUmVmZXJlbmNlL0FQSV9MaXN0Q29sbGVjdGlvbnMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdENvbGxlY3Rpb25zKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0Q29sbGVjdGlvbnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGxpZmVjeWNsZSBwb2xpY2llc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfTGlzdExpZmVjeWNsZVBvbGljaWVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RMaWZlY3ljbGVQb2xpY2llcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdExpZmVjeWNsZVBvbGljaWVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBzZWN1cml0eSBjb25maWd1cmF0aW9uc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfTGlzdFNlY3VyaXR5Q29uZmlncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0U2VjdXJpdHlDb25maWdzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0U2VjdXJpdHlDb25maWdzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCBzZWN1cml0eSBwb2xpY2llc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfTGlzdFNlY3VyaXR5UG9saWNpZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFNlY3VyaXR5UG9saWNpZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RTZWN1cml0eVBvbGljaWVzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCB0YWdzIGZvciBhIGNvbGxlY3Rpb25cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcGVuc2VhcmNoLXNlcnZpY2UvbGF0ZXN0L1NlcnZlcmxlc3NBUElSZWZlcmVuY2UvQVBJX0xpc3RUYWdzRm9yUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFRhZ3NGb3JSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFRhZ3NGb3JSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgT3BlblNlYXJjaCBTZXJ2ZXJsZXNzLW1hbmFnZWQgVlBDIGVuZHBvaW50c1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfTGlzdFZwY0VuZHBvaW50cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0VnBjRW5kcG9pbnRzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0VnBjRW5kcG9pbnRzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdGFnIGEgc2VydmVybGVzcyBjb2xsZWN0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcGVuc2VhcmNoLXNlcnZpY2UvbGF0ZXN0L1NlcnZlcmxlc3NBUElSZWZlcmVuY2UvQVBJX1RhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1RhZ1Jlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdUYWdSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSB0YWdzIGZyb20gYSBjb2xsZWN0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfVW50YWdSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VbnRhZ1Jlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVbnRhZ1Jlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIGEgZGF0YSBhY2Nlc3MgcG9saWN5XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZDb2xsZWN0aW9uKClcbiAgICogLSAuaWZJbmRleCgpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcGVuc2VhcmNoLXNlcnZpY2UvbGF0ZXN0L1NlcnZlcmxlc3NBUElSZWZlcmVuY2UvQVBJX1VwZGF0ZUFjY2Vzc1BvbGljeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVBY2Nlc3NQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZUFjY2Vzc1BvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSBhY2NvdW50IHNldHRpbmdzLCBpbmNsdWRpbmcgY2FwYWNpdHkgc2V0dGluZ3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3BlbnNlYXJjaC1zZXJ2aWNlL2xhdGVzdC9TZXJ2ZXJsZXNzQVBJUmVmZXJlbmNlL0FQSV9VcGRhdGVBY2NvdW50U2V0dGluZ3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlQWNjb3VudFNldHRpbmdzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVBY2NvdW50U2V0dGluZ3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgYSBjb2xsZWN0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlQ29sbGVjdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVDb2xsZWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVDb2xsZWN0aW9uJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIGEgbGlmZWN5Y2xlIHBvbGljeVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQ29sbGVjdGlvbigpXG4gICAqIC0gLmlmSW5kZXgoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3BlbnNlYXJjaC1zZXJ2aWNlL2xhdGVzdC9TZXJ2ZXJsZXNzQVBJUmVmZXJlbmNlL0FQSV9VcGRhdGVMaWZlY3ljbGVQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlTGlmZWN5Y2xlUG9saWN5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVMaWZlY3ljbGVQb2xpY3knKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgYSBzZWN1cml0eSBjb25maWd1cmF0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlU2VjdXJpdHlDb25maWcuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlU2VjdXJpdHlDb25maWcoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZVNlY3VyaXR5Q29uZmlnJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIGEgc2VjdXJpdHkgcG9saWN5XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZDb2xsZWN0aW9uKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29wZW5zZWFyY2gtc2VydmljZS9sYXRlc3QvU2VydmVybGVzc0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlU2VjdXJpdHlQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlU2VjdXJpdHlQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZVNlY3VyaXR5UG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIGFuIE9wZW5TZWFyY2ggU2VydmVybGVzcy1tYW5hZ2VkIFZQQyBlbmRwb2ludFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcGVuc2VhcmNoLXNlcnZpY2UvbGF0ZXN0L1NlcnZlcmxlc3NBUElSZWZlcmVuY2UvQVBJX1VwZGF0ZVZwY0VuZHBvaW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZVZwY0VuZHBvaW50KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVWcGNFbmRwb2ludCcpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFjY2Vzc0xldmVsTGlzdDogQWNjZXNzTGV2ZWxMaXN0ID0ge1xuICAgIFdyaXRlOiBbXG4gICAgICAnQVBJQWNjZXNzQWxsJyxcbiAgICAgICdDcmVhdGVBY2Nlc3NQb2xpY3knLFxuICAgICAgJ0NyZWF0ZUNvbGxlY3Rpb24nLFxuICAgICAgJ0NyZWF0ZUxpZmVjeWNsZVBvbGljeScsXG4gICAgICAnQ3JlYXRlU2VjdXJpdHlDb25maWcnLFxuICAgICAgJ0NyZWF0ZVNlY3VyaXR5UG9saWN5JyxcbiAgICAgICdDcmVhdGVWcGNFbmRwb2ludCcsXG4gICAgICAnRGFzaGJvYXJkc0FjY2Vzc0FsbCcsXG4gICAgICAnRGVsZXRlQWNjZXNzUG9saWN5JyxcbiAgICAgICdEZWxldGVDb2xsZWN0aW9uJyxcbiAgICAgICdEZWxldGVMaWZlY3ljbGVQb2xpY3knLFxuICAgICAgJ0RlbGV0ZVNlY3VyaXR5Q29uZmlnJyxcbiAgICAgICdEZWxldGVTZWN1cml0eVBvbGljeScsXG4gICAgICAnRGVsZXRlVnBjRW5kcG9pbnQnLFxuICAgICAgJ1RhZ1Jlc291cmNlJyxcbiAgICAgICdVbnRhZ1Jlc291cmNlJyxcbiAgICAgICdVcGRhdGVBY2Nlc3NQb2xpY3knLFxuICAgICAgJ1VwZGF0ZUFjY291bnRTZXR0aW5ncycsXG4gICAgICAnVXBkYXRlQ29sbGVjdGlvbicsXG4gICAgICAnVXBkYXRlTGlmZWN5Y2xlUG9saWN5JyxcbiAgICAgICdVcGRhdGVTZWN1cml0eUNvbmZpZycsXG4gICAgICAnVXBkYXRlU2VjdXJpdHlQb2xpY3knLFxuICAgICAgJ1VwZGF0ZVZwY0VuZHBvaW50J1xuICAgIF0sXG4gICAgUmVhZDogW1xuICAgICAgJ0JhdGNoR2V0Q29sbGVjdGlvbicsXG4gICAgICAnQmF0Y2hHZXRFZmZlY3RpdmVMaWZlY3ljbGVQb2xpY3knLFxuICAgICAgJ0JhdGNoR2V0TGlmZWN5Y2xlUG9saWN5JyxcbiAgICAgICdCYXRjaEdldFZwY0VuZHBvaW50JyxcbiAgICAgICdHZXRBY2Nlc3NQb2xpY3knLFxuICAgICAgJ0dldEFjY291bnRTZXR0aW5ncycsXG4gICAgICAnR2V0UG9saWNpZXNTdGF0cycsXG4gICAgICAnR2V0U2VjdXJpdHlDb25maWcnLFxuICAgICAgJ0dldFNlY3VyaXR5UG9saWN5J1xuICAgIF0sXG4gICAgTGlzdDogW1xuICAgICAgJ0xpc3RBY2Nlc3NQb2xpY2llcycsXG4gICAgICAnTGlzdENvbGxlY3Rpb25zJyxcbiAgICAgICdMaXN0TGlmZWN5Y2xlUG9saWNpZXMnLFxuICAgICAgJ0xpc3RTZWN1cml0eUNvbmZpZ3MnLFxuICAgICAgJ0xpc3RTZWN1cml0eVBvbGljaWVzJyxcbiAgICAgICdMaXN0VGFnc0ZvclJlc291cmNlJyxcbiAgICAgICdMaXN0VnBjRW5kcG9pbnRzJ1xuICAgIF1cbiAgfTtcblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgQ29sbGVjdGlvbiB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcGVuc2VhcmNoLXNlcnZpY2UvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3NlcnZlcmxlc3Mtb3ZlcnZpZXcuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbklkIC0gSWRlbnRpZmllciBmb3IgdGhlIGNvbGxlY3Rpb25JZC5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKi9cbiAgcHVibGljIG9uQ29sbGVjdGlvbihjb2xsZWN0aW9uSWQ6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTphb3NzOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpjb2xsZWN0aW9uLyR7IGNvbGxlY3Rpb25JZCB9YCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgRGFzaGJvYXJkcyB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcGVuc2VhcmNoLXNlcnZpY2UvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3NlcnZlcmxlc3Mtb3ZlcnZpZXcuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICovXG4gIHB1YmxpYyBvbkRhc2hib2FyZHMoYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTphb3NzOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpkYXNoYm9hcmRzL2RlZmF1bHRgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgaWRlbnRpZmllciBvZiB0aGUgY29sbGVjdGlvblxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3BlbnNlYXJjaC1zZXJ2aWNlL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zZWN1cml0eS1pYW0tc2VydmVybGVzcy5odG1sI3NlY3VyaXR5X2lhbV9zZXJ2ZXJsZXNzLWNvbmRpdGlvbmtleXNcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0FQSUFjY2Vzc0FsbCgpXG4gICAqIC0gLnRvRGFzaGJvYXJkc0FjY2Vzc0FsbCgpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQ29sbGVjdGlvbklkKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBDb2xsZWN0aW9uSWRgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB0aGUgY29sbGVjdGlvbiBuYW1lXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcGVuc2VhcmNoLXNlcnZpY2UvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3NlY3VyaXR5LWlhbS1zZXJ2ZXJsZXNzLmh0bWwjc2VjdXJpdHlfaWFtX3NlcnZlcmxlc3MtY29uZGl0aW9ua2V5c1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQVBJQWNjZXNzQWxsKClcbiAgICogLSAudG9DcmVhdGVBY2Nlc3NQb2xpY3koKVxuICAgKiAtIC50b0NyZWF0ZUxpZmVjeWNsZVBvbGljeSgpXG4gICAqIC0gLnRvQ3JlYXRlU2VjdXJpdHlQb2xpY3koKVxuICAgKiAtIC50b0Rhc2hib2FyZHNBY2Nlc3NBbGwoKVxuICAgKiAtIC50b0RlbGV0ZUFjY2Vzc1BvbGljeSgpXG4gICAqIC0gLnRvRGVsZXRlTGlmZWN5Y2xlUG9saWN5KClcbiAgICogLSAudG9EZWxldGVTZWN1cml0eVBvbGljeSgpXG4gICAqIC0gLnRvR2V0QWNjZXNzUG9saWN5KClcbiAgICogLSAudG9HZXRTZWN1cml0eVBvbGljeSgpXG4gICAqIC0gLnRvVXBkYXRlQWNjZXNzUG9saWN5KClcbiAgICogLSAudG9VcGRhdGVMaWZlY3ljbGVQb2xpY3koKVxuICAgKiAtIC50b1VwZGF0ZVNlY3VyaXR5UG9saWN5KClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZDb2xsZWN0aW9uKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBjb2xsZWN0aW9uYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIGluZGV4XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcGVuc2VhcmNoLXNlcnZpY2UvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3NlY3VyaXR5LWlhbS1zZXJ2ZXJsZXNzLmh0bWwjc2VjdXJpdHlfaWFtX3NlcnZlcmxlc3MtY29uZGl0aW9ua2V5c1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ3JlYXRlQWNjZXNzUG9saWN5KClcbiAgICogLSAudG9DcmVhdGVMaWZlY3ljbGVQb2xpY3koKVxuICAgKiAtIC50b0RlbGV0ZUFjY2Vzc1BvbGljeSgpXG4gICAqIC0gLnRvRGVsZXRlTGlmZWN5Y2xlUG9saWN5KClcbiAgICogLSAudG9HZXRBY2Nlc3NQb2xpY3koKVxuICAgKiAtIC50b1VwZGF0ZUFjY2Vzc1BvbGljeSgpXG4gICAqIC0gLnRvVXBkYXRlTGlmZWN5Y2xlUG9saWN5KClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZJbmRleCh2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgaW5kZXhgLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBiYXNlZCBvbiB0aGUgdGFncyB0aGF0IGFyZSBwYXNzZWQgaW4gdGhlIHJlcXVlc3RcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NyZWF0ZUNvbGxlY3Rpb24oKVxuICAgKiAtIC50b1RhZ1Jlc291cmNlKClcbiAgICpcbiAgICogQHBhcmFtIHRhZ0tleSBUaGUgdGFnIGtleSB0byBjaGVja1xuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkF3c1JlcXVlc3RUYWcodGFnS2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6UmVxdWVzdFRhZy8keyB0YWdLZXkgfWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJhc2VkIG9uIHRoZSB0YWdzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVzb3VyY2VcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b1RhZ1Jlc291cmNlKClcbiAgICpcbiAgICogQXBwbGllcyB0byByZXNvdXJjZSB0eXBlczpcbiAgICogLSBDb2xsZWN0aW9uXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXNvdXJjZVRhZyh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpSZXNvdXJjZVRhZy8keyB0YWdLZXkgfWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJhc2VkIG9uIHRoZSB0YWcga2V5cyB0aGF0IGFyZSBwYXNzZWQgaW4gdGhlIHJlcXVlc3RcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NyZWF0ZUNvbGxlY3Rpb24oKVxuICAgKiAtIC50b1RhZ1Jlc291cmNlKClcbiAgICogLSAudG9VbnRhZ1Jlc291cmNlKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NUYWdLZXlzKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6VGFnS2V5c2AsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbYW9zc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYW1hem9ub3BlbnNlYXJjaHNlcnZlcmxlc3MuaHRtbCkuXG4gICAqXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihwcm9wcz86IGlhbS5Qb2xpY3lTdGF0ZW1lbnRQcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgfVxufVxuIl19