@decaf-ts/transactional-decorators 0.0.22 → 0.1.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/dist/transactional-decorators.cjs +544 -0
- package/dist/transactional-decorators.esm.cjs +533 -0
- package/lib/Transaction.cjs +1 -2
- package/lib/constants.cjs +1 -2
- package/lib/decorators.cjs +1 -2
- package/lib/esm/Transaction.d.ts +86 -0
- package/lib/esm/Transaction.js +1 -2
- package/lib/esm/constants.d.ts +1 -0
- package/lib/esm/constants.js +1 -2
- package/lib/esm/decorators.d.ts +19 -0
- package/lib/esm/decorators.js +1 -2
- package/{dist/types → lib/esm}/index.d.ts +1 -1
- package/lib/esm/index.js +2 -3
- package/lib/esm/interfaces/TransactionLock.js +1 -2
- package/lib/esm/interfaces/index.js +1 -2
- package/lib/esm/locks/Lock.js +1 -2
- package/lib/esm/locks/SyncronousLock.js +1 -2
- package/lib/esm/locks/index.js +1 -2
- package/lib/esm/types.js +1 -2
- package/lib/esm/utils.js +1 -2
- package/lib/index.cjs +2 -3
- package/lib/index.d.ts +24 -0
- package/lib/interfaces/TransactionLock.cjs +1 -2
- package/lib/interfaces/TransactionLock.d.ts +26 -0
- package/lib/interfaces/index.cjs +1 -2
- package/lib/interfaces/index.d.ts +1 -0
- package/lib/locks/Lock.cjs +1 -2
- package/lib/locks/Lock.d.ts +24 -0
- package/lib/locks/SyncronousLock.cjs +1 -2
- package/lib/locks/SyncronousLock.d.ts +40 -0
- package/lib/locks/index.cjs +1 -2
- package/lib/locks/index.d.ts +2 -0
- package/lib/types.cjs +1 -2
- package/lib/types.d.ts +7 -0
- package/lib/utils.cjs +1 -2
- package/lib/utils.d.ts +1 -0
- package/package.json +22 -34
- package/dist/esm/transactional-decorators.js +0 -2
- package/dist/esm/transactional-decorators.js.LICENSE.txt +0 -14
- package/dist/transactional-decorators.js +0 -2
- package/dist/transactional-decorators.js.LICENSE.txt +0 -14
- /package/{dist/types → lib}/Transaction.d.ts +0 -0
- /package/{dist/types → lib}/constants.d.ts +0 -0
- /package/{dist/types → lib}/decorators.d.ts +0 -0
- /package/{dist/types → lib/esm}/interfaces/TransactionLock.d.ts +0 -0
- /package/{dist/types → lib/esm}/interfaces/index.d.ts +0 -0
- /package/{dist/types → lib/esm}/locks/Lock.d.ts +0 -0
- /package/{dist/types → lib/esm}/locks/SyncronousLock.d.ts +0 -0
- /package/{dist/types → lib/esm}/locks/index.d.ts +0 -0
- /package/{dist/types → lib/esm}/types.d.ts +0 -0
- /package/{dist/types → lib/esm}/utils.d.ts +0 -0
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
(function (global, factory) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@decaf-ts/reflection'), require('@decaf-ts/db-decorators')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', '@decaf-ts/reflection', '@decaf-ts/db-decorators'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["transactional-decorators"] = {}, global.reflection, global.dbDecorators));
|
|
5
|
+
})(this, (function (exports, reflection, dbDecorators) { 'use strict';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @summary Simple Promise based Lock class
|
|
9
|
+
*
|
|
10
|
+
* @class Lock
|
|
11
|
+
* @category Transactions
|
|
12
|
+
*/
|
|
13
|
+
class Lock {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.queue = [];
|
|
16
|
+
this.locked = false;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* @summary executes when lock is available
|
|
20
|
+
* @param {Function} func
|
|
21
|
+
*/
|
|
22
|
+
async execute(func) {
|
|
23
|
+
await this.acquire();
|
|
24
|
+
let result;
|
|
25
|
+
try {
|
|
26
|
+
result = await Promise.resolve(func());
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
this.release();
|
|
30
|
+
throw e;
|
|
31
|
+
}
|
|
32
|
+
this.release();
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* @summary waits to acquire the lock
|
|
37
|
+
* @param {string} [issuer]
|
|
38
|
+
*/
|
|
39
|
+
async acquire() {
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
41
|
+
const self = this;
|
|
42
|
+
if (self.locked) {
|
|
43
|
+
return new Promise((resolve) => self.queue.push(resolve));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
self.locked = true;
|
|
47
|
+
return Promise.resolve();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* @summary releases the lock
|
|
52
|
+
*/
|
|
53
|
+
release() {
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
55
|
+
const self = this;
|
|
56
|
+
const next = self.queue.shift();
|
|
57
|
+
if (next) {
|
|
58
|
+
if (typeof globalThis.window === "undefined")
|
|
59
|
+
globalThis.process.nextTick(next); // if you are on node
|
|
60
|
+
else
|
|
61
|
+
setTimeout(next, 0); // if you are in the browser
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
self.locked = false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
class SyncronousLock {
|
|
70
|
+
constructor(counter = 1, onBegin, onEnd) {
|
|
71
|
+
this.currentTransaction = undefined;
|
|
72
|
+
this.lock = new Lock();
|
|
73
|
+
this.counter = counter;
|
|
74
|
+
this.pendingTransactions = [];
|
|
75
|
+
this.onBegin = onBegin;
|
|
76
|
+
this.onEnd = onEnd;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* @summary Submits a transaction to be processed
|
|
80
|
+
* @param {Transaction} transaction
|
|
81
|
+
*/
|
|
82
|
+
submit(transaction) {
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
84
|
+
const self = this;
|
|
85
|
+
self.lock.acquire().then(() => {
|
|
86
|
+
if (self.currentTransaction &&
|
|
87
|
+
self.currentTransaction.id === transaction.id) {
|
|
88
|
+
self.lock.release();
|
|
89
|
+
return transaction.fire();
|
|
90
|
+
}
|
|
91
|
+
if (self.counter > 0) {
|
|
92
|
+
self.counter--;
|
|
93
|
+
self.lock.release();
|
|
94
|
+
return self.fireTransaction(transaction);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
self.pendingTransactions.push(transaction);
|
|
98
|
+
self.lock.release();
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* @summary Executes a transaction
|
|
104
|
+
*
|
|
105
|
+
* @param {Transaction} transaction
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
fireTransaction(transaction) {
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
110
|
+
const self = this;
|
|
111
|
+
self.lock.acquire().then(() => {
|
|
112
|
+
self.currentTransaction = transaction;
|
|
113
|
+
self.lock.release();
|
|
114
|
+
if (self.onBegin)
|
|
115
|
+
self.onBegin().then(() => {
|
|
116
|
+
// all.call(
|
|
117
|
+
// self,
|
|
118
|
+
// `Firing transaction {0}. {1} remaining...`,
|
|
119
|
+
// transaction.id,
|
|
120
|
+
// this.pendingTransactions.length,
|
|
121
|
+
// );
|
|
122
|
+
transaction.fire();
|
|
123
|
+
});
|
|
124
|
+
else {
|
|
125
|
+
// all.call(
|
|
126
|
+
// self,
|
|
127
|
+
// `Firing transaction {0}. {1} remaining...`,
|
|
128
|
+
// transaction.id,
|
|
129
|
+
// this.pendingTransactions.length,
|
|
130
|
+
// );
|
|
131
|
+
transaction.fire();
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* @summary Releases The lock after the conclusion of a transaction
|
|
137
|
+
*/
|
|
138
|
+
async release(err) {
|
|
139
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
140
|
+
const self = this;
|
|
141
|
+
return new Promise((resolve) => {
|
|
142
|
+
self.lock.acquire().then(() => {
|
|
143
|
+
if (!self.currentTransaction)
|
|
144
|
+
console.warn("Trying to release an unexisting transaction. should never happen...");
|
|
145
|
+
// debug.call(
|
|
146
|
+
// self,
|
|
147
|
+
// "Releasing transaction: {0}",
|
|
148
|
+
// self.currentTransaction?.toString(true, true),
|
|
149
|
+
// );
|
|
150
|
+
self.currentTransaction = undefined;
|
|
151
|
+
self.lock.release();
|
|
152
|
+
const afterConclusionCB = () => {
|
|
153
|
+
self.lock.acquire().then(() => {
|
|
154
|
+
if (self.pendingTransactions.length > 0) {
|
|
155
|
+
const transaction = self.pendingTransactions.shift();
|
|
156
|
+
const cb = () => self.fireTransaction(transaction);
|
|
157
|
+
//
|
|
158
|
+
// all(
|
|
159
|
+
// `Releasing Transaction Lock on transaction {0}`,
|
|
160
|
+
// transaction.id,
|
|
161
|
+
// );
|
|
162
|
+
if (typeof globalThis.window ===
|
|
163
|
+
"undefined")
|
|
164
|
+
globalThis.process.nextTick(cb); // if you are on node
|
|
165
|
+
else
|
|
166
|
+
setTimeout(cb, 0); // if you are in the browser
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
self.counter++;
|
|
170
|
+
}
|
|
171
|
+
self.lock.release();
|
|
172
|
+
resolve();
|
|
173
|
+
});
|
|
174
|
+
};
|
|
175
|
+
if (self.onEnd)
|
|
176
|
+
self.onEnd(err).then(() => afterConclusionCB());
|
|
177
|
+
else
|
|
178
|
+
afterConclusionCB();
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const TransactionalKeys = {
|
|
185
|
+
REFLECT: "model.transactional.",
|
|
186
|
+
TRANSACTIONAL: "transactional",
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
function getObjectName(obj) {
|
|
190
|
+
if (!obj)
|
|
191
|
+
return;
|
|
192
|
+
if (typeof obj === "string")
|
|
193
|
+
return obj;
|
|
194
|
+
if (obj.constructor &&
|
|
195
|
+
obj.constructor.name &&
|
|
196
|
+
["Function", "Object"].indexOf(obj.constructor.name) === -1)
|
|
197
|
+
return obj.constructor.name;
|
|
198
|
+
if (typeof obj === "function" && obj.name)
|
|
199
|
+
return obj.name;
|
|
200
|
+
return obj.toString();
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @summary Transaction Class
|
|
205
|
+
*
|
|
206
|
+
* @param {string} source
|
|
207
|
+
* @param {string} [method]
|
|
208
|
+
* @param {function(): void} [action]
|
|
209
|
+
* @param {any[]} [metadata]
|
|
210
|
+
*
|
|
211
|
+
* @class Transaction
|
|
212
|
+
*
|
|
213
|
+
* @category Transactions
|
|
214
|
+
*/
|
|
215
|
+
class Transaction {
|
|
216
|
+
constructor(source, method, action, metadata) {
|
|
217
|
+
this.id = Date.now();
|
|
218
|
+
this.action = action;
|
|
219
|
+
this.method = method;
|
|
220
|
+
this.log = [[this.id, source, method].join(" | ")];
|
|
221
|
+
this.source = source;
|
|
222
|
+
this.metadata = metadata;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* @summary Pushes a transaction to que queue and waits its resolution
|
|
226
|
+
*
|
|
227
|
+
* @param {any} issuer any class. will be used as this when calling the callbackMethod
|
|
228
|
+
* @param {Function} callbackMethod callback function containing the transaction. will be called with the issuear as this
|
|
229
|
+
* @param {any[]} args arguments to pass to the method. Last one must be the callback
|
|
230
|
+
*/
|
|
231
|
+
static push(issuer, callbackMethod, ...args) {
|
|
232
|
+
const callback = args.pop();
|
|
233
|
+
if (!callback || typeof callback !== "function")
|
|
234
|
+
throw new Error("Missing callback");
|
|
235
|
+
const cb = (err, ...args) => {
|
|
236
|
+
Transaction.getLock()
|
|
237
|
+
.release(err)
|
|
238
|
+
.then(() => callback(err, ...args));
|
|
239
|
+
};
|
|
240
|
+
const transaction = new Transaction(issuer.constructor.name, callbackMethod.name ? getObjectName(callbackMethod) : "Anonymous", () => {
|
|
241
|
+
return callbackMethod.call(transaction.bindToTransaction(issuer), ...args, cb);
|
|
242
|
+
});
|
|
243
|
+
Transaction.getLock().submit(transaction);
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* @summary Sets the lock to be used
|
|
247
|
+
* @param lock
|
|
248
|
+
*/
|
|
249
|
+
static setLock(lock) {
|
|
250
|
+
this.lock = lock;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* @summary gets the lock
|
|
254
|
+
*/
|
|
255
|
+
static getLock() {
|
|
256
|
+
if (!this.lock)
|
|
257
|
+
this.lock = new SyncronousLock();
|
|
258
|
+
return this.lock;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* @summary submits a transaction
|
|
262
|
+
* @param {Transaction} transaction
|
|
263
|
+
*/
|
|
264
|
+
static submit(transaction) {
|
|
265
|
+
Transaction.getLock().submit(transaction);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* @summary releases the lock
|
|
269
|
+
* @param {Err} err
|
|
270
|
+
*/
|
|
271
|
+
static async release(err) {
|
|
272
|
+
return Transaction.getLock().release(err);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* @summary retrieves the metadata for the transaction
|
|
276
|
+
*/
|
|
277
|
+
getMetadata() {
|
|
278
|
+
return this.metadata ? [...this.metadata] : undefined;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* @summary Binds a new operation to the current transaction
|
|
282
|
+
* @param {Transaction} nextTransaction
|
|
283
|
+
*/
|
|
284
|
+
bindTransaction(nextTransaction) {
|
|
285
|
+
// all(`Binding the {0} to {1}`, nextTransaction, this);
|
|
286
|
+
this.log.push(...nextTransaction.log);
|
|
287
|
+
nextTransaction.bindTransaction = this.bindToTransaction.bind(this);
|
|
288
|
+
nextTransaction.bindToTransaction = this.bindToTransaction.bind(this);
|
|
289
|
+
this.action = nextTransaction.action;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* @summary Binds the Transactional Decorated Object to the transaction
|
|
293
|
+
* @description by having all {@link transactional} decorated
|
|
294
|
+
* methods always pass the current Transaction as an argument
|
|
295
|
+
*
|
|
296
|
+
* @param {any} obj
|
|
297
|
+
* @return {any} the bound {@param obj}
|
|
298
|
+
*/
|
|
299
|
+
bindToTransaction(obj) {
|
|
300
|
+
const transactionalMethods = dbDecorators.getAllPropertyDecoratorsRecursive(obj, undefined, TransactionalKeys.REFLECT);
|
|
301
|
+
if (!transactionalMethods)
|
|
302
|
+
return obj;
|
|
303
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
304
|
+
const self = this;
|
|
305
|
+
const boundObj = reflection.Reflection.getAllProperties(obj).reduce((accum, k) => {
|
|
306
|
+
if (Object.keys(transactionalMethods).indexOf(k) !== -1 &&
|
|
307
|
+
transactionalMethods[k].find((o) => o.key === TransactionalKeys.TRANSACTIONAL))
|
|
308
|
+
accum[k] = (...args) => obj[k].call(obj.__originalObj || obj, self, ...args);
|
|
309
|
+
else if (k === "clazz" || k === "constructor")
|
|
310
|
+
accum[k] = obj[k];
|
|
311
|
+
else if (typeof obj[k] === "function")
|
|
312
|
+
accum[k] = obj[k].bind(obj.__originalObj || obj);
|
|
313
|
+
else if (typeof obj[k] === "object" && obj[k].constructor) {
|
|
314
|
+
const decs = reflection.Reflection.getClassDecorators(TransactionalKeys.REFLECT, obj[k]);
|
|
315
|
+
if (decs.find((e) => e.key === TransactionalKeys.TRANSACTIONAL))
|
|
316
|
+
accum[k] = self.bindToTransaction(obj[k]);
|
|
317
|
+
else
|
|
318
|
+
accum[k] = obj[k];
|
|
319
|
+
}
|
|
320
|
+
else
|
|
321
|
+
accum[k] = obj[k];
|
|
322
|
+
return accum;
|
|
323
|
+
}, {});
|
|
324
|
+
boundObj[dbDecorators.DBKeys.ORIGINAL] = obj[dbDecorators.DBKeys.ORIGINAL] || obj;
|
|
325
|
+
boundObj.toString = () => getObjectName(boundObj[dbDecorators.DBKeys.ORIGINAL]) +
|
|
326
|
+
" proxy for transaction " +
|
|
327
|
+
this.id;
|
|
328
|
+
return boundObj;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* @summary Fires the Transaction
|
|
332
|
+
*/
|
|
333
|
+
fire() {
|
|
334
|
+
if (!this.action)
|
|
335
|
+
throw new Error(`Missing the method`);
|
|
336
|
+
return this.action();
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* @summary toString override
|
|
340
|
+
* @param {boolean} [withId] defaults to true
|
|
341
|
+
* @param {boolean} [withLog] defaults to true
|
|
342
|
+
*/
|
|
343
|
+
toString(withId = true, withLog = false) {
|
|
344
|
+
return `${withId ? `[${this.id}]` : ""}[Transaction][${this.source}.${this.method}${withLog ? `]\nTransaction Log:\n${this.log.join("\n")}` : "]"}`;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* @summary gets the transactions reflections key
|
|
348
|
+
* @function getRepoKey
|
|
349
|
+
* @param {string} key
|
|
350
|
+
* @memberOf module:db-decorators.Transactions
|
|
351
|
+
* */
|
|
352
|
+
static key(key) {
|
|
353
|
+
return TransactionalKeys.REFLECT + key;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* @summary Sets a class Async method as transactional
|
|
359
|
+
*
|
|
360
|
+
* @param {any[]} [data] option metadata available to the {@link TransactionLock}
|
|
361
|
+
*
|
|
362
|
+
* @function transactional
|
|
363
|
+
*
|
|
364
|
+
* @memberOf module:db-decorators.Decorators.transactions
|
|
365
|
+
*/
|
|
366
|
+
function transactional(...data) {
|
|
367
|
+
return function (target, propertyKey, descriptor) {
|
|
368
|
+
if (!descriptor)
|
|
369
|
+
throw new dbDecorators.InternalError("Missing descriptor. Should be impossible");
|
|
370
|
+
reflection.metadata(Transaction.key(TransactionalKeys.TRANSACTIONAL), data)(target, propertyKey);
|
|
371
|
+
const originalMethod = descriptor.value;
|
|
372
|
+
const methodWrapper = function (...args) {
|
|
373
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
374
|
+
const self = this;
|
|
375
|
+
return new Promise((resolve, reject) => {
|
|
376
|
+
const cb = (err, result) => {
|
|
377
|
+
Transaction.release(err).then(() => {
|
|
378
|
+
if (err)
|
|
379
|
+
return reject(err);
|
|
380
|
+
resolve(result);
|
|
381
|
+
});
|
|
382
|
+
};
|
|
383
|
+
let transaction = args.shift();
|
|
384
|
+
if (transaction instanceof Transaction) {
|
|
385
|
+
const updatedTransaction = new Transaction(this.constructor.name, propertyKey, async () => {
|
|
386
|
+
originalMethod
|
|
387
|
+
.call(updatedTransaction.bindToTransaction(self), ...args)
|
|
388
|
+
.then(resolve)
|
|
389
|
+
.catch(reject);
|
|
390
|
+
}, data.length ? data : undefined);
|
|
391
|
+
transaction.bindTransaction(updatedTransaction);
|
|
392
|
+
transaction.fire();
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
args.unshift(transaction);
|
|
396
|
+
transaction = new Transaction(this.constructor.name, propertyKey, () => {
|
|
397
|
+
originalMethod
|
|
398
|
+
.call(transaction.bindToTransaction(self), ...args)
|
|
399
|
+
.then((result) => cb(undefined, result))
|
|
400
|
+
.catch(cb);
|
|
401
|
+
}, data.length ? data : undefined);
|
|
402
|
+
Transaction.submit(transaction);
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
};
|
|
406
|
+
Object.defineProperty(methodWrapper, "name", {
|
|
407
|
+
value: propertyKey,
|
|
408
|
+
});
|
|
409
|
+
descriptor.value = methodWrapper;
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
//
|
|
413
|
+
// /**
|
|
414
|
+
// * @summary Sets a class Async method as transactional
|
|
415
|
+
// *
|
|
416
|
+
// * @param {any[]} [metadata] option metadata available to the {@link TransactionLock}
|
|
417
|
+
// *
|
|
418
|
+
// * @function transactionalAsync
|
|
419
|
+
// *
|
|
420
|
+
// * @memberOf module:db-decorators.Decorators.transactions
|
|
421
|
+
// */
|
|
422
|
+
// export function transactionalAsync(...metadata: any[]) {
|
|
423
|
+
// return function (
|
|
424
|
+
// target: any,
|
|
425
|
+
// propertyKey: string,
|
|
426
|
+
// descriptor: PropertyDescriptor,
|
|
427
|
+
// ) {
|
|
428
|
+
// metadasta(getTransactionalKey(TransactionalKeys.TRANSACTIONAL))
|
|
429
|
+
// Reflect.defineMetadata(
|
|
430
|
+
// ,
|
|
431
|
+
// {
|
|
432
|
+
// type: "async",
|
|
433
|
+
// metadata: metadata.length ? metadata : undefined,
|
|
434
|
+
// } as TransactionalMetadata,
|
|
435
|
+
// target,
|
|
436
|
+
// propertyKey,
|
|
437
|
+
// );
|
|
438
|
+
//
|
|
439
|
+
// const originalMethod = descriptor.value;
|
|
440
|
+
//
|
|
441
|
+
// const methodWrapper = function (this: any, ...args: any[]) {
|
|
442
|
+
// const callback: Callback = args.pop();
|
|
443
|
+
// if (!callback || typeof callback !== "function")
|
|
444
|
+
// throw new CriticalError(`Missing Callback`);
|
|
445
|
+
//
|
|
446
|
+
// const cb = (err?: Err, ...args: any[]) => {
|
|
447
|
+
// Transaction.release(err).then((_) => callback(err, ...args));
|
|
448
|
+
// };
|
|
449
|
+
//
|
|
450
|
+
// const self = this;
|
|
451
|
+
//
|
|
452
|
+
// let transaction = args.shift();
|
|
453
|
+
// if (transaction instanceof Transaction) {
|
|
454
|
+
// const updatedTransaction: Transaction = new Transaction(
|
|
455
|
+
// this.constructor.name,
|
|
456
|
+
// propertyKey,
|
|
457
|
+
// () => {
|
|
458
|
+
// try {
|
|
459
|
+
// return originalMethod.call(
|
|
460
|
+
// updatedTransaction.bindToTransaction(self),
|
|
461
|
+
// ...args,
|
|
462
|
+
// callback,
|
|
463
|
+
// );
|
|
464
|
+
// } catch (e: any) {
|
|
465
|
+
// return callback(e);
|
|
466
|
+
// }
|
|
467
|
+
// },
|
|
468
|
+
// metadata.length ? metadata : undefined,
|
|
469
|
+
// );
|
|
470
|
+
//
|
|
471
|
+
// transaction.bindTransaction(updatedTransaction);
|
|
472
|
+
// transaction.fire();
|
|
473
|
+
// } else {
|
|
474
|
+
// args.unshift(transaction);
|
|
475
|
+
// transaction = undefined;
|
|
476
|
+
// transaction = new Transaction(
|
|
477
|
+
// this.constructor.name,
|
|
478
|
+
// propertyKey,
|
|
479
|
+
// () => {
|
|
480
|
+
// try {
|
|
481
|
+
// return originalMethod.call(
|
|
482
|
+
// transaction.bindToTransaction(self),
|
|
483
|
+
// ...args,
|
|
484
|
+
// cb,
|
|
485
|
+
// );
|
|
486
|
+
// } catch (e: any) {
|
|
487
|
+
// return cb(e);
|
|
488
|
+
// }
|
|
489
|
+
// },
|
|
490
|
+
// metadata.length ? metadata : undefined,
|
|
491
|
+
// );
|
|
492
|
+
// Transaction.submit(transaction);
|
|
493
|
+
// }
|
|
494
|
+
// };
|
|
495
|
+
//
|
|
496
|
+
// Object.defineProperty(methodWrapper, "name", {
|
|
497
|
+
// value: propertyKey,
|
|
498
|
+
// });
|
|
499
|
+
// descriptor.value = methodWrapper;
|
|
500
|
+
// };
|
|
501
|
+
// }
|
|
502
|
+
/**
|
|
503
|
+
* @summary Util function to wrap super calls with the transaction when the super's method is also transactional
|
|
504
|
+
*
|
|
505
|
+
* @param {Function} method the super method (must be bound to the proper this), eg: super.create.bind(this)
|
|
506
|
+
* @param {any[]} args the arguments to call the method with
|
|
507
|
+
*
|
|
508
|
+
* @memberOf module:db-decorators.Transaction
|
|
509
|
+
*/
|
|
510
|
+
function transactionalSuperCall(method, ...args) {
|
|
511
|
+
const lock = Transaction.getLock();
|
|
512
|
+
const currentTransaction = lock.currentTransaction;
|
|
513
|
+
return method(currentTransaction, ...args);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* @summary Module summary
|
|
518
|
+
* @description Module description
|
|
519
|
+
* @module ts-workspace
|
|
520
|
+
*/
|
|
521
|
+
/**
|
|
522
|
+
* @summary Namespace summary
|
|
523
|
+
* @description Namespace description
|
|
524
|
+
* @namespace Namespace
|
|
525
|
+
* @memberOf module:ts-workspace
|
|
526
|
+
*/
|
|
527
|
+
/**
|
|
528
|
+
* @summary stores the current package version
|
|
529
|
+
* @description this is how you should document a constant
|
|
530
|
+
* @const VERSION
|
|
531
|
+
* @memberOf module:ts-workspace
|
|
532
|
+
*/
|
|
533
|
+
const VERSION = "0.1.0";
|
|
534
|
+
|
|
535
|
+
exports.Lock = Lock;
|
|
536
|
+
exports.SyncronousLock = SyncronousLock;
|
|
537
|
+
exports.Transaction = Transaction;
|
|
538
|
+
exports.TransactionalKeys = TransactionalKeys;
|
|
539
|
+
exports.VERSION = VERSION;
|
|
540
|
+
exports.transactional = transactional;
|
|
541
|
+
exports.transactionalSuperCall = transactionalSuperCall;
|
|
542
|
+
|
|
543
|
+
}));
|
|
544
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb25hbC1kZWNvcmF0b3JzLmNqcyIsInNvdXJjZXMiOlsiLi4vc3JjL2xvY2tzL0xvY2sudHMiLCIuLi9zcmMvbG9ja3MvU3luY3Jvbm91c0xvY2sudHMiLCIuLi9zcmMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3V0aWxzLnRzIiwiLi4vc3JjL1RyYW5zYWN0aW9uLnRzIiwiLi4vc3JjL2RlY29yYXRvcnMudHMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTG9ja0NhbGxhYmxlIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgU2ltcGxlIFByb21pc2UgYmFzZWQgTG9jayBjbGFzc1xuICpcbiAqIEBjbGFzcyBMb2NrXG4gKiBAY2F0ZWdvcnkgVHJhbnNhY3Rpb25zXG4gKi9cbmV4cG9ydCBjbGFzcyBMb2NrIHtcbiAgcHJpdmF0ZSBxdWV1ZTogTG9ja0NhbGxhYmxlW10gPSBbXTtcbiAgcHJpdmF0ZSBsb2NrZWQgPSBmYWxzZTtcblxuICAvKipcbiAgICogQHN1bW1hcnkgZXhlY3V0ZXMgd2hlbiBsb2NrIGlzIGF2YWlsYWJsZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jXG4gICAqL1xuICBhc3luYyBleGVjdXRlKGZ1bmM6ICgpID0+IGFueSkge1xuICAgIGF3YWl0IHRoaXMuYWNxdWlyZSgpO1xuICAgIGxldCByZXN1bHQ6IGFueTtcbiAgICB0cnkge1xuICAgICAgcmVzdWx0ID0gYXdhaXQgUHJvbWlzZS5yZXNvbHZlKGZ1bmMoKSk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aGlzLnJlbGVhc2UoKTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICAgIHRoaXMucmVsZWFzZSgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgd2FpdHMgdG8gYWNxdWlyZSB0aGUgbG9ja1xuICAgKiBAcGFyYW0ge3N0cmluZ30gW2lzc3Vlcl1cbiAgICovXG4gIGFzeW5jIGFjcXVpcmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgaWYgKHNlbGYubG9ja2VkKSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHNlbGYucXVldWUucHVzaChyZXNvbHZlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGYubG9ja2VkID0gdHJ1ZTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgcmVsZWFzZXMgdGhlIGxvY2tcbiAgICovXG4gIHJlbGVhc2UoKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgY29uc3QgbmV4dDogTG9ja0NhbGxhYmxlIHwgdW5kZWZpbmVkID0gc2VsZi5xdWV1ZS5zaGlmdCgpO1xuICAgIGlmIChuZXh0KSB7XG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiAoZ2xvYmFsVGhpcyBhcyB1bmtub3duIGFzIHsgd2luZG93OiBhbnkgfSkud2luZG93ID09PSBcInVuZGVmaW5lZFwiXG4gICAgICApXG4gICAgICAgIGdsb2JhbFRoaXMucHJvY2Vzcy5uZXh0VGljayhuZXh0KTsgLy8gaWYgeW91IGFyZSBvbiBub2RlXG4gICAgICBlbHNlIHNldFRpbWVvdXQobmV4dCwgMCk7IC8vIGlmIHlvdSBhcmUgaW4gdGhlIGJyb3dzZXJcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZi5sb2NrZWQgPSBmYWxzZTtcbiAgICB9XG4gIH1cbn1cbiIsIi8qKlxuICogQHN1bW1hcnkgU2ltcGxlIFN5bmNocm9ub3VzIExvY2sgaW1wbGVtZW50YXRpb25cbiAqIEBkZXNjcmlwdGlvbiBmb3IgdHJhbnNhY3Rpb24gbWFuYWdlbWVudFxuICogYWRhcHRlZCBmcm9tIHtAbGluayBodHRwczovL3d3dy50YWxraW5naGlnaHRlY2guY29tL2VuL2NyZWF0aW5nLWEtanMtbG9jay1mb3ItYS1yZXNvdXJjZS99XG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IFtjb3VudGVyXSB0aGUgbnVtYmVyIG9mIHNpbXVsdGFuZW91cyB0cmFuc2FjdGlvbnMgYWxsb3dlZC4gZGVmYXVsdHMgdG8gMVxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29uQmVnaW5dIHRvIGJlIGNhbGxlZCBhdCB0aGUgc3RhcnQgb2YgdGhlIHRyYW5zYWN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb25FbmRdIHRvIGJlIGNhbGxlZCBhdCB0aGUgY29uY2x1c2lvbiBvZiB0aGUgdHJhbnNhY3Rpb25cbiAqXG4gKiBAY2xhc3MgU3luY3Jvbm91c0xvY2tcbiAqIEBpbXBsZW1lbnRzIFRyYW5zYWN0aW9uTG9ja1xuICpcbiAqIEBjYXRlZ29yeSBUcmFuc2FjdGlvbnNcbiAqLyBpbXBvcnQgeyBUcmFuc2FjdGlvbiB9IGZyb20gXCIuLi9UcmFuc2FjdGlvblwiO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25Mb2NrIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvVHJhbnNhY3Rpb25Mb2NrXCI7XG5pbXBvcnQgeyBMb2NrIH0gZnJvbSBcIi4vTG9ja1wiO1xuXG5leHBvcnQgY2xhc3MgU3luY3Jvbm91c0xvY2sgaW1wbGVtZW50cyBUcmFuc2FjdGlvbkxvY2sge1xuICBwcml2YXRlIGNvdW50ZXI6IG51bWJlcjtcbiAgcHJpdmF0ZSBwZW5kaW5nVHJhbnNhY3Rpb25zOiBUcmFuc2FjdGlvbltdO1xuICBjdXJyZW50VHJhbnNhY3Rpb24/OiBUcmFuc2FjdGlvbiA9IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBvbkJlZ2luPzogKCkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgcHJpdmF0ZSByZWFkb25seSBvbkVuZD86IChlcnI/OiBFcnJvcikgPT4gUHJvbWlzZTx2b2lkPjtcblxuICBwcml2YXRlIHJlYWRvbmx5IGxvY2sgPSBuZXcgTG9jaygpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGNvdW50ZXI6IG51bWJlciA9IDEsXG4gICAgb25CZWdpbj86ICgpID0+IFByb21pc2U8dm9pZD4sXG4gICAgb25FbmQ/OiAoZXJyPzogRXJyb3IpID0+IFByb21pc2U8dm9pZD4sXG4gICkge1xuICAgIHRoaXMuY291bnRlciA9IGNvdW50ZXI7XG4gICAgdGhpcy5wZW5kaW5nVHJhbnNhY3Rpb25zID0gW107XG4gICAgdGhpcy5vbkJlZ2luID0gb25CZWdpbjtcbiAgICB0aGlzLm9uRW5kID0gb25FbmQ7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgU3VibWl0cyBhIHRyYW5zYWN0aW9uIHRvIGJlIHByb2Nlc3NlZFxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKi9cbiAgc3VibWl0KHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbik6IHZvaWQge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIHNlbGYubG9jay5hY3F1aXJlKCkudGhlbigoKSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIHNlbGYuY3VycmVudFRyYW5zYWN0aW9uICYmXG4gICAgICAgIHNlbGYuY3VycmVudFRyYW5zYWN0aW9uLmlkID09PSB0cmFuc2FjdGlvbi5pZFxuICAgICAgKSB7XG4gICAgICAgIHNlbGYubG9jay5yZWxlYXNlKCk7XG4gICAgICAgIHJldHVybiB0cmFuc2FjdGlvbi5maXJlKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzZWxmLmNvdW50ZXIgPiAwKSB7XG4gICAgICAgIHNlbGYuY291bnRlci0tO1xuICAgICAgICBzZWxmLmxvY2sucmVsZWFzZSgpO1xuICAgICAgICByZXR1cm4gc2VsZi5maXJlVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2VsZi5wZW5kaW5nVHJhbnNhY3Rpb25zLnB1c2godHJhbnNhY3Rpb24pO1xuICAgICAgICBzZWxmLmxvY2sucmVsZWFzZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEV4ZWN1dGVzIGEgdHJhbnNhY3Rpb25cbiAgICpcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgZmlyZVRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbikge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIHNlbGYubG9jay5hY3F1aXJlKCkudGhlbigoKSA9PiB7XG4gICAgICBzZWxmLmN1cnJlbnRUcmFuc2FjdGlvbiA9IHRyYW5zYWN0aW9uO1xuICAgICAgc2VsZi5sb2NrLnJlbGVhc2UoKTtcbiAgICAgIGlmIChzZWxmLm9uQmVnaW4pXG4gICAgICAgIHNlbGYub25CZWdpbigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIC8vIGFsbC5jYWxsKFxuICAgICAgICAgIC8vICAgc2VsZixcbiAgICAgICAgICAvLyAgIGBGaXJpbmcgdHJhbnNhY3Rpb24gezB9LiB7MX0gcmVtYWluaW5nLi4uYCxcbiAgICAgICAgICAvLyAgIHRyYW5zYWN0aW9uLmlkLFxuICAgICAgICAgIC8vICAgdGhpcy5wZW5kaW5nVHJhbnNhY3Rpb25zLmxlbmd0aCxcbiAgICAgICAgICAvLyApO1xuICAgICAgICAgIHRyYW5zYWN0aW9uLmZpcmUoKTtcbiAgICAgICAgfSk7XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy8gYWxsLmNhbGwoXG4gICAgICAgIC8vICAgc2VsZixcbiAgICAgICAgLy8gICBgRmlyaW5nIHRyYW5zYWN0aW9uIHswfS4gezF9IHJlbWFpbmluZy4uLmAsXG4gICAgICAgIC8vICAgdHJhbnNhY3Rpb24uaWQsXG4gICAgICAgIC8vICAgdGhpcy5wZW5kaW5nVHJhbnNhY3Rpb25zLmxlbmd0aCxcbiAgICAgICAgLy8gKTtcbiAgICAgICAgdHJhbnNhY3Rpb24uZmlyZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZWxlYXNlcyBUaGUgbG9jayBhZnRlciB0aGUgY29uY2x1c2lvbiBvZiBhIHRyYW5zYWN0aW9uXG4gICAqL1xuICBhc3luYyByZWxlYXNlKGVycj86IEVycm9yKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICBzZWxmLmxvY2suYWNxdWlyZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAoIXNlbGYuY3VycmVudFRyYW5zYWN0aW9uKVxuICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgIFwiVHJ5aW5nIHRvIHJlbGVhc2UgYW4gdW5leGlzdGluZyB0cmFuc2FjdGlvbi4gc2hvdWxkIG5ldmVyIGhhcHBlbi4uLlwiLFxuICAgICAgICAgICk7XG4gICAgICAgIC8vIGRlYnVnLmNhbGwoXG4gICAgICAgIC8vICAgc2VsZixcbiAgICAgICAgLy8gICBcIlJlbGVhc2luZyB0cmFuc2FjdGlvbjogezB9XCIsXG4gICAgICAgIC8vICAgc2VsZi5jdXJyZW50VHJhbnNhY3Rpb24/LnRvU3RyaW5nKHRydWUsIHRydWUpLFxuICAgICAgICAvLyApO1xuICAgICAgICBzZWxmLmN1cnJlbnRUcmFuc2FjdGlvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgc2VsZi5sb2NrLnJlbGVhc2UoKTtcblxuICAgICAgICBjb25zdCBhZnRlckNvbmNsdXNpb25DQiA9ICgpID0+IHtcbiAgICAgICAgICBzZWxmLmxvY2suYWNxdWlyZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHNlbGYucGVuZGluZ1RyYW5zYWN0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID1cbiAgICAgICAgICAgICAgICBzZWxmLnBlbmRpbmdUcmFuc2FjdGlvbnMuc2hpZnQoKSBhcyBUcmFuc2FjdGlvbjtcblxuICAgICAgICAgICAgICBjb25zdCBjYiA9ICgpID0+IHNlbGYuZmlyZVRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKTtcbiAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgLy8gYWxsKFxuICAgICAgICAgICAgICAvLyAgIGBSZWxlYXNpbmcgVHJhbnNhY3Rpb24gTG9jayBvbiB0cmFuc2FjdGlvbiB7MH1gLFxuICAgICAgICAgICAgICAvLyAgIHRyYW5zYWN0aW9uLmlkLFxuICAgICAgICAgICAgICAvLyApO1xuXG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICB0eXBlb2YgKGdsb2JhbFRoaXMgYXMgdW5rbm93biBhcyB7IHdpbmRvdzogYW55IH0pLndpbmRvdyA9PT1cbiAgICAgICAgICAgICAgICBcInVuZGVmaW5lZFwiXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICBnbG9iYWxUaGlzLnByb2Nlc3MubmV4dFRpY2soY2IpOyAvLyBpZiB5b3UgYXJlIG9uIG5vZGVcbiAgICAgICAgICAgICAgZWxzZSBzZXRUaW1lb3V0KGNiLCAwKTsgLy8gaWYgeW91IGFyZSBpbiB0aGUgYnJvd3NlclxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgc2VsZi5jb3VudGVyKys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWxmLmxvY2sucmVsZWFzZSgpO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChzZWxmLm9uRW5kKSBzZWxmLm9uRW5kKGVycikudGhlbigoKSA9PiBhZnRlckNvbmNsdXNpb25DQigpKTtcbiAgICAgICAgZWxzZSBhZnRlckNvbmNsdXNpb25DQigpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbn1cbiIsImV4cG9ydCBjb25zdCBUcmFuc2FjdGlvbmFsS2V5czogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgUkVGTEVDVDogXCJtb2RlbC50cmFuc2FjdGlvbmFsLlwiLFxuICBUUkFOU0FDVElPTkFMOiBcInRyYW5zYWN0aW9uYWxcIixcbn07XG4iLCJleHBvcnQgZnVuY3Rpb24gZ2V0T2JqZWN0TmFtZShvYmo6IGFueSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghb2JqKSByZXR1cm47XG4gIGlmICh0eXBlb2Ygb2JqID09PSBcInN0cmluZ1wiKSByZXR1cm4gb2JqO1xuICBpZiAoXG4gICAgb2JqLmNvbnN0cnVjdG9yICYmXG4gICAgb2JqLmNvbnN0cnVjdG9yLm5hbWUgJiZcbiAgICBbXCJGdW5jdGlvblwiLCBcIk9iamVjdFwiXS5pbmRleE9mKG9iai5jb25zdHJ1Y3Rvci5uYW1lKSA9PT0gLTFcbiAgKVxuICAgIHJldHVybiBvYmouY29uc3RydWN0b3IubmFtZTtcbiAgaWYgKHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiAmJiBvYmoubmFtZSkgcmV0dXJuIG9iai5uYW1lO1xuICByZXR1cm4gb2JqLnRvU3RyaW5nKCk7XG59XG4iLCJpbXBvcnQgeyBUcmFuc2FjdGlvbkxvY2sgfSBmcm9tIFwiLi9pbnRlcmZhY2VzL1RyYW5zYWN0aW9uTG9ja1wiO1xuaW1wb3J0IHsgUmVmbGVjdGlvbiB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgQ2FsbGJhY2sgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgU3luY3Jvbm91c0xvY2sgfSBmcm9tIFwiLi9sb2Nrcy9TeW5jcm9ub3VzTG9ja1wiO1xuaW1wb3J0IHtcbiAgREJLZXlzLFxuICBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUsXG59IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgZ2V0T2JqZWN0TmFtZSB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbmFsS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFRyYW5zYWN0aW9uIENsYXNzXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZVxuICogQHBhcmFtIHtzdHJpbmd9IFttZXRob2RdXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCk6IHZvaWR9IFthY3Rpb25dXG4gKiBAcGFyYW0ge2FueVtdfSBbbWV0YWRhdGFdXG4gKlxuICogQGNsYXNzIFRyYW5zYWN0aW9uXG4gKlxuICogQGNhdGVnb3J5IFRyYW5zYWN0aW9uc1xuICovXG5leHBvcnQgY2xhc3MgVHJhbnNhY3Rpb24ge1xuICByZWFkb25seSBpZDogbnVtYmVyO1xuICBwcm90ZWN0ZWQgYWN0aW9uPzogKCkgPT4gYW55O1xuICByZWFkb25seSBtZXRob2Q/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHNvdXJjZT86IHN0cmluZztcbiAgcmVhZG9ubHkgbG9nOiBzdHJpbmdbXTtcbiAgcHJpdmF0ZSByZWFkb25seSBtZXRhZGF0YT86IGFueVtdO1xuXG4gIHByaXZhdGUgc3RhdGljIGxvY2s6IFRyYW5zYWN0aW9uTG9jaztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBzb3VyY2U6IHN0cmluZyxcbiAgICBtZXRob2Q/OiBzdHJpbmcsXG4gICAgYWN0aW9uPzogKCkgPT4gYW55LFxuICAgIG1ldGFkYXRhPzogYW55W11cbiAgKSB7XG4gICAgdGhpcy5pZCA9IERhdGUubm93KCk7XG4gICAgdGhpcy5hY3Rpb24gPSBhY3Rpb247XG4gICAgdGhpcy5tZXRob2QgPSBtZXRob2Q7XG4gICAgdGhpcy5sb2cgPSBbW3RoaXMuaWQsIHNvdXJjZSwgbWV0aG9kXS5qb2luKFwiIHwgXCIpXTtcbiAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZTtcbiAgICB0aGlzLm1ldGFkYXRhID0gbWV0YWRhdGE7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUHVzaGVzIGEgdHJhbnNhY3Rpb24gdG8gcXVlIHF1ZXVlIGFuZCB3YWl0cyBpdHMgcmVzb2x1dGlvblxuICAgKlxuICAgKiBAcGFyYW0ge2FueX0gaXNzdWVyIGFueSBjbGFzcy4gd2lsbCBiZSB1c2VkIGFzIHRoaXMgd2hlbiBjYWxsaW5nIHRoZSBjYWxsYmFja01ldGhvZFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja01ldGhvZCBjYWxsYmFjayBmdW5jdGlvbiBjb250YWluaW5nIHRoZSB0cmFuc2FjdGlvbi4gd2lsbCBiZSBjYWxsZWQgd2l0aCB0aGUgaXNzdWVhciBhcyB0aGlzXG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3MgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZC4gTGFzdCBvbmUgbXVzdCBiZSB0aGUgY2FsbGJhY2tcbiAgICovXG4gIHN0YXRpYyBwdXNoKFxuICAgIGlzc3VlcjogYW55LFxuICAgIGNhbGxiYWNrTWV0aG9kOiAoLi4uYXJneno6IChhbnkgfCBDYWxsYmFjaylbXSkgPT4gdm9pZCxcbiAgICAuLi5hcmdzOiAoYW55IHwgQ2FsbGJhY2spW11cbiAgKSB7XG4gICAgY29uc3QgY2FsbGJhY2s6IENhbGxiYWNrID0gYXJncy5wb3AoKTtcbiAgICBpZiAoIWNhbGxiYWNrIHx8IHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBjYWxsYmFja1wiKTtcbiAgICBjb25zdCBjYiA9IChlcnI/OiBFcnJvciwgLi4uYXJnczogYW55W10pID0+IHtcbiAgICAgIFRyYW5zYWN0aW9uLmdldExvY2soKVxuICAgICAgICAucmVsZWFzZShlcnIpXG4gICAgICAgIC50aGVuKCgpID0+IGNhbGxiYWNrKGVyciwgLi4uYXJncykpO1xuICAgIH07XG4gICAgY29uc3QgdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uID0gbmV3IFRyYW5zYWN0aW9uKFxuICAgICAgaXNzdWVyLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgICBjYWxsYmFja01ldGhvZC5uYW1lID8gZ2V0T2JqZWN0TmFtZShjYWxsYmFja01ldGhvZCkgOiBcIkFub255bW91c1wiLFxuICAgICAgKCkgPT4ge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2tNZXRob2QuY2FsbChcbiAgICAgICAgICB0cmFuc2FjdGlvbi5iaW5kVG9UcmFuc2FjdGlvbihpc3N1ZXIpLFxuICAgICAgICAgIC4uLmFyZ3MsXG4gICAgICAgICAgY2JcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICApO1xuICAgIFRyYW5zYWN0aW9uLmdldExvY2soKS5zdWJtaXQodHJhbnNhY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFNldHMgdGhlIGxvY2sgdG8gYmUgdXNlZFxuICAgKiBAcGFyYW0gbG9ja1xuICAgKi9cbiAgc3RhdGljIHNldExvY2sobG9jazogVHJhbnNhY3Rpb25Mb2NrKSB7XG4gICAgdGhpcy5sb2NrID0gbG9jaztcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBnZXRzIHRoZSBsb2NrXG4gICAqL1xuICBzdGF0aWMgZ2V0TG9jaygpOiBUcmFuc2FjdGlvbkxvY2sge1xuICAgIGlmICghdGhpcy5sb2NrKSB0aGlzLmxvY2sgPSBuZXcgU3luY3Jvbm91c0xvY2soKTtcbiAgICByZXR1cm4gdGhpcy5sb2NrO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHN1Ym1pdHMgYSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKi9cbiAgc3RhdGljIHN1Ym1pdCh0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb24pIHtcbiAgICBUcmFuc2FjdGlvbi5nZXRMb2NrKCkuc3VibWl0KHRyYW5zYWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSByZWxlYXNlcyB0aGUgbG9ja1xuICAgKiBAcGFyYW0ge0Vycn0gZXJyXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgcmVsZWFzZShlcnI/OiBFcnJvcikge1xuICAgIHJldHVybiBUcmFuc2FjdGlvbi5nZXRMb2NrKCkucmVsZWFzZShlcnIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHJldHJpZXZlcyB0aGUgbWV0YWRhdGEgZm9yIHRoZSB0cmFuc2FjdGlvblxuICAgKi9cbiAgZ2V0TWV0YWRhdGEoKSB7XG4gICAgcmV0dXJuIHRoaXMubWV0YWRhdGEgPyBbLi4udGhpcy5tZXRhZGF0YV0gOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgQmluZHMgYSBuZXcgb3BlcmF0aW9uIHRvIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IG5leHRUcmFuc2FjdGlvblxuICAgKi9cbiAgYmluZFRyYW5zYWN0aW9uKG5leHRUcmFuc2FjdGlvbjogVHJhbnNhY3Rpb24pIHtcbiAgICAvLyBhbGwoYEJpbmRpbmcgdGhlIHswfSB0byB7MX1gLCBuZXh0VHJhbnNhY3Rpb24sIHRoaXMpO1xuICAgIHRoaXMubG9nLnB1c2goLi4ubmV4dFRyYW5zYWN0aW9uLmxvZyk7XG4gICAgbmV4dFRyYW5zYWN0aW9uLmJpbmRUcmFuc2FjdGlvbiA9IHRoaXMuYmluZFRvVHJhbnNhY3Rpb24uYmluZCh0aGlzKTtcbiAgICBuZXh0VHJhbnNhY3Rpb24uYmluZFRvVHJhbnNhY3Rpb24gPSB0aGlzLmJpbmRUb1RyYW5zYWN0aW9uLmJpbmQodGhpcyk7XG4gICAgdGhpcy5hY3Rpb24gPSBuZXh0VHJhbnNhY3Rpb24uYWN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEJpbmRzIHRoZSBUcmFuc2FjdGlvbmFsIERlY29yYXRlZCBPYmplY3QgdG8gdGhlIHRyYW5zYWN0aW9uXG4gICAqIEBkZXNjcmlwdGlvbiBieSBoYXZpbmcgYWxsIHtAbGluayB0cmFuc2FjdGlvbmFsfSBkZWNvcmF0ZWRcbiAgICogbWV0aG9kcyBhbHdheXMgcGFzcyB0aGUgY3VycmVudCBUcmFuc2FjdGlvbiBhcyBhbiBhcmd1bWVudFxuICAgKlxuICAgKiBAcGFyYW0ge2FueX0gb2JqXG4gICAqIEByZXR1cm4ge2FueX0gdGhlIGJvdW5kIHtAcGFyYW0gb2JqfVxuICAgKi9cbiAgYmluZFRvVHJhbnNhY3Rpb24ob2JqOiBhbnkpOiBhbnkge1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uYWxNZXRob2RzID0gZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzUmVjdXJzaXZlKFxuICAgICAgb2JqLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgVHJhbnNhY3Rpb25hbEtleXMuUkVGTEVDVFxuICAgICk7XG4gICAgaWYgKCF0cmFuc2FjdGlvbmFsTWV0aG9kcykgcmV0dXJuIG9iajtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXNcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IGJvdW5kT2JqID0gUmVmbGVjdGlvbi5nZXRBbGxQcm9wZXJ0aWVzKG9iaikucmVkdWNlKFxuICAgICAgKGFjY3VtOiBhbnksIGs6IHN0cmluZykgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgT2JqZWN0LmtleXModHJhbnNhY3Rpb25hbE1ldGhvZHMpLmluZGV4T2YoaykgIT09IC0xICYmXG4gICAgICAgICAgdHJhbnNhY3Rpb25hbE1ldGhvZHNba10uZmluZChcbiAgICAgICAgICAgIChvKSA9PiBvLmtleSA9PT0gVHJhbnNhY3Rpb25hbEtleXMuVFJBTlNBQ1RJT05BTFxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgICAgIGFjY3VtW2tdID0gKC4uLmFyZ3M6IGFueVtdKSA9PlxuICAgICAgICAgICAgb2JqW2tdLmNhbGwob2JqLl9fb3JpZ2luYWxPYmogfHwgb2JqLCBzZWxmLCAuLi5hcmdzKTtcbiAgICAgICAgZWxzZSBpZiAoayA9PT0gXCJjbGF6elwiIHx8IGsgPT09IFwiY29uc3RydWN0b3JcIikgYWNjdW1ba10gPSBvYmpba107XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmpba10gPT09IFwiZnVuY3Rpb25cIilcbiAgICAgICAgICBhY2N1bVtrXSA9IG9ialtrXS5iaW5kKG9iai5fX29yaWdpbmFsT2JqIHx8IG9iaik7XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmpba10gPT09IFwib2JqZWN0XCIgJiYgb2JqW2tdLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgY29uc3QgZGVjcyA9IFJlZmxlY3Rpb24uZ2V0Q2xhc3NEZWNvcmF0b3JzKFxuICAgICAgICAgICAgVHJhbnNhY3Rpb25hbEtleXMuUkVGTEVDVCxcbiAgICAgICAgICAgIG9ialtrXVxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKGRlY3MuZmluZCgoZTogYW55KSA9PiBlLmtleSA9PT0gVHJhbnNhY3Rpb25hbEtleXMuVFJBTlNBQ1RJT05BTCkpXG4gICAgICAgICAgICBhY2N1bVtrXSA9IHNlbGYuYmluZFRvVHJhbnNhY3Rpb24ob2JqW2tdKTtcbiAgICAgICAgICBlbHNlIGFjY3VtW2tdID0gb2JqW2tdO1xuICAgICAgICB9IGVsc2UgYWNjdW1ba10gPSBvYmpba107XG5cbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSxcbiAgICAgIHt9XG4gICAgKTtcblxuICAgIGJvdW5kT2JqW0RCS2V5cy5PUklHSU5BTF0gPSBvYmpbREJLZXlzLk9SSUdJTkFMXSB8fCBvYmo7XG4gICAgYm91bmRPYmoudG9TdHJpbmcgPSAoKSA9PlxuICAgICAgZ2V0T2JqZWN0TmFtZShib3VuZE9ialtEQktleXMuT1JJR0lOQUxdKSArXG4gICAgICBcIiBwcm94eSBmb3IgdHJhbnNhY3Rpb24gXCIgK1xuICAgICAgdGhpcy5pZDtcblxuICAgIHJldHVybiBib3VuZE9iajtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBGaXJlcyB0aGUgVHJhbnNhY3Rpb25cbiAgICovXG4gIGZpcmUoKSB7XG4gICAgaWYgKCF0aGlzLmFjdGlvbikgdGhyb3cgbmV3IEVycm9yKGBNaXNzaW5nIHRoZSBtZXRob2RgKTtcbiAgICByZXR1cm4gdGhpcy5hY3Rpb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSB0b1N0cmluZyBvdmVycmlkZVxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFt3aXRoSWRdIGRlZmF1bHRzIHRvIHRydWVcbiAgICogQHBhcmFtIHtib29sZWFufSBbd2l0aExvZ10gZGVmYXVsdHMgdG8gdHJ1ZVxuICAgKi9cbiAgdG9TdHJpbmcod2l0aElkID0gdHJ1ZSwgd2l0aExvZyA9IGZhbHNlKSB7XG4gICAgcmV0dXJuIGAke3dpdGhJZCA/IGBbJHt0aGlzLmlkfV1gIDogXCJcIn1bVHJhbnNhY3Rpb25dWyR7dGhpcy5zb3VyY2V9LiR7dGhpcy5tZXRob2R9JHtcbiAgICAgIHdpdGhMb2cgPyBgXVxcblRyYW5zYWN0aW9uIExvZzpcXG4ke3RoaXMubG9nLmpvaW4oXCJcXG5cIil9YCA6IFwiXVwiXG4gICAgfWA7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgZ2V0cyB0aGUgdHJhbnNhY3Rpb25zIHJlZmxlY3Rpb25zIGtleVxuICAgKiBAZnVuY3Rpb24gZ2V0UmVwb0tleVxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gICAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9ycy5UcmFuc2FjdGlvbnNcbiAgICogKi9cbiAgc3RhdGljIGtleShrZXk6IHN0cmluZykge1xuICAgIHJldHVybiBUcmFuc2FjdGlvbmFsS2V5cy5SRUZMRUNUICsga2V5O1xuICB9XG59XG4iLCJpbXBvcnQgeyBUcmFuc2FjdGlvbmFsS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgbWV0YWRhdGEgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IFRyYW5zYWN0aW9uIH0gZnJvbSBcIi4vVHJhbnNhY3Rpb25cIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBTZXRzIGEgY2xhc3MgQXN5bmMgbWV0aG9kIGFzIHRyYW5zYWN0aW9uYWxcbiAqXG4gKiBAcGFyYW0ge2FueVtdfSAgW2RhdGFdIG9wdGlvbiBtZXRhZGF0YSBhdmFpbGFibGUgdG8gdGhlIHtAbGluayBUcmFuc2FjdGlvbkxvY2t9XG4gKlxuICogQGZ1bmN0aW9uIHRyYW5zYWN0aW9uYWxcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuRGVjb3JhdG9ycy50cmFuc2FjdGlvbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zYWN0aW9uYWwoLi4uZGF0YTogYW55W10pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChcbiAgICB0YXJnZXQ6IGFueSxcbiAgICBwcm9wZXJ0eUtleT86IGFueSxcbiAgICBkZXNjcmlwdG9yPzogUHJvcGVydHlEZXNjcmlwdG9yXG4gICkge1xuICAgIGlmICghZGVzY3JpcHRvcilcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiTWlzc2luZyBkZXNjcmlwdG9yLiBTaG91bGQgYmUgaW1wb3NzaWJsZVwiKTtcbiAgICBtZXRhZGF0YShUcmFuc2FjdGlvbi5rZXkoVHJhbnNhY3Rpb25hbEtleXMuVFJBTlNBQ1RJT05BTCksIGRhdGEpKFxuICAgICAgdGFyZ2V0LFxuICAgICAgcHJvcGVydHlLZXlcbiAgICApO1xuXG4gICAgY29uc3Qgb3JpZ2luYWxNZXRob2QgPSBkZXNjcmlwdG9yLnZhbHVlO1xuXG4gICAgY29uc3QgbWV0aG9kV3JhcHBlciA9IGZ1bmN0aW9uICh0aGlzOiBhbnksIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2U8YW55PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGNvbnN0IGNiID0gKGVycj86IEVycm9yLCByZXN1bHQ/OiBhbnkpID0+IHtcbiAgICAgICAgICBUcmFuc2FjdGlvbi5yZWxlYXNlKGVycikudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBpZiAoZXJyKSByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgbGV0IHRyYW5zYWN0aW9uID0gYXJncy5zaGlmdCgpO1xuICAgICAgICBpZiAodHJhbnNhY3Rpb24gaW5zdGFuY2VvZiBUcmFuc2FjdGlvbikge1xuICAgICAgICAgIGNvbnN0IHVwZGF0ZWRUcmFuc2FjdGlvbjogVHJhbnNhY3Rpb24gPSBuZXcgVHJhbnNhY3Rpb24oXG4gICAgICAgICAgICB0aGlzLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgICAgICAgICBwcm9wZXJ0eUtleSxcbiAgICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgb3JpZ2luYWxNZXRob2RcbiAgICAgICAgICAgICAgICAuY2FsbCh1cGRhdGVkVHJhbnNhY3Rpb24uYmluZFRvVHJhbnNhY3Rpb24oc2VsZiksIC4uLmFyZ3MpXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVzb2x2ZSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gocmVqZWN0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkYXRhLmxlbmd0aCA/IGRhdGEgOiB1bmRlZmluZWRcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgdHJhbnNhY3Rpb24uYmluZFRyYW5zYWN0aW9uKHVwZGF0ZWRUcmFuc2FjdGlvbik7XG4gICAgICAgICAgdHJhbnNhY3Rpb24uZmlyZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFyZ3MudW5zaGlmdCh0cmFuc2FjdGlvbik7XG4gICAgICAgICAgdHJhbnNhY3Rpb24gPSBuZXcgVHJhbnNhY3Rpb24oXG4gICAgICAgICAgICB0aGlzLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgICAgICAgICBwcm9wZXJ0eUtleSxcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgb3JpZ2luYWxNZXRob2RcbiAgICAgICAgICAgICAgICAuY2FsbCh0cmFuc2FjdGlvbi5iaW5kVG9UcmFuc2FjdGlvbihzZWxmKSwgLi4uYXJncylcbiAgICAgICAgICAgICAgICAudGhlbigocmVzdWx0OiBhbnkpID0+IGNiKHVuZGVmaW5lZCwgcmVzdWx0KSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goY2IpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRhdGEubGVuZ3RoID8gZGF0YSA6IHVuZGVmaW5lZFxuICAgICAgICAgICk7XG4gICAgICAgICAgVHJhbnNhY3Rpb24uc3VibWl0KHRyYW5zYWN0aW9uKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtZXRob2RXcmFwcGVyLCBcIm5hbWVcIiwge1xuICAgICAgdmFsdWU6IHByb3BlcnR5S2V5LFxuICAgIH0pO1xuICAgIGRlc2NyaXB0b3IudmFsdWUgPSBtZXRob2RXcmFwcGVyO1xuICB9O1xufVxuLy9cbi8vIC8qKlxuLy8gICogQHN1bW1hcnkgU2V0cyBhIGNsYXNzIEFzeW5jIG1ldGhvZCBhcyB0cmFuc2FjdGlvbmFsXG4vLyAgKlxuLy8gICogQHBhcmFtIHthbnlbXX0gIFttZXRhZGF0YV0gb3B0aW9uIG1ldGFkYXRhIGF2YWlsYWJsZSB0byB0aGUge0BsaW5rIFRyYW5zYWN0aW9uTG9ja31cbi8vICAqXG4vLyAgKiBAZnVuY3Rpb24gdHJhbnNhY3Rpb25hbEFzeW5jXG4vLyAgKlxuLy8gICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzLkRlY29yYXRvcnMudHJhbnNhY3Rpb25zXG4vLyAgKi9cbi8vIGV4cG9ydCBmdW5jdGlvbiB0cmFuc2FjdGlvbmFsQXN5bmMoLi4ubWV0YWRhdGE6IGFueVtdKSB7XG4vLyAgIHJldHVybiBmdW5jdGlvbiAoXG4vLyAgICAgdGFyZ2V0OiBhbnksXG4vLyAgICAgcHJvcGVydHlLZXk6IHN0cmluZyxcbi8vICAgICBkZXNjcmlwdG9yOiBQcm9wZXJ0eURlc2NyaXB0b3IsXG4vLyAgICkge1xuLy8gICAgIG1ldGFkYXN0YShnZXRUcmFuc2FjdGlvbmFsS2V5KFRyYW5zYWN0aW9uYWxLZXlzLlRSQU5TQUNUSU9OQUwpKVxuLy8gICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoXG4vLyAgICAgICAsXG4vLyAgICAgICB7XG4vLyAgICAgICAgIHR5cGU6IFwiYXN5bmNcIixcbi8vICAgICAgICAgbWV0YWRhdGE6IG1ldGFkYXRhLmxlbmd0aCA/IG1ldGFkYXRhIDogdW5kZWZpbmVkLFxuLy8gICAgICAgfSBhcyBUcmFuc2FjdGlvbmFsTWV0YWRhdGEsXG4vLyAgICAgICB0YXJnZXQsXG4vLyAgICAgICBwcm9wZXJ0eUtleSxcbi8vICAgICApO1xuLy9cbi8vICAgICBjb25zdCBvcmlnaW5hbE1ldGhvZCA9IGRlc2NyaXB0b3IudmFsdWU7XG4vL1xuLy8gICAgIGNvbnN0IG1ldGhvZFdyYXBwZXIgPSBmdW5jdGlvbiAodGhpczogYW55LCAuLi5hcmdzOiBhbnlbXSkge1xuLy8gICAgICAgY29uc3QgY2FsbGJhY2s6IENhbGxiYWNrID0gYXJncy5wb3AoKTtcbi8vICAgICAgIGlmICghY2FsbGJhY2sgfHwgdHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpXG4vLyAgICAgICAgIHRocm93IG5ldyBDcml0aWNhbEVycm9yKGBNaXNzaW5nIENhbGxiYWNrYCk7XG4vL1xuLy8gICAgICAgY29uc3QgY2IgPSAoZXJyPzogRXJyLCAuLi5hcmdzOiBhbnlbXSkgPT4ge1xuLy8gICAgICAgICBUcmFuc2FjdGlvbi5yZWxlYXNlKGVycikudGhlbigoXykgPT4gY2FsbGJhY2soZXJyLCAuLi5hcmdzKSk7XG4vLyAgICAgICB9O1xuLy9cbi8vICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuLy9cbi8vICAgICAgIGxldCB0cmFuc2FjdGlvbiA9IGFyZ3Muc2hpZnQoKTtcbi8vICAgICAgIGlmICh0cmFuc2FjdGlvbiBpbnN0YW5jZW9mIFRyYW5zYWN0aW9uKSB7XG4vLyAgICAgICAgIGNvbnN0IHVwZGF0ZWRUcmFuc2FjdGlvbjogVHJhbnNhY3Rpb24gPSBuZXcgVHJhbnNhY3Rpb24oXG4vLyAgICAgICAgICAgdGhpcy5jb25zdHJ1Y3Rvci5uYW1lLFxuLy8gICAgICAgICAgIHByb3BlcnR5S2V5LFxuLy8gICAgICAgICAgICgpID0+IHtcbi8vICAgICAgICAgICAgIHRyeSB7XG4vLyAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbE1ldGhvZC5jYWxsKFxuLy8gICAgICAgICAgICAgICAgIHVwZGF0ZWRUcmFuc2FjdGlvbi5iaW5kVG9UcmFuc2FjdGlvbihzZWxmKSxcbi8vICAgICAgICAgICAgICAgICAuLi5hcmdzLFxuLy8gICAgICAgICAgICAgICAgIGNhbGxiYWNrLFxuLy8gICAgICAgICAgICAgICApO1xuLy8gICAgICAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4vLyAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlKTtcbi8vICAgICAgICAgICAgIH1cbi8vICAgICAgICAgICB9LFxuLy8gICAgICAgICAgIG1ldGFkYXRhLmxlbmd0aCA/IG1ldGFkYXRhIDogdW5kZWZpbmVkLFxuLy8gICAgICAgICApO1xuLy9cbi8vICAgICAgICAgdHJhbnNhY3Rpb24uYmluZFRyYW5zYWN0aW9uKHVwZGF0ZWRUcmFuc2FjdGlvbik7XG4vLyAgICAgICAgIHRyYW5zYWN0aW9uLmZpcmUoKTtcbi8vICAgICAgIH0gZWxzZSB7XG4vLyAgICAgICAgIGFyZ3MudW5zaGlmdCh0cmFuc2FjdGlvbik7XG4vLyAgICAgICAgIHRyYW5zYWN0aW9uID0gdW5kZWZpbmVkO1xuLy8gICAgICAgICB0cmFuc2FjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbihcbi8vICAgICAgICAgICB0aGlzLmNvbnN0cnVjdG9yLm5hbWUsXG4vLyAgICAgICAgICAgcHJvcGVydHlLZXksXG4vLyAgICAgICAgICAgKCkgPT4ge1xuLy8gICAgICAgICAgICAgdHJ5IHtcbi8vICAgICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsTWV0aG9kLmNhbGwoXG4vLyAgICAgICAgICAgICAgICAgdHJhbnNhY3Rpb24uYmluZFRvVHJhbnNhY3Rpb24oc2VsZiksXG4vLyAgICAgICAgICAgICAgICAgLi4uYXJncyxcbi8vICAgICAgICAgICAgICAgICBjYixcbi8vICAgICAgICAgICAgICAgKTtcbi8vICAgICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuLy8gICAgICAgICAgICAgICByZXR1cm4gY2IoZSk7XG4vLyAgICAgICAgICAgICB9XG4vLyAgICAgICAgICAgfSxcbi8vICAgICAgICAgICBtZXRhZGF0YS5sZW5ndGggPyBtZXRhZGF0YSA6IHVuZGVmaW5lZCxcbi8vICAgICAgICAgKTtcbi8vICAgICAgICAgVHJhbnNhY3Rpb24uc3VibWl0KHRyYW5zYWN0aW9uKTtcbi8vICAgICAgIH1cbi8vICAgICB9O1xuLy9cbi8vICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobWV0aG9kV3JhcHBlciwgXCJuYW1lXCIsIHtcbi8vICAgICAgIHZhbHVlOiBwcm9wZXJ0eUtleSxcbi8vICAgICB9KTtcbi8vICAgICBkZXNjcmlwdG9yLnZhbHVlID0gbWV0aG9kV3JhcHBlcjtcbi8vICAgfTtcbi8vIH1cblxuLyoqXG4gKiBAc3VtbWFyeSBVdGlsIGZ1bmN0aW9uIHRvIHdyYXAgc3VwZXIgY2FsbHMgd2l0aCB0aGUgdHJhbnNhY3Rpb24gd2hlbiB0aGUgc3VwZXIncyBtZXRob2QgaXMgYWxzbyB0cmFuc2FjdGlvbmFsXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gbWV0aG9kIHRoZSBzdXBlciBtZXRob2QgKG11c3QgYmUgYm91bmQgdG8gdGhlIHByb3BlciB0aGlzKSwgZWc6IHN1cGVyLmNyZWF0ZS5iaW5kKHRoaXMpXG4gKiBAcGFyYW0ge2FueVtdfSBhcmdzIHRoZSBhcmd1bWVudHMgdG8gY2FsbCB0aGUgbWV0aG9kIHdpdGhcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuVHJhbnNhY3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zYWN0aW9uYWxTdXBlckNhbGwobWV0aG9kOiBhbnksIC4uLmFyZ3M6IGFueSkge1xuICBjb25zdCBsb2NrID0gVHJhbnNhY3Rpb24uZ2V0TG9jaygpO1xuICBjb25zdCBjdXJyZW50VHJhbnNhY3Rpb24gPSBsb2NrLmN1cnJlbnRUcmFuc2FjdGlvbjtcbiAgcmV0dXJuIG1ldGhvZChjdXJyZW50VHJhbnNhY3Rpb24sIC4uLmFyZ3MpO1xufVxuIiwiZXhwb3J0ICogZnJvbSBcIi4vaW50ZXJmYWNlc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vbG9ja3NcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnN0YW50c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZGVjb3JhdG9yc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vVHJhbnNhY3Rpb25cIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgTW9kdWxlIHN1bW1hcnlcbiAqIEBkZXNjcmlwdGlvbiBNb2R1bGUgZGVzY3JpcHRpb25cbiAqIEBtb2R1bGUgdHMtd29ya3NwYWNlXG4gKi9cblxuLyoqXG4gKiBAc3VtbWFyeSBOYW1lc3BhY2Ugc3VtbWFyeVxuICogQGRlc2NyaXB0aW9uIE5hbWVzcGFjZSBkZXNjcmlwdGlvblxuICogQG5hbWVzcGFjZSBOYW1lc3BhY2VcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dHMtd29ya3NwYWNlXG4gKi9cblxuLyoqXG4gKiBAc3VtbWFyeSBzdG9yZXMgdGhlIGN1cnJlbnQgcGFja2FnZSB2ZXJzaW9uXG4gKiBAZGVzY3JpcHRpb24gdGhpcyBpcyBob3cgeW91IHNob3VsZCBkb2N1bWVudCBhIGNvbnN0YW50XG4gKiBAY29uc3QgVkVSU0lPTlxuICogQG1lbWJlck9mIG1vZHVsZTp0cy13b3Jrc3BhY2VcbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG4iXSwibmFtZXMiOlsiZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzUmVjdXJzaXZlIiwiUmVmbGVjdGlvbiIsIkRCS2V5cyIsIkludGVybmFsRXJyb3IiLCJtZXRhZGF0YSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0lBRUE7Ozs7O0lBS0c7VUFDVSxJQUFJLENBQUE7SUFBakIsSUFBQSxXQUFBLEdBQUE7WUFDVSxJQUFLLENBQUEsS0FBQSxHQUFtQixFQUFFO1lBQzFCLElBQU0sQ0FBQSxNQUFBLEdBQUcsS0FBSzs7SUFFdEI7OztJQUdHO1FBQ0gsTUFBTSxPQUFPLENBQUMsSUFBZSxFQUFBO0lBQzNCLFFBQUEsTUFBTSxJQUFJLENBQUMsT0FBTyxFQUFFO0lBQ3BCLFFBQUEsSUFBSSxNQUFXO0lBQ2YsUUFBQSxJQUFJO2dCQUNGLE1BQU0sR0FBRyxNQUFNLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7O1lBQ3RDLE9BQU8sQ0FBTSxFQUFFO2dCQUNmLElBQUksQ0FBQyxPQUFPLEVBQUU7SUFDZCxZQUFBLE1BQU0sQ0FBQzs7WUFFVCxJQUFJLENBQUMsT0FBTyxFQUFFO0lBQ2QsUUFBQSxPQUFPLE1BQU07O0lBR2Y7OztJQUdHO0lBQ0gsSUFBQSxNQUFNLE9BQU8sR0FBQTs7WUFFWCxNQUFNLElBQUksR0FBRyxJQUFJO0lBQ2pCLFFBQUEsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO0lBQ2YsWUFBQSxPQUFPLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxLQUFL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O0lBQ2xDLEtBQUM7SUFDSDtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUVBOzs7Ozs7O0lBT0c7YUFDYSxzQkFBc0IsQ0FBQyxNQUFXLEVBQUUsR0FBRyxJQUFTLEVBQUE7SUFDOUQsSUFBQSxNQUFNLElBQUksR0FBRyxXQUFXLENBQUMsT0FBTyxFQUFFO0lBQ2xDLElBQUEsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsa0JBQWtCO0lBQ2xELElBQUEsT0FBTyxNQUFNLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxJQUFJLENBQUM7SUFDNUM7O0lDaExBOzs7O0lBSUc7SUFFSDs7Ozs7SUFLRztJQUVIOzs7OztJQUtHO0FBQ0ksVUFBTSxPQUFPLEdBQUc7Ozs7Ozs7Ozs7Ozs7OyJ9
|