UNPKG

@aws-cdk/aws-ec2

Version:

The CDK Construct Library for AWS::EC2

240 lines 45.3 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.Instance = void 0; const jsiiDeprecationWarnings = require("../.warnings.jsii.js"); const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const crypto = require("crypto"); const iam = require("@aws-cdk/aws-iam"); const core_1 = require("@aws-cdk/core"); const aspects_1 = require("./aspects"); const connections_1 = require("./connections"); const ec2_generated_1 = require("./ec2.generated"); const ebs_util_1 = require("./private/ebs-util"); const security_group_1 = require("./security-group"); const vpc_1 = require("./vpc"); /** * Name tag constant */ const NAME_TAG = 'Name'; /** * This represents a single EC2 instance */ class Instance extends core_1.Resource { constructor(scope, id, props) { super(scope, id); this.securityGroups = []; try { jsiiDeprecationWarnings._aws_cdk_aws_ec2_InstanceProps(props); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, Instance); } throw error; } if (props.initOptions && !props.init) { throw new Error('Setting \'initOptions\' requires that \'init\' is also set'); } if (props.securityGroup) { this.securityGroup = props.securityGroup; } else { this.securityGroup = new security_group_1.SecurityGroup(this, 'InstanceSecurityGroup', { vpc: props.vpc, allowAllOutbound: props.allowAllOutbound !== false, }); } this.connections = new connections_1.Connections({ securityGroups: [this.securityGroup] }); this.securityGroups.push(this.securityGroup); core_1.Tags.of(this).add(NAME_TAG, props.instanceName || this.node.path); this.role = props.role || new iam.Role(this, 'InstanceRole', { assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'), }); this.grantPrincipal = this.role; const iamProfile = new iam.CfnInstanceProfile(this, 'InstanceProfile', { roles: [this.role.roleName], }); // use delayed evaluation const imageConfig = props.machineImage.getImage(this); this.userData = props.userData ?? imageConfig.userData; const userDataToken = core_1.Lazy.string({ produce: () => core_1.Fn.base64(this.userData.render()) }); const securityGroupsToken = core_1.Lazy.list({ produce: () => this.securityGroups.map(sg => sg.securityGroupId) }); const { subnets } = props.vpc.selectSubnets(props.vpcSubnets); let subnet; if (props.availabilityZone) { const selected = subnets.filter(sn => sn.availabilityZone === props.availabilityZone); if (selected.length === 1) { subnet = selected[0]; } else { core_1.Annotations.of(this).addError(`Need exactly 1 subnet to match AZ '${props.availabilityZone}', found ${selected.length}. Use a different availabilityZone.`); } } else { if (subnets.length > 0) { subnet = subnets[0]; } else { core_1.Annotations.of(this).addError(`Did not find any subnets matching '${JSON.stringify(props.vpcSubnets)}', please use a different selection.`); } } if (!subnet) { // We got here and we don't have a subnet because of validation errors. // Invent one on the spot so the code below doesn't fail. subnet = vpc_1.Subnet.fromSubnetAttributes(this, 'DummySubnet', { subnetId: 's-notfound', availabilityZone: 'az-notfound', }); } this.instance = new ec2_generated_1.CfnInstance(this, 'Resource', { imageId: imageConfig.imageId, keyName: props.keyName, instanceType: props.instanceType.toString(), securityGroupIds: securityGroupsToken, iamInstanceProfile: iamProfile.ref, userData: userDataToken, subnetId: subnet.subnetId, availabilityZone: subnet.availabilityZone, sourceDestCheck: props.sourceDestCheck, blockDeviceMappings: props.blockDevices !== undefined ? ebs_util_1.instanceBlockDeviceMappings(this, props.blockDevices) : undefined, privateIpAddress: props.privateIpAddress, propagateTagsToVolumeOnCreation: props.propagateTagsToVolumeOnCreation, monitoring: props.detailedMonitoring, }); this.instance.node.addDependency(this.role); this.osType = imageConfig.osType; this.node.defaultChild = this.instance; this.instanceId = this.instance.ref; this.instanceAvailabilityZone = this.instance.attrAvailabilityZone; this.instancePrivateDnsName = this.instance.attrPrivateDnsName; this.instancePrivateIp = this.instance.attrPrivateIp; this.instancePublicDnsName = this.instance.attrPublicDnsName; this.instancePublicIp = this.instance.attrPublicIp; if (props.init) { this.applyCloudFormationInit(props.init, props.initOptions); } this.applyUpdatePolicies(props); // Trigger replacement (via new logical ID) on user data change, if specified or cfn-init is being used. // // This is slightly tricky -- we need to resolve the UserData string (in order to get at actual Asset hashes, // instead of the Token stringifications of them ('${Token[1234]}'). However, in the case of CFN Init usage, // a UserData is going to contain the logicalID of the resource itself, which means infinite recursion if we // try to naively resolve. We need a recursion breaker in this. const originalLogicalId = core_1.Stack.of(this).getLogicalId(this.instance); let recursing = false; this.instance.overrideLogicalId(core_1.Lazy.uncachedString({ produce: (context) => { if (recursing) { return originalLogicalId; } if (!(props.userDataCausesReplacement ?? props.initOptions)) { return originalLogicalId; } const md5 = crypto.createHash('md5'); recursing = true; try { md5.update(JSON.stringify(context.resolve(this.userData.render()))); } finally { recursing = false; } const digest = md5.digest('hex').slice(0, 16); return `${originalLogicalId}${digest}`; }, })); if (props.requireImdsv2) { core_1.Aspects.of(this).add(new aspects_1.InstanceRequireImdsv2Aspect()); } } /** * Add the security group to the instance. * * @param securityGroup: The security group to add */ addSecurityGroup(securityGroup) { try { jsiiDeprecationWarnings._aws_cdk_aws_ec2_ISecurityGroup(securityGroup); } catch (error) { if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") { Error.captureStackTrace(error, this.addSecurityGroup); } throw error; } this.securityGroups.push(securityGroup); } /** * Add command to the startup script of the instance. * The command must be in the scripting language supported by the instance's OS (i.e. Linux/Windows). */ addUserData(...commands) { this.userData.addCommands(...commands); } /** * Adds a statement to the IAM role assumed by the instance. */ addToRolePolicy(statement) { this.role.addToPrincipalPolicy(statement); } /** * Use a CloudFormation Init configuration at instance startup * * This does the following: * * - Attaches the CloudFormation Init metadata to the Instance resource. * - Add commands to the instance UserData to run `cfn-init` and `cfn-signal`. * - Update the instance's CreationPolicy to wait for the `cfn-signal` commands. */ applyCloudFormationInit(init, options = {}) { init.attach(this.instance, { platform: this.osType, instanceRole: this.role, userData: this.userData, configSets: options.configSets, embedFingerprint: options.embedFingerprint, printLog: options.printLog, ignoreFailures: options.ignoreFailures, includeRole: options.includeRole, includeUrl: options.includeUrl, }); this.waitForResourceSignal(options.timeout ?? core_1.Duration.minutes(5)); } /** * Wait for a single additional resource signal * * Add 1 to the current ResourceSignal Count and add the given timeout to the current timeout. * * Use this to pause the CloudFormation deployment to wait for the instances * in the AutoScalingGroup to report successful startup during * creation and updates. The UserData script needs to invoke `cfn-signal` * with a success or failure code after it is done setting up the instance. */ waitForResourceSignal(timeout) { const oldResourceSignal = this.instance.cfnOptions.creationPolicy?.resourceSignal; this.instance.cfnOptions.creationPolicy = { ...this.instance.cfnOptions.creationPolicy, resourceSignal: { count: (oldResourceSignal?.count ?? 0) + 1, timeout: (oldResourceSignal?.timeout ? core_1.Duration.parse(oldResourceSignal?.timeout).plus(timeout) : timeout).toIsoString(), }, }; } /** * Apply CloudFormation update policies for the instance */ applyUpdatePolicies(props) { if (props.resourceSignalTimeout !== undefined) { this.instance.cfnOptions.creationPolicy = { ...this.instance.cfnOptions.creationPolicy, resourceSignal: { timeout: props.resourceSignalTimeout && props.resourceSignalTimeout.toIsoString(), }, }; } } } exports.Instance = Instance; _a = JSII_RTTI_SYMBOL_1; Instance[_a] = { fqn: "@aws-cdk/aws-ec2.Instance", version: "1.204.0" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdGFuY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbnN0YW5jZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxpQ0FBaUM7QUFDakMsd0NBQXdDO0FBRXhDLHdDQUEyRztBQUUzRyx1Q0FBd0Q7QUFFeEQsK0NBQTBEO0FBQzFELG1EQUE4QztBQUc5QyxpREFBaUU7QUFDakUscURBQWlFO0FBR2pFLCtCQUFzRDtBQUV0RDs7R0FFRztBQUNILE1BQU0sUUFBUSxHQUFXLE1BQU0sQ0FBQztBQThPaEM7O0dBRUc7QUFDSCxNQUFhLFFBQVMsU0FBUSxlQUFRO0lBMkRwQyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQW9CO1FBQzVELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFIRixtQkFBYyxHQUFxQixFQUFFLENBQUM7Ozs7OzsrQ0F6RDVDLFFBQVE7Ozs7UUE4RGpCLElBQUksS0FBSyxDQUFDLFdBQVcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUU7WUFDcEMsTUFBTSxJQUFJLEtBQUssQ0FBQyw0REFBNEQsQ0FBQyxDQUFDO1NBQy9FO1FBRUQsSUFBSSxLQUFLLENBQUMsYUFBYSxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQztTQUMxQzthQUFNO1lBQ0wsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLDhCQUFhLENBQUMsSUFBSSxFQUFFLHVCQUF1QixFQUFFO2dCQUNwRSxHQUFHLEVBQUUsS0FBSyxDQUFDLEdBQUc7Z0JBQ2QsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQixLQUFLLEtBQUs7YUFDbkQsQ0FBQyxDQUFDO1NBQ0o7UUFDRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUkseUJBQVcsQ0FBQyxFQUFFLGNBQWMsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDN0UsSUFBSSxDQUFDLGNBQWMs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QUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxjQUFjLEdBQUc7Z0JBQ3hDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsY0FBYztnQkFDMUMsY0FBYyxFQUFFO29CQUNkLE9BQU8sRUFBRSxLQUFLLENBQUMscUJBQXFCLElBQUksS0FBSyxDQUFDLHFCQUFxQixDQUFDLFdBQVcsRUFBRTtpQkFDbEY7YUFDRixDQUFDO1NBQ0g7S0FDRjs7QUF0UUgsNEJBdVFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgKiBhcyBpYW0gZnJvbSAnQGF3cy1jZGsvYXdzLWlhbSc7XG5cbmltcG9ydCB7IEFubm90YXRpb25zLCBBc3BlY3RzLCBEdXJhdGlvbiwgRm4sIElSZXNvdXJjZSwgTGF6eSwgUmVzb3VyY2UsIFN0YWNrLCBUYWdzIH0gZnJvbSAnQGF3cy1jZGsvY29yZSc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IEluc3RhbmNlUmVxdWlyZUltZHN2MkFzcGVjdCB9IGZyb20gJy4vYXNwZWN0cyc7XG5pbXBvcnQgeyBDbG91ZEZvcm1hdGlvbkluaXQgfSBmcm9tICcuL2Nmbi1pbml0JztcbmltcG9ydCB7IENvbm5lY3Rpb25zLCBJQ29ubmVjdGFibGUgfSBmcm9tICcuL2Nvbm5lY3Rpb25zJztcbmltcG9ydCB7IENmbkluc3RhbmNlIH0gZnJvbSAnLi9lYzIuZ2VuZXJhdGVkJztcbmltcG9ydCB7IEluc3RhbmNlVHlwZSB9IGZyb20gJy4vaW5zdGFuY2UtdHlwZXMnO1xuaW1wb3J0IHsgSU1hY2hpbmVJbWFnZSwgT3BlcmF0aW5nU3lzdGVtVHlwZSB9IGZyb20gJy4vbWFjaGluZS1pbWFnZSc7XG5pbXBvcnQgeyBpbnN0YW5jZUJsb2NrRGV2aWNlTWFwcGluZ3MgfSBmcm9tICcuL3ByaXZhdGUvZWJzLXV0aWwnO1xuaW1wb3J0IHsgSVNlY3VyaXR5R3JvdXAsIFNlY3VyaXR5R3JvdXAgfSBmcm9tICcuL3NlY3VyaXR5LWdyb3VwJztcbmltcG9ydCB7IFVzZXJEYXRhIH0gZnJvbSAnLi91c2VyLWRhdGEnO1xuaW1wb3J0IHsgQmxvY2tEZXZpY2UgfSBmcm9tICcuL3ZvbHVtZSc7XG5pbXBvcnQgeyBJVnBjLCBTdWJuZXQsIFN1Ym5ldFNlbGVjdGlvbiB9IGZyb20gJy4vdnBjJztcblxuLyoqXG4gKiBOYW1lIHRhZyBjb25zdGFudFxuICovXG5jb25zdCBOQU1FX1RBRzogc3RyaW5nID0gJ05hbWUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIElJbnN0YW5jZSBleHRlbmRzIElSZXNvdXJjZSwgSUNvbm5lY3RhYmxlLCBpYW0uSUdyYW50YWJsZSB7XG4gIC8qKlxuICAgKiBUaGUgaW5zdGFuY2UncyBJRFxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBpbnN0YW5jZUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBhdmFpbGFiaWxpdHkgem9uZSB0aGUgaW5zdGFuY2Ugd2FzIGxhdW5jaGVkIGluXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbmNlQXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQcml2YXRlIEROUyBuYW1lIGZvciB0aGlzIGluc3RhbmNlXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbmNlUHJpdmF0ZURuc05hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogUHJpdmF0ZSBJUCBmb3IgdGhpcyBpbnN0YW5jZVxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBpbnN0YW5jZVByaXZhdGVJcDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQdWJsaWNseS1yb3V0YWJsZSBETlMgbmFtZSBmb3IgdGhpcyBpbnN0YW5jZS5cbiAgICpcbiAgICogKE1heSBiZSBhbiBlbXB0eSBzdHJpbmcgaWYgdGhlIGluc3RhbmNlIGRvZXMgbm90IGhhdmUgYSBwdWJsaWMgbmFtZSkuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbmNlUHVibGljRG5zTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQdWJsaWNseS1yb3V0YWJsZSBJUCAgYWRkcmVzcyBmb3IgdGhpcyBpbnN0YW5jZS5cbiAgICpcbiAgICogKE1heSBiZSBhbiBlbXB0eSBzdHJpbmcgaWYgdGhlIGluc3RhbmNlIGRvZXMgbm90IGhhdmUgYSBwdWJsaWMgSVApLlxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBpbnN0YW5jZVB1YmxpY0lwOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBvZiBhbiBFQzIgSW5zdGFuY2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbnN0YW5jZVByb3BzIHtcblxuICAvKipcbiAgICogTmFtZSBvZiBTU0gga2V5cGFpciB0byBncmFudCBhY2Nlc3MgdG8gaW5zdGFuY2VcbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBTU0ggYWNjZXNzIHdpbGwgYmUgcG9zc2libGUuXG4gICAqL1xuICByZWFkb25seSBrZXlOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXaGVyZSB0byBwbGFjZSB0aGUgaW5zdGFuY2Ugd2l0aGluIHRoZSBWUENcbiAgICpcbiAgICogQGRlZmF1bHQgLSBQcml2YXRlIHN1Ym5ldHMuXG4gICAqL1xuICByZWFkb25seSB2cGNTdWJuZXRzPzogU3VibmV0U2VsZWN0aW9uO1xuXG4gIC8qKlxuICAgKiBJbiB3aGljaCBBWiB0byBwbGFjZSB0aGUgaW5zdGFuY2Ugd2l0aGluIHRoZSBWUENcbiAgICpcbiAgICogQGRlZmF1bHQgLSBSYW5kb20gem9uZS5cbiAgICovXG4gIHJlYWRvbmx5IGF2YWlsYWJpbGl0eVpvbmU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGluc3RhbmNlIGNvdWxkIGluaXRpYXRlIGNvbm5lY3Rpb25zIHRvIGFueXdoZXJlIGJ5IGRlZmF1bHQuXG4gICAqIFRoaXMgcHJvcGVydHkgaXMgb25seSB1c2VkIHdoZW4geW91IGRvIG5vdCBwcm92aWRlIGEgc2VjdXJpdHkgZ3JvdXAuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGFsbG93QWxsT3V0Ym91bmQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgbGVuZ3RoIG9mIHRpbWUgdG8gd2FpdCBmb3IgdGhlIHJlc291cmNlU2lnbmFsQ291bnRcbiAgICpcbiAgICogVGhlIG1heGltdW0gdmFsdWUgaXMgNDMyMDAgKDEyIGhvdXJzKS5cbiAgICpcbiAgICogQGRlZmF1bHQgRHVyYXRpb24ubWludXRlcyg1KVxuICAgKi9cbiAgcmVhZG9ubHkgcmVzb3VyY2VTaWduYWxUaW1lb3V0PzogRHVyYXRpb247XG5cbiAgLyoqXG4gICAqIFZQQyB0byBsYXVuY2ggdGhlIGluc3RhbmNlIGluLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjOiBJVnBjO1xuXG4gIC8qKlxuICAgKiBTZWN1cml0eSBHcm91cCB0byBhc3NpZ24gdG8gdGhpcyBpbnN0YW5jZVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGNyZWF0ZSBuZXcgc2VjdXJpdHkgZ3JvdXBcbiAgICovXG4gIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXA/OiBJU2VjdXJpdHlHcm91cDtcblxuICAvKipcbiAgICogVHlwZSBvZiBpbnN0YW5jZSB0byBsYXVuY2hcbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbmNlVHlwZTogSW5zdGFuY2VUeXBlO1xuXG4gIC8qKlxuICAgKiBBTUkgdG8gbGF1bmNoXG4gICAqL1xuICByZWFkb25seSBtYWNoaW5lSW1hZ2U6IElNYWNoaW5lSW1hZ2U7XG5cbiAgLyoqXG4gICAqIFNwZWNpZmljIFVzZXJEYXRhIHRvIHVzZVxuICAgKlxuICAgKiBUaGUgVXNlckRhdGEgbWF5IHN0aWxsIGJlIG11dGF0ZWQgYWZ0ZXIgY3JlYXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQSBVc2VyRGF0YSBvYmplY3QgYXBwcm9wcmlhdGUgZm9yIHRoZSBNYWNoaW5lSW1hZ2Unc1xuICAgKiBPcGVyYXRpbmcgU3lzdGVtIGlzIGNyZWF0ZWQuXG4gICAqL1xuICByZWFkb25seSB1c2VyRGF0YT86IFVzZXJEYXRhO1xuXG4gIC8qKlxuICAgKiBDaGFuZ2VzIHRvIHRoZSBVc2VyRGF0YSBmb3JjZSByZXBsYWNlbWVudFxuICAgKlxuICAgKiBEZXBlbmRpbmcgdGhlIEVDMiBpbnN0YW5jZSB0eXBlLCBjaGFuZ2luZyBVc2VyRGF0YSBlaXRoZXJcbiAgICogcmVzdGFydHMgdGhlIGluc3RhbmNlIG9yIHJlcGxhY2VzIHRoZSBpbnN0YW5jZS5cbiAgICpcbiAgICogLSBJbnN0YW5jZSBzdG9yZS1iYWNrZWQgaW5zdGFuY2VzIGFyZSByZXBsYWNlZC5cbiAgICogLSBFQlMtYmFja2VkIGluc3RhbmNlcyBhcmUgcmVzdGFydGVkLlxuICAgKlxuICAgKiBCeSBkZWZhdWx0LCByZXN0YXJ0aW5nIGRvZXMgbm90IGV4ZWN1dGUgdGhlIG5ldyBVc2VyRGF0YSBzbyB5b3VcbiAgICogd2lsbCBuZWVkIGEgZGlmZmVyZW50IG1lY2hhbmlzbSB0byBlbnN1cmUgdGhlIGluc3RhbmNlIGlzIHJlc3RhcnRlZC5cbiAgICpcbiAgICogU2V0dGluZyB0aGlzIHRvIGB0cnVlYCB3aWxsIG1ha2UgdGhlIGluc3RhbmNlJ3MgTG9naWNhbCBJRCBkZXBlbmQgb24gdGhlXG4gICAqIFVzZXJEYXRhLCB3aGljaCB3aWxsIGNhdXNlIENsb3VkRm9ybWF0aW9uIHRvIHJlcGxhY2UgaXQgaWYgdGhlIFVzZXJEYXRhXG4gICAqIGNoYW5nZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdHJ1ZSBpZmYgYGluaXRPcHRpb25zYCBpcyBzcGVjaWZpZWQsIGZhbHNlIG90aGVyd2lzZS5cbiAgICovXG4gIHJlYWRvbmx5IHVzZXJEYXRhQ2F1c2VzUmVwbGFjZW1lbnQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBbiBJQU0gcm9sZSB0byBhc3NvY2lhdGUgd2l0aCB0aGUgaW5zdGFuY2UgcHJvZmlsZSBhc3NpZ25lZCB0byB0aGlzIEF1dG8gU2NhbGluZyBHcm91cC5cbiAgICpcbiAgICogVGhlIHJvbGUgbXVzdCBiZSBhc3N1bWFibGUgYnkgdGhlIHNlcnZpY2UgcHJpbmNpcGFsIGBlYzIuYW1hem9uYXdzLmNvbWA6XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNvbnN0IHJvbGUgPSBuZXcgaWFtLlJvbGUodGhpcywgJ015Um9sZScsIHtcbiAgICogICBhc3N1bWVkQnk6IG5ldyBpYW0uU2VydmljZVByaW5jaXBhbCgnZWMyLmFtYXpvbmF3cy5jb20nKVxuICAgKiB9KTtcbiAgICpcbiAgICogQGRlZmF1bHQgLSBBIHJvbGUgd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGNyZWF0ZWQsIGl0IGNhbiBiZSBhY2Nlc3NlZCB2aWEgdGhlIGByb2xlYCBwcm9wZXJ0eVxuICAgKi9cbiAgcmVhZG9ubHkgcm9sZT86IGlhbS5JUm9sZTtcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIGluc3RhbmNlXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQ0RLIGdlbmVyYXRlZCBuYW1lXG4gICAqL1xuICByZWFkb25seSBpbnN0YW5jZU5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB3aGV0aGVyIHRvIGVuYWJsZSBhbiBpbnN0YW5jZSBsYXVuY2hlZCBpbiBhIFZQQyB0byBwZXJmb3JtIE5BVC5cbiAgICogVGhpcyBjb250cm9scyB3aGV0aGVyIHNvdXJjZS9kZXN0aW5hdGlvbiBjaGVja2luZyBpcyBlbmFibGVkIG9uIHRoZSBpbnN0YW5jZS5cbiAgICogQSB2YWx1ZSBvZiB0cnVlIG1lYW5zIHRoYXQgY2hlY2tpbmcgaXMgZW5hYmxlZCwgYW5kIGZhbHNlIG1lYW5zIHRoYXQgY2hlY2tpbmcgaXMgZGlzYWJsZWQuXG4gICAqIFRoZSB2YWx1ZSBtdXN0IGJlIGZhbHNlIGZvciB0aGUgaW5zdGFuY2UgdG8gcGVyZm9ybSBOQVQuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IHNvdXJjZURlc3RDaGVjaz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyBob3cgYmxvY2sgZGV2aWNlcyBhcmUgZXhwb3NlZCB0byB0aGUgaW5zdGFuY2UuIFlvdSBjYW4gc3BlY2lmeSB2aXJ0dWFsIGRldmljZXMgYW5kIEVCUyB2b2x1bWVzLlxuICAgKlxuICAgKiBFYWNoIGluc3RhbmNlIHRoYXQgaXMgbGF1bmNoZWQgaGFzIGFuIGFzc29jaWF0ZWQgcm9vdCBkZXZpY2Ugdm9sdW1lLFxuICAgKiBlaXRoZXIgYW4gQW1hem9uIEVCUyB2b2x1bWUgb3IgYW4gaW5zdGFuY2Ugc3RvcmUgdm9sdW1lLlxuICAgKiBZb3UgY2FuIHVzZSBibG9jayBkZXZpY2UgbWFwcGluZ3MgdG8gc3BlY2lmeSBhZGRpdGlvbmFsIEVCUyB2b2x1bWVzIG9yXG4gICAqIGluc3RhbmNlIHN0b3JlIHZvbHVtZXMgdG8gYXR0YWNoIHRvIGFuIGluc3RhbmNlIHdoZW4gaXQgaXMgbGF1bmNoZWQuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0VDMi9sYXRlc3QvVXNlckd1aWRlL2Jsb2NrLWRldmljZS1tYXBwaW5nLWNvbmNlcHRzLmh0bWxcbiAgICpcbiAgICogQGRlZmF1bHQgLSBVc2VzIHRoZSBibG9jayBkZXZpY2UgbWFwcGluZyBvZiB0aGUgQU1JXG4gICAqL1xuICByZWFkb25seSBibG9ja0RldmljZXM/OiBCbG9ja0RldmljZVtdO1xuXG4gIC8qKlxuICAgKiBEZWZpbmVzIGEgcHJpdmF0ZSBJUCBhZGRyZXNzIHRvIGFzc29jaWF0ZSB3aXRoIGFuIGluc3RhbmNlLlxuICAgKlxuICAgKiBQcml2YXRlIElQIHNob3VsZCBiZSBhdmFpbGFibGUgd2l0aGluIHRoZSBWUEMgdGhhdCB0aGUgaW5zdGFuY2UgaXMgYnVpbGQgd2l0aGluLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGFzc29jaWF0aW9uXG4gICAqL1xuICByZWFkb25seSBwcml2YXRlSXBBZGRyZXNzPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQcm9wYWdhdGUgdGhlIEVDMiBpbnN0YW5jZSB0YWdzIHRvIHRoZSBFQlMgdm9sdW1lcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgcHJvcGFnYXRlVGFnc1RvVm9sdW1lT25DcmVhdGlvbj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEFwcGx5IHRoZSBnaXZlbiBDbG91ZEZvcm1hdGlvbiBJbml0IGNvbmZpZ3VyYXRpb24gdG8gdGhlIGluc3RhbmNlIGF0IHN0YXJ0dXBcbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBDbG91ZEZvcm1hdGlvbiBpbml0XG4gICAqL1xuICByZWFkb25seSBpbml0PzogQ2xvdWRGb3JtYXRpb25Jbml0O1xuXG4gIC8qKlxuICAgKiBVc2UgdGhlIGdpdmVuIG9wdGlvbnMgZm9yIGFwcGx5aW5nIENsb3VkRm9ybWF0aW9uIEluaXRcbiAgICpcbiAgICogRGVzY3JpYmVzIHRoZSBjb25maWdzZXRzIHRvIHVzZSBhbmQgdGhlIHRpbWVvdXQgdG8gd2FpdFxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGRlZmF1bHQgb3B0aW9uc1xuICAgKi9cbiAgcmVhZG9ubHkgaW5pdE9wdGlvbnM/OiBBcHBseUNsb3VkRm9ybWF0aW9uSW5pdE9wdGlvbnM7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgSU1EU3YyIHNob3VsZCBiZSByZXF1aXJlZCBvbiB0aGlzIGluc3RhbmNlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGZhbHNlXG4gICAqL1xuICByZWFkb25seSByZXF1aXJlSW1kc3YyPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciBcIkRldGFpbGVkIE1vbml0b3JpbmdcIiBpcyBlbmFibGVkIGZvciB0aGlzIGluc3RhbmNlXG4gICAqIEtlZXAgaW4gbWluZCB0aGF0IERldGFpbGVkIE1vbml0b3JpbmcgcmVzdWx0cyBpbiBleHRyYSBjaGFyZ2VzXG4gICAqXG4gICAqIEBzZWUgaHR0cDovL2F3cy5hbWF6b24uY29tL2Nsb3Vkd2F0Y2gvcHJpY2luZy9cbiAgICogQGRlZmF1bHQgLSBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgZGV0YWlsZWRNb25pdG9yaW5nPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUaGlzIHJlcHJlc2VudHMgYSBzaW5nbGUgRUMyIGluc3RhbmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBJbnN0YW5jZSBleHRlbmRzIFJlc291cmNlIGltcGxlbWVudHMgSUluc3RhbmNlIHtcblxuICAvKipcbiAgICogVGhlIHR5cGUgb2YgT1MgdGhlIGluc3RhbmNlIGlzIHJ1bm5pbmcuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgb3NUeXBlOiBPcGVyYXRpbmdTeXN0ZW1UeXBlO1xuXG4gIC8qKlxuICAgKiBBbGxvd3Mgc3BlY2lmeSBzZWN1cml0eSBncm91cCBjb25uZWN0aW9ucyBmb3IgdGhlIGluc3RhbmNlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGNvbm5lY3Rpb25zOiBDb25uZWN0aW9ucztcblxuICAvKipcbiAgICogVGhlIElBTSByb2xlIGFzc3VtZWQgYnkgdGhlIGluc3RhbmNlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHJvbGU6IGlhbS5JUm9sZTtcblxuICAvKipcbiAgICogVGhlIHByaW5jaXBhbCB0byBncmFudCBwZXJtaXNzaW9ucyB0b1xuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGdyYW50UHJpbmNpcGFsOiBpYW0uSVByaW5jaXBhbDtcblxuICAvKipcbiAgICogVXNlckRhdGEgZm9yIHRoZSBpbnN0YW5jZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHVzZXJEYXRhOiBVc2VyRGF0YTtcblxuICAvKipcbiAgICogdGhlIHVuZGVybHlpbmcgaW5zdGFuY2UgcmVzb3VyY2VcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpbnN0YW5jZTogQ2ZuSW5zdGFuY2U7XG4gIC8qKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaW5zdGFuY2VJZDogc3RyaW5nO1xuICAvKipcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGluc3RhbmNlQXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nO1xuICAvKipcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGluc3RhbmNlUHJpdmF0ZURuc05hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpbnN0YW5jZVByaXZhdGVJcDogc3RyaW5nO1xuICAvKipcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGluc3RhbmNlUHVibGljRG5zTmFtZTogc3RyaW5nO1xuICAvKipcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGluc3RhbmNlUHVibGljSXA6IHN0cmluZztcblxuICBwcml2YXRlIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXA6IElTZWN1cml0eUdyb3VwO1xuICBwcml2YXRlIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXBzOiBJU2VjdXJpdHlHcm91cFtdID0gW107XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IEluc3RhbmNlUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgaWYgKHByb3BzLmluaXRPcHRpb25zICYmICFwcm9wcy5pbml0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NldHRpbmcgXFwnaW5pdE9wdGlvbnNcXCcgcmVxdWlyZXMgdGhhdCBcXCdpbml0XFwnIGlzIGFsc28gc2V0Jyk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLnNlY3VyaXR5R3JvdXApIHtcbiAgICAgIHRoaXMuc2VjdXJpdHlHcm91cCA9IHByb3BzLnNlY3VyaXR5R3JvdXA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VjdXJpdHlHcm91cCA9IG5ldyBTZWN1cml0eUdyb3VwKHRoaXMsICdJbnN0YW5jZVNlY3VyaXR5R3JvdXAnLCB7XG4gICAgICAgIHZwYzogcHJvcHMudnBjLFxuICAgICAgICBhbGxvd0FsbE91dGJvdW5kOiBwcm9wcy5hbGxvd0FsbE91dGJvdW5kICE9PSBmYWxzZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLmNvbm5lY3Rpb25zID0gbmV3IENvbm5lY3Rpb25zKHsgc2VjdXJpdHlHcm91cHM6IFt0aGlzLnNlY3VyaXR5R3JvdXBdIH0pO1xuICAgIHRoaXMuc2VjdXJpdHlHcm91cHMucHVzaCh0aGlzLnNlY3VyaXR5R3JvdXApO1xuICAgIFRhZ3Mub2YodGhpcykuYWRkKE5BTUVfVEFHLCBwcm9wcy5pbnN0YW5jZU5hbWUgfHwgdGhpcy5ub2RlLnBhdGgpO1xuXG4gICAgdGhpcy5yb2xlID0gcHJvcHMucm9sZSB8fCBuZXcgaWFtLlJvbGUodGhpcywgJ0luc3RhbmNlUm9sZScsIHtcbiAgICAgIGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdlYzIuYW1hem9uYXdzLmNvbScpLFxuICAgIH0pO1xuICAgIHRoaXMuZ3JhbnRQcmluY2lwYWwgPSB0aGlzLnJvbGU7XG5cbiAgICBjb25zdCBpYW1Qcm9maWxlID0gbmV3IGlhbS5DZm5JbnN0YW5jZVByb2ZpbGUodGhpcywgJ0luc3RhbmNlUHJvZmlsZScsIHtcbiAgICAgIHJvbGVzOiBbdGhpcy5yb2xlLnJvbGVOYW1lXSxcbiAgICB9KTtcblxuICAgIC8vIHVzZSBkZWxheWVkIGV2YWx1YXRpb25cbiAgICBjb25zdCBpbWFnZUNvbmZpZyA9IHByb3BzLm1hY2hpbmVJbWFnZS5nZXRJbWFnZSh0aGlzKTtcbiAgICB0aGlzLnVzZXJEYXRhID0gcHJvcHMudXNlckRhdGEgPz8gaW1hZ2VDb25maWcudXNlckRhdGE7XG4gICAgY29uc3QgdXNlckRhdGFUb2tlbiA9IExhenkuc3RyaW5nKHsgcHJvZHVjZTogKCkgPT4gRm4uYmFzZTY0KHRoaXMudXNlckRhdGEucmVuZGVyKCkpIH0pO1xuICAgIGNvbnN0IHNlY3VyaXR5R3JvdXBzVG9rZW4gPSBMYXp5Lmxpc3QoeyBwcm9kdWNlOiAoKSA9PiB0aGlzLnNlY3VyaXR5R3JvdXBzLm1hcChzZyA9PiBzZy5zZWN1cml0eUdyb3VwSWQpIH0pO1xuXG4gICAgY29uc3QgeyBzdWJuZXRzIH0gPSBwcm9wcy52cGMuc2VsZWN0U3VibmV0cyhwcm9wcy52cGNTdWJuZXRzKTtcbiAgICBsZXQgc3VibmV0O1xuICAgIGlmIChwcm9wcy5hdmFpbGFiaWxpdHlab25lKSB7XG4gICAgICBjb25zdCBzZWxlY3RlZCA9IHN1Ym5ldHMuZmlsdGVyKHNuID0+IHNuLmF2YWlsYWJpbGl0eVpvbmUgPT09IHByb3BzLmF2YWlsYWJpbGl0eVpvbmUpO1xuICAgICAgaWYgKHNlbGVjdGVkLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBzdWJuZXQgPSBzZWxlY3RlZFswXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIEFubm90YXRpb25zLm9mKHRoaXMpLmFkZEVycm9yKGBOZWVkIGV4YWN0bHkgMSBzdWJuZXQgdG8gbWF0Y2ggQVogJyR7cHJvcHMuYXZhaWxhYmlsaXR5Wm9uZX0nLCBmb3VuZCAke3NlbGVjdGVkLmxlbmd0aH0uIFVzZSBhIGRpZmZlcmVudCBhdmFpbGFiaWxpdHlab25lLmApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoc3VibmV0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHN1Ym5ldCA9IHN1Ym5ldHNbMF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBBbm5vdGF0aW9ucy5vZih0aGlzKS5hZGRFcnJvcihgRGlkIG5vdCBmaW5kIGFueSBzdWJuZXRzIG1hdGNoaW5nICcke0pTT04uc3RyaW5naWZ5KHByb3BzLnZwY1N1Ym5ldHMpfScsIHBsZWFzZSB1c2UgYSBkaWZmZXJlbnQgc2VsZWN0aW9uLmApO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIXN1Ym5ldCkge1xuICAgICAgLy8gV2UgZ290IGhlcmUgYW5kIHdlIGRvbid0IGhhdmUgYSBzdWJuZXQgYmVjYXVzZSBvZiB2YWxpZGF0aW9uIGVycm9ycy5cbiAgICAgIC8vIEludmVudCBvbmUgb24gdGhlIHNwb3Qgc28gdGhlIGNvZGUgYmVsb3cgZG9lc24ndCBmYWlsLlxuICAgICAgc3VibmV0ID0gU3VibmV0LmZyb21TdWJuZXRBdHRyaWJ1dGVzKHRoaXMsICdEdW1teVN1Ym5ldCcsIHtcbiAgICAgICAgc3VibmV0SWQ6ICdzLW5vdGZvdW5kJyxcbiAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogJ2F6LW5vdGZvdW5kJyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuaW5zdGFuY2UgPSBuZXcgQ2ZuSW5zdGFuY2UodGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgaW1hZ2VJZDogaW1hZ2VDb25maWcuaW1hZ2VJZCxcbiAgICAgIGtleU5hbWU6IHByb3BzLmtleU5hbWUsXG4gICAgICBpbnN0YW5jZVR5cGU6IHByb3BzLmluc3RhbmNlVHlwZS50b1N0cmluZygpLFxuICAgICAgc2VjdXJpdHlHcm91cElkczogc2VjdXJpdHlHcm91cHNUb2tlbixcbiAgICAgIGlhbUluc3RhbmNlUHJvZmlsZTogaWFtUHJvZmlsZS5yZWYsXG4gICAgICB1c2VyRGF0YTogdXNlckRhdGFUb2tlbixcbiAgICAgIHN1Ym5ldElkOiBzdWJuZXQuc3VibmV0SWQsXG4gICAgICBhdmFpbGFiaWxpdHlab25lOiBzdWJuZXQuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICAgIHNvdXJjZURlc3RDaGVjazogcHJvcHMuc291cmNlRGVzdENoZWNrLFxuICAgICAgYmxvY2tEZXZpY2VNYXBwaW5nczogcHJvcHMuYmxvY2tEZXZpY2VzICE9PSB1bmRlZmluZWQgPyBpbnN0YW5jZUJsb2NrRGV2aWNlTWFwcGluZ3ModGhpcywgcHJvcHMuYmxvY2tEZXZpY2VzKSA6IHVuZGVmaW5lZCxcbiAgICAgIHByaXZhdGVJcEFkZHJlc3M6IHByb3BzLnByaXZhdGVJcEFkZHJlc3MsXG4gICAgICBwcm9wYWdhdGVUYWdzVG9Wb2x1bWVPbkNyZWF0aW9uOiBwcm9wcy5wcm9wYWdhdGVUYWdzVG9Wb2x1bWVPbkNyZWF0aW9uLFxuICAgICAgbW9uaXRvcmluZzogcHJvcHMuZGV0YWlsZWRNb25pdG9yaW5nLFxuICAgIH0pO1xuICAgIHRoaXMuaW5zdGFuY2Uubm9kZS5hZGREZXBlbmRlbmN5KHRoaXMucm9sZSk7XG5cbiAgICB0aGlzLm9zVHlwZSA9IGltYWdlQ29uZmlnLm9zVHlwZTtcbiAgICB0aGlzLm5vZGUuZGVmYXVsdENoaWxkID0gdGhpcy5pbnN0YW5jZTtcblxuICAgIHRoaXMuaW5zdGFuY2VJZCA9IHRoaXMuaW5zdGFuY2UucmVmO1xuICAgIHRoaXMuaW5zdGFuY2VBdmFpbGFiaWxpdHlab25lID0gdGhpcy5pbnN0YW5jZS5hdHRyQXZhaWxhYmlsaXR5Wm9uZTtcbiAgICB0aGlzLmluc3RhbmNlUHJpdmF0ZURuc05hbWUgPSB0aGlzLmluc3RhbmNlLmF0dHJQcml2YXRlRG5zTmFtZTtcbiAgICB0aGlzLmluc3RhbmNlUHJpdmF0ZUlwID0gdGhpcy5pbnN0YW5jZS5hdHRyUHJpdmF0ZUlwO1xuICAgIHRoaXMuaW5zdGFuY2VQdWJsaWNEbnNOYW1lID0gdGhpcy5pbnN0YW5jZS5hdHRyUHVibGljRG5zTmFtZTtcbiAgICB0aGlzLmluc3RhbmNlUHVibGljSXAgPSB0aGlzLmluc3RhbmNlLmF0dHJQdWJsaWNJcDtcblxuICAgIGlmIChwcm9wcy5pbml0KSB7XG4gICAgICB0aGlzLmFwcGx5Q2xvdWRGb3JtYXRpb25Jbml0KHByb3BzLmluaXQsIHByb3BzLmluaXRPcHRpb25zKTtcbiAgICB9XG5cbiAgICB0aGlzLmFwcGx5VXBkYXRlUG9saWNpZXMocHJvcHMpO1xuXG4gICAgLy8gVHJpZ2dlciByZXBsYWNlbWVudCAodmlhIG5ldyBsb2dpY2FsIElEKSBvbiB1c2VyIGRhdGEgY2hhbmdlLCBpZiBzcGVjaWZpZWQgb3IgY2ZuLWluaXQgaXMgYmVpbmcgdXNlZC5cbiAgICAvL1xuICAgIC8vIFRoaXMgaXMgc2xpZ2h0bHkgdHJpY2t5IC0tIHdlIG5lZWQgdG8gcmVzb2x2ZSB0aGUgVXNlckRhdGEgc3RyaW5nIChpbiBvcmRlciB0byBnZXQgYXQgYWN0dWFsIEFzc2V0IGhhc2hlcyxcbiAgICAvLyBpbnN0ZWFkIG9mIHRoZSBUb2tlbiBzdHJpbmdpZmljYXRpb25zIG9mIHRoZW0gKCcke1Rva2VuWzEyMzRdfScpLiBIb3dldmVyLCBpbiB0aGUgY2FzZSBvZiBDRk4gSW5pdCB1c2FnZSxcbiAgICAvLyBhIFVzZXJEYXRhIGlzIGdvaW5nIHRvIGNvbnRhaW4gdGhlIGxvZ2ljYWxJRCBvZiB0aGUgcmVzb3VyY2UgaXRzZWxmLCB3aGljaCBtZWFucyBpbmZpbml0ZSByZWN1cnNpb24gaWYgd2VcbiAgICAvLyB0cnkgdG8gbmFpdmVseSByZXNvbHZlLiBXZSBuZWVkIGEgcmVjdXJzaW9uIGJyZWFrZXIgaW4gdGhpcy5cbiAgICBjb25zdCBvcmlnaW5hbExvZ2ljYWxJZCA9IFN0YWNrLm9mKHRoaXMpLmdldExvZ2ljYWxJZCh0aGlzLmluc3RhbmNlKTtcbiAgICBsZXQgcmVjdXJzaW5nID0gZmFsc2U7XG4gICAgdGhpcy5pbnN0YW5jZS5vdmVycmlkZUxvZ2ljYWxJZChMYXp5LnVuY2FjaGVkU3RyaW5nKHtcbiAgICAgIHByb2R1Y2U6IChjb250ZXh0KSA9PiB7XG4gICAgICAgIGlmIChyZWN1cnNpbmcpIHsgcmV0dXJuIG9yaWdpbmFsTG9naWNhbElkOyB9XG4gICAgICAgIGlmICghKHByb3BzLnVzZXJEYXRhQ2F1c2VzUmVwbGFjZW1lbnQgPz8gcHJvcHMuaW5pdE9wdGlvbnMpKSB7IHJldHVybiBvcmlnaW5hbExvZ2ljYWxJZDsgfVxuXG4gICAgICAgIGNvbnN0IG1kNSA9IGNyeXB0by5jcmVhdGVIYXNoKCdtZDUnKTtcbiAgICAgICAgcmVjdXJzaW5nID0gdHJ1ZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBtZDUudXBkYXRlKEpTT04uc3RyaW5naWZ5KGNvbnRleHQucmVzb2x2ZSh0aGlzLnVzZXJEYXRhLnJlbmRlcigpKSkpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHJlY3Vyc2luZyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRpZ2VzdCA9IG1kNS5kaWdlc3QoJ2hleCcpLnNsaWNlKDAsIDE2KTtcbiAgICAgICAgcmV0dXJuIGAke29yaWdpbmFsTG9naWNhbElkfSR7ZGlnZXN0fWA7XG4gICAgICB9LFxuICAgIH0pKTtcblxuICAgIGlmIChwcm9wcy5yZXF1aXJlSW1kc3YyKSB7XG4gICAgICBBc3BlY3RzLm9mKHRoaXMpLmFkZChuZXcgSW5zdGFuY2VSZXF1aXJlSW1kc3YyQXNwZWN0KCkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgdGhlIHNlY3VyaXR5IGdyb3VwIHRvIHRoZSBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIHNlY3VyaXR5R3JvdXA6IFRoZSBzZWN1cml0eSBncm91cCB0byBhZGRcbiAgICovXG4gIHB1YmxpYyBhZGRTZWN1cml0eUdyb3VwKHNlY3VyaXR5R3JvdXA6IElTZWN1cml0eUdyb3VwKTogdm9pZCB7XG4gICAgdGhpcy5zZWN1cml0eUdyb3Vwcy5wdXNoKHNlY3VyaXR5R3JvdXApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBjb21tYW5kIHRvIHRoZSBzdGFydHVwIHNjcmlwdCBvZiB0aGUgaW5zdGFuY2UuXG4gICAqIFRoZSBjb21tYW5kIG11c3QgYmUgaW4gdGhlIHNjcmlwdGluZyBsYW5ndWFnZSBzdXBwb3J0ZWQgYnkgdGhlIGluc3RhbmNlJ3MgT1MgKGkuZS4gTGludXgvV2luZG93cykuXG4gICAqL1xuICBwdWJsaWMgYWRkVXNlckRhdGEoLi4uY29tbWFuZHM6IHN0cmluZ1tdKSB7XG4gICAgdGhpcy51c2VyRGF0YS5hZGRDb21tYW5kcyguLi5jb21tYW5kcyk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHN0YXRlbWVudCB0byB0aGUgSUFNIHJvbGUgYXNzdW1lZCBieSB0aGUgaW5zdGFuY2UuXG4gICAqL1xuICBwdWJsaWMgYWRkVG9Sb2xlUG9saWN5KHN0YXRlbWVudDogaWFtLlBvbGljeVN0YXRlbWVudCkge1xuICAgIHRoaXMucm9sZS5hZGRUb1ByaW5jaXBhbFBvbGljeShzdGF0ZW1lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZSBhIENsb3VkRm9ybWF0aW9uIEluaXQgY29uZmlndXJhdGlvbiBhdCBpbnN0YW5jZSBzdGFydHVwXG4gICAqXG4gICAqIFRoaXMgZG9lcyB0aGUgZm9sbG93aW5nOlxuICAgKlxuICAgKiAtIEF0dGFjaGVzIHRoZSBDbG91ZEZvcm1hdGlvbiBJbml0IG1ldGFkYXRhIHRvIHRoZSBJbnN0YW5jZSByZXNvdXJjZS5cbiAgICogLSBBZGQgY29tbWFuZHMgdG8gdGhlIGluc3RhbmNlIFVzZXJEYXRhIHRvIHJ1biBgY2ZuLWluaXRgIGFuZCBgY2ZuLXNpZ25hbGAuXG4gICAqIC0gVXBkYXRlIHRoZSBpbnN0YW5jZSdzIENyZWF0aW9uUG9saWN5IHRvIHdhaXQgZm9yIHRoZSBgY2ZuLXNpZ25hbGAgY29tbWFuZHMuXG4gICAqL1xuICBwcml2YXRlIGFwcGx5Q2xvdWRGb3JtYXRpb25Jbml0KGluaXQ6IENsb3VkRm9ybWF0aW9uSW5pdCwgb3B0aW9uczogQXBwbHlDbG91ZEZvcm1hdGlvbkluaXRPcHRpb25zID0ge30pIHtcbiAgICBpbml0LmF0dGFjaCh0aGlzLmluc3RhbmNlLCB7XG4gICAgICBwbGF0Zm9ybTogdGhpcy5vc1R5cGUsXG4gICAgICBpbnN0YW5jZVJvbGU6IHRoaXMucm9sZSxcbiAgICAgIHVzZXJEYXRhOiB0aGlzLnVzZXJEYXRhLFxuICAgICAgY29uZmlnU2V0czogb3B0aW9ucy5jb25maWdTZXRzLFxuICAgICAgZW1iZWRGaW5nZXJwcmludDogb3B0aW9ucy5lbWJlZEZpbmdlcnByaW50LFxuICAgICAgcHJpbnRMb2c6IG9wdGlvbnMucHJpbnRMb2csXG4gICAgICBpZ25vcmVGYWlsdXJlczogb3B0aW9ucy5pZ25vcmVGYWlsdXJlcyxcbiAgICAgIGluY2x1ZGVSb2xlOiBvcHRpb25zLmluY2x1ZGVSb2xlLFxuICAgICAgaW5jbHVkZVVybDogb3B0aW9ucy5pbmNsdWRlVXJsLFxuICAgIH0pO1xuICAgIHRoaXMud2FpdEZvclJlc291cmNlU2lnbmFsKG9wdGlvbnMudGltZW91dCA/PyBEdXJhdGlvbi5taW51dGVzKDUpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXYWl0IGZvciBhIHNpbmdsZSBhZGRpdGlvbmFsIHJlc291cmNlIHNpZ25hbFxuICAgKlxuICAgKiBBZGQgMSB0byB0aGUgY3VycmVudCBSZXNvdXJjZVNpZ25hbCBDb3VudCBhbmQgYWRkIHRoZSBnaXZlbiB0aW1lb3V0IHRvIHRoZSBjdXJyZW50IHRpbWVvdXQuXG4gICAqXG4gICAqIFVzZSB0aGlzIHRvIHBhdXNlIHRoZSBDbG91ZEZvcm1hdGlvbiBkZXBsb3ltZW50IHRvIHdhaXQgZm9yIHRoZSBpbnN0YW5jZXNcbiAgICogaW4gdGhlIEF1dG9TY2FsaW5nR3JvdXAgdG8gcmVwb3J0IHN1Y2Nlc3NmdWwgc3RhcnR1cCBkdXJpbmdcbiAgICogY3JlYXRpb24gYW5kIHVwZGF0ZXMuIFRoZSBVc2VyRGF0YSBzY3JpcHQgbmVlZHMgdG8gaW52b2tlIGBjZm4tc2lnbmFsYFxuICAgKiB3aXRoIGEgc3VjY2VzcyBvciBmYWlsdXJlIGNvZGUgYWZ0ZXIgaXQgaXMgZG9uZSBzZXR0aW5nIHVwIHRoZSBpbnN0YW5jZS5cbiAgICovXG4gIHByaXZhdGUgd2FpdEZvclJlc291cmNlU2lnbmFsKHRpbWVvdXQ6IER1cmF0aW9uKSB7XG4gICAgY29uc3Qgb2xkUmVzb3VyY2VTaWduYWwgPSB0aGlzLmluc3RhbmNlLmNmbk9wdGlvbnMuY3JlYXRpb25Qb2xpY3k/LnJlc291cmNlU2lnbmFsO1xuICAgIHRoaXMuaW5zdGFuY2UuY2ZuT3B0aW9ucy5jcmVhdGlvblBvbGljeSA9IHtcbiAgICAgIC4uLnRoaXMuaW5zdGFuY2UuY2ZuT3B0aW9ucy5jcmVhdGlvblBvbGljeSxcbiAgICAgIHJlc291cmNlU2lnbmFsOiB7XG4gICAgICAgIGNvdW50OiAob2xkUmVzb3VyY2VTaWduYWw/LmNvdW50ID8/IDApICsgMSxcbiAgICAgICAgdGltZW91dDogKG9sZFJlc291cmNlU2lnbmFsPy50aW1lb3V0ID8gRHVyYXRpb24ucGFyc2Uob2xkUmVzb3VyY2VTaWduYWw/LnRpbWVvdXQpLnBsdXModGltZW91dCkgOiB0aW1lb3V0KS50b0lzb1N0cmluZygpLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGx5IENsb3VkRm9ybWF0aW9uIHVwZGF0ZSBwb2xpY2llcyBmb3IgdGhlIGluc3RhbmNlXG4gICAqL1xuICBwcml2YXRlIGFwcGx5VXBkYXRlUG9saWNpZXMocHJvcHM6IEluc3RhbmNlUHJvcHMpIHtcbiAgICBpZiAocHJvcHMucmVzb3VyY2VTaWduYWxUaW1lb3V0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuaW5zdGFuY2UuY2ZuT3B0aW9ucy5jcmVhdGlvblBvbGljeSA9IHtcbiAgICAgICAgLi4udGhpcy5pbnN0YW5jZS5jZm5PcHRpb25zLmNyZWF0aW9uUG9saWN5LFxuICAgICAgICByZXNvdXJjZVNpZ25hbDoge1xuICAgICAgICAgIHRpbWVvdXQ6IHByb3BzLnJlc291cmNlU2lnbmFsVGltZW91dCAmJiBwcm9wcy5yZXNvdXJjZVNpZ25hbFRpbWVvdXQudG9Jc29TdHJpbmcoKSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYXBwbHlpbmcgQ2xvdWRGb3JtYXRpb24gaW5pdCB0byBhbiBpbnN0YW5jZSBvciBpbnN0YW5jZSBncm91cFxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwcGx5Q2xvdWRGb3JtYXRpb25Jbml0T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBDb25maWdTZXQgdG8gYWN0aXZhdGVcbiAgICpcbiAgICogQGRlZmF1bHQgWydkZWZhdWx0J11cbiAgICovXG4gIHJlYWRvbmx5IGNvbmZpZ1NldHM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGltZW91dCB3YWl0aW5nIGZvciB0aGUgY29uZmlndXJhdGlvbiB0byBiZSBhcHBsaWVkXG4gICAqXG4gICAqIEBkZWZhdWx0IER1cmF0aW9uLm1pbnV0ZXMoNSlcbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXQ/OiBEdXJhdGlvbjtcblxuICAvKipcbiAgICogRm9yY2UgaW5zdGFuY2UgcmVwbGFjZW1lbnQgYnkgZW1iZWRkaW5nIGEgY29uZmlnIGZpbmdlcnByaW50XG4gICAqXG4gICAqIElmIGB0cnVlYCAodGhlIGRlZmF1bHQpLCBhIGhhc2ggb2YgdGhlIGNvbmZpZyB3aWxsIGJlIGVtYmVkZGVkIGludG8gdGhlXG4gICAqIFVzZXJEYXRhLCBzbyB0aGF0IGlmIHRoZSBjb25maWcgY2hhbmdlcywgdGhlIFVzZXJEYXRhIGNoYW5nZXMuXG4gICAqXG4gICAqIC0gSWYgdGhlIEVDMiBpbnN0YW5jZSBpcyBpbnN0YW5jZS1zdG9yZSBiYWNrZWQgb3JcbiAgICogICBgdXNlckRhdGFDYXVzZXNSZXBsYWNlbWVudGAgaXMgc2V0LCB0aGlzIHdpbGwgY2F1c2UgdGhlIGluc3RhbmNlIHRvIGJlXG4gICAqICAgcmVwbGFjZWQgYW5kIHRoZSBuZXcgY29uZmlndXJhdGlvbiB0byBiZSBhcHBsaWVkLlxuICAgKiAtIElmIHRoZSBpbnN0YW5jZSBpcyBFQlMtYmFja2VkIGFuZCBgdXNlckRhdGFDYXVzZXNSZXBsYWNlbWVudGAgaXMgbm90XG4gICAqICAgc2V0LCB0aGUgY2hhbmdlIG9mIFVzZXJEYXRhIHdpbGwgbWFrZSB0aGUgaW5zdGFuY2UgcmVzdGFydCBidXQgbm90IGJlXG4gICAqICAgcmVwbGFjZWQsIGFuZCB0aGUgY29uZmlndXJhdGlvbiB3aWxsIG5vdCBiZSBhcHBsaWVkIGF1dG9tYXRpY2FsbHkuXG4gICAqXG4gICAqIElmIGBmYWxzZWAsIG5vIGhhc2ggd2lsbCBiZSBlbWJlZGRlZCwgYW5kIGlmIHRoZSBDbG91ZEZvcm1hdGlvbiBJbml0XG4gICAqIGNvbmZpZyBjaGFuZ2VzIG5vdGhpbmcgd2lsbCBoYXBwZW4gdG8gdGhlIHJ1bm5pbmcgaW5zdGFuY2UuIElmIGFcbiAgICogY29uZmlnIHVwZGF0ZSBpbnRyb2R1Y2VzIGVycm9ycywgeW91IHdpbGwgbm90IG5vdGljZSB1bnRpbCBhZnRlciB0aGVcbiAgICogQ2xvdWRGb3JtYXRpb24gZGVwbG95bWVudCBzdWNjZXNzZnVsbHkgZmluaXNoZXMgYW5kIHRoZSBuZXh0IGluc3RhbmNlXG4gICAqIGZhaWxzIHRvIGxhdW5jaC5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgZW1iZWRGaW5nZXJwcmludD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFByaW50IHRoZSByZXN1bHRzIG9mIHJ1bm5pbmcgY2ZuLWluaXQgdG8gdGhlIEluc3RhbmNlIFN5c3RlbSBMb2dcbiAgICpcbiAgICogQnkgZGVmYXVsdCwgdGhlIG91dHB1dCBvZiBydW5uaW5nIGNmbi1pbml0IGlzIHdyaXR0ZW4gdG8gYSBsb2cgZmlsZVxuICAgKiBvbiB0aGUgaW5zdGFuY2UuIFNldCB0aGlzIHRvIGB0cnVlYCB0byBwcmludCBpdCB0byB0aGUgU3lzdGVtIExvZ1xuICAgKiAodmlzaWJsZSBmcm9tIHRoZSBFQzIgQ29uc29sZSksIGBmYWxzZWAgdG8gbm90IHByaW50IGl0LlxuICAgKlxuICAgKiAoQmUgYXdhcmUgdGhhdCB0aGUgc3lzdGVtIGxvZyBpcyByZWZyZXNoZWQgYXQgY2VydGFpbiBwb2ludHMgaW5cbiAgICogdGltZSBvZiB0aGUgaW5zdGFuY2UgbGlmZSBjeWNsZSwgYW5kIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG1heVxuICAgKiBub3QgYWx3YXlzIHNob3cgdXApLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBwcmludExvZz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIERvbid0IGZhaWwgdGhlIGluc3RhbmNlIGNyZWF0aW9uIHdoZW4gY2ZuLWluaXQgZmFpbHNcbiAgICpcbiAgICogWW91IGNhbiB1c2UgdGhpcyB0byBwcmV2ZW50IENsb3VkRm9ybWF0aW9uIGZyb20gcm9sbGluZyBiYWNrIHdoZW5cbiAgICogaW5zdGFuY2VzIGZhaWwgdG8gc3RhcnQgdXAsIHRvIGhlbHAgaW4gZGVidWdnaW5nLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgaWdub3JlRmFpbHVyZXM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJbmNsdWRlIC0tdXJsIGFyZ3VtZW50IHdoZW4gcnVubmluZyBjZm4taW5pdCBhbmQgY2ZuLXNpZ25hbCBjb21tYW5kc1xuICAgKlxuICAgKiBUaGlzIHdpbGwgYmUgdGhlIGNsb3VkZm9ybWF0aW9uIGVuZHBvaW50IGluIHRoZSBkZXBsb3llZCByZWdpb25cbiAgICogZS5nLiBodHRwczovL2Nsb3VkZm9ybWF0aW9uLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBpbmNsdWRlVXJsPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogSW5jbHVkZSAtLXJvbGUgYXJndW1lbnQgd2hlbiBydW5uaW5nIGNmbi1pbml0IGFuZCBjZm4tc2lnbmFsIGNvbW1hbmRzXG4gICAqXG4gICAqIFRoaXMgd2lsbCBiZSB0aGUgSUFNIGluc3RhbmNlIHByb2ZpbGUgYXR0YWNoZWQgdG8gdGhlIEVDMiBpbnN0YW5jZVxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgaW5jbHVkZVJvbGU/OiBib29sZWFuO1xufVxuIl19