@dbx-tools/shared-core 0.9.5 → 0.9.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,16 +8,16 @@ namespaces so call sites stay explicit:
8
8
 
9
9
  ```ts
10
10
  import {
11
- async,
12
- brand,
13
- error,
11
+ asyncUtils,
12
+ brandUtils,
13
+ errorUtils,
14
14
  hash,
15
15
  http,
16
16
  json,
17
17
  log,
18
18
  net,
19
19
  object,
20
- string,
20
+ stringUtils,
21
21
  } from "@dbx-tools/shared-core";
22
22
  ```
23
23
 
@@ -46,11 +46,11 @@ Key features:
46
46
  ## Brand Context
47
47
 
48
48
  ```ts
49
- import { brand } from "@dbx-tools/shared-core";
49
+ import { brandUtils } from "@dbx-tools/shared-core";
50
50
 
51
- const context = brand.parseBrandContext({ name: "Acme Data" });
52
- const jsonSchema = brand.brandContextJsonSchema();
53
- const instructions = brand.brandContextPrompt(context);
51
+ const context = brandUtils.parseBrandContext({ name: "Acme Data" });
52
+ const jsonSchema = brandUtils.brandContextJsonSchema();
53
+ const instructions = brandUtils.brandContextPrompt(context);
54
54
  ```
55
55
 
56
56
  `BrandContextSchema` validates identity, theme-aware assets, colors,
@@ -62,7 +62,7 @@ to discover and read YAML/JSON files, and
62
62
  ## Async Control
63
63
 
64
64
  ```ts
65
- for await (const status of async.poll(fetchStatus, {
65
+ for await (const status of asyncUtils.poll(fetchStatus, {
66
66
  intervalMs: 250,
67
67
  timeoutMs: 30_000,
68
68
  predicate: (s) => s !== "READY",
@@ -70,11 +70,11 @@ for await (const status of async.poll(fetchStatus, {
70
70
  render(status);
71
71
  }
72
72
 
73
- await async.sleep(500, abortSignal);
73
+ await asyncUtils.sleep(500, abortSignal);
74
74
  ```
75
75
 
76
- `async.poll()` is useful for Databricks APIs that expose long-running state.
77
- `async.tieAbortSignal()` and `async.sleep()` let route handlers connect caller
76
+ `asyncUtils.poll()` is useful for Databricks APIs that expose long-running state.
77
+ `asyncUtils.tieAbortSignal()` and `asyncUtils.sleep()` let route handlers connect caller
78
78
  cancellation to background work.
79
79
 
80
80
  ## Error Handling
@@ -83,14 +83,14 @@ cancellation to background work.
83
83
  try {
84
84
  await run();
85
85
  } catch (err) {
86
- logger.warn("run failed", { error: error.errorMessage(err) });
87
- const ctx = error.errorContext(err);
86
+ logger.warn("run failed", { error: errorUtils.errorMessage(err) });
87
+ const ctx = errorUtils.errorContext(err);
88
88
  return Response.json({ message: ctx.message }, { status: ctx.status ?? 500 });
89
89
  }
90
90
  ```
91
91
 
92
- `error.toError()`, `error.errorMessage()`, `error.errorMessages()`, and
93
- `error.errorNodes()` normalize unknown thrown values. `error.errorContext()`
92
+ `errorUtils.toError()`, `errorUtils.errorMessage()`, `errorUtils.errorMessages()`, and
93
+ `errorUtils.errorNodes()` normalize unknown thrown values. `errorUtils.errorContext()`
94
94
  extracts HTTP-ish status/message detail from nested errors.
95
95
 
96
96
  ## Hashes And Ids
@@ -127,26 +127,26 @@ reading a file this repo generated itself.
127
127
  ## Strings And Descriptions
128
128
 
129
129
  ```ts
130
- const slug = string.toSlug("My Cool Project!");
131
- const id = string.toIdentifierWithOptions({ delimiter: "_" }, "Model Name");
132
- const unique = string.toUniqueSlug("Send Email", { fallbackPrefix: "tool" });
133
- const description = string.toDescription([
130
+ const slug = stringUtils.toSlug("My Cool Project!");
131
+ const id = stringUtils.toIdentifierWithOptions({ delimiter: "_" }, "Model Name");
132
+ const unique = stringUtils.toUniqueSlug("Send Email", { fallbackPrefix: "tool" });
133
+ const description = stringUtils.toDescription([
134
134
  "Answer with SQL first.",
135
135
  { "When data is missing": "Say what is missing." },
136
136
  ]);
137
137
  ```
138
138
 
139
- `string.tokenize()`, `toSlug()`, and `toIdentifier()` keep package names, tool
139
+ `stringUtils.tokenize()`, `toSlug()`, and `toIdentifier()` keep package names, tool
140
140
  ids, schema ids, and generated labels consistent. `toDescription()` turns nested
141
141
  description data into prompt/tool text without hand-concatenating paragraphs.
142
142
 
143
143
  Three helpers exist so call sites stop re-implementing them:
144
144
 
145
145
  ```ts
146
- const label = string.toLabel("web_search"); // "Web Search"
147
- const name = string.capitalize(segment); // no charAt(0).toUpperCase() idiom
148
- const host = string.trimToEmpty(parsed.host); // unknown JSON field -> string
149
- const allowed = string.parseList(process.env.ALLOWED_URLS);
146
+ const label = stringUtils.toLabel("web_search"); // "Web Search"
147
+ const name = stringUtils.capitalize(segment); // no charAt(0).toUpperCase() idiom
148
+ const host = stringUtils.trimToEmpty(parsed.host); // unknown JSON field -> string
149
+ const allowed = stringUtils.parseList(process.env.ALLOWED_URLS);
150
150
  ```
151
151
 
152
152
  `toLabel()` and `capitalize()` are the humanizers for identifiers and path
@@ -325,7 +325,7 @@ parse IPv4 and IPv6 into a shared bigint comparison model.
325
325
  ## Allow-List Patterns
326
326
 
327
327
  ```ts
328
- // One matcher from a config array OR a delimited env string.
328
+ // One matcher from a config array OR a delimited env stringUtils.
329
329
  const forwardable = pattern.toPatternMatcher(["x-mastra-*", "/^x-trace-/", "x-tenant"]);
330
330
 
331
331
  forwardable("x-mastra-model"); // true (glob)
@@ -337,7 +337,7 @@ forwardable("x-forwarded-user"); // false
337
337
  Every configurable allow-list in this repo takes the same three shapes, so the
338
338
  compilation lives here once: a `/regex/` literal (with optional flags), a
339
339
  shell-style glob (`*`, `?`, anchored at both ends, all other characters escaped),
340
- or a literal compared whole-string. Matching is case-insensitive by default -
340
+ or a literal compared whole-stringUtils. Matching is case-insensitive by default -
341
341
  what HTTP header names and email addresses both want - and `caseSensitive` opts
342
342
  out.
343
343
 
@@ -366,12 +366,12 @@ the request.
366
366
  ## Memoization
367
367
 
368
368
  ```ts
369
- const getRanges = functionModule.memoize(fetchRanges, {
369
+ const getRanges = functionUtils.memoize(fetchRanges, {
370
370
  ttlMs: 24 * 60 * 60 * 1000,
371
371
  });
372
372
  ```
373
373
 
374
- `functionModule.memoize()` caches sync or async factories, evicts rejected
374
+ `functionUtils.memoize()` caches sync or async factories, evicts rejected
375
375
  promises, and supports TTL-based refresh. It is useful for public metadata feeds,
376
376
  SDK catalogues, and expensive computed constants.
377
377
 
@@ -397,11 +397,11 @@ when disabled.
397
397
 
398
398
  ## Modules
399
399
 
400
- - `async` - polling, sleep, and abort-signal wiring.
401
- - `error` - unknown-error normalization and HTTP-ish error context.
400
+ - `asyncUtils` - polling, sleep, and abort-signal wiring.
401
+ - `errorUtils` - unknown-error normalization and HTTP-ish error context.
402
402
  - `hash` - ids, FNV hashes, and base32 encoding.
403
403
  - `json` - non-throwing `parse()` and record-narrowing `parseRecord()`.
404
- - `string` - tokenization, slugs, identifiers, human labels, string coercion,
404
+ - `stringUtils` - tokenization, slugs, identifiers, human labels, string coercion,
405
405
  config lists, descriptions, pluralization, and HTML escaping.
406
406
  - `object` - record checks, number/boolean/date/duration coercion, present-only
407
407
  field spreading, deep equality, JSON-round-trip guards
@@ -414,6 +414,6 @@ when disabled.
414
414
  - `execution` - direct executor fallback, cancellation merging, and result unwrapping.
415
415
  - `net` - URL building, email parsing, path matching, IP/CIDR helpers.
416
416
  - `token` - JWT payload and scope readers.
417
- - `functionModule` - memoization.
417
+ - `functionUtils` - memoization.
418
418
  - `log` - tagged leveled logging.
419
- - `brand` - Zod schema, defaults, JSON Schema, and LLM prompt serialization.
419
+ - `brandUtils` - Zod schema, defaults, JSON Schema, and LLM prompt serialization.
package/index.ts CHANGED
@@ -3,12 +3,12 @@
3
3
  // Hand edits are overwritten on the next watch; this file is read-only.
4
4
 
5
5
  export const PACKAGE_IDENTIFIER = "@dbx-tools/shared-core";
6
- export const PACKAGE_VERSION = "0.9.5";
7
- export * as async from "./src/async.ts";
8
- export * as brand from "./src/brand.ts";
9
- export * as error from "./src/error.ts";
6
+ export const PACKAGE_VERSION = "0.9.6";
7
+ export * as asyncUtils from "./src/async-utils.ts";
8
+ export * as brandUtils from "./src/brand-utils.ts";
9
+ export * as errorUtils from "./src/error-utils.ts";
10
10
  export * as execution from "./src/execution.ts";
11
- export * as functionModule from "./src/function.ts";
11
+ export * as functionUtils from "./src/function-utils.ts";
12
12
  export * as hash from "./src/hash.ts";
13
13
  export * as http from "./src/http.ts";
14
14
  export * as json from "./src/json.ts";
@@ -17,19 +17,19 @@ export * as net from "./src/net.ts";
17
17
  export * as object from "./src/object.ts";
18
18
  export * as pattern from "./src/pattern.ts";
19
19
  export * as predicate from "./src/predicate.ts";
20
- export * as string from "./src/string.ts";
20
+ export * as stringUtils from "./src/string-utils.ts";
21
21
  export * as token from "./src/token.ts";
22
- export type { PollContext, PollProducer, PollOptions } from "./src/async.ts";
23
- export { DEFAULT_BRAND_ASSETS, BrandAssetSetSchema, BrandColorsSchema, BrandVoiceSchema, BrandContextSchema, defaultBrandContext } from "./src/brand.ts";
24
- export type { BrandContext, BrandContextInput, BrandAssetSet } from "./src/brand.ts";
25
- export type { ErrorContext } from "./src/error.ts";
22
+ export type { ConcurrentErrorMode, MapConcurrentOptions, PollContext, PollProducer, PollOptions } from "./src/async-utils.ts";
23
+ export { DEFAULT_BRAND_ASSETS, BrandAssetSetSchema, BrandColorsSchema, BrandVoiceSchema, BrandContextSchema, defaultBrandContext } from "./src/brand-utils.ts";
24
+ export type { BrandContext, BrandContextInput, BrandAssetSet } from "./src/brand-utils.ts";
25
+ export type { ErrorContext } from "./src/error-utils.ts";
26
26
  export type { ExecutionResult, Executor, ExecutionFailure, RunOptions } from "./src/execution.ts";
27
- export type { MemoizeOptions } from "./src/function.ts";
27
+ export type { MemoizeOptions } from "./src/function-utils.ts";
28
28
  export type { HeaderLike } from "./src/http.ts";
29
29
  export type { LogLevel, Logger } from "./src/log.ts";
30
30
  export type { UrlLike, IpVersion, ParsedIp, Cidr, UrlBuilder, ParseEmailsOptions } from "./src/net.ts";
31
31
  export type { Sequence, Container, Collection, OneOrMany, NameLike, NonFunctionKeys, SerializablePrimitive, SerializableValue, ToNumberOptions, ToDateOptions, ToDurationOptions, DeepEqualComparator } from "./src/object.ts";
32
32
  export type { PatternOptions } from "./src/pattern.ts";
33
33
  export type { PredicateFunction, TypePredicateFunction, PredicateInput, Predicate } from "./src/predicate.ts";
34
- export type { TokenizeOptions, KeyOptions, IdentifierOptions, Description } from "./src/string.ts";
34
+ export type { TokenizeOptions, KeyOptions, IdentifierOptions, Description } from "./src/string-utils.ts";
35
35
  export { ACCESS_TOKEN_HEADER, USER_ID_HEADER, USER_EMAIL_HEADER } from "./src/token.ts";
package/lib/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  export declare const PACKAGE_IDENTIFIER = "@dbx-tools/shared-core";
2
- export declare const PACKAGE_VERSION = "0.9.5";
3
- export * as async from "./src/async.ts";
4
- export * as brand from "./src/brand.ts";
5
- export * as error from "./src/error.ts";
2
+ export declare const PACKAGE_VERSION = "0.9.6";
3
+ export * as asyncUtils from "./src/async-utils.ts";
4
+ export * as brandUtils from "./src/brand-utils.ts";
5
+ export * as errorUtils from "./src/error-utils.ts";
6
6
  export * as execution from "./src/execution.ts";
7
- export * as functionModule from "./src/function.ts";
7
+ export * as functionUtils from "./src/function-utils.ts";
8
8
  export * as hash from "./src/hash.ts";
9
9
  export * as http from "./src/http.ts";
10
10
  export * as json from "./src/json.ts";
@@ -13,19 +13,19 @@ export * as net from "./src/net.ts";
13
13
  export * as object from "./src/object.ts";
14
14
  export * as pattern from "./src/pattern.ts";
15
15
  export * as predicate from "./src/predicate.ts";
16
- export * as string from "./src/string.ts";
16
+ export * as stringUtils from "./src/string-utils.ts";
17
17
  export * as token from "./src/token.ts";
18
- export type { PollContext, PollProducer, PollOptions } from "./src/async.ts";
19
- export { DEFAULT_BRAND_ASSETS, BrandAssetSetSchema, BrandColorsSchema, BrandVoiceSchema, BrandContextSchema, defaultBrandContext } from "./src/brand.ts";
20
- export type { BrandContext, BrandContextInput, BrandAssetSet } from "./src/brand.ts";
21
- export type { ErrorContext } from "./src/error.ts";
18
+ export type { ConcurrentErrorMode, MapConcurrentOptions, PollContext, PollProducer, PollOptions } from "./src/async-utils.ts";
19
+ export { DEFAULT_BRAND_ASSETS, BrandAssetSetSchema, BrandColorsSchema, BrandVoiceSchema, BrandContextSchema, defaultBrandContext } from "./src/brand-utils.ts";
20
+ export type { BrandContext, BrandContextInput, BrandAssetSet } from "./src/brand-utils.ts";
21
+ export type { ErrorContext } from "./src/error-utils.ts";
22
22
  export type { ExecutionResult, Executor, ExecutionFailure, RunOptions } from "./src/execution.ts";
23
- export type { MemoizeOptions } from "./src/function.ts";
23
+ export type { MemoizeOptions } from "./src/function-utils.ts";
24
24
  export type { HeaderLike } from "./src/http.ts";
25
25
  export type { LogLevel, Logger } from "./src/log.ts";
26
26
  export type { UrlLike, IpVersion, ParsedIp, Cidr, UrlBuilder, ParseEmailsOptions } from "./src/net.ts";
27
27
  export type { Sequence, Container, Collection, OneOrMany, NameLike, NonFunctionKeys, SerializablePrimitive, SerializableValue, ToNumberOptions, ToDateOptions, ToDurationOptions, DeepEqualComparator } from "./src/object.ts";
28
28
  export type { PatternOptions } from "./src/pattern.ts";
29
29
  export type { PredicateFunction, TypePredicateFunction, PredicateInput, Predicate } from "./src/predicate.ts";
30
- export type { TokenizeOptions, KeyOptions, IdentifierOptions, Description } from "./src/string.ts";
30
+ export type { TokenizeOptions, KeyOptions, IdentifierOptions, Description } from "./src/string-utils.ts";
31
31
  export { ACCESS_TOKEN_HEADER, USER_ID_HEADER, USER_EMAIL_HEADER } from "./src/token.ts";
package/lib/index.js CHANGED
@@ -2,12 +2,12 @@
2
2
  // Regenerated from the exporting modules in ./src.
3
3
  // Hand edits are overwritten on the next watch; this file is read-only.
4
4
  export const PACKAGE_IDENTIFIER = "@dbx-tools/shared-core";
5
- export const PACKAGE_VERSION = "0.9.5";
6
- export * as async from "./src/async.js";
7
- export * as brand from "./src/brand.js";
8
- export * as error from "./src/error.js";
5
+ export const PACKAGE_VERSION = "0.9.6";
6
+ export * as asyncUtils from "./src/async-utils.js";
7
+ export * as brandUtils from "./src/brand-utils.js";
8
+ export * as errorUtils from "./src/error-utils.js";
9
9
  export * as execution from "./src/execution.js";
10
- export * as functionModule from "./src/function.js";
10
+ export * as functionUtils from "./src/function-utils.js";
11
11
  export * as hash from "./src/hash.js";
12
12
  export * as http from "./src/http.js";
13
13
  export * as json from "./src/json.js";
@@ -16,8 +16,8 @@ export * as net from "./src/net.js";
16
16
  export * as object from "./src/object.js";
17
17
  export * as pattern from "./src/pattern.js";
18
18
  export * as predicate from "./src/predicate.js";
19
- export * as string from "./src/string.js";
19
+ export * as stringUtils from "./src/string-utils.js";
20
20
  export * as token from "./src/token.js";
21
- export { DEFAULT_BRAND_ASSETS, BrandAssetSetSchema, BrandColorsSchema, BrandVoiceSchema, BrandContextSchema, defaultBrandContext } from "./src/brand.js";
21
+ export { DEFAULT_BRAND_ASSETS, BrandAssetSetSchema, BrandColorsSchema, BrandVoiceSchema, BrandContextSchema, defaultBrandContext } from "./src/brand-utils.js";
22
22
  export { ACCESS_TOKEN_HEADER, USER_ID_HEADER, USER_EMAIL_HEADER } from "./src/token.js";
23
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyx3QkFBd0IsQ0FBQztBQUMzRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDO0FBQ3ZDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLEtBQUssTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QyxPQUFPLEtBQUssS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sS0FBSyxTQUFTLE1BQU0sb0JBQW9CLENBQUM7QUFDaEQsT0FBTyxLQUFLLGNBQWMsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRCxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEtBQUssR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUNwQyxPQUFPLEtBQUssR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUNwQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxLQUFLLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG1CQUFtQixFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFZekosT0FBTyxFQUFFLG1CQUFtQixFQUFFLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gR0VORVJBVEVEIGJ5IHByb2plbiB3YXRjaCAtIERPIE5PVCBFRElULlxuLy8gUmVnZW5lcmF0ZWQgZnJvbSB0aGUgZXhwb3J0aW5nIG1vZHVsZXMgaW4gLi9zcmMuXG4vLyBIYW5kIGVkaXRzIGFyZSBvdmVyd3JpdHRlbiBvbiB0aGUgbmV4dCB3YXRjaDsgdGhpcyBmaWxlIGlzIHJlYWQtb25seS5cblxuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfSURFTlRJRklFUiA9IFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9IFwiMC45LjVcIjtcbmV4cG9ydCAqIGFzIGFzeW5jIGZyb20gXCIuL3NyYy9hc3luYy50c1wiO1xuZXhwb3J0ICogYXMgYnJhbmQgZnJvbSBcIi4vc3JjL2JyYW5kLnRzXCI7XG5leHBvcnQgKiBhcyBlcnJvciBmcm9tIFwiLi9zcmMvZXJyb3IudHNcIjtcbmV4cG9ydCAqIGFzIGV4ZWN1dGlvbiBmcm9tIFwiLi9zcmMvZXhlY3V0aW9uLnRzXCI7XG5leHBvcnQgKiBhcyBmdW5jdGlvbk1vZHVsZSBmcm9tIFwiLi9zcmMvZnVuY3Rpb24udHNcIjtcbmV4cG9ydCAqIGFzIGhhc2ggZnJvbSBcIi4vc3JjL2hhc2gudHNcIjtcbmV4cG9ydCAqIGFzIGh0dHAgZnJvbSBcIi4vc3JjL2h0dHAudHNcIjtcbmV4cG9ydCAqIGFzIGpzb24gZnJvbSBcIi4vc3JjL2pzb24udHNcIjtcbmV4cG9ydCAqIGFzIGxvZyBmcm9tIFwiLi9zcmMvbG9nLnRzXCI7XG5leHBvcnQgKiBhcyBuZXQgZnJvbSBcIi4vc3JjL25ldC50c1wiO1xuZXhwb3J0ICogYXMgb2JqZWN0IGZyb20gXCIuL3NyYy9vYmplY3QudHNcIjtcbmV4cG9ydCAqIGFzIHBhdHRlcm4gZnJvbSBcIi4vc3JjL3BhdHRlcm4udHNcIjtcbmV4cG9ydCAqIGFzIHByZWRpY2F0ZSBmcm9tIFwiLi9zcmMvcHJlZGljYXRlLnRzXCI7XG5leHBvcnQgKiBhcyBzdHJpbmcgZnJvbSBcIi4vc3JjL3N0cmluZy50c1wiO1xuZXhwb3J0ICogYXMgdG9rZW4gZnJvbSBcIi4vc3JjL3Rva2VuLnRzXCI7XG5leHBvcnQgdHlwZSB7IFBvbGxDb250ZXh0LCBQb2xsUHJvZHVjZXIsIFBvbGxPcHRpb25zIH0gZnJvbSBcIi4vc3JjL2FzeW5jLnRzXCI7XG5leHBvcnQgeyBERUZBVUxUX0JSQU5EX0FTU0VUUywgQnJhbmRBc3NldFNldFNjaGVtYSwgQnJhbmRDb2xvcnNTY2hlbWEsIEJyYW5kVm9pY2VTY2hlbWEsIEJyYW5kQ29udGV4dFNjaGVtYSwgZGVmYXVsdEJyYW5kQ29udGV4dCB9IGZyb20gXCIuL3NyYy9icmFuZC50c1wiO1xuZXhwb3J0IHR5cGUgeyBCcmFuZENvbnRleHQsIEJyYW5kQ29udGV4dElucHV0LCBCcmFuZEFzc2V0U2V0IH0gZnJvbSBcIi4vc3JjL2JyYW5kLnRzXCI7XG5leHBvcnQgdHlwZSB7IEVycm9yQ29udGV4dCB9IGZyb20gXCIuL3NyYy9lcnJvci50c1wiO1xuZXhwb3J0IHR5cGUgeyBFeGVjdXRpb25SZXN1bHQsIEV4ZWN1dG9yLCBFeGVjdXRpb25GYWlsdXJlLCBSdW5PcHRpb25zIH0gZnJvbSBcIi4vc3JjL2V4ZWN1dGlvbi50c1wiO1xuZXhwb3J0IHR5cGUgeyBNZW1vaXplT3B0aW9ucyB9IGZyb20gXCIuL3NyYy9mdW5jdGlvbi50c1wiO1xuZXhwb3J0IHR5cGUgeyBIZWFkZXJMaWtlIH0gZnJvbSBcIi4vc3JjL2h0dHAudHNcIjtcbmV4cG9ydCB0eXBlIHsgTG9nTGV2ZWwsIExvZ2dlciB9IGZyb20gXCIuL3NyYy9sb2cudHNcIjtcbmV4cG9ydCB0eXBlIHsgVXJsTGlrZSwgSXBWZXJzaW9uLCBQYXJzZWRJcCwgQ2lkciwgVXJsQnVpbGRlciwgUGFyc2VFbWFpbHNPcHRpb25zIH0gZnJvbSBcIi4vc3JjL25ldC50c1wiO1xuZXhwb3J0IHR5cGUgeyBTZXF1ZW5jZSwgQ29udGFpbmVyLCBDb2xsZWN0aW9uLCBPbmVPck1hbnksIE5hbWVMaWtlLCBOb25GdW5jdGlvbktleXMsIFNlcmlhbGl6YWJsZVByaW1pdGl2ZSwgU2VyaWFsaXphYmxlVmFsdWUsIFRvTnVtYmVyT3B0aW9ucywgVG9EYXRlT3B0aW9ucywgVG9EdXJhdGlvbk9wdGlvbnMsIERlZXBFcXVhbENvbXBhcmF0b3IgfSBmcm9tIFwiLi9zcmMvb2JqZWN0LnRzXCI7XG5leHBvcnQgdHlwZSB7IFBhdHRlcm5PcHRpb25zIH0gZnJvbSBcIi4vc3JjL3BhdHRlcm4udHNcIjtcbmV4cG9ydCB0eXBlIHsgUHJlZGljYXRlRnVuY3Rpb24sIFR5cGVQcmVkaWNhdGVGdW5jdGlvbiwgUHJlZGljYXRlSW5wdXQsIFByZWRpY2F0ZSB9IGZyb20gXCIuL3NyYy9wcmVkaWNhdGUudHNcIjtcbmV4cG9ydCB0eXBlIHsgVG9rZW5pemVPcHRpb25zLCBLZXlPcHRpb25zLCBJZGVudGlmaWVyT3B0aW9ucywgRGVzY3JpcHRpb24gfSBmcm9tIFwiLi9zcmMvc3RyaW5nLnRzXCI7XG5leHBvcnQgeyBBQ0NFU1NfVE9LRU5fSEVBREVSLCBVU0VSX0lEX0hFQURFUiwgVVNFUl9FTUFJTF9IRUFERVIgfSBmcm9tIFwiLi9zcmMvdG9rZW4udHNcIjtcbiJdfQ==
23
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyx3QkFBd0IsQ0FBQztBQUMzRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDO0FBQ3ZDLE9BQU8sS0FBSyxVQUFVLE1BQU0sc0JBQXNCLENBQUM7QUFDbkQsT0FBTyxLQUFLLFVBQVUsTUFBTSxzQkFBc0IsQ0FBQztBQUNuRCxPQUFPLEtBQUssVUFBVSxNQUFNLHNCQUFzQixDQUFDO0FBQ25ELE9BQU8sS0FBSyxTQUFTLE1BQU0sb0JBQW9CLENBQUM7QUFDaEQsT0FBTyxLQUFLLGFBQWEsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEtBQUssR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUNwQyxPQUFPLEtBQUssR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUNwQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxLQUFLLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEtBQUssV0FBVyxNQUFNLHVCQUF1QixDQUFDO0FBQ3JELE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG1CQUFtQixFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixFQUFFLG1CQUFtQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFZL0osT0FBTyxFQUFFLG1CQUFtQixFQUFFLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gR0VORVJBVEVEIGJ5IHByb2plbiB3YXRjaCAtIERPIE5PVCBFRElULlxuLy8gUmVnZW5lcmF0ZWQgZnJvbSB0aGUgZXhwb3J0aW5nIG1vZHVsZXMgaW4gLi9zcmMuXG4vLyBIYW5kIGVkaXRzIGFyZSBvdmVyd3JpdHRlbiBvbiB0aGUgbmV4dCB3YXRjaDsgdGhpcyBmaWxlIGlzIHJlYWQtb25seS5cblxuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfSURFTlRJRklFUiA9IFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9IFwiMC45LjZcIjtcbmV4cG9ydCAqIGFzIGFzeW5jVXRpbHMgZnJvbSBcIi4vc3JjL2FzeW5jLXV0aWxzLnRzXCI7XG5leHBvcnQgKiBhcyBicmFuZFV0aWxzIGZyb20gXCIuL3NyYy9icmFuZC11dGlscy50c1wiO1xuZXhwb3J0ICogYXMgZXJyb3JVdGlscyBmcm9tIFwiLi9zcmMvZXJyb3ItdXRpbHMudHNcIjtcbmV4cG9ydCAqIGFzIGV4ZWN1dGlvbiBmcm9tIFwiLi9zcmMvZXhlY3V0aW9uLnRzXCI7XG5leHBvcnQgKiBhcyBmdW5jdGlvblV0aWxzIGZyb20gXCIuL3NyYy9mdW5jdGlvbi11dGlscy50c1wiO1xuZXhwb3J0ICogYXMgaGFzaCBmcm9tIFwiLi9zcmMvaGFzaC50c1wiO1xuZXhwb3J0ICogYXMgaHR0cCBmcm9tIFwiLi9zcmMvaHR0cC50c1wiO1xuZXhwb3J0ICogYXMganNvbiBmcm9tIFwiLi9zcmMvanNvbi50c1wiO1xuZXhwb3J0ICogYXMgbG9nIGZyb20gXCIuL3NyYy9sb2cudHNcIjtcbmV4cG9ydCAqIGFzIG5ldCBmcm9tIFwiLi9zcmMvbmV0LnRzXCI7XG5leHBvcnQgKiBhcyBvYmplY3QgZnJvbSBcIi4vc3JjL29iamVjdC50c1wiO1xuZXhwb3J0ICogYXMgcGF0dGVybiBmcm9tIFwiLi9zcmMvcGF0dGVybi50c1wiO1xuZXhwb3J0ICogYXMgcHJlZGljYXRlIGZyb20gXCIuL3NyYy9wcmVkaWNhdGUudHNcIjtcbmV4cG9ydCAqIGFzIHN0cmluZ1V0aWxzIGZyb20gXCIuL3NyYy9zdHJpbmctdXRpbHMudHNcIjtcbmV4cG9ydCAqIGFzIHRva2VuIGZyb20gXCIuL3NyYy90b2tlbi50c1wiO1xuZXhwb3J0IHR5cGUgeyBDb25jdXJyZW50RXJyb3JNb2RlLCBNYXBDb25jdXJyZW50T3B0aW9ucywgUG9sbENvbnRleHQsIFBvbGxQcm9kdWNlciwgUG9sbE9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvYXN5bmMtdXRpbHMudHNcIjtcbmV4cG9ydCB7IERFRkFVTFRfQlJBTkRfQVNTRVRTLCBCcmFuZEFzc2V0U2V0U2NoZW1hLCBCcmFuZENvbG9yc1NjaGVtYSwgQnJhbmRWb2ljZVNjaGVtYSwgQnJhbmRDb250ZXh0U2NoZW1hLCBkZWZhdWx0QnJhbmRDb250ZXh0IH0gZnJvbSBcIi4vc3JjL2JyYW5kLXV0aWxzLnRzXCI7XG5leHBvcnQgdHlwZSB7IEJyYW5kQ29udGV4dCwgQnJhbmRDb250ZXh0SW5wdXQsIEJyYW5kQXNzZXRTZXQgfSBmcm9tIFwiLi9zcmMvYnJhbmQtdXRpbHMudHNcIjtcbmV4cG9ydCB0eXBlIHsgRXJyb3JDb250ZXh0IH0gZnJvbSBcIi4vc3JjL2Vycm9yLXV0aWxzLnRzXCI7XG5leHBvcnQgdHlwZSB7IEV4ZWN1dGlvblJlc3VsdCwgRXhlY3V0b3IsIEV4ZWN1dGlvbkZhaWx1cmUsIFJ1bk9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvZXhlY3V0aW9uLnRzXCI7XG5leHBvcnQgdHlwZSB7IE1lbW9pemVPcHRpb25zIH0gZnJvbSBcIi4vc3JjL2Z1bmN0aW9uLXV0aWxzLnRzXCI7XG5leHBvcnQgdHlwZSB7IEhlYWRlckxpa2UgfSBmcm9tIFwiLi9zcmMvaHR0cC50c1wiO1xuZXhwb3J0IHR5cGUgeyBMb2dMZXZlbCwgTG9nZ2VyIH0gZnJvbSBcIi4vc3JjL2xvZy50c1wiO1xuZXhwb3J0IHR5cGUgeyBVcmxMaWtlLCBJcFZlcnNpb24sIFBhcnNlZElwLCBDaWRyLCBVcmxCdWlsZGVyLCBQYXJzZUVtYWlsc09wdGlvbnMgfSBmcm9tIFwiLi9zcmMvbmV0LnRzXCI7XG5leHBvcnQgdHlwZSB7IFNlcXVlbmNlLCBDb250YWluZXIsIENvbGxlY3Rpb24sIE9uZU9yTWFueSwgTmFtZUxpa2UsIE5vbkZ1bmN0aW9uS2V5cywgU2VyaWFsaXphYmxlUHJpbWl0aXZlLCBTZXJpYWxpemFibGVWYWx1ZSwgVG9OdW1iZXJPcHRpb25zLCBUb0RhdGVPcHRpb25zLCBUb0R1cmF0aW9uT3B0aW9ucywgRGVlcEVxdWFsQ29tcGFyYXRvciB9IGZyb20gXCIuL3NyYy9vYmplY3QudHNcIjtcbmV4cG9ydCB0eXBlIHsgUGF0dGVybk9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvcGF0dGVybi50c1wiO1xuZXhwb3J0IHR5cGUgeyBQcmVkaWNhdGVGdW5jdGlvbiwgVHlwZVByZWRpY2F0ZUZ1bmN0aW9uLCBQcmVkaWNhdGVJbnB1dCwgUHJlZGljYXRlIH0gZnJvbSBcIi4vc3JjL3ByZWRpY2F0ZS50c1wiO1xuZXhwb3J0IHR5cGUgeyBUb2tlbml6ZU9wdGlvbnMsIEtleU9wdGlvbnMsIElkZW50aWZpZXJPcHRpb25zLCBEZXNjcmlwdGlvbiB9IGZyb20gXCIuL3NyYy9zdHJpbmctdXRpbHMudHNcIjtcbmV4cG9ydCB7IEFDQ0VTU19UT0tFTl9IRUFERVIsIFVTRVJfSURfSEVBREVSLCBVU0VSX0VNQUlMX0hFQURFUiB9IGZyb20gXCIuL3NyYy90b2tlbi50c1wiO1xuIl19
@@ -1,3 +1,23 @@
1
+ /** Controls how {@link mapConcurrent} reacts when a worker rejects. */
2
+ export type ConcurrentErrorMode = "fail-fast" | "settle";
3
+ /** Bounded-worker settings for {@link mapConcurrent}. */
4
+ export interface MapConcurrentOptions {
5
+ /** Maximum number of callbacks running at once. */
6
+ concurrency: number;
7
+ /**
8
+ * `"fail-fast"` stops claiming new work after the first rejection.
9
+ * `"settle"` attempts every value and throws an `AggregateError` afterward.
10
+ */
11
+ errorMode?: ConcurrentErrorMode;
12
+ }
13
+ /**
14
+ * Map values through a bounded worker pool while preserving input order.
15
+ *
16
+ * Active callbacks are always allowed to settle. In fail-fast mode no new
17
+ * callback starts after the first observed rejection. Settle mode attempts
18
+ * every value and reports all failures in input order through `AggregateError`.
19
+ */
20
+ export declare function mapConcurrent<T, R>(values: readonly T[], callback: (value: T, index: number) => R | PromiseLike<R>, options: MapConcurrentOptions): Promise<R[]>;
1
21
  export declare function boundedRetryDelay(attempt: number, delaysMs?: readonly number[]): number;
2
22
  /**
3
23
  * Per-iteration context handed to {@link PollProducer} and the
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Cancellation-aware async primitives: an abortable {@link sleep}, an
3
+ * {@link AbortController} linker ({@link tieAbortSignal}), and a periodic
4
+ * {@link poll} generator. Dependency-free; `poll`'s `"distinct"` filter
5
+ * uses the local {@link deepEqual}.
6
+ *
7
+ * @module
8
+ */
9
+ import { deepEqual } from "./object.js";
10
+ const DEFAULT_RETRY_DELAYS_MS = [1_000, 2_000, 5_000, 10_000, 30_000];
11
+ /**
12
+ * Map values through a bounded worker pool while preserving input order.
13
+ *
14
+ * Active callbacks are always allowed to settle. In fail-fast mode no new
15
+ * callback starts after the first observed rejection. Settle mode attempts
16
+ * every value and reports all failures in input order through `AggregateError`.
17
+ */
18
+ export async function mapConcurrent(values, callback, options) {
19
+ const { concurrency, errorMode = "fail-fast" } = options;
20
+ if (!Number.isSafeInteger(concurrency) || concurrency < 1) {
21
+ throw new RangeError(`concurrency must be a positive integer, got ${String(concurrency)}`);
22
+ }
23
+ if (values.length === 0)
24
+ return [];
25
+ const results = new Array(values.length);
26
+ const failures = [];
27
+ let next = 0;
28
+ let failed = false;
29
+ const worker = async () => {
30
+ while (next < values.length && !(failed && errorMode === "fail-fast")) {
31
+ const index = next++;
32
+ try {
33
+ results[index] = await callback(values[index], index);
34
+ }
35
+ catch (reason) {
36
+ failures.push({ index, reason });
37
+ failed = true;
38
+ }
39
+ }
40
+ };
41
+ await Promise.all(Array.from({ length: Math.min(concurrency, values.length) }, () => worker()));
42
+ if (failures.length === 0)
43
+ return results;
44
+ failures.sort((left, right) => left.index - right.index);
45
+ if (errorMode === "settle") {
46
+ throw new AggregateError(failures.map(({ reason }) => reason), `${failures.length} concurrent operation${failures.length === 1 ? "" : "s"} failed`);
47
+ }
48
+ throw failures[0].reason;
49
+ }
50
+ export function boundedRetryDelay(attempt, delaysMs = DEFAULT_RETRY_DELAYS_MS) {
51
+ if (!delaysMs.length)
52
+ return 0;
53
+ return delaysMs[Math.min(Math.max(0, attempt), delaysMs.length - 1)];
54
+ }
55
+ /**
56
+ * Async iterable that drives a periodic poll. Each iteration:
57
+ *
58
+ * 1. Builds a {@link PollContext} (`attempt`, `previous`, `signal`,
59
+ * shared `attributes`) and calls `producer(ctx)`; yields the
60
+ * resolved value (subject to `filter`).
61
+ * 2. Evaluates `options.predicate(value, ctx)`; stops when it
62
+ * returns (or resolves to) `false`.
63
+ * 3. Sleeps `options.intervalMs` before the next attempt.
64
+ *
65
+ * The first call runs immediately (no leading sleep) so the consumer
66
+ * sees a value without waiting an interval. Errors thrown by
67
+ * `producer` propagate through the generator.
68
+ *
69
+ * `poll` always creates an internal `AbortController` and exposes
70
+ * `internal.signal` as `ctx.signal`, so producers can rely on a
71
+ * defined signal without a nullish check. The external
72
+ * `options.signal` is tied in, and a `try/finally` aborts the
73
+ * internal signal when the consumer breaks out of the `for await`
74
+ * (or the loop throws), so any producer work still holding the
75
+ * signal sees the cancellation too.
76
+ *
77
+ * @example
78
+ * for await (const msg of poll(
79
+ * async ({ signal }) =>
80
+ * client.genie.getMessage({ ... }, { abortSignal: signal }),
81
+ * {
82
+ * intervalMs: 250,
83
+ * predicate: (m) => !TERMINAL_STATUSES.has(m.status),
84
+ * signal: controller.signal,
85
+ * },
86
+ * )) {
87
+ * render(msg);
88
+ * }
89
+ */
90
+ export async function* poll(producer, options) {
91
+ const { intervalMs, predicate, signal, attributes, timeoutMs } = options;
92
+ const controller = new AbortController();
93
+ if (signal)
94
+ tieAbortSignal(controller, signal);
95
+ if (timeoutMs !== undefined) {
96
+ tieAbortSignal(controller, AbortSignal.timeout(timeoutMs));
97
+ }
98
+ // Single shared attributes object so writes from one iteration are
99
+ // visible on the next. `{} as A` is safe because either the caller
100
+ // supplied `attributes` (typed) or `A` defaulted to the unknown
101
+ // record shape (in which case `{}` satisfies it).
102
+ const sharedAttributes = attributes ?? {};
103
+ try {
104
+ let previous;
105
+ for (let attempt = 0;; attempt++) {
106
+ controller.signal.throwIfAborted();
107
+ const ctx = {
108
+ attempt,
109
+ previous,
110
+ signal: controller.signal,
111
+ attributes: sharedAttributes,
112
+ };
113
+ const value = await producer(ctx);
114
+ if (options.filter) {
115
+ if (options.filter === "distinct") {
116
+ if (deepEqual(previous, value)) {
117
+ await sleep(intervalMs, controller.signal);
118
+ continue;
119
+ }
120
+ }
121
+ else if (!(await options.filter(value, ctx))) {
122
+ await sleep(intervalMs, controller.signal);
123
+ continue;
124
+ }
125
+ }
126
+ yield value;
127
+ if (predicate && !(await predicate(value, ctx)))
128
+ return;
129
+ await sleep(intervalMs, controller.signal);
130
+ previous = value;
131
+ }
132
+ }
133
+ finally {
134
+ controller.abort();
135
+ }
136
+ }
137
+ /**
138
+ * Tie a child `AbortController` to a parent signal. The child aborts
139
+ * whenever the parent aborts; aborting the child does not affect the
140
+ * parent (so a fetch-level cancel doesn't tear down the main poll loop).
141
+ */
142
+ export function tieAbortSignal(child, parent) {
143
+ if (!parent) {
144
+ return;
145
+ }
146
+ else if (parent.aborted) {
147
+ child.abort(parent.reason);
148
+ return;
149
+ }
150
+ parent.addEventListener("abort", () => child.abort(parent.reason), {
151
+ once: true,
152
+ });
153
+ }
154
+ /**
155
+ * Combine several optional cancellation sources into one signal that aborts
156
+ * as soon as any of them does.
157
+ *
158
+ * The usual caller is an operation that has to honor more than one source at
159
+ * once - a caller's own signal (a closed connection, an agent run being
160
+ * cancelled) plus one derived from a timeout - where the awaited I/O accepts
161
+ * only a single signal. Absent sources are ignored, and a lone signal is
162
+ * returned as-is so the common path allocates nothing. Returns `undefined`
163
+ * only when every input is absent, which callers can pass straight through
164
+ * to an optional `signal` parameter.
165
+ *
166
+ * Aborting an input aborts the result (carrying that input's `reason`);
167
+ * nothing propagates back the other way.
168
+ *
169
+ * @example
170
+ * await fetch(url, { signal: combineAbortSignals(req.signal, timeout.signal) });
171
+ */
172
+ export function combineAbortSignals(...signals) {
173
+ const present = signals.filter((signal) => signal !== undefined);
174
+ if (present.length <= 1)
175
+ return present[0];
176
+ return AbortSignal.any(present);
177
+ }
178
+ /**
179
+ * Promisified `setTimeout` that wakes up early (and rejects with
180
+ * `signal.reason`) when `signal` aborts mid-wait. Short-circuits to a
181
+ * rejected promise when the signal is already aborted on entry, so the
182
+ * abort path is consistent regardless of whether the wait actually
183
+ * started.
184
+ *
185
+ * Use as the building block for any "wait, but cancel cleanly" pattern -
186
+ * inter-poll backoff, pacing loops, retry timers, long-poll budgets - so
187
+ * cancellation always rejects with the caller's `signal.reason` rather
188
+ * than silently resolving after the timer expires.
189
+ *
190
+ * @example
191
+ * await sleep(250, req.signal);
192
+ */
193
+ export function sleep(ms, signal) {
194
+ if (signal?.aborted)
195
+ return Promise.reject(signal.reason);
196
+ return new Promise((resolve, reject) => {
197
+ const onAbort = () => {
198
+ clearTimeout(timer);
199
+ reject(signal.reason);
200
+ };
201
+ const timer = setTimeout(() => {
202
+ signal?.removeEventListener("abort", onAbort);
203
+ resolve();
204
+ }, ms);
205
+ signal?.addEventListener("abort", onAbort, { once: true });
206
+ });
207
+ }
208
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMtdXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXN5bmMtdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7R0FPRztBQUNILE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFeEMsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQVUsQ0FBQztBQWdCL0U7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxhQUFhLENBQ2pDLE1BQW9CLEVBQ3BCLFFBQXlELEVBQ3pELE9BQTZCO0lBRTdCLE1BQU0sRUFBRSxXQUFXLEVBQUUsU0FBUyxHQUFHLFdBQVcsRUFBRSxHQUFHLE9BQU8sQ0FBQztJQUN6RCxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsSUFBSSxXQUFXLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDMUQsTUFBTSxJQUFJLFVBQVUsQ0FBQywrQ0FBK0MsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM3RixDQUFDO0lBQ0QsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUVuQyxNQUFNLE9BQU8sR0FBRyxJQUFJLEtBQUssQ0FBSSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDNUMsTUFBTSxRQUFRLEdBQThDLEVBQUUsQ0FBQztJQUMvRCxJQUFJLElBQUksR0FBRyxDQUFDLENBQUM7SUFDYixJQUFJLE1BQU0sR0FBRyxLQUFLLENBQUM7SUFFbkIsTUFBTSxNQUFNLEdBQUcsS0FBSyxJQUFtQixFQUFFO1FBQ3ZDLE9BQU8sSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLE1BQU0sSUFBSSxTQUFTLEtBQUssV0FBVyxDQUFDLEVBQUUsQ0FBQztZQUN0RSxNQUFN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LENBQUMsR0FBRyxFQUFFO1lBQzVCLE1BQU0sRUFBRSxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDOUMsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDUCxNQUFNLEVBQUUsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzdELENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ2FuY2VsbGF0aW9uLWF3YXJlIGFzeW5jIHByaW1pdGl2ZXM6IGFuIGFib3J0YWJsZSB7QGxpbmsgc2xlZXB9LCBhblxuICoge0BsaW5rIEFib3J0Q29udHJvbGxlcn0gbGlua2VyICh7QGxpbmsgdGllQWJvcnRTaWduYWx9KSwgYW5kIGEgcGVyaW9kaWNcbiAqIHtAbGluayBwb2xsfSBnZW5lcmF0b3IuIERlcGVuZGVuY3ktZnJlZTsgYHBvbGxgJ3MgYFwiZGlzdGluY3RcImAgZmlsdGVyXG4gKiB1c2VzIHRoZSBsb2NhbCB7QGxpbmsgZGVlcEVxdWFsfS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cbmltcG9ydCB7IGRlZXBFcXVhbCB9IGZyb20gXCIuL29iamVjdC50c1wiO1xuXG5jb25zdCBERUZBVUxUX1JFVFJZX0RFTEFZU19NUyA9IFsxXzAwMCwgMl8wMDAsIDVfMDAwLCAxMF8wMDAsIDMwXzAwMF0gYXMgY29uc3Q7XG5cbi8qKiBDb250cm9scyBob3cge0BsaW5rIG1hcENvbmN1cnJlbnR9IHJlYWN0cyB3aGVuIGEgd29ya2VyIHJlamVjdHMuICovXG5leHBvcnQgdHlwZSBDb25jdXJyZW50RXJyb3JNb2RlID0gXCJmYWlsLWZhc3RcIiB8IFwic2V0dGxlXCI7XG5cbi8qKiBCb3VuZGVkLXdvcmtlciBzZXR0aW5ncyBmb3Ige0BsaW5rIG1hcENvbmN1cnJlbnR9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBNYXBDb25jdXJyZW50T3B0aW9ucyB7XG4gIC8qKiBNYXhpbXVtIG51bWJlciBvZiBjYWxsYmFja3MgcnVubmluZyBhdCBvbmNlLiAqL1xuICBjb25jdXJyZW5jeTogbnVtYmVyO1xuICAvKipcbiAgICogYFwiZmFpbC1mYXN0XCJgIHN0b3BzIGNsYWltaW5nIG5ldyB3b3JrIGFmdGVyIHRoZSBmaXJzdCByZWplY3Rpb24uXG4gICAqIGBcInNldHRsZVwiYCBhdHRlbXB0cyBldmVyeSB2YWx1ZSBhbmQgdGhyb3dzIGFuIGBBZ2dyZWdhdGVFcnJvcmAgYWZ0ZXJ3YXJkLlxuICAgKi9cbiAgZXJyb3JNb2RlPzogQ29uY3VycmVudEVycm9yTW9kZTtcbn1cblxuLyoqXG4gKiBNYXAgdmFsdWVzIHRocm91Z2ggYSBib3VuZGVkIHdvcmtlciBwb29sIHdoaWxlIHByZXNlcnZpbmcgaW5wdXQgb3JkZXIuXG4gKlxuICogQWN0aXZlIGNhbGxiYWNrcyBhcmUgYWx3YXlzIGFsbG93ZWQgdG8gc2V0dGxlLiBJbiBmYWlsLWZhc3QgbW9kZSBubyBuZXdcbiAqIGNhbGxiYWNrIHN0YXJ0cyBhZnRlciB0aGUgZmlyc3Qgb2JzZXJ2ZWQgcmVqZWN0aW9uLiBTZXR0bGUgbW9kZSBhdHRlbXB0c1xuICogZXZlcnkgdmFsdWUgYW5kIHJlcG9ydHMgYWxsIGZhaWx1cmVzIGluIGlucHV0IG9yZGVyIHRocm91Z2ggYEFnZ3JlZ2F0ZUVycm9yYC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1hcENvbmN1cnJlbnQ8VCwgUj4oXG4gIHZhbHVlczogcmVhZG9ubHkgVFtdLFxuICBjYWxsYmFjazogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiBSIHwgUHJvbWlzZUxpa2U8Uj4sXG4gIG9wdGlvbnM6IE1hcENvbmN1cnJlbnRPcHRpb25zLFxuKTogUHJvbWlzZTxSW10+IHtcbiAgY29uc3QgeyBjb25jdXJyZW5jeSwgZXJyb3JNb2RlID0gXCJmYWlsLWZhc3RcIiB9ID0gb3B0aW9ucztcbiAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihjb25jdXJyZW5jeSkgfHwgY29uY3VycmVuY3kgPCAxKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYGNvbmN1cnJlbmN5IG11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyLCBnb3QgJHtTdHJpbmcoY29uY3VycmVuY3kpfWApO1xuICB9XG4gIGlmICh2YWx1ZXMubGVuZ3RoID09PSAwKSByZXR1cm4gW107XG5cbiAgY29uc3QgcmVzdWx0cyA9IG5ldyBBcnJheTxSPih2YWx1ZXMubGVuZ3RoKTtcbiAgY29uc3QgZmFpbHVyZXM6IEFycmF5PHsgaW5kZXg6IG51bWJlcjsgcmVhc29uOiB1bmtub3duIH0+ID0gW107XG4gIGxldCBuZXh0ID0gMDtcbiAgbGV0IGZhaWxlZCA9IGZhbHNlO1xuXG4gIGNvbnN0IHdvcmtlciA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICB3aGlsZSAobmV4dCA8IHZhbHVlcy5sZW5ndGggJiYgIShmYWlsZWQgJiYgZXJyb3JNb2RlID09PSBcImZhaWwtZmFzdFwiKSkge1xuICAgICAgY29uc3QgaW5kZXggPSBuZXh0Kys7XG4gICAgICB0cnkge1xuICAgICAgICByZXN1bHRzW2luZGV4XSA9IGF3YWl0IGNhbGxiYWNrKHZhbHVlc1tpbmRleF0hLCBpbmRleCk7XG4gICAgICB9IGNhdGNoIChyZWFzb24pIHtcbiAgICAgICAgZmFpbHVyZXMucHVzaCh7IGluZGV4LCByZWFzb24gfSk7XG4gICAgICAgIGZhaWxlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGF3YWl0IFByb21pc2UuYWxsKEFycmF5LmZyb20oeyBsZW5ndGg6IE1hdGgubWluKGNvbmN1cnJlbmN5LCB2YWx1ZXMubGVuZ3RoKSB9LCAoKSA9PiB3b3JrZXIoKSkpO1xuICBpZiAoZmFpbHVyZXMubGVuZ3RoID09PSAwKSByZXR1cm4gcmVzdWx0cztcblxuICBmYWlsdXJlcy5zb3J0KChsZWZ0LCByaWdodCkgPT4gbGVmdC5pbmRleCAtIHJpZ2h0LmluZGV4KTtcbiAgaWYgKGVycm9yTW9kZSA9PT0gXCJzZXR0bGVcIikge1xuICAgIHRocm93IG5ldyBBZ2dyZWdhdGVFcnJvcihcbiAgICAgIGZhaWx1cmVzLm1hcCgoeyByZWFzb24gfSkgPT4gcmVhc29uKSxcbiAgICAgIGAke2ZhaWx1cmVzLmxlbmd0aH0gY29uY3VycmVudCBvcGVyYXRpb24ke2ZhaWx1cmVzLmxlbmd0aCA9PT0gMSA/IFwiXCIgOiBcInNcIn0gZmFpbGVkYCxcbiAgICApO1xuICB9XG4gIHRocm93IGZhaWx1cmVzWzBdIS5yZWFzb247XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBib3VuZGVkUmV0cnlEZWxheShcbiAgYXR0ZW1wdDogbnVtYmVyLFxuICBkZWxheXNNczogcmVhZG9ubHkgbnVtYmVyW10gPSBERUZBVUxUX1JFVFJZX0RFTEFZU19NUyxcbik6IG51bWJlciB7XG4gIGlmICghZGVsYXlzTXMubGVuZ3RoKSByZXR1cm4gMDtcbiAgcmV0dXJuIGRlbGF5c01zW01hdGgubWluKE1hdGgubWF4KDAsIGF0dGVtcHQpLCBkZWxheXNNcy5sZW5ndGggLSAxKV0hO1xufVxuXG4vKipcbiAqIFBlci1pdGVyYXRpb24gY29udGV4dCBoYW5kZWQgdG8ge0BsaW5rIFBvbGxQcm9kdWNlcn0gYW5kIHRoZVxuICogcHJlZGljYXRlIG9uIGVhY2ggc3RlcCBvZiBhIHtAbGluayBwb2xsfSBsb29wLiBCdW5kbGVzIHRoZVxuICogaXRlcmF0aW9uIG1ldGFkYXRhIHNvIHRoZSBjYWxsIHNpZ25hdHVyZXMgc3RheSBzdGFibGUgYXMgYHBvbGxgXG4gKiBncm93cyBhZGRpdGlvbmFsIGZpZWxkcy5cbiAqXG4gKiBgc2lnbmFsYCBpcyBvd25lZCBieSBgcG9sbGA6IGl0IHRyYWNrcyB0aGUgZXh0ZXJuYWxcbiAqIGBQb2xsT3B0aW9ucy5zaWduYWxgICh3aGVuIHN1cHBsaWVkKSBhbmQgYWxzbyBmaXJlcyB3aGVuIHRoZVxuICogY29uc3VtZXIgYnJlYWtzIG91dCBvZiB0aGUgbG9vcCwgc28gcHJvZHVjZXJzIGNhbiBmb3J3YXJkIGl0IHRvXG4gKiBhbnkgaW4tZmxpZ2h0IHdvcmsgKGBmZXRjaGAsIFNESyBjYWxscywgZXRjLikgYW5kIGhhdmUgYSBzaW5nbGVcbiAqIGNhbmNlbGxhdGlvbiBzb3VyY2UgdGVhciBkb3duIGJvdGggdGhlIHJlcXVlc3QgYW5kIHRoZSBsb29wLlxuICpcbiAqIGBhdHRyaWJ1dGVzYCBpcyBhIG11dGFibGUgc2NyYXRjaHBhZCBzaGFyZWQgYWNyb3NzIGV2ZXJ5XG4gKiBpdGVyYXRpb24gb2YgYSBzaW5nbGUgYHBvbGxgIHJ1bi4gVGhlIHNhbWUgb2JqZWN0IHJlZmVyZW5jZSBpc1xuICogcGFzc2VkIGVhY2ggY2FsbCBzbyB3cml0ZXMgZnJvbSBvbmUgaXRlcmF0aW9uIGFyZSB2aXNpYmxlIHRvIHRoZVxuICogbmV4dCAtIHVzZWZ1bCBmb3Igc3Rhc2hpbmcgcGVyLWxvb3Agc3RhdGUgKHJldHJ5IGNvdW50ZXJzLCBzdGFydFxuICogdGltZXN0YW1wcywgYW55dGhpbmcgeW91J2Qgb3RoZXJ3aXNlIGNsb3NlIG92ZXIgdmlhIGEgbGV0KS5cbiAqIEdlbmVyaWMgYEFgIGxldHMgY2FsbGVycyB0eXBlIHRoZSBiYWc7IGRlZmF1bHRzIHRvXG4gKiBgUmVjb3JkPHN0cmluZywgdW5rbm93bj5gLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvbGxDb250ZXh0PFQsIEEgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4ge1xuICAvKiogWmVyby1iYXNlZCBpdGVyYXRpb24gaW5kZXggKGAwYCBvbiB0aGUgZmlyc3QgY2FsbCkuICovXG4gIGF0dGVtcHQ6IG51bWJlcjtcbiAgLyoqIFZhbHVlIHlpZWxkZWQgb24gdGhlIHByaW9yIGl0ZXJhdGlvbjsgYHVuZGVmaW5lZGAgb24gdGhlIGZpcnN0LiAqL1xuICBwcmV2aW91czogVCB8IHVuZGVmaW5lZDtcbiAgLyoqIENhbmNlbGxhdGlvbiBoYW5kbGUuIEFsd2F5cyBkZWZpbmVkOyBmb3J3YXJkIHRvIGluLWZsaWdodCB3b3JrLiAqL1xuICBzaWduYWw6IEFib3J0U2lnbmFsO1xuICAvKiogUGVyLXJ1biBtdXRhYmxlIHNjcmF0Y2hwYWQgc2hhcmVkIGFjcm9zcyBpdGVyYXRpb25zLiAqL1xuICBhdHRyaWJ1dGVzOiBBO1xufVxuXG4vKiogT25lIHN0ZXAgb2YgYSB7QGxpbmsgcG9sbH0gbG9vcC4gU2VlIHtAbGluayBQb2xsQ29udGV4dH0uICovXG5leHBvcnQgdHlwZSBQb2xsUHJvZHVjZXI8VCwgQSA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+PiA9IChcbiAgY3R4OiBQb2xsQ29udGV4dDxULCBBPixcbikgPT4gVCB8IFByb21pc2VMaWtlPFQ+O1xuXG4vKipcbiAqIENvbnRyb2xzIHBvbGwgY2FkZW5jZSwgZmlsdGVyaW5nLCB0ZXJtaW5hdGlvbiwgY2FuY2VsbGF0aW9uLCB0aW1lb3V0LCBhbmRcbiAqIHRoZSBtdXRhYmxlIHBlci1ydW4gYXR0cmlidXRlcyBleHBvc2VkIHRocm91Z2gge0BsaW5rIFBvbGxDb250ZXh0fS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQb2xsT3B0aW9uczxULCBBID0gUmVjb3JkPHN0cmluZywgdW5rbm93bj4+IHtcbiAgLyoqIE1pbGxpc2Vjb25kcyB0byB3YWl0IGJldHdlZW4gcG9sbHMuICovXG4gIGludGVydmFsTXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIFByZWRpY2F0ZSBldmFsdWF0ZWQgYWdhaW5zdCBlYWNoIHlpZWxkZWQgdmFsdWU6IHJldHVybiBgdHJ1ZWAgdG9cbiAgICoga2VlcCBpdCwgYGZhbHNlYCB0byBza2lwIGl0ICh3aXRob3V0IHN0b3BwaW5nIHRoZSBsb29wKS4gTWF5IGJlXG4gICAqIHN5bmMgb3IgYXN5bmMgLSBhIGBQcm9taXNlTGlrZTxib29sZWFuPmAgaXMgYXdhaXRlZCBiZWZvcmUgdGhlXG4gICAqIGRlY2lzaW9uIGlzIG1hZGUuIFJlY2VpdmVzIHRoZSBzYW1lIHtAbGluayBQb2xsQ29udGV4dH0gYXMgdGhlXG4gICAqIHByb2R1Y2VyIChzYW1lIGBzaWduYWxgLCBzYW1lIGBhdHRyaWJ1dGVzYCBiYWcpLiBUaGUgc3BlY2lhbFxuICAgKiB2YWx1ZSBgXCJkaXN0aW5jdFwiYCBza2lwcyBhIHZhbHVlIHRoYXQgZGVlcC1lcXVhbHMgdGhlIHByZXZpb3VzXG4gICAqIG9uZS5cbiAgICovXG4gIGZpbHRlcj86ICgodmFsdWU6IFQsIGN0eDogUG9sbENvbnRleHQ8VCwgQT4pID0+IGJvb2xlYW4gfCBQcm9taXNlTGlrZTxib29sZWFuPikgfCBcImRpc3RpbmN0XCI7XG4gIC8qKlxuICAgKiBQcmVkaWNhdGUgZXZhbHVhdGVkIGFnYWluc3QgZWFjaCB5aWVsZGVkIHZhbHVlOiByZXR1cm4gYHRydWVgIHRvXG4gICAqIGtlZXAgcG9sbGluZywgYGZhbHNlYCB0byBzdG9wLiBNYXkgYmUgc3luYyBvciBhc3luYy4gT21pdCB0byBwb2xsXG4gICAqIGZvcmV2ZXIgKHRoZSBjb25zdW1lciBzdG9wcyBieSBicmVha2luZyBvdXQgb2YgdGhlIGxvb3Agb3IgYnlcbiAgICogYWJvcnRpbmcgYHNpZ25hbGApLlxuICAgKi9cbiAgcHJlZGljYXRlPzogKHZhbHVlOiBULCBjdHg6IFBvbGxDb250ZXh0PFQsIEE+KSA9PiBib29sZWFuIHwgUHJvbWlzZUxpa2U8Ym9vbGVhbj47XG4gIC8qKlxuICAgKiBFeHRlcm5hbCBjYW5jZWxsYXRpb24gaGFuZGxlLiBUaWVkIGludG8gdGhlIGludGVybmFsIHNpZ25hbCB0aGF0XG4gICAqIGBwb2xsYCBoYW5kcyB0byBgcHJvZHVjZXJgLCBzbyBhYm9ydGluZyBpdCB0ZWFycyBkb3duIGJvdGggdGhlXG4gICAqIGluLWZsaWdodCByZXF1ZXN0IGFuZCB0aGUgaW50ZXItcG9sbCBzbGVlcC5cbiAgICovXG4gIHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICAvKipcbiAgICogSGFyZCB1cHBlciBib3VuZCBvbiB0aGUgdG90YWwgbGlmZXRpbWUgb2YgdGhlIHBvbGwgbG9vcCwgaW5cbiAgICogbWlsbGlzZWNvbmRzLiBXaGVuIHRoZSBidWRnZXQgZWxhcHNlcywgYHBvbGxgIGFib3J0cyBpdHMgaW50ZXJuYWxcbiAgICogc2lnbmFsIHNvIHRoZSBpbi1mbGlnaHQgcHJvZHVjZXIgYW5kIGludGVyLXBvbGwgc2xlZXAgYm90aCB0ZWFyXG4gICAqIGRvd24gcHJvbXB0bHksIGFuZCB0aGUgbG9vcCB0aHJvd3MgdGhlIGBUaW1lb3V0RXJyb3JgXG4gICAqIGBET01FeGNlcHRpb25gIHByb2R1Y2VkIGJ5IGBBYm9ydFNpZ25hbC50aW1lb3V0KHRpbWVvdXRNcylgLiBUaGVcbiAgICogYnVkZ2V0IHN0YXJ0cyB0aWNraW5nIHRoZSBtb21lbnQgdGhlIGdlbmVyYXRvciBpcyBjcmVhdGVkLlxuICAgKi9cbiAgdGltZW91dE1zPzogbnVtYmVyO1xuICAvKipcbiAgICogSW5pdGlhbCB2YWx1ZSBmb3IgYGN0eC5hdHRyaWJ1dGVzYC4gRGVmYXVsdHMgdG8gYHt9YC4gVGhlIHNhbWVcbiAgICogb2JqZWN0IGlzIHJldXNlZCBhY3Jvc3MgaXRlcmF0aW9ucywgc28gY2FsbGVycyBjYW4gcHJlLXBvcHVsYXRlXG4gICAqIGZpZWxkcyAodGltZXJzLCByZXRyeSBjb3VudGVycywgZXRjLikgYW5kIHRoZSBwcm9kdWNlciAvXG4gICAqIHByZWRpY2F0ZSBjYW4gbXV0YXRlIHRoZW0gaW4gcGxhY2UuXG4gICAqL1xuICBhdHRyaWJ1dGVzPzogQTtcbn1cblxuLyoqXG4gKiBBc3luYyBpdGVyYWJsZSB0aGF0IGRyaXZlcyBhIHBlcmlvZGljIHBvbGwuIEVhY2ggaXRlcmF0aW9uOlxuICpcbiAqICAgMS4gQnVpbGRzIGEge0BsaW5rIFBvbGxDb250ZXh0fSAoYGF0dGVtcHRgLCBgcHJldmlvdXNgLCBgc2lnbmFsYCxcbiAqICAgICAgc2hhcmVkIGBhdHRyaWJ1dGVzYCkgYW5kIGNhbGxzIGBwcm9kdWNlcihjdHgpYDsgeWllbGRzIHRoZVxuICogICAgICByZXNvbHZlZCB2YWx1ZSAoc3ViamVjdCB0byBgZmlsdGVyYCkuXG4gKiAgIDIuIEV2YWx1YXRlcyBgb3B0aW9ucy5wcmVkaWNhdGUodmFsdWUsIGN0eClgOyBzdG9wcyB3aGVuIGl0XG4gKiAgICAgIHJldHVybnMgKG9yIHJlc29sdmVzIHRvKSBgZmFsc2VgLlxuICogICAzLiBTbGVlcHMgYG9wdGlvbnMuaW50ZXJ2YWxNc2AgYmVmb3JlIHRoZSBuZXh0IGF0dGVtcHQuXG4gKlxuICogVGhlIGZpcnN0IGNhbGwgcnVucyBpbW1lZGlhdGVseSAobm8gbGVhZGluZyBzbGVlcCkgc28gdGhlIGNvbnN1bWVyXG4gKiBzZWVzIGEgdmFsdWUgd2l0aG91dCB3YWl0aW5nIGFuIGludGVydmFsLiBFcnJvcnMgdGhyb3duIGJ5XG4gKiBgcHJvZHVjZXJgIHByb3BhZ2F0ZSB0aHJvdWdoIHRoZSBnZW5lcmF0b3IuXG4gKlxuICogYHBvbGxgIGFsd2F5cyBjcmVhdGVzIGFuIGludGVybmFsIGBBYm9ydENvbnRyb2xsZXJgIGFuZCBleHBvc2VzXG4gKiBgaW50ZXJuYWwuc2lnbmFsYCBhcyBgY3R4LnNpZ25hbGAsIHNvIHByb2R1Y2VycyBjYW4gcmVseSBvbiBhXG4gKiBkZWZpbmVkIHNpZ25hbCB3aXRob3V0IGEgbnVsbGlzaCBjaGVjay4gVGhlIGV4dGVybmFsXG4gKiBgb3B0aW9ucy5zaWduYWxgIGlzIHRpZWQgaW4sIGFuZCBhIGB0cnkvZmluYWxseWAgYWJvcnRzIHRoZVxuICogaW50ZXJuYWwgc2lnbmFsIHdoZW4gdGhlIGNvbnN1bWVyIGJyZWFrcyBvdXQgb2YgdGhlIGBmb3IgYXdhaXRgXG4gKiAob3IgdGhlIGxvb3AgdGhyb3dzKSwgc28gYW55IHByb2R1Y2VyIHdvcmsgc3RpbGwgaG9sZGluZyB0aGVcbiAqIHNpZ25hbCBzZWVzIHRoZSBjYW5jZWxsYXRpb24gdG9vLlxuICpcbiAqIEBleGFtcGxlXG4gKiBmb3IgYXdhaXQgKGNvbnN0IG1zZyBvZiBwb2xsKFxuICogICBhc3luYyAoeyBzaWduYWwgfSkgPT5cbiAqICAgICBjbGllbnQuZ2VuaWUuZ2V0TWVzc2FnZSh7IC4uLiB9LCB7IGFib3J0U2lnbmFsOiBzaWduYWwgfSksXG4gKiAgIHtcbiAqICAgICBpbnRlcnZhbE1zOiAyNTAsXG4gKiAgICAgcHJlZGljYXRlOiAobSkgPT4gIVRFUk1JTkFMX1NUQVRVU0VTLmhhcyhtLnN0YXR1cyksXG4gKiAgICAgc2lnbmFsOiBjb250cm9sbGVyLnNpZ25hbCxcbiAqICAgfSxcbiAqICkpIHtcbiAqICAgcmVuZGVyKG1zZyk7XG4gKiB9XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiogcG9sbDxULCBBID0gUmVjb3JkPHN0cmluZywgdW5rbm93bj4+KFxuICBwcm9kdWNlcjogUG9sbFByb2R1Y2VyPFQsIEE+LFxuICBvcHRpb25zOiBQb2xsT3B0aW9uczxULCBBPixcbik6IEFzeW5jR2VuZXJhdG9yPFQsIHZvaWQsIHZvaWQ+IHtcbiAgY29uc3QgeyBpbnRlcnZhbE1zLCBwcmVkaWNhdGUsIHNpZ25hbCwgYXR0cmlidXRlcywgdGltZW91dE1zIH0gPSBvcHRpb25zO1xuICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICBpZiAoc2lnbmFsKSB0aWVBYm9ydFNpZ25hbChjb250cm9sbGVyLCBzaWduYWwpO1xuICBpZiAodGltZW91dE1zICE9PSB1bmRlZmluZWQpIHtcbiAgICB0aWVBYm9ydFNpZ25hbChjb250cm9sbGVyLCBBYm9ydFNpZ25hbC50aW1lb3V0KHRpbWVvdXRNcykpO1xuICB9XG4gIC8vIFNpbmdsZSBzaGFyZWQgYXR0cmlidXRlcyBvYmplY3Qgc28gd3JpdGVzIGZyb20gb25lIGl0ZXJhdGlvbiBhcmVcbiAgLy8gdmlzaWJsZSBvbiB0aGUgbmV4dC4gYHt9IGFzIEFgIGlzIHNhZmUgYmVjYXVzZSBlaXRoZXIgdGhlIGNhbGxlclxuICAvLyBzdXBwbGllZCBgYXR0cmlidXRlc2AgKHR5cGVkKSBvciBgQWAgZGVmYXVsdGVkIHRvIHRoZSB1bmtub3duXG4gIC8vIHJlY29yZCBzaGFwZSAoaW4gd2hpY2ggY2FzZSBge31gIHNhdGlzZmllcyBpdCkuXG4gIGNvbnN0IHNoYXJlZEF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzID8/ICh7fSBhcyBBKTtcbiAgdHJ5IHtcbiAgICBsZXQgcHJldmlvdXM6IFQgfCB1bmRlZmluZWQ7XG4gICAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IDsgYXR0ZW1wdCsrKSB7XG4gICAgICBjb250cm9sbGVyLnNpZ25hbC50aHJvd0lmQWJvcnRlZCgpO1xuICAgICAgY29uc3QgY3R4OiBQb2xsQ29udGV4dDxULCBBPiA9IHtcbiAgICAgICAgYXR0ZW1wdCxcbiAgICAgICAgcHJldmlvdXMsXG4gICAgICAgIHNpZ25hbDogY29udHJvbGxlci5zaWduYWwsXG4gICAgICAgIGF0dHJpYnV0ZXM6IHNoYXJlZEF0dHJpYnV0ZXMsXG4gICAgICB9O1xuICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCBwcm9kdWNlcihjdHgpO1xuICAgICAgaWYgKG9wdGlvbnMuZmlsdGVyKSB7XG4gICAgICAgIGlmIChvcHRpb25zLmZpbHRlciA9PT0gXCJkaXN0aW5jdFwiKSB7XG4gICAgICAgICAgaWYgKGRlZXBFcXVhbChwcmV2aW91cywgdmFsdWUpKSB7XG4gICAgICAgICAgICBhd2FpdCBzbGVlcChpbnRlcnZhbE1zLCBjb250cm9sbGVyLnNpZ25hbCk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoIShhd2FpdCBvcHRpb25zLmZpbHRlcih2YWx1ZSwgY3R4KSkpIHtcbiAgICAgICAgICBhd2FpdCBzbGVlcChpbnRlcnZhbE1zLCBjb250cm9sbGVyLnNpZ25hbCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHlpZWxkIHZhbHVlO1xuICAgICAgaWYgKHByZWRpY2F0ZSAmJiAhKGF3YWl0IHByZWRpY2F0ZSh2YWx1ZSwgY3R4KSkpIHJldHVybjtcbiAgICAgIGF3YWl0IHNsZWVwKGludGVydmFsTXMsIGNvbnRyb2xsZXIuc2lnbmFsKTtcbiAgICAgIHByZXZpb3VzID0gdmFsdWU7XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIGNvbnRyb2xsZXIuYWJvcnQoKTtcbiAgfVxufVxuXG4vKipcbiAqIFRpZSBhIGNoaWxkIGBBYm9ydENvbnRyb2xsZXJgIHRvIGEgcGFyZW50IHNpZ25hbC4gVGhlIGNoaWxkIGFib3J0c1xuICogd2hlbmV2ZXIgdGhlIHBhcmVudCBhYm9ydHM7IGFib3J0aW5nIHRoZSBjaGlsZCBkb2VzIG5vdCBhZmZlY3QgdGhlXG4gKiBwYXJlbnQgKHNvIGEgZmV0Y2gtbGV2ZWwgY2FuY2VsIGRvZXNuJ3QgdGVhciBkb3duIHRoZSBtYWluIHBvbGwgbG9vcCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0aWVBYm9ydFNpZ25hbChjaGlsZDogQWJvcnRDb250cm9sbGVyLCBwYXJlbnQ/OiBBYm9ydFNpZ25hbCk6IHZvaWQge1xuICBpZiAoIXBhcmVudCkge1xuICAgIHJldHVybjtcbiAgfSBlbHNlIGlmIChwYXJlbnQuYWJvcnRlZCkge1xuICAgIGNoaWxkLmFib3J0KHBhcmVudC5yZWFzb24pO1xuICAgIHJldHVybjtcbiAgfVxuICBwYXJlbnQuYWRkRXZlbnRMaXN0ZW5lcihcImFib3J0XCIsICgpID0+IGNoaWxkLmFib3J0KHBhcmVudC5yZWFzb24pLCB7XG4gICAgb25jZTogdHJ1ZSxcbiAgfSk7XG59XG5cbi8qKlxuICogQ29tYmluZSBzZXZlcmFsIG9wdGlvbmFsIGNhbmNlbGxhdGlvbiBzb3VyY2VzIGludG8gb25lIHNpZ25hbCB0aGF0IGFib3J0c1xuICogYXMgc29vbiBhcyBhbnkgb2YgdGhlbSBkb2VzLlxuICpcbiAqIFRoZSB1c3VhbCBjYWxsZXIgaXMgYW4gb3BlcmF0aW9uIHRoYXQgaGFzIHRvIGhvbm9yIG1vcmUgdGhhbiBvbmUgc291cmNlIGF0XG4gKiBvbmNlIC0gYSBjYWxsZXIncyBvd24gc2lnbmFsIChhIGNsb3NlZCBjb25uZWN0aW9uLCBhbiBhZ2VudCBydW4gYmVpbmdcbiAqIGNhbmNlbGxlZCkgcGx1cyBvbmUgZGVyaXZlZCBmcm9tIGEgdGltZW91dCAtIHdoZXJlIHRoZSBhd2FpdGVkIEkvTyBhY2NlcHRzXG4gKiBvbmx5IGEgc2luZ2xlIHNpZ25hbC4gQWJzZW50IHNvdXJjZXMgYXJlIGlnbm9yZWQsIGFuZCBhIGxvbmUgc2lnbmFsIGlzXG4gKiByZXR1cm5lZCBhcy1pcyBzbyB0aGUgY29tbW9uIHBhdGggYWxsb2NhdGVzIG5vdGhpbmcuIFJldHVybnMgYHVuZGVmaW5lZGBcbiAqIG9ubHkgd2hlbiBldmVyeSBpbnB1dCBpcyBhYnNlbnQsIHdoaWNoIGNhbGxlcnMgY2FuIHBhc3Mgc3RyYWlnaHQgdGhyb3VnaFxuICogdG8gYW4gb3B0aW9uYWwgYHNpZ25hbGAgcGFyYW1ldGVyLlxuICpcbiAqIEFib3J0aW5nIGFuIGlucHV0IGFib3J0cyB0aGUgcmVzdWx0IChjYXJyeWluZyB0aGF0IGlucHV0J3MgYHJlYXNvbmApO1xuICogbm90aGluZyBwcm9wYWdhdGVzIGJhY2sgdGhlIG90aGVyIHdheS5cbiAqXG4gKiBAZXhhbXBsZVxuICogYXdhaXQgZmV0Y2godXJsLCB7IHNpZ25hbDogY29tYmluZUFib3J0U2lnbmFscyhyZXEuc2lnbmFsLCB0aW1lb3V0LnNpZ25hbCkgfSk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21iaW5lQWJvcnRTaWduYWxzKFxuICAuLi5zaWduYWxzOiAoQWJvcnRTaWduYWwgfCB1bmRlZmluZWQpW11cbik6IEFib3J0U2lnbmFsIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcHJlc2VudCA9IHNpZ25hbHMuZmlsdGVyKChzaWduYWwpOiBzaWduYWwgaXMgQWJvcnRTaWduYWwgPT4gc2lnbmFsICE9PSB1bmRlZmluZWQpO1xuICBpZiAocHJlc2VudC5sZW5ndGggPD0gMSkgcmV0dXJuIHByZXNlbnRbMF07XG4gIHJldHVybiBBYm9ydFNpZ25hbC5hbnkocHJlc2VudCk7XG59XG5cbi8qKlxuICogUHJvbWlzaWZpZWQgYHNldFRpbWVvdXRgIHRoYXQgd2FrZXMgdXAgZWFybHkgKGFuZCByZWplY3RzIHdpdGhcbiAqIGBzaWduYWwucmVhc29uYCkgd2hlbiBgc2lnbmFsYCBhYm9ydHMgbWlkLXdhaXQuIFNob3J0LWNpcmN1aXRzIHRvIGFcbiAqIHJlamVjdGVkIHByb21pc2Ugd2hlbiB0aGUgc2lnbmFsIGlzIGFscmVhZHkgYWJvcnRlZCBvbiBlbnRyeSwgc28gdGhlXG4gKiBhYm9ydCBwYXRoIGlzIGNvbnNpc3RlbnQgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZSB3YWl0IGFjdHVhbGx5XG4gKiBzdGFydGVkLlxuICpcbiAqIFVzZSBhcyB0aGUgYnVpbGRpbmcgYmxvY2sgZm9yIGFueSBcIndhaXQsIGJ1dCBjYW5jZWwgY2xlYW5seVwiIHBhdHRlcm4gLVxuICogaW50ZXItcG9sbCBiYWNrb2ZmLCBwYWNpbmcgbG9vcHMsIHJldHJ5IHRpbWVycywgbG9uZy1wb2xsIGJ1ZGdldHMgLSBzb1xuICogY2FuY2VsbGF0aW9uIGFsd2F5cyByZWplY3RzIHdpdGggdGhlIGNhbGxlcidzIGBzaWduYWwucmVhc29uYCByYXRoZXJcbiAqIHRoYW4gc2lsZW50bHkgcmVzb2x2aW5nIGFmdGVyIHRoZSB0aW1lciBleHBpcmVzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBhd2FpdCBzbGVlcCgyNTAsIHJlcS5zaWduYWwpO1xuICovXG5leHBvcnQgZnVuY3Rpb24gc2xlZXAobXM6IG51bWJlciwgc2lnbmFsPzogQWJvcnRTaWduYWwpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKHNpZ25hbD8uYWJvcnRlZCkgcmV0dXJuIFByb21pc2UucmVqZWN0KHNpZ25hbC5yZWFzb24pO1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IG9uQWJvcnQgPSAoKTogdm9pZCA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgcmVqZWN0KHNpZ25hbCEucmVhc29uKTtcbiAgICB9O1xuICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBzaWduYWw/LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJhYm9ydFwiLCBvbkFib3J0KTtcbiAgICAgIHJlc29sdmUoKTtcbiAgICB9LCBtcyk7XG4gICAgc2lnbmFsPy5hZGRFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgb25BYm9ydCwgeyBvbmNlOiB0cnVlIH0pO1xuICB9KTtcbn1cbiJdfQ==