UNPKG

@aws-cdk/integ-runner

Version:

CDK Integration Testing Tool

148 lines 14.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WorkList = void 0; exports.exec = exec; exports.execWithSubShell = execWithSubShell; exports.renderCommand = renderCommand; exports.flatten = flatten; exports.chain = chain; exports.chunks = chunks; exports.promiseWithResolvers = promiseWithResolvers; // Helper functions for CDK Exec const child_process_1 = require("child_process"); /** * Our own execute function which doesn't use shells and strings. */ function exec(commandLine, options = {}) { const proc = (0, child_process_1.spawnSync)(commandLine[0], commandLine.slice(1), { stdio: ['ignore', 'pipe', options.verbose ? 'inherit' : 'pipe'], // inherit STDERR in verbose mode env: { ...process.env, ...options.env, }, cwd: options.cwd, }); if (proc.error) { throw proc.error; } if (proc.status !== 0) { if (process.stderr) { // will be 'null' in verbose mode process.stderr.write(proc.stderr); } throw new Error(`Command exited with ${proc.status ? `status ${proc.status}` : `signal ${proc.signal}`}`); } const output = proc.stdout.toString('utf-8').trim(); return output; } /** * Like exec, but any arrays encountered inside the command array are pull out and executed first, than their value is inserted again. * This mimics execution a command with sub shell behavior. * * For example this input: * ``` * ["git", "checkout", ["git", "merge-base", "HEAD"], "--," "path/to/file"] * ``` * will run something like this: * ``` * git checkout $(git merge-base HEAD) -- path/to/file * ``` * * Note that the algorithm will detect sub shells first, exec them and then * substitute the return values in. */ function execWithSubShell(command, options = {}) { const resolvedCommand = command.map((cmd) => { if (Array.isArray(cmd)) { return execWithSubShell(cmd, options); } return cmd; }); return exec(resolvedCommand, options); } /** * Takes the same input as `execWithSubShell` and returns a string with sub shells. */ function renderCommand(command) { return command.map((cmd) => { if (Array.isArray(cmd)) { return `$(${renderCommand(cmd)})`; } return cmd; }).join(' '); } /** * Flatten a list of lists into a list of elements */ function flatten(xs) { return Array.prototype.concat.apply([], xs); } /** * Chain commands */ function chain(commands) { return commands.filter(c => !!c).join(' && '); } /** * Split command to chunks by space */ function chunks(command) { const result = command.match(/(?:[^\s"]+|"[^"]*")+/g); return result ?? []; } /** * A class holding a set of items which are being crossed off in time * * If it takes too long to cross off a new item, print the list. */ class WorkList { items; options; remaining; timeout; timer; constructor(items, options = {}) { this.items = items; this.options = options; this.remaining = new Set(this.items); this.timeout = options.timeout ?? 60_000; this.scheduleTimer(); } crossOff(item) { this.remaining.delete(item); this.stopTimer(); if (this.remaining.size > 0) { this.scheduleTimer(); } } done() { this.remaining.clear(); this.stopTimer(); } stopTimer() { if (this.timer) { clearTimeout(this.timer); this.timer = undefined; } } scheduleTimer() { this.timer = setTimeout(() => this.report(), this.timeout); } report() { this.options.onTimeout?.(this.remaining); } } exports.WorkList = WorkList; /** * A backport of Promiser.withResolvers * * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers */ function promiseWithResolvers() { let resolve, reject; const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); return { promise, resolve: resolve, reject: reject }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ1dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFNQSxvQkF1QkM7QUFvQkQsNENBU0M7QUFLRCxzQ0FPQztBQUtELDBCQUVDO0FBS0Qsc0JBRUM7QUFLRCx3QkFHQztBQWtFRCxvREFPQztBQXJLRCxnQ0FBZ0M7QUFDaEMsaURBQTBDO0FBRTFDOztHQUVHO0FBQ0gsU0FBZ0IsSUFBSSxDQUFDLFdBQXFCLEVBQUUsVUFBMEQsRUFBRztJQUN2RyxNQUFNLElBQUksR0FBRyxJQUFBLHlCQUFTLEVBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUU7UUFDM0QsS0FBSyxFQUFFLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLGlDQUFpQztRQUNsRyxHQUFHLEVBQUU7WUFDSCxHQUFHLE9BQU8sQ0FBQyxHQUFHO1lBQ2QsR0FBRyxPQUFPLENBQUMsR0FBRztTQUNmO1FBQ0QsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHO0tBQ2pCLENBQUMsQ0FBQztJQUVILElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2YsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ25CLENBQUM7SUFDRCxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDdEIsSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxpQ0FBaUM7WUFDckQsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BDLENBQUM7UUFDRCxNQUFNLElBQUksS0FBSyxDQUFDLHVCQUF1QixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxVQUFVLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzVHLENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUVwRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBSUQ7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsU0FBZ0IsZ0JBQWdCLENBQUMsT0FBZ0IsRUFBRSxVQUEwRCxFQUFHO0lBQzlHLE1BQU0sZUFBZSxHQUFhLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtRQUNwRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2QixPQUFPLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN4QyxDQUFDO1FBQ0QsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDLENBQUMsQ0FBQztJQUVILE9BQU8sSUFBSSxDQUFDLGVBQWUsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUN4QyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixhQUFhLENBQUMsT0FBZ0I7SUFDNUMsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7UUFDekIsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDdkIsT0FBTyxLQUFLLGFBQWEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO1FBQ3BDLENBQUM7UUFDRCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNmLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLE9BQU8sQ0FBSSxFQUFTO0lBQ2xDLE9BQU8sS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUM5QyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixLQUFLLENBQUMsUUFBa0I7SUFDdEMsT0FBTyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixNQUFNLENBQUMsT0FBZTtJQUNwQyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDdEQsT0FBTyxNQUFNLElBQUksRUFBRSxDQUFDO0FBQ3RCLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBYSxRQUFRO0lBS1U7SUFBNkI7SUFKekMsU0FBUyxDQUFTO0lBQ2xCLE9BQU8sQ0FBUztJQUN6QixLQUFLLENBQWtCO0lBRS9CLFlBQTZCLEtBQVUsRUFBbUIsVUFBOEIsRUFBRTtRQUE3RCxVQUFLLEdBQUwsS0FBSyxDQUFLO1FBQW1CLFlBQU8sR0FBUCxPQUFPLENBQXlCO1FBQ3hGLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUM7UUFDekMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFTSxRQUFRLENBQUMsSUFBTztRQUNyQixJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDakIsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDdkIsQ0FBQztJQUNILENBQUM7SUFFTSxJQUFJO1FBQ1QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUVPLFNBQVM7UUFDZixJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNmLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDekIsSUFBSSxDQUFDLEtBQUssR0FBRyxTQUFTLENBQUM7UUFDekIsQ0FBQztJQUNILENBQUM7SUFFTyxhQUFhO1FBQ25CLElBQUksQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUVPLE1BQU07UUFDWixJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMzQyxDQUFDO0NBQ0Y7QUF0Q0QsNEJBc0NDO0FBZ0JEOzs7O0dBSUc7QUFDSCxTQUFnQixvQkFBb0I7SUFDbEMsSUFBSSxPQUEwQyxFQUFFLE1BQXdDLENBQUM7SUFDekYsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLENBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUU7UUFDMUMsT0FBTyxHQUFHLEdBQUcsQ0FBQztRQUNkLE1BQU0sR0FBRyxHQUFHLENBQUM7SUFDZixDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQVEsRUFBRSxNQUFNLEVBQUUsTUFBTyxFQUFFLENBQUM7QUFDekQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIENESyBFeGVjXG5pbXBvcnQgeyBzcGF3blN5bmMgfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcblxuLyoqXG4gKiBPdXIgb3duIGV4ZWN1dGUgZnVuY3Rpb24gd2hpY2ggZG9lc24ndCB1c2Ugc2hlbGxzIGFuZCBzdHJpbmdzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXhlYyhjb21tYW5kTGluZTogc3RyaW5nW10sIG9wdGlvbnM6IHsgY3dkPzogc3RyaW5nOyB2ZXJib3NlPzogYm9vbGVhbjsgZW52PzogYW55IH0gPSB7IH0pOiBhbnkge1xuICBjb25zdCBwcm9jID0gc3Bhd25TeW5jKGNvbW1hbmRMaW5lWzBdLCBjb21tYW5kTGluZS5zbGljZSgxKSwge1xuICAgIHN0ZGlvOiBbJ2lnbm9yZScsICdwaXBlJywgb3B0aW9ucy52ZXJib3NlID8gJ2luaGVyaXQnIDogJ3BpcGUnXSwgLy8gaW5oZXJpdCBTVERFUlIgaW4gdmVyYm9zZSBtb2RlXG4gICAgZW52OiB7XG4gICAgICAuLi5wcm9jZXNzLmVudixcbiAgICAgIC4uLm9wdGlvbnMuZW52LFxuICAgIH0sXG4gICAgY3dkOiBvcHRpb25zLmN3ZCxcbiAgfSk7XG5cbiAgaWYgKHByb2MuZXJyb3IpIHtcbiAgICB0aHJvdyBwcm9jLmVycm9yO1xuICB9XG4gIGlmIChwcm9jLnN0YXR1cyAhPT0gMCkge1xuICAgIGlmIChwcm9jZXNzLnN0ZGVycikgeyAvLyB3aWxsIGJlICdudWxsJyBpbiB2ZXJib3NlIG1vZGVcbiAgICAgIHByb2Nlc3Muc3RkZXJyLndyaXRlKHByb2Muc3RkZXJyKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDb21tYW5kIGV4aXRlZCB3aXRoICR7cHJvYy5zdGF0dXMgPyBgc3RhdHVzICR7cHJvYy5zdGF0dXN9YCA6IGBzaWduYWwgJHtwcm9jLnNpZ25hbH1gfWApO1xuICB9XG5cbiAgY29uc3Qgb3V0cHV0ID0gcHJvYy5zdGRvdXQudG9TdHJpbmcoJ3V0Zi04JykudHJpbSgpO1xuXG4gIHJldHVybiBvdXRwdXQ7XG59XG5cbnR5cGUgQ29tbWFuZCA9IEFycmF5PHN0cmluZyB8IENvbW1hbmQ+O1xuXG4vKipcbiAqIExpa2UgZXhlYywgYnV0IGFueSBhcnJheXMgZW5jb3VudGVyZWQgaW5zaWRlIHRoZSBjb21tYW5kIGFycmF5IGFyZSBwdWxsIG91dCBhbmQgZXhlY3V0ZWQgZmlyc3QsIHRoYW4gdGhlaXIgdmFsdWUgaXMgaW5zZXJ0ZWQgYWdhaW4uXG4gKiBUaGlzIG1pbWljcyBleGVjdXRpb24gYSBjb21tYW5kIHdpdGggc3ViIHNoZWxsIGJlaGF2aW9yLlxuICpcbiAqIEZvciBleGFtcGxlIHRoaXMgaW5wdXQ6XG4gKiBgYGBcbiAqIFtcImdpdFwiLCBcImNoZWNrb3V0XCIsIFtcImdpdFwiLCBcIm1lcmdlLWJhc2VcIiwgXCJIRUFEXCJdLCBcIi0tLFwiIFwicGF0aC90by9maWxlXCJdXG4gKiBgYGBcbiAqIHdpbGwgcnVuIHNvbWV0aGluZyBsaWtlIHRoaXM6XG4gKiBgYGBcbiAqIGdpdCBjaGVja291dCAkKGdpdCBtZXJnZS1iYXNlIEhFQUQpIC0tIHBhdGgvdG8vZmlsZVxuICogYGBgXG4gKlxuICogTm90ZSB0aGF0IHRoZSBhbGdvcml0aG0gd2lsbCBkZXRlY3Qgc3ViIHNoZWxscyBmaXJzdCwgZXhlYyB0aGVtIGFuZCB0aGVuXG4gKiBzdWJzdGl0dXRlIHRoZSByZXR1cm4gdmFsdWVzIGluLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXhlY1dpdGhTdWJTaGVsbChjb21tYW5kOiBDb21tYW5kLCBvcHRpb25zOiB7IGN3ZD86IHN0cmluZzsgdmVyYm9zZT86IGJvb2xlYW47IGVudj86IGFueSB9ID0geyB9KTogYW55IHtcbiAgY29uc3QgcmVzb2x2ZWRDb21tYW5kOiBzdHJpbmdbXSA9IGNvbW1hbmQubWFwKChjbWQpID0+IHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShjbWQpKSB7XG4gICAgICByZXR1cm4gZXhlY1dpdGhTdWJTaGVsbChjbWQsIG9wdGlvbnMpO1xuICAgIH1cbiAgICByZXR1cm4gY21kO1xuICB9KTtcblxuICByZXR1cm4gZXhlYyhyZXNvbHZlZENvbW1hbmQsIG9wdGlvbnMpO1xufVxuXG4vKipcbiAqIFRha2VzIHRoZSBzYW1lIGlucHV0IGFzIGBleGVjV2l0aFN1YlNoZWxsYCBhbmQgcmV0dXJucyBhIHN0cmluZyB3aXRoIHN1YiBzaGVsbHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJDb21tYW5kKGNvbW1hbmQ6IENvbW1hbmQpOiBzdHJpbmcge1xuICByZXR1cm4gY29tbWFuZC5tYXAoKGNtZCkgPT4ge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGNtZCkpIHtcbiAgICAgIHJldHVybiBgJCgke3JlbmRlckNvbW1hbmQoY21kKX0pYDtcbiAgICB9XG4gICAgcmV0dXJuIGNtZDtcbiAgfSkuam9pbignICcpO1xufVxuXG4vKipcbiAqIEZsYXR0ZW4gYSBsaXN0IG9mIGxpc3RzIGludG8gYSBsaXN0IG9mIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmbGF0dGVuPFQ+KHhzOiBUW11bXSk6IFRbXSB7XG4gIHJldHVybiBBcnJheS5wcm90b3R5cGUuY29uY2F0LmFwcGx5KFtdLCB4cyk7XG59XG5cbi8qKlxuICogQ2hhaW4gY29tbWFuZHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoYWluKGNvbW1hbmRzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIHJldHVybiBjb21tYW5kcy5maWx0ZXIoYyA9PiAhIWMpLmpvaW4oJyAmJiAnKTtcbn1cblxuLyoqXG4gKiBTcGxpdCBjb21tYW5kIHRvIGNodW5rcyBieSBzcGFjZVxuICovXG5leHBvcnQgZnVuY3Rpb24gY2h1bmtzKGNvbW1hbmQ6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgY29uc3QgcmVzdWx0ID0gY29tbWFuZC5tYXRjaCgvKD86W15cXHNcIl0rfFwiW15cIl0qXCIpKy9nKTtcbiAgcmV0dXJuIHJlc3VsdCA/PyBbXTtcbn1cblxuLyoqXG4gKiBBIGNsYXNzIGhvbGRpbmcgYSBzZXQgb2YgaXRlbXMgd2hpY2ggYXJlIGJlaW5nIGNyb3NzZWQgb2ZmIGluIHRpbWVcbiAqXG4gKiBJZiBpdCB0YWtlcyB0b28gbG9uZyB0byBjcm9zcyBvZmYgYSBuZXcgaXRlbSwgcHJpbnQgdGhlIGxpc3QuXG4gKi9cbmV4cG9ydCBjbGFzcyBXb3JrTGlzdDxBPiB7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVtYWluaW5nOiBTZXQ8QT47XG4gIHByaXZhdGUgcmVhZG9ubHkgdGltZW91dDogbnVtYmVyO1xuICBwcml2YXRlIHRpbWVyPzogTm9kZUpTLlRpbWVvdXQ7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBpdGVtczogQVtdLCBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IFdvcmtMaXN0T3B0aW9uczxBPiA9IHt9KSB7XG4gICAgdGhpcy5yZW1haW5pbmcgPSBuZXcgU2V0KHRoaXMuaXRlbXMpO1xuICAgIHRoaXMudGltZW91dCA9IG9wdGlvbnMudGltZW91dCA/PyA2MF8wMDA7XG4gICAgdGhpcy5zY2hlZHVsZVRpbWVyKCk7XG4gIH1cblxuICBwdWJsaWMgY3Jvc3NPZmYoaXRlbTogQSkge1xuICAgIHRoaXMucmVtYWluaW5nLmRlbGV0ZShpdGVtKTtcbiAgICB0aGlzLnN0b3BUaW1lcigpO1xuICAgIGlmICh0aGlzLnJlbWFpbmluZy5zaXplID4gMCkge1xuICAgICAgdGhpcy5zY2hlZHVsZVRpbWVyKCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGRvbmUoKSB7XG4gICAgdGhpcy5yZW1haW5pbmcuY2xlYXIoKTtcbiAgICB0aGlzLnN0b3BUaW1lcigpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdG9wVGltZXIoKSB7XG4gICAgaWYgKHRoaXMudGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTtcbiAgICAgIHRoaXMudGltZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzY2hlZHVsZVRpbWVyKCkge1xuICAgIHRoaXMudGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMucmVwb3J0KCksIHRoaXMudGltZW91dCk7XG4gIH1cblxuICBwcml2YXRlIHJlcG9ydCgpIHtcbiAgICB0aGlzLm9wdGlvbnMub25UaW1lb3V0Py4odGhpcy5yZW1haW5pbmcpO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgV29ya0xpc3RPcHRpb25zPEE+IHtcbiAgLyoqXG4gICAqIFdoZW4gdG8gcmVwbHkgd2l0aCByZW1haW5pbmcgaXRlbXNcbiAgICpcbiAgICogQGRlZmF1bHQgNjAwMDBcbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEZ1bmN0aW9uIHRvIGNhbGwgd2hlbiB0aW1lb3V0IGhpdHNcbiAgICovXG4gIHJlYWRvbmx5IG9uVGltZW91dD86ICh4OiBTZXQ8QT4pID0+IHZvaWQ7XG59XG5cbi8qKlxuICogQSBiYWNrcG9ydCBvZiBQcm9taXNlci53aXRoUmVzb2x2ZXJzXG4gKlxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9Qcm9taXNlL3dpdGhSZXNvbHZlcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByb21pc2VXaXRoUmVzb2x2ZXJzPEE+KCk6IFByb21pc2VBbmRSZXNvbHZlcnM8QT4ge1xuICBsZXQgcmVzb2x2ZTogUHJvbWlzZUFuZFJlc29sdmVyczxBPlsncmVzb2x2ZSddLCByZWplY3Q6IFByb21pc2VBbmRSZXNvbHZlcnM8QT5bJ3JlamVjdCddO1xuICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2U8QT4oKHJlcywgcmVqKSA9PiB7XG4gICAgcmVzb2x2ZSA9IHJlcztcbiAgICByZWplY3QgPSByZWo7XG4gIH0pO1xuICByZXR1cm4geyBwcm9taXNlLCByZXNvbHZlOiByZXNvbHZlISwgcmVqZWN0OiByZWplY3QhIH07XG59XG5cbmludGVyZmFjZSBQcm9taXNlQW5kUmVzb2x2ZXJzPEE+IHtcbiAgcHJvbWlzZTogUHJvbWlzZTxBPjtcbiAgcmVzb2x2ZTogKHZhbHVlOiBBKSA9PiB2b2lkO1xuICByZWplY3Q6IChyZWFzb246IGFueSkgPT4gdm9pZDtcbn1cbiJdfQ==