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.

230 lines 39.6 kB
"use strict"; var _a, _b, _c, _d, _e; Object.defineProperty(exports, "__esModule", { value: true }); exports.NetworkLoadBalancerRecommendedAlarmsAspect = exports.NetworkLoadBalancer = exports.NetworkLoadBalancerRecommendedAlarms = exports.NetworkLoadBalancerTcpTargetResetCountAlarm = exports.NetworkLoadBalancerTcpElbResetCountAlarm = exports.NetworkLoadBalancerRecommendedAlarmsMetrics = 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 NetworkLoadBalancer alarms. */ var NetworkLoadBalancerRecommendedAlarmsMetrics; (function (NetworkLoadBalancerRecommendedAlarmsMetrics) { /** * The number of reset (RST) packets sent from the load balancer. */ NetworkLoadBalancerRecommendedAlarmsMetrics["TCP_ELB_RESET_COUNT"] = "TcpElbResetCount"; /** * The number of reset (RST) packets generated by the targets. */ NetworkLoadBalancerRecommendedAlarmsMetrics["TCP_TARGET_RESET_COUNT"] = "TcpTargetResetCount"; })(NetworkLoadBalancerRecommendedAlarmsMetrics || (exports.NetworkLoadBalancerRecommendedAlarmsMetrics = NetworkLoadBalancerRecommendedAlarmsMetrics = {})); /** * This alarm is used to detect when the load balancer is sending TCP reset packets. * * A high number of resets can indicate connectivity issues between the load balancer and clients. * * The alarm is triggered when the number of TCP resets from the load balancer is greater than threshold. */ class NetworkLoadBalancerTcpElbResetCountAlarm extends aws_cdk_lib_1.aws_cloudwatch.Alarm { constructor(scope, id, props) { const alarmName = props.alarmName ?? `${props.loadBalancer.loadBalancerName} - ${NetworkLoadBalancerRecommendedAlarmsMetrics.TCP_ELB_RESET_COUNT}`; const period = props.period ?? aws_cdk_lib_1.Duration.minutes(1); const evaluationPeriods = props.evaluationPeriods ?? 3; const datapointsToAlarm = props.datapointsToAlarm ?? 3; const threshold = props.threshold ?? 0; const treatMissingData = props.treatMissingData ?? aws_cdk_lib_1.aws_cloudwatch.TreatMissingData.MISSING; const alarmDescription = props.alarmDescription ?? 'This alarm is used to detect when the load balancer is sending TCP reset packets.' + ' A high number of resets can indicate connectivity issues between the load balancer and clients.'; (0, common_1.validateTotalAlarmPeriod)(period, evaluationPeriods, alarmName); super(scope, id, { alarmName, metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({ namespace: 'AWS/NetworkELB', metricName: NetworkLoadBalancerRecommendedAlarmsMetrics.TCP_ELB_RESET_COUNT, dimensionsMap: { LoadBalancer: props.loadBalancer.loadBalancerFullName, }, statistic: 'Sum', period, }), 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.NetworkLoadBalancerTcpElbResetCountAlarm = NetworkLoadBalancerTcpElbResetCountAlarm; _a = JSII_RTTI_SYMBOL_1; NetworkLoadBalancerTcpElbResetCountAlarm[_a] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.NetworkLoadBalancerTcpElbResetCountAlarm", version: "0.0.17" }; /** * This alarm is used to detect when the targets are sending TCP reset packets. * * A high number of resets can indicate connectivity issues between the load balancer and targets. * * The alarm is triggered when the number of TCP resets from targets is greater than threshold. */ class NetworkLoadBalancerTcpTargetResetCountAlarm extends aws_cdk_lib_1.aws_cloudwatch.Alarm { constructor(scope, id, props) { const alarmName = props.alarmName ?? `${props.loadBalancer.loadBalancerName} - ${NetworkLoadBalancerRecommendedAlarmsMetrics.TCP_TARGET_RESET_COUNT}`; const period = props.period ?? aws_cdk_lib_1.Duration.minutes(1); const evaluationPeriods = props.evaluationPeriods ?? 3; const datapointsToAlarm = props.datapointsToAlarm ?? 3; const threshold = props.threshold ?? 0; const treatMissingData = props.treatMissingData ?? aws_cdk_lib_1.aws_cloudwatch.TreatMissingData.MISSING; const alarmDescription = props.alarmDescription ?? 'This alarm is used to detect when the targets are sending TCP reset packets.' + ' A high number of resets can indicate connectivity issues between the load balancer and targets.'; (0, common_1.validateTotalAlarmPeriod)(period, evaluationPeriods, alarmName); super(scope, id, { alarmName, metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({ namespace: 'AWS/NetworkELB', metricName: NetworkLoadBalancerRecommendedAlarmsMetrics.TCP_TARGET_RESET_COUNT, dimensionsMap: { LoadBalancer: props.loadBalancer.loadBalancerFullName, }, statistic: 'Sum', period, }), 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.NetworkLoadBalancerTcpTargetResetCountAlarm = NetworkLoadBalancerTcpTargetResetCountAlarm; _b = JSII_RTTI_SYMBOL_1; NetworkLoadBalancerTcpTargetResetCountAlarm[_b] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.NetworkLoadBalancerTcpTargetResetCountAlarm", version: "0.0.17" }; /** * A construct that creates the recommended alarms for a NetworkLoadBalancer. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/elb-metricscollected.html */ class NetworkLoadBalancerRecommendedAlarms extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); if (!props.excludeAlarms?.includes(NetworkLoadBalancerRecommendedAlarmsMetrics.TCP_ELB_RESET_COUNT)) { this.alarmTcpElbResetCount = new NetworkLoadBalancerTcpElbResetCountAlarm(this, `${props.loadBalancer.node.id}_TcpElbResetCount`, { loadBalancer: props.loadBalancer, treatMissingData: props.treatMissingData, ...props.configTcpElbResetCountAlarm, }); if (props.defaultAlarmAction && !props.configTcpElbResetCountAlarm?.alarmAction) { this.alarmTcpElbResetCount.addAlarmAction(props.defaultAlarmAction); } if (props.defaultOkAction && !props.configTcpElbResetCountAlarm?.okAction) { this.alarmTcpElbResetCount.addOkAction(props.defaultOkAction); } if (props.defaultInsufficientDataAction && !props.configTcpElbResetCountAlarm?.insufficientDataAction) { this.alarmTcpElbResetCount.addInsufficientDataAction(props.defaultInsufficientDataAction); } } if (!props.excludeAlarms?.includes(NetworkLoadBalancerRecommendedAlarmsMetrics.TCP_TARGET_RESET_COUNT)) { this.alarmTcpTargetResetCount = new NetworkLoadBalancerTcpTargetResetCountAlarm(this, `${props.loadBalancer.node.id}_TcpTargetResetCount`, { loadBalancer: props.loadBalancer, treatMissingData: props.treatMissingData, ...props.configTcpTargetResetCountAlarm, }); if (props.defaultAlarmAction && !props.configTcpTargetResetCountAlarm?.alarmAction) { this.alarmTcpTargetResetCount.addAlarmAction(props.defaultAlarmAction); } if (props.defaultOkAction && !props.configTcpTargetResetCountAlarm?.okAction) { this.alarmTcpTargetResetCount.addOkAction(props.defaultOkAction); } if (props.defaultInsufficientDataAction && !props.configTcpTargetResetCountAlarm?.insufficientDataAction) { this.alarmTcpTargetResetCount.addInsufficientDataAction(props.defaultInsufficientDataAction); } } } } exports.NetworkLoadBalancerRecommendedAlarms = NetworkLoadBalancerRecommendedAlarms; _c = JSII_RTTI_SYMBOL_1; NetworkLoadBalancerRecommendedAlarms[_c] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.NetworkLoadBalancerRecommendedAlarms", version: "0.0.17" }; /** * An extension for the NetworkLoadBalancer construct that provides methods * to create recommended alarms. */ class NetworkLoadBalancer extends aws_cdk_lib_1.aws_elasticloadbalancingv2.NetworkLoadBalancer { constructor(scope, id, props) { super(scope, id, props); } /** * Creates an alarm that monitors the TCP reset count from the load balancer. */ alarmTcpElbResetCount(props) { return new NetworkLoadBalancerTcpElbResetCountAlarm(this, 'TcpElbResetCountAlarm', { loadBalancer: this, ...props, }); } /** * Creates an alarm that monitors the TCP reset count from targets. */ alarmTcpTargetResetCount(props) { return new NetworkLoadBalancerTcpTargetResetCountAlarm(this, 'TcpTargetResetCountAlarm', { loadBalancer: this, ...props, }); } /** * Creates the recommended alarms for the NetworkLoadBalancer. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/elb-metricscollected.html */ applyRecommendedAlarms(props) { return new NetworkLoadBalancerRecommendedAlarms(this, 'NetworkLoadBalancerRecommendedAlarms', { loadBalancer: this, ...props, }); } } exports.NetworkLoadBalancer = NetworkLoadBalancer; _d = JSII_RTTI_SYMBOL_1; NetworkLoadBalancer[_d] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.NetworkLoadBalancer", version: "0.0.17" }; /** * Configures the recommended alarms for a NetworkLoadBalancer. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/elb-metricscollected.html */ class NetworkLoadBalancerRecommendedAlarmsAspect { constructor(props) { this.props = props; } visit(node) { if (node instanceof aws_cdk_lib_1.aws_elasticloadbalancingv2.NetworkLoadBalancer) { if (this.props.excludeResources && this.props.excludeResources.includes(node.node.id)) { return; } else { const loadBalancer = node; new NetworkLoadBalancerRecommendedAlarms(loadBalancer, 'NetworkLoadBalancerRecommendedAlarmsFromAspect', { loadBalancer, ...this.props, }); } } } } exports.NetworkLoadBalancerRecommendedAlarmsAspect = NetworkLoadBalancerRecommendedAlarmsAspect; _e = JSII_RTTI_SYMBOL_1; NetworkLoadBalancerRecommendedAlarmsAspect[_e] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.NetworkLoadBalancerRecommendedAlarmsAspect", version: "0.0.17" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV0d29ya2xvYWRiYWxhbmNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9uZXR3b3JrbG9hZGJhbGFuY2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNkNBS3FCO0FBQ3JCLDJDQUFtRDtBQUNuRCxxQ0FBb0U7QUFFcEU7O0dBRUc7QUFDSCxJQUFZLDJDQVNYO0FBVEQsV0FBWSwyQ0FBMkM7SUFDckQ7O09BRUc7SUFDSCx1RkFBd0MsQ0FBQTtJQUN4Qzs7T0FFRztJQUNILDZGQUE4QyxDQUFBO0FBQ2hELENBQUMsRUFUVywyQ0FBMkMsMkRBQTNDLDJDQUEyQyxRQVN0RDtBQW9FRDs7Ozs7O0dBTUc7QUFDSCxNQUFhLHdDQUF5QyxTQUFRLDRCQUFVLENBQUMsS0FBSztJQUM1RSxZQUFZLEtBQWlCLEVBQUUsRUFBVSxFQUFFLEtBQW9EO1FBQzdGLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLElBQUksR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDLGdCQUFnQixNQUFNLDJDQUEyQyxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFDbkosTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sSUFBSSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRCxNQUFNLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLENBQUM7UUFDdkQsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUMsaUJBQWlCLElBQUksQ0FBQyxDQUFDO1FBQ3ZELE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLGdCQUFnQixJQUFJLDRCQUFVLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDO1FBQ3ZGLE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLGdCQUFnQixJQUFJLG1GQUFtRjtjQUNsSSxrR0FBa0csQ0FB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QyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUN0RixPQUFPO1lBQ1QsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sWUFBWSxHQUFHLElBQWlDLENBQUM7Z0JBRXZELElBQUksb0NBQW9DLENBQUMsWUFBWSxFQUFFLGdEQUFnRCxFQUFFO29CQUN2RyxZQUFZO29CQUNaLEdBQUcsSUFBSSxDQUFDLEtBQUs7aUJBQ2QsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDOztBQWhCSCxnR0FpQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBJQXNwZWN0LFxuICBhd3NfZWxhc3RpY2xvYWRiYWxhbmNpbmd2MiBhcyBlbGJ2MixcbiAgYXdzX2Nsb3Vkd2F0Y2ggYXMgY2xvdWR3YXRjaCxcbiAgRHVyYXRpb24sXG59IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IENvbnN0cnVjdCwgSUNvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQWxhcm1CYXNlUHJvcHMsIHZhbGlkYXRlVG90YWxBbGFybVBlcmlvZCB9IGZyb20gJy4vY29tbW9uJztcblxuLyoqXG4gKiBUaGUgcmVjb21tZW5kZWQgbWV0cmljcyBmb3IgTmV0d29ya0xvYWRCYWxhbmNlciBhbGFybXMuXG4gKi9cbmV4cG9ydCBlbnVtIE5ldHdvcmtMb2FkQmFsYW5jZXJSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3Mge1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiByZXNldCAoUlNUKSBwYWNrZXRzIHNlbnQgZnJvbSB0aGUgbG9hZCBiYWxhbmNlci5cbiAgICovXG4gIFRDUF9FTEJfUkVTRVRfQ09VTlQgPSAnVGNwRWxiUmVzZXRDb3VudCcsXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIHJlc2V0IChSU1QpIHBhY2tldHMgZ2VuZXJhdGVkIGJ5IHRoZSB0YXJnZXRzLlxuICAgKi9cbiAgVENQX1RBUkdFVF9SRVNFVF9DT1VOVCA9ICdUY3BUYXJnZXRSZXNldENvdW50Jyxcbn1cblxuLyoqXG4gKiBUaGUgY29tbW9uIG9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBhbGFybXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmV0d29ya0xvYWRCYWxhbmNlckFsYXJtQmFzZUNvbmZpZyBleHRlbmRzIEFsYXJtQmFzZVByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBwZXJpb2Qgb3ZlciB3aGljaCB0aGUgc3BlY2lmaWVkIHN0YXRpc3RpYyBpcyBhcHBsaWVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBEdXJhdGlvbi5taW51dGVzKDEpXG4gICAqL1xuICByZWFkb25seSBwZXJpb2Q/OiBEdXJhdGlvbjtcbn1cblxuLyoqXG4gKiBUaGUgY29tbW9uIHByb3BlcnRpZXMgZm9yIHRoZSBOZXR3b3JrTG9hZEJhbGFuY2VyIGFsYXJtcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOZXR3b3JrTG9hZEJhbGFuY2VyQWxhcm1Qcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgTmV0d29ya0xvYWRCYWxhbmNlciB0byBtb25pdG9yLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9hZEJhbGFuY2VyOiBlbGJ2Mi5OZXR3b3JrTG9hZEJhbGFuY2VyO1xufVxuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBUY3BFbGJSZXNldENvdW50IGFsYXJtLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5ldHdvcmtMb2FkQmFsYW5jZXJUY3BFbGJSZXNldENvdW50QWxhcm1Db25maWcgZXh0ZW5kcyBOZXR3b3JrTG9hZEJhbGFuY2VyQWxhcm1CYXNlQ29uZmlnIHtcbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSBhZ2FpbnN0IHdoaWNoIHRoZSBzcGVjaWZpZWQgc3RhdGlzdGljIGlzIGNvbXBhcmVkLlxuICAgKiBZb3Ugc2hvdWxkIHNldCB0aGlzIHRocmVzaG9sZCBiYXNlZCBvbiB0aGUgYWNjZXB0YWJsZSBudW1iZXIgb2YgVENQIHJlc2V0cyBmcm9tIHRoZSBsb2FkIGJhbGFuY2VyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAwXG4gICAqL1xuICByZWFkb25seSB0aHJlc2hvbGQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIHBlcmlvZHMgb3ZlciB3aGljaCBkYXRhIGlzIGNvbXBhcmVkIHRvIHRoZSBzcGVjaWZpZWQgdGhyZXNob2xkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAzXG4gICAqL1xuICByZWFkb25seSBldmFsdWF0aW9uUGVyaW9kcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgZGF0YSBwb2ludHMgdGhhdCBtdXN0IGJlIGJyZWFjaGluZyB0byB0cmlnZ2VyIHRoZSBhbGFybS5cbiAgICpcbiAgICogQGRlZmF1bHQgM1xuICAgKi9cbiAgcmVhZG9ubHkgZGF0YXBvaW50c1RvQWxhcm0/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgYWxhcm0gbmFtZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBsb2FkQmFsYW5jZXJOYW1lICsgJyAtIFRjcEVsYlJlc2V0Q291bnQnXG4gICAqL1xuICByZWFkb25seSBhbGFybU5hbWU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgZGVzY3JpcHRpb24gb2YgdGhlIGFsYXJtLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFRoaXMgYWxhcm0gaXMgdXNlZCB0byBkZXRlY3Qgd2hlbiB0aGUgbG9hZCBiYWxhbmNlciBpcyBzZW5kaW5nIFRDUCByZXNldCBwYWNrZXRzLlxuICAgKiBBIGhpZ2ggbnVtYmVyIG9mIHJlc2V0cyBjYW4gaW5kaWNhdGUgY29ubmVjdGl2aXR5IGlzc3VlcyBiZXR3ZWVuIHRoZSBsb2FkIGJhbGFuY2VyIGFuZCBjbGllbnRzLlxuICAgKi9cbiAgcmVhZG9ubHkgYWxhcm1EZXNjcmlwdGlvbj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgcHJvcGVydGllcyBmb3IgdGhlIE5ldHdvcmtMb2FkQmFsYW5jZXJUY3BFbGJSZXNldENvdW50QWxhcm0gY29uc3RydWN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5ldHdvcmtMb2FkQmFsYW5jZXJUY3BFbGJSZXNldENvdW50QWxhcm1Qcm9wcyBleHRlbmRzXG4gIE5ldHdvcmtMb2FkQmFsYW5jZXJBbGFybVByb3BzLCBOZXR3b3JrTG9hZEJhbGFuY2VyVGNwRWxiUmVzZXRDb3VudEFsYXJtQ29uZmlnIHt9XG5cbi8qKlxuICogVGhpcyBhbGFybSBpcyB1c2VkIHRvIGRldGVjdCB3aGVuIHRoZSBsb2FkIGJhbGFuY2VyIGlzIHNlbmRpbmcgVENQIHJlc2V0IHBhY2tldHMuXG4gKlxuICogQSBoaWdoIG51bWJlciBvZiByZXNldHMgY2FuIGluZGljYXRlIGNvbm5lY3Rpdml0eSBpc3N1ZXMgYmV0d2VlbiB0aGUgbG9hZCBiYWxhbmNlciBhbmQgY2xpZW50cy5cbiAqXG4gKiBUaGUgYWxhcm0gaXMgdHJpZ2dlcmVkIHdoZW4gdGhlIG51bWJlciBvZiBUQ1AgcmVzZXRzIGZyb20gdGhlIGxvYWQgYmFsYW5jZXIgaXMgZ3JlYXRlciB0aGFuIHRocmVzaG9sZC5cbiAqL1xuZXhwb3J0IGNsYXNzIE5ldHdvcmtMb2FkQmFsYW5jZXJUY3BFbGJSZXNldENvdW50QWxhcm0gZXh0ZW5kcyBjbG91ZHdhdGNoLkFsYXJtIHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IElDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBOZXR3b3JrTG9hZEJhbGFuY2VyVGNwRWxiUmVzZXRDb3VudEFsYXJtUHJvcHMpIHtcbiAgICBjb25zdCBhbGFybU5hbWUgPSBwcm9wcy5hbGFybU5hbWUgPz8gYCR7cHJvcHMubG9hZEJhbGFuY2VyLmxvYWRCYWxhbmNlck5hbWV9IC0gJHtOZXR3b3JrTG9hZEJhbGFuY2VyUmVjb21tZW5kZWRBbGFybXNNZXRyaWNzLlRDUF9FTEJfUkVTRVRfQ09VTlR9YDtcbiAgICBjb25zdCBwZXJpb2QgPSBwcm9wcy5wZXJpb2QgPz8gRHVyYXRpb24ubWludXRlcygxKTtcbiAgICBjb25zdCBldmFsdWF0aW9uUGVyaW9kcyA9IHByb3BzLmV2YWx1YXRpb25QZXJpb2RzID8/IDM7XG4gICAgY29uc3QgZGF0YXBvaW50c1RvQWxhcm0gPSBwcm9wcy5kYXRhcG9pbnRzVG9BbGFybSA/PyAzO1xuICAgIGNvbnN0IHRocmVzaG9sZCA9IHByb3BzLnRocmVzaG9sZCA/PyAwO1xuICAgIGNvbnN0IHRyZWF0TWlzc2luZ0RhdGEgPSBwcm9wcy50cmVhdE1pc3NpbmdEYXRhID8/IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5NSVNTSU5HO1xuICAgIGNvbnN0IGFsYXJtRGVzY3JpcHRpb24gPSBwcm9wcy5hbGFybURlc2NyaXB0aW9uID8/ICdUaGlzIGFsYXJtIGlzIHVzZWQgdG8gZGV0ZWN0IHdoZW4gdGhlIGxvYWQgYmFsYW5jZXIgaXMgc2VuZGluZyBUQ1AgcmVzZXQgcGFja2V0cy4nXG4gICAgICArICcgQSBoaWdoIG51bWJlciBvZiByZXNldHMgY2FuIGluZGljYXRlIGNvbm5lY3Rpdml0eSBpc3N1ZXMgYmV0d2VlbiB0aGUgbG9hZCBiYWxhbmNlciBhbmQgY2xpZW50cy4nO1xuXG4gICAgdmFsaWRhdGVUb3RhbEFsYXJtUGVyaW9kKHBlcmlvZCwgZXZhbHVhdGlvblBlcmlvZHMsIGFsYXJtTmFtZSk7XG5cbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIGFsYXJtTmFtZSxcbiAgICAgIG1ldHJpYzogbmV3IGNsb3Vkd2F0Y2guTWV0cmljKHtcbiAgICAgICAgbmFtZXNwYWNlOiAnQVdTL05ldHdvcmtFTEInLFxuICAgICAgICBtZXRyaWNOYW1lOiBOZXR3b3JrTG9hZEJhbGFuY2VyUmVjb21tZW5kZWRBbGFybXNNZXRyaWNzLlRDUF9FTEJfUkVTRVRfQ09VTlQsXG4gICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICBMb2FkQmFsYW5jZXI6IHByb3BzLmxvYWRCYWxhbmNlci5sb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgICAgICAgfSxcbiAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgcGVyaW9kLFxuICAgICAgfSksXG4gICAgICB0aHJlc2hvbGQsXG4gICAgICBldmFsdWF0aW9uUGVyaW9kcyxcbiAgICAgIGRhdGFwb2ludHNUb0FsYXJtLFxuICAgICAgdHJlYXRNaXNzaW5nRGF0YSxcbiAgICAgIGNvbXBhcmlzb25PcGVyYXRvcjogY2xvdWR3YXRjaC5Db21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX1RIUkVTSE9MRCxcbiAgICAgIGFsYXJtRGVzY3JpcHRpb24sXG4gICAgfSk7XG5cbiAgICBpZiAocHJvcHMuYWxhcm1BY3Rpb24pIHRoaXMuYWRkQWxhcm1BY3Rpb24ocHJvcHMuYWxhcm1BY3Rpb24pO1xuICAgIGlmIChwcm9wcy5va0FjdGlvbikgdGhpcy5hZGRPa0FjdGlvbihwcm9wcy5va0FjdGlvbik7XG4gICAgaWYgKHByb3BzLmluc3VmZmljaWVudERhdGFBY3Rpb24pIHRoaXMuYWRkSW5zdWZmaWNpZW50RGF0YUFjdGlvbihwcm9wcy5pbnN1ZmZpY2llbnREYXRhQWN0aW9uKTtcbiAgfVxufVxuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBUY3BUYXJnZXRSZXNldENvdW50IGFsYXJtLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5ldHdvcmtMb2FkQmFsYW5jZXJUY3BUYXJnZXRSZXNldENvdW50QWxhcm1Db25maWcgZXh0ZW5kcyBOZXR3b3JrTG9hZEJhbGFuY2VyQWxhcm1CYXNlQ29uZmlnIHtcbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSBhZ2FpbnN0IHdoaWNoIHRoZSBzcGVjaWZpZWQgc3RhdGlzdGljIGlzIGNvbXBhcmVkLlxuICAgKiBZb3Ugc2hvdWxkIHNldCB0aGlzIHRocmVzaG9sZCBiYXNlZCBvbiB0aGUgYWNjZXB0YWJsZSBudW1iZXIgb2YgVENQIHJlc2V0cyBmcm9tIHRhcmdldHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IDBcbiAgICovXG4gIHJlYWRvbmx5IHRocmVzaG9sZD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgcGVyaW9kcyBvdmVyIHdoaWNoIGRhdGEgaXMgY29tcGFyZWQgdG8gdGhlIHNwZWNpZmllZCB0aHJlc2hvbGQuXG4gICAqXG4gICAqIEBkZWZhdWx0IDNcbiAgICovXG4gIHJlYWRvbmx5IGV2YWx1YXRpb25QZXJpb2RzPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBkYXRhIHBvaW50cyB0aGF0IG11c3QgYmUgYnJlYWNoaW5nIHRvIHRyaWdnZXIgdGhlIGFsYXJtLlxuICAgKlxuICAgKiBAZGVmYXVsdCAzXG4gICAqL1xuICByZWFkb25seSBkYXRhcG9pbnRzVG9BbGFybT86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBhbGFybSBuYW1lLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGxvYWRCYWxhbmNlck5hbWUgKyAnIC0gVGNwVGFyZ2V0UmVzZXRDb3VudCdcbiAgICovXG4gIHJlYWRvbmx5IGFsYXJtTmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgYWxhcm0uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gVGhpcyBhbGFybSBpcyB1c2VkIHRvIGRldGVjdCB3aGVuIHRoZSB0YXJnZXRzIGFyZSBzZW5kaW5nIFRDUCByZXNldCBwYWNrZXRzLlxuICAgKiBBIGhpZ2ggbnVtYmVyIG9mIHJlc2V0cyBjYW4gaW5kaWNhdGUgY29ubmVjdGl2aXR5IGlzc3VlcyBiZXR3ZWVuIHRoZSBsb2FkIGJhbGFuY2VyIGFuZCB0YXJnZXRzLlxuICAgKi9cbiAgcmVhZG9ubHkgYWxhcm1EZXNjcmlwdGlvbj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgcHJvcGVydGllcyBmb3IgdGhlIE5ldHdvcmtMb2FkQmFsYW5jZXJUY3BUYXJnZXRSZXNldENvdW50QWxhcm0gY29uc3RydWN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5ldHdvcmtMb2FkQmFsYW5jZXJUY3BUYXJnZXRSZXNldENvdW50QWxhcm1Qcm9wcyBleHRlbmRzXG4gIE5ldHdvcmtMb2FkQmFsYW5jZXJBbGFybVByb3BzLCBOZXR3b3JrTG9hZEJhbGFuY2VyVGNwVGFyZ2V0UmVzZXRDb3VudEFsYXJtQ29uZmlnIHt9XG5cbi8qKlxuICogVGhpcyBhbGFybSBpcyB1c2VkIHRvIGRldGVjdCB3aGVuIHRoZSB0YXJnZXRzIGFyZSBzZW5kaW5nIFRDUCByZXNldCBwYWNrZXRzLlxuICpcbiAqIEEgaGlnaCBudW1iZXIgb2YgcmVzZXRzIGNhbiBpbmRpY2F0ZSBjb25uZWN0aXZpdHkgaXNzdWVzIGJldHdlZW4gdGhlIGxvYWQgYmFsYW5jZXIgYW5kIHRhcmdldHMuXG4gKlxuICogVGhlIGFsYXJtIGlzIHRyaWdnZXJlZCB3aGVuIHRoZSBudW1iZXIgb2YgVENQIHJlc2V0cyBmcm9tIHRhcmdldHMgaXMgZ3JlYXRlciB0aGFuIHRocmVzaG9sZC5cbiAqL1xuZXhwb3J0IGNsYXNzIE5ldHdvcmtMb2FkQmFsYW5jZXJUY3BUYXJnZXRSZXNldENvdW50QWxhcm0gZXh0ZW5kcyBjbG91ZHdhdGNoLkFsYXJtIHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IElDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBOZXR3b3JrTG9hZEJhbGFuY2VyVGNwVGFyZ2V0UmVzZXRDb3VudEFsYXJtUHJvcHMpIHtcbiAgICBjb25zdCBhbGFybU5hbWUgPSBwcm9wcy5hbGFybU5hbWUgPz8gYCR7cHJvcHMubG9hZEJhbGFuY2VyLmxvYWRCYWxhbmNlck5hbWV9IC0gJHtOZXR3b3JrTG9hZEJhbGFuY2VyUmVjb21tZW5kZWRBbGFybXNNZXRyaWNzLlRDUF9UQVJHRVRfUkVTRVRfQ09VTlR9YDtcbiAgICBjb25zdCBwZXJpb2QgPSBwcm9wcy5wZXJpb2QgPz8gRHVyYXRpb24ubWludXRlcygxKTtcbiAgICBjb25zdCBldmFsdWF0aW9uUGVyaW9kcyA9IHByb3BzLmV2YWx1YXRpb25QZXJpb2RzID8/IDM7XG4gICAgY29uc3QgZGF0YXBvaW50c1RvQWxhcm0gPSBwcm9wcy5kYXRhcG9pbnRzVG9BbGFybSA/PyAzO1xuICAgIGNvbnN0IHRocmVzaG9sZCA9IHByb3BzLnRocmVzaG9sZCA/PyAwO1xuICAgIGNvbnN0IHRyZWF0TWlzc2luZ0RhdGEgPSBwcm9wcy50cmVhdE1pc3NpbmdEYXRhID8/IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5NSVNTSU5HO1xuICAgIGNvbnN0IGFsYXJtRGVzY3JpcHRpb24gPSBwcm9wcy5hbGFybURlc2NyaXB0aW9uID8/ICdUaGlzIGFsYXJtIGlzIHVzZWQgdG8gZGV0ZWN0IHdoZW4gdGhlIHRhcmdldHMgYXJlIHNlbmRpbmcgVENQIHJlc2V0IHBhY2tldHMuJ1xuICAgICAgKyAnIEEgaGlnaCBudW1iZXIgb2YgcmVzZXRzIGNhbiBpbmRpY2F0ZSBjb25uZWN0aXZpdHkgaXNzdWVzIGJldHdlZW4gdGhlIGxvYWQgYmFsYW5jZXIgYW5kIHRhcmdldHMuJztcblxuICAgIHZhbGlkYXRlVG90YWxBbGFybVBlcmlvZChwZXJpb2QsIGV2YWx1YXRpb25QZXJpb2RzLCBhbGFybU5hbWUpO1xuXG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBhbGFybU5hbWUsXG4gICAgICBtZXRyaWM6IG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICAgIG5hbWVzcGFjZTogJ0FXUy9OZXR3b3JrRUxCJyxcbiAgICAgICAgbWV0cmljTmFtZTogTmV0d29ya0xvYWRCYWxhbmNlclJlY29tbWVuZGVkQWxhcm1zTWV0cmljcy5UQ1BfVEFSR0VUX1JFU0VUX0NPVU5ULFxuICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgTG9hZEJhbGFuY2VyOiBwcm9wcy5sb2FkQmFsYW5jZXIubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICAgIH0sXG4gICAgICAgIHN0YXRpc3RpYzogJ1N1bScsXG4gICAgICAgIHBlcmlvZCxcbiAgICAgIH0pLFxuICAgICAgdGhyZXNob2xkLFxuICAgICAgZXZhbHVhdGlvblBlcmlvZHMsXG4gICAgICBkYXRhcG9pbnRzVG9BbGFybSxcbiAgICAgIHRyZWF0TWlzc2luZ0RhdGEsXG4gICAgICBjb21wYXJpc29uT3BlcmF0b3I6IGNsb3Vkd2F0Y2guQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9USFJFU0hPTEQsXG4gICAgICBhbGFybURlc2NyaXB0aW9uLFxuICAgIH0pO1xuXG4gICAgaWYgKHByb3BzLmFsYXJtQWN0aW9uKSB0aGlzLmFkZEFsYXJtQWN0aW9uKHByb3BzLmFsYXJtQWN0aW9uKTtcbiAgICBpZiAocHJvcHMub2tBY3Rpb24pIHRoaXMuYWRkT2tBY3Rpb24ocHJvcHMub2tBY3Rpb24pO1xuICAgIGlmIChwcm9wcy5pbnN1ZmZpY2llbnREYXRhQWN0aW9uKSB0aGlzLmFkZEluc3VmZmljaWVudERhdGFBY3Rpb24ocHJvcHMuaW5zdWZmaWNpZW50RGF0YUFjdGlvbik7XG4gIH1cbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9ucyBmb3IgdGhlIHJlY29tbWVuZGVkIGFsYXJtcyBmb3IgYSBOZXR3b3JrTG9hZEJhbGFuY2VyLlxuICpcbiAqIERlZmF1bHQgYWN0aW9ucyBhcmUgb3ZlcnJpZGRlbiBieSB0aGUgYWN0aW9ucyBzcGVjaWZpZWQgaW4gdGhlXG4gKiBpbmRpdmlkdWFsIGFsYXJtIGNvbmZpZ3VyYXRpb25zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5ldHdvcmtMb2FkQmFsYW5jZXJSZWNvbW1lbmRlZEFsYXJtc0NvbmZpZyB7XG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCBhY3Rpb24gdG8gdGFrZSB3aGVuIGFuIGFsYXJtIGlzIHRyaWdnZXJlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBOb25lXG4gICAqL1xuICByZWFkb25seSBkZWZhdWx0QWxhcm1BY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvbjtcbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IGFjdGlvbiB0byB0YWtlIHdoZW4gYW4gYWxhcm0gZW50ZXJzIHRoZSBvayBzdGF0ZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBOb25lXG4gICAqL1xuICByZWFkb25seSBkZWZhdWx0T2tBY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvbjtcbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IGFjdGlvbiB0byB0YWtlIHdoZW4gYW4gYWxhcm0gaGFzIGluc3VmZmljaWVudCBkYXRhLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vbmVcbiAgICovXG4gIHJlYWRvbmx5IGRlZmF1bHRJbnN1ZmZpY2llbnREYXRhQWN0aW9uPzogY2xvdWR3YXRjaC5JQWxhcm1BY3Rpb247XG4gIC8qKlxuICAgKiBIb3cgdG8gaGFuZGxlIG1pc3NpbmcgZGF0YSBmb3IgdGhpcyBhbGFybS5cbiAgICpcbiAgICogQGRlZmF1bHQgVHJlYXRNaXNzaW5nRGF0YS5NSVNTSU5HXG4gICAqL1xuICByZWFkb25seSB0cmVhdE1pc3NpbmdEYXRhPzogY2xvdWR3YXRjaC5UcmVhdE1pc3NpbmdEYXRhO1xuICAvKipcbiAgICogQWxhcm0gbWV0cmljcyB0byBleGNsdWRlIGZyb20gdGhlIHJlY29tbWVuZGVkIGFsYXJtcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBOb25lXG4gICAqL1xuICByZWFkb25seSBleGNsdWRlQWxhcm1zPzogTmV0d29ya0xvYWRCYWxhbmNlclJlY29tbWVuZGVkQWxhcm1zTWV0cmljc1tdO1xuICAvKipcbiAgICogVGhlIHJlc291cmNlcyB0byBleGNsdWRlIGZyb20gdGhlIHJlY29tbWVuZGVkIGFsYXJtcy5cbiAgICpcbiAgICogVXNlIGEgcmVzb3VyY2VzIGlkIHRvIGV4Y2x1ZGUgYSBzcGVjaWZpYyByZXNvdXJjZS5cbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGVSZXNvdXJjZXM/OiBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIFRoZSBjb25maWd1cmF0aW9uIGZvciB0aGUgVGNwRWxiUmVzZXRDb3VudCBhbGFybS5cbiAgICovXG4gIHJlYWRvbmx5IGNvbmZpZ1RjcEVsYlJlc2V0Q291bnRBbGFybT86IE5ldHdvcmtMb2FkQmFsYW5jZXJUY3BFbGJSZXNldENvdW50QWxhcm1Db25maWc7XG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJhdGlvbiBmb3IgdGhlIFRjcFRhcmdldFJlc2V0Q291bnQgYWxhcm0uXG4gICAqL1xuICByZWFkb25seSBjb25maWdUY3BUYXJnZXRSZXNldENvdW50QWxhcm0/OiBOZXR3b3JrTG9hZEJhbGFuY2VyVGNwVGFyZ2V0UmVzZXRDb3VudEFsYXJtQ29uZmlnO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIHRoZSBOZXR3b3JrTG9hZEJhbGFuY2VyUmVjb21tZW5kZWRBbGFybXMgY29uc3RydWN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5ldHdvcmtMb2FkQmFsYW5jZXJSZWNvbW1lbmRlZEFsYXJtc1Byb3BzIGV4dGVuZHMgTmV0d29ya0xvYWRCYWxhbmNlclJlY29tbWVuZGVkQWxhcm1zQ29uZmlnIHtcbiAgLyoqXG4gICAqIFRoZSBOZXR3b3JrTG9hZEJhbGFuY2VyIHRvIG1vbml0b3IuXG4gICAqL1xuICByZWFkb25seSBsb2FkQmFsYW5jZXI6IGVsYnYyLk5ldHdvcmtMb2FkQmFsYW5jZXI7XG59XG5cbi8qKlxuICogQSBjb25zdHJ1Y3QgdGhhdCBjcmVhdGVzIHRoZSByZWNvbW1lbmRlZCBhbGFybXMgZm9yIGEgTmV0d29ya0xvYWRCYWxhbmNlci5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZFdhdGNoL2xhdGVzdC9tb25pdG9yaW5nL2VsYi1tZXRyaWNzY29sbGVjdGVkLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIE5ldHdvcmtMb2FkQmFsYW5jZXJSZWNvbW1lbmRlZEFsYXJtcyBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKlxuICAgKiBUaGUgVGNwRWxiUmVzZXRDb3VudCBhbGFybS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBhbGFybVRjcEVsYlJlc2V0Q291bnQ/OiBOZXR3b3JrTG9hZEJhbGFuY2VyVGNwRWxiUmVzZXRDb3VudEFsYXJtO1xuXG4gIC8qKlxuICAgKiBUaGUgVGNwVGFyZ2V0UmVzZXRDb3VudCBhbGFybS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBhbGFybVRjcFRhcmdldFJlc2V0Q291bnQ/OiBOZXR3b3JrTG9hZEJhbGFuY2VyVGNwVGFyZ2V0UmVzZXRDb3VudEFsYXJtO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBOZXR3b3JrTG9hZEJhbGFuY2VyUmVjb21tZW5kZWRBbGFybXNQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBpZiAoIXByb3BzLmV4Y2x1ZGVBbGFybXM/LmluY2x1ZGVzKE5ldHdvcmtMb2FkQmFsYW5jZXJSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3MuVENQX0VMQl9SRVNFVF9DT1VOVCkpIHtcbiAgICAgIHRoaXMuYWxhcm1UY3BFbGJSZXNldENvdW50ID0gbmV3IE5ldHdvcmtMb2FkQmFsYW5jZXJUY3BFbGJSZXNldENvdW50QWxhcm0odGhpcywgYCR7cHJvcHMubG9hZEJhbGFuY2VyLm5vZGUuaWR9X1RjcEVsYlJlc2V0Q291bnRgLCB7XG4gICAgICAgIGxvYWRCYWxhbmNlcjogcHJvcHMubG9hZEJhbGFuY2VyLFxuICAgICAgICB0cmVhdE1pc3NpbmdEYXRhOiBwcm9wcy50cmVhdE1pc3NpbmdEYXRhLFxuICAgICAgICAuLi5wcm9wcy5jb25maWdUY3BFbGJSZXNldENvdW50QWxhcm0sXG4gICAgICB9KTtcblxuICAgICAgaWYgKHByb3BzLmRlZmF1bHRBbGFybUFjdGlvbiAmJiAhcHJvcHMuY29uZmlnVGNwRWxiUmVzZXRDb3VudEFsYXJtPy5hbGFybUFjdGlvbikge1xuICAgICAgICB0aGlzLmFsYXJtVGNwRWxiUmVzZXRDb3VudC5hZGRBbGFybUFjdGlvbihwcm9wcy5kZWZhdWx0QWxhcm1BY3Rpb24pO1xuICAgICAgfVxuXG4gICAgICBpZiAocHJvcHMuZGVmYXVsdE9rQWN0aW9uICYmICFwcm9wcy5jb25maWdUY3BFbGJSZXNldENvdW50QWxhcm0/Lm9rQWN0aW9uKSB7XG4gICAgICAgIHRoaXMuYWxhcm1UY3BFbGJSZXNldENvdW50LmFkZE9rQWN0aW9uKHByb3BzLmRlZmF1bHRPa0FjdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wcy5kZWZhdWx0SW5zdWZmaWNpZW50RGF0YUFjdGlvbiAmJiAhcHJvcHMuY29uZmlnVGNwRWxiUmVzZXRDb3VudEFsYXJtPy5pbnN1ZmZpY2llbnREYXRhQWN0aW9uKSB7XG4gICAgICAgIHRoaXMuYWxhcm1UY3BFbGJSZXNldENvdW50LmFkZEluc3VmZmljaWVudERhdGFBY3Rpb24ocHJvcHMuZGVmYXVsdEluc3VmZmljaWVudERhdGFBY3Rpb24pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghcHJvcHMuZXhjbHVkZUFsYXJtcz8uaW5jbHVkZXMoTmV0d29ya0xvYWRCYWxhbmNlclJlY29tbWVuZGVkQWxhcm1zTWV0cmljcy5UQ1BfVEFSR0VUX1JFU0VUX0NPVU5UKSkge1xuICAgICAgdGhpcy5hbGFybVRjcFRhcmdldFJlc2V0Q291bnQgPSBuZXcgTmV0d29ya0xvYWRCYWxhbmNlclRjcFRhcmdldFJlc2V0Q291bnRBbGFybSh0aGlzLCBgJHtwcm9wcy5sb2FkQmFsYW5jZXIubm9kZS5pZH1fVGNwVGFyZ2V0UmVzZXRDb3VudGAsIHtcbiAgICAgICAgbG9hZEJhbGFuY2VyOiBwcm9wcy5sb2FkQmFsYW5jZXIsXG4gICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IHByb3BzLnRyZWF0TWlzc2luZ0RhdGEsXG4gICAgICAgIC4uLnByb3BzLmNvbmZpZ1RjcFRhcmdldFJlc2V0Q291bnRBbGFybSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAocHJvcHMuZGVmYXVsdEFsYXJtQWN0aW9uICYmICFwcm9wcy5jb25maWdUY3BUYXJnZXRSZXNldENvdW50QWxhcm0/LmFsYXJtQWN0aW9uKSB7XG4gICAgICAgIHRoaXMuYWxhcm1UY3BUYXJnZXRSZXNldENvdW50LmFkZEFsYXJtQWN0aW9uKHByb3BzLmRlZmF1bHRBbGFybUFjdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wcy5kZWZhdWx0T2tBY3Rpb24gJiYgIXByb3BzLmNvbmZpZ1RjcFRhcmdldFJlc2V0Q291bnRBbGFybT8ub2tBY3Rpb24pIHtcbiAgICAgICAgdGhpcy5hbGFybVRjcFRhcmdldFJlc2V0Q291bnQuYWRkT2tBY3Rpb24ocHJvcHMuZGVmYXVsdE9rQWN0aW9uKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHByb3BzLmRlZmF1bHRJbnN1ZmZpY2llbnREYXRhQWN0aW9uICYmICFwcm9wcy5jb25maWdUY3BUYXJnZXRSZXNldENvdW50QWxhcm0/Lmluc3VmZmljaWVudERhdGFBY3Rpb24pIHtcbiAgICAgICAgdGhpcy5hbGFybVRjcFRhcmdldFJlc2V0Q291bnQuYWRkSW5zdWZmaWNpZW50RGF0YUFjdGlvbihwcm9wcy5kZWZhdWx0SW5zdWZmaWNpZW50RGF0YUFjdGlvbik7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQW4gZXh0ZW5zaW9uIGZvciB0aGUgTmV0d29ya0xvYWRCYWxhbmNlciBjb25zdHJ1Y3QgdGhhdCBwcm92aWRlcyBtZXRob2RzXG4gKiB0byBjcmVhdGUgcmVjb21tZW5kZWQgYWxhcm1zLlxuICovXG5leHBvcnQgY2xhc3MgTmV0d29ya0xvYWRCYWxhbmNlciBleHRlbmRzIGVsYnYyLk5ldHdvcmtMb2FkQmFsYW5jZXIge1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogZWxidjIuTmV0d29ya0xvYWRCYWxhbmNlclByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCBwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBhbGFybSB0aGF0IG1vbml0b3JzIHRoZSBUQ1AgcmVzZXQgY291bnQgZnJvbSB0aGUgbG9hZCBiYWxhbmNlci5cbiAgICovXG4gIHB1YmxpYyBhbGFybVRjcEVsYlJlc2V0Q291bnQocHJvcHM/OiBOZXR3b3JrTG9hZEJhbGFuY2VyVGNwRWxiUmVzZXRDb3VudEFsYXJtQ29uZmlnKTogTmV0d29ya0xvYWRCYWxhbmNlclRjcEVsYlJlc2V0Q291bnRBbGFybSB7XG4gICAgcmV0dXJuIG5ldyBOZXR3b3JrTG9hZEJhbGFuY2VyVGNwRWxiUmVzZXRDb3VudEFsYXJtKHRoaXMsICdUY3BFbGJSZXNldENvdW50QWxhcm0nLCB7XG4gICAgICBsb2FkQmFsYW5jZXI6IHRoaXMsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGFsYXJtIHRoYXQgbW9uaXRvcnMgdGhlIFRDUCByZXNldCBjb3VudCBmcm9tIHRhcmdldHMuXG4gICAqL1xuICBwdWJsaWMgYWxhcm1UY3BUYXJnZXRSZXNldENvdW50KHByb3BzPzogTmV0d29ya0xvYWRCYWxhbmNlclRjcFRhcmdldFJlc2V0Q291bnRBbGFybUNvbmZpZyk6IE5ldHdvcmtMb2FkQmFsYW5jZXJUY3BUYXJnZXRSZXNldENvdW50QWxhcm0ge1xuICAgIHJldHVybiBuZXcgTmV0d29ya0xvYWRCYWxhbmNlclRjcFRhcmdldFJlc2V0Q291bnRBbGFybSh0aGlzLCAnVGNwVGFyZ2V0UmVzZXRDb3VudEFsYXJtJywge1xuICAgICAgbG9hZEJhbGFuY2VyOiB0aGlzLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgcmVjb21tZW5kZWQgYWxhcm1zIGZvciB0aGUgTmV0d29ya0xvYWRCYWxhbmNlci5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvbW9uaXRvcmluZy9lbGItbWV0cmljc2NvbGxlY3RlZC5odG1sXG4gICAqL1xuICBwdWJsaWMgYXBwbHlSZWNvbW1lbmRlZEFsYXJtcyhwcm9wczogTmV0d29ya0xvYWRCYWxhbmNlclJlY29tbWVuZGVkQWxhcm1zQ29uZmlnKTogTmV0d29ya0xvYWRCYWxhbmNlclJlY29tbWVuZGVkQWxhcm1zIHtcbiAgICByZXR1cm4gbmV3IE5ldHdvcmtMb2FkQmFsYW5jZXJSZWNvbW1lbmRlZEFsYXJtcyh0aGlzLCAnTmV0d29ya0xvYWRCYWxhbmNlclJlY29tbWVuZGVkQWxhcm1zJywge1xuICAgICAgbG9hZEJhbGFuY2VyOiB0aGlzLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBDb25maWd1cmVzIHRoZSByZWNvbW1lbmRlZCBhbGFybXMgZm9yIGEgTmV0d29ya0xvYWRCYWxhbmNlci5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZFdhdGNoL2xhdGVzdC9tb25pdG9yaW5nL2VsYi1tZXRyaWNzY29sbGVjdGVkLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIE5ldHdvcmtMb2FkQmFsYW5jZXJSZWNvbW1lbmRlZEFsYXJtc0FzcGVjdCBpbXBsZW1lbnRzIElBc3BlY3Qge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHByb3BzOiBOZXR3b3JrTG9hZEJhbGFuY2VyUmVjb21tZW5kZWRBbGFybXNDb25maWcpIHt9XG5cbiAgcHVibGljIHZpc2l0KG5vZGU6IElDb25zdHJ1Y3QpOiB2b2lkIHtcbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIGVsYnYyLk5ldHdvcmtMb2FkQmFsYW5jZXIpIHtcbiAgICAgIGlmICh0aGlzLnByb3BzLmV4Y2x1ZGVSZXNvdXJjZXMgJiYgdGhpcy5wcm9wcy5leGNsdWRlUmVzb3VyY2VzLmluY2x1ZGVzKG5vZGUubm9kZS5pZCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbG9hZEJhbGFuY2VyID0gbm9kZSBhcyBlbGJ2Mi5OZXR3b3JrTG9hZEJhbGFuY2VyO1xuXG4gICAgICAgIG5ldyBOZXR3b3JrTG9hZEJhbGFuY2VyUmVjb21tZW5kZWRBbGFybXMobG9hZEJhbGFuY2VyLCAnTmV0d29ya0xvYWRCYWxhbmNlclJlY29tbWVuZGVkQWxhcm1zRnJvbUFzcGVjdCcsIHtcbiAgICAgICAgICBsb2FkQmFsYW5jZXIsXG4gICAgICAgICAgLi4udGhpcy5wcm9wcyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59Il19