obsidian-integration-testing 12.1.2 → 12.3.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 (90) hide show
  1. package/README.md +1 -5
  2. package/dist/lib/cjs/app-config.cjs +137 -0
  3. package/dist/lib/cjs/app-config.d.cts +190 -0
  4. package/dist/lib/cjs/appium-session-config.cjs +7 -1
  5. package/dist/lib/cjs/appium-session-config.d.cts +20 -0
  6. package/dist/lib/cjs/cdp-command-timeout-error.cjs +50 -0
  7. package/dist/lib/cjs/cdp-command-timeout-error.d.cts +48 -0
  8. package/dist/lib/cjs/connect-to-cdp.cjs +1 -1
  9. package/dist/lib/cjs/connect-to-cdp.d.cts +5 -0
  10. package/dist/lib/cjs/emulator-arguments.cjs +19 -3
  11. package/dist/lib/cjs/emulator-arguments.d.cts +44 -0
  12. package/dist/lib/cjs/emulator-device-id.cjs +1 -1
  13. package/dist/lib/cjs/emulator-device-id.d.cts +7 -6
  14. package/dist/lib/cjs/emulator-marker.cjs +169 -0
  15. package/dist/lib/cjs/emulator-marker.d.cts +224 -0
  16. package/dist/lib/cjs/emulator-reaper.cjs +248 -0
  17. package/dist/lib/cjs/emulator-reaper.d.cts +225 -0
  18. package/dist/lib/cjs/emulator-reclaim.cjs +312 -0
  19. package/dist/lib/cjs/emulator-reclaim.d.cts +179 -0
  20. package/dist/lib/cjs/eval-cap-exceeded-error.cjs +61 -0
  21. package/dist/lib/cjs/eval-cap-exceeded-error.d.cts +92 -0
  22. package/dist/lib/cjs/eval-cap.cjs +29 -0
  23. package/dist/lib/cjs/eval-cap.d.cts +43 -0
  24. package/dist/lib/cjs/global-setup-core.cjs +2 -3
  25. package/dist/lib/cjs/index.cjs +21 -1
  26. package/dist/lib/cjs/index.d.cts +7 -0
  27. package/dist/lib/cjs/library.cjs +1 -1
  28. package/dist/lib/cjs/poll-in-obsidian.cjs +1 -1
  29. package/dist/lib/cjs/poll-in-obsidian.d.cts +7 -2
  30. package/dist/lib/cjs/setup-lock.cjs +56 -8
  31. package/dist/lib/cjs/setup-lock.d.cts +53 -0
  32. package/dist/lib/cjs/soft-keyboard-geometry.cjs +17 -8
  33. package/dist/lib/cjs/soft-keyboard-geometry.d.cts +46 -9
  34. package/dist/lib/cjs/soft-keyboard.cjs +7 -4
  35. package/dist/lib/cjs/soft-keyboard.d.cts +16 -2
  36. package/dist/lib/cjs/transport-appium.cjs +70 -5
  37. package/dist/lib/cjs/transport-appium.d.cts +35 -0
  38. package/dist/lib/cjs/transport-desktop-cdp.cjs +98 -19
  39. package/dist/lib/cjs/transport-desktop-cdp.d.cts +44 -1
  40. package/dist/lib/cjs/transport-factory.cjs +297 -190
  41. package/dist/lib/cjs/transport-factory.d.cts +15 -0
  42. package/dist/lib/cjs/transport-options.cjs +1 -1
  43. package/dist/lib/cjs/transport-options.d.cts +38 -1
  44. package/dist/lib/cjs/webview-cdp.cjs +45 -14
  45. package/dist/lib/cjs/webview-cdp.d.cts +17 -0
  46. package/dist/lib/esm/app-config.d.mts +190 -0
  47. package/dist/lib/esm/app-config.mjs +110 -0
  48. package/dist/lib/esm/appium-session-config.d.mts +20 -0
  49. package/dist/lib/esm/appium-session-config.mjs +6 -1
  50. package/dist/lib/esm/cdp-command-timeout-error.d.mts +48 -0
  51. package/dist/lib/esm/cdp-command-timeout-error.mjs +26 -0
  52. package/dist/lib/esm/connect-to-cdp.d.mts +5 -0
  53. package/dist/lib/esm/connect-to-cdp.mjs +1 -1
  54. package/dist/lib/esm/emulator-arguments.d.mts +44 -0
  55. package/dist/lib/esm/emulator-arguments.mjs +16 -2
  56. package/dist/lib/esm/emulator-device-id.d.mts +7 -6
  57. package/dist/lib/esm/emulator-device-id.mjs +1 -1
  58. package/dist/lib/esm/emulator-marker.d.mts +224 -0
  59. package/dist/lib/esm/emulator-marker.mjs +134 -0
  60. package/dist/lib/esm/emulator-reaper.d.mts +225 -0
  61. package/dist/lib/esm/emulator-reaper.mjs +211 -0
  62. package/dist/lib/esm/emulator-reclaim.d.mts +179 -0
  63. package/dist/lib/esm/emulator-reclaim.mjs +291 -0
  64. package/dist/lib/esm/eval-cap-exceeded-error.d.mts +92 -0
  65. package/dist/lib/esm/eval-cap-exceeded-error.mjs +36 -0
  66. package/dist/lib/esm/eval-cap.d.mts +43 -0
  67. package/dist/lib/esm/eval-cap.mjs +5 -0
  68. package/dist/lib/esm/global-setup-core.mjs +6 -4
  69. package/dist/lib/esm/index.d.mts +7 -0
  70. package/dist/lib/esm/index.mjs +21 -1
  71. package/dist/lib/esm/library.mjs +1 -1
  72. package/dist/lib/esm/poll-in-obsidian.d.mts +7 -2
  73. package/dist/lib/esm/poll-in-obsidian.mjs +1 -1
  74. package/dist/lib/esm/setup-lock.d.mts +53 -0
  75. package/dist/lib/esm/setup-lock.mjs +52 -7
  76. package/dist/lib/esm/soft-keyboard-geometry.d.mts +46 -9
  77. package/dist/lib/esm/soft-keyboard-geometry.mjs +17 -8
  78. package/dist/lib/esm/soft-keyboard.d.mts +16 -2
  79. package/dist/lib/esm/soft-keyboard.mjs +7 -4
  80. package/dist/lib/esm/transport-appium.d.mts +35 -0
  81. package/dist/lib/esm/transport-appium.mjs +73 -5
  82. package/dist/lib/esm/transport-desktop-cdp.d.mts +44 -1
  83. package/dist/lib/esm/transport-desktop-cdp.mjs +98 -19
  84. package/dist/lib/esm/transport-factory.d.mts +15 -0
  85. package/dist/lib/esm/transport-factory.mjs +305 -184
  86. package/dist/lib/esm/transport-options.d.mts +38 -1
  87. package/dist/lib/esm/transport-options.mjs +1 -1
  88. package/dist/lib/esm/webview-cdp.d.mts +17 -0
  89. package/dist/lib/esm/webview-cdp.mjs +45 -14
  90. package/package.json +4 -4
@@ -28,7 +28,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var setup_lock_exports = {};
30
30
  __export(setup_lock_exports, {
31
- acquireSetupLock: () => acquireSetupLock
31
+ ANDROID_SETUP_LOCK_SCOPE: () => ANDROID_SETUP_LOCK_SCOPE,
32
+ acquireSetupLock: () => acquireSetupLock,
33
+ checkIsSetupLockHeld: () => checkIsSetupLockHeld,
34
+ tryAcquireSetupLock: () => tryAcquireSetupLock
32
35
  });
33
36
  module.exports = __toCommonJS(setup_lock_exports);
34
37
  var import_node_fs = require("node:fs");
@@ -37,6 +40,7 @@ var import_node_path = require("node:path");
37
40
  var import_node_process = __toESM(require("node:process"), 1);
38
41
  var import_error_to_string = require("./error-to-string.cjs");
39
42
  var import_log = require("./log.cjs");
43
+ const ANDROID_SETUP_LOCK_SCOPE = "android";
40
44
  const LOCK_DIR_NAME = "obsidian-integration-testing";
41
45
  const LOCK_FILE_SUFFIX = ".setup.lock";
42
46
  const POLL_INTERVAL_IN_MILLISECONDS = 500;
@@ -75,9 +79,8 @@ async function acquireSetupLock(params) {
75
79
  });
76
80
  }
77
81
  const info = readLockFileInfo(lockFilePath);
78
- if (info && checkIsLockStale(info)) {
79
- (0, import_log.log)(`[integration-setup:${label}] Stealing stale '${scope}' setup lock from ${describeInfo(info)}.`);
80
- (0, import_node_fs.rmSync)(lockFilePath, { force: true });
82
+ if (info && checkIsLockStale(info, HEARTBEAT_STALE_IN_MILLISECONDS)) {
83
+ stealStaleLock({ info, label, lockFilePath, scope });
81
84
  if (Date.now() >= deadlineInMilliseconds) {
82
85
  throw createTimeoutError({
83
86
  info,
@@ -109,10 +112,48 @@ async function acquireSetupLock(params) {
109
112
  await delay(POLL_INTERVAL_IN_MILLISECONDS);
110
113
  }
111
114
  }
112
- function checkIsLockStale(info) {
115
+ function checkIsSetupLockHeld(scope) {
116
+ let text;
117
+ try {
118
+ text = (0, import_node_fs.readFileSync)(getLockFilePath(scope), "utf-8");
119
+ } catch (error) {
120
+ return getErrorCode(error) !== "ENOENT";
121
+ }
122
+ let info;
123
+ try {
124
+ info = JSON.parse(text);
125
+ } catch {
126
+ return true;
127
+ }
128
+ return !checkIsLockStale(info, HEARTBEAT_STALE_IN_MILLISECONDS);
129
+ }
130
+ function tryAcquireSetupLock(params) {
131
+ const { label, scope } = params;
132
+ const lockFilePath = getLockFilePath(scope);
133
+ (0, import_node_fs.mkdirSync)(getLockDirectory(), { recursive: true });
134
+ let ownInfo = tryCreateLockFile(lockFilePath, label);
135
+ if (!ownInfo) {
136
+ const info = readLockFileInfo(lockFilePath);
137
+ if (!info || !checkIsLockStale(info, params.staleAfterSilenceInMilliseconds ?? HEARTBEAT_STALE_IN_MILLISECONDS)) {
138
+ return void 0;
139
+ }
140
+ stealStaleLock({ info, label, lockFilePath, scope });
141
+ ownInfo = tryCreateLockFile(lockFilePath, label);
142
+ if (!ownInfo) {
143
+ return void 0;
144
+ }
145
+ }
146
+ return createLockHandle({
147
+ label,
148
+ lockFilePath,
149
+ ownInfo,
150
+ scope
151
+ });
152
+ }
153
+ function checkIsLockStale(info, heartbeatStaleInMilliseconds) {
113
154
  const silentForInMilliseconds = Date.now() - getLastSeenAtInMilliseconds(info);
114
155
  if (info.hostname === (0, import_node_os.hostname)()) {
115
- return !checkIsProcessAlive(info.pid) || silentForInMilliseconds > HEARTBEAT_STALE_IN_MILLISECONDS;
156
+ return !checkIsProcessAlive(info.pid) || silentForInMilliseconds > heartbeatStaleInMilliseconds;
116
157
  }
117
158
  return silentForInMilliseconds > STALE_LOCK_AGE_IN_MILLISECONDS;
118
159
  }
@@ -245,6 +286,10 @@ function readLockFileInfo(lockFilePath) {
245
286
  return null;
246
287
  }
247
288
  }
289
+ function stealStaleLock(params) {
290
+ (0, import_log.log)(`[integration-setup:${params.label}] Stealing stale '${params.scope}' setup lock from ${describeInfo(params.info)}.`);
291
+ (0, import_node_fs.rmSync)(params.lockFilePath, { force: true });
292
+ }
248
293
  function tryCreateLockFile(lockFilePath, label) {
249
294
  const nowInMilliseconds = Date.now();
250
295
  const info = {
@@ -266,6 +311,9 @@ function tryCreateLockFile(lockFilePath, label) {
266
311
  }
267
312
  // Annotate the CommonJS export names for ESM import in node:
268
313
  0 && (module.exports = {
269
- acquireSetupLock
314
+ ANDROID_SETUP_LOCK_SCOPE,
315
+ acquireSetupLock,
316
+ checkIsSetupLockHeld,
317
+ tryAcquireSetupLock
270
318
  });
271
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3NldHVwLWxvY2sudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBDcm9zcy1wcm9jZXNzIGFkdmlzb3J5IGxvY2sgdGhhdCBzZXJpYWxpemVzIHdob2xlIGludGVncmF0aW9uLXRlc3QgcnVucy5cbiAqXG4gKiBUd28gdGVzdCBydW5zIHRoYXQgZHJpdmUgdGhlIHNhbWUgc2hhcmVkIHJlc291cmNlcyBjb3JydXB0IGVhY2ggb3RoZXI6IG9uXG4gKiBkZXNrdG9wIHRoZXkgc2hhcmUgdGhlIHNpbmdsZSBsb2NhbCBPYnNpZGlhbiBpbnN0YW5jZSwgaXRzIGBvYnNpZGlhbi5qc29uYFxuICogcmVnaXN0cnksIGFuZCB0aGUgQ0RQIHBvcnQ7IG9uIEFuZHJvaWQgdGhleSBzaGFyZSB0aGUgZW11bGF0b3IgYW5kIHRoZSBBcHBpdW1cbiAqIHNlcnZlci4gT25lIHJ1bidzIHNldHVwL3RlYXJkb3duIGtpbGxzIG9yIHJlY29uZmlndXJlcyB0aGUgaW5zdGFuY2UgdGhlIG90aGVyXG4gKiBydW4gaXMgbWlkLWV2YWwgb24gKG9ic2VydmVkIGFzIGBFQ09OTlJFRlVTRURgIG9yIFwidmF1bHQgbm90IG9wZW5cIiksIHNvIGJvdGhcbiAqIHJ1bnMgZmFpbC5cbiAqXG4gKiBUaGlzIGxvY2sgbWFrZXMgdGhlIHNlY29uZCBydW4gKip3YWl0KiogZm9yIHRoZSBmaXJzdCB0byBmaW5pc2ggaW5zdGVhZCBvZlxuICogcnVubmluZyBjb25jdXJyZW50bHkuIEl0IGlzIGhlbGQgZm9yIHRoZSBlbnRpcmUgcnVuOiBhY3F1aXJlZCBhdCB0aGUgc3RhcnQgb2ZcbiAqIHRoZSBjb3JlIHNldHVwIGFuZCByZWxlYXNlZCBieSB0aGUgY29yZSB0ZWFyZG93biAoYW5kIGJ5IHRoZSBwcm9jZXNzIGNsZWFudXBcbiAqIGhhbmRsZXJzKS4gVGhlIGxvY2sgaXMgYSBzZW50aW5lbCBmaWxlIGluIGEgc2hhcmVkIHRlbXAgZGlyZWN0b3J5LCBhbmQgaXRzXG4gKiBob2xkZXIga2VlcHMgYSAqKmhlYXJ0YmVhdCoqIHRpbWVzdGFtcCBpbnNpZGUgaXQgZnJlc2ggZm9yIGFzIGxvbmcgYXMgaXQgaG9sZHNcbiAqIHRoZSBsb2NrIFx1MjAxNCBzbyBhIHJ1biB0aGF0IGNyYXNoZWQgd2l0aG91dCByZWxlYXNpbmcgc3RvcHMgYmVhdGluZyBhbmQgdGhlIG5leHRcbiAqIHJ1biBkZXRlY3RzIHRoZSBsb2NrIGFzIHN0YWxlIGFuZCBzdGVhbHMgaXQuXG4gKlxuICogVGhlIGhlYXJ0YmVhdCwgbm90IHRoZSBob2xkZXIncyBQSUQsIGlzIHdoYXQgcHJvdmVzIGEgaG9sZGVyIGlzIHN0aWxsIHRoZXJlOiBhXG4gKiBQSUQgcHJvYmUgb25seSBhbnN3ZXJzIFwiZG9lcyAqYSogcHJvY2VzcyB3aXRoIHRoaXMgUElEIGV4aXN0XCIsIHdoaWNoIGFcbiAqIHJlY3ljbGVkIFBJRCBzYXRpc2ZpZXMgbG9uZyBhZnRlciB0aGUgcmVhbCBob2xkZXIgZGllZCBcdTIwMTQgbGVhdmluZyBldmVyeSBsYXRlclxuICogcnVuIHRvIGJsb2NrIGZvciB0aGUgZnVsbCBhY3F1aXNpdGlvbiB0aW1lb3V0LlxuICovXG5cbmltcG9ydCB7XG4gIG1rZGlyU3luYyxcbiAgcmVhZEZpbGVTeW5jLFxuICBybVN5bmMsXG4gIHdyaXRlRmlsZVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBob3N0bmFtZSxcbiAgdG1wZGlyXG59IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQgeyBlcnJvclRvU3RyaW5nIH0gZnJvbSAnLi9lcnJvci10by1zdHJpbmcuY2pzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLmNqcyc7XG5cbmNvbnN0IExPQ0tfRElSX05BTUUgPSAnb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZyc7XG5jb25zdCBMT0NLX0ZJTEVfU1VGRklYID0gJy5zZXR1cC5sb2NrJztcbmNvbnN0IFBPTExfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gNTAwO1xuY29uc3QgTUlMTElTRUNPTkRTX1BFUl9TRUNPTkQgPSAxMDAwO1xuY29uc3QgU0VDT05EU19QRVJfTUlOVVRFID0gNjA7XG5jb25zdCBIRUFSVEJFQVRfSU5URVJWQUxfSU5fU0VDT05EUyA9IDU7XG5jb25zdCBIRUFSVEJFQVRfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gSEVBUlRCRUFUX0lOVEVSVkFMX0lOX1NFQ09ORFMgKiBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORDtcbi8vIEdlbmVyb3VzIG9uIHB1cnBvc2U6IGEgZGVhZCBob2xkZXIgaXMgbm9ybWFsbHkgY2F1Z2h0IGluc3RhbnRseSBieSB0aGUgUElEXG4vLyBQcm9iZSwgc28gdGhpcyB0aHJlc2hvbGQgb25seSBoYXMgdG8gY292ZXIgdGhlIHJlY3ljbGVkLVBJRCBjYXNlLiBUd28gbWludXRlc1xuLy8gS2VlcHMgYSBob2xkZXIgdGhhdCBibG9ja3MgaXRzIGV2ZW50IGxvb3AgZHVyaW5nIGhlYXZ5IHN5bmNocm9ub3VzIHdvcmsgKGFcbi8vIExhcmdlIHZhdWx0IHN5bmMsIGFuIGluc3RhbGxlciB1bnBhY2spIGZyb20gYmVpbmcgcm9iYmVkIHdoaWxlIGl0IGlzIGFsaXZlLlxuY29uc3QgTUlTU0VEX0hFQVJUQkVBVFNfQkVGT1JFX1NUQUxFID0gMjQ7XG5jb25zdCBIRUFSVEJFQVRfU1RBTEVfSU5fTUlMTElTRUNPTkRTID0gSEVBUlRCRUFUX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyAqIE1JU1NFRF9IRUFSVEJFQVRTX0JFRk9SRV9TVEFMRTtcbmNvbnN0IFdBSVRfTE9HX0lOVEVSVkFMX0lOX1NFQ09ORFMgPSAzMDtcbmNvbnN0IFdBSVRfTE9HX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IFdBSVRfTE9HX0lOVEVSVkFMX0lOX1NFQ09ORFMgKiBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORDtcbmNvbnN0IFNUQUxFX0xPQ0tfQUdFX0lOX01JTlVURVMgPSAzMDtcbmNvbnN0IERFRkFVTFRfVElNRU9VVF9JTl9NSU5VVEVTID0gNjA7XG5jb25zdCBTVEFMRV9MT0NLX0FHRV9JTl9NSUxMSVNFQ09ORFMgPSBTVEFMRV9MT0NLX0FHRV9JTl9NSU5VVEVTICogU0VDT05EU19QRVJfTUlOVVRFICogTUlMTElTRUNPTkRTX1BFUl9TRUNPTkQ7XG5jb25zdCBERUZBVUxUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gREVGQVVMVF9USU1FT1VUX0lOX01JTlVURVMgKiBTRUNPTkRTX1BFUl9NSU5VVEUgKiBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORDtcbmNvbnN0IFBST0NFU1NfRVhJU1RFTkNFX1BST0JFX1NJR05BTCA9IDA7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGFjcXVpcmVTZXR1cExvY2t9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFjcXVpcmVTZXR1cExvY2tQYXJhbXMge1xuICAvKipcbiAgU2hvcnQgdHJhbnNwb3J0IGxhYmVsIGZvciBsb2cgbWVzc2FnZXMgKGUuZy4gYFwib2JzaWRpYW4tY2xpXCJgKS5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIExvZ2ljYWwgc2NvcGUgdGhlIGxvY2sgc2VyaWFsaXplcyB3aXRoaW4uIFJ1bnMgdGhhdCBzaGFyZSByZXNvdXJjZXMgbXVzdFxuICAgKiB1c2UgdGhlIHNhbWUgc2NvcGUgKGUuZy4gYFwiZGVza3RvcFwiYCBmb3IgdGhlIENMSS9DRFAgdHJhbnNwb3J0cywgYFwiYW5kcm9pZFwiYFxuICAgKiBmb3IgdGhlIEFwcGl1bSB0cmFuc3BvcnQpLlxuICAgKi9cbiAgcmVhZG9ubHkgc2NvcGU6IHN0cmluZztcblxuICAvKipcbiAgICogTWF4aW11bSB0aW1lIHRvIHdhaXQgZm9yIGEgY29tcGV0aW5nIHJ1biB0byByZWxlYXNlIHRoZSBsb2NrIGJlZm9yZSBnaXZpbmdcbiAgICogdXAgYW5kIHRocm93aW5nLlxuICAgKlxuICAgKiBAZGVmYXVsdCAxIGhvdXJcbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXRJbk1pbGxpc2Vjb25kcz86IG51bWJlciB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBBIGhlbGQgc2V0dXAgbG9jay4gUmVsZWFzZSBpdCBvbmNlIHRoZSBydW4ncyB0ZWFyZG93biBpcyBjb21wbGV0ZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZXR1cExvY2sge1xuICAvKipcbiAgUmVsZWFzZXMgdGhlIGxvY2suIFNhZmUgdG8gY2FsbCBtb3JlIHRoYW4gb25jZS5cbiAgICovXG4gIHJlbGVhc2UoKTogdm9pZDtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgY3JlYXRlTG9ja0hhbmRsZX0uXG4gKi9cbmludGVyZmFjZSBDcmVhdGVMb2NrSGFuZGxlUGFyYW1zIHtcbiAgLyoqXG4gIFRoZSB0cmFuc3BvcnQgbGFiZWwgb2YgdGhpcyBydW4uXG4gICAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgcGF0aCB0byB0aGUgbG9jayBmaWxlIHRoaXMgcnVuIGp1c3QgY3JlYXRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2tGaWxlUGF0aDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgbG9jayBpbmZvIHRoaXMgcnVuIHdyb3RlIHdoZW4gaXQgYWNxdWlyZWQgdGhlIGxvY2suXG4gICAqL1xuICByZWFkb25seSBvd25JbmZvOiBMb2NrRmlsZUluZm87XG5cbiAgLyoqXG4gIFRoZSBsb2NrIHNjb3BlLCBmb3IgbG9nIG1lc3NhZ2VzLlxuICAgKi9cbiAgcmVhZG9ubHkgc2NvcGU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgY3JlYXRlVGltZW91dEVycm9yfS5cbiAqL1xuaW50ZXJmYWNlIENyZWF0ZVRpbWVvdXRFcnJvclBhcmFtcyB7XG4gIC8qKlxuICBUaGUgY3VycmVudCBob2xkZXIncyBsb2NrIGluZm8sIG9yIGBudWxsYCBpZiBpdCBjb3VsZCBub3QgYmUgcmVhZC5cbiAgICovXG4gIHJlYWRvbmx5IGluZm86IExvY2tGaWxlSW5mbyB8IG51bGw7XG5cbiAgLyoqXG4gIFRoZSBsb2NrIHNjb3BlLlxuICAgKi9cbiAgcmVhZG9ubHkgc2NvcGU6IHN0cmluZztcblxuICAvKipcbiAgVGhlIHRpbWVvdXQgdGhhdCBlbGFwc2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgdGltZW91dEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGZvcm1hdFdhaXRNZXNzYWdlfS5cbiAqL1xuaW50ZXJmYWNlIEZvcm1hdFdhaXRNZXNzYWdlUGFyYW1zIHtcbiAgLyoqXG4gIFRoZSBjdXJyZW50IGhvbGRlcidzIGxvY2sgaW5mbywgb3IgYG51bGxgIGlmIGl0IGNvdWxkIG5vdCBiZSByZWFkLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5mbzogTG9ja0ZpbGVJbmZvIHwgbnVsbDtcblxuICAvKipcbiAgVGhlIHRyYW5zcG9ydCBsYWJlbCBvZiB0aGUgd2FpdGluZyBydW4uXG4gICAqL1xuICByZWFkb25seSBsYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICBIb3cgbXVjaCBvZiB0aGUgYWNxdWlzaXRpb24gdGltZW91dCBpcyBsZWZ0LlxuICAgKi9cbiAgcmVhZG9ubHkgcmVtYWluaW5nSW5NaWxsaXNlY29uZHM6IG51bWJlcjtcblxuICAvKipcbiAgVGhlIGxvY2sgc2NvcGUuXG4gICAqL1xuICByZWFkb25seSBzY29wZTogc3RyaW5nO1xuXG4gIC8qKlxuICBIb3cgbG9uZyB0aGlzIHJ1biBoYXMgYmVlbiB3YWl0aW5nIHNvIGZhci5cbiAgICovXG4gIHJlYWRvbmx5IHdhaXRlZEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG59XG5cbi8qKlxuICogVGhlIEpTT04gcGF5bG9hZCBzdG9yZWQgaW5zaWRlIGEgbG9jayBmaWxlLCBpZGVudGlmeWluZyB0aGUgaG9sZGVyLlxuICovXG5pbnRlcmZhY2UgTG9ja0ZpbGVJbmZvIHtcbiAgLyoqXG4gIFdoZW4gdGhlIGxvY2sgd2FzIGFjcXVpcmVkIChgRGF0ZS5ub3coKWAgZXBvY2ggbWlsbGlzZWNvbmRzKS5cbiAgICovXG4gIHJlYWRvbmx5IGFjcXVpcmVkQXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaGVuIHRoZSBob2xkZXIgbGFzdCBwcm92ZWQgaXQgd2FzIHN0aWxsIGFsaXZlIChgRGF0ZS5ub3coKWAgZXBvY2hcbiAgICogbWlsbGlzZWNvbmRzKSwgcmVmcmVzaGVkIGV2ZXJ5IHtAbGluayBIRUFSVEJFQVRfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTfVxuICAgKiB3aGlsZSB0aGUgbG9jayBpcyBoZWxkLlxuICAgKlxuICAgKiBBYnNlbnQgaW4gYSBsb2NrIGZpbGUgd3JpdHRlbiBieSBhbiBvbGRlciB2ZXJzaW9uIG9mIHRoaXMgcGFja2FnZSwgd2hpY2hcbiAgICogc3RhbXBlZCB0aGUgUElEIGJ1dCBuZXZlciBiZWF0LlxuICAgKi9cbiAgcmVhZG9ubHkgaGVhcnRiZWF0QXRJbk1pbGxpc2Vjb25kcz86IG51bWJlciB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgVGhlIGhvc3QgdGhhdCBob2xkcyB0aGUgbG9jayAoUElEIGxpdmVuZXNzIGlzIG9ubHkgdmFsaWQgb24gdGhlIHNhbWUgaG9zdCkuXG4gICAqL1xuICByZWFkb25seSBob3N0bmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgdHJhbnNwb3J0IGxhYmVsIG9mIHRoZSBob2xkaW5nIHJ1bi5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBwcm9jZXNzIElEIG9mIHRoZSBob2xkaW5nIHJ1bi5cbiAgICovXG4gIHJlYWRvbmx5IHBpZDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBkaWRSZWZyZXNoSGVhcnRiZWF0fS5cbiAqL1xuaW50ZXJmYWNlIFJlZnJlc2hIZWFydGJlYXRQYXJhbXMge1xuICAvKipcbiAgVGhlIHRyYW5zcG9ydCBsYWJlbCBvZiB0aGlzIHJ1bi5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBwYXRoIHRvIHRoZSBsb2NrIGZpbGUgdG8gcmVmcmVzaC5cbiAgICovXG4gIHJlYWRvbmx5IGxvY2tGaWxlUGF0aDogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgbG9jayBpbmZvIHRoaXMgcnVuIHdyb3RlIHdoZW4gaXQgYWNxdWlyZWQgdGhlIGxvY2suXG4gICAqL1xuICByZWFkb25seSBvd25JbmZvOiBMb2NrRmlsZUluZm87XG59XG5cbi8qKlxuICogQWNxdWlyZXMgdGhlIGNyb3NzLXByb2Nlc3Mgc2V0dXAgbG9jayBmb3IgdGhlIGdpdmVuIHNjb3BlLCB3YWl0aW5nIHVudGlsIGFueVxuICogY29tcGV0aW5nIHJ1biByZWxlYXNlcyBpdCAob3IgaXRzIGxvY2sgaXMgZGV0ZWN0ZWQgYXMgc3RhbGUpLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgbG9jayBwYXJhbWV0ZXJzLlxuICogQHJldHVybnMgQSBoYW5kbGUgd2hvc2Uge0BsaW5rIFNldHVwTG9jay5yZWxlYXNlfSBmcmVlcyB0aGUgbG9jay5cbiAqIEB0aHJvd3MgSWYgdGhlIGxvY2sgY2Fubm90IGJlIGFjcXVpcmVkIHdpdGhpbiBgdGltZW91dEluTWlsbGlzZWNvbmRzYC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFjcXVpcmVTZXR1cExvY2socGFyYW1zOiBBY3F1aXJlU2V0dXBMb2NrUGFyYW1zKTogUHJvbWlzZTxTZXR1cExvY2s+IHtcbiAgY29uc3Qge1xuICAgIGxhYmVsLFxuICAgIHNjb3BlXG4gIH0gPSBwYXJhbXM7XG4gIGNvbnN0IHRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IHBhcmFtcy50aW1lb3V0SW5NaWxsaXNlY29uZHMgPz8gREVGQVVMVF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgY29uc3QgbG9ja0ZpbGVQYXRoID0gZ2V0TG9ja0ZpbGVQYXRoKHNjb3BlKTtcbiAgbWtkaXJTeW5jKGdldExvY2tEaXJlY3RvcnkoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgY29uc3Qgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMgPSBEYXRlLm5vdygpO1xuICBjb25zdCBkZWFkbGluZUluTWlsbGlzZWNvbmRzID0gc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMgKyB0aW1lb3V0SW5NaWxsaXNlY29uZHM7XG4gIGxldCBsYXN0TG9nZ2VkV2FpdEF0SW5NaWxsaXNlY29uZHM6IG51bGwgfCBudW1iZXIgPSBudWxsO1xuXG4gIGZvciAoOzspIHtcbiAgICBjb25zdCBvd25JbmZvID0gdHJ5Q3JlYXRlTG9ja0ZpbGUobG9ja0ZpbGVQYXRoLCBsYWJlbCk7XG4gICAgaWYgKG93bkluZm8pIHtcbiAgICAgIHJldHVybiBjcmVhdGVMb2NrSGFuZGxlKHtcbiAgICAgICAgbGFiZWwsXG4gICAgICAgIGxvY2tGaWxlUGF0aCxcbiAgICAgICAgb3duSW5mbyxcbiAgICAgICAgc2NvcGVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGluZm8gPSByZWFkTG9ja0ZpbGVJbmZvKGxvY2tGaWxlUGF0aCk7XG4gICAgaWYgKGluZm8gJiYgY2hlY2tJc0xvY2tTdGFsZShpbmZvKSkge1xuICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFN0ZWFsaW5nIHN0YWxlICcke3Njb3BlfScgc2V0dXAgbG9jayBmcm9tICR7ZGVzY3JpYmVJbmZvKGluZm8pfS5gKTtcbiAgICAgIHJtU3luYyhsb2NrRmlsZVBhdGgsIHsgZm9yY2U6IHRydWUgfSk7XG4gICAgICAvLyBSZXRyeSBpbW1lZGlhdGVseSBcdTIwMTQgYnV0IHN0aWxsIGhvbm91ciB0aGUgZGVhZGxpbmUsIHNvIGEgbG9jayB0aGF0IGFcbiAgICAgIC8vIENvbXBldGluZyBydW4ga2VlcHMgcmVjcmVhdGluZyBjYW5ub3Qgc3BpbiB0aGlzIGxvb3AgZm9yZXZlci5cbiAgICAgIGlmIChEYXRlLm5vdygpID49IGRlYWRsaW5lSW5NaWxsaXNlY29uZHMpIHtcbiAgICAgICAgdGhyb3cgY3JlYXRlVGltZW91dEVycm9yKHtcbiAgICAgICAgICBpbmZvLFxuICAgICAgICAgIHNjb3BlLFxuICAgICAgICAgIHRpbWVvdXRJbk1pbGxpc2Vjb25kc1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IG5vd0luTWlsbGlzZWNvbmRzID0gRGF0ZS5ub3coKTtcbiAgICBpZiAobm93SW5NaWxsaXNlY29uZHMgPj0gZGVhZGxpbmVJbk1pbGxpc2Vjb25kcykge1xuICAgICAgdGhyb3cgY3JlYXRlVGltZW91dEVycm9yKHtcbiAgICAgICAgaW5mbyxcbiAgICAgICAgc2NvcGUsXG4gICAgICAgIHRpbWVvdXRJbk1pbGxpc2Vjb25kc1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2hvdWxkTG9nV2FpdCA9IGxhc3RMb2dnZWRXYWl0QXRJbk1pbGxpc2Vjb25kcyA9PT0gbnVsbFxuICAgICAgfHwgbm93SW5NaWxsaXNlY29uZHMgLSBsYXN0TG9nZ2VkV2FpdEF0SW5NaWxsaXNlY29uZHMgPj0gV0FJVF9MT0dfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTO1xuICAgIGlmIChzaG91bGRMb2dXYWl0KSB7XG4gICAgICBsYXN0TG9nZ2VkV2FpdEF0SW5NaWxsaXNlY29uZHMgPSBub3dJbk1pbGxpc2Vjb25kcztcbiAgICAgIGxvZyhmb3JtYXRXYWl0TWVzc2FnZSh7XG4gICAgICAgIGluZm8sXG4gICAgICAgIGxhYmVsLFxuICAgICAgICByZW1haW5pbmdJbk1pbGxpc2Vjb25kczogZGVhZGxpbmVJbk1pbGxpc2Vjb25kcyAtIG5vd0luTWlsbGlzZWNvbmRzLFxuICAgICAgICBzY29wZSxcbiAgICAgICAgd2FpdGVkSW5NaWxsaXNlY29uZHM6IG5vd0luTWlsbGlzZWNvbmRzIC0gc3RhcnRlZEF0SW5NaWxsaXNlY29uZHNcbiAgICAgIH0pKTtcbiAgICB9XG5cbiAgICBhd2FpdCBkZWxheShQT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG4gIH1cbn1cblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgYSBsb2NrIGNhbiBiZSBjb25zaWRlcmVkIGFiYW5kb25lZC5cbiAqXG4gKiBBIGxpdmUgaG9sZGVyIHJlZnJlc2hlcyBpdHMgaGVhcnRiZWF0IGV2ZXJ5XG4gKiB7QGxpbmsgSEVBUlRCRUFUX0lOVEVSVkFMX0lOX01JTExJU0VDT05EU30sIHNvIGEgaGVhcnRiZWF0IHRoYXQgc3RvcHBlZCBtZWFuc1xuICogdGhlIGhvbGRlciBpcyBnb25lLiBUaGF0IGlzIHRoZSBwcmltYXJ5IHNpZ25hbCwgYmVjYXVzZSB0aGUgcmVjb3JkZWQgUElEIGFsb25lXG4gKiBjYW5ub3QgYmUgdHJ1c3RlZDoge0BsaW5rIGNoZWNrSXNQcm9jZXNzQWxpdmV9IG9ubHkgYW5zd2VycyBcImRvZXMgKmEqIHByb2Nlc3NcbiAqIHdpdGggdGhpcyBQSUQgZXhpc3RcIiwgd2hpY2ggYSByZWN5Y2xlZCBQSUQgc2F0aXNmaWVzIGxvbmcgYWZ0ZXIgdGhlIGhvbGRlclxuICogZGllZC5cbiAqXG4gKiBPbiB0aGUgc2FtZSBob3N0IGEgZGVhZCBQSUQgaXMgc3RpbGwgYW4gaW1tZWRpYXRlIGdpdmUtYXdheSwgc28gaXQgaXMga2VwdCBhc1xuICogYSBmYXN0IHBhdGguIE9uIGEgZGlmZmVyZW50IGhvc3QgKGEgc2hhcmVkL25ldHdvcmsgdGVtcCBkaXJlY3RvcnkpIHRoZSBQSURcbiAqIGNhbm5vdCBiZSBwcm9iZWQgYXQgYWxsIGFuZCB0aGUgdHdvIGNsb2NrcyBtYXkgZGlzYWdyZWUsIHNvIHRoZSBtdWNoIHdpZGVyXG4gKiB7QGxpbmsgU1RBTEVfTE9DS19BR0VfSU5fTUlMTElTRUNPTkRTfSB0aHJlc2hvbGQgaXMgdXNlZCBpbnN0ZWFkLlxuICpcbiAqIEBwYXJhbSBpbmZvIC0gVGhlIHBhcnNlZCBsb2NrIGluZm8uXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGxvY2sgaXMgc3RhbGUgYW5kIG1heSBiZSBzdG9sZW4uXG4gKi9cbmZ1bmN0aW9uIGNoZWNrSXNMb2NrU3RhbGUoaW5mbzogTG9ja0ZpbGVJbmZvKTogYm9vbGVhbiB7XG4gIGNvbnN0IHNpbGVudEZvckluTWlsbGlzZWNvbmRzID0gRGF0ZS5ub3coKSAtIGdldExhc3RTZWVuQXRJbk1pbGxpc2Vjb25kcyhpbmZvKTtcblxuICBpZiAoaW5mby5ob3N0bmFtZSA9PT0gaG9zdG5hbWUoKSkge1xuICAgIHJldHVybiAhY2hlY2tJc1Byb2Nlc3NBbGl2ZShpbmZvLnBpZCkgfHwgc2lsZW50Rm9ySW5NaWxsaXNlY29uZHMgPiBIRUFSVEJFQVRfU1RBTEVfSU5fTUlMTElTRUNPTkRTO1xuICB9XG5cbiAgcmV0dXJuIHNpbGVudEZvckluTWlsbGlzZWNvbmRzID4gU1RBTEVfTE9DS19BR0VfSU5fTUlMTElTRUNPTkRTO1xufVxuXG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciBhIGxvY2sgZmlsZSBzdGlsbCBuYW1lcyB0aGlzIHByb2Nlc3MgYXMgaXRzIGhvbGRlci5cbiAqXG4gKiBAcGFyYW0gaW5mbyAtIFRoZSBwYXJzZWQgbG9jayBpbmZvLlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoaXMgcHJvY2VzcyBob2xkcyB0aGUgbG9jay5cbiAqL1xuZnVuY3Rpb24gY2hlY2tJc093bkxvY2soaW5mbzogTG9ja0ZpbGVJbmZvKTogYm9vbGVhbiB7XG4gIHJldHVybiBpbmZvLnBpZCA9PT0gcHJvY2Vzcy5waWQgJiYgaW5mby5ob3N0bmFtZSA9PT0gaG9zdG5hbWUoKTtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIHByb2Nlc3Mgd2l0aCB0aGUgZ2l2ZW4gUElEIGlzIGN1cnJlbnRseSBhbGl2ZS5cbiAqXG4gKiBAcGFyYW0gcGlkIC0gVGhlIHByb2Nlc3MgSUQgdG8gcHJvYmUuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHByb2Nlc3MgZXhpc3RzLlxuICovXG5mdW5jdGlvbiBjaGVja0lzUHJvY2Vzc0FsaXZlKHBpZDogbnVtYmVyKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgcHJvY2Vzcy5raWxsKHBpZCwgUFJPQ0VTU19FWElTVEVOQ0VfUFJPQkVfU0lHTkFMKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAvLyBgRVBFUk1gIG1lYW5zIHRoZSBwcm9jZXNzIGV4aXN0cyBidXQgaXMgb3duZWQgYnkgYW5vdGhlciB1c2VyIFx1MjAxNCBzdGlsbCBhbGl2ZS5cbiAgICByZXR1cm4gZ2V0RXJyb3JDb2RlKGVycm9yKSA9PT0gJ0VQRVJNJztcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSB7QGxpbmsgU2V0dXBMb2NrfSBoYW5kbGUgdGhhdCBrZWVwcyB0aGUgbG9jaydzIGhlYXJ0YmVhdCBmcmVzaCB3aGlsZVxuICogaGVsZCBhbmQgcmVtb3ZlcyB0aGUgbG9jayBmaWxlIG9uIHJlbGVhc2UuXG4gKlxuICogVGhlIGhlYXJ0YmVhdCB0aW1lciBpcyBgdW5yZWZgZWQgc28gaXQgY2FuIG5ldmVyIGtlZXAgdGhlIHByb2Nlc3MgYWxpdmUgb24gaXRzXG4gKiBvd24sIGFuZCBpdCBzdG9wcyBhcyBzb29uIGFzIHRoZSBsb2NrIGZpbGUgbmFtZXMgc29tZWJvZHkgZWxzZSBcdTIwMTQgYSBydW4gd2hvc2VcbiAqIGxvY2sgd2FzIHN0b2xlbiBtdXN0IG5vdCBvdmVyd3JpdGUgaXRzIHN1Y2Nlc3NvcidzIGxvY2ssIG5vciBkZWxldGUgaXQgb25cbiAqIHJlbGVhc2UuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBoYW5kbGUgcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIFRoZSBsb2NrIGhhbmRsZS5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlTG9ja0hhbmRsZShwYXJhbXM6IENyZWF0ZUxvY2tIYW5kbGVQYXJhbXMpOiBTZXR1cExvY2sge1xuICBjb25zdCB7XG4gICAgbGFiZWwsXG4gICAgbG9ja0ZpbGVQYXRoLFxuICAgIG93bkluZm8sXG4gICAgc2NvcGVcbiAgfSA9IHBhcmFtcztcbiAgbGV0IGlzUmVsZWFzZWQgPSBmYWxzZTtcblxuICBjb25zdCBoZWFydGJlYXRUaW1lciA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICBjb25zdCBpc1N0aWxsT3VycyA9IGRpZFJlZnJlc2hIZWFydGJlYXQoe1xuICAgICAgbGFiZWwsXG4gICAgICBsb2NrRmlsZVBhdGgsXG4gICAgICBvd25JbmZvXG4gICAgfSk7XG4gICAgaWYgKGlzU3RpbGxPdXJzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNsZWFySW50ZXJ2YWwoaGVhcnRiZWF0VGltZXIpO1xuICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBUaGUgJyR7c2NvcGV9JyBzZXR1cCBsb2NrIGlzIG5vIGxvbmdlciBvdXJzIFx1MjAxNCBhbm90aGVyIHJ1biB0b29rIGl0IG92ZXIuIEhlYXJ0YmVhdCBzdG9wcGVkLmApO1xuICB9LCBIRUFSVEJFQVRfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTKTtcbiAgaGVhcnRiZWF0VGltZXIudW5yZWYoKTtcblxuICByZXR1cm4ge1xuICAgIHJlbGVhc2UoKTogdm9pZCB7XG4gICAgICBpZiAoaXNSZWxlYXNlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpc1JlbGVhc2VkID0gdHJ1ZTtcbiAgICAgIGNsZWFySW50ZXJ2YWwoaGVhcnRiZWF0VGltZXIpO1xuXG4gICAgICBjb25zdCBpbmZvID0gcmVhZExvY2tGaWxlSW5mbyhsb2NrRmlsZVBhdGgpO1xuICAgICAgaWYgKGluZm8gJiYgIWNoZWNrSXNPd25Mb2NrKGluZm8pKSB7XG4gICAgICAgIGxvZyhgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBMZWF2aW5nIHRoZSAnJHtzY29wZX0nIHNldHVwIGxvY2sgaW4gcGxhY2UgXHUyMDE0IGl0IG5vdyBiZWxvbmdzIHRvICR7ZGVzY3JpYmVJbmZvKGluZm8pfS5gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcm1TeW5jKGxvY2tGaWxlUGF0aCwgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBlcnJvciB0aHJvd24gd2hlbiB0aGUgbG9jayBjb3VsZCBub3QgYmUgYWNxdWlyZWQgaW4gdGltZS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGVycm9yIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyBUaGUgZXJyb3IgdG8gdGhyb3cuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVRpbWVvdXRFcnJvcihwYXJhbXM6IENyZWF0ZVRpbWVvdXRFcnJvclBhcmFtcyk6IEVycm9yIHtcbiAgY29uc3Qge1xuICAgIGluZm8sXG4gICAgc2NvcGUsXG4gICAgdGltZW91dEluTWlsbGlzZWNvbmRzXG4gIH0gPSBwYXJhbXM7XG4gIHJldHVybiBuZXcgRXJyb3IoXG4gICAgYFRpbWVkIG91dCBhZnRlciAke1N0cmluZyh0aW1lb3V0SW5NaWxsaXNlY29uZHMpfW1zIHdhaXRpbmcgZm9yIHRoZSAnJHtzY29wZX0nIGludGVncmF0aW9uLXRlc3Qgc2V0dXAgbG9jayBgXG4gICAgICArIGBoZWxkIGJ5ICR7ZGVzY3JpYmVIb2xkZXIoaW5mbyl9LiBBbm90aGVyIGludGVncmF0aW9uLXRlc3QgcnVuIGlzIHN0aWxsIGluIHByb2dyZXNzLmBcbiAgKTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBhZnRlciB0aGUgZ2l2ZW4gZGVsYXkuIFVzZWQgdG8gcG9sbCBiZXR3ZWVuIGxvY2stYWNxdWlzaXRpb24gYXR0ZW1wdHMuXG4gKlxuICogQHBhcmFtIG1pbGxpc2Vjb25kcyAtIFRoZSBkZWxheSBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgZGVsYXkuXG4gKi9cbmZ1bmN0aW9uIGRlbGF5KG1pbGxpc2Vjb25kczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgbWlsbGlzZWNvbmRzKTtcbiAgfSk7XG59XG5cbi8qKlxuICogQnVpbGRzIGEgaHVtYW4tcmVhZGFibGUgZGVzY3JpcHRpb24gb2YgdGhlIGN1cnJlbnQgbG9jayBob2xkZXIgZm9yIGxvZy9lcnJvclxuICogbWVzc2FnZXMuXG4gKlxuICogQHBhcmFtIGluZm8gLSBUaGUgcGFyc2VkIGxvY2sgaW5mbywgb3IgYG51bGxgIGlmIGl0IGNvdWxkIG5vdCBiZSByZWFkLlxuICogQHJldHVybnMgQSBkZXNjcmlwdGlvbiBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGRlc2NyaWJlSG9sZGVyKGluZm86IExvY2tGaWxlSW5mbyB8IG51bGwpOiBzdHJpbmcge1xuICByZXR1cm4gaW5mbyA/IGRlc2NyaWJlSW5mbyhpbmZvKSA6ICdhbm90aGVyIHJ1bic7XG59XG5cbi8qKlxuICogRm9ybWF0cyBhIHtAbGluayBMb2NrRmlsZUluZm99IGFzIGEgc2hvcnQgaWRlbnRpZmllciBzdHJpbmcuXG4gKlxuICogQHBhcmFtIGluZm8gLSBUaGUgbG9jayBpbmZvLlxuICogQHJldHVybnMgQSBzdHJpbmcgbGlrZSBgcGlkIDEyMzQgKG9ic2lkaWFuLWNsaSkgb24gaG9zdGAuXG4gKi9cbmZ1bmN0aW9uIGRlc2NyaWJlSW5mbyhpbmZvOiBMb2NrRmlsZUluZm8pOiBzdHJpbmcge1xuICByZXR1cm4gYHBpZCAke1N0cmluZyhpbmZvLnBpZCl9ICgke2luZm8ubGFiZWx9KSBvbiAke2luZm8uaG9zdG5hbWV9YDtcbn1cblxuLyoqXG4gKiBSZXdyaXRlcyB0aGUgbG9jayBmaWxlIHdpdGggYSBmcmVzaCBoZWFydGJlYXQgdGltZXN0YW1wLCBzbyB3YWl0aW5nIHJ1bnMgY2FuXG4gKiB0ZWxsIHRoaXMgaG9sZGVyIGFwYXJ0IGZyb20gYSBjcmFzaGVkIG9uZSB3aG9zZSBQSUQgaGFzIGJlZW4gcmVjeWNsZWQuXG4gKlxuICogQSBsb2NrIGZpbGUgdGhhdCBpcyBtaXNzaW5nIG9yIHVucmVhZGFibGUgaXMgc3RpbGwgdHJlYXRlZCBhcyBvdXJzIGFuZCByZXdyaXR0ZW46XG4gKiB0aGlzIHJ1biBuZXZlciByZWxlYXNlZCwgc28gaXRzIGNsYWltIHN0YW5kcy5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHJlZnJlc2ggcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIGB0cnVlYCB3aGlsZSB0aGUgbG9jayBpcyBzdGlsbCBvdXJzLCBgZmFsc2VgIG9uY2UgYW5vdGhlciBydW4gb3ducyBpdC5cbiAqL1xuZnVuY3Rpb24gZGlkUmVmcmVzaEhlYXJ0YmVhdChwYXJhbXM6IFJlZnJlc2hIZWFydGJlYXRQYXJhbXMpOiBib29sZWFuIHtcbiAgY29uc3Qge1xuICAgIGxhYmVsLFxuICAgIGxvY2tGaWxlUGF0aCxcbiAgICBvd25JbmZvXG4gIH0gPSBwYXJhbXM7XG5cbiAgY29uc3QgaW5mbyA9IHJlYWRMb2NrRmlsZUluZm8obG9ja0ZpbGVQYXRoKTtcbiAgaWYgKGluZm8gJiYgIWNoZWNrSXNPd25Mb2NrKGluZm8pKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgcmVmcmVzaGVkSW5mbzogTG9ja0ZpbGVJbmZvID0ge1xuICAgIC4uLm93bkluZm8sXG4gICAgaGVhcnRiZWF0QXRJbk1pbGxpc2Vjb25kczogRGF0ZS5ub3coKVxuICB9O1xuICB0cnkge1xuICAgIHdyaXRlRmlsZVN5bmMobG9ja0ZpbGVQYXRoLCBKU09OLnN0cmluZ2lmeShyZWZyZXNoZWRJbmZvKSk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgLy8gTm90IGZhdGFsOiB0aGUgbG9jayBpcyBzdGlsbCBoZWxkIGFuZCB3aWxsIHN0aWxsIGJlIHJlbGVhc2VkLiBPbmx5IGl0c1xuICAgIC8vIEhlYXJ0YmVhdCBnb2VzIHN0YWxlLCB3aGljaCBhdCB3b3JzdCBsZXRzIGEgd2FpdGluZyBydW4gc3RlYWwgaXQuXG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIEZhaWxlZCB0byByZWZyZXNoIHRoZSBzZXR1cCBsb2NrIGhlYXJ0YmVhdDogJHtlcnJvclRvU3RyaW5nKGVycm9yKX1gKTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBGb3JtYXRzIGEgZHVyYXRpb24gYXMgYSBjb21wYWN0IGAxbSAzMHNgIC8gYDQ1c2Agc3RyaW5nIGZvciBwcm9ncmVzcyBsb2dzLlxuICpcbiAqIEBwYXJhbSBtaWxsaXNlY29uZHMgLSBUaGUgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLlxuICogQHJldHVybnMgVGhlIGZvcm1hdHRlZCBkdXJhdGlvbi5cbiAqL1xuZnVuY3Rpb24gZm9ybWF0RHVyYXRpb24obWlsbGlzZWNvbmRzOiBudW1iZXIpOiBzdHJpbmcge1xuICBjb25zdCB0b3RhbFNlY29uZHMgPSBNYXRoLnJvdW5kKG1pbGxpc2Vjb25kcyAvIE1JTExJU0VDT05EU19QRVJfU0VDT05EKTtcbiAgY29uc3QgbWludXRlcyA9IE1hdGguZmxvb3IodG90YWxTZWNvbmRzIC8gU0VDT05EU19QRVJfTUlOVVRFKTtcbiAgY29uc3Qgc2Vjb25kcyA9IHRvdGFsU2Vjb25kcyAlIFNFQ09ORFNfUEVSX01JTlVURTtcbiAgcmV0dXJuIG1pbnV0ZXMgPiAwID8gYCR7U3RyaW5nKG1pbnV0ZXMpfW0gJHtTdHJpbmcoc2Vjb25kcyl9c2AgOiBgJHtTdHJpbmcoc2Vjb25kcyl9c2A7XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBwZXJpb2RpYyBcInN0aWxsIHdhaXRpbmdcIiBwcm9ncmVzcyBsaW5lLCBzbyBhIGxlZ2l0aW1hdGUgbXVsdGktbWludXRlXG4gKiB3YWl0IGlzIGRpc3Rpbmd1aXNoYWJsZSBmcm9tIGEgaGFuZyBpbiB0aGUgdGVybWluYWwuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBtZXNzYWdlIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyBUaGUgbWVzc2FnZSB0byBsb2cuXG4gKi9cbmZ1bmN0aW9uIGZvcm1hdFdhaXRNZXNzYWdlKHBhcmFtczogRm9ybWF0V2FpdE1lc3NhZ2VQYXJhbXMpOiBzdHJpbmcge1xuICBjb25zdCB7XG4gICAgaW5mbyxcbiAgICBsYWJlbCxcbiAgICByZW1haW5pbmdJbk1pbGxpc2Vjb25kcyxcbiAgICBzY29wZSxcbiAgICB3YWl0ZWRJbk1pbGxpc2Vjb25kc1xuICB9ID0gcGFyYW1zO1xuICBjb25zdCBoZWxkRm9yID0gaW5mbyA/IGAsIGhlbGQgZm9yICR7Zm9ybWF0RHVyYXRpb24oRGF0ZS5ub3coKSAtIGluZm8uYWNxdWlyZWRBdEluTWlsbGlzZWNvbmRzKX1gIDogJyc7XG4gIHJldHVybiBgW2ludGVncmF0aW9uLXNldHVwOiR7bGFiZWx9XSBXYWl0aW5nIGZvciB0aGUgJyR7c2NvcGV9JyBzZXR1cCBsb2NrIGhlbGQgYnkgJHtkZXNjcmliZUhvbGRlcihpbmZvKX0gdG8gYmUgcmVsZWFzZWQgYFxuICAgICsgYCh3YWl0ZWQgJHtmb3JtYXREdXJhdGlvbih3YWl0ZWRJbk1pbGxpc2Vjb25kcyl9JHtoZWxkRm9yfSwgZ2l2aW5nIHVwIGluICR7Zm9ybWF0RHVyYXRpb24ocmVtYWluaW5nSW5NaWxsaXNlY29uZHMpfSkuLi5gO1xufVxuXG4vKipcbiAqIEV4dHJhY3RzIHRoZSBgY29kZWAgZnJvbSBhIE5vZGUuanMgc3lzdGVtIGVycm9yLCBpZiBwcmVzZW50LlxuICpcbiAqIEBwYXJhbSBlcnJvciAtIFRoZSB0aHJvd24gdmFsdWUuXG4gKiBAcmV0dXJucyBUaGUgZXJyb3IgY29kZSBzdHJpbmcsIG9yIGB1bmRlZmluZWRgIGlmIG5vdCBhIGNvZGVkIGVycm9yLlxuICovXG5mdW5jdGlvbiBnZXRFcnJvckNvZGUoZXJyb3I6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiAnY29kZScgaW4gZXJyb3IgJiYgdHlwZW9mIGVycm9yLmNvZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGVycm9yLmNvZGU7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHdoZW4gdGhlIGhvbGRlciB3YXMgbGFzdCBrbm93biB0byBiZSBhbGl2ZSBcdTIwMTQgaXRzIG1vc3QgcmVjZW50IGhlYXJ0YmVhdCxcbiAqIGZhbGxpbmcgYmFjayB0byBpdHMgYWNxdWlzaXRpb24gdGltZSBmb3IgYSBsb2NrIGZpbGUgd3JpdHRlbiBieSBhbiBvbGRlclxuICogdmVyc2lvbiBvZiB0aGlzIHBhY2thZ2UgdGhhdCBzdGFtcGVkIG5vIGhlYXJ0YmVhdCBhdCBhbGwuXG4gKlxuICogQHBhcmFtIGluZm8gLSBUaGUgcGFyc2VkIGxvY2sgaW5mby5cbiAqIEByZXR1cm5zIFRoZSBlcG9jaCBtaWxsaXNlY29uZHMgb2YgdGhlIGhvbGRlcidzIGxhc3Qgc2lnbiBvZiBsaWZlLlxuICovXG5mdW5jdGlvbiBnZXRMYXN0U2VlbkF0SW5NaWxsaXNlY29uZHMoaW5mbzogTG9ja0ZpbGVJbmZvKTogbnVtYmVyIHtcbiAgcmV0dXJuIGluZm8uaGVhcnRiZWF0QXRJbk1pbGxpc2Vjb25kcyA/PyBpbmZvLmFjcXVpcmVkQXRJbk1pbGxpc2Vjb25kcztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzaGFyZWQgbG9jayBkaXJlY3RvcnkgaW5zaWRlIHRoZSBPUyB0ZW1wIGRpcmVjdG9yeS5cbiAqXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgbG9jayBkaXJlY3RvcnkuXG4gKi9cbmZ1bmN0aW9uIGdldExvY2tEaXJlY3RvcnkoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4odG1wZGlyKCksIExPQ0tfRElSX05BTUUpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGxvY2sgZmlsZSBwYXRoIGZvciB0aGUgZ2l2ZW4gc2NvcGUuXG4gKlxuICogQHBhcmFtIHNjb3BlIC0gVGhlIGxvY2sgc2NvcGUuXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgc2NvcGUncyBsb2NrIGZpbGUuXG4gKi9cbmZ1bmN0aW9uIGdldExvY2tGaWxlUGF0aChzY29wZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4oZ2V0TG9ja0RpcmVjdG9yeSgpLCBgJHtzY29wZX0ke0xPQ0tfRklMRV9TVUZGSVh9YCk7XG59XG5cbi8qKlxuICogUmVhZHMgYW5kIHBhcnNlcyB0aGUgbG9jayBmaWxlLCBpZiBpdCBleGlzdHMgYW5kIGlzIHZhbGlkIEpTT04uXG4gKlxuICogQHBhcmFtIGxvY2tGaWxlUGF0aCAtIFRoZSBwYXRoIHRvIHRoZSBsb2NrIGZpbGUuXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIGxvY2sgaW5mbywgb3IgYG51bGxgIGlmIGl0IGNvdWxkIG5vdCBiZSByZWFkLlxuICovXG5mdW5jdGlvbiByZWFkTG9ja0ZpbGVJbmZvKGxvY2tGaWxlUGF0aDogc3RyaW5nKTogTG9ja0ZpbGVJbmZvIHwgbnVsbCB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UocmVhZEZpbGVTeW5jKGxvY2tGaWxlUGF0aCwgJ3V0Zi04JykpIGFzIExvY2tGaWxlSW5mbztcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuLyoqXG4gKiBBdHRlbXB0cyB0byBhdG9taWNhbGx5IGNyZWF0ZSB0aGUgbG9jayBmaWxlIChmYWlsaW5nIGlmIGl0IGFscmVhZHkgZXhpc3RzKS5cbiAqXG4gKiBAcGFyYW0gbG9ja0ZpbGVQYXRoIC0gVGhlIHBhdGggdG8gdGhlIGxvY2sgZmlsZS5cbiAqIEBwYXJhbSBsYWJlbCAtIFRoZSB0cmFuc3BvcnQgbGFiZWwgdG8gcmVjb3JkIGluIHRoZSBsb2NrIGZpbGUuXG4gKiBAcmV0dXJucyBUaGUgbG9jayBpbmZvIHdyaXR0ZW4gb24gc3VjY2Vzcywgb3IgYG51bGxgIGlmIHRoZSBsb2NrIGlzIGFscmVhZHkgaGVsZC5cbiAqIEB0aHJvd3MgSWYgdGhlIGZpbGUgc3lzdGVtIGZhaWxzIGZvciBhbnkgcmVhc29uIG90aGVyIHRoYW4gdGhlIGZpbGUgZXhpc3RpbmcuXG4gKi9cbmZ1bmN0aW9uIHRyeUNyZWF0ZUxvY2tGaWxlKGxvY2tGaWxlUGF0aDogc3RyaW5nLCBsYWJlbDogc3RyaW5nKTogTG9ja0ZpbGVJbmZvIHwgbnVsbCB7XG4gIGNvbnN0IG5vd0luTWlsbGlzZWNvbmRzID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgaW5mbzogTG9ja0ZpbGVJbmZvID0ge1xuICAgIGFjcXVpcmVkQXRJbk1pbGxpc2Vjb25kczogbm93SW5NaWxsaXNlY29uZHMsXG4gICAgaGVhcnRiZWF0QXRJbk1pbGxpc2Vjb25kczogbm93SW5NaWxsaXNlY29uZHMsXG4gICAgaG9zdG5hbWU6IGhvc3RuYW1lKCksXG4gICAgbGFiZWwsXG4gICAgcGlkOiBwcm9jZXNzLnBpZFxuICB9O1xuXG4gIHRyeSB7XG4gICAgd3JpdGVGaWxlU3luYyhsb2NrRmlsZVBhdGgsIEpTT04uc3RyaW5naWZ5KGluZm8pLCB7IGZsYWc6ICd3eCcgfSk7XG4gICAgcmV0dXJuIGluZm87XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgaWYgKGdldEVycm9yQ29kZShlcnJvcikgPT09ICdFRVhJU1QnKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBMEJBLHFCQUtPO0FBQ1AscUJBR087QUFDUCx1QkFBcUI7QUFDckIsMEJBQW9CO0FBRXBCLDZCQUE4QjtBQUM5QixpQkFBb0I7QUFFcEIsTUFBTSxnQkFBZ0I7QUFDdEIsTUFBTSxtQkFBbUI7QUFDekIsTUFBTSxnQ0FBZ0M7QUFDdEMsTUFBTSwwQkFBMEI7QUFDaEMsTUFBTSxxQkFB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
319
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3NldHVwLWxvY2sudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBDcm9zcy1wcm9jZXNzIGFkdmlzb3J5IGxvY2sgdGhhdCBzZXJpYWxpemVzIHdob2xlIGludGVncmF0aW9uLXRlc3QgcnVucy5cbiAqXG4gKiBUd28gdGVzdCBydW5zIHRoYXQgZHJpdmUgdGhlIHNhbWUgc2hhcmVkIHJlc291cmNlcyBjb3JydXB0IGVhY2ggb3RoZXI6IG9uXG4gKiBkZXNrdG9wIHRoZXkgc2hhcmUgdGhlIHNpbmdsZSBsb2NhbCBPYnNpZGlhbiBpbnN0YW5jZSwgaXRzIGBvYnNpZGlhbi5qc29uYFxuICogcmVnaXN0cnksIGFuZCB0aGUgQ0RQIHBvcnQ7IG9uIEFuZHJvaWQgdGhleSBzaGFyZSB0aGUgZW11bGF0b3IgYW5kIHRoZSBBcHBpdW1cbiAqIHNlcnZlci4gT25lIHJ1bidzIHNldHVwL3RlYXJkb3duIGtpbGxzIG9yIHJlY29uZmlndXJlcyB0aGUgaW5zdGFuY2UgdGhlIG90aGVyXG4gKiBydW4gaXMgbWlkLWV2YWwgb24gKG9ic2VydmVkIGFzIGBFQ09OTlJFRlVTRURgIG9yIFwidmF1bHQgbm90IG9wZW5cIiksIHNvIGJvdGhcbiAqIHJ1bnMgZmFpbC5cbiAqXG4gKiBUaGlzIGxvY2sgbWFrZXMgdGhlIHNlY29uZCBydW4gKip3YWl0KiogZm9yIHRoZSBmaXJzdCB0byBmaW5pc2ggaW5zdGVhZCBvZlxuICogcnVubmluZyBjb25jdXJyZW50bHkuIEl0IGlzIGhlbGQgZm9yIHRoZSBlbnRpcmUgcnVuOiBhY3F1aXJlZCBhdCB0aGUgc3RhcnQgb2ZcbiAqIHRoZSBjb3JlIHNldHVwIGFuZCByZWxlYXNlZCBieSB0aGUgY29yZSB0ZWFyZG93biAoYW5kIGJ5IHRoZSBwcm9jZXNzIGNsZWFudXBcbiAqIGhhbmRsZXJzKS4gVGhlIGxvY2sgaXMgYSBzZW50aW5lbCBmaWxlIGluIGEgc2hhcmVkIHRlbXAgZGlyZWN0b3J5LCBhbmQgaXRzXG4gKiBob2xkZXIga2VlcHMgYSAqKmhlYXJ0YmVhdCoqIHRpbWVzdGFtcCBpbnNpZGUgaXQgZnJlc2ggZm9yIGFzIGxvbmcgYXMgaXQgaG9sZHNcbiAqIHRoZSBsb2NrIFx1MjAxNCBzbyBhIHJ1biB0aGF0IGNyYXNoZWQgd2l0aG91dCByZWxlYXNpbmcgc3RvcHMgYmVhdGluZyBhbmQgdGhlIG5leHRcbiAqIHJ1biBkZXRlY3RzIHRoZSBsb2NrIGFzIHN0YWxlIGFuZCBzdGVhbHMgaXQuXG4gKlxuICogVGhlIGhlYXJ0YmVhdCwgbm90IHRoZSBob2xkZXIncyBQSUQsIGlzIHdoYXQgcHJvdmVzIGEgaG9sZGVyIGlzIHN0aWxsIHRoZXJlOiBhXG4gKiBQSUQgcHJvYmUgb25seSBhbnN3ZXJzIFwiZG9lcyAqYSogcHJvY2VzcyB3aXRoIHRoaXMgUElEIGV4aXN0XCIsIHdoaWNoIGFcbiAqIHJlY3ljbGVkIFBJRCBzYXRpc2ZpZXMgbG9uZyBhZnRlciB0aGUgcmVhbCBob2xkZXIgZGllZCBcdTIwMTQgbGVhdmluZyBldmVyeSBsYXRlclxuICogcnVuIHRvIGJsb2NrIGZvciB0aGUgZnVsbCBhY3F1aXNpdGlvbiB0aW1lb3V0LlxuICovXG5cbmltcG9ydCB7XG4gIG1rZGlyU3luYyxcbiAgcmVhZEZpbGVTeW5jLFxuICBybVN5bmMsXG4gIHdyaXRlRmlsZVN5bmNcbn0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBob3N0bmFtZSxcbiAgdG1wZGlyXG59IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQgeyBlcnJvclRvU3RyaW5nIH0gZnJvbSAnLi9lcnJvci10by1zdHJpbmcuY2pzJztcbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLmNqcyc7XG5cbi8qKlxuICogVGhlIHNjb3BlIGV2ZXJ5IEFuZHJvaWQgcnVuIHNlcmlhbGl6ZXMgb246IHRoZSBBcHBpdW0gdHJhbnNwb3J0J3MgZ2xvYmFsXG4gKiBzZXR1cCwgYSBwcm9qZWN0IHRoYXQgdGFrZXMgdGhlIGxvY2sgaXRzZWxmLCBhbmQgdGhlIGVtdWxhdG9yIHJlYXBlciBhbGxcbiAqIGhhdmUgdG8gbmFtZSB0aGUgc2FtZSBvbmUsIG9yIHRoZXkgc2VyaWFsaXplIGFnYWluc3Qgbm90aGluZy5cbiAqL1xuZXhwb3J0IGNvbnN0IEFORFJPSURfU0VUVVBfTE9DS19TQ09QRSA9ICdhbmRyb2lkJztcblxuY29uc3QgTE9DS19ESVJfTkFNRSA9ICdvYnNpZGlhbi1pbnRlZ3JhdGlvbi10ZXN0aW5nJztcbmNvbnN0IExPQ0tfRklMRV9TVUZGSVggPSAnLnNldHVwLmxvY2snO1xuY29uc3QgUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSA1MDA7XG5jb25zdCBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORCA9IDEwMDA7XG5jb25zdCBTRUNPTkRTX1BFUl9NSU5VVEUgPSA2MDtcbmNvbnN0IEhFQVJUQkVBVF9JTlRFUlZBTF9JTl9TRUNPTkRTID0gNTtcbmNvbnN0IEhFQVJUQkVBVF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSBIRUFSVEJFQVRfSU5URVJWQUxfSU5fU0VDT05EUyAqIE1JTExJU0VDT05EU19QRVJfU0VDT05EO1xuLy8gR2VuZXJvdXMgb24gcHVycG9zZTogYSBkZWFkIGhvbGRlciBpcyBub3JtYWxseSBjYXVnaHQgaW5zdGFudGx5IGJ5IHRoZSBQSURcbi8vIFByb2JlLCBzbyB0aGlzIHRocmVzaG9sZCBvbmx5IGhhcyB0byBjb3ZlciB0aGUgcmVjeWNsZWQtUElEIGNhc2UuIFR3byBtaW51dGVzXG4vLyBLZWVwcyBhIGhvbGRlciB0aGF0IGJsb2NrcyBpdHMgZXZlbnQgbG9vcCBkdXJpbmcgaGVhdnkgc3luY2hyb25vdXMgd29yayAoYVxuLy8gTGFyZ2UgdmF1bHQgc3luYywgYW4gaW5zdGFsbGVyIHVucGFjaykgZnJvbSBiZWluZyByb2JiZWQgd2hpbGUgaXQgaXMgYWxpdmUuXG5jb25zdCBNSVNTRURfSEVBUlRCRUFUU19CRUZPUkVfU1RBTEUgPSAyNDtcbmNvbnN0IEhFQVJUQkVBVF9TVEFMRV9JTl9NSUxMSVNFQ09ORFMgPSBIRUFSVEJFQVRfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTICogTUlTU0VEX0hFQVJUQkVBVFNfQkVGT1JFX1NUQUxFO1xuY29uc3QgV0FJVF9MT0dfSU5URVJWQUxfSU5fU0VDT05EUyA9IDMwO1xuY29uc3QgV0FJVF9MT0dfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTID0gV0FJVF9MT0dfSU5URVJWQUxfSU5fU0VDT05EUyAqIE1JTExJU0VDT05EU19QRVJfU0VDT05EO1xuY29uc3QgU1RBTEVfTE9DS19BR0VfSU5fTUlOVVRFUyA9IDMwO1xuY29uc3QgREVGQVVMVF9USU1FT1VUX0lOX01JTlVURVMgPSA2MDtcbmNvbnN0IFNUQUxFX0xPQ0tfQUdFX0lOX01JTExJU0VDT05EUyA9IFNUQUxFX0xPQ0tfQUdFX0lOX01JTlVURVMgKiBTRUNPTkRTX1BFUl9NSU5VVEUgKiBNSUxMSVNFQ09ORFNfUEVSX1NFQ09ORDtcbmNvbnN0IERFRkFVTFRfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSBERUZBVUxUX1RJTUVPVVRfSU5fTUlOVVRFUyAqIFNFQ09ORFNfUEVSX01JTlVURSAqIE1JTExJU0VDT05EU19QRVJfU0VDT05EO1xuY29uc3QgUFJPQ0VTU19FWElTVEVOQ0VfUFJPQkVfU0lHTkFMID0gMDtcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgYWNxdWlyZVNldHVwTG9ja30uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWNxdWlyZVNldHVwTG9ja1BhcmFtcyB7XG4gIC8qKlxuICBTaG9ydCB0cmFuc3BvcnQgbGFiZWwgZm9yIGxvZyBtZXNzYWdlcyAoZS5nLiBgXCJvYnNpZGlhbi1jbGlcImApLlxuICAgKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgICogTG9naWNhbCBzY29wZSB0aGUgbG9jayBzZXJpYWxpemVzIHdpdGhpbi4gUnVucyB0aGF0IHNoYXJlIHJlc291cmNlcyBtdXN0XG4gICAqIHVzZSB0aGUgc2FtZSBzY29wZSAoZS5nLiBgXCJkZXNrdG9wXCJgIGZvciB0aGUgQ0xJL0NEUCB0cmFuc3BvcnRzLCBgXCJhbmRyb2lkXCJgXG4gICAqIGZvciB0aGUgQXBwaXVtIHRyYW5zcG9ydCkuXG4gICAqL1xuICByZWFkb25seSBzY29wZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBNYXhpbXVtIHRpbWUgdG8gd2FpdCBmb3IgYSBjb21wZXRpbmcgcnVuIHRvIHJlbGVhc2UgdGhlIGxvY2sgYmVmb3JlIGdpdmluZ1xuICAgKiB1cCBhbmQgdGhyb3dpbmcuXG4gICAqXG4gICAqIEBkZWZhdWx0IDEgaG91clxuICAgKi9cbiAgcmVhZG9ubHkgdGltZW91dEluTWlsbGlzZWNvbmRzPzogbnVtYmVyIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEEgaGVsZCBzZXR1cCBsb2NrLiBSZWxlYXNlIGl0IG9uY2UgdGhlIHJ1bidzIHRlYXJkb3duIGlzIGNvbXBsZXRlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNldHVwTG9jayB7XG4gIC8qKlxuICBSZWxlYXNlcyB0aGUgbG9jay4gU2FmZSB0byBjYWxsIG1vcmUgdGhhbiBvbmNlLlxuICAgKi9cbiAgcmVsZWFzZSgpOiB2b2lkO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayB0cnlBY3F1aXJlU2V0dXBMb2NrfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUcnlBY3F1aXJlU2V0dXBMb2NrUGFyYW1zIHtcbiAgLyoqXG4gIFNob3J0IHRyYW5zcG9ydCBsYWJlbCBmb3IgbG9nIG1lc3NhZ2VzLCByZWNvcmRlZCBpbiB0aGUgbG9jayBmaWxlIGFzIHRoZSBob2xkZXIncy5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIExvZ2ljYWwgc2NvcGUgdGhlIGxvY2sgc2VyaWFsaXplcyB3aXRoaW4gXHUyMDE0IHNlZSB7QGxpbmsgQWNxdWlyZVNldHVwTG9ja1BhcmFtcy5zY29wZX0uXG4gICAqL1xuICByZWFkb25seSBzY29wZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBIb3cgbG9uZyBhIHNhbWUtaG9zdCBob2xkZXIgd2hvc2UgUElEIGlzIHN0aWxsIGFsaXZlIG1heSBnbyB3aXRob3V0IGFcbiAgICogaGVhcnRiZWF0IGJlZm9yZSBpdHMgbG9jayBjb3VudHMgYXMgYWJhbmRvbmVkLlxuICAgKlxuICAgKiBBIGRlYWQgaG9sZGVyIFBJRCBpcyBhYmFuZG9uZWQgYXQgb25jZSB3aGF0ZXZlciB0aGlzIHNheXMuIFRoZSBkZWZhdWx0IGlzXG4gICAqIHRoZSB0aHJlc2hvbGQgZXZlcnkgd2FpdGluZyBydW4gc3RlYWxzIG9uOyBhIGNhbGxlciB0aGF0IGlzICphbHdheXMqIHdhaXRpbmdcbiAgICogXHUyMDE0IHRoZSBlbXVsYXRvciByZWFwZXIgXHUyMDE0IHBhc3NlcyBhIGZhciB3aWRlciBvbmUsIHNvIGEgbGl2ZSBydW4gdGhhdCBibG9ja3NcbiAgICogaXRzIGV2ZW50IGxvb3AgZm9yIGEgY291cGxlIG9mIG1pbnV0ZXMgaXMgbm90IHJvYmJlZCBvZiBpdHMgbG9jay5cbiAgICpcbiAgICogQGRlZmF1bHQgMiBtaW51dGVzXG4gICAqL1xuICByZWFkb25seSBzdGFsZUFmdGVyU2lsZW5jZUluTWlsbGlzZWNvbmRzPzogbnVtYmVyIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBjcmVhdGVMb2NrSGFuZGxlfS5cbiAqL1xuaW50ZXJmYWNlIENyZWF0ZUxvY2tIYW5kbGVQYXJhbXMge1xuICAvKipcbiAgVGhlIHRyYW5zcG9ydCBsYWJlbCBvZiB0aGlzIHJ1bi5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBwYXRoIHRvIHRoZSBsb2NrIGZpbGUgdGhpcyBydW4ganVzdCBjcmVhdGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9ja0ZpbGVQYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBsb2NrIGluZm8gdGhpcyBydW4gd3JvdGUgd2hlbiBpdCBhY3F1aXJlZCB0aGUgbG9jay5cbiAgICovXG4gIHJlYWRvbmx5IG93bkluZm86IExvY2tGaWxlSW5mbztcblxuICAvKipcbiAgVGhlIGxvY2sgc2NvcGUsIGZvciBsb2cgbWVzc2FnZXMuXG4gICAqL1xuICByZWFkb25seSBzY29wZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBjcmVhdGVUaW1lb3V0RXJyb3J9LlxuICovXG5pbnRlcmZhY2UgQ3JlYXRlVGltZW91dEVycm9yUGFyYW1zIHtcbiAgLyoqXG4gIFRoZSBjdXJyZW50IGhvbGRlcidzIGxvY2sgaW5mbywgb3IgYG51bGxgIGlmIGl0IGNvdWxkIG5vdCBiZSByZWFkLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5mbzogTG9ja0ZpbGVJbmZvIHwgbnVsbDtcblxuICAvKipcbiAgVGhlIGxvY2sgc2NvcGUuXG4gICAqL1xuICByZWFkb25seSBzY29wZTogc3RyaW5nO1xuXG4gIC8qKlxuICBUaGUgdGltZW91dCB0aGF0IGVsYXBzZWQuXG4gICAqL1xuICByZWFkb25seSB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgZm9ybWF0V2FpdE1lc3NhZ2V9LlxuICovXG5pbnRlcmZhY2UgRm9ybWF0V2FpdE1lc3NhZ2VQYXJhbXMge1xuICAvKipcbiAgVGhlIGN1cnJlbnQgaG9sZGVyJ3MgbG9jayBpbmZvLCBvciBgbnVsbGAgaWYgaXQgY291bGQgbm90IGJlIHJlYWQuXG4gICAqL1xuICByZWFkb25seSBpbmZvOiBMb2NrRmlsZUluZm8gfCBudWxsO1xuXG4gIC8qKlxuICBUaGUgdHJhbnNwb3J0IGxhYmVsIG9mIHRoZSB3YWl0aW5nIHJ1bi5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIEhvdyBtdWNoIG9mIHRoZSBhY3F1aXNpdGlvbiB0aW1lb3V0IGlzIGxlZnQuXG4gICAqL1xuICByZWFkb25seSByZW1haW5pbmdJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICBUaGUgbG9jayBzY29wZS5cbiAgICovXG4gIHJlYWRvbmx5IHNjb3BlOiBzdHJpbmc7XG5cbiAgLyoqXG4gIEhvdyBsb25nIHRoaXMgcnVuIGhhcyBiZWVuIHdhaXRpbmcgc28gZmFyLlxuICAgKi9cbiAgcmVhZG9ubHkgd2FpdGVkSW5NaWxsaXNlY29uZHM6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBUaGUgSlNPTiBwYXlsb2FkIHN0b3JlZCBpbnNpZGUgYSBsb2NrIGZpbGUsIGlkZW50aWZ5aW5nIHRoZSBob2xkZXIuXG4gKi9cbmludGVyZmFjZSBMb2NrRmlsZUluZm8ge1xuICAvKipcbiAgV2hlbiB0aGUgbG9jayB3YXMgYWNxdWlyZWQgKGBEYXRlLm5vdygpYCBlcG9jaCBtaWxsaXNlY29uZHMpLlxuICAgKi9cbiAgcmVhZG9ubHkgYWNxdWlyZWRBdEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFdoZW4gdGhlIGhvbGRlciBsYXN0IHByb3ZlZCBpdCB3YXMgc3RpbGwgYWxpdmUgKGBEYXRlLm5vdygpYCBlcG9jaFxuICAgKiBtaWxsaXNlY29uZHMpLCByZWZyZXNoZWQgZXZlcnkge0BsaW5rIEhFQVJUQkVBVF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFN9XG4gICAqIHdoaWxlIHRoZSBsb2NrIGlzIGhlbGQuXG4gICAqXG4gICAqIEFic2VudCBpbiBhIGxvY2sgZmlsZSB3cml0dGVuIGJ5IGFuIG9sZGVyIHZlcnNpb24gb2YgdGhpcyBwYWNrYWdlLCB3aGljaFxuICAgKiBzdGFtcGVkIHRoZSBQSUQgYnV0IG5ldmVyIGJlYXQuXG4gICAqL1xuICByZWFkb25seSBoZWFydGJlYXRBdEluTWlsbGlzZWNvbmRzPzogbnVtYmVyIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICBUaGUgaG9zdCB0aGF0IGhvbGRzIHRoZSBsb2NrIChQSUQgbGl2ZW5lc3MgaXMgb25seSB2YWxpZCBvbiB0aGUgc2FtZSBob3N0KS5cbiAgICovXG4gIHJlYWRvbmx5IGhvc3RuYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSB0cmFuc3BvcnQgbGFiZWwgb2YgdGhlIGhvbGRpbmcgcnVuLlxuICAgKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgVGhlIHByb2Nlc3MgSUQgb2YgdGhlIGhvbGRpbmcgcnVuLlxuICAgKi9cbiAgcmVhZG9ubHkgcGlkOiBudW1iZXI7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGRpZFJlZnJlc2hIZWFydGJlYXR9LlxuICovXG5pbnRlcmZhY2UgUmVmcmVzaEhlYXJ0YmVhdFBhcmFtcyB7XG4gIC8qKlxuICBUaGUgdHJhbnNwb3J0IGxhYmVsIG9mIHRoaXMgcnVuLlxuICAgKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgVGhlIHBhdGggdG8gdGhlIGxvY2sgZmlsZSB0byByZWZyZXNoLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9ja0ZpbGVQYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBsb2NrIGluZm8gdGhpcyBydW4gd3JvdGUgd2hlbiBpdCBhY3F1aXJlZCB0aGUgbG9jay5cbiAgICovXG4gIHJlYWRvbmx5IG93bkluZm86IExvY2tGaWxlSW5mbztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgc3RlYWxTdGFsZUxvY2t9LlxuICovXG5pbnRlcmZhY2UgU3RlYWxTdGFsZUxvY2tQYXJhbXMge1xuICAvKipcbiAgVGhlIGFiYW5kb25lZCBob2xkZXIncyBsb2NrIGluZm8uXG4gICAqL1xuICByZWFkb25seSBpbmZvOiBMb2NrRmlsZUluZm87XG5cbiAgLyoqXG4gIFRoZSB0cmFuc3BvcnQgbGFiZWwgb2YgdGhlIHN0ZWFsaW5nIHJ1bi5cbiAgICovXG4gIHJlYWRvbmx5IGxhYmVsOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBwYXRoIHRvIHRoZSBsb2NrIGZpbGUgdG8gcmVtb3ZlLlxuICAgKi9cbiAgcmVhZG9ubHkgbG9ja0ZpbGVQYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gIFRoZSBsb2NrIHNjb3BlLCBmb3IgdGhlIGxvZyBtZXNzYWdlLlxuICAgKi9cbiAgcmVhZG9ubHkgc2NvcGU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBBY3F1aXJlcyB0aGUgY3Jvc3MtcHJvY2VzcyBzZXR1cCBsb2NrIGZvciB0aGUgZ2l2ZW4gc2NvcGUsIHdhaXRpbmcgdW50aWwgYW55XG4gKiBjb21wZXRpbmcgcnVuIHJlbGVhc2VzIGl0IChvciBpdHMgbG9jayBpcyBkZXRlY3RlZCBhcyBzdGFsZSkuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBsb2NrIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyBBIGhhbmRsZSB3aG9zZSB7QGxpbmsgU2V0dXBMb2NrLnJlbGVhc2V9IGZyZWVzIHRoZSBsb2NrLlxuICogQHRocm93cyBJZiB0aGUgbG9jayBjYW5ub3QgYmUgYWNxdWlyZWQgd2l0aGluIGB0aW1lb3V0SW5NaWxsaXNlY29uZHNgLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWNxdWlyZVNldHVwTG9jayhwYXJhbXM6IEFjcXVpcmVTZXR1cExvY2tQYXJhbXMpOiBQcm9taXNlPFNldHVwTG9jaz4ge1xuICBjb25zdCB7XG4gICAgbGFiZWwsXG4gICAgc2NvcGVcbiAgfSA9IHBhcmFtcztcbiAgY29uc3QgdGltZW91dEluTWlsbGlzZWNvbmRzID0gcGFyYW1zLnRpbWVvdXRJbk1pbGxpc2Vjb25kcyA/PyBERUZBVUxUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuICBjb25zdCBsb2NrRmlsZVBhdGggPSBnZXRMb2NrRmlsZVBhdGgoc2NvcGUpO1xuICBta2RpclN5bmMoZ2V0TG9ja0RpcmVjdG9yeSgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICBjb25zdCBzdGFydGVkQXRJbk1pbGxpc2Vjb25kcyA9IERhdGUubm93KCk7XG4gIGNvbnN0IGRlYWRsaW5lSW5NaWxsaXNlY29uZHMgPSBzdGFydGVkQXRJbk1pbGxpc2Vjb25kcyArIHRpbWVvdXRJbk1pbGxpc2Vjb25kcztcbiAgbGV0IGxhc3RMb2dnZWRXYWl0QXRJbk1pbGxpc2Vjb25kczogbnVsbCB8IG51bWJlciA9IG51bGw7XG5cbiAgZm9yICg7Oykge1xuICAgIGNvbnN0IG93bkluZm8gPSB0cnlDcmVhdGVMb2NrRmlsZShsb2NrRmlsZVBhdGgsIGxhYmVsKTtcbiAgICBpZiAob3duSW5mbykge1xuICAgICAgcmV0dXJuIGNyZWF0ZUxvY2tIYW5kbGUoe1xuICAgICAgICBsYWJlbCxcbiAgICAgICAgbG9ja0ZpbGVQYXRoLFxuICAgICAgICBvd25JbmZvLFxuICAgICAgICBzY29wZVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgaW5mbyA9IHJlYWRMb2NrRmlsZUluZm8obG9ja0ZpbGVQYXRoKTtcbiAgICBpZiAoaW5mbyAmJiBjaGVja0lzTG9ja1N0YWxlKGluZm8sIEhFQVJUQkVBVF9TVEFMRV9JTl9NSUxMSVNFQ09ORFMpKSB7XG4gICAgICBzdGVhbFN0YWxlTG9jayh7IGluZm8sIGxhYmVsLCBsb2NrRmlsZVBhdGgsIHNjb3BlIH0pO1xuICAgICAgLy8gUmV0cnkgaW1tZWRpYXRlbHkgXHUyMDE0IGJ1dCBzdGlsbCBob25vdXIgdGhlIGRlYWRsaW5lLCBzbyBhIGxvY2sgdGhhdCBhXG4gICAgICAvLyBDb21wZXRpbmcgcnVuIGtlZXBzIHJlY3JlYXRpbmcgY2Fubm90IHNwaW4gdGhpcyBsb29wIGZvcmV2ZXIuXG4gICAgICBpZiAoRGF0ZS5ub3coKSA+PSBkZWFkbGluZUluTWlsbGlzZWNvbmRzKSB7XG4gICAgICAgIHRocm93IGNyZWF0ZVRpbWVvdXRFcnJvcih7XG4gICAgICAgICAgaW5mbyxcbiAgICAgICAgICBzY29wZSxcbiAgICAgICAgICB0aW1lb3V0SW5NaWxsaXNlY29uZHNcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBub3dJbk1pbGxpc2Vjb25kcyA9IERhdGUubm93KCk7XG4gICAgaWYgKG5vd0luTWlsbGlzZWNvbmRzID49IGRlYWRsaW5lSW5NaWxsaXNlY29uZHMpIHtcbiAgICAgIHRocm93IGNyZWF0ZVRpbWVvdXRFcnJvcih7XG4gICAgICAgIGluZm8sXG4gICAgICAgIHNjb3BlLFxuICAgICAgICB0aW1lb3V0SW5NaWxsaXNlY29uZHNcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHNob3VsZExvZ1dhaXQgPSBsYXN0TG9nZ2VkV2FpdEF0SW5NaWxsaXNlY29uZHMgPT09IG51bGxcbiAgICAgIHx8IG5vd0luTWlsbGlzZWNvbmRzIC0gbGFzdExvZ2dlZFdhaXRBdEluTWlsbGlzZWNvbmRzID49IFdBSVRfTE9HX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUztcbiAgICBpZiAoc2hvdWxkTG9nV2FpdCkge1xuICAgICAgbGFzdExvZ2dlZFdhaXRBdEluTWlsbGlzZWNvbmRzID0gbm93SW5NaWxsaXNlY29uZHM7XG4gICAgICBsb2coZm9ybWF0V2FpdE1lc3NhZ2Uoe1xuICAgICAgICBpbmZvLFxuICAgICAgICBsYWJlbCxcbiAgICAgICAgcmVtYWluaW5nSW5NaWxsaXNlY29uZHM6IGRlYWRsaW5lSW5NaWxsaXNlY29uZHMgLSBub3dJbk1pbGxpc2Vjb25kcyxcbiAgICAgICAgc2NvcGUsXG4gICAgICAgIHdhaXRlZEluTWlsbGlzZWNvbmRzOiBub3dJbk1pbGxpc2Vjb25kcyAtIHN0YXJ0ZWRBdEluTWlsbGlzZWNvbmRzXG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgYXdhaXQgZGVsYXkoUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICB9XG59XG5cbi8qKlxuICogUmVwb3J0cyB3aGV0aGVyIGEgcnVuIGN1cnJlbnRseSBob2xkcyB0aGUgc2V0dXAgbG9jayBmb3IgYSBzY29wZS5cbiAqXG4gKiBBIGxvY2sgZmlsZSB0aGF0IGV4aXN0cyBidXQgY2Fubm90IGJlIHJlYWQgY291bnRzIGFzIGhlbGQgXHUyMDE0IHRoZSBzYW1lIGFuc3dlclxuICoge0BsaW5rIGFjcXVpcmVTZXR1cExvY2t9IGdpdmVzIGJ5IHdhaXRpbmcgb24gaXQ6IGl0IGlzIGVpdGhlciBtaWQtd3JpdGUgb3JcbiAqIGNvcnJ1cHQsIGFuZCBlaXRoZXIgd2F5IG5vIHJ1biBjYW4gdGFrZSBpdC5cbiAqXG4gKiBAcGFyYW0gc2NvcGUgLSBUaGUgbG9jayBzY29wZS5cbiAqIEByZXR1cm5zIGB0cnVlYCB3aGVuIGEgaG9sZGVyIHRoYXQgaXMgbm90IHN0YWxlIG93bnMgdGhlIGxvY2suXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGVja0lzU2V0dXBMb2NrSGVsZChzY29wZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGxldCB0ZXh0OiBzdHJpbmc7XG4gIHRyeSB7XG4gICAgdGV4dCA9IHJlYWRGaWxlU3luYyhnZXRMb2NrRmlsZVBhdGgoc2NvcGUpLCAndXRmLTgnKTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICByZXR1cm4gZ2V0RXJyb3JDb2RlKGVycm9yKSAhPT0gJ0VOT0VOVCc7XG4gIH1cblxuICBsZXQgaW5mbzogTG9ja0ZpbGVJbmZvO1xuICB0cnkge1xuICAgIGluZm8gPSBKU09OLnBhcnNlKHRleHQpIGFzIExvY2tGaWxlSW5mbztcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gIWNoZWNrSXNMb2NrU3RhbGUoaW5mbywgSEVBUlRCRUFUX1NUQUxFX0lOX01JTExJU0VDT05EUyk7XG59XG5cbi8qKlxuICogVGFrZXMgdGhlIHNldHVwIGxvY2sgZm9yIGEgc2NvcGUgaWYgaXQgaXMgZnJlZSBvciBhYmFuZG9uZWQsIHdpdGhvdXQgd2FpdGluZy5cbiAqXG4gKiBPbmUgYXR0ZW1wdDogYSBsaXZlIGhvbGRlciBcdTIwMTQgb3IgYSBsb2NrIGZpbGUgdGhhdCBjYW5ub3QgYmUgcmVhZCBcdTIwMTQgbWVhbnNcbiAqIGB1bmRlZmluZWRgLCBhbmQgdGhlIGNhbGxlciBkZWNpZGVzIHdoZXRoZXIgdG8gdHJ5IGFnYWluIGxhdGVyLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgbG9jayBwYXJhbWV0ZXJzLlxuICogQHJldHVybnMgQSBoYW5kbGUgd2hvc2Uge0BsaW5rIFNldHVwTG9jay5yZWxlYXNlfSBmcmVlcyB0aGUgbG9jaywgb3IgYHVuZGVmaW5lZGAgd2hpbGUgYW5vdGhlciBydW4gaG9sZHMgaXQuXG4gKiBAdGhyb3dzIElmIHRoZSBmaWxlIHN5c3RlbSBmYWlscyBmb3IgYW55IHJlYXNvbiBvdGhlciB0aGFuIHRoZSBsb2NrIGZpbGUgYWxyZWFkeSBleGlzdGluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyeUFjcXVpcmVTZXR1cExvY2socGFyYW1zOiBUcnlBY3F1aXJlU2V0dXBMb2NrUGFyYW1zKTogU2V0dXBMb2NrIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgeyBsYWJlbCwgc2NvcGUgfSA9IHBhcmFtcztcbiAgY29uc3QgbG9ja0ZpbGVQYXRoID0gZ2V0TG9ja0ZpbGVQYXRoKHNjb3BlKTtcbiAgbWtkaXJTeW5jKGdldExvY2tEaXJlY3RvcnkoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgbGV0IG93bkluZm8gPSB0cnlDcmVhdGVMb2NrRmlsZShsb2NrRmlsZVBhdGgsIGxhYmVsKTtcbiAgaWYgKCFvd25JbmZvKSB7XG4gICAgY29uc3QgaW5mbyA9IHJlYWRMb2NrRmlsZUluZm8obG9ja0ZpbGVQYXRoKTtcbiAgICBpZiAoIWluZm8gfHwgIWNoZWNrSXNMb2NrU3RhbGUoaW5mbywgcGFyYW1zLnN0YWxlQWZ0ZXJTaWxlbmNlSW5NaWxsaXNlY29uZHMgPz8gSEVBUlRCRUFUX1NUQUxFX0lOX01JTExJU0VDT05EUykpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgc3RlYWxTdGFsZUxvY2soeyBpbmZvLCBsYWJlbCwgbG9ja0ZpbGVQYXRoLCBzY29wZSB9KTtcbiAgICBvd25JbmZvID0gdHJ5Q3JlYXRlTG9ja0ZpbGUobG9ja0ZpbGVQYXRoLCBsYWJlbCk7XG4gICAgaWYgKCFvd25JbmZvKSB7XG4gICAgICAvLyBBbm90aGVyIHJ1biByZWNyZWF0ZWQgaXQgYmV0d2VlbiB0aGUgc3RlYWwgYW5kIHRoaXMgYXR0ZW1wdDsgaXQgaXMgdGhlaXJzIG5vdy5cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZUxvY2tIYW5kbGUoe1xuICAgIGxhYmVsLFxuICAgIGxvY2tGaWxlUGF0aCxcbiAgICBvd25JbmZvLFxuICAgIHNjb3BlXG4gIH0pO1xufVxuXG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciBhIGxvY2sgY2FuIGJlIGNvbnNpZGVyZWQgYWJhbmRvbmVkLlxuICpcbiAqIEEgbGl2ZSBob2xkZXIgcmVmcmVzaGVzIGl0cyBoZWFydGJlYXQgZXZlcnlcbiAqIHtAbGluayBIRUFSVEJFQVRfSU5URVJWQUxfSU5fTUlMTElTRUNPTkRTfSwgc28gYSBoZWFydGJlYXQgdGhhdCBzdG9wcGVkIG1lYW5zXG4gKiB0aGUgaG9sZGVyIGlzIGdvbmUuIFRoYXQgaXMgdGhlIHByaW1hcnkgc2lnbmFsLCBiZWNhdXNlIHRoZSByZWNvcmRlZCBQSUQgYWxvbmVcbiAqIGNhbm5vdCBiZSB0cnVzdGVkOiB7QGxpbmsgY2hlY2tJc1Byb2Nlc3NBbGl2ZX0gb25seSBhbnN3ZXJzIFwiZG9lcyAqYSogcHJvY2Vzc1xuICogd2l0aCB0aGlzIFBJRCBleGlzdFwiLCB3aGljaCBhIHJlY3ljbGVkIFBJRCBzYXRpc2ZpZXMgbG9uZyBhZnRlciB0aGUgaG9sZGVyXG4gKiBkaWVkLlxuICpcbiAqIE9uIHRoZSBzYW1lIGhvc3QgYSBkZWFkIFBJRCBpcyBzdGlsbCBhbiBpbW1lZGlhdGUgZ2l2ZS1hd2F5LCBzbyBpdCBpcyBrZXB0IGFzXG4gKiBhIGZhc3QgcGF0aC4gT24gYSBkaWZmZXJlbnQgaG9zdCAoYSBzaGFyZWQvbmV0d29yayB0ZW1wIGRpcmVjdG9yeSkgdGhlIFBJRFxuICogY2Fubm90IGJlIHByb2JlZCBhdCBhbGwgYW5kIHRoZSB0d28gY2xvY2tzIG1heSBkaXNhZ3JlZSwgc28gdGhlIG11Y2ggd2lkZXJcbiAqIHtAbGluayBTVEFMRV9MT0NLX0FHRV9JTl9NSUxMSVNFQ09ORFN9IHRocmVzaG9sZCBpcyB1c2VkIGluc3RlYWQuXG4gKlxuICogQHBhcmFtIGluZm8gLSBUaGUgcGFyc2VkIGxvY2sgaW5mby5cbiAqIEBwYXJhbSBoZWFydGJlYXRTdGFsZUluTWlsbGlzZWNvbmRzIC0gSG93IGxvbmcgYSBzYW1lLWhvc3QgaG9sZGVyIHdob3NlIFBJRCBpcyBhbGl2ZSBtYXkgc3RheSBzaWxlbnQuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGxvY2sgaXMgc3RhbGUgYW5kIG1heSBiZSBzdG9sZW4uXG4gKi9cbmZ1bmN0aW9uIGNoZWNrSXNMb2NrU3RhbGUoaW5mbzogTG9ja0ZpbGVJbmZvLCBoZWFydGJlYXRTdGFsZUluTWlsbGlzZWNvbmRzOiBudW1iZXIpOiBib29sZWFuIHtcbiAgY29uc3Qgc2lsZW50Rm9ySW5NaWxsaXNlY29uZHMgPSBEYXRlLm5vdygpIC0gZ2V0TGFzdFNlZW5BdEluTWlsbGlzZWNvbmRzKGluZm8pO1xuXG4gIGlmIChpbmZvLmhvc3RuYW1lID09PSBob3N0bmFtZSgpKSB7XG4gICAgcmV0dXJuICFjaGVja0lzUHJvY2Vzc0FsaXZlKGluZm8ucGlkKSB8fCBzaWxlbnRGb3JJbk1pbGxpc2Vjb25kcyA+IGhlYXJ0YmVhdFN0YWxlSW5NaWxsaXNlY29uZHM7XG4gIH1cblxuICByZXR1cm4gc2lsZW50Rm9ySW5NaWxsaXNlY29uZHMgPiBTVEFMRV9MT0NLX0FHRV9JTl9NSUxMSVNFQ09ORFM7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgbG9jayBmaWxlIHN0aWxsIG5hbWVzIHRoaXMgcHJvY2VzcyBhcyBpdHMgaG9sZGVyLlxuICpcbiAqIEBwYXJhbSBpbmZvIC0gVGhlIHBhcnNlZCBsb2NrIGluZm8uXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhpcyBwcm9jZXNzIGhvbGRzIHRoZSBsb2NrLlxuICovXG5mdW5jdGlvbiBjaGVja0lzT3duTG9jayhpbmZvOiBMb2NrRmlsZUluZm8pOiBib29sZWFuIHtcbiAgcmV0dXJuIGluZm8ucGlkID09PSBwcm9jZXNzLnBpZCAmJiBpbmZvLmhvc3RuYW1lID09PSBob3N0bmFtZSgpO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgcHJvY2VzcyB3aXRoIHRoZSBnaXZlbiBQSUQgaXMgY3VycmVudGx5IGFsaXZlLlxuICpcbiAqIEBwYXJhbSBwaWQgLSBUaGUgcHJvY2VzcyBJRCB0byBwcm9iZS5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvY2VzcyBleGlzdHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrSXNQcm9jZXNzQWxpdmUocGlkOiBudW1iZXIpOiBib29sZWFuIHtcbiAgdHJ5IHtcbiAgICBwcm9jZXNzLmtpbGwocGlkLCBQUk9DRVNTX0VYSVNURU5DRV9QUk9CRV9TSUdOQUwpO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIC8vIGBFUEVSTWAgbWVhbnMgdGhlIHByb2Nlc3MgZXhpc3RzIGJ1dCBpcyBvd25lZCBieSBhbm90aGVyIHVzZXIgXHUyMDE0IHN0aWxsIGFsaXZlLlxuICAgIHJldHVybiBnZXRFcnJvckNvZGUoZXJyb3IpID09PSAnRVBFUk0nO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIHtAbGluayBTZXR1cExvY2t9IGhhbmRsZSB0aGF0IGtlZXBzIHRoZSBsb2NrJ3MgaGVhcnRiZWF0IGZyZXNoIHdoaWxlXG4gKiBoZWxkIGFuZCByZW1vdmVzIHRoZSBsb2NrIGZpbGUgb24gcmVsZWFzZS5cbiAqXG4gKiBUaGUgaGVhcnRiZWF0IHRpbWVyIGlzIGB1bnJlZmBlZCBzbyBpdCBjYW4gbmV2ZXIga2VlcCB0aGUgcHJvY2VzcyBhbGl2ZSBvbiBpdHNcbiAqIG93biwgYW5kIGl0IHN0b3BzIGFzIHNvb24gYXMgdGhlIGxvY2sgZmlsZSBuYW1lcyBzb21lYm9keSBlbHNlIFx1MjAxNCBhIHJ1biB3aG9zZVxuICogbG9jayB3YXMgc3RvbGVuIG11c3Qgbm90IG92ZXJ3cml0ZSBpdHMgc3VjY2Vzc29yJ3MgbG9jaywgbm9yIGRlbGV0ZSBpdCBvblxuICogcmVsZWFzZS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGhhbmRsZSBwYXJhbWV0ZXJzLlxuICogQHJldHVybnMgVGhlIGxvY2sgaGFuZGxlLlxuICovXG5mdW5jdGlvbiBjcmVhdGVMb2NrSGFuZGxlKHBhcmFtczogQ3JlYXRlTG9ja0hhbmRsZVBhcmFtcyk6IFNldHVwTG9jayB7XG4gIGNvbnN0IHtcbiAgICBsYWJlbCxcbiAgICBsb2NrRmlsZVBhdGgsXG4gICAgb3duSW5mbyxcbiAgICBzY29wZVxuICB9ID0gcGFyYW1zO1xuICBsZXQgaXNSZWxlYXNlZCA9IGZhbHNlO1xuXG4gIGNvbnN0IGhlYXJ0YmVhdFRpbWVyID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgIGNvbnN0IGlzU3RpbGxPdXJzID0gZGlkUmVmcmVzaEhlYXJ0YmVhdCh7XG4gICAgICBsYWJlbCxcbiAgICAgIGxvY2tGaWxlUGF0aCxcbiAgICAgIG93bkluZm9cbiAgICB9KTtcbiAgICBpZiAoaXNTdGlsbE91cnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY2xlYXJJbnRlcnZhbChoZWFydGJlYXRUaW1lcik7XG4gICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFRoZSAnJHtzY29wZX0nIHNldHVwIGxvY2sgaXMgbm8gbG9uZ2VyIG91cnMgXHUyMDE0IGFub3RoZXIgcnVuIHRvb2sgaXQgb3Zlci4gSGVhcnRiZWF0IHN0b3BwZWQuYCk7XG4gIH0sIEhFQVJUQkVBVF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICBoZWFydGJlYXRUaW1lci51bnJlZigpO1xuXG4gIHJldHVybiB7XG4gICAgcmVsZWFzZSgpOiB2b2lkIHtcbiAgICAgIGlmIChpc1JlbGVhc2VkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlzUmVsZWFzZWQgPSB0cnVlO1xuICAgICAgY2xlYXJJbnRlcnZhbChoZWFydGJlYXRUaW1lcik7XG5cbiAgICAgIGNvbnN0IGluZm8gPSByZWFkTG9ja0ZpbGVJbmZvKGxvY2tGaWxlUGF0aCk7XG4gICAgICBpZiAoaW5mbyAmJiAhY2hlY2tJc093bkxvY2soaW5mbykpIHtcbiAgICAgICAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIExlYXZpbmcgdGhlICcke3Njb3BlfScgc2V0dXAgbG9jayBpbiBwbGFjZSBcdTIwMTQgaXQgbm93IGJlbG9uZ3MgdG8gJHtkZXNjcmliZUluZm8oaW5mbyl9LmApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBybVN5bmMobG9ja0ZpbGVQYXRoLCB7IGZvcmNlOiB0cnVlIH0pO1xuICAgIH1cbiAgfTtcbn1cblxuLyoqXG4gKiBCdWlsZHMgdGhlIGVycm9yIHRocm93biB3aGVuIHRoZSBsb2NrIGNvdWxkIG5vdCBiZSBhY3F1aXJlZCBpbiB0aW1lLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZXJyb3IgcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIFRoZSBlcnJvciB0byB0aHJvdy5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlVGltZW91dEVycm9yKHBhcmFtczogQ3JlYXRlVGltZW91dEVycm9yUGFyYW1zKTogRXJyb3Ige1xuICBjb25zdCB7XG4gICAgaW5mbyxcbiAgICBzY29wZSxcbiAgICB0aW1lb3V0SW5NaWxsaXNlY29uZHNcbiAgfSA9IHBhcmFtcztcbiAgcmV0dXJuIG5ldyBFcnJvcihcbiAgICBgVGltZWQgb3V0IGFmdGVyICR7U3RyaW5nKHRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9bXMgd2FpdGluZyBmb3IgdGhlICcke3Njb3BlfScgaW50ZWdyYXRpb24tdGVzdCBzZXR1cCBsb2NrIGBcbiAgICAgICsgYGhlbGQgYnkgJHtkZXNjcmliZUhvbGRlcihpbmZvKX0uIEFub3RoZXIgaW50ZWdyYXRpb24tdGVzdCBydW4gaXMgc3RpbGwgaW4gcHJvZ3Jlc3MuYFxuICApO1xufVxuXG4vKipcbiAqIFJlc29sdmVzIGFmdGVyIHRoZSBnaXZlbiBkZWxheS4gVXNlZCB0byBwb2xsIGJldHdlZW4gbG9jay1hY3F1aXNpdGlvbiBhdHRlbXB0cy5cbiAqXG4gKiBAcGFyYW0gbWlsbGlzZWNvbmRzIC0gVGhlIGRlbGF5IGluIG1pbGxpc2Vjb25kcy5cbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIHRoZSBkZWxheS5cbiAqL1xuZnVuY3Rpb24gZGVsYXkobWlsbGlzZWNvbmRzOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgc2V0VGltZW91dChyZXNvbHZlLCBtaWxsaXNlY29uZHMpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBCdWlsZHMgYSBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUgY3VycmVudCBsb2NrIGhvbGRlciBmb3IgbG9nL2Vycm9yXG4gKiBtZXNzYWdlcy5cbiAqXG4gKiBAcGFyYW0gaW5mbyAtIFRoZSBwYXJzZWQgbG9jayBpbmZvLCBvciBgbnVsbGAgaWYgaXQgY291bGQgbm90IGJlIHJlYWQuXG4gKiBAcmV0dXJucyBBIGRlc2NyaXB0aW9uIHN0cmluZy5cbiAqL1xuZnVuY3Rpb24gZGVzY3JpYmVIb2xkZXIoaW5mbzogTG9ja0ZpbGVJbmZvIHwgbnVsbCk6IHN0cmluZyB7XG4gIHJldHVybiBpbmZvID8gZGVzY3JpYmVJbmZvKGluZm8pIDogJ2Fub3RoZXIgcnVuJztcbn1cblxuLyoqXG4gKiBGb3JtYXRzIGEge0BsaW5rIExvY2tGaWxlSW5mb30gYXMgYSBzaG9ydCBpZGVudGlmaWVyIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gaW5mbyAtIFRoZSBsb2NrIGluZm8uXG4gKiBAcmV0dXJucyBBIHN0cmluZyBsaWtlIGBwaWQgMTIzNCAob2JzaWRpYW4tY2xpKSBvbiBob3N0YC5cbiAqL1xuZnVuY3Rpb24gZGVzY3JpYmVJbmZvKGluZm86IExvY2tGaWxlSW5mbyk6IHN0cmluZyB7XG4gIHJldHVybiBgcGlkICR7U3RyaW5nKGluZm8ucGlkKX0gKCR7aW5mby5sYWJlbH0pIG9uICR7aW5mby5ob3N0bmFtZX1gO1xufVxuXG4vKipcbiAqIFJld3JpdGVzIHRoZSBsb2NrIGZpbGUgd2l0aCBhIGZyZXNoIGhlYXJ0YmVhdCB0aW1lc3RhbXAsIHNvIHdhaXRpbmcgcnVucyBjYW5cbiAqIHRlbGwgdGhpcyBob2xkZXIgYXBhcnQgZnJvbSBhIGNyYXNoZWQgb25lIHdob3NlIFBJRCBoYXMgYmVlbiByZWN5Y2xlZC5cbiAqXG4gKiBBIGxvY2sgZmlsZSB0aGF0IGlzIG1pc3Npbmcgb3IgdW5yZWFkYWJsZSBpcyBzdGlsbCB0cmVhdGVkIGFzIG91cnMgYW5kIHJld3JpdHRlbjpcbiAqIHRoaXMgcnVuIG5ldmVyIHJlbGVhc2VkLCBzbyBpdHMgY2xhaW0gc3RhbmRzLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcmVmcmVzaCBwYXJhbWV0ZXJzLlxuICogQHJldHVybnMgYHRydWVgIHdoaWxlIHRoZSBsb2NrIGlzIHN0aWxsIG91cnMsIGBmYWxzZWAgb25jZSBhbm90aGVyIHJ1biBvd25zIGl0LlxuICovXG5mdW5jdGlvbiBkaWRSZWZyZXNoSGVhcnRiZWF0KHBhcmFtczogUmVmcmVzaEhlYXJ0YmVhdFBhcmFtcyk6IGJvb2xlYW4ge1xuICBjb25zdCB7XG4gICAgbGFiZWwsXG4gICAgbG9ja0ZpbGVQYXRoLFxuICAgIG93bkluZm9cbiAgfSA9IHBhcmFtcztcblxuICBjb25zdCBpbmZvID0gcmVhZExvY2tGaWxlSW5mbyhsb2NrRmlsZVBhdGgpO1xuICBpZiAoaW5mbyAmJiAhY2hlY2tJc093bkxvY2soaW5mbykpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCByZWZyZXNoZWRJbmZvOiBMb2NrRmlsZUluZm8gPSB7XG4gICAgLi4ub3duSW5mbyxcbiAgICBoZWFydGJlYXRBdEluTWlsbGlzZWNvbmRzOiBEYXRlLm5vdygpXG4gIH07XG4gIHRyeSB7XG4gICAgd3JpdGVGaWxlU3luYyhsb2NrRmlsZVBhdGgsIEpTT04uc3RyaW5naWZ5KHJlZnJlc2hlZEluZm8pKTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAvLyBOb3QgZmF0YWw6IHRoZSBsb2NrIGlzIHN0aWxsIGhlbGQgYW5kIHdpbGwgc3RpbGwgYmUgcmVsZWFzZWQuIE9ubHkgaXRzXG4gICAgLy8gSGVhcnRiZWF0IGdvZXMgc3RhbGUsIHdoaWNoIGF0IHdvcnN0IGxldHMgYSB3YWl0aW5nIHJ1biBzdGVhbCBpdC5cbiAgICBsb2coYFtpbnRlZ3JhdGlvbi1zZXR1cDoke2xhYmVsfV0gRmFpbGVkIHRvIHJlZnJlc2ggdGhlIHNldHVwIGxvY2sgaGVhcnRiZWF0OiAke2Vycm9yVG9TdHJpbmcoZXJyb3IpfWApO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIEZvcm1hdHMgYSBkdXJhdGlvbiBhcyBhIGNvbXBhY3QgYDFtIDMwc2AgLyBgNDVzYCBzdHJpbmcgZm9yIHByb2dyZXNzIGxvZ3MuXG4gKlxuICogQHBhcmFtIG1pbGxpc2Vjb25kcyAtIFRoZSBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcmV0dXJucyBUaGUgZm9ybWF0dGVkIGR1cmF0aW9uLlxuICovXG5mdW5jdGlvbiBmb3JtYXREdXJhdGlvbihtaWxsaXNlY29uZHM6IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IHRvdGFsU2Vjb25kcyA9IE1hdGgucm91bmQobWlsbGlzZWNvbmRzIC8gTUlMTElTRUNPTkRTX1BFUl9TRUNPTkQpO1xuICBjb25zdCBtaW51dGVzID0gTWF0aC5mbG9vcih0b3RhbFNlY29uZHMgLyBTRUNPTkRTX1BFUl9NSU5VVEUpO1xuICBjb25zdCBzZWNvbmRzID0gdG90YWxTZWNvbmRzICUgU0VDT05EU19QRVJfTUlOVVRFO1xuICByZXR1cm4gbWludXRlcyA+IDAgPyBgJHtTdHJpbmcobWludXRlcyl9bSAke1N0cmluZyhzZWNvbmRzKX1zYCA6IGAke1N0cmluZyhzZWNvbmRzKX1zYDtcbn1cblxuLyoqXG4gKiBCdWlsZHMgdGhlIHBlcmlvZGljIFwic3RpbGwgd2FpdGluZ1wiIHByb2dyZXNzIGxpbmUsIHNvIGEgbGVnaXRpbWF0ZSBtdWx0aS1taW51dGVcbiAqIHdhaXQgaXMgZGlzdGluZ3Vpc2hhYmxlIGZyb20gYSBoYW5nIGluIHRoZSB0ZXJtaW5hbC5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIG1lc3NhZ2UgcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIFRoZSBtZXNzYWdlIHRvIGxvZy5cbiAqL1xuZnVuY3Rpb24gZm9ybWF0V2FpdE1lc3NhZ2UocGFyYW1zOiBGb3JtYXRXYWl0TWVzc2FnZVBhcmFtcyk6IHN0cmluZyB7XG4gIGNvbnN0IHtcbiAgICBpbmZvLFxuICAgIGxhYmVsLFxuICAgIHJlbWFpbmluZ0luTWlsbGlzZWNvbmRzLFxuICAgIHNjb3BlLFxuICAgIHdhaXRlZEluTWlsbGlzZWNvbmRzXG4gIH0gPSBwYXJhbXM7XG4gIGNvbnN0IGhlbGRGb3IgPSBpbmZvID8gYCwgaGVsZCBmb3IgJHtmb3JtYXREdXJhdGlvbihEYXRlLm5vdygpIC0gaW5mby5hY3F1aXJlZEF0SW5NaWxsaXNlY29uZHMpfWAgOiAnJztcbiAgcmV0dXJuIGBbaW50ZWdyYXRpb24tc2V0dXA6JHtsYWJlbH1dIFdhaXRpbmcgZm9yIHRoZSAnJHtzY29wZX0nIHNldHVwIGxvY2sgaGVsZCBieSAke2Rlc2NyaWJlSG9sZGVyKGluZm8pfSB0byBiZSByZWxlYXNlZCBgXG4gICAgKyBgKHdhaXRlZCAke2Zvcm1hdER1cmF0aW9uKHdhaXRlZEluTWlsbGlzZWNvbmRzKX0ke2hlbGRGb3J9LCBnaXZpbmcgdXAgaW4gJHtmb3JtYXREdXJhdGlvbihyZW1haW5pbmdJbk1pbGxpc2Vjb25kcyl9KS4uLmA7XG59XG5cbi8qKlxuICogRXh0cmFjdHMgdGhlIGBjb2RlYCBmcm9tIGEgTm9kZS5qcyBzeXN0ZW0gZXJyb3IsIGlmIHByZXNlbnQuXG4gKlxuICogQHBhcmFtIGVycm9yIC0gVGhlIHRocm93biB2YWx1ZS5cbiAqIEByZXR1cm5zIFRoZSBlcnJvciBjb2RlIHN0cmluZywgb3IgYHVuZGVmaW5lZGAgaWYgbm90IGEgY29kZWQgZXJyb3IuXG4gKi9cbmZ1bmN0aW9uIGdldEVycm9yQ29kZShlcnJvcjogdW5rbm93bik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmICdjb2RlJyBpbiBlcnJvciAmJiB0eXBlb2YgZXJyb3IuY29kZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZXJyb3IuY29kZTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFJldHVybnMgd2hlbiB0aGUgaG9sZGVyIHdhcyBsYXN0IGtub3duIHRvIGJlIGFsaXZlIFx1MjAxNCBpdHMgbW9zdCByZWNlbnQgaGVhcnRiZWF0LFxuICogZmFsbGluZyBiYWNrIHRvIGl0cyBhY3F1aXNpdGlvbiB0aW1lIGZvciBhIGxvY2sgZmlsZSB3cml0dGVuIGJ5IGFuIG9sZGVyXG4gKiB2ZXJzaW9uIG9mIHRoaXMgcGFja2FnZSB0aGF0IHN0YW1wZWQgbm8gaGVhcnRiZWF0IGF0IGFsbC5cbiAqXG4gKiBAcGFyYW0gaW5mbyAtIFRoZSBwYXJzZWQgbG9jayBpbmZvLlxuICogQHJldHVybnMgVGhlIGVwb2NoIG1pbGxpc2Vjb25kcyBvZiB0aGUgaG9sZGVyJ3MgbGFzdCBzaWduIG9mIGxpZmUuXG4gKi9cbmZ1bmN0aW9uIGdldExhc3RTZWVuQXRJbk1pbGxpc2Vjb25kcyhpbmZvOiBMb2NrRmlsZUluZm8pOiBudW1iZXIge1xuICByZXR1cm4gaW5mby5oZWFydGJlYXRBdEluTWlsbGlzZWNvbmRzID8/IGluZm8uYWNxdWlyZWRBdEluTWlsbGlzZWNvbmRzO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHNoYXJlZCBsb2NrIGRpcmVjdG9yeSBpbnNpZGUgdGhlIE9TIHRlbXAgZGlyZWN0b3J5LlxuICpcbiAqIEByZXR1cm5zIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBsb2NrIGRpcmVjdG9yeS5cbiAqL1xuZnVuY3Rpb24gZ2V0TG9ja0RpcmVjdG9yeSgpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbih0bXBkaXIoKSwgTE9DS19ESVJfTkFNRSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbG9jayBmaWxlIHBhdGggZm9yIHRoZSBnaXZlbiBzY29wZS5cbiAqXG4gKiBAcGFyYW0gc2NvcGUgLSBUaGUgbG9jayBzY29wZS5cbiAqIEByZXR1cm5zIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBzY29wZSdzIGxvY2sgZmlsZS5cbiAqL1xuZnVuY3Rpb24gZ2V0TG9ja0ZpbGVQYXRoKHNjb3BlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihnZXRMb2NrRGlyZWN0b3J5KCksIGAke3Njb3BlfSR7TE9DS19GSUxFX1NVRkZJWH1gKTtcbn1cblxuLyoqXG4gKiBSZWFkcyBhbmQgcGFyc2VzIHRoZSBsb2NrIGZpbGUsIGlmIGl0IGV4aXN0cyBhbmQgaXMgdmFsaWQgSlNPTi5cbiAqXG4gKiBAcGFyYW0gbG9ja0ZpbGVQYXRoIC0gVGhlIHBhdGggdG8gdGhlIGxvY2sgZmlsZS5cbiAqIEByZXR1cm5zIFRoZSBwYXJzZWQgbG9jayBpbmZvLCBvciBgbnVsbGAgaWYgaXQgY291bGQgbm90IGJlIHJlYWQuXG4gKi9cbmZ1bmN0aW9uIHJlYWRMb2NrRmlsZUluZm8obG9ja0ZpbGVQYXRoOiBzdHJpbmcpOiBMb2NrRmlsZUluZm8gfCBudWxsIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShyZWFkRmlsZVN5bmMobG9ja0ZpbGVQYXRoLCAndXRmLTgnKSkgYXMgTG9ja0ZpbGVJbmZvO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG4vKipcbiAqIFJlbW92ZXMgYW4gYWJhbmRvbmVkIGhvbGRlcidzIGxvY2sgZmlsZSwgc2F5aW5nIHdob3NlIGl0IHdhcy5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGFiYW5kb25lZCBob2xkZXIsIGFuZCB3aG8gaXMgdGFraW5nIG92ZXIuXG4gKi9cbmZ1bmN0aW9uIHN0ZWFsU3RhbGVMb2NrKHBhcmFtczogU3RlYWxTdGFsZUxvY2tQYXJhbXMpOiB2b2lkIHtcbiAgbG9nKGBbaW50ZWdyYXRpb24tc2V0dXA6JHtwYXJhbXMubGFiZWx9XSBTdGVhbGluZyBzdGFsZSAnJHtwYXJhbXMuc2NvcGV9JyBzZXR1cCBsb2NrIGZyb20gJHtkZXNjcmliZUluZm8ocGFyYW1zLmluZm8pfS5gKTtcbiAgcm1TeW5jKHBhcmFtcy5sb2NrRmlsZVBhdGgsIHsgZm9yY2U6IHRydWUgfSk7XG59XG5cbi8qKlxuICogQXR0ZW1wdHMgdG8gYXRvbWljYWxseSBjcmVhdGUgdGhlIGxvY2sgZmlsZSAoZmFpbGluZyBpZiBpdCBhbHJlYWR5IGV4aXN0cykuXG4gKlxuICogQHBhcmFtIGxvY2tGaWxlUGF0aCAtIFRoZSBwYXRoIHRvIHRoZSBsb2NrIGZpbGUuXG4gKiBAcGFyYW0gbGFiZWwgLSBUaGUgdHJhbnNwb3J0IGxhYmVsIHRvIHJlY29yZCBpbiB0aGUgbG9jayBmaWxlLlxuICogQHJldHVybnMgVGhlIGxvY2sgaW5mbyB3cml0dGVuIG9uIHN1Y2Nlc3MsIG9yIGBudWxsYCBpZiB0aGUgbG9jayBpcyBhbHJlYWR5IGhlbGQuXG4gKiBAdGhyb3dzIElmIHRoZSBmaWxlIHN5c3RlbSBmYWlscyBmb3IgYW55IHJlYXNvbiBvdGhlciB0aGFuIHRoZSBmaWxlIGV4aXN0aW5nLlxuICovXG5mdW5jdGlvbiB0cnlDcmVhdGVMb2NrRmlsZShsb2NrRmlsZVBhdGg6IHN0cmluZywgbGFiZWw6IHN0cmluZyk6IExvY2tGaWxlSW5mbyB8IG51bGwge1xuICBjb25zdCBub3dJbk1pbGxpc2Vjb25kcyA9IERhdGUubm93KCk7XG4gIGNvbnN0IGluZm86IExvY2tGaWxlSW5mbyA9IHtcbiAgICBhY3F1aXJlZEF0SW5NaWxsaXNlY29uZHM6IG5vd0luTWlsbGlzZWNvbmRzLFxuICAgIGhlYXJ0YmVhdEF0SW5NaWxsaXNlY29uZHM6IG5vd0luTWlsbGlzZWNvbmRzLFxuICAgIGhvc3RuYW1lOiBob3N0bmFtZSgpLFxuICAgIGxhYmVsLFxuICAgIHBpZDogcHJvY2Vzcy5waWRcbiAgfTtcblxuICB0cnkge1xuICAgIHdyaXRlRmlsZVN5bmMobG9ja0ZpbGVQYXRoLCBKU09OLnN0cmluZ2lmeShpbmZvKSwgeyBmbGFnOiAnd3gnIH0pO1xuICAgIHJldHVybiBpbmZvO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGlmIChnZXRFcnJvckNvZGUoZXJyb3IpID09PSAnRUVYSVNUJykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHRocm93IGVycm9yO1xuICB9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQTBCQSxxQkFLTztBQUNQLHFCQUdPO0FBQ1AsdUJBQXFCO0FBQ3JCLDBCQUFvQjtBQUVwQiw2QkFBOEI7QUFDOUIsaUJBQW9CO0FBT2IsTUFBTSwyQkFBMkI7QUFFeEMsTUFBTSxnQkFBZ0I7QUFDdEIsTUFBTSxtQkFBbUI7QUFDekIsTUFBTSxnQ0FBZ0M7QUFDdEMsTUFBTSwwQkFBMEI7QUFDaEMsTUFBTSxxQkFBcUI7QUFDM0IsTUFBTSxnQ0FBZ0M7QUFDdEMsTUFBTSxxQ0FBcUMsZ0NBQWdDO0FBSzNFLE1BQU0saUNBQWlDO0FBQ3ZDLE1BQU0sa0NBQWtDLHFDQUFxQztBQUM3RSxNQUFNLCtCQUErQjtBQUNyQyxNQUFNLG9DQUFv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
@@ -23,6 +23,12 @@
23
23
  * recycled PID satisfies long after the real holder died — leaving every later
24
24
  * run to block for the full acquisition timeout.
25
25
  */
26
+ /**
27
+ * The scope every Android run serializes on: the Appium transport's global
28
+ * setup, a project that takes the lock itself, and the emulator reaper all
29
+ * have to name the same one, or they serialize against nothing.
30
+ */
31
+ export declare const ANDROID_SETUP_LOCK_SCOPE = "android";
26
32
  /**
27
33
  * Parameters for {@link acquireSetupLock}.
28
34
  */
@@ -54,6 +60,31 @@ export interface SetupLock {
54
60
  */
55
61
  release(): void;
56
62
  }
63
+ /**
64
+ * Parameters for {@link tryAcquireSetupLock}.
65
+ */
66
+ export interface TryAcquireSetupLockParams {
67
+ /**
68
+ Short transport label for log messages, recorded in the lock file as the holder's.
69
+ */
70
+ readonly label: string;
71
+ /**
72
+ Logical scope the lock serializes within — see {@link AcquireSetupLockParams.scope}.
73
+ */
74
+ readonly scope: string;
75
+ /**
76
+ * How long a same-host holder whose PID is still alive may go without a
77
+ * heartbeat before its lock counts as abandoned.
78
+ *
79
+ * A dead holder PID is abandoned at once whatever this says. The default is
80
+ * the threshold every waiting run steals on; a caller that is *always* waiting
81
+ * — the emulator reaper — passes a far wider one, so a live run that blocks
82
+ * its event loop for a couple of minutes is not robbed of its lock.
83
+ *
84
+ * @default 2 minutes
85
+ */
86
+ readonly staleAfterSilenceInMilliseconds?: number | undefined;
87
+ }
57
88
  /**
58
89
  * Acquires the cross-process setup lock for the given scope, waiting until any
59
90
  * competing run releases it (or its lock is detected as stale).
@@ -63,3 +94,25 @@ export interface SetupLock {
63
94
  * @throws If the lock cannot be acquired within `timeoutInMilliseconds`.
64
95
  */
65
96
  export declare function acquireSetupLock(params: AcquireSetupLockParams): Promise<SetupLock>;
97
+ /**
98
+ * Reports whether a run currently holds the setup lock for a scope.
99
+ *
100
+ * A lock file that exists but cannot be read counts as held — the same answer
101
+ * {@link acquireSetupLock} gives by waiting on it: it is either mid-write or
102
+ * corrupt, and either way no run can take it.
103
+ *
104
+ * @param scope - The lock scope.
105
+ * @returns `true` when a holder that is not stale owns the lock.
106
+ */
107
+ export declare function checkIsSetupLockHeld(scope: string): boolean;
108
+ /**
109
+ * Takes the setup lock for a scope if it is free or abandoned, without waiting.
110
+ *
111
+ * One attempt: a live holder — or a lock file that cannot be read — means
112
+ * `undefined`, and the caller decides whether to try again later.
113
+ *
114
+ * @param params - The lock parameters.
115
+ * @returns A handle whose {@link SetupLock.release} frees the lock, or `undefined` while another run holds it.
116
+ * @throws If the file system fails for any reason other than the lock file already existing.
117
+ */
118
+ export declare function tryAcquireSetupLock(params: TryAcquireSetupLockParams): SetupLock | undefined;
@@ -29,21 +29,27 @@ const DEFAULT_MINIMUM_KEYBOARD_HEIGHT_IN_PIXELS = 100;
29
29
  const INPUT_METHOD_STATE_REG_EXP = /mInputShown|mIsInputViewShown|mHaveConnection|mShowRequested/;
30
30
  const CENTER_DIVISOR = 2;
31
31
  function buildSoftKeyboardDiagnosticMessage(params) {
32
- const { inputRect } = params.snapshot;
33
- const inputBottom = inputRect ? inputRect.top + inputRect.height : null;
34
- return [
32
+ const baselineTop = params.baselineSnapshot.inputRect?.top ?? null;
33
+ const currentTop = params.snapshot.inputRect?.top ?? null;
34
+ const lift = baselineTop === null || currentTop === null ? null : baselineTop - currentTop;
35
+ const lines = [
35
36
  `raiseSoftKeyboard: the keyboard did not come up. Device framebuffer written to ${params.screenshotPath}.`,
36
- `page: innerHeight=${String(params.snapshot.innerHeight)} inputBottom=${inputBottom === null ? "(no input)" : String(inputBottom)}`,
37
+ `page: innerHeight=${String(params.snapshot.innerHeight)} baselineInputTop=${formatMeasurement(baselineTop)} inputTop=${formatMeasurement(currentTop)} lift=${formatMeasurement(lift)}`,
37
38
  `device: ${params.inputMethodState || "(no input_method state reported)"}`
38
- ].join("\n");
39
+ ];
40
+ if (lift === 0) {
41
+ lines.push("The field did not move at all. If the device says the keyboard is showing, it was already up before the first touch \u2014 this check cannot tell that from a field that never lifts.");
42
+ }
43
+ return lines.join("\n");
39
44
  }
40
45
  function checkIsSoftKeyboardUp(params) {
46
+ const baselineRect = params.baselineSnapshot.inputRect;
41
47
  const { inputRect } = params.snapshot;
42
- if (!inputRect) {
48
+ if (!baselineRect || !inputRect) {
43
49
  return false;
44
50
  }
45
51
  const minimumKeyboardHeightInPixels = params.minimumKeyboardHeightInPixels ?? DEFAULT_MINIMUM_KEYBOARD_HEIGHT_IN_PIXELS;
46
- return params.snapshot.innerHeight - (inputRect.top + inputRect.height) > minimumKeyboardHeightInPixels;
52
+ return baselineRect.top - inputRect.top > minimumKeyboardHeightInPixels;
47
53
  }
48
54
  function parseInputMethodState(dumpsysOutput) {
49
55
  return dumpsysOutput.split("\n").filter((line) => INPUT_METHOD_STATE_REG_EXP.test(line)).map((line) => line.trim()).join(" | ");
@@ -64,6 +70,9 @@ function resolveSoftKeyboardTapPoints(params) {
64
70
  { xInPixels, yInPixels: centerYInPixels }
65
71
  ];
66
72
  }
73
+ function formatMeasurement(value) {
74
+ return value === null ? "(no input)" : String(value);
75
+ }
67
76
  // Annotate the CommonJS export names for ESM import in node:
68
77
  0 && (module.exports = {
69
78
  DEFAULT_MINIMUM_KEYBOARD_HEIGHT_IN_PIXELS,
@@ -72,4 +81,4 @@ function resolveSoftKeyboardTapPoints(params) {
72
81
  parseInputMethodState,
73
82
  resolveSoftKeyboardTapPoints
74
83
  });
75
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3NvZnQta2V5Ym9hcmQtZ2VvbWV0cnkudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBEZWNpZGVzIHdoZXRoZXIgdGhlIEFuZHJvaWQgc29mdCBrZXlib2FyZCBpcyB1cCwgYW5kIHdoZXJlIHRvIHRvdWNoIHRvIHJhaXNlXG4gKiBpdCBcdTIwMTQgZnJvbSBnZW9tZXRyeSBhbG9uZS5cbiAqXG4gKiAqKk5vdGhpbmcgaW4gdGhlIHBhZ2UgcmVwb3J0cyB0aGUga2V5Ym9hcmQuKiogYGlubmVySGVpZ2h0YCwgYHZpc3VhbFZpZXdwb3J0YFxuICogYW5kIHRoZSBtb2RhbCBjb250YWluZXIgYWxsIHN0YXkgYXQgdGhlaXIgZnVsbCBoZWlnaHQgd2l0aCB0aGUga2V5Ym9hcmQgc2hvd25cbiAqIGFuZCBgZHVtcHN5cyBpbnB1dF9tZXRob2RgIHJlcG9ydGluZyBgbUlucHV0U2hvd249dHJ1ZWAgXHUyMDE0IE9ic2lkaWFuIE1vYmlsZSBrZWVwc1xuICogYSBmdWxsLXNjcmVlbiBjb250YWluZXIgYW5kIGxpZnRzIGl0cyBjb250ZW50cyBpbnNpZGUgaXQuIFRoZSBvbmx5IHNpZ25hbCBpc1xuICogdGhlIGZpZWxkJ3Mgb3duIG9mZnNldCBmcm9tIHRoZSBib3R0b20sIHdoaWNoIGlzIHdoeSB0aGUgZGV0ZWN0aW9uIGhlcmUgaXNcbiAqIGdlb21ldHJpYyByYXRoZXIgdGhhbiBhbiBBUEkgY2FsbC4gVHdvIHJ1bnMgZmFpbGVkIG9uIHRoYXQgYmVmb3JlIGEgZnJhbWVidWZmZXJcbiAqIGR1bXAgc2FpZCBzbywgd2hpY2ggaXMgYWxzbyB3aHkgdGhlIGRpYWdub3N0aWMgYmVsb3cgZXhpc3RzLlxuICpcbiAqIFB1cmUgYW5kIHVuaXQtdGVzdGVkOyB0aGUgdG91Y2hpbmcgYW5kIHRoZSBjYXB0dXJlIGxpdmUgaW4gYHNvZnQta2V5Ym9hcmRgLlxuICovXG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGJ1aWxkU29mdEtleWJvYXJkRGlhZ25vc3RpY01lc3NhZ2V9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkU29mdEtleWJvYXJkRGlhZ25vc3RpY01lc3NhZ2VQYXJhbXMge1xuICAvKipcbiAgICogVGhlIGxpbmVzIG9mIGBkdW1wc3lzIGlucHV0X21ldGhvZGAgd29ydGggcmVhZGluZywgYXMge0BsaW5rIHBhcnNlSW5wdXRNZXRob2RTdGF0ZX0gcmV0dXJuZWQgdGhlbS5cbiAgICovXG4gIHJlYWRvbmx5IGlucHV0TWV0aG9kU3RhdGU6IHN0cmluZztcblxuICAvKipcbiAgICogV2hlcmUgdGhlIGRldmljZSBmcmFtZWJ1ZmZlciB3YXMgd3JpdHRlbiwgc28gdGhlIHJlYWRlciBjYW4gbG9vayBhdCB3aGF0IHRoZSBkZXZpY2Ugd2FzIHNob3dpbmcuXG4gICAqL1xuICByZWFkb25seSBzY3JlZW5zaG90UGF0aDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZ2VvbWV0cnkgcmVhZCBhZnRlciB0aGUgbGFzdCB0b3VjaC5cbiAgICovXG4gIHJlYWRvbmx5IHNuYXBzaG90OiBTb2Z0S2V5Ym9hcmRWaWV3cG9ydFNuYXBzaG90O1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBjaGVja0lzU29mdEtleWJvYXJkVXB9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENoZWNrSXNTb2Z0S2V5Ym9hcmRVcFBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgbGVhc3QgYSByYWlzZWQga2V5Ym9hcmQgbGlmdHMgdGhlIGZpZWxkIGJ5LCBzbyBhIHN0cmF5IHJvdW5kaW5nIHBpeGVsIGlzIG5vdCByZWFkIGFzIG9uZS5cbiAgICpcbiAgICogQGRlZmF1bHQge0BsaW5rIERFRkFVTFRfTUlOSU1VTV9LRVlCT0FSRF9IRUlHSFRfSU5fUElYRUxTfVxuICAgKi9cbiAgcmVhZG9ubHkgbWluaW11bUtleWJvYXJkSGVpZ2h0SW5QaXhlbHM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBnZW9tZXRyeSB0byBqdWRnZS5cbiAgICovXG4gIHJlYWRvbmx5IHNuYXBzaG90OiBTb2Z0S2V5Ym9hcmRWaWV3cG9ydFNuYXBzaG90O1xufVxuXG4vKipcbiAqIEEgcmVjdGFuZ2xlIGFzIHRoZSByZW5kZXJlciByZXBvcnRzIGl0LCBpbiBDU1MgcGl4ZWxzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVsZW1lbnRSZWN0IHtcbiAgLyoqXG4gICAqIFRoZSByZWN0YW5nbGUncyBoZWlnaHQuXG4gICAqL1xuICByZWFkb25seSBoZWlnaHQ6IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGRpc3RhbmNlIGZyb20gdGhlIHZpZXdwb3J0J3MgbGVmdCBlZGdlLlxuICAgKi9cbiAgcmVhZG9ubHkgbGVmdDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgZGlzdGFuY2UgZnJvbSB0aGUgdmlld3BvcnQncyB0b3AgZWRnZS5cbiAgICovXG4gIHJlYWRvbmx5IHRvcDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVjdGFuZ2xlJ3Mgd2lkdGguXG4gICAqL1xuICByZWFkb25seSB3aWR0aDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayByZXNvbHZlU29mdEtleWJvYXJkVGFwUG9pbnRzfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlU29mdEtleWJvYXJkVGFwUG9pbnRzUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBnZW9tZXRyeSB0aGUgdGFwIGlzIGFpbWVkIGZyb20uXG4gICAqL1xuICByZWFkb25seSBzbmFwc2hvdDogU29mdEtleWJvYXJkVmlld3BvcnRTbmFwc2hvdDtcbn1cblxuLyoqXG4gKiBBIHBvaW50IG9uIHRoZSBkZXZpY2UncyBzY3JlZW4sIGluIGRldmljZSBwaXhlbHMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU29mdEtleWJvYXJkVGFwUG9pbnQge1xuICAvKipcbiAgICogVGhlIGRpc3RhbmNlIGZyb20gdGhlIHNjcmVlbidzIGxlZnQgZWRnZS5cbiAgICovXG4gIHJlYWRvbmx5IHhJblBpeGVsczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgZGlzdGFuY2UgZnJvbSB0aGUgc2NyZWVuJ3MgdG9wIGVkZ2UuXG4gICAqL1xuICByZWFkb25seSB5SW5QaXhlbHM6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBXaGF0IHRoZSByZW5kZXJlciBrbm93cyBhYm91dCBpdHMgb3duIGdlb21ldHJ5LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNvZnRLZXlib2FyZFZpZXdwb3J0U25hcHNob3Qge1xuICAvKipcbiAgICogVGhlIHJhdGlvIGJldHdlZW4gQ1NTIHBpeGVscyBhbmQgdGhlIGRldmljZSBwaXhlbHMgYGFkYiBzaGVsbCBpbnB1dCB0YXBgIHNwZWFrcyBpbi5cbiAgICovXG4gIHJlYWRvbmx5IGRldmljZVBpeGVsUmF0aW86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIHZpZXdwb3J0J3MgaGVpZ2h0IGluIENTUyBwaXhlbHMuXG4gICAqXG4gICAqIEtlcHQgZm9yIHRoZSBkaWFnbm9zdGljIGFzIG11Y2ggYXMgdGhlIGRlY2lzaW9uOiBpdCBkb2VzICoqbm90Kiogc2hyaW5rIHdoZW4gdGhlIGtleWJvYXJkIGNvbWVzIHVwLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5uZXJIZWlnaHQ6IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGZpZWxkJ3MgcmVjdCwgd2hpY2ggaXMgd2hhdCBzYXlzIHdoZXRoZXIgdGhlIGtleWJvYXJkIGlzIHVwLCBvciBgbnVsbGAgd2hlbiBpdCBpcyBub3Qgb24gc2NyZWVuLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5wdXRSZWN0OiBFbGVtZW50UmVjdCB8IG51bGw7XG5cbiAgLyoqXG4gICAqIFRoZSB3aW5kb3cncyBvZmZzZXQgZnJvbSB0aGUgdG9wIG9mIHRoZSBzY3JlZW4sIGFzIHRoZSBwYWdlIHVuZGVyc3RhbmRzIGl0LlxuICAgKi9cbiAgcmVhZG9ubHkgc2NyZWVuWTogbnVtYmVyO1xufVxuXG4vKipcbiAqIFRoZSBsZWFzdCBhIHJhaXNlZCBrZXlib2FyZCBsaWZ0cyB0aGUgZmllbGQgYnksIHNvIGEgc3RyYXkgcm91bmRpbmcgcGl4ZWwgaXMgbm90IHJlYWQgYXMgb25lLlxuICpcbiAqIEV4cG9ydGVkIGJlY2F1c2UgaXQgaXMgdGhlIG51bWJlciBib3RoIHtAbGluayBjaGVja0lzU29mdEtleWJvYXJkVXB9IGFuZCBgcmFpc2VTb2Z0S2V5Ym9hcmRgIGRlZmF1bHQgdG8sXG4gKiBhbmQgYSBzdWl0ZSB0aWdodGVuaW5nIGl0IHdhbnRzIHRvIHNheSBzbyByZWxhdGl2ZSB0byB0aGlzIHJhdGhlciB0aGFuIGluIHRoZSBhYnN0cmFjdC5cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfTUlOSU1VTV9LRVlCT0FSRF9IRUlHSFRfSU5fUElYRUxTID0gMTAwO1xuXG4vKipcbiAqIFRoZSBgZHVtcHN5cyBpbnB1dF9tZXRob2RgIGZpZWxkcyB0aGF0IHNheSB3aGV0aGVyIHRoZSBJTUUgaXMgYWN0dWFsbHkgc2hvd2luZy5cbiAqL1xuY29uc3QgSU5QVVRfTUVUSE9EX1NUQVRFX1JFR19FWFAgPSAvbUlucHV0U2hvd258bUlzSW5wdXRWaWV3U2hvd258bUhhdmVDb25uZWN0aW9ufG1TaG93UmVxdWVzdGVkLztcblxuLyoqXG4gKiBIb3cgbWFueSBlcXVhbCBwYXJ0cyB0aGUgZmllbGQgaXMgc3BsaXQgaW50byB0byBmaW5kIGl0cyBjZW50cmUuXG4gKi9cbmNvbnN0IENFTlRFUl9ESVZJU09SID0gMjtcblxuLyoqXG4gKiBCdWlsZHMgdGhlIG1lc3NhZ2UgYSBmYWlsZWQgcmFpc2UgcmVwb3J0cy5cbiAqXG4gKiBBIGJhcmUgXCJ0aGUga2V5Ym9hcmQgZGlkIG5vdCBjb21lIHVwXCIgaXMgdW5yZWFkYWJsZSBcdTIwMTQgd2hhdCB0aGUgcmVhZGVyIG5lZWRzIGlzIHdoYXQgdGhlIHBhZ2Ugc2F3IGFuZCB3aGF0XG4gKiB0aGUgZGV2aWNlIHRob3VnaHQsIHNpZGUgYnkgc2lkZSwgYmVjYXVzZSB0aGUgdHdvIGRpc2FncmVlaW5nIGlzIHRoZSB3aG9sZSBkaWFnbm9zaXMuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBldmlkZW5jZSBnYXRoZXJlZCBhZnRlciB0aGUgbGFzdCB0b3VjaC5cbiAqIEByZXR1cm5zIFRoZSBtZXNzYWdlLCByZWFkeSB0byB0aHJvdy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkU29mdEtleWJvYXJkRGlhZ25vc3RpY01lc3NhZ2UocGFyYW1zOiBCdWlsZFNvZnRLZXlib2FyZERpYWdub3N0aWNNZXNzYWdlUGFyYW1zKTogc3RyaW5nIHtcbiAgY29uc3QgeyBpbnB1dFJlY3QgfSA9IHBhcmFtcy5zbmFwc2hvdDtcbiAgY29uc3QgaW5wdXRCb3R0b20gPSBpbnB1dFJlY3QgPyBpbnB1dFJlY3QudG9wICsgaW5wdXRSZWN0LmhlaWdodCA6IG51bGw7XG5cbiAgcmV0dXJuIFtcbiAgICBgcmFpc2VTb2Z0S2V5Ym9hcmQ6IHRoZSBrZXlib2FyZCBkaWQgbm90IGNvbWUgdXAuIERldmljZSBmcmFtZWJ1ZmZlciB3cml0dGVuIHRvICR7cGFyYW1zLnNjcmVlbnNob3RQYXRofS5gLFxuICAgIGBwYWdlOiBpbm5lckhlaWdodD0ke1N0cmluZyhwYXJhbXMuc25hcHNob3QuaW5uZXJIZWlnaHQpfSBpbnB1dEJvdHRvbT0ke2lucHV0Qm90dG9tID09PSBudWxsID8gJyhubyBpbnB1dCknIDogU3RyaW5nKGlucHV0Qm90dG9tKX1gLFxuICAgIGBkZXZpY2U6ICR7cGFyYW1zLmlucHV0TWV0aG9kU3RhdGUgfHwgJyhubyBpbnB1dF9tZXRob2Qgc3RhdGUgcmVwb3J0ZWQpJ31gXG4gIF0uam9pbignXFxuJyk7XG59XG5cbi8qKlxuICogRGVjaWRlcyB3aGV0aGVyIHRoZSBJTUUgaXMgdXAsIGZyb20gdGhlIHBhZ2UncyBvd24gZ2VvbWV0cnkuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBnZW9tZXRyeSB0byBqdWRnZSwgYW5kIGhvdyBmYXIgdGhlIGZpZWxkIG11c3QgaGF2ZSBsaWZ0ZWQuXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBmaWVsZCBoYXMgc3RvcHBlZCBzaG9ydCBvZiB0aGUgYm90dG9tIHRvIG1ha2Ugcm9vbSBmb3IgYSBrZXlib2FyZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrSXNTb2Z0S2V5Ym9hcmRVcChwYXJhbXM6IENoZWNrSXNTb2Z0S2V5Ym9hcmRVcFBhcmFtcyk6IGJvb2xlYW4ge1xuICBjb25zdCB7IGlucHV0UmVjdCB9ID0gcGFyYW1zLnNuYXBzaG90O1xuICBpZiAoIWlucHV0UmVjdCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IG1pbmltdW1LZXlib2FyZEhlaWdodEluUGl4ZWxzID0gcGFyYW1zLm1pbmltdW1LZXlib2FyZEhlaWdodEluUGl4ZWxzID8/IERFRkFVTFRfTUlOSU1VTV9LRVlCT0FSRF9IRUlHSFRfSU5fUElYRUxTO1xuICByZXR1cm4gcGFyYW1zLnNuYXBzaG90LmlubmVySGVpZ2h0IC0gKGlucHV0UmVjdC50b3AgKyBpbnB1dFJlY3QuaGVpZ2h0KSA+IG1pbmltdW1LZXlib2FyZEhlaWdodEluUGl4ZWxzO1xufVxuXG4vKipcbiAqIFJlZHVjZXMgYGR1bXBzeXMgaW5wdXRfbWV0aG9kYCB0byB0aGUgaGFuZGZ1bCBvZiBmaWVsZHMgdGhhdCBzYXkgd2hldGhlciB0aGUgSU1FIGlzIHNob3dpbmcuXG4gKlxuICogQHBhcmFtIGR1bXBzeXNPdXRwdXQgLSBSYXcgc3Rkb3V0IG9mIGBhZGIgc2hlbGwgZHVtcHN5cyBpbnB1dF9tZXRob2RgLlxuICogQHJldHVybnMgVGhlIGludGVyZXN0aW5nIGZpZWxkcywgdHJpbW1lZCBhbmQgam9pbmVkLCBvciBhbiBlbXB0eSBzdHJpbmcgd2hlbiBub25lIHdlcmUgcmVwb3J0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUlucHV0TWV0aG9kU3RhdGUoZHVtcHN5c091dHB1dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGR1bXBzeXNPdXRwdXRcbiAgICAuc3BsaXQoJ1xcbicpXG4gICAgLmZpbHRlcigobGluZSkgPT4gSU5QVVRfTUVUSE9EX1NUQVRFX1JFR19FWFAudGVzdChsaW5lKSlcbiAgICAubWFwKChsaW5lKSA9PiBsaW5lLnRyaW0oKSlcbiAgICAuam9pbignIHwgJyk7XG59XG5cbi8qKlxuICogV29ya3Mgb3V0IHdoZXJlIHRvIHRvdWNoLCBpbiB0aGUgZGV2aWNlIHBpeGVscyBgYWRiIHNoZWxsIGlucHV0IHRhcGAgc3BlYWtzLlxuICpcbiAqIFR3byBjYW5kaWRhdGVzLCBub3Qgb25lOiB0aGUgV2ViVmlldyBtYXkgb3IgbWF5IG5vdCBzdGFydCBhdCB0aGUgdG9wIG9mIHRoZSBzY3JlZW4sIGFuZCB0aGUgcGFnZSBjYW5ub3RcbiAqIHRlbGwgd2hpY2guIEJvdGggbGFuZCBpbnNpZGUgdGhlIGZpZWxkIFx1MjAxNCBpdCBpcyB0YWxsZXIgdGhhbiB0aGUgb2Zmc2V0IFx1MjAxNCBzbyBhIHdyb25nIGd1ZXNzIGNvc3RzIG9uZSB0b3VjaFxuICogcmF0aGVyIHRoYW4gYSBtaXMtdGFwIG9uIHdoYXRldmVyIHNpdHMgYmVsb3cuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBnZW9tZXRyeSB0aGUgdGFwIGlzIGFpbWVkIGZyb20uXG4gKiBAcmV0dXJucyBUaGUgcG9pbnRzIHRvIHRyeSwgaW4gb3JkZXIsIG9yIGFuIGVtcHR5IGFycmF5IHdoZW4gdGhlIGZpZWxkIGlzIG5vdCBvbiBzY3JlZW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlU29mdEtleWJvYXJkVGFwUG9pbnRzKHBhcmFtczogUmVzb2x2ZVNvZnRLZXlib2FyZFRhcFBvaW50c1BhcmFtcyk6IFNvZnRLZXlib2FyZFRhcFBvaW50W10ge1xuICBjb25zdCB7IGRldmljZVBpeGVsUmF0aW8sIGlucHV0UmVjdCwgc2NyZWVuWSB9ID0gcGFyYW1zLnNuYXBzaG90O1xuICBpZiAoIWlucHV0UmVjdCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHhJblBpeGVscyA9IE1hdGgucm91bmQoKGlucHV0UmVjdC5sZWZ0ICsgaW5wdXRSZWN0LndpZHRoIC8gQ0VOVEVSX0RJVklTT1IpICogZGV2aWNlUGl4ZWxSYXRpbyk7XG4gIGNvbnN0IGNlbnRlcllJblBpeGVscyA9IE1hdGgucm91bmQoKGlucHV0UmVjdC50b3AgKyBpbnB1dFJlY3QuaGVpZ2h0IC8gQ0VOVEVSX0RJVklTT1IpICogZGV2aWNlUGl4ZWxSYXRpbyk7XG4gIGNvbnN0IHRvcE9mZnNldEluUGl4ZWxzID0gTWF0aC5yb3VuZChzY3JlZW5ZICogZGV2aWNlUGl4ZWxSYXRpbyk7XG5cbiAgaWYgKHRvcE9mZnNldEluUGl4ZWxzID09PSAwKSB7XG4gICAgcmV0dXJuIFt7IHhJblBpeGVscywgeUluUGl4ZWxzOiBjZW50ZXJZSW5QaXhlbHMgfV07XG4gIH1cblxuICByZXR1cm4gW1xuICAgIHsgeEluUGl4ZWxzLCB5SW5QaXhlbHM6IGNlbnRlcllJblBpeGVscyArIHRvcE9mZnNldEluUGl4ZWxzIH0sXG4gICAgeyB4SW5QaXhlbHMsIHlJblBpeGVsczogY2VudGVyWUluUGl4ZWxzIH1cbiAgXTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQXlJTyxNQUFNLDRDQUE0QztBQUt6RCxNQUFNLDZCQUE2QjtBQUtuQyxNQUFNLGlCQUFpQjtBQVdoQixTQUFTLG1DQUFtQyxRQUEwRDtBQUMzRyxRQUFNLEVBQUUsVUFBVSxJQUFJLE9BQU87QUFDN0IsUUFBTSxjQUFjLFlBQVksVUFBVSxNQUFNLFVBQVUsU0FBUztBQUVuRSxTQUFPO0FBQUEsSUFDTCxrRkFBa0YsT0FBTyxjQUFjO0FBQUEsSUFDdkcscUJBQXFCLE9BQU8sT0FBTyxTQUFTLFdBQVcsQ0FBQyxnQkFBZ0IsZ0JBQWdCLE9BQU8sZUFBZSxPQUFPLFdBQVcsQ0FBQztBQUFBLElBQ2pJLFdBQVcsT0FBTyxvQkFBb0Isa0NBQWtDO0FBQUEsRUFDMUUsRUFBRSxLQUFLLElBQUk7QUFDYjtBQVFPLFNBQVMsc0JBQXNCLFFBQThDO0FBQ2xGLFFBQU0sRUFBRSxVQUFVLElBQUksT0FBTztBQUM3QixNQUFJLENBQUMsV0FBVztBQUNkLFdBQU87QUFBQSxFQUNUO0FBRUEsUUFBTSxnQ0FBZ0MsT0FBTyxpQ0FBaUM7QUFDOUUsU0FBTyxPQUFPLFNBQVMsZUFBZSxVQUFVLE1BQU0sVUFBVSxVQUFVO0FBQzVFO0FBUU8sU0FBUyxzQkFBc0IsZUFBK0I7QUFDbkUsU0FBTyxjQUNKLE1BQU0sSUFBSSxFQUNWLE9BQU8sQ0FBQyxTQUFTLDJCQUEyQixLQUFLLElBQUksQ0FBQyxFQUN0RCxJQUFJLENBQUMsU0FBUyxLQUFLLEtBQUssQ0FBQyxFQUN6QixLQUFLLEtBQUs7QUFDZjtBQVlPLFNBQVMsNkJBQTZCLFFBQW9FO0FBQy9HLFFBQU0sRUFBRSxrQkFBa0IsV0FBVyxRQUFRLElBQUksT0FBTztBQUN4RCxNQUFJLENBQUMsV0FBVztBQUNkLFdBQU8sQ0FBQztBQUFBLEVBQ1Y7QUFFQSxRQUFNLFlBQVksS0FBSyxPQUFPLFVBQVUsT0FBTyxVQUFVLFFBQVEsa0JBQWtCLGdCQUFnQjtBQUNuRyxRQUFNLGtCQUFrQixLQUFLLE9BQU8sVUFBVSxNQUFNLFVBQVUsU0FBUyxrQkFBa0IsZ0JBQWdCO0FBQ3pHLFFBQU0sb0JBQW9CLEtBQUssTUFBTSxVQUFVLGdCQUFnQjtBQUUvRCxNQUFJLHNCQUFzQixHQUFHO0FBQzNCLFdBQU8sQ0FBQyxFQUFFLFdBQVcsV0FBVyxnQkFBZ0IsQ0FBQztBQUFBLEVBQ25EO0FBRUEsU0FBTztBQUFBLElBQ0wsRUFBRSxXQUFXLFdBQVcsa0JBQWtCLGtCQUFrQjtBQUFBLElBQzVELEVBQUUsV0FBVyxXQUFXLGdCQUFnQjtBQUFBLEVBQzFDO0FBQ0Y7IiwKICAibmFtZXMiOiBbXQp9Cg==
84
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3NvZnQta2V5Ym9hcmQtZ2VvbWV0cnkudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBEZWNpZGVzIHdoZXRoZXIgdGhlIEFuZHJvaWQgc29mdCBrZXlib2FyZCBpcyB1cCwgYW5kIHdoZXJlIHRvIHRvdWNoIHRvIHJhaXNlXG4gKiBpdCBcdTIwMTQgZnJvbSBnZW9tZXRyeSBhbG9uZS5cbiAqXG4gKiAqKk5vdGhpbmcgaW4gdGhlIHBhZ2UgcmVwb3J0cyB0aGUga2V5Ym9hcmQuKiogYGlubmVySGVpZ2h0YCwgYHZpc3VhbFZpZXdwb3J0YFxuICogYW5kIHRoZSBtb2RhbCBjb250YWluZXIgYWxsIHN0YXkgYXQgdGhlaXIgZnVsbCBoZWlnaHQgd2l0aCB0aGUga2V5Ym9hcmQgc2hvd25cbiAqIGFuZCBgZHVtcHN5cyBpbnB1dF9tZXRob2RgIHJlcG9ydGluZyBgbUlucHV0U2hvd249dHJ1ZWAgXHUyMDE0IE9ic2lkaWFuIE1vYmlsZSBrZWVwc1xuICogYSBmdWxsLXNjcmVlbiBjb250YWluZXIgYW5kIGxpZnRzIGl0cyBjb250ZW50cyBpbnNpZGUgaXQuIFRoZSBvbmx5IHNpZ25hbCBpc1xuICogdGhhdCB0aGUgZmllbGQgKm1vdmVzKiwgd2hpY2ggaXMgd2h5IHRoZSBkZXRlY3Rpb24gaGVyZSBpcyBnZW9tZXRyaWMgcmF0aGVyXG4gKiB0aGFuIGFuIEFQSSBjYWxsLiBUd28gcnVucyBmYWlsZWQgb24gdGhhdCBiZWZvcmUgYSBmcmFtZWJ1ZmZlciBkdW1wIHNhaWQgc28sXG4gKiB3aGljaCBpcyBhbHNvIHdoeSB0aGUgZGlhZ25vc3RpYyBiZWxvdyBleGlzdHMuXG4gKlxuICogKipUaGUgc2lnbmFsIGlzIGEgREVMVEEgYWdhaW5zdCBhIGJhc2VsaW5lIHJlYWQgYmVmb3JlIHRoZSB0b3VjaCwgbm90IHRoZVxuICogZmllbGQncyBhYnNvbHV0ZSBvZmZzZXQgZnJvbSB0aGUgYm90dG9tLioqIFRoZSBhYnNvbHV0ZSBvZmZzZXQgd2FzIHRoZSBvcmlnaW5hbFxuICogdGVzdCBhbmQgaXQgaXMgcmlnaHQgb25seSBmb3IgYSAqKmJvdHRvbS1hbmNob3JlZCoqIGZpZWxkIFx1MjAxNCBhIHN1Z2dlc3RlciwgYVxuICogY29tbWFuZCBwYWxldHRlIFx1MjAxNCB3aGVyZSBcImNsZWFyIG9mIHRoZSBib3R0b21cIiBhbmQgXCJsaWZ0ZWRcIiBhcmUgdGhlIHNhbWVcbiAqIHNlbnRlbmNlLiBGb3IgYSAqKmNlbnRyZWQgbW9kYWwqKiB0aGUgY29uZGl0aW9uIGlzIGFscmVhZHkgdHJ1ZSB3aXRoIG5vXG4gKiBrZXlib2FyZCBhdCBhbGwsIHNvIHRoZSB0ZXN0IHBhc3NlZCB2YWN1b3VzbHkgYW5kIGByYWlzZVNvZnRLZXlib2FyZGAgcmV0dXJuZWRcbiAqIHN1Y2Nlc3MgaGF2aW5nIGRpc3BhdGNoZWQgbm8gdG91Y2ggKG1lYXN1cmVkIDIwMjYtMDktMTIgYWdhaW5zdCBhIGNlbnRyZWRcbiAqIHByb21wdCBtb2RhbDogdGhlIGZpZWxkJ3MgYHRvcGAgcmVhZCBgMzUyLjQ0NTMxMjVgIGJlZm9yZSBhbmQgYWZ0ZXIgcmVhbCB0YXBzXG4gKiBhbmQgdGhlIGNoZWNrIHNhaWQgdGhlIGtleWJvYXJkIHdhcyB1cCBib3RoIHRpbWVzKS4gQSBkZWx0YSBpcyB0aGUgc2FtZSBwdWJsaWNcbiAqIEFQSSBmb3IgYm90aCBzaGFwZXMsIGFuZCBpdCBjb3N0cyBhIGZpZWxkIHRoYXQgY2Fubm90IG1vdmUgaXRzIHZlcmRpY3QgXHUyMDE0IHNlZVxuICoge0BsaW5rIGNoZWNrSXNTb2Z0S2V5Ym9hcmRVcH0gZm9yIHRoZSBvbmUgY2FzZSB0aGF0IHRyYWRlcyBhd2F5LlxuICpcbiAqIFB1cmUgYW5kIHVuaXQtdGVzdGVkOyB0aGUgdG91Y2hpbmcgYW5kIHRoZSBjYXB0dXJlIGxpdmUgaW4gYHNvZnQta2V5Ym9hcmRgLlxuICovXG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGJ1aWxkU29mdEtleWJvYXJkRGlhZ25vc3RpY01lc3NhZ2V9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkU29mdEtleWJvYXJkRGlhZ25vc3RpY01lc3NhZ2VQYXJhbXMge1xuICAvKipcbiAgICogVGhlIGdlb21ldHJ5IHJlYWQgYmVmb3JlIHRoZSBmaXJzdCB0b3VjaCwgd2hpY2ggaXMgd2hhdCB0aGUgdmVyZGljdCBpcyBtZWFzdXJlZCBhZ2FpbnN0LlxuICAgKi9cbiAgcmVhZG9ubHkgYmFzZWxpbmVTbmFwc2hvdDogU29mdEtleWJvYXJkVmlld3BvcnRTbmFwc2hvdDtcblxuICAvKipcbiAgICogVGhlIGxpbmVzIG9mIGBkdW1wc3lzIGlucHV0X21ldGhvZGAgd29ydGggcmVhZGluZywgYXMge0BsaW5rIHBhcnNlSW5wdXRNZXRob2RTdGF0ZX0gcmV0dXJuZWQgdGhlbS5cbiAgICovXG4gIHJlYWRvbmx5IGlucHV0TWV0aG9kU3RhdGU6IHN0cmluZztcblxuICAvKipcbiAgICogV2hlcmUgdGhlIGRldmljZSBmcmFtZWJ1ZmZlciB3YXMgd3JpdHRlbiwgc28gdGhlIHJlYWRlciBjYW4gbG9vayBhdCB3aGF0IHRoZSBkZXZpY2Ugd2FzIHNob3dpbmcuXG4gICAqL1xuICByZWFkb25seSBzY3JlZW5zaG90UGF0aDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZ2VvbWV0cnkgcmVhZCBhZnRlciB0aGUgbGFzdCB0b3VjaC5cbiAgICovXG4gIHJlYWRvbmx5IHNuYXBzaG90OiBTb2Z0S2V5Ym9hcmRWaWV3cG9ydFNuYXBzaG90O1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBjaGVja0lzU29mdEtleWJvYXJkVXB9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENoZWNrSXNTb2Z0S2V5Ym9hcmRVcFBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgZ2VvbWV0cnkgcmVhZCAqKmJlZm9yZSoqIHRoZSBmaXJzdCB0b3VjaCwgd2l0aCB0aGUga2V5Ym9hcmQgc3RpbGwgZG93bi5cbiAgICpcbiAgICogUmVxdWlyZWQsIGFuZCBkZWxpYmVyYXRlbHkgbm90IG9wdGlvbmFsOiBhbiBhYnNlbnQgYmFzZWxpbmUgY291bGQgb25seSBtZWFuIGZhbGxpbmcgYmFjayB0byB0aGVcbiAgICogYWJzb2x1dGUtb2Zmc2V0IHRlc3QsIHdoaWNoIGlzIHRoZSB2YWN1b3VzIHBhc3MgdGhpcyBwYXJhbWV0ZXIgZXhpc3RzIHRvIG1ha2UgdW5yZXByZXNlbnRhYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgYmFzZWxpbmVTbmFwc2hvdDogU29mdEtleWJvYXJkVmlld3BvcnRTbmFwc2hvdDtcblxuICAvKipcbiAgICogVGhlIGxlYXN0IGEgcmFpc2VkIGtleWJvYXJkIGxpZnRzIHRoZSBmaWVsZCBieSwgc28gYSBzdHJheSByb3VuZGluZyBwaXhlbCBpcyBub3QgcmVhZCBhcyBvbmUuXG4gICAqXG4gICAqIEBkZWZhdWx0IHtAbGluayBERUZBVUxUX01JTklNVU1fS0VZQk9BUkRfSEVJR0hUX0lOX1BJWEVMU31cbiAgICovXG4gIHJlYWRvbmx5IG1pbmltdW1LZXlib2FyZEhlaWdodEluUGl4ZWxzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgZ2VvbWV0cnkgdG8ganVkZ2UsIHJlYWQgYWZ0ZXIgdGhlIHRvdWNoLlxuICAgKi9cbiAgcmVhZG9ubHkgc25hcHNob3Q6IFNvZnRLZXlib2FyZFZpZXdwb3J0U25hcHNob3Q7XG59XG5cbi8qKlxuICogQSByZWN0YW5nbGUgYXMgdGhlIHJlbmRlcmVyIHJlcG9ydHMgaXQsIGluIENTUyBwaXhlbHMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRWxlbWVudFJlY3Qge1xuICAvKipcbiAgICogVGhlIHJlY3RhbmdsZSdzIGhlaWdodC5cbiAgICovXG4gIHJlYWRvbmx5IGhlaWdodDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgZGlzdGFuY2UgZnJvbSB0aGUgdmlld3BvcnQncyBsZWZ0IGVkZ2UuXG4gICAqL1xuICByZWFkb25seSBsZWZ0OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBkaXN0YW5jZSBmcm9tIHRoZSB2aWV3cG9ydCdzIHRvcCBlZGdlLlxuICAgKi9cbiAgcmVhZG9ubHkgdG9wOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSByZWN0YW5nbGUncyB3aWR0aC5cbiAgICovXG4gIHJlYWRvbmx5IHdpZHRoOiBudW1iZXI7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIHJlc29sdmVTb2Z0S2V5Ym9hcmRUYXBQb2ludHN9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVTb2Z0S2V5Ym9hcmRUYXBQb2ludHNQYXJhbXMge1xuICAvKipcbiAgICogVGhlIGdlb21ldHJ5IHRoZSB0YXAgaXMgYWltZWQgZnJvbS5cbiAgICovXG4gIHJlYWRvbmx5IHNuYXBzaG90OiBTb2Z0S2V5Ym9hcmRWaWV3cG9ydFNuYXBzaG90O1xufVxuXG4vKipcbiAqIEEgcG9pbnQgb24gdGhlIGRldmljZSdzIHNjcmVlbiwgaW4gZGV2aWNlIHBpeGVscy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTb2Z0S2V5Ym9hcmRUYXBQb2ludCB7XG4gIC8qKlxuICAgKiBUaGUgZGlzdGFuY2UgZnJvbSB0aGUgc2NyZWVuJ3MgbGVmdCBlZGdlLlxuICAgKi9cbiAgcmVhZG9ubHkgeEluUGl4ZWxzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBkaXN0YW5jZSBmcm9tIHRoZSBzY3JlZW4ncyB0b3AgZWRnZS5cbiAgICovXG4gIHJlYWRvbmx5IHlJblBpeGVsczogbnVtYmVyO1xufVxuXG4vKipcbiAqIFdoYXQgdGhlIHJlbmRlcmVyIGtub3dzIGFib3V0IGl0cyBvd24gZ2VvbWV0cnkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU29mdEtleWJvYXJkVmlld3BvcnRTbmFwc2hvdCB7XG4gIC8qKlxuICAgKiBUaGUgcmF0aW8gYmV0d2VlbiBDU1MgcGl4ZWxzIGFuZCB0aGUgZGV2aWNlIHBpeGVscyBgYWRiIHNoZWxsIGlucHV0IHRhcGAgc3BlYWtzIGluLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlUGl4ZWxSYXRpbzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgdmlld3BvcnQncyBoZWlnaHQgaW4gQ1NTIHBpeGVscy5cbiAgICpcbiAgICogS2VwdCBmb3IgdGhlIGRpYWdub3N0aWMgYXMgbXVjaCBhcyB0aGUgZGVjaXNpb246IGl0IGRvZXMgKipub3QqKiBzaHJpbmsgd2hlbiB0aGUga2V5Ym9hcmQgY29tZXMgdXAuXG4gICAqL1xuICByZWFkb25seSBpbm5lckhlaWdodDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgZmllbGQncyByZWN0LCB3aGljaCBpcyB3aGF0IHNheXMgd2hldGhlciB0aGUga2V5Ym9hcmQgaXMgdXAsIG9yIGBudWxsYCB3aGVuIGl0IGlzIG5vdCBvbiBzY3JlZW4uXG4gICAqL1xuICByZWFkb25seSBpbnB1dFJlY3Q6IEVsZW1lbnRSZWN0IHwgbnVsbDtcblxuICAvKipcbiAgICogVGhlIHdpbmRvdydzIG9mZnNldCBmcm9tIHRoZSB0b3Agb2YgdGhlIHNjcmVlbiwgYXMgdGhlIHBhZ2UgdW5kZXJzdGFuZHMgaXQuXG4gICAqL1xuICByZWFkb25seSBzY3JlZW5ZOiBudW1iZXI7XG59XG5cbi8qKlxuICogVGhlIGxlYXN0IGEgcmFpc2VkIGtleWJvYXJkIGxpZnRzIHRoZSBmaWVsZCBieSwgc28gYSBzdHJheSByb3VuZGluZyBwaXhlbCBpcyBub3QgcmVhZCBhcyBvbmUuXG4gKlxuICogRXhwb3J0ZWQgYmVjYXVzZSBpdCBpcyB0aGUgbnVtYmVyIGJvdGgge0BsaW5rIGNoZWNrSXNTb2Z0S2V5Ym9hcmRVcH0gYW5kIGByYWlzZVNvZnRLZXlib2FyZGAgZGVmYXVsdCB0byxcbiAqIGFuZCBhIHN1aXRlIHRpZ2h0ZW5pbmcgaXQgd2FudHMgdG8gc2F5IHNvIHJlbGF0aXZlIHRvIHRoaXMgcmF0aGVyIHRoYW4gaW4gdGhlIGFic3RyYWN0LlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9NSU5JTVVNX0tFWUJPQVJEX0hFSUdIVF9JTl9QSVhFTFMgPSAxMDA7XG5cbi8qKlxuICogVGhlIGBkdW1wc3lzIGlucHV0X21ldGhvZGAgZmllbGRzIHRoYXQgc2F5IHdoZXRoZXIgdGhlIElNRSBpcyBhY3R1YWxseSBzaG93aW5nLlxuICovXG5jb25zdCBJTlBVVF9NRVRIT0RfU1RBVEVfUkVHX0VYUCA9IC9tSW5wdXRTaG93bnxtSXNJbnB1dFZpZXdTaG93bnxtSGF2ZUNvbm5lY3Rpb258bVNob3dSZXF1ZXN0ZWQvO1xuXG4vKipcbiAqIEhvdyBtYW55IGVxdWFsIHBhcnRzIHRoZSBmaWVsZCBpcyBzcGxpdCBpbnRvIHRvIGZpbmQgaXRzIGNlbnRyZS5cbiAqL1xuY29uc3QgQ0VOVEVSX0RJVklTT1IgPSAyO1xuXG4vKipcbiAqIEJ1aWxkcyB0aGUgbWVzc2FnZSBhIGZhaWxlZCByYWlzZSByZXBvcnRzLlxuICpcbiAqIEEgYmFyZSBcInRoZSBrZXlib2FyZCBkaWQgbm90IGNvbWUgdXBcIiBpcyB1bnJlYWRhYmxlIFx1MjAxNCB3aGF0IHRoZSByZWFkZXIgbmVlZHMgaXMgd2hhdCB0aGUgcGFnZSBzYXcgYW5kIHdoYXRcbiAqIHRoZSBkZXZpY2UgdGhvdWdodCwgc2lkZSBieSBzaWRlLCBiZWNhdXNlIHRoZSB0d28gZGlzYWdyZWVpbmcgaXMgdGhlIHdob2xlIGRpYWdub3Npcy4gVGhlIHBhZ2UncyBoYWxmIGlzXG4gKiB0aGUgbGlmdCBhbmQgdGhlIHR3byB0b3BzIGl0IGNhbWUgZnJvbSwgc2luY2UgdGhlIGxpZnQgaXMgdGhlIHZlcmRpY3Q7IGEgbGlmdCBvZiB6ZXJvIGdldHMgYSBzZW50ZW5jZSBvZlxuICogaXRzIG93biwgYmVpbmcgdGhlIG9uZSByZWFkaW5nIHRoYXQgYW4gYWxyZWFkeS11cCBrZXlib2FyZCBhbHNvIHByb2R1Y2VzLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZXZpZGVuY2UgZ2F0aGVyZWQgYmVmb3JlIHRoZSBmaXJzdCB0b3VjaCBhbmQgYWZ0ZXIgdGhlIGxhc3Qgb25lLlxuICogQHJldHVybnMgVGhlIG1lc3NhZ2UsIHJlYWR5IHRvIHRocm93LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRTb2Z0S2V5Ym9hcmREaWFnbm9zdGljTWVzc2FnZShwYXJhbXM6IEJ1aWxkU29mdEtleWJvYXJkRGlhZ25vc3RpY01lc3NhZ2VQYXJhbXMpOiBzdHJpbmcge1xuICBjb25zdCBiYXNlbGluZVRvcCA9IHBhcmFtcy5iYXNlbGluZVNuYXBzaG90LmlucHV0UmVjdD8udG9wID8/IG51bGw7XG4gIGNvbnN0IGN1cnJlbnRUb3AgPSBwYXJhbXMuc25hcHNob3QuaW5wdXRSZWN0Py50b3AgPz8gbnVsbDtcbiAgY29uc3QgbGlmdCA9IGJhc2VsaW5lVG9wID09PSBudWxsIHx8IGN1cnJlbnRUb3AgPT09IG51bGwgPyBudWxsIDogYmFzZWxpbmVUb3AgLSBjdXJyZW50VG9wO1xuXG4gIGNvbnN0IGxpbmVzID0gW1xuICAgIGByYWlzZVNvZnRLZXlib2FyZDogdGhlIGtleWJvYXJkIGRpZCBub3QgY29tZSB1cC4gRGV2aWNlIGZyYW1lYnVmZmVyIHdyaXR0ZW4gdG8gJHtwYXJhbXMuc2NyZWVuc2hvdFBhdGh9LmAsXG4gICAgYHBhZ2U6IGlubmVySGVpZ2h0PSR7U3RyaW5nKHBhcmFtcy5zbmFwc2hvdC5pbm5lckhlaWdodCl9IGJhc2VsaW5lSW5wdXRUb3A9JHtmb3JtYXRNZWFzdXJlbWVudChiYXNlbGluZVRvcCl9IGlucHV0VG9wPSR7Zm9ybWF0TWVhc3VyZW1lbnQoY3VycmVudFRvcCl9IGxpZnQ9JHtmb3JtYXRNZWFzdXJlbWVudChsaWZ0KX1gLFxuICAgIGBkZXZpY2U6ICR7cGFyYW1zLmlucHV0TWV0aG9kU3RhdGUgfHwgJyhubyBpbnB1dF9tZXRob2Qgc3RhdGUgcmVwb3J0ZWQpJ31gXG4gIF07XG5cbiAgaWYgKGxpZnQgPT09IDApIHtcbiAgICBsaW5lcy5wdXNoKCdUaGUgZmllbGQgZGlkIG5vdCBtb3ZlIGF0IGFsbC4gSWYgdGhlIGRldmljZSBzYXlzIHRoZSBrZXlib2FyZCBpcyBzaG93aW5nLCBpdCB3YXMgYWxyZWFkeSB1cCBiZWZvcmUgdGhlIGZpcnN0IHRvdWNoIFx1MjAxNCB0aGlzIGNoZWNrIGNhbm5vdCB0ZWxsIHRoYXQgZnJvbSBhIGZpZWxkIHRoYXQgbmV2ZXIgbGlmdHMuJyk7XG4gIH1cblxuICByZXR1cm4gbGluZXMuam9pbignXFxuJyk7XG59XG5cbi8qKlxuICogRGVjaWRlcyB3aGV0aGVyIHRoZSBJTUUgaXMgdXAsIGZyb20gaG93IGZhciB0aGUgZmllbGQgbW92ZWQuXG4gKlxuICogVGhlIHZlcmRpY3QgaXMgYSAqKmRlbHRhKio6IHRoZSBmaWVsZCBtdXN0IGhhdmUgcmlzZW4gZnJvbSB3aGVyZSBpdCBzYXQgYmVmb3JlIHRoZSB0b3VjaCwgYnkgYXQgbGVhc3RcbiAqIGBtaW5pbXVtS2V5Ym9hcmRIZWlnaHRJblBpeGVsc2AuIE9ic2lkaWFuIE1vYmlsZSBsaWZ0cyB3aGF0ZXZlciBpcyBvbiBzY3JlZW4gdG8gbWFrZSByb29tIGZvciB0aGUgSU1FLFxuICogc28gYSBmaWVsZCB0aGF0IGhhcyBub3QgbW92ZWQgaGFzIGhhZCBubyBrZXlib2FyZCBhcnJpdmUgdW5kZXIgaXQgXHUyMDE0IHdoZXRoZXIgaXQgaXMgYSBib3R0b20tYW5jaG9yZWRcbiAqIHN1Z2dlc3RlciBvciBhIGNlbnRyZWQgbW9kYWwuXG4gKlxuICogKipUaGUgb25lIGNhc2UgdGhpcyBnZXRzIHdyb25nLCBkZWxpYmVyYXRlbHk6KiogYSBrZXlib2FyZCB0aGF0IHdhcyAqYWxyZWFkeSogdXAgYmVmb3JlIHRoZSBiYXNlbGluZSB3YXNcbiAqIHJlYWQuIFRoZSBmaWVsZCBoYXMgbm93aGVyZSBsZWZ0IHRvIGxpZnQgdG8sIHNvIHRoZSBhbnN3ZXIgaXMgYGZhbHNlYC4gTm8gYW1vdW50IG9mIGdlb21ldHJ5IHNlcGFyYXRlc1xuICogdGhhdCBmcm9tIGEgY2VudHJlZCBtb2RhbCB3aXRoIG5vIGtleWJvYXJkIFx1MjAxNCBib3RoIHJlYWQgYXMgXCJjbGVhciBvZiB0aGUgYm90dG9tIGFuZCBub3QgbW92aW5nXCIgXHUyMDE0IGFuZCBvZlxuICogdGhlIHR3byBwb3NzaWJsZSB3cm9uZyBhbnN3ZXJzLCBhIGxvdWQgYGZhbHNlYCBpcyB0aGUgb25lIHdvcnRoIGtlZXBpbmc6IGl0IGZhaWxzIGEgY2FwdHVyZSByYXRoZXIgdGhhblxuICogc2lsZW50bHkgcmV0dXJuaW5nIGEgc2NyZWVuc2hvdCBvZiBhIGtleWJvYXJkIHRoYXQgaXMgbm90IHRoZXJlLiBSZWFkIHRoZSBiYXNlbGluZSB3aXRoIHRoZSBrZXlib2FyZFxuICogZG93biwgd2hpY2ggaXMgd2hhdCBgcmFpc2VTb2Z0S2V5Ym9hcmRgIGRvZXMuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBnZW9tZXRyeSBiZWZvcmUgYW5kIGFmdGVyIHRoZSB0b3VjaCwgYW5kIGhvdyBmYXIgdGhlIGZpZWxkIG11c3QgaGF2ZSBsaWZ0ZWQuXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBmaWVsZCBsaWZ0ZWQgZmFyIGVub3VnaCB0byBoYXZlIG1hZGUgcm9vbSBmb3IgYSBrZXlib2FyZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrSXNTb2Z0S2V5Ym9hcmRVcChwYXJhbXM6IENoZWNrSXNTb2Z0S2V5Ym9hcmRVcFBhcmFtcyk6IGJvb2xlYW4ge1xuICBjb25zdCBiYXNlbGluZVJlY3QgPSBwYXJhbXMuYmFzZWxpbmVTbmFwc2hvdC5pbnB1dFJlY3Q7XG4gIGNvbnN0IHsgaW5wdXRSZWN0IH0gPSBwYXJhbXMuc25hcHNob3Q7XG4gIGlmICghYmFzZWxpbmVSZWN0IHx8ICFpbnB1dFJlY3QpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBtaW5pbXVtS2V5Ym9hcmRIZWlnaHRJblBpeGVscyA9IHBhcmFtcy5taW5pbXVtS2V5Ym9hcmRIZWlnaHRJblBpeGVscyA/PyBERUZBVUxUX01JTklNVU1fS0VZQk9BUkRfSEVJR0hUX0lOX1BJWEVMUztcbiAgcmV0dXJuIGJhc2VsaW5lUmVjdC50b3AgLSBpbnB1dFJlY3QudG9wID4gbWluaW11bUtleWJvYXJkSGVpZ2h0SW5QaXhlbHM7XG59XG5cbi8qKlxuICogUmVkdWNlcyBgZHVtcHN5cyBpbnB1dF9tZXRob2RgIHRvIHRoZSBoYW5kZnVsIG9mIGZpZWxkcyB0aGF0IHNheSB3aGV0aGVyIHRoZSBJTUUgaXMgc2hvd2luZy5cbiAqXG4gKiBAcGFyYW0gZHVtcHN5c091dHB1dCAtIFJhdyBzdGRvdXQgb2YgYGFkYiBzaGVsbCBkdW1wc3lzIGlucHV0X21ldGhvZGAuXG4gKiBAcmV0dXJucyBUaGUgaW50ZXJlc3RpbmcgZmllbGRzLCB0cmltbWVkIGFuZCBqb2luZWQsIG9yIGFuIGVtcHR5IHN0cmluZyB3aGVuIG5vbmUgd2VyZSByZXBvcnRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlSW5wdXRNZXRob2RTdGF0ZShkdW1wc3lzT3V0cHV0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gZHVtcHN5c091dHB1dFxuICAgIC5zcGxpdCgnXFxuJylcbiAgICAuZmlsdGVyKChsaW5lKSA9PiBJTlBVVF9NRVRIT0RfU1RBVEVfUkVHX0VYUC50ZXN0KGxpbmUpKVxuICAgIC5tYXAoKGxpbmUpID0+IGxpbmUudHJpbSgpKVxuICAgIC5qb2luKCcgfCAnKTtcbn1cblxuLyoqXG4gKiBXb3JrcyBvdXQgd2hlcmUgdG8gdG91Y2gsIGluIHRoZSBkZXZpY2UgcGl4ZWxzIGBhZGIgc2hlbGwgaW5wdXQgdGFwYCBzcGVha3MuXG4gKlxuICogVHdvIGNhbmRpZGF0ZXMsIG5vdCBvbmU6IHRoZSBXZWJWaWV3IG1heSBvciBtYXkgbm90IHN0YXJ0IGF0IHRoZSB0b3Agb2YgdGhlIHNjcmVlbiwgYW5kIHRoZSBwYWdlIGNhbm5vdFxuICogdGVsbCB3aGljaC4gQm90aCBsYW5kIGluc2lkZSB0aGUgZmllbGQgXHUyMDE0IGl0IGlzIHRhbGxlciB0aGFuIHRoZSBvZmZzZXQgXHUyMDE0IHNvIGEgd3JvbmcgZ3Vlc3MgY29zdHMgb25lIHRvdWNoXG4gKiByYXRoZXIgdGhhbiBhIG1pcy10YXAgb24gd2hhdGV2ZXIgc2l0cyBiZWxvdy5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGdlb21ldHJ5IHRoZSB0YXAgaXMgYWltZWQgZnJvbS5cbiAqIEByZXR1cm5zIFRoZSBwb2ludHMgdG8gdHJ5LCBpbiBvcmRlciwgb3IgYW4gZW1wdHkgYXJyYXkgd2hlbiB0aGUgZmllbGQgaXMgbm90IG9uIHNjcmVlbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVTb2Z0S2V5Ym9hcmRUYXBQb2ludHMocGFyYW1zOiBSZXNvbHZlU29mdEtleWJvYXJkVGFwUG9pbnRzUGFyYW1zKTogU29mdEtleWJvYXJkVGFwUG9pbnRbXSB7XG4gIGNvbnN0IHsgZGV2aWNlUGl4ZWxSYXRpbywgaW5wdXRSZWN0LCBzY3JlZW5ZIH0gPSBwYXJhbXMuc25hcHNob3Q7XG4gIGlmICghaW5wdXRSZWN0KSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgY29uc3QgeEluUGl4ZWxzID0gTWF0aC5yb3VuZCgoaW5wdXRSZWN0LmxlZnQgKyBpbnB1dFJlY3Qud2lkdGggLyBDRU5URVJfRElWSVNPUikgKiBkZXZpY2VQaXhlbFJhdGlvKTtcbiAgY29uc3QgY2VudGVyWUluUGl4ZWxzID0gTWF0aC5yb3VuZCgoaW5wdXRSZWN0LnRvcCArIGlucHV0UmVjdC5oZWlnaHQgLyBDRU5URVJfRElWSVNPUikgKiBkZXZpY2VQaXhlbFJhdGlvKTtcbiAgY29uc3QgdG9wT2Zmc2V0SW5QaXhlbHMgPSBNYXRoLnJvdW5kKHNjcmVlblkgKiBkZXZpY2VQaXhlbFJhdGlvKTtcblxuICBpZiAodG9wT2Zmc2V0SW5QaXhlbHMgPT09IDApIHtcbiAgICByZXR1cm4gW3sgeEluUGl4ZWxzLCB5SW5QaXhlbHM6IGNlbnRlcllJblBpeGVscyB9XTtcbiAgfVxuXG4gIHJldHVybiBbXG4gICAgeyB4SW5QaXhlbHMsIHlJblBpeGVsczogY2VudGVyWUluUGl4ZWxzICsgdG9wT2Zmc2V0SW5QaXhlbHMgfSxcbiAgICB7IHhJblBpeGVscywgeUluUGl4ZWxzOiBjZW50ZXJZSW5QaXhlbHMgfVxuICBdO1xufVxuXG4vKipcbiAqIEZvcm1hdHMgYSBtZWFzdXJlbWVudCBmb3IgdGhlIGRpYWdub3N0aWMsIHNheWluZyBzbyByYXRoZXIgdGhhbiBwcmludGluZyBhIG51bWJlciB3aGVuIHRoZXJlIHdhcyBub25lLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBtZWFzdXJlbWVudCwgb3IgYG51bGxgIHdoZW4gdGhlIGZpZWxkIHdhcyBub3Qgb24gc2NyZWVuIHRvIG1lYXN1cmUuXG4gKiBAcmV0dXJucyBUaGUgbnVtYmVyIGFzIHRleHQsIG9yIGAobm8gaW5wdXQpYC5cbiAqL1xuZnVuY3Rpb24gZm9ybWF0TWVhc3VyZW1lbnQodmFsdWU6IG51bGwgfCBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gdmFsdWUgPT09IG51bGwgPyAnKG5vIGlucHV0KScgOiBTdHJpbmcodmFsdWUpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBa0tPLE1BQU0sNENBQTRDO0FBS3pELE1BQU0sNkJBQTZCO0FBS25DLE1BQU0saUJBQWlCO0FBYWhCLFNBQVMsbUNBQW1DLFFBQTBEO0FBQzNHLFFBQU0sY0FBYyxPQUFPLGlCQUFpQixXQUFXLE9BQU87QUFDOUQsUUFBTSxhQUFhLE9BQU8sU0FBUyxXQUFXLE9BQU87QUFDckQsUUFBTSxPQUFPLGdCQUFnQixRQUFRLGVBQWUsT0FBTyxPQUFPLGNBQWM7QUFFaEYsUUFBTSxRQUFRO0FBQUEsSUFDWixrRkFBa0YsT0FBTyxjQUFjO0FBQUEsSUFDdkcscUJBQXFCLE9BQU8sT0FBTyxTQUFTLFdBQVcsQ0FBQyxxQkFBcUIsa0JBQWtCLFdBQVcsQ0FBQyxhQUFhLGtCQUFrQixVQUFVLENBQUMsU0FBUyxrQkFBa0IsSUFBSSxDQUFDO0FBQUEsSUFDckwsV0FBVyxPQUFPLG9CQUFvQixrQ0FBa0M7QUFBQSxFQUMxRTtBQUVBLE1BQUksU0FBUyxHQUFHO0FBQ2QsVUFBTSxLQUFLLHVMQUFrTDtBQUFBLEVBQy9MO0FBRUEsU0FBTyxNQUFNLEtBQUssSUFBSTtBQUN4QjtBQW9CTyxTQUFTLHNCQUFzQixRQUE4QztBQUNsRixRQUFNLGVBQWUsT0FBTyxpQkFBaUI7QUFDN0MsUUFBTSxFQUFFLFVBQVUsSUFBSSxPQUFPO0FBQzdCLE1BQUksQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXO0FBQy9CLFdBQU87QUFBQSxFQUNUO0FBRUEsUUFBTSxnQ0FBZ0MsT0FBTyxpQ0FBaUM7QUFDOUUsU0FBTyxhQUFhLE1BQU0sVUFBVSxNQUFNO0FBQzVDO0FBUU8sU0FBUyxzQkFBc0IsZUFBK0I7QUFDbkUsU0FBTyxjQUNKLE1BQU0sSUFBSSxFQUNWLE9BQU8sQ0FBQyxTQUFTLDJCQUEyQixLQUFLLElBQUksQ0FBQyxFQUN0RCxJQUFJLENBQUMsU0FBUyxLQUFLLEtBQUssQ0FBQyxFQUN6QixLQUFLLEtBQUs7QUFDZjtBQVlPLFNBQVMsNkJBQTZCLFFBQW9FO0FBQy9HLFFBQU0sRUFBRSxrQkFBa0IsV0FBVyxRQUFRLElBQUksT0FBTztBQUN4RCxNQUFJLENBQUMsV0FBVztBQUNkLFdBQU8sQ0FBQztBQUFBLEVBQ1Y7QUFFQSxRQUFNLFlBQVksS0FBSyxPQUFPLFVBQVUsT0FBTyxVQUFVLFFBQVEsa0JBQWtCLGdCQUFnQjtBQUNuRyxRQUFNLGtCQUFrQixLQUFLLE9BQU8sVUFBVSxNQUFNLFVBQVUsU0FBUyxrQkFBa0IsZ0JBQWdCO0FBQ3pHLFFBQU0sb0JBQW9CLEtBQUssTUFBTSxVQUFVLGdCQUFnQjtBQUUvRCxNQUFJLHNCQUFzQixHQUFHO0FBQzNCLFdBQU8sQ0FBQyxFQUFFLFdBQVcsV0FBVyxnQkFBZ0IsQ0FBQztBQUFBLEVBQ25EO0FBRUEsU0FBTztBQUFBLElBQ0wsRUFBRSxXQUFXLFdBQVcsa0JBQWtCLGtCQUFrQjtBQUFBLElBQzVELEVBQUUsV0FBVyxXQUFXLGdCQUFnQjtBQUFBLEVBQzFDO0FBQ0Y7QUFRQSxTQUFTLGtCQUFrQixPQUE4QjtBQUN2RCxTQUFPLFVBQVUsT0FBTyxlQUFlLE9BQU8sS0FBSztBQUNyRDsiLAogICJuYW1lcyI6IFtdCn0K
@@ -8,9 +8,21 @@
8
8
  * and the modal container all stay at their full height with the keyboard shown
9
9
  * and `dumpsys input_method` reporting `mInputShown=true` — Obsidian Mobile keeps
10
10
  * a full-screen container and lifts its contents inside it. The only signal is
11
- * the field's own offset from the bottom, which is why the detection here is
12
- * geometric rather than an API call. Two runs failed on that before a framebuffer
13
- * dump said so, which is also why the diagnostic below exists.
11
+ * that the field *moves*, which is why the detection here is geometric rather
12
+ * than an API call. Two runs failed on that before a framebuffer dump said so,
13
+ * which is also why the diagnostic below exists.
14
+ *
15
+ * **The signal is a DELTA against a baseline read before the touch, not the
16
+ * field's absolute offset from the bottom.** The absolute offset was the original
17
+ * test and it is right only for a **bottom-anchored** field — a suggester, a
18
+ * command palette — where "clear of the bottom" and "lifted" are the same
19
+ * sentence. For a **centred modal** the condition is already true with no
20
+ * keyboard at all, so the test passed vacuously and `raiseSoftKeyboard` returned
21
+ * success having dispatched no touch (measured 2026-09-12 against a centred
22
+ * prompt modal: the field's `top` read `352.4453125` before and after real taps
23
+ * and the check said the keyboard was up both times). A delta is the same public
24
+ * API for both shapes, and it costs a field that cannot move its verdict — see
25
+ * {@link checkIsSoftKeyboardUp} for the one case that trades away.
14
26
  *
15
27
  * Pure and unit-tested; the touching and the capture live in `soft-keyboard`.
16
28
  */
@@ -18,6 +30,10 @@
18
30
  * Parameters for {@link buildSoftKeyboardDiagnosticMessage}.
19
31
  */
20
32
  export interface BuildSoftKeyboardDiagnosticMessageParams {
33
+ /**
34
+ * The geometry read before the first touch, which is what the verdict is measured against.
35
+ */
36
+ readonly baselineSnapshot: SoftKeyboardViewportSnapshot;
21
37
  /**
22
38
  * The lines of `dumpsys input_method` worth reading, as {@link parseInputMethodState} returned them.
23
39
  */
@@ -35,6 +51,13 @@ export interface BuildSoftKeyboardDiagnosticMessageParams {
35
51
  * Parameters for {@link checkIsSoftKeyboardUp}.
36
52
  */
37
53
  export interface CheckIsSoftKeyboardUpParams {
54
+ /**
55
+ * The geometry read **before** the first touch, with the keyboard still down.
56
+ *
57
+ * Required, and deliberately not optional: an absent baseline could only mean falling back to the
58
+ * absolute-offset test, which is the vacuous pass this parameter exists to make unrepresentable.
59
+ */
60
+ readonly baselineSnapshot: SoftKeyboardViewportSnapshot;
38
61
  /**
39
62
  * The least a raised keyboard lifts the field by, so a stray rounding pixel is not read as one.
40
63
  *
@@ -42,7 +65,7 @@ export interface CheckIsSoftKeyboardUpParams {
42
65
  */
43
66
  readonly minimumKeyboardHeightInPixels?: number;
44
67
  /**
45
- * The geometry to judge.
68
+ * The geometry to judge, read after the touch.
46
69
  */
47
70
  readonly snapshot: SoftKeyboardViewportSnapshot;
48
71
  }
@@ -123,17 +146,31 @@ export declare const DEFAULT_MINIMUM_KEYBOARD_HEIGHT_IN_PIXELS = 100;
123
146
  * Builds the message a failed raise reports.
124
147
  *
125
148
  * A bare "the keyboard did not come up" is unreadable — what the reader needs is what the page saw and what
126
- * the device thought, side by side, because the two disagreeing is the whole diagnosis.
149
+ * the device thought, side by side, because the two disagreeing is the whole diagnosis. The page's half is
150
+ * the lift and the two tops it came from, since the lift is the verdict; a lift of zero gets a sentence of
151
+ * its own, being the one reading that an already-up keyboard also produces.
127
152
  *
128
- * @param params - The evidence gathered after the last touch.
153
+ * @param params - The evidence gathered before the first touch and after the last one.
129
154
  * @returns The message, ready to throw.
130
155
  */
131
156
  export declare function buildSoftKeyboardDiagnosticMessage(params: BuildSoftKeyboardDiagnosticMessageParams): string;
132
157
  /**
133
- * Decides whether the IME is up, from the page's own geometry.
158
+ * Decides whether the IME is up, from how far the field moved.
159
+ *
160
+ * The verdict is a **delta**: the field must have risen from where it sat before the touch, by at least
161
+ * `minimumKeyboardHeightInPixels`. Obsidian Mobile lifts whatever is on screen to make room for the IME,
162
+ * so a field that has not moved has had no keyboard arrive under it — whether it is a bottom-anchored
163
+ * suggester or a centred modal.
164
+ *
165
+ * **The one case this gets wrong, deliberately:** a keyboard that was *already* up before the baseline was
166
+ * read. The field has nowhere left to lift to, so the answer is `false`. No amount of geometry separates
167
+ * that from a centred modal with no keyboard — both read as "clear of the bottom and not moving" — and of
168
+ * the two possible wrong answers, a loud `false` is the one worth keeping: it fails a capture rather than
169
+ * silently returning a screenshot of a keyboard that is not there. Read the baseline with the keyboard
170
+ * down, which is what `raiseSoftKeyboard` does.
134
171
  *
135
- * @param params - The geometry to judge, and how far the field must have lifted.
136
- * @returns Whether the field has stopped short of the bottom to make room for a keyboard.
172
+ * @param params - The geometry before and after the touch, and how far the field must have lifted.
173
+ * @returns Whether the field lifted far enough to have made room for a keyboard.
137
174
  */
138
175
  export declare function checkIsSoftKeyboardUp(params: CheckIsSoftKeyboardUpParams): boolean;
139
176
  /**