obsidian-integration-testing 5.1.2 → 5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +97 -0
- package/bin/obsidian-integration-testing.mjs +4 -0
- package/dist/lib/cjs/cli.cjs +95 -0
- package/dist/lib/cjs/cli.d.cts +15 -0
- package/dist/lib/cjs/connect-to-cdp.cjs +87 -0
- package/dist/lib/cjs/connect-to-cdp.d.cts +130 -0
- package/dist/lib/cjs/eval-in-obsidian.cjs +1 -1
- package/dist/lib/cjs/eval-in-obsidian.d.cts +89 -0
- package/dist/lib/cjs/index.cjs +4 -1
- package/dist/lib/cjs/index.d.cts +3 -1
- package/dist/lib/cjs/library.cjs +1 -1
- package/dist/lib/cjs/namespace-bootstrap.cjs +35 -4
- package/dist/lib/cjs/transport-desktop-cdp.cjs +81 -34
- package/dist/lib/cjs/transport-desktop-cdp.d.cts +21 -0
- package/dist/lib/esm/cli.d.mts +15 -0
- package/dist/lib/esm/cli.mjs +61 -0
- package/dist/lib/esm/connect-to-cdp.d.mts +130 -0
- package/dist/lib/esm/connect-to-cdp.mjs +63 -0
- package/dist/lib/esm/eval-in-obsidian.d.mts +89 -0
- package/dist/lib/esm/eval-in-obsidian.mjs +1 -1
- package/dist/lib/esm/index.d.mts +3 -1
- package/dist/lib/esm/index.mjs +3 -1
- package/dist/lib/esm/library.mjs +1 -1
- package/dist/lib/esm/namespace-bootstrap.mjs +35 -4
- package/dist/lib/esm/transport-desktop-cdp.d.mts +21 -0
- package/dist/lib/esm/transport-desktop-cdp.mjs +81 -34
- package/dist/obsidian-integration-testing-5.3.0.tgz +0 -0
- package/package.json +5 -1
- package/dist/obsidian-integration-testing-5.1.2.tgz +0 -0
package/README.md
CHANGED
|
@@ -109,6 +109,64 @@ const title = await evalInObsidian({
|
|
|
109
109
|
});
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
+
### Simulate real user input (trusted keyboard & pointer)
|
|
113
|
+
|
|
114
|
+
Every callback also receives helpers that inject **trusted** input at the Chromium level
|
|
115
|
+
(via Electron's `webContents.sendInputEvent`) — the kind of event only the browser/OS
|
|
116
|
+
normally produces. This matters because the in-page alternatives give false results:
|
|
117
|
+
`dispatchEvent(new KeyboardEvent(...))` / `new MouseEvent(...)` are untrusted
|
|
118
|
+
(`isTrusted: false`), so CodeMirror ignores the keystroke and `:hover` never takes effect;
|
|
119
|
+
`execCommand('insertText')` mutates the selection even when the editor is not focused,
|
|
120
|
+
masking focus bugs as false passes. The trusted helpers flow through the real input
|
|
121
|
+
pipeline, so text lands **only if the editor genuinely holds focus** and `:hover` rules
|
|
122
|
+
genuinely apply.
|
|
123
|
+
|
|
124
|
+
The element/editor arguments are live renderer DOM nodes — the callback runs in the Obsidian
|
|
125
|
+
renderer, so no cross-process serialization is needed.
|
|
126
|
+
|
|
127
|
+
| Helper | Purpose |
|
|
128
|
+
|------------------------------------|----------------------------------------------------------------------------------------------------------------------|
|
|
129
|
+
| `typeIntoEditor({ editor, text })` | Focuses `editor` (caret to end), types `text` as trusted key events, then polls until the document reflects it. |
|
|
130
|
+
| `hoverElement({ element })` | Moves the pointer to `element`'s center, then polls until `element.matches(':hover')`. |
|
|
131
|
+
| `unhoverElement({ element })` | Moves the pointer just outside `element`'s bounding box, then polls until it no longer matches `:hover`. |
|
|
132
|
+
| `moveMouse({ x, y })` | Low-level primitive: injects one trusted pointer move at the given web-contents DIP coordinates (does **not** poll). |
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
// Type into the active editor — only succeeds if the editor truly holds focus.
|
|
136
|
+
const typed = await evalInObsidian({
|
|
137
|
+
fn: async ({ app, obsidianModule, typeIntoEditor }) => {
|
|
138
|
+
const view = app.workspace.getActiveViewOfType(obsidianModule.MarkdownView);
|
|
139
|
+
const editor = view?.editor;
|
|
140
|
+
if (!editor) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
await typeIntoEditor({ editor, text: 'Hello, world!' });
|
|
145
|
+
return editor.getValue();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Observe a genuine :hover state (real theme var() values, real compositing).
|
|
150
|
+
await evalInObsidian({
|
|
151
|
+
fn: async ({ hoverElement, unhoverElement }) => {
|
|
152
|
+
const bar = document.querySelector<HTMLElement>('.minimized-modal-bar');
|
|
153
|
+
if (!bar) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
await hoverElement({ element: bar });
|
|
158
|
+
// ...assert the hovered appearance...
|
|
159
|
+
await unhoverElement({ element: bar });
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
> **Serialize focus/pointer-dependent test files.** Trusted input targets the single shared
|
|
165
|
+
> window's **global** focus and pointer, so test files that depend on either must not run in
|
|
166
|
+
> parallel against the one shared Obsidian instance (they race for focus, and a
|
|
167
|
+
> `detachLeavesOfType('markdown')` in one file wipes another's editor). Run your
|
|
168
|
+
> obsidian-integration Vitest project serially — `fileParallelism: false` and `maxWorkers: 1`.
|
|
169
|
+
|
|
112
170
|
### Pass complex arguments
|
|
113
171
|
|
|
114
172
|
Arguments are JSON-serialized. You can even pass functions — they are serialized via `toString()`:
|
|
@@ -636,6 +694,45 @@ npx vitest run --project integration-tests:android-appium
|
|
|
636
694
|
npx vitest run --project integration-tests:*
|
|
637
695
|
```
|
|
638
696
|
|
|
697
|
+
## Ad-hoc debugging (`connectToCdp` and the CLI)
|
|
698
|
+
|
|
699
|
+
Outside of a test framework, `connectToCdp()` launches (or attaches to) a `CDP` Obsidian instance, opens a vault, bootstraps the runtime helpers, and returns a disposable connection — handy for reproducing behavior in a real Obsidian from a throwaway script or the REPL.
|
|
700
|
+
|
|
701
|
+
```ts
|
|
702
|
+
import { connectToCdp } from 'obsidian-integration-testing';
|
|
703
|
+
|
|
704
|
+
// Owns an isolated instance + an empty temp vault (both cleaned up on dispose).
|
|
705
|
+
await using conn = await connectToCdp();
|
|
706
|
+
|
|
707
|
+
console.log(conn.port, conn.cdpUrl); // the free CDP port the instance was launched on
|
|
708
|
+
|
|
709
|
+
// Raw expression → normalized string result:
|
|
710
|
+
await conn.invoke('app.vault.getName()');
|
|
711
|
+
|
|
712
|
+
// Rich, typed path — `fn` runs in the Obsidian renderer with { app, obsidianModule, typeIntoEditor, context }:
|
|
713
|
+
await conn.evalInObsidian({ fn: ({ app }) => app.workspace.getActiveFile()?.path ?? null });
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
`connectToCdp` accepts the same version knobs as the transport (`obsidianVersion`, `obsidianInstallerVersion`, `host`, `commandTimeoutInMilliseconds`, both defaulting to your installed Obsidian), plus:
|
|
717
|
+
|
|
718
|
+
- **`vault`** — path to an existing vault to open. When omitted, an empty temporary vault is created.
|
|
719
|
+
- **`port`** — attach to an already-running Obsidian on this `CDP` port instead of owning an instance (as in [Attaching to a running Obsidian](#attaching-to-a-running-obsidian)).
|
|
720
|
+
- **`shouldRemoveVaultOnDispose`** — whether `dispose()` removes the vault directory. Defaults to `true` for an implicit temp vault and `false` when a `vault` path is given, so a **real vault is never auto-deleted**. Set it explicitly to override.
|
|
721
|
+
|
|
722
|
+
> [!WARNING]
|
|
723
|
+
>
|
|
724
|
+
> Opening a **real** vault in the owned instance may write to that vault's `.obsidian` config (normal Obsidian behavior). The vault directory itself is never deleted unless `shouldRemoveVaultOnDispose` is `true`.
|
|
725
|
+
|
|
726
|
+
### CLI
|
|
727
|
+
|
|
728
|
+
The package ships an `obsidian-integration-testing` bin that wraps `connectToCdp`, prints the chosen port/URL, and stays alive until `Ctrl+C` — useful when an external tool (raw `CDP` `ws`, DevTools) needs to attach to a printed port:
|
|
729
|
+
|
|
730
|
+
```bash
|
|
731
|
+
npx obsidian-integration-testing --vault F:/path/to/vault --obsidian-version 1.8.10
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
Flags mirror the options above: `--vault`, `--obsidian-version`, `--obsidian-installer-version`, `--port`, `--host`, `--command-timeout`, and `--no-remove-vault` (keep the temp vault on exit).
|
|
735
|
+
|
|
639
736
|
## Support
|
|
640
737
|
|
|
641
738
|
<!-- markdownlint-disable MD033 -->
|
|
@@ -0,0 +1,95 @@
|
|
|
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 cli_exports = {};
|
|
30
|
+
__export(cli_exports, {
|
|
31
|
+
main: () => main
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(cli_exports);
|
|
34
|
+
var import_node_process = __toESM(require("node:process"), 1);
|
|
35
|
+
var import_node_util = require("node:util");
|
|
36
|
+
var import_connect_to_cdp = require("./connect-to-cdp.cjs");
|
|
37
|
+
async function main() {
|
|
38
|
+
const { values } = (0, import_node_util.parseArgs)({
|
|
39
|
+
options: {
|
|
40
|
+
"command-timeout": { type: "string" },
|
|
41
|
+
"host": { type: "string" },
|
|
42
|
+
"no-remove-vault": { type: "boolean" },
|
|
43
|
+
"obsidian-installer-version": { type: "string" },
|
|
44
|
+
"obsidian-version": { type: "string" },
|
|
45
|
+
"port": { type: "string" },
|
|
46
|
+
"vault": { type: "string" }
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
const connection = await (0, import_connect_to_cdp.connectToCdp)(buildOptions(values));
|
|
50
|
+
import_node_process.default.stdout.write(
|
|
51
|
+
`Obsidian CDP ready.
|
|
52
|
+
port: ${String(connection.port)}
|
|
53
|
+
cdpUrl: ${connection.cdpUrl}
|
|
54
|
+
vault: ${connection.vault.path}
|
|
55
|
+
Runtime helpers bootstrapped as window.__obsidianIntegrationTesting.
|
|
56
|
+
Press Ctrl+C to stop.
|
|
57
|
+
`
|
|
58
|
+
);
|
|
59
|
+
await waitForShutdownSignal();
|
|
60
|
+
import_node_process.default.stdout.write("\nShutting down\u2026\n");
|
|
61
|
+
await connection.dispose();
|
|
62
|
+
}
|
|
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 Error(`--${flag} must be a number, got: ${raw}`);
|
|
78
|
+
}
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
function waitForShutdownSignal() {
|
|
82
|
+
return new Promise((resolve) => {
|
|
83
|
+
import_node_process.default.once("SIGINT", () => {
|
|
84
|
+
resolve();
|
|
85
|
+
});
|
|
86
|
+
import_node_process.default.once("SIGTERM", () => {
|
|
87
|
+
resolve();
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
92
|
+
0 && (module.exports = {
|
|
93
|
+
main
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NsaS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFRoaW4gQ0xJIG92ZXIge0BsaW5rIGNvbm5lY3RUb0NkcH06IGxhdW5jaGVzIChvciBhdHRhY2hlcyB0bykgYSBDRFAtZW5hYmxlZFxuICogT2JzaWRpYW4gaW5zdGFuY2Ugd2l0aCB0aGUgcnVudGltZSBoZWxwZXIgbmFtZXNwYWNlIGJvb3RzdHJhcHBlZCwgcHJpbnRzIHRoZVxuICogY2hvc2VuIENEUCBwb3J0L1VSTCwgYW5kIHN0YXlzIGFsaXZlIHVudGlsIGludGVycnVwdGVkIHNvIGFuIGV4dGVybmFsIHRvb2xcbiAqIChyYXcgQ0RQIGB3c2AsIERldlRvb2xzLCBcdTIwMjYpIGNhbiBhdHRhY2guXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgQ0xJIChsYXVuY2hlcyBPYnNpZGlhbiAvIENEUCkgY292ZXJlZCBtYW51YWxseSwgbm90IGJ5IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5pbXBvcnQgeyBwYXJzZUFyZ3MgfSBmcm9tICdub2RlOnV0aWwnO1xuXG5pbXBvcnQgdHlwZSB7IENvbm5lY3RUb0NkcE9wdGlvbnMgfSBmcm9tICcuL2Nvbm5lY3QtdG8tY2RwLmNqcyc7XG5cbmltcG9ydCB7IGNvbm5lY3RUb0NkcCB9IGZyb20gJy4vY29ubmVjdC10by1jZHAuY2pzJztcblxuLyoqXG4gKiBUaGUgc2hhcGUgb2YgdGhlIHBhcnNlZCBDTEkgZmxhZyB2YWx1ZXMuXG4gKi9cbmludGVyZmFjZSBQYXJzZWRDbGlWYWx1ZXMge1xuICAnY29tbWFuZC10aW1lb3V0Jz86IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgJ2hvc3QnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAnbm8tcmVtb3ZlLXZhdWx0Jz86IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gICdvYnNpZGlhbi1pbnN0YWxsZXItdmVyc2lvbic/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICdvYnNpZGlhbi12ZXJzaW9uJz86IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgJ3BvcnQnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAndmF1bHQnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFBhcnNlcyBDTEkgYXJndW1lbnRzLCBvcGVucyB0aGUgY29ubmVjdGlvbiwgcHJpbnRzIGl0cyBlbmRwb2ludCwgYW5kIGJsb2Nrc1xuICogdW50aWwgYFNJR0lOVGAvYFNJR1RFUk1gLCBkaXNwb3NpbmcgdGhlIGNvbm5lY3Rpb24gb24gc2h1dGRvd24uXG4gKlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBjb25uZWN0aW9uIGhhcyBiZWVuIGRpc3Bvc2VkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWFpbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyB2YWx1ZXMgfSA9IHBhcnNlQXJncyh7XG4gICAgb3B0aW9uczoge1xuICAgICAgJ2NvbW1hbmQtdGltZW91dCc6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICdob3N0JzogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgJ25vLXJlbW92ZS12YXVsdCc6IHsgdHlwZTogJ2Jvb2xlYW4nIH0sXG4gICAgICAnb2JzaWRpYW4taW5zdGFsbGVyLXZlcnNpb24nOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAnb2JzaWRpYW4tdmVyc2lvbic6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICdwb3J0JzogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgJ3ZhdWx0JzogeyB0eXBlOiAnc3RyaW5nJyB9XG4gICAgfVxuICB9KTtcblxuICBjb25zdCBjb25uZWN0aW9uID0gYXdhaXQgY29ubmVjdFRvQ2RwKGJ1aWxkT3B0aW9ucyh2YWx1ZXMpKTtcblxuICBwcm9jZXNzLnN0ZG91dC53cml0ZShcbiAgICAnT2JzaWRpYW4gQ0RQIHJlYWR5LlxcbidcbiAgICAgICsgYCAgcG9ydDogICAke1N0cmluZyhjb25uZWN0aW9uLnBvcnQpfVxcbmBcbiAgICAgICsgYCAgY2RwVXJsOiAke2Nvbm5lY3Rpb24uY2RwVXJsfVxcbmBcbiAgICAgICsgYCAgdmF1bHQ6ICAke2Nvbm5lY3Rpb24udmF1bHQucGF0aH1cXG5gXG4gICAgICArICdSdW50aW1lIGhlbHBlcnMgYm9vdHN0cmFwcGVkIGFzIHdpbmRvdy5fX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nLlxcbidcbiAgICAgICsgJ1ByZXNzIEN0cmwrQyB0byBzdG9wLlxcbidcbiAgKTtcblxuICBhd2FpdCB3YWl0Rm9yU2h1dGRvd25TaWduYWwoKTtcblxuICBwcm9jZXNzLnN0ZG91dC53cml0ZSgnXFxuU2h1dHRpbmcgZG93blx1MjAyNlxcbicpO1xuICBhd2FpdCBjb25uZWN0aW9uLmRpc3Bvc2UoKTtcbn1cblxuLyoqXG4gKiBCdWlsZHMge0BsaW5rIENvbm5lY3RUb0NkcE9wdGlvbnN9IGZyb20gcGFyc2VkIENMSSBmbGFnIHZhbHVlcy5cbiAqXG4gKiBAcGFyYW0gdmFsdWVzIC0gVGhlIHBhcnNlZCBgcGFyc2VBcmdzYCB2YWx1ZXMuXG4gKiBAcmV0dXJucyBUaGUgY29ubmVjdGlvbiBvcHRpb25zLlxuICovXG5mdW5jdGlvbiBidWlsZE9wdGlvbnModmFsdWVzOiBQYXJzZWRDbGlWYWx1ZXMpOiBDb25uZWN0VG9DZHBPcHRpb25zIHtcbiAgcmV0dXJuIHtcbiAgICAuLi4odmFsdWVzWydjb21tYW5kLXRpbWVvdXQnXSAhPT0gdW5kZWZpbmVkICYmIHsgY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kczogcGFyc2VOdW1iZXIoJ2NvbW1hbmQtdGltZW91dCcsIHZhbHVlc1snY29tbWFuZC10aW1lb3V0J10pIH0pLFxuICAgIC4uLih2YWx1ZXMuaG9zdCAhPT0gdW5kZWZpbmVkICYmIHsgaG9zdDogdmFsdWVzLmhvc3QgfSksXG4gICAgLi4uKHZhbHVlc1snbm8tcmVtb3ZlLXZhdWx0J10gPT09IHRydWUgJiYgeyBzaG91bGRSZW1vdmVWYXVsdE9uRGlzcG9zZTogZmFsc2UgfSksXG4gICAgLi4uKHZhbHVlc1snb2JzaWRpYW4taW5zdGFsbGVyLXZlcnNpb24nXSAhPT0gdW5kZWZpbmVkICYmIHsgb2JzaWRpYW5JbnN0YWxsZXJWZXJzaW9uOiB2YWx1ZXNbJ29ic2lkaWFuLWluc3RhbGxlci12ZXJzaW9uJ10gfSksXG4gICAgLi4uKHZhbHVlc1snb2JzaWRpYW4tdmVyc2lvbiddICE9PSB1bmRlZmluZWQgJiYgeyBvYnNpZGlhblZlcnNpb246IHZhbHVlc1snb2JzaWRpYW4tdmVyc2lvbiddIH0pLFxuICAgIC4uLih2YWx1ZXMucG9ydCAhPT0gdW5kZWZpbmVkICYmIHsgcG9ydDogcGFyc2VOdW1iZXIoJ3BvcnQnLCB2YWx1ZXMucG9ydCkgfSksXG4gICAgLi4uKHZhbHVlcy52YXVsdCAhPT0gdW5kZWZpbmVkICYmIHsgdmF1bHQ6IHZhbHVlcy52YXVsdCB9KVxuICB9O1xufVxuXG4vKipcbiAqIFBhcnNlcyBhIG51bWVyaWMgQ0xJIGZsYWcgdmFsdWUsIHRocm93aW5nIG9uIGEgbm9uLWZpbml0ZSByZXN1bHQuXG4gKlxuICogQHBhcmFtIGZsYWcgLSBUaGUgZmxhZyBuYW1lIChmb3IgdGhlIGVycm9yIG1lc3NhZ2UpLlxuICogQHBhcmFtIHJhdyAtIFRoZSByYXcgc3RyaW5nIHZhbHVlLlxuICogQHJldHVybnMgVGhlIHBhcnNlZCBudW1iZXIuXG4gKiBAdGhyb3dzIEVycm9yIGlmIGByYXdgIGlzIG5vdCBhIGZpbml0ZSBudW1iZXIuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlTnVtYmVyKGZsYWc6IHN0cmluZywgcmF3OiBzdHJpbmcpOiBudW1iZXIge1xuICBjb25zdCB2YWx1ZSA9IE51bWJlcihyYXcpO1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYC0tJHtmbGFnfSBtdXN0IGJlIGEgbnVtYmVyLCBnb3Q6ICR7cmF3fWApO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBvbmNlIHRoZSBwcm9jZXNzIHJlY2VpdmVzIGBTSUdJTlRgIG9yIGBTSUdURVJNYC5cbiAqXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uIHRoZSBmaXJzdCBzaHV0ZG93biBzaWduYWwuXG4gKi9cbmZ1bmN0aW9uIHdhaXRGb3JTaHV0ZG93blNpZ25hbCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgcHJvY2Vzcy5vbmNlKCdTSUdJTlQnLCAoKSA9PiB7XG4gICAgICByZXNvbHZlKCk7XG4gICAgfSk7XG4gICAgcHJvY2Vzcy5vbmNlKCdTSUdURVJNJywgKCkgPT4ge1xuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBV0EsMEJBQW9CO0FBQ3BCLHVCQUEwQjtBQUkxQiw0QkFBNkI7QUFxQjdCLGVBQXNCLE9BQXNCO0FBQzFDLFFBQU0sRUFBRSxPQUFPLFFBQUksNEJBQVU7QUFBQSxJQUMzQixTQUFTO0FBQUEsTUFDUCxtQkFBbUIsRUFBRSxNQUFNLFNBQVM7QUFBQSxNQUNwQyxRQUFRLEVBQUUsTUFBTSxTQUFTO0FBQUEsTUFDekIsbUJBQW1CLEVBQUUsTUFBTSxVQUFVO0FBQUEsTUFDckMsOEJBQThCLEVBQUUsTUFBTSxTQUFTO0FBQUEsTUFDL0Msb0JBQW9CLEVBQUUsTUFBTSxTQUFTO0FBQUEsTUFDckMsUUFBUSxFQUFFLE1BQU0sU0FBUztBQUFBLE1BQ3pCLFNBQVMsRUFBRSxNQUFNLFNBQVM7QUFBQSxJQUM1QjtBQUFBLEVBQ0YsQ0FBQztBQUVELFFBQU0sYUFBYSxVQUFNLG9DQUFhLGFBQWEsTUFBTSxDQUFDO0FBRTFELHNCQUFBQSxRQUFRLE9BQU87QUFBQSxJQUNiO0FBQUEsWUFDaUIsT0FBTyxXQUFXLElBQUksQ0FBQztBQUFBLFlBQ3ZCLFdBQVcsTUFBTTtBQUFBLFlBQ2pCLFdBQVcsTUFBTSxJQUFJO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFHeEM7QUFFQSxRQUFNLHNCQUFzQjtBQUU1QixzQkFBQUEsUUFBUSxPQUFPLE1BQU0seUJBQW9CO0FBQ3pDLFFBQU0sV0FBVyxRQUFRO0FBQzNCO0FBUUEsU0FBUyxhQUFhLFFBQThDO0FBQ2xFLFNBQU87QUFBQSxJQUNMLEdBQUksT0FBTyxpQkFBaUIsTUFBTSxVQUFhLEVBQUUsOEJBQThCLFlBQVksbUJBQW1CLE9BQU8saUJBQWlCLENBQUMsRUFBRTtBQUFBLElBQ3pJLEdBQUksT0FBTyxTQUFTLFVBQWEsRUFBRSxNQUFNLE9BQU8sS0FBSztBQUFBLElBQ3JELEdBQUksT0FBTyxpQkFBaUIsTUFBTSxRQUFRLEVBQUUsNEJBQTRCLE1BQU07QUFBQSxJQUM5RSxHQUFJLE9BQU8sNEJBQTRCLE1BQU0sVUFBYSxFQUFFLDBCQUEwQixPQUFPLDRCQUE0QixFQUFFO0FBQUEsSUFDM0gsR0FBSSxPQUFPLGtCQUFrQixNQUFNLFVBQWEsRUFBRSxpQkFBaUIsT0FBTyxrQkFBa0IsRUFBRTtBQUFBLElBQzlGLEdBQUksT0FBTyxTQUFTLFVBQWEsRUFBRSxNQUFNLFlBQVksUUFBUSxPQUFPLElBQUksRUFBRTtBQUFBLElBQzFFLEdBQUksT0FBTyxVQUFVLFVBQWEsRUFBRSxPQUFPLE9BQU8sTUFBTTtBQUFBLEVBQzFEO0FBQ0Y7QUFVQSxTQUFTLFlBQVksTUFBYyxLQUFxQjtBQUN0RCxRQUFNLFFBQVEsT0FBTyxHQUFHO0FBQ3hCLE1BQUksQ0FBQyxPQUFPLFNBQVMsS0FBSyxHQUFHO0FBQzNCLFVBQU0sSUFBSSxNQUFNLEtBQUssSUFBSSwyQkFBMkIsR0FBRyxFQUFFO0FBQUEsRUFDM0Q7QUFDQSxTQUFPO0FBQ1Q7QUFPQSxTQUFTLHdCQUF1QztBQUM5QyxTQUFPLElBQUksUUFBYyxDQUFDLFlBQVk7QUFDcEMsd0JBQUFBLFFBQVEsS0FBSyxVQUFVLE1BQU07QUFDM0IsY0FBUTtBQUFBLElBQ1YsQ0FBQztBQUNELHdCQUFBQSxRQUFRLEtBQUssV0FBVyxNQUFNO0FBQzVCLGNBQVE7QUFBQSxJQUNWLENBQUM7QUFBQSxFQUNILENBQUM7QUFDSDsiLAogICJuYW1lcyI6IFsicHJvY2VzcyJdCn0K
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file
|
|
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.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Parses CLI arguments, opens the connection, prints its endpoint, and blocks
|
|
11
|
+
* until `SIGINT`/`SIGTERM`, disposing the connection on shutdown.
|
|
12
|
+
*
|
|
13
|
+
* @returns A {@link Promise} that resolves once the connection has been disposed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function main(): Promise<void>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var connect_to_cdp_exports = {};
|
|
20
|
+
__export(connect_to_cdp_exports, {
|
|
21
|
+
connectToCdp: () => connectToCdp
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(connect_to_cdp_exports);
|
|
24
|
+
var import_eval_in_obsidian = require("./eval-in-obsidian.cjs");
|
|
25
|
+
var import_temp_vault = require("./temp-vault.cjs");
|
|
26
|
+
var import_transport_desktop_cdp = require("./transport-desktop-cdp.cjs");
|
|
27
|
+
var import_transport_factory = require("./transport-factory.cjs");
|
|
28
|
+
const DEFAULT_CDP_HOST = "localhost";
|
|
29
|
+
async function connectToCdp(options) {
|
|
30
|
+
const transportOptions = {
|
|
31
|
+
type: "obsidian-cdp",
|
|
32
|
+
...options?.commandTimeoutInMilliseconds !== void 0 && { commandTimeoutInMilliseconds: options.commandTimeoutInMilliseconds },
|
|
33
|
+
...options?.host !== void 0 && { host: options.host },
|
|
34
|
+
...options?.obsidianInstallerVersion !== void 0 && { obsidianInstallerVersion: options.obsidianInstallerVersion },
|
|
35
|
+
...options?.obsidianVersion !== void 0 && { obsidianVersion: options.obsidianVersion },
|
|
36
|
+
...options?.port !== void 0 && { port: options.port }
|
|
37
|
+
};
|
|
38
|
+
const transport = await (0, import_transport_factory.createTransportFromOptions)(transportOptions);
|
|
39
|
+
const vault = new import_temp_vault.TempVault(options?.vault);
|
|
40
|
+
const shouldRemoveVaultOnDispose = options?.shouldRemoveVaultOnDispose ?? options?.vault === void 0;
|
|
41
|
+
await vault.register(transport);
|
|
42
|
+
const { host, port } = resolveEndpoint(transport, options);
|
|
43
|
+
const cdpUrl = `http://${host}:${String(port)}`;
|
|
44
|
+
const connection = {
|
|
45
|
+
cdpUrl,
|
|
46
|
+
async dispose() {
|
|
47
|
+
try {
|
|
48
|
+
if (shouldRemoveVaultOnDispose) {
|
|
49
|
+
await vault.dispose(transport);
|
|
50
|
+
} else {
|
|
51
|
+
await transport.unregisterVault(vault.path);
|
|
52
|
+
}
|
|
53
|
+
} finally {
|
|
54
|
+
await transport.dispose?.();
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
async evalInObsidian(params) {
|
|
58
|
+
return (0, import_eval_in_obsidian.evalInObsidian)({ ...params, transport, vaultPath: vault.path });
|
|
59
|
+
},
|
|
60
|
+
async invoke(expression) {
|
|
61
|
+
return transport.evaluate(expression, { cwd: vault.path });
|
|
62
|
+
},
|
|
63
|
+
port,
|
|
64
|
+
async [Symbol.asyncDispose]() {
|
|
65
|
+
await connection.dispose();
|
|
66
|
+
},
|
|
67
|
+
vault
|
|
68
|
+
};
|
|
69
|
+
return connection;
|
|
70
|
+
}
|
|
71
|
+
function resolveEndpoint(transport, options) {
|
|
72
|
+
if (transport instanceof import_transport_desktop_cdp.DesktopCdpTransport) {
|
|
73
|
+
const endpoint = transport.getOwnedInstanceEndpoint();
|
|
74
|
+
if (endpoint) {
|
|
75
|
+
return { host: endpoint.host, port: endpoint.port };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (options?.port !== void 0) {
|
|
79
|
+
return { host: options.host ?? DEFAULT_CDP_HOST, port: options.port };
|
|
80
|
+
}
|
|
81
|
+
throw new Error("connectToCdp: could not determine the CDP port.");
|
|
82
|
+
}
|
|
83
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
84
|
+
0 && (module.exports = {
|
|
85
|
+
connectToCdp
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2Nvbm5lY3QtdG8tY2RwLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogUHJvZ3JhbW1hdGljIGhlbHBlciB0byBsYXVuY2ggKG9yIGF0dGFjaCB0bykgYSBDRFAtZW5hYmxlZCBPYnNpZGlhbiBpbnN0YW5jZVxuICogd2l0aCB0aGUgcnVudGltZSBoZWxwZXIgbmFtZXNwYWNlIGJvb3RzdHJhcHBlZCwgZm9yIGFkLWhvYyByZWFsLWFwcCBkZWJ1Z2dpbmcuXG4gKlxuICogQSBzaW5nbGUge0BsaW5rIGNvbm5lY3RUb0NkcH0gY2FsbCByZXNvbHZlcyB0aGUgb3duZWQtaW5zdGFuY2UgY29uZmlnLCBvcGVucyBhXG4gKiB2YXVsdCwgYW5kIGJvb3RzdHJhcHMgYHdpbmRvdy5fX29ic2lkaWFuSW50ZWdyYXRpb25UZXN0aW5nYCAoc28gYGV2YWxXcmFwcGVyYCxcbiAqIGB0eXBlSW50b0VkaXRvcmAsIGBzZXJpYWxpemVFcnJvcmAsIGBnZXRPYnNpZGlhbk1vZHVsZWAsIFx1MjAyNiBhcmUgYXZhaWxhYmxlKSwgdGhlblxuICogaGFuZHMgYmFjayBhIGRpc3Bvc2FibGUge0BsaW5rIENkcENvbm5lY3Rpb259IGV4cG9zaW5nIHRoZSBjaG9zZW4gQ0RQIHBvcnQsIGFcbiAqIHJhdyB7QGxpbmsgQ2RwQ29ubmVjdGlvbi5pbnZva2V9IGFuZCB0aGUgcmljaCB7QGxpbmsgQ2RwQ29ubmVjdGlvbi5ldmFsSW5PYnNpZGlhbn0uXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgY29kZSAobGF1bmNoZXMgT2JzaWRpYW4gLyBDRFApIGNvdmVyZWQgYnkgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCB1bml0IHRlc3RzLiAqL1xuXG5pbXBvcnQgdHlwZSB7IEV4Y2VwdCB9IGZyb20gJ3R5cGUtZmVzdCc7XG5cbmltcG9ydCB0eXBlIHsgQ29udGV4dElkIH0gZnJvbSAnLi9jb250ZXh0LWlkLmNqcyc7XG5pbXBvcnQgdHlwZSB7XG4gIEV2YWxJbk9ic2lkaWFuUGFyYW1zLFxuICBHZW5lcmljT2JqZWN0XG59IGZyb20gJy4vZXZhbC1pbi1vYnNpZGlhbi5janMnO1xuaW1wb3J0IHR5cGUgeyBPYnNpZGlhbkNkcFRyYW5zcG9ydE9wdGlvbnMgfSBmcm9tICcuL3RyYW5zcG9ydC1vcHRpb25zLmNqcyc7XG5cbmltcG9ydCB7IGV2YWxJbk9ic2lkaWFuIH0gZnJvbSAnLi9ldmFsLWluLW9ic2lkaWFuLmNqcyc7XG5pbXBvcnQgeyBUZW1wVmF1bHQgfSBmcm9tICcuL3RlbXAtdmF1bHQuY2pzJztcbmltcG9ydCB7IERlc2t0b3BDZHBUcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC1kZXNrdG9wLWNkcC5janMnO1xuaW1wb3J0IHsgY3JlYXRlVHJhbnNwb3J0RnJvbU9wdGlvbnMgfSBmcm9tICcuL3RyYW5zcG9ydC1mYWN0b3J5LmNqcyc7XG5cbmNvbnN0IERFRkFVTFRfQ0RQX0hPU1QgPSAnbG9jYWxob3N0JztcblxuLyoqXG4gKiBBIGxpdmUgY29ubmVjdGlvbiB0byBhIENEUC1lbmFibGVkIE9ic2lkaWFuIGluc3RhbmNlIHdpdGggdGhlIHJ1bnRpbWUgaGVscGVyXG4gKiBuYW1lc3BhY2UgYm9vdHN0cmFwcGVkLlxuICpcbiAqIEltcGxlbWVudHMgYEFzeW5jRGlzcG9zYWJsZWAsIHNvIGBhd2FpdCB1c2luZyBjb25uID0gYXdhaXQgY29ubmVjdFRvQ2RwKFx1MjAyNilgXG4gKiBkaXNwb3NlcyBpdCAoa2lsbGluZyBhbiBvd25lZCBpbnN0YW5jZSBhbmQgXHUyMDE0IGZvciBhIHRocm93LWF3YXkgdGVtcCB2YXVsdCBcdTIwMTRcbiAqIHJlbW92aW5nIGl0cyBkaXJlY3RvcnkpIGF1dG9tYXRpY2FsbHkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2RwQ29ubmVjdGlvbiBleHRlbmRzIEFzeW5jRGlzcG9zYWJsZSB7XG4gIC8qKlxuICAgKiBUaGUgYmFzZSBDRFAgVVJMLCBlLmcuIGBodHRwOi8vbG9jYWxob3N0OjUxODg4YC5cbiAgICovXG4gIHJlYWRvbmx5IGNkcFVybDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBEaXNwb3NlcyB0aGUgY29ubmVjdGlvbjoga2lsbHMgYW4gb3duZWQgaW5zdGFuY2UgYW5kIHJlbW92ZXMgaXRzIGlzb2xhdGVkXG4gICAqIHVzZXItZGF0YSBkaXIuIFRoZSB2YXVsdCBkaXJlY3RvcnkgaXMgcmVtb3ZlZCBvbmx5IHdoZW4gaXQgaXMgYSB0aHJvdy1hd2F5XG4gICAqIHRlbXAgdmF1bHQgKHNlZSB7QGxpbmsgQ29ubmVjdFRvQ2RwT3B0aW9ucy5zaG91bGRSZW1vdmVWYXVsdE9uRGlzcG9zZX0pOyBhXG4gICAqIHJlYWwgdmF1bHQgcGFzc2VkIHZpYSB7QGxpbmsgQ29ubmVjdFRvQ2RwT3B0aW9ucy52YXVsdH0gaXMgbmV2ZXIgZGVsZXRlZC5cbiAgICpcbiAgICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIGRpc3Bvc2FsIGNvbXBsZXRlcy5cbiAgICovXG4gIGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPjtcblxuICAvKipcbiAgICogRXZhbHVhdGVzIGEgc2VsZi1jb250YWluZWQgZnVuY3Rpb24gaW5zaWRlIE9ic2lkaWFuIHZpYSB0aGUgcmljaCBoZWxwZXJcbiAgICogcGF0aCwgcmVjZWl2aW5nIGB7IGFwcCwgb2JzaWRpYW5Nb2R1bGUsIHR5cGVJbnRvRWRpdG9yLCBjb250ZXh0IH1gIHBsdXMgYW55XG4gICAqIGBhcmdzYC4gTWlycm9ycyB0aGUgdG9wLWxldmVsIGBldmFsSW5PYnNpZGlhbmAsIHdpdGggdGhlIHRyYW5zcG9ydCBhbmQgdmF1bHRcbiAgICogcGF0aCBwcmUtYm91bmQgdG8gdGhpcyBjb25uZWN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGV2YWx1YXRpb24gcGFyYW1ldGVycyAoYGZuYCwgb3B0aW9uYWwgYGFyZ3NgL2Bjb250ZXh0SWRgKS5cbiAgICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB0byB0aGUgcmV0dXJuIHZhbHVlIG9mIGBmbmAuXG4gICAqL1xuICBldmFsSW5PYnNpZGlhbjxBcmdzIGV4dGVuZHMgR2VuZXJpY09iamVjdCwgUmVzdWx0LCBUQ29udGV4dElkIGV4dGVuZHMgQ29udGV4dElkPHVua25vd24+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkPihcbiAgICBwYXJhbXM6IEV4Y2VwdDxFdmFsSW5PYnNpZGlhblBhcmFtczxBcmdzLCBSZXN1bHQsIFRDb250ZXh0SWQ+LCAndHJhbnNwb3J0JyB8ICd2YXVsdFBhdGgnPlxuICApOiBQcm9taXNlPFJlc3VsdD47XG5cbiAgLyoqXG4gICAqIEV2YWx1YXRlcyBhIHJhdyBKYXZhU2NyaXB0IGV4cHJlc3Npb24gaW5zaWRlIE9ic2lkaWFuIGFuZCByZXR1cm5zIHRoZVxuICAgKiBub3JtYWxpemVkIHN0cmluZyByZXN1bHQgKGUuZy4gYCc1J2AsIGEgSlNPTiBzdHJpbmcsIG9yIGAnKG5vIG91dHB1dCknYCkuXG4gICAqXG4gICAqIEBwYXJhbSBleHByZXNzaW9uIC0gQSBzZWxmLWNvbnRhaW5lZCBKYXZhU2NyaXB0IGV4cHJlc3Npb24uXG4gICAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHJhdyByZXN1bHQgc3RyaW5nLlxuICAgKi9cbiAgaW52b2tlKGV4cHJlc3Npb246IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPjtcblxuICAvKipcbiAgICogVGhlIENEUCBwb3J0IHRoZSBpbnN0YW5jZSBpcyByZWFjaGFibGUgb24gKHRoZSBmcmVlIHBvcnQgY2hvc2VuIGZvciBhblxuICAgKiBvd25lZCBpbnN0YW5jZSwgb3IgdGhlIGF0dGFjaGVkIHtAbGluayBDb25uZWN0VG9DZHBPcHRpb25zLnBvcnR9KS5cbiAgICovXG4gIHJlYWRvbmx5IHBvcnQ6IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIG9wZW5lZCB2YXVsdC4gRXhwb3NlcyBgcGF0aGAgYW5kIGBwb3B1bGF0ZSguLi4pYCBmb3Igc2VlZGluZyBmaWxlcy5cbiAgICovXG4gIHJlYWRvbmx5IHZhdWx0OiBUZW1wVmF1bHQ7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3Ige0BsaW5rIGNvbm5lY3RUb0NkcH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29ubmVjdFRvQ2RwT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaW1lb3V0IGluIG1pbGxpc2Vjb25kcyBmb3IgaW5kaXZpZHVhbCBDRFAgY29tbWFuZHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IGAzMDAwMGBcbiAgICovXG4gIHJlYWRvbmx5IGNvbW1hbmRUaW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIENEUCBob3N0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgJ2xvY2FsaG9zdCdgXG4gICAqL1xuICByZWFkb25seSBob3N0Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQaW5zIHRoZSBFbGVjdHJvbiBzaGVsbCAoaW5zdGFsbGVyIGJ1aWxkKSB0aGUgb3duZWQgaW5zdGFuY2UgcnVucy4gQWNjZXB0c1xuICAgKiBgJ3gueS56J2AsIGAncHVibGljLWxhdGVzdCdgLCBvciBgJ2NhdGFseXN0LWxhdGVzdCdgLiBJZ25vcmVkIHdoZW5cbiAgICoge0BsaW5rIHBvcnR9IChhdHRhY2ggbW9kZSkgaXMgc2V0LiBXaGVuIG9taXR0ZWQsIHRoZSBpbnN0YWxsZWQgc2hlbGwgaXMgdXNlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgYHVuZGVmaW5lZGBcbiAgICovXG4gIHJlYWRvbmx5IG9ic2lkaWFuSW5zdGFsbGVyVmVyc2lvbj86IHN0cmluZztcblxuICAvKipcbiAgICogUGlucyB0aGUgT2JzaWRpYW4gYXBwIHZlcnNpb24gKGFzYXIpIHRoZSBvd25lZCBpbnN0YW5jZSBydW5zLiBBY2NlcHRzXG4gICAqIGAneC55LnonYCwgYCdwdWJsaWMtbGF0ZXN0J2AsIG9yIGAnY2F0YWx5c3QtbGF0ZXN0J2AuIElnbm9yZWQgd2hlblxuICAgKiB7QGxpbmsgcG9ydH0gKGF0dGFjaCBtb2RlKSBpcyBzZXQuIFdoZW4gb21pdHRlZCwgdGhlIGluc3RhbGxlZCB2ZXJzaW9uIGlzIHVzZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB1bmRlZmluZWRgXG4gICAqL1xuICByZWFkb25seSBvYnNpZGlhblZlcnNpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENEUCBwb3J0IG9mIGFuIGFscmVhZHktcnVubmluZyBPYnNpZGlhbiB0byAqKmF0dGFjaCoqIHRvLiBXaGVuIG9taXR0ZWQsIGFuXG4gICAqIGlzb2xhdGVkIGluc3RhbmNlIGlzIGxhdW5jaGVkIG9uIGFuIGF1dG9tYXRpY2FsbHkgY2hvc2VuIGZyZWUgcG9ydC5cbiAgICpcbiAgICogQGRlZmF1bHQgYHVuZGVmaW5lZGBcbiAgICovXG4gIHJlYWRvbmx5IHBvcnQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gcmVtb3ZlIHRoZSB2YXVsdCBkaXJlY3Rvcnkgb24ge0BsaW5rIENkcENvbm5lY3Rpb24uZGlzcG9zZX0uXG4gICAqXG4gICAqIFdoZW4gb21pdHRlZCwgZGVmYXVsdHMgdG8gYHRydWVgIGZvciBhbiBpbXBsaWNpdCB0aHJvdy1hd2F5IHRlbXAgdmF1bHRcbiAgICogKHtAbGluayB2YXVsdH0gbm90IGdpdmVuKSBhbmQgYGZhbHNlYCB3aGVuIGEge0BsaW5rIHZhdWx0fSBwYXRoIGlzIGdpdmVuLCBzb1xuICAgKiBhIHJlYWwgdmF1bHQgaXMgbmV2ZXIgZGVsZXRlZC4gU2V0IGV4cGxpY2l0bHkgdG8gb3ZlcnJpZGUuXG4gICAqL1xuICByZWFkb25seSBzaG91bGRSZW1vdmVWYXVsdE9uRGlzcG9zZT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEFic29sdXRlIHBhdGggdG8gYW4gZXhpc3RpbmcgdmF1bHQgdG8gb3Blbi4gV2hlbiBvbWl0dGVkLCBhbiBlbXB0eSB0ZW1wb3JhcnlcbiAgICogdmF1bHQgaXMgY3JlYXRlZCAoYW5kIHJlbW92ZWQgb24gZGlzcG9zZSB1bmxlc3NcbiAgICoge0BsaW5rIHNob3VsZFJlbW92ZVZhdWx0T25EaXNwb3NlfSBzYXlzIG90aGVyd2lzZSkuXG4gICAqXG4gICAqIEBkZWZhdWx0IGB1bmRlZmluZWRgXG4gICAqL1xuICByZWFkb25seSB2YXVsdD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIHJlc29sdmVkIENEUCBob3N0L3BvcnQgcGFpci5cbiAqL1xuaW50ZXJmYWNlIFJlc29sdmVkRW5kcG9pbnQge1xuICBob3N0OiBzdHJpbmc7XG4gIHBvcnQ6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBMYXVuY2hlcyAob3IgYXR0YWNoZXMgdG8pIGEgQ0RQLWVuYWJsZWQgT2JzaWRpYW4gaW5zdGFuY2UsIG9wZW5zIGEgdmF1bHQsIGFuZFxuICogYm9vdHN0cmFwcyB0aGUgcnVudGltZSBoZWxwZXIgbmFtZXNwYWNlLCByZXR1cm5pbmcgYSBkaXNwb3NhYmxlIGNvbm5lY3Rpb24uXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBDb25uZWN0aW9uIG9wdGlvbnMuXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHRvIHRoZSBsaXZlIHtAbGluayBDZHBDb25uZWN0aW9ufS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvbm5lY3RUb0NkcChvcHRpb25zPzogQ29ubmVjdFRvQ2RwT3B0aW9ucyk6IFByb21pc2U8Q2RwQ29ubmVjdGlvbj4ge1xuICBjb25zdCB0cmFuc3BvcnRPcHRpb25zOiBPYnNpZGlhbkNkcFRyYW5zcG9ydE9wdGlvbnMgPSB7XG4gICAgdHlwZTogJ29ic2lkaWFuLWNkcCcsXG4gICAgLi4uKG9wdGlvbnM/LmNvbW1hbmRUaW1lb3V0SW5NaWxsaXNlY29uZHMgIT09IHVuZGVmaW5lZCAmJiB7IGNvbW1hbmRUaW1lb3V0SW5NaWxsaXNlY29uZHM6IG9wdGlvbnMuY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kcyB9KSxcbiAgICAuLi4ob3B0aW9ucz8uaG9zdCAhPT0gdW5kZWZpbmVkICYmIHsgaG9zdDogb3B0aW9ucy5ob3N0IH0pLFxuICAgIC4uLihvcHRpb25zPy5vYnNpZGlhbkluc3RhbGxlclZlcnNpb24gIT09IHVuZGVmaW5lZCAmJiB7IG9ic2lkaWFuSW5zdGFsbGVyVmVyc2lvbjogb3B0aW9ucy5vYnNpZGlhbkluc3RhbGxlclZlcnNpb24gfSksXG4gICAgLi4uKG9wdGlvbnM/Lm9ic2lkaWFuVmVyc2lvbiAhPT0gdW5kZWZpbmVkICYmIHsgb2JzaWRpYW5WZXJzaW9uOiBvcHRpb25zLm9ic2lkaWFuVmVyc2lvbiB9KSxcbiAgICAuLi4ob3B0aW9ucz8ucG9ydCAhPT0gdW5kZWZpbmVkICYmIHsgcG9ydDogb3B0aW9ucy5wb3J0IH0pXG4gIH07XG5cbiAgY29uc3QgdHJhbnNwb3J0ID0gYXdhaXQgY3JlYXRlVHJhbnNwb3J0RnJvbU9wdGlvbnModHJhbnNwb3J0T3B0aW9ucyk7XG4gIGNvbnN0IHZhdWx0ID0gbmV3IFRlbXBWYXVsdChvcHRpb25zPy52YXVsdCk7XG4gIGNvbnN0IHNob3VsZFJlbW92ZVZhdWx0T25EaXNwb3NlID0gb3B0aW9ucz8uc2hvdWxkUmVtb3ZlVmF1bHRPbkRpc3Bvc2UgPz8gKG9wdGlvbnM/LnZhdWx0ID09PSB1bmRlZmluZWQpO1xuXG4gIC8vIFJlZ2lzdGVyaW5nIHRoZSB2YXVsdCBpcyB3aGF0IGxhdW5jaGVzIHRoZSBvd25lZCBpbnN0YW5jZSAocHJvdmlzaW9ucyB0aGVcbiAgLy8gQXNhciwgb3BlbnMgdGhlIHZhdWx0LCBhbmQgYm9vdHN0cmFwcyB0aGUgaGVscGVyIG5hbWVzcGFjZSksIG9yIG9wZW5zIHRoZVxuICAvLyBWYXVsdCBpbiB0aGUgYXR0YWNoZWQgaW5zdGFuY2UuXG4gIGF3YWl0IHZhdWx0LnJlZ2lzdGVyKHRyYW5zcG9ydCk7XG5cbiAgY29uc3QgeyBob3N0LCBwb3J0IH0gPSByZXNvbHZlRW5kcG9pbnQodHJhbnNwb3J0LCBvcHRpb25zKTtcbiAgY29uc3QgY2RwVXJsID0gYGh0dHA6Ly8ke2hvc3R9OiR7U3RyaW5nKHBvcnQpfWA7XG5cbiAgY29uc3QgY29ubmVjdGlvbjogQ2RwQ29ubmVjdGlvbiA9IHtcbiAgICBjZHBVcmwsXG5cbiAgICBhc3luYyBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKHNob3VsZFJlbW92ZVZhdWx0T25EaXNwb3NlKSB7XG4gICAgICAgICAgYXdhaXQgdmF1bHQuZGlzcG9zZSh0cmFuc3BvcnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGF3YWl0IHRyYW5zcG9ydC51bnJlZ2lzdGVyVmF1bHQodmF1bHQucGF0aCk7XG4gICAgICAgIH1cbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHRyYW5zcG9ydC5kaXNwb3NlPy4oKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYXN5bmMgZXZhbEluT2JzaWRpYW48QXJncyBleHRlbmRzIEdlbmVyaWNPYmplY3QsIFJlc3VsdCwgVENvbnRleHRJZCBleHRlbmRzIENvbnRleHRJZDx1bmtub3duPiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZD4oXG4gICAgICBwYXJhbXM6IEV4Y2VwdDxFdmFsSW5PYnNpZGlhblBhcmFtczxBcmdzLCBSZXN1bHQsIFRDb250ZXh0SWQ+LCAndHJhbnNwb3J0JyB8ICd2YXVsdFBhdGgnPlxuICAgICk6IFByb21pc2U8UmVzdWx0PiB7XG4gICAgICByZXR1cm4gZXZhbEluT2JzaWRpYW48QXJncywgUmVzdWx0LCBUQ29udGV4dElkPih7IC4uLnBhcmFtcywgdHJhbnNwb3J0LCB2YXVsdFBhdGg6IHZhdWx0LnBhdGggfSk7XG4gICAgfSxcblxuICAgIGFzeW5jIGludm9rZShleHByZXNzaW9uOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgcmV0dXJuIHRyYW5zcG9ydC5ldmFsdWF0ZShleHByZXNzaW9uLCB7IGN3ZDogdmF1bHQucGF0aCB9KTtcbiAgICB9LFxuXG4gICAgcG9ydCxcblxuICAgIGFzeW5jIFtTeW1ib2wuYXN5bmNEaXNwb3NlXSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGF3YWl0IGNvbm5lY3Rpb24uZGlzcG9zZSgpO1xuICAgIH0sXG5cbiAgICB2YXVsdFxuICB9O1xuXG4gIHJldHVybiBjb25uZWN0aW9uO1xufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBDRFAgaG9zdC9wb3J0IGZvciB0aGUgY29ubmVjdGlvbjogZnJvbSB0aGUgb3duZWQgaW5zdGFuY2Unc1xuICogbGF1bmNoZWQgZW5kcG9pbnQgd2hlbiBwcmVzZW50LCBvdGhlcndpc2UgZnJvbSB0aGUgYXR0YWNoIG9wdGlvbnMuXG4gKlxuICogQHBhcmFtIHRyYW5zcG9ydCAtIFRoZSB0cmFuc3BvcnQgY3JlYXRlZCBmb3IgdGhpcyBjb25uZWN0aW9uLlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgY29ubmVjdGlvbiBvcHRpb25zLlxuICogQHJldHVybnMgVGhlIHJlc29sdmVkIGhvc3QgYW5kIHBvcnQuXG4gKiBAdGhyb3dzIEVycm9yIGlmIHRoZSBwb3J0IGNhbm5vdCBiZSBkZXRlcm1pbmVkLlxuICovXG5mdW5jdGlvbiByZXNvbHZlRW5kcG9pbnQodHJhbnNwb3J0OiB1bmtub3duLCBvcHRpb25zOiBDb25uZWN0VG9DZHBPcHRpb25zIHwgdW5kZWZpbmVkKTogUmVzb2x2ZWRFbmRwb2ludCB7XG4gIGlmICh0cmFuc3BvcnQgaW5zdGFuY2VvZiBEZXNrdG9wQ2RwVHJhbnNwb3J0KSB7XG4gICAgY29uc3QgZW5kcG9pbnQgPSB0cmFuc3BvcnQuZ2V0T3duZWRJbnN0YW5jZUVuZHBvaW50KCk7XG4gICAgaWYgKGVuZHBvaW50KSB7XG4gICAgICByZXR1cm4geyBob3N0OiBlbmRwb2ludC5ob3N0LCBwb3J0OiBlbmRwb2ludC5wb3J0IH07XG4gICAgfVxuICB9XG5cbiAgaWYgKG9wdGlvbnM/LnBvcnQgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB7IGhvc3Q6IG9wdGlvbnMuaG9zdCA/PyBERUZBVUxUX0NEUF9IT1NULCBwb3J0OiBvcHRpb25zLnBvcnQgfTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignY29ubmVjdFRvQ2RwOiBjb3VsZCBub3QgZGV0ZXJtaW5lIHRoZSBDRFAgcG9ydC4nKTtcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUF3QkEsOEJBQStCO0FBQy9CLHdCQUEwQjtBQUMxQixtQ0FBb0M7QUFDcEMsK0JBQTJDO0FBRTNDLE1BQU0sbUJBQW1CO0FBMEl6QixlQUFzQixhQUFhLFNBQXVEO0FBQ3hGLFFBQU0sbUJBQWdEO0FBQUEsSUFDcEQsTUFBTTtBQUFBLElBQ04sR0FBSSxTQUFTLGlDQUFpQyxVQUFhLEVBQUUsOEJBQThCLFFBQVEsNkJBQTZCO0FBQUEsSUFDaEksR0FBSSxTQUFTLFNBQVMsVUFBYSxFQUFFLE1BQU0sUUFBUSxLQUFLO0FBQUEsSUFDeEQsR0FBSSxTQUFTLDZCQUE2QixVQUFhLEVBQUUsMEJBQTBCLFFBQVEseUJBQXlCO0FBQUEsSUFDcEgsR0FBSSxTQUFTLG9CQUFvQixVQUFhLEVBQUUsaUJBQWlCLFFBQVEsZ0JBQWdCO0FBQUEsSUFDekYsR0FBSSxTQUFTLFNBQVMsVUFBYSxFQUFFLE1BQU0sUUFBUSxLQUFLO0FBQUEsRUFDMUQ7QUFFQSxRQUFNLFlBQVksVUFBTSxxREFBMkIsZ0JBQWdCO0FBQ25FLFFBQU0sUUFBUSxJQUFJLDRCQUFVLFNBQVMsS0FBSztBQUMxQyxRQUFNLDZCQUE2QixTQUFTLDhCQUErQixTQUFTLFVBQVU7QUFLOUYsUUFBTSxNQUFNLFNBQVMsU0FBUztBQUU5QixRQUFNLEVBQUUsTUFBTSxLQUFLLElBQUksZ0JBQWdCLFdBQVcsT0FBTztBQUN6RCxRQUFNLFNBQVMsVUFBVSxJQUFJLElBQUksT0FBTyxJQUFJLENBQUM7QUFFN0MsUUFBTSxhQUE0QjtBQUFBLElBQ2hDO0FBQUEsSUFFQSxNQUFNLFVBQXlCO0FBQzdCLFVBQUk7QUFDRixZQUFJLDRCQUE0QjtBQUM5QixnQkFBTSxNQUFNLFFBQVEsU0FBUztBQUFBLFFBQy9CLE9BQU87QUFDTCxnQkFBTSxVQUFVLGdCQUFnQixNQUFNLElBQUk7QUFBQSxRQUM1QztBQUFBLE1BQ0YsVUFBRTtBQUNBLGNBQU0sVUFBVSxVQUFVO0FBQUEsTUFDNUI7QUFBQSxJQUNGO0FBQUEsSUFFQSxNQUFNLGVBQ0osUUFDaUI7QUFDakIsaUJBQU8sd0NBQXlDLEVBQUUsR0FBRyxRQUFRLFdBQVcsV0FBVyxNQUFNLEtBQUssQ0FBQztBQUFBLElBQ2pHO0FBQUEsSUFFQSxNQUFNLE9BQU8sWUFBcUM7QUFDaEQsYUFBTyxVQUFVLFNBQVMsWUFBWSxFQUFFLEtBQUssTUFBTSxLQUFLLENBQUM7QUFBQSxJQUMzRDtBQUFBLElBRUE7QUFBQSxJQUVBLE9BQU8sT0FBTyxZQUFZLElBQW1CO0FBQzNDLFlBQU0sV0FBVyxRQUFRO0FBQUEsSUFDM0I7QUFBQSxJQUVBO0FBQUEsRUFDRjtBQUVBLFNBQU87QUFDVDtBQVdBLFNBQVMsZ0JBQWdCLFdBQW9CLFNBQTREO0FBQ3ZHLE1BQUkscUJBQXFCLGtEQUFxQjtBQUM1QyxVQUFNLFdBQVcsVUFBVSx5QkFBeUI7QUFDcEQsUUFBSSxVQUFVO0FBQ1osYUFBTyxFQUFFLE1BQU0sU0FBUyxNQUFNLE1BQU0sU0FBUyxLQUFLO0FBQUEsSUFDcEQ7QUFBQSxFQUNGO0FBRUEsTUFBSSxTQUFTLFNBQVMsUUFBVztBQUMvQixXQUFPLEVBQUUsTUFBTSxRQUFRLFFBQVEsa0JBQWtCLE1BQU0sUUFBUSxLQUFLO0FBQUEsRUFDdEU7QUFFQSxRQUFNLElBQUksTUFBTSxpREFBaUQ7QUFDbkU7IiwKICAibmFtZXMiOiBbXQp9Cg==
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file
|
|
3
|
+
*
|
|
4
|
+
* Programmatic helper to launch (or attach to) a CDP-enabled Obsidian instance
|
|
5
|
+
* with the runtime helper namespace bootstrapped, for ad-hoc real-app debugging.
|
|
6
|
+
*
|
|
7
|
+
* A single {@link connectToCdp} call resolves the owned-instance config, opens a
|
|
8
|
+
* vault, and bootstraps `window.__obsidianIntegrationTesting` (so `evalWrapper`,
|
|
9
|
+
* `typeIntoEditor`, `serializeError`, `getObsidianModule`, … are available), then
|
|
10
|
+
* hands back a disposable {@link CdpConnection} exposing the chosen CDP port, a
|
|
11
|
+
* raw {@link CdpConnection.invoke} and the rich {@link CdpConnection.evalInObsidian}.
|
|
12
|
+
*/
|
|
13
|
+
import type { Except } from 'type-fest';
|
|
14
|
+
import type { ContextId } from './context-id.cjs';
|
|
15
|
+
import type { EvalInObsidianParams, GenericObject } from './eval-in-obsidian.cjs';
|
|
16
|
+
import { TempVault } from './temp-vault.cjs';
|
|
17
|
+
/**
|
|
18
|
+
* A live connection to a CDP-enabled Obsidian instance with the runtime helper
|
|
19
|
+
* namespace bootstrapped.
|
|
20
|
+
*
|
|
21
|
+
* Implements `AsyncDisposable`, so `await using conn = await connectToCdp(…)`
|
|
22
|
+
* disposes it (killing an owned instance and — for a throw-away temp vault —
|
|
23
|
+
* removing its directory) automatically.
|
|
24
|
+
*/
|
|
25
|
+
export interface CdpConnection extends AsyncDisposable {
|
|
26
|
+
/**
|
|
27
|
+
* The base CDP URL, e.g. `http://localhost:51888`.
|
|
28
|
+
*/
|
|
29
|
+
readonly cdpUrl: string;
|
|
30
|
+
/**
|
|
31
|
+
* Disposes the connection: kills an owned instance and removes its isolated
|
|
32
|
+
* user-data dir. The vault directory is removed only when it is a throw-away
|
|
33
|
+
* temp vault (see {@link ConnectToCdpOptions.shouldRemoveVaultOnDispose}); a
|
|
34
|
+
* real vault passed via {@link ConnectToCdpOptions.vault} is never deleted.
|
|
35
|
+
*
|
|
36
|
+
* @returns A {@link Promise} that resolves once disposal completes.
|
|
37
|
+
*/
|
|
38
|
+
dispose(): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Evaluates a self-contained function inside Obsidian via the rich helper
|
|
41
|
+
* path, receiving `{ app, obsidianModule, typeIntoEditor, context }` plus any
|
|
42
|
+
* `args`. Mirrors the top-level `evalInObsidian`, with the transport and vault
|
|
43
|
+
* path pre-bound to this connection.
|
|
44
|
+
*
|
|
45
|
+
* @param params - The evaluation parameters (`fn`, optional `args`/`contextId`).
|
|
46
|
+
* @returns A {@link Promise} that resolves to the return value of `fn`.
|
|
47
|
+
*/
|
|
48
|
+
evalInObsidian<Args extends GenericObject, Result, TContextId extends ContextId<unknown> | undefined = undefined>(params: Except<EvalInObsidianParams<Args, Result, TContextId>, 'transport' | 'vaultPath'>): Promise<Result>;
|
|
49
|
+
/**
|
|
50
|
+
* Evaluates a raw JavaScript expression inside Obsidian and returns the
|
|
51
|
+
* normalized string result (e.g. `'5'`, a JSON string, or `'(no output)'`).
|
|
52
|
+
*
|
|
53
|
+
* @param expression - A self-contained JavaScript expression.
|
|
54
|
+
* @returns A {@link Promise} that resolves to the raw result string.
|
|
55
|
+
*/
|
|
56
|
+
invoke(expression: string): Promise<string>;
|
|
57
|
+
/**
|
|
58
|
+
* The CDP port the instance is reachable on (the free port chosen for an
|
|
59
|
+
* owned instance, or the attached {@link ConnectToCdpOptions.port}).
|
|
60
|
+
*/
|
|
61
|
+
readonly port: number;
|
|
62
|
+
/**
|
|
63
|
+
* The opened vault. Exposes `path` and `populate(...)` for seeding files.
|
|
64
|
+
*/
|
|
65
|
+
readonly vault: TempVault;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Options for {@link connectToCdp}.
|
|
69
|
+
*/
|
|
70
|
+
export interface ConnectToCdpOptions {
|
|
71
|
+
/**
|
|
72
|
+
* Timeout in milliseconds for individual CDP commands.
|
|
73
|
+
*
|
|
74
|
+
* @default `30000`
|
|
75
|
+
*/
|
|
76
|
+
readonly commandTimeoutInMilliseconds?: number;
|
|
77
|
+
/**
|
|
78
|
+
* CDP host.
|
|
79
|
+
*
|
|
80
|
+
* @default `'localhost'`
|
|
81
|
+
*/
|
|
82
|
+
readonly host?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Pins the Electron shell (installer build) the owned instance runs. Accepts
|
|
85
|
+
* `'x.y.z'`, `'public-latest'`, or `'catalyst-latest'`. Ignored when
|
|
86
|
+
* {@link port} (attach mode) is set. When omitted, the installed shell is used.
|
|
87
|
+
*
|
|
88
|
+
* @default `undefined`
|
|
89
|
+
*/
|
|
90
|
+
readonly obsidianInstallerVersion?: string;
|
|
91
|
+
/**
|
|
92
|
+
* Pins the Obsidian app version (asar) the owned instance runs. Accepts
|
|
93
|
+
* `'x.y.z'`, `'public-latest'`, or `'catalyst-latest'`. Ignored when
|
|
94
|
+
* {@link port} (attach mode) is set. When omitted, the installed version is used.
|
|
95
|
+
*
|
|
96
|
+
* @default `undefined`
|
|
97
|
+
*/
|
|
98
|
+
readonly obsidianVersion?: string;
|
|
99
|
+
/**
|
|
100
|
+
* CDP port of an already-running Obsidian to **attach** to. When omitted, an
|
|
101
|
+
* isolated instance is launched on an automatically chosen free port.
|
|
102
|
+
*
|
|
103
|
+
* @default `undefined`
|
|
104
|
+
*/
|
|
105
|
+
readonly port?: number;
|
|
106
|
+
/**
|
|
107
|
+
* Whether to remove the vault directory on {@link CdpConnection.dispose}.
|
|
108
|
+
*
|
|
109
|
+
* When omitted, defaults to `true` for an implicit throw-away temp vault
|
|
110
|
+
* ({@link vault} not given) and `false` when a {@link vault} path is given, so
|
|
111
|
+
* a real vault is never deleted. Set explicitly to override.
|
|
112
|
+
*/
|
|
113
|
+
readonly shouldRemoveVaultOnDispose?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Absolute path to an existing vault to open. When omitted, an empty temporary
|
|
116
|
+
* vault is created (and removed on dispose unless
|
|
117
|
+
* {@link shouldRemoveVaultOnDispose} says otherwise).
|
|
118
|
+
*
|
|
119
|
+
* @default `undefined`
|
|
120
|
+
*/
|
|
121
|
+
readonly vault?: string;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Launches (or attaches to) a CDP-enabled Obsidian instance, opens a vault, and
|
|
125
|
+
* bootstraps the runtime helper namespace, returning a disposable connection.
|
|
126
|
+
*
|
|
127
|
+
* @param options - Connection options.
|
|
128
|
+
* @returns A {@link Promise} that resolves to the live {@link CdpConnection}.
|
|
129
|
+
*/
|
|
130
|
+
export declare function connectToCdp(options?: ConnectToCdpOptions): Promise<CdpConnection>;
|
|
@@ -79,4 +79,4 @@ ${sanitizedDetail}`);
|
|
|
79
79
|
0 && (module.exports = {
|
|
80
80
|
evalInObsidian
|
|
81
81
|
});
|
|
82
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2V2YWwtaW4tb2JzaWRpYW4udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBFdmFsdWF0ZXMgYSBmdW5jdGlvbiBpbnNpZGUgYSBydW5uaW5nIE9ic2lkaWFuIGluc3RhbmNlIHZpYSBhIHBsdWdnYWJsZSB0cmFuc3BvcnQuXG4gKi9cblxuaW1wb3J0IHR5cGUge1xuICBBcHAsXG4gIEVkaXRvclxufSBmcm9tICdvYnNpZGlhbic7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0LXgvbm8tbmFtZXNwYWNlIC0tIFdlIG5lZWQgdG8gcmVmZXJlbmNlIGBvYnNpZGlhbmAgbW9kdWxlLlxuaW1wb3J0IHR5cGUgKiBhcyBvYnNpZGlhbiBmcm9tICdvYnNpZGlhbic7XG5pbXBvcnQgdHlwZSB7IFByb21pc2FibGUgfSBmcm9tICd0eXBlLWZlc3QnO1xuXG5pbXBvcnQgeyBleGlzdHNTeW5jIH0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQgdHlwZSB7XG4gIENvbnRleHRBcmdzLFxuICBDb250ZXh0SWRcbn0gZnJvbSAnLi9jb250ZXh0LWlkLmNqcyc7XG5pbXBvcnQgdHlwZSB7IEdlbmVyYXRlTmFtZXNwYWNlQ2FsbFBhcmFtcyB9IGZyb20gJy4vZ2VuZXJhdGUtZnVuY3Rpb24tY2FsbC5janMnO1xuaW1wb3J0IHR5cGUgeyBPYnNpZGlhblRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LmNqcyc7XG5cbmltcG9ydCB7XG4gIGdldFRyYW5zcG9ydE9wdGlvbnMsXG4gIGdldFZhdWx0UGF0aFxufSBmcm9tICcuL2NvbnRleHQtcHJvdmlkZXIuY2pzJztcbmltcG9ydCB7IGdlbmVyYXRlTmFtZXNwYWNlQ2FsbCB9IGZyb20gJy4vZ2VuZXJhdGUtZnVuY3Rpb24tY2FsbC5janMnO1xuaW1wb3J0IHsgZW5zdXJlTmFtZXNwYWNlQm9vdHN0cmFwcGVkIH0gZnJvbSAnLi9uYW1lc3BhY2UtYm9vdHN0cmFwLmNqcyc7XG5pbXBvcnQgeyBnZXRPckNyZWF0ZVRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWZhY3RvcnkuY2pzJztcblxuaW50ZXJmYWNlIEV2YWxFcnJvckVudmVsb3BlIHtcbiAgdHlwZTogJ2Vycm9yJztcbiAgdmFsdWU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBEaXNjcmltaW5hdGVkIGVudmVsb3BlIHJldHVybmVkIGJ5IHRoZSByZWdpc3RlcmVkIGBldmFsV3JhcHBlcmAgZnJvbSBpbnNpZGUgdGhlIE9ic2lkaWFuIHByb2Nlc3MuXG4gKlxuICogLSBgRXZhbEVycm9yRW52ZWxvcGVgIFx1MjAxNCBgZm5gIHRocmV3OyBgdmFsdWVgIGlzIHRoZSBzZXJpYWxpemVkIGVycm9yLlxuICogLSBgRXZhbFVuZGVmaW5lZEVudmVsb3BlYCBcdTIwMTQgYGZuYCByZXR1cm5lZCBgdW5kZWZpbmVkYC5cbiAqIC0gYEV2YWxWYWx1ZUVudmVsb3BlYCBcdTIwMTQgYGZuYCByZXR1cm5lZCBhIEpTT04tc2VyaWFsaXphYmxlIHZhbHVlLlxuICovXG50eXBlIEV2YWxSZXN1bHRFbnZlbG9wZSA9XG4gIHwgRXZhbEVycm9yRW52ZWxvcGVcbiAgfCBFdmFsVW5kZWZpbmVkRW52ZWxvcGVcbiAgfCBFdmFsVmFsdWVFbnZlbG9wZTtcblxuaW50ZXJmYWNlIEV2YWxVbmRlZmluZWRFbnZlbG9wZSB7XG4gIHR5cGU6ICd1bmRlZmluZWQnO1xufVxuXG5pbnRlcmZhY2UgRXZhbFZhbHVlRW52ZWxvcGUge1xuICB2YWx1ZTogdW5rbm93bjtcbn1cblxuY29uc3QgTk9fT1VUUFVUID0gJyhubyBvdXRwdXQpJztcblxuLyoqXG4gKiBDb21tb24gYXJndW1lbnRzIGF1dG9tYXRpY2FsbHkgcHJvdmlkZWQgdG8gZXZlcnkge0BsaW5rIGV2YWxJbk9ic2lkaWFufSBjYWxsYmFjay5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb21tb25BcmdzIHtcbiAgLyoqXG4gICAqIFRoZSBPYnNpZGlhbiB7QGxpbmsgQXBwfSBpbnN0YW5jZS5cbiAgICovXG4gIGFwcDogQXBwO1xuXG4gIC8qKlxuICAgKiBUaGUgYG9ic2lkaWFuYCBtb2R1bGUsIHJlc29sdmVkIGF0IHJ1bnRpbWUgaW5zaWRlIHRoZSBPYnNpZGlhbiBwcm9jZXNzLlxuICAgKi9cbiAgb2JzaWRpYW5Nb2R1bGU6IHR5cGVvZiBvYnNpZGlhbjtcblxuICAvKipcbiAgICogVHlwZXMgdGV4dCBpbnRvIGEgQ29kZU1pcnJvciB7QGxpbmsgRWRpdG9yfSB1c2luZyAqKnRydXN0ZWQqKiBFbGVjdHJvblxuICAgKiBrZXlib2FyZCBpbnB1dC5cbiAgICpcbiAgICogQSB0cnVzdGVkIGV2ZW50IChpbmplY3RlZCB2aWEgRWxlY3Ryb24ncyBgd2ViQ29udGVudHMuc2VuZElucHV0RXZlbnRgKVxuICAgKiBiZWhhdmVzIGxpa2UgYSByZWFsIGtleXByZXNzOiBpdCBpcyBkZWxpdmVyZWQgdG8gdGhlIHdpbmRvdydzIERPTS1mb2N1c2VkXG4gICAqIGVsZW1lbnQgYW5kIGZsb3dzIHRocm91Z2ggQ29kZU1pcnJvcidzIHJlYWwgaW5wdXQgcGlwZWxpbmUsIHNvIHRoZSB0eXBlZFxuICAgKiB0ZXh0IHJlYWNoZXMgdGhlIGRvY3VtZW50ICoqb25seSBpZiB0aGUgZWRpdG9yIGdlbnVpbmVseSBob2xkcyBmb2N1cyoqLlxuICAgKiBUaGlzIG1ha2VzIFwidGhlIHVzZXIgdHlwZWQgaW50byB0aGUgZWRpdG9yXCIgYSBmYWl0aGZ1bCBlbmQtdG8tZW5kIGNoZWNrLFxuICAgKiB1bmxpa2UgYGRpc3BhdGNoRXZlbnQobmV3IEtleWJvYXJkRXZlbnQoLi4uKSlgICh1bnRydXN0ZWQgXHUyMDE0IGlnbm9yZWQgYnlcbiAgICogQ29kZU1pcnJvcikgb3IgYGV4ZWNDb21tYW5kKCdpbnNlcnRUZXh0JylgIChtdXRhdGVzIHRoZSBzZWxlY3Rpb24gZXZlblxuICAgKiB3aGVuIHRoZSBlZGl0b3IgaXMgbm90IGZvY3VzZWQsIG1hc2tpbmcgZm9jdXMgYnVncyBhcyBmYWxzZSBwb3NpdGl2ZXMpLlxuICAgKlxuICAgKiBBZnRlciBpbmplY3RpbmcgdGhlIGtleXN0cm9rZXMgaXQgcG9sbHMgdW50aWwgdGhlIGRvY3VtZW50IHJlZmxlY3RzIHRoZVxuICAgKiBpbnB1dCwgb3IgYSBib3VuZGVkIHRpbWVvdXQgZWxhcHNlcyAodGhlIGV4cGVjdGVkIG91dGNvbWUgd2hlbiB0aGUgZWRpdG9yXG4gICAqIGlzIHJlYWQtb25seSBhbmQgcmVqZWN0cyB0aGUgaW5wdXQsIG9yIHdoZW4gZm9jdXMgd2FzIHN0b2xlbikuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZWRpdG9yIHRvIHR5cGUgaW50byBhbmQgdGhlIHRleHQgdG8gdHlwZS5cbiAgICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBrZXlzdHJva2VzIGhhdmUgc2V0dGxlZC5cbiAgICovXG4gIHR5cGVJbnRvRWRpdG9yKHRoaXM6IHZvaWQsIHBhcmFtczogVHlwZUludG9FZGl0b3JQYXJhbXMpOiBQcm9taXNlPHZvaWQ+O1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBldmFsSW5PYnNpZGlhbn0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRXZhbEluT2JzaWRpYW5QYXJhbXM8QXJncyBleHRlbmRzIEdlbmVyaWNPYmplY3QsIFJlc3VsdCwgVENvbnRleHRJZCBleHRlbmRzIENvbnRleHRJZDx1bmtub3duPiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZD4ge1xuICAvKipcbiAgICogQWRkaXRpb25hbCBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgZnVuY3Rpb24uIFZhbHVlcyBtYXkgaW5jbHVkZSBmdW5jdGlvbnMgXHUyMDE0XG4gICAqIHRoZXkgYXJlIHNlcmlhbGl6ZWQgdmlhIGB0b1N0cmluZygpYC5cbiAgICovXG4gIHJlYWRvbmx5IGFyZ3M/OiBBcmdzO1xuXG4gIC8qKlxuICAgKiBBIHtAbGluayBDb250ZXh0SWR9IGxpbmtpbmcgdGhpcyBjYWxsIHRvIGEgcGVyc2lzdGVudCBzdG9yZSBvbiBgd2luZG93YFxuICAgKiBpbiB0aGUgT2JzaWRpYW4gcHJvY2Vzcy4gVGhlIGNhbGxiYWNrIHJlY2VpdmVzIGEgdHlwZWQgYGNvbnRleHRgIG9iamVjdFxuICAgKiB0aGF0IHN1cnZpdmVzIGFjcm9zcyBjYWxscyBzaGFyaW5nIHRoZSBzYW1lIElELlxuICAgKlxuICAgKiBXaGVuIG9taXR0ZWQsIGBjb250ZXh0YCBpcyBhIGZyZXNoIGVtcHR5IG9iamVjdCBlYWNoIGNhbGwuXG4gICAqL1xuICByZWFkb25seSBjb250ZXh0SWQ/OiBUQ29udGV4dElkO1xuXG4gIC8qKlxuICAgKiBUaGUgZnVuY3Rpb24gdG8gZXZhbHVhdGUgaW4gdGhlIE9ic2lkaWFuIGNvbnRleHQuXG4gICAqL1xuICBmbihhcmdzOiBBcmdzICYgQ29tbW9uQXJncyAmIENvbnRleHRBcmdzPFRDb250ZXh0SWQ+KTogUHJvbWlzYWJsZTxSZXN1bHQ+O1xuXG4gIC8qKlxuICAgKiBTa2lwcyBwcmUtZmxpZ2h0IGNoZWNrcyAodmF1bHQgcmVnaXN0cmF0aW9uLCBDTEkgYXZhaWxhYmlsaXR5KS5cbiAgICogVXNlZCBpbnRlcm5hbGx5IGJ5IHZhdWx0IHJlZ2lzdHJhdGlvbiBmdW5jdGlvbnMuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkU2tpcFByZWZsaWdodENoZWNrcz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIE92ZXJyaWRlIHRoZSB0cmFuc3BvcnQgZm9yIHRoaXMgY2FsbC4gV2hlbiBvbWl0dGVkLCB1c2VzIHRoZSB0cmFuc3BvcnRcbiAgICogY29uZmlndXJlZCB2aWEgdGhlIGNvbnRleHQgcHJvdmlkZXIgKHNldCBieSB0aGUgZnJhbWV3b3JrIGFkYXB0ZXIncyBnbG9iYWwgc2V0dXApLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0PzogT2JzaWRpYW5UcmFuc3BvcnQ7XG5cbiAgLyoqXG4gICAqIFRoZSBwYXRoIHRvIHRoZSBPYnNpZGlhbiB2YXVsdC4gRGVmYXVsdHMgdG8gYHByb2Nlc3MuY3dkKClgLlxuICAgKi9cbiAgcmVhZG9ubHkgdmF1bHRQYXRoPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgcGxhaW4gb2JqZWN0IHdpdGggc3RyaW5nIGtleXMuXG4gKi9cbmV4cG9ydCB0eXBlIEdlbmVyaWNPYmplY3QgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgQ29tbW9uQXJncy50eXBlSW50b0VkaXRvcn0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVHlwZUludG9FZGl0b3JQYXJhbXMge1xuICAvKipcbiAgICogVGhlIGVkaXRvciB0byB0eXBlIGludG8uIEl0IGlzIGZvY3VzZWQgKHdpdGggdGhlIGNhcmV0IG1vdmVkIHRvIHRoZSBlbmQgb2ZcbiAgICogdGhlIGRvY3VtZW50KSBiZWZvcmUgdGhlIGtleXN0cm9rZXMgYXJlIGluamVjdGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgZWRpdG9yOiBFZGl0b3I7XG5cbiAgLyoqXG4gICAqIFRoZSB0ZXh0IHRvIHR5cGUsIG9uZSB0cnVzdGVkIGNoYXJhY3RlciBldmVudCBwZXIgY29kZSBwb2ludC5cbiAgICovXG4gIHJlYWRvbmx5IHRleHQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBFdmFsdWF0ZXMgYSBmdW5jdGlvbiBpbnNpZGUgdGhlIHJ1bm5pbmcgT2JzaWRpYW4gaW5zdGFuY2VcbiAqIHZpYSB0aGUgYWN0aXZlIHRyYW5zcG9ydCBhbmQgcmV0dXJucyB0aGUgcGFyc2VkIHJlc3VsdC5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gcmVjZWl2ZXMgYW4gYXJncyBvYmplY3QgdGhhdCBpbmNsdWRlcyBgYXBwYCwgYG9ic2lkaWFuTW9kdWxlYCxcbiAqIGBjb250ZXh0YCwgYW5kIGFueSBhZGRpdGlvbmFsIGBhcmdzYCBwYXNzZWQgYnkgdGhlIGNhbGxlci5cbiAqIEl0IGlzIHNlcmlhbGl6ZWQgdmlhIGB0b1N0cmluZygpYCBhbmQgaW52b2tlZCBhcyBhbiBJSUZFLlxuICogVGhlIGZ1bmN0aW9uIG11c3QgYmUgc2VsZi1jb250YWluZWQgXHUyMDE0IGNsb3N1cmVzIG92ZXIgbG9jYWwgdmFyaWFibGVzIHdpbGwgbm90IHdvcmsuXG4gKiBQYXNzIGFueSBuZWVkZWQgdmFsdWVzIGFzIGBhcmdzYCBcdTIwMTQgdGhleSBhcmUgSlNPTi1zZXJpYWxpemVkIGFuZCBkZXNlcmlhbGl6ZWQgb24gdGhlIE9ic2lkaWFuIHNpZGUuXG4gKlxuICogVGhlIHJlc3VsdCBpcyBgSlNPTi5zdHJpbmdpZnlgJ2Qgb24gdGhlIE9ic2lkaWFuIHNpZGUgYW5kIHBhcnNlZCBiYWNrLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhlIGZ1bmN0aW9uIHRvIGV2YWx1YXRlLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB0byB0aGUgcmV0dXJuIHZhbHVlIG9mIGBmbmAuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBldmFsSW5PYnNpZGlhbjxBcmdzIGV4dGVuZHMgR2VuZXJpY09iamVjdCwgUmVzdWx0LCBUQ29udGV4dElkIGV4dGVuZHMgQ29udGV4dElkPHVua25vd24+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkPihcbiAgcGFyYW1zOiBFdmFsSW5PYnNpZGlhblBhcmFtczxBcmdzLCBSZXN1bHQsIFRDb250ZXh0SWQ+XG4pOiBQcm9taXNlPFJlc3VsdD4ge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3VuYm91bmQtbWV0aG9kIC0tIGBmbmAgY2FuIGJlIHVuYm91bmQuXG4gIGNvbnN0IHsgYXJncyA9IHt9LCBjb250ZXh0SWQsIGZuLCBzaG91bGRTa2lwUHJlZmxpZ2h0Q2hlY2tzID0gZmFsc2UsIHRyYW5zcG9ydDogdHJhbnNwb3J0T3ZlcnJpZGUsIHZhdWx0UGF0aCB9ID0gcGFyYW1zO1xuICBjb25zdCBjd2QgPSB2YXVsdFBhdGggPz8gZ2V0VmF1bHRQYXRoKCkgPz8gcHJvY2Vzcy5jd2QoKTtcblxuICAvLyBDaGVjazogVmF1bHQgcGF0aCBleGlzdHMgb24gZGlzay5cbiAgaWYgKHZhdWx0UGF0aCAhPT0gdW5kZWZpbmVkICYmICFleGlzdHNTeW5jKHZhdWx0UGF0aCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFZhdWx0IHBhdGggZG9lcyBub3QgZXhpc3Q6ICR7dmF1bHRQYXRofWApO1xuICB9XG5cbiAgY29uc3QgdHJhbnNwb3J0ID0gdHJhbnNwb3J0T3ZlcnJpZGUgPz8gYXdhaXQgZ2V0T3JDcmVhdGVUcmFuc3BvcnQoZ2V0VHJhbnNwb3J0T3B0aW9ucygpKTtcblxuICBpZiAoIXNob3VsZFNraXBQcmVmbGlnaHRDaGVja3MpIHtcbiAgICBhd2FpdCB0cmFuc3BvcnQucHJlZmxpZ2h0Q2hlY2soY3dkKTtcbiAgfVxuXG4gIGF3YWl0IGVuc3VyZU5hbWVzcGFjZUJvb3RzdHJhcHBlZCh0cmFuc3BvcnQsIGN3ZCk7XG5cbiAgY29uc3QgbmFtZXNwYWNlQ2FsbFBhcmFtczogR2VuZXJhdGVOYW1lc3BhY2VDYWxsUGFyYW1zID0ge1xuICAgIGFyZ3MsXG4gICAgZm4sXG4gICAgLi4uKGNvbnRleHRJZCAhPT0gdW5kZWZpbmVkICYmIHsgY29udGV4dElkOiBTdHJpbmcoY29udGV4dElkKSB9KVxuICB9O1xuXG4gIGNvbnN0IGV4cHJlc3Npb24gPSBnZW5lcmF0ZU5hbWVzcGFjZUNhbGwobmFtZXNwYWNlQ2FsbFBhcmFtcyk7XG5cbiAgY29uc3QgcmVzdWx0U3RyID0gYXdhaXQgdHJhbnNwb3J0LmV2YWx1YXRlKGV4cHJlc3Npb24sIHsgY3dkIH0pO1xuXG4gIGlmIChyZXN1bHRTdHIgPT09ICcnIHx8IHJlc3VsdFN0ciA9PT0gTk9fT1VUUFVUKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZCBhcyBSZXN1bHQ7XG4gIH1cblxuICBsZXQgZW52ZWxvcGU6IEV2YWxSZXN1bHRFbnZlbG9wZTtcbiAgdHJ5IHtcbiAgICBlbnZlbG9wZSA9IEpTT04ucGFyc2UocmVzdWx0U3RyKSBhcyBFdmFsUmVzdWx0RW52ZWxvcGU7XG4gIH0gY2F0Y2gge1xuICAgIHRocm93IG5ldyBFcnJvcihgZXZhbEluT2JzaWRpYW46IE9ic2lkaWFuIHJldHVybmVkIG5vbi1KU09OIG91dHB1dDogJHtyZXN1bHRTdHJ9YCk7XG4gIH1cblxuICBpZiAoJ3R5cGUnIGluIGVudmVsb3BlKSB7XG4gICAgaWYgKGVudmVsb3BlLnR5cGUgPT09ICdlcnJvcicpIHtcbiAgICAgIC8vIFJld3JpdGUgYmFyZS1vcmlnaW4gbG9jYWxob3N0IHN0YWNrIGZyYW1lcyBsaWtlIFwiKGh0dHA6Ly9sb2NhbGhvc3QvOjkxNTozMilcIlxuICAgICAgLy8gU28gVml0ZXN0J3Mgc291cmNlLW1hcCByZXNvbHZlciB3b24ndCBleHRyYWN0IFwiL1wiIGFzIHRoZSBmaWxlIHBhdGggYW5kIGNyYXNoXG4gICAgICAvLyBXaXRoIEVJU0RJUiB3aGVuIGl0IHRyaWVzIHRvIHJlYWRGaWxlU3luYyBvbiB0aGUgcm9vdCBkaXJlY3RvcnkuXG4gICAgICBjb25zdCBzYW5pdGl6ZWREZXRhaWwgPSBlbnZlbG9wZS52YWx1ZVxuICAgICAgICAucmVwbGFjZSgvXFwoaHR0cHM/OlxcL1xcL2xvY2FsaG9zdFxcLzooPzxsaW5lPlxcZCkvZywgJyhvYnNpZGlhbi13ZWJ2aWV3OiQ8bGluZT4nKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgZXZhbEluT2JzaWRpYW46IEVycm9yIGluc2lkZSBPYnNpZGlhbjpcXG4ke3Nhbml0aXplZERldGFpbH1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkIGFzIFJlc3VsdDtcbiAgfVxuXG4gIHJldHVybiBlbnZlbG9wZS52YWx1ZSBhcyBSZXN1bHQ7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQWNBLHFCQUEyQjtBQUMzQiwwQkFBb0I7QUFTcEIsOEJBR087QUFDUCxvQ0FBc0M7QUFDdEMsaUNBQTRDO0FBQzVDLCtCQUFxQztBQTJCckMsTUFBTSxZQUFZO0FBdUhsQixlQUFzQixlQUNwQixRQUNpQjtBQUVqQixRQUFNLEVBQUUsT0FBTyxDQUFDLEdBQUcsV0FBVyxJQUFJLDRCQUE0QixPQUFPLFdBQVcsbUJBQW1CLFVBQVUsSUFBSTtBQUNqSCxRQUFNLE1BQU0saUJBQWEsc0NBQWEsS0FBSyxvQkFBQUEsUUFBUSxJQUFJO0FBR3ZELE1BQUksY0FBYyxVQUFhLEtBQUMsMkJBQVcsU0FBUyxHQUFHO0FBQ3JELFVBQU0sSUFBSSxNQUFNLDhCQUE4QixTQUFTLEVBQUU7QUFBQSxFQUMzRDtBQUVBLFFBQU0sWUFBWSxxQkFBcUIsVUFBTSxtREFBcUIsNkNBQW9CLENBQUM7QUFFdkYsTUFBSSxDQUFDLDJCQUEyQjtBQUM5QixVQUFNLFVBQVUsZUFBZSxHQUFHO0FBQUEsRUFDcEM7QUFFQSxZQUFNLHdEQUE0QixXQUFXLEdBQUc7QUFFaEQsUUFBTSxzQkFBbUQ7QUFBQSxJQUN2RDtBQUFBLElBQ0E7QUFBQSxJQUNBLEdBQUksY0FBYyxVQUFhLEVBQUUsV0FBVyxPQUFPLFNBQVMsRUFBRTtBQUFBLEVBQ2hFO0FBRUEsUUFBTSxpQkFBYSxxREFBc0IsbUJBQW1CO0FBRTVELFFBQU0sWUFBWSxNQUFNLFVBQVUsU0FBUyxZQUFZLEVBQUUsSUFBSSxDQUFDO0FBRTlELE1BQUksY0FBYyxNQUFNLGNBQWMsV0FBVztBQUMvQyxXQUFPO0FBQUEsRUFDVDtBQUVBLE1BQUk7QUFDSixNQUFJO0FBQ0YsZUFBVyxLQUFLLE1BQU0sU0FBUztBQUFBLEVBQ2pDLFFBQVE7QUFDTixVQUFNLElBQUksTUFBTSxzREFBc0QsU0FBUyxFQUFFO0FBQUEsRUFDbkY7QUFFQSxNQUFJLFVBQVUsVUFBVTtBQUN0QixRQUFJLFNBQVMsU0FBUyxTQUFTO0FBSTdCLFlBQU0sa0JBQWtCLFNBQVMsTUFDOUIsUUFBUSx5Q0FBeUMsMkJBQTJCO0FBQy9FLFlBQU0sSUFBSSxNQUFNO0FBQUEsRUFBMkMsZUFBZSxFQUFFO0FBQUEsSUFDOUU7QUFFQSxXQUFPO0FBQUEsRUFDVDtBQUVBLFNBQU8sU0FBUztBQUNsQjsiLAogICJuYW1lcyI6IFsicHJvY2VzcyJdCn0K
|
|
82
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2V2YWwtaW4tb2JzaWRpYW4udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBFdmFsdWF0ZXMgYSBmdW5jdGlvbiBpbnNpZGUgYSBydW5uaW5nIE9ic2lkaWFuIGluc3RhbmNlIHZpYSBhIHBsdWdnYWJsZSB0cmFuc3BvcnQuXG4gKi9cblxuaW1wb3J0IHR5cGUge1xuICBBcHAsXG4gIEVkaXRvclxufSBmcm9tICdvYnNpZGlhbic7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0LXgvbm8tbmFtZXNwYWNlIC0tIFdlIG5lZWQgdG8gcmVmZXJlbmNlIGBvYnNpZGlhbmAgbW9kdWxlLlxuaW1wb3J0IHR5cGUgKiBhcyBvYnNpZGlhbiBmcm9tICdvYnNpZGlhbic7XG5pbXBvcnQgdHlwZSB7IFByb21pc2FibGUgfSBmcm9tICd0eXBlLWZlc3QnO1xuXG5pbXBvcnQgeyBleGlzdHNTeW5jIH0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuXG5pbXBvcnQgdHlwZSB7XG4gIENvbnRleHRBcmdzLFxuICBDb250ZXh0SWRcbn0gZnJvbSAnLi9jb250ZXh0LWlkLmNqcyc7XG5pbXBvcnQgdHlwZSB7IEdlbmVyYXRlTmFtZXNwYWNlQ2FsbFBhcmFtcyB9IGZyb20gJy4vZ2VuZXJhdGUtZnVuY3Rpb24tY2FsbC5janMnO1xuaW1wb3J0IHR5cGUgeyBPYnNpZGlhblRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LmNqcyc7XG5cbmltcG9ydCB7XG4gIGdldFRyYW5zcG9ydE9wdGlvbnMsXG4gIGdldFZhdWx0UGF0aFxufSBmcm9tICcuL2NvbnRleHQtcHJvdmlkZXIuY2pzJztcbmltcG9ydCB7IGdlbmVyYXRlTmFtZXNwYWNlQ2FsbCB9IGZyb20gJy4vZ2VuZXJhdGUtZnVuY3Rpb24tY2FsbC5janMnO1xuaW1wb3J0IHsgZW5zdXJlTmFtZXNwYWNlQm9vdHN0cmFwcGVkIH0gZnJvbSAnLi9uYW1lc3BhY2UtYm9vdHN0cmFwLmNqcyc7XG5pbXBvcnQgeyBnZXRPckNyZWF0ZVRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWZhY3RvcnkuY2pzJztcblxuaW50ZXJmYWNlIEV2YWxFcnJvckVudmVsb3BlIHtcbiAgdHlwZTogJ2Vycm9yJztcbiAgdmFsdWU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBEaXNjcmltaW5hdGVkIGVudmVsb3BlIHJldHVybmVkIGJ5IHRoZSByZWdpc3RlcmVkIGBldmFsV3JhcHBlcmAgZnJvbSBpbnNpZGUgdGhlIE9ic2lkaWFuIHByb2Nlc3MuXG4gKlxuICogLSBgRXZhbEVycm9yRW52ZWxvcGVgIFx1MjAxNCBgZm5gIHRocmV3OyBgdmFsdWVgIGlzIHRoZSBzZXJpYWxpemVkIGVycm9yLlxuICogLSBgRXZhbFVuZGVmaW5lZEVudmVsb3BlYCBcdTIwMTQgYGZuYCByZXR1cm5lZCBgdW5kZWZpbmVkYC5cbiAqIC0gYEV2YWxWYWx1ZUVudmVsb3BlYCBcdTIwMTQgYGZuYCByZXR1cm5lZCBhIEpTT04tc2VyaWFsaXphYmxlIHZhbHVlLlxuICovXG50eXBlIEV2YWxSZXN1bHRFbnZlbG9wZSA9XG4gIHwgRXZhbEVycm9yRW52ZWxvcGVcbiAgfCBFdmFsVW5kZWZpbmVkRW52ZWxvcGVcbiAgfCBFdmFsVmFsdWVFbnZlbG9wZTtcblxuaW50ZXJmYWNlIEV2YWxVbmRlZmluZWRFbnZlbG9wZSB7XG4gIHR5cGU6ICd1bmRlZmluZWQnO1xufVxuXG5pbnRlcmZhY2UgRXZhbFZhbHVlRW52ZWxvcGUge1xuICB2YWx1ZTogdW5rbm93bjtcbn1cblxuY29uc3QgTk9fT1VUUFVUID0gJyhubyBvdXRwdXQpJztcblxuLyoqXG4gKiBDb21tb24gYXJndW1lbnRzIGF1dG9tYXRpY2FsbHkgcHJvdmlkZWQgdG8gZXZlcnkge0BsaW5rIGV2YWxJbk9ic2lkaWFufSBjYWxsYmFjay5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb21tb25BcmdzIHtcbiAgLyoqXG4gICAqIFRoZSBPYnNpZGlhbiB7QGxpbmsgQXBwfSBpbnN0YW5jZS5cbiAgICovXG4gIGFwcDogQXBwO1xuXG4gIC8qKlxuICAgKiBNb3ZlcyB0aGUgbW91c2UgcG9pbnRlciB0byB0aGUgY2VudGVyIG9mIGFuIGVsZW1lbnQgdXNpbmcgKip0cnVzdGVkKipcbiAgICogRWxlY3Ryb24gcG9pbnRlciBpbnB1dCwgdGhlbiBwb2xscyB1bnRpbCB0aGUgZWxlbWVudCBhY3R1YWxseSBtYXRjaGVzXG4gICAqIGA6aG92ZXJgLlxuICAgKlxuICAgKiBCZWNhdXNlIHRoZSBtb3ZlIGlzIHRydXN0ZWQgKHNlZSB7QGxpbmsgQ29tbW9uQXJncy5tb3ZlTW91c2V9KSwgdGhlIHJlYWxcbiAgICogYDpob3ZlcmAgc3RhdGUgdGFrZXMgZWZmZWN0IGluIHRoZSBDU1MgZW5naW5lIFx1MjAxNCByZWFsIHRoZW1lIGB2YXIoKWAgdmFsdWVzXG4gICAqIGFuZCByZWFsIGNvbXBvc2l0aW5nIFx1MjAxNCBpbnN0ZWFkIG9mIGEgaGFuZC1zaW11bGF0ZWQgY2FzY2FkZS4gSXQgcG9sbHMgdGhlXG4gICAqIGxpdmUgYGVsZW1lbnQubWF0Y2hlcygnOmhvdmVyJylgIHN0YXRlIChub3QgYSBmaXhlZCBkZWxheSksIHNvIGl0IGlzIHJvYnVzdFxuICAgKiB1bmRlciBzaGFyZWQtaW5zdGFuY2UgbG9hZC4gSXQgdGFyZ2V0cyB0aGUgc2luZ2xlIHNoYXJlZCB3aW5kb3cnc1xuICAgKiAqKmdsb2JhbCoqIHBvaW50ZXIsIHNvIG9ubHkgb25lIGVsZW1lbnQgaXMgaG92ZXJlZCBhdCBhIHRpbWUuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZWxlbWVudCB0byBob3Zlci5cbiAgICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBlbGVtZW50IG1hdGNoZXMgYDpob3ZlcmAuXG4gICAqL1xuICBob3ZlckVsZW1lbnQodGhpczogdm9pZCwgcGFyYW1zOiBIb3ZlckVsZW1lbnRQYXJhbXMpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIC8qKlxuICAgKiBNb3ZlcyB0aGUgbW91c2UgcG9pbnRlciB0byB0aGUgZ2l2ZW4gd2ViLWNvbnRlbnRzIGNvb3JkaW5hdGVzIHVzaW5nIGFcbiAgICogKip0cnVzdGVkKiogRWxlY3Ryb24gcG9pbnRlciBtb3ZlLlxuICAgKlxuICAgKiBBIHRydXN0ZWQgbW92ZSAoaW5qZWN0ZWQgdmlhIEVsZWN0cm9uJ3MgYHdlYkNvbnRlbnRzLnNlbmRJbnB1dEV2ZW50YClcbiAgICogdXBkYXRlcyB0aGUgcmVhbCBwb2ludGVyIHN0YXRlIGluIHRoZSBDU1MgZW5naW5lLCBzbyBgOmhvdmVyYCBydWxlc1xuICAgKiBnZW51aW5lbHkgYXBwbHkgXHUyMDE0IHVubGlrZSBgZGlzcGF0Y2hFdmVudChuZXcgTW91c2VFdmVudCgnbW91c2VvdmVyJykpYCxcbiAgICogd2hpY2ggaXMgdW50cnVzdGVkIGFuZCBuZXZlciBzZXRzIGA6aG92ZXJgLiBJdCB0YXJnZXRzIHRoZSBzaW5nbGUgc2hhcmVkXG4gICAqIHdpbmRvdydzICoqZ2xvYmFsKiogcG9pbnRlciwgc28gb25seSBvbmUgZWxlbWVudCBpcyBob3ZlcmVkIGF0IGEgdGltZS5cbiAgICpcbiAgICogVGhpcyBpcyB0aGUgbG93LWxldmVsIHByaW1pdGl2ZTogaXQgcGVyZm9ybXMgYSBzaW5nbGUgbW92ZSBhbmQgZG9lcyAqKm5vdCoqXG4gICAqIHdhaXQgZm9yIGFueSBzdGF0ZSB0byBzZXR0bGUgKGNhbGxlcnMgcG9sbCB0aGVpciBvd24gcmVhZGluZXNzIHNpZ25hbCkuXG4gICAqIFByZWZlciB7QGxpbmsgQ29tbW9uQXJncy5ob3ZlckVsZW1lbnR9IC8ge0BsaW5rIENvbW1vbkFyZ3MudW5ob3ZlckVsZW1lbnR9XG4gICAqIGZvciBlbGVtZW50LXJlbGF0aXZlIG1vdmVzOyB1c2UgYG1vdmVNb3VzZWAgZGlyZWN0bHkgd2hlbiBhblxuICAgKiBlbGVtZW50LXJlbGF0aXZlIHRhcmdldCBkb2VzIG5vdCBmaXQgKGUuZy4gYW4gZWxlbWVudCBzcGFubmluZyB0aGUgZnVsbFxuICAgKiB2aWV3cG9ydCB3aWR0aCkuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgd2ViLWNvbnRlbnRzIERJUCBjb29yZGluYXRlcyB0byBtb3ZlIHRvLlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIG1vdmUgaGFzIGJlZW4gaW5qZWN0ZWQuXG4gICAqL1xuICBtb3ZlTW91c2UodGhpczogdm9pZCwgcGFyYW1zOiBNb3ZlTW91c2VQYXJhbXMpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIC8qKlxuICAgKiBUaGUgYG9ic2lkaWFuYCBtb2R1bGUsIHJlc29sdmVkIGF0IHJ1bnRpbWUgaW5zaWRlIHRoZSBPYnNpZGlhbiBwcm9jZXNzLlxuICAgKi9cbiAgb2JzaWRpYW5Nb2R1bGU6IHR5cGVvZiBvYnNpZGlhbjtcblxuICAvKipcbiAgICogVHlwZXMgdGV4dCBpbnRvIGEgQ29kZU1pcnJvciB7QGxpbmsgRWRpdG9yfSB1c2luZyAqKnRydXN0ZWQqKiBFbGVjdHJvblxuICAgKiBrZXlib2FyZCBpbnB1dC5cbiAgICpcbiAgICogQSB0cnVzdGVkIGV2ZW50IChpbmplY3RlZCB2aWEgRWxlY3Ryb24ncyBgd2ViQ29udGVudHMuc2VuZElucHV0RXZlbnRgKVxuICAgKiBiZWhhdmVzIGxpa2UgYSByZWFsIGtleXByZXNzOiBpdCBpcyBkZWxpdmVyZWQgdG8gdGhlIHdpbmRvdydzIERPTS1mb2N1c2VkXG4gICAqIGVsZW1lbnQgYW5kIGZsb3dzIHRocm91Z2ggQ29kZU1pcnJvcidzIHJlYWwgaW5wdXQgcGlwZWxpbmUsIHNvIHRoZSB0eXBlZFxuICAgKiB0ZXh0IHJlYWNoZXMgdGhlIGRvY3VtZW50ICoqb25seSBpZiB0aGUgZWRpdG9yIGdlbnVpbmVseSBob2xkcyBmb2N1cyoqLlxuICAgKiBUaGlzIG1ha2VzIFwidGhlIHVzZXIgdHlwZWQgaW50byB0aGUgZWRpdG9yXCIgYSBmYWl0aGZ1bCBlbmQtdG8tZW5kIGNoZWNrLFxuICAgKiB1bmxpa2UgYGRpc3BhdGNoRXZlbnQobmV3IEtleWJvYXJkRXZlbnQoLi4uKSlgICh1bnRydXN0ZWQgXHUyMDE0IGlnbm9yZWQgYnlcbiAgICogQ29kZU1pcnJvcikgb3IgYGV4ZWNDb21tYW5kKCdpbnNlcnRUZXh0JylgIChtdXRhdGVzIHRoZSBzZWxlY3Rpb24gZXZlblxuICAgKiB3aGVuIHRoZSBlZGl0b3IgaXMgbm90IGZvY3VzZWQsIG1hc2tpbmcgZm9jdXMgYnVncyBhcyBmYWxzZSBwb3NpdGl2ZXMpLlxuICAgKlxuICAgKiBBZnRlciBpbmplY3RpbmcgdGhlIGtleXN0cm9rZXMgaXQgcG9sbHMgdW50aWwgdGhlIGRvY3VtZW50IHJlZmxlY3RzIHRoZVxuICAgKiBpbnB1dCwgb3IgYSBib3VuZGVkIHRpbWVvdXQgZWxhcHNlcyAodGhlIGV4cGVjdGVkIG91dGNvbWUgd2hlbiB0aGUgZWRpdG9yXG4gICAqIGlzIHJlYWQtb25seSBhbmQgcmVqZWN0cyB0aGUgaW5wdXQsIG9yIHdoZW4gZm9jdXMgd2FzIHN0b2xlbikuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgZWRpdG9yIHRvIHR5cGUgaW50byBhbmQgdGhlIHRleHQgdG8gdHlwZS5cbiAgICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBrZXlzdHJva2VzIGhhdmUgc2V0dGxlZC5cbiAgICovXG4gIHR5cGVJbnRvRWRpdG9yKHRoaXM6IHZvaWQsIHBhcmFtczogVHlwZUludG9FZGl0b3JQYXJhbXMpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIC8qKlxuICAgKiBNb3ZlcyB0aGUgbW91c2UgcG9pbnRlciB0byBhIHBvaW50IGp1c3Qgb3V0c2lkZSBhbiBlbGVtZW50J3MgYm91bmRpbmcgYm94XG4gICAqIHVzaW5nIGEgKip0cnVzdGVkKiogRWxlY3Ryb24gcG9pbnRlciBtb3ZlLCB0aGVuIHBvbGxzIHVudGlsIHRoZSBlbGVtZW50IG5vXG4gICAqIGxvbmdlciBtYXRjaGVzIGA6aG92ZXJgLlxuICAgKlxuICAgKiBUaGUgaW52ZXJzZSBvZiB7QGxpbmsgQ29tbW9uQXJncy5ob3ZlckVsZW1lbnR9LiBJdCB0YXJnZXRzIHRoZSBzaW5nbGVcbiAgICogc2hhcmVkIHdpbmRvdydzICoqZ2xvYmFsKiogcG9pbnRlciwgc28gb25seSBvbmUgZWxlbWVudCBpcyBob3ZlcmVkIGF0IGFcbiAgICogdGltZS4gV2hlbiBhbiBlbGVtZW50IHNwYW5zIHRoZSBmdWxsIHZpZXdwb3J0IChubyBwb2ludCBvdXRzaWRlIGl0cyBib3ggaXNcbiAgICogcmVhY2hhYmxlKSwgdXNlIHtAbGluayBDb21tb25BcmdzLm1vdmVNb3VzZX0gZGlyZWN0bHkgdG8gbW92ZSB0aGUgcG9pbnRlclxuICAgKiB0byBhIGtub3duIGVtcHR5IGNvb3JkaW5hdGUgaW5zdGVhZC5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBlbGVtZW50IHRvIG1vdmUgdGhlIHBvaW50ZXIgYXdheSBmcm9tLlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIGVsZW1lbnQgbm8gbG9uZ2VyIG1hdGNoZXNcbiAgICogICBgOmhvdmVyYC5cbiAgICovXG4gIHVuaG92ZXJFbGVtZW50KHRoaXM6IHZvaWQsIHBhcmFtczogVW5ob3ZlckVsZW1lbnRQYXJhbXMpOiBQcm9taXNlPHZvaWQ+O1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBldmFsSW5PYnNpZGlhbn0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRXZhbEluT2JzaWRpYW5QYXJhbXM8QXJncyBleHRlbmRzIEdlbmVyaWNPYmplY3QsIFJlc3VsdCwgVENvbnRleHRJZCBleHRlbmRzIENvbnRleHRJZDx1bmtub3duPiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZD4ge1xuICAvKipcbiAgICogQWRkaXRpb25hbCBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgZnVuY3Rpb24uIFZhbHVlcyBtYXkgaW5jbHVkZSBmdW5jdGlvbnMgXHUyMDE0XG4gICAqIHRoZXkgYXJlIHNlcmlhbGl6ZWQgdmlhIGB0b1N0cmluZygpYC5cbiAgICovXG4gIHJlYWRvbmx5IGFyZ3M/OiBBcmdzO1xuXG4gIC8qKlxuICAgKiBBIHtAbGluayBDb250ZXh0SWR9IGxpbmtpbmcgdGhpcyBjYWxsIHRvIGEgcGVyc2lzdGVudCBzdG9yZSBvbiBgd2luZG93YFxuICAgKiBpbiB0aGUgT2JzaWRpYW4gcHJvY2Vzcy4gVGhlIGNhbGxiYWNrIHJlY2VpdmVzIGEgdHlwZWQgYGNvbnRleHRgIG9iamVjdFxuICAgKiB0aGF0IHN1cnZpdmVzIGFjcm9zcyBjYWxscyBzaGFyaW5nIHRoZSBzYW1lIElELlxuICAgKlxuICAgKiBXaGVuIG9taXR0ZWQsIGBjb250ZXh0YCBpcyBhIGZyZXNoIGVtcHR5IG9iamVjdCBlYWNoIGNhbGwuXG4gICAqL1xuICByZWFkb25seSBjb250ZXh0SWQ/OiBUQ29udGV4dElkO1xuXG4gIC8qKlxuICAgKiBUaGUgZnVuY3Rpb24gdG8gZXZhbHVhdGUgaW4gdGhlIE9ic2lkaWFuIGNvbnRleHQuXG4gICAqL1xuICBmbihhcmdzOiBBcmdzICYgQ29tbW9uQXJncyAmIENvbnRleHRBcmdzPFRDb250ZXh0SWQ+KTogUHJvbWlzYWJsZTxSZXN1bHQ+O1xuXG4gIC8qKlxuICAgKiBTa2lwcyBwcmUtZmxpZ2h0IGNoZWNrcyAodmF1bHQgcmVnaXN0cmF0aW9uLCBDTEkgYXZhaWxhYmlsaXR5KS5cbiAgICogVXNlZCBpbnRlcm5hbGx5IGJ5IHZhdWx0IHJlZ2lzdHJhdGlvbiBmdW5jdGlvbnMuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkU2tpcFByZWZsaWdodENoZWNrcz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIE92ZXJyaWRlIHRoZSB0cmFuc3BvcnQgZm9yIHRoaXMgY2FsbC4gV2hlbiBvbWl0dGVkLCB1c2VzIHRoZSB0cmFuc3BvcnRcbiAgICogY29uZmlndXJlZCB2aWEgdGhlIGNvbnRleHQgcHJvdmlkZXIgKHNldCBieSB0aGUgZnJhbWV3b3JrIGFkYXB0ZXIncyBnbG9iYWwgc2V0dXApLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0PzogT2JzaWRpYW5UcmFuc3BvcnQ7XG5cbiAgLyoqXG4gICAqIFRoZSBwYXRoIHRvIHRoZSBPYnNpZGlhbiB2YXVsdC4gRGVmYXVsdHMgdG8gYHByb2Nlc3MuY3dkKClgLlxuICAgKi9cbiAgcmVhZG9ubHkgdmF1bHRQYXRoPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgcGxhaW4gb2JqZWN0IHdpdGggc3RyaW5nIGtleXMuXG4gKi9cbmV4cG9ydCB0eXBlIEdlbmVyaWNPYmplY3QgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgQ29tbW9uQXJncy5ob3ZlckVsZW1lbnR9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEhvdmVyRWxlbWVudFBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgZWxlbWVudCB0byBob3Zlci4gVGhlIHBvaW50ZXIgaXMgbW92ZWQgdG8gaXRzIGNlbnRlci4gVGhpcyBpcyBhIGxpdmVcbiAgICogcmVuZGVyZXIgRE9NIG5vZGUgXHUyMDE0IHRoZSBjYWxsYmFjayBydW5zIGluLXJlbmRlcmVyLCBzbyBubyBjcm9zcy1wcm9jZXNzXG4gICAqIHNlcmlhbGl6YXRpb24gaXMgbmVlZGVkIChzYW1lIGFzIHtAbGluayBUeXBlSW50b0VkaXRvclBhcmFtcy5lZGl0b3J9KS5cbiAgICovXG4gIHJlYWRvbmx5IGVsZW1lbnQ6IEhUTUxFbGVtZW50O1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBDb21tb25BcmdzLm1vdmVNb3VzZX0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTW92ZU1vdXNlUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSB4IGNvb3JkaW5hdGUgKHdlYi1jb250ZW50cyBESVApIHRvIG1vdmUgdGhlIHBvaW50ZXIgdG8uXG4gICAqL1xuICByZWFkb25seSB4OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSB5IGNvb3JkaW5hdGUgKHdlYi1jb250ZW50cyBESVApIHRvIG1vdmUgdGhlIHBvaW50ZXIgdG8uXG4gICAqL1xuICByZWFkb25seSB5OiBudW1iZXI7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIENvbW1vbkFyZ3MudHlwZUludG9FZGl0b3J9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFR5cGVJbnRvRWRpdG9yUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBlZGl0b3IgdG8gdHlwZSBpbnRvLiBJdCBpcyBmb2N1c2VkICh3aXRoIHRoZSBjYXJldCBtb3ZlZCB0byB0aGUgZW5kIG9mXG4gICAqIHRoZSBkb2N1bWVudCkgYmVmb3JlIHRoZSBrZXlzdHJva2VzIGFyZSBpbmplY3RlZC5cbiAgICovXG4gIHJlYWRvbmx5IGVkaXRvcjogRWRpdG9yO1xuXG4gIC8qKlxuICAgKiBUaGUgdGV4dCB0byB0eXBlLCBvbmUgdHJ1c3RlZCBjaGFyYWN0ZXIgZXZlbnQgcGVyIGNvZGUgcG9pbnQuXG4gICAqL1xuICByZWFkb25seSB0ZXh0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIENvbW1vbkFyZ3MudW5ob3ZlckVsZW1lbnR9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFVuaG92ZXJFbGVtZW50UGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBlbGVtZW50IHRvIG1vdmUgdGhlIHBvaW50ZXIgYXdheSBmcm9tLiBUaGUgcG9pbnRlciBpcyBtb3ZlZCB0byBhIHBvaW50XG4gICAqIGp1c3Qgb3V0c2lkZSBpdHMgYm91bmRpbmcgYm94LiBUaGlzIGlzIGEgbGl2ZSByZW5kZXJlciBET00gbm9kZSBcdTIwMTQgdGhlXG4gICAqIGNhbGxiYWNrIHJ1bnMgaW4tcmVuZGVyZXIsIHNvIG5vIGNyb3NzLXByb2Nlc3Mgc2VyaWFsaXphdGlvbiBpcyBuZWVkZWRcbiAgICogKHNhbWUgYXMge0BsaW5rIFR5cGVJbnRvRWRpdG9yUGFyYW1zLmVkaXRvcn0pLlxuICAgKi9cbiAgcmVhZG9ubHkgZWxlbWVudDogSFRNTEVsZW1lbnQ7XG59XG5cbi8qKlxuICogRXZhbHVhdGVzIGEgZnVuY3Rpb24gaW5zaWRlIHRoZSBydW5uaW5nIE9ic2lkaWFuIGluc3RhbmNlXG4gKiB2aWEgdGhlIGFjdGl2ZSB0cmFuc3BvcnQgYW5kIHJldHVybnMgdGhlIHBhcnNlZCByZXN1bHQuXG4gKlxuICogVGhlIGZ1bmN0aW9uIHJlY2VpdmVzIGFuIGFyZ3Mgb2JqZWN0IHRoYXQgaW5jbHVkZXMgYGFwcGAsIGBvYnNpZGlhbk1vZHVsZWAsXG4gKiBgY29udGV4dGAsIGFuZCBhbnkgYWRkaXRpb25hbCBgYXJnc2AgcGFzc2VkIGJ5IHRoZSBjYWxsZXIuXG4gKiBJdCBpcyBzZXJpYWxpemVkIHZpYSBgdG9TdHJpbmcoKWAgYW5kIGludm9rZWQgYXMgYW4gSUlGRS5cbiAqIFRoZSBmdW5jdGlvbiBtdXN0IGJlIHNlbGYtY29udGFpbmVkIFx1MjAxNCBjbG9zdXJlcyBvdmVyIGxvY2FsIHZhcmlhYmxlcyB3aWxsIG5vdCB3b3JrLlxuICogUGFzcyBhbnkgbmVlZGVkIHZhbHVlcyBhcyBgYXJnc2AgXHUyMDE0IHRoZXkgYXJlIEpTT04tc2VyaWFsaXplZCBhbmQgZGVzZXJpYWxpemVkIG9uIHRoZSBPYnNpZGlhbiBzaWRlLlxuICpcbiAqIFRoZSByZXN1bHQgaXMgYEpTT04uc3RyaW5naWZ5YCdkIG9uIHRoZSBPYnNpZGlhbiBzaWRlIGFuZCBwYXJzZWQgYmFjay5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoZSBmdW5jdGlvbiB0byBldmFsdWF0ZS5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHJldHVybiB2YWx1ZSBvZiBgZm5gLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZXZhbEluT2JzaWRpYW48QXJncyBleHRlbmRzIEdlbmVyaWNPYmplY3QsIFJlc3VsdCwgVENvbnRleHRJZCBleHRlbmRzIENvbnRleHRJZDx1bmtub3duPiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZD4oXG4gIHBhcmFtczogRXZhbEluT2JzaWRpYW5QYXJhbXM8QXJncywgUmVzdWx0LCBUQ29udGV4dElkPlxuKTogUHJvbWlzZTxSZXN1bHQ+IHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC91bmJvdW5kLW1ldGhvZCAtLSBgZm5gIGNhbiBiZSB1bmJvdW5kLlxuICBjb25zdCB7IGFyZ3MgPSB7fSwgY29udGV4dElkLCBmbiwgc2hvdWxkU2tpcFByZWZsaWdodENoZWNrcyA9IGZhbHNlLCB0cmFuc3BvcnQ6IHRyYW5zcG9ydE92ZXJyaWRlLCB2YXVsdFBhdGggfSA9IHBhcmFtcztcbiAgY29uc3QgY3dkID0gdmF1bHRQYXRoID8/IGdldFZhdWx0UGF0aCgpID8/IHByb2Nlc3MuY3dkKCk7XG5cbiAgLy8gQ2hlY2s6IFZhdWx0IHBhdGggZXhpc3RzIG9uIGRpc2suXG4gIGlmICh2YXVsdFBhdGggIT09IHVuZGVmaW5lZCAmJiAhZXhpc3RzU3luYyh2YXVsdFBhdGgpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBWYXVsdCBwYXRoIGRvZXMgbm90IGV4aXN0OiAke3ZhdWx0UGF0aH1gKTtcbiAgfVxuXG4gIGNvbnN0IHRyYW5zcG9ydCA9IHRyYW5zcG9ydE92ZXJyaWRlID8/IGF3YWl0IGdldE9yQ3JlYXRlVHJhbnNwb3J0KGdldFRyYW5zcG9ydE9wdGlvbnMoKSk7XG5cbiAgaWYgKCFzaG91bGRTa2lwUHJlZmxpZ2h0Q2hlY2tzKSB7XG4gICAgYXdhaXQgdHJhbnNwb3J0LnByZWZsaWdodENoZWNrKGN3ZCk7XG4gIH1cblxuICBhd2FpdCBlbnN1cmVOYW1lc3BhY2VCb290c3RyYXBwZWQodHJhbnNwb3J0LCBjd2QpO1xuXG4gIGNvbnN0IG5hbWVzcGFjZUNhbGxQYXJhbXM6IEdlbmVyYXRlTmFtZXNwYWNlQ2FsbFBhcmFtcyA9IHtcbiAgICBhcmdzLFxuICAgIGZuLFxuICAgIC4uLihjb250ZXh0SWQgIT09IHVuZGVmaW5lZCAmJiB7IGNvbnRleHRJZDogU3RyaW5nKGNvbnRleHRJZCkgfSlcbiAgfTtcblxuICBjb25zdCBleHByZXNzaW9uID0gZ2VuZXJhdGVOYW1lc3BhY2VDYWxsKG5hbWVzcGFjZUNhbGxQYXJhbXMpO1xuXG4gIGNvbnN0IHJlc3VsdFN0ciA9IGF3YWl0IHRyYW5zcG9ydC5ldmFsdWF0ZShleHByZXNzaW9uLCB7IGN3ZCB9KTtcblxuICBpZiAocmVzdWx0U3RyID09PSAnJyB8fCByZXN1bHRTdHIgPT09IE5PX09VVFBVVCkge1xuICAgIHJldHVybiB1bmRlZmluZWQgYXMgUmVzdWx0O1xuICB9XG5cbiAgbGV0IGVudmVsb3BlOiBFdmFsUmVzdWx0RW52ZWxvcGU7XG4gIHRyeSB7XG4gICAgZW52ZWxvcGUgPSBKU09OLnBhcnNlKHJlc3VsdFN0cikgYXMgRXZhbFJlc3VsdEVudmVsb3BlO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGV2YWxJbk9ic2lkaWFuOiBPYnNpZGlhbiByZXR1cm5lZCBub24tSlNPTiBvdXRwdXQ6ICR7cmVzdWx0U3RyfWApO1xuICB9XG5cbiAgaWYgKCd0eXBlJyBpbiBlbnZlbG9wZSkge1xuICAgIGlmIChlbnZlbG9wZS50eXBlID09PSAnZXJyb3InKSB7XG4gICAgICAvLyBSZXdyaXRlIGJhcmUtb3JpZ2luIGxvY2FsaG9zdCBzdGFjayBmcmFtZXMgbGlrZSBcIihodHRwOi8vbG9jYWxob3N0Lzo5MTU6MzIpXCJcbiAgICAgIC8vIFNvIFZpdGVzdCdzIHNvdXJjZS1tYXAgcmVzb2x2ZXIgd29uJ3QgZXh0cmFjdCBcIi9cIiBhcyB0aGUgZmlsZSBwYXRoIGFuZCBjcmFzaFxuICAgICAgLy8gV2l0aCBFSVNESVIgd2hlbiBpdCB0cmllcyB0byByZWFkRmlsZVN5bmMgb24gdGhlIHJvb3QgZGlyZWN0b3J5LlxuICAgICAgY29uc3Qgc2FuaXRpemVkRGV0YWlsID0gZW52ZWxvcGUudmFsdWVcbiAgICAgICAgLnJlcGxhY2UoL1xcKGh0dHBzPzpcXC9cXC9sb2NhbGhvc3RcXC86KD88bGluZT5cXGQpL2csICcob2JzaWRpYW4td2VidmlldzokPGxpbmU+Jyk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGV2YWxJbk9ic2lkaWFuOiBFcnJvciBpbnNpZGUgT2JzaWRpYW46XFxuJHtzYW5pdGl6ZWREZXRhaWx9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZCBhcyBSZXN1bHQ7XG4gIH1cblxuICByZXR1cm4gZW52ZWxvcGUudmFsdWUgYXMgUmVzdWx0O1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFjQSxxQkFBMkI7QUFDM0IsMEJBQW9CO0FBU3BCLDhCQUdPO0FBQ1Asb0NBQXNDO0FBQ3RDLGlDQUE0QztBQUM1QywrQkFBcUM7QUEyQnJDLE1BQU0sWUFBWTtBQXVObEIsZUFBc0IsZUFDcEIsUUFDaUI7QUFFakIsUUFBTSxFQUFFLE9BQU8sQ0FBQyxHQUFHLFdBQVcsSUFBSSw0QkFBNEIsT0FBTyxXQUFXLG1CQUFtQixVQUFVLElBQUk7QUFDakgsUUFBTSxNQUFNLGlCQUFhLHNDQUFhLEtBQUssb0JBQUFBLFFBQVEsSUFBSTtBQUd2RCxNQUFJLGNBQWMsVUFBYSxLQUFDLDJCQUFXLFNBQVMsR0FBRztBQUNyRCxVQUFNLElBQUksTUFBTSw4QkFBOEIsU0FBUyxFQUFFO0FBQUEsRUFDM0Q7QUFFQSxRQUFNLFlBQVkscUJBQXFCLFVBQU0sbURBQXFCLDZDQUFvQixDQUFDO0FBRXZGLE1BQUksQ0FBQywyQkFBMkI7QUFDOUIsVUFBTSxVQUFVLGVBQWUsR0FBRztBQUFBLEVBQ3BDO0FBRUEsWUFBTSx3REFBNEIsV0FBVyxHQUFHO0FBRWhELFFBQU0sc0JBQW1EO0FBQUEsSUFDdkQ7QUFBQSxJQUNBO0FBQUEsSUFDQSxHQUFJLGNBQWMsVUFBYSxFQUFFLFdBQVcsT0FBTyxTQUFTLEVBQUU7QUFBQSxFQUNoRTtBQUVBLFFBQU0saUJBQWEscURBQXNCLG1CQUFtQjtBQUU1RCxRQUFNLFlBQVksTUFBTSxVQUFVLFNBQVMsWUFBWSxFQUFFLElBQUksQ0FBQztBQUU5RCxNQUFJLGNBQWMsTUFBTSxjQUFjLFdBQVc7QUFDL0MsV0FBTztBQUFBLEVBQ1Q7QUFFQSxNQUFJO0FBQ0osTUFBSTtBQUNGLGVBQVcsS0FBSyxNQUFNLFNBQVM7QUFBQSxFQUNqQyxRQUFRO0FBQ04sVUFBTSxJQUFJLE1BQU0sc0RBQXNELFNBQVMsRUFBRTtBQUFBLEVBQ25GO0FBRUEsTUFBSSxVQUFVLFVBQVU7QUFDdEIsUUFBSSxTQUFTLFNBQVMsU0FBUztBQUk3QixZQUFNLGtCQUFrQixTQUFTLE1BQzlCLFFBQVEseUNBQXlDLDJCQUEyQjtBQUMvRSxZQUFNLElBQUksTUFBTTtBQUFBLEVBQTJDLGVBQWUsRUFBRTtBQUFBLElBQzlFO0FBRUEsV0FBTztBQUFBLEVBQ1Q7QUFFQSxTQUFPLFNBQVM7QUFDbEI7IiwKICAibmFtZXMiOiBbInByb2Nlc3MiXQp9Cg==
|