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.
- package/.devcontainer/devcontainer.json +4 -3
- package/README.md +37 -16
- package/lib/index.d.ts +33 -8
- package/lib/index.js +78 -10
- package/package.json +9 -3
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dev-fetch-retrier",
|
|
3
|
-
"image": "mcr.microsoft.com/devcontainers/base:
|
|
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:
|
|
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
|
[](https://www.npmjs.com/package/fetch-retrier)
|
|
6
4
|
[](https://www.npmjs.com/package/fetch-retrier)
|
|
7
5
|
[](https://github.com/gammarers-labs/fetch-retrier/actions/workflows/build.yml)
|
|
8
6
|
[](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
|
-
- **
|
|
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
|
|
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 ===
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
46
|
-
*
|
|
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
|
|
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
|
|
161
|
-
*
|
|
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,
|
|
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
|
|
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
|
|
152
|
-
*
|
|
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(
|
|
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.
|
|
46
|
+
"projen": "^0.101.23",
|
|
47
47
|
"ts-jest": "^29.4.12",
|
|
48
48
|
"ts-node": "^10.9.2",
|
|
49
|
-
"typescript": "
|
|
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.
|
|
65
|
+
"version": "0.5.0",
|
|
60
66
|
"jest": {
|
|
61
67
|
"coverageProvider": "v8",
|
|
62
68
|
"testMatch": [
|