@decaf-ts/for-pouch 0.2.14 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +159 -16
- package/README.md +24 -2
- package/dist/for-pouch.cjs +2 -754
- package/dist/for-pouch.cjs.map +1 -0
- package/dist/for-pouch.js +2 -0
- package/dist/for-pouch.js.map +1 -0
- package/lib/PouchRepository.cjs +1 -1
- package/lib/PouchRepository.js.map +1 -0
- package/lib/adapter.cjs +33 -35
- package/lib/adapter.d.ts +25 -24
- package/lib/adapter.js.map +1 -0
- package/lib/constants.cjs +1 -1
- package/lib/constants.js.map +1 -0
- package/lib/esm/PouchRepository.js +1 -1
- package/lib/esm/PouchRepository.js.map +1 -0
- package/lib/esm/adapter.d.ts +25 -24
- package/lib/esm/adapter.js +32 -34
- package/lib/esm/adapter.js.map +1 -0
- package/lib/esm/constants.js +1 -1
- package/lib/esm/constants.js.map +1 -0
- package/lib/esm/index.d.ts +1 -1
- package/lib/esm/index.js +2 -2
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/types.js +1 -1
- package/lib/esm/types.js.map +1 -0
- package/lib/index.cjs +2 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js.map +1 -0
- package/lib/types.cjs +1 -1
- package/lib/types.js.map +1 -0
- package/package.json +23 -59
- package/dist/for-pouch.esm.cjs +0 -731
package/dist/for-pouch.cjs
CHANGED
|
@@ -1,754 +1,2 @@
|
|
|
1
|
-
(function (
|
|
2
|
-
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'reflect-metadata', '@decaf-ts/for-couchdb', '@decaf-ts/db-decorators', '@decaf-ts/core', '@decaf-ts/decorator-validation', 'pouchdb-core', 'pouchdb-mapreduce', 'pouchdb-replication', 'pouchdb-find', '@decaf-ts/decoration'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["for-pouch"] = {}, null, global.forCouchdb, global.dbDecorators, global.core, global.decoratorValidation, global.PouchDB, global.PouchMapReduce, global.PouchReplication, global.PouchFind, global.decoration));
|
|
5
|
-
})(this, (function (exports, reflectMetadata, forCouchdb, dbDecorators, core, decoratorValidation, PouchDB, PouchMapReduce, PouchReplication, PouchFind, decoration) { 'use strict';
|
|
6
|
-
|
|
7
|
-
function _interopNamespaceDefault(e) {
|
|
8
|
-
var n = Object.create(null);
|
|
9
|
-
if (e) {
|
|
10
|
-
Object.keys(e).forEach(function (k) {
|
|
11
|
-
if (k !== 'default') {
|
|
12
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
-
enumerable: true,
|
|
15
|
-
get: function () { return e[k]; }
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
n.default = e;
|
|
21
|
-
return Object.freeze(n);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
var PouchMapReduce__namespace = /*#__PURE__*/_interopNamespaceDefault(PouchMapReduce);
|
|
25
|
-
var PouchReplication__namespace = /*#__PURE__*/_interopNamespaceDefault(PouchReplication);
|
|
26
|
-
var PouchFind__namespace = /*#__PURE__*/_interopNamespaceDefault(PouchFind);
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* @description Identifier for PouchDB flavor in the decorator system
|
|
30
|
-
* @summary A string constant that identifies the PouchDB implementation in the decorator system.
|
|
31
|
-
* This is used to target decorators specifically for PouchDB adapters.
|
|
32
|
-
* @const PouchFlavour
|
|
33
|
-
* @memberOf module:for-pouch
|
|
34
|
-
*/
|
|
35
|
-
const PouchFlavour = "pouch";
|
|
36
|
-
/**
|
|
37
|
-
* @description Default relative path where local PouchDB databases are stored
|
|
38
|
-
* @summary Used when creating a local PouchDB instance without a remote host; combined with dbName to form the filesystem path.
|
|
39
|
-
* @const DefaultLocalStoragePath
|
|
40
|
-
* @memberOf module:for-pouch
|
|
41
|
-
*/
|
|
42
|
-
const DefaultLocalStoragePath = "local_dbs";
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* @description Sets the creator ID on a model during creation or update operations
|
|
46
|
-
* @summary This function is used as a decorator handler to automatically set the creator ID field on a model
|
|
47
|
-
* when it's being created or updated. It extracts the UUID from the context and assigns it to the specified key.
|
|
48
|
-
* @template M - The model type that extends Model
|
|
49
|
-
* @template R - The repository type that extends PouchRepository<M>
|
|
50
|
-
* @template V - The relations metadata type that extends RelationsMetadata
|
|
51
|
-
* @param {R} this - The repository instance
|
|
52
|
-
* @param {Context<PouchFlags>} context - The operation context containing flags
|
|
53
|
-
* @param {V} data - The relations metadata
|
|
54
|
-
* @param key - The property key to set on the model
|
|
55
|
-
* @param {M} model - The model instance to modify
|
|
56
|
-
* @return {Promise<void>} A promise that resolves when the operation is complete
|
|
57
|
-
* @function createdByOnPouchCreateUpdate
|
|
58
|
-
* @memberOf module:for-pouch
|
|
59
|
-
*/
|
|
60
|
-
async function createdByOnPouchCreateUpdate(context, data, key, model) {
|
|
61
|
-
try {
|
|
62
|
-
const uuid = context.get("UUID");
|
|
63
|
-
model[key] = uuid;
|
|
64
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
65
|
-
}
|
|
66
|
-
catch (e) {
|
|
67
|
-
throw new core.UnsupportedError("No User found in context. Please provide a user in the context");
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* @description PouchDB implementation of the CouchDBAdapter
|
|
72
|
-
* @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.
|
|
73
|
-
* @template PouchFlags - The flags specific to PouchDB operations
|
|
74
|
-
* @template Context<PouchFlags> - The context type with PouchDB flags
|
|
75
|
-
* @param {PouchConfig} config - Adapter configuration (remote credentials or local storage path, db name, plugins)
|
|
76
|
-
* @param {string} [alias] - Optional alias for the database
|
|
77
|
-
* @class PouchAdapter
|
|
78
|
-
* @example
|
|
79
|
-
* ```typescript
|
|
80
|
-
* import { PouchAdapter } from '@decaf-ts/for-pouch';
|
|
81
|
-
*
|
|
82
|
-
* // Create a PouchAdapter with config
|
|
83
|
-
* const adapter = new PouchAdapter({
|
|
84
|
-
* protocol: 'http',
|
|
85
|
-
* host: 'localhost:5984',
|
|
86
|
-
* user: 'admin',
|
|
87
|
-
* password: 'secret',
|
|
88
|
-
* dbName: 'my-database',
|
|
89
|
-
* plugins: []
|
|
90
|
-
* });
|
|
91
|
-
*
|
|
92
|
-
* // Or use local storage
|
|
93
|
-
* const localAdapter = new PouchAdapter({
|
|
94
|
-
* protocol: 'http', // ignored for local
|
|
95
|
-
* dbName: 'local-db',
|
|
96
|
-
* storagePath: 'local_dbs',
|
|
97
|
-
* plugins: []
|
|
98
|
-
* });
|
|
99
|
-
*
|
|
100
|
-
* // Use the adapter for database operations
|
|
101
|
-
* const result = await adapter.read('users', 'user-123');
|
|
102
|
-
* ```
|
|
103
|
-
* @mermaid
|
|
104
|
-
* sequenceDiagram
|
|
105
|
-
* participant Client
|
|
106
|
-
* participant PouchAdapter
|
|
107
|
-
* participant PouchDB
|
|
108
|
-
* participant CouchDB
|
|
109
|
-
*
|
|
110
|
-
* Client->>PouchAdapter: new PouchAdapter(config, alias?)
|
|
111
|
-
* PouchAdapter->>CouchDBAdapter: super(config, PouchFlavour, alias)
|
|
112
|
-
*
|
|
113
|
-
* Client->>PouchAdapter: create(table, id, model)
|
|
114
|
-
* PouchAdapter->>PouchDB: put(model)
|
|
115
|
-
* PouchDB->>CouchDB: HTTP PUT
|
|
116
|
-
* CouchDB-->>PouchDB: Response
|
|
117
|
-
* PouchDB-->>PouchAdapter: Response
|
|
118
|
-
* PouchAdapter-->>Client: Updated model
|
|
119
|
-
*
|
|
120
|
-
* Client->>PouchAdapter: read(table, id)
|
|
121
|
-
* PouchAdapter->>PouchDB: get(id)
|
|
122
|
-
* PouchDB->>CouchDB: HTTP GET
|
|
123
|
-
* CouchDB-->>PouchDB: Document
|
|
124
|
-
* PouchDB-->>PouchAdapter: Document
|
|
125
|
-
* PouchAdapter-->>Client: Model
|
|
126
|
-
*/
|
|
127
|
-
class PouchAdapter extends forCouchdb.CouchDBAdapter {
|
|
128
|
-
constructor(config, alias) {
|
|
129
|
-
super(config, PouchFlavour, alias);
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* @description Lazily initializes and returns the underlying PouchDB client
|
|
133
|
-
* @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.
|
|
134
|
-
* @return {Database} A PouchDB Database instance ready to perform operations
|
|
135
|
-
* @mermaid
|
|
136
|
-
* sequenceDiagram
|
|
137
|
-
* participant Caller
|
|
138
|
-
* participant PouchAdapter
|
|
139
|
-
* participant PouchDB
|
|
140
|
-
* Caller->>PouchAdapter: getClient()
|
|
141
|
-
* alt client not initialized
|
|
142
|
-
* PouchAdapter->>PouchAdapter: register plugins
|
|
143
|
-
* PouchAdapter->>PouchDB: new PouchDB(url or path)
|
|
144
|
-
* alt creation fails
|
|
145
|
-
* PouchDB-->>PouchAdapter: Error
|
|
146
|
-
* PouchAdapter-->>Caller: throws InternalError
|
|
147
|
-
* else success
|
|
148
|
-
* PouchDB-->>PouchAdapter: Database
|
|
149
|
-
* PouchAdapter-->>Caller: cached client
|
|
150
|
-
* end
|
|
151
|
-
* else client initialized
|
|
152
|
-
* PouchAdapter-->>Caller: cached client
|
|
153
|
-
* end
|
|
154
|
-
*/
|
|
155
|
-
getClient() {
|
|
156
|
-
if (!this._client) {
|
|
157
|
-
const plugins = [
|
|
158
|
-
PouchMapReduce__namespace,
|
|
159
|
-
PouchReplication__namespace,
|
|
160
|
-
PouchFind__namespace,
|
|
161
|
-
...this.config.plugins,
|
|
162
|
-
];
|
|
163
|
-
for (const plugin of plugins) {
|
|
164
|
-
try {
|
|
165
|
-
PouchDB.plugin(plugin);
|
|
166
|
-
}
|
|
167
|
-
catch (e) {
|
|
168
|
-
if (e instanceof Error && e.message.includes("redefine property"))
|
|
169
|
-
continue; //plugin has already been loaded so it's ok
|
|
170
|
-
throw e;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
const { host, protocol, user, password, dbName, storagePath } = this.config;
|
|
174
|
-
try {
|
|
175
|
-
if (host && user) {
|
|
176
|
-
this._client = new PouchDB(`${protocol}://${user}:${password}@${host}/${dbName}`);
|
|
177
|
-
}
|
|
178
|
-
else
|
|
179
|
-
this._client = new PouchDB(`${storagePath || DefaultLocalStoragePath}/${dbName}`);
|
|
180
|
-
}
|
|
181
|
-
catch (e) {
|
|
182
|
-
throw new dbDecorators.InternalError(`Failed to create PouchDB client: ${e}`);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
return this._client;
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* @description Generates operation flags for PouchDB operations
|
|
189
|
-
* @summary Creates a set of flags for a specific operation, including a UUID for identification.
|
|
190
|
-
* This method extracts the user ID from the database URL or generates a random UUID if not available.
|
|
191
|
-
* @template M - The model type that extends Model
|
|
192
|
-
* @param {OperationKeys} operation - The operation key (create, read, update, delete)
|
|
193
|
-
* @param {Constructor<M>} model - The model constructor
|
|
194
|
-
* @param {Partial<PouchFlags>} flags - Partial flags to be merged
|
|
195
|
-
* @return {Promise<PouchFlags>} The complete set of flags for the operation
|
|
196
|
-
*/
|
|
197
|
-
async flags(operation, model, flags) {
|
|
198
|
-
if (!this.config.user)
|
|
199
|
-
this.config.user = crypto.randomUUID();
|
|
200
|
-
return Object.assign(await super.flags(operation, model, flags), {
|
|
201
|
-
UUID: this.config.user,
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* @description Creates database indexes for the given models
|
|
206
|
-
* @summary Generates and creates indexes in the PouchDB database based on the provided model constructors.
|
|
207
|
-
* This method uses the generateIndexes utility to create index definitions and then creates them in the database.
|
|
208
|
-
* @template M - The model type that extends Model
|
|
209
|
-
* @param models - The model constructors to create indexes for
|
|
210
|
-
* @return {Promise<void>} A promise that resolves when all indexes are created
|
|
211
|
-
*/
|
|
212
|
-
async index(...models) {
|
|
213
|
-
const indexes = forCouchdb.generateIndexes(models);
|
|
214
|
-
for (const index of indexes) {
|
|
215
|
-
const res = await this.client.createIndex(index);
|
|
216
|
-
const { result } = res;
|
|
217
|
-
if (result === "existing")
|
|
218
|
-
throw new dbDecorators.ConflictError(`Index ${index.name} already exists`);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* @description Creates a new document in the database
|
|
223
|
-
* @summary Inserts a new document into the PouchDB database using the put operation.
|
|
224
|
-
* This method handles error parsing and ensures the operation was successful.
|
|
225
|
-
* @param {string} tableName - The name of the table/collection
|
|
226
|
-
* @param {string|number} id - The document ID
|
|
227
|
-
* @param {Record<string, any>} model - The document data to insert
|
|
228
|
-
* @return {Promise<Record<string, any>>} A promise that resolves to the created document with metadata
|
|
229
|
-
* @mermaid
|
|
230
|
-
* sequenceDiagram
|
|
231
|
-
* participant Client
|
|
232
|
-
* participant PouchAdapter
|
|
233
|
-
* participant PouchDB
|
|
234
|
-
*
|
|
235
|
-
* Client->>PouchAdapter: create(tableName, id, model)
|
|
236
|
-
* PouchAdapter->>PouchDB: put(model)
|
|
237
|
-
* alt Success
|
|
238
|
-
* PouchDB-->>PouchAdapter: Response with ok=true
|
|
239
|
-
* PouchAdapter->>PouchAdapter: assignMetadata(model, response.rev)
|
|
240
|
-
* PouchAdapter-->>Client: Updated model with metadata
|
|
241
|
-
* else Error
|
|
242
|
-
* PouchDB-->>PouchAdapter: Error
|
|
243
|
-
* PouchAdapter->>PouchAdapter: parseError(e)
|
|
244
|
-
* PouchAdapter-->>Client: Throws error
|
|
245
|
-
* end
|
|
246
|
-
*/
|
|
247
|
-
async create(tableName, id, model) {
|
|
248
|
-
let response;
|
|
249
|
-
try {
|
|
250
|
-
response = await this.client.put(model);
|
|
251
|
-
}
|
|
252
|
-
catch (e) {
|
|
253
|
-
throw this.parseError(e);
|
|
254
|
-
}
|
|
255
|
-
if (!response.ok)
|
|
256
|
-
throw new dbDecorators.InternalError(`Failed to insert doc id: ${id} in table ${tableName}`);
|
|
257
|
-
return this.assignMetadata(model, response.rev);
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* @description Creates multiple documents in the database in a single operation
|
|
261
|
-
* @summary Inserts multiple documents into the PouchDB database using the bulkDocs operation.
|
|
262
|
-
* This method handles error parsing and ensures all operations were successful.
|
|
263
|
-
* @param {string} tableName - The name of the table/collection
|
|
264
|
-
* @param {string[]|number[]} ids - The document IDs
|
|
265
|
-
* @param models - The document data to insert
|
|
266
|
-
* @return A promise that resolves to the created documents with metadata
|
|
267
|
-
* @mermaid
|
|
268
|
-
* sequenceDiagram
|
|
269
|
-
* participant Client
|
|
270
|
-
* participant PouchAdapter
|
|
271
|
-
* participant PouchDB
|
|
272
|
-
*
|
|
273
|
-
* Client->>PouchAdapter: createAll(tableName, ids, models)
|
|
274
|
-
* PouchAdapter->>PouchDB: bulkDocs(models)
|
|
275
|
-
* alt Success
|
|
276
|
-
* PouchDB-->>PouchAdapter: Array of responses with ok=true
|
|
277
|
-
* PouchAdapter->>PouchAdapter: assignMultipleMetadata(models, revs)
|
|
278
|
-
* PouchAdapter-->>Client: Updated models with metadata
|
|
279
|
-
* else Error
|
|
280
|
-
* PouchDB-->>PouchAdapter: Array with errors
|
|
281
|
-
* PouchAdapter->>PouchAdapter: Check for errors
|
|
282
|
-
* PouchAdapter-->>Client: Throws InternalError
|
|
283
|
-
* end
|
|
284
|
-
*/
|
|
285
|
-
async createAll(tableName, ids, models) {
|
|
286
|
-
let response;
|
|
287
|
-
try {
|
|
288
|
-
response = await this.client.bulkDocs(models);
|
|
289
|
-
}
|
|
290
|
-
catch (e) {
|
|
291
|
-
throw PouchAdapter.parseError(e);
|
|
292
|
-
}
|
|
293
|
-
if (!response.every((r) => r.ok)) {
|
|
294
|
-
const errors = response.reduce((accum, el, i) => {
|
|
295
|
-
if (el.error)
|
|
296
|
-
accum.push(`el ${i}: ${el.error}${el.reason ? ` - ${el.reason}` : ""}`);
|
|
297
|
-
return accum;
|
|
298
|
-
}, []);
|
|
299
|
-
throw new dbDecorators.InternalError(errors.join("\n"));
|
|
300
|
-
}
|
|
301
|
-
return this.assignMultipleMetadata(models, response.map((r) => r.rev));
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* @description Retrieves a document from the database by ID
|
|
305
|
-
* @summary Fetches a document from the PouchDB database using the get operation.
|
|
306
|
-
* This method generates the document ID based on the table name and ID, then retrieves the document.
|
|
307
|
-
* @param {string} tableName - The name of the table/collection
|
|
308
|
-
* @param {string|number} id - The document ID
|
|
309
|
-
* @return {Promise<Record<string, any>>} A promise that resolves to the retrieved document with metadata
|
|
310
|
-
* @mermaid
|
|
311
|
-
* sequenceDiagram
|
|
312
|
-
* participant Client
|
|
313
|
-
* participant PouchAdapter
|
|
314
|
-
* participant PouchDB
|
|
315
|
-
*
|
|
316
|
-
* Client->>PouchAdapter: read(tableName, id)
|
|
317
|
-
* PouchAdapter->>PouchAdapter: generateId(tableName, id)
|
|
318
|
-
* PouchAdapter->>PouchDB: get(_id)
|
|
319
|
-
* alt Success
|
|
320
|
-
* PouchDB-->>PouchAdapter: Document
|
|
321
|
-
* PouchAdapter->>PouchAdapter: assignMetadata(record, record._rev)
|
|
322
|
-
* PouchAdapter-->>Client: Document with metadata
|
|
323
|
-
* else Error
|
|
324
|
-
* PouchDB-->>PouchAdapter: Error
|
|
325
|
-
* PouchAdapter->>PouchAdapter: parseError(e)
|
|
326
|
-
* PouchAdapter-->>Client: Throws error
|
|
327
|
-
* end
|
|
328
|
-
*/
|
|
329
|
-
async read(tableName, id) {
|
|
330
|
-
const _id = this.generateId(tableName, id);
|
|
331
|
-
let record;
|
|
332
|
-
try {
|
|
333
|
-
record = await this.client.get(_id);
|
|
334
|
-
}
|
|
335
|
-
catch (e) {
|
|
336
|
-
throw PouchAdapter.parseError(e);
|
|
337
|
-
}
|
|
338
|
-
return this.assignMetadata(record, record._rev);
|
|
339
|
-
}
|
|
340
|
-
/**
|
|
341
|
-
* @description Retrieves multiple documents from the database by their IDs
|
|
342
|
-
* @summary Fetches multiple documents from the PouchDB database using the bulkGet operation.
|
|
343
|
-
* This method generates document IDs based on the table name and IDs, then retrieves the documents.
|
|
344
|
-
* @param {string} tableName - The name of the table/collection
|
|
345
|
-
* @param {Array<string|number|bigint>} ids - The document IDs
|
|
346
|
-
* @return A promise that resolves to the retrieved documents with metadata
|
|
347
|
-
* @mermaid
|
|
348
|
-
* sequenceDiagram
|
|
349
|
-
* participant Client
|
|
350
|
-
* participant PouchAdapter
|
|
351
|
-
* participant PouchDB
|
|
352
|
-
*
|
|
353
|
-
* Client->>PouchAdapter: readAll(tableName, ids)
|
|
354
|
-
* PouchAdapter->>PouchAdapter: Map ids to generateId(tableName, id)
|
|
355
|
-
* PouchAdapter->>PouchDB: bulkGet({docs})
|
|
356
|
-
* alt Success
|
|
357
|
-
* PouchDB-->>PouchAdapter: BulkGetResponse
|
|
358
|
-
* PouchAdapter->>PouchAdapter: Process results
|
|
359
|
-
* PouchAdapter->>PouchAdapter: assignMetadata for each doc
|
|
360
|
-
* PouchAdapter-->>Client: Documents with metadata
|
|
361
|
-
* else Error
|
|
362
|
-
* PouchAdapter->>PouchAdapter: parseError(error)
|
|
363
|
-
* PouchAdapter-->>Client: Throws error
|
|
364
|
-
* end
|
|
365
|
-
*/
|
|
366
|
-
async readAll(tableName, ids) {
|
|
367
|
-
const results = await this.client.bulkGet({
|
|
368
|
-
docs: ids.map((id) => ({ id: this.generateId(tableName, id) })),
|
|
369
|
-
});
|
|
370
|
-
const res = results.results.reduce((accum, r) => {
|
|
371
|
-
r.docs.forEach((d) => {
|
|
372
|
-
if (d.error || !d.ok)
|
|
373
|
-
throw PouchAdapter.parseError(d.error ||
|
|
374
|
-
new dbDecorators.InternalError("Missing valid response"));
|
|
375
|
-
const result = Object.assign({}, d.ok);
|
|
376
|
-
accum.push(this.assignMetadata(result, d.ok[forCouchdb.CouchDBKeys.REV]));
|
|
377
|
-
});
|
|
378
|
-
return accum;
|
|
379
|
-
}, []);
|
|
380
|
-
return res;
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* @description Updates an existing document in the database
|
|
384
|
-
* @summary Updates a document in the PouchDB database using the put operation.
|
|
385
|
-
* This method handles error parsing and ensures the operation was successful.
|
|
386
|
-
* @param {string} tableName - The name of the table/collection
|
|
387
|
-
* @param {string|number} id - The document ID
|
|
388
|
-
* @param {Record<string, any>} model - The updated document data
|
|
389
|
-
* @return {Promise<Record<string, any>>} A promise that resolves to the updated document with metadata
|
|
390
|
-
* @mermaid
|
|
391
|
-
* sequenceDiagram
|
|
392
|
-
* participant Client
|
|
393
|
-
* participant PouchAdapter
|
|
394
|
-
* participant PouchDB
|
|
395
|
-
*
|
|
396
|
-
* Client->>PouchAdapter: update(tableName, id, model)
|
|
397
|
-
* PouchAdapter->>PouchDB: put(model)
|
|
398
|
-
* alt Success
|
|
399
|
-
* PouchDB-->>PouchAdapter: Response with ok=true
|
|
400
|
-
* PouchAdapter->>PouchAdapter: assignMetadata(model, response.rev)
|
|
401
|
-
* PouchAdapter-->>Client: Updated model with metadata
|
|
402
|
-
* else Error
|
|
403
|
-
* PouchDB-->>PouchAdapter: Error
|
|
404
|
-
* PouchAdapter->>PouchAdapter: parseError(e)
|
|
405
|
-
* PouchAdapter-->>Client: Throws error
|
|
406
|
-
* end
|
|
407
|
-
*/
|
|
408
|
-
async update(tableName, id, model) {
|
|
409
|
-
let response;
|
|
410
|
-
try {
|
|
411
|
-
response = await this.client.put(model);
|
|
412
|
-
}
|
|
413
|
-
catch (e) {
|
|
414
|
-
throw PouchAdapter.parseError(e);
|
|
415
|
-
}
|
|
416
|
-
if (!response.ok)
|
|
417
|
-
throw new dbDecorators.InternalError(`Failed to update doc id: ${id} in table ${tableName}`);
|
|
418
|
-
return this.assignMetadata(model, response.rev);
|
|
419
|
-
}
|
|
420
|
-
/**
|
|
421
|
-
* @description Updates multiple documents in the database in a single operation
|
|
422
|
-
* @summary Updates multiple documents in the PouchDB database using the bulkDocs operation.
|
|
423
|
-
* This method handles error parsing and ensures all operations were successful.
|
|
424
|
-
* @param {string} tableName - The name of the table/collection
|
|
425
|
-
* @param {string[]|number[]} ids - The document IDs
|
|
426
|
-
* @param models - The updated document data
|
|
427
|
-
* @return A promise that resolves to the updated documents with metadata
|
|
428
|
-
* @mermaid
|
|
429
|
-
* sequenceDiagram
|
|
430
|
-
* participant Client
|
|
431
|
-
* participant PouchAdapter
|
|
432
|
-
* participant PouchDB
|
|
433
|
-
*
|
|
434
|
-
* Client->>PouchAdapter: updateAll(tableName, ids, models)
|
|
435
|
-
* PouchAdapter->>PouchDB: bulkDocs(models)
|
|
436
|
-
* alt Success
|
|
437
|
-
* PouchDB-->>PouchAdapter: Array of responses with ok=true
|
|
438
|
-
* PouchAdapter->>PouchAdapter: assignMultipleMetadata(models, revs)
|
|
439
|
-
* PouchAdapter-->>Client: Updated models with metadata
|
|
440
|
-
* else Error
|
|
441
|
-
* PouchDB-->>PouchAdapter: Array with errors
|
|
442
|
-
* PouchAdapter->>PouchAdapter: Check for errors
|
|
443
|
-
* PouchAdapter-->>Client: Throws InternalError
|
|
444
|
-
* end
|
|
445
|
-
*/
|
|
446
|
-
async updateAll(tableName, ids, models) {
|
|
447
|
-
let response;
|
|
448
|
-
try {
|
|
449
|
-
response = await this.client.bulkDocs(models);
|
|
450
|
-
}
|
|
451
|
-
catch (e) {
|
|
452
|
-
throw PouchAdapter.parseError(e);
|
|
453
|
-
}
|
|
454
|
-
if (!response.every((r) => !r.error)) {
|
|
455
|
-
const errors = response.reduce((accum, el, i) => {
|
|
456
|
-
if (el.error)
|
|
457
|
-
accum.push(`el ${i}: ${el.error}${el.reason ? ` - ${el.reason}` : ""}`);
|
|
458
|
-
return accum;
|
|
459
|
-
}, []);
|
|
460
|
-
throw new dbDecorators.InternalError(errors.join("\n"));
|
|
461
|
-
}
|
|
462
|
-
return this.assignMultipleMetadata(models, response.map((r) => r.rev));
|
|
463
|
-
}
|
|
464
|
-
/**
|
|
465
|
-
* @description Deletes a document from the database by ID
|
|
466
|
-
* @summary Removes a document from the PouchDB database using the remove operation.
|
|
467
|
-
* This method first retrieves the document to get its revision, then deletes it.
|
|
468
|
-
* @param {string} tableName - The name of the table/collection
|
|
469
|
-
* @param {string|number} id - The document ID
|
|
470
|
-
* @return {Promise<Record<string, any>>} A promise that resolves to the deleted document with metadata
|
|
471
|
-
* @mermaid
|
|
472
|
-
* sequenceDiagram
|
|
473
|
-
* participant Client
|
|
474
|
-
* participant PouchAdapter
|
|
475
|
-
* participant PouchDB
|
|
476
|
-
*
|
|
477
|
-
* Client->>PouchAdapter: delete(tableName, id)
|
|
478
|
-
* PouchAdapter->>PouchAdapter: generateId(tableName, id)
|
|
479
|
-
* PouchAdapter->>PouchDB: get(_id)
|
|
480
|
-
* PouchDB-->>PouchAdapter: Document with _rev
|
|
481
|
-
* PouchAdapter->>PouchDB: remove(_id, record._rev)
|
|
482
|
-
* alt Success
|
|
483
|
-
* PouchDB-->>PouchAdapter: Success response
|
|
484
|
-
* PouchAdapter->>PouchAdapter: assignMetadata(record, record._rev)
|
|
485
|
-
* PouchAdapter-->>Client: Deleted document with metadata
|
|
486
|
-
* else Error
|
|
487
|
-
* PouchDB-->>PouchAdapter: Error
|
|
488
|
-
* PouchAdapter->>PouchAdapter: parseError(e)
|
|
489
|
-
* PouchAdapter-->>Client: Throws error
|
|
490
|
-
* end
|
|
491
|
-
*/
|
|
492
|
-
async delete(tableName, id) {
|
|
493
|
-
const _id = this.generateId(tableName, id);
|
|
494
|
-
let record;
|
|
495
|
-
try {
|
|
496
|
-
record = await this.client.get(_id);
|
|
497
|
-
await this.client.remove(_id, record._rev);
|
|
498
|
-
}
|
|
499
|
-
catch (e) {
|
|
500
|
-
throw PouchAdapter.parseError(e);
|
|
501
|
-
}
|
|
502
|
-
return this.assignMetadata(record, record._rev);
|
|
503
|
-
}
|
|
504
|
-
/**
|
|
505
|
-
* @description Deletes multiple documents from the database by their IDs
|
|
506
|
-
* @summary Removes multiple documents from the PouchDB database in a single operation.
|
|
507
|
-
* This method first retrieves all documents to get their revisions, then marks them as deleted.
|
|
508
|
-
* @param {string} tableName - The name of the table/collection
|
|
509
|
-
* @param {Array<string|number|bigint>} ids - The document IDs
|
|
510
|
-
* @return A promise that resolves to the deleted documents with metadata
|
|
511
|
-
* @mermaid
|
|
512
|
-
* sequenceDiagram
|
|
513
|
-
* participant Client
|
|
514
|
-
* participant PouchAdapter
|
|
515
|
-
* participant PouchDB
|
|
516
|
-
*
|
|
517
|
-
* Client->>PouchAdapter: deleteAll(tableName, ids)
|
|
518
|
-
* PouchAdapter->>PouchAdapter: Map ids to generateId(tableName, id)
|
|
519
|
-
* PouchAdapter->>PouchDB: bulkGet({docs})
|
|
520
|
-
* PouchDB-->>PouchAdapter: BulkGetResponse with documents
|
|
521
|
-
* PouchAdapter->>PouchAdapter: Mark documents as deleted
|
|
522
|
-
* PouchAdapter->>PouchDB: bulkDocs(marked documents)
|
|
523
|
-
* alt Success
|
|
524
|
-
* PouchDB-->>PouchAdapter: Success responses
|
|
525
|
-
* PouchAdapter->>PouchAdapter: Process results
|
|
526
|
-
* PouchAdapter->>PouchAdapter: assignMetadata for each doc
|
|
527
|
-
* PouchAdapter-->>Client: Deleted documents with metadata
|
|
528
|
-
* else Error
|
|
529
|
-
* PouchAdapter->>PouchAdapter: Check for errors
|
|
530
|
-
* PouchAdapter-->>Client: Throws InternalError
|
|
531
|
-
* end
|
|
532
|
-
*/
|
|
533
|
-
async deleteAll(tableName, ids) {
|
|
534
|
-
const results = await this.client.bulkGet({
|
|
535
|
-
docs: ids.map((id) => ({ id: this.generateId(tableName, id) })),
|
|
536
|
-
});
|
|
537
|
-
const deletion = await this.client.bulkDocs(results.results.map((r) => {
|
|
538
|
-
r[forCouchdb.CouchDBKeys.DELETED] = true;
|
|
539
|
-
return r;
|
|
540
|
-
}));
|
|
541
|
-
const errs = deletion.filter((d) => d.error);
|
|
542
|
-
if (errs.length)
|
|
543
|
-
throw new dbDecorators.InternalError(errs.join("\n"));
|
|
544
|
-
return results.results.reduce((accum, r) => {
|
|
545
|
-
r.docs.forEach((d) => {
|
|
546
|
-
const result = Object.assign({}, d.ok);
|
|
547
|
-
accum.push(this.assignMetadata(result, d.ok[forCouchdb.CouchDBKeys.REV]));
|
|
548
|
-
});
|
|
549
|
-
return accum;
|
|
550
|
-
}, []);
|
|
551
|
-
}
|
|
552
|
-
/**
|
|
553
|
-
* @description Executes a raw Mango query against the database
|
|
554
|
-
* @summary Performs a direct find operation using a Mango query object.
|
|
555
|
-
* This method allows for complex queries beyond the standard CRUD operations.
|
|
556
|
-
* @template V - The return type
|
|
557
|
-
* @param {MangoQuery} rawInput - The Mango query to execute
|
|
558
|
-
* @param {boolean} [process=true] - Whether to process the response (true returns just docs, false returns full response)
|
|
559
|
-
* @return {Promise<V>} A promise that resolves to the query results
|
|
560
|
-
* @mermaid
|
|
561
|
-
* sequenceDiagram
|
|
562
|
-
* participant Client
|
|
563
|
-
* participant PouchAdapter
|
|
564
|
-
* participant PouchDB
|
|
565
|
-
*
|
|
566
|
-
* Client->>PouchAdapter: raw<V>(rawInput, process)
|
|
567
|
-
* PouchAdapter->>PouchDB: find(rawInput)
|
|
568
|
-
* alt Success
|
|
569
|
-
* PouchDB-->>PouchAdapter: FindResponse
|
|
570
|
-
* alt process=true
|
|
571
|
-
* PouchAdapter-->>Client: response.docs as V
|
|
572
|
-
* else process=false
|
|
573
|
-
* PouchAdapter-->>Client: response as V
|
|
574
|
-
* end
|
|
575
|
-
* else Error
|
|
576
|
-
* PouchDB-->>PouchAdapter: Error
|
|
577
|
-
* PouchAdapter->>PouchAdapter: parseError(e)
|
|
578
|
-
* PouchAdapter-->>Client: Throws error
|
|
579
|
-
* end
|
|
580
|
-
*/
|
|
581
|
-
async raw(rawInput, process = true) {
|
|
582
|
-
try {
|
|
583
|
-
const response = await this.client.find(rawInput);
|
|
584
|
-
if (response.warning)
|
|
585
|
-
console.warn(response.warning);
|
|
586
|
-
if (process)
|
|
587
|
-
return response.docs;
|
|
588
|
-
return response;
|
|
589
|
-
}
|
|
590
|
-
catch (e) {
|
|
591
|
-
throw PouchAdapter.parseError(e);
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
/**
|
|
595
|
-
* @description Parses and converts errors from PouchDB to application-specific errors
|
|
596
|
-
* @summary Converts PouchDB errors to the application's error hierarchy.
|
|
597
|
-
* This instance method delegates to the static parseError method.
|
|
598
|
-
* @param {Error|string} err - The error object or message to parse
|
|
599
|
-
* @param {string} [reason] - Optional reason for the error
|
|
600
|
-
* @return {BaseError} The converted error object
|
|
601
|
-
*/
|
|
602
|
-
parseError(err, reason) {
|
|
603
|
-
return PouchAdapter.parseError(err, reason);
|
|
604
|
-
}
|
|
605
|
-
/**
|
|
606
|
-
* @description Static method to parse and convert errors from PouchDB to application-specific errors
|
|
607
|
-
* @summary Converts PouchDB errors to the application's error hierarchy based on error codes and messages.
|
|
608
|
-
* This method analyzes the error type, status code, or message to determine the appropriate error class.
|
|
609
|
-
* @param {Error|string} err - The error object or message to parse
|
|
610
|
-
* @param {string} [reason] - Optional reason for the error
|
|
611
|
-
* @return {BaseError} The converted error object
|
|
612
|
-
* @mermaid
|
|
613
|
-
* sequenceDiagram
|
|
614
|
-
* participant Caller
|
|
615
|
-
* participant PouchAdapter
|
|
616
|
-
*
|
|
617
|
-
* Caller->>PouchAdapter: parseError(err, reason)
|
|
618
|
-
* alt err is BaseError
|
|
619
|
-
* PouchAdapter-->>Caller: Return err as is
|
|
620
|
-
* else err is string
|
|
621
|
-
* alt contains "already exist" or "update conflict"
|
|
622
|
-
* PouchAdapter-->>Caller: ConflictError
|
|
623
|
-
* else contains "missing" or "deleted"
|
|
624
|
-
* PouchAdapter-->>Caller: NotFoundError
|
|
625
|
-
* end
|
|
626
|
-
* else err has status
|
|
627
|
-
* alt status is 401, 412, 409
|
|
628
|
-
* PouchAdapter-->>Caller: ConflictError
|
|
629
|
-
* else status is 404
|
|
630
|
-
* PouchAdapter-->>Caller: NotFoundError
|
|
631
|
-
* else status is 400
|
|
632
|
-
* alt message contains "No index exists"
|
|
633
|
-
* PouchAdapter-->>Caller: IndexError
|
|
634
|
-
* else
|
|
635
|
-
* PouchAdapter-->>Caller: InternalError
|
|
636
|
-
* end
|
|
637
|
-
* else message contains "ECONNREFUSED"
|
|
638
|
-
* PouchAdapter-->>Caller: ConnectionError
|
|
639
|
-
* else
|
|
640
|
-
* PouchAdapter-->>Caller: InternalError
|
|
641
|
-
* end
|
|
642
|
-
* end
|
|
643
|
-
*/
|
|
644
|
-
static parseError(err, reason) {
|
|
645
|
-
// return super.parseError(err, reason);
|
|
646
|
-
if (err instanceof dbDecorators.BaseError)
|
|
647
|
-
return err;
|
|
648
|
-
let code = "";
|
|
649
|
-
if (typeof err === "string") {
|
|
650
|
-
code = err;
|
|
651
|
-
if (code.match(/already exist|update conflict/g))
|
|
652
|
-
return new dbDecorators.ConflictError(code);
|
|
653
|
-
if (code.match(/missing|deleted/g))
|
|
654
|
-
return new dbDecorators.NotFoundError(code);
|
|
655
|
-
}
|
|
656
|
-
else if (err.status) {
|
|
657
|
-
code = err.status;
|
|
658
|
-
reason = reason || err.message;
|
|
659
|
-
}
|
|
660
|
-
else {
|
|
661
|
-
code = err.message;
|
|
662
|
-
}
|
|
663
|
-
switch (code.toString()) {
|
|
664
|
-
case "401":
|
|
665
|
-
case "412":
|
|
666
|
-
case "409":
|
|
667
|
-
return new dbDecorators.ConflictError(reason);
|
|
668
|
-
case "404":
|
|
669
|
-
return new dbDecorators.NotFoundError(reason);
|
|
670
|
-
case "400":
|
|
671
|
-
if (code.toString().match(/No\sindex\sexists/g))
|
|
672
|
-
return new forCouchdb.IndexError(err);
|
|
673
|
-
return new dbDecorators.InternalError(err);
|
|
674
|
-
default:
|
|
675
|
-
if (code.toString().match(/ECONNREFUSED/g))
|
|
676
|
-
return new core.ConnectionError(err);
|
|
677
|
-
return new dbDecorators.InternalError(err);
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
/**
|
|
681
|
-
* @description Sets up decorations for PouchDB-specific model properties
|
|
682
|
-
* @summary Configures decorators for createdBy and updatedBy fields in models.
|
|
683
|
-
* This method defines how these fields should be automatically populated during create and update operations.
|
|
684
|
-
* @mermaid
|
|
685
|
-
* sequenceDiagram
|
|
686
|
-
* participant Caller
|
|
687
|
-
* participant PouchAdapter
|
|
688
|
-
* participant Decoration
|
|
689
|
-
*
|
|
690
|
-
* Caller->>PouchAdapter: decoration()
|
|
691
|
-
* PouchAdapter->>Repository: key(PersistenceKeys.CREATED_BY)
|
|
692
|
-
* Repository-->>PouchAdapter: createdByKey
|
|
693
|
-
* PouchAdapter->>Repository: key(PersistenceKeys.UPDATED_BY)
|
|
694
|
-
* Repository-->>PouchAdapter: updatedByKey
|
|
695
|
-
*
|
|
696
|
-
* PouchAdapter->>Decoration: flavouredAs(PouchFlavour)
|
|
697
|
-
* Decoration-->>PouchAdapter: DecoratorBuilder
|
|
698
|
-
* PouchAdapter->>Decoration: for(createdByKey)
|
|
699
|
-
* PouchAdapter->>Decoration: define(onCreate, propMetadata)
|
|
700
|
-
* PouchAdapter->>Decoration: apply()
|
|
701
|
-
*
|
|
702
|
-
* PouchAdapter->>Decoration: flavouredAs(PouchFlavour)
|
|
703
|
-
* Decoration-->>PouchAdapter: DecoratorBuilder
|
|
704
|
-
* PouchAdapter->>Decoration: for(updatedByKey)
|
|
705
|
-
* PouchAdapter->>Decoration: define(onCreate, propMetadata)
|
|
706
|
-
* PouchAdapter->>Decoration: apply()
|
|
707
|
-
*/
|
|
708
|
-
static decoration() {
|
|
709
|
-
super.decoration();
|
|
710
|
-
const createdByKey = core.Repository.key(core.PersistenceKeys.CREATED_BY);
|
|
711
|
-
const updatedByKey = core.Repository.key(core.PersistenceKeys.UPDATED_BY);
|
|
712
|
-
decoratorValidation.Decoration.flavouredAs(PouchFlavour)
|
|
713
|
-
.for(createdByKey)
|
|
714
|
-
.define(dbDecorators.onCreate(createdByOnPouchCreateUpdate), decoratorValidation.propMetadata(createdByKey, {}))
|
|
715
|
-
.apply();
|
|
716
|
-
decoratorValidation.Decoration.flavouredAs(PouchFlavour)
|
|
717
|
-
.for(updatedByKey)
|
|
718
|
-
.define(dbDecorators.onCreateUpdate(createdByOnPouchCreateUpdate), decoratorValidation.propMetadata(updatedByKey, {}))
|
|
719
|
-
.apply();
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
PouchAdapter.setCurrent(PouchFlavour);
|
|
723
|
-
|
|
724
|
-
PouchAdapter.decoration();
|
|
725
|
-
/**
|
|
726
|
-
* @description A TypeScript adapter for PouchDB integration
|
|
727
|
-
* @summary Provides a repository-pattern implementation backed by PouchDB, exposing the {@link PouchAdapter} to interface with databases, the {@link PouchRepository} for typed data access, configuration {@link module:for-pouch|constants} like {@link PouchFlavour} and {@link DefaultLocalStoragePath}, and related {@link module:for-pouch|types}. This module wires up decorators on load to support created/updated-by fields.
|
|
728
|
-
* @module for-pouch
|
|
729
|
-
*/
|
|
730
|
-
/**
|
|
731
|
-
* @description Package version identifier
|
|
732
|
-
* @summary Stores the current version of the for-pouch package
|
|
733
|
-
* @const VERSION
|
|
734
|
-
* @memberOf module:for-pouch
|
|
735
|
-
*/
|
|
736
|
-
const VERSION = "0.2.13";
|
|
737
|
-
/**
|
|
738
|
-
* @description Package version identifier
|
|
739
|
-
* @summary Stores the current version of the for-pouch package
|
|
740
|
-
* @const VERSION
|
|
741
|
-
* @memberOf module:for-pouch
|
|
742
|
-
*/
|
|
743
|
-
const PACKAGE_NAME = "@decaf-ts/for-pouch";
|
|
744
|
-
decoration.Metadata.registerLibrary(PACKAGE_NAME, VERSION);
|
|
745
|
-
|
|
746
|
-
exports.DefaultLocalStoragePath = DefaultLocalStoragePath;
|
|
747
|
-
exports.PACKAGE_NAME = PACKAGE_NAME;
|
|
748
|
-
exports.PouchAdapter = PouchAdapter;
|
|
749
|
-
exports.PouchFlavour = PouchFlavour;
|
|
750
|
-
exports.VERSION = VERSION;
|
|
751
|
-
exports.createdByOnPouchCreateUpdate = createdByOnPouchCreateUpdate;
|
|
752
|
-
|
|
753
|
-
}));
|
|
754
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yLXBvdWNoLmNqcyIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbnN0YW50cy50cyIsIi4uL3NyYy9hZGFwdGVyLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGRlc2NyaXB0aW9uIElkZW50aWZpZXIgZm9yIFBvdWNoREIgZmxhdm9yIGluIHRoZSBkZWNvcmF0b3Igc3lzdGVtXG4gKiBAc3VtbWFyeSBBIHN0cmluZyBjb25zdGFudCB0aGF0IGlkZW50aWZpZXMgdGhlIFBvdWNoREIgaW1wbGVtZW50YXRpb24gaW4gdGhlIGRlY29yYXRvciBzeXN0ZW0uXG4gKiBUaGlzIGlzIHVzZWQgdG8gdGFyZ2V0IGRlY29yYXRvcnMgc3BlY2lmaWNhbGx5IGZvciBQb3VjaERCIGFkYXB0ZXJzLlxuICogQGNvbnN0IFBvdWNoRmxhdm91clxuICogQG1lbWJlck9mIG1vZHVsZTpmb3ItcG91Y2hcbiAqL1xuZXhwb3J0IGNvbnN0IFBvdWNoRmxhdm91ciA9IFwicG91Y2hcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVmYXVsdCByZWxhdGl2ZSBwYXRoIHdoZXJlIGxvY2FsIFBvdWNoREIgZGF0YWJhc2VzIGFyZSBzdG9yZWRcbiAqIEBzdW1tYXJ5IFVzZWQgd2hlbiBjcmVhdGluZyBhIGxvY2FsIFBvdWNoREIgaW5zdGFuY2Ugd2l0aG91dCBhIHJlbW90ZSBob3N0OyBjb21iaW5lZCB3aXRoIGRiTmFtZSB0byBmb3JtIHRoZSBmaWxlc3lzdGVtIHBhdGguXG4gKiBAY29uc3QgRGVmYXVsdExvY2FsU3RvcmFnZVBhdGhcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Zm9yLXBvdWNoXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0TG9jYWxTdG9yYWdlUGF0aCA9IFwibG9jYWxfZGJzXCI7XG4iLCJpbXBvcnQgXCJyZWZsZWN0LW1ldGFkYXRhXCI7XG5pbXBvcnQge1xuICBDb3VjaERCQWRhcHRlcixcbiAgQ291Y2hEQktleXMsXG4gIENyZWF0ZUluZGV4UmVxdWVzdCxcbiAgZ2VuZXJhdGVJbmRleGVzLFxuICBJbmRleEVycm9yLFxuICBNYW5nb1F1ZXJ5LFxufSBmcm9tIFwiQGRlY2FmLXRzL2Zvci1jb3VjaGRiXCI7XG5pbXBvcnQge1xuICBCYXNlRXJyb3IsXG4gIENvbmZsaWN0RXJyb3IsXG4gIENvbnRleHQsXG4gIEludGVybmFsRXJyb3IsXG4gIE5vdEZvdW5kRXJyb3IsXG4gIG9uQ3JlYXRlLFxuICBvbkNyZWF0ZVVwZGF0ZSxcbiAgT3BlcmF0aW9uS2V5cyxcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQge1xuICBDb25uZWN0aW9uRXJyb3IsXG4gIFBlcnNpc3RlbmNlS2V5cyxcbiAgUmVsYXRpb25zTWV0YWRhdGEsXG4gIFJlcG9zaXRvcnksXG4gIFVuc3VwcG9ydGVkRXJyb3IsXG59IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IERhdGFiYXNlID0gUG91Y2hEQi5EYXRhYmFzZTtcbmltcG9ydCBSZXNwb25zZSA9IFBvdWNoREIuQ29yZS5SZXNwb25zZTtcbmltcG9ydCBFcnIgPSBQb3VjaERCLkNvcmUuRXJyb3I7XG5pbXBvcnQgSWRNZXRhID0gUG91Y2hEQi5Db3JlLklkTWV0YTtcbmltcG9ydCBHZXRNZXRhID0gUG91Y2hEQi5Db3JlLkdldE1ldGE7XG5pbXBvcnQgQ3JlYXRlSW5kZXhSZXNwb25zZSA9IFBvdWNoREIuRmluZC5DcmVhdGVJbmRleFJlc3BvbnNlO1xuaW1wb3J0IHtcbiAgQ29uc3RydWN0b3IsXG4gIERlY29yYXRpb24sXG4gIE1vZGVsLFxuICBwcm9wTWV0YWRhdGEsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCBCdWxrR2V0UmVzcG9uc2UgPSBQb3VjaERCLkNvcmUuQnVsa0dldFJlc3BvbnNlO1xuaW1wb3J0IEZpbmRSZXNwb25zZSA9IFBvdWNoREIuRmluZC5GaW5kUmVzcG9uc2U7XG5pbXBvcnQgeyBQb3VjaENvbmZpZywgUG91Y2hGbGFncyB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBEZWZhdWx0TG9jYWxTdG9yYWdlUGF0aCwgUG91Y2hGbGF2b3VyIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBQb3VjaFJlcG9zaXRvcnkgfSBmcm9tIFwiLi9Qb3VjaFJlcG9zaXRvcnlcIjtcbmltcG9ydCBQb3VjaERCIGZyb20gXCJwb3VjaGRiLWNvcmVcIjtcbmltcG9ydCAqIGFzIFBvdWNoTWFwUmVkdWNlIGZyb20gXCJwb3VjaGRiLW1hcHJlZHVjZVwiO1xuaW1wb3J0ICogYXMgUG91Y2hSZXBsaWNhdGlvbiBmcm9tIFwicG91Y2hkYi1yZXBsaWNhdGlvblwiO1xuaW1wb3J0ICogYXMgUG91Y2hGaW5kIGZyb20gXCJwb3VjaGRiLWZpbmRcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgY3JlYXRvciBJRCBvbiBhIG1vZGVsIGR1cmluZyBjcmVhdGlvbiBvciB1cGRhdGUgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGFzIGEgZGVjb3JhdG9yIGhhbmRsZXIgdG8gYXV0b21hdGljYWxseSBzZXQgdGhlIGNyZWF0b3IgSUQgZmllbGQgb24gYSBtb2RlbFxuICogd2hlbiBpdCdzIGJlaW5nIGNyZWF0ZWQgb3IgdXBkYXRlZC4gSXQgZXh0cmFjdHMgdGhlIFVVSUQgZnJvbSB0aGUgY29udGV4dCBhbmQgYXNzaWducyBpdCB0byB0aGUgc3BlY2lmaWVkIGtleS5cbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgdGhhdCBleHRlbmRzIE1vZGVsXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSByZXBvc2l0b3J5IHR5cGUgdGhhdCBleHRlbmRzIFBvdWNoUmVwb3NpdG9yeTxNPlxuICogQHRlbXBsYXRlIFYgLSBUaGUgcmVsYXRpb25zIG1ldGFkYXRhIHR5cGUgdGhhdCBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhXG4gKiBAcGFyYW0ge1J9IHRoaXMgLSBUaGUgcmVwb3NpdG9yeSBpbnN0YW5jZVxuICogQHBhcmFtIHtDb250ZXh0PFBvdWNoRmxhZ3M+fSBjb250ZXh0IC0gVGhlIG9wZXJhdGlvbiBjb250ZXh0IGNvbnRhaW5pbmcgZmxhZ3NcbiAqIEBwYXJhbSB7Vn0gZGF0YSAtIFRoZSByZWxhdGlvbnMgbWV0YWRhdGFcbiAqIEBwYXJhbSBrZXkgLSBUaGUgcHJvcGVydHkga2V5IHRvIHNldCBvbiB0aGUgbW9kZWxcbiAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UgdG8gbW9kaWZ5XG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBvcGVyYXRpb24gaXMgY29tcGxldGVcbiAqIEBmdW5jdGlvbiBjcmVhdGVkQnlPblBvdWNoQ3JlYXRlVXBkYXRlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmZvci1wb3VjaFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlZEJ5T25Qb3VjaENyZWF0ZVVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUG91Y2hSZXBvc2l0b3J5PE0+LFxuICBWIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4+KFxuICB0aGlzOiBSLFxuICBjb250ZXh0OiBDb250ZXh0PFBvdWNoRmxhZ3M+LFxuICBkYXRhOiBWLFxuICBrZXk6IGtleW9mIE0sXG4gIG1vZGVsOiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCB1dWlkOiBzdHJpbmcgPSBjb250ZXh0LmdldChcIlVVSURcIik7XG4gICAgbW9kZWxba2V5XSA9IHV1aWQgYXMgTVtrZXlvZiBNXTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRFcnJvcihcbiAgICAgIFwiTm8gVXNlciBmb3VuZCBpbiBjb250ZXh0LiBQbGVhc2UgcHJvdmlkZSBhIHVzZXIgaW4gdGhlIGNvbnRleHRcIlxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUG91Y2hEQiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgQ291Y2hEQkFkYXB0ZXJcbiAqIEBzdW1tYXJ5IENvbmNyZXRlIGFkYXB0ZXIgdGhhdCBicmlkZ2VzIHRoZSBnZW5lcmljIENvdWNoREJBZGFwdGVyIHRvIGEgUG91Y2hEQiBiYWNrZW5kLiBJdCBzdXBwb3J0cyBDUlVEIChzaW5nbGUgYW5kIGJ1bGspLCBpbmRleGluZyBhbmQgTWFuZ28gcXVlcmllcywgYW5kIHdpcmVzIGZsYXZvdXItc3BlY2lmaWMgZGVjb3JhdGlvbnMuXG4gKiBAdGVtcGxhdGUgUG91Y2hGbGFncyAtIFRoZSBmbGFncyBzcGVjaWZpYyB0byBQb3VjaERCIG9wZXJhdGlvbnNcbiAqIEB0ZW1wbGF0ZSBDb250ZXh0PFBvdWNoRmxhZ3M+IC0gVGhlIGNvbnRleHQgdHlwZSB3aXRoIFBvdWNoREIgZmxhZ3NcbiAqIEBwYXJhbSB7UG91Y2hDb25maWd9IGNvbmZpZyAtIEFkYXB0ZXIgY29uZmlndXJhdGlvbiAocmVtb3RlIGNyZWRlbnRpYWxzIG9yIGxvY2FsIHN0b3JhZ2UgcGF0aCwgZGIgbmFtZSwgcGx1Z2lucylcbiAqIEBwYXJhbSB7c3RyaW5nfSBbYWxpYXNdIC0gT3B0aW9uYWwgYWxpYXMgZm9yIHRoZSBkYXRhYmFzZVxuICogQGNsYXNzIFBvdWNoQWRhcHRlclxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IFBvdWNoQWRhcHRlciB9IGZyb20gJ0BkZWNhZi10cy9mb3ItcG91Y2gnO1xuICpcbiAqIC8vIENyZWF0ZSBhIFBvdWNoQWRhcHRlciB3aXRoIGNvbmZpZ1xuICogY29uc3QgYWRhcHRlciA9IG5ldyBQb3VjaEFkYXB0ZXIoe1xuICogICBwcm90b2NvbDogJ2h0dHAnLFxuICogICBob3N0OiAnbG9jYWxob3N0OjU5ODQnLFxuICogICB1c2VyOiAnYWRtaW4nLFxuICogICBwYXNzd29yZDogJ3NlY3JldCcsXG4gKiAgIGRiTmFtZTogJ215LWRhdGFiYXNlJyxcbiAqICAgcGx1Z2luczogW11cbiAqIH0pO1xuICpcbiAqIC8vIE9yIHVzZSBsb2NhbCBzdG9yYWdlXG4gKiBjb25zdCBsb2NhbEFkYXB0ZXIgPSBuZXcgUG91Y2hBZGFwdGVyKHtcbiAqICAgcHJvdG9jb2w6ICdodHRwJywgLy8gaWdub3JlZCBmb3IgbG9jYWxcbiAqICAgZGJOYW1lOiAnbG9jYWwtZGInLFxuICogICBzdG9yYWdlUGF0aDogJ2xvY2FsX2RicycsXG4gKiAgIHBsdWdpbnM6IFtdXG4gKiB9KTtcbiAqXG4gKiAvLyBVc2UgdGhlIGFkYXB0ZXIgZm9yIGRhdGFiYXNlIG9wZXJhdGlvbnNcbiAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGFkYXB0ZXIucmVhZCgndXNlcnMnLCAndXNlci0xMjMnKTtcbiAqIGBgYFxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgUG91Y2hBZGFwdGVyXG4gKiAgIHBhcnRpY2lwYW50IFBvdWNoREJcbiAqICAgcGFydGljaXBhbnQgQ291Y2hEQlxuICpcbiAqICAgQ2xpZW50LT4+UG91Y2hBZGFwdGVyOiBuZXcgUG91Y2hBZGFwdGVyKGNvbmZpZywgYWxpYXM/KVxuICogICBQb3VjaEFkYXB0ZXItPj5Db3VjaERCQWRhcHRlcjogc3VwZXIoY29uZmlnLCBQb3VjaEZsYXZvdXIsIGFsaWFzKVxuICpcbiAqICAgQ2xpZW50LT4+UG91Y2hBZGFwdGVyOiBjcmVhdGUodGFibGUsIGlkLCBtb2RlbClcbiAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogcHV0KG1vZGVsKVxuICogICBQb3VjaERCLT4+Q291Y2hEQjogSFRUUCBQVVRcbiAqICAgQ291Y2hEQi0tPj5Qb3VjaERCOiBSZXNwb25zZVxuICogICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogUmVzcG9uc2VcbiAqICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogVXBkYXRlZCBtb2RlbFxuICpcbiAqICAgQ2xpZW50LT4+UG91Y2hBZGFwdGVyOiByZWFkKHRhYmxlLCBpZClcbiAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogZ2V0KGlkKVxuICogICBQb3VjaERCLT4+Q291Y2hEQjogSFRUUCBHRVRcbiAqICAgQ291Y2hEQi0tPj5Qb3VjaERCOiBEb2N1bWVudFxuICogICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogRG9jdW1lbnRcbiAqICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogTW9kZWxcbiAqL1xuZXhwb3J0IGNsYXNzIFBvdWNoQWRhcHRlciBleHRlbmRzIENvdWNoREJBZGFwdGVyPFxuICBQb3VjaENvbmZpZyxcbiAgRGF0YWJhc2UsXG4gIFBvdWNoRmxhZ3MsXG4gIENvbnRleHQ8UG91Y2hGbGFncz5cbj4ge1xuICBjb25zdHJ1Y3Rvcihjb25maWc6IFBvdWNoQ29uZmlnLCBhbGlhcz86IHN0cmluZykge1xuICAgIHN1cGVyKGNvbmZpZywgUG91Y2hGbGF2b3VyLCBhbGlhcyk7XG4gIH1cblxuLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMYXppbHkgaW5pdGlhbGl6ZXMgYW5kIHJldHVybnMgdGhlIHVuZGVybHlpbmcgUG91Y2hEQiBjbGllbnRcbiAgICogQHN1bW1hcnkgTG9hZHMgcmVxdWlyZWQgUG91Y2hEQiBwbHVnaW5zIG9uY2UsIGJ1aWxkcyB0aGUgY29ubmVjdGlvbiBVUkwgb3IgbG9jYWwgc3RvcmFnZSBwYXRoIGZyb20gY29uZmlnLCBhbmQgY2FjaGVzIHRoZSBEYXRhYmFzZSBpbnN0YW5jZSBmb3IgcmV1c2UuIFRocm93cyBJbnRlcm5hbEVycm9yIGlmIGNsaWVudCBjcmVhdGlvbiBmYWlscy5cbiAgICogQHJldHVybiB7RGF0YWJhc2V9IEEgUG91Y2hEQiBEYXRhYmFzZSBpbnN0YW5jZSByZWFkeSB0byBwZXJmb3JtIG9wZXJhdGlvbnNcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hBZGFwdGVyXG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hEQlxuICAgKiAgIENhbGxlci0+PlBvdWNoQWRhcHRlcjogZ2V0Q2xpZW50KClcbiAgICogICBhbHQgY2xpZW50IG5vdCBpbml0aWFsaXplZFxuICAgKiAgICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiByZWdpc3RlciBwbHVnaW5zXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaERCOiBuZXcgUG91Y2hEQih1cmwgb3IgcGF0aClcbiAgICogICAgIGFsdCBjcmVhdGlvbiBmYWlsc1xuICAgKiAgICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogRXJyb3JcbiAgICogICAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogdGhyb3dzIEludGVybmFsRXJyb3JcbiAgICogICAgIGVsc2Ugc3VjY2Vzc1xuICAgKiAgICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogRGF0YWJhc2VcbiAgICogICAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogY2FjaGVkIGNsaWVudFxuICAgKiAgICAgZW5kXG4gICAqICAgZWxzZSBjbGllbnQgaW5pdGlhbGl6ZWRcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DYWxsZXI6IGNhY2hlZCBjbGllbnRcbiAgICogICBlbmRcbiAgICovXG4gIG92ZXJyaWRlIGdldENsaWVudCgpOiBEYXRhYmFzZSB7XG4gICAgaWYgKCF0aGlzLl9jbGllbnQpIHtcbiAgICAgIGNvbnN0IHBsdWdpbnMgPSBbXG4gICAgICAgIFBvdWNoTWFwUmVkdWNlLFxuICAgICAgICBQb3VjaFJlcGxpY2F0aW9uLFxuICAgICAgICBQb3VjaEZpbmQsXG4gICAgICAgIC4uLnRoaXMuY29uZmlnLnBsdWdpbnMsXG4gICAgICBdO1xuICAgICAgZm9yIChjb25zdCBwbHVnaW4gb2YgcGx1Z2lucykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIFBvdWNoREIucGx1Z2luKHBsdWdpbik7XG4gICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgRXJyb3IgJiYgZS5tZXNzYWdlLmluY2x1ZGVzKFwicmVkZWZpbmUgcHJvcGVydHlcIikpXG4gICAgICAgICAgICBjb250aW51ZTsgLy9wbHVnaW4gaGFzIGFscmVhZHkgYmVlbiBsb2FkZWQgc28gaXQncyBva1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgeyBob3N0LCBwcm90b2NvbCwgdXNlciwgcGFzc3dvcmQsIGRiTmFtZSwgc3RvcmFnZVBhdGggfSA9XG4gICAgICAgIHRoaXMuY29uZmlnO1xuXG4gICAgICB0cnkge1xuICAgICAgICBpZiAoaG9zdCAmJiB1c2VyKSB7XG4gICAgICAgICAgdGhpcy5fY2xpZW50ID0gbmV3IFBvdWNoREIoXG4gICAgICAgICAgICBgJHtwcm90b2NvbH06Ly8ke3VzZXJ9OiR7cGFzc3dvcmR9QCR7aG9zdH0vJHtkYk5hbWV9YFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZVxuICAgICAgICAgIHRoaXMuX2NsaWVudCA9IG5ldyBQb3VjaERCKFxuICAgICAgICAgICAgYCR7c3RvcmFnZVBhdGggfHwgRGVmYXVsdExvY2FsU3RvcmFnZVBhdGh9LyR7ZGJOYW1lfWBcbiAgICAgICAgICApO1xuICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBQb3VjaERCIGNsaWVudDogJHtlfWApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY2xpZW50IGFzIERhdGFiYXNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZW5lcmF0ZXMgb3BlcmF0aW9uIGZsYWdzIGZvciBQb3VjaERCIG9wZXJhdGlvbnNcbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIHNldCBvZiBmbGFncyBmb3IgYSBzcGVjaWZpYyBvcGVyYXRpb24sIGluY2x1ZGluZyBhIFVVSUQgZm9yIGlkZW50aWZpY2F0aW9uLlxuICAgKiBUaGlzIG1ldGhvZCBleHRyYWN0cyB0aGUgdXNlciBJRCBmcm9tIHRoZSBkYXRhYmFzZSBVUkwgb3IgZ2VuZXJhdGVzIGEgcmFuZG9tIFVVSUQgaWYgbm90IGF2YWlsYWJsZS5cbiAgICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZSB0aGF0IGV4dGVuZHMgTW9kZWxcbiAgICogQHBhcmFtIHtPcGVyYXRpb25LZXlzfSBvcGVyYXRpb24gLSBUaGUgb3BlcmF0aW9uIGtleSAoY3JlYXRlLCByZWFkLCB1cGRhdGUsIGRlbGV0ZSlcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgLSBUaGUgbW9kZWwgY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtQYXJ0aWFsPFBvdWNoRmxhZ3M+fSBmbGFncyAtIFBhcnRpYWwgZmxhZ3MgdG8gYmUgbWVyZ2VkXG4gICAqIEByZXR1cm4ge1Byb21pc2U8UG91Y2hGbGFncz59IFRoZSBjb21wbGV0ZSBzZXQgb2YgZmxhZ3MgZm9yIHRoZSBvcGVyYXRpb25cbiAgICovXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyBmbGFnczxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIG9wZXJhdGlvbjogT3BlcmF0aW9uS2V5cyxcbiAgICBtb2RlbDogQ29uc3RydWN0b3I8TT4sXG4gICAgZmxhZ3M6IFBhcnRpYWw8UG91Y2hGbGFncz5cbiAgKTogUHJvbWlzZTxQb3VjaEZsYWdzPiB7XG4gICAgaWYgKCF0aGlzLmNvbmZpZy51c2VyKSB0aGlzLmNvbmZpZy51c2VyID0gY3J5cHRvLnJhbmRvbVVVSUQoKTtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihhd2FpdCBzdXBlci5mbGFncyhvcGVyYXRpb24sIG1vZGVsLCBmbGFncyksIHtcbiAgICAgIFVVSUQ6IHRoaXMuY29uZmlnLnVzZXIsXG4gICAgfSkgYXMgUG91Y2hGbGFncztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBkYXRhYmFzZSBpbmRleGVzIGZvciB0aGUgZ2l2ZW4gbW9kZWxzXG4gICAqIEBzdW1tYXJ5IEdlbmVyYXRlcyBhbmQgY3JlYXRlcyBpbmRleGVzIGluIHRoZSBQb3VjaERCIGRhdGFiYXNlIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBtb2RlbCBjb25zdHJ1Y3RvcnMuXG4gICAqIFRoaXMgbWV0aG9kIHVzZXMgdGhlIGdlbmVyYXRlSW5kZXhlcyB1dGlsaXR5IHRvIGNyZWF0ZSBpbmRleCBkZWZpbml0aW9ucyBhbmQgdGhlbiBjcmVhdGVzIHRoZW0gaW4gdGhlIGRhdGFiYXNlLlxuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIHRoYXQgZXh0ZW5kcyBNb2RlbFxuICAgKiBAcGFyYW0gbW9kZWxzIC0gVGhlIG1vZGVsIGNvbnN0cnVjdG9ycyB0byBjcmVhdGUgaW5kZXhlcyBmb3JcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgaW5kZXhlcyBhcmUgY3JlYXRlZFxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGluZGV4PE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgLi4ubW9kZWxzOiBDb25zdHJ1Y3RvcjxNPltdXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGluZGV4ZXM6IENyZWF0ZUluZGV4UmVxdWVzdFtdID0gZ2VuZXJhdGVJbmRleGVzKG1vZGVscyk7XG4gICAgZm9yIChjb25zdCBpbmRleCBvZiBpbmRleGVzKSB7XG4gICAgICBjb25zdCByZXM6IENyZWF0ZUluZGV4UmVzcG9uc2U8YW55PiA9IGF3YWl0IHRoaXMuY2xpZW50LmNyZWF0ZUluZGV4KFxuICAgICAgICBpbmRleCBhcyBhbnlcbiAgICAgICk7XG4gICAgICBjb25zdCB7IHJlc3VsdCB9ID0gcmVzO1xuICAgICAgaWYgKHJlc3VsdCA9PT0gXCJleGlzdGluZ1wiKVxuICAgICAgICB0aHJvdyBuZXcgQ29uZmxpY3RFcnJvcihgSW5kZXggJHtpbmRleC5uYW1lfSBhbHJlYWR5IGV4aXN0c2ApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIG5ldyBkb2N1bWVudCBpbiB0aGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgSW5zZXJ0cyBhIG5ldyBkb2N1bWVudCBpbnRvIHRoZSBQb3VjaERCIGRhdGFiYXNlIHVzaW5nIHRoZSBwdXQgb3BlcmF0aW9uLlxuICAgKiBUaGlzIG1ldGhvZCBoYW5kbGVzIGVycm9yIHBhcnNpbmcgYW5kIGVuc3VyZXMgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gaWQgLSBUaGUgZG9jdW1lbnQgSURcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBtb2RlbCAtIFRoZSBkb2N1bWVudCBkYXRhIHRvIGluc2VydFxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgY3JlYXRlZCBkb2N1bWVudCB3aXRoIG1ldGFkYXRhXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoREJcbiAgICpcbiAgICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IGNyZWF0ZSh0YWJsZU5hbWUsIGlkLCBtb2RlbClcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaERCOiBwdXQobW9kZWwpXG4gICAqICAgYWx0IFN1Y2Nlc3NcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBSZXNwb25zZSB3aXRoIG9rPXRydWVcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogYXNzaWduTWV0YWRhdGEobW9kZWwsIHJlc3BvbnNlLnJldilcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IFVwZGF0ZWQgbW9kZWwgd2l0aCBtZXRhZGF0YVxuICAgKiAgIGVsc2UgRXJyb3JcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBFcnJvclxuICAgKiAgICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBwYXJzZUVycm9yKGUpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBUaHJvd3MgZXJyb3JcbiAgICogICBlbmRcbiAgICovXG4gIGFzeW5jIGNyZWF0ZShcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICAgIGxldCByZXNwb25zZTogUmVzcG9uc2U7XG4gICAgdHJ5IHtcbiAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy5jbGllbnQucHV0KG1vZGVsKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyB0aGlzLnBhcnNlRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgfVxuXG4gICAgaWYgKCFyZXNwb25zZS5vaylcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGluc2VydCBkb2MgaWQ6ICR7aWR9IGluIHRhYmxlICR7dGFibGVOYW1lfWBcbiAgICAgICk7XG4gICAgcmV0dXJuIHRoaXMuYXNzaWduTWV0YWRhdGEobW9kZWwsIHJlc3BvbnNlLnJldik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgbXVsdGlwbGUgZG9jdW1lbnRzIGluIHRoZSBkYXRhYmFzZSBpbiBhIHNpbmdsZSBvcGVyYXRpb25cbiAgICogQHN1bW1hcnkgSW5zZXJ0cyBtdWx0aXBsZSBkb2N1bWVudHMgaW50byB0aGUgUG91Y2hEQiBkYXRhYmFzZSB1c2luZyB0aGUgYnVsa0RvY3Mgb3BlcmF0aW9uLlxuICAgKiBUaGlzIG1ldGhvZCBoYW5kbGVzIGVycm9yIHBhcnNpbmcgYW5kIGVuc3VyZXMgYWxsIG9wZXJhdGlvbnMgd2VyZSBzdWNjZXNzZnVsLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlL2NvbGxlY3Rpb25cbiAgICogQHBhcmFtIHtzdHJpbmdbXXxudW1iZXJbXX0gaWRzIC0gVGhlIGRvY3VtZW50IElEc1xuICAgKiBAcGFyYW0gIG1vZGVscyAtIFRoZSBkb2N1bWVudCBkYXRhIHRvIGluc2VydFxuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBjcmVhdGVkIGRvY3VtZW50cyB3aXRoIG1ldGFkYXRhXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoREJcbiAgICpcbiAgICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IGNyZWF0ZUFsbCh0YWJsZU5hbWUsIGlkcywgbW9kZWxzKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PlBvdWNoREI6IGJ1bGtEb2NzKG1vZGVscylcbiAgICogICBhbHQgU3VjY2Vzc1xuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IEFycmF5IG9mIHJlc3BvbnNlcyB3aXRoIG9rPXRydWVcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogYXNzaWduTXVsdGlwbGVNZXRhZGF0YShtb2RlbHMsIHJldnMpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBVcGRhdGVkIG1vZGVscyB3aXRoIG1ldGFkYXRhXG4gICAqICAgZWxzZSBFcnJvclxuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IEFycmF5IHdpdGggZXJyb3JzXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IENoZWNrIGZvciBlcnJvcnNcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IFRocm93cyBJbnRlcm5hbEVycm9yXG4gICAqICAgZW5kXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyBjcmVhdGVBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWRzOiBzdHJpbmdbXSB8IG51bWJlcltdLFxuICAgIG1vZGVsczogUmVjb3JkPHN0cmluZywgYW55PltdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPiB7XG4gICAgbGV0IHJlc3BvbnNlOiBSZXNwb25zZVtdIHwgRXJyW107XG4gICAgdHJ5IHtcbiAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy5jbGllbnQuYnVsa0RvY3MobW9kZWxzKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IFBvdWNoQWRhcHRlci5wYXJzZUVycm9yKGUpO1xuICAgIH1cbiAgICBpZiAoIXJlc3BvbnNlLmV2ZXJ5KChyOiBSZXNwb25zZSB8IEVycikgPT4gKHIgYXMgUmVzcG9uc2UpLm9rKSkge1xuICAgICAgY29uc3QgZXJyb3JzID0gcmVzcG9uc2UucmVkdWNlKChhY2N1bTogc3RyaW5nW10sIGVsLCBpKSA9PiB7XG4gICAgICAgIGlmIChlbC5lcnJvcilcbiAgICAgICAgICBhY2N1bS5wdXNoKFxuICAgICAgICAgICAgYGVsICR7aX06ICR7ZWwuZXJyb3J9JHtlbC5yZWFzb24gPyBgIC0gJHtlbC5yZWFzb259YCA6IFwiXCJ9YFxuICAgICAgICAgICk7XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0sIFtdKTtcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGVycm9ycy5qb2luKFwiXFxuXCIpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5hc3NpZ25NdWx0aXBsZU1ldGFkYXRhKFxuICAgICAgbW9kZWxzLFxuICAgICAgcmVzcG9uc2UubWFwKChyKSA9PiByLnJldiBhcyBzdHJpbmcpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgZG9jdW1lbnQgZnJvbSB0aGUgZGF0YWJhc2UgYnkgSURcbiAgICogQHN1bW1hcnkgRmV0Y2hlcyBhIGRvY3VtZW50IGZyb20gdGhlIFBvdWNoREIgZGF0YWJhc2UgdXNpbmcgdGhlIGdldCBvcGVyYXRpb24uXG4gICAqIFRoaXMgbWV0aG9kIGdlbmVyYXRlcyB0aGUgZG9jdW1lbnQgSUQgYmFzZWQgb24gdGhlIHRhYmxlIG5hbWUgYW5kIElELCB0aGVuIHJldHJpZXZlcyB0aGUgZG9jdW1lbnQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUvY29sbGVjdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGlkIC0gVGhlIGRvY3VtZW50IElEXG4gICAqIEByZXR1cm4ge1Byb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSByZXRyaWV2ZWQgZG9jdW1lbnQgd2l0aCBtZXRhZGF0YVxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaEFkYXB0ZXJcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaERCXG4gICAqXG4gICAqICAgQ2xpZW50LT4+UG91Y2hBZGFwdGVyOiByZWFkKHRhYmxlTmFtZSwgaWQpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBnZW5lcmF0ZUlkKHRhYmxlTmFtZSwgaWQpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogZ2V0KF9pZClcbiAgICogICBhbHQgU3VjY2Vzc1xuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IERvY3VtZW50XG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IGFzc2lnbk1ldGFkYXRhKHJlY29yZCwgcmVjb3JkLl9yZXYpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBEb2N1bWVudCB3aXRoIG1ldGFkYXRhXG4gICAqICAgZWxzZSBFcnJvclxuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IEVycm9yXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IHBhcnNlRXJyb3IoZSlcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IFRocm93cyBlcnJvclxuICAgKiAgIGVuZFxuICAgKi9cbiAgYXN5bmMgcmVhZChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICAgIGNvbnN0IF9pZCA9IHRoaXMuZ2VuZXJhdGVJZCh0YWJsZU5hbWUsIGlkKTtcbiAgICBsZXQgcmVjb3JkOiBJZE1ldGEgJiBHZXRNZXRhO1xuICAgIHRyeSB7XG4gICAgICByZWNvcmQgPSBhd2FpdCB0aGlzLmNsaWVudC5nZXQoX2lkKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IFBvdWNoQWRhcHRlci5wYXJzZUVycm9yKGUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5hc3NpZ25NZXRhZGF0YShyZWNvcmQsIHJlY29yZC5fcmV2KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG11bHRpcGxlIGRvY3VtZW50cyBmcm9tIHRoZSBkYXRhYmFzZSBieSB0aGVpciBJRHNcbiAgICogQHN1bW1hcnkgRmV0Y2hlcyBtdWx0aXBsZSBkb2N1bWVudHMgZnJvbSB0aGUgUG91Y2hEQiBkYXRhYmFzZSB1c2luZyB0aGUgYnVsa0dldCBvcGVyYXRpb24uXG4gICAqIFRoaXMgbWV0aG9kIGdlbmVyYXRlcyBkb2N1bWVudCBJRHMgYmFzZWQgb24gdGhlIHRhYmxlIG5hbWUgYW5kIElEcywgdGhlbiByZXRyaWV2ZXMgdGhlIGRvY3VtZW50cy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nfG51bWJlcnxiaWdpbnQ+fSBpZHMgLSBUaGUgZG9jdW1lbnQgSURzXG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHJldHJpZXZlZCBkb2N1bWVudHMgd2l0aCBtZXRhZGF0YVxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaEFkYXB0ZXJcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaERCXG4gICAqXG4gICAqICAgQ2xpZW50LT4+UG91Y2hBZGFwdGVyOiByZWFkQWxsKHRhYmxlTmFtZSwgaWRzKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogTWFwIGlkcyB0byBnZW5lcmF0ZUlkKHRhYmxlTmFtZSwgaWQpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogYnVsa0dldCh7ZG9jc30pXG4gICAqICAgYWx0IFN1Y2Nlc3NcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBCdWxrR2V0UmVzcG9uc2VcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogUHJvY2VzcyByZXN1bHRzXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IGFzc2lnbk1ldGFkYXRhIGZvciBlYWNoIGRvY1xuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogRG9jdW1lbnRzIHdpdGggbWV0YWRhdGFcbiAgICogICBlbHNlIEVycm9yXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IHBhcnNlRXJyb3IoZXJyb3IpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBUaHJvd3MgZXJyb3JcbiAgICogICBlbmRcbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIHJlYWRBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWRzOiAoc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50KVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPiB7XG4gICAgY29uc3QgcmVzdWx0czogQnVsa0dldFJlc3BvbnNlPGFueT4gPSBhd2FpdCB0aGlzLmNsaWVudC5idWxrR2V0KHtcbiAgICAgIGRvY3M6IGlkcy5tYXAoKGlkKSA9PiAoeyBpZDogdGhpcy5nZW5lcmF0ZUlkKHRhYmxlTmFtZSwgaWQgYXMgYW55KSB9KSksXG4gICAgfSk7XG4gICAgY29uc3QgcmVzID0gcmVzdWx0cy5yZXN1bHRzLnJlZHVjZSgoYWNjdW06IGFueVtdLCByKSA9PiB7XG4gICAgICByLmRvY3MuZm9yRWFjaCgoZCkgPT4ge1xuICAgICAgICBpZiAoKGQgYXMgYW55KS5lcnJvciB8fCAhKGQgYXMgYW55KS5vaylcbiAgICAgICAgICB0aHJvdyBQb3VjaEFkYXB0ZXIucGFyc2VFcnJvcihcbiAgICAgICAgICAgICgoZCBhcyB7IGVycm9yOiBFcnIgfSkuZXJyb3IgYXMgRXJyb3IpIHx8XG4gICAgICAgICAgICAgIG5ldyBJbnRlcm5hbEVycm9yKFwiTWlzc2luZyB2YWxpZCByZXNwb25zZVwiKVxuICAgICAgICAgICk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IE9iamVjdC5hc3NpZ24oe30sIChkIGFzIHsgb2s6IGFueSB9KS5vayk7XG4gICAgICAgIGFjY3VtLnB1c2godGhpcy5hc3NpZ25NZXRhZGF0YShyZXN1bHQsIChkIGFzIGFueSkub2tbQ291Y2hEQktleXMuUkVWXSkpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSwgW10pO1xuXG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVXBkYXRlcyBhbiBleGlzdGluZyBkb2N1bWVudCBpbiB0aGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgVXBkYXRlcyBhIGRvY3VtZW50IGluIHRoZSBQb3VjaERCIGRhdGFiYXNlIHVzaW5nIHRoZSBwdXQgb3BlcmF0aW9uLlxuICAgKiBUaGlzIG1ldGhvZCBoYW5kbGVzIGVycm9yIHBhcnNpbmcgYW5kIGVuc3VyZXMgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gaWQgLSBUaGUgZG9jdW1lbnQgSURcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBtb2RlbCAtIFRoZSB1cGRhdGVkIGRvY3VtZW50IGRhdGFcbiAgICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHVwZGF0ZWQgZG9jdW1lbnQgd2l0aCBtZXRhZGF0YVxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaEFkYXB0ZXJcbiAgICogICBwYXJ0aWNpcGFudCBQb3VjaERCXG4gICAqXG4gICAqICAgQ2xpZW50LT4+UG91Y2hBZGFwdGVyOiB1cGRhdGUodGFibGVOYW1lLCBpZCwgbW9kZWwpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogcHV0KG1vZGVsKVxuICAgKiAgIGFsdCBTdWNjZXNzXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogUmVzcG9uc2Ugd2l0aCBvaz10cnVlXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IGFzc2lnbk1ldGFkYXRhKG1vZGVsLCByZXNwb25zZS5yZXYpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBVcGRhdGVkIG1vZGVsIHdpdGggbWV0YWRhdGFcbiAgICogICBlbHNlIEVycm9yXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogRXJyb3JcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogcGFyc2VFcnJvcihlKVxuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogVGhyb3dzIGVycm9yXG4gICAqICAgZW5kXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyB1cGRhdGUoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlcixcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PlxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+IHtcbiAgICBsZXQgcmVzcG9uc2U6IFJlc3BvbnNlO1xuICAgIHRyeSB7XG4gICAgICByZXNwb25zZSA9IGF3YWl0IHRoaXMuY2xpZW50LnB1dChtb2RlbCk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBQb3VjaEFkYXB0ZXIucGFyc2VFcnJvcihlKTtcbiAgICB9XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gdXBkYXRlIGRvYyBpZDogJHtpZH0gaW4gdGFibGUgJHt0YWJsZU5hbWV9YFxuICAgICAgKTtcbiAgICByZXR1cm4gdGhpcy5hc3NpZ25NZXRhZGF0YShtb2RlbCwgcmVzcG9uc2UucmV2KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVXBkYXRlcyBtdWx0aXBsZSBkb2N1bWVudHMgaW4gdGhlIGRhdGFiYXNlIGluIGEgc2luZ2xlIG9wZXJhdGlvblxuICAgKiBAc3VtbWFyeSBVcGRhdGVzIG11bHRpcGxlIGRvY3VtZW50cyBpbiB0aGUgUG91Y2hEQiBkYXRhYmFzZSB1c2luZyB0aGUgYnVsa0RvY3Mgb3BlcmF0aW9uLlxuICAgKiBUaGlzIG1ldGhvZCBoYW5kbGVzIGVycm9yIHBhcnNpbmcgYW5kIGVuc3VyZXMgYWxsIG9wZXJhdGlvbnMgd2VyZSBzdWNjZXNzZnVsLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlL2NvbGxlY3Rpb25cbiAgICogQHBhcmFtIHtzdHJpbmdbXXxudW1iZXJbXX0gaWRzIC0gVGhlIGRvY3VtZW50IElEc1xuICAgKiBAcGFyYW0gbW9kZWxzIC0gVGhlIHVwZGF0ZWQgZG9jdW1lbnQgZGF0YVxuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSB1cGRhdGVkIGRvY3VtZW50cyB3aXRoIG1ldGFkYXRhXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoREJcbiAgICpcbiAgICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IHVwZGF0ZUFsbCh0YWJsZU5hbWUsIGlkcywgbW9kZWxzKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PlBvdWNoREI6IGJ1bGtEb2NzKG1vZGVscylcbiAgICogICBhbHQgU3VjY2Vzc1xuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IEFycmF5IG9mIHJlc3BvbnNlcyB3aXRoIG9rPXRydWVcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogYXNzaWduTXVsdGlwbGVNZXRhZGF0YShtb2RlbHMsIHJldnMpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBVcGRhdGVkIG1vZGVscyB3aXRoIG1ldGFkYXRhXG4gICAqICAgZWxzZSBFcnJvclxuICAgKiAgICAgUG91Y2hEQi0tPj5Qb3VjaEFkYXB0ZXI6IEFycmF5IHdpdGggZXJyb3JzXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IENoZWNrIGZvciBlcnJvcnNcbiAgICogICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IFRocm93cyBJbnRlcm5hbEVycm9yXG4gICAqICAgZW5kXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyB1cGRhdGVBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWRzOiBzdHJpbmdbXSB8IG51bWJlcltdLFxuICAgIG1vZGVsczogUmVjb3JkPHN0cmluZywgYW55PltdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPiB7XG4gICAgbGV0IHJlc3BvbnNlOiAoUmVzcG9uc2UgfCBFcnIpW107XG4gICAgdHJ5IHtcbiAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy5jbGllbnQuYnVsa0RvY3MobW9kZWxzKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IFBvdWNoQWRhcHRlci5wYXJzZUVycm9yKGUpO1xuICAgIH1cbiAgICBpZiAoIXJlc3BvbnNlLmV2ZXJ5KChyKSA9PiAhKHIgYXMgYW55KS5lcnJvcikpIHtcbiAgICAgIGNvbnN0IGVycm9ycyA9IHJlc3BvbnNlLnJlZHVjZSgoYWNjdW06IHN0cmluZ1tdLCBlbCwgaSkgPT4ge1xuICAgICAgICBpZiAoKGVsIGFzIGFueSkuZXJyb3IpXG4gICAgICAgICAgYWNjdW0ucHVzaChcbiAgICAgICAgICAgIGBlbCAke2l9OiAkeyhlbCBhcyBhbnkpLmVycm9yfSR7KGVsIGFzIGFueSkucmVhc29uID8gYCAtICR7KGVsIGFzIGFueSkucmVhc29ufWAgOiBcIlwifWBcbiAgICAgICAgICApO1xuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LCBbXSk7XG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihlcnJvcnMuam9pbihcIlxcblwiKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYXNzaWduTXVsdGlwbGVNZXRhZGF0YShcbiAgICAgIG1vZGVscyxcbiAgICAgIHJlc3BvbnNlLm1hcCgocikgPT4gci5yZXYgYXMgc3RyaW5nKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERlbGV0ZXMgYSBkb2N1bWVudCBmcm9tIHRoZSBkYXRhYmFzZSBieSBJRFxuICAgKiBAc3VtbWFyeSBSZW1vdmVzIGEgZG9jdW1lbnQgZnJvbSB0aGUgUG91Y2hEQiBkYXRhYmFzZSB1c2luZyB0aGUgcmVtb3ZlIG9wZXJhdGlvbi5cbiAgICogVGhpcyBtZXRob2QgZmlyc3QgcmV0cmlldmVzIHRoZSBkb2N1bWVudCB0byBnZXQgaXRzIHJldmlzaW9uLCB0aGVuIGRlbGV0ZXMgaXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUvY29sbGVjdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGlkIC0gVGhlIGRvY3VtZW50IElEXG4gICAqIEByZXR1cm4ge1Byb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkZWxldGVkIGRvY3VtZW50IHdpdGggbWV0YWRhdGFcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpZW50XG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hBZGFwdGVyXG4gICAqICAgcGFydGljaXBhbnQgUG91Y2hEQlxuICAgKlxuICAgKiAgIENsaWVudC0+PlBvdWNoQWRhcHRlcjogZGVsZXRlKHRhYmxlTmFtZSwgaWQpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBnZW5lcmF0ZUlkKHRhYmxlTmFtZSwgaWQpXG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogZ2V0KF9pZClcbiAgICogICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogRG9jdW1lbnQgd2l0aCBfcmV2XG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hEQjogcmVtb3ZlKF9pZCwgcmVjb3JkLl9yZXYpXG4gICAqICAgYWx0IFN1Y2Nlc3NcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBTdWNjZXNzIHJlc3BvbnNlXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IGFzc2lnbk1ldGFkYXRhKHJlY29yZCwgcmVjb3JkLl9yZXYpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBEZWxldGVkIGRvY3VtZW50IHdpdGggbWV0YWRhdGFcbiAgICogICBlbHNlIEVycm9yXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogRXJyb3JcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogcGFyc2VFcnJvcihlKVxuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogVGhyb3dzIGVycm9yXG4gICAqICAgZW5kXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyBkZWxldGUoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlclxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+IHtcbiAgICBjb25zdCBfaWQgPSB0aGlzLmdlbmVyYXRlSWQodGFibGVOYW1lLCBpZCk7XG4gICAgbGV0IHJlY29yZDogSWRNZXRhICYgR2V0TWV0YTtcbiAgICB0cnkge1xuICAgICAgcmVjb3JkID0gYXdhaXQgdGhpcy5jbGllbnQuZ2V0KF9pZCk7XG4gICAgICBhd2FpdCB0aGlzLmNsaWVudC5yZW1vdmUoX2lkLCByZWNvcmQuX3Jldik7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBQb3VjaEFkYXB0ZXIucGFyc2VFcnJvcihlKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYXNzaWduTWV0YWRhdGEocmVjb3JkLCByZWNvcmQuX3Jldik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERlbGV0ZXMgbXVsdGlwbGUgZG9jdW1lbnRzIGZyb20gdGhlIGRhdGFiYXNlIGJ5IHRoZWlyIElEc1xuICAgKiBAc3VtbWFyeSBSZW1vdmVzIG11bHRpcGxlIGRvY3VtZW50cyBmcm9tIHRoZSBQb3VjaERCIGRhdGFiYXNlIGluIGEgc2luZ2xlIG9wZXJhdGlvbi5cbiAgICogVGhpcyBtZXRob2QgZmlyc3QgcmV0cmlldmVzIGFsbCBkb2N1bWVudHMgdG8gZ2V0IHRoZWlyIHJldmlzaW9ucywgdGhlbiBtYXJrcyB0aGVtIGFzIGRlbGV0ZWQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUvY29sbGVjdGlvblxuICAgKiBAcGFyYW0ge0FycmF5PHN0cmluZ3xudW1iZXJ8YmlnaW50Pn0gaWRzIC0gVGhlIGRvY3VtZW50IElEc1xuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkZWxldGVkIGRvY3VtZW50cyB3aXRoIG1ldGFkYXRhXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoREJcbiAgICpcbiAgICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IGRlbGV0ZUFsbCh0YWJsZU5hbWUsIGlkcylcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IE1hcCBpZHMgdG8gZ2VuZXJhdGVJZCh0YWJsZU5hbWUsIGlkKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PlBvdWNoREI6IGJ1bGtHZXQoe2RvY3N9KVxuICAgKiAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBCdWxrR2V0UmVzcG9uc2Ugd2l0aCBkb2N1bWVudHNcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IE1hcmsgZG9jdW1lbnRzIGFzIGRlbGV0ZWRcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaERCOiBidWxrRG9jcyhtYXJrZWQgZG9jdW1lbnRzKVxuICAgKiAgIGFsdCBTdWNjZXNzXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogU3VjY2VzcyByZXNwb25zZXNcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogUHJvY2VzcyByZXN1bHRzXG4gICAqICAgICBQb3VjaEFkYXB0ZXItPj5Qb3VjaEFkYXB0ZXI6IGFzc2lnbk1ldGFkYXRhIGZvciBlYWNoIGRvY1xuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogRGVsZXRlZCBkb2N1bWVudHMgd2l0aCBtZXRhZGF0YVxuICAgKiAgIGVsc2UgRXJyb3JcbiAgICogICAgIFBvdWNoQWRhcHRlci0+PlBvdWNoQWRhcHRlcjogQ2hlY2sgZm9yIGVycm9yc1xuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNsaWVudDogVGhyb3dzIEludGVybmFsRXJyb3JcbiAgICogICBlbmRcbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIGRlbGV0ZUFsbChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZHM6IChzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQpW11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBjb25zdCByZXN1bHRzOiBCdWxrR2V0UmVzcG9uc2U8YW55PiA9IGF3YWl0IHRoaXMuY2xpZW50LmJ1bGtHZXQoe1xuICAgICAgZG9jczogaWRzLm1hcCgoaWQpID0+ICh7IGlkOiB0aGlzLmdlbmVyYXRlSWQodGFibGVOYW1lLCBpZCBhcyBhbnkpIH0pKSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGRlbGV0aW9uOiAoUmVzcG9uc2UgfCBFcnIpW10gPSBhd2FpdCB0aGlzLmNsaWVudC5idWxrRG9jcyhcbiAgICAgIHJlc3VsdHMucmVzdWx0cy5tYXAoKHIpID0+IHtcbiAgICAgICAgKHIgYXMgYW55KVtDb3VjaERCS2V5cy5ERUxFVEVEXSA9IHRydWU7XG4gICAgICAgIHJldHVybiByO1xuICAgICAgfSlcbiAgICApO1xuXG4gICAgY29uc3QgZXJycyA9IGRlbGV0aW9uLmZpbHRlcigoZCkgPT4gKGQgYXMgYW55KS5lcnJvcik7XG4gICAgaWYgKGVycnMubGVuZ3RoKSB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihlcnJzLmpvaW4oXCJcXG5cIikpO1xuXG4gICAgcmV0dXJuIHJlc3VsdHMucmVzdWx0cy5yZWR1Y2UoKGFjY3VtOiBhbnlbXSwgcikgPT4ge1xuICAgICAgci5kb2NzLmZvckVhY2goKGQpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gT2JqZWN0LmFzc2lnbih7fSwgKGQgYXMgeyBvazogYW55IH0pLm9rKTtcbiAgICAgICAgYWNjdW0ucHVzaCh0aGlzLmFzc2lnbk1ldGFkYXRhKHJlc3VsdCwgKGQgYXMgYW55KS5va1tDb3VjaERCS2V5cy5SRVZdKSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBhY2N1bTtcbiAgICB9LCBbXSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEV4ZWN1dGVzIGEgcmF3IE1hbmdvIHF1ZXJ5IGFnYWluc3QgdGhlIGRhdGFiYXNlXG4gICAqIEBzdW1tYXJ5IFBlcmZvcm1zIGEgZGlyZWN0IGZpbmQgb3BlcmF0aW9uIHVzaW5nIGEgTWFuZ28gcXVlcnkgb2JqZWN0LlxuICAgKiBUaGlzIG1ldGhvZCBhbGxvd3MgZm9yIGNvbXBsZXggcXVlcmllcyBiZXlvbmQgdGhlIHN0YW5kYXJkIENSVUQgb3BlcmF0aW9ucy5cbiAgICogQHRlbXBsYXRlIFYgLSBUaGUgcmV0dXJuIHR5cGVcbiAgICogQHBhcmFtIHtNYW5nb1F1ZXJ5fSByYXdJbnB1dCAtIFRoZSBNYW5nbyBxdWVyeSB0byBleGVjdXRlXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Byb2Nlc3M9dHJ1ZV0gLSBXaGV0aGVyIHRvIHByb2Nlc3MgdGhlIHJlc3BvbnNlICh0cnVlIHJldHVybnMganVzdCBkb2NzLCBmYWxzZSByZXR1cm5zIGZ1bGwgcmVzcG9uc2UpXG4gICAqIEByZXR1cm4ge1Byb21pc2U8Vj59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBxdWVyeSByZXN1bHRzXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoREJcbiAgICpcbiAgICogICBDbGllbnQtPj5Qb3VjaEFkYXB0ZXI6IHJhdzxWPihyYXdJbnB1dCwgcHJvY2VzcylcbiAgICogICBQb3VjaEFkYXB0ZXItPj5Qb3VjaERCOiBmaW5kKHJhd0lucHV0KVxuICAgKiAgIGFsdCBTdWNjZXNzXG4gICAqICAgICBQb3VjaERCLS0+PlBvdWNoQWRhcHRlcjogRmluZFJlc3BvbnNlXG4gICAqICAgICBhbHQgcHJvY2Vzcz10cnVlXG4gICAqICAgICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IHJlc3BvbnNlLmRvY3MgYXMgVlxuICAgKiAgICAgZWxzZSBwcm9jZXNzPWZhbHNlXG4gICAqICAgICAgIFBvdWNoQWRhcHRlci0tPj5DbGllbnQ6IHJlc3BvbnNlIGFzIFZcbiAgICogICAgIGVuZFxuICAgKiAgIGVsc2UgRXJyb3JcbiAgICogICAgIFBvdWNoREItLT4+UG91Y2hBZGFwdGVyOiBFcnJvclxuICAgKiAgICAgUG91Y2hBZGFwdGVyLT4+UG91Y2hBZGFwdGVyOiBwYXJzZUVycm9yKGUpXG4gICAqICAgICBQb3VjaEFkYXB0ZXItLT4+Q2xpZW50OiBUaHJvd3MgZXJyb3JcbiAgICogICBlbmRcbiAgICovXG4gIGFzeW5jIHJhdzxWPihyYXdJbnB1dDogTWFuZ29RdWVyeSwgcHJvY2VzcyA9IHRydWUpOiBQcm9taXNlPFY+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2U6IEZpbmRSZXNwb25zZTxhbnk+ID0gYXdhaXQgdGhpcy5jbGllbnQuZmluZChcbiAgICAgICAgcmF3SW5wdXQgYXMgYW55XG4gICAgICApO1xuICAgICAgaWYgKHJlc3BvbnNlLndhcm5pbmcpIGNvbnNvbGUud2FybihyZXNwb25zZS53YXJuaW5nKTtcbiAgICAgIGlmIChwcm9jZXNzKSByZXR1cm4gcmVzcG9uc2UuZG9jcyBhcyBWO1xuICAgICAgcmV0dXJuIHJlc3BvbnNlIGFzIFY7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBQb3VjaEFkYXB0ZXIucGFyc2VFcnJvcihlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFBhcnNlcyBhbmQgY29udmVydHMgZXJyb3JzIGZyb20gUG91Y2hEQiB0byBhcHBsaWNhdGlvbi1zcGVjaWZpYyBlcnJvcnNcbiAgICogQHN1bW1hcnkgQ29udmVydHMgUG91Y2hEQiBlcnJvcnMgdG8gdGhlIGFwcGxpY2F0aW9uJ3MgZXJyb3IgaGllcmFyY2h5LlxuICAgKiBUaGlzIGluc3RhbmNlIG1ldGhvZCBkZWxlZ2F0ZXMgdG8gdGhlIHN0YXRpYyBwYXJzZUVycm9yIG1ldGhvZC5cbiAgICogQHBhcmFtIHtFcnJvcnxzdHJpbmd9IGVyciAtIFRoZSBlcnJvciBvYmplY3Qgb3IgbWVzc2FnZSB0byBwYXJzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3JlYXNvbl0gLSBPcHRpb25hbCByZWFzb24gZm9yIHRoZSBlcnJvclxuICAgKiBAcmV0dXJuIHtCYXNlRXJyb3J9IFRoZSBjb252ZXJ0ZWQgZXJyb3Igb2JqZWN0XG4gICAqL1xuICBvdmVycmlkZSBwYXJzZUVycm9yKGVycjogRXJyb3IgfCBzdHJpbmcsIHJlYXNvbj86IHN0cmluZyk6IEJhc2VFcnJvciB7XG4gICAgcmV0dXJuIFBvdWNoQWRhcHRlci5wYXJzZUVycm9yKGVyciwgcmVhc29uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU3RhdGljIG1ldGhvZCB0byBwYXJzZSBhbmQgY29udmVydCBlcnJvcnMgZnJvbSBQb3VjaERCIHRvIGFwcGxpY2F0aW9uLXNwZWNpZmljIGVycm9yc1xuICAgKiBAc3VtbWFyeSBDb252ZXJ0cyBQb3VjaERCIGVycm9ycyB0byB0aGUgYXBwbGljYXRpb24ncyBlcnJvciBoaWVyYXJjaHkgYmFzZWQgb24gZXJyb3IgY29kZXMgYW5kIG1lc3NhZ2VzLlxuICAgKiBUaGlzIG1ldGhvZCBhbmFseXplcyB0aGUgZXJyb3IgdHlwZSwgc3RhdHVzIGNvZGUsIG9yIG1lc3NhZ2UgdG8gZGV0ZXJtaW5lIHRoZSBhcHByb3ByaWF0ZSBlcnJvciBjbGFzcy5cbiAgICogQHBhcmFtIHtFcnJvcnxzdHJpbmd9IGVyciAtIFRoZSBlcnJvciBvYmplY3Qgb3IgbWVzc2FnZSB0byBwYXJzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3JlYXNvbl0gLSBPcHRpb25hbCByZWFzb24gZm9yIHRoZSBlcnJvclxuICAgKiBAcmV0dXJuIHtCYXNlRXJyb3J9IFRoZSBjb252ZXJ0ZWQgZXJyb3Igb2JqZWN0XG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKlxuICAgKiAgIENhbGxlci0+PlBvdWNoQWRhcHRlcjogcGFyc2VFcnJvcihlcnIsIHJlYXNvbilcbiAgICogICBhbHQgZXJyIGlzIEJhc2VFcnJvclxuICAgKiAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogUmV0dXJuIGVyciBhcyBpc1xuICAgKiAgIGVsc2UgZXJyIGlzIHN0cmluZ1xuICAgKiAgICAgYWx0IGNvbnRhaW5zIFwiYWxyZWFkeSBleGlzdFwiIG9yIFwidXBkYXRlIGNvbmZsaWN0XCJcbiAgICogICAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogQ29uZmxpY3RFcnJvclxuICAgKiAgICAgZWxzZSBjb250YWlucyBcIm1pc3NpbmdcIiBvciBcImRlbGV0ZWRcIlxuICAgKiAgICAgICBQb3VjaEFkYXB0ZXItLT4+Q2FsbGVyOiBOb3RGb3VuZEVycm9yXG4gICAqICAgICBlbmRcbiAgICogICBlbHNlIGVyciBoYXMgc3RhdHVzXG4gICAqICAgICBhbHQgc3RhdHVzIGlzIDQwMSwgNDEyLCA0MDlcbiAgICogICAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogQ29uZmxpY3RFcnJvclxuICAgKiAgICAgZWxzZSBzdGF0dXMgaXMgNDA0XG4gICAqICAgICAgIFBvdWNoQWRhcHRlci0tPj5DYWxsZXI6IE5vdEZvdW5kRXJyb3JcbiAgICogICAgIGVsc2Ugc3RhdHVzIGlzIDQwMFxuICAgKiAgICAgICBhbHQgbWVzc2FnZSBjb250YWlucyBcIk5vIGluZGV4IGV4aXN0c1wiXG4gICAqICAgICAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogSW5kZXhFcnJvclxuICAgKiAgICAgICBlbHNlXG4gICAqICAgICAgICAgUG91Y2hBZGFwdGVyLS0+PkNhbGxlcjogSW50ZXJuYWxFcnJvclxuICAgKiAgICAgICBlbmRcbiAgICogICAgIGVsc2UgbWVzc2FnZSBjb250YWlucyBcIkVDT05OUkVGVVNFRFwiXG4gICAqICAgICAgIFBvdWNoQWRhcHRlci0tPj5DYWxsZXI6IENvbm5lY3Rpb25FcnJvclxuICAgKiAgICAgZWxzZVxuICAgKiAgICAgICBQb3VjaEFkYXB0ZXItLT4+Q2FsbGVyOiBJbnRlcm5hbEVycm9yXG4gICAqICAgICBlbmRcbiAgICogICBlbmRcbiAgICovXG4gIHN0YXRpYyBvdmVycmlkZSBwYXJzZUVycm9yKGVycjogRXJyb3IgfCBzdHJpbmcsIHJlYXNvbj86IHN0cmluZyk6IEJhc2VFcnJvciB7XG4gICAgLy8gcmV0dXJuIHN1cGVyLnBhcnNlRXJyb3IoZXJyLCByZWFzb24pO1xuICAgIGlmIChlcnIgaW5zdGFuY2VvZiBCYXNlRXJyb3IpIHJldHVybiBlcnIgYXMgYW55O1xuICAgIGxldCBjb2RlOiBzdHJpbmcgPSBcIlwiO1xuICAgIGlmICh0eXBlb2YgZXJyID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBjb2RlID0gZXJyO1xuICAgICAgaWYgKGNvZGUubWF0Y2goL2FscmVhZHkgZXhpc3R8dXBkYXRlIGNvbmZsaWN0L2cpKVxuICAgICAgICByZXR1cm4gbmV3IENvbmZsaWN0RXJyb3IoY29kZSk7XG4gICAgICBpZiAoY29kZS5tYXRjaCgvbWlzc2luZ3xkZWxldGVkL2cpKSByZXR1cm4gbmV3IE5vdEZvdW5kRXJyb3IoY29kZSk7XG4gICAgfSBlbHNlIGlmICgoZXJyIGFzIGFueSkuc3RhdHVzKSB7XG4gICAgICBjb2RlID0gKGVyciBhcyBhbnkpLnN0YXR1cztcbiAgICAgIHJlYXNvbiA9IHJlYXNvbiB8fCBlcnIubWVzc2FnZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZSA9IGVyci5tZXNzYWdlO1xuICAgIH1cblxuICAgIHN3aXRjaCAoY29kZS50b1N0cmluZygpKSB7XG4gICAgICBjYXNlIFwiNDAxXCI6XG4gICAgICBjYXNlIFwiNDEyXCI6XG4gICAgICBjYXNlIFwiNDA5XCI6XG4gICAgICAgIHJldHVybiBuZXcgQ29uZmxpY3RFcnJvcihyZWFzb24gYXMgc3RyaW5nKTtcbiAgICAgIGNhc2UgXCI0MDRcIjpcbiAgICAgICAgcmV0dXJuIG5ldyBOb3RGb3VuZEVycm9yKHJlYXNvbiBhcyBzdHJpbmcpO1xuICAgICAgY2FzZSBcIjQwMFwiOlxuICAgICAgICBpZiAoY29kZS50b1N0cmluZygpLm1hdGNoKC9Ob1xcc2luZGV4XFxzZXhpc3RzL2cpKVxuICAgICAgICAgIHJldHVybiBuZXcgSW5kZXhFcnJvcihlcnIpO1xuICAgICAgICByZXR1cm4gbmV3IEludGVybmFsRXJyb3IoZXJyKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChjb2RlLnRvU3RyaW5nKCkubWF0Y2goL0VDT05OUkVGVVNFRC9nKSlcbiAgICAgICAgICByZXR1cm4gbmV3IENvbm5lY3Rpb25FcnJvcihlcnIpO1xuICAgICAgICByZXR1cm4gbmV3IEludGVybmFsRXJyb3IoZXJyKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdXAgZGVjb3JhdGlvbnMgZm9yIFBvdWNoREItc3BlY2lmaWMgbW9kZWwgcHJvcGVydGllc1xuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIGRlY29yYXRvcnMgZm9yIGNyZWF0ZWRCeSBhbmQgdXBkYXRlZEJ5IGZpZWxkcyBpbiBtb2RlbHMuXG4gICAqIFRoaXMgbWV0aG9kIGRlZmluZXMgaG93IHRoZXNlIGZpZWxkcyBzaG91bGQgYmUgYXV0b21hdGljYWxseSBwb3B1bGF0ZWQgZHVyaW5nIGNyZWF0ZSBhbmQgdXBkYXRlIG9wZXJhdGlvbnMuXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICAgKiAgIHBhcnRpY2lwYW50IFBvdWNoQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IERlY29yYXRpb25cbiAgICpcbiAgICogICBDYWxsZXItPj5Qb3VjaEFkYXB0ZXI6IGRlY29yYXRpb24oKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PlJlcG9zaXRvcnk6IGtleShQZXJzaXN0ZW5jZUtleXMuQ1JFQVRFRF9CWSlcbiAgICogICBSZXBvc2l0b3J5LS0+PlBvdWNoQWRhcHRlcjogY3JlYXRlZEJ5S2V5XG4gICAqICAgUG91Y2hBZGFwdGVyLT4+UmVwb3NpdG9yeToga2V5KFBlcnNpc3RlbmNlS2V5cy5VUERBVEVEX0JZKVxuICAgKiAgIFJlcG9zaXRvcnktLT4+UG91Y2hBZGFwdGVyOiB1cGRhdGVkQnlLZXlcbiAgICpcbiAgICogICBQb3VjaEFkYXB0ZXItPj5EZWNvcmF0aW9uOiBmbGF2b3VyZWRBcyhQb3VjaEZsYXZvdXIpXG4gICAqICAgRGVjb3JhdGlvbi0tPj5Qb3VjaEFkYXB0ZXI6IERlY29yYXRvckJ1aWxkZXJcbiAgICogICBQb3VjaEFkYXB0ZXItPj5EZWNvcmF0aW9uOiBmb3IoY3JlYXRlZEJ5S2V5KVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PkRlY29yYXRpb246IGRlZmluZShvbkNyZWF0ZSwgcHJvcE1ldGFkYXRhKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PkRlY29yYXRpb246IGFwcGx5KClcbiAgICpcbiAgICogICBQb3VjaEFkYXB0ZXItPj5EZWNvcmF0aW9uOiBmbGF2b3VyZWRBcyhQb3VjaEZsYXZvdXIpXG4gICAqICAgRGVjb3JhdGlvbi0tPj5Qb3VjaEFkYXB0ZXI6IERlY29yYXRvckJ1aWxkZXJcbiAgICogICBQb3VjaEFkYXB0ZXItPj5EZWNvcmF0aW9uOiBmb3IodXBkYXRlZEJ5S2V5KVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PkRlY29yYXRpb246IGRlZmluZShvbkNyZWF0ZSwgcHJvcE1ldGFkYXRhKVxuICAgKiAgIFBvdWNoQWRhcHRlci0+PkRlY29yYXRpb246IGFwcGx5KClcbiAgICovXG4gIHN0YXRpYyBvdmVycmlkZSBkZWNvcmF0aW9uKCkge1xuICAgIHN1cGVyLmRlY29yYXRpb24oKTtcbiAgICBjb25zdCBjcmVhdGVkQnlLZXkgPSBSZXBvc2l0b3J5LmtleShQZXJzaXN0ZW5jZUtleXMuQ1JFQVRFRF9CWSk7XG4gICAgY29uc3QgdXBkYXRlZEJ5S2V5ID0gUmVwb3NpdG9yeS5rZXkoUGVyc2lzdGVuY2VLZXlzLlVQREFURURfQlkpO1xuICAgIERlY29yYXRpb24uZmxhdm91cmVkQXMoUG91Y2hGbGF2b3VyKVxuICAgICAgLmZvcihjcmVhdGVkQnlLZXkpXG4gICAgICAuZGVmaW5lKFxuICAgICAgICBvbkNyZWF0ZShjcmVhdGVkQnlPblBvdWNoQ3JlYXRlVXBkYXRlKSxcbiAgICAgICAgcHJvcE1ldGFkYXRhKGNyZWF0ZWRCeUtleSwge30pXG4gICAgICApXG4gICAgICAuYXBwbHkoKTtcbiAgICBEZWNvcmF0aW9uLmZsYXZvdXJlZEFzKFBvdWNoRmxhdm91cilcbiAgICAgIC5mb3IodXBkYXRlZEJ5S2V5KVxuICAgICAgLmRlZmluZShcbiAgICAgICAgb25DcmVhdGVVcGRhdGUoY3JlYXRlZEJ5T25Qb3VjaENyZWF0ZVVwZGF0ZSksXG4gICAgICAgIHByb3BNZXRhZGF0YSh1cGRhdGVkQnlLZXksIHt9KVxuICAgICAgKVxuICAgICAgLmFwcGx5KCk7XG4gIH1cbn1cblxuUG91Y2hBZGFwdGVyLnNldEN1cnJlbnQoUG91Y2hGbGF2b3VyKTtcbiIsImltcG9ydCB7IFBvdWNoQWRhcHRlciB9IGZyb20gXCIuL2FkYXB0ZXJcIjtcbmltcG9ydCB7IE1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0aW9uXCI7XG5cblBvdWNoQWRhcHRlci5kZWNvcmF0aW9uKCk7XG5cbmV4cG9ydCAqIGZyb20gXCIuL2NvbnN0YW50c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vUG91Y2hSZXBvc2l0b3J5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlc1wiO1xuLy8gbGVmdCB0byB0aGUgZW5kIG9uIHB1cnBvc2VcbmV4cG9ydCAqIGZyb20gXCIuL2FkYXB0ZXJcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQSBUeXBlU2NyaXB0IGFkYXB0ZXIgZm9yIFBvdWNoREIgaW50ZWdyYXRpb25cbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIGEgcmVwb3NpdG9yeS1wYXR0ZXJuIGltcGxlbWVudGF0aW9uIGJhY2tlZCBieSBQb3VjaERCLCBleHBvc2luZyB0aGUge0BsaW5rIFBvdWNoQWRhcHRlcn0gdG8gaW50ZXJmYWNlIHdpdGggZGF0YWJhc2VzLCB0aGUge0BsaW5rIFBvdWNoUmVwb3NpdG9yeX0gZm9yIHR5cGVkIGRhdGEgYWNjZXNzLCBjb25maWd1cmF0aW9uIHtAbGluayBtb2R1bGU6Zm9yLXBvdWNofGNvbnN0YW50c30gbGlrZSB7QGxpbmsgUG91Y2hGbGF2b3VyfSBhbmQge0BsaW5rIERlZmF1bHRMb2NhbFN0b3JhZ2VQYXRofSwgYW5kIHJlbGF0ZWQge0BsaW5rIG1vZHVsZTpmb3ItcG91Y2h8dHlwZXN9LiBUaGlzIG1vZHVsZSB3aXJlcyB1cCBkZWNvcmF0b3JzIG9uIGxvYWQgdG8gc3VwcG9ydCBjcmVhdGVkL3VwZGF0ZWQtYnkgZmllbGRzLlxuICogQG1vZHVsZSBmb3ItcG91Y2hcbiAqL1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBQYWNrYWdlIHZlcnNpb24gaWRlbnRpZmllclxuICogQHN1bW1hcnkgU3RvcmVzIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgdGhlIGZvci1wb3VjaCBwYWNrYWdlXG4gKiBAY29uc3QgVkVSU0lPTlxuICogQG1lbWJlck9mIG1vZHVsZTpmb3ItcG91Y2hcbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFBhY2thZ2UgdmVyc2lvbiBpZGVudGlmaWVyXG4gKiBAc3VtbWFyeSBTdG9yZXMgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUgZm9yLXBvdWNoIHBhY2thZ2VcbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmZvci1wb3VjaFxuICovXG5leHBvcnQgY29uc3QgUEFDS0FHRV9OQU1FID0gXCIjI1BBQ0tBR0UjI1wiO1xuTWV0YWRhdGEucmVnaXN0ZXJMaWJyYXJ5KFBBQ0tBR0VfTkFNRSwgVkVSU0lPTik7XG4iXSwibmFtZXMiOlsiVW5zdXBwb3J0ZWRFcnJvciIsIkNvdWNoREJBZGFwdGVyIiwiUG91Y2hNYXBSZWR1Y2UiLCJQb3VjaFJlcGxpY2F0aW9uIiwiUG91Y2hGaW5kIiwiSW50ZXJuYWxFcnJvciIsImdlbmVyYXRlSW5kZXhlcyIsIkNvbmZsaWN0RXJyb3IiLCJDb3VjaERCS2V5cyIsIkJhc2VFcnJvciIsIk5vdEZvdW5kRXJyb3IiLCJJbmRleEVycm9yIiwiQ29ubmVjdGlvbkVycm9yIiwiUmVwb3NpdG9yeSIsIlBlcnNpc3RlbmNlS2V5cyIsIkRlY29yYXRpb24iLCJvbkNyZWF0ZSIsInByb3BNZXRhZGF0YSIsIm9uQ3JlYXRlVXBkYXRlIiwiTWV0YWRhdGEiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQUFBOzs7Ozs7SUFNRztBQUNJLFVBQU0sWUFBWSxHQUFHO0lBRTVCOzs7OztJQUtHO0FBQ0ksVUFBTSx1QkFBdUIsR0FBRzs7SUNpQ3ZDOzs7Ozs7Ozs7Ozs7Ozs7SUFlRztJQUNJLGVBQWUsNEJBQTRCLENBTWhELE9BQTRCLEVBQzVCLElBQU8sRUFDUCxHQUFZLEVBQ1osS0FBUSxFQUFBO0lBRVIsSUFBQSxJQUFJO1lBQ0YsTUFBTSxJQUFJLEdBQVcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUM7SUFDeEMsUUFBQSxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBa0I7OztRQUUvQixPQUFPLENBQVUsRUFBRTtJQUNuQixRQUFBLE1BQU0sSUFBSUEscUJBQWdCLENBQ3hCLGdFQUFnRSxDQUNqRTs7SUFFTDtJQUVBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQXdERztJQUNHLE1BQU8sWUFBYSxTQUFRQyx5QkFLakMsQ0FBQTtRQUNDLFdBQVksQ0FBQSxNQUFtQixFQUFFLEtBQWMsRUFBQTtJQUM3QyxRQUFBLEtBQUssQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLEtBQUssQ0FBQzs7SUFHdEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBdUJLO1FBQ00sU0FBUyxHQUFBO0lBQ2hCLFFBQUEsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDakIsWUFBQSxNQUFNLE9BQU8sR0FBRztvQkFDZEMseUJBQWM7b0JBQ2RDLDJCQUFnQjtvQkFDaEJDLG9CQUFTO0lBQ1QsZ0JBQUEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU87aUJBQ3ZCO0lBQ0QsWUFBQSxLQUFLLE1BQU0sTUFBTSxJQUFJLE9B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
|
|
1
|
+
var e,r;e=this,r=function(e,r,t,a,o,n,s,c,i,d){"use strict";function u(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function l(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach(t=>{if("default"!==t){var a=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,a.get?a:{enumerable:!0,get:()=>e[t]})}}),r.default=e,Object.freeze(r)}var h=u(n),f=l(s),p=l(c),w=l(i);const g="pouch",E="local_dbs";async function y(e,r,t,a){try{const r=e.get("UUID");a[t]=r}catch(e){throw new o.UnsupportedError("No User found in context. Please provide a user in the context")}}class b extends t.CouchDBAdapter{constructor(e,r){super(e,g,r)}getClient(){if(!this._client){const e=[f,p,w,...this.config.plugins];for(const r of e)try{h.default.plugin(r)}catch(e){if(e instanceof Error&&e.message.includes("redefine property"))continue;throw e}const{host:r,protocol:t,user:o,password:n,dbName:s,storagePath:c}=this.config;try{this._client=r&&o?new h.default(`${t}://${o}:${n}@${r}/${s}`):new h.default(`${c||E}/${s}`)}catch(e){throw new a.InternalError("Failed to create PouchDB client: "+e)}}return this._client}async flags(e,r,t){return this.config.user||(this.config.user=crypto.randomUUID()),Object.assign(await super.flags(e,r,t),{UUID:this.config.user})}async index(...e){const r=t.generateIndexes(e);for(const e of r){const r=await this.client.createIndex(e),{result:t}=r;if("existing"===t)throw new a.ConflictError(`Index ${e.name} already exists`)}}async create(e,r,t){let o;try{o=await this.client.put(t)}catch(e){throw this.parseError(e)}if(!o.ok)throw new a.InternalError(`Failed to insert doc id: ${r} in table ${e}`);return this.assignMetadata(t,o.rev)}async createAll(e,r,t){let o;try{o=await this.client.bulkDocs(t)}catch(e){throw b.parseError(e)}if(!o.every(e=>e.ok)){const e=o.reduce((e,r,t)=>(r.error&&e.push(`el ${t}: ${r.error}${r.reason?" - "+r.reason:""}`),e),[]);throw new a.InternalError(e.join("\n"))}return this.assignMultipleMetadata(t,o.map(e=>e.rev))}async read(e,r){const t=this.generateId(e,r);let a;try{a=await this.client.get(t)}catch(e){throw b.parseError(e)}return this.assignMetadata(a,a._rev)}async readAll(e,r){return(await this.client.bulkGet({docs:r.map(r=>({id:this.generateId(e,r)}))})).results.reduce((e,r)=>(r.docs.forEach(r=>{if(r.error||!r.ok)throw b.parseError(r.error||new a.InternalError("Missing valid response"));const o=Object.assign({},r.ok);e.push(this.assignMetadata(o,r.ok[t.CouchDBKeys.REV]))}),e),[])}async update(e,r,t){let o;try{o=await this.client.put(t)}catch(e){throw b.parseError(e)}if(!o.ok)throw new a.InternalError(`Failed to update doc id: ${r} in table ${e}`);return this.assignMetadata(t,o.rev)}async updateAll(e,r,t){let o;try{o=await this.client.bulkDocs(t)}catch(e){throw b.parseError(e)}if(!o.every(e=>!e.error)){const e=o.reduce((e,r,t)=>(r.error&&e.push(`el ${t}: ${r.error}${r.reason?" - "+r.reason:""}`),e),[]);throw new a.InternalError(e.join("\n"))}return this.assignMultipleMetadata(t,o.map(e=>e.rev))}async delete(e,r){const t=this.generateId(e,r);let a;try{a=await this.client.get(t),await this.client.remove(t,a._rev)}catch(e){throw b.parseError(e)}return this.assignMetadata(a,a._rev)}async deleteAll(e,r){const o=await this.client.bulkGet({docs:r.map(r=>({id:this.generateId(e,r)}))}),n=(await this.client.bulkDocs(o.results.map(e=>(e[t.CouchDBKeys.DELETED]=!0,e)))).filter(e=>e.error);if(n.length)throw new a.InternalError(n.join("\n"));return o.results.reduce((e,r)=>(r.docs.forEach(r=>{const a=Object.assign({},r.ok);e.push(this.assignMetadata(a,r.ok[t.CouchDBKeys.REV]))}),e),[])}async raw(e,r=!0){try{const t=await this.client.find(e);return t.warning&&this.log.for(this.raw).warn(t.warning),r?t.docs:t}catch(e){throw b.parseError(e)}}parseError(e,r){return b.parseError(e,r)}static parseError(e,r){if(e instanceof a.BaseError)return e;let n="";if("string"==typeof e){if(n=e,n.match(/already exist|update conflict/g))return new a.ConflictError(n);if(n.match(/missing|deleted/g))return new a.NotFoundError(n)}else e.status?(n=e.status,r=r||e.message):n=e.message;switch(n.toString()){case"401":case"412":case"409":return new a.ConflictError(r);case"404":return new a.NotFoundError(r);case"400":return n.toString().match(/No\sindex\sexists/g)?new t.IndexError(e):new a.InternalError(e);default:return n.toString().match(/ECONNREFUSED/g)?new o.ConnectionError(e):new a.InternalError(e)}}static decoration(){super.decoration(),d.Decoration.flavouredAs(g).for(o.PersistenceKeys.CREATED_BY).define(a.onCreate(y),d.propMetadata(o.PersistenceKeys.CREATED_BY,{})).apply(),d.Decoration.flavouredAs(g).for(o.PersistenceKeys.UPDATED_BY).define(a.onCreateUpdate(y),d.propMetadata(o.PersistenceKeys.UPDATED_BY,{})).apply()}}o.Adapter.setCurrent(g),b.decoration();const D="##VERSION##",m="##PACKAGE##";d.Metadata.registerLibrary(m,D),e.DefaultLocalStoragePath=E,e.PACKAGE_NAME=m,e.PouchAdapter=b,e.PouchFlavour=g,e.VERSION=D,e.createdByOnPouchCreateUpdate=y},"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("reflect-metadata"),require("@decaf-ts/for-couchdb"),require("@decaf-ts/db-decorators"),require("@decaf-ts/core"),require("pouchdb-core"),require("pouchdb-mapreduce"),require("pouchdb-replication"),require("pouchdb-find"),require("@decaf-ts/decoration")):"function"==typeof define&&define.amd?define(["exports","reflect-metadata","@decaf-ts/for-couchdb","@decaf-ts/db-decorators","@decaf-ts/core","pouchdb-core","pouchdb-mapreduce","pouchdb-replication","pouchdb-find","@decaf-ts/decoration"],r):r((e="undefined"!=typeof globalThis?globalThis:e||self)["for-pouch"]={},e.reflectMetadata,e.decafTsForCouchdb,e.decafTsDbDecorators,e.decafTsCore,e.pouchdbCore,e.pouchdbMapreduce,e.pouchdbReplication,e.pouchdbFind,e.decafTsDecoration);
|
|
2
|
+
//# sourceMappingURL=for-pouch.cjs.map
|