athena-query-result-pager 0.5.7 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  ![npm](https://img.shields.io/npm/v/athena-query-result-pager)
4
4
  ![license](https://img.shields.io/npm/l/athena-query-result-pager)
5
5
 
6
- Paginate [AWS Athena](https://docs.aws.amazon.com/athena/latest/ug/v3-sdk.html) **`GetQueryResults`** calls with AWS SDK v3. This library walks **`NextToken`**, parses tabular rows with [athena-query-result-parser](https://www.npmjs.com/package/athena-query-result-parser) (0.5+), and forwards **`MaxResults`**, **`QueryResultType`**, and optional **`ParseResultSetOptions`** from **[PagerOptions](#options)** on every page fetch.
6
+ Paginate [AWS Athena](https://docs.aws.amazon.com/athena/latest/ug/v3-sdk.html) **`GetQueryResults`** calls with AWS SDK v3. This library walks **`NextToken`**, parses tabular rows with [athena-query-result-parser](https://www.npmjs.com/package/athena-query-result-parser) (0.6+), and forwards **`MaxResults`**, **`QueryResultType`**, and optional **`ParseResultSetOptions`** from **[PagerOptions](#options)** on every page fetch.
7
7
 
8
8
  Page-level and row-level APIs are symmetric: use the base method for raw **`ParsedRow`** values, or the `*With` / `rowParser` variant for custom types.
9
9
 
@@ -28,13 +28,13 @@ Both still require a finished query execution and rely on your **`AthenaClient`*
28
28
 
29
29
  - Sends paginated Athena **`GetQueryResults`** requests (`NextToken` / **`MaxResults`**).
30
30
  - Forwards **`QueryResultType`** from the pager constructor on each request — accepts the full AWS SDK enum (**`QueryResultType.DATA_ROWS`**, **`QueryResultType.DATA_MANIFEST`**, …). Use **`QueryResultType.DATA_MANIFEST`** for CTAS / UNLOAD / INSERT manifest workflows when Athena allows it.
31
- - Forwards **`parseResultSetOptions`** to every parser invocation — **`columnCountMismatchBehavior`**, **`skipHeaderRow`**, **`headerRowDetectionStrategy`**, **`unavailableResultBehavior`**, **`maxRows`**, and other [parser 0.5+ options](https://www.npmjs.com/package/athena-query-result-parser).
31
+ - Forwards **`parseResultSetOptions`** to every parser invocation — **`columnCountMismatchBehavior`**, **`skipHeaderRow`**, **`headerRowDetectionStrategy`**, **`unavailableResultBehavior`**, **`maxRows`**, and other [parser 0.6+ options](https://www.npmjs.com/package/athena-query-result-parser).
32
32
  - **Paired APIs** for raw **`ParsedRow`** dictionaries versus typed rows via **`RowParser<T>`**:
33
- - Page level: **`fetchPage`** / **`fetchPageWith`**, **`iteratePages`** / **`iteratePagesWith`**
33
+ - Page level: **`fetchPage`** / **`fetchPageWith`**, **`fetchPageDetailed`** (with **`ParseResultSetDiagnostics`**), **`iteratePages`** / **`iteratePagesWith`** / **`iteratePagesDetailed`**
34
34
  - Row level: **`iterateRows`** (no parser) / **`iterateRows`** (with **`rowParser`**)
35
35
  - Async generators iterate **page-by-page** or **row-by-row** without holding full result sets in memory (only one page of rows is buffered at a time for row iterators).
36
- - Fail-fast validation: **`maxResults`** must be an integer in **`1..1000`**; **`queryExecutionId`** must be non-empty (**`fetchPage`**, **`fetchPageWith`**).
37
- - Re-exports **`QueryResultType`**, parser types (**`ParseResultSetOptions`**, **`ParsedRow`**, **`RowParser<T>`**, …), and parser utilities (**`rowToTypedObject`**, **`parseResultSetOnce`**, **`EXTRA_COLUMNS_KEY`**, …) from the package entry point.
36
+ - Fail-fast validation with typed errors (**`AthenaQueryResultPagerError`** hierarchy): **`maxResults`** must be an integer in **`1..1000`**; **`queryExecutionId`** must be non-empty (**`fetchPage`**, **`fetchPageWith`**).
37
+ - Re-exports **`QueryResultType`**, parser types (**`ParseResultSetOptions`**, **`ParsedRow`**, **`RowParser<T>`**, …), parser error classes (**`AthenaQueryResultParserError`**, …), and parser utilities (**`rowToTypedObject`**, **`parseResultSetOnce`**, **`EXTRA_COLUMNS_KEY`**, …) from the package entry point.
38
38
  - Helpers: **`AthenaQueryResultPager.hasNextPage`**, **`getLastHeaderRowDecision()`**, and **`reset()`** (usually optional — parser state resets automatically when **`queryExecutionId`** changes).
39
39
  - Does **not** wait for query completion or add Athena-specific retry beyond the AWS SDK client — see **[Caller responsibilities](#caller-responsibilities)**.
40
40
 
@@ -52,7 +52,7 @@ yarn add athena-query-result-pager
52
52
  pnpm add athena-query-result-pager
53
53
  ```
54
54
 
55
- Runtime dependencies: `@aws-sdk/client-athena`, `athena-query-result-parser` **`^0.5.0`**. Your application typically already instantiates **`AthenaClient`** with credentials and Region.
55
+ Runtime dependencies: `@aws-sdk/client-athena`, `athena-query-result-parser` **`^0.6.0`**. Your application typically already instantiates **`AthenaClient`** with credentials and Region.
56
56
 
57
57
  ## Usage
58
58
 
@@ -75,7 +75,7 @@ const manifestPager = new AthenaQueryResultPager(client, {
75
75
  queryResultType: QueryResultType.DATA_MANIFEST,
76
76
  });
77
77
 
78
- // Parser options (athena-query-result-parser 0.5+), applied on every page parse:
78
+ // Parser options (athena-query-result-parser 0.6+), applied on every page parse:
79
79
  const strictPager = new AthenaQueryResultPager(client, {
80
80
  parseResultSetOptions: {
81
81
  columnCountMismatchBehavior: 'throw',
@@ -97,6 +97,15 @@ if (AthenaQueryResultPager.hasNextPage(page)) {
97
97
  }
98
98
  ```
99
99
 
100
+ ### Fetch one page with parse diagnostics
101
+
102
+ When you need per-page parser diagnostics (`headerRowDecision`, `rawRowCount`, `truncatedByMaxRows`, …), use **`fetchPageDetailed`**:
103
+
104
+ ```ts
105
+ const page = await pager.fetchPageDetailed('query-execution-id');
106
+ console.log(page.rows, page.diagnostics.headerRowDecision, page.diagnostics.rawRowCount);
107
+ ```
108
+
100
109
  ### Fetch one page with a custom row parser
101
110
 
102
111
  ```ts
@@ -123,6 +132,11 @@ for await (const page of pager.iteratePages('query-execution-id')) {
123
132
  console.log(page.rowCount, page.rows);
124
133
  }
125
134
 
135
+ // With parse diagnostics per page
136
+ for await (const page of pager.iteratePagesDetailed('query-execution-id')) {
137
+ console.log(page.rowCount, page.diagnostics.truncatedByMaxRows);
138
+ }
139
+
126
140
  // With custom row parser
127
141
  for await (const page of pager.iteratePagesWith('query-execution-id', rowParser)) {
128
142
  console.log(page.rowCount, page.rows);
@@ -145,9 +159,13 @@ for await (const row of pager.iterateRows('query-execution-id', rowParser)) {
145
159
 
146
160
  ### Inspect header-row skipping
147
161
 
148
- When **`parseResultSetOptions.skipHeaderRow`** is **`'auto'`**, check whether the first row was skipped:
162
+ When **`parseResultSetOptions.skipHeaderRow`** is **`'auto'`**, check whether the first row was skipped — either from the latest page diagnostics or via the pager helper:
149
163
 
150
164
  ```ts
165
+ const page = await pager.fetchPageDetailed('query-execution-id');
166
+ console.log(page.diagnostics.headerRowDecision?.skipped, page.diagnostics.headerRowDecision?.reason);
167
+
168
+ // Or after fetchPage / fetchPageWith:
151
169
  await pager.fetchPage('query-execution-id');
152
170
  const decision = pager.getLastHeaderRowDecision();
153
171
  console.log(decision?.skipped, decision?.reason);
@@ -178,7 +196,7 @@ Handle the following in the calling application (or via **`AthenaClient`** confi
178
196
  - **`maxResults?: number`**
179
197
  - Default **`1000`**.
180
198
  - Valid range: integer **`1..1000`** (Athena **`GetQueryResults`** limit).
181
- - Throws **`RangeError`** when invalid (**constructor**).
199
+ - Throws **`AthenaQueryResultPagerInvalidMaxResultsError`** when invalid (**constructor**).
182
200
  - **`queryResultType?: QueryResultType`**
183
201
  - Type is the AWS SDK **`QueryResultType`** enum (**`QueryResultType.DATA_ROWS`**, **`QueryResultType.DATA_MANIFEST`**, …) — not restricted to a single literal.
184
202
  - Import **`QueryResultType`** from **`athena-query-result-pager`** (re-exported from **`@aws-sdk/client-athena`**).
@@ -195,7 +213,7 @@ Handle the following in the calling application (or via **`AthenaClient`** confi
195
213
  - **`fetchPage(queryExecutionId, nextToken?)`**
196
214
  - **`fetchPageWith(queryExecutionId, rowParser, nextToken?)`**
197
215
 
198
- Both throw if **`queryExecutionId`** is empty or whitespace-only (before invoking AWS).
216
+ **`fetchPage`**, **`fetchPageDetailed`**, and **`fetchPageWith`** throw **`AthenaQueryResultPagerEmptyQueryExecutionIdError`** if **`queryExecutionId`** is empty or whitespace-only (before invoking AWS). Parser errors from **`athena-query-result-parser`** are propagated unchanged (not wrapped in pager errors).
199
217
 
200
218
  ## API
201
219
 
@@ -203,8 +221,10 @@ Both throw if **`queryExecutionId`** is empty or whitespace-only (before invokin
203
221
 
204
222
  - **`constructor(client: AthenaClient, options?: PagerOptions)`**
205
223
  - **`fetchPage(queryExecutionId, nextToken?)`** → **`Promise<PageResult<ParsedRow>>`**
224
+ - **`fetchPageDetailed(queryExecutionId, nextToken?)`** → **`Promise<PageDetailedResult>`** (includes **`ParseResultSetDiagnostics`**)
206
225
  - **`fetchPageWith<T>(queryExecutionId, rowParser, nextToken?)`** → **`Promise<PageResult<T>>`**
207
226
  - **`iteratePages(queryExecutionId)`** → **`AsyncGenerator<PageResult<ParsedRow>>`**
227
+ - **`iteratePagesDetailed(queryExecutionId)`** → **`AsyncGenerator<PageDetailedResult>`**
208
228
  - **`iteratePagesWith<T>(queryExecutionId, rowParser)`** → **`AsyncGenerator<PageResult<T>>`**
209
229
  - **`iterateRows(queryExecutionId)`** → **`AsyncGenerator<ParsedRow>`**
210
230
  - **`iterateRows<T>(queryExecutionId, rowParser)`** → **`AsyncGenerator<T>`**
@@ -212,19 +232,29 @@ Both throw if **`queryExecutionId`** is empty or whitespace-only (before invokin
212
232
  - **`reset()`** — clears bundled parser state (**header row bookkeeping**). Usually unnecessary: **`fetchPage`** / **`fetchPageWith`** reset automatically when **`queryExecutionId`** changes.
213
233
  - **`static hasNextPage<T>(pageResult: PageResult<T>)`** → **`boolean`**
214
234
 
235
+ ### Errors
236
+
237
+ - **`AthenaQueryResultPagerError`** — abstract base; **`code`** is a stable machine-readable identifier
238
+ - **`AthenaQueryResultPagerEmptyQueryExecutionIdError`** — **`code`**: `'empty-query-execution-id'` (fetch methods)
239
+ - **`AthenaQueryResultPagerInvalidMaxResultsError`** — **`code`**: `'invalid-max-results'` (**constructor**); exposes **`maxResults`**
240
+
241
+ Parser errors (**`AthenaQueryResultParserError`** and subclasses) are re-exported from **`athena-query-result-parser`** and are not wrapped by the pager.
242
+
215
243
  ### Types and re-exports
216
244
 
217
245
  - **`PageResult<T>`** — **`{ rows: T[]; nextToken?: string; rowCount: number }`**
246
+ - **`PageDetailedResult`** — **`PageResult<ParsedRow>`** plus **`diagnostics: ParseResultSetDiagnostics`**
218
247
  - **`PagerOptions`** — **`{ maxResults?: number; queryResultType?: QueryResultType; parseResultSetOptions?: ParseResultSetOptions }`**
219
248
  - **`QueryResultType`** — enum re-exported from **`@aws-sdk/client-athena`** (**`DATA_ROWS`**, **`DATA_MANIFEST`**, …)
220
249
  - **`ParseResultSetOptions`**, **`ColumnCountMismatchBehavior`**, **`HeaderRowDecision`**, **`ParsedRow`**, **`RowParser<T>`**, **`TypedParsedRow`**, **`AthenaTypedValue`**, **`UnavailableResultBehavior`**, **`MaxRowsExceededBehavior`**, **`ParseResultSetUnavailableReason`**, **`ParseResultSetDiagnostics`**, **`ParseResultSetDetailedResult`**, **`ParserReusePolicy`**, **`AthenaQueryResultParserOptions`** — re-exported from **`athena-query-result-parser`**
250
+ - **`AthenaQueryResultParserError`**, **`AthenaQueryResultParserColumnCountMismatchError`**, **`AthenaQueryResultParserDuplicateColumnNameError`**, **`AthenaQueryResultParserHeaderRowMismatchError`**, **`AthenaQueryResultParserUnavailableResultError`**, **`AthenaQueryResultParserInvalidMaxRowsError`**, **`AthenaQueryResultParserMaxRowsExceededError`** — re-exported parser error classes (0.6+)
221
251
  - **`EXTRA_COLUMNS_KEY`**, **`toNumber`**, **`toBoolean`**, **`toDate`**, **`headersFromMeta`**, **`rowToObject`**, **`rowToTypedObject`**, **`isHeaderRow`**, **`parseResultSetOnce`**, **`parseResultSetDetailedOnce`**, **`parseResultSetIterOnce`**, **`parseResultSetWithOnce`** — re-exported parser utilities
222
252
 
223
253
  ## Requirements
224
254
 
225
255
  - Node.js **`>= 20.0.0`**
226
256
  - **`@aws-sdk/client-athena`** — provide **`AthenaClient`**; **`QueryResultType`** is also re-exported by this package
227
- - **`athena-query-result-parser`** **`^0.5.0`**
257
+ - **`athena-query-result-parser`** **`^0.6.0`**
228
258
 
229
259
  ## License
230
260
 
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Base error thrown by {@link AthenaQueryResultPager} validation.
3
+ *
4
+ * Catch this type to handle every pager-initiated failure, or catch a subclass for a
5
+ * specific case. {@link code} is a stable machine-readable identifier.
6
+ *
7
+ * Errors propagated from {@link AthenaQueryResultParser} are **not** wrapped; they
8
+ * remain {@link AthenaQueryResultParserError} (or subclasses) when thrown by the parser.
9
+ */
10
+ export declare abstract class AthenaQueryResultPagerError extends Error {
11
+ /**
12
+ * Stable error code for logging, metrics, and programmatic handling.
13
+ */
14
+ abstract readonly code: string;
15
+ protected constructor(message: string);
16
+ }
17
+ /**
18
+ * Thrown when `queryExecutionId` is empty or whitespace only.
19
+ */
20
+ export declare class AthenaQueryResultPagerEmptyQueryExecutionIdError extends AthenaQueryResultPagerError {
21
+ readonly code: "empty-query-execution-id";
22
+ constructor();
23
+ }
24
+ /**
25
+ * Thrown when `options.maxResults` is not an integer in `1..1000` inclusive.
26
+ */
27
+ export declare class AthenaQueryResultPagerInvalidMaxResultsError extends AthenaQueryResultPagerError {
28
+ readonly code: "invalid-max-results";
29
+ /**
30
+ * The invalid `maxResults` value that was supplied.
31
+ */
32
+ readonly maxResults: number;
33
+ constructor(maxResults: number);
34
+ }
package/lib/errors.js ADDED
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AthenaQueryResultPagerInvalidMaxResultsError = exports.AthenaQueryResultPagerEmptyQueryExecutionIdError = exports.AthenaQueryResultPagerError = void 0;
4
+ /** Minimum `MaxResults` value allowed by Athena `GetQueryResults`. */
5
+ const MIN_MAX_RESULTS = 1;
6
+ /** Maximum `MaxResults` value allowed by Athena `GetQueryResults`. */
7
+ const MAX_MAX_RESULTS = 1000;
8
+ const EMPTY_QUERY_EXECUTION_ID_MESSAGE = 'queryExecutionId must be a non-empty string';
9
+ const describeInvalidMaxResults = (maxResults) => `options.maxResults must be an integer between ${MIN_MAX_RESULTS} and ${MAX_MAX_RESULTS}, got ${String(maxResults)}`;
10
+ /**
11
+ * Base error thrown by {@link AthenaQueryResultPager} validation.
12
+ *
13
+ * Catch this type to handle every pager-initiated failure, or catch a subclass for a
14
+ * specific case. {@link code} is a stable machine-readable identifier.
15
+ *
16
+ * Errors propagated from {@link AthenaQueryResultParser} are **not** wrapped; they
17
+ * remain {@link AthenaQueryResultParserError} (or subclasses) when thrown by the parser.
18
+ */
19
+ class AthenaQueryResultPagerError extends Error {
20
+ constructor(message) {
21
+ super(message);
22
+ this.name = new.target.name;
23
+ Object.setPrototypeOf(this, new.target.prototype);
24
+ }
25
+ }
26
+ exports.AthenaQueryResultPagerError = AthenaQueryResultPagerError;
27
+ /**
28
+ * Thrown when `queryExecutionId` is empty or whitespace only.
29
+ */
30
+ class AthenaQueryResultPagerEmptyQueryExecutionIdError extends AthenaQueryResultPagerError {
31
+ constructor() {
32
+ super(EMPTY_QUERY_EXECUTION_ID_MESSAGE);
33
+ this.code = 'empty-query-execution-id';
34
+ }
35
+ }
36
+ exports.AthenaQueryResultPagerEmptyQueryExecutionIdError = AthenaQueryResultPagerEmptyQueryExecutionIdError;
37
+ /**
38
+ * Thrown when `options.maxResults` is not an integer in `1..1000` inclusive.
39
+ */
40
+ class AthenaQueryResultPagerInvalidMaxResultsError extends AthenaQueryResultPagerError {
41
+ constructor(maxResults) {
42
+ super(describeInvalidMaxResults(maxResults));
43
+ this.code = 'invalid-max-results';
44
+ this.maxResults = maxResults;
45
+ }
46
+ }
47
+ exports.AthenaQueryResultPagerInvalidMaxResultsError = AthenaQueryResultPagerInvalidMaxResultsError;
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Vycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxzRUFBc0U7QUFDdEUsTUFBTSxlQUFlLEdBQUcsQ0FBQyxDQUFDO0FBQzFCLHNFQUFzRTtBQUN0RSxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUM7QUFFN0IsTUFBTSxnQ0FBZ0MsR0FBRyw2Q0FBNkMsQ0FBQztBQUV2RixNQUFNLHlCQUF5QixHQUFHLENBQUMsVUFBa0IsRUFBVSxFQUFFLENBQy9ELGlEQUFpRCxlQUFlLFFBQVEsZUFBZSxTQUFTLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO0FBRXZIOzs7Ozs7OztHQVFHO0FBQ0gsTUFBc0IsMkJBQTRCLFNBQVEsS0FBSztJQU03RCxZQUFzQixPQUFlO1FBQ25DLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNmLElBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7UUFDNUIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNwRCxDQUFDO0NBQ0Y7QUFYRCxrRUFXQztBQUVEOztHQUVHO0FBQ0gsTUFBYSxnREFBaUQsU0FBUSwyQkFBMkI7SUFHL0Y7UUFDRSxLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztRQUhqQyxTQUFJLEdBQUcsMEJBQW1DLENBQUM7SUFJcEQsQ0FBQztDQUNGO0FBTkQsNEdBTUM7QUFFRDs7R0FFRztBQUNILE1BQWEsNENBQTZDLFNBQVEsMkJBQTJCO0lBUTNGLFlBQVksVUFBa0I7UUFDNUIsS0FBSyxDQUFDLHlCQUF5QixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFSdEMsU0FBSSxHQUFHLHFCQUE4QixDQUFDO1FBUzdDLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO0lBQy9CLENBQUM7Q0FDRjtBQVpELG9HQVlDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIE1pbmltdW0gYE1heFJlc3VsdHNgIHZhbHVlIGFsbG93ZWQgYnkgQXRoZW5hIGBHZXRRdWVyeVJlc3VsdHNgLiAqL1xuY29uc3QgTUlOX01BWF9SRVNVTFRTID0gMTtcbi8qKiBNYXhpbXVtIGBNYXhSZXN1bHRzYCB2YWx1ZSBhbGxvd2VkIGJ5IEF0aGVuYSBgR2V0UXVlcnlSZXN1bHRzYC4gKi9cbmNvbnN0IE1BWF9NQVhfUkVTVUxUUyA9IDEwMDA7XG5cbmNvbnN0IEVNUFRZX1FVRVJZX0VYRUNVVElPTl9JRF9NRVNTQUdFID0gJ3F1ZXJ5RXhlY3V0aW9uSWQgbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcnO1xuXG5jb25zdCBkZXNjcmliZUludmFsaWRNYXhSZXN1bHRzID0gKG1heFJlc3VsdHM6IG51bWJlcik6IHN0cmluZyA9PlxuICBgb3B0aW9ucy5tYXhSZXN1bHRzIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuICR7TUlOX01BWF9SRVNVTFRTfSBhbmQgJHtNQVhfTUFYX1JFU1VMVFN9LCBnb3QgJHtTdHJpbmcobWF4UmVzdWx0cyl9YDtcblxuLyoqXG4gKiBCYXNlIGVycm9yIHRocm93biBieSB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYWdlcn0gdmFsaWRhdGlvbi5cbiAqXG4gKiBDYXRjaCB0aGlzIHR5cGUgdG8gaGFuZGxlIGV2ZXJ5IHBhZ2VyLWluaXRpYXRlZCBmYWlsdXJlLCBvciBjYXRjaCBhIHN1YmNsYXNzIGZvciBhXG4gKiBzcGVjaWZpYyBjYXNlLiB7QGxpbmsgY29kZX0gaXMgYSBzdGFibGUgbWFjaGluZS1yZWFkYWJsZSBpZGVudGlmaWVyLlxuICpcbiAqIEVycm9ycyBwcm9wYWdhdGVkIGZyb20ge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFyc2VyfSBhcmUgKipub3QqKiB3cmFwcGVkOyB0aGV5XG4gKiByZW1haW4ge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFyc2VyRXJyb3J9IChvciBzdWJjbGFzc2VzKSB3aGVuIHRocm93biBieSB0aGUgcGFyc2VyLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQXRoZW5hUXVlcnlSZXN1bHRQYWdlckVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAvKipcbiAgICogU3RhYmxlIGVycm9yIGNvZGUgZm9yIGxvZ2dpbmcsIG1ldHJpY3MsIGFuZCBwcm9ncmFtbWF0aWMgaGFuZGxpbmcuXG4gICAqL1xuICBhYnN0cmFjdCByZWFkb25seSBjb2RlOiBzdHJpbmc7XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IG5ldy50YXJnZXQubmFtZTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgbmV3LnRhcmdldC5wcm90b3R5cGUpO1xuICB9XG59XG5cbi8qKlxuICogVGhyb3duIHdoZW4gYHF1ZXJ5RXhlY3V0aW9uSWRgIGlzIGVtcHR5IG9yIHdoaXRlc3BhY2Ugb25seS5cbiAqL1xuZXhwb3J0IGNsYXNzIEF0aGVuYVF1ZXJ5UmVzdWx0UGFnZXJFbXB0eVF1ZXJ5RXhlY3V0aW9uSWRFcnJvciBleHRlbmRzIEF0aGVuYVF1ZXJ5UmVzdWx0UGFnZXJFcnJvciB7XG4gIHJlYWRvbmx5IGNvZGUgPSAnZW1wdHktcXVlcnktZXhlY3V0aW9uLWlkJyBhcyBjb25zdDtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihFTVBUWV9RVUVSWV9FWEVDVVRJT05fSURfTUVTU0FHRSk7XG4gIH1cbn1cblxuLyoqXG4gKiBUaHJvd24gd2hlbiBgb3B0aW9ucy5tYXhSZXN1bHRzYCBpcyBub3QgYW4gaW50ZWdlciBpbiBgMS4uMTAwMGAgaW5jbHVzaXZlLlxuICovXG5leHBvcnQgY2xhc3MgQXRoZW5hUXVlcnlSZXN1bHRQYWdlckludmFsaWRNYXhSZXN1bHRzRXJyb3IgZXh0ZW5kcyBBdGhlbmFRdWVyeVJlc3VsdFBhZ2VyRXJyb3Ige1xuICByZWFkb25seSBjb2RlID0gJ2ludmFsaWQtbWF4LXJlc3VsdHMnIGFzIGNvbnN0O1xuXG4gIC8qKlxuICAgKiBUaGUgaW52YWxpZCBgbWF4UmVzdWx0c2AgdmFsdWUgdGhhdCB3YXMgc3VwcGxpZWQuXG4gICAqL1xuICByZWFkb25seSBtYXhSZXN1bHRzOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IobWF4UmVzdWx0czogbnVtYmVyKSB7XG4gICAgc3VwZXIoZGVzY3JpYmVJbnZhbGlkTWF4UmVzdWx0cyhtYXhSZXN1bHRzKSk7XG4gICAgdGhpcy5tYXhSZXN1bHRzID0gbWF4UmVzdWx0cztcbiAgfVxufVxuIl19
package/lib/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { AthenaClient, QueryResultType } from '@aws-sdk/client-athena';
2
- import { type HeaderRowDecision, type ParseResultSetOptions, type ParsedRow, type RowParser } from 'athena-query-result-parser';
2
+ import { type HeaderRowDecision, type ParseResultSetDiagnostics, type ParseResultSetOptions, type ParsedRow, type RowParser } from 'athena-query-result-parser';
3
3
  /**
4
4
  * One page of Athena query results returned by {@link AthenaQueryResultPager} after a fetch or generator step.
5
5
  *
@@ -13,6 +13,14 @@ export interface PageResult<T> {
13
13
  /** Same as `rows.length` for convenience. */
14
14
  rowCount: number;
15
15
  }
16
+ /**
17
+ * One page of Athena query results with {@link ParseResultSetDiagnostics} from
18
+ * {@link AthenaQueryResultParser.parseResultSetDetailed}.
19
+ */
20
+ export interface PageDetailedResult extends PageResult<ParsedRow> {
21
+ /** Parser diagnostics for this page only (header-row decision, raw row count, truncation, …). */
22
+ diagnostics: ParseResultSetDiagnostics;
23
+ }
16
24
  /**
17
25
  * Settings applied to every `GetQueryResults` invocation made by {@link AthenaQueryResultPager}.
18
26
  */
@@ -45,7 +53,9 @@ export interface PagerOptions {
45
53
  *
46
54
  * Provides paired APIs for raw {@link ParsedRow} access versus custom {@link RowParser} mapping at the page level
47
55
  * (`fetchPage` / `fetchPageWith`, `iteratePages` / `iteratePagesWith`) and at the row level
48
- * (`iterateRows` with or without `rowParser`).
56
+ * (`iterateRows` with or without `rowParser`). Use {@link AthenaQueryResultPager.fetchPageDetailed} when
57
+ * per-page {@link ParseResultSetDiagnostics} is needed (for example `headerRowDecision`, `rawRowCount`,
58
+ * `truncatedByMaxRows`).
49
59
  *
50
60
  * Constructor `maxResults`, `queryResultType`, and optional `parseResultSetOptions` are applied on every
51
61
  * `GetQueryResults` request and {@link AthenaQueryResultParser} invocation respectively.
@@ -74,14 +84,14 @@ export declare class AthenaQueryResultPager {
74
84
  private readonly parseResultSetOptions?;
75
85
  /** Stateful parser reused across pages of the same execution; reset on execution change or {@link AthenaQueryResultPager.reset}. */
76
86
  private parser;
77
- /** Last `queryExecutionId` passed to `fetchPage` / `fetchPageWith`; used to auto-reset the parser. */
87
+ /** Last `queryExecutionId` passed to fetch methods; used to auto-reset the parser. */
78
88
  private activeQueryExecutionId;
79
89
  /**
80
90
  * Creates a pager bound to `client` with optional per-request defaults.
81
91
  *
82
92
  * @param client - SDK v3 `AthenaClient` used to call `GetQueryResults`.
83
93
  * @param options - Optional `MaxResults`, `QueryResultType`, and `ParseResultSetOptions`; defaults apply when omitted.
84
- * @throws {RangeError} When `maxResults` is not an integer in `1..1000` inclusive.
94
+ * @throws {AthenaQueryResultPagerInvalidMaxResultsError} When `maxResults` is not an integer in `1..1000` inclusive.
85
95
  */
86
96
  constructor(client: AthenaClient, options?: PagerOptions);
87
97
  /**
@@ -92,6 +102,15 @@ export declare class AthenaQueryResultPager {
92
102
  * @param queryExecutionId - Athena query execution identifier for the upcoming fetch.
93
103
  */
94
104
  private readonly ensureParserForExecution;
105
+ /**
106
+ * Validates `queryExecutionId`, ensures parser state, and invokes `GetQueryResults`.
107
+ *
108
+ * @param queryExecutionId - Athena query execution identifier.
109
+ * @param nextToken - Continuation token from a prior page, if any.
110
+ * @returns Raw AWS response for the requested page.
111
+ * @throws {AthenaQueryResultPagerEmptyQueryExecutionIdError} When `queryExecutionId` is empty or whitespace only.
112
+ */
113
+ private readonly sendGetQueryResults;
95
114
  /**
96
115
  * Retrieves a single results page as dictionary-shaped {@link ParsedRow} values.
97
116
  *
@@ -101,9 +120,21 @@ export declare class AthenaQueryResultPager {
101
120
  * @param queryExecutionId - Athena query execution identifier.
102
121
  * @param nextToken - Pass `undefined` first; subsequent calls use {@link PageResult.nextToken}.
103
122
  * @returns Parsed rows plus pagination metadata from this response only.
104
- * @throws {Error} When `queryExecutionId` is empty or whitespace only.
123
+ * @throws {AthenaQueryResultPagerEmptyQueryExecutionIdError} When `queryExecutionId` is empty or whitespace only.
105
124
  */
106
125
  fetchPage(queryExecutionId: string, nextToken?: string): Promise<PageResult<ParsedRow>>;
126
+ /**
127
+ * Retrieves one page as {@link ParsedRow} values plus {@link ParseResultSetDiagnostics}.
128
+ *
129
+ * Uses {@link AthenaQueryResultParser.parseResultSetDetailed} on the AWS response.
130
+ * When `queryExecutionId` differs from the previous fetch sequence, the bundled parser is reset first.
131
+ *
132
+ * @param queryExecutionId - Athena query execution identifier.
133
+ * @param nextToken - Pass `undefined` first; subsequent calls use {@link PageDetailedResult.nextToken}.
134
+ * @returns Parsed rows, pagination metadata, and parser diagnostics for this response only.
135
+ * @throws {AthenaQueryResultPagerEmptyQueryExecutionIdError} When `queryExecutionId` is empty or whitespace only.
136
+ */
137
+ fetchPageDetailed(queryExecutionId: string, nextToken?: string): Promise<PageDetailedResult>;
107
138
  /**
108
139
  * Retrieves one page and maps each {@link ParsedRow} through `rowParser`.
109
140
  *
@@ -115,7 +146,7 @@ export declare class AthenaQueryResultPager {
115
146
  * @param rowParser - Converts each dictionary row into `T`.
116
147
  * @param nextToken - Pass `undefined` first; subsequent calls use {@link PageResult.nextToken}.
117
148
  * @returns Transformed rows plus pagination metadata from this response only.
118
- * @throws {Error} When `queryExecutionId` is empty or whitespace only.
149
+ * @throws {AthenaQueryResultPagerEmptyQueryExecutionIdError} When `queryExecutionId` is empty or whitespace only.
119
150
  */
120
151
  fetchPageWith<T>(queryExecutionId: string, rowParser: RowParser<T>, nextToken?: string): Promise<PageResult<T>>;
121
152
  /**
@@ -125,6 +156,13 @@ export declare class AthenaQueryResultPager {
125
156
  * @yields One page at a time until AWS returns no `NextToken`.
126
157
  */
127
158
  iteratePages(queryExecutionId: string): AsyncGenerator<PageResult<ParsedRow>>;
159
+ /**
160
+ * Lazily walks all pages for an execution, yielding one {@link PageDetailedResult} per step.
161
+ *
162
+ * @param queryExecutionId - Athena query execution identifier.
163
+ * @yields One page at a time (with diagnostics) until AWS returns no `NextToken`.
164
+ */
165
+ iteratePagesDetailed(queryExecutionId: string): AsyncGenerator<PageDetailedResult>;
128
166
  /**
129
167
  * Same as {@link AthenaQueryResultPager.iteratePages} but maps each row through `rowParser` on every page.
130
168
  *
@@ -165,13 +203,13 @@ export declare class AthenaQueryResultPager {
165
203
  /**
166
204
  * Clears the bundled {@link AthenaQueryResultParser} state and the tracked active execution id.
167
205
  *
168
- * Usually unnecessary: {@link AthenaQueryResultPager.fetchPage} and {@link AthenaQueryResultPager.fetchPageWith}
169
- * reset automatically when `queryExecutionId` changes. Call explicitly to clear state without starting a new fetch
206
+ * Usually unnecessary: fetch methods reset automatically when `queryExecutionId` changes. Call explicitly to clear state without starting a new fetch
170
207
  * (for example so {@link AthenaQueryResultPager.getLastHeaderRowDecision} returns `null`).
171
208
  */
172
209
  reset(): void;
173
210
  }
211
+ export { AthenaQueryResultPagerEmptyQueryExecutionIdError, AthenaQueryResultPagerError, AthenaQueryResultPagerInvalidMaxResultsError, } from './errors';
174
212
  /** Re-exports {@link QueryResultType} from `@aws-sdk/client-athena`. */
175
213
  export { QueryResultType } from '@aws-sdk/client-athena';
176
- export { EXTRA_COLUMNS_KEY, headersFromMeta, isHeaderRow, parseResultSetDetailedOnce, parseResultSetIterOnce, parseResultSetOnce, parseResultSetWithOnce, rowToObject, rowToTypedObject, toBoolean, toDate, toNumber, } from 'athena-query-result-parser';
214
+ export { AthenaQueryResultParserColumnCountMismatchError, AthenaQueryResultParserDuplicateColumnNameError, AthenaQueryResultParserError, AthenaQueryResultParserHeaderRowMismatchError, AthenaQueryResultParserInvalidMaxRowsError, AthenaQueryResultParserMaxRowsExceededError, AthenaQueryResultParserUnavailableResultError, EXTRA_COLUMNS_KEY, headersFromMeta, isHeaderRow, parseResultSetDetailedOnce, parseResultSetIterOnce, parseResultSetOnce, parseResultSetWithOnce, rowToObject, rowToTypedObject, toBoolean, toDate, toNumber, } from 'athena-query-result-parser';
177
215
  export type { AthenaQueryResultParserOptions, AthenaTypedValue, ColumnCountMismatchBehavior, HeaderRowDecision, MaxRowsExceededBehavior, ParseResultSetDiagnostics, ParseResultSetDetailedResult, ParseResultSetOptions, ParseResultSetUnavailableReason, ParsedRow, ParserReusePolicy, RowParser, TypedParsedRow, UnavailableResultBehavior, } from 'athena-query-result-parser';
package/lib/index.js CHANGED
@@ -1,14 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toNumber = exports.toDate = exports.toBoolean = exports.rowToTypedObject = exports.rowToObject = exports.parseResultSetWithOnce = exports.parseResultSetOnce = exports.parseResultSetIterOnce = exports.parseResultSetDetailedOnce = exports.isHeaderRow = exports.headersFromMeta = exports.EXTRA_COLUMNS_KEY = exports.QueryResultType = exports.AthenaQueryResultPager = void 0;
3
+ exports.toNumber = exports.toDate = exports.toBoolean = exports.rowToTypedObject = exports.rowToObject = exports.parseResultSetWithOnce = exports.parseResultSetOnce = exports.parseResultSetIterOnce = exports.parseResultSetDetailedOnce = exports.isHeaderRow = exports.headersFromMeta = exports.EXTRA_COLUMNS_KEY = exports.AthenaQueryResultParserUnavailableResultError = exports.AthenaQueryResultParserMaxRowsExceededError = exports.AthenaQueryResultParserInvalidMaxRowsError = exports.AthenaQueryResultParserHeaderRowMismatchError = exports.AthenaQueryResultParserError = exports.AthenaQueryResultParserDuplicateColumnNameError = exports.AthenaQueryResultParserColumnCountMismatchError = exports.QueryResultType = exports.AthenaQueryResultPagerInvalidMaxResultsError = exports.AthenaQueryResultPagerError = exports.AthenaQueryResultPagerEmptyQueryExecutionIdError = exports.AthenaQueryResultPager = void 0;
4
4
  const client_athena_1 = require("@aws-sdk/client-athena");
5
5
  const athena_query_result_parser_1 = require("athena-query-result-parser");
6
+ const errors_1 = require("./errors");
6
7
  /** Default maximum number of result rows requested per {@link AthenaQueryResultPager} API call (`MaxResults`). */
7
8
  const DEFAULT_MAX_RESULTS = 1000;
8
- /** Minimum `MaxResults` value allowed by Athena `GetQueryResults`. */
9
- const MIN_MAX_RESULTS = 1;
10
- /** Maximum `MaxResults` value allowed by Athena `GetQueryResults`. */
11
- const MAX_MAX_RESULTS = 1000;
12
9
  /** Default `QueryResultType` forwarded to Athena `GetQueryResults`. */
13
10
  const DEFAULT_QUERY_RESULT_TYPE = client_athena_1.QueryResultType.DATA_ROWS;
14
11
  /**
@@ -17,7 +14,9 @@ const DEFAULT_QUERY_RESULT_TYPE = client_athena_1.QueryResultType.DATA_ROWS;
17
14
  *
18
15
  * Provides paired APIs for raw {@link ParsedRow} access versus custom {@link RowParser} mapping at the page level
19
16
  * (`fetchPage` / `fetchPageWith`, `iteratePages` / `iteratePagesWith`) and at the row level
20
- * (`iterateRows` with or without `rowParser`).
17
+ * (`iterateRows` with or without `rowParser`). Use {@link AthenaQueryResultPager.fetchPageDetailed} when
18
+ * per-page {@link ParseResultSetDiagnostics} is needed (for example `headerRowDecision`, `rawRowCount`,
19
+ * `truncatedByMaxRows`).
21
20
  *
22
21
  * Constructor `maxResults`, `queryResultType`, and optional `parseResultSetOptions` are applied on every
23
22
  * `GetQueryResults` request and {@link AthenaQueryResultParser} invocation respectively.
@@ -45,7 +44,7 @@ class AthenaQueryResultPager {
45
44
  *
46
45
  * @param client - SDK v3 `AthenaClient` used to call `GetQueryResults`.
47
46
  * @param options - Optional `MaxResults`, `QueryResultType`, and `ParseResultSetOptions`; defaults apply when omitted.
48
- * @throws {RangeError} When `maxResults` is not an integer in `1..1000` inclusive.
47
+ * @throws {AthenaQueryResultPagerInvalidMaxResultsError} When `maxResults` is not an integer in `1..1000` inclusive.
49
48
  */
50
49
  constructor(client, options = {}) {
51
50
  /**
@@ -61,9 +60,30 @@ class AthenaQueryResultPager {
61
60
  }
62
61
  this.activeQueryExecutionId = queryExecutionId;
63
62
  };
63
+ /**
64
+ * Validates `queryExecutionId`, ensures parser state, and invokes `GetQueryResults`.
65
+ *
66
+ * @param queryExecutionId - Athena query execution identifier.
67
+ * @param nextToken - Continuation token from a prior page, if any.
68
+ * @returns Raw AWS response for the requested page.
69
+ * @throws {AthenaQueryResultPagerEmptyQueryExecutionIdError} When `queryExecutionId` is empty or whitespace only.
70
+ */
71
+ this.sendGetQueryResults = async (queryExecutionId, nextToken) => {
72
+ if (queryExecutionId.trim() === '') {
73
+ throw new errors_1.AthenaQueryResultPagerEmptyQueryExecutionIdError();
74
+ }
75
+ this.ensureParserForExecution(queryExecutionId);
76
+ const input = {
77
+ QueryExecutionId: queryExecutionId,
78
+ NextToken: nextToken,
79
+ MaxResults: this.options.maxResults,
80
+ QueryResultType: this.options.queryResultType,
81
+ };
82
+ return this.client.send(new client_athena_1.GetQueryResultsCommand(input));
83
+ };
64
84
  const maxResults = options.maxResults ?? DEFAULT_MAX_RESULTS;
65
- if (!Number.isInteger(maxResults) || maxResults < MIN_MAX_RESULTS || maxResults > MAX_MAX_RESULTS) {
66
- throw new RangeError(`options.maxResults must be an integer between ${MIN_MAX_RESULTS} and ${MAX_MAX_RESULTS}, got ${String(maxResults)}`);
85
+ if (!Number.isInteger(maxResults) || maxResults < 1 || maxResults > 1000) {
86
+ throw new errors_1.AthenaQueryResultPagerInvalidMaxResultsError(maxResults);
67
87
  }
68
88
  this.client = client;
69
89
  this.options = {
@@ -83,20 +103,10 @@ class AthenaQueryResultPager {
83
103
  * @param queryExecutionId - Athena query execution identifier.
84
104
  * @param nextToken - Pass `undefined` first; subsequent calls use {@link PageResult.nextToken}.
85
105
  * @returns Parsed rows plus pagination metadata from this response only.
86
- * @throws {Error} When `queryExecutionId` is empty or whitespace only.
106
+ * @throws {AthenaQueryResultPagerEmptyQueryExecutionIdError} When `queryExecutionId` is empty or whitespace only.
87
107
  */
88
108
  async fetchPage(queryExecutionId, nextToken) {
89
- if (queryExecutionId.trim() === '') {
90
- throw new Error('queryExecutionId must be a non-empty string');
91
- }
92
- this.ensureParserForExecution(queryExecutionId);
93
- const input = {
94
- QueryExecutionId: queryExecutionId,
95
- NextToken: nextToken,
96
- MaxResults: this.options.maxResults,
97
- QueryResultType: this.options.queryResultType,
98
- };
99
- const response = await this.client.send(new client_athena_1.GetQueryResultsCommand(input));
109
+ const response = await this.sendGetQueryResults(queryExecutionId, nextToken);
100
110
  const rows = this.parser.parseResultSet(response.ResultSet, this.parseResultSetOptions);
101
111
  return {
102
112
  rows,
@@ -104,6 +114,27 @@ class AthenaQueryResultPager {
104
114
  rowCount: rows.length,
105
115
  };
106
116
  }
117
+ /**
118
+ * Retrieves one page as {@link ParsedRow} values plus {@link ParseResultSetDiagnostics}.
119
+ *
120
+ * Uses {@link AthenaQueryResultParser.parseResultSetDetailed} on the AWS response.
121
+ * When `queryExecutionId` differs from the previous fetch sequence, the bundled parser is reset first.
122
+ *
123
+ * @param queryExecutionId - Athena query execution identifier.
124
+ * @param nextToken - Pass `undefined` first; subsequent calls use {@link PageDetailedResult.nextToken}.
125
+ * @returns Parsed rows, pagination metadata, and parser diagnostics for this response only.
126
+ * @throws {AthenaQueryResultPagerEmptyQueryExecutionIdError} When `queryExecutionId` is empty or whitespace only.
127
+ */
128
+ async fetchPageDetailed(queryExecutionId, nextToken) {
129
+ const response = await this.sendGetQueryResults(queryExecutionId, nextToken);
130
+ const parsed = this.parser.parseResultSetDetailed(response.ResultSet, this.parseResultSetOptions);
131
+ return {
132
+ rows: parsed.rows,
133
+ nextToken: response.NextToken,
134
+ rowCount: parsed.rows.length,
135
+ diagnostics: parsed.diagnostics,
136
+ };
137
+ }
107
138
  /**
108
139
  * Retrieves one page and maps each {@link ParsedRow} through `rowParser`.
109
140
  *
@@ -115,20 +146,10 @@ class AthenaQueryResultPager {
115
146
  * @param rowParser - Converts each dictionary row into `T`.
116
147
  * @param nextToken - Pass `undefined` first; subsequent calls use {@link PageResult.nextToken}.
117
148
  * @returns Transformed rows plus pagination metadata from this response only.
118
- * @throws {Error} When `queryExecutionId` is empty or whitespace only.
149
+ * @throws {AthenaQueryResultPagerEmptyQueryExecutionIdError} When `queryExecutionId` is empty or whitespace only.
119
150
  */
120
151
  async fetchPageWith(queryExecutionId, rowParser, nextToken) {
121
- if (queryExecutionId.trim() === '') {
122
- throw new Error('queryExecutionId must be a non-empty string');
123
- }
124
- this.ensureParserForExecution(queryExecutionId);
125
- const input = {
126
- QueryExecutionId: queryExecutionId,
127
- NextToken: nextToken,
128
- MaxResults: this.options.maxResults,
129
- QueryResultType: this.options.queryResultType,
130
- };
131
- const response = await this.client.send(new client_athena_1.GetQueryResultsCommand(input));
152
+ const response = await this.sendGetQueryResults(queryExecutionId, nextToken);
132
153
  const rows = this.parser.parseResultSetWith(response.ResultSet, rowParser, this.parseResultSetOptions);
133
154
  return {
134
155
  rows,
@@ -150,6 +171,20 @@ class AthenaQueryResultPager {
150
171
  nextToken = page.nextToken;
151
172
  } while (nextToken);
152
173
  }
174
+ /**
175
+ * Lazily walks all pages for an execution, yielding one {@link PageDetailedResult} per step.
176
+ *
177
+ * @param queryExecutionId - Athena query execution identifier.
178
+ * @yields One page at a time (with diagnostics) until AWS returns no `NextToken`.
179
+ */
180
+ async *iteratePagesDetailed(queryExecutionId) {
181
+ let nextToken;
182
+ do {
183
+ const page = await this.fetchPageDetailed(queryExecutionId, nextToken);
184
+ yield page;
185
+ nextToken = page.nextToken;
186
+ } while (nextToken);
187
+ }
153
188
  /**
154
189
  * Same as {@link AthenaQueryResultPager.iteratePages} but maps each row through `rowParser` on every page.
155
190
  *
@@ -195,8 +230,7 @@ class AthenaQueryResultPager {
195
230
  /**
196
231
  * Clears the bundled {@link AthenaQueryResultParser} state and the tracked active execution id.
197
232
  *
198
- * Usually unnecessary: {@link AthenaQueryResultPager.fetchPage} and {@link AthenaQueryResultPager.fetchPageWith}
199
- * reset automatically when `queryExecutionId` changes. Call explicitly to clear state without starting a new fetch
233
+ * Usually unnecessary: fetch methods reset automatically when `queryExecutionId` changes. Call explicitly to clear state without starting a new fetch
200
234
  * (for example so {@link AthenaQueryResultPager.getLastHeaderRowDecision} returns `null`).
201
235
  */
202
236
  reset() {
@@ -205,10 +239,21 @@ class AthenaQueryResultPager {
205
239
  }
206
240
  }
207
241
  exports.AthenaQueryResultPager = AthenaQueryResultPager;
242
+ var errors_2 = require("./errors");
243
+ Object.defineProperty(exports, "AthenaQueryResultPagerEmptyQueryExecutionIdError", { enumerable: true, get: function () { return errors_2.AthenaQueryResultPagerEmptyQueryExecutionIdError; } });
244
+ Object.defineProperty(exports, "AthenaQueryResultPagerError", { enumerable: true, get: function () { return errors_2.AthenaQueryResultPagerError; } });
245
+ Object.defineProperty(exports, "AthenaQueryResultPagerInvalidMaxResultsError", { enumerable: true, get: function () { return errors_2.AthenaQueryResultPagerInvalidMaxResultsError; } });
208
246
  /** Re-exports {@link QueryResultType} from `@aws-sdk/client-athena`. */
209
247
  var client_athena_2 = require("@aws-sdk/client-athena");
210
248
  Object.defineProperty(exports, "QueryResultType", { enumerable: true, get: function () { return client_athena_2.QueryResultType; } });
211
249
  var athena_query_result_parser_2 = require("athena-query-result-parser");
250
+ Object.defineProperty(exports, "AthenaQueryResultParserColumnCountMismatchError", { enumerable: true, get: function () { return athena_query_result_parser_2.AthenaQueryResultParserColumnCountMismatchError; } });
251
+ Object.defineProperty(exports, "AthenaQueryResultParserDuplicateColumnNameError", { enumerable: true, get: function () { return athena_query_result_parser_2.AthenaQueryResultParserDuplicateColumnNameError; } });
252
+ Object.defineProperty(exports, "AthenaQueryResultParserError", { enumerable: true, get: function () { return athena_query_result_parser_2.AthenaQueryResultParserError; } });
253
+ Object.defineProperty(exports, "AthenaQueryResultParserHeaderRowMismatchError", { enumerable: true, get: function () { return athena_query_result_parser_2.AthenaQueryResultParserHeaderRowMismatchError; } });
254
+ Object.defineProperty(exports, "AthenaQueryResultParserInvalidMaxRowsError", { enumerable: true, get: function () { return athena_query_result_parser_2.AthenaQueryResultParserInvalidMaxRowsError; } });
255
+ Object.defineProperty(exports, "AthenaQueryResultParserMaxRowsExceededError", { enumerable: true, get: function () { return athena_query_result_parser_2.AthenaQueryResultParserMaxRowsExceededError; } });
256
+ Object.defineProperty(exports, "AthenaQueryResultParserUnavailableResultError", { enumerable: true, get: function () { return athena_query_result_parser_2.AthenaQueryResultParserUnavailableResultError; } });
212
257
  Object.defineProperty(exports, "EXTRA_COLUMNS_KEY", { enumerable: true, get: function () { return athena_query_result_parser_2.EXTRA_COLUMNS_KEY; } });
213
258
  Object.defineProperty(exports, "headersFromMeta", { enumerable: true, get: function () { return athena_query_result_parser_2.headersFromMeta; } });
214
259
  Object.defineProperty(exports, "isHeaderRow", { enumerable: true, get: function () { return athena_query_result_parser_2.isHeaderRow; } });
@@ -221,4 +266,4 @@ Object.defineProperty(exports, "rowToTypedObject", { enumerable: true, get: func
221
266
  Object.defineProperty(exports, "toBoolean", { enumerable: true, get: function () { return athena_query_result_parser_2.toBoolean; } });
222
267
  Object.defineProperty(exports, "toDate", { enumerable: true, get: function () { return athena_query_result_parser_2.toDate; } });
223
268
  Object.defineProperty(exports, "toNumber", { enumerable: true, get: function () { return athena_query_result_parser_2.toNumber; } });
224
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMERBQWlJO0FBQ2pJLDJFQU1vQztBQUVwQyxrSEFBa0g7QUFDbEgsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUM7QUFDakMsc0VBQXNFO0FBQ3RFLE1BQU0sZUFBZSxHQUFHLENBQUMsQ0FBQztBQUMxQixzRUFBc0U7QUFDdEUsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDO0FBRTdCLHVFQUF1RTtBQUN2RSxNQUFNLHlCQUF5QixHQUFHLCtCQUFlLENBQUMsU0FBUyxDQUFDO0FBMkM1RDs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxNQUFhLHNCQUFzQjtJQUVqQzs7Ozs7O09BTUc7SUFDSCxNQUFNLENBQUMsV0FBVyxDQUFJLFVBQXlCO1FBQzdDLE9BQU8sVUFBVSxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUM7SUFDNUMsQ0FBQztJQWFEOzs7Ozs7T0FNRztJQUNILFlBQVksTUFBb0IsRUFBRSxVQUF3QixFQUFFO1FBa0I1RDs7Ozs7O1dBTUc7UUFDYyw2QkFBd0IsR0FBRyxDQUFDLGdCQUF3QixFQUFRLEVBQUU7WUFDN0UsSUFBSSxJQUFJLENBQUMsc0JBQXNCLEtBQUssU0FBUyxJQUFJLElBQUksQ0FBQyxzQkFBc0IsS0FBSyxnQkFBZ0IsRUFBRSxDQUFDO2dCQUNsRyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3RCLENBQUM7WUFDRCxJQUFJLENBQUMsc0JBQXNCLEdBQUcsZ0JBQWdCLENBQUM7UUFDakQsQ0FBQyxDQUFDO1FBN0JBLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxVQUFVLElBQUksbUJBQW1CLENBQUM7UUFDN0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUksVUFBVSxHQUFHLGVBQWUsSUFBSSxVQUFVLEdBQUcsZUFBZSxFQUFF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QztJQUVEOzs7Ozs7T0FNRztJQUNILEtBQUs7UUFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxTQUFTLENBQUM7SUFDMUMsQ0FBQztDQUNGO0FBalFELHdEQWlRQztBQUVELHdFQUF3RTtBQUN4RSx3REFBeUQ7QUFBaEQsZ0hBQUEsZUFBZSxPQUFBO0FBQ3hCLHlFQWFvQztBQVpsQywrSEFBQSxpQkFBaUIsT0FBQTtBQUNqQiw2SEFBQSxlQUFlLE9BQUE7QUFDZix5SEFBQSxXQUFXLE9BQUE7QUFDWCx3SUFBQSwwQkFBMEIsT0FBQTtBQUMxQixvSUFBQSxzQkFBc0IsT0FBQTtBQUN0QixnSUFBQSxrQkFBa0IsT0FBQTtBQUNsQixvSUFBQSxzQkFBc0IsT0FBQTtBQUN0Qix5SEFBQSxXQUFXLE9BQUE7QUFDWCw4SEFBQSxnQkFBZ0IsT0FBQTtBQUNoQix1SEFBQSxTQUFTLE9BQUE7QUFDVCxvSEFBQSxNQUFNLE9BQUE7QUFDTixzSEFBQSxRQUFRLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBdGhlbmFDbGllbnQsIEdldFF1ZXJ5UmVzdWx0c0NvbW1hbmQsIFF1ZXJ5UmVzdWx0VHlwZSwgdHlwZSBHZXRRdWVyeVJlc3VsdHNDb21tYW5kSW5wdXQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtYXRoZW5hJztcbmltcG9ydCB7XG4gIEF0aGVuYVF1ZXJ5UmVzdWx0UGFyc2VyLFxuICB0eXBlIEhlYWRlclJvd0RlY2lzaW9uLFxuICB0eXBlIFBhcnNlUmVzdWx0U2V0T3B0aW9ucyxcbiAgdHlwZSBQYXJzZWRSb3csXG4gIHR5cGUgUm93UGFyc2VyLFxufSBmcm9tICdhdGhlbmEtcXVlcnktcmVzdWx0LXBhcnNlcic7XG5cbi8qKiBEZWZhdWx0IG1heGltdW0gbnVtYmVyIG9mIHJlc3VsdCByb3dzIHJlcXVlc3RlZCBwZXIge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFnZXJ9IEFQSSBjYWxsIChgTWF4UmVzdWx0c2ApLiAqL1xuY29uc3QgREVGQVVMVF9NQVhfUkVTVUxUUyA9IDEwMDA7XG4vKiogTWluaW11bSBgTWF4UmVzdWx0c2AgdmFsdWUgYWxsb3dlZCBieSBBdGhlbmEgYEdldFF1ZXJ5UmVzdWx0c2AuICovXG5jb25zdCBNSU5fTUFYX1JFU1VMVFMgPSAxO1xuLyoqIE1heGltdW0gYE1heFJlc3VsdHNgIHZhbHVlIGFsbG93ZWQgYnkgQXRoZW5hIGBHZXRRdWVyeVJlc3VsdHNgLiAqL1xuY29uc3QgTUFYX01BWF9SRVNVTFRTID0gMTAwMDtcblxuLyoqIERlZmF1bHQgYFF1ZXJ5UmVzdWx0VHlwZWAgZm9yd2FyZGVkIHRvIEF0aGVuYSBgR2V0UXVlcnlSZXN1bHRzYC4gKi9cbmNvbnN0IERFRkFVTFRfUVVFUllfUkVTVUxUX1RZUEUgPSBRdWVyeVJlc3VsdFR5cGUuREFUQV9ST1dTO1xuXG4vKipcbiAqIE9uZSBwYWdlIG9mIEF0aGVuYSBxdWVyeSByZXN1bHRzIHJldHVybmVkIGJ5IHtAbGluayBBdGhlbmFRdWVyeVJlc3VsdFBhZ2VyfSBhZnRlciBhIGZldGNoIG9yIGdlbmVyYXRvciBzdGVwLlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFJvdyByZXByZXNlbnRhdGlvbjsgdXNlIHtAbGluayBQYXJzZWRSb3d9IG9yIGEgdHlwZSBwcm9kdWNlZCBieSB7QGxpbmsgUm93UGFyc2VyfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYWdlUmVzdWx0PFQ+IHtcbiAgLyoqIFBhcnNlZCByb3dzIGZvciB0aGlzIHBhZ2Ugb25seS4gKi9cbiAgcm93czogVFtdO1xuICAvKiogQ29udGludWF0aW9uIHRva2VuIGZvciB0aGUgZm9sbG93aW5nIHBhZ2UgKGB1bmRlZmluZWRgIHdoZW4gdGhpcyBpcyB0aGUgbGFzdCBwYWdlKS4gKi9cbiAgbmV4dFRva2VuPzogc3RyaW5nO1xuICAvKiogU2FtZSBhcyBgcm93cy5sZW5ndGhgIGZvciBjb252ZW5pZW5jZS4gKi9cbiAgcm93Q291bnQ6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBTZXR0aW5ncyBhcHBsaWVkIHRvIGV2ZXJ5IGBHZXRRdWVyeVJlc3VsdHNgIGludm9jYXRpb24gbWFkZSBieSB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYWdlcn0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGFnZXJPcHRpb25zIHtcbiAgLyoqXG4gICAqIGBNYXhSZXN1bHRzYCBwZXIgcmVxdWVzdCDigJQgbXVzdCBiZSBhbiBpbnRlZ2VyIGZyb20gMSB0aHJvdWdoIDEwMDAgKEF0aGVuYSBsaW1pdHMpLlxuICAgKiBAZGVmYXVsdFZhbHVlIDEwMDBcbiAgICovXG4gIG1heFJlc3VsdHM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBBdGhlbmEgYEdldFF1ZXJ5UmVzdWx0c2Age0BsaW5rIFF1ZXJ5UmVzdWx0VHlwZX0g4oCUIGFueSBtZW1iZXIgb2YgdGhlIEFXUyBTREsgZW51bVxuICAgKiAoZm9yIGV4YW1wbGUge0BsaW5rIFF1ZXJ5UmVzdWx0VHlwZS5EQVRBX1JPV1N9IGZvciB0YWJ1bGFyIHJvd3Mgb3Ige0BsaW5rIFF1ZXJ5UmVzdWx0VHlwZS5EQVRBX01BTklGRVNUfVxuICAgKiBmb3IgQ1RBUyAvIFVOTE9BRCAvIElOU0VSVCBtYW5pZmVzdCBvdXRwdXRzIHdoZW4gQXRoZW5hIHN1cHBvcnRzIHRoZW0pLlxuICAgKiBAZGVmYXVsdFZhbHVlIHtAbGluayBRdWVyeVJlc3VsdFR5cGUuREFUQV9ST1dTfVxuICAgKi9cbiAgcXVlcnlSZXN1bHRUeXBlPzogUXVlcnlSZXN1bHRUeXBlO1xuICAvKipcbiAgICogT3B0aW9ucyBmb3J3YXJkZWQgdG8gZXZlcnkge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFyc2VyLnBhcnNlUmVzdWx0U2V0fSAvXG4gICAqIHtAbGluayBBdGhlbmFRdWVyeVJlc3VsdFBhcnNlci5wYXJzZVJlc3VsdFNldFdpdGh9IGNhbGwgKGZvciBleGFtcGxlXG4gICAqIGBjb2x1bW5Db3VudE1pc21hdGNoQmVoYXZpb3JgLCBgc2tpcEhlYWRlclJvd2AsIGBoZWFkZXJSb3dEZXRlY3Rpb25TdHJhdGVneWAsXG4gICAqIGB1bmF2YWlsYWJsZVJlc3VsdEJlaGF2aW9yYCwgYG1heFJvd3NgKS5cbiAgICpcbiAgICogQHNlZSBQYXJzZVJlc3VsdFNldE9wdGlvbnNcbiAgICovXG4gIHBhcnNlUmVzdWx0U2V0T3B0aW9ucz86IFBhcnNlUmVzdWx0U2V0T3B0aW9ucztcbn1cblxuLyoqXG4gKiBQYWdpbmF0ZXMgQXRoZW5hIGBHZXRRdWVyeVJlc3VsdHNgIChBV1MgU0RLIGZvciBKYXZhU2NyaXB0IHYzKTogd2Fsa3MgYE5leHRUb2tlbmAgYW5kIHBhcnNlcyB0YWJ1bGFyIHJvd3Mgd2l0aFxuICogYGF0aGVuYS1xdWVyeS1yZXN1bHQtcGFyc2VyYCB3aGVuIG5lZWRlZC5cbiAqXG4gKiBQcm92aWRlcyBwYWlyZWQgQVBJcyBmb3IgcmF3IHtAbGluayBQYXJzZWRSb3d9IGFjY2VzcyB2ZXJzdXMgY3VzdG9tIHtAbGluayBSb3dQYXJzZXJ9IG1hcHBpbmcgYXQgdGhlIHBhZ2UgbGV2ZWxcbiAqIChgZmV0Y2hQYWdlYCAvIGBmZXRjaFBhZ2VXaXRoYCwgYGl0ZXJhdGVQYWdlc2AgLyBgaXRlcmF0ZVBhZ2VzV2l0aGApIGFuZCBhdCB0aGUgcm93IGxldmVsXG4gKiAoYGl0ZXJhdGVSb3dzYCB3aXRoIG9yIHdpdGhvdXQgYHJvd1BhcnNlcmApLlxuICpcbiAqIENvbnN0cnVjdG9yIGBtYXhSZXN1bHRzYCwgYHF1ZXJ5UmVzdWx0VHlwZWAsIGFuZCBvcHRpb25hbCBgcGFyc2VSZXN1bHRTZXRPcHRpb25zYCBhcmUgYXBwbGllZCBvbiBldmVyeVxuICogYEdldFF1ZXJ5UmVzdWx0c2AgcmVxdWVzdCBhbmQge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFyc2VyfSBpbnZvY2F0aW9uIHJlc3BlY3RpdmVseS5cbiAqIFdoZW4gYHF1ZXJ5RXhlY3V0aW9uSWRgIGNoYW5nZXMgYmV0d2VlbiBmZXRjaGVzLCB0aGUgYnVuZGxlZCBwYXJzZXIgaXMgcmVzZXQgYXV0b21hdGljYWxseS5cbiAqXG4gKiBEb2VzIG5vdCB3YWl0IGZvciBxdWVyeSBjb21wbGV0aW9uIG9yIGFkZCBBdGhlbmEtc3BlY2lmaWMgcmV0cnk6IGNhbGxlcnMgc2hvdWxkIHdhaXQgdW50aWwgdGhlIGV4ZWN1dGlvblxuICogc3VjY2VlZHMgKGZvciBleGFtcGxlIHZpYSBgR2V0UXVlcnlFeGVjdXRpb25gKSBhbmQgY29uZmlndXJlIFNESyAvIGFwcGxpY2F0aW9uLWxldmVsIHJldHJ5IGZvciB0aHJvdHRsaW5nLlxuICogQVdTIFNESyBlcnJvcnMgZnJvbSBgR2V0UXVlcnlSZXN1bHRzYCBhcmUgcHJvcGFnYXRlZCBhcyB0aHJvd24uXG4gKlxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0phdmFTY3JpcHRTREsvdjMvbGF0ZXN0L2NsaWVudC9hdGhlbmEvY29tbWFuZC9HZXRRdWVyeVJlc3VsdHNDb21tYW5kLyB8IEdldFF1ZXJ5UmVzdWx0c0NvbW1hbmQgKEFXUyBTREspfVxuICovXG5leHBvcnQgY2xhc3MgQXRoZW5hUXVlcnlSZXN1bHRQYWdlciB7XG5cbiAgLyoqXG4gICAqIFJlcG9ydHMgd2hldGhlciBhbm90aGVyIHJlc3VsdHMgcGFnZSBpcyBhdmFpbGFibGUgZm9yIHRoZSBzYW1lIHF1ZXJ5IGV4ZWN1dGlvbi5cbiAgICpcbiAgICogQHR5cGVQYXJhbSBUIC0gUm93IHR5cGUgaGVsZCBpbiB7QGxpbmsgUGFnZVJlc3VsdC5yb3dzfS5cbiAgICogQHBhcmFtIHBhZ2VSZXN1bHQgLSBUaGUgbW9zdCByZWNlbnRseSByZXRyaWV2ZWQgcGFnZSBmcm9tIGBmZXRjaFBhZ2VgLCBgZmV0Y2hQYWdlV2l0aGAsIG9yIGEgcGFnZSBpdGVyYXRvci5cbiAgICogQHJldHVybnMgYHRydWVgIHdoZW4ge0BsaW5rIFBhZ2VSZXN1bHQubmV4dFRva2VufSBpcyBkZWZpbmVkIGFuZCBhbm90aGVyIHBhZ2Ugc2hvdWxkIGJlIGZldGNoZWQuXG4gICAqL1xuICBzdGF0aWMgaGFzTmV4dFBhZ2U8VD4ocGFnZVJlc3VsdDogUGFnZVJlc3VsdDxUPik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBwYWdlUmVzdWx0Lm5leHRUb2tlbiAhPT0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqIFNESyB2MyBjbGllbnQgdXNlZCBmb3IgZXZlcnkgYEdldFF1ZXJ5UmVzdWx0c2AgY2FsbC4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IEF0aGVuYUNsaWVudDtcbiAgLyoqIE5vcm1hbGl6ZWQgcGFnZXIgc2V0dGluZ3MgKGV2ZXJ5IGZpZWxkIHNldCBhZnRlciBtZXJnaW5nIGRlZmF1bHRzKS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBvcHRpb25zOiBSZXF1aXJlZDxQaWNrPFBhZ2VyT3B0aW9ucywgJ21heFJlc3VsdHMnIHwgJ3F1ZXJ5UmVzdWx0VHlwZSc+PjtcbiAgLyoqIFBhcnNlciBvcHRpb25zIGFwcGxpZWQgb24gZXZlcnkgcGFnZSBwYXJzZSAodW5kZWZpbmVkIHVzZXMgcGFyc2VyIGRlZmF1bHRzKS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBwYXJzZVJlc3VsdFNldE9wdGlvbnM/OiBQYXJzZVJlc3VsdFNldE9wdGlvbnM7XG4gIC8qKiBTdGF0ZWZ1bCBwYXJzZXIgcmV1c2VkIGFjcm9zcyBwYWdlcyBvZiB0aGUgc2FtZSBleGVjdXRpb247IHJlc2V0IG9uIGV4ZWN1dGlvbiBjaGFuZ2Ugb3Ige0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFnZXIucmVzZXR9LiAqL1xuICBwcml2YXRlIHBhcnNlcjogQXRoZW5hUXVlcnlSZXN1bHRQYXJzZXI7XG4gIC8qKiBMYXN0IGBxdWVyeUV4ZWN1dGlvbklkYCBwYXNzZWQgdG8gYGZldGNoUGFnZWAgLyBgZmV0Y2hQYWdlV2l0aGA7IHVzZWQgdG8gYXV0by1yZXNldCB0aGUgcGFyc2VyLiAqL1xuICBwcml2YXRlIGFjdGl2ZVF1ZXJ5RXhlY3V0aW9uSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHBhZ2VyIGJvdW5kIHRvIGBjbGllbnRgIHdpdGggb3B0aW9uYWwgcGVyLXJlcXVlc3QgZGVmYXVsdHMuXG4gICAqXG4gICAqIEBwYXJhbSBjbGllbnQgLSBTREsgdjMgYEF0aGVuYUNsaWVudGAgdXNlZCB0byBjYWxsIGBHZXRRdWVyeVJlc3VsdHNgLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIGBNYXhSZXN1bHRzYCwgYFF1ZXJ5UmVzdWx0VHlwZWAsIGFuZCBgUGFyc2VSZXN1bHRTZXRPcHRpb25zYDsgZGVmYXVsdHMgYXBwbHkgd2hlbiBvbWl0dGVkLlxuICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBXaGVuIGBtYXhSZXN1bHRzYCBpcyBub3QgYW4gaW50ZWdlciBpbiBgMS4uMTAwMGAgaW5jbHVzaXZlLlxuICAgKi9cbiAgY29uc3RydWN0b3IoY2xpZW50OiBBdGhlbmFDbGllbnQsIG9wdGlvbnM6IFBhZ2VyT3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgbWF4UmVzdWx0cyA9IG9wdGlvbnMubWF4UmVzdWx0cyA/PyBERUZBVUxUX01BWF9SRVNVTFRTO1xuICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihtYXhSZXN1bHRzKSB8fCBtYXhSZXN1bHRzIDwgTUlOX01BWF9SRVNVTFRTIHx8IG1heFJlc3VsdHMgPiBNQVhfTUFYX1JFU1VMVFMpIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFxuICAgICAgICBgb3B0aW9ucy5tYXhSZXN1bHRzIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuICR7TUlOX01BWF9SRVNVTFRTfSBhbmQgJHtNQVhfTUFYX1JFU1VMVFN9LCBnb3QgJHtTdHJpbmcobWF4UmVzdWx0cyl9YCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5jbGllbnQgPSBjbGllbnQ7XG4gICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgbWF4UmVzdWx0cyxcbiAgICAgIHF1ZXJ5UmVzdWx0VHlwZTogb3B0aW9ucy5xdWVyeVJlc3VsdFR5cGUgPz8gREVGQVVMVF9RVUVSWV9SRVNVTFRfVFlQRSxcbiAgICB9O1xuICAgIHRoaXMucGFyc2VSZXN1bHRTZXRPcHRpb25zID0gb3B0aW9ucy5wYXJzZVJlc3VsdFNldE9wdGlvbnM7XG4gICAgLy8gRGVmYXVsdCByZXVzZVBvbGljeSBpcyAncGFnaW5hdGUnOiByZXRhaW4gaGVhZGVycyAvIGhlYWRlci1yb3ctZHJvcHBlZCBhY3Jvc3MgcGFnZXMgb2Ygb25lIHF1ZXJ5LlxuICAgIHRoaXMucGFyc2VyID0gQXRoZW5hUXVlcnlSZXN1bHRQYXJzZXIuY3JlYXRlKCk7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXRzIHRoZSBidW5kbGVkIHBhcnNlciB3aGVuIGBxdWVyeUV4ZWN1dGlvbklkYCBkaWZmZXJzIGZyb20gdGhlIHByZXZpb3VzIGZldGNoIHNlcXVlbmNlLlxuICAgKlxuICAgKiBTYW1lLWV4ZWN1dGlvbiBwYWdpbmF0aW9uICh3aXRoIGBuZXh0VG9rZW5gKSBrZWVwcyBwYXJzZXIgc3RhdGUgc28gaGVhZGVyLXJvdyBoYW5kbGluZyBzdGF5cyBjb3JyZWN0LlxuICAgKlxuICAgKiBAcGFyYW0gcXVlcnlFeGVjdXRpb25JZCAtIEF0aGVuYSBxdWVyeSBleGVjdXRpb24gaWRlbnRpZmllciBmb3IgdGhlIHVwY29taW5nIGZldGNoLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBlbnN1cmVQYXJzZXJGb3JFeGVjdXRpb24gPSAocXVlcnlFeGVjdXRpb25JZDogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgaWYgKHRoaXMuYWN0aXZlUXVlcnlFeGVjdXRpb25JZCAhPT0gdW5kZWZpbmVkICYmIHRoaXMuYWN0aXZlUXVlcnlFeGVjdXRpb25JZCAhPT0gcXVlcnlFeGVjdXRpb25JZCkge1xuICAgICAgdGhpcy5wYXJzZXIucmVzZXQoKTtcbiAgICB9XG4gICAgdGhpcy5hY3RpdmVRdWVyeUV4ZWN1dGlvbklkID0gcXVlcnlFeGVjdXRpb25JZDtcbiAgfTtcblxuICAvKipcbiAgICogUmV0cmlldmVzIGEgc2luZ2xlIHJlc3VsdHMgcGFnZSBhcyBkaWN0aW9uYXJ5LXNoYXBlZCB7QGxpbmsgUGFyc2VkUm93fSB2YWx1ZXMuXG4gICAqXG4gICAqIFVzZXMge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFyc2VyLnBhcnNlUmVzdWx0U2V0fSBvbiB0aGUgQVdTIHJlc3BvbnNlLlxuICAgKiBXaGVuIGBxdWVyeUV4ZWN1dGlvbklkYCBkaWZmZXJzIGZyb20gdGhlIHByZXZpb3VzIGZldGNoIHNlcXVlbmNlLCB0aGUgYnVuZGxlZCBwYXJzZXIgaXMgcmVzZXQgZmlyc3QuXG4gICAqXG4gICAqIEBwYXJhbSBxdWVyeUV4ZWN1dGlvbklkIC0gQXRoZW5hIHF1ZXJ5IGV4ZWN1dGlvbiBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0gbmV4dFRva2VuIC0gUGFzcyBgdW5kZWZpbmVkYCBmaXJzdDsgc3Vic2VxdWVudCBjYWxscyB1c2Uge0BsaW5rIFBhZ2VSZXN1bHQubmV4dFRva2VufS5cbiAgICogQHJldHVybnMgUGFyc2VkIHJvd3MgcGx1cyBwYWdpbmF0aW9uIG1ldGFkYXRhIGZyb20gdGhpcyByZXNwb25zZSBvbmx5LlxuICAgKiBAdGhyb3dzIHtFcnJvcn0gV2hlbiBgcXVlcnlFeGVjdXRpb25JZGAgaXMgZW1wdHkgb3Igd2hpdGVzcGFjZSBvbmx5LlxuICAgKi9cbiAgYXN5bmMgZmV0Y2hQYWdlKFxuICAgIHF1ZXJ5RXhlY3V0aW9uSWQ6IHN0cmluZyxcbiAgICBuZXh0VG9rZW4/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8UGFnZVJlc3VsdDxQYXJzZWRSb3c+PiB7XG4gICAgaWYgKHF1ZXJ5RXhlY3V0aW9uSWQudHJpbSgpID09PSAnJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdxdWVyeUV4ZWN1dGlvbklkIG11c3QgYmUgYSBub24tZW1wdHkgc3RyaW5nJyk7XG4gICAgfVxuXG4gICAgdGhpcy5lbnN1cmVQYXJzZXJGb3JFeGVjdXRpb24ocXVlcnlFeGVjdXRpb25JZCk7XG5cbiAgICBjb25zdCBpbnB1dDogR2V0UXVlcnlSZXN1bHRzQ29tbWFuZElucHV0ID0ge1xuICAgICAgUXVlcnlFeGVjdXRpb25JZDogcXVlcnlFeGVjdXRpb25JZCxcbiAgICAgIE5leHRUb2tlbjogbmV4dFRva2VuLFxuICAgICAgTWF4UmVzdWx0czogdGhpcy5vcHRpb25zLm1heFJlc3VsdHMsXG4gICAgICBRdWVyeVJlc3VsdFR5cGU6IHRoaXMub3B0aW9ucy5xdWVyeVJlc3VsdFR5cGUsXG4gICAgfTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5jbGllbnQuc2VuZChuZXcgR2V0UXVlcnlSZXN1bHRzQ29tbWFuZChpbnB1dCkpO1xuXG4gICAgY29uc3Qgcm93cyA9IHRoaXMucGFyc2VyLnBhcnNlUmVzdWx0U2V0KHJlc3BvbnNlLlJlc3VsdFNldCwgdGhpcy5wYXJzZVJlc3VsdFNldE9wdGlvbnMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJvd3MsXG4gICAgICBuZXh0VG9rZW46IHJlc3BvbnNlLk5leHRUb2tlbixcbiAgICAgIHJvd0NvdW50OiByb3dzLmxlbmd0aCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBvbmUgcGFnZSBhbmQgbWFwcyBlYWNoIHtAbGluayBQYXJzZWRSb3d9IHRocm91Z2ggYHJvd1BhcnNlcmAuXG4gICAqXG4gICAqIFVzZXMge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFyc2VyLnBhcnNlUmVzdWx0U2V0V2l0aH0gb24gdGhlIEFXUyByZXNwb25zZS5cbiAgICogV2hlbiBgcXVlcnlFeGVjdXRpb25JZGAgZGlmZmVycyBmcm9tIHRoZSBwcmV2aW91cyBmZXRjaCBzZXF1ZW5jZSwgdGhlIGJ1bmRsZWQgcGFyc2VyIGlzIHJlc2V0IGZpcnN0LlxuICAgKlxuICAgKiBAdHlwZVBhcmFtIFQgLSBPdXRwdXQgdHlwZSBwcm9kdWNlZCBieSBgcm93UGFyc2VyYC5cbiAgICogQHBhcmFtIHF1ZXJ5RXhlY3V0aW9uSWQgLSBBdGhlbmEgcXVlcnkgZXhlY3V0aW9uIGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSByb3dQYXJzZXIgLSBDb252ZXJ0cyBlYWNoIGRpY3Rpb25hcnkgcm93IGludG8gYFRgLlxuICAgKiBAcGFyYW0gbmV4dFRva2VuIC0gUGFzcyBgdW5kZWZpbmVkYCBmaXJzdDsgc3Vic2VxdWVudCBjYWxscyB1c2Uge0BsaW5rIFBhZ2VSZXN1bHQubmV4dFRva2VufS5cbiAgICogQHJldHVybnMgVHJhbnNmb3JtZWQgcm93cyBwbHVzIHBhZ2luYXRpb24gbWV0YWRhdGEgZnJvbSB0aGlzIHJlc3BvbnNlIG9ubHkuXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBXaGVuIGBxdWVyeUV4ZWN1dGlvbklkYCBpcyBlbXB0eSBvciB3aGl0ZXNwYWNlIG9ubHkuXG4gICAqL1xuICBhc3luYyBmZXRjaFBhZ2VXaXRoPFQ+KFxuICAgIHF1ZXJ5RXhlY3V0aW9uSWQ6IHN0cmluZyxcbiAgICByb3dQYXJzZXI6IFJvd1BhcnNlcjxUPixcbiAgICBuZXh0VG9rZW4/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8UGFnZVJlc3VsdDxUPj4ge1xuICAgIGlmIChxdWVyeUV4ZWN1dGlvbklkLnRyaW0oKSA9PT0gJycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigncXVlcnlFeGVjdXRpb25JZCBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuICAgIH1cblxuICAgIHRoaXMuZW5zdXJlUGFyc2VyRm9yRXhlY3V0aW9uKHF1ZXJ5RXhlY3V0aW9uSWQpO1xuXG4gICAgY29uc3QgaW5wdXQ6IEdldFF1ZXJ5UmVzdWx0c0NvbW1hbmRJbnB1dCA9IHtcbiAgICAgIFF1ZXJ5RXhlY3V0aW9uSWQ6IHF1ZXJ5RXhlY3V0aW9uSWQsXG4gICAgICBOZXh0VG9rZW46IG5leHRUb2tlbixcbiAgICAgIE1heFJlc3VsdHM6IHRoaXMub3B0aW9ucy5tYXhSZXN1bHRzLFxuICAgICAgUXVlcnlSZXN1bHRUeXBlOiB0aGlzLm9wdGlvbnMucXVlcnlSZXN1bHRUeXBlLFxuICAgIH07XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuY2xpZW50LnNlbmQobmV3IEdldFF1ZXJ5UmVzdWx0c0NvbW1hbmQoaW5wdXQpKTtcblxuICAgIGNvbnN0IHJvd3MgPSB0aGlzLnBhcnNlci5wYXJzZVJlc3VsdFNldFdpdGgoXG4gICAgICByZXNwb25zZS5SZXN1bHRTZXQsXG4gICAgICByb3dQYXJzZXIsXG4gICAgICB0aGlzLnBhcnNlUmVzdWx0U2V0T3B0aW9ucyxcbiAgICApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJvd3MsXG4gICAgICBuZXh0VG9rZW46IHJlc3BvbnNlLk5leHRUb2tlbixcbiAgICAgIHJvd0NvdW50OiByb3dzLmxlbmd0aCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIExhemlseSB3YWxrcyBhbGwgcGFnZXMgZm9yIGFuIGV4ZWN1dGlvbiwgeWllbGRpbmcgb25lIHtAbGluayBQYWdlUmVzdWx0fSBvZiB7QGxpbmsgUGFyc2VkUm93fSBwZXIgc3RlcC5cbiAgICpcbiAgICogQHBhcmFtIHF1ZXJ5RXhlY3V0aW9uSWQgLSBBdGhlbmEgcXVlcnkgZXhlY3V0aW9uIGlkZW50aWZpZXIuXG4gICAqIEB5aWVsZHMgT25lIHBhZ2UgYXQgYSB0aW1lIHVudGlsIEFXUyByZXR1cm5zIG5vIGBOZXh0VG9rZW5gLlxuICAgKi9cbiAgYXN5bmMgKml0ZXJhdGVQYWdlcyhcbiAgICBxdWVyeUV4ZWN1dGlvbklkOiBzdHJpbmcsXG4gICk6IEFzeW5jR2VuZXJhdG9yPFBhZ2VSZXN1bHQ8UGFyc2VkUm93Pj4ge1xuICAgIGxldCBuZXh0VG9rZW46IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIGRvIHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmZldGNoUGFnZShxdWVyeUV4ZWN1dGlvbklkLCBuZXh0VG9rZW4pO1xuICAgICAgeWllbGQgcGFnZTtcbiAgICAgIG5leHRUb2tlbiA9IHBhZ2UubmV4dFRva2VuO1xuICAgIH0gd2hpbGUgKG5leHRUb2tlbik7XG4gIH1cblxuICAvKipcbiAgICogU2FtZSBhcyB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYWdlci5pdGVyYXRlUGFnZXN9IGJ1dCBtYXBzIGVhY2ggcm93IHRocm91Z2ggYHJvd1BhcnNlcmAgb24gZXZlcnkgcGFnZS5cbiAgICpcbiAgICogQHR5cGVQYXJhbSBUIC0gT3V0cHV0IHR5cGUgZW1pdHRlZCBpbiB7QGxpbmsgUGFnZVJlc3VsdC5yb3dzfS5cbiAgICogQHBhcmFtIHF1ZXJ5RXhlY3V0aW9uSWQgLSBBdGhlbmEgcXVlcnkgZXhlY3V0aW9uIGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSByb3dQYXJzZXIgLSBDb252ZXJ0cyBlYWNoIHBhcnNlZCByb3cgaW50byBgVGAuXG4gICAqIEB5aWVsZHMgU3VjY2Vzc2l2ZSB7QGxpbmsgUGFnZVJlc3VsdH0gdmFsdWVzIHdob3NlIGByb3dzYCBhcmUgdHlwZWQgYXMgYFRgLlxuICAgKi9cbiAgYXN5bmMgKml0ZXJhdGVQYWdlc1dpdGg8VD4oXG4gICAgcXVlcnlFeGVjdXRpb25JZDogc3RyaW5nLFxuICAgIHJvd1BhcnNlcjogUm93UGFyc2VyPFQ+LFxuICApOiBBc3luY0dlbmVyYXRvcjxQYWdlUmVzdWx0PFQ+PiB7XG4gICAgbGV0IG5leHRUb2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgZG8ge1xuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZmV0Y2hQYWdlV2l0aChxdWVyeUV4ZWN1dGlvbklkLCByb3dQYXJzZXIsIG5leHRUb2tlbik7XG4gICAgICB5aWVsZCBwYWdlO1xuICAgICAgbmV4dFRva2VuID0gcGFnZS5uZXh0VG9rZW47XG4gICAgfSB3aGlsZSAobmV4dFRva2VuKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGbGF0dGVucyB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYWdlci5pdGVyYXRlUGFnZXN9IGludG8gaW5kaXZpZHVhbCB7QGxpbmsgUGFyc2VkUm93fSB2YWx1ZXMgKG9uZSByb3cgcGVyIGBuZXh0KClgKS5cbiAgICpcbiAgICogT25seSBvbmUgcGFnZSBvZiByb3dzIGlzIGhlbGQgaW4gbWVtb3J5IGF0IGEgdGltZS5cbiAgICpcbiAgICogQHBhcmFtIHF1ZXJ5RXhlY3V0aW9uSWQgLSBBdGhlbmEgcXVlcnkgZXhlY3V0aW9uIGlkZW50aWZpZXIuXG4gICAqIEB5aWVsZHMgRWFjaCBkaWN0aW9uYXJ5LXNoYXBlZCByb3cgaW4gZXhlY3V0aW9uIG9yZGVyLlxuICAgKi9cbiAgaXRlcmF0ZVJvd3MoXG4gICAgcXVlcnlFeGVjdXRpb25JZDogc3RyaW5nLFxuICApOiBBc3luY0dlbmVyYXRvcjxQYXJzZWRSb3c+O1xuXG4gIC8qKlxuICAgKiBGbGF0dGVucyB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYWdlci5pdGVyYXRlUGFnZXNXaXRofSBpbnRvIGluZGl2aWR1YWwgYFRgIHZhbHVlcyAob25lIHJvdyBwZXIgYG5leHQoKWApLlxuICAgKlxuICAgKiBPbmx5IG9uZSBwYWdlIG9mIHJvd3MgaXMgaGVsZCBpbiBtZW1vcnkgYXQgYSB0aW1lLlxuICAgKlxuICAgKiBAdHlwZVBhcmFtIFQgLSBPdXRwdXQgdHlwZSBwcm9kdWNlZCBieSBgcm93UGFyc2VyYC5cbiAgICogQHBhcmFtIHF1ZXJ5RXhlY3V0aW9uSWQgLSBBdGhlbmEgcXVlcnkgZXhlY3V0aW9uIGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSByb3dQYXJzZXIgLSBDb252ZXJ0cyBlYWNoIHBhcnNlZCByb3cgaW50byBgVGAuXG4gICAqIEB5aWVsZHMgRWFjaCB0cmFuc2Zvcm1lZCByb3cgaW4gZXhlY3V0aW9uIG9yZGVyLlxuICAgKi9cbiAgaXRlcmF0ZVJvd3M8VD4oXG4gICAgcXVlcnlFeGVjdXRpb25JZDogc3RyaW5nLFxuICAgIHJvd1BhcnNlcjogUm93UGFyc2VyPFQ+LFxuICApOiBBc3luY0dlbmVyYXRvcjxUPjtcblxuICAvKipcbiAgICogU2hhcmVkIGltcGxlbWVudGF0aW9uIGZvciB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYWdlci5pdGVyYXRlUm93c30gb3ZlcmxvYWRzLlxuICAgKlxuICAgKiBEZWxlZ2F0ZXMgdG8ge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFnZXIuaXRlcmF0ZVBhZ2VzfSB3aGVuIGByb3dQYXJzZXJgIGlzIG9taXR0ZWQ7IG90aGVyd2lzZSB0b1xuICAgKiB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYWdlci5pdGVyYXRlUGFnZXNXaXRofS5cbiAgICovXG4gIGFzeW5jICppdGVyYXRlUm93czxUPihcbiAgICBxdWVyeUV4ZWN1dGlvbklkOiBzdHJpbmcsXG4gICAgcm93UGFyc2VyPzogUm93UGFyc2VyPFQ+LFxuICApOiBBc3luY0dlbmVyYXRvcjxQYXJzZWRSb3cgfCBUPiB7XG4gICAgY29uc3QgcGFnZXMgPSByb3dQYXJzZXJcbiAgICAgID8gdGhpcy5pdGVyYXRlUGFnZXNXaXRoKHF1ZXJ5RXhlY3V0aW9uSWQsIHJvd1BhcnNlcilcbiAgICAgIDogdGhpcy5pdGVyYXRlUGFnZXMocXVlcnlFeGVjdXRpb25JZCk7XG5cbiAgICBmb3IgYXdhaXQgKGNvbnN0IHBhZ2Ugb2YgcGFnZXMpIHtcbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHBhZ2Uucm93cykge1xuICAgICAgICB5aWVsZCByb3c7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGJ1bmRsZWQgcGFyc2VyJ3MgbW9zdCByZWNlbnQgaGVhZGVyLXJvdyBkZWNpc2lvbi5cbiAgICpcbiAgICogVXNlZnVsIHdoZW4ge0BsaW5rIFBhZ2VyT3B0aW9ucy5wYXJzZVJlc3VsdFNldE9wdGlvbnN9IHVzZXMgYHNraXBIZWFkZXJSb3c6ICdhdXRvJ2AuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBsYXN0IHtAbGluayBIZWFkZXJSb3dEZWNpc2lvbn0sIG9yIGBudWxsYCBiZWZvcmUgYW55IHBhcnNlIC8gYWZ0ZXIge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFnZXIucmVzZXR9LlxuICAgKi9cbiAgZ2V0TGFzdEhlYWRlclJvd0RlY2lzaW9uKCk6IEhlYWRlclJvd0RlY2lzaW9uIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VyLmdldExhc3RIZWFkZXJSb3dEZWNpc2lvbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFycyB0aGUgYnVuZGxlZCB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYXJzZXJ9IHN0YXRlIGFuZCB0aGUgdHJhY2tlZCBhY3RpdmUgZXhlY3V0aW9uIGlkLlxuICAgKlxuICAgKiBVc3VhbGx5IHVubmVjZXNzYXJ5OiB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYWdlci5mZXRjaFBhZ2V9IGFuZCB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYWdlci5mZXRjaFBhZ2VXaXRofVxuICAgKiByZXNldCBhdXRvbWF0aWNhbGx5IHdoZW4gYHF1ZXJ5RXhlY3V0aW9uSWRgIGNoYW5nZXMuIENhbGwgZXhwbGljaXRseSB0byBjbGVhciBzdGF0ZSB3aXRob3V0IHN0YXJ0aW5nIGEgbmV3IGZldGNoXG4gICAqIChmb3IgZXhhbXBsZSBzbyB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYWdlci5nZXRMYXN0SGVhZGVyUm93RGVjaXNpb259IHJldHVybnMgYG51bGxgKS5cbiAgICovXG4gIHJlc2V0KCk6IHZvaWQge1xuICAgIHRoaXMucGFyc2VyLnJlc2V0KCk7XG4gICAgdGhpcy5hY3RpdmVRdWVyeUV4ZWN1dGlvbklkID0gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKiBSZS1leHBvcnRzIHtAbGluayBRdWVyeVJlc3VsdFR5cGV9IGZyb20gYEBhd3Mtc2RrL2NsaWVudC1hdGhlbmFgLiAqL1xuZXhwb3J0IHsgUXVlcnlSZXN1bHRUeXBlIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWF0aGVuYSc7XG5leHBvcnQge1xuICBFWFRSQV9DT0xVTU5TX0tFWSxcbiAgaGVhZGVyc0Zyb21NZXRhLFxuICBpc0hlYWRlclJvdyxcbiAgcGFyc2VSZXN1bHRTZXREZXRhaWxlZE9uY2UsXG4gIHBhcnNlUmVzdWx0U2V0SXRlck9uY2UsXG4gIHBhcnNlUmVzdWx0U2V0T25jZSxcbiAgcGFyc2VSZXN1bHRTZXRXaXRoT25jZSxcbiAgcm93VG9PYmplY3QsXG4gIHJvd1RvVHlwZWRPYmplY3QsXG4gIHRvQm9vbGVhbixcbiAgdG9EYXRlLFxuICB0b051bWJlcixcbn0gZnJvbSAnYXRoZW5hLXF1ZXJ5LXJlc3VsdC1wYXJzZXInO1xuZXhwb3J0IHR5cGUge1xuICBBdGhlbmFRdWVyeVJlc3VsdFBhcnNlck9wdGlvbnMsXG4gIEF0aGVuYVR5cGVkVmFsdWUsXG4gIENvbHVtbkNvdW50TWlzbWF0Y2hCZWhhdmlvcixcbiAgSGVhZGVyUm93RGVjaXNpb24sXG4gIE1heFJvd3NFeGNlZWRlZEJlaGF2aW9yLFxuICBQYXJzZVJlc3VsdFNldERpYWdub3N0aWNzLFxuICBQYXJzZVJlc3VsdFNldERldGFpbGVkUmVzdWx0LFxuICBQYXJzZVJlc3VsdFNldE9wdGlvbnMsXG4gIFBhcnNlUmVzdWx0U2V0VW5hdmFpbGFibGVSZWFzb24sXG4gIFBhcnNlZFJvdyxcbiAgUGFyc2VyUmV1c2VQb2xpY3ksXG4gIFJvd1BhcnNlcixcbiAgVHlwZWRQYXJzZWRSb3csXG4gIFVuYXZhaWxhYmxlUmVzdWx0QmVoYXZpb3IsXG59IGZyb20gJ2F0aGVuYS1xdWVyeS1yZXN1bHQtcGFyc2VyJzsiXX0=
269
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMERBTWdDO0FBQ2hDLDJFQU9vQztBQUNwQyxxQ0FHa0I7QUFFbEIsa0hBQWtIO0FBQ2xILE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDO0FBQ2pDLHVFQUF1RTtBQUN2RSxNQUFNLHlCQUF5QixHQUFHLCtCQUFlLENBQUMsU0FBUyxDQUFDO0FBb0Q1RDs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQWEsc0JBQXNCO0lBRWpDOzs7Ozs7T0FNRztJQUNILE1BQU0sQ0FBQyxXQUFXLENBQUksVUFBeUI7UUFDN0MsT0FBTyxVQUFVLENBQUMsU0FBUyxLQUFLLFNBQVMsQ0FBQztJQUM1QyxDQUFDO0lBYUQ7Ozs7OztPQU1HO0lBQ0gsWUFBWSxNQUFvQixFQUFFLFVBQXdCLEVBQUU7UUFnQjVEOzs7Ozs7V0FNRztRQUNjLDZCQUF3QixHQUFHLENBQUMsZ0JBQXdCLEVBQVEsRUFBRTtZQUM3RSxJQUFJLElBQUksQ0FBQyxzQkFBc0IsS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLHNCQUFzQixLQUFLLGdCQUFnQixFQUFFLENBQUM7Z0JBQ2xHLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDdEIsQ0FBQztZQUNELElBQUksQ0FBQyxzQkFBc0IsR0FBRyxnQkFBZ0IsQ0FBQztRQUNqRCxDQUFDLENBQUM7UUFFRjs7Ozs7OztXQU9HO1FBQ2Msd0JBQW1CLEdBQUcsS0FBSyxFQUMxQyxnQkFBd0IsRUFDeEIsU0FBa0IsRUFDcUIsRUFBRTtZQUN6QyxJQUFJLGdCQUFnQixDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDO2dCQUNuQyxNQUFNLElBQUkseURBQWdELEVBQUUsQ0FBQztZQUMvRCxDQUFDO1lBRUQsSUFBSSxDQUFDLHdCQUF3QixDQUFDLGdCQUFnQixDQUFDLENBQUM7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QUFDMUIsb0lBQUEsc0JBQXNCLE9BQUE7QUFDdEIsZ0lBQUEsa0JBQWtCLE9BQUE7QUFDbEIsb0lBQUEsc0JBQXNCLE9BQUE7QUFDdEIseUhBQUEsV0FBVyxPQUFBO0FBQ1gsOEhBQUEsZ0JBQWdCLE9BQUE7QUFDaEIsdUhBQUEsU0FBUyxPQUFBO0FBQ1Qsb0hBQUEsTUFBTSxPQUFBO0FBQ04sc0hBQUEsUUFBUSxPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQXRoZW5hQ2xpZW50LFxuICBHZXRRdWVyeVJlc3VsdHNDb21tYW5kLFxuICBRdWVyeVJlc3VsdFR5cGUsXG4gIHR5cGUgR2V0UXVlcnlSZXN1bHRzQ29tbWFuZElucHV0LFxuICB0eXBlIEdldFF1ZXJ5UmVzdWx0c0NvbW1hbmRPdXRwdXQsXG59IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1hdGhlbmEnO1xuaW1wb3J0IHtcbiAgQXRoZW5hUXVlcnlSZXN1bHRQYXJzZXIsXG4gIHR5cGUgSGVhZGVyUm93RGVjaXNpb24sXG4gIHR5cGUgUGFyc2VSZXN1bHRTZXREaWFnbm9zdGljcyxcbiAgdHlwZSBQYXJzZVJlc3VsdFNldE9wdGlvbnMsXG4gIHR5cGUgUGFyc2VkUm93LFxuICB0eXBlIFJvd1BhcnNlcixcbn0gZnJvbSAnYXRoZW5hLXF1ZXJ5LXJlc3VsdC1wYXJzZXInO1xuaW1wb3J0IHtcbiAgQXRoZW5hUXVlcnlSZXN1bHRQYWdlckVtcHR5UXVlcnlFeGVjdXRpb25JZEVycm9yLFxuICBBdGhlbmFRdWVyeVJlc3VsdFBhZ2VySW52YWxpZE1heFJlc3VsdHNFcnJvcixcbn0gZnJvbSAnLi9lcnJvcnMnO1xuXG4vKiogRGVmYXVsdCBtYXhpbXVtIG51bWJlciBvZiByZXN1bHQgcm93cyByZXF1ZXN0ZWQgcGVyIHtAbGluayBBdGhlbmFRdWVyeVJlc3VsdFBhZ2VyfSBBUEkgY2FsbCAoYE1heFJlc3VsdHNgKS4gKi9cbmNvbnN0IERFRkFVTFRfTUFYX1JFU1VMVFMgPSAxMDAwO1xuLyoqIERlZmF1bHQgYFF1ZXJ5UmVzdWx0VHlwZWAgZm9yd2FyZGVkIHRvIEF0aGVuYSBgR2V0UXVlcnlSZXN1bHRzYC4gKi9cbmNvbnN0IERFRkFVTFRfUVVFUllfUkVTVUxUX1RZUEUgPSBRdWVyeVJlc3VsdFR5cGUuREFUQV9ST1dTO1xuXG4vKipcbiAqIE9uZSBwYWdlIG9mIEF0aGVuYSBxdWVyeSByZXN1bHRzIHJldHVybmVkIGJ5IHtAbGluayBBdGhlbmFRdWVyeVJlc3VsdFBhZ2VyfSBhZnRlciBhIGZldGNoIG9yIGdlbmVyYXRvciBzdGVwLlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFJvdyByZXByZXNlbnRhdGlvbjsgdXNlIHtAbGluayBQYXJzZWRSb3d9IG9yIGEgdHlwZSBwcm9kdWNlZCBieSB7QGxpbmsgUm93UGFyc2VyfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYWdlUmVzdWx0PFQ+IHtcbiAgLyoqIFBhcnNlZCByb3dzIGZvciB0aGlzIHBhZ2Ugb25seS4gKi9cbiAgcm93czogVFtdO1xuICAvKiogQ29udGludWF0aW9uIHRva2VuIGZvciB0aGUgZm9sbG93aW5nIHBhZ2UgKGB1bmRlZmluZWRgIHdoZW4gdGhpcyBpcyB0aGUgbGFzdCBwYWdlKS4gKi9cbiAgbmV4dFRva2VuPzogc3RyaW5nO1xuICAvKiogU2FtZSBhcyBgcm93cy5sZW5ndGhgIGZvciBjb252ZW5pZW5jZS4gKi9cbiAgcm93Q291bnQ6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBPbmUgcGFnZSBvZiBBdGhlbmEgcXVlcnkgcmVzdWx0cyB3aXRoIHtAbGluayBQYXJzZVJlc3VsdFNldERpYWdub3N0aWNzfSBmcm9tXG4gKiB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYXJzZXIucGFyc2VSZXN1bHRTZXREZXRhaWxlZH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGFnZURldGFpbGVkUmVzdWx0IGV4dGVuZHMgUGFnZVJlc3VsdDxQYXJzZWRSb3c+IHtcbiAgLyoqIFBhcnNlciBkaWFnbm9zdGljcyBmb3IgdGhpcyBwYWdlIG9ubHkgKGhlYWRlci1yb3cgZGVjaXNpb24sIHJhdyByb3cgY291bnQsIHRydW5jYXRpb24sIOKApikuICovXG4gIGRpYWdub3N0aWNzOiBQYXJzZVJlc3VsdFNldERpYWdub3N0aWNzO1xufVxuXG4vKipcbiAqIFNldHRpbmdzIGFwcGxpZWQgdG8gZXZlcnkgYEdldFF1ZXJ5UmVzdWx0c2AgaW52b2NhdGlvbiBtYWRlIGJ5IHtAbGluayBBdGhlbmFRdWVyeVJlc3VsdFBhZ2VyfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYWdlck9wdGlvbnMge1xuICAvKipcbiAgICogYE1heFJlc3VsdHNgIHBlciByZXF1ZXN0IOKAlCBtdXN0IGJlIGFuIGludGVnZXIgZnJvbSAxIHRocm91Z2ggMTAwMCAoQXRoZW5hIGxpbWl0cykuXG4gICAqIEBkZWZhdWx0VmFsdWUgMTAwMFxuICAgKi9cbiAgbWF4UmVzdWx0cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIEF0aGVuYSBgR2V0UXVlcnlSZXN1bHRzYCB7QGxpbmsgUXVlcnlSZXN1bHRUeXBlfSDigJQgYW55IG1lbWJlciBvZiB0aGUgQVdTIFNESyBlbnVtXG4gICAqIChmb3IgZXhhbXBsZSB7QGxpbmsgUXVlcnlSZXN1bHRUeXBlLkRBVEFfUk9XU30gZm9yIHRhYnVsYXIgcm93cyBvciB7QGxpbmsgUXVlcnlSZXN1bHRUeXBlLkRBVEFfTUFOSUZFU1R9XG4gICAqIGZvciBDVEFTIC8gVU5MT0FEIC8gSU5TRVJUIG1hbmlmZXN0IG91dHB1dHMgd2hlbiBBdGhlbmEgc3VwcG9ydHMgdGhlbSkuXG4gICAqIEBkZWZhdWx0VmFsdWUge0BsaW5rIFF1ZXJ5UmVzdWx0VHlwZS5EQVRBX1JPV1N9XG4gICAqL1xuICBxdWVyeVJlc3VsdFR5cGU/OiBRdWVyeVJlc3VsdFR5cGU7XG4gIC8qKlxuICAgKiBPcHRpb25zIGZvcndhcmRlZCB0byBldmVyeSB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYXJzZXIucGFyc2VSZXN1bHRTZXR9IC9cbiAgICoge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFyc2VyLnBhcnNlUmVzdWx0U2V0V2l0aH0gY2FsbCAoZm9yIGV4YW1wbGVcbiAgICogYGNvbHVtbkNvdW50TWlzbWF0Y2hCZWhhdmlvcmAsIGBza2lwSGVhZGVyUm93YCwgYGhlYWRlclJvd0RldGVjdGlvblN0cmF0ZWd5YCxcbiAgICogYHVuYXZhaWxhYmxlUmVzdWx0QmVoYXZpb3JgLCBgbWF4Um93c2ApLlxuICAgKlxuICAgKiBAc2VlIFBhcnNlUmVzdWx0U2V0T3B0aW9uc1xuICAgKi9cbiAgcGFyc2VSZXN1bHRTZXRPcHRpb25zPzogUGFyc2VSZXN1bHRTZXRPcHRpb25zO1xufVxuXG4vKipcbiAqIFBhZ2luYXRlcyBBdGhlbmEgYEdldFF1ZXJ5UmVzdWx0c2AgKEFXUyBTREsgZm9yIEphdmFTY3JpcHQgdjMpOiB3YWxrcyBgTmV4dFRva2VuYCBhbmQgcGFyc2VzIHRhYnVsYXIgcm93cyB3aXRoXG4gKiBgYXRoZW5hLXF1ZXJ5LXJlc3VsdC1wYXJzZXJgIHdoZW4gbmVlZGVkLlxuICpcbiAqIFByb3ZpZGVzIHBhaXJlZCBBUElzIGZvciByYXcge0BsaW5rIFBhcnNlZFJvd30gYWNjZXNzIHZlcnN1cyBjdXN0b20ge0BsaW5rIFJvd1BhcnNlcn0gbWFwcGluZyBhdCB0aGUgcGFnZSBsZXZlbFxuICogKGBmZXRjaFBhZ2VgIC8gYGZldGNoUGFnZVdpdGhgLCBgaXRlcmF0ZVBhZ2VzYCAvIGBpdGVyYXRlUGFnZXNXaXRoYCkgYW5kIGF0IHRoZSByb3cgbGV2ZWxcbiAqIChgaXRlcmF0ZVJvd3NgIHdpdGggb3Igd2l0aG91dCBgcm93UGFyc2VyYCkuIFVzZSB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYWdlci5mZXRjaFBhZ2VEZXRhaWxlZH0gd2hlblxuICogcGVyLXBhZ2Uge0BsaW5rIFBhcnNlUmVzdWx0U2V0RGlhZ25vc3RpY3N9IGlzIG5lZWRlZCAoZm9yIGV4YW1wbGUgYGhlYWRlclJvd0RlY2lzaW9uYCwgYHJhd1Jvd0NvdW50YCxcbiAqIGB0cnVuY2F0ZWRCeU1heFJvd3NgKS5cbiAqXG4gKiBDb25zdHJ1Y3RvciBgbWF4UmVzdWx0c2AsIGBxdWVyeVJlc3VsdFR5cGVgLCBhbmQgb3B0aW9uYWwgYHBhcnNlUmVzdWx0U2V0T3B0aW9uc2AgYXJlIGFwcGxpZWQgb24gZXZlcnlcbiAqIGBHZXRRdWVyeVJlc3VsdHNgIHJlcXVlc3QgYW5kIHtAbGluayBBdGhlbmFRdWVyeVJlc3VsdFBhcnNlcn0gaW52b2NhdGlvbiByZXNwZWN0aXZlbHkuXG4gKiBXaGVuIGBxdWVyeUV4ZWN1dGlvbklkYCBjaGFuZ2VzIGJldHdlZW4gZmV0Y2hlcywgdGhlIGJ1bmRsZWQgcGFyc2VyIGlzIHJlc2V0IGF1dG9tYXRpY2FsbHkuXG4gKlxuICogRG9lcyBub3Qgd2FpdCBmb3IgcXVlcnkgY29tcGxldGlvbiBvciBhZGQgQXRoZW5hLXNwZWNpZmljIHJldHJ5OiBjYWxsZXJzIHNob3VsZCB3YWl0IHVudGlsIHRoZSBleGVjdXRpb25cbiAqIHN1Y2NlZWRzIChmb3IgZXhhbXBsZSB2aWEgYEdldFF1ZXJ5RXhlY3V0aW9uYCkgYW5kIGNvbmZpZ3VyZSBTREsgLyBhcHBsaWNhdGlvbi1sZXZlbCByZXRyeSBmb3IgdGhyb3R0bGluZy5cbiAqIEFXUyBTREsgZXJyb3JzIGZyb20gYEdldFF1ZXJ5UmVzdWx0c2AgYXJlIHByb3BhZ2F0ZWQgYXMgdGhyb3duLlxuICpcbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NKYXZhU2NyaXB0U0RLL3YzL2xhdGVzdC9jbGllbnQvYXRoZW5hL2NvbW1hbmQvR2V0UXVlcnlSZXN1bHRzQ29tbWFuZC8gfCBHZXRRdWVyeVJlc3VsdHNDb21tYW5kIChBV1MgU0RLKX1cbiAqL1xuZXhwb3J0IGNsYXNzIEF0aGVuYVF1ZXJ5UmVzdWx0UGFnZXIge1xuXG4gIC8qKlxuICAgKiBSZXBvcnRzIHdoZXRoZXIgYW5vdGhlciByZXN1bHRzIHBhZ2UgaXMgYXZhaWxhYmxlIGZvciB0aGUgc2FtZSBxdWVyeSBleGVjdXRpb24uXG4gICAqXG4gICAqIEB0eXBlUGFyYW0gVCAtIFJvdyB0eXBlIGhlbGQgaW4ge0BsaW5rIFBhZ2VSZXN1bHQucm93c30uXG4gICAqIEBwYXJhbSBwYWdlUmVzdWx0IC0gVGhlIG1vc3QgcmVjZW50bHkgcmV0cmlldmVkIHBhZ2UgZnJvbSBgZmV0Y2hQYWdlYCwgYGZldGNoUGFnZVdpdGhgLCBvciBhIHBhZ2UgaXRlcmF0b3IuXG4gICAqIEByZXR1cm5zIGB0cnVlYCB3aGVuIHtAbGluayBQYWdlUmVzdWx0Lm5leHRUb2tlbn0gaXMgZGVmaW5lZCBhbmQgYW5vdGhlciBwYWdlIHNob3VsZCBiZSBmZXRjaGVkLlxuICAgKi9cbiAgc3RhdGljIGhhc05leHRQYWdlPFQ+KHBhZ2VSZXN1bHQ6IFBhZ2VSZXN1bHQ8VD4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gcGFnZVJlc3VsdC5uZXh0VG9rZW4gIT09IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKiBTREsgdjMgY2xpZW50IHVzZWQgZm9yIGV2ZXJ5IGBHZXRRdWVyeVJlc3VsdHNgIGNhbGwuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50OiBBdGhlbmFDbGllbnQ7XG4gIC8qKiBOb3JtYWxpemVkIHBhZ2VyIHNldHRpbmdzIChldmVyeSBmaWVsZCBzZXQgYWZ0ZXIgbWVyZ2luZyBkZWZhdWx0cykuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogUmVxdWlyZWQ8UGljazxQYWdlck9wdGlvbnMsICdtYXhSZXN1bHRzJyB8ICdxdWVyeVJlc3VsdFR5cGUnPj47XG4gIC8qKiBQYXJzZXIgb3B0aW9ucyBhcHBsaWVkIG9uIGV2ZXJ5IHBhZ2UgcGFyc2UgKHVuZGVmaW5lZCB1c2VzIHBhcnNlciBkZWZhdWx0cykuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcGFyc2VSZXN1bHRTZXRPcHRpb25zPzogUGFyc2VSZXN1bHRTZXRPcHRpb25zO1xuICAvKiogU3RhdGVmdWwgcGFyc2VyIHJldXNlZCBhY3Jvc3MgcGFnZXMgb2YgdGhlIHNhbWUgZXhlY3V0aW9uOyByZXNldCBvbiBleGVjdXRpb24gY2hhbmdlIG9yIHtAbGluayBBdGhlbmFRdWVyeVJlc3VsdFBhZ2VyLnJlc2V0fS4gKi9cbiAgcHJpdmF0ZSBwYXJzZXI6IEF0aGVuYVF1ZXJ5UmVzdWx0UGFyc2VyO1xuICAvKiogTGFzdCBgcXVlcnlFeGVjdXRpb25JZGAgcGFzc2VkIHRvIGZldGNoIG1ldGhvZHM7IHVzZWQgdG8gYXV0by1yZXNldCB0aGUgcGFyc2VyLiAqL1xuICBwcml2YXRlIGFjdGl2ZVF1ZXJ5RXhlY3V0aW9uSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHBhZ2VyIGJvdW5kIHRvIGBjbGllbnRgIHdpdGggb3B0aW9uYWwgcGVyLXJlcXVlc3QgZGVmYXVsdHMuXG4gICAqXG4gICAqIEBwYXJhbSBjbGllbnQgLSBTREsgdjMgYEF0aGVuYUNsaWVudGAgdXNlZCB0byBjYWxsIGBHZXRRdWVyeVJlc3VsdHNgLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIGBNYXhSZXN1bHRzYCwgYFF1ZXJ5UmVzdWx0VHlwZWAsIGFuZCBgUGFyc2VSZXN1bHRTZXRPcHRpb25zYDsgZGVmYXVsdHMgYXBwbHkgd2hlbiBvbWl0dGVkLlxuICAgKiBAdGhyb3dzIHtBdGhlbmFRdWVyeVJlc3VsdFBhZ2VySW52YWxpZE1heFJlc3VsdHNFcnJvcn0gV2hlbiBgbWF4UmVzdWx0c2AgaXMgbm90IGFuIGludGVnZXIgaW4gYDEuLjEwMDBgIGluY2x1c2l2ZS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKGNsaWVudDogQXRoZW5hQ2xpZW50LCBvcHRpb25zOiBQYWdlck9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IG1heFJlc3VsdHMgPSBvcHRpb25zLm1heFJlc3VsdHMgPz8gREVGQVVMVF9NQVhfUkVTVUxUUztcbiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIobWF4UmVzdWx0cykgfHwgbWF4UmVzdWx0cyA8IDEgfHwgbWF4UmVzdWx0cyA+IDEwMDApIHtcbiAgICAgIHRocm93IG5ldyBBdGhlbmFRdWVyeVJlc3VsdFBhZ2VySW52YWxpZE1heFJlc3VsdHNFcnJvcihtYXhSZXN1bHRzKTtcbiAgICB9XG5cbiAgICB0aGlzLmNsaWVudCA9IGNsaWVudDtcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBtYXhSZXN1bHRzLFxuICAgICAgcXVlcnlSZXN1bHRUeXBlOiBvcHRpb25zLnF1ZXJ5UmVzdWx0VHlwZSA/PyBERUZBVUxUX1FVRVJZX1JFU1VMVF9UWVBFLFxuICAgIH07XG4gICAgdGhpcy5wYXJzZVJlc3VsdFNldE9wdGlvbnMgPSBvcHRpb25zLnBhcnNlUmVzdWx0U2V0T3B0aW9ucztcbiAgICAvLyBEZWZhdWx0IHJldXNlUG9saWN5IGlzICdwYWdpbmF0ZSc6IHJldGFpbiBoZWFkZXJzIC8gaGVhZGVyLXJvdy1kcm9wcGVkIGFjcm9zcyBwYWdlcyBvZiBvbmUgcXVlcnkuXG4gICAgdGhpcy5wYXJzZXIgPSBBdGhlbmFRdWVyeVJlc3VsdFBhcnNlci5jcmVhdGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNldHMgdGhlIGJ1bmRsZWQgcGFyc2VyIHdoZW4gYHF1ZXJ5RXhlY3V0aW9uSWRgIGRpZmZlcnMgZnJvbSB0aGUgcHJldmlvdXMgZmV0Y2ggc2VxdWVuY2UuXG4gICAqXG4gICAqIFNhbWUtZXhlY3V0aW9uIHBhZ2luYXRpb24gKHdpdGggYG5leHRUb2tlbmApIGtlZXBzIHBhcnNlciBzdGF0ZSBzbyBoZWFkZXItcm93IGhhbmRsaW5nIHN0YXlzIGNvcnJlY3QuXG4gICAqXG4gICAqIEBwYXJhbSBxdWVyeUV4ZWN1dGlvbklkIC0gQXRoZW5hIHF1ZXJ5IGV4ZWN1dGlvbiBpZGVudGlmaWVyIGZvciB0aGUgdXBjb21pbmcgZmV0Y2guXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGVuc3VyZVBhcnNlckZvckV4ZWN1dGlvbiA9IChxdWVyeUV4ZWN1dGlvbklkOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5hY3RpdmVRdWVyeUV4ZWN1dGlvbklkICE9PSB1bmRlZmluZWQgJiYgdGhpcy5hY3RpdmVRdWVyeUV4ZWN1dGlvbklkICE9PSBxdWVyeUV4ZWN1dGlvbklkKSB7XG4gICAgICB0aGlzLnBhcnNlci5yZXNldCgpO1xuICAgIH1cbiAgICB0aGlzLmFjdGl2ZVF1ZXJ5RXhlY3V0aW9uSWQgPSBxdWVyeUV4ZWN1dGlvbklkO1xuICB9O1xuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYHF1ZXJ5RXhlY3V0aW9uSWRgLCBlbnN1cmVzIHBhcnNlciBzdGF0ZSwgYW5kIGludm9rZXMgYEdldFF1ZXJ5UmVzdWx0c2AuXG4gICAqXG4gICAqIEBwYXJhbSBxdWVyeUV4ZWN1dGlvbklkIC0gQXRoZW5hIHF1ZXJ5IGV4ZWN1dGlvbiBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0gbmV4dFRva2VuIC0gQ29udGludWF0aW9uIHRva2VuIGZyb20gYSBwcmlvciBwYWdlLCBpZiBhbnkuXG4gICAqIEByZXR1cm5zIFJhdyBBV1MgcmVzcG9uc2UgZm9yIHRoZSByZXF1ZXN0ZWQgcGFnZS5cbiAgICogQHRocm93cyB7QXRoZW5hUXVlcnlSZXN1bHRQYWdlckVtcHR5UXVlcnlFeGVjdXRpb25JZEVycm9yfSBXaGVuIGBxdWVyeUV4ZWN1dGlvbklkYCBpcyBlbXB0eSBvciB3aGl0ZXNwYWNlIG9ubHkuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHNlbmRHZXRRdWVyeVJlc3VsdHMgPSBhc3luYyAoXG4gICAgcXVlcnlFeGVjdXRpb25JZDogc3RyaW5nLFxuICAgIG5leHRUb2tlbj86IHN0cmluZyxcbiAgKTogUHJvbWlzZTxHZXRRdWVyeVJlc3VsdHNDb21tYW5kT3V0cHV0PiA9PiB7XG4gICAgaWYgKHF1ZXJ5RXhlY3V0aW9uSWQudHJpbSgpID09PSAnJykge1xuICAgICAgdGhyb3cgbmV3IEF0aGVuYVF1ZXJ5UmVzdWx0UGFnZXJFbXB0eVF1ZXJ5RXhlY3V0aW9uSWRFcnJvcigpO1xuICAgIH1cblxuICAgIHRoaXMuZW5zdXJlUGFyc2VyRm9yRXhlY3V0aW9uKHF1ZXJ5RXhlY3V0aW9uSWQpO1xuXG4gICAgY29uc3QgaW5wdXQ6IEdldFF1ZXJ5UmVzdWx0c0NvbW1hbmRJbnB1dCA9IHtcbiAgICAgIFF1ZXJ5RXhlY3V0aW9uSWQ6IHF1ZXJ5RXhlY3V0aW9uSWQsXG4gICAgICBOZXh0VG9rZW46IG5leHRUb2tlbixcbiAgICAgIE1heFJlc3VsdHM6IHRoaXMub3B0aW9ucy5tYXhSZXN1bHRzLFxuICAgICAgUXVlcnlSZXN1bHRUeXBlOiB0aGlzLm9wdGlvbnMucXVlcnlSZXN1bHRUeXBlLFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5jbGllbnQuc2VuZChuZXcgR2V0UXVlcnlSZXN1bHRzQ29tbWFuZChpbnB1dCkpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgYSBzaW5nbGUgcmVzdWx0cyBwYWdlIGFzIGRpY3Rpb25hcnktc2hhcGVkIHtAbGluayBQYXJzZWRSb3d9IHZhbHVlcy5cbiAgICpcbiAgICogVXNlcyB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYXJzZXIucGFyc2VSZXN1bHRTZXR9IG9uIHRoZSBBV1MgcmVzcG9uc2UuXG4gICAqIFdoZW4gYHF1ZXJ5RXhlY3V0aW9uSWRgIGRpZmZlcnMgZnJvbSB0aGUgcHJldmlvdXMgZmV0Y2ggc2VxdWVuY2UsIHRoZSBidW5kbGVkIHBhcnNlciBpcyByZXNldCBmaXJzdC5cbiAgICpcbiAgICogQHBhcmFtIHF1ZXJ5RXhlY3V0aW9uSWQgLSBBdGhlbmEgcXVlcnkgZXhlY3V0aW9uIGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSBuZXh0VG9rZW4gLSBQYXNzIGB1bmRlZmluZWRgIGZpcnN0OyBzdWJzZXF1ZW50IGNhbGxzIHVzZSB7QGxpbmsgUGFnZVJlc3VsdC5uZXh0VG9rZW59LlxuICAgKiBAcmV0dXJucyBQYXJzZWQgcm93cyBwbHVzIHBhZ2luYXRpb24gbWV0YWRhdGEgZnJvbSB0aGlzIHJlc3BvbnNlIG9ubHkuXG4gICAqIEB0aHJvd3Mge0F0aGVuYVF1ZXJ5UmVzdWx0UGFnZXJFbXB0eVF1ZXJ5RXhlY3V0aW9uSWRFcnJvcn0gV2hlbiBgcXVlcnlFeGVjdXRpb25JZGAgaXMgZW1wdHkgb3Igd2hpdGVzcGFjZSBvbmx5LlxuICAgKi9cbiAgYXN5bmMgZmV0Y2hQYWdlKFxuICAgIHF1ZXJ5RXhlY3V0aW9uSWQ6IHN0cmluZyxcbiAgICBuZXh0VG9rZW4/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8UGFnZVJlc3VsdDxQYXJzZWRSb3c+PiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNlbmRHZXRRdWVyeVJlc3VsdHMocXVlcnlFeGVjdXRpb25JZCwgbmV4dFRva2VuKTtcblxuICAgIGNvbnN0IHJvd3MgPSB0aGlzLnBhcnNlci5wYXJzZVJlc3VsdFNldChyZXNwb25zZS5SZXN1bHRTZXQsIHRoaXMucGFyc2VSZXN1bHRTZXRPcHRpb25zKTtcblxuICAgIHJldHVybiB7XG4gICAgICByb3dzLFxuICAgICAgbmV4dFRva2VuOiByZXNwb25zZS5OZXh0VG9rZW4sXG4gICAgICByb3dDb3VudDogcm93cy5sZW5ndGgsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgb25lIHBhZ2UgYXMge0BsaW5rIFBhcnNlZFJvd30gdmFsdWVzIHBsdXMge0BsaW5rIFBhcnNlUmVzdWx0U2V0RGlhZ25vc3RpY3N9LlxuICAgKlxuICAgKiBVc2VzIHtAbGluayBBdGhlbmFRdWVyeVJlc3VsdFBhcnNlci5wYXJzZVJlc3VsdFNldERldGFpbGVkfSBvbiB0aGUgQVdTIHJlc3BvbnNlLlxuICAgKiBXaGVuIGBxdWVyeUV4ZWN1dGlvbklkYCBkaWZmZXJzIGZyb20gdGhlIHByZXZpb3VzIGZldGNoIHNlcXVlbmNlLCB0aGUgYnVuZGxlZCBwYXJzZXIgaXMgcmVzZXQgZmlyc3QuXG4gICAqXG4gICAqIEBwYXJhbSBxdWVyeUV4ZWN1dGlvbklkIC0gQXRoZW5hIHF1ZXJ5IGV4ZWN1dGlvbiBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0gbmV4dFRva2VuIC0gUGFzcyBgdW5kZWZpbmVkYCBmaXJzdDsgc3Vic2VxdWVudCBjYWxscyB1c2Uge0BsaW5rIFBhZ2VEZXRhaWxlZFJlc3VsdC5uZXh0VG9rZW59LlxuICAgKiBAcmV0dXJucyBQYXJzZWQgcm93cywgcGFnaW5hdGlvbiBtZXRhZGF0YSwgYW5kIHBhcnNlciBkaWFnbm9zdGljcyBmb3IgdGhpcyByZXNwb25zZSBvbmx5LlxuICAgKiBAdGhyb3dzIHtBdGhlbmFRdWVyeVJlc3VsdFBhZ2VyRW1wdHlRdWVyeUV4ZWN1dGlvbklkRXJyb3J9IFdoZW4gYHF1ZXJ5RXhlY3V0aW9uSWRgIGlzIGVtcHR5IG9yIHdoaXRlc3BhY2Ugb25seS5cbiAgICovXG4gIGFzeW5jIGZldGNoUGFnZURldGFpbGVkKFxuICAgIHF1ZXJ5RXhlY3V0aW9uSWQ6IHN0cmluZyxcbiAgICBuZXh0VG9rZW4/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8UGFnZURldGFpbGVkUmVzdWx0PiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNlbmRHZXRRdWVyeVJlc3VsdHMocXVlcnlFeGVjdXRpb25JZCwgbmV4dFRva2VuKTtcblxuICAgIGNvbnN0IHBhcnNlZCA9IHRoaXMucGFyc2VyLnBhcnNlUmVzdWx0U2V0RGV0YWlsZWQocmVzcG9uc2UuUmVzdWx0U2V0LCB0aGlzLnBhcnNlUmVzdWx0U2V0T3B0aW9ucyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcm93czogcGFyc2VkLnJvd3MsXG4gICAgICBuZXh0VG9rZW46IHJlc3BvbnNlLk5leHRUb2tlbixcbiAgICAgIHJvd0NvdW50OiBwYXJzZWQucm93cy5sZW5ndGgsXG4gICAgICBkaWFnbm9zdGljczogcGFyc2VkLmRpYWdub3N0aWNzLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIG9uZSBwYWdlIGFuZCBtYXBzIGVhY2gge0BsaW5rIFBhcnNlZFJvd30gdGhyb3VnaCBgcm93UGFyc2VyYC5cbiAgICpcbiAgICogVXNlcyB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYXJzZXIucGFyc2VSZXN1bHRTZXRXaXRofSBvbiB0aGUgQVdTIHJlc3BvbnNlLlxuICAgKiBXaGVuIGBxdWVyeUV4ZWN1dGlvbklkYCBkaWZmZXJzIGZyb20gdGhlIHByZXZpb3VzIGZldGNoIHNlcXVlbmNlLCB0aGUgYnVuZGxlZCBwYXJzZXIgaXMgcmVzZXQgZmlyc3QuXG4gICAqXG4gICAqIEB0eXBlUGFyYW0gVCAtIE91dHB1dCB0eXBlIHByb2R1Y2VkIGJ5IGByb3dQYXJzZXJgLlxuICAgKiBAcGFyYW0gcXVlcnlFeGVjdXRpb25JZCAtIEF0aGVuYSBxdWVyeSBleGVjdXRpb24gaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHJvd1BhcnNlciAtIENvbnZlcnRzIGVhY2ggZGljdGlvbmFyeSByb3cgaW50byBgVGAuXG4gICAqIEBwYXJhbSBuZXh0VG9rZW4gLSBQYXNzIGB1bmRlZmluZWRgIGZpcnN0OyBzdWJzZXF1ZW50IGNhbGxzIHVzZSB7QGxpbmsgUGFnZVJlc3VsdC5uZXh0VG9rZW59LlxuICAgKiBAcmV0dXJucyBUcmFuc2Zvcm1lZCByb3dzIHBsdXMgcGFnaW5hdGlvbiBtZXRhZGF0YSBmcm9tIHRoaXMgcmVzcG9uc2Ugb25seS5cbiAgICogQHRocm93cyB7QXRoZW5hUXVlcnlSZXN1bHRQYWdlckVtcHR5UXVlcnlFeGVjdXRpb25JZEVycm9yfSBXaGVuIGBxdWVyeUV4ZWN1dGlvbklkYCBpcyBlbXB0eSBvciB3aGl0ZXNwYWNlIG9ubHkuXG4gICAqL1xuICBhc3luYyBmZXRjaFBhZ2VXaXRoPFQ+KFxuICAgIHF1ZXJ5RXhlY3V0aW9uSWQ6IHN0cmluZyxcbiAgICByb3dQYXJzZXI6IFJvd1BhcnNlcjxUPixcbiAgICBuZXh0VG9rZW4/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8UGFnZVJlc3VsdDxUPj4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5zZW5kR2V0UXVlcnlSZXN1bHRzKHF1ZXJ5RXhlY3V0aW9uSWQsIG5leHRUb2tlbik7XG5cbiAgICBjb25zdCByb3dzID0gdGhpcy5wYXJzZXIucGFyc2VSZXN1bHRTZXRXaXRoKFxuICAgICAgcmVzcG9uc2UuUmVzdWx0U2V0LFxuICAgICAgcm93UGFyc2VyLFxuICAgICAgdGhpcy5wYXJzZVJlc3VsdFNldE9wdGlvbnMsXG4gICAgKTtcblxuICAgIHJldHVybiB7XG4gICAgICByb3dzLFxuICAgICAgbmV4dFRva2VuOiByZXNwb25zZS5OZXh0VG9rZW4sXG4gICAgICByb3dDb3VudDogcm93cy5sZW5ndGgsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMYXppbHkgd2Fsa3MgYWxsIHBhZ2VzIGZvciBhbiBleGVjdXRpb24sIHlpZWxkaW5nIG9uZSB7QGxpbmsgUGFnZVJlc3VsdH0gb2Yge0BsaW5rIFBhcnNlZFJvd30gcGVyIHN0ZXAuXG4gICAqXG4gICAqIEBwYXJhbSBxdWVyeUV4ZWN1dGlvbklkIC0gQXRoZW5hIHF1ZXJ5IGV4ZWN1dGlvbiBpZGVudGlmaWVyLlxuICAgKiBAeWllbGRzIE9uZSBwYWdlIGF0IGEgdGltZSB1bnRpbCBBV1MgcmV0dXJucyBubyBgTmV4dFRva2VuYC5cbiAgICovXG4gIGFzeW5jICppdGVyYXRlUGFnZXMoXG4gICAgcXVlcnlFeGVjdXRpb25JZDogc3RyaW5nLFxuICApOiBBc3luY0dlbmVyYXRvcjxQYWdlUmVzdWx0PFBhcnNlZFJvdz4+IHtcbiAgICBsZXQgbmV4dFRva2VuOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICBkbyB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgdGhpcy5mZXRjaFBhZ2UocXVlcnlFeGVjdXRpb25JZCwgbmV4dFRva2VuKTtcbiAgICAgIHlpZWxkIHBhZ2U7XG4gICAgICBuZXh0VG9rZW4gPSBwYWdlLm5leHRUb2tlbjtcbiAgICB9IHdoaWxlIChuZXh0VG9rZW4pO1xuICB9XG5cbiAgLyoqXG4gICAqIExhemlseSB3YWxrcyBhbGwgcGFnZXMgZm9yIGFuIGV4ZWN1dGlvbiwgeWllbGRpbmcgb25lIHtAbGluayBQYWdlRGV0YWlsZWRSZXN1bHR9IHBlciBzdGVwLlxuICAgKlxuICAgKiBAcGFyYW0gcXVlcnlFeGVjdXRpb25JZCAtIEF0aGVuYSBxdWVyeSBleGVjdXRpb24gaWRlbnRpZmllci5cbiAgICogQHlpZWxkcyBPbmUgcGFnZSBhdCBhIHRpbWUgKHdpdGggZGlhZ25vc3RpY3MpIHVudGlsIEFXUyByZXR1cm5zIG5vIGBOZXh0VG9rZW5gLlxuICAgKi9cbiAgYXN5bmMgKml0ZXJhdGVQYWdlc0RldGFpbGVkKFxuICAgIHF1ZXJ5RXhlY3V0aW9uSWQ6IHN0cmluZyxcbiAgKTogQXN5bmNHZW5lcmF0b3I8UGFnZURldGFpbGVkUmVzdWx0PiB7XG4gICAgbGV0IG5leHRUb2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgZG8ge1xuICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuZmV0Y2hQYWdlRGV0YWlsZWQocXVlcnlFeGVjdXRpb25JZCwgbmV4dFRva2VuKTtcbiAgICAgIHlpZWxkIHBhZ2U7XG4gICAgICBuZXh0VG9rZW4gPSBwYWdlLm5leHRUb2tlbjtcbiAgICB9IHdoaWxlIChuZXh0VG9rZW4pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhbWUgYXMge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFnZXIuaXRlcmF0ZVBhZ2VzfSBidXQgbWFwcyBlYWNoIHJvdyB0aHJvdWdoIGByb3dQYXJzZXJgIG9uIGV2ZXJ5IHBhZ2UuXG4gICAqXG4gICAqIEB0eXBlUGFyYW0gVCAtIE91dHB1dCB0eXBlIGVtaXR0ZWQgaW4ge0BsaW5rIFBhZ2VSZXN1bHQucm93c30uXG4gICAqIEBwYXJhbSBxdWVyeUV4ZWN1dGlvbklkIC0gQXRoZW5hIHF1ZXJ5IGV4ZWN1dGlvbiBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0gcm93UGFyc2VyIC0gQ29udmVydHMgZWFjaCBwYXJzZWQgcm93IGludG8gYFRgLlxuICAgKiBAeWllbGRzIFN1Y2Nlc3NpdmUge0BsaW5rIFBhZ2VSZXN1bHR9IHZhbHVlcyB3aG9zZSBgcm93c2AgYXJlIHR5cGVkIGFzIGBUYC5cbiAgICovXG4gIGFzeW5jICppdGVyYXRlUGFnZXNXaXRoPFQ+KFxuICAgIHF1ZXJ5RXhlY3V0aW9uSWQ6IHN0cmluZyxcbiAgICByb3dQYXJzZXI6IFJvd1BhcnNlcjxUPixcbiAgKTogQXN5bmNHZW5lcmF0b3I8UGFnZVJlc3VsdDxUPj4ge1xuICAgIGxldCBuZXh0VG9rZW46IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIGRvIHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCB0aGlzLmZldGNoUGFnZVdpdGgocXVlcnlFeGVjdXRpb25JZCwgcm93UGFyc2VyLCBuZXh0VG9rZW4pO1xuICAgICAgeWllbGQgcGFnZTtcbiAgICAgIG5leHRUb2tlbiA9IHBhZ2UubmV4dFRva2VuO1xuICAgIH0gd2hpbGUgKG5leHRUb2tlbik7XG4gIH1cblxuICAvKipcbiAgICogRmxhdHRlbnMge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFnZXIuaXRlcmF0ZVBhZ2VzfSBpbnRvIGluZGl2aWR1YWwge0BsaW5rIFBhcnNlZFJvd30gdmFsdWVzIChvbmUgcm93IHBlciBgbmV4dCgpYCkuXG4gICAqXG4gICAqIE9ubHkgb25lIHBhZ2Ugb2Ygcm93cyBpcyBoZWxkIGluIG1lbW9yeSBhdCBhIHRpbWUuXG4gICAqXG4gICAqIEBwYXJhbSBxdWVyeUV4ZWN1dGlvbklkIC0gQXRoZW5hIHF1ZXJ5IGV4ZWN1dGlvbiBpZGVudGlmaWVyLlxuICAgKiBAeWllbGRzIEVhY2ggZGljdGlvbmFyeS1zaGFwZWQgcm93IGluIGV4ZWN1dGlvbiBvcmRlci5cbiAgICovXG4gIGl0ZXJhdGVSb3dzKFxuICAgIHF1ZXJ5RXhlY3V0aW9uSWQ6IHN0cmluZyxcbiAgKTogQXN5bmNHZW5lcmF0b3I8UGFyc2VkUm93PjtcblxuICAvKipcbiAgICogRmxhdHRlbnMge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFnZXIuaXRlcmF0ZVBhZ2VzV2l0aH0gaW50byBpbmRpdmlkdWFsIGBUYCB2YWx1ZXMgKG9uZSByb3cgcGVyIGBuZXh0KClgKS5cbiAgICpcbiAgICogT25seSBvbmUgcGFnZSBvZiByb3dzIGlzIGhlbGQgaW4gbWVtb3J5IGF0IGEgdGltZS5cbiAgICpcbiAgICogQHR5cGVQYXJhbSBUIC0gT3V0cHV0IHR5cGUgcHJvZHVjZWQgYnkgYHJvd1BhcnNlcmAuXG4gICAqIEBwYXJhbSBxdWVyeUV4ZWN1dGlvbklkIC0gQXRoZW5hIHF1ZXJ5IGV4ZWN1dGlvbiBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0gcm93UGFyc2VyIC0gQ29udmVydHMgZWFjaCBwYXJzZWQgcm93IGludG8gYFRgLlxuICAgKiBAeWllbGRzIEVhY2ggdHJhbnNmb3JtZWQgcm93IGluIGV4ZWN1dGlvbiBvcmRlci5cbiAgICovXG4gIGl0ZXJhdGVSb3dzPFQ+KFxuICAgIHF1ZXJ5RXhlY3V0aW9uSWQ6IHN0cmluZyxcbiAgICByb3dQYXJzZXI6IFJvd1BhcnNlcjxUPixcbiAgKTogQXN5bmNHZW5lcmF0b3I8VD47XG5cbiAgLyoqXG4gICAqIFNoYXJlZCBpbXBsZW1lbnRhdGlvbiBmb3Ige0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFnZXIuaXRlcmF0ZVJvd3N9IG92ZXJsb2Fkcy5cbiAgICpcbiAgICogRGVsZWdhdGVzIHRvIHtAbGluayBBdGhlbmFRdWVyeVJlc3VsdFBhZ2VyLml0ZXJhdGVQYWdlc30gd2hlbiBgcm93UGFyc2VyYCBpcyBvbWl0dGVkOyBvdGhlcndpc2UgdG9cbiAgICoge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFnZXIuaXRlcmF0ZVBhZ2VzV2l0aH0uXG4gICAqL1xuICBhc3luYyAqaXRlcmF0ZVJvd3M8VD4oXG4gICAgcXVlcnlFeGVjdXRpb25JZDogc3RyaW5nLFxuICAgIHJvd1BhcnNlcj86IFJvd1BhcnNlcjxUPixcbiAgKTogQXN5bmNHZW5lcmF0b3I8UGFyc2VkUm93IHwgVD4ge1xuICAgIGNvbnN0IHBhZ2VzID0gcm93UGFyc2VyXG4gICAgICA/IHRoaXMuaXRlcmF0ZVBhZ2VzV2l0aChxdWVyeUV4ZWN1dGlvbklkLCByb3dQYXJzZXIpXG4gICAgICA6IHRoaXMuaXRlcmF0ZVBhZ2VzKHF1ZXJ5RXhlY3V0aW9uSWQpO1xuXG4gICAgZm9yIGF3YWl0IChjb25zdCBwYWdlIG9mIHBhZ2VzKSB7XG4gICAgICBmb3IgKGNvbnN0IHJvdyBvZiBwYWdlLnJvd3MpIHtcbiAgICAgICAgeWllbGQgcm93O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBidW5kbGVkIHBhcnNlcidzIG1vc3QgcmVjZW50IGhlYWRlci1yb3cgZGVjaXNpb24uXG4gICAqXG4gICAqIFVzZWZ1bCB3aGVuIHtAbGluayBQYWdlck9wdGlvbnMucGFyc2VSZXN1bHRTZXRPcHRpb25zfSB1c2VzIGBza2lwSGVhZGVyUm93OiAnYXV0bydgLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgbGFzdCB7QGxpbmsgSGVhZGVyUm93RGVjaXNpb259LCBvciBgbnVsbGAgYmVmb3JlIGFueSBwYXJzZSAvIGFmdGVyIHtAbGluayBBdGhlbmFRdWVyeVJlc3VsdFBhZ2VyLnJlc2V0fS5cbiAgICovXG4gIGdldExhc3RIZWFkZXJSb3dEZWNpc2lvbigpOiBIZWFkZXJSb3dEZWNpc2lvbiB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLnBhcnNlci5nZXRMYXN0SGVhZGVyUm93RGVjaXNpb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgdGhlIGJ1bmRsZWQge0BsaW5rIEF0aGVuYVF1ZXJ5UmVzdWx0UGFyc2VyfSBzdGF0ZSBhbmQgdGhlIHRyYWNrZWQgYWN0aXZlIGV4ZWN1dGlvbiBpZC5cbiAgICpcbiAgICogVXN1YWxseSB1bm5lY2Vzc2FyeTogZmV0Y2ggbWV0aG9kcyByZXNldCBhdXRvbWF0aWNhbGx5IHdoZW4gYHF1ZXJ5RXhlY3V0aW9uSWRgIGNoYW5nZXMuIENhbGwgZXhwbGljaXRseSB0byBjbGVhciBzdGF0ZSB3aXRob3V0IHN0YXJ0aW5nIGEgbmV3IGZldGNoXG4gICAqIChmb3IgZXhhbXBsZSBzbyB7QGxpbmsgQXRoZW5hUXVlcnlSZXN1bHRQYWdlci5nZXRMYXN0SGVhZGVyUm93RGVjaXNpb259IHJldHVybnMgYG51bGxgKS5cbiAgICovXG4gIHJlc2V0KCk6IHZvaWQge1xuICAgIHRoaXMucGFyc2VyLnJlc2V0KCk7XG4gICAgdGhpcy5hY3RpdmVRdWVyeUV4ZWN1dGlvbklkID0gdW5kZWZpbmVkO1xuICB9XG59XG5cbmV4cG9ydCB7XG4gIEF0aGVuYVF1ZXJ5UmVzdWx0UGFnZXJFbXB0eVF1ZXJ5RXhlY3V0aW9uSWRFcnJvcixcbiAgQXRoZW5hUXVlcnlSZXN1bHRQYWdlckVycm9yLFxuICBBdGhlbmFRdWVyeVJlc3VsdFBhZ2VySW52YWxpZE1heFJlc3VsdHNFcnJvcixcbn0gZnJvbSAnLi9lcnJvcnMnO1xuLyoqIFJlLWV4cG9ydHMge0BsaW5rIFF1ZXJ5UmVzdWx0VHlwZX0gZnJvbSBgQGF3cy1zZGsvY2xpZW50LWF0aGVuYWAuICovXG5leHBvcnQgeyBRdWVyeVJlc3VsdFR5cGUgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtYXRoZW5hJztcbmV4cG9ydCB7XG4gIEF0aGVuYVF1ZXJ5UmVzdWx0UGFyc2VyQ29sdW1uQ291bnRNaXNtYXRjaEVycm9yLFxuICBBdGhlbmFRdWVyeVJlc3VsdFBhcnNlckR1cGxpY2F0ZUNvbHVtbk5hbWVFcnJvcixcbiAgQXRoZW5hUXVlcnlSZXN1bHRQYXJzZXJFcnJvcixcbiAgQXRoZW5hUXVlcnlSZXN1bHRQYXJzZXJIZWFkZXJSb3dNaXNtYXRjaEVycm9yLFxuICBBdGhlbmFRdWVyeVJlc3VsdFBhcnNlckludmFsaWRNYXhSb3dzRXJyb3IsXG4gIEF0aGVuYVF1ZXJ5UmVzdWx0UGFyc2VyTWF4Um93c0V4Y2VlZGVkRXJyb3IsXG4gIEF0aGVuYVF1ZXJ5UmVzdWx0UGFyc2VyVW5hdmFpbGFibGVSZXN1bHRFcnJvcixcbiAgRVhUUkFfQ09MVU1OU19LRVksXG4gIGhlYWRlcnNGcm9tTWV0YSxcbiAgaXNIZWFkZXJSb3csXG4gIHBhcnNlUmVzdWx0U2V0RGV0YWlsZWRPbmNlLFxuICBwYXJzZVJlc3VsdFNldEl0ZXJPbmNlLFxuICBwYXJzZVJlc3VsdFNldE9uY2UsXG4gIHBhcnNlUmVzdWx0U2V0V2l0aE9uY2UsXG4gIHJvd1RvT2JqZWN0LFxuICByb3dUb1R5cGVkT2JqZWN0LFxuICB0b0Jvb2xlYW4sXG4gIHRvRGF0ZSxcbiAgdG9OdW1iZXIsXG59IGZyb20gJ2F0aGVuYS1xdWVyeS1yZXN1bHQtcGFyc2VyJztcbmV4cG9ydCB0eXBlIHtcbiAgQXRoZW5hUXVlcnlSZXN1bHRQYXJzZXJPcHRpb25zLFxuICBBdGhlbmFUeXBlZFZhbHVlLFxuICBDb2x1bW5Db3VudE1pc21hdGNoQmVoYXZpb3IsXG4gIEhlYWRlclJvd0RlY2lzaW9uLFxuICBNYXhSb3dzRXhjZWVkZWRCZWhhdmlvcixcbiAgUGFyc2VSZXN1bHRTZXREaWFnbm9zdGljcyxcbiAgUGFyc2VSZXN1bHRTZXREZXRhaWxlZFJlc3VsdCxcbiAgUGFyc2VSZXN1bHRTZXRPcHRpb25zLFxuICBQYXJzZVJlc3VsdFNldFVuYXZhaWxhYmxlUmVhc29uLFxuICBQYXJzZWRSb3csXG4gIFBhcnNlclJldXNlUG9saWN5LFxuICBSb3dQYXJzZXIsXG4gIFR5cGVkUGFyc2VkUm93LFxuICBVbmF2YWlsYWJsZVJlc3VsdEJlaGF2aW9yLFxufSBmcm9tICdhdGhlbmEtcXVlcnktcmVzdWx0LXBhcnNlcic7Il19
package/package.json CHANGED
@@ -44,14 +44,14 @@
44
44
  "eslint-plugin-import": "^2.32.0",
45
45
  "jest": "^30.5.1",
46
46
  "jest-junit": "^17",
47
- "projen": "^0.103.20",
47
+ "projen": "^0.103.23",
48
48
  "ts-jest": "^29.4.12",
49
49
  "ts-node": "^10.9.2",
50
50
  "typescript": "6.0.x"
51
51
  },
52
52
  "dependencies": {
53
53
  "@aws-sdk/client-athena": "^3.983.0",
54
- "athena-query-result-parser": "^0.5.0"
54
+ "athena-query-result-parser": "^0.6.0"
55
55
  },
56
56
  "keywords": [
57
57
  "athena",
@@ -75,7 +75,7 @@
75
75
  "publishConfig": {
76
76
  "access": "public"
77
77
  },
78
- "version": "0.5.7",
78
+ "version": "0.6.0",
79
79
  "jest": {
80
80
  "coverageProvider": "v8",
81
81
  "testMatch": [