@dbx-tools/core 0.9.19 → 0.9.28

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.
@@ -32,7 +32,12 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
32
32
  import { mkdir, open } from "node:fs/promises";
33
33
  import { tmpdir } from "node:os";
34
34
  import { dirname, join } from "node:path";
35
- import { asyncUtils, errorUtils, functionUtils, hash, log, object } from "@dbx-tools/shared-core";
35
+ import * as asyncUtils from "@dbx-tools/shared-core/async-utils";
36
+ import * as errorUtils from "@dbx-tools/shared-core/error-utils";
37
+ import * as functionUtils from "@dbx-tools/shared-core/function-utils";
38
+ import * as hash from "@dbx-tools/shared-core/hash";
39
+ import * as log from "@dbx-tools/shared-core/log";
40
+ import * as object from "@dbx-tools/shared-core/object";
36
41
  import lockfile from "proper-lockfile";
37
42
  const logger = log.logger("core:file-lock");
38
43
  const DEFAULT_BACKENDS = ["file"];
@@ -98,6 +103,51 @@ export async function withFileLock(key, fn, options = {}) {
98
103
  }
99
104
  throw new Error("withFileLock: no lock backend available");
100
105
  }
106
+ /**
107
+ * Acquire a cross-process lock and return an explicit lease.
108
+ *
109
+ * Prefer {@link withFileLock} for ordinary JavaScript callers. This lower-level
110
+ * shape exists for storage adapters and cross-language bridges that cannot
111
+ * conveniently pass an async callback through their FFI boundary.
112
+ */
113
+ export async function acquireFileLock(key, options = {}) {
114
+ let acquisition;
115
+ let resolveAcquired;
116
+ let rejectAcquired;
117
+ let resolveRelease;
118
+ const acquired = new Promise((resolve, reject) => {
119
+ resolveAcquired = resolve;
120
+ rejectAcquired = reject;
121
+ });
122
+ const released = new Promise((resolve) => {
123
+ resolveRelease = resolve;
124
+ });
125
+ const run = withFileLock(key, async () => {
126
+ resolveAcquired();
127
+ await released;
128
+ }, {
129
+ ...options,
130
+ onAcquire: (value) => {
131
+ acquisition = value;
132
+ options.onAcquire?.(value);
133
+ },
134
+ });
135
+ void run.catch(rejectAcquired);
136
+ await acquired;
137
+ if (!acquisition)
138
+ throw new Error("File-lock backend was not recorded");
139
+ let active = true;
140
+ return {
141
+ ...acquisition,
142
+ async release() {
143
+ if (!active)
144
+ return;
145
+ active = false;
146
+ resolveRelease();
147
+ await run;
148
+ },
149
+ };
150
+ }
101
151
  /** Canonical filesystem-safe id for a lock key. */
102
152
  function lockId(key) {
103
153
  const stable = object
@@ -227,4 +277,4 @@ function assertBeforeDeadline(lockPath, deadline) {
227
277
  async function ensureParentDir(lockPath) {
228
278
  await mkdir(dirname(lockPath), { recursive: true });
229
279
  }
230
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1sb2NrLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ZpbGUtbG9jay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRzs7Ozs7Ozs7O0FBRUgsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRTFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2xHLE9BQU8sUUFBUSxNQUFNLGlCQUFpQixDQUFDO0FBRXZDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztBQUs1QyxNQUFNLGdCQUFnQixHQUErQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBRTlELDJEQUEyRDtBQUMzRCxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUM7QUFFbkI7Ozs7R0FJRztBQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLE1BQU0sQ0FBQztBQUUzRSwrRUFBK0U7QUFDL0UsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztBQUVuRix1REFBdUQ7QUFDdkQsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDO0FBQ2xCLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBQztBQUNsQixNQUFNLE9BQU8sR0FBRyxDQUFDLENBQUM7QUFtQ2xCOzs7Ozs7Ozs7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b250ZW50IjpbIi8qKlxuICogQ2FzY2FkaW5nIGNyb3NzLXByb2Nlc3MgbXV0dWFsIGV4Y2x1c2lvbiB2aWEgYSBsb2NrZmlsZS5cbiAqXG4gKiBTZXJpYWxpemVzIGNvbmN1cnJlbnQgKnByb2Nlc3NlcyogKHR3byBgYnVuIHJ1biBkZW1vYCBzaGVsbHMsIGEgQ0xJIGJlc2lkZSBhXG4gKiBzZXJ2ZXIpIG9uIHRoZSBzYW1lIGtleS4gRm9yIGluLXByb2Nlc3MgLyB3b3JrZXItdGhyZWFkIGV4Y2x1c2lvbiB1c2VcbiAqIHtAbGluayB3aXRoUHJvY2Vzc0xvY2t9IGZyb20gYC4vcHJvY2Vzcy1sb2NrLnRzYCBpbnN0ZWFkLlxuICpcbiAqIEJhY2tlbmRzOlxuICpcbiAqIDEuICoqZmlsZSoqIChkZWZhdWx0KSDigJQgYHByb3Blci1sb2NrZmlsZWAgYXRvbWljIGxvY2stZGlyZWN0b3J5IGNyZWF0aW9uLFxuICogICAgaGVhcnRiZWF0LCBzdGFsZSByZWNvdmVyeSwgYW5kIG93bmVyc2hpcC1zYWZlIHJlbGVhc2UuIEJ1biBhbmQgTm9kZSB1c2VcbiAqICAgIHRoaXMgc2FtZSBwcm90b2NvbC5cbiAqIDIuICoqZmxvY2sqKiAoZXhwbGljaXQgY29tcGF0aWJpbGl0eSBvcHRpb24pIOKAlCBgZmxvY2soMilgIHZpYSBCdW4gRkZJIG9uXG4gKiAgICBVbml4LiBJdCByZW1haW5zIGF2YWlsYWJsZSB0byBjYWxsZXJzIHRoYXQgc2VsZWN0ZWQgaXQgZXhwbGljaXRseSwgYnV0IGFcbiAqICAgIHJ1bnRpbWUtZGVwZW5kZW50IGNhc2NhZGUgY2Fubm90IGNvb3JkaW5hdGUgQnVuIGFuZCBOb2RlLlxuICpcbiAqIFRoZSBmaXJzdCBiYWNrZW5kIHRoYXQgY2FuIGJlICppbml0aWFsaXplZCogaXMgdXNlZCBmb3IgdGhlIHdob2xlIGNhbGwuIEEgYnVzeVxuICogbG9jayB3YWl0czsgYW4gdW5hdmFpbGFibGUgYmFja2VuZCBmYWxscyB0aHJvdWdoIHRvIHRoZSBuZXh0LiBDYWxsZXJzIG1heSBvbmx5XG4gKiBib3VuZCBob3cgbG9uZyB0byB3YWl0ICh7QGxpbmsgRmlsZUxvY2tPcHRpb25zLnRpbWVvdXRNc30pOyBzdGFsZSB0aW1pbmcgaXNcbiAqIG5vdCBjb25maWd1cmFibGUgc28gZXZlcnkgaG9sZGVyIGFuZCB3YWl0ZXIgYWdyZWVzLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBta2Rpciwgb3BlbiB9IGZyb20gXCJub2RlOmZzL3Byb21pc2VzXCI7XG5pbXBvcnQgeyB0bXBkaXIgfSBmcm9tIFwibm9kZTpvc1wiO1xuaW1wb3J0IHsgZGlybmFtZSwgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcblxuaW1wb3J0IHsgYXN5bmNVdGlscywgZXJyb3JVdGlscywgZnVuY3Rpb25VdGlscywgaGFzaCwgbG9nLCBvYmplY3QgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IGxvY2tmaWxlIGZyb20gXCJwcm9wZXItbG9ja2ZpbGVcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcImNvcmU6ZmlsZS1sb2NrXCIpO1xuXG4vKiogQmFja2VuZHMge0BsaW5rIHdpdGhGaWxlTG9ja30gY2FuIGF0dGVtcHQsIGluIGNhc2NhZGUgb3JkZXIuICovXG5leHBvcnQgdHlwZSBGaWxlTG9ja0JhY2tlbmQgPSBcImZsb2NrXCIgfCBcImZpbGVcIjtcblxuY29uc3QgREVGQVVMVF9CQUNLRU5EUzogcmVhZG9ubHkgRmlsZUxvY2tCYWNrZW5kW10gPSBbXCJmaWxlXCJdO1xuXG4vKiogUG9sbCBpbnRlcnZhbCB3aGlsZSB3YWl0aW5nIGZvciBhIGNvbnRlbmRlZCBPUyBsb2NrLiAqL1xuY29uc3QgUE9MTF9NUyA9IDUwO1xuXG4vKipcbiAqIEFnZSBhZnRlciB3aGljaCBhbiB1bnJlZnJlc2hlZCBsb2NrIGRpcmVjdG9yeSBtYXkgYmUgcmVtb3ZlZC5cbiAqIE1hdGNoZXMgYHByb3Blci1sb2NrZmlsZWAncyBkZWZhdWx0LiBOb3QgY2FsbGVyLWNvbmZpZ3VyYWJsZTogZXZlcnkgcHJvY2Vzc1xuICogbXVzdCBzaGFyZSB0aGUgc2FtZSB0aHJlc2hvbGQgb3IgYSBsaXZlIGhvbGRlciBjYW4gYmUgbWlzdGFrZW4gZm9yIHN0YWxlLlxuICovXG5jb25zdCBTVEFMRV9NUyA9IG9iamVjdC50b051bWJlcihwcm9jZXNzLmVudi5GSUxFX0xPQ0tfU1RBTEVfTVMpID8/IDEwXzAwMDtcblxuLyoqIEhlYXJ0YmVhdCBpbnRlcnZhbCBmb3IgcmVmcmVzaGluZyBsb2NrLWRpcmVjdG9yeSBtdGltZSAoYFNUQUxFX01TIC8gMmApLiAqL1xuY29uc3QgVVBEQVRFX01TID0gb2JqZWN0LnRvTnVtYmVyKHByb2Nlc3MuZW52LkZJTEVfTE9DS19VUERBVEVfTVMpID8/IFNUQUxFX01TIC8gMjtcblxuLyoqIGBmbG9jaygyKWAgb3BlcmF0aW9uIGJpdHMgKExpbnV4IC8gbWFjT1MgLyBCU0QpLiAqL1xuY29uc3QgTE9DS19FWCA9IDI7XG5jb25zdCBMT0NLX05CID0gNDtcbmNvbnN0IExPQ0tfVU4gPSA4O1xuXG4vKiogUmVzdWx0IG1ldGFkYXRhIHdoZW4gYSBjYWxsZXIgd2FudHMgdG8ga25vdyB3aGljaCBiYWNrZW5kIHJhbi4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRmlsZUxvY2tBY3F1aXNpdGlvbiB7XG4gIGJhY2tlbmQ6IEZpbGVMb2NrQmFja2VuZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGaWxlTG9ja09wdGlvbnMge1xuICAvKipcbiAgICogRGlyZWN0b3J5IGZvciBsb2NrZmlsZXMuIERlZmF1bHRzIHRvIGAkVE1QRElSL2RieC10b29scy1sb2Nrc2AuXG4gICAqL1xuICBkaXI/OiBzdHJpbmc7XG4gIC8qKiBPdmVycmlkZSB0aGUgYmFja2VuZCBsaXN0LiBEZWZhdWx0cyB0byB0aGUgcG9ydGFibGUgYGZpbGVgIHByb3RvY29sLiAqL1xuICBiYWNrZW5kcz86IHJlYWRvbmx5IEZpbGVMb2NrQmFja2VuZFtdO1xuICAvKipcbiAgICogU3RvcCB3YWl0aW5nIGFuZCB0aHJvdyBhZnRlciB0aGlzIG1hbnkgbWlsbGlzZWNvbmRzLiBPbWl0IHRvIHBvbGwgZm9yZXZlci5cbiAgICogVGhpcyBpcyB0aGUgb25seSB3YWl0LWxvb3Aga25vYjsgc3RhbGUgcmVjbGFpbSB0aW1pbmcgaXMgZml4ZWQuXG4gICAqL1xuICB0aW1lb3V0TXM/OiBudW1iZXI7XG4gIC8qKiBJbnZva2VkIG9uY2UgdGhlIGJhY2tlbmQgZm9yIHRoaXMgY2FsbCBoYXMgYmVlbiBjaG9zZW4uICovXG4gIG9uQWNxdWlyZT86IChhY3F1aXNpdGlvbjogRmlsZUxvY2tBY3F1aXNpdGlvbikgPT4gdm9pZDtcbiAgLyoqIEludm9rZWQgb25jZSB3aGVuIHRoZSBzZWxlY3RlZCBsb2NrIGlzIGFscmVhZHkgaGVsZCBieSBhbm90aGVyIHByb2Nlc3MuICovXG4gIG9uV2FpdD86IChhY3F1aXNpdGlvbjogRmlsZUxvY2tBY3F1aXNpdGlvbikgPT4gdm9pZDtcbn1cblxudHlwZSBGbG9ja0ZuID0gKGZkOiBudW1iZXIsIG9wZXJhdGlvbjogbnVtYmVyKSA9PiBudW1iZXI7XG5cbmludGVyZmFjZSBCdW5GZmlNb2R1bGUge1xuICBkbG9wZW46IChcbiAgICBwYXRoOiBzdHJpbmcsXG4gICAgc3ltYm9sczogUmVjb3JkPHN0cmluZywgeyBhcmdzOiBzdHJpbmdbXTsgcmV0dXJuczogc3RyaW5nIH0+LFxuICApID0+IHsgc3ltYm9sczogeyBmbG9jazogRmxvY2tGbiB9IH07XG4gIHN1ZmZpeDogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJ1biBgZm5gIHdoaWxlIGhvbGRpbmcgYSBjcm9zcy1wcm9jZXNzIGxvY2sgbmFtZWQgYnkgYGtleWAuXG4gKlxuICogYGtleWAgaXMgY2Fub25pY2FsaXplZCB3aXRoIGBvYmplY3QudG9TdGFibGVLZXlgLCB0aGUgc2FtZSBpZGVudGl0eSBydWxlIGFzXG4gKiBwcm9jZXNzIGFuZCBQb3N0Z3JlcyBhZHZpc29yeSBsb2Nrcy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYXdhaXQgd2l0aEZpbGVMb2NrKFtcImNhY2hlXCIsIFwiYXBwa2l0XCJdLCBhc3luYyAoKSA9PiB7XG4gKiAgIGF3YWl0IG1pZ3JhdGUoKTtcbiAqIH0pO1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd2l0aEZpbGVMb2NrPFQ+KFxuICBrZXk6IHVua25vd24sXG4gIGZuOiAoKSA9PiBUIHwgUHJvbWlzZTxUPixcbiAgb3B0aW9uczogRmlsZUxvY2tPcHRpb25zID0ge30sXG4pOiBQcm9taXNlPFQ+IHtcbiAgaWYgKG9wdGlvbnMudGltZW91dE1zICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy50aW1lb3V0TXMgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInRpbWVvdXRNcyBtdXN0IGJlIG5vbi1uZWdhdGl2ZVwiKTtcbiAgfVxuICBjb25zdCBpZCA9IGxvY2tJZChrZXkpO1xuICBjb25zdCBiYWNrZW5kcyA9IG9wdGlvbnMuYmFja2VuZHMgPz8gREVGQVVMVF9CQUNLRU5EUztcbiAgY29uc3QgZGlyID0gb3B0aW9ucy5kaXIgPz8gam9pbih0bXBkaXIoKSwgXCJkYngtdG9vbHMtbG9ja3NcIik7XG4gIGNvbnN0IGRlYWRsaW5lID0gb3B0aW9ucy50aW1lb3V0TXMgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IERhdGUubm93KCkgKyBvcHRpb25zLnRpbWVvdXRNcztcblxuICBmb3IgKGNvbnN0IGJhY2tlbmQgb2YgYmFja2VuZHMpIHtcbiAgICBzd2l0Y2ggKGJhY2tlbmQpIHtcbiAgICAgIGNhc2UgXCJmbG9ja1wiOiB7XG4gICAgICAgIGNvbnN0IGxvY2tQYXRoID0gam9pbihkaXIsIGAke2lkfS5mbG9ja2ApO1xuICAgICAgICBjb25zdCBmbG9jayA9IGF3YWl0IHJlc29sdmVGbG9jaygpO1xuICAgICAgICBpZiAoIWZsb2NrKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKFwibG9jayBiYWNrZW5kIHVuYXZhaWxhYmxlXCIsIHsgYmFja2VuZCwga2V5OiBpZCB9KTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBsb2dnZXIuZGVidWcoXCJhY3F1aXJpbmcgbG9ja1wiLCB7IGJhY2tlbmQsIGtleTogaWQsIHBhdGg6IGxvY2tQYXRoIH0pO1xuICAgICAgICBjb25zdCBhY3F1aXNpdGlvbiA9IHsgYmFja2VuZCB9IGFzIGNvbnN0O1xuICAgICAgICBvcHRpb25zLm9uQWNxdWlyZT8uKGFjcXVpc2l0aW9uKTtcbiAgICAgICAgcmV0dXJuIGhvbGRGbG9jayhsb2NrUGF0aCwgZmxvY2ssIGRlYWRsaW5lLCBmbiwgKCkgPT4gb3B0aW9ucy5vbldhaXQ/LihhY3F1aXNpdGlvbikpO1xuICAgICAgfVxuICAgICAgY2FzZSBcImZpbGVcIjoge1xuICAgICAgICBjb25zdCBsb2NrUGF0aCA9IGpvaW4oZGlyLCBpZCk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhcImFjcXVpcmluZyBsb2NrXCIsIHsgYmFja2VuZCwga2V5OiBpZCwgcGF0aDogbG9ja1BhdGggfSk7XG4gICAgICAgIGNvbnN0IGFjcXVpc2l0aW9uID0geyBiYWNrZW5kIH0gYXMgY29uc3Q7XG4gICAgICAgIG9wdGlvbnMub25BY3F1aXJlPy4oYWNxdWlzaXRpb24pO1xuICAgICAgICByZXR1cm4gaG9sZExvY2tEaXJlY3RvcnkobG9ja1BhdGgsIGRlYWRsaW5lLCBmbiwgKCkgPT4gb3B0aW9ucy5vbldhaXQ/LihhY3F1aXNpdGlvbikpO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICBjb25zdCBfZXhoYXVzdGl2ZTogbmV2ZXIgPSBiYWNrZW5kO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVua25vd24gZmlsZS1sb2NrIGJhY2tlbmQ6ICR7U3RyaW5nKF9leGhhdXN0aXZlKX1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoXCJ3aXRoRmlsZUxvY2s6IG5vIGxvY2sgYmFja2VuZCBhdmFpbGFibGVcIik7XG59XG5cbi8qKiBDYW5vbmljYWwgZmlsZXN5c3RlbS1zYWZlIGlkIGZvciBhIGxvY2sga2V5LiAqL1xuZnVuY3Rpb24gbG9ja0lkKGtleTogdW5rbm93bik6IHN0cmluZyB7XG4gIGNvbnN0IHN0YWJsZSA9IG9iamVjdFxuICAgIC50b09uZU9yTWFueShrZXkpXG4gICAgLm1hcCgocGFydCkgPT4gb2JqZWN0LnRvU3RhYmxlS2V5KHBhcnQpKVxuICAgIC5qb2luKFwiXFx1MDAwMFwiKTtcbiAgLy8gU2hvcnQgZGlnZXN0IHNvIHBhdGhzIHN0YXkgd2VsbCB1bmRlciBPUyBsaW1pdHM7IGNvbGxpc2lvbnMgYXJlIGZpbmUg4oCUIHRoZXlcbiAgLy8gb25seSBtZXJnZSBjcml0aWNhbCBzZWN0aW9ucyB0aGF0IGFscmVhZHkgc2hhcmVkIGEga2V5IHN0cmluZy5cbiAgcmV0dXJuIGhhc2guZm52SGFzaChzdGFibGUpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYGZsb2NrKDIpYCB0aHJvdWdoIEJ1biBGRkkgd2hlbiBwb3NzaWJsZS5cbiAqXG4gKiBNZW1vaXplZDogdGhlIEZGSSBpbXBvcnQgKyBsaWJjIGBkbG9wZW5gIHJ1biBvbmNlIHBlciBwcm9jZXNzLiBSZXR1cm5zXG4gKiBgdW5kZWZpbmVkYCBvbiBXaW5kb3dzLCB1bmRlciBwbGFpbiBOb2RlLCBvciB3aGVuIGxpYmMgY2Fubm90IGJlIGxvYWRlZCDigJRcbiAqIGNhbGxlcnMgZmFsbCB0aHJvdWdoIHRvIHRoZSBuZXh0IGJhY2tlbmQuIEEgbWlzcyBpcyBjYWNoZWQgdG9vLCBzbyBhIHByb2Nlc3NcbiAqIHRoYXQgY2Fubm90IGZsb2NrIG5ldmVyIHJldHJpZXMgdGhlIGxvYWQuXG4gKi9cbmNvbnN0IHJlc29sdmVGbG9jayA9IGZ1bmN0aW9uVXRpbHMubWVtb2l6ZShhc3luYyAoKTogUHJvbWlzZTxGbG9ja0ZuIHwgdW5kZWZpbmVkPiA9PiB7XG4gIGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSBcIndpbjMyXCIpIHJldHVybiB1bmRlZmluZWQ7XG4gIGlmICghcHJvY2Vzcy52ZXJzaW9ucy5idW4pIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgdHJ5IHtcbiAgICAvLyBEeW5hbWljIHNwZWNpZmllciBzbyBgdHNjYCAobm8gYEB0eXBlc2AgZm9yIGBidW46ZmZpYCkgZG9lcyBub3QgcmVzb2x2ZSBpdDtcbiAgICAvLyB0aGUgaW1wb3J0IG9ubHkgc3VjY2VlZHMgdW5kZXIgQnVuIGF0IHJ1bnRpbWUuXG4gICAgY29uc3Qgc3BlY2lmaWVyID0gXCJidW46ZmZpXCI7XG4gICAgY29uc3QgZmZpID0gKGF3YWl0IGltcG9ydChzcGVjaWZpZXIpKSBhcyB1bmtub3duIGFzIEJ1bkZmaU1vZHVsZTtcbiAgICBjb25zdCBsaWJQYXRoID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gXCJkYXJ3aW5cIiA/IFwibGliU3lzdGVtLkIuZHlsaWJcIiA6IGBsaWJjLiR7ZmZpLnN1ZmZpeH1gO1xuICAgIGNvbnN0IGxpYiA9IGZmaS5kbG9wZW4obGliUGF0aCwge1xuICAgICAgZmxvY2s6IHsgYXJnczogW1wiaTMyXCIsIFwiaTMyXCJdLCByZXR1cm5zOiBcImkzMlwiIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIGxpYi5zeW1ib2xzLmZsb2NrO1xuICB9IGNhdGNoIChjYXVzZSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhcImZsb2NrIEZGSSB1bmF2YWlsYWJsZVwiLCB7IGVycm9yOiBlcnJvclV0aWxzLmVycm9yTWVzc2FnZShjYXVzZSkgfSk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufSk7XG5cbmFzeW5jIGZ1bmN0aW9uIGhvbGRGbG9jazxUPihcbiAgbG9ja1BhdGg6IHN0cmluZyxcbiAgZmxvY2s6IEZsb2NrRm4sXG4gIGRlYWRsaW5lOiBudW1iZXIgfCB1bmRlZmluZWQsXG4gIGZuOiAoKSA9PiBUIHwgUHJvbWlzZTxUPixcbiAgb25XYWl0OiAoKSA9PiB2b2lkLFxuKTogUHJvbWlzZTxUPiB7XG4gIGF3YWl0IGVuc3VyZVBhcmVudERpcihsb2NrUGF0aCk7XG4gIGNvbnN0IGhhbmRsZSA9IGF3YWl0IG9wZW4obG9ja1BhdGgsIFwiYStcIik7XG4gIHRyeSB7XG4gICAgYXdhaXQgd2FpdEZvckZsb2NrKGhhbmRsZS5mZCwgZmxvY2ssIGxvY2tQYXRoLCBkZWFkbGluZSwgb25XYWl0KTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IGZuKCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGZsb2NrKGhhbmRsZS5mZCwgTE9DS19VTik7XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIGF3YWl0IGhhbmRsZS5jbG9zZSgpLmNhdGNoKCgpID0+IHt9KTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiB3YWl0Rm9yRmxvY2soXG4gIGZkOiBudW1iZXIsXG4gIGZsb2NrOiBGbG9ja0ZuLFxuICBsb2NrUGF0aDogc3RyaW5nLFxuICBkZWFkbGluZTogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICBvbldhaXQ6ICgpID0+IHZvaWQsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgbGV0IHdhaXRpbmcgPSBmYWxzZTtcbiAgZm9yICg7Oykge1xuICAgIGNvbnN0IHJjID0gZmxvY2soZmQsIExPQ0tfRVggfCBMT0NLX05CKTtcbiAgICBpZiAocmMgPT09IDApIHJldHVybjtcbiAgICBpZiAoIXdhaXRpbmcpIHtcbiAgICAgIHdhaXRpbmcgPSB0cnVlO1xuICAgICAgb25XYWl0KCk7XG4gICAgfVxuICAgIGFzc2VydEJlZm9yZURlYWRsaW5lKGxvY2tQYXRoLCBkZWFkbGluZSk7XG4gICAgYXdhaXQgYXN5bmNVdGlscy5zbGVlcChQT0xMX01TKTtcbiAgfVxufVxuXG4vKipcbiAqIFBvcnRhYmxlIGxvY2stZGlyZWN0b3J5IG93bmVyc2hpcCB0aHJvdWdoIGBwcm9wZXItbG9ja2ZpbGVgLlxuICovXG5hc3luYyBmdW5jdGlvbiBob2xkTG9ja0RpcmVjdG9yeTxUPihcbiAgbG9ja1BhdGg6IHN0cmluZyxcbiAgZGVhZGxpbmU6IG51bWJlciB8IHVuZGVmaW5lZCxcbiAgZm46ICgpID0+IFQgfCBQcm9taXNlPFQ+LFxuICBvbldhaXQ6ICgpID0+IHZvaWQsXG4pOiBQcm9taXNlPFQ+IHtcbiAgYXdhaXQgZW5zdXJlUGFyZW50RGlyKGxvY2tQYXRoKTtcbiAgY29uc3QgcmVsZWFzZSA9IGF3YWl0IGFjcXVpcmVMb2NrRGlyZWN0b3J5KGxvY2tQYXRoLCBkZWFkbGluZSwgb25XYWl0KTtcbiAgbGV0IGNhbGxiYWNrRXJyb3I6IHVua25vd247XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IGZuKCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY2FsbGJhY2tFcnJvciA9IGVycm9yO1xuICAgIHRocm93IGVycm9yO1xuICB9IGZpbmFsbHkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCByZWxlYXNlKCk7XG4gICAgfSBjYXRjaCAoY2F1c2UpIHtcbiAgICAgIGlmIChjYWxsYmFja0Vycm9yID09PSB1bmRlZmluZWQgfHwgKGNhdXNlIGFzIE5vZGVKUy5FcnJub0V4Y2VwdGlvbikuY29kZSAhPT0gXCJFUkVMRUFTRURcIikge1xuICAgICAgICB0aHJvdyBjYXVzZTtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci53YXJuKFwibG9jayByZWxlYXNlIHdhcyBhbHJlYWR5IGNvbXBsZXRlZCBhZnRlciBjYWxsYmFjayBmYWlsdXJlXCIsIHtcbiAgICAgICAgcGF0aDogbG9ja1BhdGgsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gYWNxdWlyZUxvY2tEaXJlY3RvcnkoXG4gIGxvY2tQYXRoOiBzdHJpbmcsXG4gIGRlYWRsaW5lOiBudW1iZXIgfCB1bmRlZmluZWQsXG4gIG9uV2FpdDogKCkgPT4gdm9pZCxcbik6IFByb21pc2U8KCkgPT4gUHJvbWlzZTx2b2lkPj4ge1xuICBsZXQgd2FpdGluZyA9IGZhbHNlO1xuICBmb3IgKDs7KSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBsb2NrZmlsZS5sb2NrKGxvY2tQYXRoLCB7XG4gICAgICAgIHJlYWxwYXRoOiBmYWxzZSxcbiAgICAgICAgc3RhbGU6IFNUQUxFX01TLFxuICAgICAgICB1cGRhdGU6IFVQREFURV9NUyxcbiAgICAgICAgcmV0cmllczogMCxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGNhdXNlKSB7XG4gICAgICBjb25zdCBlcnIgPSBjYXVzZSBhcyBOb2RlSlMuRXJybm9FeGNlcHRpb247XG4gICAgICBpZiAoZXJyLmNvZGUgIT09IFwiRUxPQ0tFRFwiKSB0aHJvdyBlcnJvclV0aWxzLnRvRXJyb3IoY2F1c2UpO1xuICAgICAgaWYgKCF3YWl0aW5nKSB7XG4gICAgICAgIHdhaXRpbmcgPSB0cnVlO1xuICAgICAgICBvbldhaXQoKTtcbiAgICAgIH1cbiAgICAgIGFzc2VydEJlZm9yZURlYWRsaW5lKGxvY2tQYXRoLCBkZWFkbGluZSk7XG4gICAgICBhd2FpdCBhc3luY1V0aWxzLnNsZWVwKFBPTExfTVMpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhc3NlcnRCZWZvcmVEZWFkbGluZShsb2NrUGF0aDogc3RyaW5nLCBkZWFkbGluZTogbnVtYmVyIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gIGlmIChkZWFkbGluZSAhPT0gdW5kZWZpbmVkICYmIERhdGUubm93KCkgPj0gZGVhZGxpbmUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFRpbWVkIG91dCB3YWl0aW5nIGZvciBmaWxlIGxvY2s6ICR7bG9ja1BhdGh9YCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZW5zdXJlUGFyZW50RGlyKGxvY2tQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgbWtkaXIoZGlybmFtZShsb2NrUGF0aCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xufVxuIl19
280
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1sb2NrLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ZpbGUtbG9jay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRzs7Ozs7Ozs7O0FBRUgsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRTFDLE9BQU8sS0FBSyxVQUFVLE1BQU0sb0NBQW9DLENBQUM7QUFDakUsT0FBTyxLQUFLLFVBQVUsTUFBTSxvQ0FBb0MsQ0FBQztBQUNqRSxPQUFPLEtBQUssYUFBYSxNQUFNLHVDQUF1QyxDQUFDO0FBQ3ZFLE9BQU8sS0FBSyxJQUFJLE1BQU0sNkJBQTZCLENBQUM7QUFDcEQsT0FBTyxLQUFLLEdBQUcsTUFBTSw0QkFBNEIsQ0FBQztBQUNsRCxPQUFPLEtBQUssTUFBTSxNQUFNLCtCQUErQixDQUFDO0FBQ3hELE9BQU8sUUFBUSxNQUFNLGlCQUFpQixDQUFDO0FBRXZDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztBQUs1QyxNQUFNLGdCQUFnQixHQUErQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBRTlELDJEQUEyRDtBQUMzRCxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUM7QUFFbkI7Ozs7R0FJRztBQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLE1BQU0sQ0FBQztBQUUzRSwrRUFBK0U7QUFDL0UsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLElBQUksUUFBUSxH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QUUsSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUNyRCxNQUFNLElBQUksS0FBSyxDQUFDLG9DQUFvQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7QUFDSCxDQUFDO0FBRUQsS0FBSyxVQUFVLGVBQWUsQ0FBQyxRQUFnQjtJQUM3QyxNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUN0RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDYXNjYWRpbmcgY3Jvc3MtcHJvY2VzcyBtdXR1YWwgZXhjbHVzaW9uIHZpYSBhIGxvY2tmaWxlLlxuICpcbiAqIFNlcmlhbGl6ZXMgY29uY3VycmVudCAqcHJvY2Vzc2VzKiAodHdvIGBidW4gcnVuIGRlbW9gIHNoZWxscywgYSBDTEkgYmVzaWRlIGFcbiAqIHNlcnZlcikgb24gdGhlIHNhbWUga2V5LiBGb3IgaW4tcHJvY2VzcyAvIHdvcmtlci10aHJlYWQgZXhjbHVzaW9uIHVzZVxuICoge0BsaW5rIHdpdGhQcm9jZXNzTG9ja30gZnJvbSBgLi9wcm9jZXNzLWxvY2sudHNgIGluc3RlYWQuXG4gKlxuICogQmFja2VuZHM6XG4gKlxuICogMS4gKipmaWxlKiogKGRlZmF1bHQpIOKAlCBgcHJvcGVyLWxvY2tmaWxlYCBhdG9taWMgbG9jay1kaXJlY3RvcnkgY3JlYXRpb24sXG4gKiAgICBoZWFydGJlYXQsIHN0YWxlIHJlY292ZXJ5LCBhbmQgb3duZXJzaGlwLXNhZmUgcmVsZWFzZS4gQnVuIGFuZCBOb2RlIHVzZVxuICogICAgdGhpcyBzYW1lIHByb3RvY29sLlxuICogMi4gKipmbG9jayoqIChleHBsaWNpdCBjb21wYXRpYmlsaXR5IG9wdGlvbikg4oCUIGBmbG9jaygyKWAgdmlhIEJ1biBGRkkgb25cbiAqICAgIFVuaXguIEl0IHJlbWFpbnMgYXZhaWxhYmxlIHRvIGNhbGxlcnMgdGhhdCBzZWxlY3RlZCBpdCBleHBsaWNpdGx5LCBidXQgYVxuICogICAgcnVudGltZS1kZXBlbmRlbnQgY2FzY2FkZSBjYW5ub3QgY29vcmRpbmF0ZSBCdW4gYW5kIE5vZGUuXG4gKlxuICogVGhlIGZpcnN0IGJhY2tlbmQgdGhhdCBjYW4gYmUgKmluaXRpYWxpemVkKiBpcyB1c2VkIGZvciB0aGUgd2hvbGUgY2FsbC4gQSBidXN5XG4gKiBsb2NrIHdhaXRzOyBhbiB1bmF2YWlsYWJsZSBiYWNrZW5kIGZhbGxzIHRocm91Z2ggdG8gdGhlIG5leHQuIENhbGxlcnMgbWF5IG9ubHlcbiAqIGJvdW5kIGhvdyBsb25nIHRvIHdhaXQgKHtAbGluayBGaWxlTG9ja09wdGlvbnMudGltZW91dE1zfSk7IHN0YWxlIHRpbWluZyBpc1xuICogbm90IGNvbmZpZ3VyYWJsZSBzbyBldmVyeSBob2xkZXIgYW5kIHdhaXRlciBhZ3JlZXMuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IG1rZGlyLCBvcGVuIH0gZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gXCJub2RlOm9zXCI7XG5pbXBvcnQgeyBkaXJuYW1lLCBqb2luIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuXG5pbXBvcnQgKiBhcyBhc3luY1V0aWxzIGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlL2FzeW5jLXV0aWxzXCI7XG5pbXBvcnQgKiBhcyBlcnJvclV0aWxzIGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlL2Vycm9yLXV0aWxzXCI7XG5pbXBvcnQgKiBhcyBmdW5jdGlvblV0aWxzIGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlL2Z1bmN0aW9uLXV0aWxzXCI7XG5pbXBvcnQgKiBhcyBoYXNoIGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlL2hhc2hcIjtcbmltcG9ydCAqIGFzIGxvZyBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZS9sb2dcIjtcbmltcG9ydCAqIGFzIG9iamVjdCBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZS9vYmplY3RcIjtcbmltcG9ydCBsb2NrZmlsZSBmcm9tIFwicHJvcGVyLWxvY2tmaWxlXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJjb3JlOmZpbGUtbG9ja1wiKTtcblxuLyoqIEJhY2tlbmRzIHtAbGluayB3aXRoRmlsZUxvY2t9IGNhbiBhdHRlbXB0LCBpbiBjYXNjYWRlIG9yZGVyLiAqL1xuZXhwb3J0IHR5cGUgRmlsZUxvY2tCYWNrZW5kID0gXCJmbG9ja1wiIHwgXCJmaWxlXCI7XG5cbmNvbnN0IERFRkFVTFRfQkFDS0VORFM6IHJlYWRvbmx5IEZpbGVMb2NrQmFja2VuZFtdID0gW1wiZmlsZVwiXTtcblxuLyoqIFBvbGwgaW50ZXJ2YWwgd2hpbGUgd2FpdGluZyBmb3IgYSBjb250ZW5kZWQgT1MgbG9jay4gKi9cbmNvbnN0IFBPTExfTVMgPSA1MDtcblxuLyoqXG4gKiBBZ2UgYWZ0ZXIgd2hpY2ggYW4gdW5yZWZyZXNoZWQgbG9jayBkaXJlY3RvcnkgbWF5IGJlIHJlbW92ZWQuXG4gKiBNYXRjaGVzIGBwcm9wZXItbG9ja2ZpbGVgJ3MgZGVmYXVsdC4gTm90IGNhbGxlci1jb25maWd1cmFibGU6IGV2ZXJ5IHByb2Nlc3NcbiAqIG11c3Qgc2hhcmUgdGhlIHNhbWUgdGhyZXNob2xkIG9yIGEgbGl2ZSBob2xkZXIgY2FuIGJlIG1pc3Rha2VuIGZvciBzdGFsZS5cbiAqL1xuY29uc3QgU1RBTEVfTVMgPSBvYmplY3QudG9OdW1iZXIocHJvY2Vzcy5lbnYuRklMRV9MT0NLX1NUQUxFX01TKSA/PyAxMF8wMDA7XG5cbi8qKiBIZWFydGJlYXQgaW50ZXJ2YWwgZm9yIHJlZnJlc2hpbmcgbG9jay1kaXJlY3RvcnkgbXRpbWUgKGBTVEFMRV9NUyAvIDJgKS4gKi9cbmNvbnN0IFVQREFURV9NUyA9IG9iamVjdC50b051bWJlcihwcm9jZXNzLmVudi5GSUxFX0xPQ0tfVVBEQVRFX01TKSA/PyBTVEFMRV9NUyAvIDI7XG5cbi8qKiBgZmxvY2soMilgIG9wZXJhdGlvbiBiaXRzIChMaW51eCAvIG1hY09TIC8gQlNEKS4gKi9cbmNvbnN0IExPQ0tfRVggPSAyO1xuY29uc3QgTE9DS19OQiA9IDQ7XG5jb25zdCBMT0NLX1VOID0gODtcblxuLyoqIFJlc3VsdCBtZXRhZGF0YSB3aGVuIGEgY2FsbGVyIHdhbnRzIHRvIGtub3cgd2hpY2ggYmFja2VuZCByYW4uICovXG5leHBvcnQgaW50ZXJmYWNlIEZpbGVMb2NrQWNxdWlzaXRpb24ge1xuICBiYWNrZW5kOiBGaWxlTG9ja0JhY2tlbmQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmlsZUxvY2tPcHRpb25zIHtcbiAgLyoqXG4gICAqIERpcmVjdG9yeSBmb3IgbG9ja2ZpbGVzLiBEZWZhdWx0cyB0byBgJFRNUERJUi9kYngtdG9vbHMtbG9ja3NgLlxuICAgKi9cbiAgZGlyPzogc3RyaW5nO1xuICAvKiogT3ZlcnJpZGUgdGhlIGJhY2tlbmQgbGlzdC4gRGVmYXVsdHMgdG8gdGhlIHBvcnRhYmxlIGBmaWxlYCBwcm90b2NvbC4gKi9cbiAgYmFja2VuZHM/OiByZWFkb25seSBGaWxlTG9ja0JhY2tlbmRbXTtcbiAgLyoqXG4gICAqIFN0b3Agd2FpdGluZyBhbmQgdGhyb3cgYWZ0ZXIgdGhpcyBtYW55IG1pbGxpc2Vjb25kcy4gT21pdCB0byBwb2xsIGZvcmV2ZXIuXG4gICAqIFRoaXMgaXMgdGhlIG9ubHkgd2FpdC1sb29wIGtub2I7IHN0YWxlIHJlY2xhaW0gdGltaW5nIGlzIGZpeGVkLlxuICAgKi9cbiAgdGltZW91dE1zPzogbnVtYmVyO1xuICAvKiogSW52b2tlZCBvbmNlIHRoZSBiYWNrZW5kIGZvciB0aGlzIGNhbGwgaGFzIGJlZW4gY2hvc2VuLiAqL1xuICBvbkFjcXVpcmU/OiAoYWNxdWlzaXRpb246IEZpbGVMb2NrQWNxdWlzaXRpb24pID0+IHZvaWQ7XG4gIC8qKiBJbnZva2VkIG9uY2Ugd2hlbiB0aGUgc2VsZWN0ZWQgbG9jayBpcyBhbHJlYWR5IGhlbGQgYnkgYW5vdGhlciBwcm9jZXNzLiAqL1xuICBvbldhaXQ/OiAoYWNxdWlzaXRpb246IEZpbGVMb2NrQWNxdWlzaXRpb24pID0+IHZvaWQ7XG59XG5cbi8qKiBFeHBsaWNpdCBjcm9zcy1wcm9jZXNzIGxlYXNlIHJldHVybmVkIGJ5IHtAbGluayBhY3F1aXJlRmlsZUxvY2t9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBGaWxlTG9ja0xlYXNlIGV4dGVuZHMgRmlsZUxvY2tBY3F1aXNpdGlvbiB7XG4gIC8qKiBSZWxlYXNlIHRoZSBoZWxkIGxvY2suIFJlcGVhdGVkIGNhbGxzIGFyZSBzYWZlLiAqL1xuICByZWxlYXNlKCk6IFByb21pc2U8dm9pZD47XG59XG5cbnR5cGUgRmxvY2tGbiA9IChmZDogbnVtYmVyLCBvcGVyYXRpb246IG51bWJlcikgPT4gbnVtYmVyO1xuXG5pbnRlcmZhY2UgQnVuRmZpTW9kdWxlIHtcbiAgZGxvcGVuOiAoXG4gICAgcGF0aDogc3RyaW5nLFxuICAgIHN5bWJvbHM6IFJlY29yZDxzdHJpbmcsIHsgYXJnczogc3RyaW5nW107IHJldHVybnM6IHN0cmluZyB9PixcbiAgKSA9PiB7IHN5bWJvbHM6IHsgZmxvY2s6IEZsb2NrRm4gfSB9O1xuICBzdWZmaXg6IHN0cmluZztcbn1cblxuLyoqXG4gKiBSdW4gYGZuYCB3aGlsZSBob2xkaW5nIGEgY3Jvc3MtcHJvY2VzcyBsb2NrIG5hbWVkIGJ5IGBrZXlgLlxuICpcbiAqIGBrZXlgIGlzIGNhbm9uaWNhbGl6ZWQgd2l0aCBgb2JqZWN0LnRvU3RhYmxlS2V5YCwgdGhlIHNhbWUgaWRlbnRpdHkgcnVsZSBhc1xuICogcHJvY2VzcyBhbmQgUG9zdGdyZXMgYWR2aXNvcnkgbG9ja3MuXG4gKlxuICogQGV4YW1wbGVcbiAqIGF3YWl0IHdpdGhGaWxlTG9jayhbXCJjYWNoZVwiLCBcImFwcGtpdFwiXSwgYXN5bmMgKCkgPT4ge1xuICogICBhd2FpdCBtaWdyYXRlKCk7XG4gKiB9KTtcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdpdGhGaWxlTG9jazxUPihcbiAga2V5OiB1bmtub3duLFxuICBmbjogKCkgPT4gVCB8IFByb21pc2U8VD4sXG4gIG9wdGlvbnM6IEZpbGVMb2NrT3B0aW9ucyA9IHt9LFxuKTogUHJvbWlzZTxUPiB7XG4gIGlmIChvcHRpb25zLnRpbWVvdXRNcyAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMudGltZW91dE1zIDwgMCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ0aW1lb3V0TXMgbXVzdCBiZSBub24tbmVnYXRpdmVcIik7XG4gIH1cbiAgY29uc3QgaWQgPSBsb2NrSWQoa2V5KTtcbiAgY29uc3QgYmFja2VuZHMgPSBvcHRpb25zLmJhY2tlbmRzID8/IERFRkFVTFRfQkFDS0VORFM7XG4gIGNvbnN0IGRpciA9IG9wdGlvbnMuZGlyID8/IGpvaW4odG1wZGlyKCksIFwiZGJ4LXRvb2xzLWxvY2tzXCIpO1xuICBjb25zdCBkZWFkbGluZSA9IG9wdGlvbnMudGltZW91dE1zID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBEYXRlLm5vdygpICsgb3B0aW9ucy50aW1lb3V0TXM7XG5cbiAgZm9yIChjb25zdCBiYWNrZW5kIG9mIGJhY2tlbmRzKSB7XG4gICAgc3dpdGNoIChiYWNrZW5kKSB7XG4gICAgICBjYXNlIFwiZmxvY2tcIjoge1xuICAgICAgICBjb25zdCBsb2NrUGF0aCA9IGpvaW4oZGlyLCBgJHtpZH0uZmxvY2tgKTtcbiAgICAgICAgY29uc3QgZmxvY2sgPSBhd2FpdCByZXNvbHZlRmxvY2soKTtcbiAgICAgICAgaWYgKCFmbG9jaykge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhcImxvY2sgYmFja2VuZCB1bmF2YWlsYWJsZVwiLCB7IGJhY2tlbmQsIGtleTogaWQgfSk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgbG9nZ2VyLmRlYnVnKFwiYWNxdWlyaW5nIGxvY2tcIiwgeyBiYWNrZW5kLCBrZXk6IGlkLCBwYXRoOiBsb2NrUGF0aCB9KTtcbiAgICAgICAgY29uc3QgYWNxdWlzaXRpb24gPSB7IGJhY2tlbmQgfSBhcyBjb25zdDtcbiAgICAgICAgb3B0aW9ucy5vbkFjcXVpcmU/LihhY3F1aXNpdGlvbik7XG4gICAgICAgIHJldHVybiBob2xkRmxvY2sobG9ja1BhdGgsIGZsb2NrLCBkZWFkbGluZSwgZm4sICgpID0+IG9wdGlvbnMub25XYWl0Py4oYWNxdWlzaXRpb24pKTtcbiAgICAgIH1cbiAgICAgIGNhc2UgXCJmaWxlXCI6IHtcbiAgICAgICAgY29uc3QgbG9ja1BhdGggPSBqb2luKGRpciwgaWQpO1xuICAgICAgICBsb2dnZXIuZGVidWcoXCJhY3F1aXJpbmcgbG9ja1wiLCB7IGJhY2tlbmQsIGtleTogaWQsIHBhdGg6IGxvY2tQYXRoIH0pO1xuICAgICAgICBjb25zdCBhY3F1aXNpdGlvbiA9IHsgYmFja2VuZCB9IGFzIGNvbnN0O1xuICAgICAgICBvcHRpb25zLm9uQWNxdWlyZT8uKGFjcXVpc2l0aW9uKTtcbiAgICAgICAgcmV0dXJuIGhvbGRMb2NrRGlyZWN0b3J5KGxvY2tQYXRoLCBkZWFkbGluZSwgZm4sICgpID0+IG9wdGlvbnMub25XYWl0Py4oYWNxdWlzaXRpb24pKTtcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgY29uc3QgX2V4aGF1c3RpdmU6IG5ldmVyID0gYmFja2VuZDtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bmtub3duIGZpbGUtbG9jayBiYWNrZW5kOiAke1N0cmluZyhfZXhoYXVzdGl2ZSl9YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKFwid2l0aEZpbGVMb2NrOiBubyBsb2NrIGJhY2tlbmQgYXZhaWxhYmxlXCIpO1xufVxuXG4vKipcbiAqIEFjcXVpcmUgYSBjcm9zcy1wcm9jZXNzIGxvY2sgYW5kIHJldHVybiBhbiBleHBsaWNpdCBsZWFzZS5cbiAqXG4gKiBQcmVmZXIge0BsaW5rIHdpdGhGaWxlTG9ja30gZm9yIG9yZGluYXJ5IEphdmFTY3JpcHQgY2FsbGVycy4gVGhpcyBsb3dlci1sZXZlbFxuICogc2hhcGUgZXhpc3RzIGZvciBzdG9yYWdlIGFkYXB0ZXJzIGFuZCBjcm9zcy1sYW5ndWFnZSBicmlkZ2VzIHRoYXQgY2Fubm90XG4gKiBjb252ZW5pZW50bHkgcGFzcyBhbiBhc3luYyBjYWxsYmFjayB0aHJvdWdoIHRoZWlyIEZGSSBib3VuZGFyeS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFjcXVpcmVGaWxlTG9jayhcbiAga2V5OiB1bmtub3duLFxuICBvcHRpb25zOiBGaWxlTG9ja09wdGlvbnMgPSB7fSxcbik6IFByb21pc2U8RmlsZUxvY2tMZWFzZT4ge1xuICBsZXQgYWNxdWlzaXRpb246IEZpbGVMb2NrQWNxdWlzaXRpb24gfCB1bmRlZmluZWQ7XG4gIGxldCByZXNvbHZlQWNxdWlyZWQhOiAoKSA9PiB2b2lkO1xuICBsZXQgcmVqZWN0QWNxdWlyZWQhOiAoZXJyb3I6IHVua25vd24pID0+IHZvaWQ7XG4gIGxldCByZXNvbHZlUmVsZWFzZSE6ICgpID0+IHZvaWQ7XG4gIGNvbnN0IGFjcXVpcmVkID0gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHJlc29sdmVBY3F1aXJlZCA9IHJlc29sdmU7XG4gICAgcmVqZWN0QWNxdWlyZWQgPSByZWplY3Q7XG4gIH0pO1xuICBjb25zdCByZWxlYXNlZCA9IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgcmVzb2x2ZVJlbGVhc2UgPSByZXNvbHZlO1xuICB9KTtcbiAgY29uc3QgcnVuID0gd2l0aEZpbGVMb2NrKFxuICAgIGtleSxcbiAgICBhc3luYyAoKSA9PiB7XG4gICAgICByZXNvbHZlQWNxdWlyZWQoKTtcbiAgICAgIGF3YWl0IHJlbGVhc2VkO1xuICAgIH0sXG4gICAge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIG9uQWNxdWlyZTogKHZhbHVlKSA9PiB7XG4gICAgICAgIGFjcXVpc2l0aW9uID0gdmFsdWU7XG4gICAgICAgIG9wdGlvbnMub25BY3F1aXJlPy4odmFsdWUpO1xuICAgICAgfSxcbiAgICB9LFxuICApO1xuICB2b2lkIHJ1bi5jYXRjaChyZWplY3RBY3F1aXJlZCk7XG4gIGF3YWl0IGFjcXVpcmVkO1xuICBpZiAoIWFjcXVpc2l0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJGaWxlLWxvY2sgYmFja2VuZCB3YXMgbm90IHJlY29yZGVkXCIpO1xuXG4gIGxldCBhY3RpdmUgPSB0cnVlO1xuICByZXR1cm4ge1xuICAgIC4uLmFjcXVpc2l0aW9uLFxuICAgIGFzeW5jIHJlbGVhc2UoKSB7XG4gICAgICBpZiAoIWFjdGl2ZSkgcmV0dXJuO1xuICAgICAgYWN0aXZlID0gZmFsc2U7XG4gICAgICByZXNvbHZlUmVsZWFzZSgpO1xuICAgICAgYXdhaXQgcnVuO1xuICAgIH0sXG4gIH07XG59XG5cbi8qKiBDYW5vbmljYWwgZmlsZXN5c3RlbS1zYWZlIGlkIGZvciBhIGxvY2sga2V5LiAqL1xuZnVuY3Rpb24gbG9ja0lkKGtleTogdW5rbm93bik6IHN0cmluZyB7XG4gIGNvbnN0IHN0YWJsZSA9IG9iamVjdFxuICAgIC50b09uZU9yTWFueShrZXkpXG4gICAgLm1hcCgocGFydCkgPT4gb2JqZWN0LnRvU3RhYmxlS2V5KHBhcnQpKVxuICAgIC5qb2luKFwiXFx1MDAwMFwiKTtcbiAgLy8gU2hvcnQgZGlnZXN0IHNvIHBhdGhzIHN0YXkgd2VsbCB1bmRlciBPUyBsaW1pdHM7IGNvbGxpc2lvbnMgYXJlIGZpbmUg4oCUIHRoZXlcbiAgLy8gb25seSBtZXJnZSBjcml0aWNhbCBzZWN0aW9ucyB0aGF0IGFscmVhZHkgc2hhcmVkIGEga2V5IHN0cmluZy5cbiAgcmV0dXJuIGhhc2guZm52SGFzaChzdGFibGUpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYGZsb2NrKDIpYCB0aHJvdWdoIEJ1biBGRkkgd2hlbiBwb3NzaWJsZS5cbiAqXG4gKiBNZW1vaXplZDogdGhlIEZGSSBpbXBvcnQgKyBsaWJjIGBkbG9wZW5gIHJ1biBvbmNlIHBlciBwcm9jZXNzLiBSZXR1cm5zXG4gKiBgdW5kZWZpbmVkYCBvbiBXaW5kb3dzLCB1bmRlciBwbGFpbiBOb2RlLCBvciB3aGVuIGxpYmMgY2Fubm90IGJlIGxvYWRlZCDigJRcbiAqIGNhbGxlcnMgZmFsbCB0aHJvdWdoIHRvIHRoZSBuZXh0IGJhY2tlbmQuIEEgbWlzcyBpcyBjYWNoZWQgdG9vLCBzbyBhIHByb2Nlc3NcbiAqIHRoYXQgY2Fubm90IGZsb2NrIG5ldmVyIHJldHJpZXMgdGhlIGxvYWQuXG4gKi9cbmNvbnN0IHJlc29sdmVGbG9jayA9IGZ1bmN0aW9uVXRpbHMubWVtb2l6ZShhc3luYyAoKTogUHJvbWlzZTxGbG9ja0ZuIHwgdW5kZWZpbmVkPiA9PiB7XG4gIGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSBcIndpbjMyXCIpIHJldHVybiB1bmRlZmluZWQ7XG4gIGlmICghcHJvY2Vzcy52ZXJzaW9ucy5idW4pIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgdHJ5IHtcbiAgICAvLyBEeW5hbWljIHNwZWNpZmllciBzbyBgdHNjYCAobm8gYEB0eXBlc2AgZm9yIGBidW46ZmZpYCkgZG9lcyBub3QgcmVzb2x2ZSBpdDtcbiAgICAvLyB0aGUgaW1wb3J0IG9ubHkgc3VjY2VlZHMgdW5kZXIgQnVuIGF0IHJ1bnRpbWUuXG4gICAgY29uc3Qgc3BlY2lmaWVyID0gXCJidW46ZmZpXCI7XG4gICAgY29uc3QgZmZpID0gKGF3YWl0IGltcG9ydChzcGVjaWZpZXIpKSBhcyB1bmtub3duIGFzIEJ1bkZmaU1vZHVsZTtcbiAgICBjb25zdCBsaWJQYXRoID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gXCJkYXJ3aW5cIiA/IFwibGliU3lzdGVtLkIuZHlsaWJcIiA6IGBsaWJjLiR7ZmZpLnN1ZmZpeH1gO1xuICAgIGNvbnN0IGxpYiA9IGZmaS5kbG9wZW4obGliUGF0aCwge1xuICAgICAgZmxvY2s6IHsgYXJnczogW1wiaTMyXCIsIFwiaTMyXCJdLCByZXR1cm5zOiBcImkzMlwiIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIGxpYi5zeW1ib2xzLmZsb2NrO1xuICB9IGNhdGNoIChjYXVzZSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhcImZsb2NrIEZGSSB1bmF2YWlsYWJsZVwiLCB7IGVycm9yOiBlcnJvclV0aWxzLmVycm9yTWVzc2FnZShjYXVzZSkgfSk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufSk7XG5cbmFzeW5jIGZ1bmN0aW9uIGhvbGRGbG9jazxUPihcbiAgbG9ja1BhdGg6IHN0cmluZyxcbiAgZmxvY2s6IEZsb2NrRm4sXG4gIGRlYWRsaW5lOiBudW1iZXIgfCB1bmRlZmluZWQsXG4gIGZuOiAoKSA9PiBUIHwgUHJvbWlzZTxUPixcbiAgb25XYWl0OiAoKSA9PiB2b2lkLFxuKTogUHJvbWlzZTxUPiB7XG4gIGF3YWl0IGVuc3VyZVBhcmVudERpcihsb2NrUGF0aCk7XG4gIGNvbnN0IGhhbmRsZSA9IGF3YWl0IG9wZW4obG9ja1BhdGgsIFwiYStcIik7XG4gIHRyeSB7XG4gICAgYXdhaXQgd2FpdEZvckZsb2NrKGhhbmRsZS5mZCwgZmxvY2ssIGxvY2tQYXRoLCBkZWFkbGluZSwgb25XYWl0KTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IGZuKCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGZsb2NrKGhhbmRsZS5mZCwgTE9DS19VTik7XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIGF3YWl0IGhhbmRsZS5jbG9zZSgpLmNhdGNoKCgpID0+IHt9KTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiB3YWl0Rm9yRmxvY2soXG4gIGZkOiBudW1iZXIsXG4gIGZsb2NrOiBGbG9ja0ZuLFxuICBsb2NrUGF0aDogc3RyaW5nLFxuICBkZWFkbGluZTogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICBvbldhaXQ6ICgpID0+IHZvaWQsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgbGV0IHdhaXRpbmcgPSBmYWxzZTtcbiAgZm9yICg7Oykge1xuICAgIGNvbnN0IHJjID0gZmxvY2soZmQsIExPQ0tfRVggfCBMT0NLX05CKTtcbiAgICBpZiAocmMgPT09IDApIHJldHVybjtcbiAgICBpZiAoIXdhaXRpbmcpIHtcbiAgICAgIHdhaXRpbmcgPSB0cnVlO1xuICAgICAgb25XYWl0KCk7XG4gICAgfVxuICAgIGFzc2VydEJlZm9yZURlYWRsaW5lKGxvY2tQYXRoLCBkZWFkbGluZSk7XG4gICAgYXdhaXQgYXN5bmNVdGlscy5zbGVlcChQT0xMX01TKTtcbiAgfVxufVxuXG4vKipcbiAqIFBvcnRhYmxlIGxvY2stZGlyZWN0b3J5IG93bmVyc2hpcCB0aHJvdWdoIGBwcm9wZXItbG9ja2ZpbGVgLlxuICovXG5hc3luYyBmdW5jdGlvbiBob2xkTG9ja0RpcmVjdG9yeTxUPihcbiAgbG9ja1BhdGg6IHN0cmluZyxcbiAgZGVhZGxpbmU6IG51bWJlciB8IHVuZGVmaW5lZCxcbiAgZm46ICgpID0+IFQgfCBQcm9taXNlPFQ+LFxuICBvbldhaXQ6ICgpID0+IHZvaWQsXG4pOiBQcm9taXNlPFQ+IHtcbiAgYXdhaXQgZW5zdXJlUGFyZW50RGlyKGxvY2tQYXRoKTtcbiAgY29uc3QgcmVsZWFzZSA9IGF3YWl0IGFjcXVpcmVMb2NrRGlyZWN0b3J5KGxvY2tQYXRoLCBkZWFkbGluZSwgb25XYWl0KTtcbiAgbGV0IGNhbGxiYWNrRXJyb3I6IHVua25vd247XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IGZuKCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY2FsbGJhY2tFcnJvciA9IGVycm9yO1xuICAgIHRocm93IGVycm9yO1xuICB9IGZpbmFsbHkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCByZWxlYXNlKCk7XG4gICAgfSBjYXRjaCAoY2F1c2UpIHtcbiAgICAgIGlmIChjYWxsYmFja0Vycm9yID09PSB1bmRlZmluZWQgfHwgKGNhdXNlIGFzIE5vZGVKUy5FcnJub0V4Y2VwdGlvbikuY29kZSAhPT0gXCJFUkVMRUFTRURcIikge1xuICAgICAgICB0aHJvdyBjYXVzZTtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci53YXJuKFwibG9jayByZWxlYXNlIHdhcyBhbHJlYWR5IGNvbXBsZXRlZCBhZnRlciBjYWxsYmFjayBmYWlsdXJlXCIsIHtcbiAgICAgICAgcGF0aDogbG9ja1BhdGgsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gYWNxdWlyZUxvY2tEaXJlY3RvcnkoXG4gIGxvY2tQYXRoOiBzdHJpbmcsXG4gIGRlYWRsaW5lOiBudW1iZXIgfCB1bmRlZmluZWQsXG4gIG9uV2FpdDogKCkgPT4gdm9pZCxcbik6IFByb21pc2U8KCkgPT4gUHJvbWlzZTx2b2lkPj4ge1xuICBsZXQgd2FpdGluZyA9IGZhbHNlO1xuICBmb3IgKDs7KSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBsb2NrZmlsZS5sb2NrKGxvY2tQYXRoLCB7XG4gICAgICAgIHJlYWxwYXRoOiBmYWxzZSxcbiAgICAgICAgc3RhbGU6IFNUQUxFX01TLFxuICAgICAgICB1cGRhdGU6IFVQREFURV9NUyxcbiAgICAgICAgcmV0cmllczogMCxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGNhdXNlKSB7XG4gICAgICBjb25zdCBlcnIgPSBjYXVzZSBhcyBOb2RlSlMuRXJybm9FeGNlcHRpb247XG4gICAgICBpZiAoZXJyLmNvZGUgIT09IFwiRUxPQ0tFRFwiKSB0aHJvdyBlcnJvclV0aWxzLnRvRXJyb3IoY2F1c2UpO1xuICAgICAgaWYgKCF3YWl0aW5nKSB7XG4gICAgICAgIHdhaXRpbmcgPSB0cnVlO1xuICAgICAgICBvbldhaXQoKTtcbiAgICAgIH1cbiAgICAgIGFzc2VydEJlZm9yZURlYWRsaW5lKGxvY2tQYXRoLCBkZWFkbGluZSk7XG4gICAgICBhd2FpdCBhc3luY1V0aWxzLnNsZWVwKFBPTExfTVMpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhc3NlcnRCZWZvcmVEZWFkbGluZShsb2NrUGF0aDogc3RyaW5nLCBkZWFkbGluZTogbnVtYmVyIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gIGlmIChkZWFkbGluZSAhPT0gdW5kZWZpbmVkICYmIERhdGUubm93KCkgPj0gZGVhZGxpbmUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFRpbWVkIG91dCB3YWl0aW5nIGZvciBmaWxlIGxvY2s6ICR7bG9ja1BhdGh9YCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZW5zdXJlUGFyZW50RGlyKGxvY2tQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgbWtkaXIoZGlybmFtZShsb2NrUGF0aCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xufVxuIl19
package/package.json CHANGED
@@ -26,8 +26,7 @@
26
26
  "typescript": "^5.9.3"
27
27
  },
28
28
  "dependencies": {
29
- "@dbx-tools/core-rs": "^0.9.19",
30
- "@dbx-tools/shared-core": "^0.9.19",
29
+ "@dbx-tools/shared-core": "^0.9.28",
31
30
  "extract-zip": "^2.0.1",
32
31
  "proper-lockfile": "^4.1.2",
33
32
  "semver": "^7.7.3",
@@ -69,7 +68,7 @@
69
68
  "./package.json": "./package.json"
70
69
  }
71
70
  },
72
- "version": "0.9.19",
71
+ "version": "0.9.28",
73
72
  "types": "./lib/index.d.ts",
74
73
  "type": "module",
75
74
  "exports": {
package/src/bin.ts CHANGED
@@ -21,8 +21,10 @@ import { basename, join } from "node:path";
21
21
  import { fileURLToPath } from "node:url";
22
22
  import { promisify } from "node:util";
23
23
 
24
- import { errorUtils, log } from "@dbx-tools/shared-core";
24
+ import * as errorUtils from "@dbx-tools/shared-core/error-utils";
25
+ import * as log from "@dbx-tools/shared-core/log";
25
26
  import extractZip from "extract-zip";
27
+ import { coerce, gte, type SemVer } from "semver";
26
28
  import { x as extractTar } from "tar";
27
29
 
28
30
  import { withFileLock } from "./file-lock.ts";
@@ -95,11 +97,6 @@ export interface BinUrlResolveContext {
95
97
  export interface BinSource {
96
98
  url: string;
97
99
  sha256?: string;
98
- /**
99
- * Skip `--version` on this candidate. Use when the source already identified
100
- * the requested version, such as `cargo install --version`.
101
- */
102
- trustVersion?: boolean;
103
100
  }
104
101
 
105
102
  /** A download source resolved only when the executable is not already installed. */
@@ -172,25 +169,20 @@ export function parseVersion({ stdout, stderr }: BinVersionOutput): string | und
172
169
  return detectedVersions(stdout).at(0)?.raw ?? detectedVersions(stderr).at(0)?.raw;
173
170
  }
174
171
 
175
- function numericVersion(version: string, strict: boolean): number[] | undefined {
176
- const pattern = strict ? /^\s*v?(\d+(?:\.\d+){0,2})\s*$/i : /\bv?(\d+(?:\.\d+){0,2})/i;
177
- const match = pattern.exec(version);
178
- return match?.[1]?.split(".").map(Number);
172
+ function minimumSemVer(version: string): SemVer | undefined {
173
+ if (!/^\s*v?\d+(?:\.\d+){0,2}\s*$/i.test(version)) return undefined;
174
+ return coerce(version, { loose: true }) ?? undefined;
179
175
  }
180
176
 
181
- function meetsMinVersion(version: string, minVersion: string | undefined): boolean {
182
- if (!minVersion) return true;
183
- const actual = numericVersion(version, false);
184
- const minimum = numericVersion(minVersion, true);
177
+ /** Compare a detected tool version against a one-to-three-component minimum. */
178
+ export function isVersionAtLeast(version: string, minVersion: string): boolean {
179
+ const minimum = minimumSemVer(minVersion);
185
180
  if (!minimum) {
186
181
  throw new TypeError(`invalid minimum binary version: ${minVersion}`);
187
182
  }
183
+ const actual = coerce(version, { loose: true });
188
184
  if (!actual) return false;
189
- for (let index = 0; index < Math.max(actual.length, minimum.length); index += 1) {
190
- const difference = (actual[index] ?? 0) - (minimum[index] ?? 0);
191
- if (difference !== 0) return difference > 0;
192
- }
193
- return true;
185
+ return gte(actual, minimum);
194
186
  }
195
187
 
196
188
  async function isValidBin(path: string, options: BinOptions): Promise<boolean> {
@@ -227,7 +219,9 @@ async function isValidBin(path: string, options: BinOptions): Promise<boolean> {
227
219
  stdout,
228
220
  stderr,
229
221
  });
230
- const valid = version !== undefined && meetsMinVersion(version, options.minVersion);
222
+ const valid =
223
+ version !== undefined &&
224
+ (options.minVersion === undefined || isVersionAtLeast(version, options.minVersion));
231
225
  logger.debug("binary version checked", {
232
226
  path,
233
227
  version,
@@ -367,7 +361,7 @@ export async function ensure(
367
361
  url: BinUrl,
368
362
  options: BinOptions = {},
369
363
  ): Promise<BinContext> {
370
- if (options.minVersion && !numericVersion(options.minVersion, true)) {
364
+ if (options.minVersion && !minimumSemVer(options.minVersion)) {
371
365
  throw new TypeError(`invalid minimum binary version: ${options.minVersion}`);
372
366
  }
373
367
  const destination = context(name, options.homeDir ?? homedir(), options.destination);
@@ -400,13 +394,8 @@ export async function ensure(
400
394
  logger.debug("resolved binary source", { name, from });
401
395
  const selected = await selectedBin(destination, source, temp, options);
402
396
  await chmod(selected, 0o755);
403
- const accepted = source.trustVersion ? { ...options, skipVersionCheck: true } : options;
404
- if (!(await isValidBin(selected, accepted))) {
405
- throw new Error(
406
- source.trustVersion
407
- ? `selected binary is not executable: ${selected}`
408
- : `selected binary has no acceptable version: ${selected}`,
409
- );
397
+ if (!(await isValidBin(selected, options))) {
398
+ throw new Error(`selected binary has no acceptable version: ${selected}`);
410
399
  }
411
400
 
412
401
  await mkdir(destination.binDir, { recursive: true });
@@ -415,7 +404,7 @@ export async function ensure(
415
404
  await chmod(staged, 0o755);
416
405
  await rename(staged, destination.path);
417
406
  staged = undefined;
418
- if (!(await isValidBin(destination.path, accepted))) {
407
+ if (!(await isValidBin(destination.path, options))) {
419
408
  throw new Error(`installed binary is invalid after rename: ${destination.path}`);
420
409
  }
421
410
  logger.info("installed binary", {
@@ -30,8 +30,7 @@ import { spawnSync } from "node:child_process";
30
30
  import { readFileSync } from "node:fs";
31
31
  import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
32
32
  import { parseEnv } from "node:util";
33
- import { isDatabricksAppEnvironment } from "@dbx-tools/core-rs";
34
- import { json, log, object, stringUtils } from "@dbx-tools/shared-core";
33
+ import { environmentUtils, json, log, object, stringUtils } from "@dbx-tools/shared-core";
35
34
  import { parse as parseYaml } from "yaml";
36
35
  import { z } from "zod";
37
36
  import { cachedRecord, statSync } from "./file.ts";
@@ -251,11 +250,7 @@ export function getBundlePath(data: Record<string, unknown>, path: string): stri
251
250
  export function isDatabricksAppEnv(
252
251
  source: Record<string, string | undefined> = process.env,
253
252
  ): boolean {
254
- return isDatabricksAppEnvironment(
255
- new Map(
256
- Object.entries(source).filter((entry): entry is [string, string] => entry[1] !== undefined),
257
- ),
258
- );
253
+ return environmentUtils.isDatabricksAppEnv(source);
259
254
  }
260
255
 
261
256
  /** Exact, uppercase, and tokenized-uppercase names for a human-friendly key. */
package/src/exec.ts CHANGED
@@ -554,8 +554,15 @@ export function spawn(...args: SpawnArgs<ExecOptions>): ChildProcessResult {
554
554
  exitCode = await waitForExit(proc);
555
555
  await Promise.all([stdinWrite, ...reads]);
556
556
  } catch (err) {
557
- await Promise.allSettled([stdinWrite, ...reads]);
558
- if (!isCommandNotFoundError(err)) throw err;
557
+ if (!isCommandNotFoundError(err)) {
558
+ await Promise.allSettled([stdinWrite, ...reads]);
559
+ throw err;
560
+ }
561
+ proc.stdin?.destroy();
562
+ proc.stdout?.destroy();
563
+ proc.stderr?.destroy();
564
+ await Promise.allSettled([stdinWrite]);
565
+ for (const read of reads) void read.catch(() => undefined);
559
566
  commandNotFoundError = err;
560
567
  exitCode = COMMAND_NOT_FOUND_EXIT_CODE;
561
568
  }
package/src/file-lock.ts CHANGED
@@ -26,7 +26,12 @@ import { mkdir, open } from "node:fs/promises";
26
26
  import { tmpdir } from "node:os";
27
27
  import { dirname, join } from "node:path";
28
28
 
29
- import { asyncUtils, errorUtils, functionUtils, hash, log, object } from "@dbx-tools/shared-core";
29
+ import * as asyncUtils from "@dbx-tools/shared-core/async-utils";
30
+ import * as errorUtils from "@dbx-tools/shared-core/error-utils";
31
+ import * as functionUtils from "@dbx-tools/shared-core/function-utils";
32
+ import * as hash from "@dbx-tools/shared-core/hash";
33
+ import * as log from "@dbx-tools/shared-core/log";
34
+ import * as object from "@dbx-tools/shared-core/object";
30
35
  import lockfile from "proper-lockfile";
31
36
 
32
37
  const logger = log.logger("core:file-lock");
@@ -77,6 +82,12 @@ export interface FileLockOptions {
77
82
  onWait?: (acquisition: FileLockAcquisition) => void;
78
83
  }
79
84
 
85
+ /** Explicit cross-process lease returned by {@link acquireFileLock}. */
86
+ export interface FileLockLease extends FileLockAcquisition {
87
+ /** Release the held lock. Repeated calls are safe. */
88
+ release(): Promise<void>;
89
+ }
90
+
80
91
  type FlockFn = (fd: number, operation: number) => number;
81
92
 
82
93
  interface BunFfiModule {
@@ -142,6 +153,58 @@ export async function withFileLock<T>(
142
153
  throw new Error("withFileLock: no lock backend available");
143
154
  }
144
155
 
156
+ /**
157
+ * Acquire a cross-process lock and return an explicit lease.
158
+ *
159
+ * Prefer {@link withFileLock} for ordinary JavaScript callers. This lower-level
160
+ * shape exists for storage adapters and cross-language bridges that cannot
161
+ * conveniently pass an async callback through their FFI boundary.
162
+ */
163
+ export async function acquireFileLock(
164
+ key: unknown,
165
+ options: FileLockOptions = {},
166
+ ): Promise<FileLockLease> {
167
+ let acquisition: FileLockAcquisition | undefined;
168
+ let resolveAcquired!: () => void;
169
+ let rejectAcquired!: (error: unknown) => void;
170
+ let resolveRelease!: () => void;
171
+ const acquired = new Promise<void>((resolve, reject) => {
172
+ resolveAcquired = resolve;
173
+ rejectAcquired = reject;
174
+ });
175
+ const released = new Promise<void>((resolve) => {
176
+ resolveRelease = resolve;
177
+ });
178
+ const run = withFileLock(
179
+ key,
180
+ async () => {
181
+ resolveAcquired();
182
+ await released;
183
+ },
184
+ {
185
+ ...options,
186
+ onAcquire: (value) => {
187
+ acquisition = value;
188
+ options.onAcquire?.(value);
189
+ },
190
+ },
191
+ );
192
+ void run.catch(rejectAcquired);
193
+ await acquired;
194
+ if (!acquisition) throw new Error("File-lock backend was not recorded");
195
+
196
+ let active = true;
197
+ return {
198
+ ...acquisition,
199
+ async release() {
200
+ if (!active) return;
201
+ active = false;
202
+ resolveRelease();
203
+ await run;
204
+ },
205
+ };
206
+ }
207
+
145
208
  /** Canonical filesystem-safe id for a lock key. */
146
209
  function lockId(key: unknown): string {
147
210
  const stable = object