UNPKG

aws-cdk

Version:

CDK Toolkit, the command line tool for CDK apps

243 lines 37 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable import/order */ const chalk_1 = require("chalk"); const console_listener_1 = require("./console-listener"); const stack_activity_monitor_1 = require("../../lib/api/util/cloudformation/stack-activity-monitor"); let TIMESTAMP; let HUMAN_TIME; beforeAll(() => { TIMESTAMP = new Date().getTime(); HUMAN_TIME = new Date(TIMESTAMP).toLocaleTimeString(); }); test('prints 0/4 progress report, when addActivity is called with an "IN_PROGRESS" ResourceStatus', () => { const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ resourceTypeColumnWidth: 23, resourcesTotal: 3, stream: process.stderr, }); const output = console_listener_1.stderr.inspectSync(() => { historyActivityPrinter.addActivity({ event: { LogicalResourceId: 'stack1', ResourceStatus: 'IN_PROGRESS', Timestamp: new Date(TIMESTAMP), ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', StackName: 'stack-name', }, }); }); expect(output[0].trim()).toStrictEqual(`stack-name | 0/4 | ${HUMAN_TIME} | ${(0, chalk_1.reset)('IN_PROGRESS ')} | AWS::CloudFormation::Stack | ${(0, chalk_1.reset)((0, chalk_1.bold)('stack1'))}`); }); test('prints 1/4 progress report, when addActivity is called with an "UPDATE_COMPLETE" ResourceStatus', () => { const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ resourceTypeColumnWidth: 23, resourcesTotal: 3, stream: process.stderr, }); const output = console_listener_1.stderr.inspectSync(() => { historyActivityPrinter.addActivity({ event: { LogicalResourceId: 'stack1', ResourceStatus: 'UPDATE_COMPLETE', Timestamp: new Date(TIMESTAMP), ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', StackName: 'stack-name', }, }); }); expect(output[0].trim()).toStrictEqual(`stack-name | 1/4 | ${HUMAN_TIME} | ${(0, chalk_1.green)('UPDATE_COMPLETE ')} | AWS::CloudFormation::Stack | ${(0, chalk_1.green)((0, chalk_1.bold)('stack1'))}`); }); test('prints 1/4 progress report, when addActivity is called with an "UPDATE_COMPLETE_CLEAN_IN_PROGRESS" ResourceStatus', () => { const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ resourceTypeColumnWidth: 23, resourcesTotal: 3, stream: process.stderr, }); const output = console_listener_1.stderr.inspectSync(() => { historyActivityPrinter.addActivity({ event: { LogicalResourceId: 'stack1', ResourceStatus: 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS', Timestamp: new Date(TIMESTAMP), ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', StackName: 'stack-name', }, }); }); expect(output[0].trim()).toStrictEqual(`stack-name | 1/4 | ${HUMAN_TIME} | ${(0, chalk_1.green)('UPDATE_COMPLETE_CLEA')} | AWS::CloudFormation::Stack | ${(0, chalk_1.green)((0, chalk_1.bold)('stack1'))}`); }); test('prints 1/4 progress report, when addActivity is called with an "ROLLBACK_COMPLETE_CLEAN_IN_PROGRESS" ResourceStatus', () => { const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ resourceTypeColumnWidth: 23, resourcesTotal: 3, stream: process.stderr, }); const output = console_listener_1.stderr.inspectSync(() => { historyActivityPrinter.addActivity({ event: { LogicalResourceId: 'stack1', ResourceStatus: 'ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS', Timestamp: new Date(TIMESTAMP), ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', StackName: 'stack-name', }, }); }); expect(output[0].trim()).toStrictEqual(`stack-name | 1/4 | ${HUMAN_TIME} | ${(0, chalk_1.yellow)('ROLLBACK_COMPLETE_CL')} | AWS::CloudFormation::Stack | ${(0, chalk_1.yellow)((0, chalk_1.bold)('stack1'))}`); }); test('prints 0/4 progress report, when addActivity is called with an "UPDATE_FAILED" ResourceStatus', () => { const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ resourceTypeColumnWidth: 23, resourcesTotal: 3, stream: process.stderr, }); const output = console_listener_1.stderr.inspectSync(() => { historyActivityPrinter.addActivity({ event: { LogicalResourceId: 'stack1', ResourceStatus: 'UPDATE_FAILED', Timestamp: new Date(TIMESTAMP), ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', StackName: 'stack-name', }, }); }); expect(output[0].trim()).toStrictEqual(`stack-name | 0/4 | ${HUMAN_TIME} | ${(0, chalk_1.red)('UPDATE_FAILED ')} | AWS::CloudFormation::Stack | ${(0, chalk_1.red)((0, chalk_1.bold)('stack1'))}`); }); test('does not print "Failed Resources:" list, when all deployments are successful', () => { const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ resourceTypeColumnWidth: 23, resourcesTotal: 1, stream: process.stderr, }); const output = console_listener_1.stderr.inspectSync(() => { historyActivityPrinter.addActivity({ event: { LogicalResourceId: 'stack1', ResourceStatus: 'IN_PROGRESS', Timestamp: new Date(TIMESTAMP), ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', StackName: 'stack-name', }, }); historyActivityPrinter.addActivity({ event: { LogicalResourceId: 'stack1', ResourceStatus: 'UPDATE_COMPLETE', Timestamp: new Date(TIMESTAMP), ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', StackName: 'stack-name', }, }); historyActivityPrinter.addActivity({ event: { LogicalResourceId: 'stack2', ResourceStatus: 'UPDATE_COMPLETE', Timestamp: new Date(TIMESTAMP), ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', StackName: 'stack-name', }, }); historyActivityPrinter.stop(); }); expect(output.length).toStrictEqual(3); expect(output[0].trim()).toStrictEqual(`stack-name | 0/2 | ${HUMAN_TIME} | ${(0, chalk_1.reset)('IN_PROGRESS ')} | AWS::CloudFormation::Stack | ${(0, chalk_1.reset)((0, chalk_1.bold)('stack1'))}`); expect(output[1].trim()).toStrictEqual(`stack-name | 1/2 | ${HUMAN_TIME} | ${(0, chalk_1.green)('UPDATE_COMPLETE ')} | AWS::CloudFormation::Stack | ${(0, chalk_1.green)((0, chalk_1.bold)('stack1'))}`); expect(output[2].trim()).toStrictEqual(`stack-name | 2/2 | ${HUMAN_TIME} | ${(0, chalk_1.green)('UPDATE_COMPLETE ')} | AWS::CloudFormation::Stack | ${(0, chalk_1.green)((0, chalk_1.bold)('stack2'))}`); }); test('prints "Failed Resources:" list, when at least one deployment fails', () => { const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ resourceTypeColumnWidth: 23, resourcesTotal: 1, stream: process.stderr, }); const output = console_listener_1.stderr.inspectSync(() => { historyActivityPrinter.addActivity({ event: { LogicalResourceId: 'stack1', ResourceStatus: 'IN_PROGRESS', Timestamp: new Date(TIMESTAMP), ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', StackName: 'stack-name', }, }); historyActivityPrinter.addActivity({ event: { LogicalResourceId: 'stack1', ResourceStatus: 'UPDATE_FAILED', Timestamp: new Date(TIMESTAMP), ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', StackName: 'stack-name', }, }); historyActivityPrinter.stop(); }); expect(output.length).toStrictEqual(4); expect(output[0].trim()).toStrictEqual(`stack-name | 0/2 | ${HUMAN_TIME} | ${(0, chalk_1.reset)('IN_PROGRESS ')} | AWS::CloudFormation::Stack | ${(0, chalk_1.reset)((0, chalk_1.bold)('stack1'))}`); expect(output[1].trim()).toStrictEqual(`stack-name | 0/2 | ${HUMAN_TIME} | ${(0, chalk_1.red)('UPDATE_FAILED ')} | AWS::CloudFormation::Stack | ${(0, chalk_1.red)((0, chalk_1.bold)('stack1'))}`); expect(output[2].trim()).toStrictEqual('Failed resources:'); expect(output[3].trim()).toStrictEqual(`stack-name | ${HUMAN_TIME} | ${(0, chalk_1.red)('UPDATE_FAILED ')} | AWS::CloudFormation::Stack | ${(0, chalk_1.red)((0, chalk_1.bold)('stack1'))}`); }); test('print failed resources because of hook failures', () => { const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ resourceTypeColumnWidth: 23, resourcesTotal: 1, stream: process.stderr, }); const output = console_listener_1.stderr.inspectSync(() => { historyActivityPrinter.addActivity({ event: { LogicalResourceId: 'stack1', ResourceStatus: 'IN_PROGRESS', Timestamp: new Date(TIMESTAMP), ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', StackName: 'stack-name', HookStatus: 'HOOK_COMPLETE_FAILED', HookType: 'hook1', HookStatusReason: 'stack1 must obey certain rules', }, }); historyActivityPrinter.addActivity({ event: { LogicalResourceId: 'stack1', ResourceStatus: 'UPDATE_FAILED', Timestamp: new Date(TIMESTAMP), ResourceType: 'AWS::CloudFormation::Stack', StackId: '', EventId: '', StackName: 'stack-name', ResourceStatusReason: 'The following hook(s) failed: hook1', }, }); historyActivityPrinter.stop(); }); expect(output.length).toStrictEqual(4); expect(output[0].trim()).toStrictEqual(`stack-name | 0/2 | ${HUMAN_TIME} | ${(0, chalk_1.reset)('IN_PROGRESS ')} | AWS::CloudFormation::Stack | ${(0, chalk_1.reset)((0, chalk_1.bold)('stack1'))}`); expect(output[1].trim()).toStrictEqual(`stack-name | 0/2 | ${HUMAN_TIME} | ${(0, chalk_1.red)('UPDATE_FAILED ')} | AWS::CloudFormation::Stack | ${(0, chalk_1.red)((0, chalk_1.bold)('stack1'))} ${(0, chalk_1.red)((0, chalk_1.bold)('The following hook(s) failed: hook1 : stack1 must obey certain rules'))}`); expect(output[2].trim()).toStrictEqual('Failed resources:'); expect(output[3].trim()).toStrictEqual(`stack-name | ${HUMAN_TIME} | ${(0, chalk_1.red)('UPDATE_FAILED ')} | AWS::CloudFormation::Stack | ${(0, chalk_1.red)((0, chalk_1.bold)('stack1'))} ${(0, chalk_1.red)((0, chalk_1.bold)('The following hook(s) failed: hook1 : stack1 must obey certain rules'))}`); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2stYWN0aXZpdHktbW9uaXRvci50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3RhY2stYWN0aXZpdHktbW9uaXRvci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsaUNBQWlDO0FBQ2pDLGlDQUF3RDtBQUN4RCx5REFBNEM7QUFDNUMscUdBQWtHO0FBRWxHLElBQUksU0FBaUIsQ0FBQztBQUN0QixJQUFJLFVBQWtCLENBQUM7QUFFdkIsU0FBUyxDQUFDLEdBQUcsRUFBRTtJQUNiLFNBQVMsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2pDLFVBQVUsR0FBRyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0FBQ3hELENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLDZGQUE2RixFQUFFLEdBQUcsRUFBRTtJQUN2RyxNQUFNLHNCQUFzQixHQUFHLElBQUksK0NBQXNCLENBQUM7UUFDeEQsdUJBQXVCLEVBQUUsRUFBRTtRQUMzQixjQUFjLEVBQUUsQ0FBQztRQUNqQixNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07S0FDdkIsQ0FBQyxDQUFDO0lBRUgsTUFBTSxNQUFNLEdBQUcseUJBQU0sQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFO1FBQ3JDLHNCQUFzQixDQUFDLFdBQVcsQ0FBQztZQUNqQyxLQUFLLEVBQUU7Z0JBQ0wsaUJBQWlCLEVBQUUsUUFBUTtnQkFDM0IsY0FBYyxFQUFFLGFBQWE7Z0JBQzdCLFNBQVMsRUFBRSxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUM7Z0JBQzlCLFlBQVksRUFBRSw0QkFBNEI7Z0JBQzFDLE9BQU8sRUFBRSxFQUFFO2dCQUNYLE9BQU8sRUFBRSxFQUFFO2dCQUNYLFNBQVMsRUFBRSxZQUFZO2FBQ3hCO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxNQUFNLENBQUMsTUFBTSxDQUFDLENB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LHNCQUFzQixDQUFDLG1DQUFtQyxJQUFBLFdBQUcsRUFBQyxJQUFBLFlBQUksRUFBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLElBQUEsV0FBRyxFQUFDLElBQUEsWUFBSSxFQUFDLHNFQUFzRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDdlAsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQzVELE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLFVBQVUsTUFBTSxJQUFBLFdBQUcsRUFBQyxzQkFBc0IsQ0FBQyxtQ0FBbUMsSUFBQSxXQUFHLEVBQUMsSUFBQSxZQUFJLEVBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxJQUFBLFdBQUcsRUFBQyxJQUFBLFlBQUksRUFBQyxzRUFBc0UsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ25QLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L29yZGVyICovXG5pbXBvcnQgeyBib2xkLCByZXNldCwgZ3JlZW4sIHllbGxvdywgcmVkIH0gZnJvbSAnY2hhbGsnO1xuaW1wb3J0IHsgc3RkZXJyIH0gZnJvbSAnLi9jb25zb2xlLWxpc3RlbmVyJztcbmltcG9ydCB7IEhpc3RvcnlBY3Rpdml0eVByaW50ZXIgfSBmcm9tICcuLi8uLi9saWIvYXBpL3V0aWwvY2xvdWRmb3JtYXRpb24vc3RhY2stYWN0aXZpdHktbW9uaXRvcic7XG5cbmxldCBUSU1FU1RBTVA6IG51bWJlcjtcbmxldCBIVU1BTl9USU1FOiBzdHJpbmc7XG5cbmJlZm9yZUFsbCgoKSA9PiB7XG4gIFRJTUVTVEFNUCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICBIVU1BTl9USU1FID0gbmV3IERhdGUoVElNRVNUQU1QKS50b0xvY2FsZVRpbWVTdHJpbmcoKTtcbn0pO1xuXG50ZXN0KCdwcmludHMgMC80IHByb2dyZXNzIHJlcG9ydCwgd2hlbiBhZGRBY3Rpdml0eSBpcyBjYWxsZWQgd2l0aCBhbiBcIklOX1BST0dSRVNTXCIgUmVzb3VyY2VTdGF0dXMnLCAoKSA9PiB7XG4gIGNvbnN0IGhpc3RvcnlBY3Rpdml0eVByaW50ZXIgPSBuZXcgSGlzdG9yeUFjdGl2aXR5UHJpbnRlcih7XG4gICAgcmVzb3VyY2VUeXBlQ29sdW1uV2lkdGg6IDIzLFxuICAgIHJlc291cmNlc1RvdGFsOiAzLFxuICAgIHN0cmVhbTogcHJvY2Vzcy5zdGRlcnIsXG4gIH0pO1xuXG4gIGNvbnN0IG91dHB1dCA9IHN0ZGVyci5pbnNwZWN0U3luYygoKSA9PiB7XG4gICAgaGlzdG9yeUFjdGl2aXR5UHJpbnRlci5hZGRBY3Rpdml0eSh7XG4gICAgICBldmVudDoge1xuICAgICAgICBMb2dpY2FsUmVzb3VyY2VJZDogJ3N0YWNrMScsXG4gICAgICAgIFJlc291cmNlU3RhdHVzOiAnSU5fUFJPR1JFU1MnLFxuICAgICAgICBUaW1lc3RhbXA6IG5ldyBEYXRlKFRJTUVTVEFNUCksXG4gICAgICAgIFJlc291cmNlVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgU3RhY2tJZDogJycsXG4gICAgICAgIEV2ZW50SWQ6ICcnLFxuICAgICAgICBTdGFja05hbWU6ICdzdGFjay1uYW1lJyxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH0pO1xuXG4gIGV4cGVjdChvdXRwdXRbMF0udHJpbSgpKS50b1N0cmljdEVxdWFsKGBzdGFjay1uYW1lIHwgMC80IHwgJHtIVU1BTl9USU1FfSB8ICR7cmVzZXQoJ0lOX1BST0dSRVNTICAgICAgICAgJyl9IHwgQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2sgfCAke3Jlc2V0KGJvbGQoJ3N0YWNrMScpKX1gKTtcbn0pO1xuXG50ZXN0KCdwcmludHMgMS80IHByb2dyZXNzIHJlcG9ydCwgd2hlbiBhZGRBY3Rpdml0eSBpcyBjYWxsZWQgd2l0aCBhbiBcIlVQREFURV9DT01QTEVURVwiIFJlc291cmNlU3RhdHVzJywgKCkgPT4ge1xuICBjb25zdCBoaXN0b3J5QWN0aXZpdHlQcmludGVyID0gbmV3IEhpc3RvcnlBY3Rpdml0eVByaW50ZXIoe1xuICAgIHJlc291cmNlVHlwZUNvbHVtbldpZHRoOiAyMyxcbiAgICByZXNvdXJjZXNUb3RhbDogMyxcbiAgICBzdHJlYW06IHByb2Nlc3Muc3RkZXJyLFxuICB9KTtcblxuICBjb25zdCBvdXRwdXQgPSBzdGRlcnIuaW5zcGVjdFN5bmMoKCkgPT4ge1xuICAgIGhpc3RvcnlBY3Rpdml0eVByaW50ZXIuYWRkQWN0aXZpdHkoe1xuICAgICAgZXZlbnQ6IHtcbiAgICAgICAgTG9naWNhbFJlc291cmNlSWQ6ICdzdGFjazEnLFxuICAgICAgICBSZXNvdXJjZVN0YXR1czogJ1VQREFURV9DT01QTEVURScsXG4gICAgICAgIFRpbWVzdGFtcDogbmV3IERhdGUoVElNRVNUQU1QKSxcbiAgICAgICAgUmVzb3VyY2VUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICBTdGFja0lkOiAnJyxcbiAgICAgICAgRXZlbnRJZDogJycsXG4gICAgICAgIFN0YWNrTmFtZTogJ3N0YWNrLW5hbWUnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfSk7XG5cbiAgZXhwZWN0KG91dHB1dFswXS50cmltKCkpLnRvU3RyaWN0RXF1YWwoYHN0YWNrLW5hbWUgfCAxLzQgfCAke0hVTUFOX1RJTUV9IHwgJHtncmVlbignVVBEQVRFX0NPTVBMRVRFICAgICAnKX0gfCBBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjayB8ICR7Z3JlZW4oYm9sZCgnc3RhY2sxJykpfWApO1xufSk7XG5cbnRlc3QoJ3ByaW50cyAxLzQgcHJvZ3Jlc3MgcmVwb3J0LCB3aGVuIGFkZEFjdGl2aXR5IGlzIGNhbGxlZCB3aXRoIGFuIFwiVVBEQVRFX0NPTVBMRVRFX0NMRUFOX0lOX1BST0dSRVNTXCIgUmVzb3VyY2VTdGF0dXMnLCAoKSA9PiB7XG4gIGNvbnN0IGhpc3RvcnlBY3Rpdml0eVByaW50ZXIgPSBuZXcgSGlzdG9yeUFjdGl2aXR5UHJpbnRlcih7XG4gICAgcmVzb3VyY2VUeXBlQ29sdW1uV2lkdGg6IDIzLFxuICAgIHJlc291cmNlc1RvdGFsOiAzLFxuICAgIHN0cmVhbTogcHJvY2Vzcy5zdGRlcnIsXG4gIH0pO1xuXG4gIGNvbnN0IG91dHB1dCA9IHN0ZGVyci5pbnNwZWN0U3luYygoKSA9PiB7XG4gICAgaGlzdG9yeUFjdGl2aXR5UHJpbnRlci5hZGRBY3Rpdml0eSh7XG4gICAgICBldmVudDoge1xuICAgICAgICBMb2dpY2FsUmVzb3VyY2VJZDogJ3N0YWNrMScsXG4gICAgICAgIFJlc291cmNlU3RhdHVzOiAnVVBEQVRFX0NPTVBMRVRFX0NMRUFOVVBfSU5fUFJPR1JFU1MnLFxuICAgICAgICBUaW1lc3RhbXA6IG5ldyBEYXRlKFRJTUVTVEFNUCksXG4gICAgICAgIFJlc291cmNlVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgU3RhY2tJZDogJycsXG4gICAgICAgIEV2ZW50SWQ6ICcnLFxuICAgICAgICBTdGFja05hbWU6ICdzdGFjay1uYW1lJyxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH0pO1xuXG4gIGV4cGVjdChvdXRwdXRbMF0udHJpbSgpKS50b1N0cmljdEVxdWFsKGBzdGFjay1uYW1lIHwgMS80IHwgJHtIVU1BTl9USU1FfSB8ICR7Z3JlZW4oJ1VQREFURV9DT01QTEVURV9DTEVBJyl9IHwgQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2sgfCAke2dyZWVuKGJvbGQoJ3N0YWNrMScpKX1gKTtcbn0pO1xuXG50ZXN0KCdwcmludHMgMS80IHByb2dyZXNzIHJlcG9ydCwgd2hlbiBhZGRBY3Rpdml0eSBpcyBjYWxsZWQgd2l0aCBhbiBcIlJPTExCQUNLX0NPTVBMRVRFX0NMRUFOX0lOX1BST0dSRVNTXCIgUmVzb3VyY2VTdGF0dXMnLCAoKSA9PiB7XG4gIGNvbnN0IGhpc3RvcnlBY3Rpdml0eVByaW50ZXIgPSBuZXcgSGlzdG9yeUFjdGl2aXR5UHJpbnRlcih7XG4gICAgcmVzb3VyY2VUeXBlQ29sdW1uV2lkdGg6IDIzLFxuICAgIHJlc291cmNlc1RvdGFsOiAzLFxuICAgIHN0cmVhbTogcHJvY2Vzcy5zdGRlcnIsXG4gIH0pO1xuXG4gIGNvbnN0IG91dHB1dCA9IHN0ZGVyci5pbnNwZWN0U3luYygoKSA9PiB7XG4gICAgaGlzdG9yeUFjdGl2aXR5UHJpbnRlci5hZGRBY3Rpdml0eSh7XG4gICAgICBldmVudDoge1xuICAgICAgICBMb2dpY2FsUmVzb3VyY2VJZDogJ3N0YWNrMScsXG4gICAgICAgIFJlc291cmNlU3RhdHVzOiAnUk9MTEJBQ0tfQ09NUExFVEVfQ0xFQU5VUF9JTl9QUk9HUkVTUycsXG4gICAgICAgIFRpbWVzdGFtcDogbmV3IERhdGUoVElNRVNUQU1QKSxcbiAgICAgICAgUmVzb3VyY2VUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICBTdGFja0lkOiAnJyxcbiAgICAgICAgRXZlbnRJZDogJycsXG4gICAgICAgIFN0YWNrTmFtZTogJ3N0YWNrLW5hbWUnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfSk7XG5cbiAgZXhwZWN0KG91dHB1dFswXS50cmltKCkpLnRvU3RyaWN0RXF1YWwoYHN0YWNrLW5hbWUgfCAxLzQgfCAke0hVTUFOX1RJTUV9IHwgJHt5ZWxsb3coJ1JPTExCQUNLX0NPTVBMRVRFX0NMJyl9IHwgQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2sgfCAke3llbGxvdyhib2xkKCdzdGFjazEnKSl9YCk7XG59KTtcblxudGVzdCgncHJpbnRzIDAvNCBwcm9ncmVzcyByZXBvcnQsIHdoZW4gYWRkQWN0aXZpdHkgaXMgY2FsbGVkIHdpdGggYW4gXCJVUERBVEVfRkFJTEVEXCIgUmVzb3VyY2VTdGF0dXMnLCAoKSA9PiB7XG4gIGNvbnN0IGhpc3RvcnlBY3Rpdml0eVByaW50ZXIgPSBuZXcgSGlzdG9yeUFjdGl2aXR5UHJpbnRlcih7XG4gICAgcmVzb3VyY2VUeXBlQ29sdW1uV2lkdGg6IDIzLFxuICAgIHJlc291cmNlc1RvdGFsOiAzLFxuICAgIHN0cmVhbTogcHJvY2Vzcy5zdGRlcnIsXG4gIH0pO1xuXG4gIGNvbnN0IG91dHB1dCA9IHN0ZGVyci5pbnNwZWN0U3luYygoKSA9PiB7XG4gICAgaGlzdG9yeUFjdGl2aXR5UHJpbnRlci5hZGRBY3Rpdml0eSh7XG4gICAgICBldmVudDoge1xuICAgICAgICBMb2dpY2FsUmVzb3VyY2VJZDogJ3N0YWNrMScsXG4gICAgICAgIFJlc291cmNlU3RhdHVzOiAnVVBEQVRFX0ZBSUxFRCcsXG4gICAgICAgIFRpbWVzdGFtcDogbmV3IERhdGUoVElNRVNUQU1QKSxcbiAgICAgICAgUmVzb3VyY2VUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICBTdGFja0lkOiAnJyxcbiAgICAgICAgRXZlbnRJZDogJycsXG4gICAgICAgIFN0YWNrTmFtZTogJ3N0YWNrLW5hbWUnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfSk7XG5cbiAgZXhwZWN0KG91dHB1dFswXS50cmltKCkpLnRvU3RyaWN0RXF1YWwoYHN0YWNrLW5hbWUgfCAwLzQgfCAke0hVTUFOX1RJTUV9IHwgJHtyZWQoJ1VQREFURV9GQUlMRUQgICAgICAgJyl9IHwgQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2sgfCAke3JlZChib2xkKCdzdGFjazEnKSl9YCk7XG59KTtcblxudGVzdCgnZG9lcyBub3QgcHJpbnQgXCJGYWlsZWQgUmVzb3VyY2VzOlwiIGxpc3QsIHdoZW4gYWxsIGRlcGxveW1lbnRzIGFyZSBzdWNjZXNzZnVsJywgKCkgPT4ge1xuICBjb25zdCBoaXN0b3J5QWN0aXZpdHlQcmludGVyID0gbmV3IEhpc3RvcnlBY3Rpdml0eVByaW50ZXIoe1xuICAgIHJlc291cmNlVHlwZUNvbHVtbldpZHRoOiAyMyxcbiAgICByZXNvdXJjZXNUb3RhbDogMSxcbiAgICBzdHJlYW06IHByb2Nlc3Muc3RkZXJyLFxuICB9KTtcblxuICBjb25zdCBvdXRwdXQgPSBzdGRlcnIuaW5zcGVjdFN5bmMoKCkgPT4ge1xuICAgIGhpc3RvcnlBY3Rpdml0eVByaW50ZXIuYWRkQWN0aXZpdHkoe1xuICAgICAgZXZlbnQ6IHtcbiAgICAgICAgTG9naWNhbFJlc291cmNlSWQ6ICdzdGFjazEnLFxuICAgICAgICBSZXNvdXJjZVN0YXR1czogJ0lOX1BST0dSRVNTJyxcbiAgICAgICAgVGltZXN0YW1wOiBuZXcgRGF0ZShUSU1FU1RBTVApLFxuICAgICAgICBSZXNvdXJjZVR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgIFN0YWNrSWQ6ICcnLFxuICAgICAgICBFdmVudElkOiAnJyxcbiAgICAgICAgU3RhY2tOYW1lOiAnc3RhY2stbmFtZScsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGhpc3RvcnlBY3Rpdml0eVByaW50ZXIuYWRkQWN0aXZpdHkoe1xuICAgICAgZXZlbnQ6IHtcbiAgICAgICAgTG9naWNhbFJlc291cmNlSWQ6ICdzdGFjazEnLFxuICAgICAgICBSZXNvdXJjZVN0YXR1czogJ1VQREFURV9DT01QTEVURScsXG4gICAgICAgIFRpbWVzdGFtcDogbmV3IERhdGUoVElNRVNUQU1QKSxcbiAgICAgICAgUmVzb3VyY2VUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICBTdGFja0lkOiAnJyxcbiAgICAgICAgRXZlbnRJZDogJycsXG4gICAgICAgIFN0YWNrTmFtZTogJ3N0YWNrLW5hbWUnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBoaXN0b3J5QWN0aXZpdHlQcmludGVyLmFkZEFjdGl2aXR5KHtcbiAgICAgIGV2ZW50OiB7XG4gICAgICAgIExvZ2ljYWxSZXNvdXJjZUlkOiAnc3RhY2syJyxcbiAgICAgICAgUmVzb3VyY2VTdGF0dXM6ICdVUERBVEVfQ09NUExFVEUnLFxuICAgICAgICBUaW1lc3RhbXA6IG5ldyBEYXRlKFRJTUVTVEFNUCksXG4gICAgICAgIFJlc291cmNlVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgU3RhY2tJZDogJycsXG4gICAgICAgIEV2ZW50SWQ6ICcnLFxuICAgICAgICBTdGFja05hbWU6ICdzdGFjay1uYW1lJyxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgaGlzdG9yeUFjdGl2aXR5UHJpbnRlci5zdG9wKCk7XG4gIH0pO1xuXG4gIGV4cGVjdChvdXRwdXQubGVuZ3RoKS50b1N0cmljdEVxdWFsKDMpO1xuICBleHBlY3Qob3V0cHV0WzBdLnRyaW0oKSkudG9TdHJpY3RFcXVhbChgc3RhY2stbmFtZSB8IDAvMiB8ICR7SFVNQU5fVElNRX0gfCAke3Jlc2V0KCdJTl9QUk9HUkVTUyAgICAgICAgICcpfSB8IEFXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrIHwgJHtyZXNldChib2xkKCdzdGFjazEnKSl9YCk7XG4gIGV4cGVjdChvdXRwdXRbMV0udHJpbSgpKS50b1N0cmljdEVxdWFsKGBzdGFjay1uYW1lIHwgMS8yIHwgJHtIVU1BTl9USU1FfSB8ICR7Z3JlZW4oJ1VQREFURV9DT01QTEVURSAgICAgJyl9IHwgQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2sgfCAke2dyZWVuKGJvbGQoJ3N0YWNrMScpKX1gKTtcbiAgZXhwZWN0KG91dHB1dFsyXS50cmltKCkpLnRvU3RyaWN0RXF1YWwoYHN0YWNrLW5hbWUgfCAyLzIgfCAke0hVTUFOX1RJTUV9IHwgJHtncmVlbignVVBEQVRFX0NPTVBMRVRFICAgICAnKX0gfCBBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjayB8ICR7Z3JlZW4oYm9sZCgnc3RhY2syJykpfWApO1xufSk7XG5cbnRlc3QoJ3ByaW50cyBcIkZhaWxlZCBSZXNvdXJjZXM6XCIgbGlzdCwgd2hlbiBhdCBsZWFzdCBvbmUgZGVwbG95bWVudCBmYWlscycsICgpID0+IHtcbiAgY29uc3QgaGlzdG9yeUFjdGl2aXR5UHJpbnRlciA9IG5ldyBIaXN0b3J5QWN0aXZpdHlQcmludGVyKHtcbiAgICByZXNvdXJjZVR5cGVDb2x1bW5XaWR0aDogMjMsXG4gICAgcmVzb3VyY2VzVG90YWw6IDEsXG4gICAgc3RyZWFtOiBwcm9jZXNzLnN0ZGVycixcbiAgfSk7XG5cbiAgY29uc3Qgb3V0cHV0ID0gc3RkZXJyLmluc3BlY3RTeW5jKCgpID0+IHtcbiAgICBoaXN0b3J5QWN0aXZpdHlQcmludGVyLmFkZEFjdGl2aXR5KHtcbiAgICAgIGV2ZW50OiB7XG4gICAgICAgIExvZ2ljYWxSZXNvdXJjZUlkOiAnc3RhY2sxJyxcbiAgICAgICAgUmVzb3VyY2VTdGF0dXM6ICdJTl9QUk9HUkVTUycsXG4gICAgICAgIFRpbWVzdGFtcDogbmV3IERhdGUoVElNRVNUQU1QKSxcbiAgICAgICAgUmVzb3VyY2VUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICBTdGFja0lkOiAnJyxcbiAgICAgICAgRXZlbnRJZDogJycsXG4gICAgICAgIFN0YWNrTmFtZTogJ3N0YWNrLW5hbWUnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBoaXN0b3J5QWN0aXZpdHlQcmludGVyLmFkZEFjdGl2aXR5KHtcbiAgICAgIGV2ZW50OiB7XG4gICAgICAgIExvZ2ljYWxSZXNvdXJjZUlkOiAnc3RhY2sxJyxcbiAgICAgICAgUmVzb3VyY2VTdGF0dXM6ICdVUERBVEVfRkFJTEVEJyxcbiAgICAgICAgVGltZXN0YW1wOiBuZXcgRGF0ZShUSU1FU1RBTVApLFxuICAgICAgICBSZXNvdXJjZVR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgIFN0YWNrSWQ6ICcnLFxuICAgICAgICBFdmVudElkOiAnJyxcbiAgICAgICAgU3RhY2tOYW1lOiAnc3RhY2stbmFtZScsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGhpc3RvcnlBY3Rpdml0eVByaW50ZXIuc3RvcCgpO1xuICB9KTtcblxuICBleHBlY3Qob3V0cHV0Lmxlbmd0aCkudG9TdHJpY3RFcXVhbCg0KTtcbiAgZXhwZWN0KG91dHB1dFswXS50cmltKCkpLnRvU3RyaWN0RXF1YWwoYHN0YWNrLW5hbWUgfCAwLzIgfCAke0hVTUFOX1RJTUV9IHwgJHtyZXNldCgnSU5fUFJPR1JFU1MgICAgICAgICAnKX0gfCBBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjayB8ICR7cmVzZXQoYm9sZCgnc3RhY2sxJykpfWApO1xuICBleHBlY3Qob3V0cHV0WzFdLnRyaW0oKSkudG9TdHJpY3RFcXVhbChgc3RhY2stbmFtZSB8IDAvMiB8ICR7SFVNQU5fVElNRX0gfCAke3JlZCgnVVBEQVRFX0ZBSUxFRCAgICAgICAnKX0gfCBBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjayB8ICR7cmVkKGJvbGQoJ3N0YWNrMScpKX1gKTtcbiAgZXhwZWN0KG91dHB1dFsyXS50cmltKCkpLnRvU3RyaWN0RXF1YWwoJ0ZhaWxlZCByZXNvdXJjZXM6Jyk7XG4gIGV4cGVjdChvdXRwdXRbM10udHJpbSgpKS50b1N0cmljdEVxdWFsKGBzdGFjay1uYW1lIHwgJHtIVU1BTl9USU1FfSB8ICR7cmVkKCdVUERBVEVfRkFJTEVEICAgICAgICcpfSB8IEFXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrIHwgJHtyZWQoYm9sZCgnc3RhY2sxJykpfWApO1xufSk7XG5cbnRlc3QoJ3ByaW50IGZhaWxlZCByZXNvdXJjZXMgYmVjYXVzZSBvZiBob29rIGZhaWx1cmVzJywgKCkgPT4ge1xuICBjb25zdCBoaXN0b3J5QWN0aXZpdHlQcmludGVyID0gbmV3IEhpc3RvcnlBY3Rpdml0eVByaW50ZXIoe1xuICAgIHJlc291cmNlVHlwZUNvbHVtbldpZHRoOiAyMyxcbiAgICByZXNvdXJjZXNUb3RhbDogMSxcbiAgICBzdHJlYW06IHByb2Nlc3Muc3RkZXJyLFxuICB9KTtcblxuICBjb25zdCBvdXRwdXQgPSBzdGRlcnIuaW5zcGVjdFN5bmMoKCkgPT4ge1xuICAgIGhpc3RvcnlBY3Rpdml0eVByaW50ZXIuYWRkQWN0aXZpdHkoe1xuICAgICAgZXZlbnQ6IHtcbiAgICAgICAgTG9naWNhbFJlc291cmNlSWQ6ICdzdGFjazEnLFxuICAgICAgICBSZXNvdXJjZVN0YXR1czogJ0lOX1BST0dSRVNTJyxcbiAgICAgICAgVGltZXN0YW1wOiBuZXcgRGF0ZShUSU1FU1RBTVApLFxuICAgICAgICBSZXNvdXJjZVR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgIFN0YWNrSWQ6ICcnLFxuICAgICAgICBFdmVudElkOiAnJyxcbiAgICAgICAgU3RhY2tOYW1lOiAnc3RhY2stbmFtZScsXG4gICAgICAgIEhvb2tTdGF0dXM6ICdIT09LX0NPTVBMRVRFX0ZBSUxFRCcsXG4gICAgICAgIEhvb2tUeXBlOiAnaG9vazEnLFxuICAgICAgICBIb29rU3RhdHVzUmVhc29uOiAnc3RhY2sxIG11c3Qgb2JleSBjZXJ0YWluIHJ1bGVzJyxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgaGlzdG9yeUFjdGl2aXR5UHJpbnRlci5hZGRBY3Rpdml0eSh7XG4gICAgICBldmVudDoge1xuICAgICAgICBMb2dpY2FsUmVzb3VyY2VJZDogJ3N0YWNrMScsXG4gICAgICAgIFJlc291cmNlU3RhdHVzOiAnVVBEQVRFX0ZBSUxFRCcsXG4gICAgICAgIFRpbWVzdGFtcDogbmV3IERhdGUoVElNRVNUQU1QKSxcbiAgICAgICAgUmVzb3VyY2VUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICBTdGFja0lkOiAnJyxcbiAgICAgICAgRXZlbnRJZDogJycsXG4gICAgICAgIFN0YWNrTmFtZTogJ3N0YWNrLW5hbWUnLFxuICAgICAgICBSZXNvdXJjZVN0YXR1c1JlYXNvbjogJ1RoZSBmb2xsb3dpbmcgaG9vayhzKSBmYWlsZWQ6IGhvb2sxJyxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgaGlzdG9yeUFjdGl2aXR5UHJpbnRlci5zdG9wKCk7XG4gIH0pO1xuXG4gIGV4cGVjdChvdXRwdXQubGVuZ3RoKS50b1N0cmljdEVxdWFsKDQpO1xuICBleHBlY3Qob3V0cHV0WzBdLnRyaW0oKSkudG9TdHJpY3RFcXVhbChgc3RhY2stbmFtZSB8IDAvMiB8ICR7SFVNQU5fVElNRX0gfCAke3Jlc2V0KCdJTl9QUk9HUkVTUyAgICAgICAgICcpfSB8IEFXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrIHwgJHtyZXNldChib2xkKCdzdGFjazEnKSl9YCk7XG4gIGV4cGVjdChvdXRwdXRbMV0udHJpbSgpKS50b1N0cmljdEVxdWFsKGBzdGFjay1uYW1lIHwgMC8yIHwgJHtIVU1BTl9USU1FfSB8ICR7cmVkKCdVUERBVEVfRkFJTEVEICAgICAgICcpfSB8IEFXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrIHwgJHtyZWQoYm9sZCgnc3RhY2sxJykpfSAke3JlZChib2xkKCdUaGUgZm9sbG93aW5nIGhvb2socykgZmFpbGVkOiBob29rMSA6IHN0YWNrMSBtdXN0IG9iZXkgY2VydGFpbiBydWxlcycpKX1gKTtcbiAgZXhwZWN0KG91dHB1dFsyXS50cmltKCkpLnRvU3RyaWN0RXF1YWwoJ0ZhaWxlZCByZXNvdXJjZXM6Jyk7XG4gIGV4cGVjdChvdXRwdXRbM10udHJpbSgpKS50b1N0cmljdEVxdWFsKGBzdGFjay1uYW1lIHwgJHtIVU1BTl9USU1FfSB8ICR7cmVkKCdVUERBVEVfRkFJTEVEICAgICAgICcpfSB8IEFXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrIHwgJHtyZWQoYm9sZCgnc3RhY2sxJykpfSAke3JlZChib2xkKCdUaGUgZm9sbG93aW5nIGhvb2socykgZmFpbGVkOiBob29rMSA6IHN0YWNrMSBtdXN0IG9iZXkgY2VydGFpbiBydWxlcycpKX1gKTtcbn0pO1xuXG4iXX0=