@pmcretail/mapper-library 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +2 -2
  2. package/bundles/pmcretail-mapper-library.umd.js +6133 -0
  3. package/bundles/pmcretail-mapper-library.umd.js.map +1 -0
  4. package/bundles/pmcretail-mapper-library.umd.min.js +16 -0
  5. package/bundles/pmcretail-mapper-library.umd.min.js.map +1 -0
  6. package/esm2015/lib/RJ-mapper.class.js +1061 -0
  7. package/esm2015/lib/TransactionDocumentBuilder.js +1535 -0
  8. package/esm2015/lib/basket.service.js +851 -0
  9. package/esm2015/lib/mapper-library.component.js +27 -0
  10. package/esm2015/lib/mapper-library.model.js +974 -0
  11. package/esm2015/lib/mapper-library.module.js +21 -0
  12. package/esm2015/lib/number-util.service.js +77 -0
  13. package/esm2015/pmcretail-mapper-library.js +10 -0
  14. package/esm2015/public-api.js +12 -0
  15. package/esm5/lib/RJ-mapper.class.js +1262 -0
  16. package/esm5/lib/TransactionDocumentBuilder.js +2469 -0
  17. package/esm5/lib/basket.service.js +1076 -0
  18. package/esm5/lib/mapper-library.component.js +29 -0
  19. package/esm5/lib/mapper-library.model.js +974 -0
  20. package/esm5/lib/mapper-library.module.js +25 -0
  21. package/esm5/lib/number-util.service.js +94 -0
  22. package/esm5/pmcretail-mapper-library.js +10 -0
  23. package/esm5/public-api.js +12 -0
  24. package/{fesm2020/pmcretail-mapper-library.mjs → fesm2015/pmcretail-mapper-library.js} +2627 -602
  25. package/fesm2015/pmcretail-mapper-library.js.map +1 -0
  26. package/fesm5/pmcretail-mapper-library.js +5919 -0
  27. package/fesm5/pmcretail-mapper-library.js.map +1 -0
  28. package/lib/TransactionDocumentBuilder.d.ts +1 -1
  29. package/lib/basket.service.d.ts +1 -5
  30. package/lib/mapper-library.component.d.ts +0 -3
  31. package/lib/mapper-library.module.d.ts +0 -5
  32. package/lib/number-util.service.d.ts +2 -4
  33. package/package.json +16 -26
  34. package/pmcretail-mapper-library.d.ts +1 -1
  35. package/pmcretail-mapper-library.metadata.json +1 -0
  36. package/public-api.d.ts +0 -1
  37. package/esm2020/lib/RJ-mapper.class.mjs +0 -597
  38. package/esm2020/lib/TransactionDocumentBuilder.mjs +0 -1240
  39. package/esm2020/lib/basket.service.mjs +0 -527
  40. package/esm2020/lib/mapper-library.component.mjs +0 -26
  41. package/esm2020/lib/mapper-library.model.mjs +0 -20
  42. package/esm2020/lib/mapper-library.module.mjs +0 -21
  43. package/esm2020/lib/mapper-library.service.mjs +0 -56
  44. package/esm2020/lib/number-util.service.mjs +0 -41
  45. package/esm2020/pmcretail-mapper-library.mjs +0 -5
  46. package/esm2020/public-api.mjs +0 -8
  47. package/fesm2015/pmcretail-mapper-library.mjs +0 -2526
  48. package/fesm2015/pmcretail-mapper-library.mjs.map +0 -1
  49. package/fesm2020/pmcretail-mapper-library.mjs.map +0 -1
  50. package/lib/mapper-library.service.d.ts +0 -9
@@ -0,0 +1,1076 @@
1
+ /**
2
+ * @fileoverview added by tsickle
3
+ * Generated from: lib/basket.service.ts
4
+ * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5
+ */
6
+ import * as tslib_1 from "tslib";
7
+ import { BehaviorSubject } from 'rxjs';
8
+ import { DELIVERY_METHODS } from './mapper-library.model';
9
+ var BasketService = /** @class */ (function () {
10
+ function BasketService(numberUtilService) {
11
+ this.numberUtilService = numberUtilService;
12
+ this.currentBasket = {
13
+ products: [],
14
+ transactionDiscount: [],
15
+ quantity: 0,
16
+ total: 0,
17
+ saleTotal: 0,
18
+ baseCurrency: ''
19
+ };
20
+ this.basketSource = new BehaviorSubject(null);
21
+ this.basket = this.basketSource.asObservable();
22
+ this.productSource = new BehaviorSubject(null);
23
+ this.product = this.productSource.asObservable();
24
+ this.peerSource = new BehaviorSubject(false);
25
+ this.peerSync = this.peerSource.asObservable();
26
+ this.scanSource = new BehaviorSubject(false);
27
+ this.scanner = this.scanSource.asObservable();
28
+ }
29
+ Object.defineProperty(BasketService.prototype, "isMixedBasketSales", {
30
+ get: /**
31
+ * @return {?}
32
+ */
33
+ function () {
34
+ return this._isMixedBasketSales;
35
+ },
36
+ set: /**
37
+ * @param {?} v
38
+ * @return {?}
39
+ */
40
+ function (v) {
41
+ this._isMixedBasketSales = v;
42
+ },
43
+ enumerable: true,
44
+ configurable: true
45
+ });
46
+ /**
47
+ * @param {?} basket
48
+ * @return {?}
49
+ */
50
+ BasketService.prototype.updateBasket = /**
51
+ * @param {?} basket
52
+ * @return {?}
53
+ */
54
+ function (basket) {
55
+ this.currentBasket = basket;
56
+ this.isMixedBasketSales = this.filterProductListWithWebOrder(true).length > 0;
57
+ this.basketSource.next(basket);
58
+ };
59
+ /**
60
+ * calculates the total basket value and quantity
61
+ * @param null
62
+ * @returns void
63
+ */
64
+ /**
65
+ * calculates the total basket value and quantity
66
+ * @param {?} basketDetails
67
+ * @param {?} basketState
68
+ * @return {?} void
69
+ */
70
+ BasketService.prototype.updateBasketTotal = /**
71
+ * calculates the total basket value and quantity
72
+ * @param {?} basketDetails
73
+ * @param {?} basketState
74
+ * @return {?} void
75
+ */
76
+ function (basketDetails, basketState) {
77
+ var e_1, _a;
78
+ basketDetails.quantity = 0;
79
+ basketDetails.total = 0;
80
+ try {
81
+ for (var _b = tslib_1.__values(basketDetails.products), _c = _b.next(); !_c.done; _c = _b.next()) {
82
+ var p = _c.value;
83
+ basketDetails.quantity = basketDetails.quantity + p.quantity;
84
+ basketDetails.total =
85
+ this.numberUtilService.trimTo2Decimal(basketDetails.total) +
86
+ this.numberUtilService.trimTo2Decimal(p.total);
87
+ }
88
+ }
89
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
90
+ finally {
91
+ try {
92
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
93
+ }
94
+ finally { if (e_1) throw e_1.error; }
95
+ }
96
+ console.log("e:basket :basket service : basketDetails updated values for transaction id", basketDetails.transactionId, JSON.stringify(basketDetails));
97
+ basketDetails.basketTotal = basketDetails.total;
98
+ basketState.updateBasket(basketDetails);
99
+ };
100
+ /**
101
+ * add Line promotion
102
+ * @param null
103
+ * @returns basketDetails
104
+ */
105
+ /**
106
+ * add Line promotion
107
+ * @param {?} promotionList
108
+ * @param {?} basketDetails
109
+ * @return {?} basketDetails
110
+ */
111
+ BasketService.prototype.addlinePromotion = /**
112
+ * add Line promotion
113
+ * @param {?} promotionList
114
+ * @param {?} basketDetails
115
+ * @return {?} basketDetails
116
+ */
117
+ function (promotionList, basketDetails) {
118
+ var e_2, _a, e_3, _b;
119
+ console.log("e:basket :basket Service : promotionList and basketDetails for linePromotions", JSON.stringify(promotionList), JSON.stringify(basketDetails));
120
+ if (promotionList &&
121
+ promotionList.result &&
122
+ promotionList.result.linePromotions &&
123
+ promotionList.result.linePromotions.length > 0) {
124
+ try {
125
+ for (var _c = tslib_1.__values(basketDetails.products), _d = _c.next(); !_d.done; _d = _c.next()) {
126
+ var element = _d.value;
127
+ try {
128
+ for (var _e = (e_3 = void 0, tslib_1.__values(promotionList.result.linePromotions)), _f = _e.next(); !_f.done; _f = _e.next()) {
129
+ var promotionelement = _f.value;
130
+ if (element.itemLineId.toString() ===
131
+ promotionelement.itemLineId.toString()) {
132
+ element.linePromotions = promotionelement;
133
+ }
134
+ }
135
+ }
136
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
137
+ finally {
138
+ try {
139
+ if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
140
+ }
141
+ finally { if (e_3) throw e_3.error; }
142
+ }
143
+ }
144
+ }
145
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
146
+ finally {
147
+ try {
148
+ if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
149
+ }
150
+ finally { if (e_2) throw e_2.error; }
151
+ }
152
+ }
153
+ return basketDetails;
154
+ };
155
+ /**
156
+ * add Transaction promotion
157
+ * @param null
158
+ * @returns basketDetails
159
+ */
160
+ /**
161
+ * add Transaction promotion
162
+ * @param {?} promotionList
163
+ * @param {?} basketdetails
164
+ * @return {?} basketDetails
165
+ */
166
+ BasketService.prototype.addTransactionPromotion = /**
167
+ * add Transaction promotion
168
+ * @param {?} promotionList
169
+ * @param {?} basketdetails
170
+ * @return {?} basketDetails
171
+ */
172
+ function (promotionList, basketdetails) {
173
+ var _this = this;
174
+ console.log("e:basket :basket Service : promotionList and basketDetails for transactionPromotion", JSON.stringify(promotionList), JSON.stringify(basketdetails), JSON.stringify(basketdetails.transactionPromotion));
175
+ if (promotionList &&
176
+ promotionList.result &&
177
+ promotionList.result.transactionPromotion &&
178
+ promotionList.result.transactionPromotion.length > 0) {
179
+ promotionList.result.transactionPromotion.forEach((/**
180
+ * @param {?} tPromotion
181
+ * @return {?}
182
+ */
183
+ function (tPromotion) {
184
+ /** @type {?} */
185
+ var transactionPromotionEntryUpdated = Object.assign({}, tPromotion);
186
+ transactionPromotionEntryUpdated.itemLineIds = basketdetails.products.map((/**
187
+ * @param {?} product
188
+ * @return {?}
189
+ */
190
+ function (product) {
191
+ return product.itemLineId;
192
+ }));
193
+ if (!basketdetails.transactionPromotion) {
194
+ basketdetails.transactionPromotion = [];
195
+ }
196
+ basketdetails.transactionPromotion.push(transactionPromotionEntryUpdated);
197
+ basketdetails = _this.transactionPromotionProductPortionCalc(basketdetails, transactionPromotionEntryUpdated);
198
+ }));
199
+ }
200
+ console.log("basket details in refund calculation file", JSON.stringify(basketdetails));
201
+ return basketdetails;
202
+ };
203
+ /**
204
+ * @param {?} basketDetails
205
+ * @return {?}
206
+ */
207
+ BasketService.prototype.updateProductTotalForSummary = /**
208
+ * @param {?} basketDetails
209
+ * @return {?}
210
+ */
211
+ function (basketDetails) {
212
+ /*sale- product refundedQuantity = undefined
213
+ partial refund - product refundedQuantity is > 0
214
+ total refund - proudct refundedQuantity is > 0
215
+ exchange - exchange product refundedQuantity is > 0
216
+ new product refundedQuantity = undefined
217
+ old product without exchange refundedQuantity = 0
218
+ unreference refund-product refundedQuantity is > 0 */
219
+ var e_4, _a;
220
+ basketDetails.total = 0;
221
+ basketDetails.quantity = 0;
222
+ try {
223
+ for (var _b = tslib_1.__values(basketDetails.products), _c = _b.next(); !_c.done; _c = _b.next()) {
224
+ var product = _c.value;
225
+ if (product.linePromotions) {
226
+ product.total = product.linePromotions.promotionLinePrice;
227
+ }
228
+ else if (product.lineDiscount && !product.linePromotions) {
229
+ product.total = product.lineDiscount.discountedLinePrice;
230
+ }
231
+ else {
232
+ product.total = product.totalLinePrice;
233
+ }
234
+ product.total =
235
+ product.total -
236
+ Math.abs(product.refundedTotal ? product.refundedTotal : 0);
237
+ basketDetails.total += product.total;
238
+ basketDetails.quantity =
239
+ basketDetails.quantity +
240
+ (product.quantity -
241
+ (product.refundedQuantity ? product.refundedQuantity : 0));
242
+ console.log("e-basket:ExchangeSummaryScreen:update basketdetails total :" +
243
+ basketDetails.total +
244
+ " Product line ID : " +
245
+ product.itemLineId +
246
+ " product total : " +
247
+ product.total, "quantity : " + basketDetails.quantity);
248
+ }
249
+ }
250
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
251
+ finally {
252
+ try {
253
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
254
+ }
255
+ finally { if (e_4) throw e_4.error; }
256
+ }
257
+ return this.updateBasketTotalForSummary(basketDetails);
258
+ };
259
+ /**
260
+ * @param {?} basketDetails
261
+ * @return {?}
262
+ */
263
+ BasketService.prototype.updateBasketTotalForSummary = /**
264
+ * @param {?} basketDetails
265
+ * @return {?}
266
+ */
267
+ function (basketDetails) {
268
+ basketDetails.basketTotal = basketDetails.total;
269
+ console.info("ebasket : basket Service : update Basket Total for transaction transactionDiscount ", JSON.stringify(basketDetails.transactionDiscount));
270
+ console.info("ebasket : basket Service : update Basket Total for transaction transactionPromotion ", JSON.stringify(basketDetails.transactionPromotion));
271
+ basketDetails = this.updateTransactionPromotion(basketDetails);
272
+ basketDetails = this.updateTransactionDiscount(basketDetails);
273
+ basketDetails.basketTotal = Number(basketDetails.basketTotal.toFixed(2));
274
+ console.info("ebasket : basket Service : update Basket Total: basketTotal after promotion applied for basketTotal", basketDetails.basketTotal);
275
+ return basketDetails;
276
+ };
277
+ /**
278
+ * @param {?} basketDetails
279
+ * @return {?}
280
+ */
281
+ BasketService.prototype.updateTransactionDiscount = /**
282
+ * @param {?} basketDetails
283
+ * @return {?}
284
+ */
285
+ function (basketDetails) {
286
+ if (basketDetails.transactionDiscount &&
287
+ basketDetails.transactionDiscount.length > 0) {
288
+ /** @type {?} */
289
+ var discountTotal = basketDetails.transactionDiscount.reduce((/**
290
+ * @param {?} n
291
+ * @param {?} __1
292
+ * @return {?}
293
+ */
294
+ function (n, _a) {
295
+ var discountAmount = _a.discountAmount;
296
+ return n + discountAmount;
297
+ }), 0);
298
+ console.log("ebasket : basket Service : discountTotal ", discountTotal);
299
+ basketDetails.basketTotal =
300
+ basketDetails.basketTotal - Math.abs(discountTotal);
301
+ }
302
+ return basketDetails;
303
+ };
304
+ /**
305
+ * @param {?} basketDetails
306
+ * @return {?}
307
+ */
308
+ BasketService.prototype.updateTransactionPromotion = /**
309
+ * @param {?} basketDetails
310
+ * @return {?}
311
+ */
312
+ function (basketDetails) {
313
+ if (basketDetails.transactionPromotion &&
314
+ basketDetails.transactionPromotion.length > 0) {
315
+ /** @type {?} */
316
+ var discountTotal = basketDetails.transactionPromotion.reduce((/**
317
+ * @param {?} n
318
+ * @param {?} __1
319
+ * @return {?}
320
+ */
321
+ function (n, _a) {
322
+ var promotionAmount = _a.promotionAmount;
323
+ return n + promotionAmount;
324
+ }), 0);
325
+ basketDetails.basketTotal =
326
+ basketDetails.basketTotal - Math.abs(discountTotal);
327
+ }
328
+ return basketDetails;
329
+ };
330
+ /**
331
+ * @param {?} basket
332
+ * @return {?}
333
+ */
334
+ BasketService.prototype.updateBasketTotalWithoutDiscount = /**
335
+ * @param {?} basket
336
+ * @return {?}
337
+ */
338
+ function (basket) {
339
+ var e_5, _a;
340
+ basket.total = 0;
341
+ basket.quantity = 0;
342
+ try {
343
+ for (var _b = tslib_1.__values(basket.products), _c = _b.next(); !_c.done; _c = _b.next()) {
344
+ var product = _c.value;
345
+ if (product.linePromotions) {
346
+ product.total = product.linePromotions.promotionLinePrice;
347
+ }
348
+ else if (product.lineDiscount && !product.linePromotions) {
349
+ product.total = product.lineDiscount.discountedLinePrice || 0;
350
+ }
351
+ else {
352
+ product.total = product.totalLinePrice;
353
+ }
354
+ product.total =
355
+ product.total -
356
+ Math.abs(product.refundedTotal ? product.refundedTotal : 0);
357
+ basket.total += product.total;
358
+ basket.quantity =
359
+ basket.quantity +
360
+ (product.quantity -
361
+ (product.refundedQuantity ? product.refundedQuantity : 0));
362
+ console.log("e-basket:basket service:update basketdetails total :" +
363
+ JSON.stringify(basket) +
364
+ basket.total +
365
+ " Product line ID : " +
366
+ product.itemLineId +
367
+ " product total : " +
368
+ product.total);
369
+ }
370
+ }
371
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
372
+ finally {
373
+ try {
374
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
375
+ }
376
+ finally { if (e_5) throw e_5.error; }
377
+ }
378
+ basket.basketTotal = basket.total;
379
+ return basket;
380
+ };
381
+ /**
382
+ * @param {?} basket
383
+ * @return {?}
384
+ */
385
+ BasketService.prototype.updateBasketTotalWithDiscounts = /**
386
+ * @param {?} basket
387
+ * @return {?}
388
+ */
389
+ function (basket) {
390
+ console.log("e:basket :RefundBasketScreen : this.basketDetails new values", basket, JSON.stringify(basket.basketTotal));
391
+ if (basket.transactionPromotion && basket.transactionPromotion.length > 0) {
392
+ /** @type {?} */
393
+ var discountTotal = basket.transactionPromotion.reduce((/**
394
+ * @param {?} n
395
+ * @param {?} __1
396
+ * @return {?}
397
+ */
398
+ function (n, _a) {
399
+ var promotionAmount = _a.promotionAmount;
400
+ return n + promotionAmount;
401
+ }), 0);
402
+ basket.basketTotal = basket.basketTotal - discountTotal;
403
+ }
404
+ if (basket.transactionDiscount && basket.transactionDiscount.length > 0) {
405
+ /** @type {?} */
406
+ var discountTotal = basket.transactionDiscount.reduce((/**
407
+ * @param {?} n
408
+ * @param {?} __1
409
+ * @return {?}
410
+ */
411
+ function (n, _a) {
412
+ var discountAmount = _a.discountAmount;
413
+ return n + discountAmount;
414
+ }), 0);
415
+ basket.basketTotal = basket.basketTotal - discountTotal;
416
+ }
417
+ console.log("e:basket :RefundBasketScreen : basket new values", JSON.stringify(basket));
418
+ return basket;
419
+ };
420
+ /**
421
+ * @param {?} basket
422
+ * @return {?}
423
+ */
424
+ BasketService.prototype.transactionDiscountAndPromotionProductortionCalculation = /**
425
+ * @param {?} basket
426
+ * @return {?}
427
+ */
428
+ function (basket) {
429
+ var _this = this;
430
+ if (basket.transactionDiscount && basket.transactionDiscount.length > 0) {
431
+ basket.transactionDiscount.forEach((/**
432
+ * @param {?} discount
433
+ * @return {?}
434
+ */
435
+ function (discount) {
436
+ return (basket = _this.transactionDiscountProductPortionCalc(basket, discount));
437
+ }));
438
+ }
439
+ if (basket.transactionPromotion && basket.transactionPromotion.length > 0) {
440
+ basket.transactionPromotion.forEach((/**
441
+ * @param {?} promotion
442
+ * @return {?}
443
+ */
444
+ function (promotion) {
445
+ basket = _this.transactionPromotionProductPortionCalc(basket, promotion);
446
+ }));
447
+ }
448
+ console.log("ebasket: basket item discount protion calculation", basket, basket.products);
449
+ return basket;
450
+ };
451
+ /**
452
+ * @param {?} basket
453
+ * @param {?} promotion
454
+ * @return {?}
455
+ */
456
+ BasketService.prototype.transactionPromotionProductPortionCalc = /**
457
+ * @param {?} basket
458
+ * @param {?} promotion
459
+ * @return {?}
460
+ */
461
+ function (basket, promotion) {
462
+ var _this = this;
463
+ /** @type {?} */
464
+ var total = 0;
465
+ /** @type {?} */
466
+ var percentage = 0;
467
+ {
468
+ basket.products.forEach((/**
469
+ * @param {?} p
470
+ * @return {?}
471
+ */
472
+ function (p) {
473
+ if (promotion.itemLineIds.includes(p.itemLineId)) {
474
+ p = _this.validateProductItemDiscount(p);
475
+ /** @type {?} */
476
+ var productContributionInTotal = _this.numberUtilService.trimTo2Decimal2(p.itemDiscounts.trnDiscountsPortion) +
477
+ _this.numberUtilService.trimTo2Decimal2(p.itemDiscounts.trnPromotionsPortion) -
478
+ _this.numberUtilService.trimTo2Decimal2(p.itemDiscounts.refundPortion);
479
+ total += (p.total - _this.numberUtilService.trimTo2Decimal2(productContributionInTotal));
480
+ }
481
+ }));
482
+ console.log("ebasket: trnsactionPromotion: " + JSON.stringify(promotion) + ", selected products total: " + total);
483
+ basket.products.forEach((/**
484
+ * @param {?} product
485
+ * @return {?}
486
+ */
487
+ function (product) {
488
+ product = _this.validateProductItemDiscount(product);
489
+ /** @type {?} */
490
+ var productContributionInTotal = _this.numberUtilService.trimTo2Decimal2(product.itemDiscounts.trnDiscountsPortion) +
491
+ _this.numberUtilService.trimTo2Decimal2(product.itemDiscounts.trnPromotionsPortion) -
492
+ _this.numberUtilService.trimTo2Decimal2(product.itemDiscounts.refundPortion);
493
+ if (promotion.itemLineIds.includes(product.itemLineId)) {
494
+ percentage = ((product.total - _this.numberUtilService.trimTo2Decimal2(productContributionInTotal)) / total) * 100;
495
+ product.itemDiscounts.trnPromotionsPortion +=
496
+ (promotion.promotionAmount * percentage) / 100;
497
+ product.itemDiscounts.trnPromotionsPortion = _this.numberUtilService.trimTo2Decimal2(product.itemDiscounts.trnPromotionsPortion);
498
+ }
499
+ }));
500
+ }
501
+ return basket;
502
+ };
503
+ /**
504
+ * @param {?} basket
505
+ * @param {?} discount
506
+ * @return {?}
507
+ */
508
+ BasketService.prototype.transactionDiscountProductPortionCalc = /**
509
+ * @param {?} basket
510
+ * @param {?} discount
511
+ * @return {?}
512
+ */
513
+ function (basket, discount) {
514
+ var _this = this;
515
+ /** @type {?} */
516
+ var total = 0;
517
+ /** @type {?} */
518
+ var percentage = 0;
519
+ basket.products.forEach((/**
520
+ * @param {?} p
521
+ * @return {?}
522
+ */
523
+ function (p) {
524
+ if (discount.itemLineIds.includes(p.itemLineId)) {
525
+ p = _this.validateProductItemDiscount(p);
526
+ /** @type {?} */
527
+ var productContributionInTotal = _this.numberUtilService.trimTo2Decimal2(p.itemDiscounts.trnDiscountsPortion) +
528
+ _this.numberUtilService.trimTo2Decimal2(p.itemDiscounts.trnPromotionsPortion) -
529
+ _this.numberUtilService.trimTo2Decimal2(p.itemDiscounts.refundPortion);
530
+ total += (p.total - _this.numberUtilService.trimTo2Decimal2(productContributionInTotal));
531
+ }
532
+ }));
533
+ console.log("ebasket: trnsactionDiscount: " + JSON.stringify(discount) + ", selected products total: " + total);
534
+ basket.products.forEach((/**
535
+ * @param {?} product
536
+ * @return {?}
537
+ */
538
+ function (product) {
539
+ product = _this.validateProductItemDiscount(product);
540
+ console.log(product.discountable, "ebasket : basket service : discountable in basket service");
541
+ /** @type {?} */
542
+ var productContributionInTotal = _this.numberUtilService.trimTo2Decimal2(product.itemDiscounts.trnDiscountsPortion) +
543
+ _this.numberUtilService.trimTo2Decimal2(product.itemDiscounts.trnPromotionsPortion) -
544
+ _this.numberUtilService.trimTo2Decimal2(product.itemDiscounts.refundPortion);
545
+ if (discount.itemLineIds.includes(product.itemLineId) && product.discountable == true) {
546
+ percentage = ((product.total - _this.numberUtilService.trimTo2Decimal2(productContributionInTotal)) / total) * 100;
547
+ product.itemDiscounts.trnDiscountsPortion +=
548
+ (discount.discountAmount * percentage) / 100;
549
+ product.itemDiscounts.trnDiscountsPortion = _this.numberUtilService.trimTo2Decimal2(product.itemDiscounts.trnDiscountsPortion);
550
+ }
551
+ }));
552
+ return basket;
553
+ };
554
+ /**
555
+ * @param {?} product
556
+ * @return {?}
557
+ */
558
+ BasketService.prototype.validateProductItemDiscount = /**
559
+ * @param {?} product
560
+ * @return {?}
561
+ */
562
+ function (product) {
563
+ if (!product.itemDiscounts) {
564
+ product.itemDiscounts = {
565
+ trnDiscountsPortion: 0,
566
+ trnPromotionsPortion: 0,
567
+ refundPortion: 0,
568
+ };
569
+ }
570
+ return product;
571
+ };
572
+ /**
573
+ * @param {?} product
574
+ * @return {?}
575
+ */
576
+ BasketService.prototype.markProduct = /**
577
+ * @param {?} product
578
+ * @return {?}
579
+ */
580
+ function (product) {
581
+ this.productSource.next(product);
582
+ };
583
+ /**
584
+ * @param {?} peerSync
585
+ * @return {?}
586
+ */
587
+ BasketService.prototype.stopPeerSyncProcess = /**
588
+ * @param {?} peerSync
589
+ * @return {?}
590
+ */
591
+ function (peerSync) {
592
+ this.peerSource.next(peerSync);
593
+ };
594
+ /**
595
+ * @param {?} isScanning
596
+ * @return {?}
597
+ */
598
+ BasketService.prototype.scanStart = /**
599
+ * @param {?} isScanning
600
+ * @return {?}
601
+ */
602
+ function (isScanning) {
603
+ this.scanSource.next(isScanning);
604
+ };
605
+ /**
606
+ * @param {?} promotion
607
+ * @return {?}
608
+ */
609
+ BasketService.prototype.promotionRemainingCalculation = /**
610
+ * @param {?} promotion
611
+ * @return {?}
612
+ */
613
+ function (promotion) {
614
+ /** @type {?} */
615
+ var promotionValue = 0;
616
+ promotion.forEach((/**
617
+ * @param {?} element
618
+ * @return {?}
619
+ */
620
+ function (element) {
621
+ promotionValue += element.promotionAmount;
622
+ }));
623
+ return promotionValue;
624
+ };
625
+ /**
626
+ * @param {?} discount
627
+ * @return {?}
628
+ */
629
+ BasketService.prototype.discountRemainingCalculation = /**
630
+ * @param {?} discount
631
+ * @return {?}
632
+ */
633
+ function (discount) {
634
+ /** @type {?} */
635
+ var discountValue = 0;
636
+ discount.forEach((/**
637
+ * @param {?} element
638
+ * @return {?}
639
+ */
640
+ function (element) {
641
+ discountValue += element.discountAmount;
642
+ }));
643
+ return discountValue;
644
+ };
645
+ /**
646
+ * @param {?} discount
647
+ * @return {?}
648
+ */
649
+ BasketService.prototype.discountRefundedCalculation = /**
650
+ * @param {?} discount
651
+ * @return {?}
652
+ */
653
+ function (discount) {
654
+ /** @type {?} */
655
+ var discountValue = 0;
656
+ discount.forEach((/**
657
+ * @param {?} element
658
+ * @return {?}
659
+ */
660
+ function (element) {
661
+ if (element.discountAmount < 0) {
662
+ discountValue += element.discountAmount;
663
+ }
664
+ }));
665
+ return discountValue;
666
+ };
667
+ /**
668
+ * @param {?} products
669
+ * @return {?}
670
+ */
671
+ BasketService.prototype.generateNewItemLineId = /**
672
+ * @param {?} products
673
+ * @return {?}
674
+ */
675
+ function (products) {
676
+ /** @type {?} */
677
+ var largestNumber = 0;
678
+ if (products.length > 0) {
679
+ /** @type {?} */
680
+ var itemLineIdArray = products.map((/**
681
+ * @param {?} product
682
+ * @return {?}
683
+ */
684
+ function (product) {
685
+ return product.itemLineId;
686
+ }));
687
+ largestNumber = itemLineIdArray.reduce((/**
688
+ * @param {?} a
689
+ * @param {?} b
690
+ * @return {?}
691
+ */
692
+ function (a, b) { return Math.max(a, b); }));
693
+ }
694
+ return largestNumber + 1;
695
+ };
696
+ /**
697
+ * @param {?} product
698
+ * @param {?} quantity
699
+ * @return {?}
700
+ */
701
+ BasketService.prototype.updateBasketProductDataAsPerQuantity = /**
702
+ * @param {?} product
703
+ * @param {?} quantity
704
+ * @return {?}
705
+ */
706
+ function (product, quantity) {
707
+ console.log("ebasket: updateBasketProductDataAsPerQuantity : " + quantity + " product: " + JSON.stringify(product));
708
+ product.quantity = quantity;
709
+ if (product.hasOwnProperty("lineDiscount")) {
710
+ // && this.product.quantity !== this.productDetailForm.controls.quantity.value
711
+ product.lineDiscount.discountedLinePrice = Number(this.numberUtilService.getFlooredFixed(product.lineDiscount.unitPrice * quantity, 2));
712
+ product.lineDiscount.discountAmount =
713
+ product.totalLinePrice - product.lineDiscount.discountedLinePrice;
714
+ }
715
+ else {
716
+ product.totalLinePrice =
717
+ quantity * this.numberUtilService.trimTo2Decimal(product.selectedPrice);
718
+ }
719
+ if (product.lineDiscount) {
720
+ product.total = product.lineDiscount.discountedLinePrice;
721
+ }
722
+ else {
723
+ product.total = product.totalLinePrice;
724
+ }
725
+ console.log("ebasket: updateBasketProductDataAsPerQuantity : " + quantity + " product: " + JSON.stringify(product));
726
+ return product;
727
+ };
728
+ /**
729
+ * @param {?} isWebOrder
730
+ * @return {?}
731
+ */
732
+ BasketService.prototype.filterProductListWithWebOrder = /**
733
+ * @param {?} isWebOrder
734
+ * @return {?}
735
+ */
736
+ function (isWebOrder) {
737
+ console.log("ebasket: filterProductListWithWebOrder hit", JSON.stringify(this.currentBasket.products));
738
+ if (isWebOrder)
739
+ return this.currentBasket.products.filter((/**
740
+ * @param {?} x
741
+ * @return {?}
742
+ */
743
+ function (x) { return x.isWebOrder; }));
744
+ else {
745
+ return this.currentBasket.products.filter((/**
746
+ * @param {?} x
747
+ * @return {?}
748
+ */
749
+ function (x) { return !x.isWebOrder; }));
750
+ }
751
+ };
752
+ /**
753
+ * @return {?}
754
+ */
755
+ BasketService.prototype.filterProductListWithDelivery = /**
756
+ * @return {?}
757
+ */
758
+ function () {
759
+ console.log("ebasket: filterProductListWithDelivery hit", JSON.stringify(this.currentBasket.products));
760
+ return this.currentBasket.products.filter((/**
761
+ * @param {?} x
762
+ * @return {?}
763
+ */
764
+ function (x) { return x.deliveryMethod === DELIVERY_METHODS.DELIVERY.toString(); }));
765
+ };
766
+ /**
767
+ * @param {?} group
768
+ * @param {?} products
769
+ * @return {?}
770
+ */
771
+ BasketService.prototype.filterProductListWithDeliveryGroup = /**
772
+ * @param {?} group
773
+ * @param {?} products
774
+ * @return {?}
775
+ */
776
+ function (group, products) {
777
+ console.log("ebasket: filterProductListWithDeliveryGroup hit", JSON.stringify(products));
778
+ return products.filter((/**
779
+ * @param {?} x
780
+ * @return {?}
781
+ */
782
+ function (x) { return x.deliveryGroup === group; }));
783
+ };
784
+ /**
785
+ * @param {?} products
786
+ * @return {?}
787
+ */
788
+ BasketService.prototype.generateNewDeliveryGroupNumber = /**
789
+ * @param {?} products
790
+ * @return {?}
791
+ */
792
+ function (products) {
793
+ /** @type {?} */
794
+ var largestNumber = 0;
795
+ if (products.length > 0) {
796
+ /** @type {?} */
797
+ var deliveryGroupArr = products.map((/**
798
+ * @param {?} product
799
+ * @return {?}
800
+ */
801
+ function (product) {
802
+ if (product.deliveryGroup) {
803
+ return parseInt(product.deliveryGroup);
804
+ }
805
+ return 0;
806
+ }));
807
+ largestNumber = deliveryGroupArr.reduce((/**
808
+ * @param {?} a
809
+ * @param {?} b
810
+ * @return {?}
811
+ */
812
+ function (a, b) { return Math.max(a, b); }));
813
+ }
814
+ return (largestNumber + 1).toString();
815
+ };
816
+ /**
817
+ * @param {?} products
818
+ * @return {?}
819
+ */
820
+ BasketService.prototype.getDeliveryGroupNumbers = /**
821
+ * @param {?} products
822
+ * @return {?}
823
+ */
824
+ function (products) {
825
+ console.log("getDeliveryGroupNumbers initiating : ", JSON.stringify(products));
826
+ /** @type {?} */
827
+ var uniqueAndsortedResult = [];
828
+ if (products.length > 0) {
829
+ /** @type {?} */
830
+ var deliveryGroupArr = products.map((/**
831
+ * @param {?} product
832
+ * @return {?}
833
+ */
834
+ function (product) {
835
+ if (product.deliveryGroup) {
836
+ return parseInt(product.deliveryGroup);
837
+ }
838
+ else if (product.deliveryMethod === "1") {
839
+ return 1;
840
+ }
841
+ return 0;
842
+ }));
843
+ uniqueAndsortedResult = Array.from(new Set(deliveryGroupArr)).sort((/**
844
+ * @param {?} a
845
+ * @param {?} b
846
+ * @return {?}
847
+ */
848
+ function (a, b) { return a - b; }));
849
+ console.log("getDeliveryGroupNumbers : ", JSON.stringify(uniqueAndsortedResult));
850
+ }
851
+ return uniqueAndsortedResult;
852
+ };
853
+ /**
854
+ * @param {?} products
855
+ * @return {?}
856
+ */
857
+ BasketService.prototype.updateProductsWithNewDeliveryGroupNumber = /**
858
+ * @param {?} products
859
+ * @return {?}
860
+ */
861
+ function (products) {
862
+ console.log("updateProductsWithNewDeliveryGroupNumber initiating : ", JSON.stringify(products));
863
+ /** @type {?} */
864
+ var newGroupNumber = this.generateNewDeliveryGroupNumber(this.currentBasket.products);
865
+ if (products.length > 0) {
866
+ this.currentBasket.products.forEach((/**
867
+ * @param {?} cBProducts
868
+ * @return {?}
869
+ */
870
+ function (cBProducts) {
871
+ products.forEach((/**
872
+ * @param {?} element
873
+ * @return {?}
874
+ */
875
+ function (element) {
876
+ if (cBProducts.itemLineId === element.itemLineId) {
877
+ cBProducts.deliveryGroup = newGroupNumber;
878
+ }
879
+ }));
880
+ }));
881
+ }
882
+ this.updateBasket(this.currentBasket);
883
+ return;
884
+ };
885
+ /**
886
+ * @param {?} products
887
+ * @return {?}
888
+ */
889
+ BasketService.prototype.calculateEstimatedTime = /**
890
+ * @param {?} products
891
+ * @return {?}
892
+ */
893
+ function (products) {
894
+ try {
895
+ /** @type {?} */
896
+ var time_1;
897
+ /** @type {?} */
898
+ var estmatedTime_1 = 0;
899
+ /** @type {?} */
900
+ var estimatedDays_1 = "Hours";
901
+ products.forEach((/**
902
+ * @param {?} element
903
+ * @return {?}
904
+ */
905
+ function (element) {
906
+ if (element.leadTime.type.toLocaleLowerCase() === "weeks") {
907
+ time_1 = Number(element.leadTime.value) * 24 * 7;
908
+ estmatedTime_1 = Math.max(estmatedTime_1, time_1);
909
+ estimatedDays_1 = (estmatedTime_1 === time_1) ? element.leadTime.type : estimatedDays_1;
910
+ console.log("week", estmatedTime_1, estimatedDays_1);
911
+ }
912
+ else if (element.leadTime.type.toLocaleLowerCase() === "days") {
913
+ time_1 = Number(element.leadTime.value) * 24;
914
+ estmatedTime_1 = Math.max(estmatedTime_1, time_1);
915
+ estimatedDays_1 = (estmatedTime_1 === time_1) ? element.leadTime.type : estimatedDays_1;
916
+ console.log("days", estmatedTime_1, estimatedDays_1);
917
+ }
918
+ else if (element.leadTime.type.toLocaleLowerCase() === "months") {
919
+ time_1 = Number(element.leadTime.value) * 24 * 30;
920
+ estmatedTime_1 = Math.max(estmatedTime_1, time_1);
921
+ estimatedDays_1 = (estmatedTime_1 === time_1) ? element.leadTime.type : estimatedDays_1;
922
+ console.log("months", estmatedTime_1, estimatedDays_1);
923
+ }
924
+ else if (element.leadTime.type.toLocaleLowerCase() === "years") {
925
+ time_1 = Number(element.leadTime.value) * 24 * 365;
926
+ estmatedTime_1 = Math.max(estmatedTime_1, time_1);
927
+ estimatedDays_1 = (estmatedTime_1 === time_1) ? element.leadTime.type : estimatedDays_1;
928
+ console.log("years", estmatedTime_1, estimatedDays_1);
929
+ }
930
+ else {
931
+ time_1 = Number(element.leadTime.value);
932
+ estmatedTime_1 = Math.max(estmatedTime_1, time_1);
933
+ estimatedDays_1 = (estmatedTime_1 === time_1) ? element.leadTime.type : estimatedDays_1;
934
+ console.log("hours", estmatedTime_1, estimatedDays_1);
935
+ }
936
+ }));
937
+ if (estimatedDays_1.toLocaleLowerCase() === "days") {
938
+ estmatedTime_1 = estmatedTime_1 / 24;
939
+ }
940
+ else if (estimatedDays_1.toLocaleLowerCase() === "weeks") {
941
+ estmatedTime_1 = estmatedTime_1 / (24 * 7);
942
+ }
943
+ else if (estimatedDays_1.toLocaleLowerCase() === "months") {
944
+ estmatedTime_1 = estmatedTime_1 / (24 * 30);
945
+ }
946
+ else if (estimatedDays_1.toLocaleLowerCase() === "years") {
947
+ estmatedTime_1 = estmatedTime_1 / (24 * 365);
948
+ }
949
+ /** @type {?} */
950
+ var estimate = {
951
+ value: estmatedTime_1.toString(),
952
+ type: estimatedDays_1
953
+ };
954
+ return estimate;
955
+ }
956
+ catch (error) {
957
+ console.log("error in calculateEstimatedTime", error);
958
+ }
959
+ return 0;
960
+ };
961
+ /**
962
+ * @param {?} oldGroup
963
+ * @param {?} newGroup
964
+ * @return {?}
965
+ */
966
+ BasketService.prototype.updateProductsWithDeliveryGroupNumber = /**
967
+ * @param {?} oldGroup
968
+ * @param {?} newGroup
969
+ * @return {?}
970
+ */
971
+ function (oldGroup, newGroup) {
972
+ console.log("updateProductsWithDeliveryGroupNumber initiating");
973
+ this.currentBasket.products.forEach((/**
974
+ * @param {?} cBProducts
975
+ * @return {?}
976
+ */
977
+ function (cBProducts) {
978
+ if (cBProducts.deliveryGroup === oldGroup) {
979
+ cBProducts.deliveryGroup = newGroup;
980
+ }
981
+ }));
982
+ this.updateBasket(this.currentBasket);
983
+ return;
984
+ };
985
+ /**
986
+ * @return {?}
987
+ */
988
+ BasketService.prototype.getDeliveryInfo = /**
989
+ * @return {?}
990
+ */
991
+ function () {
992
+ var _this = this;
993
+ console.log("getDeliveryGroupInfor initiating");
994
+ try {
995
+ /** @type {?} */
996
+ var groupInfo_1 = {
997
+ groups: []
998
+ };
999
+ this.getDeliveryGroupNumbers(this.currentBasket.products).forEach((/**
1000
+ * @param {?} groupNumber
1001
+ * @return {?}
1002
+ */
1003
+ function (groupNumber) {
1004
+ /** @type {?} */
1005
+ var group = {
1006
+ groupNumber: groupNumber,
1007
+ items: [],
1008
+ estimate: {
1009
+ type: "Hours",
1010
+ value: "0"
1011
+ }
1012
+ };
1013
+ _this.currentBasket.products.forEach((/**
1014
+ * @param {?} cBProducts
1015
+ * @return {?}
1016
+ */
1017
+ function (cBProducts) {
1018
+ if (cBProducts.deliveryGroup === groupNumber.toString()) {
1019
+ group.items.push(cBProducts);
1020
+ }
1021
+ }));
1022
+ group.estimate = _this.calculateEstimatedTime(group.items);
1023
+ groupInfo_1.groups.push(group);
1024
+ }));
1025
+ return groupInfo_1;
1026
+ }
1027
+ catch (error) {
1028
+ console.log("error", error);
1029
+ }
1030
+ };
1031
+ return BasketService;
1032
+ }());
1033
+ export { BasketService };
1034
+ if (false) {
1035
+ /** @type {?} */
1036
+ BasketService.prototype.currentBasket;
1037
+ /**
1038
+ * @type {?}
1039
+ * @private
1040
+ */
1041
+ BasketService.prototype.basketSource;
1042
+ /** @type {?} */
1043
+ BasketService.prototype.basket;
1044
+ /**
1045
+ * @type {?}
1046
+ * @private
1047
+ */
1048
+ BasketService.prototype.productSource;
1049
+ /** @type {?} */
1050
+ BasketService.prototype.product;
1051
+ /**
1052
+ * @type {?}
1053
+ * @private
1054
+ */
1055
+ BasketService.prototype.peerSource;
1056
+ /** @type {?} */
1057
+ BasketService.prototype.peerSync;
1058
+ /**
1059
+ * @type {?}
1060
+ * @private
1061
+ */
1062
+ BasketService.prototype.scanSource;
1063
+ /** @type {?} */
1064
+ BasketService.prototype.scanner;
1065
+ /**
1066
+ * @type {?}
1067
+ * @private
1068
+ */
1069
+ BasketService.prototype._isMixedBasketSales;
1070
+ /**
1071
+ * @type {?}
1072
+ * @private
1073
+ */
1074
+ BasketService.prototype.numberUtilService;
1075
+ }
1076
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFza2V0LnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AcG1jcmV0YWlsL21hcHBlci1saWJyYXJ5LyIsInNvdXJjZXMiOlsibGliL2Jhc2tldC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdkMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFLMUQ7SUErQkUsdUJBQW9CLGlCQUFvQztRQUFwQyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBOUJ4RCxrQkFBYSxHQUFXO1lBQ3RCLFFBQVEsRUFBRSxFQUFFO1lBQ1osbUJBQW1CLEVBQUUsRUFBRTtZQUN2QixRQUFRLEVBQUUsQ0FBQztZQUNYLEtBQUssRUFBRSxDQUFDO1lBQ1IsU0FBUyxFQUFFLENBQUM7WUFDWixZQUFZLEVBQUUsRUFBRTtTQUNqQixDQUFDO1FBRU0saUJBQVksR0FBRyxJQUFJLGVBQWUsQ0FBTSxJQUFJLENBQUMsQ0FBQztRQUN0RCxXQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUVsQyxrQkFBYSxHQUFHLElBQUksZUFBZSxDQUFNLElBQUksQ0FBQyxDQUFDO1FBQ3ZELFlBQU8sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBRXBDLGVBQVUsR0FBRyxJQUFJLGVBQWUsQ0FBVSxLQUFLLENBQUMsQ0FBQztRQUN6RCxhQUFRLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUVsQyxlQUFVLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDekQsWUFBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxFQUFFLENBQUM7SUFXbUIsQ0FBQztJQVI3RCxzQkFBVyw2Q0FBa0I7Ozs7UUFBN0I7WUFDRSxPQUFPLElBQUksQ0FBQyxtQkFB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LENBQUMsT0FBTzs7OztnQkFBQyxVQUFBLFVBQVU7b0JBQzVDLElBQUksVUFBVSxDQUFDLGFBQWEsS0FBSyxXQUFXLENBQUMsUUFBUSxFQUFFLEVBQUU7d0JBQ3ZELEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO3FCQUM5QjtnQkFDSCxDQUFDLEVBQUMsQ0FBQztnQkFFSCxLQUFLLENBQUMsUUFBUSxHQUFHLEtBQUksQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBRTFELFdBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRS9CLENBQUMsRUFBQyxDQUFDO1lBRUgsT0FBTyxXQUFTLENBQUM7U0FDbEI7UUFDRCxPQUFPLEtBQUssRUFBRTtZQUNaLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQzdCO0lBQ0gsQ0FBQztJQUNILG9CQUFDO0FBQUQsQ0FBQyxBQTVyQkQsSUE0ckJDOzs7O0lBM3JCQyxzQ0FPRTs7Ozs7SUFFRixxQ0FBc0Q7O0lBQ3RELCtCQUEwQzs7Ozs7SUFFMUMsc0NBQXVEOztJQUN2RCxnQ0FBNEM7Ozs7O0lBRTVDLG1DQUF5RDs7SUFDekQsaUNBQTBDOzs7OztJQUUxQyxtQ0FBeUQ7O0lBQ3pELGdDQUF5Qzs7Ozs7SUFFekMsNENBQWlEOzs7OztJQVNyQywwQ0FBNEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBERUxJVkVSWV9NRVRIT0RTIH0gZnJvbSAnLi9tYXBwZXItbGlicmFyeS5tb2RlbCc7XHJcbmltcG9ydCB7IEJhc2tldCwgRGVsaXZlcnlHcm91cEluZm8sIERlbGl2ZXJ5SW5mbywgUHJvZHVjdCwgVHJhbnNhY3Rpb25Qcm9tb3Rpb24gfSBmcm9tICcuL21hcHBlci1saWJyYXJ5Lm1vZGVsJztcclxuaW1wb3J0IHsgVHJhbnNhY3Rpb25EaXNjb3VudCB9IGZyb20gJy4vbWFwcGVyLWxpYnJhcnkubW9kZWwnO1xyXG5pbXBvcnQgeyBOdW1iZXJVdGlsU2VydmljZSB9IGZyb20gJy4vbnVtYmVyLXV0aWwuc2VydmljZSc7XHJcblxyXG5leHBvcnQgY2xhc3MgQmFza2V0U2VydmljZSB7XHJcbiAgY3VycmVudEJhc2tldDogQmFza2V0ID0ge1xyXG4gICAgcHJvZHVjdHM6IFtdLFxyXG4gICAgdHJhbnNhY3Rpb25EaXNjb3VudDogW10sXHJcbiAgICBxdWFudGl0eTogMCxcclxuICAgIHRvdGFsOiAwLFxyXG4gICAgc2FsZVRvdGFsOiAwLFxyXG4gICAgYmFzZUN1cnJlbmN5OiAnJ1xyXG4gIH07XHJcblxyXG4gIHByaXZhdGUgYmFza2V0U291cmNlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxhbnk+KG51bGwpO1xyXG4gIGJhc2tldCA9IHRoaXMuYmFza2V0U291cmNlLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIHByb2R1Y3RTb3VyY2UgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGFueT4obnVsbCk7XHJcbiAgcHJvZHVjdCA9IHRoaXMucHJvZHVjdFNvdXJjZS5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgcHJpdmF0ZSBwZWVyU291cmNlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XHJcbiAgcGVlclN5bmMgPSB0aGlzLnBlZXJTb3VyY2UuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgc2NhblNvdXJjZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xyXG4gIHNjYW5uZXIgPSB0aGlzLnNjYW5Tb3VyY2UuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX2lzTWl4ZWRCYXNrZXRTYWxlczogYm9vbGVhbiB8IHVuZGVmaW5lZDtcclxuICBwdWJsaWMgZ2V0IGlzTWl4ZWRCYXNrZXRTYWxlcygpOiBhbnkge1xyXG4gICAgcmV0dXJuIHRoaXMuX2lzTWl4ZWRCYXNrZXRTYWxlcztcclxuICB9XHJcbiAgcHVibGljIHNldCBpc01peGVkQmFza2V0U2FsZXModjogYW55KSB7XHJcbiAgICB0aGlzLl9pc01peGVkQmFza2V0U2FsZXMgPSB2O1xyXG4gIH1cclxuXHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbnVtYmVyVXRpbFNlcnZpY2U6IE51bWJlclV0aWxTZXJ2aWNlKSB7IH1cclxuXHJcbiAgdXBkYXRlQmFza2V0KGJhc2tldDogQmFza2V0KSB7XHJcbiAgICB0aGlzLmN1cnJlbnRCYXNrZXQgPSBiYXNrZXQ7XHJcbiAgICB0aGlzLmlzTWl4ZWRCYXNrZXRTYWxlcyA9IHRoaXMuZmlsdGVyUHJvZHVjdExpc3RXaXRoV2ViT3JkZXIodHJ1ZSkubGVuZ3RoID4gMDtcclxuICAgIHRoaXMuYmFza2V0U291cmNlLm5leHQoYmFza2V0KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGNhbGN1bGF0ZXMgdGhlIHRvdGFsIGJhc2tldCB2YWx1ZSBhbmQgcXVhbnRpdHlcclxuICAgKiBAcGFyYW0gIG51bGxcclxuICAgKiBAcmV0dXJucyB2b2lkXHJcbiAgICovXHJcbiAgdXBkYXRlQmFza2V0VG90YWwoYmFza2V0RGV0YWlsczogeyBxdWFudGl0eTogbnVtYmVyOyB0b3RhbDogbnVtYmVyOyBwcm9kdWN0czogYW55OyB0cmFuc2FjdGlvbklkOiBhbnk7IGJhc2tldFRvdGFsOiBhbnk7IH0sIGJhc2tldFN0YXRlOiB7IHVwZGF0ZUJhc2tldDogKGFyZzA6IGFueSkgPT4gdm9pZDsgfSkge1xyXG4gICAgYmFza2V0RGV0YWlscy5xdWFudGl0eSA9IDA7XHJcbiAgICBiYXNrZXREZXRhaWxzLnRvdGFsID0gMDtcclxuICAgIGZvciAoY29uc3QgcCBvZiBiYXNrZXREZXRhaWxzLnByb2R1Y3RzKSB7XHJcbiAgICAgIGJhc2tldERldGFpbHMucXVhbnRpdHkgPSBiYXNrZXREZXRhaWxzLnF1YW50aXR5ICsgcC5xdWFudGl0eTtcclxuICAgICAgYmFza2V0RGV0YWlscy50b3RhbCA9XHJcbiAgICAgICAgdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbChiYXNrZXREZXRhaWxzLnRvdGFsKSArXHJcbiAgICAgICAgdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbChwLnRvdGFsKTtcclxuICAgIH1cclxuICAgIGNvbnNvbGUubG9nKFxyXG4gICAgICBcImU6YmFza2V0IDpiYXNrZXQgc2VydmljZSA6IGJhc2tldERldGFpbHMgdXBkYXRlZCB2YWx1ZXMgZm9yIHRyYW5zYWN0aW9uIGlkXCIsXHJcbiAgICAgIGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25JZCxcclxuICAgICAgSlNPTi5zdHJpbmdpZnkoYmFza2V0RGV0YWlscylcclxuICAgICk7XHJcbiAgICBiYXNrZXREZXRhaWxzLmJhc2tldFRvdGFsID0gYmFza2V0RGV0YWlscy50b3RhbDtcclxuICAgIGJhc2tldFN0YXRlLnVwZGF0ZUJhc2tldChiYXNrZXREZXRhaWxzKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGFkZCBMaW5lIHByb21vdGlvblxyXG4gICAqIEBwYXJhbSAgbnVsbFxyXG4gICAqIEByZXR1cm5zIGJhc2tldERldGFpbHNcclxuICAgKi9cclxuICBhZGRsaW5lUHJvbW90aW9uKHByb21vdGlvbkxpc3Q6IHsgcmVzdWx0OiB7IGxpbmVQcm9tb3Rpb25zOiBzdHJpbmcgfCBhbnlbXTsgfTsgfSwgYmFza2V0RGV0YWlsczogeyBwcm9kdWN0czogYW55OyB9KSB7XHJcbiAgICBjb25zb2xlLmxvZyhcclxuICAgICAgXCJlOmJhc2tldCA6YmFza2V0IFNlcnZpY2UgOiBwcm9tb3Rpb25MaXN0IGFuZCBiYXNrZXREZXRhaWxzIGZvciBsaW5lUHJvbW90aW9uc1wiLFxyXG4gICAgICBKU09OLnN0cmluZ2lmeShwcm9tb3Rpb25MaXN0KSxcclxuICAgICAgSlNPTi5zdHJpbmdpZnkoYmFza2V0RGV0YWlscylcclxuICAgICk7XHJcbiAgICBpZiAoXHJcbiAgICAgIHByb21vdGlvbkxpc3QgJiZcclxuICAgICAgcHJvbW90aW9uTGlzdC5yZXN1bHQgJiZcclxuICAgICAgcHJvbW90aW9uTGlzdC5yZXN1bHQubGluZVByb21vdGlvbnMgJiZcclxuICAgICAgcHJvbW90aW9uTGlzdC5yZXN1bHQubGluZVByb21vdGlvbnMubGVuZ3RoID4gMFxyXG4gICAgKSB7XHJcbiAgICAgIGZvciAodmFyIGVsZW1lbnQgb2YgYmFza2V0RGV0YWlscy5wcm9kdWN0cykge1xyXG4gICAgICAgIGZvciAodmFyIHByb21vdGlvbmVsZW1lbnQgb2YgcHJvbW90aW9uTGlzdC5yZXN1bHQubGluZVByb21vdGlvbnMpIHtcclxuICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgZWxlbWVudC5pdGVtTGluZUlkLnRvU3RyaW5nKCkgPT09XHJcbiAgICAgICAgICAgIHByb21vdGlvbmVsZW1lbnQuaXRlbUxpbmVJZC50b1N0cmluZygpXHJcbiAgICAgICAgICApIHtcclxuICAgICAgICAgICAgZWxlbWVudC5saW5lUHJvbW90aW9ucyA9IHByb21vdGlvbmVsZW1lbnQ7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYmFza2V0RGV0YWlscztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGFkZCBUcmFuc2FjdGlvbiBwcm9tb3Rpb25cclxuICAgKiBAcGFyYW0gIG51bGxcclxuICAgKiBAcmV0dXJucyBiYXNrZXREZXRhaWxzXHJcbiAgICovXHJcblxyXG4gIGFkZFRyYW5zYWN0aW9uUHJvbW90aW9uKHByb21vdGlvbkxpc3Q6IHsgcmVzdWx0OiB7IHRyYW5zYWN0aW9uUHJvbW90aW9uOiBhbnkgfTsgfSwgYmFza2V0ZGV0YWlsczogQmFza2V0KSB7XHJcbiAgICBjb25zb2xlLmxvZyhcclxuICAgICAgXCJlOmJhc2tldCA6YmFza2V0IFNlcnZpY2UgOiBwcm9tb3Rpb25MaXN0IGFuZCBiYXNrZXREZXRhaWxzIGZvciB0cmFuc2FjdGlvblByb21vdGlvblwiLFxyXG4gICAgICBKU09OLnN0cmluZ2lmeShwcm9tb3Rpb25MaXN0KSxcclxuICAgICAgSlNPTi5zdHJpbmdpZnkoYmFza2V0ZGV0YWlscyksXHJcbiAgICAgIEpTT04uc3RyaW5naWZ5KGJhc2tldGRldGFpbHMudHJhbnNhY3Rpb25Qcm9tb3Rpb24pXHJcbiAgICApO1xyXG4gICAgaWYgKFxyXG4gICAgICBwcm9tb3Rpb25MaXN0ICYmXHJcbiAgICAgIHByb21vdGlvbkxpc3QucmVzdWx0ICYmXHJcbiAgICAgIHByb21vdGlvbkxpc3QucmVzdWx0LnRyYW5zYWN0aW9uUHJvbW90aW9uICYmXHJcbiAgICAgIHByb21vdGlvbkxpc3QucmVzdWx0LnRyYW5zYWN0aW9uUHJvbW90aW9uLmxlbmd0aCA+IDBcclxuICAgICkge1xyXG4gICAgICBwcm9tb3Rpb25MaXN0LnJlc3VsdC50cmFuc2FjdGlvblByb21vdGlvbi5mb3JFYWNoKCh0UHJvbW90aW9uOiBhbnkpID0+IHtcclxuICAgICAgICBsZXQgdHJhbnNhY3Rpb25Qcm9tb3Rpb25FbnRyeVVwZGF0ZWQ6IGFueSA9IE9iamVjdC5hc3NpZ24oXHJcbiAgICAgICAgICB7fSxcclxuICAgICAgICAgIHRQcm9tb3Rpb25cclxuICAgICAgICApO1xyXG5cclxuICAgICAgICB0cmFuc2FjdGlvblByb21vdGlvbkVudHJ5VXBkYXRlZC5pdGVtTGluZUlkcyA9IGJhc2tldGRldGFpbHMucHJvZHVjdHMubWFwKFxyXG4gICAgICAgICAgKHByb2R1Y3QpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHByb2R1Y3QuaXRlbUxpbmVJZDtcclxuICAgICAgICAgIH1cclxuICAgICAgICApO1xyXG5cclxuICAgICAgICBpZiAoIWJhc2tldGRldGFpbHMudHJhbnNhY3Rpb25Qcm9tb3Rpb24pIHtcclxuICAgICAgICAgIGJhc2tldGRldGFpbHMudHJhbnNhY3Rpb25Qcm9tb3Rpb24gPSBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYmFza2V0ZGV0YWlscy50cmFuc2FjdGlvblByb21vdGlvbi5wdXNoKFxyXG4gICAgICAgICAgdHJhbnNhY3Rpb25Qcm9tb3Rpb25FbnRyeVVwZGF0ZWRcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICBiYXNrZXRkZXRhaWxzID0gdGhpcy50cmFuc2FjdGlvblByb21vdGlvblByb2R1Y3RQb3J0aW9uQ2FsYyhcclxuICAgICAgICAgIGJhc2tldGRldGFpbHMsXHJcbiAgICAgICAgICB0cmFuc2FjdGlvblByb21vdGlvbkVudHJ5VXBkYXRlZFxyXG4gICAgICAgICk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgY29uc29sZS5sb2coXHJcbiAgICAgIFwiYmFza2V0IGRldGFpbHMgaW4gcmVmdW5kIGNhbGN1bGF0aW9uIGZpbGVcIixcclxuICAgICAgSlNPTi5zdHJpbmdpZnkoYmFza2V0ZGV0YWlscylcclxuICAgICk7XHJcbiAgICByZXR1cm4gYmFza2V0ZGV0YWlscztcclxuICB9XHJcblxyXG4gIHVwZGF0ZVByb2R1Y3RUb3RhbEZvclN1bW1hcnkoYmFza2V0RGV0YWlsczogeyB0b3RhbDogc3RyaW5nIHwgbnVtYmVyOyBxdWFudGl0eTogc3RyaW5nIHwgbnVtYmVyOyBwcm9kdWN0czogYW55OyB9KSB7XHJcbiAgICAvKnNhbGUtICAgICAgICAgICAgcHJvZHVjdCByZWZ1bmRlZFF1YW50aXR5ID0gdW5kZWZpbmVkXHJcbiAgICBwYXJ0aWFsIHJlZnVuZCAtICAgcHJvZHVjdCByZWZ1bmRlZFF1YW50aXR5IGlzID4gMFxyXG4gICAgdG90YWwgcmVmdW5kIC0gICAgIHByb3VkY3QgcmVmdW5kZWRRdWFudGl0eSBpcyA+IDBcclxuICAgIGV4Y2hhbmdlIC0gICAgICAgICBleGNoYW5nZSBwcm9kdWN0IHJlZnVuZGVkUXVhbnRpdHkgaXMgPiAwICBcclxuICAgICAgICAgICAgICAgICAgICAgICBuZXcgcHJvZHVjdCByZWZ1bmRlZFF1YW50aXR5ID0gdW5kZWZpbmVkICBcclxuICAgICAgICAgICAgICAgICAgICAgICBvbGQgcHJvZHVjdCB3aXRob3V0IGV4Y2hhbmdlIHJlZnVuZGVkUXVhbnRpdHkgPSAwXHJcbiAgICB1bnJlZmVyZW5jZSByZWZ1bmQtcHJvZHVjdCByZWZ1bmRlZFF1YW50aXR5IGlzID4gMCAqL1xyXG5cclxuICAgIGJhc2tldERldGFpbHMudG90YWwgPSAwO1xyXG4gICAgYmFza2V0RGV0YWlscy5xdWFudGl0eSA9IDA7XHJcbiAgICBmb3IgKHZhciBwcm9kdWN0IG9mIGJhc2tldERldGFpbHMucHJvZHVjdHMpIHtcclxuICAgICAgaWYgKHByb2R1Y3QubGluZVByb21vdGlvbnMpIHtcclxuICAgICAgICBwcm9kdWN0LnRvdGFsID0gcHJvZHVjdC5saW5lUHJvbW90aW9ucy5wcm9tb3Rpb25MaW5lUHJpY2U7XHJcbiAgICAgIH0gZWxzZSBpZiAocHJvZHVjdC5saW5lRGlzY291bnQgJiYgIXByb2R1Y3QubGluZVByb21vdGlvbnMpIHtcclxuICAgICAgICBwcm9kdWN0LnRvdGFsID0gcHJvZHVjdC5saW5lRGlzY291bnQuZGlzY291bnRlZExpbmVQcmljZTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBwcm9kdWN0LnRvdGFsID0gcHJvZHVjdC50b3RhbExpbmVQcmljZTtcclxuICAgICAgfVxyXG4gICAgICBwcm9kdWN0LnRvdGFsID1cclxuICAgICAgICBwcm9kdWN0LnRvdGFsIC1cclxuICAgICAgICBNYXRoLmFicyhwcm9kdWN0LnJlZnVuZGVkVG90YWwgPyBwcm9kdWN0LnJlZnVuZGVkVG90YWwgOiAwKTtcclxuXHJcbiAgICAgIGJhc2tldERldGFpbHMudG90YWwgKz0gcHJvZHVjdC50b3RhbDtcclxuICAgICAgYmFza2V0RGV0YWlscy5xdWFudGl0eSA9XHJcbiAgICAgICAgYmFza2V0RGV0YWlscy5xdWFudGl0eSArXHJcbiAgICAgICAgKHByb2R1Y3QucXVhbnRpdHkgLVxyXG4gICAgICAgICAgKHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eSA/IHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eSA6IDApKTtcclxuICAgICAgY29uc29sZS5sb2coXHJcbiAgICAgICAgXCJlLWJhc2tldDpFeGNoYW5nZVN1bW1hcnlTY3JlZW46dXBkYXRlIGJhc2tldGRldGFpbHMgdG90YWwgOlwiICtcclxuICAgICAgICBiYXNrZXREZXRhaWxzLnRvdGFsICtcclxuICAgICAgICBcIiBQcm9kdWN0IGxpbmUgSUQgOiBcIiArXHJcbiAgICAgICAgcHJvZHVjdC5pdGVtTGluZUlkICtcclxuICAgICAgICBcIiBwcm9kdWN0IHRvdGFsIDogXCIgK1xyXG4gICAgICAgIHByb2R1Y3QudG90YWwsXHJcbiAgICAgICAgXCJxdWFudGl0eSAgOiBcIiArIGJhc2tldERldGFpbHMucXVhbnRpdHlcclxuICAgICAgKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLnVwZGF0ZUJhc2tldFRvdGFsRm9yU3VtbWFyeShiYXNrZXREZXRhaWxzKTtcclxuICB9XHJcblxyXG4gIHVwZGF0ZUJhc2tldFRvdGFsRm9yU3VtbWFyeShiYXNrZXREZXRhaWxzOiBhbnkpIHtcclxuICAgIGJhc2tldERldGFpbHMuYmFza2V0VG90YWwgPSBiYXNrZXREZXRhaWxzLnRvdGFsO1xyXG4gICAgY29uc29sZS5pbmZvKFxyXG4gICAgICBcImViYXNrZXQgOiBiYXNrZXQgU2VydmljZSA6IHVwZGF0ZSBCYXNrZXQgVG90YWwgZm9yIHRyYW5zYWN0aW9uIHRyYW5zYWN0aW9uRGlzY291bnQgIFwiLFxyXG4gICAgICBKU09OLnN0cmluZ2lmeShiYXNrZXREZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQpXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnNvbGUuaW5mbyhcclxuICAgICAgXCJlYmFza2V0IDogYmFza2V0IFNlcnZpY2UgOiB1cGRhdGUgQmFza2V0IFRvdGFsIGZvciB0cmFuc2FjdGlvbiB0cmFuc2FjdGlvblByb21vdGlvbiAgXCIsXHJcbiAgICAgIEpTT04uc3RyaW5naWZ5KGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25Qcm9tb3Rpb24pXHJcbiAgICApO1xyXG5cclxuICAgIGJhc2tldERldGFpbHMgPSB0aGlzLnVwZGF0ZVRyYW5zYWN0aW9uUHJvbW90aW9uKGJhc2tldERldGFpbHMpO1xyXG4gICAgYmFza2V0RGV0YWlscyA9IHRoaXMudXBkYXRlVHJhbnNhY3Rpb25EaXNjb3VudChiYXNrZXREZXRhaWxzKTtcclxuICAgIGJhc2tldERldGFpbHMuYmFza2V0VG90YWwgPSBOdW1iZXIoYmFza2V0RGV0YWlscy5iYXNrZXRUb3RhbC50b0ZpeGVkKDIpKTtcclxuXHJcbiAgICBjb25zb2xlLmluZm8oXHJcbiAgICAgIFwiZWJhc2tldCA6IGJhc2tldCBTZXJ2aWNlIDogdXBkYXRlIEJhc2tldCBUb3RhbDogYmFza2V0VG90YWwgYWZ0ZXIgcHJvbW90aW9uIGFwcGxpZWQgIGZvciBiYXNrZXRUb3RhbFwiLFxyXG4gICAgICBiYXNrZXREZXRhaWxzLmJhc2tldFRvdGFsXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIGJhc2tldERldGFpbHM7XHJcbiAgfVxyXG5cclxuICB1cGRhdGVUcmFuc2FjdGlvbkRpc2NvdW50KGJhc2tldERldGFpbHM6IHsgdHJhbnNhY3Rpb25EaXNjb3VudDogYW55W107IGJhc2tldFRvdGFsOiBudW1iZXI7IH0pIHtcclxuICAgIGlmIChcclxuICAgICAgYmFza2V0RGV0YWlscy50cmFuc2FjdGlvbkRpc2NvdW50ICYmXHJcbiAgICAgIGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudC5sZW5ndGggPiAwXHJcbiAgICApIHtcclxuICAgICAgY29uc3QgZGlzY291bnRUb3RhbCA9IGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudC5yZWR1Y2UoXHJcbiAgICAgICAgKG46IGFueSwgeyBkaXNjb3VudEFtb3VudCB9OiBhbnkpID0+IG4gKyBkaXNjb3VudEFtb3VudCxcclxuICAgICAgICAwXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnNvbGUubG9nKFwiZWJhc2tldCA6IGJhc2tldCBTZXJ2aWNlIDogIGRpc2NvdW50VG90YWwgXCIsIGRpc2NvdW50VG90YWwpO1xyXG4gICAgICBiYXNrZXREZXRhaWxzLmJhc2tldFRvdGFsID1cclxuICAgICAgICBiYXNrZXREZXRhaWxzLmJhc2tldFRvdGFsIC0gTWF0aC5hYnMoZGlzY291bnRUb3RhbCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYmFza2V0RGV0YWlscztcclxuICB9XHJcblxyXG4gIHVwZGF0ZVRyYW5zYWN0aW9uUHJvbW90aW9uKGJhc2tldERldGFpbHM6IHsgdHJhbnNhY3Rpb25Qcm9tb3Rpb246IGFueVtdOyBiYXNrZXRUb3RhbDogbnVtYmVyOyB9KSB7XHJcbiAgICBpZiAoXHJcbiAgICAgIGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25Qcm9tb3Rpb24gJiZcclxuICAgICAgYmFza2V0RGV0YWlscy50cmFuc2FjdGlvblByb21vdGlvbi5sZW5ndGggPiAwXHJcbiAgICApIHtcclxuICAgICAgY29uc3QgZGlzY291bnRUb3RhbCA9IGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25Qcm9tb3Rpb24ucmVkdWNlKFxyXG4gICAgICAgIChuOiBhbnksIHsgcHJvbW90aW9uQW1vdW50IH06IGFueSkgPT4gbiArIHByb21vdGlvbkFtb3VudCxcclxuICAgICAgICAwXHJcbiAgICAgICk7XHJcbiAgICAgIGJhc2tldERldGFpbHMuYmFza2V0VG90YWwgPVxyXG4gICAgICAgIGJhc2tldERldGFpbHMuYmFza2V0VG90YWwgLSBNYXRoLmFicyhkaXNjb3VudFRvdGFsKTtcclxuICAgIH1cclxuICAgIHJldHVybiBiYXNrZXREZXRhaWxzO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlQmFza2V0VG90YWxXaXRob3V0RGlzY291bnQoYmFza2V0OiBCYXNrZXQpOiBCYXNrZXQge1xyXG4gICAgYmFza2V0LnRvdGFsID0gMDtcclxuICAgIGJhc2tldC5xdWFudGl0eSA9IDA7XHJcblxyXG4gICAgZm9yICh2YXIgcHJvZHVjdCBvZiBiYXNrZXQucHJvZHVjdHMpIHtcclxuICAgICAgaWYgKHByb2R1Y3QubGluZVByb21vdGlvbnMpIHtcclxuICAgICAgICBwcm9kdWN0LnRvdGFsID0gcHJvZHVjdC5saW5lUHJvbW90aW9ucy5wcm9tb3Rpb25MaW5lUHJpY2U7XHJcbiAgICAgIH0gZWxzZSBpZiAocHJvZHVjdC5saW5lRGlzY291bnQgJiYgIXByb2R1Y3QubGluZVByb21vdGlvbnMpIHtcclxuICAgICAgICBwcm9kdWN0LnRvdGFsID0gcHJvZHVjdC5saW5lRGlzY291bnQuZGlzY291bnRlZExpbmVQcmljZSB8fCAwO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHByb2R1Y3QudG90YWwgPSBwcm9kdWN0LnRvdGFsTGluZVByaWNlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBwcm9kdWN0LnRvdGFsID1cclxuICAgICAgICBwcm9kdWN0LnRvdGFsIC1cclxuICAgICAgICBNYXRoLmFicyhwcm9kdWN0LnJlZnVuZGVkVG90YWwgPyBwcm9kdWN0LnJlZnVuZGVkVG90YWwgOiAwKTtcclxuICAgICAgYmFza2V0LnRvdGFsICs9IHByb2R1Y3QudG90YWw7XHJcbiAgICAgIGJhc2tldC5xdWFudGl0eSA9XHJcbiAgICAgICAgYmFza2V0LnF1YW50aXR5ICtcclxuICAgICAgICAocHJvZHVjdC5xdWFudGl0eSAtXHJcbiAgICAgICAgICAocHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5ID8gcHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5IDogMCkpO1xyXG5cclxuICAgICAgY29uc29sZS5sb2coXHJcbiAgICAgICAgXCJlLWJhc2tldDpiYXNrZXQgc2VydmljZTp1cGRhdGUgYmFza2V0ZGV0YWlscyB0b3RhbCA6XCIgK1xyXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KGJhc2tldCkgK1xyXG4gICAgICAgIGJhc2tldC50b3RhbCArXHJcbiAgICAgICAgXCIgUHJvZHVjdCBsaW5lIElEIDogXCIgK1xyXG4gICAgICAgIHByb2R1Y3QuaXRlbUxpbmVJZCArXHJcbiAgICAgICAgXCIgcHJvZHVjdCB0b3RhbCA6IFwiICtcclxuICAgICAgICBwcm9kdWN0LnRvdGFsXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgYmFza2V0LmJhc2tldFRvdGFsID0gYmFza2V0LnRvdGFsO1xyXG4gICAgcmV0dXJuIGJhc2tldDtcclxuICB9XHJcblxyXG4gIHVwZGF0ZUJhc2tldFRvdGFsV2l0aERpc2NvdW50cyhiYXNrZXQ6IGFueSk6IEJhc2tldCB7XHJcbiAgICBjb25zb2xlLmxvZyhcclxuICAgICAgXCJlOmJhc2tldCA6UmVmdW5kQmFza2V0U2NyZWVuIDogdGhpcy5iYXNrZXREZXRhaWxzIG5ldyB2YWx1ZXNcIixcclxuICAgICAgYmFza2V0LFxyXG4gICAgICBKU09OLnN0cmluZ2lmeShiYXNrZXQuYmFza2V0VG90YWwpXHJcbiAgICApO1xyXG4gICAgaWYgKGJhc2tldC50cmFuc2FjdGlvblByb21vdGlvbiAmJiBiYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb24ubGVuZ3RoID4gMCkge1xyXG4gICAgICBjb25zdCBkaXNjb3VudFRvdGFsID0gYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uLnJlZHVjZShcclxuICAgICAgICAobjogYW55LCB7IHByb21vdGlvbkFtb3VudCB9OiBhbnkpID0+IG4gKyBwcm9tb3Rpb25BbW91bnQsXHJcbiAgICAgICAgMFxyXG4gICAgICApO1xyXG4gICAgICBiYXNrZXQuYmFza2V0VG90YWwgPSBiYXNrZXQuYmFza2V0VG90YWwgLSBkaXNjb3VudFRvdGFsO1xyXG4gICAgfVxyXG4gICAgaWYgKGJhc2tldC50cmFuc2FjdGlvbkRpc2NvdW50ICYmIGJhc2tldC50cmFuc2FjdGlvbkRpc2NvdW50Lmxlbmd0aCA+IDApIHtcclxuICAgICAgY29uc3QgZGlzY291bnRUb3RhbCA9IGJhc2tldC50cmFuc2FjdGlvbkRpc2NvdW50LnJlZHVjZShcclxuICAgICAgICAobjogYW55LCB7IGRpc2NvdW50QW1vdW50IH06IGFueSkgPT4gbiArIGRpc2NvdW50QW1vdW50LFxyXG4gICAgICAgIDBcclxuICAgICAgKTtcclxuXHJcbiAgICAgIGJhc2tldC5iYXNrZXRUb3RhbCA9IGJhc2tldC5iYXNrZXRUb3RhbCAtIGRpc2NvdW50VG90YWw7XHJcbiAgICB9XHJcbiAgICBjb25zb2xlLmxvZyhcclxuICAgICAgXCJlOmJhc2tldCA6UmVmdW5kQmFza2V0U2NyZWVuIDogYmFza2V0IG5ldyB2YWx1ZXNcIixcclxuICAgICAgSlNPTi5zdHJpbmdpZnkoYmFza2V0KVxyXG4gICAgKTtcclxuXHJcbiAgICByZXR1cm4gYmFza2V0O1xyXG4gIH1cclxuXHJcbiAgdHJhbnNhY3Rpb25EaXNjb3VudEFuZFByb21vdGlvblByb2R1Y3RvcnRpb25DYWxjdWxhdGlvbihiYXNrZXQ6IEJhc2tldCkge1xyXG4gICAgaWYgKGJhc2tldC50cmFuc2FjdGlvbkRpc2NvdW50ICYmIGJhc2tldC50cmFuc2FjdGlvbkRpc2NvdW50Lmxlbmd0aCA+IDApIHtcclxuICAgICAgYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQuZm9yRWFjaChcclxuICAgICAgICAoZGlzY291bnQpID0+XHJcbiAgICAgICAgKGJhc2tldCA9IHRoaXMudHJhbnNhY3Rpb25EaXNjb3VudFByb2R1Y3RQb3J0aW9uQ2FsYyhcclxuICAgICAgICAgIGJhc2tldCxcclxuICAgICAgICAgIGRpc2NvdW50XHJcbiAgICAgICAgKSlcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uICYmIGJhc2tldC50cmFuc2FjdGlvblByb21vdGlvbi5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGJhc2tldC50cmFuc2FjdGlvblByb21vdGlvbi5mb3JFYWNoKChwcm9tb3Rpb24pID0+IHtcclxuICAgICAgICBiYXNrZXQgPSB0aGlzLnRyYW5zYWN0aW9uUHJvbW90aW9uUHJvZHVjdFBvcnRpb25DYWxjKGJhc2tldCwgcHJvbW90aW9uKTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBjb25zb2xlLmxvZyhcclxuICAgICAgXCJlYmFza2V0OiBiYXNrZXQgaXRlbSBkaXNjb3VudCBwcm90aW9uIGNhbGN1bGF0aW9uXCIsXHJcbiAgICAgIGJhc2tldCxcclxuICAgICAgYmFza2V0LnByb2R1Y3RzXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIGJhc2tldDtcclxuICB9XHJcblxyXG4gIHRyYW5zYWN0aW9uUHJvbW90aW9uUHJvZHVjdFBvcnRpb25DYWxjKFxyXG4gICAgYmFza2V0OiBhbnksXHJcbiAgICBwcm9tb3Rpb246IGFueVxyXG4gICkge1xyXG4gICAgbGV0IHRvdGFsID0gMDtcclxuICAgIGxldCBwZXJjZW50YWdlID0gMDtcclxuICAgIHtcclxuICAgICAgYmFza2V0LnByb2R1Y3RzLmZvckVhY2goKHA6YW55KSA9PiB7XHJcbiAgICAgICAgaWYgKHByb21vdGlvbi5pdGVtTGluZUlkcy5pbmNsdWRlcyhwLml0ZW1MaW5lSWQpKSB7XHJcbiAgICAgICAgICBwID0gdGhpcy52YWxpZGF0ZVByb2R1Y3RJdGVtRGlzY291bnQocCk7XHJcbiAgICAgICAgICBjb25zdCBwcm9kdWN0Q29udHJpYnV0aW9uSW5Ub3RhbCA9XHJcbiAgICAgICAgICAgIHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHAuaXRlbURpc2NvdW50cy50cm5EaXNjb3VudHNQb3J0aW9uKSArXHJcbiAgICAgICAgICAgIHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHAuaXRlbURpc2NvdW50cy50cm5Qcm9tb3Rpb25zUG9ydGlvbikgLVxyXG4gICAgICAgICAgICB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMihwLml0ZW1EaXNjb3VudHMucmVmdW5kUG9ydGlvbik7XHJcbiAgICAgICAgICB0b3RhbCArPSAocC50b3RhbCAtIHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHByb2R1Y3RDb250cmlidXRpb25JblRvdGFsKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgICAgY29uc29sZS5sb2coXHJcbiAgICAgICAgYGViYXNrZXQ6IHRybnNhY3Rpb25Qcm9tb3Rpb246ICR7SlNPTi5zdHJpbmdpZnkoXHJcbiAgICAgICAgICBwcm9tb3Rpb25cclxuICAgICAgICApfSwgc2VsZWN0ZWQgcHJvZHVjdHMgdG90YWw6ICR7dG90YWx9YFxyXG4gICAgICApO1xyXG4gICAgICBiYXNrZXQucHJvZHVjdHMuZm9yRWFjaCgocHJvZHVjdDogYW55KSA9PiB7XHJcbiAgICAgICAgcHJvZHVjdCA9IHRoaXMudmFsaWRhdGVQcm9kdWN0SXRlbURpc2NvdW50KHByb2R1Y3QpO1xyXG5cclxuICAgICAgICBjb25zdCBwcm9kdWN0Q29udHJpYnV0aW9uSW5Ub3RhbCA9XHJcbiAgICAgICAgICB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMihwcm9kdWN0Lml0ZW1EaXNjb3VudHMudHJuRGlzY291bnRzUG9ydGlvbikgK1xyXG4gICAgICAgICAgdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIocHJvZHVjdC5pdGVtRGlzY291bnRzLnRyblByb21vdGlvbnNQb3J0aW9uKSAtXHJcbiAgICAgICAgICB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMihwcm9kdWN0Lml0ZW1EaXNjb3VudHMucmVmdW5kUG9ydGlvbik7XHJcblxyXG4gICAgICAgIGlmIChwcm9tb3Rpb24uaXRlbUxpbmVJZHMuaW5jbHVkZXMocHJvZHVjdC5pdGVtTGluZUlkKSkge1xyXG4gICAgICAgICAgcGVyY2VudGFnZSA9ICgocHJvZHVjdC50b3RhbCAtIHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHByb2R1Y3RDb250cmlidXRpb25JblRvdGFsKSkgLyB0b3RhbCkgKiAxMDA7XHJcbiAgICAgICAgICBwcm9kdWN0Lml0ZW1EaXNjb3VudHMudHJuUHJvbW90aW9uc1BvcnRpb24gKz1cclxuICAgICAgICAgICAgKHByb21vdGlvbi5wcm9tb3Rpb25BbW91bnQgKiBwZXJjZW50YWdlKSAvIDEwMDtcclxuICAgICAgICAgIHByb2R1Y3QuaXRlbURpc2NvdW50cy50cm5Qcm9tb3Rpb25zUG9ydGlvbiA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHByb2R1Y3QuaXRlbURpc2NvdW50cy50cm5Qcm9tb3Rpb25zUG9ydGlvbik7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiBiYXNrZXQ7XHJcbiAgfVxyXG5cclxuICB0cmFuc2FjdGlvbkRpc2NvdW50UHJvZHVjdFBvcnRpb25DYWxjKFxyXG4gICAgYmFza2V0OiBhbnksXHJcbiAgICBkaXNjb3VudDogYW55XHJcbiAgKSB7XHJcbiAgICBsZXQgdG90YWwgPSAwO1xyXG4gICAgbGV0IHBlcmNlbnRhZ2UgPSAwO1xyXG5cclxuICAgIGJhc2tldC5wcm9kdWN0cy5mb3JFYWNoKChwOiBhbnkpID0+IHtcclxuICAgICAgaWYgKGRpc2NvdW50Lml0ZW1MaW5lSWRzLmluY2x1ZGVzKHAuaXRlbUxpbmVJZCkpIHtcclxuICAgICAgICBwID0gdGhpcy52YWxpZGF0ZVByb2R1Y3RJdGVtRGlzY291bnQocCk7XHJcbiAgICAgICAgY29uc3QgcHJvZHVjdENvbnRyaWJ1dGlvbkluVG90YWwgPVxyXG4gICAgICAgICAgdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIocC5pdGVtRGlzY291bnRzLnRybkRpc2NvdW50c1BvcnRpb24pICtcclxuICAgICAgICAgIHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHAuaXRlbURpc2NvdW50cy50cm5Qcm9tb3Rpb25zUG9ydGlvbikgLVxyXG4gICAgICAgICAgdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIocC5pdGVtRGlzY291bnRzLnJlZnVuZFBvcnRpb24pO1xyXG5cclxuXHJcbiAgICAgICAgdG90YWwgKz0gKHAudG90YWwgLSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMihwcm9kdWN0Q29udHJpYnV0aW9uSW5Ub3RhbCkpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBjb25zb2xlLmxvZyhcclxuICAgICAgYGViYXNrZXQ6IHRybnNhY3Rpb25EaXNjb3VudDogJHtKU09OLnN0cmluZ2lmeShcclxuICAgICAgICBkaXNjb3VudFxyXG4gICAgICApfSwgc2VsZWN0ZWQgcHJvZHVjdHMgdG90YWw6ICR7dG90YWx9YFxyXG4gICAgKTtcclxuXHJcbiAgICBiYXNrZXQucHJvZHVjdHMuZm9yRWFjaCgocHJvZHVjdDphbnkpID0+IHtcclxuICAgICAgcHJvZHVjdCA9IHRoaXMudmFsaWRhdGVQcm9kdWN0SXRlbURpc2NvdW50KHByb2R1Y3QpO1xyXG4gICAgICBjb25zb2xlLmxvZyhwcm9kdWN0LmRpc2NvdW50YWJsZSwgXCJlYmFza2V0IDogYmFza2V0IHNlcnZpY2UgOiBkaXNjb3VudGFibGUgaW4gYmFza2V0IHNlcnZpY2VcIik7XHJcblxyXG4gICAgICBjb25zdCBwcm9kdWN0Q29udHJpYnV0aW9uSW5Ub3RhbCA9XHJcbiAgICAgICAgdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIocHJvZHVjdC5pdGVtRGlzY291bnRzLnRybkRpc2NvdW50c1BvcnRpb24pICtcclxuICAgICAgICB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMihwcm9kdWN0Lml0ZW1EaXNjb3VudHMudHJuUHJvbW90aW9uc1BvcnRpb24pIC1cclxuICAgICAgICB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMihwcm9kdWN0Lml0ZW1EaXNjb3VudHMucmVmdW5kUG9ydGlvbik7XHJcblxyXG4gICAgICBpZiAoZGlzY291bnQuaXRlbUxpbmVJZHMuaW5jbHVkZXMocHJvZHVjdC5pdGVtTGluZUlkKSAmJiBwcm9kdWN0LmRpc2NvdW50YWJsZSA9PSB0cnVlKSB7XHJcbiAgICAgICAgcGVyY2VudGFnZSA9ICgocHJvZHVjdC50b3RhbCAtIHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHByb2R1Y3RDb250cmlidXRpb25JblRvdGFsKSkgLyB0b3RhbCkgKiAxMDA7XHJcbiAgICAgICAgcHJvZHVjdC5pdGVtRGlzY291bnRzLnRybkRpc2NvdW50c1BvcnRpb24gKz1cclxuICAgICAgICAgIChkaXNjb3VudC5kaXNjb3VudEFtb3VudCAqIHBlcmNlbnRhZ2UpIC8gMTAwO1xyXG4gICAgICAgIHByb2R1Y3QuaXRlbURpc2NvdW50cy50cm5EaXNjb3VudHNQb3J0aW9uID0gdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIocHJvZHVjdC5pdGVtRGlzY291bnRzLnRybkRpc2NvdW50c1BvcnRpb24pXHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIGJhc2tldDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB2YWxpZGF0ZVByb2R1Y3RJdGVtRGlzY291bnQocHJvZHVjdDogUHJvZHVjdCkge1xyXG4gICAgaWYgKCFwcm9kdWN0Lml0ZW1EaXNjb3VudHMpIHtcclxuICAgICAgcHJvZHVjdC5pdGVtRGlzY291bnRzID0ge1xyXG4gICAgICAgIHRybkRpc2NvdW50c1BvcnRpb246IDAsXHJcbiAgICAgICAgdHJuUHJvbW90aW9uc1BvcnRpb246IDAsXHJcbiAgICAgICAgcmVmdW5kUG9ydGlvbjogMCxcclxuICAgICAgfTtcclxuICAgIH1cclxuICAgIHJldHVybiBwcm9kdWN0O1xyXG4gIH1cclxuXHJcbiAgbWFya1Byb2R1Y3QocHJvZHVjdDogUHJvZHVjdCkge1xyXG4gICAgdGhpcy5wcm9kdWN0U291cmNlLm5leHQocHJvZHVjdCk7XHJcbiAgfVxyXG4gIHN0b3BQZWVyU3luY1Byb2Nlc3MocGVlclN5bmM6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMucGVlclNvdXJjZS5uZXh0KHBlZXJTeW5jKTtcclxuICB9XHJcblxyXG4gIHNjYW5TdGFydChpc1NjYW5uaW5nOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLnNjYW5Tb3VyY2UubmV4dChpc1NjYW5uaW5nKTtcclxuICB9XHJcblxyXG4gIHByb21vdGlvblJlbWFpbmluZ0NhbGN1bGF0aW9uKHByb21vdGlvbjogVHJhbnNhY3Rpb25Qcm9tb3Rpb25bXSkge1xyXG4gICAgdmFyIHByb21vdGlvblZhbHVlID0gMDtcclxuICAgIHByb21vdGlvbi5mb3JFYWNoKChlbGVtZW50KSA9PiB7XHJcbiAgICAgIHByb21vdGlvblZhbHVlICs9IGVsZW1lbnQucHJvbW90aW9uQW1vdW50O1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gcHJvbW90aW9uVmFsdWU7XHJcbiAgfVxyXG5cclxuICBkaXNjb3VudFJlbWFpbmluZ0NhbGN1bGF0aW9uKGRpc2NvdW50OiBUcmFuc2FjdGlvbkRpc2NvdW50W10pIHtcclxuICAgIHZhciBkaXNjb3VudFZhbHVlID0gMDtcclxuICAgIGRpc2NvdW50LmZvckVhY2goKGVsZW1lbnQpID0+IHtcclxuICAgICAgZGlzY291bnRWYWx1ZSArPSBlbGVtZW50LmRpc2NvdW50QW1vdW50O1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gZGlzY291bnRWYWx1ZTtcclxuICB9XHJcblxyXG4gIGRpc2NvdW50UmVmdW5kZWRDYWxjdWxhdGlvbihkaXNjb3VudDogVHJhbnNhY3Rpb25EaXNjb3VudFtdKSB7XHJcbiAgICB2YXIgZGlzY291bnRWYWx1ZSA9IDA7XHJcbiAgICBkaXNjb3VudC5mb3JFYWNoKChlbGVtZW50KSA9PiB7XHJcbiAgICAgIGlmIChlbGVtZW50LmRpc2NvdW50QW1vdW50IDwgMCkge1xyXG4gICAgICAgIGRpc2NvdW50VmFsdWUgKz0gZWxlbWVudC5kaXNjb3VudEFtb3VudDtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gZGlzY291bnRWYWx1ZTtcclxuICB9XHJcblxyXG4gIGdlbmVyYXRlTmV3SXRlbUxpbmVJZChwcm9kdWN0czogUHJvZHVjdFtdKSB7XHJcbiAgICBsZXQgbGFyZ2VzdE51bWJlcjogYW55ID0gMDtcclxuXHJcbiAgICBpZiAocHJvZHVjdHMubGVuZ3RoID4gMCkge1xyXG4gICAgICBsZXQgaXRlbUxpbmVJZEFycmF5ID0gcHJvZHVjdHMubWFwKChwcm9kdWN0KSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIHByb2R1Y3QuaXRlbUxpbmVJZDtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBsYXJnZXN0TnVtYmVyID0gaXRlbUxpbmVJZEFycmF5LnJlZHVjZSgoYSA6YW55LCBiOmFueSkgPT4gTWF0aC5tYXgoYSwgYikpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBsYXJnZXN0TnVtYmVyICsgMTtcclxuICB9XHJcblxyXG4gIHVwZGF0ZUJhc2tldFByb2R1Y3REYXRhQXNQZXJRdWFudGl0eShcclxuICAgIHByb2R1Y3Q6IGFueSxcclxuICAgIHF1YW50aXR5OiBudW1iZXJcclxuICApOiBQcm9kdWN0IHtcclxuXHJcbiAgICBjb25zb2xlLmxvZyhgZWJhc2tldDogdXBkYXRlQmFza2V0UHJvZHVjdERhdGFBc1BlclF1YW50aXR5IDogJHtxdWFudGl0eX0gcHJvZHVjdDogJHtKU09OLnN0cmluZ2lmeShwcm9kdWN0KX1gKTtcclxuICAgIHByb2R1Y3QucXVhbnRpdHkgPSBxdWFudGl0eTtcclxuICAgIGlmIChwcm9kdWN0Lmhhc093blByb3BlcnR5KFwibGluZURpc2NvdW50XCIpKSB7XHJcbiAgICAgIC8vICYmIHRoaXMucHJvZHVjdC5xdWFudGl0eSAhPT0gdGhpcy5wcm9kdWN0RGV0YWlsRm9ybS5jb250cm9scy5xdWFudGl0eS52YWx1ZVxyXG4gICAgICBwcm9kdWN0LmxpbmVEaXNjb3VudC5kaXNjb3VudGVkTGluZVByaWNlID0gTnVtYmVyKFxyXG4gICAgICAgIHRoaXMubnVtYmVyVXRpbFNlcnZpY2UuZ2V0Rmxvb3JlZEZpeGVkKFxyXG4gICAgICAgICAgcHJvZHVjdC5saW5lRGlzY291bnQudW5pdFByaWNlICogcXVhbnRpdHksXHJcbiAgICAgICAgICAyXHJcbiAgICAgICAgKVxyXG4gICAgICApO1xyXG4gICAgICBwcm9kdWN0LmxpbmVEaXNjb3VudC5kaXNjb3VudEFtb3VudCA9XHJcbiAgICAgICAgcHJvZHVjdC50b3RhbExpbmVQcmljZSAtIHByb2R1Y3QubGluZURpc2NvdW50LmRpc2NvdW50ZWRMaW5lUHJpY2U7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBwcm9kdWN0LnRvdGFsTGluZVByaWNlID1cclxuICAgICAgICBxdWFudGl0eSAqIHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwocHJvZHVjdC5zZWxlY3RlZFByaWNlKTtcclxuICAgIH1cclxuICAgIGlmIChwcm9kdWN0LmxpbmVEaXNjb3VudCkge1xyXG4gICAgICBwcm9kdWN0LnRvdGFsID0gcHJvZHVjdC5saW5lRGlzY291bnQuZGlzY291bnRlZExpbmVQcmljZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHByb2R1Y3QudG90YWwgPSBwcm9kdWN0LnRvdGFsTGluZVByaWNlO1xyXG4gICAgfVxyXG4gICAgY29uc29sZS5sb2coYGViYXNrZXQ6IHVwZGF0ZUJhc2tldFByb2R1Y3REYXRhQXNQZXJRdWFudGl0eSA6ICR7cXVhbnRpdHl9IHByb2R1Y3Q6ICR7SlNPTi5zdHJpbmdpZnkocHJvZHVjdCl9YCk7XHJcblxyXG4gICAgcmV0dXJuIHByb2R1Y3Q7XHJcbiAgfVxyXG5cclxuICBmaWx0ZXJQcm9kdWN0TGlzdFdpdGhXZWJPcmRlcihpc1dlYk9yZGVyOiBib29sZWFuKTogUHJvZHVjdFtdIHtcclxuICAgIGNvbnNvbGUubG9nKFwiZWJhc2tldDogZmlsdGVyUHJvZHVjdExpc3RXaXRoV2ViT3JkZXIgaGl0XCIsIEpTT04uc3RyaW5naWZ5KHRoaXMuY3VycmVudEJhc2tldC5wcm9kdWN0cykpO1xyXG4gICAgaWYgKGlzV2ViT3JkZXIpXHJcbiAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRCYXNrZXQucHJvZHVjdHMuZmlsdGVyKCh4KSA9PiB4LmlzV2ViT3JkZXIpO1xyXG4gICAgZWxzZSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRCYXNrZXQucHJvZHVjdHMuZmlsdGVyKCh4KSA9PiAheC5pc1dlYk9yZGVyKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGZpbHRlclByb2R1Y3RMaXN0V2l0aERlbGl2ZXJ5KCk6IFByb2R1Y3RbXSB7XHJcbiAgICBjb25zb2xlLmxvZyhcImViYXNrZXQ6IGZpbHRlclByb2R1Y3RMaXN0V2l0aERlbGl2ZXJ5IGhpdFwiLCBKU09OLnN0cmluZ2lmeSh0aGlzLmN1cnJlbnRCYXNrZXQucHJvZHVjdHMpKTtcclxuICAgIHJldHVybiB0aGlzLmN1cnJlbnRCYXNrZXQucHJvZHVjdHMuZmlsdGVyKCh4KSA9PiB4LmRlbGl2ZXJ5TWV0aG9kID09PSBERUxJVkVSWV9NRVRIT0RTLkRFTElWRVJZLnRvU3RyaW5nKCkpO1xyXG4gIH1cclxuXHJcbiAgZmlsdGVyUHJvZHVjdExpc3RXaXRoRGVsaXZlcnlHcm91cChncm91cDogc3RyaW5nLCBwcm9kdWN0czogUHJvZHVjdFtdKTogUHJvZHVjdFtdIHtcclxuICAgIGNvbnNvbGUubG9nKFwiZWJhc2tldDogZmlsdGVyUHJvZHVjdExpc3RXaXRoRGVsaXZlcnlHcm91cCBoaXRcIiwgSlNPTi5zdHJpbmdpZnkocHJvZHVjdHMpKTtcclxuICAgIHJldHVybiBwcm9kdWN0cy5maWx0ZXIoKHgpID0+IHguZGVsaXZlcnlHcm91cCA9PT0gZ3JvdXApO1xyXG4gIH1cclxuXHJcbiAgZ2VuZXJhdGVOZXdEZWxpdmVyeUdyb3VwTnVtYmVyKHByb2R1Y3RzOiBQcm9kdWN0W10pIHtcclxuICAgIGxldCBsYXJnZXN0TnVtYmVyID0gMDtcclxuXHJcbiAgICBpZiAocHJvZHVjdHMubGVuZ3RoID4gMCkge1xyXG4gICAgICBsZXQgZGVsaXZlcnlHcm91cEFyciA9IHByb2R1Y3RzLm1hcCgocHJvZHVjdCkgPT4ge1xyXG4gICAgICAgIGlmIChwcm9kdWN0LmRlbGl2ZXJ5R3JvdXApIHtcclxuICAgICAgICAgIHJldHVybiBwYXJzZUludChwcm9kdWN0LmRlbGl2ZXJ5R3JvdXApO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gMDtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBsYXJnZXN0TnVtYmVyID0gZGVsaXZlcnlHcm91cEFyci5yZWR1Y2UoKGEsIGIpID0+IE1hdGgubWF4KGEsIGIpKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gKGxhcmdlc3ROdW1iZXIgKyAxKS50b1N0cmluZygpO1xyXG4gIH1cclxuXHJcbiAgZ2V0RGVsaXZlcnlHcm91cE51bWJlcnMocHJvZHVjdHM6IFByb2R1Y3RbXSkge1xyXG4gICAgY29uc29sZS5sb2coXCJnZXREZWxpdmVyeUdyb3VwTnVtYmVycyBpbml0aWF0aW5nIDogXCIsIEpTT04uc3RyaW5naWZ5KHByb2R1Y3RzKSk7XHJcblxyXG4gICAgbGV0IHVuaXF1ZUFuZHNvcnRlZFJlc3VsdDogbnVtYmVyW10gPSBbXTtcclxuXHJcbiAgICBpZiAocHJvZHVjdHMubGVuZ3RoID4gMCkge1xyXG4gICAgICBsZXQgZGVsaXZlcnlHcm91cEFyciA9IHByb2R1Y3RzLm1hcCgocHJvZHVjdCkgPT4ge1xyXG4gICAgICAgIGlmIChwcm9kdWN0LmRlbGl2ZXJ5R3JvdXApIHtcclxuICAgICAgICAgIHJldHVybiBwYXJzZUludChwcm9kdWN0LmRlbGl2ZXJ5R3JvdXApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChwcm9kdWN0LmRlbGl2ZXJ5TWV0aG9kID09PSBcIjFcIikge1xyXG4gICAgICAgICAgcmV0dXJuIDE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiAwO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHVuaXF1ZUFuZHNvcnRlZFJlc3VsdCA9IEFycmF5LmZyb20obmV3IFNldChkZWxpdmVyeUdyb3VwQXJyKSkuc29ydCgoYSwgYikgPT4gYSAtIGIpO1xyXG4gICAgICBjb25zb2xlLmxvZyhcImdldERlbGl2ZXJ5R3JvdXBOdW1iZXJzIDogXCIsIEpTT04uc3RyaW5naWZ5KHVuaXF1ZUFuZHNvcnRlZFJlc3VsdCkpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHVuaXF1ZUFuZHNvcnRlZFJlc3VsdDtcclxuICB9XHJcblxyXG4gIHVwZGF0ZVByb2R1Y3RzV2l0aE5ld0RlbGl2ZXJ5R3JvdXBOdW1iZXIocHJvZHVjdHM6IFByb2R1Y3RbXSkge1xyXG4gICAgY29uc29sZS5sb2coXCJ1cGRhdGVQcm9kdWN0c1dpdGhOZXdEZWxpdmVyeUdyb3VwTnVtYmVyIGluaXRpYXRpbmcgOiBcIiwgSlNPTi5zdHJpbmdpZnkocHJvZHVjdHMpKTtcclxuXHJcbiAgICBsZXQgbmV3R3JvdXBOdW1iZXIgPSB0aGlzLmdlbmVyYXRlTmV3RGVsaXZlcnlHcm91cE51bWJlcih0aGlzLmN1cnJlbnRCYXNrZXQucHJvZHVjdHMpO1xyXG4gICAgaWYgKHByb2R1Y3RzLmxlbmd0aCA+IDApIHtcclxuICAgICAgdGhpcy5jdXJyZW50QmFza2V0LnByb2R1Y3RzLmZvckVhY2goY0JQcm9kdWN0cyA9PiB7XHJcbiAgICAgICAgcHJvZHVjdHMuZm9yRWFjaChlbGVtZW50ID0+IHtcclxuICAgICAgICAgIGlmIChjQlByb2R1Y3RzLml0ZW1MaW5lSWQgPT09IGVsZW1lbnQuaXRlbUxpbmVJZCkge1xyXG4gICAgICAgICAgICBjQlByb2R1Y3RzLmRlbGl2ZXJ5R3JvdXAgPSBuZXdHcm91cE51bWJlcjtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnVwZGF0ZUJhc2tldCh0aGlzLmN1cnJlbnRCYXNrZXQpO1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgY2FsY3VsYXRlRXN0aW1hdGVkVGltZShwcm9kdWN0czogYW55W10pIHtcclxuICAgIHRyeSB7XHJcbiAgICAgIGxldCB0aW1lO1xyXG4gICAgICBsZXQgZXN0bWF0ZWRUaW1lOiBudW1iZXIgPSAwO1xyXG4gICAgICBsZXQgZXN0aW1hdGVkRGF5czogc3RyaW5nID0gXCJIb3Vyc1wiO1xyXG4gICAgICBwcm9kdWN0cy5mb3JFYWNoKChlbGVtZW50OiB7IGxlYWRUaW1lOiB7IHR5cGU6IHN0cmluZzsgdmFsdWU6IGFueTsgfTsgfSkgPT4ge1xyXG5cclxuICAgICAgICBpZiAoZWxlbWVudC5sZWFkVGltZS50eXBlLnRvTG9jYWxlTG93ZXJDYXNlKCkgPT09IFwid2Vla3NcIikge1xyXG4gICAgICAgICAgdGltZSA9IE51bWJlcihlbGVtZW50LmxlYWRUaW1lLnZhbHVlKSAqIDI0ICogNztcclxuICAgICAgICAgIGVzdG1hdGVkVGltZSA9IE1hdGgubWF4KGVzdG1hdGVkVGltZSwgdGltZSk7XHJcbiAgICAgICAgICBlc3RpbWF0ZWREYXlzID0gKGVzdG1hdGVkVGltZSA9PT0gdGltZSkgPyBlbGVtZW50LmxlYWRUaW1lLnR5cGUgOiBlc3RpbWF0ZWREYXlzXHJcbiAgICAgICAgICBjb25zb2xlLmxvZyhcIndlZWtcIiwgZXN0bWF0ZWRUaW1lLCBlc3RpbWF0ZWREYXlzKTtcclxuXHJcbiAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50LmxlYWRUaW1lLnR5cGUudG9Mb2NhbGVMb3dlckNhc2UoKSA9PT0gXCJkYXlzXCIpIHtcclxuICAgICAgICAgIHRpbWUgPSBOdW1iZXIoZWxlbWVudC5sZWFkVGltZS52YWx1ZSkgKiAyNDtcclxuICAgICAgICAgIGVzdG1hdGVkVGltZSA9IE1hdGgubWF4KGVzdG1hdGVkVGltZSwgdGltZSk7XHJcbiAgICAgICAgICBlc3RpbWF0ZWREYXlzID0gKGVzdG1hdGVkVGltZSA9PT0gdGltZSkgPyBlbGVtZW50LmxlYWRUaW1lLnR5cGUgOiBlc3RpbWF0ZWREYXlzXHJcblxyXG4gICAgICAgICAgY29uc29sZS5sb2coXCJkYXlzXCIsIGVzdG1hdGVkVGltZSwgZXN0aW1hdGVkRGF5cyk7XHJcblxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChlbGVtZW50LmxlYWRUaW1lLnR5cGUudG9Mb2NhbGVMb3dlckNhc2UoKSA9PT0gXCJtb250aHNcIikge1xyXG4gICAgICAgICAgdGltZSA9IE51bWJlcihlbGVtZW50LmxlYWRUaW1lLnZhbHVlKSAqIDI0ICogMzA7XHJcbiAgICAgICAgICBlc3RtYXRlZFRpbWUgPSBNYXRoLm1heChlc3RtYXRlZFRpbWUsIHRpbWUpO1xyXG4gICAgICAgICAgZXN0aW1hdGVkRGF5cyA9IChlc3RtYXRlZFRpbWUgPT09IHRpbWUpID8gZWxlbWVudC5sZWFkVGltZS50eXBlIDogZXN0aW1hdGVkRGF5c1xyXG5cclxuICAgICAgICAgIGNvbnNvbGUubG9nKFwibW9udGhzXCIsIGVzdG1hdGVkVGltZSwgZXN0aW1hdGVkRGF5cyk7XHJcblxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChlbGVtZW50LmxlYWRUaW1lLnR5cGUudG9Mb2NhbGVMb3dlckNhc2UoKSA9PT0gXCJ5ZWFyc1wiKSB7XHJcbiAgICAgICAgICB0aW1lID0gTnVtYmVyKGVsZW1lbnQubGVhZFRpbWUudmFsdWUpICogMjQgKiAzNjU7XHJcbiAgICAgICAgICBlc3RtYXRlZFRpbWUgPSBNYXRoLm1heChlc3RtYXRlZFRpbWUsIHRpbWUpO1xyXG4gICAgICAgICAgZXN0aW1hdGVkRGF5cyA9IChlc3RtYXRlZFRpbWUgPT09IHRpbWUpID8gZWxlbWVudC5sZWFkVGltZS50eXBlIDogZXN0aW1hdGVkRGF5c1xyXG5cclxuICAgICAgICAgIGNvbnNvbGUubG9nKFwieWVhcnNcIiwgZXN0bWF0ZWRUaW1lLCBlc3RpbWF0ZWREYXlzKTtcclxuXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRpbWUgPSBOdW1iZXIoZWxlbWVudC5sZWFkVGltZS52YWx1ZSk7XHJcbiAgICAgICAgICBlc3RtYXRlZFRpbWUgPSBNYXRoLm1heChlc3RtYXRlZFRpbWUsIHRpbWUpO1xyXG4gICAgICAgICAgZXN0aW1hdGVkRGF5cyA9IChlc3RtYXRlZFRpbWUgPT09IHRpbWUpID8gZWxlbWVudC5sZWFkVGltZS50eXBlIDogZXN0aW1hdGVkRGF5cztcclxuICAgICAgICAgIGNvbnNvbGUubG9nKFwiaG91cnNcIiwgZXN0bWF0ZWRUaW1lLCBlc3RpbWF0ZWREYXlzKTtcclxuXHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGlmIChlc3RpbWF0ZWREYXlzLnRvTG9jYWxlTG93ZXJDYXNlKCkgPT09IFwiZGF5c1wiKSB7XHJcbiAgICAgICAgZXN0bWF0ZWRUaW1lID0gZXN0bWF0ZWRUaW1lIC8gMjQ7XHJcbiAgICAgIH0gZWxzZSBpZiAoZXN0aW1hdGVkRGF5cy50b0xvY2FsZUxvd2VyQ2FzZSgpID09PSBcIndlZWtzXCIpIHtcclxuICAgICAgICBlc3RtYXRlZFRpbWUgPSBlc3RtYXRlZFRpbWUgLyAoMjQgKiA3KTtcclxuICAgICAgfSBlbHNlIGlmIChlc3RpbWF0ZWREYXlzLnRvTG9jYWxlTG93ZXJDYXNlKCkgPT09IFwibW9udGhzXCIpIHtcclxuICAgICAgICBlc3RtYXRlZFRpbWUgPSBlc3RtYXRlZFRpbWUgLyAoMjQgKiAzMCk7XHJcbiAgICAgIH0gZWxzZSBpZiAoZXN0aW1hdGVkRGF5cy50b0xvY2FsZUxvd2VyQ2FzZSgpID09PSBcInllYXJzXCIpIHtcclxuICAgICAgICBlc3RtYXRlZFRpbWUgPSBlc3RtYXRlZFRpbWUgLyAoMjQgKiAzNjUpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBsZXQgZXN0aW1hdGUgPSB7XHJcbiAgICAgICAgdmFsdWU6IGVzdG1hdGVkVGltZS50b1N0cmluZygpLFxyXG4gICAgICAgIHR5cGU6IGVzdGltYXRlZERheXNcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gZXN0aW1hdGU7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zb2xlLmxvZyhcImVycm9yIGluIGNhbGN1bGF0ZUVzdGltYXRlZFRpbWVcIiwgZXJyb3IpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIDA7XHJcbiAgfVxyXG5cclxuICB1cGRhdGVQcm9kdWN0c1dpdGhEZWxpdmVyeUdyb3VwTnVtYmVyKG9sZEdyb3VwOiBzdHJpbmcsIG5ld0dyb3VwOiBzdHJpbmcpIHtcclxuICAgIGNvbnNvbGUubG9nKFwidXBkYXRlUHJvZHVjdHNXaXRoRGVsaXZlcnlHcm91cE51bWJlciBpbml0aWF0aW5nXCIpO1xyXG5cclxuICAgIHRoaXMuY3VycmVudEJhc2tldC5wcm9kdWN0cy5mb3JFYWNoKGNCUHJvZHVjdHMgPT4ge1xyXG4gICAgICBpZiAoY0JQcm9kdWN0cy5kZWxpdmVyeUdyb3VwID09PSBvbGRHcm91cCkge1xyXG4gICAgICAgIGNCUHJvZHVjdHMuZGVsaXZlcnlHcm91cCA9IG5ld0dyb3VwO1xyXG4gICAgICB9XHJcblxyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy51cGRhdGVCYXNrZXQodGhpcy5jdXJyZW50QmFza2V0KTtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIGdldERlbGl2ZXJ5SW5mbygpOiBhbnkge1xyXG4gICAgY29uc29sZS5sb2coXCJnZXREZWxpdmVyeUdyb3VwSW5mb3IgaW5pdGlhdGluZ1wiKTtcclxuICAgIHRyeSB7XHJcbiAgICAgIGxldCBncm91cEluZm86IERlbGl2ZXJ5SW5mbyA9IHtcclxuICAgICAgICBncm91cHM6IFtdXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMuZ2V0RGVsaXZlcnlHcm91cE51bWJlcnModGhpcy5jdXJyZW50QmFza2V0LnByb2R1Y3RzKS5mb3JFYWNoKChncm91cE51bWJlcikgPT4ge1xyXG4gICAgICAgIGxldCBncm91cDogYW55ID0ge1xyXG4gICAgICAgICAgZ3JvdXBOdW1iZXI6IGdyb3VwTnVtYmVyLFxyXG4gICAgICAgICAgaXRlbXM6IFtdLFxyXG4gICAgICAgICAgZXN0aW1hdGU6IHtcclxuICAgICAgICAgICAgdHlwZTogXCJIb3Vyc1wiLFxyXG4gICAgICAgICAgICB2YWx1ZTogXCIwXCJcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5jdXJyZW50QmFza2V0LnByb2R1Y3RzLmZvckVhY2goY0JQcm9kdWN0cyA9PiB7XHJcbiAgICAgICAgICBpZiAoY0JQcm9kdWN0cy5kZWxpdmVyeUdyb3VwID09PSBncm91cE51bWJlci50b1N0cmluZygpKSB7XHJcbiAgICAgICAgICAgIGdyb3VwLml0ZW1zLnB1c2goY0JQcm9kdWN0cyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGdyb3VwLmVzdGltYXRlID0gdGhpcy5jYWxjdWxhdGVFc3RpbWF0ZWRUaW1lKGdyb3VwLml0ZW1zKTtcclxuXHJcbiAgICAgICAgZ3JvdXBJbmZvLmdyb3Vwcy5wdXNoKGdyb3VwKTtcclxuXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgcmV0dXJuIGdyb3VwSW5mbztcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zb2xlLmxvZyhcImVycm9yXCIsIGVycm9yKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIl19