obsidian-integration-testing 12.0.0 → 12.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/dist/lib/cjs/adb-device-list.cjs +54 -0
  2. package/dist/lib/cjs/adb-device-list.d.cts +72 -0
  3. package/dist/lib/cjs/adb.cjs +61 -0
  4. package/dist/lib/cjs/adb.d.cts +61 -0
  5. package/dist/lib/cjs/android-sdk.cjs +52 -0
  6. package/dist/lib/cjs/android-sdk.d.cts +29 -0
  7. package/dist/lib/cjs/app-startup-progress.cjs +87 -0
  8. package/dist/lib/cjs/app-startup-progress.d.cts +128 -0
  9. package/dist/lib/cjs/appium-server-marker.cjs +29 -32
  10. package/dist/lib/cjs/appium-server-marker.d.cts +22 -0
  11. package/dist/lib/cjs/avd-probe-verdict.cjs +90 -0
  12. package/dist/lib/cjs/avd-probe-verdict.d.cts +175 -0
  13. package/dist/lib/cjs/community-plugin-registry.cjs +1 -1
  14. package/dist/lib/cjs/community-plugin-registry.d.cts +1 -1
  15. package/dist/lib/cjs/config-directory-fallback-error.cjs +57 -0
  16. package/dist/lib/cjs/config-directory-fallback-error.d.cts +64 -0
  17. package/dist/lib/cjs/config-directory.cjs +46 -0
  18. package/dist/lib/cjs/config-directory.d.cts +45 -0
  19. package/dist/lib/cjs/connect-to-cdp.cjs +13 -7
  20. package/dist/lib/cjs/connect-to-cdp.d.cts +19 -0
  21. package/dist/lib/cjs/demo-vault-bootstrap.cjs +1 -1
  22. package/dist/lib/cjs/demo-vault-bootstrap.d.cts +3 -2
  23. package/dist/lib/cjs/demo-vault-populate.cjs +3 -2
  24. package/dist/lib/cjs/device-readiness.cjs +38 -3
  25. package/dist/lib/cjs/device-readiness.d.cts +83 -9
  26. package/dist/lib/cjs/device-screenshot.cjs +42 -0
  27. package/dist/lib/cjs/device-screenshot.d.cts +36 -0
  28. package/dist/lib/cjs/device-setting-restore.cjs +45 -0
  29. package/dist/lib/cjs/device-setting-restore.d.cts +60 -0
  30. package/dist/lib/cjs/device-settings-command.cjs +49 -0
  31. package/dist/lib/cjs/device-settings-command.d.cts +76 -0
  32. package/dist/lib/cjs/device-settings.cjs +88 -0
  33. package/dist/lib/cjs/device-settings.d.cts +94 -0
  34. package/dist/lib/cjs/emulator-arguments.cjs +6 -2
  35. package/dist/lib/cjs/emulator-arguments.d.cts +26 -0
  36. package/dist/lib/cjs/emulator-backend.cjs +71 -0
  37. package/dist/lib/cjs/emulator-backend.d.cts +76 -0
  38. package/dist/lib/cjs/emulator-device-id.cjs +32 -0
  39. package/dist/lib/cjs/emulator-device-id.d.cts +49 -0
  40. package/dist/lib/cjs/emulator-liveness.cjs +72 -0
  41. package/dist/lib/cjs/emulator-liveness.d.cts +158 -0
  42. package/dist/lib/cjs/emulator-snapshot.cjs +57 -0
  43. package/dist/lib/cjs/emulator-snapshot.d.cts +68 -0
  44. package/dist/lib/cjs/global-setup-core.cjs +30 -30
  45. package/dist/lib/cjs/global-setup-core.d.cts +27 -2
  46. package/dist/lib/cjs/headless-vault-config.cjs +51 -0
  47. package/dist/lib/cjs/headless-vault-config.d.cts +67 -0
  48. package/dist/lib/cjs/index.cjs +67 -3
  49. package/dist/lib/cjs/index.d.cts +24 -1
  50. package/dist/lib/cjs/library.cjs +1 -1
  51. package/dist/lib/cjs/mobile-input.cjs +14 -2
  52. package/dist/lib/cjs/mobile-input.d.cts +5 -9
  53. package/dist/lib/cjs/namespace-bootstrap.cjs +1 -1
  54. package/dist/lib/cjs/obsidian-instance.cjs +52 -3
  55. package/dist/lib/cjs/obsidian-instance.d.cts +12 -0
  56. package/dist/lib/cjs/open-obsidian-settings-tab.cjs +1 -1
  57. package/dist/lib/cjs/open-obsidian-settings-tab.d.cts +3 -2
  58. package/dist/lib/cjs/owned-instance-exit-marker.cjs +99 -0
  59. package/dist/lib/cjs/owned-instance-exit-marker.d.cts +106 -0
  60. package/dist/lib/cjs/owned-instance-exited-error.cjs +106 -0
  61. package/dist/lib/cjs/owned-instance-exited-error.d.cts +98 -0
  62. package/dist/lib/cjs/owned-vault-seed.cjs +9 -5
  63. package/dist/lib/cjs/owned-vault-seed.d.cts +24 -3
  64. package/dist/lib/cjs/parent-liveness.cjs +42 -5
  65. package/dist/lib/cjs/parent-liveness.d.cts +37 -5
  66. package/dist/lib/cjs/port-owner.cjs +61 -0
  67. package/dist/lib/cjs/port-owner.d.cts +47 -0
  68. package/dist/lib/cjs/process-capture.cjs +62 -0
  69. package/dist/lib/cjs/process-capture.d.cts +83 -0
  70. package/dist/lib/cjs/process-exit-message.cjs +14 -8
  71. package/dist/lib/cjs/process-exit-message.d.cts +37 -3
  72. package/dist/lib/cjs/process-liveness.cjs +51 -0
  73. package/dist/lib/cjs/process-liveness.d.cts +18 -0
  74. package/dist/lib/cjs/resolve-emulator-device-id.cjs +54 -0
  75. package/dist/lib/cjs/resolve-emulator-device-id.d.cts +28 -0
  76. package/dist/lib/cjs/run-version-matrix.cjs +1 -1
  77. package/dist/lib/cjs/run-version-matrix.d.cts +1 -1
  78. package/dist/lib/cjs/soft-keyboard-geometry.cjs +75 -0
  79. package/dist/lib/cjs/soft-keyboard-geometry.d.cts +156 -0
  80. package/dist/lib/cjs/soft-keyboard.cjs +118 -0
  81. package/dist/lib/cjs/soft-keyboard.d.cts +82 -0
  82. package/dist/lib/cjs/teardown-verdict.cjs +53 -0
  83. package/dist/lib/cjs/teardown-verdict.d.cts +69 -0
  84. package/dist/lib/cjs/temporary-vault.cjs +43 -8
  85. package/dist/lib/cjs/temporary-vault.d.cts +47 -5
  86. package/dist/lib/cjs/transport-appium.cjs +102 -17
  87. package/dist/lib/cjs/transport-appium.d.cts +53 -3
  88. package/dist/lib/cjs/transport-desktop-cdp.cjs +195 -6
  89. package/dist/lib/cjs/transport-desktop-cdp.d.cts +99 -0
  90. package/dist/lib/cjs/transport-factory.cjs +951 -133
  91. package/dist/lib/cjs/transport-options.cjs +11 -3
  92. package/dist/lib/cjs/transport-options.d.cts +131 -12
  93. package/dist/lib/cjs/transport.cjs +1 -1
  94. package/dist/lib/cjs/transport.d.cts +7 -1
  95. package/dist/lib/cjs/vault-plugin-install.cjs +40 -0
  96. package/dist/lib/cjs/vault-plugin-install.d.cts +64 -0
  97. package/dist/lib/cjs/vault-teardown-verdict.cjs +42 -0
  98. package/dist/lib/cjs/vault-teardown-verdict.d.cts +57 -0
  99. package/dist/lib/cjs/version-matrix.cjs +1 -1
  100. package/dist/lib/cjs/version-matrix.d.cts +2 -2
  101. package/dist/lib/cjs/webview-cdp.cjs +6 -7
  102. package/dist/lib/cjs/webview-cdp.d.cts +5 -1
  103. package/dist/lib/esm/adb-device-list.d.mts +72 -0
  104. package/dist/lib/esm/adb-device-list.mjs +28 -0
  105. package/dist/lib/esm/adb.d.mts +61 -0
  106. package/dist/lib/esm/adb.mjs +35 -0
  107. package/dist/lib/esm/android-sdk.d.mts +29 -0
  108. package/dist/lib/esm/android-sdk.mjs +18 -0
  109. package/dist/lib/esm/app-startup-progress.d.mts +128 -0
  110. package/dist/lib/esm/app-startup-progress.mjs +59 -0
  111. package/dist/lib/esm/appium-server-marker.d.mts +22 -0
  112. package/dist/lib/esm/appium-server-marker.mjs +28 -22
  113. package/dist/lib/esm/avd-probe-verdict.d.mts +175 -0
  114. package/dist/lib/esm/avd-probe-verdict.mjs +62 -0
  115. package/dist/lib/esm/community-plugin-registry.d.mts +1 -1
  116. package/dist/lib/esm/community-plugin-registry.mjs +1 -1
  117. package/dist/lib/esm/config-directory-fallback-error.d.mts +64 -0
  118. package/dist/lib/esm/config-directory-fallback-error.mjs +33 -0
  119. package/dist/lib/esm/config-directory.d.mts +45 -0
  120. package/dist/lib/esm/config-directory.mjs +21 -0
  121. package/dist/lib/esm/connect-to-cdp.d.mts +19 -0
  122. package/dist/lib/esm/connect-to-cdp.mjs +13 -7
  123. package/dist/lib/esm/demo-vault-bootstrap.d.mts +3 -2
  124. package/dist/lib/esm/demo-vault-bootstrap.mjs +1 -1
  125. package/dist/lib/esm/demo-vault-populate.mjs +3 -2
  126. package/dist/lib/esm/device-readiness.d.mts +83 -9
  127. package/dist/lib/esm/device-readiness.mjs +34 -2
  128. package/dist/lib/esm/device-screenshot.d.mts +36 -0
  129. package/dist/lib/esm/device-screenshot.mjs +18 -0
  130. package/dist/lib/esm/device-setting-restore.d.mts +60 -0
  131. package/dist/lib/esm/device-setting-restore.mjs +20 -0
  132. package/dist/lib/esm/device-settings-command.d.mts +76 -0
  133. package/dist/lib/esm/device-settings-command.mjs +23 -0
  134. package/dist/lib/esm/device-settings.d.mts +94 -0
  135. package/dist/lib/esm/device-settings.mjs +67 -0
  136. package/dist/lib/esm/emulator-arguments.d.mts +26 -0
  137. package/dist/lib/esm/emulator-arguments.mjs +6 -2
  138. package/dist/lib/esm/emulator-backend.d.mts +76 -0
  139. package/dist/lib/esm/emulator-backend.mjs +45 -0
  140. package/dist/lib/esm/emulator-device-id.d.mts +49 -0
  141. package/dist/lib/esm/emulator-device-id.mjs +8 -0
  142. package/dist/lib/esm/emulator-liveness.d.mts +158 -0
  143. package/dist/lib/esm/emulator-liveness.mjs +47 -0
  144. package/dist/lib/esm/emulator-snapshot.d.mts +68 -0
  145. package/dist/lib/esm/emulator-snapshot.mjs +32 -0
  146. package/dist/lib/esm/global-setup-core.d.mts +27 -2
  147. package/dist/lib/esm/global-setup-core.mjs +34 -35
  148. package/dist/lib/esm/headless-vault-config.d.mts +67 -0
  149. package/dist/lib/esm/headless-vault-config.mjs +31 -0
  150. package/dist/lib/esm/index.d.mts +24 -1
  151. package/dist/lib/esm/index.mjs +68 -2
  152. package/dist/lib/esm/library.mjs +1 -1
  153. package/dist/lib/esm/mobile-input.d.mts +5 -9
  154. package/dist/lib/esm/mobile-input.mjs +14 -2
  155. package/dist/lib/esm/namespace-bootstrap.mjs +1 -1
  156. package/dist/lib/esm/obsidian-instance.d.mts +12 -0
  157. package/dist/lib/esm/obsidian-instance.mjs +55 -3
  158. package/dist/lib/esm/open-obsidian-settings-tab.d.mts +3 -2
  159. package/dist/lib/esm/open-obsidian-settings-tab.mjs +1 -1
  160. package/dist/lib/esm/owned-instance-exit-marker.d.mts +106 -0
  161. package/dist/lib/esm/owned-instance-exit-marker.mjs +78 -0
  162. package/dist/lib/esm/owned-instance-exited-error.d.mts +98 -0
  163. package/dist/lib/esm/owned-instance-exited-error.mjs +81 -0
  164. package/dist/lib/esm/owned-vault-seed.d.mts +24 -3
  165. package/dist/lib/esm/owned-vault-seed.mjs +9 -5
  166. package/dist/lib/esm/parent-liveness.d.mts +37 -5
  167. package/dist/lib/esm/parent-liveness.mjs +42 -5
  168. package/dist/lib/esm/port-owner.d.mts +47 -0
  169. package/dist/lib/esm/port-owner.mjs +36 -0
  170. package/dist/lib/esm/process-capture.d.mts +83 -0
  171. package/dist/lib/esm/process-capture.mjs +38 -0
  172. package/dist/lib/esm/process-exit-message.d.mts +37 -3
  173. package/dist/lib/esm/process-exit-message.mjs +13 -8
  174. package/dist/lib/esm/process-liveness.d.mts +18 -0
  175. package/dist/lib/esm/process-liveness.mjs +17 -0
  176. package/dist/lib/esm/resolve-emulator-device-id.d.mts +28 -0
  177. package/dist/lib/esm/resolve-emulator-device-id.mjs +33 -0
  178. package/dist/lib/esm/run-version-matrix.d.mts +1 -1
  179. package/dist/lib/esm/run-version-matrix.mjs +1 -1
  180. package/dist/lib/esm/soft-keyboard-geometry.d.mts +156 -0
  181. package/dist/lib/esm/soft-keyboard-geometry.mjs +47 -0
  182. package/dist/lib/esm/soft-keyboard.d.mts +82 -0
  183. package/dist/lib/esm/soft-keyboard.mjs +91 -0
  184. package/dist/lib/esm/teardown-verdict.d.mts +69 -0
  185. package/dist/lib/esm/teardown-verdict.mjs +28 -0
  186. package/dist/lib/esm/temporary-vault.d.mts +47 -5
  187. package/dist/lib/esm/temporary-vault.mjs +43 -8
  188. package/dist/lib/esm/transport-appium.d.mts +53 -3
  189. package/dist/lib/esm/transport-appium.mjs +108 -17
  190. package/dist/lib/esm/transport-desktop-cdp.d.mts +99 -0
  191. package/dist/lib/esm/transport-desktop-cdp.mjs +202 -7
  192. package/dist/lib/esm/transport-factory.mjs +995 -138
  193. package/dist/lib/esm/transport-options.d.mts +131 -12
  194. package/dist/lib/esm/transport-options.mjs +9 -2
  195. package/dist/lib/esm/transport.d.mts +7 -1
  196. package/dist/lib/esm/vault-plugin-install.d.mts +64 -0
  197. package/dist/lib/esm/vault-plugin-install.mjs +20 -0
  198. package/dist/lib/esm/vault-teardown-verdict.d.mts +57 -0
  199. package/dist/lib/esm/vault-teardown-verdict.mjs +18 -0
  200. package/dist/lib/esm/version-matrix.d.mts +2 -2
  201. package/dist/lib/esm/version-matrix.mjs +1 -1
  202. package/dist/lib/esm/webview-cdp.d.mts +5 -1
  203. package/dist/lib/esm/webview-cdp.mjs +6 -7
  204. package/package.json +26 -24
  205. package/dist/lib/cjs/native-dialog-monitor.cjs +0 -192
  206. package/dist/lib/cjs/native-dialog-monitor.d.cts +0 -66
  207. package/dist/lib/cjs/obsidian-namespace.cjs +0 -17
  208. package/dist/lib/cjs/obsidian-namespace.d.cts +0 -128
  209. package/dist/lib/esm/native-dialog-monitor.d.mts +0 -66
  210. package/dist/lib/esm/native-dialog-monitor.mjs +0 -158
  211. package/dist/lib/esm/obsidian-namespace.d.mts +0 -128
  212. package/dist/lib/esm/obsidian-namespace.mjs +0 -1
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var adb_device_list_exports = {};
20
+ __export(adb_device_list_exports, {
21
+ checkIsDeviceListed: () => checkIsDeviceListed,
22
+ listOnlineDeviceIds: () => listOnlineDeviceIds,
23
+ parseAdbDevices: () => parseAdbDevices
24
+ });
25
+ module.exports = __toCommonJS(adb_device_list_exports);
26
+ const ONLINE_DEVICE_STATE = "device";
27
+ function checkIsDeviceListed(params) {
28
+ return parseAdbDevices(params.devicesOutput).some((entry) => entry.deviceId === params.deviceId);
29
+ }
30
+ function listOnlineDeviceIds(devicesOutput) {
31
+ return parseAdbDevices(devicesOutput).filter((entry) => entry.state === ONLINE_DEVICE_STATE).map((entry) => entry.deviceId);
32
+ }
33
+ function parseAdbDevices(devicesOutput) {
34
+ const entries = [];
35
+ for (const rawLine of devicesOutput.split("\n")) {
36
+ const line = rawLine.trim();
37
+ const separatorIndex = line.indexOf(" ");
38
+ if (separatorIndex === -1) {
39
+ continue;
40
+ }
41
+ entries.push({
42
+ deviceId: line.slice(0, separatorIndex).trim(),
43
+ state: line.slice(separatorIndex + 1).trim()
44
+ });
45
+ }
46
+ return entries;
47
+ }
48
+ // Annotate the CommonJS export names for ESM import in node:
49
+ 0 && (module.exports = {
50
+ checkIsDeviceListed,
51
+ listOnlineDeviceIds,
52
+ parseAdbDevices
53
+ });
54
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2FkYi1kZXZpY2UtbGlzdC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFB1cmUgaGVscGVycyBmb3IgcGFyc2luZyBgYWRiIGRldmljZXNgIG91dHB1dC5cbiAqXG4gKiBLZXB0IHNlcGFyYXRlIGZyb20gdGhlIGludGVncmF0aW9uLW9ubHkgYHRyYW5zcG9ydC1mYWN0b3J5YCAoZXhjbHVkZWQgZnJvbVxuICogdW5pdCB0ZXN0cykgc28gdGhlIHBhcnNpbmcgc3RheXMgdW5pdC10ZXN0YWJsZSBcdTIwMTQgdGhlIGZhY3RvcnkgaXRzZWxmIHNoZWxscyBvdXRcbiAqIHRvIGBhZGJgLlxuICpcbiAqIFRoZSBsaXN0aW5nIGFuc3dlcnMgdHdvICoqZGlmZmVyZW50KiogcXVlc3Rpb25zLCBhbmQgY29uZmxhdGluZyB0aGVtIGlzIGFcbiAqIGRlZmVjdCByYXRoZXIgdGhhbiBhIG5pY2V0eTpcbiAqXG4gKiAtICpJcyB0aGUgZGV2aWNlIHVzYWJsZT8qIFx1MjAxNCBvbmx5IGEgZGV2aWNlIGluIHRoZSBgZGV2aWNlYCBzdGF0ZSBpcywgd2hpY2ggaXNcbiAqICAgd2hhdCB0aGUgc2Vzc2lvbiBwcmVmbGlnaHQgYXNrcyAoe0BsaW5rIGxpc3RPbmxpbmVEZXZpY2VJZHN9KS5cbiAqIC0gKklzIHRoZSBkZXZpY2UgZ29uZT8qIFx1MjAxNCBhIGR5aW5nIGVtdWxhdG9yIGRyb3BzIHRvIGBvZmZsaW5lYCB3aGlsZSBpdCBzdGlsbFxuICogICBob2xkcyB0aGUgQVZEJ3MgYG11bHRpaW5zdGFuY2UubG9ja2AgYW5kIGl0cyBjb25zb2xlIHBvcnQsIHNvIHRlYXJkb3duIG11c3RcbiAqICAgdHJlYXQgKiphbnkqKiBsaXN0ZWQgc3RhdGUgYXMgXCJzdGlsbCBoZXJlXCIgKHtAbGluayBjaGVja0lzRGV2aWNlTGlzdGVkfSkuXG4gKiAgIFJlYWRpbmcgYG9mZmxpbmVgIGFzIGdvbmUgaXMgd2hhdCBsZXRzIHRoZSBuZXh0IHJ1biBjb2xsaWRlIHdpdGggYSBsZWZ0b3Zlci5cbiAqL1xuXG4vKipcbiAqIE9uZSByb3cgb2YgYGFkYiBkZXZpY2VzYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBZGJEZXZpY2VFbnRyeSB7XG4gIC8qKlxuICBUaGUgZGV2aWNlIFVESUQsIGUuZy4gYGVtdWxhdG9yLTU1NTRgLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlSWQ6IHN0cmluZztcblxuICAvKipcbiAgVGhlIGRldmljZSBzdGF0ZSBhZGIgcmVwb3J0cywgZS5nLiBgZGV2aWNlYCwgYG9mZmxpbmVgLCBgdW5hdXRob3JpemVkYC5cbiAgICovXG4gIHJlYWRvbmx5IHN0YXRlOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGNoZWNrSXNEZXZpY2VMaXN0ZWR9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENoZWNrSXNEZXZpY2VMaXN0ZWRQYXJhbXMge1xuICAvKipcbiAgVGhlIGRldmljZSBVRElEIHRvIGxvb2sgZm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlSWQ6IHN0cmluZztcblxuICAvKipcbiAgUmF3IHN0ZG91dCBvZiBgYWRiIGRldmljZXNgLlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlc091dHB1dDogc3RyaW5nO1xufVxuXG5jb25zdCBPTkxJTkVfREVWSUNFX1NUQVRFID0gJ2RldmljZSc7XG5cbi8qKlxuICogRGVjaWRlcyB3aGV0aGVyIGEgZGV2aWNlIGlzIHN0aWxsIGxpc3RlZCBhdCBhbGwsICoqaW4gYW55IHN0YXRlKiouXG4gKlxuICogVGhpcyBpcyB0ZWFyZG93bidzIHF1ZXN0aW9uLCBub3QgdGhlIHByZWZsaWdodCdzOiBhbiBlbXVsYXRvciB0aGF0IGFuc3dlcnNcbiAqIGBvZmZsaW5lYCBoYXMgbm90IHJlbGVhc2VkIHRoZSBBVkQuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBsaXN0aW5nIG91dHB1dCBhbmQgdGhlIGRldmljZSB0byBsb29rIGZvci5cbiAqIEByZXR1cm5zIGB0cnVlYCB3aGVuIHRoZSBkZXZpY2UgYXBwZWFycyBpbiB0aGUgbGlzdGluZywgd2hhdGV2ZXIgaXRzIHN0YXRlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tJc0RldmljZUxpc3RlZChwYXJhbXM6IENoZWNrSXNEZXZpY2VMaXN0ZWRQYXJhbXMpOiBib29sZWFuIHtcbiAgcmV0dXJuIHBhcnNlQWRiRGV2aWNlcyhwYXJhbXMuZGV2aWNlc091dHB1dCkuc29tZSgoZW50cnkpID0+IGVudHJ5LmRldmljZUlkID09PSBwYXJhbXMuZGV2aWNlSWQpO1xufVxuXG4vKipcbiAqIExpc3RzIHRoZSBkZXZpY2VzIHRoYXQgYXJlIGFjdHVhbGx5IHVzYWJsZSBcdTIwMTQgdGhvc2UgaW4gdGhlIGBkZXZpY2VgIHN0YXRlLlxuICpcbiAqIEBwYXJhbSBkZXZpY2VzT3V0cHV0IC0gUmF3IHN0ZG91dCBvZiBgYWRiIGRldmljZXNgLlxuICogQHJldHVybnMgVGhlIG9ubGluZSBkZXZpY2UgSURzLCBpbiBsaXN0ZWQgb3JkZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXN0T25saW5lRGV2aWNlSWRzKGRldmljZXNPdXRwdXQ6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIHBhcnNlQWRiRGV2aWNlcyhkZXZpY2VzT3V0cHV0KVxuICAgIC5maWx0ZXIoKGVudHJ5KSA9PiBlbnRyeS5zdGF0ZSA9PT0gT05MSU5FX0RFVklDRV9TVEFURSlcbiAgICAubWFwKChlbnRyeSkgPT4gZW50cnkuZGV2aWNlSWQpO1xufVxuXG4vKipcbiAqIFBhcnNlcyB0aGUgcm93cyBvZiBgYWRiIGRldmljZXNgIGludG8gZGV2aWNlIElEcyBhbmQgc3RhdGVzLlxuICpcbiAqIEV2ZXJ5IHJvdyBpcyBgPGlkPlxcdDxzdGF0ZT5gOyB0aGUgYExpc3Qgb2YgZGV2aWNlcyBhdHRhY2hlZGAgaGVhZGVyIGFuZCB0aGVcbiAqIGAqIGRhZW1vbiBcdTIwMjYgKmAgYmFubmVyIGNhcnJ5IG5vIHRhYiwgd2hpY2ggaXMgd2hhdCBkaXN0aW5ndWlzaGVzIHRoZW0uXG4gKlxuICogQHBhcmFtIGRldmljZXNPdXRwdXQgLSBSYXcgc3Rkb3V0IG9mIGBhZGIgZGV2aWNlc2AuXG4gKiBAcmV0dXJucyBPbmUgZW50cnkgcGVyIGxpc3RlZCBkZXZpY2UsIGluIGxpc3RlZCBvcmRlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQWRiRGV2aWNlcyhkZXZpY2VzT3V0cHV0OiBzdHJpbmcpOiBBZGJEZXZpY2VFbnRyeVtdIHtcbiAgY29uc3QgZW50cmllczogQWRiRGV2aWNlRW50cnlbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgcmF3TGluZSBvZiBkZXZpY2VzT3V0cHV0LnNwbGl0KCdcXG4nKSkge1xuICAgIGNvbnN0IGxpbmUgPSByYXdMaW5lLnRyaW0oKTtcbiAgICBjb25zdCBzZXBhcmF0b3JJbmRleCA9IGxpbmUuaW5kZXhPZignXFx0Jyk7XG4gICAgaWYgKHNlcGFyYXRvckluZGV4ID09PSAtMSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgZW50cmllcy5wdXNoKHtcbiAgICAgIGRldmljZUlkOiBsaW5lLnNsaWNlKDAsIHNlcGFyYXRvckluZGV4KS50cmltKCksXG4gICAgICBzdGF0ZTogbGluZS5zbGljZShzZXBhcmF0b3JJbmRleCArIDEpLnRyaW0oKVxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGVudHJpZXM7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQWtEQSxNQUFNLHNCQUFzQjtBQVdyQixTQUFTLG9CQUFvQixRQUE0QztBQUM5RSxTQUFPLGdCQUFnQixPQUFPLGFBQWEsRUFBRSxLQUFLLENBQUMsVUFBVSxNQUFNLGFBQWEsT0FBTyxRQUFRO0FBQ2pHO0FBUU8sU0FBUyxvQkFBb0IsZUFBaUM7QUFDbkUsU0FBTyxnQkFBZ0IsYUFBYSxFQUNqQyxPQUFPLENBQUMsVUFBVSxNQUFNLFVBQVUsbUJBQW1CLEVBQ3JELElBQUksQ0FBQyxVQUFVLE1BQU0sUUFBUTtBQUNsQztBQVdPLFNBQVMsZ0JBQWdCLGVBQXlDO0FBQ3ZFLFFBQU0sVUFBNEIsQ0FBQztBQUVuQyxhQUFXLFdBQVcsY0FBYyxNQUFNLElBQUksR0FBRztBQUMvQyxVQUFNLE9BQU8sUUFBUSxLQUFLO0FBQzFCLFVBQU0saUJBQWlCLEtBQUssUUFBUSxHQUFJO0FBQ3hDLFFBQUksbUJBQW1CLElBQUk7QUFDekI7QUFBQSxJQUNGO0FBRUEsWUFBUSxLQUFLO0FBQUEsTUFDWCxVQUFVLEtBQUssTUFBTSxHQUFHLGNBQWMsRUFBRSxLQUFLO0FBQUEsTUFDN0MsT0FBTyxLQUFLLE1BQU0saUJBQWlCLENBQUMsRUFBRSxLQUFLO0FBQUEsSUFDN0MsQ0FBQztBQUFBLEVBQ0g7QUFFQSxTQUFPO0FBQ1Q7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Pure helpers for parsing `adb devices` output.
5
+ *
6
+ * Kept separate from the integration-only `transport-factory` (excluded from
7
+ * unit tests) so the parsing stays unit-testable — the factory itself shells out
8
+ * to `adb`.
9
+ *
10
+ * The listing answers two **different** questions, and conflating them is a
11
+ * defect rather than a nicety:
12
+ *
13
+ * - *Is the device usable?* — only a device in the `device` state is, which is
14
+ * what the session preflight asks ({@link listOnlineDeviceIds}).
15
+ * - *Is the device gone?* — a dying emulator drops to `offline` while it still
16
+ * holds the AVD's `multiinstance.lock` and its console port, so teardown must
17
+ * treat **any** listed state as "still here" ({@link checkIsDeviceListed}).
18
+ * Reading `offline` as gone is what lets the next run collide with a leftover.
19
+ */
20
+ /**
21
+ * One row of `adb devices`.
22
+ */
23
+ export interface AdbDeviceEntry {
24
+ /**
25
+ The device UDID, e.g. `emulator-5554`.
26
+ */
27
+ readonly deviceId: string;
28
+ /**
29
+ The device state adb reports, e.g. `device`, `offline`, `unauthorized`.
30
+ */
31
+ readonly state: string;
32
+ }
33
+ /**
34
+ * Parameters for {@link checkIsDeviceListed}.
35
+ */
36
+ export interface CheckIsDeviceListedParams {
37
+ /**
38
+ The device UDID to look for.
39
+ */
40
+ readonly deviceId: string;
41
+ /**
42
+ Raw stdout of `adb devices`.
43
+ */
44
+ readonly devicesOutput: string;
45
+ }
46
+ /**
47
+ * Decides whether a device is still listed at all, **in any state**.
48
+ *
49
+ * This is teardown's question, not the preflight's: an emulator that answers
50
+ * `offline` has not released the AVD.
51
+ *
52
+ * @param params - The listing output and the device to look for.
53
+ * @returns `true` when the device appears in the listing, whatever its state.
54
+ */
55
+ export declare function checkIsDeviceListed(params: CheckIsDeviceListedParams): boolean;
56
+ /**
57
+ * Lists the devices that are actually usable — those in the `device` state.
58
+ *
59
+ * @param devicesOutput - Raw stdout of `adb devices`.
60
+ * @returns The online device IDs, in listed order.
61
+ */
62
+ export declare function listOnlineDeviceIds(devicesOutput: string): string[];
63
+ /**
64
+ * Parses the rows of `adb devices` into device IDs and states.
65
+ *
66
+ * Every row is `<id>\t<state>`; the `List of devices attached` header and the
67
+ * `* daemon … *` banner carry no tab, which is what distinguishes them.
68
+ *
69
+ * @param devicesOutput - Raw stdout of `adb devices`.
70
+ * @returns One entry per listed device, in listed order.
71
+ */
72
+ export declare function parseAdbDevices(devicesOutput: string): AdbDeviceEntry[];
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var adb_exports = {};
20
+ __export(adb_exports, {
21
+ runAdbBinary: () => runAdbBinary,
22
+ runAdbText: () => runAdbText,
23
+ runAdbTextWithoutDevice: () => runAdbTextWithoutDevice
24
+ });
25
+ module.exports = __toCommonJS(adb_exports);
26
+ var import_node_child_process = require("node:child_process");
27
+ const OUTPUT_MAX_BUFFER_IN_BYTES = 67108864;
28
+ async function runAdbBinary(params) {
29
+ const commandArguments = ["-s", params.deviceId, ...params.commandArguments];
30
+ return await new Promise((resolve, reject) => {
31
+ (0, import_node_child_process.execFile)("adb", commandArguments, { encoding: "buffer", maxBuffer: OUTPUT_MAX_BUFFER_IN_BYTES }, (error, stdout) => {
32
+ if (error) {
33
+ reject(new Error(`Failed to run 'adb ${commandArguments.join(" ")}': ${error.message}. Is ADB installed and in PATH?`));
34
+ return;
35
+ }
36
+ resolve(stdout);
37
+ });
38
+ });
39
+ }
40
+ async function runAdbText(params) {
41
+ const stdout = await runAdbBinary(params);
42
+ return new TextDecoder().decode(stdout).trim();
43
+ }
44
+ async function runAdbTextWithoutDevice(commandArguments) {
45
+ return await new Promise((resolve, reject) => {
46
+ (0, import_node_child_process.execFile)("adb", [...commandArguments], { encoding: "utf-8", maxBuffer: OUTPUT_MAX_BUFFER_IN_BYTES }, (error, stdout) => {
47
+ if (error) {
48
+ reject(new Error(`Failed to run 'adb ${commandArguments.join(" ")}': ${error.message}. Is ADB installed and in PATH?`));
49
+ return;
50
+ }
51
+ resolve(stdout.trim());
52
+ });
53
+ });
54
+ }
55
+ // Annotate the CommonJS export names for ESM import in node:
56
+ 0 && (module.exports = {
57
+ runAdbBinary,
58
+ runAdbText,
59
+ runAdbTextWithoutDevice
60
+ });
61
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2FkYi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFJ1bnMgYGFkYmAgYW5kIGhhbmRzIGJhY2sgd2hhdCBpdCBwcmludGVkIFx1MjAxNCBhcyB0ZXh0LCBvciBhcyByYXcgYnl0ZXMuXG4gKlxuICogVGhlIGhhcm5lc3MgYWxyZWFkeSBzaGVsbHMgb3V0IHRvIGBhZGJgIGluIGhhbGYgYSBkb3plbiBwbGFjZXMgaW5zaWRlXG4gKiBgdHJhbnNwb3J0LWZhY3RvcnlgIC8gYHRyYW5zcG9ydC1hcHBpdW1gLCBidXQgYWx3YXlzIHRocm91Z2ggYGV4ZWNgLCB3aGljaFxuICogZGVjb2RlcyBzdGRvdXQgYXMgVVRGLTguIFRoYXQgaXMgZmluZSBmb3IgYGRldmljZXNgIGFuZCBgc2V0dGluZ3MgZ2V0YCBhbmRcbiAqIGZhdGFsbHkgd3JvbmcgZm9yIGBleGVjLW91dCBzY3JlZW5jYXAgLXBgLCB3aG9zZSBzdGRvdXQgaXMgYSBQTkc6IGRlY29kaW5nIGl0XG4gKiBhcyB0ZXh0IGNvcnJ1cHRzIGV2ZXJ5IGJ5dGUgYWJvdmUgMHg3Ri4gSGVuY2UgdGhlIHR3byBydW5uZXJzIGhlcmUgXHUyMDE0IHRoZSBzYW1lXG4gKiBjb21tYW5kIHNoYXBlLCBkaWZmZXJpbmcgb25seSBpbiB3aGV0aGVyIHRoZSBvdXRwdXQgaXMgZGVjb2RlZC5cbiAqXG4gKiBUaGVzZSBhcmUgdGhlIHByb2Nlc3MgbGF5ZXIgZm9yIHRoZSBkZXZpY2UtZmFjaW5nIGhlbHBlcnMgYSBjYXB0dXJlIHN1aXRlXG4gKiB1c2VzIChgZGV2aWNlLXNjcmVlbnNob3RgLCBgZGV2aWNlLXNldHRpbmdzYCwgYHNvZnQta2V5Ym9hcmRgKTsgdGhleSBhcmUgbm90IGFcbiAqIGdlbmVyYWwtcHVycG9zZSBhZGIgd3JhcHBlciBhbmQgZGVsaWJlcmF0ZWx5IGRvIG5vdCB0cnkgdG8gYmVjb21lIG9uZS5cbiAqXG4gKiBFdmVyeSBmdW5jdGlvbiBoZXJlIHNoZWxscyBvdXQsIHNvIHRoZSB3aG9sZSBtb2R1bGUgaXMgaW50ZWdyYXRpb24tdGltZSBjb2RlLlxuICogVGhhdCBpcyBhbHNvIHdoeSB0aGUgcGFyc2luZyBhbmQgZ2VvbWV0cnkgdGhlc2UgaGVscGVycyBkZXBlbmQgb24gbGl2ZSBpblxuICogdGhlaXIgb3duIG1vZHVsZXMgXHUyMDE0IHRoZSBzYW1lIHNwbGl0IGBhZGItZGV2aWNlLWxpc3RgIGFscmVhZHkgaGFzIGZyb20gdGhlXG4gKiB0cmFuc3BvcnQgZmFjdG9yeSwgc28gYSBzb3J0IHJ1bGUgY2FuIG5ldmVyIG1vdmUgYSB1bml0LXRlc3RlZCBmdW5jdGlvblxuICogaW5zaWRlIGEgY292ZXJhZ2UtaWdub3JlZCBibG9jay5cbiAqL1xuXG4vKiB2OCBpZ25vcmUgc3RhcnQgLS0gSW50ZWdyYXRpb24tdGltZSBjb2RlIChzaGVsbHMgb3V0IHRvIGEgcmVhbCBkZXZpY2UpIGNvdmVyZWQgYnkgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCB1bml0IHRlc3RzLiAqL1xuXG5pbXBvcnQgeyBleGVjRmlsZSB9IGZyb20gJ25vZGU6Y2hpbGRfcHJvY2Vzcyc7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIHJ1bkFkYkJpbmFyeX0gYW5kIHtAbGluayBydW5BZGJUZXh0fS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSdW5BZGJQYXJhbXMge1xuICAvKipcbiAgICogVGhlIGFyZ3VtZW50cyB0byBwYXNzIGFmdGVyIGAtcyA8ZGV2aWNlSWQ+YCwgZS5nLiBgWydzaGVsbCcsICdpbnB1dCcsICd0YXAnLCAnMTAnLCAnMjAnXWAuXG4gICAqL1xuICByZWFkb25seSBjb21tYW5kQXJndW1lbnRzOiByZWFkb25seSBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIGRldmljZSB0byBhZGRyZXNzLCBhcyBgYWRiIGRldmljZXNgIGxpc3RzIGl0LlxuICAgKi9cbiAgcmVhZG9ubHkgZGV2aWNlSWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIHNjcmVlbmNhcCBvZiBhIDkwMHgxNjAwIGRldmljZSBydW5zIHRvIGFib3V0IDEwMCBLQiwgYnV0IGEgdGFibGV0IEFWRCdzIGZyYW1lYnVmZmVyIGlzIHNldmVyYWwgTUIgYW5kXG4gKiB0aGUgZGVmYXVsdCAxIE1pQiBgbWF4QnVmZmVyYCBmYWlscyB0aGUgY2FsbCByYXRoZXIgdGhhbiByZXR1cm5pbmcgYSB1c2FibGUgaW1hZ2UuXG4gKi9cbmNvbnN0IE9VVFBVVF9NQVhfQlVGRkVSX0lOX0JZVEVTID0gNjdfMTA4Xzg2NDtcblxuLyoqXG4gKiBSdW5zIGBhZGIgLXMgPGRldmljZUlkPiA8Y29tbWFuZEFyZ3VtZW50cz5gIGFuZCByZXR1cm5zIHN0ZG91dCAqKnVuZGVjb2RlZCoqLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZGV2aWNlIGFuZCB0aGUgYXJndW1lbnRzIHRvIHJ1bi5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHJhdyBzdGRvdXQgYnl0ZXMuXG4gKiBAdGhyb3dzIEVycm9yIGlmIGFkYiBjb3VsZCBub3QgYmUgcnVuLCBvciBleGl0ZWQgbm9uLXplcm8uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBydW5BZGJCaW5hcnkocGFyYW1zOiBSdW5BZGJQYXJhbXMpOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgY29uc3QgY29tbWFuZEFyZ3VtZW50cyA9IFsnLXMnLCBwYXJhbXMuZGV2aWNlSWQsIC4uLnBhcmFtcy5jb21tYW5kQXJndW1lbnRzXTtcblxuICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGV4ZWNGaWxlKCdhZGInLCBjb21tYW5kQXJndW1lbnRzLCB7IGVuY29kaW5nOiAnYnVmZmVyJywgbWF4QnVmZmVyOiBPVVRQVVRfTUFYX0JVRkZFUl9JTl9CWVRFUyB9LCAoZXJyb3IsIHN0ZG91dCkgPT4ge1xuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBydW4gJ2FkYiAke2NvbW1hbmRBcmd1bWVudHMuam9pbignICcpfSc6ICR7ZXJyb3IubWVzc2FnZX0uIElzIEFEQiBpbnN0YWxsZWQgYW5kIGluIFBBVEg/YCkpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHJlc29sdmUoc3Rkb3V0KTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogUnVucyBgYWRiIC1zIDxkZXZpY2VJZD4gPGNvbW1hbmRBcmd1bWVudHM+YCBhbmQgcmV0dXJucyBzdGRvdXQgYXMgdHJpbW1lZCB0ZXh0LlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZGV2aWNlIGFuZCB0aGUgYXJndW1lbnRzIHRvIHJ1bi5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgdG8gc3Rkb3V0LCB3aXRoIHN1cnJvdW5kaW5nIHdoaXRlc3BhY2UgcmVtb3ZlZC5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgYWRiIGNvdWxkIG5vdCBiZSBydW4sIG9yIGV4aXRlZCBub24temVyby5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1bkFkYlRleHQocGFyYW1zOiBSdW5BZGJQYXJhbXMpOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBzdGRvdXQgPSBhd2FpdCBydW5BZGJCaW5hcnkocGFyYW1zKTtcbiAgcmV0dXJuIG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShzdGRvdXQpLnRyaW0oKTtcbn1cblxuLyoqXG4gKiBSdW5zIGBhZGIgPGNvbW1hbmRBcmd1bWVudHM+YCB3aXRoIG5vIGRldmljZSBzZWxlY3RlZC5cbiAqXG4gKiBPbmx5IGBkZXZpY2VzYCBuZWVkcyB0aGlzIFx1MjAxNCBldmVyeSBvdGhlciBjYWxsIGluIHRoaXMgZmFtaWx5IGFkZHJlc3NlcyBvbmUgZGV2aWNlLlxuICpcbiAqIEBwYXJhbSBjb21tYW5kQXJndW1lbnRzIC0gVGhlIGFyZ3VtZW50cyB0byBydW4uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHRvIHN0ZG91dCwgd2l0aCBzdXJyb3VuZGluZyB3aGl0ZXNwYWNlIHJlbW92ZWQuXG4gKiBAdGhyb3dzIEVycm9yIGlmIGFkYiBjb3VsZCBub3QgYmUgcnVuLCBvciBleGl0ZWQgbm9uLXplcm8uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBydW5BZGJUZXh0V2l0aG91dERldmljZShjb21tYW5kQXJndW1lbnRzOiByZWFkb25seSBzdHJpbmdbXSk6IFByb21pc2U8c3RyaW5nPiB7XG4gIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgZXhlY0ZpbGUoJ2FkYicsIFsuLi5jb21tYW5kQXJndW1lbnRzXSwgeyBlbmNvZGluZzogJ3V0Zi04JywgbWF4QnVmZmVyOiBPVVRQVVRfTUFYX0JVRkZFUl9JTl9CWVRFUyB9LCAoZXJyb3IsIHN0ZG91dCkgPT4ge1xuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBydW4gJ2FkYiAke2NvbW1hbmRBcmd1bWVudHMuam9pbignICcpfSc6ICR7ZXJyb3IubWVzc2FnZX0uIElzIEFEQiBpbnN0YWxsZWQgYW5kIGluIFBBVEg/YCkpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHJlc29sdmUoc3Rkb3V0LnRyaW0oKSk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKiB2OCBpZ25vcmUgc3RvcCAqL1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUF5QkEsZ0NBQXlCO0FBcUJ6QixNQUFNLDZCQUE2QjtBQVNuQyxlQUFzQixhQUFhLFFBQTJDO0FBQzVFLFFBQU0sbUJBQW1CLENBQUMsTUFBTSxPQUFPLFVBQVUsR0FBRyxPQUFPLGdCQUFnQjtBQUUzRSxTQUFPLE1BQU0sSUFBSSxRQUFRLENBQUMsU0FBUyxXQUFXO0FBQzVDLDRDQUFTLE9BQU8sa0JBQWtCLEVBQUUsVUFBVSxVQUFVLFdBQVcsMkJBQTJCLEdBQUcsQ0FBQyxPQUFPLFdBQVc7QUFDbEgsVUFBSSxPQUFPO0FBQ1QsZUFBTyxJQUFJLE1BQU0sc0JBQXNCLGlCQUFpQixLQUFLLEdBQUcsQ0FBQyxNQUFNLE1BQU0sT0FBTyxpQ0FBaUMsQ0FBQztBQUN0SDtBQUFBLE1BQ0Y7QUFFQSxjQUFRLE1BQU07QUFBQSxJQUNoQixDQUFDO0FBQUEsRUFDSCxDQUFDO0FBQ0g7QUFTQSxlQUFzQixXQUFXLFFBQXVDO0FBQ3RFLFFBQU0sU0FBUyxNQUFNLGFBQWEsTUFBTTtBQUN4QyxTQUFPLElBQUksWUFBWSxFQUFFLE9BQU8sTUFBTSxFQUFFLEtBQUs7QUFDL0M7QUFXQSxlQUFzQix3QkFBd0Isa0JBQXNEO0FBQ2xHLFNBQU8sTUFBTSxJQUFJLFFBQVEsQ0FBQyxTQUFTLFdBQVc7QUFDNUMsNENBQVMsT0FBTyxDQUFDLEdBQUcsZ0JBQWdCLEdBQUcsRUFBRSxVQUFVLFNBQVMsV0FBVywyQkFBMkIsR0FBRyxDQUFDLE9BQU8sV0FBVztBQUN0SCxVQUFJLE9BQU87QUFDVCxlQUFPLElBQUksTUFBTSxzQkFBc0IsaUJBQWlCLEtBQUssR0FBRyxDQUFDLE1BQU0sTUFBTSxPQUFPLGlDQUFpQyxDQUFDO0FBQ3RIO0FBQUEsTUFDRjtBQUVBLGNBQVEsT0FBTyxLQUFLLENBQUM7QUFBQSxJQUN2QixDQUFDO0FBQUEsRUFDSCxDQUFDO0FBQ0g7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Runs `adb` and hands back what it printed — as text, or as raw bytes.
5
+ *
6
+ * The harness already shells out to `adb` in half a dozen places inside
7
+ * `transport-factory` / `transport-appium`, but always through `exec`, which
8
+ * decodes stdout as UTF-8. That is fine for `devices` and `settings get` and
9
+ * fatally wrong for `exec-out screencap -p`, whose stdout is a PNG: decoding it
10
+ * as text corrupts every byte above 0x7F. Hence the two runners here — the same
11
+ * command shape, differing only in whether the output is decoded.
12
+ *
13
+ * These are the process layer for the device-facing helpers a capture suite
14
+ * uses (`device-screenshot`, `device-settings`, `soft-keyboard`); they are not a
15
+ * general-purpose adb wrapper and deliberately do not try to become one.
16
+ *
17
+ * Every function here shells out, so the whole module is integration-time code.
18
+ * That is also why the parsing and geometry these helpers depend on live in
19
+ * their own modules — the same split `adb-device-list` already has from the
20
+ * transport factory, so a sort rule can never move a unit-tested function
21
+ * inside a coverage-ignored block.
22
+ */
23
+ /**
24
+ * Parameters for {@link runAdbBinary} and {@link runAdbText}.
25
+ */
26
+ export interface RunAdbParams {
27
+ /**
28
+ * The arguments to pass after `-s <deviceId>`, e.g. `['shell', 'input', 'tap', '10', '20']`.
29
+ */
30
+ readonly commandArguments: readonly string[];
31
+ /**
32
+ * The device to address, as `adb devices` lists it.
33
+ */
34
+ readonly deviceId: string;
35
+ }
36
+ /**
37
+ * Runs `adb -s <deviceId> <commandArguments>` and returns stdout **undecoded**.
38
+ *
39
+ * @param params - The device and the arguments to run.
40
+ * @returns A {@link Promise} that resolves to the raw stdout bytes.
41
+ * @throws Error if adb could not be run, or exited non-zero.
42
+ */
43
+ export declare function runAdbBinary(params: RunAdbParams): Promise<Uint8Array>;
44
+ /**
45
+ * Runs `adb -s <deviceId> <commandArguments>` and returns stdout as trimmed text.
46
+ *
47
+ * @param params - The device and the arguments to run.
48
+ * @returns A {@link Promise} that resolves to stdout, with surrounding whitespace removed.
49
+ * @throws Error if adb could not be run, or exited non-zero.
50
+ */
51
+ export declare function runAdbText(params: RunAdbParams): Promise<string>;
52
+ /**
53
+ * Runs `adb <commandArguments>` with no device selected.
54
+ *
55
+ * Only `devices` needs this — every other call in this family addresses one device.
56
+ *
57
+ * @param commandArguments - The arguments to run.
58
+ * @returns A {@link Promise} that resolves to stdout, with surrounding whitespace removed.
59
+ * @throws Error if adb could not be run, or exited non-zero.
60
+ */
61
+ export declare function runAdbTextWithoutDevice(commandArguments: readonly string[]): Promise<string>;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var android_sdk_exports = {};
30
+ __export(android_sdk_exports, {
31
+ resolveEmulatorBinaryPath: () => resolveEmulatorBinaryPath
32
+ });
33
+ module.exports = __toCommonJS(android_sdk_exports);
34
+ var import_node_path = require("node:path");
35
+ var import_node_process = __toESM(require("node:process"), 1);
36
+ function resolveEmulatorBinaryPath() {
37
+ return (0, import_node_path.join)(resolveAndroidSdkRoot(), "emulator", "emulator");
38
+ }
39
+ function resolveAndroidSdkRoot() {
40
+ const sdkRoot = import_node_process.default.env["ANDROID_HOME"] ?? import_node_process.default.env["ANDROID_SDK_ROOT"];
41
+ if (!sdkRoot) {
42
+ throw new Error(
43
+ "Cannot find Android emulator: neither ANDROID_HOME nor ANDROID_SDK_ROOT environment variable is set."
44
+ );
45
+ }
46
+ return sdkRoot;
47
+ }
48
+ // Annotate the CommonJS export names for ESM import in node:
49
+ 0 && (module.exports = {
50
+ resolveEmulatorBinaryPath
51
+ });
52
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2FuZHJvaWQtc2RrLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogUmVzb2x2ZXMgdGhlIEFuZHJvaWQgU0RLIGJpbmFyaWVzIHRoZSBoYXJuZXNzIHNoZWxscyBvdXQgdG8uXG4gKlxuICogTGl2ZXMgaGVyZSByYXRoZXIgdGhhbiBhcyBhIHByaXZhdGUgbWV0aG9kIG9uIHRoZSBpbnRlZ3JhdGlvbi1vbmx5XG4gKiBgdHJhbnNwb3J0LWZhY3RvcnlgIGJlY2F1c2UgaXQgaXMgYW4gKiphZ3JlZW1lbnQqKiwgbm90IGFuIGltcGxlbWVudGF0aW9uXG4gKiBkZXRhaWw6IGBzY3JpcHRzL2VtdWxhdG9yLXdlZGdlLXByb2JlLnRzYCBleGlzdHMgdG8gcmVwcm9kdWNlIGEgaG9zdCBmYXVsdCBieVxuICogYm9vdGluZyB0aGUgZW11bGF0b3IgZXhhY3RseSBhcyBhIHJ1biB3b3VsZCwgYW5kIGEgcHJvYmUgdGhhdCByZXNvbHZlZCBhXG4gKiBkaWZmZXJlbnQgYmluYXJ5IHRoYW4gdGhlIGhhcm5lc3Mgd291bGQgcXVpZXRseSBtZWFzdXJlIHNvbWV0aGluZyBlbHNlLiBPbmVcbiAqIGZ1bmN0aW9uLCBvbmUgYW5zd2VyLCBib3RoIGNhbGxlcnMuXG4gKlxuICogVGhlIGxvb2t1cCBpdHNlbGYgaXMgdGhlIFNESydzIG93biBjb252ZW50aW9uIFx1MjAxNCBgQU5EUk9JRF9IT01FYCBmaXJzdCwgdGhlbiB0aGVcbiAqIG9sZGVyIGBBTkRST0lEX1NES19ST09UYCBcdTIwMTQgYW5kIGl0IGRlbGliZXJhdGVseSBkb2VzICoqbm90KiogZmFsbCBiYWNrIHRvIGFcbiAqIHBsYXRmb3JtLWRlZmF1bHQgaW5zdGFsbCBwYXRoLiBBIHdyb25nIGd1ZXNzIHdvdWxkIGJvb3Qgc29tZSBvdGhlciBTREsnc1xuICogZW11bGF0b3IgYW5kIHJlcG9ydCBvbiBpdCBhcyB0aG91Z2ggaXQgd2VyZSB0aGUgY29uZmlndXJlZCBvbmU7IGFuIGVycm9yIHRoYXRcbiAqIG5hbWVzIGJvdGggdmFyaWFibGVzIGlzIHRoZSBzaG9ydGVyIHJvdXRlIHRvIGEgd29ya2luZyBzZXR1cC5cbiAqL1xuXG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIGBlbXVsYXRvcmAgYmluYXJ5IGZyb20gdGhlIEFuZHJvaWQgU0RLIHJvb3QuXG4gKlxuICogTm8gZXh0ZW5zaW9uIGlzIGFwcGVuZGVkOiBOb2RlJ3MgcHJvY2VzcyBzcGF3bmluZyByZXNvbHZlcyBgZW11bGF0b3IuZXhlYCBvblxuICogV2luZG93cyBvbiBpdHMgb3duLCBhbmQgdGhlIHNhbWUgcGF0aCBzdHJpbmcgaXMgd2hhdCB0aGUgU0RLJ3Mgb3duIHRvb2xpbmdcbiAqIGRvY3VtZW50cy5cbiAqXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgYGVtdWxhdG9yYCBiaW5hcnkuXG4gKiBAdGhyb3dzIFdoZW4gbmVpdGhlciBgQU5EUk9JRF9IT01FYCBub3IgYEFORFJPSURfU0RLX1JPT1RgIGlzIHNldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVFbXVsYXRvckJpbmFyeVBhdGgoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4ocmVzb2x2ZUFuZHJvaWRTZGtSb290KCksICdlbXVsYXRvcicsICdlbXVsYXRvcicpO1xufVxuXG5mdW5jdGlvbiByZXNvbHZlQW5kcm9pZFNka1Jvb3QoKTogc3RyaW5nIHtcbiAgY29uc3Qgc2RrUm9vdCA9IHByb2Nlc3MuZW52WydBTkRST0lEX0hPTUUnXSA/PyBwcm9jZXNzLmVudlsnQU5EUk9JRF9TREtfUk9PVCddO1xuICBpZiAoIXNka1Jvb3QpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnQ2Fubm90IGZpbmQgQW5kcm9pZCBlbXVsYXRvcjogbmVpdGhlciBBTkRST0lEX0hPTUUgbm9yIEFORFJPSURfU0RLX1JPT1QgZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgc2V0LidcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIHNka1Jvb3Q7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQW1CQSx1QkFBcUI7QUFDckIsMEJBQW9CO0FBWWIsU0FBUyw0QkFBb0M7QUFDbEQsYUFBTyx1QkFBSyxzQkFBc0IsR0FBRyxZQUFZLFVBQVU7QUFDN0Q7QUFFQSxTQUFTLHdCQUFnQztBQUN2QyxRQUFNLFVBQVUsb0JBQUFBLFFBQVEsSUFBSSxjQUFjLEtBQUssb0JBQUFBLFFBQVEsSUFBSSxrQkFBa0I7QUFDN0UsTUFBSSxDQUFDLFNBQVM7QUFDWixVQUFNLElBQUk7QUFBQSxNQUNSO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFFQSxTQUFPO0FBQ1Q7IiwKICAibmFtZXMiOiBbInByb2Nlc3MiXQp9Cg==
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Resolves the Android SDK binaries the harness shells out to.
5
+ *
6
+ * Lives here rather than as a private method on the integration-only
7
+ * `transport-factory` because it is an **agreement**, not an implementation
8
+ * detail: `scripts/emulator-wedge-probe.ts` exists to reproduce a host fault by
9
+ * booting the emulator exactly as a run would, and a probe that resolved a
10
+ * different binary than the harness would quietly measure something else. One
11
+ * function, one answer, both callers.
12
+ *
13
+ * The lookup itself is the SDK's own convention — `ANDROID_HOME` first, then the
14
+ * older `ANDROID_SDK_ROOT` — and it deliberately does **not** fall back to a
15
+ * platform-default install path. A wrong guess would boot some other SDK's
16
+ * emulator and report on it as though it were the configured one; an error that
17
+ * names both variables is the shorter route to a working setup.
18
+ */
19
+ /**
20
+ * Resolves the `emulator` binary from the Android SDK root.
21
+ *
22
+ * No extension is appended: Node's process spawning resolves `emulator.exe` on
23
+ * Windows on its own, and the same path string is what the SDK's own tooling
24
+ * documents.
25
+ *
26
+ * @returns The absolute path to the `emulator` binary.
27
+ * @throws When neither `ANDROID_HOME` nor `ANDROID_SDK_ROOT` is set.
28
+ */
29
+ export declare function resolveEmulatorBinaryPath(): string;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var app_startup_progress_exports = {};
20
+ __export(app_startup_progress_exports, {
21
+ buildStartupTimeoutMessage: () => buildStartupTimeoutMessage,
22
+ checkAppStarted: () => checkAppStarted,
23
+ checkLayoutReady: () => checkLayoutReady,
24
+ classifyAppStartupProbe: () => classifyAppStartupProbe,
25
+ compareAppStartupMilestones: () => compareAppStartupMilestones
26
+ });
27
+ module.exports = __toCommonJS(app_startup_progress_exports);
28
+ const MILESTONE_ORDER = [
29
+ "no-webview",
30
+ "no-app",
31
+ "no-workspace",
32
+ "workspace-not-ready",
33
+ "layout-ready"
34
+ ];
35
+ const APP_STARTED_MILESTONE = "no-workspace";
36
+ const MILESTONE_DESCRIPTIONS = {
37
+ "layout-ready": "the workspace finished laying out",
38
+ "no-app": "the WebView answered, but `globalThis.app` never appeared",
39
+ "no-webview": "the WebView never answered a single probe",
40
+ "no-workspace": "`globalThis.app` appeared, but `app.workspace` never did",
41
+ "workspace-not-ready": "`app.workspace` exists, but `layoutReady` never became true"
42
+ };
43
+ const PHASE_DESCRIPTIONS = {
44
+ "app-start": "Obsidian Mobile did not finish starting",
45
+ "layout-ready": "Obsidian layout did not become ready"
46
+ };
47
+ function buildStartupTimeoutMessage(params) {
48
+ const {
49
+ elapsedInMilliseconds,
50
+ milestone,
51
+ phase,
52
+ pollCount,
53
+ slowestRoundTripInMilliseconds,
54
+ timeoutInMilliseconds
55
+ } = params;
56
+ return `${PHASE_DESCRIPTIONS[phase]} within ${String(timeoutInMilliseconds)}ms (elapsed ${String(elapsedInMilliseconds)}ms). Furthest progress: ${MILESTONE_DESCRIPTIONS[milestone]}. Probed ${String(pollCount)} time(s), slowest round-trip ${String(slowestRoundTripInMilliseconds)}ms. A handful of probes each taking tens of seconds means a contended guest, not a slow Obsidian \u2014 let the emulator go idle before the run, or raise \`deviceIdleTimeoutInMilliseconds\`.`;
57
+ }
58
+ function checkAppStarted(milestone) {
59
+ return compareAppStartupMilestones(milestone, APP_STARTED_MILESTONE) >= 0;
60
+ }
61
+ function checkLayoutReady(milestone) {
62
+ return milestone === "layout-ready";
63
+ }
64
+ function classifyAppStartupProbe(probeResult) {
65
+ if (!probeResult) {
66
+ return "no-webview";
67
+ }
68
+ if (!probeResult.hasApp) {
69
+ return "no-app";
70
+ }
71
+ if (!probeResult.hasWorkspace) {
72
+ return "no-workspace";
73
+ }
74
+ return probeResult.isLayoutReady ? "layout-ready" : "workspace-not-ready";
75
+ }
76
+ function compareAppStartupMilestones(left, right) {
77
+ return MILESTONE_ORDER.indexOf(left) - MILESTONE_ORDER.indexOf(right);
78
+ }
79
+ // Annotate the CommonJS export names for ESM import in node:
80
+ 0 && (module.exports = {
81
+ buildStartupTimeoutMessage,
82
+ checkAppStarted,
83
+ checkLayoutReady,
84
+ classifyAppStartupProbe,
85
+ compareAppStartupMilestones
86
+ });
87
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2FwcC1zdGFydHVwLXByb2dyZXNzLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogUHVyZSBoZWxwZXJzIGZvciB0cmFja2luZyBob3cgZmFyIE9ic2lkaWFuIE1vYmlsZSBoYXMgZ290IHRocm91Z2ggaXRzIHN0YXJ0dXBcbiAqIGFmdGVyIGBsb2NhdGlvbi5yZWxvYWQoKWAsIGFuZCBmb3IgZGVzY3JpYmluZyB3aGVyZSBpdCBzdGFsbGVkIHdoZW4gYSBidWRnZXRcbiAqIHJ1bnMgb3V0LlxuICpcbiAqIFN0YXJ0dXAgaXMgd2F0Y2hlZCBhcyBhICoqbGFkZGVyIG9mIG1pbGVzdG9uZXMqKiwgbm90IGEgc2luZ2xlIGJvb2xlYW4sXG4gKiBiZWNhdXNlIHRoZSB0d28gaGFsdmVzIG9mIGl0IGNvc3Qgd2lsZGx5IGRpZmZlcmVudCBhbW91bnRzIG9mIHRpbWUgYW5kIG9ubHlcbiAqIG9uZSBvZiB0aGVtIGlzIE9ic2lkaWFuJ3MgZmF1bHQuIFJlYWNoaW5nIGBnbG9iYWxUaGlzLmFwcGAgaXMgdGhlIGFwcCBjb2xkXG4gKiBzdGFydCBcdTIwMTQgdGhlIFdlYlZpZXcgcmVsb2FkaW5nLCB0aGUgZ3Vlc3Qgc3RpbGwgY2h1cm5pbmcgXHUyMDE0IGFuZCBvbiBhIGNvbGQgb3JcbiAqIGNvbnRlbmRlZCBlbXVsYXRvciBpdCBjYW4gdGFrZSBtaW51dGVzLiBFdmVyeXRoaW5nIGFmdGVyIGl0IGlzIE9ic2lkaWFuXG4gKiBvcGVuaW5nIHRoZSB2YXVsdCBhbmQgbG9hZGluZyBwbHVnaW5zLCB3aGljaCAqKkwxOSoqIG1lYXN1cmVkIGF0IH4xcyAoXHUyMjY0OC40c1xuICogdW5kZXIgMTItY29yZSArIGRpc2sgKyBtZW1vcnkgc3RyZXNzKS4gQ2hhcmdpbmcgYm90aCB0byBvbmUgOTBzIHdhbGwgY2xvY2sgaXNcbiAqIHdoYXQgbWFkZSBhIGZpcnN0IHJ1biBhZnRlciBhIG1hY2hpbmUgcmVzdGFydCBmYWlsIGJ5IGRlc2lnbiwgc28gdGhlIHRyYW5zcG9ydFxuICogcnVucyB0aGVtIGFzIHR3byBidWRnZXRzIGFuZCB1c2VzIHRoZXNlIGhlbHBlcnMgdG8gdGVsbCB0aGVtIGFwYXJ0LlxuICpcbiAqIEtlcHQgc2VwYXJhdGUgZnJvbSB0aGUgaW50ZWdyYXRpb24tb25seSBgdHJhbnNwb3J0LWFwcGl1bWAgKGV4Y2x1ZGVkIGZyb20gdW5pdFxuICogdGVzdHMpIHNvIHRoZSBjbGFzc2lmaWNhdGlvbiBhbmQgbWVzc2FnZSBmb3JtYXR0aW5nIHN0YXkgdW5pdC10ZXN0YWJsZSBcdTIwMTQgdGhlXG4gKiBwb2xsaW5nIGl0c2VsZiBuZWVkcyBhIHJlYWwgZGV2aWNlLlxuICovXG5cbi8qKlxuICogSG93IGZhciBPYnNpZGlhbiBoYXMgZ290IHRocm91Z2ggaXRzIHN0YXJ0dXAsIGFzIHNlZW4gZnJvbSBvbmUgV2ViVmlldyBwcm9iZS5cbiAqXG4gKiBPcmRlcmVkIGZyb20gbGVhc3QgdG8gbW9zdCBhZHZhbmNlZDsge0BsaW5rIGNvbXBhcmVBcHBTdGFydHVwTWlsZXN0b25lc31cbiAqIHJlbGllcyBvbiB0aGF0IG9yZGVyLlxuICovXG5leHBvcnQgdHlwZSBBcHBTdGFydHVwTWlsZXN0b25lID1cbiAgfCAnbGF5b3V0LXJlYWR5J1xuICB8ICduby1hcHAnXG4gIHwgJ25vLXdlYnZpZXcnXG4gIHwgJ25vLXdvcmtzcGFjZSdcbiAgfCAnd29ya3NwYWNlLW5vdC1yZWFkeSc7XG5cbi8qKlxuICogV2hpY2ggb2YgdGhlIHR3byBzdGFydHVwIGJ1ZGdldHMgd2FzIGJlaW5nIHNwZW50IHdoZW4gaXQgcmFuIG91dC5cbiAqL1xuZXhwb3J0IHR5cGUgQXBwU3RhcnR1cFBoYXNlID0gJ2FwcC1zdGFydCcgfCAnbGF5b3V0LXJlYWR5JztcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgYnVpbGRTdGFydHVwVGltZW91dE1lc3NhZ2V9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkU3RhcnR1cFRpbWVvdXRNZXNzYWdlUGFyYW1zIHtcbiAgLyoqXG4gIEhvdyBsb25nIHRoaXMgcGhhc2UncyBidWRnZXQgaGFkIGJlZW4gc3BlbnQgd2hlbiBpdCByYW4gb3V0LlxuICAgKi9cbiAgcmVhZG9ubHkgZWxhcHNlZEluTWlsbGlzZWNvbmRzOiBudW1iZXI7XG5cbiAgLyoqXG4gIFRoZSBmdXJ0aGVzdCBtaWxlc3RvbmUgcmVhY2hlZCBiZWZvcmUgdGhlIGJ1ZGdldCByYW4gb3V0LlxuICAgKi9cbiAgcmVhZG9ubHkgbWlsZXN0b25lOiBBcHBTdGFydHVwTWlsZXN0b25lO1xuXG4gIC8qKlxuICBUaGUgcGhhc2Ugd2hvc2UgYnVkZ2V0IHJhbiBvdXQuXG4gICAqL1xuICByZWFkb25seSBwaGFzZTogQXBwU3RhcnR1cFBoYXNlO1xuXG4gIC8qKlxuICBIb3cgbWFueSBwcm9iZXMgd2VyZSBtYWRlIGR1cmluZyB0aGUgcGhhc2UuXG4gICAqL1xuICByZWFkb25seSBwb2xsQ291bnQ6IG51bWJlcjtcblxuICAvKipcbiAgVGhlIHNsb3dlc3Qgc2luZ2xlIHByb2JlIHJvdW5kLXRyaXAgb2JzZXJ2ZWQgZHVyaW5nIHRoZSBwaGFzZS5cbiAgICovXG4gIHJlYWRvbmx5IHNsb3dlc3RSb3VuZFRyaXBJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICBUaGUgYnVkZ2V0IHRoYXQgcmFuIG91dC5cbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xufVxuXG4vKipcbiAqIFRoZSByYXcgc2hhcGUgYSBXZWJWaWV3IHN0YXJ0dXAgcHJvYmUgcmVwb3J0cyBiYWNrLlxuICpcbiAqIE1pcnJvcnMgd2hhdCB0aGUgaW5qZWN0ZWQgcHJvYmUgZnVuY3Rpb24gY2FuIG9ic2VydmUgd2l0aG91dCBpbXBvcnRpbmdcbiAqIGFueXRoaW5nOiB3aGV0aGVyIHRoZSBnbG9iYWwgYGFwcGAgb2JqZWN0IGV4aXN0cyB5ZXQsIHdoZXRoZXIgaXRzIGB3b3Jrc3BhY2VgXG4gKiBkb2VzLCBhbmQgd2hldGhlciB0aGF0IHdvcmtzcGFjZSBoYXMgZmluaXNoZWQgbGF5aW5nIG91dC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGFydHVwUHJvYmVSZXN1bHQge1xuICAvKipcbiAgV2hldGhlciBgZ2xvYmFsVGhpcy5hcHBgIGlzIGRlZmluZWQuXG4gICAqL1xuICByZWFkb25seSBoYXNBcHA6IGJvb2xlYW47XG5cbiAgLyoqXG4gIFdoZXRoZXIgYGFwcC53b3Jrc3BhY2VgIGlzIGRlZmluZWQuXG4gICAqL1xuICByZWFkb25seSBoYXNXb3Jrc3BhY2U6IGJvb2xlYW47XG5cbiAgLyoqXG4gIFdoZXRoZXIgYGFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHlgIGlzIHRydXRoeS5cbiAgICovXG4gIHJlYWRvbmx5IGlzTGF5b3V0UmVhZHk6IGJvb2xlYW47XG59XG5cbi8qKlxuICogVGhlIG1pbGVzdG9uZSBsYWRkZXIsIGxlYXN0IHRvIG1vc3QgYWR2YW5jZWQuIFRoZSBpbmRleCBpbiB0aGlzIGFycmF5ICppcypcbiAqIHRoZSBvcmRlcmluZyB1c2VkIGJ5IHtAbGluayBjb21wYXJlQXBwU3RhcnR1cE1pbGVzdG9uZXN9LlxuICovXG5jb25zdCBNSUxFU1RPTkVfT1JERVI6IHJlYWRvbmx5IEFwcFN0YXJ0dXBNaWxlc3RvbmVbXSA9IFtcbiAgJ25vLXdlYnZpZXcnLFxuICAnbm8tYXBwJyxcbiAgJ25vLXdvcmtzcGFjZScsXG4gICd3b3Jrc3BhY2Utbm90LXJlYWR5JyxcbiAgJ2xheW91dC1yZWFkeSdcbl07XG5cbi8qKlxuICogVGhlIG1pbGVzdG9uZSBhdCB3aGljaCB0aGUgYXBwLXN0YXJ0IHBoYXNlIGlzIHNhdGlzZmllZDogYGdsb2JhbFRoaXMuYXBwYFxuICogZXhpc3RzLCBzbyB0aGUgV2ViVmlldyBoYXMgcmVsb2FkZWQgYW5kIE9ic2lkaWFuJ3Mgb3duIGJvb3QgaGFzIGJlZ3VuLiBXaGF0XG4gKiByZW1haW5zIGZyb20gaGVyZSBpcyBPYnNpZGlhbiB3b3JrLCB3aGljaCB0aGUgdGlnaHQgbGF5b3V0LXJlYWR5IGJ1ZGdldFxuICogY292ZXJzLlxuICovXG5jb25zdCBBUFBfU1RBUlRFRF9NSUxFU1RPTkU6IEFwcFN0YXJ0dXBNaWxlc3RvbmUgPSAnbm8td29ya3NwYWNlJztcblxuLyoqXG4gKiBIdW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbnMgb2YgZWFjaCBtaWxlc3RvbmUsIHVzZWQgaW4gdGhlIHRpbWVvdXQgbWVzc2FnZSBzb1xuICogdGhlIGZhaWx1cmUgbmFtZXMgd2hhdCBuZXZlciBoYXBwZW5lZCBpbnN0ZWFkIG9mIG9ubHkgd2hhdCB3YXMgaG9wZWQgZm9yLlxuICovXG5jb25zdCBNSUxFU1RPTkVfREVTQ1JJUFRJT05TOiBSZWNvcmQ8QXBwU3RhcnR1cE1pbGVzdG9uZSwgc3RyaW5nPiA9IHtcbiAgJ2xheW91dC1yZWFkeSc6ICd0aGUgd29ya3NwYWNlIGZpbmlzaGVkIGxheWluZyBvdXQnLFxuICAnbm8tYXBwJzogJ3RoZSBXZWJWaWV3IGFuc3dlcmVkLCBidXQgYGdsb2JhbFRoaXMuYXBwYCBuZXZlciBhcHBlYXJlZCcsXG4gICduby13ZWJ2aWV3JzogJ3RoZSBXZWJWaWV3IG5ldmVyIGFuc3dlcmVkIGEgc2luZ2xlIHByb2JlJyxcbiAgJ25vLXdvcmtzcGFjZSc6ICdgZ2xvYmFsVGhpcy5hcHBgIGFwcGVhcmVkLCBidXQgYGFwcC53b3Jrc3BhY2VgIG5ldmVyIGRpZCcsXG4gICd3b3Jrc3BhY2Utbm90LXJlYWR5JzogJ2BhcHAud29ya3NwYWNlYCBleGlzdHMsIGJ1dCBgbGF5b3V0UmVhZHlgIG5ldmVyIGJlY2FtZSB0cnVlJ1xufTtcblxuLyoqXG4gKiBXaGF0IGVhY2ggcGhhc2Ugd2FzIHdhaXRpbmcgZm9yLCB1c2VkIGluIHRoZSB0aW1lb3V0IG1lc3NhZ2UuXG4gKi9cbmNvbnN0IFBIQVNFX0RFU0NSSVBUSU9OUzogUmVjb3JkPEFwcFN0YXJ0dXBQaGFzZSwgc3RyaW5nPiA9IHtcbiAgJ2FwcC1zdGFydCc6ICdPYnNpZGlhbiBNb2JpbGUgZGlkIG5vdCBmaW5pc2ggc3RhcnRpbmcnLFxuICAnbGF5b3V0LXJlYWR5JzogJ09ic2lkaWFuIGxheW91dCBkaWQgbm90IGJlY29tZSByZWFkeSdcbn07XG5cbi8qKlxuICogQnVpbGRzIHRoZSBkaWFnbm9zdGljIG1lc3NhZ2UgZm9yIGEgc3RhcnR1cCBidWRnZXQgdGhhdCByYW4gb3V0LlxuICpcbiAqIEl0IG5hbWVzIHRoZSBtaWxlc3RvbmUgYWN0dWFsbHkgcmVhY2hlZCwgdGhlIHBvbGwgY291bnQgYW5kIHRoZSBzbG93ZXN0IHByb2JlXG4gKiByb3VuZC10cmlwLCBiZWNhdXNlIHRob3NlIHRocmVlIHRvZ2V0aGVyIHNlcGFyYXRlIHRoZSBmYWlsdXJlIG1vZGVzICoqTDE5KipcbiAqIGNvdWxkIG5vdCB0ZWxsIGFwYXJ0IGZyb20gdGhlIG9sZCBtZXNzYWdlOiBhIGdlbnVpbmUgT2JzaWRpYW4gc2xvd2Rvd24gc2hvd3NcbiAqIG1hbnkgZmFzdCBwb2xscyBzdGFsbGVkIGF0IG9uZSBtaWxlc3RvbmUsIHdoZXJlYXMgYSBjb250ZW5kZWQgZ3Vlc3Qgc2hvd3MgYVxuICogaGFuZGZ1bCBvZiBwb2xscyBlYWNoIHRha2luZyB0ZW5zIG9mIHNlY29uZHMuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwaGFzZSwgdGhlIG1pbGVzdG9uZSByZWFjaGVkLCBhbmQgdGhlIHRpbWluZyBldmlkZW5jZS5cbiAqIEByZXR1cm5zIEEgaHVtYW4tcmVhZGFibGUgZXJyb3IgbWVzc2FnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkU3RhcnR1cFRpbWVvdXRNZXNzYWdlKHBhcmFtczogQnVpbGRTdGFydHVwVGltZW91dE1lc3NhZ2VQYXJhbXMpOiBzdHJpbmcge1xuICBjb25zdCB7XG4gICAgZWxhcHNlZEluTWlsbGlzZWNvbmRzLFxuICAgIG1pbGVzdG9uZSxcbiAgICBwaGFzZSxcbiAgICBwb2xsQ291bnQsXG4gICAgc2xvd2VzdFJvdW5kVHJpcEluTWlsbGlzZWNvbmRzLFxuICAgIHRpbWVvdXRJbk1pbGxpc2Vjb25kc1xuICB9ID0gcGFyYW1zO1xuXG4gIHJldHVybiBgJHtQSEFTRV9ERVNDUklQVElPTlNbcGhhc2VdfSB3aXRoaW4gJHtTdHJpbmcodGltZW91dEluTWlsbGlzZWNvbmRzKX1tcyBgXG4gICAgKyBgKGVsYXBzZWQgJHtTdHJpbmcoZWxhcHNlZEluTWlsbGlzZWNvbmRzKX1tcykuIEZ1cnRoZXN0IHByb2dyZXNzOiAke01JTEVTVE9ORV9ERVNDUklQVElPTlNbbWlsZXN0b25lXX0uIGBcbiAgICArIGBQcm9iZWQgJHtTdHJpbmcocG9sbENvdW50KX0gdGltZShzKSwgc2xvd2VzdCByb3VuZC10cmlwICR7U3RyaW5nKHNsb3dlc3RSb3VuZFRyaXBJbk1pbGxpc2Vjb25kcyl9bXMuIGBcbiAgICArICdBIGhhbmRmdWwgb2YgcHJvYmVzIGVhY2ggdGFraW5nIHRlbnMgb2Ygc2Vjb25kcyBtZWFucyBhIGNvbnRlbmRlZCBndWVzdCwgbm90IGEgc2xvdyBPYnNpZGlhbiBcdTIwMTQgJ1xuICAgICsgJ2xldCB0aGUgZW11bGF0b3IgZ28gaWRsZSBiZWZvcmUgdGhlIHJ1biwgb3IgcmFpc2UgYGRldmljZUlkbGVUaW1lb3V0SW5NaWxsaXNlY29uZHNgLic7XG59XG5cbi8qKlxuICogUmVwb3J0cyB3aGV0aGVyIHRoZSBhcHAtc3RhcnQgcGhhc2UgaXMgc2F0aXNmaWVkIGF0IHRoaXMgbWlsZXN0b25lLlxuICpcbiAqIEBwYXJhbSBtaWxlc3RvbmUgLSBUaGUgbWlsZXN0b25lIHRoZSBsYXRlc3QgcHJvYmUgcmVwb3J0ZWQuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgb25jZSBgZ2xvYmFsVGhpcy5hcHBgIGV4aXN0cywgc28gdGhlIGxheW91dC1yZWFkeSBidWRnZXQgbWF5IHN0YXJ0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tBcHBTdGFydGVkKG1pbGVzdG9uZTogQXBwU3RhcnR1cE1pbGVzdG9uZSk6IGJvb2xlYW4ge1xuICByZXR1cm4gY29tcGFyZUFwcFN0YXJ0dXBNaWxlc3RvbmVzKG1pbGVzdG9uZSwgQVBQX1NUQVJURURfTUlMRVNUT05FKSA+PSAwO1xufVxuXG4vKipcbiAqIFJlcG9ydHMgd2hldGhlciB0aGUgbGF5b3V0LXJlYWR5IHBoYXNlIGlzIHNhdGlzZmllZCBhdCB0aGlzIG1pbGVzdG9uZS5cbiAqXG4gKiBAcGFyYW0gbWlsZXN0b25lIC0gVGhlIG1pbGVzdG9uZSB0aGUgbGF0ZXN0IHByb2JlIHJlcG9ydGVkLlxuICogQHJldHVybnMgYHRydWVgIG9uY2UgdGhlIHdvcmtzcGFjZSBoYXMgZmluaXNoZWQgbGF5aW5nIG91dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrTGF5b3V0UmVhZHkobWlsZXN0b25lOiBBcHBTdGFydHVwTWlsZXN0b25lKTogYm9vbGVhbiB7XG4gIHJldHVybiBtaWxlc3RvbmUgPT09ICdsYXlvdXQtcmVhZHknO1xufVxuXG4vKipcbiAqIFR1cm5zIGEgV2ViVmlldyBwcm9iZSBpbnRvIGEgbWlsZXN0b25lLlxuICpcbiAqIEEgcHJvYmUgdGhhdCBjb3VsZCBub3QgcnVuIGF0IGFsbCBcdTIwMTQgYHVuZGVmaW5lZGAsIGJlY2F1c2UgYGJyb3dzZXIuZXhlY3V0ZSgpYFxuICogdGhyZXcgd2hpbGUgdGhlIHBhZ2Ugd2FzIG1pZC1yZWxvYWQgXHUyMDE0IGlzIHRoZSBsZWFzdCBhZHZhbmNlZCBtaWxlc3RvbmUgcmF0aGVyXG4gKiB0aGFuIGFuIGVycm9yOiBkdXJpbmcgYSByZWxvYWQgaXQgaXMgdGhlIGV4cGVjdGVkIHJlYWRpbmcuXG4gKlxuICogQHBhcmFtIHByb2JlUmVzdWx0IC0gV2hhdCB0aGUgcHJvYmUgcmVwb3J0ZWQsIG9yIGB1bmRlZmluZWRgIHdoZW4gaXQgdGhyZXcuXG4gKiBAcmV0dXJucyBUaGUgbWlsZXN0b25lIHRoYXQgcmVhZGluZyByZXByZXNlbnRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2xhc3NpZnlBcHBTdGFydHVwUHJvYmUocHJvYmVSZXN1bHQ6IFN0YXJ0dXBQcm9iZVJlc3VsdCB8IHVuZGVmaW5lZCk6IEFwcFN0YXJ0dXBNaWxlc3RvbmUge1xuICBpZiAoIXByb2JlUmVzdWx0KSB7XG4gICAgcmV0dXJuICduby13ZWJ2aWV3JztcbiAgfVxuICBpZiAoIXByb2JlUmVzdWx0Lmhhc0FwcCkge1xuICAgIHJldHVybiAnbm8tYXBwJztcbiAgfVxuICBpZiAoIXByb2JlUmVzdWx0Lmhhc1dvcmtzcGFjZSkge1xuICAgIHJldHVybiAnbm8td29ya3NwYWNlJztcbiAgfVxuICByZXR1cm4gcHJvYmVSZXN1bHQuaXNMYXlvdXRSZWFkeSA/ICdsYXlvdXQtcmVhZHknIDogJ3dvcmtzcGFjZS1ub3QtcmVhZHknO1xufVxuXG4vKipcbiAqIE9yZGVycyB0d28gbWlsZXN0b25lcyBvbiB0aGUgc3RhcnR1cCBsYWRkZXIuXG4gKlxuICogQHBhcmFtIGxlZnQgLSBUaGUgZmlyc3QgbWlsZXN0b25lLlxuICogQHBhcmFtIHJpZ2h0IC0gVGhlIHNlY29uZCBtaWxlc3RvbmUuXG4gKiBAcmV0dXJucyBBIG5lZ2F0aXZlIG51bWJlciB3aGVuIGBsZWZ0YCBpcyBsZXNzIGFkdmFuY2VkLCBgMGAgd2hlbiBlcXVhbCwgYSBwb3NpdGl2ZSBudW1iZXIgd2hlbiBtb3JlIGFkdmFuY2VkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29tcGFyZUFwcFN0YXJ0dXBNaWxlc3RvbmVzKGxlZnQ6IEFwcFN0YXJ0dXBNaWxlc3RvbmUsIHJpZ2h0OiBBcHBTdGFydHVwTWlsZXN0b25lKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1JTEVTVE9ORV9PUkRFUi5pbmRleE9mKGxlZnQpIC0gTUlMRVNUT05FX09SREVSLmluZGV4T2YocmlnaHQpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBdUdBLE1BQU0sa0JBQWtEO0FBQUEsRUFDdEQ7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQ0Y7QUFRQSxNQUFNLHdCQUE2QztBQU1uRCxNQUFNLHlCQUE4RDtBQUFBLEVBQ2xFLGdCQUFnQjtBQUFBLEVBQ2hCLFVBQVU7QUFBQSxFQUNWLGNBQWM7QUFBQSxFQUNkLGdCQUFnQjtBQUFBLEVBQ2hCLHVCQUF1QjtBQUN6QjtBQUtBLE1BQU0scUJBQXNEO0FBQUEsRUFDMUQsYUFBYTtBQUFBLEVBQ2IsZ0JBQWdCO0FBQ2xCO0FBY08sU0FBUywyQkFBMkIsUUFBa0Q7QUFDM0YsUUFBTTtBQUFBLElBQ0o7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLEVBQ0YsSUFBSTtBQUVKLFNBQU8sR0FBRyxtQkFBbUIsS0FBSyxDQUFDLFdBQVcsT0FBTyxxQkFBcUIsQ0FBQyxlQUMzRCxPQUFPLHFCQUFxQixDQUFDLDJCQUEyQix1QkFBdUIsU0FBUyxDQUFDLFlBQzNGLE9BQU8sU0FBUyxDQUFDLGdDQUFnQyxPQUFPLDhCQUE4QixDQUFDO0FBR3ZHO0FBUU8sU0FBUyxnQkFBZ0IsV0FBeUM7QUFDdkUsU0FBTyw0QkFBNEIsV0FBVyxxQkFBcUIsS0FBSztBQUMxRTtBQVFPLFNBQVMsaUJBQWlCLFdBQXlDO0FBQ3hFLFNBQU8sY0FBYztBQUN2QjtBQVlPLFNBQVMsd0JBQXdCLGFBQWtFO0FBQ3hHLE1BQUksQ0FBQyxhQUFhO0FBQ2hCLFdBQU87QUFBQSxFQUNUO0FBQ0EsTUFBSSxDQUFDLFlBQVksUUFBUTtBQUN2QixXQUFPO0FBQUEsRUFDVDtBQUNBLE1BQUksQ0FBQyxZQUFZLGNBQWM7QUFDN0IsV0FBTztBQUFBLEVBQ1Q7QUFDQSxTQUFPLFlBQVksZ0JBQWdCLGlCQUFpQjtBQUN0RDtBQVNPLFNBQVMsNEJBQTRCLE1BQTJCLE9BQW9DO0FBQ3pHLFNBQU8sZ0JBQWdCLFFBQVEsSUFBSSxJQUFJLGdCQUFnQixRQUFRLEtBQUs7QUFDdEU7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -0,0 +1,128 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Pure helpers for tracking how far Obsidian Mobile has got through its startup
5
+ * after `location.reload()`, and for describing where it stalled when a budget
6
+ * runs out.
7
+ *
8
+ * Startup is watched as a **ladder of milestones**, not a single boolean,
9
+ * because the two halves of it cost wildly different amounts of time and only
10
+ * one of them is Obsidian's fault. Reaching `globalThis.app` is the app cold
11
+ * start — the WebView reloading, the guest still churning — and on a cold or
12
+ * contended emulator it can take minutes. Everything after it is Obsidian
13
+ * opening the vault and loading plugins, which **L19** measured at ~1s (≤8.4s
14
+ * under 12-core + disk + memory stress). Charging both to one 90s wall clock is
15
+ * what made a first run after a machine restart fail by design, so the transport
16
+ * runs them as two budgets and uses these helpers to tell them apart.
17
+ *
18
+ * Kept separate from the integration-only `transport-appium` (excluded from unit
19
+ * tests) so the classification and message formatting stay unit-testable — the
20
+ * polling itself needs a real device.
21
+ */
22
+ /**
23
+ * How far Obsidian has got through its startup, as seen from one WebView probe.
24
+ *
25
+ * Ordered from least to most advanced; {@link compareAppStartupMilestones}
26
+ * relies on that order.
27
+ */
28
+ export type AppStartupMilestone = 'layout-ready' | 'no-app' | 'no-webview' | 'no-workspace' | 'workspace-not-ready';
29
+ /**
30
+ * Which of the two startup budgets was being spent when it ran out.
31
+ */
32
+ export type AppStartupPhase = 'app-start' | 'layout-ready';
33
+ /**
34
+ * Parameters for {@link buildStartupTimeoutMessage}.
35
+ */
36
+ export interface BuildStartupTimeoutMessageParams {
37
+ /**
38
+ How long this phase's budget had been spent when it ran out.
39
+ */
40
+ readonly elapsedInMilliseconds: number;
41
+ /**
42
+ The furthest milestone reached before the budget ran out.
43
+ */
44
+ readonly milestone: AppStartupMilestone;
45
+ /**
46
+ The phase whose budget ran out.
47
+ */
48
+ readonly phase: AppStartupPhase;
49
+ /**
50
+ How many probes were made during the phase.
51
+ */
52
+ readonly pollCount: number;
53
+ /**
54
+ The slowest single probe round-trip observed during the phase.
55
+ */
56
+ readonly slowestRoundTripInMilliseconds: number;
57
+ /**
58
+ The budget that ran out.
59
+ */
60
+ readonly timeoutInMilliseconds: number;
61
+ }
62
+ /**
63
+ * The raw shape a WebView startup probe reports back.
64
+ *
65
+ * Mirrors what the injected probe function can observe without importing
66
+ * anything: whether the global `app` object exists yet, whether its `workspace`
67
+ * does, and whether that workspace has finished laying out.
68
+ */
69
+ export interface StartupProbeResult {
70
+ /**
71
+ Whether `globalThis.app` is defined.
72
+ */
73
+ readonly hasApp: boolean;
74
+ /**
75
+ Whether `app.workspace` is defined.
76
+ */
77
+ readonly hasWorkspace: boolean;
78
+ /**
79
+ Whether `app.workspace.layoutReady` is truthy.
80
+ */
81
+ readonly isLayoutReady: boolean;
82
+ }
83
+ /**
84
+ * Builds the diagnostic message for a startup budget that ran out.
85
+ *
86
+ * It names the milestone actually reached, the poll count and the slowest probe
87
+ * round-trip, because those three together separate the failure modes **L19**
88
+ * could not tell apart from the old message: a genuine Obsidian slowdown shows
89
+ * many fast polls stalled at one milestone, whereas a contended guest shows a
90
+ * handful of polls each taking tens of seconds.
91
+ *
92
+ * @param params - The phase, the milestone reached, and the timing evidence.
93
+ * @returns A human-readable error message.
94
+ */
95
+ export declare function buildStartupTimeoutMessage(params: BuildStartupTimeoutMessageParams): string;
96
+ /**
97
+ * Reports whether the app-start phase is satisfied at this milestone.
98
+ *
99
+ * @param milestone - The milestone the latest probe reported.
100
+ * @returns `true` once `globalThis.app` exists, so the layout-ready budget may start.
101
+ */
102
+ export declare function checkAppStarted(milestone: AppStartupMilestone): boolean;
103
+ /**
104
+ * Reports whether the layout-ready phase is satisfied at this milestone.
105
+ *
106
+ * @param milestone - The milestone the latest probe reported.
107
+ * @returns `true` once the workspace has finished laying out.
108
+ */
109
+ export declare function checkLayoutReady(milestone: AppStartupMilestone): boolean;
110
+ /**
111
+ * Turns a WebView probe into a milestone.
112
+ *
113
+ * A probe that could not run at all — `undefined`, because `browser.execute()`
114
+ * threw while the page was mid-reload — is the least advanced milestone rather
115
+ * than an error: during a reload it is the expected reading.
116
+ *
117
+ * @param probeResult - What the probe reported, or `undefined` when it threw.
118
+ * @returns The milestone that reading represents.
119
+ */
120
+ export declare function classifyAppStartupProbe(probeResult: StartupProbeResult | undefined): AppStartupMilestone;
121
+ /**
122
+ * Orders two milestones on the startup ladder.
123
+ *
124
+ * @param left - The first milestone.
125
+ * @param right - The second milestone.
126
+ * @returns A negative number when `left` is less advanced, `0` when equal, a positive number when more advanced.
127
+ */
128
+ export declare function compareAppStartupMilestones(left: AppStartupMilestone, right: AppStartupMilestone): number;