UNPKG

@aws-cdk/aws-ssm

Version:

The CDK Construct Library for AWS::SSM

382 lines 52.6 kB
"use strict"; var _a, _b; Object.defineProperty(exports, "__esModule", { value: true }); exports.StringListParameter = exports.StringParameter = exports.ParameterTier = exports.ParameterDataType = exports.ParameterType = void 0; const jsiiDeprecationWarnings = require("../.warnings.jsii.js"); const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const iam = require("@aws-cdk/aws-iam"); const cxschema = require("@aws-cdk/cloud-assembly-schema"); const core_1 = require("@aws-cdk/core"); const ssm = require("./ssm.generated"); const util_1 = require("./util"); /** * Basic features shared across all types of SSM Parameters. */ class ParameterBase extends core_1.Resource { grantRead(grantee) { if (this.encryptionKey) { this.encryptionKey.grantDecrypt(grantee); } return iam.Grant.addToPrincipal({ grantee, actions: [ 'ssm:DescribeParameters', 'ssm:GetParameters', 'ssm:GetParameter', 'ssm:GetParameterHistory', ], resourceArns: [this.parameterArn], }); } grantWrite(grantee) { if (this.encryptionKey) { this.encryptionKey.grantEncrypt(grantee); } return iam.Grant.addToPrincipal({ grantee, actions: ['ssm:PutParameter'], resourceArns: [this.parameterArn], }); } } /** * SSM parameter type */ var ParameterType; (function (ParameterType) { /** * String */ ParameterType["STRING"] = "String"; /** * Secure String * * Parameter Store uses an AWS Key Management Service (KMS) customer master key (CMK) to encrypt the parameter value. * Parameters of type SecureString cannot be created directly from a CDK application. */ ParameterType["SECURE_STRING"] = "SecureString"; /** * String List */ ParameterType["STRING_LIST"] = "StringList"; /** * An Amazon EC2 image ID, such as ami-0ff8a91507f77f867 */ ParameterType["AWS_EC2_IMAGE_ID"] = "AWS::EC2::Image::Id"; })(ParameterType = exports.ParameterType || (exports.ParameterType = {})); /** * SSM parameter data type */ var ParameterDataType; (function (ParameterDataType) { /** * Text */ ParameterDataType["TEXT"] = "text"; /** * Aws Ec2 Image */ ParameterDataType["AWS_EC2_IMAGE"] = "aws:ec2:image"; })(ParameterDataType = exports.ParameterDataType || (exports.ParameterDataType = {})); /** * SSM parameter tier */ var ParameterTier; (function (ParameterTier) { /** * String */ ParameterTier["ADVANCED"] = "Advanced"; /** * String */ ParameterTier["INTELLIGENT_TIERING"] = "Intelligent-Tiering"; /** * String */ ParameterTier["STANDARD"] = "Standard"; })(ParameterTier = exports.ParameterTier || (exports.ParameterTier = {})); /** * Creates a new String SSM Parameter. * @resource AWS::SSM::Parameter */ class StringParameter extends ParameterBase { constructor(scope, id, props) { super(scope, id, { physicalName: props.parameterName, }); try { jsiiDeprecationWarnings._aws_cdk_aws_ssm_StringParameterProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, StringParameter); } throw error; } if (props.allowedPattern) { _assertValidValue(props.stringValue, props.allowedPattern); } validateParameterName(this.physicalName); if (props.description && props.description?.length > 1024) { throw new Error('Description cannot be longer than 1024 characters.'); } if (props.type && props.type === ParameterType.AWS_EC2_IMAGE_ID) { throw new Error('The type must either be ParameterType.STRING or ParameterType.STRING_LIST. Did you mean to set dataType: ParameterDataType.AWS_EC2_IMAGE instead?'); } const resource = new ssm.CfnParameter(this, 'Resource', { allowedPattern: props.allowedPattern, description: props.description, name: this.physicalName, tier: props.tier, type: props.type || ParameterType.STRING, dataType: props.dataType, value: props.stringValue, }); this.parameterName = this.getResourceNameAttribute(resource.ref); this.parameterArn = util_1.arnForParameterName(this, this.parameterName, { physicalName: props.parameterName || util_1.AUTOGEN_MARKER, simpleName: props.simpleName, }); this.parameterType = resource.attrType; this.stringValue = resource.attrValue; } /** * Imports an external string parameter by name. */ static fromStringParameterName(scope, id, stringParameterName) { return this.fromStringParameterAttributes(scope, id, { parameterName: stringParameterName }); } /** * Imports an external string parameter with name and optional version. */ static fromStringParameterAttributes(scope, id, attrs) { try { jsiiDeprecationWarnings._aws_cdk_aws_ssm_StringParameterAttributes(attrs); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.fromStringParameterAttributes); } throw error; } if (!attrs.parameterName) { throw new Error('parameterName cannot be an empty string'); } const type = attrs.type || ParameterType.STRING; const stringValue = attrs.version ? new core_1.CfnDynamicReference(core_1.CfnDynamicReferenceService.SSM, `${attrs.parameterName}:${core_1.Tokenization.stringifyNumber(attrs.version)}`).toString() : new core_1.CfnParameter(scope, `${id}.Parameter`, { type: `AWS::SSM::Parameter::Value<${type}>`, default: attrs.parameterName }).valueAsString; class Import extends ParameterBase { constructor() { super(...arguments); this.parameterName = attrs.parameterName; this.parameterArn = util_1.arnForParameterName(this, attrs.parameterName, { simpleName: attrs.simpleName }); this.parameterType = type; this.stringValue = stringValue; } } return new Import(scope, id); } /** * Imports a secure string parameter from the SSM parameter store. */ static fromSecureStringParameterAttributes(scope, id, attrs) { try { jsiiDeprecationWarnings._aws_cdk_aws_ssm_SecureStringParameterAttributes(attrs); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.fromSecureStringParameterAttributes); } throw error; } const version = attrs.version ? core_1.Tokenization.stringifyNumber(attrs.version) : ''; const stringValue = new core_1.CfnDynamicReference(core_1.CfnDynamicReferenceService.SSM_SECURE, `${attrs.parameterName}:${version}`).toString(); class Import extends ParameterBase { constructor() { super(...arguments); this.parameterName = attrs.parameterName; this.parameterArn = util_1.arnForParameterName(this, attrs.parameterName, { simpleName: attrs.simpleName }); this.parameterType = ParameterType.SECURE_STRING; this.stringValue = stringValue; this.encryptionKey = attrs.encryptionKey; } } return new Import(scope, id); } /** * Reads the value of an SSM parameter during synthesis through an * environmental context provider. * * Requires that the stack this scope is defined in will have explicit * account/region information. Otherwise, it will fail during synthesis. */ static valueFromLookup(scope, parameterName) { const value = core_1.ContextProvider.getValue(scope, { provider: cxschema.ContextProvider.SSM_PARAMETER_PROVIDER, props: { parameterName }, dummyValue: `dummy-value-for-${parameterName}`, }).value; return value; } /** * Returns a token that will resolve (during deployment) to the string value of an SSM string parameter. * @param scope Some scope within a stack * @param parameterName The name of the SSM parameter. * @param version The parameter version (recommended in order to ensure that the value won't change during deployment) */ static valueForStringParameter(scope, parameterName, version) { return StringParameter.valueForTypedStringParameter(scope, parameterName, ParameterType.STRING, version); } /** * Returns a token that will resolve (during deployment) to the string value of an SSM string parameter. * @param scope Some scope within a stack * @param parameterName The name of the SSM parameter. * @param type The type of the SSM parameter. * @param version The parameter version (recommended in order to ensure that the value won't change during deployment) */ static valueForTypedStringParameter(scope, parameterName, type = ParameterType.STRING, version) { try { jsiiDeprecationWarnings._aws_cdk_aws_ssm_ParameterType(type); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.valueForTypedStringParameter); } throw error; } const stack = core_1.Stack.of(scope); const id = makeIdentityForImportedValue(parameterName); const exists = stack.node.tryFindChild(id); if (exists) { return exists.stringValue; } return this.fromStringParameterAttributes(stack, id, { parameterName, version, type }).stringValue; } /** * Returns a token that will resolve (during deployment) * @param scope Some scope within a stack * @param parameterName The name of the SSM parameter * @param version The parameter version (required for secure strings) * @deprecated Use `SecretValue.ssmSecure()` instead, it will correctly type the imported value as a `SecretValue` and allow importing without version. */ static valueForSecureStringParameter(scope, parameterName, version) { try { jsiiDeprecationWarnings.print("@aws-cdk/aws-ssm.StringParameter#valueForSecureStringParameter", "Use `SecretValue.ssmSecure()` instead, it will correctly type the imported value as a `SecretValue` and allow importing without version."); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.valueForSecureStringParameter); } throw error; } const stack = core_1.Stack.of(scope); const id = makeIdentityForImportedValue(parameterName); const exists = stack.node.tryFindChild(id); if (exists) { return exists.stringValue; } return this.fromSecureStringParameterAttributes(stack, id, { parameterName, version }).stringValue; } } exports.StringParameter = StringParameter; _a = JSII_RTTI_SYMBOL_1; StringParameter[_a] = { fqn: "@aws-cdk/aws-ssm.StringParameter", version: "1.204.0" }; /** * Creates a new StringList SSM Parameter. * @resource AWS::SSM::Parameter */ class StringListParameter extends ParameterBase { constructor(scope, id, props) { super(scope, id, { physicalName: props.parameterName, }); try { jsiiDeprecationWarnings._aws_cdk_aws_ssm_StringListParameterProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, StringListParameter); } throw error; } if (props.stringListValue.find(str => !core_1.Token.isUnresolved(str) && str.indexOf(',') !== -1)) { throw new Error('Values of a StringList SSM Parameter cannot contain the \',\' character. Use a string parameter instead.'); } if (props.allowedPattern && !core_1.Token.isUnresolved(props.stringListValue)) { props.stringListValue.forEach(str => _assertValidValue(str, props.allowedPattern)); } validateParameterName(this.physicalName); if (props.description && props.description?.length > 1024) { throw new Error('Description cannot be longer than 1024 characters.'); } const resource = new ssm.CfnParameter(this, 'Resource', { allowedPattern: props.allowedPattern, description: props.description, name: this.physicalName, tier: props.tier, type: ParameterType.STRING_LIST, value: props.stringListValue.join(','), }); this.parameterName = this.getResourceNameAttribute(resource.ref); this.parameterArn = util_1.arnForParameterName(this, this.parameterName, { physicalName: props.parameterName || util_1.AUTOGEN_MARKER, simpleName: props.simpleName, }); this.parameterType = resource.attrType; this.stringListValue = core_1.Fn.split(',', resource.attrValue); } /** * Imports an external parameter of type string list. * Returns a token and should not be parsed. */ static fromStringListParameterName(scope, id, stringListParameterName) { class Import extends ParameterBase { constructor() { super(...arguments); this.parameterName = stringListParameterName; this.parameterArn = util_1.arnForParameterName(this, this.parameterName); this.parameterType = ParameterType.STRING_LIST; this.stringListValue = core_1.Fn.split(',', new core_1.CfnDynamicReference(core_1.CfnDynamicReferenceService.SSM, stringListParameterName).toString()); } } return new Import(scope, id); } } exports.StringListParameter = StringListParameter; _b = JSII_RTTI_SYMBOL_1; StringListParameter[_b] = { fqn: "@aws-cdk/aws-ssm.StringListParameter", version: "1.204.0" }; /** * Validates whether a supplied value conforms to the allowedPattern, granted neither is an unresolved token. * * @param value the value to be validated. * @param allowedPattern the regular expression to use for validation. * * @throws if the ``value`` does not conform to the ``allowedPattern`` and neither is an unresolved token (per * ``cdk.unresolved``). */ function _assertValidValue(value, allowedPattern) { if (core_1.Token.isUnresolved(value) || core_1.Token.isUnresolved(allowedPattern)) { // Unable to perform validations against unresolved tokens return; } if (!new RegExp(allowedPattern).test(value)) { throw new Error(`The supplied value (${value}) does not match the specified allowedPattern (${allowedPattern})`); } } function makeIdentityForImportedValue(parameterName) { return `SsmParameterValue:${parameterName}:C96584B6-F00A-464E-AD19-53AFF4B05118`; } function validateParameterName(parameterName) { if (core_1.Token.isUnresolved(parameterName)) { return; } if (parameterName.length > 2048) { throw new Error('name cannot be longer than 2048 characters.'); } if (!parameterName.match(/^[\/\w.-]+$/)) { throw new Error(`name must only contain letters, numbers, and the following 4 symbols .-_/; got ${parameterName}`); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyYW1ldGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicGFyYW1ldGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHdDQUF3QztBQUV4QywyREFBMkQ7QUFDM0Qsd0NBSXVCO0FBRXZCLHVDQUF1QztBQUN2QyxpQ0FBNkQ7QUFvSjdEOztHQUVHO0FBQ0gsTUFBZSxhQUFjLFNBQVEsZUFBUTtJQVlwQyxTQUFTLENBQUMsT0FBdUI7UUFDdEMsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ3RCLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQzFDO1FBQ0QsT0FBTyxHQUFHLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQztZQUM5QixPQUFPO1lBQ1AsT0FBTyxFQUFFO2dCQUNQLHdCQUF3QjtnQkFDeEIsbUJBQW1CO2dCQUNuQixrQkFBa0I7Z0JBQ2xCLHlCQUF5QjthQUMxQjtZQUNELFlBQVksRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUM7U0FDbEMsQ0FBQyxDQUFDO0tBQ0o7SUFFTSxVQUFVLENBQUMsT0FBdUI7UUFDdkMsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ3RCLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQzFDO1FBQ0QsT0FBTyxHQUFHLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQztZQUM5QixPQUFPO1lBQ1AsT0FBTyxFQUFFLENBQUMsa0JBQWtCLENBQUM7WUFDN0IsWUFBWSxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQztTQUNsQyxDQUFDLENBQUM7S0FDSjtDQUNGO0FBRUQ7O0dBRUc7QUFDSCxJQUFZLGFBb0JYO0FBcEJELFdBQVksYUFBYTtJQUN2Qjs7T0FFRztJQUNILGtDQUFpQixDQUFBO0lBQ2pCOzs7OztPQUtHO0lBQ0gsK0NBQThCLENBQUE7SUFDOUI7O09BRUc7SUFDSCwyQ0FBMEIsQ0FBQTtJ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b3J0ICogYXMga21zIGZyb20gJ0Bhd3MtY2RrL2F3cy1rbXMnO1xuaW1wb3J0ICogYXMgY3hzY2hlbWEgZnJvbSAnQGF3cy1jZGsvY2xvdWQtYXNzZW1ibHktc2NoZW1hJztcbmltcG9ydCB7XG4gIENmbkR5bmFtaWNSZWZlcmVuY2UsIENmbkR5bmFtaWNSZWZlcmVuY2VTZXJ2aWNlLCBDZm5QYXJhbWV0ZXIsXG4gIENvbnN0cnVjdCBhcyBDb21wYXRDb25zdHJ1Y3QsIENvbnRleHRQcm92aWRlciwgRm4sIElSZXNvdXJjZSwgUmVzb3VyY2UsIFN0YWNrLCBUb2tlbixcbiAgVG9rZW5pemF0aW9uLFxufSBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0ICogYXMgc3NtIGZyb20gJy4vc3NtLmdlbmVyYXRlZCc7XG5pbXBvcnQgeyBhcm5Gb3JQYXJhbWV0ZXJOYW1lLCBBVVRPR0VOX01BUktFUiB9IGZyb20gJy4vdXRpbCc7XG5cbi8qKlxuICogQW4gU1NNIFBhcmFtZXRlciByZWZlcmVuY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSVBhcmFtZXRlciBleHRlbmRzIElSZXNvdXJjZSB7XG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSBTU00gUGFyYW1ldGVyIHJlc291cmNlLlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBwYXJhbWV0ZXJBcm46IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIFNTTSBQYXJhbWV0ZXIgcmVzb3VyY2UuXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IHBhcmFtZXRlck5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHR5cGUgb2YgdGhlIFNTTSBQYXJhbWV0ZXIgcmVzb3VyY2UuXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IHBhcmFtZXRlclR5cGU6IHN0cmluZztcblxuICAvKipcbiAgICogR3JhbnRzIHJlYWQgKERlc2NyaWJlUGFyYW1ldGVyLCBHZXRQYXJhbWV0ZXIsIEdldFBhcmFtZXRlckhpc3RvcnkpIHBlcm1pc3Npb25zIG9uIHRoZSBTU00gUGFyYW1ldGVyLlxuICAgKlxuICAgKiBAcGFyYW0gZ3JhbnRlZSB0aGUgcm9sZSB0byBiZSBncmFudGVkIHJlYWQtb25seSBhY2Nlc3MgdG8gdGhlIHBhcmFtZXRlci5cbiAgICovXG4gIGdyYW50UmVhZChncmFudGVlOiBpYW0uSUdyYW50YWJsZSk6IGlhbS5HcmFudDtcblxuICAvKipcbiAgICogR3JhbnRzIHdyaXRlIChQdXRQYXJhbWV0ZXIpIHBlcm1pc3Npb25zIG9uIHRoZSBTU00gUGFyYW1ldGVyLlxuICAgKlxuICAgKiBAcGFyYW0gZ3JhbnRlZSB0aGUgcm9sZSB0byBiZSBncmFudGVkIHdyaXRlIGFjY2VzcyB0byB0aGUgcGFyYW1ldGVyLlxuICAgKi9cbiAgZ3JhbnRXcml0ZShncmFudGVlOiBpYW0uSUdyYW50YWJsZSk6IGlhbS5HcmFudDtcbn1cblxuLyoqXG4gKiBBIFN0cmluZyBTU00gUGFyYW1ldGVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIElTdHJpbmdQYXJhbWV0ZXIgZXh0ZW5kcyBJUGFyYW1ldGVyIHtcbiAgLyoqXG4gICAqIFRoZSBwYXJhbWV0ZXIgdmFsdWUuIFZhbHVlIG11c3Qgbm90IG5lc3QgYW5vdGhlciBwYXJhbWV0ZXIuIERvIG5vdCB1c2Uge3t9fSBpbiB0aGUgdmFsdWUuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGUgVmFsdWVcbiAgICovXG4gIHJlYWRvbmx5IHN0cmluZ1ZhbHVlOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSBTdHJpbmdMaXN0IFNTTSBQYXJhbWV0ZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSVN0cmluZ0xpc3RQYXJhbWV0ZXIgZXh0ZW5kcyBJUGFyYW1ldGVyIHtcbiAgLyoqXG4gICAqIFRoZSBwYXJhbWV0ZXIgdmFsdWUuIFZhbHVlIG11c3Qgbm90IG5lc3QgYW5vdGhlciBwYXJhbWV0ZXIuIERvIG5vdCB1c2Uge3t9fSBpbiB0aGUgdmFsdWUuIFZhbHVlcyBpbiB0aGUgYXJyYXlcbiAgICogY2Fubm90IGNvbnRhaW4gY29tbWFzIChgYCxgYCkuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGUgVmFsdWVcbiAgICovXG4gIHJlYWRvbmx5IHN0cmluZ0xpc3RWYWx1ZTogc3RyaW5nW107XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBuZWVkZWQgdG8gY3JlYXRlIGEgbmV3IFNTTSBQYXJhbWV0ZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGFyYW1ldGVyT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBBIHJlZ3VsYXIgZXhwcmVzc2lvbiB1c2VkIHRvIHZhbGlkYXRlIHRoZSBwYXJhbWV0ZXIgdmFsdWUuIEZvciBleGFtcGxlLCBmb3IgU3RyaW5nIHR5cGVzIHdpdGggdmFsdWVzIHJlc3RyaWN0ZWQgdG9cbiAgICogbnVtYmVycywgeW91IGNhbiBzcGVjaWZ5IHRoZSBmb2xsb3dpbmc6IGBgXlxcZCskYGBcbiAgICpcbiAgICogQGRlZmF1bHQgbm8gdmFsaWRhdGlvbiBpcyBwZXJmb3JtZWRcbiAgICovXG4gIHJlYWRvbmx5IGFsbG93ZWRQYXR0ZXJuPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBJbmZvcm1hdGlvbiBhYm91dCB0aGUgcGFyYW1ldGVyIHRoYXQgeW91IHdhbnQgdG8gYWRkIHRvIHRoZSBzeXN0ZW0uXG4gICAqXG4gICAqIEBkZWZhdWx0IG5vbmVcbiAgICovXG4gIHJlYWRvbmx5IGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGEgbmFtZSB3aWxsIGJlIGdlbmVyYXRlZCBieSBDbG91ZEZvcm1hdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgcGFyYW1ldGVyTmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogSW5kaWNhdGVzIG9mIHRoZSBwYXJhbWV0ZXIgbmFtZSBpcyBhIHNpbXBsZSBuYW1lIChpLmUuIGRvZXMgbm90IGluY2x1ZGUgXCIvXCJcbiAgICogc2VwYXJhdG9ycykuXG4gICAqXG4gICAqIFRoaXMgaXMgb25seSByZXF1aXJlZCBvbmx5IGlmIGBwYXJhbWV0ZXJOYW1lYCBpcyBhIHRva2VuLCB3aGljaCBtZWFucyB3ZVxuICAgKiBhcmUgdW5hYmxlIHRvIGRldGVjdCBpZiB0aGUgbmFtZSBpcyBzaW1wbGUgb3IgXCJwYXRoLWxpa2VcIiBmb3IgdGhlIHB1cnBvc2VcbiAgICogb2YgcmVuZGVyaW5nIFNTTSBwYXJhbWV0ZXIgQVJOcy5cbiAgICpcbiAgICogSWYgYHBhcmFtZXRlck5hbWVgIGlzIG5vdCBzcGVjaWZpZWQsIGBzaW1wbGVOYW1lYCBtdXN0IGJlIGB0cnVlYCAob3JcbiAgICogdW5kZWZpbmVkKSBzaW5jZSB0aGUgbmFtZSBnZW5lcmF0ZWQgYnkgQVdTIENsb3VkRm9ybWF0aW9uIGlzIGFsd2F5cyBhXG4gICAqIHNpbXBsZSBuYW1lLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGF1dG8tZGV0ZWN0IGJhc2VkIG9uIGBwYXJhbWV0ZXJOYW1lYFxuICAgKi9cbiAgcmVhZG9ubHkgc2ltcGxlTmFtZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSB0aWVyIG9mIHRoZSBzdHJpbmcgcGFyYW1ldGVyXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdW5kZWZpbmVkXG4gICAqL1xuICByZWFkb25seSB0aWVyPzogUGFyYW1ldGVyVGllcjtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIG5lZWRlZCB0byBjcmVhdGUgYSBTdHJpbmcgU1NNIHBhcmFtZXRlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdHJpbmdQYXJhbWV0ZXJQcm9wcyBleHRlbmRzIFBhcmFtZXRlck9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIuIEl0IG1heSBub3QgcmVmZXJlbmNlIGFub3RoZXIgcGFyYW1ldGVyIGFuZCBgYHt7fX1gYCBjYW5ub3QgYmUgdXNlZCBpbiB0aGUgdmFsdWUuXG4gICAqL1xuICByZWFkb25seSBzdHJpbmdWYWx1ZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgdHlwZSBvZiB0aGUgc3RyaW5nIHBhcmFtZXRlclxuICAgKlxuICAgKiBAZGVmYXVsdCBQYXJhbWV0ZXJUeXBlLlNUUklOR1xuICAgKi9cbiAgcmVhZG9ubHkgdHlwZT86IFBhcmFtZXRlclR5cGU7XG5cbiAgLyoqXG4gICAqIFRoZSBkYXRhIHR5cGUgb2YgdGhlIHBhcmFtZXRlciwgc3VjaCBhcyBgdGV4dGAgb3IgYGF3czplYzI6aW1hZ2VgLlxuICAgKlxuICAgKiBAZGVmYXVsdCBQYXJhbWV0ZXJEYXRhVHlwZS5URVhUXG4gICAqL1xuICByZWFkb25seSBkYXRhVHlwZT86IFBhcmFtZXRlckRhdGFUeXBlO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgbmVlZGVkIHRvIGNyZWF0ZSBhIFN0cmluZ0xpc3QgU1NNIFBhcmFtZXRlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0cmluZ0xpc3RQYXJhbWV0ZXJQcm9wcyBleHRlbmRzIFBhcmFtZXRlck9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIHZhbHVlcyBvZiB0aGUgcGFyYW1ldGVyLiBJdCBtYXkgbm90IHJlZmVyZW5jZSBhbm90aGVyIHBhcmFtZXRlciBhbmQgYGB7e319YGAgY2Fubm90IGJlIHVzZWQgaW4gdGhlIHZhbHVlLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RyaW5nTGlzdFZhbHVlOiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBCYXNpYyBmZWF0dXJlcyBzaGFyZWQgYWNyb3NzIGFsbCB0eXBlcyBvZiBTU00gUGFyYW1ldGVycy5cbiAqL1xuYWJzdHJhY3QgY2xhc3MgUGFyYW1ldGVyQmFzZSBleHRlbmRzIFJlc291cmNlIGltcGxlbWVudHMgSVBhcmFtZXRlciB7XG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSBwYXJhbWV0ZXJBcm46IHN0cmluZztcbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IHBhcmFtZXRlck5hbWU6IHN0cmluZztcbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IHBhcmFtZXRlclR5cGU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGVuY3J5cHRpb24ga2V5IHRoYXQgaXMgdXNlZCB0byBlbmNyeXB0IHRoaXMgcGFyYW1ldGVyLlxuICAgKlxuICAgKiAqIEBkZWZhdWx0IC0gZGVmYXVsdCBtYXN0ZXIga2V5XG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZW5jcnlwdGlvbktleT86IGttcy5JS2V5O1xuXG4gIHB1YmxpYyBncmFudFJlYWQoZ3JhbnRlZTogaWFtLklHcmFudGFibGUpOiBpYW0uR3JhbnQge1xuICAgIGlmICh0aGlzLmVuY3J5cHRpb25LZXkpIHtcbiAgICAgIHRoaXMuZW5jcnlwdGlvbktleS5ncmFudERlY3J5cHQoZ3JhbnRlZSk7XG4gICAgfVxuICAgIHJldHVybiBpYW0uR3JhbnQuYWRkVG9QcmluY2lwYWwoe1xuICAgICAgZ3JhbnRlZSxcbiAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgJ3NzbTpEZXNjcmliZVBhcmFtZXRlcnMnLFxuICAgICAgICAnc3NtOkdldFBhcmFtZXRlcnMnLFxuICAgICAgICAnc3NtOkdldFBhcmFtZXRlcicsXG4gICAgICAgICdzc206R2V0UGFyYW1ldGVySGlzdG9yeScsXG4gICAgICBdLFxuICAgICAgcmVzb3VyY2VBcm5zOiBbdGhpcy5wYXJhbWV0ZXJBcm5dLFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGdyYW50V3JpdGUoZ3JhbnRlZTogaWFtLklHcmFudGFibGUpOiBpYW0uR3JhbnQge1xuICAgIGlmICh0aGlzLmVuY3J5cHRpb25LZXkpIHtcbiAgICAgIHRoaXMuZW5jcnlwdGlvbktleS5ncmFudEVuY3J5cHQoZ3JhbnRlZSk7XG4gICAgfVxuICAgIHJldHVybiBpYW0uR3JhbnQuYWRkVG9QcmluY2lwYWwoe1xuICAgICAgZ3JhbnRlZSxcbiAgICAgIGFjdGlvbnM6IFsnc3NtOlB1dFBhcmFtZXRlciddLFxuICAgICAgcmVzb3VyY2VBcm5zOiBbdGhpcy5wYXJhbWV0ZXJBcm5dLFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogU1NNIHBhcmFtZXRlciB0eXBlXG4gKi9cbmV4cG9ydCBlbnVtIFBhcmFtZXRlclR5cGUge1xuICAvKipcbiAgICogU3RyaW5nXG4gICAqL1xuICBTVFJJTkcgPSAnU3RyaW5nJyxcbiAgLyoqXG4gICAqIFNlY3VyZSBTdHJpbmdcbiAgICpcbiAgICogUGFyYW1ldGVyIFN0b3JlIHVzZXMgYW4gQVdTIEtleSBNYW5hZ2VtZW50IFNlcnZpY2UgKEtNUykgY3VzdG9tZXIgbWFzdGVyIGtleSAoQ01LKSB0byBlbmNyeXB0IHRoZSBwYXJhbWV0ZXIgdmFsdWUuXG4gICAqIFBhcmFtZXRlcnMgb2YgdHlwZSBTZWN1cmVTdHJpbmcgY2Fubm90IGJlIGNyZWF0ZWQgZGlyZWN0bHkgZnJvbSBhIENESyBhcHBsaWNhdGlvbi5cbiAgICovXG4gIFNFQ1VSRV9TVFJJTkcgPSAnU2VjdXJlU3RyaW5nJyxcbiAgLyoqXG4gICAqIFN0cmluZyBMaXN0XG4gICAqL1xuICBTVFJJTkdfTElTVCA9ICdTdHJpbmdMaXN0JyxcbiAgLyoqXG4gICAqIEFuIEFtYXpvbiBFQzIgaW1hZ2UgSUQsIHN1Y2ggYXMgYW1pLTBmZjhhOTE1MDdmNzdmODY3XG4gICAqL1xuICBBV1NfRUMyX0lNQUdFX0lEID0gJ0FXUzo6RUMyOjpJbWFnZTo6SWQnLFxufVxuXG4vKipcbiAqIFNTTSBwYXJhbWV0ZXIgZGF0YSB0eXBlXG4gKi9cbmV4cG9ydCBlbnVtIFBhcmFtZXRlckRhdGFUeXBlIHtcbiAgLyoqXG4gICAqIFRleHRcbiAgICovXG4gIFRFWFQgPSAndGV4dCcsXG4gIC8qKlxuICAgKiBBd3MgRWMyIEltYWdlXG4gICAqL1xuICBBV1NfRUMyX0lNQUdFID0gJ2F3czplYzI6aW1hZ2UnLFxufVxuXG4vKipcbiAqIFNTTSBwYXJhbWV0ZXIgdGllclxuICovXG5leHBvcnQgZW51bSBQYXJhbWV0ZXJUaWVyIHtcbiAgLyoqXG4gICAqIFN0cmluZ1xuICAgKi9cbiAgQURWQU5DRUQgPSAnQWR2YW5jZWQnLFxuICAvKipcbiAgICogU3RyaW5nXG4gICAqL1xuICBJTlRFTExJR0VOVF9USUVSSU5HID0gJ0ludGVsbGlnZW50LVRpZXJpbmcnLFxuICAvKipcbiAgICogU3RyaW5nXG4gICAqL1xuICBTVEFOREFSRCA9ICdTdGFuZGFyZCcsXG59XG5cbi8qKlxuICogQ29tbW9uIGF0dHJpYnV0ZXMgZm9yIHN0cmluZyBwYXJhbWV0ZXJzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbW1vblN0cmluZ1BhcmFtZXRlckF0dHJpYnV0ZXMge1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlciBzdG9yZSB2YWx1ZS5cbiAgICpcbiAgICogVGhpcyB2YWx1ZSBjYW4gYmUgYSB0b2tlbiBvciBhIGNvbmNyZXRlIHN0cmluZy4gSWYgaXQgaXMgYSBjb25jcmV0ZSBzdHJpbmdcbiAgICogYW5kIGluY2x1ZGVzIFwiL1wiIGl0IG11c3QgYWxzbyBiZSBwcmVmaXhlZCB3aXRoIGEgXCIvXCIgKGZ1bGx5LXF1YWxpZmllZCkuXG4gICAqL1xuICByZWFkb25seSBwYXJhbWV0ZXJOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyBvZiB0aGUgcGFyYW1ldGVyIG5hbWUgaXMgYSBzaW1wbGUgbmFtZSAoaS5lLiBkb2VzIG5vdCBpbmNsdWRlIFwiL1wiXG4gICAqIHNlcGFyYXRvcnMpLlxuICAgKlxuICAgKiBUaGlzIGlzIG9ubHkgcmVxdWlyZWQgb25seSBpZiBgcGFyYW1ldGVyTmFtZWAgaXMgYSB0b2tlbiwgd2hpY2ggbWVhbnMgd2VcbiAgICogYXJlIHVuYWJsZSB0byBkZXRlY3QgaWYgdGhlIG5hbWUgaXMgc2ltcGxlIG9yIFwicGF0aC1saWtlXCIgZm9yIHRoZSBwdXJwb3NlXG4gICAqIG9mIHJlbmRlcmluZyBTU00gcGFyYW1ldGVyIEFSTnMuXG4gICAqXG4gICAqIElmIGBwYXJhbWV0ZXJOYW1lYCBpcyBub3Qgc3BlY2lmaWVkLCBgc2ltcGxlTmFtZWAgbXVzdCBiZSBgdHJ1ZWAgKG9yXG4gICAqIHVuZGVmaW5lZCkgc2luY2UgdGhlIG5hbWUgZ2VuZXJhdGVkIGJ5IEFXUyBDbG91ZEZvcm1hdGlvbiBpcyBhbHdheXMgYVxuICAgKiBzaW1wbGUgbmFtZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBhdXRvLWRldGVjdCBiYXNlZCBvbiBgcGFyYW1ldGVyTmFtZWBcbiAgICovXG4gIHJlYWRvbmx5IHNpbXBsZU5hbWU/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIEF0dHJpYnV0ZXMgZm9yIHBhcmFtZXRlcnMgb2YgdmFyaW91cyB0eXBlcyBvZiBzdHJpbmcuXG4gKlxuICogQHNlZSBQYXJhbWV0ZXJUeXBlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RyaW5nUGFyYW1ldGVyQXR0cmlidXRlcyBleHRlbmRzIENvbW1vblN0cmluZ1BhcmFtZXRlckF0dHJpYnV0ZXMge1xuICAvKipcbiAgICogVGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZSB2YWx1ZSB5b3Ugd2lzaCB0byByZXRyaWV2ZS5cbiAgICpcbiAgICogQGRlZmF1bHQgVGhlIGxhdGVzdCB2ZXJzaW9uIHdpbGwgYmUgcmV0cmlldmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbj86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIHR5cGUgb2YgdGhlIHN0cmluZyBwYXJhbWV0ZXJcbiAgICpcbiAgICogQGRlZmF1bHQgUGFyYW1ldGVyVHlwZS5TVFJJTkdcbiAgICovXG4gIHJlYWRvbmx5IHR5cGU/OiBQYXJhbWV0ZXJUeXBlO1xufVxuXG4vKipcbiAqIEF0dHJpYnV0ZXMgZm9yIHNlY3VyZSBzdHJpbmcgcGFyYW1ldGVycy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZWN1cmVTdHJpbmdQYXJhbWV0ZXJBdHRyaWJ1dGVzIGV4dGVuZHMgQ29tbW9uU3RyaW5nUGFyYW1ldGVyQXR0cmlidXRlcyB7XG4gIC8qKlxuICAgKiBUaGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIHZhbHVlIHlvdSB3aXNoIHRvIHJldHJpZXZlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEFXUyBDbG91ZEZvcm1hdGlvbiB1c2VzIHRoZSBsYXRlc3QgdmVyc2lvbiBvZiB0aGUgcGFyYW1ldGVyXG4gICAqL1xuICByZWFkb25seSB2ZXJzaW9uPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgZW5jcnlwdGlvbiBrZXkgdGhhdCBpcyB1c2VkIHRvIGVuY3J5cHQgdGhpcyBwYXJhbWV0ZXJcbiAgICpcbiAgICogQGRlZmF1bHQgLSBkZWZhdWx0IG1hc3RlciBrZXlcbiAgICovXG4gIHJlYWRvbmx5IGVuY3J5cHRpb25LZXk/OiBrbXMuSUtleTtcblxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgU3RyaW5nIFNTTSBQYXJhbWV0ZXIuXG4gKiBAcmVzb3VyY2UgQVdTOjpTU006OlBhcmFtZXRlclxuICovXG5leHBvcnQgY2xhc3MgU3RyaW5nUGFyYW1ldGVyIGV4dGVuZHMgUGFyYW1ldGVyQmFzZSBpbXBsZW1lbnRzIElTdHJpbmdQYXJhbWV0ZXIge1xuXG4gIC8qKlxuICAgKiBJbXBvcnRzIGFuIGV4dGVybmFsIHN0cmluZyBwYXJhbWV0ZXIgYnkgbmFtZS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbVN0cmluZ1BhcmFtZXRlck5hbWUoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgc3RyaW5nUGFyYW1ldGVyTmFtZTogc3RyaW5nKTogSVN0cmluZ1BhcmFtZXRlciB7XG4gICAgcmV0dXJuIHRoaXMuZnJvbVN0cmluZ1BhcmFtZXRlckF0dHJpYnV0ZXMoc2NvcGUsIGlkLCB7IHBhcmFtZXRlck5hbWU6IHN0cmluZ1BhcmFtZXRlck5hbWUgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW1wb3J0cyBhbiBleHRlcm5hbCBzdHJpbmcgcGFyYW1ldGVyIHdpdGggbmFtZSBhbmQgb3B0aW9uYWwgdmVyc2lvbi5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbVN0cmluZ1BhcmFtZXRlckF0dHJpYnV0ZXMoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgYXR0cnM6IFN0cmluZ1BhcmFtZXRlckF0dHJpYnV0ZXMpOiBJU3RyaW5nUGFyYW1ldGVyIHtcbiAgICBpZiAoIWF0dHJzLnBhcmFtZXRlck5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigncGFyYW1ldGVyTmFtZSBjYW5ub3QgYmUgYW4gZW1wdHkgc3RyaW5nJyk7XG4gICAgfVxuXG4gICAgY29uc3QgdHlwZSA9IGF0dHJzLnR5cGUgfHwgUGFyYW1ldGVyVHlwZS5TVFJJTkc7XG5cbiAgICBjb25zdCBzdHJpbmdWYWx1ZSA9IGF0dHJzLnZlcnNpb25cbiAgICAgID8gbmV3IENmbkR5bmFtaWNSZWZlcmVuY2UoQ2ZuRHluYW1pY1JlZmVyZW5jZVNlcnZpY2UuU1NNLCBgJHthdHRycy5wYXJhbWV0ZXJOYW1lfToke1Rva2VuaXphdGlvbi5zdHJpbmdpZnlOdW1iZXIoYXR0cnMudmVyc2lvbil9YCkudG9TdHJpbmcoKVxuICAgICAgOiBuZXcgQ2ZuUGFyYW1ldGVyKHNjb3BlIGFzIENvbXBhdENvbnN0cnVjdCwgYCR7aWR9LlBhcmFtZXRlcmAsIHsgdHlwZTogYEFXUzo6U1NNOjpQYXJhbWV0ZXI6OlZhbHVlPCR7dHlwZX0+YCwgZGVmYXVsdDogYXR0cnMucGFyYW1ldGVyTmFtZSB9KS52YWx1ZUFzU3RyaW5nO1xuXG4gICAgY2xhc3MgSW1wb3J0IGV4dGVuZHMgUGFyYW1ldGVyQmFzZSB7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgcGFyYW1ldGVyTmFtZSA9IGF0dHJzLnBhcmFtZXRlck5hbWU7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgcGFyYW1ldGVyQXJuID0gYXJuRm9yUGFyYW1ldGVyTmFtZSh0aGlzLCBhdHRycy5wYXJhbWV0ZXJOYW1lLCB7IHNpbXBsZU5hbWU6IGF0dHJzLnNpbXBsZU5hbWUgfSk7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgcGFyYW1ldGVyVHlwZSA9IHR5cGU7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgc3RyaW5nVmFsdWUgPSBzdHJpbmdWYWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEltcG9ydChzY29wZSwgaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEltcG9ydHMgYSBzZWN1cmUgc3RyaW5nIHBhcmFtZXRlciBmcm9tIHRoZSBTU00gcGFyYW1ldGVyIHN0b3JlLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tU2VjdXJlU3RyaW5nUGFyYW1ldGVyQXR0cmlidXRlcyhzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBhdHRyczogU2VjdXJlU3RyaW5nUGFyYW1ldGVyQXR0cmlidXRlcyk6IElTdHJpbmdQYXJhbWV0ZXIge1xuICAgIGNvbnN0IHZlcnNpb24gPSBhdHRycy52ZXJzaW9uID8gVG9rZW5pemF0aW9uLnN0cmluZ2lmeU51bWJlcihhdHRycy52ZXJzaW9uKSA6ICcnO1xuICAgIGNvbnN0IHN0cmluZ1ZhbHVlID0gbmV3IENmbkR5bmFtaWNSZWZlcmVuY2UoQ2ZuRHluYW1pY1JlZmVyZW5jZVNlcnZpY2UuU1NNX1NFQ1VSRSwgYCR7YXR0cnMucGFyYW1ldGVyTmFtZX06JHt2ZXJzaW9ufWApLnRvU3RyaW5nKCk7XG5cbiAgICBjbGFzcyBJbXBvcnQgZXh0ZW5kcyBQYXJhbWV0ZXJCYXNlIHtcbiAgICAgIHB1YmxpYyByZWFkb25seSBwYXJhbWV0ZXJOYW1lID0gYXR0cnMucGFyYW1ldGVyTmFtZTtcbiAgICAgIHB1YmxpYyByZWFkb25seSBwYXJhbWV0ZXJBcm4gPSBhcm5Gb3JQYXJhbWV0ZXJOYW1lKHRoaXMsIGF0dHJzLnBhcmFtZXRlck5hbWUsIHsgc2ltcGxlTmFtZTogYXR0cnMuc2ltcGxlTmFtZSB9KTtcbiAgICAgIHB1YmxpYyByZWFkb25seSBwYXJhbWV0ZXJUeXBlID0gUGFyYW1ldGVyVHlwZS5TRUNVUkVfU1RSSU5HO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHN0cmluZ1ZhbHVlID0gc3RyaW5nVmFsdWU7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgZW5jcnlwdGlvbktleSA9IGF0dHJzLmVuY3J5cHRpb25LZXk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyB0aGUgdmFsdWUgb2YgYW4gU1NNIHBhcmFtZXRlciBkdXJpbmcgc3ludGhlc2lzIHRocm91Z2ggYW5cbiAgICogZW52aXJvbm1lbnRhbCBjb250ZXh0IHByb3ZpZGVyLlxuICAgKlxuICAgKiBSZXF1aXJlcyB0aGF0IHRoZSBzdGFjayB0aGlzIHNjb3BlIGlzIGRlZmluZWQgaW4gd2lsbCBoYXZlIGV4cGxpY2l0XG4gICAqIGFjY291bnQvcmVnaW9uIGluZm9ybWF0aW9uLiBPdGhlcndpc2UsIGl0IHdpbGwgZmFpbCBkdXJpbmcgc3ludGhlc2lzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyB2YWx1ZUZyb21Mb29rdXAoc2NvcGU6IENvbXBhdENvbnN0cnVjdCwgcGFyYW1ldGVyTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCB2YWx1ZSA9IENvbnRleHRQcm92aWRlci5nZXRWYWx1ZShzY29wZSwge1xuICAgICAgcHJvdmlkZXI6IGN4c2NoZW1hLkNvbnRleHRQcm92aWRlci5TU01fUEFSQU1FVEVSX1BST1ZJREVSLFxuICAgICAgcHJvcHM6IHsgcGFyYW1ldGVyTmFtZSB9LFxuICAgICAgZHVtbXlWYWx1ZTogYGR1bW15LXZhbHVlLWZvci0ke3BhcmFtZXRlck5hbWV9YCxcbiAgICB9KS52YWx1ZTtcblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgdG9rZW4gdGhhdCB3aWxsIHJlc29sdmUgKGR1cmluZyBkZXBsb3ltZW50KSB0byB0aGUgc3RyaW5nIHZhbHVlIG9mIGFuIFNTTSBzdHJpbmcgcGFyYW1ldGVyLlxuICAgKiBAcGFyYW0gc2NvcGUgU29tZSBzY29wZSB3aXRoaW4gYSBzdGFja1xuICAgKiBAcGFyYW0gcGFyYW1ldGVyTmFtZSBUaGUgbmFtZSBvZiB0aGUgU1NNIHBhcmFtZXRlci5cbiAgICogQHBhcmFtIHZlcnNpb24gVGhlIHBhcmFtZXRlciB2ZXJzaW9uIChyZWNvbW1lbmRlZCBpbiBvcmRlciB0byBlbnN1cmUgdGhhdCB0aGUgdmFsdWUgd29uJ3QgY2hhbmdlIGR1cmluZyBkZXBsb3ltZW50KVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyB2YWx1ZUZvclN0cmluZ1BhcmFtZXRlcihzY29wZTogQ29uc3RydWN0LCBwYXJhbWV0ZXJOYW1lOiBzdHJpbmcsIHZlcnNpb24/OiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBTdHJpbmdQYXJhbWV0ZXIudmFsdWVGb3JUeXBlZFN0cmluZ1BhcmFtZXRlcihzY29wZSwgcGFyYW1ldGVyTmFtZSwgUGFyYW1ldGVyVHlwZS5TVFJJTkcsIHZlcnNpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSB0b2tlbiB0aGF0IHdpbGwgcmVzb2x2ZSAoZHVyaW5nIGRlcGxveW1lbnQpIHRvIHRoZSBzdHJpbmcgdmFsdWUgb2YgYW4gU1NNIHN0cmluZyBwYXJhbWV0ZXIuXG4gICAqIEBwYXJhbSBzY29wZSBTb21lIHNjb3BlIHdpdGhpbiBhIHN0YWNrXG4gICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lIFRoZSBuYW1lIG9mIHRoZSBTU00gcGFyYW1ldGVyLlxuICAgKiBAcGFyYW0gdHlwZSBUaGUgdHlwZSBvZiB0aGUgU1NNIHBhcmFtZXRlci5cbiAgICogQHBhcmFtIHZlcnNpb24gVGhlIHBhcmFtZXRlciB2ZXJzaW9uIChyZWNvbW1lbmRlZCBpbiBvcmRlciB0byBlbnN1cmUgdGhhdCB0aGUgdmFsdWUgd29uJ3QgY2hhbmdlIGR1cmluZyBkZXBsb3ltZW50KVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyB2YWx1ZUZvclR5cGVkU3RyaW5nUGFyYW1ldGVyKHNjb3BlOiBDb25zdHJ1Y3QsIHBhcmFtZXRlck5hbWU6IHN0cmluZywgdHlwZSA9IFBhcmFtZXRlclR5cGUuU1RSSU5HLCB2ZXJzaW9uPzogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHNjb3BlKTtcbiAgICBjb25zdCBpZCA9IG1ha2VJZGVudGl0eUZvckltcG9ydGVkVmFsdWUocGFyYW1ldGVyTmFtZSk7XG4gICAgY29uc3QgZXhpc3RzID0gc3RhY2subm9kZS50cnlGaW5kQ2hpbGQoaWQpIGFzIElTdHJpbmdQYXJhbWV0ZXI7XG5cbiAgICBpZiAoZXhpc3RzKSB7IHJldHVybiBleGlzdHMuc3RyaW5nVmFsdWU7IH1cblxuICAgIHJldHVybiB0aGlzLmZyb21TdHJpbmdQYXJhbWV0ZXJBdHRyaWJ1dGVzKHN0YWNrLCBpZCwgeyBwYXJhbWV0ZXJOYW1lLCB2ZXJzaW9uLCB0eXBlIH0pLnN0cmluZ1ZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSB0b2tlbiB0aGF0IHdpbGwgcmVzb2x2ZSAoZHVyaW5nIGRlcGxveW1lbnQpXG4gICAqIEBwYXJhbSBzY29wZSBTb21lIHNjb3BlIHdpdGhpbiBhIHN0YWNrXG4gICAqIEBwYXJhbSBwYXJhbWV0ZXJOYW1lIFRoZSBuYW1lIG9mIHRoZSBTU00gcGFyYW1ldGVyXG4gICAqIEBwYXJhbSB2ZXJzaW9uIFRoZSBwYXJhbWV0ZXIgdmVyc2lvbiAocmVxdWlyZWQgZm9yIHNlY3VyZSBzdHJpbmdzKVxuICAgKiBAZGVwcmVjYXRlZCBVc2UgYFNlY3JldFZhbHVlLnNzbVNlY3VyZSgpYCBpbnN0ZWFkLCBpdCB3aWxsIGNvcnJlY3RseSB0eXBlIHRoZSBpbXBvcnRlZCB2YWx1ZSBhcyBhIGBTZWNyZXRWYWx1ZWAgYW5kIGFsbG93IGltcG9ydGluZyB3aXRob3V0IHZlcnNpb24uXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHZhbHVlRm9yU2VjdXJlU3RyaW5nUGFyYW1ldGVyKHNjb3BlOiBDb25zdHJ1Y3QsIHBhcmFtZXRlck5hbWU6IHN0cmluZywgdmVyc2lvbjogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHNjb3BlKTtcbiAgICBjb25zdCBpZCA9IG1ha2VJZGVudGl0eUZvckltcG9ydGVkVmFsdWUocGFyYW1ldGVyTmFtZSk7XG4gICAgY29uc3QgZXhpc3RzID0gc3RhY2subm9kZS50cnlGaW5kQ2hpbGQoaWQpIGFzIElTdHJpbmdQYXJhbWV0ZXI7XG4gICAgaWYgKGV4aXN0cykgeyByZXR1cm4gZXhpc3RzLnN0cmluZ1ZhbHVlOyB9XG5cbiAgICByZXR1cm4gdGhpcy5mcm9tU2VjdXJlU3RyaW5nUGFyYW1ldGVyQXR0cmlidXRlcyhzdGFjaywgaWQsIHsgcGFyYW1ldGVyTmFtZSwgdmVyc2lvbiB9KS5zdHJpbmdWYWx1ZTtcbiAgfVxuXG4gIHB1YmxpYyByZWFkb25seSBwYXJhbWV0ZXJBcm46IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlck5hbWU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlclR5cGU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHN0cmluZ1ZhbHVlOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFN0cmluZ1BhcmFtZXRlclByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBwaHlzaWNhbE5hbWU6IHByb3BzLnBhcmFtZXRlck5hbWUsXG4gICAgfSk7XG5cbiAgICBpZiAocHJvcHMuYWxsb3dlZFBhdHRlcm4pIHtcbiAgICAgIF9hc3NlcnRWYWxpZFZhbHVlKHByb3BzLnN0cmluZ1ZhbHVlLCBwcm9wcy5hbGxvd2VkUGF0dGVybik7XG4gICAgfVxuXG4gICAgdmFsaWRhdGVQYXJhbWV0ZXJOYW1lKHRoaXMucGh5c2ljYWxOYW1lKTtcblxuICAgIGlmIChwcm9wcy5kZXNjcmlwdGlvbiAmJiBwcm9wcy5kZXNjcmlwdGlvbj8ubGVuZ3RoID4gMTAyNCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdEZXNjcmlwdGlvbiBjYW5ub3QgYmUgbG9uZ2VyIHRoYW4gMTAyNCBjaGFyYWN0ZXJzLicpO1xuICAgIH1cblxuICAgIGlmIChwcm9wcy50eXBlICYmIHByb3BzLnR5cGUgPT09IFBhcmFtZXRlclR5cGUuQVdTX0VDMl9JTUFHRV9JRCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgdHlwZSBtdXN0IGVpdGhlciBiZSBQYXJhbWV0ZXJUeXBlLlNUUklORyBvciBQYXJhbWV0ZXJUeXBlLlNUUklOR19MSVNULiBEaWQgeW91IG1lYW4gdG8gc2V0IGRhdGFUeXBlOiBQYXJhbWV0ZXJEYXRhVHlwZS5BV1NfRUMyX0lNQUdFIGluc3RlYWQ/Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzb3VyY2UgPSBuZXcgc3NtLkNmblBhcmFtZXRlcih0aGlzLCAnUmVzb3VyY2UnLCB7XG4gICAgICBhbGxvd2VkUGF0dGVybjogcHJvcHMuYWxsb3dlZFBhdHRlcm4sXG4gICAgICBkZXNjcmlwdGlvbjogcHJvcHMuZGVzY3JpcHRpb24sXG4gICAgICBuYW1lOiB0aGlzLnBoeXNpY2FsTmFtZSxcbiAgICAgIHRpZXI6IHByb3BzLnRpZXIsXG4gICAgICB0eXBlOiBwcm9wcy50eXBlIHx8IFBhcmFtZXRlclR5cGUuU1RSSU5HLFxuICAgICAgZGF0YVR5cGU6IHByb3BzLmRhdGFUeXBlLFxuICAgICAgdmFsdWU6IHByb3BzLnN0cmluZ1ZhbHVlLFxuICAgIH0pO1xuXG4gICAgdGhpcy5wYXJhbWV0ZXJOYW1lID0gdGhpcy5nZXRSZXNvdXJjZU5hbWVBdHRyaWJ1dGUocmVzb3VyY2UucmVmKTtcbiAgICB0aGlzLnBhcmFtZXRlckFybiA9IGFybkZvclBhcmFtZXRlck5hbWUodGhpcywgdGhpcy5wYXJhbWV0ZXJOYW1lLCB7XG4gICAgICBwaHlzaWNhbE5hbWU6IHByb3BzLnBhcmFtZXRlck5hbWUgfHwgQVVUT0dFTl9NQVJLRVIsXG4gICAgICBzaW1wbGVOYW1lOiBwcm9wcy5zaW1wbGVOYW1lLFxuICAgIH0pO1xuXG4gICAgdGhpcy5wYXJhbWV0ZXJUeXBlID0gcmVzb3VyY2UuYXR0clR5cGU7XG4gICAgdGhpcy5zdHJpbmdWYWx1ZSA9IHJlc291cmNlLmF0dHJWYWx1ZTtcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgU3RyaW5nTGlzdCBTU00gUGFyYW1ldGVyLlxuICogQHJlc291cmNlIEFXUzo6U1NNOjpQYXJhbWV0ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmluZ0xpc3RQYXJhbWV0ZXIgZXh0ZW5kcyBQYXJhbWV0ZXJCYXNlIGltcGxlbWVudHMgSVN0cmluZ0xpc3RQYXJhbWV0ZXIge1xuXG4gIC8qKlxuICAgKiBJbXBvcnRzIGFuIGV4dGVybmFsIHBhcmFtZXRlciBvZiB0eXBlIHN0cmluZyBsaXN0LlxuICAgKiBSZXR1cm5zIGEgdG9rZW4gYW5kIHNob3VsZCBub3QgYmUgcGFyc2VkLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tU3RyaW5nTGlzdFBhcmFtZXRlck5hbWUoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgc3RyaW5nTGlzdFBhcmFtZXRlck5hbWU6IHN0cmluZyk6IElTdHJpbmdMaXN0UGFyYW1ldGVyIHtcbiAgICBjbGFzcyBJbXBvcnQgZXh0ZW5kcyBQYXJhbWV0ZXJCYXNlIHtcbiAgICAgIHB1YmxpYyByZWFkb25seSBwYXJhbWV0ZXJOYW1lID0gc3RyaW5nTGlzdFBhcmFtZXRlck5hbWU7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgcGFyYW1ldGVyQXJuID0gYXJuRm9yUGFyYW1ldGVyTmFtZSh0aGlzLCB0aGlzLnBhcmFtZXRlck5hbWUpO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlclR5cGUgPSBQYXJhbWV0ZXJUeXBlLlNUUklOR19MSVNUO1xuICAgICAgcHVibGljIHJlYWRvbmx5IHN0cmluZ0xpc3RWYWx1ZSA9IEZuLnNwbGl0KCcsJywgbmV3IENmbkR5bmFtaWNSZWZlcmVuY2UoQ2ZuRHluYW1pY1JlZmVyZW5jZVNlcnZpY2UuU1NNLCBzdHJpbmdMaXN0UGFyYW1ldGVyTmFtZSkudG9TdHJpbmcoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gIHB1YmxpYyByZWFkb25seSBwYXJhbWV0ZXJBcm46IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlck5hbWU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHBhcmFtZXRlclR5cGU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHN0cmluZ0xpc3RWYWx1ZTogc3RyaW5nW107XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFN0cmluZ0xpc3RQYXJhbWV0ZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuICAgICAgcGh5c2ljYWxOYW1lOiBwcm9wcy5wYXJhbWV0ZXJOYW1lLFxuICAgIH0pO1xuXG4gICAgaWYgKHByb3BzLnN0cmluZ0xpc3RWYWx1ZS5maW5kKHN0ciA9PiAhVG9rZW4uaXNVbnJlc29sdmVkKHN0cikgJiYgc3RyLmluZGV4T2YoJywnKSAhPT0gLTEpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ZhbHVlcyBvZiBhIFN0cmluZ0xpc3QgU1NNIFBhcmFtZXRlciBjYW5ub3QgY29udGFpbiB0aGUgXFwnLFxcJyBjaGFyYWN0ZXIuIFVzZSBhIHN0cmluZyBwYXJhbWV0ZXIgaW5zdGVhZC4nKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuYWxsb3dlZFBhdHRlcm4gJiYgIVRva2VuLmlzVW5yZXNvbHZlZChwcm9wcy5zdHJpbmdMaXN0VmFsdWUpKSB7XG4gICAgICBwcm9wcy5zdHJpbmdMaXN0VmFsdWUuZm9yRWFjaChzdHIgPT4gX2Fzc2VydFZhbGlkVmFsdWUoc3RyLCBwcm9wcy5hbGxvd2VkUGF0dGVybiEpKTtcbiAgICB9XG5cbiAgICB2YWxpZGF0ZVBhcmFtZXRlck5hbWUodGhpcy5waHlzaWNhbE5hbWUpO1xuXG4gICAgaWYgKHByb3BzLmRlc2NyaXB0aW9uICYmIHByb3BzLmRlc2NyaXB0aW9uPy5sZW5ndGggPiAxMDI0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Rlc2NyaXB0aW9uIGNhbm5vdCBiZSBsb25nZXIgdGhhbiAxMDI0IGNoYXJhY3RlcnMuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzb3VyY2UgPSBuZXcgc3NtLkNmblBhcmFtZXRlcih0aGlzLCAnUmVzb3VyY2UnLCB7XG4gICAgICBhbGxvd2VkUGF0dGVybjogc