flexdataset 0.21.2 → 0.23.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.
@@ -0,0 +1,528 @@
1
+ "use strict";
2
+ /**
3
+ * Iceberg (parquet) format-version-2 table type.
4
+ *
5
+ * Iceberg partitions are transforms applied to a data column, so duplicate
6
+ * detection keys on the (source column, normalized transform) pair — `year(ts)`
7
+ * and `month(ts)` are distinct, while `day` and `DAY` collapse.
8
+ *
9
+ * The format version is encoded in the `tableType` discriminator: this engine is
10
+ * inherently v2, so a present `formatVersion` must equal `EXPECTED_FORMAT_VERSION`.
11
+ * A future `iceberg_parquet_v3` sibling subclass overrides that one constant.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.IcebergParquetV2Table = void 0;
15
+ const table_type_1 = require("../table-type");
16
+ const iceberg_1 = require("../iceberg");
17
+ /**
18
+ * Whether a string is a positive integer (digits only, value > 0). Iceberg
19
+ * table-property values are strings, so numeric checks parse the string.
20
+ *
21
+ * @param value Property value string.
22
+ * @returns True when `value` is a positive integer.
23
+ */
24
+ function isPositiveInteger(value) {
25
+ return /^\d+$/.test(value) && Number(value) > 0;
26
+ }
27
+ /**
28
+ * Whether a string is a non-negative integer (digits only, value >= 0).
29
+ *
30
+ * @param value Property value string.
31
+ * @returns True when `value` is a non-negative integer.
32
+ */
33
+ function isNonNegativeInteger(value) {
34
+ return /^\d+$/.test(value);
35
+ }
36
+ /**
37
+ * Whether a string is an integer within an inclusive range.
38
+ *
39
+ * @param value Property value string.
40
+ * @param min Inclusive lower bound.
41
+ * @param max Inclusive upper bound.
42
+ * @returns True when `value` is an integer in `[min, max]`.
43
+ */
44
+ function isIntegerInRange(value, min, max) {
45
+ if (!/^\d+$/.test(value)) {
46
+ return false;
47
+ }
48
+ const parsed = Number(value);
49
+ return parsed >= min && parsed <= max;
50
+ }
51
+ /** Iceberg (parquet) format-version-2 table. */
52
+ class IcebergParquetV2Table extends table_type_1.TableTypeBase {
53
+ /**
54
+ * The Iceberg format version this engine pins to. A present `formatVersion`
55
+ * must equal this. A future v3 sibling subclass overrides this single value.
56
+ */
57
+ static EXPECTED_FORMAT_VERSION = 2;
58
+ /**
59
+ * Validate a column type against the Iceberg v0 type registry.
60
+ *
61
+ * @param type Type string from a column definition.
62
+ * @returns True when the type is a valid Iceberg type.
63
+ */
64
+ isValidColumnType(type) {
65
+ return (0, iceberg_1.isValidIcebergType)(type);
66
+ }
67
+ /**
68
+ * Iceberg partition rules.
69
+ *
70
+ * Emits: `NO_DUPLICATE_PARTITIONS` (keyed by `${name} ${transformKind}:${param}`,
71
+ * falling back to a lowercased trim of the raw transform when it doesn't
72
+ * parse, so whitespace / case variants of the same transform collapse),
73
+ * `ICEBERG_TRANSFORM_SOURCE_EXISTS`, `ICEBERG_TRANSFORM_VALID`, and
74
+ * `ICEBERG_TRANSFORM_SOURCE_TYPE_LEGAL`.
75
+ *
76
+ * @returns Every partition-related violation.
77
+ */
78
+ partitionViolations() {
79
+ const violations = [];
80
+ const { partitions, } = this.definition;
81
+ const seen = new Set();
82
+ partitions.forEach((partition, index) => {
83
+ const key = this.partitionKey(partition);
84
+ if (seen.has(key)) {
85
+ violations.push(this.violation({
86
+ level: 'error',
87
+ code: 'NO_DUPLICATE_PARTITIONS',
88
+ field: `partitions[${index}]`,
89
+ message: `duplicate partition: "${partition.name}" with transform "${partition.type}"`,
90
+ }));
91
+ }
92
+ seen.add(key);
93
+ });
94
+ partitions.forEach((partition, index) => {
95
+ const sourceColumn = this.definition.columns.find((column) => column.name === partition.name);
96
+ if (sourceColumn === undefined) {
97
+ violations.push(this.violation({
98
+ level: 'error',
99
+ code: 'ICEBERG_TRANSFORM_SOURCE_EXISTS',
100
+ field: `partitions[${index}].name`,
101
+ message: `Iceberg partition source column "${partition.name}" is not defined in columns`,
102
+ }));
103
+ return;
104
+ }
105
+ const transform = (0, iceberg_1.parseIcebergTransform)(partition.type);
106
+ if (transform === null) {
107
+ violations.push(this.violation({
108
+ level: 'error',
109
+ code: 'ICEBERG_TRANSFORM_VALID',
110
+ field: `partitions[${index}].type`,
111
+ message: `"${partition.type}" is not a valid Iceberg partition transform`,
112
+ }));
113
+ return;
114
+ }
115
+ const sourceType = (0, iceberg_1.parseIcebergType)(sourceColumn.type);
116
+ if (sourceType !== null && !(0, iceberg_1.transformLegalOnType)(transform, sourceType)) {
117
+ violations.push(this.violation({
118
+ level: 'error',
119
+ code: 'ICEBERG_TRANSFORM_SOURCE_TYPE_LEGAL',
120
+ field: `partitions[${index}].type`,
121
+ message: `transform "${partition.type}" is not legal on `
122
+ + `column "${partition.name}" of type "${sourceColumn.type}"`,
123
+ }));
124
+ }
125
+ });
126
+ return violations;
127
+ }
128
+ /// Table-property keys whose value must come from a closed set.
129
+ static ENUM_PROPERTIES = {
130
+ 'write.format.default': [
131
+ 'parquet',
132
+ 'avro',
133
+ 'orc',
134
+ ],
135
+ 'write.parquet.compression-codec': [
136
+ 'zstd',
137
+ 'gzip',
138
+ 'snappy',
139
+ 'lz4',
140
+ 'none',
141
+ ],
142
+ 'write.avro.compression-codec': [
143
+ 'gzip',
144
+ 'zstd',
145
+ 'snappy',
146
+ 'uncompressed',
147
+ ],
148
+ 'write.orc.compression-codec': [
149
+ 'zstd',
150
+ 'lz4',
151
+ 'lzo',
152
+ 'zlib',
153
+ 'snappy',
154
+ 'none',
155
+ ],
156
+ 'write.distribution-mode': [
157
+ 'none',
158
+ 'hash',
159
+ 'range',
160
+ ],
161
+ 'write.metadata.compression-codec': [
162
+ 'none',
163
+ 'gzip',
164
+ ],
165
+ };
166
+ /// Table-property keys whose value must be a positive integer.
167
+ static POSITIVE_INT_PROPERTIES = [
168
+ 'write.target-file-size-bytes',
169
+ 'history.expire.max-snapshot-age-ms',
170
+ 'history.expire.min-snapshots-to-keep',
171
+ 'history.expire.max-ref-age-ms',
172
+ 'write.metadata.previous-versions-max',
173
+ 'commit.retry.min-wait-ms',
174
+ 'commit.retry.max-wait-ms',
175
+ 'commit.retry.total-timeout-ms',
176
+ ];
177
+ /// Table-property keys whose value must be a non-negative integer.
178
+ static NON_NEGATIVE_INT_PROPERTIES = [
179
+ 'commit.retry.num-retries',
180
+ ];
181
+ /// Table-property keys whose value must be an integer within an inclusive range.
182
+ static INT_RANGE_PROPERTIES = {
183
+ 'write.parquet.compression-level': {
184
+ min: 1,
185
+ max: 22,
186
+ },
187
+ };
188
+ /// Legal sort directions and null orderings.
189
+ static SORT_DIRECTIONS = new Set([
190
+ 'asc',
191
+ 'desc',
192
+ ]);
193
+ static SORT_NULL_ORDERS = new Set([
194
+ 'nulls-first',
195
+ 'nulls-last',
196
+ ]);
197
+ /**
198
+ * Iceberg engine-specific rules: format version, table properties, and sort
199
+ * order.
200
+ *
201
+ * @returns Every engine-specific violation.
202
+ */
203
+ engineSpecificViolations() {
204
+ return [
205
+ ...this.formatVersionViolations(),
206
+ ...this.tablePropertyViolations(),
207
+ ...this.sortOrderViolations(),
208
+ ...this.identifierFieldViolations(),
209
+ ...this.fieldIdViolations(),
210
+ ];
211
+ }
212
+ /**
213
+ * Validate Iceberg column field ids — the ids Iceberg uses for schema
214
+ * evolution. Pinning them keeps old data files readable across renames and
215
+ * drops, so they are all-or-nothing per table: either every column declares
216
+ * an `id` or none do. When present, each id must be a positive integer and
217
+ * unique within the table.
218
+ *
219
+ * Emits `ICEBERG_FIELD_ID_ALL_OR_NONE`, `ICEBERG_FIELD_ID_POSITIVE`, and
220
+ * `ICEBERG_FIELD_ID_UNIQUE`.
221
+ *
222
+ * @returns Every field-id violation.
223
+ */
224
+ fieldIdViolations() {
225
+ const violations = [];
226
+ const { columns, } = this.definition;
227
+ const withId = columns.filter((column) => column.id !== undefined);
228
+ if (withId.length === 0) {
229
+ return [];
230
+ }
231
+ if (withId.length !== columns.length) {
232
+ violations.push(this.violation({
233
+ level: 'error',
234
+ code: 'ICEBERG_FIELD_ID_ALL_OR_NONE',
235
+ field: 'columns',
236
+ message: `either every column declares an id or none do; ${withId.length} `
237
+ + `of ${columns.length} columns have an id`,
238
+ }));
239
+ }
240
+ const seen = new Set();
241
+ columns.forEach((column, index) => {
242
+ const { id, } = column;
243
+ if (id === undefined) {
244
+ return;
245
+ }
246
+ // Integer-ness is enforced structurally by the JSON Schema, so an id
247
+ // that reaches the engine is always an integer; only its sign is
248
+ // checked here.
249
+ if (id < 1) {
250
+ violations.push(this.violation({
251
+ level: 'error',
252
+ code: 'ICEBERG_FIELD_ID_POSITIVE',
253
+ field: `columns[${index}].id`,
254
+ message: `column "${column.name}" id ${id} must be a positive integer`,
255
+ }));
256
+ return;
257
+ }
258
+ if (seen.has(id)) {
259
+ violations.push(this.violation({
260
+ level: 'error',
261
+ code: 'ICEBERG_FIELD_ID_UNIQUE',
262
+ field: `columns[${index}].id`,
263
+ message: `column "${column.name}" reuses field id ${id}; ids must be unique within the table`,
264
+ }));
265
+ }
266
+ seen.add(id);
267
+ });
268
+ return violations;
269
+ }
270
+ /**
271
+ * Validate the Iceberg sort order.
272
+ *
273
+ * Emits `NO_DUPLICATE_SORT_FIELDS` (keyed by source column + normalized
274
+ * transform), `ICEBERG_SORT_COLUMN_EXISTS`, `ICEBERG_SORT_DIRECTION_VALID`,
275
+ * `ICEBERG_SORT_NULL_ORDER_VALID`, `ICEBERG_SORT_TRANSFORM_VALID`, and
276
+ * `ICEBERG_SORT_TRANSFORM_TYPE_LEGAL`.
277
+ *
278
+ * @returns Every sort-order violation.
279
+ */
280
+ sortOrderViolations() {
281
+ const violations = [];
282
+ const { sortOrder, } = this.definition;
283
+ const seen = new Set();
284
+ sortOrder.forEach((field, index) => {
285
+ const key = this.sortFieldKey(field);
286
+ if (seen.has(key)) {
287
+ violations.push(this.violation({
288
+ level: 'error',
289
+ code: 'NO_DUPLICATE_SORT_FIELDS',
290
+ field: `sortOrder[${index}]`,
291
+ message: `duplicate sort field: "${field.column}"`
292
+ + `${field.transform ? ` with transform "${field.transform}"` : ''}`,
293
+ }));
294
+ }
295
+ seen.add(key);
296
+ });
297
+ sortOrder.forEach((field, index) => {
298
+ if (!IcebergParquetV2Table.SORT_DIRECTIONS.has(field.direction)) {
299
+ violations.push(this.violation({
300
+ level: 'error',
301
+ code: 'ICEBERG_SORT_DIRECTION_VALID',
302
+ field: `sortOrder[${index}].direction`,
303
+ message: `sort direction "${field.direction}" must be "asc" or "desc"`,
304
+ }));
305
+ }
306
+ if (!IcebergParquetV2Table.SORT_NULL_ORDERS.has(field.nullOrder)) {
307
+ violations.push(this.violation({
308
+ level: 'error',
309
+ code: 'ICEBERG_SORT_NULL_ORDER_VALID',
310
+ field: `sortOrder[${index}].nullOrder`,
311
+ message: `sort null order "${field.nullOrder}" must be "nulls-first" or "nulls-last"`,
312
+ }));
313
+ }
314
+ const sourceColumn = this.definition.columns.find((column) => column.name === field.column);
315
+ if (sourceColumn === undefined) {
316
+ violations.push(this.violation({
317
+ level: 'error',
318
+ code: 'ICEBERG_SORT_COLUMN_EXISTS',
319
+ field: `sortOrder[${index}].column`,
320
+ message: `sort column "${field.column}" is not defined in columns`,
321
+ }));
322
+ return;
323
+ }
324
+ if (field.transform === undefined) {
325
+ return;
326
+ }
327
+ const transform = (0, iceberg_1.parseIcebergTransform)(field.transform);
328
+ if (transform === null) {
329
+ violations.push(this.violation({
330
+ level: 'error',
331
+ code: 'ICEBERG_SORT_TRANSFORM_VALID',
332
+ field: `sortOrder[${index}].transform`,
333
+ message: `"${field.transform}" is not a valid Iceberg transform`,
334
+ }));
335
+ return;
336
+ }
337
+ const sourceType = (0, iceberg_1.parseIcebergType)(sourceColumn.type);
338
+ if (sourceType !== null && !(0, iceberg_1.transformLegalOnType)(transform, sourceType)) {
339
+ violations.push(this.violation({
340
+ level: 'error',
341
+ code: 'ICEBERG_SORT_TRANSFORM_TYPE_LEGAL',
342
+ field: `sortOrder[${index}].transform`,
343
+ message: `transform "${field.transform}" is not legal on `
344
+ + `column "${field.column}" of type "${sourceColumn.type}"`,
345
+ }));
346
+ }
347
+ });
348
+ return violations;
349
+ }
350
+ /**
351
+ * Normalize a sort field into its identity key. An omitted transform and an
352
+ * explicit `identity` collapse to the same key so they count as duplicates.
353
+ *
354
+ * @param field Sort field to key.
355
+ * @returns The identity string for duplicate detection.
356
+ */
357
+ sortFieldKey(field) {
358
+ if (field.transform === undefined) {
359
+ return `${field.column} identity:`;
360
+ }
361
+ const transform = (0, iceberg_1.parseIcebergTransform)(field.transform);
362
+ const normalizedTransform = transform
363
+ ? `${transform.kind}:${transform.param ?? ''}`
364
+ : field.transform.trim().toLowerCase();
365
+ return `${field.column} ${normalizedTransform}`;
366
+ }
367
+ /// ICEBERG_FORMAT_VERSION_VALID — `formatVersion`, when set, equals the
368
+ /// version this engine pins to (2 for `iceberg_parquet_v2`).
369
+ formatVersionViolations() {
370
+ const { formatVersion, } = this.definition;
371
+ const expected = this.constructor.EXPECTED_FORMAT_VERSION;
372
+ if (formatVersion === undefined || formatVersion === expected) {
373
+ return [];
374
+ }
375
+ return [
376
+ this.violation({
377
+ level: 'error',
378
+ code: 'ICEBERG_FORMAT_VERSION_VALID',
379
+ field: 'formatVersion',
380
+ message: `Iceberg formatVersion "${formatVersion}" must be ${expected}`,
381
+ }),
382
+ ];
383
+ }
384
+ /**
385
+ * Validate the closed-domain Iceberg table properties. Keys outside the
386
+ * known set pass through unvalidated.
387
+ *
388
+ * Emits `ICEBERG_PROPERTY_ENUM_VALID`, `ICEBERG_PROPERTY_POSITIVE_INT`,
389
+ * `ICEBERG_PROPERTY_NON_NEGATIVE_INT`, `ICEBERG_PROPERTY_INT_RANGE`, and
390
+ * `ICEBERG_COMMIT_RETRY_ORDERING`.
391
+ *
392
+ * @returns Every table-property violation.
393
+ */
394
+ tablePropertyViolations() {
395
+ const violations = [];
396
+ const properties = this.definition.tableProperties;
397
+ for (const [key, value,] of Object.entries(properties)) {
398
+ const allowed = IcebergParquetV2Table.ENUM_PROPERTIES[key];
399
+ if (allowed !== undefined && !allowed.includes(value)) {
400
+ violations.push(this.violation({
401
+ level: 'error',
402
+ code: 'ICEBERG_PROPERTY_ENUM_VALID',
403
+ field: `tableProperties["${key}"]`,
404
+ message: `table property "${key}" value "${value}" must be one of: ${allowed.join(', ')}`,
405
+ }));
406
+ }
407
+ if (IcebergParquetV2Table.POSITIVE_INT_PROPERTIES.includes(key) && !isPositiveInteger(value)) {
408
+ violations.push(this.violation({
409
+ level: 'error',
410
+ code: 'ICEBERG_PROPERTY_POSITIVE_INT',
411
+ field: `tableProperties["${key}"]`,
412
+ message: `table property "${key}" value "${value}" must be a positive integer`,
413
+ }));
414
+ }
415
+ if (IcebergParquetV2Table.NON_NEGATIVE_INT_PROPERTIES.includes(key) && !isNonNegativeInteger(value)) {
416
+ violations.push(this.violation({
417
+ level: 'error',
418
+ code: 'ICEBERG_PROPERTY_NON_NEGATIVE_INT',
419
+ field: `tableProperties["${key}"]`,
420
+ message: `table property "${key}" value "${value}" must be a non-negative integer`,
421
+ }));
422
+ }
423
+ const range = IcebergParquetV2Table.INT_RANGE_PROPERTIES[key];
424
+ if (range !== undefined && !isIntegerInRange(value, range.min, range.max)) {
425
+ violations.push(this.violation({
426
+ level: 'error',
427
+ code: 'ICEBERG_PROPERTY_INT_RANGE',
428
+ field: `tableProperties["${key}"]`,
429
+ message: `table property "${key}" value "${value}" must be an integer between `
430
+ + `${range.min} and ${range.max}`,
431
+ }));
432
+ }
433
+ }
434
+ violations.push(...this.commitRetryOrderingViolations(properties));
435
+ return violations;
436
+ }
437
+ /// ICEBERG_COMMIT_RETRY_ORDERING — commit.retry waits obey
438
+ /// min-wait-ms <= max-wait-ms <= total-timeout-ms when all are positive ints.
439
+ commitRetryOrderingViolations(properties) {
440
+ const values = [
441
+ properties['commit.retry.min-wait-ms'],
442
+ properties['commit.retry.max-wait-ms'],
443
+ properties['commit.retry.total-timeout-ms'],
444
+ ];
445
+ if (!values.every((value) => value !== undefined && isPositiveInteger(value))) {
446
+ return [];
447
+ }
448
+ const [min, max, total,] = values.map(Number);
449
+ if (min <= max && max <= total) {
450
+ return [];
451
+ }
452
+ return [
453
+ this.violation({
454
+ level: 'error',
455
+ code: 'ICEBERG_COMMIT_RETRY_ORDERING',
456
+ field: 'tableProperties["commit.retry.min-wait-ms"]',
457
+ message: 'commit.retry waits must satisfy min-wait-ms <= max-wait-ms <= total-timeout-ms',
458
+ }),
459
+ ];
460
+ }
461
+ /**
462
+ * Validate Iceberg identifier fields (the row-identity / equality-delete
463
+ * key). Equality deletes are a v2 feature, which this engine inherently is;
464
+ * identifier fields must be required primitive columns that are not
465
+ * float/double.
466
+ *
467
+ * Emits `ICEBERG_IDENTIFIER_COLUMN_EXISTS`, `ICEBERG_IDENTIFIER_REQUIRED`,
468
+ * and `ICEBERG_IDENTIFIER_TYPE_PRIMITIVE`.
469
+ *
470
+ * @returns Every identifier-field violation.
471
+ */
472
+ identifierFieldViolations() {
473
+ const violations = [];
474
+ const { identifierFields, } = this.definition;
475
+ if (identifierFields.length === 0) {
476
+ return [];
477
+ }
478
+ identifierFields.forEach((name, index) => {
479
+ const field = `identifierFields[${index}]`;
480
+ const column = this.definition.columns.find((candidate) => candidate.name === name);
481
+ if (column === undefined) {
482
+ violations.push(this.violation({
483
+ level: 'error',
484
+ code: 'ICEBERG_IDENTIFIER_COLUMN_EXISTS',
485
+ field,
486
+ message: `identifier field "${name}" is not defined in columns`,
487
+ }));
488
+ return;
489
+ }
490
+ if (column.nullable === true) {
491
+ violations.push(this.violation({
492
+ level: 'error',
493
+ code: 'ICEBERG_IDENTIFIER_REQUIRED',
494
+ field,
495
+ message: `identifier field "${name}" must be required (nullable: false)`,
496
+ }));
497
+ }
498
+ const type = (0, iceberg_1.parseIcebergType)(column.type);
499
+ if (type === null || type.kind === iceberg_1.IcebergTypeKind.FLOAT || type.kind === iceberg_1.IcebergTypeKind.DOUBLE) {
500
+ violations.push(this.violation({
501
+ level: 'error',
502
+ code: 'ICEBERG_IDENTIFIER_TYPE_PRIMITIVE',
503
+ field,
504
+ message: `identifier field "${name}" must be a primitive type other than float or double`,
505
+ }));
506
+ }
507
+ });
508
+ return violations;
509
+ }
510
+ /**
511
+ * Normalize a partition into its identity key. When the transform parses,
512
+ * collapse on `${kind}:${param}` so `day` and `DAY`, `bucket[16]` and
513
+ * `bucket[ 16 ]` are the same. When the transform doesn't parse, the
514
+ * lowercased trim of the raw string is the best identity we have.
515
+ *
516
+ * @param partition Partition to key.
517
+ * @returns The identity string for duplicate detection.
518
+ */
519
+ partitionKey(partition) {
520
+ const transform = (0, iceberg_1.parseIcebergTransform)(partition.type);
521
+ const normalizedTransform = transform
522
+ ? `${transform.kind}:${transform.param ?? ''}`
523
+ : partition.type.trim().toLowerCase();
524
+ return `${partition.name} ${normalizedTransform}`;
525
+ }
526
+ }
527
+ exports.IcebergParquetV2Table = IcebergParquetV2Table;
528
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWNlYmVyZy1wYXJxdWV0LXYyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3RhYmxlLXR5cGVzL2ljZWJlcmctcGFycXVldC12Mi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7R0FVRzs7O0FBT0gsOENBRXVCO0FBQ3ZCLHdDQU1vQjtBQUVwQjs7Ozs7O0dBTUc7QUFDSCxTQUFTLGlCQUFpQixDQUFDLEtBQWE7SUFDcEMsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEQsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBUyxvQkFBb0IsQ0FBQyxLQUFhO0lBQ3ZDLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMvQixDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILFNBQVMsZ0JBQWdCLENBQUMsS0FBYSxFQUFFLEdBQVcsRUFBRSxHQUFXO0lBQzdELElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDdkIsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM3QixPQUFPLE1BQU0sSUFBSSxHQUFHLElBQUksTUFBTSxJQUFJLEdBQUcsQ0FBQztBQUMxQyxDQUFDO0FBRUQsZ0RBQWdEO0FBQ2hELE1BQWEscUJBQXNCLFNBQVEsMEJBQWE7SUFDcEQ7OztPQUdHO0lBQ08sTUFBTSxDQUFVLHVCQUF1QixHQUFHLENBQUMsQ0FBQztJQUV0RDs7Ozs7T0FLRztJQUNJLGlCQUFpQixDQUFDLElBQVk7UUFDakMsT0FBTyxJQUFBLDRCQUFrQixFQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksbUJBQW1CO1FBQ3RC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QUFzQztpQkFDM0UsQ0FBQyxDQUFDLENBQUM7WUFDUixDQUFDO1lBQ0QsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBZ0IsRUFBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDM0MsSUFBSSxJQUFJLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUsseUJBQWUsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyx5QkFBZSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUMvRixVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7b0JBQzNCLEtBQUssRUFBRSxPQUFPO29CQUNkLElBQUksRUFBRSxtQ0FBbUM7b0JBQ3pDLEtBQUs7b0JBQ0wsT0FBTyxFQUFFLHFCQUFxQixJQUFJLHVEQUF1RDtpQkFDNUYsQ0FBQyxDQUFDLENBQUM7WUFDUixDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLFVBQVUsQ0FBQztJQUN0QixDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSyxZQUFZLENBQUMsU0FBb0I7UUFDckMsTUFBTSxTQUFTLEdBQUcsSUFBQSwrQkFBcUIsRUFBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEQsTUFBTSxtQkFBbUIsR0FBRyxTQUFTO1lBQ2pDLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxJQUFJLElBQUksU0FBUyxDQUFDLEtBQUssSUFBSSxFQUFFLEVBQUU7WUFDOUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDMUMsT0FBTyxHQUFHLFNBQVMsQ0FBQyxJQUFJLElBQUksbUJBQW1CLEVBQUUsQ0FBQztJQUN0RCxDQUFDOztBQWxoQkwsc0RBbWhCQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogSWNlYmVyZyAocGFycXVldCkgZm9ybWF0LXZlcnNpb24tMiB0YWJsZSB0eXBlLlxuICpcbiAqIEljZWJlcmcgcGFydGl0aW9ucyBhcmUgdHJhbnNmb3JtcyBhcHBsaWVkIHRvIGEgZGF0YSBjb2x1bW4sIHNvIGR1cGxpY2F0ZVxuICogZGV0ZWN0aW9uIGtleXMgb24gdGhlIChzb3VyY2UgY29sdW1uLCBub3JtYWxpemVkIHRyYW5zZm9ybSkgcGFpciDigJQgYHllYXIodHMpYFxuICogYW5kIGBtb250aCh0cylgIGFyZSBkaXN0aW5jdCwgd2hpbGUgYGRheWAgYW5kIGBEQVlgIGNvbGxhcHNlLlxuICpcbiAqIFRoZSBmb3JtYXQgdmVyc2lvbiBpcyBlbmNvZGVkIGluIHRoZSBgdGFibGVUeXBlYCBkaXNjcmltaW5hdG9yOiB0aGlzIGVuZ2luZSBpc1xuICogaW5oZXJlbnRseSB2Miwgc28gYSBwcmVzZW50IGBmb3JtYXRWZXJzaW9uYCBtdXN0IGVxdWFsIGBFWFBFQ1RFRF9GT1JNQVRfVkVSU0lPTmAuXG4gKiBBIGZ1dHVyZSBgaWNlYmVyZ19wYXJxdWV0X3YzYCBzaWJsaW5nIHN1YmNsYXNzIG92ZXJyaWRlcyB0aGF0IG9uZSBjb25zdGFudC5cbiAqL1xuXG5pbXBvcnQge1xuICAgIFBhcnRpdGlvbixcbiAgICBTb3J0RmllbGQsXG4gICAgVmlvbGF0aW9uLFxufSBmcm9tICcuLi9tb2RlbCc7XG5pbXBvcnQge1xuICAgIFRhYmxlVHlwZUJhc2UsXG59IGZyb20gJy4uL3RhYmxlLXR5cGUnO1xuaW1wb3J0IHtcbiAgICBJY2ViZXJnVHlwZUtpbmQsXG4gICAgaXNWYWxpZEljZWJlcmdUeXBlLFxuICAgIHBhcnNlSWNlYmVyZ1RyYW5zZm9ybSxcbiAgICBwYXJzZUljZWJlcmdUeXBlLFxuICAgIHRyYW5zZm9ybUxlZ2FsT25UeXBlLFxufSBmcm9tICcuLi9pY2ViZXJnJztcblxuLyoqXG4gKiBXaGV0aGVyIGEgc3RyaW5nIGlzIGEgcG9zaXRpdmUgaW50ZWdlciAoZGlnaXRzIG9ubHksIHZhbHVlID4gMCkuIEljZWJlcmdcbiAqIHRhYmxlLXByb3BlcnR5IHZhbHVlcyBhcmUgc3RyaW5ncywgc28gbnVtZXJpYyBjaGVja3MgcGFyc2UgdGhlIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgUHJvcGVydHkgdmFsdWUgc3RyaW5nLlxuICogQHJldHVybnMgVHJ1ZSB3aGVuIGB2YWx1ZWAgaXMgYSBwb3NpdGl2ZSBpbnRlZ2VyLlxuICovXG5mdW5jdGlvbiBpc1Bvc2l0aXZlSW50ZWdlcih2YWx1ZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIC9eXFxkKyQvLnRlc3QodmFsdWUpICYmIE51bWJlcih2YWx1ZSkgPiAwO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgYSBzdHJpbmcgaXMgYSBub24tbmVnYXRpdmUgaW50ZWdlciAoZGlnaXRzIG9ubHksIHZhbHVlID49IDApLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSBQcm9wZXJ0eSB2YWx1ZSBzdHJpbmcuXG4gKiBAcmV0dXJucyBUcnVlIHdoZW4gYHZhbHVlYCBpcyBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyLlxuICovXG5mdW5jdGlvbiBpc05vbk5lZ2F0aXZlSW50ZWdlcih2YWx1ZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIC9eXFxkKyQvLnRlc3QodmFsdWUpO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgYSBzdHJpbmcgaXMgYW4gaW50ZWdlciB3aXRoaW4gYW4gaW5jbHVzaXZlIHJhbmdlLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSBQcm9wZXJ0eSB2YWx1ZSBzdHJpbmcuXG4gKiBAcGFyYW0gbWluIEluY2x1c2l2ZSBsb3dlciBib3VuZC5cbiAqIEBwYXJhbSBtYXggSW5jbHVzaXZlIHVwcGVyIGJvdW5kLlxuICogQHJldHVybnMgVHJ1ZSB3aGVuIGB2YWx1ZWAgaXMgYW4gaW50ZWdlciBpbiBgW21pbiwgbWF4XWAuXG4gKi9cbmZ1bmN0aW9uIGlzSW50ZWdlckluUmFuZ2UodmFsdWU6IHN0cmluZywgbWluOiBudW1iZXIsIG1heDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgaWYgKCEvXlxcZCskLy50ZXN0KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZCA9IE51bWJlcih2YWx1ZSk7XG4gICAgcmV0dXJuIHBhcnNlZCA+PSBtaW4gJiYgcGFyc2VkIDw9IG1heDtcbn1cblxuLyoqIEljZWJlcmcgKHBhcnF1ZXQpIGZvcm1hdC12ZXJzaW9uLTIgdGFibGUuICovXG5leHBvcnQgY2xhc3MgSWNlYmVyZ1BhcnF1ZXRWMlRhYmxlIGV4dGVuZHMgVGFibGVUeXBlQmFzZSB7XG4gICAgLyoqXG4gICAgICogVGhlIEljZWJlcmcgZm9ybWF0IHZlcnNpb24gdGhpcyBlbmdpbmUgcGlucyB0by4gQSBwcmVzZW50IGBmb3JtYXRWZXJzaW9uYFxuICAgICAqIG11c3QgZXF1YWwgdGhpcy4gQSBmdXR1cmUgdjMgc2libGluZyBzdWJjbGFzcyBvdmVycmlkZXMgdGhpcyBzaW5nbGUgdmFsdWUuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHN0YXRpYyByZWFkb25seSBFWFBFQ1RFRF9GT1JNQVRfVkVSU0lPTiA9IDI7XG5cbiAgICAvKipcbiAgICAgKiBWYWxpZGF0ZSBhIGNvbHVtbiB0eXBlIGFnYWluc3QgdGhlIEljZWJlcmcgdjAgdHlwZSByZWdpc3RyeS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0eXBlIFR5cGUgc3RyaW5nIGZyb20gYSBjb2x1bW4gZGVmaW5pdGlvbi5cbiAgICAgKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhlIHR5cGUgaXMgYSB2YWxpZCBJY2ViZXJnIHR5cGUuXG4gICAgICovXG4gICAgcHVibGljIGlzVmFsaWRDb2x1bW5UeXBlKHR5cGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gaXNWYWxpZEljZWJlcmdUeXBlKHR5cGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEljZWJlcmcgcGFydGl0aW9uIHJ1bGVzLlxuICAgICAqXG4gICAgICogRW1pdHM6IGBOT19EVVBMSUNBVEVfUEFSVElUSU9OU2AgKGtleWVkIGJ5IGAke25hbWV9ICR7dHJhbnNmb3JtS2luZH06JHtwYXJhbX1gLFxuICAgICAqIGZhbGxpbmcgYmFjayB0byBhIGxvd2VyY2FzZWQgdHJpbSBvZiB0aGUgcmF3IHRyYW5zZm9ybSB3aGVuIGl0IGRvZXNuJ3RcbiAgICAgKiBwYXJzZSwgc28gd2hpdGVzcGFjZSAvIGNhc2UgdmFyaWFudHMgb2YgdGhlIHNhbWUgdHJhbnNmb3JtIGNvbGxhcHNlKSxcbiAgICAgKiBgSUNFQkVSR19UUkFOU0ZPUk1fU09VUkNFX0VYSVNUU2AsIGBJQ0VCRVJHX1RSQU5TRk9STV9WQUxJRGAsIGFuZFxuICAgICAqIGBJQ0VCRVJHX1RSQU5TRk9STV9TT1VSQ0VfVFlQRV9MRUdBTGAuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBFdmVyeSBwYXJ0aXRpb24tcmVsYXRlZCB2aW9sYXRpb24uXG4gICAgICovXG4gICAgcHVibGljIHBhcnRpdGlvblZpb2xhdGlvbnMoKTogVmlvbGF0aW9uW10ge1xuICAgICAgICBjb25zdCB2aW9sYXRpb25zOiBWaW9sYXRpb25bXSA9IFtdO1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICBwYXJ0aXRpb25zLFxuICAgICAgICB9ID0gdGhpcy5kZWZpbml0aW9uO1xuXG4gICAgICAgIGNvbnN0IHNlZW4gPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICAgICAgcGFydGl0aW9ucy5mb3JFYWNoKChwYXJ0aXRpb24sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSB0aGlzLnBhcnRpdGlvbktleShwYXJ0aXRpb24pO1xuICAgICAgICAgICAgaWYgKHNlZW4uaGFzKGtleSkpIHtcbiAgICAgICAgICAgICAgICB2aW9sYXRpb25zLnB1c2godGhpcy52aW9sYXRpb24oe1xuICAgICAgICAgICAgICAgICAgICBsZXZlbDogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICAgICAgY29kZTogJ05PX0RVUExJQ0FURV9QQVJUSVRJT05TJyxcbiAgICAgICAgICAgICAgICAgICAgZmllbGQ6IGBwYXJ0aXRpb25zWyR7aW5kZXh9XWAsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBkdXBsaWNhdGUgcGFydGl0aW9uOiBcIiR7cGFydGl0aW9uLm5hbWV9XCIgd2l0aCB0cmFuc2Zvcm0gXCIke3BhcnRpdGlvbi50eXBlfVwiYCxcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWVuLmFkZChrZXkpO1xuICAgICAgICB9KTtcblxuICAgICAgICBwYXJ0aXRpb25zLmZvckVhY2goKHBhcnRpdGlvbiwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZUNvbHVtbiA9IHRoaXMuZGVmaW5pdGlvbi5jb2x1bW5zLmZpbmQoKGNvbHVtbikgPT4gY29sdW1uLm5hbWUgPT09IHBhcnRpdGlvbi5uYW1lKTtcbiAgICAgICAgICAgIGlmIChzb3VyY2VDb2x1bW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHZpb2xhdGlvbnMucHVzaCh0aGlzLnZpb2xhdGlvbih7XG4gICAgICAgICAgICAgICAgICAgIGxldmVsOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICBjb2RlOiAnSUNFQkVSR19UUkFOU0ZPUk1fU09VUkNFX0VYSVNUUycsXG4gICAgICAgICAgICAgICAgICAgIGZpZWxkOiBgcGFydGl0aW9uc1ske2luZGV4fV0ubmFtZWAsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBJY2ViZXJnIHBhcnRpdGlvbiBzb3VyY2UgY29sdW1uIFwiJHtwYXJ0aXRpb24ubmFtZX1cIiBpcyBub3QgZGVmaW5lZCBpbiBjb2x1bW5zYCxcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gcGFyc2VJY2ViZXJnVHJhbnNmb3JtKHBhcnRpdGlvbi50eXBlKTtcbiAgICAgICAgICAgIGlmICh0cmFuc2Zvcm0gPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB2aW9sYXRpb25zLnB1c2godGhpcy52aW9sYXRpb24oe1xuICAgICAgICAgICAgICAgICAgICBsZXZlbDogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICAgICAgY29kZTogJ0lDRUJFUkdfVFJBTlNGT1JNX1ZBTElEJyxcbiAgICAgICAgICAgICAgICAgICAgZmllbGQ6IGBwYXJ0aXRpb25zWyR7aW5kZXh9XS50eXBlYCxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogYFwiJHtwYXJ0aXRpb24udHlwZX1cIiBpcyBub3QgYSB2YWxpZCBJY2ViZXJnIHBhcnRpdGlvbiB0cmFuc2Zvcm1gLFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBzb3VyY2VUeXBlID0gcGFyc2VJY2ViZXJnVHlwZShzb3VyY2VDb2x1bW4udHlwZSk7XG4gICAgICAgICAgICBpZiAoc291cmNlVHlwZSAhPT0gbnVsbCAmJiAhdHJhbnNmb3JtTGVnYWxPblR5cGUodHJhbnNmb3JtLCBzb3VyY2VUeXBlKSkge1xuICAgICAgICAgICAgICAgIHZpb2xhdGlvbnMucHVzaCh0aGlzLnZpb2xhdGlvbih7XG4gICAgICAgICAgICAgICAgICAgIGxldmVsOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICBjb2RlOiAnSUNFQkVSR19UUkFOU0ZPUk1fU09VUkNFX1RZUEVfTEVHQUwnLFxuICAgICAgICAgICAgICAgICAgICBmaWVsZDogYHBhcnRpdGlvbnNbJHtpbmRleH1dLnR5cGVgLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBgdHJhbnNmb3JtIFwiJHtwYXJ0aXRpb24udHlwZX1cIiBpcyBub3QgbGVnYWwgb24gYFxuICAgICAgICAgICAgICAgICAgICAgICAgKyBgY29sdW1uIFwiJHtwYXJ0aXRpb24ubmFtZX1cIiBvZiB0eXBlIFwiJHtzb3VyY2VDb2x1bW4udHlwZX1cImAsXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdmlvbGF0aW9ucztcbiAgICB9XG5cbiAgICAvLy8gVGFibGUtcHJvcGVydHkga2V5cyB3aG9zZSB2YWx1ZSBtdXN0IGNvbWUgZnJvbSBhIGNsb3NlZCBzZXQuXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgRU5VTV9QUk9QRVJUSUVTOiBSZWNvcmQ8c3RyaW5nLCByZWFkb25seSBzdHJpbmdbXT4gPSB7XG4gICAgICAgICd3cml0ZS5mb3JtYXQuZGVmYXVsdCc6IFtcbiAgICAgICAgICAgICdwYXJxdWV0JyxcbiAgICAgICAgICAgICdhdnJvJyxcbiAgICAgICAgICAgICdvcmMnLFxuICAgICAgICBdLFxuICAgICAgICAnd3JpdGUucGFycXVldC5jb21wcmVzc2lvbi1jb2RlYyc6IFtcbiAgICAgICAgICAgICd6c3RkJyxcbiAgICAgICAgICAgICdnemlwJyxcbiAgICAgICAgICAgICdzbmFwcHknLFxuICAgICAgICAgICAgJ2x6NCcsXG4gICAgICAgICAgICAnbm9uZScsXG4gICAgICAgIF0sXG4gICAgICAgICd3cml0ZS5hdnJvLmNvbXByZXNzaW9uLWNvZGVjJzogW1xuICAgICAgICAgICAgJ2d6aXAnLFxuICAgICAgICAgICAgJ3pzdGQnLFxuICAgICAgICAgICAgJ3NuYXBweScsXG4gICAgICAgICAgICAndW5jb21wcmVzc2VkJyxcbiAgICAgICAgXSxcbiAgICAgICAgJ3dyaXRlLm9yYy5jb21wcmVzc2lvbi1jb2RlYyc6IFtcbiAgICAgICAgICAgICd6c3RkJyxcbiAgICAgICAgICAgICdsejQnLFxuICAgICAgICAgICAgJ2x6bycsXG4gICAgICAgICAgICAnemxpYicsXG4gICAgICAgICAgICAnc25hcHB5JyxcbiAgICAgICAgICAgICdub25lJyxcbiAgICAgICAgXSxcbiAgICAgICAgJ3dyaXRlLmRpc3RyaWJ1dGlvbi1tb2RlJzogW1xuICAgICAgICAgICAgJ25vbmUnLFxuICAgICAgICAgICAgJ2hhc2gnLFxuICAgICAgICAgICAgJ3JhbmdlJyxcbiAgICAgICAgXSxcbiAgICAgICAgJ3dyaXRlLm1ldGFkYXRhLmNvbXByZXNzaW9uLWNvZGVjJzogW1xuICAgICAgICAgICAgJ25vbmUnLFxuICAgICAgICAgICAgJ2d6aXAnLFxuICAgICAgICBdLFxuICAgIH07XG5cbiAgICAvLy8gVGFibGUtcHJvcGVydHkga2V5cyB3aG9zZSB2YWx1ZSBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlci5cbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBQT1NJVElWRV9JTlRfUFJPUEVSVElFUzogcmVhZG9ubHkgc3RyaW5nW10gPSBbXG4gICAgICAgICd3cml0ZS50YXJnZXQtZmlsZS1zaXplLWJ5dGVzJyxcbiAgICAgICAgJ2hpc3RvcnkuZXhwaXJlLm1heC1zbmFwc2hvdC1hZ2UtbXMnLFxuICAgICAgICAnaGlzdG9yeS5leHBpcmUubWluLXNuYXBzaG90cy10by1rZWVwJyxcbiAgICAgICAgJ2hpc3RvcnkuZXhwaXJlLm1heC1yZWYtYWdlLW1zJyxcbiAgICAgICAgJ3dyaXRlLm1ldGFkYXRhLnByZXZpb3VzLXZlcnNpb25zLW1heCcsXG4gICAgICAgICdjb21taXQucmV0cnkubWluLXdhaXQtbXMnLFxuICAgICAgICAnY29tbWl0LnJldHJ5Lm1heC13YWl0LW1zJyxcbiAgICAgICAgJ2NvbW1pdC5yZXRyeS50b3RhbC10aW1lb3V0LW1zJyxcbiAgICBdO1xuXG4gICAgLy8vIFRhYmxlLXByb3BlcnR5IGtleXMgd2hvc2UgdmFsdWUgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyLlxuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IE5PTl9ORUdBVElWRV9JTlRfUFJPUEVSVElFUzogcmVhZG9ubHkgc3RyaW5nW10gPSBbXG4gICAgICAgICdjb21taXQucmV0cnkubnVtLXJldHJpZXMnLFxuICAgIF07XG5cbiAgICAvLy8gVGFibGUtcHJvcGVydHkga2V5cyB3aG9zZSB2YWx1ZSBtdXN0IGJlIGFuIGludGVnZXIgd2l0aGluIGFuIGluY2x1c2l2ZSByYW5nZS5cbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBJTlRfUkFOR0VfUFJPUEVSVElFUzogUmVjb3JkPHN0cmluZywgeyBtaW46IG51bWJlcjsgbWF4OiBudW1iZXIgfT4gPSB7XG4gICAgICAgICd3cml0ZS5wYXJxdWV0LmNvbXByZXNzaW9uLWxldmVsJzoge1xuICAgICAgICAgICAgbWluOiAxLFxuICAgICAgICAgICAgbWF4OiAyMixcbiAgICAgICAgfSxcbiAgICB9O1xuXG4gICAgLy8vIExlZ2FsIHNvcnQgZGlyZWN0aW9ucyBhbmQgbnVsbCBvcmRlcmluZ3MuXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgU09SVF9ESVJFQ1RJT05TID0gbmV3IFNldChbXG4gICAgICAgICdhc2MnLFxuICAgICAgICAnZGVzYycsXG4gICAgXSk7XG5cbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBTT1JUX05VTExfT1JERVJTID0gbmV3IFNldChbXG4gICAgICAgICdudWxscy1maXJzdCcsXG4gICAgICAgICdudWxscy1sYXN0JyxcbiAgICBdKTtcblxuICAgIC8qKlxuICAgICAqIEljZWJlcmcgZW5naW5lLXNwZWNpZmljIHJ1bGVzOiBmb3JtYXQgdmVyc2lvbiwgdGFibGUgcHJvcGVydGllcywgYW5kIHNvcnRcbiAgICAgKiBvcmRlci5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEV2ZXJ5IGVuZ2luZS1zcGVjaWZpYyB2aW9sYXRpb24uXG4gICAgICovXG4gICAgcHVibGljIGVuZ2luZVNwZWNpZmljVmlvbGF0aW9ucygpOiBWaW9sYXRpb25bXSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAuLi50aGlzLmZvcm1hdFZlcnNpb25WaW9sYXRpb25zKCksXG4gICAgICAgICAgICAuLi50aGlzLnRhYmxlUHJvcGVydHlWaW9sYXRpb25zKCksXG4gICAgICAgICAgICAuLi50aGlzLnNvcnRPcmRlclZpb2xhdGlvbnMoKSxcbiAgICAgICAgICAgIC4uLnRoaXMuaWRlbnRpZmllckZpZWxkVmlvbGF0aW9ucygpLFxuICAgICAgICAgICAgLi4udGhpcy5maWVsZElkVmlvbGF0aW9ucygpLFxuICAgICAgICBdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFZhbGlkYXRlIEljZWJlcmcgY29sdW1uIGZpZWxkIGlkcyDigJQgdGhlIGlkcyBJY2ViZXJnIHVzZXMgZm9yIHNjaGVtYVxuICAgICAqIGV2b2x1dGlvbi4gUGlubmluZyB0aGVtIGtlZXBzIG9sZCBkYXRhIGZpbGVzIHJlYWRhYmxlIGFjcm9zcyByZW5hbWVzIGFuZFxuICAgICAqIGRyb3BzLCBzbyB0aGV5IGFyZSBhbGwtb3Itbm90aGluZyBwZXIgdGFibGU6IGVpdGhlciBldmVyeSBjb2x1bW4gZGVjbGFyZXNcbiAgICAgKiBhbiBgaWRgIG9yIG5vbmUgZG8uIFdoZW4gcHJlc2VudCwgZWFjaCBpZCBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciBhbmRcbiAgICAgKiB1bmlxdWUgd2l0aGluIHRoZSB0YWJsZS5cbiAgICAgKlxuICAgICAqIEVtaXRzIGBJQ0VCRVJHX0ZJRUxEX0lEX0FMTF9PUl9OT05FYCwgYElDRUJFUkdfRklFTERfSURfUE9TSVRJVkVgLCBhbmRcbiAgICAgKiBgSUNFQkVSR19GSUVMRF9JRF9VTklRVUVgLlxuICAgICAqXG4gICAgICogQHJldHVybnMgRXZlcnkgZmllbGQtaWQgdmlvbGF0aW9uLlxuICAgICAqL1xuICAgIHByaXZhdGUgZmllbGRJZFZpb2xhdGlvbnMoKTogVmlvbGF0aW9uW10ge1xuICAgICAgICBjb25zdCB2aW9sYXRpb25zOiBWaW9sYXRpb25bXSA9IFtdO1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICBjb2x1bW5zLFxuICAgICAgICB9ID0gdGhpcy5kZWZpbml0aW9uO1xuXG4gICAgICAgIGNvbnN0IHdpdGhJZCA9IGNvbHVtbnMuZmlsdGVyKChjb2x1bW4pID0+IGNvbHVtbi5pZCAhPT0gdW5kZWZpbmVkKTtcbiAgICAgICAgaWYgKHdpdGhJZC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh3aXRoSWQubGVuZ3RoICE9PSBjb2x1bW5zLmxlbmd0aCkge1xuICAgICAgICAgICAgdmlvbGF0aW9ucy5wdXNoKHRoaXMudmlvbGF0aW9uKHtcbiAgICAgICAgICAgICAgICBsZXZlbDogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICBjb2RlOiAnSUNFQkVSR19GSUVMRF9JRF9BTExfT1JfTk9ORScsXG4gICAgICAgICAgICAgICAgZmllbGQ6ICdjb2x1bW5zJyxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBgZWl0aGVyIGV2ZXJ5IGNvbHVtbiBkZWNsYXJlcyBhbiBpZCBvciBub25lIGRvOyAke3dpdGhJZC5sZW5ndGh9IGBcbiAgICAgICAgICAgICAgICAgICAgKyBgb2YgJHtjb2x1bW5zLmxlbmd0aH0gY29sdW1ucyBoYXZlIGFuIGlkYCxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNlZW4gPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgICAgICAgY29sdW1ucy5mb3JFYWNoKChjb2x1bW4sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICB9ID0gY29sdW1uO1xuICAgICAgICAgICAgaWYgKGlkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBJbnRlZ2VyLW5lc3MgaXMgZW5mb3JjZWQgc3RydWN0dXJhbGx5IGJ5IHRoZSBKU09OIFNjaGVtYSwgc28gYW4gaWRcbiAgICAgICAgICAgIC8vIHRoYXQgcmVhY2hlcyB0aGUgZW5naW5lIGlzIGFsd2F5cyBhbiBpbnRlZ2VyOyBvbmx5IGl0cyBzaWduIGlzXG4gICAgICAgICAgICAvLyBjaGVja2VkIGhlcmUuXG4gICAgICAgICAgICBpZiAoaWQgPCAxKSB7XG4gICAgICAgICAgICAgICAgdmlvbGF0aW9ucy5wdXNoKHRoaXMudmlvbGF0aW9uKHtcbiAgICAgICAgICAgICAgICAgICAgbGV2ZWw6ICdlcnJvcicsXG4gICAgICAgICAgICAgICAgICAgIGNvZGU6ICdJQ0VCRVJHX0ZJRUxEX0lEX1BPU0lUSVZFJyxcbiAgICAgICAgICAgICAgICAgICAgZmllbGQ6IGBjb2x1bW5zWyR7aW5kZXh9XS5pZGAsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBjb2x1bW4gXCIke2NvbHVtbi5uYW1lfVwiIGlkICR7aWR9IG11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyYCxcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNlZW4uaGFzKGlkKSkge1xuICAgICAgICAgICAgICAgIHZpb2xhdGlvbnMucHVzaCh0aGlzLnZpb2xhdGlvbih7XG4gICAgICAgICAgICAgICAgICAgIGxldmVsOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICBjb2RlOiAnSUNFQkVSR19GSUVMRF9JRF9VTklRVUUnLFxuICAgICAgICAgICAgICAgICAgICBmaWVsZDogYGNvbHVtbnNbJHtpbmRleH1dLmlkYCxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogYGNvbHVtbiBcIiR7Y29sdW1uLm5hbWV9XCIgcmV1c2VzIGZpZWxkIGlkICR7aWR9OyBpZHMgbXVzdCBiZSB1bmlxdWUgd2l0aGluIHRoZSB0YWJsZWAsXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2Vlbi5hZGQoaWQpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdmlvbGF0aW9ucztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBWYWxpZGF0ZSB0aGUgSWNlYmVyZyBzb3J0IG9yZGVyLlxuICAgICAqXG4gICAgICogRW1pdHMgYE5PX0RVUExJQ0FURV9TT1JUX0ZJRUxEU2AgKGtleWVkIGJ5IHNvdXJjZSBjb2x1bW4gKyBub3JtYWxpemVkXG4gICAgICogdHJhbnNmb3JtKSwgYElDRUJFUkdfU09SVF9DT0xVTU5fRVhJU1RTYCwgYElDRUJFUkdfU09SVF9ESVJFQ1RJT05fVkFMSURgLFxuICAgICAqIGBJQ0VCRVJHX1NPUlRfTlVMTF9PUkRFUl9WQUxJRGAsIGBJQ0VCRVJHX1NPUlRfVFJBTlNGT1JNX1ZBTElEYCwgYW5kXG4gICAgICogYElDRUJFUkdfU09SVF9UUkFOU0ZPUk1fVFlQRV9MRUdBTGAuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBFdmVyeSBzb3J0LW9yZGVyIHZpb2xhdGlvbi5cbiAgICAgKi9cbiAgICBwcml2YXRlIHNvcnRPcmRlclZpb2xhdGlvbnMoKTogVmlvbGF0aW9uW10ge1xuICAgICAgICBjb25zdCB2aW9sYXRpb25zOiBWaW9sYXRpb25bXSA9IFtdO1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICBzb3J0T3JkZXIsXG4gICAgICAgIH0gPSB0aGlzLmRlZmluaXRpb247XG5cbiAgICAgICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgICBzb3J0T3JkZXIuZm9yRWFjaCgoZmllbGQsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSB0aGlzLnNvcnRGaWVsZEtleShmaWVsZCk7XG4gICAgICAgICAgICBpZiAoc2Vlbi5oYXMoa2V5KSkge1xuICAgICAgICAgICAgICAgIHZpb2xhdGlvbnMucHVzaCh0aGlzLnZpb2xhdGlvbih7XG4gICAgICAgICAgICAgICAgICAgIGxldmVsOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICBjb2RlOiAnTk9fRFVQTElDQVRFX1NPUlRfRklFTERTJyxcbiAgICAgICAgICAgICAgICAgICAgZmllbGQ6IGBzb3J0T3JkZXJbJHtpbmRleH1dYCxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogYGR1cGxpY2F0ZSBzb3J0IGZpZWxkOiBcIiR7ZmllbGQuY29sdW1ufVwiYFxuICAgICAgICAgICAgICAgICAgICAgICAgKyBgJHtmaWVsZC50cmFuc2Zvcm0gPyBgIHdpdGggdHJhbnNmb3JtIFwiJHtmaWVsZC50cmFuc2Zvcm19XCJgIDogJyd9YCxcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWVuLmFkZChrZXkpO1xuICAgICAgICB9KTtcblxuICAgICAgICBzb3J0T3JkZXIuZm9yRWFjaCgoZmllbGQsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBpZiAoIUljZWJlcmdQYXJxdWV0VjJUYWJsZS5TT1JUX0RJUkVDVElPTlMuaGFzKGZpZWxkLmRpcmVjdGlvbikpIHtcbiAgICAgICAgICAgICAgICB2aW9sYXRpb25zLnB1c2godGhpcy52aW9sYXRpb24oe1xuICAgICAgICAgICAgICAgICAgICBsZXZlbDogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICAgICAgY29kZTogJ0lDRUJFUkdfU09SVF9ESVJFQ1RJT05fVkFMSUQnLFxuICAgICAgICAgICAgICAgICAgICBmaWVsZDogYHNvcnRPcmRlclske2luZGV4fV0uZGlyZWN0aW9uYCxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogYHNvcnQgZGlyZWN0aW9uIFwiJHtmaWVsZC5kaXJlY3Rpb259XCIgbXVzdCBiZSBcImFzY1wiIG9yIFwiZGVzY1wiYCxcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIUljZWJlcmdQYXJxdWV0VjJUYWJsZS5TT1JUX05VTExfT1JERVJTLmhhcyhmaWVsZC5udWxsT3JkZXIpKSB7XG4gICAgICAgICAgICAgICAgdmlvbGF0aW9ucy5wdXNoKHRoaXMudmlvbGF0aW9uKHtcbiAgICAgICAgICAgICAgICAgICAgbGV2ZWw6ICdlcnJvcicsXG4gICAgICAgICAgICAgICAgICAgIGNvZGU6ICdJQ0VCRVJHX1NPUlRfTlVMTF9PUkRFUl9WQUxJRCcsXG4gICAgICAgICAgICAgICAgICAgIGZpZWxkOiBgc29ydE9yZGVyWyR7aW5kZXh9XS5udWxsT3JkZXJgLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBgc29ydCBudWxsIG9yZGVyIFwiJHtmaWVsZC5udWxsT3JkZXJ9XCIgbXVzdCBiZSBcIm51bGxzLWZpcnN0XCIgb3IgXCJudWxscy1sYXN0XCJgLFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgc291cmNlQ29sdW1uID0gdGhpcy5kZWZpbml0aW9uLmNvbHVtbnMuZmluZCgoY29sdW1uKSA9PiBjb2x1bW4ubmFtZSA9PT0gZmllbGQuY29sdW1uKTtcbiAgICAgICAgICAgIGlmIChzb3VyY2VDb2x1bW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHZpb2xhdGlvbnMucHVzaCh0aGlzLnZpb2xhdGlvbih7XG4gICAgICAgICAgICAgICAgICAgIGxldmVsOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICBjb2RlOiAnSUNFQkVSR19TT1JUX0NPTFVNTl9FWElTVFMnLFxuICAgICAgICAgICAgICAgICAgICBmaWVsZDogYHNvcnRPcmRlclske2luZGV4fV0uY29sdW1uYCxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogYHNvcnQgY29sdW1uIFwiJHtmaWVsZC5jb2x1bW59XCIgaXMgbm90IGRlZmluZWQgaW4gY29sdW1uc2AsXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGZpZWxkLnRyYW5zZm9ybSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gcGFyc2VJY2ViZXJnVHJhbnNmb3JtKGZpZWxkLnRyYW5zZm9ybSk7XG4gICAgICAgICAgICBpZiAodHJhbnNmb3JtID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdmlvbGF0aW9ucy5wdXNoKHRoaXMudmlvbGF0aW9uKHtcbiAgICAgICAgICAgICAgICAgICAgbGV2ZWw6ICdlcnJvcicsXG4gICAgICAgICAgICAgICAgICAgIGNvZGU6ICdJQ0VCRVJHX1NPUlRfVFJBTlNGT1JNX1ZBTElEJyxcbiAgICAgICAgICAgICAgICAgICAgZmllbGQ6IGBzb3J0T3JkZXJbJHtpbmRleH1dLnRyYW5zZm9ybWAsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBcIiR7ZmllbGQudHJhbnNmb3JtfVwiIGlzIG5vdCBhIHZhbGlkIEljZWJlcmcgdHJhbnNmb3JtYCxcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc291cmNlVHlwZSA9IHBhcnNlSWNlYmVyZ1R5cGUoc291cmNlQ29sdW1uLnR5cGUpO1xuICAgICAgICAgICAgaWYgKHNvdXJjZVR5cGUgIT09IG51bGwgJiYgIXRyYW5zZm9ybUxlZ2FsT25UeXBlKHRyYW5zZm9ybSwgc291cmNlVHlwZSkpIHtcbiAgICAgICAgICAgICAgICB2aW9sYXRpb25zLnB1c2godGhpcy52aW9sYXRpb24oe1xuICAgICAgICAgICAgICAgICAgICBsZXZlbDogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICAgICAgY29kZTogJ0lDRUJFUkdfU09SVF9UUkFOU0ZPUk1fVFlQRV9MRUdBTCcsXG4gICAgICAgICAgICAgICAgICAgIGZpZWxkOiBgc29ydE9yZGVyWyR7aW5kZXh9XS50cmFuc2Zvcm1gLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBgdHJhbnNmb3JtIFwiJHtmaWVsZC50cmFuc2Zvcm19XCIgaXMgbm90IGxlZ2FsIG9uIGBcbiAgICAgICAgICAgICAgICAgICAgICAgICsgYGNvbHVtbiBcIiR7ZmllbGQuY29sdW1ufVwiIG9mIHR5cGUgXCIke3NvdXJjZUNvbHVtbi50eXBlfVwiYCxcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB2aW9sYXRpb25zO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE5vcm1hbGl6ZSBhIHNvcnQgZmllbGQgaW50byBpdHMgaWRlbnRpdHkga2V5LiBBbiBvbWl0dGVkIHRyYW5zZm9ybSBhbmQgYW5cbiAgICAgKiBleHBsaWNpdCBgaWRlbnRpdHlgIGNvbGxhcHNlIHRvIHRoZSBzYW1lIGtleSBzbyB0aGV5IGNvdW50IGFzIGR1cGxpY2F0ZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZmllbGQgU29ydCBmaWVsZCB0byBrZXkuXG4gICAgICogQHJldHVybnMgVGhlIGlkZW50aXR5IHN0cmluZyBmb3IgZHVwbGljYXRlIGRldGVjdGlvbi5cbiAgICAgKi9cbiAgICBwcml2YXRlIHNvcnRGaWVsZEtleShmaWVsZDogU29ydEZpZWxkKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKGZpZWxkLnRyYW5zZm9ybSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gYCR7ZmllbGQuY29sdW1ufSBpZGVudGl0eTpgO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IHBhcnNlSWNlYmVyZ1RyYW5zZm9ybShmaWVsZC50cmFuc2Zvcm0pO1xuICAgICAgICBjb25zdCBub3JtYWxpemVkVHJhbnNmb3JtID0gdHJhbnNmb3JtXG4gICAgICAgICAgICA/IGAke3RyYW5zZm9ybS5raW5kfToke3RyYW5zZm9ybS5wYXJhbSA/PyAnJ31gXG4gICAgICAgICAgICA6IGZpZWxkLnRyYW5zZm9ybS50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgcmV0dXJuIGAke2ZpZWxkLmNvbHVtbn0gJHtub3JtYWxpemVkVHJhbnNmb3JtfWA7XG4gICAgfVxuXG4gICAgLy8vIElDRUJFUkdfRk9STUFUX1ZFUlNJT05fVkFMSUQg4oCUIGBmb3JtYXRWZXJzaW9uYCwgd2hlbiBzZXQsIGVxdWFscyB0aGVcbiAgICAvLy8gdmVyc2lvbiB0aGlzIGVuZ2luZSBwaW5zIHRvICgyIGZvciBgaWNlYmVyZ19wYXJxdWV0X3YyYCkuXG4gICAgcHJpdmF0ZSBmb3JtYXRWZXJzaW9uVmlvbGF0aW9ucygpOiBWaW9sYXRpb25bXSB7XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIGZvcm1hdFZlcnNpb24sXG4gICAgICAgIH0gPSB0aGlzLmRlZmluaXRpb247XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkID0gKHRoaXMuY29uc3RydWN0b3IgYXMgdHlwZW9mIEljZWJlcmdQYXJxdWV0VjJUYWJsZSkuRVhQRUNURURfRk9STUFUX1ZFUlNJT047XG4gICAgICAgIGlmIChmb3JtYXRWZXJzaW9uID09PSB1bmRlZmluZWQgfHwgZm9ybWF0VmVyc2lvbiA9PT0gZXhwZWN0ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgdGhpcy52aW9sYXRpb24oe1xuICAgICAgICAgICAgICAgIGxldmVsOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgIGNvZGU6ICdJQ0VCRVJHX0ZPUk1BVF9WRVJTSU9OX1ZBTElEJyxcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2Zvcm1hdFZlcnNpb24nLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGBJY2ViZXJnIGZvcm1hdFZlcnNpb24gXCIke2Zvcm1hdFZlcnNpb259XCIgbXVzdCBiZSAke2V4cGVjdGVkfWAsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBWYWxpZGF0ZSB0aGUgY2xvc2VkLWRvbWFpbiBJY2ViZXJnIHRhYmxlIHByb3BlcnRpZXMuIEtleXMgb3V0c2lkZSB0aGVcbiAgICAgKiBrbm93biBzZXQgcGFzcyB0aHJvdWdoIHVudmFsaWRhdGVkLlxuICAgICAqXG4gICAgICogRW1pdHMgYElDRUJFUkdfUFJPUEVSVFlfRU5VTV9WQUxJRGAsIGBJQ0VCRVJHX1BST1BFUlRZX1BPU0lUSVZFX0lOVGAsXG4gICAgICogYElDRUJFUkdfUFJPUEVSVFlfTk9OX05FR0FUSVZFX0lOVGAsIGBJQ0VCRVJHX1BST1BFUlRZX0lOVF9SQU5HRWAsIGFuZFxuICAgICAqIGBJQ0VCRVJHX0NPTU1JVF9SRVRSWV9PUkRFUklOR2AuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBFdmVyeSB0YWJsZS1wcm9wZXJ0eSB2aW9sYXRpb24uXG4gICAgICovXG4gICAgcHJpdmF0ZSB0YWJsZVByb3BlcnR5VmlvbGF0aW9ucygpOiBWaW9sYXRpb25bXSB7XG4gICAgICAgIGNvbnN0IHZpb2xhdGlvbnM6IFZpb2xhdGlvbltdID0gW107XG4gICAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSB0aGlzLmRlZmluaXRpb24udGFibGVQcm9wZXJ0aWVzO1xuXG4gICAgICAgIGZvciAoY29uc3QgW1xuICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgIF0gb2YgT2JqZWN0LmVudHJpZXMocHJvcGVydGllcykpIHtcbiAgICAgICAgICAgIGNvbnN0IGFsbG93ZWQgPSBJY2ViZXJnUGFycXVldFYyVGFibGUuRU5VTV9QUk9QRVJUSUVTW2tleV07XG4gICAgICAgICAgICBpZiAoYWxsb3dlZCAhPT0gdW5kZWZpbmVkICYmICFhbGxvd2VkLmluY2x1ZGVzKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHZpb2xhdGlvbnMucHVzaCh0aGlzLnZpb2xhdGlvbih7XG4gICAgICAgICAgICAgICAgICAgIGxldmVsOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICBjb2RlOiAnSUNFQkVSR19QUk9QRVJUWV9FTlVNX1ZBTElEJyxcbiAgICAgICAgICAgICAgICAgICAgZmllbGQ6IGB0YWJsZVByb3BlcnRpZXNbXCIke2tleX1cIl1gLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBgdGFibGUgcHJvcGVydHkgXCIke2tleX1cIiB2YWx1ZSBcIiR7dmFsdWV9XCIgbXVzdCBiZSBvbmUgb2Y6ICR7YWxsb3dlZC5qb2luKCcsICcpfWAsXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoSWNlYmVyZ1BhcnF1ZXRWMlRhYmxlLlBPU0lUSVZFX0lOVF9QUk9QRVJUSUVTLmluY2x1ZGVzKGtleSkgJiYgIWlzUG9zaXRpdmVJbnRlZ2VyKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHZpb2xhdGlvbnMucHVzaCh0aGlzLnZpb2xhdGlvbih7XG4gICAgICAgICAgICAgICAgICAgIGxldmVsOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICBjb2RlOiAnSUNFQkVSR19QUk9QRVJUWV9QT1NJVElWRV9JTlQnLFxuICAgICAgICAgICAgICAgICAgICBmaWVsZDogYHRhYmxlUHJvcGVydGllc1tcIiR7a2V5fVwiXWAsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGB0YWJsZSBwcm9wZXJ0eSBcIiR7a2V5fVwiIHZhbHVlIFwiJHt2YWx1ZX1cIiBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlcmAsXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoSWNlYmVyZ1BhcnF1ZXRWMlRhYmxlLk5PTl9ORUdBVElWRV9JTlRfUFJPUEVSVElFUy5pbmNsdWRlcyhrZXkpICYmICFpc05vbk5lZ2F0aXZlSW50ZWdlcih2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB2aW9sYXRpb25zLnB1c2godGhpcy52aW9sYXRpb24oe1xuICAgICAgICAgICAgICAgICAgICBsZXZlbDogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICAgICAgY29kZTogJ0lDRUJFUkdfUFJPUEVSVFlfTk9OX05FR0FUSVZFX0lOVCcsXG4gICAgICAgICAgICAgICAgICAgIGZpZWxkOiBgdGFibGVQcm9wZXJ0aWVzW1wiJHtrZXl9XCJdYCxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogYHRhYmxlIHByb3BlcnR5IFwiJHtrZXl9XCIgdmFsdWUgXCIke3ZhbHVlfVwiIG11c3QgYmUgYSBub24tbmVnYXRpdmUgaW50ZWdlcmAsXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCByYW5nZSA9IEljZWJlcmdQYXJxdWV0VjJUYWJsZS5JTlRfUkFOR0VfUFJPUEVSVElFU1trZXldO1xuICAgICAgICAgICAgaWYgKHJhbmdlICE9PSB1bmRlZmluZWQgJiYgIWlzSW50ZWdlckluUmFuZ2UodmFsdWUsIHJhbmdlLm1pbiwgcmFuZ2UubWF4KSkge1xuICAgICAgICAgICAgICAgIHZpb2xhdGlvbnMucHVzaCh0aGlzLnZpb2xhdGlvbih7XG4gICAgICAgICAgICAgICAgICAgIGxldmVsOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICBjb2RlOiAnSUNFQkVSR19QUk9QRVJUWV9JTlRfUkFOR0UnLFxuICAgICAgICAgICAgICAgICAgICBmaWVsZDogYHRhYmxlUHJvcGVydGllc1tcIiR7a2V5fVwiXWAsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGB0YWJsZSBwcm9wZXJ0eSBcIiR7a2V5fVwiIHZhbHVlIFwiJHt2YWx1ZX1cIiBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiBgXG4gICAgICAgICAgICAgICAgICAgICAgICArIGAke3JhbmdlLm1pbn0gYW5kICR7cmFuZ2UubWF4fWAsXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmlvbGF0aW9ucy5wdXNoKC4uLnRoaXMuY29tbWl0UmV0cnlPcmRlcmluZ1Zpb2xhdGlvbnMocHJvcGVydGllcykpO1xuXG4gICAgICAgIHJldHVybiB2aW9sYXRpb25zO1xuICAgIH1cblxuICAgIC8vLyBJQ0VCRVJHX0NPTU1JVF9SRVRSWV9PUkRFUklORyDigJQgY29tbWl0LnJldHJ5IHdhaXRzIG9iZXlcbiAgICAvLy8gbWluLXdhaXQtbXMgPD0gbWF4LXdhaXQtbXMgPD0gdG90YWwtdGltZW91dC1tcyB3aGVuIGFsbCBhcmUgcG9zaXRpdmUgaW50cy5cbiAgICBwcml2YXRlIGNvbW1pdFJldHJ5T3JkZXJpbmdWaW9sYXRpb25zKHByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pOiBWaW9sYXRpb25bXSB7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IFtcbiAgICAgICAgICAgIHByb3BlcnRpZXNbJ2NvbW1pdC5yZXRyeS5taW4td2FpdC1tcyddLFxuICAgICAgICAgICAgcHJvcGVydGllc1snY29tbWl0LnJldHJ5Lm1heC13YWl0LW1zJ10sXG4gICAgICAgICAgICBwcm9wZXJ0aWVzWydjb21taXQucmV0cnkudG90YWwtdGltZW91dC1tcyddLFxuICAgICAgICBdO1xuICAgICAgICBpZiAoIXZhbHVlcy5ldmVyeSgodmFsdWUpID0+IHZhbHVlICE9PSB1bmRlZmluZWQgJiYgaXNQb3NpdGl2ZUludGVnZXIodmFsdWUpKSkge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IFtcbiAgICAgICAgICAgIG1pbixcbiAgICAgICAgICAgIG1heCxcbiAgICAgICAgICAgIHRvdGFsLFxuICAgICAgICBdID0gdmFsdWVzLm1hcChOdW1iZXIpO1xuICAgICAgICBpZiAobWluIDw9IG1heCAmJiBtYXggPD0gdG90YWwpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgdGhpcy52aW9sYXRpb24oe1xuICAgICAgICAgICAgICAgIGxldmVsOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgIGNvZGU6ICdJQ0VCRVJHX0NPTU1JVF9SRVRSWV9PUkRFUklORycsXG4gICAgICAgICAgICAgICAgZmllbGQ6ICd0YWJsZVByb3BlcnRpZXNbXCJjb21taXQucmV0cnkubWluLXdhaXQtbXNcIl0nLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdjb21taXQucmV0cnkgd2FpdHMgbXVzdCBzYXRpc2Z5IG1pbi13YWl0LW1zIDw9IG1heC13YWl0LW1zIDw9IHRvdGFsLXRpbWVvdXQtbXMnLFxuICAgICAgICAgICAgfSksXG4gICAgICAgIF07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVmFsaWRhdGUgSWNlYmVyZyBpZGVudGlmaWVyIGZpZWxkcyAodGhlIHJvdy1pZGVudGl0eSAvIGVxdWFsaXR5LWRlbGV0ZVxuICAgICAqIGtleSkuIEVxdWFsaXR5IGRlbGV0ZXMgYXJlIGEgdjIgZmVhdHVyZSwgd2hpY2ggdGhpcyBlbmdpbmUgaW5oZXJlbnRseSBpcztcbiAgICAgKiBpZGVudGlmaWVyIGZpZWxkcyBtdXN0IGJlIHJlcXVpcmVkIHByaW1pdGl2ZSBjb2x1bW5zIHRoYXQgYXJlIG5vdFxuICAgICAqIGZsb2F0L2RvdWJsZS5cbiAgICAgKlxuICAgICAqIEVtaXRzIGBJQ0VCRVJHX0lERU5USUZJRVJfQ09MVU1OX0VYSVNUU2AsIGBJQ0VCRVJHX0lERU5USUZJRVJfUkVRVUlSRURgLFxuICAgICAqIGFuZCBgSUNFQkVSR19JREVOVElGSUVSX1RZUEVfUFJJTUlUSVZFYC5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEV2ZXJ5IGlkZW50aWZpZXItZmllbGQgdmlvbGF0aW9uLlxuICAgICAqL1xuICAgIHByaXZhdGUgaWRlbnRpZmllckZpZWxkVmlvbGF0aW9ucygpOiBWaW9sYXRpb25bXSB7XG4gICAgICAgIGNvbnN0IHZpb2xhdGlvbnM6IFZpb2xhdGlvbltdID0gW107XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIGlkZW50aWZpZXJGaWVsZHMsXG4gICAgICAgIH0gPSB0aGlzLmRlZmluaXRpb247XG5cbiAgICAgICAgaWYgKGlkZW50aWZpZXJGaWVsZHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cblxuICAgICAgICBpZGVudGlmaWVyRmllbGRzLmZvckVhY2goKG5hbWUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmaWVsZCA9IGBpZGVudGlmaWVyRmllbGRzWyR7aW5kZXh9XWA7XG4gICAgICAgICAgICBjb25zdCBjb2x1bW4gPSB0aGlzLmRlZmluaXRpb24uY29sdW1ucy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5uYW1lID09PSBuYW1lKTtcbiAgICAgICAgICAgIGlmIChjb2x1bW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHZpb2xhdGlvbnMucHVzaCh0aGlzLnZpb2xhdGlvbih7XG4gICAgICAgICAgICAgICAgICAgIGxldmVsOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgICAgICBjb2RlOiAnSUNFQkVSR19JREVOVElGSUVSX0NPTFVNTl9FWElTVFMnLFxuICAgICAgICAgICAgICAgICAgICBmaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogYGlkZW50aWZpZXIgZmllbGQgXCIke25hbWV9XCIgaXMgbm90IGRlZmluZWQgaW4gY29sdW1uc2AsXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjb2x1bW4ubnVsbGFibGUgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICB2aW9sYXRpb25zLnB1c2godGhpcy52aW9sYXRpb24oe1xuICAgICAgICAgICAgICAgICAgICBsZXZlbDogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICAgICAgY29kZTogJ0lDRUJFUkdfSURFTlRJRklFUl9SRVFVSVJFRCcsXG4gICAgICAgICAgICAgICAgICAgIGZpZWxkLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBgaWRlbnRpZmllciBmaWVsZCBcIiR7bmFtZX1cIiBtdXN0IGJlIHJlcXVpcmVkIChudWxsYWJsZTogZmFsc2UpYCxcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB0eXBlID0gcGFyc2VJY2ViZXJnVHlwZShjb2x1bW4udHlwZSk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gbnVsbCB8fCB0eXBlLmtpbmQgPT09IEljZWJlcmdUeXBlS2luZC5GTE9BVCB8fCB0eXBlLmtpbmQgPT09IEljZWJlcmdUeXBlS2luZC5ET1VCTEUpIHtcbiAgICAgICAgICAgICAgICB2aW9sYXRpb25zLnB1c2godGhpcy52aW9sYXRpb24oe1xuICAgICAgICAgICAgICAgICAgICBsZXZlbDogJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICAgICAgY29kZTogJ0lDRUJFUkdfSURFTlRJRklFUl9UWVBFX1BSSU1JVElWRScsXG4gICAgICAgICAgICAgICAgICAgIGZpZWxkLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBgaWRlbnRpZmllciBmaWVsZCBcIiR7bmFtZX1cIiBtdXN0IGJlIGEgcHJpbWl0aXZlIHR5cGUgb3RoZXIgdGhhbiBmbG9hdCBvciBkb3VibGVgLFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHZpb2xhdGlvbnM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTm9ybWFsaXplIGEgcGFydGl0aW9uIGludG8gaXRzIGlkZW50aXR5IGtleS4gV2hlbiB0aGUgdHJhbnNmb3JtIHBhcnNlcyxcbiAgICAgKiBjb2xsYXBzZSBvbiBgJHtraW5kfToke3BhcmFtfWAgc28gYGRheWAgYW5kIGBEQVlgLCBgYnVja2V0WzE2XWAgYW5kXG4gICAgICogYGJ1Y2tldFsgMTYgXWAgYXJlIHRoZSBzYW1lLiBXaGVuIHRoZSB0cmFuc2Zvcm0gZG9lc24ndCBwYXJzZSwgdGhlXG4gICAgICogbG93ZXJjYXNlZCB0cmltIG9mIHRoZSByYXcgc3RyaW5nIGlzIHRoZSBiZXN0IGlkZW50aXR5IHdlIGhhdmUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcGFydGl0aW9uIFBhcnRpdGlvbiB0byBrZXkuXG4gICAgICogQHJldHVybnMgVGhlIGlkZW50aXR5IHN0cmluZyBmb3IgZHVwbGljYXRlIGRldGVjdGlvbi5cbiAgICAgKi9cbiAgICBwcml2YXRlIHBhcnRpdGlvbktleShwYXJ0aXRpb246IFBhcnRpdGlvbik6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IHBhcnNlSWNlYmVyZ1RyYW5zZm9ybShwYXJ0aXRpb24udHlwZSk7XG4gICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRUcmFuc2Zvcm0gPSB0cmFuc2Zvcm1cbiAgICAgICAgICAgID8gYCR7dHJhbnNmb3JtLmtpbmR9OiR7dHJhbnNmb3JtLnBhcmFtID8/ICcnfWBcbiAgICAgICAgICAgIDogcGFydGl0aW9uLnR5cGUudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHJldHVybiBgJHtwYXJ0aXRpb24ubmFtZX0gJHtub3JtYWxpemVkVHJhbnNmb3JtfWA7XG4gICAgfVxufVxuIl19
@@ -8,12 +8,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
8
8
  exports.createTableType = createTableType;
9
9
  const model_1 = require("../model");
10
10
  const hive_parquet_1 = require("./hive-parquet");
11
- const iceberg_parquet_1 = require("./iceberg-parquet");
11
+ const iceberg_parquet_v2_1 = require("./iceberg-parquet-v2");
12
12
  const postgres_18_1 = require("./postgres-18");
13
13
  /// Exhaustive map: every value of the `TableType` enum has a concrete subclass.
14
14
  const REGISTRY = {
15
15
  [model_1.TableType.HIVE_PARQUET]: hive_parquet_1.HiveParquetTable,
16
- [model_1.TableType.ICEBERG_PARQUET]: iceberg_parquet_1.IcebergParquetTable,
16
+ [model_1.TableType.ICEBERG_PARQUET_V2]: iceberg_parquet_v2_1.IcebergParquetV2Table,
17
17
  [model_1.TableType.POSTGRES_18]: postgres_18_1.Postgres18Table,
18
18
  };
19
19
  /**
@@ -33,4 +33,4 @@ function createTableType(fields) {
33
33
  const Constructor = REGISTRY[tableType] ?? hive_parquet_1.HiveParquetTable;
34
34
  return new Constructor(fields);
35
35
  }
36
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGFibGUtdHlwZXMvcmVnaXN0cnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7O0dBSUc7O0FBbUNILDBDQVVDO0FBM0NELG9DQUVrQjtBQUtsQixpREFFd0I7QUFDeEIsdURBRTJCO0FBQzNCLCtDQUV1QjtBQUt2QixnRkFBZ0Y7QUFDaEYsTUFBTSxRQUFRLEdBQTRDO0lBQ3RELENBQUMsaUJBQVMsQ0FBQyxZQUFZLENBQUMsRUFBRSwrQkFBZ0I7SUFDMUMsQ0FBQyxpQkFBUyxDQUFDLGVBQWUsQ0FBQyxFQUFFLHFDQUFtQjtJQUNoRCxDQUFDLGlCQUFTLENBQUMsV0FBVyxDQUFDLEVBQUUsNkJBQWU7Q0FDM0MsQ0FBQztBQUVGOzs7OztHQUtHO0FBQ0gsU0FBZ0IsZUFBZSxDQUFDLE1BQXVCO0lBQ25ELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBc0IsQ0FBQztJQUMzRCw0RUFBNEU7SUFDNUUsd0VBQXdFO0lBQ3hFLDBFQUEwRTtJQUMxRSwyRUFBMkU7SUFDM0UseUVBQXlFO0lBQ3pFLDZCQUE2QjtJQUM3QixNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksK0JBQWdCLENBQUM7SUFDNUQsT0FBTyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNuQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSZWdpc3RyeSBtYXBwaW5nIHRoZSBgdGFibGVUeXBlYCBzdHJpbmcgdG8gdGhlIGNvbmNyZXRlIGBUYWJsZVR5cGVCYXNlYFxuICogc3ViY2xhc3MgdGhhdCBpbXBsZW1lbnRzIGl0LiBBZGRpbmcgYSBuZXcgZW5naW5lIGlzIGEgbWF0dGVyIG9mIHdyaXRpbmcgYVxuICogc3ViY2xhc3MgYW5kIGFkZGluZyBvbmUgZW50cnkgaGVyZS5cbiAqL1xuXG5pbXBvcnQge1xuICAgIFRhYmxlVHlwZSxcbn0gZnJvbSAnLi4vbW9kZWwnO1xuaW1wb3J0IHtcbiAgICBUYWJsZVR5cGVCYXNlLFxuICAgIFRhYmxlVHlwZUZpZWxkcyxcbn0gZnJvbSAnLi4vdGFibGUtdHlwZSc7XG5pbXBvcnQge1xuICAgIEhpdmVQYXJxdWV0VGFibGUsXG59IGZyb20gJy4vaGl2ZS1wYXJxdWV0JztcbmltcG9ydCB7XG4gICAgSWNlYmVyZ1BhcnF1ZXRUYWJsZSxcbn0gZnJvbSAnLi9pY2ViZXJnLXBhcnF1ZXQnO1xuaW1wb3J0IHtcbiAgICBQb3N0Z3JlczE4VGFibGUsXG59IGZyb20gJy4vcG9zdGdyZXMtMTgnO1xuXG4vKiogQ29uc3RydWN0b3Igc2lnbmF0dXJlIHNoYXJlZCBieSBldmVyeSBjb25jcmV0ZSB0YWJsZSBzdWJjbGFzcy4gKi9cbnR5cGUgVGFibGVUeXBlQ29uc3RydWN0b3IgPSBuZXcgKGZpZWxkczogVGFibGVUeXBlRmllbGRzKSA9PiBUYWJsZVR5cGVCYXNlO1xuXG4vLy8gRXhoYXVzdGl2ZSBtYXA6IGV2ZXJ5IHZhbHVlIG9mIHRoZSBgVGFibGVUeXBlYCBlbnVtIGhhcyBhIGNvbmNyZXRlIHN1YmNsYXNzLlxuY29uc3QgUkVHSVNUUlk6IFJlY29yZDxUYWJsZVR5cGUsIFRhYmxlVHlwZUNvbnN0cnVjdG9yPiA9IHtcbiAgICBbVGFibGVUeXBlLkhJVkVfUEFSUVVFVF06IEhpdmVQYXJxdWV0VGFibGUsXG4gICAgW1RhYmxlVHlwZS5JQ0VCRVJHX1BBUlFVRVRdOiBJY2ViZXJnUGFycXVldFRhYmxlLFxuICAgIFtUYWJsZVR5cGUuUE9TVEdSRVNfMThdOiBQb3N0Z3JlczE4VGFibGUsXG59O1xuXG4vKipcbiAqIEJ1aWxkIHRoZSBjb25jcmV0ZSBgVGFibGVUeXBlQmFzZWAgc3ViY2xhc3MgZm9yIHRoZSBnaXZlbiBmaWVsZHMuXG4gKlxuICogQHBhcmFtIGZpZWxkcyBUaGUgbm9ybWFsaXplZCB0YWJsZSBmaWVsZHMuXG4gKiBAcmV0dXJucyBBIGNvbmNyZXRlIHRhYmxlIGluc3RhbmNlIGZvciB0aGUgZW5naW5lIG5hbWVkIGJ5IGBmaWVsZHMuZGVmaW5pdGlvbi50YWJsZVR5cGVgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVGFibGVUeXBlKGZpZWxkczogVGFibGVUeXBlRmllbGRzKTogVGFibGVUeXBlQmFzZSB7XG4gICAgY29uc3QgdGFibGVUeXBlID0gZmllbGRzLmRlZmluaXRpb24udGFibGVUeXBlIGFzIFRhYmxlVHlwZTtcbiAgICAvLy8gQW4gdW5yZWNvZ25pemVkIGB0YWJsZVR5cGVgIG9ubHkgb2NjdXJzIHdoZW4gTGF5ZXIgMSBhbHJlYWR5IGZsYWdnZWQgdGhlXG4gICAgLy8vIGZpbGU6IHN1Y2ggdGFibGVzIGFyZSBza2lwcGVkIGJ5IGludHJhLXRhYmxlIHJ1bGVzIGFuZCBza2lwcGVkIGFzIEZLXG4gICAgLy8vIHRhcmdldHMsIHNvIHRoZSBjaG9pY2UgaGVyZSBpcyBwdXJlbHkgZm9yIGNyb3NzLWZpbGUgKnJlc29sdXRpb24qICh0aGVcbiAgICAvLy8gaW5zdGFuY2Ugc3RpbGwgbmVlZHMgdG8gbGFuZCBpbiBgd29ybGQudGFibGVzYCBzbyBkZXBlbmRzT24gLyBGSyBzb3VyY2VcbiAgICAvLy8gbG9va3VwcyBkb24ndCBwcmV0ZW5kIHRoZSBmaWxlIGlzIG1pc3NpbmcpLiBgSGl2ZVBhcnF1ZXRUYWJsZWAgaXMgdGhlXG4gICAgLy8vIHJlc29sdXRpb24tb25seSBmYWxsYmFjay5cbiAgICBjb25zdCBDb25zdHJ1Y3RvciA9IFJFR0lTVFJZW3RhYmxlVHlwZV0gPz8gSGl2ZVBhcnF1ZXRUYWJsZTtcbiAgICByZXR1cm4gbmV3IENvbnN0cnVjdG9yKGZpZWxkcyk7XG59XG4iXX0=
36
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGFibGUtdHlwZXMvcmVnaXN0cnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7O0dBSUc7O0FBbUNILDBDQVVDO0FBM0NELG9DQUVrQjtBQUtsQixpREFFd0I7QUFDeEIsNkRBRThCO0FBQzlCLCtDQUV1QjtBQUt2QixnRkFBZ0Y7QUFDaEYsTUFBTSxRQUFRLEdBQTRDO0lBQ3RELENBQUMsaUJBQVMsQ0FBQyxZQUFZLENBQUMsRUFBRSwrQkFBZ0I7SUFDMUMsQ0FBQyxpQkFBUyxDQUFDLGtCQUFrQixDQUFDLEVBQUUsMENBQXFCO0lBQ3JELENBQUMsaUJBQVMsQ0FBQyxXQUFXLENBQUMsRUFBRSw2QkFBZTtDQUMzQyxDQUFDO0FBRUY7Ozs7O0dBS0c7QUFDSCxTQUFnQixlQUFlLENBQUMsTUFBdUI7SUFDbkQsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxTQUFzQixDQUFDO0lBQzNELDRFQUE0RTtJQUM1RSx3RUFBd0U7SUFDeEUsMEVBQTBFO0lBQzFFLDJFQUEyRTtJQUMzRSx5RUFBeUU7SUFDekUsNkJBQTZCO0lBQzdCLE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSSwrQkFBZ0IsQ0FBQztJQUM1RCxPQUFPLElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ25DLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFJlZ2lzdHJ5IG1hcHBpbmcgdGhlIGB0YWJsZVR5cGVgIHN0cmluZyB0byB0aGUgY29uY3JldGUgYFRhYmxlVHlwZUJhc2VgXG4gKiBzdWJjbGFzcyB0aGF0IGltcGxlbWVudHMgaXQuIEFkZGluZyBhIG5ldyBlbmdpbmUgaXMgYSBtYXR0ZXIgb2Ygd3JpdGluZyBhXG4gKiBzdWJjbGFzcyBhbmQgYWRkaW5nIG9uZSBlbnRyeSBoZXJlLlxuICovXG5cbmltcG9ydCB7XG4gICAgVGFibGVUeXBlLFxufSBmcm9tICcuLi9tb2RlbCc7XG5pbXBvcnQge1xuICAgIFRhYmxlVHlwZUJhc2UsXG4gICAgVGFibGVUeXBlRmllbGRzLFxufSBmcm9tICcuLi90YWJsZS10eXBlJztcbmltcG9ydCB7XG4gICAgSGl2ZVBhcnF1ZXRUYWJsZSxcbn0gZnJvbSAnLi9oaXZlLXBhcnF1ZXQnO1xuaW1wb3J0IHtcbiAgICBJY2ViZXJnUGFycXVldFYyVGFibGUsXG59IGZyb20gJy4vaWNlYmVyZy1wYXJxdWV0LXYyJztcbmltcG9ydCB7XG4gICAgUG9zdGdyZXMxOFRhYmxlLFxufSBmcm9tICcuL3Bvc3RncmVzLTE4JztcblxuLyoqIENvbnN0cnVjdG9yIHNpZ25hdHVyZSBzaGFyZWQgYnkgZXZlcnkgY29uY3JldGUgdGFibGUgc3ViY2xhc3MuICovXG50eXBlIFRhYmxlVHlwZUNvbnN0cnVjdG9yID0gbmV3IChmaWVsZHM6IFRhYmxlVHlwZUZpZWxkcykgPT4gVGFibGVUeXBlQmFzZTtcblxuLy8vIEV4aGF1c3RpdmUgbWFwOiBldmVyeSB2YWx1ZSBvZiB0aGUgYFRhYmxlVHlwZWAgZW51bSBoYXMgYSBjb25jcmV0ZSBzdWJjbGFzcy5cbmNvbnN0IFJFR0lTVFJZOiBSZWNvcmQ8VGFibGVUeXBlLCBUYWJsZVR5cGVDb25zdHJ1Y3Rvcj4gPSB7XG4gICAgW1RhYmxlVHlwZS5ISVZFX1BBUlFVRVRdOiBIaXZlUGFycXVldFRhYmxlLFxuICAgIFtUYWJsZVR5cGUuSUNFQkVSR19QQVJRVUVUX1YyXTogSWNlYmVyZ1BhcnF1ZXRWMlRhYmxlLFxuICAgIFtUYWJsZVR5cGUuUE9TVEdSRVNfMThdOiBQb3N0Z3JlczE4VGFibGUsXG59O1xuXG4vKipcbiAqIEJ1aWxkIHRoZSBjb25jcmV0ZSBgVGFibGVUeXBlQmFzZWAgc3ViY2xhc3MgZm9yIHRoZSBnaXZlbiBmaWVsZHMuXG4gKlxuICogQHBhcmFtIGZpZWxkcyBUaGUgbm9ybWFsaXplZCB0YWJsZSBmaWVsZHMuXG4gKiBAcmV0dXJucyBBIGNvbmNyZXRlIHRhYmxlIGluc3RhbmNlIGZvciB0aGUgZW5naW5lIG5hbWVkIGJ5IGBmaWVsZHMuZGVmaW5pdGlvbi50YWJsZVR5cGVgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVGFibGVUeXBlKGZpZWxkczogVGFibGVUeXBlRmllbGRzKTogVGFibGVUeXBlQmFzZSB7XG4gICAgY29uc3QgdGFibGVUeXBlID0gZmllbGRzLmRlZmluaXRpb24udGFibGVUeXBlIGFzIFRhYmxlVHlwZTtcbiAgICAvLy8gQW4gdW5yZWNvZ25pemVkIGB0YWJsZVR5cGVgIG9ubHkgb2NjdXJzIHdoZW4gTGF5ZXIgMSBhbHJlYWR5IGZsYWdnZWQgdGhlXG4gICAgLy8vIGZpbGU6IHN1Y2ggdGFibGVzIGFyZSBza2lwcGVkIGJ5IGludHJhLXRhYmxlIHJ1bGVzIGFuZCBza2lwcGVkIGFzIEZLXG4gICAgLy8vIHRhcmdldHMsIHNvIHRoZSBjaG9pY2UgaGVyZSBpcyBwdXJlbHkgZm9yIGNyb3NzLWZpbGUgKnJlc29sdXRpb24qICh0aGVcbiAgICAvLy8gaW5zdGFuY2Ugc3RpbGwgbmVlZHMgdG8gbGFuZCBpbiBgd29ybGQudGFibGVzYCBzbyBkZXBlbmRzT24gLyBGSyBzb3VyY2VcbiAgICAvLy8gbG9va3VwcyBkb24ndCBwcmV0ZW5kIHRoZSBmaWxlIGlzIG1pc3NpbmcpLiBgSGl2ZVBhcnF1ZXRUYWJsZWAgaXMgdGhlXG4gICAgLy8vIHJlc29sdXRpb24tb25seSBmYWxsYmFjay5cbiAgICBjb25zdCBDb25zdHJ1Y3RvciA9IFJFR0lTVFJZW3RhYmxlVHlwZV0gPz8gSGl2ZVBhcnF1ZXRUYWJsZTtcbiAgICByZXR1cm4gbmV3IENvbnN0cnVjdG9yKGZpZWxkcyk7XG59XG4iXX0=