UNPKG

@energica-city/shared-amplify-utils

Version:

Shared utilities for AWS Amplify projects

304 lines 46.9 kB
"use strict"; // @ts-nocheck const mockLogger = { log: vi.fn(), error: vi.fn(), info: vi.fn(), warn: vi.fn(), }; vi.mock('../log', () => ({ logger: mockLogger, })); vi.mock('@log', () => ({ logger: mockLogger, })); describe('Error Utility', () => { beforeEach(() => { vi.clearAllMocks(); vi.resetModules(); }); afterEach(() => { vi.clearAllMocks(); vi.resetModules(); }); describe('throwError', () => { it('should throw error with simple message', async () => { const { throwError } = await import('./error'); expect(() => throwError('Simple error message')).toThrow('Simple error message'); expect(mockLogger.error).toHaveBeenCalledWith('Simple error message', { errorType: 'undefined', stack: expect.any(String), }); }); it('should throw error with message and Error object', async () => { const { throwError } = await import('./error'); const originalError = new Error('Database connection failed'); expect(() => throwError('User creation failed', originalError)).toThrow('User creation failed: Database connection failed'); expect(mockLogger.error).toHaveBeenCalledWith('User creation failed: Database connection failed', { originalError: { name: 'Error', message: 'Database connection failed', stack: expect.any(String), }, errorType: 'object', stack: expect.any(String), }); }); it('should throw error with message and string error', async () => { const { throwError } = await import('./error'); expect(() => throwError('Operation failed', 'Network timeout')).toThrow('Operation failed: Network timeout'); expect(mockLogger.error).toHaveBeenCalledWith('Operation failed: Network timeout', { originalError: 'Network timeout', errorType: 'string', stack: expect.any(String), }); }); it('should throw error with message and context object', async () => { const { throwError } = await import('./error'); const context = { userId: '123', operation: 'create', additionalInfo: 'test', }; expect(() => throwError('Context error', context)).toThrow('Context error'); expect(mockLogger.error).toHaveBeenCalledWith('Context error', { userId: '123', operation: 'create', additionalInfo: 'test', errorType: 'object', stack: expect.any(String), }); }); it('should throw error with message and primitive value', async () => { const { throwError } = await import('./error'); expect(() => throwError('Number error', 404)).toThrow('Number error: 404'); expect(mockLogger.error).toHaveBeenCalledWith('Number error: 404', { originalError: 404, errorType: 'number', stack: expect.any(String), }); }); it('should throw error with Error object only', async () => { const { throwError } = await import('./error'); const error = new Error('Direct error'); expect(() => throwError(error)).toThrow('Direct error'); expect(mockLogger.error).toHaveBeenCalledWith('Direct error', { originalError: { name: 'Error', message: 'Direct error', stack: expect.any(String), }, errorType: 'object', stack: expect.any(String), }); }); it('should throw error with array of errors', async () => { const { throwError } = await import('./error'); const errors = [ new Error('First error'), { message: 'Second error' }, 'Third error', ]; expect(() => throwError(errors)).toThrow('Multiple errors occurred: First error; Second error; Third error'); expect(mockLogger.error).toHaveBeenCalledWith('Multiple errors occurred: First error; Second error; Third error', { errors, errorType: 'object', stack: expect.any(String), }); }); it('should handle single error in array', async () => { const { throwError } = await import('./error'); const errors = [new Error('Single error')]; expect(() => throwError(errors)).toThrow('Single error'); expect(mockLogger.error).toHaveBeenCalledWith('Single error', { errors, errorType: 'object', stack: expect.any(String), }); }); it('should handle empty array', async () => { const { throwError } = await import('./error'); const errors = []; expect(() => throwError(errors)).toThrow('Unknown error occurred'); expect(mockLogger.error).toHaveBeenCalledWith('Unknown error occurred', { errors, errorType: 'object', stack: expect.any(String), }); }); it('should handle unknown object with message property', async () => { const { throwError } = await import('./error'); const unknownError = { message: 'Custom error', code: 500 }; expect(() => throwError(unknownError)).toThrow('Custom error'); expect(mockLogger.error).toHaveBeenCalledWith('Custom error', { originalError: unknownError, errorType: 'object', stack: expect.any(String), }); }); it('should handle unknown object without message property', async () => { const { throwError } = await import('./error'); const unknownError = { code: 500, status: 'failed' }; expect(() => throwError(unknownError)).toThrow('Unexpected error: [object Object]'); expect(mockLogger.error).toHaveBeenCalledWith('Unexpected error: [object Object]', { originalError: unknownError, errorType: 'object', stack: expect.any(String), }); }); it('should preserve original stack trace when available', async () => { const { throwError } = await import('./error'); const originalError = new Error('Original error'); originalError.stack = 'Original stack trace\n at someFunction'; try { throwError('Wrapped error', originalError); } catch (error) { expect(error.stack).toContain('Wrapped error: Original error'); expect(error.stack).toContain('Caused by: Original stack trace'); } }); it('should handle null and undefined values', async () => { const { throwError } = await import('./error'); expect(() => throwError('Null error', null)).toThrow('Null error: null'); expect(() => throwError('Undefined error', undefined)).toThrow('Undefined error'); }); }); describe('extractErrorMessage', () => { it('should extract message from Error object', async () => { const { extractErrorMessage } = await import('./error'); const error = new Error('Test error message'); const result = extractErrorMessage(error); expect(result).toBe('Test error message'); }); it('should return string as-is', async () => { const { extractErrorMessage } = await import('./error'); const result = extractErrorMessage('String error'); expect(result).toBe('String error'); }); it('should extract message from object with message property', async () => { const { extractErrorMessage } = await import('./error'); const error = { message: 'Object error message', code: 404 }; const result = extractErrorMessage(error); expect(result).toBe('Object error message'); }); it('should handle array of errors', async () => { const { extractErrorMessage } = await import('./error'); const errors = [ new Error('First error'), 'Second error', { message: 'Third error' }, ]; const result = extractErrorMessage(errors); expect(result).toBe('First error; Second error; Third error'); }); it('should convert unknown types to string', async () => { const { extractErrorMessage } = await import('./error'); expect(extractErrorMessage(404)).toBe('404'); expect(extractErrorMessage(true)).toBe('true'); expect(extractErrorMessage(null)).toBe('null'); expect(extractErrorMessage(undefined)).toBe('undefined'); }); it('should handle complex objects', async () => { const { extractErrorMessage } = await import('./error'); const complexObject = { code: 500, details: { reason: 'timeout' } }; const result = extractErrorMessage(complexObject); expect(result).toBe('[object Object]'); }); it('should handle empty array', async () => { const { extractErrorMessage } = await import('./error'); const result = extractErrorMessage([]); expect(result).toBe(''); }); it('should handle nested arrays', async () => { const { extractErrorMessage } = await import('./error'); const nestedErrors = [ 'Error 1', ['Nested error 1', 'Nested error 2'], new Error('Error 2'), ]; const result = extractErrorMessage(nestedErrors); expect(result).toBe('Error 1; Nested error 1; Nested error 2; Error 2'); }); }); describe('createErrorContext', () => { it('should create error context object', async () => { const { createErrorContext } = await import('./error'); const context = { userId: '123', operation: 'create', endpoint: '/api/users', }; const result = createErrorContext(context); expect(result).toEqual({ userId: '123', operation: 'create', endpoint: '/api/users', }); }); it('should handle empty context', async () => { const { createErrorContext } = await import('./error'); const result = createErrorContext({}); expect(result).toEqual({}); }); it('should handle various data types in context', async () => { const { createErrorContext } = await import('./error'); const context = { stringValue: 'test', numberValue: 42, booleanValue: true, arrayValue: [1, 2, 3], objectValue: { nested: 'value' }, nullValue: null, undefinedValue: undefined, }; const result = createErrorContext(context); expect(result).toEqual({ stringValue: 'test', numberValue: 42, booleanValue: true, arrayValue: [1, 2, 3], objectValue: { nested: 'value' }, nullValue: null, }); }); }); describe('integration tests', () => { it('should work with typical QueryFactory error pattern', async () => { const { throwError } = await import('./error'); const dbError = new Error('Connection timeout'); expect(() => throwError('User could not be created', dbError)).toThrow('User could not be created: Connection timeout'); expect(mockLogger.error).toHaveBeenCalledWith('User could not be created: Connection timeout', expect.objectContaining({ originalError: expect.objectContaining({ name: 'Error', message: 'Connection timeout', }), errorType: 'object', stack: expect.any(String), })); }); it('should work with GraphQL errors array pattern', async () => { const { throwError } = await import('./error'); const graphqlErrors = [ { message: 'Field validation failed' }, { message: 'Permission denied' }, ]; expect(() => throwError(graphqlErrors)).toThrow('Multiple errors occurred: Field validation failed; Permission denied'); }); it('should work with context-based error pattern', async () => { const { throwError, createErrorContext } = await import('./error'); const context = createErrorContext({ userId: 'user-123', operation: 'delete', resource: 'Calendar', }); expect(() => throwError('Resource deletion failed', context)).toThrow('Resource deletion failed'); expect(mockLogger.error).toHaveBeenCalledWith('Resource deletion failed', expect.objectContaining({ userId: 'user-123', operation: 'delete', resource: 'Calendar', })); }); }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3IudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL2Vycm9yL2Vycm9yLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLGNBQWM7QUFDZCxNQUFNLFVBQVUsR0FBRztJQUNqQixHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRTtJQUNaLEtBQUssRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFO0lBQ2QsSUFBSSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUU7SUFDYixJQUFJLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRTtDQUNkLENBQUM7QUFFRixFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZCLE1BQU0sRUFBRSxVQUFVO0NBQ25CLENBQUMsQ0FBQyxDQUFDO0FBRUosRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNyQixNQUFNLEVBQUUsVUFBVTtDQUNuQixDQUFDLENBQUMsQ0FBQztBQUVKLFFBQVEsQ0FBQyxlQUFlLEVBQUUsR0FBRyxFQUFFO0lBQzdCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7UUFDZCxFQUFFLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDbkIsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3BCLENBQUMsQ0FBQyxDQUFDO0lBRUgsU0FBUyxDQUFDLEdBQUcsRUFBRTtRQUNiLEVBQUUsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNuQixFQUFFLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDcEIsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRTtRQUMxQixFQUFFLENBQUMsd0NBQXdDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDdEQsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLE1BQU0sTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRS9DLE1BQU0sQ0FBQyxHQUFH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QUFnQixDQUFDO2dCQUN0QixNQUFNLEVBQUUsVUFBVTtnQkFDbEIsU0FBUyxFQUFFLFFBQVE7Z0JBQ25CLFFBQVEsRUFBRSxVQUFVO2FBQ3JCLENBQUMsQ0FDSCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLW5vY2hlY2tcbmNvbnN0IG1vY2tMb2dnZXIgPSB7XG4gIGxvZzogdmkuZm4oKSxcbiAgZXJyb3I6IHZpLmZuKCksXG4gIGluZm86IHZpLmZuKCksXG4gIHdhcm46IHZpLmZuKCksXG59O1xuXG52aS5tb2NrKCcuLi9sb2cnLCAoKSA9PiAoe1xuICBsb2dnZXI6IG1vY2tMb2dnZXIsXG59KSk7XG5cbnZpLm1vY2soJ0Bsb2cnLCAoKSA9PiAoe1xuICBsb2dnZXI6IG1vY2tMb2dnZXIsXG59KSk7XG5cbmRlc2NyaWJlKCdFcnJvciBVdGlsaXR5JywgKCkgPT4ge1xuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICB2aS5jbGVhckFsbE1vY2tzKCk7XG4gICAgdmkucmVzZXRNb2R1bGVzKCk7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgdmkuY2xlYXJBbGxNb2NrcygpO1xuICAgIHZpLnJlc2V0TW9kdWxlcygpO1xuICB9KTtcblxuICBkZXNjcmliZSgndGhyb3dFcnJvcicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIHdpdGggc2ltcGxlIG1lc3NhZ2UnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IHRocm93RXJyb3IgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuXG4gICAgICBleHBlY3QoKCkgPT4gdGhyb3dFcnJvcignU2ltcGxlIGVycm9yIG1lc3NhZ2UnKSkudG9UaHJvdyhcbiAgICAgICAgJ1NpbXBsZSBlcnJvciBtZXNzYWdlJyxcbiAgICAgICk7XG4gICAgICBleHBlY3QobW9ja0xvZ2dlci5lcnJvcikudG9IYXZlQmVlbkNhbGxlZFdpdGgoJ1NpbXBsZSBlcnJvciBtZXNzYWdlJywge1xuICAgICAgICBlcnJvclR5cGU6ICd1bmRlZmluZWQnLFxuICAgICAgICBzdGFjazogZXhwZWN0LmFueShTdHJpbmcpLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIHdpdGggbWVzc2FnZSBhbmQgRXJyb3Igb2JqZWN0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyB0aHJvd0Vycm9yIH0gPSBhd2FpdCBpbXBvcnQoJy4vZXJyb3InKTtcbiAgICAgIGNvbnN0IG9yaWdpbmFsRXJyb3IgPSBuZXcgRXJyb3IoJ0RhdGFiYXNlIGNvbm5lY3Rpb24gZmFpbGVkJyk7XG5cbiAgICAgIGV4cGVjdCgoKSA9PiB0aHJvd0Vycm9yKCdVc2VyIGNyZWF0aW9uIGZhaWxlZCcsIG9yaWdpbmFsRXJyb3IpKS50b1Rocm93KFxuICAgICAgICAnVXNlciBjcmVhdGlvbiBmYWlsZWQ6IERhdGFiYXNlIGNvbm5lY3Rpb24gZmFpbGVkJyxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChtb2NrTG9nZ2VyLmVycm9yKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgICAgJ1VzZXIgY3JlYXRpb24gZmFpbGVkOiBEYXRhYmFzZSBjb25uZWN0aW9uIGZhaWxlZCcsXG4gICAgICAgIHtcbiAgICAgICAgICBvcmlnaW5hbEVycm9yOiB7XG4gICAgICAgICAgICBuYW1lOiAnRXJyb3InLFxuICAgICAgICAgICAgbWVzc2FnZTogJ0RhdGFiYXNlIGNvbm5lY3Rpb24gZmFpbGVkJyxcbiAgICAgICAgICAgIHN0YWNrOiBleHBlY3QuYW55KFN0cmluZyksXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlcnJvclR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgIHN0YWNrOiBleHBlY3QuYW55KFN0cmluZyksXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aXRoIG1lc3NhZ2UgYW5kIHN0cmluZyBlcnJvcicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgdGhyb3dFcnJvciB9ID0gYXdhaXQgaW1wb3J0KCcuL2Vycm9yJyk7XG5cbiAgICAgIGV4cGVjdCgoKSA9PiB0aHJvd0Vycm9yKCdPcGVyYXRpb24gZmFpbGVkJywgJ05ldHdvcmsgdGltZW91dCcpKS50b1Rocm93KFxuICAgICAgICAnT3BlcmF0aW9uIGZhaWxlZDogTmV0d29yayB0aW1lb3V0JyxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChtb2NrTG9nZ2VyLmVycm9yKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgICAgJ09wZXJhdGlvbiBmYWlsZWQ6IE5ldHdvcmsgdGltZW91dCcsXG4gICAgICAgIHtcbiAgICAgICAgICBvcmlnaW5hbEVycm9yOiAnTmV0d29yayB0aW1lb3V0JyxcbiAgICAgICAgICBlcnJvclR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgIHN0YWNrOiBleHBlY3QuYW55KFN0cmluZyksXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aXRoIG1lc3NhZ2UgYW5kIGNvbnRleHQgb2JqZWN0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyB0aHJvd0Vycm9yIH0gPSBhd2FpdCBpbXBvcnQoJy4vZXJyb3InKTtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSB7XG4gICAgICAgIHVzZXJJZDogJzEyMycsXG4gICAgICAgIG9wZXJhdGlvbjogJ2NyZWF0ZScsXG4gICAgICAgIGFkZGl0aW9uYWxJbmZvOiAndGVzdCcsXG4gICAgICB9O1xuXG4gICAgICBleHBlY3QoKCkgPT4gdGhyb3dFcnJvcignQ29udGV4dCBlcnJvcicsIGNvbnRleHQpKS50b1Rocm93KFxuICAgICAgICAnQ29udGV4dCBlcnJvcicsXG4gICAgICApO1xuXG4gICAgICBleHBlY3QobW9ja0xvZ2dlci5lcnJvcikudG9IYXZlQmVlbkNhbGxlZFdpdGgoJ0NvbnRleHQgZXJyb3InLCB7XG4gICAgICAgIHVzZXJJZDogJzEyMycsXG4gICAgICAgIG9wZXJhdGlvbjogJ2NyZWF0ZScsXG4gICAgICAgIGFkZGl0aW9uYWxJbmZvOiAndGVzdCcsXG4gICAgICAgIGVycm9yVHlwZTogJ29iamVjdCcsXG4gICAgICAgIHN0YWNrOiBleHBlY3QuYW55KFN0cmluZyksXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igd2l0aCBtZXNzYWdlIGFuZCBwcmltaXRpdmUgdmFsdWUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IHRocm93RXJyb3IgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuXG4gICAgICBleHBlY3QoKCkgPT4gdGhyb3dFcnJvcignTnVtYmVyIGVycm9yJywgNDA0KSkudG9UaHJvdyhcbiAgICAgICAgJ051bWJlciBlcnJvcjogNDA0JyxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChtb2NrTG9nZ2VyLmVycm9yKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCgnTnVtYmVyIGVycm9yOiA0MDQnLCB7XG4gICAgICAgIG9yaWdpbmFsRXJyb3I6IDQwNCxcbiAgICAgICAgZXJyb3JUeXBlOiAnbnVtYmVyJyxcbiAgICAgICAgc3RhY2s6IGV4cGVjdC5hbnkoU3RyaW5nKSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aXRoIEVycm9yIG9iamVjdCBvbmx5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyB0aHJvd0Vycm9yIH0gPSBhd2FpdCBpbXBvcnQoJy4vZXJyb3InKTtcbiAgICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCdEaXJlY3QgZXJyb3InKTtcblxuICAgICAgZXhwZWN0KCgpID0+IHRocm93RXJyb3IoZXJyb3IpKS50b1Rocm93KCdEaXJlY3QgZXJyb3InKTtcblxuICAgICAgZXhwZWN0KG1vY2tMb2dnZXIuZXJyb3IpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdEaXJlY3QgZXJyb3InLCB7XG4gICAgICAgIG9yaWdpbmFsRXJyb3I6IHtcbiAgICAgICAgICBuYW1lOiAnRXJyb3InLFxuICAgICAgICAgIG1lc3NhZ2U6ICdEaXJlY3QgZXJyb3InLFxuICAgICAgICAgIHN0YWNrOiBleHBlY3QuYW55KFN0cmluZyksXG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yVHlwZTogJ29iamVjdCcsXG4gICAgICAgIHN0YWNrOiBleHBlY3QuYW55KFN0cmluZyksXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igd2l0aCBhcnJheSBvZiBlcnJvcnMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IHRocm93RXJyb3IgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuICAgICAgY29uc3QgZXJyb3JzID0gW1xuICAgICAgICBuZXcgRXJyb3IoJ0ZpcnN0IGVycm9yJyksXG4gICAgICAgIHsgbWVzc2FnZTogJ1NlY29uZCBlcnJvcicgfSxcbiAgICAgICAgJ1RoaXJkIGVycm9yJyxcbiAgICAgIF07XG5cbiAgICAgIGV4cGVjdCgoKSA9PiB0aHJvd0Vycm9yKGVycm9ycykpLnRvVGhyb3coXG4gICAgICAgICdNdWx0aXBsZSBlcnJvcnMgb2NjdXJyZWQ6IEZpcnN0IGVycm9yOyBTZWNvbmQgZXJyb3I7IFRoaXJkIGVycm9yJyxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChtb2NrTG9nZ2VyLmVycm9yKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgICAgJ011bHRpcGxlIGVycm9ycyBvY2N1cnJlZDogRmlyc3QgZXJyb3I7IFNlY29uZCBlcnJvcjsgVGhpcmQgZXJyb3InLFxuICAgICAgICB7XG4gICAgICAgICAgZXJyb3JzLFxuICAgICAgICAgIGVycm9yVHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgc3RhY2s6IGV4cGVjdC5hbnkoU3RyaW5nKSxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBzaW5nbGUgZXJyb3IgaW4gYXJyYXknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IHRocm93RXJyb3IgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuICAgICAgY29uc3QgZXJyb3JzID0gW25ldyBFcnJvcignU2luZ2xlIGVycm9yJyldO1xuXG4gICAgICBleHBlY3QoKCkgPT4gdGhyb3dFcnJvcihlcnJvcnMpKS50b1Rocm93KCdTaW5nbGUgZXJyb3InKTtcblxuICAgICAgZXhwZWN0KG1vY2tMb2dnZXIuZXJyb3IpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdTaW5nbGUgZXJyb3InLCB7XG4gICAgICAgIGVycm9ycyxcbiAgICAgICAgZXJyb3JUeXBlOiAnb2JqZWN0JyxcbiAgICAgICAgc3RhY2s6IGV4cGVjdC5hbnkoU3RyaW5nKSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgZW1wdHkgYXJyYXknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IHRocm93RXJyb3IgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuICAgICAgY29uc3QgZXJyb3JzID0gW107XG5cbiAgICAgIGV4cGVjdCgoKSA9PiB0aHJvd0Vycm9yKGVycm9ycykpLnRvVGhyb3coJ1Vua25vd24gZXJyb3Igb2NjdXJyZWQnKTtcblxuICAgICAgZXhwZWN0KG1vY2tMb2dnZXIuZXJyb3IpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdVbmtub3duIGVycm9yIG9jY3VycmVkJywge1xuICAgICAgICBlcnJvcnMsXG4gICAgICAgIGVycm9yVHlwZTogJ29iamVjdCcsXG4gICAgICAgIHN0YWNrOiBleHBlY3QuYW55KFN0cmluZyksXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIHVua25vd24gb2JqZWN0IHdpdGggbWVzc2FnZSBwcm9wZXJ0eScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgdGhyb3dFcnJvciB9ID0gYXdhaXQgaW1wb3J0KCcuL2Vycm9yJyk7XG4gICAgICBjb25zdCB1bmtub3duRXJyb3IgPSB7IG1lc3NhZ2U6ICdDdXN0b20gZXJyb3InLCBjb2RlOiA1MDAgfTtcblxuICAgICAgZXhwZWN0KCgpID0+IHRocm93RXJyb3IodW5rbm93bkVycm9yKSkudG9UaHJvdygnQ3VzdG9tIGVycm9yJyk7XG5cbiAgICAgIGV4cGVjdChtb2NrTG9nZ2VyLmVycm9yKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCgnQ3VzdG9tIGVycm9yJywge1xuICAgICAgICBvcmlnaW5hbEVycm9yOiB1bmtub3duRXJyb3IsXG4gICAgICAgIGVycm9yVHlwZTogJ29iamVjdCcsXG4gICAgICAgIHN0YWNrOiBleHBlY3QuYW55KFN0cmluZyksXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIHVua25vd24gb2JqZWN0IHdpdGhvdXQgbWVzc2FnZSBwcm9wZXJ0eScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgdGhyb3dFcnJvciB9ID0gYXdhaXQgaW1wb3J0KCcuL2Vycm9yJyk7XG4gICAgICBjb25zdCB1bmtub3duRXJyb3IgPSB7IGNvZGU6IDUwMCwgc3RhdHVzOiAnZmFpbGVkJyB9O1xuXG4gICAgICBleHBlY3QoKCkgPT4gdGhyb3dFcnJvcih1bmtub3duRXJyb3IpKS50b1Rocm93KFxuICAgICAgICAnVW5leHBlY3RlZCBlcnJvcjogW29iamVjdCBPYmplY3RdJyxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChtb2NrTG9nZ2VyLmVycm9yKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgICAgJ1VuZXhwZWN0ZWQgZXJyb3I6IFtvYmplY3QgT2JqZWN0XScsXG4gICAgICAgIHtcbiAgICAgICAgICBvcmlnaW5hbEVycm9yOiB1bmtub3duRXJyb3IsXG4gICAgICAgICAgZXJyb3JUeXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICBzdGFjazogZXhwZWN0LmFueShTdHJpbmcpLFxuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcHJlc2VydmUgb3JpZ2luYWwgc3RhY2sgdHJhY2Ugd2hlbiBhdmFpbGFibGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IHRocm93RXJyb3IgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuICAgICAgY29uc3Qgb3JpZ2luYWxFcnJvciA9IG5ldyBFcnJvcignT3JpZ2luYWwgZXJyb3InKTtcbiAgICAgIG9yaWdpbmFsRXJyb3Iuc3RhY2sgPSAnT3JpZ2luYWwgc3RhY2sgdHJhY2VcXG4gIGF0IHNvbWVGdW5jdGlvbic7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHRocm93RXJyb3IoJ1dyYXBwZWQgZXJyb3InLCBvcmlnaW5hbEVycm9yKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGV4cGVjdChlcnJvci5zdGFjaykudG9Db250YWluKCdXcmFwcGVkIGVycm9yOiBPcmlnaW5hbCBlcnJvcicpO1xuICAgICAgICBleHBlY3QoZXJyb3Iuc3RhY2spLnRvQ29udGFpbignQ2F1c2VkIGJ5OiBPcmlnaW5hbCBzdGFjayB0cmFjZScpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgbnVsbCBhbmQgdW5kZWZpbmVkIHZhbHVlcycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgdGhyb3dFcnJvciB9ID0gYXdhaXQgaW1wb3J0KCcuL2Vycm9yJyk7XG5cbiAgICAgIGV4cGVjdCgoKSA9PiB0aHJvd0Vycm9yKCdOdWxsIGVycm9yJywgbnVsbCkpLnRvVGhyb3coJ051bGwgZXJyb3I6IG51bGwnKTtcblxuICAgICAgZXhwZWN0KCgpID0+IHRocm93RXJyb3IoJ1VuZGVmaW5lZCBlcnJvcicsIHVuZGVmaW5lZCkpLnRvVGhyb3coXG4gICAgICAgICdVbmRlZmluZWQgZXJyb3InLFxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2V4dHJhY3RFcnJvck1lc3NhZ2UnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBleHRyYWN0IG1lc3NhZ2UgZnJvbSBFcnJvciBvYmplY3QnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IGV4dHJhY3RFcnJvck1lc3NhZ2UgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuICAgICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoJ1Rlc3QgZXJyb3IgbWVzc2FnZScpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBleHRyYWN0RXJyb3JNZXNzYWdlKGVycm9yKTtcblxuICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZSgnVGVzdCBlcnJvciBtZXNzYWdlJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBzdHJpbmcgYXMtaXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IGV4dHJhY3RFcnJvck1lc3NhZ2UgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBleHRyYWN0RXJyb3JNZXNzYWdlKCdTdHJpbmcgZXJyb3InKTtcblxuICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZSgnU3RyaW5nIGVycm9yJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4dHJhY3QgbWVzc2FnZSBmcm9tIG9iamVjdCB3aXRoIG1lc3NhZ2UgcHJvcGVydHknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IGV4dHJhY3RFcnJvck1lc3NhZ2UgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuICAgICAgY29uc3QgZXJyb3IgPSB7IG1lc3NhZ2U6ICdPYmplY3QgZXJyb3IgbWVzc2FnZScsIGNvZGU6IDQwNCB9O1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBleHRyYWN0RXJyb3JNZXNzYWdlKGVycm9yKTtcblxuICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZSgnT2JqZWN0IGVycm9yIG1lc3NhZ2UnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIGFycmF5IG9mIGVycm9ycycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgZXh0cmFjdEVycm9yTWVzc2FnZSB9ID0gYXdhaXQgaW1wb3J0KCcuL2Vycm9yJyk7XG4gICAgICBjb25zdCBlcnJvcnMgPSBbXG4gICAgICAgIG5ldyBFcnJvcignRmlyc3QgZXJyb3InKSxcbiAgICAgICAgJ1NlY29uZCBlcnJvcicsXG4gICAgICAgIHsgbWVzc2FnZTogJ1RoaXJkIGVycm9yJyB9LFxuICAgICAgXTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gZXh0cmFjdEVycm9yTWVzc2FnZShlcnJvcnMpO1xuXG4gICAgICBleHBlY3QocmVzdWx0KS50b0JlKCdGaXJzdCBlcnJvcjsgU2Vjb25kIGVycm9yOyBUaGlyZCBlcnJvcicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb252ZXJ0IHVua25vd24gdHlwZXMgdG8gc3RyaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyBleHRyYWN0RXJyb3JNZXNzYWdlIH0gPSBhd2FpdCBpbXBvcnQoJy4vZXJyb3InKTtcblxuICAgICAgZXhwZWN0KGV4dHJhY3RFcnJvck1lc3NhZ2UoNDA0KSkudG9CZSgnNDA0Jyk7XG4gICAgICBleHBlY3QoZXh0cmFjdEVycm9yTWVzc2FnZSh0cnVlKSkudG9CZSgndHJ1ZScpO1xuICAgICAgZXhwZWN0KGV4dHJhY3RFcnJvck1lc3NhZ2UobnVsbCkpLnRvQmUoJ251bGwnKTtcbiAgICAgIGV4cGVjdChleHRyYWN0RXJyb3JNZXNzYWdlKHVuZGVmaW5lZCkpLnRvQmUoJ3VuZGVmaW5lZCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgY29tcGxleCBvYmplY3RzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyBleHRyYWN0RXJyb3JNZXNzYWdlIH0gPSBhd2FpdCBpbXBvcnQoJy4vZXJyb3InKTtcbiAgICAgIGNvbnN0IGNvbXBsZXhPYmplY3QgPSB7IGNvZGU6IDUwMCwgZGV0YWlsczogeyByZWFzb246ICd0aW1lb3V0JyB9IH07XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGV4dHJhY3RFcnJvck1lc3NhZ2UoY29tcGxleE9iamVjdCk7XG5cbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoJ1tvYmplY3QgT2JqZWN0XScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgZW1wdHkgYXJyYXknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IGV4dHJhY3RFcnJvck1lc3NhZ2UgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBleHRyYWN0RXJyb3JNZXNzYWdlKFtdKTtcblxuICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZSgnJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBuZXN0ZWQgYXJyYXlzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyBleHRyYWN0RXJyb3JNZXNzYWdlIH0gPSBhd2FpdCBpbXBvcnQoJy4vZXJyb3InKTtcbiAgICAgIGNvbnN0IG5lc3RlZEVycm9ycyA9IFtcbiAgICAgICAgJ0Vycm9yIDEnLFxuICAgICAgICBbJ05lc3RlZCBlcnJvciAxJywgJ05lc3RlZCBlcnJvciAyJ10sXG4gICAgICAgIG5ldyBFcnJvcignRXJyb3IgMicpLFxuICAgICAgXTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gZXh0cmFjdEVycm9yTWVzc2FnZShuZXN0ZWRFcnJvcnMpO1xuXG4gICAgICBleHBlY3QocmVzdWx0KS50b0JlKCdFcnJvciAxOyBOZXN0ZWQgZXJyb3IgMTsgTmVzdGVkIGVycm9yIDI7IEVycm9yIDInKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NyZWF0ZUVycm9yQ29udGV4dCcsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBlcnJvciBjb250ZXh0IG9iamVjdCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHsgY3JlYXRlRXJyb3JDb250ZXh0IH0gPSBhd2FpdCBpbXBvcnQoJy4vZXJyb3InKTtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSB7XG4gICAgICAgIHVzZXJJZDogJzEyMycsXG4gICAgICAgIG9wZXJhdGlvbjogJ2NyZWF0ZScsXG4gICAgICAgIGVuZHBvaW50OiAnL2FwaS91c2VycycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBjcmVhdGVFcnJvckNvbnRleHQoY29udGV4dCk7XG5cbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvRXF1YWwoe1xuICAgICAgICB1c2VySWQ6ICcxMjMnLFxuICAgICAgICBvcGVyYXRpb246ICdjcmVhdGUnLFxuICAgICAgICBlbmRwb2ludDogJy9hcGkvdXNlcnMnLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBlbXB0eSBjb250ZXh0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyBjcmVhdGVFcnJvckNvbnRleHQgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBjcmVhdGVFcnJvckNvbnRleHQoe30pO1xuXG4gICAgICBleHBlY3QocmVzdWx0KS50b0VxdWFsKHt9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIHZhcmlvdXMgZGF0YSB0eXBlcyBpbiBjb250ZXh0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyBjcmVhdGVFcnJvckNvbnRleHQgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuICAgICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgICAgc3RyaW5nVmFsdWU6ICd0ZXN0JyxcbiAgICAgICAgbnVtYmVyVmFsdWU6IDQyLFxuICAgICAgICBib29sZWFuVmFsdWU6IHRydWUsXG4gICAgICAgIGFycmF5VmFsdWU6IFsxLCAyLCAzXSxcbiAgICAgICAgb2JqZWN0VmFsdWU6IHsgbmVzdGVkOiAndmFsdWUnIH0sXG4gICAgICAgIG51bGxWYWx1ZTogbnVsbCxcbiAgICAgICAgdW5kZWZpbmVkVmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGNyZWF0ZUVycm9yQ29udGV4dChjb250ZXh0KTtcblxuICAgICAgZXhwZWN0KHJlc3VsdCkudG9FcXVhbCh7XG4gICAgICAgIHN0cmluZ1ZhbHVlOiAndGVzdCcsXG4gICAgICAgIG51bWJlclZhbHVlOiA0MixcbiAgICAgICAgYm9vbGVhblZhbHVlOiB0cnVlLFxuICAgICAgICBhcnJheVZhbHVlOiBbMSwgMiwgM10sXG4gICAgICAgIG9iamVjdFZhbHVlOiB7IG5lc3RlZDogJ3ZhbHVlJyB9LFxuICAgICAgICBudWxsVmFsdWU6IG51bGwsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2ludGVncmF0aW9uIHRlc3RzJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgd29yayB3aXRoIHR5cGljYWwgUXVlcnlGYWN0b3J5IGVycm9yIHBhdHRlcm4nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IHRocm93RXJyb3IgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuICAgICAgY29uc3QgZGJFcnJvciA9IG5ldyBFcnJvcignQ29ubmVjdGlvbiB0aW1lb3V0Jyk7XG5cbiAgICAgIGV4cGVjdCgoKSA9PiB0aHJvd0Vycm9yKCdVc2VyIGNvdWxkIG5vdCBiZSBjcmVhdGVkJywgZGJFcnJvcikpLnRvVGhyb3coXG4gICAgICAgICdVc2VyIGNvdWxkIG5vdCBiZSBjcmVhdGVkOiBDb25uZWN0aW9uIHRpbWVvdXQnLFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KG1vY2tMb2dnZXIuZXJyb3IpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxuICAgICAgICAnVXNlciBjb3VsZCBub3QgYmUgY3JlYXRlZDogQ29ubmVjdGlvbiB0aW1lb3V0JyxcbiAgICAgICAgZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgICAgICAgIG9yaWdpbmFsRXJyb3I6IGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgICAgIG5hbWU6ICdFcnJvcicsXG4gICAgICAgICAgICBtZXNzYWdlOiAnQ29ubmVjdGlvbiB0aW1lb3V0JyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBlcnJvclR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgIHN0YWNrOiBleHBlY3QuYW55KFN0cmluZyksXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgd29yayB3aXRoIEdyYXBoUUwgZXJyb3JzIGFycmF5IHBhdHRlcm4nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB7IHRocm93RXJyb3IgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuICAgICAgY29uc3QgZ3JhcGhxbEVycm9ycyA9IFtcbiAgICAgICAgeyBtZXNzYWdlOiAnRmllbGQgdmFsaWRhdGlvbiBmYWlsZWQnIH0sXG4gICAgICAgIHsgbWVzc2FnZTogJ1Blcm1pc3Npb24gZGVuaWVkJyB9LFxuICAgICAgXTtcblxuICAgICAgZXhwZWN0KCgpID0+IHRocm93RXJyb3IoZ3JhcGhxbEVycm9ycykpLnRvVGhyb3coXG4gICAgICAgICdNdWx0aXBsZSBlcnJvcnMgb2NjdXJyZWQ6IEZpZWxkIHZhbGlkYXRpb24gZmFpbGVkOyBQZXJtaXNzaW9uIGRlbmllZCcsXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB3b3JrIHdpdGggY29udGV4dC1iYXNlZCBlcnJvciBwYXR0ZXJuJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgeyB0aHJvd0Vycm9yLCBjcmVhdGVFcnJvckNvbnRleHQgfSA9IGF3YWl0IGltcG9ydCgnLi9lcnJvcicpO1xuICAgICAgY29uc3QgY29udGV4dCA9IGNyZWF0ZUVycm9yQ29udGV4dCh7XG4gICAgICAgIHVzZXJJZDogJ3VzZXItMTIzJyxcbiAgICAgICAgb3BlcmF0aW9uOiAnZGVsZXRlJyxcbiAgICAgICAgcmVzb3VyY2U6ICdDYWxlbmRhcicsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KCgpID0+IHRocm93RXJyb3IoJ1Jlc291cmNlIGRlbGV0aW9uIGZhaWxlZCcsIGNvbnRleHQpKS50b1Rocm93KFxuICAgICAgICAnUmVzb3VyY2UgZGVsZXRpb24gZmFpbGVkJyxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChtb2NrTG9nZ2VyLmVycm9yKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcbiAgICAgICAgJ1Jlc291cmNlIGRlbGV0aW9uIGZhaWxlZCcsXG4gICAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgICB1c2VySWQ6ICd1c2VyLTEyMycsXG4gICAgICAgICAgb3BlcmF0aW9uOiAnZGVsZXRlJyxcbiAgICAgICAgICByZXNvdXJjZTogJ0NhbGVuZGFyJyxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19