obsidian-integration-testing 11.0.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/lib/cjs/appium-server-marker.cjs +115 -0
  2. package/dist/lib/cjs/appium-server-marker.d.cts +81 -0
  3. package/dist/lib/cjs/cli.cjs +104 -19
  4. package/dist/lib/cjs/cli.d.cts +16 -8
  5. package/dist/lib/cjs/community-plugin-registry.cjs +52 -0
  6. package/dist/lib/cjs/community-plugin-registry.d.cts +116 -0
  7. package/dist/lib/cjs/context-provider.cjs +12 -1
  8. package/dist/lib/cjs/context-provider.d.cts +26 -3
  9. package/dist/lib/cjs/demo-vault-bootstrap.cjs +148 -0
  10. package/dist/lib/cjs/demo-vault-bootstrap.d.cts +113 -0
  11. package/dist/lib/cjs/demo-vault-populate.cjs +36 -9
  12. package/dist/lib/cjs/demo-vault-populate.d.cts +70 -0
  13. package/dist/lib/cjs/eval-in-obsidian.cjs +1 -1
  14. package/dist/lib/cjs/eval-in-obsidian.d.cts +42 -13
  15. package/dist/lib/cjs/index.cjs +13 -1
  16. package/dist/lib/cjs/index.d.cts +8 -4
  17. package/dist/lib/cjs/installer-asset.cjs +1 -1
  18. package/dist/lib/cjs/installer-asset.d.cts +1 -1
  19. package/dist/lib/cjs/integration-setup-failed-error.cjs +62 -0
  20. package/dist/lib/cjs/integration-setup-failed-error.d.cts +66 -0
  21. package/dist/lib/cjs/jest/global-setup.cjs +2 -2
  22. package/dist/lib/cjs/jest/global-setup.d.cts +5 -1
  23. package/dist/lib/cjs/kill-process-tree.cjs +18 -7
  24. package/dist/lib/cjs/kill-process-tree.d.cts +10 -2
  25. package/dist/lib/cjs/library.cjs +1 -1
  26. package/dist/lib/cjs/mobile-input.cjs +161 -0
  27. package/dist/lib/cjs/mobile-input.d.cts +160 -0
  28. package/dist/lib/cjs/namespace-bootstrap.cjs +92 -9
  29. package/dist/lib/cjs/obsidian-installer.cjs +1 -1
  30. package/dist/lib/cjs/obsidian-metadata.cjs +123 -17
  31. package/dist/lib/cjs/obsidian-metadata.d.cts +17 -6
  32. package/dist/lib/cjs/obsidian-version-switch.cjs +3 -3
  33. package/dist/lib/cjs/release-catalog.cjs +73 -0
  34. package/dist/lib/cjs/release-catalog.d.cts +125 -0
  35. package/dist/lib/cjs/transport-appium.cjs +122 -1
  36. package/dist/lib/cjs/transport-appium.d.cts +51 -0
  37. package/dist/lib/cjs/transport-desktop-cdp.cjs +7 -1
  38. package/dist/lib/cjs/transport-desktop-cdp.d.cts +1 -0
  39. package/dist/lib/cjs/transport-factory.cjs +237 -32
  40. package/dist/lib/cjs/transport-factory.d.cts +10 -1
  41. package/dist/lib/cjs/vitest/global-setup.cjs +13 -7
  42. package/dist/lib/cjs/vitest/global-setup.d.cts +5 -1
  43. package/dist/lib/cjs/vitest/setup.cjs +2 -1
  44. package/dist/lib/cjs/vitest/setup.d.cts +5 -0
  45. package/dist/lib/cjs/vitest/typings.d.cts +6 -4
  46. package/dist/lib/cjs/webview-cdp.cjs +264 -0
  47. package/dist/lib/cjs/webview-cdp.d.cts +152 -0
  48. package/dist/lib/cjs/wedged-appium-server.cjs +113 -0
  49. package/dist/lib/cjs/wedged-appium-server.d.cts +187 -0
  50. package/dist/lib/esm/appium-server-marker.d.mts +81 -0
  51. package/dist/lib/esm/appium-server-marker.mjs +83 -0
  52. package/dist/lib/esm/cli.d.mts +16 -8
  53. package/dist/lib/esm/cli.mjs +110 -19
  54. package/dist/lib/esm/community-plugin-registry.d.mts +116 -0
  55. package/dist/lib/esm/community-plugin-registry.mjs +23 -0
  56. package/dist/lib/esm/context-provider.d.mts +26 -3
  57. package/dist/lib/esm/context-provider.mjs +10 -1
  58. package/dist/lib/esm/demo-vault-bootstrap.d.mts +113 -0
  59. package/dist/lib/esm/demo-vault-bootstrap.mjs +127 -0
  60. package/dist/lib/esm/demo-vault-populate.d.mts +70 -0
  61. package/dist/lib/esm/demo-vault-populate.mjs +33 -8
  62. package/dist/lib/esm/eval-in-obsidian.d.mts +42 -13
  63. package/dist/lib/esm/eval-in-obsidian.mjs +1 -1
  64. package/dist/lib/esm/index.d.mts +8 -4
  65. package/dist/lib/esm/index.mjs +16 -2
  66. package/dist/lib/esm/installer-asset.d.mts +1 -1
  67. package/dist/lib/esm/installer-asset.mjs +1 -1
  68. package/dist/lib/esm/integration-setup-failed-error.d.mts +66 -0
  69. package/dist/lib/esm/integration-setup-failed-error.mjs +38 -0
  70. package/dist/lib/esm/jest/global-setup.d.mts +5 -1
  71. package/dist/lib/esm/jest/global-setup.mjs +2 -2
  72. package/dist/lib/esm/kill-process-tree.d.mts +10 -2
  73. package/dist/lib/esm/kill-process-tree.mjs +16 -6
  74. package/dist/lib/esm/library.mjs +1 -1
  75. package/dist/lib/esm/mobile-input.d.mts +160 -0
  76. package/dist/lib/esm/mobile-input.mjs +132 -0
  77. package/dist/lib/esm/namespace-bootstrap.mjs +95 -9
  78. package/dist/lib/esm/obsidian-installer.mjs +1 -1
  79. package/dist/lib/esm/obsidian-metadata.d.mts +17 -6
  80. package/dist/lib/esm/obsidian-metadata.mjs +123 -17
  81. package/dist/lib/esm/obsidian-version-switch.mjs +3 -3
  82. package/dist/lib/esm/release-catalog.d.mts +125 -0
  83. package/dist/lib/esm/release-catalog.mjs +46 -0
  84. package/dist/lib/esm/transport-appium.d.mts +51 -0
  85. package/dist/lib/esm/transport-appium.mjs +126 -1
  86. package/dist/lib/esm/transport-desktop-cdp.d.mts +1 -0
  87. package/dist/lib/esm/transport-desktop-cdp.mjs +7 -1
  88. package/dist/lib/esm/transport-factory.d.mts +10 -1
  89. package/dist/lib/esm/transport-factory.mjs +249 -35
  90. package/dist/lib/esm/vitest/global-setup.d.mts +5 -1
  91. package/dist/lib/esm/vitest/global-setup.mjs +14 -7
  92. package/dist/lib/esm/vitest/setup.d.mts +5 -0
  93. package/dist/lib/esm/vitest/setup.mjs +3 -1
  94. package/dist/lib/esm/vitest/typings.d.mts +6 -4
  95. package/dist/lib/esm/webview-cdp.d.mts +152 -0
  96. package/dist/lib/esm/webview-cdp.mjs +236 -0
  97. package/dist/lib/esm/wedged-appium-server.d.mts +187 -0
  98. package/dist/lib/esm/wedged-appium-server.mjs +86 -0
  99. package/package.json +2 -1
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var appium_server_marker_exports = {};
30
+ __export(appium_server_marker_exports, {
31
+ checkIsHarnessOwnedAppiumServer: () => checkIsHarnessOwnedAppiumServer,
32
+ clearAppiumServerMarker: () => clearAppiumServerMarker,
33
+ readAppiumServerMarker: () => readAppiumServerMarker,
34
+ writeAppiumServerMarker: () => writeAppiumServerMarker
35
+ });
36
+ module.exports = __toCommonJS(appium_server_marker_exports);
37
+ var import_node_fs = require("node:fs");
38
+ var import_node_os = require("node:os");
39
+ var import_node_path = require("node:path");
40
+ var import_node_process = __toESM(require("node:process"), 1);
41
+ var import_log = require("./log.cjs");
42
+ const MARKER_DIR_NAME = "obsidian-integration-testing";
43
+ const MARKER_FILE_SUFFIX = ".appium-server.json";
44
+ const PROCESS_EXISTENCE_PROBE_SIGNAL = 0;
45
+ function checkIsHarnessOwnedAppiumServer(marker) {
46
+ if (!marker) {
47
+ return false;
48
+ }
49
+ try {
50
+ import_node_process.default.kill(marker.pid, PROCESS_EXISTENCE_PROBE_SIGNAL);
51
+ return true;
52
+ } catch (error) {
53
+ return getErrorCode(error) === "EPERM";
54
+ }
55
+ }
56
+ function clearAppiumServerMarker(port) {
57
+ try {
58
+ (0, import_node_fs.rmSync)(getMarkerFilePath(port), { force: true });
59
+ } catch (error) {
60
+ (0, import_log.log)(`[appium-server-marker] Could not remove the marker for port ${String(port)}: ${getErrorMessage(error)}`);
61
+ }
62
+ }
63
+ function readAppiumServerMarker(port) {
64
+ let parsed;
65
+ try {
66
+ parsed = JSON.parse((0, import_node_fs.readFileSync)(getMarkerFilePath(port), "utf-8"));
67
+ } catch {
68
+ return void 0;
69
+ }
70
+ return parseMarker(parsed, port);
71
+ }
72
+ function writeAppiumServerMarker(params) {
73
+ const marker = {
74
+ pid: params.pid,
75
+ port: params.port,
76
+ startedAtInMilliseconds: Date.now()
77
+ };
78
+ try {
79
+ (0, import_node_fs.mkdirSync)(getMarkerDirectory(), { recursive: true });
80
+ (0, import_node_fs.writeFileSync)(getMarkerFilePath(params.port), JSON.stringify(marker));
81
+ } catch (error) {
82
+ (0, import_log.log)(`[appium-server-marker] Could not record the server on port ${String(params.port)}: ${getErrorMessage(error)}`);
83
+ }
84
+ }
85
+ function getErrorCode(error) {
86
+ return typeof error === "object" && error !== null && "code" in error ? String(error.code) : void 0;
87
+ }
88
+ function getErrorMessage(error) {
89
+ return error instanceof Error ? error.message : String(error);
90
+ }
91
+ function getMarkerDirectory() {
92
+ return (0, import_node_path.join)((0, import_node_os.tmpdir)(), MARKER_DIR_NAME);
93
+ }
94
+ function getMarkerFilePath(port) {
95
+ return (0, import_node_path.join)(getMarkerDirectory(), `${String(port)}${MARKER_FILE_SUFFIX}`);
96
+ }
97
+ function parseMarker(parsed, port) {
98
+ if (typeof parsed !== "object" || parsed === null) {
99
+ return void 0;
100
+ }
101
+ const record = parsed;
102
+ const { pid, port: markedPort, startedAtInMilliseconds } = record;
103
+ if (typeof pid !== "number" || typeof startedAtInMilliseconds !== "number" || markedPort !== port) {
104
+ return void 0;
105
+ }
106
+ return { pid, port, startedAtInMilliseconds };
107
+ }
108
+ // Annotate the CommonJS export names for ESM import in node:
109
+ 0 && (module.exports = {
110
+ checkIsHarnessOwnedAppiumServer,
111
+ clearAppiumServerMarker,
112
+ readAppiumServerMarker,
113
+ writeAppiumServerMarker
114
+ });
115
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2FwcGl1bS1zZXJ2ZXItbWFya2VyLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogUmVjb3JkcyB3aGljaCBBcHBpdW0gc2VydmVyIG9uIGEgcG9ydCB0aGlzIGhhcm5lc3Mgc3RhcnRlZCwgc28gYSBsYXRlciBydW5cbiAqIHRoYXQgZmluZHMgYSBzZXJ2ZXIgYWxyZWFkeSBsaXN0ZW5pbmcgY2FuIHRlbGwgKipwcm92ZW5hbmNlKio6IG9uZSBvZiBvdXIgb3duXG4gKiBzZXJ2ZXJzIGxlZnQgb3ZlciBmcm9tIGFuIGVhcmxpZXIgcnVuLCBvciBhIGZvcmVpZ24gb25lIHRoZSB1c2VyIG1hbmFnZXMuXG4gKlxuICogVGhlIHByZWZsaWdodCBhZG9wdHMgYW55IHNlcnZlciB0aGF0IGFuc3dlcnMgYC9zdGF0dXNgLCBhbmQgYWRvcHRpb24gaXMgdGhlXG4gKiByaWdodCBkZWZhdWx0IFx1MjAxNCBzdGFydGluZyBhIHNlY29uZCBzZXJ2ZXIgb24gYW4gb2NjdXBpZWQgcG9ydCBjYW5ub3Qgd29yay4gQnV0XG4gKiBhZG9wdGluZyBzaWxlbnRseSBtZWFucyBhIHdlZGdlZCBsZWZ0b3ZlciAoc2VlIGB3ZWRnZWQtYXBwaXVtLXNlcnZlci50c2ApIGlzXG4gKiBpbmRpc3Rpbmd1aXNoYWJsZSBmcm9tIGEgaGVhbHRoeSBzZXJ2ZXIsIGFuZCB0aGUgaGFybmVzcyBoYXMgbm8gYmFzaXMgb24gd2hpY2hcbiAqIHRvIGRlY2lkZSB3aGV0aGVyIHJlc3RhcnRpbmcgaXQgaXMgaXRzIGNhbGwgdG8gbWFrZS4gVGhlIG1hcmtlciBzdXBwbGllcyB0aGF0XG4gKiBiYXNpczogYSBzZXJ2ZXIgd2Ugc3RhcnRlZCBtYXkgYmUgcmVzdGFydGVkLCBhIGZvcmVpZ24gb25lIGlzIG9ubHkgZXZlclxuICogcmVwb3J0ZWQuXG4gKlxuICogVGhlIG1hcmtlciBpcyBhIHNtYWxsIEpTT04gc2VudGluZWwgbmV4dCB0byB0aGUgc2V0dXAgbG9jayAoYHNldHVwLWxvY2sudHNgKSxcbiAqIGtleWVkIGJ5IHBvcnQsIGFuZCBpcyBkZWxpYmVyYXRlbHkgdG9sZXJhbnQgXHUyMDE0IGEgbWlzc2luZywgdW5yZWFkYWJsZSwgb3JcbiAqIG1pc21hdGNoZWQgbWFya2VyIHNpbXBseSByZWFkcyBhcyBcIm5vdCBvdXJzXCIuXG4gKi9cblxuaW1wb3J0IHtcbiAgbWtkaXJTeW5jLFxuICByZWFkRmlsZVN5bmMsXG4gIHJtU3luYyxcbiAgd3JpdGVGaWxlU3luY1xufSBmcm9tICdub2RlOmZzJztcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQgeyBsb2cgfSBmcm9tICcuL2xvZy5janMnO1xuXG5jb25zdCBNQVJLRVJfRElSX05BTUUgPSAnb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZyc7XG5jb25zdCBNQVJLRVJfRklMRV9TVUZGSVggPSAnLmFwcGl1bS1zZXJ2ZXIuanNvbic7XG5jb25zdCBQUk9DRVNTX0VYSVNURU5DRV9QUk9CRV9TSUdOQUwgPSAwO1xuXG4vKipcbiAqIElkZW50aWZpZXMgdGhlIEFwcGl1bSBzZXJ2ZXIgdGhpcyBoYXJuZXNzIHN0YXJ0ZWQgb24gYSBwb3J0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwcGl1bVNlcnZlck1hcmtlciB7XG4gIC8qKlxuICBQSUQgb2YgdGhlIHNwYXduZWQgc2VydmVyIHByb2Nlc3MgKHRoZSBzaGVsbCB3cmFwcGVyIHRoYXQgb3ducyB0aGUgc2VydmVyJ3MgcHJvY2VzcyB0cmVlKS5cbiAgICovXG4gIHJlYWRvbmx5IHBpZDogbnVtYmVyO1xuXG4gIC8qKlxuICBUaGUgcG9ydCB0aGUgc2VydmVyIHdhcyBzdGFydGVkIG9uLlxuICAgKi9cbiAgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xuXG4gIC8qKlxuICBXaGVuIHRoZSBzZXJ2ZXIgd2FzIHN0YXJ0ZWQgKGBEYXRlLm5vdygpYCBlcG9jaCBtaWxsaXNlY29uZHMpLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHM6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgd3JpdGVBcHBpdW1TZXJ2ZXJNYXJrZXJ9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFdyaXRlQXBwaXVtU2VydmVyTWFya2VyUGFyYW1zIHtcbiAgLyoqXG4gIFBJRCBvZiB0aGUgc3Bhd25lZCBzZXJ2ZXIgcHJvY2Vzcy5cbiAgICovXG4gIHJlYWRvbmx5IHBpZDogbnVtYmVyO1xuXG4gIC8qKlxuICBUaGUgcG9ydCB0aGUgc2VydmVyIHdhcyBzdGFydGVkIG9uLlxuICAgKi9cbiAgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBtYXJrZWQgc2VydmVyIGlzIHN0aWxsIHJ1bm5pbmcsIHdoaWNoIGlzIHdoYXQgbWFrZXMgYW5cbiAqIGFkb3B0ZWQgc2VydmVyIG91cnMgdG8gcmVzdGFydC5cbiAqXG4gKiBBIGRlYWQgUElEIG1lYW5zIHRoZSBtYXJrZXIgb3V0bGl2ZWQgaXRzIHNlcnZlciwgc28gd2hhdGV2ZXIgYW5zd2VycyBvbiB0aGF0XG4gKiBwb3J0IG5vdyBpcyBzb21lYm9keSBlbHNlJ3MgXHUyMDE0IHRoZSBtYXJrZXIgcHJvdmVzIG5vdGhpbmcgYWJvdXQgaXQuXG4gKlxuICogQHBhcmFtIG1hcmtlciAtIFRoZSBtYXJrZXIgcmVhZCBmb3IgdGhlIHBvcnQsIG9yIGB1bmRlZmluZWRgIHdoZW4gdGhlcmUgaXMgbm9uZS5cbiAqIEByZXR1cm5zIGB0cnVlYCB3aGVuIGFuIGVhcmxpZXIgcnVuIG9mIHRoaXMgaGFybmVzcyBzdGFydGVkIHRoZSBzZXJ2ZXIgbm93IGxpc3RlbmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrSXNIYXJuZXNzT3duZWRBcHBpdW1TZXJ2ZXIobWFya2VyOiBBcHBpdW1TZXJ2ZXJNYXJrZXIgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgaWYgKCFtYXJrZXIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB0cnkge1xuICAgIHByb2Nlc3Mua2lsbChtYXJrZXIucGlkLCBQUk9DRVNTX0VYSVNURU5DRV9QUk9CRV9TSUdOQUwpO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIC8vIGBFUEVSTWAgbWVhbnMgdGhlIHByb2Nlc3MgZXhpc3RzIGJ1dCBpcyBvd25lZCBieSBhbm90aGVyIHVzZXIgXHUyMDE0IHN0aWxsIGFsaXZlLlxuICAgIHJldHVybiBnZXRFcnJvckNvZGUoZXJyb3IpID09PSAnRVBFUk0nO1xuICB9XG59XG5cbi8qKlxuICogUmVtb3ZlcyB0aGUgbWFya2VyIGZvciBhIHBvcnQuIENhbGxlZCBvbmNlIHRoZSBtYXJrZWQgc2VydmVyIGhhcyBiZWVuIHN0b3BwZWQsXG4gKiBzbyBhIGxhdGVyIHJ1biBkb2VzIG5vdCBtaXN0YWtlIGEgcmVjeWNsZWQgUElEIGZvciBvdXIgc2VydmVyLlxuICpcbiAqIEBwYXJhbSBwb3J0IC0gVGhlIEFwcGl1bSBzZXJ2ZXIgcG9ydC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyQXBwaXVtU2VydmVyTWFya2VyKHBvcnQ6IG51bWJlcik6IHZvaWQge1xuICB0cnkge1xuICAgIHJtU3luYyhnZXRNYXJrZXJGaWxlUGF0aChwb3J0KSwgeyBmb3JjZTogdHJ1ZSB9KTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBsb2coYFthcHBpdW0tc2VydmVyLW1hcmtlcl0gQ291bGQgbm90IHJlbW92ZSB0aGUgbWFya2VyIGZvciBwb3J0ICR7U3RyaW5nKHBvcnQpfTogJHtnZXRFcnJvck1lc3NhZ2UoZXJyb3IpfWApO1xuICB9XG59XG5cbi8qKlxuICogUmVhZHMgdGhlIG1hcmtlciBmb3IgYSBwb3J0LlxuICpcbiAqIEBwYXJhbSBwb3J0IC0gVGhlIEFwcGl1bSBzZXJ2ZXIgcG9ydC5cbiAqIEByZXR1cm5zIFRoZSBtYXJrZXIsIG9yIGB1bmRlZmluZWRgIHdoZW4gdGhlcmUgaXMgbm9uZSwgaXQgaXMgdW5yZWFkYWJsZSwgb3IgaXQgZG9lcyBub3QgZGVzY3JpYmUgdGhpcyBwb3J0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZEFwcGl1bVNlcnZlck1hcmtlcihwb3J0OiBudW1iZXIpOiBBcHBpdW1TZXJ2ZXJNYXJrZXIgfCB1bmRlZmluZWQge1xuICBsZXQgcGFyc2VkOiB1bmtub3duO1xuICB0cnkge1xuICAgIHBhcnNlZCA9IEpTT04ucGFyc2UocmVhZEZpbGVTeW5jKGdldE1hcmtlckZpbGVQYXRoKHBvcnQpLCAndXRmLTgnKSk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICByZXR1cm4gcGFyc2VNYXJrZXIocGFyc2VkLCBwb3J0KTtcbn1cblxuLyoqXG4gKiBSZWNvcmRzIHRoZSBzZXJ2ZXIgdGhpcyBydW4ganVzdCBzdGFydGVkLCBzdGFtcGluZyBpdCB3aXRoIHRoZSBjdXJyZW50IHRpbWUgc29cbiAqIGEgbGF0ZXIgcnVuIGNhbiByZXBvcnQgaG93IGxvbmcgaXQgaGFzIGJlZW4gdXAuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBzdGFydGVkIHNlcnZlcidzIFBJRCBhbmQgcG9ydC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyaXRlQXBwaXVtU2VydmVyTWFya2VyKHBhcmFtczogV3JpdGVBcHBpdW1TZXJ2ZXJNYXJrZXJQYXJhbXMpOiB2b2lkIHtcbiAgY29uc3QgbWFya2VyOiBBcHBpdW1TZXJ2ZXJNYXJrZXIgPSB7XG4gICAgcGlkOiBwYXJhbXMucGlkLFxuICAgIHBvcnQ6IHBhcmFtcy5wb3J0LFxuICAgIHN0YXJ0ZWRBdEluTWlsbGlzZWNvbmRzOiBEYXRlLm5vdygpXG4gIH07XG5cbiAgdHJ5IHtcbiAgICBta2RpclN5bmMoZ2V0TWFya2VyRGlyZWN0b3J5KCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIHdyaXRlRmlsZVN5bmMoZ2V0TWFya2VyRmlsZVBhdGgocGFyYW1zLnBvcnQpLCBKU09OLnN0cmluZ2lmeShtYXJrZXIpKTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBsb2coYFthcHBpdW0tc2VydmVyLW1hcmtlcl0gQ291bGQgbm90IHJlY29yZCB0aGUgc2VydmVyIG9uIHBvcnQgJHtTdHJpbmcocGFyYW1zLnBvcnQpfTogJHtnZXRFcnJvck1lc3NhZ2UoZXJyb3IpfWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldEVycm9yQ29kZShlcnJvcjogdW5rbm93bik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiB0eXBlb2YgZXJyb3IgPT09ICdvYmplY3QnICYmIGVycm9yICE9PSBudWxsICYmICdjb2RlJyBpbiBlcnJvciA/IFN0cmluZyhlcnJvci5jb2RlKSA6IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gZ2V0RXJyb3JNZXNzYWdlKGVycm9yOiB1bmtub3duKTogc3RyaW5nIHtcbiAgcmV0dXJuIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcbn1cblxuZnVuY3Rpb24gZ2V0TWFya2VyRGlyZWN0b3J5KCk6IHN0cmluZyB7XG4gIHJldHVybiBqb2luKHRtcGRpcigpLCBNQVJLRVJfRElSX05BTUUpO1xufVxuXG5mdW5jdGlvbiBnZXRNYXJrZXJGaWxlUGF0aChwb3J0OiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihnZXRNYXJrZXJEaXJlY3RvcnkoKSwgYCR7U3RyaW5nKHBvcnQpfSR7TUFSS0VSX0ZJTEVfU1VGRklYfWApO1xufVxuXG5mdW5jdGlvbiBwYXJzZU1hcmtlcihwYXJzZWQ6IHVua25vd24sIHBvcnQ6IG51bWJlcik6IEFwcGl1bVNlcnZlck1hcmtlciB8IHVuZGVmaW5lZCB7XG4gIGlmICh0eXBlb2YgcGFyc2VkICE9PSAnb2JqZWN0JyB8fCBwYXJzZWQgPT09IG51bGwpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgcmVjb3JkID0gcGFyc2VkIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBjb25zdCB7IHBpZCwgcG9ydDogbWFya2VkUG9ydCwgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMgfSA9IHJlY29yZDtcblxuICBpZiAodHlwZW9mIHBpZCAhPT0gJ251bWJlcicgfHwgdHlwZW9mIHN0YXJ0ZWRBdEluTWlsbGlzZWNvbmRzICE9PSAnbnVtYmVyJyB8fCBtYXJrZWRQb3J0ICE9PSBwb3J0KSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiB7IHBpZCwgcG9ydCwgc3RhcnRlZEF0SW5NaWxsaXNlY29uZHMgfTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBb0JBLHFCQUtPO0FBQ1AscUJBQXVCO0FBQ3ZCLHVCQUFxQjtBQUNyQiwwQkFBb0I7QUFFcEIsaUJBQW9CO0FBRXBCLE1BQU0sa0JBQWtCO0FBQ3hCLE1BQU0scUJBQXFCO0FBQzNCLE1BQU0saUNBQWlDO0FBK0NoQyxTQUFTLGdDQUFnQyxRQUFpRDtBQUMvRixNQUFJLENBQUMsUUFBUTtBQUNYLFdBQU87QUFBQSxFQUNUO0FBRUEsTUFBSTtBQUNGLHdCQUFBQSxRQUFRLEtBQUssT0FBTyxLQUFLLDhCQUE4QjtBQUN2RCxXQUFPO0FBQUEsRUFDVCxTQUFTLE9BQWdCO0FBRXZCLFdBQU8sYUFBYSxLQUFLLE1BQU07QUFBQSxFQUNqQztBQUNGO0FBUU8sU0FBUyx3QkFBd0IsTUFBb0I7QUFDMUQsTUFBSTtBQUNGLCtCQUFPLGtCQUFrQixJQUFJLEdBQUcsRUFBRSxPQUFPLEtBQUssQ0FBQztBQUFBLEVBQ2pELFNBQVMsT0FBZ0I7QUFDdkIsd0JBQUksK0RBQStELE9BQU8sSUFBSSxDQUFDLEtBQUssZ0JBQWdCLEtBQUssQ0FBQyxFQUFFO0FBQUEsRUFDOUc7QUFDRjtBQVFPLFNBQVMsdUJBQXVCLE1BQThDO0FBQ25GLE1BQUk7QUFDSixNQUFJO0FBQ0YsYUFBUyxLQUFLLFVBQU0sNkJBQWEsa0JBQWtCLElBQUksR0FBRyxPQUFPLENBQUM7QUFBQSxFQUNwRSxRQUFRO0FBQ04sV0FBTztBQUFBLEVBQ1Q7QUFFQSxTQUFPLFlBQVksUUFBUSxJQUFJO0FBQ2pDO0FBUU8sU0FBUyx3QkFBd0IsUUFBNkM7QUFDbkYsUUFBTSxTQUE2QjtBQUFBLElBQ2pDLEtBQUssT0FBTztBQUFBLElBQ1osTUFBTSxPQUFPO0FBQUEsSUFDYix5QkFBeUIsS0FBSyxJQUFJO0FBQUEsRUFDcEM7QUFFQSxNQUFJO0FBQ0Ysa0NBQVUsbUJBQW1CLEdBQUcsRUFBRSxXQUFXLEtBQUssQ0FBQztBQUNuRCxzQ0FBYyxrQkFBa0IsT0FBTyxJQUFJLEdBQUcsS0FBSyxVQUFVLE1BQU0sQ0FBQztBQUFBLEVBQ3RFLFNBQVMsT0FBZ0I7QUFDdkIsd0JBQUksOERBQThELE9BQU8sT0FBTyxJQUFJLENBQUMsS0FBSyxnQkFBZ0IsS0FBSyxDQUFDLEVBQUU7QUFBQSxFQUNwSDtBQUNGO0FBRUEsU0FBUyxhQUFhLE9BQW9DO0FBQ3hELFNBQU8sT0FBTyxVQUFVLFlBQVksVUFBVSxRQUFRLFVBQVUsUUFBUSxPQUFPLE1BQU0sSUFBSSxJQUFJO0FBQy9GO0FBRUEsU0FBUyxnQkFBZ0IsT0FBd0I7QUFDL0MsU0FBTyxpQkFBaUIsUUFBUSxNQUFNLFVBQVUsT0FBTyxLQUFLO0FBQzlEO0FBRUEsU0FBUyxxQkFBNkI7QUFDcEMsYUFBTywyQkFBSyx1QkFBTyxHQUFHLGVBQWU7QUFDdkM7QUFFQSxTQUFTLGtCQUFrQixNQUFzQjtBQUMvQyxhQUFPLHVCQUFLLG1CQUFtQixHQUFHLEdBQUcsT0FBTyxJQUFJLENBQUMsR0FBRyxrQkFBa0IsRUFBRTtBQUMxRTtBQUVBLFNBQVMsWUFBWSxRQUFpQixNQUE4QztBQUNsRixNQUFJLE9BQU8sV0FBVyxZQUFZLFdBQVcsTUFBTTtBQUNqRCxXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sU0FBUztBQUNmLFFBQU0sRUFBRSxLQUFLLE1BQU0sWUFBWSx3QkFBd0IsSUFBSTtBQUUzRCxNQUFJLE9BQU8sUUFBUSxZQUFZLE9BQU8sNEJBQTRCLFlBQVksZUFBZSxNQUFNO0FBQ2pHLFdBQU87QUFBQSxFQUNUO0FBRUEsU0FBTyxFQUFFLEtBQUssTUFBTSx3QkFBd0I7QUFDOUM7IiwKICAibmFtZXMiOiBbInByb2Nlc3MiXQp9Cg==
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Records which Appium server on a port this harness started, so a later run
5
+ * that finds a server already listening can tell **provenance**: one of our own
6
+ * servers left over from an earlier run, or a foreign one the user manages.
7
+ *
8
+ * The preflight adopts any server that answers `/status`, and adoption is the
9
+ * right default — starting a second server on an occupied port cannot work. But
10
+ * adopting silently means a wedged leftover (see `wedged-appium-server.ts`) is
11
+ * indistinguishable from a healthy server, and the harness has no basis on which
12
+ * to decide whether restarting it is its call to make. The marker supplies that
13
+ * basis: a server we started may be restarted, a foreign one is only ever
14
+ * reported.
15
+ *
16
+ * The marker is a small JSON sentinel next to the setup lock (`setup-lock.ts`),
17
+ * keyed by port, and is deliberately tolerant — a missing, unreadable, or
18
+ * mismatched marker simply reads as "not ours".
19
+ */
20
+ /**
21
+ * Identifies the Appium server this harness started on a port.
22
+ */
23
+ export interface AppiumServerMarker {
24
+ /**
25
+ PID of the spawned server process (the shell wrapper that owns the server's process tree).
26
+ */
27
+ readonly pid: number;
28
+ /**
29
+ The port the server was started on.
30
+ */
31
+ readonly port: number;
32
+ /**
33
+ When the server was started (`Date.now()` epoch milliseconds).
34
+ */
35
+ readonly startedAtInMilliseconds: number;
36
+ }
37
+ /**
38
+ * Parameters for {@link writeAppiumServerMarker}.
39
+ */
40
+ export interface WriteAppiumServerMarkerParams {
41
+ /**
42
+ PID of the spawned server process.
43
+ */
44
+ readonly pid: number;
45
+ /**
46
+ The port the server was started on.
47
+ */
48
+ readonly port: number;
49
+ }
50
+ /**
51
+ * Checks whether the marked server is still running, which is what makes an
52
+ * adopted server ours to restart.
53
+ *
54
+ * A dead PID means the marker outlived its server, so whatever answers on that
55
+ * port now is somebody else's — the marker proves nothing about it.
56
+ *
57
+ * @param marker - The marker read for the port, or `undefined` when there is none.
58
+ * @returns `true` when an earlier run of this harness started the server now listening.
59
+ */
60
+ export declare function checkIsHarnessOwnedAppiumServer(marker: AppiumServerMarker | undefined): boolean;
61
+ /**
62
+ * Removes the marker for a port. Called once the marked server has been stopped,
63
+ * so a later run does not mistake a recycled PID for our server.
64
+ *
65
+ * @param port - The Appium server port.
66
+ */
67
+ export declare function clearAppiumServerMarker(port: number): void;
68
+ /**
69
+ * Reads the marker for a port.
70
+ *
71
+ * @param port - The Appium server port.
72
+ * @returns The marker, or `undefined` when there is none, it is unreadable, or it does not describe this port.
73
+ */
74
+ export declare function readAppiumServerMarker(port: number): AppiumServerMarker | undefined;
75
+ /**
76
+ * Records the server this run just started, stamping it with the current time so
77
+ * a later run can report how long it has been up.
78
+ *
79
+ * @param params - The started server's PID and port.
80
+ */
81
+ export declare function writeAppiumServerMarker(params: WriteAppiumServerMarkerParams): void;
@@ -31,10 +31,113 @@ __export(cli_exports, {
31
31
  main: () => main
32
32
  });
33
33
  module.exports = __toCommonJS(cli_exports);
34
+ var import_node_fs = require("node:fs");
35
+ var import_node_path = require("node:path");
34
36
  var import_node_process = __toESM(require("node:process"), 1);
35
37
  var import_node_util = require("node:util");
36
38
  var import_connect_to_cdp = require("./connect-to-cdp.cjs");
39
+ var import_demo_vault_bootstrap = require("./demo-vault-bootstrap.cjs");
40
+ const BOOTSTRAP_DEMO_VAULT_COMMAND = "bootstrap-demo-vault";
41
+ const HELP_FLAGS = /* @__PURE__ */ new Set(["--help", "-h"]);
42
+ const SUBCOMMAND_ARGUMENTS_START_INDEX = 3;
43
+ const USAGE = `Usage:
44
+ obsidian-integration-testing [options]
45
+ Launch (or attach to) a CDP-enabled Obsidian instance and print its endpoint.
46
+ Options: --vault, --port, --host, --obsidian-version, --obsidian-installer-version,
47
+ --command-timeout, --no-remove-vault
48
+
49
+ obsidian-integration-testing ${BOOTSTRAP_DEMO_VAULT_COMMAND} [options]
50
+ Install a demo vault's injected community plugins from their published GitHub
51
+ releases, so integration tests run without opening Obsidian by hand.
52
+ Options: --demo-vault <path> demo vault directory (default: ./demo-vault)
53
+ --plugin <id> plugin id to install (repeatable; default: every
54
+ id already present under .obsidian/plugins/)
55
+ --repo <owner/name> override the registry lookup (single --plugin only)
56
+ --version <tag> pin a release tag (single --plugin only)
57
+ --force re-download plugins that are already installed
58
+ `;
37
59
  async function main() {
60
+ const [, , firstArgument] = import_node_process.default.argv;
61
+ if (firstArgument !== void 0 && HELP_FLAGS.has(firstArgument)) {
62
+ import_node_process.default.stdout.write(USAGE);
63
+ return;
64
+ }
65
+ if (firstArgument === BOOTSTRAP_DEMO_VAULT_COMMAND) {
66
+ await runBootstrapDemoVaultCommand(import_node_process.default.argv.slice(SUBCOMMAND_ARGUMENTS_START_INDEX));
67
+ return;
68
+ }
69
+ await runConnectCommand();
70
+ }
71
+ function buildOptions(values) {
72
+ return {
73
+ ...values["command-timeout"] !== void 0 && { commandTimeoutInMilliseconds: parseNumber("command-timeout", values["command-timeout"]) },
74
+ ...values.host !== void 0 && { host: values.host },
75
+ ...values["no-remove-vault"] === true && { shouldRemoveVaultOnDispose: false },
76
+ ...values["obsidian-installer-version"] !== void 0 && { obsidianInstallerVersion: values["obsidian-installer-version"] },
77
+ ...values["obsidian-version"] !== void 0 && { obsidianVersion: values["obsidian-version"] },
78
+ ...values.port !== void 0 && { port: parseNumber("port", values.port) },
79
+ ...values.vault !== void 0 && { vault: values.vault }
80
+ };
81
+ }
82
+ function discoverDemoVaultPluginIds(demoVaultPath) {
83
+ const pluginsDirectory = (0, import_node_path.join)(demoVaultPath, ".obsidian", "plugins");
84
+ if (!(0, import_node_fs.existsSync)(pluginsDirectory)) {
85
+ return [];
86
+ }
87
+ return (0, import_node_fs.readdirSync)(pluginsDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
88
+ }
89
+ function parseNumber(flag, raw) {
90
+ const value = Number(raw);
91
+ if (!Number.isFinite(value)) {
92
+ throw new TypeError(`--${flag} must be a number, got: ${raw}`);
93
+ }
94
+ return value;
95
+ }
96
+ async function runBootstrapDemoVaultCommand(commandArguments) {
97
+ const { values } = (0, import_node_util.parseArgs)({
98
+ // eslint-disable-next-line unicorn/name-replacements -- `args` is Node's own `parseArgs` option name.
99
+ args: commandArguments,
100
+ options: {
101
+ "demo-vault": { type: "string" },
102
+ "force": { type: "boolean" },
103
+ "plugin": { multiple: true, type: "string" },
104
+ "repo": { type: "string" },
105
+ "version": { type: "string" }
106
+ }
107
+ });
108
+ const demoVaultPath = (0, import_node_path.resolve)(values["demo-vault"] ?? (0, import_node_path.join)(import_node_process.default.cwd(), "demo-vault"));
109
+ const pluginIds = values.plugin ?? discoverDemoVaultPluginIds(demoVaultPath);
110
+ if (pluginIds.length === 0) {
111
+ throw new Error(
112
+ `No community plugins to install: ${demoVaultPath} has no .obsidian/plugins/ entries. Name them explicitly, e.g. --plugin fix-require-modules.`
113
+ );
114
+ }
115
+ if (pluginIds.length > 1 && (values.repo !== void 0 || values.version !== void 0)) {
116
+ throw new Error("--repo and --version apply to a single plugin; pass exactly one --plugin, or run the command once per plugin.");
117
+ }
118
+ const injectPlugins = pluginIds.map((pluginId) => ({
119
+ pluginId,
120
+ ...values.repo !== void 0 && { repo: values.repo },
121
+ ...values.version !== void 0 && { version: values.version }
122
+ }));
123
+ const result = await (0, import_demo_vault_bootstrap.bootstrapDemoVaultPlugins)({
124
+ demoVaultPath,
125
+ injectPlugins,
126
+ shouldForce: values.force === true
127
+ });
128
+ for (const info of result.installed) {
129
+ import_node_process.default.stdout.write(`Installed ${info.pluginId} from ${info.repo}@${info.version ?? "latest"}: ${info.assetNames.join(", ")}
130
+ `);
131
+ }
132
+ if (result.skippedPluginIds.length > 0) {
133
+ import_node_process.default.stdout.write(`Already installed (use --force to re-download): ${result.skippedPluginIds.join(", ")}
134
+ `);
135
+ }
136
+ if (result.installed.length === 0) {
137
+ import_node_process.default.stdout.write("Nothing to install.\n");
138
+ }
139
+ }
140
+ async function runConnectCommand() {
38
141
  const { values } = (0, import_node_util.parseArgs)({
39
142
  options: {
40
143
  "command-timeout": { type: "string" },
@@ -60,24 +163,6 @@ Press Ctrl+C to stop.
60
163
  import_node_process.default.stdout.write("\nShutting down\u2026\n");
61
164
  await connection.dispose();
62
165
  }
63
- function buildOptions(values) {
64
- return {
65
- ...values["command-timeout"] !== void 0 && { commandTimeoutInMilliseconds: parseNumber("command-timeout", values["command-timeout"]) },
66
- ...values.host !== void 0 && { host: values.host },
67
- ...values["no-remove-vault"] === true && { shouldRemoveVaultOnDispose: false },
68
- ...values["obsidian-installer-version"] !== void 0 && { obsidianInstallerVersion: values["obsidian-installer-version"] },
69
- ...values["obsidian-version"] !== void 0 && { obsidianVersion: values["obsidian-version"] },
70
- ...values.port !== void 0 && { port: parseNumber("port", values.port) },
71
- ...values.vault !== void 0 && { vault: values.vault }
72
- };
73
- }
74
- function parseNumber(flag, raw) {
75
- const value = Number(raw);
76
- if (!Number.isFinite(value)) {
77
- throw new TypeError(`--${flag} must be a number, got: ${raw}`);
78
- }
79
- return value;
80
- }
81
166
  function waitForShutdownOrInstanceClose(cdpUrl) {
82
167
  const POLL_INTERVAL_IN_MILLISECONDS = 1e3;
83
168
  return new Promise((resolve) => {
@@ -113,4 +198,4 @@ function waitForShutdownOrInstanceClose(cdpUrl) {
113
198
  0 && (module.exports = {
114
199
  main
115
200
  });
116
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NsaS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFRoaW4gQ0xJIG92ZXIge0BsaW5rIGNvbm5lY3RUb0NkcH06IGxhdW5jaGVzIChvciBhdHRhY2hlcyB0bykgYSBDRFAtZW5hYmxlZFxuICogT2JzaWRpYW4gaW5zdGFuY2Ugd2l0aCB0aGUgcnVudGltZSBoZWxwZXIgbmFtZXNwYWNlIGJvb3RzdHJhcHBlZCwgcHJpbnRzIHRoZVxuICogY2hvc2VuIENEUCBwb3J0L1VSTCwgYW5kIHN0YXlzIGFsaXZlIHVudGlsIGludGVycnVwdGVkIHNvIGFuIGV4dGVybmFsIHRvb2xcbiAqIChyYXcgQ0RQIGB3c2AsIERldlRvb2xzLCBcdTIwMjYpIGNhbiBhdHRhY2guXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgQ0xJIChsYXVuY2hlcyBPYnNpZGlhbiAvIENEUCkgY292ZXJlZCBtYW51YWxseSwgbm90IGJ5IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5pbXBvcnQgeyBwYXJzZUFyZ3MgfSBmcm9tICdub2RlOnV0aWwnO1xuXG5pbXBvcnQgdHlwZSB7IENvbm5lY3RUb0NkcE9wdGlvbnMgfSBmcm9tICcuL2Nvbm5lY3QtdG8tY2RwLmNqcyc7XG5cbmltcG9ydCB7IGNvbm5lY3RUb0NkcCB9IGZyb20gJy4vY29ubmVjdC10by1jZHAuY2pzJztcblxuLyoqXG4gKiBUaGUgc2hhcGUgb2YgdGhlIHBhcnNlZCBDTEkgZmxhZyB2YWx1ZXMuXG4gKi9cbmludGVyZmFjZSBQYXJzZWRDbGlWYWx1ZXMge1xuICAnY29tbWFuZC10aW1lb3V0Jz86IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgJ2hvc3QnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAnbm8tcmVtb3ZlLXZhdWx0Jz86IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gICdvYnNpZGlhbi1pbnN0YWxsZXItdmVyc2lvbic/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICdvYnNpZGlhbi12ZXJzaW9uJz86IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgJ3BvcnQnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAndmF1bHQnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFBhcnNlcyBDTEkgYXJndW1lbnRzLCBvcGVucyB0aGUgY29ubmVjdGlvbiwgcHJpbnRzIGl0cyBlbmRwb2ludCwgYW5kIGJsb2Nrc1xuICogdW50aWwgYFNJR0lOVGAvYFNJR1RFUk1gIG9yIHRoZSBvd25lZCBPYnNpZGlhbiB3aW5kb3cgaXMgY2xvc2VkLCBkaXNwb3NpbmcgdGhlXG4gKiBjb25uZWN0aW9uIG9uIHNodXRkb3duLlxuICpcbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUgY29ubmVjdGlvbiBoYXMgYmVlbiBkaXNwb3NlZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1haW4oKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgdmFsdWVzIH0gPSBwYXJzZUFyZ3Moe1xuICAgIG9wdGlvbnM6IHtcbiAgICAgICdjb21tYW5kLXRpbWVvdXQnOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAnaG9zdCc6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICduby1yZW1vdmUtdmF1bHQnOiB7IHR5cGU6ICdib29sZWFuJyB9LFxuICAgICAgJ29ic2lkaWFuLWluc3RhbGxlci12ZXJzaW9uJzogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgJ29ic2lkaWFuLXZlcnNpb24nOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAncG9ydCc6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICd2YXVsdCc6IHsgdHlwZTogJ3N0cmluZycgfVxuICAgIH1cbiAgfSk7XG5cbiAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IGNvbm5lY3RUb0NkcChidWlsZE9wdGlvbnModmFsdWVzKSk7XG5cbiAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoXG4gICAgJ09ic2lkaWFuIENEUCByZWFkeS5cXG4nXG4gICAgICArIGAgIHBvcnQ6ICAgJHtTdHJpbmcoY29ubmVjdGlvbi5wb3J0KX1cXG5gXG4gICAgICArIGAgIGNkcFVybDogJHtjb25uZWN0aW9uLmNkcFVybH1cXG5gXG4gICAgICArIGAgIHZhdWx0OiAgJHtjb25uZWN0aW9uLnZhdWx0LnBhdGh9XFxuYFxuICAgICAgKyAnUnVudGltZSBoZWxwZXJzIGJvb3RzdHJhcHBlZCBhcyB3aW5kb3cuX19vYnNpZGlhbkludGVncmF0aW9uVGVzdGluZy5cXG4nXG4gICAgICArICdQcmVzcyBDdHJsK0MgdG8gc3RvcC5cXG4nXG4gICk7XG5cbiAgYXdhaXQgd2FpdEZvclNodXRkb3duT3JJbnN0YW5jZUNsb3NlKGNvbm5lY3Rpb24uY2RwVXJsKTtcblxuICBwcm9jZXNzLnN0ZG91dC53cml0ZSgnXFxuU2h1dHRpbmcgZG93blx1MjAyNlxcbicpO1xuICBhd2FpdCBjb25uZWN0aW9uLmRpc3Bvc2UoKTtcbn1cblxuLyoqXG4gKiBCdWlsZHMge0BsaW5rIENvbm5lY3RUb0NkcE9wdGlvbnN9IGZyb20gcGFyc2VkIENMSSBmbGFnIHZhbHVlcy5cbiAqXG4gKiBAcGFyYW0gdmFsdWVzIC0gVGhlIHBhcnNlZCBgcGFyc2VBcmdzYCB2YWx1ZXMuXG4gKiBAcmV0dXJucyBUaGUgY29ubmVjdGlvbiBvcHRpb25zLlxuICovXG5mdW5jdGlvbiBidWlsZE9wdGlvbnModmFsdWVzOiBQYXJzZWRDbGlWYWx1ZXMpOiBDb25uZWN0VG9DZHBPcHRpb25zIHtcbiAgcmV0dXJuIHtcbiAgICAuLi4odmFsdWVzWydjb21tYW5kLXRpbWVvdXQnXSAhPT0gdW5kZWZpbmVkICYmIHsgY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kczogcGFyc2VOdW1iZXIoJ2NvbW1hbmQtdGltZW91dCcsIHZhbHVlc1snY29tbWFuZC10aW1lb3V0J10pIH0pLFxuICAgIC4uLih2YWx1ZXMuaG9zdCAhPT0gdW5kZWZpbmVkICYmIHsgaG9zdDogdmFsdWVzLmhvc3QgfSksXG4gICAgLi4uKHZhbHVlc1snbm8tcmVtb3ZlLXZhdWx0J10gPT09IHRydWUgJiYgeyBzaG91bGRSZW1vdmVWYXVsdE9uRGlzcG9zZTogZmFsc2UgfSksXG4gICAgLi4uKHZhbHVlc1snb2JzaWRpYW4taW5zdGFsbGVyLXZlcnNpb24nXSAhPT0gdW5kZWZpbmVkICYmIHsgb2JzaWRpYW5JbnN0YWxsZXJWZXJzaW9uOiB2YWx1ZXNbJ29ic2lkaWFuLWluc3RhbGxlci12ZXJzaW9uJ10gfSksXG4gICAgLi4uKHZhbHVlc1snb2JzaWRpYW4tdmVyc2lvbiddICE9PSB1bmRlZmluZWQgJiYgeyBvYnNpZGlhblZlcnNpb246IHZhbHVlc1snb2JzaWRpYW4tdmVyc2lvbiddIH0pLFxuICAgIC4uLih2YWx1ZXMucG9ydCAhPT0gdW5kZWZpbmVkICYmIHsgcG9ydDogcGFyc2VOdW1iZXIoJ3BvcnQnLCB2YWx1ZXMucG9ydCkgfSksXG4gICAgLi4uKHZhbHVlcy52YXVsdCAhPT0gdW5kZWZpbmVkICYmIHsgdmF1bHQ6IHZhbHVlcy52YXVsdCB9KVxuICB9O1xufVxuXG4vKipcbiAqIFBhcnNlcyBhIG51bWVyaWMgQ0xJIGZsYWcgdmFsdWUsIHRocm93aW5nIG9uIGEgbm9uLWZpbml0ZSByZXN1bHQuXG4gKlxuICogQHBhcmFtIGZsYWcgLSBUaGUgZmxhZyBuYW1lIChmb3IgdGhlIGVycm9yIG1lc3NhZ2UpLlxuICogQHBhcmFtIHJhdyAtIFRoZSByYXcgc3RyaW5nIHZhbHVlLlxuICogQHJldHVybnMgVGhlIHBhcnNlZCBudW1iZXIuXG4gKiBAdGhyb3dzIEVycm9yIGlmIGByYXdgIGlzIG5vdCBhIGZpbml0ZSBudW1iZXIuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlTnVtYmVyKGZsYWc6IHN0cmluZywgcmF3OiBzdHJpbmcpOiBudW1iZXIge1xuICBjb25zdCB2YWx1ZSA9IE51bWJlcihyYXcpO1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAtLSR7ZmxhZ30gbXVzdCBiZSBhIG51bWJlciwgZ290OiAke3Jhd31gKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgb25jZSB0aGUgcHJvY2VzcyByZWNlaXZlcyBgU0lHSU5UYC9gU0lHVEVSTWAsIG9yIHRoZSBDRFAgZW5kcG9pbnRcbiAqIHN0b3BzIGFuc3dlcmluZyAodGhlIG93bmVkIE9ic2lkaWFuIHdpbmRvdyB3YXMgY2xvc2VkKS5cbiAqXG4gKiBAcGFyYW0gY2RwVXJsIC0gVGhlIGNvbm5lY3Rpb24ncyBDRFAgYmFzZSBVUkwgdG8gcG9sbC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb24gdGhlIGZpcnN0IHNodXRkb3duIHRyaWdnZXIuXG4gKi9cbmZ1bmN0aW9uIHdhaXRGb3JTaHV0ZG93bk9ySW5zdGFuY2VDbG9zZShjZHBVcmw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBQT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDEwMDA7XG4gIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgIGNvbnN0IHZlcnNpb25VcmwgPSBgJHtjZHBVcmx9L2pzb24vdmVyc2lvbmA7XG4gICAgbGV0IGlzU2V0dGxlZCA9IGZhbHNlO1xuXG4gICAgY29uc3QgdGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICBwcm9iZUFsaXZlKCkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAvLyBJZ25vcmUgcG9sbCBlcnJvcnMuXG4gICAgICB9KTtcbiAgICB9LCBQT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG5cbiAgICBwcm9jZXNzLm9uY2UoJ1NJR0lOVCcsIHNldHRsZSk7XG4gICAgcHJvY2Vzcy5vbmNlKCdTSUdURVJNJywgc2V0dGxlKTtcblxuICAgIGFzeW5jIGZ1bmN0aW9uIHByb2JlQWxpdmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHZlcnNpb25VcmwpO1xuICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgc2V0dGxlKCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBUaGUgQ0RQIHBvcnQgc3RvcHBlZCBhbnN3ZXJpbmc6IHRoZSBPYnNpZGlhbiB3aW5kb3cgd2FzIGNsb3NlZC5cbiAgICAgICAgc2V0dGxlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2V0dGxlKCk6IHZvaWQge1xuICAgICAgaWYgKGlzU2V0dGxlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpc1NldHRsZWQgPSB0cnVlO1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aW1lcik7XG4gICAgICByZXNvbHZlKCk7XG4gICAgfVxuICB9KTtcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBV0EsMEJBQW9CO0FBQ3BCLHVCQUEwQjtBQUkxQiw0QkFBNkI7QUFzQjdCLGVBQXNCLE9BQXNCO0FBQzFDLFFBQU0sRUFBRSxPQUFPLFFBQUksNEJBQVU7QUFBQSxJQUMzQixTQUFTO0FBQUEsTUFDUCxtQkFBbUIsRUFBRSxNQUFNLFNBQVM7QUFBQSxNQUNwQyxRQUFRLEVBQUUsTUFBTSxTQUFTO0FBQUEsTUFDekIsbUJBQW1CLEVBQUUsTUFBTSxVQUFVO0FBQUEsTUFDckMsOEJBQThCLEVBQUUsTUFBTSxTQUFTO0FBQUEsTUFDL0Msb0JBQW9CLEVBQUUsTUFBTSxTQUFTO0FBQUEsTUFDckMsUUFBUSxFQUFFLE1BQU0sU0FBUztBQUFBLE1BQ3pCLFNB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
201
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NsaS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFRoZSBwYWNrYWdlJ3MgQ0xJLiBUd28gY29tbWFuZHM6XG4gKlxuICogLSBUaGUgKipkZWZhdWx0KiogKG5vIHN1YmNvbW1hbmQpIFx1MjAxNCBhIHRoaW4gQ0xJIG92ZXIge0BsaW5rIGNvbm5lY3RUb0NkcH06IGxhdW5jaGVzXG4gKiAgIChvciBhdHRhY2hlcyB0bykgYSBDRFAtZW5hYmxlZCBPYnNpZGlhbiBpbnN0YW5jZSB3aXRoIHRoZSBydW50aW1lIGhlbHBlclxuICogICBuYW1lc3BhY2UgYm9vdHN0cmFwcGVkLCBwcmludHMgdGhlIGNob3NlbiBDRFAgcG9ydC9VUkwsIGFuZCBzdGF5cyBhbGl2ZSB1bnRpbFxuICogICBpbnRlcnJ1cHRlZCBzbyBhbiBleHRlcm5hbCB0b29sIChyYXcgQ0RQIGB3c2AsIERldlRvb2xzLCBcdTIwMjYpIGNhbiBhdHRhY2guXG4gKiAtICoqYGJvb3RzdHJhcC1kZW1vLXZhdWx0YCoqIFx1MjAxNCBpbnN0YWxscyBhIGRlbW8gdmF1bHQncyBpbmplY3RlZCBjb21tdW5pdHkgcGx1Z2luc1xuICogICBoZWFkbGVzc2x5IChzZWUgYGRlbW8tdmF1bHQtYm9vdHN0cmFwLnRzYCkuIFRoaXMgaXMgdGhlIGNvcHktcGFzdGVhYmxlIHJlbWVkeVxuICogICBgYnVpbGREZW1vVmF1bHRQb3B1bGF0ZWAncyB0aHJvdyBuYW1lcywgcmVwbGFjaW5nIHRoZSBHVUktb25seSBcIm9wZW5cbiAqICAgYGRlbW8tdmF1bHQvYCBpbiBPYnNpZGlhbiBvbmNlXCIgc3RlcCB0aGF0IGEgZnJlc2ggY2xvbmUgb3IgQ0kgY2Fubm90IHBlcmZvcm0uXG4gKlxuICogQW55dGhpbmcgdGhhdCBpcyBub3QgYSByZWNvZ25pemVkIHN1YmNvbW1hbmQgZmFsbHMgdGhyb3VnaCB0byB0aGUgZGVmYXVsdFxuICogY29tbWFuZCwgc28gYG9ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmcgLS12YXVsdCBcdTIwMjZgIGtlZXBzIHdvcmtpbmcgdW5jaGFuZ2VkLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIENMSSAobGF1bmNoZXMgT2JzaWRpYW4gLyBDRFAsIGRvd25sb2FkcyByZWxlYXNlcykgY292ZXJlZCBtYW51YWxseSwgbm90IGJ5IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB7XG4gIGV4aXN0c1N5bmMsXG4gIHJlYWRkaXJTeW5jXG59IGZyb20gJ25vZGU6ZnMnO1xuaW1wb3J0IHtcbiAgam9pbixcbiAgcmVzb2x2ZSBhcyByZXNvbHZlUGF0aFxufSBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHByb2Nlc3MgZnJvbSAnbm9kZTpwcm9jZXNzJztcbmltcG9ydCB7IHBhcnNlQXJncyB9IGZyb20gJ25vZGU6dXRpbCc7XG5cbmltcG9ydCB0eXBlIHsgQ29ubmVjdFRvQ2RwT3B0aW9ucyB9IGZyb20gJy4vY29ubmVjdC10by1jZHAuY2pzJztcbmltcG9ydCB0eXBlIHsgSW5qZWN0UGx1Z2luUGFyYW1zIH0gZnJvbSAnLi9kZW1vLXZhdWx0LXBvcHVsYXRlLmNqcyc7XG5cbmltcG9ydCB7IGNvbm5lY3RUb0NkcCB9IGZyb20gJy4vY29ubmVjdC10by1jZHAuY2pzJztcbmltcG9ydCB7IGJvb3RzdHJhcERlbW9WYXVsdFBsdWdpbnMgfSBmcm9tICcuL2RlbW8tdmF1bHQtYm9vdHN0cmFwLmNqcyc7XG5cbmNvbnN0IEJPT1RTVFJBUF9ERU1PX1ZBVUxUX0NPTU1BTkQgPSAnYm9vdHN0cmFwLWRlbW8tdmF1bHQnO1xuY29uc3QgSEVMUF9GTEFHUyA9IG5ldyBTZXQoWyctLWhlbHAnLCAnLWgnXSk7XG5cbi8qKlxuSW5kZXggb2YgYSBzdWJjb21tYW5kJ3MgZmlyc3QgYXJndW1lbnQgaW4gYHByb2Nlc3MuYXJndmAgKGBbbm9kZSwgc2NyaXB0LCBzdWJjb21tYW5kLCBcdTIwMjZdYCkuXG4gKi9cbmNvbnN0IFNVQkNPTU1BTkRfQVJHVU1FTlRTX1NUQVJUX0lOREVYID0gMztcblxuY29uc3QgVVNBR0UgPSBgVXNhZ2U6XG4gIG9ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmcgW29wdGlvbnNdXG4gICAgICBMYXVuY2ggKG9yIGF0dGFjaCB0bykgYSBDRFAtZW5hYmxlZCBPYnNpZGlhbiBpbnN0YW5jZSBhbmQgcHJpbnQgaXRzIGVuZHBvaW50LlxuICAgICAgT3B0aW9uczogLS12YXVsdCwgLS1wb3J0LCAtLWhvc3QsIC0tb2JzaWRpYW4tdmVyc2lvbiwgLS1vYnNpZGlhbi1pbnN0YWxsZXItdmVyc2lvbixcbiAgICAgICAgICAgICAgIC0tY29tbWFuZC10aW1lb3V0LCAtLW5vLXJlbW92ZS12YXVsdFxuXG4gIG9ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmcgJHtCT09UU1RSQVBfREVNT19WQVVMVF9DT01NQU5EfSBbb3B0aW9uc11cbiAgICAgIEluc3RhbGwgYSBkZW1vIHZhdWx0J3MgaW5qZWN0ZWQgY29tbXVuaXR5IHBsdWdpbnMgZnJvbSB0aGVpciBwdWJsaXNoZWQgR2l0SHViXG4gICAgICByZWxlYXNlcywgc28gaW50ZWdyYXRpb24gdGVzdHMgcnVuIHdpdGhvdXQgb3BlbmluZyBPYnNpZGlhbiBieSBoYW5kLlxuICAgICAgT3B0aW9uczogLS1kZW1vLXZhdWx0IDxwYXRoPiAgIGRlbW8gdmF1bHQgZGlyZWN0b3J5IChkZWZhdWx0OiAuL2RlbW8tdmF1bHQpXG4gICAgICAgICAgICAgICAtLXBsdWdpbiA8aWQ+ICAgICAgICAgcGx1Z2luIGlkIHRvIGluc3RhbGwgKHJlcGVhdGFibGU7IGRlZmF1bHQ6IGV2ZXJ5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQgYWxyZWFkeSBwcmVzZW50IHVuZGVyIC5vYnNpZGlhbi9wbHVnaW5zLylcbiAgICAgICAgICAgICAgIC0tcmVwbyA8b3duZXIvbmFtZT4gICBvdmVycmlkZSB0aGUgcmVnaXN0cnkgbG9va3VwIChzaW5nbGUgLS1wbHVnaW4gb25seSlcbiAgICAgICAgICAgICAgIC0tdmVyc2lvbiA8dGFnPiAgICAgICBwaW4gYSByZWxlYXNlIHRhZyAoc2luZ2xlIC0tcGx1Z2luIG9ubHkpXG4gICAgICAgICAgICAgICAtLWZvcmNlICAgICAgICAgICAgICAgcmUtZG93bmxvYWQgcGx1Z2lucyB0aGF0IGFyZSBhbHJlYWR5IGluc3RhbGxlZFxuYDtcblxuLyoqXG4gKiBUaGUgc2hhcGUgb2YgdGhlIHBhcnNlZCBDTEkgZmxhZyB2YWx1ZXMuXG4gKi9cbmludGVyZmFjZSBQYXJzZWRDbGlWYWx1ZXMge1xuICAnY29tbWFuZC10aW1lb3V0Jz86IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgJ2hvc3QnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAnbm8tcmVtb3ZlLXZhdWx0Jz86IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gICdvYnNpZGlhbi1pbnN0YWxsZXItdmVyc2lvbic/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICdvYnNpZGlhbi12ZXJzaW9uJz86IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgJ3BvcnQnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAndmF1bHQnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIERpc3BhdGNoZXMgdG8gdGhlIHJlcXVlc3RlZCBzdWJjb21tYW5kLCBmYWxsaW5nIHRocm91Z2ggdG8gdGhlIGRlZmF1bHQgQ0RQXG4gKiBjb21tYW5kIGZvciBhbnl0aGluZyB0aGF0IGlzIG5vdCBvbmUuXG4gKlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBjaG9zZW4gY29tbWFuZCBoYXMgZmluaXNoZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBtYWluKCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBbLCAsIGZpcnN0QXJndW1lbnRdID0gcHJvY2Vzcy5hcmd2O1xuXG4gIGlmIChmaXJzdEFyZ3VtZW50ICE9PSB1bmRlZmluZWQgJiYgSEVMUF9GTEFHUy5oYXMoZmlyc3RBcmd1bWVudCkpIHtcbiAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShVU0FHRSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGZpcnN0QXJndW1lbnQgPT09IEJPT1RTVFJBUF9ERU1PX1ZBVUxUX0NPTU1BTkQpIHtcbiAgICBhd2FpdCBydW5Cb290c3RyYXBEZW1vVmF1bHRDb21tYW5kKHByb2Nlc3MuYXJndi5zbGljZShTVUJDT01NQU5EX0FSR1VNRU5UU19TVEFSVF9JTkRFWCkpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGF3YWl0IHJ1bkNvbm5lY3RDb21tYW5kKCk7XG59XG5cbi8qKlxuICogQnVpbGRzIHtAbGluayBDb25uZWN0VG9DZHBPcHRpb25zfSBmcm9tIHBhcnNlZCBDTEkgZmxhZyB2YWx1ZXMuXG4gKlxuICogQHBhcmFtIHZhbHVlcyAtIFRoZSBwYXJzZWQgYHBhcnNlQXJnc2AgdmFsdWVzLlxuICogQHJldHVybnMgVGhlIGNvbm5lY3Rpb24gb3B0aW9ucy5cbiAqL1xuZnVuY3Rpb24gYnVpbGRPcHRpb25zKHZhbHVlczogUGFyc2VkQ2xpVmFsdWVzKTogQ29ubmVjdFRvQ2RwT3B0aW9ucyB7XG4gIHJldHVybiB7XG4gICAgLi4uKHZhbHVlc1snY29tbWFuZC10aW1lb3V0J10gIT09IHVuZGVmaW5lZCAmJiB7IGNvbW1hbmRUaW1lb3V0SW5NaWxsaXNlY29uZHM6IHBhcnNlTnVtYmVyKCdjb21tYW5kLXRpbWVvdXQnLCB2YWx1ZXNbJ2NvbW1hbmQtdGltZW91dCddKSB9KSxcbiAgICAuLi4odmFsdWVzLmhvc3QgIT09IHVuZGVmaW5lZCAmJiB7IGhvc3Q6IHZhbHVlcy5ob3N0IH0pLFxuICAgIC4uLih2YWx1ZXNbJ25vLXJlbW92ZS12YXVsdCddID09PSB0cnVlICYmIHsgc2hvdWxkUmVtb3ZlVmF1bHRPbkRpc3Bvc2U6IGZhbHNlIH0pLFxuICAgIC4uLih2YWx1ZXNbJ29ic2lkaWFuLWluc3RhbGxlci12ZXJzaW9uJ10gIT09IHVuZGVmaW5lZCAmJiB7IG9ic2lkaWFuSW5zdGFsbGVyVmVyc2lvbjogdmFsdWVzWydvYnNpZGlhbi1pbnN0YWxsZXItdmVyc2lvbiddIH0pLFxuICAgIC4uLih2YWx1ZXNbJ29ic2lkaWFuLXZlcnNpb24nXSAhPT0gdW5kZWZpbmVkICYmIHsgb2JzaWRpYW5WZXJzaW9uOiB2YWx1ZXNbJ29ic2lkaWFuLXZlcnNpb24nXSB9KSxcbiAgICAuLi4odmFsdWVzLnBvcnQgIT09IHVuZGVmaW5lZCAmJiB7IHBvcnQ6IHBhcnNlTnVtYmVyKCdwb3J0JywgdmFsdWVzLnBvcnQpIH0pLFxuICAgIC4uLih2YWx1ZXMudmF1bHQgIT09IHVuZGVmaW5lZCAmJiB7IHZhdWx0OiB2YWx1ZXMudmF1bHQgfSlcbiAgfTtcbn1cblxuLyoqXG4gKiBMaXN0cyB0aGUgcGx1Z2luIGlkcyBhbHJlYWR5IHByZXNlbnQgdW5kZXIgYSBkZW1vIHZhdWx0J3MgYC5vYnNpZGlhbi9wbHVnaW5zL2AsIHVzZWQgYXMgdGhlIGRlZmF1bHRcbiAqIGluc3RhbGwgc2V0IHdoZW4gYC0tcGx1Z2luYCBpcyBvbWl0dGVkLiBBIGZvbGRlciB0aGF0IGV4aXN0cyBidXQgbGFja3MgYG1haW4uanNgIGlzIGV4YWN0bHkgdGhlIHN0YXRlXG4gKiB0aGlzIGNvbW1hbmQgcmVwYWlycywgc28gcHJlc2VuY2UgXHUyMDE0IG5vdCBjb21wbGV0ZW5lc3MgXHUyMDE0IGlzIHRoZSBjcml0ZXJpb24uXG4gKlxuICogQHBhcmFtIGRlbW9WYXVsdFBhdGggLSBUaGUgZGVtbyB2YXVsdCByb290LlxuICogQHJldHVybnMgVGhlIHBsdWdpbiBpZHMsIG9yIGFuIGVtcHR5IGFycmF5IHdoZW4gdGhlIHZhdWx0IGhhcyBubyBwbHVnaW5zIGZvbGRlci5cbiAqL1xuZnVuY3Rpb24gZGlzY292ZXJEZW1vVmF1bHRQbHVnaW5JZHMoZGVtb1ZhdWx0UGF0aDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBwbHVnaW5zRGlyZWN0b3J5ID0gam9pbihkZW1vVmF1bHRQYXRoLCAnLm9ic2lkaWFuJywgJ3BsdWdpbnMnKTtcbiAgaWYgKCFleGlzdHNTeW5jKHBsdWdpbnNEaXJlY3RvcnkpKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIHJldHVybiByZWFkZGlyU3luYyhwbHVnaW5zRGlyZWN0b3J5LCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSkuZmlsdGVyKChlbnRyeSkgPT4gZW50cnkuaXNEaXJlY3RvcnkoKSkubWFwKChlbnRyeSkgPT4gZW50cnkubmFtZSk7XG59XG5cbi8qKlxuICogUGFyc2VzIGEgbnVtZXJpYyBDTEkgZmxhZyB2YWx1ZSwgdGhyb3dpbmcgb24gYSBub24tZmluaXRlIHJlc3VsdC5cbiAqXG4gKiBAcGFyYW0gZmxhZyAtIFRoZSBmbGFnIG5hbWUgKGZvciB0aGUgZXJyb3IgbWVzc2FnZSkuXG4gKiBAcGFyYW0gcmF3IC0gVGhlIHJhdyBzdHJpbmcgdmFsdWUuXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIG51bWJlci5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgYHJhd2AgaXMgbm90IGEgZmluaXRlIG51bWJlci5cbiAqL1xuZnVuY3Rpb24gcGFyc2VOdW1iZXIoZmxhZzogc3RyaW5nLCByYXc6IHN0cmluZyk6IG51bWJlciB7XG4gIGNvbnN0IHZhbHVlID0gTnVtYmVyKHJhdyk7XG4gIGlmICghTnVtYmVyLmlzRmluaXRlKHZhbHVlKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYC0tJHtmbGFnfSBtdXN0IGJlIGEgbnVtYmVyLCBnb3Q6ICR7cmF3fWApO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBSdW5zIHRoZSBgYm9vdHN0cmFwLWRlbW8tdmF1bHRgIHN1YmNvbW1hbmQuXG4gKlxuICogQHBhcmFtIGNvbW1hbmRBcmd1bWVudHMgLSBUaGUgc3ViY29tbWFuZCdzIGFyZ3VtZW50cyAoZXZlcnl0aGluZyBhZnRlciB0aGUgc3ViY29tbWFuZCBuYW1lKS5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUgaW5zdGFsbCBoYXMgZmluaXNoZWQuXG4gKiBAdGhyb3dzIEVycm9yIGlmIG5vIHBsdWdpbiBpZHMgY2FuIGJlIGRldGVybWluZWQsIG9yIGAtLXJlcG9gIC8gYC0tdmVyc2lvbmAgYXJlIHVzZWQgd2l0aCBzZXZlcmFsIHBsdWdpbnMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJ1bkJvb3RzdHJhcERlbW9WYXVsdENvbW1hbmQoY29tbWFuZEFyZ3VtZW50czogc3RyaW5nW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyB2YWx1ZXMgfSA9IHBhcnNlQXJncyh7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHVuaWNvcm4vbmFtZS1yZXBsYWNlbWVudHMgLS0gYGFyZ3NgIGlzIE5vZGUncyBvd24gYHBhcnNlQXJnc2Agb3B0aW9uIG5hbWUuXG4gICAgYXJnczogY29tbWFuZEFyZ3VtZW50cyxcbiAgICBvcHRpb25zOiB7XG4gICAgICAnZGVtby12YXVsdCc6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICdmb3JjZSc6IHsgdHlwZTogJ2Jvb2xlYW4nIH0sXG4gICAgICAncGx1Z2luJzogeyBtdWx0aXBsZTogdHJ1ZSwgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICdyZXBvJzogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgJ3ZlcnNpb24nOiB7IHR5cGU6ICdzdHJpbmcnIH1cbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IGRlbW9WYXVsdFBhdGggPSByZXNvbHZlUGF0aCh2YWx1ZXNbJ2RlbW8tdmF1bHQnXSA/PyBqb2luKHByb2Nlc3MuY3dkKCksICdkZW1vLXZhdWx0JykpO1xuICBjb25zdCBwbHVnaW5JZHMgPSB2YWx1ZXMucGx1Z2luID8/IGRpc2NvdmVyRGVtb1ZhdWx0UGx1Z2luSWRzKGRlbW9WYXVsdFBhdGgpO1xuXG4gIGlmIChwbHVnaW5JZHMubGVuZ3RoID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYE5vIGNvbW11bml0eSBwbHVnaW5zIHRvIGluc3RhbGw6ICR7ZGVtb1ZhdWx0UGF0aH0gaGFzIG5vIC5vYnNpZGlhbi9wbHVnaW5zLyBlbnRyaWVzLiBgXG4gICAgICAgICsgJ05hbWUgdGhlbSBleHBsaWNpdGx5LCBlLmcuIC0tcGx1Z2luIGZpeC1yZXF1aXJlLW1vZHVsZXMuJ1xuICAgICk7XG4gIH1cblxuICBpZiAocGx1Z2luSWRzLmxlbmd0aCA+IDEgJiYgKHZhbHVlcy5yZXBvICE9PSB1bmRlZmluZWQgfHwgdmFsdWVzLnZlcnNpb24gIT09IHVuZGVmaW5lZCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJy0tcmVwbyBhbmQgLS12ZXJzaW9uIGFwcGx5IHRvIGEgc2luZ2xlIHBsdWdpbjsgcGFzcyBleGFjdGx5IG9uZSAtLXBsdWdpbiwgb3IgcnVuIHRoZSBjb21tYW5kIG9uY2UgcGVyIHBsdWdpbi4nKTtcbiAgfVxuXG4gIGNvbnN0IGluamVjdFBsdWdpbnM6IEluamVjdFBsdWdpblBhcmFtc1tdID0gcGx1Z2luSWRzLm1hcCgocGx1Z2luSWQpID0+ICh7XG4gICAgcGx1Z2luSWQsXG4gICAgLi4uKHZhbHVlcy5yZXBvICE9PSB1bmRlZmluZWQgJiYgeyByZXBvOiB2YWx1ZXMucmVwbyB9KSxcbiAgICAuLi4odmFsdWVzLnZlcnNpb24gIT09IHVuZGVmaW5lZCAmJiB7IHZlcnNpb246IHZhbHVlcy52ZXJzaW9uIH0pXG4gIH0pKTtcblxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBib290c3RyYXBEZW1vVmF1bHRQbHVnaW5zKHtcbiAgICBkZW1vVmF1bHRQYXRoLFxuICAgIGluamVjdFBsdWdpbnMsXG4gICAgc2hvdWxkRm9yY2U6IHZhbHVlcy5mb3JjZSA9PT0gdHJ1ZVxuICB9KTtcblxuICBmb3IgKGNvbnN0IGluZm8gb2YgcmVzdWx0Lmluc3RhbGxlZCkge1xuICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGBJbnN0YWxsZWQgJHtpbmZvLnBsdWdpbklkfSBmcm9tICR7aW5mby5yZXBvfUAke2luZm8udmVyc2lvbiA/PyAnbGF0ZXN0J306ICR7aW5mby5hc3NldE5hbWVzLmpvaW4oJywgJyl9XFxuYCk7XG4gIH1cblxuICBpZiAocmVzdWx0LnNraXBwZWRQbHVnaW5JZHMubGVuZ3RoID4gMCkge1xuICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGBBbHJlYWR5IGluc3RhbGxlZCAodXNlIC0tZm9yY2UgdG8gcmUtZG93bmxvYWQpOiAke3Jlc3VsdC5za2lwcGVkUGx1Z2luSWRzLmpvaW4oJywgJyl9XFxuYCk7XG4gIH1cblxuICBpZiAocmVzdWx0Lmluc3RhbGxlZC5sZW5ndGggPT09IDApIHtcbiAgICBwcm9jZXNzLnN0ZG91dC53cml0ZSgnTm90aGluZyB0byBpbnN0YWxsLlxcbicpO1xuICB9XG59XG5cbi8qKlxuICogUnVucyB0aGUgZGVmYXVsdCBjb21tYW5kOiBwYXJzZXMgQ0xJIGFyZ3VtZW50cywgb3BlbnMgdGhlIGNvbm5lY3Rpb24sIHByaW50cyBpdHNcbiAqIGVuZHBvaW50LCBhbmQgYmxvY2tzIHVudGlsIGBTSUdJTlRgL2BTSUdURVJNYCBvciB0aGUgb3duZWQgT2JzaWRpYW4gd2luZG93IGlzXG4gKiBjbG9zZWQsIGRpc3Bvc2luZyB0aGUgY29ubmVjdGlvbiBvbiBzaHV0ZG93bi5cbiAqXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIGNvbm5lY3Rpb24gaGFzIGJlZW4gZGlzcG9zZWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJ1bkNvbm5lY3RDb21tYW5kKCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IHZhbHVlcyB9ID0gcGFyc2VBcmdzKHtcbiAgICBvcHRpb25zOiB7XG4gICAgICAnY29tbWFuZC10aW1lb3V0JzogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgJ2hvc3QnOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAnbm8tcmVtb3ZlLXZhdWx0JzogeyB0eXBlOiAnYm9vbGVhbicgfSxcbiAgICAgICdvYnNpZGlhbi1pbnN0YWxsZXItdmVyc2lvbic6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICdvYnNpZGlhbi12ZXJzaW9uJzogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgJ3BvcnQnOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAndmF1bHQnOiB7IHR5cGU6ICdzdHJpbmcnIH1cbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IGNvbm5lY3Rpb24gPSBhd2FpdCBjb25uZWN0VG9DZHAoYnVpbGRPcHRpb25zKHZhbHVlcykpO1xuXG4gIHByb2Nlc3Muc3Rkb3V0LndyaXRlKFxuICAgICdPYnNpZGlhbiBDRFAgcmVhZHkuXFxuJ1xuICAgICAgKyBgICBwb3J0OiAgICR7U3RyaW5nKGNvbm5lY3Rpb24ucG9ydCl9XFxuYFxuICAgICAgKyBgICBjZHBVcmw6ICR7Y29ubmVjdGlvbi5jZHBVcmx9XFxuYFxuICAgICAgKyBgICB2YXVsdDogICR7Y29ubmVjdGlvbi52YXVsdC5wYXRofVxcbmBcbiAgICAgICsgJ1J1bnRpbWUgaGVscGVycyBib290c3RyYXBwZWQgYXMgd2luZG93Ll9fb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmcuXFxuJ1xuICAgICAgKyAnUHJlc3MgQ3RybCtDIHRvIHN0b3AuXFxuJ1xuICApO1xuXG4gIGF3YWl0IHdhaXRGb3JTaHV0ZG93bk9ySW5zdGFuY2VDbG9zZShjb25uZWN0aW9uLmNkcFVybCk7XG5cbiAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoJ1xcblNodXR0aW5nIGRvd25cdTIwMjZcXG4nKTtcbiAgYXdhaXQgY29ubmVjdGlvbi5kaXNwb3NlKCk7XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgb25jZSB0aGUgcHJvY2VzcyByZWNlaXZlcyBgU0lHSU5UYC9gU0lHVEVSTWAsIG9yIHRoZSBDRFAgZW5kcG9pbnRcbiAqIHN0b3BzIGFuc3dlcmluZyAodGhlIG93bmVkIE9ic2lkaWFuIHdpbmRvdyB3YXMgY2xvc2VkKS5cbiAqXG4gKiBAcGFyYW0gY2RwVXJsIC0gVGhlIGNvbm5lY3Rpb24ncyBDRFAgYmFzZSBVUkwgdG8gcG9sbC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb24gdGhlIGZpcnN0IHNodXRkb3duIHRyaWdnZXIuXG4gKi9cbmZ1bmN0aW9uIHdhaXRGb3JTaHV0ZG93bk9ySW5zdGFuY2VDbG9zZShjZHBVcmw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBQT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDEwMDA7XG4gIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgIGNvbnN0IHZlcnNpb25VcmwgPSBgJHtjZHBVcmx9L2pzb24vdmVyc2lvbmA7XG4gICAgbGV0IGlzU2V0dGxlZCA9IGZhbHNlO1xuXG4gICAgY29uc3QgdGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICBwcm9iZUFsaXZlKCkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAvLyBJZ25vcmUgcG9sbCBlcnJvcnMuXG4gICAgICB9KTtcbiAgICB9LCBQT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG5cbiAgICBwcm9jZXNzLm9uY2UoJ1NJR0lOVCcsIHNldHRsZSk7XG4gICAgcHJvY2Vzcy5vbmNlKCdTSUdURVJNJywgc2V0dGxlKTtcblxuICAgIGFzeW5jIGZ1bmN0aW9uIHByb2JlQWxpdmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHZlcnNpb25VcmwpO1xuICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgc2V0dGxlKCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBUaGUgQ0RQIHBvcnQgc3RvcHBlZCBhbnN3ZXJpbmc6IHRoZSBPYnNpZGlhbiB3aW5kb3cgd2FzIGNsb3NlZC5cbiAgICAgICAgc2V0dGxlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2V0dGxlKCk6IHZvaWQge1xuICAgICAgaWYgKGlzU2V0dGxlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpc1NldHRsZWQgPSB0cnVlO1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aW1lcik7XG4gICAgICByZXNvbHZlKCk7XG4gICAgfVxuICB9KTtcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBb0JBLHFCQUdPO0FBQ1AsdUJBR087QUFDUCwwQkFBb0I7QUFDcEIsdUJBQTBCO0FBSzFCLDRCQUE2QjtBQUM3QixrQ0FBMEM7QUFFMUMsTUFBTSwrQkFBK0I7QUFDckMsTUFBTSxhQUFhLG9CQUFJLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQztBQUszQyxNQUFNLG1DQUFtQztBQUV6QyxNQUFNLFFBQVE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsaUNBTW1CLDRCQUE0QjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQThCN0QsZUFBc0IsT0FBc0I7QUFDMUMsUUFBTSxDQUFDLEVBQUUsRUFBRSxhQUFhLElBQUksb0JBQUFBLFFBQVE7QUFFcEMsTUFBSSxrQkFBa0IsVUFBYSxXQUFXLElBQUksYUFBYSxHQUFHO0FBQ2hFLHdCQUFBQSxRQUFRLE9BQU8sTUFBTSxLQUFLO0FBQzFCO0FBQUEsRUFDRjtBQUVBLE1BQUksa0JBQWtCLDhCQUE4QjtBQUNsRCxVQUFNLDZCQUE2QixvQkFBQUEsUUFBUSxLQUFLLE1BQU0sZ0NBQWdDLENBQUM7QUFDdkY7QUFBQSxFQUNGO0FBRUEsUUFBTSxrQkFBa0I7QUFDMUI7QUFRQSxTQUFTLGFBQWEsUUFBOEM7QUFDbEUsU0FBTztBQUFBLElBQ0wsR0FBSSxPQUFPLGlCQUFpQixNQUFNLFVBQWEsRUFBRSw4QkFBOEIsWUFBWSxtQkFBbUIsT0FBTyxpQkFBaUIsQ0FBQyxFQUFFO0FBQUEsSUFDekksR0FBSSxPQUFPLFNBQVMsVUFBYSxFQUFFLE1BQU0sT0FBTyxLQUFLO0FBQUEsSUFDckQsR0FBSSxPQUFPLGlCQUFpQixNQUFNLFFBQVEsRUFBRSw0QkFBNEIsTUFBTTtBQUFBLElBQzlFLEdBQUksT0FBTyw0QkFBNEIsTUFBTSxVQUFhLEVBQUUsMEJBQTBCLE9BQU8sNEJBQTRCLEVBQUU7QUFBQSxJQUMzSCxHQUFJLE9BQU8sa0JBQWtCLE1BQU0sVUFBYSxFQUFFLGlCQUFpQixPQUFPLGtCQUFrQixFQUFFO0FBQUEsSUFDOUYsR0FBSSxPQUFPLFNBQVMsVUFBYSxFQUFFLE1BQU0sWUFBWSxRQUFRLE9BQU8sSUFBSSxFQUFFO0FBQUEsSUFDMUUsR0FBSSxPQUFPLFVBQVUsVUFBYSxFQUFFLE9BQU8sT0FBTyxNQUFNO0FBQUEsRUFDMUQ7QUFDRjtBQVVBLFNBQVMsMkJBQTJCLGVBQWlDO0FBQ25FLFFBQU0sdUJBQW1CLHVCQUFLLGVBQWUsYUFBYSxTQUFTO0FBQ25FLE1BQUksS0FBQywyQkFBVyxnQkFBZ0IsR0FBRztBQUNqQyxXQUFPLENBQUM7QUFBQSxFQUNWO0FBQ0EsYUFBTyw0QkFBWSxrQkFBa0IsRUFBRSxlQUFlLEtBQUssQ0FBQyxFQUFFLE9BQU8sQ0FBQyxVQUFVLE1BQU0sWUFBWSxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsTUFBTSxJQUFJO0FBQ2hJO0FBVUEsU0FBUyxZQUFZLE1BQWMsS0FBcUI7QUFDdEQsUUFBTSxRQUFRLE9BQU8sR0FBRztBQUN4QixNQUFJLENBQUMsT0FBTyxTQUFTLEtBQUssR0FBRztBQUMzQixVQUFNLElBQUksVUFBVSxLQUFLLElBQUksMkJBQTJCLEdBQUcsRUFBRTtBQUFBLEVBQy9EO0FBQ0EsU0FBTztBQUNUO0FBU0EsZUFBZSw2QkFBNkIsa0JBQTJDO0FBQ3JGLFFBQU0sRUFBRSxPQUFPLFFBQUksNEJBQVU7QUFBQTtBQUFBLElBRTNCLE1BQU07QUFBQSxJQUNOLFNBQVM7QUFBQSxNQUNQLGNBQWMsRUFBRSxNQUFNLFNBQVM7QUFBQSxNQUMvQixTQUFTLEVBQUUsTUFBTSxVQUFVO0FBQUEsTUFDM0IsVUFBVSxFQUFFLFVBQVUsTUFBTSxNQUFNLFNBQVM7QUFBQSxNQUMzQyxRQUFRLEVBQUUsTUFBTSxTQUFTO0FBQUEsTUFDekIsV0FBVyxFQUFFLE1BQU0sU0FBUztBQUFBLElBQzlCO0FBQUEsRUFDRixDQUFDO0FBRUQsUUFBTSxvQkFBZ0IsaUJBQUFDLFNBQVksT0FBTyxZQUFZLFNBQUssdUJBQUssb0JBQUFELFFBQVEsSUFBSSxHQUFHLFlBQVksQ0FBQztBQUMzRixRQUFNLFlBQVksT0FBTyxVQUFVLDJCQUEyQixhQUFhO0FBRTNFLE1BQUksVUFBVSxXQUFXLEdBQUc7QUFDMUIsVUFBTSxJQUFJO0FBQUEsTUFDUixvQ0FBb0MsYUFBYTtBQUFBLElBRW5EO0FBQUEsRUFDRjtBQUVBLE1BQUksVUFBVSxTQUFTLE1BQU0sT0FBTyxTQUFTLFVBQWEsT0FBTyxZQUFZLFNBQVk7QUFDdkYsVUFBTSxJQUFJLE1BQU0sK0dBQStHO0FBQUEsRUFDakk7QUFFQSxRQUFNLGdCQUFzQyxVQUFVLElBQUksQ0FBQyxjQUFjO0FBQUEsSUFDdkU7QUFBQSxJQUNBLEdBQUksT0FBTyxTQUFTLFVBQWEsRUFBRSxNQUFNLE9BQU8sS0FBSztBQUFBLElBQ3JELEdBQUksT0FBTyxZQUFZLFVBQWEsRUFBRSxTQUFTLE9BQU8sUUFBUTtBQUFBLEVBQ2hFLEVBQUU7QUFFRixRQUFNLFNBQVMsVUFBTSx1REFBMEI7QUFBQSxJQUM3QztBQUFBLElBQ0E7QUFBQSxJQUNBLGFBQWEsT0FBTyxVQUFVO0FBQUEsRUFDaEMsQ0FBQztBQUVELGFBQVcsUUFBUSxPQUFPLFdBQVc7QUFDbkMsd0JBQUFBLFFBQVEsT0FBTyxNQUFNLGFBQWEsS0FBSyxRQUFRLFNBQVMsS0FBSyxJQUFJLElBQUksS0FBSyxXQUFXLFFBQVEsS0FBSyxLQUFLLFdBQVcsS0FBSyxJQUFJLENBQUM7QUFBQSxDQUFJO0FBQUEsRUFDbEk7QUFFQSxNQUFJLE9BQU8saUJBQWlCLFNBQVMsR0FBRztBQUN0Qyx3QkFBQUEsUUFBUSxPQUFPLE1BQU0sbURBQW1ELE9BQU8saUJBQWlCLEtBQUssSUFBSSxDQUFDO0FBQUEsQ0FBSTtBQUFBLEVBQ2hIO0FBRUEsTUFBSSxPQUFPLFVBQVUsV0FBVyxHQUFHO0FBQ2pDLHdCQUFBQSxRQUFRLE9BQU8sTUFBTSx1QkFBdUI7QUFBQSxFQUM5QztBQUNGO0FBU0EsZUFBZSxvQkFBbUM7QUFDaEQsUUFBTSxFQUFFLE9BQU8sUUFBSSw0QkFBVTtBQUFBLElBQzNCLFNBQVM7QUFBQSxNQUNQLG1CQUFtQixFQUFFLE1BQU0sU0FBUztBQUFBLE1BQ3BDLFFBQVEsRUFBRSxNQUFNLFNBQVM7QUFBQSxNQUN6QixtQkFBbUIsRUFBRSxNQUFNLFVBQVU7QUFBQSxNQUNyQyw4QkFBOEIsRUFBRSxNQUFNLFNBQVM7QUFBQSxNQUMvQyxvQkFBb0IsRUFBRSxNQUFNLFNBQVM7QUFBQSxNQUNyQyxRQUFRLEVBQUUsTUFBTSxTQUFTO0FBQUEsTUFDekIsU0FBUyxFQUFFLE1BQU0sU0FBUztBQUFBLElBQzVCO0FBQUEsRUFDRixDQUFDO0FBRUQsUUFBTSxhQUFhLFVBQU0sb0NBQWEsYUFBYSxNQUFNLENBQUM7QUFFMUQsc0JBQUFBLFFBQVEsT0FBTztBQUFBLElBQ2I7QUFBQSxZQUNpQixPQUFPLFdBQVcsSUFBSSxDQUFDO0FBQUEsWUFDdkIsV0FBVyxNQUFNO0FBQUEsWUFDakIsV0FBVyxNQUFNLElBQUk7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUd4QztBQUVBLFFBQU0sK0JBQStCLFdBQVcsTUFBTTtBQUV0RCxzQkFBQUEsUUFBUSxPQUFPLE1BQU0seUJBQW9CO0FBQ3pDLFFBQU0sV0FBVyxRQUFRO0FBQzNCO0FBU0EsU0FBUywrQkFBK0IsUUFBK0I7QUFDckUsUUFBTSxnQ0FBZ0M7QUFDdEMsU0FBTyxJQUFJLFFBQWMsQ0FBQyxZQUFZO0FBQ3BDLFVBQU0sYUFBYSxHQUFHLE1BQU07QUFDNUIsUUFBSSxZQUFZO0FBRWhCLFVBQU0sUUFBUSxZQUFZLE1BQU07QUFDOUIsaUJBQVcsRUFBRSxNQUFNLE1BQU07QUFBQSxNQUV6QixDQUFDO0FBQUEsSUFDSCxHQUFHLDZCQUE2QjtBQUVoQyx3QkFBQUEsUUFBUSxLQUFLLFVBQVUsTUFBTTtBQUM3Qix3QkFBQUEsUUFBUSxLQUFLLFdBQVcsTUFBTTtBQUU5QixtQkFBZSxhQUE0QjtBQUN6QyxVQUFJO0FBQ0YsY0FBTSxXQUFXLE1BQU0sTUFBTSxVQUFVO0FBQ3ZDLFlBQUksQ0FBQyxTQUFTLElBQUk7QUFDaEIsaUJBQU87QUFBQSxRQUNUO0FBQUEsTUFDRixRQUFRO0FBRU4sZUFBTztBQUFBLE1BQ1Q7QUFBQSxJQUNGO0FBRUEsYUFBUyxTQUFlO0FBQ3RCLFVBQUksV0FBVztBQUNiO0FBQUEsTUFDRjtBQUNBLGtCQUFZO0FBQ1osb0JBQWMsS0FBSztBQUNuQixjQUFRO0FBQUEsSUFDVjtBQUFBLEVBQ0YsQ0FBQztBQUNIOyIsCiAgIm5hbWVzIjogWyJwcm9jZXNzIiwgInJlc29sdmVQYXRoIl0KfQo=
@@ -1,16 +1,24 @@
1
1
  /**
2
2
  * @file
3
3
  *
4
- * Thin CLI over {@link connectToCdp}: launches (or attaches to) a CDP-enabled
5
- * Obsidian instance with the runtime helper namespace bootstrapped, prints the
6
- * chosen CDP port/URL, and stays alive until interrupted so an external tool
7
- * (raw CDP `ws`, DevTools, …) can attach.
4
+ * The package's CLI. Two commands:
5
+ *
6
+ * - The **default** (no subcommand) a thin CLI over {@link connectToCdp}: launches
7
+ * (or attaches to) a CDP-enabled Obsidian instance with the runtime helper
8
+ * namespace bootstrapped, prints the chosen CDP port/URL, and stays alive until
9
+ * interrupted so an external tool (raw CDP `ws`, DevTools, …) can attach.
10
+ * - **`bootstrap-demo-vault`** — installs a demo vault's injected community plugins
11
+ * headlessly (see `demo-vault-bootstrap.ts`). This is the copy-pasteable remedy
12
+ * `buildDemoVaultPopulate`'s throw names, replacing the GUI-only "open
13
+ * `demo-vault/` in Obsidian once" step that a fresh clone or CI cannot perform.
14
+ *
15
+ * Anything that is not a recognized subcommand falls through to the default
16
+ * command, so `obsidian-integration-testing --vault …` keeps working unchanged.
8
17
  */
9
18
  /**
10
- * Parses CLI arguments, opens the connection, prints its endpoint, and blocks
11
- * until `SIGINT`/`SIGTERM` or the owned Obsidian window is closed, disposing the
12
- * connection on shutdown.
19
+ * Dispatches to the requested subcommand, falling through to the default CDP
20
+ * command for anything that is not one.
13
21
  *
14
- * @returns A {@link Promise} that resolves once the connection has been disposed.
22
+ * @returns A {@link Promise} that resolves once the chosen command has finished.
15
23
  */
16
24
  export declare function main(): Promise<void>;
@@ -0,0 +1,52 @@
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 community_plugin_registry_exports = {};
20
+ __export(community_plugin_registry_exports, {
21
+ COMMUNITY_PLUGINS_REGISTRY_URL: () => COMMUNITY_PLUGINS_REGISTRY_URL,
22
+ OPTIONAL_PLUGIN_ASSET_NAMES: () => OPTIONAL_PLUGIN_ASSET_NAMES,
23
+ REQUIRED_PLUGIN_ASSET_NAMES: () => REQUIRED_PLUGIN_ASSET_NAMES,
24
+ buildPluginAssetUrl: () => buildPluginAssetUrl,
25
+ isValidRepoReference: () => isValidRepoReference,
26
+ selectPluginRepo: () => selectPluginRepo
27
+ });
28
+ module.exports = __toCommonJS(community_plugin_registry_exports);
29
+ const COMMUNITY_PLUGINS_REGISTRY_URL = "https://raw.githubusercontent.com/obsidianmd/obsidian-releases/master/community-plugins.json";
30
+ const REQUIRED_PLUGIN_ASSET_NAMES = ["main.js", "manifest.json"];
31
+ const OPTIONAL_PLUGIN_ASSET_NAMES = ["styles.css"];
32
+ function buildPluginAssetUrl(params) {
33
+ const { assetName, repo, version } = params;
34
+ const releasePath = version === void 0 ? "latest/download" : `download/${version}`;
35
+ return `https://github.com/${repo}/releases/${releasePath}/${assetName}`;
36
+ }
37
+ function isValidRepoReference(repo) {
38
+ return /^[\w.-]+\/[\w.-]+$/.test(repo);
39
+ }
40
+ function selectPluginRepo(params) {
41
+ return params.entries.find((entry) => entry.id === params.pluginId)?.repo;
42
+ }
43
+ // Annotate the CommonJS export names for ESM import in node:
44
+ 0 && (module.exports = {
45
+ COMMUNITY_PLUGINS_REGISTRY_URL,
46
+ OPTIONAL_PLUGIN_ASSET_NAMES,
47
+ REQUIRED_PLUGIN_ASSET_NAMES,
48
+ buildPluginAssetUrl,
49
+ isValidRepoReference,
50
+ selectPluginRepo
51
+ });
52
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvbW11bml0eS1wbHVnaW4tcmVnaXN0cnkudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBQdXJlIGhlbHBlcnMgZm9yIHJlc29sdmluZyBhIGNvbW11bml0eSBwbHVnaW4ncyAqKkdpdEh1YiByZWxlYXNlIGFzc2V0cyoqIGZyb21cbiAqIG5vdGhpbmcgYnV0IGl0cyBwbHVnaW4gaWQgXHUyMDE0IHRoZSBpZCBcdTIxOTIgcmVwbyBsb29rdXAgYW5kIHRoZSBhc3NldCBVUkwgc2hhcGVzLlxuICpcbiAqIEEgcGx1Z2luJ3MgYnVpbHQgZmlsZXMgbmV2ZXIgbGl2ZSBpbiBnaXQ6IGAub2JzaWRpYW4vcGx1Z2lucy8qYCBpcyBnaXRpZ25vcmVkIGluXG4gKiBldmVyeSBmbGVldCBwbHVnaW4gcmVwbywgc28gYSBkZW1vIHZhdWx0J3MgaW5qZWN0ZWQgY29tbXVuaXR5IHBsdWdpbnMgZXhpc3Qgb25cbiAqIGV4YWN0bHkgdGhlIG1hY2hpbmUgdGhhdCBvbmNlIG9wZW5lZCB0aGF0IHZhdWx0IGluIE9ic2lkaWFuLiBUbyBpbnN0YWxsIHRoZW1cbiAqIGhlYWRsZXNzbHkgKHNlZSBgZGVtby12YXVsdC1ib290c3RyYXAudHNgKSB0d28gdGhpbmdzIG11c3QgYmUgZGVyaXZhYmxlOlxuICpcbiAqIC0gKipXaGljaCByZXBvIHB1Ymxpc2hlcyB0aGUgaWQuKiogT2JzaWRpYW4ncyBvd24gcmVnaXN0cnkgXHUyMDE0XG4gKiAgIHtAbGluayBDT01NVU5JVFlfUExVR0lOU19SRUdJU1RSWV9VUkx9LCBzZXJ2ZWQgZnJvbSB0aGUgc2FtZVxuICogICBgb2JzaWRpYW5tZC9vYnNpZGlhbi1yZWxlYXNlc2AgcmVwb3NpdG9yeSB0aGUgaW5zdGFsbGVyIGRvd25sb2FkZXIgYWxyZWFkeVxuICogICB1c2VzIFx1MjAxNCBtYXBzIGV2ZXJ5IGNvbW11bml0eSBwbHVnaW4ncyBgaWRgIHRvIGl0cyBgb3duZXIvbmFtZWAgcmVwby4gVGhhdCBpc1xuICogICB0aGUgc2FtZSB0YWJsZSB0aGUgaW4tYXBwIGNvbW11bml0eSBicm93c2VyIGluc3RhbGxzIGZyb20sIHNvIG5vXG4gKiAgIHBsdWdpbi1zcGVjaWZpYyBtYXBwaW5nIGhhcyB0byBiZSBoYXJkY29kZWQgaGVyZS5cbiAqIC0gKipXaGVyZSB0aGF0IHJlcG8ncyBhc3NldHMgbGl2ZS4qKiBBIHBsdWdpbiByZWxlYXNlIHB1Ymxpc2hlcyBgbWFuaWZlc3QuanNvbmAsXG4gKiAgIGBtYWluLmpzYCBhbmQgKG9wdGlvbmFsbHkpIGBzdHlsZXMuY3NzYCBhcyByZWxlYXNlIGFzc2V0cztcbiAqICAge0BsaW5rIGJ1aWxkUGx1Z2luQXNzZXRVcmx9IGJ1aWxkcyB0aGUgVVJMIGZvciBvbmUsIGZvciBlaXRoZXIgdGhlIGxhdGVzdFxuICogICByZWxlYXNlIG9yIGEgcGlubmVkIHRhZy5cbiAqXG4gKiBFdmVyeXRoaW5nIGRlY2lkYWJsZSB3aXRob3V0IHRoZSBuZXR3b3JrIGxpdmVzIGhlcmUgc28gaXQgc3RheXMgdW5pdC10ZXN0ZWQ7IHRoZVxuICogZmV0Y2hpbmcgYW5kIHdyaXRpbmcgc2l0IGluIGBkZW1vLXZhdWx0LWJvb3RzdHJhcC50c2AsIG1pcnJvcmluZyB0aGVcbiAqIGBpbnN0YWxsZXItYXNzZXQudHNgIC8gYG9ic2lkaWFuLWluc3RhbGxlci50c2Agc3BsaXQuXG4gKi9cblxuLyoqXG4gKiBPYnNpZGlhbidzIG93biBjb21tdW5pdHkgcGx1Z2luIHJlZ2lzdHJ5OiB0aGUgYGlkYCBcdTIxOTIgYHJlcG9gIHRhYmxlIHRoZSBpbi1hcHBcbiAqIGNvbW11bml0eSBicm93c2VyIGluc3RhbGxzIGZyb20sIHNlcnZlZCBmcm9tIHRoZSBgb2JzaWRpYW5tZC9vYnNpZGlhbi1yZWxlYXNlc2BcbiAqIHJlcG9zaXRvcnkuXG4gKi9cbmV4cG9ydCBjb25zdCBDT01NVU5JVFlfUExVR0lOU19SRUdJU1RSWV9VUkwgPSAnaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL29ic2lkaWFubWQvb2JzaWRpYW4tcmVsZWFzZXMvbWFzdGVyL2NvbW11bml0eS1wbHVnaW5zLmpzb24nO1xuXG4vKipcbiAqIFRoZSBgbWFpbi5qc2AgLyBgbWFuaWZlc3QuanNvbmAgcGFpciBldmVyeSBwbHVnaW4gcmVsZWFzZSBtdXN0IHB1Ymxpc2ggZm9yIHRoZVxuICogcGx1Z2luIHRvIGJlIGxvYWRhYmxlIFx1MjAxNCB0aGUgc2FtZSB0d28gZmlsZXMgYGJ1aWxkRGVtb1ZhdWx0UG9wdWxhdGVgIHJlcXVpcmVzIG9uXG4gKiBkaXNrLlxuICovXG5leHBvcnQgY29uc3QgUkVRVUlSRURfUExVR0lOX0FTU0VUX05BTUVTID0gWydtYWluLmpzJywgJ21hbmlmZXN0Lmpzb24nXSBhcyBjb25zdDtcblxuLyoqXG4gKiBgc3R5bGVzLmNzc2AgaXMgcHVibGlzaGVkIG9ubHkgYnkgcGx1Z2lucyB0aGF0IHNoaXAgQ1NTLCBzbyBhIGRvd25sb2FkIG9mIGl0IGlzXG4gKiBhbGxvd2VkIHRvIDQwNCB3aXRob3V0IGZhaWxpbmcgdGhlIGluc3RhbGwuXG4gKi9cbmV4cG9ydCBjb25zdCBPUFRJT05BTF9QTFVHSU5fQVNTRVRfTkFNRVMgPSBbJ3N0eWxlcy5jc3MnXSBhcyBjb25zdDtcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgYnVpbGRQbHVnaW5Bc3NldFVybH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQnVpbGRQbHVnaW5Bc3NldFVybFBhcmFtcyB7XG4gIC8qKlxuICBUaGUgcmVsZWFzZSBhc3NldCdzIGZpbGUgbmFtZSwgZS5nLiBgbWFpbi5qc2AuXG4gICAqL1xuICByZWFkb25seSBhc3NldE5hbWU6IHN0cmluZztcblxuICAvKipcbiAgVGhlIHB1Ymxpc2hpbmcgR2l0SHViIHJlcG9zaXRvcnksIGFzIGBvd25lci9uYW1lYC5cbiAgICovXG4gIHJlYWRvbmx5IHJlcG86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHJlbGVhc2UgdGFnIHRvIGRvd25sb2FkIGZyb20uIE9taXQgZm9yIHRoZSByZXBvc2l0b3J5J3MgbGF0ZXN0IHJlbGVhc2UgXHUyMDE0XG4gICAqIHdoaWNoIGlzIHdoYXQgdGhlIGluLWFwcCBjb21tdW5pdHkgYnJvd3NlciBpbnN0YWxscy5cbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb24/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogT25lIHJvdyBvZiBPYnNpZGlhbidzIGBjb21tdW5pdHktcGx1Z2lucy5qc29uYCwgcmVkdWNlZCB0byB0aGUgZmllbGRzIHRoZVxuICogYm9vdHN0cmFwIG5lZWRzLiBUaGUgcHVibGlzaGVkIHJvd3MgY2FycnkgYG5hbWVgLCBgYXV0aG9yYCBhbmQgYGRlc2NyaXB0aW9uYFxuICogdG9vOyB0aGV5IGFyZSBkZWxpYmVyYXRlbHkgbm90IG1vZGVsbGVkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbW11bml0eVBsdWdpblJlZ2lzdHJ5RW50cnkge1xuICAvKipcbiAgVGhlIHBsdWdpbidzIGlkIFx1MjAxNCBpdHMgYC5vYnNpZGlhbi9wbHVnaW5zLzxpZD5gIGZvbGRlciBuYW1lLlxuICAgKi9cbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcblxuICAvKipcbiAgVGhlIHB1Ymxpc2hpbmcgR2l0SHViIHJlcG9zaXRvcnksIGFzIGBvd25lci9uYW1lYC5cbiAgICovXG4gIHJlYWRvbmx5IHJlcG86IHN0cmluZztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgc2VsZWN0UGx1Z2luUmVwb30uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VsZWN0UGx1Z2luUmVwb1BhcmFtcyB7XG4gIC8qKlxuICBUaGUgcmVnaXN0cnkgcm93cywgYXMgcHVibGlzaGVkIGJ5IHtAbGluayBDT01NVU5JVFlfUExVR0lOU19SRUdJU1RSWV9VUkx9LlxuICAgKi9cbiAgcmVhZG9ubHkgZW50cmllczogcmVhZG9ubHkgQ29tbXVuaXR5UGx1Z2luUmVnaXN0cnlFbnRyeVtdO1xuXG4gIC8qKlxuICBUaGUgcGx1Z2luIGlkIHRvIGxvb2sgdXAuXG4gICAqL1xuICByZWFkb25seSBwbHVnaW5JZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIEJ1aWxkcyB0aGUgZG93bmxvYWQgVVJMIGZvciBvbmUgYXNzZXQgb2YgYSBwbHVnaW4ncyBHaXRIdWIgcmVsZWFzZS5cbiAqXG4gKiBHaXRIdWIgc2VydmVzIHR3byBmb3JtcyBcdTIwMTQgYSBwaW5uZWQgYHJlbGVhc2VzL2Rvd25sb2FkLzx0YWc+Lzxhc3NldD5gIGFuZCB0aGVcbiAqIG1vdmluZyBgcmVsZWFzZXMvbGF0ZXN0L2Rvd25sb2FkLzxhc3NldD5gIFx1MjAxNCBzbyBhIHBpbm5lZCB2ZXJzaW9uIGFuZCB0aGUgZGVmYXVsdFxuICogXCJ3aGF0ZXZlciBpcyBjdXJyZW50XCIgc2hhcmUgb25lIGJ1aWxkZXIuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSB7QGxpbmsgQnVpbGRQbHVnaW5Bc3NldFVybFBhcmFtc30uXG4gKiBAcmV0dXJucyBUaGUgYXNzZXQncyBkb3dubG9hZCBVUkwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFBsdWdpbkFzc2V0VXJsKHBhcmFtczogQnVpbGRQbHVnaW5Bc3NldFVybFBhcmFtcyk6IHN0cmluZyB7XG4gIGNvbnN0IHsgYXNzZXROYW1lLCByZXBvLCB2ZXJzaW9uIH0gPSBwYXJhbXM7XG4gIGNvbnN0IHJlbGVhc2VQYXRoID0gdmVyc2lvbiA9PT0gdW5kZWZpbmVkID8gJ2xhdGVzdC9kb3dubG9hZCcgOiBgZG93bmxvYWQvJHt2ZXJzaW9ufWA7XG4gIHJldHVybiBgaHR0cHM6Ly9naXRodWIuY29tLyR7cmVwb30vcmVsZWFzZXMvJHtyZWxlYXNlUGF0aH0vJHthc3NldE5hbWV9YDtcbn1cblxuLyoqXG4gKiBDaGVja3MgdGhhdCBhIHN0cmluZyBoYXMgdGhlIGBvd25lci9uYW1lYCBzaGFwZSBhIEdpdEh1YiByZXBvc2l0b3J5IHJlZmVyZW5jZVxuICogbmVlZHMsIHNvIGEgbWFsZm9ybWVkIG92ZXJyaWRlIGlzIHJlamVjdGVkIGJlZm9yZSBpdCBpcyBzcGxpY2VkIGludG8gYSBVUkwuXG4gKlxuICogQHBhcmFtIHJlcG8gLSBUaGUgY2FuZGlkYXRlIHJlcG9zaXRvcnkgcmVmZXJlbmNlLlxuICogQHJldHVybnMgV2hldGhlciBpdCBpcyBhIHdlbGwtZm9ybWVkIGBvd25lci9uYW1lYCBwYWlyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFJlcG9SZWZlcmVuY2UocmVwbzogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiAvXltcXHcuLV0rXFwvW1xcdy4tXSskLy50ZXN0KHJlcG8pO1xufVxuXG4vKipcbiAqIExvb2tzIGEgcGx1Z2luIGlkIHVwIGluIE9ic2lkaWFuJ3MgY29tbXVuaXR5IHBsdWdpbiByZWdpc3RyeS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHtAbGluayBTZWxlY3RQbHVnaW5SZXBvUGFyYW1zfS5cbiAqIEByZXR1cm5zIFRoZSBwdWJsaXNoaW5nIGBvd25lci9uYW1lYCByZXBvLCBvciBgdW5kZWZpbmVkYCB3aGVuIHRoZSBpZCBpcyBub3QgYVxuICogICByZWdpc3RlcmVkIGNvbW11bml0eSBwbHVnaW4gKGEgcHJpdmF0ZSBvciB1bmxpc3RlZCBwbHVnaW4sIG9yIGEgdHlwbykuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWxlY3RQbHVnaW5SZXBvKHBhcmFtczogU2VsZWN0UGx1Z2luUmVwb1BhcmFtcyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBwYXJhbXMuZW50cmllcy5maW5kKChlbnRyeSkgPT4gZW50cnkuaWQgPT09IHBhcmFtcy5wbHVnaW5JZCk/LnJlcG87XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQWdDTyxNQUFNLGlDQUFpQztBQU92QyxNQUFNLDhCQUE4QixDQUFDLFdBQVcsZUFBZTtBQU0vRCxNQUFNLDhCQUE4QixDQUFDLFlBQVk7QUFpRWpELFNBQVMsb0JBQW9CLFFBQTJDO0FBQzdFLFFBQU0sRUFBRSxXQUFXLE1BQU0sUUFBUSxJQUFJO0FBQ3JDLFFBQU0sY0FBYyxZQUFZLFNBQVksb0JBQW9CLFlBQVksT0FBTztBQUNuRixTQUFPLHNCQUFzQixJQUFJLGFBQWEsV0FBVyxJQUFJLFNBQVM7QUFDeEU7QUFTTyxTQUFTLHFCQUFxQixNQUF1QjtBQUMxRCxTQUFPLHFCQUFxQixLQUFLLElBQUk7QUFDdkM7QUFTTyxTQUFTLGlCQUFpQixRQUFvRDtBQUNuRixTQUFPLE9BQU8sUUFBUSxLQUFLLENBQUMsVUFBVSxNQUFNLE9BQU8sT0FBTyxRQUFRLEdBQUc7QUFDdkU7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -0,0 +1,116 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Pure helpers for resolving a community plugin's **GitHub release assets** from
5
+ * nothing but its plugin id — the id → repo lookup and the asset URL shapes.
6
+ *
7
+ * A plugin's built files never live in git: `.obsidian/plugins/*` is gitignored in
8
+ * every fleet plugin repo, so a demo vault's injected community plugins exist on
9
+ * exactly the machine that once opened that vault in Obsidian. To install them
10
+ * headlessly (see `demo-vault-bootstrap.ts`) two things must be derivable:
11
+ *
12
+ * - **Which repo publishes the id.** Obsidian's own registry —
13
+ * {@link COMMUNITY_PLUGINS_REGISTRY_URL}, served from the same
14
+ * `obsidianmd/obsidian-releases` repository the installer downloader already
15
+ * uses — maps every community plugin's `id` to its `owner/name` repo. That is
16
+ * the same table the in-app community browser installs from, so no
17
+ * plugin-specific mapping has to be hardcoded here.
18
+ * - **Where that repo's assets live.** A plugin release publishes `manifest.json`,
19
+ * `main.js` and (optionally) `styles.css` as release assets;
20
+ * {@link buildPluginAssetUrl} builds the URL for one, for either the latest
21
+ * release or a pinned tag.
22
+ *
23
+ * Everything decidable without the network lives here so it stays unit-tested; the
24
+ * fetching and writing sit in `demo-vault-bootstrap.ts`, mirroring the
25
+ * `installer-asset.ts` / `obsidian-installer.ts` split.
26
+ */
27
+ /**
28
+ * Obsidian's own community plugin registry: the `id` → `repo` table the in-app
29
+ * community browser installs from, served from the `obsidianmd/obsidian-releases`
30
+ * repository.
31
+ */
32
+ export declare const COMMUNITY_PLUGINS_REGISTRY_URL = "https://raw.githubusercontent.com/obsidianmd/obsidian-releases/master/community-plugins.json";
33
+ /**
34
+ * The `main.js` / `manifest.json` pair every plugin release must publish for the
35
+ * plugin to be loadable — the same two files `buildDemoVaultPopulate` requires on
36
+ * disk.
37
+ */
38
+ export declare const REQUIRED_PLUGIN_ASSET_NAMES: readonly ["main.js", "manifest.json"];
39
+ /**
40
+ * `styles.css` is published only by plugins that ship CSS, so a download of it is
41
+ * allowed to 404 without failing the install.
42
+ */
43
+ export declare const OPTIONAL_PLUGIN_ASSET_NAMES: readonly ["styles.css"];
44
+ /**
45
+ * Parameters for {@link buildPluginAssetUrl}.
46
+ */
47
+ export interface BuildPluginAssetUrlParams {
48
+ /**
49
+ The release asset's file name, e.g. `main.js`.
50
+ */
51
+ readonly assetName: string;
52
+ /**
53
+ The publishing GitHub repository, as `owner/name`.
54
+ */
55
+ readonly repo: string;
56
+ /**
57
+ * The release tag to download from. Omit for the repository's latest release —
58
+ * which is what the in-app community browser installs.
59
+ */
60
+ readonly version?: string | undefined;
61
+ }
62
+ /**
63
+ * One row of Obsidian's `community-plugins.json`, reduced to the fields the
64
+ * bootstrap needs. The published rows carry `name`, `author` and `description`
65
+ * too; they are deliberately not modelled.
66
+ */
67
+ export interface CommunityPluginRegistryEntry {
68
+ /**
69
+ The plugin's id — its `.obsidian/plugins/<id>` folder name.
70
+ */
71
+ readonly id: string;
72
+ /**
73
+ The publishing GitHub repository, as `owner/name`.
74
+ */
75
+ readonly repo: string;
76
+ }
77
+ /**
78
+ * Parameters for {@link selectPluginRepo}.
79
+ */
80
+ export interface SelectPluginRepoParams {
81
+ /**
82
+ The registry rows, as published by {@link COMMUNITY_PLUGINS_REGISTRY_URL}.
83
+ */
84
+ readonly entries: readonly CommunityPluginRegistryEntry[];
85
+ /**
86
+ The plugin id to look up.
87
+ */
88
+ readonly pluginId: string;
89
+ }
90
+ /**
91
+ * Builds the download URL for one asset of a plugin's GitHub release.
92
+ *
93
+ * GitHub serves two forms — a pinned `releases/download/<tag>/<asset>` and the
94
+ * moving `releases/latest/download/<asset>` — so a pinned version and the default
95
+ * "whatever is current" share one builder.
96
+ *
97
+ * @param params - The {@link BuildPluginAssetUrlParams}.
98
+ * @returns The asset's download URL.
99
+ */
100
+ export declare function buildPluginAssetUrl(params: BuildPluginAssetUrlParams): string;
101
+ /**
102
+ * Checks that a string has the `owner/name` shape a GitHub repository reference
103
+ * needs, so a malformed override is rejected before it is spliced into a URL.
104
+ *
105
+ * @param repo - The candidate repository reference.
106
+ * @returns Whether it is a well-formed `owner/name` pair.
107
+ */
108
+ export declare function isValidRepoReference(repo: string): boolean;
109
+ /**
110
+ * Looks a plugin id up in Obsidian's community plugin registry.
111
+ *
112
+ * @param params - The {@link SelectPluginRepoParams}.
113
+ * @returns The publishing `owner/name` repo, or `undefined` when the id is not a
114
+ * registered community plugin (a private or unlisted plugin, or a typo).
115
+ */
116
+ export declare function selectPluginRepo(params: SelectPluginRepoParams): string | undefined;