obsidian-integration-testing 16.0.0 → 17.0.1

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 (77) hide show
  1. package/dist/lib/cjs/adb.cjs +2 -2
  2. package/dist/lib/cjs/adb.d.cts +10 -0
  3. package/dist/lib/cjs/avd-name-channel.cjs +74 -0
  4. package/dist/lib/cjs/avd-name-channel.d.cts +152 -0
  5. package/dist/lib/cjs/avd-probe-verdict.cjs +11 -4
  6. package/dist/lib/cjs/avd-probe-verdict.d.cts +7 -0
  7. package/dist/lib/cjs/device-screenshot.cjs +1 -1
  8. package/dist/lib/cjs/device-screenshot.d.cts +3 -1
  9. package/dist/lib/cjs/emulator-backend.cjs +22 -1
  10. package/dist/lib/cjs/emulator-backend.d.cts +81 -0
  11. package/dist/lib/cjs/emulator-reclaim.cjs +78 -34
  12. package/dist/lib/cjs/emulator-reclaim.d.cts +57 -9
  13. package/dist/lib/cjs/enable-plugin.cjs +17 -8
  14. package/dist/lib/cjs/enable-plugin.d.cts +3 -1
  15. package/dist/lib/cjs/eval-in-obsidian.cjs +1 -1
  16. package/dist/lib/cjs/eval-in-obsidian.d.cts +12 -0
  17. package/dist/lib/cjs/host-process-query-verdict.cjs +103 -0
  18. package/dist/lib/cjs/host-process-query-verdict.d.cts +196 -0
  19. package/dist/lib/cjs/index.cjs +14 -1
  20. package/dist/lib/cjs/index.d.cts +3 -1
  21. package/dist/lib/cjs/launched-device-selection.cjs +46 -0
  22. package/dist/lib/cjs/launched-device-selection.d.cts +112 -0
  23. package/dist/lib/cjs/library.cjs +1 -1
  24. package/dist/lib/cjs/namespace-bootstrap.cjs +62 -1
  25. package/dist/lib/cjs/paint-out-status-bar.cjs +170 -0
  26. package/dist/lib/cjs/paint-out-status-bar.d.cts +236 -0
  27. package/dist/lib/cjs/port-owner-query-verdict.cjs +94 -0
  28. package/dist/lib/cjs/port-owner-query-verdict.d.cts +161 -0
  29. package/dist/lib/cjs/resolve-emulator-device-id.cjs +27 -4
  30. package/dist/lib/cjs/sharp-loader.cjs +1 -1
  31. package/dist/lib/cjs/sharp-loader.d.cts +67 -2
  32. package/dist/lib/cjs/soft-keyboard-geometry.cjs +12 -2
  33. package/dist/lib/cjs/soft-keyboard-geometry.d.cts +17 -2
  34. package/dist/lib/cjs/soft-keyboard.cjs +130 -28
  35. package/dist/lib/cjs/soft-keyboard.d.cts +65 -6
  36. package/dist/lib/cjs/transport-appium.cjs +74 -4
  37. package/dist/lib/cjs/transport-appium.d.cts +49 -2
  38. package/dist/lib/cjs/transport-factory.cjs +162 -42
  39. package/dist/lib/esm/adb.d.mts +10 -0
  40. package/dist/lib/esm/adb.mjs +2 -2
  41. package/dist/lib/esm/avd-name-channel.d.mts +152 -0
  42. package/dist/lib/esm/avd-name-channel.mjs +45 -0
  43. package/dist/lib/esm/avd-probe-verdict.d.mts +7 -0
  44. package/dist/lib/esm/avd-probe-verdict.mjs +15 -4
  45. package/dist/lib/esm/device-screenshot.d.mts +3 -1
  46. package/dist/lib/esm/device-screenshot.mjs +1 -1
  47. package/dist/lib/esm/emulator-backend.d.mts +81 -0
  48. package/dist/lib/esm/emulator-backend.mjs +19 -1
  49. package/dist/lib/esm/emulator-reclaim.d.mts +57 -9
  50. package/dist/lib/esm/emulator-reclaim.mjs +84 -36
  51. package/dist/lib/esm/enable-plugin.d.mts +3 -1
  52. package/dist/lib/esm/enable-plugin.mjs +17 -8
  53. package/dist/lib/esm/eval-in-obsidian.d.mts +12 -0
  54. package/dist/lib/esm/eval-in-obsidian.mjs +1 -1
  55. package/dist/lib/esm/host-process-query-verdict.d.mts +196 -0
  56. package/dist/lib/esm/host-process-query-verdict.mjs +74 -0
  57. package/dist/lib/esm/index.d.mts +3 -1
  58. package/dist/lib/esm/index.mjs +15 -1
  59. package/dist/lib/esm/launched-device-selection.d.mts +112 -0
  60. package/dist/lib/esm/launched-device-selection.mjs +21 -0
  61. package/dist/lib/esm/library.mjs +1 -1
  62. package/dist/lib/esm/namespace-bootstrap.mjs +62 -1
  63. package/dist/lib/esm/paint-out-status-bar.d.mts +236 -0
  64. package/dist/lib/esm/paint-out-status-bar.mjs +142 -0
  65. package/dist/lib/esm/port-owner-query-verdict.d.mts +161 -0
  66. package/dist/lib/esm/port-owner-query-verdict.mjs +73 -0
  67. package/dist/lib/esm/resolve-emulator-device-id.mjs +32 -4
  68. package/dist/lib/esm/sharp-loader.d.mts +67 -2
  69. package/dist/lib/esm/sharp-loader.mjs +1 -1
  70. package/dist/lib/esm/soft-keyboard-geometry.d.mts +17 -2
  71. package/dist/lib/esm/soft-keyboard-geometry.mjs +11 -2
  72. package/dist/lib/esm/soft-keyboard.d.mts +65 -6
  73. package/dist/lib/esm/soft-keyboard.mjs +131 -28
  74. package/dist/lib/esm/transport-appium.d.mts +49 -2
  75. package/dist/lib/esm/transport-appium.mjs +74 -4
  76. package/dist/lib/esm/transport-factory.mjs +176 -44
  77. package/package.json +1 -1
@@ -12,14 +12,14 @@
12
12
  * `OBSIDIAN_METADATA` global — which the factory's import graph reaches —
13
13
  * cannot load at all. So nothing this module imports may reach it either.
14
14
  */
15
- import type { ChildProcess } from 'node:child_process';
15
+ import type { ChildProcess, ExecFileException } from 'node:child_process';
16
16
  import type { ProcessListEntry } from './emulator-backend.mjs';
17
17
  /**
18
18
  * Budget for one quick `adb` call — `adb devices`, a console command.
19
19
  */
20
20
  export declare const ADB_DEVICE_CHECK_TIMEOUT_IN_MILLISECONDS = 5000;
21
21
  export declare const ADB_DUMPSYS_MAX_BUFFER_IN_BYTES = 8388608;
22
- export declare const HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS = 30000;
22
+ export declare const HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS = 120000;
23
23
  /**
24
24
  * Parameters for {@link EmulatorReclaimer.reclaimLeftoverEmulators}.
25
25
  */
@@ -74,6 +74,29 @@ export interface HostCommandQuery {
74
74
  */
75
75
  readonly commandArguments: string[];
76
76
  }
77
+ /**
78
+ * Everything one host process listing left behind, kept together so the
79
+ * classification sees the whole picture.
80
+ *
81
+ * `execFile`'s callback discards nothing here — not stderr, and not a *failed*
82
+ * call's partial stdout. The old code kept only `error.message`, which for
83
+ * `execFile` is `Command failed: <cmd>` plus stderr, so a killed child (empty
84
+ * stderr) produced a line naming the command and nothing else.
85
+ */
86
+ export interface HostProcessQueryResult {
87
+ /**
88
+ `execFile`'s error, or `null` when the listing succeeded.
89
+ */
90
+ readonly error: ExecFileException | null;
91
+ /**
92
+ Whatever the child wrote to stderr.
93
+ */
94
+ readonly standardError: string;
95
+ /**
96
+ Whatever the child wrote to stdout — a partial listing when the call failed part-way.
97
+ */
98
+ readonly standardOutput: string;
99
+ }
77
100
  /**
78
101
  * Finds, stops and verifies the harness's emulators, reporting through the
79
102
  * caller's log so each caller keeps its own prefix.
@@ -98,16 +121,34 @@ export declare class EmulatorReclaimer {
98
121
  */
99
122
  getDevicesOutput(): Promise<string>;
100
123
  /**
101
- * Lists every process on the host.
124
+ * Lists the host's emulator processes — every process whose image name could
125
+ * be the launcher or a QEMU backend, and on POSIX every process on the host.
126
+ *
127
+ * On Windows this is two **filtered** `tasklist` calls rather than one
128
+ * whole-host listing (`buildEmulatorProcessQueries` carries the measurement
129
+ * that made the switch), run in parallel. A filtered call may legitimately
130
+ * find nothing, but only when it says so: a clean exit with neither a row nor
131
+ * `tasklist`'s own no-match notice is still a failed query, and comes back as
132
+ * `undefined` exactly like one that did not run — never as an empty list a
133
+ * caller could read as "no emulator is running".
134
+ *
135
+ * Each failed call logs **one** line, from `host-process-query-verdict.ts`,
136
+ * naming which way it failed. The predecessor logged two contradictory ones
137
+ * for a single failure — `could not list host processes` immediately followed
138
+ * by `listed no processes` — because a failed call resolved `''`, which then
139
+ * parsed to zero rows and tripped the zero-row check as well.
102
140
  *
103
- * A host always has processes, so a listing that parses to **zero** rows is a
104
- * failed query however it exited, and comes back as `undefined` exactly like
105
- * one that did not run — never as an empty list a caller could read as "no
106
- * emulator is running".
141
+ * **If any call fails, the whole answer is `undefined`**, and a failed call's
142
+ * partial stdout is parsed but never returned: the owned PID set is the
143
+ * difference between two answers, so a half answer — one image name's
144
+ * processes without the other's, or a truncated listing — would both miss a
145
+ * process this run owns and claim one it does not, and killing a process the
146
+ * run does not own is the one thing **L46** forbids. The row count goes into
147
+ * the log instead, as the evidence that the command was working.
107
148
  *
108
- * @returns The host's processes, or `undefined` when the listing failed.
149
+ * @returns The host's emulator processes, or `undefined` when a query failed.
109
150
  */
110
- queryHostProcesses(): Promise<ProcessListEntry[] | undefined>;
151
+ queryEmulatorProcesses(): Promise<ProcessListEntry[] | undefined>;
111
152
  /**
112
153
  * Stops the emulators this harness started that no live run is responsible
113
154
  * for, and drops the markers that no longer describe a running emulator.
@@ -169,6 +210,13 @@ export declare class EmulatorReclaimer {
169
210
  * @param scope - Whether an emulator another live harness process owns is spared.
170
211
  */
171
212
  private reclaimLeftoverEmulator;
213
+ /**
214
+ * Runs one of the emulator process queries and classifies how it ended.
215
+ *
216
+ * @param query - The query.
217
+ * @returns Its parsed rows, or `undefined` when it failed.
218
+ */
219
+ private runEmulatorProcessQuery;
172
220
  /**
173
221
  * Polls until this run's emulator is gone, or the budget elapses.
174
222
  *
@@ -2,8 +2,9 @@ import { execFile } from "node:child_process";
2
2
  import process from "node:process";
3
3
  import { checkIsDeviceListed } from "./adb-device-list.mjs";
4
4
  import {
5
- parsePosixProcessList,
6
- parseWindowsTaskList,
5
+ buildEmulatorProcessQueries,
6
+ checkIsNoMatchReported,
7
+ parseEmulatorProcessQueryOutput,
7
8
  selectEmulatorBackendPids
8
9
  } from "./emulator-backend.mjs";
9
10
  import {
@@ -13,6 +14,10 @@ import {
13
14
  resolveEmulatorMarkerVerdict,
14
15
  selectLiveMarkedPids
15
16
  } from "./emulator-marker.mjs";
17
+ import {
18
+ buildHostProcessQueryMessage,
19
+ resolveHostProcessQueryOutcome
20
+ } from "./host-process-query-verdict.mjs";
16
21
  import {
17
22
  killProcessTree,
18
23
  killProcessTreeByPid
@@ -24,7 +29,7 @@ import {
24
29
  } from "./teardown-verdict.mjs";
25
30
  const ADB_DEVICE_CHECK_TIMEOUT_IN_MILLISECONDS = 5e3;
26
31
  const ADB_DUMPSYS_MAX_BUFFER_IN_BYTES = 8388608;
27
- const HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS = 3e4;
32
+ const HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS = 12e4;
28
33
  const EMULATOR_ESCALATED_STOP_TIMEOUT_IN_MILLISECONDS = 5e3;
29
34
  const EMULATOR_STOP_POLL_INTERVAL_IN_MILLISECONDS = 500;
30
35
  const EMULATOR_STOP_TIMEOUT_IN_MILLISECONDS = 2e4;
@@ -64,34 +69,41 @@ class EmulatorReclaimer {
64
69
  });
65
70
  }
66
71
  /**
67
- * Lists every process on the host.
72
+ * Lists the host's emulator processes — every process whose image name could
73
+ * be the launcher or a QEMU backend, and on POSIX every process on the host.
74
+ *
75
+ * On Windows this is two **filtered** `tasklist` calls rather than one
76
+ * whole-host listing (`buildEmulatorProcessQueries` carries the measurement
77
+ * that made the switch), run in parallel. A filtered call may legitimately
78
+ * find nothing, but only when it says so: a clean exit with neither a row nor
79
+ * `tasklist`'s own no-match notice is still a failed query, and comes back as
80
+ * `undefined` exactly like one that did not run — never as an empty list a
81
+ * caller could read as "no emulator is running".
68
82
  *
69
- * A host always has processes, so a listing that parses to **zero** rows is a
70
- * failed query however it exited, and comes back as `undefined` exactly like
71
- * one that did not run — never as an empty list a caller could read as "no
72
- * emulator is running".
83
+ * Each failed call logs **one** line, from `host-process-query-verdict.ts`,
84
+ * naming which way it failed. The predecessor logged two contradictory ones
85
+ * for a single failure — `could not list host processes` immediately followed
86
+ * by `listed no processes` — because a failed call resolved `''`, which then
87
+ * parsed to zero rows and tripped the zero-row check as well.
73
88
  *
74
- * @returns The host's processes, or `undefined` when the listing failed.
89
+ * **If any call fails, the whole answer is `undefined`**, and a failed call's
90
+ * partial stdout is parsed but never returned: the owned PID set is the
91
+ * difference between two answers, so a half answer — one image name's
92
+ * processes without the other's, or a truncated listing — would both miss a
93
+ * process this run owns and claim one it does not, and killing a process the
94
+ * run does not own is the one thing **L46** forbids. The row count goes into
95
+ * the log instead, as the evidence that the command was working.
96
+ *
97
+ * @returns The host's emulator processes, or `undefined` when a query failed.
75
98
  */
76
- async queryHostProcesses() {
77
- const query = buildHostProcessQuery();
78
- const output = await new Promise((resolve) => {
79
- execFile(
80
- query.command,
81
- query.commandArguments,
82
- { maxBuffer: ADB_DUMPSYS_MAX_BUFFER_IN_BYTES, timeout: HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS },
83
- (error, stdout) => {
84
- if (error) {
85
- this.log(`Warning: could not list host processes (\`${query.command}\`): ${error.message}`);
86
- }
87
- resolve(error ? "" : stdout);
88
- }
89
- );
90
- });
91
- const processes = parseHostProcessList(output);
92
- if (processes.length === 0) {
93
- this.log(`Warning: \`${query.command}\` listed no processes.`);
94
- return void 0;
99
+ async queryEmulatorProcesses() {
100
+ const answers = await Promise.all(buildEmulatorProcessQueries(process.platform).map((query) => this.runEmulatorProcessQuery(query)));
101
+ const processes = [];
102
+ for (const answer of answers) {
103
+ if (answer === void 0) {
104
+ return void 0;
105
+ }
106
+ processes.push(...answer);
95
107
  }
96
108
  return processes;
97
109
  }
@@ -114,7 +126,7 @@ class EmulatorReclaimer {
114
126
  if (markers.length === 0) {
115
127
  return;
116
128
  }
117
- const processes = await this.queryHostProcesses();
129
+ const processes = await this.queryEmulatorProcesses();
118
130
  if (processes === void 0) {
119
131
  this.log(`Cannot judge ${String(markers.length)} emulator marker(s) without a host process listing; leaving them for a later run.`);
120
132
  return;
@@ -254,6 +266,48 @@ class EmulatorReclaimer {
254
266
  ownedEmulatorPids: selectLiveMarkedPids(marker, liveEmulatorPids)
255
267
  });
256
268
  }
269
+ /**
270
+ * Runs one of the emulator process queries and classifies how it ended.
271
+ *
272
+ * @param query - The query.
273
+ * @returns Its parsed rows, or `undefined` when it failed.
274
+ */
275
+ async runEmulatorProcessQuery(query) {
276
+ const startedAtInMilliseconds = Date.now();
277
+ const result = await new Promise((resolve) => {
278
+ execFile(
279
+ query.command,
280
+ [...query.commandArguments],
281
+ { maxBuffer: ADB_DUMPSYS_MAX_BUFFER_IN_BYTES, timeout: HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS },
282
+ (error, stdout, stderr) => {
283
+ resolve({ error, standardError: stderr, standardOutput: stdout });
284
+ }
285
+ );
286
+ });
287
+ const processes = parseEmulatorProcessQueryOutput({ output: result.standardOutput, query });
288
+ const outcome = resolveHostProcessQueryOutcome({
289
+ errorCode: result.error?.code ?? null,
290
+ hasFailed: result.error !== null,
291
+ hasReportedNoMatch: checkIsNoMatchReported({ output: result.standardOutput, query }),
292
+ isKilled: result.error?.killed ?? false,
293
+ rowCount: processes.length,
294
+ standardError: result.standardError
295
+ });
296
+ const message = buildHostProcessQueryMessage({
297
+ command: [query.command, ...query.commandArguments].join(" "),
298
+ elapsedInMilliseconds: Date.now() - startedAtInMilliseconds,
299
+ exitCode: typeof result.error?.code === "number" ? result.error.code : null,
300
+ outcome,
301
+ partialRowCount: processes.length,
302
+ signal: result.error?.signal ?? null,
303
+ standardError: result.standardError,
304
+ timeoutInMilliseconds: HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS
305
+ });
306
+ if (message !== void 0) {
307
+ this.log(message);
308
+ }
309
+ return outcome === "listed" ? processes : void 0;
310
+ }
257
311
  /**
258
312
  * Polls until this run's emulator is gone, or the budget elapses.
259
313
  *
@@ -273,19 +327,13 @@ class EmulatorReclaimer {
273
327
  return false;
274
328
  }
275
329
  }
276
- function buildHostProcessQuery() {
277
- return process.platform === "win32" ? { command: "tasklist", commandArguments: ["/FO", "CSV", "/NH"] } : { command: "ps", commandArguments: ["-eo", "pid=,comm="] };
278
- }
279
330
  function describeMarkedEmulator(marker) {
280
331
  return marker.deviceId === void 0 ? `AVD "${marker.avdName}" (no device: it was still booting when it was recorded)` : `AVD "${marker.avdName}" on device ${marker.deviceId}`;
281
332
  }
282
- function parseHostProcessList(output) {
283
- return process.platform === "win32" ? parseWindowsTaskList(output) : parsePosixProcessList(output);
284
- }
285
333
  export {
286
334
  ADB_DEVICE_CHECK_TIMEOUT_IN_MILLISECONDS,
287
335
  ADB_DUMPSYS_MAX_BUFFER_IN_BYTES,
288
336
  EmulatorReclaimer,
289
337
  HOST_PROCESS_QUERY_TIMEOUT_IN_MILLISECONDS
290
338
  };
291
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2VtdWxhdG9yLXJlY2xhaW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBTdG9wcyB0aGUgZW11bGF0b3JzIHRoaXMgaGFybmVzcyBzdGFydGVkLCBhbmQgKip2ZXJpZmllcyoqIGVhY2ggc3RvcCBcdTIwMTQgdGhlXG4gKiBtYXJrZXItZHJpdmVuIGhhbGYgb2YgZW11bGF0b3Igb3duZXJzaGlwIChgZW11bGF0b3ItbWFya2VyLnRzYCwgKipMNTYqKikuXG4gKlxuICogSXQgbGl2ZXMgYXBhcnQgZnJvbSBgdHJhbnNwb3J0LWZhY3RvcnkudHNgIHNvIHRoYXQgYSBwcm9jZXNzIHdpdGggbm8gYnVzaW5lc3NcbiAqIGxvYWRpbmcgdGhlIHdob2xlIHRyYW5zcG9ydCBzdGFjayBjYW4gc3RpbGwgc3RvcCBhbiBlbXVsYXRvciBjb3JyZWN0bHkuIFRoYXRcbiAqIHByb2Nlc3MgaXMgdGhlIGVtdWxhdG9yIHJlYXBlciAoYGVtdWxhdG9yLXJlYXBlci50c2ApOiBpdCBydW5zIGRldGFjaGVkIGZyb21cbiAqIGFueSB0ZXN0IHJ1bm5lciwgYW5kIGluIHRoaXMgcmVwbydzIG93biBzdWl0ZXMgaXQgcnVucyBzdHJhaWdodCBmcm9tIHNvdXJjZVxuICogdW5kZXIgTm9kZSdzIHR5cGUgc3RyaXBwaW5nLCB3aGVyZSBhIG1vZHVsZSByZWFkaW5nIHRoZSBidWlsZC10aW1lXG4gKiBgT0JTSURJQU5fTUVUQURBVEFgIGdsb2JhbCBcdTIwMTQgd2hpY2ggdGhlIGZhY3RvcnkncyBpbXBvcnQgZ3JhcGggcmVhY2hlcyBcdTIwMTRcbiAqIGNhbm5vdCBsb2FkIGF0IGFsbC4gU28gbm90aGluZyB0aGlzIG1vZHVsZSBpbXBvcnRzIG1heSByZWFjaCBpdCBlaXRoZXIuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgZW11bGF0b3IgbWFuYWdlbWVudCBjb3ZlcmVkIGJ5IHRoZSBBbmRyb2lkIGludGVncmF0aW9uIHN1aXRlLCBub3QgdW5pdCB0ZXN0cy4gKi9cblxuaW1wb3J0IHR5cGUgeyBDaGlsZFByb2Nlc3MgfSBmcm9tICdub2RlOmNoaWxkX3Byb2Nlc3MnO1xuXG5pbXBvcnQgeyBleGVjRmlsZSB9IGZyb20gJ25vZGU6Y2hpbGRfcHJvY2Vzcyc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQgdHlwZSB7IFByb2Nlc3NMaXN0RW50cnkgfSBmcm9tICcuL2VtdWxhdG9yLWJhY2tlbmQubWpzJztcbmltcG9ydCB0eXBlIHsgRW11bGF0b3JNYXJrZXIgfSBmcm9tICcuL2VtdWxhdG9yLW1hcmtlci5tanMnO1xuXG5pbXBvcnQgeyBjaGVja0lzRGV2aWNlTGlzdGVkIH0gZnJvbSAnLi9hZGItZGV2aWNlLWxpc3QubWpzJztcbmltcG9ydCB7XG4gIHBhcnNlUG9zaXhQcm9jZXNzTGlzdCxcbiAgcGFyc2VXaW5kb3dzVGFza0xpc3QsXG4gIHNlbGVjdEVtdWxhdG9yQmFja2VuZFBpZHNcbn0gZnJvbSAnLi9lbXVsYXRvci1iYWNrZW5kLm1qcyc7XG5pbXBvcnQge1xuICBjbGVhckVtdWxhdG9yTWFya2VyLFxuICBjbGVhckVtdWxhdG9yTWFya2VySWZTdG9wcGVkLFxuICBsaXN0RW11bGF0b3JNYXJrZXJzLFxuICByZXNvbHZlRW11bGF0b3JNYXJrZXJWZXJkaWN0LFxuICBzZWxlY3RMaXZlTWFya2VkUGlkc1xufSBmcm9tICcuL2VtdWxhdG9yLW1hcmtlci5tanMnO1xuaW1wb3J0IHtcbiAga2lsbFByb2Nlc3NUcmVlLFxuICBraWxsUHJvY2Vzc1RyZWVCeVBpZFxufSBmcm9tICcuL2tpbGwtcHJvY2Vzcy10cmVlLm1qcyc7XG5pbXBvcnQgeyBjaGVja0lzUHJvY2Vzc0FsaXZlIH0gZnJvbSAnLi9wcm9jZXNzLWxpdmVuZXNzLm1qcyc7XG5pbXBvcnQge1xuICBidWlsZFRlYXJkb3duTWVzc2FnZSxcbiAgcmVzb2x2ZVRlYXJkb3duT3V0Y29tZVxufSBmcm9tICcuL3RlYXJkb3duLXZlcmRpY3QubWpzJztcblxuLyoqXG4gKiBCdWRnZXQgZm9yIG9uZSBxdWljayBgYWRiYCBjYWxsIFx1MjAxNCBgYWRiIGRldmljZXNgLCBhIGNvbnNvbGUgY29tbWFuZC5cbiAqL1xuZXhwb3J0IGNvbnN0IEFEQl9ERVZJQ0VfQ0hFQ0tfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSA1MDAwO1xuXG4vKlxuICogYGR1bXBzeXMgY29ubmVjdGl2aXR5YCBpcyBmYXIgbGFyZ2VyIHRoYW4gdGhlIG90aGVyIHByb2Jlcycgb3V0cHV0LCBhbmQgTm9kZSdzXG4gKiBkZWZhdWx0IDEgTWlCIGBtYXhCdWZmZXJgIHdvdWxkIGZhaWwgdGhlIGNhbGwgcmF0aGVyIHRoYW4gdHJ1bmNhdGUgaXQgXHUyMDE0IHdoaWNoXG4gKiB3b3VsZCByZWFkIGFzIFwibm90IHJlYWR5XCIgZm9yZXZlciBhbmQgYnVybiB0aGUgd2hvbGUgbmV0d29yayBidWRnZXQuIEEgaG9zdFxuICogcHJvY2VzcyBsaXN0aW5nIHNoYXJlcyB0aGUgc2FtZSBjZWlsaW5nLlxuICovXG5leHBvcnQgY29uc3QgQURCX0RVTVBTWVNfTUFYX0JVRkZFUl9JTl9CWVRFUyA9IDhfMzg4XzYwODtcblxuLypcbiAqIDMwcywgbm90IHRoZSAxMHMgYSBgdGFza2xpc3RgIGNvc3RzIG9uIGFuIGlkbGUgaG9zdDogdGhpcyBxdWVyeSBydW5zIGluIHRoZVxuICogc2FtZSBwb3N0LWJvb3QgY29udGVudGlvbiB3aW5kb3cgdGhhdCBpbmZsYXRlcyBldmVyeSBgYWRiYCByb3VuZC10cmlwIDI1LTUweFxuICogKEw0NSksIGFuZCB0aGUgZmlyc3QgZW5kLXRvLWVuZCBydW4gb3ZlcnJhbiBhIDEwcyBidWRnZXQgdGhlcmUgXHUyMDE0IHNpbGVudGx5XG4gKiBkaXNhcm1pbmcgdGhlIHRlYXJkb3duIGVzY2FsYXRpb24uIFNpemVkIGxpa2UgYEFEQl9EVU1QU1lTX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTYCxcbiAqIGZvciB0aGUgc2FtZSByZWFzb24uXG4gKi9cbmV4cG9ydCBjb25zdCBIT1NUX1BST0NFU1NfUVVFUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSAzMF8wMDA7XG5cbmNvbnN0IEVNVUxBVE9SX0VTQ0FMQVRFRF9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNTAwMDtcbmNvbnN0IEVNVUxBVE9SX1NUT1BfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSA1MDA7XG5jb25zdCBFTVVMQVRPUl9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMjBfMDAwO1xuY29uc3QgTUlMTElTRUNPTkRTX1BFUl9TRUNPTkQgPSAxMDAwO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBFbXVsYXRvclJlY2xhaW1lci5yZWNsYWltTGVmdG92ZXJFbXVsYXRvcnN9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVtdWxhdG9yUmVjbGFpbWVyUmVjbGFpbUxlZnRvdmVyRW11bGF0b3JzUGFyYW1zIHtcbiAgLyoqXG4gIEFuIEFWRCB3aG9zZSBsZWZ0b3ZlciBpcyBsZWZ0IGFsb25lIFx1MjAxNCB0aGUgb25lIGEgcHJlZmxpZ2h0IGlzIGFib3V0IHRvIGFkb3B0IGluc3RlYWQuXG4gICAqL1xuICByZWFkb25seSBleGNlcHRBdmROYW1lPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBgJ3ByZWZsaWdodCdgIHNwYXJlcyBhbiBlbXVsYXRvciBhbm90aGVyIGxpdmUgaGFybmVzcyBwcm9jZXNzIHN0aWxsIG93bnMuXG4gICAqIGAnZW5kLW9mLXJ1bidgIGRvZXMgbm90OiB0aGUgY2FsbGVyIGhvbGRzIHRoZSBgYW5kcm9pZGAgbG9jayB3aXRoIG5vIHJ1biBpblxuICAgKiBmbGlnaHQgXHUyMDE0IHRoZSBydW4ncyBvd24gZ2xvYmFsIHRlYXJkb3duLCBvciB0aGUgZW11bGF0b3IgcmVhcGVyIGFmdGVyIHRoZVxuICAgKiBydW4gaXMgZ29uZSBcdTIwMTQgc28gdGhhdCBvd25lciBjYW4gb25seSBiZSBvbmUgb2YgdGhlIGZpbmlzaGVkIHJ1bidzXG4gICAqIHByb2Nlc3Nlcywgd2hpY2ggbm8gbG9uZ2VyIGhhcyBhIHR1cm4gdG8gc3RvcCBpdC5cbiAgICovXG4gIHJlYWRvbmx5IHNjb3BlOiAnZW5kLW9mLXJ1bicgfCAncHJlZmxpZ2h0Jztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgRW11bGF0b3JSZWNsYWltZXIuc3RvcEVtdWxhdG9yfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbXVsYXRvclJlY2xhaW1lclN0b3BFbXVsYXRvclBhcmFtcyB7XG4gIC8qKlxuICBUaGUgQVZEIG5hbWUsIG5hbWVkIGluIHRoZSB3YXJuaW5nIHNvIHRoZSBsZWZ0b3ZlciBpcyBpZGVudGlmaWFibGUsIGFuZCB0aGUga2V5IG9mIGl0cyBtYXJrZXIuXG4gICAqL1xuICByZWFkb25seSBhdmROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBkZXZpY2UgdGhlIGVtdWxhdG9yIGlzIHNlcnZpbmcsIHNodXQgZG93biBvdmVyIGl0cyBjb25zb2xlIGFuZCBwb2xsZWRcbiAgICogdG8gZGVjaWRlIHdoZXRoZXIgaXQgYWN0dWFsbHkgc3RvcHBlZC4gYHVuZGVmaW5lZGAgd2hlbiB0aGUgZW11bGF0b3IgZmFpbGVkXG4gICAqIGJlZm9yZSBhbnkgZGV2aWNlIGFwcGVhcmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlSWQ/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFRoZSBlbXVsYXRvciBsYXVuY2hlciBwcm9jZXNzIHRoaXMgcnVuIHNwYXduZWQuIGB1bmRlZmluZWRgIGZvciBhIGxlZnRvdmVyXG4gICAqIHRoaXMgcnVuIHRvb2sgb3Zlciwgd2hvc2UgbGF1bmNoZXIgYmVsb25nZWQgdG8gYW5vdGhlciBwcm9jZXNzLlxuICAgKi9cbiAgcmVhZG9ubHkgZW11bGF0b3JQcm9jZXNzPzogQ2hpbGRQcm9jZXNzIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgZW11bGF0b3IgUElEcyB0aGlzIHJ1biBvd25zLCBlc2NhbGF0ZWQgdG8gd2hlbiB0aGUgY29uc29sZSBhbmQgdGhlIGxhdW5jaGVyJ3MgdHJlZSBraWxsIGxlYXZlIG9uZSBiZWhpbmQuXG4gICAqL1xuICByZWFkb25seSBvd25lZEVtdWxhdG9yUGlkczogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbi8qKlxuICogQSBob3N0IGNvbW1hbmQgYW5kIGl0cyBhcmd1bWVudHMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSG9zdENvbW1hbmRRdWVyeSB7XG4gIC8qKlxuICBUaGUgZXhlY3V0YWJsZSB0byBydW4uXG4gICAqL1xuICByZWFkb25seSBjb21tYW5kOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBjb21tYW5kJ3MgYXJndW1lbnRzLlxuICAgKi9cbiAgcmVhZG9ubHkgY29tbWFuZEFyZ3VtZW50czogc3RyaW5nW107XG59XG5cbmludGVyZmFjZSBFbXVsYXRvclJlY2xhaW1lckNoZWNrSXNFbXVsYXRvckdvbmVQYXJhbXMge1xuICAvKipcbiAgVGhlIGRldmljZSB0aGUgZW11bGF0b3Igc2VydmVzLCBvciBgdW5kZWZpbmVkYCB3aGVuIG5vbmUgZXZlciBhcHBlYXJlZCBcdTIwMTQgdGhlIFBJRHMgYXJlIHRoZW4gdGhlIG9ubHkgcHJvb2YuXG4gICAqL1xuICByZWFkb25seSBkZXZpY2VJZD86IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIGVtdWxhdG9yIFBJRHMgdGhpcyBydW4gb3ducy5cbiAgICovXG4gIHJlYWRvbmx5IG93bmVkRW11bGF0b3JQaWRzOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuaW50ZXJmYWNlIEVtdWxhdG9yUmVjbGFpbWVyV2FpdEZvckVtdWxhdG9yU3RvcHBlZFBhcmFtcyB7XG4gIC8qKlxuICBUaGUgZGV2aWNlIHRoZSBlbXVsYXRvciBzZXJ2ZXMsIG9yIGB1bmRlZmluZWRgIHdoZW4gbm9uZSBldmVyIGFwcGVhcmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlSWQ/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSBlbXVsYXRvciBQSURzIHRoaXMgcnVuIG93bnMuXG4gICAqL1xuICByZWFkb25seSBvd25lZEVtdWxhdG9yUGlkczogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgLyoqXG4gIEhvdyBsb25nIHRvIHdhaXQgZm9yIHRoZSBlbXVsYXRvciB0byBkaXNhcHBlYXIsIGluIG1pbGxpc2Vjb25kcy5cbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xufVxuXG4vKipcbiAqIEZpbmRzLCBzdG9wcyBhbmQgdmVyaWZpZXMgdGhlIGhhcm5lc3MncyBlbXVsYXRvcnMsIHJlcG9ydGluZyB0aHJvdWdoIHRoZVxuICogY2FsbGVyJ3MgbG9nIHNvIGVhY2ggY2FsbGVyIGtlZXBzIGl0cyBvd24gcHJlZml4LlxuICovXG5leHBvcnQgY2xhc3MgRW11bGF0b3JSZWNsYWltZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGxvZzogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZDtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHJlY2xhaW1lciB0aGF0IHJlcG9ydHMgdW5kZXIgdGhlIGNhbGxlcidzIG93biBsb2cgcHJlZml4LlxuICAgKlxuICAgKiBAcGFyYW0gbG9nIC0gUmVjZWl2ZXMgZXZlcnkgcHJvZ3Jlc3MgYW5kIHZlcmRpY3QgbGluZS5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihsb2c6IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQpIHtcbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGBhZGIgZGV2aWNlc2AgYW5kIHJldHVybnMgaXRzIHJhdyBzdGRvdXQuXG4gICAqXG4gICAqIFRoZSByYXcgbGlzdGluZyBpcyB3aGF0IHRlYXJkb3duIG5lZWRzOiBgZ2V0Q29ubmVjdGVkRGV2aWNlSWRzYCBrZWVwcyBvbmx5XG4gICAqIHRoZSBgZGV2aWNlYCBzdGF0ZSwgYW5kIGFuIGVtdWxhdG9yIG9uIGl0cyB3YXkgb3V0IGFuc3dlcnMgYG9mZmxpbmVgIHdoaWxlXG4gICAqIHN0aWxsIGhvbGRpbmcgdGhlIEFWRCBcdTIwMTQgc2VlIGBhZGItZGV2aWNlLWxpc3QudHNgLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgcmF3IGBhZGIgZGV2aWNlc2Agb3V0cHV0LlxuICAgKiBAdGhyb3dzIElmIGFkYiBjb3VsZCBub3QgYmUgcnVuIGF0IGFsbC5cbiAgICovXG4gIHB1YmxpYyBnZXREZXZpY2VzT3V0cHV0KCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHN0cmluZz4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZXhlY0ZpbGUoJ2FkYicsIFsnZGV2aWNlcyddLCB7IHRpbWVvdXQ6IEFEQl9ERVZJQ0VfQ0hFQ0tfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfSwgKGVycm9yLCBzdGRvdXQsIHN0ZGVycikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gcnVuICdhZGIgZGV2aWNlcyc6ICR7ZXJyb3IubWVzc2FnZX0uIElzIEFEQiBpbnN0YWxsZWQgYW5kIGluIFBBVEg/YCkpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RkZXJyKSB7XG4gICAgICAgICAgdGhpcy5sb2coYEFEQiBzdGRlcnI6ICR7c3RkZXJyLnRyaW0oKX1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXNvbHZlKHN0ZG91dCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0cyBldmVyeSBwcm9jZXNzIG9uIHRoZSBob3N0LlxuICAgKlxuICAgKiBBIGhvc3QgYWx3YXlzIGhhcyBwcm9jZXNzZXMsIHNvIGEgbGlzdGluZyB0aGF0IHBhcnNlcyB0byAqKnplcm8qKiByb3dzIGlzIGFcbiAgICogZmFpbGVkIHF1ZXJ5IGhvd2V2ZXIgaXQgZXhpdGVkLCBhbmQgY29tZXMgYmFjayBhcyBgdW5kZWZpbmVkYCBleGFjdGx5IGxpa2VcbiAgICogb25lIHRoYXQgZGlkIG5vdCBydW4gXHUyMDE0IG5ldmVyIGFzIGFuIGVtcHR5IGxpc3QgYSBjYWxsZXIgY291bGQgcmVhZCBhcyBcIm5vXG4gICAqIGVtdWxhdG9yIGlzIHJ1bm5pbmdcIi5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIGhvc3QncyBwcm9jZXNzZXMsIG9yIGB1bmRlZmluZWRgIHdoZW4gdGhlIGxpc3RpbmcgZmFpbGVkLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHF1ZXJ5SG9zdFByb2Nlc3NlcygpOiBQcm9taXNlPFByb2Nlc3NMaXN0RW50cnlbXSB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IHF1ZXJ5ID0gYnVpbGRIb3N0UHJvY2Vzc1F1ZXJ5KCk7XG4gICAgY29uc3Qgb3V0cHV0ID0gYXdhaXQgbmV3IFByb21pc2U8c3RyaW5nPigocmVzb2x2ZSkgPT4ge1xuICAgICAgZXhlY0ZpbGUoXG4gICAgICAgIHF1ZXJ5LmNvbW1hbmQsXG4gICAgICAgIHF1ZXJ5LmNvbW1hbmRBcmd1bWVudHMsXG4gICAgICAgIHsgbWF4QnVmZmVyOiBBREJfRFVNUFNZU19NQVhfQlVGRkVSX0lOX0JZVEVTLCB0aW1lb3V0OiBIT1NUX1BST0NFU1NfUVVFUllfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfSxcbiAgICAgICAgKGVycm9yLCBzdGRvdXQpID0+IHtcbiAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXMubG9nKGBXYXJuaW5nOiBjb3VsZCBub3QgbGlzdCBob3N0IHByb2Nlc3NlcyAoXFxgJHtxdWVyeS5jb21tYW5kfVxcYCk6ICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzb2x2ZShlcnJvciA/ICcnIDogc3Rkb3V0KTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHByb2Nlc3NlcyA9IHBhcnNlSG9zdFByb2Nlc3NMaXN0KG91dHB1dCk7XG4gICAgaWYgKHByb2Nlc3Nlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMubG9nKGBXYXJuaW5nOiBcXGAke3F1ZXJ5LmNvbW1hbmR9XFxgIGxpc3RlZCBubyBwcm9jZXNzZXMuYCk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiBwcm9jZXNzZXM7XG4gIH1cblxuICAvKipcbiAgICogU3RvcHMgdGhlIGVtdWxhdG9ycyB0aGlzIGhhcm5lc3Mgc3RhcnRlZCB0aGF0IG5vIGxpdmUgcnVuIGlzIHJlc3BvbnNpYmxlXG4gICAqIGZvciwgYW5kIGRyb3BzIHRoZSBtYXJrZXJzIHRoYXQgbm8gbG9uZ2VyIGRlc2NyaWJlIGEgcnVubmluZyBlbXVsYXRvci5cbiAgICpcbiAgICogT25seSBldmVyIGFjdHMgb24gYSAqKm1hcmtlci12ZXJpZmllZCoqIGVtdWxhdG9yOiBvbmUgd2hvc2UgbWFya2VyIG5hbWVzIGFcbiAgICogUElEIHRoYXQgaXMgc3RpbGwgYSBsaXZlIGVtdWxhdG9yIHByb2Nlc3MuIEFuIGVtdWxhdG9yIHdpdGhvdXQgYSBtYXJrZXIgXHUyMDE0XG4gICAqIGJvb3RlZCBieSBoYW5kLCBieSBDSSwgb3IgYnkgYW5vdGhlciB0b29sIFx1MjAxNCBpcyBuZXZlciB0b3VjaGVkLCB3aGljaCBrZWVwc1xuICAgKiB0aGUgTDQ2IGxpbmU6IG5ldmVyIGEgYHFlbXUqYCBzd2VlcC5cbiAgICpcbiAgICogQ2FsbGVycyBtdXN0IGhvbGQgdGhlIGBhbmRyb2lkYCBzZXR1cCBsb2NrIChMNyksIHdoaWNoIGlzIHdoYXQgbWFrZXMgYVxuICAgKiBsZWZ0b3ZlciBzYWZlIHRvIHN0b3A6IG5vIG90aGVyIEFuZHJvaWQgcnVuIGNhbiBiZSBtaWQtZmxpZ2h0IG9uIGl0LlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gV2hpY2ggQVZEIHRvIGxlYXZlIGFsb25lLCBhbmQgd2hldGhlciB0aGlzIHJ1biBpcyBlbmRpbmcuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVjbGFpbUxlZnRvdmVyRW11bGF0b3JzKHBhcmFtczogRW11bGF0b3JSZWNsYWltZXJSZWNsYWltTGVmdG92ZXJFbXVsYXRvcnNQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBtYXJrZXJzID0gbGlzdEVtdWxhdG9yTWFya2VycygpLmZpbHRlcigobWFya2VyKSA9PiBtYXJrZXIuYXZkTmFtZSAhPT0gcGFyYW1zLmV4Y2VwdEF2ZE5hbWUpO1xuICAgIGlmIChtYXJrZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHByb2Nlc3NlcyA9IGF3YWl0IHRoaXMucXVlcnlIb3N0UHJvY2Vzc2VzKCk7XG4gICAgaWYgKHByb2Nlc3NlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBXaXRob3V0IGEgbGlzdGluZyBldmVyeSBtYXJrZXIgd291bGQgcmVhZCBhcyBzdGFsZSwgYW5kIGRlbGV0aW5nIHRoZW0gd291bGQgbGVhdmUgdGhlIGxlZnRvdmVycyBpbXBvc3NpYmxlIHRvIGNvbnZpY3QuXG4gICAgICB0aGlzLmxvZyhgQ2Fubm90IGp1ZGdlICR7U3RyaW5nKG1hcmtlcnMubGVuZ3RoKX0gZW11bGF0b3IgbWFya2VyKHMpIHdpdGhvdXQgYSBob3N0IHByb2Nlc3MgbGlzdGluZzsgbGVhdmluZyB0aGVtIGZvciBhIGxhdGVyIHJ1bi5gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBsaXZlRW11bGF0b3JQaWRzID0gc2VsZWN0RW11bGF0b3JCYWNrZW5kUGlkcyh7IGtub3duUGlkczogW10sIHByb2Nlc3NlcyB9KTtcbiAgICBmb3IgKGNvbnN0IG1hcmtlciBvZiBtYXJrZXJzKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlY2xhaW1MZWZ0b3ZlckVtdWxhdG9yKG1hcmtlciwgbGl2ZUVtdWxhdG9yUGlkcywgcGFyYW1zLnNjb3BlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3RvcHMgYW4gZW11bGF0b3IgdGhpcyBoYXJuZXNzIG93bnMsIGFuZCAqKnZlcmlmaWVzKiogaXQgc3RvcHBlZC5cbiAgICpcbiAgICogVGhlIGNvbnNvbGUgc2h1dGRvd24gZ29lcyBmaXJzdCBiZWNhdXNlIGl0IGlzIHRoZSBvbmx5IHBhdGggdGhhdCByZWxlYXNlc1xuICAgKiB0aGUgQVZEJ3MgYG11bHRpaW5zdGFuY2UubG9ja2A7IGEgYHRhc2traWxsYCBsZWF2ZXMgdGhlIGxvY2sgYmVoaW5kLCBhbmQgYVxuICAgKiBzdGFsZSBsb2NrIGlzIHdoYXQgbWFrZXMgdGhlIG5leHQgcnVuIGZhaWwgd2l0aCBgUnVubmluZyBtdWx0aXBsZSBlbXVsYXRvcnNcbiAgICogd2l0aCB0aGUgc2FtZSBBVkRgIFx1MjAxNCBhIEZBVEFMIHRoZSBlbXVsYXRvciB3cml0ZXMgdG8gaXRzIG93biBzdGRvdXQsIHdoZXJlXG4gICAqIG5vYm9keSBzZWVzIGl0LlxuICAgKlxuICAgKiBXb3JrcyB3aXRob3V0IGEgbGF1bmNoZXIgaGFuZGxlIHRvbzogYSBsZWZ0b3ZlciB0aGlzIHJ1biB0b29rIG92ZXIgaGFzIG9ubHlcbiAgICogaXRzIFBJRHMsIHdoaWNoIGlzIGFsbCB0aGUgZXNjYWxhdGlvbiBiZWxvdyBldmVyIG5lZWRlZC4gVGhlIG1hcmtlciBnb2VzXG4gICAqIG9ubHkgd2l0aCBhICoqdmVyaWZpZWQqKiBzdG9wLCBzbyBhbiBlbXVsYXRvciB0aGF0IG91dGxpdmVkIHRoaXMgYXR0ZW1wdFxuICAgKiBzdGF5cyBjb252aWN0YWJsZSBieSB0aGUgbmV4dCBvbmUuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZW11bGF0b3IgcHJvY2VzcywgdGhlIGRldmljZSBpdCBzZXJ2ZXMgYW5kIHRoZSBQSURzIHRoaXMgcnVuIG93bnMuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc3RvcEVtdWxhdG9yKHBhcmFtczogRW11bGF0b3JSZWNsYWltZXJTdG9wRW11bGF0b3JQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAocGFyYW1zLmRldmljZUlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMua2lsbEVtdWxhdG9yQ29uc29sZShwYXJhbXMuZGV2aWNlSWQpO1xuICAgIH1cbiAgICBpZiAocGFyYW1zLmVtdWxhdG9yUHJvY2Vzcykge1xuICAgICAga2lsbFByb2Nlc3NUcmVlKHBhcmFtcy5lbXVsYXRvclByb2Nlc3MpO1xuICAgIH1cblxuICAgIGNvbnN0IHdhaXRQYXJhbXM6IEVtdWxhdG9yUmVjbGFpbWVyV2FpdEZvckVtdWxhdG9yU3RvcHBlZFBhcmFtcyA9IHtcbiAgICAgIGRldmljZUlkOiBwYXJhbXMuZGV2aWNlSWQsXG4gICAgICBvd25lZEVtdWxhdG9yUGlkczogcGFyYW1zLm93bmVkRW11bGF0b3JQaWRzLFxuICAgICAgdGltZW91dEluTWlsbGlzZWNvbmRzOiBFTVVMQVRPUl9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTXG4gICAgfTtcblxuICAgIGxldCBoYXNFc2NhbGF0ZWQgPSBmYWxzZTtcbiAgICBsZXQgaXNTdG9wcGVkID0gYXdhaXQgdGhpcy53YWl0Rm9yRW11bGF0b3JTdG9wcGVkKHdhaXRQYXJhbXMpO1xuXG4gICAgaWYgKCFpc1N0b3BwZWQpIHtcbiAgICAgIGNvbnN0IHN1cnZpdmluZ1BpZHMgPSBwYXJhbXMub3duZWRFbXVsYXRvclBpZHMuZmlsdGVyKChwaWQpID0+IGNoZWNrSXNQcm9jZXNzQWxpdmUocGlkKSk7XG4gICAgICBpZiAoc3Vydml2aW5nUGlkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGhhc0VzY2FsYXRlZCA9IHRydWU7XG4gICAgICAgIHRoaXMubG9nKFxuICAgICAgICAgIGBBdXRvLXN0YXJ0ZWQgZW11bGF0b3Igb3V0bGl2ZWQgaXRzIGNvbnNvbGUgc2h1dGRvd24gYW5kIHRoZSBsYXVuY2hlcidzIHByb2Nlc3MgdHJlZTsgZXNjYWxhdGluZyB0byB0aGUgZW11bGF0b3IgUElEKHMpIHRoaXMgcnVuIG93bnM6IFske3N1cnZpdmluZ1BpZHMuam9pbignLCAnKX1dLmBcbiAgICAgICAgKTtcbiAgICAgICAgZm9yIChjb25zdCBwaWQgb2Ygc3Vydml2aW5nUGlkcykge1xuICAgICAgICAgIGtpbGxQcm9jZXNzVHJlZUJ5UGlkKHBpZCk7XG4gICAgICAgIH1cbiAgICAgICAgaXNTdG9wcGVkID0gYXdhaXQgdGhpcy53YWl0Rm9yRW11bGF0b3JTdG9wcGVkKHsgLi4ud2FpdFBhcmFtcywgdGltZW91dEluTWlsbGlzZWNvbmRzOiBFTVVMQVRPUl9FU0NBTEFURURfU1RPUF9USU1FT1VUX0lOX01JTExJU0VDT05EUyB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmxvZyhidWlsZFRlYXJkb3duTWVzc2FnZSh7XG4gICAgICBldmlkZW5jZTogcGFyYW1zLmRldmljZUlkID09PSB1bmRlZmluZWQgPyBgQVZEIFwiJHtwYXJhbXMuYXZkTmFtZX1cImAgOiBgQVZEIFwiJHtwYXJhbXMuYXZkTmFtZX1cIiBvbiBkZXZpY2UgJHtwYXJhbXMuZGV2aWNlSWR9YCxcbiAgICAgIG91dGNvbWU6IHJlc29sdmVUZWFyZG93bk91dGNvbWUoeyBoYXNFc2NhbGF0ZWQsIGlzU3RvcHBlZCB9KSxcbiAgICAgIHN1YmplY3Q6ICdBdXRvLXN0YXJ0ZWQgZW11bGF0b3InLFxuICAgICAgdGltZW91dEluTWlsbGlzZWNvbmRzOiBFTVVMQVRPUl9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTXG4gICAgfSkpO1xuXG4gICAgaWYgKGlzU3RvcHBlZCkge1xuICAgICAgY2xlYXJFbXVsYXRvck1hcmtlcklmU3RvcHBlZChwYXJhbXMuYXZkTmFtZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlY2lkZXMgd2hldGhlciB0aGUgZW11bGF0b3IgdGhpcyBydW4gc3RhcnRlZCBpcyByZWFsbHkgZ29uZS5cbiAgICpcbiAgICogVHdvIGluZGVwZW5kZW50IHByb29mcywgY2hlYXBlc3QgZmlyc3Q6IG5vbmUgb2YgdGhlIFBJRHMgdGhpcyBydW4gb3ducyBpc1xuICAgKiBhbGl2ZSwgYW5kIHRoZSBkZXZpY2Ugbm8gbG9uZ2VyIGFwcGVhcnMgaW4gYGFkYiBkZXZpY2VzYCAqKmluIGFueSBzdGF0ZSoqIChhXG4gICAqIGR5aW5nIGVtdWxhdG9yIGFuc3dlcnMgYG9mZmxpbmVgIHdoaWxlIGl0IHN0aWxsIGhvbGRzIHRoZSBBVkQpLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGRldmljZSBhbmQgdGhlIFBJRHMgdGhpcyBydW4gb3ducy5cbiAgICogQHJldHVybnMgYHRydWVgIHdoZW4gbm90aGluZyBvZiB0aGlzIHJ1bidzIGVtdWxhdG9yIGlzIGxlZnQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNoZWNrSXNFbXVsYXRvckdvbmUocGFyYW1zOiBFbXVsYXRvclJlY2xhaW1lckNoZWNrSXNFbXVsYXRvckdvbmVQYXJhbXMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAocGFyYW1zLm93bmVkRW11bGF0b3JQaWRzLnNvbWUoKHBpZCkgPT4gY2hlY2tJc1Byb2Nlc3NBbGl2ZShwaWQpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuZGV2aWNlSWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiAhY2hlY2tJc0RldmljZUxpc3RlZCh7IGRldmljZUlkOiBwYXJhbXMuZGV2aWNlSWQsIGRldmljZXNPdXRwdXQ6IGF3YWl0IHRoaXMuZ2V0RGV2aWNlc091dHB1dCgpIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAvKlxuICAgICAgICogQW4gYWRiIHRoYXQgY2Fubm90IHJ1biBpcyBub3QgZXZpZGVuY2UgYWJvdXQgdGhlIGVtdWxhdG9yIFx1MjAxNCBhbmQgdGhlIFBJRFxuICAgICAgICogcHJvYmUgYWJvdmUgaGFzIGFscmVhZHkgc2FpZCB0aGlzIHJ1bidzIHByb2Nlc3NlcyBhcmUgZ29uZSwgd2hpY2ggaXMgdGhlXG4gICAgICAgKiBzdHJvbmdlciBvZiB0aGUgdHdvIHByb29mcy5cbiAgICAgICAqL1xuICAgICAgdGhpcy5sb2coYENvdWxkIG5vdCByZS1jaGVjayBjb25uZWN0ZWQgZGV2aWNlcyB3aGlsZSBzdG9wcGluZyB0aGUgZW11bGF0b3I6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFza3MgdGhlIGVtdWxhdG9yIHRvIHNodXQgaXRzZWxmIGRvd24gb3ZlciBpdHMgY29uc29sZS5cbiAgICpcbiAgICogUHJlZmVycmVkIG92ZXIga2lsbGluZyB0aGUgcHJvY2VzcyBvdXRyaWdodCBiZWNhdXNlIGl0IGlzIHRoZSBwYXRoIHRoYXRcbiAgICogcmVsZWFzZXMgdGhlIEFWRCdzIGBtdWx0aWluc3RhbmNlLmxvY2tgLiBCZXN0LWVmZm9ydDogYSBjb25zb2xlIHRoYXQgZG9lc1xuICAgKiBub3QgYW5zd2VyIGlzIHJlcG9ydGVkIGFuZCB0aGUgY2FsbGVyIGZhbGxzIHRocm91Z2ggdG8gdGhlIGtpbGwuXG4gICAqXG4gICAqIEBwYXJhbSBkZXZpY2VJZCAtIFRoZSBlbXVsYXRvcidzIGRldmljZSBJRC5cbiAgICovXG4gIHByaXZhdGUga2lsbEVtdWxhdG9yQ29uc29sZShkZXZpY2VJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICBleGVjRmlsZSgnYWRiJywgWyctcycsIGRldmljZUlkLCAnZW11JywgJ2tpbGwnXSwgeyB0aW1lb3V0OiBBREJfREVWSUNFX0NIRUNLX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH0sIChlcnJvciwgc3Rkb3V0KSA9PiB7XG4gICAgICAgIHRoaXMubG9nKFxuICAgICAgICAgIGVycm9yXG4gICAgICAgICAgICA/IGBFbXVsYXRvciBjb25zb2xlIHNodXRkb3duIGZvciAke2RldmljZUlkfSBkaWQgbm90IGFuc3dlcjogJHtlcnJvci5tZXNzYWdlfWBcbiAgICAgICAgICAgIDogYEVtdWxhdG9yIGNvbnNvbGUgc2h1dGRvd24gZm9yICR7ZGV2aWNlSWR9OiAke3N0ZG91dC50cmltKCl9YFxuICAgICAgICApO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBY3RzIG9uIG9uZSBlbXVsYXRvciBtYXJrZXIgZm9yIHtAbGluayByZWNsYWltTGVmdG92ZXJFbXVsYXRvcnN9LlxuICAgKlxuICAgKiBAcGFyYW0gbWFya2VyIC0gVGhlIG1hcmtlciB0byBqdWRnZS5cbiAgICogQHBhcmFtIGxpdmVFbXVsYXRvclBpZHMgLSBUaGUgZW11bGF0b3IgcHJvY2Vzc2VzIGN1cnJlbnRseSBydW5uaW5nIG9uIHRoZSBob3N0LlxuICAgKiBAcGFyYW0gc2NvcGUgLSBXaGV0aGVyIGFuIGVtdWxhdG9yIGFub3RoZXIgbGl2ZSBoYXJuZXNzIHByb2Nlc3Mgb3ducyBpcyBzcGFyZWQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlY2xhaW1MZWZ0b3ZlckVtdWxhdG9yKG1hcmtlcjogRW11bGF0b3JNYXJrZXIsIGxpdmVFbXVsYXRvclBpZHM6IHJlYWRvbmx5IG51bWJlcltdLCBzY29wZTogRW11bGF0b3JSZWNsYWltZXJSZWNsYWltTGVmdG92ZXJFbXVsYXRvcnNQYXJhbXNbJ3Njb3BlJ10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB2ZXJkaWN0ID0gcmVzb2x2ZUVtdWxhdG9yTWFya2VyVmVyZGljdCh7XG4gICAgICBjdXJyZW50UGlkOiBwcm9jZXNzLnBpZCxcbiAgICAgIGlzT3duZXJBbGl2ZTogY2hlY2tJc1Byb2Nlc3NBbGl2ZShtYXJrZXIub3duZXJQaWQpLFxuICAgICAgbGl2ZUVtdWxhdG9yUGlkcyxcbiAgICAgIG1hcmtlclxuICAgIH0pO1xuXG4gICAgaWYgKHZlcmRpY3QgPT09ICdzdGFsZS1tYXJrZXInKSB7XG4gICAgICB0aGlzLmxvZyhgRHJvcHBpbmcgdGhlIGVtdWxhdG9yIG1hcmtlciBmb3IgQVZEIFwiJHttYXJrZXIuYXZkTmFtZX1cIjogbm9uZSBvZiBpdHMgUElEcyBbJHttYXJrZXIub3duZWRFbXVsYXRvclBpZHMuam9pbignLCAnKX1dIGlzIGEgcnVubmluZyBlbXVsYXRvciBhbnkgbW9yZS5gKTtcbiAgICAgIGNsZWFyRW11bGF0b3JNYXJrZXIobWFya2VyLmF2ZE5hbWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8qXG4gICAgICogQSBtYXJrZXIgd3JpdHRlbiBhdCBsYXVuY2ggaGFzIG5vIGRldmljZSB5ZXQ6IHRoZSBlbXVsYXRvciB3YXMgc3RpbGxcbiAgICAgKiBib290aW5nIHdoZW4gd2hhdGV2ZXIgcmVjb3JkZWQgaXQgc3RvcHBlZCBsb29raW5nLiBUaGUgc3RvcCBiZWxvdyByZWFkc1xuICAgICAqIHRoYXQgYWJzZW5jZSBjb3JyZWN0bHkgXHUyMDE0IG5vIGNvbnNvbGUgdG8gc2h1dCBkb3duLCB0aGUgb3duZWQgUElEcyBhcmUgdGhlXG4gICAgICogd2hvbGUgb2YgdGhlIGV2aWRlbmNlIFx1MjAxNCBzbyBpdCBpcyBkZXNjcmliZWQgcmF0aGVyIHRoYW4gcGFwZXJlZCBvdmVyLlxuICAgICAqL1xuICAgIGNvbnN0IGV2aWRlbmNlID0gZGVzY3JpYmVNYXJrZWRFbXVsYXRvcihtYXJrZXIpO1xuXG4gICAgaWYgKHZlcmRpY3QgPT09ICdpbi11c2UtYnktbGl2ZS1ydW4nICYmIHNjb3BlID09PSAncHJlZmxpZ2h0Jykge1xuICAgICAgdGhpcy5sb2coYExlYXZpbmcgdGhlIGVtdWxhdG9yIGZvciAke2V2aWRlbmNlfSBhbG9uZTogdGhlIGhhcm5lc3MgcHJvY2VzcyB0aGF0IG93bnMgaXQgKFBJRCAke1N0cmluZyhtYXJrZXIub3duZXJQaWQpfSkgaXMgc3RpbGwgcnVubmluZy5gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBhZ2VJblNlY29uZHMgPSBNYXRoLnJvdW5kKChEYXRlLm5vdygpIC0gbWFya2VyLnN0YXJ0ZWRBdEluTWlsbGlzZWNvbmRzKSAvIE1JTExJU0VDT05EU19QRVJfU0VDT05EKTtcbiAgICB0aGlzLmxvZyhcbiAgICAgIGBTdG9wcGluZyB0aGUgZW11bGF0b3IgZm9yICR7ZXZpZGVuY2V9OiB0aGlzIGhhcm5lc3Mgc3RhcnRlZCBpdCAke1N0cmluZyhhZ2VJblNlY29uZHMpfXMgYWdvLCBhbmQgbm8gbGl2ZSBydW4gaXMgbGVmdCB0byBzdG9wIGl0LmBcbiAgICApO1xuICAgIGF3YWl0IHRoaXMuc3RvcEVtdWxhdG9yKHtcbiAgICAgIGF2ZE5hbWU6IG1hcmtlci5hdmROYW1lLFxuICAgICAgZGV2aWNlSWQ6IG1hcmtlci5kZXZpY2VJZCxcbiAgICAgIG93bmVkRW11bGF0b3JQaWRzOiBzZWxlY3RMaXZlTWFya2VkUGlkcyhtYXJrZXIsIGxpdmVFbXVsYXRvclBpZHMpXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUG9sbHMgdW50aWwgdGhpcyBydW4ncyBlbXVsYXRvciBpcyBnb25lLCBvciB0aGUgYnVkZ2V0IGVsYXBzZXMuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZGV2aWNlLCB0aGUgUElEcyB0aGlzIHJ1biBvd25zLCBhbmQgdGhlIGJ1ZGdldC5cbiAgICogQHJldHVybnMgYHRydWVgIHdoZW4gdGhlIGVtdWxhdG9yIGRpc2FwcGVhcmVkIHdpdGhpbiB0aGUgYnVkZ2V0LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yRW11bGF0b3JTdG9wcGVkKHBhcmFtczogRW11bGF0b3JSZWNsYWltZXJXYWl0Rm9yRW11bGF0b3JTdG9wcGVkUGFyYW1zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgcGFyYW1zLnRpbWVvdXRJbk1pbGxpc2Vjb25kcztcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGlmIChhd2FpdCB0aGlzLmNoZWNrSXNFbXVsYXRvckdvbmUocGFyYW1zKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgc2V0VGltZW91dChyZXNvbHZlLCBFTVVMQVRPUl9TVE9QX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIEJ1aWxkcyB0aGUgcGxhdGZvcm0ncyBcImxpc3QgZXZlcnkgcHJvY2Vzc1wiIHF1ZXJ5LlxuICpcbiAqIEByZXR1cm5zIFRoZSBjb21tYW5kIGFuZCBhcmd1bWVudHMgdG8gcnVuLlxuICovXG5mdW5jdGlvbiBidWlsZEhvc3RQcm9jZXNzUXVlcnkoKTogSG9zdENvbW1hbmRRdWVyeSB7XG4gIHJldHVybiBwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInXG4gICAgPyB7IGNvbW1hbmQ6ICd0YXNrbGlzdCcsIGNvbW1hbmRBcmd1bWVudHM6IFsnL0ZPJywgJ0NTVicsICcvTkgnXSB9XG4gICAgOiB7IGNvbW1hbmQ6ICdwcycsIGNvbW1hbmRBcmd1bWVudHM6IFsnLWVvJywgJ3BpZD0sY29tbT0nXSB9O1xufVxuXG4vKipcbiAqIE5hbWVzIHRoZSBlbXVsYXRvciBhIG1hcmtlciBkZXNjcmliZXMsIGZvciB0aGUgbG9nLlxuICpcbiAqIEBwYXJhbSBtYXJrZXIgLSBUaGUgbWFya2VyLlxuICogQHJldHVybnMgVGhlIEFWRCBhbmQgaXRzIGRldmljZSwgb3IgdGhlIEFWRCBhbG9uZSBmb3IgYSBsYXVuY2ggdGhhdCBoYWQgbm90IHByb2R1Y2VkIGEgZGV2aWNlIHlldC5cbiAqL1xuZnVuY3Rpb24gZGVzY3JpYmVNYXJrZWRFbXVsYXRvcihtYXJrZXI6IEVtdWxhdG9yTWFya2VyKTogc3RyaW5nIHtcbiAgcmV0dXJuIG1hcmtlci5kZXZpY2VJZCA9PT0gdW5kZWZpbmVkXG4gICAgPyBgQVZEIFwiJHttYXJrZXIuYXZkTmFtZX1cIiAobm8gZGV2aWNlOiBpdCB3YXMgc3RpbGwgYm9vdGluZyB3aGVuIGl0IHdhcyByZWNvcmRlZClgXG4gICAgOiBgQVZEIFwiJHttYXJrZXIuYXZkTmFtZX1cIiBvbiBkZXZpY2UgJHttYXJrZXIuZGV2aWNlSWR9YDtcbn1cblxuLyoqXG4gKiBQYXJzZXMgYSBob3N0IHByb2Nlc3MgbGlzdGluZyB3aXRoIHRoZSBwbGF0Zm9ybSdzIHBhcnNlci5cbiAqXG4gKiBAcGFyYW0gb3V0cHV0IC0gUmF3IHN0ZG91dCBvZiB7QGxpbmsgYnVpbGRIb3N0UHJvY2Vzc1F1ZXJ5fSdzIGNvbW1hbmQuXG4gKiBAcmV0dXJucyBUaGUgbGlzdGVkIHByb2Nlc3Nlcy5cbiAqL1xuZnVuY3Rpb24gcGFyc2VIb3N0UHJvY2Vzc0xpc3Qob3V0cHV0OiBzdHJpbmcpOiBQcm9jZXNzTGlzdEVudHJ5W10ge1xuICByZXR1cm4gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJyA/IHBhcnNlV2luZG93c1Rhc2tMaXN0KG91dHB1dCkgOiBwYXJzZVBvc2l4UHJvY2Vzc0xpc3Qob3V0cHV0KTtcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICJBQW1CQSxTQUFTLGdCQUFnQjtBQUN6QixPQUFPLGFBQWE7QUFLcEIsU0FBUywyQkFBMkI7QUFDcEM7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1A7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUDtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMsMkJBQTJC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MEJBQW9CLE9BQU8sT0FBTztBQUNsQztBQUFBLElBQ0Y7QUFRQSxVQUFNLFdBQVcsdUJBQXVCLE1BQU07QUFFOUMsUUFBSSxZQUFZLHdCQUF3QixVQUFVLGFBQWE7QUFDN0QsV0FBSyxJQUFJLDRCQUE0QixRQUFRLGlEQUFpRCxPQUFPLE9BQU8sUUFBUSxDQUFDLHFCQUFxQjtBQUMxSTtBQUFBLElBQ0Y7QUFFQSxVQUFNLGVBQWUsS0FBSyxPQUFPLEtBQUssSUFBSSxJQUFJLE9BQU8sMkJBQTJCLHVCQUF1QjtBQUN2RyxTQUFLO0FBQUEsTUFDSCw2QkFBNkIsUUFBUSw2QkFBNkIsT0FBTyxZQUFZLENBQUM7QUFBQSxJQUN4RjtBQUNBLFVBQU0sS0FBSyxhQUFhO0FBQUEsTUFDdEIsU0FBUyxPQUFPO0FBQUEsTUFDaEIsVUFBVSxPQUFPO0FBQUEsTUFDakIsbUJBQW1CLHFCQUFxQixRQUFRLGdCQUFnQjtBQUFBLElBQ2xFLENBQUM7QUFBQSxFQUNIO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFRQSxNQUFjLHVCQUF1QixRQUF5RTtBQUM1RyxVQUFNLFdBQVcsS0FBSyxJQUFJLElBQUksT0FBTztBQUVyQyxXQUFPLEtBQUssSUFBSSxJQUFJLFVBQVU7QUFDNUIsVUFBSSxNQUFNLEtBQUssb0JBQW9CLE1BQU0sR0FBRztBQUMxQyxlQUFPO0FBQUEsTUFDVDtBQUVBLFlBQU0sSUFBSSxRQUFRLENBQUMsWUFBWTtBQUM3QixtQkFBVyxTQUFTLDJDQUEyQztBQUFBLE1BQ2pFLENBQUM7QUFBQSxJQUNIO0FBRUEsV0FBTztBQUFBLEVBQ1Q7QUFDRjtBQU9BLFNBQVMsd0JBQTBDO0FBQ2pELFNBQU8sUUFBUSxhQUFhLFVBQ3hCLEVBQUUsU0FBUyxZQUFZLGtCQUFrQixDQUFDLE9BQU8sT0FBTyxLQUFLLEVBQUUsSUFDL0QsRUFBRSxTQUFTLE1BQU0sa0JBQWtCLENBQUMsT0FBTyxZQUFZLEVBQUU7QUFDL0Q7QUFRQSxTQUFTLHVCQUF1QixRQUFnQztBQUM5RCxTQUFPLE9BQU8sYUFBYSxTQUN2QixRQUFRLE9BQU8sT0FBTyw2REFDdEIsUUFBUSxPQUFPLE9BQU8sZUFBZSxPQUFPLFFBQVE7QUFDMUQ7QUFRQSxTQUFTLHFCQUFxQixRQUFvQztBQUNoRSxTQUFPLFFBQVEsYUFBYSxVQUFVLHFCQUFxQixNQUFNLElBQUksc0JBQXNCLE1BQU07QUFDbkc7IiwKICAibmFtZXMiOiBbXQp9Cg==
339
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2VtdWxhdG9yLXJlY2xhaW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBTdG9wcyB0aGUgZW11bGF0b3JzIHRoaXMgaGFybmVzcyBzdGFydGVkLCBhbmQgKip2ZXJpZmllcyoqIGVhY2ggc3RvcCBcdTIwMTQgdGhlXG4gKiBtYXJrZXItZHJpdmVuIGhhbGYgb2YgZW11bGF0b3Igb3duZXJzaGlwIChgZW11bGF0b3ItbWFya2VyLnRzYCwgKipMNTYqKikuXG4gKlxuICogSXQgbGl2ZXMgYXBhcnQgZnJvbSBgdHJhbnNwb3J0LWZhY3RvcnkudHNgIHNvIHRoYXQgYSBwcm9jZXNzIHdpdGggbm8gYnVzaW5lc3NcbiAqIGxvYWRpbmcgdGhlIHdob2xlIHRyYW5zcG9ydCBzdGFjayBjYW4gc3RpbGwgc3RvcCBhbiBlbXVsYXRvciBjb3JyZWN0bHkuIFRoYXRcbiAqIHByb2Nlc3MgaXMgdGhlIGVtdWxhdG9yIHJlYXBlciAoYGVtdWxhdG9yLXJlYXBlci50c2ApOiBpdCBydW5zIGRldGFjaGVkIGZyb21cbiAqIGFueSB0ZXN0IHJ1bm5lciwgYW5kIGluIHRoaXMgcmVwbydzIG93biBzdWl0ZXMgaXQgcnVucyBzdHJhaWdodCBmcm9tIHNvdXJjZVxuICogdW5kZXIgTm9kZSdzIHR5cGUgc3RyaXBwaW5nLCB3aGVyZSBhIG1vZHVsZSByZWFkaW5nIHRoZSBidWlsZC10aW1lXG4gKiBgT0JTSURJQU5fTUVUQURBVEFgIGdsb2JhbCBcdTIwMTQgd2hpY2ggdGhlIGZhY3RvcnkncyBpbXBvcnQgZ3JhcGggcmVhY2hlcyBcdTIwMTRcbiAqIGNhbm5vdCBsb2FkIGF0IGFsbC4gU28gbm90aGluZyB0aGlzIG1vZHVsZSBpbXBvcnRzIG1heSByZWFjaCBpdCBlaXRoZXIuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgZW11bGF0b3IgbWFuYWdlbWVudCBjb3ZlcmVkIGJ5IHRoZSBBbmRyb2lkIGludGVncmF0aW9uIHN1aXRlLCBub3QgdW5pdCB0ZXN0cy4gKi9cblxuaW1wb3J0IHR5cGUge1xuICBDaGlsZFByb2Nlc3MsXG4gIEV4ZWNGaWxlRXhjZXB0aW9uXG59IGZyb20gJ25vZGU6Y2hpbGRfcHJvY2Vzcyc7XG5cbmltcG9ydCB7IGV4ZWNGaWxlIH0gZnJvbSAnbm9kZTpjaGlsZF9wcm9jZXNzJztcbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5cbmltcG9ydCB0eXBlIHtcbiAgRW11bGF0b3JQcm9jZXNzUXVlcnksXG4gIFByb2Nlc3NMaXN0RW50cnlcbn0gZnJvbSAnLi9lbXVsYXRvci1iYWNrZW5kLm1qcyc7XG5pbXBvcnQgdHlwZSB7IEVtdWxhdG9yTWFya2VyIH0gZnJvbSAnLi9lbXVsYXRvci1tYXJrZXIubWpzJztcblxuaW1wb3J0IHsgY2hlY2tJc0RldmljZUxpc3RlZCB9IGZyb20gJy4vYWRiLWRldmljZS1saXN0Lm1qcyc7XG5pbXBvcnQge1xuICBidWlsZEVtdWxhdG9yUHJvY2Vzc1F1ZXJpZXMsXG4gIGNoZWNrSXNOb01hdGNoUmVwb3J0ZWQsXG4gIHBhcnNlRW11bGF0b3JQcm9jZXNzUXVlcnlPdXRwdXQsXG4gIHNlbGVjdEVtdWxhdG9yQmFja2VuZFBpZHNcbn0gZnJvbSAnLi9lbXVsYXRvci1iYWNrZW5kLm1qcyc7XG5pbXBvcnQge1xuICBjbGVhckVtdWxhdG9yTWFya2VyLFxuICBjbGVhckVtdWxhdG9yTWFya2VySWZTdG9wcGVkLFxuICBsaXN0RW11bGF0b3JNYXJrZXJzLFxuICByZXNvbHZlRW11bGF0b3JNYXJrZXJWZXJkaWN0LFxuICBzZWxlY3RMaXZlTWFya2VkUGlkc1xufSBmcm9tICcuL2VtdWxhdG9yLW1hcmtlci5tanMnO1xuaW1wb3J0IHtcbiAgYnVpbGRIb3N0UHJvY2Vzc1F1ZXJ5TWVzc2FnZSxcbiAgcmVzb2x2ZUhvc3RQcm9jZXNzUXVlcnlPdXRjb21lXG59IGZyb20gJy4vaG9zdC1wcm9jZXNzLXF1ZXJ5LXZlcmRpY3QubWpzJztcbmltcG9ydCB7XG4gIGtpbGxQcm9jZXNzVHJlZSxcbiAga2lsbFByb2Nlc3NUcmVlQnlQaWRcbn0gZnJvbSAnLi9raWxsLXByb2Nlc3MtdHJlZS5tanMnO1xuaW1wb3J0IHsgY2hlY2tJc1Byb2Nlc3NBbGl2ZSB9IGZyb20gJy4vcHJvY2Vzcy1saXZlbmVzcy5tanMnO1xuaW1wb3J0IHtcbiAgYnVpbGRUZWFyZG93bk1lc3NhZ2UsXG4gIHJlc29sdmVUZWFyZG93bk91dGNvbWVcbn0gZnJvbSAnLi90ZWFyZG93bi12ZXJkaWN0Lm1qcyc7XG5cbi8qKlxuICogQnVkZ2V0IGZvciBvbmUgcXVpY2sgYGFkYmAgY2FsbCBcdTIwMTQgYGFkYiBkZXZpY2VzYCwgYSBjb25zb2xlIGNvbW1hbmQuXG4gKi9cbmV4cG9ydCBjb25zdCBBREJfREVWSUNFX0NIRUNLX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNTAwMDtcblxuLypcbiAqIGBkdW1wc3lzIGNvbm5lY3Rpdml0eWAgaXMgZmFyIGxhcmdlciB0aGFuIHRoZSBvdGhlciBwcm9iZXMnIG91dHB1dCwgYW5kIE5vZGUnc1xuICogZGVmYXVsdCAxIE1pQiBgbWF4QnVmZmVyYCB3b3VsZCBmYWlsIHRoZSBjYWxsIHJhdGhlciB0aGFuIHRydW5jYXRlIGl0IFx1MjAxNCB3aGljaFxuICogd291bGQgcmVhZCBhcyBcIm5vdCByZWFkeVwiIGZvcmV2ZXIgYW5kIGJ1cm4gdGhlIHdob2xlIG5ldHdvcmsgYnVkZ2V0LiBBIGhvc3RcbiAqIHByb2Nlc3MgbGlzdGluZyBzaGFyZXMgdGhlIHNhbWUgY2VpbGluZy5cbiAqL1xuZXhwb3J0IGNvbnN0IEFEQl9EVU1QU1lTX01BWF9CVUZGRVJfSU5fQllURVMgPSA4XzM4OF82MDg7XG5cbi8qXG4gKiAxMjBzLCBub3QgdGhlIH4xcyBhIHdob2xlLWhvc3QgYHRhc2tsaXN0YCBjb3N0cyBvbiBhbiBpZGxlIGhvc3Q6IHRoaXMgcXVlcnlcbiAqIHJ1bnMgaW4gdGhlIHNhbWUgcG9zdC1ib290IGNvbnRlbnRpb24gd2luZG93IHRoYXQgaW5mbGF0ZXMgZXZlcnkgYGFkYmBcbiAqIHJvdW5kLXRyaXAgMjUtNTB4IChMNDUpLCBhbmQgYXMgYSB3aG9sZS1ob3N0IGxpc3RpbmcgaXQgd2FzIHRoZSBtb3N0XG4gKiBjb250ZW50aW9uLXNlbnNpdGl2ZSBjYWxsIHRoZSBoYXJuZXNzIG1hZGUgXHUyMDE0IGl0IHdhbGtlZCBldmVyeSBwcm9jZXNzIG9uIHRoZVxuICogaG9zdCwgc28gaXQgcGFpZCB0aGUgaG9zdCdzIHNsb3dkb3duIH41NDAgdGltZXMgb3Zlci5cbiAqXG4gKiBUaGUgdHdvIGVhcmxpZXIgbnVtYmVycyB3ZXJlIGJvdGggZ3Vlc3NlcywgYW5kIGJvdGggd2VyZSB0b28gc21hbGwuIDEwcyB3YXNcbiAqIG92ZXJydW4gb24gdGhlIGZpcnN0IGVuZC10by1lbmQgcnVuLiAzMHMgdGhlbiBmYWlsZWQgKipldmVyeSoqIEFuZHJvaWQgcnVuXG4gKiBmcm9tIG9uZSBob3N0IChtZWFzdXJlZCAyMDI2LTA5LTIwIGFjcm9zcyB0aHJlZSBydW5zIGFuZCB0d28gQVZEcyksIGVhY2ggdGltZVxuICoga2lsbGluZyB0aGUgY2hpbGQgYXQgfjMwcyB3aXRoIG5vdGhpbmcgb24gc3RkZXJyIFx1MjAxNCB0aGUgc2hhcGUgdGhhdCByZWFkcyBhcyBhblxuICogdW5leHBsYWluZWQgc3Bhd24gZmFpbHVyZSBhbmQgc2lsZW50bHkgZGlzYXJtcyB0aGUgZXNjYWxhdGlvbi5cbiAqXG4gKiBTbyB0aGlzIG9uZSBpcyBtZWFzdXJlZCBpbnN0ZWFkLiBUcmFjZWQgd2l0aCBubyBidWRnZXQgYXQgYWxsIGR1cmluZyBhblxuICogZW11bGF0b3IgYm9vdCBvbiB0aGF0IGhvc3QgKDIwMjYtMDktMjMsIG49NDApOiBwNTAgMi45cywgcDc1IDQuNHMsIHA5MCAxNy44cyxcbiAqIHA5NSAyOS4xcywgbWF4ICoqOTIuMnMqKi4gRXZlcnkgb25lIG9mIHRoZSA0MCBjb21wbGV0ZWQgdGhlIGZ1bGwgfjUzMC1yb3dcbiAqIGxpc3RpbmcgYW5kIGV4aXRlZCB3aXRoaW4gNTVtcyBvZiBpdHMgbGFzdCByb3csIHNvIG5vbmUgb2YgdGhlbSB3YXMgaHVuZyBcdTIwMTRcbiAqIHRoZSBjb3N0IGlzIHNwcmVhZCBhY3Jvc3MgdGhlIHJvd3MsIGluIDEuMC0yLjdzIHBhdXNlcyBvbiBpbmRpdmlkdWFsXG4gKiBwcm9jZXNzZXMuIDMwcyB0aGVyZWZvcmUgY3V0IG9mZiB0aGUgdG9wIDIuNSUgb2YgYSBkaXN0cmlidXRpb24gd2hvc2UgdGFpbFxuICogcmVhY2hlcyA5MnMsIGFuZCBhIHJlYWwgcnVuIFx1MjAxNCB3aGljaCBib290cyB0aGUgZW11bGF0b3IsIHN0YXJ0cyBBcHBpdW0sXG4gKiBpbnN0YWxscyB0aGUgYXBwIGFuZCBydW5zIFZpdGVzdCBhdCBvbmNlIFx1MjAxNCBpcyBtb3JlIGNvbnRlbmRlZCB0aGFuIHRoYXQgdHJhY2UuXG4gKlxuICogMTIwcyBpcyB+MS4zeCB0aGUgd29yc3Qgb2JzZXJ2ZWQgY2FsbCwgYW5kIGNvc3RzIG5vdGhpbmcgYXQgdGhlIG1lZGlhbi5cbiAqXG4gKiAqKlRoYXQgdGFpbCBiZWxvbmdlZCB0byB0aGUgd2hvbGUtaG9zdCBsaXN0aW5nLCB3aGljaCBXaW5kb3dzIG5vIGxvbmdlclxuICogbWFrZXMuKiogVGhlIHF1ZXJ5IGlzIG5vdyBmaWx0ZXJlZCB0byB0aGUgZW11bGF0b3IgaW1hZ2UgbmFtZXNcbiAqIChgYnVpbGRFbXVsYXRvclByb2Nlc3NRdWVyaWVzYCksIGFuZCB0aGUgZmlsdGVyZWQgY2FsbCBza2lwcyB0aGUgcGVyLXByb2Nlc3NcbiAqIHdvcmsgdGhlIHRhaWwgd2FzIG1hZGUgb2Y6IHdpdGggZXZlcnkgY29yZSBzYXR1cmF0ZWQgaXQgbmV2ZXIgZXhjZWVkZWQgNTA1bXNcbiAqIHdoZXJlIHRoZSB3aG9sZS1ob3N0IGNhbGwgc3RhbGxlZCBmb3IgMTIwLjlzLiBUaGUgYnVkZ2V0IHN0YXlzIGF0IDEyMHMgYXMgYVxuICogY2VpbGluZyByYXRoZXIgdGhhbiBhIGZvcmVjYXN0IFx1MjAxNCBpdCBjb3N0cyBub3RoaW5nIHdoZW4gdGhlIGNhbGwgaXMgZmFzdCwgYW5kXG4gKiBQT1NJWCBzdGlsbCBsaXN0cyB0aGUgd2hvbGUgaG9zdC4gSWYgYSBmaWx0ZXJlZCBjYWxsIGV2ZXIgb3ZlcnJ1bnMgaXQsIHRoZVxuICogbmV4dCBzdGVwIGlzIG5vdCBhIGZpZnRoIG51bWJlciBidXQgZGVyaXZpbmcgb3duZXJzaGlwIHdpdGhvdXQgYSBwcm9jZXNzXG4gKiBsaXN0aW5nIGF0IGFsbC5cbiAqL1xuZXhwb3J0IGNvbnN0IEhPU1RfUFJPQ0VTU19RVUVSWV9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDEyMF8wMDA7XG5cbmNvbnN0IEVNVUxBVE9SX0VTQ0FMQVRFRF9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNTAwMDtcbmNvbnN0IEVNVUxBVE9SX1NUT1BfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSA1MDA7XG5jb25zdCBFTVVMQVRPUl9TVE9QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMjBfMDAwO1xuY29uc3QgTUlMTElTRUNPTkRTX1BFUl9TRUNPTkQgPSAxMDAwO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBFbXVsYXRvclJlY2xhaW1lci5yZWNsYWltTGVmdG92ZXJFbXVsYXRvcnN9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVtdWxhdG9yUmVjbGFpbWVyUmVjbGFpbUxlZnRvdmVyRW11bGF0b3JzUGFyYW1zIHtcbiAgLyoqXG4gIEFuIEFWRCB3aG9zZSBsZWZ0b3ZlciBpcyBsZWZ0IGFsb25lIFx1MjAxNCB0aGUgb25lIGEgcHJlZmxpZ2h0IGlzIGFib3V0IHRvIGFkb3B0IGluc3RlYWQuXG4gICAqL1xuICByZWFkb25seSBleGNlcHRBdmROYW1lPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBgJ3ByZWZsaWdodCdgIHNwYXJlcyBhbiBlbXVsYXRvciBhbm90aGVyIGxpdmUgaGFybmVzcyBwcm9jZXNzIHN0aWxsIG93bnMuXG4gICAqIGAnZW5kLW9mLXJ1bidgIGRvZXMgbm90OiB0aGUgY2FsbGVyIGhvbGRzIHRoZSBgYW5kcm9pZGAgbG9jayB3aXRoIG5vIHJ1biBpblxuICAgKiBmbGlnaHQgXHUyMDE0IHRoZSBydW4ncyBvd24gZ2xvYmFsIHRlYXJkb3duLCBvciB0aGUgZW11bGF0b3IgcmVhcGVyIGFmdGVyIHRoZVxuICAgKiBydW4gaXMgZ29uZSBcdTIwMTQgc28gdGhhdCBvd25lciBjYW4gb25seSBiZSBvbmUgb2YgdGhlIGZpbmlzaGVkIHJ1bidzXG4gICAqIHByb2Nlc3Nlcywgd2hpY2ggbm8gbG9uZ2VyIGhhcyBhIHR1cm4gdG8gc3RvcCBpdC5cbiAgICovXG4gIHJlYWRvbmx5IHNjb3BlOiAnZW5kLW9mLXJ1bicgfCAncHJlZmxpZ2h0Jztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgRW11bGF0b3JSZWNsYWltZXIuc3RvcEVtdWxhdG9yfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbXVsYXRvclJlY2xhaW1lclN0b3BFbXVsYXRvclBhcmFtcyB7XG4gIC8qKlxuICBUaGUgQVZEIG5hbWUsIG5hbWVkIGluIHRoZSB3YXJuaW5nIHNvIHRoZSBsZWZ0b3ZlciBpcyBpZGVudGlmaWFibGUsIGFuZCB0aGUga2V5IG9mIGl0cyBtYXJrZXIuXG4gICAqL1xuICByZWFkb25seSBhdmROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBkZXZpY2UgdGhlIGVtdWxhdG9yIGlzIHNlcnZpbmcsIHNodXQgZG93biBvdmVyIGl0cyBjb25zb2xlIGFuZCBwb2xsZWRcbiAgICogdG8gZGVjaWRlIHdoZXRoZXIgaXQgYWN0dWFsbHkgc3RvcHBlZC4gYHVuZGVmaW5lZGAgd2hlbiB0aGUgZW11bGF0b3IgZmFpbGVkXG4gICAqIGJlZm9yZSBhbnkgZGV2aWNlIGFwcGVhcmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlSWQ/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFRoZSBlbXVsYXRvciBsYXVuY2hlciBwcm9jZXNzIHRoaXMgcnVuIHNwYXduZWQuIGB1bmRlZmluZWRgIGZvciBhIGxlZnRvdmVyXG4gICAqIHRoaXMgcnVuIHRvb2sgb3Zlciwgd2hvc2UgbGF1bmNoZXIgYmVsb25nZWQgdG8gYW5vdGhlciBwcm9jZXNzLlxuICAgKi9cbiAgcmVhZG9ubHkgZW11bGF0b3JQcm9jZXNzPzogQ2hpbGRQcm9jZXNzIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgZW11bGF0b3IgUElEcyB0aGlzIHJ1biBvd25zLCBlc2NhbGF0ZWQgdG8gd2hlbiB0aGUgY29uc29sZSBhbmQgdGhlIGxhdW5jaGVyJ3MgdHJlZSBraWxsIGxlYXZlIG9uZSBiZWhpbmQuXG4gICAqL1xuICByZWFkb25seSBvd25lZEVtdWxhdG9yUGlkczogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbi8qKlxuICogQSBob3N0IGNvbW1hbmQgYW5kIGl0cyBhcmd1bWVudHMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSG9zdENvbW1hbmRRdWVyeSB7XG4gIC8qKlxuICBUaGUgZXhlY3V0YWJsZSB0byBydW4uXG4gICAqL1xuICByZWFkb25seSBjb21tYW5kOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBjb21tYW5kJ3MgYXJndW1lbnRzLlxuICAgKi9cbiAgcmVhZG9ubHkgY29tbWFuZEFyZ3VtZW50czogc3RyaW5nW107XG59XG5cbi8qKlxuICogRXZlcnl0aGluZyBvbmUgaG9zdCBwcm9jZXNzIGxpc3RpbmcgbGVmdCBiZWhpbmQsIGtlcHQgdG9nZXRoZXIgc28gdGhlXG4gKiBjbGFzc2lmaWNhdGlvbiBzZWVzIHRoZSB3aG9sZSBwaWN0dXJlLlxuICpcbiAqIGBleGVjRmlsZWAncyBjYWxsYmFjayBkaXNjYXJkcyBub3RoaW5nIGhlcmUgXHUyMDE0IG5vdCBzdGRlcnIsIGFuZCBub3QgYSAqZmFpbGVkKlxuICogY2FsbCdzIHBhcnRpYWwgc3Rkb3V0LiBUaGUgb2xkIGNvZGUga2VwdCBvbmx5IGBlcnJvci5tZXNzYWdlYCwgd2hpY2ggZm9yXG4gKiBgZXhlY0ZpbGVgIGlzIGBDb21tYW5kIGZhaWxlZDogPGNtZD5gIHBsdXMgc3RkZXJyLCBzbyBhIGtpbGxlZCBjaGlsZCAoZW1wdHlcbiAqIHN0ZGVycikgcHJvZHVjZWQgYSBsaW5lIG5hbWluZyB0aGUgY29tbWFuZCBhbmQgbm90aGluZyBlbHNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEhvc3RQcm9jZXNzUXVlcnlSZXN1bHQge1xuICAvKipcbiAgYGV4ZWNGaWxlYCdzIGVycm9yLCBvciBgbnVsbGAgd2hlbiB0aGUgbGlzdGluZyBzdWNjZWVkZWQuXG4gICAqL1xuICByZWFkb25seSBlcnJvcjogRXhlY0ZpbGVFeGNlcHRpb24gfCBudWxsO1xuXG4gIC8qKlxuICBXaGF0ZXZlciB0aGUgY2hpbGQgd3JvdGUgdG8gc3RkZXJyLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhbmRhcmRFcnJvcjogc3RyaW5nO1xuXG4gIC8qKlxuICBXaGF0ZXZlciB0aGUgY2hpbGQgd3JvdGUgdG8gc3Rkb3V0IFx1MjAxNCBhIHBhcnRpYWwgbGlzdGluZyB3aGVuIHRoZSBjYWxsIGZhaWxlZCBwYXJ0LXdheS5cbiAgICovXG4gIHJlYWRvbmx5IHN0YW5kYXJkT3V0cHV0OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBFbXVsYXRvclJlY2xhaW1lckNoZWNrSXNFbXVsYXRvckdvbmVQYXJhbXMge1xuICAvKipcbiAgVGhlIGRldmljZSB0aGUgZW11bGF0b3Igc2VydmVzLCBvciBgdW5kZWZpbmVkYCB3aGVuIG5vbmUgZXZlciBhcHBlYXJlZCBcdTIwMTQgdGhlIFBJRHMgYXJlIHRoZW4gdGhlIG9ubHkgcHJvb2YuXG4gICAqL1xuICByZWFkb25seSBkZXZpY2VJZD86IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIGVtdWxhdG9yIFBJRHMgdGhpcyBydW4gb3ducy5cbiAgICovXG4gIHJlYWRvbmx5IG93bmVkRW11bGF0b3JQaWRzOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuaW50ZXJmYWNlIEVtdWxhdG9yUmVjbGFpbWVyV2FpdEZvckVtdWxhdG9yU3RvcHBlZFBhcmFtcyB7XG4gIC8qKlxuICBUaGUgZGV2aWNlIHRoZSBlbXVsYXRvciBzZXJ2ZXMsIG9yIGB1bmRlZmluZWRgIHdoZW4gbm9uZSBldmVyIGFwcGVhcmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlSWQ/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gIFRoZSBlbXVsYXRvciBQSURzIHRoaXMgcnVuIG93bnMuXG4gICAqL1xuICByZWFkb25seSBvd25lZEVtdWxhdG9yUGlkczogcmVhZG9ubHkgbnVtYmVyW107XG5cbiAgLyoqXG4gIEhvdyBsb25nIHRvIHdhaXQgZm9yIHRoZSBlbXVsYXRvciB0byBkaXNhcHBlYXIsIGluIG1pbGxpc2Vjb25kcy5cbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xufVxuXG4vKipcbiAqIEZpbmRzLCBzdG9wcyBhbmQgdmVyaWZpZXMgdGhlIGhhcm5lc3MncyBlbXVsYXRvcnMsIHJlcG9ydGluZyB0aHJvdWdoIHRoZVxuICogY2FsbGVyJ3MgbG9nIHNvIGVhY2ggY2FsbGVyIGtlZXBzIGl0cyBvd24gcHJlZml4LlxuICovXG5leHBvcnQgY2xhc3MgRW11bGF0b3JSZWNsYWltZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGxvZzogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZDtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHJlY2xhaW1lciB0aGF0IHJlcG9ydHMgdW5kZXIgdGhlIGNhbGxlcidzIG93biBsb2cgcHJlZml4LlxuICAgKlxuICAgKiBAcGFyYW0gbG9nIC0gUmVjZWl2ZXMgZXZlcnkgcHJvZ3Jlc3MgYW5kIHZlcmRpY3QgbGluZS5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihsb2c6IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQpIHtcbiAgICB0aGlzLmxvZyA9IGxvZztcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGBhZGIgZGV2aWNlc2AgYW5kIHJldHVybnMgaXRzIHJhdyBzdGRvdXQuXG4gICAqXG4gICAqIFRoZSByYXcgbGlzdGluZyBpcyB3aGF0IHRlYXJkb3duIG5lZWRzOiBgZ2V0Q29ubmVjdGVkRGV2aWNlSWRzYCBrZWVwcyBvbmx5XG4gICAqIHRoZSBgZGV2aWNlYCBzdGF0ZSwgYW5kIGFuIGVtdWxhdG9yIG9uIGl0cyB3YXkgb3V0IGFuc3dlcnMgYG9mZmxpbmVgIHdoaWxlXG4gICAqIHN0aWxsIGhvbGRpbmcgdGhlIEFWRCBcdTIwMTQgc2VlIGBhZGItZGV2aWNlLWxpc3QudHNgLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgcmF3IGBhZGIgZGV2aWNlc2Agb3V0cHV0LlxuICAgKiBAdGhyb3dzIElmIGFkYiBjb3VsZCBub3QgYmUgcnVuIGF0IGFsbC5cbiAgICovXG4gIHB1YmxpYyBnZXREZXZpY2VzT3V0cHV0KCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHN0cmluZz4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZXhlY0ZpbGUoJ2FkYicsIFsnZGV2aWNlcyddLCB7IHRpbWVvdXQ6IEFEQl9ERVZJQ0VfQ0hFQ0tfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfSwgKGVycm9yLCBzdGRvdXQsIHN0ZGVycikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBGYWlsZWQgdG8gcnVuICdhZGIgZGV2aWNlcyc6ICR7ZXJyb3IubWVzc2FnZX0uIElzIEFEQiBpbnN0YWxsZWQgYW5kIGluIFBBVEg/YCkpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RkZXJyKSB7XG4gICAgICAgICAgdGhpcy5sb2coYEFEQiBzdGRlcnI6ICR7c3RkZXJyLnRyaW0oKX1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXNvbHZlKHN0ZG91dCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0cyB0aGUgaG9zdCdzIGVtdWxhdG9yIHByb2Nlc3NlcyBcdTIwMTQgZXZlcnkgcHJvY2VzcyB3aG9zZSBpbWFnZSBuYW1lIGNvdWxkXG4gICAqIGJlIHRoZSBsYXVuY2hlciBvciBhIFFFTVUgYmFja2VuZCwgYW5kIG9uIFBPU0lYIGV2ZXJ5IHByb2Nlc3Mgb24gdGhlIGhvc3QuXG4gICAqXG4gICAqIE9uIFdpbmRvd3MgdGhpcyBpcyB0d28gKipmaWx0ZXJlZCoqIGB0YXNrbGlzdGAgY2FsbHMgcmF0aGVyIHRoYW4gb25lXG4gICAqIHdob2xlLWhvc3QgbGlzdGluZyAoYGJ1aWxkRW11bGF0b3JQcm9jZXNzUXVlcmllc2AgY2FycmllcyB0aGUgbWVhc3VyZW1lbnRcbiAgICogdGhhdCBtYWRlIHRoZSBzd2l0Y2gpLCBydW4gaW4gcGFyYWxsZWwuIEEgZmlsdGVyZWQgY2FsbCBtYXkgbGVnaXRpbWF0ZWx5XG4gICAqIGZpbmQgbm90aGluZywgYnV0IG9ubHkgd2hlbiBpdCBzYXlzIHNvOiBhIGNsZWFuIGV4aXQgd2l0aCBuZWl0aGVyIGEgcm93IG5vclxuICAgKiBgdGFza2xpc3RgJ3Mgb3duIG5vLW1hdGNoIG5vdGljZSBpcyBzdGlsbCBhIGZhaWxlZCBxdWVyeSwgYW5kIGNvbWVzIGJhY2sgYXNcbiAgICogYHVuZGVmaW5lZGAgZXhhY3RseSBsaWtlIG9uZSB0aGF0IGRpZCBub3QgcnVuIFx1MjAxNCBuZXZlciBhcyBhbiBlbXB0eSBsaXN0IGFcbiAgICogY2FsbGVyIGNvdWxkIHJlYWQgYXMgXCJubyBlbXVsYXRvciBpcyBydW5uaW5nXCIuXG4gICAqXG4gICAqIEVhY2ggZmFpbGVkIGNhbGwgbG9ncyAqKm9uZSoqIGxpbmUsIGZyb20gYGhvc3QtcHJvY2Vzcy1xdWVyeS12ZXJkaWN0LnRzYCxcbiAgICogbmFtaW5nIHdoaWNoIHdheSBpdCBmYWlsZWQuIFRoZSBwcmVkZWNlc3NvciBsb2dnZWQgdHdvIGNvbnRyYWRpY3Rvcnkgb25lc1xuICAgKiBmb3IgYSBzaW5nbGUgZmFpbHVyZSBcdTIwMTQgYGNvdWxkIG5vdCBsaXN0IGhvc3QgcHJvY2Vzc2VzYCBpbW1lZGlhdGVseSBmb2xsb3dlZFxuICAgKiBieSBgbGlzdGVkIG5vIHByb2Nlc3Nlc2AgXHUyMDE0IGJlY2F1c2UgYSBmYWlsZWQgY2FsbCByZXNvbHZlZCBgJydgLCB3aGljaCB0aGVuXG4gICAqIHBhcnNlZCB0byB6ZXJvIHJvd3MgYW5kIHRyaXBwZWQgdGhlIHplcm8tcm93IGNoZWNrIGFzIHdlbGwuXG4gICAqXG4gICAqICoqSWYgYW55IGNhbGwgZmFpbHMsIHRoZSB3aG9sZSBhbnN3ZXIgaXMgYHVuZGVmaW5lZGAqKiwgYW5kIGEgZmFpbGVkIGNhbGwnc1xuICAgKiBwYXJ0aWFsIHN0ZG91dCBpcyBwYXJzZWQgYnV0IG5ldmVyIHJldHVybmVkOiB0aGUgb3duZWQgUElEIHNldCBpcyB0aGVcbiAgICogZGlmZmVyZW5jZSBiZXR3ZWVuIHR3byBhbnN3ZXJzLCBzbyBhIGhhbGYgYW5zd2VyIFx1MjAxNCBvbmUgaW1hZ2UgbmFtZSdzXG4gICAqIHByb2Nlc3NlcyB3aXRob3V0IHRoZSBvdGhlcidzLCBvciBhIHRydW5jYXRlZCBsaXN0aW5nIFx1MjAxNCB3b3VsZCBib3RoIG1pc3MgYVxuICAgKiBwcm9jZXNzIHRoaXMgcnVuIG93bnMgYW5kIGNsYWltIG9uZSBpdCBkb2VzIG5vdCwgYW5kIGtpbGxpbmcgYSBwcm9jZXNzIHRoZVxuICAgKiBydW4gZG9lcyBub3Qgb3duIGlzIHRoZSBvbmUgdGhpbmcgKipMNDYqKiBmb3JiaWRzLiBUaGUgcm93IGNvdW50IGdvZXMgaW50b1xuICAgKiB0aGUgbG9nIGluc3RlYWQsIGFzIHRoZSBldmlkZW5jZSB0aGF0IHRoZSBjb21tYW5kIHdhcyB3b3JraW5nLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgaG9zdCdzIGVtdWxhdG9yIHByb2Nlc3Nlcywgb3IgYHVuZGVmaW5lZGAgd2hlbiBhIHF1ZXJ5IGZhaWxlZC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBxdWVyeUVtdWxhdG9yUHJvY2Vzc2VzKCk6IFByb21pc2U8UHJvY2Vzc0xpc3RFbnRyeVtdIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3QgYW5zd2VycyA9IGF3YWl0IFByb21pc2UuYWxsKGJ1aWxkRW11bGF0b3JQcm9jZXNzUXVlcmllcyhwcm9jZXNzLnBsYXRmb3JtKS5tYXAoKHF1ZXJ5KSA9PiB0aGlzLnJ1bkVtdWxhdG9yUHJvY2Vzc1F1ZXJ5KHF1ZXJ5KSkpO1xuICAgIGNvbnN0IHByb2Nlc3NlczogUHJvY2Vzc0xpc3RFbnRyeVtdID0gW107XG4gICAgZm9yIChjb25zdCBhbnN3ZXIgb2YgYW5zd2Vycykge1xuICAgICAgaWYgKGFuc3dlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBwcm9jZXNzZXMucHVzaCguLi5hbnN3ZXIpO1xuICAgIH1cblxuICAgIHJldHVybiBwcm9jZXNzZXM7XG4gIH1cblxuICAvKipcbiAgICogU3RvcHMgdGhlIGVtdWxhdG9ycyB0aGlzIGhhcm5lc3Mgc3RhcnRlZCB0aGF0IG5vIGxpdmUgcnVuIGlzIHJlc3BvbnNpYmxlXG4gICAqIGZvciwgYW5kIGRyb3BzIHRoZSBtYXJrZXJzIHRoYXQgbm8gbG9uZ2VyIGRlc2NyaWJlIGEgcnVubmluZyBlbXVsYXRvci5cbiAgICpcbiAgICogT25seSBldmVyIGFjdHMgb24gYSAqKm1hcmtlci12ZXJpZmllZCoqIGVtdWxhdG9yOiBvbmUgd2hvc2UgbWFya2VyIG5hbWVzIGFcbiAgICogUElEIHRoYXQgaXMgc3RpbGwgYSBsaXZlIGVtdWxhdG9yIHByb2Nlc3MuIEFuIGVtdWxhdG9yIHdpdGhvdXQgYSBtYXJrZXIgXHUyMDE0XG4gICAqIGJvb3RlZCBieSBoYW5kLCBieSBDSSwgb3IgYnkgYW5vdGhlciB0b29sIFx1MjAxNCBpcyBuZXZlciB0b3VjaGVkLCB3aGljaCBrZWVwc1xuICAgKiB0aGUgTDQ2IGxpbmU6IG5ldmVyIGEgYHFlbXUqYCBzd2VlcC5cbiAgICpcbiAgICogQ2FsbGVycyBtdXN0IGhvbGQgdGhlIGBhbmRyb2lkYCBzZXR1cCBsb2NrIChMNyksIHdoaWNoIGlzIHdoYXQgbWFrZXMgYVxuICAgKiBsZWZ0b3ZlciBzYWZlIHRvIHN0b3A6IG5vIG90aGVyIEFuZHJvaWQgcnVuIGNhbiBiZSBtaWQtZmxpZ2h0IG9uIGl0LlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gV2hpY2ggQVZEIHRvIGxlYXZlIGFsb25lLCBhbmQgd2hldGhlciB0aGlzIHJ1biBpcyBlbmRpbmcuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVjbGFpbUxlZnRvdmVyRW11bGF0b3JzKHBhcmFtczogRW11bGF0b3JSZWNsYWltZXJSZWNsYWltTGVmdG92ZXJFbXVsYXRvcnNQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBtYXJrZXJzID0gbGlzdEVtdWxhdG9yTWFya2VycygpLmZpbHRlcigobWFya2VyKSA9PiBtYXJrZXIuYXZkTmFtZSAhPT0gcGFyYW1zLmV4Y2VwdEF2ZE5hbWUpO1xuICAgIGlmIChtYXJrZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHByb2Nlc3NlcyA9IGF3YWl0IHRoaXMucXVlcnlFbXVsYXRvclByb2Nlc3NlcygpO1xuICAgIGlmIChwcm9jZXNzZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gV2l0aG91dCBhIGxpc3RpbmcgZXZlcnkgbWFya2VyIHdvdWxkIHJlYWQgYXMgc3RhbGUsIGFuZCBkZWxldGluZyB0aGVtIHdvdWxkIGxlYXZlIHRoZSBsZWZ0b3ZlcnMgaW1wb3NzaWJsZSB0byBjb252aWN0LlxuICAgICAgdGhpcy5sb2coYENhbm5vdCBqdWRnZSAke1N0cmluZyhtYXJrZXJzLmxlbmd0aCl9IGVtdWxhdG9yIG1hcmtlcihzKSB3aXRob3V0IGEgaG9zdCBwcm9jZXNzIGxpc3Rpbmc7IGxlYXZpbmcgdGhlbSBmb3IgYSBsYXRlciBydW4uYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbGl2ZUVtdWxhdG9yUGlkcyA9IHNlbGVjdEVtdWxhdG9yQmFja2VuZFBpZHMoeyBrbm93blBpZHM6IFtdLCBwcm9jZXNzZXMgfSk7XG4gICAgZm9yIChjb25zdCBtYXJrZXIgb2YgbWFya2Vycykge1xuICAgICAgYXdhaXQgdGhpcy5yZWNsYWltTGVmdG92ZXJFbXVsYXRvcihtYXJrZXIsIGxpdmVFbXVsYXRvclBpZHMsIHBhcmFtcy5zY29wZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN0b3BzIGFuIGVtdWxhdG9yIHRoaXMgaGFybmVzcyBvd25zLCBhbmQgKip2ZXJpZmllcyoqIGl0IHN0b3BwZWQuXG4gICAqXG4gICAqIFRoZSBjb25zb2xlIHNodXRkb3duIGdvZXMgZmlyc3QgYmVjYXVzZSBpdCBpcyB0aGUgb25seSBwYXRoIHRoYXQgcmVsZWFzZXNcbiAgICogdGhlIEFWRCdzIGBtdWx0aWluc3RhbmNlLmxvY2tgOyBhIGB0YXNra2lsbGAgbGVhdmVzIHRoZSBsb2NrIGJlaGluZCwgYW5kIGFcbiAgICogc3RhbGUgbG9jayBpcyB3aGF0IG1ha2VzIHRoZSBuZXh0IHJ1biBmYWlsIHdpdGggYFJ1bm5pbmcgbXVsdGlwbGUgZW11bGF0b3JzXG4gICAqIHdpdGggdGhlIHNhbWUgQVZEYCBcdTIwMTQgYSBGQVRBTCB0aGUgZW11bGF0b3Igd3JpdGVzIHRvIGl0cyBvd24gc3Rkb3V0LCB3aGVyZVxuICAgKiBub2JvZHkgc2VlcyBpdC5cbiAgICpcbiAgICogV29ya3Mgd2l0aG91dCBhIGxhdW5jaGVyIGhhbmRsZSB0b286IGEgbGVmdG92ZXIgdGhpcyBydW4gdG9vayBvdmVyIGhhcyBvbmx5XG4gICAqIGl0cyBQSURzLCB3aGljaCBpcyBhbGwgdGhlIGVzY2FsYXRpb24gYmVsb3cgZXZlciBuZWVkZWQuIFRoZSBtYXJrZXIgZ29lc1xuICAgKiBvbmx5IHdpdGggYSAqKnZlcmlmaWVkKiogc3RvcCwgc28gYW4gZW11bGF0b3IgdGhhdCBvdXRsaXZlZCB0aGlzIGF0dGVtcHRcbiAgICogc3RheXMgY29udmljdGFibGUgYnkgdGhlIG5leHQgb25lLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGVtdWxhdG9yIHByb2Nlc3MsIHRoZSBkZXZpY2UgaXQgc2VydmVzIGFuZCB0aGUgUElEcyB0aGlzIHJ1biBvd25zLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHN0b3BFbXVsYXRvcihwYXJhbXM6IEVtdWxhdG9yUmVjbGFpbWVyU3RvcEVtdWxhdG9yUGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHBhcmFtcy5kZXZpY2VJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhd2FpdCB0aGlzLmtpbGxFbXVsYXRvckNvbnNvbGUocGFyYW1zLmRldmljZUlkKTtcbiAgICB9XG4gICAgaWYgKHBhcmFtcy5lbXVsYXRvclByb2Nlc3MpIHtcbiAgICAgIGtpbGxQcm9jZXNzVHJlZShwYXJhbXMuZW11bGF0b3JQcm9jZXNzKTtcbiAgICB9XG5cbiAgICBjb25zdCB3YWl0UGFyYW1zOiBFbXVsYXRvclJlY2xhaW1lcldhaXRGb3JFbXVsYXRvclN0b3BwZWRQYXJhbXMgPSB7XG4gICAgICBkZXZpY2VJZDogcGFyYW1zLmRldmljZUlkLFxuICAgICAgb3duZWRFbXVsYXRvclBpZHM6IHBhcmFtcy5vd25lZEVtdWxhdG9yUGlkcyxcbiAgICAgIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogRU1VTEFUT1JfU1RPUF9USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICAgIH07XG5cbiAgICBsZXQgaGFzRXNjYWxhdGVkID0gZmFsc2U7XG4gICAgbGV0IGlzU3RvcHBlZCA9IGF3YWl0IHRoaXMud2FpdEZvckVtdWxhdG9yU3RvcHBlZCh3YWl0UGFyYW1zKTtcblxuICAgIGlmICghaXNTdG9wcGVkKSB7XG4gICAgICBjb25zdCBzdXJ2aXZpbmdQaWRzID0gcGFyYW1zLm93bmVkRW11bGF0b3JQaWRzLmZpbHRlcigocGlkKSA9PiBjaGVja0lzUHJvY2Vzc0FsaXZlKHBpZCkpO1xuICAgICAgaWYgKHN1cnZpdmluZ1BpZHMubGVuZ3RoID4gMCkge1xuICAgICAgICBoYXNFc2NhbGF0ZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLmxvZyhcbiAgICAgICAgICBgQXV0by1zdGFydGVkIGVtdWxhdG9yIG91dGxpdmVkIGl0cyBjb25zb2xlIHNodXRkb3duIGFuZCB0aGUgbGF1bmNoZXIncyBwcm9jZXNzIHRyZWU7IGVzY2FsYXRpbmcgdG8gdGhlIGVtdWxhdG9yIFBJRChzKSB0aGlzIHJ1biBvd25zOiBbJHtzdXJ2aXZpbmdQaWRzLmpvaW4oJywgJyl9XS5gXG4gICAgICAgICk7XG4gICAgICAgIGZvciAoY29uc3QgcGlkIG9mIHN1cnZpdmluZ1BpZHMpIHtcbiAgICAgICAgICBraWxsUHJvY2Vzc1RyZWVCeVBpZChwaWQpO1xuICAgICAgICB9XG4gICAgICAgIGlzU3RvcHBlZCA9IGF3YWl0IHRoaXMud2FpdEZvckVtdWxhdG9yU3RvcHBlZCh7IC4uLndhaXRQYXJhbXMsIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogRU1VTEFUT1JfRVNDQUxBVEVEX1NUT1BfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5sb2coYnVpbGRUZWFyZG93bk1lc3NhZ2Uoe1xuICAgICAgZXZpZGVuY2U6IHBhcmFtcy5kZXZpY2VJZCA9PT0gdW5kZWZpbmVkID8gYEFWRCBcIiR7cGFyYW1zLmF2ZE5hbWV9XCJgIDogYEFWRCBcIiR7cGFyYW1zLmF2ZE5hbWV9XCIgb24gZGV2aWNlICR7cGFyYW1zLmRldmljZUlkfWAsXG4gICAgICBvdXRjb21lOiByZXNvbHZlVGVhcmRvd25PdXRjb21lKHsgaGFzRXNjYWxhdGVkLCBpc1N0b3BwZWQgfSksXG4gICAgICBzdWJqZWN0OiAnQXV0by1zdGFydGVkIGVtdWxhdG9yJyxcbiAgICAgIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogRU1VTEFUT1JfU1RPUF9USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICAgIH0pKTtcblxuICAgIGlmIChpc1N0b3BwZWQpIHtcbiAgICAgIGNsZWFyRW11bGF0b3JNYXJrZXJJZlN0b3BwZWQocGFyYW1zLmF2ZE5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNpZGVzIHdoZXRoZXIgdGhlIGVtdWxhdG9yIHRoaXMgcnVuIHN0YXJ0ZWQgaXMgcmVhbGx5IGdvbmUuXG4gICAqXG4gICAqIFR3byBpbmRlcGVuZGVudCBwcm9vZnMsIGNoZWFwZXN0IGZpcnN0OiBub25lIG9mIHRoZSBQSURzIHRoaXMgcnVuIG93bnMgaXNcbiAgICogYWxpdmUsIGFuZCB0aGUgZGV2aWNlIG5vIGxvbmdlciBhcHBlYXJzIGluIGBhZGIgZGV2aWNlc2AgKippbiBhbnkgc3RhdGUqKiAoYVxuICAgKiBkeWluZyBlbXVsYXRvciBhbnN3ZXJzIGBvZmZsaW5lYCB3aGlsZSBpdCBzdGlsbCBob2xkcyB0aGUgQVZEKS5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBkZXZpY2UgYW5kIHRoZSBQSURzIHRoaXMgcnVuIG93bnMuXG4gICAqIEByZXR1cm5zIGB0cnVlYCB3aGVuIG5vdGhpbmcgb2YgdGhpcyBydW4ncyBlbXVsYXRvciBpcyBsZWZ0LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjaGVja0lzRW11bGF0b3JHb25lKHBhcmFtczogRW11bGF0b3JSZWNsYWltZXJDaGVja0lzRW11bGF0b3JHb25lUGFyYW1zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKHBhcmFtcy5vd25lZEVtdWxhdG9yUGlkcy5zb21lKChwaWQpID0+IGNoZWNrSXNQcm9jZXNzQWxpdmUocGlkKSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmRldmljZUlkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gIWNoZWNrSXNEZXZpY2VMaXN0ZWQoeyBkZXZpY2VJZDogcGFyYW1zLmRldmljZUlkLCBkZXZpY2VzT3V0cHV0OiBhd2FpdCB0aGlzLmdldERldmljZXNPdXRwdXQoKSB9KTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgLypcbiAgICAgICAqIEFuIGFkYiB0aGF0IGNhbm5vdCBydW4gaXMgbm90IGV2aWRlbmNlIGFib3V0IHRoZSBlbXVsYXRvciBcdTIwMTQgYW5kIHRoZSBQSURcbiAgICAgICAqIHByb2JlIGFib3ZlIGhhcyBhbHJlYWR5IHNhaWQgdGhpcyBydW4ncyBwcm9jZXNzZXMgYXJlIGdvbmUsIHdoaWNoIGlzIHRoZVxuICAgICAgICogc3Ryb25nZXIgb2YgdGhlIHR3byBwcm9vZnMuXG4gICAgICAgKi9cbiAgICAgIHRoaXMubG9nKGBDb3VsZCBub3QgcmUtY2hlY2sgY29ubmVjdGVkIGRldmljZXMgd2hpbGUgc3RvcHBpbmcgdGhlIGVtdWxhdG9yOiAke2Vycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBc2tzIHRoZSBlbXVsYXRvciB0byBzaHV0IGl0c2VsZiBkb3duIG92ZXIgaXRzIGNvbnNvbGUuXG4gICAqXG4gICAqIFByZWZlcnJlZCBvdmVyIGtpbGxpbmcgdGhlIHByb2Nlc3Mgb3V0cmlnaHQgYmVjYXVzZSBpdCBpcyB0aGUgcGF0aCB0aGF0XG4gICAqIHJlbGVhc2VzIHRoZSBBVkQncyBgbXVsdGlpbnN0YW5jZS5sb2NrYC4gQmVzdC1lZmZvcnQ6IGEgY29uc29sZSB0aGF0IGRvZXNcbiAgICogbm90IGFuc3dlciBpcyByZXBvcnRlZCBhbmQgdGhlIGNhbGxlciBmYWxscyB0aHJvdWdoIHRvIHRoZSBraWxsLlxuICAgKlxuICAgKiBAcGFyYW0gZGV2aWNlSWQgLSBUaGUgZW11bGF0b3IncyBkZXZpY2UgSUQuXG4gICAqL1xuICBwcml2YXRlIGtpbGxFbXVsYXRvckNvbnNvbGUoZGV2aWNlSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgZXhlY0ZpbGUoJ2FkYicsIFsnLXMnLCBkZXZpY2VJZCwgJ2VtdScsICdraWxsJ10sIHsgdGltZW91dDogQURCX0RFVklDRV9DSEVDS19USU1FT1VUX0lOX01JTExJU0VDT05EUyB9LCAoZXJyb3IsIHN0ZG91dCkgPT4ge1xuICAgICAgICB0aGlzLmxvZyhcbiAgICAgICAgICBlcnJvclxuICAgICAgICAgICAgPyBgRW11bGF0b3IgY29uc29sZSBzaHV0ZG93biBmb3IgJHtkZXZpY2VJZH0gZGlkIG5vdCBhbnN3ZXI6ICR7ZXJyb3IubWVzc2FnZX1gXG4gICAgICAgICAgICA6IGBFbXVsYXRvciBjb25zb2xlIHNodXRkb3duIGZvciAke2RldmljZUlkfTogJHtzdGRvdXQudHJpbSgpfWBcbiAgICAgICAgKTtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQWN0cyBvbiBvbmUgZW11bGF0b3IgbWFya2VyIGZvciB7QGxpbmsgcmVjbGFpbUxlZnRvdmVyRW11bGF0b3JzfS5cbiAgICpcbiAgICogQHBhcmFtIG1hcmtlciAtIFRoZSBtYXJrZXIgdG8ganVkZ2UuXG4gICAqIEBwYXJhbSBsaXZlRW11bGF0b3JQaWRzIC0gVGhlIGVtdWxhdG9yIHByb2Nlc3NlcyBjdXJyZW50bHkgcnVubmluZyBvbiB0aGUgaG9zdC5cbiAgICogQHBhcmFtIHNjb3BlIC0gV2hldGhlciBhbiBlbXVsYXRvciBhbm90aGVyIGxpdmUgaGFybmVzcyBwcm9jZXNzIG93bnMgaXMgc3BhcmVkLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWNsYWltTGVmdG92ZXJFbXVsYXRvcihtYXJrZXI6IEVtdWxhdG9yTWFya2VyLCBsaXZlRW11bGF0b3JQaWRzOiByZWFkb25seSBudW1iZXJbXSwgc2NvcGU6IEVtdWxhdG9yUmVjbGFpbWVyUmVjbGFpbUxlZnRvdmVyRW11bGF0b3JzUGFyYW1zWydzY29wZSddKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdmVyZGljdCA9IHJlc29sdmVFbXVsYXRvck1hcmtlclZlcmRpY3Qoe1xuICAgICAgY3VycmVudFBpZDogcHJvY2Vzcy5waWQsXG4gICAgICBpc093bmVyQWxpdmU6IGNoZWNrSXNQcm9jZXNzQWxpdmUobWFya2VyLm93bmVyUGlkKSxcbiAgICAgIGxpdmVFbXVsYXRvclBpZHMsXG4gICAgICBtYXJrZXJcbiAgICB9KTtcblxuICAgIGlmICh2ZXJkaWN0ID09PSAnc3RhbGUtbWFya2VyJykge1xuICAgICAgdGhpcy5sb2coYERyb3BwaW5nIHRoZSBlbXVsYXRvciBtYXJrZXIgZm9yIEFWRCBcIiR7bWFya2VyLmF2ZE5hbWV9XCI6IG5vbmUgb2YgaXRzIFBJRHMgWyR7bWFya2VyLm93bmVkRW11bGF0b3JQaWRzLmpvaW4oJywgJyl9XSBpcyBhIHJ1bm5pbmcgZW11bGF0b3IgYW55IG1vcmUuYCk7XG4gICAgICBjbGVhckVtdWxhdG9yTWFya2VyKG1hcmtlci5hdmROYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvKlxuICAgICAqIEEgbWFya2VyIHdyaXR0ZW4gYXQgbGF1bmNoIGhhcyBubyBkZXZpY2UgeWV0OiB0aGUgZW11bGF0b3Igd2FzIHN0aWxsXG4gICAgICogYm9vdGluZyB3aGVuIHdoYXRldmVyIHJlY29yZGVkIGl0IHN0b3BwZWQgbG9va2luZy4gVGhlIHN0b3AgYmVsb3cgcmVhZHNcbiAgICAgKiB0aGF0IGFic2VuY2UgY29ycmVjdGx5IFx1MjAxNCBubyBjb25zb2xlIHRvIHNodXQgZG93biwgdGhlIG93bmVkIFBJRHMgYXJlIHRoZVxuICAgICAqIHdob2xlIG9mIHRoZSBldmlkZW5jZSBcdTIwMTQgc28gaXQgaXMgZGVzY3JpYmVkIHJhdGhlciB0aGFuIHBhcGVyZWQgb3Zlci5cbiAgICAgKi9cbiAgICBjb25zdCBldmlkZW5jZSA9IGRlc2NyaWJlTWFya2VkRW11bGF0b3IobWFya2VyKTtcblxuICAgIGlmICh2ZXJkaWN0ID09PSAnaW4tdXNlLWJ5LWxpdmUtcnVuJyAmJiBzY29wZSA9PT0gJ3ByZWZsaWdodCcpIHtcbiAgICAgIHRoaXMubG9nKGBMZWF2aW5nIHRoZSBlbXVsYXRvciBmb3IgJHtldmlkZW5jZX0gYWxvbmU6IHRoZSBoYXJuZXNzIHByb2Nlc3MgdGhhdCBvd25zIGl0IChQSUQgJHtTdHJpbmcobWFya2VyLm93bmVyUGlkKX0pIGlzIHN0aWxsIHJ1bm5pbmcuYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYWdlSW5TZWNvbmRzID0gTWF0aC5yb3VuZCgoRGF0ZS5ub3coKSAtIG1hcmtlci5zdGFydGVkQXRJbk1pbGxpc2Vjb25kcykgLyBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORCk7XG4gICAgdGhpcy5sb2coXG4gICAgICBgU3RvcHBpbmcgdGhlIGVtdWxhdG9yIGZvciAke2V2aWRlbmNlfTogdGhpcyBoYXJuZXNzIHN0YXJ0ZWQgaXQgJHtTdHJpbmcoYWdlSW5TZWNvbmRzKX1zIGFnbywgYW5kIG5vIGxpdmUgcnVuIGlzIGxlZnQgdG8gc3RvcCBpdC5gXG4gICAgKTtcbiAgICBhd2FpdCB0aGlzLnN0b3BFbXVsYXRvcih7XG4gICAgICBhdmROYW1lOiBtYXJrZXIuYXZkTmFtZSxcbiAgICAgIGRldmljZUlkOiBtYXJrZXIuZGV2aWNlSWQsXG4gICAgICBvd25lZEVtdWxhdG9yUGlkczogc2VsZWN0TGl2ZU1hcmtlZFBpZHMobWFya2VyLCBsaXZlRW11bGF0b3JQaWRzKVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgb25lIG9mIHRoZSBlbXVsYXRvciBwcm9jZXNzIHF1ZXJpZXMgYW5kIGNsYXNzaWZpZXMgaG93IGl0IGVuZGVkLlxuICAgKlxuICAgKiBAcGFyYW0gcXVlcnkgLSBUaGUgcXVlcnkuXG4gICAqIEByZXR1cm5zIEl0cyBwYXJzZWQgcm93cywgb3IgYHVuZGVmaW5lZGAgd2hlbiBpdCBmYWlsZWQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJ1bkVtdWxhdG9yUHJvY2Vzc1F1ZXJ5KHF1ZXJ5OiBFbXVsYXRvclByb2Nlc3NRdWVyeSk6IFByb21pc2U8UHJvY2Vzc0xpc3RFbnRyeVtdIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3Qgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG5ldyBQcm9taXNlPEhvc3RQcm9jZXNzUXVlcnlSZXN1bHQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICBleGVjRmlsZShcbiAgICAgICAgcXVlcnkuY29tbWFuZCxcbiAgICAgICAgWy4uLnF1ZXJ5LmNvbW1hbmRBcmd1bWVudHNdLFxuICAgICAgICB7IG1heEJ1ZmZlcjogQURCX0RVTVBTWVNfTUFYX0JVRkZFUl9JTl9CWVRFUywgdGltZW91dDogSE9TVF9QUk9DRVNTX1FVRVJZX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH0sXG4gICAgICAgIChlcnJvciwgc3Rkb3V0LCBzdGRlcnIpID0+IHtcbiAgICAgICAgICByZXNvbHZlKHsgZXJyb3IsIHN0YW5kYXJkRXJyb3I6IHN0ZGVyciwgc3RhbmRhcmRPdXRwdXQ6IHN0ZG91dCB9KTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHByb2Nlc3NlcyA9IHBhcnNlRW11bGF0b3JQcm9jZXNzUXVlcnlPdXRwdXQoeyBvdXRwdXQ6IHJlc3VsdC5zdGFuZGFyZE91dHB1dCwgcXVlcnkgfSk7XG4gICAgY29uc3Qgb3V0Y29tZSA9IHJlc29sdmVIb3N0UHJvY2Vzc1F1ZXJ5T3V0Y29tZSh7XG4gICAgICBlcnJvckNvZGU6IHJlc3VsdC5lcnJvcj8uY29kZSA/PyBudWxsLFxuICAgICAgaGFzRmFpbGVkOiByZXN1bHQuZXJyb3IgIT09IG51bGwsXG4gICAgICBoYXNSZXBvcnRlZE5vTWF0Y2g6IGNoZWNrSXNOb01hdGNoUmVwb3J0ZWQoeyBvdXRwdXQ6IHJlc3VsdC5zdGFuZGFyZE91dHB1dCwgcXVlcnkgfSksXG4gICAgICBpc0tpbGxlZDogcmVzdWx0LmVycm9yPy5raWxsZWQgPz8gZmFsc2UsXG4gICAgICByb3dDb3VudDogcHJvY2Vzc2VzLmxlbmd0aCxcbiAgICAgIHN0YW5kYXJkRXJyb3I6IHJlc3VsdC5zdGFuZGFyZEVycm9yXG4gICAgfSk7XG5cbiAgICBjb25zdCBtZXNzYWdlID0gYnVpbGRIb3N0UHJvY2Vzc1F1ZXJ5TWVzc2FnZSh7XG4gICAgICBjb21tYW5kOiBbcXVlcnkuY29tbWFuZCwgLi4ucXVlcnkuY29tbWFuZEFyZ3VtZW50c10uam9pbignICcpLFxuICAgICAgZWxhcHNlZEluTWlsbGlzZWNvbmRzOiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMsXG4gICAgICBleGl0Q29kZTogdHlwZW9mIHJlc3VsdC5lcnJvcj8uY29kZSA9PT0gJ251bWJlcicgPyByZXN1bHQuZXJyb3IuY29kZSA6IG51bGwsXG4gICAgICBvdXRjb21lLFxuICAgICAgcGFydGlhbFJvd0NvdW50OiBwcm9jZXNzZXMubGVuZ3RoLFxuICAgICAgc2lnbmFsOiByZXN1bHQuZXJyb3I/LnNpZ25hbCA/PyBudWxsLFxuICAgICAgc3RhbmRhcmRFcnJvcjogcmVzdWx0LnN0YW5kYXJkRXJyb3IsXG4gICAgICB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IEhPU1RfUFJPQ0VTU19RVUVSWV9USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICAgIH0pO1xuICAgIGlmIChtZXNzYWdlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMubG9nKG1lc3NhZ2UpO1xuICAgIH1cblxuICAgIHJldHVybiBvdXRjb21lID09PSAnbGlzdGVkJyA/IHByb2Nlc3NlcyA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQb2xscyB1bnRpbCB0aGlzIHJ1bidzIGVtdWxhdG9yIGlzIGdvbmUsIG9yIHRoZSBidWRnZXQgZWxhcHNlcy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBkZXZpY2UsIHRoZSBQSURzIHRoaXMgcnVuIG93bnMsIGFuZCB0aGUgYnVkZ2V0LlxuICAgKiBAcmV0dXJucyBgdHJ1ZWAgd2hlbiB0aGUgZW11bGF0b3IgZGlzYXBwZWFyZWQgd2l0aGluIHRoZSBidWRnZXQuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHdhaXRGb3JFbXVsYXRvclN0b3BwZWQocGFyYW1zOiBFbXVsYXRvclJlY2xhaW1lcldhaXRGb3JFbXVsYXRvclN0b3BwZWRQYXJhbXMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBwYXJhbXMudGltZW91dEluTWlsbGlzZWNvbmRzO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgaWYgKGF3YWl0IHRoaXMuY2hlY2tJc0VtdWxhdG9yR29uZShwYXJhbXMpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIEVNVUxBVE9SX1NUT1BfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogTmFtZXMgdGhlIGVtdWxhdG9yIGEgbWFya2VyIGRlc2NyaWJlcywgZm9yIHRoZSBsb2cuXG4gKlxuICogQHBhcmFtIG1hcmtlciAtIFRoZSBtYXJrZXIuXG4gKiBAcmV0dXJucyBUaGUgQVZEIGFuZCBpdHMgZGV2aWNlLCBvciB0aGUgQVZEIGFsb25lIGZvciBhIGxhdW5jaCB0aGF0IGhhZCBub3QgcHJvZHVjZWQgYSBkZXZpY2UgeWV0LlxuICovXG5mdW5jdGlvbiBkZXNjcmliZU1hcmtlZEVtdWxhdG9yKG1hcmtlcjogRW11bGF0b3JNYXJrZXIpOiBzdHJpbmcge1xuICByZXR1cm4gbWFya2VyLmRldmljZUlkID09PSB1bmRlZmluZWRcbiAgICA/IGBBVkQgXCIke21hcmtlci5hdmROYW1lfVwiIChubyBkZXZpY2U6IGl0IHdhcyBzdGlsbCBib290aW5nIHdoZW4gaXQgd2FzIHJlY29yZGVkKWBcbiAgICA6IGBBVkQgXCIke21hcmtlci5hdmROYW1lfVwiIG9uIGRldmljZSAke21hcmtlci5kZXZpY2VJZH1gO1xufVxuXG4vKiB2OCBpZ25vcmUgc3RvcCAqL1xuIl0sCiAgIm1hcHBpbmdzIjogIkFBc0JBLFNBQVMsZ0JBQWdCO0FBQ3pCLE9BQU8sYUFBYTtBQVFwQixTQUFTLDJCQUEyQjtBQUNwQztBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1A7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUDtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1AsU0FBUywyQkFBMkI7QUFDcEM7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFLQSxNQUFNLDJDQUEyQztBQVFqRCxNQUFNLGtDQUFrQztBQW9DeEMsTUFBTSw2Q0FBNkM7QUFFMUQsTUFBTSxrREFBa0Q7QUFDeEQsTUFBTSw4Q0FBOEM7QUFDcEQsTUFBTSx3Q0FBd0M7QUFDOUMsTUFBTSwwQkFBMEI7QUEySHpCLE1BQU0sa0JBQWtCO0FBQUEsRUFDWjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9WLFlBQVksS0FBZ0M7QUFDakQsU0FBSyxNQUFNO0FBQUEsRUFDYjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFZTyxtQkFBb0M7QUFDekMsV0FBTyxJQUFJLFFBQWdCLENBQUMsU0FBUyxXQUFXO0FBQzlDLGVBQVMs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
@@ -49,7 +49,9 @@ export interface EnablePluginResult {
49
49
  *
50
50
  * Monkey-patches `app.plugins.loadPlugin` to intercept errors before
51
51
  * Obsidian's `enablePlugin` try-catch swallows them. The original method
52
- * is always restored in a `finally` block.
52
+ * is restored in a `finally` block — but only while the patch this function
53
+ * installed is still the one in place, so a plugin that patched the same slot
54
+ * during its own load keeps its patch.
53
55
  *
54
56
  * Designed to be passed as the `callback` argument to {@link evalInObsidian}.
55
57
  *
@@ -18,6 +18,7 @@ async function enablePluginWithErrorCapture({ app, pluginId }) {
18
18
  throw error;
19
19
  }
20
20
  };
21
+ const ourLoadPlugin = app.plugins.loadPlugin;
21
22
  const capturedConsole = [];
22
23
  const formatHolder = globalThis;
23
24
  function formatArgument(argument) {
@@ -38,14 +39,16 @@ async function enablePluginWithErrorCapture({ app, pluginId }) {
38
39
  }
39
40
  const origConsoleError = console.error;
40
41
  const origConsoleWarn = console.warn;
41
- console.error = (...input) => {
42
+ function ourConsoleError(...input) {
42
43
  recordConsole(...input);
43
44
  origConsoleError.apply(console, input);
44
- };
45
- console.warn = (...input) => {
45
+ }
46
+ function ourConsoleWarn(...input) {
46
47
  recordConsole(...input);
47
48
  origConsoleWarn.apply(console, input);
48
- };
49
+ }
50
+ console.error = ourConsoleError;
51
+ console.warn = ourConsoleWarn;
49
52
  function onWindowError(event) {
50
53
  capturedConsole.push(event.error instanceof Error ? formatArgument(event.error) : event.message);
51
54
  }
@@ -57,9 +60,15 @@ async function enablePluginWithErrorCapture({ app, pluginId }) {
57
60
  try {
58
61
  await app.plugins.enablePluginAndSave(pluginId);
59
62
  } finally {
60
- app.plugins.loadPlugin = origLoadPlugin;
61
- console.error = origConsoleError;
62
- console.warn = origConsoleWarn;
63
+ if (app.plugins.loadPlugin === ourLoadPlugin) {
64
+ app.plugins.loadPlugin = origLoadPlugin;
65
+ }
66
+ if (console.error === ourConsoleError) {
67
+ console.error = origConsoleError;
68
+ }
69
+ if (console.warn === ourConsoleWarn) {
70
+ console.warn = origConsoleWarn;
71
+ }
63
72
  globalThis.removeEventListener("error", onWindowError);
64
73
  globalThis.removeEventListener("unhandledrejection", onUnhandledRejection);
65
74
  }
@@ -83,4 +92,4 @@ export {
83
92
  enablePluginWithErrorCapture,
84
93
  getGenericPluginLoadFailureMessage
85
94
  };
86
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2VuYWJsZS1wbHVnaW4udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBTaGFyZWQgaGVscGVyIGZvciBlbmFibGluZyBhbiBPYnNpZGlhbiBwbHVnaW4gd2l0aCBlcnJvciBjYXB0dXJlLlxuICogVXNlZCBieSBib3RoIHRoZSBnbG9iYWwgc2V0dXAgYW5kIGludGVncmF0aW9uIHRlc3RzLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIGNvZGUgY292ZXJlZCBieSBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB0eXBlIHsgUGx1Z2luIH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQgdHlwZSB7IENvbW1vbkFyZ3VtZW50cyB9IGZyb20gJy4vZXZhbC1pbi1vYnNpZGlhbi5tanMnO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBlbmFibGVQbHVnaW5XaXRoRXJyb3JDYXB0dXJlfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbmFibGVQbHVnaW5QYXJhbXMge1xuICAvKipcbiAgICogVGhlIElEIG9mIHRoZSBwbHVnaW4gdG8gZW5hYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgcGx1Z2luSWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZXN1bHQgb2YgZW5hYmxpbmcgYSBwbHVnaW4gd2l0aCBlcnJvciBjYXB0dXJlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVuYWJsZVBsdWdpblJlc3VsdCB7XG4gIC8qKlxuICAgKiBUaGUgZXJyb3IgbWVzc2FnZSBjYXB0dXJlZCBieSB0aGUgYGxvYWRQbHVnaW5gIG1vbmtleS1wYXRjaCwgb3IgYHVuZGVmaW5lZGBcbiAgICogd2hlbiB0aGUgcGF0Y2ggc2F3IG5vIHRocm93LiBXaGVuIE9ic2lkaWFuIHN3YWxsb3dzIHRoZSBlcnJvciAqYmVmb3JlKiB0aGVcbiAgICogcGF0Y2ggKGxlYXZpbmcgdGhpcyBlbXB0eSkgYnV0IHRoZSBwbHVnaW4gc3RpbGwgZmFpbGVkIHRvIGxvYWQsIHRoZSByZWFsXG4gICAqIGNhdXNlIFx1MjAxNCBpZiBpdCByZWFjaGVkIHRoZSByZW5kZXJlciBjb25zb2xlIFx1MjAxNCBpcyBpbiB7QGxpbmsgRW5hYmxlUGx1Z2luUmVzdWx0LnJlbmRlcmVyQ29uc29sZUVycm9yc30uXG4gICAqL1xuICByZWFkb25seSBlcnJvck1lc3NhZ2U6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgcGx1Z2luIGlzIGluIHRoZSBlbmFibGVkIHNldCBhZnRlciB0aGUgZW5hYmxlIGF0dGVtcHQuXG4gICAqIEEgcGx1Z2luIGNhbiBiZSBcImVuYWJsZWRcIiAoY29uZmlndXJlZCkgYnV0IG5vdCBcImxvYWRlZFwiIChmYWlsZWQgdG8gaW5pdGlhbGl6ZSkuXG4gICAqL1xuICByZWFkb25seSBpc0VuYWJsZWQ6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHBsdWdpbiBpbnN0YW5jZSBhY3R1YWxseSBleGlzdHMgaW4gYGFwcC5wbHVnaW5zLnBsdWdpbnNgLlxuICAgKiBUaGlzIGlzIHRoZSBkZWZpbml0aXZlIGNoZWNrIFx1MjAxNCBhIHBsdWdpbiB0aGF0IGlzIGVuYWJsZWQgYnV0IG5vdCBsb2FkZWQgaGFzIGZhaWxlZC5cbiAgICovXG4gIHJlYWRvbmx5IGlzTG9hZGVkOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDb25zb2xlL2Vycm9yIG91dHB1dCBjYXB0dXJlZCBpbiB0aGUgcmVuZGVyZXIgZHVyaW5nIHRoZSBlbmFibGUgd2luZG93IFx1MjAxNFxuICAgKiBwb3B1bGF0ZWQgKipvbmx5Kiogd2hlbiB0aGUgcGx1Z2luIGZhaWxlZCB0byBsb2FkIGFuZCB0aGUgbW9ua2V5LXBhdGNoIHNhd1xuICAgKiBubyB0aHJvdyAoYCFlcnJvck1lc3NhZ2UgJiYgIWlzTG9hZGVkYCksIGkuZS4gZXhhY3RseSB0aGUgY2FzZSB0aGF0IHdvdWxkXG4gICAqIG90aGVyd2lzZSBzdXJmYWNlIHRoZSBnZW5lcmljIHtAbGluayBnZXRHZW5lcmljUGx1Z2luTG9hZEZhaWx1cmVNZXNzYWdlfSB0ZXh0LlxuICAgKiBgdW5kZWZpbmVkYCBvdGhlcndpc2UgKGluY2x1ZGluZyBvbiBzdWNjZXNzIGFuZCB3aGVuIHtAbGluayBFbmFibGVQbHVnaW5SZXN1bHQuZXJyb3JNZXNzYWdlfSBhbHJlYWR5IGhhcyB0aGUgZXJyb3IpLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVuZGVyZXJDb25zb2xlRXJyb3JzOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG5cbmludGVyZmFjZSBJbnRlZ3JhdGlvblRlc3RpbmdFcnJvclRvU3RyaW5nIHtcbiAgZXJyb3JUb1N0cmluZzogKGVycm9yOiB1bmtub3duKSA9PiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBJbnRlZ3JhdGlvblRlc3RpbmdIb2xkZXIge1xuICBfX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nOiBJbnRlZ3JhdGlvblRlc3RpbmdFcnJvclRvU3RyaW5nO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgYSBwbHVnaW4gaW5zaWRlIE9ic2lkaWFuIGFuZCBjYXB0dXJlcyBhbnkgbG9hZCBlcnJvci5cbiAqXG4gKiBNb25rZXktcGF0Y2hlcyBgYXBwLnBsdWdpbnMubG9hZFBsdWdpbmAgdG8gaW50ZXJjZXB0IGVycm9ycyBiZWZvcmVcbiAqIE9ic2lkaWFuJ3MgYGVuYWJsZVBsdWdpbmAgdHJ5LWNhdGNoIHN3YWxsb3dzIHRoZW0uIFRoZSBvcmlnaW5hbCBtZXRob2RcbiAqIGlzIGFsd2F5cyByZXN0b3JlZCBpbiBhIGBmaW5hbGx5YCBibG9jay5cbiAqXG4gKiBEZXNpZ25lZCB0byBiZSBwYXNzZWQgYXMgdGhlIGBjYWxsYmFja2AgYXJndW1lbnQgdG8ge0BsaW5rIGV2YWxJbk9ic2lkaWFufS5cbiAqXG4gKiBAcGFyYW0gaW5wdXQgLSBUaGUgY29tbW9uIGlucHV0IHBsdXMgdGhlIHBsdWdpbiBJRC5cbiAqIEBwYXJhbSBpbnB1dC5hcHAgLSBUaGUgT2JzaWRpYW4gYXBwIGluc3RhbmNlLlxuICogQHBhcmFtIGlucHV0LnBsdWdpbklkIC0gVGhlIElEIG9mIHRoZSBwbHVnaW4gdG8gZW5hYmxlLlxuICogQHJldHVybnMgVGhlIGVuYWJsZSByZXN1bHQgd2l0aCBlcnJvciBtZXNzYWdlIGFuZCBlbmFibGVkIHN0YXR1cy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGVuYWJsZVBsdWdpbldpdGhFcnJvckNhcHR1cmUoeyBhcHAsIHBsdWdpbklkIH06IENvbW1vbkFyZ3VtZW50cyAmIEVuYWJsZVBsdWdpblBhcmFtcyk6IFByb21pc2U8RW5hYmxlUGx1Z2luUmVzdWx0PiB7XG4gIGlmICghYXBwLnBsdWdpbnMuaXNFbmFibGVkKCkpIHtcbiAgICBhd2FpdCBhcHAucGx1Z2lucy5zZXRFbmFibGUodHJ1ZSk7XG4gIH1cblxuICAvKlxuICAgKiBGb3JjZSBhIGdlbnVpbmUgcmVsb2FkIHdoZW4gcmV0cnlpbmcuIElmIGEgcHJpb3IgYXR0ZW1wdCBsZWZ0IHRoZSBwbHVnaW4gaW5cbiAgICogdGhlIGVuYWJsZWQgc2V0IGJ1dCBub3QgbG9hZGVkICh0aGUgY29sZC1ib290IHJhY2UpLCBhIHBsYWluIHJlLWVuYWJsZSBjYW5cbiAgICogc2hvcnQtY2lyY3VpdCBvbiBzb21lIE9ic2lkaWFuIHZlcnNpb25zIHdpdGhvdXQgcmUtYXR0ZW1wdGluZyB0aGUgbG9hZC5cbiAgICogRnVsbHkgcmVzZXQgdGhlIGVuYWJsZWQgc3RhdGUgZmlyc3Qgc28gdGhlIGBlbmFibGVQbHVnaW5BbmRTYXZlYCBiZWxvdyBpcyBhXG4gICAqIHJlYWwgZnJlc2ggZW5hYmxlICsgbG9hZC4gTm8tb3Agb24gdGhlIGZpcnN0IGF0dGVtcHQgKG5vdCB5ZXQgZW5hYmxlZCkuXG4gICAqL1xuICBpZiAoYXBwLnBsdWdpbnMuZW5hYmxlZFBsdWdpbnMuaGFzKHBsdWdpbklkKSAmJiAhT2JqZWN0Lmhhc093bihhcHAucGx1Z2lucy5wbHVnaW5zLCBwbHVnaW5JZCkpIHtcbiAgICBhd2FpdCBhcHAucGx1Z2lucy5kaXNhYmxlUGx1Z2luQW5kU2F2ZShwbHVnaW5JZCk7XG4gIH1cblxuICBsZXQgZXJyb3JNZXNzYWdlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvdW5ib3VuZC1tZXRob2QgLS0gSW50ZW50aW9uYWwgbW9ua2V5LXBhdGNoOyByZXN0b3JlZCBpbiBmaW5hbGx5LlxuICBjb25zdCBvcmlnTG9hZFBsdWdpbiA9IGFwcC5wbHVnaW5zLmxvYWRQbHVnaW47XG4gIGFwcC5wbHVnaW5zLmxvYWRQbHVnaW4gPSBhc3luYyBmdW5jdGlvbiBsb2FkUGx1Z2luKGlkOiBzdHJpbmcsIGlzVXNlckVuYWJsZWQ/OiBib29sZWFuKTogUHJvbWlzZTxQbHVnaW4+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgb3JpZ0xvYWRQbHVnaW4uY2FsbCh0aGlzLCBpZCwgaXNVc2VyRW5hYmxlZCk7XG4gICAgICBlcnJvck1lc3NhZ2UgPSB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXggLS0gQXBwcm92ZWQgZG91YmxlIGNhc3Q6IGBfX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nYCBpcyBvdXIgaW50ZXJuYWwgV2luZG93IGF1Z21lbnRhdGlvbiwgaW50ZW50aW9uYWxseSBrZXB0IGxvY2FsIChub3QgZGVjbGFyZWQgZ2xvYmFsbHkpIHRvIGF2b2lkIGxlYWtpbmcgaW50byBjb25zdW1lciB0eXBlcy5cbiAgICAgIGNvbnN0IGhvbGRlciA9IGdsb2JhbFRoaXMgYXMgdW5rbm93biBhcyBQYXJ0aWFsPEludGVncmF0aW9uVGVzdGluZ0hvbGRlcj47XG4gICAgICBlcnJvck1lc3NhZ2UgPSBob2xkZXIuX19vYnNpZGlhbkludGVncmF0aW9uVGVzdGluZz8uZXJyb3JUb1N0cmluZyhlcnJvcikgPz8gU3RyaW5nKGVycm9yKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfTtcblxuICAvKlxuICAgKiBMYXllciAxIFx1MjAxNCBjYXB0dXJlIHRoZSByZW5kZXJlciBjb25zb2xlICsgdW5jYXVnaHQgZXJyb3JzIGZvciB0aGUgZHVyYXRpb24gb2ZcbiAgICogdGhlIGVuYWJsZS4gSWYgT2JzaWRpYW4gc3dhbGxvd3MgdGhlIGxvYWQgZXJyb3IgYmVmb3JlIHRoZSBtb25rZXktcGF0Y2ggYWJvdmVcbiAgICogc2VlcyBpdCAobGVhdmluZyBgZXJyb3JNZXNzYWdlYCBlbXB0eSksIHRoZSByZWFsIGNhdXNlIGlzIHR5cGljYWxseSBzdGlsbFxuICAgKiBgY29uc29sZS5lcnJvcmAnZCwgc28gY2FwdHVyaW5nIGl0IGhlcmUgc3VyZmFjZXMgaXQgaW4gcGxhY2Ugb2YgdGhlIGdlbmVyaWNcbiAgICogZmFsbGJhY2suIFdvcmtzIG9uIGRlc2t0b3AgYW5kIEFuZHJvaWQgYWxpa2Ugc2luY2UgdGhpcyB3aG9sZSBmdW5jdGlvbiBpc1xuICAgKiBzZXJpYWxpemVkIGFuZCBpbmplY3RlZCBpbnRvIHRoZSByZW5kZXJlci5cbiAgICovXG4gIGNvbnN0IGNhcHR1cmVkQ29uc29sZTogc3RyaW5nW10gPSBbXTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4IC0tIEFwcHJvdmVkIGRvdWJsZSBjYXN0LCBzYW1lIHJhdGlvbmFsZSBhcyBhYm92ZS5cbiAgY29uc3QgZm9ybWF0SG9sZGVyID0gZ2xvYmFsVGhpcyBhcyB1bmtub3duIGFzIFBhcnRpYWw8SW50ZWdyYXRpb25UZXN0aW5nSG9sZGVyPjtcbiAgZnVuY3Rpb24gZm9ybWF0QXJndW1lbnQoYXJndW1lbnQ6IHVua25vd24pOiBzdHJpbmcge1xuICAgIGlmIChhcmd1bWVudCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICByZXR1cm4gZm9ybWF0SG9sZGVyLl9fb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3Rpbmc/LmVycm9yVG9TdHJpbmcoYXJndW1lbnQpID8/IFN0cmluZyhhcmd1bWVudCk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYXJndW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnQ7XG4gICAgfVxuICAgIGlmIChhcmd1bWVudCA9PT0gdW5kZWZpbmVkIHx8IGFyZ3VtZW50ID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gU3RyaW5nKGFyZ3VtZW50KTtcbiAgICB9XG4gICAgY29uc3QganNvbiA9IEpTT04uc3RyaW5naWZ5KGFyZ3VtZW50KTtcbiAgICByZXR1cm4ganNvbiA/PyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJndW1lbnQpO1xuICB9XG4gIGZ1bmN0aW9uIHJlY29yZENvbnNvbGUoLi4uaW5wdXQ6IHVua25vd25bXSk6IHZvaWQge1xuICAgIGNhcHR1cmVkQ29uc29sZS5wdXNoKGlucHV0Lm1hcCgoYXJndW1lbnQpID0+IGZvcm1hdEFyZ3VtZW50KGFyZ3VtZW50KSkuam9pbignICcpKTtcbiAgfVxuICBjb25zdCBvcmlnQ29uc29sZUVycm9yID0gY29uc29sZS5lcnJvcjtcbiAgY29uc3Qgb3JpZ0NvbnNvbGVXYXJuID0gY29uc29sZS53YXJuO1xuICBjb25zb2xlLmVycm9yID0gKC4uLmlucHV0OiB1bmtub3duW10pOiB2b2lkID0+IHtcbiAgICByZWNvcmRDb25zb2xlKC4uLmlucHV0KTtcbiAgICBvcmlnQ29uc29sZUVycm9yLmFwcGx5KGNvbnNvbGUsIGlucHV0KTtcbiAgfTtcbiAgY29uc29sZS53YXJuID0gKC4uLmlucHV0OiB1bmtub3duW10pOiB2b2lkID0+IHtcbiAgICByZWNvcmRDb25zb2xlKC4uLmlucHV0KTtcbiAgICBvcmlnQ29uc29sZVdhcm4uYXBwbHkoY29uc29sZSwgaW5wdXQpO1xuICB9O1xuICBmdW5jdGlvbiBvbldpbmRvd0Vycm9yKGV2ZW50OiBFcnJvckV2ZW50KTogdm9pZCB7XG4gICAgY2FwdHVyZWRDb25zb2xlLnB1c2goZXZlbnQuZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGZvcm1hdEFyZ3VtZW50KGV2ZW50LmVycm9yKSA6IGV2ZW50Lm1lc3NhZ2UpO1xuICB9XG4gIGZ1bmN0aW9uIG9uVW5oYW5kbGVkUmVqZWN0aW9uKGV2ZW50OiBQcm9taXNlUmVqZWN0aW9uRXZlbnQpOiB2b2lkIHtcbiAgICBjYXB0dXJlZENvbnNvbGUucHVzaChmb3JtYXRBcmd1bWVudChldmVudC5yZWFzb24pKTtcbiAgfVxuICBnbG9iYWxUaGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgb25XaW5kb3dFcnJvcik7XG4gIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcigndW5oYW5kbGVkcmVqZWN0aW9uJywgb25VbmhhbmRsZWRSZWplY3Rpb24pO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgYXBwLnBsdWdpbnMuZW5hYmxlUGx1Z2luQW5kU2F2ZShwbHVnaW5JZCk7XG4gIH0gZmluYWxseSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlcXVpcmUtYXRvbWljLXVwZGF0ZXMgLS0gSW50ZW50aW9uYWwgcmVzdG9yZSBvZiBtb25rZXktcGF0Y2guXG4gICAgYXBwLnBsdWdpbnMubG9hZFBsdWdpbiA9IG9yaWdMb2FkUGx1Z2luO1xuICAgIGNvbnNvbGUuZXJyb3IgPSBvcmlnQ29uc29sZUVycm9yO1xuICAgIGNvbnNvbGUud2FybiA9IG9yaWdDb25zb2xlV2FybjtcbiAgICBnbG9iYWxUaGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgb25XaW5kb3dFcnJvcik7XG4gICAgZ2xvYmFsVGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCd1bmhhbmRsZWRyZWplY3Rpb24nLCBvblVuaGFuZGxlZFJlamVjdGlvbik7XG4gIH1cblxuICBjb25zdCBpc0xvYWRlZCA9IE9iamVjdC5oYXNPd24oYXBwLnBsdWdpbnMucGx1Z2lucywgcGx1Z2luSWQpO1xuXG4gIGxldCByZW5kZXJlckNvbnNvbGVFcnJvcnM6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgaWYgKCFlcnJvck1lc3NhZ2UgJiYgIWlzTG9hZGVkKSB7XG4gICAgY29uc3Qgam9pbmVkID0gY2FwdHVyZWRDb25zb2xlLmpvaW4oJ1xcbicpLnRyaW0oKTtcbiAgICByZW5kZXJlckNvbnNvbGVFcnJvcnMgPSBqb2luZWQgfHwgdW5kZWZpbmVkO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBlcnJvck1lc3NhZ2UsXG4gICAgaXNFbmFibGVkOiBhcHAucGx1Z2lucy5lbmFibGVkUGx1Z2lucy5oYXMocGx1Z2luSWQpLFxuICAgIGlzTG9hZGVkLFxuICAgIHJlbmRlcmVyQ29uc29sZUVycm9yc1xuICB9O1xufVxuXG4vKipcbiAqIFRoZSBnZW5lcmljIGxhc3QtcmVzb3J0IG1lc3NhZ2Ugc2hvd24gd2hlbiBhIHBsdWdpbiBpcyBpbiB0aGUgZW5hYmxlZCBzZXQgYnV0XG4gKiBub3QgbG9hZGVkIGFuZCBubyByZWFsIGVycm9yIGNvdWxkIGJlIGNhcHR1cmVkIChuZWl0aGVyIHRoZSBgbG9hZFBsdWdpbmBcbiAqIG1vbmtleS1wYXRjaCBub3IgdGhlIHJlbmRlcmVyIGNvbnNvbGUgbm9yLCBvbiBBbmRyb2lkLCBgYWRiIGxvZ2NhdGAgc3VyZmFjZWQgYVxuICogY2F1c2UpLlxuICpcbiAqIEhvc3Qtc2lkZSBoZWxwZXIgXHUyMDE0IHVzZWQgYnkgdGhlIHNldHVwIG9yY2hlc3RyYXRpb24gdG8gY29tcG9zZSB0aGUgZmluYWxcbiAqIGZhaWx1cmUgbWVzc2FnZSwgc28gdGhlIHJlbmRlcmVyLWluamVjdGVkIHtAbGluayBlbmFibGVQbHVnaW5XaXRoRXJyb3JDYXB0dXJlfVxuICogc3RheXMgc2VsZi1jb250YWluZWQuXG4gKlxuICogQHBhcmFtIHBsdWdpbklkIC0gVGhlIElEIG9mIHRoZSBwbHVnaW4gdGhhdCBmYWlsZWQgdG8gbG9hZC5cbiAqIEByZXR1cm5zIFRoZSBnZW5lcmljIGZhaWx1cmUgbWVzc2FnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEdlbmVyaWNQbHVnaW5Mb2FkRmFpbHVyZU1lc3NhZ2UocGx1Z2luSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgUGx1Z2luIFwiJHtwbHVnaW5JZH1cIiBpcyBpbiB0aGUgZW5hYmxlZCBzZXQgYnV0IG5vdCBsb2FkZWQuIGBcbiAgICArICdPYnNpZGlhbiBtYXkgaGF2ZSBjYXVnaHQgdGhlIGVycm9yIGJlZm9yZSB0aGUgbW9ua2V5LXBhdGNoLiAnXG4gICAgKyAnQ2hlY2sgdGhlIE9ic2lkaWFuIGNvbnNvbGUgZm9yIGRldGFpbHMuJztcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICJBQStFQSxlQUFzQiw2QkFBNkIsRUFBRSxLQUFLLFNBQVMsR0FBc0U7QUFDdkksTUFBSSxDQUFDLElBQUksUUFBUSxVQUFVLEdBQUc7QUFDNUIsVUFBTSxJQUFJLFFBQVEsVUFBVSxJQUFJO0FBQUEsRUFDbEM7QUFTQSxNQUFJLElBQUksUUFBUSxlQUFlLElBQUksUUFBUSxLQUFLLENBQUMsT0FBTyxPQUFPLElBQUksUUFBUSxTQUFTLFFBQVEsR0FBRztBQUM3RixVQUFNLElBQUksUUFBUSxxQkFBcUIsUUFBUTtBQUFBLEVBQ2pEO0FBRUEsTUFBSTtBQUVKLFFBQU0saUJBQWlCLElBQUksUUFBUTtBQUNuQyxNQUFJLFFBQVEsYUFBYSxlQUFlLFdBQVcsSUFBWSxlQUEwQztBQUN2RyxRQUFJO0FBQ0YsWUFBTSxTQUFTLE1BQU0sZUFBZSxLQUFLLE1BQU0sSUFBSSxhQUFhO0FBQ2hFLHFCQUFlO0FBQ2YsYUFBTztBQUFBLElBQ1QsU0FBUyxPQUFPO0FBRWQsWUFBTSxTQUFTO0FBQ2YscUJBQWUsT0FBTyw4QkFBOEIsY0FBYyxLQUFLLEtBQUssT0FBTyxLQUFLO0FBQ3hGLFlBQU07QUFBQSxJQUNSO0FBQUEsRUFDRjtBQVVBLFFBQU0sa0JBQTRCLENBQUM7QUFFbkMsUUFBTSxlQUFlO0FBQ3JCLFdBQVMsZUFBZSxVQUEyQjtBQUNqRCxRQUFJLG9CQUFvQixPQUFPO0FBQzdCLGFBQU8sYUFBYSw4QkFBOEIsY0FBYyxRQUFRLEtBQUssT0FBTyxRQUFRO0FBQUEsSUFDOUY7QUFDQSxRQUFJLE9BQU8sYUFBYSxVQUFVO0FBQ2hDLGFBQU87QUFBQSxJQUNUO0FBQ0EsUUFBSSxhQUFhLFVBQWEsYUFBYSxNQUFNO0FBQy9DLGFBQU8sT0FBTyxRQUFRO0FBQUEsSUFDeEI7QUFDQSxVQUFNLE9BQU8sS0FBSyxVQUFVLFFBQVE7QUFDcEMsV0FBTyxRQUFRLE9BQU8sVUFBVSxTQUFTLEtBQUssUUFBUTtBQUFBLEVBQ3hEO0FBQ0EsV0FBUyxpQkFBaUIsT0FBd0I7QUFDaEQsb0JBQWdCLEtBQUssTUFBTSxJQUFJLENBQUMsYUFBYSxlQUFlLFFBQVEsQ0FBQyxFQUFFLEtBQUssR0FBRyxDQUFDO0FBQUEsRUFDbEY7QUFDQSxRQUFNLG1CQUFtQixRQUFRO0FBQ2pDLFFBQU0sa0JBQWtCLFFBQVE7QUFDaEMsVUFBUSxRQUFRLElBQUksVUFBMkI7QUFDN0Msa0JBQWMsR0FBRyxLQUFLO0FBQ3RCLHFCQUFpQixNQUFNLFNBQVMsS0FBSztBQUFBLEVBQ3ZDO0FBQ0EsVUFBUSxPQUFPLElBQUksVUFBMkI7QUFDNUMsa0JBQWMsR0FBRyxLQUFLO0FBQ3RCLG9CQUFnQixNQUFNLFNBQVMsS0FBSztBQUFBLEVBQ3RDO0FBQ0EsV0FBUyxjQUFjLE9BQXlCO0FBQzlDLG9CQUFnQixLQUFLLE1BQU0saUJBQWlCLFFBQVEsZUFBZSxNQUFNLEtBQUssSUFBSSxNQUFNLE9BQU87QUFBQSxFQUNqRztBQUNBLFdBQVMscUJBQXFCLE9BQW9DO0FBQ2hFLG9CQUFnQixLQUFLLGVBQWUsTUFBTSxNQUFNLENBQUM7QUFBQSxFQUNuRDtBQUNBLGFBQVcsaUJBQWlCLFNBQVMsYUFBYTtBQUNsRCxhQUFXLGlCQUFpQixzQkFBc0Isb0JBQW9CO0FBRXRFLE1BQUk7QUFDRixVQUFNLElBQUksUUFBUSxvQkFBb0IsUUFBUTtBQUFBLEVBQ2hELFVBQUU7QUFFQSxRQUFJLFFBQVEsYUFBYTtBQUN6QixZQUFRLFFBQVE7QUFDaEIsWUFBUSxPQUFPO0FBQ2YsZUFBVyxvQkFBb0IsU0FBUyxhQUFhO0FBQ3JELGVBQVcsb0JBQW9CLHNCQUFzQixvQkFBb0I7QUFBQSxFQUMzRTtBQUVBLFFBQU0sV0FBVyxPQUFPLE9BQU8sSUFBSSxRQUFRLFNBQVMsUUFBUTtBQUU1RCxNQUFJO0FBQ0osTUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVU7QUFDOUIsVUFBTSxTQUFTLGdCQUFnQixLQUFLLElBQUksRUFBRSxLQUFLO0FBQy9DLDRCQUF3QixVQUFVO0FBQUEsRUFDcEM7QUFFQSxTQUFPO0FBQUEsSUFDTDtBQUFBLElBQ0EsV0FBVyxJQUFJLFFBQVEsZUFBZSxJQUFJLFFBQVE7QUFBQSxJQUNsRDtBQUFBLElBQ0E7QUFBQSxFQUNGO0FBQ0Y7QUFlTyxTQUFTLG1DQUFtQyxVQUEwQjtBQUMzRSxTQUFPLFdBQVcsUUFBUTtBQUc1QjsiLAogICJuYW1lcyI6IFtdCn0K
95
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2VuYWJsZS1wbHVnaW4udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBTaGFyZWQgaGVscGVyIGZvciBlbmFibGluZyBhbiBPYnNpZGlhbiBwbHVnaW4gd2l0aCBlcnJvciBjYXB0dXJlLlxuICogVXNlZCBieSBib3RoIHRoZSBnbG9iYWwgc2V0dXAgYW5kIGludGVncmF0aW9uIHRlc3RzLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIGNvZGUgY292ZXJlZCBieSBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB0eXBlIHsgUGx1Z2luIH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQgdHlwZSB7IENvbW1vbkFyZ3VtZW50cyB9IGZyb20gJy4vZXZhbC1pbi1vYnNpZGlhbi5tanMnO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBlbmFibGVQbHVnaW5XaXRoRXJyb3JDYXB0dXJlfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbmFibGVQbHVnaW5QYXJhbXMge1xuICAvKipcbiAgICogVGhlIElEIG9mIHRoZSBwbHVnaW4gdG8gZW5hYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgcGx1Z2luSWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZXN1bHQgb2YgZW5hYmxpbmcgYSBwbHVnaW4gd2l0aCBlcnJvciBjYXB0dXJlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVuYWJsZVBsdWdpblJlc3VsdCB7XG4gIC8qKlxuICAgKiBUaGUgZXJyb3IgbWVzc2FnZSBjYXB0dXJlZCBieSB0aGUgYGxvYWRQbHVnaW5gIG1vbmtleS1wYXRjaCwgb3IgYHVuZGVmaW5lZGBcbiAgICogd2hlbiB0aGUgcGF0Y2ggc2F3IG5vIHRocm93LiBXaGVuIE9ic2lkaWFuIHN3YWxsb3dzIHRoZSBlcnJvciAqYmVmb3JlKiB0aGVcbiAgICogcGF0Y2ggKGxlYXZpbmcgdGhpcyBlbXB0eSkgYnV0IHRoZSBwbHVnaW4gc3RpbGwgZmFpbGVkIHRvIGxvYWQsIHRoZSByZWFsXG4gICAqIGNhdXNlIFx1MjAxNCBpZiBpdCByZWFjaGVkIHRoZSByZW5kZXJlciBjb25zb2xlIFx1MjAxNCBpcyBpbiB7QGxpbmsgRW5hYmxlUGx1Z2luUmVzdWx0LnJlbmRlcmVyQ29uc29sZUVycm9yc30uXG4gICAqL1xuICByZWFkb25seSBlcnJvck1lc3NhZ2U6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgcGx1Z2luIGlzIGluIHRoZSBlbmFibGVkIHNldCBhZnRlciB0aGUgZW5hYmxlIGF0dGVtcHQuXG4gICAqIEEgcGx1Z2luIGNhbiBiZSBcImVuYWJsZWRcIiAoY29uZmlndXJlZCkgYnV0IG5vdCBcImxvYWRlZFwiIChmYWlsZWQgdG8gaW5pdGlhbGl6ZSkuXG4gICAqL1xuICByZWFkb25seSBpc0VuYWJsZWQ6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHBsdWdpbiBpbnN0YW5jZSBhY3R1YWxseSBleGlzdHMgaW4gYGFwcC5wbHVnaW5zLnBsdWdpbnNgLlxuICAgKiBUaGlzIGlzIHRoZSBkZWZpbml0aXZlIGNoZWNrIFx1MjAxNCBhIHBsdWdpbiB0aGF0IGlzIGVuYWJsZWQgYnV0IG5vdCBsb2FkZWQgaGFzIGZhaWxlZC5cbiAgICovXG4gIHJlYWRvbmx5IGlzTG9hZGVkOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDb25zb2xlL2Vycm9yIG91dHB1dCBjYXB0dXJlZCBpbiB0aGUgcmVuZGVyZXIgZHVyaW5nIHRoZSBlbmFibGUgd2luZG93IFx1MjAxNFxuICAgKiBwb3B1bGF0ZWQgKipvbmx5Kiogd2hlbiB0aGUgcGx1Z2luIGZhaWxlZCB0byBsb2FkIGFuZCB0aGUgbW9ua2V5LXBhdGNoIHNhd1xuICAgKiBubyB0aHJvdyAoYCFlcnJvck1lc3NhZ2UgJiYgIWlzTG9hZGVkYCksIGkuZS4gZXhhY3RseSB0aGUgY2FzZSB0aGF0IHdvdWxkXG4gICAqIG90aGVyd2lzZSBzdXJmYWNlIHRoZSBnZW5lcmljIHtAbGluayBnZXRHZW5lcmljUGx1Z2luTG9hZEZhaWx1cmVNZXNzYWdlfSB0ZXh0LlxuICAgKiBgdW5kZWZpbmVkYCBvdGhlcndpc2UgKGluY2x1ZGluZyBvbiBzdWNjZXNzIGFuZCB3aGVuIHtAbGluayBFbmFibGVQbHVnaW5SZXN1bHQuZXJyb3JNZXNzYWdlfSBhbHJlYWR5IGhhcyB0aGUgZXJyb3IpLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVuZGVyZXJDb25zb2xlRXJyb3JzOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG5cbmludGVyZmFjZSBJbnRlZ3JhdGlvblRlc3RpbmdFcnJvclRvU3RyaW5nIHtcbiAgZXJyb3JUb1N0cmluZzogKGVycm9yOiB1bmtub3duKSA9PiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBJbnRlZ3JhdGlvblRlc3RpbmdIb2xkZXIge1xuICBfX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nOiBJbnRlZ3JhdGlvblRlc3RpbmdFcnJvclRvU3RyaW5nO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgYSBwbHVnaW4gaW5zaWRlIE9ic2lkaWFuIGFuZCBjYXB0dXJlcyBhbnkgbG9hZCBlcnJvci5cbiAqXG4gKiBNb25rZXktcGF0Y2hlcyBgYXBwLnBsdWdpbnMubG9hZFBsdWdpbmAgdG8gaW50ZXJjZXB0IGVycm9ycyBiZWZvcmVcbiAqIE9ic2lkaWFuJ3MgYGVuYWJsZVBsdWdpbmAgdHJ5LWNhdGNoIHN3YWxsb3dzIHRoZW0uIFRoZSBvcmlnaW5hbCBtZXRob2RcbiAqIGlzIHJlc3RvcmVkIGluIGEgYGZpbmFsbHlgIGJsb2NrIFx1MjAxNCBidXQgb25seSB3aGlsZSB0aGUgcGF0Y2ggdGhpcyBmdW5jdGlvblxuICogaW5zdGFsbGVkIGlzIHN0aWxsIHRoZSBvbmUgaW4gcGxhY2UsIHNvIGEgcGx1Z2luIHRoYXQgcGF0Y2hlZCB0aGUgc2FtZSBzbG90XG4gKiBkdXJpbmcgaXRzIG93biBsb2FkIGtlZXBzIGl0cyBwYXRjaC5cbiAqXG4gKiBEZXNpZ25lZCB0byBiZSBwYXNzZWQgYXMgdGhlIGBjYWxsYmFja2AgYXJndW1lbnQgdG8ge0BsaW5rIGV2YWxJbk9ic2lkaWFufS5cbiAqXG4gKiBAcGFyYW0gaW5wdXQgLSBUaGUgY29tbW9uIGlucHV0IHBsdXMgdGhlIHBsdWdpbiBJRC5cbiAqIEBwYXJhbSBpbnB1dC5hcHAgLSBUaGUgT2JzaWRpYW4gYXBwIGluc3RhbmNlLlxuICogQHBhcmFtIGlucHV0LnBsdWdpbklkIC0gVGhlIElEIG9mIHRoZSBwbHVnaW4gdG8gZW5hYmxlLlxuICogQHJldHVybnMgVGhlIGVuYWJsZSByZXN1bHQgd2l0aCBlcnJvciBtZXNzYWdlIGFuZCBlbmFibGVkIHN0YXR1cy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGVuYWJsZVBsdWdpbldpdGhFcnJvckNhcHR1cmUoeyBhcHAsIHBsdWdpbklkIH06IENvbW1vbkFyZ3VtZW50cyAmIEVuYWJsZVBsdWdpblBhcmFtcyk6IFByb21pc2U8RW5hYmxlUGx1Z2luUmVzdWx0PiB7XG4gIGlmICghYXBwLnBsdWdpbnMuaXNFbmFibGVkKCkpIHtcbiAgICBhd2FpdCBhcHAucGx1Z2lucy5zZXRFbmFibGUodHJ1ZSk7XG4gIH1cblxuICAvKlxuICAgKiBGb3JjZSBhIGdlbnVpbmUgcmVsb2FkIHdoZW4gcmV0cnlpbmcuIElmIGEgcHJpb3IgYXR0ZW1wdCBsZWZ0IHRoZSBwbHVnaW4gaW5cbiAgICogdGhlIGVuYWJsZWQgc2V0IGJ1dCBub3QgbG9hZGVkICh0aGUgY29sZC1ib290IHJhY2UpLCBhIHBsYWluIHJlLWVuYWJsZSBjYW5cbiAgICogc2hvcnQtY2lyY3VpdCBvbiBzb21lIE9ic2lkaWFuIHZlcnNpb25zIHdpdGhvdXQgcmUtYXR0ZW1wdGluZyB0aGUgbG9hZC5cbiAgICogRnVsbHkgcmVzZXQgdGhlIGVuYWJsZWQgc3RhdGUgZmlyc3Qgc28gdGhlIGBlbmFibGVQbHVnaW5BbmRTYXZlYCBiZWxvdyBpcyBhXG4gICAqIHJlYWwgZnJlc2ggZW5hYmxlICsgbG9hZC4gTm8tb3Agb24gdGhlIGZpcnN0IGF0dGVtcHQgKG5vdCB5ZXQgZW5hYmxlZCkuXG4gICAqL1xuICBpZiAoYXBwLnBsdWdpbnMuZW5hYmxlZFBsdWdpbnMuaGFzKHBsdWdpbklkKSAmJiAhT2JqZWN0Lmhhc093bihhcHAucGx1Z2lucy5wbHVnaW5zLCBwbHVnaW5JZCkpIHtcbiAgICBhd2FpdCBhcHAucGx1Z2lucy5kaXNhYmxlUGx1Z2luQW5kU2F2ZShwbHVnaW5JZCk7XG4gIH1cblxuICBsZXQgZXJyb3JNZXNzYWdlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvdW5ib3VuZC1tZXRob2QgLS0gSW50ZW50aW9uYWwgbW9ua2V5LXBhdGNoOyByZXN0b3JlZCBpbiBmaW5hbGx5LlxuICBjb25zdCBvcmlnTG9hZFBsdWdpbiA9IGFwcC5wbHVnaW5zLmxvYWRQbHVnaW47XG4gIGFwcC5wbHVnaW5zLmxvYWRQbHVnaW4gPSBhc3luYyBmdW5jdGlvbiBsb2FkUGx1Z2luKGlkOiBzdHJpbmcsIGlzVXNlckVuYWJsZWQ/OiBib29sZWFuKTogUHJvbWlzZTxQbHVnaW4+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgb3JpZ0xvYWRQbHVnaW4uY2FsbCh0aGlzLCBpZCwgaXNVc2VyRW5hYmxlZCk7XG4gICAgICBlcnJvck1lc3NhZ2UgPSB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXggLS0gQXBwcm92ZWQgZG91YmxlIGNhc3Q6IGBfX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nYCBpcyBvdXIgaW50ZXJuYWwgV2luZG93IGF1Z21lbnRhdGlvbiwgaW50ZW50aW9uYWxseSBrZXB0IGxvY2FsIChub3QgZGVjbGFyZWQgZ2xvYmFsbHkpIHRvIGF2b2lkIGxlYWtpbmcgaW50byBjb25zdW1lciB0eXBlcy5cbiAgICAgIGNvbnN0IGhvbGRlciA9IGdsb2JhbFRoaXMgYXMgdW5rbm93biBhcyBQYXJ0aWFsPEludGVncmF0aW9uVGVzdGluZ0hvbGRlcj47XG4gICAgICBlcnJvck1lc3NhZ2UgPSBob2xkZXIuX19vYnNpZGlhbkludGVncmF0aW9uVGVzdGluZz8uZXJyb3JUb1N0cmluZyhlcnJvcikgPz8gU3RyaW5nKGVycm9yKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfTtcbiAgLypcbiAgICogUmVhZCB0aGUgd3JhcHBlciBiYWNrIHNvIHRoZSBgZmluYWxseWAgY2FuIHRlbGwgXCJzdGlsbCBvdXJzXCIgZnJvbSBcInNvbWVvbmUgcGF0Y2hlZCBvdmVyIHVzXCIuIEFzc2lnbmluZ1xuICAgKiBpdCB0aHJvdWdoIGBhcHAucGx1Z2lucy5sb2FkUGx1Z2luYCByYXRoZXIgdGhhbiBkZWNsYXJpbmcgaXQgc3RhbmRhbG9uZSBpcyB3aGF0IHR5cGVzIGl0cyBgdGhpc2AuXG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3VuYm91bmQtbWV0aG9kIC0tIFJlYWRpbmcgYmFjayB0aGUgcGF0Y2gganVzdCBpbnN0YWxsZWQsIHRvIHJlc3RvcmUgaXQgY29uZGl0aW9uYWxseS5cbiAgY29uc3Qgb3VyTG9hZFBsdWdpbiA9IGFwcC5wbHVnaW5zLmxvYWRQbHVnaW47XG5cbiAgLypcbiAgICogTGF5ZXIgMSBcdTIwMTQgY2FwdHVyZSB0aGUgcmVuZGVyZXIgY29uc29sZSArIHVuY2F1Z2h0IGVycm9ycyBmb3IgdGhlIGR1cmF0aW9uIG9mXG4gICAqIHRoZSBlbmFibGUuIElmIE9ic2lkaWFuIHN3YWxsb3dzIHRoZSBsb2FkIGVycm9yIGJlZm9yZSB0aGUgbW9ua2V5LXBhdGNoIGFib3ZlXG4gICAqIHNlZXMgaXQgKGxlYXZpbmcgYGVycm9yTWVzc2FnZWAgZW1wdHkpLCB0aGUgcmVhbCBjYXVzZSBpcyB0eXBpY2FsbHkgc3RpbGxcbiAgICogYGNvbnNvbGUuZXJyb3JgJ2QsIHNvIGNhcHR1cmluZyBpdCBoZXJlIHN1cmZhY2VzIGl0IGluIHBsYWNlIG9mIHRoZSBnZW5lcmljXG4gICAqIGZhbGxiYWNrLiBXb3JrcyBvbiBkZXNrdG9wIGFuZCBBbmRyb2lkIGFsaWtlIHNpbmNlIHRoaXMgd2hvbGUgZnVuY3Rpb24gaXNcbiAgICogc2VyaWFsaXplZCBhbmQgaW5qZWN0ZWQgaW50byB0aGUgcmVuZGVyZXIuXG4gICAqL1xuICBjb25zdCBjYXB0dXJlZENvbnNvbGU6IHN0cmluZ1tdID0gW107XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheCAtLSBBcHByb3ZlZCBkb3VibGUgY2FzdCwgc2FtZSByYXRpb25hbGUgYXMgYWJvdmUuXG4gIGNvbnN0IGZvcm1hdEhvbGRlciA9IGdsb2JhbFRoaXMgYXMgdW5rbm93biBhcyBQYXJ0aWFsPEludGVncmF0aW9uVGVzdGluZ0hvbGRlcj47XG4gIGZ1bmN0aW9uIGZvcm1hdEFyZ3VtZW50KGFyZ3VtZW50OiB1bmtub3duKTogc3RyaW5nIHtcbiAgICBpZiAoYXJndW1lbnQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgcmV0dXJuIGZvcm1hdEhvbGRlci5fX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nPy5lcnJvclRvU3RyaW5nKGFyZ3VtZW50KSA/PyBTdHJpbmcoYXJndW1lbnQpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGFyZ3VtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50O1xuICAgIH1cbiAgICBpZiAoYXJndW1lbnQgPT09IHVuZGVmaW5lZCB8fCBhcmd1bWVudCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIFN0cmluZyhhcmd1bWVudCk7XG4gICAgfVxuICAgIGNvbnN0IGpzb24gPSBKU09OLnN0cmluZ2lmeShhcmd1bWVudCk7XG4gICAgcmV0dXJuIGpzb24gPz8gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZ3VtZW50KTtcbiAgfVxuICBmdW5jdGlvbiByZWNvcmRDb25zb2xlKC4uLmlucHV0OiB1bmtub3duW10pOiB2b2lkIHtcbiAgICBjYXB0dXJlZENvbnNvbGUucHVzaChpbnB1dC5tYXAoKGFyZ3VtZW50KSA9PiBmb3JtYXRBcmd1bWVudChhcmd1bWVudCkpLmpvaW4oJyAnKSk7XG4gIH1cbiAgY29uc3Qgb3JpZ0NvbnNvbGVFcnJvciA9IGNvbnNvbGUuZXJyb3I7XG4gIGNvbnN0IG9yaWdDb25zb2xlV2FybiA9IGNvbnNvbGUud2FybjtcbiAgZnVuY3Rpb24gb3VyQ29uc29sZUVycm9yKC4uLmlucHV0OiB1bmtub3duW10pOiB2b2lkIHtcbiAgICByZWNvcmRDb25zb2xlKC4uLmlucHV0KTtcbiAgICBvcmlnQ29uc29sZUVycm9yLmFwcGx5KGNvbnNvbGUsIGlucHV0KTtcbiAgfVxuICBmdW5jdGlvbiBvdXJDb25zb2xlV2FybiguLi5pbnB1dDogdW5rbm93bltdKTogdm9pZCB7XG4gICAgcmVjb3JkQ29uc29sZSguLi5pbnB1dCk7XG4gICAgb3JpZ0NvbnNvbGVXYXJuLmFwcGx5KGNvbnNvbGUsIGlucHV0KTtcbiAgfVxuICBjb25zb2xlLmVycm9yID0gb3VyQ29uc29sZUVycm9yO1xuICBjb25zb2xlLndhcm4gPSBvdXJDb25zb2xlV2FybjtcbiAgZnVuY3Rpb24gb25XaW5kb3dFcnJvcihldmVudDogRXJyb3JFdmVudCk6IHZvaWQge1xuICAgIGNhcHR1cmVkQ29uc29sZS5wdXNoKGV2ZW50LmVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBmb3JtYXRBcmd1bWVudChldmVudC5lcnJvcikgOiBldmVudC5tZXNzYWdlKTtcbiAgfVxuICBmdW5jdGlvbiBvblVuaGFuZGxlZFJlamVjdGlvbihldmVudDogUHJvbWlzZVJlamVjdGlvbkV2ZW50KTogdm9pZCB7XG4gICAgY2FwdHVyZWRDb25zb2xlLnB1c2goZm9ybWF0QXJndW1lbnQoZXZlbnQucmVhc29uKSk7XG4gIH1cbiAgZ2xvYmFsVGhpcy5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsIG9uV2luZG93RXJyb3IpO1xuICBnbG9iYWxUaGlzLmFkZEV2ZW50TGlzdGVuZXIoJ3VuaGFuZGxlZHJlamVjdGlvbicsIG9uVW5oYW5kbGVkUmVqZWN0aW9uKTtcblxuICB0cnkge1xuICAgIGF3YWl0IGFwcC5wbHVnaW5zLmVuYWJsZVBsdWdpbkFuZFNhdmUocGx1Z2luSWQpO1xuICB9IGZpbmFsbHkge1xuICAgIC8qXG4gICAgICogUmVzdG9yZSBPTkxZIHdoYXQgdGhpcyBmdW5jdGlvbiBpbnN0YWxsZWQuIFRoZSBwbHVnaW4gdW5kZXIgdGVzdCBsb2FkcyBJTlNJREUgdGhlIGB0cnlgIGFib3ZlLCBzbyBpdHNcbiAgICAgKiBgb25sb2FkYCBydW5zIGJlZm9yZSB0aGlzIGxpbmUgXHUyMDE0IGFuZCBhIHBsdWdpbiB0aGF0IG1vbmtleS1wYXRjaGVzIGFueSBvZiB0aGVzZSB0aHJlZSBzbG90cyB0aGVyZSB3cml0ZXNcbiAgICAgKiBhbiBvd24gcHJvcGVydHkgb3ZlciBvdXJzICh0aGUgc2hhcGUgYG1vbmtleS1hcm91bmRgIHByb2R1Y2VzKS4gQW4gdW5jb25kaXRpb25hbCByZXN0b3JlIHB1dHMgYmFjayB0aGVcbiAgICAgKiB2YWx1ZSByZWFkIGJlZm9yZSB0aGF0IHBsdWdpbiBleGlzdGVkLCBkZWxldGluZyBpdHMgcGF0Y2ggd2l0aCBubyBlcnJvciBhbmQgbm8gd2FybmluZzsgYGxvYWRQbHVnaW5gIGlzXG4gICAgICogdGhlIG9ubHkgY29tcGxldGUgc2VhbSBmb3Igb2JzZXJ2aW5nIGBhcHAucGx1Z2lucy5wbHVnaW5zYCBtb3ZlLCBzbyBhIHBsdWdpbiByZWFjaGluZyBmb3IgaXQgaXMgb3JkaW5hcnlcbiAgICAgKiByYXRoZXIgdGhhbiBleG90aWMuIFRoZSBndWFyZCBpcyBgbW9ua2V5LWFyb3VuZGAncyBvd24gdW5pbnN0YWxsZXIgZGlzY2lwbGluZSAoYGlmIChvYmpbbWV0aG9kXSA9PT1cbiAgICAgKiB3cmFwcGVyKWApOiB3aGVuIHNvbWVvbmUgcGF0Y2hlZCBvdmVyIHVzLCBsZWF2aW5nIHRoZSBjaGFpbiBhbG9uZSBpcyB0aGUgY29ycmVjdCBuby1vcCBcdTIwMTQgb3VyIHdyYXBwZXIgaXNcbiAgICAgKiBzdGlsbCBpbiBpdCwgb25lIGxldmVsIGRvd24sIGFuZCB1bndpbmRzIHdoZW4gdGhhdCBwbHVnaW4gdW5wYXRjaGVzLlxuICAgICAqL1xuICAgIGlmIChhcHAucGx1Z2lucy5sb2FkUGx1Z2luID09PSBvdXJMb2FkUGx1Z2luKSB7XG4gICAgICBhcHAucGx1Z2lucy5sb2FkUGx1Z2luID0gb3JpZ0xvYWRQbHVnaW47XG4gICAgfVxuICAgIGlmIChjb25zb2xlLmVycm9yID09PSBvdXJDb25zb2xlRXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IgPSBvcmlnQ29uc29sZUVycm9yO1xuICAgIH1cbiAgICBpZiAoY29uc29sZS53YXJuID09PSBvdXJDb25zb2xlV2Fybikge1xuICAgICAgY29uc29sZS53YXJuID0gb3JpZ0NvbnNvbGVXYXJuO1xuICAgIH1cbiAgICBnbG9iYWxUaGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgb25XaW5kb3dFcnJvcik7XG4gICAgZ2xvYmFsVGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCd1bmhhbmRsZWRyZWplY3Rpb24nLCBvblVuaGFuZGxlZFJlamVjdGlvbik7XG4gIH1cblxuICBjb25zdCBpc0xvYWRlZCA9IE9iamVjdC5oYXNPd24oYXBwLnBsdWdpbnMucGx1Z2lucywgcGx1Z2luSWQpO1xuXG4gIGxldCByZW5kZXJlckNvbnNvbGVFcnJvcnM6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgaWYgKCFlcnJvck1lc3NhZ2UgJiYgIWlzTG9hZGVkKSB7XG4gICAgY29uc3Qgam9pbmVkID0gY2FwdHVyZWRDb25zb2xlLmpvaW4oJ1xcbicpLnRyaW0oKTtcbiAgICByZW5kZXJlckNvbnNvbGVFcnJvcnMgPSBqb2luZWQgfHwgdW5kZWZpbmVkO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBlcnJvck1lc3NhZ2UsXG4gICAgaXNFbmFibGVkOiBhcHAucGx1Z2lucy5lbmFibGVkUGx1Z2lucy5oYXMocGx1Z2luSWQpLFxuICAgIGlzTG9hZGVkLFxuICAgIHJlbmRlcmVyQ29uc29sZUVycm9yc1xuICB9O1xufVxuXG4vKipcbiAqIFRoZSBnZW5lcmljIGxhc3QtcmVzb3J0IG1lc3NhZ2Ugc2hvd24gd2hlbiBhIHBsdWdpbiBpcyBpbiB0aGUgZW5hYmxlZCBzZXQgYnV0XG4gKiBub3QgbG9hZGVkIGFuZCBubyByZWFsIGVycm9yIGNvdWxkIGJlIGNhcHR1cmVkIChuZWl0aGVyIHRoZSBgbG9hZFBsdWdpbmBcbiAqIG1vbmtleS1wYXRjaCBub3IgdGhlIHJlbmRlcmVyIGNvbnNvbGUgbm9yLCBvbiBBbmRyb2lkLCBgYWRiIGxvZ2NhdGAgc3VyZmFjZWQgYVxuICogY2F1c2UpLlxuICpcbiAqIEhvc3Qtc2lkZSBoZWxwZXIgXHUyMDE0IHVzZWQgYnkgdGhlIHNldHVwIG9yY2hlc3RyYXRpb24gdG8gY29tcG9zZSB0aGUgZmluYWxcbiAqIGZhaWx1cmUgbWVzc2FnZSwgc28gdGhlIHJlbmRlcmVyLWluamVjdGVkIHtAbGluayBlbmFibGVQbHVnaW5XaXRoRXJyb3JDYXB0dXJlfVxuICogc3RheXMgc2VsZi1jb250YWluZWQuXG4gKlxuICogQHBhcmFtIHBsdWdpbklkIC0gVGhlIElEIG9mIHRoZSBwbHVnaW4gdGhhdCBmYWlsZWQgdG8gbG9hZC5cbiAqIEByZXR1cm5zIFRoZSBnZW5lcmljIGZhaWx1cmUgbWVzc2FnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEdlbmVyaWNQbHVnaW5Mb2FkRmFpbHVyZU1lc3NhZ2UocGx1Z2luSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgUGx1Z2luIFwiJHtwbHVnaW5JZH1cIiBpcyBpbiB0aGUgZW5hYmxlZCBzZXQgYnV0IG5vdCBsb2FkZWQuIGBcbiAgICArICdPYnNpZGlhbiBtYXkgaGF2ZSBjYXVnaHQgdGhlIGVycm9yIGJlZm9yZSB0aGUgbW9ua2V5LXBhdGNoLiAnXG4gICAgKyAnQ2hlY2sgdGhlIE9ic2lkaWFuIGNvbnNvbGUgZm9yIGRldGFpbHMuJztcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICJBQWlGQSxlQUFzQiw2QkFBNkIsRUFBRSxLQUFLLFNBQVMsR0FBc0U7QUFDdkksTUFBSSxDQUFDLElBQUksUUFBUSxVQUFVLEdBQUc7QUFDNUIsVUFBTSxJQUFJLFFBQVEsVUFBVSxJQUFJO0FBQUEsRUFDbEM7QUFTQSxNQUFJLElBQUksUUFBUSxlQUFlLElBQUksUUFBUSxLQUFLLENBQUMsT0FBTyxPQUFPLElBQUksUUFBUSxTQUFTLFFBQVEsR0FBRztBQUM3RixVQUFNLElBQUksUUFBUSxxQkFBcUIsUUFBUTtBQUFBLEVBQ2pEO0FBRUEsTUFBSTtBQUVKLFFBQU0saUJBQWlCLElBQUksUUFBUTtBQUNuQyxNQUFJLFFBQVEsYUFBYSxlQUFlLFdBQVcsSUFBWSxlQUEwQztBQUN2RyxRQUFJO0FBQ0YsWUFBTSxTQUFTLE1BQU0sZUFBZSxLQUFLLE1BQU0sSUFBSSxhQUFhO0FBQ2hFLHFCQUFlO0FBQ2YsYUFBTztBQUFBLElBQ1QsU0FBUyxPQUFPO0FBRWQsWUFBTSxTQUFTO0FBQ2YscUJBQWUsT0FBTyw4QkFBOEIsY0FBYyxLQUFLLEtBQUssT0FBTyxLQUFLO0FBQ3hGLFlBQU07QUFBQSxJQUNSO0FBQUEsRUFDRjtBQU1BLFFBQU0sZ0JBQWdCLElBQUksUUFBUTtBQVVsQyxRQUFNLGtCQUE0QixDQUFDO0FBRW5DLFFBQU0sZUFBZTtBQUNyQixXQUFTLGVBQWUsVUFBMkI7QUFDakQsUUFBSSxvQkFBb0IsT0FBTztBQUM3QixhQUFPLGFBQWEsOEJBQThCLGNBQWMsUUFBUSxLQUFLLE9BQU8sUUFBUTtBQUFBLElBQzlGO0FBQ0EsUUFBSSxPQUFPLGFBQWEsVUFBVTtBQUNoQyxhQUFPO0FBQUEsSUFDVDtBQUNBLFFBQUksYUFBYSxVQUFhLGFBQWEsTUFBTTtBQUMvQyxhQUFPLE9BQU8sUUFBUTtBQUFBLElBQ3hCO0FBQ0EsVUFBTSxPQUFPLEtBQUssVUFBVSxRQUFRO0FBQ3BDLFdBQU8sUUFBUSxPQUFPLFVBQVUsU0FBUyxLQUFLLFFBQVE7QUFBQSxFQUN4RDtBQUNBLFdBQVMsaUJBQWlCLE9BQXdCO0FBQ2hELG9CQUFnQixLQUFLLE1BQU0sSUFBSSxDQUFDLGFBQWEsZUFBZSxRQUFRLENBQUMsRUFBRSxLQUFLLEdBQUcsQ0FBQztBQUFBLEVBQ2xGO0FBQ0EsUUFBTSxtQkFBbUIsUUFBUTtBQUNqQyxRQUFNLGtCQUFrQixRQUFRO0FBQ2hDLFdBQVMsbUJBQW1CLE9BQXdCO0FBQ2xELGtCQUFjLEdBQUcsS0FBSztBQUN0QixxQkFBaUIsTUFBTSxTQUFTLEtBQUs7QUFBQSxFQUN2QztBQUNBLFdBQVMsa0JBQWtCLE9BQXdCO0FBQ2pELGtCQUFjLEdBQUcsS0FBSztBQUN0QixvQkFBZ0IsTUFBTSxTQUFTLEtBQUs7QUFBQSxFQUN0QztBQUNBLFVBQVEsUUFBUTtBQUNoQixVQUFRLE9BQU87QUFDZixXQUFTLGNBQWMsT0FBeUI7QUFDOUMsb0JBQWdCLEtBQUssTUFBTSxpQkFBaUIsUUFBUSxlQUFlLE1BQU0sS0FBSyxJQUFJLE1BQU0sT0FBTztBQUFBLEVBQ2pHO0FBQ0EsV0FBUyxxQkFBcUIsT0FBb0M7QUFDaEUsb0JBQWdCLEtBQUssZUFBZSxNQUFNLE1BQU0sQ0FBQztBQUFBLEVBQ25EO0FBQ0EsYUFBVyxpQkFBaUIsU0FBUyxhQUFhO0FBQ2xELGFBQVcsaUJBQWlCLHNCQUFzQixvQkFBb0I7QUFFdEUsTUFBSTtBQUNGLFVBQU0sSUFBSSxRQUFRLG9CQUFvQixRQUFRO0FBQUEsRUFDaEQsVUFBRTtBQVdBLFFBQUksSUFBSSxRQUFRLGVBQWUsZUFBZTtBQUM1QyxVQUFJLFFBQVEsYUFBYTtBQUFBLElBQzNCO0FBQ0EsUUFBSSxRQUFRLFVBQVUsaUJBQWlCO0FBQ3JDLGNBQVEsUUFBUTtBQUFBLElBQ2xCO0FBQ0EsUUFBSSxRQUFRLFNBQVMsZ0JBQWdCO0FBQ25DLGNBQVEsT0FBTztBQUFBLElBQ2pCO0FBQ0EsZUFBVyxvQkFBb0IsU0FBUyxhQUFhO0FBQ3JELGVBQVcsb0JBQW9CLHNCQUFzQixvQkFBb0I7QUFBQSxFQUMzRTtBQUVBLFFBQU0sV0FBVyxPQUFPLE9BQU8sSUFBSSxRQUFRLFNBQVMsUUFBUTtBQUU1RCxNQUFJO0FBQ0osTUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVU7QUFDOUIsVUFBTSxTQUFTLGdCQUFnQixLQUFLLElBQUksRUFBRSxLQUFLO0FBQy9DLDRCQUF3QixVQUFVO0FBQUEsRUFDcEM7QUFFQSxTQUFPO0FBQUEsSUFDTDtBQUFBLElBQ0EsV0FBVyxJQUFJLFFBQVEsZUFBZSxJQUFJLFFBQVE7QUFBQSxJQUNsRDtBQUFBLElBQ0E7QUFBQSxFQUNGO0FBQ0Y7QUFlTyxTQUFTLG1DQUFtQyxVQUEwQjtBQUMzRSxTQUFPLFdBQVcsUUFBUTtBQUc1QjsiLAogICJuYW1lcyI6IFtdCn0K
@@ -187,6 +187,18 @@ export interface Lib {
187
187
  * the renderer cannot produce a trusted event itself — so a missing `await`
188
188
  * would let the assertion run before the click landed.
189
189
  *
190
+ * **On mobile it waits for the element to stop moving, and refuses a covered
191
+ * one.** The tap reaches the page about a second after its point is read,
192
+ * and Obsidian Mobile slides a modal in with a `transform` transition that
193
+ * can hold for over a second, so a point read too early is where the
194
+ * control *used to be*. So the mobile path first waits (up to 5 s) until no finite
195
+ * animation or transition runs on the element or any ancestor and its box
196
+ * has held across two reads, then checks with `elementFromPoint` that the
197
+ * center belongs to the element. It throws a named error in either case
198
+ * rather than tapping, because a trusted tap goes to whatever is on top and
199
+ * would otherwise land on it silently. Use {@link Lib.clickMouse} to tap a
200
+ * point deliberately, covered or not. Desktop is unchanged.
201
+ *
190
202
  * @param params - The element to click, the button to press and any modifiers
191
203
  * to hold.
192
204
  * @returns A {@link Promise} that resolves once the click has been injected.