UNPKG

@aws-cdk/integ-tests-alpha

Version:

CDK Integration Testing Constructs

205 lines 22 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.handler = handler; exports.onTimeout = onTimeout; exports.isComplete = isComplete; /* eslint-disable @cdklabs/no-throw-default-error */ /* eslint-disable no-console */ const assertion_1 = require("./assertion"); const http_1 = require("./http"); const sdk_1 = require("./sdk"); const types = __importStar(require("./types")); async function handler(event, context) { console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: '...' })}`); const provider = createResourceHandler(event, context); try { // if we are deleting the custom resource, just respond // with 'SUCCESS' since there is nothing to do. if (event.RequestType === 'Delete') { await provider.respond({ status: 'SUCCESS', reason: 'OK', }); return; } const result = await provider.handle(); // if there is a `stateMachineArn` then we have already started a state machine // execution and the rest will be handled there if ('stateMachineArn' in event.ResourceProperties) { console.info('Found "stateMachineArn", waiter statemachine started'); return; } else if ('expected' in event.ResourceProperties) { console.info('Found "expected", testing assertions'); const actualPath = event.ResourceProperties.actualPath; // if we are providing a path to make the assertion at, that means that we have // flattened the response, otherwise the path to assert against in the entire response const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse; const assertion = new assertion_1.AssertionHandler({ ...event, ResourceProperties: { ServiceToken: event.ServiceToken, actual, expected: event.ResourceProperties.expected, }, }, context); try { const assertionResult = await assertion.handle(); await provider.respond({ status: 'SUCCESS', reason: 'OK', // return both the result of the API call _and_ the assertion results data: { ...assertionResult, ...result, }, }); return; } catch (e) { await provider.respond({ status: 'FAILED', reason: e.message ?? 'Internal Error', }); return; } } await provider.respond({ status: 'SUCCESS', reason: 'OK', data: result, }); } catch (e) { await provider.respond({ status: 'FAILED', reason: e.message ?? 'Internal Error', }); return; } return; } /** * Invoked by the waiter statemachine when the retry * attempts are exhausted */ async function onTimeout(timeoutEvent) { // the event payload is passed through the `errorMessage` in the state machine // timeout event const eventPayload = JSON.parse(JSON.parse(timeoutEvent.Cause).errorMessage); const provider = createResourceHandler(eventPayload, standardContext); await provider.respond({ status: 'FAILED', // Only the properties to the IsComplete Resource need to be included. reason: 'Operation timed out: ' + JSON.stringify(eventPayload.ResourceProperties), }); } /** * Invoked by the waiter statemachine when the user is waiting for a specific * result. * * If the result of the assertion is not successful then it will throw an error * which will cause the state machine to try again */ async function isComplete(event, context) { console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: '...' })}`); const provider = createResourceHandler(event, context); try { const result = await provider.handleIsComplete(); const actualPath = event.ResourceProperties.actualPath; if (result) { const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse; if ('expected' in event.ResourceProperties) { const assertion = new assertion_1.AssertionHandler({ ...event, ResourceProperties: { ServiceToken: event.ServiceToken, actual, expected: event.ResourceProperties.expected, }, }, context); const assertionResult = await assertion.handleIsComplete(); if (!(assertionResult?.failed)) { await provider.respond({ status: 'SUCCESS', reason: 'OK', data: { ...assertionResult, ...result, }, }); return; } else { console.log(`Assertion Failed: ${JSON.stringify(assertionResult)}`); throw new Error(JSON.stringify(event)); } } await provider.respond({ status: 'SUCCESS', reason: 'OK', data: result, }); } else { console.log('No result'); throw new Error(JSON.stringify(event)); } return; } catch (e) { console.log(e); throw new Error(JSON.stringify(event)); } } function createResourceHandler(event, context) { if (event.ResourceType.startsWith(types.SDK_RESOURCE_TYPE_PREFIX)) { return new sdk_1.AwsApiCallHandler(event, context); } else if (event.ResourceType.startsWith(types.ASSERT_RESOURCE_TYPE)) { return new assertion_1.AssertionHandler(event, context); } else if (event.ResourceType.startsWith(types.HTTP_RESOURCE_TYPE)) { return new http_1.HttpHandler(event, context); } else { throw new Error(`Unsupported resource type "${event.ResourceType}`); } } const standardContext = { getRemainingTimeInMillis: () => 90000, }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQU9BLDBCQWtFQztBQU1ELDhCQVVDO0FBU0QsZ0NBK0NDO0FBakpELG9EQUFvRDtBQUNwRCwrQkFBK0I7QUFDL0IsMkNBQStDO0FBQy9DLGlDQUFxQztBQUNyQywrQkFBMEM7QUFDMUMsK0NBQWlDO0FBRTFCLEtBQUssVUFBVSxPQUFPLENBQUMsS0FBa0QsRUFBRSxPQUEwQjtJQUMxRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEdBQUcsS0FBSyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUMxRSxNQUFNLFFBQVEsR0FBRyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDdkQsSUFBSSxDQUFDO1FBQ0gsdURBQXVEO1FBQ3ZELCtDQUErQztRQUMvQyxJQUFJLEtBQUssQ0FBQyxXQUFXLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDbkMsTUFBTSxRQUFRLENBQUMsT0FBTyxDQUFDO2dCQUNyQixNQUFNLEVBQUUsU0FBUztnQkFDakIsTUFBTSxFQUFFLElBQUk7YUFDYixDQUFDLENBQUM7WUFDSCxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3ZDLCtFQUErRTtRQUMvRSwrQ0FBK0M7UUFDL0MsSUFBSSxpQkFBaUIsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUNsRCxPQUFPLENBQUMsSUFBSSxDQUFDLHNEQUFzRCxDQUFDLENBQUM7WUFDckUsT0FBTztRQUNULENBQUM7YUFBTSxJQUFJLFVBQVUsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUNsRCxPQUFPLENB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Q0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7QUFDSCxDQUFDO0FBRUQsTUFBTSxlQUFlLEdBQVE7SUFDM0Isd0JBQXdCLEVBQUUsR0FBRyxFQUFFLENBQUMsS0FBSztDQUN0QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgQGNka2xhYnMvbm8tdGhyb3ctZGVmYXVsdC1lcnJvciAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuaW1wb3J0IHsgQXNzZXJ0aW9uSGFuZGxlciB9IGZyb20gJy4vYXNzZXJ0aW9uJztcbmltcG9ydCB7IEh0dHBIYW5kbGVyIH0gZnJvbSAnLi9odHRwJztcbmltcG9ydCB7IEF3c0FwaUNhbGxIYW5kbGVyIH0gZnJvbSAnLi9zZGsnO1xuaW1wb3J0ICogYXMgdHlwZXMgZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50LCBjb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dCkge1xuICBjb25zb2xlLmxvZyhgRXZlbnQ6ICR7SlNPTi5zdHJpbmdpZnkoeyAuLi5ldmVudCwgUmVzcG9uc2VVUkw6ICcuLi4nIH0pfWApO1xuICBjb25zdCBwcm92aWRlciA9IGNyZWF0ZVJlc291cmNlSGFuZGxlcihldmVudCwgY29udGV4dCk7XG4gIHRyeSB7XG4gICAgLy8gaWYgd2UgYXJlIGRlbGV0aW5nIHRoZSBjdXN0b20gcmVzb3VyY2UsIGp1c3QgcmVzcG9uZFxuICAgIC8vIHdpdGggJ1NVQ0NFU1MnIHNpbmNlIHRoZXJlIGlzIG5vdGhpbmcgdG8gZG8uXG4gICAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJykge1xuICAgICAgYXdhaXQgcHJvdmlkZXIucmVzcG9uZCh7XG4gICAgICAgIHN0YXR1czogJ1NVQ0NFU1MnLFxuICAgICAgICByZWFzb246ICdPSycsXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcHJvdmlkZXIuaGFuZGxlKCk7XG4gICAgLy8gaWYgdGhlcmUgaXMgYSBgc3RhdGVNYWNoaW5lQXJuYCB0aGVuIHdlIGhhdmUgYWxyZWFkeSBzdGFydGVkIGEgc3RhdGUgbWFjaGluZVxuICAgIC8vIGV4ZWN1dGlvbiBhbmQgdGhlIHJlc3Qgd2lsbCBiZSBoYW5kbGVkIHRoZXJlXG4gICAgaWYgKCdzdGF0ZU1hY2hpbmVBcm4nIGluIGV2ZW50LlJlc291cmNlUHJvcGVydGllcykge1xuICAgICAgY29uc29sZS5pbmZvKCdGb3VuZCBcInN0YXRlTWFjaGluZUFyblwiLCB3YWl0ZXIgc3RhdGVtYWNoaW5lIHN0YXJ0ZWQnKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKCdleHBlY3RlZCcgaW4gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzKSB7XG4gICAgICBjb25zb2xlLmluZm8oJ0ZvdW5kIFwiZXhwZWN0ZWRcIiwgdGVzdGluZyBhc3NlcnRpb25zJyk7XG4gICAgICBjb25zdCBhY3R1YWxQYXRoID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLmFjdHVhbFBhdGg7XG4gICAgICAvLyBpZiB3ZSBhcmUgcHJvdmlkaW5nIGEgcGF0aCB0byBtYWtlIHRoZSBhc3NlcnRpb24gYXQsIHRoYXQgbWVhbnMgdGhhdCB3ZSBoYXZlXG4gICAgICAvLyBmbGF0dGVuZWQgdGhlIHJlc3BvbnNlLCBvdGhlcndpc2UgdGhlIHBhdGggdG8gYXNzZXJ0IGFnYWluc3QgaW4gdGhlIGVudGlyZSByZXNwb25zZVxuICAgICAgY29uc3QgYWN0dWFsID0gYWN0dWFsUGF0aCA/IChyZXN1bHQgYXMgeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSlbYGFwaUNhbGxSZXNwb25zZS4ke2FjdHVhbFBhdGh9YF0gOiAocmVzdWx0IGFzIHR5cGVzLkF3c0FwaUNhbGxSZXN1bHQpLmFwaUNhbGxSZXNwb25zZTtcbiAgICAgIGNvbnN0IGFzc2VydGlvbiA9IG5ldyBBc3NlcnRpb25IYW5kbGVyKHtcbiAgICAgICAgLi4uZXZlbnQsXG4gICAgICAgIFJlc291cmNlUHJvcGVydGllczoge1xuICAgICAgICAgIFNlcnZpY2VUb2tlbjogZXZlbnQuU2VydmljZVRva2VuLFxuICAgICAgICAgIGFjdHVhbCxcbiAgICAgICAgICBleHBlY3RlZDogZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLmV4cGVjdGVkLFxuICAgICAgICB9LFxuICAgICAgfSwgY29udGV4dCk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBhc3NlcnRpb25SZXN1bHQgPSBhd2FpdCBhc3NlcnRpb24uaGFuZGxlKCk7XG4gICAgICAgIGF3YWl0IHByb3ZpZGVyLnJlc3BvbmQoe1xuICAgICAgICAgIHN0YXR1czogJ1NVQ0NFU1MnLFxuICAgICAgICAgIHJlYXNvbjogJ09LJyxcbiAgICAgICAgICAvLyByZXR1cm4gYm90aCB0aGUgcmVzdWx0IG9mIHRoZSBBUEkgY2FsbCBfYW5kXyB0aGUgYXNzZXJ0aW9uIHJlc3VsdHNcbiAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAuLi5hc3NlcnRpb25SZXN1bHQsXG4gICAgICAgICAgICAuLi5yZXN1bHQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICBhd2FpdCBwcm92aWRlci5yZXNwb25kKHtcbiAgICAgICAgICBzdGF0dXM6ICdGQUlMRUQnLFxuICAgICAgICAgIHJlYXNvbjogZS5tZXNzYWdlID8/ICdJbnRlcm5hbCBFcnJvcicsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIGF3YWl0IHByb3ZpZGVyLnJlc3BvbmQoe1xuICAgICAgc3RhdHVzOiAnU1VDQ0VTUycsXG4gICAgICByZWFzb246ICdPSycsXG4gICAgICBkYXRhOiByZXN1bHQsXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGF3YWl0IHByb3ZpZGVyLnJlc3BvbmQoe1xuICAgICAgc3RhdHVzOiAnRkFJTEVEJyxcbiAgICAgIHJlYXNvbjogZS5tZXNzYWdlID8/ICdJbnRlcm5hbCBFcnJvcicsXG4gICAgfSk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHJldHVybjtcbn1cblxuLyoqXG4gKiBJbnZva2VkIGJ5IHRoZSB3YWl0ZXIgc3RhdGVtYWNoaW5lIHdoZW4gdGhlIHJldHJ5XG4gKiBhdHRlbXB0cyBhcmUgZXhoYXVzdGVkXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvblRpbWVvdXQodGltZW91dEV2ZW50OiBhbnkpIHtcbiAgLy8gdGhlIGV2ZW50IHBheWxvYWQgaXMgcGFzc2VkIHRocm91Z2ggdGhlIGBlcnJvck1lc3NhZ2VgIGluIHRoZSBzdGF0ZSBtYWNoaW5lXG4gIC8vIHRpbWVvdXQgZXZlbnRcbiAgY29uc3QgZXZlbnRQYXlsb2FkID0gSlNPTi5wYXJzZShKU09OLnBhcnNlKHRpbWVvdXRFdmVudC5DYXVzZSkuZXJyb3JNZXNzYWdlKTtcbiAgY29uc3QgcHJvdmlkZXIgPSBjcmVhdGVSZXNvdXJjZUhhbmRsZXIoZXZlbnRQYXlsb2FkLCBzdGFuZGFyZENvbnRleHQpO1xuICBhd2FpdCBwcm92aWRlci5yZXNwb25kKHtcbiAgICBzdGF0dXM6ICdGQUlMRUQnLFxuICAgIC8vIE9ubHkgdGhlIHByb3BlcnRpZXMgdG8gdGhlIElzQ29tcGxldGUgUmVzb3VyY2UgbmVlZCB0byBiZSBpbmNsdWRlZC5cbiAgICByZWFzb246ICdPcGVyYXRpb24gdGltZWQgb3V0OiAnICsgSlNPTi5zdHJpbmdpZnkoZXZlbnRQYXlsb2FkLlJlc291cmNlUHJvcGVydGllcyksXG4gIH0pO1xufVxuXG4vKipcbiAqIEludm9rZWQgYnkgdGhlIHdhaXRlciBzdGF0ZW1hY2hpbmUgd2hlbiB0aGUgdXNlciBpcyB3YWl0aW5nIGZvciBhIHNwZWNpZmljXG4gKiByZXN1bHQuXG4gKlxuICogSWYgdGhlIHJlc3VsdCBvZiB0aGUgYXNzZXJ0aW9uIGlzIG5vdCBzdWNjZXNzZnVsIHRoZW4gaXQgd2lsbCB0aHJvdyBhbiBlcnJvclxuICogd2hpY2ggd2lsbCBjYXVzZSB0aGUgc3RhdGUgbWFjaGluZSB0byB0cnkgYWdhaW5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGlzQ29tcGxldGUoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSB7XG4gIGNvbnNvbGUubG9nKGBFdmVudDogJHtKU09OLnN0cmluZ2lmeSh7IC4uLmV2ZW50LCBSZXNwb25zZVVSTDogJy4uLicgfSl9YCk7XG4gIGNvbnN0IHByb3ZpZGVyID0gY3JlYXRlUmVzb3VyY2VIYW5kbGVyKGV2ZW50LCBjb250ZXh0KTtcbiAgdHJ5IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwcm92aWRlci5oYW5kbGVJc0NvbXBsZXRlKCk7XG4gICAgY29uc3QgYWN0dWFsUGF0aCA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5hY3R1YWxQYXRoO1xuICAgIGlmIChyZXN1bHQpIHtcbiAgICAgIGNvbnN0IGFjdHVhbCA9IGFjdHVhbFBhdGggPyAocmVzdWx0IGFzIHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0pW2BhcGlDYWxsUmVzcG9uc2UuJHthY3R1YWxQYXRofWBdIDogKHJlc3VsdCBhcyB0eXBlcy5Bd3NBcGlDYWxsUmVzdWx0KS5hcGlDYWxsUmVzcG9uc2U7XG4gICAgICBpZiAoJ2V4cGVjdGVkJyBpbiBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMpIHtcbiAgICAgICAgY29uc3QgYXNzZXJ0aW9uID0gbmV3IEFzc2VydGlvbkhhbmRsZXIoe1xuICAgICAgICAgIC4uLmV2ZW50LFxuICAgICAgICAgIFJlc291cmNlUHJvcGVydGllczoge1xuICAgICAgICAgICAgU2VydmljZVRva2VuOiBldmVudC5TZXJ2aWNlVG9rZW4sXG4gICAgICAgICAgICBhY3R1YWwsXG4gICAgICAgICAgICBleHBlY3RlZDogZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLmV4cGVjdGVkLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sIGNvbnRleHQpO1xuICAgICAgICBjb25zdCBhc3NlcnRpb25SZXN1bHQgPSBhd2FpdCBhc3NlcnRpb24uaGFuZGxlSXNDb21wbGV0ZSgpO1xuICAgICAgICBpZiAoIShhc3NlcnRpb25SZXN1bHQ/LmZhaWxlZCkpIHtcbiAgICAgICAgICBhd2FpdCBwcm92aWRlci5yZXNwb25kKHtcbiAgICAgICAgICAgIHN0YXR1czogJ1NVQ0NFU1MnLFxuICAgICAgICAgICAgcmVhc29uOiAnT0snLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAuLi5hc3NlcnRpb25SZXN1bHQsXG4gICAgICAgICAgICAgIC4uLnJlc3VsdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBBc3NlcnRpb24gRmFpbGVkOiAke0pTT04uc3RyaW5naWZ5KGFzc2VydGlvblJlc3VsdCl9YCk7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEpTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGF3YWl0IHByb3ZpZGVyLnJlc3BvbmQoe1xuICAgICAgICBzdGF0dXM6ICdTVUNDRVNTJyxcbiAgICAgICAgcmVhc29uOiAnT0snLFxuICAgICAgICBkYXRhOiByZXN1bHQsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5sb2coJ05vIHJlc3VsdCcpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKEpTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUubG9nKGUpO1xuICAgIHRocm93IG5ldyBFcnJvcihKU09OLnN0cmluZ2lmeShldmVudCkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVJlc291cmNlSGFuZGxlcihldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCwgY29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQpIHtcbiAgaWYgKGV2ZW50LlJlc291cmNlVHlwZS5zdGFydHNXaXRoKHR5cGVzLlNES19SRVNPVVJDRV9UWVBFX1BSRUZJWCkpIHtcbiAgICByZXR1cm4gbmV3IEF3c0FwaUNhbGxIYW5kbGVyKGV2ZW50LCBjb250ZXh0KTtcbiAgfSBlbHNlIGlmIChldmVudC5SZXNvdXJjZVR5cGUuc3RhcnRzV2l0aCh0eXBlcy5BU1NFUlRfUkVTT1VSQ0VfVFlQRSkpIHtcbiAgICByZXR1cm4gbmV3IEFzc2VydGlvbkhhbmRsZXIoZXZlbnQsIGNvbnRleHQpO1xuICB9IGVsc2UgaWYgKGV2ZW50LlJlc291cmNlVHlwZS5zdGFydHNXaXRoKHR5cGVzLkhUVFBfUkVTT1VSQ0VfVFlQRSkpIHtcbiAgICByZXR1cm4gbmV3IEh0dHBIYW5kbGVyKGV2ZW50LCBjb250ZXh0KTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIHJlc291cmNlIHR5cGUgXCIke2V2ZW50LlJlc291cmNlVHlwZX1gKTtcbiAgfVxufVxuXG5jb25zdCBzdGFuZGFyZENvbnRleHQ6IGFueSA9IHtcbiAgZ2V0UmVtYWluaW5nVGltZUluTWlsbGlzOiAoKSA9PiA5MDAwMCxcbn07XG4iXX0=