fetch-retrier 0.4.4 → 0.5.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.
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "dev-fetch-retrier",
3
- "image": "mcr.microsoft.com/devcontainers/base:bookworm",
3
+ "image": "mcr.microsoft.com/devcontainers/base:trixie",
4
4
  "features": {
5
5
  "ghcr.io/devcontainers/features/common-utils:2": {
6
6
  "username": "developer",
7
7
  "upgradePackages": true
8
8
  },
9
9
  "ghcr.io/devcontainers/features/git:1": {},
10
- "ghcr.io/devcontainers/features/node:1": {
11
- "version": "24"
10
+ "ghcr.io/devcontainers/features/node:2": {
11
+ "version": "24",
12
+ "npmVersion": "12"
12
13
  }
13
14
  },
14
15
  "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind",
package/README.md CHANGED
@@ -1,24 +1,25 @@
1
1
  # Fetch Retrier
2
2
 
3
- A lightweight wrapper around `fetch` that adds **retries**, **per-attempt timeout**, **full jitter** backoff, and **option validation**. Pass standard `RequestInit` options (`method`, `body`, `credentials`, and more) for POST/PUT APIs and other HTTP calls that may be rate-limited or temporarily unavailable.
4
-
5
3
  [![npm version](https://img.shields.io/npm/v/fetch-retrier.svg)](https://www.npmjs.com/package/fetch-retrier)
6
4
  [![npm downloads](https://img.shields.io/npm/dm/fetch-retrier.svg)](https://www.npmjs.com/package/fetch-retrier)
7
5
  [![build](https://github.com/gammarers-labs/fetch-retrier/actions/workflows/build.yml/badge.svg)](https://github.com/gammarers-labs/fetch-retrier/actions/workflows/build.yml)
8
6
  [![release](https://github.com/gammarers-labs/fetch-retrier/actions/workflows/release.yml/badge.svg)](https://github.com/gammarers-labs/fetch-retrier/actions/workflows/release.yml)
9
7
 
8
+ A lightweight wrapper around `fetch` that adds **retries**, **per-attempt timeout**, **Retry-After** support, **full jitter** backoff, and **option validation**. Pass standard `RequestInit` options (`method`, `body`, `credentials`, and more) for POST/PUT APIs and other HTTP calls that may be rate-limited or temporarily unavailable.
9
+
10
10
  ## Features
11
11
 
12
12
  - **Configurable retries** – Set the maximum number of attempts per request (`retries >= 1`).
13
13
  - **Per-attempt timeout** – Abort each attempt when it exceeds a given duration (`timeoutMs > 0`).
14
- - **Full jitter backoff** – Exponential backoff with random jitter (AWS-style) between retries (`baseBackoffMs >= 0`).
14
+ - **Retry-After support** – On HTTP retries, prefers a valid `Retry-After` header (delta-seconds or HTTP-date); falls back to full jitter when absent or invalid.
15
+ - **Full jitter backoff** – Exponential backoff with random jitter (AWS-style) for abort/network retries and as the HTTP fallback (`baseBackoffMs >= 0`).
15
16
  - **Option validation** – Invalid numeric options throw `FetchRetrierInvalidOptionsError` at call time.
16
17
  - **RequestInit forwarding** – Pass `method`, `body`, `credentials`, `redirect`, and other `fetch` options via `init` on every attempt.
17
18
  - **Header shorthand** – Optional top-level `headers` override `init.headers` when both are set.
18
19
  - **Default retry policy** – Retries transient HTTP statuses (408, 425, 429, 500, 502, 503, 504) via `defaultShouldRetry` and `DEFAULT_RETRYABLE_HTTP_STATUSES`.
19
- - **Extensible retry predicate** – Compose `defaultShouldRetry` with custom `shouldRetry` logic.
20
+ - **Extensible retry predicate** – Compose `defaultShouldRetry` with custom `shouldRetry` logic (receives response body text).
20
21
  - **External cancellation** – Pass an `AbortSignal` to cancel in-flight requests.
21
- - **Typed errors** – `FetchRetrierHttpError`, `FetchRetrierNetworkError`, `FetchRetrierAbortError`, `FetchRetrierInvalidOptionsError`, and related classes.
22
+ - **Typed errors** – `FetchRetrierHttpError` (with `status` and `body`), `FetchRetrierNetworkError`, `FetchRetrierAbortError`, `FetchRetrierInvalidOptionsError`, and related classes.
22
23
  - **TypeScript** – Exported types including `RequestOptions` and `FetchInitOptions`.
23
24
 
24
25
  ## Installation
@@ -52,10 +53,7 @@ const options: RequestOptions = {
52
53
  };
53
54
 
54
55
  const response = await fetchRetrier('https://api.example.com/data', options);
55
-
56
- if (response.ok) {
57
- const data = await response.json();
58
- }
56
+ const data = await response.json();
59
57
  ```
60
58
 
61
59
  ### POST with JSON body (`init`)
@@ -82,7 +80,7 @@ The same `init` (including `body`) is applied on every retry attempt. Per-attemp
82
80
 
83
81
  ### Custom retry logic
84
82
 
85
- Extend the default predicate instead of reimplementing the status list:
83
+ `shouldRetry` runs only when `response.ok` is false, after `response.text()`. Extend the default predicate instead of reimplementing the status list:
86
84
 
87
85
  ```typescript
88
86
  import {
@@ -97,7 +95,8 @@ const response = await fetchRetrier('https://api.example.com/data', {
97
95
  baseBackoffMs: 500,
98
96
  shouldRetry: (res, body) => {
99
97
  if (defaultShouldRetry(res, body)) return true;
100
- if (res.status === 200 && body.includes('"retry": true')) return true;
98
+ if (res.status === 418) return true;
99
+ if (body.includes('"retryable":true')) return true;
101
100
  return false;
102
101
  },
103
102
  });
@@ -105,6 +104,27 @@ const response = await fetchRetrier('https://api.example.com/data', {
105
104
  // DEFAULT_RETRYABLE_HTTP_STATUSES is [408, 425, 429, 500, 502, 503, 504]
106
105
  ```
107
106
 
107
+ ### Handling HTTP errors
108
+
109
+ On a non-OK response that is not retried (or after retries are exhausted), `FetchRetrierHttpError` includes both `status` and the already-read `body`:
110
+
111
+ ```typescript
112
+ import { fetchRetrier, FetchRetrierHttpError } from 'fetch-retrier';
113
+
114
+ try {
115
+ await fetchRetrier('https://api.example.com/data', {
116
+ retries: 3,
117
+ timeoutMs: 5000,
118
+ baseBackoffMs: 1000,
119
+ });
120
+ } catch (err) {
121
+ if (err instanceof FetchRetrierHttpError) {
122
+ console.error(err.status, err.body);
123
+ }
124
+ throw err;
125
+ }
126
+ ```
127
+
108
128
  ### Cancellation with `AbortController`
109
129
 
110
130
  ```typescript
@@ -124,10 +144,10 @@ await fetchRetrier('https://api.example.com/data', {
124
144
 
125
145
  - **Success** – If `response.ok` is true, the response is returned immediately.
126
146
  - **Invalid options** – If `retries < 1`, `timeoutMs <= 0`, or `baseBackoffMs < 0`, `FetchRetrierInvalidOptionsError` is thrown before any request is made.
127
- - **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`).
128
- - **Non-retriable failure** – If `shouldRetry` returns false, `FetchRetrierHttpError` is thrown immediately (e.g. `Non-retriable HTTP error: 404`).
129
- - **Timeout** – If a request exceeds `timeoutMs`, it is aborted and retried until `retries` is exhausted; the final failure is `FetchRetrierAbortError`.
130
- - **Network / TypeError** – Network errors are retried with backoff; after the last attempt, `FetchRetrierNetworkError` is thrown with the original error as `cause`.
147
+ - **Retriable failure** – If the response is not OK and `shouldRetry(response, body)` returns true, the client waits and retries until `retries` is exhausted. Wait prefers a valid `Retry-After` header (delta-seconds or HTTP-date); otherwise uses full jitter. On the last attempt, `FetchRetrierHttpError` is thrown (includes `status` and `body`).
148
+ - **Non-retriable failure** – If `shouldRetry` returns false, `FetchRetrierHttpError` is thrown immediately with `status` and `body` (e.g. `Non-retriable HTTP error: 404`).
149
+ - **Timeout** – If a request exceeds `timeoutMs`, it is aborted and retried with full jitter until `retries` is exhausted; the final failure is `FetchRetrierAbortError`.
150
+ - **Network / TypeError** – Network errors are retried with full jitter; after the last attempt, `FetchRetrierNetworkError` is thrown with the original error as `cause`.
131
151
  - **Already aborted signal** – If `signal` is already aborted before an attempt starts, `FetchRetrierAlreadyAbortedError` is thrown (no attempt is made).
132
152
 
133
153
  ## Options
@@ -136,7 +156,7 @@ await fetchRetrier('https://api.example.com/data', {
136
156
  |--------|------|----------|-------------|
137
157
  | `retries` | `number` | Yes | Maximum number of attempts (including the first request). Must be `>= 1`. |
138
158
  | `timeoutMs` | `number` | Yes | Timeout in milliseconds for each attempt. Exceeded attempts are aborted and retried. Must be `> 0`. |
139
- | `baseBackoffMs` | `number` | Yes | Base delay in milliseconds for backoff. Delay is capped at `baseBackoffMs * 2^attempt` and randomized (full jitter). Must be `>= 0` (`0` skips backoff delay). |
159
+ | `baseBackoffMs` | `number` | Yes | Base delay in milliseconds for full jitter when `Retry-After` is absent or invalid (also used for abort/network retries). Cap is `baseBackoffMs * 2^attempt`, randomized. Must be `>= 0` (`0` skips backoff delay when falling back). |
140
160
  | `init` | `FetchInitOptions` | No | `fetch` options forwarded to every attempt: `method`, `body`, `credentials`, `redirect`, `mode`, `cache`, etc. `signal` is reserved for internal timeout and cancellation. |
141
161
  | `headers` | `Record<string, string>` | No | Headers sent on every attempt. Overrides `init.headers` when both are set. |
142
162
  | `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. |
@@ -148,6 +168,7 @@ await fetchRetrier('https://api.example.com/data', {
148
168
  |--------|-------------|
149
169
  | `defaultShouldRetry` | Default `shouldRetry` predicate; compose with custom logic. |
150
170
  | `DEFAULT_RETRYABLE_HTTP_STATUSES` | Readonly list of HTTP status codes retried by default. |
171
+ | `parseRetryAfterMs` | Parses a `Retry-After` header (delta-seconds or HTTP-date) into a delay in milliseconds. |
151
172
 
152
173
  ## Requirements
153
174
 
package/lib/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Retry-enabled `fetch` wrapper with per-attempt timeout, full-jitter backoff, option validation, and typed errors.
2
+ * Retry-enabled `fetch` wrapper with per-attempt timeout, Retry-After support, full-jitter backoff,
3
+ * option validation, and typed errors.
3
4
  *
4
5
  * @module fetch-retrier
5
6
  */
@@ -12,7 +13,8 @@
12
13
  */
13
14
  export type FetchInitOptions = Omit<RequestInit, 'signal'>;
14
15
  /**
15
- * Options for {@link fetchRetrier}: retry policy, timeout, backoff, request payload, and cancellation.
16
+ * Options for {@link fetchRetrier}: retry policy, timeout, backoff (including `Retry-After`),
17
+ * request payload, and cancellation.
16
18
  *
17
19
  * Request shape is built as `{ ...init, headers?, signal }` on each attempt. Top-level `headers`
18
20
  * override `init.headers` when both are provided.
@@ -42,8 +44,9 @@ export interface RequestOptions {
42
44
  */
43
45
  timeoutMs: number;
44
46
  /**
45
- * Base backoff in milliseconds for full jitter. The cap for attempt `n` is `baseBackoffMs * 2^n`.
46
- * Must be `>= 0` (`0` skips backoff delay between attempts).
47
+ * Base backoff in milliseconds for full jitter when `Retry-After` is absent or invalid.
48
+ * The cap for attempt `n` is `baseBackoffMs * 2^n`.
49
+ * Must be `>= 0` (`0` skips backoff delay between attempts when falling back to jitter).
47
50
  */
48
51
  baseBackoffMs: number;
49
52
  /**
@@ -85,16 +88,22 @@ export declare class FetchRetrierAlreadyAbortedError extends FetchRetrierAbortEr
85
88
  /**
86
89
  * Error thrown when the server returns a non-OK HTTP status and no further retry is performed.
87
90
  *
91
+ * Carries the last response `status` and the body text already consumed via `response.text()`
92
+ * (the same text passed to {@link RequestOptions.shouldRetry}).
93
+ *
88
94
  * @property status - HTTP status code from the last non-OK response
95
+ * @property body - Response body text already read via `response.text()` for that attempt
89
96
  */
90
97
  export declare class FetchRetrierHttpError extends Error {
91
98
  readonly status: number;
99
+ readonly body: string;
92
100
  readonly name: string;
93
101
  /**
94
102
  * @param message - Error description
95
103
  * @param status - HTTP status code from the last non-OK response
104
+ * @param body - Response body text already read via `response.text()` for that attempt
96
105
  */
97
- constructor(message: string, status: number);
106
+ constructor(message: string, status: number, body: string);
98
107
  }
99
108
  /**
100
109
  * Error thrown when a fetch fails with a network-level error (e.g. DNS failure, connection refused).
@@ -153,12 +162,15 @@ export declare const DEFAULT_RETRYABLE_HTTP_STATUSES: readonly number[];
153
162
  */
154
163
  export declare const defaultShouldRetry: (response: Response, _body: string) => boolean;
155
164
  /**
156
- * Wraps `fetch` with retries, per-attempt timeout, full-jitter backoff, and optional cancellation.
165
+ * Wraps `fetch` with retries, per-attempt timeout, Retry-After support, full-jitter backoff, and
166
+ * optional cancellation.
157
167
  *
158
168
  * Each attempt calls `fetch(url, { ...options.init, headers?, signal })` with an internal
159
169
  * {@link AbortSignal} for `timeoutMs`. Non-OK responses are retried when `shouldRetry` returns
160
- * `true` (default: {@link DEFAULT_RETRYABLE_HTTP_STATUSES}). The same {@link FetchInitOptions} (including `body`) is reused
161
- * on every attempt.
170
+ * `true` (default: {@link defaultShouldRetry}). Between HTTP retries, a valid `Retry-After`
171
+ * header (delta-seconds or HTTP-date) is preferred over full jitter; abort and network retries
172
+ * always use full jitter. The same {@link FetchInitOptions} (including `body`) is reused on
173
+ * every attempt.
162
174
  *
163
175
  * @param url - Request URL passed to `fetch`
164
176
  * @param options - {@link RequestOptions} controlling retries, timeout, request init, and cancellation
@@ -166,8 +178,21 @@ export declare const defaultShouldRetry: (response: Response, _body: string) =>
166
178
  * @throws {FetchRetrierInvalidOptionsError} If `retries < 1`, `timeoutMs <= 0`, or `baseBackoffMs < 0`
167
179
  * @throws {FetchRetrierAlreadyAbortedError} If `options.signal` is already aborted before an attempt
168
180
  * @throws {FetchRetrierHttpError} On a non-OK response that is not retried or after the last attempt
181
+ * (includes `status` and `body`)
169
182
  * @throws {FetchRetrierNetworkError} On a network `TypeError` after the last attempt
170
183
  * @throws {FetchRetrierAbortError} On timeout or external abort after the last attempt
171
184
  * @throws {FetchRetrierUnreachableError} If the retry loop exits without returning (internal bug)
172
185
  */
173
186
  export declare const fetchRetrier: (url: string, options: RequestOptions) => Promise<Response>;
187
+ /**
188
+ * Parses a `Retry-After` header value into a delay in milliseconds.
189
+ *
190
+ * Supports RFC 7231 forms: non-negative integer delta-seconds, or an HTTP-date. Empty values,
191
+ * non-integer numerics (e.g. floats or negatives), and unparsable dates yield `undefined` so
192
+ * callers can fall back to full jitter. An HTTP-date in the past yields `0`.
193
+ *
194
+ * @param value - Raw `Retry-After` header value
195
+ * @param nowMs - Current time in milliseconds (injectable for tests)
196
+ * @returns Delay in milliseconds, or `undefined` when the value cannot be parsed
197
+ */
198
+ export declare const parseRetryAfterMs: (value: string, nowMs?: number) => number | undefined;
package/lib/index.js CHANGED
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  /**
3
- * Retry-enabled `fetch` wrapper with per-attempt timeout, full-jitter backoff, option validation, and typed errors.
3
+ * Retry-enabled `fetch` wrapper with per-attempt timeout, Retry-After support, full-jitter backoff,
4
+ * option validation, and typed errors.
4
5
  *
5
6
  * @module fetch-retrier
6
7
  */
7
8
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.fetchRetrier = exports.defaultShouldRetry = exports.DEFAULT_RETRYABLE_HTTP_STATUSES = exports.FetchRetrierUnreachableError = exports.FetchRetrierInvalidOptionsError = exports.FetchRetrierNetworkError = exports.FetchRetrierHttpError = exports.FetchRetrierAlreadyAbortedError = exports.FetchRetrierAbortError = void 0;
9
+ exports.parseRetryAfterMs = exports.fetchRetrier = exports.defaultShouldRetry = exports.DEFAULT_RETRYABLE_HTTP_STATUSES = exports.FetchRetrierUnreachableError = exports.FetchRetrierInvalidOptionsError = exports.FetchRetrierNetworkError = exports.FetchRetrierHttpError = exports.FetchRetrierAlreadyAbortedError = exports.FetchRetrierAbortError = void 0;
9
10
  /**
10
11
  * Error thrown when a request is cancelled by timeout or an external {@link AbortSignal}.
11
12
  */
@@ -37,16 +38,22 @@ exports.FetchRetrierAlreadyAbortedError = FetchRetrierAlreadyAbortedError;
37
38
  /**
38
39
  * Error thrown when the server returns a non-OK HTTP status and no further retry is performed.
39
40
  *
41
+ * Carries the last response `status` and the body text already consumed via `response.text()`
42
+ * (the same text passed to {@link RequestOptions.shouldRetry}).
43
+ *
40
44
  * @property status - HTTP status code from the last non-OK response
45
+ * @property body - Response body text already read via `response.text()` for that attempt
41
46
  */
42
47
  class FetchRetrierHttpError extends Error {
43
48
  /**
44
49
  * @param message - Error description
45
50
  * @param status - HTTP status code from the last non-OK response
51
+ * @param body - Response body text already read via `response.text()` for that attempt
46
52
  */
47
- constructor(message, status) {
53
+ constructor(message, status, body) {
48
54
  super(message);
49
55
  this.status = status;
56
+ this.body = body;
50
57
  this.name = 'FetchRetrierHttpError';
51
58
  Object.setPrototypeOf(this, FetchRetrierHttpError.prototype);
52
59
  }
@@ -144,12 +151,15 @@ const validateRequestOptions = (options) => {
144
151
  }
145
152
  };
146
153
  /**
147
- * Wraps `fetch` with retries, per-attempt timeout, full-jitter backoff, and optional cancellation.
154
+ * Wraps `fetch` with retries, per-attempt timeout, Retry-After support, full-jitter backoff, and
155
+ * optional cancellation.
148
156
  *
149
157
  * Each attempt calls `fetch(url, { ...options.init, headers?, signal })` with an internal
150
158
  * {@link AbortSignal} for `timeoutMs`. Non-OK responses are retried when `shouldRetry` returns
151
- * `true` (default: {@link DEFAULT_RETRYABLE_HTTP_STATUSES}). The same {@link FetchInitOptions} (including `body`) is reused
152
- * on every attempt.
159
+ * `true` (default: {@link defaultShouldRetry}). Between HTTP retries, a valid `Retry-After`
160
+ * header (delta-seconds or HTTP-date) is preferred over full jitter; abort and network retries
161
+ * always use full jitter. The same {@link FetchInitOptions} (including `body`) is reused on
162
+ * every attempt.
153
163
  *
154
164
  * @param url - Request URL passed to `fetch`
155
165
  * @param options - {@link RequestOptions} controlling retries, timeout, request init, and cancellation
@@ -157,6 +167,7 @@ const validateRequestOptions = (options) => {
157
167
  * @throws {FetchRetrierInvalidOptionsError} If `retries < 1`, `timeoutMs <= 0`, or `baseBackoffMs < 0`
158
168
  * @throws {FetchRetrierAlreadyAbortedError} If `options.signal` is already aborted before an attempt
159
169
  * @throws {FetchRetrierHttpError} On a non-OK response that is not retried or after the last attempt
170
+ * (includes `status` and `body`)
160
171
  * @throws {FetchRetrierNetworkError} On a network `TypeError` after the last attempt
161
172
  * @throws {FetchRetrierAbortError} On timeout or external abort after the last attempt
162
173
  * @throws {FetchRetrierUnreachableError} If the retry loop exits without returning (internal bug)
@@ -192,12 +203,12 @@ const fetchRetrier = async (url, options) => {
192
203
  const isContinue = shouldRetry(res, text);
193
204
  if (isContinue) {
194
205
  if (attempt === retries) {
195
- throw new FetchRetrierHttpError(`HTTP ${res.status}`, res.status);
206
+ throw new FetchRetrierHttpError(`HTTP ${res.status}`, res.status, text);
196
207
  }
197
- await wait(fullJitter(baseBackoffMs, attempt));
208
+ await wait(resolveRetryDelayMs(res, baseBackoffMs, attempt));
198
209
  }
199
210
  else {
200
- throw new FetchRetrierHttpError(`Non-retriable HTTP error: ${res.status}`, res.status);
211
+ throw new FetchRetrierHttpError(`Non-retriable HTTP error: ${res.status}`, res.status, text);
201
212
  }
202
213
  }
203
214
  catch (err) {
@@ -233,6 +244,9 @@ const wait = (ms) => {
233
244
  /**
234
245
  * Full jitter backoff: random delay in `[0, base * 2^attempt)` ms (AWS-recommended pattern).
235
246
  *
247
+ * Used between abort/network retries, and as the fallback when HTTP retries lack a usable
248
+ * `Retry-After` header.
249
+ *
236
250
  * @param base - Base backoff in milliseconds
237
251
  * @param attempt - 1-based attempt index (first retry uses `attempt === 1`)
238
252
  * @returns Wait duration in milliseconds before the next attempt
@@ -241,4 +255,58 @@ const fullJitter = (base, attempt) => {
241
255
  const cap = base * Math.pow(2, attempt);
242
256
  return Math.floor(Math.random() * cap);
243
257
  };
244
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7O0dBSUc7OztBQStESDs7R0FFRztBQUNILE1BQWEsc0JBQXVCLFNBQVEsS0FBSztJQUUvQzs7T0FFRztJQUNILFlBQVksT0FBTyxHQUFHLFNBQVM7UUFDN0IsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBTEMsU0FBSSxHQUFXLHdCQUF3QixDQUFDO1FBTXhELE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLHNCQUFzQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7Q0FDRjtBQVRELHdEQVNDO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLCtCQUFnQyxTQUFRLHNCQUFzQjtJQUV6RTs7T0FFRztJQUNILFlBQVksT0FBTyxHQUFHLDRCQUE0QjtRQUNoRCxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFMQyxTQUFJLEdBQVcsaUNBQWlDLENBQUM7UUFNakUsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsK0JBQStCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDekUsQ0FBQztDQUNGO0FBVEQsMEVBU0M7QUFFRDs7OztHQUlHO0FBQ0gsTUFBYSxxQkFBc0IsU0FBUSxLQUFLO0lBRTlDOzs7T0FHRztJQUNILFlBQ0UsT0FBZSxFQUNDLE1BQWM7UUFFOUIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRkMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQVBkLFNBQUksR0FBVyx1QkFBdUIsQ0FBQztRQVV2RCxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMvRCxDQUFDO0NBQ0Y7QUFiRCxzREFhQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFhLHdCQUF5QixTQUFRLEtBQUs7SUFFakQ7OztPQUdHO0lBQ0gsWUFBWSxPQUFPLEdBQUcsZUFBZSxFQUFr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QUFDLEVBQVUsRUFBaUIsRUFBRTtJQUN6QyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDM0QsQ0FBQyxDQUFDO0FBRUY7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLEdBQUcsQ0FBQyxJQUFZLEVBQUUsT0FBZSxFQUFVLEVBQUU7SUFDM0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3hDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDekMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSZXRyeS1lbmFibGVkIGBmZXRjaGAgd3JhcHBlciB3aXRoIHBlci1hdHRlbXB0IHRpbWVvdXQsIGZ1bGwtaml0dGVyIGJhY2tvZmYsIG9wdGlvbiB2YWxpZGF0aW9uLCBhbmQgdHlwZWQgZXJyb3JzLlxuICpcbiAqIEBtb2R1bGUgZmV0Y2gtcmV0cmllclxuICovXG5cbi8qKlxuICogYGZldGNoYCBvcHRpb25zIGZvcndhcmRlZCB0byBldmVyeSBhdHRlbXB0LCBleGNsdWRpbmcgYHNpZ25hbGAuXG4gKlxuICogVXNlIGZvciBgbWV0aG9kYCwgYGJvZHlgLCBgY3JlZGVudGlhbHNgLCBgcmVkaXJlY3RgLCBgbW9kZWAsIGBjYWNoZWAsIGFuZCBvdGhlclxuICoge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9SZXF1ZXN0SW5pdCB8IFJlcXVlc3RJbml0fSBmaWVsZHMuXG4gKiBQZXItYXR0ZW1wdCBhYm9ydCBhbmQgdGltZW91dCBhcmUgaGFuZGxlZCBpbnRlcm5hbGx5IHZpYSBgc2lnbmFsYCBhbmQgbXVzdCBub3QgYmUgc2V0IGhlcmUuXG4gKi9cbmV4cG9ydCB0eXBlIEZldGNoSW5pdE9wdGlvbnMgPSBPbWl0PFJlcXVlc3RJbml0LCAnc2lnbmFsJz47XG5cbi8qKlxuICogT3B0aW9ucyBmb3Ige0BsaW5rIGZldGNoUmV0cmllcn06IHJldHJ5IHBvbGljeSwgdGltZW91dCwgYmFja29mZiwgcmVxdWVzdCBwYXlsb2FkLCBhbmQgY2FuY2VsbGF0aW9uLlxuICpcbiAqIFJlcXVlc3Qgc2hhcGUgaXMgYnVpbHQgYXMgYHsgLi4uaW5pdCwgaGVhZGVycz8sIHNpZ25hbCB9YCBvbiBlYWNoIGF0dGVtcHQuIFRvcC1sZXZlbCBgaGVhZGVyc2BcbiAqIG92ZXJyaWRlIGBpbml0LmhlYWRlcnNgIHdoZW4gYm90aCBhcmUgcHJvdmlkZWQuXG4gKlxuICogTnVtZXJpYyBmaWVsZHMgYXJlIHZhbGlkYXRlZCB3aGVuIHtAbGluayBmZXRjaFJldHJpZXJ9IGlzIGNhbGxlZDsgaW52YWxpZCB2YWx1ZXMgdGhyb3dcbiAqIHtAbGluayBGZXRjaFJldHJpZXJJbnZhbGlkT3B0aW9uc0Vycm9yfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXF1ZXN0T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBIVFRQIGhlYWRlcnMgc2VudCBvbiBldmVyeSBhdHRlbXB0LlxuICAgKiBXaGVuIGBpbml0LmhlYWRlcnNgIGlzIGFsc28gc2V0LCB0aGVzZSB2YWx1ZXMgdGFrZSBwcmVjZWRlbmNlIGZvciBkdXBsaWNhdGUga2V5cy5cbiAgICovXG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICAvKipcbiAgICogQWRkaXRpb25hbCB7QGxpbmsgRmV0Y2hJbml0T3B0aW9uc30gbWVyZ2VkIGludG8gZWFjaCBgZmV0Y2hgIGNhbGwgKGUuZy4gUE9TVCBgbWV0aG9kYCBhbmQgSlNPTiBgYm9keWApLlxuICAgKiBUaGUgc2FtZSBgaW5pdGAgaXMgcmV1c2VkIGFjcm9zcyByZXRyaWVzLlxuICAgKi9cbiAgaW5pdD86IEZldGNoSW5pdE9wdGlvbnM7XG4gIC8qKlxuICAgKiBNYXhpbXVtIG51bWJlciBvZiBhdHRlbXB0cywgaW5jbHVkaW5nIHRoZSBmaXJzdC5cbiAgICogTXVzdCBiZSBgPj0gMWAuXG4gICAqL1xuICByZXRyaWVzOiBudW1iZXI7XG4gIC8qKlxuICAgKiBQZXItYXR0ZW1wdCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kczsgdXNlcyBhbiBpbnRlcm5hbCB7QGxpbmsgQWJvcnRDb250cm9sbGVyfSB3aGVuIGV4Y2VlZGVkLlxuICAgKiBNdXN0IGJlIGA+IDBgLlxuICAgKi9cbiAgdGltZW91dE1zOiBudW1iZXI7XG4gIC8qKlxuICAgKiBCYXNlIGJhY2tvZmYgaW4gbWlsbGlzZWNvbmRzIGZvciBmdWxsIGppdHRlci4gVGhlIGNhcCBmb3IgYXR0ZW1wdCBgbmAgaXMgYGJhc2VCYWNrb2ZmTXMgKiAyXm5gLlxuICAgKiBNdXN0IGJlIGA+PSAwYCAoYDBgIHNraXBzIGJhY2tvZmYgZGVsYXkgYmV0d2VlbiBhdHRlbXB0cykuXG4gICAqL1xuICBiYXNlQmFja29mZk1zOiBudW1iZXI7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBleHRlcm5hbCB7QGxpbmsgQWJvcnRTaWduYWx9LiBXaGVuIGFib3J0ZWQsIHRoZSBpbi1mbGlnaHQgcmVxdWVzdCBpcyBhYm9ydGVkOyBvbiB0aGVcbiAgICogZmluYWwgYXR0ZW1wdCwgY2FuY2VsbGF0aW9uIHN1cmZhY2VzIGFzIHtAbGluayBGZXRjaFJldHJpZXJBYm9ydEVycm9yfS5cbiAgICovXG4gIHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICAvKipcbiAgICogSW52b2tlZCBhZnRlciBgcmVzcG9uc2UudGV4dCgpYCB3aGVuIGByZXNwb25zZS5va2AgaXMgZmFsc2UuXG4gICAqIFJldHVybiBgdHJ1ZWAgdG8gc2NoZWR1bGUgYW5vdGhlciBhdHRlbXB0ICh1bnRpbCBgcmV0cmllc2AgaXMgZXhoYXVzdGVkKS5cbiAgICogRGVmYXVsdDoge0BsaW5rIGRlZmF1bHRTaG91bGRSZXRyeX0gKHNlZSB7QGxpbmsgREVGQVVMVF9SRVRSWUFCTEVfSFRUUF9TVEFUVVNFU30pLlxuICAgKlxuICAgKiBAcGFyYW0gcmVzcG9uc2UgLSBOb24tT0sgcmVzcG9uc2UgZnJvbSB0aGUgY3VycmVudCBhdHRlbXB0XG4gICAqIEBwYXJhbSBib2R5IC0gUmVzcG9uc2UgYm9keSB0ZXh0IGZyb20gYHJlc3BvbnNlLnRleHQoKWBcbiAgICogQHJldHVybnMgYHRydWVgIHRvIHNjaGVkdWxlIGFub3RoZXIgYXR0ZW1wdCAodW50aWwgYHJldHJpZXNgIGlzIGV4aGF1c3RlZClcbiAgICovXG4gIHNob3VsZFJldHJ5PzogKHJlc3BvbnNlOiBSZXNwb25zZSwgYm9keTogc3RyaW5nKSA9PiBib29sZWFuO1xufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIGEgcmVxdWVzdCBpcyBjYW5jZWxsZWQgYnkgdGltZW91dCBvciBhbiBleHRlcm5hbCB7QGxpbmsgQWJvcnRTaWduYWx9LlxuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllckFib3J0RXJyb3InO1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBIdW1hbi1yZWFkYWJsZSByZWFzb24gKGRlZmF1bHQ6IGAnQWJvcnRlZCdgKVxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdBYm9ydGVkJykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBGZXRjaFJldHJpZXJBYm9ydEVycm9yLnByb3RvdHlwZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiB7QGxpbmsgUmVxdWVzdE9wdGlvbnMuc2lnbmFsfSBpcyBhbHJlYWR5IGFib3J0ZWQgYmVmb3JlIGFuIGF0dGVtcHQgc3RhcnRzLlxuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvciBleHRlbmRzIEZldGNoUmV0cmllckFib3J0RXJyb3Ige1xuICBvdmVycmlkZSByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvcic7XG4gIC8qKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIEh1bWFuLXJlYWRhYmxlIHJlYXNvbiAoZGVmYXVsdDogYCdTaWduYWwgd2FzIGFscmVhZHkgYWJvcnRlZCdgKVxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdTaWduYWwgd2FzIGFscmVhZHkgYWJvcnRlZCcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4gdGhlIHNlcnZlciByZXR1cm5zIGEgbm9uLU9LIEhUVFAgc3RhdHVzIGFuZCBubyBmdXJ0aGVyIHJldHJ5IGlzIHBlcmZvcm1lZC5cbiAqXG4gKiBAcHJvcGVydHkgc3RhdHVzIC0gSFRUUCBzdGF0dXMgY29kZSBmcm9tIHRoZSBsYXN0IG5vbi1PSyByZXNwb25zZVxuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVySHR0cEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBvdmVycmlkZSByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnRmV0Y2hSZXRyaWVySHR0cEVycm9yJztcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gRXJyb3IgZGVzY3JpcHRpb25cbiAgICogQHBhcmFtIHN0YXR1cyAtIEhUVFAgc3RhdHVzIGNvZGUgZnJvbSB0aGUgbGFzdCBub24tT0sgcmVzcG9uc2VcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIG1lc3NhZ2U6IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgc3RhdHVzOiBudW1iZXIsXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBGZXRjaFJldHJpZXJIdHRwRXJyb3IucHJvdG90eXBlKTtcbiAgfVxufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIGEgZmV0Y2ggZmFpbHMgd2l0aCBhIG5ldHdvcmstbGV2ZWwgZXJyb3IgKGUuZy4gRE5TIGZhaWx1cmUsIGNvbm5lY3Rpb24gcmVmdXNlZCkuXG4gKlxuICogQHByb3BlcnR5IGNhdXNlIC0gT3JpZ2luYWwgZXJyb3IgZnJvbSB0aGUgdW5kZXJseWluZyBgZmV0Y2hgLCB3aGVuIGF2YWlsYWJsZVxuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVyTmV0d29ya0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBvdmVycmlkZSByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnRmV0Y2hSZXRyaWVyTmV0d29ya0Vycm9yJztcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gSHVtYW4tcmVhZGFibGUgcmVhc29uIChkZWZhdWx0OiBgJ05ldHdvcmsgZXJyb3InYClcbiAgICogQHBhcmFtIGNhdXNlIC0gT3JpZ2luYWwgZXJyb3IgZnJvbSB0aGUgdW5kZXJseWluZyBgZmV0Y2hgLCB3aGVuIGF2YWlsYWJsZVxuICAgKi9cbiAgY29uc3RydWN0b3IobWVzc2FnZSA9ICdOZXR3b3JrIGVycm9yJywgcHVibGljIHJlYWRvbmx5IGNhdXNlPzogdW5rbm93bikge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBGZXRjaFJldHJpZXJOZXR3b3JrRXJyb3IucHJvdG90eXBlKTtcbiAgfVxufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIHtAbGluayBSZXF1ZXN0T3B0aW9uc30gY29udGFpbnMgaW52YWxpZCBudW1lcmljIHZhbHVlcy5cbiAqXG4gKiBTdWJjbGFzcyBvZiB7QGxpbmsgVHlwZUVycm9yfSBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIGBpbnN0YW5jZW9mIFR5cGVFcnJvcmAuIERpc3RpbmN0IGZyb21cbiAqIG5ldHdvcmstbGV2ZWwgYFR5cGVFcnJvcmAgdmFsdWVzIHRocm93biBieSBgZmV0Y2hgLCB3aGljaCBhcmUgcmV0cmllZCBhbmQgc3VyZmFjZWQgYXNcbiAqIHtAbGluayBGZXRjaFJldHJpZXJOZXR3b3JrRXJyb3J9IGFmdGVyIHRoZSBsYXN0IGF0dGVtcHQuXG4gKi9cbmV4cG9ydCBjbGFzcyBGZXRjaFJldHJpZXJJbnZhbGlkT3B0aW9uc0Vycm9yIGV4dGVuZHMgVHlwZUVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllckludmFsaWRPcHRpb25zRXJyb3InO1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBIdW1hbi1yZWFkYWJsZSByZWFzb24gZGVzY3JpYmluZyB0aGUgaW52YWxpZCBvcHRpb25cbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBGZXRjaFJldHJpZXJJbnZhbGlkT3B0aW9uc0Vycm9yLnByb3RvdHlwZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiBhbiBpbnRlcm5hbCBpbnZhcmlhbnQgZmFpbHMgKHNob3VsZCBub3QgaGFwcGVuIGluIG5vcm1hbCB1c2UpLlxuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVyVW5yZWFjaGFibGVFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3InO1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBIdW1hbi1yZWFkYWJsZSByZWFzb24gKGRlZmF1bHQ6IGAnVW5yZWFjaGFibGUnYClcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnVW5yZWFjaGFibGUnKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIEZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3IucHJvdG90eXBlKTtcbiAgfVxufVxuXG4vKipcbiAqIEhUVFAgc3RhdHVzIGNvZGVzIHJldHJpZWQgYnkgZGVmYXVsdCB3aGVuIHtAbGluayBSZXF1ZXN0T3B0aW9ucy5zaG91bGRSZXRyeX0gaXMgb21pdHRlZC5cbiAqXG4gKiBJbmNsdWRlcyB0cmFuc2llbnQgY2xpZW50L3NlcnZlciBlcnJvcnM6IDQwOCwgNDI1LCA0MjksIGFuZCBjb21tb24gNXh4IGdhdGV3YXkgb3Igb3ZlcmxvYWQgcmVzcG9uc2VzLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9SRVRSWUFCTEVfSFRUUF9TVEFUVVNFUzogcmVhZG9ubHkgbnVtYmVyW10gPSBbNDA4LCA0MjUsIDQyOSwgNTAwLCA1MDIsIDUwMywgNTA0XTtcblxuLyoqXG4gKiBEZWZhdWx0IHtAbGluayBSZXF1ZXN0T3B0aW9ucy5zaG91bGRSZXRyeX06IHJldHJpZXMgcmVzcG9uc2VzIHdob3NlIHN0YXR1cyBpcyBpblxuICoge0BsaW5rIERFRkFVTFRfUkVUUllBQkxFX0hUVFBfU1RBVFVTRVN9LlxuICpcbiAqIENvbXBvc2Ugd2l0aCBjdXN0b20gbG9naWMsIGZvciBleGFtcGxlOlxuICogYChyZXMsIGJvZHkpID0+IGRlZmF1bHRTaG91bGRSZXRyeShyZXMsIGJvZHkpIHx8IHJlcy5zdGF0dXMgPT09IDQxOGAuXG4gKlxuICogQHBhcmFtIHJlc3BvbnNlIC0gUmVzcG9uc2UgZnJvbSB0aGUgZmFpbGVkIGF0dGVtcHRcbiAqIEBwYXJhbSBfYm9keSAtIFJlc3BvbnNlIGJvZHkgdGV4dCAodW51c2VkIGJ5IHRoZSBkZWZhdWx0IHByZWRpY2F0ZSlcbiAqIEByZXR1cm5zIGB0cnVlYCB3aGVuIGFub3RoZXIgYXR0ZW1wdCBzaG91bGQgYmUgc2NoZWR1bGVkXG4gKi9cbmV4cG9ydCBjb25zdCBkZWZhdWx0U2hvdWxkUmV0cnkgPSAocmVzcG9uc2U6IFJlc3BvbnNlLCBfYm9keTogc3RyaW5nKTogYm9vbGVhbiA9PiB7XG4gIHJldHVybiBERUZBVUxUX1JFVFJZQUJMRV9IVFRQX1NUQVRVU0VTLmluY2x1ZGVzKHJlc3BvbnNlLnN0YXR1cyk7XG59O1xuXG4vKipcbiAqIFZhbGlkYXRlcyByZXRyeSBwb2xpY3kgbnVtZXJpYyBmaWVsZHMgb24ge0BsaW5rIFJlcXVlc3RPcHRpb25zfS5cbiAqXG4gKiBDb25zdHJhaW50czogYHJldHJpZXMgPj0gMWAsIGB0aW1lb3V0TXMgPiAwYCwgYGJhc2VCYWNrb2ZmTXMgPj0gMGAuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBPcHRpb25zIHdob3NlIGByZXRyaWVzYCwgYHRpbWVvdXRNc2AsIGFuZCBgYmFzZUJhY2tvZmZNc2AgYXJlIGNoZWNrZWRcbiAqIEB0aHJvd3Mge0ZldGNoUmV0cmllckludmFsaWRPcHRpb25zRXJyb3J9IFdoZW4gYW55IGNvbnN0cmFpbnQgaXMgdmlvbGF0ZWRcbiAqL1xuY29uc3QgdmFsaWRhdGVSZXF1ZXN0T3B0aW9ucyA9IChvcHRpb25zOiBQaWNrPFJlcXVlc3RPcHRpb25zLCAncmV0cmllcycgfCAndGltZW91dE1zJyB8ICdiYXNlQmFja29mZk1zJz4pOiB2b2lkID0+IHtcbiAgY29uc3QgeyByZXRyaWVzLCB0aW1lb3V0TXMsIGJhc2VCYWNrb2ZmTXMgfSA9IG9wdGlvbnM7XG5cbiAgaWYgKHJldHJpZXMgPCAxKSB7XG4gICAgdGhyb3cgbmV3IEZldGNoUmV0cmllckludmFsaWRPcHRpb25zRXJyb3IoJ3JldHJpZXMgbXVzdCBiZSA+PSAxJyk7XG4gIH1cbiAgaWYgKHRpbWVvdXRNcyA8PSAwKSB7XG4gICAgdGhyb3cgbmV3IEZldGNoUmV0cmllckludmFsaWRPcHRpb25zRXJyb3IoJ3RpbWVvdXRNcyBtdXN0IGJlID4gMCcpO1xuICB9XG4gIGlmIChiYXNlQmFja29mZk1zIDwgMCkge1xuICAgIHRocm93IG5ldyBGZXRjaFJldHJpZXJJbnZhbGlkT3B0aW9uc0Vycm9yKCdiYXNlQmFja29mZk1zIG11c3QgYmUgPj0gMCcpO1xuICB9XG59O1xuXG4vKipcbiAqIFdyYXBzIGBmZXRjaGAgd2l0aCByZXRyaWVzLCBwZXItYXR0ZW1wdCB0aW1lb3V0LCBmdWxsLWppdHRlciBiYWNrb2ZmLCBhbmQgb3B0aW9uYWwgY2FuY2VsbGF0aW9uLlxuICpcbiAqIEVhY2ggYXR0ZW1wdCBjYWxscyBgZmV0Y2godXJsLCB7IC4uLm9wdGlvbnMuaW5pdCwgaGVhZGVycz8sIHNpZ25hbCB9KWAgd2l0aCBhbiBpbnRlcm5hbFxuICoge0BsaW5rIEFib3J0U2lnbmFsfSBmb3IgYHRpbWVvdXRNc2AuIE5vbi1PSyByZXNwb25zZXMgYXJlIHJldHJpZWQgd2hlbiBgc2hvdWxkUmV0cnlgIHJldHVybnNcbiAqIGB0cnVlYCAoZGVmYXVsdDoge0BsaW5rIERFRkFVTFRfUkVUUllBQkxFX0hUVFBfU1RBVFVTRVN9KS4gVGhlIHNhbWUge0BsaW5rIEZldGNoSW5pdE9wdGlvbnN9IChpbmNsdWRpbmcgYGJvZHlgKSBpcyByZXVzZWRcbiAqIG9uIGV2ZXJ5IGF0dGVtcHQuXG4gKlxuICogQHBhcmFtIHVybCAtIFJlcXVlc3QgVVJMIHBhc3NlZCB0byBgZmV0Y2hgXG4gKiBAcGFyYW0gb3B0aW9ucyAtIHtAbGluayBSZXF1ZXN0T3B0aW9uc30gY29udHJvbGxpbmcgcmV0cmllcywgdGltZW91dCwgcmVxdWVzdCBpbml0LCBhbmQgY2FuY2VsbGF0aW9uXG4gKiBAcmV0dXJucyBUaGUgZmlyc3Qge0BsaW5rIFJlc3BvbnNlfSBmb3Igd2hpY2ggYG9rYCBpcyBgdHJ1ZWBcbiAqIEB0aHJvd3Mge0ZldGNoUmV0cmllckludmFsaWRPcHRpb25zRXJyb3J9IElmIGByZXRyaWVzIDwgMWAsIGB0aW1lb3V0TXMgPD0gMGAsIG9yIGBiYXNlQmFja29mZk1zIDwgMGBcbiAqIEB0aHJvd3Mge0ZldGNoUmV0cmllckFscmVhZHlBYm9ydGVkRXJyb3J9IElmIGBvcHRpb25zLnNpZ25hbGAgaXMgYWxyZWFkeSBhYm9ydGVkIGJlZm9yZSBhbiBhdHRlbXB0XG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJIdHRwRXJyb3J9IE9uIGEgbm9uLU9LIHJlc3BvbnNlIHRoYXQgaXMgbm90IHJldHJpZWQgb3IgYWZ0ZXIgdGhlIGxhc3QgYXR0ZW1wdFxuICogQHRocm93cyB7RmV0Y2hSZXRyaWVyTmV0d29ya0Vycm9yfSBPbiBhIG5ldHdvcmsgYFR5cGVFcnJvcmAgYWZ0ZXIgdGhlIGxhc3QgYXR0ZW1wdFxuICogQHRocm93cyB7RmV0Y2hSZXRyaWVyQWJvcnRFcnJvcn0gT24gdGltZW91dCBvciBleHRlcm5hbCBhYm9ydCBhZnRlciB0aGUgbGFzdCBhdHRlbXB0XG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJVbnJlYWNoYWJsZUVycm9yfSBJZiB0aGUgcmV0cnkgbG9vcCBleGl0cyB3aXRob3V0IHJldHVybmluZyAoaW50ZXJuYWwgYnVnKVxuICovXG5leHBvcnQgY29uc3QgZmV0Y2hSZXRyaWVyID0gYXN5bmMgKHVybDogc3RyaW5nLCBvcHRpb25zOiBSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8UmVzcG9uc2U+ID0+IHtcbiAgY29uc3Qge1xuICAgIGhlYWRlcnMsXG4gICAgaW5pdCxcbiAgICByZXRyaWVzLFxuICAgIHRpbWVvdXRNcyxcbiAgICBiYXNlQmFja29mZk1zLFxuICAgIHNpZ25hbDogZXh0ZXJuYWxTaWduYWwsXG4gICAgc2hvdWxkUmV0cnkgPSBkZWZhdWx0U2hvdWxkUmV0cnksXG4gIH0gPSBvcHRpb25zO1xuXG4gIHZhbGlkYXRlUmVxdWVzdE9wdGlvbnMoeyByZXRyaWVzLCB0aW1lb3V0TXMsIGJhc2VCYWNrb2ZmTXMgfSk7XG5cbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IGF0dGVtcHQgPD0gcmV0cmllczsgYXR0ZW1wdCsrKSB7XG4gICAgaWYgKGV4dGVybmFsU2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvcigpO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IGNvbnRyb2xsZXIuYWJvcnQoKSwgdGltZW91dE1zKTtcblxuICAgIGNvbnN0IG9uRXh0ZXJuYWxBYm9ydCA9ICgpOiB2b2lkID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICBjb250cm9sbGVyLmFib3J0KCk7XG4gICAgfTtcblxuICAgIGlmIChleHRlcm5hbFNpZ25hbCkge1xuICAgICAgZXh0ZXJuYWxTaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkV4dGVybmFsQWJvcnQpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICAgICAgLi4uaW5pdCxcbiAgICAgICAgLi4uKGhlYWRlcnMgIT09IHVuZGVmaW5lZCA/IHsgaGVhZGVycyB9IDoge30pLFxuICAgICAgICBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgfSk7XG5cbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICBleHRlcm5hbFNpZ25hbD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkV4dGVybmFsQWJvcnQpO1xuXG4gICAgICBpZiAocmVzLm9rKSB7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZXMudGV4dCgpO1xuICAgICAgY29uc3QgaXNDb250aW51ZSA9IHNob3VsZFJldHJ5KHJlcywgdGV4dCk7XG5cbiAgICAgIGlmIChpc0NvbnRpbnVlKSB7XG4gICAgICAgIGlmIChhdHRlbXB0ID09PSByZXRyaWVzKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZldGNoUmV0cmllckh0dHBFcnJvcihgSFRUUCAke3Jlcy5zdGF0dXN9YCwgcmVzLnN0YXR1cyk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgd2FpdChmdWxsSml0dGVyKGJhc2VCYWNrb2ZmTXMsIGF0dGVtcHQpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBGZXRjaFJldHJpZXJIdHRwRXJyb3IoYE5vbi1yZXRyaWFibGUgSFRUUCBlcnJvcjogJHtyZXMuc3RhdHVzfWAsIHJlcy5zdGF0dXMpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIGV4dGVybmFsU2lnbmFsPy5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uRXh0ZXJuYWxBYm9ydCk7XG5cbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnIubmFtZSA9PT0gJ0Fib3J0RXJyb3InKSB7XG4gICAgICAgIGlmIChhdHRlbXB0ID09PSByZXRyaWVzKSB0aHJvdyBlcnIgaW5zdGFuY2VvZiBGZXRjaFJldHJpZXJBYm9ydEVycm9yID8gZXJyIDogbmV3IEZldGNoUmV0cmllckFib3J0RXJyb3IoKTtcbiAgICAgICAgYXdhaXQgd2FpdChmdWxsSml0dGVyKGJhc2VCYWNrb2ZmTXMsIGF0dGVtcHQpKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBUeXBlRXJyb3IpIHtcbiAgICAgICAgaWYgKGF0dGVtcHQgPT09IHJldHJpZXMpIHRocm93IG5ldyBGZXRjaFJldHJpZXJOZXR3b3JrRXJyb3IoJ05ldHdvcmsgZXJyb3InLCBlcnIpO1xuICAgICAgICBhd2FpdCB3YWl0KGZ1bGxKaXR0ZXIoYmFzZUJhY2tvZmZNcywgYXR0ZW1wdCkpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBGZXRjaFJldHJpZXJVbnJlYWNoYWJsZUVycm9yKCk7XG59O1xuXG4vKipcbiAqIERlbGF5cyBleGVjdXRpb24gZm9yIHRoZSBnaXZlbiBkdXJhdGlvbiAodXNlZCBiZXR3ZWVuIHJldHJ5IGF0dGVtcHRzKS5cbiAqXG4gKiBAcGFyYW0gbXMgLSBEZWxheSBpbiBtaWxsaXNlY29uZHNcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIGBtc2BcbiAqL1xuY29uc3Qgd2FpdCA9IChtczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xufTtcblxuLyoqXG4gKiBGdWxsIGppdHRlciBiYWNrb2ZmOiByYW5kb20gZGVsYXkgaW4gYFswLCBiYXNlICogMl5hdHRlbXB0KWAgbXMgKEFXUy1yZWNvbW1lbmRlZCBwYXR0ZXJuKS5cbiAqXG4gKiBAcGFyYW0gYmFzZSAtIEJhc2UgYmFja29mZiBpbiBtaWxsaXNlY29uZHNcbiAqIEBwYXJhbSBhdHRlbXB0IC0gMS1iYXNlZCBhdHRlbXB0IGluZGV4IChmaXJzdCByZXRyeSB1c2VzIGBhdHRlbXB0ID09PSAxYClcbiAqIEByZXR1cm5zIFdhaXQgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzIGJlZm9yZSB0aGUgbmV4dCBhdHRlbXB0XG4gKi9cbmNvbnN0IGZ1bGxKaXR0ZXIgPSAoYmFzZTogbnVtYmVyLCBhdHRlbXB0OiBudW1iZXIpOiBudW1iZXIgPT4ge1xuICBjb25zdCBjYXAgPSBiYXNlICogTWF0aC5wb3coMiwgYXR0ZW1wdCk7XG4gIHJldHVybiBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBjYXApO1xufTtcbiJdfQ==
258
+ /**
259
+ * Parses a `Retry-After` header value into a delay in milliseconds.
260
+ *
261
+ * Supports RFC 7231 forms: non-negative integer delta-seconds, or an HTTP-date. Empty values,
262
+ * non-integer numerics (e.g. floats or negatives), and unparsable dates yield `undefined` so
263
+ * callers can fall back to full jitter. An HTTP-date in the past yields `0`.
264
+ *
265
+ * @param value - Raw `Retry-After` header value
266
+ * @param nowMs - Current time in milliseconds (injectable for tests)
267
+ * @returns Delay in milliseconds, or `undefined` when the value cannot be parsed
268
+ */
269
+ const parseRetryAfterMs = (value, nowMs = Date.now()) => {
270
+ const trimmed = value.trim();
271
+ if (trimmed === '') {
272
+ return undefined;
273
+ }
274
+ if (/^\d+$/.test(trimmed)) {
275
+ return Number.parseInt(trimmed, 10) * 1000;
276
+ }
277
+ // Reject other numeric forms (floats, negatives); not valid delta-seconds or HTTP-date.
278
+ if (/^-?\d+(\.\d+)?$/.test(trimmed)) {
279
+ return undefined;
280
+ }
281
+ const dateMs = Date.parse(trimmed);
282
+ if (Number.isNaN(dateMs)) {
283
+ return undefined;
284
+ }
285
+ return Math.max(0, dateMs - nowMs);
286
+ };
287
+ exports.parseRetryAfterMs = parseRetryAfterMs;
288
+ /**
289
+ * Chooses the delay before the next HTTP retry: prefer a valid `Retry-After`, else full jitter.
290
+ *
291
+ * Reads `response.headers.get('Retry-After')` and parses it with {@link parseRetryAfterMs}.
292
+ * Missing headers, or values that parse to `undefined`, fall back to {@link fullJitter}.
293
+ * Abort and network retries do not use this helper.
294
+ *
295
+ * @param response - Non-OK response from the current attempt
296
+ * @param baseBackoffMs - Base backoff passed to {@link fullJitter} when falling back
297
+ * @param attempt - 1-based attempt index
298
+ * @param nowMs - Current time in milliseconds (injectable for tests)
299
+ * @returns Wait duration in milliseconds before the next attempt
300
+ */
301
+ const resolveRetryDelayMs = (response, baseBackoffMs, attempt, nowMs = Date.now()) => {
302
+ const header = response.headers?.get('Retry-After');
303
+ if (header == null) {
304
+ return fullJitter(baseBackoffMs, attempt);
305
+ }
306
+ const fromHeader = (0, exports.parseRetryAfterMs)(header, nowMs);
307
+ if (fromHeader === undefined) {
308
+ return fullJitter(baseBackoffMs, attempt);
309
+ }
310
+ return fromHeader;
311
+ };
312
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7OztHQUtHOzs7QUFpRUg7O0dBRUc7QUFDSCxNQUFhLHNCQUF1QixTQUFRLEtBQUs7SUFFL0M7O09BRUc7SUFDSCxZQUFZLE9BQU8sR0FBRyxTQUFTO1FBQzdCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUxDLFNBQUksR0FBVyx3QkFBd0IsQ0FBQztRQU14RCxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxzQkFBc0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNoRSxDQUFDO0NBQ0Y7QUFURCx3REFTQztBQUVEOztHQUVHO0FBQ0gsTUFBYSwrQkFBZ0MsU0FBUSxzQkFBc0I7SUFFekU7O09BRUc7SUFDSCxZQUFZLE9BQU8sR0FBRyw0QkFBNEI7UUFDaEQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBTEMsU0FBSSxHQUFXLGlDQUFpQyxDQUFDO1FBTWpFLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLCtCQUErQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7Q0FDRjtBQVRELDBFQVNDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFhLHFCQUFzQixTQUFRLEtBQUs7SUFFOUM7Ozs7T0FJRztJQUNILFlBQ0UsT0FBZSxFQUNDLE1BQWMsRUFDZCxJQUFZO1FBRTVCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUhDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxTQUFJLEdBQUosSUFBSSxDQUFRO1FBVFosU0FBSSxHQUFXLHVCQUF1QixDQUFDO1FBWXZELE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLHFCQUFxQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQy9ELENBQUM7Q0FDRjtBQWZELHNEQWVDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQWEsd0JBQXlCLFNBQVEsS0FBSztJQUVqRDs7O09BR0c7SUFDSCxZQUFZLE9BQU8sR0FBRyxlQUFlLEVBQWtCLEtBQWU7UUFDcEUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRHNDLFVBQUssR0FBTCxLQUFLLENBQVU7UUFMcEQsU0FBSSxHQUFXLDBCQUEwQixDQUFDO1FBTzFELE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLHdCQUF3QixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7Q0FDRjtBQVZELDREQVVDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBYSwrQkFBZ0MsU0FBUSxTQUFTO0lBRTVEOztPQUVHO0lBQ0gsWUFBWSxPQUFlO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUxDLFNBQUksR0FBVyxpQ0FBaUMsQ0FBQztRQU1qRSxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSwrQkFBK0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN6RSxDQUFDO0NBQ0Y7QUFURCwwRUFTQztBQUVEOztHQUVHO0FBQ0gsTUFBYSw0QkFBNkIsU0FBUSxLQUFLO0lBRXJEOztPQUVHO0lBQ0gsWUFBWSxPQUFPLEdBQUcsYUFBYTtRQUNqQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFMQyxTQUFJLEdBQVcsOEJBQThCLENBQUM7UUFNOUQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsNEJBQTRCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdEUsQ0FBQztDQUNGO0FBVEQsb0VBU0M7QUFFRDs7OztHQUlHO0FBQ1UsUUFBQSwrQkFBK0IsR0FBc0IsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUV0Rzs7Ozs7Ozs7OztHQVVHO0FBQ0ksTUFBTSxrQkFBa0IsR0FBRyxDQUFDLFFBQWtCLEVBQUUsS0FBYSxFQUFXLEVBQUU7SUFDL0UsT0FBTyx1Q0FBK0IsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ25FLENBQUMsQ0FBQztBQUZXLFFBQUEsa0JBQWtCLHNCQUU3QjtBQUVGOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLHNCQUFzQixHQUFHLENBQUMsT0FBd0UsRUFBUSxFQUFFO0lBQ2hILE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxHQUFHLE9BQU8sQ0FBQztJQUV0RCxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNoQixNQUFNLElBQUksK0JBQStCLENBQUMsc0JBQXNCLENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBQ0QsSUFBSSxTQUFTLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDbkIsTUFBTSxJQUFJLCtCQUErQixDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDckUsQ0FBQztJQUNELElBQUksYUFBYSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3RCLE1BQU0sSUFBSSwrQkFBK0IsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0lBQzFFLENBQUM7QUFDSCxDQUFDLENBQUM7QUFFRjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBQ0ksTUFBTSxZQUFZLEdBQUcsS0FBSyxFQUFFLEdBQVcsRUFBRSxPQUF1QixFQUFxQixFQUFFO0lBQzVGLE1BQU0sRUFDSixPQUFPLEVBQ1AsSUFBSSxFQUNKLE9BQU8sRUFDUCxTQUFTLEVBQ1QsYUFBYSxFQUNiLE1BQU0sRUFBRSxjQUFjLEVBQ3RCLFdBQVcsR0FBRywwQkFBa0IsR0FDakMsR0FBRyxPQUFPLENBQUM7SUFFWixzQkFBc0IsQ0FBQyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLENBQUMsQ0FBQztJQUU5RCxLQUFLLElBQUksT0FBTyxHQUFHLENBQUMsRUFBRSxPQUFPLElBQUksT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUM7UUFDcEQsSUFBSSxjQUFjLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDNUIsTUFBTSxJQUFJLCtCQUErQixFQUFFLENBQUM7UUFDOUMsQ0FBQztRQUVELE1BQU0sVUFBVSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7UUFDekMsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUU5RCxNQUFNLGVBQWUsR0FBRyxHQUFTLEVBQUU7WUFDakMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3BCLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNyQixDQUFDLENBQUM7UUFFRixJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ25CLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDNUQsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILE1BQU0sR0FBRyxHQUFHLE1BQU0sS0FBSyxDQUFDLEdBQUcsRUFBRTtnQkFDM0IsR0FBRyxJQUFJO2dCQUNQLEdBQUcsQ0FBQyxPQUFPLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQzdDLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBTTthQUMxQixDQUFDLENBQUM7WUFFSCxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEIsY0FBYyxFQUFFLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxlQUFlLENBQUMsQ0FBQztZQUU5RCxJQUFJLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDWCxPQUFPLEdBQUcsQ0FBQztZQUNiLENBQUM7WUFFRCxNQUFNLElBQUksR0FBRyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUM5QixNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRTFDLElBQUksVUFBVSxFQUFFLENBQUM7Z0JBQ2YsSUFBSSxPQUFPLEtBQUssT0FBTyxFQUFFLENBQUM7b0JBQ3hCLE1BQU0sSUFBSSxxQkFBcUIsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxNQUFNLEVBQUUsRUFBRSxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUMxRSxDQUFDO2dCQUNELE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsRUFBRSxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUMvRCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sTUFBTSxJQUFJLHFCQUFxQixDQUFDLDZCQUE2QixHQUFHLENBQUMsTUFBTSxFQUFFLEVBQUUsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztZQUMvRixDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sR0FBWSxFQUFFLENBQUM7WUFDdEIsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3BCLGNBQWMsRUFBRSxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsZUFBZSxDQUFDLENBQUM7WUFFOUQsSUFBSSxHQUFHLFlBQVksS0FBSyxJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUFFLENBQUM7Z0JBQ3RELElBQUksT0FBTyxLQUFLLE9BQU87b0JBQUUsTUFBTSxHQUFHLFlBQVksc0JBQXNCLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxzQkFBc0IsRUFBRSxDQUFDO2dCQUMxRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQy9DLFNBQVM7WUFDWCxDQUFDO1lBRUQsSUFBSSxHQUFHLFlBQVksU0FBUyxFQUFFLENBQUM7Z0JBQzdCLElBQUksT0FBTyxLQUFLLE9BQU87b0JBQUUsTUFBTSxJQUFJLHdCQUF3QixDQUFDLGVBQWUsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDbEYsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO2dCQUMvQyxTQUFTO1lBQ1gsQ0FBQztZQUVELE1BQU0sR0FBRyxDQUFDO1FBQ1osQ0FBQztJQUNILENBQUM7SUFFRCxNQUFNLElBQUksNEJBQTRCLEVBQUUsQ0FBQztBQUMzQyxDQUFDLENBQUM7QUE1RVcsUUFBQSxZQUFZLGdCQTRFdkI7QUFFRjs7Ozs7R0FLRztBQUNILE1BQU0sSUFBSSxHQUFHLENBQUMsRUFBVSxFQUFpQixFQUFFO0lBQ3pDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMzRCxDQUFDLENBQUM7QUFFRjs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsR0FBRyxDQUFDLElBQVksRUFBRSxPQUFlLEVBQVUsRUFBRTtJQUMzRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDeEMsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUN6QyxDQUFDLENBQUM7QUFFRjs7Ozs7Ozs7OztHQVVHO0FBQ0ksTUFBTSxpQkFBaUIsR0FBRyxDQUFDLEtBQWEsRUFBRSxRQUFnQixJQUFJLENBQUMsR0FBRyxFQUFFLEVBQXNCLEVBQUU7SUFDakcsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzdCLElBQUksT0FBTyxLQUFLLEVBQUUsRUFBRSxDQUFDO1FBQ25CLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRCxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUMxQixPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQztJQUM3QyxDQUFDO0lBRUQsd0ZBQXdGO0lBQ3hGLElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDcEMsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbkMsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDekIsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVELE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQ3JDLENBQUMsQ0FBQztBQXJCVyxRQUFBLGlCQUFpQixxQkFxQjVCO0FBRUY7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsTUFBTSxtQkFBbUIsR0FBRyxDQUMxQixRQUFrQixFQUNsQixhQUFxQixFQUNyQixPQUFlLEVBQ2YsUUFBZ0IsSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUNsQixFQUFFO0lBQ1YsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDcEQsSUFBSSxNQUFNLElBQUksSUFBSSxFQUFFLENBQUM7UUFDbkIsT0FBTyxVQUFVLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxNQUFNLFVBQVUsR0FBRyxJQUFBLHlCQUFpQixFQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNwRCxJQUFJLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUM3QixPQUFPLFVBQVUsQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVELE9BQU8sVUFBVSxDQUFDO0FBQ3BCLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUmV0cnktZW5hYmxlZCBgZmV0Y2hgIHdyYXBwZXIgd2l0aCBwZXItYXR0ZW1wdCB0aW1lb3V0LCBSZXRyeS1BZnRlciBzdXBwb3J0LCBmdWxsLWppdHRlciBiYWNrb2ZmLFxuICogb3B0aW9uIHZhbGlkYXRpb24sIGFuZCB0eXBlZCBlcnJvcnMuXG4gKlxuICogQG1vZHVsZSBmZXRjaC1yZXRyaWVyXG4gKi9cblxuLyoqXG4gKiBgZmV0Y2hgIG9wdGlvbnMgZm9yd2FyZGVkIHRvIGV2ZXJ5IGF0dGVtcHQsIGV4Y2x1ZGluZyBgc2lnbmFsYC5cbiAqXG4gKiBVc2UgZm9yIGBtZXRob2RgLCBgYm9keWAsIGBjcmVkZW50aWFsc2AsIGByZWRpcmVjdGAsIGBtb2RlYCwgYGNhY2hlYCwgYW5kIG90aGVyXG4gKiB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1JlcXVlc3RJbml0IHwgUmVxdWVzdEluaXR9IGZpZWxkcy5cbiAqIFBlci1hdHRlbXB0IGFib3J0IGFuZCB0aW1lb3V0IGFyZSBoYW5kbGVkIGludGVybmFsbHkgdmlhIGBzaWduYWxgIGFuZCBtdXN0IG5vdCBiZSBzZXQgaGVyZS5cbiAqL1xuZXhwb3J0IHR5cGUgRmV0Y2hJbml0T3B0aW9ucyA9IE9taXQ8UmVxdWVzdEluaXQsICdzaWduYWwnPjtcblxuLyoqXG4gKiBPcHRpb25zIGZvciB7QGxpbmsgZmV0Y2hSZXRyaWVyfTogcmV0cnkgcG9saWN5LCB0aW1lb3V0LCBiYWNrb2ZmIChpbmNsdWRpbmcgYFJldHJ5LUFmdGVyYCksXG4gKiByZXF1ZXN0IHBheWxvYWQsIGFuZCBjYW5jZWxsYXRpb24uXG4gKlxuICogUmVxdWVzdCBzaGFwZSBpcyBidWlsdCBhcyBgeyAuLi5pbml0LCBoZWFkZXJzPywgc2lnbmFsIH1gIG9uIGVhY2ggYXR0ZW1wdC4gVG9wLWxldmVsIGBoZWFkZXJzYFxuICogb3ZlcnJpZGUgYGluaXQuaGVhZGVyc2Agd2hlbiBib3RoIGFyZSBwcm92aWRlZC5cbiAqXG4gKiBOdW1lcmljIGZpZWxkcyBhcmUgdmFsaWRhdGVkIHdoZW4ge0BsaW5rIGZldGNoUmV0cmllcn0gaXMgY2FsbGVkOyBpbnZhbGlkIHZhbHVlcyB0aHJvd1xuICoge0BsaW5rIEZldGNoUmV0cmllckludmFsaWRPcHRpb25zRXJyb3J9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlcXVlc3RPcHRpb25zIHtcbiAgLyoqXG4gICAqIEhUVFAgaGVhZGVycyBzZW50IG9uIGV2ZXJ5IGF0dGVtcHQuXG4gICAqIFdoZW4gYGluaXQuaGVhZGVyc2AgaXMgYWxzbyBzZXQsIHRoZXNlIHZhbHVlcyB0YWtlIHByZWNlZGVuY2UgZm9yIGR1cGxpY2F0ZSBrZXlzLlxuICAgKi9cbiAgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIHtAbGluayBGZXRjaEluaXRPcHRpb25zfSBtZXJnZWQgaW50byBlYWNoIGBmZXRjaGAgY2FsbCAoZS5nLiBQT1NUIGBtZXRob2RgIGFuZCBKU09OIGBib2R5YCkuXG4gICAqIFRoZSBzYW1lIGBpbml0YCBpcyByZXVzZWQgYWNyb3NzIHJldHJpZXMuXG4gICAqL1xuICBpbml0PzogRmV0Y2hJbml0T3B0aW9ucztcbiAgLyoqXG4gICAqIE1heGltdW0gbnVtYmVyIG9mIGF0dGVtcHRzLCBpbmNsdWRpbmcgdGhlIGZpcnN0LlxuICAgKiBNdXN0IGJlIGA+PSAxYC5cbiAgICovXG4gIHJldHJpZXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIFBlci1hdHRlbXB0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzOyB1c2VzIGFuIGludGVybmFsIHtAbGluayBBYm9ydENvbnRyb2xsZXJ9IHdoZW4gZXhjZWVkZWQuXG4gICAqIE11c3QgYmUgYD4gMGAuXG4gICAqL1xuICB0aW1lb3V0TXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIEJhc2UgYmFja29mZiBpbiBtaWxsaXNlY29uZHMgZm9yIGZ1bGwgaml0dGVyIHdoZW4gYFJldHJ5LUFmdGVyYCBpcyBhYnNlbnQgb3IgaW52YWxpZC5cbiAgICogVGhlIGNhcCBmb3IgYXR0ZW1wdCBgbmAgaXMgYGJhc2VCYWNrb2ZmTXMgKiAyXm5gLlxuICAgKiBNdXN0IGJlIGA+PSAwYCAoYDBgIHNraXBzIGJhY2tvZmYgZGVsYXkgYmV0d2VlbiBhdHRlbXB0cyB3aGVuIGZhbGxpbmcgYmFjayB0byBqaXR0ZXIpLlxuICAgKi9cbiAgYmFzZUJhY2tvZmZNczogbnVtYmVyO1xuICAvKipcbiAgICogT3B0aW9uYWwgZXh0ZXJuYWwge0BsaW5rIEFib3J0U2lnbmFsfS4gV2hlbiBhYm9ydGVkLCB0aGUgaW4tZmxpZ2h0IHJlcXVlc3QgaXMgYWJvcnRlZDsgb24gdGhlXG4gICAqIGZpbmFsIGF0dGVtcHQsIGNhbmNlbGxhdGlvbiBzdXJmYWNlcyBhcyB7QGxpbmsgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvcn0uXG4gICAqL1xuICBzaWduYWw/OiBBYm9ydFNpZ25hbDtcbiAgLyoqXG4gICAqIEludm9rZWQgYWZ0ZXIgYHJlc3BvbnNlLnRleHQoKWAgd2hlbiBgcmVzcG9uc2Uub2tgIGlzIGZhbHNlLlxuICAgKiBSZXR1cm4gYHRydWVgIHRvIHNjaGVkdWxlIGFub3RoZXIgYXR0ZW1wdCAodW50aWwgYHJldHJpZXNgIGlzIGV4aGF1c3RlZCkuXG4gICAqIERlZmF1bHQ6IHtAbGluayBkZWZhdWx0U2hvdWxkUmV0cnl9IChzZWUge0BsaW5rIERFRkFVTFRfUkVUUllBQkxFX0hUVFBfU1RBVFVTRVN9KS5cbiAgICpcbiAgICogQHBhcmFtIHJlc3BvbnNlIC0gTm9uLU9LIHJlc3BvbnNlIGZyb20gdGhlIGN1cnJlbnQgYXR0ZW1wdFxuICAgKiBAcGFyYW0gYm9keSAtIFJlc3BvbnNlIGJvZHkgdGV4dCBmcm9tIGByZXNwb25zZS50ZXh0KClgXG4gICAqIEByZXR1cm5zIGB0cnVlYCB0byBzY2hlZHVsZSBhbm90aGVyIGF0dGVtcHQgKHVudGlsIGByZXRyaWVzYCBpcyBleGhhdXN0ZWQpXG4gICAqL1xuICBzaG91bGRSZXRyeT86IChyZXNwb25zZTogUmVzcG9uc2UsIGJvZHk6IHN0cmluZykgPT4gYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiBhIHJlcXVlc3QgaXMgY2FuY2VsbGVkIGJ5IHRpbWVvdXQgb3IgYW4gZXh0ZXJuYWwge0BsaW5rIEFib3J0U2lnbmFsfS5cbiAqL1xuZXhwb3J0IGNsYXNzIEZldGNoUmV0cmllckFib3J0RXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIG92ZXJyaWRlIHJlYWRvbmx5IG5hbWU6IHN0cmluZyA9ICdGZXRjaFJldHJpZXJBYm9ydEVycm9yJztcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gSHVtYW4tcmVhZGFibGUgcmVhc29uIChkZWZhdWx0OiBgJ0Fib3J0ZWQnYClcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnQWJvcnRlZCcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4ge0BsaW5rIFJlcXVlc3RPcHRpb25zLnNpZ25hbH0gaXMgYWxyZWFkeSBhYm9ydGVkIGJlZm9yZSBhbiBhdHRlbXB0IHN0YXJ0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIEZldGNoUmV0cmllckFscmVhZHlBYm9ydGVkRXJyb3IgZXh0ZW5kcyBGZXRjaFJldHJpZXJBYm9ydEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllckFscmVhZHlBYm9ydGVkRXJyb3InO1xuICAvKipcbiAgICogQHBhcmFtIG1lc3NhZ2UgLSBIdW1hbi1yZWFkYWJsZSByZWFzb24gKGRlZmF1bHQ6IGAnU2lnbmFsIHdhcyBhbHJlYWR5IGFib3J0ZWQnYClcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnU2lnbmFsIHdhcyBhbHJlYWR5IGFib3J0ZWQnKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIEZldGNoUmV0cmllckFscmVhZHlBYm9ydGVkRXJyb3IucHJvdG90eXBlKTtcbiAgfVxufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIHRoZSBzZXJ2ZXIgcmV0dXJucyBhIG5vbi1PSyBIVFRQIHN0YXR1cyBhbmQgbm8gZnVydGhlciByZXRyeSBpcyBwZXJmb3JtZWQuXG4gKlxuICogQ2FycmllcyB0aGUgbGFzdCByZXNwb25zZSBgc3RhdHVzYCBhbmQgdGhlIGJvZHkgdGV4dCBhbHJlYWR5IGNvbnN1bWVkIHZpYSBgcmVzcG9uc2UudGV4dCgpYFxuICogKHRoZSBzYW1lIHRleHQgcGFzc2VkIHRvIHtAbGluayBSZXF1ZXN0T3B0aW9ucy5zaG91bGRSZXRyeX0pLlxuICpcbiAqIEBwcm9wZXJ0eSBzdGF0dXMgLSBIVFRQIHN0YXR1cyBjb2RlIGZyb20gdGhlIGxhc3Qgbm9uLU9LIHJlc3BvbnNlXG4gKiBAcHJvcGVydHkgYm9keSAtIFJlc3BvbnNlIGJvZHkgdGV4dCBhbHJlYWR5IHJlYWQgdmlhIGByZXNwb25zZS50ZXh0KClgIGZvciB0aGF0IGF0dGVtcHRcbiAqL1xuZXhwb3J0IGNsYXNzIEZldGNoUmV0cmllckh0dHBFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllckh0dHBFcnJvcic7XG4gIC8qKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIEVycm9yIGRlc2NyaXB0aW9uXG4gICAqIEBwYXJhbSBzdGF0dXMgLSBIVFRQIHN0YXR1cyBjb2RlIGZyb20gdGhlIGxhc3Qgbm9uLU9LIHJlc3BvbnNlXG4gICAqIEBwYXJhbSBib2R5IC0gUmVzcG9uc2UgYm9keSB0ZXh0IGFscmVhZHkgcmVhZCB2aWEgYHJlc3BvbnNlLnRleHQoKWAgZm9yIHRoYXQgYXR0ZW1wdFxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICAgIHB1YmxpYyByZWFkb25seSBzdGF0dXM6IG51bWJlcixcbiAgICBwdWJsaWMgcmVhZG9ubHkgYm9keTogc3RyaW5nLFxuICApIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVySHR0cEVycm9yLnByb3RvdHlwZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiBhIGZldGNoIGZhaWxzIHdpdGggYSBuZXR3b3JrLWxldmVsIGVycm9yIChlLmcuIEROUyBmYWlsdXJlLCBjb25uZWN0aW9uIHJlZnVzZWQpLlxuICpcbiAqIEBwcm9wZXJ0eSBjYXVzZSAtIE9yaWdpbmFsIGVycm9yIGZyb20gdGhlIHVuZGVybHlpbmcgYGZldGNoYCwgd2hlbiBhdmFpbGFibGVcbiAqL1xuZXhwb3J0IGNsYXNzIEZldGNoUmV0cmllck5ldHdvcmtFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ0ZldGNoUmV0cmllck5ldHdvcmtFcnJvcic7XG4gIC8qKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIEh1bWFuLXJlYWRhYmxlIHJlYXNvbiAoZGVmYXVsdDogYCdOZXR3b3JrIGVycm9yJ2ApXG4gICAqIEBwYXJhbSBjYXVzZSAtIE9yaWdpbmFsIGVycm9yIGZyb20gdGhlIHVuZGVybHlpbmcgYGZldGNoYCwgd2hlbiBhdmFpbGFibGVcbiAgICovXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSAnTmV0d29yayBlcnJvcicsIHB1YmxpYyByZWFkb25seSBjYXVzZT86IHVua25vd24pIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVyTmV0d29ya0Vycm9yLnByb3RvdHlwZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiB7QGxpbmsgUmVxdWVzdE9wdGlvbnN9IGNvbnRhaW5zIGludmFsaWQgbnVtZXJpYyB2YWx1ZXMuXG4gKlxuICogU3ViY2xhc3Mgb2Yge0BsaW5rIFR5cGVFcnJvcn0gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBgaW5zdGFuY2VvZiBUeXBlRXJyb3JgLiBEaXN0aW5jdCBmcm9tXG4gKiBuZXR3b3JrLWxldmVsIGBUeXBlRXJyb3JgIHZhbHVlcyB0aHJvd24gYnkgYGZldGNoYCwgd2hpY2ggYXJlIHJldHJpZWQgYW5kIHN1cmZhY2VkIGFzXG4gKiB7QGxpbmsgRmV0Y2hSZXRyaWVyTmV0d29ya0Vycm9yfSBhZnRlciB0aGUgbGFzdCBhdHRlbXB0LlxuICovXG5leHBvcnQgY2xhc3MgRmV0Y2hSZXRyaWVySW52YWxpZE9wdGlvbnNFcnJvciBleHRlbmRzIFR5cGVFcnJvciB7XG4gIG92ZXJyaWRlIHJlYWRvbmx5IG5hbWU6IHN0cmluZyA9ICdGZXRjaFJldHJpZXJJbnZhbGlkT3B0aW9uc0Vycm9yJztcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gSHVtYW4tcmVhZGFibGUgcmVhc29uIGRlc2NyaWJpbmcgdGhlIGludmFsaWQgb3B0aW9uXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgRmV0Y2hSZXRyaWVySW52YWxpZE9wdGlvbnNFcnJvci5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4gYW4gaW50ZXJuYWwgaW52YXJpYW50IGZhaWxzIChzaG91bGQgbm90IGhhcHBlbiBpbiBub3JtYWwgdXNlKS5cbiAqL1xuZXhwb3J0IGNsYXNzIEZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIG92ZXJyaWRlIHJlYWRvbmx5IG5hbWU6IHN0cmluZyA9ICdGZXRjaFJldHJpZXJVbnJlYWNoYWJsZUVycm9yJztcbiAgLyoqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gSHVtYW4tcmVhZGFibGUgcmVhc29uIChkZWZhdWx0OiBgJ1VucmVhY2hhYmxlJ2ApXG4gICAqL1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlID0gJ1VucmVhY2hhYmxlJykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBGZXRjaFJldHJpZXJVbnJlYWNoYWJsZUVycm9yLnByb3RvdHlwZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBIVFRQIHN0YXR1cyBjb2RlcyByZXRyaWVkIGJ5IGRlZmF1bHQgd2hlbiB7QGxpbmsgUmVxdWVzdE9wdGlvbnMuc2hvdWxkUmV0cnl9IGlzIG9taXR0ZWQuXG4gKlxuICogSW5jbHVkZXMgdHJhbnNpZW50IGNsaWVudC9zZXJ2ZXIgZXJyb3JzOiA0MDgsIDQyNSwgNDI5LCBhbmQgY29tbW9uIDV4eCBnYXRld2F5IG9yIG92ZXJsb2FkIHJlc3BvbnNlcy5cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfUkVUUllBQkxFX0hUVFBfU1RBVFVTRVM6IHJlYWRvbmx5IG51bWJlcltdID0gWzQwOCwgNDI1LCA0MjksIDUwMCwgNTAyLCA1MDMsIDUwNF07XG5cbi8qKlxuICogRGVmYXVsdCB7QGxpbmsgUmVxdWVzdE9wdGlvbnMuc2hvdWxkUmV0cnl9OiByZXRyaWVzIHJlc3BvbnNlcyB3aG9zZSBzdGF0dXMgaXMgaW5cbiAqIHtAbGluayBERUZBVUxUX1JFVFJZQUJMRV9IVFRQX1NUQVRVU0VTfS5cbiAqXG4gKiBDb21wb3NlIHdpdGggY3VzdG9tIGxvZ2ljLCBmb3IgZXhhbXBsZTpcbiAqIGAocmVzLCBib2R5KSA9PiBkZWZhdWx0U2hvdWxkUmV0cnkocmVzLCBib2R5KSB8fCByZXMuc3RhdHVzID09PSA0MThgLlxuICpcbiAqIEBwYXJhbSByZXNwb25zZSAtIFJlc3BvbnNlIGZyb20gdGhlIGZhaWxlZCBhdHRlbXB0XG4gKiBAcGFyYW0gX2JvZHkgLSBSZXNwb25zZSBib2R5IHRleHQgKHVudXNlZCBieSB0aGUgZGVmYXVsdCBwcmVkaWNhdGUpXG4gKiBAcmV0dXJucyBgdHJ1ZWAgd2hlbiBhbm90aGVyIGF0dGVtcHQgc2hvdWxkIGJlIHNjaGVkdWxlZFxuICovXG5leHBvcnQgY29uc3QgZGVmYXVsdFNob3VsZFJldHJ5ID0gKHJlc3BvbnNlOiBSZXNwb25zZSwgX2JvZHk6IHN0cmluZyk6IGJvb2xlYW4gPT4ge1xuICByZXR1cm4gREVGQVVMVF9SRVRSWUFCTEVfSFRUUF9TVEFUVVNFUy5pbmNsdWRlcyhyZXNwb25zZS5zdGF0dXMpO1xufTtcblxuLyoqXG4gKiBWYWxpZGF0ZXMgcmV0cnkgcG9saWN5IG51bWVyaWMgZmllbGRzIG9uIHtAbGluayBSZXF1ZXN0T3B0aW9uc30uXG4gKlxuICogQ29uc3RyYWludHM6IGByZXRyaWVzID49IDFgLCBgdGltZW91dE1zID4gMGAsIGBiYXNlQmFja29mZk1zID49IDBgLlxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9ucyB3aG9zZSBgcmV0cmllc2AsIGB0aW1lb3V0TXNgLCBhbmQgYGJhc2VCYWNrb2ZmTXNgIGFyZSBjaGVja2VkXG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJJbnZhbGlkT3B0aW9uc0Vycm9yfSBXaGVuIGFueSBjb25zdHJhaW50IGlzIHZpb2xhdGVkXG4gKi9cbmNvbnN0IHZhbGlkYXRlUmVxdWVzdE9wdGlvbnMgPSAob3B0aW9uczogUGljazxSZXF1ZXN0T3B0aW9ucywgJ3JldHJpZXMnIHwgJ3RpbWVvdXRNcycgfCAnYmFzZUJhY2tvZmZNcyc+KTogdm9pZCA9PiB7XG4gIGNvbnN0IHsgcmV0cmllcywgdGltZW91dE1zLCBiYXNlQmFja29mZk1zIH0gPSBvcHRpb25zO1xuXG4gIGlmIChyZXRyaWVzIDwgMSkge1xuICAgIHRocm93IG5ldyBGZXRjaFJldHJpZXJJbnZhbGlkT3B0aW9uc0Vycm9yKCdyZXRyaWVzIG11c3QgYmUgPj0gMScpO1xuICB9XG4gIGlmICh0aW1lb3V0TXMgPD0gMCkge1xuICAgIHRocm93IG5ldyBGZXRjaFJldHJpZXJJbnZhbGlkT3B0aW9uc0Vycm9yKCd0aW1lb3V0TXMgbXVzdCBiZSA+IDAnKTtcbiAgfVxuICBpZiAoYmFzZUJhY2tvZmZNcyA8IDApIHtcbiAgICB0aHJvdyBuZXcgRmV0Y2hSZXRyaWVySW52YWxpZE9wdGlvbnNFcnJvcignYmFzZUJhY2tvZmZNcyBtdXN0IGJlID49IDAnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBXcmFwcyBgZmV0Y2hgIHdpdGggcmV0cmllcywgcGVyLWF0dGVtcHQgdGltZW91dCwgUmV0cnktQWZ0ZXIgc3VwcG9ydCwgZnVsbC1qaXR0ZXIgYmFja29mZiwgYW5kXG4gKiBvcHRpb25hbCBjYW5jZWxsYXRpb24uXG4gKlxuICogRWFjaCBhdHRlbXB0IGNhbGxzIGBmZXRjaCh1cmwsIHsgLi4ub3B0aW9ucy5pbml0LCBoZWFkZXJzPywgc2lnbmFsIH0pYCB3aXRoIGFuIGludGVybmFsXG4gKiB7QGxpbmsgQWJvcnRTaWduYWx9IGZvciBgdGltZW91dE1zYC4gTm9uLU9LIHJlc3BvbnNlcyBhcmUgcmV0cmllZCB3aGVuIGBzaG91bGRSZXRyeWAgcmV0dXJuc1xuICogYHRydWVgIChkZWZhdWx0OiB7QGxpbmsgZGVmYXVsdFNob3VsZFJldHJ5fSkuIEJldHdlZW4gSFRUUCByZXRyaWVzLCBhIHZhbGlkIGBSZXRyeS1BZnRlcmBcbiAqIGhlYWRlciAoZGVsdGEtc2Vjb25kcyBvciBIVFRQLWRhdGUpIGlzIHByZWZlcnJlZCBvdmVyIGZ1bGwgaml0dGVyOyBhYm9ydCBhbmQgbmV0d29yayByZXRyaWVzXG4gKiBhbHdheXMgdXNlIGZ1bGwgaml0dGVyLiBUaGUgc2FtZSB7QGxpbmsgRmV0Y2hJbml0T3B0aW9uc30gKGluY2x1ZGluZyBgYm9keWApIGlzIHJldXNlZCBvblxuICogZXZlcnkgYXR0ZW1wdC5cbiAqXG4gKiBAcGFyYW0gdXJsIC0gUmVxdWVzdCBVUkwgcGFzc2VkIHRvIGBmZXRjaGBcbiAqIEBwYXJhbSBvcHRpb25zIC0ge0BsaW5rIFJlcXVlc3RPcHRpb25zfSBjb250cm9sbGluZyByZXRyaWVzLCB0aW1lb3V0LCByZXF1ZXN0IGluaXQsIGFuZCBjYW5jZWxsYXRpb25cbiAqIEByZXR1cm5zIFRoZSBmaXJzdCB7QGxpbmsgUmVzcG9uc2V9IGZvciB3aGljaCBgb2tgIGlzIGB0cnVlYFxuICogQHRocm93cyB7RmV0Y2hSZXRyaWVySW52YWxpZE9wdGlvbnNFcnJvcn0gSWYgYHJldHJpZXMgPCAxYCwgYHRpbWVvdXRNcyA8PSAwYCwgb3IgYGJhc2VCYWNrb2ZmTXMgPCAwYFxuICogQHRocm93cyB7RmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvcn0gSWYgYG9wdGlvbnMuc2lnbmFsYCBpcyBhbHJlYWR5IGFib3J0ZWQgYmVmb3JlIGFuIGF0dGVtcHRcbiAqIEB0aHJvd3Mge0ZldGNoUmV0cmllckh0dHBFcnJvcn0gT24gYSBub24tT0sgcmVzcG9uc2UgdGhhdCBpcyBub3QgcmV0cmllZCBvciBhZnRlciB0aGUgbGFzdCBhdHRlbXB0XG4gKiAgIChpbmNsdWRlcyBgc3RhdHVzYCBhbmQgYGJvZHlgKVxuICogQHRocm93cyB7RmV0Y2hSZXRyaWVyTmV0d29ya0Vycm9yfSBPbiBhIG5ldHdvcmsgYFR5cGVFcnJvcmAgYWZ0ZXIgdGhlIGxhc3QgYXR0ZW1wdFxuICogQHRocm93cyB7RmV0Y2hSZXRyaWVyQWJvcnRFcnJvcn0gT24gdGltZW91dCBvciBleHRlcm5hbCBhYm9ydCBhZnRlciB0aGUgbGFzdCBhdHRlbXB0XG4gKiBAdGhyb3dzIHtGZXRjaFJldHJpZXJVbnJlYWNoYWJsZUVycm9yfSBJZiB0aGUgcmV0cnkgbG9vcCBleGl0cyB3aXRob3V0IHJldHVybmluZyAoaW50ZXJuYWwgYnVnKVxuICovXG5leHBvcnQgY29uc3QgZmV0Y2hSZXRyaWVyID0gYXN5bmMgKHVybDogc3RyaW5nLCBvcHRpb25zOiBSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8UmVzcG9uc2U+ID0+IHtcbiAgY29uc3Qge1xuICAgIGhlYWRlcnMsXG4gICAgaW5pdCxcbiAgICByZXRyaWVzLFxuICAgIHRpbWVvdXRNcyxcbiAgICBiYXNlQmFja29mZk1zLFxuICAgIHNpZ25hbDogZXh0ZXJuYWxTaWduYWwsXG4gICAgc2hvdWxkUmV0cnkgPSBkZWZhdWx0U2hvdWxkUmV0cnksXG4gIH0gPSBvcHRpb25zO1xuXG4gIHZhbGlkYXRlUmVxdWVzdE9wdGlvbnMoeyByZXRyaWVzLCB0aW1lb3V0TXMsIGJhc2VCYWNrb2ZmTXMgfSk7XG5cbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IGF0dGVtcHQgPD0gcmV0cmllczsgYXR0ZW1wdCsrKSB7XG4gICAgaWYgKGV4dGVybmFsU2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRmV0Y2hSZXRyaWVyQWxyZWFkeUFib3J0ZWRFcnJvcigpO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IGNvbnRyb2xsZXIuYWJvcnQoKSwgdGltZW91dE1zKTtcblxuICAgIGNvbnN0IG9uRXh0ZXJuYWxBYm9ydCA9ICgpOiB2b2lkID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICBjb250cm9sbGVyLmFib3J0KCk7XG4gICAgfTtcblxuICAgIGlmIChleHRlcm5hbFNpZ25hbCkge1xuICAgICAgZXh0ZXJuYWxTaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkV4dGVybmFsQWJvcnQpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICAgICAgLi4uaW5pdCxcbiAgICAgICAgLi4uKGhlYWRlcnMgIT09IHVuZGVmaW5lZCA/IHsgaGVhZGVycyB9IDoge30pLFxuICAgICAgICBzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgfSk7XG5cbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICBleHRlcm5hbFNpZ25hbD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkV4dGVybmFsQWJvcnQpO1xuXG4gICAgICBpZiAocmVzLm9rKSB7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZXMudGV4dCgpO1xuICAgICAgY29uc3QgaXNDb250aW51ZSA9IHNob3VsZFJldHJ5KHJlcywgdGV4dCk7XG5cbiAgICAgIGlmIChpc0NvbnRpbnVlKSB7XG4gICAgICAgIGlmIChhdHRlbXB0ID09PSByZXRyaWVzKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEZldGNoUmV0cmllckh0dHBFcnJvcihgSFRUUCAke3Jlcy5zdGF0dXN9YCwgcmVzLnN0YXR1cywgdGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgd2FpdChyZXNvbHZlUmV0cnlEZWxheU1zKHJlcywgYmFzZUJhY2tvZmZNcywgYXR0ZW1wdCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEZldGNoUmV0cmllckh0dHBFcnJvcihgTm9uLXJldHJpYWJsZSBIVFRQIGVycm9yOiAke3Jlcy5zdGF0dXN9YCwgcmVzLnN0YXR1cywgdGV4dCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgZXh0ZXJuYWxTaWduYWw/LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25FeHRlcm5hbEFib3J0KTtcblxuICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yICYmIGVyci5uYW1lID09PSAnQWJvcnRFcnJvcicpIHtcbiAgICAgICAgaWYgKGF0dGVtcHQgPT09IHJldHJpZXMpIHRocm93IGVyciBpbnN0YW5jZW9mIEZldGNoUmV0cmllckFib3J0RXJyb3IgPyBlcnIgOiBuZXcgRmV0Y2hSZXRyaWVyQWJvcnRFcnJvcigpO1xuICAgICAgICBhd2FpdCB3YWl0KGZ1bGxKaXR0ZXIoYmFzZUJhY2tvZmZNcywgYXR0ZW1wdCkpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIFR5cGVFcnJvcikge1xuICAgICAgICBpZiAoYXR0ZW1wdCA9PT0gcmV0cmllcykgdGhyb3cgbmV3IEZldGNoUmV0cmllck5ldHdvcmtFcnJvcignTmV0d29yayBlcnJvcicsIGVycik7XG4gICAgICAgIGF3YWl0IHdhaXQoZnVsbEppdHRlcihiYXNlQmFja29mZk1zLCBhdHRlbXB0KSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IEZldGNoUmV0cmllclVucmVhY2hhYmxlRXJyb3IoKTtcbn07XG5cbi8qKlxuICogRGVsYXlzIGV4ZWN1dGlvbiBmb3IgdGhlIGdpdmVuIGR1cmF0aW9uICh1c2VkIGJldHdlZW4gcmV0cnkgYXR0ZW1wdHMpLlxuICpcbiAqIEBwYXJhbSBtcyAtIERlbGF5IGluIG1pbGxpc2Vjb25kc1xuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgYG1zYFxuICovXG5jb25zdCB3YWl0ID0gKG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG59O1xuXG4vKipcbiAqIEZ1bGwgaml0dGVyIGJhY2tvZmY6IHJhbmRvbSBkZWxheSBpbiBgWzAsIGJhc2UgKiAyXmF0dGVtcHQpYCBtcyAoQVdTLXJlY29tbWVuZGVkIHBhdHRlcm4pLlxuICpcbiAqIFVzZWQgYmV0d2VlbiBhYm9ydC9uZXR3b3JrIHJldHJpZXMsIGFuZCBhcyB0aGUgZmFsbGJhY2sgd2hlbiBIVFRQIHJldHJpZXMgbGFjayBhIHVzYWJsZVxuICogYFJldHJ5LUFmdGVyYCBoZWFkZXIuXG4gKlxuICogQHBhcmFtIGJhc2UgLSBCYXNlIGJhY2tvZmYgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcGFyYW0gYXR0ZW1wdCAtIDEtYmFzZWQgYXR0ZW1wdCBpbmRleCAoZmlyc3QgcmV0cnkgdXNlcyBgYXR0ZW1wdCA9PT0gMWApXG4gKiBAcmV0dXJucyBXYWl0IGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcyBiZWZvcmUgdGhlIG5leHQgYXR0ZW1wdFxuICovXG5jb25zdCBmdWxsSml0dGVyID0gKGJhc2U6IG51bWJlciwgYXR0ZW1wdDogbnVtYmVyKTogbnVtYmVyID0+IHtcbiAgY29uc3QgY2FwID0gYmFzZSAqIE1hdGgucG93KDIsIGF0dGVtcHQpO1xuICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogY2FwKTtcbn07XG5cbi8qKlxuICogUGFyc2VzIGEgYFJldHJ5LUFmdGVyYCBoZWFkZXIgdmFsdWUgaW50byBhIGRlbGF5IGluIG1pbGxpc2Vjb25kcy5cbiAqXG4gKiBTdXBwb3J0cyBSRkMgNzIzMSBmb3Jtczogbm9uLW5lZ2F0aXZlIGludGVnZXIgZGVsdGEtc2Vjb25kcywgb3IgYW4gSFRUUC1kYXRlLiBFbXB0eSB2YWx1ZXMsXG4gKiBub24taW50ZWdlciBudW1lcmljcyAoZS5nLiBmbG9hdHMgb3IgbmVnYXRpdmVzKSwgYW5kIHVucGFyc2FibGUgZGF0ZXMgeWllbGQgYHVuZGVmaW5lZGAgc29cbiAqIGNhbGxlcnMgY2FuIGZhbGwgYmFjayB0byBmdWxsIGppdHRlci4gQW4gSFRUUC1kYXRlIGluIHRoZSBwYXN0IHlpZWxkcyBgMGAuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gUmF3IGBSZXRyeS1BZnRlcmAgaGVhZGVyIHZhbHVlXG4gKiBAcGFyYW0gbm93TXMgLSBDdXJyZW50IHRpbWUgaW4gbWlsbGlzZWNvbmRzIChpbmplY3RhYmxlIGZvciB0ZXN0cylcbiAqIEByZXR1cm5zIERlbGF5IGluIG1pbGxpc2Vjb25kcywgb3IgYHVuZGVmaW5lZGAgd2hlbiB0aGUgdmFsdWUgY2Fubm90IGJlIHBhcnNlZFxuICovXG5leHBvcnQgY29uc3QgcGFyc2VSZXRyeUFmdGVyTXMgPSAodmFsdWU6IHN0cmluZywgbm93TXM6IG51bWJlciA9IERhdGUubm93KCkpOiBudW1iZXIgfCB1bmRlZmluZWQgPT4ge1xuICBjb25zdCB0cmltbWVkID0gdmFsdWUudHJpbSgpO1xuICBpZiAodHJpbW1lZCA9PT0gJycpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgaWYgKC9eXFxkKyQvLnRlc3QodHJpbW1lZCkpIHtcbiAgICByZXR1cm4gTnVtYmVyLnBhcnNlSW50KHRyaW1tZWQsIDEwKSAqIDEwMDA7XG4gIH1cblxuICAvLyBSZWplY3Qgb3RoZXIgbnVtZXJpYyBmb3JtcyAoZmxvYXRzLCBuZWdhdGl2ZXMpOyBub3QgdmFsaWQgZGVsdGEtc2Vjb25kcyBvciBIVFRQLWRhdGUuXG4gIGlmICgvXi0/XFxkKyhcXC5cXGQrKT8kLy50ZXN0KHRyaW1tZWQpKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IGRhdGVNcyA9IERhdGUucGFyc2UodHJpbW1lZCk7XG4gIGlmIChOdW1iZXIuaXNOYU4oZGF0ZU1zKSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICByZXR1cm4gTWF0aC5tYXgoMCwgZGF0ZU1zIC0gbm93TXMpO1xufTtcblxuLyoqXG4gKiBDaG9vc2VzIHRoZSBkZWxheSBiZWZvcmUgdGhlIG5leHQgSFRUUCByZXRyeTogcHJlZmVyIGEgdmFsaWQgYFJldHJ5LUFmdGVyYCwgZWxzZSBmdWxsIGppdHRlci5cbiAqXG4gKiBSZWFkcyBgcmVzcG9uc2UuaGVhZGVycy5nZXQoJ1JldHJ5LUFmdGVyJylgIGFuZCBwYXJzZXMgaXQgd2l0aCB7QGxpbmsgcGFyc2VSZXRyeUFmdGVyTXN9LlxuICogTWlzc2luZyBoZWFkZXJzLCBvciB2YWx1ZXMgdGhhdCBwYXJzZSB0byBgdW5kZWZpbmVkYCwgZmFsbCBiYWNrIHRvIHtAbGluayBmdWxsSml0dGVyfS5cbiAqIEFib3J0IGFuZCBuZXR3b3JrIHJldHJpZXMgZG8gbm90IHVzZSB0aGlzIGhlbHBlci5cbiAqXG4gKiBAcGFyYW0gcmVzcG9uc2UgLSBOb24tT0sgcmVzcG9uc2UgZnJvbSB0aGUgY3VycmVudCBhdHRlbXB0XG4gKiBAcGFyYW0gYmFzZUJhY2tvZmZNcyAtIEJhc2UgYmFja29mZiBwYXNzZWQgdG8ge0BsaW5rIGZ1bGxKaXR0ZXJ9IHdoZW4gZmFsbGluZyBiYWNrXG4gKiBAcGFyYW0gYXR0ZW1wdCAtIDEtYmFzZWQgYXR0ZW1wdCBpbmRleFxuICogQHBhcmFtIG5vd01zIC0gQ3VycmVudCB0aW1lIGluIG1pbGxpc2Vjb25kcyAoaW5qZWN0YWJsZSBmb3IgdGVzdHMpXG4gKiBAcmV0dXJucyBXYWl0IGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcyBiZWZvcmUgdGhlIG5leHQgYXR0ZW1wdFxuICovXG5jb25zdCByZXNvbHZlUmV0cnlEZWxheU1zID0gKFxuICByZXNwb25zZTogUmVzcG9uc2UsXG4gIGJhc2VCYWNrb2ZmTXM6IG51bWJlcixcbiAgYXR0ZW1wdDogbnVtYmVyLFxuICBub3dNczogbnVtYmVyID0gRGF0ZS5ub3coKSxcbik6IG51bWJlciA9PiB7XG4gIGNvbnN0IGhlYWRlciA9IHJlc3BvbnNlLmhlYWRlcnM/LmdldCgnUmV0cnktQWZ0ZXInKTtcbiAgaWYgKGhlYWRlciA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGZ1bGxKaXR0ZXIoYmFzZUJhY2tvZmZNcywgYXR0ZW1wdCk7XG4gIH1cblxuICBjb25zdCBmcm9tSGVhZGVyID0gcGFyc2VSZXRyeUFmdGVyTXMoaGVhZGVyLCBub3dNcyk7XG4gIGlmIChmcm9tSGVhZGVyID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZnVsbEppdHRlcihiYXNlQmFja29mZk1zLCBhdHRlbXB0KTtcbiAgfVxuXG4gIHJldHVybiBmcm9tSGVhZGVyO1xufTtcbiJdfQ==
package/package.json CHANGED
@@ -43,20 +43,26 @@
43
43
  "eslint-plugin-import": "^2.32.0",
44
44
  "jest": "^30.4.2",
45
45
  "jest-junit": "^17",
46
- "projen": "^0.101.20",
46
+ "projen": "^0.101.23",
47
47
  "ts-jest": "^29.4.12",
48
48
  "ts-node": "^10.9.2",
49
- "typescript": "5.9.x"
49
+ "typescript": "6.0.x"
50
50
  },
51
51
  "engines": {
52
52
  "node": ">= 20.0.0"
53
53
  },
54
+ "devEngines": {
55
+ "packageManager": {
56
+ "name": "npm",
57
+ "onFail": "ignore"
58
+ }
59
+ },
54
60
  "main": "lib/index.js",
55
61
  "license": "Apache-2.0",
56
62
  "publishConfig": {
57
63
  "access": "public"
58
64
  },
59
- "version": "0.4.4",
65
+ "version": "0.5.0",
60
66
  "jest": {
61
67
  "coverageProvider": "v8",
62
68
  "testMatch": [