cdk-iam-floyd
Version:
AWS IAM policy statement generator with fluent interface for AWS CDK
562 lines • 54.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CleanroomsMl = void 0;
const shared_1 = require("../../shared");
/**
* Statement provider for service [cleanrooms-ml](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awscleanroomsml.html).
*
* @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
*/
class CleanroomsMl extends shared_1.PolicyStatement {
/**
* Grants permission to create an audience model
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_CreateAudienceModel.html
*/
toCreateAudienceModel() {
return this.to('CreateAudienceModel');
}
/**
* Grants permission to create a configured audience model
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_CreateConfiguredAudienceModel.html
*/
toCreateConfiguredAudienceModel() {
return this.to('CreateConfiguredAudienceModel');
}
/**
* Grants permission to create a training dataset, or seed audience. In Clean Rooms ML, the TrainingDataset is metadata that points to a Glue table, which is read only during AudienceModel creation
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_CreateTrainingDataset.html
*/
toCreateTrainingDataset() {
return this.to('CreateTrainingDataset');
}
/**
* Grants permission to delete the specified audience generation job, and removes all data associated with the job
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_DeleteAudienceGenerationJob.html
*/
toDeleteAudienceGenerationJob() {
return this.to('DeleteAudienceGenerationJob');
}
/**
* Grants permission to delete the specified audience generation job, and removes all data associated with the job
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_DeleteAudienceModel.html
*/
toDeleteAudienceModel() {
return this.to('DeleteAudienceModel');
}
/**
* Grants permission to delete the specified configured audience model
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_DeleteConfiguredAudienceModel.html
*/
toDeleteConfiguredAudienceModel() {
return this.to('DeleteConfiguredAudienceModel');
}
/**
* Grants permission to delete the specified configured audience model policy
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_DeleteConfiguredAudienceModelPolicy.html
*/
toDeleteConfiguredAudienceModelPolicy() {
return this.to('DeleteConfiguredAudienceModelPolicy');
}
/**
* Grants permission to delete a training dataset
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_DeleteTrainingDataset.html
*/
toDeleteTrainingDataset() {
return this.to('DeleteTrainingDataset');
}
/**
* Grants permission to return information about an audience generation job
*
* Access Level: Read
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_GetAudienceGenerationJob.html
*/
toGetAudienceGenerationJob() {
return this.to('GetAudienceGenerationJob');
}
/**
* Grants permission to return information about an audience model
*
* Access Level: Read
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_GetAudienceModel.html
*/
toGetAudienceModel() {
return this.to('GetAudienceModel');
}
/**
* Grants permission to return information about a configured audience model
*
* Access Level: Read
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_GetConfiguredAudienceModel.html
*/
toGetConfiguredAudienceModel() {
return this.to('GetConfiguredAudienceModel');
}
/**
* Grants permission to return information about a configured audience model policy
*
* Access Level: Read
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_GetConfiguredAudienceModelPolicy.html
*/
toGetConfiguredAudienceModelPolicy() {
return this.to('GetConfiguredAudienceModelPolicy');
}
/**
* Grants permission to return information about a training dataset
*
* Access Level: Read
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_GetTrainingDataset.html
*/
toGetTrainingDataset() {
return this.to('GetTrainingDataset');
}
/**
* Grants permission to return a list of the audience export jobs
*
* Access Level: List
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_ListAudienceExportJobs.html
*/
toListAudienceExportJobs() {
return this.to('ListAudienceExportJobs');
}
/**
* Grants permission to return a list of audience generation jobs
*
* Access Level: List
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_ListAudienceGenerationJobs.html
*/
toListAudienceGenerationJobs() {
return this.to('ListAudienceGenerationJobs');
}
/**
* Grants permission to return a list of audience models
*
* Access Level: List
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_ListAudienceModels.html
*/
toListAudienceModels() {
return this.to('ListAudienceModels');
}
/**
* Grants permission to return a list of configured audience models
*
* Access Level: List
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_ListConfiguredAudienceModels.html
*/
toListConfiguredAudienceModels() {
return this.to('ListConfiguredAudienceModels');
}
/**
* Grants permission to return a list of tags for a provided resource
*
* Access Level: List
*
* Possible conditions:
* - .ifAwsTagKeys()
* - .ifAwsResourceTag()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_ListTagsForResource.html
*/
toListTagsForResource() {
return this.to('ListTagsForResource');
}
/**
* Grants permission to return a list of training datasets
*
* Access Level: List
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_ListTrainingDatasets.html
*/
toListTrainingDatasets() {
return this.to('ListTrainingDatasets');
}
/**
* Grants permission to create or update the resource policy for a configured audience model
*
* Access Level: Permissions management
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_PutConfiguredAudienceModelPolicy.html
*/
toPutConfiguredAudienceModelPolicy() {
return this.to('PutConfiguredAudienceModelPolicy');
}
/**
* Grants permission to export an audience of a specified size after you have generated an audience
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_StartAudienceExportJob.html
*/
toStartAudienceExportJob() {
return this.to('StartAudienceExportJob');
}
/**
* Grants permission to start the audience generation job
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
* - .ifCollaborationId()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_StartAudienceGenerationJob.html
*/
toStartAudienceGenerationJob() {
return this.to('StartAudienceGenerationJob');
}
/**
* Grants permission to tag a specific resource
*
* Access Level: Tagging
*
* Possible conditions:
* - .ifAwsTagKeys()
* - .ifAwsRequestTag()
* - .ifAwsResourceTag()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_TagResource.html
*/
toTagResource() {
return this.to('TagResource');
}
/**
* Grants permission to untag a specific resource
*
* Access Level: Tagging
*
* Possible conditions:
* - .ifAwsTagKeys()
* - .ifAwsResourceTag()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_UntagResource.html
*/
toUnTagResource() {
return this.to('UnTagResource');
}
/**
* Grants permission to update a configured audience model.
*
* Access Level: Write
*
* Possible conditions:
* - .ifAwsRequestTag()
* - .ifAwsTagKeys()
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_UpdateConfiguredAudienceModel.html
*/
toUpdateConfiguredAudienceModel() {
return this.to('UpdateConfiguredAudienceModel');
}
/**
* Adds a resource of type trainingdataset to the statement
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_TrainingDatasetSummary.html
*
* @param resourceId - Identifier for the resourceId.
* @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()
*/
onTrainingdataset(resourceId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:cleanrooms-ml:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:training-dataset/${resourceId}`);
}
/**
* Adds a resource of type audiencemodel to the statement
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_AudienceModelSummary.html
*
* @param resourceId - Identifier for the resourceId.
* @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()
*/
onAudiencemodel(resourceId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:cleanrooms-ml:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:audience-model/${resourceId}`);
}
/**
* Adds a resource of type configuredaudiencemodel to the statement
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_ConfiguredAudienceModelSummary.html
*
* @param resourceId - Identifier for the resourceId.
* @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()
*/
onConfiguredaudiencemodel(resourceId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:cleanrooms-ml:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:configured-audience-model/${resourceId}`);
}
/**
* Adds a resource of type audiencegenerationjob to the statement
*
* https://docs.aws.amazon.com/cleanrooms-ml/latest/APIReference/API_AudienceGenerationJobSummary.html
*
* @param resourceId - Identifier for the resourceId.
* @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()
*/
onAudiencegenerationjob(resourceId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:cleanrooms-ml:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:audience-generation-job/${resourceId}`);
}
/**
* Filters access by 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:
* - .toCreateAudienceModel()
* - .toCreateConfiguredAudienceModel()
* - .toCreateTrainingDataset()
* - .toDeleteAudienceGenerationJob()
* - .toDeleteAudienceModel()
* - .toDeleteConfiguredAudienceModel()
* - .toDeleteConfiguredAudienceModelPolicy()
* - .toDeleteTrainingDataset()
* - .toGetAudienceGenerationJob()
* - .toGetAudienceModel()
* - .toGetConfiguredAudienceModel()
* - .toGetConfiguredAudienceModelPolicy()
* - .toGetTrainingDataset()
* - .toListAudienceExportJobs()
* - .toListAudienceGenerationJobs()
* - .toStartAudienceExportJob()
* - .toStartAudienceGenerationJob()
* - .toTagResource()
* - .toUpdateConfiguredAudienceModel()
*
* @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 by 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:
* - .toListTagsForResource()
* - .toTagResource()
* - .toUnTagResource()
*
* Applies to resource types:
* - trainingdataset
* - audiencemodel
* - configuredaudiencemodel
* - audiencegenerationjob
*
* @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 by 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:
* - .toCreateAudienceModel()
* - .toCreateConfiguredAudienceModel()
* - .toCreateTrainingDataset()
* - .toDeleteAudienceGenerationJob()
* - .toDeleteAudienceModel()
* - .toDeleteConfiguredAudienceModel()
* - .toDeleteConfiguredAudienceModelPolicy()
* - .toDeleteTrainingDataset()
* - .toGetAudienceGenerationJob()
* - .toGetAudienceModel()
* - .toGetConfiguredAudienceModel()
* - .toGetConfiguredAudienceModelPolicy()
* - .toGetTrainingDataset()
* - .toListAudienceExportJobs()
* - .toListAudienceGenerationJobs()
* - .toListTagsForResource()
* - .toStartAudienceExportJob()
* - .toStartAudienceGenerationJob()
* - .toTagResource()
* - .toUnTagResource()
* - .toUpdateConfiguredAudienceModel()
*
* @param value The value(s) to check
* @param operator Works with [string operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_String). **Default:** `StringLike`
*/
ifAwsTagKeys(value, operator) {
return this.if(`aws:TagKeys`, value, operator ?? 'StringLike');
}
/**
* Filters access by clean rooms collaboration id
*
* https://docs.aws.amazon.com/TBD
*
* Applies to actions:
* - .toStartAudienceGenerationJob()
*
* @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`
*/
ifCollaborationId(value, operator) {
return this.if(`CollaborationId`, value, operator ?? 'StringLike');
}
/**
* Statement provider for service [cleanrooms-ml](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awscleanroomsml.html).
*
*/
constructor(props) {
super(props);
this.servicePrefix = 'cleanrooms-ml';
this.accessLevelList = {
Write: [
'CreateAudienceModel',
'CreateConfiguredAudienceModel',
'CreateTrainingDataset',
'DeleteAudienceGenerationJob',
'DeleteAudienceModel',
'DeleteConfiguredAudienceModel',
'DeleteConfiguredAudienceModelPolicy',
'DeleteTrainingDataset',
'StartAudienceExportJob',
'StartAudienceGenerationJob',
'UpdateConfiguredAudienceModel'
],
Read: [
'GetAudienceGenerationJob',
'GetAudienceModel',
'GetConfiguredAudienceModel',
'GetConfiguredAudienceModelPolicy',
'GetTrainingDataset'
],
List: [
'ListAudienceExportJobs',
'ListAudienceGenerationJobs',
'ListAudienceModels',
'ListConfiguredAudienceModels',
'ListTagsForResource',
'ListTrainingDatasets'
],
'Permissions management': [
'PutConfiguredAudienceModelPolicy'
],
Tagging: [
'TagResource',
'UnTagResource'
]
};
}
}
exports.CleanroomsMl = CleanroomsMl;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xlYW5yb29tc21sLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY2xlYW5yb29tc21sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHlDQUF5RDtBQUd6RDs7OztHQUlHO0FBQ0gsTUFBYSxZQUFhLFNBQVEsd0JBQWU7SUFHL0M7Ozs7Ozs7Ozs7T0FVRztJQUNJLHFCQUFxQjtRQUMxQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLCtCQUErQjtRQUNwQyxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsK0JBQStCLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLHVCQUF1QjtRQUM1QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLDZCQUE2QjtRQUNsQyxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsNkJBQTZCLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLHFCQUFxQjtRQUMxQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLCtCQUErQjtRQUNwQyxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsK0JBQStCLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLHFDQUFxQztRQUMxQyxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMscUNBQXFDLENBQUMsQ0FBQztJQUN4RCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLHVCQUF1QjtRQUM1QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FV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QUFrQzthQUNuQztZQUNELE9BQU8sRUFBRTtnQkFDUCxhQUFhO2dCQUNiLGVBQWU7YUFDaEI7U0FDRixDQUFDO0lBd0xGLENBQUM7Q0FDRjtBQXprQkQsb0NBeWtCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFjY2Vzc0xldmVsTGlzdCB9IGZyb20gJy4uLy4uL3NoYXJlZC9hY2Nlc3MtbGV2ZWwnO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50LCBPcGVyYXRvciB9IGZyb20gJy4uLy4uL3NoYXJlZCc7XG5pbXBvcnQgeyBhd3NfaWFtIGFzIGlhbSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuXG4vKipcbiAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbY2xlYW5yb29tcy1tbF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYXdzY2xlYW5yb29tc21sLmh0bWwpLlxuICpcbiAqIEBwYXJhbSBzaWQgW1NJRF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19zaWQuaHRtbCkgb2YgdGhlIHN0YXRlbWVudFxuICovXG5leHBvcnQgY2xhc3MgQ2xlYW5yb29tc01sIGV4dGVuZHMgUG9saWN5U3RhdGVtZW50IHtcbiAgcHVibGljIHNlcnZpY2VQcmVmaXggPSAnY2xlYW5yb29tcy1tbCc7XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhbiBhdWRpZW5jZSBtb2RlbFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZUF1ZGllbmNlTW9kZWwuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlQXVkaWVuY2VNb2RlbCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlQXVkaWVuY2VNb2RlbCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIGNvbmZpZ3VyZWQgYXVkaWVuY2UgbW9kZWxcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xlYW5yb29tcy1tbC9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVDb25maWd1cmVkQXVkaWVuY2VNb2RlbC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVDb25maWd1cmVkQXVkaWVuY2VNb2RlbCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlQ29uZmlndXJlZEF1ZGllbmNlTW9kZWwnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSB0cmFpbmluZyBkYXRhc2V0LCBvciBzZWVkIGF1ZGllbmNlLiBJbiBDbGVhbiBSb29tcyBNTCwgdGhlIFRyYWluaW5nRGF0YXNldCBpcyBtZXRhZGF0YSB0aGF0IHBvaW50cyB0byBhIEdsdWUgdGFibGUsIHdoaWNoIGlzIHJlYWQgb25seSBkdXJpbmcgQXVkaWVuY2VNb2RlbCBjcmVhdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NyZWF0ZVRyYWluaW5nRGF0YXNldC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVUcmFpbmluZ0RhdGFzZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZVRyYWluaW5nRGF0YXNldCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSB0aGUgc3BlY2lmaWVkIGF1ZGllbmNlIGdlbmVyYXRpb24gam9iLCBhbmQgcmVtb3ZlcyBhbGwgZGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIGpvYlxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZUF1ZGllbmNlR2VuZXJhdGlvbkpvYi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVBdWRpZW5jZUdlbmVyYXRpb25Kb2IoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZUF1ZGllbmNlR2VuZXJhdGlvbkpvYicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSB0aGUgc3BlY2lmaWVkIGF1ZGllbmNlIGdlbmVyYXRpb24gam9iLCBhbmQgcmVtb3ZlcyBhbGwgZGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIGpvYlxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZUF1ZGllbmNlTW9kZWwuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlQXVkaWVuY2VNb2RlbCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlQXVkaWVuY2VNb2RlbCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSB0aGUgc3BlY2lmaWVkIGNvbmZpZ3VyZWQgYXVkaWVuY2UgbW9kZWxcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xlYW5yb29tcy1tbC9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVDb25maWd1cmVkQXVkaWVuY2VNb2RlbC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVDb25maWd1cmVkQXVkaWVuY2VNb2RlbCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlQ29uZmlndXJlZEF1ZGllbmNlTW9kZWwnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgdGhlIHNwZWNpZmllZCBjb25maWd1cmVkIGF1ZGllbmNlIG1vZGVsIHBvbGljeVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZUNvbmZpZ3VyZWRBdWRpZW5jZU1vZGVsUG9saWN5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZUNvbmZpZ3VyZWRBdWRpZW5jZU1vZGVsUG9saWN5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVDb25maWd1cmVkQXVkaWVuY2VNb2RlbFBvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhIHRyYWluaW5nIGRhdGFzZXRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xlYW5yb29tcy1tbC9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZWxldGVUcmFpbmluZ0RhdGFzZXQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlVHJhaW5pbmdEYXRhc2V0KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWxldGVUcmFpbmluZ0RhdGFzZXQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXR1cm4gaW5mb3JtYXRpb24gYWJvdXQgYW4gYXVkaWVuY2UgZ2VuZXJhdGlvbiBqb2JcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dldEF1ZGllbmNlR2VuZXJhdGlvbkpvYi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRBdWRpZW5jZUdlbmVyYXRpb25Kb2IoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldEF1ZGllbmNlR2VuZXJhdGlvbkpvYicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHVybiBpbmZvcm1hdGlvbiBhYm91dCBhbiBhdWRpZW5jZSBtb2RlbFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsZWFucm9vbXMtbWwvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0QXVkaWVuY2VNb2RlbC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRBdWRpZW5jZU1vZGVsKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRBdWRpZW5jZU1vZGVsJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmV0dXJuIGluZm9ybWF0aW9uIGFib3V0IGEgY29uZmlndXJlZCBhdWRpZW5jZSBtb2RlbFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsZWFucm9vbXMtbWwvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0Q29uZmlndXJlZEF1ZGllbmNlTW9kZWwuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0Q29uZmlndXJlZEF1ZGllbmNlTW9kZWwoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldENvbmZpZ3VyZWRBdWRpZW5jZU1vZGVsJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmV0dXJuIGluZm9ybWF0aW9uIGFib3V0IGEgY29uZmlndXJlZCBhdWRpZW5jZSBtb2RlbCBwb2xpY3lcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dldENvbmZpZ3VyZWRBdWRpZW5jZU1vZGVsUG9saWN5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldENvbmZpZ3VyZWRBdWRpZW5jZU1vZGVsUG9saWN5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRDb25maWd1cmVkQXVkaWVuY2VNb2RlbFBvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHVybiBpbmZvcm1hdGlvbiBhYm91dCBhIHRyYWluaW5nIGRhdGFzZXRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0dldFRyYWluaW5nRGF0YXNldC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRUcmFpbmluZ0RhdGFzZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldFRyYWluaW5nRGF0YXNldCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHVybiBhIGxpc3Qgb2YgdGhlIGF1ZGllbmNlIGV4cG9ydCBqb2JzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xlYW5yb29tcy1tbC9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0QXVkaWVuY2VFeHBvcnRKb2JzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RBdWRpZW5jZUV4cG9ydEpvYnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RBdWRpZW5jZUV4cG9ydEpvYnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXR1cm4gYSBsaXN0IG9mIGF1ZGllbmNlIGdlbmVyYXRpb24gam9ic1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsZWFucm9vbXMtbWwvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdEF1ZGllbmNlR2VuZXJhdGlvbkpvYnMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdEF1ZGllbmNlR2VuZXJhdGlvbkpvYnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RBdWRpZW5jZUdlbmVyYXRpb25Kb2JzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmV0dXJuIGEgbGlzdCBvZiBhdWRpZW5jZSBtb2RlbHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RBdWRpZW5jZU1vZGVscy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0QXVkaWVuY2VNb2RlbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RBdWRpZW5jZU1vZGVscycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHVybiBhIGxpc3Qgb2YgY29uZmlndXJlZCBhdWRpZW5jZSBtb2RlbHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RDb25maWd1cmVkQXVkaWVuY2VNb2RlbHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdENvbmZpZ3VyZWRBdWRpZW5jZU1vZGVscygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdENvbmZpZ3VyZWRBdWRpZW5jZU1vZGVscycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHVybiBhIGxpc3Qgb2YgdGFncyBmb3IgYSBwcm92aWRlZCByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RUYWdzRm9yUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFRhZ3NGb3JSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFRhZ3NGb3JSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJldHVybiBhIGxpc3Qgb2YgdHJhaW5pbmcgZGF0YXNldHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RUcmFpbmluZ0RhdGFzZXRzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RUcmFpbmluZ0RhdGFzZXRzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0VHJhaW5pbmdEYXRhc2V0cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBvciB1cGRhdGUgdGhlIHJlc291cmNlIHBvbGljeSBmb3IgYSBjb25maWd1cmVkIGF1ZGllbmNlIG1vZGVsXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUGVybWlzc2lvbnMgbWFuYWdlbWVudFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xlYW5yb29tcy1tbC9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9QdXRDb25maWd1cmVkQXVkaWVuY2VNb2RlbFBvbGljeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9QdXRDb25maWd1cmVkQXVkaWVuY2VNb2RlbFBvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUHV0Q29uZmlndXJlZEF1ZGllbmNlTW9kZWxQb2xpY3knKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBleHBvcnQgYW4gYXVkaWVuY2Ugb2YgYSBzcGVjaWZpZWQgc2l6ZSBhZnRlciB5b3UgaGF2ZSBnZW5lcmF0ZWQgYW4gYXVkaWVuY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2xlYW5yb29tcy1tbC9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9TdGFydEF1ZGllbmNlRXhwb3J0Sm9iLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1N0YXJ0QXVkaWVuY2VFeHBvcnRKb2IoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1N0YXJ0QXVkaWVuY2VFeHBvcnRKb2InKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBzdGFydCB0aGUgYXVkaWVuY2UgZ2VuZXJhdGlvbiBqb2JcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKiAtIC5pZkNvbGxhYm9yYXRpb25JZCgpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1N0YXJ0QXVkaWVuY2VHZW5lcmF0aW9uSm9iLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1N0YXJ0QXVkaWVuY2VHZW5lcmF0aW9uSm9iKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTdGFydEF1ZGllbmNlR2VuZXJhdGlvbkpvYicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHRhZyBhIHNwZWNpZmljIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsZWFucm9vbXMtbWwvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVGFnUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVGFnUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1RhZ1Jlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdW50YWcgYSBzcGVjaWZpYyByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1VudGFnUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVW5UYWdSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVW5UYWdSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSBhIGNvbmZpZ3VyZWQgYXVkaWVuY2UgbW9kZWwuXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsZWFucm9vbXMtbWwvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlQ29uZmlndXJlZEF1ZGllbmNlTW9kZWwuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlQ29uZmlndXJlZEF1ZGllbmNlTW9kZWwoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZUNvbmZpZ3VyZWRBdWRpZW5jZU1vZGVsJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWNjZXNzTGV2ZWxMaXN0OiBBY2Nlc3NMZXZlbExpc3QgPSB7XG4gICAgV3JpdGU6IFtcbiAgICAgICdDcmVhdGVBdWRpZW5jZU1vZGVsJyxcbiAgICAgICdDcmVhdGVDb25maWd1cmVkQXVkaWVuY2VNb2RlbCcsXG4gICAgICAnQ3JlYXRlVHJhaW5pbmdEYXRhc2V0JyxcbiAgICAgICdEZWxldGVBdWRpZW5jZUdlbmVyYXRpb25Kb2InLFxuICAgICAgJ0RlbGV0ZUF1ZGllbmNlTW9kZWwnLFxuICAgICAgJ0RlbGV0ZUNvbmZpZ3VyZWRBdWRpZW5jZU1vZGVsJyxcbiAgICAgICdEZWxldGVDb25maWd1cmVkQXVkaWVuY2VNb2RlbFBvbGljeScsXG4gICAgICAnRGVsZXRlVHJhaW5pbmdEYXRhc2V0JyxcbiAgICAgICdTdGFydEF1ZGllbmNlRXhwb3J0Sm9iJyxcbiAgICAgICdTdGFydEF1ZGllbmNlR2VuZXJhdGlvbkpvYicsXG4gICAgICAnVXBkYXRlQ29uZmlndXJlZEF1ZGllbmNlTW9kZWwnXG4gICAgXSxcbiAgICBSZWFkOiBbXG4gICAgICAnR2V0QXVkaWVuY2VHZW5lcmF0aW9uSm9iJyxcbiAgICAgICdHZXRBdWRpZW5jZU1vZGVsJyxcbiAgICAgICdHZXRDb25maWd1cmVkQXVkaWVuY2VNb2RlbCcsXG4gICAgICAnR2V0Q29uZmlndXJlZEF1ZGllbmNlTW9kZWxQb2xpY3knLFxuICAgICAgJ0dldFRyYWluaW5nRGF0YXNldCdcbiAgICBdLFxuICAgIExpc3Q6IFtcbiAgICAgICdMaXN0QXVkaWVuY2VFeHBvcnRKb2JzJyxcbiAgICAgICdMaXN0QXVkaWVuY2VHZW5lcmF0aW9uSm9icycsXG4gICAgICAnTGlzdEF1ZGllbmNlTW9kZWxzJyxcbiAgICAgICdMaXN0Q29uZmlndXJlZEF1ZGllbmNlTW9kZWxzJyxcbiAgICAgICdMaXN0VGFnc0ZvclJlc291cmNlJyxcbiAgICAgICdMaXN0VHJhaW5pbmdEYXRhc2V0cydcbiAgICBdLFxuICAgICdQZXJtaXNzaW9ucyBtYW5hZ2VtZW50JzogW1xuICAgICAgJ1B1dENvbmZpZ3VyZWRBdWRpZW5jZU1vZGVsUG9saWN5J1xuICAgIF0sXG4gICAgVGFnZ2luZzogW1xuICAgICAgJ1RhZ1Jlc291cmNlJyxcbiAgICAgICdVblRhZ1Jlc291cmNlJ1xuICAgIF1cbiAgfTtcblxuICAvKipcbiAgICogQWRkcyBhIHJlc291cmNlIG9mIHR5cGUgdHJhaW5pbmdkYXRhc2V0IHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsZWFucm9vbXMtbWwvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVHJhaW5pbmdEYXRhc2V0U3VtbWFyeS5odG1sXG4gICAqXG4gICAqIEBwYXJhbSByZXNvdXJjZUlkIC0gSWRlbnRpZmllciBmb3IgdGhlIHJlc291cmNlSWQuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvblRyYWluaW5nZGF0YXNldChyZXNvdXJjZUlkOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06Y2xlYW5yb29tcy1tbDokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06dHJhaW5pbmctZGF0YXNldC8keyByZXNvdXJjZUlkIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgcmVzb3VyY2Ugb2YgdHlwZSBhdWRpZW5jZW1vZGVsIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2NsZWFucm9vbXMtbWwvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQXVkaWVuY2VNb2RlbFN1bW1hcnkuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gcmVzb3VyY2VJZCAtIElkZW50aWZpZXIgZm9yIHRoZSByZXNvdXJjZUlkLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqL1xuICBwdWJsaWMgb25BdWRpZW5jZW1vZGVsKHJlc291cmNlSWQ6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTpjbGVhbnJvb21zLW1sOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTphdWRpZW5jZS1tb2RlbC8keyByZXNvdXJjZUlkIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgcmVzb3VyY2Ugb2YgdHlwZSBjb25maWd1cmVkYXVkaWVuY2Vtb2RlbCB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0NvbmZpZ3VyZWRBdWRpZW5jZU1vZGVsU3VtbWFyeS5odG1sXG4gICAqXG4gICAqIEBwYXJhbSByZXNvdXJjZUlkIC0gSWRlbnRpZmllciBmb3IgdGhlIHJlc291cmNlSWQuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvbkNvbmZpZ3VyZWRhdWRpZW5jZW1vZGVsKHJlc291cmNlSWQ6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTpjbGVhbnJvb21zLW1sOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpjb25maWd1cmVkLWF1ZGllbmNlLW1vZGVsLyR7IHJlc291cmNlSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIGF1ZGllbmNlZ2VuZXJhdGlvbmpvYiB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGVhbnJvb21zLW1sL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0F1ZGllbmNlR2VuZXJhdGlvbkpvYlN1bW1hcnkuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gcmVzb3VyY2VJZCAtIElkZW50aWZpZXIgZm9yIHRoZSByZXNvdXJjZUlkLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqL1xuICBwdWJsaWMgb25BdWRpZW5jZWdlbmVyYXRpb25qb2IocmVzb3VyY2VJZDogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OmNsZWFucm9vbXMtbWw6JHsgcmVnaW9uID8/IHRoaXMuZGVmYXVsdFJlZ2lvbiB9OiR7IGFjY291bnQgPz8gdGhpcy5kZWZhdWx0QWNjb3VudCB9OmF1ZGllbmNlLWdlbmVyYXRpb24tam9iLyR7IHJlc291cmNlSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBwcmVzZW5jZSBvZiB0YWcga2V5LXZhbHVlIHBhaXJzIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy1yZXF1ZXN0dGFnXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVBdWRpZW5jZU1vZGVsKClcbiAgICogLSAudG9DcmVhdGVDb25maWd1cmVkQXVkaWVuY2VNb2RlbCgpXG4gICAqIC0gLnRvQ3JlYXRlVHJhaW5pbmdEYXRhc2V0KClcbiAgICogLSAudG9EZWxldGVBdWRpZW5jZUdlbmVyYXRpb25Kb2IoKVxuICAgKiAtIC50b0RlbGV0ZUF1ZGllbmNlTW9kZWwoKVxuICAgKiAtIC50b0RlbGV0ZUNvbmZpZ3VyZWRBdWRpZW5jZU1vZGVsKClcbiAgICogLSAudG9EZWxldGVDb25maWd1cmVkQXVkaWVuY2VNb2RlbFBvbGljeSgpXG4gICAqIC0gLnRvRGVsZXRlVHJhaW5pbmdEYXRhc2V0KClcbiAgICogLSAudG9HZXRBdWRpZW5jZUdlbmVyYXRpb25Kb2IoKVxuICAgKiAtIC50b0dldEF1ZGllbmNlTW9kZWwoKVxuICAgKiAtIC50b0dldENvbmZpZ3VyZWRBdWRpZW5jZU1vZGVsKClcbiAgICogLSAudG9HZXRDb25maWd1cmVkQXVkaWVuY2VNb2RlbFBvbGljeSgpXG4gICAqIC0gLnRvR2V0VHJhaW5pbmdEYXRhc2V0KClcbiAgICogLSAudG9MaXN0QXVkaWVuY2VFeHBvcnRKb2JzKClcbiAgICogLSAudG9MaXN0QXVkaWVuY2VHZW5lcmF0aW9uSm9icygpXG4gICAqIC0gLnRvU3RhcnRBdWRpZW5jZUV4cG9ydEpvYigpXG4gICAqIC0gLnRvU3RhcnRBdWRpZW5jZUdlbmVyYXRpb25Kb2IoKVxuICAgKiAtIC50b1RhZ1Jlc291cmNlKClcbiAgICogLSAudG9VcGRhdGVDb25maWd1cmVkQXVkaWVuY2VNb2RlbCgpXG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXF1ZXN0VGFnKHRhZ0tleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlJlcXVlc3RUYWcvJHsgdGFnS2V5IH1gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnK