UNPKG

cdk-iam-floyd

Version:

AWS IAM policy statement generator with fluent interface for AWS CDK

675 lines 57 kB
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Timestream = void 0;
const shared_1 = require("../../shared");
/**
 * Statement provider for service [timestream](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazontimestream.html).
 *
 * @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
 */
class Timestream extends shared_1.PolicyStatement {
    /**
     * Grants permission to cancel queries in your account
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_query_CancelQuery.html
     */
    toCancelQuery() {
        return this.to('CancelQuery');
    }
    /**
     * Grants permission to create a batch load task in your account
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     * - timestream:WriteRecords
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_CreateBatchLoadTask.html
     */
    toCreateBatchLoadTask() {
        return this.to('CreateBatchLoadTask');
    }
    /**
     * Grants permission to create a database in your account
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifAwsRequestTag()
     * - .ifAwsTagKeys()
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_CreateDatabase.html
     */
    toCreateDatabase() {
        return this.to('CreateDatabase');
    }
    /**
     * Grants permission to create a scheduled query in your account
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifAwsRequestTag()
     * - .ifAwsTagKeys()
     *
     * Dependent actions:
     * - iam:PassRole
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_CreateScheduledQuery.html
     */
    toCreateScheduledQuery() {
        return this.to('CreateScheduledQuery');
    }
    /**
     * Grants permission to create a table in your account
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifAwsRequestTag()
     * - .ifAwsTagKeys()
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_CreateTable.html
     */
    toCreateTable() {
        return this.to('CreateTable');
    }
    /**
     * Grants permission to delete a database in your account
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_DeleteDatabase.html
     */
    toDeleteDatabase() {
        return this.to('DeleteDatabase');
    }
    /**
     * Grants permission to delete a scheduled query in your account
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_DeleteScheduledQuery.html
     */
    toDeleteScheduledQuery() {
        return this.to('DeleteScheduledQuery');
    }
    /**
     * Grants permission to delete a table in your account
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_DeleteTable.html
     */
    toDeleteTable() {
        return this.to('DeleteTable');
    }
    /**
     * Grants permission to describe your account settings
     *
     * Access Level: Read
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_query_DescribeAccountSettings.html
     */
    toDescribeAccountSettings() {
        return this.to('DescribeAccountSettings');
    }
    /**
     * Grants permission to describe a batch load task in your account
     *
     * Access Level: Read
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_DescribeBatchLoadTask.html
     */
    toDescribeBatchLoadTask() {
        return this.to('DescribeBatchLoadTask');
    }
    /**
     * Grants permission to describe a database in your account
     *
     * Access Level: Read
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_DescribeDatabase.html
     */
    toDescribeDatabase() {
        return this.to('DescribeDatabase');
    }
    /**
     * Grants permission to describe timestream endpoints
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_DescribeEndpoints.html
     */
    toDescribeEndpoints() {
        return this.to('DescribeEndpoints');
    }
    /**
     * Grants permission to describe a scheduled query in your account
     *
     * Access Level: Read
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_DescribeScheduledQuery.html
     */
    toDescribeScheduledQuery() {
        return this.to('DescribeScheduledQuery');
    }
    /**
     * Grants permission to describe a table in your account
     *
     * Access Level: Read
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_DescribeTable.html
     */
    toDescribeTable() {
        return this.to('DescribeTable');
    }
    /**
     * Grants permission to execute a scheduled query in your account
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_ExecuteScheduledQuery.html
     */
    toExecuteScheduledQuery() {
        return this.to('ExecuteScheduledQuery');
    }
    /**
     * Grants permission to get Status of a Timestream Table Backup
     *
     * Access Level: Read
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/backups.html
     */
    toGetAwsBackupStatus() {
        return this.to('GetAwsBackupStatus');
    }
    /**
     * Grants permission to get Status of a Timestream Table Restore
     *
     * Access Level: Read
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/backups.html
     */
    toGetAwsRestoreStatus() {
        return this.to('GetAwsRestoreStatus');
    }
    /**
     * Grants permission to list batch load tasks in your account
     *
     * Access Level: List
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_ListBatchLoadTasks.html
     */
    toListBatchLoadTasks() {
        return this.to('ListBatchLoadTasks');
    }
    /**
     * Grants permission to list databases in your account
     *
     * Access Level: List
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_ListDatabases.html
     */
    toListDatabases() {
        return this.to('ListDatabases');
    }
    /**
     * Grants permission to list measures of a table in your account
     *
     * Access Level: List
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_query_Query.html
     */
    toListMeasures() {
        return this.to('ListMeasures');
    }
    /**
     * Grants permission to list scheduled queries in your account
     *
     * Access Level: List
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_ListScheduledQueries.html
     */
    toListScheduledQueries() {
        return this.to('ListScheduledQueries');
    }
    /**
     * Grants permission to list tables in your account
     *
     * Access Level: List
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_ListTables.html
     */
    toListTables() {
        return this.to('ListTables');
    }
    /**
     * Grants permission to list tags of a resource in your account
     *
     * Access Level: Read
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_ListTagsForResource.html
     */
    toListTagsForResource() {
        return this.to('ListTagsForResource');
    }
    /**
     * Grants permission to issue prepare queries
     *
     * Access Level: Read
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     * - timestream:Select
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_query_PrepareQuery.html
     */
    toPrepareQuery() {
        return this.to('PrepareQuery');
    }
    /**
     * Grants permission to resume a batch load task in your account
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     * - timestream:WriteRecords
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_ResumeBatchLoadTask.html
     */
    toResumeBatchLoadTask() {
        return this.to('ResumeBatchLoadTask');
    }
    /**
     * Grants permission to issue 'select from table' queries
     *
     * Access Level: Read
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_query_Query.html
     */
    toSelect() {
        return this.to('Select');
    }
    /**
     * Grants permission to issue 'select 1' queries
     *
     * Access Level: Read
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_query_Query.html
     */
    toSelectValues() {
        return this.to('SelectValues');
    }
    /**
     * Grants permission to start a Backup Job for a Timestream Table
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/backups.html
     */
    toStartAwsBackupJob() {
        return this.to('StartAwsBackupJob');
    }
    /**
     * Grants permission to start Restore Job for a Backup of Timestream Table
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/backups.html
     */
    toStartAwsRestoreJob() {
        return this.to('StartAwsRestoreJob');
    }
    /**
     * Grants permission to add tags to a resource
     *
     * Access Level: Tagging
     *
     * Possible conditions:
     * - .ifAwsRequestTag()
     * - .ifAwsTagKeys()
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_TagResource.html
     */
    toTagResource() {
        return this.to('TagResource');
    }
    /**
     * Grants permission to issue Unload queries
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - s3:AbortMultipartUpload
     * - s3:GetObject
     * - s3:PutObject
     * - timestream:DescribeEndpoints
     * - timestream:Select
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_query_Query.html
     */
    toUnload() {
        return this.to('Unload');
    }
    /**
     * Grants permission to remove a tag from a resource
     *
     * Access Level: Tagging
     *
     * Possible conditions:
     * - .ifAwsTagKeys()
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_UntagResource.html
     */
    toUntagResource() {
        return this.to('UntagResource');
    }
    /**
     * Grants permission to update your account settings
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_query_UpdateAccountSettings.html
     */
    toUpdateAccountSettings() {
        return this.to('UpdateAccountSettings');
    }
    /**
     * Grants permission to update a database in your account
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_UpdateDatabase.html
     */
    toUpdateDatabase() {
        return this.to('UpdateDatabase');
    }
    /**
     * Grants permission to update a scheduled query in your account
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_UpdateScheduledQuery.html
     */
    toUpdateScheduledQuery() {
        return this.to('UpdateScheduledQuery');
    }
    /**
     * Grants permission to update a table in your account
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_UpdateTable.html
     */
    toUpdateTable() {
        return this.to('UpdateTable');
    }
    /**
     * Grants permission to ingest data to a table in your account
     *
     * Access Level: Write
     *
     * Dependent actions:
     * - timestream:DescribeEndpoints
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_WriteRecords.html
     */
    toWriteRecords() {
        return this.to('WriteRecords');
    }
    /**
     * Adds a resource of type database to the statement
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_Database.html
     *
     * @param databaseName - Identifier for the databaseName.
     * @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()
     */
    onDatabase(databaseName, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:timestream:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:database/${databaseName}`);
    }
    /**
     * Adds a resource of type table to the statement
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_Table.html
     *
     * @param databaseName - Identifier for the databaseName.
     * @param tableName - Identifier for the tableName.
     * @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()
     */
    onTable(databaseName, tableName, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:timestream:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:database/${databaseName}/table/${tableName}`);
    }
    /**
     * Adds a resource of type scheduled-query to the statement
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/API_ScheduledQuery.html
     *
     * @param scheduledQueryName - Identifier for the scheduledQueryName.
     * @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()
     */
    onScheduledQuery(scheduledQueryName, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:timestream:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:scheduled-query/${scheduledQueryName}`);
    }
    /**
     * Filters access by the presence of tag key-value pairs in the request
     *
     * https://docs.aws.amazon.com/timestream/latest/developerguide/security_iam_service-with-iam.html#security_iam_service-with-iam-tags
     *
     * Applies to actions:
     * - .toCreateDatabase()
     * - .toCreateScheduledQuery()
     * - .toCreateTable()
     * - .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/timestream/latest/developerguide/security_iam_service-with-iam.html#security_iam_service-with-iam-tags
     *
     * Applies to resource types:
     * - database
     * - table
     * - scheduled-query
     *
     * @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/timestream/latest/developerguide/security_iam_service-with-iam.html#security_iam_service-with-iam-tags
     *
     * Applies to actions:
     * - .toCreateDatabase()
     * - .toCreateScheduledQuery()
     * - .toCreateTable()
     * - .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 [timestream](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazontimestream.html).
     *
     */
    constructor(props) {
        super(props);
        this.servicePrefix = 'timestream';
        this.accessLevelList = {
            Write: [
                'CancelQuery',
                'CreateBatchLoadTask',
                'CreateDatabase',
                'CreateScheduledQuery',
                'CreateTable',
                'DeleteDatabase',
                'DeleteScheduledQuery',
                'DeleteTable',
                'ExecuteScheduledQuery',
                'ResumeBatchLoadTask',
                'StartAwsBackupJob',
                'StartAwsRestoreJob',
                'Unload',
                'UpdateAccountSettings',
                'UpdateDatabase',
                'UpdateScheduledQuery',
                'UpdateTable',
                'WriteRecords'
            ],
            Read: [
                'DescribeAccountSettings',
                'DescribeBatchLoadTask',
                'DescribeDatabase',
                'DescribeScheduledQuery',
                'DescribeTable',
                'GetAwsBackupStatus',
                'GetAwsRestoreStatus',
                'ListTagsForResource',
                'PrepareQuery',
                'Select',
                'SelectValues'
            ],
            List: [
                'DescribeEndpoints',
                'ListBatchLoadTasks',
                'ListDatabases',
                'ListMeasures',
                'ListScheduledQueries',
                'ListTables'
            ],
            Tagging: [
                'TagResource',
                'UntagResource'
            ]
        };
    }
}
exports.Timestream = Timestream;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXN0cmVhbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRpbWVzdHJlYW0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EseUNBQXlEO0FBR3pEOzs7O0dBSUc7QUFDSCxNQUFhLFVBQVcsU0FBUSx3QkFBZTtJQUc3Qzs7Ozs7Ozs7O09BU0c7SUFDSSxhQUFhO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLHFCQUFxQjtRQUMxQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNJLGdCQUFnQjtRQUNyQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7O09BY0c7SUFDSSxzQkFBc0I7UUFDM0IsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDSSxhQUFhO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksZ0JBQWdCO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSSxzQkFBc0I7UUFDM0IsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLGFBQWE7UUFDbEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSSx5QkFB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Q0ksWUFBWSxDQUFDLEtBQXdCLEVBQUUsUUFBNEI7UUFDeEUsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxLQUFLLEVBQUUsUUFBUSxJQUFJLFlBQVksQ0FBQyxDQUFDO0lBQ2pFLENBQUM7SUFFRDs7O09BR0c7SUFDSCxZQUFZLEtBQWdDO1FBQzFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQWpzQlIsa0JBQWEsR0FBRyxZQUFZLENBQUM7UUFnaUIxQixvQkFBZSxHQUFvQjtZQUMzQyxLQUFLLEVBQUU7Z0JBQ0wsYUFBYTtnQkFDYixxQkFBcUI7Z0JBQ3JCLGdCQUFnQjtnQkFDaEIsc0JBQXNCO2dCQUN0QixhQUFhO2dCQUNiLGdCQUFnQjtnQkFDaEIsc0JBQXNCO2dCQUN0QixhQUFhO2dCQUNiLHVCQUF1QjtnQkFDdkIscUJBQXFCO2dCQUNyQixtQkFBbUI7Z0JBQ25CLG9CQUFvQjtnQkFDcEIsUUFBUTtnQkFDUix1QkFBdUI7Z0JBQ3ZCLGdCQUFnQjtnQkFDaEIsc0JBQXNCO2dCQUN0QixhQUFhO2dCQUNiLGNBQWM7YUFDZjtZQUNELElBQUksRUFBRTtnQkFDSix5QkFBeUI7Z0JBQ3pCLHVCQUF1QjtnQkFDdkIsa0JBQWtCO2dCQUNsQix3QkFBd0I7Z0JBQ3hCLGVBQWU7Z0JBQ2Ysb0JBQW9CO2dCQUNwQixxQkFBcUI7Z0JBQ3JCLHFCQUFxQjtnQkFDckIsY0FBYztnQkFDZCxRQUFRO2dCQUNSLGNBQWM7YUFDZjtZQUNELElBQUksRUFBRTtnQkFDSixtQkFBbUI7Z0JBQ25CLG9CQUFvQjtnQkFDcEIsZUFBZTtnQkFDZixjQUFjO2dCQUNkLHNCQUFzQjtnQkFDdEIsWUFBWTthQUNiO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLGFBQWE7Z0JBQ2IsZUFBZTthQUNoQjtTQUNGLENBQUM7SUFvSEYsQ0FBQztDQUNGO0FBcHNCRCxnQ0Fvc0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWNjZXNzTGV2ZWxMaXN0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FjY2Vzcy1sZXZlbCc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQsIE9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcbmltcG9ydCB7IGF3c19pYW0gYXMgaWFtIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5cbi8qKlxuICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFt0aW1lc3RyZWFtXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vc2VydmljZS1hdXRob3JpemF0aW9uL2xhdGVzdC9yZWZlcmVuY2UvbGlzdF9hbWF6b250aW1lc3RyZWFtLmh0bWwpLlxuICpcbiAqIEBwYXJhbSBzaWQgW1NJRF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19zaWQuaHRtbCkgb2YgdGhlIHN0YXRlbWVudFxuICovXG5leHBvcnQgY2xhc3MgVGltZXN0cmVhbSBleHRlbmRzIFBvbGljeVN0YXRlbWVudCB7XG4gIHB1YmxpYyBzZXJ2aWNlUHJlZml4ID0gJ3RpbWVzdHJlYW0nO1xuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjYW5jZWwgcXVlcmllcyBpbiB5b3VyIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSB0aW1lc3RyZWFtOkRlc2NyaWJlRW5kcG9pbnRzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90aW1lc3RyZWFtL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9BUElfcXVlcnlfQ2FuY2VsUXVlcnkuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ2FuY2VsUXVlcnkoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NhbmNlbFF1ZXJ5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgYmF0Y2ggbG9hZCB0YXNrIGluIHlvdXIgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICogLSB0aW1lc3RyZWFtOldyaXRlUmVjb3Jkc1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdGltZXN0cmVhbS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvQVBJX0NyZWF0ZUJhdGNoTG9hZFRhc2suaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlQmF0Y2hMb2FkVGFzaygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlQmF0Y2hMb2FkVGFzaycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIGRhdGFiYXNlIGluIHlvdXIgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL0FQSV9DcmVhdGVEYXRhYmFzZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVEYXRhYmFzZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlRGF0YWJhc2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBzY2hlZHVsZWQgcXVlcnkgaW4geW91ciBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gaWFtOlBhc3NSb2xlXG4gICAqIC0gdGltZXN0cmVhbTpEZXNjcmliZUVuZHBvaW50c1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdGltZXN0cmVhbS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvQVBJX0NyZWF0ZVNjaGVkdWxlZFF1ZXJ5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NyZWF0ZVNjaGVkdWxlZFF1ZXJ5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVTY2hlZHVsZWRRdWVyeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIHRhYmxlIGluIHlvdXIgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL0FQSV9DcmVhdGVUYWJsZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVUYWJsZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlVGFibGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgYSBkYXRhYmFzZSBpbiB5b3VyIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSB0aW1lc3RyZWFtOkRlc2NyaWJlRW5kcG9pbnRzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90aW1lc3RyZWFtL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9BUElfRGVsZXRlRGF0YWJhc2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlRGF0YWJhc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZURhdGFiYXNlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVsZXRlIGEgc2NoZWR1bGVkIHF1ZXJ5IGluIHlvdXIgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL0FQSV9EZWxldGVTY2hlZHVsZWRRdWVyeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVTY2hlZHVsZWRRdWVyeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlU2NoZWR1bGVkUXVlcnknKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgYSB0YWJsZSBpbiB5b3VyIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSB0aW1lc3RyZWFtOkRlc2NyaWJlRW5kcG9pbnRzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90aW1lc3RyZWFtL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9BUElfRGVsZXRlVGFibGUuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlVGFibGUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVRhYmxlJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgeW91ciBhY2NvdW50IHNldHRpbmdzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSB0aW1lc3RyZWFtOkRlc2NyaWJlRW5kcG9pbnRzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90aW1lc3RyZWFtL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9BUElfcXVlcnlfRGVzY3JpYmVBY2NvdW50U2V0dGluZ3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVBY2NvdW50U2V0dGluZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlQWNjb3VudFNldHRpbmdzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgYSBiYXRjaCBsb2FkIHRhc2sgaW4geW91ciBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSB0aW1lc3RyZWFtOkRlc2NyaWJlRW5kcG9pbnRzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90aW1lc3RyZWFtL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9BUElfRGVzY3JpYmVCYXRjaExvYWRUYXNrLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlQmF0Y2hMb2FkVGFzaygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVCYXRjaExvYWRUYXNrJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gZGVzY3JpYmUgYSBkYXRhYmFzZSBpbiB5b3VyIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL0FQSV9EZXNjcmliZURhdGFiYXNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlRGF0YWJhc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlRGF0YWJhc2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSB0aW1lc3RyZWFtIGVuZHBvaW50c1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL0FQSV9EZXNjcmliZUVuZHBvaW50cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUVuZHBvaW50cygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVFbmRwb2ludHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSBhIHNjaGVkdWxlZCBxdWVyeSBpbiB5b3VyIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL0FQSV9EZXNjcmliZVNjaGVkdWxlZFF1ZXJ5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlU2NoZWR1bGVkUXVlcnkoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlU2NoZWR1bGVkUXVlcnknKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZXNjcmliZSBhIHRhYmxlIGluIHlvdXIgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gdGltZXN0cmVhbTpEZXNjcmliZUVuZHBvaW50c1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdGltZXN0cmVhbS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvQVBJX0Rlc2NyaWJlVGFibGUuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVUYWJsZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVUYWJsZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGV4ZWN1dGUgYSBzY2hlZHVsZWQgcXVlcnkgaW4geW91ciBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gdGltZXN0cmVhbTpEZXNjcmliZUVuZHBvaW50c1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdGltZXN0cmVhbS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvQVBJX0V4ZWN1dGVTY2hlZHVsZWRRdWVyeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9FeGVjdXRlU2NoZWR1bGVkUXVlcnkoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0V4ZWN1dGVTY2hlZHVsZWRRdWVyeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBTdGF0dXMgb2YgYSBUaW1lc3RyZWFtIFRhYmxlIEJhY2t1cFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gdGltZXN0cmVhbTpEZXNjcmliZUVuZHBvaW50c1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdGltZXN0cmVhbS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvYmFja3Vwcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9HZXRBd3NCYWNrdXBTdGF0dXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0dldEF3c0JhY2t1cFN0YXR1cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGdldCBTdGF0dXMgb2YgYSBUaW1lc3RyZWFtIFRhYmxlIFJlc3RvcmVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2JhY2t1cHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvR2V0QXdzUmVzdG9yZVN0YXR1cygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnR2V0QXdzUmVzdG9yZVN0YXR1cycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgYmF0Y2ggbG9hZCB0YXNrcyBpbiB5b3VyIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL0FQSV9MaXN0QmF0Y2hMb2FkVGFza3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdEJhdGNoTG9hZFRhc2tzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0QmF0Y2hMb2FkVGFza3MnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IGRhdGFiYXNlcyBpbiB5b3VyIGFjY291bnRcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL0FQSV9MaXN0RGF0YWJhc2VzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3REYXRhYmFzZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0xpc3REYXRhYmFzZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IG1lYXN1cmVzIG9mIGEgdGFibGUgaW4geW91ciBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSB0aW1lc3RyZWFtOkRlc2NyaWJlRW5kcG9pbnRzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90aW1lc3RyZWFtL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9BUElfcXVlcnlfUXVlcnkuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdE1lYXN1cmVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0TWVhc3VyZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBsaXN0IHNjaGVkdWxlZCBxdWVyaWVzIGluIHlvdXIgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gdGltZXN0cmVhbTpEZXNjcmliZUVuZHBvaW50c1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdGltZXN0cmVhbS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvQVBJX0xpc3RTY2hlZHVsZWRRdWVyaWVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0xpc3RTY2hlZHVsZWRRdWVyaWVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdMaXN0U2NoZWR1bGVkUXVlcmllcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgdGFibGVzIGluIHlvdXIgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gdGltZXN0cmVhbTpEZXNjcmliZUVuZHBvaW50c1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdGltZXN0cmVhbS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvQVBJX0xpc3RUYWJsZXMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFRhYmxlcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFRhYmxlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGxpc3QgdGFncyBvZiBhIHJlc291cmNlIGluIHlvdXIgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gdGltZXN0cmVhbTpEZXNjcmliZUVuZHBvaW50c1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdGltZXN0cmVhbS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvQVBJX0xpc3RUYWdzRm9yUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFRhZ3NGb3JSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFRhZ3NGb3JSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGlzc3VlIHByZXBhcmUgcXVlcmllc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gdGltZXN0cmVhbTpEZXNjcmliZUVuZHBvaW50c1xuICAgKiAtIHRpbWVzdHJlYW06U2VsZWN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90aW1lc3RyZWFtL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9BUElfcXVlcnlfUHJlcGFyZVF1ZXJ5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1ByZXBhcmVRdWVyeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUHJlcGFyZVF1ZXJ5Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gcmVzdW1lIGEgYmF0Y2ggbG9hZCB0YXNrIGluIHlvdXIgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICogLSB0aW1lc3RyZWFtOldyaXRlUmVjb3Jkc1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdGltZXN0cmVhbS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvQVBJX1Jlc3VtZUJhdGNoTG9hZFRhc2suaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUmVzdW1lQmF0Y2hMb2FkVGFzaygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUmVzdW1lQmF0Y2hMb2FkVGFzaycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGlzc3VlICdzZWxlY3QgZnJvbSB0YWJsZScgcXVlcmllc1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gdGltZXN0cmVhbTpEZXNjcmliZUVuZHBvaW50c1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdGltZXN0cmVhbS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvQVBJX3F1ZXJ5X1F1ZXJ5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1NlbGVjdCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnU2VsZWN0Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gaXNzdWUgJ3NlbGVjdCAxJyBxdWVyaWVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSB0aW1lc3RyZWFtOkRlc2NyaWJlRW5kcG9pbnRzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90aW1lc3RyZWFtL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9BUElfcXVlcnlfUXVlcnkuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvU2VsZWN0VmFsdWVzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdTZWxlY3RWYWx1ZXMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBzdGFydCBhIEJhY2t1cCBKb2IgZm9yIGEgVGltZXN0cmVhbSBUYWJsZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL2JhY2t1cHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvU3RhcnRBd3NCYWNrdXBKb2IoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1N0YXJ0QXdzQmFja3VwSm9iJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gc3RhcnQgUmVzdG9yZSBKb2IgZm9yIGEgQmFja3VwIG9mIFRpbWVzdHJlYW0gVGFibGVcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSB0aW1lc3RyZWFtOkRlc2NyaWJlRW5kcG9pbnRzXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90aW1lc3RyZWFtL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9iYWNrdXBzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1N0YXJ0QXdzUmVzdG9yZUpvYigpIHtcbiAgICByZXR1cm4gdGhpcy50bygnU3RhcnRBd3NSZXN0b3JlSm9iJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWRkIHRhZ3MgdG8gYSByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gdGltZXN0cmVhbTpEZXNjcmliZUVuZHBvaW50c1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdGltZXN0cmVhbS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvQVBJX1RhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1RhZ1Jlc291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdUYWdSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGlzc3VlIFVubG9hZCBxdWVyaWVzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gczM6QWJvcnRNdWx0aXBhcnRVcGxvYWRcbiAgICogLSBzMzpHZXRPYmplY3RcbiAgICogLSBzMzpQdXRPYmplY3RcbiAgICogLSB0aW1lc3RyZWFtOkRlc2NyaWJlRW5kcG9pbnRzXG4gICAqIC0gdGltZXN0cmVhbTpTZWxlY3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL0FQSV9xdWVyeV9RdWVyeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VbmxvYWQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VubG9hZCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHJlbW92ZSBhIHRhZyBmcm9tIGEgcmVzb3VyY2VcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBUYWdnaW5nXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL0FQSV9VbnRhZ1Jlc291cmNlLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VudGFnUmVzb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VudGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgeW91ciBhY2NvdW50IHNldHRpbmdzXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gdGltZXN0cmVhbTpEZXNjcmliZUVuZHBvaW50c1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdGltZXN0cmVhbS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvQVBJX3F1ZXJ5X1VwZGF0ZUFjY291bnRTZXR0aW5ncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVBY2NvdW50U2V0dGluZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZUFjY291bnRTZXR0aW5ncycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSBhIGRhdGFiYXNlIGluIHlvdXIgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL0FQSV9VcGRhdGVEYXRhYmFzZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVEYXRhYmFzZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlRGF0YWJhc2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgYSBzY2hlZHVsZWQgcXVlcnkgaW4geW91ciBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gdGltZXN0cmVhbTpEZXNjcmliZUVuZHBvaW50c1xuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vdGltZXN0cmVhbS9sYXRlc3QvZGV2ZWxvcGVyZ3VpZGUvQVBJX1VwZGF0ZVNjaGVkdWxlZFF1ZXJ5Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZVNjaGVkdWxlZFF1ZXJ5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdVcGRhdGVTY2hlZHVsZWRRdWVyeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSBhIHRhYmxlIGluIHlvdXIgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL0FQSV9VcGRhdGVUYWJsZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9VcGRhdGVUYWJsZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVXBkYXRlVGFibGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBpbmdlc3QgZGF0YSB0byBhIHRhYmxlIGluIHlvdXIgYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIERlcGVuZGVudCBhY3Rpb25zOlxuICAgKiAtIHRpbWVzdHJlYW06RGVzY3JpYmVFbmRwb2ludHNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL0FQSV9Xcml0ZVJlY29yZHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvV3JpdGVSZWNvcmRzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdXcml0ZVJlY29yZHMnKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhY2Nlc3NMZXZlbExpc3Q6IEFjY2Vzc0xldmVsTGlzdCA9IHtcbiAgICBXcml0ZTogW1xuICAgICAgJ0NhbmNlbFF1ZXJ5JyxcbiAgICAgICdDcmVhdGVCYXRjaExvYWRUYXNrJyxcbiAgICAgICdDcmVhdGVEYXRhYmFzZScsXG4gICAgICAnQ3JlYXRlU2NoZWR1bGVkUXVlcnknLFxuICAgICAgJ0NyZWF0ZVRhYmxlJyxcbiAgICAgICdEZWxldGVEYXRhYmFzZScsXG4gICAgICAnRGVsZXRlU2NoZWR1bGVkUXVlcnknLFxuICAgICAgJ0RlbGV0ZVRhYmxlJyxcbiAgICAgICdFeGVjdXRlU2NoZWR1bGVkUXVlcnknLFxuICAgICAgJ1Jlc3VtZUJhdGNoTG9hZFRhc2snLFxuICAgICAgJ1N0YXJ0QXdzQmFja3VwSm9iJyxcbiAgICAgICdTdGFydEF3c1Jlc3RvcmVKb2InLFxuICAgICAgJ1VubG9hZCcsXG4gICAgICAnVXBkYXRlQWNjb3VudFNldHRpbmdzJyxcbiAgICAgICdVcGRhdGVEYXRhYmFzZScsXG4gICAgICAnVXBkYXRlU2NoZWR1bGVkUXVlcnknLFxuICAgICAgJ1VwZGF0ZVRhYmxlJyxcbiAgICAgICdXcml0ZVJlY29yZHMnXG4gICAgXSxcbiAgICBSZWFkOiBbXG4gICAgICAnRGVzY3JpYmVBY2NvdW50U2V0dGluZ3MnLFxuICAgICAgJ0Rlc2NyaWJlQmF0Y2hMb2FkVGFzaycsXG4gICAgICAnRGVzY3JpYmVEYXRhYmFzZScsXG4gICAgICAnRGVzY3JpYmVTY2hlZHVsZWRRdWVyeScsXG4gICAgICAnRGVzY3JpYmVUYWJsZScsXG4gICAgICAnR2V0QXdzQmFja3VwU3RhdHVzJyxcbiAgICAgICdHZXRBd3NSZXN0b3JlU3RhdHVzJyxcbiAgICAgICdMaXN0VGFnc0ZvclJlc291cmNlJyxcbiAgICAgICdQcmVwYXJlUXVlcnknLFxuICAgICAgJ1NlbGVjdCcsXG4gICAgICAnU2VsZWN0VmFsdWVzJ1xuICAgIF0sXG4gICAgTGlzdDogW1xuICAgICAgJ0Rlc2NyaWJlRW5kcG9pbnRzJyxcbiAgICAgICdMaXN0QmF0Y2hMb2FkVGFza3MnLFxuICAgICAgJ0xpc3REYXRhYmFzZXMnLFxuICAgICAgJ0xpc3RNZWFzdXJlcycsXG4gICAgICAnTGlzdFNjaGVkdWxlZFF1ZXJpZXMnLFxuICAgICAgJ0xpc3RUYWJsZXMnXG4gICAgXSxcbiAgICBUYWdnaW5nOiBbXG4gICAgICAnVGFnUmVzb3VyY2UnLFxuICAgICAgJ1VudGFnUmVzb3VyY2UnXG4gICAgXVxuICB9O1xuXG4gIC8qKlxuICAgKiBBZGRzIGEgcmVzb3VyY2Ugb2YgdHlwZSBkYXRhYmFzZSB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90aW1lc3RyZWFtL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9BUElfRGF0YWJhc2UuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gZGF0YWJhc2VOYW1lIC0gSWRlbnRpZmllciBmb3IgdGhlIGRhdGFiYXNlTmFtZS5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKi9cbiAgcHVibGljIG9uRGF0YWJhc2UoZGF0YWJhc2VOYW1lOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06dGltZXN0cmVhbTokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06ZGF0YWJhc2UvJHsgZGF0YWJhc2VOYW1lIH1gKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgcmVzb3VyY2Ugb2YgdHlwZSB0YWJsZSB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90aW1lc3RyZWFtL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9BUElfVGFibGUuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gZGF0YWJhc2VOYW1lIC0gSWRlbnRpZmllciBmb3IgdGhlIGRhdGFiYXNlTmFtZS5cbiAgICogQHBhcmFtIHRhYmxlTmFtZSAtIElkZW50aWZpZXIgZm9yIHRoZSB0YWJsZU5hbWUuXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQWNjb3VudCBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgYWNjb3VudC5cbiAgICogQHBhcmFtIHJlZ2lvbiAtIFJlZ2lvbiBvZiB0aGUgcmVzb3VyY2U7IGRlZmF1bHRzIHRvIGAqYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcmVnaW9uLlxuICAgKiBAcGFyYW0gcGFydGl0aW9uIC0gUGFydGl0aW9uIG9mIHRoZSBBV1MgYWNjb3VudCBbYXdzLCBhd3MtY24sIGF3cy11cy1nb3ZdOyBkZWZhdWx0cyB0byBgYXdzYCwgdW5sZXNzIHVzaW5nIHRoZSBDREssIHdoZXJlIHRoZSBkZWZhdWx0IGlzIHRoZSBjdXJyZW50IFN0YWNrJ3MgcGFydGl0aW9uLlxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1Jlc291cmNlVGFnKClcbiAgICovXG4gIHB1YmxpYyBvblRhYmxlKGRhdGFiYXNlTmFtZTogc3RyaW5nLCB0YWJsZU5hbWU6IHN0cmluZywgYWNjb3VudD86IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBwYXJ0aXRpb24/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5vbihgYXJuOiR7IHBhcnRpdGlvbiA/PyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTp0aW1lc3RyZWFtOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpkYXRhYmFzZS8keyBkYXRhYmFzZU5hbWUgfS90YWJsZS8keyB0YWJsZU5hbWUgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIHNjaGVkdWxlZC1xdWVyeSB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90aW1lc3RyZWFtL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9BUElfU2NoZWR1bGVkUXVlcnkuaHRtbFxuICAgKlxuICAgKiBAcGFyYW0gc2NoZWR1bGVkUXVlcnlOYW1lIC0gSWRlbnRpZmllciBmb3IgdGhlIHNjaGVkdWxlZFF1ZXJ5TmFtZS5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKi9cbiAgcHVibGljIG9uU2NoZWR1bGVkUXVlcnkoc2NoZWR1bGVkUXVlcnlOYW1lOiBzdHJpbmcsIGFjY291bnQ/OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgcGFydGl0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMub24oYGFybjokeyBwYXJ0aXRpb24gPz8gdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06dGltZXN0cmVhbTokeyByZWdpb24gPz8gdGhpcy5kZWZhdWx0UmVnaW9uIH06JHsgYWNjb3VudCA/PyB0aGlzLmRlZmF1bHRBY2NvdW50IH06c2NoZWR1bGVkLXF1ZXJ5LyR7IHNjaGVkdWxlZFF1ZXJ5TmFtZSB9YCk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIHByZXNlbmNlIG9mIHRhZyBrZXktdmFsdWUgcGFpcnMgaW4gdGhlIHJlcXVlc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3NlY3VyaXR5X2lhbV9zZXJ2aWNlLXdpdGgtaWFtLmh0bWwjc2VjdXJpdHlfaWFtX3NlcnZpY2Utd2l0aC1pYW0tdGFnc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ3JlYXRlRGF0YWJhc2UoKVxuICAgKiAtIC50b0NyZWF0ZVNjaGVkdWxlZFF1ZXJ5KClcbiAgICogLSAudG9DcmVhdGVUYWJsZSgpXG4gICAqIC0gLnRvVGFnUmVzb3VyY2UoKVxuICAgKlxuICAgKiBAcGFyYW0gdGFnS2V5IFRoZSB0YWcga2V5IHRvIGNoZWNrXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQXdzUmVxdWVzdFRhZyh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpSZXF1ZXN0VGFnLyR7IHRhZ0tleSB9YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGFnIGtleS12YWx1ZSBwYWlycyBhdHRhY2hlZCB0byB0aGUgcmVzb3VyY2VcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3RpbWVzdHJlYW0vbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3NlY3VyaXR5X2lhbV9zZXJ2aWNlLXdpdGgtaWFtLmh0bWwjc2VjdXJpdHlfaWFtX3NlcnZpY2Utd2l0aC1pYW0tdGFnc1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIGRhdGFiYXNlXG4gICAqIC0gdGFibGVcbiAgICogLSBzY2hlZHVsZWQtcXVlcnlcbiAgICpcbiAgICogQHBhcmFtIHRhZ0tleSBUaGUgdGFnIGtleSB0byBjaGVja1xuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkF3c1Jlc291cmNlVGFnKHRhZ0tleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgc3RyaW5nW10sIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5pZihgYXdzOlJlc291cmNlVGFnLyR7IHRhZ0tleSB9YCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIHByZXNlbmNlIG9mIHRhZyBrZXlzIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS90aW1lc3RyZWFtL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9zZWN1cml0eV9pYW1fc2VydmljZS13aXRoLWlhbS5odG1sI3NlY3VyaXR5X2lhbV9zZXJ2aWNlLXdpdGgtaWFtLXRhZ3NcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NyZWF0ZURhdGFiYXNlKClcbiAgICogLSAudG9DcmVhdGVTY2hlZHVsZWRRdWVyeSgpXG4gICAqIC0gLnRvQ3JlYXRlVGFibGUoKVxuICAgKiAtIC50b1RhZ1Jlc291cmNlKClcbiAgICogLSAudG9VbnRhZ1Jlc291cmNlKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NUYWdLZXlzKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6VGFnS2V5c2AsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXRlbWVudCBwcm92aWRlciBmb3Igc2VydmljZSBbdGltZXN0cmVhbV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYW1hem9udGltZXN0cmVhbS5odG1sKS5cbiAgICpcbiAgICovXG4gIGNvbnN0cnVjdG9yKHByb3BzPzogaWFtLlBvbGljeVN0YXRlbWVudFByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICB9XG59XG4iXX0=