@decaf-ts/for-couchdb 0.3.0 → 0.3.2

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.
Files changed (93) hide show
  1. package/LICENSE.md +646 -144
  2. package/README.md +371 -1
  3. package/dist/for-couchdb.cjs +907 -326
  4. package/dist/for-couchdb.esm.cjs +910 -329
  5. package/lib/adapter.cjs +249 -41
  6. package/lib/adapter.d.ts +243 -17
  7. package/lib/constants.cjs +30 -2
  8. package/lib/constants.d.ts +28 -0
  9. package/lib/errors.cjs +19 -2
  10. package/lib/errors.d.ts +17 -0
  11. package/lib/esm/adapter.d.ts +243 -17
  12. package/lib/esm/adapter.js +249 -41
  13. package/lib/esm/constants.d.ts +28 -0
  14. package/lib/esm/constants.js +30 -2
  15. package/lib/esm/errors.d.ts +17 -0
  16. package/lib/esm/errors.js +19 -2
  17. package/lib/esm/index.d.ts +6 -13
  18. package/lib/esm/index.js +7 -14
  19. package/lib/esm/indexes/generator.d.ts +47 -0
  20. package/lib/esm/indexes/generator.js +58 -1
  21. package/lib/esm/interfaces/CouchDBRepository.d.ts +10 -0
  22. package/lib/esm/interfaces/CouchDBRepository.js +1 -1
  23. package/lib/esm/model/CouchDBSequence.d.ts +15 -9
  24. package/lib/esm/model/CouchDBSequence.js +12 -1
  25. package/lib/esm/query/Paginator.d.ts +117 -4
  26. package/lib/esm/query/Paginator.js +128 -23
  27. package/lib/esm/query/Statement.d.ts +141 -8
  28. package/lib/esm/query/Statement.js +256 -28
  29. package/lib/esm/query/constants.d.ts +43 -0
  30. package/lib/esm/query/constants.js +44 -1
  31. package/lib/esm/query/index.d.ts +4 -1
  32. package/lib/esm/query/index.js +5 -2
  33. package/lib/esm/query/translate.d.ts +31 -0
  34. package/lib/esm/query/translate.js +32 -1
  35. package/lib/esm/sequences/Sequence.d.ts +0 -2
  36. package/lib/esm/sequences/Sequence.js +5 -9
  37. package/lib/esm/types.d.ts +55 -12
  38. package/lib/esm/types.js +1 -1
  39. package/lib/esm/utils.d.ts +105 -0
  40. package/lib/esm/utils.js +106 -1
  41. package/lib/index.cjs +7 -14
  42. package/lib/index.d.ts +6 -13
  43. package/lib/indexes/generator.cjs +58 -1
  44. package/lib/indexes/generator.d.ts +47 -0
  45. package/lib/interfaces/CouchDBRepository.cjs +1 -1
  46. package/lib/interfaces/CouchDBRepository.d.ts +10 -0
  47. package/lib/model/CouchDBSequence.cjs +12 -1
  48. package/lib/model/CouchDBSequence.d.ts +15 -9
  49. package/lib/query/Paginator.cjs +126 -21
  50. package/lib/query/Paginator.d.ts +117 -4
  51. package/lib/query/Statement.cjs +255 -27
  52. package/lib/query/Statement.d.ts +141 -8
  53. package/lib/query/constants.cjs +45 -2
  54. package/lib/query/constants.d.ts +43 -0
  55. package/lib/query/index.cjs +5 -2
  56. package/lib/query/index.d.ts +4 -1
  57. package/lib/query/translate.cjs +32 -1
  58. package/lib/query/translate.d.ts +31 -0
  59. package/lib/sequences/Sequence.cjs +5 -9
  60. package/lib/sequences/Sequence.d.ts +0 -2
  61. package/lib/types.cjs +1 -1
  62. package/lib/types.d.ts +55 -12
  63. package/lib/utils.cjs +106 -1
  64. package/lib/utils.d.ts +105 -0
  65. package/package.json +2 -2
  66. package/lib/esm/query/FromClause.d.ts +0 -7
  67. package/lib/esm/query/FromClause.js +0 -20
  68. package/lib/esm/query/InsertClause.d.ts +0 -7
  69. package/lib/esm/query/InsertClause.js +0 -13
  70. package/lib/esm/query/SelectClause.d.ts +0 -7
  71. package/lib/esm/query/SelectClause.js +0 -16
  72. package/lib/esm/query/ValuesClause.d.ts +0 -7
  73. package/lib/esm/query/ValuesClause.js +0 -12
  74. package/lib/esm/query/WhereClause.d.ts +0 -7
  75. package/lib/esm/query/WhereClause.js +0 -57
  76. package/lib/esm/query/factory.d.ts +0 -25
  77. package/lib/esm/query/factory.js +0 -117
  78. package/lib/esm/sequences/utils.d.ts +0 -1
  79. package/lib/esm/sequences/utils.js +0 -16
  80. package/lib/query/FromClause.cjs +0 -24
  81. package/lib/query/FromClause.d.ts +0 -7
  82. package/lib/query/InsertClause.cjs +0 -17
  83. package/lib/query/InsertClause.d.ts +0 -7
  84. package/lib/query/SelectClause.cjs +0 -20
  85. package/lib/query/SelectClause.d.ts +0 -7
  86. package/lib/query/ValuesClause.cjs +0 -16
  87. package/lib/query/ValuesClause.d.ts +0 -7
  88. package/lib/query/WhereClause.cjs +0 -61
  89. package/lib/query/WhereClause.d.ts +0 -7
  90. package/lib/query/factory.cjs +0 -121
  91. package/lib/query/factory.d.ts +0 -25
  92. package/lib/sequences/utils.cjs +0 -19
  93. package/lib/sequences/utils.d.ts +0 -1
@@ -1,12 +1,40 @@
1
- import { Repository, PersistenceKeys, pk, index, table, BaseModel, Sequence as Sequence$1, Paginator, PagingError, Statement, FromClause, InsertClause, WhereClause, Condition, SelectClause, Const, ValuesClause, ClauseFactory, GroupByClause, LimitClause, OffsetClause, QueryError, OrderByClause, Adapter, GroupOperator, Operator, ConnectionError } from '@decaf-ts/core';
2
- import { DefaultSeparator, InternalError, NotFoundError, findPrimaryKey, BaseError, prefixMethod, ConflictError } from '@decaf-ts/db-decorators';
1
+ import { Repository, PersistenceKeys, pk, index, table, BaseModel, Sequence as Sequence$1, Paginator, PagingError, QueryError, Statement, Condition, GroupOperator, Operator, final, Adapter, ConnectionError } from '@decaf-ts/core';
2
+ import { DefaultSeparator, NotFoundError, InternalError, BaseError, findPrimaryKey, prefixMethod, ConflictError } from '@decaf-ts/db-decorators';
3
3
  import { __decorate, __metadata } from 'tslib';
4
- import { required, model, sf } from '@decaf-ts/decorator-validation';
4
+ import { required, model } from '@decaf-ts/decorator-validation';
5
5
  import 'reflect-metadata';
6
6
 
7
+ /**
8
+ * @description Regular expression to identify reserved attributes in CouchDB
9
+ * @summary Matches any attribute that starts with an underscore
10
+ * @const reservedAttributes
11
+ * @memberOf module:for-couchdb
12
+ */
7
13
  const reservedAttributes = /^_.*$/g;
14
+ /**
15
+ * @description Key constants used in CouchDB operations
16
+ * @summary Collection of string constants for CouchDB document properties and operations
17
+ * @typedef {Object} CouchDBKeysType
18
+ * @property {string} SEPARATOR - Separator used for combining table name and ID
19
+ * @property {string} ID - CouchDB document ID field
20
+ * @property {string} REV - CouchDB document revision field
21
+ * @property {string} DELETED - CouchDB deleted document marker
22
+ * @property {string} TABLE - Table name marker
23
+ * @property {string} SEQUENCE - Sequence marker
24
+ * @property {string} DDOC - Design document marker
25
+ * @property {string} NATIVE - Native marker
26
+ * @property {string} INDEX - Index marker
27
+ * @memberOf module:for-couchdb
28
+ */
29
+ /**
30
+ * @description Key constants used in CouchDB operations
31
+ * @summary Collection of string constants for CouchDB document properties and operations
32
+ * @const CouchDBKeys
33
+ * @type {CouchDBKeysType}
34
+ * @memberOf module:for-couchdb
35
+ */
8
36
  const CouchDBKeys = {
9
- SEPARATOR: "_",
37
+ SEPARATOR: "__",
10
38
  ID: "_id",
11
39
  REV: "_rev",
12
40
  DELETED: "_deleted",
@@ -17,6 +45,30 @@ const CouchDBKeys = {
17
45
  INDEX: "index",
18
46
  };
19
47
 
48
+ /**
49
+ * @description Default query limit for CouchDB queries
50
+ * @summary Maximum number of documents to return in a single query
51
+ * @const CouchDBQueryLimit
52
+ * @memberOf module:for-couchdb
53
+ */
54
+ const CouchDBQueryLimit = 250;
55
+ /**
56
+ * @description Mapping of operator names to CouchDB Mango query operators
57
+ * @summary Constants for CouchDB comparison operators used in Mango queries
58
+ * @typedef {Object} CouchDBOperatorType
59
+ * @property {string} EQUAL - Equality operator ($eq)
60
+ * @property {string} DIFFERENT - Inequality operator ($ne)
61
+ * @property {string} BIGGER - Greater than operator ($gt)
62
+ * @property {string} BIGGER_EQ - Greater than or equal operator ($gte)
63
+ * @property {string} SMALLER - Less than operator ($lt)
64
+ * @property {string} SMALLER_EQ - Less than or equal operator ($lte)
65
+ * @property {string} NOT - Negation operator ($not)
66
+ * @property {string} IN - In array operator ($in)
67
+ * @property {string} REGEXP - Regular expression operator ($regex)
68
+ * @const CouchDBOperator
69
+ * @type {CouchDBOperatorType}
70
+ * @memberOf module:for-couchdb
71
+ */
20
72
  const CouchDBOperator = {
21
73
  EQUAL: "$eq",
22
74
  DIFFERENT: "$ne",
@@ -30,11 +82,31 @@ const CouchDBOperator = {
30
82
  // IS = "IS",
31
83
  REGEXP: "$regex",
32
84
  };
85
+ /**
86
+ * @description Mapping of logical operator names to CouchDB Mango query operators
87
+ * @summary Constants for CouchDB logical operators used in Mango queries
88
+ * @typedef {Object} CouchDBGroupOperatorType
89
+ * @property {string} AND - Logical AND operator ($and)
90
+ * @property {string} OR - Logical OR operator ($or)
91
+ * @const CouchDBGroupOperator
92
+ * @type {CouchDBGroupOperatorType}
93
+ * @memberOf module:for-couchdb
94
+ */
33
95
  const CouchDBGroupOperator = {
34
96
  AND: "$and",
35
97
  OR: "$or",
36
98
  };
37
99
 
100
+ /**
101
+ * @description Generates a name for a CouchDB index
102
+ * @summary Creates a standardized name for a CouchDB index by combining name parts, compositions, and direction
103
+ * @param {string[]} name - Array of name parts for the index
104
+ * @param {OrderDirection} [direction] - Optional sort direction for the index
105
+ * @param {string[]} [compositions] - Optional additional attributes to include in the index name
106
+ * @param {string} [separator=DefaultSeparator] - The separator to use between parts of the index name
107
+ * @return {string} The generated index name
108
+ * @memberOf module:for-couchdb
109
+ */
38
110
  function generateIndexName$1(name, direction, compositions, separator = DefaultSeparator) {
39
111
  return [
40
112
  ...name.map((n) => (n === CouchDBKeys.TABLE ? "table" : n)),
@@ -43,6 +115,53 @@ function generateIndexName$1(name, direction, compositions, separator = DefaultS
43
115
  CouchDBKeys.INDEX,
44
116
  ].join(separator);
45
117
  }
118
+ /**
119
+ * @description Generates CouchDB index configurations for models
120
+ * @summary Creates a set of CouchDB index configurations based on the metadata of the provided models
121
+ * @template M - The model type that extends Model
122
+ * @param models - Array of model constructors to generate indexes for
123
+ * @return {CreateIndexRequest[]} Array of CouchDB index configurations
124
+ * @function generateIndexes
125
+ * @memberOf module:for-couchdb
126
+ * @mermaid
127
+ * sequenceDiagram
128
+ * participant Caller
129
+ * participant generateIndexes
130
+ * participant generateIndexName
131
+ * participant Repository
132
+ *
133
+ * Caller->>generateIndexes: models
134
+ *
135
+ * Note over generateIndexes: Create base table index
136
+ * generateIndexes->>generateIndexName: [CouchDBKeys.TABLE]
137
+ * generateIndexName-->>generateIndexes: tableName
138
+ * generateIndexes->>generateIndexes: Create table index config
139
+ *
140
+ * loop For each model
141
+ * generateIndexes->>Repository: Get indexes metadata
142
+ * Repository-->>generateIndexes: index metadata
143
+ *
144
+ * loop For each index in metadata
145
+ * Note over generateIndexes: Extract index properties
146
+ * generateIndexes->>Repository: Get table name
147
+ * Repository-->>generateIndexes: tableName
148
+ *
149
+ * Note over generateIndexes: Define nested generate function
150
+ *
151
+ * generateIndexes->>generateIndexes: Call generate() for default order
152
+ * Note over generateIndexes: Create index name and config
153
+ *
154
+ * alt Has directions
155
+ * loop For each direction
156
+ * generateIndexes->>generateIndexes: Call generate(direction)
157
+ * Note over generateIndexes: Create ordered index config
158
+ * end
159
+ * end
160
+ * end
161
+ * end
162
+ *
163
+ * generateIndexes-->>Caller: Array of index configurations
164
+ */
46
165
  function generateIndexes(models) {
47
166
  const tableName = generateIndexName$1([CouchDBKeys.TABLE]);
48
167
  const indexes = {};
@@ -102,6 +221,17 @@ function generateIndexes(models) {
102
221
  return Object.values(indexes);
103
222
  }
104
223
 
224
+ /**
225
+ * @description Model for CouchDB sequence records
226
+ * @summary Represents a sequence in CouchDB used for generating sequential IDs
227
+ * @param {ModelArg<Sequence>} [seq] - Optional initialization data for the sequence
228
+ * @class
229
+ * @example
230
+ * // Example of creating and using a Sequence
231
+ * const sequence = new Sequence({ id: 'user-seq', current: 1 });
232
+ * // Increment the sequence
233
+ * sequence.current = Number(sequence.current) + 1;
234
+ */
105
235
  let Sequence = class Sequence extends BaseModel {
106
236
  constructor(seq) {
107
237
  super(seq);
@@ -122,21 +252,6 @@ Sequence = __decorate([
122
252
  __metadata("design:paramtypes", [Object])
123
253
  ], Sequence);
124
254
 
125
- function parseSequenceValue(type, value) {
126
- switch (type) {
127
- case "Number":
128
- return typeof value === "string"
129
- ? parseInt(value)
130
- : typeof value === "number"
131
- ? value
132
- : BigInt(value);
133
- case "BigInt":
134
- return BigInt(value);
135
- default:
136
- throw new InternalError("Should never happen");
137
- }
138
- }
139
-
140
255
  /**
141
256
  * @summary Abstract implementation of a Sequence
142
257
  * @description provides the basic functionality for {@link Sequence}s
@@ -145,13 +260,11 @@ function parseSequenceValue(type, value) {
145
260
  *
146
261
  * @class CouchDBSequence
147
262
  * @implements Sequence
148
- *
149
- * @category Sequences
150
263
  */
151
264
  class CouchDBSequence extends Sequence$1 {
152
265
  constructor(options, adapter) {
153
266
  super(options);
154
- this.repo = Repository.forModel(Sequence, adapter.flavour);
267
+ this.repo = Repository.forModel(Sequence, adapter.alias);
155
268
  }
156
269
  /**
157
270
  * @summary Retrieves the current value for the sequence
@@ -171,10 +284,10 @@ class CouchDBSequence extends Sequence$1 {
171
284
  return this.parse(startWith);
172
285
  }
173
286
  catch (e) {
174
- throw new InternalError(sf("Failed to parse initial value for sequence {0}: {1}", startWith.toString(), e));
287
+ throw new InternalError(`Failed to parse initial value for sequence ${startWith}: ${e}`);
175
288
  }
176
289
  }
177
- throw new InternalError(sf("Failed to retrieve current value for sequence {0}: {1}", name, e));
290
+ throw new InternalError(`Failed to retrieve current value for sequence ${name}: ${e}`);
178
291
  }
179
292
  }
180
293
  /**
@@ -184,7 +297,7 @@ class CouchDBSequence extends Sequence$1 {
184
297
  * @param value
185
298
  */
186
299
  parse(value) {
187
- return parseSequenceValue(this.options.type, value);
300
+ return Sequence$1.parseValue(this.options.type, value);
188
301
  }
189
302
  /**
190
303
  * @summary increments the sequence
@@ -245,16 +358,87 @@ class CouchDBSequence extends Sequence$1 {
245
358
  }
246
359
  }
247
360
 
361
+ /**
362
+ * @description Error thrown when there is an issue with CouchDB indexes
363
+ * @summary Represents an error related to CouchDB index operations
364
+ * @param {string|Error} msg - The error message or Error object
365
+ * @class
366
+ * @category Errors
367
+ * @example
368
+ * // Example of using IndexError
369
+ * try {
370
+ * // Some code that might throw an index error
371
+ * throw new IndexError("Index not found");
372
+ * } catch (error) {
373
+ * if (error instanceof IndexError) {
374
+ * console.error("Index error occurred:", error.message);
375
+ * }
376
+ * }
377
+ */
378
+ class IndexError extends BaseError {
379
+ constructor(msg) {
380
+ super(IndexError.name, msg, 404);
381
+ }
382
+ }
383
+
384
+ /**
385
+ * @description Paginator for CouchDB query results
386
+ * @summary Implements pagination for CouchDB queries using bookmarks for efficient navigation through result sets
387
+ * @template M - The model type that extends Model
388
+ * @template R - The result type
389
+ * @param {CouchDBAdapter<any, any, any>} adapter - The CouchDB adapter
390
+ * @param {MangoQuery} query - The Mango query to paginate
391
+ * @param {number} size - The page size
392
+ * @param {Constructor<M>} clazz - The model constructor
393
+ * @class CouchDBPaginator
394
+ * @example
395
+ * // Example of using CouchDBPaginator
396
+ * const adapter = new MyCouchDBAdapter(scope);
397
+ * const query = { selector: { type: "user" } };
398
+ * const paginator = new CouchDBPaginator(adapter, query, 10, User);
399
+ *
400
+ * // Get the first page
401
+ * const page1 = await paginator.page(1);
402
+ *
403
+ * // Get the next page
404
+ * const page2 = await paginator.page(2);
405
+ */
248
406
  class CouchDBPaginator extends Paginator {
407
+ /**
408
+ * @description Gets the total number of pages
409
+ * @summary Not supported in CouchDB - throws an error when accessed
410
+ * @return {number} Never returns as it throws an error
411
+ * @throws {InternalError} Always throws as this functionality is not available in CouchDB
412
+ */
249
413
  get total() {
250
414
  throw new InternalError(`The total pages api is not available for couchdb`);
251
415
  }
416
+ /**
417
+ * @description Gets the total record count
418
+ * @summary Not supported in CouchDB - throws an error when accessed
419
+ * @return {number} Never returns as it throws an error
420
+ * @throws {InternalError} Always throws as this functionality is not available in CouchDB
421
+ */
252
422
  get count() {
253
423
  throw new InternalError(`The record count api is not available for couchdb`);
254
424
  }
255
- constructor(statement, size, rawStatement) {
256
- super(statement, size, rawStatement);
425
+ /**
426
+ * @description Creates a new CouchDBPaginator instance
427
+ * @summary Initializes a paginator for CouchDB query results
428
+ * @param {CouchDBAdapter<any, any, any>} adapter - The CouchDB adapter
429
+ * @param {MangoQuery} query - The Mango query to paginate
430
+ * @param {number} size - The page size
431
+ * @param {Constructor<M>} clazz - The model constructor
432
+ */
433
+ constructor(adapter, query, size, clazz) {
434
+ super(adapter, query, size, clazz);
257
435
  }
436
+ /**
437
+ * @description Prepares a query for pagination
438
+ * @summary Modifies the raw query to include pagination parameters
439
+ * @param {MangoQuery} rawStatement - The original Mango query
440
+ * @return {MangoQuery} The prepared query with pagination parameters
441
+ */
258
442
  prepare(rawStatement) {
259
443
  const query = Object.assign({}, rawStatement);
260
444
  if (query.limit)
@@ -262,39 +446,96 @@ class CouchDBPaginator extends Paginator {
262
446
  query.limit = this.size;
263
447
  return query;
264
448
  }
265
- async page(page = 1, ...args) {
449
+ /**
450
+ * @description Retrieves a specific page of results
451
+ * @summary Executes the query with pagination and processes the results
452
+ * @param {number} [page=1] - The page number to retrieve
453
+ * @return {Promise<R[]>} A promise that resolves to an array of results
454
+ * @throws {PagingError} If trying to access a page other than the first without a bookmark, or if no class is defined
455
+ * @mermaid
456
+ * sequenceDiagram
457
+ * participant Client
458
+ * participant CouchDBPaginator
459
+ * participant Adapter
460
+ * participant CouchDB
461
+ *
462
+ * Client->>CouchDBPaginator: page(pageNumber)
463
+ * Note over CouchDBPaginator: Clone statement
464
+ * CouchDBPaginator->>CouchDBPaginator: validatePage(page)
465
+ *
466
+ * alt page !== 1
467
+ * CouchDBPaginator->>CouchDBPaginator: Check bookmark
468
+ * alt No bookmark
469
+ * CouchDBPaginator-->>Client: Throw PagingError
470
+ * else Has bookmark
471
+ * CouchDBPaginator->>CouchDBPaginator: Add bookmark to statement
472
+ * end
473
+ * end
474
+ *
475
+ * CouchDBPaginator->>Adapter: raw(statement, false)
476
+ * Adapter->>CouchDB: Execute query
477
+ * CouchDB-->>Adapter: Return results
478
+ * Adapter-->>CouchDBPaginator: Return MangoResponse
479
+ *
480
+ * Note over CouchDBPaginator: Process results
481
+ *
482
+ * alt Has warning
483
+ * CouchDBPaginator->>CouchDBPaginator: Log warning
484
+ * end
485
+ *
486
+ * CouchDBPaginator->>CouchDBPaginator: Check for clazz
487
+ *
488
+ * alt No clazz
489
+ * CouchDBPaginator-->>Client: Throw PagingError
490
+ * else Has clazz
491
+ * CouchDBPaginator->>CouchDBPaginator: Find primary key
492
+ *
493
+ * alt Has fields in statement
494
+ * CouchDBPaginator->>CouchDBPaginator: Use docs directly
495
+ * else No fields
496
+ * CouchDBPaginator->>CouchDBPaginator: Process each document
497
+ * loop For each document
498
+ * CouchDBPaginator->>CouchDBPaginator: Extract original ID
499
+ * CouchDBPaginator->>Adapter: revert(doc, clazz, pkDef.id, parsedId)
500
+ * end
501
+ * end
502
+ *
503
+ * CouchDBPaginator->>CouchDBPaginator: Store bookmark
504
+ * CouchDBPaginator->>CouchDBPaginator: Update currentPage
505
+ * CouchDBPaginator-->>Client: Return results
506
+ * end
507
+ */
508
+ async page(page = 1) {
266
509
  const statement = Object.assign({}, this.statement);
267
- const target = this.stat.getTarget();
268
- // if (!this._recordCount || !this._totalPages) {
269
- // // this._recordCount = await this.adapter
270
- // // .Query()
271
- // // .count()
272
- // // .from(target)
273
- // // .execute<number>();
274
- // }
510
+ if (!this._recordCount || !this._totalPages) {
511
+ this._totalPages = this._recordCount = 0;
512
+ const results = await this.adapter.raw({ ...statement, limit: undefined }) || [];
513
+ this._recordCount = results.length;
514
+ if (this._recordCount > 0) {
515
+ const size = statement?.limit || this.size;
516
+ this._totalPages = Math.ceil(this._recordCount / size);
517
+ }
518
+ }
275
519
  this.validatePage(page);
276
520
  if (page !== 1) {
277
521
  if (!this.bookMark)
278
522
  throw new PagingError("No bookmark. Did you start in the first page?");
279
523
  statement["bookmark"] = this.bookMark;
280
524
  }
281
- const rawResult = await this.adapter.raw(statement, false, ...args);
525
+ const rawResult = await this.adapter.raw(statement, false);
282
526
  const { docs, bookmark, warning } = rawResult;
283
527
  if (warning)
284
528
  console.warn(warning);
285
- if (!target)
529
+ if (!this.clazz)
286
530
  throw new PagingError("No statement target defined");
287
- const pkDef = findPrimaryKey(new target());
531
+ const pkDef = findPrimaryKey(new this.clazz());
288
532
  const results = statement.fields && statement.fields.length
289
533
  ? docs // has fields means its not full model
290
534
  : docs.map((d) => {
291
535
  //no fields means we need to revert to saving process
292
- if (!target)
293
- throw new PagingError("No statement target defined");
294
- const pk = pkDef.id;
295
- const originalId = d._id.split(DefaultSeparator);
536
+ const originalId = d._id.split(CouchDBKeys.SEPARATOR);
296
537
  originalId.splice(0, 1); // remove the table name
297
- return this.adapter.revert(d, target, pk, parseSequenceValue(pkDef.props.type, originalId.join(DefaultSeparator)));
538
+ return this.adapter.revert(d, this.clazz, pkDef.id, Sequence$1.parseValue(pkDef.props.type, originalId.join(CouchDBKeys.SEPARATOR)));
298
539
  });
299
540
  this.bookMark = bookmark;
300
541
  this._currentPage = page;
@@ -302,300 +543,296 @@ class CouchDBPaginator extends Paginator {
302
543
  }
303
544
  }
304
545
 
546
+ /**
547
+ * @description Translates core operators to CouchDB Mango operators
548
+ * @summary Converts Decaf.ts core operators to their equivalent CouchDB Mango query operators
549
+ * @param {GroupOperator | Operator} operator - The core operator to translate
550
+ * @return {MangoOperator} The equivalent CouchDB Mango operator
551
+ * @throws {QueryError} If no translation exists for the given operator
552
+ * @function translateOperators
553
+ * @memberOf module:for-couchdb
554
+ * @mermaid
555
+ * sequenceDiagram
556
+ * participant Caller
557
+ * participant translateOperators
558
+ * participant CouchDBOperator
559
+ * participant CouchDBGroupOperator
560
+ *
561
+ * Caller->>translateOperators: operator
562
+ *
563
+ * translateOperators->>CouchDBOperator: Check for match
564
+ * alt Found in CouchDBOperator
565
+ * CouchDBOperator-->>translateOperators: Return matching operator
566
+ * translateOperators-->>Caller: Return MangoOperator
567
+ * else Not found
568
+ * translateOperators->>CouchDBGroupOperator: Check for match
569
+ * alt Found in CouchDBGroupOperator
570
+ * CouchDBGroupOperator-->>translateOperators: Return matching operator
571
+ * translateOperators-->>Caller: Return MangoOperator
572
+ * else Not found
573
+ * translateOperators-->>Caller: Throw QueryError
574
+ * end
575
+ * end
576
+ */
577
+ function translateOperators(operator) {
578
+ for (const operators of [CouchDBOperator, CouchDBGroupOperator]) {
579
+ const el = Object.keys(operators).find((k) => k === operator);
580
+ if (el)
581
+ return operators[el];
582
+ }
583
+ throw new QueryError(`Could not find adapter translation for operator ${operator}`);
584
+ }
585
+
586
+ /**
587
+ * @description Statement builder for CouchDB Mango queries
588
+ * @summary Provides a fluent interface for building CouchDB Mango queries with type safety
589
+ * @template M - The model type that extends Model
590
+ * @template R - The result type
591
+ * @param adapter - The CouchDB adapter
592
+ * @class CouchDBStatement
593
+ * @example
594
+ * // Example of using CouchDBStatement
595
+ * const adapter = new MyCouchDBAdapter(scope);
596
+ * const statement = new CouchDBStatement<User, User[]>(adapter);
597
+ *
598
+ * // Build a query
599
+ * const users = await statement
600
+ * .from(User)
601
+ * .where(Condition.attribute<User>('age').gt(18))
602
+ * .orderBy('lastName', 'asc')
603
+ * .limit(10)
604
+ * .execute();
605
+ */
305
606
  class CouchDBStatement extends Statement {
306
607
  constructor(adapter) {
307
608
  super(adapter);
308
609
  }
309
610
  /**
310
- * @inheritDoc
611
+ * @description Builds a CouchDB Mango query from the statement
612
+ * @summary Converts the statement's conditions, selectors, and options into a CouchDB Mango query
613
+ * @return {MangoQuery} The built Mango query
614
+ * @throws {Error} If there are invalid query conditions
615
+ * @mermaid
616
+ * sequenceDiagram
617
+ * participant Statement
618
+ * participant Repository
619
+ * participant parseCondition
620
+ *
621
+ * Statement->>Statement: build()
622
+ * Note over Statement: Initialize selectors
623
+ * Statement->>Repository: Get table name
624
+ * Repository-->>Statement: Return table name
625
+ * Statement->>Statement: Create base query
626
+ *
627
+ * alt Has selectSelector
628
+ * Statement->>Statement: Add fields to query
629
+ * end
630
+ *
631
+ * alt Has whereCondition
632
+ * Statement->>Statement: Create combined condition with table
633
+ * Statement->>parseCondition: Parse condition
634
+ * parseCondition-->>Statement: Return parsed condition
635
+ *
636
+ * alt Is group operator
637
+ * alt Is AND operator
638
+ * Statement->>Statement: Flatten nested AND conditions
639
+ * else Is OR operator
640
+ * Statement->>Statement: Combine with table condition
641
+ * else
642
+ * Statement->>Statement: Throw error
643
+ * end
644
+ * else
645
+ * Statement->>Statement: Merge conditions with existing selector
646
+ * end
647
+ * end
648
+ *
649
+ * alt Has orderBySelector
650
+ * Statement->>Statement: Add sort to query
651
+ * Statement->>Statement: Ensure field exists in selector
652
+ * end
653
+ *
654
+ * alt Has limitSelector
655
+ * Statement->>Statement: Set limit
656
+ * else
657
+ * Statement->>Statement: Use default limit
658
+ * end
659
+ *
660
+ * alt Has offsetSelector
661
+ * Statement->>Statement: Set skip
662
+ * end
663
+ *
664
+ * Statement-->>Statement: Return query
311
665
  */
312
- async execute() {
313
- try {
314
- const query = this.build();
315
- if (!query.limit)
316
- query.limit = Number.MAX_SAFE_INTEGER;
317
- return this.raw(query);
666
+ build() {
667
+ const selectors = {};
668
+ selectors[CouchDBKeys.TABLE] = {};
669
+ selectors[CouchDBKeys.TABLE] = Repository.table(this.fromSelector);
670
+ const query = { selector: selectors };
671
+ if (this.selectSelector)
672
+ query.fields = this.selectSelector;
673
+ if (this.whereCondition) {
674
+ const condition = this.parseCondition(Condition.and(this.whereCondition, Condition.attribute(CouchDBKeys.TABLE).eq(query.selector[CouchDBKeys.TABLE]))).selector;
675
+ const selectorKeys = Object.keys(condition);
676
+ if (selectorKeys.length === 1 &&
677
+ Object.values(CouchDBGroupOperator).indexOf(selectorKeys[0]) !== -1)
678
+ switch (selectorKeys[0]) {
679
+ case CouchDBGroupOperator.AND:
680
+ condition[CouchDBGroupOperator.AND] = [
681
+ ...Object.values(condition[CouchDBGroupOperator.AND]).reduce((accum, val) => {
682
+ const keys = Object.keys(val);
683
+ if (keys.length !== 1)
684
+ throw new Error("Too many keys in query selector. should be one");
685
+ const k = keys[0];
686
+ if (k === CouchDBGroupOperator.AND)
687
+ accum.push(...val[k]);
688
+ else
689
+ accum.push(val);
690
+ return accum;
691
+ }, []),
692
+ ];
693
+ query.selector = condition;
694
+ break;
695
+ case CouchDBGroupOperator.OR: {
696
+ const s = {};
697
+ s[CouchDBGroupOperator.AND] = [
698
+ condition,
699
+ ...Object.entries(query.selector).map(([key, val]) => {
700
+ const result = {};
701
+ result[key] = val;
702
+ return result;
703
+ }),
704
+ ];
705
+ query.selector = s;
706
+ break;
707
+ }
708
+ default:
709
+ throw new Error("This should be impossible");
710
+ }
711
+ else {
712
+ Object.entries(condition).forEach(([key, val]) => {
713
+ if (query.selector[key])
714
+ console.warn(`A ${key} query param is about to be overridden: ${query.selector[key]} by ${val}`);
715
+ query.selector[key] = val;
716
+ });
717
+ }
318
718
  }
319
- catch (e) {
320
- throw new InternalError(e);
719
+ if (this.orderBySelector) {
720
+ query.sort = query.sort || [];
721
+ query.selector = query.selector || {};
722
+ const [selector, value] = this.orderBySelector;
723
+ const rec = {};
724
+ rec[selector] = value;
725
+ query.sort.push(rec);
726
+ if (!query.selector[selector]) {
727
+ query.selector[selector] = {};
728
+ query.selector[selector][CouchDBOperator.BIGGER] =
729
+ null;
730
+ }
321
731
  }
732
+ if (this.limitSelector) {
733
+ query.limit = this.limitSelector;
734
+ }
735
+ else {
736
+ console.warn(`No limit selector defined. Using default couchdb limit of ${CouchDBQueryLimit}`);
737
+ query.limit = CouchDBQueryLimit;
738
+ }
739
+ if (this.offsetSelector)
740
+ query.skip = this.offsetSelector;
741
+ return query;
322
742
  }
743
+ /**
744
+ * @description Creates a paginator for the statement
745
+ * @summary Builds the query and returns a CouchDBPaginator for paginated results
746
+ * @template R - The result type
747
+ * @param {number} size - The page size
748
+ * @return {Promise<Paginator<M, R, MangoQuery>>} A promise that resolves to a paginator
749
+ * @throws {InternalError} If there's an error building the query
750
+ */
323
751
  async paginate(size) {
324
752
  try {
325
753
  const query = this.build();
326
- return new CouchDBPaginator(this, size, query);
754
+ return new CouchDBPaginator(this.adapter, query, size, this.fromSelector);
327
755
  }
328
756
  catch (e) {
329
757
  throw new InternalError(e);
330
758
  }
331
759
  }
760
+ /**
761
+ * @description Processes a record from CouchDB
762
+ * @summary Extracts the ID from a CouchDB document and reverts it to a model instance
763
+ * @param {any} r - The raw record from CouchDB
764
+ * @param pkAttr - The primary key attribute of the model
765
+ * @param {"Number" | "BigInt" | undefined} sequenceType - The type of the sequence
766
+ * @return {any} The processed record
767
+ */
332
768
  processRecord(r, pkAttr, sequenceType) {
333
- if (!r[CouchDBKeys.ID])
334
- throw new InternalError(`No CouchDB Id definition found. Should not be possible`);
335
- const [, ...keyArgs] = r[CouchDBKeys.ID].split("_");
336
- const id = keyArgs.join("_");
337
- return this.adapter.revert(r, this.target, pkAttr, parseSequenceValue(sequenceType, id));
338
- }
339
- async raw(rawInput, ...args) {
340
- const results = await this.adapter.raw(rawInput, true, ...args);
341
- if (!this.fullRecord)
342
- return results;
343
- if (!this.target)
344
- throw new InternalError("No target defined in statement. should never happen");
345
- const pkDef = findPrimaryKey(new this.target());
769
+ if (r[CouchDBKeys.ID]) {
770
+ const [, ...keyArgs] = r[CouchDBKeys.ID].split(CouchDBKeys.SEPARATOR);
771
+ const id = keyArgs.join("_");
772
+ return this.adapter.revert(r, this.fromSelector, pkAttr, Sequence$1.parseValue(sequenceType, id));
773
+ }
774
+ return r;
775
+ }
776
+ /**
777
+ * @description Executes a raw Mango query
778
+ * @summary Sends a raw Mango query to CouchDB and processes the results
779
+ * @template R - The result type
780
+ * @param {MangoQuery} rawInput - The raw Mango query to execute
781
+ * @return {Promise<R>} A promise that resolves to the query results
782
+ */
783
+ async raw(rawInput) {
784
+ const results = await this.adapter.raw(rawInput, true);
785
+ const pkDef = findPrimaryKey(new this.fromSelector());
346
786
  const pkAttr = pkDef.id;
347
787
  const type = pkDef.props.type;
348
- if (Array.isArray(results))
788
+ if (!this.selectSelector)
349
789
  return results.map((r) => this.processRecord(r, pkAttr, type));
350
- return this.processRecord(results, pkAttr, type);
351
- }
352
- }
353
-
354
- // noinspection JSAnnotator
355
- class CouchDBFromClause extends FromClause {
356
- constructor(clause) {
357
- super(clause);
358
- }
359
- build(previous) {
360
- const selectors = {};
361
- selectors[CouchDBKeys.TABLE] = {};
362
- selectors[CouchDBKeys.TABLE] =
363
- typeof this.selector === "string"
364
- ? this.selector
365
- : Repository.table(this.selector);
366
- previous.selector = selectors;
367
- return previous;
368
- }
369
- }
370
-
371
- // noinspection JSAnnotator
372
- class CouchDBInsertClause extends InsertClause {
373
- constructor(clause) {
374
- super(clause);
375
- }
376
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
377
- build(query) {
378
- throw new InternalError("Not supported");
379
- }
380
- }
381
-
382
- class CouchDBWhereClause extends WhereClause {
383
- constructor(clause) {
384
- super(clause);
385
- }
386
- build(query) {
387
- const condition = this.adapter.parseCondition(Condition.and(this.condition, Condition.attribute(CouchDBKeys.TABLE).eq(query.selector[CouchDBKeys.TABLE]))).selector;
388
- const selectorKeys = Object.keys(condition);
389
- if (selectorKeys.length === 1 &&
390
- Object.values(CouchDBGroupOperator).indexOf(selectorKeys[0]) !== -1)
391
- switch (selectorKeys[0]) {
392
- case CouchDBGroupOperator.AND:
393
- condition[CouchDBGroupOperator.AND] = [
394
- ...Object.values(condition[CouchDBGroupOperator.AND]).reduce((accum, val) => {
395
- const keys = Object.keys(val);
396
- if (keys.length !== 1)
397
- throw new Error("Too many keys in query selector. should be one");
398
- const k = keys[0];
399
- if (k === CouchDBGroupOperator.AND)
400
- accum.push(...val[k]);
401
- else
402
- accum.push(val);
403
- return accum;
404
- }, []),
405
- ];
406
- query.selector = condition;
407
- break;
408
- case CouchDBGroupOperator.OR: {
409
- const s = {};
410
- s[CouchDBGroupOperator.AND] = [
411
- condition,
412
- ...Object.entries(query.selector).map(([key, val]) => {
413
- const result = {};
414
- result[key] = val;
415
- return result;
416
- }),
417
- ];
418
- query.selector = s;
419
- break;
420
- }
421
- default:
422
- throw new Error("This should be impossible");
423
- }
424
- else {
425
- Object.entries(condition).forEach(([key, val]) => {
426
- if (query.selector[key])
427
- console.warn(sf("A {0} query param is about to be overridden: {1} by {2}", key, query.selector[key], val));
428
- query.selector[key] = val;
429
- });
430
- }
431
- return query;
432
- }
433
- }
434
-
435
- class CouchDBSelectClause extends SelectClause {
436
- constructor(clause) {
437
- super(clause);
438
- }
439
- build(query) {
440
- if (!this.selector || this.selector === Const.FULL_RECORD)
441
- return query;
442
- query.fields =
443
- typeof this.selector === "string"
444
- ? [this.selector]
445
- : this.selector;
446
- return query;
447
- }
448
- }
449
-
450
- class CouchDBValuesClause extends ValuesClause {
451
- constructor(clause) {
452
- super(clause);
453
- }
454
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
455
- build(previous) {
456
- throw new InternalError("Not implemented");
457
- }
458
- }
459
-
460
- class Factory extends ClauseFactory {
461
- constructor(adapter) {
462
- super(adapter);
463
- }
464
- from(statement, selector) {
465
- return new CouchDBFromClause({ statement: statement, selector: selector });
466
- }
467
- groupBy(statement, selector) {
468
- return new (class extends GroupByClause {
469
- constructor(clause) {
470
- super(clause);
471
- }
472
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
473
- build(query) {
474
- throw new InternalError("Not implemented");
475
- }
476
- })({
477
- statement: statement,
478
- selector: selector,
479
- });
480
- }
481
- insert() {
482
- return new CouchDBInsertClause({
483
- statement: new CouchDBStatement(this.adapter),
484
- });
485
- }
486
- limit(statement, selector) {
487
- return new (class extends LimitClause {
488
- constructor(clause) {
489
- super(clause);
490
- }
491
- build(query) {
492
- query.limit = this.selector;
493
- return query;
494
- }
495
- })({
496
- statement: statement,
497
- selector: selector,
498
- });
499
- }
500
- offset(statement, selector) {
501
- return new (class extends OffsetClause {
502
- constructor(clause) {
503
- super(clause);
504
- }
505
- build(query) {
506
- const skip = parseInt(this.selector);
507
- if (isNaN(skip))
508
- throw new QueryError("Failed to parse offset");
509
- query.skip = skip;
510
- return query;
511
- }
512
- })({
513
- statement: statement,
514
- selector: selector,
515
- });
516
- }
517
- orderBy(statement, selector) {
518
- return new (class extends OrderByClause {
519
- constructor(clause) {
520
- super(clause);
521
- }
522
- build(query) {
523
- query.sort = query.sort || [];
524
- query.selector = query.selector || {};
525
- this.selector.forEach((s) => {
526
- const [selector, value] = s;
527
- const rec = {};
528
- rec[selector] = value;
529
- query.sort.push(rec);
530
- if (!query.selector[selector]) {
531
- query.selector[selector] = {};
532
- query.selector[selector][CouchDBOperator.BIGGER] = null;
533
- }
534
- // query.fields = query.fields || [];
535
- // query.fields = [...new Set([...query.fields, selector]).keys()]
536
- });
537
- return query;
538
- }
539
- })({
540
- statement: statement,
541
- selector: selector,
542
- });
543
- }
544
- select(selector) {
545
- return new CouchDBSelectClause({
546
- statement: new CouchDBStatement(this.adapter),
547
- selector: selector,
548
- });
549
- }
550
- values(statement, values) {
551
- return new CouchDBValuesClause({
552
- statement: statement,
553
- values: values,
554
- });
555
- }
556
- where(statement, condition) {
557
- return new CouchDBWhereClause({
558
- statement: statement,
559
- condition: condition,
560
- });
561
- }
562
- }
563
-
564
- function translateOperators(operator) {
565
- for (const operators of [CouchDBOperator, CouchDBGroupOperator]) {
566
- const el = Object.keys(operators).find((k) => k === operator);
567
- if (el)
568
- return operators[el];
569
- }
570
- throw new QueryError(`Could not find adapter translation for operator ${operator}`);
571
- }
572
-
573
- class IndexError extends BaseError {
574
- constructor(msg) {
575
- super(IndexError.name, msg);
576
- }
577
- }
578
-
579
- class CouchDBAdapter extends Adapter {
580
- constructor(scope, flavour) {
581
- super(scope, flavour);
582
- [this.create, this.createAll, this.update, this.updateAll].forEach((m) => {
583
- const name = m.name;
584
- prefixMethod(this, m, this[name + "Prefix"]);
585
- });
586
- }
587
- get Clauses() {
588
- if (!this.factory)
589
- this.factory = new Factory(this);
590
- return this.factory;
591
- }
592
- Query() {
593
- return super.Query();
594
- }
595
- get Statement() {
596
- return new CouchDBStatement(this);
790
+ return results;
597
791
  }
792
+ /**
793
+ * @description Parses a condition into a CouchDB Mango query selector
794
+ * @summary Converts a Condition object into a CouchDB Mango query selector structure
795
+ * @param {Condition<M>} condition - The condition to parse
796
+ * @return {MangoQuery} The Mango query with the parsed condition as its selector
797
+ * @mermaid
798
+ * sequenceDiagram
799
+ * participant Statement
800
+ * participant translateOperators
801
+ * participant merge
802
+ *
803
+ * Statement->>Statement: parseCondition(condition)
804
+ *
805
+ * Note over Statement: Extract condition parts
806
+ *
807
+ * alt Simple comparison operator
808
+ * Statement->>translateOperators: translateOperators(operator)
809
+ * translateOperators-->>Statement: Return CouchDB operator
810
+ * Statement->>Statement: Create selector with attribute and operator
811
+ * else NOT operator
812
+ * Statement->>Statement: parseCondition(attr1)
813
+ * Statement->>translateOperators: translateOperators(Operator.NOT)
814
+ * translateOperators-->>Statement: Return CouchDB NOT operator
815
+ * Statement->>Statement: Create negated selector
816
+ * else AND/OR operator
817
+ * Statement->>Statement: parseCondition(attr1)
818
+ * Statement->>Statement: parseCondition(comparison)
819
+ * Statement->>translateOperators: translateOperators(operator)
820
+ * translateOperators-->>Statement: Return CouchDB group operator
821
+ * Statement->>merge: merge(operator, op1, op2)
822
+ * merge-->>Statement: Return merged selector
823
+ * end
824
+ *
825
+ * Statement-->>Statement: Return query with selector
826
+ */
598
827
  parseCondition(condition) {
828
+ /**
829
+ * @description Merges two selectors with a logical operator
830
+ * @summary Helper function to combine two selectors with a logical operator
831
+ * @param {MangoOperator} op - The operator to use for merging
832
+ * @param {MangoSelector} obj1 - The first selector
833
+ * @param {MangoSelector} obj2 - The second selector
834
+ * @return {MangoQuery} The merged query
835
+ */
599
836
  function merge(op, obj1, obj2) {
600
837
  const result = { selector: {} };
601
838
  result.selector[op] = [obj1, obj2];
@@ -620,13 +857,93 @@ class CouchDBAdapter extends Adapter {
620
857
  }
621
858
  return { selector: op };
622
859
  }
860
+ }
861
+
862
+ /**
863
+ * @description Abstract adapter for CouchDB database operations
864
+ * @summary Provides a base implementation for CouchDB database operations, including CRUD operations, sequence management, and error handling
865
+ * @template Y - The scope type
866
+ * @template F - The repository flags type
867
+ * @template C - The context type
868
+ * @param {Y} scope - The scope for the adapter
869
+ * @param {string} flavour - The flavour of the adapter
870
+ * @param {string} [alias] - Optional alias for the adapter
871
+ * @class
872
+ * @example
873
+ * // Example of extending CouchDBAdapter
874
+ * class MyCouchDBAdapter extends CouchDBAdapter<MyScope, MyFlags, MyContext> {
875
+ * constructor(scope: MyScope) {
876
+ * super(scope, 'my-couchdb', 'my-alias');
877
+ * }
878
+ *
879
+ * // Implement abstract methods
880
+ * async index<M extends Model>(...models: Constructor<M>[]): Promise<void> {
881
+ * // Implementation
882
+ * }
883
+ *
884
+ * async raw<R>(rawInput: MangoQuery, docsOnly: boolean): Promise<R> {
885
+ * // Implementation
886
+ * }
887
+ *
888
+ * async create(tableName: string, id: string | number, model: Record<string, any>, ...args: any[]): Promise<Record<string, any>> {
889
+ * // Implementation
890
+ * }
891
+ *
892
+ * async read(tableName: string, id: string | number, ...args: any[]): Promise<Record<string, any>> {
893
+ * // Implementation
894
+ * }
895
+ *
896
+ * async update(tableName: string, id: string | number, model: Record<string, any>, ...args: any[]): Promise<Record<string, any>> {
897
+ * // Implementation
898
+ * }
899
+ *
900
+ * async delete(tableName: string, id: string | number, ...args: any[]): Promise<Record<string, any>> {
901
+ * // Implementation
902
+ * }
903
+ * }
904
+ */
905
+ class CouchDBAdapter extends Adapter {
906
+ constructor(scope, flavour, alias) {
907
+ super(scope, flavour, alias);
908
+ [this.create, this.createAll, this.update, this.updateAll].forEach((m) => {
909
+ const name = m.name;
910
+ prefixMethod(this, m, this[name + "Prefix"]);
911
+ });
912
+ }
913
+ /**
914
+ * @description Creates a new CouchDB statement for querying
915
+ * @summary Factory method that creates a new CouchDBStatement instance for building queries
916
+ * @template M - The model type
917
+ * @return {CouchDBStatement<M, any>} A new CouchDBStatement instance
918
+ */
919
+ Statement() {
920
+ return new CouchDBStatement(this);
921
+ }
922
+ /**
923
+ * @description Creates a new CouchDB sequence
924
+ * @summary Factory method that creates a new CouchDBSequence instance for managing sequences
925
+ * @param {SequenceOptions} options - The options for the sequence
926
+ * @return {Promise<Sequence>} A promise that resolves to a new Sequence instance
927
+ */
623
928
  async Sequence(options) {
624
929
  return new CouchDBSequence(options, this);
625
930
  }
931
+ /**
932
+ * @description Initializes the adapter by creating indexes for all managed models
933
+ * @summary Sets up the necessary database indexes for all models managed by this adapter
934
+ * @return {Promise<void>} A promise that resolves when initialization is complete
935
+ */
626
936
  async initialize() {
627
937
  const managedModels = Adapter.models(this.flavour);
628
938
  return this.index(...managedModels);
629
939
  }
940
+ /**
941
+ * @description Assigns metadata to a model
942
+ * @summary Adds revision metadata to a model as a non-enumerable property
943
+ * @param {Record<string, any>} model - The model to assign metadata to
944
+ * @param {string} rev - The revision string to assign
945
+ * @return {Record<string, any>} The model with metadata assigned
946
+ */
630
947
  assignMetadata(model, rev) {
631
948
  Object.defineProperty(model, PersistenceKeys.METADATA, {
632
949
  enumerable: false,
@@ -636,6 +953,13 @@ class CouchDBAdapter extends Adapter {
636
953
  });
637
954
  return model;
638
955
  }
956
+ /**
957
+ * @description Assigns metadata to multiple models
958
+ * @summary Adds revision metadata to multiple models as non-enumerable properties
959
+ * @param models - The models to assign metadata to
960
+ * @param {string[]} revs - The revision strings to assign
961
+ * @return The models with metadata assigned
962
+ */
639
963
  assignMultipleMetadata(models, revs) {
640
964
  models.forEach((m, i) => {
641
965
  Repository.setMetadata(m, revs[i]);
@@ -643,6 +967,14 @@ class CouchDBAdapter extends Adapter {
643
967
  });
644
968
  return models;
645
969
  }
970
+ /**
971
+ * @description Prepares a record for creation
972
+ * @summary Adds necessary CouchDB fields to a record before creation
973
+ * @param {string} tableName - The name of the table
974
+ * @param {string|number} id - The ID of the record
975
+ * @param {Record<string, any>} model - The model to prepare
976
+ * @return A tuple containing the tableName, id, and prepared record
977
+ */
646
978
  createPrefix(tableName, id, model) {
647
979
  const record = {};
648
980
  record[CouchDBKeys.TABLE] = tableName;
@@ -650,6 +982,15 @@ class CouchDBAdapter extends Adapter {
650
982
  Object.assign(record, model);
651
983
  return [tableName, id, record];
652
984
  }
985
+ /**
986
+ * @description Prepares multiple records for creation
987
+ * @summary Adds necessary CouchDB fields to multiple records before creation
988
+ * @param {string} tableName - The name of the table
989
+ * @param {string[]|number[]} ids - The IDs of the records
990
+ * @param models - The models to prepare
991
+ * @return A tuple containing the tableName, ids, and prepared records
992
+ * @throws {InternalError} If ids and models arrays have different lengths
993
+ */
653
994
  createAllPrefix(tableName, ids, models) {
654
995
  if (ids.length !== models.length)
655
996
  throw new InternalError("Ids and models must have the same length");
@@ -662,6 +1003,15 @@ class CouchDBAdapter extends Adapter {
662
1003
  });
663
1004
  return [tableName, ids, records];
664
1005
  }
1006
+ /**
1007
+ * @description Prepares a record for update
1008
+ * @summary Adds necessary CouchDB fields to a record before update
1009
+ * @param {string} tableName - The name of the table
1010
+ * @param {string|number} id - The ID of the record
1011
+ * @param model - The model to prepare
1012
+ * @return A tuple containing the tableName, id, and prepared record
1013
+ * @throws {InternalError} If no revision number is found in the model
1014
+ */
665
1015
  updatePrefix(tableName, id, model) {
666
1016
  const record = {};
667
1017
  record[CouchDBKeys.TABLE] = tableName;
@@ -673,6 +1023,15 @@ class CouchDBAdapter extends Adapter {
673
1023
  record[CouchDBKeys.REV] = rev;
674
1024
  return [tableName, id, record];
675
1025
  }
1026
+ /**
1027
+ * @description Prepares multiple records for update
1028
+ * @summary Adds necessary CouchDB fields to multiple records before update
1029
+ * @param {string} tableName - The name of the table
1030
+ * @param {string[]|number[]} ids - The IDs of the records
1031
+ * @param models - The models to prepare
1032
+ * @return A tuple containing the tableName, ids, and prepared records
1033
+ * @throws {InternalError} If ids and models arrays have different lengths or if no revision number is found in a model
1034
+ */
676
1035
  updateAllPrefix(tableName, ids, models) {
677
1036
  if (ids.length !== models.length)
678
1037
  throw new InternalError("Ids and models must have the same length");
@@ -689,15 +1048,91 @@ class CouchDBAdapter extends Adapter {
689
1048
  });
690
1049
  return [tableName, ids, records];
691
1050
  }
1051
+ /**
1052
+ * @description Generates a CouchDB document ID
1053
+ * @summary Combines the table name and ID to create a CouchDB document ID
1054
+ * @param {string} tableName - The name of the table
1055
+ * @param {string|number} id - The ID of the record
1056
+ * @return {string} The generated CouchDB document ID
1057
+ */
692
1058
  generateId(tableName, id) {
693
1059
  return [tableName, id].join(CouchDBKeys.SEPARATOR);
694
1060
  }
1061
+ /**
1062
+ * @description Parses an error and converts it to a BaseError
1063
+ * @summary Converts various error types to appropriate BaseError subtypes
1064
+ * @param {Error|string} err - The error to parse
1065
+ * @param {string} [reason] - Optional reason for the error
1066
+ * @return {BaseError} The parsed error as a BaseError
1067
+ */
695
1068
  parseError(err, reason) {
696
1069
  return CouchDBAdapter.parseError(err, reason);
697
1070
  }
1071
+ /**
1072
+ * @description Checks if an attribute is reserved
1073
+ * @summary Determines if an attribute name is reserved in CouchDB
1074
+ * @param {string} attr - The attribute name to check
1075
+ * @return {boolean} True if the attribute is reserved, false otherwise
1076
+ */
698
1077
  isReserved(attr) {
699
1078
  return !!attr.match(reservedAttributes);
700
1079
  }
1080
+ /**
1081
+ * @description Static method to parse an error and convert it to a BaseError
1082
+ * @summary Converts various error types to appropriate BaseError subtypes based on error codes and messages
1083
+ * @param {Error|string} err - The error to parse
1084
+ * @param {string} [reason] - Optional reason for the error
1085
+ * @return {BaseError} The parsed error as a BaseError
1086
+ * @mermaid
1087
+ * sequenceDiagram
1088
+ * participant Caller
1089
+ * participant parseError
1090
+ * participant ErrorTypes
1091
+ *
1092
+ * Caller->>parseError: err, reason
1093
+ * Note over parseError: Check if err is already a BaseError
1094
+ * alt err is BaseError
1095
+ * parseError-->>Caller: return err
1096
+ * else err is string
1097
+ * Note over parseError: Extract code from string
1098
+ * alt code matches "already exist|update conflict"
1099
+ * parseError->>ErrorTypes: new ConflictError(code)
1100
+ * ErrorTypes-->>Caller: ConflictError
1101
+ * else code matches "missing|deleted"
1102
+ * parseError->>ErrorTypes: new NotFoundError(code)
1103
+ * ErrorTypes-->>Caller: NotFoundError
1104
+ * end
1105
+ * else err has code property
1106
+ * Note over parseError: Extract code and reason
1107
+ * else err has statusCode property
1108
+ * Note over parseError: Extract code and reason
1109
+ * else
1110
+ * Note over parseError: Use err.message as code
1111
+ * end
1112
+ *
1113
+ * Note over parseError: Switch on code
1114
+ * alt code is 401, 412, or 409
1115
+ * parseError->>ErrorTypes: new ConflictError(reason)
1116
+ * ErrorTypes-->>Caller: ConflictError
1117
+ * else code is 404
1118
+ * parseError->>ErrorTypes: new NotFoundError(reason)
1119
+ * ErrorTypes-->>Caller: NotFoundError
1120
+ * else code is 400
1121
+ * alt code matches "No index exists"
1122
+ * parseError->>ErrorTypes: new IndexError(err)
1123
+ * ErrorTypes-->>Caller: IndexError
1124
+ * else
1125
+ * parseError->>ErrorTypes: new InternalError(err)
1126
+ * ErrorTypes-->>Caller: InternalError
1127
+ * end
1128
+ * else code matches "ECONNREFUSED"
1129
+ * parseError->>ErrorTypes: new ConnectionError(err)
1130
+ * ErrorTypes-->>Caller: ConnectionError
1131
+ * else
1132
+ * parseError->>ErrorTypes: new InternalError(err)
1133
+ * ErrorTypes-->>Caller: InternalError
1134
+ * end
1135
+ */
701
1136
  static parseError(err, reason) {
702
1137
  if (err instanceof BaseError)
703
1138
  return err;
@@ -738,10 +1173,104 @@ class CouchDBAdapter extends Adapter {
738
1173
  }
739
1174
  }
740
1175
  }
1176
+ __decorate([
1177
+ final(),
1178
+ __metadata("design:type", Function),
1179
+ __metadata("design:paramtypes", []),
1180
+ __metadata("design:returntype", CouchDBStatement)
1181
+ ], CouchDBAdapter.prototype, "Statement", null);
1182
+ __decorate([
1183
+ final(),
1184
+ __metadata("design:type", Function),
1185
+ __metadata("design:paramtypes", [Object]),
1186
+ __metadata("design:returntype", Promise)
1187
+ ], CouchDBAdapter.prototype, "Sequence", null);
1188
+ __decorate([
1189
+ final(),
1190
+ __metadata("design:type", Function),
1191
+ __metadata("design:paramtypes", [Object, String]),
1192
+ __metadata("design:returntype", Object)
1193
+ ], CouchDBAdapter.prototype, "assignMetadata", null);
1194
+ __decorate([
1195
+ final(),
1196
+ __metadata("design:type", Function),
1197
+ __metadata("design:paramtypes", [Array, Array]),
1198
+ __metadata("design:returntype", Array)
1199
+ ], CouchDBAdapter.prototype, "assignMultipleMetadata", null);
1200
+ __decorate([
1201
+ final(),
1202
+ __metadata("design:type", Function),
1203
+ __metadata("design:paramtypes", [String, Object, Object]),
1204
+ __metadata("design:returntype", void 0)
1205
+ ], CouchDBAdapter.prototype, "createPrefix", null);
1206
+ __decorate([
1207
+ final(),
1208
+ __metadata("design:type", Function),
1209
+ __metadata("design:paramtypes", [String, Array, Array]),
1210
+ __metadata("design:returntype", void 0)
1211
+ ], CouchDBAdapter.prototype, "createAllPrefix", null);
1212
+ __decorate([
1213
+ final(),
1214
+ __metadata("design:type", Function),
1215
+ __metadata("design:paramtypes", [String, Object, Object]),
1216
+ __metadata("design:returntype", void 0)
1217
+ ], CouchDBAdapter.prototype, "updatePrefix", null);
1218
+ __decorate([
1219
+ final(),
1220
+ __metadata("design:type", Function),
1221
+ __metadata("design:paramtypes", [String, Array, Array]),
1222
+ __metadata("design:returntype", void 0)
1223
+ ], CouchDBAdapter.prototype, "updateAllPrefix", null);
741
1224
 
1225
+ /**
1226
+ * @description Re-authenticates a connection to CouchDB
1227
+ * @summary Refreshes the authentication for a CouchDB connection using the provided credentials
1228
+ * @param {any} con - The CouchDB connection object
1229
+ * @param {string} user - The username for authentication
1230
+ * @param {string} pass - The password for authentication
1231
+ * @return {Promise<any>} A promise that resolves to the authentication result
1232
+ * @function reAuth
1233
+ * @memberOf module:for-couchdb
1234
+ */
742
1235
  async function reAuth(con, user, pass) {
743
1236
  return con.auth(user, pass);
744
1237
  }
1238
+ /**
1239
+ * @description Wraps a CouchDB database connection with automatic re-authentication
1240
+ * @summary Creates a proxy around a CouchDB database connection that automatically re-authenticates before each operation
1241
+ * @param {any} con - The CouchDB connection object
1242
+ * @param {string} dbName - The name of the database to use
1243
+ * @param {string} user - The username for authentication
1244
+ * @param {string} pass - The password for authentication
1245
+ * @return {any} The wrapped database connection object
1246
+ * @function wrapDocumentScope
1247
+ * @memberOf module:for-couchdb
1248
+ * @mermaid
1249
+ * sequenceDiagram
1250
+ * participant Client
1251
+ * participant wrapDocumentScope
1252
+ * participant DB
1253
+ * participant reAuth
1254
+ *
1255
+ * Client->>wrapDocumentScope: con, dbName, user, pass
1256
+ * wrapDocumentScope->>DB: con.use(dbName)
1257
+ * Note over wrapDocumentScope: Wrap DB methods with re-auth
1258
+ *
1259
+ * loop For each method (insert, get, put, destroy, find)
1260
+ * wrapDocumentScope->>wrapDocumentScope: Store original method
1261
+ * wrapDocumentScope->>wrapDocumentScope: Define new method with re-auth
1262
+ * end
1263
+ *
1264
+ * wrapDocumentScope->>wrapDocumentScope: Add NATIVE property with con value
1265
+ * wrapDocumentScope-->>Client: Return wrapped DB
1266
+ *
1267
+ * Note over Client: Later when client uses DB methods
1268
+ * Client->>DB: Any wrapped method call
1269
+ * DB->>reAuth: Authenticate before operation
1270
+ * reAuth-->>DB: Authentication complete
1271
+ * DB->>DB: Call original method
1272
+ * DB-->>Client: Return result
1273
+ */
745
1274
  function wrapDocumentScope(con, dbName, user, pass) {
746
1275
  const db = con.use(dbName);
747
1276
  ["insert", "get", "put", "destroy", "find"].forEach((k) => {
@@ -763,10 +1292,30 @@ function wrapDocumentScope(con, dbName, user, pass) {
763
1292
  });
764
1293
  return db;
765
1294
  }
1295
+ /**
1296
+ * @description Tests if an attribute name is reserved in CouchDB
1297
+ * @summary Checks if an attribute name starts with an underscore, which indicates it's a reserved attribute in CouchDB
1298
+ * @param {string} attr - The attribute name to test
1299
+ * @return {RegExpMatchArray|null} The match result or null if no match
1300
+ * @function testReservedAttributes
1301
+ * @memberOf module:for-couchdb
1302
+ */
766
1303
  function testReservedAttributes(attr) {
767
1304
  const regexp = /^_.*$/g;
768
1305
  return attr.match(regexp);
769
1306
  }
1307
+ /**
1308
+ * @description Generates a name for a CouchDB index
1309
+ * @summary Creates a standardized name for a CouchDB index based on the table, attribute, compositions, and order
1310
+ * @param {string} attribute - The primary attribute for the index
1311
+ * @param {string} tableName - The name of the table
1312
+ * @param {string[]} [compositions] - Optional additional attributes to include in the index
1313
+ * @param {OrderDirection} [order] - Optional sort order for the index
1314
+ * @param {string} [separator=DefaultSeparator] - The separator to use between parts of the index name
1315
+ * @return {string} The generated index name
1316
+ * @function generateIndexName
1317
+ * @memberOf module:for-couchdb
1318
+ */
770
1319
  function generateIndexName(attribute, tableName, compositions, order, separator = DefaultSeparator) {
771
1320
  const attr = [PersistenceKeys.INDEX, tableName, attribute];
772
1321
  if (compositions)
@@ -775,6 +1324,45 @@ function generateIndexName(attribute, tableName, compositions, order, separator
775
1324
  attr.push(order);
776
1325
  return attr.join(separator);
777
1326
  }
1327
+ /**
1328
+ * @description Generates a CouchDB index configuration
1329
+ * @summary Creates a complete CreateIndexRequest object for defining a CouchDB index based on specified parameters
1330
+ * @param {string} attribute - The primary attribute for the index
1331
+ * @param {string} tableName - The name of the table
1332
+ * @param {string[]} [compositions] - Optional additional attributes to include in the index
1333
+ * @param {OrderDirection} [order] - Optional sort order for the index
1334
+ * @param {string} [separator=DefaultSeparator] - The separator to use between parts of the index name
1335
+ * @return {CreateIndexRequest} The complete index configuration object
1336
+ * @function generateIndexDoc
1337
+ * @memberOf module:for-couchdb
1338
+ * @mermaid
1339
+ * sequenceDiagram
1340
+ * participant Caller
1341
+ * participant generateIndexDoc
1342
+ * participant generateIndexName
1343
+ *
1344
+ * Caller->>generateIndexDoc: attribute, tableName, compositions, order, separator
1345
+ *
1346
+ * Note over generateIndexDoc: Create partial filter selector
1347
+ * generateIndexDoc->>generateIndexDoc: Set up filter for tableName
1348
+ *
1349
+ * alt order is specified
1350
+ * Note over generateIndexDoc: Create ordered fields array
1351
+ * generateIndexDoc->>generateIndexDoc: Create orderProp for attribute
1352
+ * generateIndexDoc->>generateIndexDoc: Map compositions to ordered props
1353
+ * generateIndexDoc->>generateIndexDoc: Create sortedTable for table field
1354
+ * generateIndexDoc->>generateIndexDoc: Combine all ordered fields
1355
+ * else
1356
+ * Note over generateIndexDoc: Create simple fields array
1357
+ * generateIndexDoc->>generateIndexDoc: Use attribute, compositions, and table as strings
1358
+ * end
1359
+ *
1360
+ * generateIndexDoc->>generateIndexName: Generate index name
1361
+ * generateIndexName-->>generateIndexDoc: Return name
1362
+ *
1363
+ * Note over generateIndexDoc: Create final index request
1364
+ * generateIndexDoc-->>Caller: Return CreateIndexRequest
1365
+ */
778
1366
  function generateIndexDoc(attribute, tableName, compositions, order, separator = DefaultSeparator) {
779
1367
  const partialFilterSelector = {};
780
1368
  partialFilterSelector[CouchDBKeys.TABLE] = {};
@@ -807,23 +1395,16 @@ function generateIndexDoc(attribute, tableName, compositions, order, separator =
807
1395
  }
808
1396
 
809
1397
  /**
810
- * @summary Module summary
811
- * @description Module description
812
- * @module ts-workspace
813
- */
814
- /**
815
- * @summary Namespace summary
816
- * @description Namespace description
817
- * @namespace Namespace
818
- * @memberOf module:ts-workspace
1398
+ * @description CouchDB adapter for Decaf.ts
1399
+ * @summary A TypeScript adapter for CouchDB database operations, providing a seamless integration with the Decaf.ts framework. This module includes classes, interfaces, and utilities for working with CouchDB databases, including support for Mango queries, document operations, and sequence management.
1400
+ * @module for-couchdb
819
1401
  */
820
1402
  /**
821
- * @summary stores the current package version
822
- * @description this is how you should document a constant
1403
+ * @description Stores the current package version
1404
+ * @summary The version string of the for-couchdb package
823
1405
  * @const VERSION
824
- * @memberOf module:ts-workspace
825
1406
  */
826
- const VERSION = "0.3.0";
1407
+ const VERSION = "0.3.2";
827
1408
 
828
1409
  export { CouchDBAdapter, CouchDBKeys, CouchDBSequence, IndexError, Sequence, VERSION, generateIndexDoc, generateIndexName, generateIndexes, reAuth, reservedAttributes, testReservedAttributes, wrapDocumentScope };
829
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yLWNvdWNoZGIuZXNtLmNqcyIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbnN0YW50cy50cyIsIi4uL3NyYy9xdWVyeS9jb25zdGFudHMudHMiLCIuLi9zcmMvaW5kZXhlcy9nZW5lcmF0b3IudHMiLCIuLi9zcmMvbW9kZWwvQ291Y2hEQlNlcXVlbmNlLnRzIiwiLi4vc3JjL3NlcXVlbmNlcy91dGlscy50cyIsIi4uL3NyYy9zZXF1ZW5jZXMvU2VxdWVuY2UudHMiLCIuLi9zcmMvcXVlcnkvUGFnaW5hdG9yLnRzIiwiLi4vc3JjL3F1ZXJ5L1N0YXRlbWVudC50cyIsIi4uL3NyYy9xdWVyeS9Gcm9tQ2xhdXNlLnRzIiwiLi4vc3JjL3F1ZXJ5L0luc2VydENsYXVzZS50cyIsIi4uL3NyYy9xdWVyeS9XaGVyZUNsYXVzZS50cyIsIi4uL3NyYy9xdWVyeS9TZWxlY3RDbGF1c2UudHMiLCIuLi9zcmMvcXVlcnkvVmFsdWVzQ2xhdXNlLnRzIiwiLi4vc3JjL3F1ZXJ5L2ZhY3RvcnkudHMiLCIuLi9zcmMvcXVlcnkvdHJhbnNsYXRlLnRzIiwiLi4vc3JjL2Vycm9ycy50cyIsIi4uL3NyYy9hZGFwdGVyLnRzIiwiLi4vc3JjL3V0aWxzLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjb25zdCByZXNlcnZlZEF0dHJpYnV0ZXMgPSAvXl8uKiQvZztcblxuZXhwb3J0IGNvbnN0IENvdWNoREJLZXlzID0ge1xuICBTRVBBUkFUT1I6IFwiX1wiLFxuICBJRDogXCJfaWRcIixcbiAgUkVWOiBcIl9yZXZcIixcbiAgREVMRVRFRDogXCJfZGVsZXRlZFwiLFxuICBUQUJMRTogXCI/P3RhYmxlXCIsXG4gIFNFUVVFTkNFOiBcIj8/c2VxdWVuY2VcIixcbiAgRERPQzogXCJkZG9jXCIsXG4gIE5BVElWRTogXCJfX25hdGl2ZVwiLFxuICBJTkRFWDogXCJpbmRleFwiLFxufTtcbiIsImltcG9ydCB7IE1hbmdvT3BlcmF0b3IgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuZXhwb3J0IGNvbnN0IENvdWNoREJPcGVyYXRvcjogUmVjb3JkPHN0cmluZywgTWFuZ29PcGVyYXRvcj4gPSB7XG4gIEVRVUFMOiBcIiRlcVwiLFxuICBESUZGRVJFTlQ6IFwiJG5lXCIsXG4gIEJJR0dFUjogXCIkZ3RcIixcbiAgQklHR0VSX0VROiBcIiRndGVcIixcbiAgU01BTExFUjogXCIkbHRcIixcbiAgU01BTExFUl9FUTogXCIkbHRlXCIsXG4gIC8vIEJFVFdFRU4gPSBcIkJFVFdFRU5cIixcbiAgTk9UOiBcIiRub3RcIixcbiAgSU46IFwiJGluXCIsXG4gIC8vIElTID0gXCJJU1wiLFxuICBSRUdFWFA6IFwiJHJlZ2V4XCIsXG59O1xuXG5leHBvcnQgY29uc3QgQ291Y2hEQkdyb3VwT3BlcmF0b3I6IFJlY29yZDxzdHJpbmcsIE1hbmdvT3BlcmF0b3I+ID0ge1xuICBBTkQ6IFwiJGFuZFwiLFxuICBPUjogXCIkb3JcIixcbn07XG5cbmV4cG9ydCBjb25zdCBDb3VjaERCQ29uc3Q6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gIE5VTEw6IFwibnVsbFwiLFxufTtcbiIsImltcG9ydCB7XG4gIEluZGV4TWV0YWRhdGEsXG4gIE9yZGVyRGlyZWN0aW9uLFxuICBQZXJzaXN0ZW5jZUtleXMsXG4gIFJlcG9zaXRvcnksXG59IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgQ291Y2hEQktleXMgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBEZWZhdWx0U2VwYXJhdG9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBDb3VjaERCT3BlcmF0b3IgfSBmcm9tIFwiLi4vcXVlcnkvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBDcmVhdGVJbmRleFJlcXVlc3QgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuZnVuY3Rpb24gZ2VuZXJhdGVJbmRleE5hbWUoXG4gIG5hbWU6IHN0cmluZ1tdLFxuICBkaXJlY3Rpb24/OiBPcmRlckRpcmVjdGlvbixcbiAgY29tcG9zaXRpb25zPzogc3RyaW5nW10sXG4gIHNlcGFyYXRvciA9IERlZmF1bHRTZXBhcmF0b3Jcbikge1xuICByZXR1cm4gW1xuICAgIC4uLm5hbWUubWFwKChuKSA9PiAobiA9PT0gQ291Y2hEQktleXMuVEFCTEUgPyBcInRhYmxlXCIgOiBuKSksXG4gICAgLi4uKGNvbXBvc2l0aW9ucyB8fCBbXSksXG4gICAgLi4uKGRpcmVjdGlvbiA/IFtkaXJlY3Rpb25dIDogW10pLFxuICAgIENvdWNoREJLZXlzLklOREVYLFxuICBdLmpvaW4oc2VwYXJhdG9yKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlSW5kZXhlczxNIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbHM6IENvbnN0cnVjdG9yPE0+W11cbik6IENyZWF0ZUluZGV4UmVxdWVzdFtdIHtcbiAgY29uc3QgdGFibGVOYW1lID0gZ2VuZXJhdGVJbmRleE5hbWUoW0NvdWNoREJLZXlzLlRBQkxFXSk7XG4gIGNvbnN0IGluZGV4ZXM6IFJlY29yZDxzdHJpbmcsIENyZWF0ZUluZGV4UmVxdWVzdD4gPSB7fTtcbiAgaW5kZXhlc1t0YWJsZU5hbWVdID0ge1xuICAgIGluZGV4OiB7XG4gICAgICBmaWVsZHM6IFtDb3VjaERCS2V5cy5UQUJMRV0sXG4gICAgfSxcbiAgICBuYW1lOiB0YWJsZU5hbWUsXG4gICAgZGRvYzogdGFibGVOYW1lLFxuICAgIHR5cGU6IFwianNvblwiLFxuICB9O1xuXG4gIG1vZGVscy5mb3JFYWNoKChtKSA9PiB7XG4gICAgY29uc3QgaW5kOiBSZWNvcmQ8c3RyaW5nLCBJbmRleE1ldGFkYXRhPiA9IFJlcG9zaXRvcnkuaW5kZXhlcyhtKTtcbiAgICBPYmplY3QuZW50cmllcyhpbmQpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgY29uc3QgayA9IE9iamVjdC5rZXlzKHZhbHVlKVswXTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItY29uc3RcbiAgICAgIGxldCB7IGRpcmVjdGlvbnMsIGNvbXBvc2l0aW9ucyB9ID0gKHZhbHVlIGFzIGFueSlba107XG4gICAgICBjb25zdCB0YWJsZU5hbWUgPSBSZXBvc2l0b3J5LnRhYmxlKG0pO1xuICAgICAgY29tcG9zaXRpb25zID0gY29tcG9zaXRpb25zIHx8IFtdO1xuXG4gICAgICBmdW5jdGlvbiBnZW5lcmF0ZShzb3J0PzogT3JkZXJEaXJlY3Rpb24pIHtcbiAgICAgICAgY29uc3QgbmFtZSA9IFtcbiAgICAgICAgICB0YWJsZU5hbWUsXG4gICAgICAgICAga2V5LFxuICAgICAgICAgIC4uLihjb21wb3NpdGlvbnMgYXMgW10pLFxuICAgICAgICAgIFBlcnNpc3RlbmNlS2V5cy5JTkRFWCxcbiAgICAgICAgXS5qb2luKERlZmF1bHRTZXBhcmF0b3IpO1xuXG4gICAgICAgIGluZGV4ZXNbbmFtZV0gPSB7XG4gICAgICAgICAgaW5kZXg6IHtcbiAgICAgICAgICAgIGZpZWxkczogW2tleSwgLi4uKGNvbXBvc2l0aW9ucyBhcyBbXSksIENvdWNoREJLZXlzLlRBQkxFXS5yZWR1Y2UoXG4gICAgICAgICAgICAgIChhY2N1bTogYW55W10sIGVsKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHNvcnQpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJlczogYW55ID0ge307XG4gICAgICAgICAgICAgICAgICByZXNbZWxdID0gc29ydDtcbiAgICAgICAgICAgICAgICAgIGFjY3VtLnB1c2gocmVzKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgYWNjdW0ucHVzaChlbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgW11cbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSxcbiAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgIGRkb2M6IG5hbWUsXG4gICAgICAgICAgdHlwZTogXCJqc29uXCIsXG4gICAgICAgIH07XG4gICAgICAgIGlmICghc29ydCkge1xuICAgICAgICAgIGNvbnN0IHRhYmxlRmlsdGVyOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgICAgICAgdGFibGVGaWx0ZXJbQ291Y2hEQktleXMuVEFCTEVdID0ge307XG4gICAgICAgICAgdGFibGVGaWx0ZXJbQ291Y2hEQktleXMuVEFCTEVdW0NvdWNoREJPcGVyYXRvci5FUVVBTF0gPSB0YWJsZU5hbWU7XG4gICAgICAgICAgaW5kZXhlc1tuYW1lXS5pbmRleC5wYXJ0aWFsX2ZpbHRlcl9zZWxlY3RvciA9IHRhYmxlRmlsdGVyO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGdlbmVyYXRlKCk7XG4gICAgICBpZiAoZGlyZWN0aW9ucylcbiAgICAgICAgKGRpcmVjdGlvbnMgYXMgdW5rbm93biBhcyBPcmRlckRpcmVjdGlvbltdKS5mb3JFYWNoKChkKSA9PiBnZW5lcmF0ZShkKSk7XG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gT2JqZWN0LnZhbHVlcyhpbmRleGVzKTtcbn1cbiIsImltcG9ydCB0eXBlIHsgTW9kZWxBcmcgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBtb2RlbCwgcmVxdWlyZWQgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBCYXNlTW9kZWwsIHBrLCBpbmRleCwgdGFibGUgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IENvdWNoREJLZXlzIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuXG5AdGFibGUoQ291Y2hEQktleXMuU0VRVUVOQ0UpXG5AbW9kZWwoKVxuZXhwb3J0IGNsYXNzIFNlcXVlbmNlIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHRoZSBQcmltYXJ5IGtleSBmb3IgdGhlIERCU2VxdWVuY2VcbiAgICogQHByb3AgbmFtZVxuICAgKlxuICAgKiBAc2VlIHBrXG4gICAqL1xuICBAcGsoKVxuICBpZCE6IHN0cmluZztcbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHRoZSBjdXJyZW50IHZhbHVlIGZvciB0aGUgREJTZXF1ZW5jZVxuICAgKiBAcHJvcCBjdXJyZW50XG4gICAqXG4gICAqIEBzZWUgcmVxdWlyZWRcbiAgICogQHNlZSBpbmRleFxuICAgKi9cbiAgQHJlcXVpcmVkKClcbiAgQGluZGV4KClcbiAgY3VycmVudCE6IHN0cmluZyB8IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihzZXE/OiBNb2RlbEFyZzxTZXF1ZW5jZT4pIHtcbiAgICBzdXBlcihzZXEpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVNlcXVlbmNlVmFsdWUoXG4gIHR5cGU6IFwiTnVtYmVyXCIgfCBcIkJpZ0ludFwiIHwgdW5kZWZpbmVkLFxuICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50XG4pOiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIFwiTnVtYmVyXCI6XG4gICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiXG4gICAgICAgID8gcGFyc2VJbnQodmFsdWUpXG4gICAgICAgIDogdHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiXG4gICAgICAgICAgPyB2YWx1ZVxuICAgICAgICAgIDogQmlnSW50KHZhbHVlKTtcbiAgICBjYXNlIFwiQmlnSW50XCI6XG4gICAgICByZXR1cm4gQmlnSW50KHZhbHVlKTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJTaG91bGQgbmV2ZXIgaGFwcGVuXCIpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBzZiB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFNlcXVlbmNlIGFzIFNlcSB9IGZyb20gXCIuLi9tb2RlbC9Db3VjaERCU2VxdWVuY2VcIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IsIE5vdEZvdW5kRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IEFkYXB0ZXIsIFJlcG9zaXRvcnksIFNlcXVlbmNlT3B0aW9ucyB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgU2VxdWVuY2UgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IHBhcnNlU2VxdWVuY2VWYWx1ZSB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBNYW5nb1F1ZXJ5IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBDb3VjaERCUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9pbnRlcmZhY2VzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgQWJzdHJhY3QgaW1wbGVtZW50YXRpb24gb2YgYSBTZXF1ZW5jZVxuICogQGRlc2NyaXB0aW9uIHByb3ZpZGVzIHRoZSBiYXNpYyBmdW5jdGlvbmFsaXR5IGZvciB7QGxpbmsgU2VxdWVuY2V9c1xuICpcbiAqIEBwYXJhbSB7U2VxdWVuY2VPcHRpb25zfSBvcHRpb25zXG4gKlxuICogQGNsYXNzIENvdWNoREJTZXF1ZW5jZVxuICogQGltcGxlbWVudHMgU2VxdWVuY2VcbiAqXG4gKiBAY2F0ZWdvcnkgU2VxdWVuY2VzXG4gKi9cbmV4cG9ydCBjbGFzcyBDb3VjaERCU2VxdWVuY2UgZXh0ZW5kcyBTZXF1ZW5jZSB7XG4gIHByb3RlY3RlZCByZXBvOiBDb3VjaERCUmVwb3NpdG9yeTxTZXEsIGFueSwgYW55LCBhbnk+O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIG9wdGlvbnM6IFNlcXVlbmNlT3B0aW9ucyxcbiAgICBhZGFwdGVyOiBBZGFwdGVyPGFueSwgTWFuZ29RdWVyeSwgYW55LCBhbnk+XG4gICkge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgIHRoaXMucmVwbyA9IFJlcG9zaXRvcnkuZm9yTW9kZWwoU2VxLCBhZGFwdGVyLmZsYXZvdXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgY3VycmVudCB2YWx1ZSBmb3IgdGhlIHNlcXVlbmNlXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIGFzeW5jIGN1cnJlbnQoKTogUHJvbWlzZTxzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQ+IHtcbiAgICBjb25zdCB7IG5hbWUsIHN0YXJ0V2l0aCB9ID0gdGhpcy5vcHRpb25zO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzZXF1ZW5jZTogU2VxID0gYXdhaXQgdGhpcy5yZXBvLnJlYWQobmFtZSBhcyBzdHJpbmcpO1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2Uoc2VxdWVuY2UuY3VycmVudCBhcyBzdHJpbmcgfCBudW1iZXIpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgaWYgKGUgaW5zdGFuY2VvZiBOb3RGb3VuZEVycm9yKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc3RhcnRXaXRoID09PSBcInVuZGVmaW5lZFwiKVxuICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAgICAgXCJTdGFydGluZyB2YWx1ZSBpcyBub3QgZGVmaW5lZCBmb3IgYSBub24gZXhpc3Rpbmcgc2VxdWVuY2VcIlxuICAgICAgICAgICk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2Uoc3RhcnRXaXRoKTtcbiAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgICAgICBzZihcbiAgICAgICAgICAgICAgXCJGYWlsZWQgdG8gcGFyc2UgaW5pdGlhbCB2YWx1ZSBmb3Igc2VxdWVuY2UgezB9OiB7MX1cIixcbiAgICAgICAgICAgICAgc3RhcnRXaXRoLnRvU3RyaW5nKCksXG4gICAgICAgICAgICAgIGVcbiAgICAgICAgICAgIClcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgc2YoXG4gICAgICAgICAgXCJGYWlsZWQgdG8gcmV0cmlldmUgY3VycmVudCB2YWx1ZSBmb3Igc2VxdWVuY2UgezB9OiB7MX1cIixcbiAgICAgICAgICBuYW1lIGFzIHN0cmluZyxcbiAgICAgICAgICBlXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFBhcnNlcyB0aGUge0BsaW5rIFNlcXVlbmNlfSB2YWx1ZVxuICAgKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEBwYXJhbSB2YWx1ZVxuICAgKi9cbiAgcHJpdmF0ZSBwYXJzZSh2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50KTogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHtcbiAgICByZXR1cm4gcGFyc2VTZXF1ZW5jZVZhbHVlKHRoaXMub3B0aW9ucy50eXBlLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgaW5jcmVtZW50cyB0aGUgc2VxdWVuY2VcbiAgICogQGRlc2NyaXB0aW9uIFNlcXVlbmNlIHNwZWNpZmljIGltcGxlbWVudGF0aW9uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50fSBjdXJyZW50XG4gICAqIEBwYXJhbSBjb3VudFxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGluY3JlbWVudChcbiAgICBjdXJyZW50OiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQsXG4gICAgY291bnQ/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQ+IHtcbiAgICBjb25zdCB7IHR5cGUsIGluY3JlbWVudEJ5LCBuYW1lIH0gPSB0aGlzLm9wdGlvbnM7XG4gICAgbGV0IG5leHQ6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludDtcbiAgICBjb25zdCB0b0luY3JlbWVudEJ5ID0gY291bnQgfHwgaW5jcmVtZW50Qnk7XG4gICAgaWYgKHRvSW5jcmVtZW50QnkgJSBpbmNyZW1lbnRCeSAhPT0gMClcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgVmFsdWUgdG8gaW5jcmVtZW50IGRvZXMgbm90IGNvbnNpZGVyIHRoZSBpbmNyZW1lbnRCeSBzZXR0aW5nOiAke2luY3JlbWVudEJ5fWBcbiAgICAgICk7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlIFwiTnVtYmVyXCI6XG4gICAgICAgIG5leHQgPSAodGhpcy5wYXJzZShjdXJyZW50KSBhcyBudW1iZXIpICsgdG9JbmNyZW1lbnRCeTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwiQmlnSW50XCI6XG4gICAgICAgIG5leHQgPSAodGhpcy5wYXJzZShjdXJyZW50KSBhcyBiaWdpbnQpICsgQmlnSW50KHRvSW5jcmVtZW50QnkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiU2hvdWxkIG5ldmVyIGhhcHBlblwiKTtcbiAgICB9XG4gICAgbGV0IHNlcTogU2VxO1xuICAgIHRyeSB7XG4gICAgICBzZXEgPSBhd2FpdCB0aGlzLnJlcG8udXBkYXRlKG5ldyBTZXEoeyBpZDogbmFtZSwgY3VycmVudDogbmV4dCB9KSk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBpZiAoIShlIGluc3RhbmNlb2YgTm90Rm91bmRFcnJvcikpIHRocm93IGU7XG4gICAgICBzZXEgPSBhd2FpdCB0aGlzLnJlcG8uY3JlYXRlKG5ldyBTZXEoeyBpZDogbmFtZSwgY3VycmVudDogbmV4dCB9KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlcS5jdXJyZW50IGFzIHN0cmluZyB8IG51bWJlciB8IGJpZ2ludDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBHZW5lcmF0ZXMgdGhlIG5leHQgdmFsdWUgaW4gdGggc2VxdWVuY2VcbiAgICogQGRlc2NyaXB0aW9uIGNhbGxzIHtAbGluayBTZXF1ZW5jZSNwYXJzZX0gb24gdGhlIGN1cnJlbnQgdmFsdWVcbiAgICogZm9sbG93ZWQgYnkge0BsaW5rIFNlcXVlbmNlI2luY3JlbWVudH1cbiAgICpcbiAgICovXG4gIGFzeW5jIG5leHQoKTogUHJvbWlzZTxudW1iZXIgfCBzdHJpbmcgfCBiaWdpbnQ+IHtcbiAgICBjb25zdCBjdXJyZW50ID0gYXdhaXQgdGhpcy5jdXJyZW50KCk7XG4gICAgcmV0dXJuIHRoaXMuaW5jcmVtZW50KGN1cnJlbnQpO1xuICB9XG5cbiAgYXN5bmMgcmFuZ2UoY291bnQ6IG51bWJlcik6IFByb21pc2U8KG51bWJlciB8IHN0cmluZyB8IGJpZ2ludClbXT4ge1xuICAgIGNvbnN0IGN1cnJlbnQgPSAoYXdhaXQgdGhpcy5jdXJyZW50KCkpIGFzIG51bWJlcjtcbiAgICBjb25zdCBpbmNyZW1lbnRCeSA9IHRoaXMucGFyc2UodGhpcy5vcHRpb25zLmluY3JlbWVudEJ5KSBhcyBudW1iZXI7XG4gICAgY29uc3QgbmV4dDogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50ID0gYXdhaXQgdGhpcy5pbmNyZW1lbnQoXG4gICAgICBjdXJyZW50LFxuICAgICAgKHRoaXMucGFyc2UoY291bnQpIGFzIG51bWJlcikgKiBpbmNyZW1lbnRCeVxuICAgICk7XG4gICAgY29uc3QgcmFuZ2U6IChudW1iZXIgfCBzdHJpbmcgfCBiaWdpbnQpW10gPSBbXTtcbiAgICBmb3IgKGxldCBpOiBudW1iZXIgPSAxOyBpIDw9IGNvdW50OyBpKyspIHtcbiAgICAgIHJhbmdlLnB1c2goY3VycmVudCArIGluY3JlbWVudEJ5ICogKHRoaXMucGFyc2UoaSkgYXMgbnVtYmVyKSk7XG4gICAgfVxuICAgIGlmIChyYW5nZVtyYW5nZS5sZW5ndGggLSAxXSAhPT0gbmV4dClcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiTWlzY2FsY3VsYXRpb24gb2YgcmFuZ2VcIik7XG4gICAgcmV0dXJuIHJhbmdlO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBQYWdpbmF0b3IsXG4gIFBhZ2luZ0Vycm9yLFxuICBTZXF1ZW5jZU9wdGlvbnMsXG4gIFN0YXRlbWVudCxcbn0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQge1xuICBEZWZhdWx0U2VwYXJhdG9yLFxuICBmaW5kUHJpbWFyeUtleSxcbiAgSW50ZXJuYWxFcnJvcixcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBwYXJzZVNlcXVlbmNlVmFsdWUgfSBmcm9tIFwiLi4vc2VxdWVuY2VzL3V0aWxzXCI7XG5pbXBvcnQgeyBNYW5nb1F1ZXJ5LCBNYW5nb1Jlc3BvbnNlIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbmV4cG9ydCBjbGFzcyBDb3VjaERCUGFnaW5hdG9yPFY+IGV4dGVuZHMgUGFnaW5hdG9yPFYsIE1hbmdvUXVlcnk+IHtcbiAgcHJpdmF0ZSBib29rTWFyaz86IHN0cmluZztcblxuICBnZXQgdG90YWwoKTogbnVtYmVyIHtcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgVGhlIHRvdGFsIHBhZ2VzIGFwaSBpcyBub3QgYXZhaWxhYmxlIGZvciBjb3VjaGRiYCk7XG4gIH1cblxuICBnZXQgY291bnQoKTogbnVtYmVyIHtcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBUaGUgcmVjb3JkIGNvdW50IGFwaSBpcyBub3QgYXZhaWxhYmxlIGZvciBjb3VjaGRiYFxuICAgICk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBzdGF0ZW1lbnQ6IFN0YXRlbWVudDxNYW5nb1F1ZXJ5PixcbiAgICBzaXplOiBudW1iZXIsXG4gICAgcmF3U3RhdGVtZW50OiBNYW5nb1F1ZXJ5XG4gICkge1xuICAgIHN1cGVyKHN0YXRlbWVudCwgc2l6ZSwgcmF3U3RhdGVtZW50KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwcmVwYXJlKHJhd1N0YXRlbWVudDogTWFuZ29RdWVyeSk6IE1hbmdvUXVlcnkge1xuICAgIGNvbnN0IHF1ZXJ5OiBNYW5nb1F1ZXJ5ID0gT2JqZWN0LmFzc2lnbih7fSwgcmF3U3RhdGVtZW50KTtcbiAgICBpZiAocXVlcnkubGltaXQpIHRoaXMubGltaXQgPSBxdWVyeS5saW1pdDtcblxuICAgIHF1ZXJ5LmxpbWl0ID0gdGhpcy5zaXplO1xuXG4gICAgcmV0dXJuIHF1ZXJ5O1xuICB9XG5cbiAgYXN5bmMgcGFnZShwYWdlOiBudW1iZXIgPSAxLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8VltdPiB7XG4gICAgY29uc3Qgc3RhdGVtZW50ID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5zdGF0ZW1lbnQpO1xuICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuc3RhdC5nZXRUYXJnZXQoKTtcbiAgICAvLyBpZiAoIXRoaXMuX3JlY29yZENvdW50IHx8ICF0aGlzLl90b3RhbFBhZ2VzKSB7XG4gICAgLy8gICAvLyB0aGlzLl9yZWNvcmRDb3VudCA9IGF3YWl0IHRoaXMuYWRhcHRlclxuICAgIC8vICAgLy8gICAuUXVlcnkoKVxuICAgIC8vICAgLy8gICAuY291bnQoKVxuICAgIC8vICAgLy8gICAuZnJvbSh0YXJnZXQpXG4gICAgLy8gICAvLyAgIC5leGVjdXRlPG51bWJlcj4oKTtcbiAgICAvLyB9XG4gICAgdGhpcy52YWxpZGF0ZVBhZ2UocGFnZSk7XG5cbiAgICBpZiAocGFnZSAhPT0gMSkge1xuICAgICAgaWYgKCF0aGlzLmJvb2tNYXJrKVxuICAgICAgICB0aHJvdyBuZXcgUGFnaW5nRXJyb3IoXCJObyBib29rbWFyay4gRGlkIHlvdSBzdGFydCBpbiB0aGUgZmlyc3QgcGFnZT9cIik7XG4gICAgICBzdGF0ZW1lbnRbXCJib29rbWFya1wiXSA9IHRoaXMuYm9va01hcms7XG4gICAgfVxuICAgIGNvbnN0IHJhd1Jlc3VsdDogTWFuZ29SZXNwb25zZTxhbnk+ID0gYXdhaXQgdGhpcy5hZGFwdGVyLnJhdyhcbiAgICAgIHN0YXRlbWVudCxcbiAgICAgIGZhbHNlLFxuICAgICAgLi4uYXJnc1xuICAgICk7XG5cbiAgICBjb25zdCB7IGRvY3MsIGJvb2ttYXJrLCB3YXJuaW5nIH0gPSByYXdSZXN1bHQ7XG4gICAgaWYgKHdhcm5pbmcpIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcbiAgICBpZiAoIXRhcmdldCkgdGhyb3cgbmV3IFBhZ2luZ0Vycm9yKFwiTm8gc3RhdGVtZW50IHRhcmdldCBkZWZpbmVkXCIpO1xuICAgIGNvbnN0IHBrRGVmID0gZmluZFByaW1hcnlLZXkobmV3IHRhcmdldCgpKSBhcyB7XG4gICAgICBpZDogc3RyaW5nO1xuICAgICAgcHJvcHM6IFNlcXVlbmNlT3B0aW9ucztcbiAgICB9O1xuICAgIGNvbnN0IHJlc3VsdHMgPVxuICAgICAgc3RhdGVtZW50LmZpZWxkcyAmJiBzdGF0ZW1lbnQuZmllbGRzLmxlbmd0aFxuICAgICAgICA/IGRvY3MgLy8gaGFzIGZpZWxkcyBtZWFucyBpdHMgbm90IGZ1bGwgbW9kZWxcbiAgICAgICAgOiBkb2NzLm1hcCgoZDogYW55KSA9PiB7XG4gICAgICAgICAgICAvL25vIGZpZWxkcyBtZWFucyB3ZSBuZWVkIHRvIHJldmVydCB0byBzYXZpbmcgcHJvY2Vzc1xuICAgICAgICAgICAgaWYgKCF0YXJnZXQpIHRocm93IG5ldyBQYWdpbmdFcnJvcihcIk5vIHN0YXRlbWVudCB0YXJnZXQgZGVmaW5lZFwiKTtcbiAgICAgICAgICAgIGNvbnN0IHBrID0gcGtEZWYuaWQ7XG4gICAgICAgICAgICBjb25zdCBvcmlnaW5hbElkID0gZC5faWQuc3BsaXQoRGVmYXVsdFNlcGFyYXRvcik7XG4gICAgICAgICAgICBvcmlnaW5hbElkLnNwbGljZSgwLCAxKTsgLy8gcmVtb3ZlIHRoZSB0YWJsZSBuYW1lXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJldmVydChcbiAgICAgICAgICAgICAgZCxcbiAgICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICAgICAgICBwayxcbiAgICAgICAgICAgICAgcGFyc2VTZXF1ZW5jZVZhbHVlKFxuICAgICAgICAgICAgICAgIHBrRGVmLnByb3BzLnR5cGUsXG4gICAgICAgICAgICAgICAgb3JpZ2luYWxJZC5qb2luKERlZmF1bHRTZXBhcmF0b3IpXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgdGhpcy5ib29rTWFyayA9IGJvb2ttYXJrO1xuICAgIHRoaXMuX2N1cnJlbnRQYWdlID0gcGFnZTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxufVxuIiwiaW1wb3J0IHsgQWRhcHRlciwgU3RhdGVtZW50IH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBmaW5kUHJpbWFyeUtleSwgSW50ZXJuYWxFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBDb3VjaERCS2V5cyB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHBhcnNlU2VxdWVuY2VWYWx1ZSB9IGZyb20gXCIuLi9zZXF1ZW5jZXMvdXRpbHNcIjtcbmltcG9ydCB7IFBhZ2luYXRvciB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgQ291Y2hEQlBhZ2luYXRvciB9IGZyb20gXCIuL1BhZ2luYXRvclwiO1xuaW1wb3J0IHsgTWFuZ29RdWVyeSB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG5leHBvcnQgY2xhc3MgQ291Y2hEQlN0YXRlbWVudDxZPiBleHRlbmRzIFN0YXRlbWVudDxNYW5nb1F1ZXJ5PiB7XG4gIGNvbnN0cnVjdG9yKGFkYXB0ZXI6IEFkYXB0ZXI8WSwgTWFuZ29RdWVyeSwgYW55LCBhbnk+KSB7XG4gICAgc3VwZXIoYWRhcHRlcik7XG4gIH1cblxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGFzeW5jIGV4ZWN1dGU8WT4oKTogUHJvbWlzZTxZPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHF1ZXJ5OiBNYW5nb1F1ZXJ5ID0gdGhpcy5idWlsZCgpO1xuICAgICAgaWYgKCFxdWVyeS5saW1pdCkgcXVlcnkubGltaXQgPSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcbiAgICAgIHJldHVybiB0aGlzLnJhdyhxdWVyeSk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihlKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBwYWdpbmF0ZTxSPihzaXplOiBudW1iZXIpOiBQcm9taXNlPFBhZ2luYXRvcjxSLCBNYW5nb1F1ZXJ5Pj4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBxdWVyeTogTWFuZ29RdWVyeSA9IHRoaXMuYnVpbGQoKTtcbiAgICAgIHJldHVybiBuZXcgQ291Y2hEQlBhZ2luYXRvcih0aGlzLCBzaXplLCBxdWVyeSk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHByb2Nlc3NSZWNvcmQoXG4gICAgcjogYW55LFxuICAgIHBrQXR0cjogc3RyaW5nLFxuICAgIHNlcXVlbmNlVHlwZTogXCJOdW1iZXJcIiB8IFwiQmlnSW50XCIgfCB1bmRlZmluZWRcbiAgKSB7XG4gICAgaWYgKCFyW0NvdWNoREJLZXlzLklEXSlcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgTm8gQ291Y2hEQiBJZCBkZWZpbml0aW9uIGZvdW5kLiBTaG91bGQgbm90IGJlIHBvc3NpYmxlYFxuICAgICAgKTtcbiAgICBjb25zdCBbLCAuLi5rZXlBcmdzXSA9IHJbQ291Y2hEQktleXMuSURdLnNwbGl0KFwiX1wiKTtcblxuICAgIGNvbnN0IGlkID0ga2V5QXJncy5qb2luKFwiX1wiKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJldmVydChcbiAgICAgIHIsXG4gICAgICB0aGlzLnRhcmdldCBhcyBDb25zdHJ1Y3Rvcjxhbnk+LFxuICAgICAgcGtBdHRyLFxuICAgICAgcGFyc2VTZXF1ZW5jZVZhbHVlKHNlcXVlbmNlVHlwZSwgaWQpXG4gICAgKSBhcyBhbnk7XG4gIH1cblxuICBhc3luYyByYXc8Uj4ocmF3SW5wdXQ6IE1hbmdvUXVlcnksIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxSPiB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMuYWRhcHRlci5yYXc8Uj4ocmF3SW5wdXQsIHRydWUsIC4uLmFyZ3MpO1xuICAgIGlmICghdGhpcy5mdWxsUmVjb3JkKSByZXR1cm4gcmVzdWx0cztcbiAgICBpZiAoIXRoaXMudGFyZ2V0KVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIFwiTm8gdGFyZ2V0IGRlZmluZWQgaW4gc3RhdGVtZW50LiBzaG91bGQgbmV2ZXIgaGFwcGVuXCJcbiAgICAgICk7XG5cbiAgICBjb25zdCBwa0RlZiA9IGZpbmRQcmltYXJ5S2V5KG5ldyB0aGlzLnRhcmdldCgpIGFzIGFueSk7XG4gICAgY29uc3QgcGtBdHRyID0gcGtEZWYuaWQ7XG4gICAgY29uc3QgdHlwZSA9IHBrRGVmLnByb3BzLnR5cGU7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocmVzdWx0cykpXG4gICAgICByZXR1cm4gcmVzdWx0cy5tYXAoKHIpID0+XG4gICAgICAgIHRoaXMucHJvY2Vzc1JlY29yZChyLCBwa0F0dHIgYXMgc3RyaW5nLCB0eXBlKVxuICAgICAgKSBhcyBSO1xuICAgIHJldHVybiB0aGlzLnByb2Nlc3NSZWNvcmQocmVzdWx0cywgcGtBdHRyIGFzIHN0cmluZywgdHlwZSkgYXMgUjtcbiAgfVxufVxuIiwiaW1wb3J0IHsgRnJvbUNsYXVzZSB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgTW9kZWxBcmcsIE1vZGVsLCBDb25zdHJ1Y3RvciB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IENvdWNoREJLZXlzIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgTWFuZ29RdWVyeSB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vLyBub2luc3BlY3Rpb24gSlNBbm5vdGF0b3JcbmV4cG9ydCBjbGFzcyBDb3VjaERCRnJvbUNsYXVzZTxNIGV4dGVuZHMgTW9kZWw+IGV4dGVuZHMgRnJvbUNsYXVzZTxcbiAgTWFuZ29RdWVyeSxcbiAgTVxuPiB7XG4gIGNvbnN0cnVjdG9yKGNsYXVzZTogTW9kZWxBcmc8RnJvbUNsYXVzZTxNYW5nb1F1ZXJ5LCBNPj4pIHtcbiAgICBzdXBlcihjbGF1c2UpO1xuICB9XG5cbiAgYnVpbGQocHJldmlvdXM6IE1hbmdvUXVlcnkpOiBNYW5nb1F1ZXJ5IHtcbiAgICBjb25zdCBzZWxlY3RvcnM6IGFueSA9IHt9O1xuICAgIHNlbGVjdG9yc1tDb3VjaERCS2V5cy5UQUJMRV0gPSB7fTtcbiAgICBzZWxlY3RvcnNbQ291Y2hEQktleXMuVEFCTEVdID1cbiAgICAgIHR5cGVvZiB0aGlzLnNlbGVjdG9yID09PSBcInN0cmluZ1wiXG4gICAgICAgID8gdGhpcy5zZWxlY3RvclxuICAgICAgICA6IFJlcG9zaXRvcnkudGFibGUodGhpcy5zZWxlY3RvciBhcyBDb25zdHJ1Y3RvcjxNPik7XG4gICAgcHJldmlvdXMuc2VsZWN0b3IgPSBzZWxlY3RvcnM7XG4gICAgcmV0dXJuIHByZXZpb3VzO1xuICB9XG59XG4iLCJpbXBvcnQgeyBJbnNlcnRDbGF1c2UgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IE1vZGVsQXJnLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IE1hbmdvUXVlcnkgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuLy8gbm9pbnNwZWN0aW9uIEpTQW5ub3RhdG9yXG5leHBvcnQgY2xhc3MgQ291Y2hEQkluc2VydENsYXVzZTxNIGV4dGVuZHMgTW9kZWw+IGV4dGVuZHMgSW5zZXJ0Q2xhdXNlPFxuICBNYW5nb1F1ZXJ5LFxuICBNXG4+IHtcbiAgY29uc3RydWN0b3IoY2xhdXNlOiBNb2RlbEFyZzxJbnNlcnRDbGF1c2U8TWFuZ29RdWVyeSwgTT4+KSB7XG4gICAgc3VwZXIoY2xhdXNlKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgYnVpbGQocXVlcnk6IE1hbmdvUXVlcnkpOiBNYW5nb1F1ZXJ5IHtcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIk5vdCBzdXBwb3J0ZWRcIik7XG4gIH1cbn1cbiIsImltcG9ydCB7IENvbmRpdGlvbiwgV2hlcmVDbGF1c2UgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IE1vZGVsQXJnIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgQ291Y2hEQkdyb3VwT3BlcmF0b3IgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHNmIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgQ291Y2hEQktleXMgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBNYW5nb09wZXJhdG9yLCBNYW5nb1F1ZXJ5LCBNYW5nb1NlbGVjdG9yIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbmV4cG9ydCBjbGFzcyBDb3VjaERCV2hlcmVDbGF1c2UgZXh0ZW5kcyBXaGVyZUNsYXVzZTxNYW5nb1F1ZXJ5PiB7XG4gIGNvbnN0cnVjdG9yKGNsYXVzZTogTW9kZWxBcmc8V2hlcmVDbGF1c2U8TWFuZ29RdWVyeT4+KSB7XG4gICAgc3VwZXIoY2xhdXNlKTtcbiAgfVxuXG4gIGJ1aWxkKHF1ZXJ5OiBNYW5nb1F1ZXJ5KTogTWFuZ29RdWVyeSB7XG4gICAgY29uc3QgY29uZGl0aW9uOiBNYW5nb1NlbGVjdG9yID0gdGhpcy5hZGFwdGVyLnBhcnNlQ29uZGl0aW9uKFxuICAgICAgQ29uZGl0aW9uLmFuZChcbiAgICAgICAgdGhpcy5jb25kaXRpb24gYXMgQ29uZGl0aW9uLFxuICAgICAgICBDb25kaXRpb24uYXR0cmlidXRlKENvdWNoREJLZXlzLlRBQkxFKS5lcShcbiAgICAgICAgICBxdWVyeS5zZWxlY3RvcltDb3VjaERCS2V5cy5UQUJMRV1cbiAgICAgICAgKVxuICAgICAgKVxuICAgICkuc2VsZWN0b3I7XG5cbiAgICBjb25zdCBzZWxlY3RvcktleXMgPSBPYmplY3Qua2V5cyhjb25kaXRpb24pIGFzIE1hbmdvT3BlcmF0b3JbXTtcbiAgICBpZiAoXG4gICAgICBzZWxlY3RvcktleXMubGVuZ3RoID09PSAxICYmXG4gICAgICBPYmplY3QudmFsdWVzKENvdWNoREJHcm91cE9wZXJhdG9yKS5pbmRleE9mKHNlbGVjdG9yS2V5c1swXSkgIT09IC0xXG4gICAgKVxuICAgICAgc3dpdGNoIChzZWxlY3RvcktleXNbMF0pIHtcbiAgICAgICAgY2FzZSBDb3VjaERCR3JvdXBPcGVyYXRvci5BTkQ6XG4gICAgICAgICAgY29uZGl0aW9uW0NvdWNoREJHcm91cE9wZXJhdG9yLkFORF0gPSBbXG4gICAgICAgICAgICAuLi5PYmplY3QudmFsdWVzKFxuICAgICAgICAgICAgICBjb25kaXRpb25bQ291Y2hEQkdyb3VwT3BlcmF0b3IuQU5EXSBhcyBNYW5nb1NlbGVjdG9yXG4gICAgICAgICAgICApLnJlZHVjZSgoYWNjdW06IE1hbmdvU2VsZWN0b3JbXSwgdmFsOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHZhbCk7XG4gICAgICAgICAgICAgIGlmIChrZXlzLmxlbmd0aCAhPT0gMSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICBcIlRvbyBtYW55IGtleXMgaW4gcXVlcnkgc2VsZWN0b3IuIHNob3VsZCBiZSBvbmVcIlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGNvbnN0IGsgPSBrZXlzWzBdO1xuICAgICAgICAgICAgICBpZiAoayA9PT0gQ291Y2hEQkdyb3VwT3BlcmF0b3IuQU5EKVxuICAgICAgICAgICAgICAgIGFjY3VtLnB1c2goLi4uKHZhbFtrXSBhcyBhbnlbXSkpO1xuICAgICAgICAgICAgICBlbHNlIGFjY3VtLnB1c2godmFsKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgICAgICAgfSwgW10pLFxuICAgICAgICAgIF07XG4gICAgICAgICAgcXVlcnkuc2VsZWN0b3IgPSBjb25kaXRpb247XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgQ291Y2hEQkdyb3VwT3BlcmF0b3IuT1I6IHtcbiAgICAgICAgICBjb25zdCBzOiBSZWNvcmQ8YW55LCBhbnk+ID0ge307XG4gICAgICAgICAgc1tDb3VjaERCR3JvdXBPcGVyYXRvci5BTkRdID0gW1xuICAgICAgICAgICAgY29uZGl0aW9uLFxuICAgICAgICAgICAgLi4uT2JqZWN0LmVudHJpZXMocXVlcnkuc2VsZWN0b3IpLm1hcCgoW2tleSwgdmFsXSkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCByZXN1bHQ6IFJlY29yZDxhbnksIGFueT4gPSB7fTtcbiAgICAgICAgICAgICAgcmVzdWx0W2tleV0gPSB2YWw7XG4gICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBdO1xuICAgICAgICAgIHF1ZXJ5LnNlbGVjdG9yID0gcztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgc2hvdWxkIGJlIGltcG9zc2libGVcIik7XG4gICAgICB9XG4gICAgZWxzZSB7XG4gICAgICBPYmplY3QuZW50cmllcyhjb25kaXRpb24pLmZvckVhY2goKFtrZXksIHZhbF0pID0+IHtcbiAgICAgICAgaWYgKHF1ZXJ5LnNlbGVjdG9yW2tleV0pXG4gICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgc2YoXG4gICAgICAgICAgICAgIFwiQSB7MH0gcXVlcnkgcGFyYW0gaXMgYWJvdXQgdG8gYmUgb3ZlcnJpZGRlbjogezF9IGJ5IHsyfVwiLFxuICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgIHF1ZXJ5LnNlbGVjdG9yW2tleV0gYXMgdW5rbm93biBhcyBzdHJpbmcsXG4gICAgICAgICAgICAgIHZhbCBhcyB1bmtub3duIGFzIHN0cmluZ1xuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgIHF1ZXJ5LnNlbGVjdG9yW2tleV0gPSB2YWw7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcXVlcnk7XG4gIH1cbn1cbiIsImltcG9ydCB7IENvbnN0LCBTZWxlY3RDbGF1c2UgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IE1vZGVsQXJnLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IE1hbmdvUXVlcnkgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuZXhwb3J0IGNsYXNzIENvdWNoREJTZWxlY3RDbGF1c2U8TSBleHRlbmRzIE1vZGVsPiBleHRlbmRzIFNlbGVjdENsYXVzZTxcbiAgTWFuZ29RdWVyeSxcbiAgTVxuPiB7XG4gIGNvbnN0cnVjdG9yKGNsYXVzZTogTW9kZWxBcmc8U2VsZWN0Q2xhdXNlPE1hbmdvUXVlcnksIE0+Pikge1xuICAgIHN1cGVyKGNsYXVzZSk7XG4gIH1cblxuICBidWlsZChxdWVyeTogTWFuZ29RdWVyeSk6IE1hbmdvUXVlcnkge1xuICAgIGlmICghdGhpcy5zZWxlY3RvciB8fCB0aGlzLnNlbGVjdG9yID09PSBDb25zdC5GVUxMX1JFQ09SRCkgcmV0dXJuIHF1ZXJ5O1xuICAgIHF1ZXJ5LmZpZWxkcyA9XG4gICAgICB0eXBlb2YgdGhpcy5zZWxlY3RvciA9PT0gXCJzdHJpbmdcIlxuICAgICAgICA/IFt0aGlzLnNlbGVjdG9yIGFzIHN0cmluZ11cbiAgICAgICAgOiAodGhpcy5zZWxlY3RvciBhcyBzdHJpbmdbXSk7XG4gICAgcmV0dXJuIHF1ZXJ5O1xuICB9XG59XG4iLCJpbXBvcnQgeyBWYWx1ZXNDbGF1c2UgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IE1vZGVsQXJnLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IE1hbmdvUXVlcnkgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuZXhwb3J0IGNsYXNzIENvdWNoREJWYWx1ZXNDbGF1c2U8TSBleHRlbmRzIE1vZGVsPiBleHRlbmRzIFZhbHVlc0NsYXVzZTxcbiAgTWFuZ29RdWVyeSxcbiAgTVxuPiB7XG4gIGNvbnN0cnVjdG9yKGNsYXVzZTogTW9kZWxBcmc8VmFsdWVzQ2xhdXNlPE1hbmdvUXVlcnksIE0+Pikge1xuICAgIHN1cGVyKGNsYXVzZSk7XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGJ1aWxkKHByZXZpb3VzOiBNYW5nb1F1ZXJ5KTogTWFuZ29RdWVyeSB7XG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJOb3QgaW1wbGVtZW50ZWRcIik7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIENsYXVzZUZhY3RvcnksXG4gIENvbmRpdGlvbixcbiAgRnJvbUNsYXVzZSxcbiAgRnJvbVNlbGVjdG9yLFxuICBHcm91cEJ5U2VsZWN0b3IsXG4gIExpbWl0U2VsZWN0b3IsXG4gIE9mZnNldFNlbGVjdG9yLFxuICBPcmRlckJ5U2VsZWN0b3IsXG4gIFF1ZXJ5RXJyb3IsXG4gIFNlbGVjdFNlbGVjdG9yLFxuICBTdGF0ZW1lbnQsXG59IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgTGltaXRDbGF1c2UgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IFNlbGVjdENsYXVzZSB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgV2hlcmVDbGF1c2UgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IE9mZnNldENsYXVzZSB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgT3JkZXJCeUNsYXVzZSB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgR3JvdXBCeUNsYXVzZSB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgVmFsdWVzQ2xhdXNlIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBJbnNlcnRDbGF1c2UgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IENvdWNoREJGcm9tQ2xhdXNlIH0gZnJvbSBcIi4vRnJvbUNsYXVzZVwiO1xuaW1wb3J0IHsgTW9kZWxBcmcsIE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHtcbiAgQ29udGV4dCxcbiAgSW50ZXJuYWxFcnJvcixcbiAgUmVwb3NpdG9yeUZsYWdzLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IENvdWNoREJJbnNlcnRDbGF1c2UgfSBmcm9tIFwiLi9JbnNlcnRDbGF1c2VcIjtcbmltcG9ydCB7IENvdWNoREJTdGF0ZW1lbnQgfSBmcm9tIFwiLi9TdGF0ZW1lbnRcIjtcbmltcG9ydCB7IENvdWNoREJXaGVyZUNsYXVzZSB9IGZyb20gXCIuL1doZXJlQ2xhdXNlXCI7XG5pbXBvcnQgeyBDb3VjaERCU2VsZWN0Q2xhdXNlIH0gZnJvbSBcIi4vU2VsZWN0Q2xhdXNlXCI7XG5pbXBvcnQgeyBDb3VjaERCVmFsdWVzQ2xhdXNlIH0gZnJvbSBcIi4vVmFsdWVzQ2xhdXNlXCI7XG5pbXBvcnQgeyBDb3VjaERCT3BlcmF0b3IgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IENvdWNoREJBZGFwdGVyIH0gZnJvbSBcIi4uL2FkYXB0ZXJcIjtcbmltcG9ydCB7IE1hbmdvUXVlcnksIE1hbmdvU2VsZWN0b3IgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuZXhwb3J0IGNsYXNzIEZhY3Rvcnk8XG4gIFksXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPiBleHRlbmRzIENsYXVzZUZhY3Rvcnk8WSwgTWFuZ29RdWVyeSwgQ291Y2hEQkFkYXB0ZXI8WSwgRiwgQz4+IHtcbiAgY29uc3RydWN0b3IoYWRhcHRlcjogQ291Y2hEQkFkYXB0ZXI8WSwgRiwgQz4pIHtcbiAgICBzdXBlcihhZGFwdGVyKTtcbiAgfVxuXG4gIGZyb208TSBleHRlbmRzIE1vZGVsPihcbiAgICBzdGF0ZW1lbnQ6IFN0YXRlbWVudDxNYW5nb1F1ZXJ5PixcbiAgICBzZWxlY3RvcjogRnJvbVNlbGVjdG9yPE0+XG4gICk6IEZyb21DbGF1c2U8TWFuZ29RdWVyeSwgTT4ge1xuICAgIHJldHVybiBuZXcgQ291Y2hEQkZyb21DbGF1c2UoeyBzdGF0ZW1lbnQ6IHN0YXRlbWVudCwgc2VsZWN0b3I6IHNlbGVjdG9yIH0pO1xuICB9XG5cbiAgZ3JvdXBCeShcbiAgICBzdGF0ZW1lbnQ6IFN0YXRlbWVudDxNYW5nb1F1ZXJ5PixcbiAgICBzZWxlY3RvcjogR3JvdXBCeVNlbGVjdG9yXG4gICk6IEdyb3VwQnlDbGF1c2U8TWFuZ29RdWVyeT4ge1xuICAgIHJldHVybiBuZXcgKGNsYXNzIGV4dGVuZHMgR3JvdXBCeUNsYXVzZTxNYW5nb1F1ZXJ5PiB7XG4gICAgICBjb25zdHJ1Y3RvcihjbGF1c2U6IE1vZGVsQXJnPEdyb3VwQnlDbGF1c2U8TWFuZ29RdWVyeT4+KSB7XG4gICAgICAgIHN1cGVyKGNsYXVzZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgIGJ1aWxkKHF1ZXJ5OiBNYW5nb1F1ZXJ5KTogTWFuZ29RdWVyeSB7XG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiTm90IGltcGxlbWVudGVkXCIpO1xuICAgICAgfVxuICAgIH0pKHtcbiAgICAgIHN0YXRlbWVudDogc3RhdGVtZW50LFxuICAgICAgc2VsZWN0b3I6IHNlbGVjdG9yLFxuICAgIH0pO1xuICB9XG5cbiAgaW5zZXJ0PE0gZXh0ZW5kcyBNb2RlbD4oKTogSW5zZXJ0Q2xhdXNlPE1hbmdvUXVlcnksIE0+IHtcbiAgICByZXR1cm4gbmV3IENvdWNoREJJbnNlcnRDbGF1c2Uoe1xuICAgICAgc3RhdGVtZW50OiBuZXcgQ291Y2hEQlN0YXRlbWVudCh0aGlzLmFkYXB0ZXIpLFxuICAgIH0pO1xuICB9XG5cbiAgbGltaXQoXG4gICAgc3RhdGVtZW50OiBTdGF0ZW1lbnQ8TWFuZ29RdWVyeT4sXG4gICAgc2VsZWN0b3I6IExpbWl0U2VsZWN0b3JcbiAgKTogTGltaXRDbGF1c2U8TWFuZ29RdWVyeT4ge1xuICAgIHJldHVybiBuZXcgKGNsYXNzIGV4dGVuZHMgTGltaXRDbGF1c2U8TWFuZ29RdWVyeT4ge1xuICAgICAgY29uc3RydWN0b3IoY2xhdXNlOiBNb2RlbEFyZzxMaW1pdENsYXVzZTxNYW5nb1F1ZXJ5Pj4pIHtcbiAgICAgICAgc3VwZXIoY2xhdXNlKTtcbiAgICAgIH1cblxuICAgICAgYnVpbGQocXVlcnk6IE1hbmdvUXVlcnkpOiBNYW5nb1F1ZXJ5IHtcbiAgICAgICAgcXVlcnkubGltaXQgPSB0aGlzLnNlbGVjdG9yIGFzIG51bWJlcjtcbiAgICAgICAgcmV0dXJuIHF1ZXJ5O1xuICAgICAgfVxuICAgIH0pKHtcbiAgICAgIHN0YXRlbWVudDogc3RhdGVtZW50LFxuICAgICAgc2VsZWN0b3I6IHNlbGVjdG9yLFxuICAgIH0pO1xuICB9XG5cbiAgb2Zmc2V0KFxuICAgIHN0YXRlbWVudDogU3RhdGVtZW50PE1hbmdvUXVlcnk+LFxuICAgIHNlbGVjdG9yOiBPZmZzZXRTZWxlY3RvclxuICApOiBPZmZzZXRDbGF1c2U8TWFuZ29RdWVyeT4ge1xuICAgIHJldHVybiBuZXcgKGNsYXNzIGV4dGVuZHMgT2Zmc2V0Q2xhdXNlPE1hbmdvUXVlcnk+IHtcbiAgICAgIGNvbnN0cnVjdG9yKGNsYXVzZTogTW9kZWxBcmc8T2Zmc2V0Q2xhdXNlPE1hbmdvUXVlcnk+Pikge1xuICAgICAgICBzdXBlcihjbGF1c2UpO1xuICAgICAgfVxuXG4gICAgICBidWlsZChxdWVyeTogTWFuZ29RdWVyeSk6IE1hbmdvUXVlcnkge1xuICAgICAgICBjb25zdCBza2lwOiBudW1iZXIgPSBwYXJzZUludCh0aGlzLnNlbGVjdG9yIGFzIHVua25vd24gYXMgc3RyaW5nKTtcbiAgICAgICAgaWYgKGlzTmFOKHNraXApKSB0aHJvdyBuZXcgUXVlcnlFcnJvcihcIkZhaWxlZCB0byBwYXJzZSBvZmZzZXRcIik7XG4gICAgICAgIHF1ZXJ5LnNraXAgPSBza2lwO1xuICAgICAgICByZXR1cm4gcXVlcnk7XG4gICAgICB9XG4gICAgfSkoe1xuICAgICAgc3RhdGVtZW50OiBzdGF0ZW1lbnQsXG4gICAgICBzZWxlY3Rvcjogc2VsZWN0b3IsXG4gICAgfSk7XG4gIH1cblxuICBvcmRlckJ5KFxuICAgIHN0YXRlbWVudDogU3RhdGVtZW50PE1hbmdvUXVlcnk+LFxuICAgIHNlbGVjdG9yOiBPcmRlckJ5U2VsZWN0b3JbXVxuICApOiBPcmRlckJ5Q2xhdXNlPE1hbmdvUXVlcnk+IHtcbiAgICByZXR1cm4gbmV3IChjbGFzcyBleHRlbmRzIE9yZGVyQnlDbGF1c2U8TWFuZ29RdWVyeT4ge1xuICAgICAgY29uc3RydWN0b3IoY2xhdXNlOiBNb2RlbEFyZzxPcmRlckJ5Q2xhdXNlPE1hbmdvUXVlcnk+Pikge1xuICAgICAgICBzdXBlcihjbGF1c2UpO1xuICAgICAgfVxuXG4gICAgICBidWlsZChxdWVyeTogTWFuZ29RdWVyeSk6IE1hbmdvUXVlcnkge1xuICAgICAgICBxdWVyeS5zb3J0ID0gcXVlcnkuc29ydCB8fCBbXTtcbiAgICAgICAgcXVlcnkuc2VsZWN0b3IgPSBxdWVyeS5zZWxlY3RvciB8fCAoe30gYXMgTWFuZ29TZWxlY3Rvcik7XG4gICAgICAgIHRoaXMuc2VsZWN0b3IhLmZvckVhY2goKHMpID0+IHtcbiAgICAgICAgICBjb25zdCBbc2VsZWN0b3IsIHZhbHVlXSA9IHM7XG4gICAgICAgICAgY29uc3QgcmVjOiBhbnkgPSB7fTtcbiAgICAgICAgICByZWNbc2VsZWN0b3JdID0gdmFsdWU7XG4gICAgICAgICAgKHF1ZXJ5LnNvcnQgYXMgYW55W10pLnB1c2gocmVjIGFzIGFueSk7XG4gICAgICAgICAgaWYgKCFxdWVyeS5zZWxlY3RvcltzZWxlY3Rvcl0pIHtcbiAgICAgICAgICAgIHF1ZXJ5LnNlbGVjdG9yW3NlbGVjdG9yXSA9IHt9IGFzIE1hbmdvU2VsZWN0b3I7XG4gICAgICAgICAgICAocXVlcnkuc2VsZWN0b3Jbc2VsZWN0b3JdIGFzIE1hbmdvU2VsZWN0b3IpW1xuICAgICAgICAgICAgICBDb3VjaERCT3BlcmF0b3IuQklHR0VSXG4gICAgICAgICAgICBdID0gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gcXVlcnkuZmllbGRzID0gcXVlcnkuZmllbGRzIHx8IFtdO1xuICAgICAgICAgIC8vIHF1ZXJ5LmZpZWxkcyA9IFsuLi5uZXcgU2V0KFsuLi5xdWVyeS5maWVsZHMsIHNlbGVjdG9yXSkua2V5cygpXVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHF1ZXJ5O1xuICAgICAgfVxuICAgIH0pKHtcbiAgICAgIHN0YXRlbWVudDogc3RhdGVtZW50LFxuICAgICAgc2VsZWN0b3I6IHNlbGVjdG9yLFxuICAgIH0pO1xuICB9XG5cbiAgc2VsZWN0PE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgc2VsZWN0b3I6IFNlbGVjdFNlbGVjdG9yIHwgdW5kZWZpbmVkXG4gICk6IFNlbGVjdENsYXVzZTxNYW5nb1F1ZXJ5LCBNPiB7XG4gICAgcmV0dXJuIG5ldyBDb3VjaERCU2VsZWN0Q2xhdXNlKHtcbiAgICAgIHN0YXRlbWVudDogbmV3IENvdWNoREJTdGF0ZW1lbnQodGhpcy5hZGFwdGVyKSxcbiAgICAgIHNlbGVjdG9yOiBzZWxlY3RvcixcbiAgICB9KTtcbiAgfVxuXG4gIHZhbHVlczxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIHN0YXRlbWVudDogU3RhdGVtZW50PE1hbmdvUXVlcnk+LFxuICAgIHZhbHVlczogTVtdXG4gICk6IFZhbHVlc0NsYXVzZTxNYW5nb1F1ZXJ5LCBNPiB7XG4gICAgcmV0dXJuIG5ldyBDb3VjaERCVmFsdWVzQ2xhdXNlPE0+KHtcbiAgICAgIHN0YXRlbWVudDogc3RhdGVtZW50LFxuICAgICAgdmFsdWVzOiB2YWx1ZXMsXG4gICAgfSk7XG4gIH1cblxuICB3aGVyZShcbiAgICBzdGF0ZW1lbnQ6IFN0YXRlbWVudDxNYW5nb1F1ZXJ5PixcbiAgICBjb25kaXRpb246IENvbmRpdGlvblxuICApOiBXaGVyZUNsYXVzZTxNYW5nb1F1ZXJ5PiB7XG4gICAgcmV0dXJuIG5ldyBDb3VjaERCV2hlcmVDbGF1c2Uoe1xuICAgICAgc3RhdGVtZW50OiBzdGF0ZW1lbnQsXG4gICAgICBjb25kaXRpb246IGNvbmRpdGlvbixcbiAgICB9KTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgR3JvdXBPcGVyYXRvciwgT3BlcmF0b3IgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IENvdWNoREJHcm91cE9wZXJhdG9yLCBDb3VjaERCT3BlcmF0b3IgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFF1ZXJ5RXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IE1hbmdvT3BlcmF0b3IgfSBmcm9tIFwiLi4vdHlwZXNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zbGF0ZU9wZXJhdG9ycyhcbiAgb3BlcmF0b3I6IEdyb3VwT3BlcmF0b3IgfCBPcGVyYXRvclxuKTogTWFuZ29PcGVyYXRvciB7XG4gIGZvciAoY29uc3Qgb3BlcmF0b3JzIG9mIFtDb3VjaERCT3BlcmF0b3IsIENvdWNoREJHcm91cE9wZXJhdG9yXSkge1xuICAgIGNvbnN0IGVsID0gT2JqZWN0LmtleXMob3BlcmF0b3JzKS5maW5kKChrKSA9PiBrID09PSBvcGVyYXRvcik7XG4gICAgaWYgKGVsKSByZXR1cm4gb3BlcmF0b3JzW2VsXTtcbiAgfVxuICB0aHJvdyBuZXcgUXVlcnlFcnJvcihcbiAgICBgQ291bGQgbm90IGZpbmQgYWRhcHRlciB0cmFuc2xhdGlvbiBmb3Igb3BlcmF0b3IgJHtvcGVyYXRvcn1gXG4gICk7XG59XG4iLCJpbXBvcnQgeyBCYXNlRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuZXhwb3J0IGNsYXNzIEluZGV4RXJyb3IgZXh0ZW5kcyBCYXNlRXJyb3Ige1xuICBjb25zdHJ1Y3Rvcihtc2c6IHN0cmluZyB8IEVycm9yKSB7XG4gICAgc3VwZXIoSW5kZXhFcnJvci5uYW1lLCBtc2cpO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBBZGFwdGVyLFxuICBTZXF1ZW5jZSxcbiAgU2VxdWVuY2VPcHRpb25zLFxuICBQZXJzaXN0ZW5jZUtleXMsXG4gIE9wZXJhdG9yLFxuICBHcm91cE9wZXJhdG9yLFxuICBTdGF0ZW1lbnQsXG4gIFF1ZXJ5LFxuICBDbGF1c2VGYWN0b3J5LFxuICBDb25kaXRpb24sXG4gIENvbm5lY3Rpb25FcnJvcixcbiAgUmVwb3NpdG9yeSxcbn0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBDb3VjaERCS2V5cywgcmVzZXJ2ZWRBdHRyaWJ1dGVzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQge1xuICBCYXNlRXJyb3IsXG4gIENvbmZsaWN0RXJyb3IsXG4gIENvbnRleHQsXG4gIEludGVybmFsRXJyb3IsXG4gIE5vdEZvdW5kRXJyb3IsXG4gIHByZWZpeE1ldGhvZCxcbiAgUmVwb3NpdG9yeUZsYWdzLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCBcInJlZmxlY3QtbWV0YWRhdGFcIjtcbmltcG9ydCB7IENvdWNoREJTdGF0ZW1lbnQgfSBmcm9tIFwiLi9xdWVyeS9TdGF0ZW1lbnRcIjtcbmltcG9ydCB7IEZhY3RvcnkgfSBmcm9tIFwiLi9xdWVyeVwiO1xuaW1wb3J0IHsgdHJhbnNsYXRlT3BlcmF0b3JzIH0gZnJvbSBcIi4vcXVlcnkvdHJhbnNsYXRlXCI7XG5pbXBvcnQgeyBDb3VjaERCU2VxdWVuY2UgfSBmcm9tIFwiLi9zZXF1ZW5jZXMvU2VxdWVuY2VcIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEluZGV4RXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB7IE1hbmdvT3BlcmF0b3IsIE1hbmdvUXVlcnksIE1hbmdvU2VsZWN0b3IgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQ291Y2hEQkFkYXB0ZXI8XG4gIFksXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuPiBleHRlbmRzIEFkYXB0ZXI8WSwgTWFuZ29RdWVyeSwgRiwgQz4ge1xuICBwcm90ZWN0ZWQgZmFjdG9yeT86IEZhY3Rvcnk8WSwgRiwgQz47XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHNjb3BlOiBZLCBmbGF2b3VyOiBzdHJpbmcpIHtcbiAgICBzdXBlcihzY29wZSwgZmxhdm91cik7XG4gICAgW3RoaXMuY3JlYXRlLCB0aGlzLmNyZWF0ZUFsbCwgdGhpcy51cGRhdGUsIHRoaXMudXBkYXRlQWxsXS5mb3JFYWNoKChtKSA9PiB7XG4gICAgICBjb25zdCBuYW1lID0gbS5uYW1lO1xuICAgICAgcHJlZml4TWV0aG9kKHRoaXMsIG0sICh0aGlzIGFzIGFueSlbbmFtZSArIFwiUHJlZml4XCJdKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBDbGF1c2VzKCk6IENsYXVzZUZhY3Rvcnk8WSwgTWFuZ29RdWVyeSwgdHlwZW9mIHRoaXM+IHtcbiAgICBpZiAoIXRoaXMuZmFjdG9yeSkgdGhpcy5mYWN0b3J5ID0gbmV3IEZhY3RvcnkodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMuZmFjdG9yeSBhcyBDbGF1c2VGYWN0b3J5PFksIE1hbmdvUXVlcnksIHR5cGVvZiB0aGlzPjtcbiAgfVxuXG4gIFF1ZXJ5PE0gZXh0ZW5kcyBNb2RlbD4oKTogUXVlcnk8TWFuZ29RdWVyeSwgTT4ge1xuICAgIHJldHVybiBzdXBlci5RdWVyeSgpO1xuICB9XG5cbiAgZ2V0IFN0YXRlbWVudCgpOiBTdGF0ZW1lbnQ8TWFuZ29RdWVyeT4ge1xuICAgIHJldHVybiBuZXcgQ291Y2hEQlN0YXRlbWVudCh0aGlzKTtcbiAgfVxuXG4gIHBhcnNlQ29uZGl0aW9uKGNvbmRpdGlvbjogQ29uZGl0aW9uKTogTWFuZ29RdWVyeSB7XG4gICAgZnVuY3Rpb24gbWVyZ2UoXG4gICAgICBvcDogTWFuZ29PcGVyYXRvcixcbiAgICAgIG9iajE6IE1hbmdvU2VsZWN0b3IsXG4gICAgICBvYmoyOiBNYW5nb1NlbGVjdG9yXG4gICAgKTogTWFuZ29RdWVyeSB7XG4gICAgICBjb25zdCByZXN1bHQ6IE1hbmdvUXVlcnkgPSB7IHNlbGVjdG9yOiB7fSBhcyBNYW5nb1NlbGVjdG9yIH07XG4gICAgICByZXN1bHQuc2VsZWN0b3Jbb3BdID0gW29iajEsIG9iajJdO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBjb25zdCB7IGF0dHIxLCBvcGVyYXRvciwgY29tcGFyaXNvbiB9ID0gY29uZGl0aW9uIGFzIHVua25vd24gYXMge1xuICAgICAgYXR0cjE6IHN0cmluZyB8IENvbmRpdGlvbjtcbiAgICAgIG9wZXJhdG9yOiBPcGVyYXRvciB8IEdyb3VwT3BlcmF0b3I7XG4gICAgICBjb21wYXJpc29uOiBhbnk7XG4gICAgfTtcblxuICAgIGxldCBvcDogTWFuZ29TZWxlY3RvciA9IHt9IGFzIE1hbmdvU2VsZWN0b3I7XG4gICAgaWYgKFxuICAgICAgW0dyb3VwT3BlcmF0b3IuQU5ELCBHcm91cE9wZXJhdG9yLk9SLCBPcGVyYXRvci5OT1RdLmluZGV4T2YoXG4gICAgICAgIG9wZXJhdG9yIGFzIEdyb3VwT3BlcmF0b3JcbiAgICAgICkgPT09IC0xXG4gICAgKSB7XG4gICAgICBvcFthdHRyMSBhcyBzdHJpbmddID0ge30gYXMgTWFuZ29TZWxlY3RvcjtcbiAgICAgIChvcFthdHRyMSBhcyBzdHJpbmddIGFzIE1hbmdvU2VsZWN0b3IpW3RyYW5zbGF0ZU9wZXJhdG9ycyhvcGVyYXRvcildID1cbiAgICAgICAgY29tcGFyaXNvbjtcbiAgICB9IGVsc2UgaWYgKG9wZXJhdG9yID09PSBPcGVyYXRvci5OT1QpIHtcbiAgICAgIG9wID0gdGhpcy5wYXJzZUNvbmRpdGlvbihhdHRyMSBhcyBDb25kaXRpb24pLnNlbGVjdG9yIGFzIE1hbmdvU2VsZWN0b3I7XG4gICAgICBvcFt0cmFuc2xhdGVPcGVyYXRvcnMoT3BlcmF0b3IuTk9UKV0gPSB7fSBhcyBNYW5nb1NlbGVjdG9yO1xuICAgICAgKG9wW3RyYW5zbGF0ZU9wZXJhdG9ycyhPcGVyYXRvci5OT1QpXSBhcyBNYW5nb1NlbGVjdG9yKVtcbiAgICAgICAgKGF0dHIxIGFzIHVua25vd24gYXMgeyBhdHRyMTogc3RyaW5nIH0pLmF0dHIxXG4gICAgICBdID0gY29tcGFyaXNvbjtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgb3AxOiBhbnkgPSB0aGlzLnBhcnNlQ29uZGl0aW9uKGF0dHIxIGFzIENvbmRpdGlvbikuc2VsZWN0b3I7XG4gICAgICBjb25zdCBvcDI6IGFueSA9IHRoaXMucGFyc2VDb25kaXRpb24oY29tcGFyaXNvbiBhcyBDb25kaXRpb24pLnNlbGVjdG9yO1xuICAgICAgb3AgPSBtZXJnZSh0cmFuc2xhdGVPcGVyYXRvcnMob3BlcmF0b3IpLCBvcDEsIG9wMikuc2VsZWN0b3I7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgc2VsZWN0b3I6IG9wIH07XG4gIH1cblxuICBhc3luYyBTZXF1ZW5jZShvcHRpb25zOiBTZXF1ZW5jZU9wdGlvbnMpOiBQcm9taXNlPFNlcXVlbmNlPiB7XG4gICAgcmV0dXJuIG5ldyBDb3VjaERCU2VxdWVuY2Uob3B0aW9ucywgdGhpcyk7XG4gIH1cblxuICBhc3luYyBpbml0aWFsaXplKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG1hbmFnZWRNb2RlbHMgPSBBZGFwdGVyLm1vZGVscyh0aGlzLmZsYXZvdXIpO1xuICAgIHJldHVybiB0aGlzLmluZGV4KC4uLm1hbmFnZWRNb2RlbHMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGluZGV4PE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgLi4ubW9kZWxzOiBDb25zdHJ1Y3RvcjxNPltdXG4gICk6IFByb21pc2U8dm9pZD47XG5cbiAgYWJzdHJhY3QgcmF3PFY+KHJhd0lucHV0OiBNYW5nb1F1ZXJ5LCBwcm9jZXNzOiBib29sZWFuKTogUHJvbWlzZTxWPjtcblxuICBwcm90ZWN0ZWQgYXNzaWduTWV0YWRhdGEoXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgcmV2OiBzdHJpbmdcbiAgKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZGVsLCBQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEEsIHtcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIHZhbHVlOiByZXYsXG4gICAgfSk7XG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzc2lnbk11bHRpcGxlTWV0YWRhdGEoXG4gICAgbW9kZWxzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W10sXG4gICAgcmV2czogc3RyaW5nW11cbiAgKTogUmVjb3JkPHN0cmluZywgYW55PltdIHtcbiAgICBtb2RlbHMuZm9yRWFjaCgobSwgaSkgPT4ge1xuICAgICAgUmVwb3NpdG9yeS5zZXRNZXRhZGF0YShtIGFzIGFueSwgcmV2c1tpXSk7XG4gICAgICByZXR1cm4gbTtcbiAgICB9KTtcbiAgICByZXR1cm4gbW9kZWxzO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZVByZWZpeChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICkge1xuICAgIGNvbnN0IHJlY29yZDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgIHJlY29yZFtDb3VjaERCS2V5cy5UQUJMRV0gPSB0YWJsZU5hbWU7XG4gICAgcmVjb3JkW0NvdWNoREJLZXlzLklEXSA9IHRoaXMuZ2VuZXJhdGVJZCh0YWJsZU5hbWUsIGlkKTtcbiAgICBPYmplY3QuYXNzaWduKHJlY29yZCwgbW9kZWwpO1xuICAgIHJldHVybiBbdGFibGVOYW1lLCBpZCwgcmVjb3JkXTtcbiAgfVxuXG4gIGFic3RyYWN0IGNyZWF0ZShcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj47XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZUFsbFByZWZpeChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZHM6IHN0cmluZ1tdIHwgbnVtYmVyW10sXG4gICAgbW9kZWxzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W11cbiAgKSB7XG4gICAgaWYgKGlkcy5sZW5ndGggIT09IG1vZGVscy5sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIklkcyBhbmQgbW9kZWxzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGhcIik7XG5cbiAgICBjb25zdCByZWNvcmRzID0gaWRzLm1hcCgoaWQsIGNvdW50KSA9PiB7XG4gICAgICBjb25zdCByZWNvcmQ6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICAgIHJlY29yZFtDb3VjaERCS2V5cy5UQUJMRV0gPSB0YWJsZU5hbWU7XG4gICAgICByZWNvcmRbQ291Y2hEQktleXMuSURdID0gdGhpcy5nZW5lcmF0ZUlkKHRhYmxlTmFtZSwgaWQpO1xuICAgICAgT2JqZWN0LmFzc2lnbihyZWNvcmQsIG1vZGVsc1tjb3VudF0pO1xuICAgICAgcmV0dXJuIHJlY29yZDtcbiAgICB9KTtcbiAgICByZXR1cm4gW3RhYmxlTmFtZSwgaWRzLCByZWNvcmRzXTtcbiAgfVxuXG4gIGFic3RyYWN0IGNyZWF0ZUFsbChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZHM6IHN0cmluZ1tdIHwgbnVtYmVyW10sXG4gICAgbW9kZWxzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+O1xuXG4gIGFic3RyYWN0IHJlYWQoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlclxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+O1xuXG4gIGFic3RyYWN0IHJlYWRBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWRzOiAoc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50KVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPjtcblxuICB1cGRhdGVQcmVmaXgoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlcixcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PlxuICApIHtcbiAgICBjb25zdCByZWNvcmQ6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICByZWNvcmRbQ291Y2hEQktleXMuVEFCTEVdID0gdGFibGVOYW1lO1xuICAgIHJlY29yZFtDb3VjaERCS2V5cy5JRF0gPSB0aGlzLmdlbmVyYXRlSWQodGFibGVOYW1lLCBpZCk7XG4gICAgY29uc3QgcmV2ID0gbW9kZWxbUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXTtcbiAgICBpZiAoIXJldilcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgTm8gcmV2aXNpb24gbnVtYmVyIGZvdW5kIGZvciByZWNvcmQgd2l0aCBpZCAke2lkfWBcbiAgICAgICk7XG4gICAgT2JqZWN0LmFzc2lnbihyZWNvcmQsIG1vZGVsKTtcbiAgICByZWNvcmRbQ291Y2hEQktleXMuUkVWXSA9IHJldjtcbiAgICByZXR1cm4gW3RhYmxlTmFtZSwgaWQsIHJlY29yZF07XG4gIH1cblxuICBhYnN0cmFjdCB1cGRhdGUoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlcixcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PlxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+O1xuXG4gIHByb3RlY3RlZCB1cGRhdGVBbGxQcmVmaXgoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWRzOiBzdHJpbmdbXSB8IG51bWJlcltdLFxuICAgIG1vZGVsczogUmVjb3JkPHN0cmluZywgYW55PltdXG4gICkge1xuICAgIGlmIChpZHMubGVuZ3RoICE9PSBtb2RlbHMubGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJJZHMgYW5kIG1vZGVscyBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoXCIpO1xuXG4gICAgY29uc3QgcmVjb3JkcyA9IGlkcy5tYXAoKGlkLCBjb3VudCkgPT4ge1xuICAgICAgY29uc3QgcmVjb3JkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgICByZWNvcmRbQ291Y2hEQktleXMuVEFCTEVdID0gdGFibGVOYW1lO1xuICAgICAgcmVjb3JkW0NvdWNoREJLZXlzLklEXSA9IHRoaXMuZ2VuZXJhdGVJZCh0YWJsZU5hbWUsIGlkKTtcbiAgICAgIGNvbnN0IHJldiA9IG1vZGVsc1tjb3VudF1bUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXTtcbiAgICAgIGlmICghcmV2KVxuICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgICBgTm8gcmV2aXNpb24gbnVtYmVyIGZvdW5kIGZvciByZWNvcmQgd2l0aCBpZCAke2lkfWBcbiAgICAgICAgKTtcbiAgICAgIE9iamVjdC5hc3NpZ24ocmVjb3JkLCBtb2RlbHNbY291bnRdKTtcbiAgICAgIHJlY29yZFtDb3VjaERCS2V5cy5SRVZdID0gcmV2O1xuICAgICAgcmV0dXJuIHJlY29yZDtcbiAgICB9KTtcbiAgICByZXR1cm4gW3RhYmxlTmFtZSwgaWRzLCByZWNvcmRzXTtcbiAgfVxuXG4gIGFic3RyYWN0IHVwZGF0ZUFsbChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZHM6IHN0cmluZ1tdIHwgbnVtYmVyW10sXG4gICAgbW9kZWxzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+O1xuXG4gIGFic3RyYWN0IGRlbGV0ZShcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj47XG5cbiAgYWJzdHJhY3QgZGVsZXRlQWxsKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkczogKHN0cmluZyB8IG51bWJlciB8IGJpZ2ludClbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT5bXT47XG5cbiAgcHJvdGVjdGVkIGdlbmVyYXRlSWQodGFibGVOYW1lOiBzdHJpbmcsIGlkOiBzdHJpbmcgfCBudW1iZXIpIHtcbiAgICByZXR1cm4gW3RhYmxlTmFtZSwgaWRdLmpvaW4oQ291Y2hEQktleXMuU0VQQVJBVE9SKTtcbiAgfVxuXG4gIHBhcnNlRXJyb3IoZXJyOiBFcnJvciB8IHN0cmluZywgcmVhc29uPzogc3RyaW5nKTogQmFzZUVycm9yIHtcbiAgICByZXR1cm4gQ291Y2hEQkFkYXB0ZXIucGFyc2VFcnJvcihlcnIsIHJlYXNvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgaXNSZXNlcnZlZChhdHRyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISFhdHRyLm1hdGNoKHJlc2VydmVkQXR0cmlidXRlcyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc3RhdGljIHBhcnNlRXJyb3IoZXJyOiBFcnJvciB8IHN0cmluZywgcmVhc29uPzogc3RyaW5nKTogQmFzZUVycm9yIHtcbiAgICBpZiAoZXJyIGluc3RhbmNlb2YgQmFzZUVycm9yKSByZXR1cm4gZXJyIGFzIGFueTtcbiAgICBsZXQgY29kZTogc3RyaW5nID0gXCJcIjtcbiAgICBpZiAodHlwZW9mIGVyciA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgY29kZSA9IGVycjtcbiAgICAgIGlmIChjb2RlLm1hdGNoKC9hbHJlYWR5IGV4aXN0fHVwZGF0ZSBjb25mbGljdC9nKSlcbiAgICAgICAgcmV0dXJuIG5ldyBDb25mbGljdEVycm9yKGNvZGUpO1xuICAgICAgaWYgKGNvZGUubWF0Y2goL21pc3Npbmd8ZGVsZXRlZC9nKSkgcmV0dXJuIG5ldyBOb3RGb3VuZEVycm9yKGNvZGUpO1xuICAgIH0gZWxzZSBpZiAoKGVyciBhcyBhbnkpLmNvZGUpIHtcbiAgICAgIGNvZGUgPSAoZXJyIGFzIGFueSkuY29kZTtcbiAgICAgIHJlYXNvbiA9IHJlYXNvbiB8fCBlcnIubWVzc2FnZTtcbiAgICB9IGVsc2UgaWYgKChlcnIgYXMgYW55KS5zdGF0dXNDb2RlKSB7XG4gICAgICBjb2RlID0gKGVyciBhcyBhbnkpLnN0YXR1c0NvZGU7XG4gICAgICByZWFzb24gPSByZWFzb24gfHwgZXJyLm1lc3NhZ2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGUgPSBlcnIubWVzc2FnZTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGNvZGUudG9TdHJpbmcoKSkge1xuICAgICAgY2FzZSBcIjQwMVwiOlxuICAgICAgY2FzZSBcIjQxMlwiOlxuICAgICAgY2FzZSBcIjQwOVwiOlxuICAgICAgICByZXR1cm4gbmV3IENvbmZsaWN0RXJyb3IocmVhc29uIGFzIHN0cmluZyk7XG4gICAgICBjYXNlIFwiNDA0XCI6XG4gICAgICAgIHJldHVybiBuZXcgTm90Rm91bmRFcnJvcihyZWFzb24gYXMgc3RyaW5nKTtcbiAgICAgIGNhc2UgXCI0MDBcIjpcbiAgICAgICAgaWYgKGNvZGUudG9TdHJpbmcoKS5tYXRjaCgvTm9cXHNpbmRleFxcc2V4aXN0cy9nKSlcbiAgICAgICAgICByZXR1cm4gbmV3IEluZGV4RXJyb3IoZXJyKTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnRlcm5hbEVycm9yKGVycik7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAoY29kZS50b1N0cmluZygpLm1hdGNoKC9FQ09OTlJFRlVTRUQvZykpXG4gICAgICAgICAgcmV0dXJuIG5ldyBDb25uZWN0aW9uRXJyb3IoZXJyKTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnRlcm5hbEVycm9yKGVycik7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBPcmRlckRpcmVjdGlvbiwgUGVyc2lzdGVuY2VLZXlzIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBDb3VjaERCS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgRGVmYXVsdFNlcGFyYXRvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgQ291Y2hEQk9wZXJhdG9yIH0gZnJvbSBcIi4vcXVlcnkvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBDcmVhdGVJbmRleFJlcXVlc3QsIE1hbmdvU2VsZWN0b3IsIFNvcnRPcmRlciB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZUF1dGgoY29uOiBhbnksIHVzZXI6IHN0cmluZywgcGFzczogc3RyaW5nKSB7XG4gIHJldHVybiBjb24uYXV0aCh1c2VyLCBwYXNzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdyYXBEb2N1bWVudFNjb3BlKFxuICBjb246IGFueSxcbiAgZGJOYW1lOiBzdHJpbmcsXG4gIHVzZXI6IHN0cmluZyxcbiAgcGFzczogc3RyaW5nXG4pOiBhbnkge1xuICBjb25zdCBkYiA9IGNvbi51c2UoZGJOYW1lKTtcbiAgW1wiaW5zZXJ0XCIsIFwiZ2V0XCIsIFwicHV0XCIsIFwiZGVzdHJveVwiLCBcImZpbmRcIl0uZm9yRWFjaCgoaykgPT4ge1xuICAgIGNvbnN0IG9yaWdpbmFsID0gKGRiIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tdO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkYiwgaywge1xuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB2YWx1ZTogYXN5bmMgKC4uLmFyZ3M6IGFueVtdKSA9PiB7XG4gICAgICAgIGF3YWl0IHJlQXV0aChjb24sIHVzZXIsIHBhc3MpO1xuICAgICAgICByZXR1cm4gb3JpZ2luYWwuY2FsbChkYiwgLi4uYXJncyk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9KTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGRiLCBDb3VjaERCS2V5cy5OQVRJVkUsIHtcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZTogY29uLFxuICB9KTtcbiAgcmV0dXJuIGRiO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdGVzdFJlc2VydmVkQXR0cmlidXRlcyhhdHRyOiBzdHJpbmcpIHtcbiAgY29uc3QgcmVnZXhwID0gL15fLiokL2c7XG4gIHJldHVybiBhdHRyLm1hdGNoKHJlZ2V4cCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUluZGV4TmFtZShcbiAgYXR0cmlidXRlOiBzdHJpbmcsXG4gIHRhYmxlTmFtZTogc3RyaW5nLFxuICBjb21wb3NpdGlvbnM/OiBzdHJpbmdbXSxcbiAgb3JkZXI/OiBPcmRlckRpcmVjdGlvbixcbiAgc2VwYXJhdG9yID0gRGVmYXVsdFNlcGFyYXRvclxuKTogc3RyaW5nIHtcbiAgY29uc3QgYXR0ciA9IFtQZXJzaXN0ZW5jZUtleXMuSU5ERVgsIHRhYmxlTmFtZSwgYXR0cmlidXRlXTtcbiAgaWYgKGNvbXBvc2l0aW9ucykgYXR0ci5wdXNoKC4uLmNvbXBvc2l0aW9ucyk7XG4gIGlmIChvcmRlcikgYXR0ci5wdXNoKG9yZGVyKTtcbiAgcmV0dXJuIGF0dHIuam9pbihzZXBhcmF0b3IpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVJbmRleERvYyhcbiAgYXR0cmlidXRlOiBzdHJpbmcsXG4gIHRhYmxlTmFtZTogc3RyaW5nLFxuICBjb21wb3NpdGlvbnM/OiBzdHJpbmdbXSxcbiAgb3JkZXI/OiBPcmRlckRpcmVjdGlvbixcbiAgc2VwYXJhdG9yID0gRGVmYXVsdFNlcGFyYXRvclxuKTogQ3JlYXRlSW5kZXhSZXF1ZXN0IHtcbiAgY29uc3QgcGFydGlhbEZpbHRlclNlbGVjdG9yOiBNYW5nb1NlbGVjdG9yID0ge307XG4gIHBhcnRpYWxGaWx0ZXJTZWxlY3RvcltDb3VjaERCS2V5cy5UQUJMRV0gPSB7fSBhcyBNYW5nb1NlbGVjdG9yO1xuICAocGFydGlhbEZpbHRlclNlbGVjdG9yW0NvdWNoREJLZXlzLlRBQkxFXSBhcyBNYW5nb1NlbGVjdG9yKVtcbiAgICBDb3VjaERCT3BlcmF0b3IuRVFVQUxcbiAgXSA9IHRhYmxlTmFtZTtcbiAgbGV0IGZpZWxkczogU29ydE9yZGVyW107XG4gIGlmIChvcmRlcikge1xuICAgIGNvbnN0IG9yZGVyUHJvcDogU29ydE9yZGVyID0ge307XG4gICAgb3JkZXJQcm9wW2F0dHJpYnV0ZV0gPSBvcmRlciBhcyBcImFzY1wiIHwgXCJkZXNjXCI7XG4gICAgY29uc3Qgc29ydGVkQ29tcG9zaXRpb25zOiBTb3J0T3JkZXJbXSA9IChjb21wb3NpdGlvbnMgfHwgW10pLm1hcCgoYykgPT4ge1xuICAgICAgY29uc3QgcjogU29ydE9yZGVyID0ge307XG4gICAgICByW2NdID0gb3JkZXIgYXMgXCJhc2NcIiB8IFwiZGVzY1wiO1xuICAgICAgcmV0dXJuIHI7XG4gICAgfSk7XG4gICAgY29uc3Qgc29ydGVkVGFibGU6IFNvcnRPcmRlciA9IHt9O1xuICAgIHNvcnRlZFRhYmxlW0NvdWNoREJLZXlzLlRBQkxFXSA9IG9yZGVyIGFzIFwiYXNjXCIgfCBcImRlc2NcIjtcbiAgICBmaWVsZHMgPSBbb3JkZXJQcm9wLCAuLi5zb3J0ZWRDb21wb3NpdGlvbnMsIHNvcnRlZFRhYmxlXTtcbiAgfSBlbHNlIHtcbiAgICBmaWVsZHMgPSBbYXR0cmlidXRlLCAuLi4oY29tcG9zaXRpb25zIHx8IFtdKSwgQ291Y2hEQktleXMuVEFCTEVdO1xuICB9XG4gIGNvbnN0IG5hbWUgPSBnZW5lcmF0ZUluZGV4TmFtZShcbiAgICBhdHRyaWJ1dGUsXG4gICAgdGFibGVOYW1lLFxuICAgIGNvbXBvc2l0aW9ucyxcbiAgICBvcmRlcixcbiAgICBzZXBhcmF0b3JcbiAgKTtcbiAgcmV0dXJuIHtcbiAgICBpbmRleDoge1xuICAgICAgZmllbGRzOiBmaWVsZHMsXG4gICAgICAvLyBwYXJ0aWFsX2ZpbHRlcl9zZWxlY3RvcjogcGFydGlhbEZpbHRlclNlbGVjdG9yLFxuICAgIH0sXG4gICAgZGRvYzogW25hbWUsIENvdWNoREJLZXlzLkRET0NdLmpvaW4oc2VwYXJhdG9yKSxcbiAgICBuYW1lOiBuYW1lLFxuICB9O1xufVxuIiwiZXhwb3J0ICogZnJvbSBcIi4vaW5kZXhlc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vaW50ZXJmYWNlc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vbW9kZWxcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3NlcXVlbmNlc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vYWRhcHRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9lcnJvcnNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGVzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi91dGlsc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IE1vZHVsZSBzdW1tYXJ5XG4gKiBAZGVzY3JpcHRpb24gTW9kdWxlIGRlc2NyaXB0aW9uXG4gKiBAbW9kdWxlIHRzLXdvcmtzcGFjZVxuICovXG5cbi8qKlxuICogQHN1bW1hcnkgTmFtZXNwYWNlIHN1bW1hcnlcbiAqIEBkZXNjcmlwdGlvbiBOYW1lc3BhY2UgZGVzY3JpcHRpb25cbiAqIEBuYW1lc3BhY2UgTmFtZXNwYWNlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnRzLXdvcmtzcGFjZVxuICovXG5cbi8qKlxuICogQHN1bW1hcnkgc3RvcmVzIHRoZSBjdXJyZW50IHBhY2thZ2UgdmVyc2lvblxuICogQGRlc2NyaXB0aW9uIHRoaXMgaXMgaG93IHlvdSBzaG91bGQgZG9jdW1lbnQgYSBjb25zdGFudFxuICogQGNvbnN0IFZFUlNJT05cbiAqIEBtZW1iZXJPZiBtb2R1bGU6dHMtd29ya3NwYWNlXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuIl0sIm5hbWVzIjpbImdlbmVyYXRlSW5kZXhOYW1lIiwiU2VxdWVuY2UiLCJTZXEiXSwibWFwcGluZ3Mi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
1410
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yLWNvdWNoZGIuZXNtLmNqcyIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbnN0YW50cy50cyIsIi4uL3NyYy9xdWVyeS9jb25zdGFudHMudHMiLCIuLi9zcmMvaW5kZXhlcy9nZW5lcmF0b3IudHMiLCIuLi9zcmMvbW9kZWwvQ291Y2hEQlNlcXVlbmNlLnRzIiwiLi4vc3JjL3NlcXVlbmNlcy9TZXF1ZW5jZS50cyIsIi4uL3NyYy9lcnJvcnMudHMiLCIuLi9zcmMvcXVlcnkvUGFnaW5hdG9yLnRzIiwiLi4vc3JjL3F1ZXJ5L3RyYW5zbGF0ZS50cyIsIi4uL3NyYy9xdWVyeS9TdGF0ZW1lbnQudHMiLCIuLi9zcmMvYWRhcHRlci50cyIsIi4uL3NyYy91dGlscy50cyIsIi4uL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBkZXNjcmlwdGlvbiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gaWRlbnRpZnkgcmVzZXJ2ZWQgYXR0cmlidXRlcyBpbiBDb3VjaERCXG4gKiBAc3VtbWFyeSBNYXRjaGVzIGFueSBhdHRyaWJ1dGUgdGhhdCBzdGFydHMgd2l0aCBhbiB1bmRlcnNjb3JlXG4gKiBAY29uc3QgcmVzZXJ2ZWRBdHRyaWJ1dGVzXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmZvci1jb3VjaGRiXG4gKi9cbmV4cG9ydCBjb25zdCByZXNlcnZlZEF0dHJpYnV0ZXMgPSAvXl8uKiQvZztcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gS2V5IGNvbnN0YW50cyB1c2VkIGluIENvdWNoREIgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgQ29sbGVjdGlvbiBvZiBzdHJpbmcgY29uc3RhbnRzIGZvciBDb3VjaERCIGRvY3VtZW50IHByb3BlcnRpZXMgYW5kIG9wZXJhdGlvbnNcbiAqIEB0eXBlZGVmIHtPYmplY3R9IENvdWNoREJLZXlzVHlwZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFNFUEFSQVRPUiAtIFNlcGFyYXRvciB1c2VkIGZvciBjb21iaW5pbmcgdGFibGUgbmFtZSBhbmQgSURcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBJRCAtIENvdWNoREIgZG9jdW1lbnQgSUQgZmllbGRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSRVYgLSBDb3VjaERCIGRvY3VtZW50IHJldmlzaW9uIGZpZWxkXG4gKiBAcHJvcGVydHkge3N0cmluZ30gREVMRVRFRCAtIENvdWNoREIgZGVsZXRlZCBkb2N1bWVudCBtYXJrZXJcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBUQUJMRSAtIFRhYmxlIG5hbWUgbWFya2VyXG4gKiBAcHJvcGVydHkge3N0cmluZ30gU0VRVUVOQ0UgLSBTZXF1ZW5jZSBtYXJrZXJcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBERE9DIC0gRGVzaWduIGRvY3VtZW50IG1hcmtlclxuICogQHByb3BlcnR5IHtzdHJpbmd9IE5BVElWRSAtIE5hdGl2ZSBtYXJrZXJcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBJTkRFWCAtIEluZGV4IG1hcmtlclxuICogQG1lbWJlck9mIG1vZHVsZTpmb3ItY291Y2hkYlxuICovXG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEtleSBjb25zdGFudHMgdXNlZCBpbiBDb3VjaERCIG9wZXJhdGlvbnNcbiAqIEBzdW1tYXJ5IENvbGxlY3Rpb24gb2Ygc3RyaW5nIGNvbnN0YW50cyBmb3IgQ291Y2hEQiBkb2N1bWVudCBwcm9wZXJ0aWVzIGFuZCBvcGVyYXRpb25zXG4gKiBAY29uc3QgQ291Y2hEQktleXNcbiAqIEB0eXBlIHtDb3VjaERCS2V5c1R5cGV9XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmZvci1jb3VjaGRiXG4gKi9cbmV4cG9ydCBjb25zdCBDb3VjaERCS2V5cyA9IHtcbiAgU0VQQVJBVE9SOiBcIl9fXCIsXG4gIElEOiBcIl9pZFwiLFxuICBSRVY6IFwiX3JldlwiLFxuICBERUxFVEVEOiBcIl9kZWxldGVkXCIsXG4gIFRBQkxFOiBcIj8/dGFibGVcIixcbiAgU0VRVUVOQ0U6IFwiPz9zZXF1ZW5jZVwiLFxuICBERE9DOiBcImRkb2NcIixcbiAgTkFUSVZFOiBcIl9fbmF0aXZlXCIsXG4gIElOREVYOiBcImluZGV4XCIsXG59O1xuIiwiaW1wb3J0IHsgTWFuZ29PcGVyYXRvciB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IHF1ZXJ5IGxpbWl0IGZvciBDb3VjaERCIHF1ZXJpZXNcbiAqIEBzdW1tYXJ5IE1heGltdW0gbnVtYmVyIG9mIGRvY3VtZW50cyB0byByZXR1cm4gaW4gYSBzaW5nbGUgcXVlcnlcbiAqIEBjb25zdCBDb3VjaERCUXVlcnlMaW1pdFxuICogQG1lbWJlck9mIG1vZHVsZTpmb3ItY291Y2hkYlxuICovXG5leHBvcnQgY29uc3QgQ291Y2hEQlF1ZXJ5TGltaXQgPSAyNTA7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1hcHBpbmcgb2Ygb3BlcmF0b3IgbmFtZXMgdG8gQ291Y2hEQiBNYW5nbyBxdWVyeSBvcGVyYXRvcnNcbiAqIEBzdW1tYXJ5IENvbnN0YW50cyBmb3IgQ291Y2hEQiBjb21wYXJpc29uIG9wZXJhdG9ycyB1c2VkIGluIE1hbmdvIHF1ZXJpZXNcbiAqIEB0eXBlZGVmIHtPYmplY3R9IENvdWNoREJPcGVyYXRvclR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBFUVVBTCAtIEVxdWFsaXR5IG9wZXJhdG9yICgkZXEpXG4gKiBAcHJvcGVydHkge3N0cmluZ30gRElGRkVSRU5UIC0gSW5lcXVhbGl0eSBvcGVyYXRvciAoJG5lKVxuICogQHByb3BlcnR5IHtzdHJpbmd9IEJJR0dFUiAtIEdyZWF0ZXIgdGhhbiBvcGVyYXRvciAoJGd0KVxuICogQHByb3BlcnR5IHtzdHJpbmd9IEJJR0dFUl9FUSAtIEdyZWF0ZXIgdGhhbiBvciBlcXVhbCBvcGVyYXRvciAoJGd0ZSlcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBTTUFMTEVSIC0gTGVzcyB0aGFuIG9wZXJhdG9yICgkbHQpXG4gKiBAcHJvcGVydHkge3N0cmluZ30gU01BTExFUl9FUSAtIExlc3MgdGhhbiBvciBlcXVhbCBvcGVyYXRvciAoJGx0ZSlcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBOT1QgLSBOZWdhdGlvbiBvcGVyYXRvciAoJG5vdClcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBJTiAtIEluIGFycmF5IG9wZXJhdG9yICgkaW4pXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUkVHRVhQIC0gUmVndWxhciBleHByZXNzaW9uIG9wZXJhdG9yICgkcmVnZXgpXG4gKiBAY29uc3QgQ291Y2hEQk9wZXJhdG9yXG4gKiBAdHlwZSB7Q291Y2hEQk9wZXJhdG9yVHlwZX1cbiAqIEBtZW1iZXJPZiBtb2R1bGU6Zm9yLWNvdWNoZGJcbiAqL1xuZXhwb3J0IGNvbnN0IENvdWNoREJPcGVyYXRvcjogUmVjb3JkPHN0cmluZywgTWFuZ29PcGVyYXRvcj4gPSB7XG4gIEVRVUFMOiBcIiRlcVwiLFxuICBESUZGRVJFTlQ6IFwiJG5lXCIsXG4gIEJJR0dFUjogXCIkZ3RcIixcbiAgQklHR0VSX0VROiBcIiRndGVcIixcbiAgU01BTExFUjogXCIkbHRcIixcbiAgU01BTExFUl9FUTogXCIkbHRlXCIsXG4gIC8vIEJFVFdFRU4gPSBcIkJFVFdFRU5cIixcbiAgTk9UOiBcIiRub3RcIixcbiAgSU46IFwiJGluXCIsXG4gIC8vIElTID0gXCJJU1wiLFxuICBSRUdFWFA6IFwiJHJlZ2V4XCIsXG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNYXBwaW5nIG9mIGxvZ2ljYWwgb3BlcmF0b3IgbmFtZXMgdG8gQ291Y2hEQiBNYW5nbyBxdWVyeSBvcGVyYXRvcnNcbiAqIEBzdW1tYXJ5IENvbnN0YW50cyBmb3IgQ291Y2hEQiBsb2dpY2FsIG9wZXJhdG9ycyB1c2VkIGluIE1hbmdvIHF1ZXJpZXNcbiAqIEB0eXBlZGVmIHtPYmplY3R9IENvdWNoREJHcm91cE9wZXJhdG9yVHlwZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IEFORCAtIExvZ2ljYWwgQU5EIG9wZXJhdG9yICgkYW5kKVxuICogQHByb3BlcnR5IHtzdHJpbmd9IE9SIC0gTG9naWNhbCBPUiBvcGVyYXRvciAoJG9yKVxuICogQGNvbnN0IENvdWNoREJHcm91cE9wZXJhdG9yXG4gKiBAdHlwZSB7Q291Y2hEQkdyb3VwT3BlcmF0b3JUeXBlfVxuICogQG1lbWJlck9mIG1vZHVsZTpmb3ItY291Y2hkYlxuICovXG5leHBvcnQgY29uc3QgQ291Y2hEQkdyb3VwT3BlcmF0b3I6IFJlY29yZDxzdHJpbmcsIE1hbmdvT3BlcmF0b3I+ID0ge1xuICBBTkQ6IFwiJGFuZFwiLFxuICBPUjogXCIkb3JcIixcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFNwZWNpYWwgY29uc3RhbnQgdmFsdWVzIHVzZWQgaW4gQ291Y2hEQiBxdWVyaWVzXG4gKiBAc3VtbWFyeSBTdHJpbmcgY29uc3RhbnRzIHJlcHJlc2VudGluZyBzcGVjaWFsIHZhbHVlcyBpbiBDb3VjaERCXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBDb3VjaERCQ29uc3RUeXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTlVMTCAtIFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBudWxsIHZhbHVlXG4gKiBAY29uc3QgQ291Y2hEQkNvbnN0XG4gKiBAdHlwZSB7Q291Y2hEQkNvbnN0VHlwZX1cbiAqIEBtZW1iZXJPZiBtb2R1bGU6Zm9yLWNvdWNoZGJcbiAqL1xuZXhwb3J0IGNvbnN0IENvdWNoREJDb25zdDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgTlVMTDogXCJudWxsXCIsXG59O1xuIiwiaW1wb3J0IHtcbiAgSW5kZXhNZXRhZGF0YSxcbiAgT3JkZXJEaXJlY3Rpb24sXG4gIFBlcnNpc3RlbmNlS2V5cyxcbiAgUmVwb3NpdG9yeSxcbn0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBDb3VjaERCS2V5cyB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IERlZmF1bHRTZXBhcmF0b3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IENvdWNoREJPcGVyYXRvciB9IGZyb20gXCIuLi9xdWVyeS9jb25zdGFudHNcIjtcbmltcG9ydCB7IENyZWF0ZUluZGV4UmVxdWVzdCB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBHZW5lcmF0ZXMgYSBuYW1lIGZvciBhIENvdWNoREIgaW5kZXhcbiAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBzdGFuZGFyZGl6ZWQgbmFtZSBmb3IgYSBDb3VjaERCIGluZGV4IGJ5IGNvbWJpbmluZyBuYW1lIHBhcnRzLCBjb21wb3NpdGlvbnMsIGFuZCBkaXJlY3Rpb25cbiAqIEBwYXJhbSB7c3RyaW5nW119IG5hbWUgLSBBcnJheSBvZiBuYW1lIHBhcnRzIGZvciB0aGUgaW5kZXhcbiAqIEBwYXJhbSB7T3JkZXJEaXJlY3Rpb259IFtkaXJlY3Rpb25dIC0gT3B0aW9uYWwgc29ydCBkaXJlY3Rpb24gZm9yIHRoZSBpbmRleFxuICogQHBhcmFtIHtzdHJpbmdbXX0gW2NvbXBvc2l0aW9uc10gLSBPcHRpb25hbCBhZGRpdGlvbmFsIGF0dHJpYnV0ZXMgdG8gaW5jbHVkZSBpbiB0aGUgaW5kZXggbmFtZVxuICogQHBhcmFtIHtzdHJpbmd9IFtzZXBhcmF0b3I9RGVmYXVsdFNlcGFyYXRvcl0gLSBUaGUgc2VwYXJhdG9yIHRvIHVzZSBiZXR3ZWVuIHBhcnRzIG9mIHRoZSBpbmRleCBuYW1lXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBnZW5lcmF0ZWQgaW5kZXggbmFtZVxuICogQG1lbWJlck9mIG1vZHVsZTpmb3ItY291Y2hkYlxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZUluZGV4TmFtZShcbiAgbmFtZTogc3RyaW5nW10sXG4gIGRpcmVjdGlvbj86IE9yZGVyRGlyZWN0aW9uLFxuICBjb21wb3NpdGlvbnM/OiBzdHJpbmdbXSxcbiAgc2VwYXJhdG9yID0gRGVmYXVsdFNlcGFyYXRvclxuKSB7XG4gIHJldHVybiBbXG4gICAgLi4ubmFtZS5tYXAoKG4pID0+IChuID09PSBDb3VjaERCS2V5cy5UQUJMRSA/IFwidGFibGVcIiA6IG4pKSxcbiAgICAuLi4oY29tcG9zaXRpb25zIHx8IFtdKSxcbiAgICAuLi4oZGlyZWN0aW9uID8gW2RpcmVjdGlvbl0gOiBbXSksXG4gICAgQ291Y2hEQktleXMuSU5ERVgsXG4gIF0uam9pbihzZXBhcmF0b3IpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBHZW5lcmF0ZXMgQ291Y2hEQiBpbmRleCBjb25maWd1cmF0aW9ucyBmb3IgbW9kZWxzXG4gKiBAc3VtbWFyeSBDcmVhdGVzIGEgc2V0IG9mIENvdWNoREIgaW5kZXggY29uZmlndXJhdGlvbnMgYmFzZWQgb24gdGhlIG1ldGFkYXRhIG9mIHRoZSBwcm92aWRlZCBtb2RlbHNcbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgdGhhdCBleHRlbmRzIE1vZGVsXG4gKiBAcGFyYW0gbW9kZWxzIC0gQXJyYXkgb2YgbW9kZWwgY29uc3RydWN0b3JzIHRvIGdlbmVyYXRlIGluZGV4ZXMgZm9yXG4gKiBAcmV0dXJuIHtDcmVhdGVJbmRleFJlcXVlc3RbXX0gQXJyYXkgb2YgQ291Y2hEQiBpbmRleCBjb25maWd1cmF0aW9uc1xuICogQGZ1bmN0aW9uIGdlbmVyYXRlSW5kZXhlc1xuICogQG1lbWJlck9mIG1vZHVsZTpmb3ItY291Y2hkYlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgZ2VuZXJhdGVJbmRleGVzXG4gKiAgIHBhcnRpY2lwYW50IGdlbmVyYXRlSW5kZXhOYW1lXG4gKiAgIHBhcnRpY2lwYW50IFJlcG9zaXRvcnlcbiAqXG4gKiAgIENhbGxlci0+PmdlbmVyYXRlSW5kZXhlczogbW9kZWxzXG4gKlxuICogICBOb3RlIG92ZXIgZ2VuZXJhdGVJbmRleGVzOiBDcmVhdGUgYmFzZSB0YWJsZSBpbmRleFxuICogICBnZW5lcmF0ZUluZGV4ZXMtPj5nZW5lcmF0ZUluZGV4TmFtZTogW0NvdWNoREJLZXlzLlRBQkxFXVxuICogICBnZW5lcmF0ZUluZGV4TmFtZS0tPj5nZW5lcmF0ZUluZGV4ZXM6IHRhYmxlTmFtZVxuICogICBnZW5lcmF0ZUluZGV4ZXMtPj5nZW5lcmF0ZUluZGV4ZXM6IENyZWF0ZSB0YWJsZSBpbmRleCBjb25maWdcbiAqXG4gKiAgIGxvb3AgRm9yIGVhY2ggbW9kZWxcbiAqICAgICBnZW5lcmF0ZUluZGV4ZXMtPj5SZXBvc2l0b3J5OiBHZXQgaW5kZXhlcyBtZXRhZGF0YVxuICogICAgIFJlcG9zaXRvcnktLT4+Z2VuZXJhdGVJbmRleGVzOiBpbmRleCBtZXRhZGF0YVxuICpcbiAqICAgICBsb29wIEZvciBlYWNoIGluZGV4IGluIG1ldGFkYXRhXG4gKiAgICAgICBOb3RlIG92ZXIgZ2VuZXJhdGVJbmRleGVzOiBFeHRyYWN0IGluZGV4IHByb3BlcnRpZXNcbiAqICAgICAgIGdlbmVyYXRlSW5kZXhlcy0+PlJlcG9zaXRvcnk6IEdldCB0YWJsZSBuYW1lXG4gKiAgICAgICBSZXBvc2l0b3J5LS0+PmdlbmVyYXRlSW5kZXhlczogdGFibGVOYW1lXG4gKlxuICogICAgICAgTm90ZSBvdmVyIGdlbmVyYXRlSW5kZXhlczogRGVmaW5lIG5lc3RlZCBnZW5lcmF0ZSBmdW5jdGlvblxuICpcbiAqICAgICAgIGdlbmVyYXRlSW5kZXhlcy0+PmdlbmVyYXRlSW5kZXhlczogQ2FsbCBnZW5lcmF0ZSgpIGZvciBkZWZhdWx0IG9yZGVyXG4gKiAgICAgICBOb3RlIG92ZXIgZ2VuZXJhdGVJbmRleGVzOiBDcmVhdGUgaW5kZXggbmFtZSBhbmQgY29uZmlnXG4gKlxuICogICAgICAgYWx0IEhhcyBkaXJlY3Rpb25zXG4gKiAgICAgICAgIGxvb3AgRm9yIGVhY2ggZGlyZWN0aW9uXG4gKiAgICAgICAgICAgZ2VuZXJhdGVJbmRleGVzLT4+Z2VuZXJhdGVJbmRleGVzOiBDYWxsIGdlbmVyYXRlKGRpcmVjdGlvbilcbiAqICAgICAgICAgICBOb3RlIG92ZXIgZ2VuZXJhdGVJbmRleGVzOiBDcmVhdGUgb3JkZXJlZCBpbmRleCBjb25maWdcbiAqICAgICAgICAgZW5kXG4gKiAgICAgICBlbmRcbiAqICAgICBlbmRcbiAqICAgZW5kXG4gKlxuICogICBnZW5lcmF0ZUluZGV4ZXMtLT4+Q2FsbGVyOiBBcnJheSBvZiBpbmRleCBjb25maWd1cmF0aW9uc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVJbmRleGVzPE0gZXh0ZW5kcyBNb2RlbD4oXG4gIG1vZGVsczogQ29uc3RydWN0b3I8TT5bXVxuKTogQ3JlYXRlSW5kZXhSZXF1ZXN0W10ge1xuICBjb25zdCB0YWJsZU5hbWUgPSBnZW5lcmF0ZUluZGV4TmFtZShbQ291Y2hEQktleXMuVEFCTEVdKTtcbiAgY29uc3QgaW5kZXhlczogUmVjb3JkPHN0cmluZywgQ3JlYXRlSW5kZXhSZXF1ZXN0PiA9IHt9O1xuICBpbmRleGVzW3RhYmxlTmFtZV0gPSB7XG4gICAgaW5kZXg6IHtcbiAgICAgIGZpZWxkczogW0NvdWNoREJLZXlzLlRBQkxFXSxcbiAgICB9LFxuICAgIG5hbWU6IHRhYmxlTmFtZSxcbiAgICBkZG9jOiB0YWJsZU5hbWUsXG4gICAgdHlwZTogXCJqc29uXCIsXG4gIH07XG5cbiAgbW9kZWxzLmZvckVhY2goKG0pID0+IHtcbiAgICBjb25zdCBpbmQ6IFJlY29yZDxzdHJpbmcsIEluZGV4TWV0YWRhdGE+ID0gUmVwb3NpdG9yeS5pbmRleGVzKG0pO1xuICAgIE9iamVjdC5lbnRyaWVzKGluZCkuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBjb25zdCBrID0gT2JqZWN0LmtleXModmFsdWUpWzBdO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdFxuICAgICAgbGV0IHsgZGlyZWN0aW9ucywgY29tcG9zaXRpb25zIH0gPSAodmFsdWUgYXMgYW55KVtrXTtcbiAgICAgIGNvbnN0IHRhYmxlTmFtZSA9IFJlcG9zaXRvcnkudGFibGUobSk7XG4gICAgICBjb21wb3NpdGlvbnMgPSBjb21wb3NpdGlvbnMgfHwgW107XG5cbiAgICAgIGZ1bmN0aW9uIGdlbmVyYXRlKHNvcnQ/OiBPcmRlckRpcmVjdGlvbikge1xuICAgICAgICBjb25zdCBuYW1lID0gW1xuICAgICAgICAgIHRhYmxlTmFtZSxcbiAgICAgICAgICBrZXksXG4gICAgICAgICAgLi4uKGNvbXBvc2l0aW9ucyBhcyBbXSksXG4gICAgICAgICAgUGVyc2lzdGVuY2VLZXlzLklOREVYLFxuICAgICAgICBdLmpvaW4oRGVmYXVsdFNlcGFyYXRvcik7XG5cbiAgICAgICAgaW5kZXhlc1tuYW1lXSA9IHtcbiAgICAgICAgICBpbmRleDoge1xuICAgICAgICAgICAgZmllbGRzOiBba2V5LCAuLi4oY29tcG9zaXRpb25zIGFzIFtdKSwgQ291Y2hEQktleXMuVEFCTEVdLnJlZHVjZShcbiAgICAgICAgICAgICAgKGFjY3VtOiBhbnlbXSwgZWwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoc29ydCkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgcmVzOiBhbnkgPSB7fTtcbiAgICAgICAgICAgICAgICAgIHJlc1tlbF0gPSBzb3J0O1xuICAgICAgICAgICAgICAgICAgYWNjdW0ucHVzaChyZXMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBhY2N1bS5wdXNoKGVsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBbXVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgICAgZGRvYzogbmFtZSxcbiAgICAgICAgICB0eXBlOiBcImpzb25cIixcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKCFzb3J0KSB7XG4gICAgICAgICAgY29uc3QgdGFibGVGaWx0ZXI6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICAgICAgICB0YWJsZUZpbHRlcltDb3VjaERCS2V5cy5UQUJMRV0gPSB7fTtcbiAgICAgICAgICB0YWJsZUZpbHRlcltDb3VjaERCS2V5cy5UQUJMRV1bQ291Y2hEQk9wZXJhdG9yLkVRVUFMXSA9IHRhYmxlTmFtZTtcbiAgICAgICAgICBpbmRleGVzW25hbWVdLmluZGV4LnBhcnRpYWxfZmlsdGVyX3NlbGVjdG9yID0gdGFibGVGaWx0ZXI7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZ2VuZXJhdGUoKTtcbiAgICAgIGlmIChkaXJlY3Rpb25zKVxuICAgICAgICAoZGlyZWN0aW9ucyBhcyB1bmtub3duIGFzIE9yZGVyRGlyZWN0aW9uW10pLmZvckVhY2goKGQpID0+IGdlbmVyYXRlKGQpKTtcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBPYmplY3QudmFsdWVzKGluZGV4ZXMpO1xufVxuIiwiaW1wb3J0IHR5cGUgeyBNb2RlbEFyZyB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IG1vZGVsLCByZXF1aXJlZCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEJhc2VNb2RlbCwgcGssIGluZGV4LCB0YWJsZSB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgQ291Y2hEQktleXMgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1vZGVsIGZvciBDb3VjaERCIHNlcXVlbmNlIHJlY29yZHNcbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYSBzZXF1ZW5jZSBpbiBDb3VjaERCIHVzZWQgZm9yIGdlbmVyYXRpbmcgc2VxdWVudGlhbCBJRHNcbiAqIEBwYXJhbSB7TW9kZWxBcmc8U2VxdWVuY2U+fSBbc2VxXSAtIE9wdGlvbmFsIGluaXRpYWxpemF0aW9uIGRhdGEgZm9yIHRoZSBzZXF1ZW5jZVxuICogQGNsYXNzXG4gKiBAZXhhbXBsZVxuICogLy8gRXhhbXBsZSBvZiBjcmVhdGluZyBhbmQgdXNpbmcgYSBTZXF1ZW5jZVxuICogY29uc3Qgc2VxdWVuY2UgPSBuZXcgU2VxdWVuY2UoeyBpZDogJ3VzZXItc2VxJywgY3VycmVudDogMSB9KTtcbiAqIC8vIEluY3JlbWVudCB0aGUgc2VxdWVuY2VcbiAqIHNlcXVlbmNlLmN1cnJlbnQgPSBOdW1iZXIoc2VxdWVuY2UuY3VycmVudCkgKyAxO1xuICovXG5AdGFibGUoQ291Y2hEQktleXMuU0VRVUVOQ0UpXG5AbW9kZWwoKVxuZXhwb3J0IGNsYXNzIFNlcXVlbmNlIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBzZXF1ZW5jZVxuICAgKiBAc3VtbWFyeSBQcmltYXJ5IGtleSBmb3IgdGhlIHNlcXVlbmNlIHJlY29yZFxuICAgKi9cbiAgQHBrKClcbiAgaWQhOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgc2VxdWVuY2VcbiAgICogQHN1bW1hcnkgQ3VycmVudCBzZXF1ZW5jZSB2YWx1ZSB0aGF0IGNhbiBiZSBpbmNyZW1lbnRlZFxuICAgKi9cbiAgQHJlcXVpcmVkKClcbiAgQGluZGV4KClcbiAgY3VycmVudCE6IHN0cmluZyB8IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihzZXE/OiBNb2RlbEFyZzxTZXF1ZW5jZT4pIHtcbiAgICBzdXBlcihzZXEpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBTZXF1ZW5jZSBhcyBTZXEgfSBmcm9tIFwiLi4vbW9kZWwvQ291Y2hEQlNlcXVlbmNlXCI7XG5pbXBvcnQgeyBJbnRlcm5hbEVycm9yLCBOb3RGb3VuZEVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBBZGFwdGVyLCBSZXBvc2l0b3J5LCBTZXF1ZW5jZU9wdGlvbnMgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IFNlcXVlbmNlIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBNYW5nb1F1ZXJ5IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBDb3VjaERCUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9pbnRlcmZhY2VzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgQWJzdHJhY3QgaW1wbGVtZW50YXRpb24gb2YgYSBTZXF1ZW5jZVxuICogQGRlc2NyaXB0aW9uIHByb3ZpZGVzIHRoZSBiYXNpYyBmdW5jdGlvbmFsaXR5IGZvciB7QGxpbmsgU2VxdWVuY2V9c1xuICpcbiAqIEBwYXJhbSB7U2VxdWVuY2VPcHRpb25zfSBvcHRpb25zXG4gKlxuICogQGNsYXNzIENvdWNoREJTZXF1ZW5jZVxuICogQGltcGxlbWVudHMgU2VxdWVuY2VcbiAqL1xuZXhwb3J0IGNsYXNzIENvdWNoREJTZXF1ZW5jZSBleHRlbmRzIFNlcXVlbmNlIHtcbiAgcHJvdGVjdGVkIHJlcG86IENvdWNoREJSZXBvc2l0b3J5PFNlcSwgYW55LCBhbnksIGFueT47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgb3B0aW9uczogU2VxdWVuY2VPcHRpb25zLFxuICAgIGFkYXB0ZXI6IEFkYXB0ZXI8YW55LCBNYW5nb1F1ZXJ5LCBhbnksIGFueT5cbiAgKSB7XG4gICAgc3VwZXIob3B0aW9ucyk7XG4gICAgdGhpcy5yZXBvID0gUmVwb3NpdG9yeS5mb3JNb2RlbChTZXEsIGFkYXB0ZXIuYWxpYXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgY3VycmVudCB2YWx1ZSBmb3IgdGhlIHNlcXVlbmNlXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIGFzeW5jIGN1cnJlbnQoKTogUHJvbWlzZTxzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQ+IHtcbiAgICBjb25zdCB7IG5hbWUsIHN0YXJ0V2l0aCB9ID0gdGhpcy5vcHRpb25zO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzZXF1ZW5jZTogU2VxID0gYXdhaXQgdGhpcy5yZXBvLnJlYWQobmFtZSBhcyBzdHJpbmcpO1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2Uoc2VxdWVuY2UuY3VycmVudCBhcyBzdHJpbmcgfCBudW1iZXIpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgaWYgKGUgaW5zdGFuY2VvZiBOb3RGb3VuZEVycm9yKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc3RhcnRXaXRoID09PSBcInVuZGVmaW5lZFwiKVxuICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAgICAgXCJTdGFydGluZyB2YWx1ZSBpcyBub3QgZGVmaW5lZCBmb3IgYSBub24gZXhpc3Rpbmcgc2VxdWVuY2VcIlxuICAgICAgICAgICk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2Uoc3RhcnRXaXRoKTtcbiAgICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAgICAgYEZhaWxlZCB0byBwYXJzZSBpbml0aWFsIHZhbHVlIGZvciBzZXF1ZW5jZSAke3N0YXJ0V2l0aH06ICR7ZX1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gcmV0cmlldmUgY3VycmVudCB2YWx1ZSBmb3Igc2VxdWVuY2UgJHtuYW1lfTogJHtlfWBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFBhcnNlcyB0aGUge0BsaW5rIFNlcXVlbmNlfSB2YWx1ZVxuICAgKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEBwYXJhbSB2YWx1ZVxuICAgKi9cbiAgcHJpdmF0ZSBwYXJzZSh2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50KTogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHtcbiAgICByZXR1cm4gU2VxdWVuY2UucGFyc2VWYWx1ZSh0aGlzLm9wdGlvbnMudHlwZSwgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IGluY3JlbWVudHMgdGhlIHNlcXVlbmNlXG4gICAqIEBkZXNjcmlwdGlvbiBTZXF1ZW5jZSBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvblxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bWJlciB8IGJpZ2ludH0gY3VycmVudFxuICAgKiBAcGFyYW0gY291bnRcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBpbmNyZW1lbnQoXG4gICAgY3VycmVudDogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50LFxuICAgIGNvdW50PzogbnVtYmVyXG4gICk6IFByb21pc2U8c3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50PiB7XG4gICAgY29uc3QgeyB0eXBlLCBpbmNyZW1lbnRCeSwgbmFtZSB9ID0gdGhpcy5vcHRpb25zO1xuICAgIGxldCBuZXh0OiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQ7XG4gICAgY29uc3QgdG9JbmNyZW1lbnRCeSA9IGNvdW50IHx8IGluY3JlbWVudEJ5O1xuICAgIGlmICh0b0luY3JlbWVudEJ5ICUgaW5jcmVtZW50QnkgIT09IDApXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYFZhbHVlIHRvIGluY3JlbWVudCBkb2VzIG5vdCBjb25zaWRlciB0aGUgaW5jcmVtZW50Qnkgc2V0dGluZzogJHtpbmNyZW1lbnRCeX1gXG4gICAgICApO1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSBcIk51bWJlclwiOlxuICAgICAgICBuZXh0ID0gKHRoaXMucGFyc2UoY3VycmVudCkgYXMgbnVtYmVyKSArIHRvSW5jcmVtZW50Qnk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcIkJpZ0ludFwiOlxuICAgICAgICBuZXh0ID0gKHRoaXMucGFyc2UoY3VycmVudCkgYXMgYmlnaW50KSArIEJpZ0ludCh0b0luY3JlbWVudEJ5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIlNob3VsZCBuZXZlciBoYXBwZW5cIik7XG4gICAgfVxuICAgIGxldCBzZXE6IFNlcTtcbiAgICB0cnkge1xuICAgICAgc2VxID0gYXdhaXQgdGhpcy5yZXBvLnVwZGF0ZShuZXcgU2VxKHsgaWQ6IG5hbWUsIGN1cnJlbnQ6IG5leHQgfSkpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIE5vdEZvdW5kRXJyb3IpKSB0aHJvdyBlO1xuICAgICAgc2VxID0gYXdhaXQgdGhpcy5yZXBvLmNyZWF0ZShuZXcgU2VxKHsgaWQ6IG5hbWUsIGN1cnJlbnQ6IG5leHQgfSkpO1xuICAgIH1cblxuICAgIHJldHVybiBzZXEuY3VycmVudCBhcyBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQ7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgR2VuZXJhdGVzIHRoZSBuZXh0IHZhbHVlIGluIHRoIHNlcXVlbmNlXG4gICAqIEBkZXNjcmlwdGlvbiBjYWxscyB7QGxpbmsgU2VxdWVuY2UjcGFyc2V9IG9uIHRoZSBjdXJyZW50IHZhbHVlXG4gICAqIGZvbGxvd2VkIGJ5IHtAbGluayBTZXF1ZW5jZSNpbmNyZW1lbnR9XG4gICAqXG4gICAqL1xuICBhc3luYyBuZXh0KCk6IFByb21pc2U8bnVtYmVyIHwgc3RyaW5nIHwgYmlnaW50PiB7XG4gICAgY29uc3QgY3VycmVudCA9IGF3YWl0IHRoaXMuY3VycmVudCgpO1xuICAgIHJldHVybiB0aGlzLmluY3JlbWVudChjdXJyZW50KTtcbiAgfVxuXG4gIGFzeW5jIHJhbmdlKGNvdW50OiBudW1iZXIpOiBQcm9taXNlPChudW1iZXIgfCBzdHJpbmcgfCBiaWdpbnQpW10+IHtcbiAgICBjb25zdCBjdXJyZW50ID0gKGF3YWl0IHRoaXMuY3VycmVudCgpKSBhcyBudW1iZXI7XG4gICAgY29uc3QgaW5jcmVtZW50QnkgPSB0aGlzLnBhcnNlKHRoaXMub3B0aW9ucy5pbmNyZW1lbnRCeSkgYXMgbnVtYmVyO1xuICAgIGNvbnN0IG5leHQ6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCA9IGF3YWl0IHRoaXMuaW5jcmVtZW50KFxuICAgICAgY3VycmVudCxcbiAgICAgICh0aGlzLnBhcnNlKGNvdW50KSBhcyBudW1iZXIpICogaW5jcmVtZW50QnlcbiAgICApO1xuICAgIGNvbnN0IHJhbmdlOiAobnVtYmVyIHwgc3RyaW5nIHwgYmlnaW50KVtdID0gW107XG4gICAgZm9yIChsZXQgaTogbnVtYmVyID0gMTsgaSA8PSBjb3VudDsgaSsrKSB7XG4gICAgICByYW5nZS5wdXNoKGN1cnJlbnQgKyBpbmNyZW1lbnRCeSAqICh0aGlzLnBhcnNlKGkpIGFzIG51bWJlcikpO1xuICAgIH1cbiAgICBpZiAocmFuZ2VbcmFuZ2UubGVuZ3RoIC0gMV0gIT09IG5leHQpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIk1pc2NhbGN1bGF0aW9uIG9mIHJhbmdlXCIpO1xuICAgIHJldHVybiByYW5nZTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQmFzZUVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVycm9yIHRocm93biB3aGVuIHRoZXJlIGlzIGFuIGlzc3VlIHdpdGggQ291Y2hEQiBpbmRleGVzXG4gKiBAc3VtbWFyeSBSZXByZXNlbnRzIGFuIGVycm9yIHJlbGF0ZWQgdG8gQ291Y2hEQiBpbmRleCBvcGVyYXRpb25zXG4gKiBAcGFyYW0ge3N0cmluZ3xFcnJvcn0gbXNnIC0gVGhlIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0XG4gKiBAY2xhc3NcbiAqIEBjYXRlZ29yeSBFcnJvcnNcbiAqIEBleGFtcGxlXG4gKiAvLyBFeGFtcGxlIG9mIHVzaW5nIEluZGV4RXJyb3JcbiAqIHRyeSB7XG4gKiAgIC8vIFNvbWUgY29kZSB0aGF0IG1pZ2h0IHRocm93IGFuIGluZGV4IGVycm9yXG4gKiAgIHRocm93IG5ldyBJbmRleEVycm9yKFwiSW5kZXggbm90IGZvdW5kXCIpO1xuICogfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgaWYgKGVycm9yIGluc3RhbmNlb2YgSW5kZXhFcnJvcikge1xuICogICAgIGNvbnNvbGUuZXJyb3IoXCJJbmRleCBlcnJvciBvY2N1cnJlZDpcIiwgZXJyb3IubWVzc2FnZSk7XG4gKiAgIH1cbiAqIH1cbiAqL1xuZXhwb3J0IGNsYXNzIEluZGV4RXJyb3IgZXh0ZW5kcyBCYXNlRXJyb3Ige1xuICBjb25zdHJ1Y3Rvcihtc2c6IHN0cmluZyB8IEVycm9yKSB7XG4gICAgc3VwZXIoSW5kZXhFcnJvci5uYW1lLCBtc2csIDQwNCk7XG4gIH1cbn1cbiIsImltcG9ydCB7IFBhZ2luYXRvciwgUGFnaW5nRXJyb3IsIFNlcXVlbmNlIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBmaW5kUHJpbWFyeUtleSwgSW50ZXJuYWxFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgTWFuZ29RdWVyeSwgTWFuZ29SZXNwb25zZSB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgQ291Y2hEQkFkYXB0ZXIgfSBmcm9tIFwiLi4vYWRhcHRlclwiO1xuaW1wb3J0IHsgQ291Y2hEQktleXMgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFBhZ2luYXRvciBmb3IgQ291Y2hEQiBxdWVyeSByZXN1bHRzXG4gKiBAc3VtbWFyeSBJbXBsZW1lbnRzIHBhZ2luYXRpb24gZm9yIENvdWNoREIgcXVlcmllcyB1c2luZyBib29rbWFya3MgZm9yIGVmZmljaWVudCBuYXZpZ2F0aW9uIHRocm91Z2ggcmVzdWx0IHNldHNcbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgdGhhdCBleHRlbmRzIE1vZGVsXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSByZXN1bHQgdHlwZVxuICogQHBhcmFtIHtDb3VjaERCQWRhcHRlcjxhbnksIGFueSwgYW55Pn0gYWRhcHRlciAtIFRoZSBDb3VjaERCIGFkYXB0ZXJcbiAqIEBwYXJhbSB7TWFuZ29RdWVyeX0gcXVlcnkgLSBUaGUgTWFuZ28gcXVlcnkgdG8gcGFnaW5hdGVcbiAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIC0gVGhlIHBhZ2Ugc2l6ZVxuICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gY2xhenogLSBUaGUgbW9kZWwgY29uc3RydWN0b3JcbiAqIEBjbGFzcyBDb3VjaERCUGFnaW5hdG9yXG4gKiBAZXhhbXBsZVxuICogLy8gRXhhbXBsZSBvZiB1c2luZyBDb3VjaERCUGFnaW5hdG9yXG4gKiBjb25zdCBhZGFwdGVyID0gbmV3IE15Q291Y2hEQkFkYXB0ZXIoc2NvcGUpO1xuICogY29uc3QgcXVlcnkgPSB7IHNlbGVjdG9yOiB7IHR5cGU6IFwidXNlclwiIH0gfTtcbiAqIGNvbnN0IHBhZ2luYXRvciA9IG5ldyBDb3VjaERCUGFnaW5hdG9yKGFkYXB0ZXIsIHF1ZXJ5LCAxMCwgVXNlcik7XG4gKlxuICogLy8gR2V0IHRoZSBmaXJzdCBwYWdlXG4gKiBjb25zdCBwYWdlMSA9IGF3YWl0IHBhZ2luYXRvci5wYWdlKDEpO1xuICpcbiAqIC8vIEdldCB0aGUgbmV4dCBwYWdlXG4gKiBjb25zdCBwYWdlMiA9IGF3YWl0IHBhZ2luYXRvci5wYWdlKDIpO1xuICovXG5leHBvcnQgY2xhc3MgQ291Y2hEQlBhZ2luYXRvcjxNIGV4dGVuZHMgTW9kZWwsIFI+IGV4dGVuZHMgUGFnaW5hdG9yPFxuICBNLFxuICBSLFxuICBNYW5nb1F1ZXJ5XG4+IHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBCb29rbWFyayBmb3IgQ291Y2hEQiBwYWdpbmF0aW9uXG4gICAqIEBzdW1tYXJ5IFN0b3JlcyB0aGUgYm9va21hcmsgcmV0dXJuZWQgYnkgQ291Y2hEQiBmb3IgY29udGludWluZyBwYWdpbmF0aW9uXG4gICAqL1xuICBwcml2YXRlIGJvb2tNYXJrPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgdG90YWwgbnVtYmVyIG9mIHBhZ2VzXG4gICAqIEBzdW1tYXJ5IE5vdCBzdXBwb3J0ZWQgaW4gQ291Y2hEQiAtIHRocm93cyBhbiBlcnJvciB3aGVuIGFjY2Vzc2VkXG4gICAqIEByZXR1cm4ge251bWJlcn0gTmV2ZXIgcmV0dXJucyBhcyBpdCB0aHJvd3MgYW4gZXJyb3JcbiAgICogQHRocm93cyB7SW50ZXJuYWxFcnJvcn0gQWx3YXlzIHRocm93cyBhcyB0aGlzIGZ1bmN0aW9uYWxpdHkgaXMgbm90IGF2YWlsYWJsZSBpbiBDb3VjaERCXG4gICAqL1xuICBvdmVycmlkZSBnZXQgdG90YWwoKTogbnVtYmVyIHtcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgVGhlIHRvdGFsIHBhZ2VzIGFwaSBpcyBub3QgYXZhaWxhYmxlIGZvciBjb3VjaGRiYCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIHRvdGFsIHJlY29yZCBjb3VudFxuICAgKiBAc3VtbWFyeSBOb3Qgc3VwcG9ydGVkIGluIENvdWNoREIgLSB0aHJvd3MgYW4gZXJyb3Igd2hlbiBhY2Nlc3NlZFxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE5ldmVyIHJldHVybnMgYXMgaXQgdGhyb3dzIGFuIGVycm9yXG4gICAqIEB0aHJvd3Mge0ludGVybmFsRXJyb3J9IEFsd2F5cyB0aHJvd3MgYXMgdGhpcyBmdW5jdGlvbmFsaXR5IGlzIG5vdCBhdmFpbGFibGUgaW4gQ291Y2hEQlxuICAgKi9cbiAgb3ZlcnJpZGUgZ2V0IGNvdW50KCk6IG51bWJlciB7XG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICBgVGhlIHJlY29yZCBjb3VudCBhcGkgaXMgbm90IGF2YWlsYWJsZSBmb3IgY291Y2hkYmBcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmV3IENvdWNoREJQYWdpbmF0b3IgaW5zdGFuY2VcbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgYSBwYWdpbmF0b3IgZm9yIENvdWNoREIgcXVlcnkgcmVzdWx0c1xuICAgKiBAcGFyYW0ge0NvdWNoREJBZGFwdGVyPGFueSwgYW55LCBhbnk+fSBhZGFwdGVyIC0gVGhlIENvdWNoREIgYWRhcHRlclxuICAgKiBAcGFyYW0ge01hbmdvUXVlcnl9IHF1ZXJ5IC0gVGhlIE1hbmdvIHF1ZXJ5IHRvIHBhZ2luYXRlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIC0gVGhlIHBhZ2Ugc2l6ZVxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBjbGF6eiAtIFRoZSBtb2RlbCBjb25zdHJ1Y3RvclxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgYWRhcHRlcjogQ291Y2hEQkFkYXB0ZXI8YW55LCBhbnksIGFueT4sXG4gICAgcXVlcnk6IE1hbmdvUXVlcnksXG4gICAgc2l6ZTogbnVtYmVyLFxuICAgIGNsYXp6OiBDb25zdHJ1Y3RvcjxNPlxuICApIHtcbiAgICBzdXBlcihhZGFwdGVyLCBxdWVyeSwgc2l6ZSwgY2xhenopO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcmVwYXJlcyBhIHF1ZXJ5IGZvciBwYWdpbmF0aW9uXG4gICAqIEBzdW1tYXJ5IE1vZGlmaWVzIHRoZSByYXcgcXVlcnkgdG8gaW5jbHVkZSBwYWdpbmF0aW9uIHBhcmFtZXRlcnNcbiAgICogQHBhcmFtIHtNYW5nb1F1ZXJ5fSByYXdTdGF0ZW1lbnQgLSBUaGUgb3JpZ2luYWwgTWFuZ28gcXVlcnlcbiAgICogQHJldHVybiB7TWFuZ29RdWVyeX0gVGhlIHByZXBhcmVkIHF1ZXJ5IHdpdGggcGFnaW5hdGlvbiBwYXJhbWV0ZXJzXG4gICAqL1xuICBwcm90ZWN0ZWQgcHJlcGFyZShyYXdTdGF0ZW1lbnQ6IE1hbmdvUXVlcnkpOiBNYW5nb1F1ZXJ5IHtcbiAgICBjb25zdCBxdWVyeTogTWFuZ29RdWVyeSA9IE9iamVjdC5hc3NpZ24oe30sIHJhd1N0YXRlbWVudCk7XG4gICAgaWYgKHF1ZXJ5LmxpbWl0KSB0aGlzLmxpbWl0ID0gcXVlcnkubGltaXQ7XG5cbiAgICBxdWVyeS5saW1pdCA9IHRoaXMuc2l6ZTtcblxuICAgIHJldHVybiBxdWVyeTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgc3BlY2lmaWMgcGFnZSBvZiByZXN1bHRzXG4gICAqIEBzdW1tYXJ5IEV4ZWN1dGVzIHRoZSBxdWVyeSB3aXRoIHBhZ2luYXRpb24gYW5kIHByb2Nlc3NlcyB0aGUgcmVzdWx0c1xuICAgKiBAcGFyYW0ge251bWJlcn0gW3BhZ2U9MV0gLSBUaGUgcGFnZSBudW1iZXIgdG8gcmV0cmlldmVcbiAgICogQHJldHVybiB7UHJvbWlzZTxSW10+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiByZXN1bHRzXG4gICAqIEB0aHJvd3Mge1BhZ2luZ0Vycm9yfSBJZiB0cnlpbmcgdG8gYWNjZXNzIGEgcGFnZSBvdGhlciB0aGFuIHRoZSBmaXJzdCB3aXRob3V0IGEgYm9va21hcmssIG9yIGlmIG5vIGNsYXNzIGlzIGRlZmluZWRcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gICAqICAgcGFydGljaXBhbnQgQ291Y2hEQlBhZ2luYXRvclxuICAgKiAgIHBhcnRpY2lwYW50IEFkYXB0ZXJcbiAgICogICBwYXJ0aWNpcGFudCBDb3VjaERCXG4gICAqXG4gICAqICAgQ2xpZW50LT4+Q291Y2hEQlBhZ2luYXRvcjogcGFnZShwYWdlTnVtYmVyKVxuICAgKiAgIE5vdGUgb3ZlciBDb3VjaERCUGFnaW5hdG9yOiBDbG9uZSBzdGF0ZW1lbnRcbiAgICogICBDb3VjaERCUGFnaW5hdG9yLT4+Q291Y2hEQlBhZ2luYXRvcjogdmFsaWRhdGVQYWdlKHBhZ2UpXG4gICAqXG4gICAqICAgYWx0IHBhZ2UgIT09IDFcbiAgICogICAgIENvdWNoREJQYWdpbmF0b3ItPj5Db3VjaERCUGFnaW5hdG9yOiBDaGVjayBib29rbWFya1xuICAgKiAgICAgYWx0IE5vIGJvb2ttYXJrXG4gICAqICAgICAgIENvdWNoREJQYWdpbmF0b3ItLT4+Q2xpZW50OiBUaHJvdyBQYWdpbmdFcnJvclxuICAgKiAgICAgZWxzZSBIYXMgYm9va21hcmtcbiAgICogICAgICAgQ291Y2hEQlBhZ2luYXRvci0+PkNvdWNoREJQYWdpbmF0b3I6IEFkZCBib29rbWFyayB0byBzdGF0ZW1lbnRcbiAgICogICAgIGVuZFxuICAgKiAgIGVuZFxuICAgKlxuICAgKiAgIENvdWNoREJQYWdpbmF0b3ItPj5BZGFwdGVyOiByYXcoc3RhdGVtZW50LCBmYWxzZSlcbiAgICogICBBZGFwdGVyLT4+Q291Y2hEQjogRXhlY3V0ZSBxdWVyeVxuICAgKiAgIENvdWNoREItLT4+QWRhcHRlcjogUmV0dXJuIHJlc3VsdHNcbiAgICogICBBZGFwdGVyLS0+PkNvdWNoREJQYWdpbmF0b3I6IFJldHVybiBNYW5nb1Jlc3BvbnNlXG4gICAqXG4gICAqICAgTm90ZSBvdmVyIENvdWNoREJQYWdpbmF0b3I6IFByb2Nlc3MgcmVzdWx0c1xuICAgKlxuICAgKiAgIGFsdCBIYXMgd2FybmluZ1xuICAgKiAgICAgQ291Y2hEQlBhZ2luYXRvci0+PkNvdWNoREJQYWdpbmF0b3I6IExvZyB3YXJuaW5nXG4gICAqICAgZW5kXG4gICAqXG4gICAqICAgQ291Y2hEQlBhZ2luYXRvci0+PkNvdWNoREJQYWdpbmF0b3I6IENoZWNrIGZvciBjbGF6elxuICAgKlxuICAgKiAgIGFsdCBObyBjbGF6elxuICAgKiAgICAgQ291Y2hEQlBhZ2luYXRvci0tPj5DbGllbnQ6IFRocm93IFBhZ2luZ0Vycm9yXG4gICAqICAgZWxzZSBIYXMgY2xhenpcbiAgICogICAgIENvdWNoREJQYWdpbmF0b3ItPj5Db3VjaERCUGFnaW5hdG9yOiBGaW5kIHByaW1hcnkga2V5XG4gICAqXG4gICAqICAgICBhbHQgSGFzIGZpZWxkcyBpbiBzdGF0ZW1lbnRcbiAgICogICAgICAgQ291Y2hEQlBhZ2luYXRvci0+PkNvdWNoREJQYWdpbmF0b3I6IFVzZSBkb2NzIGRpcmVjdGx5XG4gICAqICAgICBlbHNlIE5vIGZpZWxkc1xuICAgKiAgICAgICBDb3VjaERCUGFnaW5hdG9yLT4+Q291Y2hEQlBhZ2luYXRvcjogUHJvY2VzcyBlYWNoIGRvY3VtZW50XG4gICAqICAgICAgIGxvb3AgRm9yIGVhY2ggZG9jdW1lbnRcbiAgICogICAgICAgICBDb3VjaERCUGFnaW5hdG9yLT4+Q291Y2hEQlBhZ2luYXRvcjogRXh0cmFjdCBvcmlnaW5hbCBJRFxuICAgKiAgICAgICAgIENvdWNoREJQYWdpbmF0b3ItPj5BZGFwdGVyOiByZXZlcnQoZG9jLCBjbGF6eiwgcGtEZWYuaWQsIHBhcnNlZElkKVxuICAgKiAgICAgICBlbmRcbiAgICogICAgIGVuZFxuICAgKlxuICAgKiAgICAgQ291Y2hEQlBhZ2luYXRvci0+PkNvdWNoREJQYWdpbmF0b3I6IFN0b3JlIGJvb2ttYXJrXG4gICAqICAgICBDb3VjaERCUGFnaW5hdG9yLT4+Q291Y2hEQlBhZ2luYXRvcjogVXBkYXRlIGN1cnJlbnRQYWdlXG4gICAqICAgICBDb3VjaERCUGFnaW5hdG9yLS0+PkNsaWVudDogUmV0dXJuIHJlc3VsdHNcbiAgICogICBlbmRcbiAgICovXG4gIGFzeW5jIHBhZ2UocGFnZTogbnVtYmVyID0gMSk6IFByb21pc2U8UltdPiB7XG4gICAgY29uc3Qgc3RhdGVtZW50ID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5zdGF0ZW1lbnQpO1xuXG4gICBpZiAoIXRoaXMuX3JlY29yZENvdW50IHx8ICF0aGlzLl90b3RhbFBhZ2VzKSB7XG4gICAgICAgIHRoaXMuX3RvdGFsUGFnZXMgPSB0aGlzLl9yZWNvcmRDb3VudCA9IDA7XG4gICAgICAgIGNvbnN0IHJlc3VsdHM6IFJbXSA9IGF3YWl0IHRoaXMuYWRhcHRlci5yYXcoeyAuLi5zdGF0ZW1lbnQsIGxpbWl0OiB1bmRlZmluZWQgfSkgfHwgW107XG4gICAgICAgIHRoaXMuX3JlY29yZENvdW50ID0gcmVzdWx0cy5sZW5ndGg7XG4gICAgICAgIGlmICh0aGlzLl9yZWNvcmRDb3VudCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IHNpemUgPSBzdGF0ZW1lbnQ/LmxpbWl0IHx8IHRoaXMuc2l6ZTtcbiAgICAgICAgICAgIHRoaXMuX3RvdGFsUGFnZXMgPSBNYXRoLmNlaWwodGhpcy5fcmVjb3JkQ291bnQgLyBzaXplKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMudmFsaWRhdGVQYWdlKHBhZ2UpO1xuXG4gICAgaWYgKHBhZ2UgIT09IDEpIHtcbiAgICAgIGlmICghdGhpcy5ib29rTWFyaylcbiAgICAgICAgdGhyb3cgbmV3IFBhZ2luZ0Vycm9yKFwiTm8gYm9va21hcmsuIERpZCB5b3Ugc3RhcnQgaW4gdGhlIGZpcnN0IHBhZ2U/XCIpO1xuICAgICAgc3RhdGVtZW50W1wiYm9va21hcmtcIl0gPSB0aGlzLmJvb2tNYXJrO1xuICAgIH1cbiAgICBjb25zdCByYXdSZXN1bHQ6IE1hbmdvUmVzcG9uc2U8YW55PiA9IGF3YWl0IHRoaXMuYWRhcHRlci5yYXcoXG4gICAgICBzdGF0ZW1lbnQsXG4gICAgICBmYWxzZVxuICAgICk7XG5cbiAgICBjb25zdCB7IGRvY3MsIGJvb2ttYXJrLCB3YXJuaW5nIH0gPSByYXdSZXN1bHQ7XG4gICAgaWYgKHdhcm5pbmcpIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcbiAgICBpZiAoIXRoaXMuY2xhenopIHRocm93IG5ldyBQYWdpbmdFcnJvcihcIk5vIHN0YXRlbWVudCB0YXJnZXQgZGVmaW5lZFwiKTtcbiAgICBjb25zdCBwa0RlZiA9IGZpbmRQcmltYXJ5S2V5KG5ldyB0aGlzLmNsYXp6KCkpO1xuICAgIGNvbnN0IHJlc3VsdHMgPVxuICAgICAgc3RhdGVtZW50LmZpZWxkcyAmJiBzdGF0ZW1lbnQuZmllbGRzLmxlbmd0aFxuICAgICAgICA/IGRvY3MgLy8gaGFzIGZpZWxkcyBtZWFucyBpdHMgbm90IGZ1bGwgbW9kZWxcbiAgICAgICAgOiBkb2NzLm1hcCgoZDogYW55KSA9PiB7XG4gICAgICAgICAgICAvL25vIGZpZWxkcyBtZWFucyB3ZSBuZWVkIHRvIHJldmVydCB0byBzYXZpbmcgcHJvY2Vzc1xuICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxJZCA9IGQuX2lkLnNwbGl0KENvdWNoREJLZXlzLlNFUEFSQVRPUik7XG4gICAgICAgICAgICBvcmlnaW5hbElkLnNwbGljZSgwLCAxKTsgLy8gcmVtb3ZlIHRoZSB0YWJsZSBuYW1lXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJldmVydChcbiAgICAgICAgICAgICAgZCxcbiAgICAgICAgICAgICAgdGhpcy5jbGF6eixcbiAgICAgICAgICAgICAgcGtEZWYuaWQsXG4gICAgICAgICAgICAgIFNlcXVlbmNlLnBhcnNlVmFsdWUoXG4gICAgICAgICAgICAgICAgcGtEZWYucHJvcHMudHlwZSxcbiAgICAgICAgICAgICAgICBvcmlnaW5hbElkLmpvaW4oQ291Y2hEQktleXMuU0VQQVJBVE9SKVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgIHRoaXMuYm9va01hcmsgPSBib29rbWFyaztcbiAgICB0aGlzLl9jdXJyZW50UGFnZSA9IHBhZ2U7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cbn1cbiIsImltcG9ydCB7IEdyb3VwT3BlcmF0b3IsIE9wZXJhdG9yIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBDb3VjaERCR3JvdXBPcGVyYXRvciwgQ291Y2hEQk9wZXJhdG9yIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBRdWVyeUVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBNYW5nb09wZXJhdG9yIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFRyYW5zbGF0ZXMgY29yZSBvcGVyYXRvcnMgdG8gQ291Y2hEQiBNYW5nbyBvcGVyYXRvcnNcbiAqIEBzdW1tYXJ5IENvbnZlcnRzIERlY2FmLnRzIGNvcmUgb3BlcmF0b3JzIHRvIHRoZWlyIGVxdWl2YWxlbnQgQ291Y2hEQiBNYW5nbyBxdWVyeSBvcGVyYXRvcnNcbiAqIEBwYXJhbSB7R3JvdXBPcGVyYXRvciB8IE9wZXJhdG9yfSBvcGVyYXRvciAtIFRoZSBjb3JlIG9wZXJhdG9yIHRvIHRyYW5zbGF0ZVxuICogQHJldHVybiB7TWFuZ29PcGVyYXRvcn0gVGhlIGVxdWl2YWxlbnQgQ291Y2hEQiBNYW5nbyBvcGVyYXRvclxuICogQHRocm93cyB7UXVlcnlFcnJvcn0gSWYgbm8gdHJhbnNsYXRpb24gZXhpc3RzIGZvciB0aGUgZ2l2ZW4gb3BlcmF0b3JcbiAqIEBmdW5jdGlvbiB0cmFuc2xhdGVPcGVyYXRvcnNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Zm9yLWNvdWNoZGJcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IHRyYW5zbGF0ZU9wZXJhdG9yc1xuICogICBwYXJ0aWNpcGFudCBDb3VjaERCT3BlcmF0b3JcbiAqICAgcGFydGljaXBhbnQgQ291Y2hEQkdyb3VwT3BlcmF0b3JcbiAqICAgXG4gKiAgIENhbGxlci0+PnRyYW5zbGF0ZU9wZXJhdG9yczogb3BlcmF0b3JcbiAqICAgXG4gKiAgIHRyYW5zbGF0ZU9wZXJhdG9ycy0+PkNvdWNoREJPcGVyYXRvcjogQ2hlY2sgZm9yIG1hdGNoXG4gKiAgIGFsdCBGb3VuZCBpbiBDb3VjaERCT3BlcmF0b3JcbiAqICAgICBDb3VjaERCT3BlcmF0b3ItLT4+dHJhbnNsYXRlT3BlcmF0b3JzOiBSZXR1cm4gbWF0Y2hpbmcgb3BlcmF0b3JcbiAqICAgICB0cmFuc2xhdGVPcGVyYXRvcnMtLT4+Q2FsbGVyOiBSZXR1cm4gTWFuZ29PcGVyYXRvclxuICogICBlbHNlIE5vdCBmb3VuZFxuICogICAgIHRyYW5zbGF0ZU9wZXJhdG9ycy0+PkNvdWNoREJHcm91cE9wZXJhdG9yOiBDaGVjayBmb3IgbWF0Y2hcbiAqICAgICBhbHQgRm91bmQgaW4gQ291Y2hEQkdyb3VwT3BlcmF0b3JcbiAqICAgICAgIENvdWNoREJHcm91cE9wZXJhdG9yLS0+PnRyYW5zbGF0ZU9wZXJhdG9yczogUmV0dXJuIG1hdGNoaW5nIG9wZXJhdG9yXG4gKiAgICAgICB0cmFuc2xhdGVPcGVyYXRvcnMtLT4+Q2FsbGVyOiBSZXR1cm4gTWFuZ29PcGVyYXRvclxuICogICAgIGVsc2UgTm90IGZvdW5kXG4gKiAgICAgICB0cmFuc2xhdGVPcGVyYXRvcnMtLT4+Q2FsbGVyOiBUaHJvdyBRdWVyeUVycm9yXG4gKiAgICAgZW5kXG4gKiAgIGVuZFxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNsYXRlT3BlcmF0b3JzKFxuICBvcGVyYXRvcjogR3JvdXBPcGVyYXRvciB8IE9wZXJhdG9yXG4pOiBNYW5nb09wZXJhdG9yIHtcbiAgZm9yIChjb25zdCBvcGVyYXRvcnMgb2YgW0NvdWNoREJPcGVyYXRvciwgQ291Y2hEQkdyb3VwT3BlcmF0b3JdKSB7XG4gICAgY29uc3QgZWwgPSBPYmplY3Qua2V5cyhvcGVyYXRvcnMpLmZpbmQoKGspID0+IGsgPT09IG9wZXJhdG9yKTtcbiAgICBpZiAoZWwpIHJldHVybiBvcGVyYXRvcnNbZWxdO1xuICB9XG4gIHRocm93IG5ldyBRdWVyeUVycm9yKFxuICAgIGBDb3VsZCBub3QgZmluZCBhZGFwdGVyIHRyYW5zbGF0aW9uIGZvciBvcGVyYXRvciAke29wZXJhdG9yfWBcbiAgKTtcbn1cbiIsImltcG9ydCB7XG4gIENvbmRpdGlvbixcbiAgR3JvdXBPcGVyYXRvcixcbiAgT3BlcmF0b3IsXG4gIE9yZGVyRGlyZWN0aW9uLFxuICBQYWdpbmF0b3IsXG4gIFJlcG9zaXRvcnksXG4gIFNlcXVlbmNlLFxuICBTdGF0ZW1lbnQsXG59IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgTWFuZ29PcGVyYXRvciwgTWFuZ29RdWVyeSwgTWFuZ29TZWxlY3RvciB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBDb3VjaERCQWRhcHRlciB9IGZyb20gXCIuLi9hZGFwdGVyXCI7XG5pbXBvcnQgeyB0cmFuc2xhdGVPcGVyYXRvcnMgfSBmcm9tIFwiLi90cmFuc2xhdGVcIjtcbmltcG9ydCB7IENvdWNoREJLZXlzIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHtcbiAgQ291Y2hEQkdyb3VwT3BlcmF0b3IsXG4gIENvdWNoREJPcGVyYXRvcixcbiAgQ291Y2hEQlF1ZXJ5TGltaXQsXG59IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQ291Y2hEQlBhZ2luYXRvciB9IGZyb20gXCIuL1BhZ2luYXRvclwiO1xuaW1wb3J0IHsgZmluZFByaW1hcnlLZXksIEludGVybmFsRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gU3RhdGVtZW50IGJ1aWxkZXIgZm9yIENvdWNoREIgTWFuZ28gcXVlcmllc1xuICogQHN1bW1hcnkgUHJvdmlkZXMgYSBmbHVlbnQgaW50ZXJmYWNlIGZvciBidWlsZGluZyBDb3VjaERCIE1hbmdvIHF1ZXJpZXMgd2l0aCB0eXBlIHNhZmV0eVxuICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZSB0aGF0IGV4dGVuZHMgTW9kZWxcbiAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHJlc3VsdCB0eXBlXG4gKiBAcGFyYW0gYWRhcHRlciAtIFRoZSBDb3VjaERCIGFkYXB0ZXJcbiAqIEBjbGFzcyBDb3VjaERCU3RhdGVtZW50XG4gKiBAZXhhbXBsZVxuICogLy8gRXhhbXBsZSBvZiB1c2luZyBDb3VjaERCU3RhdGVtZW50XG4gKiBjb25zdCBhZGFwdGVyID0gbmV3IE15Q291Y2hEQkFkYXB0ZXIoc2NvcGUpO1xuICogY29uc3Qgc3RhdGVtZW50ID0gbmV3IENvdWNoREJTdGF0ZW1lbnQ8VXNlciwgVXNlcltdPihhZGFwdGVyKTtcbiAqXG4gKiAvLyBCdWlsZCBhIHF1ZXJ5XG4gKiBjb25zdCB1c2VycyA9IGF3YWl0IHN0YXRlbWVudFxuICogICAuZnJvbShVc2VyKVxuICogICAud2hlcmUoQ29uZGl0aW9uLmF0dHJpYnV0ZTxVc2VyPignYWdlJykuZ3QoMTgpKVxuICogICAub3JkZXJCeSgnbGFzdE5hbWUnLCAnYXNjJylcbiAqICAgLmxpbWl0KDEwKVxuICogICAuZXhlY3V0ZSgpO1xuICovXG5leHBvcnQgY2xhc3MgQ291Y2hEQlN0YXRlbWVudDxNIGV4dGVuZHMgTW9kZWwsIFI+IGV4dGVuZHMgU3RhdGVtZW50PFxuICBNYW5nb1F1ZXJ5LFxuICBNLFxuICBSXG4+IHtcbiAgY29uc3RydWN0b3IoYWRhcHRlcjogQ291Y2hEQkFkYXB0ZXI8YW55LCBhbnksIGFueT4pIHtcbiAgICBzdXBlcihhZGFwdGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQnVpbGRzIGEgQ291Y2hEQiBNYW5nbyBxdWVyeSBmcm9tIHRoZSBzdGF0ZW1lbnRcbiAgICogQHN1bW1hcnkgQ29udmVydHMgdGhlIHN0YXRlbWVudCdzIGNvbmRpdGlvbnMsIHNlbGVjdG9ycywgYW5kIG9wdGlvbnMgaW50byBhIENvdWNoREIgTWFuZ28gcXVlcnlcbiAgICogQHJldHVybiB7TWFuZ29RdWVyeX0gVGhlIGJ1aWx0IE1hbmdvIHF1ZXJ5XG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGVyZSBhcmUgaW52YWxpZCBxdWVyeSBjb25kaXRpb25zXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IFN0YXRlbWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFJlcG9zaXRvcnlcbiAgICogICBwYXJ0aWNpcGFudCBwYXJzZUNvbmRpdGlvblxuICAgKlxuICAgKiAgIFN0YXRlbWVudC0+PlN0YXRlbWVudDogYnVpbGQoKVxuICAgKiAgIE5vdGUgb3ZlciBTdGF0ZW1lbnQ6IEluaXRpYWxpemUgc2VsZWN0b3JzXG4gICAqICAgU3RhdGVtZW50LT4+UmVwb3NpdG9yeTogR2V0IHRhYmxlIG5hbWVcbiAgICogICBSZXBvc2l0b3J5LS0+PlN0YXRlbWVudDogUmV0dXJuIHRhYmxlIG5hbWVcbiAgICogICBTdGF0ZW1lbnQtPj5TdGF0ZW1lbnQ6IENyZWF0ZSBiYXNlIHF1ZXJ5XG4gICAqXG4gICAqICAgYWx0IEhhcyBzZWxlY3RTZWxlY3RvclxuICAgKiAgICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBBZGQgZmllbGRzIHRvIHF1ZXJ5XG4gICAqICAgZW5kXG4gICAqXG4gICAqICAgYWx0IEhhcyB3aGVyZUNvbmRpdGlvblxuICAgKiAgICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBDcmVhdGUgY29tYmluZWQgY29uZGl0aW9uIHdpdGggdGFibGVcbiAgICogICAgIFN0YXRlbWVudC0+PnBhcnNlQ29uZGl0aW9uOiBQYXJzZSBjb25kaXRpb25cbiAgICogICAgIHBhcnNlQ29uZGl0aW9uLS0+PlN0YXRlbWVudDogUmV0dXJuIHBhcnNlZCBjb25kaXRpb25cbiAgICpcbiAgICogICAgIGFsdCBJcyBncm91cCBvcGVyYXRvclxuICAgKiAgICAgICBhbHQgSXMgQU5EIG9wZXJhdG9yXG4gICAqICAgICAgICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBGbGF0dGVuIG5lc3RlZCBBTkQgY29uZGl0aW9uc1xuICAgKiAgICAgICBlbHNlIElzIE9SIG9wZXJhdG9yXG4gICAqICAgICAgICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBDb21iaW5lIHdpdGggdGFibGUgY29uZGl0aW9uXG4gICAqICAgICAgIGVsc2VcbiAgICogICAgICAgICBTdGF0ZW1lbnQtPj5TdGF0ZW1lbnQ6IFRocm93IGVycm9yXG4gICAqICAgICAgIGVuZFxuICAgKiAgICAgZWxzZVxuICAgKiAgICAgICBTdGF0ZW1lbnQtPj5TdGF0ZW1lbnQ6IE1lcmdlIGNvbmRpdGlvbnMgd2l0aCBleGlzdGluZyBzZWxlY3RvclxuICAgKiAgICAgZW5kXG4gICAqICAgZW5kXG4gICAqXG4gICAqICAgYWx0IEhhcyBvcmRlckJ5U2VsZWN0b3JcbiAgICogICAgIFN0YXRlbWVudC0+PlN0YXRlbWVudDogQWRkIHNvcnQgdG8gcXVlcnlcbiAgICogICAgIFN0YXRlbWVudC0+PlN0YXRlbWVudDogRW5zdXJlIGZpZWxkIGV4aXN0cyBpbiBzZWxlY3RvclxuICAgKiAgIGVuZFxuICAgKlxuICAgKiAgIGFsdCBIYXMgbGltaXRTZWxlY3RvclxuICAgKiAgICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBTZXQgbGltaXRcbiAgICogICBlbHNlXG4gICAqICAgICBTdGF0ZW1lbnQtPj5TdGF0ZW1lbnQ6IFVzZSBkZWZhdWx0IGxpbWl0XG4gICAqICAgZW5kXG4gICAqXG4gICAqICAgYWx0IEhhcyBvZmZzZXRTZWxlY3RvclxuICAgKiAgICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBTZXQgc2tpcFxuICAgKiAgIGVuZFxuICAgKlxuICAgKiAgIFN0YXRlbWVudC0tPj5TdGF0ZW1lbnQ6IFJldHVybiBxdWVyeVxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkKCk6IE1hbmdvUXVlcnkge1xuICAgIGNvbnN0IHNlbGVjdG9yczogTWFuZ29TZWxlY3RvciA9IHt9O1xuICAgIHNlbGVjdG9yc1tDb3VjaERCS2V5cy5UQUJMRV0gPSB7fTtcbiAgICBzZWxlY3RvcnNbQ291Y2hEQktleXMuVEFCTEVdID0gUmVwb3NpdG9yeS50YWJsZSh0aGlzLmZyb21TZWxlY3Rvcik7XG4gICAgY29uc3QgcXVlcnk6IE1hbmdvUXVlcnkgPSB7IHNlbGVjdG9yOiBzZWxlY3RvcnMgfTtcbiAgICBpZiAodGhpcy5zZWxlY3RTZWxlY3RvcikgcXVlcnkuZmllbGRzID0gdGhpcy5zZWxlY3RTZWxlY3RvciBhcyBzdHJpbmdbXTtcblxuICAgIGlmICh0aGlzLndoZXJlQ29uZGl0aW9uKSB7XG4gICAgICBjb25zdCBjb25kaXRpb246IE1hbmdvU2VsZWN0b3IgPSB0aGlzLnBhcnNlQ29uZGl0aW9uKFxuICAgICAgICBDb25kaXRpb24uYW5kKFxuICAgICAgICAgIHRoaXMud2hlcmVDb25kaXRpb24sXG4gICAgICAgICAgQ29uZGl0aW9uLmF0dHJpYnV0ZTxNPihDb3VjaERCS2V5cy5UQUJMRSBhcyBrZXlvZiBNKS5lcShcbiAgICAgICAgICAgIHF1ZXJ5LnNlbGVjdG9yW0NvdWNoREJLZXlzLlRBQkxFXVxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgKS5zZWxlY3RvcjtcbiAgICAgIGNvbnN0IHNlbGVjdG9yS2V5cyA9IE9iamVjdC5rZXlzKGNvbmRpdGlvbikgYXMgTWFuZ29PcGVyYXRvcltdO1xuICAgICAgaWYgKFxuICAgICAgICBzZWxlY3RvcktleXMubGVuZ3RoID09PSAxICYmXG4gICAgICAgIE9iamVjdC52YWx1ZXMoQ291Y2hEQkdyb3VwT3BlcmF0b3IpLmluZGV4T2Yoc2VsZWN0b3JLZXlzWzBdKSAhPT0gLTFcbiAgICAgIClcbiAgICAgICAgc3dpdGNoIChzZWxlY3RvcktleXNbMF0pIHtcbiAgICAgICAgICBjYXNlIENvdWNoREJHcm91cE9wZXJhdG9yLkFORDpcbiAgICAgICAgICAgIGNvbmRpdGlvbltDb3VjaERCR3JvdXBPcGVyYXRvci5BTkRdID0gW1xuICAgICAgICAgICAgICAuLi5PYmplY3QudmFsdWVzKFxuICAgICAgICAgICAgICAgIGNvbmRpdGlvbltDb3VjaERCR3JvdXBPcGVyYXRvci5BTkRdIGFzIE1hbmdvU2VsZWN0b3JcbiAgICAgICAgICAgICAgKS5yZWR1Y2UoKGFjY3VtOiBNYW5nb1NlbGVjdG9yW10sIHZhbDogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHZhbCk7XG4gICAgICAgICAgICAgICAgaWYgKGtleXMubGVuZ3RoICE9PSAxKVxuICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICBcIlRvbyBtYW55IGtleXMgaW4gcXVlcnkgc2VsZWN0b3IuIHNob3VsZCBiZSBvbmVcIlxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBjb25zdCBrID0ga2V5c1swXTtcbiAgICAgICAgICAgICAgICBpZiAoayA9PT0gQ291Y2hEQkdyb3VwT3BlcmF0b3IuQU5EKVxuICAgICAgICAgICAgICAgICAgYWNjdW0ucHVzaCguLi4odmFsW2tdIGFzIGFueVtdKSk7XG4gICAgICAgICAgICAgICAgZWxzZSBhY2N1bS5wdXNoKHZhbCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgICAgICAgICB9LCBbXSksXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgcXVlcnkuc2VsZWN0b3IgPSBjb25kaXRpb247XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIENvdWNoREJHcm91cE9wZXJhdG9yLk9SOiB7XG4gICAgICAgICAgICBjb25zdCBzOiBSZWNvcmQ8YW55LCBhbnk+ID0ge307XG4gICAgICAgICAgICBzW0NvdWNoREJHcm91cE9wZXJhdG9yLkFORF0gPSBbXG4gICAgICAgICAgICAgIGNvbmRpdGlvbixcbiAgICAgICAgICAgICAgLi4uT2JqZWN0LmVudHJpZXMocXVlcnkuc2VsZWN0b3IpLm1hcCgoW2tleSwgdmFsXSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdDogUmVjb3JkPGFueSwgYW55PiA9IHt9O1xuICAgICAgICAgICAgICAgIHJlc3VsdFtrZXldID0gdmFsO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIHF1ZXJ5LnNlbGVjdG9yID0gcztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBzaG91bGQgYmUgaW1wb3NzaWJsZVwiKTtcbiAgICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIE9iamVjdC5lbnRyaWVzKGNvbmRpdGlvbikuZm9yRWFjaCgoW2tleSwgdmFsXSkgPT4ge1xuICAgICAgICAgIGlmIChxdWVyeS5zZWxlY3RvcltrZXldKVxuICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICBgQSAke2tleX0gcXVlcnkgcGFyYW0gaXMgYWJvdXQgdG8gYmUgb3ZlcnJpZGRlbjogJHtxdWVyeS5zZWxlY3RvcltrZXldfSBieSAke3ZhbH1gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIHF1ZXJ5LnNlbGVjdG9yW2tleV0gPSB2YWw7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLm9yZGVyQnlTZWxlY3Rvcikge1xuICAgICAgcXVlcnkuc29ydCA9IHF1ZXJ5LnNvcnQgfHwgW107XG4gICAgICBxdWVyeS5zZWxlY3RvciA9IHF1ZXJ5LnNlbGVjdG9yIHx8ICh7fSBhcyBNYW5nb1NlbGVjdG9yKTtcbiAgICAgIGNvbnN0IFtzZWxlY3RvciwgdmFsdWVdID0gdGhpcy5vcmRlckJ5U2VsZWN0b3IgYXMgW1xuICAgICAgICBzdHJpbmcsXG4gICAgICAgIE9yZGVyRGlyZWN0aW9uLFxuICAgICAgXTtcbiAgICAgIGNvbnN0IHJlYzogYW55ID0ge307XG4gICAgICByZWNbc2VsZWN0b3JdID0gdmFsdWU7XG4gICAgICAocXVlcnkuc29ydCBhcyBhbnlbXSkucHVzaChyZWMgYXMgYW55KTtcbiAgICAgIGlmICghcXVlcnkuc2VsZWN0b3Jbc2VsZWN0b3JdKSB7XG4gICAgICAgIHF1ZXJ5LnNlbGVjdG9yW3NlbGVjdG9yXSA9IHt9IGFzIE1hbmdvU2VsZWN0b3I7XG4gICAgICAgIChxdWVyeS5zZWxlY3RvcltzZWxlY3Rvcl0gYXMgTWFuZ29TZWxlY3RvcilbQ291Y2hEQk9wZXJhdG9yLkJJR0dFUl0gPVxuICAgICAgICAgIG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubGltaXRTZWxlY3Rvcikge1xuICAgICAgcXVlcnkubGltaXQgPSB0aGlzLmxpbWl0U2VsZWN0b3I7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYE5vIGxpbWl0IHNlbGVjdG9yIGRlZmluZWQuIFVzaW5nIGRlZmF1bHQgY291Y2hkYiBsaW1pdCBvZiAke0NvdWNoREJRdWVyeUxpbWl0fWBcbiAgICAgICk7XG4gICAgICBxdWVyeS5saW1pdCA9IENvdWNoREJRdWVyeUxpbWl0O1xuICAgIH1cblxuICAgIGlmICh0aGlzLm9mZnNldFNlbGVjdG9yKSBxdWVyeS5za2lwID0gdGhpcy5vZmZzZXRTZWxlY3RvcjtcblxuICAgIHJldHVybiBxdWVyeTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIHBhZ2luYXRvciBmb3IgdGhlIHN0YXRlbWVudFxuICAgKiBAc3VtbWFyeSBCdWlsZHMgdGhlIHF1ZXJ5IGFuZCByZXR1cm5zIGEgQ291Y2hEQlBhZ2luYXRvciBmb3IgcGFnaW5hdGVkIHJlc3VsdHNcbiAgICogQHRlbXBsYXRlIFIgLSBUaGUgcmVzdWx0IHR5cGVcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNpemUgLSBUaGUgcGFnZSBzaXplXG4gICAqIEByZXR1cm4ge1Byb21pc2U8UGFnaW5hdG9yPE0sIFIsIE1hbmdvUXVlcnk+Pn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBwYWdpbmF0b3JcbiAgICogQHRocm93cyB7SW50ZXJuYWxFcnJvcn0gSWYgdGhlcmUncyBhbiBlcnJvciBidWlsZGluZyB0aGUgcXVlcnlcbiAgICovXG4gIGFzeW5jIHBhZ2luYXRlPFI+KHNpemU6IG51bWJlcik6IFByb21pc2U8UGFnaW5hdG9yPE0sIFIsIE1hbmdvUXVlcnk+PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHF1ZXJ5OiBNYW5nb1F1ZXJ5ID0gdGhpcy5idWlsZCgpO1xuICAgICAgcmV0dXJuIG5ldyBDb3VjaERCUGFnaW5hdG9yKFxuICAgICAgICB0aGlzLmFkYXB0ZXIgYXMgYW55LFxuICAgICAgICBxdWVyeSxcbiAgICAgICAgc2l6ZSxcbiAgICAgICAgdGhpcy5mcm9tU2VsZWN0b3JcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByb2Nlc3NlcyBhIHJlY29yZCBmcm9tIENvdWNoREJcbiAgICogQHN1bW1hcnkgRXh0cmFjdHMgdGhlIElEIGZyb20gYSBDb3VjaERCIGRvY3VtZW50IGFuZCByZXZlcnRzIGl0IHRvIGEgbW9kZWwgaW5zdGFuY2VcbiAgICogQHBhcmFtIHthbnl9IHIgLSBUaGUgcmF3IHJlY29yZCBmcm9tIENvdWNoREJcbiAgICogQHBhcmFtIHBrQXR0ciAtIFRoZSBwcmltYXJ5IGtleSBhdHRyaWJ1dGUgb2YgdGhlIG1vZGVsXG4gICAqIEBwYXJhbSB7XCJOdW1iZXJcIiB8IFwiQmlnSW50XCIgfCB1bmRlZmluZWR9IHNlcXVlbmNlVHlwZSAtIFRoZSB0eXBlIG9mIHRoZSBzZXF1ZW5jZVxuICAgKiBAcmV0dXJuIHthbnl9IFRoZSBwcm9jZXNzZWQgcmVjb3JkXG4gICAqL1xuICBwcml2YXRlIHByb2Nlc3NSZWNvcmQoXG4gICAgcjogYW55LFxuICAgIHBrQXR0cjoga2V5b2YgTSxcbiAgICBzZXF1ZW5jZVR5cGU6IFwiTnVtYmVyXCIgfCBcIkJpZ0ludFwiIHwgdW5kZWZpbmVkXG4gICkge1xuICAgIGlmIChyW0NvdWNoREJLZXlzLklEXSkge1xuICAgICAgY29uc3QgWywgLi4ua2V5QXJnc10gPSByW0NvdWNoREJLZXlzLklEXS5zcGxpdChDb3VjaERCS2V5cy5TRVBBUkFUT1IpO1xuXG4gICAgICBjb25zdCBpZCA9IGtleUFyZ3Muam9pbihcIl9cIik7XG4gICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJldmVydChcbiAgICAgICAgcixcbiAgICAgICAgdGhpcy5mcm9tU2VsZWN0b3IsXG4gICAgICAgIHBrQXR0cixcbiAgICAgICAgU2VxdWVuY2UucGFyc2VWYWx1ZShzZXF1ZW5jZVR5cGUsIGlkKVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEV4ZWN1dGVzIGEgcmF3IE1hbmdvIHF1ZXJ5XG4gICAqIEBzdW1tYXJ5IFNlbmRzIGEgcmF3IE1hbmdvIHF1ZXJ5IHRvIENvdWNoREIgYW5kIHByb2Nlc3NlcyB0aGUgcmVzdWx0c1xuICAgKiBAdGVtcGxhdGUgUiAtIFRoZSByZXN1bHQgdHlwZVxuICAgKiBAcGFyYW0ge01hbmdvUXVlcnl9IHJhd0lucHV0IC0gVGhlIHJhdyBNYW5nbyBxdWVyeSB0byBleGVjdXRlXG4gICAqIEByZXR1cm4ge1Byb21pc2U8Uj59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBxdWVyeSByZXN1bHRzXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyByYXc8Uj4ocmF3SW5wdXQ6IE1hbmdvUXVlcnkpOiBQcm9taXNlPFI+IHtcbiAgICBjb25zdCByZXN1bHRzOiBhbnlbXSA9IGF3YWl0IHRoaXMuYWRhcHRlci5yYXcocmF3SW5wdXQsIHRydWUpO1xuXG4gICAgY29uc3QgcGtEZWYgPSBmaW5kUHJpbWFyeUtleShuZXcgdGhpcy5mcm9tU2VsZWN0b3IoKSk7XG4gICAgY29uc3QgcGtBdHRyID0gcGtEZWYuaWQ7XG4gICAgY29uc3QgdHlwZSA9IHBrRGVmLnByb3BzLnR5cGU7XG5cbiAgICBpZiAoIXRoaXMuc2VsZWN0U2VsZWN0b3IpXG4gICAgICByZXR1cm4gcmVzdWx0cy5tYXAoKHIpID0+IHRoaXMucHJvY2Vzc1JlY29yZChyLCBwa0F0dHIsIHR5cGUpKSBhcyBSO1xuICAgIHJldHVybiByZXN1bHRzIGFzIFI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFBhcnNlcyBhIGNvbmRpdGlvbiBpbnRvIGEgQ291Y2hEQiBNYW5nbyBxdWVyeSBzZWxlY3RvclxuICAgKiBAc3VtbWFyeSBDb252ZXJ0cyBhIENvbmRpdGlvbiBvYmplY3QgaW50byBhIENvdWNoREIgTWFuZ28gcXVlcnkgc2VsZWN0b3Igc3RydWN0dXJlXG4gICAqIEBwYXJhbSB7Q29uZGl0aW9uPE0+fSBjb25kaXRpb24gLSBUaGUgY29uZGl0aW9uIHRvIHBhcnNlXG4gICAqIEByZXR1cm4ge01hbmdvUXVlcnl9IFRoZSBNYW5nbyBxdWVyeSB3aXRoIHRoZSBwYXJzZWQgY29uZGl0aW9uIGFzIGl0cyBzZWxlY3RvclxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBTdGF0ZW1lbnRcbiAgICogICBwYXJ0aWNpcGFudCB0cmFuc2xhdGVPcGVyYXRvcnNcbiAgICogICBwYXJ0aWNpcGFudCBtZXJnZVxuICAgKlxuICAgKiAgIFN0YXRlbWVudC0+PlN0YXRlbWVudDogcGFyc2VDb25kaXRpb24oY29uZGl0aW9uKVxuICAgKlxuICAgKiAgIE5vdGUgb3ZlciBTdGF0ZW1lbnQ6IEV4dHJhY3QgY29uZGl0aW9uIHBhcnRzXG4gICAqXG4gICAqICAgYWx0IFNpbXBsZSBjb21wYXJpc29uIG9wZXJhdG9yXG4gICAqICAgICBTdGF0ZW1lbnQtPj50cmFuc2xhdGVPcGVyYXRvcnM6IHRyYW5zbGF0ZU9wZXJhdG9ycyhvcGVyYXRvcilcbiAgICogICAgIHRyYW5zbGF0ZU9wZXJhdG9ycy0tPj5TdGF0ZW1lbnQ6IFJldHVybiBDb3VjaERCIG9wZXJhdG9yXG4gICAqICAgICBTdGF0ZW1lbnQtPj5TdGF0ZW1lbnQ6IENyZWF0ZSBzZWxlY3RvciB3aXRoIGF0dHJpYnV0ZSBhbmQgb3BlcmF0b3JcbiAgICogICBlbHNlIE5PVCBvcGVyYXRvclxuICAgKiAgICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBwYXJzZUNvbmRpdGlvbihhdHRyMSlcbiAgICogICAgIFN0YXRlbWVudC0+PnRyYW5zbGF0ZU9wZXJhdG9yczogdHJhbnNsYXRlT3BlcmF0b3JzKE9wZXJhdG9yLk5PVClcbiAgICogICAgIHRyYW5zbGF0ZU9wZXJhdG9ycy0tPj5TdGF0ZW1lbnQ6IFJldHVybiBDb3VjaERCIE5PVCBvcGVyYXRvclxuICAgKiAgICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBDcmVhdGUgbmVnYXRlZCBzZWxlY3RvclxuICAgKiAgIGVsc2UgQU5EL09SIG9wZXJhdG9yXG4gICAqICAgICBTdGF0ZW1lbnQtPj5TdGF0ZW1lbnQ6IHBhcnNlQ29uZGl0aW9uKGF0dHIxKVxuICAgKiAgICAgU3RhdGVtZW50LT4+U3RhdGVtZW50OiBwYXJzZUNvbmRpdGlvbihjb21wYXJpc29uKVxuICAgKiAgICAgU3RhdGVtZW50LT4+dHJhbnNsYXRlT3BlcmF0b3JzOiB0cmFuc2xhdGVPcGVyYXRvcnMob3BlcmF0b3IpXG4gICAqICAgICB0cmFuc2xhdGVPcGVyYXRvcnMtLT4+U3RhdGVtZW50OiBSZXR1cm4gQ291Y2hEQiBncm91cCBvcGVyYXRvclxuICAgKiAgICAgU3RhdGVtZW50LT4+bWVyZ2U6IG1lcmdlKG9wZXJhdG9yLCBvcDEsIG9wMilcbiAgICogICAgIG1lcmdlLS0+PlN0YXRlbWVudDogUmV0dXJuIG1lcmdlZCBzZWxlY3RvclxuICAgKiAgIGVuZFxuICAgKlxuICAgKiAgIFN0YXRlbWVudC0tPj5TdGF0ZW1lbnQ6IFJldHVybiBxdWVyeSB3aXRoIHNlbGVjdG9yXG4gICAqL1xuICBwcm90ZWN0ZWQgcGFyc2VDb25kaXRpb24oY29uZGl0aW9uOiBDb25kaXRpb248TT4pOiBNYW5nb1F1ZXJ5IHtcbiAgICAvKipcbiAgICAgKiBAZGVzY3JpcHRpb24gTWVyZ2VzIHR3byBzZWxlY3RvcnMgd2l0aCBhIGxvZ2ljYWwgb3BlcmF0b3JcbiAgICAgKiBAc3VtbWFyeSBIZWxwZXIgZnVuY3Rpb24gdG8gY29tYmluZSB0d28gc2VsZWN0b3JzIHdpdGggYSBsb2dpY2FsIG9wZXJhdG9yXG4gICAgICogQHBhcmFtIHtNYW5nb09wZXJhdG9yfSBvcCAtIFRoZSBvcGVyYXRvciB0byB1c2UgZm9yIG1lcmdpbmdcbiAgICAgKiBAcGFyYW0ge01hbmdvU2VsZWN0b3J9IG9iajEgLSBUaGUgZmlyc3Qgc2VsZWN0b3JcbiAgICAgKiBAcGFyYW0ge01hbmdvU2VsZWN0b3J9IG9iajIgLSBUaGUgc2Vjb25kIHNlbGVjdG9yXG4gICAgICogQHJldHVybiB7TWFuZ29RdWVyeX0gVGhlIG1lcmdlZCBxdWVyeVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1lcmdlKFxuICAgICAgb3A6IE1hbmdvT3BlcmF0b3IsXG4gICAgICBvYmoxOiBNYW5nb1NlbGVjdG9yLFxuICAgICAgb2JqMjogTWFuZ29TZWxlY3RvclxuICAgICk6IE1hbmdvUXVlcnkge1xuICAgICAgY29uc3QgcmVzdWx0OiBNYW5nb1F1ZXJ5ID0geyBzZWxlY3Rvcjoge30gYXMgTWFuZ29TZWxlY3RvciB9O1xuICAgICAgcmVzdWx0LnNlbGVjdG9yW29wXSA9IFtvYmoxLCBvYmoyXTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgY29uc3QgeyBhdHRyMSwgb3BlcmF0b3IsIGNvbXBhcmlzb24gfSA9IGNvbmRpdGlvbiBhcyB1bmtub3duIGFzIHtcbiAgICAgIGF0dHIxOiBzdHJpbmcgfCBDb25kaXRpb248TT47XG4gICAgICBvcGVyYXRvcjogT3BlcmF0b3IgfCBHcm91cE9wZXJhdG9yO1xuICAgICAgY29tcGFyaXNvbjogYW55O1xuICAgIH07XG5cbiAgICBsZXQgb3A6IE1hbmdvU2VsZWN0b3IgPSB7fSBhcyBNYW5nb1NlbGVjdG9yO1xuICAgIGlmIChcbiAgICAgIFtHcm91cE9wZXJhdG9yLkFORCwgR3JvdXBPcGVyYXRvci5PUiwgT3BlcmF0b3IuTk9UXS5pbmRleE9mKFxuICAgICAgICBvcGVyYXRvciBhcyBHcm91cE9wZXJhdG9yXG4gICAgICApID09PSAtMVxuICAgICkge1xuICAgICAgb3BbYXR0cjEgYXMgc3RyaW5nXSA9IHt9IGFzIE1hbmdvU2VsZWN0b3I7XG4gICAgICAob3BbYXR0cjEgYXMgc3RyaW5nXSBhcyBNYW5nb1NlbGVjdG9yKVt0cmFuc2xhdGVPcGVyYXRvcnMob3BlcmF0b3IpXSA9XG4gICAgICAgIGNvbXBhcmlzb247XG4gICAgfSBlbHNlIGlmIChvcGVyYXRvciA9PT0gT3BlcmF0b3IuTk9UKSB7XG4gICAgICBvcCA9IHRoaXMucGFyc2VDb25kaXRpb24oYXR0cjEgYXMgQ29uZGl0aW9uPE0+KS5zZWxlY3RvciBhcyBNYW5nb1NlbGVjdG9yO1xuICAgICAgb3BbdHJhbnNsYXRlT3BlcmF0b3JzKE9wZXJhdG9yLk5PVCldID0ge30gYXMgTWFuZ29TZWxlY3RvcjtcbiAgICAgIChvcFt0cmFuc2xhdGVPcGVyYXRvcnMoT3BlcmF0b3IuTk9UKV0gYXMgTWFuZ29TZWxlY3RvcilbXG4gICAgICAgIChhdHRyMSBhcyB1bmtub3duIGFzIHsgYXR0cjE6IHN0cmluZyB9KS5hdHRyMVxuICAgICAgXSA9IGNvbXBhcmlzb247XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG9wMTogYW55ID0gdGhpcy5wYXJzZUNvbmRpdGlvbihhdHRyMSBhcyBDb25kaXRpb248TT4pLnNlbGVjdG9yO1xuICAgICAgY29uc3Qgb3AyOiBhbnkgPSB0aGlzLnBhcnNlQ29uZGl0aW9uKGNvbXBhcmlzb24gYXMgQ29uZGl0aW9uPE0+KS5zZWxlY3RvcjtcbiAgICAgIG9wID0gbWVyZ2UodHJhbnNsYXRlT3BlcmF0b3JzKG9wZXJhdG9yKSwgb3AxLCBvcDIpLnNlbGVjdG9yO1xuICAgIH1cblxuICAgIHJldHVybiB7IHNlbGVjdG9yOiBvcCB9O1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBBZGFwdGVyLFxuICBTZXF1ZW5jZSxcbiAgdHlwZSBTZXF1ZW5jZU9wdGlvbnMsXG4gIFBlcnNpc3RlbmNlS2V5cyxcbiAgQ29ubmVjdGlvbkVycm9yLFxuICBSZXBvc2l0b3J5LFxufSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IENvdWNoREJLZXlzLCByZXNlcnZlZEF0dHJpYnV0ZXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gIEJhc2VFcnJvcixcbiAgQ29uZmxpY3RFcnJvcixcbiAgQ29udGV4dCxcbiAgSW50ZXJuYWxFcnJvcixcbiAgTm90Rm91bmRFcnJvcixcbiAgcHJlZml4TWV0aG9kLFxuICBSZXBvc2l0b3J5RmxhZ3MsXG59IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IFwicmVmbGVjdC1tZXRhZGF0YVwiO1xuXG5pbXBvcnQgeyBDb3VjaERCU2VxdWVuY2UgfSBmcm9tIFwiLi9zZXF1ZW5jZXMvU2VxdWVuY2VcIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEluZGV4RXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB7IE1hbmdvUXVlcnkgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgQ291Y2hEQlN0YXRlbWVudCB9IGZyb20gXCIuL3F1ZXJ5XCI7XG5pbXBvcnQgeyBmaW5hbCB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBYnN0cmFjdCBhZGFwdGVyIGZvciBDb3VjaERCIGRhdGFiYXNlIG9wZXJhdGlvbnNcbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIGEgYmFzZSBpbXBsZW1lbnRhdGlvbiBmb3IgQ291Y2hEQiBkYXRhYmFzZSBvcGVyYXRpb25zLCBpbmNsdWRpbmcgQ1JVRCBvcGVyYXRpb25zLCBzZXF1ZW5jZSBtYW5hZ2VtZW50LCBhbmQgZXJyb3IgaGFuZGxpbmdcbiAqIEB0ZW1wbGF0ZSBZIC0gVGhlIHNjb3BlIHR5cGVcbiAqIEB0ZW1wbGF0ZSBGIC0gVGhlIHJlcG9zaXRvcnkgZmxhZ3MgdHlwZVxuICogQHRlbXBsYXRlIEMgLSBUaGUgY29udGV4dCB0eXBlXG4gKiBAcGFyYW0ge1l9IHNjb3BlIC0gVGhlIHNjb3BlIGZvciB0aGUgYWRhcHRlclxuICogQHBhcmFtIHtzdHJpbmd9IGZsYXZvdXIgLSBUaGUgZmxhdm91ciBvZiB0aGUgYWRhcHRlclxuICogQHBhcmFtIHtzdHJpbmd9IFthbGlhc10gLSBPcHRpb25hbCBhbGlhcyBmb3IgdGhlIGFkYXB0ZXJcbiAqIEBjbGFzc1xuICogQGV4YW1wbGVcbiAqIC8vIEV4YW1wbGUgb2YgZXh0ZW5kaW5nIENvdWNoREJBZGFwdGVyXG4gKiBjbGFzcyBNeUNvdWNoREJBZGFwdGVyIGV4dGVuZHMgQ291Y2hEQkFkYXB0ZXI8TXlTY29wZSwgTXlGbGFncywgTXlDb250ZXh0PiB7XG4gKiAgIGNvbnN0cnVjdG9yKHNjb3BlOiBNeVNjb3BlKSB7XG4gKiAgICAgc3VwZXIoc2NvcGUsICdteS1jb3VjaGRiJywgJ215LWFsaWFzJyk7XG4gKiAgIH1cbiAqXG4gKiAgIC8vIEltcGxlbWVudCBhYnN0cmFjdCBtZXRob2RzXG4gKiAgIGFzeW5jIGluZGV4PE0gZXh0ZW5kcyBNb2RlbD4oLi4ubW9kZWxzOiBDb25zdHJ1Y3RvcjxNPltdKTogUHJvbWlzZTx2b2lkPiB7XG4gKiAgICAgLy8gSW1wbGVtZW50YXRpb25cbiAqICAgfVxuICpcbiAqICAgYXN5bmMgcmF3PFI+KHJhd0lucHV0OiBNYW5nb1F1ZXJ5LCBkb2NzT25seTogYm9vbGVhbik6IFByb21pc2U8Uj4ge1xuICogICAgIC8vIEltcGxlbWVudGF0aW9uXG4gKiAgIH1cbiAqXG4gKiAgIGFzeW5jIGNyZWF0ZSh0YWJsZU5hbWU6IHN0cmluZywgaWQ6IHN0cmluZyB8IG51bWJlciwgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT4sIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gKiAgICAgLy8gSW1wbGVtZW50YXRpb25cbiAqICAgfVxuICpcbiAqICAgYXN5bmMgcmVhZCh0YWJsZU5hbWU6IHN0cmluZywgaWQ6IHN0cmluZyB8IG51bWJlciwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+IHtcbiAqICAgICAvLyBJbXBsZW1lbnRhdGlvblxuICogICB9XG4gKlxuICogICBhc3luYyB1cGRhdGUodGFibGVOYW1lOiBzdHJpbmcsIGlkOiBzdHJpbmcgfCBudW1iZXIsIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICogICAgIC8vIEltcGxlbWVudGF0aW9uXG4gKiAgIH1cbiAqXG4gKiAgIGFzeW5jIGRlbGV0ZSh0YWJsZU5hbWU6IHN0cmluZywgaWQ6IHN0cmluZyB8IG51bWJlciwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+IHtcbiAqICAgICAvLyBJbXBsZW1lbnRhdGlvblxuICogICB9XG4gKiB9XG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBDb3VjaERCQWRhcHRlcjxcbiAgWSxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4+IGV4dGVuZHMgQWRhcHRlcjxZLCBNYW5nb1F1ZXJ5LCBGLCBDPiB7XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihzY29wZTogWSwgZmxhdm91cjogc3RyaW5nLCBhbGlhcz86IHN0cmluZykge1xuICAgIHN1cGVyKHNjb3BlLCBmbGF2b3VyLCBhbGlhcyk7XG4gICAgW3RoaXMuY3JlYXRlLCB0aGlzLmNyZWF0ZUFsbCwgdGhpcy51cGRhdGUsIHRoaXMudXBkYXRlQWxsXS5mb3JFYWNoKChtKSA9PiB7XG4gICAgICBjb25zdCBuYW1lID0gbS5uYW1lO1xuICAgICAgcHJlZml4TWV0aG9kKHRoaXMsIG0sICh0aGlzIGFzIGFueSlbbmFtZSArIFwiUHJlZml4XCJdKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIG5ldyBDb3VjaERCIHN0YXRlbWVudCBmb3IgcXVlcnlpbmdcbiAgICogQHN1bW1hcnkgRmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IENvdWNoREJTdGF0ZW1lbnQgaW5zdGFuY2UgZm9yIGJ1aWxkaW5nIHF1ZXJpZXNcbiAgICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZVxuICAgKiBAcmV0dXJuIHtDb3VjaERCU3RhdGVtZW50PE0sIGFueT59IEEgbmV3IENvdWNoREJTdGF0ZW1lbnQgaW5zdGFuY2VcbiAgICovXG4gIEBmaW5hbCgpXG4gIFN0YXRlbWVudDxNIGV4dGVuZHMgTW9kZWw+KCk6IENvdWNoREJTdGF0ZW1lbnQ8TSwgYW55PiB7XG4gICAgcmV0dXJuIG5ldyBDb3VjaERCU3RhdGVtZW50KHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmV3IENvdWNoREIgc2VxdWVuY2VcbiAgICogQHN1bW1hcnkgRmFjdG9yeSBtZXRob2QgdGhhdCBjcmVhdGVzIGEgbmV3IENvdWNoREJTZXF1ZW5jZSBpbnN0YW5jZSBmb3IgbWFuYWdpbmcgc2VxdWVuY2VzXG4gICAqIEBwYXJhbSB7U2VxdWVuY2VPcHRpb25zfSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgZm9yIHRoZSBzZXF1ZW5jZVxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFNlcXVlbmNlPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBuZXcgU2VxdWVuY2UgaW5zdGFuY2VcbiAgICovXG4gIEBmaW5hbCgpXG4gIGFzeW5jIFNlcXVlbmNlKG9wdGlvbnM6IFNlcXVlbmNlT3B0aW9ucyk6IFByb21pc2U8U2VxdWVuY2U+IHtcbiAgICByZXR1cm4gbmV3IENvdWNoREJTZXF1ZW5jZShvcHRpb25zLCB0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSW5pdGlhbGl6ZXMgdGhlIGFkYXB0ZXIgYnkgY3JlYXRpbmcgaW5kZXhlcyBmb3IgYWxsIG1hbmFnZWQgbW9kZWxzXG4gICAqIEBzdW1tYXJ5IFNldHMgdXAgdGhlIG5lY2Vzc2FyeSBkYXRhYmFzZSBpbmRleGVzIGZvciBhbGwgbW9kZWxzIG1hbmFnZWQgYnkgdGhpcyBhZGFwdGVyXG4gICAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gaW5pdGlhbGl6YXRpb24gaXMgY29tcGxldGVcbiAgICovXG4gIGFzeW5jIGluaXRpYWxpemUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbWFuYWdlZE1vZGVscyA9IEFkYXB0ZXIubW9kZWxzKHRoaXMuZmxhdm91cik7XG4gICAgcmV0dXJuIHRoaXMuaW5kZXgoLi4ubWFuYWdlZE1vZGVscyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgaW5kZXhlcyBmb3IgdGhlIGdpdmVuIG1vZGVsc1xuICAgKiBAc3VtbWFyeSBBYnN0cmFjdCBtZXRob2QgdGhhdCBtdXN0IGJlIGltcGxlbWVudGVkIHRvIGNyZWF0ZSBkYXRhYmFzZSBpbmRleGVzIGZvciB0aGUgc3BlY2lmaWVkIG1vZGVsc1xuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlXG4gICAqIEBwYXJhbSB7Li4uQ29uc3RydWN0b3I8TT59IG1vZGVscyAtIFRoZSBtb2RlbCBjb25zdHJ1Y3RvcnMgdG8gY3JlYXRlIGluZGV4ZXMgZm9yXG4gICAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gYWxsIGluZGV4ZXMgYXJlIGNyZWF0ZWRcbiAgICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBpbmRleDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIC4uLm1vZGVsczogQ29uc3RydWN0b3I8TT5bXVxuICApOiBQcm9taXNlPHZvaWQ+O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRXhlY3V0ZXMgYSByYXcgTWFuZ28gcXVlcnkgYWdhaW5zdCB0aGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgQWJzdHJhY3QgbWV0aG9kIHRoYXQgbXVzdCBiZSBpbXBsZW1lbnRlZCB0byBleGVjdXRlIHJhdyBNYW5nbyBxdWVyaWVzXG4gICAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHJlc3VsdCB0eXBlXG4gICAqIEBwYXJhbSB7TWFuZ29RdWVyeX0gcmF3SW5wdXQgLSBUaGUgcmF3IE1hbmdvIHF1ZXJ5IHRvIGV4ZWN1dGVcbiAgICogQHBhcmFtIHtib29sZWFufSBkb2NzT25seSAtIFdoZXRoZXIgdG8gcmV0dXJuIG9ubHkgdGhlIGRvY3VtZW50cyBvciB0aGUgZnVsbCByZXNwb25zZVxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFI+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgcXVlcnkgcmVzdWx0XG4gICAqL1xuICBhYnN0cmFjdCBvdmVycmlkZSByYXc8Uj4ocmF3SW5wdXQ6IE1hbmdvUXVlcnksIGRvY3NPbmx5OiBib29sZWFuKTogUHJvbWlzZTxSPjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFzc2lnbnMgbWV0YWRhdGEgdG8gYSBtb2RlbFxuICAgKiBAc3VtbWFyeSBBZGRzIHJldmlzaW9uIG1ldGFkYXRhIHRvIGEgbW9kZWwgYXMgYSBub24tZW51bWVyYWJsZSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG1vZGVsIC0gVGhlIG1vZGVsIHRvIGFzc2lnbiBtZXRhZGF0YSB0b1xuICAgKiBAcGFyYW0ge3N0cmluZ30gcmV2IC0gVGhlIHJldmlzaW9uIHN0cmluZyB0byBhc3NpZ25cbiAgICogQHJldHVybiB7UmVjb3JkPHN0cmluZywgYW55Pn0gVGhlIG1vZGVsIHdpdGggbWV0YWRhdGEgYXNzaWduZWRcbiAgICovXG4gIEBmaW5hbCgpXG4gIHByb3RlY3RlZCBhc3NpZ25NZXRhZGF0YShcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICByZXY6IHN0cmluZ1xuICApOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kZWwsIFBlcnNpc3RlbmNlS2V5cy5NRVRBREFUQSwge1xuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgdmFsdWU6IHJldixcbiAgICB9KTtcbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFzc2lnbnMgbWV0YWRhdGEgdG8gbXVsdGlwbGUgbW9kZWxzXG4gICAqIEBzdW1tYXJ5IEFkZHMgcmV2aXNpb24gbWV0YWRhdGEgdG8gbXVsdGlwbGUgbW9kZWxzIGFzIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXNcbiAgICogQHBhcmFtIG1vZGVscyAtIFRoZSBtb2RlbHMgdG8gYXNzaWduIG1ldGFkYXRhIHRvXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IHJldnMgLSBUaGUgcmV2aXNpb24gc3RyaW5ncyB0byBhc3NpZ25cbiAgICogQHJldHVybiBUaGUgbW9kZWxzIHdpdGggbWV0YWRhdGEgYXNzaWduZWRcbiAgICovXG4gIEBmaW5hbCgpXG4gIHByb3RlY3RlZCBhc3NpZ25NdWx0aXBsZU1ldGFkYXRhKFxuICAgIG1vZGVsczogUmVjb3JkPHN0cmluZywgYW55PltdLFxuICAgIHJldnM6IHN0cmluZ1tdXG4gICk6IFJlY29yZDxzdHJpbmcsIGFueT5bXSB7XG4gICAgbW9kZWxzLmZvckVhY2goKG0sIGkpID0+IHtcbiAgICAgIFJlcG9zaXRvcnkuc2V0TWV0YWRhdGEobSBhcyBhbnksIHJldnNbaV0pO1xuICAgICAgcmV0dXJuIG07XG4gICAgfSk7XG4gICAgcmV0dXJuIG1vZGVscztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJlcGFyZXMgYSByZWNvcmQgZm9yIGNyZWF0aW9uXG4gICAqIEBzdW1tYXJ5IEFkZHMgbmVjZXNzYXJ5IENvdWNoREIgZmllbGRzIHRvIGEgcmVjb3JkIGJlZm9yZSBjcmVhdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gaWQgLSBUaGUgSUQgb2YgdGhlIHJlY29yZFxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG1vZGVsIC0gVGhlIG1vZGVsIHRvIHByZXBhcmVcbiAgICogQHJldHVybiBBIHR1cGxlIGNvbnRhaW5pbmcgdGhlIHRhYmxlTmFtZSwgaWQsIGFuZCBwcmVwYXJlZCByZWNvcmRcbiAgICovXG4gIEBmaW5hbCgpXG4gIHByb3RlY3RlZCBjcmVhdGVQcmVmaXgoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlcixcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PlxuICApIHtcbiAgICBjb25zdCByZWNvcmQ6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICByZWNvcmRbQ291Y2hEQktleXMuVEFCTEVdID0gdGFibGVOYW1lO1xuICAgIHJlY29yZFtDb3VjaERCS2V5cy5JRF0gPSB0aGlzLmdlbmVyYXRlSWQodGFibGVOYW1lLCBpZCk7XG4gICAgT2JqZWN0LmFzc2lnbihyZWNvcmQsIG1vZGVsKTtcbiAgICByZXR1cm4gW3RhYmxlTmFtZSwgaWQsIHJlY29yZF07XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgcmVjb3JkIGluIHRoZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBBYnN0cmFjdCBtZXRob2QgdGhhdCBtdXN0IGJlIGltcGxlbWVudGVkIHRvIGNyZWF0ZSBhIG5ldyByZWNvcmRcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZVxuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGlkIC0gVGhlIElEIG9mIHRoZSByZWNvcmRcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBtb2RlbCAtIFRoZSBtb2RlbCB0byBjcmVhdGVcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzXG4gICAqIEByZXR1cm4ge1Byb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBjcmVhdGVkIHJlY29yZFxuICAgKi9cbiAgYWJzdHJhY3Qgb3ZlcnJpZGUgY3JlYXRlKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIsXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIG11bHRpcGxlIHJlY29yZHMgZm9yIGNyZWF0aW9uXG4gICAqIEBzdW1tYXJ5IEFkZHMgbmVjZXNzYXJ5IENvdWNoREIgZmllbGRzIHRvIG11bHRpcGxlIHJlY29yZHMgYmVmb3JlIGNyZWF0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGVcbiAgICogQHBhcmFtIHtzdHJpbmdbXXxudW1iZXJbXX0gaWRzIC0gVGhlIElEcyBvZiB0aGUgcmVjb3Jkc1xuICAgKiBAcGFyYW0gbW9kZWxzIC0gVGhlIG1vZGVscyB0byBwcmVwYXJlXG4gICAqIEByZXR1cm4gQSB0dXBsZSBjb250YWluaW5nIHRoZSB0YWJsZU5hbWUsIGlkcywgYW5kIHByZXBhcmVkIHJlY29yZHNcbiAgICogQHRocm93cyB7SW50ZXJuYWxFcnJvcn0gSWYgaWRzIGFuZCBtb2RlbHMgYXJyYXlzIGhhdmUgZGlmZmVyZW50IGxlbmd0aHNcbiAgICovXG4gIEBmaW5hbCgpXG4gIHByb3RlY3RlZCBjcmVhdGVBbGxQcmVmaXgoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWRzOiBzdHJpbmdbXSB8IG51bWJlcltdLFxuICAgIG1vZGVsczogUmVjb3JkPHN0cmluZywgYW55PltdXG4gICkge1xuICAgIGlmIChpZHMubGVuZ3RoICE9PSBtb2RlbHMubGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJJZHMgYW5kIG1vZGVscyBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoXCIpO1xuXG4gICAgY29uc3QgcmVjb3JkcyA9IGlkcy5tYXAoKGlkLCBjb3VudCkgPT4ge1xuICAgICAgY29uc3QgcmVjb3JkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgICByZWNvcmRbQ291Y2hEQktleXMuVEFCTEVdID0gdGFibGVOYW1lO1xuICAgICAgcmVjb3JkW0NvdWNoREJLZXlzLklEXSA9IHRoaXMuZ2VuZXJhdGVJZCh0YWJsZU5hbWUsIGlkKTtcbiAgICAgIE9iamVjdC5hc3NpZ24ocmVjb3JkLCBtb2RlbHNbY291bnRdKTtcbiAgICAgIHJldHVybiByZWNvcmQ7XG4gICAgfSk7XG4gICAgcmV0dXJuIFt0YWJsZU5hbWUsIGlkcywgcmVjb3Jkc107XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlYWRzIGEgcmVjb3JkIGZyb20gdGhlIGRhdGFiYXNlXG4gICAqIEBzdW1tYXJ5IEFic3RyYWN0IG1ldGhvZCB0aGF0IG11c3QgYmUgaW1wbGVtZW50ZWQgdG8gcmVhZCBhIHJlY29yZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gaWQgLSBUaGUgSUQgb2YgdGhlIHJlY29yZFxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHJlYWQgcmVjb3JkXG4gICAqL1xuICBhYnN0cmFjdCBvdmVycmlkZSByZWFkKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIGEgcmVjb3JkIGZvciB1cGRhdGVcbiAgICogQHN1bW1hcnkgQWRkcyBuZWNlc3NhcnkgQ291Y2hEQiBmaWVsZHMgdG8gYSByZWNvcmQgYmVmb3JlIHVwZGF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gaWQgLSBUaGUgSUQgb2YgdGhlIHJlY29yZFxuICAgKiBAcGFyYW0gbW9kZWwgLSBUaGUgbW9kZWwgdG8gcHJlcGFyZVxuICAgKiBAcmV0dXJuIEEgdHVwbGUgY29udGFpbmluZyB0aGUgdGFibGVOYW1lLCBpZCwgYW5kIHByZXBhcmVkIHJlY29yZFxuICAgKiBAdGhyb3dzIHtJbnRlcm5hbEVycm9yfSBJZiBubyByZXZpc2lvbiBudW1iZXIgaXMgZm91bmQgaW4gdGhlIG1vZGVsXG4gICAqL1xuICBAZmluYWwoKVxuICB1cGRhdGVQcmVmaXgoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlcixcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PlxuICApIHtcbiAgICBjb25zdCByZWNvcmQ6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICByZWNvcmRbQ291Y2hEQktleXMuVEFCTEVdID0gdGFibGVOYW1lO1xuICAgIHJlY29yZFtDb3VjaERCS2V5cy5JRF0gPSB0aGlzLmdlbmVyYXRlSWQodGFibGVOYW1lLCBpZCk7XG4gICAgY29uc3QgcmV2ID0gbW9kZWxbUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXTtcbiAgICBpZiAoIXJldilcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgTm8gcmV2aXNpb24gbnVtYmVyIGZvdW5kIGZvciByZWNvcmQgd2l0aCBpZCAke2lkfWBcbiAgICAgICk7XG4gICAgT2JqZWN0LmFzc2lnbihyZWNvcmQsIG1vZGVsKTtcbiAgICByZWNvcmRbQ291Y2hEQktleXMuUkVWXSA9IHJldjtcbiAgICByZXR1cm4gW3RhYmxlTmFtZSwgaWQsIHJlY29yZF07XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVwZGF0ZXMgYSByZWNvcmQgaW4gdGhlIGRhdGFiYXNlXG4gICAqIEBzdW1tYXJ5IEFic3RyYWN0IG1ldGhvZCB0aGF0IG11c3QgYmUgaW1wbGVtZW50ZWQgdG8gdXBkYXRlIGEgcmVjb3JkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGVcbiAgICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBpZCAtIFRoZSBJRCBvZiB0aGUgcmVjb3JkXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gbW9kZWwgLSBUaGUgbW9kZWwgdG8gdXBkYXRlXG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50c1xuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSB1cGRhdGVkIHJlY29yZFxuICAgKi9cbiAgYWJzdHJhY3Qgb3ZlcnJpZGUgdXBkYXRlKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIsXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIG11bHRpcGxlIHJlY29yZHMgZm9yIHVwZGF0ZVxuICAgKiBAc3VtbWFyeSBBZGRzIG5lY2Vzc2FyeSBDb3VjaERCIGZpZWxkcyB0byBtdWx0aXBsZSByZWNvcmRzIGJlZm9yZSB1cGRhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZVxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfG51bWJlcltdfSBpZHMgLSBUaGUgSURzIG9mIHRoZSByZWNvcmRzXG4gICAqIEBwYXJhbSBtb2RlbHMgLSBUaGUgbW9kZWxzIHRvIHByZXBhcmVcbiAgICogQHJldHVybiBBIHR1cGxlIGNvbnRhaW5pbmcgdGhlIHRhYmxlTmFtZSwgaWRzLCBhbmQgcHJlcGFyZWQgcmVjb3Jkc1xuICAgKiBAdGhyb3dzIHtJbnRlcm5hbEVycm9yfSBJZiBpZHMgYW5kIG1vZGVscyBhcnJheXMgaGF2ZSBkaWZmZXJlbnQgbGVuZ3RocyBvciBpZiBubyByZXZpc2lvbiBudW1iZXIgaXMgZm91bmQgaW4gYSBtb2RlbFxuICAgKi9cbiAgQGZpbmFsKClcbiAgcHJvdGVjdGVkIHVwZGF0ZUFsbFByZWZpeChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZHM6IHN0cmluZ1tdIHwgbnVtYmVyW10sXG4gICAgbW9kZWxzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W11cbiAgKSB7XG4gICAgaWYgKGlkcy5sZW5ndGggIT09IG1vZGVscy5sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIklkcyBhbmQgbW9kZWxzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGhcIik7XG5cbiAgICBjb25zdCByZWNvcmRzID0gaWRzLm1hcCgoaWQsIGNvdW50KSA9PiB7XG4gICAgICBjb25zdCByZWNvcmQ6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICAgIHJlY29yZFtDb3VjaERCS2V5cy5UQUJMRV0gPSB0YWJsZU5hbWU7XG4gICAgICByZWNvcmRbQ291Y2hEQktleXMuSURdID0gdGhpcy5nZW5lcmF0ZUlkKHRhYmxlTmFtZSwgaWQpO1xuICAgICAgY29uc3QgcmV2ID0gbW9kZWxzW2NvdW50XVtQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEFdO1xuICAgICAgaWYgKCFyZXYpXG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAgIGBObyByZXZpc2lvbiBudW1iZXIgZm91bmQgZm9yIHJlY29yZCB3aXRoIGlkICR7aWR9YFxuICAgICAgICApO1xuICAgICAgT2JqZWN0LmFzc2lnbihyZWNvcmQsIG1vZGVsc1tjb3VudF0pO1xuICAgICAgcmVjb3JkW0NvdWNoREJLZXlzLlJFVl0gPSByZXY7XG4gICAgICByZXR1cm4gcmVjb3JkO1xuICAgIH0pO1xuICAgIHJldHVybiBbdGFibGVOYW1lLCBpZHMsIHJlY29yZHNdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBEZWxldGVzIGEgcmVjb3JkIGZyb20gdGhlIGRhdGFiYXNlXG4gICAqIEBzdW1tYXJ5IEFic3RyYWN0IG1ldGhvZCB0aGF0IG11c3QgYmUgaW1wbGVtZW50ZWQgdG8gZGVsZXRlIGEgcmVjb3JkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGVcbiAgICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBpZCAtIFRoZSBJRCBvZiB0aGUgcmVjb3JkXG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50c1xuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkZWxldGVkIHJlY29yZFxuICAgKi9cbiAgYWJzdHJhY3Qgb3ZlcnJpZGUgZGVsZXRlKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdlbmVyYXRlcyBhIENvdWNoREIgZG9jdW1lbnQgSURcbiAgICogQHN1bW1hcnkgQ29tYmluZXMgdGhlIHRhYmxlIG5hbWUgYW5kIElEIHRvIGNyZWF0ZSBhIENvdWNoREIgZG9jdW1lbnQgSURcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZVxuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGlkIC0gVGhlIElEIG9mIHRoZSByZWNvcmRcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgZ2VuZXJhdGVkIENvdWNoREIgZG9jdW1lbnQgSURcbiAgICovXG4gIHByb3RlY3RlZCBnZW5lcmF0ZUlkKHRhYmxlTmFtZTogc3RyaW5nLCBpZDogc3RyaW5nIHwgbnVtYmVyKSB7XG4gICAgcmV0dXJuIFt0YWJsZU5hbWUsIGlkXS5qb2luKENvdWNoREJLZXlzLlNFUEFSQVRPUik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFBhcnNlcyBhbiBlcnJvciBhbmQgY29udmVydHMgaXQgdG8gYSBCYXNlRXJyb3JcbiAgICogQHN1bW1hcnkgQ29udmVydHMgdmFyaW91cyBlcnJvciB0eXBlcyB0byBhcHByb3ByaWF0ZSBCYXNlRXJyb3Igc3VidHlwZXNcbiAgICogQHBhcmFtIHtFcnJvcnxzdHJpbmd9IGVyciAtIFRoZSBlcnJvciB0byBwYXJzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3JlYXNvbl0gLSBPcHRpb25hbCByZWFzb24gZm9yIHRoZSBlcnJvclxuICAgKiBAcmV0dXJuIHtCYXNlRXJyb3J9IFRoZSBwYXJzZWQgZXJyb3IgYXMgYSBCYXNlRXJyb3JcbiAgICovXG4gIHBhcnNlRXJyb3IoZXJyOiBFcnJvciB8IHN0cmluZywgcmVhc29uPzogc3RyaW5nKTogQmFzZUVycm9yIHtcbiAgICByZXR1cm4gQ291Y2hEQkFkYXB0ZXIucGFyc2VFcnJvcihlcnIsIHJlYXNvbik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENoZWNrcyBpZiBhbiBhdHRyaWJ1dGUgaXMgcmVzZXJ2ZWRcbiAgICogQHN1bW1hcnkgRGV0ZXJtaW5lcyBpZiBhbiBhdHRyaWJ1dGUgbmFtZSBpcyByZXNlcnZlZCBpbiBDb3VjaERCXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyIC0gVGhlIGF0dHJpYnV0ZSBuYW1lIHRvIGNoZWNrXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGF0dHJpYnV0ZSBpcyByZXNlcnZlZCwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqL1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgaXNSZXNlcnZlZChhdHRyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISFhdHRyLm1hdGNoKHJlc2VydmVkQXR0cmlidXRlcyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFN0YXRpYyBtZXRob2QgdG8gcGFyc2UgYW4gZXJyb3IgYW5kIGNvbnZlcnQgaXQgdG8gYSBCYXNlRXJyb3JcbiAgICogQHN1bW1hcnkgQ29udmVydHMgdmFyaW91cyBlcnJvciB0eXBlcyB0byBhcHByb3ByaWF0ZSBCYXNlRXJyb3Igc3VidHlwZXMgYmFzZWQgb24gZXJyb3IgY29kZXMgYW5kIG1lc3NhZ2VzXG4gICAqIEBwYXJhbSB7RXJyb3J8c3RyaW5nfSBlcnIgLSBUaGUgZXJyb3IgdG8gcGFyc2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtyZWFzb25dIC0gT3B0aW9uYWwgcmVhc29uIGZvciB0aGUgZXJyb3JcbiAgICogQHJldHVybiB7QmFzZUVycm9yfSBUaGUgcGFyc2VkIGVycm9yIGFzIGEgQmFzZUVycm9yXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICAgKiAgIHBhcnRpY2lwYW50IHBhcnNlRXJyb3JcbiAgICogICBwYXJ0aWNpcGFudCBFcnJvclR5cGVzXG4gICAqXG4gICAqICAgQ2FsbGVyLT4+cGFyc2VFcnJvcjogZXJyLCByZWFzb25cbiAgICogICBOb3RlIG92ZXIgcGFyc2VFcnJvcjogQ2hlY2sgaWYgZXJyIGlzIGFscmVhZHkgYSBCYXNlRXJyb3JcbiAgICogICBhbHQgZXJyIGlzIEJhc2VFcnJvclxuICAgKiAgICAgcGFyc2VFcnJvci0tPj5DYWxsZXI6IHJldHVybiBlcnJcbiAgICogICBlbHNlIGVyciBpcyBzdHJpbmdcbiAgICogICAgIE5vdGUgb3ZlciBwYXJzZUVycm9yOiBFeHRyYWN0IGNvZGUgZnJvbSBzdHJpbmdcbiAgICogICAgIGFsdCBjb2RlIG1hdGNoZXMgXCJhbHJlYWR5IGV4aXN0fHVwZGF0ZSBjb25mbGljdFwiXG4gICAqICAgICAgIHBhcnNlRXJyb3ItPj5FcnJvclR5cGVzOiBuZXcgQ29uZmxpY3RFcnJvcihjb2RlKVxuICAgKiAgICAgICBFcnJvclR5cGVzLS0+PkNhbGxlcjogQ29uZmxpY3RFcnJvclxuICAgKiAgICAgZWxzZSBjb2RlIG1hdGNoZXMgXCJtaXNzaW5nfGRlbGV0ZWRcIlxuICAgKiAgICAgICBwYXJzZUVycm9yLT4+RXJyb3JUeXBlczogbmV3IE5vdEZvdW5kRXJyb3IoY29kZSlcbiAgICogICAgICAgRXJyb3JUeXBlcy0tPj5DYWxsZXI6IE5vdEZvdW5kRXJyb3JcbiAgICogICAgIGVuZFxuICAgKiAgIGVsc2UgZXJyIGhhcyBjb2RlIHByb3BlcnR5XG4gICAqICAgICBOb3RlIG92ZXIgcGFyc2VFcnJvcjogRXh0cmFjdCBjb2RlIGFuZCByZWFzb25cbiAgICogICBlbHNlIGVyciBoYXMgc3RhdHVzQ29kZSBwcm9wZXJ0eVxuICAgKiAgICAgTm90ZSBvdmVyIHBhcnNlRXJyb3I6IEV4dHJhY3QgY29kZSBhbmQgcmVhc29uXG4gICAqICAgZWxzZVxuICAgKiAgICAgTm90ZSBvdmVyIHBhcnNlRXJyb3I6IFVzZSBlcnIubWVzc2FnZSBhcyBjb2RlXG4gICAqICAgZW5kXG4gICAqXG4gICAqICAgTm90ZSBvdmVyIHBhcnNlRXJyb3I6IFN3aXRjaCBvbiBjb2RlXG4gICAqICAgYWx0IGNvZGUgaXMgNDAxLCA0MTIsIG9yIDQwOVxuICAgKiAgICAgcGFyc2VFcnJvci0+PkVycm9yVHlwZXM6IG5ldyBDb25mbGljdEVycm9yKHJlYXNvbilcbiAgICogICAgIEVycm9yVHlwZXMtLT4+Q2FsbGVyOiBDb25mbGljdEVycm9yXG4gICAqICAgZWxzZSBjb2RlIGlzIDQwNFxuICAgKiAgICAgcGFyc2VFcnJvci0+PkVycm9yVHlwZXM6IG5ldyBOb3RGb3VuZEVycm9yKHJlYXNvbilcbiAgICogICAgIEVycm9yVHlwZXMtLT4+Q2FsbGVyOiBOb3RGb3VuZEVycm9yXG4gICAqICAgZWxzZSBjb2RlIGlzIDQwMFxuICAgKiAgICAgYWx0IGNvZGUgbWF0Y2hlcyBcIk5vIGluZGV4IGV4aXN0c1wiXG4gICAqICAgICAgIHBhcnNlRXJyb3ItPj5FcnJvclR5cGVzOiBuZXcgSW5kZXhFcnJvcihlcnIpXG4gICAqICAgICAgIEVycm9yVHlwZXMtLT4+Q2FsbGVyOiBJbmRleEVycm9yXG4gICAqICAgICBlbHNlXG4gICAqICAgICAgIHBhcnNlRXJyb3ItPj5FcnJvclR5cGVzOiBuZXcgSW50ZXJuYWxFcnJvcihlcnIpXG4gICAqICAgICAgIEVycm9yVHlwZXMtLT4+Q2FsbGVyOiBJbnRlcm5hbEVycm9yXG4gICAqICAgICBlbmRcbiAgICogICBlbHNlIGNvZGUgbWF0Y2hlcyBcIkVDT05OUkVGVVNFRFwiXG4gICAqICAgICBwYXJzZUVycm9yLT4+RXJyb3JUeXBlczogbmV3IENvbm5lY3Rpb25FcnJvcihlcnIpXG4gICAqICAgICBFcnJvclR5cGVzLS0+PkNhbGxlcjogQ29ubmVjdGlvbkVycm9yXG4gICAqICAgZWxzZVxuICAgKiAgICAgcGFyc2VFcnJvci0+PkVycm9yVHlwZXM6IG5ldyBJbnRlcm5hbEVycm9yKGVycilcbiAgICogICAgIEVycm9yVHlwZXMtLT4+Q2FsbGVyOiBJbnRlcm5hbEVycm9yXG4gICAqICAgZW5kXG4gICAqL1xuICBwcm90ZWN0ZWQgc3RhdGljIHBhcnNlRXJyb3IoZXJyOiBFcnJvciB8IHN0cmluZywgcmVhc29uPzogc3RyaW5nKTogQmFzZUVycm9yIHtcbiAgICBpZiAoZXJyIGluc3RhbmNlb2YgQmFzZUVycm9yKSByZXR1cm4gZXJyIGFzIGFueTtcbiAgICBsZXQgY29kZTogc3RyaW5nID0gXCJcIjtcbiAgICBpZiAodHlwZW9mIGVyciA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgY29kZSA9IGVycjtcbiAgICAgIGlmIChjb2RlLm1hdGNoKC9hbHJlYWR5IGV4aXN0fHVwZGF0ZSBjb25mbGljdC9nKSlcbiAgICAgICAgcmV0dXJuIG5ldyBDb25mbGljdEVycm9yKGNvZGUpO1xuICAgICAgaWYgKGNvZGUubWF0Y2goL21pc3Npbmd8ZGVsZXRlZC9nKSkgcmV0dXJuIG5ldyBOb3RGb3VuZEVycm9yKGNvZGUpO1xuICAgIH0gZWxzZSBpZiAoKGVyciBhcyBhbnkpLmNvZGUpIHtcbiAgICAgIGNvZGUgPSAoZXJyIGFzIGFueSkuY29kZTtcbiAgICAgIHJlYXNvbiA9IHJlYXNvbiB8fCBlcnIubWVzc2FnZTtcbiAgICB9IGVsc2UgaWYgKChlcnIgYXMgYW55KS5zdGF0dXNDb2RlKSB7XG4gICAgICBjb2RlID0gKGVyciBhcyBhbnkpLnN0YXR1c0NvZGU7XG4gICAgICByZWFzb24gPSByZWFzb24gfHwgZXJyLm1lc3NhZ2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGUgPSBlcnIubWVzc2FnZTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGNvZGUudG9TdHJpbmcoKSkge1xuICAgICAgY2FzZSBcIjQwMVwiOlxuICAgICAgY2FzZSBcIjQxMlwiOlxuICAgICAgY2FzZSBcIjQwOVwiOlxuICAgICAgICByZXR1cm4gbmV3IENvbmZsaWN0RXJyb3IocmVhc29uIGFzIHN0cmluZyk7XG4gICAgICBjYXNlIFwiNDA0XCI6XG4gICAgICAgIHJldHVybiBuZXcgTm90Rm91bmRFcnJvcihyZWFzb24gYXMgc3RyaW5nKTtcbiAgICAgIGNhc2UgXCI0MDBcIjpcbiAgICAgICAgaWYgKGNvZGUudG9TdHJpbmcoKS5tYXRjaCgvTm9cXHNpbmRleFxcc2V4aXN0cy9nKSlcbiAgICAgICAgICByZXR1cm4gbmV3IEluZGV4RXJyb3IoZXJyKTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnRlcm5hbEVycm9yKGVycik7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAoY29kZS50b1N0cmluZygpLm1hdGNoKC9FQ09OTlJFRlVTRUQvZykpXG4gICAgICAgICAgcmV0dXJuIG5ldyBDb25uZWN0aW9uRXJyb3IoZXJyKTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnRlcm5hbEVycm9yKGVycik7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBPcmRlckRpcmVjdGlvbiwgUGVyc2lzdGVuY2VLZXlzIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBDb3VjaERCS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgRGVmYXVsdFNlcGFyYXRvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgQ291Y2hEQk9wZXJhdG9yIH0gZnJvbSBcIi4vcXVlcnkvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBDcmVhdGVJbmRleFJlcXVlc3QsIE1hbmdvU2VsZWN0b3IsIFNvcnRPcmRlciB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlLWF1dGhlbnRpY2F0ZXMgYSBjb25uZWN0aW9uIHRvIENvdWNoREJcbiAqIEBzdW1tYXJ5IFJlZnJlc2hlcyB0aGUgYXV0aGVudGljYXRpb24gZm9yIGEgQ291Y2hEQiBjb25uZWN0aW9uIHVzaW5nIHRoZSBwcm92aWRlZCBjcmVkZW50aWFsc1xuICogQHBhcmFtIHthbnl9IGNvbiAtIFRoZSBDb3VjaERCIGNvbm5lY3Rpb24gb2JqZWN0XG4gKiBAcGFyYW0ge3N0cmluZ30gdXNlciAtIFRoZSB1c2VybmFtZSBmb3IgYXV0aGVudGljYXRpb25cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXNzIC0gVGhlIHBhc3N3b3JkIGZvciBhdXRoZW50aWNhdGlvblxuICogQHJldHVybiB7UHJvbWlzZTxhbnk+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgYXV0aGVudGljYXRpb24gcmVzdWx0XG4gKiBAZnVuY3Rpb24gcmVBdXRoXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmZvci1jb3VjaGRiXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZUF1dGgoY29uOiBhbnksIHVzZXI6IHN0cmluZywgcGFzczogc3RyaW5nKSB7XG4gIHJldHVybiBjb24uYXV0aCh1c2VyLCBwYXNzKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gV3JhcHMgYSBDb3VjaERCIGRhdGFiYXNlIGNvbm5lY3Rpb24gd2l0aCBhdXRvbWF0aWMgcmUtYXV0aGVudGljYXRpb25cbiAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBwcm94eSBhcm91bmQgYSBDb3VjaERCIGRhdGFiYXNlIGNvbm5lY3Rpb24gdGhhdCBhdXRvbWF0aWNhbGx5IHJlLWF1dGhlbnRpY2F0ZXMgYmVmb3JlIGVhY2ggb3BlcmF0aW9uXG4gKiBAcGFyYW0ge2FueX0gY29uIC0gVGhlIENvdWNoREIgY29ubmVjdGlvbiBvYmplY3RcbiAqIEBwYXJhbSB7c3RyaW5nfSBkYk5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZGF0YWJhc2UgdG8gdXNlXG4gKiBAcGFyYW0ge3N0cmluZ30gdXNlciAtIFRoZSB1c2VybmFtZSBmb3IgYXV0aGVudGljYXRpb25cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXNzIC0gVGhlIHBhc3N3b3JkIGZvciBhdXRoZW50aWNhdGlvblxuICogQHJldHVybiB7YW55fSBUaGUgd3JhcHBlZCBkYXRhYmFzZSBjb25uZWN0aW9uIG9iamVjdFxuICogQGZ1bmN0aW9uIHdyYXBEb2N1bWVudFNjb3BlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmZvci1jb3VjaGRiXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICogICBwYXJ0aWNpcGFudCB3cmFwRG9jdW1lbnRTY29wZVxuICogICBwYXJ0aWNpcGFudCBEQlxuICogICBwYXJ0aWNpcGFudCByZUF1dGhcbiAqICAgXG4gKiAgIENsaWVudC0+PndyYXBEb2N1bWVudFNjb3BlOiBjb24sIGRiTmFtZSwgdXNlciwgcGFzc1xuICogICB3cmFwRG9jdW1lbnRTY29wZS0+PkRCOiBjb24udXNlKGRiTmFtZSlcbiAqICAgTm90ZSBvdmVyIHdyYXBEb2N1bWVudFNjb3BlOiBXcmFwIERCIG1ldGhvZHMgd2l0aCByZS1hdXRoXG4gKiAgIFxuICogICBsb29wIEZvciBlYWNoIG1ldGhvZCAoaW5zZXJ0LCBnZXQsIHB1dCwgZGVzdHJveSwgZmluZClcbiAqICAgICB3cmFwRG9jdW1lbnRTY29wZS0+PndyYXBEb2N1bWVudFNjb3BlOiBTdG9yZSBvcmlnaW5hbCBtZXRob2RcbiAqICAgICB3cmFwRG9jdW1lbnRTY29wZS0+PndyYXBEb2N1bWVudFNjb3BlOiBEZWZpbmUgbmV3IG1ldGhvZCB3aXRoIHJlLWF1dGhcbiAqICAgZW5kXG4gKiAgIFxuICogICB3cmFwRG9jdW1lbnRTY29wZS0+PndyYXBEb2N1bWVudFNjb3BlOiBBZGQgTkFUSVZFIHByb3BlcnR5IHdpdGggY29uIHZhbHVlXG4gKiAgIHdyYXBEb2N1bWVudFNjb3BlLS0+PkNsaWVudDogUmV0dXJuIHdyYXBwZWQgREJcbiAqICAgXG4gKiAgIE5vdGUgb3ZlciBDbGllbnQ6IExhdGVyIHdoZW4gY2xpZW50IHVzZXMgREIgbWV0aG9kc1xuICogICBDbGllbnQtPj5EQjogQW55IHdyYXBwZWQgbWV0aG9kIGNhbGxcbiAqICAgREItPj5yZUF1dGg6IEF1dGhlbnRpY2F0ZSBiZWZvcmUgb3BlcmF0aW9uXG4gKiAgIHJlQXV0aC0tPj5EQjogQXV0aGVudGljYXRpb24gY29tcGxldGVcbiAqICAgREItPj5EQjogQ2FsbCBvcmlnaW5hbCBtZXRob2RcbiAqICAgREItLT4+Q2xpZW50OiBSZXR1cm4gcmVzdWx0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cmFwRG9jdW1lbnRTY29wZShcbiAgY29uOiBhbnksXG4gIGRiTmFtZTogc3RyaW5nLFxuICB1c2VyOiBzdHJpbmcsXG4gIHBhc3M6IHN0cmluZ1xuKTogYW55IHtcbiAgY29uc3QgZGIgPSBjb24udXNlKGRiTmFtZSk7XG4gIFtcImluc2VydFwiLCBcImdldFwiLCBcInB1dFwiLCBcImRlc3Ryb3lcIiwgXCJmaW5kXCJdLmZvckVhY2goKGspID0+IHtcbiAgICBjb25zdCBvcmlnaW5hbCA9IChkYiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtrXTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZGIsIGssIHtcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgdmFsdWU6IGFzeW5jICguLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgICAgICBhd2FpdCByZUF1dGgoY29uLCB1c2VyLCBwYXNzKTtcbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsLmNhbGwoZGIsIC4uLmFyZ3MpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfSk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkYiwgQ291Y2hEQktleXMuTkFUSVZFLCB7XG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IGNvbixcbiAgfSk7XG4gIHJldHVybiBkYjtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVGVzdHMgaWYgYW4gYXR0cmlidXRlIG5hbWUgaXMgcmVzZXJ2ZWQgaW4gQ291Y2hEQlxuICogQHN1bW1hcnkgQ2hlY2tzIGlmIGFuIGF0dHJpYnV0ZSBuYW1lIHN0YXJ0cyB3aXRoIGFuIHVuZGVyc2NvcmUsIHdoaWNoIGluZGljYXRlcyBpdCdzIGEgcmVzZXJ2ZWQgYXR0cmlidXRlIGluIENvdWNoREJcbiAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyIC0gVGhlIGF0dHJpYnV0ZSBuYW1lIHRvIHRlc3RcbiAqIEByZXR1cm4ge1JlZ0V4cE1hdGNoQXJyYXl8bnVsbH0gVGhlIG1hdGNoIHJlc3VsdCBvciBudWxsIGlmIG5vIG1hdGNoXG4gKiBAZnVuY3Rpb24gdGVzdFJlc2VydmVkQXR0cmlidXRlc1xuICogQG1lbWJlck9mIG1vZHVsZTpmb3ItY291Y2hkYlxuICovXG5leHBvcnQgZnVuY3Rpb24gdGVzdFJlc2VydmVkQXR0cmlidXRlcyhhdHRyOiBzdHJpbmcpIHtcbiAgY29uc3QgcmVnZXhwID0gL15fLiokL2c7XG4gIHJldHVybiBhdHRyLm1hdGNoKHJlZ2V4cCk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEdlbmVyYXRlcyBhIG5hbWUgZm9yIGEgQ291Y2hEQiBpbmRleFxuICogQHN1bW1hcnkgQ3JlYXRlcyBhIHN0YW5kYXJkaXplZCBuYW1lIGZvciBhIENvdWNoREIgaW5kZXggYmFzZWQgb24gdGhlIHRhYmxlLCBhdHRyaWJ1dGUsIGNvbXBvc2l0aW9ucywgYW5kIG9yZGVyXG4gKiBAcGFyYW0ge3N0cmluZ30gYXR0cmlidXRlIC0gVGhlIHByaW1hcnkgYXR0cmlidXRlIGZvciB0aGUgaW5kZXhcbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGVcbiAqIEBwYXJhbSB7c3RyaW5nW119IFtjb21wb3NpdGlvbnNdIC0gT3B0aW9uYWwgYWRkaXRpb25hbCBhdHRyaWJ1dGVzIHRvIGluY2x1ZGUgaW4gdGhlIGluZGV4XG4gKiBAcGFyYW0ge09yZGVyRGlyZWN0aW9ufSBbb3JkZXJdIC0gT3B0aW9uYWwgc29ydCBvcmRlciBmb3IgdGhlIGluZGV4XG4gKiBAcGFyYW0ge3N0cmluZ30gW3NlcGFyYXRvcj1EZWZhdWx0U2VwYXJhdG9yXSAtIFRoZSBzZXBhcmF0b3IgdG8gdXNlIGJldHdlZW4gcGFydHMgb2YgdGhlIGluZGV4IG5hbWVcbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGdlbmVyYXRlZCBpbmRleCBuYW1lXG4gKiBAZnVuY3Rpb24gZ2VuZXJhdGVJbmRleE5hbWVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Zm9yLWNvdWNoZGJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlSW5kZXhOYW1lKFxuICBhdHRyaWJ1dGU6IHN0cmluZyxcbiAgdGFibGVOYW1lOiBzdHJpbmcsXG4gIGNvbXBvc2l0aW9ucz86IHN0cmluZ1tdLFxuICBvcmRlcj86IE9yZGVyRGlyZWN0aW9uLFxuICBzZXBhcmF0b3IgPSBEZWZhdWx0U2VwYXJhdG9yXG4pOiBzdHJpbmcge1xuICBjb25zdCBhdHRyID0gW1BlcnNpc3RlbmNlS2V5cy5JTkRFWCwgdGFibGVOYW1lLCBhdHRyaWJ1dGVdO1xuICBpZiAoY29tcG9zaXRpb25zKSBhdHRyLnB1c2goLi4uY29tcG9zaXRpb25zKTtcbiAgaWYgKG9yZGVyKSBhdHRyLnB1c2gob3JkZXIpO1xuICByZXR1cm4gYXR0ci5qb2luKHNlcGFyYXRvcik7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEdlbmVyYXRlcyBhIENvdWNoREIgaW5kZXggY29uZmlndXJhdGlvblxuICogQHN1bW1hcnkgQ3JlYXRlcyBhIGNvbXBsZXRlIENyZWF0ZUluZGV4UmVxdWVzdCBvYmplY3QgZm9yIGRlZmluaW5nIGEgQ291Y2hEQiBpbmRleCBiYXNlZCBvbiBzcGVjaWZpZWQgcGFyYW1ldGVyc1xuICogQHBhcmFtIHtzdHJpbmd9IGF0dHJpYnV0ZSAtIFRoZSBwcmltYXJ5IGF0dHJpYnV0ZSBmb3IgdGhlIGluZGV4XG4gKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBbY29tcG9zaXRpb25zXSAtIE9wdGlvbmFsIGFkZGl0aW9uYWwgYXR0cmlidXRlcyB0byBpbmNsdWRlIGluIHRoZSBpbmRleFxuICogQHBhcmFtIHtPcmRlckRpcmVjdGlvbn0gW29yZGVyXSAtIE9wdGlvbmFsIHNvcnQgb3JkZXIgZm9yIHRoZSBpbmRleFxuICogQHBhcmFtIHtzdHJpbmd9IFtzZXBhcmF0b3I9RGVmYXVsdFNlcGFyYXRvcl0gLSBUaGUgc2VwYXJhdG9yIHRvIHVzZSBiZXR3ZWVuIHBhcnRzIG9mIHRoZSBpbmRleCBuYW1lXG4gKiBAcmV0dXJuIHtDcmVhdGVJbmRleFJlcXVlc3R9IFRoZSBjb21wbGV0ZSBpbmRleCBjb25maWd1cmF0aW9uIG9iamVjdFxuICogQGZ1bmN0aW9uIGdlbmVyYXRlSW5kZXhEb2NcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Zm9yLWNvdWNoZGJcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IGdlbmVyYXRlSW5kZXhEb2NcbiAqICAgcGFydGljaXBhbnQgZ2VuZXJhdGVJbmRleE5hbWVcbiAqICAgXG4gKiAgIENhbGxlci0+PmdlbmVyYXRlSW5kZXhEb2M6IGF0dHJpYnV0ZSwgdGFibGVOYW1lLCBjb21wb3NpdGlvbnMsIG9yZGVyLCBzZXBhcmF0b3JcbiAqICAgXG4gKiAgIE5vdGUgb3ZlciBnZW5lcmF0ZUluZGV4RG9jOiBDcmVhdGUgcGFydGlhbCBmaWx0ZXIgc2VsZWN0b3JcbiAqICAgZ2VuZXJhdGVJbmRleERvYy0+PmdlbmVyYXRlSW5kZXhEb2M6IFNldCB1cCBmaWx0ZXIgZm9yIHRhYmxlTmFtZVxuICogICBcbiAqICAgYWx0IG9yZGVyIGlzIHNwZWNpZmllZFxuICogICAgIE5vdGUgb3ZlciBnZW5lcmF0ZUluZGV4RG9jOiBDcmVhdGUgb3JkZXJlZCBmaWVsZHMgYXJyYXlcbiAqICAgICBnZW5lcmF0ZUluZGV4RG9jLT4+Z2VuZXJhdGVJbmRleERvYzogQ3JlYXRlIG9yZGVyUHJvcCBmb3IgYXR0cmlidXRlXG4gKiAgICAgZ2VuZXJhdGVJbmRleERvYy0+PmdlbmVyYXRlSW5kZXhEb2M6IE1hcCBjb21wb3NpdGlvbnMgdG8gb3JkZXJlZCBwcm9wc1xuICogICAgIGdlbmVyYXRlSW5kZXhEb2MtPj5nZW5lcmF0ZUluZGV4RG9jOiBDcmVhdGUgc29ydGVkVGFibGUgZm9yIHRhYmxlIGZpZWxkXG4gKiAgICAgZ2VuZXJhdGVJbmRleERvYy0+PmdlbmVyYXRlSW5kZXhEb2M6IENvbWJpbmUgYWxsIG9yZGVyZWQgZmllbGRzXG4gKiAgIGVsc2VcbiAqICAgICBOb3RlIG92ZXIgZ2VuZXJhdGVJbmRleERvYzogQ3JlYXRlIHNpbXBsZSBmaWVsZHMgYXJyYXlcbiAqICAgICBnZW5lcmF0ZUluZGV4RG9jLT4+Z2VuZXJhdGVJbmRleERvYzogVXNlIGF0dHJpYnV0ZSwgY29tcG9zaXRpb25zLCBhbmQgdGFibGUgYXMgc3RyaW5nc1xuICogICBlbmRcbiAqICAgXG4gKiAgIGdlbmVyYXRlSW5kZXhEb2MtPj5nZW5lcmF0ZUluZGV4TmFtZTogR2VuZXJhdGUgaW5kZXggbmFtZVxuICogICBnZW5lcmF0ZUluZGV4TmFtZS0tPj5nZW5lcmF0ZUluZGV4RG9jOiBSZXR1cm4gbmFtZVxuICogICBcbiAqICAgTm90ZSBvdmVyIGdlbmVyYXRlSW5kZXhEb2M6IENyZWF0ZSBmaW5hbCBpbmRleCByZXF1ZXN0XG4gKiAgIGdlbmVyYXRlSW5kZXhEb2MtLT4+Q2FsbGVyOiBSZXR1cm4gQ3JlYXRlSW5kZXhSZXF1ZXN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUluZGV4RG9jKFxuICBhdHRyaWJ1dGU6IHN0cmluZyxcbiAgdGFibGVOYW1lOiBzdHJpbmcsXG4gIGNvbXBvc2l0aW9ucz86IHN0cmluZ1tdLFxuICBvcmRlcj86IE9yZGVyRGlyZWN0aW9uLFxuICBzZXBhcmF0b3IgPSBEZWZhdWx0U2VwYXJhdG9yXG4pOiBDcmVhdGVJbmRleFJlcXVlc3Qge1xuICBjb25zdCBwYXJ0aWFsRmlsdGVyU2VsZWN0b3I6IE1hbmdvU2VsZWN0b3IgPSB7fTtcbiAgcGFydGlhbEZpbHRlclNlbGVjdG9yW0NvdWNoREJLZXlzLlRBQkxFXSA9IHt9IGFzIE1hbmdvU2VsZWN0b3I7XG4gIChwYXJ0aWFsRmlsdGVyU2VsZWN0b3JbQ291Y2hEQktleXMuVEFCTEVdIGFzIE1hbmdvU2VsZWN0b3IpW1xuICAgIENvdWNoREJPcGVyYXRvci5FUVVBTFxuICBdID0gdGFibGVOYW1lO1xuICBsZXQgZmllbGRzOiBTb3J0T3JkZXJbXTtcbiAgaWYgKG9yZGVyKSB7XG4gICAgY29uc3Qgb3JkZXJQcm9wOiBTb3J0T3JkZXIgPSB7fTtcbiAgICBvcmRlclByb3BbYXR0cmlidXRlXSA9IG9yZGVyIGFzIFwiYXNjXCIgfCBcImRlc2NcIjtcbiAgICBjb25zdCBzb3J0ZWRDb21wb3NpdGlvbnM6IFNvcnRPcmRlcltdID0gKGNvbXBvc2l0aW9ucyB8fCBbXSkubWFwKChjKSA9PiB7XG4gICAgICBjb25zdCByOiBTb3J0T3JkZXIgPSB7fTtcbiAgICAgIHJbY10gPSBvcmRlciBhcyBcImFzY1wiIHwgXCJkZXNjXCI7XG4gICAgICByZXR1cm4gcjtcbiAgICB9KTtcbiAgICBjb25zdCBzb3J0ZWRUYWJsZTogU29ydE9yZGVyID0ge307XG4gICAgc29ydGVkVGFibGVbQ291Y2hEQktleXMuVEFCTEVdID0gb3JkZXIgYXMgXCJhc2NcIiB8IFwiZGVzY1wiO1xuICAgIGZpZWxkcyA9IFtvcmRlclByb3AsIC4uLnNvcnRlZENvbXBvc2l0aW9ucywgc29ydGVkVGFibGVdO1xuICB9IGVsc2Uge1xuICAgIGZpZWxkcyA9IFthdHRyaWJ1dGUsIC4uLihjb21wb3NpdGlvbnMgfHwgW10pLCBDb3VjaERCS2V5cy5UQUJMRV07XG4gIH1cbiAgY29uc3QgbmFtZSA9IGdlbmVyYXRlSW5kZXhOYW1lKFxuICAgIGF0dHJpYnV0ZSxcbiAgICB0YWJsZU5hbWUsXG4gICAgY29tcG9zaXRpb25zLFxuICAgIG9yZGVyLFxuICAgIHNlcGFyYXRvclxuICApO1xuICByZXR1cm4ge1xuICAgIGluZGV4OiB7XG4gICAgICBmaWVsZHM6IGZpZWxkcyxcbiAgICAgIC8vIHBhcnRpYWxfZmlsdGVyX3NlbGVjdG9yOiBwYXJ0aWFsRmlsdGVyU2VsZWN0b3IsXG4gICAgfSxcbiAgICBkZG9jOiBbbmFtZSwgQ291Y2hEQktleXMuRERPQ10uam9pbihzZXBhcmF0b3IpLFxuICAgIG5hbWU6IG5hbWUsXG4gIH07XG59XG4iLCJleHBvcnQgKiBmcm9tIFwiLi9pbmRleGVzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9pbnRlcmZhY2VzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9tb2RlbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vc2VxdWVuY2VzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hZGFwdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2Vycm9yc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZXNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWxzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvdWNoREIgYWRhcHRlciBmb3IgRGVjYWYudHNcbiAqIEBzdW1tYXJ5IEEgVHlwZVNjcmlwdCBhZGFwdGVyIGZvciBDb3VjaERCIGRhdGFiYXNlIG9wZXJhdGlvbnMsIHByb3ZpZGluZyBhIHNlYW1sZXNzIGludGVncmF0aW9uIHdpdGggdGhlIERlY2FmLnRzIGZyYW1ld29yay4gVGhpcyBtb2R1bGUgaW5jbHVkZXMgY2xhc3NlcywgaW50ZXJmYWNlcywgYW5kIHV0aWxpdGllcyBmb3Igd29ya2luZyB3aXRoIENvdWNoREIgZGF0YWJhc2VzLCBpbmNsdWRpbmcgc3VwcG9ydCBmb3IgTWFuZ28gcXVlcmllcywgZG9jdW1lbnQgb3BlcmF0aW9ucywgYW5kIHNlcXVlbmNlIG1hbmFnZW1lbnQuXG4gKiBAbW9kdWxlIGZvci1jb3VjaGRiXG4gKi9cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gU3RvcmVzIHRoZSBjdXJyZW50IHBhY2thZ2UgdmVyc2lvblxuICogQHN1bW1hcnkgVGhlIHZlcnNpb24gc3RyaW5nIG9mIHRoZSBmb3ItY291Y2hkYiBwYWNrYWdlXG4gKiBAY29uc3QgVkVSU0lPTlxuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6WyJnZW5lcmF0ZUluZGV4TmFtZSIsIlNlcXVlbmNlIiwiU2VxIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7Ozs7QUFLRztBQUNJLE1BQU0sa0JBQWtCLEdBQUc7QUFFbEM7Ozs7Ozs7Ozs7Ozs7O0FBY0c7QUFFSDs7Ozs7O0FBTUc7QUFDVSxNQUFBLFdBQVcsR0FBRztBQUN6QixJQUFBLFNBQVMsRUFBRSxJQUFJO0FBQ2YsSUFBQSxFQUFFLEVBQUUsS0FBSztBQUNULElBQUEsR0FBRyxFQUFFLE1BQU07QUFDWCxJQUFBLE9BQU8sRUFBRSxVQUFVO0FBQ25CLElBQUEsS0FBSyxFQUFFLFNBQVM7QUFDaEIsSUFBQSxRQUFRLEVBQUUsWUFBWTtBQUN0QixJQUFBLElBQUksRUFBRSxNQUFNO0FBQ1osSUFBQSxNQUFNLEVBQUUsVUFBVTtBQUNsQixJQUFBLEtBQUssRUFBRSxPQUFPOzs7QUN0Q2hCOzs7OztBQUtHO0FBQ0ksTUFBTSxpQkFBaUIsR0FBRyxHQUFHO0FBRXBDOzs7Ozs7Ozs7Ozs7Ozs7O0FBZ0JHO0FBQ0ksTUFBTSxlQUFlLEdBQWtDO0FBQzVELElBQUEsS0FBSyxFQUFFLEtBQUs7QUFDWixJQUFBLFNBQVMsRUFBRSxLQUFLO0FBQ2hCLElBQUEsTUFBTSxFQUFFLEtBQUs7QUFDYixJQUFBLFNBQVMsRUFBRSxNQUFNO0FBQ2pCLElBQUEsT0FBTyxFQUFFLEtBQUs7QUFDZCxJQUFBLFVBQVUsRUFBRSxNQUFNOztBQUVsQixJQUFBLEdBQUcsRUFBRSxNQUFNO0FBQ1gsSUFBQSxFQUFFLEVBQUUsS0FBSzs7QUFFVCxJQUFBLE1BQU0sRUFBRSxRQUFRO0NBQ2pCO0FBRUQ7Ozs7Ozs7OztBQVNHO0FBQ0ksTUFBTSxvQkFBb0IsR0FBa0M7QUFDakUsSUFBQSxHQUFHLEVBQUUsTUFBTTtBQUNYLElBQUEsRUFBRSxFQUFFLEtBQUs7Q0FDVjs7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