@aws-cdk/aws-ssm
Version:
The CDK Construct Library for AWS::SSM
382 lines • 52.6 kB
JavaScript
"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