obsidian-integration-testing 9.1.0 → 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 +44 -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 +52 -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.0.tgz +0 -0
@@ -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.mjs';
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>;
@@ -0,0 +1,48 @@
1
+ import { log } from "./log.mjs";
2
+ import { fetchDesktopReleasesManifest } from "./obsidian-version-switch.mjs";
3
+ import {
4
+ buildVersionMatrix,
5
+ formatVersionMatrixPlan,
6
+ formatVersionMatrixRunHeader,
7
+ hasChannelSpec,
8
+ resolveRequestedSpecs,
9
+ resolveVersionSpecs,
10
+ runVersionMatrixEntries
11
+ } from "./version-matrix.mjs";
12
+ async function runObsidianVersionMatrix(params) {
13
+ const { run, versions } = params;
14
+ const { isDefault, specs } = resolveRequestedSpecs(versions);
15
+ const manifest = hasChannelSpec(specs) ? await fetchDesktopReleasesManifest() : void 0;
16
+ const { droppedSpecs, resolvedSpecs } = resolveVersionSpecs({
17
+ manifest,
18
+ // The default list must not break every consumer's gate when a channel is
19
+ // Momentarily absent from the manifest; an explicitly requested specifier
20
+ // That cannot resolve is a real error.
21
+ shouldTolerateUnresolvableSpecs: isDefault,
22
+ specs
23
+ });
24
+ for (const { reason, spec } of droppedSpecs) {
25
+ logMatrix(`Skipping "${spec}": ${reason}`);
26
+ }
27
+ const entries = buildVersionMatrix(resolvedSpecs);
28
+ logPlan(resolvedSpecs, entries);
29
+ await runVersionMatrixEntries({
30
+ entries,
31
+ onEntryStart: (headerParams) => {
32
+ logMatrix(formatVersionMatrixRunHeader(headerParams));
33
+ },
34
+ run
35
+ });
36
+ }
37
+ function logMatrix(message) {
38
+ log(`[version-matrix] ${message}`);
39
+ }
40
+ function logPlan(resolvedSpecs, entries) {
41
+ for (const line of formatVersionMatrixPlan({ entries, resolvedSpecs })) {
42
+ logMatrix(line);
43
+ }
44
+ }
45
+ export {
46
+ runObsidianVersionMatrix
47
+ };
48
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3J1bi12ZXJzaW9uLW1hdHJpeC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIEludGVncmF0aW9uLXRpbWUgcnVubmVyIHRoYXQgZXhlY3V0ZXMgYSBzdWl0ZSBvbmNlIHBlciAqKmRpc3RpbmN0Kiogc3VwcG9ydGVkXG4gKiBPYnNpZGlhbiB2ZXJzaW9uLlxuICpcbiAqIFRoaW4gZ2x1ZSBvdmVyIHRoZSBwdXJlIGB2ZXJzaW9uLW1hdHJpeC50c2AgZGVjaXNpb24gbGF5ZXI6IHRoZSBvbmx5IHRoaW5nc1xuICogdGhhdCBoYXBwZW4gaGVyZSBhcmUgdGhlIHNpbmdsZSBtYW5pZmVzdCBmZXRjaCBhbmQgdGhlIGxvZ2dpbmcuIEV2ZXJ5dGhpbmdcbiAqIHRoYXQgZGVjaWRlcyBcdTIwMTQgbm9ybWFsaXppbmcgdGhlIHJlcXVlc3RlZCBzcGVjaWZpZXJzLCByZXNvbHZpbmcgdGhlbSxcbiAqIGRlLWR1cGxpY2F0aW5nIG9uIHRoZSByZXNvbHZlZCB2ZXJzaW9uLCBzZXF1ZW5jaW5nIHRoZSBydW5zLCBhbmQgYnVpbGRpbmcgdGhlXG4gKiBmYWlsdXJlIHN1bW1hcnkgXHUyMDE0IGlzIHB1cmUgYW5kIHVuaXQtdGVzdGVkIG5leHQgZG9vci5cbiAqXG4gKiBUaGUgbG9vcCBsaXZlcyBhYm92ZSB0aGUgdHJhbnNwb3J0IHJhdGhlciB0aGFuIGluc2lkZSBpdCBiZWNhdXNlIGEgdGVzdFxuICogZnJhbWV3b3JrJ3MgZ2xvYmFsIHNldHVwIGNhbm5vdCByZS1ydW4gaXRzIG93biB0ZXN0IGZpbGVzOiBpdCBsYXVuY2hlcyBvbmVcbiAqIGluc3RhbmNlIGZvciBvbmUgcnVuLiBLZWVwaW5nIHRoZSBsb29wIGZyYW1ld29yay1hZ25vc3RpYyAodGhlIGNhbGxlciBzdXBwbGllc1xuICogYHJ1bmApIGlzIHdoYXQgbGV0cyBWaXRlc3QsIEplc3QsIGFuZCBtYW51YWwgY29uc3VtZXJzIGFsbCBpbmhlcml0IGl0IChMNikuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgZ2x1ZSAobmV0d29yayBmZXRjaCArIGxvZ2dpbmcpIGNvdmVyZWQgYnkgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCB1bml0IHRlc3RzLiAqL1xuXG5pbXBvcnQgdHlwZSB7XG4gIE9ic2lkaWFuVmVyc2lvbk1hdHJpeEVudHJ5LFxuICBSZXNvbHZlZFZlcnNpb25TcGVjXG59IGZyb20gJy4vdmVyc2lvbi1tYXRyaXgubWpzJztcblxuaW1wb3J0IHsgbG9nIH0gZnJvbSAnLi9sb2cubWpzJztcbmltcG9ydCB7IGZldGNoRGVza3RvcFJlbGVhc2VzTWFuaWZlc3QgfSBmcm9tICcuL29ic2lkaWFuLXZlcnNpb24tc3dpdGNoLm1qcyc7XG5pbXBvcnQge1xuICBidWlsZFZlcnNpb25NYXRyaXgsXG4gIGZvcm1hdFZlcnNpb25NYXRyaXhQbGFuLFxuICBmb3JtYXRWZXJzaW9uTWF0cml4UnVuSGVhZGVyLFxuICBoYXNDaGFubmVsU3BlYyxcbiAgcmVzb2x2ZVJlcXVlc3RlZFNwZWNzLFxuICByZXNvbHZlVmVyc2lvblNwZWNzLFxuICBydW5WZXJzaW9uTWF0cml4RW50cmllc1xufSBmcm9tICcuL3ZlcnNpb24tbWF0cml4Lm1qcyc7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIHJ1bk9ic2lkaWFuVmVyc2lvbk1hdHJpeH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUnVuT2JzaWRpYW5WZXJzaW9uTWF0cml4UGFyYW1zIHtcbiAgLyoqXG4gICAqIFJ1bnMgdGhlIHN1aXRlcyBhZ2FpbnN0IG9uZSBjb25jcmV0ZSBPYnNpZGlhbiB2ZXJzaW9uLCB0aHJvd2luZyBvbiBmYWlsdXJlLlxuICAgKlxuICAgKiBUaGUgZW50cnkncyBgdmVyc2lvbmAgaXMgdGhlIGNvbmNyZXRlIGB4LnkuemAgdG8gcGluIFx1MjAxNCB0eXBpY2FsbHkgZm9yd2FyZGVkIHRvXG4gICAqIHRoZSB0ZXN0LXJ1bm5lciBjaGlsZCBhcyBgT0JTSURJQU5fVkVSU0lPTmAuXG4gICAqL1xuICByZWFkb25seSBydW46IChlbnRyeTogT2JzaWRpYW5WZXJzaW9uTWF0cml4RW50cnkpID0+IFByb21pc2U8dm9pZD4gfCB2b2lkO1xuXG4gIC8qKlxuICAgKiBUaGUgdmVyc2lvbiBzcGVjaWZpZXJzIHRvIHJ1biBhZ2FpbnN0OiBhbiBhcnJheSwgb3IgYSBjb21tYS1zZXBhcmF0ZWQgc3RyaW5nXG4gICAqIHNvIGFuIGVudiB2YXIgY2FuIGJlIHBhc3NlZCBzdHJhaWdodCB0aHJvdWdoLlxuICAgKlxuICAgKiBFYWNoIGFjY2VwdHMgYW4gZXhwbGljaXQgYCd4LnkueidgLCBgJ3B1YmxpYy1sYXRlc3QnYCwgb3IgYCdjYXRhbHlzdC1sYXRlc3QnYC5cbiAgICogRGVmYXVsdHMgdG8gYm90aCBlbmRzIG9mIHRoZSBzdXBwb3J0ZWQgcmFuZ2UgKEc5OSkgd2hlbiBvbWl0dGVkIG9yIGVtcHR5LCBhbmRcbiAgICogdGhlIGxpc3QgaXMgYWx3YXlzIGRlLWR1cGxpY2F0ZWQgb24gdGhlICoqcmVzb2x2ZWQqKiB2ZXJzaW9uIFx1MjAxNCBzbyB3aGVuIHB1YmxpY1xuICAgKiBoYXMgY2F1Z2h0IHVwIHRvIGNhdGFseXN0LCB0aGUgc3VpdGVzIHJ1biBvbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbnM/OiByZWFkb25seSBzdHJpbmdbXSB8IHN0cmluZyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSdW5zIGEgc3VpdGUgb25jZSBwZXIgZGlzdGluY3Qgc3VwcG9ydGVkIE9ic2lkaWFuIHZlcnNpb24uXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwZXItdmVyc2lvbiBydW5uZXIgYW5kIHRoZSByZXF1ZXN0ZWQgdmVyc2lvbnMuXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgZXZlcnkgdmVyc2lvbiBoYXMgcnVuIHN1Y2Nlc3NmdWxseS5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgbm8gdmVyc2lvbiBjb3VsZCBiZSByZXNvbHZlZCwgb3IgYW4ge0BsaW5rIEFnZ3JlZ2F0ZUVycm9yfVxuICogICBuYW1pbmcgZXZlcnkgdmVyc2lvbiB3aG9zZSBydW4gZmFpbGVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuT2JzaWRpYW5WZXJzaW9uTWF0cml4KHBhcmFtczogUnVuT2JzaWRpYW5WZXJzaW9uTWF0cml4UGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgcnVuLCB2ZXJzaW9ucyB9ID0gcGFyYW1zO1xuXG4gIGNvbnN0IHsgaXNEZWZhdWx0LCBzcGVjcyB9ID0gcmVzb2x2ZVJlcXVlc3RlZFNwZWNzKHZlcnNpb25zKTtcbiAgY29uc3QgbWFuaWZlc3QgPSBoYXNDaGFubmVsU3BlYyhzcGVjcykgPyBhd2FpdCBmZXRjaERlc2t0b3BSZWxlYXNlc01hbmlmZXN0KCkgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHsgZHJvcHBlZFNwZWNzLCByZXNvbHZlZFNwZWNzIH0gPSByZXNvbHZlVmVyc2lvblNwZWNzKHtcbiAgICBtYW5pZmVzdCxcbiAgICAvLyBUaGUgZGVmYXVsdCBsaXN0IG11c3Qgbm90IGJyZWFrIGV2ZXJ5IGNvbnN1bWVyJ3MgZ2F0ZSB3aGVuIGEgY2hhbm5lbCBpc1xuICAgIC8vIE1vbWVudGFyaWx5IGFic2VudCBmcm9tIHRoZSBtYW5pZmVzdDsgYW4gZXhwbGljaXRseSByZXF1ZXN0ZWQgc3BlY2lmaWVyXG4gICAgLy8gVGhhdCBjYW5ub3QgcmVzb2x2ZSBpcyBhIHJlYWwgZXJyb3IuXG4gICAgc2hvdWxkVG9sZXJhdGVVbnJlc29sdmFibGVTcGVjczogaXNEZWZhdWx0LFxuICAgIHNwZWNzXG4gIH0pO1xuXG4gIGZvciAoY29uc3QgeyByZWFzb24sIHNwZWMgfSBvZiBkcm9wcGVkU3BlY3MpIHtcbiAgICBsb2dNYXRyaXgoYFNraXBwaW5nIFwiJHtzcGVjfVwiOiAke3JlYXNvbn1gKTtcbiAgfVxuXG4gIGNvbnN0IGVudHJpZXMgPSBidWlsZFZlcnNpb25NYXRyaXgocmVzb2x2ZWRTcGVjcyk7XG4gIGxvZ1BsYW4ocmVzb2x2ZWRTcGVjcywgZW50cmllcyk7XG5cbiAgYXdhaXQgcnVuVmVyc2lvbk1hdHJpeEVudHJpZXMoe1xuICAgIGVudHJpZXMsXG4gICAgb25FbnRyeVN0YXJ0OiAoaGVhZGVyUGFyYW1zKSA9PiB7XG4gICAgICBsb2dNYXRyaXgoZm9ybWF0VmVyc2lvbk1hdHJpeFJ1bkhlYWRlcihoZWFkZXJQYXJhbXMpKTtcbiAgICB9LFxuICAgIHJ1blxuICB9KTtcbn1cblxuLyoqXG4gKiBMb2dzIGEgbWF0cml4IG1lc3NhZ2UgdW5kZXIgYSBjb25zaXN0ZW50IHByZWZpeC5cbiAqXG4gKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGxvZy5cbiAqL1xuZnVuY3Rpb24gbG9nTWF0cml4KG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICBsb2coYFt2ZXJzaW9uLW1hdHJpeF0gJHttZXNzYWdlfWApO1xufVxuXG4vKipcbiAqIExvZ3Mgd2hhdCB0aGUgc3BlY2lmaWVycyByZXNvbHZlZCB0byBhbmQgaG93IG1hbnkgcnVucyB0aGF0IGltcGxpZXMuXG4gKlxuICogQHBhcmFtIHJlc29sdmVkU3BlY3MgLSBUaGUgcmVzb2x2ZWQgc3BlY2lmaWVycywgaW4gcmVxdWVzdGVkIG9yZGVyLlxuICogQHBhcmFtIGVudHJpZXMgLSBUaGUgZGUtZHVwbGljYXRlZCBtYXRyaXguXG4gKi9cbmZ1bmN0aW9uIGxvZ1BsYW4ocmVzb2x2ZWRTcGVjczogcmVhZG9ubHkgUmVzb2x2ZWRWZXJzaW9uU3BlY1tdLCBlbnRyaWVzOiByZWFkb25seSBPYnNpZGlhblZlcnNpb25NYXRyaXhFbnRyeVtdKTogdm9pZCB7XG4gIGZvciAoY29uc3QgbGluZSBvZiBmb3JtYXRWZXJzaW9uTWF0cml4UGxhbih7IGVudHJpZXMsIHJlc29sdmVkU3BlY3MgfSkpIHtcbiAgICBsb2dNYXRyaXgobGluZSk7XG4gIH1cbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICJBQXlCQSxTQUFTLFdBQVc7QUFDcEIsU0FBUyxvQ0FBb0M7QUFDN0M7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsT0FDSztBQWtDUCxlQUFzQix5QkFBeUIsUUFBdUQ7QUFDcEcsUUFBTSxFQUFFLEtBQUssU0FBUyxJQUFJO0FBRTFCLFFBQU0sRUFBRSxXQUFXLE1BQU0sSUFBSSxzQkFBc0IsUUFBUTtBQUMzRCxRQUFNLFdBQVcsZUFBZSxLQUFLLElBQUksTUFBTSw2QkFBNkIsSUFBSTtBQUNoRixRQUFNLEVBQUUsY0FBYyxjQUFjLElBQUksb0JBQW9CO0FBQUEsSUFDMUQ7QUFBQTtBQUFBO0FBQUE7QUFBQSxJQUlBLGlDQUFpQztBQUFBLElBQ2pDO0FBQUEsRUFDRixDQUFDO0FBRUQsYUFBVyxFQUFFLFFBQVEsS0FBSyxLQUFLLGNBQWM7QUFDM0MsY0FBVSxhQUFhLElBQUksTUFBTSxNQUFNLEVBQUU7QUFBQSxFQUMzQztBQUVBLFFBQU0sVUFBVSxtQkFBbUIsYUFBYTtBQUNoRCxVQUFRLGVBQWUsT0FBTztBQUU5QixRQUFNLHdCQUF3QjtBQUFBLElBQzVCO0FBQUEsSUFDQSxjQUFjLENBQUMsaUJBQWlCO0FBQzlCLGdCQUFVLDZCQUE2QixZQUFZLENBQUM7QUFBQSxJQUN0RDtBQUFBLElBQ0E7QUFBQSxFQUNGLENBQUM7QUFDSDtBQU9BLFNBQVMsVUFBVSxTQUF1QjtBQUN4QyxNQUFJLG9CQUFvQixPQUFPLEVBQUU7QUFDbkM7QUFRQSxTQUFTLFFBQVEsZUFBK0MsU0FBc0Q7QUFDcEgsYUFBVyxRQUFRLHdCQUF3QixFQUFFLFNBQVMsY0FBYyxDQUFDLEdBQUc7QUFDdEUsY0FBVSxJQUFJO0FBQUEsRUFDaEI7QUFDRjsiLAogICJuYW1lcyI6IFtdCn0K
@@ -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}.
@@ -10,12 +10,19 @@ import {
10
10
  } from "node:os";
11
11
  import { join } from "node:path";
12
12
  import process from "node:process";
13
+ import { errorToString } from "./error-to-string.mjs";
13
14
  import { log } from "./log.mjs";
14
15
  const LOCK_DIR_NAME = "obsidian-integration-testing";
15
16
  const LOCK_FILE_SUFFIX = ".setup.lock";
16
17
  const POLL_INTERVAL_IN_MILLISECONDS = 500;
17
18
  const MILLISECONDS_PER_SECOND = 1e3;
18
19
  const SECONDS_PER_MINUTE = 60;
20
+ const HEARTBEAT_INTERVAL_IN_SECONDS = 5;
21
+ const HEARTBEAT_INTERVAL_IN_MILLISECONDS = HEARTBEAT_INTERVAL_IN_SECONDS * MILLISECONDS_PER_SECOND;
22
+ const MISSED_HEARTBEATS_BEFORE_STALE = 24;
23
+ const HEARTBEAT_STALE_IN_MILLISECONDS = HEARTBEAT_INTERVAL_IN_MILLISECONDS * MISSED_HEARTBEATS_BEFORE_STALE;
24
+ const WAIT_LOG_INTERVAL_IN_SECONDS = 30;
25
+ const WAIT_LOG_INTERVAL_IN_MILLISECONDS = WAIT_LOG_INTERVAL_IN_SECONDS * MILLISECONDS_PER_SECOND;
19
26
  const STALE_LOCK_AGE_IN_MINUTES = 30;
20
27
  const DEFAULT_TIMEOUT_IN_MINUTES = 60;
21
28
  const STALE_LOCK_AGE_IN_MILLISECONDS = STALE_LOCK_AGE_IN_MINUTES * SECONDS_PER_MINUTE * MILLISECONDS_PER_SECOND;
@@ -29,42 +36,119 @@ async function acquireSetupLock(params) {
29
36
  const timeoutInMilliseconds = params.timeoutInMilliseconds ?? DEFAULT_TIMEOUT_IN_MILLISECONDS;
30
37
  const lockFilePath = getLockFilePath(scope);
31
38
  mkdirSync(getLockDir(), { recursive: true });
32
- const deadlineInMilliseconds = Date.now() + timeoutInMilliseconds;
33
- let hasLoggedWait = false;
39
+ const startedAtInMilliseconds = Date.now();
40
+ const deadlineInMilliseconds = startedAtInMilliseconds + timeoutInMilliseconds;
41
+ let lastLoggedWaitAtInMilliseconds = null;
34
42
  for (; ; ) {
35
- if (tryCreateLockFile(lockFilePath, label)) {
36
- return createLockHandle(lockFilePath);
43
+ const ownInfo = tryCreateLockFile(lockFilePath, label);
44
+ if (ownInfo) {
45
+ return createLockHandle({
46
+ label,
47
+ lockFilePath,
48
+ ownInfo,
49
+ scope
50
+ });
37
51
  }
38
52
  const info = readLockFileInfo(lockFilePath);
39
- if (info && isLockStale(info)) {
53
+ if (info && checkIsLockStale(info)) {
40
54
  log(`[integration-setup:${label}] Stealing stale '${scope}' setup lock from ${describeInfo(info)}.`);
41
55
  rmSync(lockFilePath, { force: true });
56
+ if (Date.now() >= deadlineInMilliseconds) {
57
+ throw createTimeoutError({
58
+ info,
59
+ scope,
60
+ timeoutInMilliseconds
61
+ });
62
+ }
42
63
  continue;
43
64
  }
44
- if (Date.now() >= deadlineInMilliseconds) {
45
- throw new Error(
46
- `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.`
47
- );
65
+ const nowInMilliseconds = Date.now();
66
+ if (nowInMilliseconds >= deadlineInMilliseconds) {
67
+ throw createTimeoutError({
68
+ info,
69
+ scope,
70
+ timeoutInMilliseconds
71
+ });
48
72
  }
49
- if (!hasLoggedWait) {
50
- hasLoggedWait = true;
51
- log(`[integration-setup:${label}] Waiting for the '${scope}' setup lock held by ${describeHolder(info)} to be released...`);
73
+ const shouldLogWait = lastLoggedWaitAtInMilliseconds === null || nowInMilliseconds - lastLoggedWaitAtInMilliseconds >= WAIT_LOG_INTERVAL_IN_MILLISECONDS;
74
+ if (shouldLogWait) {
75
+ lastLoggedWaitAtInMilliseconds = nowInMilliseconds;
76
+ log(formatWaitMessage({
77
+ info,
78
+ label,
79
+ remainingInMilliseconds: deadlineInMilliseconds - nowInMilliseconds,
80
+ scope,
81
+ waitedInMilliseconds: nowInMilliseconds - startedAtInMilliseconds
82
+ }));
52
83
  }
53
84
  await delay(POLL_INTERVAL_IN_MILLISECONDS);
54
85
  }
55
86
  }
56
- function createLockHandle(lockFilePath) {
87
+ function checkIsLockStale(info) {
88
+ const silentForInMilliseconds = Date.now() - getLastSeenAtInMilliseconds(info);
89
+ if (info.hostname === hostname()) {
90
+ return !checkIsProcessAlive(info.pid) || silentForInMilliseconds > HEARTBEAT_STALE_IN_MILLISECONDS;
91
+ }
92
+ return silentForInMilliseconds > STALE_LOCK_AGE_IN_MILLISECONDS;
93
+ }
94
+ function checkIsOwnLock(info) {
95
+ return info.pid === process.pid && info.hostname === hostname();
96
+ }
97
+ function checkIsProcessAlive(pid) {
98
+ try {
99
+ process.kill(pid, PROCESS_EXISTENCE_PROBE_SIGNAL);
100
+ return true;
101
+ } catch (error) {
102
+ return getErrorCode(error) === "EPERM";
103
+ }
104
+ }
105
+ function createLockHandle(params) {
106
+ const {
107
+ label,
108
+ lockFilePath,
109
+ ownInfo,
110
+ scope
111
+ } = params;
57
112
  let isReleased = false;
113
+ const heartbeatTimer = setInterval(() => {
114
+ const isStillOurs = refreshHeartbeat({
115
+ label,
116
+ lockFilePath,
117
+ ownInfo
118
+ });
119
+ if (isStillOurs) {
120
+ return;
121
+ }
122
+ clearInterval(heartbeatTimer);
123
+ log(`[integration-setup:${label}] The '${scope}' setup lock is no longer ours \u2014 another run took it over. Heartbeat stopped.`);
124
+ }, HEARTBEAT_INTERVAL_IN_MILLISECONDS);
125
+ heartbeatTimer.unref();
58
126
  return {
59
127
  release() {
60
128
  if (isReleased) {
61
129
  return;
62
130
  }
63
131
  isReleased = true;
132
+ clearInterval(heartbeatTimer);
133
+ const info = readLockFileInfo(lockFilePath);
134
+ if (info && !checkIsOwnLock(info)) {
135
+ log(`[integration-setup:${label}] Leaving the '${scope}' setup lock in place \u2014 it now belongs to ${describeInfo(info)}.`);
136
+ return;
137
+ }
64
138
  rmSync(lockFilePath, { force: true });
65
139
  }
66
140
  };
67
141
  }
142
+ function createTimeoutError(params) {
143
+ const {
144
+ info,
145
+ scope,
146
+ timeoutInMilliseconds
147
+ } = params;
148
+ return new Error(
149
+ `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.`
150
+ );
151
+ }
68
152
  function delay(milliseconds) {
69
153
  return new Promise((resolve) => {
70
154
  setTimeout(resolve, milliseconds);
@@ -76,52 +160,81 @@ function describeHolder(info) {
76
160
  function describeInfo(info) {
77
161
  return `pid ${String(info.pid)} (${info.label}) on ${info.hostname}`;
78
162
  }
163
+ function formatDuration(milliseconds) {
164
+ const totalSeconds = Math.round(milliseconds / MILLISECONDS_PER_SECOND);
165
+ const minutes = Math.floor(totalSeconds / SECONDS_PER_MINUTE);
166
+ const seconds = totalSeconds % SECONDS_PER_MINUTE;
167
+ return minutes > 0 ? `${String(minutes)}m ${String(seconds)}s` : `${String(seconds)}s`;
168
+ }
169
+ function formatWaitMessage(params) {
170
+ const {
171
+ info,
172
+ label,
173
+ remainingInMilliseconds,
174
+ scope,
175
+ waitedInMilliseconds
176
+ } = params;
177
+ const heldFor = info ? `, held for ${formatDuration(Date.now() - info.acquiredAtInMilliseconds)}` : "";
178
+ 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)})...`;
179
+ }
79
180
  function getErrorCode(error) {
80
181
  if (error instanceof Error && "code" in error && typeof error.code === "string") {
81
182
  return error.code;
82
183
  }
83
184
  return void 0;
84
185
  }
186
+ function getLastSeenAtInMilliseconds(info) {
187
+ return info.heartbeatAtInMilliseconds ?? info.acquiredAtInMilliseconds;
188
+ }
85
189
  function getLockDir() {
86
190
  return join(tmpdir(), LOCK_DIR_NAME);
87
191
  }
88
192
  function getLockFilePath(scope) {
89
193
  return join(getLockDir(), `${scope}${LOCK_FILE_SUFFIX}`);
90
194
  }
91
- function isLockStale(info) {
92
- if (info.hostname === hostname()) {
93
- return !isProcessAlive(info.pid);
94
- }
95
- return Date.now() - info.acquiredAtInMilliseconds > STALE_LOCK_AGE_IN_MILLISECONDS;
96
- }
97
- function isProcessAlive(pid) {
98
- try {
99
- process.kill(pid, PROCESS_EXISTENCE_PROBE_SIGNAL);
100
- return true;
101
- } catch (error) {
102
- return getErrorCode(error) === "EPERM";
103
- }
104
- }
105
195
  function readLockFileInfo(lockFilePath) {
106
196
  try {
107
197
  return JSON.parse(readFileSync(lockFilePath, "utf-8"));
108
198
  } catch {
109
- return void 0;
199
+ return null;
200
+ }
201
+ }
202
+ function refreshHeartbeat(params) {
203
+ const {
204
+ label,
205
+ lockFilePath,
206
+ ownInfo
207
+ } = params;
208
+ const info = readLockFileInfo(lockFilePath);
209
+ if (info && !checkIsOwnLock(info)) {
210
+ return false;
211
+ }
212
+ const refreshedInfo = {
213
+ ...ownInfo,
214
+ heartbeatAtInMilliseconds: Date.now()
215
+ };
216
+ try {
217
+ writeFileSync(lockFilePath, JSON.stringify(refreshedInfo));
218
+ } catch (error) {
219
+ log(`[integration-setup:${label}] Failed to refresh the setup lock heartbeat: ${errorToString(error)}`);
110
220
  }
221
+ return true;
111
222
  }
112
223
  function tryCreateLockFile(lockFilePath, label) {
224
+ const nowInMilliseconds = Date.now();
113
225
  const info = {
114
- acquiredAtInMilliseconds: Date.now(),
226
+ acquiredAtInMilliseconds: nowInMilliseconds,
227
+ heartbeatAtInMilliseconds: nowInMilliseconds,
115
228
  hostname: hostname(),
116
229
  label,
117
230
  pid: process.pid
118
231
  };
119
232
  try {
120
233
  writeFileSync(lockFilePath, JSON.stringify(info), { flag: "wx" });
121
- return true;
234
+ return info;
122
235
  } catch (error) {
123
236
  if (getErrorCode(error) === "EEXIST") {
124
- return false;
237
+ return null;
125
238
  }
126
239
  throw error;
127
240
  }
@@ -129,4 +242,4 @@ function tryCreateLockFile(lockFilePath, label) {
129
242
  export {
130
243
  acquireSetupLock
131
244
  };
132
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3NldHVwLWxvY2sudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBDcm9zcy1wcm9jZXNzIGFkdmlzb3J5IGxvY2sgdGhhdCBzZXJpYWxpemVzIHdob2xlIGludGVncmF0aW9uLXRlc3QgcnVucy5cbiAqXG4gKiBUd28gdGVzdCBydW5zIHRoYXQgZHJpdmUgdGhlIHNhbWUgc2hhcmVkIHJlc291cmNlcyBjb3JydXB0IGVhY2ggb3RoZXI6IG9uXG4gKiBkZXNrdG9wIHRoZXkgc2hhcmUgdGhlIHNpbmdsZSBsb2NhbCBPYnNpZGlhbiBpbnN0YW5jZSwgaXRzIGBvYnNpZGlhbi5qc29uYFxuICogcmVnaXN0cnksIGFuZCB0aGUgQ0RQIHBvcnQ7IG9uIEFuZHJvaWQgdGhleSBzaGFyZSB0aGUgZW11bGF0b3IgYW5kIHRoZSBBcHBpdW1cbiAqIHNlcnZlci4gT25lIHJ1bidzIHNldHVwL3RlYXJkb3duIGtpbGxzIG9yIHJlY29uZmlndXJlcyB0aGUgaW5zdGFuY2UgdGhlIG90aGVyXG4gKiBydW4gaXMgbWlkLWV2YWwgb24gKG9ic2VydmVkIGFzIGBFQ09OTlJFRlVTRURgIG9yIFwidmF1bHQgbm90IG9wZW5cIiksIHNvIGJvdGhcbiAqIHJ1bnMgZmFpbC5cbiAqXG4gKiBUaGlzIGxvY2sgbWFrZXMgdGhlIHNlY29uZCBydW4gKip3YWl0KiogZm9yIHRoZSBmaXJzdCB0byBmaW5pc2ggaW5zdGVhZCBvZlxuICogcnVubmluZyBjb25jdXJyZW50bHkuIEl0IGlzIGhlbGQgZm9yIHRoZSBlbnRpcmUgcnVuOiBhY3F1aXJlZCBhdCB0aGUgc3RhcnQgb2ZcbiAqIHRoZSBjb3JlIHNldHVwIGFuZCByZWxlYXNlZCBieSB0aGUgY29yZSB0ZWFyZG93biAoYW5kIGJ5IHRoZSBwcm9jZXNzIGNsZWFudXBcbiAqIGhhbmRsZXJzKS4gVGhlIGxvY2sgaXMgYSBzZW50aW5lbCBmaWxlIGluIGEgc2hhcmVkIHRlbXAgZGlyZWN0b3J5LCBjYXJyeWluZ1xuICogdGhlIGhvbGRlcidzIFBJRCBzbyBhIHJ1biB0aGF0IGNyYXNoZWQgd2l0aG91dCByZWxlYXNpbmcgbGVhdmVzIGEgbG9jayB0aGF0XG4gKiB0aGUgbmV4dCBydW4gZGV0ZWN0cyBhcyBzdGFsZSBhbmQgc3RlYWxzLlxuICovXG5cbmltcG9ydCB7XG4gIG1rZGlyU3luYyxcbiAgcmVhZEZpbGVTeW5jLFxuICBybVN5bmMsXG4gIHdyaXRlRmlsZVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBob3N0bmFtZSxcbiAgdG1wZGlyXG59IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQgeyBsb2cgfSBmcm9tICcuL2xvZy5tanMnO1xuXG5jb25zdCBMT0NLX0RJUl9OQU1FID0gJ29ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmcnO1xuY29uc3QgTE9DS19GSUxFX1NVRkZJWCA9ICcuc2V0dXAubG9jayc7XG5jb25zdCBQT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IE1JTExJU0VDT05EU19QRVJfU0VDT05EID0gMTAwMDtcbmNvbnN0IFNFQ09ORFNfUEVSX01JTlVURSA9IDYwO1xuY29uc3QgU1RBTEVfTE9DS19BR0VfSU5fTUlOVVRFUyA9IDMwO1xuY29uc3QgREVGQVVMVF9USU1FT1VUX0lOX01JTlVURVMgPSA2MDtcbmNvbnN0IFNUQUxFX0xPQ0tfQUdFX0lOX01JTExJU0VDT05EUyA9IFNUQUxFX0xPQ0tfQUdFX0lOX01JTlVURVMgKiBTRUNPTkRTX1BFUl9NSU5VVEUgKiBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORDtcbmNvbnN0IERFRkFVTFRfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSBERUZBVUxUX1RJTUVPVVRfSU5fTUlOVVRFUyAqIFNFQ09ORFNfUEVSX01JTlVURSAqIE1JTExJU0VDT05EU19QRVJfU0VDT05EO1xuY29uc3QgUFJPQ0VTU19FWElTVEVOQ0VfUFJPQkVfU0lHTkFMID0gMDtcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgYWNxdWlyZVNldHVwTG9ja30uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWNxdWlyZVNldHVwTG9ja1BhcmFtcyB7XG4gIC8qKiBTaG9ydCB0cmFuc3BvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcyAoZS5nLiBgXCJvYnNpZGlhbi1jbGlcImApLiAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBMb2dpY2FsIHNjb3BlIHRoZSBsb2NrIHNlcmlhbGl6ZXMgd2l0aGluLiBSdW5zIHRoYXQgc2hhcmUgcmVzb3VyY2VzIG11c3RcbiAgICogdXNlIHRoZSBzYW1lIHNjb3BlIChlLmcuIGBcImRlc2t0b3BcImAgZm9yIHRoZSBDTEkvQ0RQIHRyYW5zcG9ydHMsIGBcImFuZHJvaWRcImBcbiAgICogZm9yIHRoZSBBcHBpdW0gdHJhbnNwb3J0KS5cbiAgICovXG4gIHJlYWRvbmx5IHNjb3BlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE1heGltdW0gdGltZSB0byB3YWl0IGZvciBhIGNvbXBldGluZyBydW4gdG8gcmVsZWFzZSB0aGUgbG9jayBiZWZvcmUgZ2l2aW5nXG4gICAqIHVwIGFuZCB0aHJvd2luZy5cbiAgICpcbiAgICogQGRlZmF1bHQgMSBob3VyXG4gICAqL1xuICByZWFkb25seSB0aW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXIgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQSBoZWxkIHNldHVwIGxvY2suIFJlbGVhc2UgaXQgb25jZSB0aGUgcnVuJ3MgdGVhcmRvd24gaXMgY29tcGxldGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2V0dXBMb2NrIHtcbiAgLyoqIFJlbGVhc2VzIHRoZSBsb2NrLiBTYWZlIHRvIGNhbGwgbW9yZSB0aGFuIG9uY2UuICovXG4gIHJlbGVhc2UoKTogdm9pZDtcbn1cblxuLyoqXG4gKiBUaGUgSlNPTiBwYXlsb2FkIHN0b3JlZCBpbnNpZGUgYSBsb2NrIGZpbGUsIGlkZW50aWZ5aW5nIHRoZSBob2xkZXIuXG4gKi9cbmludGVyZmFjZSBMb2NrRmlsZUluZm8ge1xuICAvKiogV2hlbiB0aGUgbG9jayB3YXMgYWNxdWlyZWQgKGBEYXRlLm5vdygpYCBlcG9jaCBtaWxsaXNlY29uZHMpLiAqL1xuICByZWFkb25seSBhY3F1aXJlZEF0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcblxuICAvKiogVGhlIGhvc3QgdGhhdCBob2xkcyB0aGUgbG9jayAoUElEIGxpdmVuZXNzIGlzIG9ubHkgdmFsaWQgb24gdGhlIHNhbWUgaG9zdCkuICovXG4gIHJlYWRvbmx5IGhvc3RuYW1lOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSB0cmFuc3BvcnQgbGFiZWwgb2YgdGhlIGhvbGRpbmcgcnVuLiAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKiBUaGUgcHJvY2VzcyBJRCBvZiB0aGUgaG9sZGluZyBydW4uICovXG4gIHJlYWRvbmx5IHBpZDogbnVtYmVyO1xufVxuXG4vKipcbiAqIEFjcXVpcmVzIHRoZSBjcm9zcy1wcm9jZXNzIHNldHVwIGxvY2sgZm9yIHRoZSBnaXZlbiBzY29wZSwgd2FpdGluZyB1bnRpbCBhbnlcbiAqIGNvbXBldGluZyBydW4gcmVsZWFzZXMgaXQgKG9yIGl0cyBsb2NrIGlzIGRldGVjdGVkIGFzIHN0YWxlKS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGxvY2sgcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIEEgaGFuZGxlIHdob3NlIHtAbGluayBTZXR1cExvY2sucmVsZWFzZX0gZnJlZXMgdGhlIGxvY2suXG4gKiBAdGhyb3dzIElmIHRoZSBsb2NrIGNhbm5vdCBiZSBhY3F1aXJlZCB3aXRoaW4gYHRpbWVvdXRJbk1pbGxpc2Vjb25kc2AuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhY3F1aXJlU2V0dXBMb2NrKHBhcmFtczogQWNxdWlyZVNldHVwTG9ja1BhcmFtcyk6IFByb21pc2U8U2V0dXBMb2NrPiB7XG4gIGNvbnN0IHtcbiAgICBsYWJlbCxcbiAgICBzY29wZVxuICB9ID0gcGFyYW1zO1xuICBjb25zdCB0aW1lb3V0SW5NaWxsaXNlY29uZHMgPSBwYXJhbXMudGltZW91dEluTWlsbGlzZWNvbmRzID8/IERFRkFVTFRfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gIGNvbnN0IGxvY2tGaWxlUGF0aCA9IGdldExvY2tGaWxlUGF0aChzY29wZSk7XG4gIG1rZGlyU3luYyhnZXRMb2NrRGlyKCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuXG4gIGNvbnN0IGRlYWRsaW5lSW5NaWxsaXNlY29uZHMgPSBEYXRlLm5vdygpICsgdGltZW91dEluTWlsbGlzZWNvbmRzO1xuICBsZXQgaGFzTG9nZ2VkV2FpdCA9IGZhbHNlO1xuXG4gIGZvciAoOzspIHtcbiAgICBpZiAodHJ5Q3JlYXRlTG9ja0ZpbGUobG9ja0ZpbGVQYXRoLCBsYWJlbCkpIHtcbiAgICAgIHJldHVybiBjcmVhdGVMb2NrSGFuZGxlKGxvY2tGaWxlUGF0aCk7XG4gICAgfVxuXG4gICAgY29uc3QgaW5mbyA9IHJlYWRMb2NrRmlsZUluZm8obG9ja0ZpbGVQYXRoKTtcbiAgICBpZiAoaW5mbyAmJiBpc0xvY2tTdGFsZShpbmZvKSkge1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFN0ZWFsaW5nIHN0YWxlICcke3Njb3BlfScgc2V0dXAgbG9jayBmcm9tICR7ZGVzY3JpYmVJbmZvKGluZm8pfS5gKTtcbiAgICAgIHJtU3luYyhsb2NrRmlsZVBhdGgsIHsgZm9yY2U6IHRydWUgfSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoRGF0ZS5ub3coKSA+PSBkZWFkbGluZUluTWlsbGlzZWNvbmRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBUaW1lZCBvdXQgYWZ0ZXIgJHtTdHJpbmcodGltZW91dEluTWlsbGlzZWNvbmRzKX1tcyB3YWl0aW5nIGZvciB0aGUgJyR7c2NvcGV9JyBpbnRlZ3JhdGlvbi10ZXN0IHNldHVwIGxvY2sgYFxuICAgICAgICAgICsgYGhlbGQgYnkgJHtkZXNjcmliZUhvbGRlcihpbmZvKX0uIEFub3RoZXIgaW50ZWdyYXRpb24tdGVzdCBydW4gaXMgc3RpbGwgaW4gcHJvZ3Jlc3MuYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIWhhc0xvZ2dlZFdhaXQpIHtcbiAgICAgIGhhc0xvZ2dlZFdhaXQgPSB0cnVlO1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFdhaXRpbmcgZm9yIHRoZSAnJHtzY29wZX0nIHNldHVwIGxvY2sgaGVsZCBieSAke2Rlc2NyaWJlSG9sZGVyKGluZm8pfSB0byBiZSByZWxlYXNlZC4uLmApO1xuICAgIH1cblxuICAgIGF3YWl0IGRlbGF5KFBPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSB7QGxpbmsgU2V0dXBMb2NrfSBoYW5kbGUgdGhhdCByZW1vdmVzIHRoZSBsb2NrIGZpbGUgb24gcmVsZWFzZS5cbiAqXG4gKiBAcGFyYW0gbG9ja0ZpbGVQYXRoIC0gVGhlIHBhdGggdG8gdGhlIGxvY2sgZmlsZSB0byByZW1vdmUgb24gcmVsZWFzZS5cbiAqIEByZXR1cm5zIFRoZSBsb2NrIGhhbmRsZS5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlTG9ja0hhbmRsZShsb2NrRmlsZVBhdGg6IHN0cmluZyk6IFNldHVwTG9jayB7XG4gIGxldCBpc1JlbGVhc2VkID0gZmFsc2U7XG4gIHJldHVybiB7XG4gICAgcmVsZWFzZSgpOiB2b2lkIHtcbiAgICAgIGlmIChpc1JlbGVhc2VkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlzUmVsZWFzZWQgPSB0cnVlO1xuICAgICAgcm1TeW5jKGxvY2tGaWxlUGF0aCwgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgYWZ0ZXIgdGhlIGdpdmVuIGRlbGF5LiBVc2VkIHRvIHBvbGwgYmV0d2VlbiBsb2NrLWFjcXVpc2l0aW9uIGF0dGVtcHRzLlxuICpcbiAqIEBwYXJhbSBtaWxsaXNlY29uZHMgLSBUaGUgZGVsYXkgaW4gbWlsbGlzZWNvbmRzLlxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIGRlbGF5LlxuICovXG5mdW5jdGlvbiBkZWxheShtaWxsaXNlY29uZHM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICBzZXRUaW1lb3V0KHJlc29sdmUsIG1pbGxpc2Vjb25kcyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEJ1aWxkcyBhIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIG9mIHRoZSBjdXJyZW50IGxvY2sgaG9sZGVyIGZvciBsb2cvZXJyb3JcbiAqIG1lc3NhZ2VzLlxuICpcbiAqIEBwYXJhbSBpbmZvIC0gVGhlIHBhcnNlZCBsb2NrIGluZm8sIG9yIGB1bmRlZmluZWRgIGlmIGl0IGNvdWxkIG5vdCBiZSByZWFkLlxuICogQHJldHVybnMgQSBkZXNjcmlwdGlvbiBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGRlc2NyaWJlSG9sZGVyKGluZm86IExvY2tGaWxlSW5mbyB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gIHJldHVybiBpbmZvID8gZGVzY3JpYmVJbmZvKGluZm8pIDogJ2Fub3RoZXIgcnVuJztcbn1cblxuLyoqXG4gKiBGb3JtYXRzIGEge0BsaW5rIExvY2tGaWxlSW5mb30gYXMgYSBzaG9ydCBpZGVudGlmaWVyIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gaW5mbyAtIFRoZSBsb2NrIGluZm8uXG4gKiBAcmV0dXJucyBBIHN0cmluZyBsaWtlIGBwaWQgMTIzNCAob2JzaWRpYW4tY2xpKSBvbiBob3N0YC5cbiAqL1xuZnVuY3Rpb24gZGVzY3JpYmVJbmZvKGluZm86IExvY2tGaWxlSW5mbyk6IHN0cmluZyB7XG4gIHJldHVybiBgcGlkICR7U3RyaW5nKGluZm8ucGlkKX0gKCR7aW5mby5sYWJlbH0pIG9uICR7aW5mby5ob3N0bmFtZX1gO1xufVxuXG4vKipcbiAqIEV4dHJhY3RzIHRoZSBgY29kZWAgZnJvbSBhIE5vZGUuanMgc3lzdGVtIGVycm9yLCBpZiBwcmVzZW50LlxuICpcbiAqIEBwYXJhbSBlcnJvciAtIFRoZSB0aHJvd24gdmFsdWUuXG4gKiBAcmV0dXJucyBUaGUgZXJyb3IgY29kZSBzdHJpbmcsIG9yIGB1bmRlZmluZWRgIGlmIG5vdCBhIGNvZGVkIGVycm9yLlxuICovXG5mdW5jdGlvbiBnZXRFcnJvckNvZGUoZXJyb3I6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiAnY29kZScgaW4gZXJyb3IgJiYgdHlwZW9mIGVycm9yLmNvZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGVycm9yLmNvZGU7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzaGFyZWQgbG9jayBkaXJlY3RvcnkgaW5zaWRlIHRoZSBPUyB0ZW1wIGRpcmVjdG9yeS5cbiAqXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgbG9jayBkaXJlY3RvcnkuXG4gKi9cbmZ1bmN0aW9uIGdldExvY2tEaXIoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4odG1wZGlyKCksIExPQ0tfRElSX05BTUUpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGxvY2sgZmlsZSBwYXRoIGZvciB0aGUgZ2l2ZW4gc2NvcGUuXG4gKlxuICogQHBhcmFtIHNjb3BlIC0gVGhlIGxvY2sgc2NvcGUuXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgc2NvcGUncyBsb2NrIGZpbGUuXG4gKi9cbmZ1bmN0aW9uIGdldExvY2tGaWxlUGF0aChzY29wZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4oZ2V0TG9ja0RpcigpLCBgJHtzY29wZX0ke0xPQ0tfRklMRV9TVUZGSVh9YCk7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgbG9jayBjYW4gYmUgY29uc2lkZXJlZCBhYmFuZG9uZWQuXG4gKlxuICogT24gdGhlIHNhbWUgaG9zdCwgdGhlIGhvbGRlcidzIFBJRCBpcyBwcm9iZWQgZGlyZWN0bHk6IGEgZGVhZCBQSUQgbWVhbnMgdGhlXG4gKiBydW4gY3Jhc2hlZCB3aXRob3V0IHJlbGVhc2luZy4gT24gYSBkaWZmZXJlbnQgaG9zdCAoYSBzaGFyZWQvbmV0d29yayB0ZW1wXG4gKiBkaXJlY3RvcnkpIHRoZSBQSUQgY2Fubm90IGJlIHByb2JlZCwgc28gYW4gYWdlIHRocmVzaG9sZCBpcyB1c2VkIGluc3RlYWQuXG4gKlxuICogQHBhcmFtIGluZm8gLSBUaGUgcGFyc2VkIGxvY2sgaW5mby5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbG9jayBpcyBzdGFsZSBhbmQgbWF5IGJlIHN0b2xlbi5cbiAqL1xuZnVuY3Rpb24gaXNMb2NrU3RhbGUoaW5mbzogTG9ja0ZpbGVJbmZvKTogYm9vbGVhbiB7XG4gIGlmIChpbmZvLmhvc3RuYW1lID09PSBob3N0bmFtZSgpKSB7XG4gICAgcmV0dXJuICFpc1Byb2Nlc3NBbGl2ZShpbmZvLnBpZCk7XG4gIH1cblxuICByZXR1cm4gRGF0ZS5ub3coKSAtIGluZm8uYWNxdWlyZWRBdEluTWlsbGlzZWNvbmRzID4gU1RBTEVfTE9DS19BR0VfSU5fTUlMTElTRUNPTkRTO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgcHJvY2VzcyB3aXRoIHRoZSBnaXZlbiBQSUQgaXMgY3VycmVudGx5IGFsaXZlLlxuICpcbiAqIEBwYXJhbSBwaWQgLSBUaGUgcHJvY2VzcyBJRCB0byBwcm9iZS5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvY2VzcyBleGlzdHMuXG4gKi9cbmZ1bmN0aW9uIGlzUHJvY2Vzc0FsaXZlKHBpZDogbnVtYmVyKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgcHJvY2Vzcy5raWxsKHBpZCwgUFJPQ0VTU19FWElTVEVOQ0VfUFJPQkVfU0lHTkFMKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAvLyBgRVBFUk1gIG1lYW5zIHRoZSBwcm9jZXNzIGV4aXN0cyBidXQgaXMgb3duZWQgYnkgYW5vdGhlciB1c2VyIFx1MjAxNCBzdGlsbCBhbGl2ZS5cbiAgICByZXR1cm4gZ2V0RXJyb3JDb2RlKGVycm9yKSA9PT0gJ0VQRVJNJztcbiAgfVxufVxuXG4vKipcbiAqIFJlYWRzIGFuZCBwYXJzZXMgdGhlIGxvY2sgZmlsZSwgaWYgaXQgZXhpc3RzIGFuZCBpcyB2YWxpZCBKU09OLlxuICpcbiAqIEBwYXJhbSBsb2NrRmlsZVBhdGggLSBUaGUgcGF0aCB0byB0aGUgbG9jayBmaWxlLlxuICogQHJldHVybnMgVGhlIHBhcnNlZCBsb2NrIGluZm8sIG9yIGB1bmRlZmluZWRgIGlmIGl0IGNvdWxkIG5vdCBiZSByZWFkLlxuICovXG5mdW5jdGlvbiByZWFkTG9ja0ZpbGVJbmZvKGxvY2tGaWxlUGF0aDogc3RyaW5nKTogTG9ja0ZpbGVJbmZvIHwgdW5kZWZpbmVkIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShyZWFkRmlsZVN5bmMobG9ja0ZpbGVQYXRoLCAndXRmLTgnKSkgYXMgTG9ja0ZpbGVJbmZvO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKlxuICogQXR0ZW1wdHMgdG8gYXRvbWljYWxseSBjcmVhdGUgdGhlIGxvY2sgZmlsZSAoZmFpbGluZyBpZiBpdCBhbHJlYWR5IGV4aXN0cykuXG4gKlxuICogQHBhcmFtIGxvY2tGaWxlUGF0aCAtIFRoZSBwYXRoIHRvIHRoZSBsb2NrIGZpbGUuXG4gKiBAcGFyYW0gbGFiZWwgLSBUaGUgdHJhbnNwb3J0IGxhYmVsIHRvIHJlY29yZCBpbiB0aGUgbG9jayBmaWxlLlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBsb2NrIHdhcyBhY3F1aXJlZCwgYGZhbHNlYCBpZiBpdCBpcyBhbHJlYWR5IGhlbGQuXG4gKiBAdGhyb3dzIElmIHRoZSBmaWxlIHN5c3RlbSBmYWlscyBmb3IgYW55IHJlYXNvbiBvdGhlciB0aGFuIHRoZSBmaWxlIGV4aXN0aW5nLlxuICovXG5mdW5jdGlvbiB0cnlDcmVhdGVMb2NrRmlsZShsb2NrRmlsZVBhdGg6IHN0cmluZywgbGFiZWw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBpbmZvOiBMb2NrRmlsZUluZm8gPSB7XG4gICAgYWNxdWlyZWRBdEluTWlsbGlzZWNvbmRzOiBEYXRlLm5vdygpLFxuICAgIGhvc3RuYW1lOiBob3N0bmFtZSgpLFxuICAgIGxhYmVsLFxuICAgIHBpZDogcHJvY2Vzcy5waWRcbiAgfTtcblxuICB0cnkge1xuICAgIHdyaXRlRmlsZVN5bmMobG9ja0ZpbGVQYXRoLCBKU09OLnN0cmluZ2lmeShpbmZvKSwgeyBmbGFnOiAnd3gnIH0pO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGlmIChnZXRFcnJvckNvZGUoZXJyb3IpID09PSAnRUVYSVNUJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIkFBb0JBO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUDtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMsWUFBWTtBQUNyQixPQUFPLGFBQWE7QUFFcEIsU0FBUyxXQUFXO0FBRXBCLE1BQU0sZ0JBQWdCO0FBQ3RCLE1BQU0sbUJBQW1CO0FBQ3pCLE1BQU0sZ0NBQWdDO0FBQ3RDLE1BQU0sMEJB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
245
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3NldHVwLWxvY2sudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBDcm9zcy1wcm9jZXNzIGFkdmlzb3J5IGxvY2sgdGhhdCBzZXJpYWxpemVzIHdob2xlIGludGVncmF0aW9uLXRlc3QgcnVucy5cbiAqXG4gKiBUd28gdGVzdCBydW5zIHRoYXQgZHJpdmUgdGhlIHNhbWUgc2hhcmVkIHJlc291cmNlcyBjb3JydXB0IGVhY2ggb3RoZXI6IG9uXG4gKiBkZXNrdG9wIHRoZXkgc2hhcmUgdGhlIHNpbmdsZSBsb2NhbCBPYnNpZGlhbiBpbnN0YW5jZSwgaXRzIGBvYnNpZGlhbi5qc29uYFxuICogcmVnaXN0cnksIGFuZCB0aGUgQ0RQIHBvcnQ7IG9uIEFuZHJvaWQgdGhleSBzaGFyZSB0aGUgZW11bGF0b3IgYW5kIHRoZSBBcHBpdW1cbiAqIHNlcnZlci4gT25lIHJ1bidzIHNldHVwL3RlYXJkb3duIGtpbGxzIG9yIHJlY29uZmlndXJlcyB0aGUgaW5zdGFuY2UgdGhlIG90aGVyXG4gKiBydW4gaXMgbWlkLWV2YWwgb24gKG9ic2VydmVkIGFzIGBFQ09OTlJFRlVTRURgIG9yIFwidmF1bHQgbm90IG9wZW5cIiksIHNvIGJvdGhcbiAqIHJ1bnMgZmFpbC5cbiAqXG4gKiBUaGlzIGxvY2sgbWFrZXMgdGhlIHNlY29uZCBydW4gKip3YWl0KiogZm9yIHRoZSBmaXJzdCB0byBmaW5pc2ggaW5zdGVhZCBvZlxuICogcnVubmluZyBjb25jdXJyZW50bHkuIEl0IGlzIGhlbGQgZm9yIHRoZSBlbnRpcmUgcnVuOiBhY3F1aXJlZCBhdCB0aGUgc3RhcnQgb2ZcbiAqIHRoZSBjb3JlIHNldHVwIGFuZCByZWxlYXNlZCBieSB0aGUgY29yZSB0ZWFyZG93biAoYW5kIGJ5IHRoZSBwcm9jZXNzIGNsZWFudXBcbiAqIGhhbmRsZXJzKS4gVGhlIGxvY2sgaXMgYSBzZW50aW5lbCBmaWxlIGluIGEgc2hhcmVkIHRlbXAgZGlyZWN0b3J5LCBhbmQgaXRzXG4gKiBob2xkZXIga2VlcHMgYSAqKmhlYXJ0YmVhdCoqIHRpbWVzdGFtcCBpbnNpZGUgaXQgZnJlc2ggZm9yIGFzIGxvbmcgYXMgaXQgaG9sZHNcbiAqIHRoZSBsb2NrIFx1MjAxNCBzbyBhIHJ1biB0aGF0IGNyYXNoZWQgd2l0aG91dCByZWxlYXNpbmcgc3RvcHMgYmVhdGluZyBhbmQgdGhlIG5leHRcbiAqIHJ1biBkZXRlY3RzIHRoZSBsb2NrIGFzIHN0YWxlIGFuZCBzdGVhbHMgaXQuXG4gKlxuICogVGhlIGhlYXJ0YmVhdCwgbm90IHRoZSBob2xkZXIncyBQSUQsIGlzIHdoYXQgcHJvdmVzIGEgaG9sZGVyIGlzIHN0aWxsIHRoZXJlOiBhXG4gKiBQSUQgcHJvYmUgb25seSBhbnN3ZXJzIFwiZG9lcyAqYSogcHJvY2VzcyB3aXRoIHRoaXMgUElEIGV4aXN0XCIsIHdoaWNoIGFcbiAqIHJlY3ljbGVkIFBJRCBzYXRpc2ZpZXMgbG9uZyBhZnRlciB0aGUgcmVhbCBob2xkZXIgZGllZCBcdTIwMTQgbGVhdmluZyBldmVyeSBsYXRlclxuICogcnVuIHRvIGJsb2NrIGZvciB0aGUgZnVsbCBhY3F1aXNpdGlvbiB0aW1lb3V0LlxuICovXG5cbmltcG9ydCB7XG4gIG1rZGlyU3luYyxcbiAgcmVhZEZpbGVTeW5jLFxuICBybVN5bmMsXG4gIHdyaXRlRmlsZVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBob3N0bmFtZSxcbiAgdG1wZGlyXG59IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQgeyBlcnJvclRvU3RyaW5nIH0gZnJvbSAnLi9lcnJvci10by1zdHJpbmcubWpzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLm1qcyc7XG5cbmNvbnN0IExPQ0tfRElSX05BTUUgPSAnb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZyc7XG5jb25zdCBMT0NLX0ZJTEVfU1VGRklYID0gJy5zZXR1cC5sb2NrJztcbmNvbnN0IFBPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuY29uc3QgTUlMTElTRUNPTkRTX1BFUl9TRUNPTkQgPSAxMDAwO1xuY29uc3QgU0VDT05EU19QRVJfTUlOVVRFID0gNjA7XG5jb25zdCBIRUFSVEJFQVRfSU5URVJWQUxfSU5fU0VDT05EUyA9IDU7XG5jb25zdCBIRUFSVEJFQVRfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gSEVBUlRCRUFUX0lOVEVSVkFMX0lOX1NFQ09ORFMgKiBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORDtcbi8vIEdlbmVyb3VzIG9uIHB1cnBvc2U6IGEgZGVhZCBob2xkZXIgaXMgbm9ybWFsbHkgY2F1Z2h0IGluc3RhbnRseSBieSB0aGUgUElEXG4vLyBQcm9iZSwgc28gdGhpcyB0aHJlc2hvbGQgb25seSBoYXMgdG8gY292ZXIgdGhlIHJlY3ljbGVkLVBJRCBjYXNlLiBUd28gbWludXRlc1xuLy8gS2VlcHMgYSBob2xkZXIgdGhhdCBibG9ja3MgaXRzIGV2ZW50IGxvb3AgZHVyaW5nIGhlYXZ5IHN5bmNocm9ub3VzIHdvcmsgKGFcbi8vIExhcmdlIHZhdWx0IHN5bmMsIGFuIGluc3RhbGxlciB1bnBhY2spIGZyb20gYmVpbmcgcm9iYmVkIHdoaWxlIGl0IGlzIGFsaXZlLlxuY29uc3QgTUlTU0VEX0hFQVJUQkVBVFNfQkVGT1JFX1NUQUxFID0gMjQ7XG5jb25zdCBIRUFSVEJFQVRfU1RBTEVfSU5fTUlMTElTRUNPTkRTID0gSEVBUlRCRUFUX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyAqIE1JU1NFRF9IRUFSVEJFQVRTX0JFRk9SRV9TVEFMRTtcbmNvbnN0IFdBSVRfTE9HX0lOVEVSVkFMX0lOX1NFQ09ORFMgPSAzMDtcbmNvbnN0IFdBSVRfTE9HX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IFdBSVRfTE9HX0lOVEVSVkFMX0lOX1NFQ09ORFMgKiBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORDtcbmNvbnN0IFNUQUxFX0xPQ0tfQUdFX0lOX01JTlVURVMgPSAzMDtcbmNvbnN0IERFRkFVTFRfVElNRU9VVF9JTl9NSU5VVEVTID0gNjA7XG5jb25zdCBTVEFMRV9MT0NLX0FHRV9JTl9NSUxMSVNFQ09ORFMgPSBTVEFMRV9MT0NLX0FHRV9JTl9NSU5VVEVTICogU0VDT05EU19QRVJfTUlOVVRFICogTUlMTElTRUNPTkRTX1BFUl9TRUNPTkQ7XG5jb25zdCBERUZBVUxUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gREVGQVVMVF9USU1FT1VUX0lOX01JTlVURVMgKiBTRUNPTkRTX1BFUl9NSU5VVEUgKiBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORDtcbmNvbnN0IFBST0NFU1NfRVhJU1RFTkNFX1BST0JFX1NJR05BTCA9IDA7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGFjcXVpcmVTZXR1cExvY2t9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFjcXVpcmVTZXR1cExvY2tQYXJhbXMge1xuICAvKiogU2hvcnQgdHJhbnNwb3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMgKGUuZy4gYFwib2JzaWRpYW4tY2xpXCJgKS4gKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgICogTG9naWNhbCBzY29wZSB0aGUgbG9jayBzZXJpYWxpemVzIHdpdGhpbi4gUnVucyB0aGF0IHNoYXJlIHJlc291cmNlcyBtdXN0XG4gICAqIHVzZSB0aGUgc2FtZSBzY29wZSAoZS5nLiBgXCJkZXNrdG9wXCJgIGZvciB0aGUgQ0xJL0NEUCB0cmFuc3BvcnRzLCBgXCJhbmRyb2lkXCJgXG4gICAqIGZvciB0aGUgQXBwaXVtIHRyYW5zcG9ydCkuXG4gICAqL1xuICByZWFkb25seSBzY29wZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBNYXhpbXVtIHRpbWUgdG8gd2FpdCBmb3IgYSBjb21wZXRpbmcgcnVuIHRvIHJlbGVhc2UgdGhlIGxvY2sgYmVmb3JlIGdpdmluZ1xuICAgKiB1cCBhbmQgdGhyb3dpbmcuXG4gICAqXG4gICAqIEBkZWZhdWx0IDEgaG91clxuICAgKi9cbiAgcmVhZG9ubHkgdGltZW91dEluTWlsbGlzZWNvbmRzPzogbnVtYmVyIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEEgaGVsZCBzZXR1cCBsb2NrLiBSZWxlYXNlIGl0IG9uY2UgdGhlIHJ1bidzIHRlYXJkb3duIGlzIGNvbXBsZXRlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNldHVwTG9jayB7XG4gIC8qKiBSZWxlYXNlcyB0aGUgbG9jay4gU2FmZSB0byBjYWxsIG1vcmUgdGhhbiBvbmNlLiAqL1xuICByZWxlYXNlKCk6IHZvaWQ7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGNyZWF0ZUxvY2tIYW5kbGV9LlxuICovXG5pbnRlcmZhY2UgQ3JlYXRlTG9ja0hhbmRsZVBhcmFtcyB7XG4gIC8qKiBUaGUgdHJhbnNwb3J0IGxhYmVsIG9mIHRoaXMgcnVuLiAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKiBUaGUgcGF0aCB0byB0aGUgbG9jayBmaWxlIHRoaXMgcnVuIGp1c3QgY3JlYXRlZC4gKi9cbiAgcmVhZG9ubHkgbG9ja0ZpbGVQYXRoOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSBsb2NrIGluZm8gdGhpcyBydW4gd3JvdGUgd2hlbiBpdCBhY3F1aXJlZCB0aGUgbG9jay4gKi9cbiAgcmVhZG9ubHkgb3duSW5mbzogTG9ja0ZpbGVJbmZvO1xuXG4gIC8qKiBUaGUgbG9jayBzY29wZSwgZm9yIGxvZyBtZXNzYWdlcy4gKi9cbiAgcmVhZG9ubHkgc2NvcGU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgY3JlYXRlVGltZW91dEVycm9yfS5cbiAqL1xuaW50ZXJmYWNlIENyZWF0ZVRpbWVvdXRFcnJvclBhcmFtcyB7XG4gIC8qKiBUaGUgY3VycmVudCBob2xkZXIncyBsb2NrIGluZm8sIG9yIGBudWxsYCBpZiBpdCBjb3VsZCBub3QgYmUgcmVhZC4gKi9cbiAgcmVhZG9ubHkgaW5mbzogTG9ja0ZpbGVJbmZvIHwgbnVsbDtcblxuICAvKiogVGhlIGxvY2sgc2NvcGUuICovXG4gIHJlYWRvbmx5IHNjb3BlOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSB0aW1lb3V0IHRoYXQgZWxhcHNlZC4gKi9cbiAgcmVhZG9ubHkgdGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGZvcm1hdFdhaXRNZXNzYWdlfS5cbiAqL1xuaW50ZXJmYWNlIEZvcm1hdFdhaXRNZXNzYWdlUGFyYW1zIHtcbiAgLyoqIFRoZSBjdXJyZW50IGhvbGRlcidzIGxvY2sgaW5mbywgb3IgYG51bGxgIGlmIGl0IGNvdWxkIG5vdCBiZSByZWFkLiAqL1xuICByZWFkb25seSBpbmZvOiBMb2NrRmlsZUluZm8gfCBudWxsO1xuXG4gIC8qKiBUaGUgdHJhbnNwb3J0IGxhYmVsIG9mIHRoZSB3YWl0aW5nIHJ1bi4gKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKiogSG93IG11Y2ggb2YgdGhlIGFjcXVpc2l0aW9uIHRpbWVvdXQgaXMgbGVmdC4gKi9cbiAgcmVhZG9ubHkgcmVtYWluaW5nSW5NaWxsaXNlY29uZHM6IG51bWJlcjtcblxuICAvKiogVGhlIGxvY2sgc2NvcGUuICovXG4gIHJlYWRvbmx5IHNjb3BlOiBzdHJpbmc7XG5cbiAgLyoqIEhvdyBsb25nIHRoaXMgcnVuIGhhcyBiZWVuIHdhaXRpbmcgc28gZmFyLiAqL1xuICByZWFkb25seSB3YWl0ZWRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xufVxuXG4vKipcbiAqIFRoZSBKU09OIHBheWxvYWQgc3RvcmVkIGluc2lkZSBhIGxvY2sgZmlsZSwgaWRlbnRpZnlpbmcgdGhlIGhvbGRlci5cbiAqL1xuaW50ZXJmYWNlIExvY2tGaWxlSW5mbyB7XG4gIC8qKiBXaGVuIHRoZSBsb2NrIHdhcyBhY3F1aXJlZCAoYERhdGUubm93KClgIGVwb2NoIG1pbGxpc2Vjb25kcykuICovXG4gIHJlYWRvbmx5IGFjcXVpcmVkQXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaGVuIHRoZSBob2xkZXIgbGFzdCBwcm92ZWQgaXQgd2FzIHN0aWxsIGFsaXZlIChgRGF0ZS5ub3coKWAgZXBvY2hcbiAgICogbWlsbGlzZWNvbmRzKSwgcmVmcmVzaGVkIGV2ZXJ5IHtAbGluayBIRUFSVEJFQVRfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTfVxuICAgKiB3aGlsZSB0aGUgbG9jayBpcyBoZWxkLlxuICAgKlxuICAgKiBBYnNlbnQgaW4gYSBsb2NrIGZpbGUgd3JpdHRlbiBieSBhbiBvbGRlciB2ZXJzaW9uIG9mIHRoaXMgcGFja2FnZSwgd2hpY2hcbiAgICogc3RhbXBlZCB0aGUgUElEIGJ1dCBuZXZlciBiZWF0LlxuICAgKi9cbiAgcmVhZG9ubHkgaGVhcnRiZWF0QXRJbk1pbGxpc2Vjb25kcz86IG51bWJlciB8IHVuZGVmaW5lZDtcblxuICAvKiogVGhlIGhvc3QgdGhhdCBob2xkcyB0aGUgbG9jayAoUElEIGxpdmVuZXNzIGlzIG9ubHkgdmFsaWQgb24gdGhlIHNhbWUgaG9zdCkuICovXG4gIHJlYWRvbmx5IGhvc3RuYW1lOiBzdHJpbmc7XG5cbiAgLyoqIFRoZSB0cmFuc3BvcnQgbGFiZWwgb2YgdGhlIGhvbGRpbmcgcnVuLiAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKiBUaGUgcHJvY2VzcyBJRCBvZiB0aGUgaG9sZGluZyBydW4uICovXG4gIHJlYWRvbmx5IHBpZDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayByZWZyZXNoSGVhcnRiZWF0fS5cbiAqL1xuaW50ZXJmYWNlIFJlZnJlc2hIZWFydGJlYXRQYXJhbXMge1xuICAvKiogVGhlIHRyYW5zcG9ydCBsYWJlbCBvZiB0aGlzIHJ1bi4gKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKiogVGhlIHBhdGggdG8gdGhlIGxvY2sgZmlsZSB0byByZWZyZXNoLiAqL1xuICByZWFkb25seSBsb2NrRmlsZVBhdGg6IHN0cmluZztcblxuICAvKiogVGhlIGxvY2sgaW5mbyB0aGlzIHJ1biB3cm90ZSB3aGVuIGl0IGFjcXVpcmVkIHRoZSBsb2NrLiAqL1xuICByZWFkb25seSBvd25JbmZvOiBMb2NrRmlsZUluZm87XG59XG5cbi8qKlxuICogQWNxdWlyZXMgdGhlIGNyb3NzLXByb2Nlc3Mgc2V0dXAgbG9jayBmb3IgdGhlIGdpdmVuIHNjb3BlLCB3YWl0aW5nIHVudGlsIGFueVxuICogY29tcGV0aW5nIHJ1biByZWxlYXNlcyBpdCAob3IgaXRzIGxvY2sgaXMgZGV0ZWN0ZWQgYXMgc3RhbGUpLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgbG9jayBwYXJhbWV0ZXJzLlxuICogQHJldHVybnMgQSBoYW5kbGUgd2hvc2Uge0BsaW5rIFNldHVwTG9jay5yZWxlYXNlfSBmcmVlcyB0aGUgbG9jay5cbiAqIEB0aHJvd3MgSWYgdGhlIGxvY2sgY2Fubm90IGJlIGFjcXVpcmVkIHdpdGhpbiBgdGltZW91dEluTWlsbGlzZWNvbmRzYC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFjcXVpcmVTZXR1cExvY2socGFyYW1zOiBBY3F1aXJlU2V0dXBMb2NrUGFyYW1zKTogUHJvbWlzZTxTZXR1cExvY2s+IHtcbiAgY29uc3Qge1xuICAgIGxhYmVsLFxuICAgIHNjb3BlXG4gIH0gPSBwYXJhbXM7XG4gIGNvbnN0IHRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IHBhcmFtcy50aW1lb3V0SW5NaWxsaXNlY29uZHMgPz8gREVGQVVMVF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgY29uc3QgbG9ja0ZpbGVQYXRoID0gZ2V0TG9ja0ZpbGVQYXRoKHNjb3BlKTtcbiAgbWtkaXJTeW5jKGdldExvY2tEaXIoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgY29uc3Qgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMgPSBEYXRlLm5vdygpO1xuICBjb25zdCBkZWFkbGluZUluTWlsbGlzZWNvbmRzID0gc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMgKyB0aW1lb3V0SW5NaWxsaXNlY29uZHM7XG4gIGxldCBsYXN0TG9nZ2VkV2FpdEF0SW5NaWxsaXNlY29uZHM6IG51bGwgfCBudW1iZXIgPSBudWxsO1xuXG4gIGZvciAoOzspIHtcbiAgICBjb25zdCBvd25JbmZvID0gdHJ5Q3JlYXRlTG9ja0ZpbGUobG9ja0ZpbGVQYXRoLCBsYWJlbCk7XG4gICAgaWYgKG93bkluZm8pIHtcbiAgICAgIHJldHVybiBjcmVhdGVMb2NrSGFuZGxlKHtcbiAgICAgICAgbGFiZWwsXG4gICAgICAgIGxvY2tGaWxlUGF0aCxcbiAgICAgICAgb3duSW5mbyxcbiAgICAgICAgc2NvcGVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGluZm8gPSByZWFkTG9ja0ZpbGVJbmZvKGxvY2tGaWxlUGF0aCk7XG4gICAgaWYgKGluZm8gJiYgY2hlY2tJc0xvY2tTdGFsZShpbmZvKSkge1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFN0ZWFsaW5nIHN0YWxlICcke3Njb3BlfScgc2V0dXAgbG9jayBmcm9tICR7ZGVzY3JpYmVJbmZvKGluZm8pfS5gKTtcbiAgICAgIHJtU3luYyhsb2NrRmlsZVBhdGgsIHsgZm9yY2U6IHRydWUgfSk7XG4gICAgICAvLyBSZXRyeSBpbW1lZGlhdGVseSBcdTIwMTQgYnV0IHN0aWxsIGhvbm91ciB0aGUgZGVhZGxpbmUsIHNvIGEgbG9jayB0aGF0IGFcbiAgICAgIC8vIENvbXBldGluZyBydW4ga2VlcHMgcmVjcmVhdGluZyBjYW5ub3Qgc3BpbiB0aGlzIGxvb3AgZm9yZXZlci5cbiAgICAgIGlmIChEYXRlLm5vdygpID49IGRlYWRsaW5lSW5NaWxsaXNlY29uZHMpIHtcbiAgICAgICAgdGhyb3cgY3JlYXRlVGltZW91dEVycm9yKHtcbiAgICAgICAgICBpbmZvLFxuICAgICAgICAgIHNjb3BlLFxuICAgICAgICAgIHRpbWVvdXRJbk1pbGxpc2Vjb25kc1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IG5vd0luTWlsbGlzZWNvbmRzID0gRGF0ZS5ub3coKTtcbiAgICBpZiAobm93SW5NaWxsaXNlY29uZHMgPj0gZGVhZGxpbmVJbk1pbGxpc2Vjb25kcykge1xuICAgICAgdGhyb3cgY3JlYXRlVGltZW91dEVycm9yKHtcbiAgICAgICAgaW5mbyxcbiAgICAgICAgc2NvcGUsXG4gICAgICAgIHRpbWVvdXRJbk1pbGxpc2Vjb25kc1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2hvdWxkTG9nV2FpdCA9IGxhc3RMb2dnZWRXYWl0QXRJbk1pbGxpc2Vjb25kcyA9PT0gbnVsbFxuICAgICAgfHwgbm93SW5NaWxsaXNlY29uZHMgLSBsYXN0TG9nZ2VkV2FpdEF0SW5NaWxsaXNlY29uZHMgPj0gV0FJVF9MT0dfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTO1xuICAgIGlmIChzaG91bGRMb2dXYWl0KSB7XG4gICAgICBsYXN0TG9nZ2VkV2FpdEF0SW5NaWxsaXNlY29uZHMgPSBub3dJbk1pbGxpc2Vjb25kcztcbiAgICAgIGxvZyhmb3JtYXRXYWl0TWVzc2FnZSh7XG4gICAgICAgIGluZm8sXG4gICAgICAgIGxhYmVsLFxuICAgICAgICByZW1haW5pbmdJbk1pbGxpc2Vjb25kczogZGVhZGxpbmVJbk1pbGxpc2Vjb25kcyAtIG5vd0luTWlsbGlzZWNvbmRzLFxuICAgICAgICBzY29wZSxcbiAgICAgICAgd2FpdGVkSW5NaWxsaXNlY29uZHM6IG5vd0luTWlsbGlzZWNvbmRzIC0gc3RhcnRlZEF0SW5NaWxsaXNlY29uZHNcbiAgICAgIH0pKTtcbiAgICB9XG5cbiAgICBhd2FpdCBkZWxheShQT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgYSBsb2NrIGNhbiBiZSBjb25zaWRlcmVkIGFiYW5kb25lZC5cbiAqXG4gKiBBIGxpdmUgaG9sZGVyIHJlZnJlc2hlcyBpdHMgaGVhcnRiZWF0IGV2ZXJ5XG4gKiB7QGxpbmsgSEVBUlRCRUFUX0lOVEVSVkFMX0lOX01JTExJU0VDT05EU30sIHNvIGEgaGVhcnRiZWF0IHRoYXQgc3RvcHBlZCBtZWFuc1xuICogdGhlIGhvbGRlciBpcyBnb25lLiBUaGF0IGlzIHRoZSBwcmltYXJ5IHNpZ25hbCwgYmVjYXVzZSB0aGUgcmVjb3JkZWQgUElEIGFsb25lXG4gKiBjYW5ub3QgYmUgdHJ1c3RlZDoge0BsaW5rIGNoZWNrSXNQcm9jZXNzQWxpdmV9IG9ubHkgYW5zd2VycyBcImRvZXMgKmEqIHByb2Nlc3NcbiAqIHdpdGggdGhpcyBQSUQgZXhpc3RcIiwgd2hpY2ggYSByZWN5Y2xlZCBQSUQgc2F0aXNmaWVzIGxvbmcgYWZ0ZXIgdGhlIGhvbGRlclxuICogZGllZC5cbiAqXG4gKiBPbiB0aGUgc2FtZSBob3N0IGEgZGVhZCBQSUQgaXMgc3RpbGwgYW4gaW1tZWRpYXRlIGdpdmUtYXdheSwgc28gaXQgaXMga2VwdCBhc1xuICogYSBmYXN0IHBhdGguIE9uIGEgZGlmZmVyZW50IGhvc3QgKGEgc2hhcmVkL25ldHdvcmsgdGVtcCBkaXJlY3RvcnkpIHRoZSBQSURcbiAqIGNhbm5vdCBiZSBwcm9iZWQgYXQgYWxsIGFuZCB0aGUgdHdvIGNsb2NrcyBtYXkgZGlzYWdyZWUsIHNvIHRoZSBtdWNoIHdpZGVyXG4gKiB7QGxpbmsgU1RBTEVfTE9DS19BR0VfSU5fTUlMTElTRUNPTkRTfSB0aHJlc2hvbGQgaXMgdXNlZCBpbnN0ZWFkLlxuICpcbiAqIEBwYXJhbSBpbmZvIC0gVGhlIHBhcnNlZCBsb2NrIGluZm8uXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGxvY2sgaXMgc3RhbGUgYW5kIG1heSBiZSBzdG9sZW4uXG4gKi9cbmZ1bmN0aW9uIGNoZWNrSXNMb2NrU3RhbGUoaW5mbzogTG9ja0ZpbGVJbmZvKTogYm9vbGVhbiB7XG4gIGNvbnN0IHNpbGVudEZvckluTWlsbGlzZWNvbmRzID0gRGF0ZS5ub3coKSAtIGdldExhc3RTZWVuQXRJbk1pbGxpc2Vjb25kcyhpbmZvKTtcblxuICBpZiAoaW5mby5ob3N0bmFtZSA9PT0gaG9zdG5hbWUoKSkge1xuICAgIHJldHVybiAhY2hlY2tJc1Byb2Nlc3NBbGl2ZShpbmZvLnBpZCkgfHwgc2lsZW50Rm9ySW5NaWxsaXNlY29uZHMgPiBIRUFSVEJFQVRfU1RBTEVfSU5fTUlMTElTRUNPTkRTO1xuICB9XG5cbiAgcmV0dXJuIHNpbGVudEZvckluTWlsbGlzZWNvbmRzID4gU1RBTEVfTE9DS19BR0VfSU5fTUlMTElTRUNPTkRTO1xufVxuXG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciBhIGxvY2sgZmlsZSBzdGlsbCBuYW1lcyB0aGlzIHByb2Nlc3MgYXMgaXRzIGhvbGRlci5cbiAqXG4gKiBAcGFyYW0gaW5mbyAtIFRoZSBwYXJzZWQgbG9jayBpbmZvLlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoaXMgcHJvY2VzcyBob2xkcyB0aGUgbG9jay5cbiAqL1xuZnVuY3Rpb24gY2hlY2tJc093bkxvY2soaW5mbzogTG9ja0ZpbGVJbmZvKTogYm9vbGVhbiB7XG4gIHJldHVybiBpbmZvLnBpZCA9PT0gcHJvY2Vzcy5waWQgJiYgaW5mby5ob3N0bmFtZSA9PT0gaG9zdG5hbWUoKTtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIHByb2Nlc3Mgd2l0aCB0aGUgZ2l2ZW4gUElEIGlzIGN1cnJlbnRseSBhbGl2ZS5cbiAqXG4gKiBAcGFyYW0gcGlkIC0gVGhlIHByb2Nlc3MgSUQgdG8gcHJvYmUuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHByb2Nlc3MgZXhpc3RzLlxuICovXG5mdW5jdGlvbiBjaGVja0lzUHJvY2Vzc0FsaXZlKHBpZDogbnVtYmVyKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgcHJvY2Vzcy5raWxsKHBpZCwgUFJPQ0VTU19FWElTVEVOQ0VfUFJPQkVfU0lHTkFMKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAvLyBgRVBFUk1gIG1lYW5zIHRoZSBwcm9jZXNzIGV4aXN0cyBidXQgaXMgb3duZWQgYnkgYW5vdGhlciB1c2VyIFx1MjAxNCBzdGlsbCBhbGl2ZS5cbiAgICByZXR1cm4gZ2V0RXJyb3JDb2RlKGVycm9yKSA9PT0gJ0VQRVJNJztcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSB7QGxpbmsgU2V0dXBMb2NrfSBoYW5kbGUgdGhhdCBrZWVwcyB0aGUgbG9jaydzIGhlYXJ0YmVhdCBmcmVzaCB3aGlsZVxuICogaGVsZCBhbmQgcmVtb3ZlcyB0aGUgbG9jayBmaWxlIG9uIHJlbGVhc2UuXG4gKlxuICogVGhlIGhlYXJ0YmVhdCB0aW1lciBpcyBgdW5yZWZgZWQgc28gaXQgY2FuIG5ldmVyIGtlZXAgdGhlIHByb2Nlc3MgYWxpdmUgb24gaXRzXG4gKiBvd24sIGFuZCBpdCBzdG9wcyBhcyBzb29uIGFzIHRoZSBsb2NrIGZpbGUgbmFtZXMgc29tZWJvZHkgZWxzZSBcdTIwMTQgYSBydW4gd2hvc2VcbiAqIGxvY2sgd2FzIHN0b2xlbiBtdXN0IG5vdCBvdmVyd3JpdGUgaXRzIHN1Y2Nlc3NvcidzIGxvY2ssIG5vciBkZWxldGUgaXQgb25cbiAqIHJlbGVhc2UuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBoYW5kbGUgcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIFRoZSBsb2NrIGhhbmRsZS5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlTG9ja0hhbmRsZShwYXJhbXM6IENyZWF0ZUxvY2tIYW5kbGVQYXJhbXMpOiBTZXR1cExvY2sge1xuICBjb25zdCB7XG4gICAgbGFiZWwsXG4gICAgbG9ja0ZpbGVQYXRoLFxuICAgIG93bkluZm8sXG4gICAgc2NvcGVcbiAgfSA9IHBhcmFtcztcbiAgbGV0IGlzUmVsZWFzZWQgPSBmYWxzZTtcblxuICBjb25zdCBoZWFydGJlYXRUaW1lciA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICBjb25zdCBpc1N0aWxsT3VycyA9IHJlZnJlc2hIZWFydGJlYXQoe1xuICAgICAgbGFiZWwsXG4gICAgICBsb2NrRmlsZVBhdGgsXG4gICAgICBvd25JbmZvXG4gICAgfSk7XG4gICAgaWYgKGlzU3RpbGxPdXJzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNsZWFySW50ZXJ2YWwoaGVhcnRiZWF0VGltZXIpO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBUaGUgJyR7c2NvcGV9JyBzZXR1cCBsb2NrIGlzIG5vIGxvbmdlciBvdXJzIFx1MjAxNCBhbm90aGVyIHJ1biB0b29rIGl0IG92ZXIuIEhlYXJ0YmVhdCBzdG9wcGVkLmApO1xuICB9LCBIRUFSVEJFQVRfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgaGVhcnRiZWF0VGltZXIudW5yZWYoKTtcblxuICByZXR1cm4ge1xuICAgIHJlbGVhc2UoKTogdm9pZCB7XG4gICAgICBpZiAoaXNSZWxlYXNlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpc1JlbGVhc2VkID0gdHJ1ZTtcbiAgICAgIGNsZWFySW50ZXJ2YWwoaGVhcnRiZWF0VGltZXIpO1xuXG4gICAgICBjb25zdCBpbmZvID0gcmVhZExvY2tGaWxlSW5mbyhsb2NrRmlsZVBhdGgpO1xuICAgICAgaWYgKGluZm8gJiYgIWNoZWNrSXNPd25Mb2NrKGluZm8pKSB7XG4gICAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBMZWF2aW5nIHRoZSAnJHtzY29wZX0nIHNldHVwIGxvY2sgaW4gcGxhY2UgXHUyMDE0IGl0IG5vdyBiZWxvbmdzIHRvICR7ZGVzY3JpYmVJbmZvKGluZm8pfS5gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcm1TeW5jKGxvY2tGaWxlUGF0aCwgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBlcnJvciB0aHJvd24gd2hlbiB0aGUgbG9jayBjb3VsZCBub3QgYmUgYWNxdWlyZWQgaW4gdGltZS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGVycm9yIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyBUaGUgZXJyb3IgdG8gdGhyb3cuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVRpbWVvdXRFcnJvcihwYXJhbXM6IENyZWF0ZVRpbWVvdXRFcnJvclBhcmFtcyk6IEVycm9yIHtcbiAgY29uc3Qge1xuICAgIGluZm8sXG4gICAgc2NvcGUsXG4gICAgdGltZW91dEluTWlsbGlzZWNvbmRzXG4gIH0gPSBwYXJhbXM7XG4gIHJldHVybiBuZXcgRXJyb3IoXG4gICAgYFRpbWVkIG91dCBhZnRlciAke1N0cmluZyh0aW1lb3V0SW5NaWxsaXNlY29uZHMpfW1zIHdhaXRpbmcgZm9yIHRoZSAnJHtzY29wZX0nIGludGVncmF0aW9uLXRlc3Qgc2V0dXAgbG9jayBgXG4gICAgICArIGBoZWxkIGJ5ICR7ZGVzY3JpYmVIb2xkZXIoaW5mbyl9LiBBbm90aGVyIGludGVncmF0aW9uLXRlc3QgcnVuIGlzIHN0aWxsIGluIHByb2dyZXNzLmBcbiAgKTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBhZnRlciB0aGUgZ2l2ZW4gZGVsYXkuIFVzZWQgdG8gcG9sbCBiZXR3ZWVuIGxvY2stYWNxdWlzaXRpb24gYXR0ZW1wdHMuXG4gKlxuICogQHBhcmFtIG1pbGxpc2Vjb25kcyAtIFRoZSBkZWxheSBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgZGVsYXkuXG4gKi9cbmZ1bmN0aW9uIGRlbGF5KG1pbGxpc2Vjb25kczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgbWlsbGlzZWNvbmRzKTtcbiAgfSk7XG59XG5cbi8qKlxuICogQnVpbGRzIGEgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhlIGN1cnJlbnQgbG9jayBob2xkZXIgZm9yIGxvZy9lcnJvclxuICogbWVzc2FnZXMuXG4gKlxuICogQHBhcmFtIGluZm8gLSBUaGUgcGFyc2VkIGxvY2sgaW5mbywgb3IgYG51bGxgIGlmIGl0IGNvdWxkIG5vdCBiZSByZWFkLlxuICogQHJldHVybnMgQSBkZXNjcmlwdGlvbiBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGRlc2NyaWJlSG9sZGVyKGluZm86IExvY2tGaWxlSW5mbyB8IG51bGwpOiBzdHJpbmcge1xuICByZXR1cm4gaW5mbyA/IGRlc2NyaWJlSW5mbyhpbmZvKSA6ICdhbm90aGVyIHJ1bic7XG59XG5cbi8qKlxuICogRm9ybWF0cyBhIHtAbGluayBMb2NrRmlsZUluZm99IGFzIGEgc2hvcnQgaWRlbnRpZmllciBzdHJpbmcuXG4gKlxuICogQHBhcmFtIGluZm8gLSBUaGUgbG9jayBpbmZvLlxuICogQHJldHVybnMgQSBzdHJpbmcgbGlrZSBgcGlkIDEyMzQgKG9ic2lkaWFuLWNsaSkgb24gaG9zdGAuXG4gKi9cbmZ1bmN0aW9uIGRlc2NyaWJlSW5mbyhpbmZvOiBMb2NrRmlsZUluZm8pOiBzdHJpbmcge1xuICByZXR1cm4gYHBpZCAke1N0cmluZyhpbmZvLnBpZCl9ICgke2luZm8ubGFiZWx9KSBvbiAke2luZm8uaG9zdG5hbWV9YDtcbn1cblxuLyoqXG4gKiBGb3JtYXRzIGEgZHVyYXRpb24gYXMgYSBjb21wYWN0IGAxbSAzMHNgIC8gYDQ1c2Agc3RyaW5nIGZvciBwcm9ncmVzcyBsb2dzLlxuICpcbiAqIEBwYXJhbSBtaWxsaXNlY29uZHMgLSBUaGUgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLlxuICogQHJldHVybnMgVGhlIGZvcm1hdHRlZCBkdXJhdGlvbi5cbiAqL1xuZnVuY3Rpb24gZm9ybWF0RHVyYXRpb24obWlsbGlzZWNvbmRzOiBudW1iZXIpOiBzdHJpbmcge1xuICBjb25zdCB0b3RhbFNlY29uZHMgPSBNYXRoLnJvdW5kKG1pbGxpc2Vjb25kcyAvIE1JTExJU0VDT05EU19QRVJfU0VDT05EKTtcbiAgY29uc3QgbWludXRlcyA9IE1hdGguZmxvb3IodG90YWxTZWNvbmRzIC8gU0VDT05EU19QRVJfTUlOVVRFKTtcbiAgY29uc3Qgc2Vjb25kcyA9IHRvdGFsU2Vjb25kcyAlIFNFQ09ORFNfUEVSX01JTlVURTtcbiAgcmV0dXJuIG1pbnV0ZXMgPiAwID8gYCR7U3RyaW5nKG1pbnV0ZXMpfW0gJHtTdHJpbmcoc2Vjb25kcyl9c2AgOiBgJHtTdHJpbmcoc2Vjb25kcyl9c2A7XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBwZXJpb2RpYyBcInN0aWxsIHdhaXRpbmdcIiBwcm9ncmVzcyBsaW5lLCBzbyBhIGxlZ2l0aW1hdGUgbXVsdGktbWludXRlXG4gKiB3YWl0IGlzIGRpc3Rpbmd1aXNoYWJsZSBmcm9tIGEgaGFuZyBpbiB0aGUgdGVybWluYWwuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBtZXNzYWdlIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyBUaGUgbWVzc2FnZSB0byBsb2cuXG4gKi9cbmZ1bmN0aW9uIGZvcm1hdFdhaXRNZXNzYWdlKHBhcmFtczogRm9ybWF0V2FpdE1lc3NhZ2VQYXJhbXMpOiBzdHJpbmcge1xuICBjb25zdCB7XG4gICAgaW5mbyxcbiAgICBsYWJlbCxcbiAgICByZW1haW5pbmdJbk1pbGxpc2Vjb25kcyxcbiAgICBzY29wZSxcbiAgICB3YWl0ZWRJbk1pbGxpc2Vjb25kc1xuICB9ID0gcGFyYW1zO1xuICBjb25zdCBoZWxkRm9yID0gaW5mbyA/IGAsIGhlbGQgZm9yICR7Zm9ybWF0RHVyYXRpb24oRGF0ZS5ub3coKSAtIGluZm8uYWNxdWlyZWRBdEluTWlsbGlzZWNvbmRzKX1gIDogJyc7XG4gIHJldHVybiBgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBXYWl0aW5nIGZvciB0aGUgJyR7c2NvcGV9JyBzZXR1cCBsb2NrIGhlbGQgYnkgJHtkZXNjcmliZUhvbGRlcihpbmZvKX0gdG8gYmUgcmVsZWFzZWQgYFxuICAgICsgYCh3YWl0ZWQgJHtmb3JtYXREdXJhdGlvbih3YWl0ZWRJbk1pbGxpc2Vjb25kcyl9JHtoZWxkRm9yfSwgZ2l2aW5nIHVwIGluICR7Zm9ybWF0RHVyYXRpb24ocmVtYWluaW5nSW5NaWxsaXNlY29uZHMpfSkuLi5gO1xufVxuXG4vKipcbiAqIEV4dHJhY3RzIHRoZSBgY29kZWAgZnJvbSBhIE5vZGUuanMgc3lzdGVtIGVycm9yLCBpZiBwcmVzZW50LlxuICpcbiAqIEBwYXJhbSBlcnJvciAtIFRoZSB0aHJvd24gdmFsdWUuXG4gKiBAcmV0dXJucyBUaGUgZXJyb3IgY29kZSBzdHJpbmcsIG9yIGB1bmRlZmluZWRgIGlmIG5vdCBhIGNvZGVkIGVycm9yLlxuICovXG5mdW5jdGlvbiBnZXRFcnJvckNvZGUoZXJyb3I6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiAnY29kZScgaW4gZXJyb3IgJiYgdHlwZW9mIGVycm9yLmNvZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGVycm9yLmNvZGU7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHdoZW4gdGhlIGhvbGRlciB3YXMgbGFzdCBrbm93biB0byBiZSBhbGl2ZSBcdTIwMTQgaXRzIG1vc3QgcmVjZW50IGhlYXJ0YmVhdCxcbiAqIGZhbGxpbmcgYmFjayB0byBpdHMgYWNxdWlzaXRpb24gdGltZSBmb3IgYSBsb2NrIGZpbGUgd3JpdHRlbiBieSBhbiBvbGRlclxuICogdmVyc2lvbiBvZiB0aGlzIHBhY2thZ2UgdGhhdCBzdGFtcGVkIG5vIGhlYXJ0YmVhdCBhdCBhbGwuXG4gKlxuICogQHBhcmFtIGluZm8gLSBUaGUgcGFyc2VkIGxvY2sgaW5mby5cbiAqIEByZXR1cm5zIFRoZSBlcG9jaCBtaWxsaXNlY29uZHMgb2YgdGhlIGhvbGRlcidzIGxhc3Qgc2lnbiBvZiBsaWZlLlxuICovXG5mdW5jdGlvbiBnZXRMYXN0U2VlbkF0SW5NaWxsaXNlY29uZHMoaW5mbzogTG9ja0ZpbGVJbmZvKTogbnVtYmVyIHtcbiAgcmV0dXJuIGluZm8uaGVhcnRiZWF0QXRJbk1pbGxpc2Vjb25kcyA/PyBpbmZvLmFjcXVpcmVkQXRJbk1pbGxpc2Vjb25kcztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzaGFyZWQgbG9jayBkaXJlY3RvcnkgaW5zaWRlIHRoZSBPUyB0ZW1wIGRpcmVjdG9yeS5cbiAqXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgbG9jayBkaXJlY3RvcnkuXG4gKi9cbmZ1bmN0aW9uIGdldExvY2tEaXIoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4odG1wZGlyKCksIExPQ0tfRElSX05BTUUpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGxvY2sgZmlsZSBwYXRoIGZvciB0aGUgZ2l2ZW4gc2NvcGUuXG4gKlxuICogQHBhcmFtIHNjb3BlIC0gVGhlIGxvY2sgc2NvcGUuXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgc2NvcGUncyBsb2NrIGZpbGUuXG4gKi9cbmZ1bmN0aW9uIGdldExvY2tGaWxlUGF0aChzY29wZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4oZ2V0TG9ja0RpcigpLCBgJHtzY29wZX0ke0xPQ0tfRklMRV9TVUZGSVh9YCk7XG59XG5cbi8qKlxuICogUmVhZHMgYW5kIHBhcnNlcyB0aGUgbG9jayBmaWxlLCBpZiBpdCBleGlzdHMgYW5kIGlzIHZhbGlkIEpTT04uXG4gKlxuICogQHBhcmFtIGxvY2tGaWxlUGF0aCAtIFRoZSBwYXRoIHRvIHRoZSBsb2NrIGZpbGUuXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIGxvY2sgaW5mbywgb3IgYG51bGxgIGlmIGl0IGNvdWxkIG5vdCBiZSByZWFkLlxuICovXG5mdW5jdGlvbiByZWFkTG9ja0ZpbGVJbmZvKGxvY2tGaWxlUGF0aDogc3RyaW5nKTogTG9ja0ZpbGVJbmZvIHwgbnVsbCB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UocmVhZEZpbGVTeW5jKGxvY2tGaWxlUGF0aCwgJ3V0Zi04JykpIGFzIExvY2tGaWxlSW5mbztcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXdyaXRlcyB0aGUgbG9jayBmaWxlIHdpdGggYSBmcmVzaCBoZWFydGJlYXQgdGltZXN0YW1wLCBzbyB3YWl0aW5nIHJ1bnMgY2FuXG4gKiB0ZWxsIHRoaXMgaG9sZGVyIGFwYXJ0IGZyb20gYSBjcmFzaGVkIG9uZSB3aG9zZSBQSUQgaGFzIGJlZW4gcmVjeWNsZWQuXG4gKlxuICogQSBsb2NrIGZpbGUgdGhhdCBpcyBtaXNzaW5nIG9yIHVucmVhZGFibGUgaXMgc3RpbGwgdHJlYXRlZCBhcyBvdXJzIGFuZCByZXdyaXR0ZW46XG4gKiB0aGlzIHJ1biBuZXZlciByZWxlYXNlZCwgc28gaXRzIGNsYWltIHN0YW5kcy5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHJlZnJlc2ggcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIGB0cnVlYCB3aGlsZSB0aGUgbG9jayBpcyBzdGlsbCBvdXJzLCBgZmFsc2VgIG9uY2UgYW5vdGhlciBydW4gb3ducyBpdC5cbiAqL1xuZnVuY3Rpb24gcmVmcmVzaEhlYXJ0YmVhdChwYXJhbXM6IFJlZnJlc2hIZWFydGJlYXRQYXJhbXMpOiBib29sZWFuIHtcbiAgY29uc3Qge1xuICAgIGxhYmVsLFxuICAgIGxvY2tGaWxlUGF0aCxcbiAgICBvd25JbmZvXG4gIH0gPSBwYXJhbXM7XG5cbiAgY29uc3QgaW5mbyA9IHJlYWRMb2NrRmlsZUluZm8obG9ja0ZpbGVQYXRoKTtcbiAgaWYgKGluZm8gJiYgIWNoZWNrSXNPd25Mb2NrKGluZm8pKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgcmVmcmVzaGVkSW5mbzogTG9ja0ZpbGVJbmZvID0ge1xuICAgIC4uLm93bkluZm8sXG4gICAgaGVhcnRiZWF0QXRJbk1pbGxpc2Vjb25kczogRGF0ZS5ub3coKVxuICB9O1xuICB0cnkge1xuICAgIHdyaXRlRmlsZVN5bmMobG9ja0ZpbGVQYXRoLCBKU09OLnN0cmluZ2lmeShyZWZyZXNoZWRJbmZvKSk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgLy8gTm90IGZhdGFsOiB0aGUgbG9jayBpcyBzdGlsbCBoZWxkIGFuZCB3aWxsIHN0aWxsIGJlIHJlbGVhc2VkLiBPbmx5IGl0c1xuICAgIC8vIEhlYXJ0YmVhdCBnb2VzIHN0YWxlLCB3aGljaCBhdCB3b3JzdCBsZXRzIGEgd2FpdGluZyBydW4gc3RlYWwgaXQuXG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIEZhaWxlZCB0byByZWZyZXNoIHRoZSBzZXR1cCBsb2NrIGhlYXJ0YmVhdDogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBBdHRlbXB0cyB0byBhdG9taWNhbGx5IGNyZWF0ZSB0aGUgbG9jayBmaWxlIChmYWlsaW5nIGlmIGl0IGFscmVhZHkgZXhpc3RzKS5cbiAqXG4gKiBAcGFyYW0gbG9ja0ZpbGVQYXRoIC0gVGhlIHBhdGggdG8gdGhlIGxvY2sgZmlsZS5cbiAqIEBwYXJhbSBsYWJlbCAtIFRoZSB0cmFuc3BvcnQgbGFiZWwgdG8gcmVjb3JkIGluIHRoZSBsb2NrIGZpbGUuXG4gKiBAcmV0dXJucyBUaGUgbG9jayBpbmZvIHdyaXR0ZW4gb24gc3VjY2Vzcywgb3IgYG51bGxgIGlmIHRoZSBsb2NrIGlzIGFscmVhZHkgaGVsZC5cbiAqIEB0aHJvd3MgSWYgdGhlIGZpbGUgc3lzdGVtIGZhaWxzIGZvciBhbnkgcmVhc29uIG90aGVyIHRoYW4gdGhlIGZpbGUgZXhpc3RpbmcuXG4gKi9cbmZ1bmN0aW9uIHRyeUNyZWF0ZUxvY2tGaWxlKGxvY2tGaWxlUGF0aDogc3RyaW5nLCBsYWJlbDogc3RyaW5nKTogTG9ja0ZpbGVJbmZvIHwgbnVsbCB7XG4gIGNvbnN0IG5vd0luTWlsbGlzZWNvbmRzID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgaW5mbzogTG9ja0ZpbGVJbmZvID0ge1xuICAgIGFjcXVpcmVkQXRJbk1pbGxpc2Vjb25kczogbm93SW5NaWxsaXNlY29uZHMsXG4gICAgaGVhcnRiZWF0QXRJbk1pbGxpc2Vjb25kczogbm93SW5NaWxsaXNlY29uZHMsXG4gICAgaG9zdG5hbWU6IGhvc3RuYW1lKCksXG4gICAgbGFiZWwsXG4gICAgcGlkOiBwcm9jZXNzLnBpZFxuICB9O1xuXG4gIHRyeSB7XG4gICAgd3JpdGVGaWxlU3luYyhsb2NrRmlsZVBhdGgsIEpTT04uc3RyaW5naWZ5KGluZm8pLCB7IGZsYWc6ICd3eCcgfSk7XG4gICAgcmV0dXJuIGluZm87XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgaWYgKGdldEVycm9yQ29kZShlcnJvcikgPT09ICdFRVhJU1QnKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cbiJdLAogICJtYXBwaW5ncyI6ICJBQTBCQTtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1A7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUCxTQUFTLFlBQVk7QUFDckIsT0FBTyxhQUFhO0FBRXBCLFNBQVMscUJBQXFCO0FBQzlCLFNBQVMsV0FBVztBQUVwQixNQUFNLGdCQUFnQjtBQUN0QixNQUFNLG1CQUFtQjtBQUN6QixNQUFNLGdDQUFnQztBQUN0QyxNQUFNLDBCQUEwQjtBQUNoQyxNQUFNLHFCQUFxQjtBQUMzQixNQUFNLGdDQUFnQztBQUN0QyxNQUFNLHFDQUFxQyxnQ0FBZ0M7QUFLM0UsTUFBTSxpQ0FBaUM7QUFDdkMsTUFBTSxrQ0FBa0MscUNBQXFDO0FBQzdFLE1BQU0sK0JBQStCO0FBQ3JDLE1BQU0sb0NBQW9DLCtCQUErQjtBQUN6RSxNQUFNLDRC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
@@ -15,6 +15,7 @@ import {
15
15
  relative
16
16
  } from "node:path";
17
17
  import { getTransportOptions } from "./context-provider.mjs";
18
+ import { TEMP_VAULT_DIR_PREFIX } from "./leftover-cleanup.mjs";
18
19
  import { getOrCreateTransport } from "./transport-factory.mjs";
19
20
  import {
20
21
  registerVault,
@@ -33,7 +34,7 @@ class TempVault {
33
34
  * @param path - An explicit vault path. If omitted, a temp directory is created.
34
35
  */
35
36
  constructor(path) {
36
- this.path = path ?? mkdtempSync(join(tmpdir(), "temp-vault-"));
37
+ this.path = path ?? mkdtempSync(join(tmpdir(), TEMP_VAULT_DIR_PREFIX));
37
38
  }
38
39
  /**
39
40
  * Unregisters the vault from Obsidian and deletes the temp directory.
@@ -153,4 +154,4 @@ async function retryRm(path) {
153
154
  export {
154
155
  TempVault
155
156
  };
156
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RlbXAtdmF1bHQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBNYW5hZ2VzIHRlbXBvcmFyeSB2YXVsdCBsaWZlY3ljbGUgZm9yIGludGVncmF0aW9uIHRlc3RzLlxuICovXG5cbmltcG9ydCB7XG4gIG1rZGlyU3luYyxcbiAgbWtkdGVtcFN5bmMsXG4gIHdyaXRlRmlsZVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICByZWFkZGlyLFxuICByZWFkRmlsZSxcbiAgcm1cbn0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyB0bXBkaXIgfSBmcm9tICdub2RlOm9zJztcbmltcG9ydCB7XG4gIGRpcm5hbWUsXG4gIGpvaW4sXG4gIHJlbGF0aXZlXG59IGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB0eXBlIHsgT2JzaWRpYW5UcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC5tanMnO1xuXG5pbXBvcnQgeyBnZXRUcmFuc3BvcnRPcHRpb25zIH0gZnJvbSAnLi9jb250ZXh0LXByb3ZpZGVyLm1qcyc7XG5pbXBvcnQgeyBnZXRPckNyZWF0ZVRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWZhY3RvcnkubWpzJztcbmltcG9ydCB7XG4gIHJlZ2lzdGVyVmF1bHQsXG4gIHVucmVnaXN0ZXJWYXVsdFxufSBmcm9tICcuL3ZhdWx0LXJlZ2lzdHJ5Lm1qcyc7XG5cbi8qKlxuICogQ29udGVudCB2YWx1ZSBmb3IgYSBzaW5nbGUgZW50cnkgaW4gYSB7QGxpbmsgUG9wdWxhdGVGaWxlc30gbWFwLlxuICpcbiAqIC0gYHN0cmluZ2AgXHUyMDE0IHRleHQgZmlsZSAod3JpdHRlbiBhcyBVVEYtOCkuXG4gKiAtIGBVaW50OEFycmF5YCBcdTIwMTQgYmluYXJ5IGZpbGUgKHdyaXR0ZW4gYXMgcmF3IGJ5dGVzOyBgQnVmZmVyYCBpcyBhY2NlcHRlZFxuICogICBiZWNhdXNlIGBCdWZmZXIgZXh0ZW5kcyBVaW50OEFycmF5YCkuXG4gKiAtIGB1bmRlZmluZWRgIFx1MjAxNCBlbXB0eSBmb2xkZXIgKHRoZSBrZXkgKiptdXN0KiogZW5kIHdpdGggYC9gKS5cbiAqL1xuZXhwb3J0IHR5cGUgUG9wdWxhdGVGaWxlQ29udGVudCA9IHN0cmluZyB8IFVpbnQ4QXJyYXkgfCB1bmRlZmluZWQ7XG5cbi8qKlxuICogQSBtYXAgb2YgdmF1bHQtcmVsYXRpdmUgcGF0aHMgdG8gdGhlaXIgY29udGVudCwgdXNlZCBieVxuICoge0BsaW5rIFRlbXBWYXVsdC5wb3B1bGF0ZX0uXG4gKlxuICogUGF0aHMgZW5kaW5nIHdpdGggYC9gIGRlbm90ZSBmb2xkZXJzIGFuZCAqKm11c3QqKiBoYXZlIGFuIGB1bmRlZmluZWRgIHZhbHVlLlxuICogQWxsIG90aGVyIHBhdGhzIGFyZSB3cml0dGVuIGFzIGZpbGVzLlxuICovXG5leHBvcnQgdHlwZSBQb3B1bGF0ZUZpbGVzUGFyYW1zID0gUmVjb3JkPHN0cmluZywgUG9wdWxhdGVGaWxlQ29udGVudD47XG5cbmNvbnN0IFJNX1JFVFJZX0RFTEFZX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IFJNX1JFVFJZX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMTAwMDA7XG5cbi8qKlxuICogQSB0ZW1wb3JhcnkgT2JzaWRpYW4gdmF1bHQgZm9yIGludGVncmF0aW9uIHRlc3RzLlxuICpcbiAqIENyZWF0ZXMgYSB0ZW1wIGRpcmVjdG9yeSBhbmQgcmVnaXN0ZXJzIGl0IGluIHRoZSBydW5uaW5nIE9ic2lkaWFuIGluc3RhbmNlXG4gKiBzbyB0aGF0IHRoZSBPYnNpZGlhbiBDTEkgY2FuIHRhcmdldCBpdCB2aWEgYGN3ZGAuXG4gKi9cbmV4cG9ydCBjbGFzcyBUZW1wVmF1bHQge1xuICAvKipcbiAgICogVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHRlbXBvcmFyeSB2YXVsdC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBwYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgdGVtcCB2YXVsdC5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggLSBBbiBleHBsaWNpdCB2YXVsdCBwYXRoLiBJZiBvbWl0dGVkLCBhIHRlbXAgZGlyZWN0b3J5IGlzIGNyZWF0ZWQuXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IocGF0aD86IHN0cmluZykge1xuICAgIHRoaXMucGF0aCA9IHBhdGggPz8gbWtkdGVtcFN5bmMoam9pbih0bXBkaXIoKSwgJ3RlbXAtdmF1bHQtJykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucmVnaXN0ZXJzIHRoZSB2YXVsdCBmcm9tIE9ic2lkaWFuIGFuZCBkZWxldGVzIHRoZSB0ZW1wIGRpcmVjdG9yeS5cbiAgICpcbiAgICogQHBhcmFtIHRyYW5zcG9ydE92ZXJyaWRlIC0gQW4gZXhwbGljaXQgdHJhbnNwb3J0IHRvIHVzZSB3aGVuIHVucmVnaXN0ZXJpbmcuXG4gICAqICAgV2hlbiBvbWl0dGVkLCBmYWxscyBiYWNrIHRvIHRoZSB0cmFuc3BvcnQgY29uZmlndXJlZCB2aWEgdGhlIGNvbnRleHQgcHJvdmlkZXIuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZGlzcG9zZSh0cmFuc3BvcnRPdmVycmlkZT86IE9ic2lkaWFuVHJhbnNwb3J0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHVucmVnaXN0ZXJWYXVsdCh0aGlzLnBhdGgsIHRyYW5zcG9ydE92ZXJyaWRlKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgcmV0cnlSbSh0aGlzLnBhdGgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBXcml0ZXMgZmlsZXMgYW5kIGZvbGRlcnMgaW50byB0aGUgdmF1bHQgZGlyZWN0b3J5LlxuICAgKiBQYXJlbnQgZGlyZWN0b3JpZXMgYXJlIGNyZWF0ZWQgYXV0b21hdGljYWxseS5cbiAgICpcbiAgICogLSBgc3RyaW5nYCB2YWx1ZXMgYXJlIHdyaXR0ZW4gYXMgVVRGLTggdGV4dCBmaWxlcy5cbiAgICogLSBgVWludDhBcnJheWAgdmFsdWVzIChpbmNsdWRpbmcgYEJ1ZmZlcmApIGFyZSB3cml0dGVuIGFzIGJpbmFyeSBmaWxlcy5cbiAgICogLSBQYXRocyBlbmRpbmcgd2l0aCBgL2AgYXJlIHRyZWF0ZWQgYXMgZW1wdHkgZm9sZGVycyAodmFsdWUgbXVzdCBiZSBgdW5kZWZpbmVkYCkuXG4gICAqXG4gICAqIEBwYXJhbSBmaWxlcyAtIE1hcCBvZiBmaWxlL2ZvbGRlciBwYXRocyB0byBjb250ZW50LlxuICAgKi9cbiAgcHVibGljIHBvcHVsYXRlKGZpbGVzOiBQb3B1bGF0ZUZpbGVzUGFyYW1zKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBbZmlsZVBhdGgsIGNvbnRlbnRdIG9mIE9iamVjdC5lbnRyaWVzKGZpbGVzKSkge1xuICAgICAgY29uc3QgZnVsbFBhdGggPSBqb2luKHRoaXMucGF0aCwgZmlsZVBhdGgpO1xuICAgICAgaWYgKGZpbGVQYXRoLmVuZHNXaXRoKCcvJykpIHtcbiAgICAgICAgaWYgKGNvbnRlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRm9sZGVyIHBhdGggXCIke2ZpbGVQYXRofVwiIG11c3QgaGF2ZSB1bmRlZmluZWQgY29udGVudGApO1xuICAgICAgICB9XG4gICAgICAgIG1rZGlyU3luYyhmdWxsUGF0aCwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoY29udGVudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGaWxlIHBhdGggXCIke2ZpbGVQYXRofVwiIG11c3QgaGF2ZSBkZWZpbmVkIGNvbnRlbnQ7IHVzZSBhIHRyYWlsaW5nIFwiL1wiIGZvciBmb2xkZXJzYCk7XG4gICAgICAgIH1cbiAgICAgICAgbWtkaXJTeW5jKGRpcm5hbWUoZnVsbFBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgd3JpdGVGaWxlU3luYyhmdWxsUGF0aCwgY29udGVudCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyB0aGlzIHZhdWx0IGluIHRoZSBydW5uaW5nIE9ic2lkaWFuIGluc3RhbmNlIHNvIHRoZSBDTEkgY2FuIHRhcmdldCBpdC5cbiAgICpcbiAgICogQHBhcmFtIHRyYW5zcG9ydE92ZXJyaWRlIC0gQW4gZXhwbGljaXQgdHJhbnNwb3J0IHRvIHVzZS4gV2hlbiBvbWl0dGVkLFxuICAgKiAgIGZhbGxzIGJhY2sgdG8gdGhlIHRyYW5zcG9ydCBjb25maWd1cmVkIHZpYSB0aGUgY29udGV4dCBwcm92aWRlci5cbiAgICovXG4gIHB1YmxpYyBhc3luYyByZWdpc3Rlcih0cmFuc3BvcnRPdmVycmlkZT86IE9ic2lkaWFuVHJhbnNwb3J0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgcmVnaXN0ZXJWYXVsdCh0aGlzLnBhdGgsIHRyYW5zcG9ydE92ZXJyaWRlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc3luYyBkaXNwb3NhYmxlIHN1cHBvcnQgZm9yIGBhd2FpdCB1c2luZ2AuXG4gICAqXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIHZhdWx0IGlzIGRpc3Bvc2VkLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIFtTeW1ib2wuYXN5bmNEaXNwb3NlXSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5kaXNwb3NlKCk7XG4gIH1cblxuICAvKiB2OCBpZ25vcmUgc3RhcnQgLS0gSW50ZWdyYXRpb24tdGltZSBjb2RlIHRoYXQgcmVxdWlyZXMgYSBydW5uaW5nIHRyYW5zcG9ydC4gKi9cblxuICAvKipcbiAgICogUHVzaGVzIGFsbCBmaWxlcyBmcm9tIHRoZSBsb2NhbCBzdGFnaW5nIGRpcmVjdG9yeSB0byB0aGUgdGFyZ2V0IGRldmljZVxuICAgKiB2aWEgdGhlIGFjdGl2ZSB0cmFuc3BvcnQncyBgcHVzaEZpbGVzKClgLlxuICAgKlxuICAgKiBPbiBkZXNrdG9wIHRyYW5zcG9ydHMgdGhpcyBpcyBhIG5vLW9wIChmaWxlcyBhcmUgYWxyZWFkeSBsb2NhbCkuXG4gICAqIE9uIG1vYmlsZSB0cmFuc3BvcnRzIChBcHBpdW0pIHRoaXMgcHVzaGVzIGZpbGVzIHRvIHRoZSBkZXZpY2UuXG4gICAqXG4gICAqIENhbGwgdGhpcyBhZnRlciB7QGxpbmsgcG9wdWxhdGV9IGFuZCBiZWZvcmUge0BsaW5rIHJlZ2lzdGVyfSB3aGVuIHVzaW5nXG4gICAqIGEgbW9iaWxlIHRyYW5zcG9ydC5cbiAgICpcbiAgICogQHBhcmFtIHRyYW5zcG9ydE92ZXJyaWRlIC0gQW4gZXhwbGljaXQgdHJhbnNwb3J0IHRvIHVzZS4gV2hlbiBvbWl0dGVkLFxuICAgKiAgIGZhbGxzIGJhY2sgdG8gdGhlIHRyYW5zcG9ydCBjb25maWd1cmVkIHZpYSB0aGUgY29udGV4dCBwcm92aWRlci5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBzeW5jVG9EZXZpY2UodHJhbnNwb3J0T3ZlcnJpZGU/OiBPYnNpZGlhblRyYW5zcG9ydCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHRyYW5zcG9ydCA9IHRyYW5zcG9ydE92ZXJyaWRlID8/IGF3YWl0IGdldE9yQ3JlYXRlVHJhbnNwb3J0KGdldFRyYW5zcG9ydE9wdGlvbnMoKSk7XG4gICAgaWYgKCF0cmFuc3BvcnQucHVzaEZpbGVzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZmlsZXMgPSBhd2FpdCB0aGlzLmNvbGxlY3RGaWxlcyh0aGlzLnBhdGgpO1xuICAgIGF3YWl0IHRyYW5zcG9ydC5wdXNoRmlsZXModGhpcy5wYXRoLCBmaWxlcyk7XG4gIH1cblxuICAvKipcbiAgICogUmVjdXJzaXZlbHkgcmVhZHMgYWxsIGZpbGVzIGZyb20gYSBkaXJlY3RvcnkgaW50byBhIGZsYXQgbWFwLlxuICAgKlxuICAgKiBAcGFyYW0gZGlyIC0gVGhlIGRpcmVjdG9yeSB0byByZWFkLlxuICAgKiBAcmV0dXJucyBBIG1hcCBvZiByZWxhdGl2ZSBmaWxlIHBhdGhzIHRvIGNvbnRlbnQgYnVmZmVycy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY29sbGVjdEZpbGVzKGRpcjogc3RyaW5nKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBVaW50OEFycmF5Pj4ge1xuICAgIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgVWludDhBcnJheT4gPSB7fTtcbiAgICBjb25zdCBlbnRyaWVzID0gYXdhaXQgcmVhZGRpcihkaXIsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KTtcblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgY29uc3QgZnVsbFBhdGggPSBqb2luKGRpciwgZW50cnkubmFtZSk7XG4gICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSByZWxhdGl2ZSh0aGlzLnBhdGgsIGZ1bGxQYXRoKTtcblxuICAgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihyZXN1bHQsIGF3YWl0IHRoaXMuY29sbGVjdEZpbGVzKGZ1bGxQYXRoKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRbcmVsYXRpdmVQYXRoXSA9IGF3YWl0IHJlYWRGaWxlKGZ1bGxQYXRoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIC8qIHY4IGlnbm9yZSBzdG9wICovXG59XG5cbi8qKlxuICogUmV0cmllcyBgcm1gIHVudGlsIGl0IHN1Y2NlZWRzIG9yIHRpbWVzIG91dC5cbiAqIE9ic2lkaWFuIG1heSBob2xkIGZpbGUgbG9ja3MgYnJpZWZseSBhZnRlciBhIHdpbmRvdyBpcyBkZXN0cm95ZWQuXG4gKlxuICogQHBhcmFtIHBhdGggLSBUaGUgcGF0aCB0byB0aGUgZGlyZWN0b3J5IHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGRpcmVjdG9yeSBpcyByZW1vdmVkLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXRyeVJtKHBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBSTV9SRVRSWV9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBybShwYXRoLCB7IGZvcmNlOiB0cnVlLCByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICByZXR1cm47XG4gICAgfSBjYXRjaCB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIFJNX1JFVFJZX0RFTEFZX0lOX01JTExJU0VDT05EUyk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgLy8gRmluYWwgYXR0ZW1wdCBcdTIwMTQgbGV0IGl0IHRocm93LlxuICBhd2FpdCBybShwYXRoLCB7IGZvcmNlOiB0cnVlLCByZWN1cnNpdmU6IHRydWUgfSk7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiQUFNQTtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUDtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUCxTQUFTLGNBQWM7QUFDdkI7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBSVAsU0FBUywyQkFBMkI7QUFDcEMsU0FBUyw0QkFBNEI7QUFDckM7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFxQlAsTUFBTSxpQ0FBaUM7QUFDdkMsTUFBTSxtQ0FBbUM7QUFRbEMsTUFBTSxVQUFVO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFJTDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9ULFlBQVksTUFBZTtBQUNoQyxTQUFLLE9BQU8sUUFBUSxZQUFZLEtBQUssT0FBTyxHQUFHLGFBQWEsQ0FBQztBQUFBLEVBQy9EO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFRQSxNQUFhLFFBQVEsbUJBQXNEO0FBQ3pFLFFBQUk7QUFDRixZQUFNLGdCQUFnQixLQUFLLE1BQU0saUJBQWlCO0FBQUEsSUFDcEQsVUFBRTtBQUNBLFlBQU0sUUFBUSxLQUFLLElBQUk7QUFBQSxJQUN6QjtBQUFBLEVBQ0Y7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBWU8sU0FBUyxPQUFrQztBQUNoRCxlQUFXLENBQUMsVUFBVSxPQUFPLEtBQUssT0FBTyxRQUFRLEtBQUssR0FBRztBQUN2RCxZQUFNLFdBQVcsS0FBSyxLQUFLLE1BQU0sUUFBUTtBQUN6QyxVQUFJLFNBQVMsU0FBUyxHQUFHLEdBQUc7QUFDMUIsWUFBSSxZQUFZLFFBQVc7QUFDekIsZ0JBQU0sSUFBSSxNQUFNLGdCQUFnQixRQUFRLCtCQUErQjtBQUFBLFFBQ3pFO0FBQ0Esa0JBQVUsVUFBVSxFQUFFLFdBQVcsS0FBSyxDQUFDO0FBQUEsTUFDekMsT0FBTztBQUNMLFlBQUksWUFBWSxRQUFXO0FBQ3pCLGdCQUFNLElBQUksTUFBTSxjQUFjLFFBQVEsNkRBQTZEO0FBQUEsUUFDckc7QUFDQSxrQkFBVSxRQUFRLFFBQVEsR0FBRyxFQUFFLFdBQVcsS0FBSyxDQUFDO0FBQ2hELHNCQUFjLFVBQVUsT0FBTztBQUFBLE1BQ2pDO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVFBLE1BQWEsU0FBUyxtQkFBc0Q7QUFDMUUsVUFBTSxjQUFjLEtBQUssTUFBTSxpQkFBaUI7QUFBQSxFQUNsRDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9BLE9BQWMsT0FBTyxZQUFZLElBQW1CO0FBQ2xELFdBQU8sS0FBSyxRQUFRO0FBQUEsRUFDdEI7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFpQkEsTUFBYSxhQUFhLG1CQUFzRDtBQUM5RSxVQUFNLFlBQVkscUJBQXFCLE1BQU0scUJBQXFCLG9CQUFvQixDQUFDO0FBQ3ZGLFFBQUksQ0FBQyxVQUFVLFdBQVc7QUFDeEI7QUFBQSxJQUNGO0FBRUEsVUFBTSxRQUFRLE1BQU0sS0FBSyxhQUFhLEtBQUssSUFBSTtBQUMvQyxVQUFNLFVBQVUsVUFBVSxLQUFLLE1BQU0sS0FBSztBQUFBLEVBQzVDO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFRQSxNQUFjLGFBQWEsS0FBa0Q7QUFDM0UsVUFBTSxTQUFxQyxDQUFDO0FBQzVDLFVBQU0sVUFBVSxNQUFNLFFBQVEsS0FBSyxFQUFFLGVBQWUsS0FBSyxDQUFDO0FBRTFELGVBQVcsU0FBUyxTQUFTO0FBQzNCLFlBQU0sV0FBVyxLQUFLLEtBQUssTUFBTSxJQUFJO0FBQ3JDLFlBQU0sZUFBZSxTQUFTLEtBQUssTUFBTSxRQUFRO0FBRWpELFVBQUksTUFBTSxZQUFZLEdBQUc7QUFDdkIsZUFBTyxPQUFPLFFBQVEsTUFBTSxLQUFLLGFBQWEsUUFBUSxDQUFDO0FBQUEsTUFDekQsT0FBTztBQUNMLGVBQU8sWUFBWSxJQUFJLE1BQU0sU0FBUyxRQUFRO0FBQUEsTUFDaEQ7QUFBQSxJQUNGO0FBRUEsV0FBTztBQUFBLEVBQ1Q7QUFBQTtBQUVGO0FBU0EsZUFBZSxRQUFRLE1BQTZCO0FBQ2xELFFBQU0sV0FBVyxLQUFLLElBQUksSUFBSTtBQUM5QixTQUFPLEtBQUssSUFBSSxJQUFJLFVBQVU7QUFDNUIsUUFBSTtBQUNGLFlBQU0sR0FBRyxNQUFNLEVBQUUsT0FBTyxNQUFNLFdBQVcsS0FBSyxDQUFDO0FBQy9DO0FBQUEsSUFDRixRQUFRO0FBQ04sWUFBTSxJQUFJLFFBQVEsQ0FBQyxZQUFZO0FBQzdCLG1CQUFXLFNBQVMsOEJBQThCO0FBQUEsTUFDcEQsQ0FBQztBQUFBLElBQ0g7QUFBQSxFQUNGO0FBRUEsUUFBTSxHQUFHLE1BQU0sRUFBRSxPQUFPLE1BQU0sV0FBVyxLQUFLLENBQUM7QUFDakQ7IiwKICAibmFtZXMiOiBbXQp9Cg==
157
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RlbXAtdmF1bHQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBNYW5hZ2VzIHRlbXBvcmFyeSB2YXVsdCBsaWZlY3ljbGUgZm9yIGludGVncmF0aW9uIHRlc3RzLlxuICovXG5cbmltcG9ydCB7XG4gIG1rZGlyU3luYyxcbiAgbWtkdGVtcFN5bmMsXG4gIHdyaXRlRmlsZVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICByZWFkZGlyLFxuICByZWFkRmlsZSxcbiAgcm1cbn0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyB0bXBkaXIgfSBmcm9tICdub2RlOm9zJztcbmltcG9ydCB7XG4gIGRpcm5hbWUsXG4gIGpvaW4sXG4gIHJlbGF0aXZlXG59IGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB0eXBlIHsgT2JzaWRpYW5UcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC5tanMnO1xuXG5pbXBvcnQgeyBnZXRUcmFuc3BvcnRPcHRpb25zIH0gZnJvbSAnLi9jb250ZXh0LXByb3ZpZGVyLm1qcyc7XG5pbXBvcnQgeyBURU1QX1ZBVUxUX0RJUl9QUkVGSVggfSBmcm9tICcuL2xlZnRvdmVyLWNsZWFudXAubWpzJztcbmltcG9ydCB7IGdldE9yQ3JlYXRlVHJhbnNwb3J0IH0gZnJvbSAnLi90cmFuc3BvcnQtZmFjdG9yeS5tanMnO1xuaW1wb3J0IHtcbiAgcmVnaXN0ZXJWYXVsdCxcbiAgdW5yZWdpc3RlclZhdWx0XG59IGZyb20gJy4vdmF1bHQtcmVnaXN0cnkubWpzJztcblxuLyoqXG4gKiBDb250ZW50IHZhbHVlIGZvciBhIHNpbmdsZSBlbnRyeSBpbiBhIHtAbGluayBQb3B1bGF0ZUZpbGVzfSBtYXAuXG4gKlxuICogLSBgc3RyaW5nYCBcdTIwMTQgdGV4dCBmaWxlICh3cml0dGVuIGFzIFVURi04KS5cbiAqIC0gYFVpbnQ4QXJyYXlgIFx1MjAxNCBiaW5hcnkgZmlsZSAod3JpdHRlbiBhcyByYXcgYnl0ZXM7IGBCdWZmZXJgIGlzIGFjY2VwdGVkXG4gKiAgIGJlY2F1c2UgYEJ1ZmZlciBleHRlbmRzIFVpbnQ4QXJyYXlgKS5cbiAqIC0gYHVuZGVmaW5lZGAgXHUyMDE0IGVtcHR5IGZvbGRlciAodGhlIGtleSAqKm11c3QqKiBlbmQgd2l0aCBgL2ApLlxuICovXG5leHBvcnQgdHlwZSBQb3B1bGF0ZUZpbGVDb250ZW50ID0gc3RyaW5nIHwgVWludDhBcnJheSB8IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBBIG1hcCBvZiB2YXVsdC1yZWxhdGl2ZSBwYXRocyB0byB0aGVpciBjb250ZW50LCB1c2VkIGJ5XG4gKiB7QGxpbmsgVGVtcFZhdWx0LnBvcHVsYXRlfS5cbiAqXG4gKiBQYXRocyBlbmRpbmcgd2l0aCBgL2AgZGVub3RlIGZvbGRlcnMgYW5kICoqbXVzdCoqIGhhdmUgYW4gYHVuZGVmaW5lZGAgdmFsdWUuXG4gKiBBbGwgb3RoZXIgcGF0aHMgYXJlIHdyaXR0ZW4gYXMgZmlsZXMuXG4gKi9cbmV4cG9ydCB0eXBlIFBvcHVsYXRlRmlsZXNQYXJhbXMgPSBSZWNvcmQ8c3RyaW5nLCBQb3B1bGF0ZUZpbGVDb250ZW50PjtcblxuY29uc3QgUk1fUkVUUllfREVMQVlfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuY29uc3QgUk1fUkVUUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAxMDAwMDtcblxuLyoqXG4gKiBBIHRlbXBvcmFyeSBPYnNpZGlhbiB2YXVsdCBmb3IgaW50ZWdyYXRpb24gdGVzdHMuXG4gKlxuICogQ3JlYXRlcyBhIHRlbXAgZGlyZWN0b3J5IGFuZCByZWdpc3RlcnMgaXQgaW4gdGhlIHJ1bm5pbmcgT2JzaWRpYW4gaW5zdGFuY2VcbiAqIHNvIHRoYXQgdGhlIE9ic2lkaWFuIENMSSBjYW4gdGFyZ2V0IGl0IHZpYSBgY3dkYC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRlbXBWYXVsdCB7XG4gIC8qKlxuICAgKiBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgdGVtcG9yYXJ5IHZhdWx0LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHBhdGg6IHN0cmluZztcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyB0ZW1wIHZhdWx0LlxuICAgKlxuICAgKiBAcGFyYW0gcGF0aCAtIEFuIGV4cGxpY2l0IHZhdWx0IHBhdGguIElmIG9taXR0ZWQsIGEgdGVtcCBkaXJlY3RvcnkgaXMgY3JlYXRlZC5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihwYXRoPzogc3RyaW5nKSB7XG4gICAgdGhpcy5wYXRoID0gcGF0aCA/PyBta2R0ZW1wU3luYyhqb2luKHRtcGRpcigpLCBURU1QX1ZBVUxUX0RJUl9QUkVGSVgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnJlZ2lzdGVycyB0aGUgdmF1bHQgZnJvbSBPYnNpZGlhbiBhbmQgZGVsZXRlcyB0aGUgdGVtcCBkaXJlY3RvcnkuXG4gICAqXG4gICAqIEBwYXJhbSB0cmFuc3BvcnRPdmVycmlkZSAtIEFuIGV4cGxpY2l0IHRyYW5zcG9ydCB0byB1c2Ugd2hlbiB1bnJlZ2lzdGVyaW5nLlxuICAgKiAgIFdoZW4gb21pdHRlZCwgZmFsbHMgYmFjayB0byB0aGUgdHJhbnNwb3J0IGNvbmZpZ3VyZWQgdmlhIHRoZSBjb250ZXh0IHByb3ZpZGVyLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGRpc3Bvc2UodHJhbnNwb3J0T3ZlcnJpZGU/OiBPYnNpZGlhblRyYW5zcG9ydCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB1bnJlZ2lzdGVyVmF1bHQodGhpcy5wYXRoLCB0cmFuc3BvcnRPdmVycmlkZSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHJldHJ5Um0odGhpcy5wYXRoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogV3JpdGVzIGZpbGVzIGFuZCBmb2xkZXJzIGludG8gdGhlIHZhdWx0IGRpcmVjdG9yeS5cbiAgICogUGFyZW50IGRpcmVjdG9yaWVzIGFyZSBjcmVhdGVkIGF1dG9tYXRpY2FsbHkuXG4gICAqXG4gICAqIC0gYHN0cmluZ2AgdmFsdWVzIGFyZSB3cml0dGVuIGFzIFVURi04IHRleHQgZmlsZXMuXG4gICAqIC0gYFVpbnQ4QXJyYXlgIHZhbHVlcyAoaW5jbHVkaW5nIGBCdWZmZXJgKSBhcmUgd3JpdHRlbiBhcyBiaW5hcnkgZmlsZXMuXG4gICAqIC0gUGF0aHMgZW5kaW5nIHdpdGggYC9gIGFyZSB0cmVhdGVkIGFzIGVtcHR5IGZvbGRlcnMgKHZhbHVlIG11c3QgYmUgYHVuZGVmaW5lZGApLlxuICAgKlxuICAgKiBAcGFyYW0gZmlsZXMgLSBNYXAgb2YgZmlsZS9mb2xkZXIgcGF0aHMgdG8gY29udGVudC5cbiAgICovXG4gIHB1YmxpYyBwb3B1bGF0ZShmaWxlczogUG9wdWxhdGVGaWxlc1BhcmFtcyk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgW2ZpbGVQYXRoLCBjb250ZW50XSBvZiBPYmplY3QuZW50cmllcyhmaWxlcykpIHtcbiAgICAgIGNvbnN0IGZ1bGxQYXRoID0gam9pbih0aGlzLnBhdGgsIGZpbGVQYXRoKTtcbiAgICAgIGlmIChmaWxlUGF0aC5lbmRzV2l0aCgnLycpKSB7XG4gICAgICAgIGlmIChjb250ZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZvbGRlciBwYXRoIFwiJHtmaWxlUGF0aH1cIiBtdXN0IGhhdmUgdW5kZWZpbmVkIGNvbnRlbnRgKTtcbiAgICAgICAgfVxuICAgICAgICBta2RpclN5bmMoZnVsbFBhdGgsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGNvbnRlbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmlsZSBwYXRoIFwiJHtmaWxlUGF0aH1cIiBtdXN0IGhhdmUgZGVmaW5lZCBjb250ZW50OyB1c2UgYSB0cmFpbGluZyBcIi9cIiBmb3IgZm9sZGVyc2ApO1xuICAgICAgICB9XG4gICAgICAgIG1rZGlyU3luYyhkaXJuYW1lKGZ1bGxQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICAgIHdyaXRlRmlsZVN5bmMoZnVsbFBhdGgsIGNvbnRlbnQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgdGhpcyB2YXVsdCBpbiB0aGUgcnVubmluZyBPYnNpZGlhbiBpbnN0YW5jZSBzbyB0aGUgQ0xJIGNhbiB0YXJnZXQgaXQuXG4gICAqXG4gICAqIEBwYXJhbSB0cmFuc3BvcnRPdmVycmlkZSAtIEFuIGV4cGxpY2l0IHRyYW5zcG9ydCB0byB1c2UuIFdoZW4gb21pdHRlZCxcbiAgICogICBmYWxscyBiYWNrIHRvIHRoZSB0cmFuc3BvcnQgY29uZmlndXJlZCB2aWEgdGhlIGNvbnRleHQgcHJvdmlkZXIuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVnaXN0ZXIodHJhbnNwb3J0T3ZlcnJpZGU/OiBPYnNpZGlhblRyYW5zcG9ydCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHJlZ2lzdGVyVmF1bHQodGhpcy5wYXRoLCB0cmFuc3BvcnRPdmVycmlkZSk7XG4gIH1cblxuICAvKipcbiAgICogQXN5bmMgZGlzcG9zYWJsZSBzdXBwb3J0IGZvciBgYXdhaXQgdXNpbmdgLlxuICAgKlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSB2YXVsdCBpcyBkaXNwb3NlZC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBbU3ltYm9sLmFzeW5jRGlzcG9zZV0oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcG9zZSgpO1xuICB9XG5cbiAgLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgY29kZSB0aGF0IHJlcXVpcmVzIGEgcnVubmluZyB0cmFuc3BvcnQuICovXG5cbiAgLyoqXG4gICAqIFB1c2hlcyBhbGwgZmlsZXMgZnJvbSB0aGUgbG9jYWwgc3RhZ2luZyBkaXJlY3RvcnkgdG8gdGhlIHRhcmdldCBkZXZpY2VcbiAgICogdmlhIHRoZSBhY3RpdmUgdHJhbnNwb3J0J3MgYHB1c2hGaWxlcygpYC5cbiAgICpcbiAgICogT24gZGVza3RvcCB0cmFuc3BvcnRzIHRoaXMgaXMgYSBuby1vcCAoZmlsZXMgYXJlIGFscmVhZHkgbG9jYWwpLlxuICAgKiBPbiBtb2JpbGUgdHJhbnNwb3J0cyAoQXBwaXVtKSB0aGlzIHB1c2hlcyBmaWxlcyB0byB0aGUgZGV2aWNlLlxuICAgKlxuICAgKiBDYWxsIHRoaXMgYWZ0ZXIge0BsaW5rIHBvcHVsYXRlfSBhbmQgYmVmb3JlIHtAbGluayByZWdpc3Rlcn0gd2hlbiB1c2luZ1xuICAgKiBhIG1vYmlsZSB0cmFuc3BvcnQuXG4gICAqXG4gICAqIEBwYXJhbSB0cmFuc3BvcnRPdmVycmlkZSAtIEFuIGV4cGxpY2l0IHRyYW5zcG9ydCB0byB1c2UuIFdoZW4gb21pdHRlZCxcbiAgICogICBmYWxscyBiYWNrIHRvIHRoZSB0cmFuc3BvcnQgY29uZmlndXJlZCB2aWEgdGhlIGNvbnRleHQgcHJvdmlkZXIuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc3luY1RvRGV2aWNlKHRyYW5zcG9ydE92ZXJyaWRlPzogT2JzaWRpYW5UcmFuc3BvcnQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB0cmFuc3BvcnQgPSB0cmFuc3BvcnRPdmVycmlkZSA/PyBhd2FpdCBnZXRPckNyZWF0ZVRyYW5zcG9ydChnZXRUcmFuc3BvcnRPcHRpb25zKCkpO1xuICAgIGlmICghdHJhbnNwb3J0LnB1c2hGaWxlcykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGZpbGVzID0gYXdhaXQgdGhpcy5jb2xsZWN0RmlsZXModGhpcy5wYXRoKTtcbiAgICBhd2FpdCB0cmFuc3BvcnQucHVzaEZpbGVzKHRoaXMucGF0aCwgZmlsZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY3Vyc2l2ZWx5IHJlYWRzIGFsbCBmaWxlcyBmcm9tIGEgZGlyZWN0b3J5IGludG8gYSBmbGF0IG1hcC5cbiAgICpcbiAgICogQHBhcmFtIGRpciAtIFRoZSBkaXJlY3RvcnkgdG8gcmVhZC5cbiAgICogQHJldHVybnMgQSBtYXAgb2YgcmVsYXRpdmUgZmlsZSBwYXRocyB0byBjb250ZW50IGJ1ZmZlcnMuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNvbGxlY3RGaWxlcyhkaXI6IHN0cmluZyk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgVWludDhBcnJheT4+IHtcbiAgICBjb25zdCByZXN1bHQ6IFJlY29yZDxzdHJpbmcsIFVpbnQ4QXJyYXk+ID0ge307XG4gICAgY29uc3QgZW50cmllcyA9IGF3YWl0IHJlYWRkaXIoZGlyLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XG5cbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgIGNvbnN0IGZ1bGxQYXRoID0gam9pbihkaXIsIGVudHJ5Lm5hbWUpO1xuICAgICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcmVsYXRpdmUodGhpcy5wYXRoLCBmdWxsUGF0aCk7XG5cbiAgICAgIGlmIChlbnRyeS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIE9iamVjdC5hc3NpZ24ocmVzdWx0LCBhd2FpdCB0aGlzLmNvbGxlY3RGaWxlcyhmdWxsUGF0aCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0W3JlbGF0aXZlUGF0aF0gPSBhd2FpdCByZWFkRmlsZShmdWxsUGF0aCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICAvKiB2OCBpZ25vcmUgc3RvcCAqL1xufVxuXG4vKipcbiAqIFJldHJpZXMgYHJtYCB1bnRpbCBpdCBzdWNjZWVkcyBvciB0aW1lcyBvdXQuXG4gKiBPYnNpZGlhbiBtYXkgaG9sZCBmaWxlIGxvY2tzIGJyaWVmbHkgYWZ0ZXIgYSB3aW5kb3cgaXMgZGVzdHJveWVkLlxuICpcbiAqIEBwYXJhbSBwYXRoIC0gVGhlIHBhdGggdG8gdGhlIGRpcmVjdG9yeSB0byByZW1vdmUuXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBkaXJlY3RvcnkgaXMgcmVtb3ZlZC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmV0cnlSbShwYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgUk1fUkVUUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgcm0ocGF0aCwgeyBmb3JjZTogdHJ1ZSwgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH0gY2F0Y2gge1xuICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgc2V0VGltZW91dChyZXNvbHZlLCBSTV9SRVRSWV9ERUxBWV9JTl9NSUxMSVNFQ09ORFMpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIC8vIEZpbmFsIGF0dGVtcHQgXHUyMDE0IGxldCBpdCB0aHJvdy5cbiAgYXdhaXQgcm0ocGF0aCwgeyBmb3JjZTogdHJ1ZSwgcmVjdXJzaXZlOiB0cnVlIH0pO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIkFBTUE7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1A7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1AsU0FBUyxjQUFjO0FBQ3ZCO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUlQLFNBQVMsMkJBQTJCO0FBQ3BDLFNBQVMsNkJBQTZCO0FBQ3RDLFNBQVMsNEJBQTRCO0FBQ3JDO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBcUJQLE1BQU0saUNBQWlDO0FBQ3ZDLE1BQU0sbUNBQW1DO0FBUWxDLE1BQU0sVUFBVTtBQUFBO0FBQUE7QUFBQTtBQUFB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