@decaf-ts/for-pouch 0.2.8 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/adapter.cjs CHANGED
@@ -1,4 +1,40 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
2
38
  Object.defineProperty(exports, "__esModule", { value: true });
3
39
  exports.PouchAdapter = void 0;
4
40
  exports.createdByOnPouchCreateUpdate = createdByOnPouchCreateUpdate;
@@ -8,6 +44,10 @@ const db_decorators_1 = require("@decaf-ts/db-decorators");
8
44
  const core_1 = require("@decaf-ts/core");
9
45
  const decorator_validation_1 = require("@decaf-ts/decorator-validation");
10
46
  const constants_1 = require("./constants.cjs");
47
+ const pouchdb_core_1 = __importDefault(require("pouchdb-core"));
48
+ const PouchMapReduce = __importStar(require("pouchdb-mapreduce"));
49
+ const PouchReplication = __importStar(require("pouchdb-replication"));
50
+ const PouchFind = __importStar(require("pouchdb-find"));
11
51
  /**
12
52
  * @description Sets the creator ID on a model during creation or update operations
13
53
  * @summary This function is used as a decorator handler to automatically set the creator ID field on a model
@@ -36,25 +76,33 @@ async function createdByOnPouchCreateUpdate(context, data, key, model) {
36
76
  }
37
77
  /**
38
78
  * @description PouchDB implementation of the CouchDBAdapter
39
- * @summary This class provides a concrete implementation of the CouchDBAdapter for PouchDB.
40
- * It handles all database operations like create, read, update, delete (CRUD) for both
41
- * single documents and bulk operations. It also provides methods for querying and indexing.
42
- * @template Database - The PouchDB database type
79
+ * @summary Concrete adapter that bridges the generic CouchDBAdapter to a PouchDB backend. It supports CRUD (single and bulk), indexing and Mango queries, and wires flavour-specific decorations.
43
80
  * @template PouchFlags - The flags specific to PouchDB operations
44
81
  * @template Context<PouchFlags> - The context type with PouchDB flags
45
- * @param {Database} scope - The PouchDB database instance
82
+ * @param {PouchConfig} config - Adapter configuration (remote credentials or local storage path, db name, plugins)
46
83
  * @param {string} [alias] - Optional alias for the database
47
84
  * @class PouchAdapter
48
85
  * @example
49
86
  * ```typescript
50
- * import PouchDB from 'pouchdb';
51
87
  * import { PouchAdapter } from '@decaf-ts/for-pouch';
52
88
  *
53
- * // Create a new PouchDB instance
54
- * const db = new PouchDB('my-database');
89
+ * // Create a PouchAdapter with config
90
+ * const adapter = new PouchAdapter({
91
+ * protocol: 'http',
92
+ * host: 'localhost:5984',
93
+ * user: 'admin',
94
+ * password: 'secret',
95
+ * dbName: 'my-database',
96
+ * plugins: []
97
+ * });
55
98
  *
56
- * // Create a PouchAdapter with the database
57
- * const adapter = new PouchAdapter(db);
99
+ * // Or use local storage
100
+ * const localAdapter = new PouchAdapter({
101
+ * protocol: 'http', // ignored for local
102
+ * dbName: 'local-db',
103
+ * storagePath: 'local_dbs',
104
+ * plugins: []
105
+ * });
58
106
  *
59
107
  * // Use the adapter for database operations
60
108
  * const result = await adapter.read('users', 'user-123');
@@ -66,8 +114,8 @@ async function createdByOnPouchCreateUpdate(context, data, key, model) {
66
114
  * participant PouchDB
67
115
  * participant CouchDB
68
116
  *
69
- * Client->>PouchAdapter: new PouchAdapter(db)
70
- * PouchAdapter->>CouchDBAdapter: super(scope, PouchFlavour, alias)
117
+ * Client->>PouchAdapter: new PouchAdapter(config, alias?)
118
+ * PouchAdapter->>CouchDBAdapter: super(config, PouchFlavour, alias)
71
119
  *
72
120
  * Client->>PouchAdapter: create(table, id, model)
73
121
  * PouchAdapter->>PouchDB: put(model)
@@ -84,8 +132,64 @@ async function createdByOnPouchCreateUpdate(context, data, key, model) {
84
132
  * PouchAdapter-->>Client: Model
85
133
  */
86
134
  class PouchAdapter extends for_couchdb_1.CouchDBAdapter {
87
- constructor(scope, alias) {
88
- super(scope, constants_1.PouchFlavour, alias);
135
+ constructor(config, alias) {
136
+ super(config, constants_1.PouchFlavour, alias);
137
+ }
138
+ /**
139
+ * @description Lazily initializes and returns the underlying PouchDB client
140
+ * @summary Loads required PouchDB plugins once, builds the connection URL or local storage path from config, and caches the Database instance for reuse. Throws InternalError if client creation fails.
141
+ * @return {Database} A PouchDB Database instance ready to perform operations
142
+ * @mermaid
143
+ * sequenceDiagram
144
+ * participant Caller
145
+ * participant PouchAdapter
146
+ * participant PouchDB
147
+ * Caller->>PouchAdapter: getClient()
148
+ * alt client not initialized
149
+ * PouchAdapter->>PouchAdapter: register plugins
150
+ * PouchAdapter->>PouchDB: new PouchDB(url or path)
151
+ * alt creation fails
152
+ * PouchDB-->>PouchAdapter: Error
153
+ * PouchAdapter-->>Caller: throws InternalError
154
+ * else success
155
+ * PouchDB-->>PouchAdapter: Database
156
+ * PouchAdapter-->>Caller: cached client
157
+ * end
158
+ * else client initialized
159
+ * PouchAdapter-->>Caller: cached client
160
+ * end
161
+ */
162
+ getClient() {
163
+ if (!this._client) {
164
+ const plugins = [
165
+ PouchMapReduce,
166
+ PouchReplication,
167
+ PouchFind,
168
+ ...this.config.plugins,
169
+ ];
170
+ for (const plugin of plugins) {
171
+ try {
172
+ pouchdb_core_1.default.plugin(plugin);
173
+ }
174
+ catch (e) {
175
+ if (e instanceof Error && e.message.includes("redefine property"))
176
+ continue; //plugin has already been loaded so it's ok
177
+ throw e;
178
+ }
179
+ }
180
+ const { host, protocol, user, password, dbName, storagePath } = this.config;
181
+ try {
182
+ if (host && user) {
183
+ this._client = new pouchdb_core_1.default(`${protocol}://${user}:${password}@${host}/${dbName}`);
184
+ }
185
+ else
186
+ this._client = new pouchdb_core_1.default(`${storagePath || constants_1.DefaultLocalStoragePath}/${dbName}`);
187
+ }
188
+ catch (e) {
189
+ throw new db_decorators_1.InternalError(`Failed to create PouchDB client: ${e}`);
190
+ }
191
+ }
192
+ return this._client;
89
193
  }
90
194
  /**
91
195
  * @description Generates operation flags for PouchDB operations
@@ -98,19 +202,10 @@ class PouchAdapter extends for_couchdb_1.CouchDBAdapter {
98
202
  * @return {Promise<PouchFlags>} The complete set of flags for the operation
99
203
  */
100
204
  async flags(operation, model, flags) {
101
- let id = "";
102
- const url = this.native.name;
103
- if (url) {
104
- const regexp = /https?:\/\/(.+?):.+?@/g;
105
- const m = regexp.exec(url);
106
- if (m)
107
- id = m[1];
108
- }
109
- if (!id) {
110
- id = crypto.randomUUID();
111
- }
205
+ if (!this.config.user)
206
+ this.config.user = crypto.randomUUID();
112
207
  return Object.assign(await super.flags(operation, model, flags), {
113
- UUID: id,
208
+ UUID: this.config.user,
114
209
  });
115
210
  }
116
211
  /**
@@ -124,7 +219,7 @@ class PouchAdapter extends for_couchdb_1.CouchDBAdapter {
124
219
  async index(...models) {
125
220
  const indexes = (0, for_couchdb_1.generateIndexes)(models);
126
221
  for (const index of indexes) {
127
- const res = await this.native.createIndex(index);
222
+ const res = await this.client.createIndex(index);
128
223
  const { result } = res;
129
224
  if (result === "existing")
130
225
  throw new db_decorators_1.ConflictError(`Index ${index.name} already exists`);
@@ -159,7 +254,7 @@ class PouchAdapter extends for_couchdb_1.CouchDBAdapter {
159
254
  async create(tableName, id, model) {
160
255
  let response;
161
256
  try {
162
- response = await this.native.put(model);
257
+ response = await this.client.put(model);
163
258
  }
164
259
  catch (e) {
165
260
  throw this.parseError(e);
@@ -197,7 +292,7 @@ class PouchAdapter extends for_couchdb_1.CouchDBAdapter {
197
292
  async createAll(tableName, ids, models) {
198
293
  let response;
199
294
  try {
200
- response = await this.native.bulkDocs(models);
295
+ response = await this.client.bulkDocs(models);
201
296
  }
202
297
  catch (e) {
203
298
  throw PouchAdapter.parseError(e);
@@ -242,7 +337,7 @@ class PouchAdapter extends for_couchdb_1.CouchDBAdapter {
242
337
  const _id = this.generateId(tableName, id);
243
338
  let record;
244
339
  try {
245
- record = await this.native.get(_id);
340
+ record = await this.client.get(_id);
246
341
  }
247
342
  catch (e) {
248
343
  throw PouchAdapter.parseError(e);
@@ -276,7 +371,7 @@ class PouchAdapter extends for_couchdb_1.CouchDBAdapter {
276
371
  * end
277
372
  */
278
373
  async readAll(tableName, ids) {
279
- const results = await this.native.bulkGet({
374
+ const results = await this.client.bulkGet({
280
375
  docs: ids.map((id) => ({ id: this.generateId(tableName, id) })),
281
376
  });
282
377
  const res = results.results.reduce((accum, r) => {
@@ -320,7 +415,7 @@ class PouchAdapter extends for_couchdb_1.CouchDBAdapter {
320
415
  async update(tableName, id, model) {
321
416
  let response;
322
417
  try {
323
- response = await this.native.put(model);
418
+ response = await this.client.put(model);
324
419
  }
325
420
  catch (e) {
326
421
  throw PouchAdapter.parseError(e);
@@ -358,7 +453,7 @@ class PouchAdapter extends for_couchdb_1.CouchDBAdapter {
358
453
  async updateAll(tableName, ids, models) {
359
454
  let response;
360
455
  try {
361
- response = await this.native.bulkDocs(models);
456
+ response = await this.client.bulkDocs(models);
362
457
  }
363
458
  catch (e) {
364
459
  throw PouchAdapter.parseError(e);
@@ -405,8 +500,8 @@ class PouchAdapter extends for_couchdb_1.CouchDBAdapter {
405
500
  const _id = this.generateId(tableName, id);
406
501
  let record;
407
502
  try {
408
- record = await this.native.get(_id);
409
- await this.native.remove(_id, record._rev);
503
+ record = await this.client.get(_id);
504
+ await this.client.remove(_id, record._rev);
410
505
  }
411
506
  catch (e) {
412
507
  throw PouchAdapter.parseError(e);
@@ -443,10 +538,10 @@ class PouchAdapter extends for_couchdb_1.CouchDBAdapter {
443
538
  * end
444
539
  */
445
540
  async deleteAll(tableName, ids) {
446
- const results = await this.native.bulkGet({
541
+ const results = await this.client.bulkGet({
447
542
  docs: ids.map((id) => ({ id: this.generateId(tableName, id) })),
448
543
  });
449
- const deletion = await this.native.bulkDocs(results.results.map((r) => {
544
+ const deletion = await this.client.bulkDocs(results.results.map((r) => {
450
545
  r[for_couchdb_1.CouchDBKeys.DELETED] = true;
451
546
  return r;
452
547
  }));
@@ -492,7 +587,7 @@ class PouchAdapter extends for_couchdb_1.CouchDBAdapter {
492
587
  */
493
588
  async raw(rawInput, process = true) {
494
589
  try {
495
- const response = await this.native.find(rawInput);
590
+ const response = await this.client.find(rawInput);
496
591
  if (response.warning)
497
592
  console.warn(response.warning);
498
593
  if (process)
@@ -633,4 +728,4 @@ class PouchAdapter extends for_couchdb_1.CouchDBAdapter {
633
728
  }
634
729
  exports.PouchAdapter = PouchAdapter;
635
730
  PouchAdapter.setCurrent(constants_1.PouchFlavour);
636
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9hZGFwdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQTREQSxvRUFvQkM7QUFoRkQsNEJBQTBCO0FBQzFCLHVEQU8rQjtBQUMvQiwyREFTaUM7QUFDakMseUNBTXdCO0FBT3hCLHlFQUt3QztBQUl4QywrQ0FBMkM7QUFHM0M7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0ksS0FBSyxVQUFVLDRCQUE0QixDQU1oRCxPQUE0QixFQUM1QixJQUFPLEVBQ1AsR0FBWSxFQUNaLEtBQVE7SUFFUixJQUFJLENBQUM7UUFDSCxNQUFNLElBQUksR0FBVyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3pDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFrQixDQUFDO1FBQ2hDLDZEQUE2RDtJQUMvRCxDQUFDO0lBQUMsT0FBTyxDQUFVLEVBQUUsQ0FBQztRQUNwQixNQUFNLElBQUksdUJBQWdCLENBQ3hCLGdFQUFnRSxDQUNqRSxDQUFDO0lBQ0osQ0FBQztBQUNILENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0RHO0FBQ0gsTUFBYSxZQUFhLFNBQVEsNEJBSWpDO0lBQ0MsWUFBWSxLQUFlLEVBQUUsS0FBYztRQUN6QyxLQUFLLENBQUMsS0FBSyxFQUFFLHdCQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNnQixLQUFLLENBQUMsS0FBSyxDQUM1QixTQUF3QixFQUN4QixLQUFxQixFQUNyQixLQUEwQjtRQUUxQixJQUFJLEVBQUUsR0FBVyxFQUFFLENBQUM7UUFDcEIsTUFBTSxHQUFHLEdBQUksSUFBSSxDQUFDLE1BQXNDLENBQUMsSUFBSSxDQUFDO1FBQzlELElBQUksR0FBRyxFQUFFLENBQUM7WUFDUixNQUFNLE1BQU0sR0FBRyx3QkFBd0Is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QVUsQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sWUFBWSxHQUFHLGlCQUFVLENBQUMsR0FBRyxDQUFDLHNCQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDaEUsaUNBQVUsQ0FBQyxXQUFXLENBQUMsd0JBQVksQ0FBQzthQUNqQyxHQUFHLENBQUMsWUFBWSxDQUFDO2FBQ2pCLE1BQU0sQ0FDTCxJQUFBLHdCQUFRLEVBQUMsNEJBQTRCLENBQUMsRUFDdEMsSUFBQSxtQ0FBWSxFQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FDL0I7YUFDQSxLQUFLLEVBQUUsQ0FBQztRQUNYLGlDQUFVLENBQUMsV0FBVyxDQUFDLHdCQUFZLENBQUM7YUFDakMsR0FBRyxDQUFDLFlBQVksQ0FBQzthQUNqQixNQUFNLENBQ0wsSUFBQSw4QkFBYyxFQUFDLDRCQUE0QixDQUFDLEVBQzVDLElBQUEsbUNBQVksRUFBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLENBQy9CO2FBQ0EsS0FBSyxFQUFFLENBQUM7SUFDYixDQUFDO0NBQ0Y7QUE5bUJELG9DQThtQkM7QUFFRCxZQUFZLENBQUMsVUFBVSxDQUFDLHdCQUFZLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBcInJlZmxlY3QtbWV0YWRhdGFcIjtcbmltcG9ydCB7XG4gIENvdWNoREJBZGFwdGVyLFxuICBDb3VjaERCS2V5cyxcbiAgQ3JlYXRlSW5kZXhSZXF1ZXN0LFxuICBnZW5lcmF0ZUluZGV4ZXMsXG4gIEluZGV4RXJyb3IsXG4gIE1hbmdvUXVlcnksXG59IGZyb20gXCJAZGVjYWYtdHMvZm9yLWNvdWNoZGJcIjtcbmltcG9ydCB7XG4gIEJhc2VFcnJvcixcbiAgQ29uZmxpY3RFcnJvcixcbiAgQ29udGV4dCxcbiAgSW50ZXJuYWxFcnJvcixcbiAgTm90Rm91bmRFcnJvcixcbiAgb25DcmVhdGUsXG4gIG9uQ3JlYXRlVXBkYXRlLFxuICBPcGVyYXRpb25LZXlzLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7XG4gIENvbm5lY3Rpb25FcnJvcixcbiAgUGVyc2lzdGVuY2VLZXlzLFxuICBSZWxhdGlvbnNNZXRhZGF0YSxcbiAgUmVwb3NpdG9yeSxcbiAgVW5zdXBwb3J0ZWRFcnJvcixcbn0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgRGF0YWJhc2UgPSBQb3VjaERCLkRhdGFiYXNlO1xuaW1wb3J0IFJlc3BvbnNlID0gUG91Y2hEQi5Db3JlLlJlc3BvbnNlO1xuaW1wb3J0IEVyciA9IFBvdWNoREIuQ29yZS5FcnJvcjtcbmltcG9ydCBJZE1ldGEgPSBQb3VjaERCLkNvcmUuSWRNZXRhO1xuaW1wb3J0IEdldE1ldGEgPSBQb3VjaERCLkNvcmUuR2V0TWV0YTtcbmltcG9ydCBDcmVhdGVJbmRleFJlc3BvbnNlID0gUG91Y2hEQi5GaW5kLkNyZWF0ZUluZGV4UmVzcG9uc2U7XG5pbXBvcnQge1xuICBDb25zdHJ1Y3RvcixcbiAgRGVjb3JhdGlvbixcbiAgTW9kZWwsXG4gIHByb3BNZXRhZGF0YSxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IEJ1bGtHZXRSZXNwb25zZSA9IFBvdWNoREIuQ29yZS5CdWxrR2V0UmVzcG9uc2U7XG5pbXBvcnQgRmluZFJlc3BvbnNlID0gUG91Y2hEQi5GaW5kLkZpbmRSZXNwb25zZTtcbmltcG9ydCB7IFBvdWNoRmxhZ3MgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgUG91Y2hGbGF2b3VyIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBQb3VjaFJlcG9zaXRvcnkgfSBmcm9tIFwiLi9Qb3VjaFJlcG9zaXRvcnlcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgY3JlYXRvciBJRCBvbiBhIG1vZGVsIGR1cmluZyBjcmVhdGlvbiBvciB1cGRhdGUgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGFzIGEgZGVjb3JhdG9yIGhhbmRsZXIgdG8gYXV0b21hdGljYWxseSBzZXQgdGhlIGNyZWF0b3IgSUQgZmllbGQgb24gYSBtb2RlbFxuICogd2hlbiBpdCdzIGJlaW5nIGNyZWF0ZWQgb3IgdXBkYXRlZC4gSXQgZXh0cmFjdHMgdGhlIFVVSUQgZnJvbSB0aGUgY29udGV4dCBhbmQgYXNzaWducyBpdCB0byB0aGUgc3BlY2lmaWVkIGtleS5cbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgdGhhdCBleHRlbmRzIE1vZGVsXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSByZXBvc2l0b3J5IHR5cGUgdGhhdCBleHRlbmRzIFBvdWNoUmVwb3NpdG9yeTxNPlxuICogQHRlbXBsYXRlIFYgLSBUaGUgcmVsYXRpb25zIG1ldGFkYXRhIHR5cGUgdGhhdCBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhXG4gKiBAcGFyYW0ge1J9IHRoaXMgLSBUaGUgcmVwb3NpdG9yeSBpbnN0YW5jZVxuICogQHBhcmFtIHtDb250ZXh0PFBvdWNoRmxhZ3M+fSBjb250ZXh0IC0gVGhlIG9wZXJhdGlvbiBjb250ZXh0IGNvbnRhaW5pbmcgZmxhZ3NcbiAqIEBwYXJhbSB7Vn0gZGF0YSAtIFRoZSByZWxhdGlvbnMgbWV0YWRhdGFcbiAqIEBwYXJhbSBrZXkgLSBUaGUgcHJvcGVydHkga2V5IHRvIHNldCBvbiB0aGUgbW9kZWxcbiAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UgdG8gbW9kaWZ5XG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBvcGVyYXRpb24gaXMgY29tcGxldGVcbiAqIEBmdW5jdGlvbiBjcmVhdGVkQnlPblBvdWNoQ3JlYXRlVXBkYXRlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmZvci1wb3VjaFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlZEJ5T25Qb3VjaENyZWF0ZVVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUG91Y2hSZXBvc2l0b3J5PE0+LFxuICBWIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4+KFxuICB0aGlzOiBSLFxuICBjb250ZXh0OiBDb250ZXh0PFBvdWNoRmxhZ3M+LFxuICBkYXRhOiBWLFxuICBrZXk6IGtleW9mIE0sXG4gIG1vZGVsOiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCB1dWlkOiBzdHJpbmcgPSBjb250ZXh0LmdldChcIlVVSURcIik7XG4gICAgbW9kZWxba2V5XSA9IHV1aWQgYXMgTVtrZXlvZiBNXTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRFcnJvcihcbiAgICAgIFwiTm8gVXNlciBmb3VuZCBpbiBjb250ZXh0LiBQbGVhc2UgcHJvdmlkZSBhIHVzZXIgaW4gdGhlIGNvbnRleHRcIlxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUG91Y2hEQiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgQ291Y2hEQkFkYXB0ZXJcbiAqIEBzdW1tYXJ5IFRoaXMgY2xhc3MgcHJvdmlkZXMgYSBjb25jcmV0ZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgQ291Y2hEQkFkYXB0ZXIgZm9yIFBvdWNoREIuXG4gKiBJdCBoYW5kbGVzIGFsbCBkYXRhYmFzZSBvcGVyYXRpb25zIGxpa2UgY3JlYXRlLCByZWFkLCB1cGRhdGUsIGRlbGV0ZSAoQ1JVRCkgZm9yIGJvdGhcbiAqIHNpbmdsZSBkb2N1bWVudHMgYW5kIGJ1bGsgb3BlcmF0aW9ucy4gSXQgYWxzbyBwcm92aWRlcyBtZXRob2RzIGZvciBxdWVyeWluZyBhbmQgaW5kZXhpbmcuXG4gKiBAdGVtcGxhdGUgRGF0YWJhc2UgLSBUaGUgUG91Y2hEQiBkYXRhYmFzZSB0eXBlXG4gKiBAdGVtcGxhdGUgUG91Y2hGbGFncyAtIFRoZSBmbGFncyBzcGVjaWZpYyB0byBQb3VjaERCIG9wZXJhdGlvbnNcbiAqIEB0ZW1wbGF0ZSBDb250ZXh0PFBvdWNoRmxhZ3M+IC0gVGhlIGNvbnRleHQgdHlwZSB3aXRoIFBvdWNoREIgZmxhZ3NcbiAqIEBwYXJhbSB7RGF0YWJhc2V9IHNjb3BlIC0gVGhlIFBvdWNoREIgZGF0YWJhc2UgaW5zdGFuY2VcbiAqIEBwYXJhbSB7c3RyaW5nfSBbYWxpYXNdIC0gT3B0aW9uYWwgYWxpYXMgZm9yIHRoZSBkYXRhYmFzZVxuICogQGNsYXNzIFBvdWNoQWRhcHRlclxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCBQb3VjaERCIGZyb20gJ3BvdWNoZGInO1xuICogaW1wb3J0IHsgUG91Y2hBZGFwdGVyIH0gZnJvbSAnQGRlY2FmLXRzL2Zvci1wb3VjaCc7XG4gKlxuICogLy8gQ3JlYXRlIGEgbmV3IFBvdWNoREIgaW5zdGFuY2VcbiAqIGNvbnN0IGRiID0gbmV3IFBvdWNoREIoJ215LWRhdGFiYXNlJyk7XG4gKlxuICogLy8gQ3JlYXRlIGEgUG91Y2hBZGFwdGVyIHdpdGggdGhlIGRhdGFiYXNlXG4gKiBjb25zdCBhZGFwdGVyID0gbmV3IFBvdWNoQWRhcHRlcihkYik7XG4gKlxuICogLy8gVXNlIHRoZSBhZGFwdGVyIGZvciBkYXRhYmFzZSBvcGVyYXRpb25zXG4gKiBjb25zdCByZXN1bHQgPSBhd2FpdCBhZGFwdGVyLnJlYWQoJ3VzZXJzJywgJ3VzZXItMTIzJyk7XG4gKiBgYGBcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICogICBwYXJ0aWNpcGFudCBQb3VjaERCXG4gKiAgIHBhcnRpY2lwYW50IENvdWNoREJcbiAqXG4gKiAgIENsaWVudC0+PlBvdWNoQWRhcHRlcjogbmV3IFBvdWNoQWRhcHRlcihkYilcbiAqICAgUG91Y2hBZGFwdGVyLT4+Q291Y2hEQkFkYXB0ZXI6IHN1cGVyKHNjb3BlLCBQb3VjaEZsYXZvdXIsIGFsaWFzKVxuICpcbiAqICAgQ2xpZW50LT4+UG91Y2hBZGFwdGVyOiBjcmVhdGUodGFibGUsIGlkLCBtb2RlbClcbiAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogcHV0KG1vZGVsKVxuICogICBQb3VjaERCLT4+Q291Y2hEQjogSFRUUCBQVVRcbiAqICAgQ291Y2hEQi0tPj5Qb3VjaERCOiBSZXNwb25zZVxuICogICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogUmVzcG9uc2VcbiAqICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogVXBkYXRlZCBtb2RlbFxuICpcbiAqICAgQ2xpZW50LT4+UG91Y2hBZGFwdGVyOiByZWFkKHRhYmxlLCBpZClcbiAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogZ2V0KGlkKVxuICogICBQb3VjaERCLT4+Q291Y2hEQjogSFRUUCBHRVRcbiAqICAgQ291Y2hEQi0tPj5Qb3VjaERCOiBEb2N1bWVudFxuICogICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogRG9jdW1lbnRcbiAqICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogTW9kZWxcbiAqL1xuZXhwb3J0IGNsYXNzIFBvdWNoQWRhcHRlciBleHRlbmRzIENvdWNoREJBZGFwdGVyPFxuICBEYXRhYmFzZSxcbiAgUG91Y2hGbGFncyxcbiAgQ29udGV4dDxQb3VjaEZsYWdzPlxuPiB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBEYXRhYmFzZSwgYWxpYXM/OiBzdHJpbmcpIHtcbiAgICBzdXBlcihzY29wZSwgUG91Y2hGbGF2b3VyLCBhbGlhcyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdlbmVyYXRlcyBvcGVyYXRpb24gZmxhZ3MgZm9yIFBvdWNoREIgb3BlcmF0aW9uc1xuICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgc2V0IG9mIGZsYWdzIGZvciBhIHNwZWNpZmljIG9wZXJhdGlvbiwgaW5jbHVkaW5nIGEgVVVJRCBmb3IgaWRlbnRpZmljYXRpb24uXG4gICAqIFRoaXMgbWV0aG9kIGV4dHJhY3RzIHRoZSB1c2VyIElEIGZyb20gdGhlIGRhdGFiYXNlIFVSTCBvciBnZW5lcmF0ZXMgYSByYW5kb20gVVVJRCBpZiBub3QgYXZhaWxhYmxlLlxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoYXQgZXh0ZW5kcyBNb2RlbFxuICAgKiBAcGFyYW0ge09wZXJhdGlvbktleXN9IG9wZXJhdGlvbiAtIFRoZSBvcGVyYXRpb24ga2V5IChjcmVhdGUsIHJlYWQsIHVwZGF0ZSwgZGVsZXRlKVxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBtb2RlbCAtIFRoZSBtb2RlbCBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge1BhcnRpYWw8UG91Y2hGbGFncz59IGZsYWdzIC0gUGFydGlhbCBmbGFncyB0byBiZSBtZXJnZWRcbiAgICogQHJldHVybiB7UHJvbWlzZTxQb3VjaEZsYWdzPn0gVGhlIGNvbXBsZXRlIHNldCBvZiBmbGFncyBmb3IgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGFzeW5jIGZsYWdzPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgb3BlcmF0aW9uOiBPcGVyYXRpb25LZXlzLFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPixcbiAgICBmbGFnczogUGFydGlhbDxQb3VjaEZsYWdzPlxuICApOiBQcm9taXNlPFBvdWNoRmxhZ3M+IHtcbiAgICBsZXQgaWQ6IHN0cmluZyA9IFwiXCI7XG4gICAgY29uc3QgdXJsID0gKHRoaXMubmF0aXZlIGFzIHVua25vd24gYXMgeyBuYW1lOiBzdHJpbmcgfSkubmFtZTtcbiAgICBpZiAodXJsKSB7XG4gICAgICBjb25zdCByZWdleHAgPSAvaHR0cHM/OlxcL1xcLyguKz8pOi4rP0AvZztcbiAgICAgIGNvbnN0IG0gPSByZWdleHAuZXhlYyh1cmwpO1xuICAgICAgaWYgKG0pIGlkID0gbVsxXTtcbiAgICB9XG4gICAgaWYgKCFpZCkge1xuICAgICAgaWQgPSBjcnlwdG8ucmFuZG9tVVVJRCgpO1xuICAgIH1cblxuICAgIHJldHVybiBPYmplY3QuYXNzaWduKGF3YWl0IHN1cGVyLmZsYWdzKG9wZXJhdGlvbiwgbW9kZWwsIGZsYWdzKSwge1xuICAgICAgVVVJRDogaWQsXG4gICAgfSkgYXMgUG91Y2hGbGFncztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBkYXRhYmFzZSBpbmRleGVzIGZvciB0aGUgZ2l2ZW4gbW9kZWxzXG4gICAqIEBzdW1tYXJ5IEdlbmVyYXRlcyBhbmQgY3JlYXRlcyBpbmRleGVzIGluIHRoZSBQb3VjaERCIGRhdGFiYXNlIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBtb2RlbCBjb25zdHJ1Y3RvcnMuXG4gICAqIFRoaXMgbWV0aG9kIHVzZXMgdGhlIGdlbmVyYXRlSW5kZXhlcyB1dGlsaXR5IHRvIGNyZWF0ZSBpbmRleCBkZWZpbml0aW9ucyBhbmQgdGhlbiBjcmVhdGVzIHRoZW0gaW4gdGhlIGRhdGFiYXNlLlxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoYXQgZXh0ZW5kcyBNb2RlbFxuICAgKiBAcGFyYW0gbW9kZWxzIC0gVGhlIG1vZGVsIGNvbnN0cnVjdG9ycyB0byBjcmVhdGUgaW5kZXhlcyBmb3JcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgaW5kZXhlcyBhcmUgY3JlYXRlZFxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGluZGV4PE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgLi4ubW9kZWxzOiBDb25zdHJ1Y3RvcjxNPltdXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGluZGV4ZXM6IENyZWF0ZUluZGV4UmVxdWVzdFtdID0gZ2VuZXJhdGVJbmRleGVzKG1vZGVscyk7XG4gICAgZm9yIChjb25zdCBpbmRleCBvZiBpbmRleGVzKSB7XG4gICAgICBjb25zdCByZXM6IENyZWF0ZUluZGV4UmVzcG9uc2U8YW55PiA9IGF3YWl0IHRoaXMubmF0aXZlLmNyZWF0ZUluZGV4KFxuICAgICAgICBpbmRleCBhcyBhbnlcbiAgICAgICk7XG4gICAgICBjb25zdCB7IHJlc3VsdCB9ID0gcmVzO1xuICAgICAgaWYgKHJlc3VsdCA9PT0gXCJleGlzdGluZ1wiKVxuICAgICAgICB0aHJvdyBuZXcgQ29uZmxpY3RFcnJvcihgSW5kZXggJHtpbmRleC5uYW1lfSBhbHJlYWR5IGV4aXN0c2ApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIG5ldyBkb2N1bWVudCBpbiB0aGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgSW5zZXJ0cyBhIG5ldyBkb2N1bWVudCBpbnRvIHRoZSBQb3VjaERCIGRhdGFiYXNlIHVzaW5nIHRoZSBwdXQgb3BlcmF0aW9uLlxuICAgKiBUaGlzIG1ldGhvZCBoYW5kbGVzIGVycm9yIHBhcnNpbmcgYW5kIGVuc3VyZXMgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gaWQgLSBUaGUgZG9jdW1lbnQgSURcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBtb2RlbCAtIFRoZSBkb2N1bWVudCBkYXRhIHRvIGluc2VydFxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgY3JlYXRlZCBkb2N1bWVudCB3aXRoIG1ldGFkYXRhXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoREJcbiAgICpcbiAgICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IGNyZWF0ZSh0YWJsZU5hbWUsIGlkLCBtb2RlbClcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaERCOiBwdXQobW9kZWwpXG4gICAqICAgYWx0IFN1Y2Nlc3NcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBSZXNwb25zZSB3aXRoIG9rPXRydWVcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogYXNzaWduTWV0YWRhdGEobW9kZWwsIHJlc3BvbnNlLnJldilcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IFVwZGF0ZWQgbW9kZWwgd2l0aCBtZXRhZGF0YVxuICAgKiAgIGVsc2UgRXJyb3JcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBFcnJvclxuICAgKiAgICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBwYXJzZUVycm9yKGUpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBUaHJvd3MgZXJyb3JcbiAgICogICBlbmRcbiAgICovXG4gIGFzeW5jIGNyZWF0ZShcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICAgIGxldCByZXNwb25zZTogUmVzcG9uc2U7XG4gICAgdHJ5IHtcbiAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy5uYXRpdmUucHV0KG1vZGVsKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyB0aGlzLnBhcnNlRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgfVxuXG4gICAgaWYgKCFyZXNwb25zZS5vaylcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGluc2VydCBkb2MgaWQ6ICR7aWR9IGluIHRhYmxlICR7dGFibGVOYW1lfWBcbiAgICAgICk7XG4gICAgcmV0dXJuIHRoaXMuYXNzaWduTWV0YWRhdGEobW9kZWwsIHJlc3BvbnNlLnJldik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgbXVsdGlwbGUgZG9jdW1lbnRzIGluIHRoZSBkYXRhYmFzZSBpbiBhIHNpbmdsZSBvcGVyYXRpb25cbiAgICogQHN1bW1hcnkgSW5zZXJ0cyBtdWx0aXBsZSBkb2N1bWVudHMgaW50byB0aGUgUG91Y2hEQiBkYXRhYmFzZSB1c2luZyB0aGUgYnVsa0RvY3Mgb3BlcmF0aW9uLlxuICAgKiBUaGlzIG1ldGhvZCBoYW5kbGVzIGVycm9yIHBhcnNpbmcgYW5kIGVuc3VyZXMgYWxsIG9wZXJhdGlvbnMgd2VyZSBzdWNjZXNzZnVsLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlL2NvbGxlY3Rpb25cbiAgICogQHBhcmFtIHtzdHJpbmdbXXxudW1iZXJbXX0gaWRzIC0gVGhlIGRvY3VtZW50IElEc1xuICAgKiBAcGFyYW0gIG1vZGVscyAtIFRoZSBkb2N1bWVudCBkYXRhIHRvIGluc2VydFxuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBjcmVhdGVkIGRvY3VtZW50cyB3aXRoIG1ldGFkYXRhXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoREJcbiAgICpcbiAgICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IGNyZWF0ZUFsbCh0YWJsZU5hbWUsIGlkcywgbW9kZWxzKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PlBvdWNoREI6IGJ1bGtEb2NzKG1vZGVscylcbiAgICogICBhbHQgU3VjY2Vzc1xuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IEFycmF5IG9mIHJlc3BvbnNlcyB3aXRoIG9rPXRydWVcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogYXNzaWduTXVsdGlwbGVNZXRhZGF0YShtb2RlbHMsIHJldnMpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBVcGRhdGVkIG1vZGVscyB3aXRoIG1ldGFkYXRhXG4gICAqICAgZWxzZSBFcnJvclxuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IEFycmF5IHdpdGggZXJyb3JzXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IENoZWNrIGZvciBlcnJvcnNcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IFRocm93cyBJbnRlcm5hbEVycm9yXG4gICAqICAgZW5kXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyBjcmVhdGVBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWRzOiBzdHJpbmdbXSB8IG51bWJlcltdLFxuICAgIG1vZGVsczogUmVjb3JkPHN0cmluZywgYW55PltdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPiB7XG4gICAgbGV0IHJlc3BvbnNlOiBSZXNwb25zZVtdIHwgRXJyW107XG4gICAgdHJ5IHtcbiAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy5uYXRpdmUuYnVsa0RvY3MobW9kZWxzKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IFBvdWNoQWRhcHRlci5wYXJzZUVycm9yKGUpO1xuICAgIH1cbiAgICBpZiAoIXJlc3BvbnNlLmV2ZXJ5KChyOiBSZXNwb25zZSB8IEVycikgPT4gKHIgYXMgUmVzcG9uc2UpLm9rKSkge1xuICAgICAgY29uc3QgZXJyb3JzID0gcmVzcG9uc2UucmVkdWNlKChhY2N1bTogc3RyaW5nW10sIGVsLCBpKSA9PiB7XG4gICAgICAgIGlmIChlbC5lcnJvcilcbiAgICAgICAgICBhY2N1bS5wdXNoKFxuICAgICAgICAgICAgYGVsICR7aX06ICR7ZWwuZXJyb3J9JHtlbC5yZWFzb24gPyBgIC0gJHtlbC5yZWFzb259YCA6IFwiXCJ9YFxuICAgICAgICAgICk7XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0sIFtdKTtcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGVycm9ycy5qb2luKFwiXFxuXCIpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5hc3NpZ25NdWx0aXBsZU1ldGFkYXRhKFxuICAgICAgbW9kZWxzLFxuICAgICAgcmVzcG9uc2UubWFwKChyKSA9PiByLnJldiBhcyBzdHJpbmcpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgZG9jdW1lbnQgZnJvbSB0aGUgZGF0YWJhc2UgYnkgSURcbiAgICogQHN1bW1hcnkgRmV0Y2hlcyBhIGRvY3VtZW50IGZyb20gdGhlIFBvdWNoREIgZGF0YWJhc2UgdXNpbmcgdGhlIGdldCBvcGVyYXRpb24uXG4gICAqIFRoaXMgbWV0aG9kIGdlbmVyYXRlcyB0aGUgZG9jdW1lbnQgSUQgYmFzZWQgb24gdGhlIHRhYmxlIG5hbWUgYW5kIElELCB0aGVuIHJldHJpZXZlcyB0aGUgZG9jdW1lbnQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUvY29sbGVjdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGlkIC0gVGhlIGRvY3VtZW50IElEXG4gICAqIEByZXR1cm4ge1Byb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSByZXRyaWV2ZWQgZG9jdW1lbnQgd2l0aCBtZXRhZGF0YVxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaEFkYXB0ZXJcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaERCXG4gICAqXG4gICAqICAgQ2xpZW50LT4+UG91Y2hBZGFwdGVyOiByZWFkKHRhYmxlTmFtZSwgaWQpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBnZW5lcmF0ZUlkKHRhYmxlTmFtZSwgaWQpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogZ2V0KF9pZClcbiAgICogICBhbHQgU3VjY2Vzc1xuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IERvY3VtZW50XG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IGFzc2lnbk1ldGFkYXRhKHJlY29yZCwgcmVjb3JkLl9yZXYpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBEb2N1bWVudCB3aXRoIG1ldGFkYXRhXG4gICAqICAgZWxzZSBFcnJvclxuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IEVycm9yXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IHBhcnNlRXJyb3IoZSlcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IFRocm93cyBlcnJvclxuICAgKiAgIGVuZFxuICAgKi9cbiAgYXN5bmMgcmVhZChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICAgIGNvbnN0IF9pZCA9IHRoaXMuZ2VuZXJhdGVJZCh0YWJsZU5hbWUsIGlkKTtcbiAgICBsZXQgcmVjb3JkOiBJZE1ldGEgJiBHZXRNZXRhO1xuICAgIHRyeSB7XG4gICAgICByZWNvcmQgPSBhd2FpdCB0aGlzLm5hdGl2ZS5nZXQoX2lkKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IFBvdWNoQWRhcHRlci5wYXJzZUVycm9yKGUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5hc3NpZ25NZXRhZGF0YShyZWNvcmQsIHJlY29yZC5fcmV2KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG11bHRpcGxlIGRvY3VtZW50cyBmcm9tIHRoZSBkYXRhYmFzZSBieSB0aGVpciBJRHNcbiAgICogQHN1bW1hcnkgRmV0Y2hlcyBtdWx0aXBsZSBkb2N1bWVudHMgZnJvbSB0aGUgUG91Y2hEQiBkYXRhYmFzZSB1c2luZyB0aGUgYnVsa0dldCBvcGVyYXRpb24uXG4gICAqIFRoaXMgbWV0aG9kIGdlbmVyYXRlcyBkb2N1bWVudCBJRHMgYmFzZWQgb24gdGhlIHRhYmxlIG5hbWUgYW5kIElEcywgdGhlbiByZXRyaWV2ZXMgdGhlIGRvY3VtZW50cy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nfG51bWJlcnxiaWdpbnQ+fSBpZHMgLSBUaGUgZG9jdW1lbnQgSURzXG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHJldHJpZXZlZCBkb2N1bWVudHMgd2l0aCBtZXRhZGF0YVxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaEFkYXB0ZXJcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaERCXG4gICAqXG4gICAqICAgQ2xpZW50LT4+UG91Y2hBZGFwdGVyOiByZWFkQWxsKHRhYmxlTmFtZSwgaWRzKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogTWFwIGlkcyB0byBnZW5lcmF0ZUlkKHRhYmxlTmFtZSwgaWQpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogYnVsa0dldCh7ZG9jc30pXG4gICAqICAgYWx0IFN1Y2Nlc3NcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBCdWxrR2V0UmVzcG9uc2VcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogUHJvY2VzcyByZXN1bHRzXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IGFzc2lnbk1ldGFkYXRhIGZvciBlYWNoIGRvY1xuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogRG9jdW1lbnRzIHdpdGggbWV0YWRhdGFcbiAgICogICBlbHNlIEVycm9yXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IHBhcnNlRXJyb3IoZXJyb3IpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBUaHJvd3MgZXJyb3JcbiAgICogICBlbmRcbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIHJlYWRBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWRzOiAoc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50KVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPiB7XG4gICAgY29uc3QgcmVzdWx0czogQnVsa0dldFJlc3BvbnNlPGFueT4gPSBhd2FpdCB0aGlzLm5hdGl2ZS5idWxrR2V0KHtcbiAgICAgIGRvY3M6IGlkcy5tYXAoKGlkKSA9PiAoeyBpZDogdGhpcy5nZW5lcmF0ZUlkKHRhYmxlTmFtZSwgaWQgYXMgYW55KSB9KSksXG4gICAgfSk7XG4gICAgY29uc3QgcmVzID0gcmVzdWx0cy5yZXN1bHRzLnJlZHVjZSgoYWNjdW06IGFueVtdLCByKSA9PiB7XG4gICAgICByLmRvY3MuZm9yRWFjaCgoZCkgPT4ge1xuICAgICAgICBpZiAoKGQgYXMgYW55KS5lcnJvciB8fCAhKGQgYXMgYW55KS5vaylcbiAgICAgICAgICB0aHJvdyBQb3VjaEFkYXB0ZXIucGFyc2VFcnJvcihcbiAgICAgICAgICAgICgoZCBhcyB7IGVycm9yOiBFcnIgfSkuZXJyb3IgYXMgRXJyb3IpIHx8XG4gICAgICAgICAgICAgIG5ldyBJbnRlcm5hbEVycm9yKFwiTWlzc2luZyB2YWxpZCByZXNwb25zZVwiKVxuICAgICAgICAgICk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IE9iamVjdC5hc3NpZ24oe30sIChkIGFzIHsgb2s6IGFueSB9KS5vayk7XG4gICAgICAgIGFjY3VtLnB1c2godGhpcy5hc3NpZ25NZXRhZGF0YShyZXN1bHQsIChkIGFzIGFueSkub2tbQ291Y2hEQktleXMuUkVWXSkpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSwgW10pO1xuXG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVXBkYXRlcyBhbiBleGlzdGluZyBkb2N1bWVudCBpbiB0aGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgVXBkYXRlcyBhIGRvY3VtZW50IGluIHRoZSBQb3VjaERCIGRhdGFiYXNlIHVzaW5nIHRoZSBwdXQgb3BlcmF0aW9uLlxuICAgKiBUaGlzIG1ldGhvZCBoYW5kbGVzIGVycm9yIHBhcnNpbmcgYW5kIGVuc3VyZXMgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gaWQgLSBUaGUgZG9jdW1lbnQgSURcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBtb2RlbCAtIFRoZSB1cGRhdGVkIGRvY3VtZW50IGRhdGFcbiAgICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHVwZGF0ZWQgZG9jdW1lbnQgd2l0aCBtZXRhZGF0YVxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaEFkYXB0ZXJcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaERCXG4gICAqXG4gICAqICAgQ2xpZW50LT4+UG91Y2hBZGFwdGVyOiB1cGRhdGUodGFibGVOYW1lLCBpZCwgbW9kZWwpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogcHV0KG1vZGVsKVxuICAgKiAgIGFsdCBTdWNjZXNzXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogUmVzcG9uc2Ugd2l0aCBvaz10cnVlXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IGFzc2lnbk1ldGFkYXRhKG1vZGVsLCByZXNwb25zZS5yZXYpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBVcGRhdGVkIG1vZGVsIHdpdGggbWV0YWRhdGFcbiAgICogICBlbHNlIEVycm9yXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogRXJyb3JcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogcGFyc2VFcnJvcihlKVxuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogVGhyb3dzIGVycm9yXG4gICAqICAgZW5kXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyB1cGRhdGUoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlcixcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PlxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+IHtcbiAgICBsZXQgcmVzcG9uc2U6IFJlc3BvbnNlO1xuICAgIHRyeSB7XG4gICAgICByZXNwb25zZSA9IGF3YWl0IHRoaXMubmF0aXZlLnB1dChtb2RlbCk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBQb3VjaEFkYXB0ZXIucGFyc2VFcnJvcihlKTtcbiAgICB9XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gdXBkYXRlIGRvYyBpZDogJHtpZH0gaW4gdGFibGUgJHt0YWJsZU5hbWV9YFxuICAgICAgKTtcbiAgICByZXR1cm4gdGhpcy5hc3NpZ25NZXRhZGF0YShtb2RlbCwgcmVzcG9uc2UucmV2KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVXBkYXRlcyBtdWx0aXBsZSBkb2N1bWVudHMgaW4gdGhlIGRhdGFiYXNlIGluIGEgc2luZ2xlIG9wZXJhdGlvblxuICAgKiBAc3VtbWFyeSBVcGRhdGVzIG11bHRpcGxlIGRvY3VtZW50cyBpbiB0aGUgUG91Y2hEQiBkYXRhYmFzZSB1c2luZyB0aGUgYnVsa0RvY3Mgb3BlcmF0aW9uLlxuICAgKiBUaGlzIG1ldGhvZCBoYW5kbGVzIGVycm9yIHBhcnNpbmcgYW5kIGVuc3VyZXMgYWxsIG9wZXJhdGlvbnMgd2VyZSBzdWNjZXNzZnVsLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlL2NvbGxlY3Rpb25cbiAgICogQHBhcmFtIHtzdHJpbmdbXXxudW1iZXJbXX0gaWRzIC0gVGhlIGRvY3VtZW50IElEc1xuICAgKiBAcGFyYW0gbW9kZWxzIC0gVGhlIHVwZGF0ZWQgZG9jdW1lbnQgZGF0YVxuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSB1cGRhdGVkIGRvY3VtZW50cyB3aXRoIG1ldGFkYXRhXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoREJcbiAgICpcbiAgICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IHVwZGF0ZUFsbCh0YWJsZU5hbWUsIGlkcywgbW9kZWxzKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PlBvdWNoREI6IGJ1bGtEb2NzKG1vZGVscylcbiAgICogICBhbHQgU3VjY2Vzc1xuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IEFycmF5IG9mIHJlc3BvbnNlcyB3aXRoIG9rPXRydWVcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogYXNzaWduTXVsdGlwbGVNZXRhZGF0YShtb2RlbHMsIHJldnMpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBVcGRhdGVkIG1vZGVscyB3aXRoIG1ldGFkYXRhXG4gICAqICAgZWxzZSBFcnJvclxuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IEFycmF5IHdpdGggZXJyb3JzXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IENoZWNrIGZvciBlcnJvcnNcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IFRocm93cyBJbnRlcm5hbEVycm9yXG4gICAqICAgZW5kXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyB1cGRhdGVBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWRzOiBzdHJpbmdbXSB8IG51bWJlcltdLFxuICAgIG1vZGVsczogUmVjb3JkPHN0cmluZywgYW55PltdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPiB7XG4gICAgbGV0IHJlc3BvbnNlOiAoUmVzcG9uc2UgfCBFcnIpW107XG4gICAgdHJ5IHtcbiAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy5uYXRpdmUuYnVsa0RvY3MobW9kZWxzKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IFBvdWNoQWRhcHRlci5wYXJzZUVycm9yKGUpO1xuICAgIH1cbiAgICBpZiAoIXJlc3BvbnNlLmV2ZXJ5KChyKSA9PiAhKHIgYXMgYW55KS5lcnJvcikpIHtcbiAgICAgIGNvbnN0IGVycm9ycyA9IHJlc3BvbnNlLnJlZHVjZSgoYWNjdW06IHN0cmluZ1tdLCBlbCwgaSkgPT4ge1xuICAgICAgICBpZiAoKGVsIGFzIGFueSkuZXJyb3IpXG4gICAgICAgICAgYWNjdW0ucHVzaChcbiAgICAgICAgICAgIGBlbCAke2l9OiAkeyhlbCBhcyBhbnkpLmVycm9yfSR7KGVsIGFzIGFueSkucmVhc29uID8gYCAtICR7KGVsIGFzIGFueSkucmVhc29ufWAgOiBcIlwifWBcbiAgICAgICAgICApO1xuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LCBbXSk7XG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihlcnJvcnMuam9pbihcIlxcblwiKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYXNzaWduTXVsdGlwbGVNZXRhZGF0YShcbiAgICAgIG1vZGVscyxcbiAgICAgIHJlc3BvbnNlLm1hcCgocikgPT4gci5yZXYgYXMgc3RyaW5nKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERlbGV0ZXMgYSBkb2N1bWVudCBmcm9tIHRoZSBkYXRhYmFzZSBieSBJRFxuICAgKiBAc3VtbWFyeSBSZW1vdmVzIGEgZG9jdW1lbnQgZnJvbSB0aGUgUG91Y2hEQiBkYXRhYmFzZSB1c2luZyB0aGUgcmVtb3ZlIG9wZXJhdGlvbi5cbiAgICogVGhpcyBtZXRob2QgZmlyc3QgcmV0cmlldmVzIHRoZSBkb2N1bWVudCB0byBnZXQgaXRzIHJldmlzaW9uLCB0aGVuIGRlbGV0ZXMgaXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUvY29sbGVjdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGlkIC0gVGhlIGRvY3VtZW50IElEXG4gICAqIEByZXR1cm4ge1Byb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkZWxldGVkIGRvY3VtZW50IHdpdGggbWV0YWRhdGFcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hBZGFwdGVyXG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hEQlxuICAgKlxuICAgKiAgIENsaWVudC0+PlBvdWNoQWRhcHRlcjogZGVsZXRlKHRhYmxlTmFtZSwgaWQpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBnZW5lcmF0ZUlkKHRhYmxlTmFtZSwgaWQpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogZ2V0KF9pZClcbiAgICogICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogRG9jdW1lbnQgd2l0aCBfcmV2XG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogcmVtb3ZlKF9pZCwgcmVjb3JkLl9yZXYpXG4gICAqICAgYWx0IFN1Y2Nlc3NcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBTdWNjZXNzIHJlc3BvbnNlXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IGFzc2lnbk1ldGFkYXRhKHJlY29yZCwgcmVjb3JkLl9yZXYpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBEZWxldGVkIGRvY3VtZW50IHdpdGggbWV0YWRhdGFcbiAgICogICBlbHNlIEVycm9yXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogRXJyb3JcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogcGFyc2VFcnJvcihlKVxuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogVGhyb3dzIGVycm9yXG4gICAqICAgZW5kXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyBkZWxldGUoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlclxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+IHtcbiAgICBjb25zdCBfaWQgPSB0aGlzLmdlbmVyYXRlSWQodGFibGVOYW1lLCBpZCk7XG4gICAgbGV0IHJlY29yZDogSWRNZXRhICYgR2V0TWV0YTtcbiAgICB0cnkge1xuICAgICAgcmVjb3JkID0gYXdhaXQgdGhpcy5uYXRpdmUuZ2V0KF9pZCk7XG4gICAgICBhd2FpdCB0aGlzLm5hdGl2ZS5yZW1vdmUoX2lkLCByZWNvcmQuX3Jldik7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBQb3VjaEFkYXB0ZXIucGFyc2VFcnJvcihlKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYXNzaWduTWV0YWRhdGEocmVjb3JkLCByZWNvcmQuX3Jldik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERlbGV0ZXMgbXVsdGlwbGUgZG9jdW1lbnRzIGZyb20gdGhlIGRhdGFiYXNlIGJ5IHRoZWlyIElEc1xuICAgKiBAc3VtbWFyeSBSZW1vdmVzIG11bHRpcGxlIGRvY3VtZW50cyBmcm9tIHRoZSBQb3VjaERCIGRhdGFiYXNlIGluIGEgc2luZ2xlIG9wZXJhdGlvbi5cbiAgICogVGhpcyBtZXRob2QgZmlyc3QgcmV0cmlldmVzIGFsbCBkb2N1bWVudHMgdG8gZ2V0IHRoZWlyIHJldmlzaW9ucywgdGhlbiBtYXJrcyB0aGVtIGFzIGRlbGV0ZWQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUvY29sbGVjdGlvblxuICAgKiBAcGFyYW0ge0FycmF5PHN0cmluZ3xudW1iZXJ8YmlnaW50Pn0gaWRzIC0gVGhlIGRvY3VtZW50IElEc1xuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkZWxldGVkIGRvY3VtZW50cyB3aXRoIG1ldGFkYXRhXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoREJcbiAgICpcbiAgICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IGRlbGV0ZUFsbCh0YWJsZU5hbWUsIGlkcylcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IE1hcCBpZHMgdG8gZ2VuZXJhdGVJZCh0YWJsZU5hbWUsIGlkKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PlBvdWNoREI6IGJ1bGtHZXQoe2RvY3N9KVxuICAgKiAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBCdWxrR2V0UmVzcG9uc2Ugd2l0aCBkb2N1bWVudHNcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IE1hcmsgZG9jdW1lbnRzIGFzIGRlbGV0ZWRcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaERCOiBidWxrRG9jcyhtYXJrZWQgZG9jdW1lbnRzKVxuICAgKiAgIGFsdCBTdWNjZXNzXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogU3VjY2VzcyByZXNwb25zZXNcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogUHJvY2VzcyByZXN1bHRzXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IGFzc2lnbk1ldGFkYXRhIGZvciBlYWNoIGRvY1xuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogRGVsZXRlZCBkb2N1bWVudHMgd2l0aCBtZXRhZGF0YVxuICAgKiAgIGVsc2UgRXJyb3JcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogQ2hlY2sgZm9yIGVycm9yc1xuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogVGhyb3dzIEludGVybmFsRXJyb3JcbiAgICogICBlbmRcbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIGRlbGV0ZUFsbChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZHM6IChzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQpW11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBjb25zdCByZXN1bHRzOiBCdWxrR2V0UmVzcG9uc2U8YW55PiA9IGF3YWl0IHRoaXMubmF0aXZlLmJ1bGtHZXQoe1xuICAgICAgZG9jczogaWRzLm1hcCgoaWQpID0+ICh7IGlkOiB0aGlzLmdlbmVyYXRlSWQodGFibGVOYW1lLCBpZCBhcyBhbnkpIH0pKSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGRlbGV0aW9uOiAoUmVzcG9uc2UgfCBFcnIpW10gPSBhd2FpdCB0aGlzLm5hdGl2ZS5idWxrRG9jcyhcbiAgICAgIHJlc3VsdHMucmVzdWx0cy5tYXAoKHIpID0+IHtcbiAgICAgICAgKHIgYXMgYW55KVtDb3VjaERCS2V5cy5ERUxFVEVEXSA9IHRydWU7XG4gICAgICAgIHJldHVybiByO1xuICAgICAgfSlcbiAgICApO1xuXG4gICAgY29uc3QgZXJycyA9IGRlbGV0aW9uLmZpbHRlcigoZCkgPT4gKGQgYXMgYW55KS5lcnJvcik7XG4gICAgaWYgKGVycnMubGVuZ3RoKSB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihlcnJzLmpvaW4oXCJcXG5cIikpO1xuXG4gICAgcmV0dXJuIHJlc3VsdHMucmVzdWx0cy5yZWR1Y2UoKGFjY3VtOiBhbnlbXSwgcikgPT4ge1xuICAgICAgci5kb2NzLmZvckVhY2goKGQpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gT2JqZWN0LmFzc2lnbih7fSwgKGQgYXMgeyBvazogYW55IH0pLm9rKTtcbiAgICAgICAgYWNjdW0ucHVzaCh0aGlzLmFzc2lnbk1ldGFkYXRhKHJlc3VsdCwgKGQgYXMgYW55KS5va1tDb3VjaERCS2V5cy5SRVZdKSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBhY2N1bTtcbiAgICB9LCBbXSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEV4ZWN1dGVzIGEgcmF3IE1hbmdvIHF1ZXJ5IGFnYWluc3QgdGhlIGRhdGFiYXNlXG4gICAqIEBzdW1tYXJ5IFBlcmZvcm1zIGEgZGlyZWN0IGZpbmQgb3BlcmF0aW9uIHVzaW5nIGEgTWFuZ28gcXVlcnkgb2JqZWN0LlxuICAgKiBUaGlzIG1ldGhvZCBhbGxvd3MgZm9yIGNvbXBsZXggcXVlcmllcyBiZXlvbmQgdGhlIHN0YW5kYXJkIENSVUQgb3BlcmF0aW9ucy5cbiAgICogQHRlbXBsYXRlIFYgLSBUaGUgcmV0dXJuIHR5cGVcbiAgICogQHBhcmFtIHtNYW5nb1F1ZXJ5fSByYXdJbnB1dCAtIFRoZSBNYW5nbyBxdWVyeSB0byBleGVjdXRlXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Byb2Nlc3M9dHJ1ZV0gLSBXaGV0aGVyIHRvIHByb2Nlc3MgdGhlIHJlc3BvbnNlICh0cnVlIHJldHVybnMganVzdCBkb2NzLCBmYWxzZSByZXR1cm5zIGZ1bGwgcmVzcG9uc2UpXG4gICAqIEByZXR1cm4ge1Byb21pc2U8Vj59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBxdWVyeSByZXN1bHRzXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoREJcbiAgICpcbiAgICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IHJhdzxWPihyYXdJbnB1dCwgcHJvY2VzcylcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaERCOiBmaW5kKHJhd0lucHV0KVxuICAgKiAgIGFsdCBTdWNjZXNzXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogRmluZFJlc3BvbnNlXG4gICAqICAgICBhbHQgcHJvY2Vzcz10cnVlXG4gICAqICAgICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IHJlc3BvbnNlLmRvY3MgYXMgVlxuICAgKiAgICAgZWxzZSBwcm9jZXNzPWZhbHNlXG4gICAqICAgICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IHJlc3BvbnNlIGFzIFZcbiAgICogICAgIGVuZFxuICAgKiAgIGVsc2UgRXJyb3JcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBFcnJvclxuICAgKiAgICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBwYXJzZUVycm9yKGUpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBUaHJvd3MgZXJyb3JcbiAgICogICBlbmRcbiAgICovXG4gIGFzeW5jIHJhdzxWPihyYXdJbnB1dDogTWFuZ29RdWVyeSwgcHJvY2VzcyA9IHRydWUpOiBQcm9taXNlPFY+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2U6IEZpbmRSZXNwb25zZTxhbnk+ID0gYXdhaXQgdGhpcy5uYXRpdmUuZmluZChcbiAgICAgICAgcmF3SW5wdXQgYXMgYW55XG4gICAgICApO1xuICAgICAgaWYgKHJlc3BvbnNlLndhcm5pbmcpIGNvbnNvbGUud2FybihyZXNwb25zZS53YXJuaW5nKTtcbiAgICAgIGlmIChwcm9jZXNzKSByZXR1cm4gcmVzcG9uc2UuZG9jcyBhcyBWO1xuICAgICAgcmV0dXJuIHJlc3BvbnNlIGFzIFY7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBQb3VjaEFkYXB0ZXIucGFyc2VFcnJvcihlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFBhcnNlcyBhbmQgY29udmVydHMgZXJyb3JzIGZyb20gUG91Y2hEQiB0byBhcHBsaWNhdGlvbi1zcGVjaWZpYyBlcnJvcnNcbiAgICogQHN1bW1hcnkgQ29udmVydHMgUG91Y2hEQiBlcnJvcnMgdG8gdGhlIGFwcGxpY2F0aW9uJ3MgZXJyb3IgaGllcmFyY2h5LlxuICAgKiBUaGlzIGluc3RhbmNlIG1ldGhvZCBkZWxlZ2F0ZXMgdG8gdGhlIHN0YXRpYyBwYXJzZUVycm9yIG1ldGhvZC5cbiAgICogQHBhcmFtIHtFcnJvcnxzdHJpbmd9IGVyciAtIFRoZSBlcnJvciBvYmplY3Qgb3IgbWVzc2FnZSB0byBwYXJzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3JlYXNvbl0gLSBPcHRpb25hbCByZWFzb24gZm9yIHRoZSBlcnJvclxuICAgKiBAcmV0dXJuIHtCYXNlRXJyb3J9IFRoZSBjb252ZXJ0ZWQgZXJyb3Igb2JqZWN0XG4gICAqL1xuICBvdmVycmlkZSBwYXJzZUVycm9yKGVycjogRXJyb3IgfCBzdHJpbmcsIHJlYXNvbj86IHN0cmluZyk6IEJhc2VFcnJvciB7XG4gICAgcmV0dXJuIFBvdWNoQWRhcHRlci5wYXJzZUVycm9yKGVyciwgcmVhc29uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU3RhdGljIG1ldGhvZCB0byBwYXJzZSBhbmQgY29udmVydCBlcnJvcnMgZnJvbSBQb3VjaERCIHRvIGFwcGxpY2F0aW9uLXNwZWNpZmljIGVycm9yc1xuICAgKiBAc3VtbWFyeSBDb252ZXJ0cyBQb3VjaERCIGVycm9ycyB0byB0aGUgYXBwbGljYXRpb24ncyBlcnJvciBoaWVyYXJjaHkgYmFzZWQgb24gZXJyb3IgY29kZXMgYW5kIG1lc3NhZ2VzLlxuICAgKiBUaGlzIG1ldGhvZCBhbmFseXplcyB0aGUgZXJyb3IgdHlwZSwgc3RhdHVzIGNvZGUsIG9yIG1lc3NhZ2UgdG8gZGV0ZXJtaW5lIHRoZSBhcHByb3ByaWF0ZSBlcnJvciBjbGFzcy5cbiAgICogQHBhcmFtIHtFcnJvcnxzdHJpbmd9IGVyciAtIFRoZSBlcnJvciBvYmplY3Qgb3IgbWVzc2FnZSB0byBwYXJzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3JlYXNvbl0gLSBPcHRpb25hbCByZWFzb24gZm9yIHRoZSBlcnJvclxuICAgKiBAcmV0dXJuIHtCYXNlRXJyb3J9IFRoZSBjb252ZXJ0ZWQgZXJyb3Igb2JqZWN0XG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKlxuICAgKiAgIENhbGxlci0+PlBvdWNoQWRhcHRlcjogcGFyc2VFcnJvcihlcnIsIHJlYXNvbilcbiAgICogICBhbHQgZXJyIGlzIEJhc2VFcnJvclxuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogUmV0dXJuIGVyciBhcyBpc1xuICAgKiAgIGVsc2UgZXJyIGlzIHN0cmluZ1xuICAgKiAgICAgYWx0IGNvbnRhaW5zIFwiYWxyZWFkeSBleGlzdFwiIG9yIFwidXBkYXRlIGNvbmZsaWN0XCJcbiAgICogICAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogQ29uZmxpY3RFcnJvclxuICAgKiAgICAgZWxzZSBjb250YWlucyBcIm1pc3NpbmdcIiBvciBcImRlbGV0ZWRcIlxuICAgKiAgICAgICBQb3VjaEFkYXB0ZXItLT4+Q2FsbGVyOiBOb3RGb3VuZEVycm9yXG4gICAqICAgICBlbmRcbiAgICogICBlbHNlIGVyciBoYXMgc3RhdHVzXG4gICAqICAgICBhbHQgc3RhdHVzIGlzIDQwMSwgNDEyLCA0MDlcbiAgICogICAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogQ29uZmxpY3RFcnJvclxuICAgKiAgICAgZWxzZSBzdGF0dXMgaXMgNDA0XG4gICAqICAgICAgIFBvdWNoQWRhcHRlci0tPj5DYWxsZXI6IE5vdEZvdW5kRXJyb3JcbiAgICogICAgIGVsc2Ugc3RhdHVzIGlzIDQwMFxuICAgKiAgICAgICBhbHQgbWVzc2FnZSBjb250YWlucyBcIk5vIGluZGV4IGV4aXN0c1wiXG4gICAqICAgICAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogSW5kZXhFcnJvclxuICAgKiAgICAgICBlbHNlXG4gICAqICAgICAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogSW50ZXJuYWxFcnJvclxuICAgKiAgICAgICBlbmRcbiAgICogICAgIGVsc2UgbWVzc2FnZSBjb250YWlucyBcIkVDT05OUkVGVVNFRFwiXG4gICAqICAgICAgIFBvdWNoQWRhcHRlci0tPj5DYWxsZXI6IENvbm5lY3Rpb25FcnJvclxuICAgKiAgICAgZWxzZVxuICAgKiAgICAgICBQb3VjaEFkYXB0ZXItLT4+Q2FsbGVyOiBJbnRlcm5hbEVycm9yXG4gICAqICAgICBlbmRcbiAgICogICBlbmRcbiAgICovXG4gIHN0YXRpYyBvdmVycmlkZSBwYXJzZUVycm9yKGVycjogRXJyb3IgfCBzdHJpbmcsIHJlYXNvbj86IHN0cmluZyk6IEJhc2VFcnJvciB7XG4gICAgLy8gcmV0dXJuIHN1cGVyLnBhcnNlRXJyb3IoZXJyLCByZWFzb24pO1xuICAgIGlmIChlcnIgaW5zdGFuY2VvZiBCYXNlRXJyb3IpIHJldHVybiBlcnIgYXMgYW55O1xuICAgIGxldCBjb2RlOiBzdHJpbmcgPSBcIlwiO1xuICAgIGlmICh0eXBlb2YgZXJyID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBjb2RlID0gZXJyO1xuICAgICAgaWYgKGNvZGUubWF0Y2goL2FscmVhZHkgZXhpc3R8dXBkYXRlIGNvbmZsaWN0L2cpKVxuICAgICAgICByZXR1cm4gbmV3IENvbmZsaWN0RXJyb3IoY29kZSk7XG4gICAgICBpZiAoY29kZS5tYXRjaCgvbWlzc2luZ3xkZWxldGVkL2cpKSByZXR1cm4gbmV3IE5vdEZvdW5kRXJyb3IoY29kZSk7XG4gICAgfSBlbHNlIGlmICgoZXJyIGFzIGFueSkuc3RhdHVzKSB7XG4gICAgICBjb2RlID0gKGVyciBhcyBhbnkpLnN0YXR1cztcbiAgICAgIHJlYXNvbiA9IHJlYXNvbiB8fCBlcnIubWVzc2FnZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZSA9IGVyci5tZXNzYWdlO1xuICAgIH1cblxuICAgIHN3aXRjaCAoY29kZS50b1N0cmluZygpKSB7XG4gICAgICBjYXNlIFwiNDAxXCI6XG4gICAgICBjYXNlIFwiNDEyXCI6XG4gICAgICBjYXNlIFwiNDA5XCI6XG4gICAgICAgIHJldHVybiBuZXcgQ29uZmxpY3RFcnJvcihyZWFzb24gYXMgc3RyaW5nKTtcbiAgICAgIGNhc2UgXCI0MDRcIjpcbiAgICAgICAgcmV0dXJuIG5ldyBOb3RGb3VuZEVycm9yKHJlYXNvbiBhcyBzdHJpbmcpO1xuICAgICAgY2FzZSBcIjQwMFwiOlxuICAgICAgICBpZiAoY29kZS50b1N0cmluZygpLm1hdGNoKC9Ob1xcc2luZGV4XFxzZXhpc3RzL2cpKVxuICAgICAgICAgIHJldHVybiBuZXcgSW5kZXhFcnJvcihlcnIpO1xuICAgICAgICByZXR1cm4gbmV3IEludGVybmFsRXJyb3IoZXJyKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChjb2RlLnRvU3RyaW5nKCkubWF0Y2goL0VDT05OUkVGVVNFRC9nKSlcbiAgICAgICAgICByZXR1cm4gbmV3IENvbm5lY3Rpb25FcnJvcihlcnIpO1xuICAgICAgICByZXR1cm4gbmV3IEludGVybmFsRXJyb3IoZXJyKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdXAgZGVjb3JhdGlvbnMgZm9yIFBvdWNoREItc3BlY2lmaWMgbW9kZWwgcHJvcGVydGllc1xuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIGRlY29yYXRvcnMgZm9yIGNyZWF0ZWRCeSBhbmQgdXBkYXRlZEJ5IGZpZWxkcyBpbiBtb2RlbHMuXG4gICAqIFRoaXMgbWV0aG9kIGRlZmluZXMgaG93IHRoZXNlIGZpZWxkcyBzaG91bGQgYmUgYXV0b21hdGljYWxseSBwb3B1bGF0ZWQgZHVyaW5nIGNyZWF0ZSBhbmQgdXBkYXRlIG9wZXJhdGlvbnMuXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IERlY29yYXRpb25cbiAgICpcbiAgICogICBDYWxsZXItPj5Qb3VjaEFkYXB0ZXI6IGRlY29yYXRpb24oKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PlJlcG9zaXRvcnk6IGtleShQZXJzaXN0ZW5jZUtleXMuQ1JFQVRFRF9CWSlcbiAgICogICBSZXBvc2l0b3J5LS0+PlBvdWNoQWRhcHRlcjogY3JlYXRlZEJ5S2V5XG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UmVwb3NpdG9yeToga2V5KFBlcnNpc3RlbmNlS2V5cy5VUERBVEVEX0JZKVxuICAgKiAgIFJlcG9zaXRvcnktLT4+UG91Y2hBZGFwdGVyOiB1cGRhdGVkQnlLZXlcbiAgICpcbiAgICogICBQb3VjaEFkYXB0ZXItPj5EZWNvcmF0aW9uOiBmbGF2b3VyZWRBcyhQb3VjaEZsYXZvdXIpXG4gICAqICAgRGVjb3JhdGlvbi0tPj5Qb3VjaEFkYXB0ZXI6IERlY29yYXRvckJ1aWxkZXJcbiAgICogICBQb3VjaEFkYXB0ZXItPj5EZWNvcmF0aW9uOiBmb3IoY3JlYXRlZEJ5S2V5KVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PkRlY29yYXRpb246IGRlZmluZShvbkNyZWF0ZSwgcHJvcE1ldGFkYXRhKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PkRlY29yYXRpb246IGFwcGx5KClcbiAgICpcbiAgICogICBQb3VjaEFkYXB0ZXItPj5EZWNvcmF0aW9uOiBmbGF2b3VyZWRBcyhQb3VjaEZsYXZvdXIpXG4gICAqICAgRGVjb3JhdGlvbi0tPj5Qb3VjaEFkYXB0ZXI6IERlY29yYXRvckJ1aWxkZXJcbiAgICogICBQb3VjaEFkYXB0ZXItPj5EZWNvcmF0aW9uOiBmb3IodXBkYXRlZEJ5S2V5KVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PkRlY29yYXRpb246IGRlZmluZShvbkNyZWF0ZSwgcHJvcE1ldGFkYXRhKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PkRlY29yYXRpb246IGFwcGx5KClcbiAgICovXG4gIHN0YXRpYyBvdmVycmlkZSBkZWNvcmF0aW9uKCkge1xuICAgIHN1cGVyLmRlY29yYXRpb24oKTtcbiAgICBjb25zdCBjcmVhdGVkQnlLZXkgPSBSZXBvc2l0b3J5LmtleShQZXJzaXN0ZW5jZUtleXMuQ1JFQVRFRF9CWSk7XG4gICAgY29uc3QgdXBkYXRlZEJ5S2V5ID0gUmVwb3NpdG9yeS5rZXkoUGVyc2lzdGVuY2VLZXlzLlVQREFURURfQlkpO1xuICAgIERlY29yYXRpb24uZmxhdm91cmVkQXMoUG91Y2hGbGF2b3VyKVxuICAgICAgLmZvcihjcmVhdGVkQnlLZXkpXG4gICAgICAuZGVmaW5lKFxuICAgICAgICBvbkNyZWF0ZShjcmVhdGVkQnlPblBvdWNoQ3JlYXRlVXBkYXRlKSxcbiAgICAgICAgcHJvcE1ldGFkYXRhKGNyZWF0ZWRCeUtleSwge30pXG4gICAgICApXG4gICAgICAuYXBwbHkoKTtcbiAgICBEZWNvcmF0aW9uLmZsYXZvdXJlZEFzKFBvdWNoRmxhdm91cilcbiAgICAgIC5mb3IodXBkYXRlZEJ5S2V5KVxuICAgICAgLmRlZmluZShcbiAgICAgICAgb25DcmVhdGVVcGRhdGUoY3JlYXRlZEJ5T25Qb3VjaENyZWF0ZVVwZGF0ZSksXG4gICAgICAgIHByb3BNZXRhZGF0YSh1cGRhdGVkQnlLZXksIHt9KVxuICAgICAgKVxuICAgICAgLmFwcGx5KCk7XG4gIH1cbn1cblxuUG91Y2hBZGFwdGVyLnNldEN1cnJlbnQoUG91Y2hGbGF2b3VyKTtcbiJdfQ==
731
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9hZGFwdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWdFQSxvRUFvQkM7QUFwRkQsNEJBQTBCO0FBQzFCLHVEQU8rQjtBQUMvQiwyREFTaUM7QUFDakMseUNBTXdCO0FBT3hCLHlFQUt3QztBQUl4QywrQ0FBb0U7QUFFcEUsZ0VBQW1DO0FBQ25DLGtFQUFvRDtBQUNwRCxzRUFBd0Q7QUFDeEQsd0RBQTBDO0FBRTFDOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNJLEtBQUssVUFBVSw0QkFBNEIsQ0FNaEQsT0FBNEIsRUFDNUIsSUFBTyxFQUNQLEdBQVksRUFDWixLQUFRO0lBRVIsSUFBSSxDQUFDO1FBQ0gsTUFBTSxJQUFJLEdBQVcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN6QyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBa0IsQ0FBQztRQUNoQyw2REFBNkQ7SUFDL0QsQ0FBQztJQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7UUFDcEIsTUFBTSxJQUFJLHVCQUFnQixDQUN4QixnRUFBZ0UsQ0FDakUsQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0RHO0FBQ0gsTUFBYSxZQUFhLFNBQVEsNEJBS2pDO0lBQ0MsWUFBWSxNQUFtQixFQUFFLEtBQWM7UUFDN0MsS0FBSyxDQUFDLE1BQU0sRUFBRSx3QkFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7U0F1Qks7SUFDTSxTQUFTO1FBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDbEIsTUFBTSxPQUFPLEdBQUc7Z0JBQ2QsY0FB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QUMsR0FBRyxDQUFDLHNCQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDaEUsaUNBQVUsQ0FBQyxXQUFXLENBQUMsd0JBQVksQ0FBQzthQUNqQyxHQUFHLENBQUMsWUFBWSxDQUFDO2FBQ2pCLE1BQU0sQ0FDTCxJQUFBLHdCQUFRLEVBQUMsNEJBQTRCLENBQUMsRUFDdEMsSUFBQSxtQ0FBWSxFQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FDL0I7YUFDQSxLQUFLLEVBQUUsQ0FBQztRQUNYLGlDQUFVLENBQUMsV0FBVyxDQUFDLHdCQUFZLENBQUM7YUFDakMsR0FBRyxDQUFDLFlBQVksQ0FBQzthQUNqQixNQUFNLENBQ0wsSUFBQSw4QkFBYyxFQUFDLDRCQUE0QixDQUFDLEVBQzVDLElBQUEsbUNBQVksRUFBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLENBQy9CO2FBQ0EsS0FBSyxFQUFFLENBQUM7SUFDYixDQUFDO0NBQ0Y7QUFscUJELG9DQWtxQkM7QUFFRCxZQUFZLENBQUMsVUFBVSxDQUFDLHdCQUFZLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBcInJlZmxlY3QtbWV0YWRhdGFcIjtcbmltcG9ydCB7XG4gIENvdWNoREJBZGFwdGVyLFxuICBDb3VjaERCS2V5cyxcbiAgQ3JlYXRlSW5kZXhSZXF1ZXN0LFxuICBnZW5lcmF0ZUluZGV4ZXMsXG4gIEluZGV4RXJyb3IsXG4gIE1hbmdvUXVlcnksXG59IGZyb20gXCJAZGVjYWYtdHMvZm9yLWNvdWNoZGJcIjtcbmltcG9ydCB7XG4gIEJhc2VFcnJvcixcbiAgQ29uZmxpY3RFcnJvcixcbiAgQ29udGV4dCxcbiAgSW50ZXJuYWxFcnJvcixcbiAgTm90Rm91bmRFcnJvcixcbiAgb25DcmVhdGUsXG4gIG9uQ3JlYXRlVXBkYXRlLFxuICBPcGVyYXRpb25LZXlzLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7XG4gIENvbm5lY3Rpb25FcnJvcixcbiAgUGVyc2lzdGVuY2VLZXlzLFxuICBSZWxhdGlvbnNNZXRhZGF0YSxcbiAgUmVwb3NpdG9yeSxcbiAgVW5zdXBwb3J0ZWRFcnJvcixcbn0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgRGF0YWJhc2UgPSBQb3VjaERCLkRhdGFiYXNlO1xuaW1wb3J0IFJlc3BvbnNlID0gUG91Y2hEQi5Db3JlLlJlc3BvbnNlO1xuaW1wb3J0IEVyciA9IFBvdWNoREIuQ29yZS5FcnJvcjtcbmltcG9ydCBJZE1ldGEgPSBQb3VjaERCLkNvcmUuSWRNZXRhO1xuaW1wb3J0IEdldE1ldGEgPSBQb3VjaERCLkNvcmUuR2V0TWV0YTtcbmltcG9ydCBDcmVhdGVJbmRleFJlc3BvbnNlID0gUG91Y2hEQi5GaW5kLkNyZWF0ZUluZGV4UmVzcG9uc2U7XG5pbXBvcnQge1xuICBDb25zdHJ1Y3RvcixcbiAgRGVjb3JhdGlvbixcbiAgTW9kZWwsXG4gIHByb3BNZXRhZGF0YSxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IEJ1bGtHZXRSZXNwb25zZSA9IFBvdWNoREIuQ29yZS5CdWxrR2V0UmVzcG9uc2U7XG5pbXBvcnQgRmluZFJlc3BvbnNlID0gUG91Y2hEQi5GaW5kLkZpbmRSZXNwb25zZTtcbmltcG9ydCB7IFBvdWNoQ29uZmlnLCBQb3VjaEZsYWdzIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IERlZmF1bHRMb2NhbFN0b3JhZ2VQYXRoLCBQb3VjaEZsYXZvdXIgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFBvdWNoUmVwb3NpdG9yeSB9IGZyb20gXCIuL1BvdWNoUmVwb3NpdG9yeVwiO1xuaW1wb3J0IFBvdWNoREIgZnJvbSBcInBvdWNoZGItY29yZVwiO1xuaW1wb3J0ICogYXMgUG91Y2hNYXBSZWR1Y2UgZnJvbSBcInBvdWNoZGItbWFwcmVkdWNlXCI7XG5pbXBvcnQgKiBhcyBQb3VjaFJlcGxpY2F0aW9uIGZyb20gXCJwb3VjaGRiLXJlcGxpY2F0aW9uXCI7XG5pbXBvcnQgKiBhcyBQb3VjaEZpbmQgZnJvbSBcInBvdWNoZGItZmluZFwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBjcmVhdG9yIElEIG9uIGEgbW9kZWwgZHVyaW5nIGNyZWF0aW9uIG9yIHVwZGF0ZSBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgYXMgYSBkZWNvcmF0b3IgaGFuZGxlciB0byBhdXRvbWF0aWNhbGx5IHNldCB0aGUgY3JlYXRvciBJRCBmaWVsZCBvbiBhIG1vZGVsXG4gKiB3aGVuIGl0J3MgYmVpbmcgY3JlYXRlZCBvciB1cGRhdGVkLiBJdCBleHRyYWN0cyB0aGUgVVVJRCBmcm9tIHRoZSBjb250ZXh0IGFuZCBhc3NpZ25zIGl0IHRvIHRoZSBzcGVjaWZpZWQga2V5LlxuICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZSB0aGF0IGV4dGVuZHMgTW9kZWxcbiAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHJlcG9zaXRvcnkgdHlwZSB0aGF0IGV4dGVuZHMgUG91Y2hSZXBvc2l0b3J5PE0+XG4gKiBAdGVtcGxhdGUgViAtIFRoZSByZWxhdGlvbnMgbWV0YWRhdGEgdHlwZSB0aGF0IGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGFcbiAqIEBwYXJhbSB7Un0gdGhpcyAtIFRoZSByZXBvc2l0b3J5IGluc3RhbmNlXG4gKiBAcGFyYW0ge0NvbnRleHQ8UG91Y2hGbGFncz59IGNvbnRleHQgLSBUaGUgb3BlcmF0aW9uIGNvbnRleHQgY29udGFpbmluZyBmbGFnc1xuICogQHBhcmFtIHtWfSBkYXRhIC0gVGhlIHJlbGF0aW9ucyBtZXRhZGF0YVxuICogQHBhcmFtIGtleSAtIFRoZSBwcm9wZXJ0eSBrZXkgdG8gc2V0IG9uIHRoZSBtb2RlbFxuICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZSB0byBtb2RpZnlcbiAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIG9wZXJhdGlvbiBpcyBjb21wbGV0ZVxuICogQGZ1bmN0aW9uIGNyZWF0ZWRCeU9uUG91Y2hDcmVhdGVVcGRhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Zm9yLXBvdWNoXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVkQnlPblBvdWNoQ3JlYXRlVXBkYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBQb3VjaFJlcG9zaXRvcnk8TT4sXG4gIFYgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbj4oXG4gIHRoaXM6IFIsXG4gIGNvbnRleHQ6IENvbnRleHQ8UG91Y2hGbGFncz4sXG4gIGRhdGE6IFYsXG4gIGtleToga2V5b2YgTSxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHV1aWQ6IHN0cmluZyA9IGNvbnRleHQuZ2V0KFwiVVVJRFwiKTtcbiAgICBtb2RlbFtrZXldID0gdXVpZCBhcyBNW2tleW9mIE1dO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEVycm9yKFxuICAgICAgXCJObyBVc2VyIGZvdW5kIGluIGNvbnRleHQuIFBsZWFzZSBwcm92aWRlIGEgdXNlciBpbiB0aGUgY29udGV4dFwiXG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBQb3VjaERCIGltcGxlbWVudGF0aW9uIG9mIHRoZSBDb3VjaERCQWRhcHRlclxuICogQHN1bW1hcnkgQ29uY3JldGUgYWRhcHRlciB0aGF0IGJyaWRnZXMgdGhlIGdlbmVyaWMgQ291Y2hEQkFkYXB0ZXIgdG8gYSBQb3VjaERCIGJhY2tlbmQuIEl0IHN1cHBvcnRzIENSVUQgKHNpbmdsZSBhbmQgYnVsayksIGluZGV4aW5nIGFuZCBNYW5nbyBxdWVyaWVzLCBhbmQgd2lyZXMgZmxhdm91ci1zcGVjaWZpYyBkZWNvcmF0aW9ucy5cbiAqIEB0ZW1wbGF0ZSBQb3VjaEZsYWdzIC0gVGhlIGZsYWdzIHNwZWNpZmljIHRvIFBvdWNoREIgb3BlcmF0aW9uc1xuICogQHRlbXBsYXRlIENvbnRleHQ8UG91Y2hGbGFncz4gLSBUaGUgY29udGV4dCB0eXBlIHdpdGggUG91Y2hEQiBmbGFnc1xuICogQHBhcmFtIHtQb3VjaENvbmZpZ30gY29uZmlnIC0gQWRhcHRlciBjb25maWd1cmF0aW9uIChyZW1vdGUgY3JlZGVudGlhbHMgb3IgbG9jYWwgc3RvcmFnZSBwYXRoLCBkYiBuYW1lLCBwbHVnaW5zKVxuICogQHBhcmFtIHtzdHJpbmd9IFthbGlhc10gLSBPcHRpb25hbCBhbGlhcyBmb3IgdGhlIGRhdGFiYXNlXG4gKiBAY2xhc3MgUG91Y2hBZGFwdGVyXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgUG91Y2hBZGFwdGVyIH0gZnJvbSAnQGRlY2FmLXRzL2Zvci1wb3VjaCc7XG4gKlxuICogLy8gQ3JlYXRlIGEgUG91Y2hBZGFwdGVyIHdpdGggY29uZmlnXG4gKiBjb25zdCBhZGFwdGVyID0gbmV3IFBvdWNoQWRhcHRlcih7XG4gKiAgIHByb3RvY29sOiAnaHR0cCcsXG4gKiAgIGhvc3Q6ICdsb2NhbGhvc3Q6NTk4NCcsXG4gKiAgIHVzZXI6ICdhZG1pbicsXG4gKiAgIHBhc3N3b3JkOiAnc2VjcmV0JyxcbiAqICAgZGJOYW1lOiAnbXktZGF0YWJhc2UnLFxuICogICBwbHVnaW5zOiBbXVxuICogfSk7XG4gKlxuICogLy8gT3IgdXNlIGxvY2FsIHN0b3JhZ2VcbiAqIGNvbnN0IGxvY2FsQWRhcHRlciA9IG5ldyBQb3VjaEFkYXB0ZXIoe1xuICogICBwcm90b2NvbDogJ2h0dHAnLCAvLyBpZ25vcmVkIGZvciBsb2NhbFxuICogICBkYk5hbWU6ICdsb2NhbC1kYicsXG4gKiAgIHN0b3JhZ2VQYXRoOiAnbG9jYWxfZGJzJyxcbiAqICAgcGx1Z2luczogW11cbiAqIH0pO1xuICpcbiAqIC8vIFVzZSB0aGUgYWRhcHRlciBmb3IgZGF0YWJhc2Ugb3BlcmF0aW9uc1xuICogY29uc3QgcmVzdWx0ID0gYXdhaXQgYWRhcHRlci5yZWFkKCd1c2VycycsICd1c2VyLTEyMycpO1xuICogYGBgXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICogICBwYXJ0aWNpcGFudCBQb3VjaEFkYXB0ZXJcbiAqICAgcGFydGljaXBhbnQgUG91Y2hEQlxuICogICBwYXJ0aWNpcGFudCBDb3VjaERCXG4gKlxuICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IG5ldyBQb3VjaEFkYXB0ZXIoY29uZmlnLCBhbGlhcz8pXG4gKiAgIFBvdWNoQWRhcHRlci0+PkNvdWNoREJBZGFwdGVyOiBzdXBlcihjb25maWcsIFBvdWNoRmxhdm91ciwgYWxpYXMpXG4gKlxuICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IGNyZWF0ZSh0YWJsZSwgaWQsIG1vZGVsKVxuICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaERCOiBwdXQobW9kZWwpXG4gKiAgIFBvdWNoREItPj5Db3VjaERCOiBIVFRQIFBVVFxuICogICBDb3VjaERCLS0+PlBvdWNoREI6IFJlc3BvbnNlXG4gKiAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBSZXNwb25zZVxuICogICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBVcGRhdGVkIG1vZGVsXG4gKlxuICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IHJlYWQodGFibGUsIGlkKVxuICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaERCOiBnZXQoaWQpXG4gKiAgIFBvdWNoREItPj5Db3VjaERCOiBIVFRQIEdFVFxuICogICBDb3VjaERCLS0+PlBvdWNoREI6IERvY3VtZW50XG4gKiAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBEb2N1bWVudFxuICogICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBNb2RlbFxuICovXG5leHBvcnQgY2xhc3MgUG91Y2hBZGFwdGVyIGV4dGVuZHMgQ291Y2hEQkFkYXB0ZXI8XG4gIFBvdWNoQ29uZmlnLFxuICBEYXRhYmFzZSxcbiAgUG91Y2hGbGFncyxcbiAgQ29udGV4dDxQb3VjaEZsYWdzPlxuPiB7XG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogUG91Y2hDb25maWcsIGFsaWFzPzogc3RyaW5nKSB7XG4gICAgc3VwZXIoY29uZmlnLCBQb3VjaEZsYXZvdXIsIGFsaWFzKTtcbiAgfVxuXG4vKipcbiAgICogQGRlc2NyaXB0aW9uIExhemlseSBpbml0aWFsaXplcyBhbmQgcmV0dXJucyB0aGUgdW5kZXJseWluZyBQb3VjaERCIGNsaWVudFxuICAgKiBAc3VtbWFyeSBMb2FkcyByZXF1aXJlZCBQb3VjaERCIHBsdWdpbnMgb25jZSwgYnVpbGRzIHRoZSBjb25uZWN0aW9uIFVSTCBvciBsb2NhbCBzdG9yYWdlIHBhdGggZnJvbSBjb25maWcsIGFuZCBjYWNoZXMgdGhlIERhdGFiYXNlIGluc3RhbmNlIGZvciByZXVzZS4gVGhyb3dzIEludGVybmFsRXJyb3IgaWYgY2xpZW50IGNyZWF0aW9uIGZhaWxzLlxuICAgKiBAcmV0dXJuIHtEYXRhYmFzZX0gQSBQb3VjaERCIERhdGFiYXNlIGluc3RhbmNlIHJlYWR5IHRvIHBlcmZvcm0gb3BlcmF0aW9uc1xuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaEFkYXB0ZXJcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaERCXG4gICAqICAgQ2FsbGVyLT4+UG91Y2hBZGFwdGVyOiBnZXRDbGllbnQoKVxuICAgKiAgIGFsdCBjbGllbnQgbm90IGluaXRpYWxpemVkXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IHJlZ2lzdGVyIHBsdWdpbnNcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoREI6IG5ldyBQb3VjaERCKHVybCBvciBwYXRoKVxuICAgKiAgICAgYWx0IGNyZWF0aW9uIGZhaWxzXG4gICAqICAgICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBFcnJvclxuICAgKiAgICAgICBQb3VjaEFkYXB0ZXItLT4+Q2FsbGVyOiB0aHJvd3MgSW50ZXJuYWxFcnJvclxuICAgKiAgICAgZWxzZSBzdWNjZXNzXG4gICAqICAgICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBEYXRhYmFzZVxuICAgKiAgICAgICBQb3VjaEFkYXB0ZXItLT4+Q2FsbGVyOiBjYWNoZWQgY2xpZW50XG4gICAqICAgICBlbmRcbiAgICogICBlbHNlIGNsaWVudCBpbml0aWFsaXplZFxuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogY2FjaGVkIGNsaWVudFxuICAgKiAgIGVuZFxuICAgKi9cbiAgb3ZlcnJpZGUgZ2V0Q2xpZW50KCk6IERhdGFiYXNlIHtcbiAgICBpZiAoIXRoaXMuX2NsaWVudCkge1xuICAgICAgY29uc3QgcGx1Z2lucyA9IFtcbiAgICAgICAgUG91Y2hNYXBSZWR1Y2UsXG4gICAgICAgIFBvdWNoUmVwbGljYXRpb24sXG4gICAgICAgIFBvdWNoRmluZCxcbiAgICAgICAgLi4udGhpcy5jb25maWcucGx1Z2lucyxcbiAgICAgIF07XG4gICAgICBmb3IgKGNvbnN0IHBsdWdpbiBvZiBwbHVnaW5zKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgUG91Y2hEQi5wbHVnaW4ocGx1Z2luKTtcbiAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvciAmJiBlLm1lc3NhZ2UuaW5jbHVkZXMoXCJyZWRlZmluZSBwcm9wZXJ0eVwiKSlcbiAgICAgICAgICAgIGNvbnRpbnVlOyAvL3BsdWdpbiBoYXMgYWxyZWFkeSBiZWVuIGxvYWRlZCBzbyBpdCdzIG9rXG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCB7IGhvc3QsIHByb3RvY29sLCB1c2VyLCBwYXNzd29yZCwgZGJOYW1lLCBzdG9yYWdlUGF0aCB9ID1cbiAgICAgICAgdGhpcy5jb25maWc7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGlmIChob3N0ICYmIHVzZXIpIHtcbiAgICAgICAgICB0aGlzLl9jbGllbnQgPSBuZXcgUG91Y2hEQihcbiAgICAgICAgICAgIGAke3Byb3RvY29sfTovLyR7dXNlcn06JHtwYXNzd29yZH1AJHtob3N0fS8ke2RiTmFtZX1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlXG4gICAgICAgICAgdGhpcy5fY2xpZW50ID0gbmV3IFBvdWNoREIoXG4gICAgICAgICAgICBgJHtzdG9yYWdlUGF0aCB8fCBEZWZhdWx0TG9jYWxTdG9yYWdlUGF0aH0vJHtkYk5hbWV9YFxuICAgICAgICAgICk7XG4gICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBGYWlsZWQgdG8gY3JlYXRlIFBvdWNoREIgY2xpZW50OiAke2V9YCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jbGllbnQgYXMgRGF0YWJhc2U7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdlbmVyYXRlcyBvcGVyYXRpb24gZmxhZ3MgZm9yIFBvdWNoREIgb3BlcmF0aW9uc1xuICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgc2V0IG9mIGZsYWdzIGZvciBhIHNwZWNpZmljIG9wZXJhdGlvbiwgaW5jbHVkaW5nIGEgVVVJRCBmb3IgaWRlbnRpZmljYXRpb24uXG4gICAqIFRoaXMgbWV0aG9kIGV4dHJhY3RzIHRoZSB1c2VyIElEIGZyb20gdGhlIGRhdGFiYXNlIFVSTCBvciBnZW5lcmF0ZXMgYSByYW5kb20gVVVJRCBpZiBub3QgYXZhaWxhYmxlLlxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoYXQgZXh0ZW5kcyBNb2RlbFxuICAgKiBAcGFyYW0ge09wZXJhdGlvbktleXN9IG9wZXJhdGlvbiAtIFRoZSBvcGVyYXRpb24ga2V5IChjcmVhdGUsIHJlYWQsIHVwZGF0ZSwgZGVsZXRlKVxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBtb2RlbCAtIFRoZSBtb2RlbCBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge1BhcnRpYWw8UG91Y2hGbGFncz59IGZsYWdzIC0gUGFydGlhbCBmbGFncyB0byBiZSBtZXJnZWRcbiAgICogQHJldHVybiB7UHJvbWlzZTxQb3VjaEZsYWdzPn0gVGhlIGNvbXBsZXRlIHNldCBvZiBmbGFncyBmb3IgdGhlIG9wZXJhdGlvblxuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGFzeW5jIGZsYWdzPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgb3BlcmF0aW9uOiBPcGVyYXRpb25LZXlzLFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPixcbiAgICBmbGFnczogUGFydGlhbDxQb3VjaEZsYWdzPlxuICApOiBQcm9taXNlPFBvdWNoRmxhZ3M+IHtcbiAgICBpZiAoIXRoaXMuY29uZmlnLnVzZXIpIHRoaXMuY29uZmlnLnVzZXIgPSBjcnlwdG8ucmFuZG9tVVVJRCgpO1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKGF3YWl0IHN1cGVyLmZsYWdzKG9wZXJhdGlvbiwgbW9kZWwsIGZsYWdzKSwge1xuICAgICAgVVVJRDogdGhpcy5jb25maWcudXNlcixcbiAgICB9KSBhcyBQb3VjaEZsYWdzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGRhdGFiYXNlIGluZGV4ZXMgZm9yIHRoZSBnaXZlbiBtb2RlbHNcbiAgICogQHN1bW1hcnkgR2VuZXJhdGVzIGFuZCBjcmVhdGVzIGluZGV4ZXMgaW4gdGhlIFBvdWNoREIgZGF0YWJhc2UgYmFzZWQgb24gdGhlIHByb3ZpZGVkIG1vZGVsIGNvbnN0cnVjdG9ycy5cbiAgICogVGhpcyBtZXRob2QgdXNlcyB0aGUgZ2VuZXJhdGVJbmRleGVzIHV0aWxpdHkgdG8gY3JlYXRlIGluZGV4IGRlZmluaXRpb25zIGFuZCB0aGVuIGNyZWF0ZXMgdGhlbSBpbiB0aGUgZGF0YWJhc2UuXG4gICAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgdGhhdCBleHRlbmRzIE1vZGVsXG4gICAqIEBwYXJhbSBtb2RlbHMgLSBUaGUgbW9kZWwgY29uc3RydWN0b3JzIHRvIGNyZWF0ZSBpbmRleGVzIGZvclxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCBpbmRleGVzIGFyZSBjcmVhdGVkXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgaW5kZXg8TSBleHRlbmRzIE1vZGVsPihcbiAgICAuLi5tb2RlbHM6IENvbnN0cnVjdG9yPE0+W11cbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgaW5kZXhlczogQ3JlYXRlSW5kZXhSZXF1ZXN0W10gPSBnZW5lcmF0ZUluZGV4ZXMobW9kZWxzKTtcbiAgICBmb3IgKGNvbnN0IGluZGV4IG9mIGluZGV4ZXMpIHtcbiAgICAgIGNvbnN0IHJlczogQ3JlYXRlSW5kZXhSZXNwb25zZTxhbnk+ID0gYXdhaXQgdGhpcy5jbGllbnQuY3JlYXRlSW5kZXgoXG4gICAgICAgIGluZGV4IGFzIGFueVxuICAgICAgKTtcbiAgICAgIGNvbnN0IHsgcmVzdWx0IH0gPSByZXM7XG4gICAgICBpZiAocmVzdWx0ID09PSBcImV4aXN0aW5nXCIpXG4gICAgICAgIHRocm93IG5ldyBDb25mbGljdEVycm9yKGBJbmRleCAke2luZGV4Lm5hbWV9IGFscmVhZHkgZXhpc3RzYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmV3IGRvY3VtZW50IGluIHRoZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBJbnNlcnRzIGEgbmV3IGRvY3VtZW50IGludG8gdGhlIFBvdWNoREIgZGF0YWJhc2UgdXNpbmcgdGhlIHB1dCBvcGVyYXRpb24uXG4gICAqIFRoaXMgbWV0aG9kIGhhbmRsZXMgZXJyb3IgcGFyc2luZyBhbmQgZW5zdXJlcyB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlL2NvbGxlY3Rpb25cbiAgICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBpZCAtIFRoZSBkb2N1bWVudCBJRFxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG1vZGVsIC0gVGhlIGRvY3VtZW50IGRhdGEgdG8gaW5zZXJ0XG4gICAqIEByZXR1cm4ge1Byb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBjcmVhdGVkIGRvY3VtZW50IHdpdGggbWV0YWRhdGFcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hBZGFwdGVyXG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hEQlxuICAgKlxuICAgKiAgIENsaWVudC0+PlBvdWNoQWRhcHRlcjogY3JlYXRlKHRhYmxlTmFtZSwgaWQsIG1vZGVsKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PlBvdWNoREI6IHB1dChtb2RlbClcbiAgICogICBhbHQgU3VjY2Vzc1xuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IFJlc3BvbnNlIHdpdGggb2s9dHJ1ZVxuICAgKiAgICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBhc3NpZ25NZXRhZGF0YShtb2RlbCwgcmVzcG9uc2UucmV2KVxuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogVXBkYXRlZCBtb2RlbCB3aXRoIG1ldGFkYXRhXG4gICAqICAgZWxzZSBFcnJvclxuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IEVycm9yXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IHBhcnNlRXJyb3IoZSlcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IFRocm93cyBlcnJvclxuICAgKiAgIGVuZFxuICAgKi9cbiAgYXN5bmMgY3JlYXRlKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIsXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gICAgbGV0IHJlc3BvbnNlOiBSZXNwb25zZTtcbiAgICB0cnkge1xuICAgICAgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmNsaWVudC5wdXQobW9kZWwpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IHRoaXMucGFyc2VFcnJvcihlIGFzIEVycm9yKTtcbiAgICB9XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gaW5zZXJ0IGRvYyBpZDogJHtpZH0gaW4gdGFibGUgJHt0YWJsZU5hbWV9YFxuICAgICAgKTtcbiAgICByZXR1cm4gdGhpcy5hc3NpZ25NZXRhZGF0YShtb2RlbCwgcmVzcG9uc2UucmV2KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBtdWx0aXBsZSBkb2N1bWVudHMgaW4gdGhlIGRhdGFiYXNlIGluIGEgc2luZ2xlIG9wZXJhdGlvblxuICAgKiBAc3VtbWFyeSBJbnNlcnRzIG11bHRpcGxlIGRvY3VtZW50cyBpbnRvIHRoZSBQb3VjaERCIGRhdGFiYXNlIHVzaW5nIHRoZSBidWxrRG9jcyBvcGVyYXRpb24uXG4gICAqIFRoaXMgbWV0aG9kIGhhbmRsZXMgZXJyb3IgcGFyc2luZyBhbmQgZW5zdXJlcyBhbGwgb3BlcmF0aW9ucyB3ZXJlIHN1Y2Nlc3NmdWwuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUvY29sbGVjdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfG51bWJlcltdfSBpZHMgLSBUaGUgZG9jdW1lbnQgSURzXG4gICAqIEBwYXJhbSAgbW9kZWxzIC0gVGhlIGRvY3VtZW50IGRhdGEgdG8gaW5zZXJ0XG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGNyZWF0ZWQgZG9jdW1lbnRzIHdpdGggbWV0YWRhdGFcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hBZGFwdGVyXG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hEQlxuICAgKlxuICAgKiAgIENsaWVudC0+PlBvdWNoQWRhcHRlcjogY3JlYXRlQWxsKHRhYmxlTmFtZSwgaWRzLCBtb2RlbHMpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogYnVsa0RvY3MobW9kZWxzKVxuICAgKiAgIGFsdCBTdWNjZXNzXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogQXJyYXkgb2YgcmVzcG9uc2VzIHdpdGggb2s9dHJ1ZVxuICAgKiAgICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBhc3NpZ25NdWx0aXBsZU1ldGFkYXRhKG1vZGVscywgcmV2cylcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IFVwZGF0ZWQgbW9kZWxzIHdpdGggbWV0YWRhdGFcbiAgICogICBlbHNlIEVycm9yXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogQXJyYXkgd2l0aCBlcnJvcnNcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogQ2hlY2sgZm9yIGVycm9yc1xuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogVGhyb3dzIEludGVybmFsRXJyb3JcbiAgICogICBlbmRcbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIGNyZWF0ZUFsbChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZHM6IHN0cmluZ1tdIHwgbnVtYmVyW10sXG4gICAgbW9kZWxzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBsZXQgcmVzcG9uc2U6IFJlc3BvbnNlW10gfCBFcnJbXTtcbiAgICB0cnkge1xuICAgICAgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmNsaWVudC5idWxrRG9jcyhtb2RlbHMpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgUG91Y2hBZGFwdGVyLnBhcnNlRXJyb3IoZSk7XG4gICAgfVxuICAgIGlmICghcmVzcG9uc2UuZXZlcnkoKHI6IFJlc3BvbnNlIHwgRXJyKSA9PiAociBhcyBSZXNwb25zZSkub2spKSB7XG4gICAgICBjb25zdCBlcnJvcnMgPSByZXNwb25zZS5yZWR1Y2UoKGFjY3VtOiBzdHJpbmdbXSwgZWwsIGkpID0+IHtcbiAgICAgICAgaWYgKGVsLmVycm9yKVxuICAgICAgICAgIGFjY3VtLnB1c2goXG4gICAgICAgICAgICBgZWwgJHtpfTogJHtlbC5lcnJvcn0ke2VsLnJlYXNvbiA/IGAgLSAke2VsLnJlYXNvbn1gIDogXCJcIn1gXG4gICAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSwgW10pO1xuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoZXJyb3JzLmpvaW4oXCJcXG5cIikpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmFzc2lnbk11bHRpcGxlTWV0YWRhdGEoXG4gICAgICBtb2RlbHMsXG4gICAgICByZXNwb25zZS5tYXAoKHIpID0+IHIucmV2IGFzIHN0cmluZylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYSBkb2N1bWVudCBmcm9tIHRoZSBkYXRhYmFzZSBieSBJRFxuICAgKiBAc3VtbWFyeSBGZXRjaGVzIGEgZG9jdW1lbnQgZnJvbSB0aGUgUG91Y2hEQiBkYXRhYmFzZSB1c2luZyB0aGUgZ2V0IG9wZXJhdGlvbi5cbiAgICogVGhpcyBtZXRob2QgZ2VuZXJhdGVzIHRoZSBkb2N1bWVudCBJRCBiYXNlZCBvbiB0aGUgdGFibGUgbmFtZSBhbmQgSUQsIHRoZW4gcmV0cmlldmVzIHRoZSBkb2N1bWVudC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gaWQgLSBUaGUgZG9jdW1lbnQgSURcbiAgICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHJldHJpZXZlZCBkb2N1bWVudCB3aXRoIG1ldGFkYXRhXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoREJcbiAgICpcbiAgICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IHJlYWQodGFibGVOYW1lLCBpZClcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IGdlbmVyYXRlSWQodGFibGVOYW1lLCBpZClcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaERCOiBnZXQoX2lkKVxuICAgKiAgIGFsdCBTdWNjZXNzXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogRG9jdW1lbnRcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogYXNzaWduTWV0YWRhdGEocmVjb3JkLCByZWNvcmQuX3JldilcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IERvY3VtZW50IHdpdGggbWV0YWRhdGFcbiAgICogICBlbHNlIEVycm9yXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogRXJyb3JcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogcGFyc2VFcnJvcihlKVxuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogVGhyb3dzIGVycm9yXG4gICAqICAgZW5kXG4gICAqL1xuICBhc3luYyByZWFkKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXJcbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gICAgY29uc3QgX2lkID0gdGhpcy5nZW5lcmF0ZUlkKHRhYmxlTmFtZSwgaWQpO1xuICAgIGxldCByZWNvcmQ6IElkTWV0YSAmIEdldE1ldGE7XG4gICAgdHJ5IHtcbiAgICAgIHJlY29yZCA9IGF3YWl0IHRoaXMuY2xpZW50LmdldChfaWQpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgUG91Y2hBZGFwdGVyLnBhcnNlRXJyb3IoZSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFzc2lnbk1ldGFkYXRhKHJlY29yZCwgcmVjb3JkLl9yZXYpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgbXVsdGlwbGUgZG9jdW1lbnRzIGZyb20gdGhlIGRhdGFiYXNlIGJ5IHRoZWlyIElEc1xuICAgKiBAc3VtbWFyeSBGZXRjaGVzIG11bHRpcGxlIGRvY3VtZW50cyBmcm9tIHRoZSBQb3VjaERCIGRhdGFiYXNlIHVzaW5nIHRoZSBidWxrR2V0IG9wZXJhdGlvbi5cbiAgICogVGhpcyBtZXRob2QgZ2VuZXJhdGVzIGRvY3VtZW50IElEcyBiYXNlZCBvbiB0aGUgdGFibGUgbmFtZSBhbmQgSURzLCB0aGVuIHJldHJpZXZlcyB0aGUgZG9jdW1lbnRzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlL2NvbGxlY3Rpb25cbiAgICogQHBhcmFtIHtBcnJheTxzdHJpbmd8bnVtYmVyfGJpZ2ludD59IGlkcyAtIFRoZSBkb2N1bWVudCBJRHNcbiAgICogQHJldHVybiBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgcmV0cmlldmVkIGRvY3VtZW50cyB3aXRoIG1ldGFkYXRhXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoREJcbiAgICpcbiAgICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IHJlYWRBbGwodGFibGVOYW1lLCBpZHMpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBNYXAgaWRzIHRvIGdlbmVyYXRlSWQodGFibGVOYW1lLCBpZClcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaERCOiBidWxrR2V0KHtkb2NzfSlcbiAgICogICBhbHQgU3VjY2Vzc1xuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IEJ1bGtHZXRSZXNwb25zZVxuICAgKiAgICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBQcm9jZXNzIHJlc3VsdHNcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogYXNzaWduTWV0YWRhdGEgZm9yIGVhY2ggZG9jXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBEb2N1bWVudHMgd2l0aCBtZXRhZGF0YVxuICAgKiAgIGVsc2UgRXJyb3JcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogcGFyc2VFcnJvcihlcnJvcilcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IFRocm93cyBlcnJvclxuICAgKiAgIGVuZFxuICAgKi9cbiAgb3ZlcnJpZGUgYXN5bmMgcmVhZEFsbChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZHM6IChzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQpW11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBjb25zdCByZXN1bHRzOiBCdWxrR2V0UmVzcG9uc2U8YW55PiA9IGF3YWl0IHRoaXMuY2xpZW50LmJ1bGtHZXQoe1xuICAgICAgZG9jczogaWRzLm1hcCgoaWQpID0+ICh7IGlkOiB0aGlzLmdlbmVyYXRlSWQodGFibGVOYW1lLCBpZCBhcyBhbnkpIH0pKSxcbiAgICB9KTtcbiAgICBjb25zdCByZXMgPSByZXN1bHRzLnJlc3VsdHMucmVkdWNlKChhY2N1bTogYW55W10sIHIpID0+IHtcbiAgICAgIHIuZG9jcy5mb3JFYWNoKChkKSA9PiB7XG4gICAgICAgIGlmICgoZCBhcyBhbnkpLmVycm9yIHx8ICEoZCBhcyBhbnkpLm9rKVxuICAgICAgICAgIHRocm93IFBvdWNoQWRhcHRlci5wYXJzZUVycm9yKFxuICAgICAgICAgICAgKChkIGFzIHsgZXJyb3I6IEVyciB9KS5lcnJvciBhcyBFcnJvcikgfHxcbiAgICAgICAgICAgICAgbmV3IEludGVybmFsRXJyb3IoXCJNaXNzaW5nIHZhbGlkIHJlc3BvbnNlXCIpXG4gICAgICAgICAgKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gT2JqZWN0LmFzc2lnbih7fSwgKGQgYXMgeyBvazogYW55IH0pLm9rKTtcbiAgICAgICAgYWNjdW0ucHVzaCh0aGlzLmFzc2lnbk1ldGFkYXRhKHJlc3VsdCwgKGQgYXMgYW55KS5va1tDb3VjaERCS2V5cy5SRVZdKSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBhY2N1bTtcbiAgICB9LCBbXSk7XG5cbiAgICByZXR1cm4gcmVzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBVcGRhdGVzIGFuIGV4aXN0aW5nIGRvY3VtZW50IGluIHRoZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBVcGRhdGVzIGEgZG9jdW1lbnQgaW4gdGhlIFBvdWNoREIgZGF0YWJhc2UgdXNpbmcgdGhlIHB1dCBvcGVyYXRpb24uXG4gICAqIFRoaXMgbWV0aG9kIGhhbmRsZXMgZXJyb3IgcGFyc2luZyBhbmQgZW5zdXJlcyB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlL2NvbGxlY3Rpb25cbiAgICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBpZCAtIFRoZSBkb2N1bWVudCBJRFxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG1vZGVsIC0gVGhlIHVwZGF0ZWQgZG9jdW1lbnQgZGF0YVxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgdXBkYXRlZCBkb2N1bWVudCB3aXRoIG1ldGFkYXRhXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoREJcbiAgICpcbiAgICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IHVwZGF0ZSh0YWJsZU5hbWUsIGlkLCBtb2RlbClcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaERCOiBwdXQobW9kZWwpXG4gICAqICAgYWx0IFN1Y2Nlc3NcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBSZXNwb25zZSB3aXRoIG9rPXRydWVcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogYXNzaWduTWV0YWRhdGEobW9kZWwsIHJlc3BvbnNlLnJldilcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IFVwZGF0ZWQgbW9kZWwgd2l0aCBtZXRhZGF0YVxuICAgKiAgIGVsc2UgRXJyb3JcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBFcnJvclxuICAgKiAgICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBwYXJzZUVycm9yKGUpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBUaHJvd3MgZXJyb3JcbiAgICogICBlbmRcbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIHVwZGF0ZShcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICAgIGxldCByZXNwb25zZTogUmVzcG9uc2U7XG4gICAgdHJ5IHtcbiAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy5jbGllbnQucHV0KG1vZGVsKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IFBvdWNoQWRhcHRlci5wYXJzZUVycm9yKGUpO1xuICAgIH1cblxuICAgIGlmICghcmVzcG9uc2Uub2spXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byB1cGRhdGUgZG9jIGlkOiAke2lkfSBpbiB0YWJsZSAke3RhYmxlTmFtZX1gXG4gICAgICApO1xuICAgIHJldHVybiB0aGlzLmFzc2lnbk1ldGFkYXRhKG1vZGVsLCByZXNwb25zZS5yZXYpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBVcGRhdGVzIG11bHRpcGxlIGRvY3VtZW50cyBpbiB0aGUgZGF0YWJhc2UgaW4gYSBzaW5nbGUgb3BlcmF0aW9uXG4gICAqIEBzdW1tYXJ5IFVwZGF0ZXMgbXVsdGlwbGUgZG9jdW1lbnRzIGluIHRoZSBQb3VjaERCIGRhdGFiYXNlIHVzaW5nIHRoZSBidWxrRG9jcyBvcGVyYXRpb24uXG4gICAqIFRoaXMgbWV0aG9kIGhhbmRsZXMgZXJyb3IgcGFyc2luZyBhbmQgZW5zdXJlcyBhbGwgb3BlcmF0aW9ucyB3ZXJlIHN1Y2Nlc3NmdWwuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUvY29sbGVjdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfG51bWJlcltdfSBpZHMgLSBUaGUgZG9jdW1lbnQgSURzXG4gICAqIEBwYXJhbSBtb2RlbHMgLSBUaGUgdXBkYXRlZCBkb2N1bWVudCBkYXRhXG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHVwZGF0ZWQgZG9jdW1lbnRzIHdpdGggbWV0YWRhdGFcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hBZGFwdGVyXG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hEQlxuICAgKlxuICAgKiAgIENsaWVudC0+PlBvdWNoQWRhcHRlcjogdXBkYXRlQWxsKHRhYmxlTmFtZSwgaWRzLCBtb2RlbHMpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogYnVsa0RvY3MobW9kZWxzKVxuICAgKiAgIGFsdCBTdWNjZXNzXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogQXJyYXkgb2YgcmVzcG9uc2VzIHdpdGggb2s9dHJ1ZVxuICAgKiAgICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBhc3NpZ25NdWx0aXBsZU1ldGFkYXRhKG1vZGVscywgcmV2cylcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IFVwZGF0ZWQgbW9kZWxzIHdpdGggbWV0YWRhdGFcbiAgICogICBlbHNlIEVycm9yXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogQXJyYXkgd2l0aCBlcnJvcnNcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogQ2hlY2sgZm9yIGVycm9yc1xuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogVGhyb3dzIEludGVybmFsRXJyb3JcbiAgICogICBlbmRcbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIHVwZGF0ZUFsbChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZHM6IHN0cmluZ1tdIHwgbnVtYmVyW10sXG4gICAgbW9kZWxzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBsZXQgcmVzcG9uc2U6IChSZXNwb25zZSB8IEVycilbXTtcbiAgICB0cnkge1xuICAgICAgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmNsaWVudC5idWxrRG9jcyhtb2RlbHMpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgUG91Y2hBZGFwdGVyLnBhcnNlRXJyb3IoZSk7XG4gICAgfVxuICAgIGlmICghcmVzcG9uc2UuZXZlcnkoKHIpID0+ICEociBhcyBhbnkpLmVycm9yKSkge1xuICAgICAgY29uc3QgZXJyb3JzID0gcmVzcG9uc2UucmVkdWNlKChhY2N1bTogc3RyaW5nW10sIGVsLCBpKSA9PiB7XG4gICAgICAgIGlmICgoZWwgYXMgYW55KS5lcnJvcilcbiAgICAgICAgICBhY2N1bS5wdXNoKFxuICAgICAgICAgICAgYGVsICR7aX06ICR7KGVsIGFzIGFueSkuZXJyb3J9JHsoZWwgYXMgYW55KS5yZWFzb24gPyBgIC0gJHsoZWwgYXMgYW55KS5yZWFzb259YCA6IFwiXCJ9YFxuICAgICAgICAgICk7XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0sIFtdKTtcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGVycm9ycy5qb2luKFwiXFxuXCIpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5hc3NpZ25NdWx0aXBsZU1ldGFkYXRhKFxuICAgICAgbW9kZWxzLFxuICAgICAgcmVzcG9uc2UubWFwKChyKSA9PiByLnJldiBhcyBzdHJpbmcpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRGVsZXRlcyBhIGRvY3VtZW50IGZyb20gdGhlIGRhdGFiYXNlIGJ5IElEXG4gICAqIEBzdW1tYXJ5IFJlbW92ZXMgYSBkb2N1bWVudCBmcm9tIHRoZSBQb3VjaERCIGRhdGFiYXNlIHVzaW5nIHRoZSByZW1vdmUgb3BlcmF0aW9uLlxuICAgKiBUaGlzIG1ldGhvZCBmaXJzdCByZXRyaWV2ZXMgdGhlIGRvY3VtZW50IHRvIGdldCBpdHMgcmV2aXNpb24sIHRoZW4gZGVsZXRlcyBpdC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gaWQgLSBUaGUgZG9jdW1lbnQgSURcbiAgICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGRlbGV0ZWQgZG9jdW1lbnQgd2l0aCBtZXRhZGF0YVxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaEFkYXB0ZXJcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaERCXG4gICAqXG4gICAqICAgQ2xpZW50LT4+UG91Y2hBZGFwdGVyOiBkZWxldGUodGFibGVOYW1lLCBpZClcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IGdlbmVyYXRlSWQodGFibGVOYW1lLCBpZClcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaERCOiBnZXQoX2lkKVxuICAgKiAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBEb2N1bWVudCB3aXRoIF9yZXZcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaERCOiByZW1vdmUoX2lkLCByZWNvcmQuX3JldilcbiAgICogICBhbHQgU3VjY2Vzc1xuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IFN1Y2Nlc3MgcmVzcG9uc2VcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogYXNzaWduTWV0YWRhdGEocmVjb3JkLCByZWNvcmQuX3JldilcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IERlbGV0ZWQgZG9jdW1lbnQgd2l0aCBtZXRhZGF0YVxuICAgKiAgIGVsc2UgRXJyb3JcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBFcnJvclxuICAgKiAgICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBwYXJzZUVycm9yKGUpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBUaHJvd3MgZXJyb3JcbiAgICogICBlbmRcbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIGRlbGV0ZShcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICAgIGNvbnN0IF9pZCA9IHRoaXMuZ2VuZXJhdGVJZCh0YWJsZU5hbWUsIGlkKTtcbiAgICBsZXQgcmVjb3JkOiBJZE1ldGEgJiBHZXRNZXRhO1xuICAgIHRyeSB7XG4gICAgICByZWNvcmQgPSBhd2FpdCB0aGlzLmNsaWVudC5nZXQoX2lkKTtcbiAgICAgIGF3YWl0IHRoaXMuY2xpZW50LnJlbW92ZShfaWQsIHJlY29yZC5fcmV2KTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IFBvdWNoQWRhcHRlci5wYXJzZUVycm9yKGUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5hc3NpZ25NZXRhZGF0YShyZWNvcmQsIHJlY29yZC5fcmV2KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRGVsZXRlcyBtdWx0aXBsZSBkb2N1bWVudHMgZnJvbSB0aGUgZGF0YWJhc2UgYnkgdGhlaXIgSURzXG4gICAqIEBzdW1tYXJ5IFJlbW92ZXMgbXVsdGlwbGUgZG9jdW1lbnRzIGZyb20gdGhlIFBvdWNoREIgZGF0YWJhc2UgaW4gYSBzaW5nbGUgb3BlcmF0aW9uLlxuICAgKiBUaGlzIG1ldGhvZCBmaXJzdCByZXRyaWV2ZXMgYWxsIGRvY3VtZW50cyB0byBnZXQgdGhlaXIgcmV2aXNpb25zLCB0aGVuIG1hcmtzIHRoZW0gYXMgZGVsZXRlZC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nfG51bWJlcnxiaWdpbnQ+fSBpZHMgLSBUaGUgZG9jdW1lbnQgSURzXG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGRlbGV0ZWQgZG9jdW1lbnRzIHdpdGggbWV0YWRhdGFcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hBZGFwdGVyXG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hEQlxuICAgKlxuICAgKiAgIENsaWVudC0+PlBvdWNoQWRhcHRlcjogZGVsZXRlQWxsKHRhYmxlTmFtZSwgaWRzKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogTWFwIGlkcyB0byBnZW5lcmF0ZUlkKHRhYmxlTmFtZSwgaWQpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogYnVsa0dldCh7ZG9jc30pXG4gICAqICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IEJ1bGtHZXRSZXNwb25zZSB3aXRoIGRvY3VtZW50c1xuICAgKiAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogTWFyayBkb2N1bWVudHMgYXMgZGVsZXRlZFxuICAgKiAgIFBvdWNoQWRhcHRlci0+PlBvdWNoREI6IGJ1bGtEb2NzKG1hcmtlZCBkb2N1bWVudHMpXG4gICAqICAgYWx0IFN1Y2Nlc3NcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBTdWNjZXNzIHJlc3BvbnNlc1xuICAgKiAgICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBQcm9jZXNzIHJlc3VsdHNcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogYXNzaWduTWV0YWRhdGEgZm9yIGVhY2ggZG9jXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBEZWxldGVkIGRvY3VtZW50cyB3aXRoIG1ldGFkYXRhXG4gICAqICAgZWxzZSBFcnJvclxuICAgKiAgICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBDaGVjayBmb3IgZXJyb3JzXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBUaHJvd3MgSW50ZXJuYWxFcnJvclxuICAgKiAgIGVuZFxuICAgKi9cbiAgb3ZlcnJpZGUgYXN5bmMgZGVsZXRlQWxsKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkczogKHN0cmluZyB8IG51bWJlciB8IGJpZ2ludClbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT5bXT4ge1xuICAgIGNvbnN0IHJlc3VsdHM6IEJ1bGtHZXRSZXNwb25zZTxhbnk+ID0gYXdhaXQgdGhpcy5jbGllbnQuYnVsa0dldCh7XG4gICAgICBkb2NzOiBpZHMubWFwKChpZCkgPT4gKHsgaWQ6IHRoaXMuZ2VuZXJhdGVJZCh0YWJsZU5hbWUsIGlkIGFzIGFueSkgfSkpLFxuICAgIH0pO1xuXG4gICAgY29uc3QgZGVsZXRpb246IChSZXNwb25zZSB8IEVycilbXSA9IGF3YWl0IHRoaXMuY2xpZW50LmJ1bGtEb2NzKFxuICAgICAgcmVzdWx0cy5yZXN1bHRzLm1hcCgocikgPT4ge1xuICAgICAgICAociBhcyBhbnkpW0NvdWNoREJLZXlzLkRFTEVURURdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHI7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICBjb25zdCBlcnJzID0gZGVsZXRpb24uZmlsdGVyKChkKSA9PiAoZCBhcyBhbnkpLmVycm9yKTtcbiAgICBpZiAoZXJycy5sZW5ndGgpIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGVycnMuam9pbihcIlxcblwiKSk7XG5cbiAgICByZXR1cm4gcmVzdWx0cy5yZXN1bHRzLnJlZHVjZSgoYWNjdW06IGFueVtdLCByKSA9PiB7XG4gICAgICByLmRvY3MuZm9yRWFjaCgoZCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBPYmplY3QuYXNzaWduKHt9LCAoZCBhcyB7IG9rOiBhbnkgfSkub2spO1xuICAgICAgICBhY2N1bS5wdXNoKHRoaXMuYXNzaWduTWV0YWRhdGEocmVzdWx0LCAoZCBhcyBhbnkpLm9rW0NvdWNoREJLZXlzLlJFVl0pKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGFjY3VtO1xuICAgIH0sIFtdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRXhlY3V0ZXMgYSByYXcgTWFuZ28gcXVlcnkgYWdhaW5zdCB0aGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgUGVyZm9ybXMgYSBkaXJlY3QgZmluZCBvcGVyYXRpb24gdXNpbmcgYSBNYW5nbyBxdWVyeSBvYmplY3QuXG4gICAqIFRoaXMgbWV0aG9kIGFsbG93cyBmb3IgY29tcGxleCBxdWVyaWVzIGJleW9uZCB0aGUgc3RhbmRhcmQgQ1JVRCBvcGVyYXRpb25zLlxuICAgKiBAdGVtcGxhdGUgViAtIFRoZSByZXR1cm4gdHlwZVxuICAgKiBAcGFyYW0ge01hbmdvUXVlcnl9IHJhd0lucHV0IC0gVGhlIE1hbmdvIHF1ZXJ5IHRvIGV4ZWN1dGVcbiAgICogQHBhcmFtIHtib29sZWFufSBbcHJvY2Vzcz10cnVlXSAtIFdoZXRoZXIgdG8gcHJvY2VzcyB0aGUgcmVzcG9uc2UgKHRydWUgcmV0dXJucyBqdXN0IGRvY3MsIGZhbHNlIHJldHVybnMgZnVsbCByZXNwb25zZSlcbiAgICogQHJldHVybiB7UHJvbWlzZTxWPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHF1ZXJ5IHJlc3VsdHNcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hBZGFwdGVyXG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hEQlxuICAgKlxuICAgKiAgIENsaWVudC0+PlBvdWNoQWRhcHRlcjogcmF3PFY+KHJhd0lucHV0LCBwcm9jZXNzKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PlBvdWNoREI6IGZpbmQocmF3SW5wdXQpXG4gICAqICAgYWx0IFN1Y2Nlc3NcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBGaW5kUmVzcG9uc2VcbiAgICogICAgIGFsdCBwcm9jZXNzPXRydWVcbiAgICogICAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogcmVzcG9uc2UuZG9jcyBhcyBWXG4gICAqICAgICBlbHNlIHByb2Nlc3M9ZmFsc2VcbiAgICogICAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogcmVzcG9uc2UgYXMgVlxuICAgKiAgICAgZW5kXG4gICAqICAgZWxzZSBFcnJvclxuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IEVycm9yXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IHBhcnNlRXJyb3IoZSlcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IFRocm93cyBlcnJvclxuICAgKiAgIGVuZFxuICAgKi9cbiAgYXN5bmMgcmF3PFY+KHJhd0lucHV0OiBNYW5nb1F1ZXJ5LCBwcm9jZXNzID0gdHJ1ZSk6IFByb21pc2U8Vj4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZTogRmluZFJlc3BvbnNlPGFueT4gPSBhd2FpdCB0aGlzLmNsaWVudC5maW5kKFxuICAgICAgICByYXdJbnB1dCBhcyBhbnlcbiAgICAgICk7XG4gICAgICBpZiAocmVzcG9uc2Uud2FybmluZykgY29uc29sZS53YXJuKHJlc3BvbnNlLndhcm5pbmcpO1xuICAgICAgaWYgKHByb2Nlc3MpIHJldHVybiByZXNwb25zZS5kb2NzIGFzIFY7XG4gICAgICByZXR1cm4gcmVzcG9uc2UgYXMgVjtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IFBvdWNoQWRhcHRlci5wYXJzZUVycm9yKGUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUGFyc2VzIGFuZCBjb252ZXJ0cyBlcnJvcnMgZnJvbSBQb3VjaERCIHRvIGFwcGxpY2F0aW9uLXNwZWNpZmljIGVycm9yc1xuICAgKiBAc3VtbWFyeSBDb252ZXJ0cyBQb3VjaERCIGVycm9ycyB0byB0aGUgYXBwbGljYXRpb24ncyBlcnJvciBoaWVyYXJjaHkuXG4gICAqIFRoaXMgaW5zdGFuY2UgbWV0aG9kIGRlbGVnYXRlcyB0byB0aGUgc3RhdGljIHBhcnNlRXJyb3IgbWV0aG9kLlxuICAgKiBAcGFyYW0ge0Vycm9yfHN0cmluZ30gZXJyIC0gVGhlIGVycm9yIG9iamVjdCBvciBtZXNzYWdlIHRvIHBhcnNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcmVhc29uXSAtIE9wdGlvbmFsIHJlYXNvbiBmb3IgdGhlIGVycm9yXG4gICAqIEByZXR1cm4ge0Jhc2VFcnJvcn0gVGhlIGNvbnZlcnRlZCBlcnJvciBvYmplY3RcbiAgICovXG4gIG92ZXJyaWRlIHBhcnNlRXJyb3IoZXJyOiBFcnJvciB8IHN0cmluZywgcmVhc29uPzogc3RyaW5nKTogQmFzZUVycm9yIHtcbiAgICByZXR1cm4gUG91Y2hBZGFwdGVyLnBhcnNlRXJyb3IoZXJyLCByZWFzb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTdGF0aWMgbWV0aG9kIHRvIHBhcnNlIGFuZCBjb252ZXJ0IGVycm9ycyBmcm9tIFBvdWNoREIgdG8gYXBwbGljYXRpb24tc3BlY2lmaWMgZXJyb3JzXG4gICAqIEBzdW1tYXJ5IENvbnZlcnRzIFBvdWNoREIgZXJyb3JzIHRvIHRoZSBhcHBsaWNhdGlvbidzIGVycm9yIGhpZXJhcmNoeSBiYXNlZCBvbiBlcnJvciBjb2RlcyBhbmQgbWVzc2FnZXMuXG4gICAqIFRoaXMgbWV0aG9kIGFuYWx5emVzIHRoZSBlcnJvciB0eXBlLCBzdGF0dXMgY29kZSwgb3IgbWVzc2FnZSB0byBkZXRlcm1pbmUgdGhlIGFwcHJvcHJpYXRlIGVycm9yIGNsYXNzLlxuICAgKiBAcGFyYW0ge0Vycm9yfHN0cmluZ30gZXJyIC0gVGhlIGVycm9yIG9iamVjdCBvciBtZXNzYWdlIHRvIHBhcnNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcmVhc29uXSAtIE9wdGlvbmFsIHJlYXNvbiBmb3IgdGhlIGVycm9yXG4gICAqIEByZXR1cm4ge0Jhc2VFcnJvcn0gVGhlIGNvbnZlcnRlZCBlcnJvciBvYmplY3RcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hBZGFwdGVyXG4gICAqXG4gICAqICAgQ2FsbGVyLT4+UG91Y2hBZGFwdGVyOiBwYXJzZUVycm9yKGVyciwgcmVhc29uKVxuICAgKiAgIGFsdCBlcnIgaXMgQmFzZUVycm9yXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2FsbGVyOiBSZXR1cm4gZXJyIGFzIGlzXG4gICAqICAgZWxzZSBlcnIgaXMgc3RyaW5nXG4gICAqICAgICBhbHQgY29udGFpbnMgXCJhbHJlYWR5IGV4aXN0XCIgb3IgXCJ1cGRhdGUgY29uZmxpY3RcIlxuICAgKiAgICAgICBQb3VjaEFkYXB0ZXItLT4+Q2FsbGVyOiBDb25mbGljdEVycm9yXG4gICAqICAgICBlbHNlIGNvbnRhaW5zIFwibWlzc2luZ1wiIG9yIFwiZGVsZXRlZFwiXG4gICAqICAgICAgIFBvdWNoQWRhcHRlci0tPj5DYWxsZXI6IE5vdEZvdW5kRXJyb3JcbiAgICogICAgIGVuZFxuICAgKiAgIGVsc2UgZXJyIGhhcyBzdGF0dXNcbiAgICogICAgIGFsdCBzdGF0dXMgaXMgNDAxLCA0MTIsIDQwOVxuICAgKiAgICAgICBQb3VjaEFkYXB0ZXItLT4+Q2FsbGVyOiBDb25mbGljdEVycm9yXG4gICAqICAgICBlbHNlIHN0YXR1cyBpcyA0MDRcbiAgICogICAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogTm90Rm91bmRFcnJvclxuICAgKiAgICAgZWxzZSBzdGF0dXMgaXMgNDAwXG4gICAqICAgICAgIGFsdCBtZXNzYWdlIGNvbnRhaW5zIFwiTm8gaW5kZXggZXhpc3RzXCJcbiAgICogICAgICAgICBQb3VjaEFkYXB0ZXItLT4+Q2FsbGVyOiBJbmRleEVycm9yXG4gICAqICAgICAgIGVsc2VcbiAgICogICAgICAgICBQb3VjaEFkYXB0ZXItLT4+Q2FsbGVyOiBJbnRlcm5hbEVycm9yXG4gICAqICAgICAgIGVuZFxuICAgKiAgICAgZWxzZSBtZXNzYWdlIGNvbnRhaW5zIFwiRUNPTk5SRUZVU0VEXCJcbiAgICogICAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogQ29ubmVjdGlvbkVycm9yXG4gICAqICAgICBlbHNlXG4gICAqICAgICAgIFBvdWNoQWRhcHRlci0tPj5DYWxsZXI6IEludGVybmFsRXJyb3JcbiAgICogICAgIGVuZFxuICAgKiAgIGVuZFxuICAgKi9cbiAgc3RhdGljIG92ZXJyaWRlIHBhcnNlRXJyb3IoZXJyOiBFcnJvciB8IHN0cmluZywgcmVhc29uPzogc3RyaW5nKTogQmFzZUVycm9yIHtcbiAgICAvLyByZXR1cm4gc3VwZXIucGFyc2VFcnJvcihlcnIsIHJlYXNvbik7XG4gICAgaWYgKGVyciBpbnN0YW5jZW9mIEJhc2VFcnJvcikgcmV0dXJuIGVyciBhcyBhbnk7XG4gICAgbGV0IGNvZGU6IHN0cmluZyA9IFwiXCI7XG4gICAgaWYgKHR5cGVvZiBlcnIgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGNvZGUgPSBlcnI7XG4gICAgICBpZiAoY29kZS5tYXRjaCgvYWxyZWFkeSBleGlzdHx1cGRhdGUgY29uZmxpY3QvZykpXG4gICAgICAgIHJldHVybiBuZXcgQ29uZmxpY3RFcnJvcihjb2RlKTtcbiAgICAgIGlmIChjb2RlLm1hdGNoKC9taXNzaW5nfGRlbGV0ZWQvZykpIHJldHVybiBuZXcgTm90Rm91bmRFcnJvcihjb2RlKTtcbiAgICB9IGVsc2UgaWYgKChlcnIgYXMgYW55KS5zdGF0dXMpIHtcbiAgICAgIGNvZGUgPSAoZXJyIGFzIGFueSkuc3RhdHVzO1xuICAgICAgcmVhc29uID0gcmVhc29uIHx8IGVyci5tZXNzYWdlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlID0gZXJyLm1lc3NhZ2U7XG4gICAgfVxuXG4gICAgc3dpdGNoIChjb2RlLnRvU3RyaW5nKCkpIHtcbiAgICAgIGNhc2UgXCI0MDFcIjpcbiAgICAgIGNhc2UgXCI0MTJcIjpcbiAgICAgIGNhc2UgXCI0MDlcIjpcbiAgICAgICAgcmV0dXJuIG5ldyBDb25mbGljdEVycm9yKHJlYXNvbiBhcyBzdHJpbmcpO1xuICAgICAgY2FzZSBcIjQwNFwiOlxuICAgICAgICByZXR1cm4gbmV3IE5vdEZvdW5kRXJyb3IocmVhc29uIGFzIHN0cmluZyk7XG4gICAgICBjYXNlIFwiNDAwXCI6XG4gICAgICAgIGlmIChjb2RlLnRvU3RyaW5nKCkubWF0Y2goL05vXFxzaW5kZXhcXHNleGlzdHMvZykpXG4gICAgICAgICAgcmV0dXJuIG5ldyBJbmRleEVycm9yKGVycik7XG4gICAgICAgIHJldHVybiBuZXcgSW50ZXJuYWxFcnJvcihlcnIpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGNvZGUudG9TdHJpbmcoKS5tYXRjaCgvRUNPTk5SRUZVU0VEL2cpKVxuICAgICAgICAgIHJldHVybiBuZXcgQ29ubmVjdGlvbkVycm9yKGVycik7XG4gICAgICAgIHJldHVybiBuZXcgSW50ZXJuYWxFcnJvcihlcnIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB1cCBkZWNvcmF0aW9ucyBmb3IgUG91Y2hEQi1zcGVjaWZpYyBtb2RlbCBwcm9wZXJ0aWVzXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgZGVjb3JhdG9ycyBmb3IgY3JlYXRlZEJ5IGFuZCB1cGRhdGVkQnkgZmllbGRzIGluIG1vZGVscy5cbiAgICogVGhpcyBtZXRob2QgZGVmaW5lcyBob3cgdGhlc2UgZmllbGRzIHNob3VsZCBiZSBhdXRvbWF0aWNhbGx5IHBvcHVsYXRlZCBkdXJpbmcgY3JlYXRlIGFuZCB1cGRhdGUgb3BlcmF0aW9ucy5cbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hBZGFwdGVyXG4gICAqICAgcGFydGljaXBhbnQgRGVjb3JhdGlvblxuICAgKlxuICAgKiAgIENhbGxlci0+PlBvdWNoQWRhcHRlcjogZGVjb3JhdGlvbigpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UmVwb3NpdG9yeToga2V5KFBlcnNpc3RlbmNlS2V5cy5DUkVBVEVEX0JZKVxuICAgKiAgIFJlcG9zaXRvcnktLT4+UG91Y2hBZGFwdGVyOiBjcmVhdGVkQnlLZXlcbiAgICogICBQb3VjaEFkYXB0ZXItPj5SZXBvc2l0b3J5OiBrZXkoUGVyc2lzdGVuY2VLZXlzLlVQREFURURfQlkpXG4gICAqICAgUmVwb3NpdG9yeS0tPj5Qb3VjaEFkYXB0ZXI6IHVwZGF0ZWRCeUtleVxuICAgKlxuICAgKiAgIFBvdWNoQWRhcHRlci0+PkRlY29yYXRpb246IGZsYXZvdXJlZEFzKFBvdWNoRmxhdm91cilcbiAgICogICBEZWNvcmF0aW9uLS0+PlBvdWNoQWRhcHRlcjogRGVjb3JhdG9yQnVpbGRlclxuICAgKiAgIFBvdWNoQWRhcHRlci0+PkRlY29yYXRpb246IGZvcihjcmVhdGVkQnlLZXkpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+RGVjb3JhdGlvbjogZGVmaW5lKG9uQ3JlYXRlLCBwcm9wTWV0YWRhdGEpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+RGVjb3JhdGlvbjogYXBwbHkoKVxuICAgKlxuICAgKiAgIFBvdWNoQWRhcHRlci0+PkRlY29yYXRpb246IGZsYXZvdXJlZEFzKFBvdWNoRmxhdm91cilcbiAgICogICBEZWNvcmF0aW9uLS0+PlBvdWNoQWRhcHRlcjogRGVjb3JhdG9yQnVpbGRlclxuICAgKiAgIFBvdWNoQWRhcHRlci0+PkRlY29yYXRpb246IGZvcih1cGRhdGVkQnlLZXkpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+RGVjb3JhdGlvbjogZGVmaW5lKG9uQ3JlYXRlLCBwcm9wTWV0YWRhdGEpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+RGVjb3JhdGlvbjogYXBwbHkoKVxuICAgKi9cbiAgc3RhdGljIG92ZXJyaWRlIGRlY29yYXRpb24oKSB7XG4gICAgc3VwZXIuZGVjb3JhdGlvbigpO1xuICAgIGNvbnN0IGNyZWF0ZWRCeUtleSA9IFJlcG9zaXRvcnkua2V5KFBlcnNpc3RlbmNlS2V5cy5DUkVBVEVEX0JZKTtcbiAgICBjb25zdCB1cGRhdGVkQnlLZXkgPSBSZXBvc2l0b3J5LmtleShQZXJzaXN0ZW5jZUtleXMuVVBEQVRFRF9CWSk7XG4gICAgRGVjb3JhdGlvbi5mbGF2b3VyZWRBcyhQb3VjaEZsYXZvdXIpXG4gICAgICAuZm9yKGNyZWF0ZWRCeUtleSlcbiAgICAgIC5kZWZpbmUoXG4gICAgICAgIG9uQ3JlYXRlKGNyZWF0ZWRCeU9uUG91Y2hDcmVhdGVVcGRhdGUpLFxuICAgICAgICBwcm9wTWV0YWRhdGEoY3JlYXRlZEJ5S2V5LCB7fSlcbiAgICAgIClcbiAgICAgIC5hcHBseSgpO1xuICAgIERlY29yYXRpb24uZmxhdm91cmVkQXMoUG91Y2hGbGF2b3VyKVxuICAgICAgLmZvcih1cGRhdGVkQnlLZXkpXG4gICAgICAuZGVmaW5lKFxuICAgICAgICBvbkNyZWF0ZVVwZGF0ZShjcmVhdGVkQnlPblBvdWNoQ3JlYXRlVXBkYXRlKSxcbiAgICAgICAgcHJvcE1ldGFkYXRhKHVwZGF0ZWRCeUtleSwge30pXG4gICAgICApXG4gICAgICAuYXBwbHkoKTtcbiAgfVxufVxuXG5Qb3VjaEFkYXB0ZXIuc2V0Q3VycmVudChQb3VjaEZsYXZvdXIpO1xuIl19
package/lib/adapter.d.ts CHANGED
@@ -4,7 +4,7 @@ import { BaseError, Context, OperationKeys } from "@decaf-ts/db-decorators";
4
4
  import { RelationsMetadata } from "@decaf-ts/core";
5
5
  import Database = PouchDB.Database;
6
6
  import { Constructor, Model } from "@decaf-ts/decorator-validation";
7
- import { PouchFlags } from "./types";
7
+ import { PouchConfig, PouchFlags } from "./types";
8
8
  import { PouchRepository } from "./PouchRepository";
9
9
  /**
10
10
  * @description Sets the creator ID on a model during creation or update operations
@@ -25,25 +25,33 @@ import { PouchRepository } from "./PouchRepository";
25
25
  export declare function createdByOnPouchCreateUpdate<M extends Model, R extends PouchRepository<M>, V extends RelationsMetadata>(this: R, context: Context<PouchFlags>, data: V, key: keyof M, model: M): Promise<void>;
26
26
  /**
27
27
  * @description PouchDB implementation of the CouchDBAdapter
28
- * @summary This class provides a concrete implementation of the CouchDBAdapter for PouchDB.
29
- * It handles all database operations like create, read, update, delete (CRUD) for both
30
- * single documents and bulk operations. It also provides methods for querying and indexing.
31
- * @template Database - The PouchDB database type
28
+ * @summary Concrete adapter that bridges the generic CouchDBAdapter to a PouchDB backend. It supports CRUD (single and bulk), indexing and Mango queries, and wires flavour-specific decorations.
32
29
  * @template PouchFlags - The flags specific to PouchDB operations
33
30
  * @template Context<PouchFlags> - The context type with PouchDB flags
34
- * @param {Database} scope - The PouchDB database instance
31
+ * @param {PouchConfig} config - Adapter configuration (remote credentials or local storage path, db name, plugins)
35
32
  * @param {string} [alias] - Optional alias for the database
36
33
  * @class PouchAdapter
37
34
  * @example
38
35
  * ```typescript
39
- * import PouchDB from 'pouchdb';
40
36
  * import { PouchAdapter } from '@decaf-ts/for-pouch';
41
37
  *
42
- * // Create a new PouchDB instance
43
- * const db = new PouchDB('my-database');
38
+ * // Create a PouchAdapter with config
39
+ * const adapter = new PouchAdapter({
40
+ * protocol: 'http',
41
+ * host: 'localhost:5984',
42
+ * user: 'admin',
43
+ * password: 'secret',
44
+ * dbName: 'my-database',
45
+ * plugins: []
46
+ * });
44
47
  *
45
- * // Create a PouchAdapter with the database
46
- * const adapter = new PouchAdapter(db);
48
+ * // Or use local storage
49
+ * const localAdapter = new PouchAdapter({
50
+ * protocol: 'http', // ignored for local
51
+ * dbName: 'local-db',
52
+ * storagePath: 'local_dbs',
53
+ * plugins: []
54
+ * });
47
55
  *
48
56
  * // Use the adapter for database operations
49
57
  * const result = await adapter.read('users', 'user-123');
@@ -55,8 +63,8 @@ export declare function createdByOnPouchCreateUpdate<M extends Model, R extends
55
63
  * participant PouchDB
56
64
  * participant CouchDB
57
65
  *
58
- * Client->>PouchAdapter: new PouchAdapter(db)
59
- * PouchAdapter->>CouchDBAdapter: super(scope, PouchFlavour, alias)
66
+ * Client->>PouchAdapter: new PouchAdapter(config, alias?)
67
+ * PouchAdapter->>CouchDBAdapter: super(config, PouchFlavour, alias)
60
68
  *
61
69
  * Client->>PouchAdapter: create(table, id, model)
62
70
  * PouchAdapter->>PouchDB: put(model)
@@ -72,8 +80,33 @@ export declare function createdByOnPouchCreateUpdate<M extends Model, R extends
72
80
  * PouchDB-->>PouchAdapter: Document
73
81
  * PouchAdapter-->>Client: Model
74
82
  */
75
- export declare class PouchAdapter extends CouchDBAdapter<Database, PouchFlags, Context<PouchFlags>> {
76
- constructor(scope: Database, alias?: string);
83
+ export declare class PouchAdapter extends CouchDBAdapter<PouchConfig, Database, PouchFlags, Context<PouchFlags>> {
84
+ constructor(config: PouchConfig, alias?: string);
85
+ /**
86
+ * @description Lazily initializes and returns the underlying PouchDB client
87
+ * @summary Loads required PouchDB plugins once, builds the connection URL or local storage path from config, and caches the Database instance for reuse. Throws InternalError if client creation fails.
88
+ * @return {Database} A PouchDB Database instance ready to perform operations
89
+ * @mermaid
90
+ * sequenceDiagram
91
+ * participant Caller
92
+ * participant PouchAdapter
93
+ * participant PouchDB
94
+ * Caller->>PouchAdapter: getClient()
95
+ * alt client not initialized
96
+ * PouchAdapter->>PouchAdapter: register plugins
97
+ * PouchAdapter->>PouchDB: new PouchDB(url or path)
98
+ * alt creation fails
99
+ * PouchDB-->>PouchAdapter: Error
100
+ * PouchAdapter-->>Caller: throws InternalError
101
+ * else success
102
+ * PouchDB-->>PouchAdapter: Database
103
+ * PouchAdapter-->>Caller: cached client
104
+ * end
105
+ * else client initialized
106
+ * PouchAdapter-->>Caller: cached client
107
+ * end
108
+ */
109
+ getClient(): Database;
77
110
  /**
78
111
  * @description Generates operation flags for PouchDB operations
79
112
  * @summary Creates a set of flags for a specific operation, including a UUID for identification.