@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.
- package/README.md +2 -2
- package/bundles/pmcretail-mapper-library.umd.js +6133 -0
- package/bundles/pmcretail-mapper-library.umd.js.map +1 -0
- package/bundles/pmcretail-mapper-library.umd.min.js +16 -0
- package/bundles/pmcretail-mapper-library.umd.min.js.map +1 -0
- package/esm2015/lib/RJ-mapper.class.js +1061 -0
- package/esm2015/lib/TransactionDocumentBuilder.js +1535 -0
- package/esm2015/lib/basket.service.js +851 -0
- package/esm2015/lib/mapper-library.component.js +27 -0
- package/esm2015/lib/mapper-library.model.js +974 -0
- package/esm2015/lib/mapper-library.module.js +21 -0
- package/esm2015/lib/number-util.service.js +77 -0
- package/esm2015/pmcretail-mapper-library.js +10 -0
- package/esm2015/public-api.js +12 -0
- package/esm5/lib/RJ-mapper.class.js +1262 -0
- package/esm5/lib/TransactionDocumentBuilder.js +2469 -0
- package/esm5/lib/basket.service.js +1076 -0
- package/esm5/lib/mapper-library.component.js +29 -0
- package/esm5/lib/mapper-library.model.js +974 -0
- package/esm5/lib/mapper-library.module.js +25 -0
- package/esm5/lib/number-util.service.js +94 -0
- package/esm5/pmcretail-mapper-library.js +10 -0
- package/esm5/public-api.js +12 -0
- package/{fesm2020/pmcretail-mapper-library.mjs → fesm2015/pmcretail-mapper-library.js} +2627 -602
- package/fesm2015/pmcretail-mapper-library.js.map +1 -0
- package/fesm5/pmcretail-mapper-library.js +5919 -0
- package/fesm5/pmcretail-mapper-library.js.map +1 -0
- package/lib/TransactionDocumentBuilder.d.ts +1 -1
- package/lib/basket.service.d.ts +1 -5
- package/lib/mapper-library.component.d.ts +0 -3
- package/lib/mapper-library.module.d.ts +0 -5
- package/lib/number-util.service.d.ts +2 -4
- package/package.json +16 -26
- package/pmcretail-mapper-library.d.ts +1 -1
- package/pmcretail-mapper-library.metadata.json +1 -0
- package/public-api.d.ts +0 -1
- package/esm2020/lib/RJ-mapper.class.mjs +0 -597
- package/esm2020/lib/TransactionDocumentBuilder.mjs +0 -1240
- package/esm2020/lib/basket.service.mjs +0 -527
- package/esm2020/lib/mapper-library.component.mjs +0 -26
- package/esm2020/lib/mapper-library.model.mjs +0 -20
- package/esm2020/lib/mapper-library.module.mjs +0 -21
- package/esm2020/lib/mapper-library.service.mjs +0 -56
- package/esm2020/lib/number-util.service.mjs +0 -41
- package/esm2020/pmcretail-mapper-library.mjs +0 -5
- package/esm2020/public-api.mjs +0 -8
- package/fesm2015/pmcretail-mapper-library.mjs +0 -2526
- package/fesm2015/pmcretail-mapper-library.mjs.map +0 -1
- package/fesm2020/pmcretail-mapper-library.mjs.map +0 -1
- package/lib/mapper-library.service.d.ts +0 -9
|
@@ -0,0 +1,1535 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview added by tsickle
|
|
3
|
+
* Generated from: lib/TransactionDocumentBuilder.ts
|
|
4
|
+
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
5
|
+
*/
|
|
6
|
+
import { DELIVERY_METHODS } from "./mapper-library.model";
|
|
7
|
+
import { TRANSACTION_TYPE } from "./mapper-library.model";
|
|
8
|
+
import { BasketService } from "./basket.service";
|
|
9
|
+
import { NumberUtilService } from "./number-util.service";
|
|
10
|
+
/**
|
|
11
|
+
* Transaction document builder
|
|
12
|
+
*/
|
|
13
|
+
export class TransactionDocumentBuilder {
|
|
14
|
+
/**
|
|
15
|
+
* @param {?=} transactionDoc
|
|
16
|
+
* @param {?=} currencyPipe
|
|
17
|
+
* @param {?=} basketService
|
|
18
|
+
*/
|
|
19
|
+
constructor(transactionDoc, currencyPipe, basketService) {
|
|
20
|
+
this.currencyPipe = currencyPipe;
|
|
21
|
+
this.basketService = basketService;
|
|
22
|
+
this.numberUtilService = new NumberUtilService(currencyPipe);
|
|
23
|
+
this.basketService = new BasketService(this.numberUtilService);
|
|
24
|
+
this.storeInfo = JSON.parse(localStorage.getItem('storeInfo') || '{}');
|
|
25
|
+
if (transactionDoc) {
|
|
26
|
+
this.transactionDocument = transactionDoc;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
this.transactionDocument = {
|
|
30
|
+
transactionId: "",
|
|
31
|
+
offlineTransactionId: "",
|
|
32
|
+
transactionRef: "",
|
|
33
|
+
dateTime: "",
|
|
34
|
+
orgCode: "",
|
|
35
|
+
storeId: "",
|
|
36
|
+
storeNodeId: "",
|
|
37
|
+
storeNodeStructure: "",
|
|
38
|
+
deviceId: "",
|
|
39
|
+
terminalId: "",
|
|
40
|
+
userId: "",
|
|
41
|
+
initiatingModule: "eBasket",
|
|
42
|
+
export: false,
|
|
43
|
+
basket: (/** @type {?} */ ({})),
|
|
44
|
+
basketSummary: (/** @type {?} */ ({})),
|
|
45
|
+
baseCurrency: "",
|
|
46
|
+
type: "",
|
|
47
|
+
operationStatus: "",
|
|
48
|
+
createdAt: "",
|
|
49
|
+
updatedAt: "",
|
|
50
|
+
id: "",
|
|
51
|
+
currentTransactionDetails: (/** @type {?} */ ({})),
|
|
52
|
+
saleTotal: 0,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Transactions ref
|
|
58
|
+
* @return {?} ref
|
|
59
|
+
*/
|
|
60
|
+
transactionRef() {
|
|
61
|
+
/** @type {?} */
|
|
62
|
+
const storeDetails = JSON.parse(localStorage.getItem('storeInfo') || '{}');
|
|
63
|
+
/** @type {?} */
|
|
64
|
+
const date = new Date();
|
|
65
|
+
/** @type {?} */
|
|
66
|
+
const random = (((1 + Math.random()) * 0x10000) | 0)
|
|
67
|
+
.toString(16)
|
|
68
|
+
.substring(1);
|
|
69
|
+
this.transactionDocument.transactionRef =
|
|
70
|
+
storeDetails.orgCode + storeDetails.storeId + date.toISOString() + random;
|
|
71
|
+
console.log("ebasket: transaction ref created", this.transactionDocument.transactionRef);
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Transactions id
|
|
76
|
+
* @param {?} transactionID
|
|
77
|
+
* @param {?=} isOnline
|
|
78
|
+
* @return {?} id
|
|
79
|
+
*/
|
|
80
|
+
transactionId(transactionID, isOnline = true) {
|
|
81
|
+
if (isOnline) {
|
|
82
|
+
this.transactionDocument.transactionId = transactionID;
|
|
83
|
+
}
|
|
84
|
+
return this;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Transactions id
|
|
88
|
+
* @param {?} transactionID
|
|
89
|
+
* @param {?} isOnline
|
|
90
|
+
* @return {?} id
|
|
91
|
+
*/
|
|
92
|
+
offlineTransactionId(transactionID, isOnline) {
|
|
93
|
+
if (!isOnline) {
|
|
94
|
+
this.transactionDocument.offlineTransactionId = transactionID;
|
|
95
|
+
}
|
|
96
|
+
return this;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* storeNode Id
|
|
100
|
+
* @param {?} storeNodeId
|
|
101
|
+
* @return {?} id
|
|
102
|
+
*/
|
|
103
|
+
storeNodeId(storeNodeId) {
|
|
104
|
+
this.transactionDocument.storeNodeId = storeNodeId;
|
|
105
|
+
return this;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* storeNode structure
|
|
109
|
+
* @param {?} storeNodeStructure
|
|
110
|
+
* @return {?} id
|
|
111
|
+
*/
|
|
112
|
+
storeNodeStructure(storeNodeStructure) {
|
|
113
|
+
this.transactionDocument.storeNodeStructure = storeNodeStructure;
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Orgs code
|
|
118
|
+
* @param {?} orgCode
|
|
119
|
+
* @return {?} code
|
|
120
|
+
*/
|
|
121
|
+
orgCode(orgCode) {
|
|
122
|
+
this.transactionDocument.orgCode = orgCode;
|
|
123
|
+
return this;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Stores id
|
|
127
|
+
* @param {?} storeId
|
|
128
|
+
* @return {?} id
|
|
129
|
+
*/
|
|
130
|
+
storeId(storeId) {
|
|
131
|
+
this.transactionDocument.storeId = storeId;
|
|
132
|
+
return this;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Dates time
|
|
136
|
+
* @return {?} time
|
|
137
|
+
*/
|
|
138
|
+
dateTime() {
|
|
139
|
+
/** @type {?} */
|
|
140
|
+
const date = new Date();
|
|
141
|
+
this.transactionDocument.dateTime = date.toISOString();
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Devices id
|
|
146
|
+
* @param {?} deviceId
|
|
147
|
+
* @return {?} id
|
|
148
|
+
*/
|
|
149
|
+
deviceId(deviceId) {
|
|
150
|
+
this.transactionDocument.deviceId = deviceId;
|
|
151
|
+
return this;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* terminal id
|
|
155
|
+
* @param {?} terminalId
|
|
156
|
+
* @return {?} id
|
|
157
|
+
*/
|
|
158
|
+
terminalId(terminalId) {
|
|
159
|
+
this.transactionDocument.terminalId = terminalId;
|
|
160
|
+
return this;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* saleExport
|
|
164
|
+
* @param {?} saleExport
|
|
165
|
+
* @return {?} id
|
|
166
|
+
*/
|
|
167
|
+
export(saleExport) {
|
|
168
|
+
this.transactionDocument.export = saleExport;
|
|
169
|
+
return this;
|
|
170
|
+
}
|
|
171
|
+
/* customer(): TransactionDocumentBuilder {
|
|
172
|
+
const user = JSON.parse(localStorage.getItem('userDetails'));
|
|
173
|
+
this.transactionDocument.customer = user;
|
|
174
|
+
return this;
|
|
175
|
+
} */
|
|
176
|
+
/**
|
|
177
|
+
* Baskets transaction document builder
|
|
178
|
+
* @param {?} basketDetails
|
|
179
|
+
* @return {?} basket
|
|
180
|
+
*/
|
|
181
|
+
basket(basketDetails) {
|
|
182
|
+
console.log("ebasket: basket details update in transaction document", JSON.stringify(basketDetails));
|
|
183
|
+
this.transactionDocument.subsidiaryId = basketDetails.subsidiaryId || (localStorage.getItem('subsidiaryId') || '');
|
|
184
|
+
this.transactionDocument.basket.products = (/** @type {?} */ ([]));
|
|
185
|
+
this.transactionDocument.basket.lineDiscount = [];
|
|
186
|
+
this.transactionDocument.basket.linePromotion = [];
|
|
187
|
+
this.transactionDocument.basket.transactionPromotion = [];
|
|
188
|
+
basketDetails.products.forEach((/**
|
|
189
|
+
* @param {?} product
|
|
190
|
+
* @param {?} index
|
|
191
|
+
* @return {?}
|
|
192
|
+
*/
|
|
193
|
+
(product, index) => {
|
|
194
|
+
/** @type {?} */
|
|
195
|
+
const p = (/** @type {?} */ ({}));
|
|
196
|
+
p.itemDiscounts = (/** @type {?} */ ({}));
|
|
197
|
+
p.SKU = product.SKU;
|
|
198
|
+
p.excludePromotion = product.excludePromotion;
|
|
199
|
+
p.barCode = product.barcode;
|
|
200
|
+
p.barcodes = product.barcodes;
|
|
201
|
+
p.description = product.description;
|
|
202
|
+
p.itemLineId = product.itemLineId ? product.itemLineId.toString() : "" + (index + 1);
|
|
203
|
+
p.price = product.selectedPrice;
|
|
204
|
+
p.quantity = product.quantity;
|
|
205
|
+
p.totalLinePrice = product.quantity * product.selectedPrice;
|
|
206
|
+
p.imageUrls = product.imageUrls;
|
|
207
|
+
p.selectedRRPPrice = product.selectedRRPPrice;
|
|
208
|
+
//inventory fields
|
|
209
|
+
p.fullfilmentId = product.fullfilmentId ? product.fullfilmentId : this.storeInfo.storeId;
|
|
210
|
+
p.fullfilmentLocationName = product.fullfilmentLocationName;
|
|
211
|
+
p.deliveryGroup = product.deliveryGroup;
|
|
212
|
+
p.leadTime = product.leadTime;
|
|
213
|
+
p.deliveryMethod = product.deliveryMethod;
|
|
214
|
+
p.giftCard = product.giftCard;
|
|
215
|
+
p.giftCardExpiryDate = product.giftCardExpiryDate;
|
|
216
|
+
p.giftCardNumberIssued = product.giftCardNumberIssued;
|
|
217
|
+
p.giftCardRecipientEmail = product.giftCardRecipientEmail;
|
|
218
|
+
p.giftCardRecipientName = product.giftCardRecipientName;
|
|
219
|
+
if (product.refundedQuantity > 0) {
|
|
220
|
+
p.refundedQuantity = product.refundedQuantity;
|
|
221
|
+
p.refundedPromotionalQuantity = product.refundPromotionalQuantity;
|
|
222
|
+
p.refunded = product.refunded;
|
|
223
|
+
p.refundedReasonDescription = product.refundedReasonDescription;
|
|
224
|
+
p.refundedReason = product.refundedReason;
|
|
225
|
+
if (!p.refundedReasonDescription) {
|
|
226
|
+
p.refundedReasonDescription = p.refundedReason;
|
|
227
|
+
}
|
|
228
|
+
p.refundedTotal = product.refundedTotal;
|
|
229
|
+
p.isLastExchanged = product.isLastExchanged;
|
|
230
|
+
}
|
|
231
|
+
if (product.exchange) {
|
|
232
|
+
p.exchange = product.exchange;
|
|
233
|
+
}
|
|
234
|
+
if (product.lineDiscount) {
|
|
235
|
+
p.lineDiscount = product.lineDiscount;
|
|
236
|
+
}
|
|
237
|
+
p.itemDiscounts = (/** @type {?} */ (product.itemDiscounts));
|
|
238
|
+
this.transactionDocument.basket.products.push(p);
|
|
239
|
+
this.lineDiscount(basketDetails);
|
|
240
|
+
}));
|
|
241
|
+
console.info("ebasket: transactiondocument basket details updated", JSON.stringify(this.transactionDocument.basket));
|
|
242
|
+
return this;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* current transaction Details Total(New Products)
|
|
246
|
+
* @param {?} basket
|
|
247
|
+
* @return {?} currentTransactionDetails
|
|
248
|
+
*/
|
|
249
|
+
currentTransactionDetails(basket) {
|
|
250
|
+
console.log("ebasket: current transaction details for exchanges", basket);
|
|
251
|
+
this.transactionDocument.currentTransactionDetails.products = (/** @type {?} */ ([]));
|
|
252
|
+
this.transactionDocument.currentTransactionDetails.linePromotion = (/** @type {?} */ ([]));
|
|
253
|
+
this.transactionDocument.currentTransactionDetails.lineDiscount = (/** @type {?} */ ([]));
|
|
254
|
+
this.transactionDocument.currentTransactionDetails.transactionDiscount = [];
|
|
255
|
+
this.transactionDocument.currentTransactionDetails.products = basket.products;
|
|
256
|
+
this.transactionDocument.currentTransactionDetails.products = this.transactionDocument.currentTransactionDetails.products.filter((/**
|
|
257
|
+
* @param {?} proj
|
|
258
|
+
* @return {?}
|
|
259
|
+
*/
|
|
260
|
+
(proj) => proj.refundedQuantity != 0));
|
|
261
|
+
this.transactionDocument.currentTransactionDetails.products.forEach((/**
|
|
262
|
+
* @param {?} product
|
|
263
|
+
* @return {?}
|
|
264
|
+
*/
|
|
265
|
+
(product) => {
|
|
266
|
+
if (product.refundedQuantity) {
|
|
267
|
+
product.quantity = product.refundedQuantity;
|
|
268
|
+
// updating total line price with actual price to be refunded including the refunding qty
|
|
269
|
+
product.totalLinePrice = Math.abs(product.refundedTotal);
|
|
270
|
+
product.total = product.totalLinePrice;
|
|
271
|
+
if (product.quantity === product.refundedQuantity) {
|
|
272
|
+
product.refunded = true;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
//Updating line promotions and line discounts
|
|
276
|
+
if (product.linePromotions && !product.refundedQuantity) {
|
|
277
|
+
this.transactionDocument.currentTransactionDetails.linePromotion.push(product.linePromotions);
|
|
278
|
+
}
|
|
279
|
+
if (product.lineDiscount && !product.refundedQuantity) {
|
|
280
|
+
this.transactionDocument.currentTransactionDetails.lineDiscount.push(product.lineDiscount);
|
|
281
|
+
}
|
|
282
|
+
}));
|
|
283
|
+
console.log("ebasket: current transaction details after removing old products", this.transactionDocument.currentTransactionDetails.products);
|
|
284
|
+
if (basket.transactionDiscount && basket.transactionDiscount.length > 0) {
|
|
285
|
+
this.transactionDocument.currentTransactionDetails.transactionDiscount.push(...basket.transactionDiscount);
|
|
286
|
+
}
|
|
287
|
+
this.transactionDocument.currentTransactionDetails.basketSummary = (/** @type {?} */ ({}));
|
|
288
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.saleTotal = this.numberUtilService.trimTo2Decimal2(this.updateSaleTotal(this.transactionDocument.currentTransactionDetails));
|
|
289
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.totalItems = basket.quantity;
|
|
290
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.basketTotal = basket.basketTotal;
|
|
291
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.refundTotal = this.updateCurrentTransactionDetailsRefundTotal();
|
|
292
|
+
// For partial refund discount is updatied in total line price so discountTotal will always be zero & in case of exchange discount total is calculated
|
|
293
|
+
if (this.transactionDocument.type === TRANSACTION_TYPE.SALE_EXCHANGE) {
|
|
294
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.discountTotal = this.numberUtilService.trimTo2Decimal2(this.updateCurrentTransactionDetailsDiscountTotal());
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
if (this.transactionDocument.currentTransactionDetails.transactionDiscount && this.transactionDocument.currentTransactionDetails.transactionDiscount.length > 0) {
|
|
298
|
+
/** @type {?} */
|
|
299
|
+
let discountTotal = 0;
|
|
300
|
+
this.transactionDocument.currentTransactionDetails.transactionDiscount.forEach((/**
|
|
301
|
+
* @param {?} discount
|
|
302
|
+
* @return {?}
|
|
303
|
+
*/
|
|
304
|
+
(discount) => {
|
|
305
|
+
discountTotal += discount.discountAmount;
|
|
306
|
+
}));
|
|
307
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.discountTotal = Math.abs(discountTotal);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.discountTotal = 0;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
console.log("ebasket:this.transactionDocument.currentTransactionDetails", JSON.stringify(this.transactionDocument.currentTransactionDetails));
|
|
314
|
+
return this;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* current transaction Tax Total
|
|
318
|
+
* @param {?} basketDetails
|
|
319
|
+
* @return {?} Tax Total
|
|
320
|
+
*/
|
|
321
|
+
updateCurrentTransactionDetailsTaxBreakdown(basketDetails) {
|
|
322
|
+
/** @type {?} */
|
|
323
|
+
let transactionDiscountTotal = 0;
|
|
324
|
+
/** @type {?} */
|
|
325
|
+
let taxBreakdown = {
|
|
326
|
+
taxLines: [],
|
|
327
|
+
totalTaxableAmount: 0,
|
|
328
|
+
};
|
|
329
|
+
if (this.transactionDocument.currentTransactionDetails.transactionDiscount && this.transactionDocument.currentTransactionDetails.transactionDiscount.length > 0) {
|
|
330
|
+
this.transactionDocument.currentTransactionDetails.transactionDiscount.forEach((/**
|
|
331
|
+
* @param {?} discount
|
|
332
|
+
* @return {?}
|
|
333
|
+
*/
|
|
334
|
+
(discount) => {
|
|
335
|
+
transactionDiscountTotal += discount.discountAmount;
|
|
336
|
+
}));
|
|
337
|
+
}
|
|
338
|
+
if (this.transactionDocument.currentTransactionDetails.products && this.transactionDocument.currentTransactionDetails.products.length > 0) {
|
|
339
|
+
this.transactionDocument.currentTransactionDetails.products.forEach((/**
|
|
340
|
+
* @param {?} product
|
|
341
|
+
* @return {?}
|
|
342
|
+
*/
|
|
343
|
+
(product) => {
|
|
344
|
+
/** @type {?} */
|
|
345
|
+
let taxLine = {
|
|
346
|
+
itemLineId: product.itemLineId,
|
|
347
|
+
VAT: product.selectedVAT ? product.selectedVAT : 0,
|
|
348
|
+
VATCode: product.selectedVATCode,
|
|
349
|
+
taxLineTotal: 0,
|
|
350
|
+
taxableAmount: product.total,
|
|
351
|
+
PreTax: 0
|
|
352
|
+
};
|
|
353
|
+
console.info("Product contribution : item line ID :current transaction Details", product.itemLineId, "tax line :", JSON.stringify(taxLine), JSON.stringify(basketDetails.basketTotal));
|
|
354
|
+
//step 1
|
|
355
|
+
// if Transaction Discount and/or promotion applied, find net selling price of each product as taxableamount
|
|
356
|
+
//If transaction discount/promotion is applied taxable amount should be deducting transaction promotion and transaction disacount portion
|
|
357
|
+
if (product.refundedQuantity && product.refundedQuantity > 0) {
|
|
358
|
+
taxLine.taxableAmount = -Math.abs(taxLine.taxableAmount - product.itemDiscounts.currentRefundPortion);
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
taxLine.taxableAmount = taxLine.taxableAmount - product.itemDiscounts.trnDiscountsPortion - product.itemDiscounts.trnPromotionsPortion;
|
|
362
|
+
}
|
|
363
|
+
//step 2 - find pre tax
|
|
364
|
+
taxLine.PreTax = this.numberUtilService.trimTo2Decimal2((taxLine.taxableAmount * 100) / (100 + taxLine.VAT));
|
|
365
|
+
//step 3 - Update taxbreakdown
|
|
366
|
+
taxBreakdown.totalTaxableAmount += taxLine.taxableAmount;
|
|
367
|
+
taxLine.taxableAmount = this.numberUtilService.trimTo2Decimal2(taxLine.taxableAmount);
|
|
368
|
+
// step 4 - update tax Line total
|
|
369
|
+
taxLine.taxLineTotal = this.numberUtilService.trimTo2Decimal2(taxLine.taxableAmount - taxLine.PreTax);
|
|
370
|
+
taxBreakdown.taxLines.push(taxLine);
|
|
371
|
+
}));
|
|
372
|
+
}
|
|
373
|
+
taxBreakdown.totalTaxableAmount = this.numberUtilService.trimTo2Decimal2(taxBreakdown.totalTaxableAmount);
|
|
374
|
+
this.transactionDocument.currentTransactionDetails.taxBreakdown = taxBreakdown;
|
|
375
|
+
if (this.transactionDocument.currentTransactionDetails.taxBreakdown && this.transactionDocument.currentTransactionDetails.taxBreakdown.taxLines && this.transactionDocument.currentTransactionDetails.taxBreakdown.taxLines.length > 0) {
|
|
376
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.VATTotal = this.numberUtilService.trimTo2Decimal2(this.transactionDocument.currentTransactionDetails.taxBreakdown.taxLines.reduce((/**
|
|
377
|
+
* @param {?} n
|
|
378
|
+
* @param {?} __1
|
|
379
|
+
* @return {?}
|
|
380
|
+
*/
|
|
381
|
+
(n, { taxLineTotal }) => n + taxLineTotal), 0));
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.VATTotal = 0.00;
|
|
385
|
+
}
|
|
386
|
+
console.log("eBasket:after calculating tax currenttransactionDetails", this.transactionDocument.currentTransactionDetails);
|
|
387
|
+
return this;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* @return {?}
|
|
391
|
+
*/
|
|
392
|
+
updateCurrentTransactionDetailsTotalTaxSummary() {
|
|
393
|
+
console.log("Total Tax Summery Request :", JSON.stringify(this.transactionDocument.currentTransactionDetails.taxBreakdown));
|
|
394
|
+
/** @type {?} */
|
|
395
|
+
let totalTaxSummaryArray = [];
|
|
396
|
+
/** @type {?} */
|
|
397
|
+
let totalTaxSummaryGroup = [];
|
|
398
|
+
console.log("Tax Lines for Total Tax Summery :", JSON.stringify(this.transactionDocument.currentTransactionDetails.taxBreakdown.taxLines));
|
|
399
|
+
this.transactionDocument.currentTransactionDetails.taxBreakdown.taxLines.forEach((/**
|
|
400
|
+
* @param {?} element
|
|
401
|
+
* @return {?}
|
|
402
|
+
*/
|
|
403
|
+
(element) => {
|
|
404
|
+
/** @type {?} */
|
|
405
|
+
let TaxSummary = {
|
|
406
|
+
VATCode: "",
|
|
407
|
+
VAT: -12345,
|
|
408
|
+
PreTaxSum: 0,
|
|
409
|
+
TaxSum: 0,
|
|
410
|
+
TXrateSum: 0
|
|
411
|
+
};
|
|
412
|
+
TaxSummary.VATCode = element.VATCode;
|
|
413
|
+
TaxSummary.VAT = element.VAT;
|
|
414
|
+
TaxSummary.PreTaxSum = this.numberUtilService.trimTo2Decimal2(element.PreTax);
|
|
415
|
+
TaxSummary.TaxSum = this.numberUtilService.trimTo2Decimal2(element.taxLineTotal);
|
|
416
|
+
TaxSummary.TXrateSum = this.numberUtilService.trimTo2Decimal2(TaxSummary.PreTaxSum + TaxSummary.TaxSum);
|
|
417
|
+
totalTaxSummaryArray.push(TaxSummary);
|
|
418
|
+
}));
|
|
419
|
+
console.log("Total Tax Summery Without Grouped : ", JSON.stringify(totalTaxSummaryArray));
|
|
420
|
+
totalTaxSummaryGroup = totalTaxSummaryArray.reduce((/**
|
|
421
|
+
* @param {?} preparedArray
|
|
422
|
+
* @param {?} currentObj
|
|
423
|
+
* @return {?}
|
|
424
|
+
*/
|
|
425
|
+
(preparedArray, currentObj) => {
|
|
426
|
+
/** @type {?} */
|
|
427
|
+
let ind = preparedArray.findIndex((/**
|
|
428
|
+
* @param {?} x
|
|
429
|
+
* @return {?}
|
|
430
|
+
*/
|
|
431
|
+
(x) => x.VAT === currentObj.VAT));
|
|
432
|
+
if (ind === -1) {
|
|
433
|
+
preparedArray.push(currentObj);
|
|
434
|
+
}
|
|
435
|
+
else {
|
|
436
|
+
preparedArray[ind].VATCode = currentObj.VATCode;
|
|
437
|
+
preparedArray[ind].VAT = currentObj.VAT;
|
|
438
|
+
preparedArray[ind].PreTaxSum += currentObj.PreTaxSum;
|
|
439
|
+
preparedArray[ind].TaxSum += currentObj.TaxSum;
|
|
440
|
+
preparedArray[ind].TXrateSum += currentObj.TXrateSum;
|
|
441
|
+
}
|
|
442
|
+
return preparedArray;
|
|
443
|
+
}), []);
|
|
444
|
+
// listOfTags.map(x => unique.filter(a => a.label == x.label && a.color == x.color).length > 0 ? null : unique.push(x));
|
|
445
|
+
console.log("Total Tax Summer Group :", JSON.stringify(totalTaxSummaryGroup));
|
|
446
|
+
this.transactionDocument.currentTransactionDetails.totalTaxSummary = totalTaxSummaryGroup;
|
|
447
|
+
return this;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* current transaction Disocunt Total
|
|
451
|
+
* @return {?} Discount Total
|
|
452
|
+
*/
|
|
453
|
+
updateCurrentTransactionDetailsDiscountTotal() {
|
|
454
|
+
/** @type {?} */
|
|
455
|
+
let refundTotal = this.transactionDocument.currentTransactionDetails.basketSummary.refundTotal ? this.transactionDocument.currentTransactionDetails.basketSummary.refundTotal : 0;
|
|
456
|
+
console.log("e-basket: transaction builder updateCurrentTransactionDetailsDiscountTotal: discountTotal", refundTotal, this.transactionDocument.currentTransactionDetails.basketSummary.basketTotal, this.transactionDocument.currentTransactionDetails.basketSummary.saleTotal);
|
|
457
|
+
/** @type {?} */
|
|
458
|
+
const discountTotal = Math.abs(Math.abs(this.transactionDocument.currentTransactionDetails.basketSummary.saleTotal) -
|
|
459
|
+
(Math.abs(this.transactionDocument.currentTransactionDetails.basketSummary.basketTotal) + Math.abs(refundTotal)));
|
|
460
|
+
console.log("e-basket: transaction builder updateCurrentTransactionDetailsDiscountTotal: discountTotal", discountTotal);
|
|
461
|
+
return Number(discountTotal.toFixed(2));
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* current transaction Refund Total
|
|
465
|
+
* @return {?} Refund Total
|
|
466
|
+
*/
|
|
467
|
+
updateCurrentTransactionDetailsRefundTotal() {
|
|
468
|
+
/** @type {?} */
|
|
469
|
+
let totalRefund = 0;
|
|
470
|
+
for (let index = 0; index < this.transactionDocument.currentTransactionDetails.products.length; index++) {
|
|
471
|
+
/** @type {?} */
|
|
472
|
+
const product = this.transactionDocument.currentTransactionDetails.products[index];
|
|
473
|
+
if (product.refundedTotal) {
|
|
474
|
+
totalRefund = totalRefund + product.refundedTotal;
|
|
475
|
+
}
|
|
476
|
+
console.log("ebasket : transaction Service: totalRefund for Current TransactionDetails" + totalRefund);
|
|
477
|
+
}
|
|
478
|
+
return totalRefund;
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Baskets summary
|
|
482
|
+
* @param {?} basketDetails
|
|
483
|
+
* @return {?} summary
|
|
484
|
+
*/
|
|
485
|
+
basketSummary(basketDetails) {
|
|
486
|
+
this.transactionDocument.basketSummary.basketTotal = this.numberUtilService.trimTo2Decimal(basketDetails.basketTotal);
|
|
487
|
+
this.transactionDocument.basketSummary.saleTotal = this.numberUtilService.trimTo2Decimal2(this.updateSaleTotal(basketDetails));
|
|
488
|
+
this.transactionDocument.basketSummary.refundTotal = this.getRefundTotal();
|
|
489
|
+
if (this.transactionDocument.basket.lineDiscount ||
|
|
490
|
+
this.transactionDocument.basket.linePromotion) {
|
|
491
|
+
this.transactionDocument.basketSummary.discountTotal = this.numberUtilService.trimTo2Decimal2(this.updateDiscountTotal());
|
|
492
|
+
}
|
|
493
|
+
this.transactionDocument.basketSummary.totalItems = basketDetails.quantity;
|
|
494
|
+
if (this.transactionDocument.basket.taxBreakdown) {
|
|
495
|
+
this.transactionDocument.basketSummary.VATTotal = this.numberUtilService.trimTo2Decimal2(this.transactionDocument.basket.taxBreakdown.taxLines.reduce((/**
|
|
496
|
+
* @param {?} n
|
|
497
|
+
* @param {?} __1
|
|
498
|
+
* @return {?}
|
|
499
|
+
*/
|
|
500
|
+
(n, { taxLineTotal }) => n + taxLineTotal), 0));
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
this.transactionDocument.basketSummary.VATTotal = 0.00;
|
|
504
|
+
}
|
|
505
|
+
console.info("ebasket: basketsummary updated in transaction document: ", JSON.stringify(this.transactionDocument.basketSummary));
|
|
506
|
+
return this;
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Line Discount
|
|
510
|
+
* @param {?} basketDetails
|
|
511
|
+
* @return {?} line Discount
|
|
512
|
+
*/
|
|
513
|
+
lineDiscount(basketDetails) {
|
|
514
|
+
this.transactionDocument.basket.lineDiscount = [];
|
|
515
|
+
for (let index = 0; index < basketDetails.products.length; index++) {
|
|
516
|
+
/** @type {?} */
|
|
517
|
+
const element = basketDetails.products[index];
|
|
518
|
+
if (element.lineDiscount) {
|
|
519
|
+
this.transactionDocument.basket.lineDiscount.push(element.lineDiscount);
|
|
520
|
+
this.transactionDocument.basket.lineDiscount = this.transactionDocument.basket.lineDiscount.reduce((/**
|
|
521
|
+
* @param {?} acc
|
|
522
|
+
* @param {?} val
|
|
523
|
+
* @return {?}
|
|
524
|
+
*/
|
|
525
|
+
(acc, val) => {
|
|
526
|
+
if (!acc.find((/**
|
|
527
|
+
* @param {?} el
|
|
528
|
+
* @return {?}
|
|
529
|
+
*/
|
|
530
|
+
(el) => el.itemLineId === val.itemLineId))) {
|
|
531
|
+
acc.push(val);
|
|
532
|
+
}
|
|
533
|
+
return acc;
|
|
534
|
+
}), []);
|
|
535
|
+
}
|
|
536
|
+
// console.info(
|
|
537
|
+
// "e-basket :line discount updated in transaction document",
|
|
538
|
+
// this.transactionDocument.basket.lineDiscount
|
|
539
|
+
// );
|
|
540
|
+
}
|
|
541
|
+
return this;
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* exchange
|
|
545
|
+
* @param {?} basketDetails
|
|
546
|
+
* @return {?} exchange
|
|
547
|
+
*/
|
|
548
|
+
exchange(basketDetails) {
|
|
549
|
+
this.transactionDocument.basket.exchange = basketDetails.exchange && basketDetails.exchange.length > 0 ? [...basketDetails.exchange] : [];
|
|
550
|
+
for (let index = 0; index < basketDetails.products.length; index++) {
|
|
551
|
+
/** @type {?} */
|
|
552
|
+
const element = basketDetails.products[index];
|
|
553
|
+
if (element.exchange != undefined) {
|
|
554
|
+
/** @type {?} */
|
|
555
|
+
const isPresent = this.transactionDocument.basket.exchange.some((/**
|
|
556
|
+
* @param {?} el
|
|
557
|
+
* @return {?}
|
|
558
|
+
*/
|
|
559
|
+
(el) => el.exchangeId === element.exchange.exchangeId));
|
|
560
|
+
if (!isPresent) {
|
|
561
|
+
/** @type {?} */
|
|
562
|
+
let exchangeItems = [];
|
|
563
|
+
for (let j = 0; j < element.exchange.newItems.length; j++) {
|
|
564
|
+
/** @type {?} */
|
|
565
|
+
const item = element.exchange.newItems[j];
|
|
566
|
+
/** @type {?} */
|
|
567
|
+
let newItems = { lineItemId: item.itemLineId, Quantity: item.quantity };
|
|
568
|
+
exchangeItems.push(newItems);
|
|
569
|
+
}
|
|
570
|
+
element.exchange.newItems = [...exchangeItems];
|
|
571
|
+
this.transactionDocument.basket.exchange.push(element.exchange);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
console.log("e-basket :TransactionDocumentBuilder: this.transactionDocument.basket exchange", JSON.stringify(this.transactionDocument.basket.exchange));
|
|
575
|
+
}
|
|
576
|
+
return this;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* add previous exchange data
|
|
580
|
+
* @param {?} originalTransactionDocument
|
|
581
|
+
* @return {?} line Promotions
|
|
582
|
+
*/
|
|
583
|
+
addExchangeData(originalTransactionDocument) {
|
|
584
|
+
this.transactionDocument.basket.exchange = originalTransactionDocument.basket.exchange ? [...originalTransactionDocument.basket.exchange] : null;
|
|
585
|
+
return this;
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* line Promotions
|
|
589
|
+
* @param {?} basketDetails
|
|
590
|
+
* @return {?} line Promotions
|
|
591
|
+
*/
|
|
592
|
+
linePromotion(basketDetails) {
|
|
593
|
+
this.transactionDocument.basket.linePromotion = [];
|
|
594
|
+
for (let index = 0; index < basketDetails.products.length; index++) {
|
|
595
|
+
/** @type {?} */
|
|
596
|
+
const element = basketDetails.products[index];
|
|
597
|
+
if (element.linePromotions) {
|
|
598
|
+
this.transactionDocument.basket.linePromotion.push(element.linePromotions);
|
|
599
|
+
this.transactionDocument.basket.linePromotion = this.transactionDocument.basket.linePromotion.reduce((/**
|
|
600
|
+
* @param {?} acc
|
|
601
|
+
* @param {?} val
|
|
602
|
+
* @return {?}
|
|
603
|
+
*/
|
|
604
|
+
(acc, val) => {
|
|
605
|
+
if (!acc.find((/**
|
|
606
|
+
* @param {?} el
|
|
607
|
+
* @return {?}
|
|
608
|
+
*/
|
|
609
|
+
(el) => el.itemLineId === val.itemLineId))) {
|
|
610
|
+
acc.push(val);
|
|
611
|
+
}
|
|
612
|
+
return acc;
|
|
613
|
+
}), []);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
return this;
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* transaction Promotion
|
|
620
|
+
* @param {?} basketDetails
|
|
621
|
+
* @return {?} transaction Promotion
|
|
622
|
+
*/
|
|
623
|
+
transactionPromotion(basketDetails) {
|
|
624
|
+
if (basketDetails.transactionPromotion) {
|
|
625
|
+
this.transactionDocument.basket.transactionPromotion =
|
|
626
|
+
basketDetails.transactionPromotion;
|
|
627
|
+
// for (let index = 0; index < basketDetails.TransactionDiscount.length; index++) {
|
|
628
|
+
// this.transactionDocument.basket.transactionPromotion.push(element.linePromotions)
|
|
629
|
+
// this.transactionDocument.basket.transactionPromotion = this.transactionDocument.basket.linePromotions.reduce((acc, val) => {
|
|
630
|
+
// if (!acc.find(el => el.itemLineId === val.itemLineId)) {
|
|
631
|
+
// acc.push(val);
|
|
632
|
+
// }
|
|
633
|
+
// return acc;
|
|
634
|
+
// }, []);
|
|
635
|
+
// }
|
|
636
|
+
console.log("e-basket :TransactionDocumentBuilder: this.transactionDocument.basket.transactionPromotion", JSON.stringify(this.transactionDocument.basket.transactionPromotion));
|
|
637
|
+
}
|
|
638
|
+
return this;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* @param {?} basketDetails
|
|
642
|
+
* @return {?}
|
|
643
|
+
*/
|
|
644
|
+
transactionDiscount(basketDetails) {
|
|
645
|
+
if (basketDetails.transactionDiscount) {
|
|
646
|
+
this.transactionDocument.basket.transactionDiscount =
|
|
647
|
+
basketDetails.transactionDiscount;
|
|
648
|
+
console.log("e-basket :TransactionDocumentBuilder: transaction Discount", JSON.stringify(this.transactionDocument.basket.transactionDiscount));
|
|
649
|
+
}
|
|
650
|
+
return this;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Payments details
|
|
654
|
+
* @template THIS
|
|
655
|
+
* @this {THIS}
|
|
656
|
+
* @param {?} paymentDetails
|
|
657
|
+
* @return {THIS}
|
|
658
|
+
*/
|
|
659
|
+
paymentDetails(paymentDetails) {
|
|
660
|
+
console.info("ebasket : payment details after transaction completed", JSON.stringify(paymentDetails));
|
|
661
|
+
(/** @type {?} */ (this)).transactionDocument.paymentDetails = paymentDetails;
|
|
662
|
+
return (/** @type {?} */ (this));
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Payments details
|
|
666
|
+
* @template THIS
|
|
667
|
+
* @this {THIS}
|
|
668
|
+
* @param {?} splitPayment
|
|
669
|
+
* @return {THIS}
|
|
670
|
+
*/
|
|
671
|
+
splitPayment(splitPayment) {
|
|
672
|
+
(/** @type {?} */ (this)).transactionDocument.splitPayment = splitPayment;
|
|
673
|
+
return (/** @type {?} */ (this));
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Payments details
|
|
677
|
+
* @template THIS
|
|
678
|
+
* @this {THIS}
|
|
679
|
+
* @param {?} isPaymentCompleted
|
|
680
|
+
* @return {THIS}
|
|
681
|
+
*/
|
|
682
|
+
isPaymentCompleted(isPaymentCompleted) {
|
|
683
|
+
(/** @type {?} */ (this)).transactionDocument.isPaymentCompleted = isPaymentCompleted;
|
|
684
|
+
return (/** @type {?} */ (this));
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Bases currency
|
|
688
|
+
* @param {?} currency
|
|
689
|
+
* @return {?} currency
|
|
690
|
+
*/
|
|
691
|
+
baseCurrency(currency) {
|
|
692
|
+
this.transactionDocument.baseCurrency = currency;
|
|
693
|
+
return this;
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* gift option at
|
|
697
|
+
* @param {?} gift
|
|
698
|
+
* @return {?} at
|
|
699
|
+
*/
|
|
700
|
+
giftOption(gift) {
|
|
701
|
+
console.log("e-basket :TransactionDocumentBuilder: this.transactionDocument.giftoption", gift);
|
|
702
|
+
if (gift) {
|
|
703
|
+
this.transactionDocument.giftedReceipt = gift;
|
|
704
|
+
}
|
|
705
|
+
return this;
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* manual Discount
|
|
711
|
+
* @param discountData
|
|
712
|
+
* @returns
|
|
713
|
+
*/
|
|
714
|
+
// manualDiscount(discountData : basketDiscount):TransactionDocumentBuilder {
|
|
715
|
+
// let saleTotal = this.transactionDocument.basketSummary.basketTotal;
|
|
716
|
+
// if(discountData.discountType =='Percent'){
|
|
717
|
+
// this.transactionDocument.basketSummary.basketTotal = saleTotal-(saleTotal*(discountData.discountAmount/100));
|
|
718
|
+
// discountData.discountAmount = -1*(saleTotal-this.transactionDocument.basketSummary.basketTotal);
|
|
719
|
+
// }else {
|
|
720
|
+
// this.transactionDocument.basketSummary.basketTotal =saleTotal-discountData.discountAmount;
|
|
721
|
+
// discountData.discountAmount = -1*discountData.discountAmount;
|
|
722
|
+
// }
|
|
723
|
+
// this.transactionDocument.transactionDiscount.push(discountData);
|
|
724
|
+
// return this;
|
|
725
|
+
// }
|
|
726
|
+
/**
|
|
727
|
+
* Types transaction document builder
|
|
728
|
+
* @param {?} t
|
|
729
|
+
* @return {?} type
|
|
730
|
+
*/
|
|
731
|
+
type(t) {
|
|
732
|
+
this.transactionDocument.type = t;
|
|
733
|
+
return this;
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* Operations status
|
|
737
|
+
* @param {?} o
|
|
738
|
+
* @return {?} status
|
|
739
|
+
*/
|
|
740
|
+
operationStatus(o) {
|
|
741
|
+
this.transactionDocument.operationStatus = o;
|
|
742
|
+
return this;
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Created at
|
|
746
|
+
* @return {?} at
|
|
747
|
+
*/
|
|
748
|
+
createdAt() {
|
|
749
|
+
/** @type {?} */
|
|
750
|
+
const date = new Date();
|
|
751
|
+
this.transactionDocument.createdAt = date.toISOString();
|
|
752
|
+
this.transactionDocument.updatedAt = date.toISOString();
|
|
753
|
+
return this;
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Updated at
|
|
757
|
+
* @return {?} at
|
|
758
|
+
*/
|
|
759
|
+
updatedAt() {
|
|
760
|
+
/** @type {?} */
|
|
761
|
+
const date = new Date();
|
|
762
|
+
this.transactionDocument.updatedAt = date.toISOString();
|
|
763
|
+
return this;
|
|
764
|
+
}
|
|
765
|
+
/**
|
|
766
|
+
* transsaction completion at
|
|
767
|
+
* @return {?} transaction completion date
|
|
768
|
+
*/
|
|
769
|
+
transactionCompletedAt() {
|
|
770
|
+
/** @type {?} */
|
|
771
|
+
const date = new Date();
|
|
772
|
+
this.transactionDocument.transCompletedAt = date.toISOString();
|
|
773
|
+
return this;
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Builds transaction document builder
|
|
777
|
+
* @return {?} build
|
|
778
|
+
*/
|
|
779
|
+
build() {
|
|
780
|
+
return this.transactionDocument;
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Sales total in refund
|
|
784
|
+
* @param {?} saleTotal
|
|
785
|
+
* @return {?} total in refund
|
|
786
|
+
*/
|
|
787
|
+
saleTotalInRefund(saleTotal) {
|
|
788
|
+
this.transactionDocument.saleTotal = saleTotal;
|
|
789
|
+
return this;
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* Gets basket details
|
|
793
|
+
* @return {?} basket details
|
|
794
|
+
*/
|
|
795
|
+
getBasketDetails() {
|
|
796
|
+
console.info("ebasket: Getting Basket for transactionDocument", JSON.stringify(this.transactionDocument));
|
|
797
|
+
/** @type {?} */
|
|
798
|
+
let basket = {
|
|
799
|
+
subsidiaryId: this.transactionDocument.subsidiaryId,
|
|
800
|
+
transactionDiscount: this.transactionDocument.basket.transactionDiscount,
|
|
801
|
+
transactionPromotion: this.transactionDocument.basket.transactionPromotion,
|
|
802
|
+
transactionId: this.transactionDocument.transactionId,
|
|
803
|
+
offlineTransactionId: this.transactionDocument.offlineTransactionId,
|
|
804
|
+
total: this.transactionDocument.basketSummary.basketTotal,
|
|
805
|
+
basketTotal: this.transactionDocument.basketSummary.basketTotal,
|
|
806
|
+
discountTotal: this.transactionDocument.basketSummary.discountTotal,
|
|
807
|
+
saleTotal: this.transactionDocument.basketSummary.saleTotal,
|
|
808
|
+
refundTotal: this.transactionDocument.basketSummary.refundTotal,
|
|
809
|
+
quantity: this.transactionDocument.basketSummary.totalItems,
|
|
810
|
+
products: [],
|
|
811
|
+
baseCurrency: this.transactionDocument.baseCurrency,
|
|
812
|
+
customer: this.transactionDocument.customer,
|
|
813
|
+
};
|
|
814
|
+
basket.products = (/** @type {?} */ ([]));
|
|
815
|
+
this.transactionDocument.basket.products.forEach((/**
|
|
816
|
+
* @param {?} product
|
|
817
|
+
* @param {?} index
|
|
818
|
+
* @return {?}
|
|
819
|
+
*/
|
|
820
|
+
(product, index) => {
|
|
821
|
+
console.log(JSON.stringify(product), "ebasket: basket detail update in basket");
|
|
822
|
+
/** @type {?} */
|
|
823
|
+
const p = (/** @type {?} */ ({}));
|
|
824
|
+
p.SKU = product.SKU;
|
|
825
|
+
p.barcode = product.barCode;
|
|
826
|
+
p.barcodes = product.barcodes;
|
|
827
|
+
p.description = product.description;
|
|
828
|
+
p.imageUrls = product.imageUrls;
|
|
829
|
+
p.currency = this.transactionDocument.baseCurrency;
|
|
830
|
+
p.totalLinePrice = product.totalLinePrice;
|
|
831
|
+
p.itemLineId = Number(product.itemLineId);
|
|
832
|
+
p.excludePromotion = product.excludePromotion;
|
|
833
|
+
p.selectedPrice = product.price;
|
|
834
|
+
p.quantity = product.quantity;
|
|
835
|
+
p.total = product.totalLinePrice;
|
|
836
|
+
p.selectedRRPPrice = product.selectedRRPPrice;
|
|
837
|
+
p.fullfilmentId = product.fullfilmentId;
|
|
838
|
+
p.fullfilmentLocationName = product.fullfilmentLocationName;
|
|
839
|
+
p.deliveryGroup = product.deliveryGroup || "1";
|
|
840
|
+
p.leadTime = product.leadTime;
|
|
841
|
+
p.deliveryMethod = product.deliveryMethod || DELIVERY_METHODS.COLLECT_FROM_STORE.toString();
|
|
842
|
+
if (p.fullfilmentId != this.transactionDocument.storeId) {
|
|
843
|
+
p.isWebOrder = true;
|
|
844
|
+
}
|
|
845
|
+
p.giftCard = product.giftCard;
|
|
846
|
+
p.giftCardExpiryDate = product.giftCardExpiryDate;
|
|
847
|
+
p.giftCardNumberIssued = product.giftCardNumberIssued;
|
|
848
|
+
p.giftCardRecipientEmail = product.giftCardRecipientEmail;
|
|
849
|
+
p.giftCardRecipientName = product.giftCardRecipientName;
|
|
850
|
+
if (this.transactionDocument.basket.lineDiscount &&
|
|
851
|
+
this.transactionDocument.basket.lineDiscount.length > 0) {
|
|
852
|
+
this.transactionDocument.basket.lineDiscount.forEach((/**
|
|
853
|
+
* @param {?} lineDiscount
|
|
854
|
+
* @return {?}
|
|
855
|
+
*/
|
|
856
|
+
(lineDiscount) => {
|
|
857
|
+
if (product.itemLineId === lineDiscount.itemLineId.toString()) {
|
|
858
|
+
p.lineDiscount = lineDiscount;
|
|
859
|
+
p.total = lineDiscount.discountedLinePrice;
|
|
860
|
+
}
|
|
861
|
+
}));
|
|
862
|
+
}
|
|
863
|
+
if (this.transactionDocument.basket.linePromotion &&
|
|
864
|
+
this.transactionDocument.basket.linePromotion.length > 0) {
|
|
865
|
+
this.transactionDocument.basket.linePromotion.forEach((/**
|
|
866
|
+
* @param {?} linePromotion
|
|
867
|
+
* @return {?}
|
|
868
|
+
*/
|
|
869
|
+
(linePromotion) => {
|
|
870
|
+
if (product.itemLineId === linePromotion.itemLineId.toString()) {
|
|
871
|
+
p.linePromotions = linePromotion;
|
|
872
|
+
p.total = linePromotion.promotionLinePrice;
|
|
873
|
+
}
|
|
874
|
+
}));
|
|
875
|
+
}
|
|
876
|
+
if (this.transactionDocument.basket.taxBreakdown &&
|
|
877
|
+
this.transactionDocument.basket.taxBreakdown.taxLines.length > 0) {
|
|
878
|
+
this.transactionDocument.basket.taxBreakdown.taxLines.forEach((/**
|
|
879
|
+
* @param {?} taxLine
|
|
880
|
+
* @return {?}
|
|
881
|
+
*/
|
|
882
|
+
(taxLine) => {
|
|
883
|
+
if (product.itemLineId && product.itemLineId === taxLine.itemLineId.toString()) {
|
|
884
|
+
p.selectedVAT = taxLine.VAT;
|
|
885
|
+
p.selectedVATCode = taxLine.VATCode;
|
|
886
|
+
}
|
|
887
|
+
}));
|
|
888
|
+
}
|
|
889
|
+
if (this.transactionDocument.type === TRANSACTION_TYPE.REFUND) {
|
|
890
|
+
p.total = product.refundedTotal;
|
|
891
|
+
}
|
|
892
|
+
else if ((this.transactionDocument.type === TRANSACTION_TYPE.SALE_REFUND || TRANSACTION_TYPE.SALE_EXCHANGE) && product.refundedQuantity > 0) {
|
|
893
|
+
p.refundedReasonDescription = product.refundedReasonDescription;
|
|
894
|
+
p.refundedReason = product.refundedReason;
|
|
895
|
+
if (!p.refundedReasonDescription) {
|
|
896
|
+
p.refundedReasonDescription = p.refundedReason;
|
|
897
|
+
}
|
|
898
|
+
p.refundedQuantity = product.refundedQuantity;
|
|
899
|
+
p.refundPromotionalQuantity = product.refundedPromotionalQuantity;
|
|
900
|
+
p.refundedTotal = product.refundedTotal;
|
|
901
|
+
p.total -= Math.abs(p.refundedTotal);
|
|
902
|
+
p.isLastExchanged = product.isLastExchanged;
|
|
903
|
+
}
|
|
904
|
+
if (this.transactionDocument.type === TRANSACTION_TYPE.REFUND) {
|
|
905
|
+
if (p.total > 0) {
|
|
906
|
+
p.total *= -1;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
basket.products.push(p);
|
|
910
|
+
}));
|
|
911
|
+
basket = this.getTransactionDiscountAndTransactionPromotionPortion(basket);
|
|
912
|
+
basket.total = (basket.basketTotal || 0) + this.getTotalDiscountWithTransactionDiscountsAndPromotions(basket);
|
|
913
|
+
if (this.transactionDocument.type === TRANSACTION_TYPE.SALE_REFUND) {
|
|
914
|
+
basket.quantity = this.getRefundedTotalWithQuantity(basket);
|
|
915
|
+
}
|
|
916
|
+
console.info("ebasket: Basket created successfully", JSON.stringify(basket));
|
|
917
|
+
return basket;
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* Gets basket details
|
|
921
|
+
* @param {?} basket
|
|
922
|
+
* @return {?} refund basket details
|
|
923
|
+
*/
|
|
924
|
+
// getRefundBasketDetails(): Basket {
|
|
925
|
+
// let basket: Basket = {
|
|
926
|
+
// subsidiaryId : this.transactionDocument.subsidiaryId,
|
|
927
|
+
// transactionDiscount: this.transactionDocument.basket.transactionDiscount,
|
|
928
|
+
// transactionPromotion: this.transactionDocument.basket.transactionPromotion,
|
|
929
|
+
// transactionId: this.transactionDocument.transactionId,
|
|
930
|
+
// total: this.transactionDocument.basketSummary.basketTotal,
|
|
931
|
+
// basketTotal: this.transactionDocument.basketSummary.basketTotal,
|
|
932
|
+
// discountTotal: this.transactionDocument.basketSummary.discountTotal,
|
|
933
|
+
// saleTotal: this.transactionDocument.basketSummary.saleTotal,
|
|
934
|
+
// quantity: this.transactionDocument.basketSummary.totalItems,
|
|
935
|
+
// products: [],
|
|
936
|
+
// baseCurrency: this.transactionDocument.baseCurrency,
|
|
937
|
+
// customer: this.transactionDocument.customer,
|
|
938
|
+
// };
|
|
939
|
+
// basket.products = [] as Product[];
|
|
940
|
+
// this.transactionDocument.basket.products.forEach((product: { SKU: any; barCode: any; barcodes: any; description: any; imageUrls: any; totalLinePrice: any; itemLineId: any; excludePromotion: any; price: number; quantity: any; selectedRRPPrice: any; fullfilmentId: any; fullfilmentLocationName: any; deliveryGroup: string; leadTime: any; deliveryMethod: any; giftCard: any; giftCardExpiryDate: any; giftCardNumberIssued: any; giftCardRecipientEmail: any; giftCardRecipientName: any; itemDiscounts: any; refundedPromotionalQuantity: any; refundedQuantity: number; refunded: any; isLastExchanged: any; exchange: any; refundedTotal: number; }, index: any) => {
|
|
941
|
+
// const p = {} as Product;
|
|
942
|
+
// p.SKU = product.SKU;
|
|
943
|
+
// p.barcode = product.barCode;
|
|
944
|
+
// p.barcodes = product.barcodes;
|
|
945
|
+
// p.description = product.description;
|
|
946
|
+
// p.imageUrls = product.imageUrls;
|
|
947
|
+
// p.currency = this.transactionDocument.baseCurrency;
|
|
948
|
+
// p.totalLinePrice = product.totalLinePrice;
|
|
949
|
+
// p.itemLineId = Number(product.itemLineId);
|
|
950
|
+
// p.excludePromotion = product.excludePromotion;
|
|
951
|
+
// p.selectedPrice = product.price;
|
|
952
|
+
// p.quantity = product.quantity;
|
|
953
|
+
// p.total = product.totalLinePrice;
|
|
954
|
+
// p.selectedRRPPrice = product.selectedRRPPrice;
|
|
955
|
+
// p.fullfilmentId = product.fullfilmentId;
|
|
956
|
+
// p.fullfilmentLocationName = product.fullfilmentLocationName;
|
|
957
|
+
// p.deliveryGroup = product.deliveryGroup || "1";
|
|
958
|
+
// p.leadTime = product.leadTime;
|
|
959
|
+
// p.deliveryMethod = product.deliveryMethod || DELIVERY_METHODS.COLLECT_FROM_STORE.toString();
|
|
960
|
+
// p.giftCard = product.giftCard;
|
|
961
|
+
// p.giftCardExpiryDate = product.giftCardExpiryDate;
|
|
962
|
+
// p.giftCardNumberIssued = product.giftCardNumberIssued;
|
|
963
|
+
// p.giftCardRecipientEmail = product.giftCardRecipientEmail;
|
|
964
|
+
// p.giftCardRecipientName = product.giftCardRecipientName;
|
|
965
|
+
// if(p.fullfilmentId != this.transactionDocument.storeId)
|
|
966
|
+
// {
|
|
967
|
+
// p.isWebOrder = true;
|
|
968
|
+
// }
|
|
969
|
+
// if (product.itemDiscounts) {
|
|
970
|
+
// p.itemDiscounts = product.itemDiscounts as ItemDiscount;
|
|
971
|
+
// }
|
|
972
|
+
// // if(!p.itemDiscounts){
|
|
973
|
+
// // console.log(p.itemDiscounts);
|
|
974
|
+
// // this.basketService.transactionDiscountAndPromotionProductortionCalculation(basket);
|
|
975
|
+
// // }
|
|
976
|
+
// p.refundPromotionalQuantity = product.refundedPromotionalQuantity ? product.refundedPromotionalQuantity : 0;
|
|
977
|
+
// if (product.refundedQuantity) {
|
|
978
|
+
// p.quantity = p.quantity - product.refundedQuantity;
|
|
979
|
+
// p.totalLinePrice = (p.quantity * product.price);
|
|
980
|
+
// p.total = p.totalLinePrice;
|
|
981
|
+
// // p.refundPromotionalQuantity = product.refundedPromotionalQuantity;
|
|
982
|
+
// p.refunded = product.refunded;
|
|
983
|
+
// p.isLastExchanged = product.isLastExchanged;
|
|
984
|
+
// }
|
|
985
|
+
// if (product.exchange) {
|
|
986
|
+
// p.exchange = product.exchange;
|
|
987
|
+
// }
|
|
988
|
+
// if (
|
|
989
|
+
// this.transactionDocument.basket.lineDiscount &&
|
|
990
|
+
// this.transactionDocument.basket.lineDiscount.length > 0
|
|
991
|
+
// ) {
|
|
992
|
+
// this.transactionDocument.basket.lineDiscount.forEach((lineDiscount: { itemLineId: { toString: () => any; }; discountedLinePrice: any; }) => {
|
|
993
|
+
// if (product.itemLineId === lineDiscount.itemLineId.toString() && product.refundedQuantity > 0) {
|
|
994
|
+
// p.lineDiscount = Object.assign({}, lineDiscount);
|
|
995
|
+
// p.lineDiscount.discountedLinePrice = p.lineDiscount.unitPrice * p.quantity
|
|
996
|
+
// p.lineDiscount.discountAmount = p.total - p.lineDiscount.discountedLinePrice
|
|
997
|
+
// p.total = p.lineDiscount.discountedLinePrice;
|
|
998
|
+
// } else if (product.itemLineId === lineDiscount.itemLineId.toString()) {
|
|
999
|
+
// p.lineDiscount = lineDiscount;
|
|
1000
|
+
// p.total = lineDiscount.discountedLinePrice
|
|
1001
|
+
// }
|
|
1002
|
+
// });
|
|
1003
|
+
// }
|
|
1004
|
+
// if (
|
|
1005
|
+
// this.transactionDocument.basket.linePromotion &&
|
|
1006
|
+
// this.transactionDocument.basket.linePromotion.length > 0
|
|
1007
|
+
// ) {
|
|
1008
|
+
// this.transactionDocument.basket.linePromotion.forEach((linePromotion: { itemLineId: { toString: () => any; }; refunded: any; }) => {
|
|
1009
|
+
// if (product.itemLineId === linePromotion.itemLineId.toString() && !linePromotion.refunded) {
|
|
1010
|
+
// p.linePromotions = linePromotion;
|
|
1011
|
+
// p.total = p.linePromotions.promotionLinePrice;
|
|
1012
|
+
// p.total = p.total - (product.refundedTotal ? Math.abs(product.refundedTotal) : 0);
|
|
1013
|
+
// }
|
|
1014
|
+
// });
|
|
1015
|
+
// }
|
|
1016
|
+
// p.refundedQuantity = 0;
|
|
1017
|
+
// p.refundedTotal = 0;
|
|
1018
|
+
// if (
|
|
1019
|
+
// this.transactionDocument.basket.taxBreakdown &&
|
|
1020
|
+
// this.transactionDocument.basket.taxBreakdown.taxLines.length > 0
|
|
1021
|
+
// ) {
|
|
1022
|
+
// this.transactionDocument.basket.taxBreakdown.taxLines.forEach((taxLine: { itemLineId: { toString: () => any; }; VAT: any; VATCode: any; }) => {
|
|
1023
|
+
// if (product.itemLineId === taxLine.itemLineId.toString()) {
|
|
1024
|
+
// p.selectedVAT = taxLine.VAT;
|
|
1025
|
+
// p.selectedVATCode = taxLine.VATCode;
|
|
1026
|
+
// }
|
|
1027
|
+
// });
|
|
1028
|
+
// }
|
|
1029
|
+
// if (p.quantity > 0) {
|
|
1030
|
+
// basket.products.push(p);
|
|
1031
|
+
// }
|
|
1032
|
+
// });
|
|
1033
|
+
// // product.itemDiscounts
|
|
1034
|
+
// if (!basket.products[0].hasOwnProperty('itemDiscounts')) {
|
|
1035
|
+
// basket = this.getTransactionDiscountAndTransactionPromotionPortion(basket);
|
|
1036
|
+
// }
|
|
1037
|
+
// console.log("ebasket : TransactionDocumentBuilder :new created refunded basket", JSON.stringify(basket))
|
|
1038
|
+
// basket.quantity = basket.products.reduce(
|
|
1039
|
+
// (n: any, { quantity }: any) => n + quantity,
|
|
1040
|
+
// 0
|
|
1041
|
+
// );
|
|
1042
|
+
// basket.total = this.getTotalWithLineDiscountAndLinePromotionApplied(basket);
|
|
1043
|
+
// basket.basketTotal = basket.total;
|
|
1044
|
+
// basket.basketTotal = basket.basketTotal - this.getTotalDiscountWithTransactionDiscountsAndPromotions(basket);
|
|
1045
|
+
// console.log(
|
|
1046
|
+
// "ebasket : TransactionDocumentBuilder : update Basket Total: after promotion :basketTotal",
|
|
1047
|
+
// basket.basketTotal
|
|
1048
|
+
// );
|
|
1049
|
+
// console.log(
|
|
1050
|
+
// "e:basket :TransactionDocumentBuilder : basketDetails updated values",
|
|
1051
|
+
// JSON.stringify(basket)
|
|
1052
|
+
// );
|
|
1053
|
+
// return basket;
|
|
1054
|
+
// }
|
|
1055
|
+
getTransactionDiscountAndTransactionPromotionPortion(basket) {
|
|
1056
|
+
if (basket.transactionDiscount &&
|
|
1057
|
+
basket.transactionDiscount.length > 0) {
|
|
1058
|
+
basket.transactionDiscount.forEach((/**
|
|
1059
|
+
* @param {?} discount
|
|
1060
|
+
* @return {?}
|
|
1061
|
+
*/
|
|
1062
|
+
(discount) => {
|
|
1063
|
+
if (!discount.itemLineIds) {
|
|
1064
|
+
discount.itemLineIds = basket.products.map((/**
|
|
1065
|
+
* @param {?} product
|
|
1066
|
+
* @return {?}
|
|
1067
|
+
*/
|
|
1068
|
+
(product) => {
|
|
1069
|
+
return product.itemLineId;
|
|
1070
|
+
}));
|
|
1071
|
+
}
|
|
1072
|
+
basket = this.basketService.transactionDiscountProductPortionCalc(basket, discount);
|
|
1073
|
+
}));
|
|
1074
|
+
}
|
|
1075
|
+
if (basket.transactionPromotion &&
|
|
1076
|
+
basket.transactionPromotion.length > 0) {
|
|
1077
|
+
basket.transactionPromotion.forEach((/**
|
|
1078
|
+
* @param {?} tPromotion
|
|
1079
|
+
* @return {?}
|
|
1080
|
+
*/
|
|
1081
|
+
(tPromotion) => {
|
|
1082
|
+
if (!tPromotion.itemLineIds) {
|
|
1083
|
+
/** @type {?} */
|
|
1084
|
+
const filteredData = basket.products.filter((/**
|
|
1085
|
+
* @param {?} item
|
|
1086
|
+
* @return {?}
|
|
1087
|
+
*/
|
|
1088
|
+
(item) => {
|
|
1089
|
+
return item.excludePromotion === false;
|
|
1090
|
+
}));
|
|
1091
|
+
tPromotion.itemLineIds =
|
|
1092
|
+
filteredData.map((/**
|
|
1093
|
+
* @param {?} product
|
|
1094
|
+
* @return {?}
|
|
1095
|
+
*/
|
|
1096
|
+
(product) => {
|
|
1097
|
+
return product.itemLineId;
|
|
1098
|
+
}));
|
|
1099
|
+
}
|
|
1100
|
+
basket = this.basketService.transactionPromotionProductPortionCalc(basket, tPromotion);
|
|
1101
|
+
}));
|
|
1102
|
+
}
|
|
1103
|
+
return basket;
|
|
1104
|
+
}
|
|
1105
|
+
/**
|
|
1106
|
+
* @param {?} basketDetails
|
|
1107
|
+
* @return {?}
|
|
1108
|
+
*/
|
|
1109
|
+
getTotalDiscountWithTransactionDiscountsAndPromotions(basketDetails) {
|
|
1110
|
+
/** @type {?} */
|
|
1111
|
+
let discountTotal = 0;
|
|
1112
|
+
if (basketDetails.transactionPromotion &&
|
|
1113
|
+
basketDetails.transactionPromotion.length > 0) {
|
|
1114
|
+
discountTotal += basketDetails.transactionPromotion.reduce((/**
|
|
1115
|
+
* @param {?} n
|
|
1116
|
+
* @param {?} __1
|
|
1117
|
+
* @return {?}
|
|
1118
|
+
*/
|
|
1119
|
+
(n, { promotionAmount }) => n + promotionAmount), 0);
|
|
1120
|
+
}
|
|
1121
|
+
if (basketDetails.transactionDiscount &&
|
|
1122
|
+
basketDetails.transactionDiscount.length > 0) {
|
|
1123
|
+
discountTotal += basketDetails.transactionDiscount.reduce((/**
|
|
1124
|
+
* @param {?} n
|
|
1125
|
+
* @param {?} __1
|
|
1126
|
+
* @return {?}
|
|
1127
|
+
*/
|
|
1128
|
+
(n, { discountAmount }) => n + discountAmount), 0);
|
|
1129
|
+
}
|
|
1130
|
+
console.log("ebasket : TransactionDocumentBuilder : Transaction discount Total:", discountTotal);
|
|
1131
|
+
return discountTotal;
|
|
1132
|
+
}
|
|
1133
|
+
/**
|
|
1134
|
+
* @param {?} currency
|
|
1135
|
+
* @param {?} value
|
|
1136
|
+
* @return {?}
|
|
1137
|
+
*/
|
|
1138
|
+
appendCurrencySymbol(currency, value) {
|
|
1139
|
+
// value=this.decimalpipe.transform(value,'1.2');
|
|
1140
|
+
if (value >= 0) {
|
|
1141
|
+
/** @type {?} */
|
|
1142
|
+
const returnval = currency + value;
|
|
1143
|
+
console.log(returnval, "ebasket: add currency with value");
|
|
1144
|
+
return returnval;
|
|
1145
|
+
}
|
|
1146
|
+
else {
|
|
1147
|
+
/** @type {?} */
|
|
1148
|
+
const returnval = "-" + (currency + value * -1);
|
|
1149
|
+
console.log(returnval, "-(currency+(value*-1))");
|
|
1150
|
+
return returnval;
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
// /**
|
|
1154
|
+
// * Updates total refund
|
|
1155
|
+
// * @returns total refund
|
|
1156
|
+
// */
|
|
1157
|
+
// updateTotalRefund(): TransactionDocumentBuilder {
|
|
1158
|
+
// this.transactionDocument.basket.products.forEach((product) => {
|
|
1159
|
+
// product.refundedQuantity = product.quantity;
|
|
1160
|
+
// product.refundedTotal = product.totalLinePrice * -1;
|
|
1161
|
+
// console.log(
|
|
1162
|
+
// "ebasket: Transaction price override :",
|
|
1163
|
+
// this.transactionDocument.basket.lineDiscount
|
|
1164
|
+
// );
|
|
1165
|
+
// if (
|
|
1166
|
+
// this.transactionDocument.basket.linePromotion &&
|
|
1167
|
+
// this.transactionDocument.basket.linePromotion.length > 0
|
|
1168
|
+
// ) {
|
|
1169
|
+
// this.transactionDocument.basket.linePromotion.forEach((linePromotion) => {
|
|
1170
|
+
// console.log(
|
|
1171
|
+
// "Promotion: basket linePromotion : ",
|
|
1172
|
+
// this.transactionDocument.basket.linePromotion
|
|
1173
|
+
// );
|
|
1174
|
+
// console.log(
|
|
1175
|
+
// "linePromotion.itemLineId.toString() : ",
|
|
1176
|
+
// linePromotion.itemLineId.toString()
|
|
1177
|
+
// );
|
|
1178
|
+
// console.log(
|
|
1179
|
+
// "condition : " +
|
|
1180
|
+
// (product.itemLineId === linePromotion.itemLineId.toString())
|
|
1181
|
+
// );
|
|
1182
|
+
// if (product.itemLineId === linePromotion.itemLineId.toString()) {
|
|
1183
|
+
// product.refundedTotal =
|
|
1184
|
+
// linePromotion.promotionLinePrice * -1;
|
|
1185
|
+
// }
|
|
1186
|
+
// });
|
|
1187
|
+
// } else
|
|
1188
|
+
// if (
|
|
1189
|
+
// this.transactionDocument.basket.lineDiscount &&
|
|
1190
|
+
// this.transactionDocument.basket.lineDiscount.length > 0
|
|
1191
|
+
// ) {
|
|
1192
|
+
// this.transactionDocument.basket.lineDiscount.forEach((lineDiscount) => {
|
|
1193
|
+
// console.log(
|
|
1194
|
+
// "product.itemLineId : " +
|
|
1195
|
+
// this.transactionDocument.basket.lineDiscount
|
|
1196
|
+
// );
|
|
1197
|
+
// console.log(
|
|
1198
|
+
// "lineDiscount.itemLineId.toString() : " +
|
|
1199
|
+
// lineDiscount.itemLineId.toString()
|
|
1200
|
+
// );
|
|
1201
|
+
// console.log(
|
|
1202
|
+
// "condition : " +
|
|
1203
|
+
// (product.itemLineId === lineDiscount.itemLineId.toString())
|
|
1204
|
+
// );
|
|
1205
|
+
// if (product.itemLineId === lineDiscount.itemLineId.toString()) {
|
|
1206
|
+
// product.refundedTotal = lineDiscount.unitPrice * product.refundedQuantity * -1;
|
|
1207
|
+
// }
|
|
1208
|
+
// });
|
|
1209
|
+
// }
|
|
1210
|
+
// console.log("Product description :" + product.description);
|
|
1211
|
+
// console.log("Product total :" + product.refundedTotal);
|
|
1212
|
+
// // product.displayrefundedamount=this.appendCurrencySymbol(CURRENCY[this.transactionDocument.baseCurrency],product.refundedTotal);
|
|
1213
|
+
// // console.log(product.displayrefundedamount,"displayrefundedamount");
|
|
1214
|
+
// product.refunded = true;
|
|
1215
|
+
// });
|
|
1216
|
+
// const baskettotal = (this.transactionDocument.basketSummary.basketTotal *= -1);
|
|
1217
|
+
// // this.transactionDocument.basketSummary.displaybaskettotal=this.appendCurrencySymbol(CURRENCY[this.transactionDocument.baseCurrency], baskettotal);
|
|
1218
|
+
// const saletotal = (this.transactionDocument.basketSummary.saleTotal *= -1);
|
|
1219
|
+
// // this.transactionDocument.basketSummary.displaysaletotal = this.appendCurrencySymbol(CURRENCY[this.transactionDocument.baseCurrency], saletotal);
|
|
1220
|
+
// (this.transactionDocument.basketSummary.VATTotal *= -1);
|
|
1221
|
+
// return this;
|
|
1222
|
+
// }
|
|
1223
|
+
/**
|
|
1224
|
+
* Sale Total
|
|
1225
|
+
* @param {?} basketDetails
|
|
1226
|
+
* @return {?} Sale Total
|
|
1227
|
+
*/
|
|
1228
|
+
updateSaleTotal(basketDetails) {
|
|
1229
|
+
/** @type {?} */
|
|
1230
|
+
const saleTotal = basketDetails.products.reduce((/**
|
|
1231
|
+
* @param {?} n
|
|
1232
|
+
* @param {?} __1
|
|
1233
|
+
* @return {?}
|
|
1234
|
+
*/
|
|
1235
|
+
(n, { totalLinePrice }) => n + totalLinePrice), 0);
|
|
1236
|
+
return saleTotal;
|
|
1237
|
+
}
|
|
1238
|
+
/**
|
|
1239
|
+
* @param {?} basketDetails
|
|
1240
|
+
* @return {?}
|
|
1241
|
+
*/
|
|
1242
|
+
getTotalWithLineDiscountAndLinePromotionApplied(basketDetails) {
|
|
1243
|
+
/** @type {?} */
|
|
1244
|
+
let saletotal = 0.0;
|
|
1245
|
+
for (let product of basketDetails.products) {
|
|
1246
|
+
// if (product.linePromotions) {
|
|
1247
|
+
// saletotal += product.linePromotions.promotionLinePrice;
|
|
1248
|
+
// } else if (
|
|
1249
|
+
// product.lineDiscount &&
|
|
1250
|
+
// !product.linePromotions
|
|
1251
|
+
// ) {
|
|
1252
|
+
// saletotal +=
|
|
1253
|
+
// product.quantity * Number(product.lineDiscount.unitPrice.toFixed(2));
|
|
1254
|
+
// } else {
|
|
1255
|
+
// saletotal +=
|
|
1256
|
+
// product.quantity * Number(product.selectedPrice.toFixed(2));
|
|
1257
|
+
// }
|
|
1258
|
+
saletotal += product.total;
|
|
1259
|
+
console.log("e-basket:update product Total:" + saletotal, JSON.stringify(product));
|
|
1260
|
+
}
|
|
1261
|
+
return saletotal;
|
|
1262
|
+
}
|
|
1263
|
+
/**
|
|
1264
|
+
* @param {?} basketDetails
|
|
1265
|
+
* @return {?}
|
|
1266
|
+
*/
|
|
1267
|
+
getRefundedTotalWithQuantity(basketDetails) {
|
|
1268
|
+
/** @type {?} */
|
|
1269
|
+
let quantity = 0;
|
|
1270
|
+
for (let index = 0; index < basketDetails.products.length; index++) {
|
|
1271
|
+
/** @type {?} */
|
|
1272
|
+
const product = basketDetails.products[index];
|
|
1273
|
+
if (!product.refundedReasonDescription) {
|
|
1274
|
+
quantity = quantity + product.quantity;
|
|
1275
|
+
}
|
|
1276
|
+
else {
|
|
1277
|
+
quantity = quantity + (product.quantity - product.refundedQuantity);
|
|
1278
|
+
// basketDetails.total = basketDetails.total + product.refundedTotal;
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
return quantity;
|
|
1282
|
+
}
|
|
1283
|
+
/**
|
|
1284
|
+
* Discount Total
|
|
1285
|
+
* @return {?} Discount Total
|
|
1286
|
+
*/
|
|
1287
|
+
updateDiscountTotal() {
|
|
1288
|
+
/** @type {?} */
|
|
1289
|
+
let refundTotal = this.transactionDocument.basketSummary.refundTotal ? this.transactionDocument.basketSummary.refundTotal : 0;
|
|
1290
|
+
console.info("e-basket: transaction builder: refundTotal", JSON.stringify(refundTotal), JSON.stringify(this.transactionDocument.basketSummary));
|
|
1291
|
+
/** @type {?} */
|
|
1292
|
+
const discountTotal = Math.abs(Math.abs(this.transactionDocument.basketSummary.saleTotal) -
|
|
1293
|
+
(Math.abs(this.transactionDocument.basketSummary.basketTotal) + Math.abs(refundTotal)));
|
|
1294
|
+
console.log("e-basket: transaction builder: discountTotal", JSON.stringify(discountTotal));
|
|
1295
|
+
return Number(discountTotal.toFixed(2));
|
|
1296
|
+
}
|
|
1297
|
+
/**
|
|
1298
|
+
* @param {?} reasonCode
|
|
1299
|
+
* @return {?}
|
|
1300
|
+
*/
|
|
1301
|
+
updateReasonCode(reasonCode) {
|
|
1302
|
+
this.transactionDocument.reasonCode = reasonCode.code;
|
|
1303
|
+
this.transactionDocument.reasonDescription = reasonCode.name;
|
|
1304
|
+
return this;
|
|
1305
|
+
}
|
|
1306
|
+
/**
|
|
1307
|
+
* @param {?} useroverride
|
|
1308
|
+
* @return {?}
|
|
1309
|
+
*/
|
|
1310
|
+
updateManagerOverride(useroverride) {
|
|
1311
|
+
this.transactionDocument.override = useroverride;
|
|
1312
|
+
return this;
|
|
1313
|
+
}
|
|
1314
|
+
/**
|
|
1315
|
+
* @param {?} userID
|
|
1316
|
+
* @return {?}
|
|
1317
|
+
*/
|
|
1318
|
+
updateUserID(userID) {
|
|
1319
|
+
this.transactionDocument.userId = userID;
|
|
1320
|
+
return this;
|
|
1321
|
+
}
|
|
1322
|
+
/**
|
|
1323
|
+
* @param {?} name
|
|
1324
|
+
* @return {?}
|
|
1325
|
+
*/
|
|
1326
|
+
updateUserName(name) {
|
|
1327
|
+
this.transactionDocument.userName = name;
|
|
1328
|
+
return this;
|
|
1329
|
+
}
|
|
1330
|
+
/**
|
|
1331
|
+
* @param {?} customerDetail
|
|
1332
|
+
* @return {?}
|
|
1333
|
+
*/
|
|
1334
|
+
addCustomerDetails(customerDetail) {
|
|
1335
|
+
this.transactionDocument.customer = customerDetail;
|
|
1336
|
+
return this;
|
|
1337
|
+
}
|
|
1338
|
+
/**
|
|
1339
|
+
* @param {?} basketDetails
|
|
1340
|
+
* @return {?}
|
|
1341
|
+
*/
|
|
1342
|
+
updateTaxBreakdown(basketDetails) {
|
|
1343
|
+
// let transactionDiscountTotal = 0;
|
|
1344
|
+
/** @type {?} */
|
|
1345
|
+
let taxBreakdown = {
|
|
1346
|
+
taxLines: [],
|
|
1347
|
+
totalTaxableAmount: 0,
|
|
1348
|
+
};
|
|
1349
|
+
// if (this.transactionDocument.basket.transactionDiscount && this.transactionDocument.basket.transactionDiscount.length > 0) {
|
|
1350
|
+
// this.transactionDocument.basket.transactionDiscount.forEach((discount) => {
|
|
1351
|
+
// transactionDiscountTotal += discount.discountAmount;
|
|
1352
|
+
// });
|
|
1353
|
+
// }
|
|
1354
|
+
// if (this.transactionDocument.basket.transactionPromotion && this.transactionDocument.basket.transactionPromotion.length > 0) {
|
|
1355
|
+
// this.transactionDocument.basket.transactionPromotion.forEach(
|
|
1356
|
+
// (promotion) => {
|
|
1357
|
+
// transactionDiscountTotal += promotion.promotionAmount;
|
|
1358
|
+
// }
|
|
1359
|
+
// );
|
|
1360
|
+
// }
|
|
1361
|
+
basketDetails.products.forEach((/**
|
|
1362
|
+
* @param {?} product
|
|
1363
|
+
* @return {?}
|
|
1364
|
+
*/
|
|
1365
|
+
(product) => {
|
|
1366
|
+
/** @type {?} */
|
|
1367
|
+
let taxLine = {
|
|
1368
|
+
itemLineId: product.itemLineId,
|
|
1369
|
+
VAT: product.selectedVAT ? product.selectedVAT : 0,
|
|
1370
|
+
VATCode: product.selectedVATCode,
|
|
1371
|
+
taxLineTotal: 0,
|
|
1372
|
+
taxableAmount: product.total,
|
|
1373
|
+
PreTax: 0
|
|
1374
|
+
};
|
|
1375
|
+
console.info("Product contribution : item line ID :", product.itemLineId, "tax line :", JSON.stringify(taxLine));
|
|
1376
|
+
// step 1
|
|
1377
|
+
// if Transaction Discount and/or promotion applied, find net selling price of each product as taxableamount
|
|
1378
|
+
// if (transactionDiscountTotal > 0) {
|
|
1379
|
+
product = this.basketService.validateProductItemDiscount(product);
|
|
1380
|
+
/** @type {?} */
|
|
1381
|
+
const productContributionInTotal = product.itemDiscounts.trnDiscountsPortion +
|
|
1382
|
+
product.itemDiscounts.trnPromotionsPortion -
|
|
1383
|
+
product.itemDiscounts.refundPortion;
|
|
1384
|
+
// tp+td-rp;
|
|
1385
|
+
console.info("Product contribution : item line ID :", product.itemLineId, "contribution :", JSON.stringify(productContributionInTotal));
|
|
1386
|
+
// calculate net selling price after applying transaction discount as per product contribution
|
|
1387
|
+
taxLine.taxableAmount -= productContributionInTotal;
|
|
1388
|
+
// }
|
|
1389
|
+
//step 2 - find pre tax
|
|
1390
|
+
taxLine.PreTax = this.numberUtilService.trimTo2Decimal2((taxLine.taxableAmount * 100) / (100 + taxLine.VAT));
|
|
1391
|
+
//step 3 - Update taxbreakdown
|
|
1392
|
+
taxBreakdown.totalTaxableAmount += taxLine.taxableAmount;
|
|
1393
|
+
taxLine.taxableAmount = this.numberUtilService.trimTo2Decimal2(taxLine.taxableAmount);
|
|
1394
|
+
// step 4 - update tax Line total
|
|
1395
|
+
taxLine.taxLineTotal = this.numberUtilService.trimTo2Decimal2(taxLine.taxableAmount - taxLine.PreTax);
|
|
1396
|
+
taxBreakdown.taxLines.push(taxLine);
|
|
1397
|
+
}));
|
|
1398
|
+
taxBreakdown.totalTaxableAmount = this.numberUtilService.trimTo2Decimal2(taxBreakdown.totalTaxableAmount);
|
|
1399
|
+
this.transactionDocument.basket.taxBreakdown = taxBreakdown;
|
|
1400
|
+
return this;
|
|
1401
|
+
}
|
|
1402
|
+
/**
|
|
1403
|
+
* @return {?}
|
|
1404
|
+
*/
|
|
1405
|
+
updateTotalTaxSummary() {
|
|
1406
|
+
console.log("Total Tax Summery Request :", JSON.stringify(this.transactionDocument.basket.taxBreakdown));
|
|
1407
|
+
/** @type {?} */
|
|
1408
|
+
let totalTaxSummaryArray = [];
|
|
1409
|
+
/** @type {?} */
|
|
1410
|
+
let totalTaxSummaryGroup = [];
|
|
1411
|
+
console.log("Tax Lines for Total Tax Summery :", JSON.stringify(this.transactionDocument.basket.taxBreakdown.taxLines));
|
|
1412
|
+
this.transactionDocument.basket.taxBreakdown.taxLines.forEach((/**
|
|
1413
|
+
* @param {?} element
|
|
1414
|
+
* @return {?}
|
|
1415
|
+
*/
|
|
1416
|
+
(element) => {
|
|
1417
|
+
/** @type {?} */
|
|
1418
|
+
let TaxSummary = {
|
|
1419
|
+
VATCode: "",
|
|
1420
|
+
VAT: -12345,
|
|
1421
|
+
PreTaxSum: 0,
|
|
1422
|
+
TaxSum: 0,
|
|
1423
|
+
TXrateSum: 0
|
|
1424
|
+
};
|
|
1425
|
+
TaxSummary.VATCode = element.VATCode;
|
|
1426
|
+
TaxSummary.VAT = element.VAT;
|
|
1427
|
+
TaxSummary.PreTaxSum = this.numberUtilService.trimTo2Decimal2(element.PreTax);
|
|
1428
|
+
TaxSummary.TaxSum = this.numberUtilService.trimTo2Decimal2(element.taxLineTotal);
|
|
1429
|
+
TaxSummary.TXrateSum = this.numberUtilService.trimTo2Decimal2(TaxSummary.PreTaxSum + TaxSummary.TaxSum);
|
|
1430
|
+
totalTaxSummaryArray.push(TaxSummary);
|
|
1431
|
+
}));
|
|
1432
|
+
console.log("Total Tax Summery Without Grouped : ", JSON.stringify(totalTaxSummaryArray));
|
|
1433
|
+
totalTaxSummaryGroup = totalTaxSummaryArray.reduce((/**
|
|
1434
|
+
* @param {?} preparedArray
|
|
1435
|
+
* @param {?} currentObj
|
|
1436
|
+
* @return {?}
|
|
1437
|
+
*/
|
|
1438
|
+
(preparedArray, currentObj) => {
|
|
1439
|
+
/** @type {?} */
|
|
1440
|
+
let ind = preparedArray.findIndex((/**
|
|
1441
|
+
* @param {?} x
|
|
1442
|
+
* @return {?}
|
|
1443
|
+
*/
|
|
1444
|
+
(x) => x.VAT === currentObj.VAT));
|
|
1445
|
+
if (ind === -1) {
|
|
1446
|
+
preparedArray.push(currentObj);
|
|
1447
|
+
}
|
|
1448
|
+
else {
|
|
1449
|
+
preparedArray[ind].VATCode = currentObj.VATCode;
|
|
1450
|
+
preparedArray[ind].VAT = currentObj.VAT;
|
|
1451
|
+
preparedArray[ind].PreTaxSum += currentObj.PreTaxSum;
|
|
1452
|
+
preparedArray[ind].TaxSum += currentObj.TaxSum;
|
|
1453
|
+
preparedArray[ind].TXrateSum += currentObj.TXrateSum;
|
|
1454
|
+
}
|
|
1455
|
+
return preparedArray;
|
|
1456
|
+
}), []);
|
|
1457
|
+
console.log("Total Tax Summer Group :", totalTaxSummaryGroup);
|
|
1458
|
+
this.transactionDocument.basket.totalTaxSummary = totalTaxSummaryGroup;
|
|
1459
|
+
return this;
|
|
1460
|
+
}
|
|
1461
|
+
/**
|
|
1462
|
+
* TransactionId
|
|
1463
|
+
* @param {?} tranDoc
|
|
1464
|
+
* @return {?} OriginalTransactionId
|
|
1465
|
+
*/
|
|
1466
|
+
addOriginalTransId(tranDoc) {
|
|
1467
|
+
if (this.transactionDocument.type === TRANSACTION_TYPE.REFUND || this.transactionDocument.type === TRANSACTION_TYPE.SALE_REFUND || this.transactionDocument.type === TRANSACTION_TYPE.SALE_EXCHANGE) {
|
|
1468
|
+
this.transactionDocument.originalTransId = tranDoc.transactionId;
|
|
1469
|
+
if (tranDoc.apiResponse && tranDoc.apiResponse.internalId) {
|
|
1470
|
+
this.transactionDocument.originalExternalId = tranDoc.apiResponse.internalId.toString();
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
return this;
|
|
1474
|
+
}
|
|
1475
|
+
/**
|
|
1476
|
+
* unreferenced Refund
|
|
1477
|
+
* @return {?} boolean value
|
|
1478
|
+
*/
|
|
1479
|
+
addUnreferencedRefund() {
|
|
1480
|
+
this.transactionDocument.unreferencedRefund = true;
|
|
1481
|
+
return this;
|
|
1482
|
+
}
|
|
1483
|
+
/**
|
|
1484
|
+
* @return {?}
|
|
1485
|
+
*/
|
|
1486
|
+
getRefundTotal() {
|
|
1487
|
+
/** @type {?} */
|
|
1488
|
+
let totalRefund = 0;
|
|
1489
|
+
for (let index = 0; index < this.transactionDocument.basket.products.length; index++) {
|
|
1490
|
+
/** @type {?} */
|
|
1491
|
+
const product = this.transactionDocument.basket.products[index];
|
|
1492
|
+
if (product.refundedTotal) {
|
|
1493
|
+
totalRefund = totalRefund + product.refundedTotal;
|
|
1494
|
+
}
|
|
1495
|
+
console.log("ebasket : transaction Service: totalRefund" + totalRefund);
|
|
1496
|
+
}
|
|
1497
|
+
return totalRefund;
|
|
1498
|
+
}
|
|
1499
|
+
/**
|
|
1500
|
+
* @param {?} docId
|
|
1501
|
+
* @return {?}
|
|
1502
|
+
*/
|
|
1503
|
+
docId(docId) {
|
|
1504
|
+
this.transactionDocument.id = docId;
|
|
1505
|
+
return this;
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
if (false) {
|
|
1509
|
+
/**
|
|
1510
|
+
* @type {?}
|
|
1511
|
+
* @private
|
|
1512
|
+
*/
|
|
1513
|
+
TransactionDocumentBuilder.prototype.transactionDocument;
|
|
1514
|
+
/**
|
|
1515
|
+
* @type {?}
|
|
1516
|
+
* @private
|
|
1517
|
+
*/
|
|
1518
|
+
TransactionDocumentBuilder.prototype.numberUtilService;
|
|
1519
|
+
/**
|
|
1520
|
+
* @type {?}
|
|
1521
|
+
* @private
|
|
1522
|
+
*/
|
|
1523
|
+
TransactionDocumentBuilder.prototype.storeInfo;
|
|
1524
|
+
/**
|
|
1525
|
+
* @type {?}
|
|
1526
|
+
* @private
|
|
1527
|
+
*/
|
|
1528
|
+
TransactionDocumentBuilder.prototype.currencyPipe;
|
|
1529
|
+
/**
|
|
1530
|
+
* @type {?}
|
|
1531
|
+
* @private
|
|
1532
|
+
*/
|
|
1533
|
+
TransactionDocumentBuilder.prototype.basketService;
|
|
1534
|
+
}
|
|
1535
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AcG1jcmV0YWlsL21hcHBlci1saWJyYXJ5LyIsInNvdXJjZXMiOlsibGliL1RyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQ0EsT0FBTyxFQUFzRCxnQkFBZ0IsRUFBaUcsTUFBTSx3QkFBd0IsQ0FBQztBQUM3TSxPQUFPLEVBQUUsZ0JBQWdCLEVBQStELE1BQU0sd0JBQXdCLENBQUM7QUFDdkgsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDOzs7O0FBSzFELE1BQU0sT0FBTywwQkFBMEI7Ozs7OztJQUtyQyxZQUNFLGNBQW9DLEVBQzVCLFlBQTJCLEVBQzNCLGFBQW1DO1FBRG5DLGlCQUFZLEdBQVosWUFBWSxDQUFlO1FBQzNCLGtCQUFhLEdBQWIsYUFBYSxDQUFzQjtRQUUzQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM3RCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQy9ELElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDO1FBQ3ZFLElBQUksY0FBYyxFQUFFO1lBQ2xCLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxjQUFjLENBQUM7U0FDM0M7YUFBTTtZQUNMLElBQUksQ0FBQyxtQkFBbUIsR0FBRztnQkFDekIsYUFBYSxFQUFFLEVBQUU7Z0JBQ2pCLG9CQUFvQixFQUFFLEVBQUU7Z0JBQ3hCLGNBQWMsRUFBRSxFQUFFO2dCQUNsQixRQUFRLEVBQUUsRUFBRTtnQkFDWixP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QUFBO1NBQ3hFO1FBQ0QsT0FBTyxXQUFXLENBQUM7SUFDckIsQ0FBQzs7Ozs7SUFFRCxLQUFLLENBQUMsS0FBVTtRQUNaLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLEdBQUcsS0FBSyxDQUFDO1FBQ3RDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztDQUNGOzs7Ozs7SUFuK0NDLHlEQUFpRDs7Ozs7SUFDakQsdURBQTZDOzs7OztJQUM3QywrQ0FBd0I7Ozs7O0lBSXRCLGtEQUFtQzs7Ozs7SUFDbkMsbURBQTJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ3VycmVuY3lQaXBlIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xyXG5pbXBvcnQgeyBCYXNrZXRTdW1tYXJ5LCBDdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLCBDdXN0b21lciwgREVMSVZFUllfTUVUSE9EUywgSXRlbURpc2NvdW50cywgVGF4QnJlYWtkb3duLCBUYXhMaW5lLCBUQmFza2V0LCBUb3RhbFRheFN1bW1hcnksIFRQcm9kdWN0LCBUcmFuc2FjdGlvbkRvY3VtZW50IH0gZnJvbSBcIi4vbWFwcGVyLWxpYnJhcnkubW9kZWxcIjtcclxuaW1wb3J0IHsgVFJBTlNBQ1RJT05fVFlQRSwgQmFza2V0LCBMaW5lRGlzY291bnQsIExpbmVQcm9tb3Rpb25zLCBQcm9kdWN0LCBVc2VyT3ZlcnJpZGUgfSBmcm9tIFwiLi9tYXBwZXItbGlicmFyeS5tb2RlbFwiO1xyXG5pbXBvcnQgeyBCYXNrZXRTZXJ2aWNlIH0gZnJvbSBcIi4vYmFza2V0LnNlcnZpY2VcIjtcclxuaW1wb3J0IHsgTnVtYmVyVXRpbFNlcnZpY2UgfSBmcm9tIFwiLi9udW1iZXItdXRpbC5zZXJ2aWNlXCI7XHJcblxyXG4vKipcclxuICogVHJhbnNhY3Rpb24gZG9jdW1lbnQgYnVpbGRlclxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICBwcml2YXRlIHRyYW5zYWN0aW9uRG9jdW1lbnQ6IFRyYW5zYWN0aW9uRG9jdW1lbnQ7XHJcbiAgcHJpdmF0ZSBudW1iZXJVdGlsU2VydmljZTogTnVtYmVyVXRpbFNlcnZpY2U7XHJcbiAgcHJpdmF0ZSBzdG9yZUluZm8gOiBhbnk7XHJcbiAgXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICB0cmFuc2FjdGlvbkRvYz86IFRyYW5zYWN0aW9uRG9jdW1lbnQsXHJcbiAgICBwcml2YXRlIGN1cnJlbmN5UGlwZT86IEN1cnJlbmN5UGlwZSxcclxuICAgIHByaXZhdGUgYmFza2V0U2VydmljZT86IEJhc2tldFNlcnZpY2UgfCBhbnksXHJcbiAgKSB7XHJcbiAgICB0aGlzLm51bWJlclV0aWxTZXJ2aWNlID0gbmV3IE51bWJlclV0aWxTZXJ2aWNlKGN1cnJlbmN5UGlwZSk7XHJcbiAgICB0aGlzLmJhc2tldFNlcnZpY2UgPSBuZXcgQmFza2V0U2VydmljZSh0aGlzLm51bWJlclV0aWxTZXJ2aWNlKTtcclxuICAgIHRoaXMuc3RvcmVJbmZvID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnc3RvcmVJbmZvJykgfHwgJ3t9Jyk7XHJcbiAgICBpZiAodHJhbnNhY3Rpb25Eb2MpIHtcclxuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50ID0gdHJhbnNhY3Rpb25Eb2M7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQgPSB7XHJcbiAgICAgICAgdHJhbnNhY3Rpb25JZDogXCJcIixcclxuICAgICAgICBvZmZsaW5lVHJhbnNhY3Rpb25JZDogXCJcIixcclxuICAgICAgICB0cmFuc2FjdGlvblJlZjogXCJcIixcclxuICAgICAgICBkYXRlVGltZTogXCJcIixcclxuICAgICAgICBvcmdDb2RlOiBcIlwiLFxyXG4gICAgICAgIHN0b3JlSWQ6IFwiXCIsXHJcbiAgICAgICAgc3RvcmVOb2RlSWQ6IFwiXCIsXHJcbiAgICAgICAgc3RvcmVOb2RlU3RydWN0dXJlOiBcIlwiLFxyXG4gICAgICAgIGRldmljZUlkOiBcIlwiLFxyXG4gICAgICAgIHRlcm1pbmFsSWQ6IFwiXCIsXHJcbiAgICAgICAgdXNlcklkOiBcIlwiLFxyXG4gICAgICAgIGluaXRpYXRpbmdNb2R1bGUgOiBcImVCYXNrZXRcIixcclxuICAgICAgICBleHBvcnQ6IGZhbHNlLFxyXG4gICAgICAgIGJhc2tldDoge30gYXMgVEJhc2tldCxcclxuICAgICAgICBiYXNrZXRTdW1tYXJ5OiB7fSBhcyBCYXNrZXRTdW1tYXJ5LFxyXG4gICAgICAgIGJhc2VDdXJyZW5jeTogXCJcIixcclxuICAgICAgICB0eXBlOiBcIlwiLFxyXG4gICAgICAgIG9wZXJhdGlvblN0YXR1czogXCJcIixcclxuICAgICAgICBjcmVhdGVkQXQ6IFwiXCIsXHJcbiAgICAgICAgdXBkYXRlZEF0OiBcIlwiLFxyXG4gICAgICAgIGlkOiBcIlwiLFxyXG4gICAgICAgIGN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHM6IHt9IGFzIEN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMsXHJcbiAgICAgICAgc2FsZVRvdGFsOiAwLFxyXG4gICAgICB9O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVHJhbnNhY3Rpb25zIHJlZlxyXG4gICAqIEByZXR1cm5zIHJlZlxyXG4gICAqL1xyXG4gIHRyYW5zYWN0aW9uUmVmKCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIGNvbnN0IHN0b3JlRGV0YWlscyA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ3N0b3JlSW5mbycpIHx8ICd7fScpO1xyXG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKCk7XHJcbiAgICBjb25zdCByYW5kb20gPSAoKCgxICsgTWF0aC5yYW5kb20oKSkgKiAweDEwMDAwKSB8IDApXHJcbiAgICAgIC50b1N0cmluZygxNilcclxuICAgICAgLnN1YnN0cmluZygxKTtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC50cmFuc2FjdGlvblJlZiA9XHJcbiAgICAgIHN0b3JlRGV0YWlscy5vcmdDb2RlICsgc3RvcmVEZXRhaWxzLnN0b3JlSWQgKyBkYXRlLnRvSVNPU3RyaW5nKCkgKyByYW5kb207XHJcbiAgICBjb25zb2xlLmxvZyhcImViYXNrZXQ6IHRyYW5zYWN0aW9uIHJlZiBjcmVhdGVkXCIsIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC50cmFuc2FjdGlvblJlZilcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVHJhbnNhY3Rpb25zIGlkXHJcbiAgICogQHBhcmFtIHRyYW5zYWN0aW9uSURcclxuICAgKiBAcmV0dXJucyBpZFxyXG4gICAqL1xyXG4gIHRyYW5zYWN0aW9uSWQodHJhbnNhY3Rpb25JRDogc3RyaW5nLCBpc09ubGluZTogYm9vbGVhbiA9IHRydWUpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICBpZiAoaXNPbmxpbmUpIHtcclxuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnRyYW5zYWN0aW9uSWQgPSB0cmFuc2FjdGlvbklEO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUcmFuc2FjdGlvbnMgaWRcclxuICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JRFxyXG4gICAqIEByZXR1cm5zIGlkXHJcbiAgICovXHJcbiAgb2ZmbGluZVRyYW5zYWN0aW9uSWQodHJhbnNhY3Rpb25JRDogc3RyaW5nLCBpc09ubGluZTogYW55KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgaWYgKCFpc09ubGluZSkge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQub2ZmbGluZVRyYW5zYWN0aW9uSWQgPSB0cmFuc2FjdGlvbklEO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAqIHN0b3JlTm9kZSBJZFxyXG4gICogQHBhcmFtIHN0b3JlTm9kZUlkXHJcbiAgKiBAcmV0dXJucyBpZFxyXG4gICovXHJcbiAgc3RvcmVOb2RlSWQoc3RvcmVOb2RlSWQ6IHN0cmluZyk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5zdG9yZU5vZGVJZCA9IHN0b3JlTm9kZUlkO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuKiBzdG9yZU5vZGUgc3RydWN0dXJlXHJcbiogQHBhcmFtIHN0b3JlTm9kZVN0cnVjdHVyZVxyXG4qIEByZXR1cm5zIGlkXHJcbiovXHJcbiAgc3RvcmVOb2RlU3RydWN0dXJlKHN0b3JlTm9kZVN0cnVjdHVyZTogc3RyaW5nKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnN0b3JlTm9kZVN0cnVjdHVyZSA9IHN0b3JlTm9kZVN0cnVjdHVyZTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogT3JncyBjb2RlXHJcbiAgICogQHBhcmFtIG9yZ0NvZGVcclxuICAgKiBAcmV0dXJucyBjb2RlXHJcbiAgICovXHJcbiAgb3JnQ29kZShvcmdDb2RlOiBhbnkpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQub3JnQ29kZSA9IG9yZ0NvZGU7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcbiAgLyoqXHJcbiAgICogU3RvcmVzIGlkXHJcbiAgICogQHBhcmFtIHN0b3JlSWRcclxuICAgKiBAcmV0dXJucyBpZFxyXG4gICAqL1xyXG4gIHN0b3JlSWQoc3RvcmVJZDogYW55KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnN0b3JlSWQgPSBzdG9yZUlkO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIERhdGVzIHRpbWVcclxuICAgKiBAcmV0dXJucyB0aW1lXHJcbiAgICovXHJcbiAgZGF0ZVRpbWUoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKCk7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuZGF0ZVRpbWUgPSBkYXRlLnRvSVNPU3RyaW5nKCk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcbiAgLyoqXHJcbiAgICogRGV2aWNlcyBpZFxyXG4gICAqIEBwYXJhbSBkZXZpY2VJZFxyXG4gICAqIEByZXR1cm5zIGlkXHJcbiAgICovXHJcbiAgZGV2aWNlSWQoZGV2aWNlSWQ6IGFueSk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5kZXZpY2VJZCA9IGRldmljZUlkO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICAgKiB0ZXJtaW5hbCBpZFxyXG4gICAgICogQHBhcmFtIHRlcm1pbmFsSWRcclxuICAgICAqIEByZXR1cm5zIGlkXHJcbiAgICAgKi9cclxuICB0ZXJtaW5hbElkKHRlcm1pbmFsSWQ6IGFueSk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC50ZXJtaW5hbElkID0gdGVybWluYWxJZDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcblxyXG5cclxuXHJcblxyXG4gIC8qKlxyXG4gICAgKiBzYWxlRXhwb3J0XHJcbiAgICAqIEBwYXJhbSBzYWxlRXhwb3J0XHJcbiAgICAqIEByZXR1cm5zIGlkXHJcbiAgICAqL1xyXG4gIGV4cG9ydChzYWxlRXhwb3J0OiBhbnkpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuZXhwb3J0ID0gc2FsZUV4cG9ydDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcblxyXG5cclxuICAvKiAgY3VzdG9tZXIoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgY29uc3QgdXNlciA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ3VzZXJEZXRhaWxzJykpO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1c3RvbWVyID0gdXNlcjtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH0gKi9cclxuICAvKipcclxuICAgKiBCYXNrZXRzIHRyYW5zYWN0aW9uIGRvY3VtZW50IGJ1aWxkZXJcclxuICAgKiBAcGFyYW0gYmFza2V0RGV0YWlsc1xyXG4gICAqIEByZXR1cm5zIGJhc2tldFxyXG4gICAqL1xyXG4gIGJhc2tldChiYXNrZXREZXRhaWxzOiBCYXNrZXQpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICBjb25zb2xlLmxvZyhcImViYXNrZXQ6IGJhc2tldCBkZXRhaWxzIHVwZGF0ZSBpbiB0cmFuc2FjdGlvbiBkb2N1bWVudFwiLCBKU09OLnN0cmluZ2lmeShiYXNrZXREZXRhaWxzKSk7XHJcblxyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnN1YnNpZGlhcnlJZCA9IGJhc2tldERldGFpbHMuc3Vic2lkaWFyeUlkIHx8IChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnc3Vic2lkaWFyeUlkJykgfHwgJycpO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5wcm9kdWN0cyA9IFtdIGFzIFRQcm9kdWN0W107XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudCA9IFtdO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lUHJvbW90aW9uID0gW107XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uID0gW107XHJcbiAgICBiYXNrZXREZXRhaWxzLnByb2R1Y3RzLmZvckVhY2goKHByb2R1Y3Q6IGFueSwgaW5kZXgpID0+IHtcclxuICAgICAgY29uc3QgcCA9IHt9IGFzIFRQcm9kdWN0O1xyXG4gICAgICBwLml0ZW1EaXNjb3VudHMgPSB7fSBhcyBJdGVtRGlzY291bnRzO1xyXG4gICAgICBwLlNLVSA9IHByb2R1Y3QuU0tVO1xyXG4gICAgICBwLmV4Y2x1ZGVQcm9tb3Rpb24gPSBwcm9kdWN0LmV4Y2x1ZGVQcm9tb3Rpb247XHJcbiAgICAgIHAuYmFyQ29kZSA9IHByb2R1Y3QuYmFyY29kZTtcclxuICAgICAgcC5iYXJjb2RlcyA9IHByb2R1Y3QuYmFyY29kZXM7XHJcbiAgICAgIHAuZGVzY3JpcHRpb24gPSBwcm9kdWN0LmRlc2NyaXB0aW9uO1xyXG4gICAgICBwLml0ZW1MaW5lSWQgPSBwcm9kdWN0Lml0ZW1MaW5lSWQgPyBwcm9kdWN0Lml0ZW1MaW5lSWQudG9TdHJpbmcoKSA6IFwiXCIgKyAoaW5kZXggKyAxKTtcclxuICAgICAgcC5wcmljZSA9IHByb2R1Y3Quc2VsZWN0ZWRQcmljZTtcclxuICAgICAgcC5xdWFudGl0eSA9IHByb2R1Y3QucXVhbnRpdHk7XHJcbiAgICAgIHAudG90YWxMaW5lUHJpY2UgPSBwcm9kdWN0LnF1YW50aXR5ICogcHJvZHVjdC5zZWxlY3RlZFByaWNlO1xyXG4gICAgICBwLmltYWdlVXJscyA9IHByb2R1Y3QuaW1hZ2VVcmxzO1xyXG4gICAgICBwLnNlbGVjdGVkUlJQUHJpY2UgPSBwcm9kdWN0LnNlbGVjdGVkUlJQUHJpY2U7XHJcblxyXG4gICAgICAvL2ludmVudG9yeSBmaWVsZHNcclxuICAgICAgXHJcbiAgICAgIHAuZnVsbGZpbG1lbnRJZCA9IHByb2R1Y3QuZnVsbGZpbG1lbnRJZD8gcHJvZHVjdC5mdWxsZmlsbWVudElkOiB0aGlzLnN0b3JlSW5mby5zdG9yZUlkO1xyXG5cclxuICAgICAgcC5mdWxsZmlsbWVudExvY2F0aW9uTmFtZSA9IHByb2R1Y3QuZnVsbGZpbG1lbnRMb2NhdGlvbk5hbWU7XHJcbiAgICAgIHAuZGVsaXZlcnlHcm91cCA9IHByb2R1Y3QuZGVsaXZlcnlHcm91cDtcclxuICAgICAgcC5sZWFkVGltZSA9IHByb2R1Y3QubGVhZFRpbWU7XHJcbiAgICAgIHAuZGVsaXZlcnlNZXRob2QgPSBwcm9kdWN0LmRlbGl2ZXJ5TWV0aG9kO1xyXG5cclxuICAgICAgcC5naWZ0Q2FyZCA9IHByb2R1Y3QuZ2lmdENhcmQ7XHJcbiAgICAgIHAuZ2lmdENhcmRFeHBpcnlEYXRlID0gcHJvZHVjdC5naWZ0Q2FyZEV4cGlyeURhdGU7XHJcbiAgICAgIHAuZ2lmdENhcmROdW1iZXJJc3N1ZWQgPSBwcm9kdWN0LmdpZnRDYXJkTnVtYmVySXNzdWVkO1xyXG4gICAgICBwLmdpZnRDYXJkUmVjaXBpZW50RW1haWwgPSBwcm9kdWN0LmdpZnRDYXJkUmVjaXBpZW50RW1haWw7XHJcbiAgICAgIHAuZ2lmdENhcmRSZWNpcGllbnROYW1lID0gcHJvZHVjdC5naWZ0Q2FyZFJlY2lwaWVudE5hbWU7XHJcblxyXG4gICAgICBpZiAocHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5ID4gMCkge1xyXG4gICAgICAgIHAucmVmdW5kZWRRdWFudGl0eSA9IHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eTtcclxuICAgICAgICBwLnJlZnVuZGVkUHJvbW90aW9uYWxRdWFudGl0eSA9IHByb2R1Y3QucmVmdW5kUHJvbW90aW9uYWxRdWFudGl0eTtcclxuICAgICAgICBwLnJlZnVuZGVkID0gcHJvZHVjdC5yZWZ1bmRlZDtcclxuICAgICAgICBwLnJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb24gPSBwcm9kdWN0LnJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb247XHJcbiAgICAgICAgcC5yZWZ1bmRlZFJlYXNvbiA9IHByb2R1Y3QucmVmdW5kZWRSZWFzb247XHJcbiAgICAgICAgaWYgKCFwLnJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb24pIHtcclxuICAgICAgICAgIHAucmVmdW5kZWRSZWFzb25EZXNjcmlwdGlvbiA9IHAucmVmdW5kZWRSZWFzb247XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHAucmVmdW5kZWRUb3RhbCA9IHByb2R1Y3QucmVmdW5kZWRUb3RhbDtcclxuICAgICAgICBwLmlzTGFzdEV4Y2hhbmdlZCA9IHByb2R1Y3QuaXNMYXN0RXhjaGFuZ2VkO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAocHJvZHVjdC5leGNoYW5nZSkge1xyXG4gICAgICAgIHAuZXhjaGFuZ2UgPSBwcm9kdWN0LmV4Y2hhbmdlO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9kdWN0LmxpbmVEaXNjb3VudCkge1xyXG4gICAgICAgIHAubGluZURpc2NvdW50ID0gcHJvZHVjdC5saW5lRGlzY291bnQ7XHJcbiAgICAgIH1cclxuICAgICAgcC5pdGVtRGlzY291bnRzID0gcHJvZHVjdC5pdGVtRGlzY291bnRzIGFzIEl0ZW1EaXNjb3VudHM7XHJcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQucHJvZHVjdHMucHVzaChwKTtcclxuICAgICAgdGhpcy5saW5lRGlzY291bnQoYmFza2V0RGV0YWlscyk7XHJcbiAgICB9KTtcclxuICAgIGNvbnNvbGUuaW5mbyhcImViYXNrZXQ6IHRyYW5zYWN0aW9uZG9jdW1lbnQgYmFza2V0IGRldGFpbHMgdXBkYXRlZFwiLCBKU09OLnN0cmluZ2lmeSh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0KSk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgICAqIGN1cnJlbnQgdHJhbnNhY3Rpb24gRGV0YWlscyBUb3RhbChOZXcgUHJvZHVjdHMpXHJcbiAgICAgKiBAcmV0dXJucyBjdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzXHJcbiAgICAgKi9cclxuXHJcbiAgY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscyhiYXNrZXQ6IEJhc2tldCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIGNvbnNvbGUubG9nKFwiZWJhc2tldDogY3VycmVudCB0cmFuc2FjdGlvbiBkZXRhaWxzIGZvciBleGNoYW5nZXNcIiwgYmFza2V0KTtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnByb2R1Y3RzID0gW10gYXMgUHJvZHVjdFtdO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMubGluZVByb21vdGlvbiA9IFtdIGFzIExpbmVQcm9tb3Rpb25zW107XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5saW5lRGlzY291bnQgPSBbXSBhcyBMaW5lRGlzY291bnRbXTtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQgPSBbXTtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnByb2R1Y3RzID0gYmFza2V0LnByb2R1Y3RzO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMucHJvZHVjdHMgPSB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5wcm9kdWN0cy5maWx0ZXIoXHJcbiAgICAgICggICAgICBwcm9qOiB7IHJlZnVuZGVkUXVhbnRpdHk6IG51bWJlcjsgfSkgPT4gcHJvai5yZWZ1bmRlZFF1YW50aXR5ICE9IDBcclxuICAgICk7XHJcblxyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMucHJvZHVjdHMuZm9yRWFjaCgocHJvZHVjdDogeyByZWZ1bmRlZFF1YW50aXR5OiBhbnk7IHF1YW50aXR5OiBhbnk7IHRvdGFsTGluZVByaWNlOiBudW1iZXI7IHJlZnVuZGVkVG90YWw6IG51bWJlcjsgdG90YWw6IGFueTsgcmVmdW5kZWQ6IGJvb2xlYW47IGxpbmVQcm9tb3Rpb25zOiBhbnk7IGxpbmVEaXNjb3VudDogYW55OyB9KSA9PiB7XHJcbiAgICAgIGlmIChwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHkpIHtcclxuICAgICAgICBwcm9kdWN0LnF1YW50aXR5ID0gcHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5O1xyXG4gICAgICAgIC8vIHVwZGF0aW5nIHRvdGFsIGxpbmUgcHJpY2Ugd2l0aCBhY3R1YWwgcHJpY2UgdG8gYmUgcmVmdW5kZWQgaW5jbHVkaW5nIHRoZSByZWZ1bmRpbmcgcXR5XHJcbiAgICAgICAgcHJvZHVjdC50b3RhbExpbmVQcmljZSA9IE1hdGguYWJzKHByb2R1Y3QucmVmdW5kZWRUb3RhbCk7XHJcbiAgICAgICAgcHJvZHVjdC50b3RhbCA9IHByb2R1Y3QudG90YWxMaW5lUHJpY2U7XHJcbiAgICAgICAgaWYgKHByb2R1Y3QucXVhbnRpdHkgPT09IHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eSkge1xyXG4gICAgICAgICAgcHJvZHVjdC5yZWZ1bmRlZCA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIC8vVXBkYXRpbmcgbGluZSBwcm9tb3Rpb25zIGFuZCBsaW5lIGRpc2NvdW50cyAgICAgIFxyXG4gICAgICBpZiAocHJvZHVjdC5saW5lUHJvbW90aW9ucyAmJiAhcHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5KSB7XHJcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMubGluZVByb21vdGlvbi5wdXNoKHByb2R1Y3QubGluZVByb21vdGlvbnMpXHJcbiAgICAgIH1cclxuICAgICAgaWYgKHByb2R1Y3QubGluZURpc2NvdW50ICYmICFwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHkpIHtcclxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5saW5lRGlzY291bnQucHVzaChwcm9kdWN0LmxpbmVEaXNjb3VudClcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgY29uc29sZS5sb2coXCJlYmFza2V0OiBjdXJyZW50IHRyYW5zYWN0aW9uIGRldGFpbHMgYWZ0ZXIgcmVtb3Zpbmcgb2xkIHByb2R1Y3RzXCIsIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnByb2R1Y3RzKTtcclxuXHJcbiAgICBpZiAoYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQgJiYgYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQubGVuZ3RoID4gMCkge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy50cmFuc2FjdGlvbkRpc2NvdW50LnB1c2goLi4uYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQpO1xyXG4gICAgfVxyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeSA9IHt9IGFzIEJhc2tldFN1bW1hcnk7XHJcblxyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS5zYWxlVG90YWwgPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMih0aGlzLnVwZGF0ZVNhbGVUb3RhbCh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscykpO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS50b3RhbEl0ZW1zID0gYmFza2V0LnF1YW50aXR5O1xyXG5cclxuXHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsID0gYmFza2V0LmJhc2tldFRvdGFsO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS5yZWZ1bmRUb3RhbCA9IHRoaXMudXBkYXRlQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc1JlZnVuZFRvdGFsKCk7XHJcbiAgICAvLyBGb3IgcGFydGlhbCByZWZ1bmQgZGlzY291bnQgaXMgdXBkYXRpZWQgaW4gdG90YWwgbGluZSBwcmljZSBzbyBkaXNjb3VudFRvdGFsIHdpbGwgYWx3YXlzIGJlIHplcm8gJiBpbiBjYXNlIG9mIGV4Y2hhbmdlIGRpc2NvdW50IHRvdGFsIGlzIGNhbGN1bGF0ZWRcclxuXHJcbiAgICBpZiAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnR5cGUgPT09IFRSQU5TQUNUSU9OX1RZUEUuU0FMRV9FWENIQU5HRSkge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LmRpc2NvdW50VG90YWwgPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMih0aGlzLnVwZGF0ZUN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNEaXNjb3VudFRvdGFsKCkpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQgJiYgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgbGV0IGRpc2NvdW50VG90YWwgPSAwO1xyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQuZm9yRWFjaCgoZGlzY291bnQ6IHsgZGlzY291bnRBbW91bnQ6IG51bWJlcjsgfSkgPT4ge1xyXG4gICAgICAgICAgZGlzY291bnRUb3RhbCArPSBkaXNjb3VudC5kaXNjb3VudEFtb3VudDtcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LmRpc2NvdW50VG90YWwgPSBNYXRoLmFicyhkaXNjb3VudFRvdGFsKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LmRpc2NvdW50VG90YWwgPSAwO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgY29uc29sZS5sb2coXCJlYmFza2V0OnRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzXCIsIEpTT04uc3RyaW5naWZ5KHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzKSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG5cclxuICAvKipcclxuICogY3VycmVudCB0cmFuc2FjdGlvbiBUYXggVG90YWxcclxuICogQHJldHVybnMgVGF4IFRvdGFsXHJcbiAqL1xyXG5cclxuICB1cGRhdGVDdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzVGF4QnJlYWtkb3duKGJhc2tldERldGFpbHM6IEJhc2tldCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIGxldCB0cmFuc2FjdGlvbkRpc2NvdW50VG90YWwgPSAwO1xyXG4gICAgbGV0IHRheEJyZWFrZG93bjogVGF4QnJlYWtkb3duID0ge1xyXG4gICAgICB0YXhMaW5lczogW10sXHJcbiAgICAgIHRvdGFsVGF4YWJsZUFtb3VudDogMCxcclxuICAgIH07XHJcblxyXG4gICAgaWYgKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQgJiYgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudC5sZW5ndGggPiAwKSB7XHJcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQuZm9yRWFjaCgoZGlzY291bnQ6IHsgZGlzY291bnRBbW91bnQ6IG51bWJlcjsgfSkgPT4ge1xyXG4gICAgICAgIHRyYW5zYWN0aW9uRGlzY291bnRUb3RhbCArPSBkaXNjb3VudC5kaXNjb3VudEFtb3VudDtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnByb2R1Y3RzICYmIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnByb2R1Y3RzLmxlbmd0aCA+IDApIHtcclxuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMucHJvZHVjdHMuZm9yRWFjaCgocHJvZHVjdDogeyBpdGVtTGluZUlkOiBhbnk7IHNlbGVjdGVkVkFUOiBhbnk7IHNlbGVjdGVkVkFUQ29kZTogYW55OyB0b3RhbDogYW55OyByZWZ1bmRlZFF1YW50aXR5OiBudW1iZXI7IGl0ZW1EaXNjb3VudHM6IHsgY3VycmVudFJlZnVuZFBvcnRpb246IG51bWJlcjsgdHJuRGlzY291bnRzUG9ydGlvbjogbnVtYmVyOyB0cm5Qcm9tb3Rpb25zUG9ydGlvbjogbnVtYmVyOyB9OyB9KSA9PiB7XHJcbiAgICAgICAgbGV0IHRheExpbmU6IFRheExpbmUgPSB7XHJcbiAgICAgICAgICBpdGVtTGluZUlkOiBwcm9kdWN0Lml0ZW1MaW5lSWQsXHJcbiAgICAgICAgICBWQVQ6IHByb2R1Y3Quc2VsZWN0ZWRWQVQgPyBwcm9kdWN0LnNlbGVjdGVkVkFUIDogMCxcclxuICAgICAgICAgIFZBVENvZGU6IHByb2R1Y3Quc2VsZWN0ZWRWQVRDb2RlLFxyXG4gICAgICAgICAgdGF4TGluZVRvdGFsOiAwLFxyXG4gICAgICAgICAgdGF4YWJsZUFtb3VudDogcHJvZHVjdC50b3RhbCxcclxuICAgICAgICAgIFByZVRheDogMFxyXG5cclxuICAgICAgICB9O1xyXG4gICAgICAgIGNvbnNvbGUuaW5mbyhcIlByb2R1Y3QgY29udHJpYnV0aW9uIDogaXRlbSBsaW5lIElEIDpjdXJyZW50IHRyYW5zYWN0aW9uIERldGFpbHNcIixcclxuICAgICAgICAgIHByb2R1Y3QuaXRlbUxpbmVJZCwgXCJ0YXggbGluZSA6XCIsIEpTT04uc3RyaW5naWZ5KHRheExpbmUpLCBKU09OLnN0cmluZ2lmeShiYXNrZXREZXRhaWxzLmJhc2tldFRvdGFsKSk7XHJcblxyXG4gICAgICAgIC8vc3RlcCAxXHJcbiAgICAgICAgLy8gaWYgVHJhbnNhY3Rpb24gRGlzY291bnQgYW5kL29yIHByb21vdGlvbiBhcHBsaWVkLCBmaW5kIG5ldCBzZWxsaW5nIHByaWNlIG9mIGVhY2ggcHJvZHVjdCBhcyB0YXhhYmxlYW1vdW50XHJcblxyXG4gICAgICAgIC8vSWYgdHJhbnNhY3Rpb24gZGlzY291bnQvcHJvbW90aW9uIGlzIGFwcGxpZWQgdGF4YWJsZSBhbW91bnQgc2hvdWxkIGJlIGRlZHVjdGluZyB0cmFuc2FjdGlvbiBwcm9tb3Rpb24gYW5kIHRyYW5zYWN0aW9uIGRpc2Fjb3VudCBwb3J0aW9uXHJcbiAgICAgICAgaWYgKHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eSAmJiBwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHkgPiAwKSB7XHJcblxyXG4gICAgICAgICAgdGF4TGluZS50YXhhYmxlQW1vdW50ID0gLU1hdGguYWJzKHRheExpbmUudGF4YWJsZUFtb3VudCAtIHByb2R1Y3QuaXRlbURpc2NvdW50cy5jdXJyZW50UmVmdW5kUG9ydGlvbik7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRheExpbmUudGF4YWJsZUFtb3VudCA9IHRheExpbmUudGF4YWJsZUFtb3VudCAtIHByb2R1Y3QuaXRlbURpc2NvdW50cy50cm5EaXNjb3VudHNQb3J0aW9uIC0gcHJvZHVjdC5pdGVtRGlzY291bnRzLnRyblByb21vdGlvbnNQb3J0aW9uO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy9zdGVwIDIgLSBmaW5kIHByZSB0YXhcclxuICAgICAgICB0YXhMaW5lLlByZVRheCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKCh0YXhMaW5lLnRheGFibGVBbW91bnQgKiAxMDApIC8gKDEwMCArIHRheExpbmUuVkFUKSk7XHJcblxyXG4gICAgICAgIC8vc3RlcCAzIC0gVXBkYXRlIHRheGJyZWFrZG93blxyXG4gICAgICAgIHRheEJyZWFrZG93bi50b3RhbFRheGFibGVBbW91bnQgKz0gdGF4TGluZS50YXhhYmxlQW1vdW50O1xyXG4gICAgICAgIHRheExpbmUudGF4YWJsZUFtb3VudCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRheExpbmUudGF4YWJsZUFtb3VudCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gc3RlcCA0IC0gdXBkYXRlIHRheCBMaW5lIHRvdGFsXHJcbiAgICAgICAgdGF4TGluZS50YXhMaW5lVG90YWwgPSAgdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIodGF4TGluZS50YXhhYmxlQW1vdW50IC0gdGF4TGluZS5QcmVUYXgpO1xyXG4gICAgICAgIHRheEJyZWFrZG93bi50YXhMaW5lcy5wdXNoKHRheExpbmUpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICB0YXhCcmVha2Rvd24udG90YWxUYXhhYmxlQW1vdW50ID0gdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIodGF4QnJlYWtkb3duLnRvdGFsVGF4YWJsZUFtb3VudCk7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy50YXhCcmVha2Rvd24gPSB0YXhCcmVha2Rvd247XHJcbiAgICBpZiAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMudGF4QnJlYWtkb3duICYmIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRheEJyZWFrZG93bi50YXhMaW5lcyAmJiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy50YXhCcmVha2Rvd24udGF4TGluZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LlZBVFRvdGFsID0gdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMudGF4QnJlYWtkb3duLnRheExpbmVzLnJlZHVjZShcclxuICAgICAgICAobjogYW55LCB7IHRheExpbmVUb3RhbCB9OiBhbnkpID0+IG4gKyB0YXhMaW5lVG90YWwsXHJcbiAgICAgICAgMFxyXG4gICAgICApKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LlZBVFRvdGFsID0gMC4wMDtcclxuICAgIH1cclxuXHJcbiAgICBjb25zb2xlLmxvZyhcImVCYXNrZXQ6YWZ0ZXIgY2FsY3VsYXRpbmcgdGF4IGN1cnJlbnR0cmFuc2FjdGlvbkRldGFpbHNcIiwgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMpXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHVwZGF0ZUN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNUb3RhbFRheFN1bW1hcnkoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gIFxyXG4gICAgY29uc29sZS5sb2coXCJUb3RhbCBUYXggU3VtbWVyeSBSZXF1ZXN0IDpcIiwgSlNPTi5zdHJpbmdpZnkodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMudGF4QnJlYWtkb3duKSk7XHJcblxyXG4gICAgbGV0IHRvdGFsVGF4U3VtbWFyeUFycmF5OiBUb3RhbFRheFN1bW1hcnlbXSA9IFtdXHJcbiAgICBsZXQgdG90YWxUYXhTdW1tYXJ5R3JvdXAgPSBbXVxyXG5cclxuICAgIGNvbnNvbGUubG9nKFwiVGF4IExpbmVzIGZvciBUb3RhbCBUYXggU3VtbWVyeSA6XCIsIEpTT04uc3RyaW5naWZ5KHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRheEJyZWFrZG93bi50YXhMaW5lcykpO1xyXG5cclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRheEJyZWFrZG93bi50YXhMaW5lcy5mb3JFYWNoKChlbGVtZW50OiB7IFZBVENvZGU6IGFueTsgVkFUOiBhbnk7IFByZVRheDogYW55OyB0YXhMaW5lVG90YWw6IGFueTsgfSkgPT4ge1xyXG4gICAgICBsZXQgVGF4U3VtbWFyeTogVG90YWxUYXhTdW1tYXJ5ID0ge1xyXG4gICAgICAgIFZBVENvZGU6XCJcIixcclxuICAgICAgICBWQVQ6IC0xMjM0NSxcclxuICAgICAgICBQcmVUYXhTdW06IDAsXHJcbiAgICAgICAgVGF4U3VtOiAwLFxyXG4gICAgICAgIFRYcmF0ZVN1bTogMFxyXG4gICAgICB9O1xyXG4gICAgICAgIFRheFN1bW1hcnkuVkFUQ29kZT1lbGVtZW50LlZBVENvZGU7XHJcbiAgICAgICAgVGF4U3VtbWFyeS5WQVQgPSBlbGVtZW50LlZBVDsgICAgICAgIFxyXG4gICAgICAgXHJcbiAgICAgICAgVGF4U3VtbWFyeS5QcmVUYXhTdW0gPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMihlbGVtZW50LlByZVRheCk7ICAgICAgICBcclxuICAgICAgICBUYXhTdW1tYXJ5LlRheFN1bSA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKGVsZW1lbnQudGF4TGluZVRvdGFsKTtcclxuICAgICAgICBUYXhTdW1tYXJ5LlRYcmF0ZVN1bSA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKFRheFN1bW1hcnkuUHJlVGF4U3VtICsgVGF4U3VtbWFyeS5UYXhTdW0pOyAgICAgXHJcbiAgICAgICAgdG90YWxUYXhTdW1tYXJ5QXJyYXkucHVzaChUYXhTdW1tYXJ5KTtcclxuICAgIH0pXHJcblxyXG4gICAgY29uc29sZS5sb2coXCJUb3RhbCBUYXggU3VtbWVyeSAgV2l0aG91dCBHcm91cGVkIDogXCIsIEpTT04uc3RyaW5naWZ5KHRvdGFsVGF4U3VtbWFyeUFycmF5KSk7XHJcbiAgICBcclxuICAgIHRvdGFsVGF4U3VtbWFyeUdyb3VwID0gdG90YWxUYXhTdW1tYXJ5QXJyYXkucmVkdWNlKChwcmVwYXJlZEFycmF5OmFueSxjdXJyZW50T2JqOmFueSkgPT4ge1xyXG4gICAgICBsZXQgaW5kID0gcHJlcGFyZWRBcnJheS5maW5kSW5kZXgoKHg6IHsgVkFUOiBhbnk7IH0pID0+IHguVkFUID09PSBjdXJyZW50T2JqLlZBVCk7XHJcbiAgICAgIGlmKGluZCA9PT0gLTEpe1xyXG4gICAgICAgIHByZXBhcmVkQXJyYXkucHVzaChjdXJyZW50T2JqKVxyXG4gICAgICB9ZWxzZSB7XHJcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlZBVENvZGUgPSBjdXJyZW50T2JqLlZBVENvZGU7XHJcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlZBVCA9IGN1cnJlbnRPYmouVkFUO1xyXG4gICAgICAgIHByZXBhcmVkQXJyYXlbaW5kXS5QcmVUYXhTdW0gKz0gY3VycmVudE9iai5QcmVUYXhTdW07XHJcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlRheFN1bSArPSBjdXJyZW50T2JqLlRheFN1bTtcclxuICAgICAgICBwcmVwYXJlZEFycmF5W2luZF0uVFhyYXRlU3VtICs9IGN1cnJlbnRPYmouVFhyYXRlU3VtO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBwcmVwYXJlZEFycmF5O1xyXG4gICAgfSxbXSlcclxuICAgIC8vIGxpc3RPZlRhZ3MubWFwKHggPT4gdW5pcXVlLmZpbHRlcihhID0+IGEubGFiZWwgPT0geC5sYWJlbCAmJiBhLmNvbG9yID09IHguY29sb3IpLmxlbmd0aCA+IDAgPyBudWxsIDogdW5pcXVlLnB1c2goeCkpO1xyXG5cclxuICAgIGNvbnNvbGUubG9nKFwiVG90YWwgIFRheCBTdW1tZXIgR3JvdXAgOlwiLCBKU09OLnN0cmluZ2lmeSh0b3RhbFRheFN1bW1hcnlHcm91cCkpO1xyXG5cclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRvdGFsVGF4U3VtbWFyeSA9IHRvdGFsVGF4U3VtbWFyeUdyb3VwO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcblxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogY3VycmVudCB0cmFuc2FjdGlvbiBEaXNvY3VudCBUb3RhbFxyXG4gICAqIEByZXR1cm5zIERpc2NvdW50IFRvdGFsXHJcbiAgICovXHJcbiAgdXBkYXRlQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc0Rpc2NvdW50VG90YWwoKSB7XHJcbiAgICBsZXQgcmVmdW5kVG90YWwgPSB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LnJlZnVuZFRvdGFsID8gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS5yZWZ1bmRUb3RhbCA6IDA7XHJcblxyXG4gICAgY29uc29sZS5sb2coXCJlLWJhc2tldDogdHJhbnNhY3Rpb24gYnVpbGRlciB1cGRhdGVDdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzRGlzY291bnRUb3RhbDogZGlzY291bnRUb3RhbFwiLCByZWZ1bmRUb3RhbCwgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS5iYXNrZXRUb3RhbCwgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS5zYWxlVG90YWwpO1xyXG4gICAgY29uc3QgZGlzY291bnRUb3RhbCA9XHJcbiAgICAgIE1hdGguYWJzKFxyXG4gICAgICAgIE1hdGguYWJzKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmJhc2tldFN1bW1hcnkuc2FsZVRvdGFsKSAtXHJcbiAgICAgICAgKE1hdGguYWJzKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmJhc2tldFN1bW1hcnkuYmFza2V0VG90YWwpICsgTWF0aC5hYnMocmVmdW5kVG90YWwpKVxyXG4gICAgICApO1xyXG4gICAgY29uc29sZS5sb2coXCJlLWJhc2tldDogdHJhbnNhY3Rpb24gYnVpbGRlciB1cGRhdGVDdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzRGlzY291bnRUb3RhbDogZGlzY291bnRUb3RhbFwiLCBkaXNjb3VudFRvdGFsKVxyXG4gICAgcmV0dXJuIE51bWJlcihkaXNjb3VudFRvdGFsLnRvRml4ZWQoMikpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgKiBjdXJyZW50IHRyYW5zYWN0aW9uIFJlZnVuZCBUb3RhbFxyXG4gICogQHJldHVybnMgUmVmdW5kIFRvdGFsXHJcbiAgKi9cclxuICB1cGRhdGVDdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzUmVmdW5kVG90YWwoKSB7XHJcbiAgICBsZXQgdG90YWxSZWZ1bmQgPSAwO1xyXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnByb2R1Y3RzLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICBjb25zdCBwcm9kdWN0OiBQcm9kdWN0ID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMucHJvZHVjdHNbaW5kZXhdO1xyXG4gICAgICBpZiAocHJvZHVjdC5yZWZ1bmRlZFRvdGFsKSB7XHJcbiAgICAgICAgdG90YWxSZWZ1bmQgPSB0b3RhbFJlZnVuZCArIHByb2R1Y3QucmVmdW5kZWRUb3RhbDtcclxuICAgICAgfVxyXG4gICAgICBjb25zb2xlLmxvZyhcImViYXNrZXQgOiB0cmFuc2FjdGlvbiBTZXJ2aWNlOiB0b3RhbFJlZnVuZCBmb3IgQ3VycmVudCBUcmFuc2FjdGlvbkRldGFpbHNcIiArIHRvdGFsUmVmdW5kKVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRvdGFsUmVmdW5kO1xyXG4gIH1cclxuXHJcblxyXG5cclxuICAvKipcclxuICAgKiBCYXNrZXRzIHN1bW1hcnlcclxuICAgKiBAcGFyYW0gYmFza2V0RGV0YWlsc1xyXG4gICAqIEByZXR1cm5zIHN1bW1hcnlcclxuICAgKi9cclxuICBiYXNrZXRTdW1tYXJ5KGJhc2tldERldGFpbHM6IEJhc2tldCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsID0gdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbChiYXNrZXREZXRhaWxzLmJhc2tldFRvdGFsKTtcclxuXHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5zYWxlVG90YWwgPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMih0aGlzLnVwZGF0ZVNhbGVUb3RhbChcclxuICAgICAgYmFza2V0RGV0YWlsc1xyXG4gICAgKSk7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5yZWZ1bmRUb3RhbCA9IHRoaXMuZ2V0UmVmdW5kVG90YWwoKTtcclxuICAgIGlmIChcclxuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnQgfHxcclxuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lUHJvbW90aW9uXHJcbiAgICApIHtcclxuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuZGlzY291bnRUb3RhbCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRoaXMudXBkYXRlRGlzY291bnRUb3RhbCgpKTtcclxuICAgIH1cclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LnRvdGFsSXRlbXMgPSBiYXNrZXREZXRhaWxzLnF1YW50aXR5O1xyXG5cclxuXHJcbiAgICBpZiAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50YXhCcmVha2Rvd24pIHtcclxuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuVkFUVG90YWwgPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMih0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRheEJyZWFrZG93bi50YXhMaW5lcy5yZWR1Y2UoXHJcbiAgICAgICAgKG46IGFueSwgeyB0YXhMaW5lVG90YWwgfTogYW55KSA9PiBuICsgdGF4TGluZVRvdGFsLFxyXG4gICAgICAgIDBcclxuICAgICAgKSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuVkFUVG90YWwgPSAwLjAwO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnNvbGUuaW5mbyhcImViYXNrZXQ6IGJhc2tldHN1bW1hcnkgdXBkYXRlZCBpbiB0cmFuc2FjdGlvbiBkb2N1bWVudDogXCIsIEpTT04uc3RyaW5naWZ5KHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5KSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExpbmUgRGlzY291bnRcclxuICAgKiBAcGFyYW0gYmFza2V0RGV0YWlsc1xyXG4gICAqIEByZXR1cm5zIGxpbmUgRGlzY291bnRcclxuICAgKi9cclxuICBsaW5lRGlzY291bnQoYmFza2V0RGV0YWlsczogQmFza2V0KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnQgPSBbXTtcclxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBiYXNrZXREZXRhaWxzLnByb2R1Y3RzLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICBjb25zdCBlbGVtZW50ID0gYmFza2V0RGV0YWlscy5wcm9kdWN0c1tpbmRleF07XHJcbiAgICAgIGlmIChlbGVtZW50LmxpbmVEaXNjb3VudCkge1xyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50LnB1c2goZWxlbWVudC5saW5lRGlzY291bnQpO1xyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50ID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnQucmVkdWNlKFxyXG4gICAgICAgICAgKGFjYzogYW55W10sIHZhbDogeyBpdGVtTGluZUlkOiBhbnk7IH0pID0+IHtcclxuICAgICAgICAgICAgaWYgKCFhY2MuZmluZCgoZWw6IHsgaXRlbUxpbmVJZDogYW55OyB9KSA9PiBlbC5pdGVtTGluZUlkID09PSB2YWwuaXRlbUxpbmVJZCkpIHtcclxuICAgICAgICAgICAgICBhY2MucHVzaCh2YWwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBhY2M7XHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgICAgW11cclxuICAgICAgICApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBjb25zb2xlLmluZm8oXHJcbiAgICAgIC8vICAgXCJlLWJhc2tldCA6bGluZSBkaXNjb3VudCB1cGRhdGVkIGluIHRyYW5zYWN0aW9uIGRvY3VtZW50XCIsXHJcbiAgICAgIC8vICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnRcclxuICAgICAgLy8gKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogZXhjaGFuZ2VcclxuICAgKiBAcGFyYW0gYmFza2V0RGV0YWlsc1xyXG4gICAqIEByZXR1cm5zIGV4Y2hhbmdlIFxyXG4gICAqL1xyXG4gIGV4Y2hhbmdlKGJhc2tldERldGFpbHM6IEJhc2tldCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQuZXhjaGFuZ2UgPSBiYXNrZXREZXRhaWxzLmV4Y2hhbmdlICYmIGJhc2tldERldGFpbHMuZXhjaGFuZ2UubGVuZ3RoID4gMCA/IFsuLi5iYXNrZXREZXRhaWxzLmV4Y2hhbmdlXSA6IFtdO1xyXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGJhc2tldERldGFpbHMucHJvZHVjdHMubGVuZ3RoOyBpbmRleCsrKSB7XHJcblxyXG4gICAgICBjb25zdCBlbGVtZW50OiBhbnkgPSBiYXNrZXREZXRhaWxzLnByb2R1Y3RzW2luZGV4XTtcclxuICAgICAgaWYgKGVsZW1lbnQuZXhjaGFuZ2UgIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgY29uc3QgaXNQcmVzZW50ID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5leGNoYW5nZS5zb21lKChlbDogeyBleGNoYW5nZUlkOiBhbnk7IH0pID0+IGVsLmV4Y2hhbmdlSWQgPT09IGVsZW1lbnQuZXhjaGFuZ2UuZXhjaGFuZ2VJZCk7XHJcbiAgICAgICAgaWYgKCFpc1ByZXNlbnQpIHtcclxuICAgICAgICAgIGxldCBleGNoYW5nZUl0ZW1zID0gW107XHJcbiAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGVsZW1lbnQuZXhjaGFuZ2UubmV3SXRlbXMubGVuZ3RoOyBqKyspIHtcclxuICAgICAgICAgICAgY29uc3QgaXRlbSA9IGVsZW1lbnQuZXhjaGFuZ2UubmV3SXRlbXNbal07XHJcbiAgICAgICAgICAgIGxldCBuZXdJdGVtczogYW55ID0geyBsaW5lSXRlbUlkOiBpdGVtLml0ZW1MaW5lSWQsIFF1YW50aXR5OiBpdGVtLnF1YW50aXR5IH1cclxuICAgICAgICAgICAgZXhjaGFuZ2VJdGVtcy5wdXNoKG5ld0l0ZW1zKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGVsZW1lbnQuZXhjaGFuZ2UubmV3SXRlbXMgPSBbLi4uZXhjaGFuZ2VJdGVtc107XHJcbiAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmV4Y2hhbmdlLnB1c2goZWxlbWVudC5leGNoYW5nZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGNvbnNvbGUubG9nKFxyXG4gICAgICAgIFwiZS1iYXNrZXQgOlRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0IGV4Y2hhbmdlXCIsXHJcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5leGNoYW5nZSlcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICogYWRkIHByZXZpb3VzIGV4Y2hhbmdlIGRhdGFcclxuICAqIEBwYXJhbSBvcmlnaW5hbFRyYW5zYWN0aW9uRG9jdW1lbnRcclxuICAqIEByZXR1cm5zIGxpbmUgUHJvbW90aW9uc1xyXG4gICovXHJcbiAgYWRkRXhjaGFuZ2VEYXRhKG9yaWdpbmFsVHJhbnNhY3Rpb25Eb2N1bWVudDogVHJhbnNhY3Rpb25Eb2N1bWVudCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQuZXhjaGFuZ2UgPSBvcmlnaW5hbFRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmV4Y2hhbmdlID8gWy4uLm9yaWdpbmFsVHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQuZXhjaGFuZ2VdIDogbnVsbDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogbGluZSBQcm9tb3Rpb25zXHJcbiAgICogQHBhcmFtIGJhc2tldERldGFpbHNcclxuICAgKiBAcmV0dXJucyBsaW5lIFByb21vdGlvbnNcclxuICAgKi9cclxuICBsaW5lUHJvbW90aW9uKGJhc2tldERldGFpbHM6IEJhc2tldCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbiA9IFtdO1xyXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGJhc2tldERldGFpbHMucHJvZHVjdHMubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBiYXNrZXREZXRhaWxzLnByb2R1Y3RzW2luZGV4XTtcclxuICAgICAgaWYgKGVsZW1lbnQubGluZVByb21vdGlvbnMpIHtcclxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb24ucHVzaChcclxuICAgICAgICAgIGVsZW1lbnQubGluZVByb21vdGlvbnNcclxuICAgICAgICApO1xyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbiA9IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbi5yZWR1Y2UoXHJcbiAgICAgICAgICAoYWNjOiBhbnlbXSwgdmFsOiB7IGl0ZW1MaW5lSWQ6IGFueTsgfSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIWFjYy5maW5kKChlbDogeyBpdGVtTGluZUlkOiBhbnk7IH0pID0+IGVsLml0ZW1MaW5lSWQgPT09IHZhbC5pdGVtTGluZUlkKSkge1xyXG4gICAgICAgICAgICAgIGFjYy5wdXNoKHZhbCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGFjYztcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBbXVxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogdHJhbnNhY3Rpb24gUHJvbW90aW9uXHJcbiAgICogQHBhcmFtIGJhc2tldERldGFpbHNcclxuICAgKiBAcmV0dXJucyB0cmFuc2FjdGlvbiBQcm9tb3Rpb25cclxuICAgKi9cclxuICB0cmFuc2FjdGlvblByb21vdGlvbihiYXNrZXREZXRhaWxzOiBCYXNrZXQpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICBpZiAoYmFza2V0RGV0YWlscy50cmFuc2FjdGlvblByb21vdGlvbikge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uID1cclxuICAgICAgICBiYXNrZXREZXRhaWxzLnRyYW5zYWN0aW9uUHJvbW90aW9uO1xyXG4gICAgICAvLyAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBiYXNrZXREZXRhaWxzLlRyYW5zYWN0aW9uRGlzY291bnQubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgIC8vICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50cmFuc2FjdGlvblByb21vdGlvbi5wdXNoKGVsZW1lbnQubGluZVByb21vdGlvbnMpXHJcbiAgICAgIC8vICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50cmFuc2FjdGlvblByb21vdGlvbiA9ICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb25zLnJlZHVjZSgoYWNjLCB2YWwpID0+IHtcclxuICAgICAgLy8gICAgIGlmICghYWNjLmZpbmQoZWwgPT4gZWwuaXRlbUxpbmVJZCA9PT0gdmFsLml0ZW1MaW5lSWQpKSB7XHJcbiAgICAgIC8vICAgICAgIGFjYy5wdXNoKHZhbCk7XHJcbiAgICAgIC8vICAgICB9XHJcbiAgICAgIC8vICAgICByZXR1cm4gYWNjO1xyXG4gICAgICAvLyAgIH0sIFtdKTtcclxuICAgICAgLy8gfVxyXG4gICAgICBjb25zb2xlLmxvZyhcclxuICAgICAgICBcImUtYmFza2V0IDpUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlcjogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50cmFuc2FjdGlvblByb21vdGlvblwiLFxyXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb24pXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHRyYW5zYWN0aW9uRGlzY291bnQoYmFza2V0RGV0YWlsczogQmFza2V0KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgaWYgKGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudCkge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQgPVxyXG4gICAgICAgIGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudDtcclxuXHJcbiAgICAgIGNvbnNvbGUubG9nKFxyXG4gICAgICAgIFwiZS1iYXNrZXQgOlRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyOiB0cmFuc2FjdGlvbiBEaXNjb3VudFwiLFxyXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25EaXNjb3VudClcclxuICAgICAgKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUGF5bWVudHMgZGV0YWlsc1xyXG4gICAqIEBwYXJhbSBwYXltZW50RGV0YWlsc1xyXG4gICAqIEByZXR1cm5zXHJcbiAgICovXHJcbiAgcGF5bWVudERldGFpbHMocGF5bWVudERldGFpbHM6IGFueSkge1xyXG4gICAgY29uc29sZS5pbmZvKFwiZWJhc2tldCA6IHBheW1lbnQgZGV0YWlscyBhZnRlciB0cmFuc2FjdGlvbiBjb21wbGV0ZWRcIixKU09OLnN0cmluZ2lmeShwYXltZW50RGV0YWlscykpO1xyXG4gICAgXHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQucGF5bWVudERldGFpbHMgPSBwYXltZW50RGV0YWlscztcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcblxyXG4gIC8qKlxyXG4gICAqIFBheW1lbnRzIGRldGFpbHNcclxuICAgKiBAcGFyYW0gcGF5bWVudERldGFpbHNcclxuICAgKiBAcmV0dXJuc1xyXG4gICAqL1xyXG4gICBzcGxpdFBheW1lbnQoc3BsaXRQYXltZW50OiBib29sZWFuKSB7ICAgIFxyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnNwbGl0UGF5bWVudCA9IHNwbGl0UGF5bWVudDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH0gXHJcblxyXG4gICAvKipcclxuICAgKiBQYXltZW50cyBkZXRhaWxzXHJcbiAgICogQHBhcmFtIHBheW1lbnREZXRhaWxzXHJcbiAgICogQHJldHVybnNcclxuICAgKi9cclxuICAgIGlzUGF5bWVudENvbXBsZXRlZChpc1BheW1lbnRDb21wbGV0ZWQ6IGJvb2xlYW4pIHtcclxuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmlzUGF5bWVudENvbXBsZXRlZCA9IGlzUGF5bWVudENvbXBsZXRlZDtcclxuICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9IFxyXG4gIFxyXG5cclxuXHJcblxyXG4gIC8qKlxyXG4gICAqIEJhc2VzIGN1cnJlbmN5XHJcbiAgICogQHBhcmFtIGN1cnJlbmN5XHJcbiAgICogQHJldHVybnMgY3VycmVuY3lcclxuICAgKi9cclxuICBiYXNlQ3VycmVuY3koY3VycmVuY3k6IGFueSk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNlQ3VycmVuY3kgPSBjdXJyZW5jeTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgKiBnaWZ0IG9wdGlvbiBhdFxyXG4gICogQHJldHVybnMgYXRcclxuICAqL1xyXG4gIGdpZnRPcHRpb24oZ2lmdDogYW55KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgY29uc29sZS5sb2coXHJcbiAgICAgIFwiZS1iYXNrZXQgOlRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuZ2lmdG9wdGlvblwiLFxyXG4gICAgICBnaWZ0XHJcbiAgICApO1xyXG4gICAgaWYgKGdpZnQpIHtcclxuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmdpZnRlZFJlY2VpcHQgPSBnaWZ0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIC8qKlxyXG5cclxuLyoqXHJcbiAqIG1hbnVhbCBEaXNjb3VudFxyXG4gKiBAcGFyYW0gZGlzY291bnREYXRhXHJcbiAqIEByZXR1cm5zXHJcbiAqL1xyXG5cclxuICAvLyBtYW51YWxEaXNjb3VudChkaXNjb3VudERhdGEgOiBiYXNrZXREaXNjb3VudCk6VHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gIC8vICAgbGV0IHNhbGVUb3RhbCA9ICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5iYXNrZXRUb3RhbDtcclxuICAvLyAgIGlmKGRpc2NvdW50RGF0YS5kaXNjb3VudFR5cGUgPT0nUGVyY2VudCcpe1xyXG4gIC8vICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5iYXNrZXRUb3RhbCA9IHNhbGVUb3RhbC0oc2FsZVRvdGFsKihkaXNjb3VudERhdGEuZGlzY291bnRBbW91bnQvMTAwKSk7XHJcbiAgLy8gICAgIGRpc2NvdW50RGF0YS5kaXNjb3VudEFtb3VudCA9IC0xKihzYWxlVG90YWwtdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuYmFza2V0VG90YWwpO1xyXG4gIC8vICAgfWVsc2Uge1xyXG4gIC8vICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5iYXNrZXRUb3RhbCA9c2FsZVRvdGFsLWRpc2NvdW50RGF0YS5kaXNjb3VudEFtb3VudDtcclxuICAvLyAgICAgZGlzY291bnREYXRhLmRpc2NvdW50QW1vdW50ID0gLTEqZGlzY291bnREYXRhLmRpc2NvdW50QW1vdW50O1xyXG4gIC8vICAgfVxyXG4gIC8vICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnRyYW5zYWN0aW9uRGlzY291bnQucHVzaChkaXNjb3VudERhdGEpO1xyXG4gIC8vICAgcmV0dXJuIHRoaXM7XHJcblxyXG4gIC8vIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVHlwZXMgdHJhbnNhY3Rpb24gZG9jdW1lbnQgYnVpbGRlclxyXG4gICAqIEBwYXJhbSB0XHJcbiAgICogQHJldHVybnMgdHlwZVxyXG4gICAqL1xyXG4gIHR5cGUodDogYW55KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnR5cGUgPSB0O1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIE9wZXJhdGlvbnMgc3RhdHVzXHJcbiAgICogQHBhcmFtIG9cclxuICAgKiBAcmV0dXJucyBzdGF0dXNcclxuICAgKi9cclxuICBvcGVyYXRpb25TdGF0dXMobzogYW55KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50Lm9wZXJhdGlvblN0YXR1cyA9IG87XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlZCBhdFxyXG4gICAqIEByZXR1cm5zIGF0XHJcbiAgICovXHJcbiAgY3JlYXRlZEF0KCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmNyZWF0ZWRBdCA9IGRhdGUudG9JU09TdHJpbmcoKTtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC51cGRhdGVkQXQgPSBkYXRlLnRvSVNPU3RyaW5nKCk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcbiAgLyoqXHJcbiAgICogVXBkYXRlZCBhdFxyXG4gICAqIEByZXR1cm5zIGF0XHJcbiAgICovXHJcbiAgdXBkYXRlZEF0KCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnVwZGF0ZWRBdCA9IGRhdGUudG9JU09TdHJpbmcoKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuICAvKipcclxuICAgKiB0cmFuc3NhY3Rpb24gY29tcGxldGlvbiBhdFxyXG4gICAqIEByZXR1cm5zIHRyYW5zYWN0aW9uIGNvbXBsZXRpb24gZGF0ZVxyXG4gICAqL1xyXG4gIHRyYW5zYWN0aW9uQ29tcGxldGVkQXQoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKCk7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHJhbnNDb21wbGV0ZWRBdCA9IGRhdGUudG9JU09TdHJpbmcoKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBCdWlsZHMgdHJhbnNhY3Rpb24gZG9jdW1lbnQgYnVpbGRlclxyXG4gICAqIEByZXR1cm5zIGJ1aWxkXHJcbiAgICovXHJcbiAgYnVpbGQoKTogVHJhbnNhY3Rpb25Eb2N1bWVudCB7XHJcbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2FsZXMgdG90YWwgaW4gcmVmdW5kXHJcbiAgICogQHBhcmFtIHNhbGVUb3RhbFxyXG4gICAqIEByZXR1cm5zIHRvdGFsIGluIHJlZnVuZFxyXG4gICAqL1xyXG4gIHNhbGVUb3RhbEluUmVmdW5kKHNhbGVUb3RhbDogbnVtYmVyKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnNhbGVUb3RhbCA9IHNhbGVUb3RhbDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0cyBiYXNrZXQgZGV0YWlsc1xyXG4gICAqIEByZXR1cm5zIGJhc2tldCBkZXRhaWxzXHJcbiAgICovXHJcbiAgZ2V0QmFza2V0RGV0YWlscygpOiBCYXNrZXQge1xyXG4gICAgY29uc29sZS5pbmZvKFwiZWJhc2tldDogR2V0dGluZyBCYXNrZXQgZm9yIHRyYW5zYWN0aW9uRG9jdW1lbnRcIiwgSlNPTi5zdHJpbmdpZnkodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50KSk7XHJcblxyXG4gICAgbGV0IGJhc2tldDogQmFza2V0ID0ge1xyXG4gICAgICBzdWJzaWRpYXJ5SWQgOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuc3Vic2lkaWFyeUlkLFxyXG4gICAgICB0cmFuc2FjdGlvbkRpc2NvdW50OiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQsXHJcbiAgICAgIHRyYW5zYWN0aW9uUHJvbW90aW9uOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uLFxyXG4gICAgICB0cmFuc2FjdGlvbklkOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHJhbnNhY3Rpb25JZCxcclxuICAgICAgb2ZmbGluZVRyYW5zYWN0aW9uSWQ6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5vZmZsaW5lVHJhbnNhY3Rpb25JZCxcclxuICAgICAgdG90YWw6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsLFxyXG4gICAgICBiYXNrZXRUb3RhbDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuYmFza2V0VG90YWwsXHJcbiAgICAgIGRpc2NvdW50VG90YWw6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmRpc2NvdW50VG90YWwsXHJcbiAgICAgIHNhbGVUb3RhbDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuc2FsZVRvdGFsLFxyXG4gICAgICByZWZ1bmRUb3RhbDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkucmVmdW5kVG90YWwsXHJcbiAgICAgIHF1YW50aXR5OiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS50b3RhbEl0ZW1zLFxyXG4gICAgICBwcm9kdWN0czogW10sXHJcbiAgICAgIGJhc2VDdXJyZW5jeTogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2VDdXJyZW5jeSxcclxuICAgICAgY3VzdG9tZXI6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXN0b21lcixcclxuICAgIH07XHJcblxyXG4gICAgYmFza2V0LnByb2R1Y3RzID0gW10gYXMgUHJvZHVjdFtdO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5wcm9kdWN0cy5mb3JFYWNoKChwcm9kdWN0OiB7IFNLVTogYW55OyBiYXJDb2RlOiBhbnk7IGJhcmNvZGVzOiBhbnk7IGRlc2NyaXB0aW9uOiBhbnk7IGltYWdlVXJsczogYW55OyB0b3RhbExpbmVQcmljZTogYW55OyBpdGVtTGluZUlkOiBhbnk7IGV4Y2x1ZGVQcm9tb3Rpb246IGFueTsgcHJpY2U6IGFueTsgcXVhbnRpdHk6IGFueTsgc2VsZWN0ZWRSUlBQcmljZTogYW55OyBmdWxsZmlsbWVudElkOiBhbnk7IGZ1bGxmaWxtZW50TG9jYXRpb25OYW1lOiBhbnk7IGRlbGl2ZXJ5R3JvdXA6IHN0cmluZzsgbGVhZFRpbWU6IGFueTsgZGVsaXZlcnlNZXRob2Q6IGFueTsgZ2lmdENhcmQ6IGFueTsgZ2lmdENhcmRFeHBpcnlEYXRlOiBhbnk7IGdpZnRDYXJkTnVtYmVySXNzdWVkOiBhbnk7IGdpZnRDYXJkUmVjaXBpZW50RW1haWw6IGFueTsgZ2lmdENhcmRSZWNpcGllbnROYW1lOiBhbnk7IHJlZnVuZGVkVG90YWw6IGFueTsgcmVmdW5kZWRRdWFudGl0eTogbnVtYmVyOyByZWZ1bmRlZFJlYXNvbkRlc2NyaXB0aW9uOiBhbnk7IHJlZnVuZGVkUmVhc29uOiBhbnk7IHJlZnVuZGVkUHJvbW90aW9uYWxRdWFudGl0eTogYW55OyBpc0xhc3RFeGNoYW5nZWQ6IGFueTsgfSwgaW5kZXg6IGFueSkgPT4ge1xyXG4gICAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShwcm9kdWN0KSwgXCJlYmFza2V0OiBiYXNrZXQgZGV0YWlsIHVwZGF0ZSBpbiBiYXNrZXRcIik7XHJcbiAgICAgIGNvbnN0IHAgPSB7fSBhcyBhbnk7XHJcbiAgICAgIHAuU0tVID0gcHJvZHVjdC5TS1U7XHJcbiAgICAgIHAuYmFyY29kZSA9IHByb2R1Y3QuYmFyQ29kZTtcclxuICAgICAgcC5iYXJjb2RlcyA9IHByb2R1Y3QuYmFyY29kZXM7XHJcblxyXG4gICAgICBwLmRlc2NyaXB0aW9uID0gcHJvZHVjdC5kZXNjcmlwdGlvbjtcclxuICAgICAgcC5pbWFnZVVybHMgPSBwcm9kdWN0LmltYWdlVXJscztcclxuICAgICAgcC5jdXJyZW5jeSA9IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNlQ3VycmVuY3k7XHJcbiAgICAgIHAudG90YWxMaW5lUHJpY2UgPSBwcm9kdWN0LnRvdGFsTGluZVByaWNlO1xyXG4gICAgICBwLml0ZW1MaW5lSWQgPSBOdW1iZXIocHJvZHVjdC5pdGVtTGluZUlkKTtcclxuICAgICAgcC5leGNsdWRlUHJvbW90aW9uID0gcHJvZHVjdC5leGNsdWRlUHJvbW90aW9uO1xyXG5cclxuICAgICAgcC5zZWxlY3RlZFByaWNlID0gcHJvZHVjdC5wcmljZTtcclxuICAgICAgcC5xdWFudGl0eSA9IHByb2R1Y3QucXVhbnRpdHk7XHJcbiAgICAgIHAudG90YWwgPSBwcm9kdWN0LnRvdGFsTGluZVByaWNlO1xyXG4gICAgICBwLnNlbGVjdGVkUlJQUHJpY2UgPSBwcm9kdWN0LnNlbGVjdGVkUlJQUHJpY2U7XHJcblxyXG4gICAgICBwLmZ1bGxmaWxtZW50SWQgPSBwcm9kdWN0LmZ1bGxmaWxtZW50SWQ7XHJcbiAgICAgIHAuZnVsbGZpbG1lbnRMb2NhdGlvbk5hbWUgPSBwcm9kdWN0LmZ1bGxmaWxtZW50TG9jYXRpb25OYW1lO1xyXG4gICAgICBwLmRlbGl2ZXJ5R3JvdXAgPSBwcm9kdWN0LmRlbGl2ZXJ5R3JvdXAgfHwgXCIxXCI7XHJcbiAgICAgIHAubGVhZFRpbWUgPSBwcm9kdWN0LmxlYWRUaW1lO1xyXG4gICAgICBwLmRlbGl2ZXJ5TWV0aG9kID0gcHJvZHVjdC5kZWxpdmVyeU1ldGhvZCB8fCBERUxJVkVSWV9NRVRIT0RTLkNPTExFQ1RfRlJPTV9TVE9SRS50b1N0cmluZygpO1xyXG5cclxuICAgICAgaWYocC5mdWxsZmlsbWVudElkICE9IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5zdG9yZUlkKVxyXG4gICAgICB7XHJcbiAgICAgICAgcC5pc1dlYk9yZGVyID0gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgXHJcbiAgICAgIHAuZ2lmdENhcmQgPSBwcm9kdWN0LmdpZnRDYXJkO1xyXG4gICAgICBwLmdpZnRDYXJkRXhwaXJ5RGF0ZSA9IHByb2R1Y3QuZ2lmdENhcmRFeHBpcnlEYXRlO1xyXG4gICAgICBwLmdpZnRDYXJkTnVtYmVySXNzdWVkID0gcHJvZHVjdC5naWZ0Q2FyZE51bWJlcklzc3VlZDtcclxuICAgICAgcC5naWZ0Q2FyZFJlY2lwaWVudEVtYWlsID0gcHJvZHVjdC5naWZ0Q2FyZFJlY2lwaWVudEVtYWlsO1xyXG4gICAgICBwLmdpZnRDYXJkUmVjaXBpZW50TmFtZSA9IHByb2R1Y3QuZ2lmdENhcmRSZWNpcGllbnROYW1lO1xyXG4gICAgICBcclxuICAgICAgaWYgKFxyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50ICYmXHJcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnQubGVuZ3RoID4gMFxyXG4gICAgICApIHtcclxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudC5mb3JFYWNoKChsaW5lRGlzY291bnQ6IHsgaXRlbUxpbmVJZDogeyB0b1N0cmluZzogKCkgPT4gYW55OyB9OyBkaXNjb3VudGVkTGluZVByaWNlOiBhbnk7IH0pID0+IHtcclxuICAgICAgICAgIGlmIChwcm9kdWN0Lml0ZW1MaW5lSWQgPT09IGxpbmVEaXNjb3VudC5pdGVtTGluZUlkLnRvU3RyaW5nKCkpIHtcclxuICAgICAgICAgICAgcC5saW5lRGlzY291bnQgPSBsaW5lRGlzY291bnQ7XHJcbiAgICAgICAgICAgIHAudG90YWwgPSBsaW5lRGlzY291bnQuZGlzY291bnRlZExpbmVQcmljZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKFxyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbiAmJlxyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbi5sZW5ndGggPiAwXHJcbiAgICAgICkge1xyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbi5mb3JFYWNoKChsaW5lUHJvbW90aW9uOiB7IGl0ZW1MaW5lSWQ6IHsgdG9TdHJpbmc6ICgpID0+IGFueTsgfTsgcHJvbW90aW9uTGluZVByaWNlOiBhbnk7IH0pID0+IHtcclxuICAgICAgICAgIGlmIChwcm9kdWN0Lml0ZW1MaW5lSWQgPT09IGxpbmVQcm9tb3Rpb24uaXRlbUxpbmVJZC50b1N0cmluZygpKSB7XHJcbiAgICAgICAgICAgIHAubGluZVByb21vdGlvbnMgPSBsaW5lUHJvbW90aW9uO1xyXG4gICAgICAgICAgICBwLnRvdGFsID0gbGluZVByb21vdGlvbi5wcm9tb3Rpb25MaW5lUHJpY2U7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChcclxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRheEJyZWFrZG93biAmJlxyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudGF4QnJlYWtkb3duLnRheExpbmVzLmxlbmd0aCA+IDBcclxuICAgICAgKSB7XHJcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50YXhCcmVha2Rvd24udGF4TGluZXMuZm9yRWFjaCgodGF4TGluZTogeyBpdGVtTGluZUlkOiB7IHRvU3RyaW5nOiAoKSA9PiBhbnk7IH07IFZBVDogYW55OyBWQVRDb2RlOiBhbnk7IH0pID0+IHtcclxuICAgICAgICAgIGlmIChwcm9kdWN0Lml0ZW1MaW5lSWQgJiYgcHJvZHVjdC5pdGVtTGluZUlkID09PSB0YXhMaW5lLml0ZW1MaW5lSWQudG9TdHJpbmcoKSkge1xyXG4gICAgICAgICAgICBwLnNlbGVjdGVkVkFUID0gdGF4TGluZS5WQVQ7XHJcbiAgICAgICAgICAgIHAuc2VsZWN0ZWRWQVRDb2RlID0gdGF4TGluZS5WQVRDb2RlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnR5cGUgPT09IFRSQU5TQUNUSU9OX1RZUEUuUkVGVU5EKSB7XHJcbiAgICAgICAgcC50b3RhbCA9IHByb2R1Y3QucmVmdW5kZWRUb3RhbDtcclxuICAgICAgfSBlbHNlIGlmICgodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnR5cGUgPT09IFRSQU5TQUNUSU9OX1RZUEUuU0FMRV9SRUZVTkQgfHwgVFJBTlNBQ1RJT05fVFlQRS5TQUxFX0VYQ0hBTkdFKSAmJiBwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHkgPiAwKSB7XHJcbiAgICAgICAgcC5yZWZ1bmRlZFJlYXNvbkRlc2NyaXB0aW9uID0gcHJvZHVjdC5yZWZ1bmRlZFJlYXNvbkRlc2NyaXB0aW9uO1xyXG4gICAgICAgIHAucmVmdW5kZWRSZWFzb24gPSBwcm9kdWN0LnJlZnVuZGVkUmVhc29uO1xyXG4gICAgICAgIGlmICghcC5yZWZ1bmRlZFJlYXNvbkRlc2NyaXB0aW9uKSB7XHJcbiAgICAgICAgICBwLnJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb24gPSBwLnJlZnVuZGVkUmVhc29uO1xyXG4gICAgICAgIH1cclxuICAgICAgICBwLnJlZnVuZGVkUXVhbnRpdHkgPSBwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHk7XHJcbiAgICAgICAgcC5yZWZ1bmRQcm9tb3Rpb25hbFF1YW50aXR5ID0gcHJvZHVjdC5yZWZ1bmRlZFByb21vdGlvbmFsUXVhbnRpdHk7XHJcbiAgICAgICAgcC5yZWZ1bmRlZFRvdGFsID0gcHJvZHVjdC5yZWZ1bmRlZFRvdGFsO1xyXG4gICAgICAgIHAudG90YWwgLT0gTWF0aC5hYnMocC5yZWZ1bmRlZFRvdGFsKTtcclxuICAgICAgICBwLmlzTGFzdEV4Y2hhbmdlZCA9IHByb2R1Y3QuaXNMYXN0RXhjaGFuZ2VkO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnR5cGUgPT09IFRSQU5TQUNUSU9OX1RZUEUuUkVGVU5EKSB7XHJcbiAgICAgICAgaWYgKHAudG90YWwgPiAwKSB7XHJcbiAgICAgICAgICBwLnRvdGFsICo9IC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgYmFza2V0LnByb2R1Y3RzLnB1c2gocCk7XHJcblxyXG4gICAgfSk7XHJcblxyXG4gICAgYmFza2V0ID0gdGhpcy5nZXRUcmFuc2FjdGlvbkRpc2NvdW50QW5kVHJhbnNhY3Rpb25Qcm9tb3Rpb25Qb3J0aW9uKGJhc2tldCk7XHJcbiAgICBiYXNrZXQudG90YWwgPSAoYmFza2V0LmJhc2tldFRvdGFsIHx8IDApICsgdGhpcy5nZXRUb3RhbERpc2NvdW50V2l0aFRyYW5zYWN0aW9uRGlzY291bnRzQW5kUHJvbW90aW9ucyhiYXNrZXQpO1xyXG4gICAgaWYgKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC50eXBlID09PSBUUkFOU0FDVElPTl9UWVBFLlNBTEVfUkVGVU5EKSB7XHJcbiAgICAgIGJhc2tldC5xdWFudGl0eSA9IHRoaXMuZ2V0UmVmdW5kZWRUb3RhbFdpdGhRdWFudGl0eShiYXNrZXQpO1xyXG4gICAgfVxyXG4gICAgY29uc29sZS5pbmZvKFwiZWJhc2tldDogQmFza2V0IGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5XCIsIEpTT04uc3RyaW5naWZ5KGJhc2tldCkpXHJcbiAgICByZXR1cm4gYmFza2V0O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0cyBiYXNrZXQgZGV0YWlsc1xyXG4gICAqIEByZXR1cm5zIHJlZnVuZCBiYXNrZXQgZGV0YWlsc1xyXG4gICAqL1xyXG4gIC8vIGdldFJlZnVuZEJhc2tldERldGFpbHMoKTogQmFza2V0IHtcclxuICAvLyAgIGxldCBiYXNrZXQ6IEJhc2tldCA9IHtcclxuICAvLyAgICAgc3Vic2lkaWFyeUlkIDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnN1YnNpZGlhcnlJZCxcclxuICAvLyAgICAgdHJhbnNhY3Rpb25EaXNjb3VudDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50cmFuc2FjdGlvbkRpc2NvdW50LFxyXG4gIC8vICAgICB0cmFuc2FjdGlvblByb21vdGlvbjogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50cmFuc2FjdGlvblByb21vdGlvbixcclxuICAvLyAgICAgdHJhbnNhY3Rpb25JZDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnRyYW5zYWN0aW9uSWQsXHJcbiAgLy8gICAgIHRvdGFsOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5iYXNrZXRUb3RhbCxcclxuICAvLyAgICAgYmFza2V0VG90YWw6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsLFxyXG4gIC8vICAgICBkaXNjb3VudFRvdGFsOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5kaXNjb3VudFRvdGFsLFxyXG4gIC8vICAgICBzYWxlVG90YWw6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LnNhbGVUb3RhbCxcclxuICAvLyAgICAgcXVhbnRpdHk6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LnRvdGFsSXRlbXMsXHJcbiAgLy8gICAgIHByb2R1Y3RzOiBbXSxcclxuICAvLyAgICAgYmFzZUN1cnJlbmN5OiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFzZUN1cnJlbmN5LFxyXG4gIC8vICAgICBjdXN0b21lcjogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1c3RvbWVyLFxyXG4gIC8vICAgfTtcclxuXHJcbiAgLy8gICBiYXNrZXQucHJvZHVjdHMgPSBbXSBhcyBQcm9kdWN0W107XHJcbiAgLy8gICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnByb2R1Y3RzLmZvckVhY2goKHByb2R1Y3Q6IHsgU0tVOiBhbnk7IGJhckNvZGU6IGFueTsgYmFyY29kZXM6IGFueTsgZGVzY3JpcHRpb246IGFueTsgaW1hZ2VVcmxzOiBhbnk7IHRvdGFsTGluZVByaWNlOiBhbnk7IGl0ZW1MaW5lSWQ6IGFueTsgZXhjbHVkZVByb21vdGlvbjogYW55OyBwcmljZTogbnVtYmVyOyBxdWFudGl0eTogYW55OyBzZWxlY3RlZFJSUFByaWNlOiBhbnk7IGZ1bGxmaWxtZW50SWQ6IGFueTsgZnVsbGZpbG1lbnRMb2NhdGlvbk5hbWU6IGFueTsgZGVsaXZlcnlHcm91cDogc3RyaW5nOyBsZWFkVGltZTogYW55OyBkZWxpdmVyeU1ldGhvZDogYW55OyBnaWZ0Q2FyZDogYW55OyBnaWZ0Q2FyZEV4cGlyeURhdGU6IGFueTsgZ2lmdENhcmROdW1iZXJJc3N1ZWQ6IGFueTsgZ2lmdENhcmRSZWNpcGllbnRFbWFpbDogYW55OyBnaWZ0Q2FyZFJlY2lwaWVudE5hbWU6IGFueTsgaXRlbURpc2NvdW50czogYW55OyByZWZ1bmRlZFByb21vdGlvbmFsUXVhbnRpdHk6IGFueTsgcmVmdW5kZWRRdWFudGl0eTogbnVtYmVyOyByZWZ1bmRlZDogYW55OyBpc0xhc3RFeGNoYW5nZWQ6IGFueTsgZXhjaGFuZ2U6IGFueTsgcmVmdW5kZWRUb3RhbDogbnVtYmVyOyB9LCBpbmRleDogYW55KSA9PiB7XHJcbiAgLy8gICAgIGNvbnN0IHAgPSB7fSBhcyBQcm9kdWN0O1xyXG4gIC8vICAgICBwLlNLVSA9IHByb2R1Y3QuU0tVO1xyXG4gIC8vICAgICBwLmJhcmNvZGUgPSBwcm9kdWN0LmJhckNvZGU7XHJcbiAgLy8gICAgIHAuYmFyY29kZXMgPSBwcm9kdWN0LmJhcmNvZGVzO1xyXG5cclxuICAvLyAgICAgcC5kZXNjcmlwdGlvbiA9IHByb2R1Y3QuZGVzY3JpcHRpb247XHJcbiAgLy8gICAgIHAuaW1hZ2VVcmxzID0gcHJvZHVjdC5pbWFnZVVybHM7XHJcbiAgLy8gICAgIHAuY3VycmVuY3kgPSB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFzZUN1cnJlbmN5O1xyXG4gIC8vICAgICBwLnRvdGFsTGluZVByaWNlID0gcHJvZHVjdC50b3RhbExpbmVQcmljZTtcclxuICAvLyAgICAgcC5pdGVtTGluZUlkID0gTnVtYmVyKHByb2R1Y3QuaXRlbUxpbmVJZCk7XHJcbiAgLy8gICAgIHAuZXhjbHVkZVByb21vdGlvbiA9IHByb2R1Y3QuZXhjbHVkZVByb21vdGlvbjtcclxuXHJcbiAgLy8gICAgIHAuc2VsZWN0ZWRQcmljZSA9IHByb2R1Y3QucHJpY2U7XHJcbiAgLy8gICAgIHAucXVhbnRpdHkgPSBwcm9kdWN0LnF1YW50aXR5O1xyXG4gIC8vICAgICBwLnRvdGFsID0gcHJvZHVjdC50b3RhbExpbmVQcmljZTtcclxuICAvLyAgICAgcC5zZWxlY3RlZFJSUFByaWNlID0gcHJvZHVjdC5zZWxlY3RlZFJSUFByaWNlO1xyXG5cclxuICAvLyAgICAgcC5mdWxsZmlsbWVudElkID0gcHJvZHVjdC5mdWxsZmlsbWVudElkO1xyXG4gIC8vICAgICBwLmZ1bGxmaWxtZW50TG9jYXRpb25OYW1lID0gcHJvZHVjdC5mdWxsZmlsbWVudExvY2F0aW9uTmFtZTtcclxuICAvLyAgICAgcC5kZWxpdmVyeUdyb3VwID0gcHJvZHVjdC5kZWxpdmVyeUdyb3VwIHx8IFwiMVwiO1xyXG4gIC8vICAgICBwLmxlYWRUaW1lID0gcHJvZHVjdC5sZWFkVGltZTtcclxuICAvLyAgICAgcC5kZWxpdmVyeU1ldGhvZCA9IHByb2R1Y3QuZGVsaXZlcnlNZXRob2QgfHwgREVMSVZFUllfTUVUSE9EUy5DT0xMRUNUX0ZST01fU1RPUkUudG9TdHJpbmcoKTtcclxuXHJcbiAgLy8gICAgIHAuZ2lmdENhcmQgPSBwcm9kdWN0LmdpZnRDYXJkO1xyXG4gIC8vICAgICBwLmdpZnRDYXJkRXhwaXJ5RGF0ZSA9IHByb2R1Y3QuZ2lmdENhcmRFeHBpcnlEYXRlO1xyXG4gIC8vICAgICBwLmdpZnRDYXJkTnVtYmVySXNzdWVkID0gcHJvZHVjdC5naWZ0Q2FyZE51bWJlcklzc3VlZDtcclxuICAvLyAgICAgcC5naWZ0Q2FyZFJlY2lwaWVudEVtYWlsID0gcHJvZHVjdC5naWZ0Q2FyZFJlY2lwaWVudEVtYWlsO1xyXG4gIC8vICAgICBwLmdpZnRDYXJkUmVjaXBpZW50TmFtZSA9IHByb2R1Y3QuZ2lmdENhcmRSZWNpcGllbnROYW1lO1xyXG4gICAgICBcclxuICAgICAgXHJcbiAgLy8gICAgIGlmKHAuZnVsbGZpbG1lbnRJZCAhPSB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuc3RvcmVJZClcclxuICAvLyAgICAge1xyXG4gIC8vICAgICAgIHAuaXNXZWJPcmRlciA9IHRydWU7XHJcbiAgLy8gICAgIH1cclxuICAgICAgXHJcbiAgLy8gICAgIGlmIChwcm9kdWN0Lml0ZW1EaXNjb3VudHMpIHtcclxuICAvLyAgICAgICBwLml0ZW1EaXNjb3VudHMgPSBwcm9kdWN0Lml0ZW1EaXNjb3VudHMgYXMgSXRlbURpc2NvdW50O1xyXG4gIC8vICAgICB9XHJcblxyXG4gIC8vICAgICAvLyBpZighcC5pdGVtRGlzY291bnRzKXtcclxuICAvLyAgICAgLy8gICBjb25zb2xlLmxvZyhwLml0ZW1EaXNjb3VudHMpO1xyXG5cclxuICAvLyAgICAgLy8gICB0aGlzLmJhc2tldFNlcnZpY2UudHJhbnNhY3Rpb25EaXNjb3VudEFuZFByb21vdGlvblByb2R1Y3RvcnRpb25DYWxjdWxhdGlvbihiYXNrZXQpO1xyXG4gIC8vICAgICAvLyB9XHJcbiAgLy8gICAgIHAucmVmdW5kUHJvbW90aW9uYWxRdWFudGl0eSA9IHByb2R1Y3QucmVmdW5kZWRQcm9tb3Rpb25hbFF1YW50aXR5ID8gcHJvZHVjdC5yZWZ1bmRlZFByb21vdGlvbmFsUXVhbnRpdHkgOiAwO1xyXG5cclxuICAvLyAgICAgaWYgKHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eSkge1xyXG4gIC8vICAgICAgIHAucXVhbnRpdHkgPSBwLnF1YW50aXR5IC0gcHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5O1xyXG4gIC8vICAgICAgIHAudG90YWxMaW5lUHJpY2UgPSAocC5xdWFudGl0eSAqIHByb2R1Y3QucHJpY2UpO1xyXG4gIC8vICAgICAgIHAudG90YWwgPSBwLnRvdGFsTGluZVByaWNlO1xyXG4gIC8vICAgICAgIC8vIHAucmVmdW5kUHJvbW90aW9uYWxRdWFudGl0eSA9IHByb2R1Y3QucmVmdW5kZWRQcm9tb3Rpb25hbFF1YW50aXR5O1xyXG4gIC8vICAgICAgIHAucmVmdW5kZWQgPSBwcm9kdWN0LnJlZnVuZGVkO1xyXG4gIC8vICAgICAgIHAuaXNMYXN0RXhjaGFuZ2VkID0gcHJvZHVjdC5pc0xhc3RFeGNoYW5nZWQ7XHJcbiAgLy8gICAgIH1cclxuICAvLyAgICAgaWYgKHByb2R1Y3QuZXhjaGFuZ2UpIHtcclxuICAvLyAgICAgICBwLmV4Y2hhbmdlID0gcHJvZHVjdC5leGNoYW5nZTtcclxuICAvLyAgICAgfVxyXG5cclxuICAvLyAgICAgaWYgKFxyXG4gIC8vICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50ICYmXHJcbiAgLy8gICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnQubGVuZ3RoID4gMFxyXG4gIC8vICAgICApIHtcclxuXHJcbiAgLy8gICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnQuZm9yRWFjaCgobGluZURpc2NvdW50OiB7IGl0ZW1MaW5lSWQ6IHsgdG9TdHJpbmc6ICgpID0+IGFueTsgfTsgZGlzY291bnRlZExpbmVQcmljZTogYW55OyB9KSA9PiB7XHJcblxyXG4gIC8vICAgICAgICAgaWYgKHByb2R1Y3QuaXRlbUxpbmVJZCA9PT0gbGluZURpc2NvdW50Lml0ZW1MaW5lSWQudG9TdHJpbmcoKSAmJiBwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHkgPiAwKSB7XHJcbiAgLy8gICAgICAgICAgIHAubGluZURpc2NvdW50ID0gT2JqZWN0LmFzc2lnbih7fSwgbGluZURpc2NvdW50KTtcclxuICAvLyAgICAgICAgICAgcC5saW5lRGlzY291bnQuZGlzY291bnRlZExpbmVQcmljZSA9IHAubGluZURpc2NvdW50LnVuaXRQcmljZSAqIHAucXVhbnRpdHlcclxuICAvLyAgICAgICAgICAgcC5saW5lRGlzY291bnQuZGlzY291bnRBbW91bnQgPSBwLnRvdGFsIC0gcC5saW5lRGlzY291bnQuZGlzY291bnRlZExpbmVQcmljZVxyXG4gIC8vICAgICAgICAgICBwLnRvdGFsID0gcC5saW5lRGlzY291bnQuZGlzY291bnRlZExpbmVQcmljZTtcclxuICAvLyAgICAgICAgIH0gZWxzZSBpZiAocHJvZHVjdC5pdGVtTGluZUlkID09PSBsaW5lRGlzY291bnQuaXRlbUxpbmVJZC50b1N0cmluZygpKSB7XHJcbiAgLy8gICAgICAgICAgIHAubGluZURpc2NvdW50ID0gbGluZURpc2NvdW50O1xyXG4gIC8vICAgICAgICAgICBwLnRvdGFsID0gbGluZURpc2NvdW50LmRpc2NvdW50ZWRMaW5lUHJpY2VcclxuICAvLyAgICAgICAgIH1cclxuICAvLyAgICAgICB9KTtcclxuICAvLyAgICAgfVxyXG5cclxuICAvLyAgICAgaWYgKFxyXG4gIC8vICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbiAmJlxyXG4gIC8vICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbi5sZW5ndGggPiAwXHJcbiAgLy8gICAgICkge1xyXG4gIC8vICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbi5mb3JFYWNoKChsaW5lUHJvbW90aW9uOiB7IGl0ZW1MaW5lSWQ6IHsgdG9TdHJpbmc6ICgpID0+IGFueTsgfTsgcmVmdW5kZWQ6IGFueTsgfSkgPT4ge1xyXG4gIC8vICAgICAgICAgaWYgKHByb2R1Y3QuaXRlbUxpbmVJZCA9PT0gbGluZVByb21vdGlvbi5pdGVtTGluZUlkLnRvU3RyaW5nKCkgJiYgIWxpbmVQcm9tb3Rpb24ucmVmdW5kZWQpIHtcclxuICAvLyAgICAgICAgICAgcC5saW5lUHJvbW90aW9ucyA9IGxpbmVQcm9tb3Rpb247XHJcbiAgLy8gICAgICAgICAgIHAudG90YWwgPSBwLmxpbmVQcm9tb3Rpb25zLnByb21vdGlvbkxpbmVQcmljZTtcclxuICAvLyAgICAgICAgICAgcC50b3RhbCA9IHAudG90YWwgLSAocHJvZHVjdC5yZWZ1bmRlZFRvdGFsID8gTWF0aC5hYnMocHJvZHVjdC5yZWZ1bmRlZFRvdGFsKSA6IDApO1xyXG4gIC8vICAgICAgICAgfVxyXG4gIC8vICAgICAgIH0pO1xyXG4gIC8vICAgICB9XHJcblxyXG4gIC8vICAgICBwLnJlZnVuZGVkUXVhbnRpdHkgPSAwO1xyXG4gIC8vICAgICBwLnJlZnVuZGVkVG90YWwgPSAwO1xyXG5cclxuICAvLyAgICAgaWYgKFxyXG4gIC8vICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudGF4QnJlYWtkb3duICYmXHJcbiAgLy8gICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50YXhCcmVha2Rvd24udGF4TGluZXMubGVuZ3RoID4gMFxyXG4gIC8vICAgICApIHtcclxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRheEJyZWFrZG93bi50YXhMaW5lcy5mb3JFYWNoKCh0YXhMaW5lOiB7IGl0ZW1MaW5lSWQ6IHsgdG9TdHJpbmc6ICgpID0+IGFueTsgfTsgVkFUOiBhbnk7IFZBVENvZGU6IGFueTsgfSkgPT4ge1xyXG4gIC8vICAgICAgICAgaWYgKHByb2R1Y3QuaXRlbUxpbmVJZCA9PT0gdGF4TGluZS5pdGVtTGluZUlkLnRvU3RyaW5nKCkpIHtcclxuICAvLyAgICAgICAgICAgcC5zZWxlY3RlZFZBVCA9IHRheExpbmUuVkFUO1xyXG4gIC8vICAgICAgICAgICBwLnNlbGVjdGVkVkFUQ29kZSA9IHRheExpbmUuVkFUQ29kZTtcclxuICAvLyAgICAgICAgIH1cclxuICAvLyAgICAgICB9KTtcclxuICAvLyAgICAgfVxyXG5cclxuICAvLyAgICAgaWYgKHAucXVhbnRpdHkgPiAwKSB7XHJcbiAgLy8gICAgICAgYmFza2V0LnByb2R1Y3RzLnB1c2gocCk7XHJcbiAgLy8gICAgIH1cclxuICAvLyAgIH0pO1xyXG4gIC8vICAgLy8gcHJvZHVjdC5pdGVtRGlzY291bnRzXHJcbiAgLy8gICBpZiAoIWJhc2tldC5wcm9kdWN0c1swXS5oYXNPd25Qcm9wZXJ0eSgnaXRlbURpc2NvdW50cycpKSB7XHJcbiAgLy8gICAgIGJhc2tldCA9IHRoaXMuZ2V0VHJhbnNhY3Rpb25EaXNjb3VudEFuZFRyYW5zYWN0aW9uUHJvbW90aW9uUG9ydGlvbihiYXNrZXQpO1xyXG5cclxuICAvLyAgIH1cclxuXHJcbiAgLy8gICBjb25zb2xlLmxvZyhcImViYXNrZXQgOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciAgOm5ldyBjcmVhdGVkIHJlZnVuZGVkIGJhc2tldFwiLCBKU09OLnN0cmluZ2lmeShiYXNrZXQpKVxyXG4gIC8vICAgYmFza2V0LnF1YW50aXR5ID0gYmFza2V0LnByb2R1Y3RzLnJlZHVjZShcclxuICAvLyAgICAgKG46IGFueSwgeyBxdWFudGl0eSB9OiBhbnkpID0+IG4gKyBxdWFudGl0eSxcclxuICAvLyAgICAgMFxyXG4gIC8vICAgKTtcclxuICAvLyAgIGJhc2tldC50b3RhbCA9IHRoaXMuZ2V0VG90YWxXaXRoTGluZURpc2NvdW50QW5kTGluZVByb21vdGlvbkFwcGxpZWQoYmFza2V0KTtcclxuICAvLyAgIGJhc2tldC5iYXNrZXRUb3RhbCA9IGJhc2tldC50b3RhbDtcclxuICAvLyAgIGJhc2tldC5iYXNrZXRUb3RhbCA9IGJhc2tldC5iYXNrZXRUb3RhbCAtIHRoaXMuZ2V0VG90YWxEaXNjb3VudFdpdGhUcmFuc2FjdGlvbkRpc2NvdW50c0FuZFByb21vdGlvbnMoYmFza2V0KTtcclxuICAvLyAgIGNvbnNvbGUubG9nKFxyXG4gIC8vICAgICBcImViYXNrZXQgOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciA6IHVwZGF0ZSBCYXNrZXQgVG90YWw6IGFmdGVyIHByb21vdGlvbiA6YmFza2V0VG90YWxcIixcclxuICAvLyAgICAgYmFza2V0LmJhc2tldFRvdGFsXHJcbiAgLy8gICApO1xyXG5cclxuICAvLyAgIGNvbnNvbGUubG9nKFxyXG4gIC8vICAgICBcImU6YmFza2V0IDpUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciA6IGJhc2tldERldGFpbHMgdXBkYXRlZCB2YWx1ZXNcIixcclxuICAvLyAgICAgSlNPTi5zdHJpbmdpZnkoYmFza2V0KVxyXG4gIC8vICAgKTtcclxuICAvLyAgIHJldHVybiBiYXNrZXQ7XHJcbiAgLy8gfVxyXG5cclxuXHJcbiAgZ2V0VHJhbnNhY3Rpb25EaXNjb3VudEFuZFRyYW5zYWN0aW9uUHJvbW90aW9uUG9ydGlvbihiYXNrZXQ6YW55KSB7XHJcbiAgICBpZiAoXHJcbiAgICAgIGJhc2tldC50cmFuc2FjdGlvbkRpc2NvdW50ICYmXHJcbiAgICAgIGJhc2tldC50cmFuc2FjdGlvbkRpc2NvdW50Lmxlbmd0aCA+IDBcclxuICAgICkge1xyXG4gICAgICBiYXNrZXQudHJhbnNhY3Rpb25EaXNjb3VudC5mb3JFYWNoKChkaXNjb3VudDogeyBpdGVtTGluZUlkczogYW55OyB9KSA9PiB7XHJcbiAgICAgICAgaWYgKCFkaXNjb3VudC5pdGVtTGluZUlkcykge1xyXG4gICAgICAgICAgZGlzY291bnQuaXRlbUxpbmVJZHMgPSBiYXNrZXQucHJvZHVjdHMubWFwKChwcm9kdWN0OiB7IGl0ZW1MaW5lSWQ6IGFueTsgfSkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gcHJvZHVjdC5pdGVtTGluZUlkXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYmFza2V0ID0gdGhpcy5iYXNrZXRTZXJ2aWNlLnRyYW5zYWN0aW9uRGlzY291bnRQcm9kdWN0UG9ydGlvbkNhbGMoYmFza2V0LCBkaXNjb3VudCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgaWYgKFxyXG4gICAgICBiYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb24gJiZcclxuICAgICAgYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uLmxlbmd0aCA+IDBcclxuICAgICkge1xyXG4gICAgICBiYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb24uZm9yRWFjaCgodFByb21vdGlvbjogeyBpdGVtTGluZUlkczogYW55OyB9KSA9PiB7XHJcbiAgICAgICAgaWYgKCF0UHJvbW90aW9uLml0ZW1MaW5lSWRzKSB7XHJcbiAgICAgICAgICBjb25zdCBmaWx0ZXJlZERhdGEgPSBiYXNrZXQucHJvZHVjdHMuZmlsdGVyKFxyXG4gICAgICAgICAgICAoaXRlbTogeyBleGNsdWRlUHJvbW90aW9uOiBib29sZWFuOyB9KSA9PiB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0uZXhjbHVkZVByb21vdGlvbiA9PT0gZmFsc2U7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgIHRQcm9tb3Rpb24uaXRlbUxpbmVJZHMgPVxyXG4gICAgICAgICAgICBmaWx0ZXJlZERhdGEubWFwKChwcm9kdWN0OiB7IGl0ZW1MaW5lSWQ6IGFueTsgfSkgPT4ge1xyXG4gICAgICAgICAgICAgIHJldHVybiBwcm9kdWN0Lml0ZW1MaW5lSWRcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJhc2tldCA9IHRoaXMuYmFza2V0U2VydmljZS50cmFuc2FjdGlvblByb21vdGlvblByb2R1Y3RQb3J0aW9uQ2FsYyhiYXNrZXQsIHRQcm9tb3Rpb24pO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gYmFza2V0O1xyXG4gIH1cclxuXHJcblxyXG4gIGdldFRvdGFsRGlzY291bnRXaXRoVHJhbnNhY3Rpb25EaXNjb3VudHNBbmRQcm9tb3Rpb25zKGJhc2tldERldGFpbHM6IGFueSkge1xyXG5cclxuICAgIGxldCBkaXNjb3VudFRvdGFsID0gMDtcclxuICAgIGlmIChcclxuICAgICAgYmFza2V0RGV0YWlscy50cmFuc2FjdGlvblByb21vdGlvbiAmJlxyXG4gICAgICBiYXNrZXREZXRhaWxzLnRyYW5zYWN0aW9uUHJvbW90aW9uLmxlbmd0aCA+IDBcclxuICAgICkge1xyXG4gICAgICBkaXNjb3VudFRvdGFsICs9IGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25Qcm9tb3Rpb24ucmVkdWNlKFxyXG4gICAgICAgIChuOiBhbnksIHsgcHJvbW90aW9uQW1vdW50IH06IGFueSkgPT4gbiArIHByb21vdGlvbkFtb3VudCxcclxuICAgICAgICAwXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgICBpZiAoXHJcbiAgICAgIGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudCAmJlxyXG4gICAgICBiYXNrZXREZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQubGVuZ3RoID4gMFxyXG4gICAgKSB7XHJcblxyXG4gICAgICBkaXNjb3VudFRvdGFsICs9IGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudC5yZWR1Y2UoXHJcbiAgICAgICAgKG46IGFueSwgeyBkaXNjb3VudEFtb3VudCB9OiBhbnkpID0+IG4gKyBkaXNjb3VudEFtb3VudCxcclxuICAgICAgICAwXHJcbiAgICAgICk7XHJcblxyXG5cclxuICAgIH1cclxuICAgIGNvbnNvbGUubG9nKFwiZWJhc2tldCA6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIDogVHJhbnNhY3Rpb24gZGlzY291bnQgVG90YWw6XCIsIGRpc2NvdW50VG90YWwpO1xyXG5cclxuICAgIHJldHVybiBkaXNjb3VudFRvdGFsO1xyXG4gIH1cclxuXHJcblxyXG4gIGFwcGVuZEN1cnJlbmN5U3ltYm9sKGN1cnJlbmN5OiBudW1iZXIsIHZhbHVlOiBudW1iZXIpIHtcclxuICAgIC8vICB2YWx1ZT10aGlzLmRlY2ltYWxwaXBlLnRyYW5zZm9ybSh2YWx1ZSwnMS4yJyk7XHJcbiAgICBpZiAodmFsdWUgPj0gMCkge1xyXG4gICAgICBjb25zdCByZXR1cm52YWwgPSBjdXJyZW5jeSArIHZhbHVlO1xyXG4gICAgICBjb25zb2xlLmxvZyhyZXR1cm52YWwsIFwiZWJhc2tldDogYWRkIGN1cnJlbmN5IHdpdGggdmFsdWVcIik7XHJcbiAgICAgIHJldHVybiByZXR1cm52YWw7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCByZXR1cm52YWwgPSBcIi1cIiArIChjdXJyZW5jeSArIHZhbHVlICogLTEpO1xyXG4gICAgICBjb25zb2xlLmxvZyhyZXR1cm52YWwsIFwiLShjdXJyZW5jeSsodmFsdWUqLTEpKVwiKTtcclxuICAgICAgcmV0dXJuIHJldHVybnZhbDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIC8qKlxyXG4gIC8vICAqIFVwZGF0ZXMgdG90YWwgcmVmdW5kXHJcbiAgLy8gICogQHJldHVybnMgdG90YWwgcmVmdW5kXHJcbiAgLy8gICovXHJcbiAgLy8gdXBkYXRlVG90YWxSZWZ1bmQoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gIC8vICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5wcm9kdWN0cy5mb3JFYWNoKChwcm9kdWN0KSA9PiB7XHJcbiAgLy8gICAgIHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eSA9IHByb2R1Y3QucXVhbnRpdHk7XHJcbiAgLy8gICAgIHByb2R1Y3QucmVmdW5kZWRUb3RhbCA9IHByb2R1Y3QudG90YWxMaW5lUHJpY2UgKiAtMTtcclxuICAvLyAgICAgY29uc29sZS5sb2coXHJcbiAgLy8gICAgICAgXCJlYmFza2V0OiBUcmFuc2FjdGlvbiBwcmljZSBvdmVycmlkZSA6XCIsXHJcbiAgLy8gICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnRcclxuICAvLyAgICAgKTtcclxuXHJcbiAgLy8gICAgIGlmIChcclxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb24gJiZcclxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb24ubGVuZ3RoID4gMFxyXG4gIC8vICAgICApIHtcclxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb24uZm9yRWFjaCgobGluZVByb21vdGlvbikgPT4ge1xyXG4gIC8vICAgICAgICAgY29uc29sZS5sb2coXHJcbiAgLy8gICAgICAgICAgIFwiUHJvbW90aW9uOiBiYXNrZXQgbGluZVByb21vdGlvbiA6IFwiLFxyXG4gIC8vICAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb25cclxuICAvLyAgICAgICAgICk7XHJcbiAgLy8gICAgICAgICBjb25zb2xlLmxvZyhcclxuICAvLyAgICAgICAgICAgXCJsaW5lUHJvbW90aW9uLml0ZW1MaW5lSWQudG9TdHJpbmcoKSA6IFwiLFxyXG4gIC8vICAgICAgICAgICBsaW5lUHJvbW90aW9uLml0ZW1MaW5lSWQudG9TdHJpbmcoKVxyXG4gIC8vICAgICAgICAgKTtcclxuICAvLyAgICAgICAgIGNvbnNvbGUubG9nKFxyXG4gIC8vICAgICAgICAgICBcImNvbmRpdGlvbiA6IFwiICtcclxuICAvLyAgICAgICAgICAgKHByb2R1Y3QuaXRlbUxpbmVJZCA9PT0gbGluZVByb21vdGlvbi5pdGVtTGluZUlkLnRvU3RyaW5nKCkpXHJcbiAgLy8gICAgICAgICApO1xyXG5cclxuICAvLyAgICAgICAgIGlmIChwcm9kdWN0Lml0ZW1MaW5lSWQgPT09IGxpbmVQcm9tb3Rpb24uaXRlbUxpbmVJZC50b1N0cmluZygpKSB7XHJcbiAgLy8gICAgICAgICAgIHByb2R1Y3QucmVmdW5kZWRUb3RhbCA9XHJcbiAgLy8gICAgICAgICAgICAgbGluZVByb21vdGlvbi5wcm9tb3Rpb25MaW5lUHJpY2UgKiAtMTtcclxuICAvLyAgICAgICAgIH1cclxuICAvLyAgICAgICB9KTtcclxuICAvLyAgICAgfSBlbHNlXHJcbiAgLy8gICAgICAgaWYgKFxyXG4gIC8vICAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnQgJiZcclxuICAvLyAgICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50Lmxlbmd0aCA+IDBcclxuICAvLyAgICAgICApIHtcclxuICAvLyAgICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50LmZvckVhY2goKGxpbmVEaXNjb3VudCkgPT4ge1xyXG4gIC8vICAgICAgICAgICBjb25zb2xlLmxvZyhcclxuICAvLyAgICAgICAgICAgICBcInByb2R1Y3QuaXRlbUxpbmVJZCA6IFwiICtcclxuICAvLyAgICAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudFxyXG4gIC8vICAgICAgICAgICApO1xyXG4gIC8vICAgICAgICAgICBjb25zb2xlLmxvZyhcclxuICAvLyAgICAgICAgICAgICBcImxpbmVEaXNjb3VudC5pdGVtTGluZUlkLnRvU3RyaW5nKCkgOiBcIiArXHJcbiAgLy8gICAgICAgICAgICAgbGluZURpc2NvdW50Lml0ZW1MaW5lSWQudG9TdHJpbmcoKVxyXG4gIC8vICAgICAgICAgICApO1xyXG4gIC8vICAgICAgICAgICBjb25zb2xlLmxvZyhcclxuICAvLyAgICAgICAgICAgICBcImNvbmRpdGlvbiA6IFwiICtcclxuICAvLyAgICAgICAgICAgICAocHJvZHVjdC5pdGVtTGluZUlkID09PSBsaW5lRGlzY291bnQuaXRlbUxpbmVJZC50b1N0cmluZygpKVxyXG4gIC8vICAgICAgICAgICApO1xyXG5cclxuICAvLyAgICAgICAgICAgaWYgKHByb2R1Y3QuaXRlbUxpbmVJZCA9PT0gbGluZURpc2NvdW50Lml0ZW1MaW5lSWQudG9TdHJpbmcoKSkge1xyXG4gIC8vICAgICAgICAgICAgIHByb2R1Y3QucmVmdW5kZWRUb3RhbCA9IGxpbmVEaXNjb3VudC51bml0UHJpY2UgKiBwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHkgKiAtMTtcclxuICAvLyAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgfSk7XHJcbiAgLy8gICAgICAgfVxyXG5cclxuICAvLyAgICAgY29uc29sZS5sb2coXCJQcm9kdWN0IGRlc2NyaXB0aW9uIDpcIiArIHByb2R1Y3QuZGVzY3JpcHRpb24pO1xyXG4gIC8vICAgICBjb25zb2xlLmxvZyhcIlByb2R1Y3QgdG90YWwgOlwiICsgcHJvZHVjdC5yZWZ1bmRlZFRvdGFsKTtcclxuICAvLyAgICAgLy8gcHJvZHVjdC5kaXNwbGF5cmVmdW5kZWRhbW91bnQ9dGhpcy5hcHBlbmRDdXJyZW5jeVN5bWJvbChDVVJSRU5DWVt0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFzZUN1cnJlbmN5XSxwcm9kdWN0LnJlZnVuZGVkVG90YWwpO1xyXG4gIC8vICAgICAvLyBjb25zb2xlLmxvZyhwcm9kdWN0LmRpc3BsYXlyZWZ1bmRlZGFtb3VudCxcImRpc3BsYXlyZWZ1bmRlZGFtb3VudFwiKTtcclxuICAvLyAgICAgcHJvZHVjdC5yZWZ1bmRlZCA9IHRydWU7XHJcbiAgLy8gICB9KTtcclxuICAvLyAgIGNvbnN0IGJhc2tldHRvdGFsID0gKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsICo9IC0xKTtcclxuICAvLyAgIC8vIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmRpc3BsYXliYXNrZXR0b3RhbD10aGlzLmFwcGVuZEN1cnJlbmN5U3ltYm9sKENVUlJFTkNZW3RoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNlQ3VycmVuY3ldLCBiYXNrZXR0b3RhbCk7XHJcbiAgLy8gICBjb25zdCBzYWxldG90YWwgPSAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuc2FsZVRvdGFsICo9IC0xKTtcclxuICAvLyAgIC8vIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmRpc3BsYXlzYWxldG90YWwgPSB0aGlzLmFwcGVuZEN1cnJlbmN5U3ltYm9sKENVUlJFTkNZW3RoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNlQ3VycmVuY3ldLCBzYWxldG90YWwpO1xyXG4gIC8vICAgKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LlZBVFRvdGFsICo9IC0xKTtcclxuICAvLyAgIHJldHVybiB0aGlzO1xyXG4gIC8vIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2FsZSBUb3RhbFxyXG4gICAqIEBwYXJhbSBiYXNrZXREZXRhaWxzXHJcbiAgICogQHJldHVybnMgU2FsZSBUb3RhbFxyXG4gICAqL1xyXG4gIHVwZGF0ZVNhbGVUb3RhbChiYXNrZXREZXRhaWxzOiB7IHByb2R1Y3RzOiBhbnlbXTsgfSkge1xyXG4gICAgY29uc3Qgc2FsZVRvdGFsID0gYmFza2V0RGV0YWlscy5wcm9kdWN0cy5yZWR1Y2UoXHJcbiAgICAgIChuOiBhbnksIHsgdG90YWxMaW5lUHJpY2UgfTogYW55KSA9PiBuICsgdG90YWxMaW5lUHJpY2UsXHJcbiAgICAgIDBcclxuICAgICk7XHJcbiAgICByZXR1cm4gc2FsZVRvdGFsXHJcbiAgfVxyXG5cclxuICBnZXRUb3RhbFdpdGhMaW5lRGlzY291bnRBbmRMaW5lUHJvbW90aW9uQXBwbGllZChiYXNrZXREZXRhaWxzOiB7IHByb2R1Y3RzOiBhbnk7IH0pOiBudW1iZXIge1xyXG4gICAgbGV0IHNhbGV0b3RhbDogbnVtYmVyID0gMC4wO1xyXG4gICAgZm9yIChsZXQgcHJvZHVjdCBvZiBiYXNrZXREZXRhaWxzLnByb2R1Y3RzKSB7XHJcbiAgICAgIC8vIGlmIChwcm9kdWN0LmxpbmVQcm9tb3Rpb25zKSB7XHJcbiAgICAgIC8vICAgc2FsZXRvdGFsICs9IHByb2R1Y3QubGluZVByb21vdGlvbnMucHJvbW90aW9uTGluZVByaWNlO1xyXG4gICAgICAvLyB9IGVsc2UgaWYgKFxyXG4gICAgICAvLyAgIHByb2R1Y3QubGluZURpc2NvdW50ICYmXHJcbiAgICAgIC8vICAgIXByb2R1Y3QubGluZVByb21vdGlvbnNcclxuICAgICAgLy8gKSB7XHJcbiAgICAgIC8vICAgc2FsZXRvdGFsICs9XHJcbiAgICAgIC8vICAgICBwcm9kdWN0LnF1YW50aXR5ICogTnVtYmVyKHByb2R1Y3QubGluZURpc2NvdW50LnVuaXRQcmljZS50b0ZpeGVkKDIpKTtcclxuICAgICAgLy8gfSBlbHNlIHtcclxuICAgICAgLy8gICBzYWxldG90YWwgKz1cclxuICAgICAgLy8gICAgIHByb2R1Y3QucXVhbnRpdHkgKiBOdW1iZXIocHJvZHVjdC5zZWxlY3RlZFByaWNlLnRvRml4ZWQoMikpO1xyXG4gICAgICAvLyB9XHJcbiAgICAgIHNhbGV0b3RhbCArPSBwcm9kdWN0LnRvdGFsO1xyXG4gICAgICBjb25zb2xlLmxvZyhcclxuICAgICAgICBcImUtYmFza2V0OnVwZGF0ZSBwcm9kdWN0IFRvdGFsOlwiICsgc2FsZXRvdGFsLFxyXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHByb2R1Y3QpXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gc2FsZXRvdGFsO1xyXG4gIH1cclxuXHJcbiAgZ2V0UmVmdW5kZWRUb3RhbFdpdGhRdWFudGl0eShiYXNrZXREZXRhaWxzOiB7IHByb2R1Y3RzOiBzdHJpbmcgfCBhbnlbXTsgfSk6IG51bWJlciB7XHJcbiAgICBsZXQgcXVhbnRpdHkgPSAwO1xyXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGJhc2tldERldGFpbHMucHJvZHVjdHMubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgIGNvbnN0IHByb2R1Y3Q6IGFueSA9IGJhc2tldERldGFpbHMucHJvZHVjdHNbaW5kZXhdO1xyXG5cclxuICAgICAgaWYgKCFwcm9kdWN0LnJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb24pIHtcclxuXHJcbiAgICAgICAgcXVhbnRpdHkgPSBxdWFudGl0eSArIHByb2R1Y3QucXVhbnRpdHk7XHJcblxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHF1YW50aXR5ID0gcXVhbnRpdHkgKyAocHJvZHVjdC5xdWFudGl0eSAtIHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eSk7XHJcblxyXG4gICAgICAgIC8vIGJhc2tldERldGFpbHMudG90YWwgPSBiYXNrZXREZXRhaWxzLnRvdGFsICsgcHJvZHVjdC5yZWZ1bmRlZFRvdGFsO1xyXG5cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHF1YW50aXR5O1xyXG5cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERpc2NvdW50IFRvdGFsXHJcbiAgICogQHJldHVybnMgRGlzY291bnQgVG90YWxcclxuICAgKi9cclxuICB1cGRhdGVEaXNjb3VudFRvdGFsKCkge1xyXG4gICAgbGV0IHJlZnVuZFRvdGFsID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkucmVmdW5kVG90YWwgPyB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5yZWZ1bmRUb3RhbCA6IDA7XHJcbiAgICBjb25zb2xlLmluZm8oXCJlLWJhc2tldDogdHJhbnNhY3Rpb24gYnVpbGRlcjogcmVmdW5kVG90YWxcIiwgSlNPTi5zdHJpbmdpZnkocmVmdW5kVG90YWwpLFxyXG4gICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeSkpO1xyXG4gICAgY29uc3QgZGlzY291bnRUb3RhbCA9XHJcbiAgICAgIE1hdGguYWJzKFxyXG4gICAgICAgIE1hdGguYWJzKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LnNhbGVUb3RhbCkgLVxyXG4gICAgICAgIChcclxuICAgICAgICAgIE1hdGguYWJzKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsKSArIE1hdGguYWJzKHJlZnVuZFRvdGFsKVxyXG4gICAgICAgIClcclxuICAgICAgKTtcclxuICAgIGNvbnNvbGUubG9nKFwiZS1iYXNrZXQ6IHRyYW5zYWN0aW9uIGJ1aWxkZXI6IGRpc2NvdW50VG90YWxcIiwgSlNPTi5zdHJpbmdpZnkoZGlzY291bnRUb3RhbCkpXHJcbiAgICByZXR1cm4gTnVtYmVyKGRpc2NvdW50VG90YWwudG9GaXhlZCgyKSk7XHJcbiAgfVxyXG5cclxuICB1cGRhdGVSZWFzb25Db2RlKHJlYXNvbkNvZGU6IHtcclxuICAgIGNvZGU6IHN0cmluZztcclxuICAgIG5hbWU6IHN0cmluZztcclxuICB9KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnJlYXNvbkNvZGUgPSByZWFzb25Db2RlLmNvZGU7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQucmVhc29uRGVzY3JpcHRpb24gPSByZWFzb25Db2RlLm5hbWU7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHVwZGF0ZU1hbmFnZXJPdmVycmlkZShcclxuICAgIHVzZXJvdmVycmlkZTogVXNlck92ZXJyaWRlXHJcbiAgKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50Lm92ZXJyaWRlID0gdXNlcm92ZXJyaWRlO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICB1cGRhdGVVc2VySUQoXHJcbiAgICB1c2VySUQ6IHN0cmluZ1xyXG4gICk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC51c2VySWQgPSB1c2VySUQ7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHVwZGF0ZVVzZXJOYW1lKG5hbWU6IGFueSkgOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudXNlck5hbWUgPSBuYW1lO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcblxyXG4gIH1cclxuICBcclxuICBhZGRDdXN0b21lckRldGFpbHMoY3VzdG9tZXJEZXRhaWw6IEN1c3RvbWVyKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1c3RvbWVyID0gY3VzdG9tZXJEZXRhaWw7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHVwZGF0ZVRheEJyZWFrZG93bihiYXNrZXREZXRhaWxzOiBCYXNrZXQpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICAvLyBsZXQgdHJhbnNhY3Rpb25EaXNjb3VudFRvdGFsID0gMDtcclxuICAgIGxldCB0YXhCcmVha2Rvd246IFRheEJyZWFrZG93biA9IHtcclxuICAgICAgdGF4TGluZXM6IFtdLFxyXG4gICAgICB0b3RhbFRheGFibGVBbW91bnQ6IDAsXHJcbiAgICB9O1xyXG5cclxuXHJcblxyXG4gICAgLy8gaWYgKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25EaXNjb3VudCAmJiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQubGVuZ3RoID4gMCkge1xyXG4gICAgLy8gICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQuZm9yRWFjaCgoZGlzY291bnQpID0+IHtcclxuICAgIC8vICAgICB0cmFuc2FjdGlvbkRpc2NvdW50VG90YWwgKz0gZGlzY291bnQuZGlzY291bnRBbW91bnQ7XHJcbiAgICAvLyAgIH0pO1xyXG4gICAgLy8gfVxyXG5cclxuICAgIC8vIGlmICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uICYmIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb24ubGVuZ3RoID4gMCkge1xyXG4gICAgLy8gICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uLmZvckVhY2goXHJcbiAgICAvLyAgICAgKHByb21vdGlvbikgPT4ge1xyXG4gICAgLy8gICAgICAgdHJhbnNhY3Rpb25EaXNjb3VudFRvdGFsICs9IHByb21vdGlvbi5wcm9tb3Rpb25BbW91bnQ7XHJcbiAgICAvLyAgICAgfVxyXG4gICAgLy8gICApO1xyXG4gICAgLy8gfVxyXG5cclxuICAgIGJhc2tldERldGFpbHMucHJvZHVjdHMuZm9yRWFjaCgocHJvZHVjdDogYW55KSA9PiB7XHJcbiAgICAgIGxldCB0YXhMaW5lOiBUYXhMaW5lID0ge1xyXG4gICAgICAgIGl0ZW1MaW5lSWQ6IHByb2R1Y3QuaXRlbUxpbmVJZCxcclxuICAgICAgICBWQVQ6IHByb2R1Y3Quc2VsZWN0ZWRWQVQgPyBwcm9kdWN0LnNlbGVjdGVkVkFUIDogMCxcclxuICAgICAgICBWQVRDb2RlOiBwcm9kdWN0LnNlbGVjdGVkVkFUQ29kZSxcclxuICAgICAgICB0YXhMaW5lVG90YWw6IDAsXHJcbiAgICAgICAgdGF4YWJsZUFtb3VudDogcHJvZHVjdC50b3RhbCxcclxuICAgICAgICBQcmVUYXg6IDBcclxuICAgICAgfTtcclxuICAgICAgY29uc29sZS5pbmZvKFwiUHJvZHVjdCBjb250cmlidXRpb24gOiBpdGVtIGxpbmUgSUQgOlwiLCBwcm9kdWN0Lml0ZW1MaW5lSWQsXHJcbiAgICAgICAgXCJ0YXggbGluZSA6XCIsIEpTT04uc3RyaW5naWZ5KHRheExpbmUpKTtcclxuXHJcbiAgICAgIC8vIHN0ZXAgMVxyXG4gICAgICAvLyBpZiBUcmFuc2FjdGlvbiBEaXNjb3VudCBhbmQvb3IgcHJvbW90aW9uIGFwcGxpZWQsIGZpbmQgbmV0IHNlbGxpbmcgcHJpY2Ugb2YgZWFjaCBwcm9kdWN0IGFzIHRheGFibGVhbW91bnRcclxuICAgICAgLy8gaWYgKHRyYW5zYWN0aW9uRGlzY291bnRUb3RhbCA+IDApIHtcclxuICAgICAgcHJvZHVjdCA9IHRoaXMuYmFza2V0U2VydmljZS52YWxpZGF0ZVByb2R1Y3RJdGVtRGlzY291bnQocHJvZHVjdCk7XHJcblxyXG4gICAgICBjb25zdCBwcm9kdWN0Q29udHJpYnV0aW9uSW5Ub3RhbCA9XHJcbiAgICAgICAgcHJvZHVjdC5pdGVtRGlzY291bnRzLnRybkRpc2NvdW50c1BvcnRpb24gK1xyXG4gICAgICAgIHByb2R1Y3QuaXRlbURpc2NvdW50cy50cm5Qcm9tb3Rpb25zUG9ydGlvbiAtXHJcbiAgICAgICAgcHJvZHVjdC5pdGVtRGlzY291bnRzLnJlZnVuZFBvcnRpb247XHJcbiAgICAgIC8vICB0cCt0ZC1ycDtcclxuXHJcbiAgICAgIGNvbnNvbGUuaW5mbyhcIlByb2R1Y3QgY29udHJpYnV0aW9uIDogaXRlbSBsaW5lIElEIDpcIiwgcHJvZHVjdC5pdGVtTGluZUlkLFxyXG4gICAgICAgIFwiY29udHJpYnV0aW9uIDpcIiwgSlNPTi5zdHJpbmdpZnkocHJvZHVjdENvbnRyaWJ1dGlvbkluVG90YWwpKTtcclxuICAgICAgLy8gY2FsY3VsYXRlIG5ldCBzZWxsaW5nIHByaWNlIGFmdGVyIGFwcGx5aW5nIHRyYW5zYWN0aW9uIGRpc2NvdW50IGFzIHBlciBwcm9kdWN0IGNvbnRyaWJ1dGlvblxyXG4gICAgICB0YXhMaW5lLnRheGFibGVBbW91bnQgLT0gcHJvZHVjdENvbnRyaWJ1dGlvbkluVG90YWw7XHJcbiAgICAgIC8vIH1cclxuXHJcbiAgICAgIC8vc3RlcCAyIC0gZmluZCBwcmUgdGF4XHJcbiAgICAgIHRheExpbmUuUHJlVGF4ID0gdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIoKHRheExpbmUudGF4YWJsZUFtb3VudCAqIDEwMCkgLyAoMTAwICsgdGF4TGluZS5WQVQpKTtcclxuXHJcbiAgICAgIC8vc3RlcCAzIC0gVXBkYXRlIHRheGJyZWFrZG93blxyXG4gICAgICB0YXhCcmVha2Rvd24udG90YWxUYXhhYmxlQW1vdW50ICs9IHRheExpbmUudGF4YWJsZUFtb3VudDtcclxuICAgICAgdGF4TGluZS50YXhhYmxlQW1vdW50ID0gdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIodGF4TGluZS50YXhhYmxlQW1vdW50KTtcclxuICAgICAgXHJcbiAgICAgIC8vIHN0ZXAgNCAtIHVwZGF0ZSB0YXggTGluZSB0b3RhbFxyXG4gICAgICB0YXhMaW5lLnRheExpbmVUb3RhbCA9ICB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMih0YXhMaW5lLnRheGFibGVBbW91bnQgLSB0YXhMaW5lLlByZVRheCk7XHJcbiAgICAgIHRheEJyZWFrZG93bi50YXhMaW5lcy5wdXNoKHRheExpbmUpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGF4QnJlYWtkb3duLnRvdGFsVGF4YWJsZUFtb3VudCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRheEJyZWFrZG93bi50b3RhbFRheGFibGVBbW91bnQpO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50YXhCcmVha2Rvd24gPSB0YXhCcmVha2Rvd247XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHVwZGF0ZVRvdGFsVGF4U3VtbWFyeSgpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcblxyXG4gICAgY29uc29sZS5sb2coXCJUb3RhbCBUYXggU3VtbWVyeSBSZXF1ZXN0IDpcIiwgSlNPTi5zdHJpbmdpZnkodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50YXhCcmVha2Rvd24pKTtcclxuXHJcblxyXG4gICAgbGV0IHRvdGFsVGF4U3VtbWFyeUFycmF5OiBUb3RhbFRheFN1bW1hcnlbXSA9IFtdXHJcbiAgICBsZXQgdG90YWxUYXhTdW1tYXJ5R3JvdXAgPSBbXVxyXG5cclxuICAgIGNvbnNvbGUubG9nKFwiVGF4IExpbmVzIGZvciBUb3RhbCBUYXggU3VtbWVyeSA6XCIsIEpTT04uc3RyaW5naWZ5KHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudGF4QnJlYWtkb3duLnRheExpbmVzKSk7XHJcblxyXG5cclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudGF4QnJlYWtkb3duLnRheExpbmVzLmZvckVhY2goKGVsZW1lbnQ6IHsgVkFUQ29kZTogYW55OyBWQVQ6IGFueTsgUHJlVGF4OiBhbnk7IHRheExpbmVUb3RhbDogYW55OyB9KSA9PiB7XHJcbiAgICAgIGxldCBUYXhTdW1tYXJ5OiBUb3RhbFRheFN1bW1hcnkgPSB7XHJcbiAgICAgICAgVkFUQ29kZTogXCJcIixcclxuICAgICAgICBWQVQ6IC0xMjM0NSxcclxuICAgICAgICBQcmVUYXhTdW06IDAsXHJcbiAgICAgICAgVGF4U3VtOiAwLFxyXG4gICAgICAgIFRYcmF0ZVN1bTogMFxyXG4gIFxyXG4gICAgICB9O1xyXG4gICAgICAgVGF4U3VtbWFyeS5WQVRDb2RlID0gZWxlbWVudC5WQVRDb2RlO1xyXG4gICAgICAgIFRheFN1bW1hcnkuVkFUID0gZWxlbWVudC5WQVQ7ICAgICAgICBcclxuICAgICAgICBUYXhTdW1tYXJ5LlByZVRheFN1bSA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKGVsZW1lbnQuUHJlVGF4KTtcclxuICAgICAgICBUYXhTdW1tYXJ5LlRheFN1bSA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKGVsZW1lbnQudGF4TGluZVRvdGFsKTtcclxuICAgICAgICBUYXhTdW1tYXJ5LlRYcmF0ZVN1bSA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKFRheFN1bW1hcnkuUHJlVGF4U3VtICsgVGF4U3VtbWFyeS5UYXhTdW0pOyAgICAgIFxyXG4gICAgICAgIHRvdGFsVGF4U3VtbWFyeUFycmF5LnB1c2goVGF4U3VtbWFyeSk7XHJcbiAgICB9KVxyXG5cclxuICAgIGNvbnNvbGUubG9nKFwiVG90YWwgVGF4IFN1bW1lcnkgIFdpdGhvdXQgR3JvdXBlZCA6IFwiLCBKU09OLnN0cmluZ2lmeSh0b3RhbFRheFN1bW1hcnlBcnJheSkpO1xyXG4gICAgXHJcbiAgICB0b3RhbFRheFN1bW1hcnlHcm91cCA9IHRvdGFsVGF4U3VtbWFyeUFycmF5LnJlZHVjZSgocHJlcGFyZWRBcnJheTphbnksY3VycmVudE9iaikgPT4ge1xyXG5cclxuICAgICAgbGV0IGluZCA9IHByZXBhcmVkQXJyYXkuZmluZEluZGV4KCh4OiB7IFZBVDogYW55OyB9KSA9PiB4LlZBVCA9PT0gY3VycmVudE9iai5WQVQpO1xyXG4gICAgICBpZihpbmQgPT09IC0xKXtcclxuICAgICAgICBwcmVwYXJlZEFycmF5LnB1c2goY3VycmVudE9iailcclxuICAgICAgfWVsc2Uge1xyXG4gICAgICAgIHByZXBhcmVkQXJyYXlbaW5kXS5WQVRDb2RlID0gY3VycmVudE9iai5WQVRDb2RlO1xyXG4gICAgICAgIHByZXBhcmVkQXJyYXlbaW5kXS5WQVQgPSBjdXJyZW50T2JqLlZBVDtcclxuICAgICAgICBwcmVwYXJlZEFycmF5W2luZF0uUHJlVGF4U3VtICs9IGN1cnJlbnRPYmouUHJlVGF4U3VtO1xyXG4gICAgICAgIHByZXBhcmVkQXJyYXlbaW5kXS5UYXhTdW0gKz0gY3VycmVudE9iai5UYXhTdW07XHJcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlRYcmF0ZVN1bSArPSBjdXJyZW50T2JqLlRYcmF0ZVN1bTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gcHJlcGFyZWRBcnJheTtcclxuICAgIH0sW10pXHJcbiAgICBcclxuICAgIGNvbnNvbGUubG9nKFwiVG90YWwgIFRheCBTdW1tZXIgR3JvdXAgOlwiLHRvdGFsVGF4U3VtbWFyeUdyb3VwKTtcclxuXHJcblxyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50b3RhbFRheFN1bW1hcnkgPSB0b3RhbFRheFN1bW1hcnlHcm91cDtcclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuXHJcbiAgfVxyXG5cclxuXHJcbiAgLyoqXHJcbiAgICogVHJhbnNhY3Rpb25JZFxyXG4gICAqIEByZXR1cm5zIE9yaWdpbmFsVHJhbnNhY3Rpb25JZFxyXG4gICAqL1xyXG4gIGFkZE9yaWdpbmFsVHJhbnNJZCh0cmFuRG9jOlRyYW5zYWN0aW9uRG9jdW1lbnQpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICBpZiAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnR5cGUgPT09IFRSQU5TQUNUSU9OX1RZUEUuUkVGVU5EIHx8IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC50eXBlID09PSBUUkFOU0FDVElPTl9UWVBFLlNBTEVfUkVGVU5EIHx8IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC50eXBlID09PSBUUkFOU0FDVElPTl9UWVBFLlNBTEVfRVhDSEFOR0UpIHtcclxuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50Lm9yaWdpbmFsVHJhbnNJZCA9IHRyYW5Eb2MudHJhbnNhY3Rpb25JZDtcclxuICAgICAgaWYodHJhbkRvYy5hcGlSZXNwb25zZSAmJiB0cmFuRG9jLmFwaVJlc3BvbnNlLmludGVybmFsSWQpXHJcbiAgICAgIHtcclxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQub3JpZ2luYWxFeHRlcm5hbElkID0gdHJhbkRvYy5hcGlSZXNwb25zZS5pbnRlcm5hbElkLnRvU3RyaW5nKCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogdW5yZWZlcmVuY2VkIFJlZnVuZFxyXG4gICAqIEByZXR1cm5zIGJvb2xlYW4gdmFsdWVcclxuICAgKi9cclxuICBhZGRVbnJlZmVyZW5jZWRSZWZ1bmQoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnVucmVmZXJlbmNlZFJlZnVuZCA9IHRydWU7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIGdldFJlZnVuZFRvdGFsKCkge1xyXG4gICAgbGV0IHRvdGFsUmVmdW5kID0gMDtcclxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnByb2R1Y3RzLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICBjb25zdCBwcm9kdWN0OiBUUHJvZHVjdCA9IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQucHJvZHVjdHNbaW5kZXhdO1xyXG4gICAgICBpZiAocHJvZHVjdC5yZWZ1bmRlZFRvdGFsKSB7XHJcbiAgICAgICAgdG90YWxSZWZ1bmQgPSB0b3RhbFJlZnVuZCArIHByb2R1Y3QucmVmdW5kZWRUb3RhbDtcclxuICAgICAgfVxyXG4gICAgICBjb25zb2xlLmxvZyhcImViYXNrZXQgOiB0cmFuc2FjdGlvbiBTZXJ2aWNlOiB0b3RhbFJlZnVuZFwiICsgdG90YWxSZWZ1bmQpXHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG90YWxSZWZ1bmQ7XHJcbiAgfVxyXG5cclxuICBkb2NJZChkb2NJZDogYW55KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuaWQgPSBkb2NJZDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxufVxyXG4iXX0=
|