UNPKG

cdk-iam-floyd

Version:

AWS IAM policy statement generator with fluent interface for AWS CDK

636 lines 58.6 kB
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Elasticfilesystem = void 0;
const shared_1 = require("../../shared");
/**
 * Statement provider for service [elasticfilesystem](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonelasticfilesystem.html).
 *
 * @param sid [SID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_sid.html) of the statement
 */
class Elasticfilesystem extends shared_1.PolicyStatement {
    /**
     * Grants permission to start a backup job for an existing file system
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/efs-backup-solutions.html
     */
    toBackup() {
        return this.to('Backup');
    }
    /**
     * Grants permission to allow an NFS client read-access to a file system
     *
     * Access Level: Read
     *
     * Possible conditions:
     * - .ifAccessPointArn()
     * - .ifAccessedViaMountTarget()
     *
     * https://docs.aws.amazon.com/efs/latest/ug/efs-client-authorization.html
     */
    toClientMount() {
        return this.to('ClientMount');
    }
    /**
     * Grants permission to allow an NFS client root-access to a file system
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifAccessPointArn()
     * - .ifAccessedViaMountTarget()
     *
     * https://docs.aws.amazon.com/efs/latest/ug/efs-client-authorization.html
     */
    toClientRootAccess() {
        return this.to('ClientRootAccess');
    }
    /**
     * Grants permission to allow an NFS client write-access to a file system
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifAccessPointArn()
     * - .ifAccessedViaMountTarget()
     *
     * https://docs.aws.amazon.com/efs/latest/ug/efs-client-authorization.html
     */
    toClientWrite() {
        return this.to('ClientWrite');
    }
    /**
     * Grants permission to create an access point for the specified file system
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifAwsTagKeys()
     * - .ifAwsRequestTag()
     *
     * Dependent actions:
     * - elasticfilesystem:TagResource
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_CreateAccessPoint.html
     */
    toCreateAccessPoint() {
        return this.to('CreateAccessPoint');
    }
    /**
     * Grants permission to create a new, empty file system
     *
     * Access Level: Write
     *
     * Possible conditions:
     * - .ifAwsRequestTag()
     * - .ifAwsTagKeys()
     * - .ifEncrypted()
     *
     * Dependent actions:
     * - elasticfilesystem:TagResource
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_CreateFileSystem.html
     */
    toCreateFileSystem() {
        return this.to('CreateFileSystem');
    }
    /**
     * Grants permission to create a mount target for a file system
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_CreateMountTarget.html
     */
    toCreateMountTarget() {
        return this.to('CreateMountTarget');
    }
    /**
     * Grants permission to create a new replication configuration
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_CreateReplicationConfiguration.html
     */
    toCreateReplicationConfiguration() {
        return this.to('CreateReplicationConfiguration');
    }
    /**
     * Grants permission to create or overwrite tags associated with a file system; deprecated, see TagResource
     *
     * Access Level: Tagging
     *
     * Possible conditions:
     * - .ifAwsRequestTag()
     * - .ifAwsTagKeys()
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_CreateTags.html
     */
    toCreateTags() {
        return this.to('CreateTags');
    }
    /**
     * Grants permission to delete the specified access point
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DeleteAccessPoint.html
     */
    toDeleteAccessPoint() {
        return this.to('DeleteAccessPoint');
    }
    /**
     * Grants permission to delete a file system, permanently severing access to its contents
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DeleteFileSystem.html
     */
    toDeleteFileSystem() {
        return this.to('DeleteFileSystem');
    }
    /**
     * Grants permission to delete the resource-level policy for a file system
     *
     * Access Level: Permissions management
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DeleteFileSystemPolicy.html
     */
    toDeleteFileSystemPolicy() {
        return this.to('DeleteFileSystemPolicy');
    }
    /**
     * Grants permission to delete the specified mount target
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DeleteMountTarget.html
     */
    toDeleteMountTarget() {
        return this.to('DeleteMountTarget');
    }
    /**
     * Grants permission to delete a replication configuration
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DeleteReplicationConfiguration.html
     */
    toDeleteReplicationConfiguration() {
        return this.to('DeleteReplicationConfiguration');
    }
    /**
     * Grants permission to delete the specified tags from a file system; deprecated, see UntagResource
     *
     * Access Level: Tagging
     *
     * Possible conditions:
     * - .ifAwsTagKeys()
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DeleteTags.html
     */
    toDeleteTags() {
        return this.to('DeleteTags');
    }
    /**
     * Grants permission to view the descriptions of Amazon EFS access points
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DescribeAccessPoints.html
     */
    toDescribeAccessPoints() {
        return this.to('DescribeAccessPoints');
    }
    /**
     * Grants permission to view the account preferences in effect for an account
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DescribeAccountPreferences.html
     */
    toDescribeAccountPreferences() {
        return this.to('DescribeAccountPreferences');
    }
    /**
     * Grants permission to view the BackupPolicy object for an Amazon EFS file system
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DescribeBackupPolicy.html
     */
    toDescribeBackupPolicy() {
        return this.to('DescribeBackupPolicy');
    }
    /**
     * Grants permission to view the resource-level policy for an Amazon EFS file system
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DescribeFileSystemPolicy.html
     */
    toDescribeFileSystemPolicy() {
        return this.to('DescribeFileSystemPolicy');
    }
    /**
     * Grants permission to view the description of an Amazon EFS file system specified by file system CreationToken or FileSystemId; or to view the description of all file systems owned by the caller's AWS account in the AWS region of the endpoint that is being called
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DescribeFileSystems.html
     */
    toDescribeFileSystems() {
        return this.to('DescribeFileSystems');
    }
    /**
     * Grants permission to view the LifecycleConfiguration object for an Amazon EFS file system
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DescribeLifecycleConfiguration.html
     */
    toDescribeLifecycleConfiguration() {
        return this.to('DescribeLifecycleConfiguration');
    }
    /**
     * Grants permission to view the security groups in effect for a mount target
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DescribeMountTargetSecurityGroups.html
     */
    toDescribeMountTargetSecurityGroups() {
        return this.to('DescribeMountTargetSecurityGroups');
    }
    /**
     * Grants permission to view the descriptions of all mount targets, or a specific mount target, for a file system
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DescribeMountTargets.html
     */
    toDescribeMountTargets() {
        return this.to('DescribeMountTargets');
    }
    /**
     * Grants permission to view the description of an Amazon EFS replication configuration specified by FileSystemId; or to view the description of all replication configurations owned by the caller's AWS account in the AWS region of the endpoint that is being called
     *
     * Access Level: List
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DescribeReplicationConfigurations.html
     */
    toDescribeReplicationConfigurations() {
        return this.to('DescribeReplicationConfigurations');
    }
    /**
     * Grants permission to view the tags associated with a file system
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_DescribeTags.html
     */
    toDescribeTags() {
        return this.to('DescribeTags');
    }
    /**
     * Grants permission to view the tags associated with the specified Amazon EFS resource
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_ListTagsForResource.html
     */
    toListTagsForResource() {
        return this.to('ListTagsForResource');
    }
    /**
     * Grants permission to modify the set of security groups in effect for a mount target
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_ModifyMountTargetSecurityGroups.html
     */
    toModifyMountTargetSecurityGroups() {
        return this.to('ModifyMountTargetSecurityGroups');
    }
    /**
     * Grants permission to set the account preferences of an account
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_PutAccountPreferences.html
     */
    toPutAccountPreferences() {
        return this.to('PutAccountPreferences');
    }
    /**
     * Grants permission to enable or disable automatic backups with AWS Backup by creating a new BackupPolicy object
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_PutBackupPolicy.html
     */
    toPutBackupPolicy() {
        return this.to('PutBackupPolicy');
    }
    /**
     * Grants permission to apply a resource-level policy that defines the actions allowed or denied from given actors for the specified file system
     *
     * Access Level: Permissions management
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_PutFileSystemPolicy.html
     */
    toPutFileSystemPolicy() {
        return this.to('PutFileSystemPolicy');
    }
    /**
     * Grants permission to enable lifecycle management by creating a new LifecycleConfiguration object
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_PutLifecycleConfiguration.html
     */
    toPutLifecycleConfiguration() {
        return this.to('PutLifecycleConfiguration');
    }
    /**
     * Grants permission to read file system data for replication
     *
     * Access Level: Read
     *
     * https://docs.aws.amazon.com/efs/latest/ug/efs-replication.html
     */
    toReplicationRead() {
        return this.to('ReplicationRead');
    }
    /**
     * Grants permission to replicate data to a file system
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/efs-replication.html
     */
    toReplicationWrite() {
        return this.to('ReplicationWrite');
    }
    /**
     * Grants permission to start a restore job for a backup of a file system
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/efs-backup-solutions.html
     */
    toRestore() {
        return this.to('Restore');
    }
    /**
     * Grants permission to create or overwrite tags associated with the specified Amazon EFS resource
     *
     * Access Level: Tagging
     *
     * Possible conditions:
     * - .ifAwsRequestTag()
     * - .ifAwsTagKeys()
     * - .ifCreateAction()
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_TagResource.html
     */
    toTagResource() {
        return this.to('TagResource');
    }
    /**
     * Grants permission to delete the specified tags from an Amazon EFS resource
     *
     * Access Level: Tagging
     *
     * Possible conditions:
     * - .ifAwsTagKeys()
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_UntagResource.html
     */
    toUntagResource() {
        return this.to('UntagResource');
    }
    /**
     * Grants permission to update the throughput mode or the amount of provisioned throughput of an existing file system
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_UpdateFileSystem.html
     */
    toUpdateFileSystem() {
        return this.to('UpdateFileSystem');
    }
    /**
     * Grants permission to update the file system protection of an existing file system
     *
     * Access Level: Write
     *
     * https://docs.aws.amazon.com/efs/latest/ug/API_UpdateFileSystemProtection.html
     */
    toUpdateFileSystemProtection() {
        return this.to('UpdateFileSystemProtection');
    }
    /**
     * Adds a resource of type file-system to the statement
     *
     * https://docs.aws.amazon.com/efs/latest/ug/creating-using-create-fs.html
     *
     * @param fileSystemId - Identifier for the fileSystemId.
     * @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()
     */
    onFileSystem(fileSystemId, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:elasticfilesystem:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:file-system/${fileSystemId}`);
    }
    /**
     * Adds a resource of type access-point to the statement
     *
     * https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html
     *
     * @param accessPointId - Identifier for the accessPointId.
     * @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()
     */
    onAccessPoint(accessPointId, account, region, partition) {
        return this.on(`arn:${partition ?? this.defaultPartition}:elasticfilesystem:${region ?? this.defaultRegion}:${account ?? this.defaultAccount}:access-point/${accessPointId}`);
    }
    /**
     * Filters access by a tag key and value pair that is allowed in the request
     *
     * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag
     *
     * Applies to actions:
     * - .toCreateAccessPoint()
     * - .toCreateFileSystem()
     * - .toCreateTags()
     * - .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 a tag key and value pair of a resource
     *
     * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag
     *
     * Applies to resource types:
     * - file-system
     * - access-point
     *
     * @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 a list of tag keys that are allowed in the request
     *
     * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys
     *
     * Applies to actions:
     * - .toCreateAccessPoint()
     * - .toCreateFileSystem()
     * - .toCreateTags()
     * - .toDeleteTags()
     * - .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 ARN of the access point used to mount the file system
     *
     * https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html
     *
     * Applies to actions:
     * - .toClientMount()
     * - .toClientRootAccess()
     * - .toClientWrite()
     *
     * @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`
     */
    ifAccessPointArn(value, operator) {
        return this.if(`AccessPointArn`, value, operator ?? 'ArnLike');
    }
    /**
     * Filters access by whether the file system is accessed via mount targets
     *
     * https://docs.aws.amazon.com/efs/latest/ug/mounting-fs.html
     *
     * Applies to actions:
     * - .toClientMount()
     * - .toClientRootAccess()
     * - .toClientWrite()
     *
     * @param value `true` or `false`. **Default:** `true`
     */
    ifAccessedViaMountTarget(value) {
        return this.if(`AccessedViaMountTarget`, (typeof value !== 'undefined' ? value : true), 'Bool');
    }
    /**
     * Filters access by the name of a resource-creating API action
     *
     * https://docs.aws.amazon.com/efs/latest/ug/using-tags-efs.html
     *
     * Applies to actions:
     * - .toTagResource()
     *
     * @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`
     */
    ifCreateAction(value, operator) {
        return this.if(`CreateAction`, value, operator ?? 'StringLike');
    }
    /**
     * Filters access by whether users can create only encrypted or unencrypted file systems
     *
     * https://docs.aws.amazon.com/efs/latest/ug/encryption.html
     *
     * Applies to actions:
     * - .toCreateFileSystem()
     *
     * @param value `true` or `false`. **Default:** `true`
     */
    ifEncrypted(value) {
        return this.if(`Encrypted`, (typeof value !== 'undefined' ? value : true), 'Bool');
    }
    /**
     * Statement provider for service [elasticfilesystem](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonelasticfilesystem.html).
     *
     */
    constructor(props) {
        super(props);
        this.servicePrefix = 'elasticfilesystem';
        this.accessLevelList = {
            Write: [
                'Backup',
                'ClientRootAccess',
                'ClientWrite',
                'CreateAccessPoint',
                'CreateFileSystem',
                'CreateMountTarget',
                'CreateReplicationConfiguration',
                'DeleteAccessPoint',
                'DeleteFileSystem',
                'DeleteMountTarget',
                'DeleteReplicationConfiguration',
                'ModifyMountTargetSecurityGroups',
                'PutAccountPreferences',
                'PutBackupPolicy',
                'PutLifecycleConfiguration',
                'ReplicationWrite',
                'Restore',
                'UpdateFileSystem',
                'UpdateFileSystemProtection'
            ],
            Read: [
                'ClientMount',
                'DescribeBackupPolicy',
                'DescribeFileSystemPolicy',
                'DescribeLifecycleConfiguration',
                'DescribeMountTargetSecurityGroups',
                'DescribeMountTargets',
                'DescribeTags',
                'ListTagsForResource',
                'ReplicationRead'
            ],
            Tagging: [
                'CreateTags',
                'DeleteTags',
                'TagResource',
                'UntagResource'
            ],
            'Permissions management': [
                'DeleteFileSystemPolicy',
                'PutFileSystemPolicy'
            ],
            List: [
                'DescribeAccessPoints',
                'DescribeAccountPreferences',
                'DescribeFileSystems',
                'DescribeReplicationConfigurations'
            ]
        };
    }
}
exports.Elasticfilesystem = Elasticfilesystem;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxhc3RpY2ZpbGVzeXN0ZW0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJlbGFzdGljZmlsZXN5c3RlbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSx5Q0FBeUQ7QUFHekQ7Ozs7R0FJRztBQUNILE1BQWEsaUJBQWtCLFNBQVEsd0JBQWU7SUFHcEQ7Ozs7OztPQU1HO0lBQ0ksUUFBUTtRQUNiLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLGFBQWE7UUFDbEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksa0JBQWtCO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksYUFBYTtRQUNsQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDSSxtQkFBbUI7UUFDeEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7OztPQWNHO0lBQ0ksa0JBQWtCO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxtQkFBbUI7UUFDeEIsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGdDQUFnQztRQUNyQyxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJ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a0JBQWtCO2dCQUNsQiw0QkFBNEI7YUFDN0I7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osYUFBYTtnQkFDYixzQkFBc0I7Z0JBQ3RCLDBCQUEwQjtnQkFDMUIsZ0NBQWdDO2dCQUNoQyxtQ0FBbUM7Z0JBQ25DLHNCQUFzQjtnQkFDdEIsY0FBYztnQkFDZCxxQkFBcUI7Z0JBQ3JCLGlCQUFpQjthQUNsQjtZQUNELE9BQU8sRUFBRTtnQkFDUCxZQUFZO2dCQUNaLFlBQVk7Z0JBQ1osYUFBYTtnQkFDYixlQUFlO2FBQ2hCO1lBQ0Qsd0JBQXdCLEVBQUU7Z0JBQ3hCLHdCQUF3QjtnQkFDeEIscUJBQXFCO2FBQ3RCO1lBQ0QsSUFBSSxFQUFFO2dCQUNKLHNCQUFzQjtnQkFDdEIsNEJBQTRCO2dCQUM1QixxQkFBcUI7Z0JBQ3JCLG1DQUFtQzthQUNwQztTQUNGLENBQUM7SUFnS0YsQ0FBQztDQUNGO0FBanFCRCw4Q0FpcUJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWNjZXNzTGV2ZWxMaXN0IH0gZnJvbSAnLi4vLi4vc2hhcmVkL2FjY2Vzcy1sZXZlbCc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQsIE9wZXJhdG9yIH0gZnJvbSAnLi4vLi4vc2hhcmVkJztcbmltcG9ydCB7IGF3c19pYW0gYXMgaWFtIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5cbi8qKlxuICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFtlbGFzdGljZmlsZXN5c3RlbV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYW1hem9uZWxhc3RpY2ZpbGVzeXN0ZW0uaHRtbCkuXG4gKlxuICogQHBhcmFtIHNpZCBbU0lEXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX3NpZC5odG1sKSBvZiB0aGUgc3RhdGVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBFbGFzdGljZmlsZXN5c3RlbSBleHRlbmRzIFBvbGljeVN0YXRlbWVudCB7XG4gIHB1YmxpYyBzZXJ2aWNlUHJlZml4ID0gJ2VsYXN0aWNmaWxlc3lzdGVtJztcblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gc3RhcnQgYSBiYWNrdXAgam9iIGZvciBhbiBleGlzdGluZyBmaWxlIHN5c3RlbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL2Vmcy1iYWNrdXAtc29sdXRpb25zLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0JhY2t1cCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQmFja3VwJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gYWxsb3cgYW4gTkZTIGNsaWVudCByZWFkLWFjY2VzcyB0byBhIGZpbGUgc3lzdGVtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkFjY2Vzc1BvaW50QXJuKClcbiAgICogLSAuaWZBY2Nlc3NlZFZpYU1vdW50VGFyZ2V0KClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvZWZzLWNsaWVudC1hdXRob3JpemF0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NsaWVudE1vdW50KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDbGllbnRNb3VudCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFsbG93IGFuIE5GUyBjbGllbnQgcm9vdC1hY2Nlc3MgdG8gYSBmaWxlIHN5c3RlbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQWNjZXNzUG9pbnRBcm4oKVxuICAgKiAtIC5pZkFjY2Vzc2VkVmlhTW91bnRUYXJnZXQoKVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWZzL2xhdGVzdC91Zy9lZnMtY2xpZW50LWF1dGhvcml6YXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ2xpZW50Um9vdEFjY2VzcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ2xpZW50Um9vdEFjY2VzcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFsbG93IGFuIE5GUyBjbGllbnQgd3JpdGUtYWNjZXNzIHRvIGEgZmlsZSBzeXN0ZW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkFjY2Vzc1BvaW50QXJuKClcbiAgICogLSAuaWZBY2Nlc3NlZFZpYU1vdW50VGFyZ2V0KClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvZWZzLWNsaWVudC1hdXRob3JpemF0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0NsaWVudFdyaXRlKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDbGllbnRXcml0ZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhbiBhY2Nlc3MgcG9pbnQgZm9yIHRoZSBzcGVjaWZpZWQgZmlsZSBzeXN0ZW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKlxuICAgKiBEZXBlbmRlbnQgYWN0aW9uczpcbiAgICogLSBlbGFzdGljZmlsZXN5c3RlbTpUYWdSZXNvdXJjZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWZzL2xhdGVzdC91Zy9BUElfQ3JlYXRlQWNjZXNzUG9pbnQuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlQWNjZXNzUG9pbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0NyZWF0ZUFjY2Vzc1BvaW50Jyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gY3JlYXRlIGEgbmV3LCBlbXB0eSBmaWxlIHN5c3RlbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVxdWVzdFRhZygpXG4gICAqIC0gLmlmQXdzVGFnS2V5cygpXG4gICAqIC0gLmlmRW5jcnlwdGVkKClcbiAgICpcbiAgICogRGVwZW5kZW50IGFjdGlvbnM6XG4gICAqIC0gZWxhc3RpY2ZpbGVzeXN0ZW06VGFnUmVzb3VyY2VcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvQVBJX0NyZWF0ZUZpbGVTeXN0ZW0uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlRmlsZVN5c3RlbSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlRmlsZVN5c3RlbScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBhIG1vdW50IHRhcmdldCBmb3IgYSBmaWxlIHN5c3RlbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL0FQSV9DcmVhdGVNb3VudFRhcmdldC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9DcmVhdGVNb3VudFRhcmdldCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlTW91bnRUYXJnZXQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgYSBuZXcgcmVwbGljYXRpb24gY29uZmlndXJhdGlvblxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL0FQSV9DcmVhdGVSZXBsaWNhdGlvbkNvbmZpZ3VyYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlUmVwbGljYXRpb25Db25maWd1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdDcmVhdGVSZXBsaWNhdGlvbkNvbmZpZ3VyYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBjcmVhdGUgb3Igb3ZlcndyaXRlIHRhZ3MgYXNzb2NpYXRlZCB3aXRoIGEgZmlsZSBzeXN0ZW07IGRlcHJlY2F0ZWQsIHNlZSBUYWdSZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXF1ZXN0VGFnKClcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvQVBJX0NyZWF0ZVRhZ3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvQ3JlYXRlVGFncygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnQ3JlYXRlVGFncycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSB0aGUgc3BlY2lmaWVkIGFjY2VzcyBwb2ludFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL0FQSV9EZWxldGVBY2Nlc3NQb2ludC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVBY2Nlc3NQb2ludCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlQWNjZXNzUG9pbnQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgYSBmaWxlIHN5c3RlbSwgcGVybWFuZW50bHkgc2V2ZXJpbmcgYWNjZXNzIHRvIGl0cyBjb250ZW50c1xuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL0FQSV9EZWxldGVGaWxlU3lzdGVtLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0RlbGV0ZUZpbGVTeXN0ZW0oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZUZpbGVTeXN0ZW0nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgdGhlIHJlc291cmNlLWxldmVsIHBvbGljeSBmb3IgYSBmaWxlIHN5c3RlbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFBlcm1pc3Npb25zIG1hbmFnZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvQVBJX0RlbGV0ZUZpbGVTeXN0ZW1Qb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlRmlsZVN5c3RlbVBvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlRmlsZVN5c3RlbVBvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSB0aGUgc3BlY2lmaWVkIG1vdW50IHRhcmdldFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL0FQSV9EZWxldGVNb3VudFRhcmdldC5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVNb3VudFRhcmdldCgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlTW91bnRUYXJnZXQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgYSByZXBsaWNhdGlvbiBjb25maWd1cmF0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvQVBJX0RlbGV0ZVJlcGxpY2F0aW9uQ29uZmlndXJhdGlvbi5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZWxldGVSZXBsaWNhdGlvbkNvbmZpZ3VyYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0RlbGV0ZVJlcGxpY2F0aW9uQ29uZmlndXJhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGRlbGV0ZSB0aGUgc3BlY2lmaWVkIHRhZ3MgZnJvbSBhIGZpbGUgc3lzdGVtOyBkZXByZWNhdGVkLCBzZWUgVW50YWdSZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvQVBJX0RlbGV0ZVRhZ3MuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVsZXRlVGFncygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVsZXRlVGFncycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHZpZXcgdGhlIGRlc2NyaXB0aW9ucyBvZiBBbWF6b24gRUZTIGFjY2VzcyBwb2ludHNcbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBMaXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL0FQSV9EZXNjcmliZUFjY2Vzc1BvaW50cy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUFjY2Vzc1BvaW50cygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVBY2Nlc3NQb2ludHMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB2aWV3IHRoZSBhY2NvdW50IHByZWZlcmVuY2VzIGluIGVmZmVjdCBmb3IgYW4gYWNjb3VudFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IExpc3RcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvQVBJX0Rlc2NyaWJlQWNjb3VudFByZWZlcmVuY2VzLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlQWNjb3VudFByZWZlcmVuY2VzKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUFjY291bnRQcmVmZXJlbmNlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHZpZXcgdGhlIEJhY2t1cFBvbGljeSBvYmplY3QgZm9yIGFuIEFtYXpvbiBFRlMgZmlsZSBzeXN0ZW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL0FQSV9EZXNjcmliZUJhY2t1cFBvbGljeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUJhY2t1cFBvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVCYWNrdXBQb2xpY3knKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB2aWV3IHRoZSByZXNvdXJjZS1sZXZlbCBwb2xpY3kgZm9yIGFuIEFtYXpvbiBFRlMgZmlsZSBzeXN0ZW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL0FQSV9EZXNjcmliZUZpbGVTeXN0ZW1Qb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVGaWxlU3lzdGVtUG9saWN5KCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUZpbGVTeXN0ZW1Qb2xpY3knKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB2aWV3IHRoZSBkZXNjcmlwdGlvbiBvZiBhbiBBbWF6b24gRUZTIGZpbGUgc3lzdGVtIHNwZWNpZmllZCBieSBmaWxlIHN5c3RlbSBDcmVhdGlvblRva2VuIG9yIEZpbGVTeXN0ZW1JZDsgb3IgdG8gdmlldyB0aGUgZGVzY3JpcHRpb24gb2YgYWxsIGZpbGUgc3lzdGVtcyBvd25lZCBieSB0aGUgY2FsbGVyJ3MgQVdTIGFjY291bnQgaW4gdGhlIEFXUyByZWdpb24gb2YgdGhlIGVuZHBvaW50IHRoYXQgaXMgYmVpbmcgY2FsbGVkXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWZzL2xhdGVzdC91Zy9BUElfRGVzY3JpYmVGaWxlU3lzdGVtcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZUZpbGVTeXN0ZW1zKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUZpbGVTeXN0ZW1zJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdmlldyB0aGUgTGlmZWN5Y2xlQ29uZmlndXJhdGlvbiBvYmplY3QgZm9yIGFuIEFtYXpvbiBFRlMgZmlsZSBzeXN0ZW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBSZWFkXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL0FQSV9EZXNjcmliZUxpZmVjeWNsZUNvbmZpZ3VyYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVMaWZlY3ljbGVDb25maWd1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdEZXNjcmliZUxpZmVjeWNsZUNvbmZpZ3VyYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB2aWV3IHRoZSBzZWN1cml0eSBncm91cHMgaW4gZWZmZWN0IGZvciBhIG1vdW50IHRhcmdldFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvQVBJX0Rlc2NyaWJlTW91bnRUYXJnZXRTZWN1cml0eUdyb3Vwcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZU1vdW50VGFyZ2V0U2VjdXJpdHlHcm91cHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlTW91bnRUYXJnZXRTZWN1cml0eUdyb3VwcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHZpZXcgdGhlIGRlc2NyaXB0aW9ucyBvZiBhbGwgbW91bnQgdGFyZ2V0cywgb3IgYSBzcGVjaWZpYyBtb3VudCB0YXJnZXQsIGZvciBhIGZpbGUgc3lzdGVtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWZzL2xhdGVzdC91Zy9BUElfRGVzY3JpYmVNb3VudFRhcmdldHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvRGVzY3JpYmVNb3VudFRhcmdldHMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlTW91bnRUYXJnZXRzJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdmlldyB0aGUgZGVzY3JpcHRpb24gb2YgYW4gQW1hem9uIEVGUyByZXBsaWNhdGlvbiBjb25maWd1cmF0aW9uIHNwZWNpZmllZCBieSBGaWxlU3lzdGVtSWQ7IG9yIHRvIHZpZXcgdGhlIGRlc2NyaXB0aW9uIG9mIGFsbCByZXBsaWNhdGlvbiBjb25maWd1cmF0aW9ucyBvd25lZCBieSB0aGUgY2FsbGVyJ3MgQVdTIGFjY291bnQgaW4gdGhlIEFXUyByZWdpb24gb2YgdGhlIGVuZHBvaW50IHRoYXQgaXMgYmVpbmcgY2FsbGVkXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogTGlzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWZzL2xhdGVzdC91Zy9BUElfRGVzY3JpYmVSZXBsaWNhdGlvbkNvbmZpZ3VyYXRpb25zLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0Rlc2NyaWJlUmVwbGljYXRpb25Db25maWd1cmF0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnRGVzY3JpYmVSZXBsaWNhdGlvbkNvbmZpZ3VyYXRpb25zJyk7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHBlcm1pc3Npb24gdG8gdmlldyB0aGUgdGFncyBhc3NvY2lhdGVkIHdpdGggYSBmaWxlIHN5c3RlbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvQVBJX0Rlc2NyaWJlVGFncy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9EZXNjcmliZVRhZ3MoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ0Rlc2NyaWJlVGFncycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHZpZXcgdGhlIHRhZ3MgYXNzb2NpYXRlZCB3aXRoIHRoZSBzcGVjaWZpZWQgQW1hem9uIEVGUyByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFJlYWRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvQVBJX0xpc3RUYWdzRm9yUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTGlzdFRhZ3NGb3JSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTGlzdFRhZ3NGb3JSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIG1vZGlmeSB0aGUgc2V0IG9mIHNlY3VyaXR5IGdyb3VwcyBpbiBlZmZlY3QgZm9yIGEgbW91bnQgdGFyZ2V0XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvQVBJX01vZGlmeU1vdW50VGFyZ2V0U2VjdXJpdHlHcm91cHMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvTW9kaWZ5TW91bnRUYXJnZXRTZWN1cml0eUdyb3VwcygpIHtcbiAgICByZXR1cm4gdGhpcy50bygnTW9kaWZ5TW91bnRUYXJnZXRTZWN1cml0eUdyb3VwcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHNldCB0aGUgYWNjb3VudCBwcmVmZXJlbmNlcyBvZiBhbiBhY2NvdW50XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvQVBJX1B1dEFjY291bnRQcmVmZXJlbmNlcy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9QdXRBY2NvdW50UHJlZmVyZW5jZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1B1dEFjY291bnRQcmVmZXJlbmNlcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGVuYWJsZSBvciBkaXNhYmxlIGF1dG9tYXRpYyBiYWNrdXBzIHdpdGggQVdTIEJhY2t1cCBieSBjcmVhdGluZyBhIG5ldyBCYWNrdXBQb2xpY3kgb2JqZWN0XG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvQVBJX1B1dEJhY2t1cFBvbGljeS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9QdXRCYWNrdXBQb2xpY3koKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1B1dEJhY2t1cFBvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGFwcGx5IGEgcmVzb3VyY2UtbGV2ZWwgcG9saWN5IHRoYXQgZGVmaW5lcyB0aGUgYWN0aW9ucyBhbGxvd2VkIG9yIGRlbmllZCBmcm9tIGdpdmVuIGFjdG9ycyBmb3IgdGhlIHNwZWNpZmllZCBmaWxlIHN5c3RlbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFBlcm1pc3Npb25zIG1hbmFnZW1lbnRcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvQVBJX1B1dEZpbGVTeXN0ZW1Qb2xpY3kuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUHV0RmlsZVN5c3RlbVBvbGljeSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUHV0RmlsZVN5c3RlbVBvbGljeScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGVuYWJsZSBsaWZlY3ljbGUgbWFuYWdlbWVudCBieSBjcmVhdGluZyBhIG5ldyBMaWZlY3ljbGVDb25maWd1cmF0aW9uIG9iamVjdFxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL0FQSV9QdXRMaWZlY3ljbGVDb25maWd1cmF0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1B1dExpZmVjeWNsZUNvbmZpZ3VyYXRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1B1dExpZmVjeWNsZUNvbmZpZ3VyYXRpb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZWFkIGZpbGUgc3lzdGVtIGRhdGEgZm9yIHJlcGxpY2F0aW9uXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogUmVhZFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWZzL2xhdGVzdC91Zy9lZnMtcmVwbGljYXRpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUmVwbGljYXRpb25SZWFkKCkge1xuICAgIHJldHVybiB0aGlzLnRvKCdSZXBsaWNhdGlvblJlYWQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byByZXBsaWNhdGUgZGF0YSB0byBhIGZpbGUgc3lzdGVtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvZWZzLXJlcGxpY2F0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1JlcGxpY2F0aW9uV3JpdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1JlcGxpY2F0aW9uV3JpdGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBzdGFydCBhIHJlc3RvcmUgam9iIGZvciBhIGJhY2t1cCBvZiBhIGZpbGUgc3lzdGVtXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogV3JpdGVcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvZWZzLWJhY2t1cC1zb2x1dGlvbnMuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvUmVzdG9yZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnUmVzdG9yZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIGNyZWF0ZSBvciBvdmVyd3JpdGUgdGFncyBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBBbWF6b24gRUZTIHJlc291cmNlXG4gICAqXG4gICAqIEFjY2VzcyBMZXZlbDogVGFnZ2luZ1xuICAgKlxuICAgKiBQb3NzaWJsZSBjb25kaXRpb25zOlxuICAgKiAtIC5pZkF3c1JlcXVlc3RUYWcoKVxuICAgKiAtIC5pZkF3c1RhZ0tleXMoKVxuICAgKiAtIC5pZkNyZWF0ZUFjdGlvbigpXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL0FQSV9UYWdSZXNvdXJjZS5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9UYWdSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVGFnUmVzb3VyY2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byBkZWxldGUgdGhlIHNwZWNpZmllZCB0YWdzIGZyb20gYW4gQW1hem9uIEVGUyByZXNvdXJjZVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFRhZ2dpbmdcbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NUYWdLZXlzKClcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvQVBJX1VudGFnUmVzb3VyY2UuaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVW50YWdSZXNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpcy50bygnVW50YWdSZXNvdXJjZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBwZXJtaXNzaW9uIHRvIHVwZGF0ZSB0aGUgdGhyb3VnaHB1dCBtb2RlIG9yIHRoZSBhbW91bnQgb2YgcHJvdmlzaW9uZWQgdGhyb3VnaHB1dCBvZiBhbiBleGlzdGluZyBmaWxlIHN5c3RlbVxuICAgKlxuICAgKiBBY2Nlc3MgTGV2ZWw6IFdyaXRlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL0FQSV9VcGRhdGVGaWxlU3lzdGVtLmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b1VwZGF0ZUZpbGVTeXN0ZW0oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZUZpbGVTeXN0ZW0nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgcGVybWlzc2lvbiB0byB1cGRhdGUgdGhlIGZpbGUgc3lzdGVtIHByb3RlY3Rpb24gb2YgYW4gZXhpc3RpbmcgZmlsZSBzeXN0ZW1cbiAgICpcbiAgICogQWNjZXNzIExldmVsOiBXcml0ZVxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWZzL2xhdGVzdC91Zy9BUElfVXBkYXRlRmlsZVN5c3RlbVByb3RlY3Rpb24uaHRtbFxuICAgKi9cbiAgcHVibGljIHRvVXBkYXRlRmlsZVN5c3RlbVByb3RlY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudG8oJ1VwZGF0ZUZpbGVTeXN0ZW1Qcm90ZWN0aW9uJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWNjZXNzTGV2ZWxMaXN0OiBBY2Nlc3NMZXZlbExpc3QgPSB7XG4gICAgV3JpdGU6IFtcbiAgICAgICdCYWNrdXAnLFxuICAgICAgJ0NsaWVudFJvb3RBY2Nlc3MnLFxuICAgICAgJ0NsaWVudFdyaXRlJyxcbiAgICAgICdDcmVhdGVBY2Nlc3NQb2ludCcsXG4gICAgICAnQ3JlYXRlRmlsZVN5c3RlbScsXG4gICAgICAnQ3JlYXRlTW91bnRUYXJnZXQnLFxuICAgICAgJ0NyZWF0ZVJlcGxpY2F0aW9uQ29uZmlndXJhdGlvbicsXG4gICAgICAnRGVsZXRlQWNjZXNzUG9pbnQnLFxuICAgICAgJ0RlbGV0ZUZpbGVTeXN0ZW0nLFxuICAgICAgJ0RlbGV0ZU1vdW50VGFyZ2V0JyxcbiAgICAgICdEZWxldGVSZXBsaWNhdGlvbkNvbmZpZ3VyYXRpb24nLFxuICAgICAgJ01vZGlmeU1vdW50VGFyZ2V0U2VjdXJpdHlHcm91cHMnLFxuICAgICAgJ1B1dEFjY291bnRQcmVmZXJlbmNlcycsXG4gICAgICAnUHV0QmFja3VwUG9saWN5JyxcbiAgICAgICdQdXRMaWZlY3ljbGVDb25maWd1cmF0aW9uJyxcbiAgICAgICdSZXBsaWNhdGlvbldyaXRlJyxcbiAgICAgICdSZXN0b3JlJyxcbiAgICAgICdVcGRhdGVGaWxlU3lzdGVtJyxcbiAgICAgICdVcGRhdGVGaWxlU3lzdGVtUHJvdGVjdGlvbidcbiAgICBdLFxuICAgIFJlYWQ6IFtcbiAgICAgICdDbGllbnRNb3VudCcsXG4gICAgICAnRGVzY3JpYmVCYWNrdXBQb2xpY3knLFxuICAgICAgJ0Rlc2NyaWJlRmlsZVN5c3RlbVBvbGljeScsXG4gICAgICAnRGVzY3JpYmVMaWZlY3ljbGVDb25maWd1cmF0aW9uJyxcbiAgICAgICdEZXNjcmliZU1vdW50VGFyZ2V0U2VjdXJpdHlHcm91cHMnLFxuICAgICAgJ0Rlc2NyaWJlTW91bnRUYXJnZXRzJyxcbiAgICAgICdEZXNjcmliZVRhZ3MnLFxuICAgICAgJ0xpc3RUYWdzRm9yUmVzb3VyY2UnLFxuICAgICAgJ1JlcGxpY2F0aW9uUmVhZCdcbiAgICBdLFxuICAgIFRhZ2dpbmc6IFtcbiAgICAgICdDcmVhdGVUYWdzJyxcbiAgICAgICdEZWxldGVUYWdzJyxcbiAgICAgICdUYWdSZXNvdXJjZScsXG4gICAgICAnVW50YWdSZXNvdXJjZSdcbiAgICBdLFxuICAgICdQZXJtaXNzaW9ucyBtYW5hZ2VtZW50JzogW1xuICAgICAgJ0RlbGV0ZUZpbGVTeXN0ZW1Qb2xpY3knLFxuICAgICAgJ1B1dEZpbGVTeXN0ZW1Qb2xpY3knXG4gICAgXSxcbiAgICBMaXN0OiBbXG4gICAgICAnRGVzY3JpYmVBY2Nlc3NQb2ludHMnLFxuICAgICAgJ0Rlc2NyaWJlQWNjb3VudFByZWZlcmVuY2VzJyxcbiAgICAgICdEZXNjcmliZUZpbGVTeXN0ZW1zJyxcbiAgICAgICdEZXNjcmliZVJlcGxpY2F0aW9uQ29uZmlndXJhdGlvbnMnXG4gICAgXVxuICB9O1xuXG4gIC8qKlxuICAgKiBBZGRzIGEgcmVzb3VyY2Ugb2YgdHlwZSBmaWxlLXN5c3RlbSB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL2NyZWF0aW5nLXVzaW5nLWNyZWF0ZS1mcy5odG1sXG4gICAqXG4gICAqIEBwYXJhbSBmaWxlU3lzdGVtSWQgLSBJZGVudGlmaWVyIGZvciB0aGUgZmlsZVN5c3RlbUlkLlxuICAgKiBAcGFyYW0gYWNjb3VudCAtIEFjY291bnQgb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIGFjY291bnQuXG4gICAqIEBwYXJhbSByZWdpb24gLSBSZWdpb24gb2YgdGhlIHJlc291cmNlOyBkZWZhdWx0cyB0byBgKmAsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHJlZ2lvbi5cbiAgICogQHBhcmFtIHBhcnRpdGlvbiAtIFBhcnRpdGlvbiBvZiB0aGUgQVdTIGFjY291bnQgW2F3cywgYXdzLWNuLCBhd3MtdXMtZ292XTsgZGVmYXVsdHMgdG8gYGF3c2AsIHVubGVzcyB1c2luZyB0aGUgQ0RLLCB3aGVyZSB0aGUgZGVmYXVsdCBpcyB0aGUgY3VycmVudCBTdGFjaydzIHBhcnRpdGlvbi5cbiAgICpcbiAgICogUG9zc2libGUgY29uZGl0aW9uczpcbiAgICogLSAuaWZBd3NSZXNvdXJjZVRhZygpXG4gICAqL1xuICBwdWJsaWMgb25GaWxlU3lzdGVtKGZpbGVTeXN0ZW1JZDogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OmVsYXN0aWNmaWxlc3lzdGVtOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTpmaWxlLXN5c3RlbS8keyBmaWxlU3lzdGVtSWQgfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXNvdXJjZSBvZiB0eXBlIGFjY2Vzcy1wb2ludCB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL2Vmcy1hY2Nlc3MtcG9pbnRzLmh0bWxcbiAgICpcbiAgICogQHBhcmFtIGFjY2Vzc1BvaW50SWQgLSBJZGVudGlmaWVyIGZvciB0aGUgYWNjZXNzUG9pbnRJZC5cbiAgICogQHBhcmFtIGFjY291bnQgLSBBY2NvdW50IG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBhY2NvdW50LlxuICAgKiBAcGFyYW0gcmVnaW9uIC0gUmVnaW9uIG9mIHRoZSByZXNvdXJjZTsgZGVmYXVsdHMgdG8gYCpgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyByZWdpb24uXG4gICAqIEBwYXJhbSBwYXJ0aXRpb24gLSBQYXJ0aXRpb24gb2YgdGhlIEFXUyBhY2NvdW50IFthd3MsIGF3cy1jbiwgYXdzLXVzLWdvdl07IGRlZmF1bHRzIHRvIGBhd3NgLCB1bmxlc3MgdXNpbmcgdGhlIENESywgd2hlcmUgdGhlIGRlZmF1bHQgaXMgdGhlIGN1cnJlbnQgU3RhY2sncyBwYXJ0aXRpb24uXG4gICAqXG4gICAqIFBvc3NpYmxlIGNvbmRpdGlvbnM6XG4gICAqIC0gLmlmQXdzUmVzb3VyY2VUYWcoKVxuICAgKi9cbiAgcHVibGljIG9uQWNjZXNzUG9pbnQoYWNjZXNzUG9pbnRJZDogc3RyaW5nLCBhY2NvdW50Pzogc3RyaW5nLCByZWdpb24/OiBzdHJpbmcsIHBhcnRpdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm9uKGBhcm46JHsgcGFydGl0aW9uID8/IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OmVsYXN0aWNmaWxlc3lzdGVtOiR7IHJlZ2lvbiA/PyB0aGlzLmRlZmF1bHRSZWdpb24gfTokeyBhY2NvdW50ID8/IHRoaXMuZGVmYXVsdEFjY291bnQgfTphY2Nlc3MtcG9pbnQvJHsgYWNjZXNzUG9pbnRJZCB9YCk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgYSB0YWcga2V5IGFuZCB2YWx1ZSBwYWlyIHRoYXQgaXMgYWxsb3dlZCBpbiB0aGUgcmVxdWVzdFxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2NvbmRpdGlvbi1rZXlzLmh0bWwjY29uZGl0aW9uLWtleXMtcmVxdWVzdHRhZ1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ3JlYXRlQWNjZXNzUG9pbnQoKVxuICAgKiAtIC50b0NyZWF0ZUZpbGVTeXN0ZW0oKVxuICAgKiAtIC50b0NyZWF0ZVRhZ3MoKVxuICAgKiAtIC50b1RhZ1Jlc291cmNlKClcbiAgICpcbiAgICogQHBhcmFtIHRhZ0tleSBUaGUgdGFnIGtleSB0byBjaGVja1xuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkF3c1JlcXVlc3RUYWcodGFnS2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBhd3M6UmVxdWVzdFRhZy8keyB0YWdLZXkgfWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IGEgdGFnIGtleSBhbmQgdmFsdWUgcGFpciBvZiBhIHJlc291cmNlXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy1yZXNvdXJjZXRhZ1xuICAgKlxuICAgKiBBcHBsaWVzIHRvIHJlc291cmNlIHR5cGVzOlxuICAgKiAtIGZpbGUtc3lzdGVtXG4gICAqIC0gYWNjZXNzLXBvaW50XG4gICAqXG4gICAqIEBwYXJhbSB0YWdLZXkgVGhlIHRhZyBrZXkgdG8gY2hlY2tcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZShzKSB0byBjaGVja1xuICAgKiBAcGFyYW0gb3BlcmF0b3IgV29ya3Mgd2l0aCBbc3RyaW5nIG9wZXJhdG9yc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9wb2xpY2llc19lbGVtZW50c19jb25kaXRpb25fb3BlcmF0b3JzLmh0bWwjQ29uZGl0aW9uc19TdHJpbmcpLiAqKkRlZmF1bHQ6KiogYFN0cmluZ0xpa2VgXG4gICAqL1xuICBwdWJsaWMgaWZBd3NSZXNvdXJjZVRhZyh0YWdLZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpSZXNvdXJjZVRhZy8keyB0YWdLZXkgfWAsIHZhbHVlLCBvcGVyYXRvciA/PyAnU3RyaW5nTGlrZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IGEgbGlzdCBvZiB0YWcga2V5cyB0aGF0IGFyZSBhbGxvd2VkIGluIHRoZSByZXF1ZXN0XG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfY29uZGl0aW9uLWtleXMuaHRtbCNjb25kaXRpb24ta2V5cy10YWdrZXlzXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9DcmVhdGVBY2Nlc3NQb2ludCgpXG4gICAqIC0gLnRvQ3JlYXRlRmlsZVN5c3RlbSgpXG4gICAqIC0gLnRvQ3JlYXRlVGFncygpXG4gICAqIC0gLnRvRGVsZXRlVGFncygpXG4gICAqIC0gLnRvVGFnUmVzb3VyY2UoKVxuICAgKiAtIC50b1VudGFnUmVzb3VyY2UoKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlKHMpIHRvIGNoZWNrXG4gICAqIEBwYXJhbSBvcGVyYXRvciBXb3JrcyB3aXRoIFtzdHJpbmcgb3BlcmF0b3JzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX3BvbGljaWVzX2VsZW1lbnRzX2NvbmRpdGlvbl9vcGVyYXRvcnMuaHRtbCNDb25kaXRpb25zX1N0cmluZykuICoqRGVmYXVsdDoqKiBgU3RyaW5nTGlrZWBcbiAgICovXG4gIHB1YmxpYyBpZkF3c1RhZ0tleXModmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYGF3czpUYWdLZXlzYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdTdHJpbmdMaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgdGhlIEFSTiBvZiB0aGUgYWNjZXNzIHBvaW50IHVzZWQgdG8gbW91bnQgdGhlIGZpbGUgc3lzdGVtXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL2Vmcy1hY2Nlc3MtcG9pbnRzLmh0bWxcbiAgICpcbiAgICogQXBwbGllcyB0byBhY3Rpb25zOlxuICAgKiAtIC50b0NsaWVudE1vdW50KClcbiAgICogLSAudG9DbGllbnRSb290QWNjZXNzKClcbiAgICogLSAudG9DbGllbnRXcml0ZSgpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW2FybiBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfQVJOKS4gKipEZWZhdWx0OioqIGBBcm5MaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQWNjZXNzUG9pbnRBcm4odmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdLCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaWYoYEFjY2Vzc1BvaW50QXJuYCwgdmFsdWUsIG9wZXJhdG9yID8/ICdBcm5MaWtlJyk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhY2Nlc3MgYnkgd2hldGhlciB0aGUgZmlsZSBzeXN0ZW0gaXMgYWNjZXNzZWQgdmlhIG1vdW50IHRhcmdldHNcbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vmcy9sYXRlc3QvdWcvbW91bnRpbmctZnMuaHRtbFxuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ2xpZW50TW91bnQoKVxuICAgKiAtIC50b0NsaWVudFJvb3RBY2Nlc3MoKVxuICAgKiAtIC50b0NsaWVudFdyaXRlKClcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCBvciBgZmFsc2VgLiAqKkRlZmF1bHQ6KiogYHRydWVgXG4gICAqL1xuICBwdWJsaWMgaWZBY2Nlc3NlZFZpYU1vdW50VGFyZ2V0KHZhbHVlPzogYm9vbGVhbikge1xuICAgIHJldHVybiB0aGlzLmlmKGBBY2Nlc3NlZFZpYU1vdW50VGFyZ2V0YCwgKHR5cGVvZiB2YWx1ZSAhPT0gJ3VuZGVmaW5lZCcgPyB2YWx1ZSA6IHRydWUpLCAnQm9vbCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbHRlcnMgYWNjZXNzIGJ5IHRoZSBuYW1lIG9mIGEgcmVzb3VyY2UtY3JlYXRpbmcgQVBJIGFjdGlvblxuICAgKlxuICAgKiBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWZzL2xhdGVzdC91Zy91c2luZy10YWdzLWVmcy5odG1sXG4gICAqXG4gICAqIEFwcGxpZXMgdG8gYWN0aW9uczpcbiAgICogLSAudG9UYWdSZXNvdXJjZSgpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUocykgdG8gY2hlY2tcbiAgICogQHBhcmFtIG9wZXJhdG9yIFdvcmtzIHdpdGggW3N0cmluZyBvcGVyYXRvcnNdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfY29uZGl0aW9uX29wZXJhdG9ycy5odG1sI0NvbmRpdGlvbnNfU3RyaW5nKS4gKipEZWZhdWx0OioqIGBTdHJpbmdMaWtlYFxuICAgKi9cbiAgcHVibGljIGlmQ3JlYXRlQWN0aW9uKHZhbHVlOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3BlcmF0b3I/OiBPcGVyYXRvciB8IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmlmKGBDcmVhdGVBY3Rpb25gLCB2YWx1ZSwgb3BlcmF0b3IgPz8gJ1N0cmluZ0xpa2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJzIGFjY2VzcyBieSB3aGV0aGVyIHVzZXJzIGNhbiBjcmVhdGUgb25seSBlbmNyeXB0ZWQgb3IgdW5lbmNyeXB0ZWQgZmlsZSBzeXN0ZW1zXG4gICAqXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9lZnMvbGF0ZXN0L3VnL2VuY3J5cHRpb24uaHRtbFxuICAgKlxuICAgKiBBcHBsaWVzIHRvIGFjdGlvbnM6XG4gICAqIC0gLnRvQ3JlYXRlRmlsZVN5c3RlbSgpXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBgdHJ1ZWAgb3IgYGZhbHNlYC4gKipEZWZhdWx0OioqIGB0cnVlYFxuICAgKi9cbiAgcHVibGljIGlmRW5jcnlwdGVkKHZhbHVlPzogYm9vbGVhbikge1xuICAgIHJldHVybiB0aGlzLmlmKGBFbmNyeXB0ZWRgLCAodHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJyA/IHZhbHVlIDogdHJ1ZSksICdCb29sJyk7XG4gIH1cblxuICAvKipcbiAgICogU3RhdGVtZW50IHByb3ZpZGVyIGZvciBzZXJ2aWNlIFtlbGFzdGljZmlsZXN5c3RlbV0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3NlcnZpY2UtYXV0aG9yaXphdGlvbi9sYXRlc3QvcmVmZXJlbmNlL2xpc3RfYW1hem9uZWxhc3RpY2ZpbGVzeXN0ZW0uaHRtbCkuXG4gICAqXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihwcm9wcz86IGlhbS5Qb2xpY3lTdGF0ZW1lbnRQcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgfVxufVxuIl19