socket-function 1.2.2 → 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/SocketFunction.d.ts +1 -1
  2. package/SocketFunctionTypes.d.ts +1 -1
  3. package/hot/HotReloadController.d.ts +3 -3
  4. package/index.d.ts +25 -10
  5. package/package.json +1 -1
  6. package/require/CSSShim.d.ts +1 -1
  7. package/require/RequireController.d.ts +2 -2
  8. package/require/compileFlags.d.ts +1 -1
  9. package/require/require.d.ts +1 -1
  10. package/src/callManager.d.ts +1 -1
  11. package/test.ts +5 -11
  12. package/time/trueTimeShim.d.ts +16 -1
  13. package/time/trueTimeShim.ts +43 -7
  14. package/dist/SetProcessVariables.ts.cache +0 -9
  15. package/dist/SocketFunction.ts.cache +0 -467
  16. package/hot/dist/HotReloadController.ts.cache +0 -252
  17. package/require/dist/RequireController.ts.cache +0 -386
  18. package/require/dist/compileFlags.ts.cache +0 -41
  19. package/require/dist/extMapper.ts.cache +0 -368
  20. package/require/dist/require.ts.cache +0 -676
  21. package/src/JSONLACKS/dist/JSONLACKS.ts.cache +0 -469
  22. package/src/dist/CallFactory.ts.cache +0 -930
  23. package/src/dist/Zip.ts.cache +0 -156
  24. package/src/dist/batching.ts.cache +0 -377
  25. package/src/dist/bits.ts.cache +0 -121
  26. package/src/dist/buffers.ts.cache +0 -76
  27. package/src/dist/caching.ts.cache +0 -302
  28. package/src/dist/callHTTPHandler.ts.cache +0 -264
  29. package/src/dist/callManager.ts.cache +0 -159
  30. package/src/dist/certStore.ts.cache +0 -59
  31. package/src/dist/createSingleton.ts.cache +0 -62
  32. package/src/dist/fixLargeNetworkCalls.ts.cache +0 -17
  33. package/src/dist/forwardPort.ts.cache +0 -222
  34. package/src/dist/https.ts.cache +0 -141
  35. package/src/dist/misc.ts.cache +0 -499
  36. package/src/dist/nodeCache.ts.cache +0 -136
  37. package/src/dist/nodeProxy.ts.cache +0 -57
  38. package/src/dist/protocolNegotiation.ts.cache +0 -101
  39. package/src/dist/tlsParsing.ts.cache +0 -85
  40. package/src/dist/types.ts.cache +0 -9
  41. package/src/dist/webSocketServer.ts.cache +0 -365
  42. package/src/dist/websocketFactory.ts.cache +0 -53
  43. package/src/formatting/dist/colors.ts.cache +0 -98
  44. package/src/formatting/dist/format.ts.cache +0 -396
  45. package/src/formatting/dist/logColors.ts.cache +0 -28
  46. package/src/lz4/dist/LZ4.ts.cache +0 -53
  47. package/src/profiling/dist/getOwnTime.ts.cache +0 -100
  48. package/src/profiling/dist/measure.ts.cache +0 -338
  49. package/src/profiling/dist/stats.ts.cache +0 -202
  50. package/src/profiling/dist/statsFormat.ts.cache +0 -45
  51. package/time/dist/trueTimeShim.ts.cache +0 -707
@@ -1,100 +0,0 @@
1
- "use strict"; var console = (function shimConsole() { let baseConsole = globalThis.console; if (typeof window !== "undefined") return baseConsole; let name = __filename.replaceAll("\\", "/").split("/").pop(); let dirName = __dirname.replaceAll("\\", "/").split("/").pop(); let context = { __FILE__: __filename, __DIR__: __dirname, __NAME__: name, __DIRNAME__: dirName }; let newConsole = { ...baseConsole }; for (let shim of ["log", "info", "warn", "error"]) { newConsole[shim] = (...args) => { args.push(context); baseConsole[shim](...args); }; } newConsole.__context = context; return newConsole; })(); "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
3
- //exports.getOwnTime = exports.measureOverheadTime = exports.getOpenTimesBase = void 0;
4
- const createSingleton_1 = require("../createSingleton");
5
- // TODO: We could probably make this an optional / dev dependency, to allow
6
- // for use on machines without the ability to compile?
7
- //import { now } from "rdtsc-now";
8
- let now = () => performance.now();
9
- // Shared across every copy of this package loaded in the process, so a profile started via one
10
- // copy's startMeasure nests correctly with getOwnTime calls made through another copy. The
11
- // open-time stack MUST be a single instance, otherwise cross-copy nesting/own-time accounting
12
- // breaks (a function wrapped by copy A calling one wrapped by copy B would push onto a different
13
- // stack). See createSingleton.
14
- const openTimes = (0, createSingleton_1.createSingleton)("measure.openTimes", 1, () => []).get();
15
- function getOpenTimesBase() {
16
- return openTimes;
17
- }
18
- exports.getOpenTimesBase = getOpenTimesBase;
19
- globalThis.pendingOwnCallTime = openTimes;
20
- // NOTE: This overhead time is actually mostly for aggregate time, but it is needed,
21
- // otherwise we consistently underestimate the time spent.
22
- // ALSO! This forces high count lines to be at the top of the aggregate time list, which is really important!
23
- // NOTE: The overhead time greatly varies, but even if it only takes 100ns, if 10X of that
24
- // is significant, you are probably spending too much timing profiling anyway!
25
- exports.measureOverheadTime = 500 / 1000 / 1000;
26
- // We internally add, because of where we measure time, there is time spent before we grab the
27
- // current time, and after we record the last time, that is lost, but should be added.
28
- let addMeasureOverheadTime = 0;
29
- {
30
- // NOTE: This is going to vary considerably. I assume because sometimes we are on a core
31
- // that is free, and other times we are on a core that is hyperthreading with another hardware
32
- // thread. This really hurts us because our timing uses rdtsc, which really hates hyper threading,
33
- // and can easily get 50% slower because of it.
34
- let results = [];
35
- for (let j = 0; j < 10; j++) {
36
- const measureCount = 1000 * 10;
37
- let time = now();
38
- for (let i = 0; i < measureCount; i++) {
39
- getOwnTime("test", () => { }, () => { });
40
- }
41
- time = now() - time;
42
- let overhead = time / measureCount;
43
- results.push(overhead);
44
- }
45
- results.sort((a, b) => a - b);
46
- addMeasureOverheadTime = results[results.length / 2];
47
- }
48
- // TIMING: About 60ns, of which 40ns is just now() calls.
49
- // If async is closer to 300ns.
50
- // NOTE: Handles promises correctly
51
- function getOwnTime(name, code, onTime) {
52
- let time = now();
53
- let obj = {
54
- name,
55
- time: 0,
56
- ownTime: 0,
57
- firstStartTime: time,
58
- lastStartTime: time,
59
- };
60
- let prevOwnTime = openTimes[openTimes.length - 1];
61
- if (prevOwnTime) {
62
- prevOwnTime.ownTime += time - prevOwnTime.lastStartTime;
63
- }
64
- openTimes.push(obj);
65
- function finish() {
66
- let time = now();
67
- obj.time = time - obj.firstStartTime;
68
- if (obj === openTimes[openTimes.length - 1]) {
69
- obj.ownTime += time - obj.lastStartTime;
70
- let newOwnTime = openTimes[openTimes.length - 2];
71
- if (newOwnTime) {
72
- newOwnTime.lastStartTime = time;
73
- }
74
- }
75
- let index = openTimes.indexOf(obj);
76
- openTimes.splice(index, 1);
77
- obj.time += addMeasureOverheadTime;
78
- obj.ownTime += addMeasureOverheadTime;
79
- onTime(obj);
80
- }
81
- let isAsync = false;
82
- try {
83
- let result = code();
84
- if (result && typeof result === "object" && result instanceof Promise) {
85
- isAsync = true;
86
- return result.finally(() => {
87
- finish();
88
- });
89
- }
90
- return result;
91
- }
92
- finally {
93
- if (!isAsync) {
94
- finish();
95
- }
96
- }
97
- }
98
- exports.getOwnTime = getOwnTime;
99
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0T3duVGltZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImdldE93blRpbWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsd0RBQXFEO0FBQ3JELDJFQUEyRTtBQUMzRSx1REFBdUQ7QUFDdkQsa0NBQWtDO0FBQ2xDLElBQUksR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQVlsQywrRkFBK0Y7QUFDL0YsNEZBQTRGO0FBQzVGLCtGQUErRjtBQUMvRixrR0FBa0c7QUFDbEcsZ0NBQWdDO0FBQ2hDLE1BQU0sU0FBUyxHQUFHLElBQUEsaUNBQWUsRUFBQyxtQkFBbUIsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBMEIsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBRWxHLFNBQWdCLGdCQUFnQjtJQUM1QixPQUFPLFNBQVMsQ0FBQztBQUNyQixDQUFDO0FBRkQsNENBRUM7QUFFQSxVQUFrQixDQUFDLGtCQUFrQixHQUFHLFNBQVMsQ0FBQztBQUVuRCxvRkFBb0Y7QUFDcEYsMkRBQTJEO0FBQzNELDhHQUE4RztBQUM5RywwRkFBMEY7QUFDMUYsK0VBQStFO0FBQ2xFLFFBQUEsbUJBQW1CLEdBQUcsR0FBRyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFDckQsOEZBQThGO0FBQzlGLHVGQUF1RjtBQUN2RixJQUFJLHNCQUFzQixHQUFHLENBQUMsQ0FBQztBQUMvQixDQUFDO0lBQ0csd0ZBQXdGO0lBQ3hGLCtGQUErRjtJQUMvRixtR0FBbUc7SUFDbkcsZ0RBQWdEO0lBQ2hELElBQUksT0FBTyxHQUFhLEVBQUUsQ0FBQztJQUMzQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDMUIsTUFBTSxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUMvQixJQUFJLElBQUksR0FBRyxHQUFH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QU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7WUFBUyxDQUFDO1FBQ1AsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ1gsTUFBTSxFQUFFLENBQUM7UUFDYixDQUFDO0lBQ0wsQ0FBQztBQUNMLENBQUM7QUFyREQsZ0NBcURDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGRlYnVnYnJlYWsgZnJvbSBcImRlYnVnYnJlYWtcIjtcbmltcG9ydCB7IGlzTm9kZSB9IGZyb20gXCIuLi9taXNjXCI7XG5pbXBvcnQgeyBjcmVhdGVTaW5nbGV0b24gfSBmcm9tIFwiLi4vY3JlYXRlU2luZ2xldG9uXCI7XG4vLyBUT0RPOiBXZSBjb3VsZCBwcm9iYWJseSBtYWtlIHRoaXMgYW4gb3B0aW9uYWwgLyBkZXYgZGVwZW5kZW5jeSwgdG8gYWxsb3dcbi8vICBmb3IgdXNlIG9uIG1hY2hpbmVzIHdpdGhvdXQgdGhlIGFiaWxpdHkgdG8gY29tcGlsZT9cbi8vaW1wb3J0IHsgbm93IH0gZnJvbSBcInJkdHNjLW5vd1wiO1xubGV0IG5vdyA9ICgpID0+IHBlcmZvcm1hbmNlLm5vdygpO1xuXG5leHBvcnQgdHlwZSBPd25UaW1lT2JqID0ge1xuICAgIG5hbWU6IHN0cmluZztcbiAgICB0aW1lOiBudW1iZXI7XG4gICAgb3duVGltZTogbnVtYmVyO1xufTtcbmV4cG9ydCB0eXBlIE93blRpbWVPYmpJbnRlcm5hbCA9IE93blRpbWVPYmogJiB7XG4gICAgbGFzdFN0YXJ0VGltZTogbnVtYmVyO1xuICAgIGZpcnN0U3RhcnRUaW1lOiBudW1iZXI7XG59O1xuXG4vLyBTaGFyZWQgYWNyb3NzIGV2ZXJ5IGNvcHkgb2YgdGhpcyBwYWNrYWdlIGxvYWRlZCBpbiB0aGUgcHJvY2Vzcywgc28gYSBwcm9maWxlIHN0YXJ0ZWQgdmlhIG9uZVxuLy8gIGNvcHkncyBzdGFydE1lYXN1cmUgbmVzdHMgY29ycmVjdGx5IHdpdGggZ2V0T3duVGltZSBjYWxscyBtYWRlIHRocm91Z2ggYW5vdGhlciBjb3B5LiBUaGVcbi8vICBvcGVuLXRpbWUgc3RhY2sgTVVTVCBiZSBhIHNpbmdsZSBpbnN0YW5jZSwgb3RoZXJ3aXNlIGNyb3NzLWNvcHkgbmVzdGluZy9vd24tdGltZSBhY2NvdW50aW5nXG4vLyAgYnJlYWtzIChhIGZ1bmN0aW9uIHdyYXBwZWQgYnkgY29weSBBIGNhbGxpbmcgb25lIHdyYXBwZWQgYnkgY29weSBCIHdvdWxkIHB1c2ggb250byBhIGRpZmZlcmVudFxuLy8gIHN0YWNrKS4gU2VlIGNyZWF0ZVNpbmdsZXRvbi5cbmNvbnN0IG9wZW5UaW1lcyA9IGNyZWF0ZVNpbmdsZXRvbihcIm1lYXN1cmUub3BlblRpbWVzXCIsIDEsICgpID0+IFtdIGFzIE93blRpbWVPYmpJbnRlcm5hbFtdKS5nZXQoKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE9wZW5UaW1lc0Jhc2UoKTogT3duVGltZU9iakludGVybmFsW10ge1xuICAgIHJldHVybiBvcGVuVGltZXM7XG59XG5cbihnbG9iYWxUaGlzIGFzIGFueSkucGVuZGluZ093bkNhbGxUaW1lID0gb3BlblRpbWVzO1xuXG4vLyBOT1RFOiBUaGlzIG92ZXJoZWFkIHRpbWUgaXMgYWN0dWFsbHkgbW9zdGx5IGZvciBhZ2dyZWdhdGUgdGltZSwgYnV0IGl0IGlzIG5lZWRlZCxcbi8vICBvdGhlcndpc2Ugd2UgY29uc2lzdGVudGx5IHVuZGVyZXN0aW1hdGUgdGhlIHRpbWUgc3BlbnQuXG4vLyAgQUxTTyEgVGhpcyBmb3JjZXMgaGlnaCBjb3VudCBsaW5lcyB0byBiZSBhdCB0aGUgdG9wIG9mIHRoZSBhZ2dyZWdhdGUgdGltZSBsaXN0LCB3aGljaCBpcyByZWFsbHkgaW1wb3J0YW50IVxuLy8gTk9URTogVGhlIG92ZXJoZWFkIHRpbWUgZ3JlYXRseSB2YXJpZXMsIGJ1dCBldmVuIGlmIGl0IG9ubHkgdGFrZXMgMTAwbnMsIGlmIDEwWCBvZiB0aGF0XG4vLyAgaXMgc2lnbmlmaWNhbnQsIHlvdSBhcmUgcHJvYmFibHkgc3BlbmRpbmcgdG9vIG11Y2ggdGltaW5nIHByb2ZpbGluZyBhbnl3YXkhXG5leHBvcnQgY29uc3QgbWVhc3VyZU92ZXJoZWFkVGltZSA9IDUwMCAvIDEwMDAgLyAxMDAwO1xuLy8gV2UgaW50ZXJuYWxseSBhZGQsIGJlY2F1c2Ugb2Ygd2hlcmUgd2UgbWVhc3VyZSB0aW1lLCB0aGVyZSBpcyB0aW1lIHNwZW50IGJlZm9yZSB3ZSBncmFiIHRoZVxuLy8gIGN1cnJlbnQgdGltZSwgYW5kIGFmdGVyIHdlIHJlY29yZCB0aGUgbGFzdCB0aW1lLCB0aGF0IGlzIGxvc3QsIGJ1dCBzaG91bGQgYmUgYWRkZWQuXG5sZXQgYWRkTWVhc3VyZU92ZXJoZWFkVGltZSA9IDA7XG57XG4gICAgLy8gTk9URTogVGhpcyBpcyBnb2luZyB0byB2YXJ5IGNvbnNpZGVyYWJseS4gSSBhc3N1bWUgYmVjYXVzZSBzb21ldGltZXMgd2UgYXJlIG9uIGEgY29yZVxuICAgIC8vICB0aGF0IGlzIGZyZWUsIGFuZCBvdGhlciB0aW1lcyB3ZSBhcmUgb24gYSBjb3JlIHRoYXQgaXMgaHlwZXJ0aHJlYWRpbmcgd2l0aCBhbm90aGVyIGhhcmR3YXJlXG4gICAgLy8gIHRocmVhZC4gVGhpcyByZWFsbHkgaHVydHMgdXMgYmVjYXVzZSBvdXIgdGltaW5nIHVzZXMgcmR0c2MsIHdoaWNoIHJlYWxseSBoYXRlcyBoeXBlciB0aHJlYWRpbmcsXG4gICAgLy8gIGFuZCBjYW4gZWFzaWx5IGdldCA1MCUgc2xvd2VyIGJlY2F1c2Ugb2YgaXQuXG4gICAgbGV0IHJlc3VsdHM6IG51bWJlcltdID0gW107XG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCAxMDsgaisrKSB7XG4gICAgICAgIGNvbnN0IG1lYXN1cmVDb3VudCA9IDEwMDAgKiAxMDtcbiAgICAgICAgbGV0IHRpbWUgPSBub3coKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtZWFzdXJlQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgZ2V0T3duVGltZShcInRlc3RcIiwgKCkgPT4geyB9LCAoKSA9PiB7IH0pO1xuICAgICAgICB9XG4gICAgICAgIHRpbWUgPSBub3coKSAtIHRpbWU7XG4gICAgICAgIGxldCBvdmVyaGVhZCA9IHRpbWUgLyBtZWFzdXJlQ291bnQ7XG4gICAgICAgIHJlc3VsdHMucHVzaChvdmVyaGVhZCk7XG4gICAgfVxuICAgIHJlc3VsdHMuc29ydCgoYSwgYikgPT4gYSAtIGIpO1xuICAgIGFkZE1lYXN1cmVPdmVyaGVhZFRpbWUgPSByZXN1bHRzW3Jlc3VsdHMubGVuZ3RoIC8gMl07XG59XG5cbi8vIFRJTUlORzogQWJvdXQgNjBucywgb2Ygd2hpY2ggNDBucyBpcyBqdXN0IG5vdygpIGNhbGxzLlxuLy8gIElmIGFzeW5jIGlzIGNsb3NlciB0byAzMDBucy5cbi8vIE5PVEU6IEhhbmRsZXMgcHJvbWlzZXMgY29ycmVjdGx5XG5leHBvcnQgZnVuY3Rpb24gZ2V0T3duVGltZTxUPihcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgY29kZTogKCkgPT4gVCxcbiAgICBvblRpbWU6IChvYmo6IE93blRpbWVPYmopID0+IHZvaWRcbik6IFQge1xuICAgIGxldCB0aW1lID0gbm93KCk7XG4gICAgbGV0IG9iajogT3duVGltZU9iakludGVybmFsID0ge1xuICAgICAgICBuYW1lLFxuICAgICAgICB0aW1lOiAwLFxuICAgICAgICBvd25UaW1lOiAwLFxuICAgICAgICBmaXJzdFN0YXJ0VGltZTogdGltZSxcbiAgICAgICAgbGFzdFN0YXJ0VGltZTogdGltZSxcbiAgICB9O1xuICAgIGxldCBwcmV2T3duVGltZSA9IG9wZW5UaW1lc1tvcGVuVGltZXMubGVuZ3RoIC0gMV07XG4gICAgaWYgKHByZXZPd25UaW1lKSB7XG4gICAgICAgIHByZXZPd25UaW1lLm93blRpbWUgKz0gdGltZSAtIHByZXZPd25UaW1lLmxhc3RTdGFydFRpbWU7XG4gICAgfVxuICAgIG9wZW5UaW1lcy5wdXNoKG9iaik7XG5cbiAgICBmdW5jdGlvbiBmaW5pc2goKSB7XG4gICAgICAgIGxldCB0aW1lID0gbm93KCk7XG4gICAgICAgIG9iai50aW1lID0gdGltZSAtIG9iai5maXJzdFN0YXJ0VGltZTtcbiAgICAgICAgaWYgKG9iaiA9PT0gb3BlblRpbWVzW29wZW5UaW1lcy5sZW5ndGggLSAxXSkge1xuICAgICAgICAgICAgb2JqLm93blRpbWUgKz0gdGltZSAtIG9iai5sYXN0U3RhcnRUaW1lO1xuICAgICAgICAgICAgbGV0IG5ld093blRpbWUgPSBvcGVuVGltZXNbb3BlblRpbWVzLmxlbmd0aCAtIDJdO1xuICAgICAgICAgICAgaWYgKG5ld093blRpbWUpIHtcbiAgICAgICAgICAgICAgICBuZXdPd25UaW1lLmxhc3RTdGFydFRpbWUgPSB0aW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBpbmRleCA9IG9wZW5UaW1lcy5pbmRleE9mKG9iaik7XG4gICAgICAgIG9wZW5UaW1lcy5zcGxpY2UoaW5kZXgsIDEpO1xuXG4gICAgICAgIG9iai50aW1lICs9IGFkZE1lYXN1cmVPdmVyaGVhZFRpbWU7XG4gICAgICAgIG9iai5vd25UaW1lICs9IGFkZE1lYXN1cmVPdmVyaGVhZFRpbWU7XG5cbiAgICAgICAgb25UaW1lKG9iaik7XG4gICAgfVxuXG4gICAgbGV0IGlzQXN5bmMgPSBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gY29kZSgpO1xuICAgICAgICBpZiAocmVzdWx0ICYmIHR5cGVvZiByZXN1bHQgPT09IFwib2JqZWN0XCIgJiYgcmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgaXNBc3luYyA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0LmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGZpbmlzaCgpO1xuICAgICAgICAgICAgfSkgYXMgYW55O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaWYgKCFpc0FzeW5jKSB7XG4gICAgICAgICAgICBmaW5pc2goKTtcbiAgICAgICAgfVxuICAgIH1cbn0iXX0=
100
- /* _JS_SOURCE_HASH = "31fb9c8c80c18465404304159fbde1a41f8ffcf4f6370d5047d3ef0f84daa04d"; */
@@ -1,338 +0,0 @@
1
- "use strict"; var console = (function shimConsole() { let baseConsole = globalThis.console; if (typeof window !== "undefined") return baseConsole; let name = __filename.replaceAll("\\", "/").split("/").pop(); let dirName = __dirname.replaceAll("\\", "/").split("/").pop(); let context = { __FILE__: __filename, __DIR__: __dirname, __NAME__: name, __DIRNAME__: dirName }; let newConsole = { ...baseConsole }; for (let shim of ["log", "info", "warn", "error"]) { newConsole[shim] = (...args) => { args.push(context); baseConsole[shim](...args); }; } newConsole.__context = context; return newConsole; })(); "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
3
- //exports.addToMeasureProfile = exports.createMeasureProfile = exports.measureCodeSync = exports.measureCode = exports.logMeasureTable = exports.startMeasure = exports.registerMeasureInfo = exports.measureBlock = exports.measureWrap = exports.nameFunction = exports.measureFnc = exports.disableMeasurements = exports.enableMeasurements = void 0;
4
- const format_1 = require("../formatting/format");
5
- const logColors_1 = require("../formatting/logColors");
6
- const getOwnTime_1 = require("./getOwnTime");
7
- const stats_1 = require("./stats");
8
- const misc_1 = require("../misc");
9
- const statsFormat_1 = require("./statsFormat");
10
- const createSingleton_1 = require("../createSingleton");
11
- // Shared across every copy of this package loaded in the process, so enable/disableMeasurements
12
- // on any copy is honored by every copy's measureWrap, and so the skipped-function warning counts
13
- // across all copies. Held as a mutated-in-place object because the flags are reassigned. See
14
- // createSingleton.
15
- const measureState = (0, createSingleton_1.createSingleton)("measure.state", 1, () => ({
16
- measurementsEnabled: true,
17
- measurementsDisabled: false,
18
- functionsSkipped: 0,
19
- })).get();
20
- /** NOTE: Must be called BEFORE anything else is imported!
21
- * NOTE: Measurements on on by default now, so this doesn't really need to be called...
22
- */
23
- function enableMeasurements() {
24
- if (measureState.functionsSkipped) {
25
- console.warn((0, logColors_1.red)(`Skipped measure shimming ${measureState.functionsSkipped} functions. Fix this by calling enableMeasurements before any other imports.`));
26
- }
27
- measureState.measurementsEnabled = true;
28
- }
29
- exports.enableMeasurements = enableMeasurements;
30
- /** NOTE: Must be called BEFORE anything else is imported! */
31
- function disableMeasurements() {
32
- measureState.measurementsEnabled = false;
33
- measureState.measurementsDisabled = true;
34
- }
35
- exports.disableMeasurements = disableMeasurements;
36
- const measureOverhead = 5 / 1000;
37
- const AsyncFunction = (async () => { }).constructor;
38
- // NOTE: Also hardcoded in diskLogger.ts (in querysub)
39
- const noDiskLogPrefix = "█ ";
40
- // TIMING: 1-5us. I have seen timing values greatly vary, but it does seem to be quite high, despite
41
- // microbenchmarks saying it is slow. Perhaps it is because getOwnTime breaks the cpu pipeline,
42
- // which causes slowness for code around us, but not if we are running in isolation?
43
- // NOTE: Handles promises correctly
44
- function measureFnc(target, propertyKey, descriptor) {
45
- let name = propertyKey;
46
- if (target.name) {
47
- name = `${target.name}|${name}`;
48
- }
49
- else {
50
- let constructorName = target.constructor.name;
51
- if (constructorName) {
52
- name = `${constructorName}()|${name}`;
53
- }
54
- }
55
- if (descriptor.value instanceof AsyncFunction) {
56
- name += `(async)`;
57
- }
58
- descriptor.value = measureWrap(descriptor.value, name);
59
- }
60
- exports.measureFnc = measureFnc;
61
- // https://stackoverflow.com/questions/5905492/dynamic-function-name-in-javascript
62
- function nameFunction(name, fnc) {
63
- Object.defineProperty(fnc, "name", { value: name });
64
- return fnc;
65
- }
66
- exports.nameFunction = nameFunction;
67
- // NOTE: Handles promises correctly
68
- function measureWrap(fnc, name) {
69
- if (!measureState.measurementsEnabled) {
70
- measureState.functionsSkipped++;
71
- return fnc;
72
- }
73
- let usedName = name || fnc.name || fnc.toString().slice(0, 100).replaceAll(/\s/g, " ");
74
- let output = nameFunction(usedName, (function (...args) {
75
- if (outstandingProfiles.length === 0) {
76
- return fnc.apply(this, args);
77
- }
78
- return (0, getOwnTime_1.getOwnTime)(usedName, () => fnc.apply(this, args), recordOwnTime);
79
- }));
80
- output.originalFnc = fnc;
81
- return output;
82
- }
83
- exports.measureWrap = measureWrap;
84
- function measureBlock(fnc, name) {
85
- return measureWrap(fnc, name)();
86
- }
87
- exports.measureBlock = measureBlock;
88
- // Shared across copies so registerMeasureInfo on any copy is seen by logMeasureTable. See createSingleton.
89
- const extraInfoGetters = (0, createSingleton_1.createSingleton)("measure.extraInfoGetters", 1, () => []).get();
90
- /** NOTE: You should often call registerNodeMetadata for this as well. registerMeasureInfo
91
- * is for logs, while registerNodeMetadata is for the overview page.
92
- */
93
- function registerMeasureInfo(getInfo) {
94
- extraInfoGetters.push(getInfo);
95
- }
96
- exports.registerMeasureInfo = registerMeasureInfo;
97
- /** IMPORTANT! Always finish the profile! If you don't, you will leak A LOT of memory
98
- * (you leak all future measures, PER unfinished profile)!
99
- */
100
- function startMeasure() {
101
- if (!measureState.measurementsEnabled && !measureState.measurementsDisabled) {
102
- console.warn((0, logColors_1.red)(`To capture measurements enableMeasurements() must be called before any other imports in your entry point`));
103
- }
104
- let now = Date.now();
105
- let profile = {
106
- startTime: now,
107
- endTime: now,
108
- entries: Object.create(null),
109
- creator: new Error().stack || "",
110
- };
111
- let openAtStart = new Set((0, getOwnTime_1.getOpenTimesBase)());
112
- outstandingProfiles.push(profile);
113
- if (outstandingProfiles.length > 1000) {
114
- console.warn((0, logColors_1.red)(`You have ${outstandingProfiles.length} outstanding startMeasure calls. You are probably leaking them!`));
115
- }
116
- return {
117
- finish() {
118
- let pending = (0, getOwnTime_1.getOpenTimesBase)();
119
- let last = pending[pending.length - 1];
120
- let time = Date.now();
121
- for (let timeObj of pending) {
122
- // Ignore any values that were already open, as they are clearly not
123
- // caused by our code.
124
- if (openAtStart.has(timeObj))
125
- continue;
126
- timeObj = { ...timeObj };
127
- if (timeObj === last) {
128
- timeObj.ownTime += time - timeObj.lastStartTime;
129
- }
130
- timeObj.time = time - timeObj.firstStartTime;
131
- addToProfile(profile, timeObj);
132
- }
133
- outstandingProfiles.splice(outstandingProfiles.indexOf(profile), 1);
134
- profile.endTime = Date.now();
135
- return profile;
136
- }
137
- };
138
- }
139
- exports.startMeasure = startMeasure;
140
- function logMeasureTable(profile, config) {
141
- var _a, _b, _c, _d;
142
- let { useTotalTime, name } = config || {};
143
- const thresholdInTable = (_a = config === null || config === void 0 ? void 0 : config.thresholdInTable) !== null && _a !== void 0 ? _a : 0.02;
144
- let minTimeToLog = (_b = config === null || config === void 0 ? void 0 : config.minTimeToLog) !== null && _b !== void 0 ? _b : 20;
145
- const maxTableEntries = (_c = config === null || config === void 0 ? void 0 : config.maxTableEntries) !== null && _c !== void 0 ? _c : 10;
146
- function getTime(entry) {
147
- return useTotalTime ? entry.totalTime : entry.ownTime;
148
- }
149
- let entries = Object.values(profile.entries);
150
- entries.sort((a, b) => getTime(b).sum - getTime(a).sum);
151
- let totalTime = entries.map(x => getTime(x).sum).reduce((a, b) => a + b, 0);
152
- if (totalTime < minTimeToLog)
153
- return undefined;
154
- let mergeDepth = (_d = config === null || config === void 0 ? void 0 : config.mergeDepth) !== null && _d !== void 0 ? _d : 2;
155
- {
156
- let merged = new Map();
157
- for (let entry of entries) {
158
- let parts = entry.name.split("|");
159
- let key = parts.slice(0, mergeDepth).join("|");
160
- let existing = merged.get(key);
161
- if (!existing) {
162
- existing = { name: key, ownTime: (0, stats_1.createStatsValue)(), totalTime: (0, stats_1.createStatsValue)(), stillOpenCount: 0 };
163
- merged.set(key, existing);
164
- }
165
- (0, stats_1.addToStats)(existing.ownTime, entry.ownTime);
166
- (0, stats_1.addToStats)(existing.totalTime, entry.totalTime);
167
- existing.stillOpenCount += entry.stillOpenCount;
168
- }
169
- entries = Array.from(merged.values());
170
- entries.sort((a, b) => getTime(b).sum - getTime(a).sum);
171
- }
172
- let timeRunFor = profile.endTime - profile.startTime;
173
- let fraction = totalTime / timeRunFor;
174
- console.log();
175
- let extraInfos = extraInfoGetters.map(x => x());
176
- if ((config === null || config === void 0 ? void 0 : config.setTitle) && (0, misc_1.isNode)()) {
177
- let title = `${percent(fraction)} CPU`;
178
- title += extraInfos.map(x => x ? ` // ${x}` : "").join("");
179
- process.stdout.write(`\x1b]0;${title}\x07`);
180
- }
181
- let pid = (0, misc_1.isNode)() ? `(${process.pid}) ` : "";
182
- let title = (0, logColors_1.yellow)(`${pid}Profiled ${(0, format_1.formatTime)(totalTime)} (${percent(fraction)} CPU)${extraInfos.map(x => x ? ` (${x})` : "").filter(x => x).join(" |")} (logged at ${new Date().toISOString()}, profile for ${(0, format_1.formatTime)(timeRunFor)})`);
183
- if (name) {
184
- title = `(${(0, logColors_1.blue)(name)}) ${title}`;
185
- }
186
- console.log(noDiskLogPrefix + title);
187
- function percent(value) {
188
- return `${(value * 100).toFixed(2)}%`;
189
- }
190
- let remaining = entries.slice(maxTableEntries);
191
- entries = entries.slice(0, maxTableEntries);
192
- entries = entries.filter(entry => {
193
- const include = getTime(entry).sum / totalTime >= thresholdInTable;
194
- if (!include) {
195
- remaining.push(entry);
196
- }
197
- return include;
198
- });
199
- entries.push({
200
- name: "Other",
201
- ownTime: (0, stats_1.createStatsValue)(),
202
- totalTime: (0, stats_1.createStatsValue)(),
203
- stillOpenCount: 0,
204
- });
205
- let remainingEntry = entries[entries.length - 1];
206
- for (let entry of remaining) {
207
- (0, stats_1.addToStats)(remainingEntry.ownTime, entry.ownTime);
208
- (0, stats_1.addToStats)(remainingEntry.totalTime, entry.totalTime);
209
- remainingEntry.stillOpenCount += entry.stillOpenCount;
210
- }
211
- let maxNameLength = Math.max(...entries.map(x => x.name.length));
212
- for (let entry of entries) {
213
- let output = "";
214
- output += `${(0, logColors_1.blue)(entry.name)}`;
215
- output += Array(maxNameLength + 4 - entry.name.length).fill(" ").join("");
216
- function p(count, text) {
217
- return String(text).padStart(count, " ");
218
- }
219
- let fractionText = percent(getTime(entry).sum / totalTime);
220
- let equation = (0, statsFormat_1.formatStats)(getTime(entry));
221
- let text = `${p(6, fractionText)} ( ${equation} )`;
222
- let overhead = measureOverhead * getTime(entry).count;
223
- let overheadFraction = overhead / getTime(entry).sum;
224
- let overheadIsAProblem = overheadFraction > 0.5;
225
- if (overheadIsAProblem) {
226
- text = (0, logColors_1.yellow)(text);
227
- }
228
- output += text;
229
- if (overheadIsAProblem) {
230
- output += (0, logColors_1.red)(` measurement overhead is ~${percent(overheadFraction)} of the time.`);
231
- }
232
- if (entry.stillOpenCount > 0) {
233
- output += (0, logColors_1.red)(` (${entry.stillOpenCount} open)`);
234
- }
235
- console.log(noDiskLogPrefix + output);
236
- }
237
- console.log();
238
- return {
239
- title,
240
- entries: entries.map(entry => {
241
- let time = getTime(entry);
242
- let fraction = time.sum / totalTime;
243
- return {
244
- name: entry.name,
245
- ownTime: time.sum,
246
- fraction,
247
- equation: (0, statsFormat_1.formatStats)(time),
248
- };
249
- })
250
- };
251
- }
252
- exports.logMeasureTable = logMeasureTable;
253
- async function measureCode(code, config) {
254
- let measure = startMeasure();
255
- try {
256
- return await measureBlock(code, code.name || "untracked");
257
- }
258
- finally {
259
- finishProfile(measure, config || { name: code.name, minTimeToLog: 0 });
260
- }
261
- }
262
- exports.measureCode = measureCode;
263
- function measureCodeSync(code, config) {
264
- let measure = startMeasure();
265
- try {
266
- return measureBlock(code, code.name || "untracked");
267
- }
268
- finally {
269
- finishProfile(measure, config);
270
- }
271
- }
272
- exports.measureCodeSync = measureCodeSync;
273
- function finishProfile(measure, config) {
274
- let profile = measure.finish();
275
- logMeasureTable(profile, config);
276
- }
277
- function createMeasureProfile() {
278
- let now = Date.now();
279
- return {
280
- startTime: now,
281
- endTime: now,
282
- entries: Object.create(null),
283
- creator: new Error().stack || "",
284
- };
285
- }
286
- exports.createMeasureProfile = createMeasureProfile;
287
- function addToMeasureProfile(base, other) {
288
- for (let name in other.entries) {
289
- let entry = other.entries[name];
290
- let baseEntry = base.entries[name];
291
- if (!baseEntry) {
292
- baseEntry = {
293
- name: name,
294
- ownTime: (0, stats_1.createStatsValue)(),
295
- totalTime: (0, stats_1.createStatsValue)(),
296
- stillOpenCount: 0,
297
- };
298
- base.entries[name] = baseEntry;
299
- }
300
- (0, stats_1.addToStats)(baseEntry.ownTime, entry.ownTime);
301
- (0, stats_1.addToStats)(baseEntry.totalTime, entry.totalTime);
302
- baseEntry.stillOpenCount += entry.stillOpenCount;
303
- }
304
- }
305
- exports.addToMeasureProfile = addToMeasureProfile;
306
- // Shared across copies so a profile started through one copy captures measureWrap'd functions from
307
- // every other copy - otherwise a profile would only ever see functions wrapped by its own copy.
308
- // See createSingleton.
309
- const outstandingProfiles = (0, createSingleton_1.createSingleton)("measure.outstandingProfiles", 1, () => []).get();
310
- globalThis.outstandingProfiles = outstandingProfiles;
311
- function recordOwnTime(ownTimeObj) {
312
- if (outstandingProfiles.length === 0)
313
- return;
314
- for (let i = 0; i < outstandingProfiles.length; i++) {
315
- let profile = outstandingProfiles[i];
316
- addToProfile(profile, ownTimeObj);
317
- }
318
- }
319
- function addToProfile(profile, ownTimeObj, stillOpen) {
320
- let name = ownTimeObj.name;
321
- let entry = profile.entries[name];
322
- if (!entry) {
323
- entry = {
324
- name: name,
325
- ownTime: (0, stats_1.createStatsValue)(),
326
- totalTime: (0, stats_1.createStatsValue)(),
327
- stillOpenCount: 0,
328
- };
329
- profile.entries[name] = entry;
330
- }
331
- (0, stats_1.addToStatsValue)(entry.ownTime, ownTimeObj.ownTime);
332
- (0, stats_1.addToStatsValue)(entry.totalTime, ownTimeObj.time);
333
- if (stillOpen) {
334
- entry.stillOpenCount++;
335
- }
336
- }
337
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVhc3VyZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1lYXN1cmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsaURBQWdFO0FBQ2hFLHVEQUFxRTtBQUVyRSw2Q0FBd0U7QUFDeEUsbUNBQWlHO0FBRWpHLGtDQUFpQztBQUNqQywrQ0FBcUQ7QUFDckQsd0RBQXFEO0FBRXJELGdHQUFnRztBQUNoRyxrR0FBa0c7QUFDbEcsOEZBQThGO0FBQzlGLG9CQUFvQjtBQUNwQixNQUFNLFlBQVksR0FBRyxJQUFBLGlDQUFlLEVBQUMsZUFBZSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQzVELG1CQUFtQixFQUFFLElBQUk7SUFDekIsb0JBQW9CLEVBQUUsS0FBSztJQUMzQixnQkFBZ0IsRUFBRSxDQUFDO0NBQ3RCLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ1Y7O0VBRUU7QUFDRixTQUFnQixrQkFBa0I7SUFDOUIsSUFBSSxZQUFZLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUNoQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUEsZUFBRyxFQUFDLDRCQUE0QixZQUFZLENBQUMsZ0JBQWdCLDhFQUE4RSxDQUFDLENBQUMsQ0FBQztJQUMvSixDQUFDO0lBQ0QsWUFBWSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQztBQUM1QyxDQUFDO0FBTEQsZ0RBS0M7QUFDRCw2REFBNkQ7QUFDN0QsU0FBZ0IsbUJBQW1CO0lBQy9CLFlBQVksQ0FBQyxtQkFBbUIsR0FBRyxLQUFLLENBQUM7SUFDekMsWUFBWSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQztBQUM3QyxDQUFDO0FBSEQsa0RBR0M7QUFFRCxNQUFNLGVBQWUsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBRWpDLE1BQU0sYUFBYSxHQUFHLENBQUMsS0FBSyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUM7QUFFcEQsc0RBQXNEO0FBQ3RELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQztBQUU3QixvR0FBb0c7QUFDcEcsZ0dBQWdHO0FBQ2hHLHFGQUFxRjtBQUNyRixtQ0FBbUM7QUFDbkMsU0FBZ0IsVUFBVSxDQUFDLE1BQVcsRUFBRSxXQUFtQixFQUFFLFVBQThCO0lBQ3ZGLElBQUksSUFBSSxHQUFHLFdBQVcsQ0FBQztJQUN2QixJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNkLElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxJQUFJLElBQUksSUFBSSxFQUFFLENBQUM7SUFDcEMsQ0FBQztTQUFNLENBQUM7UUFDSixJQUFJLGVBQWUsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztRQUM5QyxJQUFJLGVBQWUsRUFBRSxDQUFDO1lBQ2xCLElBQUksR0FBRyxHQUFHLGVBQWUsTUFBTSxJQUFJLEVBQUUsQ0FBQztRQUMxQyxDQUFDO0lBQ0wsQ0FBQztJQUNELElBQUksVUFBVSxDQUFDLEtBQUssWUFBWSxhQUFhLEVBQUUsQ0FBQztRQUM1QyxJQUFJLElBQUksU0FBUyxDQUFDO0lBQ3RCLENBQUM7SUFDRCxVQUFVLENBQUMsS0FBSyxHQUFHLFdBQVcsQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQzNELENBQUM7QUFkRCxnQ0FjQztBQUVELGtGQUFrRjtBQUNsRixTQUFnQixZQUFZLENBQXFCLElBQVksRUFBRSxHQUFNO0lBQ2pFLE1BQU0sQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3BELE9BQU8sR0FBRyxDQUFDO0FBQ2YsQ0FBQztBQUhELG9DQUdDO0FBQ0QsbUNBQW1DO0FBQ25DLFNBQWdCLFdBQVcsQ0FBb0MsR0FBTSxFQUFFLElBQWE7SUFDaEYsSUFBSSxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQ3BDLFlBQVksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ2hDLE9BQU8sR0FBRyxDQUFDO0lBQ2YsQ0FBQztJQUNELElBQUksUUFBUSxHQUFHLElBQUksSUFBSSxHQUFHLENBQUMsSUFBSSxJQUFJLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDdkYsSUFBSSxNQUFNLEdBQUcsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDLFVBQXFCLEdBQUcsSUFBZTtRQUN4RSxJQUFJLG1CQUFtQixDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNuQyxPQUFPLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2pDLENBQUM7UUFDRCxPQUFPLElBQUEsdUJBQVUsRUFBQyxRQUFRLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDNUUsQ0FBQyxDQUFDLENBQU0sQ0FBQztJQUNSLE1BQWMsQ0FBQyxXQUFXLEdBQUcsR0FBRyxDQUFDO0lBQ2xDLE9BQU8sTUFBTSxDQUFDO0FBQ2xCLENBQUM7QUFkRCxrQ0FjQztBQUNELFNBQWdCLFlBQVksQ0FBb0MsR0FBTSxFQUFFLElBQWE7SUFDakYsT0FBTyxXQUFXLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUM7QUFDcEMsQ0FBQztBQUZELG9DQUVDO0FBRUQsMkdBQTJHO0FBQzNHLE1BQU0sZ0JBQWdCLEdBQUcsSUFBQSxpQ0FBZSxFQUFDLDBCQUEwQixFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFrQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDeEg7O0dBRUc7QUFDSCxTQUFnQixtQkFBbUIsQ0FBQyxPQUFpQztJQUNqRSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDbkMsQ0FBQztBQUZELGtEQUVDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixZQUFZO0lBR3hCLElBQUksQ0FBQyxZQUFZLENBQUMsbUJBQW1CLElBQUksQ0FBQyxZQUFZLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUMxRSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUEsZUFBRyxFQUFDLDBHQUEwRyxDQUFDLENBQUMsQ0FBQztJQUNsSSxDQUFDO0lBQ0QsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ3JCLElBQUksT0FBTyxHQUFtQjtRQUMxQixTQUFTLEVBQUUsR0FBRztRQUNkLE9BQU8sRUFBRSxHQUFHO1FBQ1osT0FBTyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO1FBQzVCLE9BQU8sRUFBRSxJQUFJLEtBQUssRUFBRSxDQUFDLEtBQUssSUFBSSxFQUFFO0tBQ25DLENBQUM7SUFDRixJQUFJLFdBQVcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFBLDZCQUFnQixHQUFFLENBQUMsQ0FBQztJQUU5QyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbEMsSUFBSSxtQkFBbUIsQ0FBQyxNQUFNLEdBQUcsSUFBSSxFQUFFLENBQUM7UUFDcEMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFBLGVBQUcsRUFBQyxZQUFZLG1CQUFtQixDQUFDLE1BQU0saUVBQWlFLENBQUMsQ0FBQyxDQUFDO0lBQy9ILENBQUM7SUFDRCxPQUFPO1FBQ0gsTUFBTTtZQUNGLElBQUksT0FBTyxHQUFHLElBQUEsNkJBQWdCLEdBQUUsQ0FBQztZQUNqQyxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN2QyxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDdEIsS0FBSyxJQUFJLE9BQU8sSUFBSSxPQUFPLEVBQUUsQ0FBQztnQkFDMUIsb0VBQW9FO2dCQUNwRSx1QkFBdUI7Z0JBQ3ZCLElBQUksV0FBVyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUM7b0JBQUUsU0FBUztnQkFDdkMsT0FBTyxHQUFHLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQztnQkFFekIsSUFBSSxPQUFPLEtBQUssSUFBSSxFQUFFLENBQUM7b0JBQ25CLE9BQU8sQ0FBQyxPQUFPLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUM7Z0JBQ3BELENBQUM7Z0JBQ0QsT0FBTyxDQUFDLElBQUksR0FBRyxJQUFJLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQztnQkFDN0MsWUFBWSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNuQyxDQUFDO1lBQ0QsbUJBQW1CLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNwRSxPQUFPLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUM3QixPQUFPLE9BQU8sQ0FBQztRQUNuQixDQUFDO0tBQ0osQ0FBQztBQUNOLENBQUM7QUF6Q0Qsb0NBeUNDO0FBNkJELFNBQWdCLGVBQWUsQ0FDM0IsT0FBdUIsRUFDdkIsTUFBOEI7O0lBRTlCLElBQUksRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLEdBQUcsTUFBTSxJQUFJLEVBQUUsQ0FBQztJQUMxQyxNQUFNLGdCQUFnQixHQUFHLE1BQUEsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLGdCQUFnQixtQ0FBSSxJQUFJLENBQUM7SUFDMUQsSUFBSSxZQUFZLEdBQUcsTUFBQSxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsWUFBWSxtQ0FBSSxFQUFFLENBQUM7SUFDOUMsTUFBTSxlQUFlLEdBQUcsTUFBQSxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsZUFBZSxtQ0FBSSxFQUFFLENBQUM7SUFFdEQsU0FBUyxPQUFPLENBQUMsS0FBbUI7UUFDaEMsT0FBTyxZQUFZLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7SUFDMUQsQ0FBQztJQUNELElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzdDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUV4RCxJQUFJLFNBQVMsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDNUUsSUFBSSxTQUFTLEdBQUcsWUFBWTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBRS9DLElBQUksVUFBVSxHQUFHLE1BQUEsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLFVBQVUsbUNBQUksQ0FBQyxDQUFDO0lBQ3pDLENBQUM7UUFDRyxJQUFJLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBd0IsQ0FBQztRQUM3QyxLQUFLLElBQUksS0FBSyxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ3hCLElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2xDLElBQUksR0FBRyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMvQyxJQUFJLFFBQVEsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDWixRQUFRLEdBQUcsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxJQUFBLHdCQUFnQixHQUFFLEVBQUUsU0FBUyxFQUFFLElBQUEsd0JBQWdCLEdBQUUsRUFBRSxjQUFjLEVBQUUsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hHLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzlCLENBQUM7WUFDRCxJQUFBLGtCQUFVLEVBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDNUMsSUFBQSxrQkFBVSxFQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ2hELFFBQVEsQ0FBQyxjQUFjLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQztRQUNwRCxDQUFDO1FBQ0QsT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRCxJQUFJLFVBQVUsR0FBRyxPQUFPLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUM7SUFDckQsSUFBSSxRQUFRLEdBQUcsU0FBUyxHQUFHLFVBQVUsQ0FBQztJQUV0QyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDZCxJQUFJLFVBQVUsR0FBRyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRWhELElBQUksQ0FBQSxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsUUFBUSxLQUFJLElBQUEsYUFBTSxHQUFFLEVBQUUsQ0FBQztRQUMvQixJQUFJLEtBQUssR0FBRyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO1FBQ3ZDLEtBQUssSUFBSSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDM0QsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxLQUFLLE1BQU0sQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFDRCxJQUFJLEdBQUcsR0FBRyxJQUFBLGFBQU0sR0FBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQzlDLElBQUksS0FBSyxHQUFHLElBQUEsa0JBQU0sRUFBQyxHQUFHLEdBQUcsWUFBWSxJQUFBLG1CQUFVLEVBQUMsU0FBUyxDQUFDLEtBQUssT0FBTyxDQUFDLFFBQVEsQ0FBQyxRQUFRLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxpQkFBaUIsSUFBQSxtQkFBVSxFQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM1TyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ1AsS0FBSyxHQUFHLElBQUksSUFBQSxnQkFBSSxFQUFDLElBQUksQ0FBQyxLQUFLLEtBQUssRUFBRSxDQUFDO0lBQ3ZDLENBQUM7SUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUMsQ0FBQztJQUNyQyxTQUFTLE9BQU8sQ0FBQyxLQUFhO1FBQzFCLE9BQU8sR0FBRyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUMxQyxDQUFDO0lBRUQsSUFBSSxTQUFTLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUMvQyxPQUFPLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFDNUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFDN0IsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsR0FBRyxTQUFTLElBQUksZ0JBQWdCLENBQUM7UUFDbkUsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ1gsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQixDQUFDO1FBQ0QsT0FBTyxPQUFPLENBQUM7SUFDbkIsQ0FBQyxDQUFDLENBQUM7SUFDSCxPQUFPLENBQUMsSUFBSSxDQUFDO1FBQ1QsSUFBSSxFQUFFLE9BQU87UUFDYixPQUFPLEVBQUUsSUFBQSx3QkFBZ0IsR0FBRTtRQUMzQixTQUFTLEVBQUUsSUFBQSx3QkFBZ0IsR0FBRTtRQUM3QixjQUFjLEVBQUUsQ0FBQztLQUNwQixDQUFDLENBQUM7SUFDSCxJQUFJLGNBQWMsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNqRCxLQUFLLElBQUksS0FBSyxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQzFCLElBQUEsa0JBQVUsRUFBQyxjQUFjLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNsRCxJQUFBLGtCQUFVLEVBQUMsY0FBYyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDdEQsY0FBYyxDQUFDLGNBQWMsSUFBSSxLQUFLLENBQUMsY0FBYyxDQUFDO0lBQzFELENBQUM7SUFDRCxJQUFJLGFBQWEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUVqRSxLQUFLLElBQUksS0FBSyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQ3hCLElBQUksTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUNoQixNQUFNLElBQUksR0FBRyxJQUFBLGdCQUFJLEVBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDaEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxhQUFhLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUUxRSxTQUFTLENBQUMsQ0FBQyxLQUFhLEVBQUUsSUFBcUI7WUFDM0MsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztRQUM3QyxDQUFDO1FBQ0QsSUFBSSxZQUFZLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEdBQUcsU0FBUyxDQUFDLENBQUM7UUFFM0QsSUFBSSxRQUFRLEdBQUcsSUFBQSx5QkFBVyxFQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBRTNDLElBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsTUFBTSxRQUFRLElBQUksQ0FBQztRQUNuRCxJQUFJLFFBQVEsR0FBRyxlQUFlLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUN0RCxJQUFJLGdCQUFnQixHQUFHLFFBQVEsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ3JELElBQUksa0JBQWtCLEdBQUcsZ0JBQWdCLEdBQUcsR0FBRyxDQUFDO1FBQ2hELElBQUksa0JBQWtCLEVBQUUsQ0FBQztZQUNyQixJQUFJLEdBQUcsSUFBQSxrQkFBTSxFQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hCLENBQUM7UUFFRCxNQUFNLElBQUksSUFBSSxDQUFDO1FBRWYsSUFBSSxrQkFBa0IsRUFBRSxDQUFDO1lBQ3JCLE1BQU0sSUFBSSxJQUFBLGVBQUcsRUFBQyxnQ0FBZ0MsT0FBTyxDQUFDLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzVGLENBQUM7UUFFRCxJQUFJLEtBQUssQ0FBQyxjQUFjLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDM0IsTUFBTSxJQUFJLElBQUEsZUFBRyxFQUFDLFFBQVEsS0FBSyxDQUFDLGNBQWMsUUFBUSxDQUFDLENBQUM7UUFDeEQsQ0FBQztRQUVELE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxHQUFHLE1BQU0sQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFDRCxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7SUFFZCxPQUFPO1FBQ0gsS0FBSztRQUNMLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ3pCLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMxQixJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHLFNBQVMsQ0FBQztZQUNwQyxPQUFPO2dCQUNILElBQUksRUFBRSxLQUFLLENBQUMsSUFBSTtnQkFDaEIsT0FBTyxFQUFFLElBQUksQ0FBQyxHQUFHO2dCQUNqQixRQUFRO2dCQUNSLFFBQVEsRUFBRSxJQUFBLHlCQUFXLEVBQUMsSUFBSSxDQUFDO2FBQzlCLENBQUM7UUFDTixDQUFDLENBQUM7S0FDTCxDQUFDO0FBQ04sQ0FBQztBQWhJRCwwQ0FnSUM7QUFFTSxLQUFLLFVBQVUsV0FBVyxDQUFJLElBQXNCLEVBQUUsTUFBOEI7SUFDdkYsSUFBSSxPQUFPLEdBQUcsWUFBWSxFQUFFLENBQUM7SUFDN0IsSUFBSSxDQUFDO1FBQ0QsT0FBTyxNQUFNLFlBQVksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxXQUFXLENBQUMsQ0FBQztJQUM5RCxDQUFDO1lBQVMsQ0FBQztRQUNQLGFBQWEsQ0FBQyxPQUFPLEVBQUUsTUFBTSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDM0UsQ0FBQztBQUNMLENBQUM7QUFQRCxrQ0FPQztBQUNELFNBQWdCLGVBQWUsQ0FBSSxJQUFhLEVBQUUsTUFBOEI7SUFDNUUsSUFBSSxPQUFPLEdBQUcsWUFBWSxFQUFFLENBQUM7SUFDN0IsSUFBSSxDQUFDO1FBQ0QsT0FBTyxZQUFZLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLElBQUksV0FBVyxDQUFDLENBQUM7SUFDeEQsQ0FBQztZQUFTLENBQUM7UUFDUCxhQUFhLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ25DLENBQUM7QUFDTCxDQUFDO0FBUEQsMENBT0M7QUFDRCxTQUFTLGFBQWEsQ0FBQyxPQUFxQyxFQUFFLE1BQThCO0lBQ3hGLElBQUksT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUMvQixlQUFlLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3JDLENBQUM7QUFXRCxTQUFnQixvQkFBb0I7SUFDaEMsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ3JCLE9BQU87UUFDSCxTQUFTLEVBQUUsR0FBRztRQUNkLE9BQU8sRUFBRSxHQUFHO1FBQ1osT0FBTyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO1FBQzVCLE9BQU8sRUFBRSxJQUFJLEtBQUssRUFBRSxDQUFDLEtBQUssSUFBSSxFQUFFO0tBQ25DLENBQUM7QUFDTixDQUFDO0FBUkQsb0RBUUM7QUFFRCxTQUFnQixtQkFBbUIsQ0FBQyxJQUFvQixFQUFFLEtBQXFCO0lBQzNFLEtBQUssSUFBSSxJQUFJLElBQUksS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzdCLElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEMsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDYixTQUFTLEdBQUc7Z0JBQ1IsSUFBSSxFQUFFLElBQUk7Z0JBQ1YsT0FBTyxFQUFFLElBQUEsd0JBQWdCLEdBQUU7Z0JBQzNCLFNBQVMsRUFBRSxJQUFBLHdCQUFnQixHQUFFO2dCQUM3QixjQUFjLEVBQUUsQ0FBQzthQUNwQixDQUFDO1lBQ0YsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxTQUFTLENBQUM7UUFDbkMsQ0FBQztRQUNELElBQUEsa0JBQVUsRUFBQyxTQUFTLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM3QyxJQUFBLGtCQUFVLEVBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakQsU0FBUyxDQUFDLGNBQWMsSUFBSSxLQUFLLENBQUMsY0FBYyxDQUFDO0lBQ3JELENBQUM7QUFDTCxDQUFDO0FBakJELGtEQWlCQztBQVNELG1HQUFtRztBQUNuRyxpR0FBaUc7QUFDakcsd0JBQXdCO0FBQ3hCLE1BQU0sbUJBQW1CLEdBQUcsSUFBQSxpQ0FBZSxFQUFDLDZCQUE2QixFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFzQixDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDakgsVUFBa0IsQ0FBQyxtQkFBbUIsR0FBRyxtQkFBbUIsQ0FBQztBQUM5RCxTQUFTLGFBQWEsQ0FBQyxVQUFzQjtJQUN6QyxJQUFJLG1CQUFtQixDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTztJQUM3QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsbUJBQW1CLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDbEQsSUFBSSxPQUFPLEdBQUcsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckMsWUFBWSxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztJQUN0QyxDQUFDO0FBQ0wsQ0FBQztBQUdELFNBQVMsWUFBWSxDQUFDLE9BQXVCLEVBQUUsVUFBc0IsRUFBRSxTQUFtQjtJQUN0RixJQUFJLElBQUksR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDO0lBQzNCLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbEMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1QsS0FBSyxHQUFHO1lBQ0osSUFBSSxFQUFFLElBQUk7WUFDVixPQUFPLEVBQUUsSUFBQSx3QkFBZ0IsR0FBRTtZQUMzQixTQUFTLEVBQUUsSUFBQSx3QkFBZ0IsR0FBRTtZQUM3QixjQUFjLEVBQUUsQ0FBQztTQUNwQixDQUFDO1FBQ0YsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUM7SUFDbEMsQ0FBQztJQUNELElBQUEsdUJBQWUsRUFBQyxLQUFLLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuRCxJQUFBLHVCQUFlLEVBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbEQsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUNaLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUMzQixDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBkZWJ1Z2JyZWFrIGZyb20gXCJkZWJ1Z2JyZWFrXCI7XG5pbXBvcnQgeyBmb3JtYXRUaW1lLCBmb3JtYXROdW1iZXIgfSBmcm9tIFwiLi4vZm9ybWF0dGluZy9mb3JtYXRcIjtcbmltcG9ydCB7IHJlZCwgeWVsbG93LCBibHVlLCBtYWdlbnRhIH0gZnJvbSBcIi4uL2Zvcm1hdHRpbmcvbG9nQ29sb3JzXCI7XG5cbmltcG9ydCB7IGdldE9wZW5UaW1lc0Jhc2UsIGdldE93blRpbWUsIE93blRpbWVPYmogfSBmcm9tIFwiLi9nZXRPd25UaW1lXCI7XG5pbXBvcnQgeyBhZGRUb1N0YXRzLCBhZGRUb1N0YXRzVmFsdWUsIGNyZWF0ZVN0YXRzVmFsdWUsIGdldFN0YXRzVG9wLCBTdGF0c1ZhbHVlIH0gZnJvbSBcIi4vc3RhdHNcIjtcbmltcG9ydCB7IHdoaXRlIH0gZnJvbSBcIi4uL2Zvcm1hdHRpbmcvbG9nQ29sb3JzXCI7XG5pbXBvcnQgeyBpc05vZGUgfSBmcm9tIFwiLi4vbWlzY1wiO1xuaW1wb3J0IHsgZm9ybWF0U3RhdHMsIHBlcmNlbnQgfSBmcm9tIFwiLi9zdGF0c0Zvcm1hdFwiO1xuaW1wb3J0IHsgY3JlYXRlU2luZ2xldG9uIH0gZnJvbSBcIi4uL2NyZWF0ZVNpbmdsZXRvblwiO1xuXG4vLyBTaGFyZWQgYWNyb3NzIGV2ZXJ5IGNvcHkgb2YgdGhpcyBwYWNrYWdlIGxvYWRlZCBpbiB0aGUgcHJvY2Vzcywgc28gZW5hYmxlL2Rpc2FibGVNZWFzdXJlbWVudHNcbi8vICBvbiBhbnkgY29weSBpcyBob25vcmVkIGJ5IGV2ZXJ5IGNvcHkncyBtZWFzdXJlV3JhcCwgYW5kIHNvIHRoZSBza2lwcGVkLWZ1bmN0aW9uIHdhcm5pbmcgY291bnRzXG4vLyAgYWNyb3NzIGFsbCBjb3BpZXMuIEhlbGQgYXMgYSBtdXRhdGVkLWluLXBsYWNlIG9iamVjdCBiZWNhdXNlIHRoZSBmbGFncyBhcmUgcmVhc3NpZ25lZC4gU2VlXG4vLyAgY3JlYXRlU2luZ2xldG9uLlxuY29uc3QgbWVhc3VyZVN0YXRlID0gY3JlYXRlU2luZ2xldG9uKFwibWVhc3VyZS5zdGF0ZVwiLCAxLCAoKSA9PiAoe1xuICAgIG1lYXN1cmVtZW50c0VuYWJsZWQ6IHRydWUsXG4gICAgbWVhc3VyZW1lbnRzRGlzYWJsZWQ6IGZhbHNlLFxuICAgIGZ1bmN0aW9uc1NraXBwZWQ6IDAsXG59KSkuZ2V0KCk7XG4vKiogTk9URTogTXVzdCBiZSBjYWxsZWQgQkVGT1JFIGFueXRoaW5nIGVsc2UgaXMgaW1wb3J0ZWQhXG4gKiAgICAgIE5PVEU6IE1lYXN1cmVtZW50cyBvbiBvbiBieSBkZWZhdWx0IG5vdywgc28gdGhpcyBkb2Vzbid0IHJlYWxseSBuZWVkIHRvIGJlIGNhbGxlZC4uLlxuKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmFibGVNZWFzdXJlbWVudHMoKSB7XG4gICAgaWYgKG1lYXN1cmVTdGF0ZS5mdW5jdGlvbnNTa2lwcGVkKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihyZWQoYFNraXBwZWQgbWVhc3VyZSBzaGltbWluZyAke21lYXN1cmVTdGF0ZS5mdW5jdGlvbnNTa2lwcGVkfSBmdW5jdGlvbnMuIEZpeCB0aGlzIGJ5IGNhbGxpbmcgZW5hYmxlTWVhc3VyZW1lbnRzIGJlZm9yZSBhbnkgb3RoZXIgaW1wb3J0cy5gKSk7XG4gICAgfVxuICAgIG1lYXN1cmVTdGF0ZS5tZWFzdXJlbWVudHNFbmFibGVkID0gdHJ1ZTtcbn1cbi8qKiBOT1RFOiBNdXN0IGJlIGNhbGxlZCBCRUZPUkUgYW55dGhpbmcgZWxzZSBpcyBpbXBvcnRlZCEgKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXNhYmxlTWVhc3VyZW1lbnRzKCkge1xuICAgIG1lYXN1cmVTdGF0ZS5tZWFzdXJlbWVudHNFbmFibGVkID0gZmFsc2U7XG4gICAgbWVhc3VyZVN0YXRlLm1lYXN1cmVtZW50c0Rpc2FibGVkID0gdHJ1ZTtcbn1cblxuY29uc3QgbWVhc3VyZU92ZXJoZWFkID0gNSAvIDEwMDA7XG5cbmNvbnN0IEFzeW5jRnVuY3Rpb24gPSAoYXN5bmMgKCkgPT4geyB9KS5jb25zdHJ1Y3RvcjtcblxuLy8gTk9URTogQWxzbyBoYXJkY29kZWQgaW4gZGlza0xvZ2dlci50cyAoaW4gcXVlcnlzdWIpXG5jb25zdCBub0Rpc2tMb2dQcmVmaXggPSBcIuKWiCBcIjtcblxuLy8gVElNSU5HOiAxLTV1cy4gSSBoYXZlIHNlZW4gdGltaW5nIHZhbHVlcyBncmVhdGx5IHZhcnksIGJ1dCBpdCBkb2VzIHNlZW0gdG8gYmUgcXVpdGUgaGlnaCwgZGVzcGl0ZVxuLy8gIG1pY3JvYmVuY2htYXJrcyBzYXlpbmcgaXQgaXMgc2xvdy4gUGVyaGFwcyBpdCBpcyBiZWNhdXNlIGdldE93blRpbWUgYnJlYWtzIHRoZSBjcHUgcGlwZWxpbmUsXG4vLyAgd2hpY2ggY2F1c2VzIHNsb3duZXNzIGZvciBjb2RlIGFyb3VuZCB1cywgYnV0IG5vdCBpZiB3ZSBhcmUgcnVubmluZyBpbiBpc29sYXRpb24/XG4vLyBOT1RFOiBIYW5kbGVzIHByb21pc2VzIGNvcnJlY3RseVxuZXhwb3J0IGZ1bmN0aW9uIG1lYXN1cmVGbmModGFyZ2V0OiBhbnksIHByb3BlcnR5S2V5OiBzdHJpbmcsIGRlc2NyaXB0b3I6IFByb3BlcnR5RGVzY3JpcHRvcikge1xuICAgIGxldCBuYW1lID0gcHJvcGVydHlLZXk7XG4gICAgaWYgKHRhcmdldC5uYW1lKSB7XG4gICAgICAgIG5hbWUgPSBgJHt0YXJnZXQubmFtZX18JHtuYW1lfWA7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IGNvbnN0cnVjdG9yTmFtZSA9IHRhcmdldC5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICBpZiAoY29uc3RydWN0b3JOYW1lKSB7XG4gICAgICAgICAgICBuYW1lID0gYCR7Y29uc3RydWN0b3JOYW1lfSgpfCR7bmFtZX1gO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChkZXNjcmlwdG9yLnZhbHVlIGluc3RhbmNlb2YgQXN5bmNGdW5jdGlvbikge1xuICAgICAgICBuYW1lICs9IGAoYXN5bmMpYDtcbiAgICB9XG4gICAgZGVzY3JpcHRvci52YWx1ZSA9IG1lYXN1cmVXcmFwKGRlc2NyaXB0b3IudmFsdWUsIG5hbWUpO1xufVxuXG4vLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy81OTA1NDkyL2R5bmFtaWMtZnVuY3Rpb24tbmFtZS1pbi1qYXZhc2NyaXB0XG5leHBvcnQgZnVuY3Rpb24gbmFtZUZ1bmN0aW9uPFQgZXh0ZW5kcyBGdW5jdGlvbj4obmFtZTogc3RyaW5nLCBmbmM6IFQpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZm5jLCBcIm5hbWVcIiwgeyB2YWx1ZTogbmFtZSB9KTtcbiAgICByZXR1cm4gZm5jO1xufVxuLy8gTk9URTogSGFuZGxlcyBwcm9taXNlcyBjb3JyZWN0bHlcbmV4cG9ydCBmdW5jdGlvbiBtZWFzdXJlV3JhcDxUIGV4dGVuZHMgKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnk+KGZuYzogVCwgbmFtZT86IHN0cmluZyk6IFQge1xuICAgIGlmICghbWVhc3VyZVN0YXRlLm1lYXN1cmVtZW50c0VuYWJsZWQpIHtcbiAgICAgICAgbWVhc3VyZVN0YXRlLmZ1bmN0aW9uc1NraXBwZWQrKztcbiAgICAgICAgcmV0dXJuIGZuYztcbiAgICB9XG4gICAgbGV0IHVzZWROYW1lID0gbmFtZSB8fCBmbmMubmFtZSB8fCBmbmMudG9TdHJpbmcoKS5zbGljZSgwLCAxMDApLnJlcGxhY2VBbGwoL1xccy9nLCBcIiBcIik7XG4gICAgbGV0IG91dHB1dCA9IG5hbWVGdW5jdGlvbih1c2VkTmFtZSwgKGZ1bmN0aW9uICh0aGlzOiBhbnksIC4uLmFyZ3M6IHVua25vd25bXSk6IHVua25vd24ge1xuICAgICAgICBpZiAob3V0c3RhbmRpbmdQcm9maWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmbmMuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGdldE93blRpbWUodXNlZE5hbWUsICgpID0+IGZuYy5hcHBseSh0aGlzLCBhcmdzKSwgcmVjb3JkT3duVGltZSk7XG4gICAgfSkpIGFzIFQ7XG4gICAgKG91dHB1dCBhcyBhbnkpLm9yaWdpbmFsRm5jID0gZm5jO1xuICAgIHJldHVybiBvdXRwdXQ7XG59XG5leHBvcnQgZnVuY3Rpb24gbWVhc3VyZUJsb2NrPFQgZXh0ZW5kcyAoLi4uYXJnczogYW55W10pID0+IGFueT4oZm5jOiBULCBuYW1lPzogc3RyaW5nKTogUmV0dXJuVHlwZTxUPiB7XG4gICAgcmV0dXJuIG1lYXN1cmVXcmFwKGZuYywgbmFtZSkoKTtcbn1cblxuLy8gU2hhcmVkIGFjcm9zcyBjb3BpZXMgc28gcmVnaXN0ZXJNZWFzdXJlSW5mbyBvbiBhbnkgY29weSBpcyBzZWVuIGJ5IGxvZ01lYXN1cmVUYWJsZS4gU2VlIGNyZWF0ZVNpbmdsZXRvbi5cbmNvbnN0IGV4dHJhSW5mb0dldHRlcnMgPSBjcmVhdGVTaW5nbGV0b24oXCJtZWFzdXJlLmV4dHJhSW5mb0dldHRlcnNcIiwgMSwgKCkgPT4gW10gYXMgKCgpID0+IHN0cmluZyB8IHVuZGVmaW5lZClbXSkuZ2V0KCk7XG4vKiogTk9URTogWW91IHNob3VsZCBvZnRlbiBjYWxsIHJlZ2lzdGVyTm9kZU1ldGFkYXRhIGZvciB0aGlzIGFzIHdlbGwuIHJlZ2lzdGVyTWVhc3VyZUluZm9cbiAqICAgICAgaXMgZm9yIGxvZ3MsIHdoaWxlIHJlZ2lzdGVyTm9kZU1ldGFkYXRhIGlzIGZvciB0aGUgb3ZlcnZpZXcgcGFnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyTWVhc3VyZUluZm8oZ2V0SW5mbzogKCkgPT4gc3RyaW5nIHwgdW5kZWZpbmVkKSB7XG4gICAgZXh0cmFJbmZvR2V0dGVycy5wdXNoKGdldEluZm8pO1xufVxuXG4vKiogSU1QT1JUQU5UISBBbHdheXMgZmluaXNoIHRoZSBwcm9maWxlISBJZiB5b3UgZG9uJ3QsIHlvdSB3aWxsIGxlYWsgQSBMT1Qgb2YgbWVtb3J5XG4gKiAgICAgICh5b3UgbGVhayBhbGwgZnV0dXJlIG1lYXN1cmVzLCBQRVIgdW5maW5pc2hlZCBwcm9maWxlKSFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0TWVhc3VyZSgpOiB7XG4gICAgZmluaXNoOiAoKSA9PiBNZWFzdXJlUHJvZmlsZTtcbn0ge1xuICAgIGlmICghbWVhc3VyZVN0YXRlLm1lYXN1cmVtZW50c0VuYWJsZWQgJiYgIW1lYXN1cmVTdGF0ZS5tZWFzdXJlbWVudHNEaXNhYmxlZCkge1xuICAgICAgICBjb25zb2xlLndhcm4ocmVkKGBUbyBjYXB0dXJlIG1lYXN1cmVtZW50cyBlbmFibGVNZWFzdXJlbWVudHMoKSBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgYW55IG90aGVyIGltcG9ydHMgaW4geW91ciBlbnRyeSBwb2ludGApKTtcbiAgICB9XG4gICAgbGV0IG5vdyA9IERhdGUubm93KCk7XG4gICAgbGV0IHByb2ZpbGU6IE1lYXN1cmVQcm9maWxlID0ge1xuICAgICAgICBzdGFydFRpbWU6IG5vdyxcbiAgICAgICAgZW5kVGltZTogbm93LFxuICAgICAgICBlbnRyaWVzOiBPYmplY3QuY3JlYXRlKG51bGwpLFxuICAgICAgICBjcmVhdG9yOiBuZXcgRXJyb3IoKS5zdGFjayB8fCBcIlwiLFxuICAgIH07XG4gICAgbGV0IG9wZW5BdFN0YXJ0ID0gbmV3IFNldChnZXRPcGVuVGltZXNCYXNlKCkpO1xuXG4gICAgb3V0c3RhbmRpbmdQcm9maWxlcy5wdXNoKHByb2ZpbGUpO1xuICAgIGlmIChvdXRzdGFuZGluZ1Byb2ZpbGVzLmxlbmd0aCA+IDEwMDApIHtcbiAgICAgICAgY29uc29sZS53YXJuKHJlZChgWW91IGhhdmUgJHtvdXRzdGFuZGluZ1Byb2ZpbGVzLmxlbmd0aH0gb3V0c3RhbmRpbmcgc3RhcnRNZWFzdXJlIGNhbGxzLiBZb3UgYXJlIHByb2JhYmx5IGxlYWtpbmcgdGhlbSFgKSk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIGZpbmlzaCgpIHtcbiAgICAgICAgICAgIGxldCBwZW5kaW5nID0gZ2V0T3BlblRpbWVzQmFzZSgpO1xuICAgICAgICAgICAgbGV0IGxhc3QgPSBwZW5kaW5nW3BlbmRpbmcubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICBsZXQgdGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICBmb3IgKGxldCB0aW1lT2JqIG9mIHBlbmRpbmcpIHtcbiAgICAgICAgICAgICAgICAvLyBJZ25vcmUgYW55IHZhbHVlcyB0aGF0IHdlcmUgYWxyZWFkeSBvcGVuLCBhcyB0aGV5IGFyZSBjbGVhcmx5IG5vdFxuICAgICAgICAgICAgICAgIC8vICBjYXVzZWQgYnkgb3VyIGNvZGUuXG4gICAgICAgICAgICAgICAgaWYgKG9wZW5BdFN0YXJ0Lmhhcyh0aW1lT2JqKSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgdGltZU9iaiA9IHsgLi4udGltZU9iaiB9O1xuXG4gICAgICAgICAgICAgICAgaWYgKHRpbWVPYmogPT09IGxhc3QpIHtcbiAgICAgICAgICAgICAgICAgICAgdGltZU9iai5vd25UaW1lICs9IHRpbWUgLSB0aW1lT2JqLmxhc3RTdGFydFRpbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRpbWVPYmoudGltZSA9IHRpbWUgLSB0aW1lT2JqLmZpcnN0U3RhcnRUaW1lO1xuICAgICAgICAgICAgICAgIGFkZFRvUHJvZmlsZShwcm9maWxlLCB0aW1lT2JqKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG91dHN0YW5kaW5nUHJvZmlsZXMuc3BsaWNlKG91dHN0YW5kaW5nUHJvZmlsZXMuaW5kZXhPZihwcm9maWxlKSwgMSk7XG4gICAgICAgICAgICBwcm9maWxlLmVuZFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgcmV0dXJuIHByb2ZpbGU7XG4gICAgICAgIH1cbiAgICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExvZ01lYXN1cmVUYWJsZUNvbmZpZyB7XG4gICAgdXNlVG90YWxUaW1lPzogYm9vbGVhbjtcbiAgICBuYW1lPzogc3RyaW5nO1xuICAgIHNldFRpdGxlPzogYm9vbGVhbjtcbiAgICAvLyBEZWZhdWx0cyB0byAwLjA1XG4gICAgdGhyZXNob2xkSW5UYWJsZT86IG51bWJlcjtcbiAgICAvLyBEZXRhaWxzIHRvIDUwXG4gICAgbWluVGltZVRvTG9nPzogbnVtYmVyO1xuICAgIC8vIERlZmF1bHRzIHRvIDJcbiAgICBtZXJnZURlcHRoPzogbnVtYmVyO1xuICAgIC8vIERlZmF1bHRzIHRvIDEwXG4gICAgbWF4VGFibGVFbnRyaWVzPzogbnVtYmVyO1xuXG4gICAgLy8gTm8gbG9nZ2luZywganVzdCByZXR1cm5zIEZvcm1hdHRlZE1lYXN1cmVUYWJsZVxuICAgIHJldHVybk9ubHk/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZvcm1hdHRlZE1lYXN1cmVUYWJsZSB7XG4gICAgdGl0bGU6IHN0cmluZztcbiAgICBlbnRyaWVzOiB7XG4gICAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgICAgb3duVGltZTogbnVtYmVyO1xuICAgICAgICBmcmFjdGlvbjogbnVtYmVyO1xuICAgICAgICBlcXVhdGlvbjogc3RyaW5nO1xuICAgIH1bXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxvZ01lYXN1cmVUYWJsZShcbiAgICBwcm9maWxlOiBNZWFzdXJlUHJvZmlsZSxcbiAgICBjb25maWc/OiBMb2dNZWFzdXJlVGFibGVDb25maWdcbik6IEZvcm1hdHRlZE1lYXN1cmVUYWJsZSB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IHsgdXNlVG90YWxUaW1lLCBuYW1lIH0gPSBjb25maWcgfHwge307XG4gICAgY29uc3QgdGhyZXNob2xkSW5UYWJsZSA9IGNvbmZpZz8udGhyZXNob2xkSW5UYWJsZSA/PyAwLjAyO1xuICAgIGxldCBtaW5UaW1lVG9Mb2cgPSBjb25maWc/Lm1pblRpbWVUb0xvZyA/PyAyMDtcbiAgICBjb25zdCBtYXhUYWJsZUVudHJpZXMgPSBjb25maWc/Lm1heFRhYmxlRW50cmllcyA/PyAxMDtcblxuICAgIGZ1bmN0aW9uIGdldFRpbWUoZW50cnk6IFByb2ZpbGVFbnRyeSkge1xuICAgICAgICByZXR1cm4gdXNlVG90YWxUaW1lID8gZW50cnkudG90YWxUaW1lIDogZW50cnkub3duVGltZTtcbiAgICB9XG4gICAgbGV0IGVudHJpZXMgPSBPYmplY3QudmFsdWVzKHByb2ZpbGUuZW50cmllcyk7XG4gICAgZW50cmllcy5zb3J0KChhLCBiKSA9PiBnZXRUaW1lKGIpLnN1bSAtIGdldFRpbWUoYSkuc3VtKTtcblxuICAgIGxldCB0b3RhbFRpbWUgPSBlbnRyaWVzLm1hcCh4ID0+IGdldFRpbWUoeCkuc3VtKS5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiLCAwKTtcbiAgICBpZiAodG90YWxUaW1lIDwgbWluVGltZVRvTG9nKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgbGV0IG1lcmdlRGVwdGggPSBjb25maWc/Lm1lcmdlRGVwdGggPz8gMjtcbiAgICB7XG4gICAgICAgIGxldCBtZXJnZWQgPSBuZXcgTWFwPHN0cmluZywgUHJvZmlsZUVudHJ5PigpO1xuICAgICAgICBmb3IgKGxldCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICAgICAgICBsZXQgcGFydHMgPSBlbnRyeS5uYW1lLnNwbGl0KFwifFwiKTtcbiAgICAgICAgICAgIGxldCBrZXkgPSBwYXJ0cy5zbGljZSgwLCBtZXJnZURlcHRoKS5qb2luKFwifFwiKTtcbiAgICAgICAgICAgIGxldCBleGlzdGluZyA9IG1lcmdlZC5nZXQoa2V5KTtcbiAgICAgICAgICAgIGlmICghZXhpc3RpbmcpIHtcbiAgICAgICAgICAgICAgICBleGlzdGluZyA9IHsgbmFtZToga2V5LCBvd25UaW1lOiBjcmVhdGVTdGF0c1ZhbHVlKCksIHRvdGFsVGltZTogY3JlYXRlU3RhdHNWYWx1ZSgpLCBzdGlsbE9wZW5Db3VudDogMCB9O1xuICAgICAgICAgICAgICAgIG1lcmdlZC5zZXQoa2V5LCBleGlzdGluZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhZGRUb1N0YXRzKGV4aXN0aW5nLm93blRpbWUsIGVudHJ5Lm93blRpbWUpO1xuICAgICAgICAgICAgYWRkVG9TdGF0cyhleGlzdGluZy50b3RhbFRpbWUsIGVudHJ5LnRvdGFsVGltZSk7XG4gICAgICAgICAgICBleGlzdGluZy5zdGlsbE9wZW5Db3VudCArPSBlbnRyeS5zdGlsbE9wZW5Db3VudDtcbiAgICAgICAgfVxuICAgICAgICBlbnRyaWVzID0gQXJyYXkuZnJvbShtZXJnZWQudmFsdWVzKCkpO1xuICAgICAgICBlbnRyaWVzLnNvcnQoKGEsIGIpID0+IGdldFRpbWUoYikuc3VtIC0gZ2V0VGltZShhKS5zdW0pO1xuICAgIH1cblxuICAgIGxldCB0aW1lUnVuRm9yID0gcHJvZmlsZS5lbmRUaW1lIC0gcHJvZmlsZS5zdGFydFRpbWU7XG4gICAgbGV0IGZyYWN0aW9uID0gdG90YWxUaW1lIC8gdGltZVJ1bkZvcjtcblxuICAgIGNvbnNvbGUubG9nKCk7XG4gICAgbGV0IGV4dHJhSW5mb3MgPSBleHRyYUluZm9HZXR0ZXJzLm1hcCh4ID0+IHgoKSk7XG5cbiAgICBpZiAoY29uZmlnPy5zZXRUaXRsZSAmJiBpc05vZGUoKSkge1xuICAgICAgICBsZXQgdGl0bGUgPSBgJHtwZXJjZW50KGZyYWN0aW9uKX0gQ1BVYDtcbiAgICAgICAgdGl0bGUgKz0gZXh0cmFJbmZvcy5tYXAoeCA9PiB4ID8gYCAvLyAke3h9YCA6IFwiXCIpLmpvaW4oXCJcIik7XG4gICAgICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGBcXHgxYl0wOyR7dGl0bGV9XFx4MDdgKTtcbiAgICB9XG4gICAgbGV0IHBpZCA9IGlzTm9kZSgpID8gYCgke3Byb2Nlc3MucGlkfSkgYCA6IFwiXCI7XG4gICAgbGV0IHRpdGxlID0geWVsbG93KGAke3BpZH1Qcm9maWxlZCAke2Zvcm1hdFRpbWUodG90YWxUaW1lKX0gKCR7cGVyY2VudChmcmFjdGlvbil9IENQVSkke2V4dHJhSW5mb3MubWFwKHggPT4geCA/IGAgKCR7eH0pYCA6IFwiXCIpLmZpbHRlcih4ID0+IHgpLmpvaW4oXCIgfFwiKX0gKGxvZ2dlZCBhdCAke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKX0sIHByb2ZpbGUgZm9yICR7Zm9ybWF0VGltZSh0aW1lUnVuRm9yKX0pYCk7XG4gICAgaWYgKG5hbWUpIHtcbiAgICAgICAgdGl0bGUgPSBgKCR7Ymx1ZShuYW1lKX0pICR7dGl0bGV9YDtcbiAgICB9XG4gICAgY29uc29sZS5sb2cobm9EaXNrTG9nUHJlZml4ICsgdGl0bGUpO1xuICAgIGZ1bmN0aW9uIHBlcmNlbnQodmFsdWU6IG51bWJlcikge1xuICAgICAgICByZXR1cm4gYCR7KHZhbHVlICogMTAwKS50b0ZpeGVkKDIpfSVgO1xuICAgIH1cblxuICAgIGxldCByZW1haW5pbmcgPSBlbnRyaWVzLnNsaWNlKG1heFRhYmxlRW50cmllcyk7XG4gICAgZW50cmllcyA9IGVudHJpZXMuc2xpY2UoMCwgbWF4VGFibGVFbnRyaWVzKTtcbiAgICBlbnRyaWVzID0gZW50cmllcy5maWx0ZXIoZW50cnkgPT4ge1xuICAgICAgICBjb25zdCBpbmNsdWRlID0gZ2V0VGltZShlbnRyeSkuc3VtIC8gdG90YWxUaW1lID49IHRocmVzaG9sZEluVGFibGU7XG4gICAgICAgIGlmICghaW5jbHVkZSkge1xuICAgICAgICAgICAgcmVtYWluaW5nLnB1c2goZW50cnkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbmNsdWRlO1xuICAgIH0pO1xuICAgIGVudHJpZXMucHVzaCh7XG4gICAgICAgIG5hbWU6IFwiT3RoZXJcIixcbiAgICAgICAgb3duVGltZTogY3JlYXRlU3RhdHNWYWx1ZSgpLFxuICAgICAgICB0b3RhbFRpbWU6IGNyZWF0ZVN0YXRzVmFsdWUoKSxcbiAgICAgICAgc3RpbGxPcGVuQ291bnQ6IDAsXG4gICAgfSk7XG4gICAgbGV0IHJlbWFpbmluZ0VudHJ5ID0gZW50cmllc1tlbnRyaWVzLmxlbmd0aCAtIDFdO1xuICAgIGZvciAobGV0IGVudHJ5IG9mIHJlbWFpbmluZykge1xuICAgICAgICBhZGRUb1N0YXRzKHJlbWFpbmluZ0VudHJ5Lm93blRpbWUsIGVudHJ5Lm93blRpbWUpO1xuICAgICAgICBhZGRUb1N0YXRzKHJlbWFpbmluZ0VudHJ5LnRvdGFsVGltZSwgZW50cnkudG90YWxUaW1lKTtcbiAgICAgICAgcmVtYWluaW5nRW50cnkuc3RpbGxPcGVuQ291bnQgKz0gZW50cnkuc3RpbGxPcGVuQ291bnQ7XG4gICAgfVxuICAgIGxldCBtYXhOYW1lTGVuZ3RoID0gTWF0aC5tYXgoLi4uZW50cmllcy5tYXAoeCA9PiB4Lm5hbWUubGVuZ3RoKSk7XG5cbiAgICBmb3IgKGxldCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICAgIGxldCBvdXRwdXQgPSBcIlwiO1xuICAgICAgICBvdXRwdXQgKz0gYCR7Ymx1ZShlbnRyeS5uYW1lKX1gO1xuICAgICAgICBvdXRwdXQgKz0gQXJyYXkobWF4TmFtZUxlbmd0aCArIDQgLSBlbnRyeS5uYW1lLmxlbmd0aCkuZmlsbChcIiBcIikuam9pbihcIlwiKTtcblxuICAgICAgICBmdW5jdGlvbiBwKGNvdW50OiBudW1iZXIsIHRleHQ6IHN0cmluZyB8IG51bWJlcikge1xuICAgICAgICAgICAgcmV0dXJuIFN0cmluZyh0ZXh0KS5wYWRTdGFydChjb3VudCwgXCIgXCIpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBmcmFjdGlvblRleHQgPSBwZXJjZW50KGdldFRpbWUoZW50cnkpLnN1bSAvIHRvdGFsVGltZSk7XG5cbiAgICAgICAgbGV0IGVxdWF0aW9uID0gZm9ybWF0U3RhdHMoZ2V0VGltZShlbnRyeSkpO1xuXG4gICAgICAgIGxldCB0ZXh0ID0gYCR7cCg2LCBmcmFjdGlvblRleHQpfSAoICR7ZXF1YXRpb259IClgO1xuICAgICAgICBsZXQgb3ZlcmhlYWQgPSBtZWFzdXJlT3ZlcmhlYWQgKiBnZXRUaW1lKGVudHJ5KS5jb3VudDtcbiAgICAgICAgbGV0IG92ZXJoZWFkRnJhY3Rpb24gPSBvdmVyaGVhZCAvIGdldFRpbWUoZW50cnkpLnN1bTtcbiAgICAgICAgbGV0IG92ZXJoZWFkSXNBUHJvYmxlbSA9IG92ZXJoZWFkRnJhY3Rpb24gPiAwLjU7XG4gICAgICAgIGlmIChvdmVyaGVhZElzQVByb2JsZW0pIHtcbiAgICAgICAgICAgIHRleHQgPSB5ZWxsb3codGV4dCk7XG4gICAgICAgIH1cblxuICAgICAgICBvdXRwdXQgKz0gdGV4dDtcblxuICAgICAgICBpZiAob3ZlcmhlYWRJc0FQcm9ibGVtKSB7XG4gICAgICAgICAgICBvdXRwdXQgKz0gcmVkKGAgICAgbWVhc3VyZW1lbnQgb3ZlcmhlYWQgaXMgfiR7cGVyY2VudChvdmVyaGVhZEZyYWN0aW9uKX0gb2YgdGhlIHRpbWUuYCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW50cnkuc3RpbGxPcGVuQ291bnQgPiAwKSB7XG4gICAgICAgICAgICBvdXRwdXQgKz0gcmVkKGAgICAgKCR7ZW50cnkuc3RpbGxPcGVuQ291bnR9IG9wZW4pYCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmxvZyhub0Rpc2tMb2dQcmVmaXggKyBvdXRwdXQpO1xuICAgIH1cbiAgICBjb25zb2xlLmxvZygpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgdGl0bGUsXG4gICAgICAgIGVudHJpZXM6IGVudHJpZXMubWFwKGVudHJ5ID0+IHtcbiAgICAgICAgICAgIGxldCB0aW1lID0gZ2V0VGltZShlbnRyeSk7XG4gICAgICAgICAgICBsZXQgZnJhY3Rpb24gPSB0aW1lLnN1bSAvIHRvdGFsVGltZTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgbmFtZTogZW50cnkubmFtZSxcbiAgICAgICAgICAgICAgICBvd25UaW1lOiB0aW1lLnN1bSxcbiAgICAgICAgICAgICAgICBmcmFjdGlvbixcbiAgICAgICAgICAgICAgICBlcXVhdGlvbjogZm9ybWF0U3RhdHModGltZSksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KVxuICAgIH07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBtZWFzdXJlQ29kZTxUPihjb2RlOiAoKSA9PiBQcm9taXNlPFQ+LCBjb25maWc/OiBMb2dNZWFzdXJlVGFibGVDb25maWcpIHtcbiAgICBsZXQgbWVhc3VyZSA9IHN0YXJ0TWVhc3VyZSgpO1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBtZWFzdXJlQmxvY2soY29kZSwgY29kZS5uYW1lIHx8IFwidW50cmFja2VkXCIpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGZpbmlzaFByb2ZpbGUobWVhc3VyZSwgY29uZmlnIHx8IHsgbmFtZTogY29kZS5uYW1lLCBtaW5UaW1lVG9Mb2c6IDAgfSk7XG4gICAgfVxufVxuZXhwb3J0IGZ1bmN0aW9uIG1lYXN1cmVDb2RlU3luYzxUPihjb2RlOiAoKSA9PiBULCBjb25maWc/OiBMb2dNZWFzdXJlVGFibGVDb25maWcpOiBUIHtcbiAgICBsZXQgbWVhc3VyZSA9IHN0YXJ0TWVhc3VyZSgpO1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBtZWFzdXJlQmxvY2soY29kZSwgY29kZS5uYW1lIHx8IFwidW50cmFja2VkXCIpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGZpbmlzaFByb2ZpbGUobWVhc3VyZSwgY29uZmlnKTtcbiAgICB9XG59XG5mdW5jdGlvbiBmaW5pc2hQcm9maWxlKG1lYXN1cmU6IHsgZmluaXNoKCk6IE1lYXN1cmVQcm9maWxlIH0sIGNvbmZpZz86IExvZ01lYXN1cmVUYWJsZUNvbmZpZykge1xuICAgIGxldCBwcm9maWxlID0gbWVhc3VyZS5maW5pc2goKTtcbiAgICBsb2dNZWFzdXJlVGFibGUocHJvZmlsZSwgY29uZmlnKTtcbn1cblxuXG5leHBvcnQgaW50ZXJmYWNlIE1lYXN1cmVQcm9maWxlIHtcbiAgICBzdGFydFRpbWU6IG51bWJlcjtcbiAgICBlbmRUaW1lOiBudW1iZXI7XG4gICAgZW50cmllczoge1xuICAgICAgICBbbmFtZTogc3RyaW5nXTogUHJvZmlsZUVudHJ5O1xuICAgIH07XG4gICAgY3JlYXRvcjogc3RyaW5nO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1lYXN1cmVQcm9maWxlKCk6IE1lYXN1cmVQcm9maWxlIHtcbiAgICBsZXQgbm93ID0gRGF0ZS5ub3coKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBzdGFydFRpbWU6IG5vdyxcbiAgICAgICAgZW5kVGltZTogbm93LFxuICAgICAgICBlbnRyaWVzOiBPYmplY3QuY3JlYXRlKG51bGwpLFxuICAgICAgICBjcmVhdG9yOiBuZXcgRXJyb3IoKS5zdGFjayB8fCBcIlwiLFxuICAgIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRUb01lYXN1cmVQcm9maWxlKGJhc2U6IE1lYXN1cmVQcm9maWxlLCBvdGhlcjogTWVhc3VyZVByb2ZpbGUpIHtcbiAgICBmb3IgKGxldCBuYW1lIGluIG90aGVyLmVudHJpZXMpIHtcbiAgICAgICAgbGV0IGVudHJ5ID0gb3RoZXIuZW50cmllc1tuYW1lXTtcbiAgICAgICAgbGV0IGJhc2VFbnRyeSA9IGJhc2UuZW50cmllc1tuYW1lXTtcbiAgICAgICAgaWYgKCFiYXNlRW50cnkpIHtcbiAgICAgICAgICAgIGJhc2VFbnRyeSA9IHtcbiAgICAgICAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgICAgICAgIG93blRpbWU6IGNyZWF0ZVN0YXRzVmFsdWUoKSxcbiAgICAgICAgICAgICAgICB0b3RhbFRpbWU6IGNyZWF0ZVN0YXRzVmFsdWUoKSxcbiAgICAgICAgICAgICAgICBzdGlsbE9wZW5Db3VudDogMCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBiYXNlLmVudHJpZXNbbmFtZV0gPSBiYXNlRW50cnk7XG4gICAgICAgIH1cbiAgICAgICAgYWRkVG9TdGF0cyhiYXNlRW50cnkub3duVGltZSwgZW50cnkub3duVGltZSk7XG4gICAgICAgIGFkZFRvU3RhdHMoYmFzZUVudHJ5LnRvdGFsVGltZSwgZW50cnkudG90YWxUaW1lKTtcbiAgICAgICAgYmFzZUVudHJ5LnN0aWxsT3BlbkNvdW50ICs9IGVudHJ5LnN0aWxsT3BlbkNvdW50O1xuICAgIH1cbn1cblxuaW50ZXJmYWNlIFByb2ZpbGVFbnRyeSB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIG93blRpbWU6IFN0YXRzVmFsdWU7XG4gICAgdG90YWxUaW1lOiBTdGF0c1ZhbHVlO1xuICAgIHN0aWxsT3BlbkNvdW50OiBudW1iZXI7XG59XG5cbi8vIFNoYXJlZCBhY3Jvc3MgY29waWVzIHNvIGEgcHJvZmlsZSBzdGFydGVkIHRocm91Z2ggb25lIGNvcHkgY2FwdHVyZXMgbWVhc3VyZVdyYXAnZCBmdW5jdGlvbnMgZnJvbVxuLy8gIGV2ZXJ5IG90aGVyIGNvcHkgLSBvdGhlcndpc2UgYSBwcm9maWxlIHdvdWxkIG9ubHkgZXZlciBzZWUgZnVuY3Rpb25zIHdyYXBwZWQgYnkgaXRzIG93biBjb3B5LlxuLy8gIFNlZSBjcmVhdGVTaW5nbGV0b24uXG5jb25zdCBvdXRzdGFuZGluZ1Byb2ZpbGVzID0gY3JlYXRlU2luZ2xldG9uKFwibWVhc3VyZS5vdXRzdGFuZGluZ1Byb2ZpbGVzXCIsIDEsICgpID0+IFtdIGFzIE1lYXN1cmVQcm9maWxlW10pLmdldCgpO1xuKGdsb2JhbFRoaXMgYXMgYW55KS5vdXRzdGFuZGluZ1Byb2ZpbGVzID0gb3V0c3RhbmRpbmdQcm9maWxlcztcbmZ1bmN0aW9uIHJlY29yZE93blRpbWUob3duVGltZU9iajogT3duVGltZU9iaikge1xuICAgIGlmIChvdXRzdGFuZGluZ1Byb2ZpbGVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0c3RhbmRpbmdQcm9maWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgcHJvZmlsZSA9IG91dHN0YW5kaW5nUHJvZmlsZXNbaV07XG4gICAgICAgIGFkZFRvUHJvZmlsZShwcm9maWxlLCBvd25UaW1lT2JqKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gYWRkVG9Qcm9maWxlKHByb2ZpbGU6IE1lYXN1cmVQcm9maWxlLCBvd25UaW1lT2JqOiBPd25UaW1lT2JqLCBzdGlsbE9wZW4/OiBib29sZWFuKSB7XG4gICAgbGV0IG5hbWUgPSBvd25UaW1lT2JqLm5hbWU7XG4gICAgbGV0IGVudHJ5ID0gcHJvZmlsZS5lbnRyaWVzW25hbWVdO1xuICAgIGlmICghZW50cnkpIHtcbiAgICAgICAgZW50cnkgPSB7XG4gICAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgICAgb3duVGltZTogY3JlYXRlU3RhdHNWYWx1ZSgpLFxuICAgICAgICAgICAgdG90YWxUaW1lOiBjcmVhdGVTdGF0c1ZhbHVlKCksXG4gICAgICAgICAgICBzdGlsbE9wZW5Db3VudDogMCxcbiAgICAgICAgfTtcbiAgICAgICAgcHJvZmlsZS5lbnRyaWVzW25hbWVdID0gZW50cnk7XG4gICAgfVxuICAgIGFkZFRvU3RhdHNWYWx1ZShlbnRyeS5vd25UaW1lLCBvd25UaW1lT2JqLm93blRpbWUpO1xuICAgIGFkZFRvU3RhdHNWYWx1ZShlbnRyeS50b3RhbFRpbWUsIG93blRpbWVPYmoudGltZSk7XG4gICAgaWYgKHN0aWxsT3Blbikge1xuICAgICAgICBlbnRyeS5zdGlsbE9wZW5Db3VudCsrO1xuICAgIH1cbn0iXX0=
338
- /* _JS_SOURCE_HASH = "04519135586427254303562b9fb7098c4df1167003b034ecece33ace1e3f0d11"; */