fetch-retrier 0.2.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Fetch Retrier
2
2
 
3
- A lightweight wrapper around `fetch` that adds **retries**, **timeout**, and **full jitter** backoff. Useful for calling HTTP APIs that may be rate-limited (429) or temporarily unavailable (5xx).
3
+ A lightweight wrapper around `fetch` that adds **retries**, **per-attempt timeout**, and **full jitter** backoff. Pass standard `RequestInit` options (`method`, `body`, `credentials`, and more) for POST/PUT APIs and other HTTP calls that may be rate-limited (429) or temporarily unavailable (5xx).
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/fetch-retrier.svg)](https://www.npmjs.com/package/fetch-retrier)
6
6
  [![npm downloads](https://img.shields.io/npm/dm/fetch-retrier.svg)](https://www.npmjs.com/package/fetch-retrier)
@@ -10,11 +10,14 @@ A lightweight wrapper around `fetch` that adds **retries**, **timeout**, and **f
10
10
  ## Features
11
11
 
12
12
  - **Configurable retries** – Set the maximum number of attempts per request.
13
- - **Per-request timeout** – Abort requests that exceed a given duration.
13
+ - **Per-attempt timeout** – Abort each attempt when it exceeds a given duration.
14
14
  - **Full jitter backoff** – Exponential backoff with random jitter (AWS-style) between retries.
15
- - **Custom retry predicate** – Control which status codes trigger a retry (default: 429, 500, 502, 503, 504).
16
- - **External cancellation** – Pass an `AbortSignal` to cancel an in-flight request.
17
- - **TypeScript** – Exported types for `RequestOptions` and usage in TS/JS.
15
+ - **RequestInit forwarding** – Pass `method`, `body`, `credentials`, `redirect`, and other `fetch` options via `init` on every attempt.
16
+ - **Header shorthand** – Optional top-level `headers` override `init.headers` when both are set.
17
+ - **Custom retry predicate** – Control which responses trigger a retry (default: 429, 500, 502, 503, 504).
18
+ - **External cancellation** – Pass an `AbortSignal` to cancel in-flight requests.
19
+ - **Typed errors** – `FetchRetrierHttpError`, `FetchRetrierNetworkError`, `FetchRetrierAbortError`, and related classes.
20
+ - **TypeScript** – Exported types including `RequestOptions` and `FetchInitOptions`.
18
21
 
19
22
  ## Installation
20
23
 
@@ -32,6 +35,8 @@ yarn add fetch-retrier
32
35
 
33
36
  ## Usage
34
37
 
38
+ ### GET request
39
+
35
40
  ```typescript
36
41
  import { fetchRetrier, RequestOptions } from 'fetch-retrier';
37
42
 
@@ -40,7 +45,7 @@ const options: RequestOptions = {
40
45
  timeoutMs: 5000,
41
46
  baseBackoffMs: 1000,
42
47
  headers: {
43
- 'Authorization': 'Bearer token',
48
+ Authorization: 'Bearer token',
44
49
  },
45
50
  };
46
51
 
@@ -48,20 +53,30 @@ const response = await fetchRetrier('https://api.example.com/data', options);
48
53
 
49
54
  if (response.ok) {
50
55
  const data = await response.json();
51
- // ...
52
56
  }
53
57
  ```
54
58
 
55
- ### Options
59
+ ### POST with JSON body (`init`)
56
60
 
57
- | Option | Type | Required | Description |
58
- |--------|------|----------|-------------|
59
- | `retries` | `number` | Yes | Maximum number of attempts (including the first request). |
60
- | `timeoutMs` | `number` | Yes | Timeout in milliseconds for each request. Requests are aborted when this is exceeded. |
61
- | `baseBackoffMs` | `number` | Yes | Base delay in milliseconds for backoff. Delay is capped at `baseBackoffMs * 2^attempt` and randomized (full jitter). |
62
- | `headers` | `Record<string, string>` | No | Headers to send with the request. |
63
- | `signal` | `AbortSignal` | No | Optional external abort signal. If already aborted, `FetchRetrierAlreadyAbortedError` is thrown. If aborted during an attempt, the request is aborted and retried until `retries` is exhausted. |
64
- | `shouldRetry` | `(response: Response, body: string) => boolean` | No | Custom predicate. Return `true` to retry on this response. Default: retry on status 429, 500, 502, 503, 504. |
61
+ ```typescript
62
+ import { fetchRetrier } from 'fetch-retrier';
63
+
64
+ const response = await fetchRetrier('https://api.example.com/items', {
65
+ retries: 3,
66
+ timeoutMs: 5000,
67
+ baseBackoffMs: 1000,
68
+ init: {
69
+ method: 'POST',
70
+ headers: { 'Content-Type': 'application/json' },
71
+ body: JSON.stringify({ name: 'example' }),
72
+ credentials: 'include',
73
+ },
74
+ });
75
+
76
+ const item = await response.json();
77
+ ```
78
+
79
+ The same `init` (including `body`) is applied on every retry attempt. Per-attempt `signal` and timeout are managed internally.
65
80
 
66
81
  ### Custom retry logic
67
82
 
@@ -71,7 +86,6 @@ const response = await fetchRetrier('https://api.example.com/data', {
71
86
  timeoutMs: 10000,
72
87
  baseBackoffMs: 500,
73
88
  shouldRetry: (res, body) => {
74
- // Retry on rate limit or server errors, or when body indicates "retry later"
75
89
  if ([429, 500, 502, 503].includes(res.status)) return true;
76
90
  if (res.status === 200 && body.includes('"retry": true')) return true;
77
91
  return false;
@@ -94,19 +108,31 @@ await fetchRetrier('https://api.example.com/data', {
94
108
  });
95
109
  ```
96
110
 
97
- ## Retry and error behavior
111
+ ### Retry and error behavior
98
112
 
99
113
  - **Success** – If `response.ok` is true, the response is returned immediately.
100
114
  - **Retriable failure** – If the response is not OK and `shouldRetry(response, body)` returns true, the client waits (full jitter backoff) and retries until `retries` is exhausted. On the last attempt, `FetchRetrierHttpError` is thrown (includes `status`).
101
- - **Non-retriable failure** – If `shouldRetry` returns false, `FetchRetrierHttpError` is thrown immediately (e.g. message `Non-retriable HTTP error: 404`).
102
- - **Timeout** – If a request exceeds `timeoutMs`, it is aborted and retried (same backoff) until `retries` is exhausted; the final failure is `FetchRetrierAbortError`.
103
- - **Network/TypeError** – Network errors and related `TypeError`s are retried with backoff; after the last attempt, `FetchRetrierNetworkError` is thrown with the original error as `cause`.
104
- - **Already aborted signal** – If `signal` is already aborted before an attempt starts, `FetchRetrierAlreadyAbortedError` is thrown immediately (no attempt is made).
115
+ - **Non-retriable failure** – If `shouldRetry` returns false, `FetchRetrierHttpError` is thrown immediately (e.g. `Non-retriable HTTP error: 404`).
116
+ - **Timeout** – If a request exceeds `timeoutMs`, it is aborted and retried until `retries` is exhausted; the final failure is `FetchRetrierAbortError`.
117
+ - **Network / TypeError** – Network errors are retried with backoff; after the last attempt, `FetchRetrierNetworkError` is thrown with the original error as `cause`.
118
+ - **Already aborted signal** – If `signal` is already aborted before an attempt starts, `FetchRetrierAlreadyAbortedError` is thrown (no attempt is made).
119
+
120
+ ## Options
121
+
122
+ | Option | Type | Required | Description |
123
+ |--------|------|----------|-------------|
124
+ | `retries` | `number` | Yes | Maximum number of attempts (including the first request). |
125
+ | `timeoutMs` | `number` | Yes | Timeout in milliseconds for each attempt. Exceeded attempts are aborted and retried. |
126
+ | `baseBackoffMs` | `number` | Yes | Base delay in milliseconds for backoff. Delay is capped at `baseBackoffMs * 2^attempt` and randomized (full jitter). |
127
+ | `init` | `FetchInitOptions` | No | `fetch` options forwarded to every attempt: `method`, `body`, `credentials`, `redirect`, `mode`, `cache`, etc. `signal` is reserved for internal timeout and cancellation. |
128
+ | `headers` | `Record<string, string>` | No | Headers sent on every attempt. Overrides `init.headers` when both are set. |
129
+ | `signal` | `AbortSignal` | No | External abort signal. If already aborted, `FetchRetrierAlreadyAbortedError` is thrown. If aborted during an attempt, the request is aborted and retried until `retries` is exhausted. |
130
+ | `shouldRetry` | `(response: Response, body: string) => boolean` | No | Called after `response.text()` when `response.ok` is false. Return `true` to retry. Default: 429, 500, 502, 503, 504. |
105
131
 
106
132
  ## Requirements
107
133
 
108
134
  - **Node.js** >= 20.0.0
109
- - Uses the global `fetch` (available in Node 18+).
135
+ - Uses the global `fetch` (available in Node 18+)
110
136
 
111
137
  ## License
112
138
 
package/lib/index.d.ts CHANGED
@@ -1,9 +1,33 @@
1
1
  /**
2
- * Configuration for {@link fetchRetrier}.
2
+ * Retry-enabled `fetch` wrapper with per-attempt timeout, full-jitter backoff, and typed errors.
3
+ *
4
+ * @module fetch-retrier
5
+ */
6
+ /**
7
+ * `fetch` options forwarded to every attempt, excluding `signal`.
8
+ *
9
+ * Use for `method`, `body`, `credentials`, `redirect`, `mode`, `cache`, and other
10
+ * {@link https://developer.mozilla.org/en-US/docs/Web/API/RequestInit | RequestInit} fields.
11
+ * Per-attempt abort and timeout are handled internally via `signal` and must not be set here.
12
+ */
13
+ export type FetchInitOptions = Omit<RequestInit, 'signal'>;
14
+ /**
15
+ * Options for {@link fetchRetrier}: retry policy, timeout, backoff, request payload, and cancellation.
16
+ *
17
+ * Request shape is built as `{ ...init, headers?, signal }` on each attempt. Top-level `headers`
18
+ * override `init.headers` when both are provided.
3
19
  */
4
20
  export interface RequestOptions {
5
- /** Optional HTTP headers sent with each attempt. */
21
+ /**
22
+ * HTTP headers sent on every attempt.
23
+ * When `init.headers` is also set, these values take precedence for duplicate keys.
24
+ */
6
25
  headers?: Record<string, string>;
26
+ /**
27
+ * Additional {@link FetchInitOptions} merged into each `fetch` call (e.g. POST `method` and JSON `body`).
28
+ * The same `init` is reused across retries.
29
+ */
30
+ init?: FetchInitOptions;
7
31
  /** Maximum number of attempts, including the first. */
8
32
  retries: number;
9
33
  /** Per-attempt timeout in milliseconds; uses an internal {@link AbortController} when exceeded. */
@@ -18,12 +42,18 @@ export interface RequestOptions {
18
42
  */
19
43
  signal?: AbortSignal;
20
44
  /**
21
- * Return `true` to schedule another attempt for this non-OK response.
45
+ * Invoked after `response.text()` when `response.ok` is false.
46
+ * Return `true` to schedule another attempt (until `retries` is exhausted).
22
47
  * Default: retry on status 429, 500, 502, 503, or 504.
48
+ *
49
+ * @param response - Non-OK response from the current attempt
50
+ * @param body - Response body text from `response.text()`
23
51
  */
24
52
  shouldRetry?: (response: Response, body: string) => boolean;
25
53
  }
26
- /** Error thrown when a request is cancelled by timeout or an external {@link AbortSignal}. */
54
+ /**
55
+ * Error thrown when a request is cancelled by timeout or an external {@link AbortSignal}.
56
+ */
27
57
  export declare class FetchRetrierAbortError extends Error {
28
58
  readonly name: string;
29
59
  /**
@@ -41,29 +71,37 @@ export declare class FetchRetrierAlreadyAbortedError extends FetchRetrierAbortEr
41
71
  */
42
72
  constructor(message?: string);
43
73
  }
44
- /** Error thrown when the server returns a non-OK HTTP status and no further retry is performed. */
74
+ /**
75
+ * Error thrown when the server returns a non-OK HTTP status and no further retry is performed.
76
+ *
77
+ * @property status - HTTP status code from the last non-OK response
78
+ */
45
79
  export declare class FetchRetrierHttpError extends Error {
46
80
  readonly status: number;
47
81
  readonly name: string;
48
82
  /**
49
83
  * @param message - Error description
50
- * @param status - HTTP status code from the response
84
+ * @param status - HTTP status code from the last non-OK response
51
85
  */
52
86
  constructor(message: string, status: number);
53
87
  }
54
88
  /**
55
89
  * Error thrown when a fetch fails with a network-level error (e.g. DNS failure, connection refused).
90
+ *
91
+ * @property cause - Original error from the underlying `fetch`, when available
56
92
  */
57
93
  export declare class FetchRetrierNetworkError extends Error {
58
94
  readonly cause?: unknown | undefined;
59
95
  readonly name: string;
60
96
  /**
61
97
  * @param message - Human-readable reason (default: `'Network error'`)
62
- * @param cause - Original error, if any
98
+ * @param cause - Original error from the underlying `fetch`, when available
63
99
  */
64
100
  constructor(message?: string, cause?: unknown | undefined);
65
101
  }
66
- /** Error thrown when an internal invariant fails (should not happen in normal use). */
102
+ /**
103
+ * Error thrown when an internal invariant fails (should not happen in normal use).
104
+ */
67
105
  export declare class FetchRetrierUnreachableError extends Error {
68
106
  readonly name: string;
69
107
  /**
@@ -72,17 +110,20 @@ export declare class FetchRetrierUnreachableError extends Error {
72
110
  constructor(message?: string);
73
111
  }
74
112
  /**
75
- * Performs `fetch` with retries, a per-attempt timeout, exponential backoff with full jitter,
76
- * optional {@link RequestOptions.signal} cancellation, and a configurable retry predicate for
77
- * non-OK responses.
113
+ * Wraps `fetch` with retries, per-attempt timeout, full-jitter backoff, and optional cancellation.
114
+ *
115
+ * Each attempt calls `fetch(url, { ...options.init, headers?, signal })` with an internal
116
+ * {@link AbortSignal} for `timeoutMs`. Non-OK responses are retried when `shouldRetry` returns
117
+ * `true` (default: 429 and 5xx). The same {@link FetchInitOptions} (including `body`) is reused
118
+ * on every attempt.
78
119
  *
79
- * @param url - Request URL
80
- * @param options - Retries, backoff, timeout, optional abort signal, and optional retry predicate
81
- * @returns The first successful (OK) {@link Response}
120
+ * @param url - Request URL passed to `fetch`
121
+ * @param options - {@link RequestOptions} controlling retries, timeout, request init, and cancellation
122
+ * @returns The first {@link Response} for which `ok` is `true`
82
123
  * @throws {FetchRetrierAlreadyAbortedError} If `options.signal` is already aborted before an attempt
83
124
  * @throws {FetchRetrierHttpError} On a non-OK response that is not retried or after the last attempt
84
- * @throws {FetchRetrierNetworkError} On a network error on the final attempt
85
- * @throws {FetchRetrierAbortError} On timeout or external abort on the final attempt
125
+ * @throws {FetchRetrierNetworkError} On a network `TypeError` after the last attempt
126
+ * @throws {FetchRetrierAbortError} On timeout or external abort after the last attempt
86
127
  * @throws {FetchRetrierUnreachableError} If the retry loop exits without returning (internal bug)
87
128
  */
88
129
  export declare const fetchRetrier: (url: string, options: RequestOptions) => Promise<Response>;
package/lib/index.js CHANGED
@@ -1,7 +1,14 @@
1
1
  "use strict";
2
+ /**
3
+ * Retry-enabled `fetch` wrapper with per-attempt timeout, full-jitter backoff, and typed errors.
4
+ *
5
+ * @module fetch-retrier
6
+ */
2
7
  Object.defineProperty(exports, "__esModule", { value: true });
3
8
  exports.fetchRetrier = exports.FetchRetrierUnreachableError = exports.FetchRetrierNetworkError = exports.FetchRetrierHttpError = exports.FetchRetrierAlreadyAbortedError = exports.FetchRetrierAbortError = void 0;
4
- /** Error thrown when a request is cancelled by timeout or an external {@link AbortSignal}. */
9
+ /**
10
+ * Error thrown when a request is cancelled by timeout or an external {@link AbortSignal}.
11
+ */
5
12
  class FetchRetrierAbortError extends Error {
6
13
  /**
7
14
  * @param message - Human-readable reason (default: `'Aborted'`)
@@ -27,11 +34,15 @@ class FetchRetrierAlreadyAbortedError extends FetchRetrierAbortError {
27
34
  }
28
35
  }
29
36
  exports.FetchRetrierAlreadyAbortedError = FetchRetrierAlreadyAbortedError;
30
- /** Error thrown when the server returns a non-OK HTTP status and no further retry is performed. */
37
+ /**
38
+ * Error thrown when the server returns a non-OK HTTP status and no further retry is performed.
39
+ *
40
+ * @property status - HTTP status code from the last non-OK response
41
+ */
31
42
  class FetchRetrierHttpError extends Error {
32
43
  /**
33
44
  * @param message - Error description
34
- * @param status - HTTP status code from the response
45
+ * @param status - HTTP status code from the last non-OK response
35
46
  */
36
47
  constructor(message, status) {
37
48
  super(message);
@@ -43,11 +54,13 @@ class FetchRetrierHttpError extends Error {
43
54
  exports.FetchRetrierHttpError = FetchRetrierHttpError;
44
55
  /**
45
56
  * Error thrown when a fetch fails with a network-level error (e.g. DNS failure, connection refused).
57
+ *
58
+ * @property cause - Original error from the underlying `fetch`, when available
46
59
  */
47
60
  class FetchRetrierNetworkError extends Error {
48
61
  /**
49
62
  * @param message - Human-readable reason (default: `'Network error'`)
50
- * @param cause - Original error, if any
63
+ * @param cause - Original error from the underlying `fetch`, when available
51
64
  */
52
65
  constructor(message = 'Network error', cause) {
53
66
  super(message);
@@ -57,7 +70,9 @@ class FetchRetrierNetworkError extends Error {
57
70
  }
58
71
  }
59
72
  exports.FetchRetrierNetworkError = FetchRetrierNetworkError;
60
- /** Error thrown when an internal invariant fails (should not happen in normal use). */
73
+ /**
74
+ * Error thrown when an internal invariant fails (should not happen in normal use).
75
+ */
61
76
  class FetchRetrierUnreachableError extends Error {
62
77
  /**
63
78
  * @param message - Human-readable reason (default: `'Unreachable'`)
@@ -70,27 +85,33 @@ class FetchRetrierUnreachableError extends Error {
70
85
  }
71
86
  exports.FetchRetrierUnreachableError = FetchRetrierUnreachableError;
72
87
  /**
73
- * Default {@link RequestOptions.shouldRetry} implementation: retry on HTTP 429, 500, 502, 503, 504.
88
+ * Default {@link RequestOptions.shouldRetry}: retry on HTTP 429, 500, 502, 503, or 504.
89
+ *
90
+ * @param res - Response from the failed attempt
91
+ * @returns `true` when another attempt should be scheduled
74
92
  */
75
93
  const defaultShouldRetry = (res) => {
76
94
  return [429, 500, 502, 503, 504].includes(res.status);
77
95
  };
78
96
  /**
79
- * Performs `fetch` with retries, a per-attempt timeout, exponential backoff with full jitter,
80
- * optional {@link RequestOptions.signal} cancellation, and a configurable retry predicate for
81
- * non-OK responses.
97
+ * Wraps `fetch` with retries, per-attempt timeout, full-jitter backoff, and optional cancellation.
98
+ *
99
+ * Each attempt calls `fetch(url, { ...options.init, headers?, signal })` with an internal
100
+ * {@link AbortSignal} for `timeoutMs`. Non-OK responses are retried when `shouldRetry` returns
101
+ * `true` (default: 429 and 5xx). The same {@link FetchInitOptions} (including `body`) is reused
102
+ * on every attempt.
82
103
  *
83
- * @param url - Request URL
84
- * @param options - Retries, backoff, timeout, optional abort signal, and optional retry predicate
85
- * @returns The first successful (OK) {@link Response}
104
+ * @param url - Request URL passed to `fetch`
105
+ * @param options - {@link RequestOptions} controlling retries, timeout, request init, and cancellation
106
+ * @returns The first {@link Response} for which `ok` is `true`
86
107
  * @throws {FetchRetrierAlreadyAbortedError} If `options.signal` is already aborted before an attempt
87
108
  * @throws {FetchRetrierHttpError} On a non-OK response that is not retried or after the last attempt
88
- * @throws {FetchRetrierNetworkError} On a network error on the final attempt
89
- * @throws {FetchRetrierAbortError} On timeout or external abort on the final attempt
109
+ * @throws {FetchRetrierNetworkError} On a network `TypeError` after the last attempt
110
+ * @throws {FetchRetrierAbortError} On timeout or external abort after the last attempt
90
111
  * @throws {FetchRetrierUnreachableError} If the retry loop exits without returning (internal bug)
91
112
  */
92
113
  const fetchRetrier = async (url, options) => {
93
- const { headers, retries, timeoutMs, baseBackoffMs, signal: externalSignal, shouldRetry = defaultShouldRetry } = options;
114
+ const { headers, init, retries, timeoutMs, baseBackoffMs, signal: externalSignal, shouldRetry = defaultShouldRetry, } = options;
94
115
  for (let attempt = 1; attempt <= retries; attempt++) {
95
116
  if (externalSignal?.aborted) {
96
117
  throw new FetchRetrierAlreadyAbortedError();
@@ -106,7 +127,8 @@ const fetchRetrier = async (url, options) => {
106
127
  }
107
128
  try {
108
129
  const res = await fetch(url, {
109
- headers,
130
+ ...init,
131
+ ...(headers !== undefined ? { headers } : {}),
110
132
  signal: controller.signal,
111
133
  });
112
134
  clearTimeout(timer);
@@ -148,6 +170,8 @@ const fetchRetrier = async (url, options) => {
148
170
  };
149
171
  exports.fetchRetrier = fetchRetrier;
150
172
  /**
173
+ * Delays execution for the given duration (used between retry attempts).
174
+ *
151
175
  * @param ms - Delay in milliseconds
152
176
  * @returns A promise that resolves after `ms`
153
177
  */
@@ -165,4 +189,4 @@ const fullJitter = (base, attempt) => {
165
189
  const cap = base * Math.pow(2, attempt);
166
190
  return Math.floor(Math.random() * cap);
167
191
  };
168
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBMEJBLDhGQUE4RjtBQUM5RixNQUFhLHNCQUF1QixTQUFRLEtBQUs7SUFFL0M7O09BRUc7SUFDSCxZQUFZLE9BQU8sR0FBRyxTQUFTO1FBQzdCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUxDLFNBQUksR0FBVyx3QkFBd0IsQ0FBQztRQU14RCxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxzQkFBc0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNoRSxDQUFDO0NBQ0Y7QUFURCx3REFTQztBQUVEOztHQUVHO0FBQ0gsTUFBYSwrQkFBZ0MsU0FBUSxzQkFBc0I7SUFFekU7O09BRUc7SUFDSCxZQUFZLE9BQU8sR0FBRyw0QkFBNEI7UUFDaEQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBTEMsU0FBSSxHQUFXLGlDQUFpQyxDQUFDO1FBTWpFLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLCtCQUErQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7Q0FDRjtBQVRELDBFQVNDO0FBRUQsbUdBQW1HO0FBQ25HLE1BQWEscUJBQXNCLFNBQVEsS0FBSztJQUU5Qzs7O09BR0c7SUFDSCxZQUNFLE9BQWUsRUFDQyxNQUFjO1FBRTlCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUZDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFQZCxTQUFJLEdBQVcsdUJBQXVCLENBQUM7UUFVdkQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUscUJBQXFCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDL0QsQ0FBQztDQUNGO0FBYkQsc0RBYUM7QUFFRDs7R0FFRztBQUNILE1BQWEsd0JBQXlCLFNBQVEsS0FBSztJQUVqRDs7O09BR0c7SUFDSCxZQUFZLE9BQU8sR0FBRyxlQUFlLEVBQWtCLEtBQWU7UUFDcEUs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Q3pDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMzRCxDQUFDLENBQUM7QUFFRjs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsR0FBRyxDQUFDLElBQVksRUFBRSxPQUFlLEVBQVUsRUFBRTtJQUMzRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDeEMsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUN6QyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHtAbGluayBmZXRjaFJldHJpZXJ9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlcXVlc3RPcHRpb25zIHtcbiAgLyoqIE9wdGlvbmFsIEhUVFAgaGVhZGVycyBzZW50IHdpdGggZWFjaCBhdHRlbXB0LiAqL1xuICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgLyoqIE1heGltdW0gbnVtYmVyIG9mIGF0dGVtcHRzLCBpbmNsdWRpbmcgdGhlIGZpcnN0LiAqL1xuICByZXRyaWVzOiBudW1iZXI7XG4gIC8qKiBQZXItYXR0ZW1wdCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kczsgdXNlcyBhbiBpbnRlcm5hbCB7QGxpbmsgQWJvcnRDb250cm9sbGVyfSB3aGVuIGV4Y2VlZGVkLiAqL1xuICB0aW1lb3V0TXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIEJhc2UgYmFja29mZiBpbiBtaWxsaXNlY29uZHMgZm9yIGZ1bGwgaml0dGVyLiBUaGUgY2FwIGZvciBhdHRlbXB0IGBuYCBpcyBgYmFzZUJhY2tvZmZNcyAqIDJebmAuXG4gICAqL1xuICBiYXNlQmFja29mZk1zOiBudW1iZXI7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBleHRlcm5hbCB7QGxpbmsgQWJvcnRTaWduYWx9LiBXaGVuIGFib3J0ZWQsIHRoZSBpbi1mbGlnaHQgcmVxdWVzdCBpcyBhYm9ydGVkOyBvbiB0aGVcbiAgICogZmluYWwgYXR0ZW1wdCwgY2FuY2VsbGF0aW9uIHN1cmZhY2VzIGFzIHtAbGluayBGZXRjaFJldHJpZXJBYm9ydEVycm9yfS5cbiAgICovXG4gIHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICAvKipcbiAgICogUmV0dXJuIGB0cnVlYCB0byBzY2hlZHVsZSBhbm90aGVyIGF0dGVtcHQgZm9yIHRoaXMgbm9uLU9LIHJlc3BvbnNlLlxuICAgKiBEZWZhdWx0OiByZXRyeSBvbiBzdGF0dXMgNDI5LCA1MDAsIDUwMiwgNTAzLCBvciA1MDQuXG4gICAqL1xuICBzaG91bGRSZXRyeT86IChyZXNwb25zZTogUmVzcG9uc2UsIGJvZHk6IHN0cmluZykgPT4gYm9vbGVhbjtcbn1cblxuLyoqIEVycm9yIHRocm93biB3aGVuIGEgcmVxdWVzdCBpcyBjYW5jZWxsZWQgYnkgdGltZW91dCBvciBhbiBleHRlcm5hbCB7QGxpbmsgQWJvcnRTaWduYWx9LiAqL1xuZXhwb3J0IGNsYXNzIEZldGNoUmV0cmllckFib3J0RXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIG92ZXJyaWRlIHJlYWRvbmx5IG5hbWU6IHN0cmluZyA9ICdGZXRjaFJldHJpZXJBYm9ydEVycm9yJztcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gSHVtYW4tcmVhZGFibGUgcmVhc29uIChkZWZhdWx0OiBgJ0Fib3J0ZWQnYClcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnQWJvcnRlZCcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4ge0BsaW5rIFJlcXVlc3RPcHRpb25zLnNpZ25hbH0gaXMgYWxyZWFkeSBhYm9ydGVkIGJlZm9yZSBhbiBhdHRlbXB0IHN0YXJ0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIEZldGNoUmV0cmllckFscmVhZHlBYm9ydGVkRXJyb3IgZXh0ZW5kcyBGZXRjaFJldHJpZXJBYm9ydEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllckFscmVhZHlBYm9ydGVkRXJyb3InO1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBIdW1hbi1yZWFkYWJsZSByZWFzb24gKGRlZmF1bHQ6IGAnU2lnbmFsIHdhcyBhbHJlYWR5IGFib3J0ZWQnYClcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnU2lnbmFsIHdhcyBhbHJlYWR5IGFib3J0ZWQnKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIEZldGNoUmV0cmllckFscmVhZHlBYm9ydGVkRXJyb3IucHJvdG90eXBlKTtcbiAgfVxufVxuXG4vKiogRXJyb3IgdGhyb3duIHdoZW4gdGhlIHNlcnZlciByZXR1cm5zIGEgbm9uLU9LIEhUVFAgc3RhdHVzIGFuZCBubyBmdXJ0aGVyIHJldHJ5IGlzIHBlcmZvcm1lZC4gKi9cbmV4cG9ydCBjbGFzcyBGZXRjaFJldHJpZXJIdHRwRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIG92ZXJyaWRlIHJlYWRvbmx5IG5hbWU6IHN0cmluZyA9ICdGZXRjaFJldHJpZXJIdHRwRXJyb3InO1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBFcnJvciBkZXNjcmlwdGlvblxuICAgKiBAcGFyYW0gc3RhdHVzIC0gSFRUUCBzdGF0dXMgY29kZSBmcm9tIHRoZSByZXNwb25zZVxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICAgIHB1YmxpYyByZWFkb25seSBzdGF0dXM6IG51bWJlcixcbiAgKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIEZldGNoUmV0cmllckh0dHBFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4gYSBmZXRjaCBmYWlscyB3aXRoIGEgbmV0d29yay1sZXZlbCBlcnJvciAoZS5nLiBETlMgZmFpbHVyZSwgY29ubmVjdGlvbiByZWZ1c2VkKS5cbiAqL1xuZXhwb3J0IGNsYXNzIEZldGNoUmV0cmllck5ldHdvcmtFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllck5ldHdvcmtFcnJvcic7XG4gIC8qKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIEh1bWFuLXJlYWRhYmxlIHJlYXNvbiAoZGVmYXVsdDogYCdOZXR3b3JrIGVycm9yJ2ApXG4gICAqIEBwYXJhbSBjYXVzZSAtIE9yaWdpbmFsIGVycm9yLCBpZiBhbnlcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnTmV0d29yayBlcnJvcicsIHB1YmxpYyByZWFkb25seSBjYXVzZT86IHVua25vd24pIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVyTmV0d29ya0Vycm9yLnByb3RvdHlwZSk7XG4gIH1cbn1cblxuLyoqIEVycm9yIHRocm93biB3aGVuIGFuIGludGVybmFsIGludmFyaWFudCBmYWlscyAoc2hvdWxkIG5vdCBoYXBwZW4gaW4gbm9ybWFsIHVzZSkuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVyVW5yZWFjaGFibGVFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3InO1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBIdW1hbi1yZWFkYWJsZSByZWFzb24gKGRlZmF1bHQ6IGAnVW5yZWFjaGFibGUnYClcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnVW5yZWFjaGFibGUnKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIEZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3IucHJvdG90eXBlKTtcbiAgfVxufVxuXG4vKipcbiAqIERlZmF1bHQge0BsaW5rIFJlcXVlc3RPcHRpb25zLnNob3VsZFJldHJ5fSBpbXBsZW1lbnRhdGlvbjogcmV0cnkgb24gSFRUUCA0MjksIDUwMCwgNTAyLCA1MDMsIDUwNC5cbiAqL1xuY29uc3QgZGVmYXVsdFNob3VsZFJldHJ5ID0gKHJlczogUmVzcG9uc2UpOiBib29sZWFuID0+IHtcbiAgcmV0dXJuIFs0MjksIDUwMCwgNTAyLCA1MDMsIDUwNF0uaW5jbHVkZXMocmVzLnN0YXR1cyk7XG59O1xuXG4vKipcbiAqIFBlcmZvcm1zIGBmZXRjaGAgd2l0aCByZXRyaWVzLCBhIHBlci1hdHRlbXB0IHRpbWVvdXQsIGV4cG9uZW50aWFsIGJhY2tvZmYgd2l0aCBmdWxsIGppdHRlcixcbiAqIG9wdGlvbmFsIHtAbGluayBSZXF1ZXN0T3B0aW9ucy5zaWduYWx9IGNhbmNlbGxhdGlvbiwgYW5kIGEgY29uZmlndXJhYmxlIHJldHJ5IHByZWRpY2F0ZSBmb3JcbiAqIG5vbi1PSyByZXNwb25zZXMuXG4gKlxuICogQHBhcmFtIHVybCAtIFJlcXVlc3QgVVJMXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFJldHJpZXMsIGJhY2tvZmYsIHRpbWVvdXQsIG9wdGlvbmFsIGFib3J0IHNpZ25hbCwgYW5kIG9wdGlvbmFsIHJldHJ5IHByZWRpY2F0ZVxuICogQHJldHVybnMgVGhlIGZpcnN0IHN1Y2Nlc3NmdWwgKE9LKSB7QGxpbmsgUmVzcG9uc2V9XG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJBbHJlYWR5QWJvcnRlZEVycm9yfSBJZiBgb3B0aW9ucy5zaWduYWxgIGlzIGFscmVhZHkgYWJvcnRlZCBiZWZvcmUgYW4gYXR0ZW1wdFxuICogQHRocm93cyB7RmV0Y2hSZXRyaWVySHR0cEVycm9yfSBPbiBhIG5vbi1PSyByZXNwb25zZSB0aGF0IGlzIG5vdCByZXRyaWVkIG9yIGFmdGVyIHRoZSBsYXN0IGF0dGVtcHRcbiAqIEB0aHJvd3Mge0ZldGNoUmV0cmllck5ldHdvcmtFcnJvcn0gT24gYSBuZXR3b3JrIGVycm9yIG9uIHRoZSBmaW5hbCBhdHRlbXB0XG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJBYm9ydEVycm9yfSBPbiB0aW1lb3V0IG9yIGV4dGVybmFsIGFib3J0IG9uIHRoZSBmaW5hbCBhdHRlbXB0XG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJVbnJlYWNoYWJsZUVycm9yfSBJZiB0aGUgcmV0cnkgbG9vcCBleGl0cyB3aXRob3V0IHJldHVybmluZyAoaW50ZXJuYWwgYnVnKVxuICovXG5leHBvcnQgY29uc3QgZmV0Y2hSZXRyaWVyID0gYXN5bmMgKHVybDogc3RyaW5nLCBvcHRpb25zOiBSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8UmVzcG9uc2U+ID0+IHtcbiAgY29uc3QgeyBoZWFkZXJzLCByZXRyaWVzLCB0aW1lb3V0TXMsIGJhc2VCYWNrb2ZmTXMsIHNpZ25hbDogZXh0ZXJuYWxTaWduYWwsIHNob3VsZFJldHJ5ID0gZGVmYXVsdFNob3VsZFJldHJ5IH0gPSBvcHRpb25zO1xuXG4gIGZvciAobGV0IGF0dGVtcHQgPSAxOyBhdHRlbXB0IDw9IHJldHJpZXM7IGF0dGVtcHQrKykge1xuICAgIGlmIChleHRlcm5hbFNpZ25hbD8uYWJvcnRlZCkge1xuICAgICAgdGhyb3cgbmV3IEZldGNoUmV0cmllckFscmVhZHlBYm9ydGVkRXJyb3IoKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiBjb250cm9sbGVyLmFib3J0KCksIHRpbWVvdXRNcyk7XG5cbiAgICBjb25zdCBvbkV4dGVybmFsQWJvcnQgPSAoKTogdm9pZCA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgY29udHJvbGxlci5hYm9ydCgpO1xuICAgIH07XG5cbiAgICBpZiAoZXh0ZXJuYWxTaWduYWwpIHtcbiAgICAgIGV4dGVybmFsU2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25FeHRlcm5hbEFib3J0KTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2godXJsLCB7XG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIHNpZ25hbDogY29udHJvbGxlci5zaWduYWwsXG4gICAgICB9KTtcblxuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIGV4dGVybmFsU2lnbmFsPy5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uRXh0ZXJuYWxBYm9ydCk7XG5cbiAgICAgIGlmIChyZXMub2spIHtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgIH1cblxuICAgICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlcy50ZXh0KCk7XG4gICAgICBjb25zdCBpc0NvbnRpbnVlID0gc2hvdWxkUmV0cnkocmVzLCB0ZXh0KTtcblxuICAgICAgaWYgKGlzQ29udGludWUpIHtcbiAgICAgICAgaWYgKGF0dGVtcHQgPT09IHJldHJpZXMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRmV0Y2hSZXRyaWVySHR0cEVycm9yKGBIVFRQICR7cmVzLnN0YXR1c31gLCByZXMuc3RhdHVzKTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB3YWl0KGZ1bGxKaXR0ZXIoYmFzZUJhY2tvZmZNcywgYXR0ZW1wdCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEZldGNoUmV0cmllckh0dHBFcnJvcihgTm9uLXJldHJpYWJsZSBIVFRQIGVycm9yOiAke3Jlcy5zdGF0dXN9YCwgcmVzLnN0YXR1cyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgZXh0ZXJuYWxTaWduYWw/LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25FeHRlcm5hbEFib3J0KTtcblxuICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yICYmIGVyci5uYW1lID09PSAnQWJvcnRFcnJvcicpIHtcbiAgICAgICAgaWYgKGF0dGVtcHQgPT09IHJldHJpZXMpIHRocm93IGVyciBpbnN0YW5jZW9mIEZldGNoUmV0cmllckFib3J0RXJyb3IgPyBlcnIgOiBuZXcgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvcigpO1xuICAgICAgICBhd2FpdCB3YWl0KGZ1bGxKaXR0ZXIoYmFzZUJhY2tvZmZNcywgYXR0ZW1wdCkpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIFR5cGVFcnJvcikge1xuICAgICAgICBpZiAoYXR0ZW1wdCA9PT0gcmV0cmllcykgdGhyb3cgbmV3IEZldGNoUmV0cmllck5ldHdvcmtFcnJvcignTmV0d29yayBlcnJvcicsIGVycik7XG4gICAgICAgIGF3YWl0IHdhaXQoZnVsbEppdHRlcihiYXNlQmFja29mZk1zLCBhdHRlbXB0KSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IEZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3IoKTtcbn07XG5cbi8qKlxuICogQHBhcmFtIG1zIC0gRGVsYXkgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciBgbXNgXG4gKi9cbmNvbnN0IHdhaXQgPSAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4gPT4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbn07XG5cbi8qKlxuICogRnVsbCBqaXR0ZXIgYmFja29mZjogcmFuZG9tIGRlbGF5IGluIGBbMCwgYmFzZSAqIDJeYXR0ZW1wdClgIG1zIChBV1MtcmVjb21tZW5kZWQgcGF0dGVybikuXG4gKlxuICogQHBhcmFtIGJhc2UgLSBCYXNlIGJhY2tvZmYgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcGFyYW0gYXR0ZW1wdCAtIDEtYmFzZWQgYXR0ZW1wdCBpbmRleCAoZmlyc3QgcmV0cnkgdXNlcyBgYXR0ZW1wdCA9PT0gMWApXG4gKiBAcmV0dXJucyBXYWl0IGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcyBiZWZvcmUgdGhlIG5leHQgYXR0ZW1wdFxuICovXG5jb25zdCBmdWxsSml0dGVyID0gKGJhc2U6IG51bWJlciwgYXR0ZW1wdDogbnVtYmVyKTogbnVtYmVyID0+IHtcbiAgY29uc3QgY2FwID0gYmFzZSAqIE1hdGgucG93KDIsIGF0dGVtcHQpO1xuICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogY2FwKTtcbn07XG4iXX0=
192
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7O0dBSUc7OztBQW9ESDs7R0FFRztBQUNILE1BQWEsc0JBQXVCLFNBQVEsS0FBSztJQUUvQzs7T0FFRztJQUNILFlBQVksT0FBTyxHQUFHLFNBQVM7UUFDN0IsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBTEMsU0FBSSxHQUFXLHdCQUF3QixDQUFDO1FBTXhELE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLHNCQUFzQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7Q0FDRjtBQVRELHdEQVNDO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLCtCQUFnQyxTQUFRLHNCQUFzQjtJQUV6RTs7T0FFRztJQUNILFlBQVksT0FBTyxHQUFHLDRCQUE0QjtRQUNoRCxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFMQyxTQUFJLEdBQVcsaUNBQWlDLENBQUM7UUFNakUsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsK0JBQStCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDekUsQ0FBQztDQUNGO0FBVEQsMEVBU0M7QUFFRDs7OztHQUlHO0FBQ0gsTUFBYSxxQkFBc0IsU0FBUSxLQUFLO0lBRTlDOzs7T0FHRztJQUNILFlBQ0UsT0FBZSxFQUNDLE1BQWM7UUFFOUIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRkMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQVBkLFNBQUksR0FBVyx1QkFBdUIsQ0FBQztRQVV2RCxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMvRCxDQUFDO0NBQ0Y7QUFiRCxzREFhQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFhLHdCQUF5QixTQUFRLEtBQUs7SUFFakQ7OztPQUdHO0lBQ0gsWUFBWSxPQUFPLEdBQUcsZUFBZSxFQUFr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QUFNLElBQUksNEJBQTRCLEVBQUUsQ0FBQztBQUMzQyxDQUFDLENBQUM7QUExRVcsUUFBQSxZQUFZLGdCQTBFdkI7QUFFRjs7Ozs7R0FLRztBQUNILE1BQU0sSUFBSSxHQUFHLENBQUMsRUFBVSxFQUFpQixFQUFFO0lBQ3pDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMzRCxDQUFDLENBQUM7QUFFRjs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsR0FBRyxDQUFDLElBQVksRUFBRSxPQUFlLEVBQVUsRUFBRTtJQUMzRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDeEMsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUN6QyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFJldHJ5LWVuYWJsZWQgYGZldGNoYCB3cmFwcGVyIHdpdGggcGVyLWF0dGVtcHQgdGltZW91dCwgZnVsbC1qaXR0ZXIgYmFja29mZiwgYW5kIHR5cGVkIGVycm9ycy5cbiAqXG4gKiBAbW9kdWxlIGZldGNoLXJldHJpZXJcbiAqL1xuXG4vKipcbiAqIGBmZXRjaGAgb3B0aW9ucyBmb3J3YXJkZWQgdG8gZXZlcnkgYXR0ZW1wdCwgZXhjbHVkaW5nIGBzaWduYWxgLlxuICpcbiAqIFVzZSBmb3IgYG1ldGhvZGAsIGBib2R5YCwgYGNyZWRlbnRpYWxzYCwgYHJlZGlyZWN0YCwgYG1vZGVgLCBgY2FjaGVgLCBhbmQgb3RoZXJcbiAqIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUmVxdWVzdEluaXQgfCBSZXF1ZXN0SW5pdH0gZmllbGRzLlxuICogUGVyLWF0dGVtcHQgYWJvcnQgYW5kIHRpbWVvdXQgYXJlIGhhbmRsZWQgaW50ZXJuYWxseSB2aWEgYHNpZ25hbGAgYW5kIG11c3Qgbm90IGJlIHNldCBoZXJlLlxuICovXG5leHBvcnQgdHlwZSBGZXRjaEluaXRPcHRpb25zID0gT21pdDxSZXF1ZXN0SW5pdCwgJ3NpZ25hbCc+O1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBmZXRjaFJldHJpZXJ9OiByZXRyeSBwb2xpY3ksIHRpbWVvdXQsIGJhY2tvZmYsIHJlcXVlc3QgcGF5bG9hZCwgYW5kIGNhbmNlbGxhdGlvbi5cbiAqXG4gKiBSZXF1ZXN0IHNoYXBlIGlzIGJ1aWx0IGFzIGB7IC4uLmluaXQsIGhlYWRlcnM/LCBzaWduYWwgfWAgb24gZWFjaCBhdHRlbXB0LiBUb3AtbGV2ZWwgYGhlYWRlcnNgXG4gKiBvdmVycmlkZSBgaW5pdC5oZWFkZXJzYCB3aGVuIGJvdGggYXJlIHByb3ZpZGVkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlcXVlc3RPcHRpb25zIHtcbiAgLyoqXG4gICAqIEhUVFAgaGVhZGVycyBzZW50IG9uIGV2ZXJ5IGF0dGVtcHQuXG4gICAqIFdoZW4gYGluaXQuaGVhZGVyc2AgaXMgYWxzbyBzZXQsIHRoZXNlIHZhbHVlcyB0YWtlIHByZWNlZGVuY2UgZm9yIGR1cGxpY2F0ZSBrZXlzLlxuICAgKi9cbiAgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIHtAbGluayBGZXRjaEluaXRPcHRpb25zfSBtZXJnZWQgaW50byBlYWNoIGBmZXRjaGAgY2FsbCAoZS5nLiBQT1NUIGBtZXRob2RgIGFuZCBKU09OIGBib2R5YCkuXG4gICAqIFRoZSBzYW1lIGBpbml0YCBpcyByZXVzZWQgYWNyb3NzIHJldHJpZXMuXG4gICAqL1xuICBpbml0PzogRmV0Y2hJbml0T3B0aW9ucztcbiAgLyoqIE1heGltdW0gbnVtYmVyIG9mIGF0dGVtcHRzLCBpbmNsdWRpbmcgdGhlIGZpcnN0LiAqL1xuICByZXRyaWVzOiBudW1iZXI7XG4gIC8qKiBQZXItYXR0ZW1wdCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kczsgdXNlcyBhbiBpbnRlcm5hbCB7QGxpbmsgQWJvcnRDb250cm9sbGVyfSB3aGVuIGV4Y2VlZGVkLiAqL1xuICB0aW1lb3V0TXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIEJhc2UgYmFja29mZiBpbiBtaWxsaXNlY29uZHMgZm9yIGZ1bGwgaml0dGVyLiBUaGUgY2FwIGZvciBhdHRlbXB0IGBuYCBpcyBgYmFzZUJhY2tvZmZNcyAqIDJebmAuXG4gICAqL1xuICBiYXNlQmFja29mZk1zOiBudW1iZXI7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBleHRlcm5hbCB7QGxpbmsgQWJvcnRTaWduYWx9LiBXaGVuIGFib3J0ZWQsIHRoZSBpbi1mbGlnaHQgcmVxdWVzdCBpcyBhYm9ydGVkOyBvbiB0aGVcbiAgICogZmluYWwgYXR0ZW1wdCwgY2FuY2VsbGF0aW9uIHN1cmZhY2VzIGFzIHtAbGluayBGZXRjaFJldHJpZXJBYm9ydEVycm9yfS5cbiAgICovXG4gIHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICAvKipcbiAgICogSW52b2tlZCBhZnRlciBgcmVzcG9uc2UudGV4dCgpYCB3aGVuIGByZXNwb25zZS5va2AgaXMgZmFsc2UuXG4gICAqIFJldHVybiBgdHJ1ZWAgdG8gc2NoZWR1bGUgYW5vdGhlciBhdHRlbXB0ICh1bnRpbCBgcmV0cmllc2AgaXMgZXhoYXVzdGVkKS5cbiAgICogRGVmYXVsdDogcmV0cnkgb24gc3RhdHVzIDQyOSwgNTAwLCA1MDIsIDUwMywgb3IgNTA0LlxuICAgKlxuICAgKiBAcGFyYW0gcmVzcG9uc2UgLSBOb24tT0sgcmVzcG9uc2UgZnJvbSB0aGUgY3VycmVudCBhdHRlbXB0XG4gICAqIEBwYXJhbSBib2R5IC0gUmVzcG9uc2UgYm9keSB0ZXh0IGZyb20gYHJlc3BvbnNlLnRleHQoKWBcbiAgICovXG4gIHNob3VsZFJldHJ5PzogKHJlc3BvbnNlOiBSZXNwb25zZSwgYm9keTogc3RyaW5nKSA9PiBib29sZWFuO1xufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIGEgcmVxdWVzdCBpcyBjYW5jZWxsZWQgYnkgdGltZW91dCBvciBhbiBleHRlcm5hbCB7QGxpbmsgQWJvcnRTaWduYWx9LlxuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllckFib3J0RXJyb3InO1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBIdW1hbi1yZWFkYWJsZSByZWFzb24gKGRlZmF1bHQ6IGAnQWJvcnRlZCdgKVxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdBYm9ydGVkJykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBGZXRjaFJldHJpZXJBYm9ydEVycm9yLnByb3RvdHlwZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiB7QGxpbmsgUmVxdWVzdE9wdGlvbnMuc2lnbmFsfSBpcyBhbHJlYWR5IGFib3J0ZWQgYmVmb3JlIGFuIGF0dGVtcHQgc3RhcnRzLlxuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvciBleHRlbmRzIEZldGNoUmV0cmllckFib3J0RXJyb3Ige1xuICBvdmVycmlkZSByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvcic7XG4gIC8qKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIEh1bWFuLXJlYWRhYmxlIHJlYXNvbiAoZGVmYXVsdDogYCdTaWduYWwgd2FzIGFscmVhZHkgYWJvcnRlZCdgKVxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdTaWduYWwgd2FzIGFscmVhZHkgYWJvcnRlZCcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4gdGhlIHNlcnZlciByZXR1cm5zIGEgbm9uLU9LIEhUVFAgc3RhdHVzIGFuZCBubyBmdXJ0aGVyIHJldHJ5IGlzIHBlcmZvcm1lZC5cbiAqXG4gKiBAcHJvcGVydHkgc3RhdHVzIC0gSFRUUCBzdGF0dXMgY29kZSBmcm9tIHRoZSBsYXN0IG5vbi1PSyByZXNwb25zZVxuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVySHR0cEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBvdmVycmlkZSByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnRmV0Y2hSZXRyaWVySHR0cEVycm9yJztcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gRXJyb3IgZGVzY3JpcHRpb25cbiAgICogQHBhcmFtIHN0YXR1cyAtIEhUVFAgc3RhdHVzIGNvZGUgZnJvbSB0aGUgbGFzdCBub24tT0sgcmVzcG9uc2VcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIG1lc3NhZ2U6IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgc3RhdHVzOiBudW1iZXIsXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBGZXRjaFJldHJpZXJIdHRwRXJyb3IucHJvdG90eXBlKTtcbiAgfVxufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIGEgZmV0Y2ggZmFpbHMgd2l0aCBhIG5ldHdvcmstbGV2ZWwgZXJyb3IgKGUuZy4gRE5TIGZhaWx1cmUsIGNvbm5lY3Rpb24gcmVmdXNlZCkuXG4gKlxuICogQHByb3BlcnR5IGNhdXNlIC0gT3JpZ2luYWwgZXJyb3IgZnJvbSB0aGUgdW5kZXJseWluZyBgZmV0Y2hgLCB3aGVuIGF2YWlsYWJsZVxuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVyTmV0d29ya0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBvdmVycmlkZSByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnRmV0Y2hSZXRyaWVyTmV0d29ya0Vycm9yJztcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gSHVtYW4tcmVhZGFibGUgcmVhc29uIChkZWZhdWx0OiBgJ05ldHdvcmsgZXJyb3InYClcbiAgICogQHBhcmFtIGNhdXNlIC0gT3JpZ2luYWwgZXJyb3IgZnJvbSB0aGUgdW5kZXJseWluZyBgZmV0Y2hgLCB3aGVuIGF2YWlsYWJsZVxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdOZXR3b3JrIGVycm9yJywgcHVibGljIHJlYWRvbmx5IGNhdXNlPzogdW5rbm93bikge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBGZXRjaFJldHJpZXJOZXR3b3JrRXJyb3IucHJvdG90eXBlKTtcbiAgfVxufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIGFuIGludGVybmFsIGludmFyaWFudCBmYWlscyAoc2hvdWxkIG5vdCBoYXBwZW4gaW4gbm9ybWFsIHVzZSkuXG4gKi9cbmV4cG9ydCBjbGFzcyBGZXRjaFJldHJpZXJVbnJlYWNoYWJsZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBvdmVycmlkZSByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnRmV0Y2hSZXRyaWVyVW5yZWFjaGFibGVFcnJvcic7XG4gIC8qKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIEh1bWFuLXJlYWRhYmxlIHJlYXNvbiAoZGVmYXVsdDogYCdVbnJlYWNoYWJsZSdgKVxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdVbnJlYWNoYWJsZScpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVyVW5yZWFjaGFibGVFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogRGVmYXVsdCB7QGxpbmsgUmVxdWVzdE9wdGlvbnMuc2hvdWxkUmV0cnl9OiByZXRyeSBvbiBIVFRQIDQyOSwgNTAwLCA1MDIsIDUwMywgb3IgNTA0LlxuICpcbiAqIEBwYXJhbSByZXMgLSBSZXNwb25zZSBmcm9tIHRoZSBmYWlsZWQgYXR0ZW1wdFxuICogQHJldHVybnMgYHRydWVgIHdoZW4gYW5vdGhlciBhdHRlbXB0IHNob3VsZCBiZSBzY2hlZHVsZWRcbiAqL1xuY29uc3QgZGVmYXVsdFNob3VsZFJldHJ5ID0gKHJlczogUmVzcG9uc2UpOiBib29sZWFuID0+IHtcbiAgcmV0dXJuIFs0MjksIDUwMCwgNTAyLCA1MDMsIDUwNF0uaW5jbHVkZXMocmVzLnN0YXR1cyk7XG59O1xuXG4vKipcbiAqIFdyYXBzIGBmZXRjaGAgd2l0aCByZXRyaWVzLCBwZXItYXR0ZW1wdCB0aW1lb3V0LCBmdWxsLWppdHRlciBiYWNrb2ZmLCBhbmQgb3B0aW9uYWwgY2FuY2VsbGF0aW9uLlxuICpcbiAqIEVhY2ggYXR0ZW1wdCBjYWxscyBgZmV0Y2godXJsLCB7IC4uLm9wdGlvbnMuaW5pdCwgaGVhZGVycz8sIHNpZ25hbCB9KWAgd2l0aCBhbiBpbnRlcm5hbFxuICoge0BsaW5rIEFib3J0U2lnbmFsfSBmb3IgYHRpbWVvdXRNc2AuIE5vbi1PSyByZXNwb25zZXMgYXJlIHJldHJpZWQgd2hlbiBgc2hvdWxkUmV0cnlgIHJldHVybnNcbiAqIGB0cnVlYCAoZGVmYXVsdDogNDI5IGFuZCA1eHgpLiBUaGUgc2FtZSB7QGxpbmsgRmV0Y2hJbml0T3B0aW9uc30gKGluY2x1ZGluZyBgYm9keWApIGlzIHJldXNlZFxuICogb24gZXZlcnkgYXR0ZW1wdC5cbiAqXG4gKiBAcGFyYW0gdXJsIC0gUmVxdWVzdCBVUkwgcGFzc2VkIHRvIGBmZXRjaGBcbiAqIEBwYXJhbSBvcHRpb25zIC0ge0BsaW5rIFJlcXVlc3RPcHRpb25zfSBjb250cm9sbGluZyByZXRyaWVzLCB0aW1lb3V0LCByZXF1ZXN0IGluaXQsIGFuZCBjYW5jZWxsYXRpb25cbiAqIEByZXR1cm5zIFRoZSBmaXJzdCB7QGxpbmsgUmVzcG9uc2V9IGZvciB3aGljaCBgb2tgIGlzIGB0cnVlYFxuICogQHRocm93cyB7RmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvcn0gSWYgYG9wdGlvbnMuc2lnbmFsYCBpcyBhbHJlYWR5IGFib3J0ZWQgYmVmb3JlIGFuIGF0dGVtcHRcbiAqIEB0aHJvd3Mge0ZldGNoUmV0cmllckh0dHBFcnJvcn0gT24gYSBub24tT0sgcmVzcG9uc2UgdGhhdCBpcyBub3QgcmV0cmllZCBvciBhZnRlciB0aGUgbGFzdCBhdHRlbXB0XG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJOZXR3b3JrRXJyb3J9IE9uIGEgbmV0d29yayBgVHlwZUVycm9yYCBhZnRlciB0aGUgbGFzdCBhdHRlbXB0XG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJBYm9ydEVycm9yfSBPbiB0aW1lb3V0IG9yIGV4dGVybmFsIGFib3J0IGFmdGVyIHRoZSBsYXN0IGF0dGVtcHRcbiAqIEB0aHJvd3Mge0ZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3J9IElmIHRoZSByZXRyeSBsb29wIGV4aXRzIHdpdGhvdXQgcmV0dXJuaW5nIChpbnRlcm5hbCBidWcpXG4gKi9cbmV4cG9ydCBjb25zdCBmZXRjaFJldHJpZXIgPSBhc3luYyAodXJsOiBzdHJpbmcsIG9wdGlvbnM6IFJlcXVlc3RPcHRpb25zKTogUHJvbWlzZTxSZXNwb25zZT4gPT4ge1xuICBjb25zdCB7XG4gICAgaGVhZGVycyxcbiAgICBpbml0LFxuICAgIHJldHJpZXMsXG4gICAgdGltZW91dE1zLFxuICAgIGJhc2VCYWNrb2ZmTXMsXG4gICAgc2lnbmFsOiBleHRlcm5hbFNpZ25hbCxcbiAgICBzaG91bGRSZXRyeSA9IGRlZmF1bHRTaG91bGRSZXRyeSxcbiAgfSA9IG9wdGlvbnM7XG5cbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IGF0dGVtcHQgPD0gcmV0cmllczsgYXR0ZW1wdCsrKSB7XG4gICAgaWYgKGV4dGVybmFsU2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvcigpO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IGNvbnRyb2xsZXIuYWJvcnQoKSwgdGltZW91dE1zKTtcblxuICAgIGNvbnN0IG9uRXh0ZXJuYWxBYm9ydCA9ICgpOiB2b2lkID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICBjb250cm9sbGVyLmFib3J0KCk7XG4gICAgfTtcblxuICAgIGlmIChleHRlcm5hbFNpZ25hbCkge1xuICAgICAgZXh0ZXJuYWxTaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkV4dGVybmFsQWJvcnQpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICAgICAgLi4uaW5pdCxcbiAgICAgICAgLi4uKGhlYWRlcnMgIT09IHVuZGVmaW5lZCA/IHsgaGVhZGVycyB9IDoge30pLFxuICAgICAgICBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgfSk7XG5cbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICBleHRlcm5hbFNpZ25hbD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkV4dGVybmFsQWJvcnQpO1xuXG4gICAgICBpZiAocmVzLm9rKSB7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZXMudGV4dCgpO1xuICAgICAgY29uc3QgaXNDb250aW51ZSA9IHNob3VsZFJldHJ5KHJlcywgdGV4dCk7XG5cbiAgICAgIGlmIChpc0NvbnRpbnVlKSB7XG4gICAgICAgIGlmIChhdHRlbXB0ID09PSByZXRyaWVzKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZldGNoUmV0cmllckh0dHBFcnJvcihgSFRUUCAke3Jlcy5zdGF0dXN9YCwgcmVzLnN0YXR1cyk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgd2FpdChmdWxsSml0dGVyKGJhc2VCYWNrb2ZmTXMsIGF0dGVtcHQpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBGZXRjaFJldHJpZXJIdHRwRXJyb3IoYE5vbi1yZXRyaWFibGUgSFRUUCBlcnJvcjogJHtyZXMuc3RhdHVzfWAsIHJlcy5zdGF0dXMpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIGV4dGVybmFsU2lnbmFsPy5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uRXh0ZXJuYWxBYm9ydCk7XG5cbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnIubmFtZSA9PT0gJ0Fib3J0RXJyb3InKSB7XG4gICAgICAgIGlmIChhdHRlbXB0ID09PSByZXRyaWVzKSB0aHJvdyBlcnIgaW5zdGFuY2VvZiBGZXRjaFJldHJpZXJBYm9ydEVycm9yID8gZXJyIDogbmV3IEZldGNoUmV0cmllckFib3J0RXJyb3IoKTtcbiAgICAgICAgYXdhaXQgd2FpdChmdWxsSml0dGVyKGJhc2VCYWNrb2ZmTXMsIGF0dGVtcHQpKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBUeXBlRXJyb3IpIHtcbiAgICAgICAgaWYgKGF0dGVtcHQgPT09IHJldHJpZXMpIHRocm93IG5ldyBGZXRjaFJldHJpZXJOZXR3b3JrRXJyb3IoJ05ldHdvcmsgZXJyb3InLCBlcnIpO1xuICAgICAgICBhd2FpdCB3YWl0KGZ1bGxKaXR0ZXIoYmFzZUJhY2tvZmZNcywgYXR0ZW1wdCkpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBGZXRjaFJldHJpZXJVbnJlYWNoYWJsZUVycm9yKCk7XG59O1xuXG4vKipcbiAqIERlbGF5cyBleGVjdXRpb24gZm9yIHRoZSBnaXZlbiBkdXJhdGlvbiAodXNlZCBiZXR3ZWVuIHJldHJ5IGF0dGVtcHRzKS5cbiAqXG4gKiBAcGFyYW0gbXMgLSBEZWxheSBpbiBtaWxsaXNlY29uZHNcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIGBtc2BcbiAqL1xuY29uc3Qgd2FpdCA9IChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xufTtcblxuLyoqXG4gKiBGdWxsIGppdHRlciBiYWNrb2ZmOiByYW5kb20gZGVsYXkgaW4gYFswLCBiYXNlICogMl5hdHRlbXB0KWAgbXMgKEFXUy1yZWNvbW1lbmRlZCBwYXR0ZXJuKS5cbiAqXG4gKiBAcGFyYW0gYmFzZSAtIEJhc2UgYmFja29mZiBpbiBtaWxsaXNlY29uZHNcbiAqIEBwYXJhbSBhdHRlbXB0IC0gMS1iYXNlZCBhdHRlbXB0IGluZGV4IChmaXJzdCByZXRyeSB1c2VzIGBhdHRlbXB0ID09PSAxYClcbiAqIEByZXR1cm5zIFdhaXQgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzIGJlZm9yZSB0aGUgbmV4dCBhdHRlbXB0XG4gKi9cbmNvbnN0IGZ1bGxKaXR0ZXIgPSAoYmFzZTogbnVtYmVyLCBhdHRlbXB0OiBudW1iZXIpOiBudW1iZXIgPT4ge1xuICBjb25zdCBjYXAgPSBiYXNlICogTWF0aC5wb3coMiwgYXR0ZW1wdCk7XG4gIHJldHVybiBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBjYXApO1xufTtcbiJdfQ==
package/package.json CHANGED
@@ -42,7 +42,7 @@
42
42
  "eslint-plugin-import": "^2.32.0",
43
43
  "jest": "^30.4.2",
44
44
  "jest-junit": "^17",
45
- "projen": "^0.99.58",
45
+ "projen": "^0.99.61",
46
46
  "ts-jest": "^29.4.9",
47
47
  "ts-node": "^10.9.2",
48
48
  "typescript": "5.9.x"
@@ -55,7 +55,7 @@
55
55
  "publishConfig": {
56
56
  "access": "public"
57
57
  },
58
- "version": "0.2.9",
58
+ "version": "0.3.0",
59
59
  "jest": {
60
60
  "coverageProvider": "v8",
61
61
  "testMatch": [