obsidian-integration-testing 9.1.1 → 9.2.0

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 (43) hide show
  1. package/README.md +106 -13
  2. package/dist/lib/cjs/connect-to-cdp.cjs +23 -2
  3. package/dist/lib/cjs/global-setup-core.cjs +28 -1
  4. package/dist/lib/cjs/index.cjs +12 -1
  5. package/dist/lib/cjs/index.d.cts +5 -0
  6. package/dist/lib/cjs/leftover-cleanup.cjs +116 -0
  7. package/dist/lib/cjs/leftover-cleanup.d.cts +163 -0
  8. package/dist/lib/cjs/library.cjs +1 -1
  9. package/dist/lib/cjs/obsidian-metadata.cjs +15 -1
  10. package/dist/lib/cjs/run-version-matrix.cjs +64 -0
  11. package/dist/lib/cjs/run-version-matrix.d.cts +49 -0
  12. package/dist/lib/cjs/setup-lock.cjs +145 -32
  13. package/dist/lib/cjs/setup-lock.d.cts +9 -3
  14. package/dist/lib/cjs/temp-vault.cjs +3 -2
  15. package/dist/lib/cjs/transport-appium.cjs +86 -30
  16. package/dist/lib/cjs/transport-appium.d.cts +43 -3
  17. package/dist/lib/cjs/transport-factory.cjs +52 -4
  18. package/dist/lib/cjs/transport-options.cjs +1 -1
  19. package/dist/lib/cjs/transport-options.d.cts +57 -0
  20. package/dist/lib/cjs/version-matrix.cjs +175 -0
  21. package/dist/lib/cjs/version-matrix.d.cts +224 -0
  22. package/dist/lib/esm/connect-to-cdp.mjs +27 -2
  23. package/dist/lib/esm/global-setup-core.mjs +36 -2
  24. package/dist/lib/esm/index.d.mts +5 -0
  25. package/dist/lib/esm/index.mjs +11 -1
  26. package/dist/lib/esm/leftover-cleanup.d.mts +163 -0
  27. package/dist/lib/esm/leftover-cleanup.mjs +88 -0
  28. package/dist/lib/esm/library.mjs +1 -1
  29. package/dist/lib/esm/obsidian-metadata.mjs +15 -1
  30. package/dist/lib/esm/run-version-matrix.d.mts +49 -0
  31. package/dist/lib/esm/run-version-matrix.mjs +48 -0
  32. package/dist/lib/esm/setup-lock.d.mts +9 -3
  33. package/dist/lib/esm/setup-lock.mjs +145 -32
  34. package/dist/lib/esm/temp-vault.mjs +3 -2
  35. package/dist/lib/esm/transport-appium.d.mts +43 -3
  36. package/dist/lib/esm/transport-appium.mjs +84 -29
  37. package/dist/lib/esm/transport-factory.mjs +62 -5
  38. package/dist/lib/esm/transport-options.d.mts +57 -0
  39. package/dist/lib/esm/version-matrix.d.mts +224 -0
  40. package/dist/lib/esm/version-matrix.mjs +147 -0
  41. package/dist/obsidian-integration-testing-9.2.0.tgz +0 -0
  42. package/package.json +18 -25
  43. package/dist/obsidian-integration-testing-9.1.1.tgz +0 -0
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var run_version_matrix_exports = {};
20
+ __export(run_version_matrix_exports, {
21
+ runObsidianVersionMatrix: () => runObsidianVersionMatrix
22
+ });
23
+ module.exports = __toCommonJS(run_version_matrix_exports);
24
+ var import_log = require("./log.cjs");
25
+ var import_obsidian_version_switch = require("./obsidian-version-switch.cjs");
26
+ var import_version_matrix = require("./version-matrix.cjs");
27
+ async function runObsidianVersionMatrix(params) {
28
+ const { run, versions } = params;
29
+ const { isDefault, specs } = (0, import_version_matrix.resolveRequestedSpecs)(versions);
30
+ const manifest = (0, import_version_matrix.hasChannelSpec)(specs) ? await (0, import_obsidian_version_switch.fetchDesktopReleasesManifest)() : void 0;
31
+ const { droppedSpecs, resolvedSpecs } = (0, import_version_matrix.resolveVersionSpecs)({
32
+ manifest,
33
+ // The default list must not break every consumer's gate when a channel is
34
+ // Momentarily absent from the manifest; an explicitly requested specifier
35
+ // That cannot resolve is a real error.
36
+ shouldTolerateUnresolvableSpecs: isDefault,
37
+ specs
38
+ });
39
+ for (const { reason, spec } of droppedSpecs) {
40
+ logMatrix(`Skipping "${spec}": ${reason}`);
41
+ }
42
+ const entries = (0, import_version_matrix.buildVersionMatrix)(resolvedSpecs);
43
+ logPlan(resolvedSpecs, entries);
44
+ await (0, import_version_matrix.runVersionMatrixEntries)({
45
+ entries,
46
+ onEntryStart: (headerParams) => {
47
+ logMatrix((0, import_version_matrix.formatVersionMatrixRunHeader)(headerParams));
48
+ },
49
+ run
50
+ });
51
+ }
52
+ function logMatrix(message) {
53
+ (0, import_log.log)(`[version-matrix] ${message}`);
54
+ }
55
+ function logPlan(resolvedSpecs, entries) {
56
+ for (const line of (0, import_version_matrix.formatVersionMatrixPlan)({ entries, resolvedSpecs })) {
57
+ logMatrix(line);
58
+ }
59
+ }
60
+ // Annotate the CommonJS export names for ESM import in node:
61
+ 0 && (module.exports = {
62
+ runObsidianVersionMatrix
63
+ });
64
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3J1bi12ZXJzaW9uLW1hdHJpeC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIEludGVncmF0aW9uLXRpbWUgcnVubmVyIHRoYXQgZXhlY3V0ZXMgYSBzdWl0ZSBvbmNlIHBlciAqKmRpc3RpbmN0Kiogc3VwcG9ydGVkXG4gKiBPYnNpZGlhbiB2ZXJzaW9uLlxuICpcbiAqIFRoaW4gZ2x1ZSBvdmVyIHRoZSBwdXJlIGB2ZXJzaW9uLW1hdHJpeC50c2AgZGVjaXNpb24gbGF5ZXI6IHRoZSBvbmx5IHRoaW5nc1xuICogdGhhdCBoYXBwZW4gaGVyZSBhcmUgdGhlIHNpbmdsZSBtYW5pZmVzdCBmZXRjaCBhbmQgdGhlIGxvZ2dpbmcuIEV2ZXJ5dGhpbmdcbiAqIHRoYXQgZGVjaWRlcyBcdTIwMTQgbm9ybWFsaXppbmcgdGhlIHJlcXVlc3RlZCBzcGVjaWZpZXJzLCByZXNvbHZpbmcgdGhlbSxcbiAqIGRlLWR1cGxpY2F0aW5nIG9uIHRoZSByZXNvbHZlZCB2ZXJzaW9uLCBzZXF1ZW5jaW5nIHRoZSBydW5zLCBhbmQgYnVpbGRpbmcgdGhlXG4gKiBmYWlsdXJlIHN1bW1hcnkgXHUyMDE0IGlzIHB1cmUgYW5kIHVuaXQtdGVzdGVkIG5leHQgZG9vci5cbiAqXG4gKiBUaGUgbG9vcCBsaXZlcyBhYm92ZSB0aGUgdHJhbnNwb3J0IHJhdGhlciB0aGFuIGluc2lkZSBpdCBiZWNhdXNlIGEgdGVzdFxuICogZnJhbWV3b3JrJ3MgZ2xvYmFsIHNldHVwIGNhbm5vdCByZS1ydW4gaXRzIG93biB0ZXN0IGZpbGVzOiBpdCBsYXVuY2hlcyBvbmVcbiAqIGluc3RhbmNlIGZvciBvbmUgcnVuLiBLZWVwaW5nIHRoZSBsb29wIGZyYW1ld29yay1hZ25vc3RpYyAodGhlIGNhbGxlciBzdXBwbGllc1xuICogYHJ1bmApIGlzIHdoYXQgbGV0cyBWaXRlc3QsIEplc3QsIGFuZCBtYW51YWwgY29uc3VtZXJzIGFsbCBpbmhlcml0IGl0IChMNikuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgZ2x1ZSAobmV0d29yayBmZXRjaCArIGxvZ2dpbmcpIGNvdmVyZWQgYnkgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCB1bml0IHRlc3RzLiAqL1xuXG5pbXBvcnQgdHlwZSB7XG4gIE9ic2lkaWFuVmVyc2lvbk1hdHJpeEVudHJ5LFxuICBSZXNvbHZlZFZlcnNpb25TcGVjXG59IGZyb20gJy4vdmVyc2lvbi1tYXRyaXguY2pzJztcblxuaW1wb3J0IHsgbG9nIH0gZnJvbSAnLi9sb2cuY2pzJztcbmltcG9ydCB7IGZldGNoRGVza3RvcFJlbGVhc2VzTWFuaWZlc3QgfSBmcm9tICcuL29ic2lkaWFuLXZlcnNpb24tc3dpdGNoLmNqcyc7XG5pbXBvcnQge1xuICBidWlsZFZlcnNpb25NYXRyaXgsXG4gIGZvcm1hdFZlcnNpb25NYXRyaXhQbGFuLFxuICBmb3JtYXRWZXJzaW9uTWF0cml4UnVuSGVhZGVyLFxuICBoYXNDaGFubmVsU3BlYyxcbiAgcmVzb2x2ZVJlcXVlc3RlZFNwZWNzLFxuICByZXNvbHZlVmVyc2lvblNwZWNzLFxuICBydW5WZXJzaW9uTWF0cml4RW50cmllc1xufSBmcm9tICcuL3ZlcnNpb24tbWF0cml4LmNqcyc7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIHJ1bk9ic2lkaWFuVmVyc2lvbk1hdHJpeH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUnVuT2JzaWRpYW5WZXJzaW9uTWF0cml4UGFyYW1zIHtcbiAgLyoqXG4gICAqIFJ1bnMgdGhlIHN1aXRlcyBhZ2FpbnN0IG9uZSBjb25jcmV0ZSBPYnNpZGlhbiB2ZXJzaW9uLCB0aHJvd2luZyBvbiBmYWlsdXJlLlxuICAgKlxuICAgKiBUaGUgZW50cnkncyBgdmVyc2lvbmAgaXMgdGhlIGNvbmNyZXRlIGB4LnkuemAgdG8gcGluIFx1MjAxNCB0eXBpY2FsbHkgZm9yd2FyZGVkIHRvXG4gICAqIHRoZSB0ZXN0LXJ1bm5lciBjaGlsZCBhcyBgT0JTSURJQU5fVkVSU0lPTmAuXG4gICAqL1xuICByZWFkb25seSBydW46IChlbnRyeTogT2JzaWRpYW5WZXJzaW9uTWF0cml4RW50cnkpID0+IFByb21pc2U8dm9pZD4gfCB2b2lkO1xuXG4gIC8qKlxuICAgKiBUaGUgdmVyc2lvbiBzcGVjaWZpZXJzIHRvIHJ1biBhZ2FpbnN0OiBhbiBhcnJheSwgb3IgYSBjb21tYS1zZXBhcmF0ZWQgc3RyaW5nXG4gICAqIHNvIGFuIGVudiB2YXIgY2FuIGJlIHBhc3NlZCBzdHJhaWdodCB0aHJvdWdoLlxuICAgKlxuICAgKiBFYWNoIGFjY2VwdHMgYW4gZXhwbGljaXQgYCd4LnkueidgLCBgJ3B1YmxpYy1sYXRlc3QnYCwgb3IgYCdjYXRhbHlzdC1sYXRlc3QnYC5cbiAgICogRGVmYXVsdHMgdG8gYm90aCBlbmRzIG9mIHRoZSBzdXBwb3J0ZWQgcmFuZ2UgKEc5OSkgd2hlbiBvbWl0dGVkIG9yIGVtcHR5LCBhbmRcbiAgICogdGhlIGxpc3QgaXMgYWx3YXlzIGRlLWR1cGxpY2F0ZWQgb24gdGhlICoqcmVzb2x2ZWQqKiB2ZXJzaW9uIFx1MjAxNCBzbyB3aGVuIHB1YmxpY1xuICAgKiBoYXMgY2F1Z2h0IHVwIHRvIGNhdGFseXN0LCB0aGUgc3VpdGVzIHJ1biBvbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbnM/OiByZWFkb25seSBzdHJpbmdbXSB8IHN0cmluZyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSdW5zIGEgc3VpdGUgb25jZSBwZXIgZGlzdGluY3Qgc3VwcG9ydGVkIE9ic2lkaWFuIHZlcnNpb24uXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwZXItdmVyc2lvbiBydW5uZXIgYW5kIHRoZSByZXF1ZXN0ZWQgdmVyc2lvbnMuXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgZXZlcnkgdmVyc2lvbiBoYXMgcnVuIHN1Y2Nlc3NmdWxseS5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgbm8gdmVyc2lvbiBjb3VsZCBiZSByZXNvbHZlZCwgb3IgYW4ge0BsaW5rIEFnZ3JlZ2F0ZUVycm9yfVxuICogICBuYW1pbmcgZXZlcnkgdmVyc2lvbiB3aG9zZSBydW4gZmFpbGVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuT2JzaWRpYW5WZXJzaW9uTWF0cml4KHBhcmFtczogUnVuT2JzaWRpYW5WZXJzaW9uTWF0cml4UGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgcnVuLCB2ZXJzaW9ucyB9ID0gcGFyYW1zO1xuXG4gIGNvbnN0IHsgaXNEZWZhdWx0LCBzcGVjcyB9ID0gcmVzb2x2ZVJlcXVlc3RlZFNwZWNzKHZlcnNpb25zKTtcbiAgY29uc3QgbWFuaWZlc3QgPSBoYXNDaGFubmVsU3BlYyhzcGVjcykgPyBhd2FpdCBmZXRjaERlc2t0b3BSZWxlYXNlc01hbmlmZXN0KCkgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHsgZHJvcHBlZFNwZWNzLCByZXNvbHZlZFNwZWNzIH0gPSByZXNvbHZlVmVyc2lvblNwZWNzKHtcbiAgICBtYW5pZmVzdCxcbiAgICAvLyBUaGUgZGVmYXVsdCBsaXN0IG11c3Qgbm90IGJyZWFrIGV2ZXJ5IGNvbnN1bWVyJ3MgZ2F0ZSB3aGVuIGEgY2hhbm5lbCBpc1xuICAgIC8vIE1vbWVudGFyaWx5IGFic2VudCBmcm9tIHRoZSBtYW5pZmVzdDsgYW4gZXhwbGljaXRseSByZXF1ZXN0ZWQgc3BlY2lmaWVyXG4gICAgLy8gVGhhdCBjYW5ub3QgcmVzb2x2ZSBpcyBhIHJlYWwgZXJyb3IuXG4gICAgc2hvdWxkVG9sZXJhdGVVbnJlc29sdmFibGVTcGVjczogaXNEZWZhdWx0LFxuICAgIHNwZWNzXG4gIH0pO1xuXG4gIGZvciAoY29uc3QgeyByZWFzb24sIHNwZWMgfSBvZiBkcm9wcGVkU3BlY3MpIHtcbiAgICBsb2dNYXRyaXgoYFNraXBwaW5nIFwiJHtzcGVjfVwiOiAke3JlYXNvbn1gKTtcbiAgfVxuXG4gIGNvbnN0IGVudHJpZXMgPSBidWlsZFZlcnNpb25NYXRyaXgocmVzb2x2ZWRTcGVjcyk7XG4gIGxvZ1BsYW4ocmVzb2x2ZWRTcGVjcywgZW50cmllcyk7XG5cbiAgYXdhaXQgcnVuVmVyc2lvbk1hdHJpeEVudHJpZXMoe1xuICAgIGVudHJpZXMsXG4gICAgb25FbnRyeVN0YXJ0OiAoaGVhZGVyUGFyYW1zKSA9PiB7XG4gICAgICBsb2dNYXRyaXgoZm9ybWF0VmVyc2lvbk1hdHJpeFJ1bkhlYWRlcihoZWFkZXJQYXJhbXMpKTtcbiAgICB9LFxuICAgIHJ1blxuICB9KTtcbn1cblxuLyoqXG4gKiBMb2dzIGEgbWF0cml4IG1lc3NhZ2UgdW5kZXIgYSBjb25zaXN0ZW50IHByZWZpeC5cbiAqXG4gKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGxvZy5cbiAqL1xuZnVuY3Rpb24gbG9nTWF0cml4KG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICBsb2coYFt2ZXJzaW9uLW1hdHJpeF0gJHttZXNzYWdlfWApO1xufVxuXG4vKipcbiAqIExvZ3Mgd2hhdCB0aGUgc3BlY2lmaWVycyByZXNvbHZlZCB0byBhbmQgaG93IG1hbnkgcnVucyB0aGF0IGltcGxpZXMuXG4gKlxuICogQHBhcmFtIHJlc29sdmVkU3BlY3MgLSBUaGUgcmVzb2x2ZWQgc3BlY2lmaWVycywgaW4gcmVxdWVzdGVkIG9yZGVyLlxuICogQHBhcmFtIGVudHJpZXMgLSBUaGUgZGUtZHVwbGljYXRlZCBtYXRyaXguXG4gKi9cbmZ1bmN0aW9uIGxvZ1BsYW4ocmVzb2x2ZWRTcGVjczogcmVhZG9ubHkgUmVzb2x2ZWRWZXJzaW9uU3BlY1tdLCBlbnRyaWVzOiByZWFkb25seSBPYnNpZGlhblZlcnNpb25NYXRyaXhFbnRyeVtdKTogdm9pZCB7XG4gIGZvciAoY29uc3QgbGluZSBvZiBmb3JtYXRWZXJzaW9uTWF0cml4UGxhbih7IGVudHJpZXMsIHJlc29sdmVkU3BlY3MgfSkpIHtcbiAgICBsb2dNYXRyaXgobGluZSk7XG4gIH1cbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUF5QkEsaUJBQW9CO0FBQ3BCLHFDQUE2QztBQUM3Qyw0QkFRTztBQWtDUCxlQUFzQix5QkFBeUIsUUFBdUQ7QUFDcEcsUUFBTSxFQUFFLEtBQUssU0FBUyxJQUFJO0FBRTFCLFFBQU0sRUFBRSxXQUFXLE1BQU0sUUFBSSw2Q0FBc0IsUUFBUTtBQUMzRCxRQUFNLGVBQVcsc0NBQWUsS0FBSyxJQUFJLFVBQU0sNkRBQTZCLElBQUk7QUFDaEYsUUFBTSxFQUFFLGNBQWMsY0FBYyxRQUFJLDJDQUFvQjtBQUFBLElBQzFEO0FBQUE7QUFBQTtBQUFBO0FBQUEsSUFJQSxpQ0FBaUM7QUFBQSxJQUNqQztBQUFBLEVBQ0YsQ0FBQztBQUVELGFBQVcsRUFBRSxRQUFRLEtBQUssS0FBSyxjQUFjO0FBQzNDLGNBQVUsYUFBYSxJQUFJLE1BQU0sTUFBTSxFQUFFO0FBQUEsRUFDM0M7QUFFQSxRQUFNLGNBQVUsMENBQW1CLGFBQWE7QUFDaEQsVUFBUSxlQUFlLE9BQU87QUFFOUIsWUFBTSwrQ0FBd0I7QUFBQSxJQUM1QjtBQUFBLElBQ0EsY0FBYyxDQUFDLGlCQUFpQjtBQUM5QixvQkFBVSxvREFBNkIsWUFBWSxDQUFDO0FBQUEsSUFDdEQ7QUFBQSxJQUNBO0FBQUEsRUFDRixDQUFDO0FBQ0g7QUFPQSxTQUFTLFVBQVUsU0FBdUI7QUFDeEMsc0JBQUksb0JBQW9CLE9BQU8sRUFBRTtBQUNuQztBQVFBLFNBQVMsUUFBUSxlQUErQyxTQUFzRDtBQUNwSCxhQUFXLFlBQVEsK0NBQXdCLEVBQUUsU0FBUyxjQUFjLENBQUMsR0FBRztBQUN0RSxjQUFVLElBQUk7QUFBQSxFQUNoQjtBQUNGOyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Integration-time runner that executes a suite once per **distinct** supported
5
+ * Obsidian version.
6
+ *
7
+ * Thin glue over the pure `version-matrix.ts` decision layer: the only things
8
+ * that happen here are the single manifest fetch and the logging. Everything
9
+ * that decides — normalizing the requested specifiers, resolving them,
10
+ * de-duplicating on the resolved version, sequencing the runs, and building the
11
+ * failure summary — is pure and unit-tested next door.
12
+ *
13
+ * The loop lives above the transport rather than inside it because a test
14
+ * framework's global setup cannot re-run its own test files: it launches one
15
+ * instance for one run. Keeping the loop framework-agnostic (the caller supplies
16
+ * `run`) is what lets Vitest, Jest, and manual consumers all inherit it (L6).
17
+ */
18
+ import type { ObsidianVersionMatrixEntry } from './version-matrix.cjs';
19
+ /**
20
+ * Parameters for {@link runObsidianVersionMatrix}.
21
+ */
22
+ export interface RunObsidianVersionMatrixParams {
23
+ /**
24
+ * Runs the suites against one concrete Obsidian version, throwing on failure.
25
+ *
26
+ * The entry's `version` is the concrete `x.y.z` to pin — typically forwarded to
27
+ * the test-runner child as `OBSIDIAN_VERSION`.
28
+ */
29
+ readonly run: (entry: ObsidianVersionMatrixEntry) => Promise<void> | void;
30
+ /**
31
+ * The version specifiers to run against: an array, or a comma-separated string
32
+ * so an env var can be passed straight through.
33
+ *
34
+ * Each accepts an explicit `'x.y.z'`, `'public-latest'`, or `'catalyst-latest'`.
35
+ * Defaults to both ends of the supported range (G99) when omitted or empty, and
36
+ * the list is always de-duplicated on the **resolved** version — so when public
37
+ * has caught up to catalyst, the suites run once.
38
+ */
39
+ readonly versions?: readonly string[] | string | undefined;
40
+ }
41
+ /**
42
+ * Runs a suite once per distinct supported Obsidian version.
43
+ *
44
+ * @param params - The per-version runner and the requested versions.
45
+ * @returns A {@link Promise} that resolves once every version has run successfully.
46
+ * @throws Error if no version could be resolved, or an {@link AggregateError}
47
+ * naming every version whose run failed.
48
+ */
49
+ export declare function runObsidianVersionMatrix(params: RunObsidianVersionMatrixParams): Promise<void>;
@@ -35,12 +35,19 @@ var import_node_fs = require("node:fs");
35
35
  var import_node_os = require("node:os");
36
36
  var import_node_path = require("node:path");
37
37
  var import_node_process = __toESM(require("node:process"), 1);
38
+ var import_error_to_string = require("./error-to-string.cjs");
38
39
  var import_log = require("./log.cjs");
39
40
  const LOCK_DIR_NAME = "obsidian-integration-testing";
40
41
  const LOCK_FILE_SUFFIX = ".setup.lock";
41
42
  const POLL_INTERVAL_IN_MILLISECONDS = 500;
42
43
  const MILLISECONDS_PER_SECOND = 1e3;
43
44
  const SECONDS_PER_MINUTE = 60;
45
+ const HEARTBEAT_INTERVAL_IN_SECONDS = 5;
46
+ const HEARTBEAT_INTERVAL_IN_MILLISECONDS = HEARTBEAT_INTERVAL_IN_SECONDS * MILLISECONDS_PER_SECOND;
47
+ const MISSED_HEARTBEATS_BEFORE_STALE = 24;
48
+ const HEARTBEAT_STALE_IN_MILLISECONDS = HEARTBEAT_INTERVAL_IN_MILLISECONDS * MISSED_HEARTBEATS_BEFORE_STALE;
49
+ const WAIT_LOG_INTERVAL_IN_SECONDS = 30;
50
+ const WAIT_LOG_INTERVAL_IN_MILLISECONDS = WAIT_LOG_INTERVAL_IN_SECONDS * MILLISECONDS_PER_SECOND;
44
51
  const STALE_LOCK_AGE_IN_MINUTES = 30;
45
52
  const DEFAULT_TIMEOUT_IN_MINUTES = 60;
46
53
  const STALE_LOCK_AGE_IN_MILLISECONDS = STALE_LOCK_AGE_IN_MINUTES * SECONDS_PER_MINUTE * MILLISECONDS_PER_SECOND;
@@ -54,42 +61,119 @@ async function acquireSetupLock(params) {
54
61
  const timeoutInMilliseconds = params.timeoutInMilliseconds ?? DEFAULT_TIMEOUT_IN_MILLISECONDS;
55
62
  const lockFilePath = getLockFilePath(scope);
56
63
  (0, import_node_fs.mkdirSync)(getLockDir(), { recursive: true });
57
- const deadlineInMilliseconds = Date.now() + timeoutInMilliseconds;
58
- let hasLoggedWait = false;
64
+ const startedAtInMilliseconds = Date.now();
65
+ const deadlineInMilliseconds = startedAtInMilliseconds + timeoutInMilliseconds;
66
+ let lastLoggedWaitAtInMilliseconds = null;
59
67
  for (; ; ) {
60
- if (tryCreateLockFile(lockFilePath, label)) {
61
- return createLockHandle(lockFilePath);
68
+ const ownInfo = tryCreateLockFile(lockFilePath, label);
69
+ if (ownInfo) {
70
+ return createLockHandle({
71
+ label,
72
+ lockFilePath,
73
+ ownInfo,
74
+ scope
75
+ });
62
76
  }
63
77
  const info = readLockFileInfo(lockFilePath);
64
- if (info && isLockStale(info)) {
78
+ if (info && checkIsLockStale(info)) {
65
79
  (0, import_log.log)(`[integration-setup:${label}] Stealing stale '${scope}' setup lock from ${describeInfo(info)}.`);
66
80
  (0, import_node_fs.rmSync)(lockFilePath, { force: true });
81
+ if (Date.now() >= deadlineInMilliseconds) {
82
+ throw createTimeoutError({
83
+ info,
84
+ scope,
85
+ timeoutInMilliseconds
86
+ });
87
+ }
67
88
  continue;
68
89
  }
69
- if (Date.now() >= deadlineInMilliseconds) {
70
- throw new Error(
71
- `Timed out after ${String(timeoutInMilliseconds)}ms waiting for the '${scope}' integration-test setup lock held by ${describeHolder(info)}. Another integration-test run is still in progress.`
72
- );
90
+ const nowInMilliseconds = Date.now();
91
+ if (nowInMilliseconds >= deadlineInMilliseconds) {
92
+ throw createTimeoutError({
93
+ info,
94
+ scope,
95
+ timeoutInMilliseconds
96
+ });
73
97
  }
74
- if (!hasLoggedWait) {
75
- hasLoggedWait = true;
76
- (0, import_log.log)(`[integration-setup:${label}] Waiting for the '${scope}' setup lock held by ${describeHolder(info)} to be released...`);
98
+ const shouldLogWait = lastLoggedWaitAtInMilliseconds === null || nowInMilliseconds - lastLoggedWaitAtInMilliseconds >= WAIT_LOG_INTERVAL_IN_MILLISECONDS;
99
+ if (shouldLogWait) {
100
+ lastLoggedWaitAtInMilliseconds = nowInMilliseconds;
101
+ (0, import_log.log)(formatWaitMessage({
102
+ info,
103
+ label,
104
+ remainingInMilliseconds: deadlineInMilliseconds - nowInMilliseconds,
105
+ scope,
106
+ waitedInMilliseconds: nowInMilliseconds - startedAtInMilliseconds
107
+ }));
77
108
  }
78
109
  await delay(POLL_INTERVAL_IN_MILLISECONDS);
79
110
  }
80
111
  }
81
- function createLockHandle(lockFilePath) {
112
+ function checkIsLockStale(info) {
113
+ const silentForInMilliseconds = Date.now() - getLastSeenAtInMilliseconds(info);
114
+ if (info.hostname === (0, import_node_os.hostname)()) {
115
+ return !checkIsProcessAlive(info.pid) || silentForInMilliseconds > HEARTBEAT_STALE_IN_MILLISECONDS;
116
+ }
117
+ return silentForInMilliseconds > STALE_LOCK_AGE_IN_MILLISECONDS;
118
+ }
119
+ function checkIsOwnLock(info) {
120
+ return info.pid === import_node_process.default.pid && info.hostname === (0, import_node_os.hostname)();
121
+ }
122
+ function checkIsProcessAlive(pid) {
123
+ try {
124
+ import_node_process.default.kill(pid, PROCESS_EXISTENCE_PROBE_SIGNAL);
125
+ return true;
126
+ } catch (error) {
127
+ return getErrorCode(error) === "EPERM";
128
+ }
129
+ }
130
+ function createLockHandle(params) {
131
+ const {
132
+ label,
133
+ lockFilePath,
134
+ ownInfo,
135
+ scope
136
+ } = params;
82
137
  let isReleased = false;
138
+ const heartbeatTimer = setInterval(() => {
139
+ const isStillOurs = refreshHeartbeat({
140
+ label,
141
+ lockFilePath,
142
+ ownInfo
143
+ });
144
+ if (isStillOurs) {
145
+ return;
146
+ }
147
+ clearInterval(heartbeatTimer);
148
+ (0, import_log.log)(`[integration-setup:${label}] The '${scope}' setup lock is no longer ours \u2014 another run took it over. Heartbeat stopped.`);
149
+ }, HEARTBEAT_INTERVAL_IN_MILLISECONDS);
150
+ heartbeatTimer.unref();
83
151
  return {
84
152
  release() {
85
153
  if (isReleased) {
86
154
  return;
87
155
  }
88
156
  isReleased = true;
157
+ clearInterval(heartbeatTimer);
158
+ const info = readLockFileInfo(lockFilePath);
159
+ if (info && !checkIsOwnLock(info)) {
160
+ (0, import_log.log)(`[integration-setup:${label}] Leaving the '${scope}' setup lock in place \u2014 it now belongs to ${describeInfo(info)}.`);
161
+ return;
162
+ }
89
163
  (0, import_node_fs.rmSync)(lockFilePath, { force: true });
90
164
  }
91
165
  };
92
166
  }
167
+ function createTimeoutError(params) {
168
+ const {
169
+ info,
170
+ scope,
171
+ timeoutInMilliseconds
172
+ } = params;
173
+ return new Error(
174
+ `Timed out after ${String(timeoutInMilliseconds)}ms waiting for the '${scope}' integration-test setup lock held by ${describeHolder(info)}. Another integration-test run is still in progress.`
175
+ );
176
+ }
93
177
  function delay(milliseconds) {
94
178
  return new Promise((resolve) => {
95
179
  setTimeout(resolve, milliseconds);
@@ -101,52 +185,81 @@ function describeHolder(info) {
101
185
  function describeInfo(info) {
102
186
  return `pid ${String(info.pid)} (${info.label}) on ${info.hostname}`;
103
187
  }
188
+ function formatDuration(milliseconds) {
189
+ const totalSeconds = Math.round(milliseconds / MILLISECONDS_PER_SECOND);
190
+ const minutes = Math.floor(totalSeconds / SECONDS_PER_MINUTE);
191
+ const seconds = totalSeconds % SECONDS_PER_MINUTE;
192
+ return minutes > 0 ? `${String(minutes)}m ${String(seconds)}s` : `${String(seconds)}s`;
193
+ }
194
+ function formatWaitMessage(params) {
195
+ const {
196
+ info,
197
+ label,
198
+ remainingInMilliseconds,
199
+ scope,
200
+ waitedInMilliseconds
201
+ } = params;
202
+ const heldFor = info ? `, held for ${formatDuration(Date.now() - info.acquiredAtInMilliseconds)}` : "";
203
+ return `[integration-setup:${label}] Waiting for the '${scope}' setup lock held by ${describeHolder(info)} to be released (waited ${formatDuration(waitedInMilliseconds)}${heldFor}, giving up in ${formatDuration(remainingInMilliseconds)})...`;
204
+ }
104
205
  function getErrorCode(error) {
105
206
  if (error instanceof Error && "code" in error && typeof error.code === "string") {
106
207
  return error.code;
107
208
  }
108
209
  return void 0;
109
210
  }
211
+ function getLastSeenAtInMilliseconds(info) {
212
+ return info.heartbeatAtInMilliseconds ?? info.acquiredAtInMilliseconds;
213
+ }
110
214
  function getLockDir() {
111
215
  return (0, import_node_path.join)((0, import_node_os.tmpdir)(), LOCK_DIR_NAME);
112
216
  }
113
217
  function getLockFilePath(scope) {
114
218
  return (0, import_node_path.join)(getLockDir(), `${scope}${LOCK_FILE_SUFFIX}`);
115
219
  }
116
- function isLockStale(info) {
117
- if (info.hostname === (0, import_node_os.hostname)()) {
118
- return !isProcessAlive(info.pid);
119
- }
120
- return Date.now() - info.acquiredAtInMilliseconds > STALE_LOCK_AGE_IN_MILLISECONDS;
121
- }
122
- function isProcessAlive(pid) {
123
- try {
124
- import_node_process.default.kill(pid, PROCESS_EXISTENCE_PROBE_SIGNAL);
125
- return true;
126
- } catch (error) {
127
- return getErrorCode(error) === "EPERM";
128
- }
129
- }
130
220
  function readLockFileInfo(lockFilePath) {
131
221
  try {
132
222
  return JSON.parse((0, import_node_fs.readFileSync)(lockFilePath, "utf-8"));
133
223
  } catch {
134
- return void 0;
224
+ return null;
225
+ }
226
+ }
227
+ function refreshHeartbeat(params) {
228
+ const {
229
+ label,
230
+ lockFilePath,
231
+ ownInfo
232
+ } = params;
233
+ const info = readLockFileInfo(lockFilePath);
234
+ if (info && !checkIsOwnLock(info)) {
235
+ return false;
236
+ }
237
+ const refreshedInfo = {
238
+ ...ownInfo,
239
+ heartbeatAtInMilliseconds: Date.now()
240
+ };
241
+ try {
242
+ (0, import_node_fs.writeFileSync)(lockFilePath, JSON.stringify(refreshedInfo));
243
+ } catch (error) {
244
+ (0, import_log.log)(`[integration-setup:${label}] Failed to refresh the setup lock heartbeat: ${(0, import_error_to_string.errorToString)(error)}`);
135
245
  }
246
+ return true;
136
247
  }
137
248
  function tryCreateLockFile(lockFilePath, label) {
249
+ const nowInMilliseconds = Date.now();
138
250
  const info = {
139
- acquiredAtInMilliseconds: Date.now(),
251
+ acquiredAtInMilliseconds: nowInMilliseconds,
252
+ heartbeatAtInMilliseconds: nowInMilliseconds,
140
253
  hostname: (0, import_node_os.hostname)(),
141
254
  label,
142
255
  pid: import_node_process.default.pid
143
256
  };
144
257
  try {
145
258
  (0, import_node_fs.writeFileSync)(lockFilePath, JSON.stringify(info), { flag: "wx" });
146
- return true;
259
+ return info;
147
260
  } catch (error) {
148
261
  if (getErrorCode(error) === "EEXIST") {
149
- return false;
262
+ return null;
150
263
  }
151
264
  throw error;
152
265
  }
@@ -155,4 +268,4 @@ function tryCreateLockFile(lockFilePath, label) {
155
268
  0 && (module.exports = {
156
269
  acquireSetupLock
157
270
  });
158
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3NldHVwLWxvY2sudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBDcm9zcy1wcm9jZXNzIGFkdmlzb3J5IGxvY2sgdGhhdCBzZXJpYWxpemVzIHdob2xlIGludGVncmF0aW9uLXRlc3QgcnVucy5cbiAqXG4gKiBUd28gdGVzdCBydW5zIHRoYXQgZHJpdmUgdGhlIHNhbWUgc2hhcmVkIHJlc291cmNlcyBjb3JydXB0IGVhY2ggb3RoZXI6IG9uXG4gKiBkZXNrdG9wIHRoZXkgc2hhcmUgdGhlIHNpbmdsZSBsb2NhbCBPYnNpZGlhbiBpbnN0YW5jZSwgaXRzIGBvYnNpZGlhbi5qc29uYFxuICogcmVnaXN0cnksIGFuZCB0aGUgQ0RQIHBvcnQ7IG9uIEFuZHJvaWQgdGhleSBzaGFyZSB0aGUgZW11bGF0b3IgYW5kIHRoZSBBcHBpdW1cbiAqIHNlcnZlci4gT25lIHJ1bidzIHNldHVwL3RlYXJkb3duIGtpbGxzIG9yIHJlY29uZmlndXJlcyB0aGUgaW5zdGFuY2UgdGhlIG90aGVyXG4gKiBydW4gaXMgbWlkLWV2YWwgb24gKG9ic2VydmVkIGFzIGBFQ09OTlJFRlVTRURgIG9yIFwidmF1bHQgbm90IG9wZW5cIiksIHNvIGJvdGhcbiAqIHJ1bnMgZmFpbC5cbiAqXG4gKiBUaGlzIGxvY2sgbWFrZXMgdGhlIHNlY29uZCBydW4gKip3YWl0KiogZm9yIHRoZSBmaXJzdCB0byBmaW5pc2ggaW5zdGVhZCBvZlxuICogcnVubmluZyBjb25jdXJyZW50bHkuIEl0IGlzIGhlbGQgZm9yIHRoZSBlbnRpcmUgcnVuOiBhY3F1aXJlZCBhdCB0aGUgc3RhcnQgb2ZcbiAqIHRoZSBjb3JlIHNldHVwIGFuZCByZWxlYXNlZCBieSB0aGUgY29yZSB0ZWFyZG93biAoYW5kIGJ5IHRoZSBwcm9jZXNzIGNsZWFudXBcbiAqIGhhbmRsZXJzKS4gVGhlIGxvY2sgaXMgYSBzZW50aW5lbCBmaWxlIGluIGEgc2hhcmVkIHRlbXAgZGlyZWN0b3J5LCBjYXJyeWluZ1xuICogdGhlIGhvbGRlcidzIFBJRCBzbyBhIHJ1biB0aGF0IGNyYXNoZWQgd2l0aG91dCByZWxlYXNpbmcgbGVhdmVzIGEgbG9jayB0aGF0XG4gKiB0aGUgbmV4dCBydW4gZGV0ZWN0cyBhcyBzdGFsZSBhbmQgc3RlYWxzLlxuICovXG5cbmltcG9ydCB7XG4gIG1rZGlyU3luYyxcbiAgcmVhZEZpbGVTeW5jLFxuICBybVN5bmMsXG4gIHdyaXRlRmlsZVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBob3N0bmFtZSxcbiAgdG1wZGlyXG59IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQgeyBsb2cgfSBmcm9tICcuL2xvZy5janMnO1xuXG5jb25zdCBMT0NLX0RJUl9OQU1FID0gJ29ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmcnO1xuY29uc3QgTE9DS19GSUxFX1NVRkZJWCA9ICcuc2V0dXAubG9jayc7XG5jb25zdCBQT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IE1JTExJU0VDT05EU19QRVJfU0VDT05EID0gMTAwMDtcbmNvbnN0IFNFQ09ORFNfUEVSX01JTlVURSA9IDYwO1xuY29uc3QgU1RBTEVfTE9DS19BR0VfSU5fTUlOVVRFUyA9IDMwO1xuY29uc3QgREVGQVVMVF9USU1FT1VUX0lOX01JTlVURVMgPSA2MDtcbmNvbnN0IFNUQUxFX0xPQ0tfQUdFX0lOX01JTExJU0VDT05EUyA9IFNUQUxFX0xPQ0tfQUdFX0lOX01JTlVURVMgKiBTRUNPTkRTX1BFUl9NSU5VVEUgKiBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORDtcbmNvbnN0IERFRkFVTFRfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSBERUZBVUxUX1RJTUVPVVRfSU5fTUlOVVRFUyAqIFNFQ09ORFNfUEVSX01JTlVURSAqIE1JTExJU0VDT05EU19QRVJfU0VDT05EO1xuY29uc3QgUFJPQ0VTU19FWElTVEVOQ0VfUFJPQkVfU0lHTkFMID0gMDtcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgYWNxdWlyZVNldHVwTG9ja30uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWNxdWlyZVNldHVwTG9ja1BhcmFtcyB7XG4gIC8qKiBTaG9ydCB0cmFuc3BvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcyAoZS5nLiBgXCJvYnNpZGlhbi1jbGlcImApLiAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBMb2dpY2FsIHNjb3BlIHRoZSBsb2NrIHNlcmlhbGl6ZXMgd2l0aGluLiBSdW5zIHRoYXQgc2hhcmUgcmVzb3VyY2VzIG11c3RcbiAgICogdXNlIHRoZSBzYW1lIHNjb3BlIChlLmcuIGBcImRlc2t0b3BcImAgZm9yIHRoZSBDTEkvQ0RQIHRyYW5zcG9ydHMsIGBcImFuZHJvaWRcImBcbiAgICogZm9yIHRoZSBBcHBpdW0gdHJhbnNwb3J0KS5cbiAgICovXG4gIHJlYWRvbmx5IHNjb3BlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE1heGltdW0gdGltZSB0byB3YWl0IGZvciBhIGNvbXBldGluZyBydW4gdG8gcmVsZWFzZSB0aGUgbG9jayBiZWZvcmUgZ2l2aW5nXG4gICAqIHVwIGFuZCB0aHJvd2luZy5cbiAgICpcbiAgICogQGRlZmF1bHQgMSBob3VyXG4gICAqL1xuICByZWFkb25seSB0aW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXIgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQSBoZWxkIHNldHVwIGxvY2suIFJlbGVhc2UgaXQgb25jZSB0aGUgcnVuJ3MgdGVhcmRvd24gaXMgY29tcGxldGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2V0dXBMb2NrIHtcbiAgLyoqIFJlbGVhc2VzIHRoZSBsb2NrLiBTYWZlIHRvIGNhbGwgbW9yZSB0aGFuIG9uY2UuICovXG4gIHJlbGVhc2UoKTogdm9pZDtcbn1cblxuLyoqXG4gKiBUaGUgSlNPTiBwYXlsb2FkIHN0b3JlZCBpbnNpZGUgYSBsb2NrIGZpbGUsIGlkZW50aWZ5aW5nIHRoZSBob2xkZXIuXG4gKi9cbmludGVyZmFjZSBMb2NrRmlsZUluZm8ge1xuICAvKiogV2hlbiB0aGUgbG9jayB3YXMgYWNxdWlyZWQgKGBEYXRlLm5vdygpYCBlcG9jaCBtaWxsaXNlY29uZHMpLiAqL1xuICByZWFkb25seSBhY3F1aXJlZEF0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcblxuICAvKiogVGhlIGhvc3QgdGhhdCBob2xkcyB0aGUgbG9jayAoUElEIGxpdmVuZXNzIGlzIG9ubHkgdmFsaWQgb24gdGhlIHNhbWUgaG9zdCkuICovXG4gIHJlYWRvbmx5IGhvc3RuYW1lOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSB0cmFuc3BvcnQgbGFiZWwgb2YgdGhlIGhvbGRpbmcgcnVuLiAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKiBUaGUgcHJvY2VzcyBJRCBvZiB0aGUgaG9sZGluZyBydW4uICovXG4gIHJlYWRvbmx5IHBpZDogbnVtYmVyO1xufVxuXG4vKipcbiAqIEFjcXVpcmVzIHRoZSBjcm9zcy1wcm9jZXNzIHNldHVwIGxvY2sgZm9yIHRoZSBnaXZlbiBzY29wZSwgd2FpdGluZyB1bnRpbCBhbnlcbiAqIGNvbXBldGluZyBydW4gcmVsZWFzZXMgaXQgKG9yIGl0cyBsb2NrIGlzIGRldGVjdGVkIGFzIHN0YWxlKS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGxvY2sgcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIEEgaGFuZGxlIHdob3NlIHtAbGluayBTZXR1cExvY2sucmVsZWFzZX0gZnJlZXMgdGhlIGxvY2suXG4gKiBAdGhyb3dzIElmIHRoZSBsb2NrIGNhbm5vdCBiZSBhY3F1aXJlZCB3aXRoaW4gYHRpbWVvdXRJbk1pbGxpc2Vjb25kc2AuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhY3F1aXJlU2V0dXBMb2NrKHBhcmFtczogQWNxdWlyZVNldHVwTG9ja1BhcmFtcyk6IFByb21pc2U8U2V0dXBMb2NrPiB7XG4gIGNvbnN0IHtcbiAgICBsYWJlbCxcbiAgICBzY29wZVxuICB9ID0gcGFyYW1zO1xuICBjb25zdCB0aW1lb3V0SW5NaWxsaXNlY29uZHMgPSBwYXJhbXMudGltZW91dEluTWlsbGlzZWNvbmRzID8/IERFRkFVTFRfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gIGNvbnN0IGxvY2tGaWxlUGF0aCA9IGdldExvY2tGaWxlUGF0aChzY29wZSk7XG4gIG1rZGlyU3luYyhnZXRMb2NrRGlyKCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuXG4gIGNvbnN0IGRlYWRsaW5lSW5NaWxsaXNlY29uZHMgPSBEYXRlLm5vdygpICsgdGltZW91dEluTWlsbGlzZWNvbmRzO1xuICBsZXQgaGFzTG9nZ2VkV2FpdCA9IGZhbHNlO1xuXG4gIGZvciAoOzspIHtcbiAgICBpZiAodHJ5Q3JlYXRlTG9ja0ZpbGUobG9ja0ZpbGVQYXRoLCBsYWJlbCkpIHtcbiAgICAgIHJldHVybiBjcmVhdGVMb2NrSGFuZGxlKGxvY2tGaWxlUGF0aCk7XG4gICAgfVxuXG4gICAgY29uc3QgaW5mbyA9IHJlYWRMb2NrRmlsZUluZm8obG9ja0ZpbGVQYXRoKTtcbiAgICBpZiAoaW5mbyAmJiBpc0xvY2tTdGFsZShpbmZvKSkge1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFN0ZWFsaW5nIHN0YWxlICcke3Njb3BlfScgc2V0dXAgbG9jayBmcm9tICR7ZGVzY3JpYmVJbmZvKGluZm8pfS5gKTtcbiAgICAgIHJtU3luYyhsb2NrRmlsZVBhdGgsIHsgZm9yY2U6IHRydWUgfSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoRGF0ZS5ub3coKSA+PSBkZWFkbGluZUluTWlsbGlzZWNvbmRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBUaW1lZCBvdXQgYWZ0ZXIgJHtTdHJpbmcodGltZW91dEluTWlsbGlzZWNvbmRzKX1tcyB3YWl0aW5nIGZvciB0aGUgJyR7c2NvcGV9JyBpbnRlZ3JhdGlvbi10ZXN0IHNldHVwIGxvY2sgYFxuICAgICAgICAgICsgYGhlbGQgYnkgJHtkZXNjcmliZUhvbGRlcihpbmZvKX0uIEFub3RoZXIgaW50ZWdyYXRpb24tdGVzdCBydW4gaXMgc3RpbGwgaW4gcHJvZ3Jlc3MuYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIWhhc0xvZ2dlZFdhaXQpIHtcbiAgICAgIGhhc0xvZ2dlZFdhaXQgPSB0cnVlO1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFdhaXRpbmcgZm9yIHRoZSAnJHtzY29wZX0nIHNldHVwIGxvY2sgaGVsZCBieSAke2Rlc2NyaWJlSG9sZGVyKGluZm8pfSB0byBiZSByZWxlYXNlZC4uLmApO1xuICAgIH1cblxuICAgIGF3YWl0IGRlbGF5KFBPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSB7QGxpbmsgU2V0dXBMb2NrfSBoYW5kbGUgdGhhdCByZW1vdmVzIHRoZSBsb2NrIGZpbGUgb24gcmVsZWFzZS5cbiAqXG4gKiBAcGFyYW0gbG9ja0ZpbGVQYXRoIC0gVGhlIHBhdGggdG8gdGhlIGxvY2sgZmlsZSB0byByZW1vdmUgb24gcmVsZWFzZS5cbiAqIEByZXR1cm5zIFRoZSBsb2NrIGhhbmRsZS5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlTG9ja0hhbmRsZShsb2NrRmlsZVBhdGg6IHN0cmluZyk6IFNldHVwTG9jayB7XG4gIGxldCBpc1JlbGVhc2VkID0gZmFsc2U7XG4gIHJldHVybiB7XG4gICAgcmVsZWFzZSgpOiB2b2lkIHtcbiAgICAgIGlmIChpc1JlbGVhc2VkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlzUmVsZWFzZWQgPSB0cnVlO1xuICAgICAgcm1TeW5jKGxvY2tGaWxlUGF0aCwgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgYWZ0ZXIgdGhlIGdpdmVuIGRlbGF5LiBVc2VkIHRvIHBvbGwgYmV0d2VlbiBsb2NrLWFjcXVpc2l0aW9uIGF0dGVtcHRzLlxuICpcbiAqIEBwYXJhbSBtaWxsaXNlY29uZHMgLSBUaGUgZGVsYXkgaW4gbWlsbGlzZWNvbmRzLlxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIGRlbGF5LlxuICovXG5mdW5jdGlvbiBkZWxheShtaWxsaXNlY29uZHM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICBzZXRUaW1lb3V0KHJlc29sdmUsIG1pbGxpc2Vjb25kcyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEJ1aWxkcyBhIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIG9mIHRoZSBjdXJyZW50IGxvY2sgaG9sZGVyIGZvciBsb2cvZXJyb3JcbiAqIG1lc3NhZ2VzLlxuICpcbiAqIEBwYXJhbSBpbmZvIC0gVGhlIHBhcnNlZCBsb2NrIGluZm8sIG9yIGB1bmRlZmluZWRgIGlmIGl0IGNvdWxkIG5vdCBiZSByZWFkLlxuICogQHJldHVybnMgQSBkZXNjcmlwdGlvbiBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGRlc2NyaWJlSG9sZGVyKGluZm86IExvY2tGaWxlSW5mbyB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gIHJldHVybiBpbmZvID8gZGVzY3JpYmVJbmZvKGluZm8pIDogJ2Fub3RoZXIgcnVuJztcbn1cblxuLyoqXG4gKiBGb3JtYXRzIGEge0BsaW5rIExvY2tGaWxlSW5mb30gYXMgYSBzaG9ydCBpZGVudGlmaWVyIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gaW5mbyAtIFRoZSBsb2NrIGluZm8uXG4gKiBAcmV0dXJucyBBIHN0cmluZyBsaWtlIGBwaWQgMTIzNCAob2JzaWRpYW4tY2xpKSBvbiBob3N0YC5cbiAqL1xuZnVuY3Rpb24gZGVzY3JpYmVJbmZvKGluZm86IExvY2tGaWxlSW5mbyk6IHN0cmluZyB7XG4gIHJldHVybiBgcGlkICR7U3RyaW5nKGluZm8ucGlkKX0gKCR7aW5mby5sYWJlbH0pIG9uICR7aW5mby5ob3N0bmFtZX1gO1xufVxuXG4vKipcbiAqIEV4dHJhY3RzIHRoZSBgY29kZWAgZnJvbSBhIE5vZGUuanMgc3lzdGVtIGVycm9yLCBpZiBwcmVzZW50LlxuICpcbiAqIEBwYXJhbSBlcnJvciAtIFRoZSB0aHJvd24gdmFsdWUuXG4gKiBAcmV0dXJucyBUaGUgZXJyb3IgY29kZSBzdHJpbmcsIG9yIGB1bmRlZmluZWRgIGlmIG5vdCBhIGNvZGVkIGVycm9yLlxuICovXG5mdW5jdGlvbiBnZXRFcnJvckNvZGUoZXJyb3I6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiAnY29kZScgaW4gZXJyb3IgJiYgdHlwZW9mIGVycm9yLmNvZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGVycm9yLmNvZGU7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzaGFyZWQgbG9jayBkaXJlY3RvcnkgaW5zaWRlIHRoZSBPUyB0ZW1wIGRpcmVjdG9yeS5cbiAqXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgbG9jayBkaXJlY3RvcnkuXG4gKi9cbmZ1bmN0aW9uIGdldExvY2tEaXIoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4odG1wZGlyKCksIExPQ0tfRElSX05BTUUpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGxvY2sgZmlsZSBwYXRoIGZvciB0aGUgZ2l2ZW4gc2NvcGUuXG4gKlxuICogQHBhcmFtIHNjb3BlIC0gVGhlIGxvY2sgc2NvcGUuXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgc2NvcGUncyBsb2NrIGZpbGUuXG4gKi9cbmZ1bmN0aW9uIGdldExvY2tGaWxlUGF0aChzY29wZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4oZ2V0TG9ja0RpcigpLCBgJHtzY29wZX0ke0xPQ0tfRklMRV9TVUZGSVh9YCk7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgbG9jayBjYW4gYmUgY29uc2lkZXJlZCBhYmFuZG9uZWQuXG4gKlxuICogT24gdGhlIHNhbWUgaG9zdCwgdGhlIGhvbGRlcidzIFBJRCBpcyBwcm9iZWQgZGlyZWN0bHk6IGEgZGVhZCBQSUQgbWVhbnMgdGhlXG4gKiBydW4gY3Jhc2hlZCB3aXRob3V0IHJlbGVhc2luZy4gT24gYSBkaWZmZXJlbnQgaG9zdCAoYSBzaGFyZWQvbmV0d29yayB0ZW1wXG4gKiBkaXJlY3RvcnkpIHRoZSBQSUQgY2Fubm90IGJlIHByb2JlZCwgc28gYW4gYWdlIHRocmVzaG9sZCBpcyB1c2VkIGluc3RlYWQuXG4gKlxuICogQHBhcmFtIGluZm8gLSBUaGUgcGFyc2VkIGxvY2sgaW5mby5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbG9jayBpcyBzdGFsZSBhbmQgbWF5IGJlIHN0b2xlbi5cbiAqL1xuZnVuY3Rpb24gaXNMb2NrU3RhbGUoaW5mbzogTG9ja0ZpbGVJbmZvKTogYm9vbGVhbiB7XG4gIGlmIChpbmZvLmhvc3RuYW1lID09PSBob3N0bmFtZSgpKSB7XG4gICAgcmV0dXJuICFpc1Byb2Nlc3NBbGl2ZShpbmZvLnBpZCk7XG4gIH1cblxuICByZXR1cm4gRGF0ZS5ub3coKSAtIGluZm8uYWNxdWlyZWRBdEluTWlsbGlzZWNvbmRzID4gU1RBTEVfTE9DS19BR0VfSU5fTUlMTElTRUNPTkRTO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgcHJvY2VzcyB3aXRoIHRoZSBnaXZlbiBQSUQgaXMgY3VycmVudGx5IGFsaXZlLlxuICpcbiAqIEBwYXJhbSBwaWQgLSBUaGUgcHJvY2VzcyBJRCB0byBwcm9iZS5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvY2VzcyBleGlzdHMuXG4gKi9cbmZ1bmN0aW9uIGlzUHJvY2Vzc0FsaXZlKHBpZDogbnVtYmVyKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgcHJvY2Vzcy5raWxsKHBpZCwgUFJPQ0VTU19FWElTVEVOQ0VfUFJPQkVfU0lHTkFMKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAvLyBgRVBFUk1gIG1lYW5zIHRoZSBwcm9jZXNzIGV4aXN0cyBidXQgaXMgb3duZWQgYnkgYW5vdGhlciB1c2VyIFx1MjAxNCBzdGlsbCBhbGl2ZS5cbiAgICByZXR1cm4gZ2V0RXJyb3JDb2RlKGVycm9yKSA9PT0gJ0VQRVJNJztcbiAgfVxufVxuXG4vKipcbiAqIFJlYWRzIGFuZCBwYXJzZXMgdGhlIGxvY2sgZmlsZSwgaWYgaXQgZXhpc3RzIGFuZCBpcyB2YWxpZCBKU09OLlxuICpcbiAqIEBwYXJhbSBsb2NrRmlsZVBhdGggLSBUaGUgcGF0aCB0byB0aGUgbG9jayBmaWxlLlxuICogQHJldHVybnMgVGhlIHBhcnNlZCBsb2NrIGluZm8sIG9yIGB1bmRlZmluZWRgIGlmIGl0IGNvdWxkIG5vdCBiZSByZWFkLlxuICovXG5mdW5jdGlvbiByZWFkTG9ja0ZpbGVJbmZvKGxvY2tGaWxlUGF0aDogc3RyaW5nKTogTG9ja0ZpbGVJbmZvIHwgdW5kZWZpbmVkIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShyZWFkRmlsZVN5bmMobG9ja0ZpbGVQYXRoLCAndXRmLTgnKSkgYXMgTG9ja0ZpbGVJbmZvO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKlxuICogQXR0ZW1wdHMgdG8gYXRvbWljYWxseSBjcmVhdGUgdGhlIGxvY2sgZmlsZSAoZmFpbGluZyBpZiBpdCBhbHJlYWR5IGV4aXN0cykuXG4gKlxuICogQHBhcmFtIGxvY2tGaWxlUGF0aCAtIFRoZSBwYXRoIHRvIHRoZSBsb2NrIGZpbGUuXG4gKiBAcGFyYW0gbGFiZWwgLSBUaGUgdHJhbnNwb3J0IGxhYmVsIHRvIHJlY29yZCBpbiB0aGUgbG9jayBmaWxlLlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBsb2NrIHdhcyBhY3F1aXJlZCwgYGZhbHNlYCBpZiBpdCBpcyBhbHJlYWR5IGhlbGQuXG4gKiBAdGhyb3dzIElmIHRoZSBmaWxlIHN5c3RlbSBmYWlscyBmb3IgYW55IHJlYXNvbiBvdGhlciB0aGFuIHRoZSBmaWxlIGV4aXN0aW5nLlxuICovXG5mdW5jdGlvbiB0cnlDcmVhdGVMb2NrRmlsZShsb2NrRmlsZVBhdGg6IHN0cmluZywgbGFiZWw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBpbmZvOiBMb2NrRmlsZUluZm8gPSB7XG4gICAgYWNxdWlyZWRBdEluTWlsbGlzZWNvbmRzOiBEYXRlLm5vdygpLFxuICAgIGhvc3RuYW1lOiBob3N0bmFtZSgpLFxuICAgIGxhYmVsLFxuICAgIHBpZDogcHJvY2Vzcy5waWRcbiAgfTtcblxuICB0cnkge1xuICAgIHdyaXRlRmlsZVN5bmMobG9ja0ZpbGVQYXRoLCBKU09OLnN0cmluZ2lmeShpbmZvKSwgeyBmbGFnOiAnd3gnIH0pO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGlmIChnZXRFcnJvckNvZGUoZXJyb3IpID09PSAnRUVYSVNUJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFvQkEscUJBS087QUFDUCxxQkFHTztBQUNQLHVCQUFxQjtBQUNyQiwwQkFBb0I7QUFFcEIsaUJBQW9CO0FBRXBCLE1BQU0sZ0JBQWdCO0FBQ3RCLE1BQU0sbUJBQW1CO0FBQ3pCLE1BQU0sZ0NBQWdDO0FBQ3RDLE1BQU0sMEJBQTBCO0FBQ2hDLE1BQU0scUJBQXFCO0FB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
271
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3NldHVwLWxvY2sudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBDcm9zcy1wcm9jZXNzIGFkdmlzb3J5IGxvY2sgdGhhdCBzZXJpYWxpemVzIHdob2xlIGludGVncmF0aW9uLXRlc3QgcnVucy5cbiAqXG4gKiBUd28gdGVzdCBydW5zIHRoYXQgZHJpdmUgdGhlIHNhbWUgc2hhcmVkIHJlc291cmNlcyBjb3JydXB0IGVhY2ggb3RoZXI6IG9uXG4gKiBkZXNrdG9wIHRoZXkgc2hhcmUgdGhlIHNpbmdsZSBsb2NhbCBPYnNpZGlhbiBpbnN0YW5jZSwgaXRzIGBvYnNpZGlhbi5qc29uYFxuICogcmVnaXN0cnksIGFuZCB0aGUgQ0RQIHBvcnQ7IG9uIEFuZHJvaWQgdGhleSBzaGFyZSB0aGUgZW11bGF0b3IgYW5kIHRoZSBBcHBpdW1cbiAqIHNlcnZlci4gT25lIHJ1bidzIHNldHVwL3RlYXJkb3duIGtpbGxzIG9yIHJlY29uZmlndXJlcyB0aGUgaW5zdGFuY2UgdGhlIG90aGVyXG4gKiBydW4gaXMgbWlkLWV2YWwgb24gKG9ic2VydmVkIGFzIGBFQ09OTlJFRlVTRURgIG9yIFwidmF1bHQgbm90IG9wZW5cIiksIHNvIGJvdGhcbiAqIHJ1bnMgZmFpbC5cbiAqXG4gKiBUaGlzIGxvY2sgbWFrZXMgdGhlIHNlY29uZCBydW4gKip3YWl0KiogZm9yIHRoZSBmaXJzdCB0byBmaW5pc2ggaW5zdGVhZCBvZlxuICogcnVubmluZyBjb25jdXJyZW50bHkuIEl0IGlzIGhlbGQgZm9yIHRoZSBlbnRpcmUgcnVuOiBhY3F1aXJlZCBhdCB0aGUgc3RhcnQgb2ZcbiAqIHRoZSBjb3JlIHNldHVwIGFuZCByZWxlYXNlZCBieSB0aGUgY29yZSB0ZWFyZG93biAoYW5kIGJ5IHRoZSBwcm9jZXNzIGNsZWFudXBcbiAqIGhhbmRsZXJzKS4gVGhlIGxvY2sgaXMgYSBzZW50aW5lbCBmaWxlIGluIGEgc2hhcmVkIHRlbXAgZGlyZWN0b3J5LCBhbmQgaXRzXG4gKiBob2xkZXIga2VlcHMgYSAqKmhlYXJ0YmVhdCoqIHRpbWVzdGFtcCBpbnNpZGUgaXQgZnJlc2ggZm9yIGFzIGxvbmcgYXMgaXQgaG9sZHNcbiAqIHRoZSBsb2NrIFx1MjAxNCBzbyBhIHJ1biB0aGF0IGNyYXNoZWQgd2l0aG91dCByZWxlYXNpbmcgc3RvcHMgYmVhdGluZyBhbmQgdGhlIG5leHRcbiAqIHJ1biBkZXRlY3RzIHRoZSBsb2NrIGFzIHN0YWxlIGFuZCBzdGVhbHMgaXQuXG4gKlxuICogVGhlIGhlYXJ0YmVhdCwgbm90IHRoZSBob2xkZXIncyBQSUQsIGlzIHdoYXQgcHJvdmVzIGEgaG9sZGVyIGlzIHN0aWxsIHRoZXJlOiBhXG4gKiBQSUQgcHJvYmUgb25seSBhbnN3ZXJzIFwiZG9lcyAqYSogcHJvY2VzcyB3aXRoIHRoaXMgUElEIGV4aXN0XCIsIHdoaWNoIGFcbiAqIHJlY3ljbGVkIFBJRCBzYXRpc2ZpZXMgbG9uZyBhZnRlciB0aGUgcmVhbCBob2xkZXIgZGllZCBcdTIwMTQgbGVhdmluZyBldmVyeSBsYXRlclxuICogcnVuIHRvIGJsb2NrIGZvciB0aGUgZnVsbCBhY3F1aXNpdGlvbiB0aW1lb3V0LlxuICovXG5cbmltcG9ydCB7XG4gIG1rZGlyU3luYyxcbiAgcmVhZEZpbGVTeW5jLFxuICBybVN5bmMsXG4gIHdyaXRlRmlsZVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBob3N0bmFtZSxcbiAgdG1wZGlyXG59IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQgeyBlcnJvclRvU3RyaW5nIH0gZnJvbSAnLi9lcnJvci10by1zdHJpbmcuY2pzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLmNqcyc7XG5cbmNvbnN0IExPQ0tfRElSX05BTUUgPSAnb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZyc7XG5jb25zdCBMT0NLX0ZJTEVfU1VGRklYID0gJy5zZXR1cC5sb2NrJztcbmNvbnN0IFBPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuY29uc3QgTUlMTElTRUNPTkRTX1BFUl9TRUNPTkQgPSAxMDAwO1xuY29uc3QgU0VDT05EU19QRVJfTUlOVVRFID0gNjA7XG5jb25zdCBIRUFSVEJFQVRfSU5URVJWQUxfSU5fU0VDT05EUyA9IDU7XG5jb25zdCBIRUFSVEJFQVRfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gSEVBUlRCRUFUX0lOVEVSVkFMX0lOX1NFQ09ORFMgKiBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORDtcbi8vIEdlbmVyb3VzIG9uIHB1cnBvc2U6IGEgZGVhZCBob2xkZXIgaXMgbm9ybWFsbHkgY2F1Z2h0IGluc3RhbnRseSBieSB0aGUgUElEXG4vLyBQcm9iZSwgc28gdGhpcyB0aHJlc2hvbGQgb25seSBoYXMgdG8gY292ZXIgdGhlIHJlY3ljbGVkLVBJRCBjYXNlLiBUd28gbWludXRlc1xuLy8gS2VlcHMgYSBob2xkZXIgdGhhdCBibG9ja3MgaXRzIGV2ZW50IGxvb3AgZHVyaW5nIGhlYXZ5IHN5bmNocm9ub3VzIHdvcmsgKGFcbi8vIExhcmdlIHZhdWx0IHN5bmMsIGFuIGluc3RhbGxlciB1bnBhY2spIGZyb20gYmVpbmcgcm9iYmVkIHdoaWxlIGl0IGlzIGFsaXZlLlxuY29uc3QgTUlTU0VEX0hFQVJUQkVBVFNfQkVGT1JFX1NUQUxFID0gMjQ7XG5jb25zdCBIRUFSVEJFQVRfU1RBTEVfSU5fTUlMTElTRUNPTkRTID0gSEVBUlRCRUFUX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyAqIE1JU1NFRF9IRUFSVEJFQVRTX0JFRk9SRV9TVEFMRTtcbmNvbnN0IFdBSVRfTE9HX0lOVEVSVkFMX0lOX1NFQ09ORFMgPSAzMDtcbmNvbnN0IFdBSVRfTE9HX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IFdBSVRfTE9HX0lOVEVSVkFMX0lOX1NFQ09ORFMgKiBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORDtcbmNvbnN0IFNUQUxFX0xPQ0tfQUdFX0lOX01JTlVURVMgPSAzMDtcbmNvbnN0IERFRkFVTFRfVElNRU9VVF9JTl9NSU5VVEVTID0gNjA7XG5jb25zdCBTVEFMRV9MT0NLX0FHRV9JTl9NSUxMSVNFQ09ORFMgPSBTVEFMRV9MT0NLX0FHRV9JTl9NSU5VVEVTICogU0VDT05EU19QRVJfTUlOVVRFICogTUlMTElTRUNPTkRTX1BFUl9TRUNPTkQ7XG5jb25zdCBERUZBVUxUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gREVGQVVMVF9USU1FT1VUX0lOX01JTlVURVMgKiBTRUNPTkRTX1BFUl9NSU5VVEUgKiBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORDtcbmNvbnN0IFBST0NFU1NfRVhJU1RFTkNFX1BST0JFX1NJR05BTCA9IDA7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGFjcXVpcmVTZXR1cExvY2t9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFjcXVpcmVTZXR1cExvY2tQYXJhbXMge1xuICAvKiogU2hvcnQgdHJhbnNwb3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMgKGUuZy4gYFwib2JzaWRpYW4tY2xpXCJgKS4gKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgICogTG9naWNhbCBzY29wZSB0aGUgbG9jayBzZXJpYWxpemVzIHdpdGhpbi4gUnVucyB0aGF0IHNoYXJlIHJlc291cmNlcyBtdXN0XG4gICAqIHVzZSB0aGUgc2FtZSBzY29wZSAoZS5nLiBgXCJkZXNrdG9wXCJgIGZvciB0aGUgQ0xJL0NEUCB0cmFuc3BvcnRzLCBgXCJhbmRyb2lkXCJgXG4gICAqIGZvciB0aGUgQXBwaXVtIHRyYW5zcG9ydCkuXG4gICAqL1xuICByZWFkb25seSBzY29wZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBNYXhpbXVtIHRpbWUgdG8gd2FpdCBmb3IgYSBjb21wZXRpbmcgcnVuIHRvIHJlbGVhc2UgdGhlIGxvY2sgYmVmb3JlIGdpdmluZ1xuICAgKiB1cCBhbmQgdGhyb3dpbmcuXG4gICAqXG4gICAqIEBkZWZhdWx0IDEgaG91clxuICAgKi9cbiAgcmVhZG9ubHkgdGltZW91dEluTWlsbGlzZWNvbmRzPzogbnVtYmVyIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEEgaGVsZCBzZXR1cCBsb2NrLiBSZWxlYXNlIGl0IG9uY2UgdGhlIHJ1bidzIHRlYXJkb3duIGlzIGNvbXBsZXRlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNldHVwTG9jayB7XG4gIC8qKiBSZWxlYXNlcyB0aGUgbG9jay4gU2FmZSB0byBjYWxsIG1vcmUgdGhhbiBvbmNlLiAqL1xuICByZWxlYXNlKCk6IHZvaWQ7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGNyZWF0ZUxvY2tIYW5kbGV9LlxuICovXG5pbnRlcmZhY2UgQ3JlYXRlTG9ja0hhbmRsZVBhcmFtcyB7XG4gIC8qKiBUaGUgdHJhbnNwb3J0IGxhYmVsIG9mIHRoaXMgcnVuLiAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKiBUaGUgcGF0aCB0byB0aGUgbG9jayBmaWxlIHRoaXMgcnVuIGp1c3QgY3JlYXRlZC4gKi9cbiAgcmVhZG9ubHkgbG9ja0ZpbGVQYXRoOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSBsb2NrIGluZm8gdGhpcyBydW4gd3JvdGUgd2hlbiBpdCBhY3F1aXJlZCB0aGUgbG9jay4gKi9cbiAgcmVhZG9ubHkgb3duSW5mbzogTG9ja0ZpbGVJbmZvO1xuXG4gIC8qKiBUaGUgbG9jayBzY29wZSwgZm9yIGxvZyBtZXNzYWdlcy4gKi9cbiAgcmVhZG9ubHkgc2NvcGU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgY3JlYXRlVGltZW91dEVycm9yfS5cbiAqL1xuaW50ZXJmYWNlIENyZWF0ZVRpbWVvdXRFcnJvclBhcmFtcyB7XG4gIC8qKiBUaGUgY3VycmVudCBob2xkZXIncyBsb2NrIGluZm8sIG9yIGBudWxsYCBpZiBpdCBjb3VsZCBub3QgYmUgcmVhZC4gKi9cbiAgcmVhZG9ubHkgaW5mbzogTG9ja0ZpbGVJbmZvIHwgbnVsbDtcblxuICAvKiogVGhlIGxvY2sgc2NvcGUuICovXG4gIHJlYWRvbmx5IHNjb3BlOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSB0aW1lb3V0IHRoYXQgZWxhcHNlZC4gKi9cbiAgcmVhZG9ubHkgdGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGZvcm1hdFdhaXRNZXNzYWdlfS5cbiAqL1xuaW50ZXJmYWNlIEZvcm1hdFdhaXRNZXNzYWdlUGFyYW1zIHtcbiAgLyoqIFRoZSBjdXJyZW50IGhvbGRlcidzIGxvY2sgaW5mbywgb3IgYG51bGxgIGlmIGl0IGNvdWxkIG5vdCBiZSByZWFkLiAqL1xuICByZWFkb25seSBpbmZvOiBMb2NrRmlsZUluZm8gfCBudWxsO1xuXG4gIC8qKiBUaGUgdHJhbnNwb3J0IGxhYmVsIG9mIHRoZSB3YWl0aW5nIHJ1bi4gKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKiogSG93IG11Y2ggb2YgdGhlIGFjcXVpc2l0aW9uIHRpbWVvdXQgaXMgbGVmdC4gKi9cbiAgcmVhZG9ubHkgcmVtYWluaW5nSW5NaWxsaXNlY29uZHM6IG51bWJlcjtcblxuICAvKiogVGhlIGxvY2sgc2NvcGUuICovXG4gIHJlYWRvbmx5IHNjb3BlOiBzdHJpbmc7XG5cbiAgLyoqIEhvdyBsb25nIHRoaXMgcnVuIGhhcyBiZWVuIHdhaXRpbmcgc28gZmFyLiAqL1xuICByZWFkb25seSB3YWl0ZWRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xufVxuXG4vKipcbiAqIFRoZSBKU09OIHBheWxvYWQgc3RvcmVkIGluc2lkZSBhIGxvY2sgZmlsZSwgaWRlbnRpZnlpbmcgdGhlIGhvbGRlci5cbiAqL1xuaW50ZXJmYWNlIExvY2tGaWxlSW5mbyB7XG4gIC8qKiBXaGVuIHRoZSBsb2NrIHdhcyBhY3F1aXJlZCAoYERhdGUubm93KClgIGVwb2NoIG1pbGxpc2Vjb25kcykuICovXG4gIHJlYWRvbmx5IGFjcXVpcmVkQXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaGVuIHRoZSBob2xkZXIgbGFzdCBwcm92ZWQgaXQgd2FzIHN0aWxsIGFsaXZlIChgRGF0ZS5ub3coKWAgZXBvY2hcbiAgICogbWlsbGlzZWNvbmRzKSwgcmVmcmVzaGVkIGV2ZXJ5IHtAbGluayBIRUFSVEJFQVRfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTfVxuICAgKiB3aGlsZSB0aGUgbG9jayBpcyBoZWxkLlxuICAgKlxuICAgKiBBYnNlbnQgaW4gYSBsb2NrIGZpbGUgd3JpdHRlbiBieSBhbiBvbGRlciB2ZXJzaW9uIG9mIHRoaXMgcGFja2FnZSwgd2hpY2hcbiAgICogc3RhbXBlZCB0aGUgUElEIGJ1dCBuZXZlciBiZWF0LlxuICAgKi9cbiAgcmVhZG9ubHkgaGVhcnRiZWF0QXRJbk1pbGxpc2Vjb25kcz86IG51bWJlciB8IHVuZGVmaW5lZDtcblxuICAvKiogVGhlIGhvc3QgdGhhdCBob2xkcyB0aGUgbG9jayAoUElEIGxpdmVuZXNzIGlzIG9ubHkgdmFsaWQgb24gdGhlIHNhbWUgaG9zdCkuICovXG4gIHJlYWRvbmx5IGhvc3RuYW1lOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSB0cmFuc3BvcnQgbGFiZWwgb2YgdGhlIGhvbGRpbmcgcnVuLiAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKiBUaGUgcHJvY2VzcyBJRCBvZiB0aGUgaG9sZGluZyBydW4uICovXG4gIHJlYWRvbmx5IHBpZDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayByZWZyZXNoSGVhcnRiZWF0fS5cbiAqL1xuaW50ZXJmYWNlIFJlZnJlc2hIZWFydGJlYXRQYXJhbXMge1xuICAvKiogVGhlIHRyYW5zcG9ydCBsYWJlbCBvZiB0aGlzIHJ1bi4gKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKiogVGhlIHBhdGggdG8gdGhlIGxvY2sgZmlsZSB0byByZWZyZXNoLiAqL1xuICByZWFkb25seSBsb2NrRmlsZVBhdGg6IHN0cmluZztcblxuICAvKiogVGhlIGxvY2sgaW5mbyB0aGlzIHJ1biB3cm90ZSB3aGVuIGl0IGFjcXVpcmVkIHRoZSBsb2NrLiAqL1xuICByZWFkb25seSBvd25JbmZvOiBMb2NrRmlsZUluZm87XG59XG5cbi8qKlxuICogQWNxdWlyZXMgdGhlIGNyb3NzLXByb2Nlc3Mgc2V0dXAgbG9jayBmb3IgdGhlIGdpdmVuIHNjb3BlLCB3YWl0aW5nIHVudGlsIGFueVxuICogY29tcGV0aW5nIHJ1biByZWxlYXNlcyBpdCAob3IgaXRzIGxvY2sgaXMgZGV0ZWN0ZWQgYXMgc3RhbGUpLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgbG9jayBwYXJhbWV0ZXJzLlxuICogQHJldHVybnMgQSBoYW5kbGUgd2hvc2Uge0BsaW5rIFNldHVwTG9jay5yZWxlYXNlfSBmcmVlcyB0aGUgbG9jay5cbiAqIEB0aHJvd3MgSWYgdGhlIGxvY2sgY2Fubm90IGJlIGFjcXVpcmVkIHdpdGhpbiBgdGltZW91dEluTWlsbGlzZWNvbmRzYC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFjcXVpcmVTZXR1cExvY2socGFyYW1zOiBBY3F1aXJlU2V0dXBMb2NrUGFyYW1zKTogUHJvbWlzZTxTZXR1cExvY2s+IHtcbiAgY29uc3Qge1xuICAgIGxhYmVsLFxuICAgIHNjb3BlXG4gIH0gPSBwYXJhbXM7XG4gIGNvbnN0IHRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IHBhcmFtcy50aW1lb3V0SW5NaWxsaXNlY29uZHMgPz8gREVGQVVMVF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgY29uc3QgbG9ja0ZpbGVQYXRoID0gZ2V0TG9ja0ZpbGVQYXRoKHNjb3BlKTtcbiAgbWtkaXJTeW5jKGdldExvY2tEaXIoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgY29uc3Qgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMgPSBEYXRlLm5vdygpO1xuICBjb25zdCBkZWFkbGluZUluTWlsbGlzZWNvbmRzID0gc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMgKyB0aW1lb3V0SW5NaWxsaXNlY29uZHM7XG4gIGxldCBsYXN0TG9nZ2VkV2FpdEF0SW5NaWxsaXNlY29uZHM6IG51bGwgfCBudW1iZXIgPSBudWxsO1xuXG4gIGZvciAoOzspIHtcbiAgICBjb25zdCBvd25JbmZvID0gdHJ5Q3JlYXRlTG9ja0ZpbGUobG9ja0ZpbGVQYXRoLCBsYWJlbCk7XG4gICAgaWYgKG93bkluZm8pIHtcbiAgICAgIHJldHVybiBjcmVhdGVMb2NrSGFuZGxlKHtcbiAgICAgICAgbGFiZWwsXG4gICAgICAgIGxvY2tGaWxlUGF0aCxcbiAgICAgICAgb3duSW5mbyxcbiAgICAgICAgc2NvcGVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGluZm8gPSByZWFkTG9ja0ZpbGVJbmZvKGxvY2tGaWxlUGF0aCk7XG4gICAgaWYgKGluZm8gJiYgY2hlY2tJc0xvY2tTdGFsZShpbmZvKSkge1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFN0ZWFsaW5nIHN0YWxlICcke3Njb3BlfScgc2V0dXAgbG9jayBmcm9tICR7ZGVzY3JpYmVJbmZvKGluZm8pfS5gKTtcbiAgICAgIHJtU3luYyhsb2NrRmlsZVBhdGgsIHsgZm9yY2U6IHRydWUgfSk7XG4gICAgICAvLyBSZXRyeSBpbW1lZGlhdGVseSBcdTIwMTQgYnV0IHN0aWxsIGhvbm91ciB0aGUgZGVhZGxpbmUsIHNvIGEgbG9jayB0aGF0IGFcbiAgICAgIC8vIENvbXBldGluZyBydW4ga2VlcHMgcmVjcmVhdGluZyBjYW5ub3Qgc3BpbiB0aGlzIGxvb3AgZm9yZXZlci5cbiAgICAgIGlmIChEYXRlLm5vdygpID49IGRlYWRsaW5lSW5NaWxsaXNlY29uZHMpIHtcbiAgICAgICAgdGhyb3cgY3JlYXRlVGltZW91dEVycm9yKHtcbiAgICAgICAgICBpbmZvLFxuICAgICAgICAgIHNjb3BlLFxuICAgICAgICAgIHRpbWVvdXRJbk1pbGxpc2Vjb25kc1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IG5vd0luTWlsbGlzZWNvbmRzID0gRGF0ZS5ub3coKTtcbiAgICBpZiAobm93SW5NaWxsaXNlY29uZHMgPj0gZGVhZGxpbmVJbk1pbGxpc2Vjb25kcykge1xuICAgICAgdGhyb3cgY3JlYXRlVGltZW91dEVycm9yKHtcbiAgICAgICAgaW5mbyxcbiAgICAgICAgc2NvcGUsXG4gICAgICAgIHRpbWVvdXRJbk1pbGxpc2Vjb25kc1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2hvdWxkTG9nV2FpdCA9IGxhc3RMb2dnZWRXYWl0QXRJbk1pbGxpc2Vjb25kcyA9PT0gbnVsbFxuICAgICAgfHwgbm93SW5NaWxsaXNlY29uZHMgLSBsYXN0TG9nZ2VkV2FpdEF0SW5NaWxsaXNlY29uZHMgPj0gV0FJVF9MT0dfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTO1xuICAgIGlmIChzaG91bGRMb2dXYWl0KSB7XG4gICAgICBsYXN0TG9nZ2VkV2FpdEF0SW5NaWxsaXNlY29uZHMgPSBub3dJbk1pbGxpc2Vjb25kcztcbiAgICAgIGxvZyhmb3JtYXRXYWl0TWVzc2FnZSh7XG4gICAgICAgIGluZm8sXG4gICAgICAgIGxhYmVsLFxuICAgICAgICByZW1haW5pbmdJbk1pbGxpc2Vjb25kczogZGVhZGxpbmVJbk1pbGxpc2Vjb25kcyAtIG5vd0luTWlsbGlzZWNvbmRzLFxuICAgICAgICBzY29wZSxcbiAgICAgICAgd2FpdGVkSW5NaWxsaXNlY29uZHM6IG5vd0luTWlsbGlzZWNvbmRzIC0gc3RhcnRlZEF0SW5NaWxsaXNlY29uZHNcbiAgICAgIH0pKTtcbiAgICB9XG5cbiAgICBhd2FpdCBkZWxheShQT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgYSBsb2NrIGNhbiBiZSBjb25zaWRlcmVkIGFiYW5kb25lZC5cbiAqXG4gKiBBIGxpdmUgaG9sZGVyIHJlZnJlc2hlcyBpdHMgaGVhcnRiZWF0IGV2ZXJ5XG4gKiB7QGxpbmsgSEVBUlRCRUFUX0lOVEVSVkFMX0lOX01JTExJU0VDT05EU30sIHNvIGEgaGVhcnRiZWF0IHRoYXQgc3RvcHBlZCBtZWFuc1xuICogdGhlIGhvbGRlciBpcyBnb25lLiBUaGF0IGlzIHRoZSBwcmltYXJ5IHNpZ25hbCwgYmVjYXVzZSB0aGUgcmVjb3JkZWQgUElEIGFsb25lXG4gKiBjYW5ub3QgYmUgdHJ1c3RlZDoge0BsaW5rIGNoZWNrSXNQcm9jZXNzQWxpdmV9IG9ubHkgYW5zd2VycyBcImRvZXMgKmEqIHByb2Nlc3NcbiAqIHdpdGggdGhpcyBQSUQgZXhpc3RcIiwgd2hpY2ggYSByZWN5Y2xlZCBQSUQgc2F0aXNmaWVzIGxvbmcgYWZ0ZXIgdGhlIGhvbGRlclxuICogZGllZC5cbiAqXG4gKiBPbiB0aGUgc2FtZSBob3N0IGEgZGVhZCBQSUQgaXMgc3RpbGwgYW4gaW1tZWRpYXRlIGdpdmUtYXdheSwgc28gaXQgaXMga2VwdCBhc1xuICogYSBmYXN0IHBhdGguIE9uIGEgZGlmZmVyZW50IGhvc3QgKGEgc2hhcmVkL25ldHdvcmsgdGVtcCBkaXJlY3RvcnkpIHRoZSBQSURcbiAqIGNhbm5vdCBiZSBwcm9iZWQgYXQgYWxsIGFuZCB0aGUgdHdvIGNsb2NrcyBtYXkgZGlzYWdyZWUsIHNvIHRoZSBtdWNoIHdpZGVyXG4gKiB7QGxpbmsgU1RBTEVfTE9DS19BR0VfSU5fTUlMTElTRUNPTkRTfSB0aHJlc2hvbGQgaXMgdXNlZCBpbnN0ZWFkLlxuICpcbiAqIEBwYXJhbSBpbmZvIC0gVGhlIHBhcnNlZCBsb2NrIGluZm8uXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGxvY2sgaXMgc3RhbGUgYW5kIG1heSBiZSBzdG9sZW4uXG4gKi9cbmZ1bmN0aW9uIGNoZWNrSXNMb2NrU3RhbGUoaW5mbzogTG9ja0ZpbGVJbmZvKTogYm9vbGVhbiB7XG4gIGNvbnN0IHNpbGVudEZvckluTWlsbGlzZWNvbmRzID0gRGF0ZS5ub3coKSAtIGdldExhc3RTZWVuQXRJbk1pbGxpc2Vjb25kcyhpbmZvKTtcblxuICBpZiAoaW5mby5ob3N0bmFtZSA9PT0gaG9zdG5hbWUoKSkge1xuICAgIHJldHVybiAhY2hlY2tJc1Byb2Nlc3NBbGl2ZShpbmZvLnBpZCkgfHwgc2lsZW50Rm9ySW5NaWxsaXNlY29uZHMgPiBIRUFSVEJFQVRfU1RBTEVfSU5fTUlMTElTRUNPTkRTO1xuICB9XG5cbiAgcmV0dXJuIHNpbGVudEZvckluTWlsbGlzZWNvbmRzID4gU1RBTEVfTE9DS19BR0VfSU5fTUlMTElTRUNPTkRTO1xufVxuXG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciBhIGxvY2sgZmlsZSBzdGlsbCBuYW1lcyB0aGlzIHByb2Nlc3MgYXMgaXRzIGhvbGRlci5cbiAqXG4gKiBAcGFyYW0gaW5mbyAtIFRoZSBwYXJzZWQgbG9jayBpbmZvLlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoaXMgcHJvY2VzcyBob2xkcyB0aGUgbG9jay5cbiAqL1xuZnVuY3Rpb24gY2hlY2tJc093bkxvY2soaW5mbzogTG9ja0ZpbGVJbmZvKTogYm9vbGVhbiB7XG4gIHJldHVybiBpbmZvLnBpZCA9PT0gcHJvY2Vzcy5waWQgJiYgaW5mby5ob3N0bmFtZSA9PT0gaG9zdG5hbWUoKTtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIHByb2Nlc3Mgd2l0aCB0aGUgZ2l2ZW4gUElEIGlzIGN1cnJlbnRseSBhbGl2ZS5cbiAqXG4gKiBAcGFyYW0gcGlkIC0gVGhlIHByb2Nlc3MgSUQgdG8gcHJvYmUuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHByb2Nlc3MgZXhpc3RzLlxuICovXG5mdW5jdGlvbiBjaGVja0lzUHJvY2Vzc0FsaXZlKHBpZDogbnVtYmVyKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgcHJvY2Vzcy5raWxsKHBpZCwgUFJPQ0VTU19FWElTVEVOQ0VfUFJPQkVfU0lHTkFMKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAvLyBgRVBFUk1gIG1lYW5zIHRoZSBwcm9jZXNzIGV4aXN0cyBidXQgaXMgb3duZWQgYnkgYW5vdGhlciB1c2VyIFx1MjAxNCBzdGlsbCBhbGl2ZS5cbiAgICByZXR1cm4gZ2V0RXJyb3JDb2RlKGVycm9yKSA9PT0gJ0VQRVJNJztcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSB7QGxpbmsgU2V0dXBMb2NrfSBoYW5kbGUgdGhhdCBrZWVwcyB0aGUgbG9jaydzIGhlYXJ0YmVhdCBmcmVzaCB3aGlsZVxuICogaGVsZCBhbmQgcmVtb3ZlcyB0aGUgbG9jayBmaWxlIG9uIHJlbGVhc2UuXG4gKlxuICogVGhlIGhlYXJ0YmVhdCB0aW1lciBpcyBgdW5yZWZgZWQgc28gaXQgY2FuIG5ldmVyIGtlZXAgdGhlIHByb2Nlc3MgYWxpdmUgb24gaXRzXG4gKiBvd24sIGFuZCBpdCBzdG9wcyBhcyBzb29uIGFzIHRoZSBsb2NrIGZpbGUgbmFtZXMgc29tZWJvZHkgZWxzZSBcdTIwMTQgYSBydW4gd2hvc2VcbiAqIGxvY2sgd2FzIHN0b2xlbiBtdXN0IG5vdCBvdmVyd3JpdGUgaXRzIHN1Y2Nlc3NvcidzIGxvY2ssIG5vciBkZWxldGUgaXQgb25cbiAqIHJlbGVhc2UuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBoYW5kbGUgcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIFRoZSBsb2NrIGhhbmRsZS5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlTG9ja0hhbmRsZShwYXJhbXM6IENyZWF0ZUxvY2tIYW5kbGVQYXJhbXMpOiBTZXR1cExvY2sge1xuICBjb25zdCB7XG4gICAgbGFiZWwsXG4gICAgbG9ja0ZpbGVQYXRoLFxuICAgIG93bkluZm8sXG4gICAgc2NvcGVcbiAgfSA9IHBhcmFtcztcbiAgbGV0IGlzUmVsZWFzZWQgPSBmYWxzZTtcblxuICBjb25zdCBoZWFydGJlYXRUaW1lciA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICBjb25zdCBpc1N0aWxsT3VycyA9IHJlZnJlc2hIZWFydGJlYXQoe1xuICAgICAgbGFiZWwsXG4gICAgICBsb2NrRmlsZVBhdGgsXG4gICAgICBvd25JbmZvXG4gICAgfSk7XG4gICAgaWYgKGlzU3RpbGxPdXJzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNsZWFySW50ZXJ2YWwoaGVhcnRiZWF0VGltZXIpO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBUaGUgJyR7c2NvcGV9JyBzZXR1cCBsb2NrIGlzIG5vIGxvbmdlciBvdXJzIFx1MjAxNCBhbm90aGVyIHJ1biB0b29rIGl0IG92ZXIuIEhlYXJ0YmVhdCBzdG9wcGVkLmApO1xuICB9LCBIRUFSVEJFQVRfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgaGVhcnRiZWF0VGltZXIudW5yZWYoKTtcblxuICByZXR1cm4ge1xuICAgIHJlbGVhc2UoKTogdm9pZCB7XG4gICAgICBpZiAoaXNSZWxlYXNlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpc1JlbGVhc2VkID0gdHJ1ZTtcbiAgICAgIGNsZWFySW50ZXJ2YWwoaGVhcnRiZWF0VGltZXIpO1xuXG4gICAgICBjb25zdCBpbmZvID0gcmVhZExvY2tGaWxlSW5mbyhsb2NrRmlsZVBhdGgpO1xuICAgICAgaWYgKGluZm8gJiYgIWNoZWNrSXNPd25Mb2NrKGluZm8pKSB7XG4gICAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBMZWF2aW5nIHRoZSAnJHtzY29wZX0nIHNldHVwIGxvY2sgaW4gcGxhY2UgXHUyMDE0IGl0IG5vdyBiZWxvbmdzIHRvICR7ZGVzY3JpYmVJbmZvKGluZm8pfS5gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcm1TeW5jKGxvY2tGaWxlUGF0aCwgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBlcnJvciB0aHJvd24gd2hlbiB0aGUgbG9jayBjb3VsZCBub3QgYmUgYWNxdWlyZWQgaW4gdGltZS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGVycm9yIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyBUaGUgZXJyb3IgdG8gdGhyb3cuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVRpbWVvdXRFcnJvcihwYXJhbXM6IENyZWF0ZVRpbWVvdXRFcnJvclBhcmFtcyk6IEVycm9yIHtcbiAgY29uc3Qge1xuICAgIGluZm8sXG4gICAgc2NvcGUsXG4gICAgdGltZW91dEluTWlsbGlzZWNvbmRzXG4gIH0gPSBwYXJhbXM7XG4gIHJldHVybiBuZXcgRXJyb3IoXG4gICAgYFRpbWVkIG91dCBhZnRlciAke1N0cmluZyh0aW1lb3V0SW5NaWxsaXNlY29uZHMpfW1zIHdhaXRpbmcgZm9yIHRoZSAnJHtzY29wZX0nIGludGVncmF0aW9uLXRlc3Qgc2V0dXAgbG9jayBgXG4gICAgICArIGBoZWxkIGJ5ICR7ZGVzY3JpYmVIb2xkZXIoaW5mbyl9LiBBbm90aGVyIGludGVncmF0aW9uLXRlc3QgcnVuIGlzIHN0aWxsIGluIHByb2dyZXNzLmBcbiAgKTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBhZnRlciB0aGUgZ2l2ZW4gZGVsYXkuIFVzZWQgdG8gcG9sbCBiZXR3ZWVuIGxvY2stYWNxdWlzaXRpb24gYXR0ZW1wdHMuXG4gKlxuICogQHBhcmFtIG1pbGxpc2Vjb25kcyAtIFRoZSBkZWxheSBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgZGVsYXkuXG4gKi9cbmZ1bmN0aW9uIGRlbGF5KG1pbGxpc2Vjb25kczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgbWlsbGlzZWNvbmRzKTtcbiAgfSk7XG59XG5cbi8qKlxuICogQnVpbGRzIGEgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhlIGN1cnJlbnQgbG9jayBob2xkZXIgZm9yIGxvZy9lcnJvclxuICogbWVzc2FnZXMuXG4gKlxuICogQHBhcmFtIGluZm8gLSBUaGUgcGFyc2VkIGxvY2sgaW5mbywgb3IgYG51bGxgIGlmIGl0IGNvdWxkIG5vdCBiZSByZWFkLlxuICogQHJldHVybnMgQSBkZXNjcmlwdGlvbiBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGRlc2NyaWJlSG9sZGVyKGluZm86IExvY2tGaWxlSW5mbyB8IG51bGwpOiBzdHJpbmcge1xuICByZXR1cm4gaW5mbyA/IGRlc2NyaWJlSW5mbyhpbmZvKSA6ICdhbm90aGVyIHJ1bic7XG59XG5cbi8qKlxuICogRm9ybWF0cyBhIHtAbGluayBMb2NrRmlsZUluZm99IGFzIGEgc2hvcnQgaWRlbnRpZmllciBzdHJpbmcuXG4gKlxuICogQHBhcmFtIGluZm8gLSBUaGUgbG9jayBpbmZvLlxuICogQHJldHVybnMgQSBzdHJpbmcgbGlrZSBgcGlkIDEyMzQgKG9ic2lkaWFuLWNsaSkgb24gaG9zdGAuXG4gKi9cbmZ1bmN0aW9uIGRlc2NyaWJlSW5mbyhpbmZvOiBMb2NrRmlsZUluZm8pOiBzdHJpbmcge1xuICByZXR1cm4gYHBpZCAke1N0cmluZyhpbmZvLnBpZCl9ICgke2luZm8ubGFiZWx9KSBvbiAke2luZm8uaG9zdG5hbWV9YDtcbn1cblxuLyoqXG4gKiBGb3JtYXRzIGEgZHVyYXRpb24gYXMgYSBjb21wYWN0IGAxbSAzMHNgIC8gYDQ1c2Agc3RyaW5nIGZvciBwcm9ncmVzcyBsb2dzLlxuICpcbiAqIEBwYXJhbSBtaWxsaXNlY29uZHMgLSBUaGUgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLlxuICogQHJldHVybnMgVGhlIGZvcm1hdHRlZCBkdXJhdGlvbi5cbiAqL1xuZnVuY3Rpb24gZm9ybWF0RHVyYXRpb24obWlsbGlzZWNvbmRzOiBudW1iZXIpOiBzdHJpbmcge1xuICBjb25zdCB0b3RhbFNlY29uZHMgPSBNYXRoLnJvdW5kKG1pbGxpc2Vjb25kcyAvIE1JTExJU0VDT05EU19QRVJfU0VDT05EKTtcbiAgY29uc3QgbWludXRlcyA9IE1hdGguZmxvb3IodG90YWxTZWNvbmRzIC8gU0VDT05EU19QRVJfTUlOVVRFKTtcbiAgY29uc3Qgc2Vjb25kcyA9IHRvdGFsU2Vjb25kcyAlIFNFQ09ORFNfUEVSX01JTlVURTtcbiAgcmV0dXJuIG1pbnV0ZXMgPiAwID8gYCR7U3RyaW5nKG1pbnV0ZXMpfW0gJHtTdHJpbmcoc2Vjb25kcyl9c2AgOiBgJHtTdHJpbmcoc2Vjb25kcyl9c2A7XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBwZXJpb2RpYyBcInN0aWxsIHdhaXRpbmdcIiBwcm9ncmVzcyBsaW5lLCBzbyBhIGxlZ2l0aW1hdGUgbXVsdGktbWludXRlXG4gKiB3YWl0IGlzIGRpc3Rpbmd1aXNoYWJsZSBmcm9tIGEgaGFuZyBpbiB0aGUgdGVybWluYWwuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBtZXNzYWdlIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyBUaGUgbWVzc2FnZSB0byBsb2cuXG4gKi9cbmZ1bmN0aW9uIGZvcm1hdFdhaXRNZXNzYWdlKHBhcmFtczogRm9ybWF0V2FpdE1lc3NhZ2VQYXJhbXMpOiBzdHJpbmcge1xuICBjb25zdCB7XG4gICAgaW5mbyxcbiAgICBsYWJlbCxcbiAgICByZW1haW5pbmdJbk1pbGxpc2Vjb25kcyxcbiAgICBzY29wZSxcbiAgICB3YWl0ZWRJbk1pbGxpc2Vjb25kc1xuICB9ID0gcGFyYW1zO1xuICBjb25zdCBoZWxkRm9yID0gaW5mbyA/IGAsIGhlbGQgZm9yICR7Zm9ybWF0RHVyYXRpb24oRGF0ZS5ub3coKSAtIGluZm8uYWNxdWlyZWRBdEluTWlsbGlzZWNvbmRzKX1gIDogJyc7XG4gIHJldHVybiBgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBXYWl0aW5nIGZvciB0aGUgJyR7c2NvcGV9JyBzZXR1cCBsb2NrIGhlbGQgYnkgJHtkZXNjcmliZUhvbGRlcihpbmZvKX0gdG8gYmUgcmVsZWFzZWQgYFxuICAgICsgYCh3YWl0ZWQgJHtmb3JtYXREdXJhdGlvbih3YWl0ZWRJbk1pbGxpc2Vjb25kcyl9JHtoZWxkRm9yfSwgZ2l2aW5nIHVwIGluICR7Zm9ybWF0RHVyYXRpb24ocmVtYWluaW5nSW5NaWxsaXNlY29uZHMpfSkuLi5gO1xufVxuXG4vKipcbiAqIEV4dHJhY3RzIHRoZSBgY29kZWAgZnJvbSBhIE5vZGUuanMgc3lzdGVtIGVycm9yLCBpZiBwcmVzZW50LlxuICpcbiAqIEBwYXJhbSBlcnJvciAtIFRoZSB0aHJvd24gdmFsdWUuXG4gKiBAcmV0dXJucyBUaGUgZXJyb3IgY29kZSBzdHJpbmcsIG9yIGB1bmRlZmluZWRgIGlmIG5vdCBhIGNvZGVkIGVycm9yLlxuICovXG5mdW5jdGlvbiBnZXRFcnJvckNvZGUoZXJyb3I6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiAnY29kZScgaW4gZXJyb3IgJiYgdHlwZW9mIGVycm9yLmNvZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGVycm9yLmNvZGU7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHdoZW4gdGhlIGhvbGRlciB3YXMgbGFzdCBrbm93biB0byBiZSBhbGl2ZSBcdTIwMTQgaXRzIG1vc3QgcmVjZW50IGhlYXJ0YmVhdCxcbiAqIGZhbGxpbmcgYmFjayB0byBpdHMgYWNxdWlzaXRpb24gdGltZSBmb3IgYSBsb2NrIGZpbGUgd3JpdHRlbiBieSBhbiBvbGRlclxuICogdmVyc2lvbiBvZiB0aGlzIHBhY2thZ2UgdGhhdCBzdGFtcGVkIG5vIGhlYXJ0YmVhdCBhdCBhbGwuXG4gKlxuICogQHBhcmFtIGluZm8gLSBUaGUgcGFyc2VkIGxvY2sgaW5mby5cbiAqIEByZXR1cm5zIFRoZSBlcG9jaCBtaWxsaXNlY29uZHMgb2YgdGhlIGhvbGRlcidzIGxhc3Qgc2lnbiBvZiBsaWZlLlxuICovXG5mdW5jdGlvbiBnZXRMYXN0U2VlbkF0SW5NaWxsaXNlY29uZHMoaW5mbzogTG9ja0ZpbGVJbmZvKTogbnVtYmVyIHtcbiAgcmV0dXJuIGluZm8uaGVhcnRiZWF0QXRJbk1pbGxpc2Vjb25kcyA/PyBpbmZvLmFjcXVpcmVkQXRJbk1pbGxpc2Vjb25kcztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzaGFyZWQgbG9jayBkaXJlY3RvcnkgaW5zaWRlIHRoZSBPUyB0ZW1wIGRpcmVjdG9yeS5cbiAqXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgbG9jayBkaXJlY3RvcnkuXG4gKi9cbmZ1bmN0aW9uIGdldExvY2tEaXIoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4odG1wZGlyKCksIExPQ0tfRElSX05BTUUpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGxvY2sgZmlsZSBwYXRoIGZvciB0aGUgZ2l2ZW4gc2NvcGUuXG4gKlxuICogQHBhcmFtIHNjb3BlIC0gVGhlIGxvY2sgc2NvcGUuXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgc2NvcGUncyBsb2NrIGZpbGUuXG4gKi9cbmZ1bmN0aW9uIGdldExvY2tGaWxlUGF0aChzY29wZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4oZ2V0TG9ja0RpcigpLCBgJHtzY29wZX0ke0xPQ0tfRklMRV9TVUZGSVh9YCk7XG59XG5cbi8qKlxuICogUmVhZHMgYW5kIHBhcnNlcyB0aGUgbG9jayBmaWxlLCBpZiBpdCBleGlzdHMgYW5kIGlzIHZhbGlkIEpTT04uXG4gKlxuICogQHBhcmFtIGxvY2tGaWxlUGF0aCAtIFRoZSBwYXRoIHRvIHRoZSBsb2NrIGZpbGUuXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIGxvY2sgaW5mbywgb3IgYG51bGxgIGlmIGl0IGNvdWxkIG5vdCBiZSByZWFkLlxuICovXG5mdW5jdGlvbiByZWFkTG9ja0ZpbGVJbmZvKGxvY2tGaWxlUGF0aDogc3RyaW5nKTogTG9ja0ZpbGVJbmZvIHwgbnVsbCB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UocmVhZEZpbGVTeW5jKGxvY2tGaWxlUGF0aCwgJ3V0Zi04JykpIGFzIExvY2tGaWxlSW5mbztcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXdyaXRlcyB0aGUgbG9jayBmaWxlIHdpdGggYSBmcmVzaCBoZWFydGJlYXQgdGltZXN0YW1wLCBzbyB3YWl0aW5nIHJ1bnMgY2FuXG4gKiB0ZWxsIHRoaXMgaG9sZGVyIGFwYXJ0IGZyb20gYSBjcmFzaGVkIG9uZSB3aG9zZSBQSUQgaGFzIGJlZW4gcmVjeWNsZWQuXG4gKlxuICogQSBsb2NrIGZpbGUgdGhhdCBpcyBtaXNzaW5nIG9yIHVucmVhZGFibGUgaXMgc3RpbGwgdHJlYXRlZCBhcyBvdXJzIGFuZCByZXdyaXR0ZW46XG4gKiB0aGlzIHJ1biBuZXZlciByZWxlYXNlZCwgc28gaXRzIGNsYWltIHN0YW5kcy5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHJlZnJlc2ggcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIGB0cnVlYCB3aGlsZSB0aGUgbG9jayBpcyBzdGlsbCBvdXJzLCBgZmFsc2VgIG9uY2UgYW5vdGhlciBydW4gb3ducyBpdC5cbiAqL1xuZnVuY3Rpb24gcmVmcmVzaEhlYXJ0YmVhdChwYXJhbXM6IFJlZnJlc2hIZWFydGJlYXRQYXJhbXMpOiBib29sZWFuIHtcbiAgY29uc3Qge1xuICAgIGxhYmVsLFxuICAgIGxvY2tGaWxlUGF0aCxcbiAgICBvd25JbmZvXG4gIH0gPSBwYXJhbXM7XG5cbiAgY29uc3QgaW5mbyA9IHJlYWRMb2NrRmlsZUluZm8obG9ja0ZpbGVQYXRoKTtcbiAgaWYgKGluZm8gJiYgIWNoZWNrSXNPd25Mb2NrKGluZm8pKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgcmVmcmVzaGVkSW5mbzogTG9ja0ZpbGVJbmZvID0ge1xuICAgIC4uLm93bkluZm8sXG4gICAgaGVhcnRiZWF0QXRJbk1pbGxpc2Vjb25kczogRGF0ZS5ub3coKVxuICB9O1xuICB0cnkge1xuICAgIHdyaXRlRmlsZVN5bmMobG9ja0ZpbGVQYXRoLCBKU09OLnN0cmluZ2lmeShyZWZyZXNoZWRJbmZvKSk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgLy8gTm90IGZhdGFsOiB0aGUgbG9jayBpcyBzdGlsbCBoZWxkIGFuZCB3aWxsIHN0aWxsIGJlIHJlbGVhc2VkLiBPbmx5IGl0c1xuICAgIC8vIEhlYXJ0YmVhdCBnb2VzIHN0YWxlLCB3aGljaCBhdCB3b3JzdCBsZXRzIGEgd2FpdGluZyBydW4gc3RlYWwgaXQuXG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIEZhaWxlZCB0byByZWZyZXNoIHRoZSBzZXR1cCBsb2NrIGhlYXJ0YmVhdDogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBBdHRlbXB0cyB0byBhdG9taWNhbGx5IGNyZWF0ZSB0aGUgbG9jayBmaWxlIChmYWlsaW5nIGlmIGl0IGFscmVhZHkgZXhpc3RzKS5cbiAqXG4gKiBAcGFyYW0gbG9ja0ZpbGVQYXRoIC0gVGhlIHBhdGggdG8gdGhlIGxvY2sgZmlsZS5cbiAqIEBwYXJhbSBsYWJlbCAtIFRoZSB0cmFuc3BvcnQgbGFiZWwgdG8gcmVjb3JkIGluIHRoZSBsb2NrIGZpbGUuXG4gKiBAcmV0dXJucyBUaGUgbG9jayBpbmZvIHdyaXR0ZW4gb24gc3VjY2Vzcywgb3IgYG51bGxgIGlmIHRoZSBsb2NrIGlzIGFscmVhZHkgaGVsZC5cbiAqIEB0aHJvd3MgSWYgdGhlIGZpbGUgc3lzdGVtIGZhaWxzIGZvciBhbnkgcmVhc29uIG90aGVyIHRoYW4gdGhlIGZpbGUgZXhpc3RpbmcuXG4gKi9cbmZ1bmN0aW9uIHRyeUNyZWF0ZUxvY2tGaWxlKGxvY2tGaWxlUGF0aDogc3RyaW5nLCBsYWJlbDogc3RyaW5nKTogTG9ja0ZpbGVJbmZvIHwgbnVsbCB7XG4gIGNvbnN0IG5vd0luTWlsbGlzZWNvbmRzID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgaW5mbzogTG9ja0ZpbGVJbmZvID0ge1xuICAgIGFjcXVpcmVkQXRJbk1pbGxpc2Vjb25kczogbm93SW5NaWxsaXNlY29uZHMsXG4gICAgaGVhcnRiZWF0QXRJbk1pbGxpc2Vjb25kczogbm93SW5NaWxsaXNlY29uZHMsXG4gICAgaG9zdG5hbWU6IGhvc3RuYW1lKCksXG4gICAgbGFiZWwsXG4gICAgcGlkOiBwcm9jZXNzLnBpZFxuICB9O1xuXG4gIHRyeSB7XG4gICAgd3JpdGVGaWxlU3luYyhsb2NrRmlsZVBhdGgsIEpTT04uc3RyaW5naWZ5KGluZm8pLCB7IGZsYWc6ICd3eCcgfSk7XG4gICAgcmV0dXJuIGluZm87XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgaWYgKGdldEVycm9yQ29kZShlcnJvcikgPT09ICdFRVhJU1QnKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBMEJBLHFCQUtPO0FBQ1AscUJBR087QUFDUCx1QkFBcUI7QUFDckIsMEJBQW9CO0FBRXBCLDZCQUE4QjtBQUM5QixpQkFBb0I7QUFFcEIsTUFBTSxnQkFBZ0I7QUFDdEIsTUFBTSxtQkFBbUI7QUFDekIsTUFBTSxnQ0FBZ0M7QUFDdEMsTUFBTSwwQkFBMEI7QUFDaEMsTUFBTSxxQkFBcUI7QUFDM0IsTUFBTSxnQ0FBZ0M7QUFDdEMsTUFBTSxxQ0FBcUMsZ0NBQWdDO0FBSzNFLE1BQU0saUNBQWlDO0FBQ3ZDLE1BQU0sa0NBQWtDLHFDQUFxQztBQUM3RSxNQUFNLCtCQUErQjtBQUNyQyxNQUFNLG9DQUFvQywrQkFBK0I7QUFDekUsTUFBTSw0QkFBNEI7QUFDbEMsTUFBTSw2QkFBNkI7QUFDbkMsTUFBTSxpQ0FBaUMsNEJBQTRCLHFCQUFxQjtBQUN4RixNQUFNLGtDQUFrQyw2QkFBNkIscUJBQXFCO0FBQzFGLE1BQU0saUNBQWlDO0FBcUl2QyxlQUFzQixpQkFBaUIsUUFBb0Q7QUFDekYsUUFBTTtBQUFBLElBQ0o7QUFBQSxJQUNBO0FBQUEsRUFDRixJQUFJO0FBQ0osUUFBTSx3QkFBd0IsT0FBTyx5QkFBeUI7QUFDOUQsUUFBTSxlQUFlLGdCQUFnQixLQUFLO0FBQzFDLGdDQUFVLFdBQVcsR0FBRyxFQUFFLFdBQVcsS0FBSyxDQUFDO0FBRTNDLFFBQU0sMEJBQTBCLEtBQUssSUFBSTtBQUN6QyxRQUFNLHlCQUF5QiwwQkFBMEI7QUFDekQsTUFBSSxpQ0FBZ0Q7QUFFcEQsYUFBUztBQUNQLFVBQU0sVUFBVSxrQkFBa0IsY0FBYyxLQUFLO0FBQ3JELFFBQUksU0FBUztBQUNYLGFBQU8saUJBQWlCO0FBQUEsUUFDdEI7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxNQUNGLENBQUM7QUFBQSxJQUNIO0FBRUEsVUFBTSxPQUFPLGlCQUFpQixZQUFZO0FBQzFDLFFBQUksUUFBUSxpQkFBaUIsSUFBSSxHQUFHO0FBQ2xDLDBCQUFJLHNCQUFzQixLQUFLLHFCQUFxQixLQUFLLHFCQUFxQixhQUFhLElBQUksQ0FBQyxHQUFHO0FBQ25HLGlDQUFPLGNBQWMsRUFBRSxPQUFPLEtBQUssQ0FBQztBQUdwQyxVQUFJLEtBQUssSUFBSSxLQUFLLHdCQUF3QjtBQUN4QyxjQUFNLG1CQUFtQjtBQUFBLFVBQ3ZCO0FBQUEsVUFDQTtBQUFBLFVBQ0E7QUFBQSxRQUNGLENBQUM7QUFBQSxNQUNIO0FBQ0E7QUFBQSxJQUNGO0FBRUEsVUFBTSxvQkFBb0IsS0FBSyxJQUFJO0FBQ25DLFFBQUkscUJBQXFCLHdCQUF3QjtBQUMvQyxZQUFNLG1CQUFtQjtBQUFBLFFBQ3ZCO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxNQUNGLENBQUM7QUFBQSxJQUNIO0FBRUEsVUFBTSxnQkFBZ0IsbUNBQW1DLFFBQ3BELG9CQUFvQixrQ0FBa0M7QUFDM0QsUUFBSSxlQUFlO0FBQ2pCLHVDQUFpQztBQUNqQywwQkFBSSxrQkFBa0I7QUFBQSxRQUNwQjtBQUFBLFFBQ0E7QUFBQSxRQUNBLHlCQUF5Qix5QkFBeUI7QUFBQSxRQUNsRDtBQUFBLFFBQ0Esc0JBQXNCLG9CQUFvQjtBQUFBLE1BQzVDLENBQUMsQ0FBQztBQUFBLElBQ0o7QUFFQSxVQUFNLE1BQU0sNkJBQTZCO0FBQUEsRUFDM0M7QUFDRjtBQW9CQSxTQUFTLGlCQUFpQixNQUE2QjtBQUNyRCxRQUFNLDBCQUEwQixLQUFLLElBQUksSUFBSSw0QkFBNEIsSUFBSTtBQUU3RSxNQUFJLEtBQUssaUJBQWEseUJBQVMsR0FBRztBQUNoQyxXQUFPLENBQUMsb0JBQW9CLEtBQUssR0FBRyxLQUFLLDBCQUEwQjtBQUFBLEVBQ3JFO0FBRUEsU0FBTywwQkFBMEI7QUFDbkM7QUFRQSxTQUFTLGVBQWUsTUFBNkI7QUFDbkQsU0FBTyxLQUFLLFFBQVEsb0JBQUFBLFFBQVEsT0FBTyxLQUFLLGlCQUFhLHlCQUFTO0FBQ2hFO0FBUUEsU0FBUyxvQkFBb0IsS0FBc0I7QUFDakQsTUFBSTtBQUNGLHdCQUFBQSxRQUFRLEtBQUssS0FBSyw4QkFBOEI7QUFDaEQsV0FBTztBQUFBLEVBQ1QsU0FBUyxPQUFnQjtBQUV2QixXQUFPLGFBQWEsS0FBSyxNQUFNO0FBQUEsRUFDakM7QUFDRjtBQWNBLFNBQVMsaUJBQWlCLFFBQTJDO0FBQ25FLFFBQU07QUFBQSxJQUNKO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsRUFDRixJQUFJO0FBQ0osTUFBSSxhQUFhO0FBRWpCLFFBQU0saUJBQWlCLFlBQVksTUFBTTtBQUN2QyxVQUFNLGNBQWMsaUJBQWlCO0FBQUEsTUFDbkM7QUFBQSxNQUNBO0FBQUEsTUFDQTtBQUFBLElBQ0YsQ0FBQztBQUNELFFBQUksYUFBYTtBQUNmO0FBQUEsSUFDRjtBQUNBLGtCQUFjLGNBQWM7QUFDNUIsd0JBQUksc0JBQXNCLEtBQUssVUFBVSxLQUFLLG9GQUErRTtBQUFBLEVBQy9ILEdBQUcsa0NBQWtDO0FBQ3JDLGlCQUFlLE1BQU07QUFFckIsU0FBTztBQUFBLElBQ0wsVUFBZ0I7QUFDZCxVQUFJLFlBQVk7QUFDZDtBQUFBLE1BQ0Y7QUFDQSxtQkFBYTtBQUNiLG9CQUFjLGNBQWM7QUFFNUIsWUFBTSxPQUFPLGlCQUFpQixZQUFZO0FBQzFDLFVBQUksUUFBUSxDQUFDLGVBQWUsSUFBSSxHQUFHO0FBQ2pDLDRCQUFJLHNCQUFzQixLQUFLLGtCQUFrQixLQUFLLGtEQUE2QyxhQUFhLElBQUksQ0FBQyxHQUFHO0FBQ3hIO0FBQUEsTUFDRjtBQUNBLGlDQUFPLGNBQWMsRUFBRSxPQUFPLEtBQUssQ0FBQztBQUFBLElBQ3RDO0FBQUEsRUFDRjtBQUNGO0FBUUEsU0FBUyxtQkFBbUIsUUFBeUM7QUFDbkUsUUFBTTtBQUFBLElBQ0o7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLEVBQ0YsSUFBSTtBQUNKLFNBQU8sSUFBSTtBQUFBLElBQ1QsbUJBQW1CLE9BQU8scUJBQXFCLENBQUMsdUJBQXVCLEtBQUsseUNBQzdELGVBQWUsSUFBSSxDQUFDO0FBQUEsRUFDckM7QUFDRjtBQVFBLFNBQVMsTUFBTSxjQUFxQztBQUNsRCxTQUFPLElBQUksUUFBYyxDQUFDLFlBQVk7QUFDcEMsZUFBVyxTQUFTLFlBQVk7QUFBQSxFQUNsQyxDQUFDO0FBQ0g7QUFTQSxTQUFTLGVBQWUsTUFBbUM7QUFDekQsU0FBTyxPQUFPLGFBQWEsSUFBSSxJQUFJO0FBQ3JDO0FBUUEsU0FBUyxhQUFhLE1BQTRCO0FBQ2hELFNBQU8sT0FBTyxPQUFPLEtBQUssR0FBRyxDQUFDLEtBQUssS0FBSyxLQUFLLFFBQVEsS0FBSyxRQUFRO0FBQ3BFO0FBUUEsU0FBUyxlQUFlLGNBQThCO0FBQ3BELFFBQU0sZUFBZSxLQUFLLE1BQU0sZUFBZSx1QkFBdUI7QUFDdEUsUUFBTSxVQUFVLEtBQUssTUFBTSxlQUFlLGtCQUFrQjtBQUM1RCxRQUFNLFVBQVUsZUFBZTtBQUMvQixTQUFPLFVBQVUsSUFBSSxHQUFHLE9BQU8sT0FBTyxDQUFDLEtBQUssT0FBTyxPQUFPLENBQUMsTUFBTSxHQUFHLE9BQU8sT0FBTyxDQUFDO0FBQ3JGO0FBU0EsU0FBUyxrQkFBa0IsUUFBeUM7QUFDbEUsUUFBTTtBQUFBLElBQ0o7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsRUFDRixJQUFJO0FBQ0osUUFBTSxVQUFVLE9BQU8sY0FBYyxlQUFlLEtBQUssSUFBSSxJQUFJLEtBQUssd0JBQXdCLENBQUMsS0FBSztBQUNwRyxTQUFPLHNCQUFzQixLQUFLLHNCQUFzQixLQUFLLHdCQUF3QixlQUFlLElBQUksQ0FBQywyQkFDMUYsZUFBZSxvQkFBb0IsQ0FBQyxHQUFHLE9BQU8sa0JBQWtCLGVBQWUsdUJBQXVCLENBQUM7QUFDeEg7QUFRQSxTQUFTLGFBQWEsT0FBb0M7QUFDeEQsTUFBSSxpQkFBaUIsU0FBUyxVQUFVLFNBQVMsT0FBTyxNQUFNLFNBQVMsVUFBVTtBQUMvRSxXQUFPLE1BQU07QUFBQSxFQUNmO0FBQ0EsU0FBTztBQUNUO0FBVUEsU0FBUyw0QkFBNEIsTUFBNEI7QUFDL0QsU0FBTyxLQUFLLDZCQUE2QixLQUFLO0FBQ2hEO0FBT0EsU0FBUyxhQUFxQjtBQUM1QixhQUFPLDJCQUFLLHVCQUFPLEdBQUcsYUFBYTtBQUNyQztBQVFBLFNBQVMsZ0JBQWdCLE9BQXVCO0FBQzlDLGFBQU8sdUJBQUssV0FBVyxHQUFHLEdBQUcsS0FBSyxHQUFHLGdCQUFnQixFQUFFO0FBQ3pEO0FBUUEsU0FBUyxpQkFBaUIsY0FBMkM7QUFDbkUsTUFBSTtBQUNGLFdBQU8sS0FBSyxVQUFNLDZCQUFhLGNBQWMsT0FBTyxDQUFDO0FBQUEsRUFDdkQsUUFBUTtBQUNOLFdBQU87QUFBQSxFQUNUO0FBQ0Y7QUFZQSxTQUFTLGlCQUFpQixRQUF5QztBQUNqRSxRQUFNO0FBQUEsSUFDSjtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsRUFDRixJQUFJO0FBRUosUUFBTSxPQUFPLGlCQUFpQixZQUFZO0FBQzFDLE1BQUksUUFBUSxDQUFDLGVBQWUsSUFBSSxHQUFHO0FBQ2pDLFdBQU87QUFBQSxFQUNUO0FBRUEsUUFBTSxnQkFBOEI7QUFBQSxJQUNsQyxHQUFHO0FBQUEsSUFDSCwyQkFBMkIsS0FBSyxJQUFJO0FBQUEsRUFDdEM7QUFDQSxNQUFJO0FBQ0Ysc0NBQWMsY0FBYyxLQUFLLFVBQVUsYUFBYSxDQUFDO0FBQUEsRUFDM0QsU0FBUyxPQUFnQjtBQUd2Qix3QkFBSSxzQkFBc0IsS0FBSyxxREFBaUQsc0NBQWMsS0FBSyxDQUFDLEVBQUU7QUFBQSxFQUN4RztBQUNBLFNBQU87QUFDVDtBQVVBLFNBQVMsa0JBQWtCLGNBQXNCLE9BQW9DO0FBQ25GLFFBQU0sb0JBQW9CLEtBQUssSUFBSTtBQUNuQyxRQUFNLE9BQXFCO0FBQUEsSUFDekIsMEJBQTBCO0FBQUEsSUFDMUIsMkJBQTJCO0FBQUEsSUFDM0IsY0FBVSx5QkFBUztBQUFBLElBQ25CO0FBQUEsSUFDQSxLQUFLLG9CQUFBQSxRQUFRO0FBQUEsRUFDZjtBQUVBLE1BQUk7QUFDRixzQ0FBYyxjQUFjLEtBQUssVUFBVSxJQUFJLEdBQUcsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUNoRSxXQUFPO0FBQUEsRUFDVCxTQUFTLE9BQWdCO0FBQ3ZCLFFBQUksYUFBYSxLQUFLLE1BQU0sVUFBVTtBQUNwQyxhQUFPO0FBQUEsSUFDVDtBQUNBLFVBQU07QUFBQSxFQUNSO0FBQ0Y7IiwKICAibmFtZXMiOiBbInByb2Nlc3MiXQp9Cg==
@@ -13,9 +13,15 @@
13
13
  * This lock makes the second run **wait** for the first to finish instead of
14
14
  * running concurrently. It is held for the entire run: acquired at the start of
15
15
  * the core setup and released by the core teardown (and by the process cleanup
16
- * handlers). The lock is a sentinel file in a shared temp directory, carrying
17
- * the holder's PID so a run that crashed without releasing leaves a lock that
18
- * the next run detects as stale and steals.
16
+ * handlers). The lock is a sentinel file in a shared temp directory, and its
17
+ * holder keeps a **heartbeat** timestamp inside it fresh for as long as it holds
18
+ * the lock — so a run that crashed without releasing stops beating and the next
19
+ * run detects the lock as stale and steals it.
20
+ *
21
+ * The heartbeat, not the holder's PID, is what proves a holder is still there: a
22
+ * PID probe only answers "does *a* process with this PID exist", which a
23
+ * recycled PID satisfies long after the real holder died — leaving every later
24
+ * run to block for the full acquisition timeout.
19
25
  */
20
26
  /**
21
27
  * Parameters for {@link acquireSetupLock}.
@@ -26,6 +26,7 @@ var import_promises = require("node:fs/promises");
26
26
  var import_node_os = require("node:os");
27
27
  var import_node_path = require("node:path");
28
28
  var import_context_provider = require("./context-provider.cjs");
29
+ var import_leftover_cleanup = require("./leftover-cleanup.cjs");
29
30
  var import_transport_factory = require("./transport-factory.cjs");
30
31
  var import_vault_registry = require("./vault-registry.cjs");
31
32
  const RM_RETRY_DELAY_IN_MILLISECONDS = 500;
@@ -41,7 +42,7 @@ class TempVault {
41
42
  * @param path - An explicit vault path. If omitted, a temp directory is created.
42
43
  */
43
44
  constructor(path) {
44
- this.path = path ?? (0, import_node_fs.mkdtempSync)((0, import_node_path.join)((0, import_node_os.tmpdir)(), "temp-vault-"));
45
+ this.path = path ?? (0, import_node_fs.mkdtempSync)((0, import_node_path.join)((0, import_node_os.tmpdir)(), import_leftover_cleanup.TEMP_VAULT_DIR_PREFIX));
45
46
  }
46
47
  /**
47
48
  * Unregisters the vault from Obsidian and deletes the temp directory.
@@ -162,4 +163,4 @@ async function retryRm(path) {
162
163
  0 && (module.exports = {
163
164
  TempVault
164
165
  });
165
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RlbXAtdmF1bHQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBNYW5hZ2VzIHRlbXBvcmFyeSB2YXVsdCBsaWZlY3ljbGUgZm9yIGludGVncmF0aW9uIHRlc3RzLlxuICovXG5cbmltcG9ydCB7XG4gIG1rZGlyU3luYyxcbiAgbWtkdGVtcFN5bmMsXG4gIHdyaXRlRmlsZVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICByZWFkZGlyLFxuICByZWFkRmlsZSxcbiAgcm1cbn0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyB0bXBkaXIgfSBmcm9tICdub2RlOm9zJztcbmltcG9ydCB7XG4gIGRpcm5hbWUsXG4gIGpvaW4sXG4gIHJlbGF0aXZlXG59IGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB0eXBlIHsgT2JzaWRpYW5UcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC5janMnO1xuXG5pbXBvcnQgeyBnZXRUcmFuc3BvcnRPcHRpb25zIH0gZnJvbSAnLi9jb250ZXh0LXByb3ZpZGVyLmNqcyc7XG5pbXBvcnQgeyBnZXRPckNyZWF0ZVRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWZhY3RvcnkuY2pzJztcbmltcG9ydCB7XG4gIHJlZ2lzdGVyVmF1bHQsXG4gIHVucmVnaXN0ZXJWYXVsdFxufSBmcm9tICcuL3ZhdWx0LXJlZ2lzdHJ5LmNqcyc7XG5cbi8qKlxuICogQ29udGVudCB2YWx1ZSBmb3IgYSBzaW5nbGUgZW50cnkgaW4gYSB7QGxpbmsgUG9wdWxhdGVGaWxlc30gbWFwLlxuICpcbiAqIC0gYHN0cmluZ2AgXHUyMDE0IHRleHQgZmlsZSAod3JpdHRlbiBhcyBVVEYtOCkuXG4gKiAtIGBVaW50OEFycmF5YCBcdTIwMTQgYmluYXJ5IGZpbGUgKHdyaXR0ZW4gYXMgcmF3IGJ5dGVzOyBgQnVmZmVyYCBpcyBhY2NlcHRlZFxuICogICBiZWNhdXNlIGBCdWZmZXIgZXh0ZW5kcyBVaW50OEFycmF5YCkuXG4gKiAtIGB1bmRlZmluZWRgIFx1MjAxNCBlbXB0eSBmb2xkZXIgKHRoZSBrZXkgKiptdXN0KiogZW5kIHdpdGggYC9gKS5cbiAqL1xuZXhwb3J0IHR5cGUgUG9wdWxhdGVGaWxlQ29udGVudCA9IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCB1bmRlZmluZWQ7XG5cbi8qKlxuICogQSBtYXAgb2YgdmF1bHQtcmVsYXRpdmUgcGF0aHMgdG8gdGhlaXIgY29udGVudCwgdXNlZCBieVxuICoge0BsaW5rIFRlbXBWYXVsdC5wb3B1bGF0ZX0uXG4gKlxuICogUGF0aHMgZW5kaW5nIHdpdGggYC9gIGRlbm90ZSBmb2xkZXJzIGFuZCAqKm11c3QqKiBoYXZlIGFuIGB1bmRlZmluZWRgIHZhbHVlLlxuICogQWxsIG90aGVyIHBhdGhzIGFyZSB3cml0dGVuIGFzIGZpbGVzLlxuICovXG5leHBvcnQgdHlwZSBQb3B1bGF0ZUZpbGVzUGFyYW1zID0gUmVjb3JkPHN0cmluZywgUG9wdWxhdGVGaWxlQ29udGVudD47XG5cbmNvbnN0IFJNX1JFVFJZX0RFTEFZX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IFJNX1JFVFJZX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMTAwMDA7XG5cbi8qKlxuICogQSB0ZW1wb3JhcnkgT2JzaWRpYW4gdmF1bHQgZm9yIGludGVncmF0aW9uIHRlc3RzLlxuICpcbiAqIENyZWF0ZXMgYSB0ZW1wIGRpcmVjdG9yeSBhbmQgcmVnaXN0ZXJzIGl0IGluIHRoZSBydW5uaW5nIE9ic2lkaWFuIGluc3RhbmNlXG4gKiBzbyB0aGF0IHRoZSBPYnNpZGlhbiBDTEkgY2FuIHRhcmdldCBpdCB2aWEgYGN3ZGAuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZW1wVmF1bHQge1xuICAvKipcbiAgICogVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHRlbXBvcmFyeSB2YXVsdC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBwYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgdGVtcCB2YXVsdC5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggLSBBbiBleHBsaWNpdCB2YXVsdCBwYXRoLiBJZiBvbWl0dGVkLCBhIHRlbXAgZGlyZWN0b3J5IGlzIGNyZWF0ZWQuXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IocGF0aD86IHN0cmluZykge1xuICAgIHRoaXMucGF0aCA9IHBhdGggPz8gbWtkdGVtcFN5bmMoam9pbih0bXBkaXIoKSwgJ3RlbXAtdmF1bHQtJykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucmVnaXN0ZXJzIHRoZSB2YXVsdCBmcm9tIE9ic2lkaWFuIGFuZCBkZWxldGVzIHRoZSB0ZW1wIGRpcmVjdG9yeS5cbiAgICpcbiAgICogQHBhcmFtIHRyYW5zcG9ydE92ZXJyaWRlIC0gQW4gZXhwbGljaXQgdHJhbnNwb3J0IHRvIHVzZSB3aGVuIHVucmVnaXN0ZXJpbmcuXG4gICAqICAgV2hlbiBvbWl0dGVkLCBmYWxscyBiYWNrIHRvIHRoZSB0cmFuc3BvcnQgY29uZmlndXJlZCB2aWEgdGhlIGNvbnRleHQgcHJvdmlkZXIuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZGlzcG9zZSh0cmFuc3BvcnRPdmVycmlkZT86IE9ic2lkaWFuVHJhbnNwb3J0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHVucmVnaXN0ZXJWYXVsdCh0aGlzLnBhdGgsIHRyYW5zcG9ydE92ZXJyaWRlKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgcmV0cnlSbSh0aGlzLnBhdGgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBXcml0ZXMgZmlsZXMgYW5kIGZvbGRlcnMgaW50byB0aGUgdmF1bHQgZGlyZWN0b3J5LlxuICAgKiBQYXJlbnQgZGlyZWN0b3JpZXMgYXJlIGNyZWF0ZWQgYXV0b21hdGljYWxseS5cbiAgICpcbiAgICogLSBgc3RyaW5nYCB2YWx1ZXMgYXJlIHdyaXR0ZW4gYXMgVVRGLTggdGV4dCBmaWxlcy5cbiAgICogLSBgVWludDhBcnJheWAgdmFsdWVzIChpbmNsdWRpbmcgYEJ1ZmZlcmApIGFyZSB3cml0dGVuIGFzIGJpbmFyeSBmaWxlcy5cbiAgICogLSBQYXRocyBlbmRpbmcgd2l0aCBgL2AgYXJlIHRyZWF0ZWQgYXMgZW1wdHkgZm9sZGVycyAodmFsdWUgbXVzdCBiZSBgdW5kZWZpbmVkYCkuXG4gICAqXG4gICAqIEBwYXJhbSBmaWxlcyAtIE1hcCBvZiBmaWxlL2ZvbGRlciBwYXRocyB0byBjb250ZW50LlxuICAgKi9cbiAgcHVibGljIHBvcHVsYXRlKGZpbGVzOiBQb3B1bGF0ZUZpbGVzUGFyYW1zKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBbZmlsZVBhdGgsIGNvbnRlbnRdIG9mIE9iamVjdC5lbnRyaWVzKGZpbGVzKSkge1xuICAgICAgY29uc3QgZnVsbFBhdGggPSBqb2luKHRoaXMucGF0aCwgZmlsZVBhdGgpO1xuICAgICAgaWYgKGZpbGVQYXRoLmVuZHNXaXRoKCcvJykpIHtcbiAgICAgICAgaWYgKGNvbnRlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRm9sZGVyIHBhdGggXCIke2ZpbGVQYXRofVwiIG11c3QgaGF2ZSB1bmRlZmluZWQgY29udGVudGApO1xuICAgICAgICB9XG4gICAgICAgIG1rZGlyU3luYyhmdWxsUGF0aCwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoY29udGVudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGaWxlIHBhdGggXCIke2ZpbGVQYXRofVwiIG11c3QgaGF2ZSBkZWZpbmVkIGNvbnRlbnQ7IHVzZSBhIHRyYWlsaW5nIFwiL1wiIGZvciBmb2xkZXJzYCk7XG4gICAgICAgIH1cbiAgICAgICAgbWtkaXJTeW5jKGRpcm5hbWUoZnVsbFBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgd3JpdGVGaWxlU3luYyhmdWxsUGF0aCwgY29udGVudCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyB0aGlzIHZhdWx0IGluIHRoZSBydW5uaW5nIE9ic2lkaWFuIGluc3RhbmNlIHNvIHRoZSBDTEkgY2FuIHRhcmdldCBpdC5cbiAgICpcbiAgICogQHBhcmFtIHRyYW5zcG9ydE92ZXJyaWRlIC0gQW4gZXhwbGljaXQgdHJhbnNwb3J0IHRvIHVzZS4gV2hlbiBvbWl0dGVkLFxuICAgKiAgIGZhbGxzIGJhY2sgdG8gdGhlIHRyYW5zcG9ydCBjb25maWd1cmVkIHZpYSB0aGUgY29udGV4dCBwcm92aWRlci5cbiAgICovXG4gIHB1YmxpYyBhc3luYyByZWdpc3Rlcih0cmFuc3BvcnRPdmVycmlkZT86IE9ic2lkaWFuVHJhbnNwb3J0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgcmVnaXN0ZXJWYXVsdCh0aGlzLnBhdGgsIHRyYW5zcG9ydE92ZXJyaWRlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc3luYyBkaXNwb3NhYmxlIHN1cHBvcnQgZm9yIGBhd2FpdCB1c2luZ2AuXG4gICAqXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIHZhdWx0IGlzIGRpc3Bvc2VkLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIFtTeW1ib2wuYXN5bmNEaXNwb3NlXSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5kaXNwb3NlKCk7XG4gIH1cblxuICAvKiB2OCBpZ25vcmUgc3RhcnQgLS0gSW50ZWdyYXRpb24tdGltZSBjb2RlIHRoYXQgcmVxdWlyZXMgYSBydW5uaW5nIHRyYW5zcG9ydC4gKi9cblxuICAvKipcbiAgICogUHVzaGVzIGFsbCBmaWxlcyBmcm9tIHRoZSBsb2NhbCBzdGFnaW5nIGRpcmVjdG9yeSB0byB0aGUgdGFyZ2V0IGRldmljZVxuICAgKiB2aWEgdGhlIGFjdGl2ZSB0cmFuc3BvcnQncyBgcHVzaEZpbGVzKClgLlxuICAgKlxuICAgKiBPbiBkZXNrdG9wIHRyYW5zcG9ydHMgdGhpcyBpcyBhIG5vLW9wIChmaWxlcyBhcmUgYWxyZWFkeSBsb2NhbCkuXG4gICAqIE9uIG1vYmlsZSB0cmFuc3BvcnRzIChBcHBpdW0pIHRoaXMgcHVzaGVzIGZpbGVzIHRvIHRoZSBkZXZpY2UuXG4gICAqXG4gICAqIENhbGwgdGhpcyBhZnRlciB7QGxpbmsgcG9wdWxhdGV9IGFuZCBiZWZvcmUge0BsaW5rIHJlZ2lzdGVyfSB3aGVuIHVzaW5nXG4gICAqIGEgbW9iaWxlIHRyYW5zcG9ydC5cbiAgICpcbiAgICogQHBhcmFtIHRyYW5zcG9ydE92ZXJyaWRlIC0gQW4gZXhwbGljaXQgdHJhbnNwb3J0IHRvIHVzZS4gV2hlbiBvbWl0dGVkLFxuICAgKiAgIGZhbGxzIGJhY2sgdG8gdGhlIHRyYW5zcG9ydCBjb25maWd1cmVkIHZpYSB0aGUgY29udGV4dCBwcm92aWRlci5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBzeW5jVG9EZXZpY2UodHJhbnNwb3J0T3ZlcnJpZGU/OiBPYnNpZGlhblRyYW5zcG9ydCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHRyYW5zcG9ydCA9IHRyYW5zcG9ydE92ZXJyaWRlID8/IGF3YWl0IGdldE9yQ3JlYXRlVHJhbnNwb3J0KGdldFRyYW5zcG9ydE9wdGlvbnMoKSk7XG4gICAgaWYgKCF0cmFuc3BvcnQucHVzaEZpbGVzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZmlsZXMgPSBhd2FpdCB0aGlzLmNvbGxlY3RGaWxlcyh0aGlzLnBhdGgpO1xuICAgIGF3YWl0IHRyYW5zcG9ydC5wdXNoRmlsZXModGhpcy5wYXRoLCBmaWxlcyk7XG4gIH1cblxuICAvKipcbiAgICogUmVjdXJzaXZlbHkgcmVhZHMgYWxsIGZpbGVzIGZyb20gYSBkaXJlY3RvcnkgaW50byBhIGZsYXQgbWFwLlxuICAgKlxuICAgKiBAcGFyYW0gZGlyIC0gVGhlIGRpcmVjdG9yeSB0byByZWFkLlxuICAgKiBAcmV0dXJucyBBIG1hcCBvZiByZWxhdGl2ZSBmaWxlIHBhdGhzIHRvIGNvbnRlbnQgYnVmZmVycy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY29sbGVjdEZpbGVzKGRpcjogc3RyaW5nKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBVaW50OEFycmF5Pj4ge1xuICAgIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgVWludDhBcnJheT4gPSB7fTtcbiAgICBjb25zdCBlbnRyaWVzID0gYXdhaXQgcmVhZGRpcihkaXIsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KTtcblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgY29uc3QgZnVsbFBhdGggPSBqb2luKGRpciwgZW50cnkubmFtZSk7XG4gICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSByZWxhdGl2ZSh0aGlzLnBhdGgsIGZ1bGxQYXRoKTtcblxuICAgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihyZXN1bHQsIGF3YWl0IHRoaXMuY29sbGVjdEZpbGVzKGZ1bGxQYXRoKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRbcmVsYXRpdmVQYXRoXSA9IGF3YWl0IHJlYWRGaWxlKGZ1bGxQYXRoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIC8qIHY4IGlnbm9yZSBzdG9wICovXG59XG5cbi8qKlxuICogUmV0cmllcyBgcm1gIHVudGlsIGl0IHN1Y2NlZWRzIG9yIHRpbWVzIG91dC5cbiAqIE9ic2lkaWFuIG1heSBob2xkIGZpbGUgbG9ja3MgYnJpZWZseSBhZnRlciBhIHdpbmRvdyBpcyBkZXN0cm95ZWQuXG4gKlxuICogQHBhcmFtIHBhdGggLSBUaGUgcGF0aCB0byB0aGUgZGlyZWN0b3J5IHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGRpcmVjdG9yeSBpcyByZW1vdmVkLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXRyeVJtKHBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBSTV9SRVRSWV9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBybShwYXRoLCB7IGZvcmNlOiB0cnVlLCByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICByZXR1cm47XG4gICAgfSBjYXRjaCB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIFJNX1JFVFJZX0RFTEFZX0lOX01JTExJU0VDT05EUyk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgLy8gRmluYWwgYXR0ZW1wdCBcdTIwMTQgbGV0IGl0IHRocm93LlxuICBhd2FpdCBybShwYXRoLCB7IGZvcmNlOiB0cnVlLCByZWN1cnNpdmU6IHRydWUgfSk7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBTUEscUJBSU87QUFDUCxzQkFJTztBQUNQLHFCQUF1QjtBQUN2Qix1QkFJTztBQUlQLDhCQUFvQztBQUNwQywrQkFBcUM7QUFDckMsNEJBR087QUFxQlAsTUFBTSxpQ0FBaUM7QUFDdkMsTUFBTSxtQ0FBbUM7QUFRbEMsTUFBTSxVQUFVO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFJTDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9ULFlBQVksTUFBZTtBQUNoQyxTQUFLLE9BQU8sWUFBUSxnQ0FBWSwyQkFBSyx1QkFBTyxHQUFHLGFBQWEsQ0FBQztBQUFBLEVBQy9EO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFRQSxNQUFhLFFBQVEsbUJBQXNEO0FBQ3pFLFFBQUk7QUFD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
166
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RlbXAtdmF1bHQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBNYW5hZ2VzIHRlbXBvcmFyeSB2YXVsdCBsaWZlY3ljbGUgZm9yIGludGVncmF0aW9uIHRlc3RzLlxuICovXG5cbmltcG9ydCB7XG4gIG1rZGlyU3luYyxcbiAgbWtkdGVtcFN5bmMsXG4gIHdyaXRlRmlsZVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICByZWFkZGlyLFxuICByZWFkRmlsZSxcbiAgcm1cbn0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyB0bXBkaXIgfSBmcm9tICdub2RlOm9zJztcbmltcG9ydCB7XG4gIGRpcm5hbWUsXG4gIGpvaW4sXG4gIHJlbGF0aXZlXG59IGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB0eXBlIHsgT2JzaWRpYW5UcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC5janMnO1xuXG5pbXBvcnQgeyBnZXRUcmFuc3BvcnRPcHRpb25zIH0gZnJvbSAnLi9jb250ZXh0LXByb3ZpZGVyLmNqcyc7XG5pbXBvcnQgeyBURU1QX1ZBVUxUX0RJUl9QUkVGSVggfSBmcm9tICcuL2xlZnRvdmVyLWNsZWFudXAuY2pzJztcbmltcG9ydCB7IGdldE9yQ3JlYXRlVHJhbnNwb3J0IH0gZnJvbSAnLi90cmFuc3BvcnQtZmFjdG9yeS5janMnO1xuaW1wb3J0IHtcbiAgcmVnaXN0ZXJWYXVsdCxcbiAgdW5yZWdpc3RlclZhdWx0XG59IGZyb20gJy4vdmF1bHQtcmVnaXN0cnkuY2pzJztcblxuLyoqXG4gKiBDb250ZW50IHZhbHVlIGZvciBhIHNpbmdsZSBlbnRyeSBpbiBhIHtAbGluayBQb3B1bGF0ZUZpbGVzfSBtYXAuXG4gKlxuICogLSBgc3RyaW5nYCBcdTIwMTQgdGV4dCBmaWxlICh3cml0dGVuIGFzIFVURi04KS5cbiAqIC0gYFVpbnQ4QXJyYXlgIFx1MjAxNCBiaW5hcnkgZmlsZSAod3JpdHRlbiBhcyByYXcgYnl0ZXM7IGBCdWZmZXJgIGlzIGFjY2VwdGVkXG4gKiAgIGJlY2F1c2UgYEJ1ZmZlciBleHRlbmRzIFVpbnQ4QXJyYXlgKS5cbiAqIC0gYHVuZGVmaW5lZGAgXHUyMDE0IGVtcHR5IGZvbGRlciAodGhlIGtleSAqKm11c3QqKiBlbmQgd2l0aCBgL2ApLlxuICovXG5leHBvcnQgdHlwZSBQb3B1bGF0ZUZpbGVDb250ZW50ID0gc3RyaW5nIHwgVWludDhBcnJheSB8IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBBIG1hcCBvZiB2YXVsdC1yZWxhdGl2ZSBwYXRocyB0byB0aGVpciBjb250ZW50LCB1c2VkIGJ5XG4gKiB7QGxpbmsgVGVtcFZhdWx0LnBvcHVsYXRlfS5cbiAqXG4gKiBQYXRocyBlbmRpbmcgd2l0aCBgL2AgZGVub3RlIGZvbGRlcnMgYW5kICoqbXVzdCoqIGhhdmUgYW4gYHVuZGVmaW5lZGAgdmFsdWUuXG4gKiBBbGwgb3RoZXIgcGF0aHMgYXJlIHdyaXR0ZW4gYXMgZmlsZXMuXG4gKi9cbmV4cG9ydCB0eXBlIFBvcHVsYXRlRmlsZXNQYXJhbXMgPSBSZWNvcmQ8c3RyaW5nLCBQb3B1bGF0ZUZpbGVDb250ZW50PjtcblxuY29uc3QgUk1fUkVUUllfREVMQVlfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuY29uc3QgUk1fUkVUUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAxMDAwMDtcblxuLyoqXG4gKiBBIHRlbXBvcmFyeSBPYnNpZGlhbiB2YXVsdCBmb3IgaW50ZWdyYXRpb24gdGVzdHMuXG4gKlxuICogQ3JlYXRlcyBhIHRlbXAgZGlyZWN0b3J5IGFuZCByZWdpc3RlcnMgaXQgaW4gdGhlIHJ1bm5pbmcgT2JzaWRpYW4gaW5zdGFuY2VcbiAqIHNvIHRoYXQgdGhlIE9ic2lkaWFuIENMSSBjYW4gdGFyZ2V0IGl0IHZpYSBgY3dkYC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRlbXBWYXVsdCB7XG4gIC8qKlxuICAgKiBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgdGVtcG9yYXJ5IHZhdWx0LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHBhdGg6IHN0cmluZztcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyB0ZW1wIHZhdWx0LlxuICAgKlxuICAgKiBAcGFyYW0gcGF0aCAtIEFuIGV4cGxpY2l0IHZhdWx0IHBhdGguIElmIG9taXR0ZWQsIGEgdGVtcCBkaXJlY3RvcnkgaXMgY3JlYXRlZC5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihwYXRoPzogc3RyaW5nKSB7XG4gICAgdGhpcy5wYXRoID0gcGF0aCA/PyBta2R0ZW1wU3luYyhqb2luKHRtcGRpcigpLCBURU1QX1ZBVUxUX0RJUl9QUkVGSVgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnJlZ2lzdGVycyB0aGUgdmF1bHQgZnJvbSBPYnNpZGlhbiBhbmQgZGVsZXRlcyB0aGUgdGVtcCBkaXJlY3RvcnkuXG4gICAqXG4gICAqIEBwYXJhbSB0cmFuc3BvcnRPdmVycmlkZSAtIEFuIGV4cGxpY2l0IHRyYW5zcG9ydCB0byB1c2Ugd2hlbiB1bnJlZ2lzdGVyaW5nLlxuICAgKiAgIFdoZW4gb21pdHRlZCwgZmFsbHMgYmFjayB0byB0aGUgdHJhbnNwb3J0IGNvbmZpZ3VyZWQgdmlhIHRoZSBjb250ZXh0IHByb3ZpZGVyLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGRpc3Bvc2UodHJhbnNwb3J0T3ZlcnJpZGU/OiBPYnNpZGlhblRyYW5zcG9ydCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB1bnJlZ2lzdGVyVmF1bHQodGhpcy5wYXRoLCB0cmFuc3BvcnRPdmVycmlkZSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHJldHJ5Um0odGhpcy5wYXRoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogV3JpdGVzIGZpbGVzIGFuZCBmb2xkZXJzIGludG8gdGhlIHZhdWx0IGRpcmVjdG9yeS5cbiAgICogUGFyZW50IGRpcmVjdG9yaWVzIGFyZSBjcmVhdGVkIGF1dG9tYXRpY2FsbHkuXG4gICAqXG4gICAqIC0gYHN0cmluZ2AgdmFsdWVzIGFyZSB3cml0dGVuIGFzIFVURi04IHRleHQgZmlsZXMuXG4gICAqIC0gYFVpbnQ4QXJyYXlgIHZhbHVlcyAoaW5jbHVkaW5nIGBCdWZmZXJgKSBhcmUgd3JpdHRlbiBhcyBiaW5hcnkgZmlsZXMuXG4gICAqIC0gUGF0aHMgZW5kaW5nIHdpdGggYC9gIGFyZSB0cmVhdGVkIGFzIGVtcHR5IGZvbGRlcnMgKHZhbHVlIG11c3QgYmUgYHVuZGVmaW5lZGApLlxuICAgKlxuICAgKiBAcGFyYW0gZmlsZXMgLSBNYXAgb2YgZmlsZS9mb2xkZXIgcGF0aHMgdG8gY29udGVudC5cbiAgICovXG4gIHB1YmxpYyBwb3B1bGF0ZShmaWxlczogUG9wdWxhdGVGaWxlc1BhcmFtcyk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgW2ZpbGVQYXRoLCBjb250ZW50XSBvZiBPYmplY3QuZW50cmllcyhmaWxlcykpIHtcbiAgICAgIGNvbnN0IGZ1bGxQYXRoID0gam9pbih0aGlzLnBhdGgsIGZpbGVQYXRoKTtcbiAgICAgIGlmIChmaWxlUGF0aC5lbmRzV2l0aCgnLycpKSB7XG4gICAgICAgIGlmIChjb250ZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZvbGRlciBwYXRoIFwiJHtmaWxlUGF0aH1cIiBtdXN0IGhhdmUgdW5kZWZpbmVkIGNvbnRlbnRgKTtcbiAgICAgICAgfVxuICAgICAgICBta2RpclN5bmMoZnVsbFBhdGgsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGNvbnRlbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmlsZSBwYXRoIFwiJHtmaWxlUGF0aH1cIiBtdXN0IGhhdmUgZGVmaW5lZCBjb250ZW50OyB1c2UgYSB0cmFpbGluZyBcIi9cIiBmb3IgZm9sZGVyc2ApO1xuICAgICAgICB9XG4gICAgICAgIG1rZGlyU3luYyhkaXJuYW1lKGZ1bGxQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICAgIHdyaXRlRmlsZVN5bmMoZnVsbFBhdGgsIGNvbnRlbnQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgdGhpcyB2YXVsdCBpbiB0aGUgcnVubmluZyBPYnNpZGlhbiBpbnN0YW5jZSBzbyB0aGUgQ0xJIGNhbiB0YXJnZXQgaXQuXG4gICAqXG4gICAqIEBwYXJhbSB0cmFuc3BvcnRPdmVycmlkZSAtIEFuIGV4cGxpY2l0IHRyYW5zcG9ydCB0byB1c2UuIFdoZW4gb21pdHRlZCxcbiAgICogICBmYWxscyBiYWNrIHRvIHRoZSB0cmFuc3BvcnQgY29uZmlndXJlZCB2aWEgdGhlIGNvbnRleHQgcHJvdmlkZXIuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVnaXN0ZXIodHJhbnNwb3J0T3ZlcnJpZGU/OiBPYnNpZGlhblRyYW5zcG9ydCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHJlZ2lzdGVyVmF1bHQodGhpcy5wYXRoLCB0cmFuc3BvcnRPdmVycmlkZSk7XG4gIH1cblxuICAvKipcbiAgICogQXN5bmMgZGlzcG9zYWJsZSBzdXBwb3J0IGZvciBgYXdhaXQgdXNpbmdgLlxuICAgKlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSB2YXVsdCBpcyBkaXNwb3NlZC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBbU3ltYm9sLmFzeW5jRGlzcG9zZV0oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcG9zZSgpO1xuICB9XG5cbiAgLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgY29kZSB0aGF0IHJlcXVpcmVzIGEgcnVubmluZyB0cmFuc3BvcnQuICovXG5cbiAgLyoqXG4gICAqIFB1c2hlcyBhbGwgZmlsZXMgZnJvbSB0aGUgbG9jYWwgc3RhZ2luZyBkaXJlY3RvcnkgdG8gdGhlIHRhcmdldCBkZXZpY2VcbiAgICogdmlhIHRoZSBhY3RpdmUgdHJhbnNwb3J0J3MgYHB1c2hGaWxlcygpYC5cbiAgICpcbiAgICogT24gZGVza3RvcCB0cmFuc3BvcnRzIHRoaXMgaXMgYSBuby1vcCAoZmlsZXMgYXJlIGFscmVhZHkgbG9jYWwpLlxuICAgKiBPbiBtb2JpbGUgdHJhbnNwb3J0cyAoQXBwaXVtKSB0aGlzIHB1c2hlcyBmaWxlcyB0byB0aGUgZGV2aWNlLlxuICAgKlxuICAgKiBDYWxsIHRoaXMgYWZ0ZXIge0BsaW5rIHBvcHVsYXRlfSBhbmQgYmVmb3JlIHtAbGluayByZWdpc3Rlcn0gd2hlbiB1c2luZ1xuICAgKiBhIG1vYmlsZSB0cmFuc3BvcnQuXG4gICAqXG4gICAqIEBwYXJhbSB0cmFuc3BvcnRPdmVycmlkZSAtIEFuIGV4cGxpY2l0IHRyYW5zcG9ydCB0byB1c2UuIFdoZW4gb21pdHRlZCxcbiAgICogICBmYWxscyBiYWNrIHRvIHRoZSB0cmFuc3BvcnQgY29uZmlndXJlZCB2aWEgdGhlIGNvbnRleHQgcHJvdmlkZXIuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc3luY1RvRGV2aWNlKHRyYW5zcG9ydE92ZXJyaWRlPzogT2JzaWRpYW5UcmFuc3BvcnQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB0cmFuc3BvcnQgPSB0cmFuc3BvcnRPdmVycmlkZSA/PyBhd2FpdCBnZXRPckNyZWF0ZVRyYW5zcG9ydChnZXRUcmFuc3BvcnRPcHRpb25zKCkpO1xuICAgIGlmICghdHJhbnNwb3J0LnB1c2hGaWxlcykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGZpbGVzID0gYXdhaXQgdGhpcy5jb2xsZWN0RmlsZXModGhpcy5wYXRoKTtcbiAgICBhd2FpdCB0cmFuc3BvcnQucHVzaEZpbGVzKHRoaXMucGF0aCwgZmlsZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY3Vyc2l2ZWx5IHJlYWRzIGFsbCBmaWxlcyBmcm9tIGEgZGlyZWN0b3J5IGludG8gYSBmbGF0IG1hcC5cbiAgICpcbiAgICogQHBhcmFtIGRpciAtIFRoZSBkaXJlY3RvcnkgdG8gcmVhZC5cbiAgICogQHJldHVybnMgQSBtYXAgb2YgcmVsYXRpdmUgZmlsZSBwYXRocyB0byBjb250ZW50IGJ1ZmZlcnMuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNvbGxlY3RGaWxlcyhkaXI6IHN0cmluZyk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgVWludDhBcnJheT4+IHtcbiAgICBjb25zdCByZXN1bHQ6IFJlY29yZDxzdHJpbmcsIFVpbnQ4QXJyYXk+ID0ge307XG4gICAgY29uc3QgZW50cmllcyA9IGF3YWl0IHJlYWRkaXIoZGlyLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XG5cbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgIGNvbnN0IGZ1bGxQYXRoID0gam9pbihkaXIsIGVudHJ5Lm5hbWUpO1xuICAgICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcmVsYXRpdmUodGhpcy5wYXRoLCBmdWxsUGF0aCk7XG5cbiAgICAgIGlmIChlbnRyeS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIE9iamVjdC5hc3NpZ24ocmVzdWx0LCBhd2FpdCB0aGlzLmNvbGxlY3RGaWxlcyhmdWxsUGF0aCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0W3JlbGF0aXZlUGF0aF0gPSBhd2FpdCByZWFkRmlsZShmdWxsUGF0aCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICAvKiB2OCBpZ25vcmUgc3RvcCAqL1xufVxuXG4vKipcbiAqIFJldHJpZXMgYHJtYCB1bnRpbCBpdCBzdWNjZWVkcyBvciB0aW1lcyBvdXQuXG4gKiBPYnNpZGlhbiBtYXkgaG9sZCBmaWxlIGxvY2tzIGJyaWVmbHkgYWZ0ZXIgYSB3aW5kb3cgaXMgZGVzdHJveWVkLlxuICpcbiAqIEBwYXJhbSBwYXRoIC0gVGhlIHBhdGggdG8gdGhlIGRpcmVjdG9yeSB0byByZW1vdmUuXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBkaXJlY3RvcnkgaXMgcmVtb3ZlZC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmV0cnlSbShwYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgUk1fUkVUUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgcm0ocGF0aCwgeyBmb3JjZTogdHJ1ZSwgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH0gY2F0Y2gge1xuICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgc2V0VGltZW91dChyZXNvbHZlLCBSTV9SRVRSWV9ERUxBWV9JTl9NSUxMSVNFQ09ORFMpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIC8vIEZpbmFsIGF0dGVtcHQgXHUyMDE0IGxldCBpdCB0aHJvdy5cbiAgYXdhaXQgcm0ocGF0aCwgeyBmb3JjZTogdHJ1ZSwgcmVjdXJzaXZlOiB0cnVlIH0pO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQU1BLHFCQUlPO0FBQ1Asc0JBSU87QUFDUCxxQkFBdUI7QUFDdkIsdUJBSU87QUFJUCw4QkFBb0M7QUFDcEMsOEJBQXNDO0FBQ3RDLCtCQUFxQztBQUNyQyw0QkFHTztBQXFCUCxNQUFNLGlDQUFpQztBQUN2QyxNQUFNLG1DQUFtQztBQVFsQyxNQUFNLFVBQVU7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUlMO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBT1QsWUFBWSxNQUFlO0FBQ2hDLFNBQUssT0FBTyxZQUFRLGdDQUFZLDJCQUFLLHVCQUFPLEdBQUcsNkNBQXFCLENBQUM7QUFBQSxFQUN2RTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBUUEsTUFBYSxRQUFRLG1CQUFzRDtBQUN6RSxRQUFJO0FBQ0YsZ0JBQU0sdUNBQWdCLEtBQUssTUFBTSxpQkFBaUI7QUFBQSxJQUNwRCxVQUFFO0FBQ0EsWUFBTSxRQUFRLEtBQUssSUFBSTtBQUFBLElBQ3pCO0FBQUEsRUFDRjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFZTyxTQUFTLE9BQWtDO0FBQ2hELGVBQVcsQ0FBQyxVQUFVLE9BQU8sS0FBSyxPQUFPLFFBQVEsS0FBSyxHQUFHO0FBQ3ZELFlBQU0sZUFBVyx1QkFBSyxLQUFLLE1BQU0sUUFBUTtBQUN6QyxVQUFJLFNBQVMsU0FBUyxHQUFHLEdBQUc7QUFDMUIsWUFBSSxZQUFZLFFBQVc7QUFDekIsZ0JBQU0sSUFBSSxNQUFNLGdCQUFnQixRQUFRLCtCQUErQjtBQUFBLFFBQ3pFO0FBQ0Esc0NBQVUsVUFBVSxFQUFFLFdBQVcsS0FBSyxDQUFDO0FBQUEsTUFDekMsT0FBTztBQUNMLFlBQUksWUFBWSxRQUFXO0FBQ3pCLGdCQUFNLElBQUksTUFBTSxjQUFjLFFBQVEsNkRBQTZEO0FBQUEsUUFDckc7QUFDQSwwQ0FBVSwwQkFBUSxRQUFRLEdBQUcsRUFBRSxXQUFXLEtBQUssQ0FBQztBQUNoRCwwQ0FBYyxVQUFVLE9BQU87QUFBQSxNQUNqQztBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFRQSxNQUFhLFNBQVMsbUJBQXNEO0FBQzFFLGNBQU0scUNBQWMsS0FBSyxNQUFNLGlCQUFpQjtBQUFBLEVBQ2xEO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBT0EsT0FBYyxPQUFPLFlBQVksSUFBbUI7QUFDbEQsV0FBTyxLQUFLLFFBQVE7QUFBQSxFQUN0QjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQWlCQSxNQUFhLGFBQWEsbUJBQXNEO0FBQzlFLFVBQU0sWUFBWSxxQkFBcUIsVUFBTSxtREFBcUIsNkNBQW9CLENBQUM7QUFDdkYsUUFBSSxDQUFDLFVBQVUsV0FBVztBQUN4QjtBQUFBLElBQ0Y7QUFFQSxVQUFNLFFBQVEsTUFBTSxLQUFLLGFBQWEsS0FBSyxJQUFJO0FBQy9DLFVBQU0sVUFBVSxVQUFVLEtBQUssTUFBTSxLQUFLO0FBQUEsRUFDNUM7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVFBLE1BQWMsYUFBYSxLQUFrRDtBQUMzRSxVQUFNLFNBQXFDLENBQUM7QUFDNUMsVUFBTSxVQUFVLFVBQU0seUJBQVEsS0FBSyxFQUFFLGVBQWUsS0FBSyxDQUFDO0FBRTFELGVBQVcsU0FBUyxTQUFTO0FBQzNCLFlBQU0sZUFBVyx1QkFBSyxLQUFLLE1BQU0sSUFBSTtBQUNyQyxZQUFNLG1CQUFlLDJCQUFTLEtBQUssTUFBTSxRQUFRO0FBRWpELFVBQUksTUFBTSxZQUFZLEdBQUc7QUFDdkIsZUFBTyxPQUFPLFFBQVEsTUFBTSxLQUFLLGFBQWEsUUFBUSxDQUFDO0FBQUEsTUFDekQsT0FBTztBQUNMLGVBQU8sWUFBWSxJQUFJLFVBQU0sMEJBQVMsUUFBUTtBQUFBLE1BQ2hEO0FBQUEsSUFDRjtBQUVBLFdBQU87QUFBQSxFQUNUO0FBQUE7QUFFRjtBQVNBLGVBQWUsUUFBUSxNQUE2QjtBQUNsRCxRQUFNLFdBQVcsS0FBSyxJQUFJLElBQUk7QUFDOUIsU0FBTyxLQUFLLElBQUksSUFBSSxVQUFVO0FBQzVCLFFBQUk7QUFDRixnQkFBTSxvQkFBRyxNQUFNLEVBQUUsT0FBTyxNQUFNLFdBQVcsS0FBSyxDQUFDO0FBQy9DO0FBQUEsSUFDRixRQUFRO0FBQ04sWUFBTSxJQUFJLFFBQVEsQ0FBQyxZQUFZO0FBQzdCLG1CQUFXLFNBQVMsOEJBQThCO0FBQUEsTUFDcEQsQ0FBQztBQUFBLElBQ0g7QUFBQSxFQUNGO0FBRUEsWUFBTSxvQkFBRyxNQUFNLEVBQUUsT0FBTyxNQUFNLFdBQVcsS0FBSyxDQUFDO0FBQ2pEOyIsCiAgIm5hbWVzIjogW10KfQo=