obsidian-integration-testing 10.4.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +1 -1
  2. package/dist/lib/cjs/appium-server-marker.cjs +115 -0
  3. package/dist/lib/cjs/appium-server-marker.d.cts +81 -0
  4. package/dist/lib/cjs/cli.cjs +104 -19
  5. package/dist/lib/cjs/cli.d.cts +16 -8
  6. package/dist/lib/cjs/community-plugin-registry.cjs +52 -0
  7. package/dist/lib/cjs/community-plugin-registry.d.cts +116 -0
  8. package/dist/lib/cjs/context-provider.cjs +12 -1
  9. package/dist/lib/cjs/context-provider.d.cts +26 -3
  10. package/dist/lib/cjs/demo-vault-bootstrap.cjs +148 -0
  11. package/dist/lib/cjs/demo-vault-bootstrap.d.cts +113 -0
  12. package/dist/lib/cjs/demo-vault-populate.cjs +36 -9
  13. package/dist/lib/cjs/demo-vault-populate.d.cts +70 -0
  14. package/dist/lib/cjs/eval-in-obsidian.cjs +1 -1
  15. package/dist/lib/cjs/eval-in-obsidian.d.cts +97 -15
  16. package/dist/lib/cjs/index.cjs +16 -1
  17. package/dist/lib/cjs/index.d.cts +15 -8
  18. package/dist/lib/cjs/installer-asset.cjs +1 -1
  19. package/dist/lib/cjs/installer-asset.d.cts +1 -1
  20. package/dist/lib/cjs/integration-setup-failed-error.cjs +62 -0
  21. package/dist/lib/cjs/integration-setup-failed-error.d.cts +66 -0
  22. package/dist/lib/cjs/jest/global-setup.cjs +2 -2
  23. package/dist/lib/cjs/jest/global-setup.d.cts +5 -1
  24. package/dist/lib/cjs/kill-process-tree.cjs +18 -7
  25. package/dist/lib/cjs/kill-process-tree.d.cts +10 -2
  26. package/dist/lib/cjs/library.cjs +1 -1
  27. package/dist/lib/cjs/mobile-input.cjs +161 -0
  28. package/dist/lib/cjs/mobile-input.d.cts +160 -0
  29. package/dist/lib/cjs/namespace-bootstrap.cjs +136 -10
  30. package/dist/lib/cjs/obsidian-installer.cjs +1 -1
  31. package/dist/lib/cjs/obsidian-metadata.cjs +1257 -348
  32. package/dist/lib/cjs/obsidian-metadata.d.cts +74 -12
  33. package/dist/lib/cjs/obsidian-version-switch.cjs +3 -3
  34. package/dist/lib/cjs/open-obsidian-settings-tab.cjs +51 -0
  35. package/dist/lib/cjs/open-obsidian-settings-tab.d.cts +49 -0
  36. package/dist/lib/cjs/release-catalog.cjs +73 -0
  37. package/dist/lib/cjs/release-catalog.d.cts +125 -0
  38. package/dist/lib/cjs/transport-appium.cjs +122 -1
  39. package/dist/lib/cjs/transport-appium.d.cts +51 -0
  40. package/dist/lib/cjs/transport-desktop-cdp.cjs +7 -1
  41. package/dist/lib/cjs/transport-desktop-cdp.d.cts +2 -2
  42. package/dist/lib/cjs/transport-factory.cjs +237 -32
  43. package/dist/lib/cjs/transport-factory.d.cts +10 -1
  44. package/dist/lib/cjs/vitest/global-setup.cjs +13 -7
  45. package/dist/lib/cjs/vitest/global-setup.d.cts +5 -1
  46. package/dist/lib/cjs/vitest/setup.cjs +2 -1
  47. package/dist/lib/cjs/vitest/setup.d.cts +5 -0
  48. package/dist/lib/cjs/vitest/typings.d.cts +6 -4
  49. package/dist/lib/cjs/webview-cdp.cjs +264 -0
  50. package/dist/lib/cjs/webview-cdp.d.cts +152 -0
  51. package/dist/lib/cjs/wedged-appium-server.cjs +113 -0
  52. package/dist/lib/cjs/wedged-appium-server.d.cts +187 -0
  53. package/dist/lib/esm/appium-server-marker.d.mts +81 -0
  54. package/dist/lib/esm/appium-server-marker.mjs +83 -0
  55. package/dist/lib/esm/cli.d.mts +16 -8
  56. package/dist/lib/esm/cli.mjs +110 -19
  57. package/dist/lib/esm/community-plugin-registry.d.mts +116 -0
  58. package/dist/lib/esm/community-plugin-registry.mjs +23 -0
  59. package/dist/lib/esm/context-provider.d.mts +26 -3
  60. package/dist/lib/esm/context-provider.mjs +10 -1
  61. package/dist/lib/esm/demo-vault-bootstrap.d.mts +113 -0
  62. package/dist/lib/esm/demo-vault-bootstrap.mjs +127 -0
  63. package/dist/lib/esm/demo-vault-populate.d.mts +70 -0
  64. package/dist/lib/esm/demo-vault-populate.mjs +33 -8
  65. package/dist/lib/esm/eval-in-obsidian.d.mts +97 -15
  66. package/dist/lib/esm/eval-in-obsidian.mjs +1 -1
  67. package/dist/lib/esm/index.d.mts +15 -8
  68. package/dist/lib/esm/index.mjs +18 -2
  69. package/dist/lib/esm/installer-asset.d.mts +1 -1
  70. package/dist/lib/esm/installer-asset.mjs +1 -1
  71. package/dist/lib/esm/integration-setup-failed-error.d.mts +66 -0
  72. package/dist/lib/esm/integration-setup-failed-error.mjs +38 -0
  73. package/dist/lib/esm/jest/global-setup.d.mts +5 -1
  74. package/dist/lib/esm/jest/global-setup.mjs +2 -2
  75. package/dist/lib/esm/kill-process-tree.d.mts +10 -2
  76. package/dist/lib/esm/kill-process-tree.mjs +16 -6
  77. package/dist/lib/esm/library.mjs +1 -1
  78. package/dist/lib/esm/mobile-input.d.mts +160 -0
  79. package/dist/lib/esm/mobile-input.mjs +132 -0
  80. package/dist/lib/esm/namespace-bootstrap.mjs +139 -10
  81. package/dist/lib/esm/obsidian-installer.mjs +1 -1
  82. package/dist/lib/esm/obsidian-metadata.d.mts +74 -12
  83. package/dist/lib/esm/obsidian-metadata.mjs +1257 -348
  84. package/dist/lib/esm/obsidian-version-switch.mjs +3 -3
  85. package/dist/lib/esm/open-obsidian-settings-tab.d.mts +49 -0
  86. package/dist/lib/esm/open-obsidian-settings-tab.mjs +27 -0
  87. package/dist/lib/esm/release-catalog.d.mts +125 -0
  88. package/dist/lib/esm/release-catalog.mjs +46 -0
  89. package/dist/lib/esm/transport-appium.d.mts +51 -0
  90. package/dist/lib/esm/transport-appium.mjs +126 -1
  91. package/dist/lib/esm/transport-desktop-cdp.d.mts +2 -2
  92. package/dist/lib/esm/transport-desktop-cdp.mjs +7 -1
  93. package/dist/lib/esm/transport-factory.d.mts +10 -1
  94. package/dist/lib/esm/transport-factory.mjs +249 -35
  95. package/dist/lib/esm/vitest/global-setup.d.mts +5 -1
  96. package/dist/lib/esm/vitest/global-setup.mjs +14 -7
  97. package/dist/lib/esm/vitest/setup.d.mts +5 -0
  98. package/dist/lib/esm/vitest/setup.mjs +3 -1
  99. package/dist/lib/esm/vitest/typings.d.mts +6 -4
  100. package/dist/lib/esm/webview-cdp.d.mts +152 -0
  101. package/dist/lib/esm/webview-cdp.mjs +236 -0
  102. package/dist/lib/esm/wedged-appium-server.d.mts +187 -0
  103. package/dist/lib/esm/wedged-appium-server.mjs +86 -0
  104. package/package.json +13 -12
@@ -27,9 +27,12 @@ var import_promises = require("node:fs/promises");
27
27
  var import_node_os = require("node:os");
28
28
  var import_node_path = require("node:path");
29
29
  var import_capture_screenshot = require("./capture-screenshot.cjs");
30
+ var import_error_to_string = require("./error-to-string.cjs");
30
31
  var import_exec = require("./exec.cjs");
31
32
  var import_leftover_cleanup = require("./leftover-cleanup.cjs");
32
33
  var import_log = require("./log.cjs");
34
+ var import_mobile_input = require("./mobile-input.cjs");
35
+ var import_webview_cdp = require("./webview-cdp.cjs");
33
36
  const NO_OUTPUT = "(no output)";
34
37
  const APP_STATE_FOREGROUND = 4;
35
38
  const WEBVIEW_CONTEXT_PREFIX = "WEBVIEW_md.obsidian";
@@ -58,6 +61,20 @@ class AppiumTransport {
58
61
  appId;
59
62
  browser;
60
63
  deviceId;
64
+ /**
65
+ * The `process.on('exit')` handler that tears the channel down when nothing else will.
66
+ */
67
+ disposeInputChannelOnExit = null;
68
+ /**
69
+ * The host half of the trusted-input channel: a CDP connection to the WebView, independent of the
70
+ * Appium session, opened lazily on first evaluate and reused (see **L39**).
71
+ */
72
+ inputChannel = null;
73
+ /**
74
+ * Set once the trusted-input channel is known not to be openable here (iOS, a remote hub, no local
75
+ * `adb`), so the attempt is not repeated on every evaluate.
76
+ */
77
+ isInputChannelUnavailable = false;
61
78
  /**
62
79
  * Tracks whether the driver is currently switched to the WebView context.
63
80
  *
@@ -139,10 +156,24 @@ class AppiumTransport {
139
156
  * deletion so the session remains available for the owning process.
140
157
  */
141
158
  async dispose() {
159
+ await this.disposeInputChannel();
142
160
  if (this.isSessionOwner) {
143
161
  await this.browser.deleteSession();
144
162
  }
145
163
  }
164
+ /**
165
+ * Synchronous teardown for `process.on('exit')` handlers.
166
+ *
167
+ * Only the trusted-input channel needs it: the Appium session is the owning process's to end, and an
168
+ * abrupt exit is exactly when the async {@link AppiumTransport.dispose} never runs — which would strand
169
+ * the adb port forward on the device.
170
+ */
171
+ disposeSync() {
172
+ const channel = this.inputChannel;
173
+ this.inputChannel = null;
174
+ this.unregisterInputChannelExitHandler();
175
+ channel?.disposeSync();
176
+ }
146
177
  /**
147
178
  * Evaluates a JavaScript expression inside Obsidian Mobile's WebView.
148
179
  *
@@ -155,6 +186,7 @@ class AppiumTransport {
155
186
  */
156
187
  async evaluate(expression, _options) {
157
188
  await this.ensureWebViewContext();
189
+ await this.ensureInputChannel();
158
190
  try {
159
191
  const result = await this.browser.execute(
160
192
  `return (${expression})`
@@ -347,6 +379,55 @@ class AppiumTransport {
347
379
  }
348
380
  await this.removeDeviceVaultDirectory(deviceVaultPath);
349
381
  }
382
+ /**
383
+ * Closes the trusted-input channel, if one is open.
384
+ */
385
+ async disposeInputChannel() {
386
+ const channel = this.inputChannel;
387
+ this.inputChannel = null;
388
+ this.unregisterInputChannelExitHandler();
389
+ await channel?.dispose();
390
+ }
391
+ /**
392
+ * Opens the trusted-input channel if it is not already open, and re-opens it if the WebView went away.
393
+ *
394
+ * Installs a `Runtime.addBinding` function on the page and services every call to it for the life of the
395
+ * connection. The binding is exposed on *every* execution context of the page, so it survives the
396
+ * `location.reload()` that {@link AppiumTransport.registerVault} performs; only a full app restart, which
397
+ * destroys the WebView target, needs the reconnect below.
398
+ */
399
+ async ensureInputChannel() {
400
+ if (this.inputChannel?.isOpen || this.isInputChannelUnavailable) {
401
+ return;
402
+ }
403
+ if (this.platform !== "android") {
404
+ this.isInputChannelUnavailable = true;
405
+ return;
406
+ }
407
+ await this.disposeInputChannel();
408
+ try {
409
+ const connection = await (0, import_webview_cdp.connectToWebViewCdp)({ appId: this.appId, deviceId: this.deviceId });
410
+ await connection.send("Runtime.enable");
411
+ await connection.send("Runtime.addBinding", { name: import_mobile_input.MOBILE_INPUT_BINDING_NAME });
412
+ connection.on("Runtime.bindingCalled", (params) => {
413
+ if (params["name"] !== import_mobile_input.MOBILE_INPUT_BINDING_NAME) {
414
+ return;
415
+ }
416
+ const payload = params["payload"];
417
+ this.handleInputRequest(connection, typeof payload === "string" ? payload : "").catch(() => {
418
+ });
419
+ });
420
+ this.inputChannel = connection;
421
+ this.disposeInputChannelOnExit = () => {
422
+ connection.disposeSync();
423
+ };
424
+ process.once("exit", this.disposeInputChannelOnExit);
425
+ (0, import_log.log)("[appium-transport] Trusted-input channel open.");
426
+ } catch (error) {
427
+ this.isInputChannelUnavailable = true;
428
+ (0, import_log.log)(`[appium-transport] Trusted input is unavailable on this device: ${(0, import_error_to_string.errorToString)(error)}`);
429
+ }
430
+ }
350
431
  /**
351
432
  * Switches the driver to the `WEBVIEW_md.obsidian` context.
352
433
  *
@@ -396,6 +477,35 @@ class AppiumTransport {
396
477
  getDeviceVaultPath(vaultPath) {
397
478
  return `${this.vaultBasePath}${extractVaultName(vaultPath)}`;
398
479
  }
480
+ /**
481
+ * Services one input request from the renderer: inject, then resolve the renderer's promise.
482
+ *
483
+ * Every failure path still resolves that promise — with an error message the renderer re-throws — because
484
+ * a request that is silently dropped would hang the closure until the whole run times out, and report
485
+ * nothing about why.
486
+ *
487
+ * @param connection - The channel the request arrived on.
488
+ * @param payload - The raw JSON payload the binding was called with.
489
+ */
490
+ async handleInputRequest(connection, payload) {
491
+ let requestId = "";
492
+ try {
493
+ const { id, request } = JSON.parse(payload);
494
+ requestId = id;
495
+ await connection.sendAll((0, import_mobile_input.toCdpInputCommands)(request));
496
+ await connection.send("Runtime.evaluate", { expression: (0, import_mobile_input.buildResolveInputExpression)(id) });
497
+ } catch (error) {
498
+ const message = (0, import_error_to_string.errorToString)(error);
499
+ (0, import_log.log)(`[appium-transport] Trusted input failed: ${message}`);
500
+ if (!requestId) {
501
+ return;
502
+ }
503
+ try {
504
+ await connection.send("Runtime.evaluate", { expression: (0, import_mobile_input.buildResolveInputExpression)(requestId, message) });
505
+ } catch {
506
+ }
507
+ }
508
+ }
399
509
  /**
400
510
  * Pushes the minimal `.obsidian/app.json` vault marker via `adb push`.
401
511
  *
@@ -453,6 +563,17 @@ class AppiumTransport {
453
563
  (0, import_log.log)(`[appium-transport] Vault directory removal failed (non-fatal): ${String(error)}`);
454
564
  }
455
565
  }
566
+ /**
567
+ * Drops the `process.on('exit')` handler that would otherwise close an already-closed channel, and would
568
+ * stack a listener per reconnect.
569
+ */
570
+ unregisterInputChannelExitHandler() {
571
+ if (!this.disposeInputChannelOnExit) {
572
+ return;
573
+ }
574
+ process.off("exit", this.disposeInputChannelOnExit);
575
+ this.disposeInputChannelOnExit = null;
576
+ }
456
577
  /**
457
578
  * Polls until `app.workspace.layoutReady` is `true` in the WebView.
458
579
  */
@@ -494,4 +615,4 @@ function extractVaultName(vaultPath) {
494
615
  AppiumTransport,
495
616
  DEFAULT_ANDROID_VAULT_BASE_PATH
496
617
  });
497
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RyYW5zcG9ydC1hcHBpdW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBBcHBpdW0gdHJhbnNwb3J0IFx1MjAxNCBldmFsdWF0ZXMgZXhwcmVzc2lvbnMgaW5zaWRlIE9ic2lkaWFuIE1vYmlsZSB2aWEgV2ViVmlld1xuICogSmF2YVNjcmlwdCBpbmplY3Rpb24uIE1hbmFnZXMgdmF1bHQgbGlmZWN5Y2xlIHZpYSBsb2NhbFN0b3JhZ2UgYW5kIGZpbGUgcHVzaC5cbiAqXG4gKiBDb25maWd1cmVkIHZpYSBgZW52aXJvbm1lbnRPcHRpb25zLm9ic2lkaWFuVHJhbnNwb3J0YCBpbiB2aXRlc3QgY29uZmlnOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIHZpdGVzdC5jb25maWcudHNcbiAqIGVudmlyb25tZW50T3B0aW9uczoge1xuICogICBvYnNpZGlhblRyYW5zcG9ydDoge1xuICogICAgIHR5cGU6ICdvYnNpZGlhbi1hbmRyb2lkLWFwcGl1bScsXG4gKiAgICAgYXBwaXVtVXJsOiAnaHR0cDovL2xvY2FsaG9zdDo0NzIzJyxcbiAqICAgICBhdmROYW1lOiAnb2JzaWRpYW5fdGVzdCcsXG4gKiAgIH0sXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBGb3IgQnJvd3NlclN0YWNrLCBzZXQgYGFwcGl1bVVybGAgdG8gdGhlIEJyb3dzZXJTdGFjayBodWIgVVJMXG4gKiBcdTIwMTQgdGhlIHRyYW5zcG9ydCBpdHNlbGYgaXMgaHViLWFnbm9zdGljLlxuICpcbiAqICMjIEhvdyB2YXVsdCByZWdpc3RyYXRpb24gd29ya3Mgb24gbW9iaWxlXG4gKlxuICogT2JzaWRpYW4gTW9iaWxlIHN0b3JlcyBpdHMgdmF1bHQgcmVnaXN0cnkgaW4gdGhlIFdlYlZpZXcncyBgbG9jYWxTdG9yYWdlYDpcbiAqXG4gKiAtIGBtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzYCBcdTIwMTQgSlNPTiBhcnJheSBvZiByZWdpc3RlcmVkIHZhdWx0IHBhdGhzXG4gKiAtIGBtb2JpbGUtc2VsZWN0ZWQtdmF1bHRgIFx1MjAxNCB0aGUgY3VycmVudGx5IGFjdGl2ZSB2YXVsdCBwYXRoXG4gKiAtIGBlbmFibGUtcGx1Z2luLTx2YXVsdFBhdGg+YCBcdTIwMTQgYFwidHJ1ZVwiYCB0byBlbmFibGUgdGhlIHBsdWdpbiBzeXN0ZW0gZm9yIHRoZSB2YXVsdFxuICpcbiAqIFRvIHJlZ2lzdGVyIGEgdmF1bHQgcHJvZ3JhbW1hdGljYWxseSAod2l0aG91dCBVSSBpbnRlcmFjdGlvbik6XG4gKlxuICogMS4gUHVzaCB2YXVsdCBmaWxlcyB0byB0aGUgZGV2aWNlIChlLmcuIGAvc2RjYXJkL0RvY3VtZW50cy88TmFtZT4vLm9ic2lkaWFuL2FwcC5qc29uYClcbiAqIDIuIFN3aXRjaCB0byBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dFxuICogMy4gU2V0IHRoZSBsb2NhbFN0b3JhZ2UgZW50cmllc1xuICogNC4gQ2FsbCBgbG9jYXRpb24ucmVsb2FkKClgIFx1MjAxNCBPYnNpZGlhbiByZS1yZWFkcyBsb2NhbFN0b3JhZ2UgYW5kIG9wZW5zIHRoZSB2YXVsdFxuICpcbiAqIFRoaXMgYXZvaWRzIHRoZSBvbmJvYXJkaW5nIGZsb3cgZW50aXJlbHkuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgY29kZSBjb3ZlcmVkIGJ5IGludGVncmF0aW9uIHRlc3RzLCBub3QgdW5pdCB0ZXN0cy4gKi9cblxuaW1wb3J0IHR5cGUgeyBCcm93c2VyIH0gZnJvbSAnd2ViZHJpdmVyaW8nO1xuXG5pbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHtcbiAgcm0sXG4gIHdyaXRlRmlsZVxufSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB0eXBlIHsgQ2FwdHVyZVNjcmVlbnNob3RQYXJhbXMgfSBmcm9tICcuL2NhcHR1cmUtc2NyZWVuc2hvdC5janMnO1xuaW1wb3J0IHR5cGUge1xuICBDb25zb2xlQ2FwdHVyZUhhbmRsZSxcbiAgT2JzaWRpYW5UcmFuc3BvcnQsXG4gIFRyYW5zcG9ydEV2YWxPcHRpb25zXG59IGZyb20gJy4vdHJhbnNwb3J0LmNqcyc7XG5cbmltcG9ydCB7XG4gIGRlY29kZUJhc2U2NFBuZyxcbiAgaXNQbmdcbn0gZnJvbSAnLi9jYXB0dXJlLXNjcmVlbnNob3QuY2pzJztcbmltcG9ydCB7IGV4ZWMgfSBmcm9tICcuL2V4ZWMuY2pzJztcbmltcG9ydCB7IFRFTVBfVkFVTFRfRElSX1BSRUZJWCB9IGZyb20gJy4vbGVmdG92ZXItY2xlYW51cC5janMnO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSAnLi9sb2cuY2pzJztcblxuLyoqXG4gKiBTZXNzaW9uIGNvbm5lY3Rpb24gaW5mbyByZXR1cm5lZCBieSB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0LmdldFNlc3Npb25JbmZvfSxcbiAqIHVzZWQgdG8gcmVhdHRhY2ggZnJvbSBhbm90aGVyIHByb2Nlc3MuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXBwaXVtU2Vzc2lvbkluZm8ge1xuICAvKipcbiAgVGhlIGRldmljZSBVRElEIChlLmcuIGAnZW11bGF0b3ItNTU1NCdgKS5cbiAgICovXG4gIGRldmljZUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBBcHBpdW0vV2ViRHJpdmVyIHNlc3Npb24gSUQuXG4gICAqL1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciB0aGUgQXBwaXVtIHRyYW5zcG9ydC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcHBpdW1UcmFuc3BvcnRDb25maWcge1xuICAvKipcbiAgICogQXBwIHBhY2thZ2UgKEFuZHJvaWQpIG9yIGJ1bmRsZSBJRCAoaU9TKS5cbiAgICogRGVmYXVsdHMgdG8gYCdtZC5vYnNpZGlhbidgLlxuICAgKi9cbiAgYXBwSWQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBBcHBpdW0gYnJvd3Nlci9kcml2ZXIgaW5zdGFuY2UuXG4gICAqIENyZWF0ZWQgYnkgdGhlIGNvbnN1bWVyIHZpYSBlLmcuIFdlYkRyaXZlcklPJ3MgYHJlbW90ZSgpYC5cbiAgICovXG4gIGJyb3dzZXI6IEJyb3dzZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBkZXZpY2UgVURJRCAoZS5nLiBgJ2VtdWxhdG9yLTU1NTQnYCkuXG4gICAqIFVzZWQgZm9yIGBhZGJgIGNvbW1hbmRzIHdoZW4gcHVzaGluZyBmaWxlcyB0byB0aGUgZGV2aWNlLlxuICAgKi9cbiAgZGV2aWNlSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB0aGlzIHRyYW5zcG9ydCBvd25zIHRoZSBBcHBpdW0gc2Vzc2lvbiBhbmQgc2hvdWxkIGRlbGV0ZSBpdCBvblxuICAgKiB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0LmRpc3Bvc2V9LlxuICAgKlxuICAgKiBgdHJ1ZWAgZm9yIHNlc3Npb25zIGNyZWF0ZWQgdmlhIGByZW1vdGUoKWAgKGdsb2JhbCBzZXR1cCkuXG4gICAqIGBmYWxzZWAgZm9yIHNlc3Npb25zIHJlYXR0YWNoZWQgdmlhIGBhdHRhY2goKWAgKHRlc3Qgd29ya2VycykuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB0cnVlYFxuICAgKi9cbiAgaXNTZXNzaW9uT3duZXI/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaW1lb3V0IGluIG1pbGxpc2Vjb25kcyBmb3Igd2FpdGluZyBmb3IgYGFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHlgIGFmdGVyXG4gICAqIHRoZSB2YXVsdCBpcyAocmUpb3BlbmVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgOTAwMDBgXG4gICAqL1xuICBsYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcblxuICAvKipcbiAgICogVGFyZ2V0IHBsYXRmb3JtLiBEZXRlcm1pbmVzIFdlYlZpZXcgY29udGV4dCBuYW1pbmcgYW5kIGRldmljZSBmaWxlIHBhdGhzLlxuICAgKi9cbiAgcGxhdGZvcm06ICdhbmRyb2lkJyB8ICdpb3MnO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHJlZ2lzdGVyaW5nIGEgdmF1bHQgYWxzbyBwcnVuZXMgdGhlICoqb3RoZXIqKiBgdGVtcC12YXVsdC0qYFxuICAgKiByZWdpc3RyYXRpb25zIGVhcmxpZXIgcnVucyBsZWZ0IGluIE9ic2lkaWFuIE1vYmlsZSdzIGBsb2NhbFN0b3JhZ2VgLlxuICAgKlxuICAgKiBUaGUgZGV2aWNlLXNpZGUgZGlyZWN0b3JpZXMgYXJlIHN3ZXB0IGJlZm9yZSB0aGUgYXBwIGxhdW5jaGVzIChzZWUgdGhlXG4gICAqIGZhY3RvcnkpOyB0aGlzIHJlbW92ZXMgdGhlaXIgbm93LWRhbmdsaW5nIHJlZ2lzdHJ5IGVudHJpZXMsIHdoaWNoIGFyZSB3aGF0XG4gICAqIE9ic2lkaWFuIGFjdHVhbGx5IGVudW1lcmF0ZXMgYXQgc3RhcnR1cC4gVW5yZWdpc3RlcmluZyB0aGlzIHJ1bidzIG93biB2YXVsdFxuICAgKiBpcyB1bmFmZmVjdGVkIFx1MjAxNCB0aGF0IGFsd2F5cyBoYXBwZW5zLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgdHJ1ZWBcbiAgICovXG4gIHNob3VsZFN3ZWVwTGVmdG92ZXJzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQmFzZSBwYXRoIG9uIHRoZSBkZXZpY2Ugd2hlcmUgT2JzaWRpYW4gc3RvcmVzIHZhdWx0cy5cbiAgICpcbiAgICogRGVmYXVsdHM6XG4gICAqIC0gQW5kcm9pZDogYC9zZGNhcmQvRG9jdW1lbnRzL2BcbiAgICogLSBpT1M6IGBAbWQub2JzaWRpYW46ZG9jdW1lbnRzL2BcbiAgICovXG4gIHZhdWx0QmFzZVBhdGg/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciB3YWl0aW5nIGZvciB0aGUgV2ViVmlldyBjb250ZXh0IHRvIGJlY29tZSBhdmFpbGFibGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IGA2MDAwMGBcbiAgICovXG4gIHdlYnZpZXdUaW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG59XG5cbmNvbnN0IE5PX09VVFBVVCA9ICcobm8gb3V0cHV0KSc7XG5jb25zdCBBUFBfU1RBVEVfRk9SRUdST1VORCA9IDQ7XG5jb25zdCBXRUJWSUVXX0NPTlRFWFRfUFJFRklYID0gJ1dFQlZJRVdfbWQub2JzaWRpYW4nO1xuY29uc3QgV0VCVklFV19QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IERFRkFVTFRfV0VCVklFV19QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNjBfMDAwO1xuY29uc3QgTEFZT1VUX1JFQURZX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuY29uc3QgREVGQVVMVF9MQVlPVVRfUkVBRFlfUE9MTF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDkwXzAwMDtcbmNvbnN0IEFQUF9SRVNUQVJUX0RFTEFZX0lOX01JTExJU0VDT05EUyA9IDIwMDA7XG5jb25zdCBERUZBVUxUX0FQUF9JRCA9ICdtZC5vYnNpZGlhbic7XG5jb25zdCBBREJfVkFVTFRfUkVNT1ZFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMzBfMDAwO1xuXG4vLyAtLS0gQ29uc29sZSBjYXB0dXJlIChMYXllciAyIG9mIHRoZSBwbHVnaW4tbG9hZCBlcnJvciBzdXJmYWNpbmcsIHNlZSBUODgpIC0tLVxuY29uc3QgQ09OU09MRV9DQVBUVVJFX01BUktFUl9UQUcgPSAnT0lUX0NBUFRVUkUnO1xuY29uc3QgQ09OU09MRV9DQVBUVVJFX1RBSUxfTUFYX0xFTkdUSCA9IDgwMDA7XG5jb25zdCBBREJfTE9HX01BUktFUl9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDUwMDA7XG5jb25zdCBMT0dDQVRfRFVNUF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDEwXzAwMDtcbi8qKlxuICogYGFkYiBsb2djYXQgLXYgdGltZWAgbGluZXMgbG9vayBsaWtlIGBNTS1ERCBISDpNTTpTUy5tbW0gTEVWRUwvVEFHKCBQSUQpOiBtZXNzYWdlYC5cbiAqIEtlZXAgb25seSB0aGUgdGFncyBDaHJvbWl1bS9XZWJWaWV3IHJvdXRlcyBKUyBgY29uc29sZS4qYCBvdXRwdXQgYW5kIHVuY2F1Z2h0XG4gKiBlcnJvcnMgdG8gKGBjaHJvbWl1bWAsIHRoZSBDYXBhY2l0b3IgY29uc29sZSBicmlkZ2UsIGFuZCBuYXRpdmUgYEFuZHJvaWRSdW50aW1lYCkuXG4gKi9cbmNvbnN0IENPTlNPTEVfQ0FQVFVSRV9UQUdfUkUgPSAvXFwvKD86Y2hyb21pdW18QW5kcm9pZFJ1bnRpbWV8Q2FwYWNpdG9yXFwvQ29uc29sZSlcXCgvO1xuXG4vKipcbiAqIEJhc2UgcGF0aCBvbiBhbiBBbmRyb2lkIGRldmljZSB3aGVyZSBPYnNpZGlhbiBNb2JpbGUgc3RvcmVzIGl0cyB2YXVsdHMuXG4gKlxuICogRXhwb3J0ZWQgYmVjYXVzZSB0aGUgdHJhbnNwb3J0IGZhY3Rvcnkgc3dlZXBzIGxlZnRvdmVyIHZhdWx0cyBmcm9tIGl0IGJlZm9yZVxuICogYSB0cmFuc3BvcnQgZXhpc3RzIChzZWUgdGhlIHJlcG8ncyBMMzEpLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9BTkRST0lEX1ZBVUxUX0JBU0VfUEFUSCA9ICcvc2RjYXJkL0RvY3VtZW50cy8nO1xuXG5jb25zdCBERUZBVUxUX1ZBVUxUX0JBU0VfUEFUSDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgYW5kcm9pZDogREVGQVVMVF9BTkRST0lEX1ZBVUxUX0JBU0VfUEFUSCxcbiAgaW9zOiAnQG1kLm9ic2lkaWFuOmRvY3VtZW50cy8nXG59O1xuXG5pbnRlcmZhY2UgTG9hZGluZ0FwcCB7XG4gIHdvcmtzcGFjZT86IExvYWRpbmdXb3Jrc3BhY2U7XG59XG5cbmludGVyZmFjZSBMb2FkaW5nV29ya3NwYWNlIHtcbiAgbGF5b3V0UmVhZHk/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFRyYW5zcG9ydCB0aGF0IGNvbW11bmljYXRlcyB3aXRoIE9ic2lkaWFuIE1vYmlsZSB2aWEgQXBwaXVtIFdlYlZpZXcgSlMgaW5qZWN0aW9uLlxuICpcbiAqIEV2YWx1YXRlcyBleHByZXNzaW9ucyBieSBzd2l0Y2hpbmcgdG8gdGhlIGBXRUJWSUVXX21kLm9ic2lkaWFuYCBjb250ZXh0IGFuZFxuICogY2FsbGluZyBgZXhlY3V0ZSgpYC4gTWFuYWdlcyB2YXVsdHMgYnkgd3JpdGluZyB0byB0aGUgV2ViVmlldydzIGBsb2NhbFN0b3JhZ2VgXG4gKiAod2hpY2ggT2JzaWRpYW4gdXNlcyBhcyBpdHMgdmF1bHQgcmVnaXN0cnkgb24gbW9iaWxlKSBhbmQgcHVzaGluZyBmaWxlcyB0byB0aGUgZGV2aWNlLlxuICovXG5leHBvcnQgY2xhc3MgQXBwaXVtVHJhbnNwb3J0IGltcGxlbWVudHMgT2JzaWRpYW5UcmFuc3BvcnQge1xuICAvKipcbiAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyB0cmFuc3BvcnQgaXMgZm9yIGEgbW9iaWxlIHBsYXRmb3JtLiBBbHdheXMgYHRydWVgIGZvciB0aGlzIHRyYW5zcG9ydC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpc01vYmlsZSA9IHRydWU7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXBwSWQ6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBicm93c2VyOiBCcm93c2VyO1xuICBwcml2YXRlIHJlYWRvbmx5IGRldmljZUlkOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUcmFja3Mgd2hldGhlciB0aGUgZHJpdmVyIGlzIGN1cnJlbnRseSBzd2l0Y2hlZCB0byB0aGUgV2ViVmlldyBjb250ZXh0LlxuICAgKlxuICAgKiBTZXQgdG8gYHRydWVgIGFmdGVyIGEgc3VjY2Vzc2Z1bCBgc3dpdGNoQ29udGV4dChXRUJWSUVXX21kLm9ic2lkaWFuKWAuXG4gICAqIFJlc2V0IHRvIGBmYWxzZWAgd2hlbiB0aGUgY29udGV4dCBpcyBrbm93biB0byBiZSBpbnZhbGlkYXRlZFxuICAgKiAoZS5nLiBhZnRlciBgbG9jYXRpb24ucmVsb2FkKClgIGluIHtAbGluayByZWdpc3RlclZhdWx0fSkuXG4gICAqXG4gICAqIFdoZW4gYHRydWVgLCB7QGxpbmsgZW5zdXJlV2ViVmlld0NvbnRleHR9IHNraXBzIHRoZSBleHBlbnNpdmVcbiAgICogYGdldENvbnRleHRzKClgIGNhbGwgKHdoaWNoIHJ1bnMgYGFkYiBzaGVsbCBjYXQgL3Byb2MvbmV0L3VuaXhgIGFuZFxuICAgKiBjYW4gdGltZSBvdXQgb24gc2xvdyBlbXVsYXRvcnMpLlxuICAgKi9cbiAgcHJpdmF0ZSBpc0luV2ViVmlld0NvbnRleHQgPSBmYWxzZTtcbiAgcHJpdmF0ZSByZWFkb25seSBpc1Nlc3Npb25Pd25lcjogYm9vbGVhbjtcbiAgcHJpdmF0ZSByZWFkb25seSBsYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHBsYXRmb3JtOiAnYW5kcm9pZCcgfCAnaW9zJztcbiAgcHJpdmF0ZSByZWFkb25seSBzaG91bGRTd2VlcExlZnRvdmVyczogYm9vbGVhbjtcbiAgcHJpdmF0ZSByZWFkb25seSB2YXVsdEJhc2VQYXRoOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB3ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgQXBwaXVtIHRyYW5zcG9ydC5cbiAgICpcbiAgICogQHBhcmFtIGNvbmZpZyAtIEFwcGl1bSB0cmFuc3BvcnQgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihjb25maWc6IEFwcGl1bVRyYW5zcG9ydENvbmZpZykge1xuICAgIHRoaXMuYnJvd3NlciA9IGNvbmZpZy5icm93c2VyO1xuICAgIHRoaXMuZGV2aWNlSWQgPSBjb25maWcuZGV2aWNlSWQ7XG4gICAgdGhpcy5pc1Nlc3Npb25Pd25lciA9IGNvbmZpZy5pc1Nlc3Npb25Pd25lciA/PyB0cnVlO1xuICAgIHRoaXMubGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHMgPSBjb25maWcubGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHMgPz8gREVGQVVMVF9MQVlPVVRfUkVBRFlfUE9MTF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgICB0aGlzLnBsYXRmb3JtID0gY29uZmlnLnBsYXRmb3JtO1xuICAgIHRoaXMuYXBwSWQgPSBjb25maWcuYXBwSWQgPz8gREVGQVVMVF9BUFBfSUQ7XG4gICAgdGhpcy5zaG91bGRTd2VlcExlZnRvdmVycyA9IGNvbmZpZy5zaG91bGRTd2VlcExlZnRvdmVycyA/PyB0cnVlO1xuICAgIHRoaXMudmF1bHRCYXNlUGF0aCA9IGNvbmZpZy52YXVsdEJhc2VQYXRoID8/IERFRkFVTFRfVkFVTFRfQkFTRV9QQVRIW3RoaXMucGxhdGZvcm1dID8/IERFRkFVTFRfQU5EUk9JRF9WQVVMVF9CQVNFX1BBVEg7XG4gICAgdGhpcy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzID0gY29uZmlnLndlYnZpZXdUaW1lb3V0SW5NaWxsaXNlY29uZHMgPz8gREVGQVVMVF9XRUJWSUVXX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gIH1cblxuICAvKipcbiAgICogQmVnaW5zIGEgY29uc29sZSBjYXB0dXJlIGJ5IHN0YW1waW5nIHRoZSBkZXZpY2UgbG9nIHdpdGggYSB1bmlxdWUgbWFya2VyLlxuICAgKlxuICAgKiBVc2VzIGBhZGIgc2hlbGwgbG9nYCB0byB3cml0ZSBhIG1hcmtlciBpbnRvIGBsb2djYXRgIGF0IGNhcHR1cmUgc3RhcnQgc28gYVxuICAgKiBsYXRlciB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0LnJlYWRDb25zb2xlQ2FwdHVyZVNpbmNlfSBjYW4gc2xpY2Ugb3V0XG4gICAqIGV2ZXJ5dGhpbmcgdGhlIFdlYlZpZXcgbG9nZ2VkIGFmdGVyd2FyZHMgXHUyMDE0IHdpdGhvdXQgdGhlIGludmFzaXZlIGBsb2djYXQgLWNgXG4gICAqIGJ1ZmZlciBjbGVhci5cbiAgICpcbiAgICogQHJldHVybnMgQSBoYW5kbGUgY2FycnlpbmcgdGhlIHVuaXF1ZSBtYXJrZXIuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgYmVnaW5Db25zb2xlQ2FwdHVyZSgpOiBQcm9taXNlPENvbnNvbGVDYXB0dXJlSGFuZGxlPiB7XG4gICAgY29uc3QgbWFya2VyID0gYCR7Q09OU09MRV9DQVBUVVJFX01BUktFUl9UQUd9XyR7cmFuZG9tVVVJRCgpfWA7XG4gICAgYXdhaXQgZXhlYyhcbiAgICAgIFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3NoZWxsJywgJ2xvZycsICctdCcsIENPTlNPTEVfQ0FQVFVSRV9NQVJLRVJfVEFHLCBtYXJrZXJdLFxuICAgICAgeyBpc1F1aWV0OiB0cnVlLCBzaG91bGRJZ25vcmVFeGl0Q29kZTogdHJ1ZSwgdGltZW91dEluTWlsbGlzZWNvbmRzOiBBREJfTE9HX01BUktFUl9USU1FT1VUX0lOX01JTExJU0VDT05EUyB9XG4gICAgKTtcbiAgICByZXR1cm4geyBtYXJrZXIgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYXB0dXJlcyBhIFBORyBzY3JlZW5zaG90IG9mIHRoZSBkZXZpY2UncyBzY3JlZW4uXG4gICAqXG4gICAqIFRoZSBpbWFnZSBpcyBhbHdheXMgdGhlIGRldmljZSdzIG5hdGl2ZSBmcmFtZWJ1ZmZlciBcdTIwMTQgdGhlcmUgaXMgbm8gbW9iaWxlXG4gICAqIGVxdWl2YWxlbnQgb2YgdGhlIGRlc2t0b3Agdmlld3BvcnQgb3ZlcnJpZGUsIHNvXG4gICAqIHtAbGluayBDYXB0dXJlU2NyZWVuc2hvdFBhcmFtcy53aWR0aEluUGl4ZWxzfSAvXG4gICAqIHtAbGluayBDYXB0dXJlU2NyZWVuc2hvdFBhcmFtcy5oZWlnaHRJblBpeGVsc30gYXJlIGlnbm9yZWQuIFNpemUgYSBtb2JpbGVcbiAgICogY2FwdHVyZSBieSBjaG9vc2luZyBhbiBBVkQgd2hvc2Ugc2NyZWVuIGdlb21ldHJ5IGFscmVhZHkgbWF0Y2hlcyB3aGF0IHRoZVxuICAgKiBpbWFnZSBoYXMgdG8gYmUuXG4gICAqXG4gICAqIEBwYXJhbSBfcGFyYW1zIC0gQ2FwdHVyZSBwYXJhbWV0ZXJzLiBJZ25vcmVkIG9uIG1vYmlsZTogYGN3ZGAgZG9lcyBub3Qgc2VsZWN0IGEgd2luZG93ICh2YXVsdCB0YXJnZXRpbmcgaXMgdmlhIGxvY2FsU3RvcmFnZSksIGFuZCB0aGUgc2l6ZSBjYW5ub3QgYmUgb3ZlcnJpZGRlbi5cbiAgICogQHJldHVybnMgVGhlIHJhdyBQTkcgYnl0ZXMuXG4gICAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIGRyaXZlciByZXR1cm5zIGRhdGEgdGhhdCBpcyBub3QgYSBQTkcuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgY2FwdHVyZVNjcmVlbnNob3QoX3BhcmFtczogQ2FwdHVyZVNjcmVlbnNob3RQYXJhbXMpOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgICBjb25zdCBieXRlcyA9IGRlY29kZUJhc2U2NFBuZyhhd2FpdCB0aGlzLmJyb3dzZXIudGFrZVNjcmVlbnNob3QoKSk7XG4gICAgaWYgKCFpc1BuZyhieXRlcykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQXBwaXVtIHNjcmVlbnNob3QgZXJyb3I6IHRha2VTY3JlZW5zaG90IHJldHVybmVkIGRhdGEgdGhhdCBpcyBub3QgYSBQTkcuJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ5dGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuZHMgdGhlIEFwcGl1bSBzZXNzaW9uLlxuICAgKlxuICAgKiBPbmx5IGRlbGV0ZXMgdGhlIHNlc3Npb24gaWYgdGhpcyB0cmFuc3BvcnQgb3ducyBpdC4gVHJhbnNwb3J0cyBjcmVhdGVkXG4gICAqIHZpYSBgYXR0YWNoKClgICh0ZXN0IHdvcmtlcnMgcmV1c2luZyB0aGUgZ2xvYmFsIHNldHVwJ3Mgc2Vzc2lvbikgc2tpcFxuICAgKiBkZWxldGlvbiBzbyB0aGUgc2Vzc2lvbiByZW1haW5zIGF2YWlsYWJsZSBmb3IgdGhlIG93bmluZyBwcm9jZXNzLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuaXNTZXNzaW9uT3duZXIpIHtcbiAgICAgIGF3YWl0IHRoaXMuYnJvd3Nlci5kZWxldGVTZXNzaW9uKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEV2YWx1YXRlcyBhIEphdmFTY3JpcHQgZXhwcmVzc2lvbiBpbnNpZGUgT2JzaWRpYW4gTW9iaWxlJ3MgV2ViVmlldy5cbiAgICpcbiAgICogU3dpdGNoZXMgdG8gdGhlIGBXRUJWSUVXX21kLm9ic2lkaWFuYCBjb250ZXh0LCBleGVjdXRlcyB0aGUgZXhwcmVzc2lvbixcbiAgICogYW5kIHJldHVybnMgdGhlIHJlc3VsdCBzdHJpbmcuXG4gICAqXG4gICAqIEBwYXJhbSBleHByZXNzaW9uIC0gVGhlIEphdmFTY3JpcHQgZXhwcmVzc2lvbiB0byBldmFsdWF0ZS5cbiAgICogQHBhcmFtIF9vcHRpb25zIC0gRXZhbHVhdGlvbiBvcHRpb25zIChjd2QgaXMgbm90IHVzZWQgb24gbW9iaWxlIFx1MjAxNCB2YXVsdCB0YXJnZXRpbmcgaXMgdmlhIGxvY2FsU3RvcmFnZSkuXG4gICAqIEByZXR1cm5zIFRoZSBub3JtYWxpemVkIHJlc3VsdCBzdHJpbmcuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZXZhbHVhdGUoZXhwcmVzc2lvbjogc3RyaW5nLCBfb3B0aW9uczogVHJhbnNwb3J0RXZhbE9wdGlvbnMpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlV2ViVmlld0NvbnRleHQoKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmJyb3dzZXIuZXhlY3V0ZTxudWxsIHwgc3RyaW5nIHwgdW5kZWZpbmVkLCBbXT4oXG4gICAgICAgIGByZXR1cm4gKCR7ZXhwcmVzc2lvbn0pYFxuICAgICAgKTtcblxuICAgICAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkIHx8IHJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gTk9fT1VUUFVUO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAvLyBDb250ZXh0IG1heSBoYXZlIGJlZW4gbG9zdCBtaWQtZXhlY3V0aW9uIChlLmcuIHBhZ2UgcmVsb2FkKS5cbiAgICAgIHRoaXMuaXNJbldlYlZpZXdDb250ZXh0ID0gZmFsc2U7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgc2Vzc2lvbiBjb25uZWN0aW9uIGluZm8gbmVlZGVkIHRvIHJlYXR0YWNoIHRvIHRoaXMgc2Vzc2lvblxuICAgKiBmcm9tIGFub3RoZXIgcHJvY2VzcyAoZS5nLiBhIHRlc3Qgd29ya2VyKS5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIHNlc3Npb24gSUQgYW5kIGRldmljZSBJRC5cbiAgICovXG4gIHB1YmxpYyBnZXRTZXNzaW9uSW5mbygpOiBBcHBpdW1TZXNzaW9uSW5mbyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRldmljZUlkOiB0aGlzLmRldmljZUlkLFxuICAgICAgc2Vzc2lvbklkOiB0aGlzLmJyb3dzZXIuc2Vzc2lvbklkXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmllcyB0aGF0IHRoZSBPYnNpZGlhbiBhcHAgaXMgcnVubmluZyBhbmQgdGhlIFdlYlZpZXcgaXMgYXZhaWxhYmxlLlxuICAgKlxuICAgKiBAcGFyYW0gX3ZhdWx0UGF0aCAtIE5vdCB1c2VkIG9uIG1vYmlsZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBwcmVmbGlnaHRDaGVjayhfdmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2coJ1thcHBpdW0tdHJhbnNwb3J0XSBSdW5uaW5nIHByZWZsaWdodCBjaGVjay4uLicpO1xuICAgIGNvbnN0IHN0YXRlID0gYXdhaXQgdGhpcy5icm93c2VyLnF1ZXJ5QXBwU3RhdGUodGhpcy5hcHBJZCk7XG4gICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gQXBwIHN0YXRlOiAke1N0cmluZyhzdGF0ZSl9IChuZWVkICR7U3RyaW5nKEFQUF9TVEFURV9GT1JFR1JPVU5EKX09Zm9yZWdyb3VuZClgKTtcbiAgICBpZiAoc3RhdGUgIT09IEFQUF9TVEFURV9GT1JFR1JPVU5EKSB7XG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBBY3RpdmF0aW5nIGFwcCAke3RoaXMuYXBwSWR9Li4uYCk7XG4gICAgICB0aGlzLmlzSW5XZWJWaWV3Q29udGV4dCA9IGZhbHNlO1xuICAgICAgYXdhaXQgdGhpcy5icm93c2VyLmFjdGl2YXRlQXBwKHRoaXMuYXBwSWQpO1xuICAgICAgYXdhaXQgZGVsYXkoQVBQX1JFU1RBUlRfREVMQVlfSU5fTUlMTElTRUNPTkRTKTtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLmVuc3VyZVdlYlZpZXdDb250ZXh0KCk7XG4gICAgbG9nKCdbYXBwaXVtLXRyYW5zcG9ydF0gUHJlZmxpZ2h0IGNoZWNrIHBhc3NlZC4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdXNoZXMgdmF1bHQgZmlsZXMgdG8gdGhlIGRldmljZSB2aWEgY29tcHJlc3NlZCBgYWRiIHB1c2hgLlxuICAgKlxuICAgKiBDcmVhdGVzIGEgdGFyLmd6IGFyY2hpdmUgb2YgdGhlIGxvY2FsIHZhdWx0IGRpcmVjdG9yeSwgcHVzaGVzIGl0IHRvIHRoZVxuICAgKiBkZXZpY2UgYXMgYSBzaW5nbGUgZmlsZSwgYW5kIGV4dHJhY3RzIGl0IGluLXBsYWNlLiBUaGlzIGF2b2lkcyB0aGVcbiAgICogd2ViZHJpdmVyIGBSYW5nZUVycm9yYCBvbiBsYXJnZSBiYXNlNjQgcGF5bG9hZHMgYW5kIGlzIHNpZ25pZmljYW50bHlcbiAgICogZmFzdGVyIHRoYW4gcGVyLWZpbGUgYGJyb3dzZXIucHVzaEZpbGUoKWAgY2FsbHMuXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBUaGUgdmF1bHQgcGF0aCAodXNlZCBhcyB0aGUgdmF1bHQgZGlyZWN0b3J5IG5hbWUgb24gZGV2aWNlKS5cbiAgICogQHBhcmFtIF9maWxlcyAtIE1hcCBvZiByZWxhdGl2ZSBmaWxlIHBhdGhzIHRvIGNvbnRlbnQgYnVmZmVycyAodW51c2VkIFx1MjAxNCBhZGIgcHVzaGVzIHRoZSBkaXJlY3RvcnkgZGlyZWN0bHkpLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHB1c2hGaWxlcyh2YXVsdFBhdGg6IHN0cmluZywgX2ZpbGVzOiBSZWNvcmQ8c3RyaW5nLCBVaW50OEFycmF5Pik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGRldmljZVZhdWx0UGF0aCA9IHRoaXMuZ2V0RGV2aWNlVmF1bHRQYXRoKHZhdWx0UGF0aCk7XG4gICAgY29uc3QgYXJjaGl2ZU5hbWUgPSBgdmF1bHQtJHtyYW5kb21VVUlEKCl9LnRhci5nemA7XG4gICAgY29uc3QgbG9jYWxBcmNoaXZlID0gam9pbih0bXBkaXIoKSwgYXJjaGl2ZU5hbWUpO1xuICAgIGNvbnN0IHJlbW90ZUFyY2hpdmUgPSBgL2RhdGEvbG9jYWwvdG1wLyR7YXJjaGl2ZU5hbWV9YDtcblxuICAgIHRyeSB7XG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBDcmVhdGluZyBhcmNoaXZlOiAke2xvY2FsQXJjaGl2ZX1gKTtcbiAgICAgIGF3YWl0IGV4ZWMoWyd0YXInLCAnY3pmJywgYXJjaGl2ZU5hbWUsICctQycsIHZhdWx0UGF0aCwgJy4nXSwgeyBjd2Q6IHRtcGRpcigpLCBpc1F1aWV0OiB0cnVlIH0pO1xuXG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBQdXNoaW5nIGFyY2hpdmUgdG8gZGV2aWNlICR7dGhpcy5kZXZpY2VJZH0uLi5gKTtcbiAgICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAncHVzaCcsIGxvY2FsQXJjaGl2ZSwgcmVtb3RlQXJjaGl2ZV0sIHsgaXNRdWlldDogdHJ1ZSB9KTtcblxuICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gRXh0cmFjdGluZyBhcmNoaXZlIG9uIGRldmljZSBhdCAke2RldmljZVZhdWx0UGF0aH0uLi5gKTtcbiAgICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAnbWtkaXInLCAnLXAnLCBkZXZpY2VWYXVsdFBhdGhdLCB7IGlzUXVpZXQ6IHRydWUgfSk7XG4gICAgICBhd2FpdCBleGVjKFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3NoZWxsJywgJ3RhcicsICd4emYnLCByZW1vdGVBcmNoaXZlLCAnLUMnLCBkZXZpY2VWYXVsdFBhdGhdLCB7IGlzUXVpZXQ6IHRydWUgfSk7XG5cbiAgICAgIGxvZygnW2FwcGl1bS10cmFuc3BvcnRdIEZsdXNoaW5nIGZpbGVzeXN0ZW0gYnVmZmVycy4uLicpO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdzeW5jJ10sIHsgaXNRdWlldDogdHJ1ZSB9KTtcblxuICAgICAgbG9nKCdbYXBwaXVtLXRyYW5zcG9ydF0gQ2xlYW5pbmcgdXAgcmVtb3RlIGFyY2hpdmUuLi4nKTtcbiAgICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAncm0nLCByZW1vdGVBcmNoaXZlXSwgeyBpc1F1aWV0OiB0cnVlIH0pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBybShsb2NhbEFyY2hpdmUsIHsgZm9yY2U6IHRydWUgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIER1bXBzIGBhZGIgbG9nY2F0YCBhbmQgcmV0dXJucyB0aGUgV2ViVmlldyBjb25zb2xlL2Vycm9yIG91dHB1dCBsb2dnZWRcbiAgICogc2luY2UgdGhlIG1hcmtlciBmcm9tIHtAbGluayBBcHBpdW1UcmFuc3BvcnQuYmVnaW5Db25zb2xlQ2FwdHVyZX0uXG4gICAqXG4gICAqIEZpbHRlcnMgdG8gdGhlIENocm9taXVtL1dlYlZpZXcgdGFncyB0aGF0IGNhcnJ5IEpTIGBjb25zb2xlLipgIG91dHB1dCBhbmRcbiAgICogdW5jYXVnaHQgZXJyb3JzLCBhbmQgY2FwcyB0aGUgcmVzdWx0IGxlbmd0aC4gQm91bmRlZCwgcG9zdC1ob2MsXG4gICAqIGZhaWx1cmUtcGF0aC1vbmx5IFx1MjAxNCBuZXZlciBhIGxpdmUgbW9uaXRvci5cbiAgICpcbiAgICogQHBhcmFtIGhhbmRsZSAtIFRoZSBjYXB0dXJlIGhhbmRsZSAob3IgYHVuZGVmaW5lZGAgd2hlbiBjYXB0dXJlIG5ldmVyIHN0YXJ0ZWQpLlxuICAgKiBAcmV0dXJucyBUaGUgY2FwdHVyZWQgY29uc29sZS9lcnJvciB0ZXh0LCBvciBgdW5kZWZpbmVkYCBpZiBub3RoaW5nIHJlbGV2YW50IHdhcyBsb2dnZWQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVhZENvbnNvbGVDYXB0dXJlU2luY2UoaGFuZGxlOiBDb25zb2xlQ2FwdHVyZUhhbmRsZSB8IHVuZGVmaW5lZCk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gICAgaWYgKCFoYW5kbGUpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgZHVtcCA9IGF3YWl0IGV4ZWMoXG4gICAgICBbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdsb2djYXQnLCAnLWQnLCAnLXYnLCAndGltZSddLFxuICAgICAgeyBpc1F1aWV0OiB0cnVlLCBzaG91bGRJZ25vcmVFeGl0Q29kZTogdHJ1ZSwgdGltZW91dEluTWlsbGlzZWNvbmRzOiBMT0dDQVRfRFVNUF9USU1FT1VUX0lOX01JTExJU0VDT05EUyB9XG4gICAgKTtcblxuICAgIGNvbnN0IG1hcmtlckluZGV4ID0gZHVtcC5sYXN0SW5kZXhPZihoYW5kbGUubWFya2VyKTtcbiAgICBjb25zdCByZWdpb24gPSBtYXJrZXJJbmRleCA9PT0gLTEgPyBkdW1wIDogZHVtcC5zbGljZShtYXJrZXJJbmRleCArIGhhbmRsZS5tYXJrZXIubGVuZ3RoKTtcbiAgICBjb25zdCByZWxldmFudCA9IHJlZ2lvblxuICAgICAgLnNwbGl0KCdcXG4nKVxuICAgICAgLmZpbHRlcigobGluZSkgPT4gQ09OU09MRV9DQVBUVVJFX1RBR19SRS50ZXN0KGxpbmUpKVxuICAgICAgLmpvaW4oJ1xcbicpXG4gICAgICAudHJpbSgpO1xuXG4gICAgaWYgKCFyZWxldmFudCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVsZXZhbnQuc2xpY2UoLUNPTlNPTEVfQ0FQVFVSRV9UQUlMX01BWF9MRU5HVEgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBhIHZhdWx0IG9uIG1vYmlsZSBieSBwdXNoaW5nIGZpbGVzIGFuZCBjb25maWd1cmluZyBsb2NhbFN0b3JhZ2UuXG4gICAqXG4gICAqIFRoZSByZWdpc3RyYXRpb24gZmxvdzpcbiAgICogMS4gUHVzaCBhIG1pbmltYWwgYC5vYnNpZGlhbi9hcHAuanNvbmAgdG8gdGhlIGRldmljZSBzbyBPYnNpZGlhbiByZWNvZ25pemVzIHRoZSB2YXVsdFxuICAgKiAyLiBTd2l0Y2ggdG8gdGhlIFdlYlZpZXcgY29udGV4dFxuICAgKiAzLiBBZGQgdGhlIHZhdWx0IHRvIGxvY2FsU3RvcmFnZSAoYG1vYmlsZS1leHRlcm5hbC12YXVsdHNgLCBgbW9iaWxlLXNlbGVjdGVkLXZhdWx0YCxcbiAgICogICAgYGVuYWJsZS1wbHVnaW4tPHBhdGg+YClcbiAgICogNC4gVHJpZ2dlciBgbG9jYXRpb24ucmVsb2FkKClgIHNvIE9ic2lkaWFuIHJlLXJlYWRzIGxvY2FsU3RvcmFnZSBhbmQgb3BlbnMgdGhlIHZhdWx0XG4gICAqIDUuIFdhaXQgZm9yIGBhcHAud29ya3NwYWNlLmxheW91dFJlYWR5YFxuICAgKlxuICAgKiBFeGlzdGluZyB2YXVsdCByZWdpc3RyYXRpb25zIGluIGxvY2FsU3RvcmFnZSBhcmUgcHJlc2VydmVkIChhcHBlbmQsIG5vdFxuICAgKiBvdmVyd3JpdGUpIFx1MjAxNCBleGNlcHQgdGhlICoqaGFybmVzcydzIG93bioqIGB0ZW1wLXZhdWx0LSpgIHJlZ2lzdHJhdGlvbnMgZnJvbVxuICAgKiBlYXJsaWVyIHJ1bnMsIHdoaWNoIGFyZSBwcnVuZWQgd2hlbiB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0Q29uZmlnLnNob3VsZFN3ZWVwTGVmdG92ZXJzfVxuICAgKiBpcyBvbi4gVGhlaXIgZGlyZWN0b3JpZXMgYXJlIGFscmVhZHkgZ29uZSAodGhlIGZhY3Rvcnkgc3dlZXBzIHRoZW0gYmVmb3JlXG4gICAqIHRoZSBhcHAgbGF1bmNoZXMpLCBhbmQgaXQgaXMgdGhpcyByZWdpc3RyeSBcdTIwMTQgbm90IHRoZSBmaWxlc3lzdGVtIFx1MjAxNCB0aGF0XG4gICAqIE9ic2lkaWFuIGVudW1lcmF0ZXMgYXQgc3RhcnR1cCwgc28gbGVhdmluZyB0aGVtIGlzIHdoYXQgbWFrZXMgZWFjaCBmYWlsZWRcbiAgICogcnVuIHNsb3cgdGhlIG5leHQgb25lIGRvd24uXG4gICAqXG4gICAqIEBwYXJhbSB2YXVsdFBhdGggLSBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgdmF1bHQgb24gdGhlIGhvc3QgbWFjaGluZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyByZWdpc3RlclZhdWx0KHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gUmVnaXN0ZXJpbmcgdmF1bHQ6ICR7dmF1bHRQYXRofWApO1xuICAgIGNvbnN0IGRldmljZVZhdWx0UGF0aCA9IHRoaXMuZ2V0RGV2aWNlVmF1bHRQYXRoKHZhdWx0UGF0aCk7XG5cbiAgICAvLyBQdXNoIGEgbWluaW1hbCAub2JzaWRpYW4gZGlyZWN0b3J5IHNvIE9ic2lkaWFuIHJlY29nbml6ZXMgaXQgYXMgYSB2YXVsdC5cbiAgICBhd2FpdCB0aGlzLnB1c2hPYnNpZGlhbk1hcmtlcihkZXZpY2VWYXVsdFBhdGgpO1xuXG4gICAgLy8gU3dpdGNoIHRvIFdlYlZpZXcgYW5kIGNvbmZpZ3VyZSBsb2NhbFN0b3JhZ2UuXG4gICAgYXdhaXQgdGhpcy5lbnN1cmVXZWJWaWV3Q29udGV4dCgpO1xuXG4gICAgLy8gSW52YWxpZGF0ZSBiZWZvcmUgcmVsb2FkIFx1MjAxNCB0aGUgcGFnZSB3aWxsIG5hdmlnYXRlIGFuZCB0aGUgV2ViVmlld1xuICAgIC8vIENvbnRleHQgbWF5IGJlIHRlbXBvcmFyaWx5IHVuYXZhaWxhYmxlIGR1cmluZyByZWxvYWQuXG4gICAgdGhpcy5pc0luV2ViVmlld0NvbnRleHQgPSBmYWxzZTtcblxuICAgIGNvbnN0IHN0YWxlUHJlZml4ID0gdGhpcy5zaG91bGRTd2VlcExlZnRvdmVycyA/IGAke3RoaXMudmF1bHRCYXNlUGF0aH0ke1RFTVBfVkFVTFRfRElSX1BSRUZJWH1gIDogJyc7XG5cbiAgICBhd2FpdCB0aGlzLmJyb3dzZXIuZXhlY3V0ZShcbiAgICAgIChwYXRoOiBzdHJpbmcsIHBydW5lUHJlZml4OiBzdHJpbmcpID0+IHtcbiAgICAgICAgbGV0IGV4aXN0aW5nID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnbW9iaWxlLWV4dGVybmFsLXZhdWx0cycpID8/ICdbXScpIGFzIHN0cmluZ1tdO1xuXG4gICAgICAgIGlmIChwcnVuZVByZWZpeCkge1xuICAgICAgICAgIGNvbnN0IHN0YWxlID0gZXhpc3RpbmcuZmlsdGVyKChyZWdpc3RlcmVkKSA9PiByZWdpc3RlcmVkICE9PSBwYXRoICYmIHJlZ2lzdGVyZWQuc3RhcnRzV2l0aChwcnVuZVByZWZpeCkpO1xuICAgICAgICAgIGZvciAoY29uc3QgcmVnaXN0ZXJlZCBvZiBzdGFsZSkge1xuICAgICAgICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oYGVuYWJsZS1wbHVnaW4tJHtyZWdpc3RlcmVkfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBleGlzdGluZyA9IGV4aXN0aW5nLmZpbHRlcigocmVnaXN0ZXJlZCkgPT4gIXN0YWxlLmluY2x1ZGVzKHJlZ2lzdGVyZWQpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghZXhpc3RpbmcuaW5jbHVkZXMocGF0aCkpIHtcbiAgICAgICAgICBleGlzdGluZy5wdXNoKHBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzJywgSlNPTi5zdHJpbmdpZnkoZXhpc3RpbmcpKTtcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ21vYmlsZS1zZWxlY3RlZC12YXVsdCcsIHBhdGgpO1xuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShgZW5hYmxlLXBsdWdpbi0ke3BhdGh9YCwgJ3RydWUnKTtcbiAgICAgICAgbG9jYXRpb24ucmVsb2FkKCk7XG4gICAgICB9LFxuICAgICAgZGV2aWNlVmF1bHRQYXRoLFxuICAgICAgc3RhbGVQcmVmaXhcbiAgICApO1xuXG4gICAgLy8gV2FpdCBmb3IgcmVsb2FkICsgdmF1bHQgaW5pdGlhbGl6YXRpb24uXG4gICAgYXdhaXQgdGhpcy53YWl0Rm9yTGF5b3V0UmVhZHkoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnJlZ2lzdGVycyBhIHZhdWx0IG9uIG1vYmlsZSBieSByZW1vdmluZyBpdCBmcm9tIGxvY2FsU3RvcmFnZS5cbiAgICpcbiAgICogUHJlc2VydmVzIG90aGVyIHZhdWx0IHJlZ2lzdHJhdGlvbnMuIElmIHRoZSB1bnJlZ2lzdGVyZWQgdmF1bHQgd2FzIHNlbGVjdGVkLFxuICAgKiBzd2l0Y2hlcyB0byB0aGUgZmlyc3QgcmVtYWluaW5nIHZhdWx0IChvciBjbGVhcnMgdGhlIHNlbGVjdGlvbikuXG4gICAqXG4gICAqIFRoZSB2YXVsdCdzICoqZmlsZXMgYXJlIHRoZW4gcmVtb3ZlZCBmcm9tIHRoZSBkZXZpY2Ugb3ZlciBgYWRiYCwgd2hldGhlciBvclxuICAgKiBub3QgdGhlIGBsb2NhbFN0b3JhZ2VgIHN0ZXAgc3VjY2VlZGVkKiogXHUyMDE0IGRlbGliZXJhdGVseSwgYmVjYXVzZSB0aGVcbiAgICogYGxvY2FsU3RvcmFnZWAgc3RlcCBnb2VzIHRocm91Z2ggdGhlIFdlYlZpZXcgYW5kIGEgZGVhZCBXZWJWaWV3IGlzIGV4YWN0bHlcbiAgICogd2hhdCBtb3N0IEFuZHJvaWQgZmFpbHVyZXMgYXJlLiBSb3V0aW5nIHRoZSByZW1vdmFsIHRocm91Z2ggdGhlIGFwcCB3YXMgd2hhdFxuICAgKiBtYWRlIGV2ZXJ5IGZhaWxlZCBydW4gbGVhayBpdHMgdmF1bHQgKGBWYXVsdCBjbGVhbnVwIGVycm9yIChub24tZmF0YWwpOiBub1xuICAgKiBzdWNoIHdpbmRvd2ApLCBzbyB0aGUgZmlsZXN5c3RlbS1sZXZlbCByZW1vdmFsIG11c3Qgbm90IGRlcGVuZCBvbiBpdC5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBvbiB0aGUgaG9zdCBtYWNoaW5lLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHVucmVnaXN0ZXJWYXVsdCh2YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGRldmljZVZhdWx0UGF0aCA9IHRoaXMuZ2V0RGV2aWNlVmF1bHRQYXRoKHZhdWx0UGF0aCk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5lbnN1cmVXZWJWaWV3Q29udGV4dCgpO1xuXG4gICAgICBhd2FpdCB0aGlzLmJyb3dzZXIuZXhlY3V0ZSgocGF0aDogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnbW9iaWxlLWV4dGVybmFsLXZhdWx0cycpID8/ICdbXScpIGFzIHN0cmluZ1tdO1xuICAgICAgICBjb25zdCBmaWx0ZXJlZCA9IGV4aXN0aW5nLmZpbHRlcigodikgPT4gdiAhPT0gcGF0aCk7XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzJywgSlNPTi5zdHJpbmdpZnkoZmlsdGVyZWQpKTtcbiAgICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oYGVuYWJsZS1wbHVnaW4tJHtwYXRofWApO1xuICAgICAgICBpZiAobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ21vYmlsZS1zZWxlY3RlZC12YXVsdCcpID09PSBwYXRoKSB7XG4gICAgICAgICAgaWYgKGZpbHRlcmVkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdtb2JpbGUtc2VsZWN0ZWQtdmF1bHQnLCBmaWx0ZXJlZFswXSA/PyAnJyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKCdtb2JpbGUtc2VsZWN0ZWQtdmF1bHQnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sIGRldmljZVZhdWx0UGF0aCk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGxvZyhcbiAgICAgICAgYFthcHBpdW0tdHJhbnNwb3J0XSBDb3VsZCBub3QgZGVyZWdpc3RlciAke2RldmljZVZhdWx0UGF0aH0gZnJvbSBsb2NhbFN0b3JhZ2UgYFxuICAgICAgICAgICsgYCgke1N0cmluZyhlcnJvcil9KTsgcmVtb3ZpbmcgaXRzIGZpbGVzIGFueXdheS5gXG4gICAgICApO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMucmVtb3ZlRGV2aWNlVmF1bHREaXJlY3RvcnkoZGV2aWNlVmF1bHRQYXRoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTd2l0Y2hlcyB0aGUgZHJpdmVyIHRvIHRoZSBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dC5cbiAgICpcbiAgICogSWYgdGhlIGNvbnRleHQgd2FzIGFscmVhZHkgdmVyaWZpZWQgKGNhY2hlZCB2aWEge0BsaW5rIGlzSW5XZWJWaWV3Q29udGV4dH0pLFxuICAgKiByZXR1cm5zIGltbWVkaWF0ZWx5IHdpdGhvdXQgY2FsbGluZyBgZ2V0Q29udGV4dHMoKWAgXHUyMDE0IHdoaWNoIHJ1bnNcbiAgICogYGFkYiBzaGVsbCBjYXQgL3Byb2MvbmV0L3VuaXhgIGFuZCBjYW4gdGltZSBvdXQgb24gc2xvdyBlbXVsYXRvcnMuXG4gICAqXG4gICAqIFBvbGxzIHVudGlsIHRoZSBjb250ZXh0IGJlY29tZXMgYXZhaWxhYmxlICh0aGUgYXBwIG1heSBzdGlsbCBiZSBsb2FkaW5nKS5cbiAgICogVXNlcyB0aGUgYFdFQlZJRVdfbWQub2JzaWRpYW5gIGNvbnRleHQgc3BlY2lmaWNhbGx5IHRvIGF2b2lkIGNvbm5lY3RpbmdcbiAgICogdG8gQ2hyb21lIG9yIG90aGVyIFdlYlZpZXdzIG9uIHRoZSBkZXZpY2UuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGVuc3VyZVdlYlZpZXdDb250ZXh0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmlzSW5XZWJWaWV3Q29udGV4dCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIHRoaXMud2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcztcbiAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBXYWl0aW5nIGZvciAke1dFQlZJRVdfQ09OVEVYVF9QUkVGSVh9IGNvbnRleHQgKHRpbWVvdXQ9JHtTdHJpbmcodGhpcy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzKX1tcykuLi5gKTtcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGNvbnN0IGNvbnRleHRzID0gYXdhaXQgdGhpcy5icm93c2VyLmdldENvbnRleHRzKCk7XG4gICAgICBjb25zdCBvYnNpZGlhbkNvbnRleHQgPSBjb250ZXh0cy5maW5kKChjb250ZXh0KTogY29udGV4dCBpcyBzdHJpbmcgPT4gdHlwZW9mIGNvbnRleHQgPT09ICdzdHJpbmcnICYmIGNvbnRleHQuc3RhcnRzV2l0aChXRUJWSUVXX0NPTlRFWFRfUFJFRklYKSk7XG5cbiAgICAgIGlmIChvYnNpZGlhbkNvbnRleHQpIHtcbiAgICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gRm91bmQgV2ViVmlldyBjb250ZXh0OiAke29ic2lkaWFuQ29udGV4dH1gKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmJyb3dzZXIuc3dpdGNoQ29udGV4dChvYnNpZGlhbkNvbnRleHQpO1xuICAgICAgICAgIHRoaXMuaXNJbldlYlZpZXdDb250ZXh0ID0gdHJ1ZTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gc3dpdGNoQ29udGV4dCBmYWlsZWQ6ICR7U3RyaW5nKGVycm9yKX0uIFJlc2V0dGluZyB0byBOQVRJVkVfQVBQIGJlZm9yZSByZXRyeWluZy4uLmApO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmJyb3dzZXIuc3dpdGNoQ29udGV4dCgnTkFUSVZFX0FQUCcpO1xuICAgICAgICAgIH0gY2F0Y2ggKHJlc2V0RXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIE5BVElWRV9BUFAgcmVzZXQgYWxzbyBmYWlsZWQ6ICR7U3RyaW5nKHJlc2V0RXJyb3IpfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBXZWJWaWV3IG5vdCByZWFkeSwgYXZhaWxhYmxlIGNvbnRleHRzOiAke0pTT04uc3RyaW5naWZ5KGNvbnRleHRzKX0uIFJldHJ5aW5nLi4uYCk7XG4gICAgICBhd2FpdCBkZWxheShXRUJWSUVXX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYE5vICR7V0VCVklFV19DT05URVhUX1BSRUZJWH0gY29udGV4dCBmb3VuZCB3aXRoaW4gJHtTdHJpbmcodGhpcy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzKX1tcy4gSXMgdGhlIE9ic2lkaWFuIGFwcCBmdWxseSBsb2FkZWQ/YCk7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBob3N0LXNpZGUgdmF1bHQgcGF0aCB0byB0aGUgZGV2aWNlLXNpZGUgcGF0aC5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIEFic29sdXRlIHBhdGggb24gdGhlIGhvc3QgbWFjaGluZS5cbiAgICogQHJldHVybnMgVGhlIGRldmljZS1zaWRlIHZhdWx0IHBhdGguXG4gICAqL1xuICBwcml2YXRlIGdldERldmljZVZhdWx0UGF0aCh2YXVsdFBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3RoaXMudmF1bHRCYXNlUGF0aH0ke2V4dHJhY3RWYXVsdE5hbWUodmF1bHRQYXRoKX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1c2hlcyB0aGUgbWluaW1hbCBgLm9ic2lkaWFuL2FwcC5qc29uYCB2YXVsdCBtYXJrZXIgdmlhIGBhZGIgcHVzaGAuXG4gICAqXG4gICAqIGBicm93c2VyLnB1c2hGaWxlYCAoV2ViRHJpdmVyIGJhc2U2NCkgaXMgYW4gb3JkZXIgb2YgbWFnbml0dWRlIHNsb3dlciBvbiBhXG4gICAqIGNvbGQgb3IgbG9hZGVkIGVtdWxhdG9yIFx1MjAxNCBtZWFzdXJlZCBhdCA5XHUyMDEzMjFzIHBlciBjYWxsIGZvciB0aGlzIDItYnl0ZSBtYXJrZXIsXG4gICAqIHZlcnN1cyBzdWItc2Vjb25kIG92ZXIgYGFkYmAuIFRoaXMgbWlycm9ycyB7QGxpbmsgcHVzaEZpbGVzfSwgd2hpY2ggc3dpdGNoZWRcbiAgICogdG8gYGFkYmAgZm9yIHRoZSBzYW1lIHJlYXNvbi4gYG1rZGlyIC1wYCBndWFyYW50ZWVzIHRoZSBwYXJlbnQgZGlyZWN0b3J5LlxuICAgKlxuICAgKiBAcGFyYW0gZGV2aWNlVmF1bHRQYXRoIC0gVGhlIGRldmljZS1zaWRlIHZhdWx0IGRpcmVjdG9yeSBwYXRoLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwdXNoT2JzaWRpYW5NYXJrZXIoZGV2aWNlVmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBsb2NhbE1hcmtlciA9IGpvaW4odG1wZGlyKCksIGBvYnNpZGlhbi1tYXJrZXItJHtyYW5kb21VVUlEKCl9Lmpzb25gKTtcbiAgICBjb25zdCByZW1vdGVNYXJrZXIgPSBgJHtkZXZpY2VWYXVsdFBhdGh9Ly5vYnNpZGlhbi9hcHAuanNvbmA7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgd3JpdGVGaWxlKGxvY2FsTWFya2VyLCAne30nLCAndXRmLTgnKTtcbiAgICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAnbWtkaXInLCAnLXAnLCBgJHtkZXZpY2VWYXVsdFBhdGh9Ly5vYnNpZGlhbmBdLCB7IGlzUXVpZXQ6IHRydWUgfSk7XG4gICAgICBhd2FpdCBleGVjKFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3B1c2gnLCBsb2NhbE1hcmtlciwgcmVtb3RlTWFya2VyXSwgeyBpc1F1aWV0OiB0cnVlIH0pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBybShsb2NhbE1hcmtlciwgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhIHZhdWx0IGRpcmVjdG9yeSBmcm9tIHRoZSBkZXZpY2Ugb3ZlciBgYWRiYCwgYW5kIENIRUNLUyB0aGF0IGl0IGlzXG4gICAqIGFjdHVhbGx5IGdvbmUuXG4gICAqXG4gICAqIEJlc3QtZWZmb3J0OiBhIGZhaWx1cmUgaXMgbG9nZ2VkLCBub3QgdGhyb3duLCBzbyBhIHRlYXJkb3duIHByb2JsZW0gbmV2ZXJcbiAgICogbWFza3MgdGhlIHRlc3QgcmVzdWx0LiBUaGUgbmV4dCBydW4ncyBzdGFydC1vZi1ydW4gc3dlZXAgcGlja3MgdXAgd2hhdGV2ZXJcbiAgICogdGhpcyBjb3VsZCBub3QgcmVtb3ZlLlxuICAgKlxuICAgKiBUaGUgY2hlY2sgaXMgdGhlIHBvaW50LiBgcm0gLXJmYCBydW5zIHdpdGggYHNob3VsZElnbm9yZUV4aXRDb2RlYCwgc28gYW5cbiAgICogdW5yZW1vdmVkIGRpcmVjdG9yeSB1c2VkIHRvIGxlYXZlIG5vIHRyYWNlIGF0IGFsbCBcdTIwMTQgd2hpY2ggaXMgaG93IHJ1bnMgdGhhdFxuICAgKiBwYXNzZWQgZW5kIHRvIGVuZCB3ZXJlIHN0aWxsIGZvdW5kIHRvIGJlIGxlYWtpbmcgYSB2YXVsdCBhcGllY2UsIGludmlzaWJseSxcbiAgICogdW50aWwgc29tZW9uZSBjb3VudGVkIHRoZSBkaXJlY3RvcmllcyBvbiB0aGUgZGV2aWNlIGJ5IGhhbmQuIEEgbGVhayBpcyBub3dcbiAgICogbmFtZWQgaW4gdGhlIGxvZyBhdCB0aGUgbW9tZW50IGl0IGhhcHBlbnMuXG4gICAqXG4gICAqIEBwYXJhbSBkZXZpY2VWYXVsdFBhdGggLSBUaGUgZGV2aWNlLXNpZGUgdmF1bHQgZGlyZWN0b3J5IHBhdGguXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlbW92ZURldmljZVZhdWx0RGlyZWN0b3J5KGRldmljZVZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFJlbW92aW5nIHZhdWx0IGRpcmVjdG9yeSBmcm9tIGRldmljZTogJHtkZXZpY2VWYXVsdFBhdGh9YCk7XG4gICAgICBhd2FpdCBleGVjKFxuICAgICAgICBbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdybScsICctcmYnLCBkZXZpY2VWYXVsdFBhdGhdLFxuICAgICAgICB7IGlzUXVpZXQ6IHRydWUsIHNob3VsZElnbm9yZUV4aXRDb2RlOiB0cnVlLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IEFEQl9WQVVMVF9SRU1PVkVfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfVxuICAgICAgKTtcblxuICAgICAgY29uc3QgbGlzdGluZyA9IGF3YWl0IGV4ZWMoXG4gICAgICAgIFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3NoZWxsJywgJ2xzJywgJy1kJywgZGV2aWNlVmF1bHRQYXRoXSxcbiAgICAgICAgeyBpc1F1aWV0OiB0cnVlLCBzaG91bGRJZ25vcmVFeGl0Q29kZTogdHJ1ZSwgdGltZW91dEluTWlsbGlzZWNvbmRzOiBBREJfVkFVTFRfUkVNT1ZFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH1cbiAgICAgICk7XG5cbiAgICAgIGlmIChsaXN0aW5nLmluY2x1ZGVzKGRldmljZVZhdWx0UGF0aCkpIHtcbiAgICAgICAgbG9nKFxuICAgICAgICAgIGBbYXBwaXVtLXRyYW5zcG9ydF0gV2FybmluZzogJHtkZXZpY2VWYXVsdFBhdGh9IHN1cnZpdmVkIHJlbW92YWwgYW5kIGlzIG5vdyBsZWFrZWQgcmVzaWR1ZS4gYFxuICAgICAgICAgICAgKyAnVGhlIG5leHQgcnVuXFwncyBzdGFydC1vZi1ydW4gc3dlZXAgd2lsbCByZXRyeSBpdC4nXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFZhdWx0IGRpcmVjdG9yeSByZW1vdmFsIGZhaWxlZCAobm9uLWZhdGFsKTogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQb2xscyB1bnRpbCBgYXBwLndvcmtzcGFjZS5sYXlvdXRSZWFkeWAgaXMgYHRydWVgIGluIHRoZSBXZWJWaWV3LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyB3YWl0Rm9yTGF5b3V0UmVhZHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IGRlYWRsaW5lID0gc3RhcnQgKyB0aGlzLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzO1xuICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFdhaXRpbmcgZm9yIGxheW91dCByZWFkeSAodGltZW91dD0ke1N0cmluZyh0aGlzLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzKX1tcykuLi5gKTtcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGlzUmVhZHkgPSBhd2FpdCB0aGlzLmJyb3dzZXIuZXhlY3V0ZSgoKTogYm9vbGVhbiA9PiB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1kZXByZWNhdGVkIC0tIFdlIG5lZWQgZ2xvYmFsIGBhcHBgIHZhcmlhYmxlLlxuICAgICAgICAgIGNvbnN0IGFwcCA9IGdsb2JhbFRoaXMuYXBwIGFzIExvYWRpbmdBcHAgfCB1bmRlZmluZWQ7XG4gICAgICAgICAgcmV0dXJuICEhYXBwPy53b3Jrc3BhY2U/LmxheW91dFJlYWR5O1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGlzUmVhZHkpIHtcbiAgICAgICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBMYXlvdXQgaXMgcmVhZHkgYWZ0ZXIgJHtTdHJpbmcoRGF0ZS5ub3coKSAtIHN0YXJ0KX1tcy5gKTtcbiAgICAgICAgICB0aGlzLmlzSW5XZWJWaWV3Q29udGV4dCA9IHRydWU7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gQXBwIG5vdCByZWFkeSB5ZXQgKHBhZ2UgbWF5IGJlIHJlbG9hZGluZykuXG4gICAgICB9XG5cbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIExheW91dCBub3QgcmVhZHkgeWV0IChlbGFwc2VkPSR7U3RyaW5nKERhdGUubm93KCkgLSBzdGFydCl9bXMpLiBSZXRyeWluZy4uLmApO1xuICAgICAgYXdhaXQgZGVsYXkoTEFZT1VUX1JFQURZX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYE9ic2lkaWFuIGxheW91dCBkaWQgbm90IGJlY29tZSByZWFkeSB3aXRoaW4gJHtTdHJpbmcodGhpcy5sYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXNgKTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIGdpdmVuIGRlbGF5LlxuICpcbiAqIEBwYXJhbSBtcyAtIFRoZSBkZWxheSBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgZGVsYXkuXG4gKi9cbmZ1bmN0aW9uIGRlbGF5KG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgc2V0VGltZW91dChyZXNvbHZlLCBtcyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEV4dHJhY3RzIHRoZSB2YXVsdCBkaXJlY3RvcnkgbmFtZSBmcm9tIGEgaG9zdC1zaWRlIHZhdWx0IHBhdGguXG4gKlxuICogQHBhcmFtIHZhdWx0UGF0aCAtIEFic29sdXRlIHBhdGggb24gdGhlIGhvc3QgbWFjaGluZS5cbiAqIEByZXR1cm5zIFRoZSBsYXN0IHBhdGggc2VnbWVudCAodmF1bHQgZGlyZWN0b3J5IG5hbWUpLlxuICovXG5mdW5jdGlvbiBleHRyYWN0VmF1bHROYW1lKHZhdWx0UGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IHZhdWx0UGF0aC5yZXBsYWNlKC9bXFxcXC9dKyQvLCAnJyk7XG4gIGNvbnN0IGxhc3RTZXBhcmF0b3IgPSBNYXRoLm1heChub3JtYWxpemVkLmxhc3RJbmRleE9mKCcvJyksIG5vcm1hbGl6ZWQubGFzdEluZGV4T2YoJ1xcXFwnKSk7XG4gIHJldHVybiBub3JtYWxpemVkLnNsaWNlKGxhc3RTZXBhcmF0b3IgKyAxKTtcbn1cblxu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
618
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3RyYW5zcG9ydC1hcHBpdW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBBcHBpdW0gdHJhbnNwb3J0IFx1MjAxNCBldmFsdWF0ZXMgZXhwcmVzc2lvbnMgaW5zaWRlIE9ic2lkaWFuIE1vYmlsZSB2aWEgV2ViVmlld1xuICogSmF2YVNjcmlwdCBpbmplY3Rpb24uIE1hbmFnZXMgdmF1bHQgbGlmZWN5Y2xlIHZpYSBsb2NhbFN0b3JhZ2UgYW5kIGZpbGUgcHVzaC5cbiAqXG4gKiBDb25maWd1cmVkIHZpYSBgZW52aXJvbm1lbnRPcHRpb25zLm9ic2lkaWFuVHJhbnNwb3J0YCBpbiB2aXRlc3QgY29uZmlnOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIHZpdGVzdC5jb25maWcudHNcbiAqIGVudmlyb25tZW50T3B0aW9uczoge1xuICogICBvYnNpZGlhblRyYW5zcG9ydDoge1xuICogICAgIHR5cGU6ICdvYnNpZGlhbi1hbmRyb2lkLWFwcGl1bScsXG4gKiAgICAgYXBwaXVtVXJsOiAnaHR0cDovL2xvY2FsaG9zdDo0NzIzJyxcbiAqICAgICBhdmROYW1lOiAnb2JzaWRpYW5fdGVzdCcsXG4gKiAgIH0sXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBGb3IgQnJvd3NlclN0YWNrLCBzZXQgYGFwcGl1bVVybGAgdG8gdGhlIEJyb3dzZXJTdGFjayBodWIgVVJMXG4gKiBcdTIwMTQgdGhlIHRyYW5zcG9ydCBpdHNlbGYgaXMgaHViLWFnbm9zdGljLlxuICpcbiAqICMjIEhvdyB2YXVsdCByZWdpc3RyYXRpb24gd29ya3Mgb24gbW9iaWxlXG4gKlxuICogT2JzaWRpYW4gTW9iaWxlIHN0b3JlcyBpdHMgdmF1bHQgcmVnaXN0cnkgaW4gdGhlIFdlYlZpZXcncyBgbG9jYWxTdG9yYWdlYDpcbiAqXG4gKiAtIGBtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzYCBcdTIwMTQgSlNPTiBhcnJheSBvZiByZWdpc3RlcmVkIHZhdWx0IHBhdGhzXG4gKiAtIGBtb2JpbGUtc2VsZWN0ZWQtdmF1bHRgIFx1MjAxNCB0aGUgY3VycmVudGx5IGFjdGl2ZSB2YXVsdCBwYXRoXG4gKiAtIGBlbmFibGUtcGx1Z2luLTx2YXVsdFBhdGg+YCBcdTIwMTQgYFwidHJ1ZVwiYCB0byBlbmFibGUgdGhlIHBsdWdpbiBzeXN0ZW0gZm9yIHRoZSB2YXVsdFxuICpcbiAqIFRvIHJlZ2lzdGVyIGEgdmF1bHQgcHJvZ3JhbW1hdGljYWxseSAod2l0aG91dCBVSSBpbnRlcmFjdGlvbik6XG4gKlxuICogMS4gUHVzaCB2YXVsdCBmaWxlcyB0byB0aGUgZGV2aWNlIChlLmcuIGAvc2RjYXJkL0RvY3VtZW50cy88TmFtZT4vLm9ic2lkaWFuL2FwcC5qc29uYClcbiAqIDIuIFN3aXRjaCB0byBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dFxuICogMy4gU2V0IHRoZSBsb2NhbFN0b3JhZ2UgZW50cmllc1xuICogNC4gQ2FsbCBgbG9jYXRpb24ucmVsb2FkKClgIFx1MjAxNCBPYnNpZGlhbiByZS1yZWFkcyBsb2NhbFN0b3JhZ2UgYW5kIG9wZW5zIHRoZSB2YXVsdFxuICpcbiAqIFRoaXMgYXZvaWRzIHRoZSBvbmJvYXJkaW5nIGZsb3cgZW50aXJlbHkuXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgY29kZSBjb3ZlcmVkIGJ5IGludGVncmF0aW9uIHRlc3RzLCBub3QgdW5pdCB0ZXN0cy4gKi9cblxuaW1wb3J0IHR5cGUgeyBCcm93c2VyIH0gZnJvbSAnd2ViZHJpdmVyaW8nO1xuXG5pbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHtcbiAgcm0sXG4gIHdyaXRlRmlsZVxufSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB0eXBlIHsgQ2FwdHVyZVNjcmVlbnNob3RQYXJhbXMgfSBmcm9tICcuL2NhcHR1cmUtc2NyZWVuc2hvdC5janMnO1xuaW1wb3J0IHR5cGUgeyBNb2JpbGVJbnB1dEVudmVsb3BlIH0gZnJvbSAnLi9tb2JpbGUtaW5wdXQuY2pzJztcbmltcG9ydCB0eXBlIHtcbiAgQ29uc29sZUNhcHR1cmVIYW5kbGUsXG4gIE9ic2lkaWFuVHJhbnNwb3J0LFxuICBUcmFuc3BvcnRFdmFsT3B0aW9uc1xufSBmcm9tICcuL3RyYW5zcG9ydC5janMnO1xuaW1wb3J0IHR5cGUgeyBXZWJWaWV3Q2RwQ29ubmVjdGlvbiB9IGZyb20gJy4vd2Vidmlldy1jZHAuY2pzJztcblxuaW1wb3J0IHtcbiAgZGVjb2RlQmFzZTY0UG5nLFxuICBpc1BuZ1xufSBmcm9tICcuL2NhcHR1cmUtc2NyZWVuc2hvdC5janMnO1xuaW1wb3J0IHsgZXJyb3JUb1N0cmluZyB9IGZyb20gJy4vZXJyb3ItdG8tc3RyaW5nLmNqcyc7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAnLi9leGVjLmNqcyc7XG5pbXBvcnQgeyBURU1QX1ZBVUxUX0RJUl9QUkVGSVggfSBmcm9tICcuL2xlZnRvdmVyLWNsZWFudXAuY2pzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLmNqcyc7XG5pbXBvcnQge1xuICBidWlsZFJlc29sdmVJbnB1dEV4cHJlc3Npb24sXG4gIE1PQklMRV9JTlBVVF9CSU5ESU5HX05BTUUsXG4gIHRvQ2RwSW5wdXRDb21tYW5kc1xufSBmcm9tICcuL21vYmlsZS1pbnB1dC5janMnO1xuaW1wb3J0IHsgY29ubmVjdFRvV2ViVmlld0NkcCB9IGZyb20gJy4vd2Vidmlldy1jZHAuY2pzJztcblxuLyoqXG4gKiBTZXNzaW9uIGNvbm5lY3Rpb24gaW5mbyByZXR1cm5lZCBieSB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0LmdldFNlc3Npb25JbmZvfSxcbiAqIHVzZWQgdG8gcmVhdHRhY2ggZnJvbSBhbm90aGVyIHByb2Nlc3MuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXBwaXVtU2Vzc2lvbkluZm8ge1xuICAvKipcbiAgVGhlIGRldmljZSBVRElEIChlLmcuIGAnZW11bGF0b3ItNTU1NCdgKS5cbiAgICovXG4gIGRldmljZUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBBcHBpdW0vV2ViRHJpdmVyIHNlc3Npb24gSUQuXG4gICAqL1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciB0aGUgQXBwaXVtIHRyYW5zcG9ydC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcHBpdW1UcmFuc3BvcnRDb25maWcge1xuICAvKipcbiAgICogQXBwIHBhY2thZ2UgKEFuZHJvaWQpIG9yIGJ1bmRsZSBJRCAoaU9TKS5cbiAgICogRGVmYXVsdHMgdG8gYCdtZC5vYnNpZGlhbidgLlxuICAgKi9cbiAgYXBwSWQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBBcHBpdW0gYnJvd3Nlci9kcml2ZXIgaW5zdGFuY2UuXG4gICAqIENyZWF0ZWQgYnkgdGhlIGNvbnN1bWVyIHZpYSBlLmcuIFdlYkRyaXZlcklPJ3MgYHJlbW90ZSgpYC5cbiAgICovXG4gIGJyb3dzZXI6IEJyb3dzZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBkZXZpY2UgVURJRCAoZS5nLiBgJ2VtdWxhdG9yLTU1NTQnYCkuXG4gICAqIFVzZWQgZm9yIGBhZGJgIGNvbW1hbmRzIHdoZW4gcHVzaGluZyBmaWxlcyB0byB0aGUgZGV2aWNlLlxuICAgKi9cbiAgZGV2aWNlSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB0aGlzIHRyYW5zcG9ydCBvd25zIHRoZSBBcHBpdW0gc2Vzc2lvbiBhbmQgc2hvdWxkIGRlbGV0ZSBpdCBvblxuICAgKiB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0LmRpc3Bvc2V9LlxuICAgKlxuICAgKiBgdHJ1ZWAgZm9yIHNlc3Npb25zIGNyZWF0ZWQgdmlhIGByZW1vdGUoKWAgKGdsb2JhbCBzZXR1cCkuXG4gICAqIGBmYWxzZWAgZm9yIHNlc3Npb25zIHJlYXR0YWNoZWQgdmlhIGBhdHRhY2goKWAgKHRlc3Qgd29ya2VycykuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB0cnVlYFxuICAgKi9cbiAgaXNTZXNzaW9uT3duZXI/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaW1lb3V0IGluIG1pbGxpc2Vjb25kcyBmb3Igd2FpdGluZyBmb3IgYGFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHlgIGFmdGVyXG4gICAqIHRoZSB2YXVsdCBpcyAocmUpb3BlbmVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgOTAwMDBgXG4gICAqL1xuICBsYXlvdXRSZWFkeVRpbWVvdXRJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcblxuICAvKipcbiAgICogVGFyZ2V0IHBsYXRmb3JtLiBEZXRlcm1pbmVzIFdlYlZpZXcgY29udGV4dCBuYW1pbmcgYW5kIGRldmljZSBmaWxlIHBhdGhzLlxuICAgKi9cbiAgcGxhdGZvcm06ICdhbmRyb2lkJyB8ICdpb3MnO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHJlZ2lzdGVyaW5nIGEgdmF1bHQgYWxzbyBwcnVuZXMgdGhlICoqb3RoZXIqKiBgdGVtcC12YXVsdC0qYFxuICAgKiByZWdpc3RyYXRpb25zIGVhcmxpZXIgcnVucyBsZWZ0IGluIE9ic2lkaWFuIE1vYmlsZSdzIGBsb2NhbFN0b3JhZ2VgLlxuICAgKlxuICAgKiBUaGUgZGV2aWNlLXNpZGUgZGlyZWN0b3JpZXMgYXJlIHN3ZXB0IGJlZm9yZSB0aGUgYXBwIGxhdW5jaGVzIChzZWUgdGhlXG4gICAqIGZhY3RvcnkpOyB0aGlzIHJlbW92ZXMgdGhlaXIgbm93LWRhbmdsaW5nIHJlZ2lzdHJ5IGVudHJpZXMsIHdoaWNoIGFyZSB3aGF0XG4gICAqIE9ic2lkaWFuIGFjdHVhbGx5IGVudW1lcmF0ZXMgYXQgc3RhcnR1cC4gVW5yZWdpc3RlcmluZyB0aGlzIHJ1bidzIG93biB2YXVsdFxuICAgKiBpcyB1bmFmZmVjdGVkIFx1MjAxNCB0aGF0IGFsd2F5cyBoYXBwZW5zLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgdHJ1ZWBcbiAgICovXG4gIHNob3VsZFN3ZWVwTGVmdG92ZXJzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQmFzZSBwYXRoIG9uIHRoZSBkZXZpY2Ugd2hlcmUgT2JzaWRpYW4gc3RvcmVzIHZhdWx0cy5cbiAgICpcbiAgICogRGVmYXVsdHM6XG4gICAqIC0gQW5kcm9pZDogYC9zZGNhcmQvRG9jdW1lbnRzL2BcbiAgICogLSBpT1M6IGBAbWQub2JzaWRpYW46ZG9jdW1lbnRzL2BcbiAgICovXG4gIHZhdWx0QmFzZVBhdGg/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIGZvciB3YWl0aW5nIGZvciB0aGUgV2ViVmlldyBjb250ZXh0IHRvIGJlY29tZSBhdmFpbGFibGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IGA2MDAwMGBcbiAgICovXG4gIHdlYnZpZXdUaW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG59XG5cbmNvbnN0IE5PX09VVFBVVCA9ICcobm8gb3V0cHV0KSc7XG5jb25zdCBBUFBfU1RBVEVfRk9SRUdST1VORCA9IDQ7XG5jb25zdCBXRUJWSUVXX0NPTlRFWFRfUFJFRklYID0gJ1dFQlZJRVdfbWQub2JzaWRpYW4nO1xuY29uc3QgV0VCVklFV19QT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDUwMDtcbmNvbnN0IERFRkFVTFRfV0VCVklFV19QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNjBfMDAwO1xuY29uc3QgTEFZT1VUX1JFQURZX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuY29uc3QgREVGQVVMVF9MQVlPVVRfUkVBRFlfUE9MTF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDkwXzAwMDtcbmNvbnN0IEFQUF9SRVNUQVJUX0RFTEFZX0lOX01JTExJU0VDT05EUyA9IDIwMDA7XG5jb25zdCBERUZBVUxUX0FQUF9JRCA9ICdtZC5vYnNpZGlhbic7XG5jb25zdCBBREJfVkFVTFRfUkVNT1ZFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gMzBfMDAwO1xuXG4vLyAtLS0gQ29uc29sZSBjYXB0dXJlIChMYXllciAyIG9mIHRoZSBwbHVnaW4tbG9hZCBlcnJvciBzdXJmYWNpbmcsIHNlZSBUODgpIC0tLVxuY29uc3QgQ09OU09MRV9DQVBUVVJFX01BUktFUl9UQUcgPSAnT0lUX0NBUFRVUkUnO1xuY29uc3QgQ09OU09MRV9DQVBUVVJFX1RBSUxfTUFYX0xFTkdUSCA9IDgwMDA7XG5jb25zdCBBREJfTE9HX01BUktFUl9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDUwMDA7XG5jb25zdCBMT0dDQVRfRFVNUF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDEwXzAwMDtcbi8qKlxuICogYGFkYiBsb2djYXQgLXYgdGltZWAgbGluZXMgbG9vayBsaWtlIGBNTS1ERCBISDpNTTpTUy5tbW0gTEVWRUwvVEFHKCBQSUQpOiBtZXNzYWdlYC5cbiAqIEtlZXAgb25seSB0aGUgdGFncyBDaHJvbWl1bS9XZWJWaWV3IHJvdXRlcyBKUyBgY29uc29sZS4qYCBvdXRwdXQgYW5kIHVuY2F1Z2h0XG4gKiBlcnJvcnMgdG8gKGBjaHJvbWl1bWAsIHRoZSBDYXBhY2l0b3IgY29uc29sZSBicmlkZ2UsIGFuZCBuYXRpdmUgYEFuZHJvaWRSdW50aW1lYCkuXG4gKi9cbmNvbnN0IENPTlNPTEVfQ0FQVFVSRV9UQUdfUkUgPSAvXFwvKD86Y2hyb21pdW18QW5kcm9pZFJ1bnRpbWV8Q2FwYWNpdG9yXFwvQ29uc29sZSlcXCgvO1xuXG4vKipcbiAqIEJhc2UgcGF0aCBvbiBhbiBBbmRyb2lkIGRldmljZSB3aGVyZSBPYnNpZGlhbiBNb2JpbGUgc3RvcmVzIGl0cyB2YXVsdHMuXG4gKlxuICogRXhwb3J0ZWQgYmVjYXVzZSB0aGUgdHJhbnNwb3J0IGZhY3Rvcnkgc3dlZXBzIGxlZnRvdmVyIHZhdWx0cyBmcm9tIGl0IGJlZm9yZVxuICogYSB0cmFuc3BvcnQgZXhpc3RzIChzZWUgdGhlIHJlcG8ncyBMMzEpLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9BTkRST0lEX1ZBVUxUX0JBU0VfUEFUSCA9ICcvc2RjYXJkL0RvY3VtZW50cy8nO1xuXG5jb25zdCBERUZBVUxUX1ZBVUxUX0JBU0VfUEFUSDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgYW5kcm9pZDogREVGQVVMVF9BTkRST0lEX1ZBVUxUX0JBU0VfUEFUSCxcbiAgaW9zOiAnQG1kLm9ic2lkaWFuOmRvY3VtZW50cy8nXG59O1xuXG5pbnRlcmZhY2UgTG9hZGluZ0FwcCB7XG4gIHdvcmtzcGFjZT86IExvYWRpbmdXb3Jrc3BhY2U7XG59XG5cbmludGVyZmFjZSBMb2FkaW5nV29ya3NwYWNlIHtcbiAgbGF5b3V0UmVhZHk/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFRyYW5zcG9ydCB0aGF0IGNvbW11bmljYXRlcyB3aXRoIE9ic2lkaWFuIE1vYmlsZSB2aWEgQXBwaXVtIFdlYlZpZXcgSlMgaW5qZWN0aW9uLlxuICpcbiAqIEV2YWx1YXRlcyBleHByZXNzaW9ucyBieSBzd2l0Y2hpbmcgdG8gdGhlIGBXRUJWSUVXX21kLm9ic2lkaWFuYCBjb250ZXh0IGFuZFxuICogY2FsbGluZyBgZXhlY3V0ZSgpYC4gTWFuYWdlcyB2YXVsdHMgYnkgd3JpdGluZyB0byB0aGUgV2ViVmlldydzIGBsb2NhbFN0b3JhZ2VgXG4gKiAod2hpY2ggT2JzaWRpYW4gdXNlcyBhcyBpdHMgdmF1bHQgcmVnaXN0cnkgb24gbW9iaWxlKSBhbmQgcHVzaGluZyBmaWxlcyB0byB0aGUgZGV2aWNlLlxuICovXG5leHBvcnQgY2xhc3MgQXBwaXVtVHJhbnNwb3J0IGltcGxlbWVudHMgT2JzaWRpYW5UcmFuc3BvcnQge1xuICAvKipcbiAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyB0cmFuc3BvcnQgaXMgZm9yIGEgbW9iaWxlIHBsYXRmb3JtLiBBbHdheXMgYHRydWVgIGZvciB0aGlzIHRyYW5zcG9ydC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpc01vYmlsZSA9IHRydWU7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXBwSWQ6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBicm93c2VyOiBCcm93c2VyO1xuICBwcml2YXRlIHJlYWRvbmx5IGRldmljZUlkOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgYHByb2Nlc3Mub24oJ2V4aXQnKWAgaGFuZGxlciB0aGF0IHRlYXJzIHRoZSBjaGFubmVsIGRvd24gd2hlbiBub3RoaW5nIGVsc2Ugd2lsbC5cbiAgICovXG4gIHByaXZhdGUgZGlzcG9zZUlucHV0Q2hhbm5lbE9uRXhpdDogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG4gIC8qKlxuICAgKiBUaGUgaG9zdCBoYWxmIG9mIHRoZSB0cnVzdGVkLWlucHV0IGNoYW5uZWw6IGEgQ0RQIGNvbm5lY3Rpb24gdG8gdGhlIFdlYlZpZXcsIGluZGVwZW5kZW50IG9mIHRoZVxuICAgKiBBcHBpdW0gc2Vzc2lvbiwgb3BlbmVkIGxhemlseSBvbiBmaXJzdCBldmFsdWF0ZSBhbmQgcmV1c2VkIChzZWUgKipMMzkqKikuXG4gICAqL1xuICBwcml2YXRlIGlucHV0Q2hhbm5lbDogbnVsbCB8IFdlYlZpZXdDZHBDb25uZWN0aW9uID0gbnVsbDtcbiAgLyoqXG4gICAqIFNldCBvbmNlIHRoZSB0cnVzdGVkLWlucHV0IGNoYW5uZWwgaXMga25vd24gbm90IHRvIGJlIG9wZW5hYmxlIGhlcmUgKGlPUywgYSByZW1vdGUgaHViLCBubyBsb2NhbFxuICAgKiBgYWRiYCksIHNvIHRoZSBhdHRlbXB0IGlzIG5vdCByZXBlYXRlZCBvbiBldmVyeSBldmFsdWF0ZS5cbiAgICovXG4gIHByaXZhdGUgaXNJbnB1dENoYW5uZWxVbmF2YWlsYWJsZSA9IGZhbHNlO1xuICAvKipcbiAgICogVHJhY2tzIHdoZXRoZXIgdGhlIGRyaXZlciBpcyBjdXJyZW50bHkgc3dpdGNoZWQgdG8gdGhlIFdlYlZpZXcgY29udGV4dC5cbiAgICpcbiAgICogU2V0IHRvIGB0cnVlYCBhZnRlciBhIHN1Y2Nlc3NmdWwgYHN3aXRjaENvbnRleHQoV0VCVklFV19tZC5vYnNpZGlhbilgLlxuICAgKiBSZXNldCB0byBgZmFsc2VgIHdoZW4gdGhlIGNvbnRleHQgaXMga25vd24gdG8gYmUgaW52YWxpZGF0ZWRcbiAgICogKGUuZy4gYWZ0ZXIgYGxvY2F0aW9uLnJlbG9hZCgpYCBpbiB7QGxpbmsgcmVnaXN0ZXJWYXVsdH0pLlxuICAgKlxuICAgKiBXaGVuIGB0cnVlYCwge0BsaW5rIGVuc3VyZVdlYlZpZXdDb250ZXh0fSBza2lwcyB0aGUgZXhwZW5zaXZlXG4gICAqIGBnZXRDb250ZXh0cygpYCBjYWxsICh3aGljaCBydW5zIGBhZGIgc2hlbGwgY2F0IC9wcm9jL25ldC91bml4YCBhbmRcbiAgICogY2FuIHRpbWUgb3V0IG9uIHNsb3cgZW11bGF0b3JzKS5cbiAgICovXG4gIHByaXZhdGUgaXNJbldlYlZpZXdDb250ZXh0ID0gZmFsc2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgaXNTZXNzaW9uT3duZXI6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgbGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBwbGF0Zm9ybTogJ2FuZHJvaWQnIHwgJ2lvcyc7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2hvdWxkU3dlZXBMZWZ0b3ZlcnM6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVhZG9ubHkgdmF1bHRCYXNlUGF0aDogc3RyaW5nO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgd2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IEFwcGl1bSB0cmFuc3BvcnQuXG4gICAqXG4gICAqIEBwYXJhbSBjb25maWcgLSBBcHBpdW0gdHJhbnNwb3J0IGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IoY29uZmlnOiBBcHBpdW1UcmFuc3BvcnRDb25maWcpIHtcbiAgICB0aGlzLmJyb3dzZXIgPSBjb25maWcuYnJvd3NlcjtcbiAgICB0aGlzLmRldmljZUlkID0gY29uZmlnLmRldmljZUlkO1xuICAgIHRoaXMuaXNTZXNzaW9uT3duZXIgPSBjb25maWcuaXNTZXNzaW9uT3duZXIgPz8gdHJ1ZTtcbiAgICB0aGlzLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzID0gY29uZmlnLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzID8/IERFRkFVTFRfTEFZT1VUX1JFQURZX1BPTExfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG4gICAgdGhpcy5wbGF0Zm9ybSA9IGNvbmZpZy5wbGF0Zm9ybTtcbiAgICB0aGlzLmFwcElkID0gY29uZmlnLmFwcElkID8/IERFRkFVTFRfQVBQX0lEO1xuICAgIHRoaXMuc2hvdWxkU3dlZXBMZWZ0b3ZlcnMgPSBjb25maWcuc2hvdWxkU3dlZXBMZWZ0b3ZlcnMgPz8gdHJ1ZTtcbiAgICB0aGlzLnZhdWx0QmFzZVBhdGggPSBjb25maWcudmF1bHRCYXNlUGF0aCA/PyBERUZBVUxUX1ZBVUxUX0JBU0VfUEFUSFt0aGlzLnBsYXRmb3JtXSA/PyBERUZBVUxUX0FORFJPSURfVkFVTFRfQkFTRV9QQVRIO1xuICAgIHRoaXMud2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IGNvbmZpZy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzID8/IERFRkFVTFRfV0VCVklFV19QT0xMX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICB9XG5cbiAgLyoqXG4gICAqIEJlZ2lucyBhIGNvbnNvbGUgY2FwdHVyZSBieSBzdGFtcGluZyB0aGUgZGV2aWNlIGxvZyB3aXRoIGEgdW5pcXVlIG1hcmtlci5cbiAgICpcbiAgICogVXNlcyBgYWRiIHNoZWxsIGxvZ2AgdG8gd3JpdGUgYSBtYXJrZXIgaW50byBgbG9nY2F0YCBhdCBjYXB0dXJlIHN0YXJ0IHNvIGFcbiAgICogbGF0ZXIge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5yZWFkQ29uc29sZUNhcHR1cmVTaW5jZX0gY2FuIHNsaWNlIG91dFxuICAgKiBldmVyeXRoaW5nIHRoZSBXZWJWaWV3IGxvZ2dlZCBhZnRlcndhcmRzIFx1MjAxNCB3aXRob3V0IHRoZSBpbnZhc2l2ZSBgbG9nY2F0IC1jYFxuICAgKiBidWZmZXIgY2xlYXIuXG4gICAqXG4gICAqIEByZXR1cm5zIEEgaGFuZGxlIGNhcnJ5aW5nIHRoZSB1bmlxdWUgbWFya2VyLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGJlZ2luQ29uc29sZUNhcHR1cmUoKTogUHJvbWlzZTxDb25zb2xlQ2FwdHVyZUhhbmRsZT4ge1xuICAgIGNvbnN0IG1hcmtlciA9IGAke0NPTlNPTEVfQ0FQVFVSRV9NQVJLRVJfVEFHfV8ke3JhbmRvbVVVSUQoKX1gO1xuICAgIGF3YWl0IGV4ZWMoXG4gICAgICBbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdsb2cnLCAnLXQnLCBDT05TT0xFX0NBUFRVUkVfTUFSS0VSX1RBRywgbWFya2VyXSxcbiAgICAgIHsgaXNRdWlldDogdHJ1ZSwgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWUsIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogQURCX0xPR19NQVJLRVJfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfVxuICAgICk7XG4gICAgcmV0dXJuIHsgbWFya2VyIH07XG4gIH1cblxuICAvKipcbiAgICogQ2FwdHVyZXMgYSBQTkcgc2NyZWVuc2hvdCBvZiB0aGUgZGV2aWNlJ3Mgc2NyZWVuLlxuICAgKlxuICAgKiBUaGUgaW1hZ2UgaXMgYWx3YXlzIHRoZSBkZXZpY2UncyBuYXRpdmUgZnJhbWVidWZmZXIgXHUyMDE0IHRoZXJlIGlzIG5vIG1vYmlsZVxuICAgKiBlcXVpdmFsZW50IG9mIHRoZSBkZXNrdG9wIHZpZXdwb3J0IG92ZXJyaWRlLCBzb1xuICAgKiB7QGxpbmsgQ2FwdHVyZVNjcmVlbnNob3RQYXJhbXMud2lkdGhJblBpeGVsc30gL1xuICAgKiB7QGxpbmsgQ2FwdHVyZVNjcmVlbnNob3RQYXJhbXMuaGVpZ2h0SW5QaXhlbHN9IGFyZSBpZ25vcmVkLiBTaXplIGEgbW9iaWxlXG4gICAqIGNhcHR1cmUgYnkgY2hvb3NpbmcgYW4gQVZEIHdob3NlIHNjcmVlbiBnZW9tZXRyeSBhbHJlYWR5IG1hdGNoZXMgd2hhdCB0aGVcbiAgICogaW1hZ2UgaGFzIHRvIGJlLlxuICAgKlxuICAgKiBAcGFyYW0gX3BhcmFtcyAtIENhcHR1cmUgcGFyYW1ldGVycy4gSWdub3JlZCBvbiBtb2JpbGU6IGBjd2RgIGRvZXMgbm90IHNlbGVjdCBhIHdpbmRvdyAodmF1bHQgdGFyZ2V0aW5nIGlzIHZpYSBsb2NhbFN0b3JhZ2UpLCBhbmQgdGhlIHNpemUgY2Fubm90IGJlIG92ZXJyaWRkZW4uXG4gICAqIEByZXR1cm5zIFRoZSByYXcgUE5HIGJ5dGVzLlxuICAgKiBAdGhyb3dzIEVycm9yIGlmIHRoZSBkcml2ZXIgcmV0dXJucyBkYXRhIHRoYXQgaXMgbm90IGEgUE5HLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGNhcHR1cmVTY3JlZW5zaG90KF9wYXJhbXM6IENhcHR1cmVTY3JlZW5zaG90UGFyYW1zKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gICAgY29uc3QgYnl0ZXMgPSBkZWNvZGVCYXNlNjRQbmcoYXdhaXQgdGhpcy5icm93c2VyLnRha2VTY3JlZW5zaG90KCkpO1xuICAgIGlmICghaXNQbmcoYnl0ZXMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FwcGl1bSBzY3JlZW5zaG90IGVycm9yOiB0YWtlU2NyZWVuc2hvdCByZXR1cm5lZCBkYXRhIHRoYXQgaXMgbm90IGEgUE5HLicpO1xuICAgIH1cblxuICAgIHJldHVybiBieXRlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmRzIHRoZSBBcHBpdW0gc2Vzc2lvbi5cbiAgICpcbiAgICogT25seSBkZWxldGVzIHRoZSBzZXNzaW9uIGlmIHRoaXMgdHJhbnNwb3J0IG93bnMgaXQuIFRyYW5zcG9ydHMgY3JlYXRlZFxuICAgKiB2aWEgYGF0dGFjaCgpYCAodGVzdCB3b3JrZXJzIHJldXNpbmcgdGhlIGdsb2JhbCBzZXR1cCdzIHNlc3Npb24pIHNraXBcbiAgICogZGVsZXRpb24gc28gdGhlIHNlc3Npb24gcmVtYWlucyBhdmFpbGFibGUgZm9yIHRoZSBvd25pbmcgcHJvY2Vzcy5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuZGlzcG9zZUlucHV0Q2hhbm5lbCgpO1xuXG4gICAgaWYgKHRoaXMuaXNTZXNzaW9uT3duZXIpIHtcbiAgICAgIGF3YWl0IHRoaXMuYnJvd3Nlci5kZWxldGVTZXNzaW9uKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN5bmNocm9ub3VzIHRlYXJkb3duIGZvciBgcHJvY2Vzcy5vbignZXhpdCcpYCBoYW5kbGVycy5cbiAgICpcbiAgICogT25seSB0aGUgdHJ1c3RlZC1pbnB1dCBjaGFubmVsIG5lZWRzIGl0OiB0aGUgQXBwaXVtIHNlc3Npb24gaXMgdGhlIG93bmluZyBwcm9jZXNzJ3MgdG8gZW5kLCBhbmQgYW5cbiAgICogYWJydXB0IGV4aXQgaXMgZXhhY3RseSB3aGVuIHRoZSBhc3luYyB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0LmRpc3Bvc2V9IG5ldmVyIHJ1bnMgXHUyMDE0IHdoaWNoIHdvdWxkIHN0cmFuZFxuICAgKiB0aGUgYWRiIHBvcnQgZm9yd2FyZCBvbiB0aGUgZGV2aWNlLlxuICAgKi9cbiAgcHVibGljIGRpc3Bvc2VTeW5jKCk6IHZvaWQge1xuICAgIGNvbnN0IGNoYW5uZWwgPSB0aGlzLmlucHV0Q2hhbm5lbDtcbiAgICB0aGlzLmlucHV0Q2hhbm5lbCA9IG51bGw7XG4gICAgdGhpcy51bnJlZ2lzdGVySW5wdXRDaGFubmVsRXhpdEhhbmRsZXIoKTtcbiAgICBjaGFubmVsPy5kaXNwb3NlU3luYygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV2YWx1YXRlcyBhIEphdmFTY3JpcHQgZXhwcmVzc2lvbiBpbnNpZGUgT2JzaWRpYW4gTW9iaWxlJ3MgV2ViVmlldy5cbiAgICpcbiAgICogU3dpdGNoZXMgdG8gdGhlIGBXRUJWSUVXX21kLm9ic2lkaWFuYCBjb250ZXh0LCBleGVjdXRlcyB0aGUgZXhwcmVzc2lvbixcbiAgICogYW5kIHJldHVybnMgdGhlIHJlc3VsdCBzdHJpbmcuXG4gICAqXG4gICAqIEBwYXJhbSBleHByZXNzaW9uIC0gVGhlIEphdmFTY3JpcHQgZXhwcmVzc2lvbiB0byBldmFsdWF0ZS5cbiAgICogQHBhcmFtIF9vcHRpb25zIC0gRXZhbHVhdGlvbiBvcHRpb25zIChjd2QgaXMgbm90IHVzZWQgb24gbW9iaWxlIFx1MjAxNCB2YXVsdCB0YXJnZXRpbmcgaXMgdmlhIGxvY2FsU3RvcmFnZSkuXG4gICAqIEByZXR1cm5zIFRoZSBub3JtYWxpemVkIHJlc3VsdCBzdHJpbmcuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZXZhbHVhdGUoZXhwcmVzc2lvbjogc3RyaW5nLCBfb3B0aW9uczogVHJhbnNwb3J0RXZhbE9wdGlvbnMpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlV2ViVmlld0NvbnRleHQoKTtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZUlucHV0Q2hhbm5lbCgpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuYnJvd3Nlci5leGVjdXRlPG51bGwgfCBzdHJpbmcgfCB1bmRlZmluZWQsIFtdPihcbiAgICAgICAgYHJldHVybiAoJHtleHByZXNzaW9ufSlgXG4gICAgICApO1xuXG4gICAgICBpZiAocmVzdWx0ID09PSB1bmRlZmluZWQgfHwgcmVzdWx0ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBOT19PVVRQVVQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIC8vIENvbnRleHQgbWF5IGhhdmUgYmVlbiBsb3N0IG1pZC1leGVjdXRpb24gKGUuZy4gcGFnZSByZWxvYWQpLlxuICAgICAgdGhpcy5pc0luV2ViVmlld0NvbnRleHQgPSBmYWxzZTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBzZXNzaW9uIGNvbm5lY3Rpb24gaW5mbyBuZWVkZWQgdG8gcmVhdHRhY2ggdG8gdGhpcyBzZXNzaW9uXG4gICAqIGZyb20gYW5vdGhlciBwcm9jZXNzIChlLmcuIGEgdGVzdCB3b3JrZXIpLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgc2Vzc2lvbiBJRCBhbmQgZGV2aWNlIElELlxuICAgKi9cbiAgcHVibGljIGdldFNlc3Npb25JbmZvKCk6IEFwcGl1bVNlc3Npb25JbmZvIHtcbiAgICByZXR1cm4ge1xuICAgICAgZGV2aWNlSWQ6IHRoaXMuZGV2aWNlSWQsXG4gICAgICBzZXNzaW9uSWQ6IHRoaXMuYnJvd3Nlci5zZXNzaW9uSWRcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWVzIHRoYXQgdGhlIE9ic2lkaWFuIGFwcCBpcyBydW5uaW5nIGFuZCB0aGUgV2ViVmlldyBpcyBhdmFpbGFibGUuXG4gICAqXG4gICAqIEBwYXJhbSBfdmF1bHRQYXRoIC0gTm90IHVzZWQgb24gbW9iaWxlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHByZWZsaWdodENoZWNrKF92YXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZygnW2FwcGl1bS10cmFuc3BvcnRdIFJ1bm5pbmcgcHJlZmxpZ2h0IGNoZWNrLi4uJyk7XG4gICAgY29uc3Qgc3RhdGUgPSBhd2FpdCB0aGlzLmJyb3dzZXIucXVlcnlBcHBTdGF0ZSh0aGlzLmFwcElkKTtcbiAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBBcHAgc3RhdGU6ICR7U3RyaW5nKHN0YXRlKX0gKG5lZWQgJHtTdHJpbmcoQVBQX1NUQVRFX0ZPUkVHUk9VTkQpfT1mb3JlZ3JvdW5kKWApO1xuICAgIGlmIChzdGF0ZSAhPT0gQVBQX1NUQVRFX0ZPUkVHUk9VTkQpIHtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIEFjdGl2YXRpbmcgYXBwICR7dGhpcy5hcHBJZH0uLi5gKTtcbiAgICAgIHRoaXMuaXNJbldlYlZpZXdDb250ZXh0ID0gZmFsc2U7XG4gICAgICBhd2FpdCB0aGlzLmJyb3dzZXIuYWN0aXZhdGVBcHAodGhpcy5hcHBJZCk7XG4gICAgICBhd2FpdCBkZWxheShBUFBfUkVTVEFSVF9ERUxBWV9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuZW5zdXJlV2ViVmlld0NvbnRleHQoKTtcbiAgICBsb2coJ1thcHBpdW0tdHJhbnNwb3J0XSBQcmVmbGlnaHQgY2hlY2sgcGFzc2VkLicpO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1c2hlcyB2YXVsdCBmaWxlcyB0byB0aGUgZGV2aWNlIHZpYSBjb21wcmVzc2VkIGBhZGIgcHVzaGAuXG4gICAqXG4gICAqIENyZWF0ZXMgYSB0YXIuZ3ogYXJjaGl2ZSBvZiB0aGUgbG9jYWwgdmF1bHQgZGlyZWN0b3J5LCBwdXNoZXMgaXQgdG8gdGhlXG4gICAqIGRldmljZSBhcyBhIHNpbmdsZSBmaWxlLCBhbmQgZXh0cmFjdHMgaXQgaW4tcGxhY2UuIFRoaXMgYXZvaWRzIHRoZVxuICAgKiB3ZWJkcml2ZXIgYFJhbmdlRXJyb3JgIG9uIGxhcmdlIGJhc2U2NCBwYXlsb2FkcyBhbmQgaXMgc2lnbmlmaWNhbnRseVxuICAgKiBmYXN0ZXIgdGhhbiBwZXItZmlsZSBgYnJvd3Nlci5wdXNoRmlsZSgpYCBjYWxscy5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSB2YXVsdCBwYXRoICh1c2VkIGFzIHRoZSB2YXVsdCBkaXJlY3RvcnkgbmFtZSBvbiBkZXZpY2UpLlxuICAgKiBAcGFyYW0gX2ZpbGVzIC0gTWFwIG9mIHJlbGF0aXZlIGZpbGUgcGF0aHMgdG8gY29udGVudCBidWZmZXJzICh1bnVzZWQgXHUyMDE0IGFkYiBwdXNoZXMgdGhlIGRpcmVjdG9yeSBkaXJlY3RseSkuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcHVzaEZpbGVzKHZhdWx0UGF0aDogc3RyaW5nLCBfZmlsZXM6IFJlY29yZDxzdHJpbmcsIFVpbnQ4QXJyYXk+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZGV2aWNlVmF1bHRQYXRoID0gdGhpcy5nZXREZXZpY2VWYXVsdFBhdGgodmF1bHRQYXRoKTtcbiAgICBjb25zdCBhcmNoaXZlTmFtZSA9IGB2YXVsdC0ke3JhbmRvbVVVSUQoKX0udGFyLmd6YDtcbiAgICBjb25zdCBsb2NhbEFyY2hpdmUgPSBqb2luKHRtcGRpcigpLCBhcmNoaXZlTmFtZSk7XG4gICAgY29uc3QgcmVtb3RlQXJjaGl2ZSA9IGAvZGF0YS9sb2NhbC90bXAvJHthcmNoaXZlTmFtZX1gO1xuXG4gICAgdHJ5IHtcbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIENyZWF0aW5nIGFyY2hpdmU6ICR7bG9jYWxBcmNoaXZlfWApO1xuICAgICAgYXdhaXQgZXhlYyhbJ3RhcicsICdjemYnLCBhcmNoaXZlTmFtZSwgJy1DJywgdmF1bHRQYXRoLCAnLiddLCB7IGN3ZDogdG1wZGlyKCksIGlzUXVpZXQ6IHRydWUgfSk7XG5cbiAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIFB1c2hpbmcgYXJjaGl2ZSB0byBkZXZpY2UgJHt0aGlzLmRldmljZUlkfS4uLmApO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdwdXNoJywgbG9jYWxBcmNoaXZlLCByZW1vdGVBcmNoaXZlXSwgeyBpc1F1aWV0OiB0cnVlIH0pO1xuXG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBFeHRyYWN0aW5nIGFyY2hpdmUgb24gZGV2aWNlIGF0ICR7ZGV2aWNlVmF1bHRQYXRofS4uLmApO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdta2RpcicsICctcCcsIGRldmljZVZhdWx0UGF0aF0sIHsgaXNRdWlldDogdHJ1ZSB9KTtcbiAgICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAndGFyJywgJ3h6ZicsIHJlbW90ZUFyY2hpdmUsICctQycsIGRldmljZVZhdWx0UGF0aF0sIHsgaXNRdWlldDogdHJ1ZSB9KTtcblxuICAgICAgbG9nKCdbYXBwaXVtLXRyYW5zcG9ydF0gRmx1c2hpbmcgZmlsZXN5c3RlbSBidWZmZXJzLi4uJyk7XG4gICAgICBhd2FpdCBleGVjKFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3NoZWxsJywgJ3N5bmMnXSwgeyBpc1F1aWV0OiB0cnVlIH0pO1xuXG4gICAgICBsb2coJ1thcHBpdW0tdHJhbnNwb3J0XSBDbGVhbmluZyB1cCByZW1vdGUgYXJjaGl2ZS4uLicpO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdybScsIHJlbW90ZUFyY2hpdmVdLCB7IGlzUXVpZXQ6IHRydWUgfSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHJtKGxvY2FsQXJjaGl2ZSwgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRHVtcHMgYGFkYiBsb2djYXRgIGFuZCByZXR1cm5zIHRoZSBXZWJWaWV3IGNvbnNvbGUvZXJyb3Igb3V0cHV0IGxvZ2dlZFxuICAgKiBzaW5jZSB0aGUgbWFya2VyIGZyb20ge0BsaW5rIEFwcGl1bVRyYW5zcG9ydC5iZWdpbkNvbnNvbGVDYXB0dXJlfS5cbiAgICpcbiAgICogRmlsdGVycyB0byB0aGUgQ2hyb21pdW0vV2ViVmlldyB0YWdzIHRoYXQgY2FycnkgSlMgYGNvbnNvbGUuKmAgb3V0cHV0IGFuZFxuICAgKiB1bmNhdWdodCBlcnJvcnMsIGFuZCBjYXBzIHRoZSByZXN1bHQgbGVuZ3RoLiBCb3VuZGVkLCBwb3N0LWhvYyxcbiAgICogZmFpbHVyZS1wYXRoLW9ubHkgXHUyMDE0IG5ldmVyIGEgbGl2ZSBtb25pdG9yLlxuICAgKlxuICAgKiBAcGFyYW0gaGFuZGxlIC0gVGhlIGNhcHR1cmUgaGFuZGxlIChvciBgdW5kZWZpbmVkYCB3aGVuIGNhcHR1cmUgbmV2ZXIgc3RhcnRlZCkuXG4gICAqIEByZXR1cm5zIFRoZSBjYXB0dXJlZCBjb25zb2xlL2Vycm9yIHRleHQsIG9yIGB1bmRlZmluZWRgIGlmIG5vdGhpbmcgcmVsZXZhbnQgd2FzIGxvZ2dlZC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyByZWFkQ29uc29sZUNhcHR1cmVTaW5jZShoYW5kbGU6IENvbnNvbGVDYXB0dXJlSGFuZGxlIHwgdW5kZWZpbmVkKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICBpZiAoIWhhbmRsZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBkdW1wID0gYXdhaXQgZXhlYyhcbiAgICAgIFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ2xvZ2NhdCcsICctZCcsICctdicsICd0aW1lJ10sXG4gICAgICB7IGlzUXVpZXQ6IHRydWUsIHNob3VsZElnbm9yZUV4aXRDb2RlOiB0cnVlLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IExPR0NBVF9EVU1QX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTIH1cbiAgICApO1xuXG4gICAgY29uc3QgbWFya2VySW5kZXggPSBkdW1wLmxhc3RJbmRleE9mKGhhbmRsZS5tYXJrZXIpO1xuICAgIGNvbnN0IHJlZ2lvbiA9IG1hcmtlckluZGV4ID09PSAtMSA/IGR1bXAgOiBkdW1wLnNsaWNlKG1hcmtlckluZGV4ICsgaGFuZGxlLm1hcmtlci5sZW5ndGgpO1xuICAgIGNvbnN0IHJlbGV2YW50ID0gcmVnaW9uXG4gICAgICAuc3BsaXQoJ1xcbicpXG4gICAgICAuZmlsdGVyKChsaW5lKSA9PiBDT05TT0xFX0NBUFRVUkVfVEFHX1JFLnRlc3QobGluZSkpXG4gICAgICAuam9pbignXFxuJylcbiAgICAgIC50cmltKCk7XG5cbiAgICBpZiAoIXJlbGV2YW50KSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiByZWxldmFudC5zbGljZSgtQ09OU09MRV9DQVBUVVJFX1RBSUxfTUFYX0xFTkdUSCk7XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGEgdmF1bHQgb24gbW9iaWxlIGJ5IHB1c2hpbmcgZmlsZXMgYW5kIGNvbmZpZ3VyaW5nIGxvY2FsU3RvcmFnZS5cbiAgICpcbiAgICogVGhlIHJlZ2lzdHJhdGlvbiBmbG93OlxuICAgKiAxLiBQdXNoIGEgbWluaW1hbCBgLm9ic2lkaWFuL2FwcC5qc29uYCB0byB0aGUgZGV2aWNlIHNvIE9ic2lkaWFuIHJlY29nbml6ZXMgdGhlIHZhdWx0XG4gICAqIDIuIFN3aXRjaCB0byB0aGUgV2ViVmlldyBjb250ZXh0XG4gICAqIDMuIEFkZCB0aGUgdmF1bHQgdG8gbG9jYWxTdG9yYWdlIChgbW9iaWxlLWV4dGVybmFsLXZhdWx0c2AsIGBtb2JpbGUtc2VsZWN0ZWQtdmF1bHRgLFxuICAgKiAgICBgZW5hYmxlLXBsdWdpbi08cGF0aD5gKVxuICAgKiA0LiBUcmlnZ2VyIGBsb2NhdGlvbi5yZWxvYWQoKWAgc28gT2JzaWRpYW4gcmUtcmVhZHMgbG9jYWxTdG9yYWdlIGFuZCBvcGVucyB0aGUgdmF1bHRcbiAgICogNS4gV2FpdCBmb3IgYGFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHlgXG4gICAqXG4gICAqIEV4aXN0aW5nIHZhdWx0IHJlZ2lzdHJhdGlvbnMgaW4gbG9jYWxTdG9yYWdlIGFyZSBwcmVzZXJ2ZWQgKGFwcGVuZCwgbm90XG4gICAqIG92ZXJ3cml0ZSkgXHUyMDE0IGV4Y2VwdCB0aGUgKipoYXJuZXNzJ3Mgb3duKiogYHRlbXAtdmF1bHQtKmAgcmVnaXN0cmF0aW9ucyBmcm9tXG4gICAqIGVhcmxpZXIgcnVucywgd2hpY2ggYXJlIHBydW5lZCB3aGVuIHtAbGluayBBcHBpdW1UcmFuc3BvcnRDb25maWcuc2hvdWxkU3dlZXBMZWZ0b3ZlcnN9XG4gICAqIGlzIG9uLiBUaGVpciBkaXJlY3RvcmllcyBhcmUgYWxyZWFkeSBnb25lICh0aGUgZmFjdG9yeSBzd2VlcHMgdGhlbSBiZWZvcmVcbiAgICogdGhlIGFwcCBsYXVuY2hlcyksIGFuZCBpdCBpcyB0aGlzIHJlZ2lzdHJ5IFx1MjAxNCBub3QgdGhlIGZpbGVzeXN0ZW0gXHUyMDE0IHRoYXRcbiAgICogT2JzaWRpYW4gZW51bWVyYXRlcyBhdCBzdGFydHVwLCBzbyBsZWF2aW5nIHRoZW0gaXMgd2hhdCBtYWtlcyBlYWNoIGZhaWxlZFxuICAgKiBydW4gc2xvdyB0aGUgbmV4dCBvbmUgZG93bi5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSB2YXVsdCBvbiB0aGUgaG9zdCBtYWNoaW5lLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHJlZ2lzdGVyVmF1bHQodmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBSZWdpc3RlcmluZyB2YXVsdDogJHt2YXVsdFBhdGh9YCk7XG4gICAgY29uc3QgZGV2aWNlVmF1bHRQYXRoID0gdGhpcy5nZXREZXZpY2VWYXVsdFBhdGgodmF1bHRQYXRoKTtcblxuICAgIC8vIFB1c2ggYSBtaW5pbWFsIC5vYnNpZGlhbiBkaXJlY3Rvcnkgc28gT2JzaWRpYW4gcmVjb2duaXplcyBpdCBhcyBhIHZhdWx0LlxuICAgIGF3YWl0IHRoaXMucHVzaE9ic2lkaWFuTWFya2VyKGRldmljZVZhdWx0UGF0aCk7XG5cbiAgICAvLyBTd2l0Y2ggdG8gV2ViVmlldyBhbmQgY29uZmlndXJlIGxvY2FsU3RvcmFnZS5cbiAgICBhd2FpdCB0aGlzLmVuc3VyZVdlYlZpZXdDb250ZXh0KCk7XG5cbiAgICAvLyBJbnZhbGlkYXRlIGJlZm9yZSByZWxvYWQgXHUyMDE0IHRoZSBwYWdlIHdpbGwgbmF2aWdhdGUgYW5kIHRoZSBXZWJWaWV3XG4gICAgLy8gQ29udGV4dCBtYXkgYmUgdGVtcG9yYXJpbHkgdW5hdmFpbGFibGUgZHVyaW5nIHJlbG9hZC5cbiAgICB0aGlzLmlzSW5XZWJWaWV3Q29udGV4dCA9IGZhbHNlO1xuXG4gICAgY29uc3Qgc3RhbGVQcmVmaXggPSB0aGlzLnNob3VsZFN3ZWVwTGVmdG92ZXJzID8gYCR7dGhpcy52YXVsdEJhc2VQYXRofSR7VEVNUF9WQVVMVF9ESVJfUFJFRklYfWAgOiAnJztcblxuICAgIGF3YWl0IHRoaXMuYnJvd3Nlci5leGVjdXRlKFxuICAgICAgKHBhdGg6IHN0cmluZywgcHJ1bmVQcmVmaXg6IHN0cmluZykgPT4ge1xuICAgICAgICBsZXQgZXhpc3RpbmcgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzJykgPz8gJ1tdJykgYXMgc3RyaW5nW107XG5cbiAgICAgICAgaWYgKHBydW5lUHJlZml4KSB7XG4gICAgICAgICAgY29uc3Qgc3RhbGUgPSBleGlzdGluZy5maWx0ZXIoKHJlZ2lzdGVyZWQpID0+IHJlZ2lzdGVyZWQgIT09IHBhdGggJiYgcmVnaXN0ZXJlZC5zdGFydHNXaXRoKHBydW5lUHJlZml4KSk7XG4gICAgICAgICAgZm9yIChjb25zdCByZWdpc3RlcmVkIG9mIHN0YWxlKSB7XG4gICAgICAgICAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShgZW5hYmxlLXBsdWdpbi0ke3JlZ2lzdGVyZWR9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGV4aXN0aW5nID0gZXhpc3RpbmcuZmlsdGVyKChyZWdpc3RlcmVkKSA9PiAhc3RhbGUuaW5jbHVkZXMocmVnaXN0ZXJlZCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFleGlzdGluZy5pbmNsdWRlcyhwYXRoKSkge1xuICAgICAgICAgIGV4aXN0aW5nLnB1c2gocGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ21vYmlsZS1leHRlcm5hbC12YXVsdHMnLCBKU09OLnN0cmluZ2lmeShleGlzdGluZykpO1xuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnbW9iaWxlLXNlbGVjdGVkLXZhdWx0JywgcGF0aCk7XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKGBlbmFibGUtcGx1Z2luLSR7cGF0aH1gLCAndHJ1ZScpO1xuICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgIH0sXG4gICAgICBkZXZpY2VWYXVsdFBhdGgsXG4gICAgICBzdGFsZVByZWZpeFxuICAgICk7XG5cbiAgICAvLyBXYWl0IGZvciByZWxvYWQgKyB2YXVsdCBpbml0aWFsaXphdGlvbi5cbiAgICBhd2FpdCB0aGlzLndhaXRGb3JMYXlvdXRSZWFkeSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucmVnaXN0ZXJzIGEgdmF1bHQgb24gbW9iaWxlIGJ5IHJlbW92aW5nIGl0IGZyb20gbG9jYWxTdG9yYWdlLlxuICAgKlxuICAgKiBQcmVzZXJ2ZXMgb3RoZXIgdmF1bHQgcmVnaXN0cmF0aW9ucy4gSWYgdGhlIHVucmVnaXN0ZXJlZCB2YXVsdCB3YXMgc2VsZWN0ZWQsXG4gICAqIHN3aXRjaGVzIHRvIHRoZSBmaXJzdCByZW1haW5pbmcgdmF1bHQgKG9yIGNsZWFycyB0aGUgc2VsZWN0aW9uKS5cbiAgICpcbiAgICogVGhlIHZhdWx0J3MgKipmaWxlcyBhcmUgdGhlbiByZW1vdmVkIGZyb20gdGhlIGRldmljZSBvdmVyIGBhZGJgLCB3aGV0aGVyIG9yXG4gICAqIG5vdCB0aGUgYGxvY2FsU3RvcmFnZWAgc3RlcCBzdWNjZWVkZWQqKiBcdTIwMTQgZGVsaWJlcmF0ZWx5LCBiZWNhdXNlIHRoZVxuICAgKiBgbG9jYWxTdG9yYWdlYCBzdGVwIGdvZXMgdGhyb3VnaCB0aGUgV2ViVmlldyBhbmQgYSBkZWFkIFdlYlZpZXcgaXMgZXhhY3RseVxuICAgKiB3aGF0IG1vc3QgQW5kcm9pZCBmYWlsdXJlcyBhcmUuIFJvdXRpbmcgdGhlIHJlbW92YWwgdGhyb3VnaCB0aGUgYXBwIHdhcyB3aGF0XG4gICAqIG1hZGUgZXZlcnkgZmFpbGVkIHJ1biBsZWFrIGl0cyB2YXVsdCAoYFZhdWx0IGNsZWFudXAgZXJyb3IgKG5vbi1mYXRhbCk6IG5vXG4gICAqIHN1Y2ggd2luZG93YCksIHNvIHRoZSBmaWxlc3lzdGVtLWxldmVsIHJlbW92YWwgbXVzdCBub3QgZGVwZW5kIG9uIGl0LlxuICAgKlxuICAgKiBAcGFyYW0gdmF1bHRQYXRoIC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIHZhdWx0IG9uIHRoZSBob3N0IG1hY2hpbmUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdW5yZWdpc3RlclZhdWx0KHZhdWx0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZGV2aWNlVmF1bHRQYXRoID0gdGhpcy5nZXREZXZpY2VWYXVsdFBhdGgodmF1bHRQYXRoKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmVuc3VyZVdlYlZpZXdDb250ZXh0KCk7XG5cbiAgICAgIGF3YWl0IHRoaXMuYnJvd3Nlci5leGVjdXRlKChwYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdtb2JpbGUtZXh0ZXJuYWwtdmF1bHRzJykgPz8gJ1tdJykgYXMgc3RyaW5nW107XG4gICAgICAgIGNvbnN0IGZpbHRlcmVkID0gZXhpc3RpbmcuZmlsdGVyKCh2KSA9PiB2ICE9PSBwYXRoKTtcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ21vYmlsZS1leHRlcm5hbC12YXVsdHMnLCBKU09OLnN0cmluZ2lmeShmaWx0ZXJlZCkpO1xuICAgICAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShgZW5hYmxlLXBsdWdpbi0ke3BhdGh9YCk7XG4gICAgICAgIGlmIChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnbW9iaWxlLXNlbGVjdGVkLXZhdWx0JykgPT09IHBhdGgpIHtcbiAgICAgICAgICBpZiAoZmlsdGVyZWQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ21vYmlsZS1zZWxlY3RlZC12YXVsdCcsIGZpbHRlcmVkWzBdID8/ICcnKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oJ21vYmlsZS1zZWxlY3RlZC12YXVsdCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSwgZGV2aWNlVmF1bHRQYXRoKTtcbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgbG9nKFxuICAgICAgICBgW2FwcGl1bS10cmFuc3BvcnRdIENvdWxkIG5vdCBkZXJlZ2lzdGVyICR7ZGV2aWNlVmF1bHRQYXRofSBmcm9tIGxvY2FsU3RvcmFnZSBgXG4gICAgICAgICAgKyBgKCR7U3RyaW5nKGVycm9yKX0pOyByZW1vdmluZyBpdHMgZmlsZXMgYW55d2F5LmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5yZW1vdmVEZXZpY2VWYXVsdERpcmVjdG9yeShkZXZpY2VWYXVsdFBhdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlcyB0aGUgdHJ1c3RlZC1pbnB1dCBjaGFubmVsLCBpZiBvbmUgaXMgb3Blbi5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZGlzcG9zZUlucHV0Q2hhbm5lbCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjaGFubmVsID0gdGhpcy5pbnB1dENoYW5uZWw7XG4gICAgdGhpcy5pbnB1dENoYW5uZWwgPSBudWxsO1xuICAgIHRoaXMudW5yZWdpc3RlcklucHV0Q2hhbm5lbEV4aXRIYW5kbGVyKCk7XG4gICAgYXdhaXQgY2hhbm5lbD8uZGlzcG9zZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE9wZW5zIHRoZSB0cnVzdGVkLWlucHV0IGNoYW5uZWwgaWYgaXQgaXMgbm90IGFscmVhZHkgb3BlbiwgYW5kIHJlLW9wZW5zIGl0IGlmIHRoZSBXZWJWaWV3IHdlbnQgYXdheS5cbiAgICpcbiAgICogSW5zdGFsbHMgYSBgUnVudGltZS5hZGRCaW5kaW5nYCBmdW5jdGlvbiBvbiB0aGUgcGFnZSBhbmQgc2VydmljZXMgZXZlcnkgY2FsbCB0byBpdCBmb3IgdGhlIGxpZmUgb2YgdGhlXG4gICAqIGNvbm5lY3Rpb24uIFRoZSBiaW5kaW5nIGlzIGV4cG9zZWQgb24gKmV2ZXJ5KiBleGVjdXRpb24gY29udGV4dCBvZiB0aGUgcGFnZSwgc28gaXQgc3Vydml2ZXMgdGhlXG4gICAqIGBsb2NhdGlvbi5yZWxvYWQoKWAgdGhhdCB7QGxpbmsgQXBwaXVtVHJhbnNwb3J0LnJlZ2lzdGVyVmF1bHR9IHBlcmZvcm1zOyBvbmx5IGEgZnVsbCBhcHAgcmVzdGFydCwgd2hpY2hcbiAgICogZGVzdHJveXMgdGhlIFdlYlZpZXcgdGFyZ2V0LCBuZWVkcyB0aGUgcmVjb25uZWN0IGJlbG93LlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVJbnB1dENoYW5uZWwoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuaW5wdXRDaGFubmVsPy5pc09wZW4gfHwgdGhpcy5pc0lucHV0Q2hhbm5lbFVuYXZhaWxhYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gVGhlIGNoYW5uZWwgaXMgcmVhY2hhYmxlIG9ubHkgb3ZlciBsb2NhbCBgYWRiYCwgc28gaXQgZG9lcyBub3QgZXhpc3Qgb24gaU9TIG9yIGFnYWluc3QgYSByZW1vdGUgaHViXG4gICAgLy8gKEJyb3dzZXJTdGFjaykuIFRob3NlIGFyZSBzdXBwb3J0ZWQgdHJhbnNwb3J0cywgc28gdGhpcyBzdGF5cyAqKmJlc3QtZWZmb3J0Kio6IGEgcnVuIHRoYXQgbmV2ZXJcbiAgICAvLyBEcml2ZXMgaW5wdXQgbXVzdCBub3QgZmFpbCBiZWNhdXNlIHRoZSBjaGFubmVsIGNvdWxkIG5vdCBiZSBvcGVuZWQuIEEgcnVuIHRoYXQgKmRvZXMqIGRyaXZlIGlucHV0XG4gICAgLy8gR2V0cyBhIGxlZ2libGUgZXJyb3IgZnJvbSB0aGUgcmVuZGVyZXIncyBvd24gZ3VhcmQsIHdoaWNoIG5hbWVzIHRoZSBtaXNzaW5nIGNoYW5uZWwuXG4gICAgaWYgKHRoaXMucGxhdGZvcm0gIT09ICdhbmRyb2lkJykge1xuICAgICAgdGhpcy5pc0lucHV0Q2hhbm5lbFVuYXZhaWxhYmxlID0gdHJ1ZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLmRpc3Bvc2VJbnB1dENoYW5uZWwoKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb25uZWN0aW9uID0gYXdhaXQgY29ubmVjdFRvV2ViVmlld0NkcCh7IGFwcElkOiB0aGlzLmFwcElkLCBkZXZpY2VJZDogdGhpcy5kZXZpY2VJZCB9KTtcbiAgICAgIGF3YWl0IGNvbm5lY3Rpb24uc2VuZCgnUnVudGltZS5lbmFibGUnKTtcbiAgICAgIGF3YWl0IGNvbm5lY3Rpb24uc2VuZCgnUnVudGltZS5hZGRCaW5kaW5nJywgeyBuYW1lOiBNT0JJTEVfSU5QVVRfQklORElOR19OQU1FIH0pO1xuICAgICAgY29ubmVjdGlvbi5vbignUnVudGltZS5iaW5kaW5nQ2FsbGVkJywgKHBhcmFtczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHtcbiAgICAgICAgaWYgKHBhcmFtc1snbmFtZSddICE9PSBNT0JJTEVfSU5QVVRfQklORElOR19OQU1FKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IHBhcmFtc1sncGF5bG9hZCddO1xuICAgICAgICAvLyBEZWxpYmVyYXRlbHkgbm90IGF3YWl0ZWQ6IHRoaXMgcnVucyB3aGlsZSB0aGUgcmVuZGVyZXIncyBgRXhlY3V0ZSBTY3JpcHRgIGlzIHN0aWxsIHBlbmRpbmcsIGFuZFxuICAgICAgICAvLyBUaGF0IGlzIHRoZSB3aG9sZSBwb2ludCBcdTIwMTQgdGhlIHJlcXVlc3QgaXMgc2VydmljZWQgY29uY3VycmVudGx5IGFuZCBhbnN3ZXJlZCBieSByZXNvbHZpbmcgdGhlXG4gICAgICAgIC8vIFJlbmRlcmVyJ3MgcHJvbWlzZSBvdmVyIHRoaXMgc2FtZSBzb2NrZXQuIEl0IGhhbmRsZXMgaXRzIG93biBmYWlsdXJlcywgc28gbm90aGluZyByZWFjaGVzIGhlcmUuXG4gICAgICAgIHRoaXMuaGFuZGxlSW5wdXRSZXF1ZXN0KGNvbm5lY3Rpb24sIHR5cGVvZiBwYXlsb2FkID09PSAnc3RyaW5nJyA/IHBheWxvYWQgOiAnJykuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgIC8vIFVucmVhY2hhYmxlOiBgaGFuZGxlSW5wdXRSZXF1ZXN0YCBuZXZlciByZWplY3RzLlxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLmlucHV0Q2hhbm5lbCA9IGNvbm5lY3Rpb247XG5cbiAgICAgIC8vIFNlbGYtY2xlYW5pbmcsIGRlbGliZXJhdGVseTogdGhpcyB0cmFuc3BvcnQgY2FuIGJlIGNyZWF0ZWQgc3RyYWlnaHQgZnJvbSBhIHRlc3Qgd29ya2VyLCB3aXRoIG5vXG4gICAgICAvLyBgY29yZVNldHVwYCBvd25pbmcgaXRzIGxpZmVjeWNsZSBhbmQgdGhlcmVmb3JlIG5vdGhpbmcgdGhhdCBldmVyIGNhbGxzIGBkaXNwb3NlYC9gZGlzcG9zZVN5bmNgIFx1MjAxNFxuICAgICAgLy8gV2hpY2ggaXMgaG93IGEgcnVuIGxlYXZlcyBpdHMgYWRiIHBvcnQgZm9yd2FyZCBzdHJhbmRlZCBvbiB0aGUgZGV2aWNlIChvYnNlcnZlZCAyMDI2LTA4LTMwKS4gVGhlXG4gICAgICAvLyBIYW5kbGVyIGlzIHJlbW92ZWQgYWdhaW4gb24gZGlzcG9zYWwgc28gcmVjb25uZWN0cyBkbyBub3Qgc3RhY2sgbGlzdGVuZXJzLlxuICAgICAgdGhpcy5kaXNwb3NlSW5wdXRDaGFubmVsT25FeGl0ID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICBjb25uZWN0aW9uLmRpc3Bvc2VTeW5jKCk7XG4gICAgICB9O1xuICAgICAgcHJvY2Vzcy5vbmNlKCdleGl0JywgdGhpcy5kaXNwb3NlSW5wdXRDaGFubmVsT25FeGl0KTtcblxuICAgICAgbG9nKCdbYXBwaXVtLXRyYW5zcG9ydF0gVHJ1c3RlZC1pbnB1dCBjaGFubmVsIG9wZW4uJyk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIC8vIEdpdmUgdXAgZm9yIHRoZSBsaWZlIG9mIHRoZSB0cmFuc3BvcnQgcmF0aGVyIHRoYW4gcGF5aW5nIGFuIGBhZGJgIHJvdW5kLXRyaXAgb24gZXZlcnkgZXZhbC5cbiAgICAgIC8vIEEgc29ja2V0IHRoYXQgbWVyZWx5ICpjbG9zZWQqIGFmdGVyIGEgc3VjY2Vzc2Z1bCBjb25uZWN0IGlzIGEgZGlmZmVyZW50IGNhc2UgXHUyMDE0IGBpc09wZW5gIGlzIGZhbHNlXG4gICAgICAvLyBUaGVyZSB3aGlsZSB0aGlzIGZsYWcgc3RheXMgdW5zZXQsIHNvIHRoZSByZWNvbm5lY3QgYWJvdmUgc3RpbGwgcnVucy5cbiAgICAgIHRoaXMuaXNJbnB1dENoYW5uZWxVbmF2YWlsYWJsZSA9IHRydWU7XG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBUcnVzdGVkIGlucHV0IGlzIHVuYXZhaWxhYmxlIG9uIHRoaXMgZGV2aWNlOiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTd2l0Y2hlcyB0aGUgZHJpdmVyIHRvIHRoZSBgV0VCVklFV19tZC5vYnNpZGlhbmAgY29udGV4dC5cbiAgICpcbiAgICogSWYgdGhlIGNvbnRleHQgd2FzIGFscmVhZHkgdmVyaWZpZWQgKGNhY2hlZCB2aWEge0BsaW5rIGlzSW5XZWJWaWV3Q29udGV4dH0pLFxuICAgKiByZXR1cm5zIGltbWVkaWF0ZWx5IHdpdGhvdXQgY2FsbGluZyBgZ2V0Q29udGV4dHMoKWAgXHUyMDE0IHdoaWNoIHJ1bnNcbiAgICogYGFkYiBzaGVsbCBjYXQgL3Byb2MvbmV0L3VuaXhgIGFuZCBjYW4gdGltZSBvdXQgb24gc2xvdyBlbXVsYXRvcnMuXG4gICAqXG4gICAqIFBvbGxzIHVudGlsIHRoZSBjb250ZXh0IGJlY29tZXMgYXZhaWxhYmxlICh0aGUgYXBwIG1heSBzdGlsbCBiZSBsb2FkaW5nKS5cbiAgICogVXNlcyB0aGUgYFdFQlZJRVdfbWQub2JzaWRpYW5gIGNvbnRleHQgc3BlY2lmaWNhbGx5IHRvIGF2b2lkIGNvbm5lY3RpbmdcbiAgICogdG8gQ2hyb21lIG9yIG90aGVyIFdlYlZpZXdzIG9uIHRoZSBkZXZpY2UuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGVuc3VyZVdlYlZpZXdDb250ZXh0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmlzSW5XZWJWaWV3Q29udGV4dCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIHRoaXMud2Vidmlld1RpbWVvdXRJbk1pbGxpc2Vjb25kcztcbiAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBXYWl0aW5nIGZvciAke1dFQlZJRVdfQ09OVEVYVF9QUkVGSVh9IGNvbnRleHQgKHRpbWVvdXQ9JHtTdHJpbmcodGhpcy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzKX1tcykuLi5gKTtcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGNvbnN0IGNvbnRleHRzID0gYXdhaXQgdGhpcy5icm93c2VyLmdldENvbnRleHRzKCk7XG4gICAgICBjb25zdCBvYnNpZGlhbkNvbnRleHQgPSBjb250ZXh0cy5maW5kKChjb250ZXh0KTogY29udGV4dCBpcyBzdHJpbmcgPT4gdHlwZW9mIGNvbnRleHQgPT09ICdzdHJpbmcnICYmIGNvbnRleHQuc3RhcnRzV2l0aChXRUJWSUVXX0NPTlRFWFRfUFJFRklYKSk7XG5cbiAgICAgIGlmIChvYnNpZGlhbkNvbnRleHQpIHtcbiAgICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gRm91bmQgV2ViVmlldyBjb250ZXh0OiAke29ic2lkaWFuQ29udGV4dH1gKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmJyb3dzZXIuc3dpdGNoQ29udGV4dChvYnNpZGlhbkNvbnRleHQpO1xuICAgICAgICAgIHRoaXMuaXNJbldlYlZpZXdDb250ZXh0ID0gdHJ1ZTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gc3dpdGNoQ29udGV4dCBmYWlsZWQ6ICR7U3RyaW5nKGVycm9yKX0uIFJlc2V0dGluZyB0byBOQVRJVkVfQVBQIGJlZm9yZSByZXRyeWluZy4uLmApO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmJyb3dzZXIuc3dpdGNoQ29udGV4dCgnTkFUSVZFX0FQUCcpO1xuICAgICAgICAgIH0gY2F0Y2ggKHJlc2V0RXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIE5BVElWRV9BUFAgcmVzZXQgYWxzbyBmYWlsZWQ6ICR7U3RyaW5nKHJlc2V0RXJyb3IpfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBXZWJWaWV3IG5vdCByZWFkeSwgYXZhaWxhYmxlIGNvbnRleHRzOiAke0pTT04uc3RyaW5naWZ5KGNvbnRleHRzKX0uIFJldHJ5aW5nLi4uYCk7XG4gICAgICBhd2FpdCBkZWxheShXRUJWSUVXX1BPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYE5vICR7V0VCVklFV19DT05URVhUX1BSRUZJWH0gY29udGV4dCBmb3VuZCB3aXRoaW4gJHtTdHJpbmcodGhpcy53ZWJ2aWV3VGltZW91dEluTWlsbGlzZWNvbmRzKX1tcy4gSXMgdGhlIE9ic2lkaWFuIGFwcCBmdWxseSBsb2FkZWQ/YCk7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBob3N0LXNpZGUgdmF1bHQgcGF0aCB0byB0aGUgZGV2aWNlLXNpZGUgcGF0aC5cbiAgICpcbiAgICogQHBhcmFtIHZhdWx0UGF0aCAtIEFic29sdXRlIHBhdGggb24gdGhlIGhvc3QgbWFjaGluZS5cbiAgICogQHJldHVybnMgVGhlIGRldmljZS1zaWRlIHZhdWx0IHBhdGguXG4gICAqL1xuICBwcml2YXRlIGdldERldmljZVZhdWx0UGF0aCh2YXVsdFBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3RoaXMudmF1bHRCYXNlUGF0aH0ke2V4dHJhY3RWYXVsdE5hbWUodmF1bHRQYXRoKX1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlcnZpY2VzIG9uZSBpbnB1dCByZXF1ZXN0IGZyb20gdGhlIHJlbmRlcmVyOiBpbmplY3QsIHRoZW4gcmVzb2x2ZSB0aGUgcmVuZGVyZXIncyBwcm9taXNlLlxuICAgKlxuICAgKiBFdmVyeSBmYWlsdXJlIHBhdGggc3RpbGwgcmVzb2x2ZXMgdGhhdCBwcm9taXNlIFx1MjAxNCB3aXRoIGFuIGVycm9yIG1lc3NhZ2UgdGhlIHJlbmRlcmVyIHJlLXRocm93cyBcdTIwMTQgYmVjYXVzZVxuICAgKiBhIHJlcXVlc3QgdGhhdCBpcyBzaWxlbnRseSBkcm9wcGVkIHdvdWxkIGhhbmcgdGhlIGNsb3N1cmUgdW50aWwgdGhlIHdob2xlIHJ1biB0aW1lcyBvdXQsIGFuZCByZXBvcnRcbiAgICogbm90aGluZyBhYm91dCB3aHkuXG4gICAqXG4gICAqIEBwYXJhbSBjb25uZWN0aW9uIC0gVGhlIGNoYW5uZWwgdGhlIHJlcXVlc3QgYXJyaXZlZCBvbi5cbiAgICogQHBhcmFtIHBheWxvYWQgLSBUaGUgcmF3IEpTT04gcGF5bG9hZCB0aGUgYmluZGluZyB3YXMgY2FsbGVkIHdpdGguXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGhhbmRsZUlucHV0UmVxdWVzdChjb25uZWN0aW9uOiBXZWJWaWV3Q2RwQ29ubmVjdGlvbiwgcGF5bG9hZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbGV0IHJlcXVlc3RJZCA9ICcnO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGlkLCByZXF1ZXN0IH0gPSBKU09OLnBhcnNlKHBheWxvYWQpIGFzIE1vYmlsZUlucHV0RW52ZWxvcGU7XG4gICAgICByZXF1ZXN0SWQgPSBpZDtcbiAgICAgIGF3YWl0IGNvbm5lY3Rpb24uc2VuZEFsbCh0b0NkcElucHV0Q29tbWFuZHMocmVxdWVzdCkpO1xuICAgICAgYXdhaXQgY29ubmVjdGlvbi5zZW5kKCdSdW50aW1lLmV2YWx1YXRlJywgeyBleHByZXNzaW9uOiBidWlsZFJlc29sdmVJbnB1dEV4cHJlc3Npb24oaWQpIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3JUb1N0cmluZyhlcnJvcik7XG4gICAgICBsb2coYFthcHBpdW0tdHJhbnNwb3J0XSBUcnVzdGVkIGlucHV0IGZhaWxlZDogJHttZXNzYWdlfWApO1xuICAgICAgaWYgKCFyZXF1ZXN0SWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBjb25uZWN0aW9uLnNlbmQoJ1J1bnRpbWUuZXZhbHVhdGUnLCB7IGV4cHJlc3Npb246IGJ1aWxkUmVzb2x2ZUlucHV0RXhwcmVzc2lvbihyZXF1ZXN0SWQsIG1lc3NhZ2UpIH0pO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIFRoZSBzb2NrZXQgaXMgZ29uZTsgdGhlIHJlbmRlcmVyJ3Mgb3duIHRpbWVvdXQgaXMgdGhlIHJlbWFpbmluZyBiYWNrc3RvcC5cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHVzaGVzIHRoZSBtaW5pbWFsIGAub2JzaWRpYW4vYXBwLmpzb25gIHZhdWx0IG1hcmtlciB2aWEgYGFkYiBwdXNoYC5cbiAgICpcbiAgICogYGJyb3dzZXIucHVzaEZpbGVgIChXZWJEcml2ZXIgYmFzZTY0KSBpcyBhbiBvcmRlciBvZiBtYWduaXR1ZGUgc2xvd2VyIG9uIGFcbiAgICogY29sZCBvciBsb2FkZWQgZW11bGF0b3IgXHUyMDE0IG1lYXN1cmVkIGF0IDlcdTIwMTMyMXMgcGVyIGNhbGwgZm9yIHRoaXMgMi1ieXRlIG1hcmtlcixcbiAgICogdmVyc3VzIHN1Yi1zZWNvbmQgb3ZlciBgYWRiYC4gVGhpcyBtaXJyb3JzIHtAbGluayBwdXNoRmlsZXN9LCB3aGljaCBzd2l0Y2hlZFxuICAgKiB0byBgYWRiYCBmb3IgdGhlIHNhbWUgcmVhc29uLiBgbWtkaXIgLXBgIGd1YXJhbnRlZXMgdGhlIHBhcmVudCBkaXJlY3RvcnkuXG4gICAqXG4gICAqIEBwYXJhbSBkZXZpY2VWYXVsdFBhdGggLSBUaGUgZGV2aWNlLXNpZGUgdmF1bHQgZGlyZWN0b3J5IHBhdGguXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHB1c2hPYnNpZGlhbk1hcmtlcihkZXZpY2VWYXVsdFBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGxvY2FsTWFya2VyID0gam9pbih0bXBkaXIoKSwgYG9ic2lkaWFuLW1hcmtlci0ke3JhbmRvbVVVSUQoKX0uanNvbmApO1xuICAgIGNvbnN0IHJlbW90ZU1hcmtlciA9IGAke2RldmljZVZhdWx0UGF0aH0vLm9ic2lkaWFuL2FwcC5qc29uYDtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB3cml0ZUZpbGUobG9jYWxNYXJrZXIsICd7fScsICd1dGYtOCcpO1xuICAgICAgYXdhaXQgZXhlYyhbJ2FkYicsICctcycsIHRoaXMuZGV2aWNlSWQsICdzaGVsbCcsICdta2RpcicsICctcCcsIGAke2RldmljZVZhdWx0UGF0aH0vLm9ic2lkaWFuYF0sIHsgaXNRdWlldDogdHJ1ZSB9KTtcbiAgICAgIGF3YWl0IGV4ZWMoWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAncHVzaCcsIGxvY2FsTWFya2VyLCByZW1vdGVNYXJrZXJdLCB7IGlzUXVpZXQ6IHRydWUgfSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHJtKGxvY2FsTWFya2VyLCB7IGZvcmNlOiB0cnVlIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgdmF1bHQgZGlyZWN0b3J5IGZyb20gdGhlIGRldmljZSBvdmVyIGBhZGJgLCBhbmQgQ0hFQ0tTIHRoYXQgaXQgaXNcbiAgICogYWN0dWFsbHkgZ29uZS5cbiAgICpcbiAgICogQmVzdC1lZmZvcnQ6IGEgZmFpbHVyZSBpcyBsb2dnZWQsIG5vdCB0aHJvd24sIHNvIGEgdGVhcmRvd24gcHJvYmxlbSBuZXZlclxuICAgKiBtYXNrcyB0aGUgdGVzdCByZXN1bHQuIFRoZSBuZXh0IHJ1bidzIHN0YXJ0LW9mLXJ1biBzd2VlcCBwaWNrcyB1cCB3aGF0ZXZlclxuICAgKiB0aGlzIGNvdWxkIG5vdCByZW1vdmUuXG4gICAqXG4gICAqIFRoZSBjaGVjayBpcyB0aGUgcG9pbnQuIGBybSAtcmZgIHJ1bnMgd2l0aCBgc2hvdWxkSWdub3JlRXhpdENvZGVgLCBzbyBhblxuICAgKiB1bnJlbW92ZWQgZGlyZWN0b3J5IHVzZWQgdG8gbGVhdmUgbm8gdHJhY2UgYXQgYWxsIFx1MjAxNCB3aGljaCBpcyBob3cgcnVucyB0aGF0XG4gICAqIHBhc3NlZCBlbmQgdG8gZW5kIHdlcmUgc3RpbGwgZm91bmQgdG8gYmUgbGVha2luZyBhIHZhdWx0IGFwaWVjZSwgaW52aXNpYmx5LFxuICAgKiB1bnRpbCBzb21lb25lIGNvdW50ZWQgdGhlIGRpcmVjdG9yaWVzIG9uIHRoZSBkZXZpY2UgYnkgaGFuZC4gQSBsZWFrIGlzIG5vd1xuICAgKiBuYW1lZCBpbiB0aGUgbG9nIGF0IHRoZSBtb21lbnQgaXQgaGFwcGVucy5cbiAgICpcbiAgICogQHBhcmFtIGRldmljZVZhdWx0UGF0aCAtIFRoZSBkZXZpY2Utc2lkZSB2YXVsdCBkaXJlY3RvcnkgcGF0aC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVtb3ZlRGV2aWNlVmF1bHREaXJlY3RvcnkoZGV2aWNlVmF1bHRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gUmVtb3ZpbmcgdmF1bHQgZGlyZWN0b3J5IGZyb20gZGV2aWNlOiAke2RldmljZVZhdWx0UGF0aH1gKTtcbiAgICAgIGF3YWl0IGV4ZWMoXG4gICAgICAgIFsnYWRiJywgJy1zJywgdGhpcy5kZXZpY2VJZCwgJ3NoZWxsJywgJ3JtJywgJy1yZicsIGRldmljZVZhdWx0UGF0aF0sXG4gICAgICAgIHsgaXNRdWlldDogdHJ1ZSwgc2hvdWxkSWdub3JlRXhpdENvZGU6IHRydWUsIHRpbWVvdXRJbk1pbGxpc2Vjb25kczogQURCX1ZBVUxUX1JFTU9WRV9USU1FT1VUX0lOX01JTExJU0VDT05EUyB9XG4gICAgICApO1xuXG4gICAgICBjb25zdCBsaXN0aW5nID0gYXdhaXQgZXhlYyhcbiAgICAgICAgWydhZGInLCAnLXMnLCB0aGlzLmRldmljZUlkLCAnc2hlbGwnLCAnbHMnLCAnLWQnLCBkZXZpY2VWYXVsdFBhdGhdLFxuICAgICAgICB7IGlzUXVpZXQ6IHRydWUsIHNob3VsZElnbm9yZUV4aXRDb2RlOiB0cnVlLCB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IEFEQl9WQVVMVF9SRU1PVkVfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgfVxuICAgICAgKTtcblxuICAgICAgaWYgKGxpc3RpbmcuaW5jbHVkZXMoZGV2aWNlVmF1bHRQYXRoKSkge1xuICAgICAgICBsb2coXG4gICAgICAgICAgYFthcHBpdW0tdHJhbnNwb3J0XSBXYXJuaW5nOiAke2RldmljZVZhdWx0UGF0aH0gc3Vydml2ZWQgcmVtb3ZhbCBhbmQgaXMgbm93IGxlYWtlZCByZXNpZHVlLiBgXG4gICAgICAgICAgICArICdUaGUgbmV4dCBydW5cXCdzIHN0YXJ0LW9mLXJ1biBzd2VlcCB3aWxsIHJldHJ5IGl0LidcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gVmF1bHQgZGlyZWN0b3J5IHJlbW92YWwgZmFpbGVkIChub24tZmF0YWwpOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERyb3BzIHRoZSBgcHJvY2Vzcy5vbignZXhpdCcpYCBoYW5kbGVyIHRoYXQgd291bGQgb3RoZXJ3aXNlIGNsb3NlIGFuIGFscmVhZHktY2xvc2VkIGNoYW5uZWwsIGFuZCB3b3VsZFxuICAgKiBzdGFjayBhIGxpc3RlbmVyIHBlciByZWNvbm5lY3QuXG4gICAqL1xuICBwcml2YXRlIHVucmVnaXN0ZXJJbnB1dENoYW5uZWxFeGl0SGFuZGxlcigpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZGlzcG9zZUlucHV0Q2hhbm5lbE9uRXhpdCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHByb2Nlc3Mub2ZmKCdleGl0JywgdGhpcy5kaXNwb3NlSW5wdXRDaGFubmVsT25FeGl0KTtcbiAgICB0aGlzLmRpc3Bvc2VJbnB1dENoYW5uZWxPbkV4aXQgPSBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFBvbGxzIHVudGlsIGBhcHAud29ya3NwYWNlLmxheW91dFJlYWR5YCBpcyBgdHJ1ZWAgaW4gdGhlIFdlYlZpZXcuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHdhaXRGb3JMYXlvdXRSZWFkeSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzdGFydCA9IERhdGUubm93KCk7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBzdGFydCArIHRoaXMubGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHM7XG4gICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gV2FpdGluZyBmb3IgbGF5b3V0IHJlYWR5ICh0aW1lb3V0PSR7U3RyaW5nKHRoaXMubGF5b3V0UmVhZHlUaW1lb3V0SW5NaWxsaXNlY29uZHMpfW1zKS4uLmApO1xuXG4gICAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgaXNSZWFkeSA9IGF3YWl0IHRoaXMuYnJvd3Nlci5leGVjdXRlKCgpOiBib29sZWFuID0+IHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWRlcHJlY2F0ZWQgLS0gV2UgbmVlZCBnbG9iYWwgYGFwcGAgdmFyaWFibGUuXG4gICAgICAgICAgY29uc3QgYXBwID0gZ2xvYmFsVGhpcy5hcHAgYXMgTG9hZGluZ0FwcCB8IHVuZGVmaW5lZDtcbiAgICAgICAgICByZXR1cm4gISFhcHA/LndvcmtzcGFjZT8ubGF5b3V0UmVhZHk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoaXNSZWFkeSkge1xuICAgICAgICAgIGxvZyhgW2FwcGl1bS10cmFuc3BvcnRdIExheW91dCBpcyByZWFkeSBhZnRlciAke1N0cmluZyhEYXRlLm5vdygpIC0gc3RhcnQpfW1zLmApO1xuICAgICAgICAgIHRoaXMuaXNJbldlYlZpZXdDb250ZXh0ID0gdHJ1ZTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBBcHAgbm90IHJlYWR5IHlldCAocGFnZSBtYXkgYmUgcmVsb2FkaW5nKS5cbiAgICAgIH1cblxuICAgICAgbG9nKGBbYXBwaXVtLXRyYW5zcG9ydF0gTGF5b3V0IG5vdCByZWFkeSB5ZXQgKGVsYXBzZWQ9JHtTdHJpbmcoRGF0ZS5ub3coKSAtIHN0YXJ0KX1tcykuIFJldHJ5aW5nLi4uYCk7XG4gICAgICBhd2FpdCBkZWxheShMQVlPVVRfUkVBRFlfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihgT2JzaWRpYW4gbGF5b3V0IGRpZCBub3QgYmVjb21lIHJlYWR5IHdpdGhpbiAke1N0cmluZyh0aGlzLmxheW91dFJlYWR5VGltZW91dEluTWlsbGlzZWNvbmRzKX1tc2ApO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgZ2l2ZW4gZGVsYXkuXG4gKlxuICogQHBhcmFtIG1zIC0gVGhlIGRlbGF5IGluIG1pbGxpc2Vjb25kcy5cbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIHRoZSBkZWxheS5cbiAqL1xuZnVuY3Rpb24gZGVsYXkobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKTtcbiAgfSk7XG59XG5cbi8qKlxuICogRXh0cmFjdHMgdGhlIHZhdWx0IGRpcmVjdG9yeSBuYW1lIGZyb20gYSBob3N0LXNpZGUgdmF1bHQgcGF0aC5cbiAqXG4gKiBAcGFyYW0gdmF1bHRQYXRoIC0gQWJzb2x1dGUgcGF0aCBvbiB0aGUgaG9zdCBtYWNoaW5lLlxuICogQHJldHVybnMgVGhlIGxhc3QgcGF0aCBzZWdtZW50ICh2YXVsdCBkaXJlY3RvcnkgbmFtZSkuXG4gKi9cbmZ1bmN0aW9uIGV4dHJhY3RWYXVsdE5hbWUodmF1bHRQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBub3JtYWxpemVkID0gdmF1bHRQYXRoLnJlcGxhY2UoL1tcXFxcL10rJC8sICcnKTtcbiAgY29uc3QgbGFzdFNlcGFyYXRvciA9IE1hdGgubWF4KG5vcm1hbGl6ZWQubGFzdEluZGV4T2YoJy8nKSwgbm9ybWFsaXplZC5sYXN0SW5kZXhPZignXFxcXCcpKTtcbiAgcmV0dXJuIG5vcm1hbGl6ZWQuc2xpY2UobGFzdFNlcGFyYXRvciArIDEpO1xufVxuXG4vKiB2OCBpZ25vcmUgc3RvcCAqL1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBNENBLHlCQUEyQjtBQUMzQixzQkFHTztBQUNQLHFCQUF1QjtBQUN2Qix1QkFBcUI7QUFXckIsZ0NBR087QUFDUCw2QkFBOEI7QUFDOUIsa0JBQXFCO0FBQ3JCLDhCQUFzQztBQUN0QyxpQkFBb0I7QUFDcEIsMEJBSU87QUFDUCx5QkFBb0M7QUE4RnBDLE1BQU0sWUFBWTtBQUNsQixNQUFNLHVCQUF1QjtBQUM3QixNQUFNLHlCQUF5QjtBQUMvQixNQUFNLHdDQUF3QztBQUM5QyxNQUFNLCtDQUErQztBQUNyRCxNQUFNLDZDQUE2QztBQUNuRCxNQUFNLG9EQUFvRDtBQUMxRCxNQUFNLG9DQUFvQztBQUMxQyxNQUFNLGlCQUFpQjtBQUN2QixNQUFNLDJDQUEyQztBQUdqRCxNQUFNLDZCQUE2QjtBQUNuQyxNQUFNLGtDQUFrQztBQUN4QyxNQUFNLHlDQUF5QztBQUMvQyxNQUFNLHNDQUFzQztBQU01QyxNQUFNLHlCQUF5QjtBQVF4QixNQUFNLGtDQUFrQztBQUUvQyxNQUFNLDBCQUFrRDtBQUFBLEVBQ3RELFNBQVM7QUFBQSxFQUNULEtBQUs7QUFDUDtBQWlCTyxNQUFNLGdCQUE2QztBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSXhDLFdBQVc7QUFBQSxFQUNWO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUlULDRCQUFpRDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFLakQsZUFBNEM7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSzVDLDRCQUE0QjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVk1QixxQkFBcUI7QUFBQSxFQUNaO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPVixZQUFZLFFBQStCO0FBQ2hELFNBQUssVUFBVSxPQUFPO0FBQ3RCLFNBQUssV0FBVyxPQUFPO0FBQ3ZCLFNBQUssaUJBQWlCLE9BQU8sa0JBQWtCO0FBQy9DLFNBQUssbUNBQW1DLE9BQU8sb0NBQW9DO0FBQ25GLFNBQUssV0FBVyxPQUFPO0FBQ3ZCLFNBQUssUUFBUSxPQUFPLFNBQVM7QUFDN0IsU0FBSyx1QkFBdUIsT0FBTyx3QkFBd0I7QUFDM0QsU0FBSyxnQkFBZ0IsT0FBTyxpQkFBaUIsd0JBQXdCLEtBQUssUUFBUSxLQUFLO0FBQ3ZGLFNBQUssK0JBQStCLE9BQU8sZ0NBQWdDO0FBQUEsRUFDN0U7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBWUEsTUFBYSxzQkFBcUQ7QUFDaEUsVUFBTSxTQUFTLEdBQUcsMEJBQTBCLFFBQUksK0JBQVcsQ0FBQztBQUM1RCxjQUFNO0FBQUEsTUFDSixDQUFDLE9BQU8sTUFBTSxLQUFLLFVBQVUsU0FBUyxPQUFPLE1BQU0sNEJBQTRCLE1BQU07QUFBQSxNQUNyRixFQUFFLFNBQVMsTUFBTSxzQkFBc0IsTUFBTSx1QkFBdUIsdUNBQXVDO0FBQUEsSUFDN0c7QUFDQSxXQUFPLEVBQUUsT0FBTztBQUFBLEVBQ2xCO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBZ0JBLE1BQWEsa0JBQWtCLFNBQXVEO0FBQ3BGLFVBQU0sWUFBUSwyQ0FBZ0IsTUFBTSxLQUFLLFFBQVEsZUFBZSxDQUFDO0FBQ2pFLFFBQUksS0FBQyxpQ0FBTSxLQUFLLEdBQUc7QUFDakIsWUFBTSxJQUFJLE1BQU0sMEVBQTBFO0FBQUEsSUFDNUY7QUFFQSxXQUFPO0FBQUEsRUFDVDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFTQSxNQUFhLFVBQXlCO0FBQ3BDLFVBQU0sS0FBSyxvQkFBb0I7QUFFL0IsUUFBSSxLQUFLLGdCQUFnQjtBQUN2QixZQUFNLEtBQUssUUFBUSxjQUFjO0FBQUEsSUFDbkM7QUFBQSxFQUNGO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVNPLGNBQW9CO0FBQ3pCLFVBQU0sVUFBVSxLQUFLO0FBQ3JCLFNBQUssZUFBZTtBQUNwQixTQUFLLGtDQUFrQztBQUN2QyxhQUFTLFlBQVk7QUFBQSxFQUN2QjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFZQSxNQUFhLFNBQVMsWUFBb0IsVUFBaUQ7QUFDekYsVUFBTSxLQUFLLHFCQUFxQjtBQUNoQyxVQUFNLEtBQUssbUJBQW1CO0FBRTlCLFFBQUk7QUFDRixZQUFNLFNBQVMsTUFBTSxLQUFLLFFBQVE7QUFBQSxRQUNoQyxXQUFXLFVBQVU7QUFBQSxNQUN2QjtBQUVBLFVBQUksV0FBVyxVQUFhLFdBQVcsTUFBTTtBQUMzQyxlQUFPO0FBQUEsTUFDVDtBQUVBLGFBQU87QUFBQSxJQUNULFNBQVMsT0FBZ0I7QUFFdkIsV0FBSyxxQkFBcUI7QUFDMUIsWUFBTTtBQUFBLElBQ1I7QUFBQSxFQUNGO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFRTyxpQkFBb0M7QUFDekMsV0FBTztBQUFBLE1BQ0wsVUFBVSxLQUFLO0FBQUEsTUFDZixXQUFXLEtBQUssUUFBUTtBQUFBLElBQzFCO0FBQUEsRUFDRjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9BLE1BQWEsZUFBZSxZQUFtQztBQUM3RCx3QkFBSSwrQ0FBK0M7QUFDbkQsVUFBTSxRQUFRLE1BQU0sS0FBSyxRQUFRLGNBQWMsS0FBSyxLQUFLO0FBQ3pELHdCQUFJLGlDQUFpQyxPQUFPLEtBQUssQ0FBQyxVQUFVLE9BQU8sb0JBQW9CLENBQUMsY0FBYztBQUN0RyxRQUFJLFVBQVUsc0JBQXNCO0FBQ2xDLDBCQUFJLHFDQUFxQyxLQUFLLEtBQUssS0FBSztBQUN4RCxXQUFLLHFCQUFxQjtBQUMxQixZQUFNLEtBQUssUUFBUSxZQUFZLEtBQUssS0FBSztBQUN6QyxZQUFNLE1BQU0saUNBQWlDO0FBQUEsSUFDL0M7QUFFQSxVQUFNLEtBQUsscUJBQXFCO0FBQ2hDLHdCQUFJLDRDQUE0QztBQUFBLEVBQ2xEO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBYUEsTUFBYSxVQUFVLFdBQW1CLFFBQW1EO0FBQzNGLFVBQU0sa0JBQWtCLEtBQUssbUJBQW1CLFNBQVM7QUFDekQsVUFBTSxjQUFjLGFBQVMsK0JBQVcsQ0FBQztBQUN6QyxVQUFNLG1CQUFlLDJCQUFLLHVCQUFPLEdBQUcsV0FBVztBQUMvQyxVQUFNLGdCQUFnQixtQkFBbUIsV0FBVztBQUVwRCxRQUFJO0FBQ0YsMEJBQUksd0NBQXdDLFlBQVksRUFBRTtBQUMxRCxnQkFBTSxrQkFBSyxDQUFDLE9BQU8sT0FBTyxhQUFhLE1BQU0sV0FBVyxHQUFHLEdBQUcsRUFBRSxTQUFLLHVCQUFPLEdBQUcsU0FBUyxLQUFLLENBQUM7QUFFOUYsMEJBQUksZ0RBQWdELEtBQUssUUFBUSxLQUFLO0FBQ3RFLGdCQUFNLGtCQUFLLENBQUMsT0FBTyxNQUFNLEtBQUssVUFBVSxRQUFRLGNBQWMsYUFBYSxHQUFHLEVBQUUsU0FBUyxLQUFLLENBQUM7QUFFL0YsMEJBQUksc0RBQXNELGVBQWUsS0FBSztBQUM5RSxnQkFBTSxrQkFBSyxDQUFDLE9BQU8sTUFBTSxLQUFLLFVBQVUsU0FBUyxTQUFTLE1BQU0sZUFBZSxHQUFHLEVBQUUsU0FBUyxLQUFLLENBQUM7QUFDbkcsZ0JBQU0sa0JBQUssQ0FBQyxPQUFPLE1BQU0sS0FBSyxVQUFVLFNBQVMsT0FBTyxPQUFPLGVBQWUsTUFBTSxlQUFlLEdBQUcsRUFBRSxTQUFTLEtBQUssQ0FBQztBQUV2SCwwQkFBSSxtREFBbUQ7QUFDdkQsZ0JBQU0sa0JBQUssQ0FBQyxPQUFPLE1BQU0sS0FBSyxVQUFVLFNBQVMsTUFBTSxHQUFHLEVBQUUsU0FBUyxLQUFLLENBQUM7QUFFM0UsMEJBQUksa0RBQWtEO0FBQ3RELGdCQUFNLGtCQUFLLENBQUMsT0FBTyxNQUFNLEtBQUssVUFBVSxTQUFTLE1BQU0sYUFBYSxHQUFHLEVBQUUsU0FBUyxLQUFLLENBQUM7QUFBQSxJQUMxRixVQUFFO0FBQ0EsZ0JBQU0sb0JBQUcsY0FBYyxFQUFFLE9BQU8sS0FBSyxDQUFDO0FBQUEsSUFDeEM7QUFBQSxFQUNGO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBYUEsTUFBYSx3QkFBd0IsUUFBdUU7QUFDMUcsUUFBSSxDQUFDLFFBQVE7QUFDWCxhQUFPO0FBQUEsSUFDVDtBQUVBLFVBQU0sT0FBTyxVQUFNO0FBQUEsTUFDakIsQ0FBQyxPQUFPLE1BQU0sS0FBSyxVQUFVLFVBQVUsTUFBTSxNQUFNLE1BQU07QUFBQSxNQUN6RCxFQUFFLFNBQVMsTUFBTSxzQkFBc0IsTUFBTSx1QkFBdUIsb0NBQW9DO0FBQUEsSUFDMUc7QUFFQSxVQUFNLGNBQWMsS0FBSyxZQUFZLE9BQU8sTUFBTTtBQUNsRCxVQUFNLFNBQVMsZ0JBQWdCLEtBQUssT0FBTyxLQUFLLE1BQU0sY0FBYyxPQUFPLE9BQU8sTUFBTTtBQUN4RixVQUFNLFdBQVcsT0FDZCxNQUFNLElBQUksRUFDVixPQUFPLENBQUMsU0FBUyx1QkFBdUIsS0FBSyxJQUFJLENBQUMsRUFDbEQsS0FBSyxJQUFJLEVBQ1QsS0FBSztBQUVSLFFBQUksQ0FBQyxVQUFVO0FBQ2IsYUFBTztBQUFBLElBQ1Q7QUFFQSxXQUFPLFNBQVMsTUFBTSxDQUFDLCtCQUErQjtBQUFBLEVBQ3hEO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUF1QkEsTUFBYSxjQUFjLFdBQWtDO0FBQzNELHdCQUFJLHlDQUF5QyxTQUFTLEVBQUU7QUFDeEQsVUFBTSxrQkFBa0IsS0FBSyxtQkFBbUIsU0FBUztBQUd6RCxVQUFNLEtBQUssbUJBQW1CLGVBQWU7QUFHN0MsVUFBTSxLQUFLLHFCQUFxQjtBQUloQyxTQUFLLHFCQUFxQjtBQUUxQixVQUFNLGNBQWMsS0FBSyx1QkFBdUIsR0FBRyxLQUFLLGFBQWEsR0FBRyw2Q0FBcUIsS0FBSztBQUVsRyxVQUFNLEtBQUssUUFBUTtBQUFBLE1BQ2pCLENBQUMsTUFBYyxnQkFBd0I7QUFDckMsWUFBSSxXQUFXLEtBQUssTUFBTSxhQUFhLFFBQVEsd0JBQXdCLEtBQUssSUFBSTtBQUVoRixZQUFJLGFBQWE7QUFDZixnQkFBTSxRQUFRLFNBQVMsT0FBTyxDQUFDLGVBQWUsZUFBZSxRQUFRLFdBQVcsV0FBVyxXQUFXLENBQUM7QUFDdkcscUJBQVcsY0FBYyxPQUFPO0FBQzlCLHlCQUFhLFdBQVcsaUJBQWlCLFVBQVUsRUFBRTtBQUFBLFVBQ3ZEO0FBQ0EscUJBQVcsU0FBUyxPQUFPLENBQUMsZUFBZSxDQUFDLE1BQU0sU0FBUyxVQUFVLENBQUM7QUFBQSxRQUN4RTtBQUVBLFlBQUksQ0FBQyxTQUFTLFNBQVMsSUFBSSxHQUFHO0FBQzVCLG1CQUFTLEtBQUssSUFBSTtBQUFBLFFBQ3BCO0FBQ0EscUJBQWEsUUFBUSwwQkFBMEIsS0FBSyxVQUFVLFFBQVEsQ0FBQztBQUN2RSxxQkFBYSxRQUFRLHlCQUF5QixJQUFJO0FBQ2xELHFCQUFhLFFBQVEsaUJBQWlCLElBQUksSUFBSSxNQUFNO0FBQ3BELGlCQUFTLE9BQU87QUFBQSxNQUNsQjtBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsSUFDRjtBQUdBLFVBQU0sS0FBSyxtQkFBbUI7QUFBQSxFQUNoQztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBaUJBLE1BQWEsZ0JBQWdCLFdBQWtDO0FBQzdELFVBQU0sa0JBQWtCLEtBQUssbUJBQW1CLFNBQVM7QUFFekQsUUFBSTtBQUNGLFlBQU0sS0FBSyxxQkFBcUI7QUFFaEMsWUFBTSxLQUFLLFFBQVEsUUFBUSxDQUFDLFNBQWlCO0FBQzNDLGNBQU0sV0FBVyxLQUFLLE1BQU0sYUFBYSxRQUFRLHdCQUF3QixLQUFLLElBQUk7QUFDbEYsY0FBTSxXQUFXLFNBQVMsT0FBTyxDQUFDLE1BQU0sTUFBTSxJQUFJO0FBQ2xELHFCQUFhLFFBQVEsMEJBQTBCLEtBQUssVUFBVSxRQUFRLENBQUM7QUFDdkUscUJBQWEsV0FBVyxpQkFBaUIsSUFBSSxFQUFFO0FBQy9DLFlBQUksYUFBYSxRQUFRLHVCQUF1QixNQUFNLE1BQU07QUFDMUQsY0FBSSxTQUFTLFNBQVMsR0FBRztBQUN2Qix5QkFBYSxRQUFRLHlCQUF5QixTQUFTLENBQUMsS0FBSyxFQUFFO0FBQUEsVUFDakUsT0FBTztBQUNMLHlCQUFhLFdBQVcsdUJBQXVCO0FBQUEsVUFDakQ7QUFBQSxRQUNGO0FBQUEsTUFDRixHQUFHLGVBQWU7QUFBQSxJQUNwQixTQUFTLE9BQWdCO0FBQ3ZCO0FBQUEsUUFDRSwyQ0FBMkMsZUFBZSx1QkFDbEQsT0FBTyxLQUFLLENBQUM7QUFBQSxNQUN2QjtBQUFBLElBQ0Y7QUFFQSxVQUFNLEtBQUssMkJBQTJCLGVBQWU7QUFBQSxFQUN2RDtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBS0EsTUFBYyxzQkFBcUM7QUFDakQsVUFBTSxVQUFVLEtBQUs7QUFDckIsU0FBSyxlQUFlO0FBQ3BCLFNBQUssa0NBQWtDO0FBQ3ZDLFVBQU0sU0FBUyxRQUFRO0FBQUEsRUFDekI7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFVQSxNQUFjLHFCQUFvQztBQUNoRCxRQUFJLEtBQUssY0FBYyxVQUFVLEtBQUssMkJBQTJCO0FBQy9EO0FBQUEsSUFDRjtBQU1BLFFBQUksS0FBSyxhQUFhLFdBQVc7QUFDL0IsV0FBSyw0QkFBNEI7QUFDakM7QUFBQSxJQUNGO0FBRUEsVUFBTSxLQUFLLG9CQUFvQjtBQUUvQixRQUFJO0FBQ0YsWUFBTSxhQUFhLFVBQU0sd0NBQW9CLEVBQUUsT0FBTyxLQUFLLE9BQU8sVUFBVSxLQUFLLFNBQVMsQ0FBQztBQUMzRixZQUFNLFdBQVcsS0FBSyxnQkFBZ0I7QUFDdEMsWUFBTSxXQUFXLEtBQUssc0JBQXNCLEVBQUUsTUFBTSw4Q0FBMEIsQ0FBQztBQUMvRSxpQkFBVyxHQUFHLHlCQUF5QixDQUFDLFdBQW9DO0FBQzFFLFlBQUksT0FBTyxNQUFNLE1BQU0sK0NBQTJCO0FBQ2hEO0FBQUEsUUFDRjtBQUVBLGNBQU0sVUFBVSxPQUFPLFNBQVM7QUFJaEMsYUFBSyxtQkFBbUIsWUFBWSxPQUFPLFlBQVksV0FBVyxVQUFVLEVBQUUsRUFBRSxNQUFNLE1BQU07QUFBQSxRQUU1RixDQUFDO0FBQUEsTUFDSCxDQUFDO0FBRUQsV0FBSyxlQUFlO0FBTXBCLFdBQUssNEJBQTRCLE1BQVk7QUFDM0MsbUJBQVcsWUFBWTtBQUFBLE1BQ3pCO0FBQ0EsY0FBUSxLQUFLLFFBQVEsS0FBSyx5QkFBeUI7QUFFbkQsMEJBQUksZ0RBQWdEO0FBQUEsSUFDdEQsU0FBUyxPQUFnQjtBQUl2QixXQUFLLDRCQUE0QjtBQUNqQywwQkFBSSx1RUFBbUUsc0NBQWMsS0FBSyxDQUFDLEVBQUU7QUFBQSxJQUMvRjtBQUFBLEVBQ0Y7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFhQSxNQUFjLHVCQUFzQztBQUNsRCxRQUFJLEtBQUssb0JBQW9CO0FBQzNCO0FBQUEsSUFDRjtBQUVBLFVBQU0sV0FBVyxLQUFLLElBQUksSUFBSSxLQUFLO0FBQ25DLHdCQUFJLGtDQUFrQyxzQkFBc0IscUJBQXFCLE9BQU8sS0FBSyw0QkFBNEIsQ0FBQyxRQUFRO0FBRWxJLFdBQU8sS0FBSyxJQUFJLElBQUksVUFBVTtBQUM1QixZQUFNLFdBQVcsTUFBTSxLQUFLLFFBQVEsWUFBWTtBQUNoRCxZQUFNLGtCQUFrQixTQUFTLEtBQUssQ0FBQyxZQUErQixPQUFPLFlBQVksWUFBWSxRQUFRLFdBQVcsc0JBQXNCLENBQUM7QUFFL0ksVUFBSSxpQkFBaUI7QUFDbkIsNEJBQUksNkNBQTZDLGVBQWUsRUFBRTtBQUNsRSxZQUFJO0FBQ0YsZ0JBQU0sS0FBSyxRQUFRLGNBQWMsZUFBZTtBQUNoRCxlQUFLLHFCQUFxQjtBQUMxQjtBQUFBLFFBQ0YsU0FBUyxPQUFnQjtBQUN2Qiw4QkFBSSw0Q0FBNEMsT0FBTyxLQUFLLENBQUMsOENBQThDO0FBQzNHLGNBQUk7QUFDRixrQkFBTSxLQUFLLFFBQVEsY0FBYyxZQUFZO0FBQUEsVUFDL0MsU0FBUyxZQUFxQjtBQUM1QixnQ0FBSSxvREFBb0QsT0FBTyxVQUFVLENBQUMsRUFBRTtBQUFBLFVBQzlFO0FBQUEsUUFDRjtBQUFBLE1BQ0Y7QUFFQSwwQkFBSSw2REFBNkQsS0FBSyxVQUFVLFFBQVEsQ0FBQyxlQUFlO0FBQ3hHLFlBQU0sTUFBTSxxQ0FBcUM7QUFBQSxJQUNuRDtBQUVBLFVBQU0sSUFBSSxNQUFNLE1BQU0sc0JBQXNCLHlCQUF5QixPQUFPLEtBQUssNEJBQTRCLENBQUMsdUNBQXVDO0FBQUEsRUFDdko7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVFRLG1CQUFtQixXQUEyQjtBQUNwRCxXQUFPLEdBQUcsS0FBSyxhQUFhLEdBQUcsaUJBQWlCLFNBQVMsQ0FBQztBQUFBLEVBQzVEO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVlBLE1BQWMsbUJBQW1CLFlBQWtDLFNBQWdDO0FBQ2pHLFFBQUksWUFBWTtBQUNoQixRQUFJO0FBQ0YsWUFBTSxFQUFFLElBQUksUUFBUSxJQUFJLEtBQUssTUFBTSxPQUFPO0FBQzFDLGtCQUFZO0FBQ1osWUFBTSxXQUFXLFlBQVEsd0NBQW1CLE9BQU8sQ0FBQztBQUNwRCxZQUFNLFdBQVcsS0FBSyxvQkFBb0IsRUFBRSxnQkFBWSxpREFBNEIsRUFBRSxFQUFFLENBQUM7QUFBQSxJQUMzRixTQUFTLE9BQWdCO0FBQ3ZCLFlBQU0sY0FBVSxzQ0FBYyxLQUFLO0FBQ25DLDBCQUFJLDRDQUE0QyxPQUFPLEVBQUU7QUFDekQsVUFBSSxDQUFDLFdBQVc7QUFDZDtBQUFBLE1BQ0Y7QUFFQSxVQUFJO0FBQ0YsY0FBTSxXQUFXLEtBQUssb0JBQW9CLEVBQUUsZ0JBQVksaURBQTRCLFdBQVcsT0FBTyxFQUFFLENBQUM7QUFBQSxNQUMzRyxRQUFRO0FBQUEsTUFFUjtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVlBLE1BQWMsbUJBQW1CLGlCQUF3QztBQUN2RSxVQUFNLGtCQUFjLDJCQUFLLHVCQUFPLEdBQUcsdUJBQW1CLCtCQUFXLENBQUMsT0FBTztBQUN6RSxVQUFNLGVBQWUsR0FBRyxlQUFlO0FBRXZDLFFBQUk7QUFDRixnQkFBTSwyQkFBVSxhQUFhLE1BQU0sT0FBTztBQUMxQyxnQkFBTSxrQkFBSyxDQUFDLE9BQU8sTUFBTSxLQUFLLFVBQVUsU0FBUyxTQUFTLE1BQU0sR0FBRyxlQUFlLFlBQVksR0FBRyxFQUFFLFNBQVMsS0FBSyxDQUFDO0FBQ2xILGdCQUFNLGtCQUFLLENBQUMsT0FBTyxNQUFNLEtBQUssVUFBVSxRQUFRLGFBQWEsWUFBWSxHQUFHLEVBQUUsU0FBUyxLQUFLLENBQUM7QUFBQSxJQUMvRixVQUFFO0FBQ0EsZ0JBQU0sb0JBQUcsYUFBYSxFQUFFLE9BQU8sS0FBSyxDQUFDO0FBQUEsSUFDdkM7QUFBQSxFQUNGO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQWtCQSxNQUFjLDJCQUEyQixpQkFBd0M7QUFDL0UsUUFBSTtBQUNGLDBCQUFJLDREQUE0RCxlQUFlLEVBQUU7QUFDakYsZ0JBQU07QUFBQSxRQUNKLENBQUMsT0FBTyxNQUFNLEtBQUssVUFBVSxTQUFTLE1BQU0sT0FBTyxlQUFlO0FBQUEsUUFDbEUsRUFBRSxTQUFTLE1BQU0sc0JBQXNCLE1BQU0sdUJBQXVCLHlDQUF5QztBQUFBLE1BQy9HO0FBRUEsWUFBTSxVQUFVLFVBQU07QUFBQSxRQUNwQixDQUFDLE9BQU8sTUFBTSxLQUFLLFVBQVUsU0FBUyxNQUFNLE1BQU0sZUFBZTtBQUFBLFFBQ2pFLEVBQUUsU0FBUyxNQUFNLHNCQUFzQixNQUFNLHVCQUF1Qix5Q0FBeUM7QUFBQSxNQUMvRztBQUVBLFVBQUksUUFBUSxTQUFTLGVBQWUsR0FBRztBQUNyQztBQUFBLFVBQ0UsK0JBQStCLGVBQWU7QUFBQSxRQUVoRDtBQUFBLE1BQ0Y7QUFBQSxJQUNGLFNBQVMsT0FBZ0I7QUFDdkIsMEJBQUksa0VBQWtFLE9BQU8sS0FBSyxDQUFDLEVBQUU7QUFBQSxJQUN2RjtBQUFBLEVBQ0Y7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBTVEsb0NBQTBDO0FBQ2hELFFBQUksQ0FBQyxLQUFLLDJCQUEyQjtBQUNuQztBQUFBLElBQ0Y7QUFFQSxZQUFRLElBQUksUUFBUSxLQUFLLHlCQUF5QjtBQUNsRCxTQUFLLDRCQUE0QjtBQUFBLEVBQ25DO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFLQSxNQUFjLHFCQUFvQztBQUNoRCxVQUFNLFFBQVEsS0FBSyxJQUFJO0FBQ3ZCLFVBQU0sV0FBVyxRQUFRLEtBQUs7QUFDOUIsd0JBQUksd0RBQXdELE9BQU8sS0FBSyxnQ0FBZ0MsQ0FBQyxRQUFRO0FBRWpILFdBQU8sS0FBSyxJQUFJLElBQUksVUFBVTtBQUM1QixVQUFJO0FBQ0YsY0FBTSxVQUFVLE1BQU0sS0FBSyxRQUFRLFFBQVEsTUFBZTtBQUV4RCxnQkFBTSxNQUFNLFdBQVc7QUFDdkIsaUJBQU8sQ0FBQyxDQUFDLEtBQUssV0FBVztBQUFBLFFBQzNCLENBQUM7QUFDRCxZQUFJLFNBQVM7QUFDWCw4QkFBSSw0Q0FBNEMsT0FBTyxLQUFLLElBQUksSUFBSSxLQUFLLENBQUMsS0FBSztBQUMvRSxlQUFLLHFCQUFxQjtBQUMxQjtBQUFBLFFBQ0Y7QUFBQSxNQUNGLFFBQVE7QUFBQSxNQUVSO0FBRUEsMEJBQUksb0RBQW9ELE9BQU8sS0FBSyxJQUFJLElBQUksS0FBSyxDQUFDLGtCQUFrQjtBQUNwRyxZQUFNLE1BQU0sMENBQTBDO0FBQUEsSUFDeEQ7QUFFQSxVQUFNLElBQUksTUFBTSwrQ0FBK0MsT0FBTyxLQUFLLGdDQUFnQyxDQUFDLElBQUk7QUFBQSxFQUNsSDtBQUNGO0FBUUEsU0FBUyxNQUFNLElBQTJCO0FBQ3hDLFNBQU8sSUFBSSxRQUFRLENBQUMsWUFBWTtBQUM5QixlQUFXLFNBQVMsRUFBRTtBQUFBLEVBQ3hCLENBQUM7QUFDSDtBQVFBLFNBQVMsaUJBQWlCLFdBQTJCO0FBQ25ELFFBQU0sYUFBYSxVQUFVLFFBQVEsV0FBVyxFQUFFO0FBQ2xELFFBQU0sZ0JBQWdCLEtBQUssSUFBSSxXQUFXLFlBQVksR0FBRyxHQUFHLFdBQVcsWUFBWSxJQUFJLENBQUM7QUFDeEYsU0FBTyxXQUFXLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0M7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -143,6 +143,20 @@ export declare class AppiumTransport implements ObsidianTransport {
143
143
  private readonly appId;
144
144
  private readonly browser;
145
145
  private readonly deviceId;
146
+ /**
147
+ * The `process.on('exit')` handler that tears the channel down when nothing else will.
148
+ */
149
+ private disposeInputChannelOnExit;
150
+ /**
151
+ * The host half of the trusted-input channel: a CDP connection to the WebView, independent of the
152
+ * Appium session, opened lazily on first evaluate and reused (see **L39**).
153
+ */
154
+ private inputChannel;
155
+ /**
156
+ * Set once the trusted-input channel is known not to be openable here (iOS, a remote hub, no local
157
+ * `adb`), so the attempt is not repeated on every evaluate.
158
+ */
159
+ private isInputChannelUnavailable;
146
160
  /**
147
161
  * Tracks whether the driver is currently switched to the WebView context.
148
162
  *
@@ -201,6 +215,14 @@ export declare class AppiumTransport implements ObsidianTransport {
201
215
  * deletion so the session remains available for the owning process.
202
216
  */
203
217
  dispose(): Promise<void>;
218
+ /**
219
+ * Synchronous teardown for `process.on('exit')` handlers.
220
+ *
221
+ * Only the trusted-input channel needs it: the Appium session is the owning process's to end, and an
222
+ * abrupt exit is exactly when the async {@link AppiumTransport.dispose} never runs — which would strand
223
+ * the adb port forward on the device.
224
+ */
225
+ disposeSync(): void;
204
226
  /**
205
227
  * Evaluates a JavaScript expression inside Obsidian Mobile's WebView.
206
228
  *
@@ -287,6 +309,19 @@ export declare class AppiumTransport implements ObsidianTransport {
287
309
  * @param vaultPath - The absolute path to the vault on the host machine.
288
310
  */
289
311
  unregisterVault(vaultPath: string): Promise<void>;
312
+ /**
313
+ * Closes the trusted-input channel, if one is open.
314
+ */
315
+ private disposeInputChannel;
316
+ /**
317
+ * Opens the trusted-input channel if it is not already open, and re-opens it if the WebView went away.
318
+ *
319
+ * Installs a `Runtime.addBinding` function on the page and services every call to it for the life of the
320
+ * connection. The binding is exposed on *every* execution context of the page, so it survives the
321
+ * `location.reload()` that {@link AppiumTransport.registerVault} performs; only a full app restart, which
322
+ * destroys the WebView target, needs the reconnect below.
323
+ */
324
+ private ensureInputChannel;
290
325
  /**
291
326
  * Switches the driver to the `WEBVIEW_md.obsidian` context.
292
327
  *
@@ -306,6 +341,17 @@ export declare class AppiumTransport implements ObsidianTransport {
306
341
  * @returns The device-side vault path.
307
342
  */
308
343
  private getDeviceVaultPath;
344
+ /**
345
+ * Services one input request from the renderer: inject, then resolve the renderer's promise.
346
+ *
347
+ * Every failure path still resolves that promise — with an error message the renderer re-throws — because
348
+ * a request that is silently dropped would hang the closure until the whole run times out, and report
349
+ * nothing about why.
350
+ *
351
+ * @param connection - The channel the request arrived on.
352
+ * @param payload - The raw JSON payload the binding was called with.
353
+ */
354
+ private handleInputRequest;
309
355
  /**
310
356
  * Pushes the minimal `.obsidian/app.json` vault marker via `adb push`.
311
357
  *
@@ -334,6 +380,11 @@ export declare class AppiumTransport implements ObsidianTransport {
334
380
  * @param deviceVaultPath - The device-side vault directory path.
335
381
  */
336
382
  private removeDeviceVaultDirectory;
383
+ /**
384
+ * Drops the `process.on('exit')` handler that would otherwise close an already-closed channel, and would
385
+ * stack a listener per reconnect.
386
+ */
387
+ private unregisterInputChannelExitHandler;
337
388
  /**
338
389
  * Polls until `app.workspace.layoutReady` is `true` in the WebView.
339
390
  */