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.

237 lines 37.8 kB
"use strict"; var _a, _b, _c, _d, _e; Object.defineProperty(exports, "__esModule", { value: true }); exports.S3RecommendedAlarmsAspect = exports.Bucket = exports.S3RecommendedAlarms = exports.S3Bucket5xxErrorsAlarm = exports.S3Bucket4xxErrorsAlarm = exports.S3RecommendedAlarmsMetrics = 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 S3 bucket alarms. */ var S3RecommendedAlarmsMetrics; (function (S3RecommendedAlarmsMetrics) { /** * 4xxErrors are errors (4xx error codes) that are made in response to client requests. */ S3RecommendedAlarmsMetrics["ERRORS_4XX"] = "4xxErrors"; /** * 5xxErrors are server errors (5xx error codes) that are made in response to client requests. */ S3RecommendedAlarmsMetrics["ERRORS_5XX"] = "5xxErrors"; })(S3RecommendedAlarmsMetrics || (exports.S3RecommendedAlarmsMetrics = S3RecommendedAlarmsMetrics = {})); /** * An alarm that monitors the 4xx errors for an S3 bucket. * * This alarm is used to create a baseline for typical 4xx error * rates so that you can look into any abnormalities that might * indicate a setup issue. * * The alarm is triggered when the 4xx error rate exceeds the % threshold. */ class S3Bucket4xxErrorsAlarm extends aws_cdk_lib_1.aws_cloudwatch.Alarm { constructor(scope, id, props) { const alarmName = props.alarmName ?? `${props.bucket.bucketName} - ${S3RecommendedAlarmsMetrics.ERRORS_4XX}`; const period = props.period ?? aws_cdk_lib_1.Duration.minutes(1); const evaluationPeriods = props.evaluationPeriods ?? 15; (0, common_1.validateTotalAlarmPeriod)(period, evaluationPeriods, alarmName); super(scope, id, { alarmName, metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({ namespace: 'AWS/S3', metricName: S3RecommendedAlarmsMetrics.ERRORS_4XX, dimensionsMap: { BucketName: props.bucket.bucketName, FilterId: 'AllMetrics', }, period, statistic: 'Average', }), threshold: props.threshold ?? 0.05, evaluationPeriods, datapointsToAlarm: props.datapointsToAlarm ?? 15, treatMissingData: props.treatMissingData, comparisonOperator: aws_cdk_lib_1.aws_cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD, alarmDescription: props.alarmDescription ?? 'This alarm helps us report the total number of 4xx error status ' + 'codes that are made in response to client requests. 403 error codes might indicate an incorrect IAM policy, ' + 'and 404 error codes might indicate mis-behaving client application, for example. Enabling S3 server access ' + 'logging on a temporary basis will help you to pinpoint the issue\'s origin using the fields HTTP status and ' + 'Error Code. To understand more about the error code, see Error Responses ' + '(https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html).', }); if (props.alarmAction) this.addAlarmAction(props.alarmAction); if (props.okAction) this.addOkAction(props.okAction); if (props.insufficientDataAction) this.addInsufficientDataAction(props.insufficientDataAction); } } exports.S3Bucket4xxErrorsAlarm = S3Bucket4xxErrorsAlarm; _a = JSII_RTTI_SYMBOL_1; S3Bucket4xxErrorsAlarm[_a] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.S3Bucket4xxErrorsAlarm", version: "0.0.17" }; ; /** * An alarm that monitors the 5xx errors for an S3 bucket. * * This alarm can help to detect if the application is * experiencing issues due to 5xx errors. * * The alarm is triggered when the 5xx error rate exceeds the % threshold. */ class S3Bucket5xxErrorsAlarm extends aws_cdk_lib_1.aws_cloudwatch.Alarm { constructor(scope, id, props) { const alarmName = props.alarmName ?? `${props.bucket.bucketName} - ${S3RecommendedAlarmsMetrics.ERRORS_5XX}`; const period = props.period ?? aws_cdk_lib_1.Duration.minutes(1); const evaluationPeriods = props.evaluationPeriods ?? 15; (0, common_1.validateTotalAlarmPeriod)(period, evaluationPeriods, alarmName); super(scope, id, { alarmName, metric: new aws_cdk_lib_1.aws_cloudwatch.Metric({ namespace: 'AWS/S3', metricName: S3RecommendedAlarmsMetrics.ERRORS_5XX, dimensionsMap: { BucketName: props.bucket.bucketName, FilterId: 'AllMetrics', }, period, statistic: 'Average', }), threshold: props.threshold ?? 0.05, evaluationPeriods, datapointsToAlarm: props.datapointsToAlarm ?? 15, treatMissingData: props.treatMissingData, comparisonOperator: aws_cdk_lib_1.aws_cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD, alarmDescription: props.alarmDescription ?? 'This alarm helps you detect a high number of server-side errors. ' + 'These errors indicate that a client made a request that the server couldn\'t complete. This can help you ' + 'correlate the issue your application is facing because of S3. For more information to help you efficiently ' + 'handle or reduce errors, see Optimizing performance design patterns ' + '(https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance-design-patterns.html#optimizing-performance-timeouts-retries). ' + 'Errors might also be caused by an the issue with S3, check AWS service health dashboard for the status of Amazon S3 in your Region.', }); if (props.alarmAction) this.addAlarmAction(props.alarmAction); if (props.okAction) this.addOkAction(props.okAction); if (props.insufficientDataAction) this.addInsufficientDataAction(props.insufficientDataAction); } } exports.S3Bucket5xxErrorsAlarm = S3Bucket5xxErrorsAlarm; _b = JSII_RTTI_SYMBOL_1; S3Bucket5xxErrorsAlarm[_b] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.S3Bucket5xxErrorsAlarm", version: "0.0.17" }; ; /** * A construct that creates the recommended alarms for an S3 bucket. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#S3 */ class S3RecommendedAlarms extends constructs_1.Construct { constructor(scope, id, props) { super(scope, id); if (!props.excludeAlarms?.includes(S3RecommendedAlarmsMetrics.ERRORS_4XX)) { this.alarm4xxErrors = new S3Bucket4xxErrorsAlarm(this, `${props.bucket.node.id}_4xxErrorsAlarm`, { bucket: props.bucket, treatMissingData: props.treatMissingData, ...props.config4xxErrorsAlarm, }); if (props.defaultAlarmAction && !props.config4xxErrorsAlarm?.alarmAction) { this.alarm4xxErrors.addAlarmAction(props.defaultAlarmAction); } if (props.defaultOkAction && !props.config4xxErrorsAlarm?.okAction) { this.alarm4xxErrors.addOkAction(props.defaultOkAction); } if (props.defaultInsufficientDataAction && !props.config4xxErrorsAlarm?.insufficientDataAction) { this.alarm4xxErrors.addInsufficientDataAction(props.defaultInsufficientDataAction); } } if (!props.excludeAlarms?.includes(S3RecommendedAlarmsMetrics.ERRORS_5XX)) { this.alarm5xxErrors = new S3Bucket5xxErrorsAlarm(this, `${props.bucket.node.id}_5xxErrorsAlarm`, { bucket: props.bucket, treatMissingData: props.treatMissingData, ...props.config5xxErrorsAlarm, }); if (props.defaultAlarmAction && !props.config5xxErrorsAlarm?.alarmAction) { this.alarm5xxErrors.addAlarmAction(props.defaultAlarmAction); } if (props.defaultOkAction && !props.config5xxErrorsAlarm?.okAction) { this.alarm5xxErrors.addOkAction(props.defaultOkAction); } if (props.defaultInsufficientDataAction && !props.config5xxErrorsAlarm?.insufficientDataAction) { this.alarm5xxErrors.addInsufficientDataAction(props.defaultInsufficientDataAction); } } } } exports.S3RecommendedAlarms = S3RecommendedAlarms; _c = JSII_RTTI_SYMBOL_1; S3RecommendedAlarms[_c] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.S3RecommendedAlarms", version: "0.0.17" }; /** * An extension for the S3 Bucket construct that provides methods * to create recommended alarms. */ class Bucket extends aws_cdk_lib_1.aws_s3.Bucket { constructor(scope, id, props) { super(scope, id, props); } /** * Creates an alarm that monitors the 4xx errors for the S3 bucket. */ alarm4xxErrors(props) { return new S3Bucket4xxErrorsAlarm(this, '4xxErrorsAlarm', { bucket: this, ...props, }); } /** * Creates an alarm that monitors the 5xx errors for the S3 bucket. */ alarm5xxErrors(props) { return new S3Bucket5xxErrorsAlarm(this, '5xxErrorsAlarm', { bucket: this, ...props, }); } /** * Creates the recommended alarms for the S3 bucket. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#S3 */ applyRecommendedAlarms(props) { return new S3RecommendedAlarms(this, 'S3RecommendedAlarms', { bucket: this, ...props, }); } } exports.Bucket = Bucket; _d = JSII_RTTI_SYMBOL_1; Bucket[_d] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.Bucket", version: "0.0.17" }; /** * Configures the recommended alarms for an S3 bucket. * * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#S3 */ class S3RecommendedAlarmsAspect { constructor(props) { this.props = props; } visit(node) { if (node instanceof aws_cdk_lib_1.aws_s3.Bucket) { if (this.props?.excludeResources && this.props.excludeResources.includes(node.node.id)) { return; } else { const bucket = node; new S3RecommendedAlarms(bucket, 'S3RecommendedAlarmsFromAspect', { bucket, ...this.props, }); } } } } exports.S3RecommendedAlarmsAspect = S3RecommendedAlarmsAspect; _e = JSII_RTTI_SYMBOL_1; S3RecommendedAlarmsAspect[_e] = { fqn: "@renovosolutions/cdk-library-cloudwatch-alarms.S3RecommendedAlarmsAspect", version: "0.0.17" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiczMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvczMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2Q0FLcUI7QUFDckIsMkNBQW1EO0FBQ25ELHFDQUFvRTtBQUVwRTs7R0FFRztBQUNILElBQVksMEJBU1g7QUFURCxXQUFZLDBCQUEwQjtJQUNwQzs7T0FFRztJQUNILHNEQUF3QixDQUFBO0lBQ3hCOztPQUVHO0lBQ0gsc0RBQXdCLENBQUE7QUFDMUIsQ0FBQyxFQVRXLDBCQUEwQiwwQ0FBMUIsMEJBQTBCLFFBU3JDO0FBa0VEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBYSxzQkFBdUIsU0FBUSw0QkFBVSxDQUFDLEtBQUs7SUFDMUQsWUFBWSxLQUFpQixFQUFFLEVBQVUsRUFBRSxLQUFrQztRQUMzRSxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FBUyxJQUFJLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFVLE1BQU0sMEJBQTBCLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDN0csTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sSUFBSSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRCxNQUFNLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxpQkFBaUIsSUFBSSxFQUFFLENBQUM7UUFFeEQsSUFBQSxpQ0FBd0IsRUFBQyxNQUFNLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFL0QsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUU7WUFDZixTQUFTO1lBQ1QsTUFBTSxFQUFFLElBQUksNEJBQVUsQ0FBQyxNQUFNLENBQUM7Z0JBQzVCLFNBQVMsRUFBRSxRQUFRO2dCQUNuQixVQUFVLEVBQUUsMEJBQTBCLENBQUMsVUFBVTtnQkFDakQsYUFBYSxFQUFFO29CQUNiLFVBQVUsRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQVU7b0JBQ25DLFFBQVEsRUFBRSxZQUFZO2lCQUN2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LCtCQUErQixFQUFFO29CQUMvRCxNQUFNO29CQUNOLEdBQUcsSUFBSSxDQUFDLEtBQUs7aUJBQ2QsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDOztBQWhCSCw4REFpQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBJQXNwZWN0LFxuICBhd3NfczMgYXMgczMsXG4gIGF3c19jbG91ZHdhdGNoIGFzIGNsb3Vkd2F0Y2gsXG4gIER1cmF0aW9uLFxufSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBJQ29uc3RydWN0LCBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IEFsYXJtQmFzZVByb3BzLCB2YWxpZGF0ZVRvdGFsQWxhcm1QZXJpb2QgfSBmcm9tICcuL2NvbW1vbic7XG5cbi8qKlxuICogVGhlIHJlY29tbWVuZGVkIG1ldHJpY3MgZm9yIFMzIGJ1Y2tldCBhbGFybXMuXG4gKi9cbmV4cG9ydCBlbnVtIFMzUmVjb21tZW5kZWRBbGFybXNNZXRyaWNzIHtcbiAgLyoqXG4gICAqIDR4eEVycm9ycyBhcmUgZXJyb3JzICg0eHggZXJyb3IgY29kZXMpIHRoYXQgYXJlIG1hZGUgaW4gcmVzcG9uc2UgdG8gY2xpZW50IHJlcXVlc3RzLlxuICAgKi9cbiAgRVJST1JTXzRYWCA9ICc0eHhFcnJvcnMnLFxuICAvKipcbiAgICogNXh4RXJyb3JzIGFyZSBzZXJ2ZXIgZXJyb3JzICg1eHggZXJyb3IgY29kZXMpIHRoYXQgYXJlIG1hZGUgaW4gcmVzcG9uc2UgdG8gY2xpZW50IHJlcXVlc3RzLlxuICAgKi9cbiAgRVJST1JTXzVYWCA9ICc1eHhFcnJvcnMnLFxufVxuXG4vKipcbiAqIFRoZSBvcHRpb25hbCBjb25maWd1cmF0aW9uIGZvciB0aGUgNHh4IGFuZCA1eHggZXJyb3IgYWxhcm1zIGZvciBhbiBTMyBidWNrZXQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUzNCdWNrZXRIdHRwRXJyb3JzQWxhcm1Db25maWcgZXh0ZW5kcyBBbGFybUJhc2VQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgcGVyaW9kIG92ZXIgd2hpY2ggdGhlIHNwZWNpZmllZCBzdGF0aXN0aWMgaXMgYXBwbGllZC5cbiAgICpcbiAgICogQGRlZmF1bHQgRHVyYXRpb24ubWludXRlcygxKVxuICAgKi9cbiAgcmVhZG9ubHkgcGVyaW9kPzogRHVyYXRpb247XG4gIC8qKlxuICAgKiBUaGUgdmFsdWUgYWdhaW5zdCB3aGljaCB0aGUgc3BlY2lmaWVkIHN0YXRpc3RpYyBpcyBjb21wYXJlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgMC4wNVxuICAgKi9cbiAgcmVhZG9ubHkgdGhyZXNob2xkPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBwZXJpb2RzIG92ZXIgd2hpY2ggZGF0YSBpcyBjb21wYXJlZCB0byB0aGUgc3BlY2lmaWVkIHRocmVzaG9sZC5cbiAgICpcbiAgICogQGRlZmF1bHQgMTVcbiAgICovXG4gIHJlYWRvbmx5IGV2YWx1YXRpb25QZXJpb2RzPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBkYXRhIHBvaW50cyB0aGF0IG11c3QgYmUgYnJlYWNoaW5nIHRvIHRyaWdnZXIgdGhlIGFsYXJtLlxuICAgKlxuICAgKiBAZGVmYXVsdCAxNVxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YXBvaW50c1RvQWxhcm0/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIDR4eCBlcnJvcnMgYWxhcm0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUzNCdWNrZXQ0eHhFcnJvcnNBbGFybUNvbmZpZyBleHRlbmRzIFMzQnVja2V0SHR0cEVycm9yc0FsYXJtQ29uZmlnIHtcbiAgLyoqXG4gICAqIFRoZSBhbGFybSBuYW1lLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGJ1Y2tldC5idWNrZXROYW1lICsgJyAtIDR4eEVycm9ycydcbiAgICovXG4gIHJlYWRvbmx5IGFsYXJtTmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBhbGFybSBkZXNjcmlwdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBUaGlzIGFsYXJtIGhlbHBzIHVzIHJlcG9ydCB0aGUgdG90YWwgbnVtYmVyIG9mIDR4eCBlcnJvciBzdGF0dXMgY29kZXNcbiAgICogdGhhdCBhcmUgbWFkZSBpbiByZXNwb25zZSB0byBjbGllbnQgcmVxdWVzdHMuIDQwMyBlcnJvciBjb2RlcyBtaWdodCBpbmRpY2F0ZSBhblxuICAgKiBpbmNvcnJlY3QgSUFNIHBvbGljeSwgYW5kIDQwNCBlcnJvciBjb2RlcyBtaWdodCBpbmRpY2F0ZSBtaXMtYmVoYXZpbmcgY2xpZW50IGFwcGxpY2F0aW9uLFxuICAgKiBmb3IgZXhhbXBsZS4gRW5hYmxpbmcgUzMgc2VydmVyIGFjY2VzcyBsb2dnaW5nIG9uIGEgdGVtcG9yYXJ5IGJhc2lzIHdpbGwgaGVscCB5b3UgdG9cbiAgICogcGlucG9pbnQgdGhlIGlzc3VlJ3Mgb3JpZ2luIHVzaW5nIHRoZSBmaWVsZHMgSFRUUCBzdGF0dXMgYW5kIEVycm9yIENvZGUuIFRvIHVuZGVyc3RhbmRcbiAgICogbW9yZSBhYm91dCB0aGUgZXJyb3IgY29kZSwgc2VlIEVycm9yIFJlc3BvbnNlc1xuICAgKiAoaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvblMzL2xhdGVzdC9BUEkvRXJyb3JSZXNwb25zZXMuaHRtbCkuXG4gICAqL1xuICByZWFkb25seSBhbGFybURlc2NyaXB0aW9uPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIHRoZSBTM0J1Y2tldDR4eEVycm9yc0FsYXJtIGNvbnN0cnVjdC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTM0J1Y2tldDR4eEVycm9yc0FsYXJtUHJvcHMgZXh0ZW5kcyBTM0J1Y2tldDR4eEVycm9yc0FsYXJtQ29uZmlnIHtcbiAgLyoqXG4gICAqIFRoZSBTMyBidWNrZXQgdG8gbW9uaXRvci5cbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldDogczMuSUJ1Y2tldDtcbn1cblxuLyoqXG4gKiBBbiBhbGFybSB0aGF0IG1vbml0b3JzIHRoZSA0eHggZXJyb3JzIGZvciBhbiBTMyBidWNrZXQuXG4gKlxuICogVGhpcyBhbGFybSBpcyB1c2VkIHRvIGNyZWF0ZSBhIGJhc2VsaW5lIGZvciB0eXBpY2FsIDR4eCBlcnJvclxuICogcmF0ZXMgc28gdGhhdCB5b3UgY2FuIGxvb2sgaW50byBhbnkgYWJub3JtYWxpdGllcyB0aGF0IG1pZ2h0XG4gKiBpbmRpY2F0ZSBhIHNldHVwIGlzc3VlLlxuICpcbiAqIFRoZSBhbGFybSBpcyB0cmlnZ2VyZWQgd2hlbiB0aGUgNHh4IGVycm9yIHJhdGUgZXhjZWVkcyB0aGUgJSB0aHJlc2hvbGQuXG4gKi9cbmV4cG9ydCBjbGFzcyBTM0J1Y2tldDR4eEVycm9yc0FsYXJtIGV4dGVuZHMgY2xvdWR3YXRjaC5BbGFybSB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBJQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogUzNCdWNrZXQ0eHhFcnJvcnNBbGFybVByb3BzKSB7XG4gICAgY29uc3QgYWxhcm1OYW1lID0gcHJvcHMuYWxhcm1OYW1lID8/IGAke3Byb3BzLmJ1Y2tldC5idWNrZXROYW1lfSAtICR7UzNSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3MuRVJST1JTXzRYWH1gO1xuICAgIGNvbnN0IHBlcmlvZCA9IHByb3BzLnBlcmlvZCA/PyBEdXJhdGlvbi5taW51dGVzKDEpO1xuICAgIGNvbnN0IGV2YWx1YXRpb25QZXJpb2RzID0gcHJvcHMuZXZhbHVhdGlvblBlcmlvZHMgPz8gMTU7XG5cbiAgICB2YWxpZGF0ZVRvdGFsQWxhcm1QZXJpb2QocGVyaW9kLCBldmFsdWF0aW9uUGVyaW9kcywgYWxhcm1OYW1lKTtcblxuICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuICAgICAgYWxhcm1OYW1lLFxuICAgICAgbWV0cmljOiBuZXcgY2xvdWR3YXRjaC5NZXRyaWMoe1xuICAgICAgICBuYW1lc3BhY2U6ICdBV1MvUzMnLFxuICAgICAgICBtZXRyaWNOYW1lOiBTM1JlY29tbWVuZGVkQWxhcm1zTWV0cmljcy5FUlJPUlNfNFhYLFxuICAgICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgICAgQnVja2V0TmFtZTogcHJvcHMuYnVja2V0LmJ1Y2tldE5hbWUsXG4gICAgICAgICAgRmlsdGVySWQ6ICdBbGxNZXRyaWNzJyxcbiAgICAgICAgfSxcbiAgICAgICAgcGVyaW9kLFxuICAgICAgICBzdGF0aXN0aWM6ICdBdmVyYWdlJyxcbiAgICAgIH0pLFxuICAgICAgdGhyZXNob2xkOiBwcm9wcy50aHJlc2hvbGQgPz8gMC4wNSxcbiAgICAgIGV2YWx1YXRpb25QZXJpb2RzLFxuICAgICAgZGF0YXBvaW50c1RvQWxhcm06IHByb3BzLmRhdGFwb2ludHNUb0FsYXJtID8/IDE1LFxuICAgICAgdHJlYXRNaXNzaW5nRGF0YTogcHJvcHMudHJlYXRNaXNzaW5nRGF0YSxcbiAgICAgIGNvbXBhcmlzb25PcGVyYXRvcjogY2xvdWR3YXRjaC5Db21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX1RIUkVTSE9MRCxcbiAgICAgIGFsYXJtRGVzY3JpcHRpb246IHByb3BzLmFsYXJtRGVzY3JpcHRpb24gPz8gJ1RoaXMgYWxhcm0gaGVscHMgdXMgcmVwb3J0IHRoZSB0b3RhbCBudW1iZXIgb2YgNHh4IGVycm9yIHN0YXR1cyAnXG4gICAgICArICdjb2RlcyB0aGF0IGFyZSBtYWRlIGluIHJlc3BvbnNlIHRvIGNsaWVudCByZXF1ZXN0cy4gNDAzIGVycm9yIGNvZGVzIG1pZ2h0IGluZGljYXRlIGFuIGluY29ycmVjdCBJQU0gcG9saWN5LCAnXG4gICAgICArICdhbmQgNDA0IGVycm9yIGNvZGVzIG1pZ2h0IGluZGljYXRlIG1pcy1iZWhhdmluZyBjbGllbnQgYXBwbGljYXRpb24sIGZvciBleGFtcGxlLiBFbmFibGluZyBTMyBzZXJ2ZXIgYWNjZXNzICdcbiAgICAgICsgJ2xvZ2dpbmcgb24gYSB0ZW1wb3JhcnkgYmFzaXMgd2lsbCBoZWxwIHlvdSB0byBwaW5wb2ludCB0aGUgaXNzdWVcXCdzIG9yaWdpbiB1c2luZyB0aGUgZmllbGRzIEhUVFAgc3RhdHVzIGFuZCAnXG4gICAgICArICdFcnJvciBDb2RlLiBUbyB1bmRlcnN0YW5kIG1vcmUgYWJvdXQgdGhlIGVycm9yIGNvZGUsIHNlZSBFcnJvciBSZXNwb25zZXMgJ1xuICAgICAgKyAnKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvQVBJL0Vycm9yUmVzcG9uc2VzLmh0bWwpLicsXG4gICAgfSk7XG5cbiAgICBpZiAocHJvcHMuYWxhcm1BY3Rpb24pIHRoaXMuYWRkQWxhcm1BY3Rpb24ocHJvcHMuYWxhcm1BY3Rpb24pO1xuICAgIGlmIChwcm9wcy5va0FjdGlvbikgdGhpcy5hZGRPa0FjdGlvbihwcm9wcy5va0FjdGlvbik7XG4gICAgaWYgKHByb3BzLmluc3VmZmljaWVudERhdGFBY3Rpb24pIHRoaXMuYWRkSW5zdWZmaWNpZW50RGF0YUFjdGlvbihwcm9wcy5pbnN1ZmZpY2llbnREYXRhQWN0aW9uKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciB0aGUgNXh4IGVycm9ycyBhbGFybS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTM0J1Y2tldDV4eEVycm9yc0FsYXJtQ29uZmlnIGV4dGVuZHMgUzNCdWNrZXRIdHRwRXJyb3JzQWxhcm1Db25maWcge1xuICAvKipcbiAgICogVGhlIGFsYXJtIG5hbWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYnVja2V0LmJ1Y2tldE5hbWUgKyAnIC0gNXh4RXJyb3JzJ1xuICAgKi9cbiAgcmVhZG9ubHkgYWxhcm1OYW1lPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGFsYXJtIGRlc2NyaXB0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFRoaXMgYWxhcm0gaGVscHMgeW91IGRldGVjdCBhIGhpZ2ggbnVtYmVyIG9mIHNlcnZlci1zaWRlIGVycm9ycy4gVGhlc2UgZXJyb3JzIGluZGljYXRlXG4gICAqIHRoYXQgYSBjbGllbnQgbWFkZSBhIHJlcXVlc3QgdGhhdCB0aGUgc2VydmVyIGNvdWxkbuKAmXQgY29tcGxldGUuIFRoaXMgY2FuIGhlbHAgeW91IGNvcnJlbGF0ZSB0aGVcbiAgICogaXNzdWUgeW91ciBhcHBsaWNhdGlvbiBpcyBmYWNpbmcgYmVjYXVzZSBvZiBTMy4gRm9yIG1vcmUgaW5mb3JtYXRpb24gdG8gaGVscCB5b3UgZWZmaWNpZW50bHlcbiAgICogaGFuZGxlIG9yIHJlZHVjZSBlcnJvcnMsIHNlZSBPcHRpbWl6aW5nIHBlcmZvcm1hbmNlIGRlc2lnbiBwYXR0ZXJuc1xuICAgKiAoaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvblMzL2xhdGVzdC91c2VyZ3VpZGUvb3B0aW1pemluZy1wZXJmb3JtYW5jZS1kZXNpZ24tcGF0dGVybnMuaHRtbCNvcHRpbWl6aW5nLXBlcmZvcm1hbmNlLXRpbWVvdXRzLXJldHJpZXMpLlxuICAgKiBFcnJvcnMgbWlnaHQgYWxzbyBiZSBjYXVzZWQgYnkgYW4gdGhlIGlzc3VlIHdpdGggUzMsIGNoZWNrIEFXUyBzZXJ2aWNlIGhlYWx0aCBkYXNoYm9hcmQgZm9yIHRoZSBzdGF0dXMgb2YgQW1hem9uIFMzIGluIHlvdXIgUmVnaW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgYWxhcm1EZXNjcmlwdGlvbj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciB0aGUgUzNCdWNrZXQ1eHhFcnJvcnNBbGFybSBjb25zdHJ1Y3QuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUzNCdWNrZXQ1eHhFcnJvcnNBbGFybVByb3BzIGV4dGVuZHMgUzNCdWNrZXQ1eHhFcnJvcnNBbGFybUNvbmZpZyB7XG4gIC8qKlxuICAgKiBUaGUgUzMgYnVja2V0IHRvIG1vbml0b3IuXG4gICAqL1xuICByZWFkb25seSBidWNrZXQ6IHMzLklCdWNrZXQ7XG59XG5cbi8qKlxuICogQW4gYWxhcm0gdGhhdCBtb25pdG9ycyB0aGUgNXh4IGVycm9ycyBmb3IgYW4gUzMgYnVja2V0LlxuICpcbiAqIFRoaXMgYWxhcm0gY2FuIGhlbHAgdG8gZGV0ZWN0IGlmIHRoZSBhcHBsaWNhdGlvbiBpc1xuICogZXhwZXJpZW5jaW5nIGlzc3VlcyBkdWUgdG8gNXh4IGVycm9ycy5cbiAqXG4gKiBUaGUgYWxhcm0gaXMgdHJpZ2dlcmVkIHdoZW4gdGhlIDV4eCBlcnJvciByYXRlIGV4Y2VlZHMgdGhlICUgdGhyZXNob2xkLlxuICovXG5leHBvcnQgY2xhc3MgUzNCdWNrZXQ1eHhFcnJvcnNBbGFybSBleHRlbmRzIGNsb3Vkd2F0Y2guQWxhcm0ge1xuICBjb25zdHJ1Y3RvcihzY29wZTogSUNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFMzQnVja2V0NXh4RXJyb3JzQWxhcm1Qcm9wcykge1xuICAgIGNvbnN0IGFsYXJtTmFtZSA9IHByb3BzLmFsYXJtTmFtZSA/PyBgJHtwcm9wcy5idWNrZXQuYnVja2V0TmFtZX0gLSAke1MzUmVjb21tZW5kZWRBbGFybXNNZXRyaWNzLkVSUk9SU181WFh9YDtcbiAgICBjb25zdCBwZXJpb2QgPSBwcm9wcy5wZXJpb2QgPz8gRHVyYXRpb24ubWludXRlcygxKTtcbiAgICBjb25zdCBldmFsdWF0aW9uUGVyaW9kcyA9IHByb3BzLmV2YWx1YXRpb25QZXJpb2RzID8/IDE1O1xuXG4gICAgdmFsaWRhdGVUb3RhbEFsYXJtUGVyaW9kKHBlcmlvZCwgZXZhbHVhdGlvblBlcmlvZHMsIGFsYXJtTmFtZSk7XG5cbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIGFsYXJtTmFtZSxcbiAgICAgIG1ldHJpYzogbmV3IGNsb3Vkd2F0Y2guTWV0cmljKHtcbiAgICAgICAgbmFtZXNwYWNlOiAnQVdTL1MzJyxcbiAgICAgICAgbWV0cmljTmFtZTogUzNSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3MuRVJST1JTXzVYWCxcbiAgICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICAgIEJ1Y2tldE5hbWU6IHByb3BzLmJ1Y2tldC5idWNrZXROYW1lLFxuICAgICAgICAgIEZpbHRlcklkOiAnQWxsTWV0cmljcycsXG4gICAgICAgIH0sXG4gICAgICAgIHBlcmlvZCxcbiAgICAgICAgc3RhdGlzdGljOiAnQXZlcmFnZScsXG4gICAgICB9KSxcbiAgICAgIHRocmVzaG9sZDogcHJvcHMudGhyZXNob2xkID8/IDAuMDUsXG4gICAgICBldmFsdWF0aW9uUGVyaW9kcyxcbiAgICAgIGRhdGFwb2ludHNUb0FsYXJtOiBwcm9wcy5kYXRhcG9pbnRzVG9BbGFybSA/PyAxNSxcbiAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IHByb3BzLnRyZWF0TWlzc2luZ0RhdGEsXG4gICAgICBjb21wYXJpc29uT3BlcmF0b3I6IGNsb3Vkd2F0Y2guQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9USFJFU0hPTEQsXG4gICAgICBhbGFybURlc2NyaXB0aW9uOiBwcm9wcy5hbGFybURlc2NyaXB0aW9uID8/ICdUaGlzIGFsYXJtIGhlbHBzIHlvdSBkZXRlY3QgYSBoaWdoIG51bWJlciBvZiBzZXJ2ZXItc2lkZSBlcnJvcnMuICdcbiAgICAgICAgKyAnVGhlc2UgZXJyb3JzIGluZGljYXRlIHRoYXQgYSBjbGllbnQgbWFkZSBhIHJlcXVlc3QgdGhhdCB0aGUgc2VydmVyIGNvdWxkblxcJ3QgY29tcGxldGUuIFRoaXMgY2FuIGhlbHAgeW91ICdcbiAgICAgICAgKyAnY29ycmVsYXRlIHRoZSBpc3N1ZSB5b3VyIGFwcGxpY2F0aW9uIGlzIGZhY2luZyBiZWNhdXNlIG9mIFMzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiB0byBoZWxwIHlvdSBlZmZpY2llbnRseSAnXG4gICAgICAgICsgJ2hhbmRsZSBvciByZWR1Y2UgZXJyb3JzLCBzZWUgT3B0aW1pemluZyBwZXJmb3JtYW5jZSBkZXNpZ24gcGF0dGVybnMgJ1xuICAgICAgICArICcoaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvblMzL2xhdGVzdC91c2VyZ3VpZGUvb3B0aW1pemluZy1wZXJmb3JtYW5jZS1kZXNpZ24tcGF0dGVybnMuaHRtbCNvcHRpbWl6aW5nLXBlcmZvcm1hbmNlLXRpbWVvdXRzLXJldHJpZXMpLiAnXG4gICAgICAgICsgJ0Vycm9ycyBtaWdodCBhbHNvIGJlIGNhdXNlZCBieSBhbiB0aGUgaXNzdWUgd2l0aCBTMywgY2hlY2sgQVdTIHNlcnZpY2UgaGVhbHRoIGRhc2hib2FyZCBmb3IgdGhlIHN0YXR1cyBvZiBBbWF6b24gUzMgaW4geW91ciBSZWdpb24uJyxcbiAgICB9KTtcblxuICAgIGlmIChwcm9wcy5hbGFybUFjdGlvbikgdGhpcy5hZGRBbGFybUFjdGlvbihwcm9wcy5hbGFybUFjdGlvbik7XG4gICAgaWYgKHByb3BzLm9rQWN0aW9uKSB0aGlzLmFkZE9rQWN0aW9uKHByb3BzLm9rQWN0aW9uKTtcbiAgICBpZiAocHJvcHMuaW5zdWZmaWNpZW50RGF0YUFjdGlvbikgdGhpcy5hZGRJbnN1ZmZpY2llbnREYXRhQWN0aW9uKHByb3BzLmluc3VmZmljaWVudERhdGFBY3Rpb24pO1xuICB9XG59O1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb25zIGZvciB0aGUgcmVjb21tZW5kZWQgYWxhcm1zIGZvciBhbiBTMyBidWNrZXQuXG4gKlxuICogRGVmYXVsdCBhY3Rpb25zIGFyZSBvdmVycmlkZGVuIGJ5IHRoZSBhY3Rpb25zIHNwZWNpZmllZCBpbiB0aGVcbiAqIGluZGl2aWR1YWwgYWxhcm0gY29uZmlndXJhdGlvbnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUzNSZWNvbW1lbmRlZEFsYXJtc0NvbmZpZyB7XG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCBhY3Rpb24gdG8gdGFrZSB3aGVuIGFuIGFsYXJtIGlzIHRyaWdnZXJlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBOb25lXG4gICAqL1xuICByZWFkb25seSBkZWZhdWx0QWxhcm1BY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvbjtcbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IGFjdGlvbiB0byB0YWtlIHdoZW4gYW4gYWxhcm0gZW50ZXJzIHRoZSBvayBzdGF0ZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBOb25lXG4gICAqL1xuICByZWFkb25seSBkZWZhdWx0T2tBY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvbjtcbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IGFjdGlvbiB0byB0YWtlIHdoZW4gYW4gYWxhcm0gaGFzIGluc3VmZmljaWVudCBkYXRhLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vbmVcbiAgICovXG4gIHJlYWRvbmx5IGRlZmF1bHRJbnN1ZmZpY2llbnREYXRhQWN0aW9uPzogY2xvdWR3YXRjaC5JQWxhcm1BY3Rpb247XG4gIC8qKlxuICAgKiBIb3cgdG8gaGFuZGxlIG1pc3NpbmcgZGF0YSBmb3IgdGhpcyBhbGFybS5cbiAgICpcbiAgICogQGRlZmF1bHQgVHJlYXRNaXNzaW5nRGF0YS5NSVNTSU5HXG4gICAqL1xuICByZWFkb25seSB0cmVhdE1pc3NpbmdEYXRhPzogY2xvdWR3YXRjaC5UcmVhdE1pc3NpbmdEYXRhO1xuICAvKipcbiAgICogQWxhcm0gbWV0cmljcyB0byBleGNsdWRlIGZyb20gdGhlIHJlY29tbWVuZGVkIGFsYXJtcy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBOb25lXG4gICAqL1xuICByZWFkb25seSBleGNsdWRlQWxhcm1zPzogUzNSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3NbXTtcbiAgLyoqXG4gICAqIFRoZSByZXNvdXJjZXMgdG8gZXhjbHVkZSBmcm9tIHRoZSByZWNvbW1lbmRlZCBhbGFybXMuXG4gICAqXG4gICAqIFVzZSBhIHJlc291cmNlcyBpZCB0byBleGNsdWRlIGEgc3BlY2lmaWMgcmVzb3VyY2UuXG4gICAqL1xuICByZWFkb25seSBleGNsdWRlUmVzb3VyY2VzPzogc3RyaW5nW107XG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJhdGlvbiBmb3IgdGhlIDR4eCBlcnJvcnMgYWxhcm0uXG4gICAqL1xuICByZWFkb25seSBjb25maWc0eHhFcnJvcnNBbGFybT86IFMzQnVja2V0NHh4RXJyb3JzQWxhcm1Db25maWc7XG4gIC8qKlxuICAgKiBUaGUgY29uZmlndXJhdGlvbiBmb3IgdGhlIDV4eCBlcnJvcnMgYWxhcm0uXG4gICAqL1xuICByZWFkb25seSBjb25maWc1eHhFcnJvcnNBbGFybT86IFMzQnVja2V0NXh4RXJyb3JzQWxhcm1Db25maWc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUzNSZWNvbW1lbmRlZEFsYXJtc1Byb3BzIGV4dGVuZHMgUzNSZWNvbW1lbmRlZEFsYXJtc0NvbmZpZyB7XG4gIC8qKlxuICAgKiBUaGUgUzMgYnVja2V0IHRvIGFwcGx5IHRoZSByZWNvbW1lbmRlZCBhbGFybXMgdG8uXG4gICAqL1xuICByZWFkb25seSBidWNrZXQ6IHMzLklCdWNrZXQ7XG59XG5cbi8qKlxuICogQSBjb25zdHJ1Y3QgdGhhdCBjcmVhdGVzIHRoZSByZWNvbW1lbmRlZCBhbGFybXMgZm9yIGFuIFMzIGJ1Y2tldC5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZFdhdGNoL2xhdGVzdC9tb25pdG9yaW5nL0Jlc3RfUHJhY3RpY2VfUmVjb21tZW5kZWRfQWxhcm1zX0FXU19TZXJ2aWNlcy5odG1sI1MzXG4gKi9cbmV4cG9ydCBjbGFzcyBTM1JlY29tbWVuZGVkQWxhcm1zIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgLyoqXG4gICAqIFRoZSA0eHggZXJyb3JzIGFsYXJtLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFsYXJtNHh4RXJyb3JzPzogUzNCdWNrZXQ0eHhFcnJvcnNBbGFybTtcbiAgLyoqXG4gICAqIFRoZSA1eHggZXJyb3JzIGFsYXJtLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFsYXJtNXh4RXJyb3JzPzogUzNCdWNrZXQ1eHhFcnJvcnNBbGFybTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogUzNSZWNvbW1lbmRlZEFsYXJtc1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGlmICghcHJvcHMuZXhjbHVkZUFsYXJtcz8uaW5jbHVkZXMoUzNSZWNvbW1lbmRlZEFsYXJtc01ldHJpY3MuRVJST1JTXzRYWCkpIHtcbiAgICAgIHRoaXMuYWxhcm00eHhFcnJvcnMgPSBuZXcgUzNCdWNrZXQ0eHhFcnJvcnNBbGFybSh0aGlzLCBgJHtwcm9wcy5idWNrZXQubm9kZS5pZH1fNHh4RXJyb3JzQWxhcm1gLCB7XG4gICAgICAgIGJ1Y2tldDogcHJvcHMuYnVja2V0LFxuICAgICAgICB0cmVhdE1pc3NpbmdEYXRhOiBwcm9wcy50cmVhdE1pc3NpbmdEYXRhLFxuICAgICAgICAuLi5wcm9wcy5jb25maWc0eHhFcnJvcnNBbGFybSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAocHJvcHMuZGVmYXVsdEFsYXJtQWN0aW9uICYmICFwcm9wcy5jb25maWc0eHhFcnJvcnNBbGFybT8uYWxhcm1BY3Rpb24pIHtcbiAgICAgICAgdGhpcy5hbGFybTR4eEVycm9ycy5hZGRBbGFybUFjdGlvbihwcm9wcy5kZWZhdWx0QWxhcm1BY3Rpb24pO1xuICAgICAgfVxuXG4gICAgICBpZiAocHJvcHMuZGVmYXVsdE9rQWN0aW9uICYmICFwcm9wcy5jb25maWc0eHhFcnJvcnNBbGFybT8ub2tBY3Rpb24pIHtcbiAgICAgICAgdGhpcy5hbGFybTR4eEVycm9ycy5hZGRPa0FjdGlvbihwcm9wcy5kZWZhdWx0T2tBY3Rpb24pO1xuICAgICAgfVxuXG4gICAgICBpZiAocHJvcHMuZGVmYXVsdEluc3VmZmljaWVudERhdGFBY3Rpb24gJiYgIXByb3BzLmNvbmZpZzR4eEVycm9yc0FsYXJtPy5pbnN1ZmZpY2llbnREYXRhQWN0aW9uKSB7XG4gICAgICAgIHRoaXMuYWxhcm00eHhFcnJvcnMuYWRkSW5zdWZmaWNpZW50RGF0YUFjdGlvbihwcm9wcy5kZWZhdWx0SW5zdWZmaWNpZW50RGF0YUFjdGlvbik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFwcm9wcy5leGNsdWRlQWxhcm1zPy5pbmNsdWRlcyhTM1JlY29tbWVuZGVkQWxhcm1zTWV0cmljcy5FUlJPUlNfNVhYKSkge1xuICAgICAgdGhpcy5hbGFybTV4eEVycm9ycyA9IG5ldyBTM0J1Y2tldDV4eEVycm9yc0FsYXJtKHRoaXMsIGAke3Byb3BzLmJ1Y2tldC5ub2RlLmlkfV81eHhFcnJvcnNBbGFybWAsIHtcbiAgICAgICAgYnVja2V0OiBwcm9wcy5idWNrZXQsXG4gICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IHByb3BzLnRyZWF0TWlzc2luZ0RhdGEsXG4gICAgICAgIC4uLnByb3BzLmNvbmZpZzV4eEVycm9yc0FsYXJtLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChwcm9wcy5kZWZhdWx0QWxhcm1BY3Rpb24gJiYgIXByb3BzLmNvbmZpZzV4eEVycm9yc0FsYXJtPy5hbGFybUFjdGlvbikge1xuICAgICAgICB0aGlzLmFsYXJtNXh4RXJyb3JzLmFkZEFsYXJtQWN0aW9uKHByb3BzLmRlZmF1bHRBbGFybUFjdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wcy5kZWZhdWx0T2tBY3Rpb24gJiYgIXByb3BzLmNvbmZpZzV4eEVycm9yc0FsYXJtPy5va0FjdGlvbikge1xuICAgICAgICB0aGlzLmFsYXJtNXh4RXJyb3JzLmFkZE9rQWN0aW9uKHByb3BzLmRlZmF1bHRPa0FjdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wcy5kZWZhdWx0SW5zdWZmaWNpZW50RGF0YUFjdGlvbiAmJiAhcHJvcHMuY29uZmlnNXh4RXJyb3JzQWxhcm0/Lmluc3VmZmljaWVudERhdGFBY3Rpb24pIHtcbiAgICAgICAgdGhpcy5hbGFybTV4eEVycm9ycy5hZGRJbnN1ZmZpY2llbnREYXRhQWN0aW9uKHByb3BzLmRlZmF1bHRJbnN1ZmZpY2llbnREYXRhQWN0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBBbiBleHRlbnNpb24gZm9yIHRoZSBTMyBCdWNrZXQgY29uc3RydWN0IHRoYXQgcHJvdmlkZXMgbWV0aG9kc1xuICogdG8gY3JlYXRlIHJlY29tbWVuZGVkIGFsYXJtcy5cbiAqL1xuZXhwb3J0IGNsYXNzIEJ1Y2tldCBleHRlbmRzIHMzLkJ1Y2tldCB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzPzogczMuQnVja2V0UHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGFsYXJtIHRoYXQgbW9uaXRvcnMgdGhlIDR4eCBlcnJvcnMgZm9yIHRoZSBTMyBidWNrZXQuXG4gICAqL1xuICBwdWJsaWMgYWxhcm00eHhFcnJvcnMocHJvcHM/OiBTM0J1Y2tldDR4eEVycm9yc0FsYXJtQ29uZmlnKTogUzNCdWNrZXQ0eHhFcnJvcnNBbGFybSB7XG4gICAgcmV0dXJuIG5ldyBTM0J1Y2tldDR4eEVycm9yc0FsYXJtKHRoaXMsICc0eHhFcnJvcnNBbGFybScsIHtcbiAgICAgIGJ1Y2tldDogdGhpcyxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gYWxhcm0gdGhhdCBtb25pdG9ycyB0aGUgNXh4IGVycm9ycyBmb3IgdGhlIFMzIGJ1Y2tldC5cbiAgICovXG4gIHB1YmxpYyBhbGFybTV4eEVycm9ycyhwcm9wcz86IFMzQnVja2V0NXh4RXJyb3JzQWxhcm1Db25maWcpOiBTM0J1Y2tldDV4eEVycm9yc0FsYXJtIHtcbiAgICByZXR1cm4gbmV3IFMzQnVja2V0NXh4RXJyb3JzQWxhcm0odGhpcywgJzV4eEVycm9yc0FsYXJtJywge1xuICAgICAgYnVja2V0OiB0aGlzLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgcmVjb21tZW5kZWQgYWxhcm1zIGZvciB0aGUgUzMgYnVja2V0LlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZFdhdGNoL2xhdGVzdC9tb25pdG9yaW5nL0Jlc3RfUHJhY3RpY2VfUmVjb21tZW5kZWRfQWxhcm1zX0FXU19TZXJ2aWNlcy5odG1sI1MzXG4gICAqL1xuICBwdWJsaWMgYXBwbHlSZWNvbW1lbmRlZEFsYXJtcyhwcm9wcz86IFMzUmVjb21tZW5kZWRBbGFybXNDb25maWcpOiBTM1JlY29tbWVuZGVkQWxhcm1zIHtcbiAgICByZXR1cm4gbmV3IFMzUmVjb21tZW5kZWRBbGFybXModGhpcywgJ1MzUmVjb21tZW5kZWRBbGFybXMnLCB7XG4gICAgICBidWNrZXQ6IHRoaXMsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIENvbmZpZ3VyZXMgdGhlIHJlY29tbWVuZGVkIGFsYXJtcyBmb3IgYW4gUzMgYnVja2V0LlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L21vbml0b3JpbmcvQmVzdF9QcmFjdGljZV9SZWNvbW1lbmRlZF9BbGFybXNfQVdTX1NlcnZpY2VzLmh0bWwjUzNcbiAqL1xuZXhwb3J0IGNsYXNzIFMzUmVjb21tZW5kZWRBbGFybXNBc3BlY3QgaW1wbGVtZW50cyBJQXNwZWN0IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBwcm9wcz86IFMzUmVjb21tZW5kZWRBbGFybXNDb25maWcpIHt9XG5cbiAgcHVibGljIHZpc2l0KG5vZGU6IElDb25zdHJ1Y3QpOiB2b2lkIHtcbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIHMzLkJ1Y2tldCkge1xuICAgICAgaWYgKHRoaXMucHJvcHM/LmV4Y2x1ZGVSZXNvdXJjZXMgJiYgdGhpcy5wcm9wcy5leGNsdWRlUmVzb3VyY2VzLmluY2x1ZGVzKG5vZGUubm9kZS5pZCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgYnVja2V0ID0gbm9kZSBhcyBzMy5CdWNrZXQ7XG5cbiAgICAgICAgbmV3IFMzUmVjb21tZW5kZWRBbGFybXMoYnVja2V0LCAnUzNSZWNvbW1lbmRlZEFsYXJtc0Zyb21Bc3BlY3QnLCB7XG4gICAgICAgICAgYnVja2V0LFxuICAgICAgICAgIC4uLnRoaXMucHJvcHMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19