UNPKG

@renovosolutions/cdk-library-cloudwatch-alarms

Version:

AWS CDK Construct Library to automatically create CloudWatch Alarms for resources in a CDK app based on resource type.

238 lines 39 kB
"use strict"; var _a, _b, _c, _d, _e; Object.defineProperty(exports, "__esModule", { value: true }); exports.Ec2RecommendedAlarmsAspect = exports.Instance = exports.Ec2InstanceRecommendedAlarms = exports.Ec2InstanceStatusCheckFailedAlarm = exports.Ec2InstanceCpuUtilizationAlarm = exports.Ec2RecommendedAlarmsMetrics = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const constructs_1 = require("constructs"); const common_1 = require("./common"); /** * The recommended metrics for EC2 alarms. */ var Ec2RecommendedAlarmsMetrics; (function (Ec2RecommendedAlarmsMetrics) { /** * The percentage of physical CPU time that Amazon EC2 uses to run the EC2 instance, which includes * time spent to run both the user code and the Amazon EC2 code. */ Ec2RecommendedAlarmsMetrics["CPU_UTILIZATION"] = "CPUUtilization"; /** * Reports whether the instance has passed all status checks in the last minute. * This metric can be either 0 (passed) or 1 (failed). By default, this metric is available at * a 1-minute frequency at no charge. */ Ec2RecommendedAlarmsMetrics["STATUS_CHECK_FAILED"] = "StatusCheckFailed"; })(Ec2RecommendedAlarmsMetrics || (exports.Ec2RecommendedAlarmsMetrics = Ec2RecommendedAlarmsMetrics = {})); /** * This alarm helps to monitor the CPU utilization of an EC2 instance. * * Depending on the application, consistently high utilization levels might be normal. But if performance is degraded, * and the application is not constrained by disk I/O, memory, or network resources, then a maxed-out CPU might indicate * a resource bottleneck or application performance problems. High CPU utilization might indicate that an upgrade to a * more CPU intensive instance is required. If detailed monitoring is enabled, you can change the period to 60 seconds * instead of 300 seconds. For more information, see Enable or turn off detailed monitoring for your instances. * * The alarm is triggered when the percentage exceeds % threshold. */ class Ec2InstanceCpuUtilizationAlarm extends aws_cdk_lib_1.aws_cloudwatch.Alarm { constructor(scope, id, props) { const alarmName = props.alarmName ?? `${props.instance.instanceId} - ${Ec2RecommendedAlarmsMetrics.CPU_UTILIZATION}`; const period = props.period ?? aws_cdk_lib_1.Duration.minutes(5); const evaluationPeriods = props.evaluationPeriods ?? 3; const datapointsToAlarm = props.datapointsToAlarm ?? 3; const threshold = props.threshold ?? 80; const treatMissingData = props.treatMissingData ?? aws_cdk_lib_1.aws_cloudwatch.TreatMissingData.MISSING; const alarmDescription = props.alarmDescription ?? 'This alarm is used to detect high CPU utilization.'; (0, common_1.validateTotalAlarmPeriod)(period, evaluationPeriods, alarmName); super(scope, id, { alarmName, metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({ namespace: 'AWS/EC2', metricName: Ec2RecommendedAlarmsMetrics.CPU_UTILIZATION, dimensionsMap: { InstanceId: props.instance.instanceId, }, period, statistic: 'Average', }), threshold, evaluationPeriods, datapointsToAlarm, treatMissingData, comparisonOperator: aws_cdk_lib_1.aws_cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD, alarmDescription, }); if (props.alarmAction) this.addAlarmAction(props.alarmAction); if (props.okAction) this.addOkAction(props.okAction); if (props.insufficientDataAction) this.addInsufficientDataAction(props.insufficientDataAction); } } exports.Ec2InstanceCpuUtilizationAlarm = Ec2InstanceCpuUtilizationAlarm; _a = JSII_RTTI_SYMBOL_1; Ec2InstanceCpuUtilizationAlarm[_a] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.Ec2InstanceCpuUtilizationAlarm", version: "0.0.13" }; ; /** * This alarm helps to monitor both system status checks and instance status checks. * * If either type of status check fails, then this alarm should be in ALARM state. * * The alarm is triggered when the status reported is greater or equal to threshold. */ class Ec2InstanceStatusCheckFailedAlarm extends aws_cdk_lib_1.aws_cloudwatch.Alarm { constructor(scope, id, props) { const alarmName = props.alarmName ?? `${props.instance.instanceId} - ${Ec2RecommendedAlarmsMetrics.STATUS_CHECK_FAILED}`; const period = props.period ?? aws_cdk_lib_1.Duration.minutes(5); const evaluationPeriods = props.evaluationPeriods ?? 2; const datapointsToAlarm = props.datapointsToAlarm ?? 2; const threshold = props.threshold ?? 1; const treatMissingData = props.treatMissingData ?? aws_cdk_lib_1.aws_cloudwatch.TreatMissingData.MISSING; const alarmDescription = props.alarmDescription ?? 'This alarm is used to detect the underlying problems with instances,' + ' including both system status check failures and instance status check failures.'; (0, common_1.validateTotalAlarmPeriod)(period, evaluationPeriods, alarmName); super(scope, id, { alarmName, metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({ namespace: 'AWS/EC2', metricName: Ec2RecommendedAlarmsMetrics.STATUS_CHECK_FAILED, dimensionsMap: { InstanceId: props.instance.instanceId, }, period, statistic: 'Maximum', }), threshold, evaluationPeriods, datapointsToAlarm, treatMissingData, comparisonOperator: aws_cdk_lib_1.aws_cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD, alarmDescription, }); if (props.alarmAction) this.addAlarmAction(props.alarmAction); if (props.okAction) this.addOkAction(props.okAction); if (props.insufficientDataAction) this.addInsufficientDataAction(props.insufficientDataAction); } } exports.Ec2InstanceStatusCheckFailedAlarm = Ec2InstanceStatusCheckFailedAlarm; _b = JSII_RTTI_SYMBOL_1; Ec2InstanceStatusCheckFailedAlarm[_b] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.Ec2InstanceStatusCheckFailedAlarm", version: "0.0.13" }; ; /** * A construct that creates the recommended alarms for an EC2 Instance. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#EC2 */ class Ec2InstanceRecommendedAlarms extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); if (!props.excludeAlarms?.includes(Ec2RecommendedAlarmsMetrics.CPU_UTILIZATION)) { this.alarmCpuUtilization = new Ec2InstanceCpuUtilizationAlarm(this, `${props.instance.node.id}_CPUUtilization`, { instance: props.instance, treatMissingData: props.treatMissingData, ...props.configCpuUtilizationAlarm, }); if (props.defaultAlarmAction && !props.configCpuUtilizationAlarm?.alarmAction) { this.alarmCpuUtilization.addAlarmAction(props.defaultAlarmAction); } if (props.defaultOkAction && !props.configCpuUtilizationAlarm?.okAction) { this.alarmCpuUtilization.addOkAction(props.defaultOkAction); } if (props.defaultInsufficientDataAction && !props.configCpuUtilizationAlarm?.insufficientDataAction) { this.alarmCpuUtilization.addInsufficientDataAction(props.defaultInsufficientDataAction); } } if (!props.excludeAlarms?.includes(Ec2RecommendedAlarmsMetrics.STATUS_CHECK_FAILED)) { this.alarmStatusCheckFailed = new Ec2InstanceStatusCheckFailedAlarm(this, `${props.instance.node.id}_StatusCheckFailed`, { instance: props.instance, treatMissingData: props.treatMissingData, ...props.configStatusCheckFailedAlarm, }); if (props.defaultAlarmAction && !props.configStatusCheckFailedAlarm?.alarmAction) { this.alarmStatusCheckFailed.addAlarmAction(props.defaultAlarmAction); } if (props.defaultOkAction && !props.configStatusCheckFailedAlarm?.okAction) { this.alarmStatusCheckFailed.addOkAction(props.defaultOkAction); } if (props.defaultInsufficientDataAction && !props.configStatusCheckFailedAlarm?.insufficientDataAction) { this.alarmStatusCheckFailed.addInsufficientDataAction(props.defaultInsufficientDataAction); } } } } exports.Ec2InstanceRecommendedAlarms = Ec2InstanceRecommendedAlarms; _c = JSII_RTTI_SYMBOL_1; Ec2InstanceRecommendedAlarms[_c] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.Ec2InstanceRecommendedAlarms", version: "0.0.13" }; /** * An extension for the Instance construct that provides methods * to create recommended alarms. */ class Instance extends aws_cdk_lib_1.aws_ec2.Instance { constructor(scope, id, props) { super(scope, id, props); } /** * Creates an alarm that monitors the CPUUtilization for the EC2 instance. */ alarmCpuUtilization(props) { return new Ec2InstanceCpuUtilizationAlarm(this, 'CPUUtilizationAlarm', { instance: this, ...props, }); } /** * Creates an alarm that monitors the StatusCheckFailed for the EC2 instance. */ alarmStatusCheckFailed(props) { return new Ec2InstanceStatusCheckFailedAlarm(this, 'StatusCheckFailedAlarm', { instance: this, ...props, }); } /** * Creates the recommended alarms for the EC2 Instance. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#EC2 */ applyRecommendedAlarms(props) { return new Ec2InstanceRecommendedAlarms(this, 'Ec2InstanceRecommendedAlarms', { instance: this, ...props, }); } } exports.Instance = Instance; _d = JSII_RTTI_SYMBOL_1; Instance[_d] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.Instance", version: "0.0.13" }; /** * Configures the recommended alarms for an EC2 Instance. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#EC2 */ class Ec2RecommendedAlarmsAspect { constructor(props) { this.props = props; } visit(node) { if (node instanceof aws_cdk_lib_1.aws_ec2.Instance) { if (this.props?.excludeResources && this.props.excludeResources.includes(node.node.id)) { return; } else { const instance = node; new Ec2InstanceRecommendedAlarms(instance, 'Ec2InstanceRecommendedAlarmsFromAspect', { instance, ...this.props, }); } } } } exports.Ec2RecommendedAlarmsAspect = Ec2RecommendedAlarmsAspect; _e = JSII_RTTI_SYMBOL_1; Ec2RecommendedAlarmsAspect[_e] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.Ec2RecommendedAlarmsAspect", version: "0.0.13" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWMyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2VjMi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQUtxQjtBQUNyQiwyQ0FBbUQ7QUFDbkQscUNBQW9FO0FBRXBFOztHQUVHO0FBQ0gsSUFBWSwyQkFZWDtBQVpELFdBQVksMkJBQTJCO0lBQ3JDOzs7T0FHRztJQUNILGlFQUFrQyxDQUFBO0lBQ2xDOzs7O09BSUc7SUFDSCx3RUFBeUMsQ0FBQTtBQUMzQyxDQUFDLEVBWlcsMkJBQTJCLDJDQUEzQiwyQkFBMkIsUUFZdEM7QUFzRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQWEsOEJBQStCLFNBQVEsNEJBQVUsQ0FBQyxLQUFLO0lBQ2xFLFlBQVksS0FBaUIsRUFBRSxFQUFVLEVBQUUsS0FBMEM7UUFDbkYsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsSUFBSSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsVUFBVSxNQUFNLDJCQUEyQixDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3JILE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLElBQUksc0JBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkQsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUMsaUJBQWlCLElBQUksQ0FBQyxDQUFDO1FBQ3ZELE1BQU0saUJBQWlCLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixJQUFJLENBQUMsQ0FBQztRQUN2RCxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FBUyxJQUFJLEVBQUUsQ0FBQztRQUN4QyxNQUFNLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsSUFBSSw0QkFBVSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQztRQUN2RixNQUFNLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsSUFBSSxvREFBb0QsQ0FBQztRQUV4RyxJQUFBLGlDQUF3QixFQUFDLE1BQU0sRUFBRSxpQkFBaUIs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RSxDQUFDO2dCQUN2RixPQUFPO1lBQ1QsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sUUFBUSxHQUFHLElBQW9CLENBQUM7Z0JBRXRDLElBQUksNEJBQTRCLENBQUMsUUFBUSxFQUFFLHdDQUF3QyxFQUFFO29CQUNuRixRQUFRO29CQUNSLEdBQUcsSUFBSSxDQUFDLEtBQUs7aUJBQ2QsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDOztBQWhCSCxnRUFpQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBJQXNwZWN0LFxuICBhd3NfZWMyIGFzIGVjMixcbiAgYXdzX2Nsb3Vkd2F0Y2ggYXMgY2xvdWR3YXRjaCxcbiAgRHVyYXRpb24sXG59IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IENvbnN0cnVjdCwgSUNvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQWxhcm1CYXNlUHJvcHMsIHZhbGlkYXRlVG90YWxBbGFybVBlcmlvZCB9IGZyb20gJy4vY29tbW9uJztcblxuLyoqXG4gKiBUaGUgcmVjb21tZW5kZWQgbWV0cmljcyBmb3IgRUMyIGFsYXJtcy5cbiAqL1xuZXhwb3J0IGVudW0gRWMyUmVjb21tZW5kZWRBbGFybXNNZXRyaWNzIHtcbiAgLyoqXG4gICAqIFRoZSBwZXJjZW50YWdlIG9mIHBoeXNpY2FsIENQVSB0aW1lIHRoYXQgQW1hem9uIEVDMiB1c2VzIHRvIHJ1biB0aGUgRUMyIGluc3RhbmNlLCB3aGljaCBpbmNsdWRlc1xuICAgKiB0aW1lIHNwZW50IHRvIHJ1biBib3RoIHRoZSB1c2VyIGNvZGUgYW5kIHRoZSBBbWF6b24gRUMyIGNvZGUuXG4gICAqL1xuICBDUFVfVVRJTElaQVRJT04gPSAnQ1BVVXRpbGl6YXRpb24nLFxuICAvKipcbiAgICogUmVwb3J0cyB3aGV0aGVyIHRoZSBpbnN0YW5jZSBoYXMgcGFzc2VkIGFsbCBzdGF0dXMgY2hlY2tzIGluIHRoZSBsYXN0IG1pbnV0ZS5cbiAgICogVGhpcyBtZXRyaWMgY2FuIGJlIGVpdGhlciAwIChwYXNzZWQpIG9yIDEgKGZhaWxlZCkuIEJ5IGRlZmF1bHQsIHRoaXMgbWV0cmljIGlzIGF2YWlsYWJsZSBhdFxuICAgKiBhIDEtbWludXRlIGZyZXF1ZW5jeSBhdCBubyBjaGFyZ2UuXG4gICAqL1xuICBTVEFUVVNfQ0hFQ0tfRkFJTEVEID0gJ1N0YXR1c0NoZWNrRmFpbGVkJyxcbn1cblxuLyoqXG4gKiBUaGUgY29tbW9uIG9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBhbGFybXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRWMyQWxhcm1CYXNlQ29uZmlnIGV4dGVuZHMgQWxhcm1CYXNlUHJvcHMge1xuICAvKipcbiAgICogVGhlIHBlcmlvZCBvdmVyIHdoaWNoIHRoZSBzcGVjaWZpZWQgc3RhdGlzdGljIGlzIGFwcGxpZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IER1cmF0aW9uLm1pbnV0ZXMoMSlcbiAgICovXG4gIHJlYWRvbmx5IHBlcmlvZD86IER1cmF0aW9uO1xufVxuXG4vKipcbiAqIFRoZSBjb21tb24gcHJvcGVydGllcyBmb3IgdGhlIEVDMiBJbnN0YW5jZSBhbGFybXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRWMySW5zdGFuY2VBbGFybVByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBFQzIgSW5zdGFuY2UgdG8gbW9uaXRvci5cbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbmNlOiBlYzIuSW5zdGFuY2U7XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIENQVVV0aWxpemF0aW9uIGFsYXJtLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVjMkNwdVV0aWxpemF0aW9uQWxhcm1Db25maWcgZXh0ZW5kcyBFYzJBbGFybUJhc2VDb25maWcge1xuICAvKipcbiAgICogVHlwaWNhbGx5LCB5b3UgY2FuIHNldCB0aGUgdGhyZXNob2xkIGZvciBDUFUgdXRpbGl6YXRpb24gdG8gNzAtODAlLiBIb3dldmVyLCB5b3UgY2FuXG4gICAqIGFkanVzdCB0aGlzIHZhbHVlIGJhc2VkIG9uIHlvdXIgYWNjZXB0YWJsZSBwZXJmb3JtYW5jZSBsZXZlbCBhbmQgd29ya2xvYWQgY2hhcmFjdGVyaXN0aWNzLlxuICAgKiBGb3Igc29tZSBzeXN0ZW1zLCBjb25zaXN0ZW50bHkgaGlnaCBDUFUgdXRpbGl6YXRpb24gbWF5IGJlIG5vcm1hbCBhbmQgbm90IGluZGljYXRlIGEgcHJvYmxlbSxcbiAgICogd2hpbGUgZm9yIG90aGVycywgaXQgbWF5IGJlIGNhdXNlIG9mIGNvbmNlcm4uIEFuYWx5emUgaGlzdG9yaWNhbCBDUFUgdXRpbGl6YXRpb24gZGF0YSB0b1xuICAgKiBpZGVudGlmeSB0aGUgdXNhZ2UsIGZpbmQgd2hhdCBDUFUgdXRpbGl6YXRpb24gaXMgYWNjZXB0YWJsZSBmb3IgeW91ciBzeXN0ZW0sIGFuZCBzZXQgdGhlXG4gICAqIHRocmVzaG9sZCBhY2NvcmRpbmdseS5cbiAgICpcbiAgICogQGRlZmF1bHQgODBcbiAgICovXG4gIHJlYWRvbmx5IHRocmVzaG9sZD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgcGVyaW9kcyBvdmVyIHdoaWNoIGRhdGEgaXMgY29tcGFyZWQgdG8gdGhlIHNwZWNpZmllZCB0aHJlc2hvbGQuXG4gICAqXG4gICAqIEBkZWZhdWx0IDNcbiAgICovXG4gIHJlYWRvbmx5IGV2YWx1YXRpb25QZXJpb2RzPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBkYXRhIHBvaW50cyB0aGF0IG11c3QgYmUgYnJlYWNoaW5nIHRvIHRyaWdnZXIgdGhlIGFsYXJtLlxuICAgKlxuICAgKiBAZGVmYXVsdCAzXG4gICAqL1xuICByZWFkb25seSBkYXRhcG9pbnRzVG9BbGFybT86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBhbGFybSBuYW1lLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGluc3RhbmNlSWQgKyAnIC0gQ1BVVXRpbGl6YXRpb24nXG4gICAqL1xuICByZWFkb25seSBhbGFybU5hbWU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgZGVzY3JpcHRpb24gb2YgdGhlIGFsYXJtLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFRoaXMgYWxhcm0gaXMgdXNlZCB0byBkZXRlY3QgaGlnaCBDUFUgdXRpbGl6YXRpb24uXG4gICAqL1xuICByZWFkb25seSBhbGFybURlc2NyaXB0aW9uPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRoZSBwcm9wZXJ0aWVzIGZvciB0aGUgRWMySW5zdGFuY2VDcHVVdGlsaXphdGlvbkFsYXJtIGNvbnN0cnVjdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFYzJJbnN0YW5jZUNwdVV0aWxpemF0aW9uQWxhcm1Qcm9wcyBleHRlbmRzIEVjMkluc3RhbmNlQWxhcm1Qcm9wcywgRWMyQ3B1VXRpbGl6YXRpb25BbGFybUNvbmZpZyB7fVxuXG4vKipcbiAqIFRoaXMgYWxhcm0gaGVscHMgdG8gbW9uaXRvciB0aGUgQ1BVIHV0aWxpemF0aW9uIG9mIGFuIEVDMiBpbnN0YW5jZS5cbiAqXG4gKiBEZXBlbmRpbmcgb24gdGhlIGFwcGxpY2F0aW9uLCBjb25zaXN0ZW50bHkgaGlnaCB1dGlsaXphdGlvbiBsZXZlbHMgbWlnaHQgYmUgbm9ybWFsLiBCdXQgaWYgcGVyZm9ybWFuY2UgaXMgZGVncmFkZWQsXG4gKiBhbmQgdGhlIGFwcGxpY2F0aW9uIGlzIG5vdCBjb25zdHJhaW5lZCBieSBkaXNrIEkvTywgbWVtb3J5LCBvciBuZXR3b3JrIHJlc291cmNlcywgdGhlbiBhIG1heGVkLW91dCBDUFUgbWlnaHQgaW5kaWNhdGVcbiAqIGEgcmVzb3VyY2UgYm90dGxlbmVjayBvciBhcHBsaWNhdGlvbiBwZXJmb3JtYW5jZSBwcm9ibGVtcy4gSGlnaCBDUFUgdXRpbGl6YXRpb24gbWlnaHQgaW5kaWNhdGUgdGhhdCBhbiB1cGdyYWRlIHRvIGFcbiAqIG1vcmUgQ1BVIGludGVuc2l2ZSBpbnN0YW5jZSBpcyByZXF1aXJlZC4gSWYgZGV0YWlsZWQgbW9uaXRvcmluZyBpcyBlbmFibGVkLCB5b3UgY2FuIGNoYW5nZSB0aGUgcGVyaW9kIHRvIDYwIHNlY29uZHNcbiAqIGluc3RlYWQgb2YgMzAwIHNlY29uZHMuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgRW5hYmxlIG9yIHR1cm4gb2ZmIGRldGFpbGVkIG1vbml0b3JpbmcgZm9yIHlvdXIgaW5zdGFuY2VzLlxuICpcbiAqIFRoZSBhbGFybSBpcyB0cmlnZ2VyZWQgd2hlbiB0aGUgcGVyY2VudGFnZSBleGNlZWRzICUgdGhyZXNob2xkLlxuICovXG5leHBvcnQgY2xhc3MgRWMySW5zdGFuY2VDcHVVdGlsaXphdGlvbkFsYXJtIGV4dGVuZHMgY2xvdWR3YXRjaC5BbGFybSB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBJQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogRWMySW5zdGFuY2VDcHVVdGlsaXphdGlvbkFsYXJtUHJvcHMpIHtcbiAgICBjb25zdCBhbGFybU5hbWUgPSBwcm9wcy5hbGFybU5hbWUgPz8gYCR7cHJvcHMuaW5zdGFuY2UuaW5zdGFuY2VJZH0gLSAke0VjMlJlY29tbWVuZGVkQWxhcm1zTWV0cmljcy5DUFVfVVRJTElaQVRJT059YDtcbiAgICBjb25zdCBwZXJpb2QgPSBwcm9wcy5wZXJpb2QgPz8gRHVyYXRpb24ubWludXRlcyg1KTtcbiAgICBjb25zdCBldmFsdWF0aW9uUGVyaW9kcyA9IHByb3BzLmV2YWx1YXRpb25QZXJpb2RzID8/IDM7XG4gICAgY29uc3QgZGF0YXBvaW50c1RvQWxhcm0gPSBwcm9wcy5kYXRhcG9pbnRzVG9BbGFybSA/PyAzO1xuICAgIGNvbnN0IHRocmVzaG9sZCA9IHByb3BzLnRocmVzaG9sZCA/PyA4MDtcbiAgICBjb25zdCB0cmVhdE1pc3NpbmdEYXRhID0gcHJvcHMudHJlYXRNaXNzaW5nRGF0YSA/PyBjbG91ZHdhdGNoLlRyZWF0TWlzc2luZ0RhdGEuTUlTU0lORztcbiAgICBjb25zdCBhbGFybURlc2NyaXB0aW9uID0gcHJvcHMuYWxhcm1EZXNjcmlwdGlvbiA/PyAnVGhpcyBhbGFybSBpcyB1c2VkIHRvIGRldGVjdCBoaWdoIENQVSB1dGlsaXphdGlvbi4nO1xuXG4gICAgdmFsaWRhdGVUb3RhbEFsYXJtUGVyaW9kKHBlcmlvZCwgZXZhbHVhdGlvblBlcmlvZHMsIGFsYXJtTmFtZSk7XG5cbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIGFsYXJtTmFtZSxcbiAgICAgIG1ldHJpYzogbmV3IGNsb3Vkd2F0Y2guTWV0cmljKHtcbiAgICAgICAgbmFtZXNwYWNlOiAnQVdTL0VDMicsXG4gICAgICAgIG1ldHJpY05hbWU6IEVjMlJlY29tbWVuZGVkQWxhcm1zTWV0cmljcy5DUFVfVVRJTElaQVRJT04sXG4gICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICBJbnN0YW5jZUlkOiBwcm9wcy5pbnN0YW5jZS5pbnN0YW5jZUlkLFxuICAgICAgICB9LFxuICAgICAgICBwZXJpb2QsXG4gICAgICAgIHN0YXRpc3RpYzogJ0F2ZXJhZ2UnLFxuICAgICAgfSksXG4gICAgICB0aHJlc2hvbGQsXG4gICAgICBldmFsdWF0aW9uUGVyaW9kcyxcbiAgICAgIGRhdGFwb2ludHNUb0FsYXJtLFxuICAgICAgdHJlYXRNaXNzaW5nRGF0YSxcbiAgICAgIGNvbXBhcmlzb25PcGVyYXRvcjogY2xvdWR3YXRjaC5Db21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX1RIUkVTSE9MRCxcbiAgICAgIGFsYXJtRGVzY3JpcHRpb24sXG4gICAgfSk7XG5cbiAgICBpZiAocHJvcHMuYWxhcm1BY3Rpb24pIHRoaXMuYWRkQWxhcm1BY3Rpb24ocHJvcHMuYWxhcm1BY3Rpb24pO1xuICAgIGlmIChwcm9wcy5va0FjdGlvbikgdGhpcy5hZGRPa0FjdGlvbihwcm9wcy5va0FjdGlvbik7XG4gICAgaWYgKHByb3BzLmluc3VmZmljaWVudERhdGFBY3Rpb24pIHRoaXMuYWRkSW5zdWZmaWNpZW50RGF0YUFjdGlvbihwcm9wcy5pbnN1ZmZpY2llbnREYXRhQWN0aW9uKTtcbiAgfVxufTtcblxuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBTdGF0dXNDaGVja0ZhaWxlZCBhbGFybS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFYzJTdGF0dXNDaGVja0ZhaWxlZEFsYXJtQ29uZmlnIGV4dGVuZHMgRWMyQWxhcm1CYXNlQ29uZmlnIHtcbiAgLyoqXG4gICAqIFdoZW4gYSBzdGF0dXMgY2hlY2sgZmFpbHMsIHRoZSB2YWx1ZSBvZiB0aGlzIG1ldHJpYyBpcyAxLiBUaGUgdGhyZXNob2xkIGlzIHNldCBzbyB0aGF0IHdoZW5ldmVyIHRoZVxuICAgKiBzdGF0dXMgY2hlY2sgZmFpbHMsIHRoZSBhbGFybSBpcyBpbiBBTEFSTSBzdGF0ZS5cbiAgICpcbiAgICogQGRlZmF1bHQgMVxuICAgKi9cbiAgcmVhZG9ubHkgdGhyZXNob2xkPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBwZXJpb2RzIG92ZXIgd2hpY2ggZGF0YSBpcyBjb21wYXJlZCB0byB0aGUgc3BlY2lmaWVkIHRocmVzaG9sZC5cbiAgICpcbiAgICogQGRlZmF1bHQgMlxuICAgKi9cbiAgcmVhZG9ubHkgZXZhbHVhdGlvblBlcmlvZHM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIGRhdGEgcG9pbnRzIHRoYXQgbXVzdCBiZSBicmVhY2hpbmcgdG8gdHJpZ2dlciB0aGUgYWxhcm0uXG4gICAqXG4gICAqIEBkZWZhdWx0IDJcbiAgICovXG4gIHJlYWRvbmx5IGRhdGFwb2ludHNUb0FsYXJtPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGFsYXJtIG5hbWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gaW5zdGFuY2VJZCArICcgLSBTdGF0dXNDaGVja0ZhaWxlZCdcbiAgICovXG4gIHJlYWRvbmx5IGFsYXJtTmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgYWxhcm0uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gVGhpcyBhbGFybSBpcyB1c2VkIHRvIGRldGVjdCB0aGUgdW5kZXJseWluZyBwcm9ibGVtcyB3aXRoIGluc3RhbmNlcywgaW5jbHVkaW5nIGJvdGggc3lzdGVtXG4gICAqIHN0YXR1cyBjaGVjayBmYWlsdXJlcyBhbmQgaW5zdGFuY2Ugc3RhdHVzIGNoZWNrIGZhaWx1cmVzLlxuICAgKi9cbiAgcmVhZG9ubHkgYWxhcm1EZXNjcmlwdGlvbj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgcHJvcGVydGllcyBmb3IgdGhlIEVjMkluc3RhbmNlU3RhdHVzQ2hlY2tGYWlsZWRBbGFybSBjb25zdHJ1Y3QuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRWMySW5zdGFuY2VTdGF0dXNDaGVja0ZhaWxlZEFsYXJtUHJvcHMgZXh0ZW5kcyBFYzJJbnN0YW5jZUFsYXJtUHJvcHMsIEVjMlN0YXR1c0NoZWNrRmFpbGVkQWxhcm1Db25maWcge31cblxuLyoqXG4gKiBUaGlzIGFsYXJtIGhlbHBzIHRvIG1vbml0b3IgYm90aCBzeXN0ZW0gc3RhdHVzIGNoZWNrcyBhbmQgaW5zdGFuY2Ugc3RhdHVzIGNoZWNrcy5cbiAqXG4gKiBJZiBlaXRoZXIgdHlwZSBvZiBzdGF0dXMgY2hlY2sgZmFpbHMsIHRoZW4gdGhpcyBhbGFybSBzaG91bGQgYmUgaW4gQUxBUk0gc3RhdGUuXG4gKlxuICogVGhlIGFsYXJtIGlzIHRyaWdnZXJlZCB3aGVuIHRoZSBzdGF0dXMgcmVwb3J0ZWQgaXMgZ3JlYXRlciBvciBlcXVhbCB0byB0aHJlc2hvbGQuXG4gKi9cbmV4cG9ydCBjbGFzcyBFYzJJbnN0YW5jZVN0YXR1c0NoZWNrRmFpbGVkQWxhcm0gZXh0ZW5kcyBjbG91ZHdhdGNoLkFsYXJtIHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IElDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBFYzJJbnN0YW5jZVN0YXR1c0NoZWNrRmFpbGVkQWxhcm1Qcm9wcykge1xuICAgIGNvbnN0IGFsYXJtTmFtZSA9IHByb3BzLmFsYXJtTmFtZSA/PyBgJHtwcm9wcy5pbnN0YW5jZS5pbnN0YW5jZUlkfSAtICR7RWMyUmVjb21tZW5kZWRBbGFybXNNZXRyaWNzLlNUQVRVU19DSEVDS19GQUlMRUR9YDtcbiAgICBjb25zdCBwZXJpb2QgPSBwcm9wcy5wZXJpb2QgPz8gRHVyYXRpb24ubWludXRlcyg1KTtcbiAgICBjb25zdCBldmFsdWF0aW9uUGVyaW9kcyA9IHByb3BzLmV2YWx1YXRpb25QZXJpb2RzID8/IDI7XG4gICAgY29uc3QgZGF0YXBvaW50c1RvQWxhcm0gPSBwcm9wcy5kYXRhcG9pbnRzVG9BbGFybSA/PyAyO1xuICAgIGNvbnN0IHRocmVzaG9sZCA9IHByb3BzLnRocmVzaG9sZCA/PyAxO1xuICAgIGNvbnN0IHRyZWF0TWlzc2luZ0RhdGEgPSBwcm9wcy50cmVhdE1pc3NpbmdEYXRhID8/IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5NSVNTSU5HO1xuICAgIGNvbnN0IGFsYXJtRGVzY3JpcHRpb24gPSBwcm9wcy5hbGFybURlc2NyaXB0aW9uID8/ICdUaGlzIGFsYXJtIGlzIHVzZWQgdG8gZGV0ZWN0IHRoZSB1bmRlcmx5aW5nIHByb2JsZW1zIHdpdGggaW5zdGFuY2VzLCdcbiAgICAgICsgJyBpbmNsdWRpbmcgYm90aCBzeXN0ZW0gc3RhdHVzIGNoZWNrIGZhaWx1cmVzIGFuZCBpbnN0YW5jZSBzdGF0dXMgY2hlY2sgZmFpbHVyZXMuJztcblxuICAgIHZhbGlkYXRlVG90YWxBbGFybVBlcmlvZChwZXJpb2QsIGV2YWx1YXRpb25QZXJpb2RzLCBhbGFybU5hbWUpO1xuXG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBhbGFybU5hbWUsXG4gICAgICBtZXRyaWM6IG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICAgIG5hbWVzcGFjZTogJ0FXUy9FQzInLFxuICAgICAgICBtZXRyaWNOYW1lOiBFYzJSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3MuU1RBVFVTX0NIRUNLX0ZBSUxFRCxcbiAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgIEluc3RhbmNlSWQ6IHByb3BzLmluc3RhbmNlLmluc3RhbmNlSWQsXG4gICAgICAgIH0sXG4gICAgICAgIHBlcmlvZCxcbiAgICAgICAgc3RhdGlzdGljOiAnTWF4aW11bScsXG4gICAgICB9KSxcbiAgICAgIHRocmVzaG9sZCxcbiAgICAgIGV2YWx1YXRpb25QZXJpb2RzLFxuICAgICAgZGF0YXBvaW50c1RvQWxhcm0sXG4gICAgICB0cmVhdE1pc3NpbmdEYXRhLFxuICAgICAgY29tcGFyaXNvbk9wZXJhdG9yOiBjbG91ZHdhdGNoLkNvbXBhcmlzb25PcGVyYXRvci5HUkVBVEVSX1RIQU5fT1JfRVFVQUxfVE9fVEhSRVNIT0xELFxuICAgICAgYWxhcm1EZXNjcmlwdGlvbixcbiAgICB9KTtcblxuICAgIGlmIChwcm9wcy5hbGFybUFjdGlvbikgdGhpcy5hZGRBbGFybUFjdGlvbihwcm9wcy5hbGFybUFjdGlvbik7XG4gICAgaWYgKHByb3BzLm9rQWN0aW9uKSB0aGlzLmFkZE9rQWN0aW9uKHByb3BzLm9rQWN0aW9uKTtcbiAgICBpZiAocHJvcHMuaW5zdWZmaWNpZW50RGF0YUFjdGlvbikgdGhpcy5hZGRJbnN1ZmZpY2llbnREYXRhQWN0aW9uKHByb3BzLmluc3VmZmljaWVudERhdGFBY3Rpb24pO1xuICB9XG59O1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb25zIGZvciB0aGUgcmVjb21tZW5kZWQgYWxhcm1zIGZvciBhbiBFQzIgU2VydmljZS5cbiAqXG4gKiBEZWZhdWx0IGFjdGlvbnMgYXJlIG92ZXJyaWRkZW4gYnkgdGhlIGFjdGlvbnMgc3BlY2lmaWVkIGluIHRoZVxuICogaW5kaXZpZHVhbCBhbGFybSBjb25maWd1cmF0aW9ucy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFYzJJbnN0YW5jZVJlY29tbWVuZGVkQWxhcm1zQ29uZmlnIHtcbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IGFjdGlvbiB0byB0YWtlIHdoZW4gYW4gYWxhcm0gaXMgdHJpZ2dlcmVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vbmVcbiAgICovXG4gIHJlYWRvbmx5IGRlZmF1bHRBbGFybUFjdGlvbj86IGNsb3Vkd2F0Y2guSUFsYXJtQWN0aW9uO1xuICAvKipcbiAgICogVGhlIGRlZmF1bHQgYWN0aW9uIHRvIHRha2Ugd2hlbiBhbiBhbGFybSBlbnRlcnMgdGhlIG9rIHN0YXRlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vbmVcbiAgICovXG4gIHJlYWRvbmx5IGRlZmF1bHRPa0FjdGlvbj86IGNsb3Vkd2F0Y2guSUFsYXJtQWN0aW9uO1xuICAvKipcbiAgICogVGhlIGRlZmF1bHQgYWN0aW9uIHRvIHRha2Ugd2hlbiBhbiBhbGFybSBoYXMgaW5zdWZmaWNpZW50IGRhdGEuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm9uZVxuICAgKi9cbiAgcmVhZG9ubHkgZGVmYXVsdEluc3VmZmljaWVudERhdGFBY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvbjtcbiAgLyoqXG4gICAqIEhvdyB0byBoYW5kbGUgbWlzc2luZyBkYXRhIGZvciB0aGlzIGFsYXJtLlxuICAgKlxuICAgKiBAZGVmYXVsdCBUcmVhdE1pc3NpbmdEYXRhLk1JU1NJTkdcbiAgICovXG4gIHJlYWRvbmx5IHRyZWF0TWlzc2luZ0RhdGE/OiBjbG91ZHdhdGNoLlRyZWF0TWlzc2luZ0RhdGE7XG4gIC8qKlxuICAgKiBBbGFybSBtZXRyaWNzIHRvIGV4Y2x1ZGUgZnJvbSB0aGUgcmVjb21tZW5kZWQgYWxhcm1zLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vbmVcbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGVBbGFybXM/OiBFYzJSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3NbXTtcbiAgLyoqXG4gICAqIFRoZSByZXNvdXJjZXMgdG8gZXhjbHVkZSBmcm9tIHRoZSByZWNvbW1lbmRlZCBhbGFybXMuXG4gICAqXG4gICAqIFVzZSBhIHJlc291cmNlcyBpZCB0byBleGNsdWRlIGEgc3BlY2lmaWMgcmVzb3VyY2UuXG4gICAqL1xuICByZWFkb25seSBleGNsdWRlUmVzb3VyY2VzPzogc3RyaW5nW107XG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJhdGlvbiBmb3IgdGhlIENQVVV0aWxpemF0aW9uIGFsYXJtLlxuICAgKi9cbiAgcmVhZG9ubHkgY29uZmlnQ3B1VXRpbGl6YXRpb25BbGFybT86IEVjMkNwdVV0aWxpemF0aW9uQWxhcm1Db25maWc7XG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJhdGlvbiBmb3IgdGhlIFN0YXR1c0NoZWNrRmFpbGVkIGFsYXJtLlxuICAgKi9cbiAgcmVhZG9ubHkgY29uZmlnU3RhdHVzQ2hlY2tGYWlsZWRBbGFybT86IEVjMlN0YXR1c0NoZWNrRmFpbGVkQWxhcm1Db25maWc7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgdGhlIEVjMkluc3RhbmNlUmVjb21tZW5kZWRBbGFybXMgY29uc3RydWN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVjMkluc3RhbmNlUmVjb21tZW5kZWRBbGFybXNQcm9wcyBleHRlbmRzIEVjMkluc3RhbmNlUmVjb21tZW5kZWRBbGFybXNDb25maWcge1xuICAvKipcbiAgICogVGhlIEVDMiBJbnN0YW5jZSB0byBtb25pdG9yLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5zdGFuY2U6IGVjMi5JbnN0YW5jZTtcbn1cblxuLyoqXG4gKiBBIGNvbnN0cnVjdCB0aGF0IGNyZWF0ZXMgdGhlIHJlY29tbWVuZGVkIGFsYXJtcyBmb3IgYW4gRUMyIEluc3RhbmNlLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L21vbml0b3JpbmcvQmVzdF9QcmFjdGljZV9SZWNvbW1lbmRlZF9BbGFybXNfQVdTX1NlcnZpY2VzLmh0bWwjRUMyXG4gKi9cbmV4cG9ydCBjbGFzcyBFYzJJbnN0YW5jZVJlY29tbWVuZGVkQWxhcm1zIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgLyoqXG4gICAqIFRoZSBDUFVVdGlsaXphdGlvbiBhbGFybS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBhbGFybUNwdVV0aWxpemF0aW9uPzogRWMySW5zdGFuY2VDcHVVdGlsaXphdGlvbkFsYXJtO1xuXG4gIC8qKlxuICAgKiBUaGUgU3RhdHVzQ2hlY2tGYWlsZWQgYWxhcm0uXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYWxhcm1TdGF0dXNDaGVja0ZhaWxlZD86IEVjMkluc3RhbmNlU3RhdHVzQ2hlY2tGYWlsZWRBbGFybTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogRWMySW5zdGFuY2VSZWNvbW1lbmRlZEFsYXJtc1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGlmICghcHJvcHMuZXhjbHVkZUFsYXJtcz8uaW5jbHVkZXMoRWMyUmVjb21tZW5kZWRBbGFybXNNZXRyaWNzLkNQVV9VVElMSVpBVElPTikpIHtcbiAgICAgIHRoaXMuYWxhcm1DcHVVdGlsaXphdGlvbiA9IG5ldyBFYzJJbnN0YW5jZUNwdVV0aWxpemF0aW9uQWxhcm0odGhpcywgYCR7cHJvcHMuaW5zdGFuY2Uubm9kZS5pZH1fQ1BVVXRpbGl6YXRpb25gLCB7XG4gICAgICAgIGluc3RhbmNlOiBwcm9wcy5pbnN0YW5jZSxcbiAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogcHJvcHMudHJlYXRNaXNzaW5nRGF0YSxcbiAgICAgICAgLi4ucHJvcHMuY29uZmlnQ3B1VXRpbGl6YXRpb25BbGFybSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAocHJvcHMuZGVmYXVsdEFsYXJtQWN0aW9uICYmICFwcm9wcy5jb25maWdDcHVVdGlsaXphdGlvbkFsYXJtPy5hbGFybUFjdGlvbikge1xuICAgICAgICB0aGlzLmFsYXJtQ3B1VXRpbGl6YXRpb24uYWRkQWxhcm1BY3Rpb24ocHJvcHMuZGVmYXVsdEFsYXJtQWN0aW9uKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHByb3BzLmRlZmF1bHRPa0FjdGlvbiAmJiAhcHJvcHMuY29uZmlnQ3B1VXRpbGl6YXRpb25BbGFybT8ub2tBY3Rpb24pIHtcbiAgICAgICAgdGhpcy5hbGFybUNwdVV0aWxpemF0aW9uLmFkZE9rQWN0aW9uKHByb3BzLmRlZmF1bHRPa0FjdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wcy5kZWZhdWx0SW5zdWZmaWNpZW50RGF0YUFjdGlvbiAmJiAhcHJvcHMuY29uZmlnQ3B1VXRpbGl6YXRpb25BbGFybT8uaW5zdWZmaWNpZW50RGF0YUFjdGlvbikge1xuICAgICAgICB0aGlzLmFsYXJtQ3B1VXRpbGl6YXRpb24uYWRkSW5zdWZmaWNpZW50RGF0YUFjdGlvbihwcm9wcy5kZWZhdWx0SW5zdWZmaWNpZW50RGF0YUFjdGlvbik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFwcm9wcy5leGNsdWRlQWxhcm1zPy5pbmNsdWRlcyhFYzJSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3MuU1RBVFVTX0NIRUNLX0ZBSUxFRCkpIHtcbiAgICAgIHRoaXMuYWxhcm1TdGF0dXNDaGVja0ZhaWxlZCA9IG5ldyBFYzJJbnN0YW5jZVN0YXR1c0NoZWNrRmFpbGVkQWxhcm0odGhpcywgYCR7cHJvcHMuaW5zdGFuY2Uubm9kZS5pZH1fU3RhdHVzQ2hlY2tGYWlsZWRgLCB7XG4gICAgICAgIGluc3RhbmNlOiBwcm9wcy5pbnN0YW5jZSxcbiAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogcHJvcHMudHJlYXRNaXNzaW5nRGF0YSxcbiAgICAgICAgLi4ucHJvcHMuY29uZmlnU3RhdHVzQ2hlY2tGYWlsZWRBbGFybSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAocHJvcHMuZGVmYXVsdEFsYXJtQWN0aW9uICYmICFwcm9wcy5jb25maWdTdGF0dXNDaGVja0ZhaWxlZEFsYXJtPy5hbGFybUFjdGlvbikge1xuICAgICAgICB0aGlzLmFsYXJtU3RhdHVzQ2hlY2tGYWlsZWQuYWRkQWxhcm1BY3Rpb24ocHJvcHMuZGVmYXVsdEFsYXJtQWN0aW9uKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHByb3BzLmRlZmF1bHRPa0FjdGlvbiAmJiAhcHJvcHMuY29uZmlnU3RhdHVzQ2hlY2tGYWlsZWRBbGFybT8ub2tBY3Rpb24pIHtcbiAgICAgICAgdGhpcy5hbGFybVN0YXR1c0NoZWNrRmFpbGVkLmFkZE9rQWN0aW9uKHByb3BzLmRlZmF1bHRPa0FjdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wcy5kZWZhdWx0SW5zdWZmaWNpZW50RGF0YUFjdGlvbiAmJiAhcHJvcHMuY29uZmlnU3RhdHVzQ2hlY2tGYWlsZWRBbGFybT8uaW5zdWZmaWNpZW50RGF0YUFjdGlvbikge1xuICAgICAgICB0aGlzLmFsYXJtU3RhdHVzQ2hlY2tGYWlsZWQuYWRkSW5zdWZmaWNpZW50RGF0YUFjdGlvbihwcm9wcy5kZWZhdWx0SW5zdWZmaWNpZW50RGF0YUFjdGlvbik7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQW4gZXh0ZW5zaW9uIGZvciB0aGUgSW5zdGFuY2UgY29uc3RydWN0IHRoYXQgcHJvdmlkZXMgbWV0aG9kc1xuICogdG8gY3JlYXRlIHJlY29tbWVuZGVkIGFsYXJtcy5cbiAqL1xuZXhwb3J0IGNsYXNzIEluc3RhbmNlIGV4dGVuZHMgZWMyLkluc3RhbmNlIHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IGVjMi5JbnN0YW5jZVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCBwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBhbGFybSB0aGF0IG1vbml0b3JzIHRoZSBDUFVVdGlsaXphdGlvbiBmb3IgdGhlIEVDMiBpbnN0YW5jZS5cbiAgICovXG4gIHB1YmxpYyBhbGFybUNwdVV0aWxpemF0aW9uKHByb3BzPzogRWMyQ3B1VXRpbGl6YXRpb25BbGFybUNvbmZpZyk6IEVjMkluc3RhbmNlQ3B1VXRpbGl6YXRpb25BbGFybSB7XG4gICAgcmV0dXJuIG5ldyBFYzJJbnN0YW5jZUNwdVV0aWxpemF0aW9uQWxhcm0odGhpcywgJ0NQVVV0aWxpemF0aW9uQWxhcm0nLCB7XG4gICAgICBpbnN0YW5jZTogdGhpcyxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gYWxhcm0gdGhhdCBtb25pdG9ycyB0aGUgU3RhdHVzQ2hlY2tGYWlsZWQgZm9yIHRoZSBFQzIgaW5zdGFuY2UuXG4gICAqL1xuICBwdWJsaWMgYWxhcm1TdGF0dXNDaGVja0ZhaWxlZChwcm9wcz86IEVjMlN0YXR1c0NoZWNrRmFpbGVkQWxhcm1Db25maWcpOiBFYzJJbnN0YW5jZVN0YXR1c0NoZWNrRmFpbGVkQWxhcm0ge1xuICAgIHJldHVybiBuZXcgRWMySW5zdGFuY2VTdGF0dXNDaGVja0ZhaWxlZEFsYXJtKHRoaXMsICdTdGF0dXNDaGVja0ZhaWxlZEFsYXJtJywge1xuICAgICAgaW5zdGFuY2U6IHRoaXMsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIHRoZSByZWNvbW1lbmRlZCBhbGFybXMgZm9yIHRoZSBFQzIgSW5zdGFuY2UuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L21vbml0b3JpbmcvQmVzdF9QcmFjdGljZV9SZWNvbW1lbmRlZF9BbGFybXNfQVdTX1NlcnZpY2VzLmh0bWwjRUMyXG4gICAqL1xuICBwdWJsaWMgYXBwbHlSZWNvbW1lbmRlZEFsYXJtcyhwcm9wcz86IEVjMkluc3RhbmNlUmVjb21tZW5kZWRBbGFybXNDb25maWcpOiBFYzJJbnN0YW5jZVJlY29tbWVuZGVkQWxhcm1zIHtcbiAgICByZXR1cm4gbmV3IEVjMkluc3RhbmNlUmVjb21tZW5kZWRBbGFybXModGhpcywgJ0VjMkluc3RhbmNlUmVjb21tZW5kZWRBbGFybXMnLCB7XG4gICAgICBpbnN0YW5jZTogdGhpcyxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogQ29uZmlndXJlcyB0aGUgcmVjb21tZW5kZWQgYWxhcm1zIGZvciBhbiBFQzIgSW5zdGFuY2UuXG4gKlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvbW9uaXRvcmluZy9CZXN0X1ByYWN0aWNlX1JlY29tbWVuZGVkX0FsYXJtc19BV1NfU2VydmljZXMuaHRtbCNFQzJcbiAqL1xuZXhwb3J0IGNsYXNzIEVjMlJlY29tbWVuZGVkQWxhcm1zQXNwZWN0IGltcGxlbWVudHMgSUFzcGVjdCB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgcHJvcHM/OiBFYzJJbnN0YW5jZVJlY29tbWVuZGVkQWxhcm1zQ29uZmlnKSB7fVxuXG4gIHB1YmxpYyB2aXNpdChub2RlOiBJQ29uc3RydWN0KTogdm9pZCB7XG4gICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBlYzIuSW5zdGFuY2UpIHtcbiAgICAgIGlmICh0aGlzLnByb3BzPy5leGNsdWRlUmVzb3VyY2VzICYmIHRoaXMucHJvcHMuZXhjbHVkZVJlc291cmNlcy5pbmNsdWRlcyhub2RlLm5vZGUuaWQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGluc3RhbmNlID0gbm9kZSBhcyBlYzIuSW5zdGFuY2U7XG5cbiAgICAgICAgbmV3IEVjMkluc3RhbmNlUmVjb21tZW5kZWRBbGFybXMoaW5zdGFuY2UsICdFYzJJbnN0YW5jZVJlY29tbWVuZGVkQWxhcm1zRnJvbUFzcGVjdCcsIHtcbiAgICAgICAgICBpbnN0YW5jZSxcbiAgICAgICAgICAuLi50aGlzLnByb3BzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiJdfQ==