cdk-iam-floyd
Version:
AWS IAM policy statement generator with fluent interface for AWS CDK
656 lines • 64.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Kinesis = void 0;
const shared_1 = require("../../shared");
/**
* Statement provider for service [kinesis](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonkinesisdatastreams.html).
*
* @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
*/
class Kinesis extends shared_1.PolicyStatement {
/**
* Grants permission to add or update tags for the specified Amazon Kinesis stream. Each stream can have up to 50 tags
*
* Access Level: Tagging
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_AddTagsToStream.html
*/
toAddTagsToStream() {
return this.to('AddTagsToStream');
}
/**
* Grants permission to create a Amazon Kinesis stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_CreateStream.html
*/
toCreateStream() {
return this.to('CreateStream');
}
/**
* Grants permission to decrease the stream's retention period, which is the length of time data records are accessible after they are added to the stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DecreaseStreamRetentionPeriod.html
*/
toDecreaseStreamRetentionPeriod() {
return this.to('DecreaseStreamRetentionPeriod');
}
/**
* Grants permission to delete a resource policy associated with a specified stream or consumer
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DeleteResourcePolicy.html
*/
toDeleteResourcePolicy() {
return this.to('DeleteResourcePolicy');
}
/**
* Grants permission to delete a stream and all its shards and data
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DeleteStream.html
*/
toDeleteStream() {
return this.to('DeleteStream');
}
/**
* Grants permission to deregister a stream consumer with a Kinesis data stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DeregisterStreamConsumer.html
*/
toDeregisterStreamConsumer() {
return this.to('DeregisterStreamConsumer');
}
/**
* Grants permission to describe the account-level settings for Amazon Kinesis Data Streams
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DescribeAccountSettings.html
*/
toDescribeAccountSettings() {
return this.to('DescribeAccountSettings');
}
/**
* Grants permission to describe the shard limits and usage for the account
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DescribeLimits.html
*/
toDescribeLimits() {
return this.to('DescribeLimits');
}
/**
* Grants permission to describe the specified stream
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DescribeStream.html
*/
toDescribeStream() {
return this.to('DescribeStream');
}
/**
* Grants permission to get the description of a registered stream consumer
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DescribeStreamConsumer.html
*/
toDescribeStreamConsumer() {
return this.to('DescribeStreamConsumer');
}
/**
* Grants permission to provide a summarized description of the specified Kinesis data stream without the shard list
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DescribeStreamSummary.html
*/
toDescribeStreamSummary() {
return this.to('DescribeStreamSummary');
}
/**
* Grants permission to disables enhanced monitoring
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_DisableEnhancedMonitoring.html
*/
toDisableEnhancedMonitoring() {
return this.to('DisableEnhancedMonitoring');
}
/**
* Grants permission to enable enhanced Kinesis data stream monitoring for shard-level metrics
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_EnableEnhancedMonitoring.html
*/
toEnableEnhancedMonitoring() {
return this.to('EnableEnhancedMonitoring');
}
/**
* Grants permission to get data records from a shard
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetRecords.html
*/
toGetRecords() {
return this.to('GetRecords');
}
/**
* Grants permission to get a resource policy associated with a specified stream or consumer
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetResourcePolicy.html
*/
toGetResourcePolicy() {
return this.to('GetResourcePolicy');
}
/**
* Grants permission to get a shard iterator. A shard iterator expires five minutes after it is returned to the requester
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetShardIterator.html
*/
toGetShardIterator() {
return this.to('GetShardIterator');
}
/**
* Grants permission to increase the stream's retention period, which is the length of time data records are accessible after they are added to the stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_IncreaseStreamRetentionPeriod.html
*/
toIncreaseStreamRetentionPeriod() {
return this.to('IncreaseStreamRetentionPeriod');
}
/**
* Grants permission to temporarily inject errors for target API requests
*
* Access Level: Write
*
* Possible conditions:
* - .ifFisActionId()
* - .ifFisTargetArns()
* - .ifFisInjectPercentage()
*
* https://docs.aws.amazon.com/fis/latest/userguide/fis-actions-reference.html
*/
toInjectApiError() {
return this.to('InjectApiError');
}
/**
* Grants permission to list the shards in a stream and provides information about each shard
*
* Access Level: List
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ListShards.html
*/
toListShards() {
return this.to('ListShards');
}
/**
* Grants permission to list the stream consumers registered to receive data from a Kinesis stream using enhanced fan-out, and provides information about each consumer
*
* Access Level: List
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ListStreamConsumers.html
*/
toListStreamConsumers() {
return this.to('ListStreamConsumers');
}
/**
* Grants permission to list your streams
*
* Access Level: List
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ListStreams.html
*/
toListStreams() {
return this.to('ListStreams');
}
/**
* Grants permission to list the tags for the specified Amazon Kinesis resource
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ListTagsForResource.html
*/
toListTagsForResource() {
return this.to('ListTagsForResource');
}
/**
* Grants permission to list the tags for the specified Amazon Kinesis stream
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_ListTagsForStream.html
*/
toListTagsForStream() {
return this.to('ListTagsForStream');
}
/**
* Grants permission to merge two adjacent shards in a stream and combines them into a single shard to reduce the stream's capacity to ingest and transport data
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_MergeShards.html
*/
toMergeShards() {
return this.to('MergeShards');
}
/**
* Grants permission to write a single data record from a producer into an Amazon Kinesis stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecord.html
*/
toPutRecord() {
return this.to('PutRecord');
}
/**
* Grants permission to write multiple data records from a producer into an Amazon Kinesis stream in a single call (also referred to as a PutRecords request)
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecords.html
*/
toPutRecords() {
return this.to('PutRecords');
}
/**
* Grants permission to attach a resource policy to a specified stream or consumer
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutResourcePolicy.html
*/
toPutResourcePolicy() {
return this.to('PutResourcePolicy');
}
/**
* Grants permission to register a stream consumer with a Kinesis data stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_RegisterStreamConsumer.html
*/
toRegisterStreamConsumer() {
return this.to('RegisterStreamConsumer');
}
/**
* Grants permission to remove tags from the specified Kinesis data stream. Removed tags are deleted and cannot be recovered after this operation successfully completes
*
* Access Level: Tagging
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_RemoveTagsFromStream.html
*/
toRemoveTagsFromStream() {
return this.to('RemoveTagsFromStream');
}
/**
* Grants permission to split a shard into two new shards in the Kinesis data stream, to increase the stream's capacity to ingest and transport data
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_SplitShard.html
*/
toSplitShard() {
return this.to('SplitShard');
}
/**
* Grants permission to enable or update server-side encryption using an AWS KMS key for a specified stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_StartStreamEncryption.html
*/
toStartStreamEncryption() {
return this.to('StartStreamEncryption');
}
/**
* Grants permission to disable server-side encryption for a specified stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_StopStreamEncryption.html
*/
toStopStreamEncryption() {
return this.to('StopStreamEncryption');
}
/**
* Grants permission to listen to a specific shard with enhanced fan-out
*
* Access Level: Read
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_SubscribeToShard.html
*/
toSubscribeToShard() {
return this.to('SubscribeToShard');
}
/**
* Grants permission to add or update tags for the specified Amazon Kinesis resource. Each resource can have up to 50 tags
*
* Access Level: Tagging
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_TagResource.html
*/
toTagResource() {
return this.to('TagResource');
}
/**
* Grants permission to remove tags from the specified Kinesis data resource. Removed tags are deleted and cannot be recovered after this operation successfully completes
*
* Access Level: Tagging
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_UntagResource.html
*/
toUntagResource() {
return this.to('UntagResource');
}
/**
* Grants permission to update the account-level settings for Amazon Kinesis Data Streams
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_UpdateAccountSettings.html
*/
toUpdateAccountSettings() {
return this.to('UpdateAccountSettings');
}
/**
* Grants permission to update the maximum record size for a Kinesis data stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_UpdateMaxRecordSize.html
*/
toUpdateMaxRecordSize() {
return this.to('UpdateMaxRecordSize');
}
/**
* Grants permission to update the shard count of the specified stream to the specified number of shards
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_UpdateShardCount.html
*/
toUpdateShardCount() {
return this.to('UpdateShardCount');
}
/**
* Grants permission to update the capacity mode of the data stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_UpdateStreamMode.html
*/
toUpdateStreamMode() {
return this.to('UpdateStreamMode');
}
/**
* Grants permission to update the warm throughput for a Kinesis on-demand data stream
*
* Access Level: Write
*
* https://docs.aws.amazon.com/kinesis/latest/APIReference/API_UpdateStreamWarmThroughput.html
*/
toUpdateStreamWarmThroughput() {
return this.to('UpdateStreamWarmThroughput');
}
/**
* Adds a resource of type stream to the statement
*
* https://docs.aws.amazon.com/streams/latest/dev/key-concepts.html#stream
*
* @param streamName - Identifier for the streamName.
* @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()
*/
onStream(streamName, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:kinesis:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:stream/${streamName}`);
}
/**
* Adds a resource of type consumer to the statement
*
* https://docs.aws.amazon.com/streams/latest/dev/key-concepts.html#enabled-application
*
* @param streamType - Identifier for the streamType.
* @param streamName - Identifier for the streamName.
* @param consumerName - Identifier for the consumerName.
* @param consumerCreationTimpstamp - Identifier for the consumerCreationTimpstamp.
* @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()
*/
onConsumer(streamType, streamName, consumerName, consumerCreationTimpstamp, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:kinesis:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:${streamType}/${streamName}/consumer/${consumerName}:${consumerCreationTimpstamp}`);
}
/**
* Adds a resource of type kmsKey to the statement
*
* https://docs.aws.amazon.com/streams/latest/dev/server-side-encryption.html
*
* @param keyId - Identifier for the keyId.
* @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()
*/
onKmsKey(keyId, account, region, partition) {
return this.on(`arn:${partition ?? this.defaultPartition}:kms:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:key/${keyId}`);
}
/**
* 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:
* - .toAddTagsToStream()
* - .toCreateStream()
* - .toRegisterStreamConsumer()
* - .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 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:
* - .toAddTagsToStream()
* - .toCreateStream()
* - .toDecreaseStreamRetentionPeriod()
* - .toDeleteResourcePolicy()
* - .toDeleteStream()
* - .toDeregisterStreamConsumer()
* - .toDescribeStream()
* - .toDescribeStreamConsumer()
* - .toDescribeStreamSummary()
* - .toGetRecords()
* - .toGetResourcePolicy()
* - .toGetShardIterator()
* - .toIncreaseStreamRetentionPeriod()
* - .toListShards()
* - .toListStreamConsumers()
* - .toListTagsForResource()
* - .toListTagsForStream()
* - .toMergeShards()
* - .toPutRecord()
* - .toPutRecords()
* - .toPutResourcePolicy()
* - .toRegisterStreamConsumer()
* - .toRemoveTagsFromStream()
* - .toSplitShard()
* - .toStartStreamEncryption()
* - .toStopStreamEncryption()
* - .toSubscribeToShard()
* - .toTagResource()
* - .toUntagResource()
* - .toUpdateMaxRecordSize()
* - .toUpdateStreamWarmThroughput()
*
* Applies to resource types:
* - stream
* - consumer
* - kmsKey
*
* @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:
* - .toAddTagsToStream()
* - .toCreateStream()
* - .toRegisterStreamConsumer()
* - .toRemoveTagsFromStream()
* - .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');
}
/**
* Filters access by the ID of an AWS FIS action
*
* https://docs.aws.amazon.com/fis/latest/userguide/fis-actions-reference.html
*
* Applies to actions:
* - .toInjectApiError()
*
* @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`
*/
ifFisActionId(value, operator) {
return this.if(`FisActionId`, value, operator ?? 'StringLike');
}
/**
* Filters access by the percentage of calls being affected by an AWS FIS action
*
* https://docs.aws.amazon.com/fis/latest/userguide/fis-actions-reference.html
*
* Applies to actions:
* - .toInjectApiError()
*
* @param value The value(s) to check
* @param operator Works with [numeric operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Numeric). **Default:** `NumericEquals`
*/
ifFisInjectPercentage(value, operator) {
return this.if(`FisInjectPercentage`, value, operator ?? 'NumericEquals');
}
/**
* Filters access by the ARN of an AWS FIS target
*
* https://docs.aws.amazon.com/fis/latest/userguide/fis-actions-reference.html
*
* Applies to actions:
* - .toInjectApiError()
*
* @param value The value(s) to check
* @param operator Works with [arn operators](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_ARN). **Default:** `ArnLike`
*/
ifFisTargetArns(value, operator) {
return this.if(`FisTargetArns`, value, operator ?? 'ArnLike');
}
/**
* Statement provider for service [kinesis](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonkinesisdatastreams.html).
*
*/
constructor(props) {
super(props);
this.servicePrefix = 'kinesis';
this.accessLevelList = {
Tagging: [
'AddTagsToStream',
'RemoveTagsFromStream',
'TagResource',
'UntagResource'
],
Write: [
'CreateStream',
'DecreaseStreamRetentionPeriod',
'DeleteResourcePolicy',
'DeleteStream',
'DeregisterStreamConsumer',
'DisableEnhancedMonitoring',
'EnableEnhancedMonitoring',
'IncreaseStreamRetentionPeriod',
'InjectApiError',
'MergeShards',
'PutRecord',
'PutRecords',
'PutResourcePolicy',
'RegisterStreamConsumer',
'SplitShard',
'StartStreamEncryption',
'StopStreamEncryption',
'UpdateAccountSettings',
'UpdateMaxRecordSize',
'UpdateShardCount',
'UpdateStreamMode',
'UpdateStreamWarmThroughput'
],
Read: [
'DescribeAccountSettings',
'DescribeLimits',
'DescribeStream',
'DescribeStreamConsumer',
'DescribeStreamSummary',
'GetRecords',
'GetResourcePolicy',
'GetShardIterator',
'ListTagsForResource',
'ListTagsForStream',
'SubscribeToShard'
],
List: [
'ListShards',
'ListStreamConsumers',
'ListStreams'
]
};
}
}
exports.Kinesis = Kinesis;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2luZXNpc2RhdGFzdHJlYW1zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsia2luZXNpc2RhdGFzdHJlYW1zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHlDQUF5RDtBQUd6RDs7OztHQUlHO0FBQ0gsTUFBYSxPQUFRLFNBQVEsd0JBQWU7SUFHMUM7Ozs7OztPQU1HO0lBQ0ksaUJBQWlCO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxjQUFjO1FBQ25CLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksK0JBQStCO1FBQ3BDLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxzQkFBc0I7UUFDM0IsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGNBQWM7UUFDbkIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSwwQkFBMEI7UUFDL0IsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLHlCQUF5QjtRQUM5QixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMseUJBQXlCLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksZ0JBQWdCO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxnQkFBZ0I7UUFDckIsT0FBTyxJQUFJLENB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aUI7Z0JBQ2pCLHNCQUFzQjtnQkFDdEIsYUFBYTtnQkFDYixlQUFlO2FBQ2hCO1lBQ0QsS0FBSyxFQUFFO2dCQUNMLGNBQWM7Z0JBQ2QsK0JBQStCO2dCQUMvQixzQkFBc0I7Z0JBQ3RCLGNBQWM7Z0JBQ2QsMEJBQTBCO2dCQUMxQiwyQkFBMkI7Z0JBQzNCLDBCQUEwQjtnQkFDMUIsK0JBQStCO2dCQUMvQixnQkFBZ0I7Z0JBQ2hCLGFBQWE7Z0JBQ2IsV0FBVztnQkFDWCxZQUFZO2dCQUNaLG1CQUFtQjtnQkFDbkIsd0JBQXdCO2dCQUN4QixZQUFZO2dCQUNaLHVCQUF1QjtnQkFDdkIsc0JBQXNCO2dCQUN0Qix1QkFBdUI7Z0JBQ3ZCLHFCQUFxQjtnQkFDckIsa0JBQWtCO2dCQUNsQixrQkFBa0I7Z0JBQ2xCLDRCQUE0QjthQUM3QjtZQUNELElBQUksRUFBRTtnQkFDSix5QkFBeUI7Z0JBQ3pCLGdCQUFnQjtnQkFDaEIsZ0JBQWdCO2dCQUNoQix3QkFBd0I7Z0JBQ3hCLHVCQUF1QjtnQkFDdkIsWUFBWTtnQkFDWixtQkFBbUI7Z0JBQ25CLGtCQUFrQjtnQkFDbEIscUJBQXFCO2dCQUNyQixtQkFBbUI7Z0JBQ25CLGtCQUFrQjthQUNuQjtZQUNELElBQUksRUFBRTtnQkFDSixZQUFZO2dCQUNaLHFCQUFxQjtnQkFDckIsYUFBYTthQUNkO1NBQ0YsQ0FBQztJQXFNRixDQUFDO0NBQ0Y7QUF2ckJELDBCQXVyQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBY2Nlc3NMZXZlbExpc3QgfSBmcm9tICcuLi8uLi9zaGFyZWQvYWNjZXNzLWxldmVsJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCwgT3BlcmF0b3IgfSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuaW1wb3J0IHsgYXdzX2lhbSBhcyBpYW0gfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcblxuLyoqXG4gKiBTdGF0ZW1lbnQgcHJvdmlkZXIgZm9yIHNlcnZpY2UgW2tpbmVzaXNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXJ2aWNlLWF1dGhvcml6YXRpb24vbGF0ZXN0L3JlZmVyZW5jZS9saXN0X2FtYXpvbmtpbmVzaXNkYXRhc3RyZWFtcy5odG1sKS5cbiAqXG4gKiBAcGFyYW0gc2lkIFtTSURdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfc2lkLmh0bWwpIG9mIHRoZSBzdGF0ZW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEtpbmVzaXMgZXh0ZW5kcyBQb2xpY3lTdGF0ZW1lbnQge1xuICBwdWJsaWMgc2VydmljZVByZWZpeCA9ICdraW5lc2lzJztcblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWRkIG9yIHVwZGF0ZSB0YWdzIGZvciB0aGUgc3BlY2lmaWVkIEFtYXpvbiBLaW5lc2lzIHN0cmVhbS4gRWFjaCBzdHJlYW0gY2FuIGhhdmUgdXAgdG8gNTAgdGFnc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQWRkVGFnc1RvU3RyZWFtLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0FkZFRhZ3NUb1N0cmVhbSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQWRkVGFnc1RvU3RyZWFtJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgQW1hem9uIEtpbmVzaXMgc3RyZWFtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlU3RyZWFtLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVN0cmVhbSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlU3RyZWFtJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVjcmVhc2UgdGhlIHN0cmVhbSdzIHJldGVudGlvbiBwZXJpb2QsIHdoaWNoIGlzIHRoZSBsZW5ndGggb2YgdGltZSBkYXRhIHJlY29yZHMgYXJlIGFjY2Vzc2libGUgYWZ0ZXIgdGhleSBhcmUgYWRkZWQgdG8gdGhlIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlY3JlYXNlU3RyZWFtUmV0ZW50aW9uUGVyaW9kLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlY3JlYXNlU3RyZWFtUmV0ZW50aW9uUGVyaW9kKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZWNyZWFzZVN0cmVhbVJldGVudGlvblBlcmlvZCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSBhIHJlc291cmNlIHBvbGljeSBhc3NvY2lhdGVkIHdpdGggYSBzcGVjaWZpZWQgc3RyZWFtIG9yIGNvbnN1bWVyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGVsZXRlUmVzb3VyY2VQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlUmVzb3VyY2VQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVJlc291cmNlUG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGEgc3RyZWFtIGFuZCBhbGwgaXRzIHNoYXJkcyBhbmQgZGF0YVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0RlbGV0ZVN0cmVhbS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVTdHJlYW0oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVN0cmVhbScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlcmVnaXN0ZXIgYSBzdHJlYW0gY29uc3VtZXIgd2l0aCBhIEtpbmVzaXMgZGF0YSBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXJlZ2lzdGVyU3RyZWFtQ29uc3VtZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVyZWdpc3RlclN0cmVhbUNvbnN1bWVyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXJlZ2lzdGVyU3RyZWFtQ29uc3VtZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgYWNjb3VudC1sZXZlbCBzZXR0aW5ncyBmb3IgQW1hem9uIEtpbmVzaXMgRGF0YSBTdHJlYW1zXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZUFjY291bnRTZXR0aW5ncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUFjY291bnRTZXR0aW5ncygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVBY2NvdW50U2V0dGluZ3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aGUgc2hhcmQgbGltaXRzIGFuZCB1c2FnZSBmb3IgdGhlIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlTGltaXRzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlTGltaXRzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUxpbWl0cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlc2NyaWJlIHRoZSBzcGVjaWZpZWQgc3RyZWFtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVN0cmVhbS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVN0cmVhbSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVTdHJlYW0nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgdGhlIGRlc2NyaXB0aW9uIG9mIGEgcmVnaXN0ZXJlZCBzdHJlYW0gY29uc3VtZXJcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlU3RyZWFtQ29uc3VtZXIuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVTdHJlYW1Db25zdW1lcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVTdHJlYW1Db25zdW1lcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHByb3ZpZGUgYSBzdW1tYXJpemVkIGRlc2NyaXB0aW9uIG9mIHRoZSBzcGVjaWZpZWQgS2luZXNpcyBkYXRhIHN0cmVhbSB3aXRob3V0IHRoZSBzaGFyZCBsaXN0XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9EZXNjcmliZVN0cmVhbVN1bW1hcnkuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVTdHJlYW1TdW1tYXJ5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZVN0cmVhbVN1bW1hcnknKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkaXNhYmxlcyBlbmhhbmNlZCBtb25pdG9yaW5nXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfRGlzYWJsZUVuaGFuY2VkTW9uaXRvcmluZy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EaXNhYmxlRW5oYW5jZWRNb25pdG9yaW5nKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEaXNhYmxlRW5oYW5jZWRNb25pdG9yaW5nJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZW5hYmxlIGVuaGFuY2VkIEtpbmVzaXMgZGF0YSBzdHJlYW0gbW9uaXRvcmluZyBmb3Igc2hhcmQtbGV2ZWwgbWV0cmljc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0VuYWJsZUVuaGFuY2VkTW9uaXRvcmluZy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9FbmFibGVFbmhhbmNlZE1vbml0b3JpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0VuYWJsZUVuaGFuY2VkTW9uaXRvcmluZycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBkYXRhIHJlY29yZHMgZnJvbSBhIHNoYXJkXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9HZXRSZWNvcmRzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0dldFJlY29yZHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldFJlY29yZHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBnZXQgYSByZXNvdXJjZSBwb2xpY3kgYXNzb2NpYXRlZCB3aXRoIGEgc3BlY2lmaWVkIHN0cmVhbSBvciBjb25zdW1lclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0UmVzb3VyY2VQb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0UmVzb3VyY2VQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldFJlc291cmNlUG9saWN5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZ2V0IGEgc2hhcmQgaXRlcmF0b3IuIEEgc2hhcmQgaXRlcmF0b3IgZXhwaXJlcyBmaXZlIG1pbnV0ZXMgYWZ0ZXIgaXQgaXMgcmV0dXJuZWQgdG8gdGhlIHJlcXVlc3RlclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfR2V0U2hhcmRJdGVyYXRvci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRTaGFyZEl0ZXJhdG9yKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdHZXRTaGFyZEl0ZXJhdG9yJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gaW5jcmVhc2UgdGhlIHN0cmVhbSdzIHJldGVudGlvbiBwZXJpb2QsIHdoaWNoIGlzIHRoZSBsZW5ndGggb2YgdGltZSBkYXRhIHJlY29yZHMgYXJlIGFjY2Vzc2libGUgYWZ0ZXIgdGhleSBhcmUgYWRkZWQgdG8gdGhlIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0luY3JlYXNlU3RyZWFtUmV0ZW50aW9uUGVyaW9kLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0luY3JlYXNlU3RyZWFtUmV0ZW50aW9uUGVyaW9kKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdJbmNyZWFzZVN0cmVhbVJldGVudGlvblBlcmlvZCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHRlbXBvcmFyaWx5IGluamVjdCBlcnJvcnMgZm9yIHRhcmdldCBBUEkgcmVxdWVzdHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkZpc0FjdGlvbklkKClcbiAgICogLSAuaWZGaXNUYXJnZXRBcm5zKClcbiAgICogLSAuaWZGaXNJbmplY3RQZXJjZW50YWdlKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Zpcy9sYXRlc3QvdXNlcmd1aWRlL2Zpcy1hY3Rpb25zLXJlZmVyZW5jZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9JbmplY3RBcGlFcnJvcigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnSW5qZWN0QXBpRXJyb3InKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHRoZSBzaGFyZHMgaW4gYSBzdHJlYW0gYW5kIHByb3ZpZGVzIGluZm9ybWF0aW9uIGFib3V0IGVhY2ggc2hhcmRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RTaGFyZHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFNoYXJkcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFNoYXJkcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgdGhlIHN0cmVhbSBjb25zdW1lcnMgcmVnaXN0ZXJlZCB0byByZWNlaXZlIGRhdGEgZnJvbSBhIEtpbmVzaXMgc3RyZWFtIHVzaW5nIGVuaGFuY2VkIGZhbi1vdXQsIGFuZCBwcm92aWRlcyBpbmZvcm1hdGlvbiBhYm91dCBlYWNoIGNvbnN1bWVyXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9MaXN0U3RyZWFtQ29uc3VtZXJzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RTdHJlYW1Db25zdW1lcnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RTdHJlYW1Db25zdW1lcnMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHlvdXIgc3RyZWFtc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdFN0cmVhbXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFN0cmVhbXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3RTdHJlYW1zJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCB0aGUgdGFncyBmb3IgdGhlIHNwZWNpZmllZCBBbWF6b24gS2luZXNpcyByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfTGlzdFRhZ3NGb3JSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9MaXN0VGFnc0ZvclJlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0VGFnc0ZvclJlc291cmNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gbGlzdCB0aGUgdGFncyBmb3IgdGhlIHNwZWNpZmllZCBBbWF6b24gS2luZXNpcyBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0xpc3RUYWdzRm9yU3RyZWFtLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RUYWdzRm9yU3RyZWFtKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0VGFnc0ZvclN0cmVhbScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIG1lcmdlIHR3byBhZGphY2VudCBzaGFyZHMgaW4gYSBzdHJlYW0gYW5kIGNvbWJpbmVzIHRoZW0gaW50byBhIHNpbmdsZSBzaGFyZCB0byByZWR1Y2UgdGhlIHN0cmVhbSdzIGNhcGFjaXR5IHRvIGluZ2VzdCBhbmQgdHJhbnNwb3J0IGRhdGFcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9NZXJnZVNoYXJkcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9NZXJnZVNoYXJkcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTWVyZ2VTaGFyZHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB3cml0ZSBhIHNpbmdsZSBkYXRhIHJlY29yZCBmcm9tIGEgcHJvZHVjZXIgaW50byBhbiBBbWF6b24gS2luZXNpcyBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9QdXRSZWNvcmQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUHV0UmVjb3JkKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdQdXRSZWNvcmQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB3cml0ZSBtdWx0aXBsZSBkYXRhIHJlY29yZHMgZnJvbSBhIHByb2R1Y2VyIGludG8gYW4gQW1hem9uIEtpbmVzaXMgc3RyZWFtIGluIGEgc2luZ2xlIGNhbGwgKGFsc28gcmVmZXJyZWQgdG8gYXMgYSBQdXRSZWNvcmRzIHJlcXVlc3QpXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUHV0UmVjb3Jkcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9QdXRSZWNvcmRzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdQdXRSZWNvcmRzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYXR0YWNoIGEgcmVzb3VyY2UgcG9saWN5IHRvIGEgc3BlY2lmaWVkIHN0cmVhbSBvciBjb25zdW1lclxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1B1dFJlc291cmNlUG9saWN5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1B1dFJlc291cmNlUG9saWN5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdQdXRSZXNvdXJjZVBvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlZ2lzdGVyIGEgc3RyZWFtIGNvbnN1bWVyIHdpdGggYSBLaW5lc2lzIGRhdGEgc3RyZWFtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfUmVnaXN0ZXJTdHJlYW1Db25zdW1lci5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9SZWdpc3RlclN0cmVhbUNvbnN1bWVyKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdSZWdpc3RlclN0cmVhbUNvbnN1bWVyJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVtb3ZlIHRhZ3MgZnJvbSB0aGUgc3BlY2lmaWVkIEtpbmVzaXMgZGF0YSBzdHJlYW0uIFJlbW92ZWQgdGFncyBhcmUgZGVsZXRlZCBhbmQgY2Fubm90IGJlIHJlY292ZXJlZCBhZnRlciB0aGlzIG9wZXJhdGlvbiBzdWNjZXNzZnVsbHkgY29tcGxldGVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9SZW1vdmVUYWdzRnJvbVN0cmVhbS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9SZW1vdmVUYWdzRnJvbVN0cmVhbSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUmVtb3ZlVGFnc0Zyb21TdHJlYW0nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBzcGxpdCBhIHNoYXJkIGludG8gdHdvIG5ldyBzaGFyZHMgaW4gdGhlIEtpbmVzaXMgZGF0YSBzdHJlYW0sIHRvIGluY3JlYXNlIHRoZSBzdHJlYW0ncyBjYXBhY2l0eSB0byBpbmdlc3QgYW5kIHRyYW5zcG9ydCBkYXRhXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfU3BsaXRTaGFyZC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9TcGxpdFNoYXJkKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTcGxpdFNoYXJkJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZW5hYmxlIG9yIHVwZGF0ZSBzZXJ2ZXItc2lkZSBlbmNyeXB0aW9uIHVzaW5nIGFuIEFXUyBLTVMga2V5IGZvciBhIHNwZWNpZmllZCBzdHJlYW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9TdGFydFN0cmVhbUVuY3J5cHRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvU3RhcnRTdHJlYW1FbmNyeXB0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTdGFydFN0cmVhbUVuY3J5cHRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkaXNhYmxlIHNlcnZlci1zaWRlIGVuY3J5cHRpb24gZm9yIGEgc3BlY2lmaWVkIHN0cmVhbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1N0b3BTdHJlYW1FbmNyeXB0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1N0b3BTdHJlYW1FbmNyeXB0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTdG9wU3RyZWFtRW5jcnlwdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3RlbiB0byBhIHNwZWNpZmljIHNoYXJkIHdpdGggZW5oYW5jZWQgZmFuLW91dFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfU3Vic2NyaWJlVG9TaGFyZC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9TdWJzY3JpYmVUb1NoYXJkKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTdWJzY3JpYmVUb1NoYXJkJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWRkIG9yIHVwZGF0ZSB0YWdzIGZvciB0aGUgc3BlY2lmaWVkIEFtYXpvbiBLaW5lc2lzIHJlc291cmNlLiBFYWNoIHJlc291cmNlIGNhbiBoYXZlIHVwIHRvIDUwIHRhZ3NcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1RhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1RhZ1Jlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdUYWdSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSB0YWdzIGZyb20gdGhlIHNwZWNpZmllZCBLaW5lc2lzIGRhdGEgcmVzb3VyY2UuIFJlbW92ZWQgdGFncyBhcmUgZGVsZXRlZCBhbmQgY2Fubm90IGJlIHJlY292ZXJlZCBhZnRlciB0aGlzIG9wZXJhdGlvbiBzdWNjZXNzZnVsbHkgY29tcGxldGVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9VbnRhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VudGFnUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VudGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgdGhlIGFjY291bnQtbGV2ZWwgc2V0dGluZ3MgZm9yIEFtYXpvbiBLaW5lc2lzIERhdGEgU3RyZWFtc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9raW5lc2lzL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1VwZGF0ZUFjY291bnRTZXR0aW5ncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVBY2NvdW50U2V0dGluZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZUFjY291bnRTZXR0aW5ncycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgbWF4aW11bSByZWNvcmQgc2l6ZSBmb3IgYSBLaW5lc2lzIGRhdGEgc3RyZWFtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVXBkYXRlTWF4UmVjb3JkU2l6ZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVNYXhSZWNvcmRTaXplKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVNYXhSZWNvcmRTaXplJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdXBkYXRlIHRoZSBzaGFyZCBjb3VudCBvZiB0aGUgc3BlY2lmaWVkIHN0cmVhbSB0byB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBzaGFyZHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20va2luZXNpcy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9VcGRhdGVTaGFyZENvdW50Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZVNoYXJkQ291bnQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZVNoYXJkQ291bnQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgdGhlIGNhcGFjaXR5IG1vZGUgb2YgdGhlIGRhdGEgc3RyZWFtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2tpbmVzaXMvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfVXBkYXRl