obsidian-integration-testing 11.0.0 → 12.1.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 (234) 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/android-sdk.cjs +52 -0
  4. package/dist/lib/cjs/android-sdk.d.cts +29 -0
  5. package/dist/lib/cjs/app-startup-progress.cjs +87 -0
  6. package/dist/lib/cjs/app-startup-progress.d.cts +128 -0
  7. package/dist/lib/cjs/appium-server-marker.cjs +112 -0
  8. package/dist/lib/cjs/appium-server-marker.d.cts +103 -0
  9. package/dist/lib/cjs/avd-probe-verdict.cjs +90 -0
  10. package/dist/lib/cjs/avd-probe-verdict.d.cts +175 -0
  11. package/dist/lib/cjs/cli.cjs +104 -19
  12. package/dist/lib/cjs/cli.d.cts +16 -8
  13. package/dist/lib/cjs/community-plugin-registry.cjs +52 -0
  14. package/dist/lib/cjs/community-plugin-registry.d.cts +116 -0
  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/context-provider.cjs +12 -1
  22. package/dist/lib/cjs/context-provider.d.cts +26 -3
  23. package/dist/lib/cjs/demo-vault-bootstrap.cjs +148 -0
  24. package/dist/lib/cjs/demo-vault-bootstrap.d.cts +114 -0
  25. package/dist/lib/cjs/demo-vault-populate.cjs +38 -10
  26. package/dist/lib/cjs/demo-vault-populate.d.cts +70 -0
  27. package/dist/lib/cjs/device-readiness.cjs +38 -3
  28. package/dist/lib/cjs/device-readiness.d.cts +83 -9
  29. package/dist/lib/cjs/emulator-arguments.cjs +6 -2
  30. package/dist/lib/cjs/emulator-arguments.d.cts +26 -0
  31. package/dist/lib/cjs/emulator-backend.cjs +71 -0
  32. package/dist/lib/cjs/emulator-backend.d.cts +76 -0
  33. package/dist/lib/cjs/emulator-liveness.cjs +72 -0
  34. package/dist/lib/cjs/emulator-liveness.d.cts +158 -0
  35. package/dist/lib/cjs/emulator-snapshot.cjs +57 -0
  36. package/dist/lib/cjs/emulator-snapshot.d.cts +68 -0
  37. package/dist/lib/cjs/eval-in-obsidian.cjs +1 -1
  38. package/dist/lib/cjs/eval-in-obsidian.d.cts +42 -13
  39. package/dist/lib/cjs/global-setup-core.cjs +30 -30
  40. package/dist/lib/cjs/global-setup-core.d.cts +27 -2
  41. package/dist/lib/cjs/headless-vault-config.cjs +51 -0
  42. package/dist/lib/cjs/headless-vault-config.d.cts +67 -0
  43. package/dist/lib/cjs/index.cjs +24 -1
  44. package/dist/lib/cjs/index.d.cts +14 -5
  45. package/dist/lib/cjs/installer-asset.cjs +1 -1
  46. package/dist/lib/cjs/installer-asset.d.cts +1 -1
  47. package/dist/lib/cjs/integration-setup-failed-error.cjs +62 -0
  48. package/dist/lib/cjs/integration-setup-failed-error.d.cts +66 -0
  49. package/dist/lib/cjs/jest/global-setup.cjs +2 -2
  50. package/dist/lib/cjs/jest/global-setup.d.cts +5 -1
  51. package/dist/lib/cjs/kill-process-tree.cjs +18 -7
  52. package/dist/lib/cjs/kill-process-tree.d.cts +10 -2
  53. package/dist/lib/cjs/library.cjs +1 -1
  54. package/dist/lib/cjs/mobile-input.cjs +173 -0
  55. package/dist/lib/cjs/mobile-input.d.cts +156 -0
  56. package/dist/lib/cjs/namespace-bootstrap.cjs +92 -9
  57. package/dist/lib/cjs/obsidian-installer.cjs +1 -1
  58. package/dist/lib/cjs/obsidian-instance.cjs +52 -3
  59. package/dist/lib/cjs/obsidian-instance.d.cts +12 -0
  60. package/dist/lib/cjs/obsidian-metadata.cjs +123 -17
  61. package/dist/lib/cjs/obsidian-metadata.d.cts +17 -6
  62. package/dist/lib/cjs/obsidian-version-switch.cjs +3 -3
  63. package/dist/lib/cjs/open-obsidian-settings-tab.cjs +1 -1
  64. package/dist/lib/cjs/open-obsidian-settings-tab.d.cts +3 -2
  65. package/dist/lib/cjs/owned-instance-exit-marker.cjs +99 -0
  66. package/dist/lib/cjs/owned-instance-exit-marker.d.cts +106 -0
  67. package/dist/lib/cjs/owned-instance-exited-error.cjs +106 -0
  68. package/dist/lib/cjs/owned-instance-exited-error.d.cts +98 -0
  69. package/dist/lib/cjs/owned-vault-seed.cjs +9 -5
  70. package/dist/lib/cjs/owned-vault-seed.d.cts +24 -3
  71. package/dist/lib/cjs/parent-liveness.cjs +42 -5
  72. package/dist/lib/cjs/parent-liveness.d.cts +37 -5
  73. package/dist/lib/cjs/port-owner.cjs +61 -0
  74. package/dist/lib/cjs/port-owner.d.cts +47 -0
  75. package/dist/lib/cjs/process-capture.cjs +62 -0
  76. package/dist/lib/cjs/process-capture.d.cts +83 -0
  77. package/dist/lib/cjs/process-exit-message.cjs +14 -8
  78. package/dist/lib/cjs/process-exit-message.d.cts +37 -3
  79. package/dist/lib/cjs/process-liveness.cjs +51 -0
  80. package/dist/lib/cjs/process-liveness.d.cts +18 -0
  81. package/dist/lib/cjs/release-catalog.cjs +73 -0
  82. package/dist/lib/cjs/release-catalog.d.cts +125 -0
  83. package/dist/lib/cjs/run-version-matrix.cjs +1 -1
  84. package/dist/lib/cjs/run-version-matrix.d.cts +1 -1
  85. package/dist/lib/cjs/teardown-verdict.cjs +53 -0
  86. package/dist/lib/cjs/teardown-verdict.d.cts +69 -0
  87. package/dist/lib/cjs/temporary-vault.cjs +43 -8
  88. package/dist/lib/cjs/temporary-vault.d.cts +47 -5
  89. package/dist/lib/cjs/transport-appium.cjs +223 -17
  90. package/dist/lib/cjs/transport-appium.d.cts +104 -3
  91. package/dist/lib/cjs/transport-desktop-cdp.cjs +201 -6
  92. package/dist/lib/cjs/transport-desktop-cdp.d.cts +100 -0
  93. package/dist/lib/cjs/transport-factory.cjs +1165 -142
  94. package/dist/lib/cjs/transport-factory.d.cts +10 -1
  95. package/dist/lib/cjs/transport-options.cjs +11 -3
  96. package/dist/lib/cjs/transport-options.d.cts +131 -12
  97. package/dist/lib/cjs/transport.cjs +1 -1
  98. package/dist/lib/cjs/transport.d.cts +7 -1
  99. package/dist/lib/cjs/vault-plugin-install.cjs +40 -0
  100. package/dist/lib/cjs/vault-plugin-install.d.cts +64 -0
  101. package/dist/lib/cjs/vault-teardown-verdict.cjs +42 -0
  102. package/dist/lib/cjs/vault-teardown-verdict.d.cts +57 -0
  103. package/dist/lib/cjs/version-matrix.cjs +1 -1
  104. package/dist/lib/cjs/version-matrix.d.cts +2 -2
  105. package/dist/lib/cjs/vitest/global-setup.cjs +13 -7
  106. package/dist/lib/cjs/vitest/global-setup.d.cts +5 -1
  107. package/dist/lib/cjs/vitest/setup.cjs +2 -1
  108. package/dist/lib/cjs/vitest/setup.d.cts +5 -0
  109. package/dist/lib/cjs/vitest/typings.d.cts +6 -4
  110. package/dist/lib/cjs/webview-cdp.cjs +263 -0
  111. package/dist/lib/cjs/webview-cdp.d.cts +156 -0
  112. package/dist/lib/cjs/wedged-appium-server.cjs +113 -0
  113. package/dist/lib/cjs/wedged-appium-server.d.cts +187 -0
  114. package/dist/lib/esm/adb-device-list.d.mts +72 -0
  115. package/dist/lib/esm/adb-device-list.mjs +28 -0
  116. package/dist/lib/esm/android-sdk.d.mts +29 -0
  117. package/dist/lib/esm/android-sdk.mjs +18 -0
  118. package/dist/lib/esm/app-startup-progress.d.mts +128 -0
  119. package/dist/lib/esm/app-startup-progress.mjs +59 -0
  120. package/dist/lib/esm/appium-server-marker.d.mts +103 -0
  121. package/dist/lib/esm/appium-server-marker.mjs +89 -0
  122. package/dist/lib/esm/avd-probe-verdict.d.mts +175 -0
  123. package/dist/lib/esm/avd-probe-verdict.mjs +62 -0
  124. package/dist/lib/esm/cli.d.mts +16 -8
  125. package/dist/lib/esm/cli.mjs +110 -19
  126. package/dist/lib/esm/community-plugin-registry.d.mts +116 -0
  127. package/dist/lib/esm/community-plugin-registry.mjs +23 -0
  128. package/dist/lib/esm/config-directory-fallback-error.d.mts +64 -0
  129. package/dist/lib/esm/config-directory-fallback-error.mjs +33 -0
  130. package/dist/lib/esm/config-directory.d.mts +45 -0
  131. package/dist/lib/esm/config-directory.mjs +21 -0
  132. package/dist/lib/esm/connect-to-cdp.d.mts +19 -0
  133. package/dist/lib/esm/connect-to-cdp.mjs +13 -7
  134. package/dist/lib/esm/context-provider.d.mts +26 -3
  135. package/dist/lib/esm/context-provider.mjs +10 -1
  136. package/dist/lib/esm/demo-vault-bootstrap.d.mts +114 -0
  137. package/dist/lib/esm/demo-vault-bootstrap.mjs +127 -0
  138. package/dist/lib/esm/demo-vault-populate.d.mts +70 -0
  139. package/dist/lib/esm/demo-vault-populate.mjs +35 -9
  140. package/dist/lib/esm/device-readiness.d.mts +83 -9
  141. package/dist/lib/esm/device-readiness.mjs +34 -2
  142. package/dist/lib/esm/emulator-arguments.d.mts +26 -0
  143. package/dist/lib/esm/emulator-arguments.mjs +6 -2
  144. package/dist/lib/esm/emulator-backend.d.mts +76 -0
  145. package/dist/lib/esm/emulator-backend.mjs +45 -0
  146. package/dist/lib/esm/emulator-liveness.d.mts +158 -0
  147. package/dist/lib/esm/emulator-liveness.mjs +47 -0
  148. package/dist/lib/esm/emulator-snapshot.d.mts +68 -0
  149. package/dist/lib/esm/emulator-snapshot.mjs +32 -0
  150. package/dist/lib/esm/eval-in-obsidian.d.mts +42 -13
  151. package/dist/lib/esm/eval-in-obsidian.mjs +1 -1
  152. package/dist/lib/esm/global-setup-core.d.mts +27 -2
  153. package/dist/lib/esm/global-setup-core.mjs +34 -35
  154. package/dist/lib/esm/headless-vault-config.d.mts +67 -0
  155. package/dist/lib/esm/headless-vault-config.mjs +31 -0
  156. package/dist/lib/esm/index.d.mts +14 -5
  157. package/dist/lib/esm/index.mjs +26 -2
  158. package/dist/lib/esm/installer-asset.d.mts +1 -1
  159. package/dist/lib/esm/installer-asset.mjs +1 -1
  160. package/dist/lib/esm/integration-setup-failed-error.d.mts +66 -0
  161. package/dist/lib/esm/integration-setup-failed-error.mjs +38 -0
  162. package/dist/lib/esm/jest/global-setup.d.mts +5 -1
  163. package/dist/lib/esm/jest/global-setup.mjs +2 -2
  164. package/dist/lib/esm/kill-process-tree.d.mts +10 -2
  165. package/dist/lib/esm/kill-process-tree.mjs +16 -6
  166. package/dist/lib/esm/library.mjs +1 -1
  167. package/dist/lib/esm/mobile-input.d.mts +156 -0
  168. package/dist/lib/esm/mobile-input.mjs +144 -0
  169. package/dist/lib/esm/namespace-bootstrap.mjs +95 -9
  170. package/dist/lib/esm/obsidian-installer.mjs +1 -1
  171. package/dist/lib/esm/obsidian-instance.d.mts +12 -0
  172. package/dist/lib/esm/obsidian-instance.mjs +55 -3
  173. package/dist/lib/esm/obsidian-metadata.d.mts +17 -6
  174. package/dist/lib/esm/obsidian-metadata.mjs +123 -17
  175. package/dist/lib/esm/obsidian-version-switch.mjs +3 -3
  176. package/dist/lib/esm/open-obsidian-settings-tab.d.mts +3 -2
  177. package/dist/lib/esm/open-obsidian-settings-tab.mjs +1 -1
  178. package/dist/lib/esm/owned-instance-exit-marker.d.mts +106 -0
  179. package/dist/lib/esm/owned-instance-exit-marker.mjs +78 -0
  180. package/dist/lib/esm/owned-instance-exited-error.d.mts +98 -0
  181. package/dist/lib/esm/owned-instance-exited-error.mjs +81 -0
  182. package/dist/lib/esm/owned-vault-seed.d.mts +24 -3
  183. package/dist/lib/esm/owned-vault-seed.mjs +9 -5
  184. package/dist/lib/esm/parent-liveness.d.mts +37 -5
  185. package/dist/lib/esm/parent-liveness.mjs +42 -5
  186. package/dist/lib/esm/port-owner.d.mts +47 -0
  187. package/dist/lib/esm/port-owner.mjs +36 -0
  188. package/dist/lib/esm/process-capture.d.mts +83 -0
  189. package/dist/lib/esm/process-capture.mjs +38 -0
  190. package/dist/lib/esm/process-exit-message.d.mts +37 -3
  191. package/dist/lib/esm/process-exit-message.mjs +13 -8
  192. package/dist/lib/esm/process-liveness.d.mts +18 -0
  193. package/dist/lib/esm/process-liveness.mjs +17 -0
  194. package/dist/lib/esm/release-catalog.d.mts +125 -0
  195. package/dist/lib/esm/release-catalog.mjs +46 -0
  196. package/dist/lib/esm/run-version-matrix.d.mts +1 -1
  197. package/dist/lib/esm/run-version-matrix.mjs +1 -1
  198. package/dist/lib/esm/teardown-verdict.d.mts +69 -0
  199. package/dist/lib/esm/teardown-verdict.mjs +28 -0
  200. package/dist/lib/esm/temporary-vault.d.mts +47 -5
  201. package/dist/lib/esm/temporary-vault.mjs +43 -8
  202. package/dist/lib/esm/transport-appium.d.mts +104 -3
  203. package/dist/lib/esm/transport-appium.mjs +233 -17
  204. package/dist/lib/esm/transport-desktop-cdp.d.mts +100 -0
  205. package/dist/lib/esm/transport-desktop-cdp.mjs +208 -7
  206. package/dist/lib/esm/transport-factory.d.mts +10 -1
  207. package/dist/lib/esm/transport-factory.mjs +1220 -149
  208. package/dist/lib/esm/transport-options.d.mts +131 -12
  209. package/dist/lib/esm/transport-options.mjs +9 -2
  210. package/dist/lib/esm/transport.d.mts +7 -1
  211. package/dist/lib/esm/vault-plugin-install.d.mts +64 -0
  212. package/dist/lib/esm/vault-plugin-install.mjs +20 -0
  213. package/dist/lib/esm/vault-teardown-verdict.d.mts +57 -0
  214. package/dist/lib/esm/vault-teardown-verdict.mjs +18 -0
  215. package/dist/lib/esm/version-matrix.d.mts +2 -2
  216. package/dist/lib/esm/version-matrix.mjs +1 -1
  217. package/dist/lib/esm/vitest/global-setup.d.mts +5 -1
  218. package/dist/lib/esm/vitest/global-setup.mjs +14 -7
  219. package/dist/lib/esm/vitest/setup.d.mts +5 -0
  220. package/dist/lib/esm/vitest/setup.mjs +3 -1
  221. package/dist/lib/esm/vitest/typings.d.mts +6 -4
  222. package/dist/lib/esm/webview-cdp.d.mts +156 -0
  223. package/dist/lib/esm/webview-cdp.mjs +235 -0
  224. package/dist/lib/esm/wedged-appium-server.d.mts +187 -0
  225. package/dist/lib/esm/wedged-appium-server.mjs +86 -0
  226. package/package.json +25 -23
  227. package/dist/lib/cjs/native-dialog-monitor.cjs +0 -192
  228. package/dist/lib/cjs/native-dialog-monitor.d.cts +0 -66
  229. package/dist/lib/cjs/obsidian-namespace.cjs +0 -17
  230. package/dist/lib/cjs/obsidian-namespace.d.cts +0 -128
  231. package/dist/lib/esm/native-dialog-monitor.d.mts +0 -66
  232. package/dist/lib/esm/native-dialog-monitor.mjs +0 -158
  233. package/dist/lib/esm/obsidian-namespace.d.mts +0 -128
  234. package/dist/lib/esm/obsidian-namespace.mjs +0 -1
@@ -22,17 +22,21 @@ __export(owned_vault_seed_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(owned_vault_seed_exports);
24
24
  function buildOwnedObsidianJson(params) {
25
+ const shouldAutoOpenVault = params.shouldAutoOpenVault ?? true;
26
+ const entry = shouldAutoOpenVault ? { open: true, path: params.vaultPath, ts: params.ts } : { path: params.vaultPath, ts: params.ts };
25
27
  return {
28
+ // Spread rather than `last_open: undefined`, so the key is genuinely absent from
29
+ // The written JSON: this seed is read by Obsidian versions spanning a decade, and
30
+ // A present-but-undefined auto-open marker is not a shape any of them was tested
31
+ // Against.
26
32
  // eslint-disable-next-line camelcase -- Obsidian's own obsidian.json field name (old versions' auto-open marker).
27
- last_open: params.vaultId,
33
+ ...shouldAutoOpenVault && { last_open: params.vaultId },
28
34
  updateDisabled: true,
29
- vaults: {
30
- [params.vaultId]: { open: true, path: params.vaultPath, ts: params.ts }
31
- }
35
+ vaults: { [params.vaultId]: entry }
32
36
  };
33
37
  }
34
38
  // Annotate the CommonJS export names for ESM import in node:
35
39
  0 && (module.exports = {
36
40
  buildOwnedObsidianJson
37
41
  });
38
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL293bmVkLXZhdWx0LXNlZWQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBCdWlsZHMgdGhlIGlzb2xhdGVkIGBvYnNpZGlhbi5qc29uYCB0aGUgaGFybmVzcyBwcmUtc2VlZHMgaW50byBhbiBvd25lZFxuICogaW5zdGFuY2UncyB0ZW1wIGAtLXVzZXItZGF0YS1kaXJgIHNvIE9ic2lkaWFuIG9wZW5zIHRoZSBoYXJuZXNzIHZhdWx0IGRpcmVjdGx5XG4gKiBpbnN0ZWFkIG9mIHNob3dpbmcgdGhlIGZpcnN0LXJ1biB2YXVsdC1zZWxlY3RvciAodGhlIGBzdGFydGVyLXNjcmVlbmApLlxuICpcbiAqIFRoZSBhdXRvLW9wZW4gbWFya2VyIGNoYW5nZWQgYWNyb3NzIE9ic2lkaWFuJ3MgaGlzdG9yeSwgc28gdGhlIHNlZWQgY2Fycmllc1xuICogQk9USCBmb3JtcyBhbmQgZWFjaCB2ZXJzaW9uIHJlYWRzIHRoZSBvbmUgaXQgdW5kZXJzdGFuZHMgKGlnbm9yaW5nIHRoZSBvdGhlclxuICogdW5rbm93biBrZXkpIFx1MjAxNCBubyBwZXItdmVyc2lvbiBicmFuY2hpbmc6XG4gKlxuICogLSAqKk9sZCB2ZXJzaW9ucyoqIChjb25maXJtZWQgMC42LjQpIGF1dG8tb3BlbiBmcm9tIGEgKip0b3AtbGV2ZWwgYGxhc3Rfb3BlbmAqKlxuICogICBob2xkaW5nIHRoZSB2YXVsdCBpZCAoYG1haW4uanNgOiBgaWYgKGlkICYmIHZhdWx0cy5oYXNPd25Qcm9wZXJ0eShpZCkpXG4gKiAgIGNyZWF0ZVdpbmRvdyhpZCk7IGVsc2Ugb3BlblN0YXJ0ZXIoKTtgKSwgYW5kIHN0b3JlIGVhY2ggdmF1bHQgZW50cnkgYXMganVzdFxuICogICBgeyBwYXRoLCB0cyB9YC4gV2l0aG91dCBgbGFzdF9vcGVuYCB0aGV5IGZhbGwgdGhyb3VnaCB0byB0aGUgdmF1bHQtc2VsZWN0b3IuXG4gKiAtICoqTmV3ZXIgdmVyc2lvbnMqKiAoY29uZmlybWVkIDAuMTQuNSspIGRyb3BwZWQgYGxhc3Rfb3BlbmAgYW5kIGF1dG8tb3BlbiBmcm9tXG4gKiAgIHRoZSBwZXItZW50cnkgKipgb3BlbjogdHJ1ZWAqKiBmbGFnLlxuICpcbiAqIFNlZWRpbmcgYm90aCB3YXMgdmVyaWZpZWQgdG8gb3BlbiB0aGUgdmF1bHQgZGlyZWN0bHkgKG5vIHNlbGVjdG9yKSBvbiAwLjYuNCxcbiAqIDAuOS4yMCwgMC4xMi4xOSwgMC4xMy4xOSwgMC4xNC41IGFuZCAxLjEyLjcuIGB1cGRhdGVEaXNhYmxlZGAgc3VwcHJlc3NlcyB0aGVcbiAqIHRocm93YXdheSBpbnN0YW5jZSdzIHNlbGYtdXBkYXRlLlxuICovXG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGJ1aWxkT3duZWRPYnNpZGlhbkpzb259LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkT3duZWRPYnNpZGlhbkpzb25QYXJhbXMge1xuICAvKipcbiAgTGFzdC1hY2Nlc3MgdGltZXN0YW1wIHRvIHN0YW1wIG9uIHRoZSB2YXVsdCBlbnRyeS5cbiAgICovXG4gIHJlYWRvbmx5IHRzOiBudW1iZXI7XG5cbiAgLyoqXG4gIFRoZSByYW5kb21seS1nZW5lcmF0ZWQgdmF1bHQgaWQgdXNlZCBhcyB0aGUgcmVnaXN0cnkga2V5IGFuZCBgbGFzdF9vcGVuYC5cbiAgICovXG4gIHJlYWRvbmx5IHZhdWx0SWQ6IHN0cmluZztcblxuICAvKipcbiAgQWJzb2x1dGUgcGF0aCB0byB0aGUgaGFybmVzcyB2YXVsdCBmb2xkZXIuXG4gICAqL1xuICByZWFkb25seSB2YXVsdFBhdGg6IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgYG9ic2lkaWFuLmpzb25gIHN0cnVjdHVyZSB0aGUgaGFybmVzcyBzZWVkcyBmb3IgYW4gb3duZWQgaW5zdGFuY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3duZWRPYnNpZGlhbkpzb24ge1xuICAvKipcbiAgICogVG9wLWxldmVsIGF1dG8tb3BlbiBtYXJrZXIgKHZhdWx0IGlkKSBob25vcmVkIGJ5IG9sZCBPYnNpZGlhbiB2ZXJzaW9ucztcbiAgICogaWdub3JlZCBhcyBhbiB1bmtub3duIGtleSBieSBuZXdlciB2ZXJzaW9ucyB0aGF0IHVzZSB0aGUgcGVyLWVudHJ5IGBvcGVuYC5cbiAgICovXG4gIHJlYWRvbmx5IGxhc3Rfb3Blbjogc3RyaW5nO1xuXG4gIC8qKlxuICBEaXNhYmxlcyB0aGUgdGhyb3dhd2F5IGluc3RhbmNlJ3Mgc2VsZi11cGRhdGUuXG4gICAqL1xuICByZWFkb25seSB1cGRhdGVEaXNhYmxlZDogdHJ1ZTtcblxuICAvKipcbiAgVmF1bHQgcmVnaXN0cnkga2V5ZWQgYnkgdmF1bHQgaWQuXG4gICAqL1xuICByZWFkb25seSB2YXVsdHM6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIE93bmVkT2JzaWRpYW5WYXVsdEVudHJ5Pj47XG59XG5cbi8qKlxuICogQSBzaW5nbGUgdmF1bHQgZW50cnkgaW4gdGhlIHNlZWRlZCBgb2JzaWRpYW4uanNvbmAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3duZWRPYnNpZGlhblZhdWx0RW50cnkge1xuICAvKipcbiAgUGVyLWVudHJ5IGF1dG8tb3BlbiBmbGFnIGhvbm9yZWQgYnkgbmV3ZXIgT2JzaWRpYW4gdmVyc2lvbnMuXG4gICAqL1xuICByZWFkb25seSBvcGVuOiB0cnVlO1xuXG4gIC8qKlxuICBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBoYXJuZXNzIHZhdWx0IGZvbGRlci5cbiAgICovXG4gIHJlYWRvbmx5IHBhdGg6IHN0cmluZztcblxuICAvKipcbiAgTGFzdC1hY2Nlc3MgdGltZXN0YW1wLlxuICAgKi9cbiAgcmVhZG9ubHkgdHM6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBCdWlsZHMgdGhlIGlzb2xhdGVkIGBvYnNpZGlhbi5qc29uYCB0aGF0IGZvcmNlLW9wZW5zIHRoZSBvd25lZCB2YXVsdCBhY3Jvc3MgYWxsXG4gKiBzdXBwb3J0ZWQgT2JzaWRpYW4gdmVyc2lvbnMgKHNlZSB0aGUgZmlsZSBvdmVydmlldyBmb3IgdGhlIGR1YWwtbWFya2VyXG4gKiByYXRpb25hbGUpLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgdmF1bHQgaWQsIHBhdGgsIGFuZCB0aW1lc3RhbXAgdG8gc2VlZC5cbiAqIEByZXR1cm5zIFRoZSBgb2JzaWRpYW4uanNvbmAgb2JqZWN0IHRvIHdyaXRlIGludG8gdGhlIG93bmVkIHVzZXItZGF0YSBkaXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZE93bmVkT2JzaWRpYW5Kc29uKHBhcmFtczogQnVpbGRPd25lZE9ic2lkaWFuSnNvblBhcmFtcyk6IE93bmVkT2JzaWRpYW5Kc29uIHtcbiAgcmV0dXJuIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2FtZWxjYXNlIC0tIE9ic2lkaWFuJ3Mgb3duIG9ic2lkaWFuLmpzb24gZmllbGQgbmFtZSAob2xkIHZlcnNpb25zJyBhdXRvLW9wZW4gbWFya2VyKS5cbiAgICBsYXN0X29wZW46IHBhcmFtcy52YXVsdElkLFxuICAgIHVwZGF0ZURpc2FibGVkOiB0cnVlLFxuICAgIHZhdWx0czoge1xuICAgICAgW3BhcmFtcy52YXVsdElkXTogeyBvcGVuOiB0cnVlLCBwYXRoOiBwYXJhbXMudmF1bHRQYXRoLCB0czogcGFyYW1zLnRzIH1cbiAgICB9XG4gIH07XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBNEZPLFNBQVMsdUJBQXVCLFFBQXlEO0FBQzlGLFNBQU87QUFBQTtBQUFBLElBRUwsV0FBVyxPQUFPO0FBQUEsSUFDbEIsZ0JBQWdCO0FBQUEsSUFDaEIsUUFBUTtBQUFBLE1BQ04sQ0FBQyxPQUFPLE9BQU8sR0FBRyxFQUFFLE1BQU0sTUFBTSxNQUFNLE9BQU8sV0FBVyxJQUFJLE9BQU8sR0FBRztBQUFBLElBQ3hFO0FBQUEsRUFDRjtBQUNGOyIsCiAgIm5hbWVzIjogW10KfQo=
42
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL293bmVkLXZhdWx0LXNlZWQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBCdWlsZHMgdGhlIGlzb2xhdGVkIGBvYnNpZGlhbi5qc29uYCB0aGUgaGFybmVzcyBwcmUtc2VlZHMgaW50byBhbiBvd25lZFxuICogaW5zdGFuY2UncyB0ZW1wIGAtLXVzZXItZGF0YS1kaXJgIHNvIE9ic2lkaWFuIG9wZW5zIHRoZSBoYXJuZXNzIHZhdWx0IGRpcmVjdGx5XG4gKiBpbnN0ZWFkIG9mIHNob3dpbmcgdGhlIGZpcnN0LXJ1biB2YXVsdC1zZWxlY3RvciAodGhlIGBzdGFydGVyLXNjcmVlbmApLlxuICpcbiAqIFRoZSBhdXRvLW9wZW4gbWFya2VyIGNoYW5nZWQgYWNyb3NzIE9ic2lkaWFuJ3MgaGlzdG9yeSwgc28gdGhlIHNlZWQgY2Fycmllc1xuICogQk9USCBmb3JtcyBhbmQgZWFjaCB2ZXJzaW9uIHJlYWRzIHRoZSBvbmUgaXQgdW5kZXJzdGFuZHMgKGlnbm9yaW5nIHRoZSBvdGhlclxuICogdW5rbm93biBrZXkpIFx1MjAxNCBubyBwZXItdmVyc2lvbiBicmFuY2hpbmc6XG4gKlxuICogLSAqKk9sZCB2ZXJzaW9ucyoqIChjb25maXJtZWQgMC42LjQpIGF1dG8tb3BlbiBmcm9tIGEgKip0b3AtbGV2ZWwgYGxhc3Rfb3BlbmAqKlxuICogICBob2xkaW5nIHRoZSB2YXVsdCBpZCAoYG1haW4uanNgOiBgaWYgKGlkICYmIHZhdWx0cy5oYXNPd25Qcm9wZXJ0eShpZCkpXG4gKiAgIGNyZWF0ZVdpbmRvdyhpZCk7IGVsc2Ugb3BlblN0YXJ0ZXIoKTtgKSwgYW5kIHN0b3JlIGVhY2ggdmF1bHQgZW50cnkgYXMganVzdFxuICogICBgeyBwYXRoLCB0cyB9YC4gV2l0aG91dCBgbGFzdF9vcGVuYCB0aGV5IGZhbGwgdGhyb3VnaCB0byB0aGUgdmF1bHQtc2VsZWN0b3IuXG4gKiAtICoqTmV3ZXIgdmVyc2lvbnMqKiAoY29uZmlybWVkIDAuMTQuNSspIGRyb3BwZWQgYGxhc3Rfb3BlbmAgYW5kIGF1dG8tb3BlbiBmcm9tXG4gKiAgIHRoZSBwZXItZW50cnkgKipgb3BlbjogdHJ1ZWAqKiBmbGFnLlxuICpcbiAqIFNlZWRpbmcgYm90aCB3YXMgdmVyaWZpZWQgdG8gb3BlbiB0aGUgdmF1bHQgZGlyZWN0bHkgKG5vIHNlbGVjdG9yKSBvbiAwLjYuNCxcbiAqIDAuOS4yMCwgMC4xMi4xOSwgMC4xMy4xOSwgMC4xNC41IGFuZCAxLjEyLjcuIGB1cGRhdGVEaXNhYmxlZGAgc3VwcHJlc3NlcyB0aGVcbiAqIHRocm93YXdheSBpbnN0YW5jZSdzIHNlbGYtdXBkYXRlLlxuICpcbiAqIEJvdGggbWFya2VycyBjYW4gYWxzbyBiZSAqKndpdGhoZWxkKiogXHUyMDE0IHNlZVxuICoge0BsaW5rIEJ1aWxkT3duZWRPYnNpZGlhbkpzb25QYXJhbXMuc2hvdWxkQXV0b09wZW5WYXVsdH0uIFRoZSBvbmUgY2FsbGVyIHRoYXRcbiAqIGRvZXMgc28gd2FudHMgdGhlIHN0YXJ0ZXIgc2NyZWVuIG9uIHB1cnBvc2U6IGEgYGNvbmZpZ0RpcmVjdG9yeWAgb3ZlcnJpZGUgaXMgYVxuICogYGxvY2FsU3RvcmFnZWAgZW50cnksIGFuZCBgbG9jYWxTdG9yYWdlYCBvbmx5IGV4aXN0cyBvbmNlIGEgcmVuZGVyZXIgZG9lcywgc29cbiAqIHRoZSBvdmVycmlkZSBoYXMgdG8gYmUgd3JpdHRlbiBpbiB0aGUgc3RhcnRlciBzY3JlZW4ncyByZW5kZXJlciBiZWZvcmUgdGhlXG4gKiB2YXVsdCdzIG93biB3aW5kb3cgaXMgY3JlYXRlZC4gVGhlIHZhdWx0IHN0YXlzIHJlZ2lzdGVyZWQgdW5kZXIgdGhlIGhhcm5lc3Mnc1xuICogaWQgZWl0aGVyIHdheSwgYW5kIHRoZSBsYXRlciBgdmF1bHQtb3BlbmAgSVBDIHJldXNlcyB0aGF0IGlkICh2ZXJpZmllZCBvblxuICogMS4xMy43KSByYXRoZXIgdGhhbiBtaW50aW5nIGEgc2Vjb25kIGVudHJ5IFx1MjAxNCB3aGljaCBpcyB3aGF0IG1ha2VzIHRoZVxuICogYDx2YXVsdElkPi1jb25maWdgIGtleSBuYW1lIGtub3dhYmxlIGJlZm9yZSBsYXVuY2guXG4gKi9cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgYnVpbGRPd25lZE9ic2lkaWFuSnNvbn0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQnVpbGRPd25lZE9ic2lkaWFuSnNvblBhcmFtcyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGluY2x1ZGUgdGhlIGF1dG8tb3BlbiBtYXJrZXJzLCBzbyBPYnNpZGlhbiBvcGVucyB0aGUgdmF1bHRcbiAgICogZGlyZWN0bHkgaW5zdGVhZCBvZiBzaG93aW5nIHRoZSBzdGFydGVyIHNjcmVlbi4gUGFzcyBgZmFsc2VgIHRvIGtlZXAgdGhlXG4gICAqIHZhdWx0IHJlZ2lzdGVyZWQgYnV0IGNsb3NlZCBcdTIwMTQgdGhlIGNhbGxlciB0aGVuIG9wZW5zIGl0IGl0c2VsZiwgb3ZlciB0aGVcbiAgICogYHZhdWx0LW9wZW5gIElQQywgb25jZSBpdCBoYXMgcHJlcGFyZWQgdGhlIHN0YXJ0ZXIgc2NyZWVuJ3MgcmVuZGVyZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB0cnVlYFxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkQXV0b09wZW5WYXVsdD86IGJvb2xlYW47XG5cbiAgLyoqXG4gIExhc3QtYWNjZXNzIHRpbWVzdGFtcCB0byBzdGFtcCBvbiB0aGUgdmF1bHQgZW50cnkuXG4gICAqL1xuICByZWFkb25seSB0czogbnVtYmVyO1xuXG4gIC8qKlxuICBUaGUgcmFuZG9tbHktZ2VuZXJhdGVkIHZhdWx0IGlkIHVzZWQgYXMgdGhlIHJlZ2lzdHJ5IGtleSBhbmQgYGxhc3Rfb3BlbmAuXG4gICAqL1xuICByZWFkb25seSB2YXVsdElkOiBzdHJpbmc7XG5cbiAgLyoqXG4gIEFic29sdXRlIHBhdGggdG8gdGhlIGhhcm5lc3MgdmF1bHQgZm9sZGVyLlxuICAgKi9cbiAgcmVhZG9ubHkgdmF1bHRQYXRoOiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIGBvYnNpZGlhbi5qc29uYCBzdHJ1Y3R1cmUgdGhlIGhhcm5lc3Mgc2VlZHMgZm9yIGFuIG93bmVkIGluc3RhbmNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE93bmVkT2JzaWRpYW5Kc29uIHtcbiAgLyoqXG4gICAqIFRvcC1sZXZlbCBhdXRvLW9wZW4gbWFya2VyICh2YXVsdCBpZCkgaG9ub3JlZCBieSBvbGQgT2JzaWRpYW4gdmVyc2lvbnM7XG4gICAqIGlnbm9yZWQgYXMgYW4gdW5rbm93biBrZXkgYnkgbmV3ZXIgdmVyc2lvbnMgdGhhdCB1c2UgdGhlIHBlci1lbnRyeSBgb3BlbmAuXG4gICAqIE9taXR0ZWQgd2hlbiB0aGUgY2FsbGVyIHdpdGhoZWxkIHRoZSBhdXRvLW9wZW4gbWFya2Vycy5cbiAgICovXG4gIHJlYWRvbmx5IGxhc3Rfb3Blbj86IHN0cmluZztcblxuICAvKipcbiAgRGlzYWJsZXMgdGhlIHRocm93YXdheSBpbnN0YW5jZSdzIHNlbGYtdXBkYXRlLlxuICAgKi9cbiAgcmVhZG9ubHkgdXBkYXRlRGlzYWJsZWQ6IHRydWU7XG5cbiAgLyoqXG4gIFZhdWx0IHJlZ2lzdHJ5IGtleWVkIGJ5IHZhdWx0IGlkLlxuICAgKi9cbiAgcmVhZG9ubHkgdmF1bHRzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBPd25lZE9ic2lkaWFuVmF1bHRFbnRyeT4+O1xufVxuXG4vKipcbiAqIEEgc2luZ2xlIHZhdWx0IGVudHJ5IGluIHRoZSBzZWVkZWQgYG9ic2lkaWFuLmpzb25gLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE93bmVkT2JzaWRpYW5WYXVsdEVudHJ5IHtcbiAgLyoqXG4gICAqIFBlci1lbnRyeSBhdXRvLW9wZW4gZmxhZyBob25vcmVkIGJ5IG5ld2VyIE9ic2lkaWFuIHZlcnNpb25zLiBPbWl0dGVkIHdoZW5cbiAgICogdGhlIGNhbGxlciB3aXRoaGVsZCB0aGUgYXV0by1vcGVuIG1hcmtlcnMuXG4gICAqL1xuICByZWFkb25seSBvcGVuPzogdHJ1ZTtcblxuICAvKipcbiAgQWJzb2x1dGUgcGF0aCB0byB0aGUgaGFybmVzcyB2YXVsdCBmb2xkZXIuXG4gICAqL1xuICByZWFkb25seSBwYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gIExhc3QtYWNjZXNzIHRpbWVzdGFtcC5cbiAgICovXG4gIHJlYWRvbmx5IHRzOiBudW1iZXI7XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBpc29sYXRlZCBgb2JzaWRpYW4uanNvbmAgdGhhdCBmb3JjZS1vcGVucyB0aGUgb3duZWQgdmF1bHQgYWNyb3NzIGFsbFxuICogc3VwcG9ydGVkIE9ic2lkaWFuIHZlcnNpb25zIChzZWUgdGhlIGZpbGUgb3ZlcnZpZXcgZm9yIHRoZSBkdWFsLW1hcmtlclxuICogcmF0aW9uYWxlKS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHZhdWx0IGlkLCBwYXRoLCBhbmQgdGltZXN0YW1wIHRvIHNlZWQuXG4gKiBAcmV0dXJucyBUaGUgYG9ic2lkaWFuLmpzb25gIG9iamVjdCB0byB3cml0ZSBpbnRvIHRoZSBvd25lZCB1c2VyLWRhdGEgZGlyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRPd25lZE9ic2lkaWFuSnNvbihwYXJhbXM6IEJ1aWxkT3duZWRPYnNpZGlhbkpzb25QYXJhbXMpOiBPd25lZE9ic2lkaWFuSnNvbiB7XG4gIGNvbnN0IHNob3VsZEF1dG9PcGVuVmF1bHQgPSBwYXJhbXMuc2hvdWxkQXV0b09wZW5WYXVsdCA/PyB0cnVlO1xuICBjb25zdCBlbnRyeTogT3duZWRPYnNpZGlhblZhdWx0RW50cnkgPSBzaG91bGRBdXRvT3BlblZhdWx0XG4gICAgPyB7IG9wZW46IHRydWUsIHBhdGg6IHBhcmFtcy52YXVsdFBhdGgsIHRzOiBwYXJhbXMudHMgfVxuICAgIDogeyBwYXRoOiBwYXJhbXMudmF1bHRQYXRoLCB0czogcGFyYW1zLnRzIH07XG5cbiAgcmV0dXJuIHtcbiAgICAvLyBTcHJlYWQgcmF0aGVyIHRoYW4gYGxhc3Rfb3BlbjogdW5kZWZpbmVkYCwgc28gdGhlIGtleSBpcyBnZW51aW5lbHkgYWJzZW50IGZyb21cbiAgICAvLyBUaGUgd3JpdHRlbiBKU09OOiB0aGlzIHNlZWQgaXMgcmVhZCBieSBPYnNpZGlhbiB2ZXJzaW9ucyBzcGFubmluZyBhIGRlY2FkZSwgYW5kXG4gICAgLy8gQSBwcmVzZW50LWJ1dC11bmRlZmluZWQgYXV0by1vcGVuIG1hcmtlciBpcyBub3QgYSBzaGFwZSBhbnkgb2YgdGhlbSB3YXMgdGVzdGVkXG4gICAgLy8gQWdhaW5zdC5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2FtZWxjYXNlIC0tIE9ic2lkaWFuJ3Mgb3duIG9ic2lkaWFuLmpzb24gZmllbGQgbmFtZSAob2xkIHZlcnNpb25zJyBhdXRvLW9wZW4gbWFya2VyKS5cbiAgICAuLi5zaG91bGRBdXRvT3BlblZhdWx0ICYmIHsgbGFzdF9vcGVuOiBwYXJhbXMudmF1bHRJZCB9LFxuICAgIHVwZGF0ZURpc2FibGVkOiB0cnVlLFxuICAgIHZhdWx0czogeyBbcGFyYW1zLnZhdWx0SWRdOiBlbnRyeSB9XG4gIH07XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBa0hPLFNBQVMsdUJBQXVCLFFBQXlEO0FBQzlGLFFBQU0sc0JBQXNCLE9BQU8sdUJBQXVCO0FBQzFELFFBQU0sUUFBaUMsc0JBQ25DLEVBQUUsTUFBTSxNQUFNLE1BQU0sT0FBTyxXQUFXLElBQUksT0FBTyxHQUFHLElBQ3BELEVBQUUsTUFBTSxPQUFPLFdBQVcsSUFBSSxPQUFPLEdBQUc7QUFFNUMsU0FBTztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxJQU1MLEdBQUcsdUJBQXVCLEVBQUUsV0FBVyxPQUFPLFFBQVE7QUFBQSxJQUN0RCxnQkFBZ0I7QUFBQSxJQUNoQixRQUFRLEVBQUUsQ0FBQyxPQUFPLE9BQU8sR0FBRyxNQUFNO0FBQUEsRUFDcEM7QUFDRjsiLAogICJuYW1lcyI6IFtdCn0K
@@ -19,11 +19,30 @@
19
19
  * Seeding both was verified to open the vault directly (no selector) on 0.6.4,
20
20
  * 0.9.20, 0.12.19, 0.13.19, 0.14.5 and 1.12.7. `updateDisabled` suppresses the
21
21
  * throwaway instance's self-update.
22
+ *
23
+ * Both markers can also be **withheld** — see
24
+ * {@link BuildOwnedObsidianJsonParams.shouldAutoOpenVault}. The one caller that
25
+ * does so wants the starter screen on purpose: a `configDirectory` override is a
26
+ * `localStorage` entry, and `localStorage` only exists once a renderer does, so
27
+ * the override has to be written in the starter screen's renderer before the
28
+ * vault's own window is created. The vault stays registered under the harness's
29
+ * id either way, and the later `vault-open` IPC reuses that id (verified on
30
+ * 1.13.7) rather than minting a second entry — which is what makes the
31
+ * `<vaultId>-config` key name knowable before launch.
22
32
  */
23
33
  /**
24
34
  * Parameters for {@link buildOwnedObsidianJson}.
25
35
  */
26
36
  export interface BuildOwnedObsidianJsonParams {
37
+ /**
38
+ * Whether to include the auto-open markers, so Obsidian opens the vault
39
+ * directly instead of showing the starter screen. Pass `false` to keep the
40
+ * vault registered but closed — the caller then opens it itself, over the
41
+ * `vault-open` IPC, once it has prepared the starter screen's renderer.
42
+ *
43
+ * @default `true`
44
+ */
45
+ readonly shouldAutoOpenVault?: boolean;
27
46
  /**
28
47
  Last-access timestamp to stamp on the vault entry.
29
48
  */
@@ -44,8 +63,9 @@ export interface OwnedObsidianJson {
44
63
  /**
45
64
  * Top-level auto-open marker (vault id) honored by old Obsidian versions;
46
65
  * ignored as an unknown key by newer versions that use the per-entry `open`.
66
+ * Omitted when the caller withheld the auto-open markers.
47
67
  */
48
- readonly last_open: string;
68
+ readonly last_open?: string;
49
69
  /**
50
70
  Disables the throwaway instance's self-update.
51
71
  */
@@ -60,9 +80,10 @@ export interface OwnedObsidianJson {
60
80
  */
61
81
  export interface OwnedObsidianVaultEntry {
62
82
  /**
63
- Per-entry auto-open flag honored by newer Obsidian versions.
83
+ * Per-entry auto-open flag honored by newer Obsidian versions. Omitted when
84
+ * the caller withheld the auto-open markers.
64
85
  */
65
- readonly open: true;
86
+ readonly open?: true;
66
87
  /**
67
88
  Absolute path to the harness vault folder.
68
89
  */
@@ -25,6 +25,8 @@ __export(parent_liveness_exports, {
25
25
  module.exports = __toCommonJS(parent_liveness_exports);
26
26
  var import_node_net = require("node:net");
27
27
  const PARENT_LIVENESS_HOST = "127.0.0.1";
28
+ const RECONNECT_ATTEMPT_LIMIT = 3;
29
+ const RECONNECT_DELAY_IN_MILLISECONDS = 250;
28
30
  function buildParentLivenessWatchdogExpression(port) {
29
31
  return `(function() {
30
32
  var FLAG = '__obsidianIntegrationTestingParentLiveness';
@@ -39,20 +41,55 @@ function buildParentLivenessWatchdogExpression(port) {
39
41
  return 'unavailable';
40
42
  }
41
43
  }
42
- var socket = net.connect(${String(port)}, '${PARENT_LIVENESS_HOST}');
44
+ var PORT = ${String(port)};
45
+ var HOST = '${PARENT_LIVENESS_HOST}';
46
+ var RECONNECT_ATTEMPT_LIMIT = ${String(RECONNECT_ATTEMPT_LIMIT)};
47
+ var RECONNECT_DELAY_IN_MILLISECONDS = ${String(RECONNECT_DELAY_IN_MILLISECONDS)};
48
+ var socket = net.connect(PORT, HOST);
43
49
  window[FLAG] = socket;
44
50
  var isConnected = false;
45
51
  socket.on('connect', function() { isConnected = true; });
46
- socket.on('error', function() { /* Handled by the close listener below. */ });
52
+ socket.on('error', function() { /* The close handler below decides what an error meant. */ });
47
53
  socket.on('close', function() {
54
+ /* Fail open: a connection that never established is no evidence the harness died. */
48
55
  if (!isConnected) { return; }
56
+ reconnect(1);
57
+ });
58
+ return 'armed';
59
+
60
+ /* A close only asks the question. Reconnecting answers it. */
61
+ function reconnect(attempt) {
62
+ var didConnect = false;
63
+ var probe = net.connect(PORT, HOST);
64
+ probe.on('connect', function() {
65
+ /* Someone is still listening, so the harness is alive. This is the new token. */
66
+ didConnect = true;
67
+ window[FLAG] = probe;
68
+ probe.on('close', function() { reconnect(1); });
69
+ });
70
+ probe.on('error', function() {
71
+ /*
72
+ * This handler outlives the connect, so it doubles as the adopted socket's
73
+ * error handler. Once connected, an error says nothing about the harness \u2014
74
+ * the close that follows it re-runs the probe.
75
+ */
76
+ if (didConnect) { return; }
77
+ if (attempt < RECONNECT_ATTEMPT_LIMIT) {
78
+ setTimeout(function() { reconnect(attempt + 1); }, RECONNECT_DELAY_IN_MILLISECONDS);
79
+ return;
80
+ }
81
+ /* Nothing answered after several tries: the harness really is gone. */
82
+ destroyWindow();
83
+ });
84
+ }
85
+
86
+ function destroyWindow() {
49
87
  try {
50
88
  window.electronWindow.destroy();
51
89
  } catch (destroyError) {
52
90
  window.close();
53
91
  }
54
- });
55
- return 'armed';
92
+ }
56
93
  })()`;
57
94
  }
58
95
  async function startParentLivenessServer() {
@@ -90,4 +127,4 @@ async function listenOnFreeLoopbackPort(server) {
90
127
  buildParentLivenessWatchdogExpression,
91
128
  startParentLivenessServer
92
129
  });
93
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3BhcmVudC1saXZlbmVzcy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFRpZXMgYSBoYXJuZXNzLW93bmVkIE9ic2lkaWFuIGluc3RhbmNlJ3MgbGlmZXRpbWUgdG8gdGhlIGhhcm5lc3MgcHJvY2VzcyB0aGF0XG4gKiBsYXVuY2hlZCBpdCwgaW4gdGhlIG9uZSBkaXJlY3Rpb24gdGhlIG9wZXJhdGluZyBzeXN0ZW0gd2lsbCBub3QgZG8gZm9yIHVzLlxuICpcbiAqIFRoZSBvd25lZCBpbnN0YW5jZSBpcyBhbHJlYWR5IGEgY2hpbGQgb2YgdGhlIGhhcm5lc3MgcHJvY2VzcywgYnV0IHRoYXQgbGlua1xuICogY2FycmllcyBubyBsaWZldGltZSBndWFyYW50ZWUuIFdpbmRvd3MgbmV2ZXIgcHJvcGFnYXRlcyBhIHBhcmVudCdzIGRlYXRoIHRvXG4gKiBpdHMgY2hpbGRyZW4gXHUyMDE0IGFuIG9ycGhhbiBzaW1wbHkga2VlcHMgcnVubmluZyB3aXRoIGEgc3RhbGUgcGFyZW50IGlkIFx1MjAxNCBhbmQgb25cbiAqIFBPU0lYIGEgYFNJR0tJTExgIGFpbWVkIGF0IGEgc2luZ2xlIHBpZCBuZXZlciBjYXNjYWRlcyBlaXRoZXIuIFRoZSBpbnN0YW5jZSBpc1xuICogYWRkaXRpb25hbGx5IHNwYXduZWQgYGRldGFjaGVkYCwgc28gaXQgaXMgbm90IGV2ZW4gaW4gdGhlIGhhcm5lc3MncyBwcm9jZXNzXG4gKiBncm91cC4gVGVhcmRvd24gdGhlcmVmb3JlIHJlbGllcyBlbnRpcmVseSBvbiB0aGUgaGFybmVzcyBydW5uaW5nIGl0cyBvd25cbiAqIGNsZWFudXAgKGBraWxsUHJvY2Vzc1RyZWVgIGZyb20gYW4gYGV4aXRgL3NpZ25hbCBoYW5kbGVyKSwgd2hpY2ggaXMgZXhhY3RseVxuICogd2hhdCBhIGBTSUdLSUxMYCwgYSBUYXNrIE1hbmFnZXIga2lsbCwgb3IgYW4gSURFIHN0b3AgYnV0dG9uIGRlbmllcyBpdC4gRXZlcnlcbiAqIHN1Y2gga2lsbCBsZWFrcyBhIGhpZGRlbiBPYnNpZGlhbiBob2xkaW5nIGEgdXNlci1kYXRhIGRpciBhbmQgYSBDRFAgcG9ydCwgYW5kXG4gKiB0aGV5IGFjY3VtdWxhdGU6IHRoZSBuZXh0IHJ1biBwaWNrcyBhIGZyZXNoIHRlbXAgZGlyIGFuZCBhIGZyZWUgcG9ydCwgc29cbiAqIG5vdGhpbmcgY29sbGlkZXMgYW5kIG5vdGhpbmcgY29tcGxhaW5zLlxuICpcbiAqIFRoZSBndWFyYW50ZWVkIGZpeCBpcyBhbiBPUyBwcmltaXRpdmUgXHUyMDE0IGEgV2luZG93cyBKb2IgT2JqZWN0IHdpdGhcbiAqIGBKT0JfT0JKRUNUX0xJTUlUX0tJTExfT05fSk9CX0NMT1NFYCwgb3IgYHByY3RsKFBSX1NFVF9QREVBVEhTSUcpYCBvbiBMaW51eCBcdTIwMTRcbiAqIGJ1dCBuZWl0aGVyIGlzIHJlYWNoYWJsZSBmcm9tIE5vZGUgd2l0aG91dCBhIG5hdGl2ZSBhZGRvbiwgd2hpY2ggaXMgZmFyIHRvb1xuICogaGVhdnkgYSBkZXBlbmRlbmN5IGZvciB0aGlzIGhhcm5lc3MuXG4gKlxuICogU28gd2UgdXNlIHRoZSBvbmUgY3Jvc3MtcGxhdGZvcm0gcmVzb3VyY2UgdGhlIGtlcm5lbCAqZG9lcyogcmVjbGFpbVxuICogZGV0ZXJtaW5pc3RpY2FsbHkgb24gcHJvY2VzcyBkZWF0aDogYSBzb2NrZXQuIFRoZSBoYXJuZXNzIGxpc3RlbnMgb24gYVxuICogbG9vcGJhY2sgcG9ydCBhbmQgdGhlIGluc3RhbmNlJ3MgcmVuZGVyZXIgY29ubmVjdHMgdG8gaXQuIEhvd2V2ZXIgdGhlIGhhcm5lc3NcbiAqIGRpZXMgXHUyMDE0IGNsZWFubHksIGBTSUdLSUxMYGVkLCBvciBjcmFzaGVkIFx1MjAxNCB0aGUga2VybmVsIGNsb3NlcyBpdHMgZW5kLCB0aGVcbiAqIHJlbmRlcmVyIHNlZXMgYGNsb3NlYCwgYW5kIHRoZSB3aW5kb3cgZGVzdHJveXMgaXRzZWxmLiBObyBwb2xsaW5nLCBub1xuICogaGVhcnRiZWF0IGludGVydmFsLCBubyB0aW1lb3V0IHRvIHR1bmUuXG4gKlxuICogRGVsaWJlcmF0ZWx5IGZhaWwtb3BlbjogdGhlIHJlbmRlcmVyIG9ubHkgYXJtcyB0aGUgZGVzdHJveSBoYW5kbGVyIGFmdGVyIHRoZVxuICogY29ubmVjdGlvbiBpcyBhY3R1YWxseSBlc3RhYmxpc2hlZC4gQSB3YXRjaGRvZyB0aGF0IGNhbm5vdCByZWFjaCB0aGUgaGFybmVzc1xuICogbGVhdmVzIHRoZSBpbnN0YW5jZSBydW5uaW5nIHJhdGhlciB0aGFuIGtpbGxpbmcgYSB3aW5kb3cgdGhlIGRldmVsb3BlciBpc1xuICogd29ya2luZyBpbi5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFNlcnZlciB9IGZyb20gJ25vZGU6bmV0JztcblxuaW1wb3J0IHsgY3JlYXRlU2VydmVyIH0gZnJvbSAnbm9kZTpuZXQnO1xuXG4vKipcbiAqIEEgbGlzdGVuaW5nIGxvb3BiYWNrIHNlcnZlciB3aG9zZSBhY2NlcHRlZCBjb25uZWN0aW9ucyBhY3QgYXMgbGl2ZW5lc3MgdG9rZW5zXG4gKiBmb3IgdGhlIGhhcm5lc3MgcHJvY2Vzcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYXJlbnRMaXZlbmVzc1NlcnZlciB7XG4gIC8qKlxuICBTdG9wcyBsaXN0ZW5pbmcgYW5kIGRyb3BzIGV2ZXJ5IGFjY2VwdGVkIGNvbm5lY3Rpb24uXG4gICAqL1xuICBjbG9zZSgpOiB2b2lkO1xuXG4gIC8qKlxuICBUaGUgbG9vcGJhY2sgcG9ydCB0aGUgcmVuZGVyZXIgd2F0Y2hkb2cgc2hvdWxkIGNvbm5lY3QgYmFjayB0by5cbiAgICovXG4gIHJlYWRvbmx5IHBvcnQ6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBMb29wYmFjayBob3N0IHRoZSBsaXZlbmVzcyBzZXJ2ZXIgYmluZHMgdG8uIE5ldmVyIGV4cG9zZWQgb2ZmLW1hY2hpbmUuXG4gKi9cbmV4cG9ydCBjb25zdCBQQVJFTlRfTElWRU5FU1NfSE9TVCA9ICcxMjcuMC4wLjEnO1xuXG4vKipcbiAqIEJ1aWxkcyB0aGUgZXhwcmVzc2lvbiBldmFsdWF0ZWQgaW4gdGhlIG93bmVkIGluc3RhbmNlJ3MgcmVuZGVyZXIgdG8gYXJtIHRoZVxuICogd2F0Y2hkb2cuXG4gKlxuICogV3JpdHRlbiBpbiBFUzUgc3R5bGUgKGB2YXJgLCBgZnVuY3Rpb25gKSB3aXRoIG5vIG9wdGlvbmFsIGNoYWluaW5nLCBtYXRjaGluZ1xuICoge0BsaW5rIERJU01JU1NfVFJVU1RfRElBTE9HX0VYUFJ9OiB0aGUgc2FtZSBleHByZXNzaW9uIGhhcyB0byBwYXJzZSBvbiB0aGVcbiAqIENocm9taXVtIDgwLWVyYSByZW5kZXJlcnMgb2YgdGhlIG9sZGVzdCBzdXBwb3J0ZWQgT2JzaWRpYW4gdmVyc2lvbnMgKEwyNikuXG4gKlxuICogQXJtaW5nIGlzIGlkZW1wb3RlbnQgXHUyMDE0IGEgc2Vjb25kIGV2YWx1YXRpb24gZmluZHMgdGhlIHN0b3JlZCBzb2NrZXQgYW5kXG4gKiByZXR1cm5zIHdpdGhvdXQgb3BlbmluZyBhbm90aGVyIGNvbm5lY3Rpb24sIHNvIGEgcmV0cmllZCByZWFkaW5lc3MgcGFzcyBkb2VzXG4gKiBub3QgcGlsZSB1cCBzb2NrZXRzLlxuICpcbiAqIEBwYXJhbSBwb3J0IC0gVGhlIGxvb3BiYWNrIHBvcnQgcmV0dXJuZWQgYnkge0BsaW5rIHN0YXJ0UGFyZW50TGl2ZW5lc3NTZXJ2ZXJ9LlxuICogQHJldHVybnMgVGhlIGV4cHJlc3Npb24gdG8gZXZhbHVhdGUsIHlpZWxkaW5nIGAnYXJtZWQnYCwgYCdhbHJlYWR5LWFybWVkJ2AsIG9yIGAndW5hdmFpbGFibGUnYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUGFyZW50TGl2ZW5lc3NXYXRjaGRvZ0V4cHJlc3Npb24ocG9ydDogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAoZnVuY3Rpb24oKSB7XG4gIHZhciBGTEFHID0gJ19fb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmdQYXJlbnRMaXZlbmVzcyc7XG4gIGlmICh3aW5kb3dbRkxBR10pIHsgcmV0dXJuICdhbHJlYWR5LWFybWVkJzsgfVxuICB2YXIgbmV0O1xuICB0cnkge1xuICAgIG5ldCA9IHdpbmRvdy5yZXF1aXJlKCdub2RlOm5ldCcpO1xuICB9IGNhdGNoIChub2RlUHJlZml4RXJyb3IpIHtcbiAgICB0cnkge1xuICAgICAgbmV0ID0gd2luZG93LnJlcXVpcmUoJ25ldCcpO1xuICAgIH0gY2F0Y2ggKGJhcmVQcmVmaXhFcnJvcikge1xuICAgICAgcmV0dXJuICd1bmF2YWlsYWJsZSc7XG4gICAgfVxuICB9XG4gIHZhciBzb2NrZXQgPSBuZXQuY29ubmVjdCgke1N0cmluZyhwb3J0KX0sICcke1BBUkVOVF9MSVZFTkVTU19IT1NUfScpO1xuICB3aW5kb3dbRkxBR10gPSBzb2NrZXQ7XG4gIHZhciBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICBzb2NrZXQub24oJ2Nvbm5lY3QnLCBmdW5jdGlvbigpIHsgaXNDb25uZWN0ZWQgPSB0cnVlOyB9KTtcbiAgc29ja2V0Lm9uKCdlcnJvcicsIGZ1bmN0aW9uKCkgeyAvKiBIYW5kbGVkIGJ5IHRoZSBjbG9zZSBsaXN0ZW5lciBiZWxvdy4gKi8gfSk7XG4gIHNvY2tldC5vbignY2xvc2UnLCBmdW5jdGlvbigpIHtcbiAgICBpZiAoIWlzQ29ubmVjdGVkKSB7IHJldHVybjsgfVxuICAgIHRyeSB7XG4gICAgICB3aW5kb3cuZWxlY3Ryb25XaW5kb3cuZGVzdHJveSgpO1xuICAgIH0gY2F0Y2ggKGRlc3Ryb3lFcnJvcikge1xuICAgICAgd2luZG93LmNsb3NlKCk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuICdhcm1lZCc7XG59KSgpYDtcbn1cblxuLyoqXG4gKiBTdGFydHMgdGhlIGxvb3BiYWNrIGxpdmVuZXNzIHNlcnZlciB0aGUgb3duZWQgaW5zdGFuY2UncyByZW5kZXJlciBjb25uZWN0c1xuICogYmFjayB0by5cbiAqXG4gKiBUaGUgc2VydmVyIGFuZCBldmVyeSBhY2NlcHRlZCBzb2NrZXQgYXJlIGB1bnJlZmBlZCwgc28gaG9sZGluZyBhIHdhdGNoZG9nXG4gKiBjb25uZWN0aW9uIG9wZW4gbmV2ZXIga2VlcHMgdGhlIGhhcm5lc3MgcHJvY2VzcyBhbGl2ZSBvbiBpdHMgb3duIFx1MjAxNCB0aGVcbiAqIGNvbm5lY3Rpb24gaXMgYSB0b2tlbiB0aGUga2VybmVsIHJlY2xhaW1zLCBub3Qgd29yayB0byB3YWl0IG9uLlxuICpcbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHJlc29sdmluZyB0byB0aGUgbGlzdGVuaW5nIHtAbGluayBQYXJlbnRMaXZlbmVzc1NlcnZlcn0uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdGFydFBhcmVudExpdmVuZXNzU2VydmVyKCk6IFByb21pc2U8UGFyZW50TGl2ZW5lc3NTZXJ2ZXI+IHtcbiAgY29uc3Qgc2VydmVyID0gY3JlYXRlU2VydmVyKChzb2NrZXQpID0+IHtcbiAgICBzb2NrZXQudW5yZWYoKTtcbiAgICAvLyBUaGUgY29ubmVjdGlvbiBjYXJyaWVzIG5vIGRhdGEgXHUyMDE0IGl0IGV4aXN0cyBvbmx5IHNvIGl0cyBjbG9zZSBpcyBvYnNlcnZhYmxlLlxuICAgIHNvY2tldC5vbignZXJyb3InLCAoKSA9PiB7XG4gICAgICAvLyBBIHJlbmRlcmVyIHRvcm4gZG93biBtaWQtY29ubmVjdGlvbiByZXNldHMgcmF0aGVyIHRoYW4gY2xvc2VzOyBub3QgYW4gZXJyb3IgaGVyZS5cbiAgICB9KTtcbiAgfSk7XG4gIHNlcnZlci51bnJlZigpO1xuXG4gIGNvbnN0IHBvcnQgPSBhd2FpdCBsaXN0ZW5PbkZyZWVMb29wYmFja1BvcnQoc2VydmVyKTtcbiAgcmV0dXJuIHtcbiAgICBjbG9zZSgpOiB2b2lkIHtcbiAgICAgIHNlcnZlci5jbG9zZSgpO1xuICAgIH0sXG4gICAgcG9ydFxuICB9O1xufVxuXG4vKipcbiAqIEJpbmRzIHRoZSBzZXJ2ZXIgdG8gYW4gZXBoZW1lcmFsIGxvb3BiYWNrIHBvcnQgYW5kIHJlcG9ydHMgd2hpY2ggb25lIGl0IGdvdC5cbiAqXG4gKiBAcGFyYW0gc2VydmVyIC0gVGhlIHNlcnZlciB0byBiaW5kLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gcmVzb2x2aW5nIHRvIHRoZSBhc3NpZ25lZCBwb3J0LlxuICogQHRocm93cyBJZiB0aGUgc2VydmVyIHJlcG9ydHMgYW4gZXJyb3IgYmVmb3JlIGxpc3RlbmluZywgb3IgYmluZHMgdG8gYSBwaXBlIHJhdGhlciB0aGFuIGEgcG9ydC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gbGlzdGVuT25GcmVlTG9vcGJhY2tQb3J0KHNlcnZlcjogU2VydmVyKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlPG51bWJlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHNlcnZlci5vbmNlKCdlcnJvcicsIHJlamVjdCk7XG4gICAgc2VydmVyLmxpc3RlbigwLCBQQVJFTlRfTElWRU5FU1NfSE9TVCwgKCkgPT4ge1xuICAgICAgY29uc3QgYWRkcmVzcyA9IHNlcnZlci5hZGRyZXNzKCk7XG4gICAgICBpZiAoYWRkcmVzcyA9PT0gbnVsbCB8fCB0eXBlb2YgYWRkcmVzcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgc2VydmVyLmNsb3NlKCk7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ0ZhaWxlZCB0byBkZXRlcm1pbmUgdGhlIHBhcmVudC1saXZlbmVzcyBwb3J0LicpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZShhZGRyZXNzLnBvcnQpO1xuICAgIH0pO1xuICB9KTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBc0NBLHNCQUE2QjtBQXFCdEIsTUFBTSx1QkFBdUI7QUFpQjdCLFNBQVMsc0NBQXNDLE1BQXNCO0FBQzFFLFNBQU87QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSw2QkFhb0IsT0FBTyxJQUFJLENBQUMsTUFBTSxvQkFBb0I7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBZW5FO0FBWUEsZUFBc0IsNEJBQTJEO0FBQy9FLFFBQU0sYUFBUyw4QkFBYSxDQUFDLFdBQVc7QUFDdEMsV0FBTyxNQUFNO0FBRWIsV0FBTyxHQUFHLFNBQVMsTUFBTTtBQUFBLElBRXpCLENBQUM7QUFBQSxFQUNILENBQUM7QUFDRCxTQUFPLE1BQU07QUFFYixRQUFNLE9BQU8sTUFBTSx5QkFBeUIsTUFBTTtBQUNsRCxTQUFPO0FBQUEsSUFDTCxRQUFjO0FBQ1osYUFBTyxNQUFNO0FBQUEsSUFDZjtBQUFBLElBQ0E7QUFBQSxFQUNGO0FBQ0Y7QUFTQSxlQUFlLHlCQUF5QixRQUFpQztBQUN2RSxTQUFPLElBQUksUUFBZ0IsQ0FBQyxTQUFTLFdBQVc7QUFDOUMsV0FBTyxLQUFLLFNBQVMsTUFBTTtBQUMzQixXQUFPLE9BQU8sR0FBRyxzQkFBc0IsTUFBTTtBQUMzQyxZQUFNLFVBQVUsT0FBTyxRQUFRO0FBQy9CLFVBQUksWUFBWSxRQUFRLE9BQU8sWUFBWSxVQUFVO0FBQ25ELGVBQU8sTUFBTTtBQUNiLGVBQU8sSUFBSSxNQUFNLCtDQUErQyxDQUFDO0FBQ2pFO0FBQUEsTUFDRjtBQUNBLGNBQVEsUUFBUSxJQUFJO0FBQUEsSUFDdEIsQ0FBQztBQUFBLEVBQ0gsQ0FBQztBQUNIOyIsCiAgIm5hbWVzIjogW10KfQo=
130
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3BhcmVudC1saXZlbmVzcy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFRpZXMgYSBoYXJuZXNzLW93bmVkIE9ic2lkaWFuIGluc3RhbmNlJ3MgbGlmZXRpbWUgdG8gdGhlIGhhcm5lc3MgcHJvY2VzcyB0aGF0XG4gKiBsYXVuY2hlZCBpdCwgaW4gdGhlIG9uZSBkaXJlY3Rpb24gdGhlIG9wZXJhdGluZyBzeXN0ZW0gd2lsbCBub3QgZG8gZm9yIHVzLlxuICpcbiAqIFRoZSBvd25lZCBpbnN0YW5jZSBpcyBhbHJlYWR5IGEgY2hpbGQgb2YgdGhlIGhhcm5lc3MgcHJvY2VzcywgYnV0IHRoYXQgbGlua1xuICogY2FycmllcyBubyBsaWZldGltZSBndWFyYW50ZWUuIFdpbmRvd3MgbmV2ZXIgcHJvcGFnYXRlcyBhIHBhcmVudCdzIGRlYXRoIHRvXG4gKiBpdHMgY2hpbGRyZW4gXHUyMDE0IGFuIG9ycGhhbiBzaW1wbHkga2VlcHMgcnVubmluZyB3aXRoIGEgc3RhbGUgcGFyZW50IGlkIFx1MjAxNCBhbmQgb25cbiAqIFBPU0lYIGEgYFNJR0tJTExgIGFpbWVkIGF0IGEgc2luZ2xlIHBpZCBuZXZlciBjYXNjYWRlcyBlaXRoZXIuIFRoZSBpbnN0YW5jZSBpc1xuICogYWRkaXRpb25hbGx5IHNwYXduZWQgYGRldGFjaGVkYCwgc28gaXQgaXMgbm90IGV2ZW4gaW4gdGhlIGhhcm5lc3MncyBwcm9jZXNzXG4gKiBncm91cC4gVGVhcmRvd24gdGhlcmVmb3JlIHJlbGllcyBlbnRpcmVseSBvbiB0aGUgaGFybmVzcyBydW5uaW5nIGl0cyBvd25cbiAqIGNsZWFudXAgKGBraWxsUHJvY2Vzc1RyZWVgIGZyb20gYW4gYGV4aXRgL3NpZ25hbCBoYW5kbGVyKSwgd2hpY2ggaXMgZXhhY3RseVxuICogd2hhdCBhIGBTSUdLSUxMYCwgYSBUYXNrIE1hbmFnZXIga2lsbCwgb3IgYW4gSURFIHN0b3AgYnV0dG9uIGRlbmllcyBpdC4gRXZlcnlcbiAqIHN1Y2gga2lsbCBsZWFrcyBhIGhpZGRlbiBPYnNpZGlhbiBob2xkaW5nIGEgdXNlci1kYXRhIGRpciBhbmQgYSBDRFAgcG9ydCwgYW5kXG4gKiB0aGV5IGFjY3VtdWxhdGU6IHRoZSBuZXh0IHJ1biBwaWNrcyBhIGZyZXNoIHRlbXAgZGlyIGFuZCBhIGZyZWUgcG9ydCwgc29cbiAqIG5vdGhpbmcgY29sbGlkZXMgYW5kIG5vdGhpbmcgY29tcGxhaW5zLlxuICpcbiAqIFRoZSBndWFyYW50ZWVkIGZpeCBpcyBhbiBPUyBwcmltaXRpdmUgXHUyMDE0IGEgV2luZG93cyBKb2IgT2JqZWN0IHdpdGhcbiAqIGBKT0JfT0JKRUNUX0xJTUlUX0tJTExfT05fSk9CX0NMT1NFYCwgb3IgYHByY3RsKFBSX1NFVF9QREVBVEhTSUcpYCBvbiBMaW51eCBcdTIwMTRcbiAqIGJ1dCBuZWl0aGVyIGlzIHJlYWNoYWJsZSBmcm9tIE5vZGUgd2l0aG91dCBhIG5hdGl2ZSBhZGRvbiwgd2hpY2ggaXMgZmFyIHRvb1xuICogaGVhdnkgYSBkZXBlbmRlbmN5IGZvciB0aGlzIGhhcm5lc3MuXG4gKlxuICogU28gd2UgdXNlIHRoZSBvbmUgY3Jvc3MtcGxhdGZvcm0gcmVzb3VyY2UgdGhlIGtlcm5lbCAqZG9lcyogcmVjbGFpbVxuICogZGV0ZXJtaW5pc3RpY2FsbHkgb24gcHJvY2VzcyBkZWF0aDogYSBzb2NrZXQuIFRoZSBoYXJuZXNzIGxpc3RlbnMgb24gYVxuICogbG9vcGJhY2sgcG9ydCBhbmQgdGhlIGluc3RhbmNlJ3MgcmVuZGVyZXIgY29ubmVjdHMgdG8gaXQuIEhvd2V2ZXIgdGhlIGhhcm5lc3NcbiAqIGRpZXMgXHUyMDE0IGNsZWFubHksIGBTSUdLSUxMYGVkLCBvciBjcmFzaGVkIFx1MjAxNCB0aGUga2VybmVsIGNsb3NlcyBpdHMgZW5kIGFuZCB0aGVcbiAqIHJlbmRlcmVyIHNlZXMgYGNsb3NlYC4gTm8gcG9sbGluZywgbm8gaGVhcnRiZWF0IGludGVydmFsLCBubyB0aW1lb3V0IHRvIHR1bmUuXG4gKlxuICogKipBIGNsb3NlIGlzIGEgcXVlc3Rpb24sIG5vdCBhIHZlcmRpY3QuKiogQSBzb2NrZXQgY2xvc2luZyBpcyBub3QgdGhlIHNhbWVcbiAqIGV2ZW50IGFzIGEgcHJvY2VzcyBkeWluZywgYW5kIHRyZWF0aW5nIHRoZW0gYXMgaWRlbnRpY2FsIGRlc3Ryb3llZCBoZWFsdGh5XG4gKiBpbnN0YW5jZXM6IG1lYXN1cmVkIG9uIDIwMjYtMDktMDUsIGEgcmVuZGVyZXIncyBpZGxlIGxpdmVuZXNzIHNvY2tldCBzZW50XG4gKiBgRklOYCBvbiBpdHMgb3duIFx1MjAxNCAzIG1pbiAxMyBzIGludG8gb25lIHJ1biwgMTEgbWluIDU2IHMgaW50byBhbm90aGVyIFx1MjAxNCB3aGlsZVxuICogdGhlIGhhcm5lc3Mgd2FzIHN0aWxsIGxpc3RlbmluZyBhbmQgd2VudCBvbiB3b3JraW5nIGZvciBhbm90aGVyIDE0IG1pbnV0ZXMuXG4gKiBFdmVyeSB0ZXN0IGZpbGUgc2NoZWR1bGVkIGFmdGVyIHRoZSBkZWF0aCB0aGVuIGZhaWxlZCBpbiB0ZW5zIG9mIG1pbGxpc2Vjb25kc1xuICogd2l0aCBgRUNPTk5SRUZVU0VEYCBvbiB0aGUgZGVhZCBDRFAgcG9ydDsgdGhlIHdvcnN0IHJ1biByZXBvcnRlZCAxNTYgc3VjaFxuICogZmFpbHVyZXMgYWNyb3NzIDIxIGZpbGVzLCBub3Qgb25lIG9mIHRoZW0gYSB0ZXN0IHJlc3VsdC4gV2h5IGFuIGlkbGUgdW5yZWYnZFxuICogbG9vcGJhY2sgc29ja2V0IGluIGFuIEVsZWN0cm9uIHJlbmRlcmVyIGRvZXMgdGhhdCBpcyBub3QgZXN0YWJsaXNoZWQsIGFuZCBkb2VzXG4gKiBub3QgbmVlZCB0byBiZTogdGhlIGxpZmV0aW1lcyB2YXJ5IHJ1biB0byBydW4sIHNvIG5vIGZpeGVkIHRpbWVvdXQgZXhwbGFpbnMgaXQuXG4gKlxuICogU28gdGhlIGBjbG9zZWAgaGFuZGxlciAqKnZlcmlmaWVzIGJlZm9yZSBkZXN0cm95aW5nKio6IGl0IHJlY29ubmVjdHMgdG8gdGhlXG4gKiBzYW1lIGxvb3BiYWNrIHBvcnQuIEEgaGFybmVzcyB0aGF0IGlzIGFsaXZlIGlzIHN0aWxsIGxpc3RlbmluZywgc28gdGhlXG4gKiByZWNvbm5lY3Qgc3VjY2VlZHMgYW5kIHRoZSBuZXcgc29ja2V0IGJlY29tZXMgdGhlIGxpdmVuZXNzIHRva2VuOyBvbmx5IHdoZW5cbiAqIG5vdGhpbmcgYW5zd2VycyBhZnRlciBhIGZldyB0cmllcyBcdTIwMTQgd2hhdCBhIGRlYWQgaGFybmVzcyBhY3R1YWxseSBsb29rcyBsaWtlIFx1MjAxNFxuICogaXMgdGhlIHdpbmRvdyBkZXN0cm95ZWQuIFRoZSBsZWFrIHRoZSB3YXRjaGRvZyBleGlzdHMgdG8gcHJldmVudCBpcyBzdGlsbFxuICogcHJldmVudGVkLCBhbmQgdGhlIG1lYXN1cmVkIHJlY292ZXJ5IGlzIDExIG1zLlxuICpcbiAqIEEgcmVjb25uZWN0IHJhdGhlciB0aGFuIGEgY2hlY2sgb24gdGhlIGhhcm5lc3MncyBwcm9jZXNzIGlkLCBiZWNhdXNlIGl0IHByb3Zlc1xuICogdGhlIHRoaW5nIHRoZSB3YXRjaGRvZyBhY3R1YWxseSBkZXBlbmRzIG9uIFx1MjAxNCB0aGUgbGl2ZW5lc3Mgc2VydmVyIHN0aWxsIHNlcnZpbmdcbiAqIFx1MjAxNCBhbmQgaXQgc3RheXMgY29ycmVjdCBhZ2FpbnN0IGEgKmJ1c3kqIGhhcm5lc3M6IHRoZSBrZXJuZWwgY29tcGxldGVzIGFcbiAqIGxvb3BiYWNrIGhhbmRzaGFrZSBvdXQgb2YgdGhlIGxpc3RlbiBiYWNrbG9nIGV2ZW4gd2hpbGUgTm9kZSdzIGV2ZW50IGxvb3AgaXNcbiAqIGJsb2NrZWQuIEl0cyBvbmUgcmVzaWR1YWwgYW1iaWd1aXR5IGlzIGFjY2VwdGVkOiBhIHJlY29ubmVjdCBwcm92ZXMgKnNvbWV0aGluZypcbiAqIGlzIGxpc3RlbmluZyBvbiB0aGF0IGVwaGVtZXJhbCBwb3J0LCBub3QgdGhhdCBpdCBpcyBvdXJzLiBUaGUgcHJvYmUgZm9sbG93cyB0aGVcbiAqIGNsb3NlIGJ5IG1pbGxpc2Vjb25kcywgc28gYW5vdGhlciBwcm9jZXNzIHdpbm5pbmcgdGhhdCBleGFjdCBwb3J0IGluIGJldHdlZW4gaXNcbiAqIG5vdCBhIHJpc2sgd29ydGggYSBoYW5kc2hha2UgcHJvdG9jb2wuXG4gKlxuICogRGVsaWJlcmF0ZWx5IGZhaWwtb3BlbjogdGhlIHJlbmRlcmVyIG9ubHkgYXJtcyB0aGUgZGVzdHJveSBwYXRoIGFmdGVyIHRoZVxuICogY29ubmVjdGlvbiBpcyBhY3R1YWxseSBlc3RhYmxpc2hlZC4gQSB3YXRjaGRvZyB0aGF0IGNhbm5vdCByZWFjaCB0aGUgaGFybmVzc1xuICogbGVhdmVzIHRoZSBpbnN0YW5jZSBydW5uaW5nIHJhdGhlciB0aGFuIGtpbGxpbmcgYSB3aW5kb3cgdGhlIGRldmVsb3BlciBpc1xuICogd29ya2luZyBpbi5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFNlcnZlciB9IGZyb20gJ25vZGU6bmV0JztcblxuaW1wb3J0IHsgY3JlYXRlU2VydmVyIH0gZnJvbSAnbm9kZTpuZXQnO1xuXG4vKipcbiAqIEEgbGlzdGVuaW5nIGxvb3BiYWNrIHNlcnZlciB3aG9zZSBhY2NlcHRlZCBjb25uZWN0aW9ucyBhY3QgYXMgbGl2ZW5lc3MgdG9rZW5zXG4gKiBmb3IgdGhlIGhhcm5lc3MgcHJvY2Vzcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYXJlbnRMaXZlbmVzc1NlcnZlciB7XG4gIC8qKlxuICAgKiBTdG9wcyBsaXN0ZW5pbmcuXG4gICAqXG4gICAqIE5vZGUga2VlcHMgYWxyZWFkeS1hY2NlcHRlZCBjb25uZWN0aW9ucyBhbGl2ZSBhY3Jvc3MgYSBgY2xvc2UoKWAsIHNvIHRoaXNcbiAgICogZG9lcyBub3QgYnkgaXRzZWxmIHNpZ25hbCB0aGUgcmVuZGVyZXIgXHUyMDE0IHRoZSBrZXJuZWwgcmVjbGFpbWluZyB0aGUgc29ja2V0IG9uXG4gICAqIHByb2Nlc3MgZGVhdGggaXMgd2hhdCBkb2VzLiBXaGF0IGl0IGRvZXMgZ3VhcmFudGVlIGlzIHRoYXQgYSB3YXRjaGRvZyBwcm9iZVxuICAgKiBhcnJpdmluZyBhZnRlcndhcmRzIGlzIHJlZnVzZWQsIHdoaWNoIGlzIHRoZSBhbnN3ZXIgYSB0b3JuLWRvd24gaGFybmVzc1xuICAgKiBzaG91bGQgZ2l2ZS5cbiAgICovXG4gIGNsb3NlKCk6IHZvaWQ7XG5cbiAgLyoqXG4gIFRoZSBsb29wYmFjayBwb3J0IHRoZSByZW5kZXJlciB3YXRjaGRvZyBzaG91bGQgY29ubmVjdCBiYWNrIHRvLlxuICAgKi9cbiAgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xufVxuXG4vKipcbiAqIExvb3BiYWNrIGhvc3QgdGhlIGxpdmVuZXNzIHNlcnZlciBiaW5kcyB0by4gTmV2ZXIgZXhwb3NlZCBvZmYtbWFjaGluZS5cbiAqL1xuZXhwb3J0IGNvbnN0IFBBUkVOVF9MSVZFTkVTU19IT1NUID0gJzEyNy4wLjAuMSc7XG5cbi8qKlxuICogSG93IG1hbnkgdGltZXMgdGhlIHdhdGNoZG9nIHByb2JlcyB0aGUgbG9vcGJhY2sgcG9ydCBiZWZvcmUgY29uY2x1ZGluZyB0aGVcbiAqIGhhcm5lc3MgaXMgZ29uZS5cbiAqXG4gKiBNb3JlIHRoYW4gb25lLCBzbyBhIHNpbmdsZSB0cmFuc2llbnQgcmVmdXNhbCBjYW5ub3QgY29zdCBhIHdob2xlIHJ1bjsgc21hbGwsXG4gKiBiZWNhdXNlIGV2ZXJ5IGF0dGVtcHQgaXMgYSBsb29wYmFjayBjb25uZWN0IHRoYXQgZWl0aGVyIGNvbXBsZXRlcyBvciBpc1xuICogcmVmdXNlZCBpbW1lZGlhdGVseSwgYW5kIGFuIGluc3RhbmNlIHdob3NlIGhhcm5lc3MgcmVhbGx5IGRpZCBkaWUgc2hvdWxkIG5vdFxuICogbGluZ2VyLlxuICovXG5jb25zdCBSRUNPTk5FQ1RfQVRURU1QVF9MSU1JVCA9IDM7XG5cbi8qKlxuICogSG93IGxvbmcgdGhlIHdhdGNoZG9nIHdhaXRzIGJldHdlZW4gcHJvYmVzLlxuICpcbiAqIExvbmcgZW5vdWdoIHRvIG91dGxhc3QgYSBtb21lbnRhcnkgcmVmdXNhbCwgc2hvcnQgZW5vdWdoIHRoYXQgZXhoYXVzdGluZyB0aGVcbiAqIHdob2xlIGJ1ZGdldCBzdGlsbCBkZXN0cm95cyBhbiBvcnBoYW5lZCB3aW5kb3cgaW5zaWRlIGEgc2Vjb25kLlxuICovXG5jb25zdCBSRUNPTk5FQ1RfREVMQVlfSU5fTUlMTElTRUNPTkRTID0gMjUwO1xuXG4vKipcbiAqIEJ1aWxkcyB0aGUgZXhwcmVzc2lvbiBldmFsdWF0ZWQgaW4gdGhlIG93bmVkIGluc3RhbmNlJ3MgcmVuZGVyZXIgdG8gYXJtIHRoZVxuICogd2F0Y2hkb2cuXG4gKlxuICogV3JpdHRlbiBpbiBFUzUgc3R5bGUgKGB2YXJgLCBgZnVuY3Rpb25gKSB3aXRoIG5vIG9wdGlvbmFsIGNoYWluaW5nLCBtYXRjaGluZ1xuICoge0BsaW5rIERJU01JU1NfVFJVU1RfRElBTE9HX0VYUFJ9OiB0aGUgc2FtZSBleHByZXNzaW9uIGhhcyB0byBwYXJzZSBvbiB0aGVcbiAqIENocm9taXVtIDgwLWVyYSByZW5kZXJlcnMgb2YgdGhlIG9sZGVzdCBzdXBwb3J0ZWQgT2JzaWRpYW4gdmVyc2lvbnMgKEwyNikuXG4gKlxuICogQXJtaW5nIGlzIGlkZW1wb3RlbnQgXHUyMDE0IGEgc2Vjb25kIGV2YWx1YXRpb24gZmluZHMgdGhlIHN0b3JlZCBzb2NrZXQgYW5kXG4gKiByZXR1cm5zIHdpdGhvdXQgb3BlbmluZyBhbm90aGVyIGNvbm5lY3Rpb24sIHNvIGEgcmV0cmllZCByZWFkaW5lc3MgcGFzcyBkb2VzXG4gKiBub3QgcGlsZSB1cCBzb2NrZXRzLlxuICpcbiAqIEBwYXJhbSBwb3J0IC0gVGhlIGxvb3BiYWNrIHBvcnQgcmV0dXJuZWQgYnkge0BsaW5rIHN0YXJ0UGFyZW50TGl2ZW5lc3NTZXJ2ZXJ9LlxuICogQHJldHVybnMgVGhlIGV4cHJlc3Npb24gdG8gZXZhbHVhdGUsIHlpZWxkaW5nIGAnYXJtZWQnYCwgYCdhbHJlYWR5LWFybWVkJ2AsIG9yIGAndW5hdmFpbGFibGUnYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUGFyZW50TGl2ZW5lc3NXYXRjaGRvZ0V4cHJlc3Npb24ocG9ydDogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAoZnVuY3Rpb24oKSB7XG4gIHZhciBGTEFHID0gJ19fb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmdQYXJlbnRMaXZlbmVzcyc7XG4gIGlmICh3aW5kb3dbRkxBR10pIHsgcmV0dXJuICdhbHJlYWR5LWFybWVkJzsgfVxuICB2YXIgbmV0O1xuICB0cnkge1xuICAgIG5ldCA9IHdpbmRvdy5yZXF1aXJlKCdub2RlOm5ldCcpO1xuICB9IGNhdGNoIChub2RlUHJlZml4RXJyb3IpIHtcbiAgICB0cnkge1xuICAgICAgbmV0ID0gd2luZG93LnJlcXVpcmUoJ25ldCcpO1xuICAgIH0gY2F0Y2ggKGJhcmVQcmVmaXhFcnJvcikge1xuICAgICAgcmV0dXJuICd1bmF2YWlsYWJsZSc7XG4gICAgfVxuICB9XG4gIHZhciBQT1JUID0gJHtTdHJpbmcocG9ydCl9O1xuICB2YXIgSE9TVCA9ICcke1BBUkVOVF9MSVZFTkVTU19IT1NUfSc7XG4gIHZhciBSRUNPTk5FQ1RfQVRURU1QVF9MSU1JVCA9ICR7U3RyaW5nKFJFQ09OTkVDVF9BVFRFTVBUX0xJTUlUKX07XG4gIHZhciBSRUNPTk5FQ1RfREVMQVlfSU5fTUlMTElTRUNPTkRTID0gJHtTdHJpbmcoUkVDT05ORUNUX0RFTEFZX0lOX01JTExJU0VDT05EUyl9O1xuICB2YXIgc29ja2V0ID0gbmV0LmNvbm5lY3QoUE9SVCwgSE9TVCk7XG4gIHdpbmRvd1tGTEFHXSA9IHNvY2tldDtcbiAgdmFyIGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gIHNvY2tldC5vbignY29ubmVjdCcsIGZ1bmN0aW9uKCkgeyBpc0Nvbm5lY3RlZCA9IHRydWU7IH0pO1xuICBzb2NrZXQub24oJ2Vycm9yJywgZnVuY3Rpb24oKSB7IC8qIFRoZSBjbG9zZSBoYW5kbGVyIGJlbG93IGRlY2lkZXMgd2hhdCBhbiBlcnJvciBtZWFudC4gKi8gfSk7XG4gIHNvY2tldC5vbignY2xvc2UnLCBmdW5jdGlvbigpIHtcbiAgICAvKiBGYWlsIG9wZW46IGEgY29ubmVjdGlvbiB0aGF0IG5ldmVyIGVzdGFibGlzaGVkIGlzIG5vIGV2aWRlbmNlIHRoZSBoYXJuZXNzIGRpZWQuICovXG4gICAgaWYgKCFpc0Nvbm5lY3RlZCkgeyByZXR1cm47IH1cbiAgICByZWNvbm5lY3QoMSk7XG4gIH0pO1xuICByZXR1cm4gJ2FybWVkJztcblxuICAvKiBBIGNsb3NlIG9ubHkgYXNrcyB0aGUgcXVlc3Rpb24uIFJlY29ubmVjdGluZyBhbnN3ZXJzIGl0LiAqL1xuICBmdW5jdGlvbiByZWNvbm5lY3QoYXR0ZW1wdCkge1xuICAgIHZhciBkaWRDb25uZWN0ID0gZmFsc2U7XG4gICAgdmFyIHByb2JlID0gbmV0LmNvbm5lY3QoUE9SVCwgSE9TVCk7XG4gICAgcHJvYmUub24oJ2Nvbm5lY3QnLCBmdW5jdGlvbigpIHtcbiAgICAgIC8qIFNvbWVvbmUgaXMgc3RpbGwgbGlzdGVuaW5nLCBzbyB0aGUgaGFybmVzcyBpcyBhbGl2ZS4gVGhpcyBpcyB0aGUgbmV3IHRva2VuLiAqL1xuICAgICAgZGlkQ29ubmVjdCA9IHRydWU7XG4gICAgICB3aW5kb3dbRkxBR10gPSBwcm9iZTtcbiAgICAgIHByb2JlLm9uKCdjbG9zZScsIGZ1bmN0aW9uKCkgeyByZWNvbm5lY3QoMSk7IH0pO1xuICAgIH0pO1xuICAgIHByb2JlLm9uKCdlcnJvcicsIGZ1bmN0aW9uKCkge1xuICAgICAgLypcbiAgICAgICAqIFRoaXMgaGFuZGxlciBvdXRsaXZlcyB0aGUgY29ubmVjdCwgc28gaXQgZG91YmxlcyBhcyB0aGUgYWRvcHRlZCBzb2NrZXQnc1xuICAgICAgICogZXJyb3IgaGFuZGxlci4gT25jZSBjb25uZWN0ZWQsIGFuIGVycm9yIHNheXMgbm90aGluZyBhYm91dCB0aGUgaGFybmVzcyBcdTIwMTRcbiAgICAgICAqIHRoZSBjbG9zZSB0aGF0IGZvbGxvd3MgaXQgcmUtcnVucyB0aGUgcHJvYmUuXG4gICAgICAgKi9cbiAgICAgIGlmIChkaWRDb25uZWN0KSB7IHJldHVybjsgfVxuICAgICAgaWYgKGF0dGVtcHQgPCBSRUNPTk5FQ1RfQVRURU1QVF9MSU1JVCkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyByZWNvbm5lY3QoYXR0ZW1wdCArIDEpOyB9LCBSRUNPTk5FQ1RfREVMQVlfSU5fTUlMTElTRUNPTkRTKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLyogTm90aGluZyBhbnN3ZXJlZCBhZnRlciBzZXZlcmFsIHRyaWVzOiB0aGUgaGFybmVzcyByZWFsbHkgaXMgZ29uZS4gKi9cbiAgICAgIGRlc3Ryb3lXaW5kb3coKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlc3Ryb3lXaW5kb3coKSB7XG4gICAgdHJ5IHtcbiAgICAgIHdpbmRvdy5lbGVjdHJvbldpbmRvdy5kZXN0cm95KCk7XG4gICAgfSBjYXRjaCAoZGVzdHJveUVycm9yKSB7XG4gICAgICB3aW5kb3cuY2xvc2UoKTtcbiAgICB9XG4gIH1cbn0pKClgO1xufVxuXG4vKipcbiAqIFN0YXJ0cyB0aGUgbG9vcGJhY2sgbGl2ZW5lc3Mgc2VydmVyIHRoZSBvd25lZCBpbnN0YW5jZSdzIHJlbmRlcmVyIGNvbm5lY3RzXG4gKiBiYWNrIHRvLlxuICpcbiAqIFRoZSBzZXJ2ZXIgYW5kIGV2ZXJ5IGFjY2VwdGVkIHNvY2tldCBhcmUgYHVucmVmYGVkLCBzbyBob2xkaW5nIGEgd2F0Y2hkb2dcbiAqIGNvbm5lY3Rpb24gb3BlbiBuZXZlciBrZWVwcyB0aGUgaGFybmVzcyBwcm9jZXNzIGFsaXZlIG9uIGl0cyBvd24gXHUyMDE0IHRoZVxuICogY29ubmVjdGlvbiBpcyBhIHRva2VuIHRoZSBrZXJuZWwgcmVjbGFpbXMsIG5vdCB3b3JrIHRvIHdhaXQgb24uXG4gKlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gcmVzb2x2aW5nIHRvIHRoZSBsaXN0ZW5pbmcge0BsaW5rIFBhcmVudExpdmVuZXNzU2VydmVyfS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0YXJ0UGFyZW50TGl2ZW5lc3NTZXJ2ZXIoKTogUHJvbWlzZTxQYXJlbnRMaXZlbmVzc1NlcnZlcj4ge1xuICBjb25zdCBzZXJ2ZXIgPSBjcmVhdGVTZXJ2ZXIoKHNvY2tldCkgPT4ge1xuICAgIHNvY2tldC51bnJlZigpO1xuICAgIC8vIFRoZSBjb25uZWN0aW9uIGNhcnJpZXMgbm8gZGF0YSBcdTIwMTQgaXQgZXhpc3RzIG9ubHkgc28gaXRzIGNsb3NlIGlzIG9ic2VydmFibGUuXG4gICAgc29ja2V0Lm9uKCdlcnJvcicsICgpID0+IHtcbiAgICAgIC8vIEEgcmVuZGVyZXIgdG9ybiBkb3duIG1pZC1jb25uZWN0aW9uIHJlc2V0cyByYXRoZXIgdGhhbiBjbG9zZXM7IG5vdCBhbiBlcnJvciBoZXJlLlxuICAgIH0pO1xuICB9KTtcbiAgc2VydmVyLnVucmVmKCk7XG5cbiAgY29uc3QgcG9ydCA9IGF3YWl0IGxpc3Rlbk9uRnJlZUxvb3BiYWNrUG9ydChzZXJ2ZXIpO1xuICByZXR1cm4ge1xuICAgIGNsb3NlKCk6IHZvaWQge1xuICAgICAgc2VydmVyLmNsb3NlKCk7XG4gICAgfSxcbiAgICBwb3J0XG4gIH07XG59XG5cbi8qKlxuICogQmluZHMgdGhlIHNlcnZlciB0byBhbiBlcGhlbWVyYWwgbG9vcGJhY2sgcG9ydCBhbmQgcmVwb3J0cyB3aGljaCBvbmUgaXQgZ290LlxuICpcbiAqIEBwYXJhbSBzZXJ2ZXIgLSBUaGUgc2VydmVyIHRvIGJpbmQuXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSByZXNvbHZpbmcgdG8gdGhlIGFzc2lnbmVkIHBvcnQuXG4gKiBAdGhyb3dzIElmIHRoZSBzZXJ2ZXIgcmVwb3J0cyBhbiBlcnJvciBiZWZvcmUgbGlzdGVuaW5nLCBvciBiaW5kcyB0byBhIHBpcGUgcmF0aGVyIHRoYW4gYSBwb3J0LlxuICovXG5hc3luYyBmdW5jdGlvbiBsaXN0ZW5PbkZyZWVMb29wYmFja1BvcnQoc2VydmVyOiBTZXJ2ZXIpOiBQcm9taXNlPG51bWJlcj4ge1xuICByZXR1cm4gbmV3IFByb21pc2U8bnVtYmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgc2VydmVyLm9uY2UoJ2Vycm9yJywgcmVqZWN0KTtcbiAgICBzZXJ2ZXIubGlzdGVuKDAsIFBBUkVOVF9MSVZFTkVTU19IT1NULCAoKSA9PiB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gc2VydmVyLmFkZHJlc3MoKTtcbiAgICAgIGlmIChhZGRyZXNzID09PSBudWxsIHx8IHR5cGVvZiBhZGRyZXNzID09PSAnc3RyaW5nJykge1xuICAgICAgICBzZXJ2ZXIuY2xvc2UoKTtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignRmFpbGVkIHRvIGRldGVybWluZSB0aGUgcGFyZW50LWxpdmVuZXNzIHBvcnQuJykpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICByZXNvbHZlKGFkZHJlc3MucG9ydCk7XG4gICAgfSk7XG4gIH0pO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFnRUEsc0JBQTZCO0FBMkJ0QixNQUFNLHVCQUF1QjtBQVdwQyxNQUFNLDBCQUEwQjtBQVFoQyxNQUFNLGtDQUFrQztBQWlCakMsU0FBUyxzQ0FBc0MsTUFBc0I7QUFDMUUsU0FBTztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGVBYU0sT0FBTyxJQUFJLENBQUM7QUFBQSxnQkFDWCxvQkFBb0I7QUFBQSxrQ0FDRixPQUFPLHVCQUF1QixDQUFDO0FBQUEsMENBQ3ZCLE9BQU8sK0JBQStCLENBQUM7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQStDakY7QUFZQSxlQUFzQiw0QkFBMkQ7QUFDL0UsUUFBTSxhQUFTLDhCQUFhLENBQUMsV0FBVztBQUN0QyxXQUFPLE1BQU07QUFFYixXQUFPLEdBQUcsU0FBUyxNQUFNO0FBQUEsSUFFekIsQ0FBQztBQUFBLEVBQ0gsQ0FBQztBQUNELFNBQU8sTUFBTTtBQUViLFFBQU0sT0FBTyxNQUFNLHlCQUF5QixNQUFNO0FBQ2xELFNBQU87QUFBQSxJQUNMLFFBQWM7QUFDWixhQUFPLE1BQU07QUFBQSxJQUNmO0FBQUEsSUFDQTtBQUFBLEVBQ0Y7QUFDRjtBQVNBLGVBQWUseUJBQXlCLFFBQWlDO0FBQ3ZFLFNBQU8sSUFBSSxRQUFnQixDQUFDLFNBQVMsV0FBVztBQUM5QyxXQUFPLEtBQUssU0FBUyxNQUFNO0FBQzNCLFdBQU8sT0FBTyxHQUFHLHNCQUFzQixNQUFNO0FBQzNDLFlBQU0sVUFBVSxPQUFPLFFBQVE7QUFDL0IsVUFBSSxZQUFZLFFBQVEsT0FBTyxZQUFZLFVBQVU7QUFDbkQsZUFBTyxNQUFNO0FBQ2IsZUFBTyxJQUFJLE1BQU0sK0NBQStDLENBQUM7QUFDakU7QUFBQSxNQUNGO0FBQ0EsY0FBUSxRQUFRLElBQUk7QUFBQSxJQUN0QixDQUFDO0FBQUEsRUFDSCxDQUFDO0FBQ0g7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -24,11 +24,37 @@
24
24
  * So we use the one cross-platform resource the kernel *does* reclaim
25
25
  * deterministically on process death: a socket. The harness listens on a
26
26
  * loopback port and the instance's renderer connects to it. However the harness
27
- * dies — cleanly, `SIGKILL`ed, or crashed — the kernel closes its end, the
28
- * renderer sees `close`, and the window destroys itself. No polling, no
29
- * heartbeat interval, no timeout to tune.
27
+ * dies — cleanly, `SIGKILL`ed, or crashed — the kernel closes its end and the
28
+ * renderer sees `close`. No polling, no heartbeat interval, no timeout to tune.
30
29
  *
31
- * Deliberately fail-open: the renderer only arms the destroy handler after the
30
+ * **A close is a question, not a verdict.** A socket closing is not the same
31
+ * event as a process dying, and treating them as identical destroyed healthy
32
+ * instances: measured on 2026-09-05, a renderer's idle liveness socket sent
33
+ * `FIN` on its own — 3 min 13 s into one run, 11 min 56 s into another — while
34
+ * the harness was still listening and went on working for another 14 minutes.
35
+ * Every test file scheduled after the death then failed in tens of milliseconds
36
+ * with `ECONNREFUSED` on the dead CDP port; the worst run reported 156 such
37
+ * failures across 21 files, not one of them a test result. Why an idle unref'd
38
+ * loopback socket in an Electron renderer does that is not established, and does
39
+ * not need to be: the lifetimes vary run to run, so no fixed timeout explains it.
40
+ *
41
+ * So the `close` handler **verifies before destroying**: it reconnects to the
42
+ * same loopback port. A harness that is alive is still listening, so the
43
+ * reconnect succeeds and the new socket becomes the liveness token; only when
44
+ * nothing answers after a few tries — what a dead harness actually looks like —
45
+ * is the window destroyed. The leak the watchdog exists to prevent is still
46
+ * prevented, and the measured recovery is 11 ms.
47
+ *
48
+ * A reconnect rather than a check on the harness's process id, because it proves
49
+ * the thing the watchdog actually depends on — the liveness server still serving
50
+ * — and it stays correct against a *busy* harness: the kernel completes a
51
+ * loopback handshake out of the listen backlog even while Node's event loop is
52
+ * blocked. Its one residual ambiguity is accepted: a reconnect proves *something*
53
+ * is listening on that ephemeral port, not that it is ours. The probe follows the
54
+ * close by milliseconds, so another process winning that exact port in between is
55
+ * not a risk worth a handshake protocol.
56
+ *
57
+ * Deliberately fail-open: the renderer only arms the destroy path after the
32
58
  * connection is actually established. A watchdog that cannot reach the harness
33
59
  * leaves the instance running rather than killing a window the developer is
34
60
  * working in.
@@ -39,7 +65,13 @@
39
65
  */
40
66
  export interface ParentLivenessServer {
41
67
  /**
42
- Stops listening and drops every accepted connection.
68
+ * Stops listening.
69
+ *
70
+ * Node keeps already-accepted connections alive across a `close()`, so this
71
+ * does not by itself signal the renderer — the kernel reclaiming the socket on
72
+ * process death is what does. What it does guarantee is that a watchdog probe
73
+ * arriving afterwards is refused, which is the answer a torn-down harness
74
+ * should give.
43
75
  */
44
76
  close(): void;
45
77
  /**
@@ -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 port_owner_exports = {};
20
+ __export(port_owner_exports, {
21
+ parsePosixLsofPids: () => parsePosixLsofPids,
22
+ parseWindowsNetstatPids: () => parseWindowsNetstatPids
23
+ });
24
+ module.exports = __toCommonJS(port_owner_exports);
25
+ const LISTENING_STATE = "LISTENING";
26
+ const RADIX_DECIMAL = 10;
27
+ const TCP_PROTOCOL = "TCP";
28
+ const WHITESPACE_PATTERN = /\s+/;
29
+ function parsePosixLsofPids(lsofOutput) {
30
+ const pids = [];
31
+ for (const line of lsofOutput.split("\n")) {
32
+ const pid = Number.parseInt(line.trim(), RADIX_DECIMAL);
33
+ if (Number.isNaN(pid) || pids.includes(pid)) {
34
+ continue;
35
+ }
36
+ pids.push(pid);
37
+ }
38
+ return pids;
39
+ }
40
+ function parseWindowsNetstatPids(params) {
41
+ const localAddressSuffix = `:${String(params.port)}`;
42
+ const pids = [];
43
+ for (const rawLine of params.netstatOutput.split("\n")) {
44
+ const [protocol = "", localAddress = "", , state = "", rawPid = ""] = rawLine.trim().split(WHITESPACE_PATTERN);
45
+ if (protocol !== TCP_PROTOCOL || state !== LISTENING_STATE || !localAddress.endsWith(localAddressSuffix)) {
46
+ continue;
47
+ }
48
+ const pid = Number.parseInt(rawPid, RADIX_DECIMAL);
49
+ if (Number.isNaN(pid) || pids.includes(pid)) {
50
+ continue;
51
+ }
52
+ pids.push(pid);
53
+ }
54
+ return pids;
55
+ }
56
+ // Annotate the CommonJS export names for ESM import in node:
57
+ 0 && (module.exports = {
58
+ parsePosixLsofPids,
59
+ parseWindowsNetstatPids
60
+ });
61
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3BvcnQtb3duZXIudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBQdXJlIGhlbHBlcnMgZm9yIGFuc3dlcmluZyBcIndoaWNoIHByb2Nlc3MgaXMgc3RpbGwgaG9sZGluZyB0aGlzIHBvcnQ/XCIuXG4gKlxuICogQSB0ZWFyZG93biB0aGF0IGNhbm5vdCBhbnN3ZXIgdGhhdCBxdWVzdGlvbiBjYW4gb25seSByZS1pc3N1ZSB0aGUgc2FtZSBraWxsIGF0XG4gKiB0aGUgc2FtZSBQSUQsIHdoaWNoIGlzIG5vIGVzY2FsYXRpb24gYXQgYWxsOiB0aGUgUElEIHRoZSBoYXJuZXNzIGhvbGRzIGlzIHRoZVxuICogc2hlbGwgd3JhcHBlciBpdCBzcGF3bmVkLCBhbmQgd2hhdCBzdXJ2aXZlcyBpcyB3aGF0ZXZlciB0aGF0IHdyYXBwZXIncyB0cmVlXG4gKiB3YWxrIGZhaWxlZCB0byByZWFjaC4gVGhlIHBvcnQsIGJ5IGNvbnRyYXN0LCBpcyBkaXJlY3QgZXZpZGVuY2UgXHUyMDE0IGEgc29ja2V0XG4gKiBzdGlsbCBhbnN3ZXJpbmcgb24gNDcyMyBhZnRlciB0aGlzIHJ1biBraWxsZWQgdGhlIHNlcnZlciBpdCBzdGFydGVkIGJlbG9uZ3MgdG9cbiAqIHRoYXQgc2VydmVyLlxuICpcbiAqIEtlcHQgc2VwYXJhdGUgZnJvbSB0aGUgaW50ZWdyYXRpb24tb25seSBgdHJhbnNwb3J0LWZhY3RvcnlgIHNvIHRoZSBwYXJzaW5nXG4gKiBzdGF5cyB1bml0LXRlc3RhYmxlOyB0aGUgZmFjdG9yeSBzaGVsbHMgb3V0IHRvIGBuZXRzdGF0YCAvIGBsc29mYC5cbiAqL1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBwYXJzZVdpbmRvd3NOZXRzdGF0UGlkc30uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGFyc2VXaW5kb3dzTmV0c3RhdFBpZHNQYXJhbXMge1xuICAvKipcbiAgUmF3IHN0ZG91dCBvZiBgbmV0c3RhdCAtYW5vYC5cbiAgICovXG4gIHJlYWRvbmx5IG5ldHN0YXRPdXRwdXQ6IHN0cmluZztcblxuICAvKipcbiAgVGhlIGxvY2FsIHBvcnQgd2hvc2UgbGlzdGVuZXIgaXMgd2FudGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xufVxuXG5jb25zdCBMSVNURU5JTkdfU1RBVEUgPSAnTElTVEVOSU5HJztcbmNvbnN0IFJBRElYX0RFQ0lNQUwgPSAxMDtcbmNvbnN0IFRDUF9QUk9UT0NPTCA9ICdUQ1AnO1xuY29uc3QgV0hJVEVTUEFDRV9QQVRURVJOID0gL1xccysvO1xuXG4vKipcbiAqIFBhcnNlcyBgbHNvZiAtdGkgdGNwOjxwb3J0PmAgb3V0cHV0LCB3aGljaCBpcyBhbHJlYWR5IG9uZSBQSUQgcGVyIGxpbmUuXG4gKlxuICogQHBhcmFtIGxzb2ZPdXRwdXQgLSBSYXcgc3Rkb3V0IG9mIHRoZSBgbHNvZmAgcXVlcnkuXG4gKiBAcmV0dXJucyBUaGUgZGlzdGluY3QgUElEcywgaW4gbGlzdGVkIG9yZGVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VQb3NpeExzb2ZQaWRzKGxzb2ZPdXRwdXQ6IHN0cmluZyk6IG51bWJlcltdIHtcbiAgY29uc3QgcGlkczogbnVtYmVyW10gPSBbXTtcblxuICBmb3IgKGNvbnN0IGxpbmUgb2YgbHNvZk91dHB1dC5zcGxpdCgnXFxuJykpIHtcbiAgICBjb25zdCBwaWQgPSBOdW1iZXIucGFyc2VJbnQobGluZS50cmltKCksIFJBRElYX0RFQ0lNQUwpO1xuICAgIGlmIChOdW1iZXIuaXNOYU4ocGlkKSB8fCBwaWRzLmluY2x1ZGVzKHBpZCkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHBpZHMucHVzaChwaWQpO1xuICB9XG5cbiAgcmV0dXJuIHBpZHM7XG59XG5cbi8qKlxuICogUGFyc2VzIGBuZXRzdGF0IC1hbm9gIG91dHB1dCBmb3IgdGhlIFBJRHMgKipsaXN0ZW5pbmcqKiBvbiBhIHBvcnQuXG4gKlxuICogT25seSBgVENQYCByb3dzIGluIHRoZSBgTElTVEVOSU5HYCBzdGF0ZSBjb3VudDogYW4gZXN0YWJsaXNoZWQgY29ubmVjdGlvbiAqdG8qXG4gKiB0aGUgcG9ydCBiZWxvbmdzIHRvIGEgY2xpZW50LCBub3QgdG8gdGhlIHNlcnZlciB0aGF0IG11c3QgZGllLCBhbmQgdGhlIGBVRFBgXG4gKiByb3dzIGhhdmUgbm8gc3RhdGUgY29sdW1uIGF0IGFsbC4gVGhlIHNhbWUgc2VydmVyIGFwcGVhcnMgdHdpY2Ugd2hlbiBpdCBiaW5kc1xuICogYm90aCBJUHY0IGFuZCBJUHY2LCBzbyBQSURzIGFyZSBkZS1kdXBsaWNhdGVkLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgbGlzdGluZyBvdXRwdXQgYW5kIHRoZSBwb3J0IHRvIG1hdGNoLlxuICogQHJldHVybnMgVGhlIGRpc3RpbmN0IGxpc3RlbmluZyBQSURzLCBpbiBsaXN0ZWQgb3JkZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVdpbmRvd3NOZXRzdGF0UGlkcyhwYXJhbXM6IFBhcnNlV2luZG93c05ldHN0YXRQaWRzUGFyYW1zKTogbnVtYmVyW10ge1xuICBjb25zdCBsb2NhbEFkZHJlc3NTdWZmaXggPSBgOiR7U3RyaW5nKHBhcmFtcy5wb3J0KX1gO1xuICBjb25zdCBwaWRzOiBudW1iZXJbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgcmF3TGluZSBvZiBwYXJhbXMubmV0c3RhdE91dHB1dC5zcGxpdCgnXFxuJykpIHtcbiAgICBjb25zdCBbcHJvdG9jb2wgPSAnJywgbG9jYWxBZGRyZXNzID0gJycsICwgc3RhdGUgPSAnJywgcmF3UGlkID0gJyddID0gcmF3TGluZS50cmltKCkuc3BsaXQoV0hJVEVTUEFDRV9QQVRURVJOKTtcbiAgICBpZiAocHJvdG9jb2wgIT09IFRDUF9QUk9UT0NPTCB8fCBzdGF0ZSAhPT0gTElTVEVOSU5HX1NUQVRFIHx8ICFsb2NhbEFkZHJlc3MuZW5kc1dpdGgobG9jYWxBZGRyZXNzU3VmZml4KSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3QgcGlkID0gTnVtYmVyLnBhcnNlSW50KHJhd1BpZCwgUkFESVhfREVDSU1BTCk7XG4gICAgaWYgKE51bWJlci5pc05hTihwaWQpIHx8IHBpZHMuaW5jbHVkZXMocGlkKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgcGlkcy5wdXNoKHBpZCk7XG4gIH1cblxuICByZXR1cm4gcGlkcztcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQStCQSxNQUFNLGtCQUFrQjtBQUN4QixNQUFNLGdCQUFnQjtBQUN0QixNQUFNLGVBQWU7QUFDckIsTUFBTSxxQkFBcUI7QUFRcEIsU0FBUyxtQkFBbUIsWUFBOEI7QUFDL0QsUUFBTSxPQUFpQixDQUFDO0FBRXhCLGFBQVcsUUFBUSxXQUFXLE1BQU0sSUFBSSxHQUFHO0FBQ3pDLFVBQU0sTUFBTSxPQUFPLFNBQVMsS0FBSyxLQUFLLEdBQUcsYUFBYTtBQUN0RCxRQUFJLE9BQU8sTUFBTSxHQUFHLEtBQUssS0FBSyxTQUFTLEdBQUcsR0FBRztBQUMzQztBQUFBLElBQ0Y7QUFFQSxTQUFLLEtBQUssR0FBRztBQUFBLEVBQ2Y7QUFFQSxTQUFPO0FBQ1Q7QUFhTyxTQUFTLHdCQUF3QixRQUFpRDtBQUN2RixRQUFNLHFCQUFxQixJQUFJLE9BQU8sT0FBTyxJQUFJLENBQUM7QUFDbEQsUUFBTSxPQUFpQixDQUFDO0FBRXhCLGFBQVcsV0FBVyxPQUFPLGNBQWMsTUFBTSxJQUFJLEdBQUc7QUFDdEQsVUFBTSxDQUFDLFdBQVcsSUFBSSxlQUFlLElBQUksRUFBRSxRQUFRLElBQUksU0FBUyxFQUFFLElBQUksUUFBUSxLQUFLLEVBQUUsTUFBTSxrQkFBa0I7QUFDN0csUUFBSSxhQUFhLGdCQUFnQixVQUFVLG1CQUFtQixDQUFDLGFBQWEsU0FBUyxrQkFBa0IsR0FBRztBQUN4RztBQUFBLElBQ0Y7QUFFQSxVQUFNLE1BQU0sT0FBTyxTQUFTLFFBQVEsYUFBYTtBQUNqRCxRQUFJLE9BQU8sTUFBTSxHQUFHLEtBQUssS0FBSyxTQUFTLEdBQUcsR0FBRztBQUMzQztBQUFBLElBQ0Y7QUFFQSxTQUFLLEtBQUssR0FBRztBQUFBLEVBQ2Y7QUFFQSxTQUFPO0FBQ1Q7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Pure helpers for answering "which process is still holding this port?".
5
+ *
6
+ * A teardown that cannot answer that question can only re-issue the same kill at
7
+ * the same PID, which is no escalation at all: the PID the harness holds is the
8
+ * shell wrapper it spawned, and what survives is whatever that wrapper's tree
9
+ * walk failed to reach. The port, by contrast, is direct evidence — a socket
10
+ * still answering on 4723 after this run killed the server it started belongs to
11
+ * that server.
12
+ *
13
+ * Kept separate from the integration-only `transport-factory` so the parsing
14
+ * stays unit-testable; the factory shells out to `netstat` / `lsof`.
15
+ */
16
+ /**
17
+ * Parameters for {@link parseWindowsNetstatPids}.
18
+ */
19
+ export interface ParseWindowsNetstatPidsParams {
20
+ /**
21
+ Raw stdout of `netstat -ano`.
22
+ */
23
+ readonly netstatOutput: string;
24
+ /**
25
+ The local port whose listener is wanted.
26
+ */
27
+ readonly port: number;
28
+ }
29
+ /**
30
+ * Parses `lsof -ti tcp:<port>` output, which is already one PID per line.
31
+ *
32
+ * @param lsofOutput - Raw stdout of the `lsof` query.
33
+ * @returns The distinct PIDs, in listed order.
34
+ */
35
+ export declare function parsePosixLsofPids(lsofOutput: string): number[];
36
+ /**
37
+ * Parses `netstat -ano` output for the PIDs **listening** on a port.
38
+ *
39
+ * Only `TCP` rows in the `LISTENING` state count: an established connection *to*
40
+ * the port belongs to a client, not to the server that must die, and the `UDP`
41
+ * rows have no state column at all. The same server appears twice when it binds
42
+ * both IPv4 and IPv6, so PIDs are de-duplicated.
43
+ *
44
+ * @param params - The listing output and the port to match.
45
+ * @returns The distinct listening PIDs, in listed order.
46
+ */
47
+ export declare function parseWindowsNetstatPids(params: ParseWindowsNetstatPidsParams): number[];
@@ -0,0 +1,62 @@
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 process_capture_exports = {};
20
+ __export(process_capture_exports, {
21
+ attachProcessCapture: () => attachProcessCapture
22
+ });
23
+ module.exports = __toCommonJS(process_capture_exports);
24
+ function attachProcessCapture(child, params) {
25
+ const { maxOutputLengthInCharacters, onChunk } = params;
26
+ let capturedOutput = "";
27
+ let exitInfo;
28
+ let isCapturing = true;
29
+ attachStream(child.stdout, "stdout");
30
+ attachStream(child.stderr, "stderr");
31
+ child.once("exit", (code, signal) => {
32
+ exitInfo = { code, signal };
33
+ });
34
+ child.once("error", (error) => {
35
+ exitInfo = { code: null, signal: null, spawnError: error.message };
36
+ });
37
+ return {
38
+ readExitInfo: () => exitInfo,
39
+ readOutput: () => capturedOutput,
40
+ stopCapture: () => {
41
+ isCapturing = false;
42
+ }
43
+ };
44
+ function attachStream(stream, name) {
45
+ if (!stream) {
46
+ return;
47
+ }
48
+ stream.on("data", (chunk) => {
49
+ const text = chunk.toString();
50
+ onChunk?.({ stream: name, text });
51
+ if (isCapturing) {
52
+ capturedOutput = (capturedOutput + text).slice(-maxOutputLengthInCharacters);
53
+ }
54
+ });
55
+ stream.unref?.();
56
+ }
57
+ }
58
+ // Annotate the CommonJS export names for ESM import in node:
59
+ 0 && (module.exports = {
60
+ attachProcessCapture
61
+ });
62
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3Byb2Nlc3MtY2FwdHVyZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIEF0dGFjaGVzIG91dHB1dCBjYXB0dXJlIGFuZCBleGl0IG9ic2VydmF0aW9uIHRvIGEgc3Bhd25lZCBjaGlsZCBwcm9jZXNzLlxuICpcbiAqIEEgbG9uZy1ydW5uaW5nIGNoaWxkIHNwYXduZWQgd2l0aCBwaXBlZCBzdGRpbyBuZWVkcyB0aHJlZSB0aGluZ3MgZG9uZSB0byBpdCxcbiAqIGFuZCBnZXR0aW5nIGFueSBvZiB0aGVtIHdyb25nIGlzIGl0cyBvd24gYnVnOiBpdHMgcGlwZXMgbXVzdCBiZSAqKmRyYWluZWQqKlxuICogKGEgZnVsbCBPUyBwaXBlIGJ1ZmZlciBibG9ja3MgdGhlIHdyaXRlciBcdTIwMTQgYSBjaGF0dHkgcmVuZGVyZXIgd291bGQgaGFuZyB0aGVcbiAqIGFwcCBpdCBiZWxvbmdzIHRvKSwgaXRzIG91dHB1dCBtdXN0IGJlIGtlcHQgKipib3VuZGVkKiogKGFuIGhvdXIgb2YgbG9ncyBpc1xuICogbm90IGEgZGlhZ25vc3RpYyksIGFuZCBpdHMgYGV4aXRgIC8gYGVycm9yYCBtdXN0IGJlICoqcmVjb3JkZWQqKiBzbyBhIGNhbGxlclxuICogdGhhdCBsYXRlciBmaW5kcyB0aGUgcHJvY2VzcyB1bnJlYWNoYWJsZSBjYW4gc2F5IHdoeSBpbnN0ZWFkIG9mIGd1ZXNzaW5nLlxuICpcbiAqIEV4dHJhY3RlZCBzbyB0aGUgc3RhdGUgbWFjaGluZSBpcyB1bml0LXRlc3RhYmxlOiB0aGUgbGF1bmNoZXJzIHRoYXQgdXNlIGl0XG4gKiAoYG9ic2lkaWFuLWluc3RhbmNlLnRzYCwgYW5kIHRoZSBlbXVsYXRvci9BcHBpdW0gc3Bhd25zIGluXG4gKiBgdHJhbnNwb3J0LWZhY3RvcnkudHNgKSBhcmUgaW50ZWdyYXRpb24tdGltZSBnbHVlIGV4Y2x1ZGVkIGZyb20gdW5pdCB0ZXN0cyxcbiAqIHdoaWNoIGlzIGhvdyB0aGUgb3duZWQgT2JzaWRpYW4gaW5zdGFuY2UgY2FtZSB0byBiZSBzcGF3bmVkIGBzdGRpbzogJ2lnbm9yZSdgXG4gKiB3aXRoIG5vIGBleGl0YCBsaXN0ZW5lciBhdCBhbGwgXHUyMDE0IGl0cyBkZWF0aCB3YXMgdW5vYnNlcnZhYmxlIGJ5IGNvbnN0cnVjdGlvbi5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IENoaWxkUHJvY2VzcyB9IGZyb20gJ25vZGU6Y2hpbGRfcHJvY2Vzcyc7XG5pbXBvcnQgdHlwZSB7IFJlYWRhYmxlIH0gZnJvbSAnbm9kZTpzdHJlYW0nO1xuXG5pbXBvcnQgdHlwZSB7IFByb2Nlc3NFeGl0SW5mbyB9IGZyb20gJy4vcHJvY2Vzcy1leGl0LW1lc3NhZ2UuY2pzJztcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgYXR0YWNoUHJvY2Vzc0NhcHR1cmV9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEF0dGFjaFByb2Nlc3NDYXB0dXJlUGFyYW1zIHtcbiAgLyoqXG4gICAqIEhvdyBtYW55IGNoYXJhY3RlcnMgb2YgdGhlIG1vc3QgcmVjZW50IG91dHB1dCB0byBrZWVwLiBPbGRlciBvdXRwdXQgaXNcbiAgICogZHJvcHBlZCBmcm9tIHRoZSBmcm9udCBhcyBuZXcgb3V0cHV0IGFycml2ZXMuXG4gICAqL1xuICByZWFkb25seSBtYXhPdXRwdXRMZW5ndGhJbkNoYXJhY3RlcnM6IG51bWJlcjtcblxuICAvKipcbiAgICogQ2FsbGVkIGZvciBldmVyeSBjaHVuayBhcyBpdCBhcnJpdmVzLCBmb3IgY2FsbGVycyB0aGF0IHdhbnQgdGhlIG91dHB1dFxuICAgKiAqKmxpdmUqKiAobG9nZ2VkIGFzIHRoZSBwcm9jZXNzIHJ1bnMpIHJhdGhlciB0aGFuIG9ubHkgYXMgYSBwb3N0LW1vcnRlbVxuICAgKiB0YWlsLiBGaXJlcyByZWdhcmRsZXNzIG9mIHtAbGluayBQcm9jZXNzQ2FwdHVyZS5zdG9wQ2FwdHVyZX0sIHdoaWNoIGZyZWV6ZXNcbiAgICogdGhlIHJldGFpbmVkIHRhaWwgYW5kIG5vdGhpbmcgZWxzZS5cbiAgICovXG4gIHJlYWRvbmx5IG9uQ2h1bms/OiAoKGNodW5rOiBQcm9jZXNzT3V0cHV0Q2h1bmspID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEEgY2hpbGQgcHJvY2VzcydzIGNhcHR1cmVkIG91dHB1dCBhbmQgZXhpdCBzdGF0dXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvY2Vzc0NhcHR1cmUge1xuICAvKipcbiAgUmV0dXJucyB0aGUgZXhpdCAvIHNwYXduLWZhaWx1cmUgZGV0YWlscyBvbmNlIHRoZSBwcm9jZXNzIGlzIG5vIGxvbmdlciBydW5uaW5nLCBvdGhlcndpc2UgYHVuZGVmaW5lZGAuXG4gICAqL1xuICByZWFkRXhpdEluZm86ICgpID0+IFByb2Nlc3NFeGl0SW5mbyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgUmV0dXJucyB0aGUgY2FwdHVyZWQgc3Rkb3V0K3N0ZGVyciwgYm91bmRlZCB0byB0aGUgbW9zdCByZWNlbnQgb3V0cHV0LlxuICAgKi9cbiAgcmVhZE91dHB1dDogKCkgPT4gc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTdG9wcyBhY2N1bXVsYXRpbmcgb3V0cHV0LCBmcmVlemluZyB0aGUgdGFpbCBhdCB3aGF0IGhhcyBhcnJpdmVkIHNvIGZhci5cbiAgICogQ2FsbCBvbmNlIHN0YXJ0dXAgaGFzIHN1Y2NlZWRlZCBhbmQgdGhlIHRhaWwgaGFzIHNlcnZlZCBpdHMgcHVycG9zZS5cbiAgICpcbiAgICogVGhlIGBkYXRhYCBsaXN0ZW5lcnMgc3RheSBhdHRhY2hlZCBkZWxpYmVyYXRlbHksIHNvIHRoZSBwaXBlcyBrZWVwIGRyYWluaW5nXG4gICAqIGZvciB0aGUgcmVzdCBvZiB0aGUgcHJvY2VzcydzIGxpZmUuXG4gICAqL1xuICBzdG9wQ2FwdHVyZTogKCkgPT4gdm9pZDtcbn1cblxuLyoqXG4gKiBPbmUgY2h1bmsgb2YgYSBjaGlsZCBwcm9jZXNzJ3Mgb3V0cHV0LCBhbmQgd2hpY2ggc3RyZWFtIGl0IGNhbWUgZnJvbS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9jZXNzT3V0cHV0Q2h1bmsge1xuICAvKipcbiAgVGhlIHN0cmVhbSB0aGUgY2h1bmsgd2FzIHdyaXR0ZW4gdG8uXG4gICAqL1xuICByZWFkb25seSBzdHJlYW06ICdzdGRlcnInIHwgJ3N0ZG91dCc7XG5cbiAgLyoqXG4gIFRoZSBjaHVuaydzIHRleHQuXG4gICAqL1xuICByZWFkb25seSB0ZXh0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIGB1bnJlZmAgYSBwaXBlZCBzdGRpbyBzdHJlYW0gY2FycmllcyB0aHJvdWdoIGl0cyB1bmRlcmx5aW5nIHNvY2tldCwgd2hpY2hcbiAqIGBSZWFkYWJsZWAgYWxvbmUgZG9lcyBub3QgZGVjbGFyZS5cbiAqL1xuaW50ZXJmYWNlIFN0cmVhbVdpdGhVbnJlZiB7XG4gIHVucmVmOiAoKSA9PiB2b2lkO1xufVxuXG4vKipcbiAqIEF0dGFjaGVzIG91dHB1dCBjYXB0dXJlIGFuZCBleGl0IG9ic2VydmF0aW9uIHRvIGFuIGFscmVhZHktc3Bhd25lZCBwcm9jZXNzLlxuICpcbiAqIFRvbGVyYXRlcyBhIHByb2Nlc3Mgc3Bhd25lZCB3aXRob3V0IHBpcGVzIChgc3RkaW86ICdpZ25vcmUnYCBsZWF2ZXNcbiAqIGBzdGRvdXRgIC8gYHN0ZGVycmAgYG51bGxgKTogdGhlIGV4aXQgaGFsZiBzdGlsbCB3b3JrcywgYW5kIHRoZSBjYXB0dXJlZFxuICogb3V0cHV0IHN0YXlzIGVtcHR5LlxuICpcbiAqIEBwYXJhbSBjaGlsZCAtIFRoZSBzcGF3bmVkIHByb2Nlc3MuXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHRhaWwgYnVkZ2V0LCBhbmQgYW4gb3B0aW9uYWwgbGl2ZS1vdXRwdXQgY2FsbGJhY2suXG4gKiBAcmV0dXJucyBSZWFkZXJzIGZvciB0aGUgY2FwdHVyZWQgb3V0cHV0IGFuZCB0aGUgZXhpdCBzdGF0dXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhdHRhY2hQcm9jZXNzQ2FwdHVyZShjaGlsZDogQ2hpbGRQcm9jZXNzLCBwYXJhbXM6IEF0dGFjaFByb2Nlc3NDYXB0dXJlUGFyYW1zKTogUHJvY2Vzc0NhcHR1cmUge1xuICBjb25zdCB7IG1heE91dHB1dExlbmd0aEluQ2hhcmFjdGVycywgb25DaHVuayB9ID0gcGFyYW1zO1xuXG4gIGxldCBjYXB0dXJlZE91dHB1dCA9ICcnO1xuICBsZXQgZXhpdEluZm86IFByb2Nlc3NFeGl0SW5mbyB8IHVuZGVmaW5lZDtcbiAgbGV0IGlzQ2FwdHVyaW5nID0gdHJ1ZTtcblxuICBhdHRhY2hTdHJlYW0oY2hpbGQuc3Rkb3V0LCAnc3Rkb3V0Jyk7XG4gIGF0dGFjaFN0cmVhbShjaGlsZC5zdGRlcnIsICdzdGRlcnInKTtcblxuICBjaGlsZC5vbmNlKCdleGl0JywgKGNvZGU6IG51bGwgfCBudW1iZXIsIHNpZ25hbDogTm9kZUpTLlNpZ25hbHMgfCBudWxsKSA9PiB7XG4gICAgZXhpdEluZm8gPSB7IGNvZGUsIHNpZ25hbCB9O1xuICB9KTtcblxuICAvKlxuICAgKiBBIHNwYXduIGZhaWx1cmUgKGUuZy4gRU5PRU5UIGZvciBhIG1pc3NpbmcgYmluYXJ5KSBlbWl0cyAnZXJyb3InLCBub3RcbiAgICogJ2V4aXQnLiBSZWNvcmQgaXQgYXMgYSBzeW50aGV0aWMgZXhpdCBzbyBhIGNhbGxlciBwb2xsaW5nIGZvciByZWFkaW5lc3MgY2FuXG4gICAqIGZhaWwgZmFzdCBpbnN0ZWFkIG9mIHNwaW5uaW5nIG91dCBpdHMgd2hvbGUgYnVkZ2V0IGFnYWluc3QgYSBwcm9jZXNzIHRoYXRcbiAgICogbmV2ZXIgZXhpc3RlZC5cbiAgICovXG4gIGNoaWxkLm9uY2UoJ2Vycm9yJywgKGVycm9yOiBFcnJvcikgPT4ge1xuICAgIGV4aXRJbmZvID0geyBjb2RlOiBudWxsLCBzaWduYWw6IG51bGwsIHNwYXduRXJyb3I6IGVycm9yLm1lc3NhZ2UgfTtcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICByZWFkRXhpdEluZm86ICgpID0+IGV4aXRJbmZvLFxuICAgIHJlYWRPdXRwdXQ6ICgpID0+IGNhcHR1cmVkT3V0cHV0LFxuICAgIHN0b3BDYXB0dXJlOiAoKTogdm9pZCA9PiB7XG4gICAgICBpc0NhcHR1cmluZyA9IGZhbHNlO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBhdHRhY2hTdHJlYW0oc3RyZWFtOiBudWxsIHwgUmVhZGFibGUsIG5hbWU6IFByb2Nlc3NPdXRwdXRDaHVua1snc3RyZWFtJ10pOiB2b2lkIHtcbiAgICBpZiAoIXN0cmVhbSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN0cmVhbS5vbignZGF0YScsIChjaHVuazogQnVmZmVyKSA9PiB7XG4gICAgICBjb25zdCB0ZXh0ID0gY2h1bmsudG9TdHJpbmcoKTtcbiAgICAgIG9uQ2h1bms/Lih7IHN0cmVhbTogbmFtZSwgdGV4dCB9KTtcbiAgICAgIGlmIChpc0NhcHR1cmluZykge1xuICAgICAgICBjYXB0dXJlZE91dHB1dCA9IChjYXB0dXJlZE91dHB1dCArIHRleHQpLnNsaWNlKC1tYXhPdXRwdXRMZW5ndGhJbkNoYXJhY3RlcnMpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLypcbiAgICAgKiBgY2hpbGQudW5yZWYoKWAgb25seSByZWxlYXNlcyB0aGUgcHJvY2VzcyBoYW5kbGU7IHRoZSBzdGRpbyBwaXBlcyBhcmVcbiAgICAgKiBzZXBhcmF0ZSBoYW5kbGVzIHRoYXQga2VlcCB0aGUgZXZlbnQgbG9vcCBhbGl2ZSBvbiB0aGVpciBvd24uIEEgaGFybmVzc1xuICAgICAqIHRoYXQgcGlwZXMgYSBkZXRhY2hlZCBjaGlsZCdzIG91dHB1dCB3b3VsZCB0aGVuIHJlZnVzZSB0byBleGl0IHVudGlsIHRoYXRcbiAgICAgKiBjaGlsZCBkaWVkIFx1MjAxNCB0aGUgb3Bwb3NpdGUgb2Ygd2hhdCBgZGV0YWNoZWRgICsgYHVucmVmYCB3YXMgYXNrZWQgZm9yLlxuICAgICAqXG4gICAgICogYHVucmVmYCBsaXZlcyBvbiB0aGUgdW5kZXJseWluZyBzb2NrZXQgcmF0aGVyIHRoYW4gb24gYFJlYWRhYmxlYCwgc28gaXQgaXNcbiAgICAgKiByZWFjaGVkIHN0cnVjdHVyYWxseTogYSBzdHJlYW0gdGhhdCBkb2VzIG5vdCBjYXJyeSBvbmUgc2ltcGx5IHNraXBzIHRoaXMuXG4gICAgICovXG4gICAgKHN0cmVhbSBhcyBQYXJ0aWFsPFN0cmVhbVdpdGhVbnJlZj4pLnVucmVmPy4oKTtcbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQXFHTyxTQUFTLHFCQUFxQixPQUFxQixRQUFvRDtBQUM1RyxRQUFNLEVBQUUsNkJBQTZCLFFBQVEsSUFBSTtBQUVqRCxNQUFJLGlCQUFpQjtBQUNyQixNQUFJO0FBQ0osTUFBSSxjQUFjO0FBRWxCLGVBQWEsTUFBTSxRQUFRLFFBQVE7QUFDbkMsZUFBYSxNQUFNLFFBQVEsUUFBUTtBQUVuQyxRQUFNLEtBQUssUUFBUSxDQUFDLE1BQXFCLFdBQWtDO0FBQ3pFLGVBQVcsRUFBRSxNQUFNLE9BQU87QUFBQSxFQUM1QixDQUFDO0FBUUQsUUFBTSxLQUFLLFNBQVMsQ0FBQyxVQUFpQjtBQUNwQyxlQUFXLEVBQUUsTUFBTSxNQUFNLFFBQVEsTUFBTSxZQUFZLE1BQU0sUUFBUTtBQUFBLEVBQ25FLENBQUM7QUFFRCxTQUFPO0FBQUEsSUFDTCxjQUFjLE1BQU07QUFBQSxJQUNwQixZQUFZLE1BQU07QUFBQSxJQUNsQixhQUFhLE1BQVk7QUFDdkIsb0JBQWM7QUFBQSxJQUNoQjtBQUFBLEVBQ0Y7QUFFQSxXQUFTLGFBQWEsUUFBeUIsTUFBMEM7QUFDdkYsUUFBSSxDQUFDLFFBQVE7QUFDWDtBQUFBLElBQ0Y7QUFFQSxXQUFPLEdBQUcsUUFBUSxDQUFDLFVBQWtCO0FBQ25DLFlBQU0sT0FBTyxNQUFNLFNBQVM7QUFDNUIsZ0JBQVUsRUFBRSxRQUFRLE1BQU0sS0FBSyxDQUFDO0FBQ2hDLFVBQUksYUFBYTtBQUNmLDBCQUFrQixpQkFBaUIsTUFBTSxNQUFNLENBQUMsMkJBQTJCO0FBQUEsTUFDN0U7QUFBQSxJQUNGLENBQUM7QUFXRCxJQUFDLE9BQW9DLFFBQVE7QUFBQSxFQUMvQztBQUNGOyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Attaches output capture and exit observation to a spawned child process.
5
+ *
6
+ * A long-running child spawned with piped stdio needs three things done to it,
7
+ * and getting any of them wrong is its own bug: its pipes must be **drained**
8
+ * (a full OS pipe buffer blocks the writer — a chatty renderer would hang the
9
+ * app it belongs to), its output must be kept **bounded** (an hour of logs is
10
+ * not a diagnostic), and its `exit` / `error` must be **recorded** so a caller
11
+ * that later finds the process unreachable can say why instead of guessing.
12
+ *
13
+ * Extracted so the state machine is unit-testable: the launchers that use it
14
+ * (`obsidian-instance.ts`, and the emulator/Appium spawns in
15
+ * `transport-factory.ts`) are integration-time glue excluded from unit tests,
16
+ * which is how the owned Obsidian instance came to be spawned `stdio: 'ignore'`
17
+ * with no `exit` listener at all — its death was unobservable by construction.
18
+ */
19
+ import type { ChildProcess } from 'node:child_process';
20
+ import type { ProcessExitInfo } from './process-exit-message.cjs';
21
+ /**
22
+ * Parameters for {@link attachProcessCapture}.
23
+ */
24
+ export interface AttachProcessCaptureParams {
25
+ /**
26
+ * How many characters of the most recent output to keep. Older output is
27
+ * dropped from the front as new output arrives.
28
+ */
29
+ readonly maxOutputLengthInCharacters: number;
30
+ /**
31
+ * Called for every chunk as it arrives, for callers that want the output
32
+ * **live** (logged as the process runs) rather than only as a post-mortem
33
+ * tail. Fires regardless of {@link ProcessCapture.stopCapture}, which freezes
34
+ * the retained tail and nothing else.
35
+ */
36
+ readonly onChunk?: ((chunk: ProcessOutputChunk) => void) | undefined;
37
+ }
38
+ /**
39
+ * A child process's captured output and exit status.
40
+ */
41
+ export interface ProcessCapture {
42
+ /**
43
+ Returns the exit / spawn-failure details once the process is no longer running, otherwise `undefined`.
44
+ */
45
+ readExitInfo: () => ProcessExitInfo | undefined;
46
+ /**
47
+ Returns the captured stdout+stderr, bounded to the most recent output.
48
+ */
49
+ readOutput: () => string;
50
+ /**
51
+ * Stops accumulating output, freezing the tail at what has arrived so far.
52
+ * Call once startup has succeeded and the tail has served its purpose.
53
+ *
54
+ * The `data` listeners stay attached deliberately, so the pipes keep draining
55
+ * for the rest of the process's life.
56
+ */
57
+ stopCapture: () => void;
58
+ }
59
+ /**
60
+ * One chunk of a child process's output, and which stream it came from.
61
+ */
62
+ export interface ProcessOutputChunk {
63
+ /**
64
+ The stream the chunk was written to.
65
+ */
66
+ readonly stream: 'stderr' | 'stdout';
67
+ /**
68
+ The chunk's text.
69
+ */
70
+ readonly text: string;
71
+ }
72
+ /**
73
+ * Attaches output capture and exit observation to an already-spawned process.
74
+ *
75
+ * Tolerates a process spawned without pipes (`stdio: 'ignore'` leaves
76
+ * `stdout` / `stderr` `null`): the exit half still works, and the captured
77
+ * output stays empty.
78
+ *
79
+ * @param child - The spawned process.
80
+ * @param params - The tail budget, and an optional live-output callback.
81
+ * @returns Readers for the captured output and the exit status.
82
+ */
83
+ export declare function attachProcessCapture(child: ChildProcess, params: AttachProcessCaptureParams): ProcessCapture;
@@ -18,18 +18,23 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var process_exit_message_exports = {};
20
20
  __export(process_exit_message_exports, {
21
+ appendProcessOutputTail: () => appendProcessOutputTail,
21
22
  buildProcessExitMessage: () => buildProcessExitMessage
22
23
  });
23
24
  module.exports = __toCommonJS(process_exit_message_exports);
25
+ function appendProcessOutputTail(message, params) {
26
+ const trimmedOutput = params.output.trim();
27
+ if (trimmedOutput.length === 0) {
28
+ return message;
29
+ }
30
+ return `${message}
31
+
32
+ ${params.outputLabel} (tail):
33
+ ${trimmedOutput}`;
34
+ }
24
35
  function buildProcessExitMessage(params) {
25
36
  const { exitInfo, output, outputLabel, subject } = params;
26
- const reason = resolveReason(exitInfo);
27
- const trimmedOutput = output.trim();
28
- const details = trimmedOutput.length > 0 ? `
29
-
30
- ${outputLabel} (tail):
31
- ${trimmedOutput}` : "";
32
- return `${subject} ${reason} during startup.${details}`;
37
+ return appendProcessOutputTail(`${subject} ${resolveReason(exitInfo)} during startup.`, { output, outputLabel });
33
38
  }
34
39
  function resolveReason(exitInfo) {
35
40
  if (exitInfo.spawnError !== void 0) {
@@ -42,6 +47,7 @@ function resolveReason(exitInfo) {
42
47
  }
43
48
  // Annotate the CommonJS export names for ESM import in node:
44
49
  0 && (module.exports = {
50
+ appendProcessOutputTail,
45
51
  buildProcessExitMessage
46
52
  });
47
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3Byb2Nlc3MtZXhpdC1tZXNzYWdlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogUHVyZSBidWlsZGVyIGZvciB0aGUgZGlhZ25vc3RpYyBtZXNzYWdlIGRlc2NyaWJpbmcgYW4gYXV0by1zdGFydGVkIGNoaWxkXG4gKiBwcm9jZXNzICh0aGUgQW5kcm9pZCBlbXVsYXRvciBvciB0aGUgQXBwaXVtIHNlcnZlcikgdGhhdCBkaWVkIGR1cmluZyBzdGFydHVwLFxuICogYXBwZW5kaW5nIHRoZSBjYXB0dXJlZCBvdXRwdXQgdGFpbCB3aGVuIGF2YWlsYWJsZS5cbiAqXG4gKiBLZXB0IHNlcGFyYXRlIGZyb20gdGhlIGludGVncmF0aW9uLW9ubHkgYHRyYW5zcG9ydC1mYWN0b3J5YCAoZXhjbHVkZWQgZnJvbVxuICogdW5pdCB0ZXN0cykgc28gdGhlIG1lc3NhZ2UgZm9ybWF0dGluZyBzdGF5cyB1bml0LXRlc3RhYmxlIFx1MjAxNCB0aGUgbGF1bmNoZXJzXG4gKiB0aGVtc2VsdmVzIHNwYXduIHJlYWwgcHJvY2Vzc2VzLlxuICovXG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGJ1aWxkUHJvY2Vzc0V4aXRNZXNzYWdlfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBCdWlsZFByb2Nlc3NFeGl0TWVzc2FnZVBhcmFtcyB7XG4gIC8qKlxuICBUaGUgcHJvY2VzcydzIGV4aXQgLyBzcGF3bi1mYWlsdXJlIGRldGFpbHMuXG4gICAqL1xuICByZWFkb25seSBleGl0SW5mbzogUHJvY2Vzc0V4aXRJbmZvO1xuXG4gIC8qKlxuICBUaGUgY2FwdHVyZWQgc3Rkb3V0K3N0ZGVyciB0YWlsIChlbXB0eSB3aGVuIG5vbmUgd2FzIGNhcHR1cmVkKS5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dDogc3RyaW5nO1xuXG4gIC8qKlxuICBMYWJlbCBmb3IgdGhlIGNhcHR1cmVkIG91dHB1dCBzZWN0aW9uIChlLmcuIGBcIkVtdWxhdG9yIG91dHB1dFwiYCkuXG4gICAqL1xuICByZWFkb25seSBvdXRwdXRMYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICBIdW1hbi1yZWFkYWJsZSBzdWJqZWN0IG9mIHRoZSBwcm9jZXNzIChlLmcuIGBcIkFuZHJvaWQgZW11bGF0b3JcImApLlxuICAgKi9cbiAgcmVhZG9ubHkgc3ViamVjdDogc3RyaW5nO1xufVxuXG4vKipcbiAqIERldGFpbHMgb2YgYSBzcGF3bmVkIGNoaWxkIHByb2Nlc3MgdGhhdCBoYXMgZXhpdGVkIG9yIGZhaWxlZCB0byBzcGF3bi5cbiAqXG4gKiBBIG5vcm1hbCBleGl0IHNldHMgYGNvZGVgL2BzaWduYWxgIChleGFjdGx5IG9uZSBpcyBub24tYG51bGxgKTsgYSBzcGF3blxuICogZmFpbHVyZSAoZS5nLiBgRU5PRU5UYCBmb3IgYSBtaXNzaW5nIGJpbmFyeSkgbGVhdmVzIGJvdGggYG51bGxgIGFuZCBzZXRzXG4gKiBgc3Bhd25FcnJvcmAgdG8gdGhlIGZhaWx1cmUgbWVzc2FnZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9jZXNzRXhpdEluZm8ge1xuICAvKipcbiAgRXhpdCBjb2RlLCBvciBgbnVsbGAgd2hlbiB0ZXJtaW5hdGVkIGJ5IGEgc2lnbmFsIG9yIHdoZW4gaXQgZmFpbGVkIHRvIHNwYXduLlxuICAgKi9cbiAgcmVhZG9ubHkgY29kZTogbnVsbCB8IG51bWJlcjtcblxuICAvKipcbiAgVGVybWluYXRpbmcgc2lnbmFsLCBvciBgbnVsbGAgd2hlbiBpdCBleGl0ZWQgbm9ybWFsbHkgb3IgZmFpbGVkIHRvIHNwYXduLlxuICAgKi9cbiAgcmVhZG9ubHkgc2lnbmFsOiBOb2RlSlMuU2lnbmFscyB8IG51bGw7XG5cbiAgLyoqXG4gIFRoZSBzcGF3bi1mYWlsdXJlIG1lc3NhZ2Ugd2hlbiB0aGUgcHJvY2VzcyBuZXZlciBzdGFydGVkIChlLmcuIGBFTk9FTlRgKSwgb3RoZXJ3aXNlIGFic2VudC5cbiAgICovXG4gIHJlYWRvbmx5IHNwYXduRXJyb3I/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQnVpbGRzIGEgZGVzY3JpcHRpdmUgZXJyb3IgbWVzc2FnZSBmb3IgYW4gYXV0by1zdGFydGVkIGNoaWxkIHByb2Nlc3MgdGhhdFxuICogZXhpdGVkIChvciBmYWlsZWQgdG8gc3Bhd24pIGR1cmluZyBzdGFydHVwLCBhcHBlbmRpbmcgdGhlIGNhcHR1cmVkIG91dHB1dFxuICogdGFpbCB3aGVuIGF2YWlsYWJsZS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHN1YmplY3QsIGV4aXQgZGV0YWlscywgYW5kIGNhcHR1cmVkIG91dHB1dC5cbiAqIEByZXR1cm5zIEEgaHVtYW4tcmVhZGFibGUgZXJyb3IgbWVzc2FnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUHJvY2Vzc0V4aXRNZXNzYWdlKHBhcmFtczogQnVpbGRQcm9jZXNzRXhpdE1lc3NhZ2VQYXJhbXMpOiBzdHJpbmcge1xuICBjb25zdCB7IGV4aXRJbmZvLCBvdXRwdXQsIG91dHB1dExhYmVsLCBzdWJqZWN0IH0gPSBwYXJhbXM7XG5cbiAgY29uc3QgcmVhc29uID0gcmVzb2x2ZVJlYXNvbihleGl0SW5mbyk7XG4gIGNvbnN0IHRyaW1tZWRPdXRwdXQgPSBvdXRwdXQudHJpbSgpO1xuICBjb25zdCBkZXRhaWxzID0gdHJpbW1lZE91dHB1dC5sZW5ndGggPiAwXG4gICAgPyBgXFxuXFxuJHtvdXRwdXRMYWJlbH0gKHRhaWwpOlxcbiR7dHJpbW1lZE91dHB1dH1gXG4gICAgOiAnJztcbiAgcmV0dXJuIGAke3N1YmplY3R9ICR7cmVhc29ufSBkdXJpbmcgc3RhcnR1cC4ke2RldGFpbHN9YDtcbn1cblxuLyoqXG4gKiBEZXNjcmliZXMgd2h5IHRoZSBwcm9jZXNzIGlzIG5vIGxvbmdlciBydW5uaW5nLlxuICpcbiAqIEBwYXJhbSBleGl0SW5mbyAtIFRoZSBleGl0IC8gc3Bhd24tZmFpbHVyZSBkZXRhaWxzLlxuICogQHJldHVybnMgVGhlIHJlYXNvbiBjbGF1c2UuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVSZWFzb24oZXhpdEluZm86IFByb2Nlc3NFeGl0SW5mbyk6IHN0cmluZyB7XG4gIGlmIChleGl0SW5mby5zcGF3bkVycm9yICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gYGZhaWxlZCB0byBzdGFydCAoJHtleGl0SW5mby5zcGF3bkVycm9yfSlgO1xuICB9XG4gIGlmIChleGl0SW5mby5zaWduYWwgIT09IG51bGwpIHtcbiAgICByZXR1cm4gYHdhcyB0ZXJtaW5hdGVkIGJ5IHNpZ25hbCAke2V4aXRJbmZvLnNpZ25hbH1gO1xuICB9XG4gIHJldHVybiBgZXhpdGVkIHByZW1hdHVyZWx5IHdpdGggY29kZSAke2V4aXRJbmZvLmNvZGUgPT09IG51bGwgPyAnKG51bGwpJyA6IFN0cmluZyhleGl0SW5mby5jb2RlKX1gO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQXFFTyxTQUFTLHdCQUF3QixRQUErQztBQUNyRixRQUFNLEVBQUUsVUFBVSxRQUFRLGFBQWEsUUFBUSxJQUFJO0FBRW5ELFFBQU0sU0FBUyxjQUFjLFFBQVE7QUFDckMsUUFBTSxnQkFBZ0IsT0FBTyxLQUFLO0FBQ2xDLFFBQU0sVUFBVSxjQUFjLFNBQVMsSUFDbkM7QUFBQTtBQUFBLEVBQU8sV0FBVztBQUFBLEVBQWEsYUFBYSxLQUM1QztBQUNKLFNBQU8sR0FBRyxPQUFPLElBQUksTUFBTSxtQkFBbUIsT0FBTztBQUN2RDtBQVFBLFNBQVMsY0FBYyxVQUFtQztBQUN4RCxNQUFJLFNBQVMsZUFBZSxRQUFXO0FBQ3JDLFdBQU8sb0JBQW9CLFNBQVMsVUFBVTtBQUFBLEVBQ2hEO0FBQ0EsTUFBSSxTQUFTLFdBQVcsTUFBTTtBQUM1QixXQUFPLDRCQUE0QixTQUFTLE1BQU07QUFBQSxFQUNwRDtBQUNBLFNBQU8sZ0NBQWdDLFNBQVMsU0FBUyxPQUFPLFdBQVcsT0FBTyxTQUFTLElBQUksQ0FBQztBQUNsRzsiLAogICJuYW1lcyI6IFtdCn0K
53
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3Byb2Nlc3MtZXhpdC1tZXNzYWdlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogUHVyZSBidWlsZGVycyBmb3IgdGhlIGRpYWdub3N0aWMgbWVzc2FnZSBkZXNjcmliaW5nIGFuIGF1dG8tc3RhcnRlZCBjaGlsZFxuICogcHJvY2VzcyAodGhlIEFuZHJvaWQgZW11bGF0b3Igb3IgdGhlIEFwcGl1bSBzZXJ2ZXIpIHRoYXQgZmFpbGVkIGR1cmluZ1xuICogc3RhcnR1cCwgYXBwZW5kaW5nIHRoZSBjYXB0dXJlZCBvdXRwdXQgdGFpbCB3aGVuIGF2YWlsYWJsZS5cbiAqXG4gKiBBIHN0YXJ0dXAgZmFpbHMgdHdvIHdheXMgXHUyMDE0IHRoZSBwcm9jZXNzICoqZGllcyoqLCBvciBpdCAqKmhhbmdzKiogcGFzdCBhXG4gKiBidWRnZXQgXHUyMDE0IGFuZCB0aGUgY2FwdHVyZWQgdGFpbCBpcyBlcXVhbGx5IHRoZSBleHBsYW5hdGlvbiBpbiBib3RoLiBTbyB0aGVcbiAqIHRhaWwtYXBwZW5kaW5nIGhhbGYgaXMgaXRzIG93biBleHBvcnQsIHVzZWQgYnkgdGhlIHRpbWVvdXQgdGhyb3dzIHRoYXQgb25jZVxuICogcmVwb3J0ZWQgb25seSB0aGUgYnVkZ2V0IHRoZXkgYmxldy5cbiAqXG4gKiBLZXB0IHNlcGFyYXRlIGZyb20gdGhlIGludGVncmF0aW9uLW9ubHkgYHRyYW5zcG9ydC1mYWN0b3J5YCAoZXhjbHVkZWQgZnJvbVxuICogdW5pdCB0ZXN0cykgc28gdGhlIG1lc3NhZ2UgZm9ybWF0dGluZyBzdGF5cyB1bml0LXRlc3RhYmxlIFx1MjAxNCB0aGUgbGF1bmNoZXJzXG4gKiB0aGVtc2VsdmVzIHNwYXduIHJlYWwgcHJvY2Vzc2VzLlxuICovXG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGFwcGVuZFByb2Nlc3NPdXRwdXRUYWlsfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcHBlbmRQcm9jZXNzT3V0cHV0VGFpbFBhcmFtcyB7XG4gIC8qKlxuICBUaGUgY2FwdHVyZWQgc3Rkb3V0K3N0ZGVyciB0YWlsIChlbXB0eSB3aGVuIG5vbmUgd2FzIGNhcHR1cmVkKS5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dDogc3RyaW5nO1xuXG4gIC8qKlxuICBMYWJlbCBmb3IgdGhlIGNhcHR1cmVkIG91dHB1dCBzZWN0aW9uIChlLmcuIGBcIkVtdWxhdG9yIG91dHB1dFwiYCkuXG4gICAqL1xuICByZWFkb25seSBvdXRwdXRMYWJlbDogc3RyaW5nO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBidWlsZFByb2Nlc3NFeGl0TWVzc2FnZX0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQnVpbGRQcm9jZXNzRXhpdE1lc3NhZ2VQYXJhbXMge1xuICAvKipcbiAgVGhlIHByb2Nlc3MncyBleGl0IC8gc3Bhd24tZmFpbHVyZSBkZXRhaWxzLlxuICAgKi9cbiAgcmVhZG9ubHkgZXhpdEluZm86IFByb2Nlc3NFeGl0SW5mbztcblxuICAvKipcbiAgVGhlIGNhcHR1cmVkIHN0ZG91dCtzdGRlcnIgdGFpbCAoZW1wdHkgd2hlbiBub25lIHdhcyBjYXB0dXJlZCkuXG4gICAqL1xuICByZWFkb25seSBvdXRwdXQ6IHN0cmluZztcblxuICAvKipcbiAgTGFiZWwgZm9yIHRoZSBjYXB0dXJlZCBvdXRwdXQgc2VjdGlvbiAoZS5nLiBgXCJFbXVsYXRvciBvdXRwdXRcImApLlxuICAgKi9cbiAgcmVhZG9ubHkgb3V0cHV0TGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgSHVtYW4tcmVhZGFibGUgc3ViamVjdCBvZiB0aGUgcHJvY2VzcyAoZS5nLiBgXCJBbmRyb2lkIGVtdWxhdG9yXCJgKS5cbiAgICovXG4gIHJlYWRvbmx5IHN1YmplY3Q6IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZXRhaWxzIG9mIGEgc3Bhd25lZCBjaGlsZCBwcm9jZXNzIHRoYXQgaGFzIGV4aXRlZCBvciBmYWlsZWQgdG8gc3Bhd24uXG4gKlxuICogQSBub3JtYWwgZXhpdCBzZXRzIGBjb2RlYC9gc2lnbmFsYCAoZXhhY3RseSBvbmUgaXMgbm9uLWBudWxsYCk7IGEgc3Bhd25cbiAqIGZhaWx1cmUgKGUuZy4gYEVOT0VOVGAgZm9yIGEgbWlzc2luZyBiaW5hcnkpIGxlYXZlcyBib3RoIGBudWxsYCBhbmQgc2V0c1xuICogYHNwYXduRXJyb3JgIHRvIHRoZSBmYWlsdXJlIG1lc3NhZ2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvY2Vzc0V4aXRJbmZvIHtcbiAgLyoqXG4gIEV4aXQgY29kZSwgb3IgYG51bGxgIHdoZW4gdGVybWluYXRlZCBieSBhIHNpZ25hbCBvciB3aGVuIGl0IGZhaWxlZCB0byBzcGF3bi5cbiAgICovXG4gIHJlYWRvbmx5IGNvZGU6IG51bGwgfCBudW1iZXI7XG5cbiAgLyoqXG4gIFRlcm1pbmF0aW5nIHNpZ25hbCwgb3IgYG51bGxgIHdoZW4gaXQgZXhpdGVkIG5vcm1hbGx5IG9yIGZhaWxlZCB0byBzcGF3bi5cbiAgICovXG4gIHJlYWRvbmx5IHNpZ25hbDogTm9kZUpTLlNpZ25hbHMgfCBudWxsO1xuXG4gIC8qKlxuICBUaGUgc3Bhd24tZmFpbHVyZSBtZXNzYWdlIHdoZW4gdGhlIHByb2Nlc3MgbmV2ZXIgc3RhcnRlZCAoZS5nLiBgRU5PRU5UYCksIG90aGVyd2lzZSBhYnNlbnQuXG4gICAqL1xuICByZWFkb25seSBzcGF3bkVycm9yPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEFwcGVuZHMgYSBwcm9jZXNzJ3MgY2FwdHVyZWQgb3V0cHV0IHRhaWwgdG8gYSBtZXNzYWdlLCB3aGVuIHRoZXJlIGlzIG9uZS5cbiAqXG4gKiBTcGxpdCBvdXQgb2Yge0BsaW5rIGJ1aWxkUHJvY2Vzc0V4aXRNZXNzYWdlfSBzbyB0aGUgKip0aW1lb3V0KiogZmFpbHVyZXMgY2FuXG4gKiBjYXJyeSB0aGUgdGFpbCB0b28uIEEgcHJvY2VzcyB0aGF0IGRpZXMgZ2V0cyBpdHMgb3V0cHV0IGF0dGFjaGVkOyBvbmUgdGhhdFxuICogaGFuZ3MgdXNlZCB0byBnZXQgYE5vIG5ldyBlbXVsYXRvciBkZXZpY2UgYXBwZWFyZWQgd2l0aGluIDMwMDAwMG1zLmAgYW5kXG4gKiBub3RoaW5nIGVsc2UgXHUyMDE0IGV2ZW4gdGhvdWdoIHRoZSBsaW5lIHRoYXQgZXhwbGFpbnMgaXQgKGBGQVRBTCB8IFJ1bm5pbmdcbiAqIG11bHRpcGxlIGVtdWxhdG9ycyB3aXRoIHRoZSBzYW1lIEFWRCBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZWApIGhhZCBhbHJlYWR5XG4gKiBiZWVuIGNhcHR1cmVkLiBUaGUgZW11bGF0b3Igd3JpdGluZyBpdHMgb3duIGRpYWdub3NpcyBpcyB3b3J0aCBub3RoaW5nIGlmIHRoZVxuICogaGFybmVzcyByZWFkcyBpdCBvbiBvbmx5IG9uZSBvZiB0aGUgdHdvIHdheXMgYSBzdGFydHVwIGNhbiBmYWlsLlxuICpcbiAqIEBwYXJhbSBtZXNzYWdlIC0gVGhlIGZhaWx1cmUgbWVzc2FnZSB0byBleHRlbmQuXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGNhcHR1cmVkIHRhaWwgYW5kIGl0cyBsYWJlbC5cbiAqIEByZXR1cm5zIFRoZSBtZXNzYWdlLCB3aXRoIHRoZSB0YWlsIGFwcGVuZGVkIHdoZW4gbm9uLWVtcHR5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwZW5kUHJvY2Vzc091dHB1dFRhaWwobWVzc2FnZTogc3RyaW5nLCBwYXJhbXM6IEFwcGVuZFByb2Nlc3NPdXRwdXRUYWlsUGFyYW1zKTogc3RyaW5nIHtcbiAgY29uc3QgdHJpbW1lZE91dHB1dCA9IHBhcmFtcy5vdXRwdXQudHJpbSgpO1xuICBpZiAodHJpbW1lZE91dHB1dC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbWVzc2FnZTtcbiAgfVxuXG4gIHJldHVybiBgJHttZXNzYWdlfVxcblxcbiR7cGFyYW1zLm91dHB1dExhYmVsfSAodGFpbCk6XFxuJHt0cmltbWVkT3V0cHV0fWA7XG59XG5cbi8qKlxuICogQnVpbGRzIGEgZGVzY3JpcHRpdmUgZXJyb3IgbWVzc2FnZSBmb3IgYW4gYXV0by1zdGFydGVkIGNoaWxkIHByb2Nlc3MgdGhhdFxuICogZXhpdGVkIChvciBmYWlsZWQgdG8gc3Bhd24pIGR1cmluZyBzdGFydHVwLCBhcHBlbmRpbmcgdGhlIGNhcHR1cmVkIG91dHB1dFxuICogdGFpbCB3aGVuIGF2YWlsYWJsZS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHN1YmplY3QsIGV4aXQgZGV0YWlscywgYW5kIGNhcHR1cmVkIG91dHB1dC5cbiAqIEByZXR1cm5zIEEgaHVtYW4tcmVhZGFibGUgZXJyb3IgbWVzc2FnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUHJvY2Vzc0V4aXRNZXNzYWdlKHBhcmFtczogQnVpbGRQcm9jZXNzRXhpdE1lc3NhZ2VQYXJhbXMpOiBzdHJpbmcge1xuICBjb25zdCB7IGV4aXRJbmZvLCBvdXRwdXQsIG91dHB1dExhYmVsLCBzdWJqZWN0IH0gPSBwYXJhbXM7XG5cbiAgcmV0dXJuIGFwcGVuZFByb2Nlc3NPdXRwdXRUYWlsKGAke3N1YmplY3R9ICR7cmVzb2x2ZVJlYXNvbihleGl0SW5mbyl9IGR1cmluZyBzdGFydHVwLmAsIHsgb3V0cHV0LCBvdXRwdXRMYWJlbCB9KTtcbn1cblxuLyoqXG4gKiBEZXNjcmliZXMgd2h5IHRoZSBwcm9jZXNzIGlzIG5vIGxvbmdlciBydW5uaW5nLlxuICpcbiAqIEBwYXJhbSBleGl0SW5mbyAtIFRoZSBleGl0IC8gc3Bhd24tZmFpbHVyZSBkZXRhaWxzLlxuICogQHJldHVybnMgVGhlIHJlYXNvbiBjbGF1c2UuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVSZWFzb24oZXhpdEluZm86IFByb2Nlc3NFeGl0SW5mbyk6IHN0cmluZyB7XG4gIGlmIChleGl0SW5mby5zcGF3bkVycm9yICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gYGZhaWxlZCB0byBzdGFydCAoJHtleGl0SW5mby5zcGF3bkVycm9yfSlgO1xuICB9XG4gIGlmIChleGl0SW5mby5zaWduYWwgIT09IG51bGwpIHtcbiAgICByZXR1cm4gYHdhcyB0ZXJtaW5hdGVkIGJ5IHNpZ25hbCAke2V4aXRJbmZvLnNpZ25hbH1gO1xuICB9XG4gIHJldHVybiBgZXhpdGVkIHByZW1hdHVyZWx5IHdpdGggY29kZSAke2V4aXRJbmZvLmNvZGUgPT09IG51bGwgPyAnKG51bGwpJyA6IFN0cmluZyhleGl0SW5mby5jb2RlKX1gO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBZ0dPLFNBQVMsd0JBQXdCLFNBQWlCLFFBQStDO0FBQ3RHLFFBQU0sZ0JBQWdCLE9BQU8sT0FBTyxLQUFLO0FBQ3pDLE1BQUksY0FBYyxXQUFXLEdBQUc7QUFDOUIsV0FBTztBQUFBLEVBQ1Q7QUFFQSxTQUFPLEdBQUcsT0FBTztBQUFBO0FBQUEsRUFBTyxPQUFPLFdBQVc7QUFBQSxFQUFhLGFBQWE7QUFDdEU7QUFVTyxTQUFTLHdCQUF3QixRQUErQztBQUNyRixRQUFNLEVBQUUsVUFBVSxRQUFRLGFBQWEsUUFBUSxJQUFJO0FBRW5ELFNBQU8sd0JBQXdCLEdBQUcsT0FBTyxJQUFJLGNBQWMsUUFBUSxDQUFDLG9CQUFvQixFQUFFLFFBQVEsWUFBWSxDQUFDO0FBQ2pIO0FBUUEsU0FBUyxjQUFjLFVBQW1DO0FBQ3hELE1BQUksU0FBUyxlQUFlLFFBQVc7QUFDckMsV0FBTyxvQkFBb0IsU0FBUyxVQUFVO0FBQUEsRUFDaEQ7QUFDQSxNQUFJLFNBQVMsV0FBVyxNQUFNO0FBQzVCLFdBQU8sNEJBQTRCLFNBQVMsTUFBTTtBQUFBLEVBQ3BEO0FBQ0EsU0FBTyxnQ0FBZ0MsU0FBUyxTQUFTLE9BQU8sV0FBVyxPQUFPLFNBQVMsSUFBSSxDQUFDO0FBQ2xHOyIsCiAgIm5hbWVzIjogW10KfQo=