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.

339 lines 62.4 kB
"use strict"; var _a, _b, _c, _d, _e, _f; Object.defineProperty(exports, "__esModule", { value: true }); exports.VpcEndpointService = exports.PrivateLinkServicesVpcEndpointServiceRecommendedAlarms = exports.PrivateLinkServicesVpcEndpointServiceRstPacketsSentAlarm = exports.PrivateLinkServicesRecommendedAlarmsMetrics = exports.InterfaceVpcEndpoint = exports.PrivateLinkEndpointsInterfaceVpcEndpointRecommendedAlarms = exports.PrivateLinkEndpointsInterfaceVpcEndpointPacketsDroppedAlarm = exports.PrivateLinkEndpointsRecommendedAlarmsMetrics = 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 PrivateLink Endpoints alarms. */ var PrivateLinkEndpointsRecommendedAlarmsMetrics; (function (PrivateLinkEndpointsRecommendedAlarmsMetrics) { /** * Percentage of how close a file system is to reaching the I/O limit of the General Purpose * performance mode. */ PrivateLinkEndpointsRecommendedAlarmsMetrics["PACKETS_DROPPED"] = "PacketsDropped"; })(PrivateLinkEndpointsRecommendedAlarmsMetrics || (exports.PrivateLinkEndpointsRecommendedAlarmsMetrics = PrivateLinkEndpointsRecommendedAlarmsMetrics = {})); /** * This alarm helps to detect if the endpoint or endpoint service is unhealthy by monitoring the number of packets dropped by the endpoint. * * Note that packets larger than 8500 bytes that arrive at the VPC endpoint are dropped. For troubleshooting, * see connectivity problems between an interface VPC endpoint and an endpoint service. * * The alarm is triggered when the number of packets dropped exceeds the threshold. */ class PrivateLinkEndpointsInterfaceVpcEndpointPacketsDroppedAlarm extends aws_cdk_lib_1.aws_cloudwatch.Alarm { constructor(scope, id, props) { const alarmName = props.alarmName ?? `${props.endpoint.vpcEndpointId} - ${props.subnetId} - ${PrivateLinkEndpointsRecommendedAlarmsMetrics.PACKETS_DROPPED}`; const period = props.period ?? aws_cdk_lib_1.Duration.minutes(1); const evaluationPeriods = props.evaluationPeriods ?? 5; const datapointsToAlarm = props.datapointsToAlarm ?? 5; const threshold = props.threshold; const treatMissingData = props.treatMissingData ?? aws_cdk_lib_1.aws_cloudwatch.TreatMissingData.MISSING; const alarmDescription = props.alarmDescription ?? 'This alarm is used to detect if the endpoint or endpoint service is unhealthy.'; (0, common_1.validateTotalAlarmPeriod)(period, evaluationPeriods, alarmName); super(scope, id, { alarmName, metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({ namespace: 'AWS/PrivateLinkEndpoints', metricName: PrivateLinkEndpointsRecommendedAlarmsMetrics.PACKETS_DROPPED, dimensionsMap: { VpcEndpointId: props.endpoint.vpcEndpointId, VpcId: props.vpcId, EndpointType: props.endpointType, ServiceName: props.serviceName, SubnetId: props.subnetId, }, period, statistic: 'Sum', }), 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.PrivateLinkEndpointsInterfaceVpcEndpointPacketsDroppedAlarm = PrivateLinkEndpointsInterfaceVpcEndpointPacketsDroppedAlarm; _a = JSII_RTTI_SYMBOL_1; PrivateLinkEndpointsInterfaceVpcEndpointPacketsDroppedAlarm[_a] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.PrivateLinkEndpointsInterfaceVpcEndpointPacketsDroppedAlarm", version: "0.0.13" }; ; /** * A construct that creates the recommended alarms for an PrivateLink InterfaceVpcEndpoint. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#PrivateLinkEndpoints */ class PrivateLinkEndpointsInterfaceVpcEndpointRecommendedAlarms extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); if (!props.excludeAlarms?.includes(PrivateLinkEndpointsRecommendedAlarmsMetrics.PACKETS_DROPPED)) { this.alarmPacketsDroppedList = []; if (!props.configPacketsDroppedAlarm.subnets) { throw new Error('Subnets must be provided for the PacketsDropped alarm.'); } for (const subnet of props.configPacketsDroppedAlarm.subnets) { const config = props.configPacketsDroppedAlarm; const alarm = new PrivateLinkEndpointsInterfaceVpcEndpointPacketsDroppedAlarm(this, `${props.endpoint.node.id}_${subnet.node.id}_PacketsDropped`, { endpoint: props.endpoint, vpcId: config.vpcId, endpointType: config.endpointType, serviceName: config.serviceName, subnetId: subnet.subnetId, threshold: config.threshold, period: config.period, evaluationPeriods: config.evaluationPeriods, datapointsToAlarm: config.datapointsToAlarm, alarmName: config.alarmName, alarmDescription: config.alarmDescription, alarmAction: config.alarmAction, okAction: config.okAction, insufficientDataAction: config.insufficientDataAction, treatMissingData: config.treatMissingData, }); if (props.defaultAlarmAction && (!props.configPacketsDroppedAlarm || !props.configPacketsDroppedAlarm.alarmAction)) { alarm.addAlarmAction(props.defaultAlarmAction); } if (props.defaultOkAction && (!props.configPacketsDroppedAlarm || !props.configPacketsDroppedAlarm.okAction)) { alarm.addOkAction(props.defaultOkAction); } if (props.defaultInsufficientDataAction && (!props.configPacketsDroppedAlarm || !props.configPacketsDroppedAlarm.insufficientDataAction)) { alarm.addInsufficientDataAction(props.defaultInsufficientDataAction); } this.alarmPacketsDroppedList.push(alarm); } } } } exports.PrivateLinkEndpointsInterfaceVpcEndpointRecommendedAlarms = PrivateLinkEndpointsInterfaceVpcEndpointRecommendedAlarms; _b = JSII_RTTI_SYMBOL_1; PrivateLinkEndpointsInterfaceVpcEndpointRecommendedAlarms[_b] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.PrivateLinkEndpointsInterfaceVpcEndpointRecommendedAlarms", version: "0.0.13" }; /** * An extension for the InterfaceVpcEndpoint construct that provides methods * to create recommended alarms. */ class InterfaceVpcEndpoint extends aws_cdk_lib_1.aws_ec2.InterfaceVpcEndpoint { constructor(scope, id, props) { super(scope, id, props); } /** * Creates an alarm that monitors the PacketsDropped for the PrivateLink endpoint. */ alarmPacketsDropped(props) { let alarmPacketsDroppedList = []; if (!props.subnets) { throw new Error('Subnets must be provided for the PacketsDropped alarm.'); } for (const subnet of props.subnets) { const alarm = new PrivateLinkEndpointsInterfaceVpcEndpointPacketsDroppedAlarm(this, `${this.node.id}_${subnet.node.id}_PacketsDropped`, { endpoint: this, vpcId: props.vpcId, endpointType: props.endpointType, serviceName: props.serviceName, subnetId: subnet.subnetId, threshold: props.threshold, period: props.period, evaluationPeriods: props.evaluationPeriods, datapointsToAlarm: props.datapointsToAlarm, alarmName: props.alarmName, alarmDescription: props.alarmDescription, alarmAction: props.alarmAction, okAction: props.okAction, insufficientDataAction: props.insufficientDataAction, treatMissingData: props.treatMissingData, }); alarmPacketsDroppedList.push(alarm); } return alarmPacketsDroppedList; } /** * Creates the recommended alarms for the PrivateLink InterfaceVpcEndpoint. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#PrivateLinkEndpoints */ applyRecommendedAlarms(props) { return new PrivateLinkEndpointsInterfaceVpcEndpointRecommendedAlarms(this, 'PrivateLinkEndpointsInterfaceVpcEndpointRecommendedAlarms', { endpoint: this, ...props, }); } } exports.InterfaceVpcEndpoint = InterfaceVpcEndpoint; _c = JSII_RTTI_SYMBOL_1; InterfaceVpcEndpoint[_c] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.InterfaceVpcEndpoint", version: "0.0.13" }; /** * The recommended metrics for PrivateLink Services alarms. */ var PrivateLinkServicesRecommendedAlarmsMetrics; (function (PrivateLinkServicesRecommendedAlarmsMetrics) { /** * The number of RST packets sent to endpoints by the endpoint service. Increasing values could indicate * that there are unhealthy targets. */ PrivateLinkServicesRecommendedAlarmsMetrics["RST_PACKETS_SENT"] = "RstPacketsSent"; })(PrivateLinkServicesRecommendedAlarmsMetrics || (exports.PrivateLinkServicesRecommendedAlarmsMetrics = PrivateLinkServicesRecommendedAlarmsMetrics = {})); /** * This alarm helps you detect unhealthy targets of an endpoint service based on the number of reset packets that are sent to endpoints. * * When you debug connection errors with a consumer of your service, you can validate whether the service is resetting connections with * the RstPacketsSent metric, or if something else is failing on the network path. * * The alarm is triggered when the the number of reset packets exceeds the threshold. */ class PrivateLinkServicesVpcEndpointServiceRstPacketsSentAlarm extends aws_cdk_lib_1.aws_cloudwatch.Alarm { constructor(scope, id, props) { const alarmName = props.alarmName ?? `${props.endpointService.vpcEndpointServiceName} - ${props.az} - ${PrivateLinkServicesRecommendedAlarmsMetrics.RST_PACKETS_SENT}`; const period = props.period ?? aws_cdk_lib_1.Duration.minutes(1); const evaluationPeriods = props.evaluationPeriods ?? 5; const datapointsToAlarm = props.datapointsToAlarm ?? 5; const threshold = props.threshold; const treatMissingData = props.treatMissingData ?? aws_cdk_lib_1.aws_cloudwatch.TreatMissingData.MISSING; const alarmDescription = props.alarmDescription ?? 'This alarm is used to detect unhealthy targets of an endpoint service.'; (0, common_1.validateTotalAlarmPeriod)(period, evaluationPeriods, alarmName); super(scope, id, { alarmName, metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({ namespace: 'AWS/PrivateLinkServices', metricName: PrivateLinkServicesRecommendedAlarmsMetrics.RST_PACKETS_SENT, dimensionsMap: { ServiceId: props.endpointService.vpcEndpointServiceId, LoadBalancerArn: props.loadBalancerArn, Az: props.az, }, period, statistic: 'Sum', }), 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.PrivateLinkServicesVpcEndpointServiceRstPacketsSentAlarm = PrivateLinkServicesVpcEndpointServiceRstPacketsSentAlarm; _d = JSII_RTTI_SYMBOL_1; PrivateLinkServicesVpcEndpointServiceRstPacketsSentAlarm[_d] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.PrivateLinkServicesVpcEndpointServiceRstPacketsSentAlarm", version: "0.0.13" }; ; /** * A construct that creates the recommended alarms for an PrivateLink VpcEndpointService. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#PrivateLinkServices */ class PrivateLinkServicesVpcEndpointServiceRecommendedAlarms extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); if (!props.excludeAlarms?.includes(PrivateLinkServicesRecommendedAlarmsMetrics.RST_PACKETS_SENT)) { this.alarmRstPacketsSentList = []; if (!props.configRstPacketsSentAlarm.azs) { throw new Error('AZs must be provided for the RstPacketsSent alarm.'); } for (const az of props.configRstPacketsSentAlarm.azs) { const config = props.configRstPacketsSentAlarm; const alarm = new PrivateLinkServicesVpcEndpointServiceRstPacketsSentAlarm(this, `${props.endpointService.node.id}_${az}_RstPacketsSent`, { endpointService: props.endpointService, loadBalancerArn: config.loadBalancerArn, az: az, threshold: config.threshold, period: config.period, evaluationPeriods: config.evaluationPeriods, datapointsToAlarm: config.datapointsToAlarm, alarmName: config.alarmName, alarmDescription: config.alarmDescription, alarmAction: config.alarmAction, okAction: config.okAction, insufficientDataAction: config.insufficientDataAction, treatMissingData: config.treatMissingData, }); if (props.defaultAlarmAction && (!props.configRstPacketsSentAlarm || !props.configRstPacketsSentAlarm.alarmAction)) { alarm.addAlarmAction(props.defaultAlarmAction); } if (props.defaultOkAction && (!props.configRstPacketsSentAlarm || !props.configRstPacketsSentAlarm.okAction)) { alarm.addOkAction(props.defaultOkAction); } if (props.defaultInsufficientDataAction && (!props.configRstPacketsSentAlarm || !props.configRstPacketsSentAlarm.insufficientDataAction)) { alarm.addInsufficientDataAction(props.defaultInsufficientDataAction); } this.alarmRstPacketsSentList.push(alarm); } } } } exports.PrivateLinkServicesVpcEndpointServiceRecommendedAlarms = PrivateLinkServicesVpcEndpointServiceRecommendedAlarms; _e = JSII_RTTI_SYMBOL_1; PrivateLinkServicesVpcEndpointServiceRecommendedAlarms[_e] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.PrivateLinkServicesVpcEndpointServiceRecommendedAlarms", version: "0.0.13" }; /** * An extension for the VpcEndpointService construct that provides methods * to create recommended alarms. */ class VpcEndpointService extends aws_cdk_lib_1.aws_ec2.VpcEndpointService { constructor(scope, id, props) { super(scope, id, props); } /** * Creates an alarm that monitors the RstPacketsSent for the PrivateLink endpoint. */ alarmRstPacketsSent(props) { let alarmRstPacketsSentList = []; if (!props.azs) { throw new Error('AZs must be provided for the RstPacketsSent alarm.'); } for (const az of props.azs) { const alarm = new PrivateLinkServicesVpcEndpointServiceRstPacketsSentAlarm(this, `${this.node.id}_${az}_RstPacketsSent`, { endpointService: this, loadBalancerArn: props.loadBalancerArn, az: az, threshold: props.threshold, period: props.period, evaluationPeriods: props.evaluationPeriods, datapointsToAlarm: props.datapointsToAlarm, alarmName: props.alarmName, alarmDescription: props.alarmDescription, alarmAction: props.alarmAction, okAction: props.okAction, insufficientDataAction: props.insufficientDataAction, treatMissingData: props.treatMissingData, }); alarmRstPacketsSentList.push(alarm); } return alarmRstPacketsSentList; } /** * Creates the recommended alarms for the PrivateLink VpcEndpointService. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#PrivateLinkServices */ applyRecommendedAlarms(props) { return new PrivateLinkServicesVpcEndpointServiceRecommendedAlarms(this, 'PrivateLinkServicesVpcEndpointServiceRecommendedAlarms', { endpointService: this, ...props, }); } } exports.VpcEndpointService = VpcEndpointService; _f = JSII_RTTI_SYMBOL_1; VpcEndpointService[_f] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.VpcEndpointService", version: "0.0.13" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpdmF0ZWxpbmsuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJpdmF0ZWxpbmsudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2Q0FJcUI7QUFDckIsMkNBQW1EO0FBQ25ELHFDQUFvRTtBQUVwRTs7R0FFRztBQUNILElBQVksNENBTVg7QUFORCxXQUFZLDRDQUE0QztJQUN0RDs7O09BR0c7SUFDSCxrRkFBa0MsQ0FBQTtBQUNwQyxDQUFDLEVBTlcsNENBQTRDLDREQUE1Qyw0Q0FBNEMsUUFNdkQ7QUFtR0Q7Ozs7Ozs7R0FPRztBQUNILE1BQWEsMkRBQTRELFNBQVEsNEJBQVUsQ0FBQyxLQUFLO0lBQy9GLFlBQVksS0FBaUIsRUFBRSxFQUFVLEVBQUUsS0FBdUU7UUFDaEgsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsSUFBSSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsYUFBYSxNQUFNLEtBQUssQ0FBQyxRQUFRLE1BQU0sNENBQTRDLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDN0osTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sSUFBSSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRCxNQUFNLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLENBQUM7UUFDdkQsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUMsaUJBQWlCLElBQUksQ0FBQyxDQUFDO1FBQ3ZELE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFDbEMsTUFBTSxnQkFBZ0IsR0FBRyxLQUFLLENBQUMsZ0JBQWdCLElBQUksNEJBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUM7UUFDdkYsTUFBTSxnQkFBZ0IsR0FBRyxLQUFLLENBQUMsZ0JBQWdCLElBQUksZ0ZBQWdGLENBQUM7UUFFcEksSUFBQSxpQ0FBd0IsRUFBQyxNQUFNLEVBQUUsaUJBQWlCLEVBQUUsU0FB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UUFFRCxLQUFLLE1BQU0sRUFBRSxJQUFJLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUMzQixNQUFNLEtBQUssR0FBRyxJQUFJLHdEQUF3RCxDQUFDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsaUJBQWlCLEVBQUU7Z0JBQ3ZILGVBQWUsRUFBRSxJQUFJO2dCQUNyQixlQUFlLEVBQUUsS0FBSyxDQUFDLGVBQWU7Z0JBQ3RDLEVBQUUsRUFBRSxFQUFFO2dCQUNOLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUztnQkFDMUIsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNO2dCQUNwQixpQkFBaUIsRUFBRSxLQUFLLENBQUMsaUJBQWlCO2dCQUMxQyxpQkFBaUIsRUFBRSxLQUFLLENBQUMsaUJBQWlCO2dCQUMxQyxTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7Z0JBQzFCLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxnQkFBZ0I7Z0JBQ3hDLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVztnQkFDOUIsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO2dCQUN4QixzQkFBc0IsRUFBRSxLQUFLLENBQUMsc0JBQXNCO2dCQUNwRCxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsZ0JBQWdCO2FBQ3pDLENBQUMsQ0FBQztZQUNILHVCQUF1QixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBQ0QsT0FBTyx1QkFBdUIsQ0FBQztJQUNqQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLHNCQUFzQixDQUMzQixLQUFtRTtRQUVuRSxPQUFPLElBQUksc0RBQXNELENBQUMsSUFBSSxFQUFFLHdEQUF3RCxFQUFFO1lBQ2hJLGVBQWUsRUFBRSxJQUFJO1lBQ3JCLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztJQUNMLENBQUM7O0FBaERILGdEQWlEQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGF3c19lYzIgYXMgZWMyLFxuICBhd3NfY2xvdWR3YXRjaCBhcyBjbG91ZHdhdGNoLFxuICBEdXJhdGlvbixcbn0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgQ29uc3RydWN0LCBJQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBBbGFybUJhc2VQcm9wcywgdmFsaWRhdGVUb3RhbEFsYXJtUGVyaW9kIH0gZnJvbSAnLi9jb21tb24nO1xuXG4vKipcbiAqIFRoZSByZWNvbW1lbmRlZCBtZXRyaWNzIGZvciBQcml2YXRlTGluayBFbmRwb2ludHMgYWxhcm1zLlxuICovXG5leHBvcnQgZW51bSBQcml2YXRlTGlua0VuZHBvaW50c1JlY29tbWVuZGVkQWxhcm1zTWV0cmljcyB7XG4gIC8qKlxuICAgKiBQZXJjZW50YWdlIG9mIGhvdyBjbG9zZSBhIGZpbGUgc3lzdGVtIGlzIHRvIHJlYWNoaW5nIHRoZSBJL08gbGltaXQgb2YgdGhlIEdlbmVyYWwgUHVycG9zZVxuICAgKiBwZXJmb3JtYW5jZSBtb2RlLlxuICAgKi9cbiAgUEFDS0VUU19EUk9QUEVEID0gJ1BhY2tldHNEcm9wcGVkJyxcbn1cblxuLyoqXG4gKiBUaGUgY29tbW9uIG9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBhbGFybXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJpdmF0ZUxpbmtFbmRwb2ludHNBbGFybUJhc2VDb25maWcgZXh0ZW5kcyBBbGFybUJhc2VQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgcGVyaW9kIG92ZXIgd2hpY2ggdGhlIHNwZWNpZmllZCBzdGF0aXN0aWMgaXMgYXBwbGllZC5cbiAgICpcbiAgICogQGRlZmF1bHQgRHVyYXRpb24ubWludXRlcygxKVxuICAgKi9cbiAgcmVhZG9ubHkgcGVyaW9kPzogRHVyYXRpb247XG59XG5cbi8qKlxuICogVGhlIGNvbW1vbiBwcm9wZXJ0aWVzIGZvciB0aGUgUHJpdmF0ZUxpbmsgSW50ZXJmYWNlVnBjRW5kcG9pbnQgYWxhcm1zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByaXZhdGVMaW5rRW5kcG9pbnRzSW50ZXJmYWNlVnBjRW5kcG9pbnRBbGFybVByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBQcml2YXRlTGluayBJbnRlcmZhY2VWcGNFbmRwb2ludCB0byBtb25pdG9yLlxuICAgKi9cbiAgcmVhZG9ubHkgZW5kcG9pbnQ6IGVjMi5JbnRlcmZhY2VWcGNFbmRwb2ludDtcbiAgLyoqXG4gICAqIFRoZSBWUEMgSUQgb2YgdGhlIFByaXZhdGVMaW5rIEludGVyZmFjZVZwY0VuZHBvaW50LlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjSWQ6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSB0eXBlIG9mIHRoZSBQcml2YXRlTGluayBJbnRlcmZhY2VWcGNFbmRwb2ludC5cbiAgICovXG4gIHJlYWRvbmx5IGVuZHBvaW50VHlwZTogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHNlcnZpY2UgbmFtZSBvZiB0aGUgUHJpdmF0ZUxpbmsgSW50ZXJmYWNlVnBjRW5kcG9pbnQuXG4gICAqL1xuICByZWFkb25seSBzZXJ2aWNlTmFtZTogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHN1Ym5ldCBJRCBvZiB0aGUgUHJpdmF0ZUxpbmsgSW50ZXJmYWNlVnBjRW5kcG9pbnQuXG4gICAqL1xuICByZWFkb25seSBzdWJuZXRJZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBQYWNrZXRzRHJvcHBlZCBhbGFybS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcml2YXRlTGlua0VuZHBvaW50c1BhY2tldHNEcm9wcGVkQWxhcm1Db25maWcgZXh0ZW5kcyBQcml2YXRlTGlua0VuZHBvaW50c0FsYXJtQmFzZUNvbmZpZyB7XG4gIC8qKlxuICAgKiBTZXQgdGhlIHRocmVzaG9sZCBhY2NvcmRpbmcgdG8gdGhlIHVzZSBjYXNlLiBJZiB5b3Ugd2FudCB0byBiZSBhd2FyZSBvZiB0aGUgdW5oZWFsdGh5IHN0YXR1cyBvZiB0aGUgZW5kcG9pbnQgb3IgZW5kcG9pbnQgc2VydmljZSxcbiAgICogeW91IHNob3VsZCBzZXQgdGhlIHRocmVzaG9sZCBsb3cgc28gdGhhdCB5b3UgZ2V0IGEgY2hhbmNlIHRvIGZpeCB0aGUgaXNzdWUgYmVmb3JlIGEgaHVnZSBkYXRhIGxvc3MuIFlvdSBjYW4gdXNlIGhpc3RvcmljYWwgZGF0YSB0b1xuICAgKiB1bmRlcnN0YW5kIHRoZSB0b2xlcmFuY2UgZm9yIGRyb3BwZWQgcGFja2V0cyBhbmQgc2V0IHRoZSB0aHJlc2hvbGQgYWNjb3JkaW5nbHkuXG4gICAqL1xuICByZWFkb25seSB0aHJlc2hvbGQ6IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgcGVyaW9kcyBvdmVyIHdoaWNoIGRhdGEgaXMgY29tcGFyZWQgdG8gdGhlIHNwZWNpZmllZCB0aHJlc2hvbGQuXG4gICAqXG4gICAqIEBkZWZhdWx0IDVcbiAgICovXG4gIHJlYWRvbmx5IGV2YWx1YXRpb25QZXJpb2RzPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBkYXRhIHBvaW50cyB0aGF0IG11c3QgYmUgYnJlYWNoaW5nIHRvIHRyaWdnZXIgdGhlIGFsYXJtLlxuICAgKlxuICAgKiBAZGVmYXVsdCA1XG4gICAqL1xuICByZWFkb25seSBkYXRhcG9pbnRzVG9BbGFybT86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBhbGFybSBuYW1lLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGVuZHBvaW50SWQgKyAnIC0gJyArIHN1Ym5ldElkICsgJyAtIFBhY2tldHNEcm9wcGVkJ1xuICAgKi9cbiAgcmVhZG9ubHkgYWxhcm1OYW1lPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBhbGFybS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBUaGlzIGFsYXJtIGlzIHVzZWQgdG8gZGV0ZWN0IGlmIHRoZSBlbmRwb2ludCBvciBlbmRwb2ludCBzZXJ2aWNlIGlzIHVuaGVhbHRoeS5cbiAgICovXG4gIHJlYWRvbmx5IGFsYXJtRGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgVlBDIElEIG9mIHRoZSBQcml2YXRlTGluayBJbnRlcmZhY2VWcGNFbmRwb2ludC5cbiAgICovXG4gIHJlYWRvbmx5IHZwY0lkOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgdHlwZSBvZiB0aGUgUHJpdmF0ZUxpbmsgSW50ZXJmYWNlVnBjRW5kcG9pbnQuXG4gICAqL1xuICByZWFkb25seSBlbmRwb2ludFR5cGU6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBzZXJ2aWNlIG5hbWUgb2YgdGhlIFByaXZhdGVMaW5rIEludGVyZmFjZVZwY0VuZHBvaW50LlxuICAgKi9cbiAgcmVhZG9ubHkgc2VydmljZU5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBzdWJuZXRzIG9mIHRoZSBQcml2YXRlTGluayBJbnRlcmZhY2VWcGNFbmRwb2ludC5cbiAgICovXG4gIHJlYWRvbmx5IHN1Ym5ldHM/OiBlYzIuSVN1Ym5ldFtdO1xufVxuXG4vKipcbiAqIFRoZSBwcm9wZXJ0aWVzIGZvciB0aGUgUHJpdmF0ZUxpbmtFbmRwb2ludHNJbnRlcmZhY2VWcGNFbmRwb2ludFBhY2tldHNEcm9wcGVkQWxhcm0gY29uc3RydWN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByaXZhdGVMaW5rRW5kcG9pbnRzSW50ZXJmYWNlVnBjRW5kcG9pbnRQYWNrZXRzRHJvcHBlZEFsYXJtUHJvcHMgZXh0ZW5kc1xuICBQcml2YXRlTGlua0VuZHBvaW50c0ludGVyZmFjZVZwY0VuZHBvaW50QWxhcm1Qcm9wcyxcbiAgUHJpdmF0ZUxpbmtFbmRwb2ludHNQYWNrZXRzRHJvcHBlZEFsYXJtQ29uZmlnIHt9XG5cbi8qKlxuICogVGhpcyBhbGFybSBoZWxwcyB0byBkZXRlY3QgaWYgdGhlIGVuZHBvaW50IG9yIGVuZHBvaW50IHNlcnZpY2UgaXMgdW5oZWFsdGh5IGJ5IG1vbml0b3JpbmcgdGhlIG51bWJlciBvZiBwYWNrZXRzIGRyb3BwZWQgYnkgdGhlIGVuZHBvaW50LlxuICpcbiAqIE5vdGUgdGhhdCBwYWNrZXRzIGxhcmdlciB0aGFuIDg1MDAgYnl0ZXMgdGhhdCBhcnJpdmUgYXQgdGhlIFZQQyBlbmRwb2ludCBhcmUgZHJvcHBlZC4gRm9yIHRyb3VibGVzaG9vdGluZyxcbiAqIHNlZSBjb25uZWN0aXZpdHkgcHJvYmxlbXMgYmV0d2VlbiBhbiBpbnRlcmZhY2UgVlBDIGVuZHBvaW50IGFuZCBhbiBlbmRwb2ludCBzZXJ2aWNlLlxuICpcbiAqIFRoZSBhbGFybSBpcyB0cmlnZ2VyZWQgd2hlbiB0aGUgbnVtYmVyIG9mIHBhY2tldHMgZHJvcHBlZCBleGNlZWRzIHRoZSB0aHJlc2hvbGQuXG4gKi9cbmV4cG9ydCBjbGFzcyBQcml2YXRlTGlua0VuZHBvaW50c0ludGVyZmFjZVZwY0VuZHBvaW50UGFja2V0c0Ryb3BwZWRBbGFybSBleHRlbmRzIGNsb3Vkd2F0Y2guQWxhcm0ge1xuICBjb25zdHJ1Y3RvcihzY29wZTogSUNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFByaXZhdGVMaW5rRW5kcG9pbnRzSW50ZXJmYWNlVnBjRW5kcG9pbnRQYWNrZXRzRHJvcHBlZEFsYXJtUHJvcHMpIHtcbiAgICBjb25zdCBhbGFybU5hbWUgPSBwcm9wcy5hbGFybU5hbWUgPz8gYCR7cHJvcHMuZW5kcG9pbnQudnBjRW5kcG9pbnRJZH0gLSAke3Byb3BzLnN1Ym5ldElkfSAtICR7UHJpdmF0ZUxpbmtFbmRwb2ludHNSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3MuUEFDS0VUU19EUk9QUEVEfWA7XG4gICAgY29uc3QgcGVyaW9kID0gcHJvcHMucGVyaW9kID8/IER1cmF0aW9uLm1pbnV0ZXMoMSk7XG4gICAgY29uc3QgZXZhbHVhdGlvblBlcmlvZHMgPSBwcm9wcy5ldmFsdWF0aW9uUGVyaW9kcyA/PyA1O1xuICAgIGNvbnN0IGRhdGFwb2ludHNUb0FsYXJtID0gcHJvcHMuZGF0YXBvaW50c1RvQWxhcm0gPz8gNTtcbiAgICBjb25zdCB0aHJlc2hvbGQgPSBwcm9wcy50aHJlc2hvbGQ7XG4gICAgY29uc3QgdHJlYXRNaXNzaW5nRGF0YSA9IHByb3BzLnRyZWF0TWlzc2luZ0RhdGEgPz8gY2xvdWR3YXRjaC5UcmVhdE1pc3NpbmdEYXRhLk1JU1NJTkc7XG4gICAgY29uc3QgYWxhcm1EZXNjcmlwdGlvbiA9IHByb3BzLmFsYXJtRGVzY3JpcHRpb24gPz8gJ1RoaXMgYWxhcm0gaXMgdXNlZCB0byBkZXRlY3QgaWYgdGhlIGVuZHBvaW50IG9yIGVuZHBvaW50IHNlcnZpY2UgaXMgdW5oZWFsdGh5Lic7XG5cbiAgICB2YWxpZGF0ZVRvdGFsQWxhcm1QZXJpb2QocGVyaW9kLCBldmFsdWF0aW9uUGVyaW9kcywgYWxhcm1OYW1lKTtcblxuICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuICAgICAgYWxhcm1OYW1lLFxuICAgICAgbWV0cmljOiBuZXcgY2xvdWR3YXRjaC5NZXRyaWMoe1xuICAgICAgICBuYW1lc3BhY2U6ICdBV1MvUHJpdmF0ZUxpbmtFbmRwb2ludHMnLFxuICAgICAgICBtZXRyaWNOYW1lOiBQcml2YXRlTGlua0VuZHBvaW50c1JlY29tbWVuZGVkQWxhcm1zTWV0cmljcy5QQUNLRVRTX0RST1BQRUQsXG4gICAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgICBWcGNFbmRwb2ludElkOiBwcm9wcy5lbmRwb2ludC52cGNFbmRwb2ludElkLFxuICAgICAgICAgIFZwY0lkOiBwcm9wcy52cGNJZCxcbiAgICAgICAgICBFbmRwb2ludFR5cGU6IHByb3BzLmVuZHBvaW50VHlwZSxcbiAgICAgICAgICBTZXJ2aWNlTmFtZTogcHJvcHMuc2VydmljZU5hbWUsXG4gICAgICAgICAgU3VibmV0SWQ6IHByb3BzLnN1Ym5ldElkLFxuICAgICAgICB9LFxuICAgICAgICBwZXJpb2QsXG4gICAgICAgIHN0YXRpc3RpYzogJ1N1bScsXG4gICAgICB9KSxcbiAgICAgIHRocmVzaG9sZCxcbiAgICAgIGV2YWx1YXRpb25QZXJpb2RzLFxuICAgICAgZGF0YXBvaW50c1RvQWxhcm0sXG4gICAgICB0cmVhdE1pc3NpbmdEYXRhLFxuICAgICAgY29tcGFyaXNvbk9wZXJhdG9yOiBjbG91ZHdhdGNoLkNvbXBhcmlzb25PcGVyYXRvci5HUkVBVEVSX1RIQU5fVEhSRVNIT0xELFxuICAgICAgYWxhcm1EZXNjcmlwdGlvbixcbiAgICB9KTtcblxuICAgIGlmIChwcm9wcy5hbGFybUFjdGlvbikgdGhpcy5hZGRBbGFybUFjdGlvbihwcm9wcy5hbGFybUFjdGlvbik7XG4gICAgaWYgKHByb3BzLm9rQWN0aW9uKSB0aGlzLmFkZE9rQWN0aW9uKHByb3BzLm9rQWN0aW9uKTtcbiAgICBpZiAocHJvcHMuaW5zdWZmaWNpZW50RGF0YUFjdGlvbikgdGhpcy5hZGRJbnN1ZmZpY2llbnREYXRhQWN0aW9uKHByb3BzLmluc3VmZmljaWVudERhdGFBY3Rpb24pO1xuICB9XG59O1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb25zIGZvciB0aGUgcmVjb21tZW5kZWQgYWxhcm1zIGZvciBhbiBQcml2YXRlTGluayBTZXJ2aWNlLlxuICpcbiAqIERlZmF1bHQgYWN0aW9ucyBhcmUgb3ZlcnJpZGRlbiBieSB0aGUgYWN0aW9ucyBzcGVjaWZpZWQgaW4gdGhlXG4gKiBpbmRpdmlkdWFsIGFsYXJtIGNvbmZpZ3VyYXRpb25zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByaXZhdGVMaW5rRW5kcG9pbnRzSW50ZXJmYWNlVnBjRW5kcG9pbnRSZWNvbW1lbmRlZEFsYXJtc0NvbmZpZyB7XG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCBhY3Rpb24gdG8gdGFrZSB3aGVuIGFuIGFsYXJtIGlzIHRyaWdnZXJlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBOb25lXG4gICAqL1xuICByZWFkb25seSBkZWZhdWx0QWxhcm1BY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvbjtcbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IGFjdGlvbiB0byB0YWtlIHdoZW4gYW4gYWxhcm0gZW50ZXJzIHRoZSBvayBzdGF0ZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBOb25lXG4gICAqL1xuICByZWFkb25seSBkZWZhdWx0T2tBY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvbjtcbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IGFjdGlvbiB0byB0YWtlIHdoZW4gYW4gYWxhcm0gaGFzIGluc3VmZmljaWVudCBkYXRhLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vbmVcbiAgICovXG4gIHJlYWRvbmx5IGRlZmF1bHRJbnN1ZmZpY2llbnREYXRhQWN0aW9uPzogY2xvdWR3YXRjaC5JQWxhcm1BY3Rpb247XG4gIC8qKlxuICAgKiBIb3cgdG8gaGFuZGxlIG1pc3NpbmcgZGF0YSBmb3IgdGhpcyBhbGFybS5cbiAgICpcbiAgICogQGRlZmF1bHQgVHJlYXRNaXNzaW5nRGF0YS5NSVNTSU5HXG4gICAqL1xuICByZWFkb25seSB0cmVhdE1pc3NpbmdEYXRhPzogY2xvdWR3YXRjaC5UcmVhdE1pc3NpbmdEYXRhO1xuICAvKipcbiAgICogQWxhcm0gbWV0cmljcyB0byBleGNsdWRlIGZyb20gdGhlIHJlY29tbWVuZGVkIGFsYXJtcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBOb25lXG4gICAqL1xuICByZWFkb25seSBleGNsdWRlQWxhcm1zPzogUHJpdmF0ZUxpbmtFbmRwb2ludHNSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3NbXTtcbiAgLyoqXG4gICAqIFRoZSByZXNvdXJjZXMgdG8gZXhjbHVkZSBmcm9tIHRoZSByZWNvbW1lbmRlZCBhbGFybXMuXG4gICAqXG4gICAqIFVzZSBhIHJlc291cmNlcyBpZCB0byBleGNsdWRlIGEgc3BlY2lmaWMgcmVzb3VyY2UuXG4gICAqL1xuICByZWFkb25seSBleGNsdWRlUmVzb3VyY2VzPzogc3RyaW5nW107XG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJhdGlvbiBmb3IgdGhlIFBhY2tldHNEcm9wcGVkIGFsYXJtLlxuICAgKi9cbiAgcmVhZG9ubHkgY29uZmlnUGFja2V0c0Ryb3BwZWRBbGFybTogUHJpdmF0ZUxpbmtFbmRwb2ludHNQYWNrZXRzRHJvcHBlZEFsYXJtQ29uZmlnO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIHRoZSBQcml2YXRlTGlua0VuZHBvaW50c0ludGVyZmFjZVZwY0VuZHBvaW50UmVjb21tZW5kZWRBbGFybXMgY29uc3RydWN0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByaXZhdGVMaW5rRW5kcG9pbnRzSW50ZXJmYWNlVnBjRW5kcG9pbnRSZWNvbW1lbmRlZEFsYXJtc1Byb3BzIGV4dGVuZHNcbiAgUHJpdmF0ZUxpbmtFbmRwb2ludHNJbnRlcmZhY2VWcGNFbmRwb2ludFJlY29tbWVuZGVkQWxhcm1zQ29uZmlnIHtcbiAgLyoqXG4gICAqIFRoZSBQcml2YXRlTGluayBJbnRlcmZhY2VWcGNFbmRwb2ludCB0byBtb25pdG9yLlxuICAgKi9cbiAgcmVhZG9ubHkgZW5kcG9pbnQ6IGVjMi5JbnRlcmZhY2VWcGNFbmRwb2ludDtcbn1cblxuLyoqXG4gKiBBIGNvbnN0cnVjdCB0aGF0IGNyZWF0ZXMgdGhlIHJlY29tbWVuZGVkIGFsYXJtcyBmb3IgYW4gUHJpdmF0ZUxpbmsgSW50ZXJmYWNlVnBjRW5kcG9pbnQuXG4gKlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvbW9uaXRvcmluZy9CZXN0X1ByYWN0aWNlX1JlY29tbWVuZGVkX0FsYXJtc19BV1NfU2VydmljZXMuaHRtbCNQcml2YXRlTGlua0VuZHBvaW50c1xuICovXG5leHBvcnQgY2xhc3MgUHJpdmF0ZUxpbmtFbmRwb2ludHNJbnRlcmZhY2VWcGNFbmRwb2ludFJlY29tbWVuZGVkQWxhcm1zIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgLyoqXG4gICAqIFRoZSBQYWNrZXRzRHJvcHBlZCBhbGFybS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBhbGFybVBhY2tldHNEcm9wcGVkTGlzdD86IFByaXZhdGVMaW5rRW5kcG9pbnRzSW50ZXJmYWNlVnBjRW5kcG9pbnRQYWNrZXRzRHJvcHBlZEFsYXJtW107XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFByaXZhdGVMaW5rRW5kcG9pbnRzSW50ZXJmYWNlVnBjRW5kcG9pbnRSZWNvbW1lbmRlZEFsYXJtc1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGlmICghcHJvcHMuZXhjbHVkZUFsYXJtcz8uaW5jbHVkZXMoUHJpdmF0ZUxpbmtFbmRwb2ludHNSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3MuUEFDS0VUU19EUk9QUEVEKSkge1xuICAgICAgdGhpcy5hbGFybVBhY2tldHNEcm9wcGVkTGlzdCA9IFtdO1xuXG4gICAgICBpZiAoIXByb3BzLmNvbmZpZ1BhY2tldHNEcm9wcGVkQWxhcm0uc3VibmV0cykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N1Ym5ldHMgbXVzdCBiZSBwcm92aWRlZCBmb3IgdGhlIFBhY2tldHNEcm9wcGVkIGFsYXJtLicpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IHN1Ym5ldCBvZiBwcm9wcy5jb25maWdQYWNrZXRzRHJvcHBlZEFsYXJtLnN1Ym5ldHMpIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0gcHJvcHMuY29uZmlnUGFja2V0c0Ryb3BwZWRBbGFybTtcbiAgICAgICAgY29uc3QgYWxhcm0gPSBuZXcgUHJpdmF0ZUxpbmtFbmRwb2ludHNJbnRlcmZhY2VWcGNFbmRwb2ludFBhY2tldHNEcm9wcGVkQWxhcm0odGhpcywgYCR7cHJvcHMuZW5kcG9pbnQubm9kZS5pZH1fJHtzdWJuZXQubm9kZS5pZH1fUGFja2V0c0Ryb3BwZWRgLCB7XG4gICAgICAgICAgZW5kcG9pbnQ6IHByb3BzLmVuZHBvaW50LFxuICAgICAgICAgIHZwY0lkOiBjb25maWcudnBjSWQsXG4gICAgICAgICAgZW5kcG9pbnRUeXBlOiBjb25maWcuZW5kcG9pbnRUeXBlLFxuICAgICAgICAgIHNlcnZpY2VOYW1lOiBjb25maWcuc2VydmljZU5hbWUsXG4gICAgICAgICAgc3VibmV0SWQ6IHN1Ym5ldC5zdWJuZXRJZCxcbiAgICAgICAgICB0aHJlc2hvbGQ6IGNvbmZpZy50aHJlc2hvbGQsXG4gICAgICAgICAgcGVyaW9kOiBjb25maWcucGVyaW9kLFxuICAgICAgICAgIGV2YWx1YXRpb25QZXJpb2RzOiBjb25maWcuZXZhbHVhdGlvblBlcmlvZHMsXG4gICAgICAgICAgZGF0YXBvaW50c1RvQWxhcm06IGNvbmZpZy5kYXRhcG9pbnRzVG9BbGFybSxcbiAgICAgICAgICBhbGFybU5hbWU6IGNvbmZpZy5hbGFybU5hbWUsXG4gICAgICAgICAgYWxhcm1EZXNjcmlwdGlvbjogY29uZmlnLmFsYXJtRGVzY3JpcHRpb24sXG4gICAgICAgICAgYWxhcm1BY3Rpb246IGNvbmZpZy5hbGFybUFjdGlvbixcbiAgICAgICAgICBva0FjdGlvbjogY29uZmlnLm9rQWN0aW9uLFxuICAgICAgICAgIGluc3VmZmljaWVudERhdGFBY3Rpb246IGNvbmZpZy5pbnN1ZmZpY2llbnREYXRhQWN0aW9uLFxuICAgICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IGNvbmZpZy50cmVhdE1pc3NpbmdEYXRhLFxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgcHJvcHMuZGVmYXVsdEFsYXJtQWN0aW9uICYmXG4gICAgICAgICAgKCFwcm9wcy5jb25maWdQYWNrZXRzRHJvcHBlZEFsYXJtIHx8ICFwcm9wcy5jb25maWdQYWNrZXRzRHJvcHBlZEFsYXJtLmFsYXJtQWN0aW9uKVxuICAgICAgICApIHtcbiAgICAgICAgICBhbGFybS5hZGRBbGFybUFjdGlvbihwcm9wcy5kZWZhdWx0QWxhcm1BY3Rpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHByb3BzLmRlZmF1bHRPa0FjdGlvbiAmJlxuICAgICAgICAgICghcHJvcHMuY29uZmlnUGFja2V0c0Ryb3BwZWRBbGFybSB8fCAhcHJvcHMuY29uZmlnUGFja2V0c0Ryb3BwZWRBbGFybS5va0FjdGlvbilcbiAgICAgICAgKSB7XG4gICAgICAgICAgYWxhcm0uYWRkT2tBY3Rpb24ocHJvcHMuZGVmYXVsdE9rQWN0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICBwcm9wcy5kZWZhdWx0SW5zdWZmaWNpZW50RGF0YUFjdGlvbiAmJlxuICAgICAgICAgICghcHJvcHMuY29uZmlnUGFja2V0c0Ryb3BwZWRBbGFybSB8fCAhcHJvcHMuY29uZmlnUGFja2V0c0Ryb3BwZWRBbGFybS5pbnN1ZmZpY2llbnREYXRhQWN0aW9uKVxuICAgICAgICApIHtcbiAgICAgICAgICBhbGFybS5hZGRJbnN1ZmZpY2llbnREYXRhQWN0aW9uKHByb3BzLmRlZmF1bHRJbnN1ZmZpY2llbnREYXRhQWN0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYWxhcm1QYWNrZXRzRHJvcHBlZExpc3QucHVzaChhbGFybSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQW4gZXh0ZW5zaW9uIGZvciB0aGUgSW50ZXJmYWNlVnBjRW5kcG9pbnQgY29uc3RydWN0IHRoYXQgcHJvdmlkZXMgbWV0aG9kc1xuICogdG8gY3JlYXRlIHJlY29tbWVuZGVkIGFsYXJtcy5cbiAqL1xuZXhwb3J0IGNsYXNzIEludGVyZmFjZVZwY0VuZHBvaW50IGV4dGVuZHMgZWMyLkludGVyZmFjZVZwY0VuZHBvaW50IHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IGVjMi5JbnRlcmZhY2VWcGNFbmRwb2ludFByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCBwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBhbGFybSB0aGF0IG1vbml0b3JzIHRoZSBQYWNrZXRzRHJvcHBlZCBmb3IgdGhlIFByaXZhdGVMaW5rIGVuZHBvaW50LlxuICAgKi9cbiAgcHVibGljIGFsYXJtUGFja2V0c0Ryb3BwZWQocHJvcHM6IFByaXZhdGVMaW5rRW5kcG9pbnRzUGFja2V0c0Ryb3BwZWRBbGFybUNvbmZpZyk6IFByaXZhdGVMaW5rRW5kcG9pbnRzSW50ZXJmYWNlVnBjRW5kcG9pbnRQYWNrZXRzRHJvcHBlZEFsYXJtW10ge1xuICAgIGxldCBhbGFybVBhY2tldHNEcm9wcGVkTGlzdCA9IFtdO1xuXG4gICAgaWYgKCFwcm9wcy5zdWJuZXRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N1Ym5ldHMgbXVzdCBiZSBwcm92aWRlZCBmb3IgdGhlIFBhY2tldHNEcm9wcGVkIGFsYXJtLicpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3Qgc3VibmV0IG9mIHByb3BzLnN1Ym5ldHMpIHtcbiAgICAgIGNvbnN0IGFsYXJtID0gbmV3IFByaXZhdGVMaW5rRW5kcG9pbnRzSW50ZXJmYWNlVnBjRW5kcG9pbnRQYWNrZXRzRHJvcHBlZEFsYXJtKHRoaXMsIGAke3RoaXMubm9kZS5pZH1fJHtzdWJuZXQubm9kZS5pZH1fUGFja2V0c0Ryb3BwZWRgLCB7XG4gICAgICAgIGVuZHBvaW50OiB0aGlzLFxuICAgICAgICB2cGNJZDogcHJvcHMudnBjSWQsXG4gICAgICAgIGVuZHBvaW50VHlwZTogcHJvcHMuZW5kcG9pbnRUeXBlLFxuICAgICAgICBzZXJ2aWNlTmFtZTogcHJvcHMuc2VydmljZU5hbWUsXG4gICAgICAgIHN1Ym5ldElkOiBzdWJuZXQuc3VibmV0SWQsXG4gICAgICAgIHRocmVzaG9sZDogcHJvcHMudGhyZXNob2xkLFxuICAgICAgICBwZXJpb2Q6IHByb3BzLnBlcmlvZCxcbiAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IHByb3BzLmV2YWx1YXRpb25QZXJpb2RzLFxuICAgICAgICBkYXRhcG9pbnRzVG9BbGFybTogcHJvcHMuZGF0YXBvaW50c1RvQWxhcm0sXG4gICAgICAgIGFsYXJtTmFtZTogcHJvcHMuYWxhcm1OYW1lLFxuICAgICAgICBhbGFybURlc2NyaXB0aW9uOiBwcm9wcy5hbGFybURlc2NyaXB0aW9uLFxuICAgICAgICBhbGFybUFjdGlvbjogcHJvcHMuYWxhcm1BY3Rpb24sXG4gICAgICAgIG9rQWN0aW9uOiBwcm9wcy5va0FjdGlvbixcbiAgICAgICAgaW5zdWZmaWNpZW50RGF0YUFjdGlvbjogcHJvcHMuaW5zdWZmaWNpZW50RGF0YUFjdGlvbixcbiAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogcHJvcHMudHJlYXRNaXNzaW5nRGF0YSxcbiAgICAgIH0pO1xuICAgICAgYWxhcm1QYWNrZXRzRHJvcHBlZExpc3QucHVzaChhbGFybSk7XG4gICAgfVxuICAgIHJldHVybiBhbGFybVBhY2tldHNEcm9wcGVkTGlzdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIHRoZSByZWNvbW1lbmRlZCBhbGFybXMgZm9yIHRoZSBQcml2YXRlTGluayBJbnRlcmZhY2VWcGNFbmRwb2ludC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRXYXRjaC9sYXRlc3QvbW9uaXRvcmluZy9CZXN0X1ByYWN0aWNlX1JlY29tbWVuZGVkX0FsYXJtc19BV1NfU2VydmljZXMuaHRtbCNQcml2YXRlTGlua0VuZHBvaW50c1xuICAgKi9cbiAgcHVibGljIGFwcGx5UmVjb21tZW5kZWRBbGFybXMoXG4gICAgcHJvcHM6IFByaXZhdGVMaW5rRW5kcG9pbnRzSW50ZXJmYWNlVnBjRW5kcG9pbnRSZWNvbW1lbmRlZEFsYXJtc0NvbmZpZyxcbiAgKTogUHJpdmF0ZUxpbmtFbmRwb2ludHNJbnRlcmZhY2VWcGNFbmRwb2ludFJlY29tbWVuZGVkQWxhcm1zIHtcbiAgICByZXR1cm4gbmV3IFByaXZhdGVMaW5rRW5kcG9pbnRzSW50ZXJmYWNlVnBjRW5kcG9pbnRSZWNvbW1lbmRlZEFsYXJtcyh0aGlzLCAnUHJpdmF0ZUxpbmtFbmRwb2ludHNJbnRlcmZhY2VWcGNFbmRwb2ludFJlY29tbWVuZGVkQWxhcm1zJywge1xuICAgICAgZW5kcG9pbnQ6IHRoaXMsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIFRoZSByZWNvbW1lbmRlZCBtZXRyaWNzIGZvciBQcml2YXRlTGluayBTZXJ2aWNlcyBhbGFybXMuXG4gKi9cbmV4cG9ydCBlbnVtIFByaXZhdGVMaW5rU2VydmljZXNSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3Mge1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBSU1QgcGFja2V0cyBzZW50IHRvIGVuZHBvaW50cyBieSB0aGUgZW5kcG9pbnQgc2VydmljZS4gSW5jcmVhc2luZyB2YWx1ZXMgY291bGQgaW5kaWNhdGVcbiAgICogdGhhdCB0aGVyZSBhcmUgdW5oZWFsdGh5IHRhcmdldHMuXG4gICAqL1xuICBSU1RfUEFDS0VUU19TRU5UID0gJ1JzdFBhY2tldHNTZW50Jyxcbn1cblxuLyoqXG4gKiBUaGUgY29tbW9uIG9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBhbGFybXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJpdmF0ZUxpbmtTZXJ2aWNlc0FsYXJtQmFzZUNvbmZpZyBleHRlbmRzIEFsYXJtQmFzZVByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBwZXJpb2Qgb3ZlciB3aGljaCB0aGUgc3BlY2lmaWVkIHN0YXRpc3RpYyBpcyBhcHBsaWVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBEdXJhdGlvbi5taW51dGVzKDEpXG4gICAqL1xuICByZWFkb25seSBwZXJpb2Q/OiBEdXJhdGlvbjtcbn1cblxuLyoqXG4gKiBUaGUgY29tbW9uIHByb3BlcnRpZXMgZm9yIHRoZSBQcml2YXRlTGluayBWcGNFbmRwb2ludFNlcnZpY2UgYWxhcm1zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByaXZhdGVMaW5rU2VydmljZXNWcGNFbmRwb2ludFNlcnZpY2VBbGFybVByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBQcml2YXRlTGluayBWcGNFbmRwb2ludFNlcnZpY2UgdG8gbW9uaXRvci5cbiAgICovXG4gIHJlYWRvbmx5IGVuZHBvaW50U2VydmljZTogZWMyLlZwY0VuZHBvaW50U2VydmljZTtcbiAgLyoqXG4gICAqIFRoZSBsb2FkIGJhbGFuY2VyIEFSTiBvZiB0aGUgUHJpdmF0ZUxpbmsgVnBjRW5kcG9pbnRTZXJ2aWNlLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9hZEJhbGFuY2VyQXJuOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgYXZhaWxhYmlsaXR5IHpvbmUgb2YgdGhlIFByaXZhdGVMaW5rIFZwY0VuZHBvaW50U2VydmljZS5cbiAgICovXG4gIHJlYWRvbmx5IGF6OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIFJzdFBhY2tldHNTZW50IGFsYXJtLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByaXZhdGVMaW5rU2VydmljZXNSc3RQYWNrZXRzU2VudEFsYXJtQ29uZmlnIGV4dGVuZHMgUHJpdmF0ZUxpbmtTZXJ2aWNlc0FsYXJtQmFzZUNvbmZpZyB7XG4gIC8qKlxuICAgKiBUaGUgdGhyZXNob2xkIGRlcGVuZHMgb24gdGhlIHVzZSBjYXNlLiBJZiB5b3VyIHVzZSBjYXNlIGNhbiB0b2xlcmF0ZSB0YXJnZXRzIGJlaW5nIHVuaGVhbHRoeSwgeW91IGNhbiBzZXQgdGhlIHRocmVzaG9sZCBoaWdoLlxuICAgKiBJZiB0aGUgdXNlIGNhc2UgY2Fu4oCZdCB0b2xlcmF0ZSB1bmhlYWx0aHkgdGFyZ2V0cyB5b3UgY2FuIHNldCB0aGUgdGhyZXNob2xkIHZlcnkgbG93LlxuICAgKi9cbiAgcmVhZG9ubHkgdGhyZXNob2xkOiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIHBlcmlvZHMgb3ZlciB3aGljaCBkYXRhIGlzIGNvbXBhcmVkIHRvIHRoZSBzcGVjaWZpZWQgdGhyZXNob2xkLlxuICAgKlxuICAgKiBAZGVmYXVsdCA1XG4gICAqL1xuICByZWFkb25seSBldmFsdWF0aW9uUGVyaW9kcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgZGF0YSBwb2ludHMgdGhhdCBtdXN0IGJlIGJyZWFjaGluZyB0byB0cmlnZ2VyIHRoZSBhbGFybS5cbiAgICpcbiAgICogQGRlZmF1bHQgNVxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YXBvaW50c1RvQWxhcm0/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgYWxhcm0gbmFtZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBlbmRwb2ludFNlcnZpY2VOYW1lICsgJyAtICcgKyBheiArICcgLSBSc3RQYWNrZXRzU2VudCdcbiAgICovXG4gIHJlYWRvbmx5IGFsYXJtTmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgYWxhcm0uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gVGhpcyBhbGFybSBpcyB1c2VkIHRvIGRldGVjdCB1bmhlYWx0aHkgdGFyZ2V0cyBvZiBhbiBlbmRwb2ludCBzZXJ2aWNlLlxuICAgKi9cbiAgcmVhZG9ubHkgYWxhcm1EZXNjcmlwdGlvbj86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBsb2FkIGJhbGFuY2VyIEFSTiBvZiB0aGUgUHJpdmF0ZUxpbmsgVnBjRW5kcG9pbnRTZXJ2aWNlLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9hZEJhbGFuY2VyQX