@dbx-tools/appkit-mastra 0.6.9 → 0.6.10

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.
@@ -3,28 +3,23 @@
3
3
  *
4
4
  * Databricks AI Tools (`databricks aitools`) are Databricks-owned Agent-Skill
5
5
  * (`SKILL.md`) trees installed and kept up to date through the Databricks CLI.
6
- * The CLI installs them globally under `~/.databricks/aitools/skills/<name>/`
7
- * (with a `.state.json` manifest) and can also write a resolved, agent-agnostic
8
- * copy to any directory with `databricks aitools install --path <dir>
9
- * --skills-only`.
10
- *
11
- * {@link provisionDatabricksAITools} folds those skills into a Mastra workspace
12
- * as extra LOCAL skill scan paths so an agent can use them without anyone
13
- * hand-copying `SKILL.md` files. It never reimplements the CLI's sourcing: it
14
- * either points Mastra at the already-installed global tree, or shells out to
15
- * the CLI to materialize a curated subset into a temp dir.
6
+ * {@link provisionDatabricksAITools} shells out to the CLI
7
+ * (`databricks aitools install --path <dir>`) to materialize a resolved,
8
+ * agent-agnostic skill set into a directory, then hands it to Mastra as an
9
+ * extra LOCAL skill scan path - so an agent gets first-class Databricks skills
10
+ * without anyone hand-copying `SKILL.md` files. It never reimplements the CLI's
11
+ * sourcing; the CLI is the source of truth.
16
12
  *
17
13
  * The option is `false | true | "auto" | DatabricksAIToolsOptions`:
18
14
  *
19
15
  * - `false` (default) - off.
20
- * - `"auto"` - enable only when the global tree already exists OR the
21
- * `databricks` CLI is resolvable; otherwise silently no-op. The "on if the
22
- * CLI is around" default.
23
- * - `true` - required: fail startup (subject to `failOnError`) when neither the
24
- * installed tree nor the CLI can supply skills.
25
- * - an options bag for a specific `skills` subset, `experimental` skills, a
26
- * `refresh` that re-runs the CLI even when a tree exists, or an explicit
27
- * `path`.
16
+ * - `"auto"` - run the CLI when it's installed; if the `databricks` CLI isn't
17
+ * available, log and move on (never fails startup). The "on if the CLI is
18
+ * around" default.
19
+ * - `true` (`"require"`) - require the CLI: fail startup (subject to
20
+ * `failOnError`) when it isn't available or produces nothing.
21
+ * - an options bag for a specific `skills` subset, `experimental` skills, an
22
+ * explicit output `path`, or a custom `cli` path.
28
23
  *
29
24
  * @module
30
25
  */
@@ -33,22 +28,17 @@ export type DatabricksAIToolsMode = "auto" | "require";
33
28
  /** Options for {@link provisionDatabricksAITools}. */
34
29
  export interface DatabricksAIToolsOptions {
35
30
  /**
36
- * `"auto"` (default) enables only when the installed tree exists or the CLI
37
- * is resolvable; `"require"` fails startup when neither can supply skills.
31
+ * `"auto"` (default) runs the CLI when installed and logs-and-continues when
32
+ * it isn't; `"require"` fails startup when the CLI can't supply skills.
38
33
  */
39
34
  mode?: DatabricksAIToolsMode;
40
35
  /** Install only these skill names (comma/space list or array). */
41
36
  skills?: string | string[];
42
37
  /** Include experimental skills when the CLI has to fetch. */
43
38
  experimental?: boolean;
44
- /**
45
- * Re-run the CLI to (re)materialize skills into a fresh dir even when the
46
- * global tree already exists. Defaults to `false` (reuse the installed tree).
47
- */
48
- refresh?: boolean;
49
39
  /**
50
40
  * Explicit directory to materialize skills into with the CLI. Defaults to a
51
- * temp dir. Ignored when the installed global tree is used as-is.
41
+ * fresh {@link localFS.tmpFS} root.
52
42
  */
53
43
  path?: string;
54
44
  /** Absolute path to the `databricks` CLI. Defaults to `databricks` on PATH. */
@@ -66,7 +56,7 @@ export interface ProvisionedDatabricksAITools {
66
56
  /** Extra LOCAL skill scan paths to hand Mastra. Empty when disabled/unresolved. */
67
57
  localSkillPaths: string[];
68
58
  /** How the skills were sourced, for logging. */
69
- source?: "installed" | "cli";
59
+ source?: "cli";
70
60
  }
71
61
  /** Normalize the `databricksAITools` option into a flat options bag, or `undefined` when off. */
72
62
  export declare function normalizeDatabricksAIToolsOption(option: DatabricksAIToolsOption | undefined): DatabricksAIToolsOptions | undefined;
@@ -3,42 +3,35 @@
3
3
  *
4
4
  * Databricks AI Tools (`databricks aitools`) are Databricks-owned Agent-Skill
5
5
  * (`SKILL.md`) trees installed and kept up to date through the Databricks CLI.
6
- * The CLI installs them globally under `~/.databricks/aitools/skills/<name>/`
7
- * (with a `.state.json` manifest) and can also write a resolved, agent-agnostic
8
- * copy to any directory with `databricks aitools install --path <dir>
9
- * --skills-only`.
10
- *
11
- * {@link provisionDatabricksAITools} folds those skills into a Mastra workspace
12
- * as extra LOCAL skill scan paths so an agent can use them without anyone
13
- * hand-copying `SKILL.md` files. It never reimplements the CLI's sourcing: it
14
- * either points Mastra at the already-installed global tree, or shells out to
15
- * the CLI to materialize a curated subset into a temp dir.
6
+ * {@link provisionDatabricksAITools} shells out to the CLI
7
+ * (`databricks aitools install --path <dir>`) to materialize a resolved,
8
+ * agent-agnostic skill set into a directory, then hands it to Mastra as an
9
+ * extra LOCAL skill scan path - so an agent gets first-class Databricks skills
10
+ * without anyone hand-copying `SKILL.md` files. It never reimplements the CLI's
11
+ * sourcing; the CLI is the source of truth.
16
12
  *
17
13
  * The option is `false | true | "auto" | DatabricksAIToolsOptions`:
18
14
  *
19
15
  * - `false` (default) - off.
20
- * - `"auto"` - enable only when the global tree already exists OR the
21
- * `databricks` CLI is resolvable; otherwise silently no-op. The "on if the
22
- * CLI is around" default.
23
- * - `true` - required: fail startup (subject to `failOnError`) when neither the
24
- * installed tree nor the CLI can supply skills.
25
- * - an options bag for a specific `skills` subset, `experimental` skills, a
26
- * `refresh` that re-runs the CLI even when a tree exists, or an explicit
27
- * `path`.
16
+ * - `"auto"` - run the CLI when it's installed; if the `databricks` CLI isn't
17
+ * available, log and move on (never fails startup). The "on if the CLI is
18
+ * around" default.
19
+ * - `true` (`"require"`) - require the CLI: fail startup (subject to
20
+ * `failOnError`) when it isn't available or produces nothing.
21
+ * - an options bag for a specific `skills` subset, `experimental` skills, an
22
+ * explicit output `path`, or a custom `cli` path.
28
23
  *
29
24
  * @module
30
25
  */
31
- import { mkdtemp } from "node:fs/promises";
32
26
  import { existsSync } from "node:fs";
33
- import { homedir, tmpdir } from "node:os";
34
- import { join } from "node:path";
35
- import { spawn } from "@dbx-tools/core";
27
+ import { exec } from "@dbx-tools/core";
28
+ import { localFS } from "@dbx-tools/fs";
36
29
  import { error, log, string } from "@dbx-tools/shared-core";
37
30
  const logger = log.logger("mastra/databricks-aitools");
38
- /** Global skills tree the `databricks aitools` CLI installs into. */
39
- const GLOBAL_AITOOLS_SKILLS_PATH = join(homedir(), ".databricks", "aitools", "skills");
40
31
  /** The Databricks CLI binary name; resolved on `PATH`. */
41
32
  const DATABRICKS_CLI = "databricks";
33
+ /** Stable temp directory the CLI's skill tree is rebuilt into each boot. */
34
+ const SKILLS_CACHE_DIR = "databricks-aitools";
42
35
  /* ------------------------------- helpers ------------------------------- */
43
36
  /** Normalize the `databricksAITools` option into a flat options bag, or `undefined` when off. */
44
37
  export function normalizeDatabricksAIToolsOption(option) {
@@ -67,30 +60,22 @@ export async function provisionDatabricksAITools(option) {
67
60
  return empty;
68
61
  const mode = options.mode ?? "auto";
69
62
  const failOnError = options.failOnError ?? mode === "require";
70
- const wantsCliFetch = options.refresh === true ||
71
- options.path !== undefined ||
72
- string.parseList(options.skills).length > 0 ||
73
- options.experimental === true;
74
63
  try {
75
- // Fast path: reuse the already-installed global tree, no CLI call.
76
- if (!wantsCliFetch && installedTreeExists()) {
77
- logger.debug("using installed aitools tree", { path: GLOBAL_AITOOLS_SKILLS_PATH });
78
- return { localSkillPaths: [GLOBAL_AITOOLS_SKILLS_PATH], source: "installed" };
79
- }
64
+ // The `databricks` CLI is the source of truth. When it's resolvable, run
65
+ // `databricks aitools install --path <dir>` to materialize a fresh,
66
+ // agent-agnostic skill set into a dir Mastra can scan.
80
67
  const cliPath = await resolveCli(options.cli);
81
68
  if (cliPath) {
82
69
  const dir = await materializeViaCli(cliPath, options);
83
70
  if (dir)
84
71
  return { localSkillPaths: [dir], source: "cli" };
85
72
  }
86
- // Nothing fetched. Fall back to the installed tree if it's there.
87
- if (installedTreeExists()) {
88
- return { localSkillPaths: [GLOBAL_AITOOLS_SKILLS_PATH], source: "installed" };
89
- }
73
+ // CLI not installed (or produced nothing). "auto" logs and moves on;
74
+ // "require" fails startup unless `failOnError: false`.
90
75
  if (failOnError) {
91
- throw new Error(`Databricks AI Tools requested but no installed skills tree at "${GLOBAL_AITOOLS_SKILLS_PATH}" and the "${DATABRICKS_CLI}" CLI is not resolvable. Install with \`databricks aitools install\`, or set databricksAITools: "auto".`);
76
+ throw new Error(`Databricks AI Tools required but the "${DATABRICKS_CLI}" CLI is not available. Install the Databricks CLI (\`databricks aitools install\`), or set databricksAITools: "auto".`);
92
77
  }
93
- logger.debug("databricks aitools unavailable; skipping");
78
+ logger.info("databricks CLI not available; skipping AI Tools skills");
94
79
  return empty;
95
80
  }
96
81
  catch (err) {
@@ -101,15 +86,11 @@ export async function provisionDatabricksAITools(option) {
101
86
  return empty;
102
87
  }
103
88
  }
104
- /** Whether the CLI's global skills tree exists and holds at least one skill. */
105
- function installedTreeExists() {
106
- return existsSync(GLOBAL_AITOOLS_SKILLS_PATH);
107
- }
108
89
  /** Resolve the `databricks` CLI, returning its invocation path or `undefined`. */
109
90
  async function resolveCli(cli) {
110
91
  const command = string.trimToNull(cli) ?? DATABRICKS_CLI;
111
92
  try {
112
- const result = await spawn(command, ["aitools", "version"], {
93
+ const result = await exec.spawn(command, ["aitools", "version"], {
113
94
  stdout: "capture",
114
95
  stderr: "capture",
115
96
  check: false,
@@ -123,18 +104,43 @@ async function resolveCli(cli) {
123
104
  return undefined;
124
105
  }
125
106
  /**
126
- * Run `databricks aitools install --path <dir> --skills-only` to materialize a
127
- * resolved, agent-agnostic skill set into a directory (no agents, no state).
107
+ * Run `databricks aitools install --path <dir>` to materialize a resolved,
108
+ * agent-agnostic skill set into a directory (writes `<name>/SKILL.md` trees,
109
+ * no agents, no state) Mastra can then scan.
128
110
  */
129
111
  async function materializeViaCli(cli, options) {
130
- const dir = string.trimToNull(options.path) ?? (await mkdtemp(join(tmpdir(), "databricks-aitools-")));
131
- const args = ["aitools", "install", "--path", dir, "--skills-only"];
112
+ const explicit = string.trimToNull(options.path);
113
+ let dir;
114
+ if (explicit) {
115
+ // An explicit path is the caller's to own - install straight into it.
116
+ await installSkills(cli, options, explicit);
117
+ dir = explicit;
118
+ }
119
+ else {
120
+ // The resolved skill set is the same on almost every boot, so rebuild ONE
121
+ // stable temp tree rather than leaving a fresh scratch dir behind each
122
+ // time. The CLI writes into a throwaway root that only replaces the stable
123
+ // one on success, so a failed install keeps the previous skills usable.
124
+ const stable = await localFS.rebuildFS(SKILLS_CACHE_DIR, (scratch) => installSkills(cli, options, scratch.root));
125
+ dir = stable.root;
126
+ }
127
+ if (!existsSync(dir))
128
+ return undefined;
129
+ logger.debug("materialized aitools skills via CLI", {
130
+ path: dir,
131
+ skills: string.parseList(options.skills),
132
+ });
133
+ return dir;
134
+ }
135
+ /** Run `databricks aitools install --path <dir>`, failing loudly on a non-zero exit. */
136
+ async function installSkills(cli, options, dir) {
137
+ const args = ["aitools", "install", "--path", dir];
132
138
  const skills = string.parseList(options.skills);
133
139
  if (skills.length > 0)
134
140
  args.push("--skills", skills.join(","));
135
141
  if (options.experimental)
136
142
  args.push("--experimental");
137
- const result = await spawn(cli, args, {
143
+ const result = await exec.spawn(cli, args, {
138
144
  stdout: "capture",
139
145
  stderr: "capture",
140
146
  check: false,
@@ -142,9 +148,5 @@ async function materializeViaCli(cli, options) {
142
148
  if (result.exitCode !== 0) {
143
149
  throw new Error(`databricks aitools install failed (exit ${result.exitCode}): ${result.stderr || result.stdout}`);
144
150
  }
145
- if (!existsSync(dir))
146
- return undefined;
147
- logger.debug("materialized aitools skills via CLI", { path: dir, skills });
148
- return dir;
149
151
  }
150
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YWJyaWNrcy1haXRvb2xzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RhdGFicmlja3MtYWl0b29scy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2Qkc7QUFFSCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDM0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNyQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUMxQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4QyxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUU1RCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLDJCQUEyQixDQUFDLENBQUM7QUFFdkQscUVBQXFFO0FBQ3JFLE1BQU0sMEJBQTBCLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFFdkYsMERBQTBEO0FBQzFELE1BQU0sY0FBYyxHQUFHLFlBQVksQ0FBQztBQWdEcEMsNkVBQTZFO0FBRTdFLGlHQUFpRztBQUNqRyxNQUFNLFVBQVUsZ0NBQWdDLENBQzlDLE1BQTJDO0lBRTNDLElBQUksTUFBTSxLQUFLLFNBQVMsSUFBSSxNQUFNLEtBQUssS0FBSztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQy9ELElBQUksTUFBTSxLQUFLLElBQUk7UUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxDQUFDO0lBQ2hELElBQUksTUFBTSxLQUFLLE1BQU07UUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFB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QyxnQkFBZ0IsQ0FBQyxDQUFDO0lBRXRELE1BQU0sTUFBTSxHQUFHLE1BQU0sS0FBSyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUU7UUFDcEMsTUFBTSxFQUFFLFNBQVM7UUFDakIsTUFBTSxFQUFFLFNBQVM7UUFDakIsS0FBSyxFQUFFLEtBQUs7S0FDYixDQUFDLENBQUM7SUFDSCxJQUFJLE1BQU0sQ0FBQyxRQUFRLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDMUIsTUFBTSxJQUFJLEtBQUssQ0FDYiwyQ0FBMkMsTUFBTSxDQUFDLFFBQVEsTUFBTSxNQUFNLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FDakcsQ0FBQztJQUNKLENBQUM7SUFDRCxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQ3ZDLE1BQU0sQ0FBQyxLQUFLLENBQUMscUNBQXFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDM0UsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTdGFydHVwIHByb3Zpc2lvbmluZyBvZiBEYXRhYnJpY2tzIEFJIFRvb2xzIHNraWxscyBmb3IgYSBNYXN0cmEgd29ya3NwYWNlLlxuICpcbiAqIERhdGFicmlja3MgQUkgVG9vbHMgKGBkYXRhYnJpY2tzIGFpdG9vbHNgKSBhcmUgRGF0YWJyaWNrcy1vd25lZCBBZ2VudC1Ta2lsbFxuICogKGBTS0lMTC5tZGApIHRyZWVzIGluc3RhbGxlZCBhbmQga2VwdCB1cCB0byBkYXRlIHRocm91Z2ggdGhlIERhdGFicmlja3MgQ0xJLlxuICogVGhlIENMSSBpbnN0YWxscyB0aGVtIGdsb2JhbGx5IHVuZGVyIGB+Ly5kYXRhYnJpY2tzL2FpdG9vbHMvc2tpbGxzLzxuYW1lPi9gXG4gKiAod2l0aCBhIGAuc3RhdGUuanNvbmAgbWFuaWZlc3QpIGFuZCBjYW4gYWxzbyB3cml0ZSBhIHJlc29sdmVkLCBhZ2VudC1hZ25vc3RpY1xuICogY29weSB0byBhbnkgZGlyZWN0b3J5IHdpdGggYGRhdGFicmlja3MgYWl0b29scyBpbnN0YWxsIC0tcGF0aCA8ZGlyPlxuICogLS1za2lsbHMtb25seWAuXG4gKlxuICoge0BsaW5rIHByb3Zpc2lvbkRhdGFicmlja3NBSVRvb2xzfSBmb2xkcyB0aG9zZSBza2lsbHMgaW50byBhIE1hc3RyYSB3b3Jrc3BhY2VcbiAqIGFzIGV4dHJhIExPQ0FMIHNraWxsIHNjYW4gcGF0aHMgc28gYW4gYWdlbnQgY2FuIHVzZSB0aGVtIHdpdGhvdXQgYW55b25lXG4gKiBoYW5kLWNvcHlpbmcgYFNLSUxMLm1kYCBmaWxlcy4gSXQgbmV2ZXIgcmVpbXBsZW1lbnRzIHRoZSBDTEkncyBzb3VyY2luZzogaXRcbiAqIGVpdGhlciBwb2ludHMgTWFzdHJhIGF0IHRoZSBhbHJlYWR5LWluc3RhbGxlZCBnbG9iYWwgdHJlZSwgb3Igc2hlbGxzIG91dCB0b1xuICogdGhlIENMSSB0byBtYXRlcmlhbGl6ZSBhIGN1cmF0ZWQgc3Vic2V0IGludG8gYSB0ZW1wIGRpci5cbiAqXG4gKiBUaGUgb3B0aW9uIGlzIGBmYWxzZSB8IHRydWUgfCBcImF1dG9cIiB8IERhdGFicmlja3NBSVRvb2xzT3B0aW9uc2A6XG4gKlxuICogLSBgZmFsc2VgIChkZWZhdWx0KSAtIG9mZi5cbiAqIC0gYFwiYXV0b1wiYCAtIGVuYWJsZSBvbmx5IHdoZW4gdGhlIGdsb2JhbCB0cmVlIGFscmVhZHkgZXhpc3RzIE9SIHRoZVxuICogICBgZGF0YWJyaWNrc2AgQ0xJIGlzIHJlc29sdmFibGU7IG90aGVyd2lzZSBzaWxlbnRseSBuby1vcC4gVGhlIFwib24gaWYgdGhlXG4gKiAgIENMSSBpcyBhcm91bmRcIiBkZWZhdWx0LlxuICogLSBgdHJ1ZWAgLSByZXF1aXJlZDogZmFpbCBzdGFydHVwIChzdWJqZWN0IHRvIGBmYWlsT25FcnJvcmApIHdoZW4gbmVpdGhlciB0aGVcbiAqICAgaW5zdGFsbGVkIHRyZWUgbm9yIHRoZSBDTEkgY2FuIHN1cHBseSBza2lsbHMuXG4gKiAtIGFuIG9wdGlvbnMgYmFnIGZvciBhIHNwZWNpZmljIGBza2lsbHNgIHN1YnNldCwgYGV4cGVyaW1lbnRhbGAgc2tpbGxzLCBhXG4gKiAgIGByZWZyZXNoYCB0aGF0IHJlLXJ1bnMgdGhlIENMSSBldmVuIHdoZW4gYSB0cmVlIGV4aXN0cywgb3IgYW4gZXhwbGljaXRcbiAqICAgYHBhdGhgLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBta2R0ZW1wIH0gZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IGV4aXN0c1N5bmMgfSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHsgaG9tZWRpciwgdG1wZGlyIH0gZnJvbSBcIm5vZGU6b3NcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBzcGF3biB9IGZyb20gXCJAZGJ4LXRvb2xzL2NvcmVcIjtcbmltcG9ydCB7IGVycm9yLCBsb2csIHN0cmluZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJtYXN0cmEvZGF0YWJyaWNrcy1haXRvb2xzXCIpO1xuXG4vKiogR2xvYmFsIHNraWxscyB0cmVlIHRoZSBgZGF0YWJyaWNrcyBhaXRvb2xzYCBDTEkgaW5zdGFsbHMgaW50by4gKi9cbmNvbnN0IEdMT0JBTF9BSVRPT0xTX1NLSUxMU19QQVRIID0gam9pbihob21lZGlyKCksIFwiLmRhdGFicmlja3NcIiwgXCJhaXRvb2xzXCIsIFwic2tpbGxzXCIpO1xuXG4vKiogVGhlIERhdGFicmlja3MgQ0xJIGJpbmFyeSBuYW1lOyByZXNvbHZlZCBvbiBgUEFUSGAuICovXG5jb25zdCBEQVRBQlJJQ0tTX0NMSSA9IFwiZGF0YWJyaWNrc1wiO1xuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKiogSG93IGFnZ3Jlc3NpdmVseSB0byBlbmFibGUgRGF0YWJyaWNrcyBBSSBUb29scyBza2lsbHMuICovXG5leHBvcnQgdHlwZSBEYXRhYnJpY2tzQUlUb29sc01vZGUgPSBcImF1dG9cIiB8IFwicmVxdWlyZVwiO1xuXG4vKiogT3B0aW9ucyBmb3Ige0BsaW5rIHByb3Zpc2lvbkRhdGFicmlja3NBSVRvb2xzfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YWJyaWNrc0FJVG9vbHNPcHRpb25zIHtcbiAgLyoqXG4gICAqIGBcImF1dG9cImAgKGRlZmF1bHQpIGVuYWJsZXMgb25seSB3aGVuIHRoZSBpbnN0YWxsZWQgdHJlZSBleGlzdHMgb3IgdGhlIENMSVxuICAgKiBpcyByZXNvbHZhYmxlOyBgXCJyZXF1aXJlXCJgIGZhaWxzIHN0YXJ0dXAgd2hlbiBuZWl0aGVyIGNhbiBzdXBwbHkgc2tpbGxzLlxuICAgKi9cbiAgbW9kZT86IERhdGFicmlja3NBSVRvb2xzTW9kZTtcbiAgLyoqIEluc3RhbGwgb25seSB0aGVzZSBza2lsbCBuYW1lcyAoY29tbWEvc3BhY2UgbGlzdCBvciBhcnJheSkuICovXG4gIHNraWxscz86IHN0cmluZyB8IHN0cmluZ1tdO1xuICAvKiogSW5jbHVkZSBleHBlcmltZW50YWwgc2tpbGxzIHdoZW4gdGhlIENMSSBoYXMgdG8gZmV0Y2guICovXG4gIGV4cGVyaW1lbnRhbD86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBSZS1ydW4gdGhlIENMSSB0byAocmUpbWF0ZXJpYWxpemUgc2tpbGxzIGludG8gYSBmcmVzaCBkaXIgZXZlbiB3aGVuIHRoZVxuICAgKiBnbG9iYWwgdHJlZSBhbHJlYWR5IGV4aXN0cy4gRGVmYXVsdHMgdG8gYGZhbHNlYCAocmV1c2UgdGhlIGluc3RhbGxlZCB0cmVlKS5cbiAgICovXG4gIHJlZnJlc2g/OiBib29sZWFuO1xuICAvKipcbiAgICogRXhwbGljaXQgZGlyZWN0b3J5IHRvIG1hdGVyaWFsaXplIHNraWxscyBpbnRvIHdpdGggdGhlIENMSS4gRGVmYXVsdHMgdG8gYVxuICAgKiB0ZW1wIGRpci4gSWdub3JlZCB3aGVuIHRoZSBpbnN0YWxsZWQgZ2xvYmFsIHRyZWUgaXMgdXNlZCBhcy1pcy5cbiAgICovXG4gIHBhdGg/OiBzdHJpbmc7XG4gIC8qKiBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBgZGF0YWJyaWNrc2AgQ0xJLiBEZWZhdWx0cyB0byBgZGF0YWJyaWNrc2Agb24gUEFUSC4gKi9cbiAgY2xpPzogc3RyaW5nO1xuICAvKipcbiAgICogRmFpbCBhcHAgc3RhcnR1cCB3aGVuIHJlcXVpcmVkIHNraWxscyBjYW4ndCBiZSBwcm92aXNpb25lZC4gRGVmYXVsdHMgdG9cbiAgICogYHRydWVgIGZvciBgbW9kZTogXCJyZXF1aXJlXCJgIGFuZCBgZmFsc2VgIGZvciBgXCJhdXRvXCJgLlxuICAgKi9cbiAgZmFpbE9uRXJyb3I/OiBib29sZWFuO1xufVxuXG4vKiogVGhlIGBkYXRhYnJpY2tzQUlUb29sc2AgY29uZmlnIG9wdGlvbjogYSB0b2dnbGUsIGBcImF1dG9cImAsIG9yIGFuIG9wdGlvbnMgYmFnLiAqL1xuZXhwb3J0IHR5cGUgRGF0YWJyaWNrc0FJVG9vbHNPcHRpb24gPSBib29sZWFuIHwgXCJhdXRvXCIgfCBEYXRhYnJpY2tzQUlUb29sc09wdGlvbnM7XG5cbi8qKiBXaGF0IHtAbGluayBwcm92aXNpb25EYXRhYnJpY2tzQUlUb29sc30gcmVzb2x2ZWQuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb3Zpc2lvbmVkRGF0YWJyaWNrc0FJVG9vbHMge1xuICAvKiogRXh0cmEgTE9DQUwgc2tpbGwgc2NhbiBwYXRocyB0byBoYW5kIE1hc3RyYS4gRW1wdHkgd2hlbiBkaXNhYmxlZC91bnJlc29sdmVkLiAqL1xuICBsb2NhbFNraWxsUGF0aHM6IHN0cmluZ1tdO1xuICAvKiogSG93IHRoZSBza2lsbHMgd2VyZSBzb3VyY2VkLCBmb3IgbG9nZ2luZy4gKi9cbiAgc291cmNlPzogXCJpbnN0YWxsZWRcIiB8IFwiY2xpXCI7XG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gaGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qKiBOb3JtYWxpemUgdGhlIGBkYXRhYnJpY2tzQUlUb29sc2Agb3B0aW9uIGludG8gYSBmbGF0IG9wdGlvbnMgYmFnLCBvciBgdW5kZWZpbmVkYCB3aGVuIG9mZi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVEYXRhYnJpY2tzQUlUb29sc09wdGlvbihcbiAgb3B0aW9uOiBEYXRhYnJpY2tzQUlUb29sc09wdGlvbiB8IHVuZGVmaW5lZCxcbik6IERhdGFicmlja3NBSVRvb2xzT3B0aW9ucyB8IHVuZGVmaW5lZCB7XG4gIGlmIChvcHRpb24gPT09IHVuZGVmaW5lZCB8fCBvcHRpb24gPT09IGZhbHNlKSByZXR1cm4gdW5kZWZpbmVkO1xuICBpZiAob3B0aW9uID09PSB0cnVlKSByZXR1cm4geyBtb2RlOiBcInJlcXVpcmVcIiB9O1xuICBpZiAob3B0aW9uID09PSBcImF1dG9cIikgcmV0dXJuIHsgbW9kZTogXCJhdXRvXCIgfTtcbiAgcmV0dXJuIHsgbW9kZTogb3B0aW9uLm1vZGUgPz8gXCJhdXRvXCIsIC4uLm9wdGlvbiB9O1xufVxuXG4vKipcbiAqIE1hdGVyaWFsaXplIERhdGFicmlja3MgQUkgVG9vbHMgc2tpbGxzIGF0IGFwcCBzdGFydHVwIGFuZCByZXR1cm4gdGhlbSBhc1xuICogZXh0cmEgbG9jYWwgc2tpbGwgc2NhbiBwYXRocy5cbiAqXG4gKiBSZXNvbHV0aW9uOiByZXVzZSB0aGUgaW5zdGFsbGVkIGdsb2JhbCB0cmVlIHdoZW4gcHJlc2VudCAobm8gQ0xJIGNhbGwpIHVubGVzc1xuICogYHJlZnJlc2hgL2Bza2lsbHNgL2BwYXRoYCBhc2sgZm9yIGEgZnJlc2ggQ0xJIG1hdGVyaWFsaXphdGlvbjsgb3RoZXJ3aXNlIHJ1blxuICogYGRhdGFicmlja3MgYWl0b29scyBpbnN0YWxsIC0tcGF0aCA8ZGlyPiAtLXNraWxscy1vbmx5YCB3aGVuIHRoZSBDTEkgcmVzb2x2ZXMuXG4gKiBBIGBcInJlcXVpcmVcImAgcHJvdmlzaW9uIHRoYXQgeWllbGRzIG5vdGhpbmcgZmFpbHMgc3RhcnR1cCB1bmxlc3NcbiAqIGBmYWlsT25FcnJvcjogZmFsc2VgLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHJvdmlzaW9uRGF0YWJyaWNrc0FJVG9vbHMoXG4gIG9wdGlvbjogRGF0YWJyaWNrc0FJVG9vbHNPcHRpb24gfCB1bmRlZmluZWQsXG4pOiBQcm9taXNlPFByb3Zpc2lvbmVkRGF0YWJyaWNrc0FJVG9vbHM+IHtcbiAgY29uc3Qgb3B0aW9ucyA9IG5vcm1hbGl6ZURhdGFicmlja3NBSVRvb2xzT3B0aW9uKG9wdGlvbik7XG4gIGNvbnN0IGVtcHR5OiBQcm92aXNpb25lZERhdGFicmlja3NBSVRvb2xzID0geyBsb2NhbFNraWxsUGF0aHM6IFtdIH07XG4gIGlmICghb3B0aW9ucykgcmV0dXJuIGVtcHR5O1xuXG4gIGNvbnN0IG1vZGUgPSBvcHRpb25zLm1vZGUgPz8gXCJhdXRvXCI7XG4gIGNvbnN0IGZhaWxPbkVycm9yID0gb3B0aW9ucy5mYWlsT25FcnJvciA/PyBtb2RlID09PSBcInJlcXVpcmVcIjtcbiAgY29uc3Qgd2FudHNDbGlGZXRjaCA9XG4gICAgb3B0aW9ucy5yZWZyZXNoID09PSB0cnVlIHx8XG4gICAgb3B0aW9ucy5wYXRoICE9PSB1bmRlZmluZWQgfHxcbiAgICBzdHJpbmcucGFyc2VMaXN0KG9wdGlvbnMuc2tpbGxzKS5sZW5ndGggPiAwIHx8XG4gICAgb3B0aW9ucy5leHBlcmltZW50YWwgPT09IHRydWU7XG5cbiAgdHJ5IHtcbiAgICAvLyBGYXN0IHBhdGg6IHJldXNlIHRoZSBhbHJlYWR5LWluc3RhbGxlZCBnbG9iYWwgdHJlZSwgbm8gQ0xJIGNhbGwuXG4gICAgaWYgKCF3YW50c0NsaUZldGNoICYmIGluc3RhbGxlZFRyZWVFeGlzdHMoKSkge1xuICAgICAgbG9nZ2VyLmRlYnVnKFwidXNpbmcgaW5zdGFsbGVkIGFpdG9vbHMgdHJlZVwiLCB7IHBhdGg6IEdMT0JBTF9BSVRPT0xTX1NLSUxMU19QQVRIIH0pO1xuICAgICAgcmV0dXJuIHsgbG9jYWxTa2lsbFBhdGhzOiBbR0xPQkFMX0FJVE9PTFNfU0tJTExTX1BBVEhdLCBzb3VyY2U6IFwiaW5zdGFsbGVkXCIgfTtcbiAgICB9XG5cbiAgICBjb25zdCBjbGlQYXRoID0gYXdhaXQgcmVzb2x2ZUNsaShvcHRpb25zLmNsaSk7XG4gICAgaWYgKGNsaVBhdGgpIHtcbiAgICAgIGNvbnN0IGRpciA9IGF3YWl0IG1hdGVyaWFsaXplVmlhQ2xpKGNsaVBhdGgsIG9wdGlvbnMpO1xuICAgICAgaWYgKGRpcikgcmV0dXJuIHsgbG9jYWxTa2lsbFBhdGhzOiBbZGlyXSwgc291cmNlOiBcImNsaVwiIH07XG4gICAgfVxuXG4gICAgLy8gTm90aGluZyBmZXRjaGVkLiBGYWxsIGJhY2sgdG8gdGhlIGluc3RhbGxlZCB0cmVlIGlmIGl0J3MgdGhlcmUuXG4gICAgaWYgKGluc3RhbGxlZFRyZWVFeGlzdHMoKSkge1xuICAgICAgcmV0dXJuIHsgbG9jYWxTa2lsbFBhdGhzOiBbR0xPQkFMX0FJVE9PTFNfU0tJTExTX1BBVEhdLCBzb3VyY2U6IFwiaW5zdGFsbGVkXCIgfTtcbiAgICB9XG5cbiAgICBpZiAoZmFpbE9uRXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYERhdGFicmlja3MgQUkgVG9vbHMgcmVxdWVzdGVkIGJ1dCBubyBpbnN0YWxsZWQgc2tpbGxzIHRyZWUgYXQgXCIke0dMT0JBTF9BSVRPT0xTX1NLSUxMU19QQVRIfVwiIGFuZCB0aGUgXCIke0RBVEFCUklDS1NfQ0xJfVwiIENMSSBpcyBub3QgcmVzb2x2YWJsZS4gSW5zdGFsbCB3aXRoIFxcYGRhdGFicmlja3MgYWl0b29scyBpbnN0YWxsXFxgLCBvciBzZXQgZGF0YWJyaWNrc0FJVG9vbHM6IFwiYXV0b1wiLmAsXG4gICAgICApO1xuICAgIH1cbiAgICBsb2dnZXIuZGVidWcoXCJkYXRhYnJpY2tzIGFpdG9vbHMgdW5hdmFpbGFibGU7IHNraXBwaW5nXCIpO1xuICAgIHJldHVybiBlbXB0eTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgaWYgKGZhaWxPbkVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBmYWlsZWQgdG8gcHJvdmlzaW9uIERhdGFicmlja3MgQUkgVG9vbHMgc2tpbGxzOiAke2Vycm9yLmVycm9yTWVzc2FnZShlcnIpfWAsXG4gICAgICAgIHsgY2F1c2U6IGVycm9yLnRvRXJyb3IoZXJyKSB9LFxuICAgICAgKTtcbiAgICB9XG4gICAgbG9nZ2VyLndhcm4oXCJza2lwcGVkXCIsIHsgZXJyb3I6IGVycm9yLmVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgIHJldHVybiBlbXB0eTtcbiAgfVxufVxuXG4vKiogV2hldGhlciB0aGUgQ0xJJ3MgZ2xvYmFsIHNraWxscyB0cmVlIGV4aXN0cyBhbmQgaG9sZHMgYXQgbGVhc3Qgb25lIHNraWxsLiAqL1xuZnVuY3Rpb24gaW5zdGFsbGVkVHJlZUV4aXN0cygpOiBib29sZWFuIHtcbiAgcmV0dXJuIGV4aXN0c1N5bmMoR0xPQkFMX0FJVE9PTFNfU0tJTExTX1BBVEgpO1xufVxuXG4vKiogUmVzb2x2ZSB0aGUgYGRhdGFicmlja3NgIENMSSwgcmV0dXJuaW5nIGl0cyBpbnZvY2F0aW9uIHBhdGggb3IgYHVuZGVmaW5lZGAuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlQ2xpKGNsaTogc3RyaW5nIHwgdW5kZWZpbmVkKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgY29tbWFuZCA9IHN0cmluZy50cmltVG9OdWxsKGNsaSkgPz8gREFUQUJSSUNLU19DTEk7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3Bhd24oY29tbWFuZCwgW1wiYWl0b29sc1wiLCBcInZlcnNpb25cIl0sIHtcbiAgICAgIHN0ZG91dDogXCJjYXB0dXJlXCIsXG4gICAgICBzdGRlcnI6IFwiY2FwdHVyZVwiLFxuICAgICAgY2hlY2s6IGZhbHNlLFxuICAgIH0pO1xuICAgIGlmIChyZXN1bHQuZXhpdENvZGUgPT09IDApIHJldHVybiBjb21tYW5kO1xuICB9IGNhdGNoIHtcbiAgICAvLyBDTEkgYWJzZW50IG9yIGBhaXRvb2xzYCB1bnN1cHBvcnRlZCAtIGNhbGxlciBmYWxscyBiYWNrIC8gZmFpbHMuXG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSdW4gYGRhdGFicmlja3MgYWl0b29scyBpbnN0YWxsIC0tcGF0aCA8ZGlyPiAtLXNraWxscy1vbmx5YCB0byBtYXRlcmlhbGl6ZSBhXG4gKiByZXNvbHZlZCwgYWdlbnQtYWdub3N0aWMgc2tpbGwgc2V0IGludG8gYSBkaXJlY3RvcnkgKG5vIGFnZW50cywgbm8gc3RhdGUpLlxuICovXG5hc3luYyBmdW5jdGlvbiBtYXRlcmlhbGl6ZVZpYUNsaShcbiAgY2xpOiBzdHJpbmcsXG4gIG9wdGlvbnM6IERhdGFicmlja3NBSVRvb2xzT3B0aW9ucyxcbik6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IGRpciA9XG4gICAgc3RyaW5nLnRyaW1Ub051bGwob3B0aW9ucy5wYXRoKSA/PyAoYXdhaXQgbWtkdGVtcChqb2luKHRtcGRpcigpLCBcImRhdGFicmlja3MtYWl0b29scy1cIikpKTtcbiAgY29uc3QgYXJncyA9IFtcImFpdG9vbHNcIiwgXCJpbnN0YWxsXCIsIFwiLS1wYXRoXCIsIGRpciwgXCItLXNraWxscy1vbmx5XCJdO1xuICBjb25zdCBza2lsbHMgPSBzdHJpbmcucGFyc2VMaXN0KG9wdGlvbnMuc2tpbGxzKTtcbiAgaWYgKHNraWxscy5sZW5ndGggPiAwKSBhcmdzLnB1c2goXCItLXNraWxsc1wiLCBza2lsbHMuam9pbihcIixcIikpO1xuICBpZiAob3B0aW9ucy5leHBlcmltZW50YWwpIGFyZ3MucHVzaChcIi0tZXhwZXJpbWVudGFsXCIpO1xuXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNwYXduKGNsaSwgYXJncywge1xuICAgIHN0ZG91dDogXCJjYXB0dXJlXCIsXG4gICAgc3RkZXJyOiBcImNhcHR1cmVcIixcbiAgICBjaGVjazogZmFsc2UsXG4gIH0pO1xuICBpZiAocmVzdWx0LmV4aXRDb2RlICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYGRhdGFicmlja3MgYWl0b29scyBpbnN0YWxsIGZhaWxlZCAoZXhpdCAke3Jlc3VsdC5leGl0Q29kZX0pOiAke3Jlc3VsdC5zdGRlcnIgfHwgcmVzdWx0LnN0ZG91dH1gLFxuICAgICk7XG4gIH1cbiAgaWYgKCFleGlzdHNTeW5jKGRpcikpIHJldHVybiB1bmRlZmluZWQ7XG4gIGxvZ2dlci5kZWJ1ZyhcIm1hdGVyaWFsaXplZCBhaXRvb2xzIHNraWxscyB2aWEgQ0xJXCIsIHsgcGF0aDogZGlyLCBza2lsbHMgfSk7XG4gIHJldHVybiBkaXI7XG59XG4iXX0=
152
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YWJyaWNrcy1haXRvb2xzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RhdGFicmlja3MtYWl0b29scy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0JHO0FBRUgsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNyQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4QyxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUU1RCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLDJCQUEyQixDQUFDLENBQUM7QUFFdkQsMERBQTBEO0FBQzFELE1BQU0sY0FBYyxHQUFHLFlBQVksQ0FBQztBQUVwQyw0RUFBNEU7QUFDNUUsTUFBTSxnQkFBZ0IsR0FBRyxvQkFBb0IsQ0FBQztBQTJDOUMsNkVBQTZFO0FBRTdFLGlHQUFpRztBQUNqRyxNQUFNLFVBQVUsZ0NBQWdDLENBQzlDLE1BQTJDO0lBRTNDLElBQUksTUFBTSxLQUFLLFNBQVMsSUFBSSxNQUFNLEtBQUssS0FBSztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQy9ELElBQUksTUFBTSxLQUFLLElBQUk7UUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxDQUFDO0lBQ2hELElBQUksTUFBTSxLQUFLLE1BQU07UUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDO0lBQy9DLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksSUFBSSxNQUFNLEVBQUUsR0FBRyxNQUFNLEVBQUUsQ0FBQztBQUNwRCxDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSwwQkFBMEIsQ0FD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ekMsTUFBTSxFQUFFLFNBQVM7UUFDakIsTUFBTSxFQUFFLFNBQVM7UUFDakIsS0FBSyxFQUFFLEtBQUs7S0FDYixDQUFDLENBQUM7SUFDSCxJQUFJLE1BQU0sQ0FBQyxRQUFRLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDMUIsTUFBTSxJQUFJLEtBQUssQ0FDYiwyQ0FBMkMsTUFBTSxDQUFDLFFBQVEsTUFBTSxNQUFNLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FDakcsQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTdGFydHVwIHByb3Zpc2lvbmluZyBvZiBEYXRhYnJpY2tzIEFJIFRvb2xzIHNraWxscyBmb3IgYSBNYXN0cmEgd29ya3NwYWNlLlxuICpcbiAqIERhdGFicmlja3MgQUkgVG9vbHMgKGBkYXRhYnJpY2tzIGFpdG9vbHNgKSBhcmUgRGF0YWJyaWNrcy1vd25lZCBBZ2VudC1Ta2lsbFxuICogKGBTS0lMTC5tZGApIHRyZWVzIGluc3RhbGxlZCBhbmQga2VwdCB1cCB0byBkYXRlIHRocm91Z2ggdGhlIERhdGFicmlja3MgQ0xJLlxuICoge0BsaW5rIHByb3Zpc2lvbkRhdGFicmlja3NBSVRvb2xzfSBzaGVsbHMgb3V0IHRvIHRoZSBDTElcbiAqIChgZGF0YWJyaWNrcyBhaXRvb2xzIGluc3RhbGwgLS1wYXRoIDxkaXI+YCkgdG8gbWF0ZXJpYWxpemUgYSByZXNvbHZlZCxcbiAqIGFnZW50LWFnbm9zdGljIHNraWxsIHNldCBpbnRvIGEgZGlyZWN0b3J5LCB0aGVuIGhhbmRzIGl0IHRvIE1hc3RyYSBhcyBhblxuICogZXh0cmEgTE9DQUwgc2tpbGwgc2NhbiBwYXRoIC0gc28gYW4gYWdlbnQgZ2V0cyBmaXJzdC1jbGFzcyBEYXRhYnJpY2tzIHNraWxsc1xuICogd2l0aG91dCBhbnlvbmUgaGFuZC1jb3B5aW5nIGBTS0lMTC5tZGAgZmlsZXMuIEl0IG5ldmVyIHJlaW1wbGVtZW50cyB0aGUgQ0xJJ3NcbiAqIHNvdXJjaW5nOyB0aGUgQ0xJIGlzIHRoZSBzb3VyY2Ugb2YgdHJ1dGguXG4gKlxuICogVGhlIG9wdGlvbiBpcyBgZmFsc2UgfCB0cnVlIHwgXCJhdXRvXCIgfCBEYXRhYnJpY2tzQUlUb29sc09wdGlvbnNgOlxuICpcbiAqIC0gYGZhbHNlYCAoZGVmYXVsdCkgLSBvZmYuXG4gKiAtIGBcImF1dG9cImAgLSBydW4gdGhlIENMSSB3aGVuIGl0J3MgaW5zdGFsbGVkOyBpZiB0aGUgYGRhdGFicmlja3NgIENMSSBpc24ndFxuICogICBhdmFpbGFibGUsIGxvZyBhbmQgbW92ZSBvbiAobmV2ZXIgZmFpbHMgc3RhcnR1cCkuIFRoZSBcIm9uIGlmIHRoZSBDTEkgaXNcbiAqICAgYXJvdW5kXCIgZGVmYXVsdC5cbiAqIC0gYHRydWVgIChgXCJyZXF1aXJlXCJgKSAtIHJlcXVpcmUgdGhlIENMSTogZmFpbCBzdGFydHVwIChzdWJqZWN0IHRvXG4gKiAgIGBmYWlsT25FcnJvcmApIHdoZW4gaXQgaXNuJ3QgYXZhaWxhYmxlIG9yIHByb2R1Y2VzIG5vdGhpbmcuXG4gKiAtIGFuIG9wdGlvbnMgYmFnIGZvciBhIHNwZWNpZmljIGBza2lsbHNgIHN1YnNldCwgYGV4cGVyaW1lbnRhbGAgc2tpbGxzLCBhblxuICogICBleHBsaWNpdCBvdXRwdXQgYHBhdGhgLCBvciBhIGN1c3RvbSBgY2xpYCBwYXRoLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBleGlzdHNTeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCB7IGV4ZWMgfSBmcm9tIFwiQGRieC10b29scy9jb3JlXCI7XG5pbXBvcnQgeyBsb2NhbEZTIH0gZnJvbSBcIkBkYngtdG9vbHMvZnNcIjtcbmltcG9ydCB7IGVycm9yLCBsb2csIHN0cmluZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJtYXN0cmEvZGF0YWJyaWNrcy1haXRvb2xzXCIpO1xuXG4vKiogVGhlIERhdGFicmlja3MgQ0xJIGJpbmFyeSBuYW1lOyByZXNvbHZlZCBvbiBgUEFUSGAuICovXG5jb25zdCBEQVRBQlJJQ0tTX0NMSSA9IFwiZGF0YWJyaWNrc1wiO1xuXG4vKiogU3RhYmxlIHRlbXAgZGlyZWN0b3J5IHRoZSBDTEkncyBza2lsbCB0cmVlIGlzIHJlYnVpbHQgaW50byBlYWNoIGJvb3QuICovXG5jb25zdCBTS0lMTFNfQ0FDSEVfRElSID0gXCJkYXRhYnJpY2tzLWFpdG9vbHNcIjtcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuLyoqIEhvdyBhZ2dyZXNzaXZlbHkgdG8gZW5hYmxlIERhdGFicmlja3MgQUkgVG9vbHMgc2tpbGxzLiAqL1xuZXhwb3J0IHR5cGUgRGF0YWJyaWNrc0FJVG9vbHNNb2RlID0gXCJhdXRvXCIgfCBcInJlcXVpcmVcIjtcblxuLyoqIE9wdGlvbnMgZm9yIHtAbGluayBwcm92aXNpb25EYXRhYnJpY2tzQUlUb29sc30uICovXG5leHBvcnQgaW50ZXJmYWNlIERhdGFicmlja3NBSVRvb2xzT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBgXCJhdXRvXCJgIChkZWZhdWx0KSBydW5zIHRoZSBDTEkgd2hlbiBpbnN0YWxsZWQgYW5kIGxvZ3MtYW5kLWNvbnRpbnVlcyB3aGVuXG4gICAqIGl0IGlzbid0OyBgXCJyZXF1aXJlXCJgIGZhaWxzIHN0YXJ0dXAgd2hlbiB0aGUgQ0xJIGNhbid0IHN1cHBseSBza2lsbHMuXG4gICAqL1xuICBtb2RlPzogRGF0YWJyaWNrc0FJVG9vbHNNb2RlO1xuICAvKiogSW5zdGFsbCBvbmx5IHRoZXNlIHNraWxsIG5hbWVzIChjb21tYS9zcGFjZSBsaXN0IG9yIGFycmF5KS4gKi9cbiAgc2tpbGxzPzogc3RyaW5nIHwgc3RyaW5nW107XG4gIC8qKiBJbmNsdWRlIGV4cGVyaW1lbnRhbCBza2lsbHMgd2hlbiB0aGUgQ0xJIGhhcyB0byBmZXRjaC4gKi9cbiAgZXhwZXJpbWVudGFsPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIEV4cGxpY2l0IGRpcmVjdG9yeSB0byBtYXRlcmlhbGl6ZSBza2lsbHMgaW50byB3aXRoIHRoZSBDTEkuIERlZmF1bHRzIHRvIGFcbiAgICogZnJlc2gge0BsaW5rIGxvY2FsRlMudG1wRlN9IHJvb3QuXG4gICAqL1xuICBwYXRoPzogc3RyaW5nO1xuICAvKiogQWJzb2x1dGUgcGF0aCB0byB0aGUgYGRhdGFicmlja3NgIENMSS4gRGVmYXVsdHMgdG8gYGRhdGFicmlja3NgIG9uIFBBVEguICovXG4gIGNsaT86IHN0cmluZztcbiAgLyoqXG4gICAqIEZhaWwgYXBwIHN0YXJ0dXAgd2hlbiByZXF1aXJlZCBza2lsbHMgY2FuJ3QgYmUgcHJvdmlzaW9uZWQuIERlZmF1bHRzIHRvXG4gICAqIGB0cnVlYCBmb3IgYG1vZGU6IFwicmVxdWlyZVwiYCBhbmQgYGZhbHNlYCBmb3IgYFwiYXV0b1wiYC5cbiAgICovXG4gIGZhaWxPbkVycm9yPzogYm9vbGVhbjtcbn1cblxuLyoqIFRoZSBgZGF0YWJyaWNrc0FJVG9vbHNgIGNvbmZpZyBvcHRpb246IGEgdG9nZ2xlLCBgXCJhdXRvXCJgLCBvciBhbiBvcHRpb25zIGJhZy4gKi9cbmV4cG9ydCB0eXBlIERhdGFicmlja3NBSVRvb2xzT3B0aW9uID0gYm9vbGVhbiB8IFwiYXV0b1wiIHwgRGF0YWJyaWNrc0FJVG9vbHNPcHRpb25zO1xuXG4vKiogV2hhdCB7QGxpbmsgcHJvdmlzaW9uRGF0YWJyaWNrc0FJVG9vbHN9IHJlc29sdmVkLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm92aXNpb25lZERhdGFicmlja3NBSVRvb2xzIHtcbiAgLyoqIEV4dHJhIExPQ0FMIHNraWxsIHNjYW4gcGF0aHMgdG8gaGFuZCBNYXN0cmEuIEVtcHR5IHdoZW4gZGlzYWJsZWQvdW5yZXNvbHZlZC4gKi9cbiAgbG9jYWxTa2lsbFBhdGhzOiBzdHJpbmdbXTtcbiAgLyoqIEhvdyB0aGUgc2tpbGxzIHdlcmUgc291cmNlZCwgZm9yIGxvZ2dpbmcuICovXG4gIHNvdXJjZT86IFwiY2xpXCI7XG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gaGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qKiBOb3JtYWxpemUgdGhlIGBkYXRhYnJpY2tzQUlUb29sc2Agb3B0aW9uIGludG8gYSBmbGF0IG9wdGlvbnMgYmFnLCBvciBgdW5kZWZpbmVkYCB3aGVuIG9mZi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVEYXRhYnJpY2tzQUlUb29sc09wdGlvbihcbiAgb3B0aW9uOiBEYXRhYnJpY2tzQUlUb29sc09wdGlvbiB8IHVuZGVmaW5lZCxcbik6IERhdGFicmlja3NBSVRvb2xzT3B0aW9ucyB8IHVuZGVmaW5lZCB7XG4gIGlmIChvcHRpb24gPT09IHVuZGVmaW5lZCB8fCBvcHRpb24gPT09IGZhbHNlKSByZXR1cm4gdW5kZWZpbmVkO1xuICBpZiAob3B0aW9uID09PSB0cnVlKSByZXR1cm4geyBtb2RlOiBcInJlcXVpcmVcIiB9O1xuICBpZiAob3B0aW9uID09PSBcImF1dG9cIikgcmV0dXJuIHsgbW9kZTogXCJhdXRvXCIgfTtcbiAgcmV0dXJuIHsgbW9kZTogb3B0aW9uLm1vZGUgPz8gXCJhdXRvXCIsIC4uLm9wdGlvbiB9O1xufVxuXG4vKipcbiAqIE1hdGVyaWFsaXplIERhdGFicmlja3MgQUkgVG9vbHMgc2tpbGxzIGF0IGFwcCBzdGFydHVwIGFuZCByZXR1cm4gdGhlbSBhc1xuICogZXh0cmEgbG9jYWwgc2tpbGwgc2NhbiBwYXRocy5cbiAqXG4gKiBSZXNvbHV0aW9uOiByZXVzZSB0aGUgaW5zdGFsbGVkIGdsb2JhbCB0cmVlIHdoZW4gcHJlc2VudCAobm8gQ0xJIGNhbGwpIHVubGVzc1xuICogYHJlZnJlc2hgL2Bza2lsbHNgL2BwYXRoYCBhc2sgZm9yIGEgZnJlc2ggQ0xJIG1hdGVyaWFsaXphdGlvbjsgb3RoZXJ3aXNlIHJ1blxuICogYGRhdGFicmlja3MgYWl0b29scyBpbnN0YWxsIC0tcGF0aCA8ZGlyPiAtLXNraWxscy1vbmx5YCB3aGVuIHRoZSBDTEkgcmVzb2x2ZXMuXG4gKiBBIGBcInJlcXVpcmVcImAgcHJvdmlzaW9uIHRoYXQgeWllbGRzIG5vdGhpbmcgZmFpbHMgc3RhcnR1cCB1bmxlc3NcbiAqIGBmYWlsT25FcnJvcjogZmFsc2VgLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHJvdmlzaW9uRGF0YWJyaWNrc0FJVG9vbHMoXG4gIG9wdGlvbjogRGF0YWJyaWNrc0FJVG9vbHNPcHRpb24gfCB1bmRlZmluZWQsXG4pOiBQcm9taXNlPFByb3Zpc2lvbmVkRGF0YWJyaWNrc0FJVG9vbHM+IHtcbiAgY29uc3Qgb3B0aW9ucyA9IG5vcm1hbGl6ZURhdGFicmlja3NBSVRvb2xzT3B0aW9uKG9wdGlvbik7XG4gIGNvbnN0IGVtcHR5OiBQcm92aXNpb25lZERhdGFicmlja3NBSVRvb2xzID0geyBsb2NhbFNraWxsUGF0aHM6IFtdIH07XG4gIGlmICghb3B0aW9ucykgcmV0dXJuIGVtcHR5O1xuXG4gIGNvbnN0IG1vZGUgPSBvcHRpb25zLm1vZGUgPz8gXCJhdXRvXCI7XG4gIGNvbnN0IGZhaWxPbkVycm9yID0gb3B0aW9ucy5mYWlsT25FcnJvciA/PyBtb2RlID09PSBcInJlcXVpcmVcIjtcblxuICB0cnkge1xuICAgIC8vIFRoZSBgZGF0YWJyaWNrc2AgQ0xJIGlzIHRoZSBzb3VyY2Ugb2YgdHJ1dGguIFdoZW4gaXQncyByZXNvbHZhYmxlLCBydW5cbiAgICAvLyBgZGF0YWJyaWNrcyBhaXRvb2xzIGluc3RhbGwgLS1wYXRoIDxkaXI+YCB0byBtYXRlcmlhbGl6ZSBhIGZyZXNoLFxuICAgIC8vIGFnZW50LWFnbm9zdGljIHNraWxsIHNldCBpbnRvIGEgZGlyIE1hc3RyYSBjYW4gc2Nhbi5cbiAgICBjb25zdCBjbGlQYXRoID0gYXdhaXQgcmVzb2x2ZUNsaShvcHRpb25zLmNsaSk7XG4gICAgaWYgKGNsaVBhdGgpIHtcbiAgICAgIGNvbnN0IGRpciA9IGF3YWl0IG1hdGVyaWFsaXplVmlhQ2xpKGNsaVBhdGgsIG9wdGlvbnMpO1xuICAgICAgaWYgKGRpcikgcmV0dXJuIHsgbG9jYWxTa2lsbFBhdGhzOiBbZGlyXSwgc291cmNlOiBcImNsaVwiIH07XG4gICAgfVxuXG4gICAgLy8gQ0xJIG5vdCBpbnN0YWxsZWQgKG9yIHByb2R1Y2VkIG5vdGhpbmcpLiBcImF1dG9cIiBsb2dzIGFuZCBtb3ZlcyBvbjtcbiAgICAvLyBcInJlcXVpcmVcIiBmYWlscyBzdGFydHVwIHVubGVzcyBgZmFpbE9uRXJyb3I6IGZhbHNlYC5cbiAgICBpZiAoZmFpbE9uRXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYERhdGFicmlja3MgQUkgVG9vbHMgcmVxdWlyZWQgYnV0IHRoZSBcIiR7REFUQUJSSUNLU19DTEl9XCIgQ0xJIGlzIG5vdCBhdmFpbGFibGUuIEluc3RhbGwgdGhlIERhdGFicmlja3MgQ0xJIChcXGBkYXRhYnJpY2tzIGFpdG9vbHMgaW5zdGFsbFxcYCksIG9yIHNldCBkYXRhYnJpY2tzQUlUb29sczogXCJhdXRvXCIuYCxcbiAgICAgICk7XG4gICAgfVxuICAgIGxvZ2dlci5pbmZvKFwiZGF0YWJyaWNrcyBDTEkgbm90IGF2YWlsYWJsZTsgc2tpcHBpbmcgQUkgVG9vbHMgc2tpbGxzXCIpO1xuICAgIHJldHVybiBlbXB0eTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgaWYgKGZhaWxPbkVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBmYWlsZWQgdG8gcHJvdmlzaW9uIERhdGFicmlja3MgQUkgVG9vbHMgc2tpbGxzOiAke2Vycm9yLmVycm9yTWVzc2FnZShlcnIpfWAsXG4gICAgICAgIHsgY2F1c2U6IGVycm9yLnRvRXJyb3IoZXJyKSB9LFxuICAgICAgKTtcbiAgICB9XG4gICAgbG9nZ2VyLndhcm4oXCJza2lwcGVkXCIsIHsgZXJyb3I6IGVycm9yLmVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgIHJldHVybiBlbXB0eTtcbiAgfVxufVxuXG4vKiogUmVzb2x2ZSB0aGUgYGRhdGFicmlja3NgIENMSSwgcmV0dXJuaW5nIGl0cyBpbnZvY2F0aW9uIHBhdGggb3IgYHVuZGVmaW5lZGAuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlQ2xpKGNsaTogc3RyaW5nIHwgdW5kZWZpbmVkKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgY29tbWFuZCA9IHN0cmluZy50cmltVG9OdWxsKGNsaSkgPz8gREFUQUJSSUNLU19DTEk7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZXhlYy5zcGF3bihjb21tYW5kLCBbXCJhaXRvb2xzXCIsIFwidmVyc2lvblwiXSwge1xuICAgICAgc3Rkb3V0OiBcImNhcHR1cmVcIixcbiAgICAgIHN0ZGVycjogXCJjYXB0dXJlXCIsXG4gICAgICBjaGVjazogZmFsc2UsXG4gICAgfSk7XG4gICAgaWYgKHJlc3VsdC5leGl0Q29kZSA9PT0gMCkgcmV0dXJuIGNvbW1hbmQ7XG4gIH0gY2F0Y2gge1xuICAgIC8vIENMSSBhYnNlbnQgb3IgYGFpdG9vbHNgIHVuc3VwcG9ydGVkIC0gY2FsbGVyIGZhbGxzIGJhY2sgLyBmYWlscy5cbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFJ1biBgZGF0YWJyaWNrcyBhaXRvb2xzIGluc3RhbGwgLS1wYXRoIDxkaXI+YCB0byBtYXRlcmlhbGl6ZSBhIHJlc29sdmVkLFxuICogYWdlbnQtYWdub3N0aWMgc2tpbGwgc2V0IGludG8gYSBkaXJlY3RvcnkgKHdyaXRlcyBgPG5hbWU+L1NLSUxMLm1kYCB0cmVlcyxcbiAqIG5vIGFnZW50cywgbm8gc3RhdGUpIE1hc3RyYSBjYW4gdGhlbiBzY2FuLlxuICovXG5hc3luYyBmdW5jdGlvbiBtYXRlcmlhbGl6ZVZpYUNsaShcbiAgY2xpOiBzdHJpbmcsXG4gIG9wdGlvbnM6IERhdGFicmlja3NBSVRvb2xzT3B0aW9ucyxcbik6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IGV4cGxpY2l0ID0gc3RyaW5nLnRyaW1Ub051bGwob3B0aW9ucy5wYXRoKTtcbiAgbGV0IGRpcjogc3RyaW5nO1xuXG4gIGlmIChleHBsaWNpdCkge1xuICAgIC8vIEFuIGV4cGxpY2l0IHBhdGggaXMgdGhlIGNhbGxlcidzIHRvIG93biAtIGluc3RhbGwgc3RyYWlnaHQgaW50byBpdC5cbiAgICBhd2FpdCBpbnN0YWxsU2tpbGxzKGNsaSwgb3B0aW9ucywgZXhwbGljaXQpO1xuICAgIGRpciA9IGV4cGxpY2l0O1xuICB9IGVsc2Uge1xuICAgIC8vIFRoZSByZXNvbHZlZCBza2lsbCBzZXQgaXMgdGhlIHNhbWUgb24gYWxtb3N0IGV2ZXJ5IGJvb3QsIHNvIHJlYnVpbGQgT05FXG4gICAgLy8gc3RhYmxlIHRlbXAgdHJlZSByYXRoZXIgdGhhbiBsZWF2aW5nIGEgZnJlc2ggc2NyYXRjaCBkaXIgYmVoaW5kIGVhY2hcbiAgICAvLyB0aW1lLiBUaGUgQ0xJIHdyaXRlcyBpbnRvIGEgdGhyb3dhd2F5IHJvb3QgdGhhdCBvbmx5IHJlcGxhY2VzIHRoZSBzdGFibGVcbiAgICAvLyBvbmUgb24gc3VjY2Vzcywgc28gYSBmYWlsZWQgaW5zdGFsbCBrZWVwcyB0aGUgcHJldmlvdXMgc2tpbGxzIHVzYWJsZS5cbiAgICBjb25zdCBzdGFibGUgPSBhd2FpdCBsb2NhbEZTLnJlYnVpbGRGUyhTS0lMTFNfQ0FDSEVfRElSLCAoc2NyYXRjaCkgPT5cbiAgICAgIGluc3RhbGxTa2lsbHMoY2xpLCBvcHRpb25zLCBzY3JhdGNoLnJvb3QpLFxuICAgICk7XG4gICAgZGlyID0gc3RhYmxlLnJvb3Q7XG4gIH1cblxuICBpZiAoIWV4aXN0c1N5bmMoZGlyKSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgbG9nZ2VyLmRlYnVnKFwibWF0ZXJpYWxpemVkIGFpdG9vbHMgc2tpbGxzIHZpYSBDTElcIiwge1xuICAgIHBhdGg6IGRpcixcbiAgICBza2lsbHM6IHN0cmluZy5wYXJzZUxpc3Qob3B0aW9ucy5za2lsbHMpLFxuICB9KTtcbiAgcmV0dXJuIGRpcjtcbn1cblxuLyoqIFJ1biBgZGF0YWJyaWNrcyBhaXRvb2xzIGluc3RhbGwgLS1wYXRoIDxkaXI+YCwgZmFpbGluZyBsb3VkbHkgb24gYSBub24temVybyBleGl0LiAqL1xuYXN5bmMgZnVuY3Rpb24gaW5zdGFsbFNraWxscyhcbiAgY2xpOiBzdHJpbmcsXG4gIG9wdGlvbnM6IERhdGFicmlja3NBSVRvb2xzT3B0aW9ucyxcbiAgZGlyOiBzdHJpbmcsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgYXJncyA9IFtcImFpdG9vbHNcIiwgXCJpbnN0YWxsXCIsIFwiLS1wYXRoXCIsIGRpcl07XG4gIGNvbnN0IHNraWxscyA9IHN0cmluZy5wYXJzZUxpc3Qob3B0aW9ucy5za2lsbHMpO1xuICBpZiAoc2tpbGxzLmxlbmd0aCA+IDApIGFyZ3MucHVzaChcIi0tc2tpbGxzXCIsIHNraWxscy5qb2luKFwiLFwiKSk7XG4gIGlmIChvcHRpb25zLmV4cGVyaW1lbnRhbCkgYXJncy5wdXNoKFwiLS1leHBlcmltZW50YWxcIik7XG5cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZXhlYy5zcGF3bihjbGksIGFyZ3MsIHtcbiAgICBzdGRvdXQ6IFwiY2FwdHVyZVwiLFxuICAgIHN0ZGVycjogXCJjYXB0dXJlXCIsXG4gICAgY2hlY2s6IGZhbHNlLFxuICB9KTtcbiAgaWYgKHJlc3VsdC5leGl0Q29kZSAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBkYXRhYnJpY2tzIGFpdG9vbHMgaW5zdGFsbCBmYWlsZWQgKGV4aXQgJHtyZXN1bHQuZXhpdENvZGV9KTogJHtyZXN1bHQuc3RkZXJyIHx8IHJlc3VsdC5zdGRvdXR9YCxcbiAgICApO1xuICB9XG59XG4iXX0=
@@ -1,208 +1,90 @@
1
1
  /**
2
- * Mastra {@link WorkspaceFilesystem} implementations for Databricks Apps.
2
+ * Mastra workspace filesystem adapters.
3
3
  *
4
- * {@link DatabricksWorkspaceFilesystem} maps a Mastra workspace namespace onto
5
- * an absolute Databricks path (Unity Catalog volume, workspace object tree, or
6
- * DBFS). {@link emptyFilesystem} is a read-only no-op mount used when no
7
- * dynamic mounts resolve for a request.
8
- *
9
- * Path helpers ({@link normalizeDatabricksBasePath}, {@link isDbfsPath}, …)
10
- * are exported for tests and callers that need to reason about Databricks
11
- * paths without constructing a filesystem.
4
+ * {@link filesystems} wraps any portable `@dbx-tools/shared-fs` {@link FileSystem}
5
+ * (local disk, Databricks, memory, …) as a Mastra {@link MastraFilesystem}.
6
+ * {@link scratchFilesystem} always returns a fresh {@link localFS.tmpFS} mount
7
+ * (random id root) when Mastra needs a filesystem and no other mount resolved.
12
8
  *
13
9
  * @module
14
10
  */
15
- import { WorkspaceClient } from "@databricks/sdk-experimental";
11
+ import type { FileSystem } from "@dbx-tools/shared-fs";
16
12
  import { MastraFilesystem } from "@mastra/core/workspace";
17
13
  import type { CopyOptions, FileContent, FileEntry, FileStat, FilesystemInfo, ListOptions, MastraFilesystemOptions, ProviderStatus, ReadOptions, RemoveOptions, WriteOptions } from "@mastra/core/workspace";
18
- /** How {@link DatabricksWorkspaceFilesystem.init} handles a missing {@link basePath}. */
19
- export type DatabricksMkdirsMode = boolean | "try";
20
- /** Options for {@link DatabricksWorkspaceFilesystem}. */
21
- export interface DatabricksWorkspaceFilesystemOptions extends MastraFilesystemOptions {
22
- /** Unique identifier for this filesystem instance. */
14
+ /** Options for {@link filesystems} / {@link MastraFileSystemAdapter}. */
15
+ export interface MastraFileSystemAdapterOptions extends MastraFilesystemOptions {
16
+ /** Override the Mastra filesystem id. Defaults to the source {@link FileSystem.id}. */
23
17
  id?: string;
24
- /** Auth-scoped Databricks workspace client. */
25
- client?: WorkspaceClient;
18
+ /** Override the Mastra display name. Defaults to `MastraFileSystemAdapter`. */
19
+ name?: string;
26
20
  /**
27
- * Absolute Databricks path that roots the workspace namespace, e.g.
28
- * `/Volumes/catalog/schema/volume` or `/dbfs/FileStore/shared`.
21
+ * Override the Mastra provider id. Defaults to the source
22
+ * {@link FileSystem.backend}.
29
23
  */
30
- basePath: string;
24
+ provider?: string;
31
25
  /**
32
- * When the {@link basePath} is missing at {@link init}, create it with the
33
- * matching Databricks `mkdirs` API. `"try"` (default) logs at debug and
34
- * falls back to an empty read-only namespace on failure; `true` fails init;
35
- * `false` skips creation and uses the empty namespace.
36
- *
37
- * A successful mkdir also satisfies the write-access probe when
38
- * {@link readOnly} is omitted.
26
+ * Force read-only mounts even when the source filesystem allows writes.
27
+ * The source {@link FileSystem.readOnly} flag still applies either way.
39
28
  */
40
- mkdirs?: DatabricksMkdirsMode;
41
- /** Block writes while still allowing reads. When omitted, {@link init} probes write access. */
42
29
  readOnly?: boolean;
43
30
  }
44
- /** Normalize a Databricks base path (POSIX, no trailing slash). */
45
- export declare function normalizeDatabricksBasePath(basePath: string): string;
46
- /** True when `absolutePath` is served by DBFS rather than the UC Files API. */
47
- export declare function isDbfsPath(absolutePath: string): boolean;
48
- /** True when `absolutePath` is a Databricks workspace object path. */
49
- export declare function isWorkspaceFilesPath(absolutePath: string): boolean;
50
31
  /**
51
- * Resolve a workspace-relative path to an absolute Databricks path under
52
- * `basePath`.
32
+ * Wrap a portable {@link FileSystem} as a Mastra {@link MastraFilesystem}.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * import { filesystems } from "@dbx-tools/appkit-mastra";
37
+ * import { DatabricksFileSystem } from "@dbx-tools/databricks";
38
+ * import { localFS } from "@dbx-tools/fs";
39
+ *
40
+ * const volume = filesystems.filesystems(
41
+ * new DatabricksFileSystem({ root: "/Volumes/main/default/assets" }),
42
+ * );
43
+ * const scratch = filesystems.filesystems(localFS.tmpFS("agent-job"));
44
+ * ```
53
45
  */
54
- export declare function resolveDatabricksAbsolutePath(basePath: string, inputPath: string): string;
55
- /** Map an absolute Databricks path back to the workspace namespace. */
56
- export declare function toDatabricksWorkspacePath(basePath: string, absolutePath: string): string;
46
+ export declare function filesystems(fs: FileSystem, options?: MastraFileSystemAdapterOptions): MastraFileSystemAdapter;
57
47
  /**
58
- * Mastra filesystem provider that reads and writes through a Databricks
59
- * {@link WorkspaceClient}.
60
- *
61
- * Workspace paths are absolute within the namespace (`/notes.md` maps to
62
- * `<basePath>/notes.md`). Unity Catalog volumes use the Files API;
63
- * `/dbfs/...` paths use DBFS.
48
+ * Thin Mastra {@link MastraFilesystem} adapter over a `@dbx-tools/shared-fs`
49
+ * {@link FileSystem}. Identity fields are getters that read the source on
50
+ * access; construction does not snapshot them.
64
51
  */
65
- export declare class DatabricksWorkspaceFilesystem extends MastraFilesystem {
66
- readonly id: string;
67
- readonly name = "DatabricksWorkspaceFilesystem";
68
- readonly provider = "databricks";
69
- readonly basePath: string;
52
+ export declare class MastraFileSystemAdapter extends MastraFilesystem {
70
53
  status: ProviderStatus;
71
- private readonly client;
72
- private readonly mkdirs;
73
- private _readOnly;
74
- private _basePathMissing;
75
- get readOnly(): boolean | undefined;
76
- /**
77
- * @param options.client - Defaults to the AppKit execution-context client.
78
- * @param options.mkdirs - Default `"try"`; see {@link DatabricksMkdirsMode}.
79
- * @param options.readOnly - When omitted, {@link init} probes write access.
80
- */
81
- constructor(options: DatabricksWorkspaceFilesystemOptions);
82
- /** Resolve and sandbox a workspace-relative path under {@link basePath}. */
83
- private resolvePath;
84
- /** Map a Databricks absolute path back to the workspace namespace. */
85
- private workspacePath;
86
- /** Throw when the filesystem is read-only. */
87
- private assertWritable;
88
- /** Map SDK / HTTP errors to Mastra workspace filesystem errors. */
89
- private rethrow;
90
- /**
91
- * Probe whether {@link basePath} exists and cache the result on
92
- * {@link _basePathMissing}.
93
- */
94
- private resolveBasePathStatus;
95
- /** Delegate to {@link emptyFilesystem} when the base path is missing. */
96
- private emptyFallback;
54
+ private readonly fs;
55
+ private readonly options;
56
+ constructor(fs: FileSystem, options?: MastraFileSystemAdapterOptions);
57
+ get id(): string;
58
+ get name(): string;
59
+ get provider(): string;
60
+ get readOnly(): boolean;
61
+ get basePath(): string;
97
62
  init(): Promise<void>;
98
- /**
99
- * Write and delete a ephemeral probe file to detect read-only access when
100
- * {@link DatabricksWorkspaceFilesystemOptions.readOnly} was not set.
101
- *
102
- * @returns `true` when the probe write (and cleanup) succeeded.
103
- */
104
- private probeReadOnly;
105
63
  destroy(): Promise<void>;
106
- /** Probe that `absolutePath` exists (file or directory metadata). */
107
- private assertAbsoluteReadable;
108
- /** Read the full contents of `absolutePath` from the matching backend. */
109
- private readAbsolute;
110
- /** Write `buffer` to `absolutePath` on the matching backend. */
111
- private writeAbsolute;
112
- /** Upload a buffer to a Unity Catalog Files API path. */
113
- private uploadUcFile;
114
- /** Delete a single file at `absolutePath` (non-recursive). */
115
- private deleteAbsoluteFile;
116
- /**
117
- * Delete a file or directory at `absolutePath`.
118
- *
119
- * DBFS and workspace APIs accept `recursive`; UC volumes recurse manually.
120
- */
121
- private deleteAbsolutePath;
122
- /** Create `absolutePath` and any missing parents on the matching backend. */
123
- private mkdirAbsolute;
124
- private readDbfsFile;
125
- private readWorkspaceFile;
126
- private writeDbfsFile;
127
- private writeWorkspaceFile;
128
64
  getInfo(): FilesystemInfo<{
129
- basePath: string;
65
+ root: string;
66
+ backend: string;
130
67
  }>;
131
68
  getInstructions(): string;
132
- /** Map a workspace-relative path to the backing Databricks absolute path. */
133
- resolveAbsolutePath(inputPath: string): string | undefined;
134
- /** Read file contents from the workspace namespace. */
135
69
  readFile(inputPath: string, options?: ReadOptions): Promise<string | Buffer>;
136
- /** Write file contents into the workspace namespace. */
137
70
  writeFile(inputPath: string, content: FileContent, options?: WriteOptions): Promise<void>;
138
- /** Append to an existing file, creating it when missing. */
139
71
  appendFile(inputPath: string, content: FileContent): Promise<void>;
140
- /** Delete a file in the workspace namespace. */
141
72
  deleteFile(inputPath: string, options?: RemoveOptions): Promise<void>;
142
- /** Copy a file within the workspace namespace. */
143
73
  copyFile(src: string, dest: string, options?: CopyOptions): Promise<void>;
144
- /** Move or rename a file within the workspace namespace. */
145
74
  moveFile(src: string, dest: string, options?: CopyOptions): Promise<void>;
146
- /** Create a directory in the workspace namespace. */
147
75
  mkdir(inputPath: string, options?: {
148
76
  recursive?: boolean;
149
77
  }): Promise<void>;
150
- /** Remove a directory from the workspace namespace. */
151
78
  rmdir(inputPath: string, options?: RemoveOptions): Promise<void>;
152
- /**
153
- * Recursively delete a Unity Catalog directory tree.
154
- *
155
- * DBFS and workspace trees use native recursive delete via
156
- * {@link deleteAbsolutePath} instead.
157
- */
158
- private deleteUcDirectoryRecursive;
159
- /** List entries in a workspace directory. */
160
79
  readdir(inputPath: string, options?: ListOptions): Promise<FileEntry[]>;
161
- private readDirectoryRecursive;
162
- private listAbsoluteDirectory;
163
- /** Apply Mastra list filters (`extension`, etc.) to directory entries. */
164
- private filterEntries;
165
- /** Return whether `inputPath` exists in the workspace namespace. */
166
- exists(inputPath: string): Promise<boolean>;
167
- /** Return file or directory metadata for `inputPath`. */
168
- stat(inputPath: string): Promise<FileStat>;
169
- /**
170
- * Stat a Unity Catalog path by probing file metadata first, then
171
- * directory metadata.
172
- */
173
- private statUcAbsolute;
174
- }
175
- /**
176
- * Read-only in-memory {@link WorkspaceFilesystem} with a single empty root.
177
- * Use {@link emptyFilesystem} rather than constructing directly.
178
- */
179
- declare class EmptyFilesystem extends MastraFilesystem {
180
- readonly id = "empty-fs";
181
- readonly name = "EmptyFilesystem";
182
- readonly provider = "empty";
183
- readonly readOnly = true;
184
- status: ProviderStatus;
185
- constructor();
186
- init(): Promise<void>;
187
- destroy(): Promise<void>;
188
- getInfo(): FilesystemInfo;
189
- getInstructions(): string;
190
- private rootStat;
191
- private assertWritable;
192
- readFile(inputPath: string, _options?: ReadOptions): Promise<string | Buffer>;
193
- writeFile(_inputPath: string, _content: FileContent, _options?: WriteOptions): Promise<void>;
194
- appendFile(_inputPath: string, _content: FileContent): Promise<void>;
195
- deleteFile(inputPath: string, options?: RemoveOptions): Promise<void>;
196
- copyFile(src: string, _dest: string, _options?: CopyOptions): Promise<void>;
197
- moveFile(src: string, dest: string, options?: CopyOptions): Promise<void>;
198
- mkdir(_inputPath: string, _options?: {
199
- recursive?: boolean;
200
- }): Promise<void>;
201
- rmdir(inputPath: string, options?: RemoveOptions): Promise<void>;
202
- readdir(inputPath: string, _options?: ListOptions): Promise<FileEntry[]>;
203
80
  exists(inputPath: string): Promise<boolean>;
204
81
  stat(inputPath: string): Promise<FileStat>;
82
+ private delegate;
83
+ /** {@link delegate} for a mutation: refuse a read-only mount before doing any work. */
84
+ private delegateWrite;
85
+ /** When Mastra asks for non-recursive writes, require the parent directory. */
86
+ private assertParentExists;
87
+ private rethrow;
205
88
  }
206
- /** Memoized singleton empty read-only filesystem for no-op mounts. */
207
- export declare const emptyFilesystem: () => EmptyFilesystem;
208
- export {};
89
+ /** Fresh writable local temp mount on a root unique to this call. */
90
+ export declare function scratchFilesystem(): MastraFileSystemAdapter;