UNPKG

14.7 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.checkIteratorMessages = exports.expectMessage = exports.toArray = exports.sleep = exports.title = exports.noValidateConfigs = exports.configs = exports.record = exports.checkResourcesCleanedUp = exports.withClock = exports.stdev = exports.avg = exports.sum = exports.measureConcurrency = exports.keysOf = void 0;
4const lolex = require("lolex");
5const util_1 = require("util");
6const index_1 = require("../../index");
7const serialize_1 = require("../../src/serialize");
8const shared_1 = require("../../src/shared");
9Object.defineProperty(exports, "keysOf", { enumerable: true, get: function () { return shared_1.keysOf; } });
10const measureConcurrency = (timings) => timings
11 .map(t => t.start)
12 .map(t => timings.filter(({ start, end }) => start <= t && t < end).length)
13 .reduce((a, b) => Math.max(a, b));
14exports.measureConcurrency = measureConcurrency;
15const sum = (a) => a.reduce((total, n) => total + n, 0);
16exports.sum = sum;
17const avg = (a) => (0, exports.sum)(a) / a.length;
18exports.avg = avg;
19const stdev = (a) => {
20 const average = (0, exports.avg)(a);
21 return Math.sqrt((0, exports.avg)(a.map(v => (v - average) ** 2)));
22};
23exports.stdev = stdev;
24async function withClock(fn) {
25 const clock = lolex.install({ shouldAdvanceTime: true, now: Date.now() });
26 try {
27 await fn(clock);
28 }
29 finally {
30 clock.uninstall();
31 }
32}
33exports.withClock = withClock;
34function checkResourcesCleanedUp(t, resources) {
35 for (const key of (0, shared_1.keysOf)(resources)) {
36 t.is(resources[key], undefined);
37 if (resources[key] !== undefined) {
38 console.log(`Resource '${key}' not cleaned up: %O`, resources[key]);
39 }
40 }
41}
42exports.checkResourcesCleanedUp = checkResourcesCleanedUp;
43function record(fn) {
44 const func = Object.assign((...args) => {
45 const rv = fn(...args);
46 func.recordings.push({ args, rv });
47 index_1.log.info(`func.recordings: %O`, func.recordings);
48 return rv;
49 }, { recordings: [] });
50 return func;
51}
52exports.record = record;
53exports.configs = [
54 // { mode: "https", childProcess: false, validateSerialization: true },
55 { mode: "https", childProcess: true, validateSerialization: true },
56 // { mode: "queue", childProcess: false, validateSerialization: true },
57 { mode: "queue", childProcess: true, validateSerialization: true }
58];
59exports.noValidateConfigs = exports.configs.map(c => ({
60 ...c,
61 validateSerialization: false
62}));
63function title(provider, msg, options) {
64 const desc = options ? (0, util_1.inspect)(options, { breakLength: Infinity }) : "";
65 return [provider === "local" ? "" : "remote", provider, msg, desc]
66 .filter(x => x !== "")
67 .join(" ");
68}
69exports.title = title;
70function sleep(ms) {
71 return new Promise(resolve => setTimeout(resolve, ms));
72}
73exports.sleep = sleep;
74async function toArray(gen) {
75 const result = [];
76 for await (const elem of gen) {
77 result.push(elem);
78 }
79 return result;
80}
81exports.toArray = toArray;
82function expectMessage(t, msg, kind, expected) {
83 t.is(msg.kind, kind);
84 if (msg.kind === kind) {
85 const [value] = (0, serialize_1.deserialize)(msg.value);
86 t.deepEqual(value, expected);
87 }
88}
89exports.expectMessage = expectMessage;
90function checkIteratorMessages(t, rawMessages, arg) {
91 const messages = [];
92 t.is(rawMessages.length, arg.length + 1);
93 for (const msg of rawMessages) {
94 messages[msg.sequence] = msg;
95 }
96 let i = 0;
97 for (; i < arg.length; i++) {
98 expectMessage(t, messages[i], "iterator", { done: false, value: arg[i] });
99 }
100 expectMessage(t, messages[i], "iterator", { done: true });
101}
102exports.checkIteratorMessages = checkIteratorMessages;
103//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvZml4dHVyZXMvdXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSwrQkFBK0I7QUFDL0IsK0JBQStCO0FBQy9CLHVDQUEyRDtBQUUzRCxtREFBa0Q7QUFDbEQsNkNBQTBDO0FBRWpDLHVGQUZBLGVBQU0sT0FFQTtBQUVSLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxPQUFpQixFQUFFLEVBQUUsQ0FDcEQsT0FBTztLQUNGLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7S0FDakIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsQ0FBQyxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7S0FDMUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUo3QixRQUFBLGtCQUFrQixzQkFJVztBQUVuQyxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFBNUQsUUFBQSxHQUFHLE9BQXlEO0FBRWxFLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBVyxFQUFFLEVBQUUsQ0FBQyxJQUFBLFdBQUcsRUFBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0FBQXpDLFFBQUEsR0FBRyxPQUFzQztBQUUvQyxNQUFNLEtBQUssR0FBRyxDQUFDLENBQVcsRUFBRSxFQUFFO0lBQ2pDLE1BQU0sT0FBTyxHQUFHLElBQUEsV0FBRyxFQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFBLFdBQUcsRUFBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFELENBQUMsQ0FBQztBQUhXLFFBQUEsS0FBSyxTQUdoQjtBQUlLLEtBQUssVUFBVSxTQUFTLENBQUMsRUFBb0M7SUFDaEUsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLGlCQUFpQixFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUMxRSxJQUFJO1FBQ0EsTUFBTSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDbkI7WUFBUztRQUNOLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQztLQUNyQjtBQUNMLENBQUM7QUFQRCw4QkFPQztBQUVELFNBQWdCLHVCQUF1QixDQUNuQyxDQUFtQixFQUNuQixTQUFZO0lBRVosS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFBLGVBQU0sRUFBQyxTQUFTLENBQUMsRUFBRTtRQUNqQyxDQUFDLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUNoQyxJQUFJLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxTQUFTLEVBQUU7WUFDOUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLEdBQUcsc0JBQXNCLEVBQUUsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7U0FDdkU7S0FDSjtBQUNMLENBQUM7QUFWRCwwREFVQztBQVlELFNBQWdCLE1BQU0sQ0FBcUIsRUFBcUI7SUFDNUQsTUFBTSxJQUFJLEdBQTJCLE1BQU0sQ0FBQyxNQUFNLENBQzlDLENBQUMsR0FBRyxJQUFPLEVBQUUsRUFBRTtRQUNYLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDbkMsV0FBRyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDakQsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDLEVBQ0QsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLENBQ3JCLENBQUM7SUFDRixPQUFPLElBQUksQ0FBQztBQUNoQixDQUFDO0FBWEQsd0JBV0M7QUFFWSxRQUFBLE9BQU8sR0FBb0I7SUFDcEMsdUVBQXVFO0lBQ3ZFLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLHFCQUFxQixFQUFFLElBQUksRUFBRTtJQUNsRSx1RUFBdUU7SUFDdkUsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUscUJBQXFCLEVBQUUsSUFBSSxFQUFFO0NBQ3JFLENBQUM7QUFFVyxRQUFBLGlCQUFpQixHQUFHLGVBQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQy9DLEdBQUcsQ0FBQztJQUNKLHFCQUFxQixFQUFFLEtBQUs7Q0FDL0IsQ0FBQyxDQUFDLENBQUM7QUFFSixTQUFnQixLQUFLLENBQUMsUUFBa0IsRUFBRSxHQUFXLEVBQUUsT0FBZ0I7SUFDbkUsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFBLGNBQU8sRUFBQyxPQUFPLEVBQUUsRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ3hFLE9BQU8sQ0FBQyxRQUFRLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQztTQUM3RCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1NBQ3JCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNuQixDQUFDO0FBTEQsc0JBS0M7QUFFRCxTQUFnQixLQUFLLENBQUMsRUFBVTtJQUM1QixPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzNELENBQUM7QUFGRCxzQkFFQztBQUVNLEtBQUssVUFBVSxPQUFPLENBQUksR0FBbUM7SUFDaEUsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDO0lBQ2xCLElBQUksS0FBSyxFQUFFLE1BQU0sSUFBSSxJQUFJLEdBQUcsRUFBRTtRQUMxQixNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ3JCO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDbEIsQ0FBQztBQU5ELDBCQU1DO0FBRUQsU0FBZ0IsYUFBYSxDQUN6QixDQUFtQixFQUNuQixHQUFZLEVBQ1osSUFBNEIsRUFDNUIsUUFBVztJQUVYLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNyQixJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssSUFBSSxFQUFFO1FBQ25CLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFBLHVCQUFXLEVBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3ZDLENBQUMsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0tBQ2hDO0FBQ0wsQ0FBQztBQVhELHNDQVdDO0FBRUQsU0FBZ0IscUJBQXFCLENBQ2pDLENBQW1CLEVBQ25CLFdBQXNDLEVBQ3RDLEdBQWE7SUFFYixNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUM7SUFDcEIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDekMsS0FBSyxNQUFNLEdBQUcsSUFBSSxXQUFXLEVBQUU7UUFDM0IsUUFBUSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxHQUFHLENBQUM7S0FDaEM7SUFFRCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDVixPQUFPLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ3hCLGFBQWEsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7S0FDN0U7SUFDRCxhQUFhLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUM5RCxDQUFDO0FBaEJELHNEQWdCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEV4ZWN1dGlvbkNvbnRleHQgfSBmcm9tIFwiYXZhXCI7XG5pbXBvcnQgKiBhcyBsb2xleCBmcm9tIFwibG9sZXhcIjtcbmltcG9ydCB7IGluc3BlY3QgfSBmcm9tIFwidXRpbFwiO1xuaW1wb3J0IHsgQ29tbW9uT3B0aW9ucywgbG9nLCBQcm92aWRlciB9IGZyb20gXCIuLi8uLi9pbmRleFwiO1xuaW1wb3J0IHsgSXRlcmF0b3JSZXNwb25zZU1lc3NhZ2UsIE1lc3NhZ2UgfSBmcm9tIFwiLi4vLi4vc3JjL3Byb3ZpZGVyXCI7XG5pbXBvcnQgeyBkZXNlcmlhbGl6ZSB9IGZyb20gXCIuLi8uLi9zcmMvc2VyaWFsaXplXCI7XG5pbXBvcnQgeyBrZXlzT2YgfSBmcm9tIFwiLi4vLi4vc3JjL3NoYXJlZFwiO1xuaW1wb3J0IHsgVGltaW5nIH0gZnJvbSBcIi4vZnVuY3Rpb25zXCI7XG5leHBvcnQgeyBrZXlzT2YgfTtcblxuZXhwb3J0IGNvbnN0IG1lYXN1cmVDb25jdXJyZW5jeSA9ICh0aW1pbmdzOiBUaW1pbmdbXSkgPT5cbiAgICB0aW1pbmdzXG4gICAgICAgIC5tYXAodCA9PiB0LnN0YXJ0KVxuICAgICAgICAubWFwKHQgPT4gdGltaW5ncy5maWx0ZXIoKHsgc3RhcnQsIGVuZCB9KSA9PiBzdGFydCA8PSB0ICYmIHQgPCBlbmQpLmxlbmd0aClcbiAgICAgICAgLnJlZHVjZSgoYSwgYikgPT4gTWF0aC5tYXgoYSwgYikpO1xuXG5leHBvcnQgY29uc3Qgc3VtID0gKGE6IG51bWJlcltdKSA9PiBhLnJlZHVjZSgodG90YWwsIG4pID0+IHRvdGFsICsgbiwgMCk7XG5cbmV4cG9ydCBjb25zdCBhdmcgPSAoYTogbnVtYmVyW10pID0+IHN1bShhKSAvIGEubGVuZ3RoO1xuXG5leHBvcnQgY29uc3Qgc3RkZXYgPSAoYTogbnVtYmVyW10pID0+IHtcbiAgICBjb25zdCBhdmVyYWdlID0gYXZnKGEpO1xuICAgIHJldHVybiBNYXRoLnNxcnQoYXZnKGEubWFwKHYgPT4gKHYgLSBhdmVyYWdlKSAqKiAyKSkpO1xufTtcblxuZXhwb3J0IHR5cGUgVkNsb2NrID0gbG9sZXguSW5zdGFsbGVkQ2xvY2s8bG9sZXguQ2xvY2s+O1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd2l0aENsb2NrKGZuOiAoY2xvY2s6IFZDbG9jaykgPT4gUHJvbWlzZTx2b2lkPikge1xuICAgIGNvbnN0IGNsb2NrID0gbG9sZXguaW5zdGFsbCh7IHNob3VsZEFkdmFuY2VUaW1lOiB0cnVlLCBub3c6IERhdGUubm93KCkgfSk7XG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZm4oY2xvY2spO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGNsb2NrLnVuaW5zdGFsbCgpO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrUmVzb3VyY2VzQ2xlYW5lZFVwPFQgZXh0ZW5kcyBvYmplY3Q+KFxuICAgIHQ6IEV4ZWN1dGlvbkNvbnRleHQsXG4gICAgcmVzb3VyY2VzOiBUXG4pIHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzT2YocmVzb3VyY2VzKSkge1xuICAgICAgICB0LmlzKHJlc291cmNlc1trZXldLCB1bmRlZmluZWQpO1xuICAgICAgICBpZiAocmVzb3VyY2VzW2tleV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFJlc291cmNlICcke2tleX0nIG5vdCBjbGVhbmVkIHVwOiAlT2AsIHJlc291cmNlc1trZXldKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWNvcmRlZENhbGw8QSBleHRlbmRzIGFueVtdLCBSPiB7XG4gICAgYXJnczogQTtcbiAgICBydjogUjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWNvcmRlZEZ1bmN0aW9uPEEgZXh0ZW5kcyBhbnlbXSwgUj4ge1xuICAgICguLi5hcmdzOiBBKTogUjtcbiAgICByZWNvcmRpbmdzOiBBcnJheTxSZWNvcmRlZENhbGw8QSwgUj4+O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkPEEgZXh0ZW5kcyBhbnlbXSwgUj4oZm46ICguLi5hcmdzOiBBKSA9PiBSKSB7XG4gICAgY29uc3QgZnVuYzogUmVjb3JkZWRGdW5jdGlvbjxBLCBSPiA9IE9iamVjdC5hc3NpZ24oXG4gICAgICAgICguLi5hcmdzOiBBKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBydiA9IGZuKC4uLmFyZ3MpO1xuICAgICAgICAgICAgZnVuYy5yZWNvcmRpbmdzLnB1c2goeyBhcmdzLCBydiB9KTtcbiAgICAgICAgICAgIGxvZy5pbmZvKGBmdW5jLnJlY29yZGluZ3M6ICVPYCwgZnVuYy5yZWNvcmRpbmdzKTtcbiAgICAgICAgICAgIHJldHVybiBydjtcbiAgICAgICAgfSxcbiAgICAgICAgeyByZWNvcmRpbmdzOiBbXSB9XG4gICAgKTtcbiAgICByZXR1cm4gZnVuYztcbn1cblxuZXhwb3J0IGNvbnN0IGNvbmZpZ3M6IENvbW1vbk9wdGlvbnNbXSA9IFtcbiAgICAvLyB7IG1vZGU6IFwiaHR0cHNcIiwgY2hpbGRQcm9jZXNzOiBmYWxzZSwgdmFsaWRhdGVTZXJpYWxpemF0aW9uOiB0cnVlIH0sXG4gICAgeyBtb2RlOiBcImh0dHBzXCIsIGNoaWxkUHJvY2VzczogdHJ1ZSwgdmFsaWRhdGVTZXJpYWxpemF0aW9uOiB0cnVlIH0sXG4gICAgLy8geyBtb2RlOiBcInF1ZXVlXCIsIGNoaWxkUHJvY2VzczogZmFsc2UsIHZhbGlkYXRlU2VyaWFsaXphdGlvbjogdHJ1ZSB9LFxuICAgIHsgbW9kZTogXCJxdWV1ZVwiLCBjaGlsZFByb2Nlc3M6IHRydWUsIHZhbGlkYXRlU2VyaWFsaXphdGlvbjogdHJ1ZSB9XG5dO1xuXG5leHBvcnQgY29uc3Qgbm9WYWxpZGF0ZUNvbmZpZ3MgPSBjb25maWdzLm1hcChjID0+ICh7XG4gICAgLi4uYyxcbiAgICB2YWxpZGF0ZVNlcmlhbGl6YXRpb246IGZhbHNlXG59KSk7XG5cbmV4cG9ydCBmdW5jdGlvbiB0aXRsZShwcm92aWRlcjogUHJvdmlkZXIsIG1zZzogc3RyaW5nLCBvcHRpb25zPzogb2JqZWN0KSB7XG4gICAgY29uc3QgZGVzYyA9IG9wdGlvbnMgPyBpbnNwZWN0KG9wdGlvbnMsIHsgYnJlYWtMZW5ndGg6IEluZmluaXR5IH0pIDogXCJcIjtcbiAgICByZXR1cm4gW3Byb3ZpZGVyID09PSBcImxvY2FsXCIgPyBcIlwiIDogXCJyZW1vdGVcIiwgcHJvdmlkZXIsIG1zZywgZGVzY11cbiAgICAgICAgLmZpbHRlcih4ID0+IHggIT09IFwiXCIpXG4gICAgICAgIC5qb2luKFwiIFwiKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNsZWVwKG1zOiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0b0FycmF5PFQ+KGdlbjogQXN5bmNJdGVyYWJsZTxUPiB8IEl0ZXJhYmxlPFQ+KSB7XG4gICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgZm9yIGF3YWl0IChjb25zdCBlbGVtIG9mIGdlbikge1xuICAgICAgICByZXN1bHQucHVzaChlbGVtKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4cGVjdE1lc3NhZ2U8VD4oXG4gICAgdDogRXhlY3V0aW9uQ29udGV4dCxcbiAgICBtc2c6IE1lc3NhZ2UsXG4gICAga2luZDogXCJwcm9taXNlXCIgfCBcIml0ZXJhdG9yXCIsXG4gICAgZXhwZWN0ZWQ6IFRcbikge1xuICAgIHQuaXMobXNnLmtpbmQsIGtpbmQpO1xuICAgIGlmIChtc2cua2luZCA9PT0ga2luZCkge1xuICAgICAgICBjb25zdCBbdmFsdWVdID0gZGVzZXJpYWxpemUobXNnLnZhbHVlKTtcbiAgICAgICAgdC5kZWVwRXF1YWwodmFsdWUsIGV4cGVjdGVkKTtcbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjaGVja0l0ZXJhdG9yTWVzc2FnZXMoXG4gICAgdDogRXhlY3V0aW9uQ29udGV4dCxcbiAgICByYXdNZXNzYWdlczogSXRlcmF0b3JSZXNwb25zZU1lc3NhZ2VbXSxcbiAgICBhcmc6IHN0cmluZ1tdXG4pIHtcbiAgICBjb25zdCBtZXNzYWdlcyA9IFtdO1xuICAgIHQuaXMocmF3TWVzc2FnZXMubGVuZ3RoLCBhcmcubGVuZ3RoICsgMSk7XG4gICAgZm9yIChjb25zdCBtc2cgb2YgcmF3TWVzc2FnZXMpIHtcbiAgICAgICAgbWVzc2FnZXNbbXNnLnNlcXVlbmNlXSA9IG1zZztcbiAgICB9XG5cbiAgICBsZXQgaSA9IDA7XG4gICAgZm9yICg7IGkgPCBhcmcubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZXhwZWN0TWVzc2FnZSh0LCBtZXNzYWdlc1tpXSwgXCJpdGVyYXRvclwiLCB7IGRvbmU6IGZhbHNlLCB2YWx1ZTogYXJnW2ldIH0pO1xuICAgIH1cbiAgICBleHBlY3RNZXNzYWdlKHQsIG1lc3NhZ2VzW2ldLCBcIml0ZXJhdG9yXCIsIHsgZG9uZTogdHJ1ZSB9KTtcbn1cbiJdfQ==
\No newline at end of file