@pmcretail/mapper-library 0.0.49 → 0.0.52
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 +24 -24
- package/bundles/pmcretail-mapper-library.umd.js +4379 -4373
- package/bundles/pmcretail-mapper-library.umd.js.map +1 -1
- package/esm2015/lib/RJ-mapper.class.js +877 -877
- package/esm2015/lib/TransactionDocumentBuilder.js +1244 -1244
- package/esm2015/lib/WebReturn-mapper.class.js +326 -326
- package/esm2015/lib/WebReturnMagento2RestV1.class.js +275 -269
- package/esm2015/lib/WebReturnSalesforceMapper.class.js +409 -409
- package/esm2015/lib/basket.service.js +527 -527
- package/esm2015/lib/mapper-library.component.js +26 -26
- package/esm2015/lib/mapper-library.model.js +41 -41
- package/esm2015/lib/mapper-library.module.js +21 -21
- package/esm2015/lib/number-util.service.js +42 -42
- package/esm2015/pmcretail-mapper-library.js +4 -4
- package/esm2015/public-api.js +10 -10
- package/fesm2015/pmcretail-mapper-library.js +3743 -3737
- package/fesm2015/pmcretail-mapper-library.js.map +1 -1
- package/lib/RJ-mapper.class.d.ts +80 -80
- package/lib/TransactionDocumentBuilder.d.ts +271 -271
- package/lib/WebReturn-mapper.class.d.ts +27 -27
- package/lib/WebReturnMagento2RestV1.class.d.ts +30 -30
- package/lib/WebReturnMagento2RestV1.class.d.ts.map +1 -1
- package/lib/WebReturnSalesforceMapper.class.d.ts +35 -35
- package/lib/basket.service.d.ts +105 -105
- package/lib/mapper-library.component.d.ts +8 -8
- package/lib/mapper-library.model.d.ts +702 -701
- package/lib/mapper-library.model.d.ts.map +1 -1
- package/lib/mapper-library.module.d.ts +7 -7
- package/lib/number-util.service.d.ts +13 -13
- package/package.json +2 -2
- package/pmcretail-mapper-library.d.ts +5 -5
- package/public-api.d.ts +6 -6
|
@@ -1,1244 +1,1244 @@
|
|
|
1
|
-
import { DELIVERY_METHODS } from "./mapper-library.model";
|
|
2
|
-
import { TRANSACTION_TYPE } from "./mapper-library.model";
|
|
3
|
-
import { BasketService } from "./basket.service";
|
|
4
|
-
import { NumberUtilService } from "./number-util.service";
|
|
5
|
-
import { AppLoggerService } from '@pmcretail/common-services/common/app-logger.service';
|
|
6
|
-
/**
|
|
7
|
-
* Transaction document builder
|
|
8
|
-
*/
|
|
9
|
-
export class TransactionDocumentBuilder {
|
|
10
|
-
constructor(transactionDoc, currencyPipe, basketService) {
|
|
11
|
-
this.currencyPipe = currencyPipe;
|
|
12
|
-
this.basketService = basketService;
|
|
13
|
-
this.className = "TransactionDocumentBuilder";
|
|
14
|
-
this.numberUtilService = new NumberUtilService(currencyPipe);
|
|
15
|
-
this.basketService = new BasketService(this.numberUtilService);
|
|
16
|
-
this.storeInfo = JSON.parse(localStorage.getItem('storeInfo') || '{}');
|
|
17
|
-
if (transactionDoc) {
|
|
18
|
-
this.transactionDocument = transactionDoc;
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
this.transactionDocument = {
|
|
22
|
-
transactionId: "",
|
|
23
|
-
offlineTransactionId: "",
|
|
24
|
-
transactionRef: "",
|
|
25
|
-
dateTime: "",
|
|
26
|
-
orgCode: "",
|
|
27
|
-
storeId: "",
|
|
28
|
-
storeNodeId: "",
|
|
29
|
-
storeNodeStructure: "",
|
|
30
|
-
deviceId: "",
|
|
31
|
-
terminalId: "",
|
|
32
|
-
userId: "",
|
|
33
|
-
initiatingModule: "eBasket",
|
|
34
|
-
export: false,
|
|
35
|
-
basket: {},
|
|
36
|
-
basketSummary: {},
|
|
37
|
-
baseCurrency: "",
|
|
38
|
-
type: "",
|
|
39
|
-
operationStatus: "",
|
|
40
|
-
createdAt: "",
|
|
41
|
-
updatedAt: "",
|
|
42
|
-
id: "",
|
|
43
|
-
currentTransactionDetails: {},
|
|
44
|
-
saleTotal: 0,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Transactions ref
|
|
50
|
-
* @returns ref
|
|
51
|
-
*/
|
|
52
|
-
transactionRef() {
|
|
53
|
-
const storeDetails = JSON.parse(localStorage.getItem('storeInfo') || '{}');
|
|
54
|
-
const date = new Date();
|
|
55
|
-
const random = (((1 + Math.random()) * 0x10000) | 0)
|
|
56
|
-
.toString(16)
|
|
57
|
-
.substring(1);
|
|
58
|
-
this.transactionDocument.transactionRef =
|
|
59
|
-
storeDetails.orgCode + storeDetails.storeId + date.toISOString() + random;
|
|
60
|
-
AppLoggerService.logDebug(this.className, "transactionRef", "transaction ref created", this.transactionDocument.transactionRef);
|
|
61
|
-
return this;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Transactions id
|
|
65
|
-
* @param transactionID
|
|
66
|
-
* @returns id
|
|
67
|
-
*/
|
|
68
|
-
transactionId(transactionID, isOnline = true) {
|
|
69
|
-
if (isOnline) {
|
|
70
|
-
this.transactionDocument.transactionId = transactionID;
|
|
71
|
-
}
|
|
72
|
-
return this;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Transactions id
|
|
76
|
-
* @param transactionID
|
|
77
|
-
* @returns id
|
|
78
|
-
*/
|
|
79
|
-
offlineTransactionId(transactionID, isOnline) {
|
|
80
|
-
if (!isOnline) {
|
|
81
|
-
this.transactionDocument.offlineTransactionId = transactionID;
|
|
82
|
-
}
|
|
83
|
-
return this;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* storeNode Id
|
|
87
|
-
* @param storeNodeId
|
|
88
|
-
* @returns id
|
|
89
|
-
*/
|
|
90
|
-
storeNodeId(storeNodeId) {
|
|
91
|
-
this.transactionDocument.storeNodeId = storeNodeId;
|
|
92
|
-
return this;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* storeNode structure
|
|
96
|
-
* @param storeNodeStructure
|
|
97
|
-
* @returns id
|
|
98
|
-
*/
|
|
99
|
-
storeNodeStructure(storeNodeStructure) {
|
|
100
|
-
this.transactionDocument.storeNodeStructure = storeNodeStructure;
|
|
101
|
-
return this;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Orgs code
|
|
105
|
-
* @param orgCode
|
|
106
|
-
* @returns code
|
|
107
|
-
*/
|
|
108
|
-
orgCode(orgCode) {
|
|
109
|
-
this.transactionDocument.orgCode = orgCode;
|
|
110
|
-
return this;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Stores id
|
|
114
|
-
* @param storeId
|
|
115
|
-
* @returns id
|
|
116
|
-
*/
|
|
117
|
-
storeId(storeId) {
|
|
118
|
-
this.transactionDocument.storeId = storeId;
|
|
119
|
-
return this;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Dates time
|
|
123
|
-
* @returns time
|
|
124
|
-
*/
|
|
125
|
-
dateTime() {
|
|
126
|
-
const date = new Date();
|
|
127
|
-
this.transactionDocument.dateTime = date.toISOString();
|
|
128
|
-
return this;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Devices id
|
|
132
|
-
* @param deviceId
|
|
133
|
-
* @returns id
|
|
134
|
-
*/
|
|
135
|
-
deviceId(deviceId) {
|
|
136
|
-
this.transactionDocument.deviceId = deviceId;
|
|
137
|
-
return this;
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* terminal id
|
|
141
|
-
* @param terminalId
|
|
142
|
-
* @returns id
|
|
143
|
-
*/
|
|
144
|
-
terminalId(terminalId) {
|
|
145
|
-
this.transactionDocument.terminalId = terminalId;
|
|
146
|
-
return this;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* saleExport
|
|
150
|
-
* @param saleExport
|
|
151
|
-
* @returns id
|
|
152
|
-
*/
|
|
153
|
-
export(saleExport) {
|
|
154
|
-
this.transactionDocument.export = saleExport;
|
|
155
|
-
return this;
|
|
156
|
-
}
|
|
157
|
-
/* customer(): TransactionDocumentBuilder {
|
|
158
|
-
const user = JSON.parse(localStorage.getItem('userDetails'));
|
|
159
|
-
this.transactionDocument.customer = user;
|
|
160
|
-
return this;
|
|
161
|
-
} */
|
|
162
|
-
/**
|
|
163
|
-
* Baskets transaction document builder
|
|
164
|
-
* @param basketDetails
|
|
165
|
-
* @returns basket
|
|
166
|
-
*/
|
|
167
|
-
basket(basketDetails) {
|
|
168
|
-
AppLoggerService.logDebug(this.className, "basket", "basket details update in transaction document", basketDetails);
|
|
169
|
-
this.transactionDocument.subsidiaryId = basketDetails.subsidiaryId || (localStorage.getItem('subsidiaryId') || '');
|
|
170
|
-
this.transactionDocument.basket.products = [];
|
|
171
|
-
this.transactionDocument.basket.lineDiscount = [];
|
|
172
|
-
this.transactionDocument.basket.linePromotion = [];
|
|
173
|
-
this.transactionDocument.basket.transactionPromotion = [];
|
|
174
|
-
basketDetails.products.forEach((product, index) => {
|
|
175
|
-
const p = {};
|
|
176
|
-
p.itemDiscounts = {};
|
|
177
|
-
p.SKU = product.SKU;
|
|
178
|
-
p.excludePromotion = product.excludePromotion;
|
|
179
|
-
p.barCode = product.barcode;
|
|
180
|
-
p.barcodes = product.barcodes;
|
|
181
|
-
p.description = product.description;
|
|
182
|
-
p.itemLineId = product.itemLineId ? product.itemLineId.toString() : "" + (index + 1);
|
|
183
|
-
p.price = product.selectedPrice;
|
|
184
|
-
p.quantity = product.quantity;
|
|
185
|
-
p.totalLinePrice = product.quantity * product.selectedPrice;
|
|
186
|
-
p.imageUrls = product.imageUrls;
|
|
187
|
-
p.selectedRRPPrice = product.selectedRRPPrice;
|
|
188
|
-
//inventory fields
|
|
189
|
-
p.fullfilmentId = product.fullfilmentId ? product.fullfilmentId : this.storeInfo.storeId;
|
|
190
|
-
p.fullfilmentLocationName = product.fullfilmentLocationName;
|
|
191
|
-
p.deliveryGroup = product.deliveryGroup;
|
|
192
|
-
p.leadTime = product.leadTime;
|
|
193
|
-
p.deliveryMethod = product.deliveryMethod;
|
|
194
|
-
p.giftCard = product.giftCard;
|
|
195
|
-
p.giftCardExpiryDate = product.giftCardExpiryDate;
|
|
196
|
-
p.giftCardNumberIssued = product.giftCardNumberIssued;
|
|
197
|
-
p.giftCardRecipientEmail = product.giftCardRecipientEmail;
|
|
198
|
-
p.giftCardRecipientName = product.giftCardRecipientName;
|
|
199
|
-
if (product.refundedQuantity > 0) {
|
|
200
|
-
p.refundedQuantity = product.refundedQuantity;
|
|
201
|
-
p.refundedPromotionalQuantity = product.refundPromotionalQuantity;
|
|
202
|
-
p.refunded = product.refunded;
|
|
203
|
-
p.refundedReasonDescription = product.refundedReasonDescription;
|
|
204
|
-
p.refundedReason = product.refundedReason;
|
|
205
|
-
if (!p.refundedReasonDescription) {
|
|
206
|
-
p.refundedReasonDescription = p.refundedReason;
|
|
207
|
-
}
|
|
208
|
-
p.refundedTotal = product.refundedTotal;
|
|
209
|
-
p.isLastExchanged = product.isLastExchanged;
|
|
210
|
-
}
|
|
211
|
-
if (product.exchange) {
|
|
212
|
-
p.exchange = product.exchange;
|
|
213
|
-
}
|
|
214
|
-
if (product.lineDiscount) {
|
|
215
|
-
p.lineDiscount = product.lineDiscount;
|
|
216
|
-
}
|
|
217
|
-
p.itemDiscounts = product.itemDiscounts;
|
|
218
|
-
this.transactionDocument.basket.products.push(p);
|
|
219
|
-
this.lineDiscount(basketDetails);
|
|
220
|
-
});
|
|
221
|
-
AppLoggerService.logInfo(this.className, "basket", "transactiondocument basket details updated", this.transactionDocument.basket);
|
|
222
|
-
return this;
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* current transaction Details Total(New Products)
|
|
226
|
-
* @returns currentTransactionDetails
|
|
227
|
-
*/
|
|
228
|
-
currentTransactionDetails(basket) {
|
|
229
|
-
AppLoggerService.logDebug(this.className, "currentTransactionDetails", "current transaction details for exchanges", basket);
|
|
230
|
-
this.transactionDocument.currentTransactionDetails.products = [];
|
|
231
|
-
this.transactionDocument.currentTransactionDetails.linePromotion = [];
|
|
232
|
-
this.transactionDocument.currentTransactionDetails.lineDiscount = [];
|
|
233
|
-
this.transactionDocument.currentTransactionDetails.transactionDiscount = [];
|
|
234
|
-
this.transactionDocument.currentTransactionDetails.products = basket.products;
|
|
235
|
-
this.transactionDocument.currentTransactionDetails.products = this.transactionDocument.currentTransactionDetails.products.filter((proj) => proj.refundedQuantity != 0);
|
|
236
|
-
this.transactionDocument.currentTransactionDetails.products.forEach((product) => {
|
|
237
|
-
if (product.refundedQuantity) {
|
|
238
|
-
product.quantity = product.refundedQuantity;
|
|
239
|
-
// updating total line price with actual price to be refunded including the refunding qty
|
|
240
|
-
product.totalLinePrice = Math.abs(product.refundedTotal);
|
|
241
|
-
product.total = product.totalLinePrice;
|
|
242
|
-
if (product.quantity === product.refundedQuantity) {
|
|
243
|
-
product.refunded = true;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
//Updating line promotions and line discounts
|
|
247
|
-
if (product.linePromotions && !product.refundedQuantity) {
|
|
248
|
-
this.transactionDocument.currentTransactionDetails.linePromotion.push(product.linePromotions);
|
|
249
|
-
}
|
|
250
|
-
if (product.lineDiscount && !product.refundedQuantity) {
|
|
251
|
-
this.transactionDocument.currentTransactionDetails.lineDiscount.push(product.lineDiscount);
|
|
252
|
-
}
|
|
253
|
-
});
|
|
254
|
-
AppLoggerService.logDebug(this.className, "currentTransactionDetails", "current transaction details after removing old products", this.transactionDocument.currentTransactionDetails.products);
|
|
255
|
-
if (basket.transactionDiscount && basket.transactionDiscount.length > 0) {
|
|
256
|
-
this.transactionDocument.currentTransactionDetails.transactionDiscount.push(...basket.transactionDiscount);
|
|
257
|
-
}
|
|
258
|
-
this.transactionDocument.currentTransactionDetails.basketSummary = {};
|
|
259
|
-
this.transactionDocument.currentTransactionDetails.basketSummary.saleTotal = this.numberUtilService.trimTo2Decimal2(this.updateSaleTotal(this.transactionDocument.currentTransactionDetails));
|
|
260
|
-
this.transactionDocument.currentTransactionDetails.basketSummary.totalItems = basket.quantity;
|
|
261
|
-
this.transactionDocument.currentTransactionDetails.basketSummary.basketTotal = basket.basketTotal;
|
|
262
|
-
this.transactionDocument.currentTransactionDetails.basketSummary.refundTotal = this.updateCurrentTransactionDetailsRefundTotal();
|
|
263
|
-
// For partial refund discount is updatied in total line price so discountTotal will always be zero & in case of exchange discount total is calculated
|
|
264
|
-
if (this.transactionDocument.type === TRANSACTION_TYPE.SALE_EXCHANGE) {
|
|
265
|
-
this.transactionDocument.currentTransactionDetails.basketSummary.discountTotal = this.numberUtilService.trimTo2Decimal2(this.updateCurrentTransactionDetailsDiscountTotal());
|
|
266
|
-
}
|
|
267
|
-
else {
|
|
268
|
-
if (this.transactionDocument.currentTransactionDetails.transactionDiscount && this.transactionDocument.currentTransactionDetails.transactionDiscount.length > 0) {
|
|
269
|
-
let discountTotal = 0;
|
|
270
|
-
this.transactionDocument.currentTransactionDetails.transactionDiscount.forEach((discount) => {
|
|
271
|
-
discountTotal += discount.discountAmount;
|
|
272
|
-
});
|
|
273
|
-
this.transactionDocument.currentTransactionDetails.basketSummary.discountTotal = Math.abs(discountTotal);
|
|
274
|
-
}
|
|
275
|
-
else {
|
|
276
|
-
this.transactionDocument.currentTransactionDetails.basketSummary.discountTotal = 0;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
AppLoggerService.logInfo(this.className, "currentTransactionDetails", "currentTransactionDetails", this.transactionDocument.currentTransactionDetails);
|
|
280
|
-
return this;
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* current transaction Tax Total
|
|
284
|
-
* @returns Tax Total
|
|
285
|
-
*/
|
|
286
|
-
updateCurrentTransactionDetailsTaxBreakdown(basketDetails) {
|
|
287
|
-
let transactionDiscountTotal = 0;
|
|
288
|
-
let taxBreakdown = {
|
|
289
|
-
taxLines: [],
|
|
290
|
-
totalTaxableAmount: 0,
|
|
291
|
-
};
|
|
292
|
-
if (this.transactionDocument.currentTransactionDetails.transactionDiscount && this.transactionDocument.currentTransactionDetails.transactionDiscount.length > 0) {
|
|
293
|
-
this.transactionDocument.currentTransactionDetails.transactionDiscount.forEach((discount) => {
|
|
294
|
-
transactionDiscountTotal += discount.discountAmount;
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
if (this.transactionDocument.currentTransactionDetails.products && this.transactionDocument.currentTransactionDetails.products.length > 0) {
|
|
298
|
-
this.transactionDocument.currentTransactionDetails.products.forEach((product) => {
|
|
299
|
-
let taxLine = {
|
|
300
|
-
itemLineId: product.itemLineId,
|
|
301
|
-
VAT: product.selectedVAT ? product.selectedVAT : 0,
|
|
302
|
-
VATCode: product.selectedVATCode,
|
|
303
|
-
taxLineTotal: 0,
|
|
304
|
-
taxableAmount: product.total,
|
|
305
|
-
PreTax: 0
|
|
306
|
-
};
|
|
307
|
-
AppLoggerService.logInfo(this.className, "updateCurrentTransactionDetailsTaxBreakdown", `item line ID :current transaction Details",
|
|
308
|
-
${product.itemLineId}, tax line : ${taxLine}, basketDetails.basketTotal ${basketDetails.basketTotal}`);
|
|
309
|
-
//step 1
|
|
310
|
-
// if Transaction Discount and/or promotion applied, find net selling price of each product as taxableamount
|
|
311
|
-
//If transaction discount/promotion is applied taxable amount should be deducting transaction promotion and transaction disacount portion
|
|
312
|
-
if (product.refundedQuantity && product.refundedQuantity > 0) {
|
|
313
|
-
taxLine.taxableAmount = -Math.abs(taxLine.taxableAmount - product.itemDiscounts.currentRefundPortion);
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
taxLine.taxableAmount = taxLine.taxableAmount - product.itemDiscounts.trnDiscountsPortion - product.itemDiscounts.trnPromotionsPortion;
|
|
317
|
-
}
|
|
318
|
-
//step 2 - find pre tax
|
|
319
|
-
taxLine.PreTax = this.numberUtilService.trimTo2Decimal2((taxLine.taxableAmount * 100) / (100 + taxLine.VAT));
|
|
320
|
-
//step 3 - Update taxbreakdown
|
|
321
|
-
taxBreakdown.totalTaxableAmount += taxLine.taxableAmount;
|
|
322
|
-
taxLine.taxableAmount = this.numberUtilService.trimTo2Decimal2(taxLine.taxableAmount);
|
|
323
|
-
// step 4 - update tax Line total
|
|
324
|
-
taxLine.taxLineTotal = this.numberUtilService.trimTo2Decimal2(taxLine.taxableAmount - taxLine.PreTax);
|
|
325
|
-
taxBreakdown.taxLines.push(taxLine);
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
taxBreakdown.totalTaxableAmount = this.numberUtilService.trimTo2Decimal2(taxBreakdown.totalTaxableAmount);
|
|
329
|
-
this.transactionDocument.currentTransactionDetails.taxBreakdown = taxBreakdown;
|
|
330
|
-
if (this.transactionDocument.currentTransactionDetails.taxBreakdown && this.transactionDocument.currentTransactionDetails.taxBreakdown.taxLines && this.transactionDocument.currentTransactionDetails.taxBreakdown.taxLines.length > 0) {
|
|
331
|
-
this.transactionDocument.currentTransactionDetails.basketSummary.VATTotal = this.numberUtilService.trimTo2Decimal2(this.transactionDocument.currentTransactionDetails.taxBreakdown.taxLines.reduce((n, { taxLineTotal }) => n + taxLineTotal, 0));
|
|
332
|
-
}
|
|
333
|
-
else {
|
|
334
|
-
this.transactionDocument.currentTransactionDetails.basketSummary.VATTotal = 0.00;
|
|
335
|
-
}
|
|
336
|
-
AppLoggerService.logDebug(this.className, "updateCurrentTransactionDetailsTaxBreakdown", "eBasket:after calculating tax currenttransactionDetails", this.transactionDocument.currentTransactionDetails);
|
|
337
|
-
return this;
|
|
338
|
-
}
|
|
339
|
-
updateCurrentTransactionDetailsTotalTaxSummary() {
|
|
340
|
-
AppLoggerService.logDebug(this.className, "updateCurrentTransactionDetailsTotalTaxSummary", "Total Tax Summery Request :", this.transactionDocument.currentTransactionDetails.taxBreakdown);
|
|
341
|
-
let totalTaxSummaryArray = [];
|
|
342
|
-
let totalTaxSummaryGroup = [];
|
|
343
|
-
this.transactionDocument.currentTransactionDetails.taxBreakdown.taxLines.forEach((element) => {
|
|
344
|
-
let TaxSummary = {
|
|
345
|
-
VATCode: "",
|
|
346
|
-
VAT: -12345,
|
|
347
|
-
PreTaxSum: 0,
|
|
348
|
-
TaxSum: 0,
|
|
349
|
-
TXrateSum: 0
|
|
350
|
-
};
|
|
351
|
-
TaxSummary.VATCode = element.VATCode;
|
|
352
|
-
TaxSummary.VAT = element.VAT;
|
|
353
|
-
TaxSummary.PreTaxSum = this.numberUtilService.trimTo2Decimal2(element.PreTax);
|
|
354
|
-
TaxSummary.TaxSum = this.numberUtilService.trimTo2Decimal2(element.taxLineTotal);
|
|
355
|
-
TaxSummary.TXrateSum = this.numberUtilService.trimTo2Decimal2(TaxSummary.PreTaxSum + TaxSummary.TaxSum);
|
|
356
|
-
totalTaxSummaryArray.push(TaxSummary);
|
|
357
|
-
});
|
|
358
|
-
AppLoggerService.logDebug(this.className, "updateCurrentTransactionDetailsTotalTaxSummary", "Total Tax Summery Without Grouped : ", totalTaxSummaryArray);
|
|
359
|
-
totalTaxSummaryGroup = totalTaxSummaryArray.reduce((preparedArray, currentObj) => {
|
|
360
|
-
let ind = preparedArray.findIndex((x) => x.VAT === currentObj.VAT);
|
|
361
|
-
if (ind === -1) {
|
|
362
|
-
preparedArray.push(currentObj);
|
|
363
|
-
}
|
|
364
|
-
else {
|
|
365
|
-
preparedArray[ind].VATCode = currentObj.VATCode;
|
|
366
|
-
preparedArray[ind].VAT = currentObj.VAT;
|
|
367
|
-
preparedArray[ind].PreTaxSum += currentObj.PreTaxSum;
|
|
368
|
-
preparedArray[ind].TaxSum += currentObj.TaxSum;
|
|
369
|
-
preparedArray[ind].TXrateSum += currentObj.TXrateSum;
|
|
370
|
-
}
|
|
371
|
-
return preparedArray;
|
|
372
|
-
}, []);
|
|
373
|
-
// listOfTags.map(x => unique.filter(a => a.label == x.label && a.color == x.color).length > 0 ? null : unique.push(x));
|
|
374
|
-
AppLoggerService.logDebug(this.className, "updateCurrentTransactionDetailsTotalTaxSummary", "Total Tax Summer Group :", totalTaxSummaryGroup);
|
|
375
|
-
this.transactionDocument.currentTransactionDetails.totalTaxSummary = totalTaxSummaryGroup;
|
|
376
|
-
return this;
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* current transaction Disocunt Total
|
|
380
|
-
* @returns Discount Total
|
|
381
|
-
*/
|
|
382
|
-
updateCurrentTransactionDetailsDiscountTotal() {
|
|
383
|
-
let refundTotal = this.transactionDocument.currentTransactionDetails.basketSummary.refundTotal ? this.transactionDocument.currentTransactionDetails.basketSummary.refundTotal : 0;
|
|
384
|
-
AppLoggerService.logDebug(this.className, "updateCurrentTransactionDetailsDiscountTotal", `refundTotal ${refundTotal}, basketTotal ${this.transactionDocument.currentTransactionDetails.basketSummary.basketTotal},saleTotal ${this.transactionDocument.currentTransactionDetails.basketSummary.saleTotal}`);
|
|
385
|
-
const discountTotal = Math.abs(Math.abs(this.transactionDocument.currentTransactionDetails.basketSummary.saleTotal) -
|
|
386
|
-
(Math.abs(this.transactionDocument.currentTransactionDetails.basketSummary.basketTotal) + Math.abs(refundTotal)));
|
|
387
|
-
AppLoggerService.logDebug(this.className, "updateCurrentTransactionDetailsDiscountTotal", "discountTotal", discountTotal);
|
|
388
|
-
return Number(discountTotal.toFixed(2));
|
|
389
|
-
}
|
|
390
|
-
/**
|
|
391
|
-
* current transaction Refund Total
|
|
392
|
-
* @returns Refund Total
|
|
393
|
-
*/
|
|
394
|
-
updateCurrentTransactionDetailsRefundTotal() {
|
|
395
|
-
let totalRefund = 0;
|
|
396
|
-
for (let index = 0; index < this.transactionDocument.currentTransactionDetails.products.length; index++) {
|
|
397
|
-
const product = this.transactionDocument.currentTransactionDetails.products[index];
|
|
398
|
-
if (product.refundedTotal) {
|
|
399
|
-
totalRefund = totalRefund + product.refundedTotal;
|
|
400
|
-
}
|
|
401
|
-
AppLoggerService.logDebug(this.className, "updateCurrentTransactionDetailsRefundTotal", "totalRefund for Current TransactionDetails", totalRefund);
|
|
402
|
-
}
|
|
403
|
-
return totalRefund;
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* Baskets summary
|
|
407
|
-
* @param basketDetails
|
|
408
|
-
* @returns summary
|
|
409
|
-
*/
|
|
410
|
-
basketSummary(basketDetails) {
|
|
411
|
-
this.transactionDocument.basketSummary.basketTotal = this.numberUtilService.trimTo2Decimal(basketDetails.basketTotal);
|
|
412
|
-
this.transactionDocument.basketSummary.saleTotal = this.numberUtilService.trimTo2Decimal2(this.updateSaleTotal(basketDetails));
|
|
413
|
-
this.transactionDocument.basketSummary.refundTotal = this.getRefundTotal();
|
|
414
|
-
if (this.transactionDocument.basket.lineDiscount ||
|
|
415
|
-
this.transactionDocument.basket.linePromotion) {
|
|
416
|
-
this.transactionDocument.basketSummary.discountTotal = this.numberUtilService.trimTo2Decimal2(this.updateDiscountTotal());
|
|
417
|
-
}
|
|
418
|
-
this.transactionDocument.basketSummary.totalItems = basketDetails.quantity;
|
|
419
|
-
if (this.transactionDocument.basket.taxBreakdown) {
|
|
420
|
-
this.transactionDocument.basketSummary.VATTotal = this.numberUtilService.trimTo2Decimal2(this.transactionDocument.basket.taxBreakdown.taxLines.reduce((n, { taxLineTotal }) => n + taxLineTotal, 0));
|
|
421
|
-
}
|
|
422
|
-
else {
|
|
423
|
-
this.transactionDocument.basketSummary.VATTotal = 0.00;
|
|
424
|
-
}
|
|
425
|
-
AppLoggerService.logInfo(this.className, "basketSummary", "basketsummary updated in transaction document: ", this.transactionDocument.basketSummary);
|
|
426
|
-
return this;
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* Line Discount
|
|
430
|
-
* @param basketDetails
|
|
431
|
-
* @returns line Discount
|
|
432
|
-
*/
|
|
433
|
-
lineDiscount(basketDetails) {
|
|
434
|
-
this.transactionDocument.basket.lineDiscount = [];
|
|
435
|
-
for (let index = 0; index < basketDetails.products.length; index++) {
|
|
436
|
-
const element = basketDetails.products[index];
|
|
437
|
-
if (element.lineDiscount) {
|
|
438
|
-
this.transactionDocument.basket.lineDiscount.push(element.lineDiscount);
|
|
439
|
-
this.transactionDocument.basket.lineDiscount = this.transactionDocument.basket.lineDiscount.reduce((acc, val) => {
|
|
440
|
-
if (!acc.find((el) => el.itemLineId === val.itemLineId)) {
|
|
441
|
-
acc.push(val);
|
|
442
|
-
}
|
|
443
|
-
return acc;
|
|
444
|
-
}, []);
|
|
445
|
-
}
|
|
446
|
-
// AppLoggerService.logInfo(this.className,
|
|
447
|
-
// "e-basket :line discount updated in transaction document",
|
|
448
|
-
// this.transactionDocument.basket.lineDiscount
|
|
449
|
-
// );
|
|
450
|
-
}
|
|
451
|
-
return this;
|
|
452
|
-
}
|
|
453
|
-
/**
|
|
454
|
-
* exchange
|
|
455
|
-
* @param basketDetails
|
|
456
|
-
* @returns exchange
|
|
457
|
-
*/
|
|
458
|
-
exchange(basketDetails) {
|
|
459
|
-
this.transactionDocument.basket.exchange = basketDetails.exchange && basketDetails.exchange.length > 0 ? [...basketDetails.exchange] : [];
|
|
460
|
-
for (let index = 0; index < basketDetails.products.length; index++) {
|
|
461
|
-
const element = basketDetails.products[index];
|
|
462
|
-
if (element.exchange != undefined) {
|
|
463
|
-
const isPresent = this.transactionDocument.basket.exchange.some((el) => el.exchangeId === element.exchange.exchangeId);
|
|
464
|
-
if (!isPresent) {
|
|
465
|
-
let exchangeItems = [];
|
|
466
|
-
for (let j = 0; j < element.exchange.newItems.length; j++) {
|
|
467
|
-
const item = element.exchange.newItems[j];
|
|
468
|
-
let newItems = { lineItemId: item.itemLineId, Quantity: item.quantity };
|
|
469
|
-
exchangeItems.push(newItems);
|
|
470
|
-
}
|
|
471
|
-
element.exchange.newItems = [...exchangeItems];
|
|
472
|
-
this.transactionDocument.basket.exchange.push(element.exchange);
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
AppLoggerService.logDebug(this.className, "exchange", "this.transactionDocument.basket exchange", this.transactionDocument.basket.exchange);
|
|
476
|
-
}
|
|
477
|
-
return this;
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
* add previous exchange data
|
|
481
|
-
* @param originalTransactionDocument
|
|
482
|
-
* @returns line Promotions
|
|
483
|
-
*/
|
|
484
|
-
addExchangeData(originalTransactionDocument) {
|
|
485
|
-
this.transactionDocument.basket.exchange = originalTransactionDocument.basket.exchange ? [...originalTransactionDocument.basket.exchange] : null;
|
|
486
|
-
return this;
|
|
487
|
-
}
|
|
488
|
-
/**
|
|
489
|
-
* line Promotions
|
|
490
|
-
* @param basketDetails
|
|
491
|
-
* @returns line Promotions
|
|
492
|
-
*/
|
|
493
|
-
linePromotion(basketDetails) {
|
|
494
|
-
this.transactionDocument.basket.linePromotion = [];
|
|
495
|
-
for (let index = 0; index < basketDetails.products.length; index++) {
|
|
496
|
-
const element = basketDetails.products[index];
|
|
497
|
-
if (element.linePromotions) {
|
|
498
|
-
this.transactionDocument.basket.linePromotion.push(element.linePromotions);
|
|
499
|
-
this.transactionDocument.basket.linePromotion = this.transactionDocument.basket.linePromotion.reduce((acc, val) => {
|
|
500
|
-
if (!acc.find((el) => el.itemLineId === val.itemLineId)) {
|
|
501
|
-
acc.push(val);
|
|
502
|
-
}
|
|
503
|
-
return acc;
|
|
504
|
-
}, []);
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
return this;
|
|
508
|
-
}
|
|
509
|
-
/**
|
|
510
|
-
* transaction Promotion
|
|
511
|
-
* @param basketDetails
|
|
512
|
-
* @returns transaction Promotion
|
|
513
|
-
*/
|
|
514
|
-
transactionPromotion(basketDetails) {
|
|
515
|
-
if (basketDetails.transactionPromotion) {
|
|
516
|
-
this.transactionDocument.basket.transactionPromotion =
|
|
517
|
-
basketDetails.transactionPromotion;
|
|
518
|
-
// for (let index = 0; index < basketDetails.TransactionDiscount.length; index++) {
|
|
519
|
-
// this.transactionDocument.basket.transactionPromotion.push(element.linePromotions)
|
|
520
|
-
// this.transactionDocument.basket.transactionPromotion = this.transactionDocument.basket.linePromotions.reduce((acc, val) => {
|
|
521
|
-
// if (!acc.find(el => el.itemLineId === val.itemLineId)) {
|
|
522
|
-
// acc.push(val);
|
|
523
|
-
// }
|
|
524
|
-
// return acc;
|
|
525
|
-
// }, []);
|
|
526
|
-
// }
|
|
527
|
-
AppLoggerService.logDebug(this.className, "transactionPromotion", "this.transactionDocument.basket.transactionPromotion", this.transactionDocument.basket.transactionPromotion);
|
|
528
|
-
}
|
|
529
|
-
return this;
|
|
530
|
-
}
|
|
531
|
-
transactionDiscount(basketDetails) {
|
|
532
|
-
if (basketDetails.transactionDiscount) {
|
|
533
|
-
this.transactionDocument.basket.transactionDiscount =
|
|
534
|
-
basketDetails.transactionDiscount;
|
|
535
|
-
AppLoggerService.logDebug(this.className, "transactionDiscount", "transaction Discount", this.transactionDocument.basket.transactionDiscount);
|
|
536
|
-
}
|
|
537
|
-
return this;
|
|
538
|
-
}
|
|
539
|
-
/**
|
|
540
|
-
* Payments details
|
|
541
|
-
* @param paymentDetails
|
|
542
|
-
* @returns
|
|
543
|
-
*/
|
|
544
|
-
paymentDetails(paymentDetails) {
|
|
545
|
-
AppLoggerService.logInfo(this.className, "paymentDetails", "payment details after transaction completed", paymentDetails);
|
|
546
|
-
this.transactionDocument.paymentDetails = paymentDetails;
|
|
547
|
-
return this;
|
|
548
|
-
}
|
|
549
|
-
/**
|
|
550
|
-
* Payments details
|
|
551
|
-
* @param paymentDetails
|
|
552
|
-
* @returns
|
|
553
|
-
*/
|
|
554
|
-
splitPayment(splitPayment) {
|
|
555
|
-
this.transactionDocument.splitPayment = splitPayment;
|
|
556
|
-
return this;
|
|
557
|
-
}
|
|
558
|
-
/**
|
|
559
|
-
* Payments details
|
|
560
|
-
* @param paymentDetails
|
|
561
|
-
* @returns
|
|
562
|
-
*/
|
|
563
|
-
isPaymentCompleted(isPaymentCompleted) {
|
|
564
|
-
this.transactionDocument.isPaymentCompleted = isPaymentCompleted;
|
|
565
|
-
return this;
|
|
566
|
-
}
|
|
567
|
-
/**
|
|
568
|
-
* Bases currency
|
|
569
|
-
* @param currency
|
|
570
|
-
* @returns currency
|
|
571
|
-
*/
|
|
572
|
-
baseCurrency(currency) {
|
|
573
|
-
this.transactionDocument.baseCurrency = currency;
|
|
574
|
-
return this;
|
|
575
|
-
}
|
|
576
|
-
/**
|
|
577
|
-
* gift option at
|
|
578
|
-
* @returns at
|
|
579
|
-
*/
|
|
580
|
-
giftOption(gift) {
|
|
581
|
-
AppLoggerService.logDebug(this.className, "giftOption", "this.transactionDocument.giftoption", gift);
|
|
582
|
-
if (gift) {
|
|
583
|
-
this.transactionDocument.giftedReceipt = gift;
|
|
584
|
-
}
|
|
585
|
-
return this;
|
|
586
|
-
}
|
|
587
|
-
/**
|
|
588
|
-
|
|
589
|
-
/**
|
|
590
|
-
* manual Discount
|
|
591
|
-
* @param discountData
|
|
592
|
-
* @returns
|
|
593
|
-
*/
|
|
594
|
-
// manualDiscount(discountData : basketDiscount):TransactionDocumentBuilder {
|
|
595
|
-
// let saleTotal = this.transactionDocument.basketSummary.basketTotal;
|
|
596
|
-
// if(discountData.discountType =='Percent'){
|
|
597
|
-
// this.transactionDocument.basketSummary.basketTotal = saleTotal-(saleTotal*(discountData.discountAmount/100));
|
|
598
|
-
// discountData.discountAmount = -1*(saleTotal-this.transactionDocument.basketSummary.basketTotal);
|
|
599
|
-
// }else {
|
|
600
|
-
// this.transactionDocument.basketSummary.basketTotal =saleTotal-discountData.discountAmount;
|
|
601
|
-
// discountData.discountAmount = -1*discountData.discountAmount;
|
|
602
|
-
// }
|
|
603
|
-
// this.transactionDocument.transactionDiscount.push(discountData);
|
|
604
|
-
// return this;
|
|
605
|
-
// }
|
|
606
|
-
/**
|
|
607
|
-
* Types transaction document builder
|
|
608
|
-
* @param t
|
|
609
|
-
* @returns type
|
|
610
|
-
*/
|
|
611
|
-
type(t) {
|
|
612
|
-
this.transactionDocument.type = t;
|
|
613
|
-
return this;
|
|
614
|
-
}
|
|
615
|
-
/**
|
|
616
|
-
* Operations status
|
|
617
|
-
* @param o
|
|
618
|
-
* @returns status
|
|
619
|
-
*/
|
|
620
|
-
operationStatus(o) {
|
|
621
|
-
this.transactionDocument.operationStatus = o;
|
|
622
|
-
return this;
|
|
623
|
-
}
|
|
624
|
-
/**
|
|
625
|
-
* Created at
|
|
626
|
-
* @returns at
|
|
627
|
-
*/
|
|
628
|
-
createdAt() {
|
|
629
|
-
const date = new Date();
|
|
630
|
-
this.transactionDocument.createdAt = date.toISOString();
|
|
631
|
-
this.transactionDocument.updatedAt = date.toISOString();
|
|
632
|
-
return this;
|
|
633
|
-
}
|
|
634
|
-
/**
|
|
635
|
-
* Updated at
|
|
636
|
-
* @returns at
|
|
637
|
-
*/
|
|
638
|
-
updatedAt() {
|
|
639
|
-
const date = new Date();
|
|
640
|
-
this.transactionDocument.updatedAt = date.toISOString();
|
|
641
|
-
return this;
|
|
642
|
-
}
|
|
643
|
-
/**
|
|
644
|
-
* transsaction completion at
|
|
645
|
-
* @returns transaction completion date
|
|
646
|
-
*/
|
|
647
|
-
transactionCompletedAt() {
|
|
648
|
-
const date = new Date();
|
|
649
|
-
this.transactionDocument.transCompletedAt = date.toISOString();
|
|
650
|
-
return this;
|
|
651
|
-
}
|
|
652
|
-
/**
|
|
653
|
-
* Builds transaction document builder
|
|
654
|
-
* @returns build
|
|
655
|
-
*/
|
|
656
|
-
build() {
|
|
657
|
-
return this.transactionDocument;
|
|
658
|
-
}
|
|
659
|
-
/**
|
|
660
|
-
* Sales total in refund
|
|
661
|
-
* @param saleTotal
|
|
662
|
-
* @returns total in refund
|
|
663
|
-
*/
|
|
664
|
-
saleTotalInRefund(saleTotal) {
|
|
665
|
-
this.transactionDocument.saleTotal = saleTotal;
|
|
666
|
-
return this;
|
|
667
|
-
}
|
|
668
|
-
/**
|
|
669
|
-
* Gets basket details
|
|
670
|
-
* @returns basket details
|
|
671
|
-
*/
|
|
672
|
-
getBasketDetails() {
|
|
673
|
-
AppLoggerService.logInfo(this.className, "getBasketDetails", "Getting Basket for transactionDocument", this.transactionDocument);
|
|
674
|
-
let basket = {
|
|
675
|
-
subsidiaryId: this.transactionDocument.subsidiaryId,
|
|
676
|
-
transactionDiscount: this.transactionDocument.basket.transactionDiscount,
|
|
677
|
-
transactionPromotion: this.transactionDocument.basket.transactionPromotion,
|
|
678
|
-
transactionId: this.transactionDocument.transactionId,
|
|
679
|
-
offlineTransactionId: this.transactionDocument.offlineTransactionId,
|
|
680
|
-
total: this.transactionDocument.basketSummary.basketTotal,
|
|
681
|
-
basketTotal: this.transactionDocument.basketSummary.basketTotal,
|
|
682
|
-
discountTotal: this.transactionDocument.basketSummary.discountTotal,
|
|
683
|
-
saleTotal: this.transactionDocument.basketSummary.saleTotal,
|
|
684
|
-
refundTotal: this.transactionDocument.basketSummary.refundTotal,
|
|
685
|
-
quantity: this.transactionDocument.basketSummary.totalItems,
|
|
686
|
-
products: [],
|
|
687
|
-
baseCurrency: this.transactionDocument.baseCurrency,
|
|
688
|
-
customer: this.transactionDocument.customer,
|
|
689
|
-
};
|
|
690
|
-
basket.products = [];
|
|
691
|
-
this.transactionDocument.basket.products.forEach((product, index) => {
|
|
692
|
-
AppLoggerService.logDebug(this.className, JSON.stringify(product), "ebasket: basket detail update in basket");
|
|
693
|
-
const p = {};
|
|
694
|
-
p.SKU = product.SKU;
|
|
695
|
-
p.barcode = product.barCode;
|
|
696
|
-
p.barcodes = product.barcodes;
|
|
697
|
-
p.description = product.description;
|
|
698
|
-
p.imageUrls = product.imageUrls;
|
|
699
|
-
p.currency = this.transactionDocument.baseCurrency;
|
|
700
|
-
p.totalLinePrice = product.totalLinePrice;
|
|
701
|
-
p.itemLineId = Number(product.itemLineId);
|
|
702
|
-
p.excludePromotion = product.excludePromotion;
|
|
703
|
-
p.selectedPrice = product.price;
|
|
704
|
-
p.quantity = product.quantity;
|
|
705
|
-
p.total = product.totalLinePrice;
|
|
706
|
-
p.selectedRRPPrice = product.selectedRRPPrice;
|
|
707
|
-
p.fullfilmentId = product.fullfilmentId;
|
|
708
|
-
p.fullfilmentLocationName = product.fullfilmentLocationName;
|
|
709
|
-
p.deliveryGroup = product.deliveryGroup || "1";
|
|
710
|
-
p.leadTime = product.leadTime;
|
|
711
|
-
p.deliveryMethod = product.deliveryMethod || DELIVERY_METHODS.COLLECT_FROM_STORE.toString();
|
|
712
|
-
if (p.fullfilmentId != this.transactionDocument.storeId) {
|
|
713
|
-
p.isWebOrder = true;
|
|
714
|
-
}
|
|
715
|
-
p.giftCard = product.giftCard;
|
|
716
|
-
p.giftCardExpiryDate = product.giftCardExpiryDate;
|
|
717
|
-
p.giftCardNumberIssued = product.giftCardNumberIssued;
|
|
718
|
-
p.giftCardRecipientEmail = product.giftCardRecipientEmail;
|
|
719
|
-
p.giftCardRecipientName = product.giftCardRecipientName;
|
|
720
|
-
if (this.transactionDocument.basket.lineDiscount &&
|
|
721
|
-
this.transactionDocument.basket.lineDiscount.length > 0) {
|
|
722
|
-
this.transactionDocument.basket.lineDiscount.forEach((lineDiscount) => {
|
|
723
|
-
if (product.itemLineId === lineDiscount.itemLineId.toString()) {
|
|
724
|
-
p.lineDiscount = lineDiscount;
|
|
725
|
-
p.total = lineDiscount.discountedLinePrice;
|
|
726
|
-
}
|
|
727
|
-
});
|
|
728
|
-
}
|
|
729
|
-
if (this.transactionDocument.basket.linePromotion &&
|
|
730
|
-
this.transactionDocument.basket.linePromotion.length > 0) {
|
|
731
|
-
this.transactionDocument.basket.linePromotion.forEach((linePromotion) => {
|
|
732
|
-
if (product.itemLineId === linePromotion.itemLineId.toString()) {
|
|
733
|
-
p.linePromotions = linePromotion;
|
|
734
|
-
p.total = linePromotion.promotionLinePrice;
|
|
735
|
-
}
|
|
736
|
-
});
|
|
737
|
-
}
|
|
738
|
-
if (this.transactionDocument.basket.taxBreakdown &&
|
|
739
|
-
this.transactionDocument.basket.taxBreakdown.taxLines.length > 0) {
|
|
740
|
-
this.transactionDocument.basket.taxBreakdown.taxLines.forEach((taxLine) => {
|
|
741
|
-
if (product.itemLineId && product.itemLineId === taxLine.itemLineId.toString()) {
|
|
742
|
-
p.selectedVAT = taxLine.VAT;
|
|
743
|
-
p.selectedVATCode = taxLine.VATCode;
|
|
744
|
-
}
|
|
745
|
-
});
|
|
746
|
-
}
|
|
747
|
-
if (this.transactionDocument.type === TRANSACTION_TYPE.REFUND) {
|
|
748
|
-
p.total = product.refundedTotal;
|
|
749
|
-
}
|
|
750
|
-
else if ((this.transactionDocument.type === TRANSACTION_TYPE.SALE_REFUND || TRANSACTION_TYPE.SALE_EXCHANGE) && product.refundedQuantity > 0) {
|
|
751
|
-
p.refundedReasonDescription = product.refundedReasonDescription;
|
|
752
|
-
p.refundedReason = product.refundedReason;
|
|
753
|
-
if (!p.refundedReasonDescription) {
|
|
754
|
-
p.refundedReasonDescription = p.refundedReason;
|
|
755
|
-
}
|
|
756
|
-
p.refundedQuantity = product.refundedQuantity;
|
|
757
|
-
p.refundPromotionalQuantity = product.refundedPromotionalQuantity;
|
|
758
|
-
p.refundedTotal = product.refundedTotal;
|
|
759
|
-
p.total -= Math.abs(p.refundedTotal);
|
|
760
|
-
p.isLastExchanged = product.isLastExchanged;
|
|
761
|
-
}
|
|
762
|
-
if (this.transactionDocument.type === TRANSACTION_TYPE.REFUND) {
|
|
763
|
-
if (p.total > 0) {
|
|
764
|
-
p.total *= -1;
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
basket.products.push(p);
|
|
768
|
-
});
|
|
769
|
-
basket = this.getTransactionDiscountAndTransactionPromotionPortion(basket);
|
|
770
|
-
basket.total = (basket.basketTotal || 0) + this.getTotalDiscountWithTransactionDiscountsAndPromotions(basket);
|
|
771
|
-
if (this.transactionDocument.type === TRANSACTION_TYPE.SALE_REFUND) {
|
|
772
|
-
basket.quantity = this.getRefundedTotalWithQuantity(basket);
|
|
773
|
-
}
|
|
774
|
-
AppLoggerService.logInfo(this.className, "getBasketDetails", "Basket created successfully", basket);
|
|
775
|
-
return basket;
|
|
776
|
-
}
|
|
777
|
-
/**
|
|
778
|
-
* Gets basket details
|
|
779
|
-
* @returns refund basket details
|
|
780
|
-
*/
|
|
781
|
-
// getRefundBasketDetails(): Basket {
|
|
782
|
-
// let basket: Basket = {
|
|
783
|
-
// subsidiaryId : this.transactionDocument.subsidiaryId,
|
|
784
|
-
// transactionDiscount: this.transactionDocument.basket.transactionDiscount,
|
|
785
|
-
// transactionPromotion: this.transactionDocument.basket.transactionPromotion,
|
|
786
|
-
// transactionId: this.transactionDocument.transactionId,
|
|
787
|
-
// total: this.transactionDocument.basketSummary.basketTotal,
|
|
788
|
-
// basketTotal: this.transactionDocument.basketSummary.basketTotal,
|
|
789
|
-
// discountTotal: this.transactionDocument.basketSummary.discountTotal,
|
|
790
|
-
// saleTotal: this.transactionDocument.basketSummary.saleTotal,
|
|
791
|
-
// quantity: this.transactionDocument.basketSummary.totalItems,
|
|
792
|
-
// products: [],
|
|
793
|
-
// baseCurrency: this.transactionDocument.baseCurrency,
|
|
794
|
-
// customer: this.transactionDocument.customer,
|
|
795
|
-
// };
|
|
796
|
-
// basket.products = [] as Product[];
|
|
797
|
-
// 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) => {
|
|
798
|
-
// const p = {} as Product;
|
|
799
|
-
// p.SKU = product.SKU;
|
|
800
|
-
// p.barcode = product.barCode;
|
|
801
|
-
// p.barcodes = product.barcodes;
|
|
802
|
-
// p.description = product.description;
|
|
803
|
-
// p.imageUrls = product.imageUrls;
|
|
804
|
-
// p.currency = this.transactionDocument.baseCurrency;
|
|
805
|
-
// p.totalLinePrice = product.totalLinePrice;
|
|
806
|
-
// p.itemLineId = Number(product.itemLineId);
|
|
807
|
-
// p.excludePromotion = product.excludePromotion;
|
|
808
|
-
// p.selectedPrice = product.price;
|
|
809
|
-
// p.quantity = product.quantity;
|
|
810
|
-
// p.total = product.totalLinePrice;
|
|
811
|
-
// p.selectedRRPPrice = product.selectedRRPPrice;
|
|
812
|
-
// p.fullfilmentId = product.fullfilmentId;
|
|
813
|
-
// p.fullfilmentLocationName = product.fullfilmentLocationName;
|
|
814
|
-
// p.deliveryGroup = product.deliveryGroup || "1";
|
|
815
|
-
// p.leadTime = product.leadTime;
|
|
816
|
-
// p.deliveryMethod = product.deliveryMethod || DELIVERY_METHODS.COLLECT_FROM_STORE.toString();
|
|
817
|
-
// p.giftCard = product.giftCard;
|
|
818
|
-
// p.giftCardExpiryDate = product.giftCardExpiryDate;
|
|
819
|
-
// p.giftCardNumberIssued = product.giftCardNumberIssued;
|
|
820
|
-
// p.giftCardRecipientEmail = product.giftCardRecipientEmail;
|
|
821
|
-
// p.giftCardRecipientName = product.giftCardRecipientName;
|
|
822
|
-
// if(p.fullfilmentId != this.transactionDocument.storeId)
|
|
823
|
-
// {
|
|
824
|
-
// p.isWebOrder = true;
|
|
825
|
-
// }
|
|
826
|
-
// if (product.itemDiscounts) {
|
|
827
|
-
// p.itemDiscounts = product.itemDiscounts as ItemDiscount;
|
|
828
|
-
// }
|
|
829
|
-
// // if(!p.itemDiscounts){
|
|
830
|
-
// // AppLoggerService.logDebug(this.className, p.itemDiscounts);
|
|
831
|
-
// // this.basketService.transactionDiscountAndPromotionProductortionCalculation(basket);
|
|
832
|
-
// // }
|
|
833
|
-
// p.refundPromotionalQuantity = product.refundedPromotionalQuantity ? product.refundedPromotionalQuantity : 0;
|
|
834
|
-
// if (product.refundedQuantity) {
|
|
835
|
-
// p.quantity = p.quantity - product.refundedQuantity;
|
|
836
|
-
// p.totalLinePrice = (p.quantity * product.price);
|
|
837
|
-
// p.total = p.totalLinePrice;
|
|
838
|
-
// // p.refundPromotionalQuantity = product.refundedPromotionalQuantity;
|
|
839
|
-
// p.refunded = product.refunded;
|
|
840
|
-
// p.isLastExchanged = product.isLastExchanged;
|
|
841
|
-
// }
|
|
842
|
-
// if (product.exchange) {
|
|
843
|
-
// p.exchange = product.exchange;
|
|
844
|
-
// }
|
|
845
|
-
// if (
|
|
846
|
-
// this.transactionDocument.basket.lineDiscount &&
|
|
847
|
-
// this.transactionDocument.basket.lineDiscount.length > 0
|
|
848
|
-
// ) {
|
|
849
|
-
// this.transactionDocument.basket.lineDiscount.forEach((lineDiscount: { itemLineId: { toString: () => any; }; discountedLinePrice: any; }) => {
|
|
850
|
-
// if (product.itemLineId === lineDiscount.itemLineId.toString() && product.refundedQuantity > 0) {
|
|
851
|
-
// p.lineDiscount = Object.assign({}, lineDiscount);
|
|
852
|
-
// p.lineDiscount.discountedLinePrice = p.lineDiscount.unitPrice * p.quantity
|
|
853
|
-
// p.lineDiscount.discountAmount = p.total - p.lineDiscount.discountedLinePrice
|
|
854
|
-
// p.total = p.lineDiscount.discountedLinePrice;
|
|
855
|
-
// } else if (product.itemLineId === lineDiscount.itemLineId.toString()) {
|
|
856
|
-
// p.lineDiscount = lineDiscount;
|
|
857
|
-
// p.total = lineDiscount.discountedLinePrice
|
|
858
|
-
// }
|
|
859
|
-
// });
|
|
860
|
-
// }
|
|
861
|
-
// if (
|
|
862
|
-
// this.transactionDocument.basket.linePromotion &&
|
|
863
|
-
// this.transactionDocument.basket.linePromotion.length > 0
|
|
864
|
-
// ) {
|
|
865
|
-
// this.transactionDocument.basket.linePromotion.forEach((linePromotion: { itemLineId: { toString: () => any; }; refunded: any; }) => {
|
|
866
|
-
// if (product.itemLineId === linePromotion.itemLineId.toString() && !linePromotion.refunded) {
|
|
867
|
-
// p.linePromotions = linePromotion;
|
|
868
|
-
// p.total = p.linePromotions.promotionLinePrice;
|
|
869
|
-
// p.total = p.total - (product.refundedTotal ? Math.abs(product.refundedTotal) : 0);
|
|
870
|
-
// }
|
|
871
|
-
// });
|
|
872
|
-
// }
|
|
873
|
-
// p.refundedQuantity = 0;
|
|
874
|
-
// p.refundedTotal = 0;
|
|
875
|
-
// if (
|
|
876
|
-
// this.transactionDocument.basket.taxBreakdown &&
|
|
877
|
-
// this.transactionDocument.basket.taxBreakdown.taxLines.length > 0
|
|
878
|
-
// ) {
|
|
879
|
-
// this.transactionDocument.basket.taxBreakdown.taxLines.forEach((taxLine: { itemLineId: { toString: () => any; }; VAT: any; VATCode: any; }) => {
|
|
880
|
-
// if (product.itemLineId === taxLine.itemLineId.toString()) {
|
|
881
|
-
// p.selectedVAT = taxLine.VAT;
|
|
882
|
-
// p.selectedVATCode = taxLine.VATCode;
|
|
883
|
-
// }
|
|
884
|
-
// });
|
|
885
|
-
// }
|
|
886
|
-
// if (p.quantity > 0) {
|
|
887
|
-
// basket.products.push(p);
|
|
888
|
-
// }
|
|
889
|
-
// });
|
|
890
|
-
// // product.itemDiscounts
|
|
891
|
-
// if (!basket.products[0].hasOwnProperty('itemDiscounts')) {
|
|
892
|
-
// basket = this.getTransactionDiscountAndTransactionPromotionPortion(basket);
|
|
893
|
-
// }
|
|
894
|
-
// AppLoggerService.logDebug(this.className, "ebasket : TransactionDocumentBuilder :new created refunded basket", JSON.stringify(basket))
|
|
895
|
-
// basket.quantity = basket.products.reduce(
|
|
896
|
-
// (n: any, { quantity }: any) => n + quantity,
|
|
897
|
-
// 0
|
|
898
|
-
// );
|
|
899
|
-
// basket.total = this.getTotalWithLineDiscountAndLinePromotionApplied(basket);
|
|
900
|
-
// basket.basketTotal = basket.total;
|
|
901
|
-
// basket.basketTotal = basket.basketTotal - this.getTotalDiscountWithTransactionDiscountsAndPromotions(basket);
|
|
902
|
-
// AppLoggerService.logDebug(this.className,
|
|
903
|
-
// "ebasket : TransactionDocumentBuilder : update Basket Total: after promotion :basketTotal",
|
|
904
|
-
// basket.basketTotal
|
|
905
|
-
// );
|
|
906
|
-
// AppLoggerService.logDebug(this.className,
|
|
907
|
-
// "e:basket :TransactionDocumentBuilder : basketDetails updated values",
|
|
908
|
-
// JSON.stringify(basket)
|
|
909
|
-
// );
|
|
910
|
-
// return basket;
|
|
911
|
-
// }
|
|
912
|
-
getTransactionDiscountAndTransactionPromotionPortion(basket) {
|
|
913
|
-
if (basket.transactionDiscount &&
|
|
914
|
-
basket.transactionDiscount.length > 0) {
|
|
915
|
-
basket.transactionDiscount.forEach((discount) => {
|
|
916
|
-
if (!discount.itemLineIds) {
|
|
917
|
-
discount.itemLineIds = basket.products.map((product) => {
|
|
918
|
-
return product.itemLineId;
|
|
919
|
-
});
|
|
920
|
-
}
|
|
921
|
-
basket = this.basketService.transactionDiscountProductPortionCalc(basket, discount);
|
|
922
|
-
});
|
|
923
|
-
}
|
|
924
|
-
if (basket.transactionPromotion &&
|
|
925
|
-
basket.transactionPromotion.length > 0) {
|
|
926
|
-
basket.transactionPromotion.forEach((tPromotion) => {
|
|
927
|
-
if (!tPromotion.itemLineIds) {
|
|
928
|
-
const filteredData = basket.products.filter((item) => {
|
|
929
|
-
return item.excludePromotion === false;
|
|
930
|
-
});
|
|
931
|
-
tPromotion.itemLineIds =
|
|
932
|
-
filteredData.map((product) => {
|
|
933
|
-
return product.itemLineId;
|
|
934
|
-
});
|
|
935
|
-
}
|
|
936
|
-
basket = this.basketService.transactionPromotionProductPortionCalc(basket, tPromotion);
|
|
937
|
-
});
|
|
938
|
-
}
|
|
939
|
-
return basket;
|
|
940
|
-
}
|
|
941
|
-
getTotalDiscountWithTransactionDiscountsAndPromotions(basketDetails) {
|
|
942
|
-
let discountTotal = 0;
|
|
943
|
-
if (basketDetails.transactionPromotion &&
|
|
944
|
-
basketDetails.transactionPromotion.length > 0) {
|
|
945
|
-
discountTotal += basketDetails.transactionPromotion.reduce((n, { promotionAmount }) => n + promotionAmount, 0);
|
|
946
|
-
}
|
|
947
|
-
if (basketDetails.transactionDiscount &&
|
|
948
|
-
basketDetails.transactionDiscount.length > 0) {
|
|
949
|
-
discountTotal += basketDetails.transactionDiscount.reduce((n, { discountAmount }) => n + discountAmount, 0);
|
|
950
|
-
}
|
|
951
|
-
AppLoggerService.logDebug(this.className, "getTotalDiscountWithTransactionDiscountsAndPromotions", "Transaction discount Total:", discountTotal);
|
|
952
|
-
return discountTotal;
|
|
953
|
-
}
|
|
954
|
-
appendCurrencySymbol(currency, value) {
|
|
955
|
-
// value=this.decimalpipe.transform(value,'1.2');
|
|
956
|
-
if (value >= 0) {
|
|
957
|
-
const returnval = currency + value;
|
|
958
|
-
AppLoggerService.logDebug(this.className, "appendCurrencySymbol", "add currency with value", returnval);
|
|
959
|
-
return returnval;
|
|
960
|
-
}
|
|
961
|
-
else {
|
|
962
|
-
const returnval = "-" + (currency + value * -1);
|
|
963
|
-
AppLoggerService.logDebug(this.className, "appendCurrencySymbol", "returnVal", returnval);
|
|
964
|
-
return returnval;
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
// /**
|
|
968
|
-
// * Updates total refund
|
|
969
|
-
// * @returns total refund
|
|
970
|
-
// */
|
|
971
|
-
// updateTotalRefund(): TransactionDocumentBuilder {
|
|
972
|
-
// this.transactionDocument.basket.products.forEach((product) => {
|
|
973
|
-
// product.refundedQuantity = product.quantity;
|
|
974
|
-
// product.refundedTotal = product.totalLinePrice * -1;
|
|
975
|
-
// AppLoggerService.logDebug(this.className,
|
|
976
|
-
// "ebasket: Transaction price override :",
|
|
977
|
-
// this.transactionDocument.basket.lineDiscount
|
|
978
|
-
// );
|
|
979
|
-
// if (
|
|
980
|
-
// this.transactionDocument.basket.linePromotion &&
|
|
981
|
-
// this.transactionDocument.basket.linePromotion.length > 0
|
|
982
|
-
// ) {
|
|
983
|
-
// this.transactionDocument.basket.linePromotion.forEach((linePromotion) => {
|
|
984
|
-
// AppLoggerService.logDebug(this.className,
|
|
985
|
-
// "Promotion: basket linePromotion : ",
|
|
986
|
-
// this.transactionDocument.basket.linePromotion
|
|
987
|
-
// );
|
|
988
|
-
// AppLoggerService.logDebug(this.className,
|
|
989
|
-
// "linePromotion.itemLineId.toString() : ",
|
|
990
|
-
// linePromotion.itemLineId.toString()
|
|
991
|
-
// );
|
|
992
|
-
// AppLoggerService.logDebug(this.className,
|
|
993
|
-
// "condition : " +
|
|
994
|
-
// (product.itemLineId === linePromotion.itemLineId.toString())
|
|
995
|
-
// );
|
|
996
|
-
// if (product.itemLineId === linePromotion.itemLineId.toString()) {
|
|
997
|
-
// product.refundedTotal =
|
|
998
|
-
// linePromotion.promotionLinePrice * -1;
|
|
999
|
-
// }
|
|
1000
|
-
// });
|
|
1001
|
-
// } else
|
|
1002
|
-
// if (
|
|
1003
|
-
// this.transactionDocument.basket.lineDiscount &&
|
|
1004
|
-
// this.transactionDocument.basket.lineDiscount.length > 0
|
|
1005
|
-
// ) {
|
|
1006
|
-
// this.transactionDocument.basket.lineDiscount.forEach((lineDiscount) => {
|
|
1007
|
-
// AppLoggerService.logDebug(this.className,
|
|
1008
|
-
// "product.itemLineId : " +
|
|
1009
|
-
// this.transactionDocument.basket.lineDiscount
|
|
1010
|
-
// );
|
|
1011
|
-
// AppLoggerService.logDebug(this.className,
|
|
1012
|
-
// "lineDiscount.itemLineId.toString() : " +
|
|
1013
|
-
// lineDiscount.itemLineId.toString()
|
|
1014
|
-
// );
|
|
1015
|
-
// AppLoggerService.logDebug(this.className,
|
|
1016
|
-
// "condition : " +
|
|
1017
|
-
// (product.itemLineId === lineDiscount.itemLineId.toString())
|
|
1018
|
-
// );
|
|
1019
|
-
// if (product.itemLineId === lineDiscount.itemLineId.toString()) {
|
|
1020
|
-
// product.refundedTotal = lineDiscount.unitPrice * product.refundedQuantity * -1;
|
|
1021
|
-
// }
|
|
1022
|
-
// });
|
|
1023
|
-
// }
|
|
1024
|
-
// AppLoggerService.logDebug(this.className, "Product description :" + product.description);
|
|
1025
|
-
// AppLoggerService.logDebug(this.className, "Product total :" + product.refundedTotal);
|
|
1026
|
-
// // product.displayrefundedamount=this.appendCurrencySymbol(CURRENCY[this.transactionDocument.baseCurrency],product.refundedTotal);
|
|
1027
|
-
// // AppLoggerService.logDebug(this.className, product.displayrefundedamount,"displayrefundedamount");
|
|
1028
|
-
// product.refunded = true;
|
|
1029
|
-
// });
|
|
1030
|
-
// const baskettotal = (this.transactionDocument.basketSummary.basketTotal *= -1);
|
|
1031
|
-
// // this.transactionDocument.basketSummary.displaybaskettotal=this.appendCurrencySymbol(CURRENCY[this.transactionDocument.baseCurrency], baskettotal);
|
|
1032
|
-
// const saletotal = (this.transactionDocument.basketSummary.saleTotal *= -1);
|
|
1033
|
-
// // this.transactionDocument.basketSummary.displaysaletotal = this.appendCurrencySymbol(CURRENCY[this.transactionDocument.baseCurrency], saletotal);
|
|
1034
|
-
// (this.transactionDocument.basketSummary.VATTotal *= -1);
|
|
1035
|
-
// return this;
|
|
1036
|
-
// }
|
|
1037
|
-
/**
|
|
1038
|
-
* Sale Total
|
|
1039
|
-
* @param basketDetails
|
|
1040
|
-
* @returns Sale Total
|
|
1041
|
-
*/
|
|
1042
|
-
updateSaleTotal(basketDetails) {
|
|
1043
|
-
const saleTotal = basketDetails.products.reduce((n, { totalLinePrice }) => n + totalLinePrice, 0);
|
|
1044
|
-
return saleTotal;
|
|
1045
|
-
}
|
|
1046
|
-
getTotalWithLineDiscountAndLinePromotionApplied(basketDetails) {
|
|
1047
|
-
let saletotal = 0.0;
|
|
1048
|
-
for (let product of basketDetails.products) {
|
|
1049
|
-
// if (product.linePromotions) {
|
|
1050
|
-
// saletotal += product.linePromotions.promotionLinePrice;
|
|
1051
|
-
// } else if (
|
|
1052
|
-
// product.lineDiscount &&
|
|
1053
|
-
// !product.linePromotions
|
|
1054
|
-
// ) {
|
|
1055
|
-
// saletotal +=
|
|
1056
|
-
// product.quantity * Number(product.lineDiscount.unitPrice.toFixed(2));
|
|
1057
|
-
// } else {
|
|
1058
|
-
// saletotal +=
|
|
1059
|
-
// product.quantity * Number(product.selectedPrice.toFixed(2));
|
|
1060
|
-
// }
|
|
1061
|
-
saletotal += product.total;
|
|
1062
|
-
AppLoggerService.logDebug(this.className, "getTotalWithLineDiscountAndLinePromotionApplied", "e-basket:update product Total:" + saletotal, product);
|
|
1063
|
-
}
|
|
1064
|
-
return saletotal;
|
|
1065
|
-
}
|
|
1066
|
-
getRefundedTotalWithQuantity(basketDetails) {
|
|
1067
|
-
let quantity = 0;
|
|
1068
|
-
for (let index = 0; index < basketDetails.products.length; index++) {
|
|
1069
|
-
const product = basketDetails.products[index];
|
|
1070
|
-
if (!product.refundedReasonDescription) {
|
|
1071
|
-
quantity = quantity + product.quantity;
|
|
1072
|
-
}
|
|
1073
|
-
else {
|
|
1074
|
-
quantity = quantity + (product.quantity - product.refundedQuantity);
|
|
1075
|
-
// basketDetails.total = basketDetails.total + product.refundedTotal;
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
return quantity;
|
|
1079
|
-
}
|
|
1080
|
-
/**
|
|
1081
|
-
* Discount Total
|
|
1082
|
-
* @returns Discount Total
|
|
1083
|
-
*/
|
|
1084
|
-
updateDiscountTotal() {
|
|
1085
|
-
let refundTotal = this.transactionDocument.basketSummary.refundTotal ? this.transactionDocument.basketSummary.refundTotal : 0;
|
|
1086
|
-
AppLoggerService.logInfo(this.className, "updateDiscountTotal", `refundTotal: ${refundTotal} this.transactionDocument.basketSummary: ${this.transactionDocument.basketSummary}`);
|
|
1087
|
-
const discountTotal = Math.abs(Math.abs(this.transactionDocument.basketSummary.saleTotal) -
|
|
1088
|
-
(Math.abs(this.transactionDocument.basketSummary.basketTotal) + Math.abs(refundTotal)));
|
|
1089
|
-
AppLoggerService.logDebug(this.className, "updateDiscountTotal", "discountTotal", discountTotal);
|
|
1090
|
-
return Number(discountTotal.toFixed(2));
|
|
1091
|
-
}
|
|
1092
|
-
updateReasonCode(reasonCode) {
|
|
1093
|
-
this.transactionDocument.reasonCode = reasonCode.code;
|
|
1094
|
-
this.transactionDocument.reasonDescription = reasonCode.name;
|
|
1095
|
-
return this;
|
|
1096
|
-
}
|
|
1097
|
-
updateManagerOverride(useroverride) {
|
|
1098
|
-
this.transactionDocument.override = useroverride;
|
|
1099
|
-
return this;
|
|
1100
|
-
}
|
|
1101
|
-
updateUserID(userID) {
|
|
1102
|
-
this.transactionDocument.userId = userID;
|
|
1103
|
-
return this;
|
|
1104
|
-
}
|
|
1105
|
-
updateUserName(name) {
|
|
1106
|
-
this.transactionDocument.userName = name;
|
|
1107
|
-
return this;
|
|
1108
|
-
}
|
|
1109
|
-
addCustomerDetails(customerDetail) {
|
|
1110
|
-
this.transactionDocument.customer = customerDetail;
|
|
1111
|
-
return this;
|
|
1112
|
-
}
|
|
1113
|
-
updateTaxBreakdown(basketDetails) {
|
|
1114
|
-
// let transactionDiscountTotal = 0;
|
|
1115
|
-
let taxBreakdown = {
|
|
1116
|
-
taxLines: [],
|
|
1117
|
-
totalTaxableAmount: 0,
|
|
1118
|
-
};
|
|
1119
|
-
// if (this.transactionDocument.basket.transactionDiscount && this.transactionDocument.basket.transactionDiscount.length > 0) {
|
|
1120
|
-
// this.transactionDocument.basket.transactionDiscount.forEach((discount) => {
|
|
1121
|
-
// transactionDiscountTotal += discount.discountAmount;
|
|
1122
|
-
// });
|
|
1123
|
-
// }
|
|
1124
|
-
// if (this.transactionDocument.basket.transactionPromotion && this.transactionDocument.basket.transactionPromotion.length > 0) {
|
|
1125
|
-
// this.transactionDocument.basket.transactionPromotion.forEach(
|
|
1126
|
-
// (promotion) => {
|
|
1127
|
-
// transactionDiscountTotal += promotion.promotionAmount;
|
|
1128
|
-
// }
|
|
1129
|
-
// );
|
|
1130
|
-
// }
|
|
1131
|
-
basketDetails.products.forEach((product) => {
|
|
1132
|
-
let taxLine = {
|
|
1133
|
-
itemLineId: product.itemLineId,
|
|
1134
|
-
VAT: product.selectedVAT ? product.selectedVAT : 0,
|
|
1135
|
-
VATCode: product.selectedVATCode,
|
|
1136
|
-
taxLineTotal: 0,
|
|
1137
|
-
taxableAmount: product.total,
|
|
1138
|
-
PreTax: 0
|
|
1139
|
-
};
|
|
1140
|
-
AppLoggerService.logInfo(this.className, "updateTaxBreakdown", `item line ID :, ${product.itemLineId},
|
|
1141
|
-
"tax line :", ${taxLine}`);
|
|
1142
|
-
// step 1
|
|
1143
|
-
// if Transaction Discount and/or promotion applied, find net selling price of each product as taxableamount
|
|
1144
|
-
// if (transactionDiscountTotal > 0) {
|
|
1145
|
-
product = this.basketService.validateProductItemDiscount(product);
|
|
1146
|
-
const productContributionInTotal = product.itemDiscounts.trnDiscountsPortion +
|
|
1147
|
-
product.itemDiscounts.trnPromotionsPortion -
|
|
1148
|
-
product.itemDiscounts.refundPortion;
|
|
1149
|
-
// tp+td-rp;
|
|
1150
|
-
AppLoggerService.logInfo(this.className, "updateTaxBreakdown", `item line ID , ${product.itemLineId},
|
|
1151
|
-
"contribution :", ${productContributionInTotal}`);
|
|
1152
|
-
// calculate net selling price after applying transaction discount as per product contribution
|
|
1153
|
-
taxLine.taxableAmount -= productContributionInTotal;
|
|
1154
|
-
// }
|
|
1155
|
-
//step 2 - find pre tax
|
|
1156
|
-
taxLine.PreTax = this.numberUtilService.trimTo2Decimal2((taxLine.taxableAmount * 100) / (100 + taxLine.VAT));
|
|
1157
|
-
//step 3 - Update taxbreakdown
|
|
1158
|
-
taxBreakdown.totalTaxableAmount += taxLine.taxableAmount;
|
|
1159
|
-
taxLine.taxableAmount = this.numberUtilService.trimTo2Decimal2(taxLine.taxableAmount);
|
|
1160
|
-
// step 4 - update tax Line total
|
|
1161
|
-
taxLine.taxLineTotal = this.numberUtilService.trimTo2Decimal2(taxLine.taxableAmount - taxLine.PreTax);
|
|
1162
|
-
taxBreakdown.taxLines.push(taxLine);
|
|
1163
|
-
});
|
|
1164
|
-
taxBreakdown.totalTaxableAmount = this.numberUtilService.trimTo2Decimal2(taxBreakdown.totalTaxableAmount);
|
|
1165
|
-
this.transactionDocument.basket.taxBreakdown = taxBreakdown;
|
|
1166
|
-
return this;
|
|
1167
|
-
}
|
|
1168
|
-
updateTotalTaxSummary() {
|
|
1169
|
-
AppLoggerService.logDebug(this.className, "updateTotalTaxSummary", "Total Tax Summery Request :", this.transactionDocument.basket.taxBreakdown);
|
|
1170
|
-
let totalTaxSummaryArray = [];
|
|
1171
|
-
let totalTaxSummaryGroup = [];
|
|
1172
|
-
AppLoggerService.logDebug(this.className, "updateTotalTaxSummary", "Tax Lines for Total Tax Summery :", this.transactionDocument.basket.taxBreakdown.taxLines);
|
|
1173
|
-
this.transactionDocument.basket.taxBreakdown.taxLines.forEach((element) => {
|
|
1174
|
-
let TaxSummary = {
|
|
1175
|
-
VATCode: "",
|
|
1176
|
-
VAT: -12345,
|
|
1177
|
-
PreTaxSum: 0,
|
|
1178
|
-
TaxSum: 0,
|
|
1179
|
-
TXrateSum: 0
|
|
1180
|
-
};
|
|
1181
|
-
TaxSummary.VATCode = element.VATCode;
|
|
1182
|
-
TaxSummary.VAT = element.VAT;
|
|
1183
|
-
TaxSummary.PreTaxSum = this.numberUtilService.trimTo2Decimal2(element.PreTax);
|
|
1184
|
-
TaxSummary.TaxSum = this.numberUtilService.trimTo2Decimal2(element.taxLineTotal);
|
|
1185
|
-
TaxSummary.TXrateSum = this.numberUtilService.trimTo2Decimal2(TaxSummary.PreTaxSum + TaxSummary.TaxSum);
|
|
1186
|
-
totalTaxSummaryArray.push(TaxSummary);
|
|
1187
|
-
});
|
|
1188
|
-
AppLoggerService.logDebug(this.className, "updateTotalTaxSummary", "Total Tax Summery Without Grouped : ", totalTaxSummaryArray);
|
|
1189
|
-
totalTaxSummaryGroup = totalTaxSummaryArray.reduce((preparedArray, currentObj) => {
|
|
1190
|
-
let ind = preparedArray.findIndex((x) => x.VAT === currentObj.VAT);
|
|
1191
|
-
if (ind === -1) {
|
|
1192
|
-
preparedArray.push(currentObj);
|
|
1193
|
-
}
|
|
1194
|
-
else {
|
|
1195
|
-
preparedArray[ind].VATCode = currentObj.VATCode;
|
|
1196
|
-
preparedArray[ind].VAT = currentObj.VAT;
|
|
1197
|
-
preparedArray[ind].PreTaxSum += currentObj.PreTaxSum;
|
|
1198
|
-
preparedArray[ind].TaxSum += currentObj.TaxSum;
|
|
1199
|
-
preparedArray[ind].TXrateSum += currentObj.TXrateSum;
|
|
1200
|
-
}
|
|
1201
|
-
return preparedArray;
|
|
1202
|
-
}, []);
|
|
1203
|
-
AppLoggerService.logDebug(this.className, "updateTotalTaxSummary", "Total Tax Summer Group :", totalTaxSummaryGroup);
|
|
1204
|
-
this.transactionDocument.basket.totalTaxSummary = totalTaxSummaryGroup;
|
|
1205
|
-
return this;
|
|
1206
|
-
}
|
|
1207
|
-
/**
|
|
1208
|
-
* TransactionId
|
|
1209
|
-
* @returns OriginalTransactionId
|
|
1210
|
-
*/
|
|
1211
|
-
addOriginalTransId(tranDoc) {
|
|
1212
|
-
if (this.transactionDocument.type === TRANSACTION_TYPE.REFUND || this.transactionDocument.type === TRANSACTION_TYPE.SALE_REFUND || this.transactionDocument.type === TRANSACTION_TYPE.SALE_EXCHANGE) {
|
|
1213
|
-
this.transactionDocument.originalTransId = tranDoc.transactionId;
|
|
1214
|
-
if (tranDoc.apiResponse && tranDoc.apiResponse.internalId) {
|
|
1215
|
-
this.transactionDocument.originalExternalId = tranDoc.apiResponse.internalId.toString();
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
return this;
|
|
1219
|
-
}
|
|
1220
|
-
/**
|
|
1221
|
-
* unreferenced Refund
|
|
1222
|
-
* @returns boolean value
|
|
1223
|
-
*/
|
|
1224
|
-
addUnreferencedRefund() {
|
|
1225
|
-
this.transactionDocument.unreferencedRefund = true;
|
|
1226
|
-
return this;
|
|
1227
|
-
}
|
|
1228
|
-
getRefundTotal() {
|
|
1229
|
-
let totalRefund = 0;
|
|
1230
|
-
for (let index = 0; index < this.transactionDocument.basket.products.length; index++) {
|
|
1231
|
-
const product = this.transactionDocument.basket.products[index];
|
|
1232
|
-
if (product.refundedTotal) {
|
|
1233
|
-
totalRefund = totalRefund + product.refundedTotal;
|
|
1234
|
-
}
|
|
1235
|
-
AppLoggerService.logDebug(this.className, "getRefundTotal", "totalRefund", totalRefund);
|
|
1236
|
-
}
|
|
1237
|
-
return totalRefund;
|
|
1238
|
-
}
|
|
1239
|
-
docId(docId) {
|
|
1240
|
-
this.transactionDocument.id = docId;
|
|
1241
|
-
return this;
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9tYXBwZXItbGlicmFyeS9zcmMvbGliL1RyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBc0QsZ0JBQWdCLEVBQWlHLE1BQU0sd0JBQXdCLENBQUM7QUFDN00sT0FBTyxFQUFFLGdCQUFnQixFQUErRCxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZILE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxzREFBc0QsQ0FBQztBQUV0Rjs7R0FFRztBQUNILE1BQU0sT0FBTywwQkFBMEI7SUFNckMsWUFDRSxjQUFvQyxFQUM1QixZQUEyQixFQUMzQixhQUFtQztRQURuQyxpQkFBWSxHQUFaLFlBQVksQ0FBZTtRQUMzQixrQkFBYSxHQUFiLGFBQWEsQ0FBc0I7UUFMN0MsY0FBUyxHQUFHLDRCQUE0QixDQUFDO1FBT3ZDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzdELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxhQUFhLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDL0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUM7UUFDdkUsSUFBSSxjQUFjLEVBQUU7WUFDbEIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLGNBQWMsQ0FBQztTQUMzQzthQUFNO1lBQ0wsSUFBSSxDQUFDLG1CQUFtQixHQUFHO2dCQUN6QixhQUFhLEVBQUUs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QUFrQixHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDO2FBQ3pGO1NBQ0Y7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7O09BR0c7SUFDSCxxQkFBcUI7UUFDbkIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztRQUNuRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxjQUFjO1FBQ1osSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ3BCLEtBQUssSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDcEYsTUFBTSxPQUFPLEdBQWEsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDMUUsSUFBSSxPQUFPLENBQUMsYUFBYSxFQUFFO2dCQUN6QixXQUFXLEdBQUcsV0FBVyxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUM7YUFDbkQ7WUFDRCxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxhQUFhLEVBQUcsV0FBVyxDQUFDLENBQUE7U0FDekY7UUFDRCxPQUFPLFdBQVcsQ0FBQztJQUNyQixDQUFDO0lBRUQsS0FBSyxDQUFDLEtBQVU7UUFDWixJQUFJLENBQUMsbUJBQW1CLENBQUMsRUFBRSxHQUFHLEtBQUssQ0FBQztRQUN0QyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEN1cnJlbmN5UGlwZSB9IGZyb20gXCJAYW5ndWxhci9jb21tb25cIjtcclxuaW1wb3J0IHsgQmFza2V0U3VtbWFyeSwgQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlscywgQ3VzdG9tZXIsIERFTElWRVJZX01FVEhPRFMsIEl0ZW1EaXNjb3VudHMsIFRheEJyZWFrZG93biwgVGF4TGluZSwgVEJhc2tldCwgVG90YWxUYXhTdW1tYXJ5LCBUUHJvZHVjdCwgVHJhbnNhY3Rpb25Eb2N1bWVudCB9IGZyb20gXCIuL21hcHBlci1saWJyYXJ5Lm1vZGVsXCI7XHJcbmltcG9ydCB7IFRSQU5TQUNUSU9OX1RZUEUsIEJhc2tldCwgTGluZURpc2NvdW50LCBMaW5lUHJvbW90aW9ucywgUHJvZHVjdCwgVXNlck92ZXJyaWRlIH0gZnJvbSBcIi4vbWFwcGVyLWxpYnJhcnkubW9kZWxcIjtcclxuaW1wb3J0IHsgQmFza2V0U2VydmljZSB9IGZyb20gXCIuL2Jhc2tldC5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IE51bWJlclV0aWxTZXJ2aWNlIH0gZnJvbSBcIi4vbnVtYmVyLXV0aWwuc2VydmljZVwiO1xyXG5pbXBvcnQge0FwcExvZ2dlclNlcnZpY2V9IGZyb20gJ0BwbWNyZXRhaWwvY29tbW9uLXNlcnZpY2VzL2NvbW1vbi9hcHAtbG9nZ2VyLnNlcnZpY2UnO1xyXG5cclxuLyoqXHJcbiAqIFRyYW5zYWN0aW9uIGRvY3VtZW50IGJ1aWxkZXJcclxuICovXHJcbmV4cG9ydCBjbGFzcyBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgcHJpdmF0ZSB0cmFuc2FjdGlvbkRvY3VtZW50OiBUcmFuc2FjdGlvbkRvY3VtZW50O1xyXG4gIHByaXZhdGUgbnVtYmVyVXRpbFNlcnZpY2U6IE51bWJlclV0aWxTZXJ2aWNlO1xyXG4gIHByaXZhdGUgc3RvcmVJbmZvIDogYW55O1xyXG4gIGNsYXNzTmFtZSA9IFwiVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXJcIjtcclxuICBcclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHRyYW5zYWN0aW9uRG9jPzogVHJhbnNhY3Rpb25Eb2N1bWVudCxcclxuICAgIHByaXZhdGUgY3VycmVuY3lQaXBlPzogQ3VycmVuY3lQaXBlLFxyXG4gICAgcHJpdmF0ZSBiYXNrZXRTZXJ2aWNlPzogQmFza2V0U2VydmljZSB8IGFueSxcclxuICApIHtcclxuICAgIHRoaXMubnVtYmVyVXRpbFNlcnZpY2UgPSBuZXcgTnVtYmVyVXRpbFNlcnZpY2UoY3VycmVuY3lQaXBlKTtcclxuICAgIHRoaXMuYmFza2V0U2VydmljZSA9IG5ldyBCYXNrZXRTZXJ2aWNlKHRoaXMubnVtYmVyVXRpbFNlcnZpY2UpO1xyXG4gICAgdGhpcy5zdG9yZUluZm8gPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdzdG9yZUluZm8nKSB8fCAne30nKTtcclxuICAgIGlmICh0cmFuc2FjdGlvbkRvYykge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQgPSB0cmFuc2FjdGlvbkRvYztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudCA9IHtcclxuICAgICAgICB0cmFuc2FjdGlvbklkOiBcIlwiLFxyXG4gICAgICAgIG9mZmxpbmVUcmFuc2FjdGlvbklkOiBcIlwiLFxyXG4gICAgICAgIHRyYW5zYWN0aW9uUmVmOiBcIlwiLFxyXG4gICAgICAgIGRhdGVUaW1lOiBcIlwiLFxyXG4gICAgICAgIG9yZ0NvZGU6IFwiXCIsXHJcbiAgICAgICAgc3RvcmVJZDogXCJcIixcclxuICAgICAgICBzdG9yZU5vZGVJZDogXCJcIixcclxuICAgICAgICBzdG9yZU5vZGVTdHJ1Y3R1cmU6IFwiXCIsXHJcbiAgICAgICAgZGV2aWNlSWQ6IFwiXCIsXHJcbiAgICAgICAgdGVybWluYWxJZDogXCJcIixcclxuICAgICAgICB1c2VySWQ6IFwiXCIsXHJcbiAgICAgICAgaW5pdGlhdGluZ01vZHVsZSA6IFwiZUJhc2tldFwiLFxyXG4gICAgICAgIGV4cG9ydDogZmFsc2UsXHJcbiAgICAgICAgYmFza2V0OiB7fSBhcyBUQmFza2V0LFxyXG4gICAgICAgIGJhc2tldFN1bW1hcnk6IHt9IGFzIEJhc2tldFN1bW1hcnksXHJcbiAgICAgICAgYmFzZUN1cnJlbmN5OiBcIlwiLFxyXG4gICAgICAgIHR5cGU6IFwiXCIsXHJcbiAgICAgICAgb3BlcmF0aW9uU3RhdHVzOiBcIlwiLFxyXG4gICAgICAgIGNyZWF0ZWRBdDogXCJcIixcclxuICAgICAgICB1cGRhdGVkQXQ6IFwiXCIsXHJcbiAgICAgICAgaWQ6IFwiXCIsXHJcbiAgICAgICAgY3VycmVudFRyYW5zYWN0aW9uRGV0YWlsczoge30gYXMgQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlscyxcclxuICAgICAgICBzYWxlVG90YWw6IDAsXHJcbiAgICAgIH07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUcmFuc2FjdGlvbnMgcmVmXHJcbiAgICogQHJldHVybnMgcmVmXHJcbiAgICovXHJcbiAgdHJhbnNhY3Rpb25SZWYoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgY29uc3Qgc3RvcmVEZXRhaWxzID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnc3RvcmVJbmZvJykgfHwgJ3t9Jyk7XHJcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKTtcclxuICAgIGNvbnN0IHJhbmRvbSA9ICgoKDEgKyBNYXRoLnJhbmRvbSgpKSAqIDB4MTAwMDApIHwgMClcclxuICAgICAgLnRvU3RyaW5nKDE2KVxyXG4gICAgICAuc3Vic3RyaW5nKDEpO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnRyYW5zYWN0aW9uUmVmID1cclxuICAgICAgc3RvcmVEZXRhaWxzLm9yZ0NvZGUgKyBzdG9yZURldGFpbHMuc3RvcmVJZCArIGRhdGUudG9JU09TdHJpbmcoKSArIHJhbmRvbTtcclxuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwidHJhbnNhY3Rpb25SZWZcIiwgXCJ0cmFuc2FjdGlvbiByZWYgY3JlYXRlZFwiLCB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHJhbnNhY3Rpb25SZWYpXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRyYW5zYWN0aW9ucyBpZFxyXG4gICAqIEBwYXJhbSB0cmFuc2FjdGlvbklEXHJcbiAgICogQHJldHVybnMgaWRcclxuICAgKi9cclxuICB0cmFuc2FjdGlvbklkKHRyYW5zYWN0aW9uSUQ6IHN0cmluZywgaXNPbmxpbmU6IGJvb2xlYW4gPSB0cnVlKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgaWYgKGlzT25saW5lKSB7XHJcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC50cmFuc2FjdGlvbklkID0gdHJhbnNhY3Rpb25JRDtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVHJhbnNhY3Rpb25zIGlkXHJcbiAgICogQHBhcmFtIHRyYW5zYWN0aW9uSURcclxuICAgKiBAcmV0dXJucyBpZFxyXG4gICAqL1xyXG4gIG9mZmxpbmVUcmFuc2FjdGlvbklkKHRyYW5zYWN0aW9uSUQ6IHN0cmluZywgaXNPbmxpbmU6IGFueSk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIGlmICghaXNPbmxpbmUpIHtcclxuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50Lm9mZmxpbmVUcmFuc2FjdGlvbklkID0gdHJhbnNhY3Rpb25JRDtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgKiBzdG9yZU5vZGUgSWRcclxuICAqIEBwYXJhbSBzdG9yZU5vZGVJZFxyXG4gICogQHJldHVybnMgaWRcclxuICAqL1xyXG4gIHN0b3JlTm9kZUlkKHN0b3JlTm9kZUlkOiBzdHJpbmcpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuc3RvcmVOb2RlSWQgPSBzdG9yZU5vZGVJZDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiogc3RvcmVOb2RlIHN0cnVjdHVyZVxyXG4qIEBwYXJhbSBzdG9yZU5vZGVTdHJ1Y3R1cmVcclxuKiBAcmV0dXJucyBpZFxyXG4qL1xyXG4gIHN0b3JlTm9kZVN0cnVjdHVyZShzdG9yZU5vZGVTdHJ1Y3R1cmU6IHN0cmluZyk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5zdG9yZU5vZGVTdHJ1Y3R1cmUgPSBzdG9yZU5vZGVTdHJ1Y3R1cmU7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE9yZ3MgY29kZVxyXG4gICAqIEBwYXJhbSBvcmdDb2RlXHJcbiAgICogQHJldHVybnMgY29kZVxyXG4gICAqL1xyXG4gIG9yZ0NvZGUob3JnQ29kZTogYW55KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50Lm9yZ0NvZGUgPSBvcmdDb2RlO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIFN0b3JlcyBpZFxyXG4gICAqIEBwYXJhbSBzdG9yZUlkXHJcbiAgICogQHJldHVybnMgaWRcclxuICAgKi9cclxuICBzdG9yZUlkKHN0b3JlSWQ6IGFueSk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5zdG9yZUlkID0gc3RvcmVJZDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBEYXRlcyB0aW1lXHJcbiAgICogQHJldHVybnMgdGltZVxyXG4gICAqL1xyXG4gIGRhdGVUaW1lKCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmRhdGVUaW1lID0gZGF0ZS50b0lTT1N0cmluZygpO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIERldmljZXMgaWRcclxuICAgKiBAcGFyYW0gZGV2aWNlSWRcclxuICAgKiBAcmV0dXJucyBpZFxyXG4gICAqL1xyXG4gIGRldmljZUlkKGRldmljZUlkOiBhbnkpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuZGV2aWNlSWQgPSBkZXZpY2VJZDtcclxuXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAgICogdGVybWluYWwgaWRcclxuICAgICAqIEBwYXJhbSB0ZXJtaW5hbElkXHJcbiAgICAgKiBAcmV0dXJucyBpZFxyXG4gICAgICovXHJcbiAgdGVybWluYWxJZCh0ZXJtaW5hbElkOiBhbnkpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudGVybWluYWxJZCA9IHRlcm1pbmFsSWQ7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG5cclxuXHJcblxyXG5cclxuICAvKipcclxuICAgICogc2FsZUV4cG9ydFxyXG4gICAgKiBAcGFyYW0gc2FsZUV4cG9ydFxyXG4gICAgKiBAcmV0dXJucyBpZFxyXG4gICAgKi9cclxuICBleHBvcnQoc2FsZUV4cG9ydDogYW55KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmV4cG9ydCA9IHNhbGVFeHBvcnQ7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG5cclxuXHJcbiAgLyogIGN1c3RvbWVyKCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIGNvbnN0IHVzZXIgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCd1c2VyRGV0YWlscycpKTtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXN0b21lciA9IHVzZXI7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9ICovXHJcbiAgLyoqXHJcbiAgICogQmFza2V0cyB0cmFuc2FjdGlvbiBkb2N1bWVudCBidWlsZGVyXHJcbiAgICogQHBhcmFtIGJhc2tldERldGFpbHNcclxuICAgKiBAcmV0dXJucyBiYXNrZXRcclxuICAgKi9cclxuICBiYXNrZXQoYmFza2V0RGV0YWlsczogQmFza2V0KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJiYXNrZXRcIiwgXCJiYXNrZXQgZGV0YWlscyB1cGRhdGUgaW4gdHJhbnNhY3Rpb24gZG9jdW1lbnRcIiwgYmFza2V0RGV0YWlscyk7XHJcblxyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnN1YnNpZGlhcnlJZCA9IGJhc2tldERldGFpbHMuc3Vic2lkaWFyeUlkIHx8IChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnc3Vic2lkaWFyeUlkJykgfHwgJycpO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5wcm9kdWN0cyA9IFtdIGFzIFRQcm9kdWN0W107XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudCA9IFtdO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lUHJvbW90aW9uID0gW107XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uID0gW107XHJcbiAgICBiYXNrZXREZXRhaWxzLnByb2R1Y3RzLmZvckVhY2goKHByb2R1Y3Q6IGFueSwgaW5kZXgpID0+IHtcclxuICAgICAgY29uc3QgcCA9IHt9IGFzIFRQcm9kdWN0O1xyXG4gICAgICBwLml0ZW1EaXNjb3VudHMgPSB7fSBhcyBJdGVtRGlzY291bnRzO1xyXG4gICAgICBwLlNLVSA9IHByb2R1Y3QuU0tVO1xyXG4gICAgICBwLmV4Y2x1ZGVQcm9tb3Rpb24gPSBwcm9kdWN0LmV4Y2x1ZGVQcm9tb3Rpb247XHJcbiAgICAgIHAuYmFyQ29kZSA9IHByb2R1Y3QuYmFyY29kZTtcclxuICAgICAgcC5iYXJjb2RlcyA9IHByb2R1Y3QuYmFyY29kZXM7XHJcbiAgICAgIHAuZGVzY3JpcHRpb24gPSBwcm9kdWN0LmRlc2NyaXB0aW9uO1xyXG4gICAgICBwLml0ZW1MaW5lSWQgPSBwcm9kdWN0Lml0ZW1MaW5lSWQgPyBwcm9kdWN0Lml0ZW1MaW5lSWQudG9TdHJpbmcoKSA6IFwiXCIgKyAoaW5kZXggKyAxKTtcclxuICAgICAgcC5wcmljZSA9IHByb2R1Y3Quc2VsZWN0ZWRQcmljZTtcclxuICAgICAgcC5xdWFudGl0eSA9IHByb2R1Y3QucXVhbnRpdHk7XHJcbiAgICAgIHAudG90YWxMaW5lUHJpY2UgPSBwcm9kdWN0LnF1YW50aXR5ICogcHJvZHVjdC5zZWxlY3RlZFByaWNlO1xyXG4gICAgICBwLmltYWdlVXJscyA9IHByb2R1Y3QuaW1hZ2VVcmxzO1xyXG4gICAgICBwLnNlbGVjdGVkUlJQUHJpY2UgPSBwcm9kdWN0LnNlbGVjdGVkUlJQUHJpY2U7XHJcblxyXG4gICAgICAvL2ludmVudG9yeSBmaWVsZHNcclxuICAgICAgXHJcbiAgICAgIHAuZnVsbGZpbG1lbnRJZCA9IHByb2R1Y3QuZnVsbGZpbG1lbnRJZD8gcHJvZHVjdC5mdWxsZmlsbWVudElkOiB0aGlzLnN0b3JlSW5mby5zdG9yZUlkO1xyXG5cclxuICAgICAgcC5mdWxsZmlsbWVudExvY2F0aW9uTmFtZSA9IHByb2R1Y3QuZnVsbGZpbG1lbnRMb2NhdGlvbk5hbWU7XHJcbiAgICAgIHAuZGVsaXZlcnlHcm91cCA9IHByb2R1Y3QuZGVsaXZlcnlHcm91cDtcclxuICAgICAgcC5sZWFkVGltZSA9IHByb2R1Y3QubGVhZFRpbWU7XHJcbiAgICAgIHAuZGVsaXZlcnlNZXRob2QgPSBwcm9kdWN0LmRlbGl2ZXJ5TWV0aG9kO1xyXG5cclxuICAgICAgcC5naWZ0Q2FyZCA9IHByb2R1Y3QuZ2lmdENhcmQ7XHJcbiAgICAgIHAuZ2lmdENhcmRFeHBpcnlEYXRlID0gcHJvZHVjdC5naWZ0Q2FyZEV4cGlyeURhdGU7XHJcbiAgICAgIHAuZ2lmdENhcmROdW1iZXJJc3N1ZWQgPSBwcm9kdWN0LmdpZnRDYXJkTnVtYmVySXNzdWVkO1xyXG4gICAgICBwLmdpZnRDYXJkUmVjaXBpZW50RW1haWwgPSBwcm9kdWN0LmdpZnRDYXJkUmVjaXBpZW50RW1haWw7XHJcbiAgICAgIHAuZ2lmdENhcmRSZWNpcGllbnROYW1lID0gcHJvZHVjdC5naWZ0Q2FyZFJlY2lwaWVudE5hbWU7XHJcblxyXG4gICAgICBpZiAocHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5ID4gMCkge1xyXG4gICAgICAgIHAucmVmdW5kZWRRdWFudGl0eSA9IHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eTtcclxuICAgICAgICBwLnJlZnVuZGVkUHJvbW90aW9uYWxRdWFudGl0eSA9IHByb2R1Y3QucmVmdW5kUHJvbW90aW9uYWxRdWFudGl0eTtcclxuICAgICAgICBwLnJlZnVuZGVkID0gcHJvZHVjdC5yZWZ1bmRlZDtcclxuICAgICAgICBwLnJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb24gPSBwcm9kdWN0LnJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb247XHJcbiAgICAgICAgcC5yZWZ1bmRlZFJlYXNvbiA9IHByb2R1Y3QucmVmdW5kZWRSZWFzb247XHJcbiAgICAgICAgaWYgKCFwLnJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb24pIHtcclxuICAgICAgICAgIHAucmVmdW5kZWRSZWFzb25EZXNjcmlwdGlvbiA9IHAucmVmdW5kZWRSZWFzb247XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHAucmVmdW5kZWRUb3RhbCA9IHByb2R1Y3QucmVmdW5kZWRUb3RhbDtcclxuICAgICAgICBwLmlzTGFzdEV4Y2hhbmdlZCA9IHByb2R1Y3QuaXNMYXN0RXhjaGFuZ2VkO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAocHJvZHVjdC5leGNoYW5nZSkge1xyXG4gICAgICAgIHAuZXhjaGFuZ2UgPSBwcm9kdWN0LmV4Y2hhbmdlO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9kdWN0LmxpbmVEaXNjb3VudCkge1xyXG4gICAgICAgIHAubGluZURpc2NvdW50ID0gcHJvZHVjdC5saW5lRGlzY291bnQ7XHJcbiAgICAgIH1cclxuICAgICAgcC5pdGVtRGlzY291bnRzID0gcHJvZHVjdC5pdGVtRGlzY291bnRzIGFzIEl0ZW1EaXNjb3VudHM7XHJcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQucHJvZHVjdHMucHVzaChwKTtcclxuICAgICAgdGhpcy5saW5lRGlzY291bnQoYmFza2V0RGV0YWlscyk7XHJcbiAgICB9KTtcclxuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nSW5mbyh0aGlzLmNsYXNzTmFtZSwgXCJiYXNrZXRcIiwgXCJ0cmFuc2FjdGlvbmRvY3VtZW50IGJhc2tldCBkZXRhaWxzIHVwZGF0ZWRcIiwgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldCk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgICAqIGN1cnJlbnQgdHJhbnNhY3Rpb24gRGV0YWlscyBUb3RhbChOZXcgUHJvZHVjdHMpXHJcbiAgICAgKiBAcmV0dXJucyBjdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzXHJcbiAgICAgKi9cclxuXHJcbiAgY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscyhiYXNrZXQ6IEJhc2tldCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwiY3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc1wiLCBcImN1cnJlbnQgdHJhbnNhY3Rpb24gZGV0YWlscyBmb3IgZXhjaGFuZ2VzXCIsIGJhc2tldCk7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5wcm9kdWN0cyA9IFtdIGFzIFByb2R1Y3RbXTtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmxpbmVQcm9tb3Rpb24gPSBbXSBhcyBMaW5lUHJvbW90aW9uc1tdO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMubGluZURpc2NvdW50ID0gW10gYXMgTGluZURpc2NvdW50W107XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy50cmFuc2FjdGlvbkRpc2NvdW50ID0gW107XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5wcm9kdWN0cyA9IGJhc2tldC5wcm9kdWN0cztcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnByb2R1Y3RzID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMucHJvZHVjdHMuZmlsdGVyKFxyXG4gICAgICAoICAgICAgcHJvajogeyByZWZ1bmRlZFF1YW50aXR5OiBudW1iZXI7IH0pID0+IHByb2oucmVmdW5kZWRRdWFudGl0eSAhPSAwXHJcbiAgICApO1xyXG5cclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnByb2R1Y3RzLmZvckVhY2goKHByb2R1Y3Q6IHsgcmVmdW5kZWRRdWFudGl0eTogYW55OyBxdWFudGl0eTogYW55OyB0b3RhbExpbmVQcmljZTogbnVtYmVyOyByZWZ1bmRlZFRvdGFsOiBudW1iZXI7IHRvdGFsOiBhbnk7IHJlZnVuZGVkOiBib29sZWFuOyBsaW5lUHJvbW90aW9uczogYW55OyBsaW5lRGlzY291bnQ6IGFueTsgfSkgPT4ge1xyXG4gICAgICBpZiAocHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5KSB7XHJcbiAgICAgICAgcHJvZHVjdC5xdWFudGl0eSA9IHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eTtcclxuICAgICAgICAvLyB1cGRhdGluZyB0b3RhbCBsaW5lIHByaWNlIHdpdGggYWN0dWFsIHByaWNlIHRvIGJlIHJlZnVuZGVkIGluY2x1ZGluZyB0aGUgcmVmdW5kaW5nIHF0eVxyXG4gICAgICAgIHByb2R1Y3QudG90YWxMaW5lUHJpY2UgPSBNYXRoLmFicyhwcm9kdWN0LnJlZnVuZGVkVG90YWwpO1xyXG4gICAgICAgIHByb2R1Y3QudG90YWwgPSBwcm9kdWN0LnRvdGFsTGluZVByaWNlO1xyXG4gICAgICAgIGlmIChwcm9kdWN0LnF1YW50aXR5ID09PSBwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHkpIHtcclxuICAgICAgICAgIHByb2R1Y3QucmVmdW5kZWQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICAvL1VwZGF0aW5nIGxpbmUgcHJvbW90aW9ucyBhbmQgbGluZSBkaXNjb3VudHMgICAgICBcclxuICAgICAgaWYgKHByb2R1Y3QubGluZVByb21vdGlvbnMgJiYgIXByb2R1Y3QucmVmdW5kZWRRdWFudGl0eSkge1xyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmxpbmVQcm9tb3Rpb24ucHVzaChwcm9kdWN0LmxpbmVQcm9tb3Rpb25zKVxyXG4gICAgICB9XHJcbiAgICAgIGlmIChwcm9kdWN0LmxpbmVEaXNjb3VudCAmJiAhcHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5KSB7XHJcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMubGluZURpc2NvdW50LnB1c2gocHJvZHVjdC5saW5lRGlzY291bnQpXHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwiY3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc1wiLCBcImN1cnJlbnQgdHJhbnNhY3Rpb24gZGV0YWlscyBhZnRlciByZW1vdmluZyBvbGQgcHJvZHVjdHNcIiwgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMucHJvZHVjdHMpO1xyXG5cclxuICAgIGlmIChiYXNrZXQudHJhbnNhY3Rpb25EaXNjb3VudCAmJiBiYXNrZXQudHJhbnNhY3Rpb25EaXNjb3VudC5sZW5ndGggPiAwKSB7XHJcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQucHVzaCguLi5iYXNrZXQudHJhbnNhY3Rpb25EaXNjb3VudCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5ID0ge30gYXMgQmFza2V0U3VtbWFyeTtcclxuXHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LnNhbGVUb3RhbCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRoaXMudXBkYXRlU2FsZVRvdGFsKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzKSk7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LnRvdGFsSXRlbXMgPSBiYXNrZXQucXVhbnRpdHk7XHJcblxyXG5cclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmJhc2tldFN1bW1hcnkuYmFza2V0VG90YWwgPSBiYXNrZXQuYmFza2V0VG90YWw7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LnJlZnVuZFRvdGFsID0gdGhpcy51cGRhdGVDdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzUmVmdW5kVG90YWwoKTtcclxuICAgIC8vIEZvciBwYXJ0aWFsIHJlZnVuZCBkaXNjb3VudCBpcyB1cGRhdGllZCBpbiB0b3RhbCBsaW5lIHByaWNlIHNvIGRpc2NvdW50VG90YWwgd2lsbCBhbHdheXMgYmUgemVybyAmIGluIGNhc2Ugb2YgZXhjaGFuZ2UgZGlzY291bnQgdG90YWwgaXMgY2FsY3VsYXRlZFxyXG5cclxuICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHlwZSA9PT0gVFJBTlNBQ1RJT05fVFlQRS5TQUxFX0VYQ0hBTkdFKSB7XHJcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmJhc2tldFN1bW1hcnkuZGlzY291bnRUb3RhbCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRoaXMudXBkYXRlQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc0Rpc2NvdW50VG90YWwoKSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudCAmJiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy50cmFuc2FjdGlvbkRpc2NvdW50Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICBsZXQgZGlzY291bnRUb3RhbCA9IDA7XHJcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudC5mb3JFYWNoKChkaXNjb3VudDogeyBkaXNjb3VudEFtb3VudDogbnVtYmVyOyB9KSA9PiB7XHJcbiAgICAgICAgICBkaXNjb3VudFRvdGFsICs9IGRpc2NvdW50LmRpc2NvdW50QW1vdW50O1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmJhc2tldFN1bW1hcnkuZGlzY291bnRUb3RhbCA9IE1hdGguYWJzKGRpc2NvdW50VG90YWwpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmJhc2tldFN1bW1hcnkuZGlzY291bnRUb3RhbCA9IDA7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0luZm8odGhpcy5jbGFzc05hbWUsIFwiY3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc1wiLCBcImN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNcIiwgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMpO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuXHJcbiAgLyoqXHJcbiAqIGN1cnJlbnQgdHJhbnNhY3Rpb24gVGF4IFRvdGFsXHJcbiAqIEByZXR1cm5zIFRheCBUb3RhbFxyXG4gKi9cclxuXHJcbiAgdXBkYXRlQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc1RheEJyZWFrZG93bihiYXNrZXREZXRhaWxzOiBCYXNrZXQpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICBsZXQgdHJhbnNhY3Rpb25EaXNjb3VudFRvdGFsID0gMDtcclxuICAgIGxldCB0YXhCcmVha2Rvd246IFRheEJyZWFrZG93biA9IHtcclxuICAgICAgdGF4TGluZXM6IFtdLFxyXG4gICAgICB0b3RhbFRheGFibGVBbW91bnQ6IDAsXHJcbiAgICB9O1xyXG5cclxuICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy50cmFuc2FjdGlvbkRpc2NvdW50ICYmIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQubGVuZ3RoID4gMCkge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy50cmFuc2FjdGlvbkRpc2NvdW50LmZvckVhY2goKGRpc2NvdW50OiB7IGRpc2NvdW50QW1vdW50OiBudW1iZXI7IH0pID0+IHtcclxuICAgICAgICB0cmFuc2FjdGlvbkRpc2NvdW50VG90YWwgKz0gZGlzY291bnQuZGlzY291bnRBbW91bnQ7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5wcm9kdWN0cyAmJiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5wcm9kdWN0cy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnByb2R1Y3RzLmZvckVhY2goKHByb2R1Y3Q6IHsgaXRlbUxpbmVJZDogYW55OyBzZWxlY3RlZFZBVDogYW55OyBzZWxlY3RlZFZBVENvZGU6IGFueTsgdG90YWw6IGFueTsgcmVmdW5kZWRRdWFudGl0eTogbnVtYmVyOyBpdGVtRGlzY291bnRzOiB7IGN1cnJlbnRSZWZ1bmRQb3J0aW9uOiBudW1iZXI7IHRybkRpc2NvdW50c1BvcnRpb246IG51bWJlcjsgdHJuUHJvbW90aW9uc1BvcnRpb246IG51bWJlcjsgfTsgfSkgPT4ge1xyXG4gICAgICAgIGxldCB0YXhMaW5lOiBUYXhMaW5lID0ge1xyXG4gICAgICAgICAgaXRlbUxpbmVJZDogcHJvZHVjdC5pdGVtTGluZUlkLFxyXG4gICAgICAgICAgVkFUOiBwcm9kdWN0LnNlbGVjdGVkVkFUID8gcHJvZHVjdC5zZWxlY3RlZFZBVCA6IDAsXHJcbiAgICAgICAgICBWQVRDb2RlOiBwcm9kdWN0LnNlbGVjdGVkVkFUQ29kZSxcclxuICAgICAgICAgIHRheExpbmVUb3RhbDogMCxcclxuICAgICAgICAgIHRheGFibGVBbW91bnQ6IHByb2R1Y3QudG90YWwsXHJcbiAgICAgICAgICBQcmVUYXg6IDBcclxuXHJcbiAgICAgICAgfTtcclxuICAgICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0luZm8odGhpcy5jbGFzc05hbWUsIFwidXBkYXRlQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc1RheEJyZWFrZG93blwiLCBgaXRlbSBsaW5lIElEIDpjdXJyZW50IHRyYW5zYWN0aW9uIERldGFpbHNcIixcclxuICAgICAgICAgICR7cHJvZHVjdC5pdGVtTGluZUlkfSwgdGF4IGxpbmUgOiAke3RheExpbmV9LCBiYXNrZXREZXRhaWxzLmJhc2tldFRvdGFsICR7YmFza2V0RGV0YWlscy5iYXNrZXRUb3RhbH1gKTtcclxuXHJcbiAgICAgICAgLy9zdGVwIDFcclxuICAgICAgICAvLyBpZiBUcmFuc2FjdGlvbiBEaXNjb3VudCBhbmQvb3IgcHJvbW90aW9uIGFwcGxpZWQsIGZpbmQgbmV0IHNlbGxpbmcgcHJpY2Ugb2YgZWFjaCBwcm9kdWN0IGFzIHRheGFibGVhbW91bnRcclxuXHJcbiAgICAgICAgLy9JZiB0cmFuc2FjdGlvbiBkaXNjb3VudC9wcm9tb3Rpb24gaXMgYXBwbGllZCB0YXhhYmxlIGFtb3VudCBzaG91bGQgYmUgZGVkdWN0aW5nIHRyYW5zYWN0aW9uIHByb21vdGlvbiBhbmQgdHJhbnNhY3Rpb24gZGlzYWNvdW50IHBvcnRpb25cclxuICAgICAgICBpZiAocHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5ICYmIHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eSA+IDApIHtcclxuXHJcbiAgICAgICAgICB0YXhMaW5lLnRheGFibGVBbW91bnQgPSAtTWF0aC5hYnModGF4TGluZS50YXhhYmxlQW1vdW50IC0gcHJvZHVjdC5pdGVtRGlzY291bnRzLmN1cnJlbnRSZWZ1bmRQb3J0aW9uKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGF4TGluZS50YXhhYmxlQW1vdW50ID0gdGF4TGluZS50YXhhYmxlQW1vdW50IC0gcHJvZHVjdC5pdGVtRGlzY291bnRzLnRybkRpc2NvdW50c1BvcnRpb24gLSBwcm9kdWN0Lml0ZW1EaXNjb3VudHMudHJuUHJvbW90aW9uc1BvcnRpb247XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvL3N0ZXAgMiAtIGZpbmQgcHJlIHRheFxyXG4gICAgICAgIHRheExpbmUuUHJlVGF4ID0gdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIoKHRheExpbmUudGF4YWJsZUFtb3VudCAqIDEwMCkgLyAoMTAwICsgdGF4TGluZS5WQVQpKTtcclxuXHJcbiAgICAgICAgLy9zdGVwIDMgLSBVcGRhdGUgdGF4YnJlYWtkb3duXHJcbiAgICAgICAgdGF4QnJlYWtkb3duLnRvdGFsVGF4YWJsZUFtb3VudCArPSB0YXhMaW5lLnRheGFibGVBbW91bnQ7XHJcbiAgICAgICAgdGF4TGluZS50YXhhYmxlQW1vdW50ID0gdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIodGF4TGluZS50YXhhYmxlQW1vdW50KTtcclxuICAgICAgICBcclxuICAgICAgICAvLyBzdGVwIDQgLSB1cGRhdGUgdGF4IExpbmUgdG90YWxcclxuICAgICAgICB0YXhMaW5lLnRheExpbmVUb3RhbCA9ICB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMih0YXhMaW5lLnRheGFibGVBbW91bnQgLSB0YXhMaW5lLlByZVRheCk7XHJcbiAgICAgICAgdGF4QnJlYWtkb3duLnRheExpbmVzLnB1c2godGF4TGluZSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHRheEJyZWFrZG93bi50b3RhbFRheGFibGVBbW91bnQgPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMih0YXhCcmVha2Rvd24udG90YWxUYXhhYmxlQW1vdW50KTtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRheEJyZWFrZG93biA9IHRheEJyZWFrZG93bjtcclxuICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy50YXhCcmVha2Rvd24gJiYgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMudGF4QnJlYWtkb3duLnRheExpbmVzICYmIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRheEJyZWFrZG93bi50YXhMaW5lcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmJhc2tldFN1bW1hcnkuVkFUVG90YWwgPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMih0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy50YXhCcmVha2Rvd24udGF4TGluZXMucmVkdWNlKFxyXG4gICAgICAgIChuOiBhbnksIHsgdGF4TGluZVRvdGFsIH06IGFueSkgPT4gbiArIHRheExpbmVUb3RhbCxcclxuICAgICAgICAwXHJcbiAgICAgICkpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmJhc2tldFN1bW1hcnkuVkFUVG90YWwgPSAwLjAwO1xyXG4gICAgfVxyXG5cclxuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwidXBkYXRlQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc1RheEJyZWFrZG93blwiLCBcImVCYXNrZXQ6YWZ0ZXIgY2FsY3VsYXRpbmcgdGF4IGN1cnJlbnR0cmFuc2FjdGlvbkRldGFpbHNcIiwgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMpXHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHVwZGF0ZUN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNUb3RhbFRheFN1bW1hcnkoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gIFxyXG4gICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJ1cGRhdGVDdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzVG90YWxUYXhTdW1tYXJ5XCIsIFwiVG90YWwgVGF4IFN1bW1lcnkgUmVxdWVzdCA6XCIsIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRheEJyZWFrZG93bik7XHJcblxyXG4gICAgbGV0IHRvdGFsVGF4U3VtbWFyeUFycmF5OiBUb3RhbFRheFN1bW1hcnlbXSA9IFtdXHJcbiAgICBsZXQgdG90YWxUYXhTdW1tYXJ5R3JvdXAgPSBbXVxyXG5cclxuXHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy50YXhCcmVha2Rvd24udGF4TGluZXMuZm9yRWFjaCgoZWxlbWVudDogeyBWQVRDb2RlOiBhbnk7IFZBVDogYW55OyBQcmVUYXg6IGFueTsgdGF4TGluZVRvdGFsOiBhbnk7IH0pID0+IHtcclxuICAgICAgbGV0IFRheFN1bW1hcnk6IFRvdGFsVGF4U3VtbWFyeSA9IHtcclxuICAgICAgICBWQVRDb2RlOlwiXCIsXHJcbiAgICAgICAgVkFUOiAtMTIzNDUsXHJcbiAgICAgICAgUHJlVGF4U3VtOiAwLFxyXG4gICAgICAgIFRheFN1bTogMCxcclxuICAgICAgICBUWHJhdGVTdW06IDBcclxuICAgICAgfTtcclxuICAgICAgICBUYXhTdW1tYXJ5LlZBVENvZGU9ZWxlbWVudC5WQVRDb2RlO1xyXG4gICAgICAgIFRheFN1bW1hcnkuVkFUID0gZWxlbWVudC5WQVQ7ICAgICAgICBcclxuICAgICAgIFxyXG4gICAgICAgIFRheFN1bW1hcnkuUHJlVGF4U3VtID0gdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIoZWxlbWVudC5QcmVUYXgpOyAgICAgICAgXHJcbiAgICAgICAgVGF4U3VtbWFyeS5UYXhTdW0gPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMihlbGVtZW50LnRheExpbmVUb3RhbCk7XHJcbiAgICAgICAgVGF4U3VtbWFyeS5UWHJhdGVTdW0gPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMihUYXhTdW1tYXJ5LlByZVRheFN1bSArIFRheFN1bW1hcnkuVGF4U3VtKTsgICAgIFxyXG4gICAgICAgIHRvdGFsVGF4U3VtbWFyeUFycmF5LnB1c2goVGF4U3VtbWFyeSk7XHJcbiAgICB9KVxyXG5cclxuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwidXBkYXRlQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc1RvdGFsVGF4U3VtbWFyeVwiLCBcIlRvdGFsIFRheCBTdW1tZXJ5ICBXaXRob3V0IEdyb3VwZWQgOiBcIiwgdG90YWxUYXhTdW1tYXJ5QXJyYXkpO1xyXG4gICAgXHJcbiAgICB0b3RhbFRheFN1bW1hcnlHcm91cCA9IHRvdGFsVGF4U3VtbWFyeUFycmF5LnJlZHVjZSgocHJlcGFyZWRBcnJheTphbnksY3VycmVudE9iajphbnkpID0+IHtcclxuICAgICAgbGV0IGluZCA9IHByZXBhcmVkQXJyYXkuZmluZEluZGV4KCh4OiB7IFZBVDogYW55OyB9KSA9PiB4LlZBVCA9PT0gY3VycmVudE9iai5WQVQpO1xyXG4gICAgICBpZihpbmQgPT09IC0xKXtcclxuICAgICAgICBwcmVwYXJlZEFycmF5LnB1c2goY3VycmVudE9iailcclxuICAgICAgfWVsc2Uge1xyXG4gICAgICAgIHByZXBhcmVkQXJyYXlbaW5kXS5WQVRDb2RlID0gY3VycmVudE9iai5WQVRDb2RlO1xyXG4gICAgICAgIHByZXBhcmVkQXJyYXlbaW5kXS5WQVQgPSBjdXJyZW50T2JqLlZBVDtcclxuICAgICAgICBwcmVwYXJlZEFycmF5W2luZF0uUHJlVGF4U3VtICs9IGN1cnJlbnRPYmouUHJlVGF4U3VtO1xyXG4gICAgICAgIHByZXBhcmVkQXJyYXlbaW5kXS5UYXhTdW0gKz0gY3VycmVudE9iai5UYXhTdW07XHJcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlRYcmF0ZVN1bSArPSBjdXJyZW50T2JqLlRYcmF0ZVN1bTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gcHJlcGFyZWRBcnJheTtcclxuICAgIH0sW10pXHJcbiAgICAvLyBsaXN0T2ZUYWdzLm1hcCh4ID0+IHVuaXF1ZS5maWx0ZXIoYSA9PiBhLmxhYmVsID09IHgubGFiZWwgJiYgYS5jb2xvciA9PSB4LmNvbG9yKS5sZW5ndGggPiAwID8gbnVsbCA6IHVuaXF1ZS5wdXNoKHgpKTtcclxuXHJcbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcInVwZGF0ZUN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNUb3RhbFRheFN1bW1hcnlcIiwgXCJUb3RhbCAgVGF4IFN1bW1lciBHcm91cCA6XCIsIHRvdGFsVGF4U3VtbWFyeUdyb3VwKTtcclxuXHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy50b3RhbFRheFN1bW1hcnkgPSB0b3RhbFRheFN1bW1hcnlHcm91cDtcclxuICAgIHJldHVybiB0aGlzO1xyXG5cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGN1cnJlbnQgdHJhbnNhY3Rpb24gRGlzb2N1bnQgVG90YWxcclxuICAgKiBAcmV0dXJucyBEaXNjb3VudCBUb3RhbFxyXG4gICAqL1xyXG4gIHVwZGF0ZUN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNEaXNjb3VudFRvdGFsKCkge1xyXG4gICAgbGV0IHJlZnVuZFRvdGFsID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS5yZWZ1bmRUb3RhbCA/IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmJhc2tldFN1bW1hcnkucmVmdW5kVG90YWwgOiAwO1xyXG5cclxuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwidXBkYXRlQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc0Rpc2NvdW50VG90YWxcIiwgIGByZWZ1bmRUb3RhbCAke3JlZnVuZFRvdGFsfSwgYmFza2V0VG90YWwgJHt0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsfSxzYWxlVG90YWwgICR7dGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS5zYWxlVG90YWx9YCk7XHJcbiAgICBjb25zdCBkaXNjb3VudFRvdGFsID1cclxuICAgICAgTWF0aC5hYnMoXHJcbiAgICAgICAgTWF0aC5hYnModGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS5zYWxlVG90YWwpIC1cclxuICAgICAgICAoTWF0aC5hYnModGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS5iYXNrZXRUb3RhbCkgKyBNYXRoLmFicyhyZWZ1bmRUb3RhbCkpXHJcbiAgICAgICk7XHJcbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcInVwZGF0ZUN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNEaXNjb3VudFRvdGFsXCIsIFwiZGlzY291bnRUb3RhbFwiLCBkaXNjb3VudFRvdGFsKVxyXG4gICAgcmV0dXJuIE51bWJlcihkaXNjb3VudFRvdGFsLnRvRml4ZWQoMikpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgKiBjdXJyZW50IHRyYW5zYWN0aW9uIFJlZnVuZCBUb3RhbFxyXG4gICogQHJldHVybnMgUmVmdW5kIFRvdGFsXHJcbiAgKi9cclxuICB1cGRhdGVDdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzUmVmdW5kVG90YWwoKSB7XHJcbiAgICBsZXQgdG90YWxSZWZ1bmQgPSAwO1xyXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnByb2R1Y3RzLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICBjb25zdCBwcm9kdWN0OiBQcm9kdWN0ID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMucHJvZHVjdHNbaW5kZXhdO1xyXG4gICAgICBpZiAocHJvZHVjdC5yZWZ1bmRlZFRvdGFsKSB7XHJcbiAgICAgICAgdG90YWxSZWZ1bmQgPSB0b3RhbFJlZnVuZCArIHByb2R1Y3QucmVmdW5kZWRUb3RhbDtcclxuICAgICAgfVxyXG4gICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcInVwZGF0ZUN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNSZWZ1bmRUb3RhbFwiLCBcInRvdGFsUmVmdW5kIGZvciBDdXJyZW50IFRyYW5zYWN0aW9uRGV0YWlsc1wiICwgdG90YWxSZWZ1bmQpXHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG90YWxSZWZ1bmQ7XHJcbiAgfVxyXG5cclxuXHJcblxyXG4gIC8qKlxyXG4gICAqIEJhc2tldHMgc3VtbWFyeVxyXG4gICAqIEBwYXJhbSBiYXNrZXREZXRhaWxzXHJcbiAgICogQHJldHVybnMgc3VtbWFyeVxyXG4gICAqL1xyXG4gIGJhc2tldFN1bW1hcnkoYmFza2V0RGV0YWlsczogQmFza2V0KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuYmFza2V0VG90YWwgPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsKGJhc2tldERldGFpbHMuYmFza2V0VG90YWwpO1xyXG5cclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LnNhbGVUb3RhbCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRoaXMudXBkYXRlU2FsZVRvdGFsKFxyXG4gICAgICBiYXNrZXREZXRhaWxzXHJcbiAgICApKTtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LnJlZnVuZFRvdGFsID0gdGhpcy5nZXRSZWZ1bmRUb3RhbCgpO1xyXG4gICAgaWYgKFxyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudCB8fFxyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb25cclxuICAgICkge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5kaXNjb3VudFRvdGFsID0gdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIodGhpcy51cGRhdGVEaXNjb3VudFRvdGFsKCkpO1xyXG4gICAgfVxyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkudG90YWxJdGVtcyA9IGJhc2tldERldGFpbHMucXVhbnRpdHk7XHJcblxyXG5cclxuICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRheEJyZWFrZG93bikge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5WQVRUb3RhbCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudGF4QnJlYWtkb3duLnRheExpbmVzLnJlZHVjZShcclxuICAgICAgICAobjogYW55LCB7IHRheExpbmVUb3RhbCB9OiBhbnkpID0+IG4gKyB0YXhMaW5lVG90YWwsXHJcbiAgICAgICAgMFxyXG4gICAgICApKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5WQVRUb3RhbCA9IDAuMDA7XHJcbiAgICB9XHJcblxyXG4gICAgQXBwTG9nZ2VyU2VydmljZS5sb2dJbmZvKHRoaXMuY2xhc3NOYW1lLCBcImJhc2tldFN1bW1hcnlcIiwgXCJiYXNrZXRzdW1tYXJ5IHVwZGF0ZWQgaW4gdHJhbnNhY3Rpb24gZG9jdW1lbnQ6IFwiLCB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExpbmUgRGlzY291bnRcclxuICAgKiBAcGFyYW0gYmFza2V0RGV0YWlsc1xyXG4gICAqIEByZXR1cm5zIGxpbmUgRGlzY291bnRcclxuICAgKi9cclxuICBsaW5lRGlzY291bnQoYmFza2V0RGV0YWlsczogQmFza2V0KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnQgPSBbXTtcclxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBiYXNrZXREZXRhaWxzLnByb2R1Y3RzLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICBjb25zdCBlbGVtZW50ID0gYmFza2V0RGV0YWlscy5wcm9kdWN0c1tpbmRleF07XHJcbiAgICAgIGlmIChlbGVtZW50LmxpbmVEaXNjb3VudCkge1xyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50LnB1c2goZWxlbWVudC5saW5lRGlzY291bnQpO1xyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50ID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnQucmVkdWNlKFxyXG4gICAgICAgICAgKGFjYzogYW55W10sIHZhbDogeyBpdGVtTGluZUlkOiBhbnk7IH0pID0+IHtcclxuICAgICAgICAgICAgaWYgKCFhY2MuZmluZCgoZWw6IHsgaXRlbUxpbmVJZDogYW55OyB9KSA9PiBlbC5pdGVtTGluZUlkID09PSB2YWwuaXRlbUxpbmVJZCkpIHtcclxuICAgICAgICAgICAgICBhY2MucHVzaCh2YWwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBhY2M7XHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgICAgW11cclxuICAgICAgICApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0luZm8odGhpcy5jbGFzc05hbWUsIFxyXG4gICAgICAvLyAgIFwiZS1iYXNrZXQgOmxpbmUgZGlzY291bnQgdXBkYXRlZCBpbiB0cmFuc2FjdGlvbiBkb2N1bWVudFwiLFxyXG4gICAgICAvLyAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50XHJcbiAgICAgIC8vICk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGV4Y2hhbmdlXHJcbiAgICogQHBhcmFtIGJhc2tldERldGFpbHNcclxuICAgKiBAcmV0dXJucyBleGNoYW5nZSBcclxuICAgKi9cclxuICBleGNoYW5nZShiYXNrZXREZXRhaWxzOiBCYXNrZXQpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmV4Y2hhbmdlID0gYmFza2V0RGV0YWlscy5leGNoYW5nZSAmJiBiYXNrZXREZXRhaWxzLmV4Y2hhbmdlLmxlbmd0aCA+IDAgPyBbLi4uYmFza2V0RGV0YWlscy5leGNoYW5nZV0gOiBbXTtcclxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBiYXNrZXREZXRhaWxzLnByb2R1Y3RzLmxlbmd0aDsgaW5kZXgrKykge1xyXG5cclxuICAgICAgY29uc3QgZWxlbWVudDogYW55ID0gYmFza2V0RGV0YWlscy5wcm9kdWN0c1tpbmRleF07XHJcbiAgICAgIGlmIChlbGVtZW50LmV4Y2hhbmdlICE9IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIGNvbnN0IGlzUHJlc2VudCA9IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQuZXhjaGFuZ2Uuc29tZSgoZWw6IHsgZXhjaGFuZ2VJZDogYW55OyB9KSA9PiBlbC5leGNoYW5nZUlkID09PSBlbGVtZW50LmV4Y2hhbmdlLmV4Y2hhbmdlSWQpO1xyXG4gICAgICAgIGlmICghaXNQcmVzZW50KSB7XHJcbiAgICAgICAgICBsZXQgZXhjaGFuZ2VJdGVtcyA9IFtdO1xyXG4gICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBlbGVtZW50LmV4Y2hhbmdlLm5ld0l0ZW1zLmxlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSBlbGVtZW50LmV4Y2hhbmdlLm5ld0l0ZW1zW2pdO1xyXG4gICAgICAgICAgICBsZXQgbmV3SXRlbXM6IGFueSA9IHsgbGluZUl0ZW1JZDogaXRlbS5pdGVtTGluZUlkLCBRdWFudGl0eTogaXRlbS5xdWFudGl0eSB9XHJcbiAgICAgICAgICAgIGV4Y2hhbmdlSXRlbXMucHVzaChuZXdJdGVtcyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBlbGVtZW50LmV4Y2hhbmdlLm5ld0l0ZW1zID0gWy4uLmV4Y2hhbmdlSXRlbXNdO1xyXG4gICAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5leGNoYW5nZS5wdXNoKGVsZW1lbnQuZXhjaGFuZ2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcImV4Y2hhbmdlXCIsXHJcbiAgICAgICAgXCJ0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0IGV4Y2hhbmdlXCIsXHJcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5leGNoYW5nZVxyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgKiBhZGQgcHJldmlvdXMgZXhjaGFuZ2UgZGF0YVxyXG4gICogQHBhcmFtIG9yaWdpbmFsVHJhbnNhY3Rpb25Eb2N1bWVudFxyXG4gICogQHJldHVybnMgbGluZSBQcm9tb3Rpb25zXHJcbiAgKi9cclxuICBhZGRFeGNoYW5nZURhdGEob3JpZ2luYWxUcmFuc2FjdGlvbkRvY3VtZW50OiBUcmFuc2FjdGlvbkRvY3VtZW50KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5leGNoYW5nZSA9IG9yaWdpbmFsVHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQuZXhjaGFuZ2UgPyBbLi4ub3JpZ2luYWxUcmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5leGNoYW5nZV0gOiBudWxsO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBsaW5lIFByb21vdGlvbnNcclxuICAgKiBAcGFyYW0gYmFza2V0RGV0YWlsc1xyXG4gICAqIEByZXR1cm5zIGxpbmUgUHJvbW90aW9uc1xyXG4gICAqL1xyXG4gIGxpbmVQcm9tb3Rpb24oYmFza2V0RGV0YWlsczogQmFza2V0KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lUHJvbW90aW9uID0gW107XHJcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgYmFza2V0RGV0YWlscy5wcm9kdWN0cy5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgY29uc3QgZWxlbWVudCA9IGJhc2tldERldGFpbHMucHJvZHVjdHNbaW5kZXhdO1xyXG4gICAgICBpZiAoZWxlbWVudC5saW5lUHJvbW90aW9ucykge1xyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbi5wdXNoKFxyXG4gICAgICAgICAgZWxlbWVudC5saW5lUHJvbW90aW9uc1xyXG4gICAgICAgICk7XHJcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lUHJvbW90aW9uID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lUHJvbW90aW9uLnJlZHVjZShcclxuICAgICAgICAgIChhY2M6IGFueVtdLCB2YWw6IHsgaXRlbUxpbmVJZDogYW55OyB9KSA9PiB7XHJcbiAgICAgICAgICAgIGlmICghYWNjLmZpbmQoKGVsOiB7IGl0ZW1MaW5lSWQ6IGFueTsgfSkgPT4gZWwuaXRlbUxpbmVJZCA9PT0gdmFsLml0ZW1MaW5lSWQpKSB7XHJcbiAgICAgICAgICAgICAgYWNjLnB1c2godmFsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gYWNjO1xyXG4gICAgICAgICAgfSxcclxuICAgICAgICAgIFtdXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiB0cmFuc2FjdGlvbiBQcm9tb3Rpb25cclxuICAgKiBAcGFyYW0gYmFza2V0RGV0YWlsc1xyXG4gICAqIEByZXR1cm5zIHRyYW5zYWN0aW9uIFByb21vdGlvblxyXG4gICAqL1xyXG4gIHRyYW5zYWN0aW9uUHJvbW90aW9uKGJhc2tldERldGFpbHM6IEJhc2tldCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIGlmIChiYXNrZXREZXRhaWxzLnRyYW5zYWN0aW9uUHJvbW90aW9uKSB7XHJcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb24gPVxyXG4gICAgICAgIGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25Qcm9tb3Rpb247XHJcbiAgICAgIC8vICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGJhc2tldERldGFpbHMuVHJhbnNhY3Rpb25EaXNjb3VudC5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgLy8gICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uLnB1c2goZWxlbWVudC5saW5lUHJvbW90aW9ucylcclxuICAgICAgLy8gICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uID0gIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbnMucmVkdWNlKChhY2MsIHZhbCkgPT4ge1xyXG4gICAgICAvLyAgICAgaWYgKCFhY2MuZmluZChlbCA9PiBlbC5pdGVtTGluZUlkID09PSB2YWwuaXRlbUxpbmVJZCkpIHtcclxuICAgICAgLy8gICAgICAgYWNjLnB1c2godmFsKTtcclxuICAgICAgLy8gICAgIH1cclxuICAgICAgLy8gICAgIHJldHVybiBhY2M7XHJcbiAgICAgIC8vICAgfSwgW10pO1xyXG4gICAgICAvLyB9XHJcbiAgICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwidHJhbnNhY3Rpb25Qcm9tb3Rpb25cIixcclxuICAgICAgICBcInRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb25cIixcclxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHRyYW5zYWN0aW9uRGlzY291bnQoYmFza2V0RGV0YWlsczogQmFza2V0KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgaWYgKGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudCkge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQgPVxyXG4gICAgICAgIGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudDtcclxuXHJcbiAgICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwidHJhbnNhY3Rpb25EaXNjb3VudFwiLFxyXG4gICAgICAgIFwidHJhbnNhY3Rpb24gRGlzY291bnRcIixcclxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnRcclxuICAgICAgKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUGF5bWVudHMgZGV0YWlsc1xyXG4gICAqIEBwYXJhbSBwYXltZW50RGV0YWlsc1xyXG4gICAqIEByZXR1cm5zXHJcbiAgICovXHJcbiAgcGF5bWVudERldGFpbHMocGF5bWVudERldGFpbHM6IGFueSkge1xyXG4gICAgQXBwTG9nZ2VyU2VydmljZS5sb2dJbmZvKHRoaXMuY2xhc3NOYW1lLCBcInBheW1lbnREZXRhaWxzXCIsIFwicGF5bWVudCBkZXRhaWxzIGFmdGVyIHRyYW5zYWN0aW9uIGNvbXBsZXRlZFwiLHBheW1lbnREZXRhaWxzKTtcclxuICAgIFxyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnBheW1lbnREZXRhaWxzID0gcGF5bWVudERldGFpbHM7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG5cclxuICAvKipcclxuICAgKiBQYXltZW50cyBkZXRhaWxzXHJcbiAgICogQHBhcmFtIHBheW1lbnREZXRhaWxzXHJcbiAgICogQHJldHVybnNcclxuICAgKi9cclxuICAgc3BsaXRQYXltZW50KHNwbGl0UGF5bWVudDogYm9vbGVhbikgeyAgICBcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5zcGxpdFBheW1lbnQgPSBzcGxpdFBheW1lbnQ7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9IFxyXG5cclxuICAgLyoqXHJcbiAgICogUGF5bWVudHMgZGV0YWlsc1xyXG4gICAqIEBwYXJhbSBwYXltZW50RGV0YWlsc1xyXG4gICAqIEByZXR1cm5zXHJcbiAgICovXHJcbiAgICBpc1BheW1lbnRDb21wbGV0ZWQoaXNQYXltZW50Q29tcGxldGVkOiBib29sZWFuKSB7XHJcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5pc1BheW1lbnRDb21wbGV0ZWQgPSBpc1BheW1lbnRDb21wbGV0ZWQ7XHJcbiAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfSBcclxuICBcclxuXHJcblxyXG5cclxuICAvKipcclxuICAgKiBCYXNlcyBjdXJyZW5jeVxyXG4gICAqIEBwYXJhbSBjdXJyZW5jeVxyXG4gICAqIEByZXR1cm5zIGN1cnJlbmN5XHJcbiAgICovXHJcbiAgYmFzZUN1cnJlbmN5KGN1cnJlbmN5OiBhbnkpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFzZUN1cnJlbmN5ID0gY3VycmVuY3k7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICogZ2lmdCBvcHRpb24gYXRcclxuICAqIEByZXR1cm5zIGF0XHJcbiAgKi9cclxuICBnaWZ0T3B0aW9uKGdpZnQ6IGFueSk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwiZ2lmdE9wdGlvblwiLFxyXG4gICAgICBcInRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5naWZ0b3B0aW9uXCIsXHJcbiAgICAgIGdpZnRcclxuICAgICk7XHJcbiAgICBpZiAoZ2lmdCkge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuZ2lmdGVkUmVjZWlwdCA9IGdpZnQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcbiAgLyoqXHJcblxyXG4vKipcclxuICogbWFudWFsIERpc2NvdW50XHJcbiAqIEBwYXJhbSBkaXNjb3VudERhdGFcclxuICogQHJldHVybnNcclxuICovXHJcblxyXG4gIC8vIG1hbnVhbERpc2NvdW50KGRpc2NvdW50RGF0YSA6IGJhc2tldERpc2NvdW50KTpUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgLy8gICBsZXQgc2FsZVRvdGFsID0gIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsO1xyXG4gIC8vICAgaWYoZGlzY291bnREYXRhLmRpc2NvdW50VHlwZSA9PSdQZXJjZW50Jyl7XHJcbiAgLy8gICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsID0gc2FsZVRvdGFsLShzYWxlVG90YWwqKGRpc2NvdW50RGF0YS5kaXNjb3VudEFtb3VudC8xMDApKTtcclxuICAvLyAgICAgZGlzY291bnREYXRhLmRpc2NvdW50QW1vdW50ID0gLTEqKHNhbGVUb3RhbC10aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5iYXNrZXRUb3RhbCk7XHJcbiAgLy8gICB9ZWxzZSB7XHJcbiAgLy8gICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsID1zYWxlVG90YWwtZGlzY291bnREYXRhLmRpc2NvdW50QW1vdW50O1xyXG4gIC8vICAgICBkaXNjb3VudERhdGEuZGlzY291bnRBbW91bnQgPSAtMSpkaXNjb3VudERhdGEuZGlzY291bnRBbW91bnQ7XHJcbiAgLy8gICB9XHJcbiAgLy8gICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHJhbnNhY3Rpb25EaXNjb3VudC5wdXNoKGRpc2NvdW50RGF0YSk7XHJcbiAgLy8gICByZXR1cm4gdGhpcztcclxuXHJcbiAgLy8gfVxyXG5cclxuICAvKipcclxuICAgKiBUeXBlcyB0cmFuc2FjdGlvbiBkb2N1bWVudCBidWlsZGVyXHJcbiAgICogQHBhcmFtIHRcclxuICAgKiBAcmV0dXJucyB0eXBlXHJcbiAgICovXHJcbiAgdHlwZSh0OiBhbnkpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHlwZSA9IHQ7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcbiAgLyoqXHJcbiAgICogT3BlcmF0aW9ucyBzdGF0dXNcclxuICAgKiBAcGFyYW0gb1xyXG4gICAqIEByZXR1cm5zIHN0YXR1c1xyXG4gICAqL1xyXG4gIG9wZXJhdGlvblN0YXR1cyhvOiBhbnkpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQub3BlcmF0aW9uU3RhdHVzID0gbztcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBDcmVhdGVkIGF0XHJcbiAgICogQHJldHVybnMgYXRcclxuICAgKi9cclxuICBjcmVhdGVkQXQoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKCk7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3JlYXRlZEF0ID0gZGF0ZS50b0lTT1N0cmluZygpO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnVwZGF0ZWRBdCA9IGRhdGUudG9JU09TdHJpbmcoKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBVcGRhdGVkIGF0XHJcbiAgICogQHJldHVybnMgYXRcclxuICAgKi9cclxuICB1cGRhdGVkQXQoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKCk7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudXBkYXRlZEF0ID0gZGF0ZS50b0lTT1N0cmluZygpO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIHRyYW5zc2FjdGlvbiBjb21wbGV0aW9uIGF0XHJcbiAgICogQHJldHVybnMgdHJhbnNhY3Rpb24gY29tcGxldGlvbiBkYXRlXHJcbiAgICovXHJcbiAgdHJhbnNhY3Rpb25Db21wbGV0ZWRBdCgpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKTtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC50cmFuc0NvbXBsZXRlZEF0ID0gZGF0ZS50b0lTT1N0cmluZygpO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEJ1aWxkcyB0cmFuc2FjdGlvbiBkb2N1bWVudCBidWlsZGVyXHJcbiAgICogQHJldHVybnMgYnVpbGRcclxuICAgKi9cclxuICBidWlsZCgpOiBUcmFuc2FjdGlvbkRvY3VtZW50IHtcclxuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTYWxlcyB0b3RhbCBpbiByZWZ1bmRcclxuICAgKiBAcGFyYW0gc2FsZVRvdGFsXHJcbiAgICogQHJldHVybnMgdG90YWwgaW4gcmVmdW5kXHJcbiAgICovXHJcbiAgc2FsZVRvdGFsSW5SZWZ1bmQoc2FsZVRvdGFsOiBudW1iZXIpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuc2FsZVRvdGFsID0gc2FsZVRvdGFsO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXRzIGJhc2tldCBkZXRhaWxzXHJcbiAgICogQHJldHVybnMgYmFza2V0IGRldGFpbHNcclxuICAgKi9cclxuICBnZXRCYXNrZXREZXRhaWxzKCk6IEJhc2tldCB7XHJcbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0luZm8odGhpcy5jbGFzc05hbWUsIFwiZ2V0QmFza2V0RGV0YWlsc1wiLCBcIkdldHRpbmcgQmFza2V0IGZvciB0cmFuc2FjdGlvbkRvY3VtZW50XCIsIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudCk7XHJcblxyXG4gICAgbGV0IGJhc2tldDogQmFza2V0ID0ge1xyXG4gICAgICBzdWJzaWRpYXJ5SWQgOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuc3Vic2lkaWFyeUlkLFxyXG4gICAgICB0cmFuc2FjdGlvbkRpc2NvdW50OiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQsXHJcbiAgICAgIHRyYW5zYWN0aW9uUHJvbW90aW9uOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uLFxyXG4gICAgICB0cmFuc2FjdGlvbklkOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHJhbnNhY3Rpb25JZCxcclxuICAgICAgb2ZmbGluZVRyYW5zYWN0aW9uSWQ6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5vZmZsaW5lVHJhbnNhY3Rpb25JZCxcclxuICAgICAgdG90YWw6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsLFxyXG4gICAgICBiYXNrZXRUb3RhbDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuYmFza2V0VG90YWwsXHJcbiAgICAgIGRpc2NvdW50VG90YWw6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmRpc2NvdW50VG90YWwsXHJcbiAgICAgIHNhbGVUb3RhbDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuc2FsZVRvdGFsLFxyXG4gICAgICByZWZ1bmRUb3RhbDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkucmVmdW5kVG90YWwsXHJcbiAgICAgIHF1YW50aXR5OiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS50b3RhbEl0ZW1zLFxyXG4gICAgICBwcm9kdWN0czogW10sXHJcbiAgICAgIGJhc2VDdXJyZW5jeTogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2VDdXJyZW5jeSxcclxuICAgICAgY3VzdG9tZXI6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXN0b21lcixcclxuICAgIH07XHJcblxyXG4gICAgYmFza2V0LnByb2R1Y3RzID0gW10gYXMgUHJvZHVjdFtdO1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5wcm9kdWN0cy5mb3JFYWNoKChwcm9kdWN0OiB7IFNLVTogYW55OyBiYXJDb2RlOiBhbnk7IGJhcmNvZGVzOiBhbnk7IGRlc2NyaXB0aW9uOiBhbnk7IGltYWdlVXJsczogYW55OyB0b3RhbExpbmVQcmljZTogYW55OyBpdGVtTGluZUlkOiBhbnk7IGV4Y2x1ZGVQcm9tb3Rpb246IGFueTsgcHJpY2U6IGFueTsgcXVhbnRpdHk6IGFueTsgc2VsZWN0ZWRSUlBQcmljZTogYW55OyBmdWxsZmlsbWVudElkOiBhbnk7IGZ1bGxmaWxtZW50TG9jYXRpb25OYW1lOiBhbnk7IGRlbGl2ZXJ5R3JvdXA6IHN0cmluZzsgbGVhZFRpbWU6IGFueTsgZGVsaXZlcnlNZXRob2Q6IGFueTsgZ2lmdENhcmQ6IGFueTsgZ2lmdENhcmRFeHBpcnlEYXRlOiBhbnk7IGdpZnRDYXJkTnVtYmVySXNzdWVkOiBhbnk7IGdpZnRDYXJkUmVjaXBpZW50RW1haWw6IGFueTsgZ2lmdENhcmRSZWNpcGllbnROYW1lOiBhbnk7IHJlZnVuZGVkVG90YWw6IGFueTsgcmVmdW5kZWRRdWFudGl0eTogbnVtYmVyOyByZWZ1bmRlZFJlYXNvbkRlc2NyaXB0aW9uOiBhbnk7IHJlZnVuZGVkUmVhc29uOiBhbnk7IHJlZnVuZGVkUHJvbW90aW9uYWxRdWFudGl0eTogYW55OyBpc0xhc3RFeGNoYW5nZWQ6IGFueTsgfSwgaW5kZXg6IGFueSkgPT4ge1xyXG4gICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBKU09OLnN0cmluZ2lmeShwcm9kdWN0KSwgXCJlYmFza2V0OiBiYXNrZXQgZGV0YWlsIHVwZGF0ZSBpbiBiYXNrZXRcIik7XHJcbiAgICAgIGNvbnN0IHAgPSB7fSBhcyBhbnk7XHJcbiAgICAgIHAuU0tVID0gcHJvZHVjdC5TS1U7XHJcbiAgICAgIHAuYmFyY29kZSA9IHByb2R1Y3QuYmFyQ29kZTtcclxuICAgICAgcC5iYXJjb2RlcyA9IHByb2R1Y3QuYmFyY29kZXM7XHJcblxyXG4gICAgICBwLmRlc2NyaXB0aW9uID0gcHJvZHVjdC5kZXNjcmlwdGlvbjtcclxuICAgICAgcC5pbWFnZVVybHMgPSBwcm9kdWN0LmltYWdlVXJscztcclxuICAgICAgcC5jdXJyZW5jeSA9IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNlQ3VycmVuY3k7XHJcbiAgICAgIHAudG90YWxMaW5lUHJpY2UgPSBwcm9kdWN0LnRvdGFsTGluZVByaWNlO1xyXG4gICAgICBwLml0ZW1MaW5lSWQgPSBOdW1iZXIocHJvZHVjdC5pdGVtTGluZUlkKTtcclxuICAgICAgcC5leGNsdWRlUHJvbW90aW9uID0gcHJvZHVjdC5leGNsdWRlUHJvbW90aW9uO1xyXG5cclxuICAgICAgcC5zZWxlY3RlZFByaWNlID0gcHJvZHVjdC5wcmljZTtcclxuICAgICAgcC5xdWFudGl0eSA9IHByb2R1Y3QucXVhbnRpdHk7XHJcbiAgICAgIHAudG90YWwgPSBwcm9kdWN0LnRvdGFsTGluZVByaWNlO1xyXG4gICAgICBwLnNlbGVjdGVkUlJQUHJpY2UgPSBwcm9kdWN0LnNlbGVjdGVkUlJQUHJpY2U7XHJcblxyXG4gICAgICBwLmZ1bGxmaWxtZW50SWQgPSBwcm9kdWN0LmZ1bGxmaWxtZW50SWQ7XHJcbiAgICAgIHAuZnVsbGZpbG1lbnRMb2NhdGlvbk5hbWUgPSBwcm9kdWN0LmZ1bGxmaWxtZW50TG9jYXRpb25OYW1lO1xyXG4gICAgICBwLmRlbGl2ZXJ5R3JvdXAgPSBwcm9kdWN0LmRlbGl2ZXJ5R3JvdXAgfHwgXCIxXCI7XHJcbiAgICAgIHAubGVhZFRpbWUgPSBwcm9kdWN0LmxlYWRUaW1lO1xyXG4gICAgICBwLmRlbGl2ZXJ5TWV0aG9kID0gcHJvZHVjdC5kZWxpdmVyeU1ldGhvZCB8fCBERUxJVkVSWV9NRVRIT0RTLkNPTExFQ1RfRlJPTV9TVE9SRS50b1N0cmluZygpO1xyXG5cclxuICAgICAgaWYocC5mdWxsZmlsbWVudElkICE9IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5zdG9yZUlkKVxyXG4gICAgICB7XHJcbiAgICAgICAgcC5pc1dlYk9yZGVyID0gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgXHJcbiAgICAgIHAuZ2lmdENhcmQgPSBwcm9kdWN0LmdpZnRDYXJkO1xyXG4gICAgICBwLmdpZnRDYXJkRXhwaXJ5RGF0ZSA9IHByb2R1Y3QuZ2lmdENhcmRFeHBpcnlEYXRlO1xyXG4gICAgICBwLmdpZnRDYXJkTnVtYmVySXNzdWVkID0gcHJvZHVjdC5naWZ0Q2FyZE51bWJlcklzc3VlZDtcclxuICAgICAgcC5naWZ0Q2FyZFJlY2lwaWVudEVtYWlsID0gcHJvZHVjdC5naWZ0Q2FyZFJlY2lwaWVudEVtYWlsO1xyXG4gICAgICBwLmdpZnRDYXJkUmVjaXBpZW50TmFtZSA9IHByb2R1Y3QuZ2lmdENhcmRSZWNpcGllbnROYW1lO1xyXG4gICAgICBcclxuICAgICAgaWYgKFxyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50ICYmXHJcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnQubGVuZ3RoID4gMFxyXG4gICAgICApIHtcclxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudC5mb3JFYWNoKChsaW5lRGlzY291bnQ6IHsgaXRlbUxpbmVJZDogeyB0b1N0cmluZzogKCkgPT4gYW55OyB9OyBkaXNjb3VudGVkTGluZVByaWNlOiBhbnk7IH0pID0+IHtcclxuICAgICAgICAgIGlmIChwcm9kdWN0Lml0ZW1MaW5lSWQgPT09IGxpbmVEaXNjb3VudC5pdGVtTGluZUlkLnRvU3RyaW5nKCkpIHtcclxuICAgICAgICAgICAgcC5saW5lRGlzY291bnQgPSBsaW5lRGlzY291bnQ7XHJcbiAgICAgICAgICAgIHAudG90YWwgPSBsaW5lRGlzY291bnQuZGlzY291bnRlZExpbmVQcmljZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKFxyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbiAmJlxyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbi5sZW5ndGggPiAwXHJcbiAgICAgICkge1xyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbi5mb3JFYWNoKChsaW5lUHJvbW90aW9uOiB7IGl0ZW1MaW5lSWQ6IHsgdG9TdHJpbmc6ICgpID0+IGFueTsgfTsgcHJvbW90aW9uTGluZVByaWNlOiBhbnk7IH0pID0+IHtcclxuICAgICAgICAgIGlmIChwcm9kdWN0Lml0ZW1MaW5lSWQgPT09IGxpbmVQcm9tb3Rpb24uaXRlbUxpbmVJZC50b1N0cmluZygpKSB7XHJcbiAgICAgICAgICAgIHAubGluZVByb21vdGlvbnMgPSBsaW5lUHJvbW90aW9uO1xyXG4gICAgICAgICAgICBwLnRvdGFsID0gbGluZVByb21vdGlvbi5wcm9tb3Rpb25MaW5lUHJpY2U7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChcclxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRheEJyZWFrZG93biAmJlxyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudGF4QnJlYWtkb3duLnRheExpbmVzLmxlbmd0aCA+IDBcclxuICAgICAgKSB7XHJcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50YXhCcmVha2Rvd24udGF4TGluZXMuZm9yRWFjaCgodGF4TGluZTogeyBpdGVtTGluZUlkOiB7IHRvU3RyaW5nOiAoKSA9PiBhbnk7IH07IFZBVDogYW55OyBWQVRDb2RlOiBhbnk7IH0pID0+IHtcclxuICAgICAgICAgIGlmIChwcm9kdWN0Lml0ZW1MaW5lSWQgJiYgcHJvZHVjdC5pdGVtTGluZUlkID09PSB0YXhMaW5lLml0ZW1MaW5lSWQudG9TdHJpbmcoKSkge1xyXG4gICAgICAgICAgICBwLnNlbGVjdGVkVkFUID0gdGF4TGluZS5WQVQ7XHJcbiAgICAgICAgICAgIHAuc2VsZWN0ZWRWQVRDb2RlID0gdGF4TGluZS5WQVRDb2RlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnR5cGUgPT09IFRSQU5TQUNUSU9OX1RZUEUuUkVGVU5EKSB7XHJcbiAgICAgICAgcC50b3RhbCA9IHByb2R1Y3QucmVmdW5kZWRUb3RhbDtcclxuICAgICAgfSBlbHNlIGlmICgodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnR5cGUgPT09IFRSQU5TQUNUSU9OX1RZUEUuU0FMRV9SRUZVTkQgfHwgVFJBTlNBQ1RJT05fVFlQRS5TQUxFX0VYQ0hBTkdFKSAmJiBwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHkgPiAwKSB7XHJcbiAgICAgICAgcC5yZWZ1bmRlZFJlYXNvbkRlc2NyaXB0aW9uID0gcHJvZHVjdC5yZWZ1bmRlZFJlYXNvbkRlc2NyaXB0aW9uO1xyXG4gICAgICAgIHAucmVmdW5kZWRSZWFzb24gPSBwcm9kdWN0LnJlZnVuZGVkUmVhc29uO1xyXG4gICAgICAgIGlmICghcC5yZWZ1bmRlZFJlYXNvbkRlc2NyaXB0aW9uKSB7XHJcbiAgICAgICAgICBwLnJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb24gPSBwLnJlZnVuZGVkUmVhc29uO1xyXG4gICAgICAgIH1cclxuICAgICAgICBwLnJlZnVuZGVkUXVhbnRpdHkgPSBwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHk7XHJcbiAgICAgICAgcC5yZWZ1bmRQcm9tb3Rpb25hbFF1YW50aXR5ID0gcHJvZHVjdC5yZWZ1bmRlZFByb21vdGlvbmFsUXVhbnRpdHk7XHJcbiAgICAgICAgcC5yZWZ1bmRlZFRvdGFsID0gcHJvZHVjdC5yZWZ1bmRlZFRvdGFsO1xyXG4gICAgICAgIHAudG90YWwgLT0gTWF0aC5hYnMocC5yZWZ1bmRlZFRvdGFsKTtcclxuICAgICAgICBwLmlzTGFzdEV4Y2hhbmdlZCA9IHByb2R1Y3QuaXNMYXN0RXhjaGFuZ2VkO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnR5cGUgPT09IFRSQU5TQUNUSU9OX1RZUEUuUkVGVU5EKSB7XHJcbiAgICAgICAgaWYgKHAudG90YWwgPiAwKSB7XHJcbiAgICAgICAgICBwLnRvdGFsICo9IC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgYmFza2V0LnByb2R1Y3RzLnB1c2gocCk7XHJcblxyXG4gICAgfSk7XHJcblxyXG4gICAgYmFza2V0ID0gdGhpcy5nZXRUcmFuc2FjdGlvbkRpc2NvdW50QW5kVHJhbnNhY3Rpb25Qcm9tb3Rpb25Qb3J0aW9uKGJhc2tldCk7XHJcbiAgICBiYXNrZXQudG90YWwgPSAoYmFza2V0LmJhc2tldFRvdGFsIHx8IDApICsgdGhpcy5nZXRUb3RhbERpc2NvdW50V2l0aFRyYW5zYWN0aW9uRGlzY291bnRzQW5kUHJvbW90aW9ucyhiYXNrZXQpO1xyXG4gICAgaWYgKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC50eXBlID09PSBUUkFOU0FDVElPTl9UWVBFLlNBTEVfUkVGVU5EKSB7XHJcbiAgICAgIGJhc2tldC5xdWFudGl0eSA9IHRoaXMuZ2V0UmVmdW5kZWRUb3RhbFdpdGhRdWFudGl0eShiYXNrZXQpO1xyXG4gICAgfVxyXG4gICAgQXBwTG9nZ2VyU2VydmljZS5sb2dJbmZvKHRoaXMuY2xhc3NOYW1lLCBcImdldEJhc2tldERldGFpbHNcIiwgXCJCYXNrZXQgY3JlYXRlZCBzdWNjZXNzZnVsbHlcIiwgYmFza2V0KVxyXG4gICAgcmV0dXJuIGJhc2tldDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldHMgYmFza2V0IGRldGFpbHNcclxuICAgKiBAcmV0dXJucyByZWZ1bmQgYmFza2V0IGRldGFpbHNcclxuICAgKi9cclxuICAvLyBnZXRSZWZ1bmRCYXNrZXREZXRhaWxzKCk6IEJhc2tldCB7XHJcbiAgLy8gICBsZXQgYmFza2V0OiBCYXNrZXQgPSB7XHJcbiAgLy8gICAgIHN1YnNpZGlhcnlJZCA6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5zdWJzaWRpYXJ5SWQsXHJcbiAgLy8gICAgIHRyYW5zYWN0aW9uRGlzY291bnQ6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25EaXNjb3VudCxcclxuICAvLyAgICAgdHJhbnNhY3Rpb25Qcm9tb3Rpb246IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb24sXHJcbiAgLy8gICAgIHRyYW5zYWN0aW9uSWQ6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC50cmFuc2FjdGlvbklkLFxyXG4gIC8vICAgICB0b3RhbDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuYmFza2V0VG90YWwsXHJcbiAgLy8gICAgIGJhc2tldFRvdGFsOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5iYXNrZXRUb3RhbCxcclxuICAvLyAgICAgZGlzY291bnRUb3RhbDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuZGlzY291bnRUb3RhbCxcclxuICAvLyAgICAgc2FsZVRvdGFsOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5zYWxlVG90YWwsXHJcbiAgLy8gICAgIHF1YW50aXR5OiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS50b3RhbEl0ZW1zLFxyXG4gIC8vICAgICBwcm9kdWN0czogW10sXHJcbiAgLy8gICAgIGJhc2VDdXJyZW5jeTogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2VDdXJyZW5jeSxcclxuICAvLyAgICAgY3VzdG9tZXI6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXN0b21lcixcclxuICAvLyAgIH07XHJcblxyXG4gIC8vICAgYmFza2V0LnByb2R1Y3RzID0gW10gYXMgUHJvZHVjdFtdO1xyXG4gIC8vICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5wcm9kdWN0cy5mb3JFYWNoKChwcm9kdWN0OiB7IFNLVTogYW55OyBiYXJDb2RlOiBhbnk7IGJhcmNvZGVzOiBhbnk7IGRlc2NyaXB0aW9uOiBhbnk7IGltYWdlVXJsczogYW55OyB0b3RhbExpbmVQcmljZTogYW55OyBpdGVtTGluZUlkOiBhbnk7IGV4Y2x1ZGVQcm9tb3Rpb246IGFueTsgcHJpY2U6IG51bWJlcjsgcXVhbnRpdHk6IGFueTsgc2VsZWN0ZWRSUlBQcmljZTogYW55OyBmdWxsZmlsbWVudElkOiBhbnk7IGZ1bGxmaWxtZW50TG9jYXRpb25OYW1lOiBhbnk7IGRlbGl2ZXJ5R3JvdXA6IHN0cmluZzsgbGVhZFRpbWU6IGFueTsgZGVsaXZlcnlNZXRob2Q6IGFueTsgZ2lmdENhcmQ6IGFueTsgZ2lmdENhcmRFeHBpcnlEYXRlOiBhbnk7IGdpZnRDYXJkTnVtYmVySXNzdWVkOiBhbnk7IGdpZnRDYXJkUmVjaXBpZW50RW1haWw6IGFueTsgZ2lmdENhcmRSZWNpcGllbnROYW1lOiBhbnk7IGl0ZW1EaXNjb3VudHM6IGFueTsgcmVmdW5kZWRQcm9tb3Rpb25hbFF1YW50aXR5OiBhbnk7IHJlZnVuZGVkUXVhbnRpdHk6IG51bWJlcjsgcmVmdW5kZWQ6IGFueTsgaXNMYXN0RXhjaGFuZ2VkOiBhbnk7IGV4Y2hhbmdlOiBhbnk7IHJlZnVuZGVkVG90YWw6IG51bWJlcjsgfSwgaW5kZXg6IGFueSkgPT4ge1xyXG4gIC8vICAgICBjb25zdCBwID0ge30gYXMgUHJvZHVjdDtcclxuICAvLyAgICAgcC5TS1UgPSBwcm9kdWN0LlNLVTtcclxuICAvLyAgICAgcC5iYXJjb2RlID0gcHJvZHVjdC5iYXJDb2RlO1xyXG4gIC8vICAgICBwLmJhcmNvZGVzID0gcHJvZHVjdC5iYXJjb2RlcztcclxuXHJcbiAgLy8gICAgIHAuZGVzY3JpcHRpb24gPSBwcm9kdWN0LmRlc2NyaXB0aW9uO1xyXG4gIC8vICAgICBwLmltYWdlVXJscyA9IHByb2R1Y3QuaW1hZ2VVcmxzO1xyXG4gIC8vICAgICBwLmN1cnJlbmN5ID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2VDdXJyZW5jeTtcclxuICAvLyAgICAgcC50b3RhbExpbmVQcmljZSA9IHByb2R1Y3QudG90YWxMaW5lUHJpY2U7XHJcbiAgLy8gICAgIHAuaXRlbUxpbmVJZCA9IE51bWJlcihwcm9kdWN0Lml0ZW1MaW5lSWQpO1xyXG4gIC8vICAgICBwLmV4Y2x1ZGVQcm9tb3Rpb24gPSBwcm9kdWN0LmV4Y2x1ZGVQcm9tb3Rpb247XHJcblxyXG4gIC8vICAgICBwLnNlbGVjdGVkUHJpY2UgPSBwcm9kdWN0LnByaWNlO1xyXG4gIC8vICAgICBwLnF1YW50aXR5ID0gcHJvZHVjdC5xdWFudGl0eTtcclxuICAvLyAgICAgcC50b3RhbCA9IHByb2R1Y3QudG90YWxMaW5lUHJpY2U7XHJcbiAgLy8gICAgIHAuc2VsZWN0ZWRSUlBQcmljZSA9IHByb2R1Y3Quc2VsZWN0ZWRSUlBQcmljZTtcclxuXHJcbiAgLy8gICAgIHAuZnVsbGZpbG1lbnRJZCA9IHByb2R1Y3QuZnVsbGZpbG1lbnRJZDtcclxuICAvLyAgICAgcC5mdWxsZmlsbWVudExvY2F0aW9uTmFtZSA9IHByb2R1Y3QuZnVsbGZpbG1lbnRMb2NhdGlvbk5hbWU7XHJcbiAgLy8gICAgIHAuZGVsaXZlcnlHcm91cCA9IHByb2R1Y3QuZGVsaXZlcnlHcm91cCB8fCBcIjFcIjtcclxuICAvLyAgICAgcC5sZWFkVGltZSA9IHByb2R1Y3QubGVhZFRpbWU7XHJcbiAgLy8gICAgIHAuZGVsaXZlcnlNZXRob2QgPSBwcm9kdWN0LmRlbGl2ZXJ5TWV0aG9kIHx8IERFTElWRVJZX01FVEhPRFMuQ09MTEVDVF9GUk9NX1NUT1JFLnRvU3RyaW5nKCk7XHJcblxyXG4gIC8vICAgICBwLmdpZnRDYXJkID0gcHJvZHVjdC5naWZ0Q2FyZDtcclxuICAvLyAgICAgcC5naWZ0Q2FyZEV4cGlyeURhdGUgPSBwcm9kdWN0LmdpZnRDYXJkRXhwaXJ5RGF0ZTtcclxuICAvLyAgICAgcC5naWZ0Q2FyZE51bWJlcklzc3VlZCA9IHByb2R1Y3QuZ2lmdENhcmROdW1iZXJJc3N1ZWQ7XHJcbiAgLy8gICAgIHAuZ2lmdENhcmRSZWNpcGllbnRFbWFpbCA9IHByb2R1Y3QuZ2lmdENhcmRSZWNpcGllbnRFbWFpbDtcclxuICAvLyAgICAgcC5naWZ0Q2FyZFJlY2lwaWVudE5hbWUgPSBwcm9kdWN0LmdpZnRDYXJkUmVjaXBpZW50TmFtZTtcclxuICAgICAgXHJcbiAgICAgIFxyXG4gIC8vICAgICBpZihwLmZ1bGxmaWxtZW50SWQgIT0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnN0b3JlSWQpXHJcbiAgLy8gICAgIHtcclxuICAvLyAgICAgICBwLmlzV2ViT3JkZXIgPSB0cnVlO1xyXG4gIC8vICAgICB9XHJcbiAgICAgIFxyXG4gIC8vICAgICBpZiAocHJvZHVjdC5pdGVtRGlzY291bnRzKSB7XHJcbiAgLy8gICAgICAgcC5pdGVtRGlzY291bnRzID0gcHJvZHVjdC5pdGVtRGlzY291bnRzIGFzIEl0ZW1EaXNjb3VudDtcclxuICAvLyAgICAgfVxyXG5cclxuICAvLyAgICAgLy8gaWYoIXAuaXRlbURpc2NvdW50cyl7XHJcbiAgLy8gICAgIC8vICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgcC5pdGVtRGlzY291bnRzKTtcclxuXHJcbiAgLy8gICAgIC8vICAgdGhpcy5iYXNrZXRTZXJ2aWNlLnRyYW5zYWN0aW9uRGlzY291bnRBbmRQcm9tb3Rpb25Qcm9kdWN0b3J0aW9uQ2FsY3VsYXRpb24oYmFza2V0KTtcclxuICAvLyAgICAgLy8gfVxyXG4gIC8vICAgICBwLnJlZnVuZFByb21vdGlvbmFsUXVhbnRpdHkgPSBwcm9kdWN0LnJlZnVuZGVkUHJvbW90aW9uYWxRdWFudGl0eSA/IHByb2R1Y3QucmVmdW5kZWRQcm9tb3Rpb25hbFF1YW50aXR5IDogMDtcclxuXHJcbiAgLy8gICAgIGlmIChwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHkpIHtcclxuICAvLyAgICAgICBwLnF1YW50aXR5ID0gcC5xdWFudGl0eSAtIHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eTtcclxuICAvLyAgICAgICBwLnRvdGFsTGluZVByaWNlID0gKHAucXVhbnRpdHkgKiBwcm9kdWN0LnByaWNlKTtcclxuICAvLyAgICAgICBwLnRvdGFsID0gcC50b3RhbExpbmVQcmljZTtcclxuICAvLyAgICAgICAvLyBwLnJlZnVuZFByb21vdGlvbmFsUXVhbnRpdHkgPSBwcm9kdWN0LnJlZnVuZGVkUHJvbW90aW9uYWxRdWFudGl0eTtcclxuICAvLyAgICAgICBwLnJlZnVuZGVkID0gcHJvZHVjdC5yZWZ1bmRlZDtcclxuICAvLyAgICAgICBwLmlzTGFzdEV4Y2hhbmdlZCA9IHByb2R1Y3QuaXNMYXN0RXhjaGFuZ2VkO1xyXG4gIC8vICAgICB9XHJcbiAgLy8gICAgIGlmIChwcm9kdWN0LmV4Y2hhbmdlKSB7XHJcbiAgLy8gICAgICAgcC5leGNoYW5nZSA9IHByb2R1Y3QuZXhjaGFuZ2U7XHJcbiAgLy8gICAgIH1cclxuXHJcbiAgLy8gICAgIGlmIChcclxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudCAmJlxyXG4gIC8vICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50Lmxlbmd0aCA+IDBcclxuICAvLyAgICAgKSB7XHJcblxyXG4gIC8vICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50LmZvckVhY2goKGxpbmVEaXNjb3VudDogeyBpdGVtTGluZUlkOiB7IHRvU3RyaW5nOiAoKSA9PiBhbnk7IH07IGRpc2NvdW50ZWRMaW5lUHJpY2U6IGFueTsgfSkgPT4ge1xyXG5cclxuICAvLyAgICAgICAgIGlmIChwcm9kdWN0Lml0ZW1MaW5lSWQgPT09IGxpbmVEaXNjb3VudC5pdGVtTGluZUlkLnRvU3RyaW5nKCkgJiYgcHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5ID4gMCkge1xyXG4gIC8vICAgICAgICAgICBwLmxpbmVEaXNjb3VudCA9IE9iamVjdC5hc3NpZ24oe30sIGxpbmVEaXNjb3VudCk7XHJcbiAgLy8gICAgICAgICAgIHAubGluZURpc2NvdW50LmRpc2NvdW50ZWRMaW5lUHJpY2UgPSBwLmxpbmVEaXNjb3VudC51bml0UHJpY2UgKiBwLnF1YW50aXR5XHJcbiAgLy8gICAgICAgICAgIHAubGluZURpc2NvdW50LmRpc2NvdW50QW1vdW50ID0gcC50b3RhbCAtIHAubGluZURpc2NvdW50LmRpc2NvdW50ZWRMaW5lUHJpY2VcclxuICAvLyAgICAgICAgICAgcC50b3RhbCA9IHAubGluZURpc2NvdW50LmRpc2NvdW50ZWRMaW5lUHJpY2U7XHJcbiAgLy8gICAgICAgICB9IGVsc2UgaWYgKHByb2R1Y3QuaXRlbUxpbmVJZCA9PT0gbGluZURpc2NvdW50Lml0ZW1MaW5lSWQudG9TdHJpbmcoKSkge1xyXG4gIC8vICAgICAgICAgICBwLmxpbmVEaXNjb3VudCA9IGxpbmVEaXNjb3VudDtcclxuICAvLyAgICAgICAgICAgcC50b3RhbCA9IGxpbmVEaXNjb3VudC5kaXNjb3VudGVkTGluZVByaWNlXHJcbiAgLy8gICAgICAgICB9XHJcbiAgLy8gICAgICAgfSk7XHJcbiAgLy8gICAgIH1cclxuXHJcbiAgLy8gICAgIGlmIChcclxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb24gJiZcclxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb24ubGVuZ3RoID4gMFxyXG4gIC8vICAgICApIHtcclxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb24uZm9yRWFjaCgobGluZVByb21vdGlvbjogeyBpdGVtTGluZUlkOiB7IHRvU3RyaW5nOiAoKSA9PiBhbnk7IH07IHJlZnVuZGVkOiBhbnk7IH0pID0+IHtcclxuICAvLyAgICAgICAgIGlmIChwcm9kdWN0Lml0ZW1MaW5lSWQgPT09IGxpbmVQcm9tb3Rpb24uaXRlbUxpbmVJZC50b1N0cmluZygpICYmICFsaW5lUHJvbW90aW9uLnJlZnVuZGVkKSB7XHJcbiAgLy8gICAgICAgICAgIHAubGluZVByb21vdGlvbnMgPSBsaW5lUHJvbW90aW9uO1xyXG4gIC8vICAgICAgICAgICBwLnRvdGFsID0gcC5saW5lUHJvbW90aW9ucy5wcm9tb3Rpb25MaW5lUHJpY2U7XHJcbiAgLy8gICAgICAgICAgIHAudG90YWwgPSBwLnRvdGFsIC0gKHByb2R1Y3QucmVmdW5kZWRUb3RhbCA/IE1hdGguYWJzKHByb2R1Y3QucmVmdW5kZWRUb3RhbCkgOiAwKTtcclxuICAvLyAgICAgICAgIH1cclxuICAvLyAgICAgICB9KTtcclxuICAvLyAgICAgfVxyXG5cclxuICAvLyAgICAgcC5yZWZ1bmRlZFF1YW50aXR5ID0gMDtcclxuICAvLyAgICAgcC5yZWZ1bmRlZFRvdGFsID0gMDtcclxuXHJcbiAgLy8gICAgIGlmIChcclxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRheEJyZWFrZG93biAmJlxyXG4gIC8vICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudGF4QnJlYWtkb3duLnRheExpbmVzLmxlbmd0aCA+IDBcclxuICAvLyAgICAgKSB7XHJcbiAgLy8gICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50YXhCcmVha2Rvd24udGF4TGluZXMuZm9yRWFjaCgodGF4TGluZTogeyBpdGVtTGluZUlkOiB7IHRvU3RyaW5nOiAoKSA9PiBhbnk7IH07IFZBVDogYW55OyBWQVRDb2RlOiBhbnk7IH0pID0+IHtcclxuICAvLyAgICAgICAgIGlmIChwcm9kdWN0Lml0ZW1MaW5lSWQgPT09IHRheExpbmUuaXRlbUxpbmVJZC50b1N0cmluZygpKSB7XHJcbiAgLy8gICAgICAgICAgIHAuc2VsZWN0ZWRWQVQgPSB0YXhMaW5lLlZBVDtcclxuICAvLyAgICAgICAgICAgcC5zZWxlY3RlZFZBVENvZGUgPSB0YXhMaW5lLlZBVENvZGU7XHJcbiAgLy8gICAgICAgICB9XHJcbiAgLy8gICAgICAgfSk7XHJcbiAgLy8gICAgIH1cclxuXHJcbiAgLy8gICAgIGlmIChwLnF1YW50aXR5ID4gMCkge1xyXG4gIC8vICAgICAgIGJhc2tldC5wcm9kdWN0cy5wdXNoKHApO1xyXG4gIC8vICAgICB9XHJcbiAgLy8gICB9KTtcclxuICAvLyAgIC8vIHByb2R1Y3QuaXRlbURpc2NvdW50c1xyXG4gIC8vICAgaWYgKCFiYXNrZXQucHJvZHVjdHNbMF0uaGFzT3duUHJvcGVydHkoJ2l0ZW1EaXNjb3VudHMnKSkge1xyXG4gIC8vICAgICBiYXNrZXQgPSB0aGlzLmdldFRyYW5zYWN0aW9uRGlzY291bnRBbmRUcmFuc2FjdGlvblByb21vdGlvblBvcnRpb24oYmFza2V0KTtcclxuXHJcbiAgLy8gICB9XHJcblxyXG4gIC8vICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJlYmFza2V0IDogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIgIDpuZXcgY3JlYXRlZCByZWZ1bmRlZCBiYXNrZXRcIiwgSlNPTi5zdHJpbmdpZnkoYmFza2V0KSlcclxuICAvLyAgIGJhc2tldC5xdWFudGl0eSA9IGJhc2tldC5wcm9kdWN0cy5yZWR1Y2UoXHJcbiAgLy8gICAgIChuOiBhbnksIHsgcXVhbnRpdHkgfTogYW55KSA9PiBuICsgcXVhbnRpdHksXHJcbiAgLy8gICAgIDBcclxuICAvLyAgICk7XHJcbiAgLy8gICBiYXNrZXQudG90YWwgPSB0aGlzLmdldFRvdGFsV2l0aExpbmVEaXNjb3VudEFuZExpbmVQcm9tb3Rpb25BcHBsaWVkKGJhc2tldCk7XHJcbiAgLy8gICBiYXNrZXQuYmFza2V0VG90YWwgPSBiYXNrZXQudG90YWw7XHJcbiAgLy8gICBiYXNrZXQuYmFza2V0VG90YWwgPSBiYXNrZXQuYmFza2V0VG90YWwgLSB0aGlzLmdldFRvdGFsRGlzY291bnRXaXRoVHJhbnNhY3Rpb25EaXNjb3VudHNBbmRQcm9tb3Rpb25zKGJhc2tldCk7XHJcbiAgLy8gICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcclxuICAvLyAgICAgXCJlYmFza2V0IDogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIgOiB1cGRhdGUgQmFza2V0IFRvdGFsOiBhZnRlciBwcm9tb3Rpb24gOmJhc2tldFRvdGFsXCIsXHJcbiAgLy8gICAgIGJhc2tldC5iYXNrZXRUb3RhbFxyXG4gIC8vICAgKTtcclxuXHJcbiAgLy8gICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcclxuICAvLyAgICAgXCJlOmJhc2tldCA6VHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIgOiBiYXNrZXREZXRhaWxzIHVwZGF0ZWQgdmFsdWVzXCIsXHJcbiAgLy8gICAgIEpTT04uc3RyaW5naWZ5KGJhc2tldClcclxuICAvLyAgICk7XHJcbiAgLy8gICByZXR1cm4gYmFza2V0O1xyXG4gIC8vIH1cclxuXHJcblxyXG4gIGdldFRyYW5zYWN0aW9uRGlzY291bnRBbmRUcmFuc2FjdGlvblByb21vdGlvblBvcnRpb24oYmFza2V0OmFueSkge1xyXG4gICAgaWYgKFxyXG4gICAgICBiYXNrZXQudHJhbnNhY3Rpb25EaXNjb3VudCAmJlxyXG4gICAgICBiYXNrZXQudHJhbnNhY3Rpb25EaXNjb3VudC5sZW5ndGggPiAwXHJcbiAgICApIHtcclxuICAgICAgYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQuZm9yRWFjaCgoZGlzY291bnQ6IHsgaXRlbUxpbmVJZHM6IGFueTsgfSkgPT4ge1xyXG4gICAgICAgIGlmICghZGlzY291bnQuaXRlbUxpbmVJZHMpIHtcclxuICAgICAgICAgIGRpc2NvdW50Lml0ZW1MaW5lSWRzID0gYmFza2V0LnByb2R1Y3RzLm1hcCgocHJvZHVjdDogeyBpdGVtTGluZUlkOiBhbnk7IH0pID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHByb2R1Y3QuaXRlbUxpbmVJZFxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJhc2tldCA9IHRoaXMuYmFza2V0U2VydmljZS50cmFuc2FjdGlvbkRpc2NvdW50UHJvZHVjdFBvcnRpb25DYWxjKGJhc2tldCwgZGlzY291bnQpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIGlmIChcclxuICAgICAgYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uICYmXHJcbiAgICAgIGJhc2tldC50cmFuc2FjdGlvblByb21vdGlvbi5sZW5ndGggPiAwXHJcbiAgICApIHtcclxuICAgICAgYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uLmZvckVhY2goKHRQcm9tb3Rpb246IHsgaXRlbUxpbmVJZHM6IGFueTsgfSkgPT4ge1xyXG4gICAgICAgIGlmICghdFByb21vdGlvbi5pdGVtTGluZUlkcykge1xyXG4gICAgICAgICAgY29uc3QgZmlsdGVyZWREYXRhID0gYmFza2V0LnByb2R1Y3RzLmZpbHRlcihcclxuICAgICAgICAgICAgKGl0ZW06IHsgZXhjbHVkZVByb21vdGlvbjogYm9vbGVhbjsgfSkgPT4ge1xyXG4gICAgICAgICAgICAgIHJldHVybiBpdGVtLmV4Y2x1ZGVQcm9tb3Rpb24gPT09IGZhbHNlO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICB0UHJvbW90aW9uLml0ZW1MaW5lSWRzID1cclxuICAgICAgICAgICAgZmlsdGVyZWREYXRhLm1hcCgocHJvZHVjdDogeyBpdGVtTGluZUlkOiBhbnk7IH0pID0+IHtcclxuICAgICAgICAgICAgICByZXR1cm4gcHJvZHVjdC5pdGVtTGluZUlkXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBiYXNrZXQgPSB0aGlzLmJhc2tldFNlcnZpY2UudHJhbnNhY3Rpb25Qcm9tb3Rpb25Qcm9kdWN0UG9ydGlvbkNhbGMoYmFza2V0LCB0UHJvbW90aW9uKTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGJhc2tldDtcclxuICB9XHJcblxyXG5cclxuICBnZXRUb3RhbERpc2NvdW50V2l0aFRyYW5zYWN0aW9uRGlzY291bnRzQW5kUHJvbW90aW9ucyhiYXNrZXREZXRhaWxzOiBhbnkpIHtcclxuXHJcbiAgICBsZXQgZGlzY291bnRUb3RhbCA9IDA7XHJcbiAgICBpZiAoXHJcbiAgICAgIGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25Qcm9tb3Rpb24gJiZcclxuICAgICAgYmFza2V0RGV0YWlscy50cmFuc2FjdGlvblByb21vdGlvbi5sZW5ndGggPiAwXHJcbiAgICApIHtcclxuICAgICAgZGlzY291bnRUb3RhbCArPSBiYXNrZXREZXRhaWxzLnRyYW5zYWN0aW9uUHJvbW90aW9uLnJlZHVjZShcclxuICAgICAgICAobjogYW55LCB7IHByb21vdGlvbkFtb3VudCB9OiBhbnkpID0+IG4gKyBwcm9tb3Rpb25BbW91bnQsXHJcbiAgICAgICAgMFxyXG4gICAgICApO1xyXG4gICAgfVxyXG4gICAgaWYgKFxyXG4gICAgICBiYXNrZXREZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQgJiZcclxuICAgICAgYmFza2V0RGV0YWlscy50cmFuc2FjdGlvbkRpc2NvdW50Lmxlbmd0aCA+IDBcclxuICAgICkge1xyXG5cclxuICAgICAgZGlzY291bnRUb3RhbCArPSBiYXNrZXREZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQucmVkdWNlKFxyXG4gICAgICAgIChuOiBhbnksIHsgZGlzY291bnRBbW91bnQgfTogYW55KSA9PiBuICsgZGlzY291bnRBbW91bnQsXHJcbiAgICAgICAgMFxyXG4gICAgICApO1xyXG5cclxuXHJcbiAgICB9XHJcbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcImdldFRvdGFsRGlzY291bnRXaXRoVHJhbnNhY3Rpb25EaXNjb3VudHNBbmRQcm9tb3Rpb25zXCIsIFwiVHJhbnNhY3Rpb24gZGlzY291bnQgVG90YWw6XCIsIGRpc2NvdW50VG90YWwpO1xyXG5cclxuICAgIHJldHVybiBkaXNjb3VudFRvdGFsO1xyXG4gIH1cclxuXHJcblxyXG4gIGFwcGVuZEN1cnJlbmN5U3ltYm9sKGN1cnJlbmN5OiBudW1iZXIsIHZhbHVlOiBudW1iZXIpIHtcclxuICAgIC8vICB2YWx1ZT10aGlzLmRlY2ltYWxwaXBlLnRyYW5zZm9ybSh2YWx1ZSwnMS4yJyk7XHJcbiAgICBpZiAodmFsdWUgPj0gMCkge1xyXG4gICAgICBjb25zdCByZXR1cm52YWwgPSBjdXJyZW5jeSArIHZhbHVlO1xyXG4gICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcImFwcGVuZEN1cnJlbmN5U3ltYm9sXCIsIFwiYWRkIGN1cnJlbmN5IHdpdGggdmFsdWVcIiwgcmV0dXJudmFsKTtcclxuICAgICAgcmV0dXJuIHJldHVybnZhbDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IHJldHVybnZhbCA9IFwiLVwiICsgKGN1cnJlbmN5ICsgdmFsdWUgKiAtMSk7XHJcbiAgICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwiYXBwZW5kQ3VycmVuY3lTeW1ib2xcIiwgXCJyZXR1cm5WYWxcIiwgcmV0dXJudmFsKTtcclxuICAgICAgcmV0dXJuIHJldHVybnZhbDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIC8qKlxyXG4gIC8vICAqIFVwZGF0ZXMgdG90YWwgcmVmdW5kXHJcbiAgLy8gICogQHJldHVybnMgdG90YWwgcmVmdW5kXHJcbiAgLy8gICovXHJcbiAgLy8gdXBkYXRlVG90YWxSZWZ1bmQoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gIC8vICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5wcm9kdWN0cy5mb3JFYWNoKChwcm9kdWN0KSA9PiB7XHJcbiAgLy8gICAgIHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eSA9IHByb2R1Y3QucXVhbnRpdHk7XHJcbiAgLy8gICAgIHByb2R1Y3QucmVmdW5kZWRUb3RhbCA9IHByb2R1Y3QudG90YWxMaW5lUHJpY2UgKiAtMTtcclxuICAvLyAgICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXHJcbiAgLy8gICAgICAgXCJlYmFza2V0OiBUcmFuc2FjdGlvbiBwcmljZSBvdmVycmlkZSA6XCIsXHJcbiAgLy8gICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnRcclxuICAvLyAgICAgKTtcclxuXHJcbiAgLy8gICAgIGlmIChcclxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb24gJiZcclxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb24ubGVuZ3RoID4gMFxyXG4gIC8vICAgICApIHtcclxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb24uZm9yRWFjaCgobGluZVByb21vdGlvbikgPT4ge1xyXG4gIC8vICAgICAgICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXHJcbiAgLy8gICAgICAgICAgIFwiUHJvbW90aW9uOiBiYXNrZXQgbGluZVByb21vdGlvbiA6IFwiLFxyXG4gIC8vICAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb25cclxuICAvLyAgICAgICAgICk7XHJcbiAgLy8gICAgICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcclxuICAvLyAgICAgICAgICAgXCJsaW5lUHJvbW90aW9uLml0ZW1MaW5lSWQudG9TdHJpbmcoKSA6IFwiLFxyXG4gIC8vICAgICAgICAgICBsaW5lUHJvbW90aW9uLml0ZW1MaW5lSWQudG9TdHJpbmcoKVxyXG4gIC8vICAgICAgICAgKTtcclxuICAvLyAgICAgICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFxyXG4gIC8vICAgICAgICAgICBcImNvbmRpdGlvbiA6IFwiICtcclxuICAvLyAgICAgICAgICAgKHByb2R1Y3QuaXRlbUxpbmVJZCA9PT0gbGluZVByb21vdGlvbi5pdGVtTGluZUlkLnRvU3RyaW5nKCkpXHJcbiAgLy8gICAgICAgICApO1xyXG5cclxuICAvLyAgICAgICAgIGlmIChwcm9kdWN0Lml0ZW1MaW5lSWQgPT09IGxpbmVQcm9tb3Rpb24uaXRlbUxpbmVJZC50b1N0cmluZygpKSB7XHJcbiAgLy8gICAgICAgICAgIHByb2R1Y3QucmVmdW5kZWRUb3RhbCA9XHJcbiAgLy8gICAgICAgICAgICAgbGluZVByb21vdGlvbi5wcm9tb3Rpb25MaW5lUHJpY2UgKiAtMTtcclxuICAvLyAgICAgICAgIH1cclxuICAvLyAgICAgICB9KTtcclxuICAvLyAgICAgfSBlbHNlXHJcbiAgLy8gICAgICAgaWYgKFxyXG4gIC8vICAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnQgJiZcclxuICAvLyAgICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50Lmxlbmd0aCA+IDBcclxuICAvLyAgICAgICApIHtcclxuICAvLyAgICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50LmZvckVhY2goKGxpbmVEaXNjb3VudCkgPT4ge1xyXG4gIC8vICAgICAgICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcclxuICAvLyAgICAgICAgICAgICBcInByb2R1Y3QuaXRlbUxpbmVJZCA6IFwiICtcclxuICAvLyAgICAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudFxyXG4gIC8vICAgICAgICAgICApO1xyXG4gIC8vICAgICAgICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcclxuICAvLyAgICAgICAgICAgICBcImxpbmVEaXNjb3VudC5pdGVtTGluZUlkLnRvU3RyaW5nKCkgOiBcIiArXHJcbiAgLy8gICAgICAgICAgICAgbGluZURpc2NvdW50Lml0ZW1MaW5lSWQudG9TdHJpbmcoKVxyXG4gIC8vICAgICAgICAgICApO1xyXG4gIC8vICAgICAgICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcclxuICAvLyAgICAgICAgICAgICBcImNvbmRpdGlvbiA6IFwiICtcclxuICAvLyAgICAgICAgICAgICAocHJvZHVjdC5pdGVtTGluZUlkID09PSBsaW5lRGlzY291bnQuaXRlbUxpbmVJZC50b1N0cmluZygpKVxyXG4gIC8vICAgICAgICAgICApO1xyXG5cclxuICAvLyAgICAgICAgICAgaWYgKHByb2R1Y3QuaXRlbUxpbmVJZCA9PT0gbGluZURpc2NvdW50Lml0ZW1MaW5lSWQudG9TdHJpbmcoKSkge1xyXG4gIC8vICAgICAgICAgICAgIHByb2R1Y3QucmVmdW5kZWRUb3RhbCA9IGxpbmVEaXNjb3VudC51bml0UHJpY2UgKiBwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHkgKiAtMTtcclxuICAvLyAgICAgICAgICAgfVxyXG4gIC8vICAgICAgICAgfSk7XHJcbiAgLy8gICAgICAgfVxyXG5cclxuICAvLyAgICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJQcm9kdWN0IGRlc2NyaXB0aW9uIDpcIiArIHByb2R1Y3QuZGVzY3JpcHRpb24pO1xyXG4gIC8vICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcIlByb2R1Y3QgdG90YWwgOlwiICsgcHJvZHVjdC5yZWZ1bmRlZFRvdGFsKTtcclxuICAvLyAgICAgLy8gcHJvZHVjdC5kaXNwbGF5cmVmdW5kZWRhbW91bnQ9dGhpcy5hcHBlbmRDdXJyZW5jeVN5bWJvbChDVVJSRU5DWVt0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFzZUN1cnJlbmN5XSxwcm9kdWN0LnJlZnVuZGVkVG90YWwpO1xyXG4gIC8vICAgICAvLyBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBwcm9kdWN0LmRpc3BsYXlyZWZ1bmRlZGFtb3VudCxcImRpc3BsYXlyZWZ1bmRlZGFtb3VudFwiKTtcclxuICAvLyAgICAgcHJvZHVjdC5yZWZ1bmRlZCA9IHRydWU7XHJcbiAgLy8gICB9KTtcclxuICAvLyAgIGNvbnN0IGJhc2tldHRvdGFsID0gKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsICo9IC0xKTtcclxuICAvLyAgIC8vIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmRpc3BsYXliYXNrZXR0b3RhbD10aGlzLmFwcGVuZEN1cnJlbmN5U3ltYm9sKENVUlJFTkNZW3RoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNlQ3VycmVuY3ldLCBiYXNrZXR0b3RhbCk7XHJcbiAgLy8gICBjb25zdCBzYWxldG90YWwgPSAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuc2FsZVRvdGFsICo9IC0xKTtcclxuICAvLyAgIC8vIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmRpc3BsYXlzYWxldG90YWwgPSB0aGlzLmFwcGVuZEN1cnJlbmN5U3ltYm9sKENVUlJFTkNZW3RoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNlQ3VycmVuY3ldLCBzYWxldG90YWwpO1xyXG4gIC8vICAgKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LlZBVFRvdGFsICo9IC0xKTtcclxuICAvLyAgIHJldHVybiB0aGlzO1xyXG4gIC8vIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2FsZSBUb3RhbFxyXG4gICAqIEBwYXJhbSBiYXNrZXREZXRhaWxzXHJcbiAgICogQHJldHVybnMgU2FsZSBUb3RhbFxyXG4gICAqL1xyXG4gIHVwZGF0ZVNhbGVUb3RhbChiYXNrZXREZXRhaWxzOiB7IHByb2R1Y3RzOiBhbnlbXTsgfSkge1xyXG4gICAgY29uc3Qgc2FsZVRvdGFsID0gYmFza2V0RGV0YWlscy5wcm9kdWN0cy5yZWR1Y2UoXHJcbiAgICAgIChuOiBhbnksIHsgdG90YWxMaW5lUHJpY2UgfTogYW55KSA9PiBuICsgdG90YWxMaW5lUHJpY2UsXHJcbiAgICAgIDBcclxuICAgICk7XHJcbiAgICByZXR1cm4gc2FsZVRvdGFsXHJcbiAgfVxyXG5cclxuICBnZXRUb3RhbFdpdGhMaW5lRGlzY291bnRBbmRMaW5lUHJvbW90aW9uQXBwbGllZChiYXNrZXREZXRhaWxzOiB7IHByb2R1Y3RzOiBhbnk7IH0pOiBudW1iZXIge1xyXG4gICAgbGV0IHNhbGV0b3RhbDogbnVtYmVyID0gMC4wO1xyXG4gICAgZm9yIChsZXQgcHJvZHVjdCBvZiBiYXNrZXREZXRhaWxzLnByb2R1Y3RzKSB7XHJcbiAgICAgIC8vIGlmIChwcm9kdWN0LmxpbmVQcm9tb3Rpb25zKSB7XHJcbiAgICAgIC8vICAgc2FsZXRvdGFsICs9IHByb2R1Y3QubGluZVByb21vdGlvbnMucHJvbW90aW9uTGluZVByaWNlO1xyXG4gICAgICAvLyB9IGVsc2UgaWYgKFxyXG4gICAgICAvLyAgIHByb2R1Y3QubGluZURpc2NvdW50ICYmXHJcbiAgICAgIC8vICAgIXByb2R1Y3QubGluZVByb21vdGlvbnNcclxuICAgICAgLy8gKSB7XHJcbiAgICAgIC8vICAgc2FsZXRvdGFsICs9XHJcbiAgICAgIC8vICAgICBwcm9kdWN0LnF1YW50aXR5ICogTnVtYmVyKHByb2R1Y3QubGluZURpc2NvdW50LnVuaXRQcmljZS50b0ZpeGVkKDIpKTtcclxuICAgICAgLy8gfSBlbHNlIHtcclxuICAgICAgLy8gICBzYWxldG90YWwgKz1cclxuICAgICAgLy8gICAgIHByb2R1Y3QucXVhbnRpdHkgKiBOdW1iZXIocHJvZHVjdC5zZWxlY3RlZFByaWNlLnRvRml4ZWQoMikpO1xyXG4gICAgICAvLyB9XHJcbiAgICAgIHNhbGV0b3RhbCArPSBwcm9kdWN0LnRvdGFsO1xyXG4gICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcImdldFRvdGFsV2l0aExpbmVEaXNjb3VudEFuZExpbmVQcm9tb3Rpb25BcHBsaWVkXCIsXHJcbiAgICAgICAgXCJlLWJhc2tldDp1cGRhdGUgcHJvZHVjdCBUb3RhbDpcIiArIHNhbGV0b3RhbCxcclxuICAgICAgICBwcm9kdWN0XHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gc2FsZXRvdGFsO1xyXG4gIH1cclxuXHJcbiAgZ2V0UmVmdW5kZWRUb3RhbFdpdGhRdWFudGl0eShiYXNrZXREZXRhaWxzOiB7IHByb2R1Y3RzOiBzdHJpbmcgfCBhbnlbXTsgfSk6IG51bWJlciB7XHJcbiAgICBsZXQgcXVhbnRpdHkgPSAwO1xyXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGJhc2tldERldGFpbHMucHJvZHVjdHMubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgIGNvbnN0IHByb2R1Y3Q6IGFueSA9IGJhc2tldERldGFpbHMucHJvZHVjdHNbaW5kZXhdO1xyXG5cclxuICAgICAgaWYgKCFwcm9kdWN0LnJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb24pIHtcclxuXHJcbiAgICAgICAgcXVhbnRpdHkgPSBxdWFudGl0eSArIHByb2R1Y3QucXVhbnRpdHk7XHJcblxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHF1YW50aXR5ID0gcXVhbnRpdHkgKyAocHJvZHVjdC5xdWFudGl0eSAtIHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eSk7XHJcblxyXG4gICAgICAgIC8vIGJhc2tldERldGFpbHMudG90YWwgPSBiYXNrZXREZXRhaWxzLnRvdGFsICsgcHJvZHVjdC5yZWZ1bmRlZFRvdGFsO1xyXG5cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHF1YW50aXR5O1xyXG5cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERpc2NvdW50IFRvdGFsXHJcbiAgICogQHJldHVybnMgRGlzY291bnQgVG90YWxcclxuICAgKi9cclxuICB1cGRhdGVEaXNjb3VudFRvdGFsKCkge1xyXG4gICAgbGV0IHJlZnVuZFRvdGFsID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkucmVmdW5kVG90YWwgPyB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5yZWZ1bmRUb3RhbCA6IDA7XHJcbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0luZm8odGhpcy5jbGFzc05hbWUsIFwidXBkYXRlRGlzY291bnRUb3RhbFwiLCBgcmVmdW5kVG90YWw6ICR7cmVmdW5kVG90YWx9IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5OiAke3RoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5fWApO1xyXG4gICAgY29uc3QgZGlzY291bnRUb3RhbCA9XHJcbiAgICAgIE1hdGguYWJzKFxyXG4gICAgICAgIE1hdGguYWJzKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LnNhbGVUb3RhbCkgLVxyXG4gICAgICAgIChcclxuICAgICAgICAgIE1hdGguYWJzKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsKSArIE1hdGguYWJzKHJlZnVuZFRvdGFsKVxyXG4gICAgICAgIClcclxuICAgICAgKTtcclxuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwidXBkYXRlRGlzY291bnRUb3RhbFwiLCBcImRpc2NvdW50VG90YWxcIiwgZGlzY291bnRUb3RhbClcclxuICAgIHJldHVybiBOdW1iZXIoZGlzY291bnRUb3RhbC50b0ZpeGVkKDIpKTtcclxuICB9XHJcblxyXG4gIHVwZGF0ZVJlYXNvbkNvZGUocmVhc29uQ29kZToge1xyXG4gICAgY29kZTogc3RyaW5nO1xyXG4gICAgbmFtZTogc3RyaW5nO1xyXG4gIH0pOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQucmVhc29uQ29kZSA9IHJlYXNvbkNvZGUuY29kZTtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5yZWFzb25EZXNjcmlwdGlvbiA9IHJlYXNvbkNvZGUubmFtZTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlTWFuYWdlck92ZXJyaWRlKFxyXG4gICAgdXNlcm92ZXJyaWRlOiBVc2VyT3ZlcnJpZGVcclxuICApOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQub3ZlcnJpZGUgPSB1c2Vyb3ZlcnJpZGU7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHVwZGF0ZVVzZXJJRChcclxuICAgIHVzZXJJRDogc3RyaW5nXHJcbiAgKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnVzZXJJZCA9IHVzZXJJRDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlVXNlck5hbWUobmFtZTogYW55KSA6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC51c2VyTmFtZSA9IG5hbWU7XHJcbiAgICByZXR1cm4gdGhpcztcclxuXHJcbiAgfVxyXG4gIFxyXG4gIGFkZEN1c3RvbWVyRGV0YWlscyhjdXN0b21lckRldGFpbDogQ3VzdG9tZXIpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VzdG9tZXIgPSBjdXN0b21lckRldGFpbDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlVGF4QnJlYWtkb3duKGJhc2tldERldGFpbHM6IEJhc2tldCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIC8vIGxldCB0cmFuc2FjdGlvbkRpc2NvdW50VG90YWwgPSAwO1xyXG4gICAgbGV0IHRheEJyZWFrZG93bjogVGF4QnJlYWtkb3duID0ge1xyXG4gICAgICB0YXhMaW5lczogW10sXHJcbiAgICAgIHRvdGFsVGF4YWJsZUFtb3VudDogMCxcclxuICAgIH07XHJcblxyXG5cclxuXHJcbiAgICAvLyBpZiAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50cmFuc2FjdGlvbkRpc2NvdW50ICYmIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25EaXNjb3VudC5sZW5ndGggPiAwKSB7XHJcbiAgICAvLyAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25EaXNjb3VudC5mb3JFYWNoKChkaXNjb3VudCkgPT4ge1xyXG4gICAgLy8gICAgIHRyYW5zYWN0aW9uRGlzY291bnRUb3RhbCArPSBkaXNjb3VudC5kaXNjb3VudEFtb3VudDtcclxuICAgIC8vICAgfSk7XHJcbiAgICAvLyB9XHJcblxyXG4gICAgLy8gaWYgKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb24gJiYgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50cmFuc2FjdGlvblByb21vdGlvbi5sZW5ndGggPiAwKSB7XHJcbiAgICAvLyAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb24uZm9yRWFjaChcclxuICAgIC8vICAgICAocHJvbW90aW9uKSA9PiB7XHJcbiAgICAvLyAgICAgICB0cmFuc2FjdGlvbkRpc2NvdW50VG90YWwgKz0gcHJvbW90aW9uLnByb21vdGlvbkFtb3VudDtcclxuICAgIC8vICAgICB9XHJcbiAgICAvLyAgICk7XHJcbiAgICAvLyB9XHJcblxyXG4gICAgYmFza2V0RGV0YWlscy5wcm9kdWN0cy5mb3JFYWNoKChwcm9kdWN0OiBhbnkpID0+IHtcclxuICAgICAgbGV0IHRheExpbmU6IFRheExpbmUgPSB7XHJcbiAgICAgICAgaXRlbUxpbmVJZDogcHJvZHVjdC5pdGVtTGluZUlkLFxyXG4gICAgICAgIFZBVDogcHJvZHVjdC5zZWxlY3RlZFZBVCA/IHByb2R1Y3Quc2VsZWN0ZWRWQVQgOiAwLFxyXG4gICAgICAgIFZBVENvZGU6IHByb2R1Y3Quc2VsZWN0ZWRWQVRDb2RlLFxyXG4gICAgICAgIHRheExpbmVUb3RhbDogMCxcclxuICAgICAgICB0YXhhYmxlQW1vdW50OiBwcm9kdWN0LnRvdGFsLFxyXG4gICAgICAgIFByZVRheDogMFxyXG4gICAgICB9O1xyXG4gICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0luZm8odGhpcy5jbGFzc05hbWUsIFwidXBkYXRlVGF4QnJlYWtkb3duXCIsIGBpdGVtIGxpbmUgSUQgOiwgJHtwcm9kdWN0Lml0ZW1MaW5lSWR9LFxyXG4gICAgICAgIFwidGF4IGxpbmUgOlwiLCAke3RheExpbmV9YCk7XHJcblxyXG4gICAgICAvLyBzdGVwIDFcclxuICAgICAgLy8gaWYgVHJhbnNhY3Rpb24gRGlzY291bnQgYW5kL29yIHByb21vdGlvbiBhcHBsaWVkLCBmaW5kIG5ldCBzZWxsaW5nIHByaWNlIG9mIGVhY2ggcHJvZHVjdCBhcyB0YXhhYmxlYW1vdW50XHJcbiAgICAgIC8vIGlmICh0cmFuc2FjdGlvbkRpc2NvdW50VG90YWwgPiAwKSB7XHJcbiAgICAgIHByb2R1Y3QgPSB0aGlzLmJhc2tldFNlcnZpY2UudmFsaWRhdGVQcm9kdWN0SXRlbURpc2NvdW50KHByb2R1Y3QpO1xyXG5cclxuICAgICAgY29uc3QgcHJvZHVjdENvbnRyaWJ1dGlvbkluVG90YWwgPVxyXG4gICAgICAgIHByb2R1Y3QuaXRlbURpc2NvdW50cy50cm5EaXNjb3VudHNQb3J0aW9uICtcclxuICAgICAgICBwcm9kdWN0Lml0ZW1EaXNjb3VudHMudHJuUHJvbW90aW9uc1BvcnRpb24gLVxyXG4gICAgICAgIHByb2R1Y3QuaXRlbURpc2NvdW50cy5yZWZ1bmRQb3J0aW9uO1xyXG4gICAgICAvLyAgdHArdGQtcnA7XHJcblxyXG4gICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0luZm8odGhpcy5jbGFzc05hbWUsIFwidXBkYXRlVGF4QnJlYWtkb3duXCIsIGBpdGVtIGxpbmUgSUQgLCAke3Byb2R1Y3QuaXRlbUxpbmVJZH0sXHJcbiAgICAgICAgXCJjb250cmlidXRpb24gOlwiLCAke3Byb2R1Y3RDb250cmlidXRpb25JblRvdGFsfWApO1xyXG4gICAgICAvLyBjYWxjdWxhdGUgbmV0IHNlbGxpbmcgcHJpY2UgYWZ0ZXIgYXBwbHlpbmcgdHJhbnNhY3Rpb24gZGlzY291bnQgYXMgcGVyIHByb2R1Y3QgY29udHJpYnV0aW9uXHJcbiAgICAgIHRheExpbmUudGF4YWJsZUFtb3VudCAtPSBwcm9kdWN0Q29udHJpYnV0aW9uSW5Ub3RhbDtcclxuICAgICAgLy8gfVxyXG5cclxuICAgICAgLy9zdGVwIDIgLSBmaW5kIHByZSB0YXhcclxuICAgICAgdGF4TGluZS5QcmVUYXggPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMigodGF4TGluZS50YXhhYmxlQW1vdW50ICogMTAwKSAvICgxMDAgKyB0YXhMaW5lLlZBVCkpO1xyXG5cclxuICAgICAgLy9zdGVwIDMgLSBVcGRhdGUgdGF4YnJlYWtkb3duXHJcbiAgICAgIHRheEJyZWFrZG93bi50b3RhbFRheGFibGVBbW91bnQgKz0gdGF4TGluZS50YXhhYmxlQW1vdW50O1xyXG4gICAgICB0YXhMaW5lLnRheGFibGVBbW91bnQgPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMih0YXhMaW5lLnRheGFibGVBbW91bnQpO1xyXG4gICAgICBcclxuICAgICAgLy8gc3RlcCA0IC0gdXBkYXRlIHRheCBMaW5lIHRvdGFsXHJcbiAgICAgIHRheExpbmUudGF4TGluZVRvdGFsID0gIHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRheExpbmUudGF4YWJsZUFtb3VudCAtIHRheExpbmUuUHJlVGF4KTtcclxuICAgICAgdGF4QnJlYWtkb3duLnRheExpbmVzLnB1c2godGF4TGluZSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0YXhCcmVha2Rvd24udG90YWxUYXhhYmxlQW1vdW50ID0gdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIodGF4QnJlYWtkb3duLnRvdGFsVGF4YWJsZUFtb3VudCk7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRheEJyZWFrZG93biA9IHRheEJyZWFrZG93bjtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlVG90YWxUYXhTdW1tYXJ5KCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuXHJcbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcInVwZGF0ZVRvdGFsVGF4U3VtbWFyeVwiLCBcIlRvdGFsIFRheCBTdW1tZXJ5IFJlcXVlc3QgOlwiLCB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRheEJyZWFrZG93bik7XHJcblxyXG5cclxuICAgIGxldCB0b3RhbFRheFN1bW1hcnlBcnJheTogVG90YWxUYXhTdW1tYXJ5W10gPSBbXVxyXG4gICAgbGV0IHRvdGFsVGF4U3VtbWFyeUdyb3VwID0gW11cclxuXHJcbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcInVwZGF0ZVRvdGFsVGF4U3VtbWFyeVwiLCBcIlRheCBMaW5lcyBmb3IgVG90YWwgVGF4IFN1bW1lcnkgOlwiLCB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRheEJyZWFrZG93bi50YXhMaW5lcyk7XHJcblxyXG5cclxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudGF4QnJlYWtkb3duLnRheExpbmVzLmZvckVhY2goKGVsZW1lbnQ6IHsgVkFUQ29kZTogYW55OyBWQVQ6IGFueTsgUHJlVGF4OiBhbnk7IHRheExpbmVUb3RhbDogYW55OyB9KSA9PiB7XHJcbiAgICAgIGxldCBUYXhTdW1tYXJ5OiBUb3RhbFRheFN1bW1hcnkgPSB7XHJcbiAgICAgICAgVkFUQ29kZTogXCJcIixcclxuICAgICAgICBWQVQ6IC0xMjM0NSxcclxuICAgICAgICBQcmVUYXhTdW06IDAsXHJcbiAgICAgICAgVGF4U3VtOiAwLFxyXG4gICAgICAgIFRYcmF0ZVN1bTogMFxyXG4gIFxyXG4gICAgICB9O1xyXG4gICAgICAgVGF4U3VtbWFyeS5WQVRDb2RlID0gZWxlbWVudC5WQVRDb2RlO1xyXG4gICAgICAgIFRheFN1bW1hcnkuVkFUID0gZWxlbWVudC5WQVQ7ICAgICAgICBcclxuICAgICAgICBUYXhTdW1tYXJ5LlByZVRheFN1bSA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKGVsZW1lbnQuUHJlVGF4KTtcclxuICAgICAgICBUYXhTdW1tYXJ5LlRheFN1bSA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKGVsZW1lbnQudGF4TGluZVRvdGFsKTtcclxuICAgICAgICBUYXhTdW1tYXJ5LlRYcmF0ZVN1bSA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKFRheFN1bW1hcnkuUHJlVGF4U3VtICsgVGF4U3VtbWFyeS5UYXhTdW0pOyAgICAgIFxyXG4gICAgICAgIHRvdGFsVGF4U3VtbWFyeUFycmF5LnB1c2goVGF4U3VtbWFyeSk7XHJcbiAgICB9KVxyXG5cclxuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwidXBkYXRlVG90YWxUYXhTdW1tYXJ5XCIsIFwiVG90YWwgVGF4IFN1bW1lcnkgIFdpdGhvdXQgR3JvdXBlZCA6IFwiLCB0b3RhbFRheFN1bW1hcnlBcnJheSk7XHJcbiAgICBcclxuICAgIHRvdGFsVGF4U3VtbWFyeUdyb3VwID0gdG90YWxUYXhTdW1tYXJ5QXJyYXkucmVkdWNlKChwcmVwYXJlZEFycmF5OmFueSxjdXJyZW50T2JqKSA9PiB7XHJcblxyXG4gICAgICBsZXQgaW5kID0gcHJlcGFyZWRBcnJheS5maW5kSW5kZXgoKHg6IHsgVkFUOiBhbnk7IH0pID0+IHguVkFUID09PSBjdXJyZW50T2JqLlZBVCk7XHJcbiAgICAgIGlmKGluZCA9PT0gLTEpe1xyXG4gICAgICAgIHByZXBhcmVkQXJyYXkucHVzaChjdXJyZW50T2JqKVxyXG4gICAgICB9ZWxzZSB7XHJcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlZBVENvZGUgPSBjdXJyZW50T2JqLlZBVENvZGU7XHJcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlZBVCA9IGN1cnJlbnRPYmouVkFUO1xyXG4gICAgICAgIHByZXBhcmVkQXJyYXlbaW5kXS5QcmVUYXhTdW0gKz0gY3VycmVudE9iai5QcmVUYXhTdW07XHJcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlRheFN1bSArPSBjdXJyZW50T2JqLlRheFN1bTtcclxuICAgICAgICBwcmVwYXJlZEFycmF5W2luZF0uVFhyYXRlU3VtICs9IGN1cnJlbnRPYmouVFhyYXRlU3VtO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBwcmVwYXJlZEFycmF5O1xyXG4gICAgfSxbXSlcclxuICAgIFxyXG4gICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJ1cGRhdGVUb3RhbFRheFN1bW1hcnlcIiwgXCJUb3RhbCAgVGF4IFN1bW1lciBHcm91cCA6XCIsdG90YWxUYXhTdW1tYXJ5R3JvdXApO1xyXG5cclxuXHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRvdGFsVGF4U3VtbWFyeSA9IHRvdGFsVGF4U3VtbWFyeUdyb3VwO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG5cclxuICB9XHJcblxyXG5cclxuICAvKipcclxuICAgKiBUcmFuc2FjdGlvbklkXHJcbiAgICogQHJldHVybnMgT3JpZ2luYWxUcmFuc2FjdGlvbklkXHJcbiAgICovXHJcbiAgYWRkT3JpZ2luYWxUcmFuc0lkKHRyYW5Eb2M6VHJhbnNhY3Rpb25Eb2N1bWVudCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcclxuICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHlwZSA9PT0gVFJBTlNBQ1RJT05fVFlQRS5SRUZVTkQgfHwgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnR5cGUgPT09IFRSQU5TQUNUSU9OX1RZUEUuU0FMRV9SRUZVTkQgfHwgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnR5cGUgPT09IFRSQU5TQUNUSU9OX1RZUEUuU0FMRV9FWENIQU5HRSkge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQub3JpZ2luYWxUcmFuc0lkID0gdHJhbkRvYy50cmFuc2FjdGlvbklkO1xyXG4gICAgICBpZih0cmFuRG9jLmFwaVJlc3BvbnNlICYmIHRyYW5Eb2MuYXBpUmVzcG9uc2UuaW50ZXJuYWxJZClcclxuICAgICAge1xyXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5vcmlnaW5hbEV4dGVybmFsSWQgPSB0cmFuRG9jLmFwaVJlc3BvbnNlLmludGVybmFsSWQudG9TdHJpbmcoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiB1bnJlZmVyZW5jZWQgUmVmdW5kXHJcbiAgICogQHJldHVybnMgYm9vbGVhbiB2YWx1ZVxyXG4gICAqL1xyXG4gIGFkZFVucmVmZXJlbmNlZFJlZnVuZCgpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XHJcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudW5yZWZlcmVuY2VkUmVmdW5kID0gdHJ1ZTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgZ2V0UmVmdW5kVG90YWwoKSB7XHJcbiAgICBsZXQgdG90YWxSZWZ1bmQgPSAwO1xyXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQucHJvZHVjdHMubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgIGNvbnN0IHByb2R1Y3Q6IFRQcm9kdWN0ID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5wcm9kdWN0c1tpbmRleF07XHJcbiAgICAgIGlmIChwcm9kdWN0LnJlZnVuZGVkVG90YWwpIHtcclxuICAgICAgICB0b3RhbFJlZnVuZCA9IHRvdGFsUmVmdW5kICsgcHJvZHVjdC5yZWZ1bmRlZFRvdGFsO1xyXG4gICAgICB9XHJcbiAgICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwiZ2V0UmVmdW5kVG90YWxcIiwgXCJ0b3RhbFJlZnVuZFwiICwgdG90YWxSZWZ1bmQpXHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG90YWxSZWZ1bmQ7XHJcbiAgfVxyXG5cclxuICBkb2NJZChkb2NJZDogYW55KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xyXG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuaWQgPSBkb2NJZDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxufVxyXG4iXX0=
|
|
1
|
+
import { DELIVERY_METHODS } from "./mapper-library.model";
|
|
2
|
+
import { TRANSACTION_TYPE } from "./mapper-library.model";
|
|
3
|
+
import { BasketService } from "./basket.service";
|
|
4
|
+
import { NumberUtilService } from "./number-util.service";
|
|
5
|
+
import { AppLoggerService } from '@pmcretail/common-services/common/app-logger.service';
|
|
6
|
+
/**
|
|
7
|
+
* Transaction document builder
|
|
8
|
+
*/
|
|
9
|
+
export class TransactionDocumentBuilder {
|
|
10
|
+
constructor(transactionDoc, currencyPipe, basketService) {
|
|
11
|
+
this.currencyPipe = currencyPipe;
|
|
12
|
+
this.basketService = basketService;
|
|
13
|
+
this.className = "TransactionDocumentBuilder";
|
|
14
|
+
this.numberUtilService = new NumberUtilService(currencyPipe);
|
|
15
|
+
this.basketService = new BasketService(this.numberUtilService);
|
|
16
|
+
this.storeInfo = JSON.parse(localStorage.getItem('storeInfo') || '{}');
|
|
17
|
+
if (transactionDoc) {
|
|
18
|
+
this.transactionDocument = transactionDoc;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
this.transactionDocument = {
|
|
22
|
+
transactionId: "",
|
|
23
|
+
offlineTransactionId: "",
|
|
24
|
+
transactionRef: "",
|
|
25
|
+
dateTime: "",
|
|
26
|
+
orgCode: "",
|
|
27
|
+
storeId: "",
|
|
28
|
+
storeNodeId: "",
|
|
29
|
+
storeNodeStructure: "",
|
|
30
|
+
deviceId: "",
|
|
31
|
+
terminalId: "",
|
|
32
|
+
userId: "",
|
|
33
|
+
initiatingModule: "eBasket",
|
|
34
|
+
export: false,
|
|
35
|
+
basket: {},
|
|
36
|
+
basketSummary: {},
|
|
37
|
+
baseCurrency: "",
|
|
38
|
+
type: "",
|
|
39
|
+
operationStatus: "",
|
|
40
|
+
createdAt: "",
|
|
41
|
+
updatedAt: "",
|
|
42
|
+
id: "",
|
|
43
|
+
currentTransactionDetails: {},
|
|
44
|
+
saleTotal: 0,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Transactions ref
|
|
50
|
+
* @returns ref
|
|
51
|
+
*/
|
|
52
|
+
transactionRef() {
|
|
53
|
+
const storeDetails = JSON.parse(localStorage.getItem('storeInfo') || '{}');
|
|
54
|
+
const date = new Date();
|
|
55
|
+
const random = (((1 + Math.random()) * 0x10000) | 0)
|
|
56
|
+
.toString(16)
|
|
57
|
+
.substring(1);
|
|
58
|
+
this.transactionDocument.transactionRef =
|
|
59
|
+
storeDetails.orgCode + storeDetails.storeId + date.toISOString() + random;
|
|
60
|
+
AppLoggerService.logDebug(this.className, "transactionRef", "transaction ref created", this.transactionDocument.transactionRef);
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Transactions id
|
|
65
|
+
* @param transactionID
|
|
66
|
+
* @returns id
|
|
67
|
+
*/
|
|
68
|
+
transactionId(transactionID, isOnline = true) {
|
|
69
|
+
if (isOnline) {
|
|
70
|
+
this.transactionDocument.transactionId = transactionID;
|
|
71
|
+
}
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Transactions id
|
|
76
|
+
* @param transactionID
|
|
77
|
+
* @returns id
|
|
78
|
+
*/
|
|
79
|
+
offlineTransactionId(transactionID, isOnline) {
|
|
80
|
+
if (!isOnline) {
|
|
81
|
+
this.transactionDocument.offlineTransactionId = transactionID;
|
|
82
|
+
}
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* storeNode Id
|
|
87
|
+
* @param storeNodeId
|
|
88
|
+
* @returns id
|
|
89
|
+
*/
|
|
90
|
+
storeNodeId(storeNodeId) {
|
|
91
|
+
this.transactionDocument.storeNodeId = storeNodeId;
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* storeNode structure
|
|
96
|
+
* @param storeNodeStructure
|
|
97
|
+
* @returns id
|
|
98
|
+
*/
|
|
99
|
+
storeNodeStructure(storeNodeStructure) {
|
|
100
|
+
this.transactionDocument.storeNodeStructure = storeNodeStructure;
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Orgs code
|
|
105
|
+
* @param orgCode
|
|
106
|
+
* @returns code
|
|
107
|
+
*/
|
|
108
|
+
orgCode(orgCode) {
|
|
109
|
+
this.transactionDocument.orgCode = orgCode;
|
|
110
|
+
return this;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Stores id
|
|
114
|
+
* @param storeId
|
|
115
|
+
* @returns id
|
|
116
|
+
*/
|
|
117
|
+
storeId(storeId) {
|
|
118
|
+
this.transactionDocument.storeId = storeId;
|
|
119
|
+
return this;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Dates time
|
|
123
|
+
* @returns time
|
|
124
|
+
*/
|
|
125
|
+
dateTime() {
|
|
126
|
+
const date = new Date();
|
|
127
|
+
this.transactionDocument.dateTime = date.toISOString();
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Devices id
|
|
132
|
+
* @param deviceId
|
|
133
|
+
* @returns id
|
|
134
|
+
*/
|
|
135
|
+
deviceId(deviceId) {
|
|
136
|
+
this.transactionDocument.deviceId = deviceId;
|
|
137
|
+
return this;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* terminal id
|
|
141
|
+
* @param terminalId
|
|
142
|
+
* @returns id
|
|
143
|
+
*/
|
|
144
|
+
terminalId(terminalId) {
|
|
145
|
+
this.transactionDocument.terminalId = terminalId;
|
|
146
|
+
return this;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* saleExport
|
|
150
|
+
* @param saleExport
|
|
151
|
+
* @returns id
|
|
152
|
+
*/
|
|
153
|
+
export(saleExport) {
|
|
154
|
+
this.transactionDocument.export = saleExport;
|
|
155
|
+
return this;
|
|
156
|
+
}
|
|
157
|
+
/* customer(): TransactionDocumentBuilder {
|
|
158
|
+
const user = JSON.parse(localStorage.getItem('userDetails'));
|
|
159
|
+
this.transactionDocument.customer = user;
|
|
160
|
+
return this;
|
|
161
|
+
} */
|
|
162
|
+
/**
|
|
163
|
+
* Baskets transaction document builder
|
|
164
|
+
* @param basketDetails
|
|
165
|
+
* @returns basket
|
|
166
|
+
*/
|
|
167
|
+
basket(basketDetails) {
|
|
168
|
+
AppLoggerService.logDebug(this.className, "basket", "basket details update in transaction document", basketDetails);
|
|
169
|
+
this.transactionDocument.subsidiaryId = basketDetails.subsidiaryId || (localStorage.getItem('subsidiaryId') || '');
|
|
170
|
+
this.transactionDocument.basket.products = [];
|
|
171
|
+
this.transactionDocument.basket.lineDiscount = [];
|
|
172
|
+
this.transactionDocument.basket.linePromotion = [];
|
|
173
|
+
this.transactionDocument.basket.transactionPromotion = [];
|
|
174
|
+
basketDetails.products.forEach((product, index) => {
|
|
175
|
+
const p = {};
|
|
176
|
+
p.itemDiscounts = {};
|
|
177
|
+
p.SKU = product.SKU;
|
|
178
|
+
p.excludePromotion = product.excludePromotion;
|
|
179
|
+
p.barCode = product.barcode;
|
|
180
|
+
p.barcodes = product.barcodes;
|
|
181
|
+
p.description = product.description;
|
|
182
|
+
p.itemLineId = product.itemLineId ? product.itemLineId.toString() : "" + (index + 1);
|
|
183
|
+
p.price = product.selectedPrice;
|
|
184
|
+
p.quantity = product.quantity;
|
|
185
|
+
p.totalLinePrice = product.quantity * product.selectedPrice;
|
|
186
|
+
p.imageUrls = product.imageUrls;
|
|
187
|
+
p.selectedRRPPrice = product.selectedRRPPrice;
|
|
188
|
+
//inventory fields
|
|
189
|
+
p.fullfilmentId = product.fullfilmentId ? product.fullfilmentId : this.storeInfo.storeId;
|
|
190
|
+
p.fullfilmentLocationName = product.fullfilmentLocationName;
|
|
191
|
+
p.deliveryGroup = product.deliveryGroup;
|
|
192
|
+
p.leadTime = product.leadTime;
|
|
193
|
+
p.deliveryMethod = product.deliveryMethod;
|
|
194
|
+
p.giftCard = product.giftCard;
|
|
195
|
+
p.giftCardExpiryDate = product.giftCardExpiryDate;
|
|
196
|
+
p.giftCardNumberIssued = product.giftCardNumberIssued;
|
|
197
|
+
p.giftCardRecipientEmail = product.giftCardRecipientEmail;
|
|
198
|
+
p.giftCardRecipientName = product.giftCardRecipientName;
|
|
199
|
+
if (product.refundedQuantity > 0) {
|
|
200
|
+
p.refundedQuantity = product.refundedQuantity;
|
|
201
|
+
p.refundedPromotionalQuantity = product.refundPromotionalQuantity;
|
|
202
|
+
p.refunded = product.refunded;
|
|
203
|
+
p.refundedReasonDescription = product.refundedReasonDescription;
|
|
204
|
+
p.refundedReason = product.refundedReason;
|
|
205
|
+
if (!p.refundedReasonDescription) {
|
|
206
|
+
p.refundedReasonDescription = p.refundedReason;
|
|
207
|
+
}
|
|
208
|
+
p.refundedTotal = product.refundedTotal;
|
|
209
|
+
p.isLastExchanged = product.isLastExchanged;
|
|
210
|
+
}
|
|
211
|
+
if (product.exchange) {
|
|
212
|
+
p.exchange = product.exchange;
|
|
213
|
+
}
|
|
214
|
+
if (product.lineDiscount) {
|
|
215
|
+
p.lineDiscount = product.lineDiscount;
|
|
216
|
+
}
|
|
217
|
+
p.itemDiscounts = product.itemDiscounts;
|
|
218
|
+
this.transactionDocument.basket.products.push(p);
|
|
219
|
+
this.lineDiscount(basketDetails);
|
|
220
|
+
});
|
|
221
|
+
AppLoggerService.logInfo(this.className, "basket", "transactiondocument basket details updated", this.transactionDocument.basket);
|
|
222
|
+
return this;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* current transaction Details Total(New Products)
|
|
226
|
+
* @returns currentTransactionDetails
|
|
227
|
+
*/
|
|
228
|
+
currentTransactionDetails(basket) {
|
|
229
|
+
AppLoggerService.logDebug(this.className, "currentTransactionDetails", "current transaction details for exchanges", basket);
|
|
230
|
+
this.transactionDocument.currentTransactionDetails.products = [];
|
|
231
|
+
this.transactionDocument.currentTransactionDetails.linePromotion = [];
|
|
232
|
+
this.transactionDocument.currentTransactionDetails.lineDiscount = [];
|
|
233
|
+
this.transactionDocument.currentTransactionDetails.transactionDiscount = [];
|
|
234
|
+
this.transactionDocument.currentTransactionDetails.products = basket.products;
|
|
235
|
+
this.transactionDocument.currentTransactionDetails.products = this.transactionDocument.currentTransactionDetails.products.filter((proj) => proj.refundedQuantity != 0);
|
|
236
|
+
this.transactionDocument.currentTransactionDetails.products.forEach((product) => {
|
|
237
|
+
if (product.refundedQuantity) {
|
|
238
|
+
product.quantity = product.refundedQuantity;
|
|
239
|
+
// updating total line price with actual price to be refunded including the refunding qty
|
|
240
|
+
product.totalLinePrice = Math.abs(product.refundedTotal);
|
|
241
|
+
product.total = product.totalLinePrice;
|
|
242
|
+
if (product.quantity === product.refundedQuantity) {
|
|
243
|
+
product.refunded = true;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
//Updating line promotions and line discounts
|
|
247
|
+
if (product.linePromotions && !product.refundedQuantity) {
|
|
248
|
+
this.transactionDocument.currentTransactionDetails.linePromotion.push(product.linePromotions);
|
|
249
|
+
}
|
|
250
|
+
if (product.lineDiscount && !product.refundedQuantity) {
|
|
251
|
+
this.transactionDocument.currentTransactionDetails.lineDiscount.push(product.lineDiscount);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
AppLoggerService.logDebug(this.className, "currentTransactionDetails", "current transaction details after removing old products", this.transactionDocument.currentTransactionDetails.products);
|
|
255
|
+
if (basket.transactionDiscount && basket.transactionDiscount.length > 0) {
|
|
256
|
+
this.transactionDocument.currentTransactionDetails.transactionDiscount.push(...basket.transactionDiscount);
|
|
257
|
+
}
|
|
258
|
+
this.transactionDocument.currentTransactionDetails.basketSummary = {};
|
|
259
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.saleTotal = this.numberUtilService.trimTo2Decimal2(this.updateSaleTotal(this.transactionDocument.currentTransactionDetails));
|
|
260
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.totalItems = basket.quantity;
|
|
261
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.basketTotal = basket.basketTotal;
|
|
262
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.refundTotal = this.updateCurrentTransactionDetailsRefundTotal();
|
|
263
|
+
// For partial refund discount is updatied in total line price so discountTotal will always be zero & in case of exchange discount total is calculated
|
|
264
|
+
if (this.transactionDocument.type === TRANSACTION_TYPE.SALE_EXCHANGE) {
|
|
265
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.discountTotal = this.numberUtilService.trimTo2Decimal2(this.updateCurrentTransactionDetailsDiscountTotal());
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
if (this.transactionDocument.currentTransactionDetails.transactionDiscount && this.transactionDocument.currentTransactionDetails.transactionDiscount.length > 0) {
|
|
269
|
+
let discountTotal = 0;
|
|
270
|
+
this.transactionDocument.currentTransactionDetails.transactionDiscount.forEach((discount) => {
|
|
271
|
+
discountTotal += discount.discountAmount;
|
|
272
|
+
});
|
|
273
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.discountTotal = Math.abs(discountTotal);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.discountTotal = 0;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
AppLoggerService.logInfo(this.className, "currentTransactionDetails", "currentTransactionDetails", this.transactionDocument.currentTransactionDetails);
|
|
280
|
+
return this;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* current transaction Tax Total
|
|
284
|
+
* @returns Tax Total
|
|
285
|
+
*/
|
|
286
|
+
updateCurrentTransactionDetailsTaxBreakdown(basketDetails) {
|
|
287
|
+
let transactionDiscountTotal = 0;
|
|
288
|
+
let taxBreakdown = {
|
|
289
|
+
taxLines: [],
|
|
290
|
+
totalTaxableAmount: 0,
|
|
291
|
+
};
|
|
292
|
+
if (this.transactionDocument.currentTransactionDetails.transactionDiscount && this.transactionDocument.currentTransactionDetails.transactionDiscount.length > 0) {
|
|
293
|
+
this.transactionDocument.currentTransactionDetails.transactionDiscount.forEach((discount) => {
|
|
294
|
+
transactionDiscountTotal += discount.discountAmount;
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
if (this.transactionDocument.currentTransactionDetails.products && this.transactionDocument.currentTransactionDetails.products.length > 0) {
|
|
298
|
+
this.transactionDocument.currentTransactionDetails.products.forEach((product) => {
|
|
299
|
+
let taxLine = {
|
|
300
|
+
itemLineId: product.itemLineId,
|
|
301
|
+
VAT: product.selectedVAT ? product.selectedVAT : 0,
|
|
302
|
+
VATCode: product.selectedVATCode,
|
|
303
|
+
taxLineTotal: 0,
|
|
304
|
+
taxableAmount: product.total,
|
|
305
|
+
PreTax: 0
|
|
306
|
+
};
|
|
307
|
+
AppLoggerService.logInfo(this.className, "updateCurrentTransactionDetailsTaxBreakdown", `item line ID :current transaction Details",
|
|
308
|
+
${product.itemLineId}, tax line : ${taxLine}, basketDetails.basketTotal ${basketDetails.basketTotal}`);
|
|
309
|
+
//step 1
|
|
310
|
+
// if Transaction Discount and/or promotion applied, find net selling price of each product as taxableamount
|
|
311
|
+
//If transaction discount/promotion is applied taxable amount should be deducting transaction promotion and transaction disacount portion
|
|
312
|
+
if (product.refundedQuantity && product.refundedQuantity > 0) {
|
|
313
|
+
taxLine.taxableAmount = -Math.abs(taxLine.taxableAmount - product.itemDiscounts.currentRefundPortion);
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
taxLine.taxableAmount = taxLine.taxableAmount - product.itemDiscounts.trnDiscountsPortion - product.itemDiscounts.trnPromotionsPortion;
|
|
317
|
+
}
|
|
318
|
+
//step 2 - find pre tax
|
|
319
|
+
taxLine.PreTax = this.numberUtilService.trimTo2Decimal2((taxLine.taxableAmount * 100) / (100 + taxLine.VAT));
|
|
320
|
+
//step 3 - Update taxbreakdown
|
|
321
|
+
taxBreakdown.totalTaxableAmount += taxLine.taxableAmount;
|
|
322
|
+
taxLine.taxableAmount = this.numberUtilService.trimTo2Decimal2(taxLine.taxableAmount);
|
|
323
|
+
// step 4 - update tax Line total
|
|
324
|
+
taxLine.taxLineTotal = this.numberUtilService.trimTo2Decimal2(taxLine.taxableAmount - taxLine.PreTax);
|
|
325
|
+
taxBreakdown.taxLines.push(taxLine);
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
taxBreakdown.totalTaxableAmount = this.numberUtilService.trimTo2Decimal2(taxBreakdown.totalTaxableAmount);
|
|
329
|
+
this.transactionDocument.currentTransactionDetails.taxBreakdown = taxBreakdown;
|
|
330
|
+
if (this.transactionDocument.currentTransactionDetails.taxBreakdown && this.transactionDocument.currentTransactionDetails.taxBreakdown.taxLines && this.transactionDocument.currentTransactionDetails.taxBreakdown.taxLines.length > 0) {
|
|
331
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.VATTotal = this.numberUtilService.trimTo2Decimal2(this.transactionDocument.currentTransactionDetails.taxBreakdown.taxLines.reduce((n, { taxLineTotal }) => n + taxLineTotal, 0));
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
this.transactionDocument.currentTransactionDetails.basketSummary.VATTotal = 0.00;
|
|
335
|
+
}
|
|
336
|
+
AppLoggerService.logDebug(this.className, "updateCurrentTransactionDetailsTaxBreakdown", "eBasket:after calculating tax currenttransactionDetails", this.transactionDocument.currentTransactionDetails);
|
|
337
|
+
return this;
|
|
338
|
+
}
|
|
339
|
+
updateCurrentTransactionDetailsTotalTaxSummary() {
|
|
340
|
+
AppLoggerService.logDebug(this.className, "updateCurrentTransactionDetailsTotalTaxSummary", "Total Tax Summery Request :", this.transactionDocument.currentTransactionDetails.taxBreakdown);
|
|
341
|
+
let totalTaxSummaryArray = [];
|
|
342
|
+
let totalTaxSummaryGroup = [];
|
|
343
|
+
this.transactionDocument.currentTransactionDetails.taxBreakdown.taxLines.forEach((element) => {
|
|
344
|
+
let TaxSummary = {
|
|
345
|
+
VATCode: "",
|
|
346
|
+
VAT: -12345,
|
|
347
|
+
PreTaxSum: 0,
|
|
348
|
+
TaxSum: 0,
|
|
349
|
+
TXrateSum: 0
|
|
350
|
+
};
|
|
351
|
+
TaxSummary.VATCode = element.VATCode;
|
|
352
|
+
TaxSummary.VAT = element.VAT;
|
|
353
|
+
TaxSummary.PreTaxSum = this.numberUtilService.trimTo2Decimal2(element.PreTax);
|
|
354
|
+
TaxSummary.TaxSum = this.numberUtilService.trimTo2Decimal2(element.taxLineTotal);
|
|
355
|
+
TaxSummary.TXrateSum = this.numberUtilService.trimTo2Decimal2(TaxSummary.PreTaxSum + TaxSummary.TaxSum);
|
|
356
|
+
totalTaxSummaryArray.push(TaxSummary);
|
|
357
|
+
});
|
|
358
|
+
AppLoggerService.logDebug(this.className, "updateCurrentTransactionDetailsTotalTaxSummary", "Total Tax Summery Without Grouped : ", totalTaxSummaryArray);
|
|
359
|
+
totalTaxSummaryGroup = totalTaxSummaryArray.reduce((preparedArray, currentObj) => {
|
|
360
|
+
let ind = preparedArray.findIndex((x) => x.VAT === currentObj.VAT);
|
|
361
|
+
if (ind === -1) {
|
|
362
|
+
preparedArray.push(currentObj);
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
preparedArray[ind].VATCode = currentObj.VATCode;
|
|
366
|
+
preparedArray[ind].VAT = currentObj.VAT;
|
|
367
|
+
preparedArray[ind].PreTaxSum += currentObj.PreTaxSum;
|
|
368
|
+
preparedArray[ind].TaxSum += currentObj.TaxSum;
|
|
369
|
+
preparedArray[ind].TXrateSum += currentObj.TXrateSum;
|
|
370
|
+
}
|
|
371
|
+
return preparedArray;
|
|
372
|
+
}, []);
|
|
373
|
+
// listOfTags.map(x => unique.filter(a => a.label == x.label && a.color == x.color).length > 0 ? null : unique.push(x));
|
|
374
|
+
AppLoggerService.logDebug(this.className, "updateCurrentTransactionDetailsTotalTaxSummary", "Total Tax Summer Group :", totalTaxSummaryGroup);
|
|
375
|
+
this.transactionDocument.currentTransactionDetails.totalTaxSummary = totalTaxSummaryGroup;
|
|
376
|
+
return this;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* current transaction Disocunt Total
|
|
380
|
+
* @returns Discount Total
|
|
381
|
+
*/
|
|
382
|
+
updateCurrentTransactionDetailsDiscountTotal() {
|
|
383
|
+
let refundTotal = this.transactionDocument.currentTransactionDetails.basketSummary.refundTotal ? this.transactionDocument.currentTransactionDetails.basketSummary.refundTotal : 0;
|
|
384
|
+
AppLoggerService.logDebug(this.className, "updateCurrentTransactionDetailsDiscountTotal", `refundTotal ${refundTotal}, basketTotal ${this.transactionDocument.currentTransactionDetails.basketSummary.basketTotal},saleTotal ${this.transactionDocument.currentTransactionDetails.basketSummary.saleTotal}`);
|
|
385
|
+
const discountTotal = Math.abs(Math.abs(this.transactionDocument.currentTransactionDetails.basketSummary.saleTotal) -
|
|
386
|
+
(Math.abs(this.transactionDocument.currentTransactionDetails.basketSummary.basketTotal) + Math.abs(refundTotal)));
|
|
387
|
+
AppLoggerService.logDebug(this.className, "updateCurrentTransactionDetailsDiscountTotal", "discountTotal", discountTotal);
|
|
388
|
+
return Number(discountTotal.toFixed(2));
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* current transaction Refund Total
|
|
392
|
+
* @returns Refund Total
|
|
393
|
+
*/
|
|
394
|
+
updateCurrentTransactionDetailsRefundTotal() {
|
|
395
|
+
let totalRefund = 0;
|
|
396
|
+
for (let index = 0; index < this.transactionDocument.currentTransactionDetails.products.length; index++) {
|
|
397
|
+
const product = this.transactionDocument.currentTransactionDetails.products[index];
|
|
398
|
+
if (product.refundedTotal) {
|
|
399
|
+
totalRefund = totalRefund + product.refundedTotal;
|
|
400
|
+
}
|
|
401
|
+
AppLoggerService.logDebug(this.className, "updateCurrentTransactionDetailsRefundTotal", "totalRefund for Current TransactionDetails", totalRefund);
|
|
402
|
+
}
|
|
403
|
+
return totalRefund;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Baskets summary
|
|
407
|
+
* @param basketDetails
|
|
408
|
+
* @returns summary
|
|
409
|
+
*/
|
|
410
|
+
basketSummary(basketDetails) {
|
|
411
|
+
this.transactionDocument.basketSummary.basketTotal = this.numberUtilService.trimTo2Decimal(basketDetails.basketTotal);
|
|
412
|
+
this.transactionDocument.basketSummary.saleTotal = this.numberUtilService.trimTo2Decimal2(this.updateSaleTotal(basketDetails));
|
|
413
|
+
this.transactionDocument.basketSummary.refundTotal = this.getRefundTotal();
|
|
414
|
+
if (this.transactionDocument.basket.lineDiscount ||
|
|
415
|
+
this.transactionDocument.basket.linePromotion) {
|
|
416
|
+
this.transactionDocument.basketSummary.discountTotal = this.numberUtilService.trimTo2Decimal2(this.updateDiscountTotal());
|
|
417
|
+
}
|
|
418
|
+
this.transactionDocument.basketSummary.totalItems = basketDetails.quantity;
|
|
419
|
+
if (this.transactionDocument.basket.taxBreakdown) {
|
|
420
|
+
this.transactionDocument.basketSummary.VATTotal = this.numberUtilService.trimTo2Decimal2(this.transactionDocument.basket.taxBreakdown.taxLines.reduce((n, { taxLineTotal }) => n + taxLineTotal, 0));
|
|
421
|
+
}
|
|
422
|
+
else {
|
|
423
|
+
this.transactionDocument.basketSummary.VATTotal = 0.00;
|
|
424
|
+
}
|
|
425
|
+
AppLoggerService.logInfo(this.className, "basketSummary", "basketsummary updated in transaction document: ", this.transactionDocument.basketSummary);
|
|
426
|
+
return this;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Line Discount
|
|
430
|
+
* @param basketDetails
|
|
431
|
+
* @returns line Discount
|
|
432
|
+
*/
|
|
433
|
+
lineDiscount(basketDetails) {
|
|
434
|
+
this.transactionDocument.basket.lineDiscount = [];
|
|
435
|
+
for (let index = 0; index < basketDetails.products.length; index++) {
|
|
436
|
+
const element = basketDetails.products[index];
|
|
437
|
+
if (element.lineDiscount) {
|
|
438
|
+
this.transactionDocument.basket.lineDiscount.push(element.lineDiscount);
|
|
439
|
+
this.transactionDocument.basket.lineDiscount = this.transactionDocument.basket.lineDiscount.reduce((acc, val) => {
|
|
440
|
+
if (!acc.find((el) => el.itemLineId === val.itemLineId)) {
|
|
441
|
+
acc.push(val);
|
|
442
|
+
}
|
|
443
|
+
return acc;
|
|
444
|
+
}, []);
|
|
445
|
+
}
|
|
446
|
+
// AppLoggerService.logInfo(this.className,
|
|
447
|
+
// "e-basket :line discount updated in transaction document",
|
|
448
|
+
// this.transactionDocument.basket.lineDiscount
|
|
449
|
+
// );
|
|
450
|
+
}
|
|
451
|
+
return this;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* exchange
|
|
455
|
+
* @param basketDetails
|
|
456
|
+
* @returns exchange
|
|
457
|
+
*/
|
|
458
|
+
exchange(basketDetails) {
|
|
459
|
+
this.transactionDocument.basket.exchange = basketDetails.exchange && basketDetails.exchange.length > 0 ? [...basketDetails.exchange] : [];
|
|
460
|
+
for (let index = 0; index < basketDetails.products.length; index++) {
|
|
461
|
+
const element = basketDetails.products[index];
|
|
462
|
+
if (element.exchange != undefined) {
|
|
463
|
+
const isPresent = this.transactionDocument.basket.exchange.some((el) => el.exchangeId === element.exchange.exchangeId);
|
|
464
|
+
if (!isPresent) {
|
|
465
|
+
let exchangeItems = [];
|
|
466
|
+
for (let j = 0; j < element.exchange.newItems.length; j++) {
|
|
467
|
+
const item = element.exchange.newItems[j];
|
|
468
|
+
let newItems = { lineItemId: item.itemLineId, Quantity: item.quantity };
|
|
469
|
+
exchangeItems.push(newItems);
|
|
470
|
+
}
|
|
471
|
+
element.exchange.newItems = [...exchangeItems];
|
|
472
|
+
this.transactionDocument.basket.exchange.push(element.exchange);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
AppLoggerService.logDebug(this.className, "exchange", "this.transactionDocument.basket exchange", this.transactionDocument.basket.exchange);
|
|
476
|
+
}
|
|
477
|
+
return this;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* add previous exchange data
|
|
481
|
+
* @param originalTransactionDocument
|
|
482
|
+
* @returns line Promotions
|
|
483
|
+
*/
|
|
484
|
+
addExchangeData(originalTransactionDocument) {
|
|
485
|
+
this.transactionDocument.basket.exchange = originalTransactionDocument.basket.exchange ? [...originalTransactionDocument.basket.exchange] : null;
|
|
486
|
+
return this;
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* line Promotions
|
|
490
|
+
* @param basketDetails
|
|
491
|
+
* @returns line Promotions
|
|
492
|
+
*/
|
|
493
|
+
linePromotion(basketDetails) {
|
|
494
|
+
this.transactionDocument.basket.linePromotion = [];
|
|
495
|
+
for (let index = 0; index < basketDetails.products.length; index++) {
|
|
496
|
+
const element = basketDetails.products[index];
|
|
497
|
+
if (element.linePromotions) {
|
|
498
|
+
this.transactionDocument.basket.linePromotion.push(element.linePromotions);
|
|
499
|
+
this.transactionDocument.basket.linePromotion = this.transactionDocument.basket.linePromotion.reduce((acc, val) => {
|
|
500
|
+
if (!acc.find((el) => el.itemLineId === val.itemLineId)) {
|
|
501
|
+
acc.push(val);
|
|
502
|
+
}
|
|
503
|
+
return acc;
|
|
504
|
+
}, []);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
return this;
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* transaction Promotion
|
|
511
|
+
* @param basketDetails
|
|
512
|
+
* @returns transaction Promotion
|
|
513
|
+
*/
|
|
514
|
+
transactionPromotion(basketDetails) {
|
|
515
|
+
if (basketDetails.transactionPromotion) {
|
|
516
|
+
this.transactionDocument.basket.transactionPromotion =
|
|
517
|
+
basketDetails.transactionPromotion;
|
|
518
|
+
// for (let index = 0; index < basketDetails.TransactionDiscount.length; index++) {
|
|
519
|
+
// this.transactionDocument.basket.transactionPromotion.push(element.linePromotions)
|
|
520
|
+
// this.transactionDocument.basket.transactionPromotion = this.transactionDocument.basket.linePromotions.reduce((acc, val) => {
|
|
521
|
+
// if (!acc.find(el => el.itemLineId === val.itemLineId)) {
|
|
522
|
+
// acc.push(val);
|
|
523
|
+
// }
|
|
524
|
+
// return acc;
|
|
525
|
+
// }, []);
|
|
526
|
+
// }
|
|
527
|
+
AppLoggerService.logDebug(this.className, "transactionPromotion", "this.transactionDocument.basket.transactionPromotion", this.transactionDocument.basket.transactionPromotion);
|
|
528
|
+
}
|
|
529
|
+
return this;
|
|
530
|
+
}
|
|
531
|
+
transactionDiscount(basketDetails) {
|
|
532
|
+
if (basketDetails.transactionDiscount) {
|
|
533
|
+
this.transactionDocument.basket.transactionDiscount =
|
|
534
|
+
basketDetails.transactionDiscount;
|
|
535
|
+
AppLoggerService.logDebug(this.className, "transactionDiscount", "transaction Discount", this.transactionDocument.basket.transactionDiscount);
|
|
536
|
+
}
|
|
537
|
+
return this;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Payments details
|
|
541
|
+
* @param paymentDetails
|
|
542
|
+
* @returns
|
|
543
|
+
*/
|
|
544
|
+
paymentDetails(paymentDetails) {
|
|
545
|
+
AppLoggerService.logInfo(this.className, "paymentDetails", "payment details after transaction completed", paymentDetails);
|
|
546
|
+
this.transactionDocument.paymentDetails = paymentDetails;
|
|
547
|
+
return this;
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Payments details
|
|
551
|
+
* @param paymentDetails
|
|
552
|
+
* @returns
|
|
553
|
+
*/
|
|
554
|
+
splitPayment(splitPayment) {
|
|
555
|
+
this.transactionDocument.splitPayment = splitPayment;
|
|
556
|
+
return this;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Payments details
|
|
560
|
+
* @param paymentDetails
|
|
561
|
+
* @returns
|
|
562
|
+
*/
|
|
563
|
+
isPaymentCompleted(isPaymentCompleted) {
|
|
564
|
+
this.transactionDocument.isPaymentCompleted = isPaymentCompleted;
|
|
565
|
+
return this;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Bases currency
|
|
569
|
+
* @param currency
|
|
570
|
+
* @returns currency
|
|
571
|
+
*/
|
|
572
|
+
baseCurrency(currency) {
|
|
573
|
+
this.transactionDocument.baseCurrency = currency;
|
|
574
|
+
return this;
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* gift option at
|
|
578
|
+
* @returns at
|
|
579
|
+
*/
|
|
580
|
+
giftOption(gift) {
|
|
581
|
+
AppLoggerService.logDebug(this.className, "giftOption", "this.transactionDocument.giftoption", gift);
|
|
582
|
+
if (gift) {
|
|
583
|
+
this.transactionDocument.giftedReceipt = gift;
|
|
584
|
+
}
|
|
585
|
+
return this;
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* manual Discount
|
|
591
|
+
* @param discountData
|
|
592
|
+
* @returns
|
|
593
|
+
*/
|
|
594
|
+
// manualDiscount(discountData : basketDiscount):TransactionDocumentBuilder {
|
|
595
|
+
// let saleTotal = this.transactionDocument.basketSummary.basketTotal;
|
|
596
|
+
// if(discountData.discountType =='Percent'){
|
|
597
|
+
// this.transactionDocument.basketSummary.basketTotal = saleTotal-(saleTotal*(discountData.discountAmount/100));
|
|
598
|
+
// discountData.discountAmount = -1*(saleTotal-this.transactionDocument.basketSummary.basketTotal);
|
|
599
|
+
// }else {
|
|
600
|
+
// this.transactionDocument.basketSummary.basketTotal =saleTotal-discountData.discountAmount;
|
|
601
|
+
// discountData.discountAmount = -1*discountData.discountAmount;
|
|
602
|
+
// }
|
|
603
|
+
// this.transactionDocument.transactionDiscount.push(discountData);
|
|
604
|
+
// return this;
|
|
605
|
+
// }
|
|
606
|
+
/**
|
|
607
|
+
* Types transaction document builder
|
|
608
|
+
* @param t
|
|
609
|
+
* @returns type
|
|
610
|
+
*/
|
|
611
|
+
type(t) {
|
|
612
|
+
this.transactionDocument.type = t;
|
|
613
|
+
return this;
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Operations status
|
|
617
|
+
* @param o
|
|
618
|
+
* @returns status
|
|
619
|
+
*/
|
|
620
|
+
operationStatus(o) {
|
|
621
|
+
this.transactionDocument.operationStatus = o;
|
|
622
|
+
return this;
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Created at
|
|
626
|
+
* @returns at
|
|
627
|
+
*/
|
|
628
|
+
createdAt() {
|
|
629
|
+
const date = new Date();
|
|
630
|
+
this.transactionDocument.createdAt = date.toISOString();
|
|
631
|
+
this.transactionDocument.updatedAt = date.toISOString();
|
|
632
|
+
return this;
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Updated at
|
|
636
|
+
* @returns at
|
|
637
|
+
*/
|
|
638
|
+
updatedAt() {
|
|
639
|
+
const date = new Date();
|
|
640
|
+
this.transactionDocument.updatedAt = date.toISOString();
|
|
641
|
+
return this;
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* transsaction completion at
|
|
645
|
+
* @returns transaction completion date
|
|
646
|
+
*/
|
|
647
|
+
transactionCompletedAt() {
|
|
648
|
+
const date = new Date();
|
|
649
|
+
this.transactionDocument.transCompletedAt = date.toISOString();
|
|
650
|
+
return this;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Builds transaction document builder
|
|
654
|
+
* @returns build
|
|
655
|
+
*/
|
|
656
|
+
build() {
|
|
657
|
+
return this.transactionDocument;
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Sales total in refund
|
|
661
|
+
* @param saleTotal
|
|
662
|
+
* @returns total in refund
|
|
663
|
+
*/
|
|
664
|
+
saleTotalInRefund(saleTotal) {
|
|
665
|
+
this.transactionDocument.saleTotal = saleTotal;
|
|
666
|
+
return this;
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Gets basket details
|
|
670
|
+
* @returns basket details
|
|
671
|
+
*/
|
|
672
|
+
getBasketDetails() {
|
|
673
|
+
AppLoggerService.logInfo(this.className, "getBasketDetails", "Getting Basket for transactionDocument", this.transactionDocument);
|
|
674
|
+
let basket = {
|
|
675
|
+
subsidiaryId: this.transactionDocument.subsidiaryId,
|
|
676
|
+
transactionDiscount: this.transactionDocument.basket.transactionDiscount,
|
|
677
|
+
transactionPromotion: this.transactionDocument.basket.transactionPromotion,
|
|
678
|
+
transactionId: this.transactionDocument.transactionId,
|
|
679
|
+
offlineTransactionId: this.transactionDocument.offlineTransactionId,
|
|
680
|
+
total: this.transactionDocument.basketSummary.basketTotal,
|
|
681
|
+
basketTotal: this.transactionDocument.basketSummary.basketTotal,
|
|
682
|
+
discountTotal: this.transactionDocument.basketSummary.discountTotal,
|
|
683
|
+
saleTotal: this.transactionDocument.basketSummary.saleTotal,
|
|
684
|
+
refundTotal: this.transactionDocument.basketSummary.refundTotal,
|
|
685
|
+
quantity: this.transactionDocument.basketSummary.totalItems,
|
|
686
|
+
products: [],
|
|
687
|
+
baseCurrency: this.transactionDocument.baseCurrency,
|
|
688
|
+
customer: this.transactionDocument.customer,
|
|
689
|
+
};
|
|
690
|
+
basket.products = [];
|
|
691
|
+
this.transactionDocument.basket.products.forEach((product, index) => {
|
|
692
|
+
AppLoggerService.logDebug(this.className, JSON.stringify(product), "ebasket: basket detail update in basket");
|
|
693
|
+
const p = {};
|
|
694
|
+
p.SKU = product.SKU;
|
|
695
|
+
p.barcode = product.barCode;
|
|
696
|
+
p.barcodes = product.barcodes;
|
|
697
|
+
p.description = product.description;
|
|
698
|
+
p.imageUrls = product.imageUrls;
|
|
699
|
+
p.currency = this.transactionDocument.baseCurrency;
|
|
700
|
+
p.totalLinePrice = product.totalLinePrice;
|
|
701
|
+
p.itemLineId = Number(product.itemLineId);
|
|
702
|
+
p.excludePromotion = product.excludePromotion;
|
|
703
|
+
p.selectedPrice = product.price;
|
|
704
|
+
p.quantity = product.quantity;
|
|
705
|
+
p.total = product.totalLinePrice;
|
|
706
|
+
p.selectedRRPPrice = product.selectedRRPPrice;
|
|
707
|
+
p.fullfilmentId = product.fullfilmentId;
|
|
708
|
+
p.fullfilmentLocationName = product.fullfilmentLocationName;
|
|
709
|
+
p.deliveryGroup = product.deliveryGroup || "1";
|
|
710
|
+
p.leadTime = product.leadTime;
|
|
711
|
+
p.deliveryMethod = product.deliveryMethod || DELIVERY_METHODS.COLLECT_FROM_STORE.toString();
|
|
712
|
+
if (p.fullfilmentId != this.transactionDocument.storeId) {
|
|
713
|
+
p.isWebOrder = true;
|
|
714
|
+
}
|
|
715
|
+
p.giftCard = product.giftCard;
|
|
716
|
+
p.giftCardExpiryDate = product.giftCardExpiryDate;
|
|
717
|
+
p.giftCardNumberIssued = product.giftCardNumberIssued;
|
|
718
|
+
p.giftCardRecipientEmail = product.giftCardRecipientEmail;
|
|
719
|
+
p.giftCardRecipientName = product.giftCardRecipientName;
|
|
720
|
+
if (this.transactionDocument.basket.lineDiscount &&
|
|
721
|
+
this.transactionDocument.basket.lineDiscount.length > 0) {
|
|
722
|
+
this.transactionDocument.basket.lineDiscount.forEach((lineDiscount) => {
|
|
723
|
+
if (product.itemLineId === lineDiscount.itemLineId.toString()) {
|
|
724
|
+
p.lineDiscount = lineDiscount;
|
|
725
|
+
p.total = lineDiscount.discountedLinePrice;
|
|
726
|
+
}
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
if (this.transactionDocument.basket.linePromotion &&
|
|
730
|
+
this.transactionDocument.basket.linePromotion.length > 0) {
|
|
731
|
+
this.transactionDocument.basket.linePromotion.forEach((linePromotion) => {
|
|
732
|
+
if (product.itemLineId === linePromotion.itemLineId.toString()) {
|
|
733
|
+
p.linePromotions = linePromotion;
|
|
734
|
+
p.total = linePromotion.promotionLinePrice;
|
|
735
|
+
}
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
if (this.transactionDocument.basket.taxBreakdown &&
|
|
739
|
+
this.transactionDocument.basket.taxBreakdown.taxLines.length > 0) {
|
|
740
|
+
this.transactionDocument.basket.taxBreakdown.taxLines.forEach((taxLine) => {
|
|
741
|
+
if (product.itemLineId && product.itemLineId === taxLine.itemLineId.toString()) {
|
|
742
|
+
p.selectedVAT = taxLine.VAT;
|
|
743
|
+
p.selectedVATCode = taxLine.VATCode;
|
|
744
|
+
}
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
if (this.transactionDocument.type === TRANSACTION_TYPE.REFUND) {
|
|
748
|
+
p.total = product.refundedTotal;
|
|
749
|
+
}
|
|
750
|
+
else if ((this.transactionDocument.type === TRANSACTION_TYPE.SALE_REFUND || TRANSACTION_TYPE.SALE_EXCHANGE) && product.refundedQuantity > 0) {
|
|
751
|
+
p.refundedReasonDescription = product.refundedReasonDescription;
|
|
752
|
+
p.refundedReason = product.refundedReason;
|
|
753
|
+
if (!p.refundedReasonDescription) {
|
|
754
|
+
p.refundedReasonDescription = p.refundedReason;
|
|
755
|
+
}
|
|
756
|
+
p.refundedQuantity = product.refundedQuantity;
|
|
757
|
+
p.refundPromotionalQuantity = product.refundedPromotionalQuantity;
|
|
758
|
+
p.refundedTotal = product.refundedTotal;
|
|
759
|
+
p.total -= Math.abs(p.refundedTotal);
|
|
760
|
+
p.isLastExchanged = product.isLastExchanged;
|
|
761
|
+
}
|
|
762
|
+
if (this.transactionDocument.type === TRANSACTION_TYPE.REFUND) {
|
|
763
|
+
if (p.total > 0) {
|
|
764
|
+
p.total *= -1;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
basket.products.push(p);
|
|
768
|
+
});
|
|
769
|
+
basket = this.getTransactionDiscountAndTransactionPromotionPortion(basket);
|
|
770
|
+
basket.total = (basket.basketTotal || 0) + this.getTotalDiscountWithTransactionDiscountsAndPromotions(basket);
|
|
771
|
+
if (this.transactionDocument.type === TRANSACTION_TYPE.SALE_REFUND) {
|
|
772
|
+
basket.quantity = this.getRefundedTotalWithQuantity(basket);
|
|
773
|
+
}
|
|
774
|
+
AppLoggerService.logInfo(this.className, "getBasketDetails", "Basket created successfully", basket);
|
|
775
|
+
return basket;
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* Gets basket details
|
|
779
|
+
* @returns refund basket details
|
|
780
|
+
*/
|
|
781
|
+
// getRefundBasketDetails(): Basket {
|
|
782
|
+
// let basket: Basket = {
|
|
783
|
+
// subsidiaryId : this.transactionDocument.subsidiaryId,
|
|
784
|
+
// transactionDiscount: this.transactionDocument.basket.transactionDiscount,
|
|
785
|
+
// transactionPromotion: this.transactionDocument.basket.transactionPromotion,
|
|
786
|
+
// transactionId: this.transactionDocument.transactionId,
|
|
787
|
+
// total: this.transactionDocument.basketSummary.basketTotal,
|
|
788
|
+
// basketTotal: this.transactionDocument.basketSummary.basketTotal,
|
|
789
|
+
// discountTotal: this.transactionDocument.basketSummary.discountTotal,
|
|
790
|
+
// saleTotal: this.transactionDocument.basketSummary.saleTotal,
|
|
791
|
+
// quantity: this.transactionDocument.basketSummary.totalItems,
|
|
792
|
+
// products: [],
|
|
793
|
+
// baseCurrency: this.transactionDocument.baseCurrency,
|
|
794
|
+
// customer: this.transactionDocument.customer,
|
|
795
|
+
// };
|
|
796
|
+
// basket.products = [] as Product[];
|
|
797
|
+
// 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) => {
|
|
798
|
+
// const p = {} as Product;
|
|
799
|
+
// p.SKU = product.SKU;
|
|
800
|
+
// p.barcode = product.barCode;
|
|
801
|
+
// p.barcodes = product.barcodes;
|
|
802
|
+
// p.description = product.description;
|
|
803
|
+
// p.imageUrls = product.imageUrls;
|
|
804
|
+
// p.currency = this.transactionDocument.baseCurrency;
|
|
805
|
+
// p.totalLinePrice = product.totalLinePrice;
|
|
806
|
+
// p.itemLineId = Number(product.itemLineId);
|
|
807
|
+
// p.excludePromotion = product.excludePromotion;
|
|
808
|
+
// p.selectedPrice = product.price;
|
|
809
|
+
// p.quantity = product.quantity;
|
|
810
|
+
// p.total = product.totalLinePrice;
|
|
811
|
+
// p.selectedRRPPrice = product.selectedRRPPrice;
|
|
812
|
+
// p.fullfilmentId = product.fullfilmentId;
|
|
813
|
+
// p.fullfilmentLocationName = product.fullfilmentLocationName;
|
|
814
|
+
// p.deliveryGroup = product.deliveryGroup || "1";
|
|
815
|
+
// p.leadTime = product.leadTime;
|
|
816
|
+
// p.deliveryMethod = product.deliveryMethod || DELIVERY_METHODS.COLLECT_FROM_STORE.toString();
|
|
817
|
+
// p.giftCard = product.giftCard;
|
|
818
|
+
// p.giftCardExpiryDate = product.giftCardExpiryDate;
|
|
819
|
+
// p.giftCardNumberIssued = product.giftCardNumberIssued;
|
|
820
|
+
// p.giftCardRecipientEmail = product.giftCardRecipientEmail;
|
|
821
|
+
// p.giftCardRecipientName = product.giftCardRecipientName;
|
|
822
|
+
// if(p.fullfilmentId != this.transactionDocument.storeId)
|
|
823
|
+
// {
|
|
824
|
+
// p.isWebOrder = true;
|
|
825
|
+
// }
|
|
826
|
+
// if (product.itemDiscounts) {
|
|
827
|
+
// p.itemDiscounts = product.itemDiscounts as ItemDiscount;
|
|
828
|
+
// }
|
|
829
|
+
// // if(!p.itemDiscounts){
|
|
830
|
+
// // AppLoggerService.logDebug(this.className, p.itemDiscounts);
|
|
831
|
+
// // this.basketService.transactionDiscountAndPromotionProductortionCalculation(basket);
|
|
832
|
+
// // }
|
|
833
|
+
// p.refundPromotionalQuantity = product.refundedPromotionalQuantity ? product.refundedPromotionalQuantity : 0;
|
|
834
|
+
// if (product.refundedQuantity) {
|
|
835
|
+
// p.quantity = p.quantity - product.refundedQuantity;
|
|
836
|
+
// p.totalLinePrice = (p.quantity * product.price);
|
|
837
|
+
// p.total = p.totalLinePrice;
|
|
838
|
+
// // p.refundPromotionalQuantity = product.refundedPromotionalQuantity;
|
|
839
|
+
// p.refunded = product.refunded;
|
|
840
|
+
// p.isLastExchanged = product.isLastExchanged;
|
|
841
|
+
// }
|
|
842
|
+
// if (product.exchange) {
|
|
843
|
+
// p.exchange = product.exchange;
|
|
844
|
+
// }
|
|
845
|
+
// if (
|
|
846
|
+
// this.transactionDocument.basket.lineDiscount &&
|
|
847
|
+
// this.transactionDocument.basket.lineDiscount.length > 0
|
|
848
|
+
// ) {
|
|
849
|
+
// this.transactionDocument.basket.lineDiscount.forEach((lineDiscount: { itemLineId: { toString: () => any; }; discountedLinePrice: any; }) => {
|
|
850
|
+
// if (product.itemLineId === lineDiscount.itemLineId.toString() && product.refundedQuantity > 0) {
|
|
851
|
+
// p.lineDiscount = Object.assign({}, lineDiscount);
|
|
852
|
+
// p.lineDiscount.discountedLinePrice = p.lineDiscount.unitPrice * p.quantity
|
|
853
|
+
// p.lineDiscount.discountAmount = p.total - p.lineDiscount.discountedLinePrice
|
|
854
|
+
// p.total = p.lineDiscount.discountedLinePrice;
|
|
855
|
+
// } else if (product.itemLineId === lineDiscount.itemLineId.toString()) {
|
|
856
|
+
// p.lineDiscount = lineDiscount;
|
|
857
|
+
// p.total = lineDiscount.discountedLinePrice
|
|
858
|
+
// }
|
|
859
|
+
// });
|
|
860
|
+
// }
|
|
861
|
+
// if (
|
|
862
|
+
// this.transactionDocument.basket.linePromotion &&
|
|
863
|
+
// this.transactionDocument.basket.linePromotion.length > 0
|
|
864
|
+
// ) {
|
|
865
|
+
// this.transactionDocument.basket.linePromotion.forEach((linePromotion: { itemLineId: { toString: () => any; }; refunded: any; }) => {
|
|
866
|
+
// if (product.itemLineId === linePromotion.itemLineId.toString() && !linePromotion.refunded) {
|
|
867
|
+
// p.linePromotions = linePromotion;
|
|
868
|
+
// p.total = p.linePromotions.promotionLinePrice;
|
|
869
|
+
// p.total = p.total - (product.refundedTotal ? Math.abs(product.refundedTotal) : 0);
|
|
870
|
+
// }
|
|
871
|
+
// });
|
|
872
|
+
// }
|
|
873
|
+
// p.refundedQuantity = 0;
|
|
874
|
+
// p.refundedTotal = 0;
|
|
875
|
+
// if (
|
|
876
|
+
// this.transactionDocument.basket.taxBreakdown &&
|
|
877
|
+
// this.transactionDocument.basket.taxBreakdown.taxLines.length > 0
|
|
878
|
+
// ) {
|
|
879
|
+
// this.transactionDocument.basket.taxBreakdown.taxLines.forEach((taxLine: { itemLineId: { toString: () => any; }; VAT: any; VATCode: any; }) => {
|
|
880
|
+
// if (product.itemLineId === taxLine.itemLineId.toString()) {
|
|
881
|
+
// p.selectedVAT = taxLine.VAT;
|
|
882
|
+
// p.selectedVATCode = taxLine.VATCode;
|
|
883
|
+
// }
|
|
884
|
+
// });
|
|
885
|
+
// }
|
|
886
|
+
// if (p.quantity > 0) {
|
|
887
|
+
// basket.products.push(p);
|
|
888
|
+
// }
|
|
889
|
+
// });
|
|
890
|
+
// // product.itemDiscounts
|
|
891
|
+
// if (!basket.products[0].hasOwnProperty('itemDiscounts')) {
|
|
892
|
+
// basket = this.getTransactionDiscountAndTransactionPromotionPortion(basket);
|
|
893
|
+
// }
|
|
894
|
+
// AppLoggerService.logDebug(this.className, "ebasket : TransactionDocumentBuilder :new created refunded basket", JSON.stringify(basket))
|
|
895
|
+
// basket.quantity = basket.products.reduce(
|
|
896
|
+
// (n: any, { quantity }: any) => n + quantity,
|
|
897
|
+
// 0
|
|
898
|
+
// );
|
|
899
|
+
// basket.total = this.getTotalWithLineDiscountAndLinePromotionApplied(basket);
|
|
900
|
+
// basket.basketTotal = basket.total;
|
|
901
|
+
// basket.basketTotal = basket.basketTotal - this.getTotalDiscountWithTransactionDiscountsAndPromotions(basket);
|
|
902
|
+
// AppLoggerService.logDebug(this.className,
|
|
903
|
+
// "ebasket : TransactionDocumentBuilder : update Basket Total: after promotion :basketTotal",
|
|
904
|
+
// basket.basketTotal
|
|
905
|
+
// );
|
|
906
|
+
// AppLoggerService.logDebug(this.className,
|
|
907
|
+
// "e:basket :TransactionDocumentBuilder : basketDetails updated values",
|
|
908
|
+
// JSON.stringify(basket)
|
|
909
|
+
// );
|
|
910
|
+
// return basket;
|
|
911
|
+
// }
|
|
912
|
+
getTransactionDiscountAndTransactionPromotionPortion(basket) {
|
|
913
|
+
if (basket.transactionDiscount &&
|
|
914
|
+
basket.transactionDiscount.length > 0) {
|
|
915
|
+
basket.transactionDiscount.forEach((discount) => {
|
|
916
|
+
if (!discount.itemLineIds) {
|
|
917
|
+
discount.itemLineIds = basket.products.map((product) => {
|
|
918
|
+
return product.itemLineId;
|
|
919
|
+
});
|
|
920
|
+
}
|
|
921
|
+
basket = this.basketService.transactionDiscountProductPortionCalc(basket, discount);
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
if (basket.transactionPromotion &&
|
|
925
|
+
basket.transactionPromotion.length > 0) {
|
|
926
|
+
basket.transactionPromotion.forEach((tPromotion) => {
|
|
927
|
+
if (!tPromotion.itemLineIds) {
|
|
928
|
+
const filteredData = basket.products.filter((item) => {
|
|
929
|
+
return item.excludePromotion === false;
|
|
930
|
+
});
|
|
931
|
+
tPromotion.itemLineIds =
|
|
932
|
+
filteredData.map((product) => {
|
|
933
|
+
return product.itemLineId;
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
basket = this.basketService.transactionPromotionProductPortionCalc(basket, tPromotion);
|
|
937
|
+
});
|
|
938
|
+
}
|
|
939
|
+
return basket;
|
|
940
|
+
}
|
|
941
|
+
getTotalDiscountWithTransactionDiscountsAndPromotions(basketDetails) {
|
|
942
|
+
let discountTotal = 0;
|
|
943
|
+
if (basketDetails.transactionPromotion &&
|
|
944
|
+
basketDetails.transactionPromotion.length > 0) {
|
|
945
|
+
discountTotal += basketDetails.transactionPromotion.reduce((n, { promotionAmount }) => n + promotionAmount, 0);
|
|
946
|
+
}
|
|
947
|
+
if (basketDetails.transactionDiscount &&
|
|
948
|
+
basketDetails.transactionDiscount.length > 0) {
|
|
949
|
+
discountTotal += basketDetails.transactionDiscount.reduce((n, { discountAmount }) => n + discountAmount, 0);
|
|
950
|
+
}
|
|
951
|
+
AppLoggerService.logDebug(this.className, "getTotalDiscountWithTransactionDiscountsAndPromotions", "Transaction discount Total:", discountTotal);
|
|
952
|
+
return discountTotal;
|
|
953
|
+
}
|
|
954
|
+
appendCurrencySymbol(currency, value) {
|
|
955
|
+
// value=this.decimalpipe.transform(value,'1.2');
|
|
956
|
+
if (value >= 0) {
|
|
957
|
+
const returnval = currency + value;
|
|
958
|
+
AppLoggerService.logDebug(this.className, "appendCurrencySymbol", "add currency with value", returnval);
|
|
959
|
+
return returnval;
|
|
960
|
+
}
|
|
961
|
+
else {
|
|
962
|
+
const returnval = "-" + (currency + value * -1);
|
|
963
|
+
AppLoggerService.logDebug(this.className, "appendCurrencySymbol", "returnVal", returnval);
|
|
964
|
+
return returnval;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
// /**
|
|
968
|
+
// * Updates total refund
|
|
969
|
+
// * @returns total refund
|
|
970
|
+
// */
|
|
971
|
+
// updateTotalRefund(): TransactionDocumentBuilder {
|
|
972
|
+
// this.transactionDocument.basket.products.forEach((product) => {
|
|
973
|
+
// product.refundedQuantity = product.quantity;
|
|
974
|
+
// product.refundedTotal = product.totalLinePrice * -1;
|
|
975
|
+
// AppLoggerService.logDebug(this.className,
|
|
976
|
+
// "ebasket: Transaction price override :",
|
|
977
|
+
// this.transactionDocument.basket.lineDiscount
|
|
978
|
+
// );
|
|
979
|
+
// if (
|
|
980
|
+
// this.transactionDocument.basket.linePromotion &&
|
|
981
|
+
// this.transactionDocument.basket.linePromotion.length > 0
|
|
982
|
+
// ) {
|
|
983
|
+
// this.transactionDocument.basket.linePromotion.forEach((linePromotion) => {
|
|
984
|
+
// AppLoggerService.logDebug(this.className,
|
|
985
|
+
// "Promotion: basket linePromotion : ",
|
|
986
|
+
// this.transactionDocument.basket.linePromotion
|
|
987
|
+
// );
|
|
988
|
+
// AppLoggerService.logDebug(this.className,
|
|
989
|
+
// "linePromotion.itemLineId.toString() : ",
|
|
990
|
+
// linePromotion.itemLineId.toString()
|
|
991
|
+
// );
|
|
992
|
+
// AppLoggerService.logDebug(this.className,
|
|
993
|
+
// "condition : " +
|
|
994
|
+
// (product.itemLineId === linePromotion.itemLineId.toString())
|
|
995
|
+
// );
|
|
996
|
+
// if (product.itemLineId === linePromotion.itemLineId.toString()) {
|
|
997
|
+
// product.refundedTotal =
|
|
998
|
+
// linePromotion.promotionLinePrice * -1;
|
|
999
|
+
// }
|
|
1000
|
+
// });
|
|
1001
|
+
// } else
|
|
1002
|
+
// if (
|
|
1003
|
+
// this.transactionDocument.basket.lineDiscount &&
|
|
1004
|
+
// this.transactionDocument.basket.lineDiscount.length > 0
|
|
1005
|
+
// ) {
|
|
1006
|
+
// this.transactionDocument.basket.lineDiscount.forEach((lineDiscount) => {
|
|
1007
|
+
// AppLoggerService.logDebug(this.className,
|
|
1008
|
+
// "product.itemLineId : " +
|
|
1009
|
+
// this.transactionDocument.basket.lineDiscount
|
|
1010
|
+
// );
|
|
1011
|
+
// AppLoggerService.logDebug(this.className,
|
|
1012
|
+
// "lineDiscount.itemLineId.toString() : " +
|
|
1013
|
+
// lineDiscount.itemLineId.toString()
|
|
1014
|
+
// );
|
|
1015
|
+
// AppLoggerService.logDebug(this.className,
|
|
1016
|
+
// "condition : " +
|
|
1017
|
+
// (product.itemLineId === lineDiscount.itemLineId.toString())
|
|
1018
|
+
// );
|
|
1019
|
+
// if (product.itemLineId === lineDiscount.itemLineId.toString()) {
|
|
1020
|
+
// product.refundedTotal = lineDiscount.unitPrice * product.refundedQuantity * -1;
|
|
1021
|
+
// }
|
|
1022
|
+
// });
|
|
1023
|
+
// }
|
|
1024
|
+
// AppLoggerService.logDebug(this.className, "Product description :" + product.description);
|
|
1025
|
+
// AppLoggerService.logDebug(this.className, "Product total :" + product.refundedTotal);
|
|
1026
|
+
// // product.displayrefundedamount=this.appendCurrencySymbol(CURRENCY[this.transactionDocument.baseCurrency],product.refundedTotal);
|
|
1027
|
+
// // AppLoggerService.logDebug(this.className, product.displayrefundedamount,"displayrefundedamount");
|
|
1028
|
+
// product.refunded = true;
|
|
1029
|
+
// });
|
|
1030
|
+
// const baskettotal = (this.transactionDocument.basketSummary.basketTotal *= -1);
|
|
1031
|
+
// // this.transactionDocument.basketSummary.displaybaskettotal=this.appendCurrencySymbol(CURRENCY[this.transactionDocument.baseCurrency], baskettotal);
|
|
1032
|
+
// const saletotal = (this.transactionDocument.basketSummary.saleTotal *= -1);
|
|
1033
|
+
// // this.transactionDocument.basketSummary.displaysaletotal = this.appendCurrencySymbol(CURRENCY[this.transactionDocument.baseCurrency], saletotal);
|
|
1034
|
+
// (this.transactionDocument.basketSummary.VATTotal *= -1);
|
|
1035
|
+
// return this;
|
|
1036
|
+
// }
|
|
1037
|
+
/**
|
|
1038
|
+
* Sale Total
|
|
1039
|
+
* @param basketDetails
|
|
1040
|
+
* @returns Sale Total
|
|
1041
|
+
*/
|
|
1042
|
+
updateSaleTotal(basketDetails) {
|
|
1043
|
+
const saleTotal = basketDetails.products.reduce((n, { totalLinePrice }) => n + totalLinePrice, 0);
|
|
1044
|
+
return saleTotal;
|
|
1045
|
+
}
|
|
1046
|
+
getTotalWithLineDiscountAndLinePromotionApplied(basketDetails) {
|
|
1047
|
+
let saletotal = 0.0;
|
|
1048
|
+
for (let product of basketDetails.products) {
|
|
1049
|
+
// if (product.linePromotions) {
|
|
1050
|
+
// saletotal += product.linePromotions.promotionLinePrice;
|
|
1051
|
+
// } else if (
|
|
1052
|
+
// product.lineDiscount &&
|
|
1053
|
+
// !product.linePromotions
|
|
1054
|
+
// ) {
|
|
1055
|
+
// saletotal +=
|
|
1056
|
+
// product.quantity * Number(product.lineDiscount.unitPrice.toFixed(2));
|
|
1057
|
+
// } else {
|
|
1058
|
+
// saletotal +=
|
|
1059
|
+
// product.quantity * Number(product.selectedPrice.toFixed(2));
|
|
1060
|
+
// }
|
|
1061
|
+
saletotal += product.total;
|
|
1062
|
+
AppLoggerService.logDebug(this.className, "getTotalWithLineDiscountAndLinePromotionApplied", "e-basket:update product Total:" + saletotal, product);
|
|
1063
|
+
}
|
|
1064
|
+
return saletotal;
|
|
1065
|
+
}
|
|
1066
|
+
getRefundedTotalWithQuantity(basketDetails) {
|
|
1067
|
+
let quantity = 0;
|
|
1068
|
+
for (let index = 0; index < basketDetails.products.length; index++) {
|
|
1069
|
+
const product = basketDetails.products[index];
|
|
1070
|
+
if (!product.refundedReasonDescription) {
|
|
1071
|
+
quantity = quantity + product.quantity;
|
|
1072
|
+
}
|
|
1073
|
+
else {
|
|
1074
|
+
quantity = quantity + (product.quantity - product.refundedQuantity);
|
|
1075
|
+
// basketDetails.total = basketDetails.total + product.refundedTotal;
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
return quantity;
|
|
1079
|
+
}
|
|
1080
|
+
/**
|
|
1081
|
+
* Discount Total
|
|
1082
|
+
* @returns Discount Total
|
|
1083
|
+
*/
|
|
1084
|
+
updateDiscountTotal() {
|
|
1085
|
+
let refundTotal = this.transactionDocument.basketSummary.refundTotal ? this.transactionDocument.basketSummary.refundTotal : 0;
|
|
1086
|
+
AppLoggerService.logInfo(this.className, "updateDiscountTotal", `refundTotal: ${refundTotal} this.transactionDocument.basketSummary: ${this.transactionDocument.basketSummary}`);
|
|
1087
|
+
const discountTotal = Math.abs(Math.abs(this.transactionDocument.basketSummary.saleTotal) -
|
|
1088
|
+
(Math.abs(this.transactionDocument.basketSummary.basketTotal) + Math.abs(refundTotal)));
|
|
1089
|
+
AppLoggerService.logDebug(this.className, "updateDiscountTotal", "discountTotal", discountTotal);
|
|
1090
|
+
return Number(discountTotal.toFixed(2));
|
|
1091
|
+
}
|
|
1092
|
+
updateReasonCode(reasonCode) {
|
|
1093
|
+
this.transactionDocument.reasonCode = reasonCode.code;
|
|
1094
|
+
this.transactionDocument.reasonDescription = reasonCode.name;
|
|
1095
|
+
return this;
|
|
1096
|
+
}
|
|
1097
|
+
updateManagerOverride(useroverride) {
|
|
1098
|
+
this.transactionDocument.override = useroverride;
|
|
1099
|
+
return this;
|
|
1100
|
+
}
|
|
1101
|
+
updateUserID(userID) {
|
|
1102
|
+
this.transactionDocument.userId = userID;
|
|
1103
|
+
return this;
|
|
1104
|
+
}
|
|
1105
|
+
updateUserName(name) {
|
|
1106
|
+
this.transactionDocument.userName = name;
|
|
1107
|
+
return this;
|
|
1108
|
+
}
|
|
1109
|
+
addCustomerDetails(customerDetail) {
|
|
1110
|
+
this.transactionDocument.customer = customerDetail;
|
|
1111
|
+
return this;
|
|
1112
|
+
}
|
|
1113
|
+
updateTaxBreakdown(basketDetails) {
|
|
1114
|
+
// let transactionDiscountTotal = 0;
|
|
1115
|
+
let taxBreakdown = {
|
|
1116
|
+
taxLines: [],
|
|
1117
|
+
totalTaxableAmount: 0,
|
|
1118
|
+
};
|
|
1119
|
+
// if (this.transactionDocument.basket.transactionDiscount && this.transactionDocument.basket.transactionDiscount.length > 0) {
|
|
1120
|
+
// this.transactionDocument.basket.transactionDiscount.forEach((discount) => {
|
|
1121
|
+
// transactionDiscountTotal += discount.discountAmount;
|
|
1122
|
+
// });
|
|
1123
|
+
// }
|
|
1124
|
+
// if (this.transactionDocument.basket.transactionPromotion && this.transactionDocument.basket.transactionPromotion.length > 0) {
|
|
1125
|
+
// this.transactionDocument.basket.transactionPromotion.forEach(
|
|
1126
|
+
// (promotion) => {
|
|
1127
|
+
// transactionDiscountTotal += promotion.promotionAmount;
|
|
1128
|
+
// }
|
|
1129
|
+
// );
|
|
1130
|
+
// }
|
|
1131
|
+
basketDetails.products.forEach((product) => {
|
|
1132
|
+
let taxLine = {
|
|
1133
|
+
itemLineId: product.itemLineId,
|
|
1134
|
+
VAT: product.selectedVAT ? product.selectedVAT : 0,
|
|
1135
|
+
VATCode: product.selectedVATCode,
|
|
1136
|
+
taxLineTotal: 0,
|
|
1137
|
+
taxableAmount: product.total,
|
|
1138
|
+
PreTax: 0
|
|
1139
|
+
};
|
|
1140
|
+
AppLoggerService.logInfo(this.className, "updateTaxBreakdown", `item line ID :, ${product.itemLineId},
|
|
1141
|
+
"tax line :", ${taxLine}`);
|
|
1142
|
+
// step 1
|
|
1143
|
+
// if Transaction Discount and/or promotion applied, find net selling price of each product as taxableamount
|
|
1144
|
+
// if (transactionDiscountTotal > 0) {
|
|
1145
|
+
product = this.basketService.validateProductItemDiscount(product);
|
|
1146
|
+
const productContributionInTotal = product.itemDiscounts.trnDiscountsPortion +
|
|
1147
|
+
product.itemDiscounts.trnPromotionsPortion -
|
|
1148
|
+
product.itemDiscounts.refundPortion;
|
|
1149
|
+
// tp+td-rp;
|
|
1150
|
+
AppLoggerService.logInfo(this.className, "updateTaxBreakdown", `item line ID , ${product.itemLineId},
|
|
1151
|
+
"contribution :", ${productContributionInTotal}`);
|
|
1152
|
+
// calculate net selling price after applying transaction discount as per product contribution
|
|
1153
|
+
taxLine.taxableAmount -= productContributionInTotal;
|
|
1154
|
+
// }
|
|
1155
|
+
//step 2 - find pre tax
|
|
1156
|
+
taxLine.PreTax = this.numberUtilService.trimTo2Decimal2((taxLine.taxableAmount * 100) / (100 + taxLine.VAT));
|
|
1157
|
+
//step 3 - Update taxbreakdown
|
|
1158
|
+
taxBreakdown.totalTaxableAmount += taxLine.taxableAmount;
|
|
1159
|
+
taxLine.taxableAmount = this.numberUtilService.trimTo2Decimal2(taxLine.taxableAmount);
|
|
1160
|
+
// step 4 - update tax Line total
|
|
1161
|
+
taxLine.taxLineTotal = this.numberUtilService.trimTo2Decimal2(taxLine.taxableAmount - taxLine.PreTax);
|
|
1162
|
+
taxBreakdown.taxLines.push(taxLine);
|
|
1163
|
+
});
|
|
1164
|
+
taxBreakdown.totalTaxableAmount = this.numberUtilService.trimTo2Decimal2(taxBreakdown.totalTaxableAmount);
|
|
1165
|
+
this.transactionDocument.basket.taxBreakdown = taxBreakdown;
|
|
1166
|
+
return this;
|
|
1167
|
+
}
|
|
1168
|
+
updateTotalTaxSummary() {
|
|
1169
|
+
AppLoggerService.logDebug(this.className, "updateTotalTaxSummary", "Total Tax Summery Request :", this.transactionDocument.basket.taxBreakdown);
|
|
1170
|
+
let totalTaxSummaryArray = [];
|
|
1171
|
+
let totalTaxSummaryGroup = [];
|
|
1172
|
+
AppLoggerService.logDebug(this.className, "updateTotalTaxSummary", "Tax Lines for Total Tax Summery :", this.transactionDocument.basket.taxBreakdown.taxLines);
|
|
1173
|
+
this.transactionDocument.basket.taxBreakdown.taxLines.forEach((element) => {
|
|
1174
|
+
let TaxSummary = {
|
|
1175
|
+
VATCode: "",
|
|
1176
|
+
VAT: -12345,
|
|
1177
|
+
PreTaxSum: 0,
|
|
1178
|
+
TaxSum: 0,
|
|
1179
|
+
TXrateSum: 0
|
|
1180
|
+
};
|
|
1181
|
+
TaxSummary.VATCode = element.VATCode;
|
|
1182
|
+
TaxSummary.VAT = element.VAT;
|
|
1183
|
+
TaxSummary.PreTaxSum = this.numberUtilService.trimTo2Decimal2(element.PreTax);
|
|
1184
|
+
TaxSummary.TaxSum = this.numberUtilService.trimTo2Decimal2(element.taxLineTotal);
|
|
1185
|
+
TaxSummary.TXrateSum = this.numberUtilService.trimTo2Decimal2(TaxSummary.PreTaxSum + TaxSummary.TaxSum);
|
|
1186
|
+
totalTaxSummaryArray.push(TaxSummary);
|
|
1187
|
+
});
|
|
1188
|
+
AppLoggerService.logDebug(this.className, "updateTotalTaxSummary", "Total Tax Summery Without Grouped : ", totalTaxSummaryArray);
|
|
1189
|
+
totalTaxSummaryGroup = totalTaxSummaryArray.reduce((preparedArray, currentObj) => {
|
|
1190
|
+
let ind = preparedArray.findIndex((x) => x.VAT === currentObj.VAT);
|
|
1191
|
+
if (ind === -1) {
|
|
1192
|
+
preparedArray.push(currentObj);
|
|
1193
|
+
}
|
|
1194
|
+
else {
|
|
1195
|
+
preparedArray[ind].VATCode = currentObj.VATCode;
|
|
1196
|
+
preparedArray[ind].VAT = currentObj.VAT;
|
|
1197
|
+
preparedArray[ind].PreTaxSum += currentObj.PreTaxSum;
|
|
1198
|
+
preparedArray[ind].TaxSum += currentObj.TaxSum;
|
|
1199
|
+
preparedArray[ind].TXrateSum += currentObj.TXrateSum;
|
|
1200
|
+
}
|
|
1201
|
+
return preparedArray;
|
|
1202
|
+
}, []);
|
|
1203
|
+
AppLoggerService.logDebug(this.className, "updateTotalTaxSummary", "Total Tax Summer Group :", totalTaxSummaryGroup);
|
|
1204
|
+
this.transactionDocument.basket.totalTaxSummary = totalTaxSummaryGroup;
|
|
1205
|
+
return this;
|
|
1206
|
+
}
|
|
1207
|
+
/**
|
|
1208
|
+
* TransactionId
|
|
1209
|
+
* @returns OriginalTransactionId
|
|
1210
|
+
*/
|
|
1211
|
+
addOriginalTransId(tranDoc) {
|
|
1212
|
+
if (this.transactionDocument.type === TRANSACTION_TYPE.REFUND || this.transactionDocument.type === TRANSACTION_TYPE.SALE_REFUND || this.transactionDocument.type === TRANSACTION_TYPE.SALE_EXCHANGE) {
|
|
1213
|
+
this.transactionDocument.originalTransId = tranDoc.transactionId;
|
|
1214
|
+
if (tranDoc.apiResponse && tranDoc.apiResponse.internalId) {
|
|
1215
|
+
this.transactionDocument.originalExternalId = tranDoc.apiResponse.internalId.toString();
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
return this;
|
|
1219
|
+
}
|
|
1220
|
+
/**
|
|
1221
|
+
* unreferenced Refund
|
|
1222
|
+
* @returns boolean value
|
|
1223
|
+
*/
|
|
1224
|
+
addUnreferencedRefund() {
|
|
1225
|
+
this.transactionDocument.unreferencedRefund = true;
|
|
1226
|
+
return this;
|
|
1227
|
+
}
|
|
1228
|
+
getRefundTotal() {
|
|
1229
|
+
let totalRefund = 0;
|
|
1230
|
+
for (let index = 0; index < this.transactionDocument.basket.products.length; index++) {
|
|
1231
|
+
const product = this.transactionDocument.basket.products[index];
|
|
1232
|
+
if (product.refundedTotal) {
|
|
1233
|
+
totalRefund = totalRefund + product.refundedTotal;
|
|
1234
|
+
}
|
|
1235
|
+
AppLoggerService.logDebug(this.className, "getRefundTotal", "totalRefund", totalRefund);
|
|
1236
|
+
}
|
|
1237
|
+
return totalRefund;
|
|
1238
|
+
}
|
|
1239
|
+
docId(docId) {
|
|
1240
|
+
this.transactionDocument.id = docId;
|
|
1241
|
+
return this;
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9tYXBwZXItbGlicmFyeS9zcmMvbGliL1RyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBc0QsZ0JBQWdCLEVBQWlHLE1BQU0sd0JBQXdCLENBQUM7QUFDN00sT0FBTyxFQUFFLGdCQUFnQixFQUErRCxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZILE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxzREFBc0QsQ0FBQztBQUV0Rjs7R0FFRztBQUNILE1BQU0sT0FBTywwQkFBMEI7SUFNckMsWUFDRSxjQUFvQyxFQUM1QixZQUEyQixFQUMzQixhQUFtQztRQURuQyxpQkFBWSxHQUFaLFlBQVksQ0FBZTtRQUMzQixrQkFBYSxHQUFiLGFBQWEsQ0FBc0I7UUFMN0MsY0FBUyxHQUFHLDRCQUE0QixDQUFDO1FBT3ZDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzdELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxhQUFhLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDL0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUM7UUFDdkUsSUFBSSxjQUFjLEVBQUU7WUFDbEIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLGNBQWMsQ0FBQztTQUMzQzthQUFNO1lBQ0wsSUFBSSxDQUFDLG1CQUFtQixHQUFHO2dCQUN6QixhQUFhLEVBQUUs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QUFrQixHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDO2FBQ3pGO1NBQ0Y7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7O09BR0c7SUFDSCxxQkFBcUI7UUFDbkIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztRQUNuRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxjQUFjO1FBQ1osSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ3BCLEtBQUssSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDcEYsTUFBTSxPQUFPLEdBQWEsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDMUUsSUFBSSxPQUFPLENBQUMsYUFBYSxFQUFFO2dCQUN6QixXQUFXLEdBQUcsV0FBVyxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUM7YUFDbkQ7WUFDRCxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxhQUFhLEVBQUcsV0FBVyxDQUFDLENBQUE7U0FDekY7UUFDRCxPQUFPLFdBQVcsQ0FBQztJQUNyQixDQUFDO0lBRUQsS0FBSyxDQUFDLEtBQVU7UUFDWixJQUFJLENBQUMsbUJBQW1CLENBQUMsRUFBRSxHQUFHLEtBQUssQ0FBQztRQUN0QyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEN1cnJlbmN5UGlwZSB9IGZyb20gXCJAYW5ndWxhci9jb21tb25cIjtcbmltcG9ydCB7IEJhc2tldFN1bW1hcnksIEN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMsIEN1c3RvbWVyLCBERUxJVkVSWV9NRVRIT0RTLCBJdGVtRGlzY291bnRzLCBUYXhCcmVha2Rvd24sIFRheExpbmUsIFRCYXNrZXQsIFRvdGFsVGF4U3VtbWFyeSwgVFByb2R1Y3QsIFRyYW5zYWN0aW9uRG9jdW1lbnQgfSBmcm9tIFwiLi9tYXBwZXItbGlicmFyeS5tb2RlbFwiO1xuaW1wb3J0IHsgVFJBTlNBQ1RJT05fVFlQRSwgQmFza2V0LCBMaW5lRGlzY291bnQsIExpbmVQcm9tb3Rpb25zLCBQcm9kdWN0LCBVc2VyT3ZlcnJpZGUgfSBmcm9tIFwiLi9tYXBwZXItbGlicmFyeS5tb2RlbFwiO1xuaW1wb3J0IHsgQmFza2V0U2VydmljZSB9IGZyb20gXCIuL2Jhc2tldC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBOdW1iZXJVdGlsU2VydmljZSB9IGZyb20gXCIuL251bWJlci11dGlsLnNlcnZpY2VcIjtcbmltcG9ydCB7QXBwTG9nZ2VyU2VydmljZX0gZnJvbSAnQHBtY3JldGFpbC9jb21tb24tc2VydmljZXMvY29tbW9uL2FwcC1sb2dnZXIuc2VydmljZSc7XG5cbi8qKlxuICogVHJhbnNhY3Rpb24gZG9jdW1lbnQgYnVpbGRlclxuICovXG5leHBvcnQgY2xhc3MgVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICBwcml2YXRlIHRyYW5zYWN0aW9uRG9jdW1lbnQ6IFRyYW5zYWN0aW9uRG9jdW1lbnQ7XG4gIHByaXZhdGUgbnVtYmVyVXRpbFNlcnZpY2U6IE51bWJlclV0aWxTZXJ2aWNlO1xuICBwcml2YXRlIHN0b3JlSW5mbyA6IGFueTtcbiAgY2xhc3NOYW1lID0gXCJUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlclwiO1xuICBcbiAgY29uc3RydWN0b3IoXG4gICAgdHJhbnNhY3Rpb25Eb2M/OiBUcmFuc2FjdGlvbkRvY3VtZW50LFxuICAgIHByaXZhdGUgY3VycmVuY3lQaXBlPzogQ3VycmVuY3lQaXBlLFxuICAgIHByaXZhdGUgYmFza2V0U2VydmljZT86IEJhc2tldFNlcnZpY2UgfCBhbnksXG4gICkge1xuICAgIHRoaXMubnVtYmVyVXRpbFNlcnZpY2UgPSBuZXcgTnVtYmVyVXRpbFNlcnZpY2UoY3VycmVuY3lQaXBlKTtcbiAgICB0aGlzLmJhc2tldFNlcnZpY2UgPSBuZXcgQmFza2V0U2VydmljZSh0aGlzLm51bWJlclV0aWxTZXJ2aWNlKTtcbiAgICB0aGlzLnN0b3JlSW5mbyA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ3N0b3JlSW5mbycpIHx8ICd7fScpO1xuICAgIGlmICh0cmFuc2FjdGlvbkRvYykge1xuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50ID0gdHJhbnNhY3Rpb25Eb2M7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudCA9IHtcbiAgICAgICAgdHJhbnNhY3Rpb25JZDogXCJcIixcbiAgICAgICAgb2ZmbGluZVRyYW5zYWN0aW9uSWQ6IFwiXCIsXG4gICAgICAgIHRyYW5zYWN0aW9uUmVmOiBcIlwiLFxuICAgICAgICBkYXRlVGltZTogXCJcIixcbiAgICAgICAgb3JnQ29kZTogXCJcIixcbiAgICAgICAgc3RvcmVJZDogXCJcIixcbiAgICAgICAgc3RvcmVOb2RlSWQ6IFwiXCIsXG4gICAgICAgIHN0b3JlTm9kZVN0cnVjdHVyZTogXCJcIixcbiAgICAgICAgZGV2aWNlSWQ6IFwiXCIsXG4gICAgICAgIHRlcm1pbmFsSWQ6IFwiXCIsXG4gICAgICAgIHVzZXJJZDogXCJcIixcbiAgICAgICAgaW5pdGlhdGluZ01vZHVsZSA6IFwiZUJhc2tldFwiLFxuICAgICAgICBleHBvcnQ6IGZhbHNlLFxuICAgICAgICBiYXNrZXQ6IHt9IGFzIFRCYXNrZXQsXG4gICAgICAgIGJhc2tldFN1bW1hcnk6IHt9IGFzIEJhc2tldFN1bW1hcnksXG4gICAgICAgIGJhc2VDdXJyZW5jeTogXCJcIixcbiAgICAgICAgdHlwZTogXCJcIixcbiAgICAgICAgb3BlcmF0aW9uU3RhdHVzOiBcIlwiLFxuICAgICAgICBjcmVhdGVkQXQ6IFwiXCIsXG4gICAgICAgIHVwZGF0ZWRBdDogXCJcIixcbiAgICAgICAgaWQ6IFwiXCIsXG4gICAgICAgIGN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHM6IHt9IGFzIEN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMsXG4gICAgICAgIHNhbGVUb3RhbDogMCxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zYWN0aW9ucyByZWZcbiAgICogQHJldHVybnMgcmVmXG4gICAqL1xuICB0cmFuc2FjdGlvblJlZigpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XG4gICAgY29uc3Qgc3RvcmVEZXRhaWxzID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnc3RvcmVJbmZvJykgfHwgJ3t9Jyk7XG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgcmFuZG9tID0gKCgoMSArIE1hdGgucmFuZG9tKCkpICogMHgxMDAwMCkgfCAwKVxuICAgICAgLnRvU3RyaW5nKDE2KVxuICAgICAgLnN1YnN0cmluZygxKTtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHJhbnNhY3Rpb25SZWYgPVxuICAgICAgc3RvcmVEZXRhaWxzLm9yZ0NvZGUgKyBzdG9yZURldGFpbHMuc3RvcmVJZCArIGRhdGUudG9JU09TdHJpbmcoKSArIHJhbmRvbTtcbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcInRyYW5zYWN0aW9uUmVmXCIsIFwidHJhbnNhY3Rpb24gcmVmIGNyZWF0ZWRcIiwgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnRyYW5zYWN0aW9uUmVmKVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zYWN0aW9ucyBpZFxuICAgKiBAcGFyYW0gdHJhbnNhY3Rpb25JRFxuICAgKiBAcmV0dXJucyBpZFxuICAgKi9cbiAgdHJhbnNhY3Rpb25JZCh0cmFuc2FjdGlvbklEOiBzdHJpbmcsIGlzT25saW5lOiBib29sZWFuID0gdHJ1ZSk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICBpZiAoaXNPbmxpbmUpIHtcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC50cmFuc2FjdGlvbklkID0gdHJhbnNhY3Rpb25JRDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogVHJhbnNhY3Rpb25zIGlkXG4gICAqIEBwYXJhbSB0cmFuc2FjdGlvbklEXG4gICAqIEByZXR1cm5zIGlkXG4gICAqL1xuICBvZmZsaW5lVHJhbnNhY3Rpb25JZCh0cmFuc2FjdGlvbklEOiBzdHJpbmcsIGlzT25saW5lOiBhbnkpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XG4gICAgaWYgKCFpc09ubGluZSkge1xuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50Lm9mZmxpbmVUcmFuc2FjdGlvbklkID0gdHJhbnNhY3Rpb25JRDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgKiBzdG9yZU5vZGUgSWRcbiAgKiBAcGFyYW0gc3RvcmVOb2RlSWRcbiAgKiBAcmV0dXJucyBpZFxuICAqL1xuICBzdG9yZU5vZGVJZChzdG9yZU5vZGVJZDogc3RyaW5nKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5zdG9yZU5vZGVJZCA9IHN0b3JlTm9kZUlkO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4qIHN0b3JlTm9kZSBzdHJ1Y3R1cmVcbiogQHBhcmFtIHN0b3JlTm9kZVN0cnVjdHVyZVxuKiBAcmV0dXJucyBpZFxuKi9cbiAgc3RvcmVOb2RlU3RydWN0dXJlKHN0b3JlTm9kZVN0cnVjdHVyZTogc3RyaW5nKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5zdG9yZU5vZGVTdHJ1Y3R1cmUgPSBzdG9yZU5vZGVTdHJ1Y3R1cmU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogT3JncyBjb2RlXG4gICAqIEBwYXJhbSBvcmdDb2RlXG4gICAqIEByZXR1cm5zIGNvZGVcbiAgICovXG4gIG9yZ0NvZGUob3JnQ29kZTogYW55KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5vcmdDb2RlID0gb3JnQ29kZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogU3RvcmVzIGlkXG4gICAqIEBwYXJhbSBzdG9yZUlkXG4gICAqIEByZXR1cm5zIGlkXG4gICAqL1xuICBzdG9yZUlkKHN0b3JlSWQ6IGFueSk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuc3RvcmVJZCA9IHN0b3JlSWQ7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIERhdGVzIHRpbWVcbiAgICogQHJldHVybnMgdGltZVxuICAgKi9cbiAgZGF0ZVRpbWUoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5kYXRlVGltZSA9IGRhdGUudG9JU09TdHJpbmcoKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogRGV2aWNlcyBpZFxuICAgKiBAcGFyYW0gZGV2aWNlSWRcbiAgICogQHJldHVybnMgaWRcbiAgICovXG4gIGRldmljZUlkKGRldmljZUlkOiBhbnkpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmRldmljZUlkID0gZGV2aWNlSWQ7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgICAqIHRlcm1pbmFsIGlkXG4gICAgICogQHBhcmFtIHRlcm1pbmFsSWRcbiAgICAgKiBAcmV0dXJucyBpZFxuICAgICAqL1xuICB0ZXJtaW5hbElkKHRlcm1pbmFsSWQ6IGFueSk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudGVybWluYWxJZCA9IHRlcm1pbmFsSWQ7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuXG5cblxuXG4gIC8qKlxuICAgICogc2FsZUV4cG9ydFxuICAgICogQHBhcmFtIHNhbGVFeHBvcnRcbiAgICAqIEByZXR1cm5zIGlkXG4gICAgKi9cbiAgZXhwb3J0KHNhbGVFeHBvcnQ6IGFueSk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuZXhwb3J0ID0gc2FsZUV4cG9ydDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG5cblxuICAvKiAgY3VzdG9tZXIoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAgIGNvbnN0IHVzZXIgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCd1c2VyRGV0YWlscycpKTtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VzdG9tZXIgPSB1c2VyO1xuICAgIHJldHVybiB0aGlzO1xuICB9ICovXG4gIC8qKlxuICAgKiBCYXNrZXRzIHRyYW5zYWN0aW9uIGRvY3VtZW50IGJ1aWxkZXJcbiAgICogQHBhcmFtIGJhc2tldERldGFpbHNcbiAgICogQHJldHVybnMgYmFza2V0XG4gICAqL1xuICBiYXNrZXQoYmFza2V0RGV0YWlsczogQmFza2V0KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwiYmFza2V0XCIsIFwiYmFza2V0IGRldGFpbHMgdXBkYXRlIGluIHRyYW5zYWN0aW9uIGRvY3VtZW50XCIsIGJhc2tldERldGFpbHMpO1xuXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnN1YnNpZGlhcnlJZCA9IGJhc2tldERldGFpbHMuc3Vic2lkaWFyeUlkIHx8IChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnc3Vic2lkaWFyeUlkJykgfHwgJycpO1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQucHJvZHVjdHMgPSBbXSBhcyBUUHJvZHVjdFtdO1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50ID0gW107XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lUHJvbW90aW9uID0gW107XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50cmFuc2FjdGlvblByb21vdGlvbiA9IFtdO1xuICAgIGJhc2tldERldGFpbHMucHJvZHVjdHMuZm9yRWFjaCgocHJvZHVjdDogYW55LCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgcCA9IHt9IGFzIFRQcm9kdWN0O1xuICAgICAgcC5pdGVtRGlzY291bnRzID0ge30gYXMgSXRlbURpc2NvdW50cztcbiAgICAgIHAuU0tVID0gcHJvZHVjdC5TS1U7XG4gICAgICBwLmV4Y2x1ZGVQcm9tb3Rpb24gPSBwcm9kdWN0LmV4Y2x1ZGVQcm9tb3Rpb247XG4gICAgICBwLmJhckNvZGUgPSBwcm9kdWN0LmJhcmNvZGU7XG4gICAgICBwLmJhcmNvZGVzID0gcHJvZHVjdC5iYXJjb2RlcztcbiAgICAgIHAuZGVzY3JpcHRpb24gPSBwcm9kdWN0LmRlc2NyaXB0aW9uO1xuICAgICAgcC5pdGVtTGluZUlkID0gcHJvZHVjdC5pdGVtTGluZUlkID8gcHJvZHVjdC5pdGVtTGluZUlkLnRvU3RyaW5nKCkgOiBcIlwiICsgKGluZGV4ICsgMSk7XG4gICAgICBwLnByaWNlID0gcHJvZHVjdC5zZWxlY3RlZFByaWNlO1xuICAgICAgcC5xdWFudGl0eSA9IHByb2R1Y3QucXVhbnRpdHk7XG4gICAgICBwLnRvdGFsTGluZVByaWNlID0gcHJvZHVjdC5xdWFudGl0eSAqIHByb2R1Y3Quc2VsZWN0ZWRQcmljZTtcbiAgICAgIHAuaW1hZ2VVcmxzID0gcHJvZHVjdC5pbWFnZVVybHM7XG4gICAgICBwLnNlbGVjdGVkUlJQUHJpY2UgPSBwcm9kdWN0LnNlbGVjdGVkUlJQUHJpY2U7XG5cbiAgICAgIC8vaW52ZW50b3J5IGZpZWxkc1xuICAgICAgXG4gICAgICBwLmZ1bGxmaWxtZW50SWQgPSBwcm9kdWN0LmZ1bGxmaWxtZW50SWQ/IHByb2R1Y3QuZnVsbGZpbG1lbnRJZDogdGhpcy5zdG9yZUluZm8uc3RvcmVJZDtcblxuICAgICAgcC5mdWxsZmlsbWVudExvY2F0aW9uTmFtZSA9IHByb2R1Y3QuZnVsbGZpbG1lbnRMb2NhdGlvbk5hbWU7XG4gICAgICBwLmRlbGl2ZXJ5R3JvdXAgPSBwcm9kdWN0LmRlbGl2ZXJ5R3JvdXA7XG4gICAgICBwLmxlYWRUaW1lID0gcHJvZHVjdC5sZWFkVGltZTtcbiAgICAgIHAuZGVsaXZlcnlNZXRob2QgPSBwcm9kdWN0LmRlbGl2ZXJ5TWV0aG9kO1xuXG4gICAgICBwLmdpZnRDYXJkID0gcHJvZHVjdC5naWZ0Q2FyZDtcbiAgICAgIHAuZ2lmdENhcmRFeHBpcnlEYXRlID0gcHJvZHVjdC5naWZ0Q2FyZEV4cGlyeURhdGU7XG4gICAgICBwLmdpZnRDYXJkTnVtYmVySXNzdWVkID0gcHJvZHVjdC5naWZ0Q2FyZE51bWJlcklzc3VlZDtcbiAgICAgIHAuZ2lmdENhcmRSZWNpcGllbnRFbWFpbCA9IHByb2R1Y3QuZ2lmdENhcmRSZWNpcGllbnRFbWFpbDtcbiAgICAgIHAuZ2lmdENhcmRSZWNpcGllbnROYW1lID0gcHJvZHVjdC5naWZ0Q2FyZFJlY2lwaWVudE5hbWU7XG5cbiAgICAgIGlmIChwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHkgPiAwKSB7XG4gICAgICAgIHAucmVmdW5kZWRRdWFudGl0eSA9IHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eTtcbiAgICAgICAgcC5yZWZ1bmRlZFByb21vdGlvbmFsUXVhbnRpdHkgPSBwcm9kdWN0LnJlZnVuZFByb21vdGlvbmFsUXVhbnRpdHk7XG4gICAgICAgIHAucmVmdW5kZWQgPSBwcm9kdWN0LnJlZnVuZGVkO1xuICAgICAgICBwLnJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb24gPSBwcm9kdWN0LnJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb247XG4gICAgICAgIHAucmVmdW5kZWRSZWFzb24gPSBwcm9kdWN0LnJlZnVuZGVkUmVhc29uO1xuICAgICAgICBpZiAoIXAucmVmdW5kZWRSZWFzb25EZXNjcmlwdGlvbikge1xuICAgICAgICAgIHAucmVmdW5kZWRSZWFzb25EZXNjcmlwdGlvbiA9IHAucmVmdW5kZWRSZWFzb247XG4gICAgICAgIH1cbiAgICAgICAgcC5yZWZ1bmRlZFRvdGFsID0gcHJvZHVjdC5yZWZ1bmRlZFRvdGFsO1xuICAgICAgICBwLmlzTGFzdEV4Y2hhbmdlZCA9IHByb2R1Y3QuaXNMYXN0RXhjaGFuZ2VkO1xuICAgICAgfVxuXG4gICAgICBpZiAocHJvZHVjdC5leGNoYW5nZSkge1xuICAgICAgICBwLmV4Y2hhbmdlID0gcHJvZHVjdC5leGNoYW5nZTtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0LmxpbmVEaXNjb3VudCkge1xuICAgICAgICBwLmxpbmVEaXNjb3VudCA9IHByb2R1Y3QubGluZURpc2NvdW50O1xuICAgICAgfVxuICAgICAgcC5pdGVtRGlzY291bnRzID0gcHJvZHVjdC5pdGVtRGlzY291bnRzIGFzIEl0ZW1EaXNjb3VudHM7XG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnByb2R1Y3RzLnB1c2gocCk7XG4gICAgICB0aGlzLmxpbmVEaXNjb3VudChiYXNrZXREZXRhaWxzKTtcbiAgICB9KTtcbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0luZm8odGhpcy5jbGFzc05hbWUsIFwiYmFza2V0XCIsIFwidHJhbnNhY3Rpb25kb2N1bWVudCBiYXNrZXQgZGV0YWlscyB1cGRhdGVkXCIsIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICAgKiBjdXJyZW50IHRyYW5zYWN0aW9uIERldGFpbHMgVG90YWwoTmV3IFByb2R1Y3RzKVxuICAgICAqIEByZXR1cm5zIGN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNcbiAgICAgKi9cblxuICBjdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzKGJhc2tldDogQmFza2V0KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwiY3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc1wiLCBcImN1cnJlbnQgdHJhbnNhY3Rpb24gZGV0YWlscyBmb3IgZXhjaGFuZ2VzXCIsIGJhc2tldCk7XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMucHJvZHVjdHMgPSBbXSBhcyBQcm9kdWN0W107XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMubGluZVByb21vdGlvbiA9IFtdIGFzIExpbmVQcm9tb3Rpb25zW107XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMubGluZURpc2NvdW50ID0gW10gYXMgTGluZURpc2NvdW50W107XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudCA9IFtdO1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnByb2R1Y3RzID0gYmFza2V0LnByb2R1Y3RzO1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnByb2R1Y3RzID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMucHJvZHVjdHMuZmlsdGVyKFxuICAgICAgKCAgICAgIHByb2o6IHsgcmVmdW5kZWRRdWFudGl0eTogbnVtYmVyOyB9KSA9PiBwcm9qLnJlZnVuZGVkUXVhbnRpdHkgIT0gMFxuICAgICk7XG5cbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5wcm9kdWN0cy5mb3JFYWNoKChwcm9kdWN0OiB7IHJlZnVuZGVkUXVhbnRpdHk6IGFueTsgcXVhbnRpdHk6IGFueTsgdG90YWxMaW5lUHJpY2U6IG51bWJlcjsgcmVmdW5kZWRUb3RhbDogbnVtYmVyOyB0b3RhbDogYW55OyByZWZ1bmRlZDogYm9vbGVhbjsgbGluZVByb21vdGlvbnM6IGFueTsgbGluZURpc2NvdW50OiBhbnk7IH0pID0+IHtcbiAgICAgIGlmIChwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHkpIHtcbiAgICAgICAgcHJvZHVjdC5xdWFudGl0eSA9IHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eTtcbiAgICAgICAgLy8gdXBkYXRpbmcgdG90YWwgbGluZSBwcmljZSB3aXRoIGFjdHVhbCBwcmljZSB0byBiZSByZWZ1bmRlZCBpbmNsdWRpbmcgdGhlIHJlZnVuZGluZyBxdHlcbiAgICAgICAgcHJvZHVjdC50b3RhbExpbmVQcmljZSA9IE1hdGguYWJzKHByb2R1Y3QucmVmdW5kZWRUb3RhbCk7XG4gICAgICAgIHByb2R1Y3QudG90YWwgPSBwcm9kdWN0LnRvdGFsTGluZVByaWNlO1xuICAgICAgICBpZiAocHJvZHVjdC5xdWFudGl0eSA9PT0gcHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5KSB7XG4gICAgICAgICAgcHJvZHVjdC5yZWZ1bmRlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vVXBkYXRpbmcgbGluZSBwcm9tb3Rpb25zIGFuZCBsaW5lIGRpc2NvdW50cyAgICAgIFxuICAgICAgaWYgKHByb2R1Y3QubGluZVByb21vdGlvbnMgJiYgIXByb2R1Y3QucmVmdW5kZWRRdWFudGl0eSkge1xuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5saW5lUHJvbW90aW9uLnB1c2gocHJvZHVjdC5saW5lUHJvbW90aW9ucylcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0LmxpbmVEaXNjb3VudCAmJiAhcHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5KSB7XG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmxpbmVEaXNjb3VudC5wdXNoKHByb2R1Y3QubGluZURpc2NvdW50KVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJjdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzXCIsIFwiY3VycmVudCB0cmFuc2FjdGlvbiBkZXRhaWxzIGFmdGVyIHJlbW92aW5nIG9sZCBwcm9kdWN0c1wiLCB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5wcm9kdWN0cyk7XG5cbiAgICBpZiAoYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQgJiYgYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudC5wdXNoKC4uLmJhc2tldC50cmFuc2FjdGlvbkRpc2NvdW50KTtcbiAgICB9XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeSA9IHt9IGFzIEJhc2tldFN1bW1hcnk7XG5cbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LnNhbGVUb3RhbCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRoaXMudXBkYXRlU2FsZVRvdGFsKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzKSk7XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS50b3RhbEl0ZW1zID0gYmFza2V0LnF1YW50aXR5O1xuXG5cbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsID0gYmFza2V0LmJhc2tldFRvdGFsO1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmJhc2tldFN1bW1hcnkucmVmdW5kVG90YWwgPSB0aGlzLnVwZGF0ZUN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNSZWZ1bmRUb3RhbCgpO1xuICAgIC8vIEZvciBwYXJ0aWFsIHJlZnVuZCBkaXNjb3VudCBpcyB1cGRhdGllZCBpbiB0b3RhbCBsaW5lIHByaWNlIHNvIGRpc2NvdW50VG90YWwgd2lsbCBhbHdheXMgYmUgemVybyAmIGluIGNhc2Ugb2YgZXhjaGFuZ2UgZGlzY291bnQgdG90YWwgaXMgY2FsY3VsYXRlZFxuXG4gICAgaWYgKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC50eXBlID09PSBUUkFOU0FDVElPTl9UWVBFLlNBTEVfRVhDSEFOR0UpIHtcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmJhc2tldFN1bW1hcnkuZGlzY291bnRUb3RhbCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRoaXMudXBkYXRlQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc0Rpc2NvdW50VG90YWwoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy50cmFuc2FjdGlvbkRpc2NvdW50ICYmIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQubGVuZ3RoID4gMCkge1xuICAgICAgICBsZXQgZGlzY291bnRUb3RhbCA9IDA7XG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQuZm9yRWFjaCgoZGlzY291bnQ6IHsgZGlzY291bnRBbW91bnQ6IG51bWJlcjsgfSkgPT4ge1xuICAgICAgICAgIGRpc2NvdW50VG90YWwgKz0gZGlzY291bnQuZGlzY291bnRBbW91bnQ7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LmRpc2NvdW50VG90YWwgPSBNYXRoLmFicyhkaXNjb3VudFRvdGFsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmJhc2tldFN1bW1hcnkuZGlzY291bnRUb3RhbCA9IDA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgQXBwTG9nZ2VyU2VydmljZS5sb2dJbmZvKHRoaXMuY2xhc3NOYW1lLCBcImN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNcIiwgXCJjdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzXCIsIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG5cbiAgLyoqXG4gKiBjdXJyZW50IHRyYW5zYWN0aW9uIFRheCBUb3RhbFxuICogQHJldHVybnMgVGF4IFRvdGFsXG4gKi9cblxuICB1cGRhdGVDdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzVGF4QnJlYWtkb3duKGJhc2tldERldGFpbHM6IEJhc2tldCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICBsZXQgdHJhbnNhY3Rpb25EaXNjb3VudFRvdGFsID0gMDtcbiAgICBsZXQgdGF4QnJlYWtkb3duOiBUYXhCcmVha2Rvd24gPSB7XG4gICAgICB0YXhMaW5lczogW10sXG4gICAgICB0b3RhbFRheGFibGVBbW91bnQ6IDAsXG4gICAgfTtcblxuICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy50cmFuc2FjdGlvbkRpc2NvdW50ICYmIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudC5mb3JFYWNoKChkaXNjb3VudDogeyBkaXNjb3VudEFtb3VudDogbnVtYmVyOyB9KSA9PiB7XG4gICAgICAgIHRyYW5zYWN0aW9uRGlzY291bnRUb3RhbCArPSBkaXNjb3VudC5kaXNjb3VudEFtb3VudDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5wcm9kdWN0cyAmJiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5wcm9kdWN0cy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5wcm9kdWN0cy5mb3JFYWNoKChwcm9kdWN0OiB7IGl0ZW1MaW5lSWQ6IGFueTsgc2VsZWN0ZWRWQVQ6IGFueTsgc2VsZWN0ZWRWQVRDb2RlOiBhbnk7IHRvdGFsOiBhbnk7IHJlZnVuZGVkUXVhbnRpdHk6IG51bWJlcjsgaXRlbURpc2NvdW50czogeyBjdXJyZW50UmVmdW5kUG9ydGlvbjogbnVtYmVyOyB0cm5EaXNjb3VudHNQb3J0aW9uOiBudW1iZXI7IHRyblByb21vdGlvbnNQb3J0aW9uOiBudW1iZXI7IH07IH0pID0+IHtcbiAgICAgICAgbGV0IHRheExpbmU6IFRheExpbmUgPSB7XG4gICAgICAgICAgaXRlbUxpbmVJZDogcHJvZHVjdC5pdGVtTGluZUlkLFxuICAgICAgICAgIFZBVDogcHJvZHVjdC5zZWxlY3RlZFZBVCA/IHByb2R1Y3Quc2VsZWN0ZWRWQVQgOiAwLFxuICAgICAgICAgIFZBVENvZGU6IHByb2R1Y3Quc2VsZWN0ZWRWQVRDb2RlLFxuICAgICAgICAgIHRheExpbmVUb3RhbDogMCxcbiAgICAgICAgICB0YXhhYmxlQW1vdW50OiBwcm9kdWN0LnRvdGFsLFxuICAgICAgICAgIFByZVRheDogMFxuXG4gICAgICAgIH07XG4gICAgICAgIEFwcExvZ2dlclNlcnZpY2UubG9nSW5mbyh0aGlzLmNsYXNzTmFtZSwgXCJ1cGRhdGVDdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzVGF4QnJlYWtkb3duXCIsIGBpdGVtIGxpbmUgSUQgOmN1cnJlbnQgdHJhbnNhY3Rpb24gRGV0YWlsc1wiLFxuICAgICAgICAgICR7cHJvZHVjdC5pdGVtTGluZUlkfSwgdGF4IGxpbmUgOiAke3RheExpbmV9LCBiYXNrZXREZXRhaWxzLmJhc2tldFRvdGFsICR7YmFza2V0RGV0YWlscy5iYXNrZXRUb3RhbH1gKTtcblxuICAgICAgICAvL3N0ZXAgMVxuICAgICAgICAvLyBpZiBUcmFuc2FjdGlvbiBEaXNjb3VudCBhbmQvb3IgcHJvbW90aW9uIGFwcGxpZWQsIGZpbmQgbmV0IHNlbGxpbmcgcHJpY2Ugb2YgZWFjaCBwcm9kdWN0IGFzIHRheGFibGVhbW91bnRcblxuICAgICAgICAvL0lmIHRyYW5zYWN0aW9uIGRpc2NvdW50L3Byb21vdGlvbiBpcyBhcHBsaWVkIHRheGFibGUgYW1vdW50IHNob3VsZCBiZSBkZWR1Y3RpbmcgdHJhbnNhY3Rpb24gcHJvbW90aW9uIGFuZCB0cmFuc2FjdGlvbiBkaXNhY291bnQgcG9ydGlvblxuICAgICAgICBpZiAocHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5ICYmIHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eSA+IDApIHtcblxuICAgICAgICAgIHRheExpbmUudGF4YWJsZUFtb3VudCA9IC1NYXRoLmFicyh0YXhMaW5lLnRheGFibGVBbW91bnQgLSBwcm9kdWN0Lml0ZW1EaXNjb3VudHMuY3VycmVudFJlZnVuZFBvcnRpb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRheExpbmUudGF4YWJsZUFtb3VudCA9IHRheExpbmUudGF4YWJsZUFtb3VudCAtIHByb2R1Y3QuaXRlbURpc2NvdW50cy50cm5EaXNjb3VudHNQb3J0aW9uIC0gcHJvZHVjdC5pdGVtRGlzY291bnRzLnRyblByb21vdGlvbnNQb3J0aW9uO1xuICAgICAgICB9XG5cbiAgICAgICAgLy9zdGVwIDIgLSBmaW5kIHByZSB0YXhcbiAgICAgICAgdGF4TGluZS5QcmVUYXggPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMigodGF4TGluZS50YXhhYmxlQW1vdW50ICogMTAwKSAvICgxMDAgKyB0YXhMaW5lLlZBVCkpO1xuXG4gICAgICAgIC8vc3RlcCAzIC0gVXBkYXRlIHRheGJyZWFrZG93blxuICAgICAgICB0YXhCcmVha2Rvd24udG90YWxUYXhhYmxlQW1vdW50ICs9IHRheExpbmUudGF4YWJsZUFtb3VudDtcbiAgICAgICAgdGF4TGluZS50YXhhYmxlQW1vdW50ID0gdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIodGF4TGluZS50YXhhYmxlQW1vdW50KTtcbiAgICAgICAgXG4gICAgICAgIC8vIHN0ZXAgNCAtIHVwZGF0ZSB0YXggTGluZSB0b3RhbFxuICAgICAgICB0YXhMaW5lLnRheExpbmVUb3RhbCA9ICB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMih0YXhMaW5lLnRheGFibGVBbW91bnQgLSB0YXhMaW5lLlByZVRheCk7XG4gICAgICAgIHRheEJyZWFrZG93bi50YXhMaW5lcy5wdXNoKHRheExpbmUpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGF4QnJlYWtkb3duLnRvdGFsVGF4YWJsZUFtb3VudCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRheEJyZWFrZG93bi50b3RhbFRheGFibGVBbW91bnQpO1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRheEJyZWFrZG93biA9IHRheEJyZWFrZG93bjtcbiAgICBpZiAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMudGF4QnJlYWtkb3duICYmIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRheEJyZWFrZG93bi50YXhMaW5lcyAmJiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy50YXhCcmVha2Rvd24udGF4TGluZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS5WQVRUb3RhbCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRheEJyZWFrZG93bi50YXhMaW5lcy5yZWR1Y2UoXG4gICAgICAgIChuOiBhbnksIHsgdGF4TGluZVRvdGFsIH06IGFueSkgPT4gbiArIHRheExpbmVUb3RhbCxcbiAgICAgICAgMFxuICAgICAgKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS5WQVRUb3RhbCA9IDAuMDA7XG4gICAgfVxuXG4gICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJ1cGRhdGVDdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzVGF4QnJlYWtkb3duXCIsIFwiZUJhc2tldDphZnRlciBjYWxjdWxhdGluZyB0YXggY3VycmVudHRyYW5zYWN0aW9uRGV0YWlsc1wiLCB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscylcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHVwZGF0ZUN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNUb3RhbFRheFN1bW1hcnkoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICBcbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcInVwZGF0ZUN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNUb3RhbFRheFN1bW1hcnlcIiwgXCJUb3RhbCBUYXggU3VtbWVyeSBSZXF1ZXN0IDpcIiwgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMudGF4QnJlYWtkb3duKTtcblxuICAgIGxldCB0b3RhbFRheFN1bW1hcnlBcnJheTogVG90YWxUYXhTdW1tYXJ5W10gPSBbXVxuICAgIGxldCB0b3RhbFRheFN1bW1hcnlHcm91cCA9IFtdXG5cblxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRheEJyZWFrZG93bi50YXhMaW5lcy5mb3JFYWNoKChlbGVtZW50OiB7IFZBVENvZGU6IGFueTsgVkFUOiBhbnk7IFByZVRheDogYW55OyB0YXhMaW5lVG90YWw6IGFueTsgfSkgPT4ge1xuICAgICAgbGV0IFRheFN1bW1hcnk6IFRvdGFsVGF4U3VtbWFyeSA9IHtcbiAgICAgICAgVkFUQ29kZTpcIlwiLFxuICAgICAgICBWQVQ6IC0xMjM0NSxcbiAgICAgICAgUHJlVGF4U3VtOiAwLFxuICAgICAgICBUYXhTdW06IDAsXG4gICAgICAgIFRYcmF0ZVN1bTogMFxuICAgICAgfTtcbiAgICAgICAgVGF4U3VtbWFyeS5WQVRDb2RlPWVsZW1lbnQuVkFUQ29kZTtcbiAgICAgICAgVGF4U3VtbWFyeS5WQVQgPSBlbGVtZW50LlZBVDsgICAgICAgIFxuICAgICAgIFxuICAgICAgICBUYXhTdW1tYXJ5LlByZVRheFN1bSA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKGVsZW1lbnQuUHJlVGF4KTsgICAgICAgIFxuICAgICAgICBUYXhTdW1tYXJ5LlRheFN1bSA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKGVsZW1lbnQudGF4TGluZVRvdGFsKTtcbiAgICAgICAgVGF4U3VtbWFyeS5UWHJhdGVTdW0gPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMihUYXhTdW1tYXJ5LlByZVRheFN1bSArIFRheFN1bW1hcnkuVGF4U3VtKTsgICAgIFxuICAgICAgICB0b3RhbFRheFN1bW1hcnlBcnJheS5wdXNoKFRheFN1bW1hcnkpO1xuICAgIH0pXG5cbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcInVwZGF0ZUN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNUb3RhbFRheFN1bW1hcnlcIiwgXCJUb3RhbCBUYXggU3VtbWVyeSAgV2l0aG91dCBHcm91cGVkIDogXCIsIHRvdGFsVGF4U3VtbWFyeUFycmF5KTtcbiAgICBcbiAgICB0b3RhbFRheFN1bW1hcnlHcm91cCA9IHRvdGFsVGF4U3VtbWFyeUFycmF5LnJlZHVjZSgocHJlcGFyZWRBcnJheTphbnksY3VycmVudE9iajphbnkpID0+IHtcbiAgICAgIGxldCBpbmQgPSBwcmVwYXJlZEFycmF5LmZpbmRJbmRleCgoeDogeyBWQVQ6IGFueTsgfSkgPT4geC5WQVQgPT09IGN1cnJlbnRPYmouVkFUKTtcbiAgICAgIGlmKGluZCA9PT0gLTEpe1xuICAgICAgICBwcmVwYXJlZEFycmF5LnB1c2goY3VycmVudE9iailcbiAgICAgIH1lbHNlIHtcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlZBVENvZGUgPSBjdXJyZW50T2JqLlZBVENvZGU7XG4gICAgICAgIHByZXBhcmVkQXJyYXlbaW5kXS5WQVQgPSBjdXJyZW50T2JqLlZBVDtcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlByZVRheFN1bSArPSBjdXJyZW50T2JqLlByZVRheFN1bTtcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlRheFN1bSArPSBjdXJyZW50T2JqLlRheFN1bTtcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlRYcmF0ZVN1bSArPSBjdXJyZW50T2JqLlRYcmF0ZVN1bTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwcmVwYXJlZEFycmF5O1xuICAgIH0sW10pXG4gICAgLy8gbGlzdE9mVGFncy5tYXAoeCA9PiB1bmlxdWUuZmlsdGVyKGEgPT4gYS5sYWJlbCA9PSB4LmxhYmVsICYmIGEuY29sb3IgPT0geC5jb2xvcikubGVuZ3RoID4gMCA/IG51bGwgOiB1bmlxdWUucHVzaCh4KSk7XG5cbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcInVwZGF0ZUN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHNUb3RhbFRheFN1bW1hcnlcIiwgXCJUb3RhbCAgVGF4IFN1bW1lciBHcm91cCA6XCIsIHRvdGFsVGF4U3VtbWFyeUdyb3VwKTtcblxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnRvdGFsVGF4U3VtbWFyeSA9IHRvdGFsVGF4U3VtbWFyeUdyb3VwO1xuICAgIHJldHVybiB0aGlzO1xuXG4gIH1cblxuICAvKipcbiAgICogY3VycmVudCB0cmFuc2FjdGlvbiBEaXNvY3VudCBUb3RhbFxuICAgKiBAcmV0dXJucyBEaXNjb3VudCBUb3RhbFxuICAgKi9cbiAgdXBkYXRlQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc0Rpc2NvdW50VG90YWwoKSB7XG4gICAgbGV0IHJlZnVuZFRvdGFsID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS5yZWZ1bmRUb3RhbCA/IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmJhc2tldFN1bW1hcnkucmVmdW5kVG90YWwgOiAwO1xuXG4gICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJ1cGRhdGVDdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzRGlzY291bnRUb3RhbFwiLCAgYHJlZnVuZFRvdGFsICR7cmVmdW5kVG90YWx9LCBiYXNrZXRUb3RhbCAke3RoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLmJhc2tldFN1bW1hcnkuYmFza2V0VG90YWx9LHNhbGVUb3RhbCAgJHt0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LnNhbGVUb3RhbH1gKTtcbiAgICBjb25zdCBkaXNjb3VudFRvdGFsID1cbiAgICAgIE1hdGguYWJzKFxuICAgICAgICBNYXRoLmFicyh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VycmVudFRyYW5zYWN0aW9uRGV0YWlscy5iYXNrZXRTdW1tYXJ5LnNhbGVUb3RhbCkgLVxuICAgICAgICAoTWF0aC5hYnModGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1cnJlbnRUcmFuc2FjdGlvbkRldGFpbHMuYmFza2V0U3VtbWFyeS5iYXNrZXRUb3RhbCkgKyBNYXRoLmFicyhyZWZ1bmRUb3RhbCkpXG4gICAgICApO1xuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwidXBkYXRlQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc0Rpc2NvdW50VG90YWxcIiwgXCJkaXNjb3VudFRvdGFsXCIsIGRpc2NvdW50VG90YWwpXG4gICAgcmV0dXJuIE51bWJlcihkaXNjb3VudFRvdGFsLnRvRml4ZWQoMikpO1xuICB9XG5cbiAgLyoqXG4gICogY3VycmVudCB0cmFuc2FjdGlvbiBSZWZ1bmQgVG90YWxcbiAgKiBAcmV0dXJucyBSZWZ1bmQgVG90YWxcbiAgKi9cbiAgdXBkYXRlQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc1JlZnVuZFRvdGFsKCkge1xuICAgIGxldCB0b3RhbFJlZnVuZCA9IDA7XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnByb2R1Y3RzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgY29uc3QgcHJvZHVjdDogUHJvZHVjdCA9IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXJyZW50VHJhbnNhY3Rpb25EZXRhaWxzLnByb2R1Y3RzW2luZGV4XTtcbiAgICAgIGlmIChwcm9kdWN0LnJlZnVuZGVkVG90YWwpIHtcbiAgICAgICAgdG90YWxSZWZ1bmQgPSB0b3RhbFJlZnVuZCArIHByb2R1Y3QucmVmdW5kZWRUb3RhbDtcbiAgICAgIH1cbiAgICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwidXBkYXRlQ3VycmVudFRyYW5zYWN0aW9uRGV0YWlsc1JlZnVuZFRvdGFsXCIsIFwidG90YWxSZWZ1bmQgZm9yIEN1cnJlbnQgVHJhbnNhY3Rpb25EZXRhaWxzXCIgLCB0b3RhbFJlZnVuZClcbiAgICB9XG4gICAgcmV0dXJuIHRvdGFsUmVmdW5kO1xuICB9XG5cblxuXG4gIC8qKlxuICAgKiBCYXNrZXRzIHN1bW1hcnlcbiAgICogQHBhcmFtIGJhc2tldERldGFpbHNcbiAgICogQHJldHVybnMgc3VtbWFyeVxuICAgKi9cbiAgYmFza2V0U3VtbWFyeShiYXNrZXREZXRhaWxzOiBCYXNrZXQpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuYmFza2V0VG90YWwgPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsKGJhc2tldERldGFpbHMuYmFza2V0VG90YWwpO1xuXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuc2FsZVRvdGFsID0gdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIodGhpcy51cGRhdGVTYWxlVG90YWwoXG4gICAgICBiYXNrZXREZXRhaWxzXG4gICAgKSk7XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkucmVmdW5kVG90YWwgPSB0aGlzLmdldFJlZnVuZFRvdGFsKCk7XG4gICAgaWYgKFxuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnQgfHxcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvblxuICAgICkge1xuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuZGlzY291bnRUb3RhbCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRoaXMudXBkYXRlRGlzY291bnRUb3RhbCgpKTtcbiAgICB9XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkudG90YWxJdGVtcyA9IGJhc2tldERldGFpbHMucXVhbnRpdHk7XG5cblxuICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRheEJyZWFrZG93bikge1xuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuVkFUVG90YWwgPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMih0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRheEJyZWFrZG93bi50YXhMaW5lcy5yZWR1Y2UoXG4gICAgICAgIChuOiBhbnksIHsgdGF4TGluZVRvdGFsIH06IGFueSkgPT4gbiArIHRheExpbmVUb3RhbCxcbiAgICAgICAgMFxuICAgICAgKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuVkFUVG90YWwgPSAwLjAwO1xuICAgIH1cblxuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nSW5mbyh0aGlzLmNsYXNzTmFtZSwgXCJiYXNrZXRTdW1tYXJ5XCIsIFwiYmFza2V0c3VtbWFyeSB1cGRhdGVkIGluIHRyYW5zYWN0aW9uIGRvY3VtZW50OiBcIiwgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIExpbmUgRGlzY291bnRcbiAgICogQHBhcmFtIGJhc2tldERldGFpbHNcbiAgICogQHJldHVybnMgbGluZSBEaXNjb3VudFxuICAgKi9cbiAgbGluZURpc2NvdW50KGJhc2tldERldGFpbHM6IEJhc2tldCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudCA9IFtdO1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBiYXNrZXREZXRhaWxzLnByb2R1Y3RzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGJhc2tldERldGFpbHMucHJvZHVjdHNbaW5kZXhdO1xuICAgICAgaWYgKGVsZW1lbnQubGluZURpc2NvdW50KSB7XG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50LnB1c2goZWxlbWVudC5saW5lRGlzY291bnQpO1xuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudCA9IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50LnJlZHVjZShcbiAgICAgICAgICAoYWNjOiBhbnlbXSwgdmFsOiB7IGl0ZW1MaW5lSWQ6IGFueTsgfSkgPT4ge1xuICAgICAgICAgICAgaWYgKCFhY2MuZmluZCgoZWw6IHsgaXRlbUxpbmVJZDogYW55OyB9KSA9PiBlbC5pdGVtTGluZUlkID09PSB2YWwuaXRlbUxpbmVJZCkpIHtcbiAgICAgICAgICAgICAgYWNjLnB1c2godmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBbXVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0luZm8odGhpcy5jbGFzc05hbWUsIFxuICAgICAgLy8gICBcImUtYmFza2V0IDpsaW5lIGRpc2NvdW50IHVwZGF0ZWQgaW4gdHJhbnNhY3Rpb24gZG9jdW1lbnRcIixcbiAgICAgIC8vICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnRcbiAgICAgIC8vICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIGV4Y2hhbmdlXG4gICAqIEBwYXJhbSBiYXNrZXREZXRhaWxzXG4gICAqIEByZXR1cm5zIGV4Y2hhbmdlIFxuICAgKi9cbiAgZXhjaGFuZ2UoYmFza2V0RGV0YWlsczogQmFza2V0KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQuZXhjaGFuZ2UgPSBiYXNrZXREZXRhaWxzLmV4Y2hhbmdlICYmIGJhc2tldERldGFpbHMuZXhjaGFuZ2UubGVuZ3RoID4gMCA/IFsuLi5iYXNrZXREZXRhaWxzLmV4Y2hhbmdlXSA6IFtdO1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBiYXNrZXREZXRhaWxzLnByb2R1Y3RzLmxlbmd0aDsgaW5kZXgrKykge1xuXG4gICAgICBjb25zdCBlbGVtZW50OiBhbnkgPSBiYXNrZXREZXRhaWxzLnByb2R1Y3RzW2luZGV4XTtcbiAgICAgIGlmIChlbGVtZW50LmV4Y2hhbmdlICE9IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCBpc1ByZXNlbnQgPSB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmV4Y2hhbmdlLnNvbWUoKGVsOiB7IGV4Y2hhbmdlSWQ6IGFueTsgfSkgPT4gZWwuZXhjaGFuZ2VJZCA9PT0gZWxlbWVudC5leGNoYW5nZS5leGNoYW5nZUlkKTtcbiAgICAgICAgaWYgKCFpc1ByZXNlbnQpIHtcbiAgICAgICAgICBsZXQgZXhjaGFuZ2VJdGVtcyA9IFtdO1xuICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgZWxlbWVudC5leGNoYW5nZS5uZXdJdGVtcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgY29uc3QgaXRlbSA9IGVsZW1lbnQuZXhjaGFuZ2UubmV3SXRlbXNbal07XG4gICAgICAgICAgICBsZXQgbmV3SXRlbXM6IGFueSA9IHsgbGluZUl0ZW1JZDogaXRlbS5pdGVtTGluZUlkLCBRdWFudGl0eTogaXRlbS5xdWFudGl0eSB9XG4gICAgICAgICAgICBleGNoYW5nZUl0ZW1zLnB1c2gobmV3SXRlbXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbGVtZW50LmV4Y2hhbmdlLm5ld0l0ZW1zID0gWy4uLmV4Y2hhbmdlSXRlbXNdO1xuICAgICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQuZXhjaGFuZ2UucHVzaChlbGVtZW50LmV4Y2hhbmdlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJleGNoYW5nZVwiLFxuICAgICAgICBcInRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQgZXhjaGFuZ2VcIixcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5leGNoYW5nZVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAqIGFkZCBwcmV2aW91cyBleGNoYW5nZSBkYXRhXG4gICogQHBhcmFtIG9yaWdpbmFsVHJhbnNhY3Rpb25Eb2N1bWVudFxuICAqIEByZXR1cm5zIGxpbmUgUHJvbW90aW9uc1xuICAqL1xuICBhZGRFeGNoYW5nZURhdGEob3JpZ2luYWxUcmFuc2FjdGlvbkRvY3VtZW50OiBUcmFuc2FjdGlvbkRvY3VtZW50KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQuZXhjaGFuZ2UgPSBvcmlnaW5hbFRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmV4Y2hhbmdlID8gWy4uLm9yaWdpbmFsVHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQuZXhjaGFuZ2VdIDogbnVsbDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBsaW5lIFByb21vdGlvbnNcbiAgICogQHBhcmFtIGJhc2tldERldGFpbHNcbiAgICogQHJldHVybnMgbGluZSBQcm9tb3Rpb25zXG4gICAqL1xuICBsaW5lUHJvbW90aW9uKGJhc2tldERldGFpbHM6IEJhc2tldCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb24gPSBbXTtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgYmFza2V0RGV0YWlscy5wcm9kdWN0cy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBiYXNrZXREZXRhaWxzLnByb2R1Y3RzW2luZGV4XTtcbiAgICAgIGlmIChlbGVtZW50LmxpbmVQcm9tb3Rpb25zKSB7XG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbi5wdXNoKFxuICAgICAgICAgIGVsZW1lbnQubGluZVByb21vdGlvbnNcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lUHJvbW90aW9uID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lUHJvbW90aW9uLnJlZHVjZShcbiAgICAgICAgICAoYWNjOiBhbnlbXSwgdmFsOiB7IGl0ZW1MaW5lSWQ6IGFueTsgfSkgPT4ge1xuICAgICAgICAgICAgaWYgKCFhY2MuZmluZCgoZWw6IHsgaXRlbUxpbmVJZDogYW55OyB9KSA9PiBlbC5pdGVtTGluZUlkID09PSB2YWwuaXRlbUxpbmVJZCkpIHtcbiAgICAgICAgICAgICAgYWNjLnB1c2godmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBbXVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiB0cmFuc2FjdGlvbiBQcm9tb3Rpb25cbiAgICogQHBhcmFtIGJhc2tldERldGFpbHNcbiAgICogQHJldHVybnMgdHJhbnNhY3Rpb24gUHJvbW90aW9uXG4gICAqL1xuICB0cmFuc2FjdGlvblByb21vdGlvbihiYXNrZXREZXRhaWxzOiBCYXNrZXQpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XG4gICAgaWYgKGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25Qcm9tb3Rpb24pIHtcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb24gPVxuICAgICAgICBiYXNrZXREZXRhaWxzLnRyYW5zYWN0aW9uUHJvbW90aW9uO1xuICAgICAgLy8gICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgYmFza2V0RGV0YWlscy5UcmFuc2FjdGlvbkRpc2NvdW50Lmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgLy8gICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uLnB1c2goZWxlbWVudC5saW5lUHJvbW90aW9ucylcbiAgICAgIC8vICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50cmFuc2FjdGlvblByb21vdGlvbiA9ICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb25zLnJlZHVjZSgoYWNjLCB2YWwpID0+IHtcbiAgICAgIC8vICAgICBpZiAoIWFjYy5maW5kKGVsID0+IGVsLml0ZW1MaW5lSWQgPT09IHZhbC5pdGVtTGluZUlkKSkge1xuICAgICAgLy8gICAgICAgYWNjLnB1c2godmFsKTtcbiAgICAgIC8vICAgICB9XG4gICAgICAvLyAgICAgcmV0dXJuIGFjYztcbiAgICAgIC8vICAgfSwgW10pO1xuICAgICAgLy8gfVxuICAgICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJ0cmFuc2FjdGlvblByb21vdGlvblwiLFxuICAgICAgICBcInRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb25cIixcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50cmFuc2FjdGlvblByb21vdGlvblxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB0cmFuc2FjdGlvbkRpc2NvdW50KGJhc2tldERldGFpbHM6IEJhc2tldCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICBpZiAoYmFza2V0RGV0YWlscy50cmFuc2FjdGlvbkRpc2NvdW50KSB7XG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQgPVxuICAgICAgICBiYXNrZXREZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQ7XG5cbiAgICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwidHJhbnNhY3Rpb25EaXNjb3VudFwiLFxuICAgICAgICBcInRyYW5zYWN0aW9uIERpc2NvdW50XCIsXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25EaXNjb3VudFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogUGF5bWVudHMgZGV0YWlsc1xuICAgKiBAcGFyYW0gcGF5bWVudERldGFpbHNcbiAgICogQHJldHVybnNcbiAgICovXG4gIHBheW1lbnREZXRhaWxzKHBheW1lbnREZXRhaWxzOiBhbnkpIHtcbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0luZm8odGhpcy5jbGFzc05hbWUsIFwicGF5bWVudERldGFpbHNcIiwgXCJwYXltZW50IGRldGFpbHMgYWZ0ZXIgdHJhbnNhY3Rpb24gY29tcGxldGVkXCIscGF5bWVudERldGFpbHMpO1xuICAgIFxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5wYXltZW50RGV0YWlscyA9IHBheW1lbnREZXRhaWxzO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cblxuICAvKipcbiAgICogUGF5bWVudHMgZGV0YWlsc1xuICAgKiBAcGFyYW0gcGF5bWVudERldGFpbHNcbiAgICogQHJldHVybnNcbiAgICovXG4gICBzcGxpdFBheW1lbnQoc3BsaXRQYXltZW50OiBib29sZWFuKSB7ICAgIFxuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5zcGxpdFBheW1lbnQgPSBzcGxpdFBheW1lbnQ7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0gXG5cbiAgIC8qKlxuICAgKiBQYXltZW50cyBkZXRhaWxzXG4gICAqIEBwYXJhbSBwYXltZW50RGV0YWlsc1xuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgICBpc1BheW1lbnRDb21wbGV0ZWQoaXNQYXltZW50Q29tcGxldGVkOiBib29sZWFuKSB7XG4gICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuaXNQYXltZW50Q29tcGxldGVkID0gaXNQYXltZW50Q29tcGxldGVkO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSBcbiAgXG5cblxuXG4gIC8qKlxuICAgKiBCYXNlcyBjdXJyZW5jeVxuICAgKiBAcGFyYW0gY3VycmVuY3lcbiAgICogQHJldHVybnMgY3VycmVuY3lcbiAgICovXG4gIGJhc2VDdXJyZW5jeShjdXJyZW5jeTogYW55KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNlQ3VycmVuY3kgPSBjdXJyZW5jeTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAqIGdpZnQgb3B0aW9uIGF0XG4gICogQHJldHVybnMgYXRcbiAgKi9cbiAgZ2lmdE9wdGlvbihnaWZ0OiBhbnkpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XG4gICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJnaWZ0T3B0aW9uXCIsXG4gICAgICBcInRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5naWZ0b3B0aW9uXCIsXG4gICAgICBnaWZ0XG4gICAgKTtcbiAgICBpZiAoZ2lmdCkge1xuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmdpZnRlZFJlY2VpcHQgPSBnaWZ0O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcblxuLyoqXG4gKiBtYW51YWwgRGlzY291bnRcbiAqIEBwYXJhbSBkaXNjb3VudERhdGFcbiAqIEByZXR1cm5zXG4gKi9cblxuICAvLyBtYW51YWxEaXNjb3VudChkaXNjb3VudERhdGEgOiBiYXNrZXREaXNjb3VudCk6VHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAvLyAgIGxldCBzYWxlVG90YWwgPSAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuYmFza2V0VG90YWw7XG4gIC8vICAgaWYoZGlzY291bnREYXRhLmRpc2NvdW50VHlwZSA9PSdQZXJjZW50Jyl7XG4gIC8vICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5iYXNrZXRUb3RhbCA9IHNhbGVUb3RhbC0oc2FsZVRvdGFsKihkaXNjb3VudERhdGEuZGlzY291bnRBbW91bnQvMTAwKSk7XG4gIC8vICAgICBkaXNjb3VudERhdGEuZGlzY291bnRBbW91bnQgPSAtMSooc2FsZVRvdGFsLXRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsKTtcbiAgLy8gICB9ZWxzZSB7XG4gIC8vICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5iYXNrZXRUb3RhbCA9c2FsZVRvdGFsLWRpc2NvdW50RGF0YS5kaXNjb3VudEFtb3VudDtcbiAgLy8gICAgIGRpc2NvdW50RGF0YS5kaXNjb3VudEFtb3VudCA9IC0xKmRpc2NvdW50RGF0YS5kaXNjb3VudEFtb3VudDtcbiAgLy8gICB9XG4gIC8vICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnRyYW5zYWN0aW9uRGlzY291bnQucHVzaChkaXNjb3VudERhdGEpO1xuICAvLyAgIHJldHVybiB0aGlzO1xuXG4gIC8vIH1cblxuICAvKipcbiAgICogVHlwZXMgdHJhbnNhY3Rpb24gZG9jdW1lbnQgYnVpbGRlclxuICAgKiBAcGFyYW0gdFxuICAgKiBAcmV0dXJucyB0eXBlXG4gICAqL1xuICB0eXBlKHQ6IGFueSk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHlwZSA9IHQ7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIE9wZXJhdGlvbnMgc3RhdHVzXG4gICAqIEBwYXJhbSBvXG4gICAqIEByZXR1cm5zIHN0YXR1c1xuICAgKi9cbiAgb3BlcmF0aW9uU3RhdHVzKG86IGFueSk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQub3BlcmF0aW9uU3RhdHVzID0gbztcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogQ3JlYXRlZCBhdFxuICAgKiBAcmV0dXJucyBhdFxuICAgKi9cbiAgY3JlYXRlZEF0KCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKTtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3JlYXRlZEF0ID0gZGF0ZS50b0lTT1N0cmluZygpO1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC51cGRhdGVkQXQgPSBkYXRlLnRvSVNPU3RyaW5nKCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIFVwZGF0ZWQgYXRcbiAgICogQHJldHVybnMgYXRcbiAgICovXG4gIHVwZGF0ZWRBdCgpOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnVwZGF0ZWRBdCA9IGRhdGUudG9JU09TdHJpbmcoKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogdHJhbnNzYWN0aW9uIGNvbXBsZXRpb24gYXRcbiAgICogQHJldHVybnMgdHJhbnNhY3Rpb24gY29tcGxldGlvbiBkYXRlXG4gICAqL1xuICB0cmFuc2FjdGlvbkNvbXBsZXRlZEF0KCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKTtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHJhbnNDb21wbGV0ZWRBdCA9IGRhdGUudG9JU09TdHJpbmcoKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogQnVpbGRzIHRyYW5zYWN0aW9uIGRvY3VtZW50IGJ1aWxkZXJcbiAgICogQHJldHVybnMgYnVpbGRcbiAgICovXG4gIGJ1aWxkKCk6IFRyYW5zYWN0aW9uRG9jdW1lbnQge1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQ7XG4gIH1cblxuICAvKipcbiAgICogU2FsZXMgdG90YWwgaW4gcmVmdW5kXG4gICAqIEBwYXJhbSBzYWxlVG90YWxcbiAgICogQHJldHVybnMgdG90YWwgaW4gcmVmdW5kXG4gICAqL1xuICBzYWxlVG90YWxJblJlZnVuZChzYWxlVG90YWw6IG51bWJlcik6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuc2FsZVRvdGFsID0gc2FsZVRvdGFsO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgYmFza2V0IGRldGFpbHNcbiAgICogQHJldHVybnMgYmFza2V0IGRldGFpbHNcbiAgICovXG4gIGdldEJhc2tldERldGFpbHMoKTogQmFza2V0IHtcbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0luZm8odGhpcy5jbGFzc05hbWUsIFwiZ2V0QmFza2V0RGV0YWlsc1wiLCBcIkdldHRpbmcgQmFza2V0IGZvciB0cmFuc2FjdGlvbkRvY3VtZW50XCIsIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudCk7XG5cbiAgICBsZXQgYmFza2V0OiBCYXNrZXQgPSB7XG4gICAgICBzdWJzaWRpYXJ5SWQgOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuc3Vic2lkaWFyeUlkLFxuICAgICAgdHJhbnNhY3Rpb25EaXNjb3VudDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50cmFuc2FjdGlvbkRpc2NvdW50LFxuICAgICAgdHJhbnNhY3Rpb25Qcm9tb3Rpb246IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb24sXG4gICAgICB0cmFuc2FjdGlvbklkOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHJhbnNhY3Rpb25JZCxcbiAgICAgIG9mZmxpbmVUcmFuc2FjdGlvbklkOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQub2ZmbGluZVRyYW5zYWN0aW9uSWQsXG4gICAgICB0b3RhbDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuYmFza2V0VG90YWwsXG4gICAgICBiYXNrZXRUb3RhbDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuYmFza2V0VG90YWwsXG4gICAgICBkaXNjb3VudFRvdGFsOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5kaXNjb3VudFRvdGFsLFxuICAgICAgc2FsZVRvdGFsOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5zYWxlVG90YWwsXG4gICAgICByZWZ1bmRUb3RhbDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkucmVmdW5kVG90YWwsXG4gICAgICBxdWFudGl0eTogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkudG90YWxJdGVtcyxcbiAgICAgIHByb2R1Y3RzOiBbXSxcbiAgICAgIGJhc2VDdXJyZW5jeTogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2VDdXJyZW5jeSxcbiAgICAgIGN1c3RvbWVyOiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuY3VzdG9tZXIsXG4gICAgfTtcblxuICAgIGJhc2tldC5wcm9kdWN0cyA9IFtdIGFzIFByb2R1Y3RbXTtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnByb2R1Y3RzLmZvckVhY2goKHByb2R1Y3Q6IHsgU0tVOiBhbnk7IGJhckNvZGU6IGFueTsgYmFyY29kZXM6IGFueTsgZGVzY3JpcHRpb246IGFueTsgaW1hZ2VVcmxzOiBhbnk7IHRvdGFsTGluZVByaWNlOiBhbnk7IGl0ZW1MaW5lSWQ6IGFueTsgZXhjbHVkZVByb21vdGlvbjogYW55OyBwcmljZTogYW55OyBxdWFudGl0eTogYW55OyBzZWxlY3RlZFJSUFByaWNlOiBhbnk7IGZ1bGxmaWxtZW50SWQ6IGFueTsgZnVsbGZpbG1lbnRMb2NhdGlvbk5hbWU6IGFueTsgZGVsaXZlcnlHcm91cDogc3RyaW5nOyBsZWFkVGltZTogYW55OyBkZWxpdmVyeU1ldGhvZDogYW55OyBnaWZ0Q2FyZDogYW55OyBnaWZ0Q2FyZEV4cGlyeURhdGU6IGFueTsgZ2lmdENhcmROdW1iZXJJc3N1ZWQ6IGFueTsgZ2lmdENhcmRSZWNpcGllbnRFbWFpbDogYW55OyBnaWZ0Q2FyZFJlY2lwaWVudE5hbWU6IGFueTsgcmVmdW5kZWRUb3RhbDogYW55OyByZWZ1bmRlZFF1YW50aXR5OiBudW1iZXI7IHJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb246IGFueTsgcmVmdW5kZWRSZWFzb246IGFueTsgcmVmdW5kZWRQcm9tb3Rpb25hbFF1YW50aXR5OiBhbnk7IGlzTGFzdEV4Y2hhbmdlZDogYW55OyB9LCBpbmRleDogYW55KSA9PiB7XG4gICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBKU09OLnN0cmluZ2lmeShwcm9kdWN0KSwgXCJlYmFza2V0OiBiYXNrZXQgZGV0YWlsIHVwZGF0ZSBpbiBiYXNrZXRcIik7XG4gICAgICBjb25zdCBwID0ge30gYXMgYW55O1xuICAgICAgcC5TS1UgPSBwcm9kdWN0LlNLVTtcbiAgICAgIHAuYmFyY29kZSA9IHByb2R1Y3QuYmFyQ29kZTtcbiAgICAgIHAuYmFyY29kZXMgPSBwcm9kdWN0LmJhcmNvZGVzO1xuXG4gICAgICBwLmRlc2NyaXB0aW9uID0gcHJvZHVjdC5kZXNjcmlwdGlvbjtcbiAgICAgIHAuaW1hZ2VVcmxzID0gcHJvZHVjdC5pbWFnZVVybHM7XG4gICAgICBwLmN1cnJlbmN5ID0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2VDdXJyZW5jeTtcbiAgICAgIHAudG90YWxMaW5lUHJpY2UgPSBwcm9kdWN0LnRvdGFsTGluZVByaWNlO1xuICAgICAgcC5pdGVtTGluZUlkID0gTnVtYmVyKHByb2R1Y3QuaXRlbUxpbmVJZCk7XG4gICAgICBwLmV4Y2x1ZGVQcm9tb3Rpb24gPSBwcm9kdWN0LmV4Y2x1ZGVQcm9tb3Rpb247XG5cbiAgICAgIHAuc2VsZWN0ZWRQcmljZSA9IHByb2R1Y3QucHJpY2U7XG4gICAgICBwLnF1YW50aXR5ID0gcHJvZHVjdC5xdWFudGl0eTtcbiAgICAgIHAudG90YWwgPSBwcm9kdWN0LnRvdGFsTGluZVByaWNlO1xuICAgICAgcC5zZWxlY3RlZFJSUFByaWNlID0gcHJvZHVjdC5zZWxlY3RlZFJSUFByaWNlO1xuXG4gICAgICBwLmZ1bGxmaWxtZW50SWQgPSBwcm9kdWN0LmZ1bGxmaWxtZW50SWQ7XG4gICAgICBwLmZ1bGxmaWxtZW50TG9jYXRpb25OYW1lID0gcHJvZHVjdC5mdWxsZmlsbWVudExvY2F0aW9uTmFtZTtcbiAgICAgIHAuZGVsaXZlcnlHcm91cCA9IHByb2R1Y3QuZGVsaXZlcnlHcm91cCB8fCBcIjFcIjtcbiAgICAgIHAubGVhZFRpbWUgPSBwcm9kdWN0LmxlYWRUaW1lO1xuICAgICAgcC5kZWxpdmVyeU1ldGhvZCA9IHByb2R1Y3QuZGVsaXZlcnlNZXRob2QgfHwgREVMSVZFUllfTUVUSE9EUy5DT0xMRUNUX0ZST01fU1RPUkUudG9TdHJpbmcoKTtcblxuICAgICAgaWYocC5mdWxsZmlsbWVudElkICE9IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5zdG9yZUlkKVxuICAgICAge1xuICAgICAgICBwLmlzV2ViT3JkZXIgPSB0cnVlO1xuICAgICAgfVxuICAgIFxuICAgICAgcC5naWZ0Q2FyZCA9IHByb2R1Y3QuZ2lmdENhcmQ7XG4gICAgICBwLmdpZnRDYXJkRXhwaXJ5RGF0ZSA9IHByb2R1Y3QuZ2lmdENhcmRFeHBpcnlEYXRlO1xuICAgICAgcC5naWZ0Q2FyZE51bWJlcklzc3VlZCA9IHByb2R1Y3QuZ2lmdENhcmROdW1iZXJJc3N1ZWQ7XG4gICAgICBwLmdpZnRDYXJkUmVjaXBpZW50RW1haWwgPSBwcm9kdWN0LmdpZnRDYXJkUmVjaXBpZW50RW1haWw7XG4gICAgICBwLmdpZnRDYXJkUmVjaXBpZW50TmFtZSA9IHByb2R1Y3QuZ2lmdENhcmRSZWNpcGllbnROYW1lO1xuICAgICAgXG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50ICYmXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50Lmxlbmd0aCA+IDBcbiAgICAgICkge1xuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudC5mb3JFYWNoKChsaW5lRGlzY291bnQ6IHsgaXRlbUxpbmVJZDogeyB0b1N0cmluZzogKCkgPT4gYW55OyB9OyBkaXNjb3VudGVkTGluZVByaWNlOiBhbnk7IH0pID0+IHtcbiAgICAgICAgICBpZiAocHJvZHVjdC5pdGVtTGluZUlkID09PSBsaW5lRGlzY291bnQuaXRlbUxpbmVJZC50b1N0cmluZygpKSB7XG4gICAgICAgICAgICBwLmxpbmVEaXNjb3VudCA9IGxpbmVEaXNjb3VudDtcbiAgICAgICAgICAgIHAudG90YWwgPSBsaW5lRGlzY291bnQuZGlzY291bnRlZExpbmVQcmljZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbiAmJlxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVQcm9tb3Rpb24ubGVuZ3RoID4gMFxuICAgICAgKSB7XG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbi5mb3JFYWNoKChsaW5lUHJvbW90aW9uOiB7IGl0ZW1MaW5lSWQ6IHsgdG9TdHJpbmc6ICgpID0+IGFueTsgfTsgcHJvbW90aW9uTGluZVByaWNlOiBhbnk7IH0pID0+IHtcbiAgICAgICAgICBpZiAocHJvZHVjdC5pdGVtTGluZUlkID09PSBsaW5lUHJvbW90aW9uLml0ZW1MaW5lSWQudG9TdHJpbmcoKSkge1xuICAgICAgICAgICAgcC5saW5lUHJvbW90aW9ucyA9IGxpbmVQcm9tb3Rpb247XG4gICAgICAgICAgICBwLnRvdGFsID0gbGluZVByb21vdGlvbi5wcm9tb3Rpb25MaW5lUHJpY2U7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRheEJyZWFrZG93biAmJlxuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRheEJyZWFrZG93bi50YXhMaW5lcy5sZW5ndGggPiAwXG4gICAgICApIHtcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50YXhCcmVha2Rvd24udGF4TGluZXMuZm9yRWFjaCgodGF4TGluZTogeyBpdGVtTGluZUlkOiB7IHRvU3RyaW5nOiAoKSA9PiBhbnk7IH07IFZBVDogYW55OyBWQVRDb2RlOiBhbnk7IH0pID0+IHtcbiAgICAgICAgICBpZiAocHJvZHVjdC5pdGVtTGluZUlkICYmIHByb2R1Y3QuaXRlbUxpbmVJZCA9PT0gdGF4TGluZS5pdGVtTGluZUlkLnRvU3RyaW5nKCkpIHtcbiAgICAgICAgICAgIHAuc2VsZWN0ZWRWQVQgPSB0YXhMaW5lLlZBVDtcbiAgICAgICAgICAgIHAuc2VsZWN0ZWRWQVRDb2RlID0gdGF4TGluZS5WQVRDb2RlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHlwZSA9PT0gVFJBTlNBQ1RJT05fVFlQRS5SRUZVTkQpIHtcbiAgICAgICAgcC50b3RhbCA9IHByb2R1Y3QucmVmdW5kZWRUb3RhbDtcbiAgICAgIH0gZWxzZSBpZiAoKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC50eXBlID09PSBUUkFOU0FDVElPTl9UWVBFLlNBTEVfUkVGVU5EIHx8IFRSQU5TQUNUSU9OX1RZUEUuU0FMRV9FWENIQU5HRSkgJiYgcHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5ID4gMCkge1xuICAgICAgICBwLnJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb24gPSBwcm9kdWN0LnJlZnVuZGVkUmVhc29uRGVzY3JpcHRpb247XG4gICAgICAgIHAucmVmdW5kZWRSZWFzb24gPSBwcm9kdWN0LnJlZnVuZGVkUmVhc29uO1xuICAgICAgICBpZiAoIXAucmVmdW5kZWRSZWFzb25EZXNjcmlwdGlvbikge1xuICAgICAgICAgIHAucmVmdW5kZWRSZWFzb25EZXNjcmlwdGlvbiA9IHAucmVmdW5kZWRSZWFzb247XG4gICAgICAgIH1cbiAgICAgICAgcC5yZWZ1bmRlZFF1YW50aXR5ID0gcHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5O1xuICAgICAgICBwLnJlZnVuZFByb21vdGlvbmFsUXVhbnRpdHkgPSBwcm9kdWN0LnJlZnVuZGVkUHJvbW90aW9uYWxRdWFudGl0eTtcbiAgICAgICAgcC5yZWZ1bmRlZFRvdGFsID0gcHJvZHVjdC5yZWZ1bmRlZFRvdGFsO1xuICAgICAgICBwLnRvdGFsIC09IE1hdGguYWJzKHAucmVmdW5kZWRUb3RhbCk7XG4gICAgICAgIHAuaXNMYXN0RXhjaGFuZ2VkID0gcHJvZHVjdC5pc0xhc3RFeGNoYW5nZWQ7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHlwZSA9PT0gVFJBTlNBQ1RJT05fVFlQRS5SRUZVTkQpIHtcbiAgICAgICAgaWYgKHAudG90YWwgPiAwKSB7XG4gICAgICAgICAgcC50b3RhbCAqPSAtMTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBiYXNrZXQucHJvZHVjdHMucHVzaChwKTtcblxuICAgIH0pO1xuXG4gICAgYmFza2V0ID0gdGhpcy5nZXRUcmFuc2FjdGlvbkRpc2NvdW50QW5kVHJhbnNhY3Rpb25Qcm9tb3Rpb25Qb3J0aW9uKGJhc2tldCk7XG4gICAgYmFza2V0LnRvdGFsID0gKGJhc2tldC5iYXNrZXRUb3RhbCB8fCAwKSArIHRoaXMuZ2V0VG90YWxEaXNjb3VudFdpdGhUcmFuc2FjdGlvbkRpc2NvdW50c0FuZFByb21vdGlvbnMoYmFza2V0KTtcbiAgICBpZiAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnR5cGUgPT09IFRSQU5TQUNUSU9OX1RZUEUuU0FMRV9SRUZVTkQpIHtcbiAgICAgIGJhc2tldC5xdWFudGl0eSA9IHRoaXMuZ2V0UmVmdW5kZWRUb3RhbFdpdGhRdWFudGl0eShiYXNrZXQpO1xuICAgIH1cbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0luZm8odGhpcy5jbGFzc05hbWUsIFwiZ2V0QmFza2V0RGV0YWlsc1wiLCBcIkJhc2tldCBjcmVhdGVkIHN1Y2Nlc3NmdWxseVwiLCBiYXNrZXQpXG4gICAgcmV0dXJuIGJhc2tldDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGJhc2tldCBkZXRhaWxzXG4gICAqIEByZXR1cm5zIHJlZnVuZCBiYXNrZXQgZGV0YWlsc1xuICAgKi9cbiAgLy8gZ2V0UmVmdW5kQmFza2V0RGV0YWlscygpOiBCYXNrZXQge1xuICAvLyAgIGxldCBiYXNrZXQ6IEJhc2tldCA9IHtcbiAgLy8gICAgIHN1YnNpZGlhcnlJZCA6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5zdWJzaWRpYXJ5SWQsXG4gIC8vICAgICB0cmFuc2FjdGlvbkRpc2NvdW50OiB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQsXG4gIC8vICAgICB0cmFuc2FjdGlvblByb21vdGlvbjogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50cmFuc2FjdGlvblByb21vdGlvbixcbiAgLy8gICAgIHRyYW5zYWN0aW9uSWQ6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC50cmFuc2FjdGlvbklkLFxuICAvLyAgICAgdG90YWw6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsLFxuICAvLyAgICAgYmFza2V0VG90YWw6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsLFxuICAvLyAgICAgZGlzY291bnRUb3RhbDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuZGlzY291bnRUb3RhbCxcbiAgLy8gICAgIHNhbGVUb3RhbDogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuc2FsZVRvdGFsLFxuICAvLyAgICAgcXVhbnRpdHk6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LnRvdGFsSXRlbXMsXG4gIC8vICAgICBwcm9kdWN0czogW10sXG4gIC8vICAgICBiYXNlQ3VycmVuY3k6IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNlQ3VycmVuY3ksXG4gIC8vICAgICBjdXN0b21lcjogdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmN1c3RvbWVyLFxuICAvLyAgIH07XG5cbiAgLy8gICBiYXNrZXQucHJvZHVjdHMgPSBbXSBhcyBQcm9kdWN0W107XG4gIC8vICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5wcm9kdWN0cy5mb3JFYWNoKChwcm9kdWN0OiB7IFNLVTogYW55OyBiYXJDb2RlOiBhbnk7IGJhcmNvZGVzOiBhbnk7IGRlc2NyaXB0aW9uOiBhbnk7IGltYWdlVXJsczogYW55OyB0b3RhbExpbmVQcmljZTogYW55OyBpdGVtTGluZUlkOiBhbnk7IGV4Y2x1ZGVQcm9tb3Rpb246IGFueTsgcHJpY2U6IG51bWJlcjsgcXVhbnRpdHk6IGFueTsgc2VsZWN0ZWRSUlBQcmljZTogYW55OyBmdWxsZmlsbWVudElkOiBhbnk7IGZ1bGxmaWxtZW50TG9jYXRpb25OYW1lOiBhbnk7IGRlbGl2ZXJ5R3JvdXA6IHN0cmluZzsgbGVhZFRpbWU6IGFueTsgZGVsaXZlcnlNZXRob2Q6IGFueTsgZ2lmdENhcmQ6IGFueTsgZ2lmdENhcmRFeHBpcnlEYXRlOiBhbnk7IGdpZnRDYXJkTnVtYmVySXNzdWVkOiBhbnk7IGdpZnRDYXJkUmVjaXBpZW50RW1haWw6IGFueTsgZ2lmdENhcmRSZWNpcGllbnROYW1lOiBhbnk7IGl0ZW1EaXNjb3VudHM6IGFueTsgcmVmdW5kZWRQcm9tb3Rpb25hbFF1YW50aXR5OiBhbnk7IHJlZnVuZGVkUXVhbnRpdHk6IG51bWJlcjsgcmVmdW5kZWQ6IGFueTsgaXNMYXN0RXhjaGFuZ2VkOiBhbnk7IGV4Y2hhbmdlOiBhbnk7IHJlZnVuZGVkVG90YWw6IG51bWJlcjsgfSwgaW5kZXg6IGFueSkgPT4ge1xuICAvLyAgICAgY29uc3QgcCA9IHt9IGFzIFByb2R1Y3Q7XG4gIC8vICAgICBwLlNLVSA9IHByb2R1Y3QuU0tVO1xuICAvLyAgICAgcC5iYXJjb2RlID0gcHJvZHVjdC5iYXJDb2RlO1xuICAvLyAgICAgcC5iYXJjb2RlcyA9IHByb2R1Y3QuYmFyY29kZXM7XG5cbiAgLy8gICAgIHAuZGVzY3JpcHRpb24gPSBwcm9kdWN0LmRlc2NyaXB0aW9uO1xuICAvLyAgICAgcC5pbWFnZVVybHMgPSBwcm9kdWN0LmltYWdlVXJscztcbiAgLy8gICAgIHAuY3VycmVuY3kgPSB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFzZUN1cnJlbmN5O1xuICAvLyAgICAgcC50b3RhbExpbmVQcmljZSA9IHByb2R1Y3QudG90YWxMaW5lUHJpY2U7XG4gIC8vICAgICBwLml0ZW1MaW5lSWQgPSBOdW1iZXIocHJvZHVjdC5pdGVtTGluZUlkKTtcbiAgLy8gICAgIHAuZXhjbHVkZVByb21vdGlvbiA9IHByb2R1Y3QuZXhjbHVkZVByb21vdGlvbjtcblxuICAvLyAgICAgcC5zZWxlY3RlZFByaWNlID0gcHJvZHVjdC5wcmljZTtcbiAgLy8gICAgIHAucXVhbnRpdHkgPSBwcm9kdWN0LnF1YW50aXR5O1xuICAvLyAgICAgcC50b3RhbCA9IHByb2R1Y3QudG90YWxMaW5lUHJpY2U7XG4gIC8vICAgICBwLnNlbGVjdGVkUlJQUHJpY2UgPSBwcm9kdWN0LnNlbGVjdGVkUlJQUHJpY2U7XG5cbiAgLy8gICAgIHAuZnVsbGZpbG1lbnRJZCA9IHByb2R1Y3QuZnVsbGZpbG1lbnRJZDtcbiAgLy8gICAgIHAuZnVsbGZpbG1lbnRMb2NhdGlvbk5hbWUgPSBwcm9kdWN0LmZ1bGxmaWxtZW50TG9jYXRpb25OYW1lO1xuICAvLyAgICAgcC5kZWxpdmVyeUdyb3VwID0gcHJvZHVjdC5kZWxpdmVyeUdyb3VwIHx8IFwiMVwiO1xuICAvLyAgICAgcC5sZWFkVGltZSA9IHByb2R1Y3QubGVhZFRpbWU7XG4gIC8vICAgICBwLmRlbGl2ZXJ5TWV0aG9kID0gcHJvZHVjdC5kZWxpdmVyeU1ldGhvZCB8fCBERUxJVkVSWV9NRVRIT0RTLkNPTExFQ1RfRlJPTV9TVE9SRS50b1N0cmluZygpO1xuXG4gIC8vICAgICBwLmdpZnRDYXJkID0gcHJvZHVjdC5naWZ0Q2FyZDtcbiAgLy8gICAgIHAuZ2lmdENhcmRFeHBpcnlEYXRlID0gcHJvZHVjdC5naWZ0Q2FyZEV4cGlyeURhdGU7XG4gIC8vICAgICBwLmdpZnRDYXJkTnVtYmVySXNzdWVkID0gcHJvZHVjdC5naWZ0Q2FyZE51bWJlcklzc3VlZDtcbiAgLy8gICAgIHAuZ2lmdENhcmRSZWNpcGllbnRFbWFpbCA9IHByb2R1Y3QuZ2lmdENhcmRSZWNpcGllbnRFbWFpbDtcbiAgLy8gICAgIHAuZ2lmdENhcmRSZWNpcGllbnROYW1lID0gcHJvZHVjdC5naWZ0Q2FyZFJlY2lwaWVudE5hbWU7XG4gICAgICBcbiAgICAgIFxuICAvLyAgICAgaWYocC5mdWxsZmlsbWVudElkICE9IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5zdG9yZUlkKVxuICAvLyAgICAge1xuICAvLyAgICAgICBwLmlzV2ViT3JkZXIgPSB0cnVlO1xuICAvLyAgICAgfVxuICAgICAgXG4gIC8vICAgICBpZiAocHJvZHVjdC5pdGVtRGlzY291bnRzKSB7XG4gIC8vICAgICAgIHAuaXRlbURpc2NvdW50cyA9IHByb2R1Y3QuaXRlbURpc2NvdW50cyBhcyBJdGVtRGlzY291bnQ7XG4gIC8vICAgICB9XG5cbiAgLy8gICAgIC8vIGlmKCFwLml0ZW1EaXNjb3VudHMpe1xuICAvLyAgICAgLy8gICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBwLml0ZW1EaXNjb3VudHMpO1xuXG4gIC8vICAgICAvLyAgIHRoaXMuYmFza2V0U2VydmljZS50cmFuc2FjdGlvbkRpc2NvdW50QW5kUHJvbW90aW9uUHJvZHVjdG9ydGlvbkNhbGN1bGF0aW9uKGJhc2tldCk7XG4gIC8vICAgICAvLyB9XG4gIC8vICAgICBwLnJlZnVuZFByb21vdGlvbmFsUXVhbnRpdHkgPSBwcm9kdWN0LnJlZnVuZGVkUHJvbW90aW9uYWxRdWFudGl0eSA/IHByb2R1Y3QucmVmdW5kZWRQcm9tb3Rpb25hbFF1YW50aXR5IDogMDtcblxuICAvLyAgICAgaWYgKHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eSkge1xuICAvLyAgICAgICBwLnF1YW50aXR5ID0gcC5xdWFudGl0eSAtIHByb2R1Y3QucmVmdW5kZWRRdWFudGl0eTtcbiAgLy8gICAgICAgcC50b3RhbExpbmVQcmljZSA9IChwLnF1YW50aXR5ICogcHJvZHVjdC5wcmljZSk7XG4gIC8vICAgICAgIHAudG90YWwgPSBwLnRvdGFsTGluZVByaWNlO1xuICAvLyAgICAgICAvLyBwLnJlZnVuZFByb21vdGlvbmFsUXVhbnRpdHkgPSBwcm9kdWN0LnJlZnVuZGVkUHJvbW90aW9uYWxRdWFudGl0eTtcbiAgLy8gICAgICAgcC5yZWZ1bmRlZCA9IHByb2R1Y3QucmVmdW5kZWQ7XG4gIC8vICAgICAgIHAuaXNMYXN0RXhjaGFuZ2VkID0gcHJvZHVjdC5pc0xhc3RFeGNoYW5nZWQ7XG4gIC8vICAgICB9XG4gIC8vICAgICBpZiAocHJvZHVjdC5leGNoYW5nZSkge1xuICAvLyAgICAgICBwLmV4Y2hhbmdlID0gcHJvZHVjdC5leGNoYW5nZTtcbiAgLy8gICAgIH1cblxuICAvLyAgICAgaWYgKFxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudCAmJlxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudC5sZW5ndGggPiAwXG4gIC8vICAgICApIHtcblxuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudC5mb3JFYWNoKChsaW5lRGlzY291bnQ6IHsgaXRlbUxpbmVJZDogeyB0b1N0cmluZzogKCkgPT4gYW55OyB9OyBkaXNjb3VudGVkTGluZVByaWNlOiBhbnk7IH0pID0+IHtcblxuICAvLyAgICAgICAgIGlmIChwcm9kdWN0Lml0ZW1MaW5lSWQgPT09IGxpbmVEaXNjb3VudC5pdGVtTGluZUlkLnRvU3RyaW5nKCkgJiYgcHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5ID4gMCkge1xuICAvLyAgICAgICAgICAgcC5saW5lRGlzY291bnQgPSBPYmplY3QuYXNzaWduKHt9LCBsaW5lRGlzY291bnQpO1xuICAvLyAgICAgICAgICAgcC5saW5lRGlzY291bnQuZGlzY291bnRlZExpbmVQcmljZSA9IHAubGluZURpc2NvdW50LnVuaXRQcmljZSAqIHAucXVhbnRpdHlcbiAgLy8gICAgICAgICAgIHAubGluZURpc2NvdW50LmRpc2NvdW50QW1vdW50ID0gcC50b3RhbCAtIHAubGluZURpc2NvdW50LmRpc2NvdW50ZWRMaW5lUHJpY2VcbiAgLy8gICAgICAgICAgIHAudG90YWwgPSBwLmxpbmVEaXNjb3VudC5kaXNjb3VudGVkTGluZVByaWNlO1xuICAvLyAgICAgICAgIH0gZWxzZSBpZiAocHJvZHVjdC5pdGVtTGluZUlkID09PSBsaW5lRGlzY291bnQuaXRlbUxpbmVJZC50b1N0cmluZygpKSB7XG4gIC8vICAgICAgICAgICBwLmxpbmVEaXNjb3VudCA9IGxpbmVEaXNjb3VudDtcbiAgLy8gICAgICAgICAgIHAudG90YWwgPSBsaW5lRGlzY291bnQuZGlzY291bnRlZExpbmVQcmljZVxuICAvLyAgICAgICAgIH1cbiAgLy8gICAgICAgfSk7XG4gIC8vICAgICB9XG5cbiAgLy8gICAgIGlmIChcbiAgLy8gICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lUHJvbW90aW9uICYmXG4gIC8vICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbi5sZW5ndGggPiAwXG4gIC8vICAgICApIHtcbiAgLy8gICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lUHJvbW90aW9uLmZvckVhY2goKGxpbmVQcm9tb3Rpb246IHsgaXRlbUxpbmVJZDogeyB0b1N0cmluZzogKCkgPT4gYW55OyB9OyByZWZ1bmRlZDogYW55OyB9KSA9PiB7XG4gIC8vICAgICAgICAgaWYgKHByb2R1Y3QuaXRlbUxpbmVJZCA9PT0gbGluZVByb21vdGlvbi5pdGVtTGluZUlkLnRvU3RyaW5nKCkgJiYgIWxpbmVQcm9tb3Rpb24ucmVmdW5kZWQpIHtcbiAgLy8gICAgICAgICAgIHAubGluZVByb21vdGlvbnMgPSBsaW5lUHJvbW90aW9uO1xuICAvLyAgICAgICAgICAgcC50b3RhbCA9IHAubGluZVByb21vdGlvbnMucHJvbW90aW9uTGluZVByaWNlO1xuICAvLyAgICAgICAgICAgcC50b3RhbCA9IHAudG90YWwgLSAocHJvZHVjdC5yZWZ1bmRlZFRvdGFsID8gTWF0aC5hYnMocHJvZHVjdC5yZWZ1bmRlZFRvdGFsKSA6IDApO1xuICAvLyAgICAgICAgIH1cbiAgLy8gICAgICAgfSk7XG4gIC8vICAgICB9XG5cbiAgLy8gICAgIHAucmVmdW5kZWRRdWFudGl0eSA9IDA7XG4gIC8vICAgICBwLnJlZnVuZGVkVG90YWwgPSAwO1xuXG4gIC8vICAgICBpZiAoXG4gIC8vICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudGF4QnJlYWtkb3duICYmXG4gIC8vICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudGF4QnJlYWtkb3duLnRheExpbmVzLmxlbmd0aCA+IDBcbiAgLy8gICAgICkge1xuICAvLyAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRheEJyZWFrZG93bi50YXhMaW5lcy5mb3JFYWNoKCh0YXhMaW5lOiB7IGl0ZW1MaW5lSWQ6IHsgdG9TdHJpbmc6ICgpID0+IGFueTsgfTsgVkFUOiBhbnk7IFZBVENvZGU6IGFueTsgfSkgPT4ge1xuICAvLyAgICAgICAgIGlmIChwcm9kdWN0Lml0ZW1MaW5lSWQgPT09IHRheExpbmUuaXRlbUxpbmVJZC50b1N0cmluZygpKSB7XG4gIC8vICAgICAgICAgICBwLnNlbGVjdGVkVkFUID0gdGF4TGluZS5WQVQ7XG4gIC8vICAgICAgICAgICBwLnNlbGVjdGVkVkFUQ29kZSA9IHRheExpbmUuVkFUQ29kZTtcbiAgLy8gICAgICAgICB9XG4gIC8vICAgICAgIH0pO1xuICAvLyAgICAgfVxuXG4gIC8vICAgICBpZiAocC5xdWFudGl0eSA+IDApIHtcbiAgLy8gICAgICAgYmFza2V0LnByb2R1Y3RzLnB1c2gocCk7XG4gIC8vICAgICB9XG4gIC8vICAgfSk7XG4gIC8vICAgLy8gcHJvZHVjdC5pdGVtRGlzY291bnRzXG4gIC8vICAgaWYgKCFiYXNrZXQucHJvZHVjdHNbMF0uaGFzT3duUHJvcGVydHkoJ2l0ZW1EaXNjb3VudHMnKSkge1xuICAvLyAgICAgYmFza2V0ID0gdGhpcy5nZXRUcmFuc2FjdGlvbkRpc2NvdW50QW5kVHJhbnNhY3Rpb25Qcm9tb3Rpb25Qb3J0aW9uKGJhc2tldCk7XG5cbiAgLy8gICB9XG5cbiAgLy8gICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcImViYXNrZXQgOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciAgOm5ldyBjcmVhdGVkIHJlZnVuZGVkIGJhc2tldFwiLCBKU09OLnN0cmluZ2lmeShiYXNrZXQpKVxuICAvLyAgIGJhc2tldC5xdWFudGl0eSA9IGJhc2tldC5wcm9kdWN0cy5yZWR1Y2UoXG4gIC8vICAgICAobjogYW55LCB7IHF1YW50aXR5IH06IGFueSkgPT4gbiArIHF1YW50aXR5LFxuICAvLyAgICAgMFxuICAvLyAgICk7XG4gIC8vICAgYmFza2V0LnRvdGFsID0gdGhpcy5nZXRUb3RhbFdpdGhMaW5lRGlzY291bnRBbmRMaW5lUHJvbW90aW9uQXBwbGllZChiYXNrZXQpO1xuICAvLyAgIGJhc2tldC5iYXNrZXRUb3RhbCA9IGJhc2tldC50b3RhbDtcbiAgLy8gICBiYXNrZXQuYmFza2V0VG90YWwgPSBiYXNrZXQuYmFza2V0VG90YWwgLSB0aGlzLmdldFRvdGFsRGlzY291bnRXaXRoVHJhbnNhY3Rpb25EaXNjb3VudHNBbmRQcm9tb3Rpb25zKGJhc2tldCk7XG4gIC8vICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXG4gIC8vICAgICBcImViYXNrZXQgOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciA6IHVwZGF0ZSBCYXNrZXQgVG90YWw6IGFmdGVyIHByb21vdGlvbiA6YmFza2V0VG90YWxcIixcbiAgLy8gICAgIGJhc2tldC5iYXNrZXRUb3RhbFxuICAvLyAgICk7XG5cbiAgLy8gICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcbiAgLy8gICAgIFwiZTpiYXNrZXQgOlRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIDogYmFza2V0RGV0YWlscyB1cGRhdGVkIHZhbHVlc1wiLFxuICAvLyAgICAgSlNPTi5zdHJpbmdpZnkoYmFza2V0KVxuICAvLyAgICk7XG4gIC8vICAgcmV0dXJuIGJhc2tldDtcbiAgLy8gfVxuXG5cbiAgZ2V0VHJhbnNhY3Rpb25EaXNjb3VudEFuZFRyYW5zYWN0aW9uUHJvbW90aW9uUG9ydGlvbihiYXNrZXQ6YW55KSB7XG4gICAgaWYgKFxuICAgICAgYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQgJiZcbiAgICAgIGJhc2tldC50cmFuc2FjdGlvbkRpc2NvdW50Lmxlbmd0aCA+IDBcbiAgICApIHtcbiAgICAgIGJhc2tldC50cmFuc2FjdGlvbkRpc2NvdW50LmZvckVhY2goKGRpc2NvdW50OiB7IGl0ZW1MaW5lSWRzOiBhbnk7IH0pID0+IHtcbiAgICAgICAgaWYgKCFkaXNjb3VudC5pdGVtTGluZUlkcykge1xuICAgICAgICAgIGRpc2NvdW50Lml0ZW1MaW5lSWRzID0gYmFza2V0LnByb2R1Y3RzLm1hcCgocHJvZHVjdDogeyBpdGVtTGluZUlkOiBhbnk7IH0pID0+IHtcbiAgICAgICAgICAgIHJldHVybiBwcm9kdWN0Lml0ZW1MaW5lSWRcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBiYXNrZXQgPSB0aGlzLmJhc2tldFNlcnZpY2UudHJhbnNhY3Rpb25EaXNjb3VudFByb2R1Y3RQb3J0aW9uQ2FsYyhiYXNrZXQsIGRpc2NvdW50KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICBiYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb24gJiZcbiAgICAgIGJhc2tldC50cmFuc2FjdGlvblByb21vdGlvbi5sZW5ndGggPiAwXG4gICAgKSB7XG4gICAgICBiYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb24uZm9yRWFjaCgodFByb21vdGlvbjogeyBpdGVtTGluZUlkczogYW55OyB9KSA9PiB7XG4gICAgICAgIGlmICghdFByb21vdGlvbi5pdGVtTGluZUlkcykge1xuICAgICAgICAgIGNvbnN0IGZpbHRlcmVkRGF0YSA9IGJhc2tldC5wcm9kdWN0cy5maWx0ZXIoXG4gICAgICAgICAgICAoaXRlbTogeyBleGNsdWRlUHJvbW90aW9uOiBib29sZWFuOyB9KSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBpdGVtLmV4Y2x1ZGVQcm9tb3Rpb24gPT09IGZhbHNlO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICB0UHJvbW90aW9uLml0ZW1MaW5lSWRzID1cbiAgICAgICAgICAgIGZpbHRlcmVkRGF0YS5tYXAoKHByb2R1Y3Q6IHsgaXRlbUxpbmVJZDogYW55OyB9KSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBwcm9kdWN0Lml0ZW1MaW5lSWRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGJhc2tldCA9IHRoaXMuYmFza2V0U2VydmljZS50cmFuc2FjdGlvblByb21vdGlvblByb2R1Y3RQb3J0aW9uQ2FsYyhiYXNrZXQsIHRQcm9tb3Rpb24pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJhc2tldDtcbiAgfVxuXG5cbiAgZ2V0VG90YWxEaXNjb3VudFdpdGhUcmFuc2FjdGlvbkRpc2NvdW50c0FuZFByb21vdGlvbnMoYmFza2V0RGV0YWlsczogYW55KSB7XG5cbiAgICBsZXQgZGlzY291bnRUb3RhbCA9IDA7XG4gICAgaWYgKFxuICAgICAgYmFza2V0RGV0YWlscy50cmFuc2FjdGlvblByb21vdGlvbiAmJlxuICAgICAgYmFza2V0RGV0YWlscy50cmFuc2FjdGlvblByb21vdGlvbi5sZW5ndGggPiAwXG4gICAgKSB7XG4gICAgICBkaXNjb3VudFRvdGFsICs9IGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25Qcm9tb3Rpb24ucmVkdWNlKFxuICAgICAgICAobjogYW55LCB7IHByb21vdGlvbkFtb3VudCB9OiBhbnkpID0+IG4gKyBwcm9tb3Rpb25BbW91bnQsXG4gICAgICAgIDBcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIGJhc2tldERldGFpbHMudHJhbnNhY3Rpb25EaXNjb3VudCAmJlxuICAgICAgYmFza2V0RGV0YWlscy50cmFuc2FjdGlvbkRpc2NvdW50Lmxlbmd0aCA+IDBcbiAgICApIHtcblxuICAgICAgZGlzY291bnRUb3RhbCArPSBiYXNrZXREZXRhaWxzLnRyYW5zYWN0aW9uRGlzY291bnQucmVkdWNlKFxuICAgICAgICAobjogYW55LCB7IGRpc2NvdW50QW1vdW50IH06IGFueSkgPT4gbiArIGRpc2NvdW50QW1vdW50LFxuICAgICAgICAwXG4gICAgICApO1xuXG5cbiAgICB9XG4gICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJnZXRUb3RhbERpc2NvdW50V2l0aFRyYW5zYWN0aW9uRGlzY291bnRzQW5kUHJvbW90aW9uc1wiLCBcIlRyYW5zYWN0aW9uIGRpc2NvdW50IFRvdGFsOlwiLCBkaXNjb3VudFRvdGFsKTtcblxuICAgIHJldHVybiBkaXNjb3VudFRvdGFsO1xuICB9XG5cblxuICBhcHBlbmRDdXJyZW5jeVN5bWJvbChjdXJyZW5jeTogbnVtYmVyLCB2YWx1ZTogbnVtYmVyKSB7XG4gICAgLy8gIHZhbHVlPXRoaXMuZGVjaW1hbHBpcGUudHJhbnNmb3JtKHZhbHVlLCcxLjInKTtcbiAgICBpZiAodmFsdWUgPj0gMCkge1xuICAgICAgY29uc3QgcmV0dXJudmFsID0gY3VycmVuY3kgKyB2YWx1ZTtcbiAgICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwiYXBwZW5kQ3VycmVuY3lTeW1ib2xcIiwgXCJhZGQgY3VycmVuY3kgd2l0aCB2YWx1ZVwiLCByZXR1cm52YWwpO1xuICAgICAgcmV0dXJuIHJldHVybnZhbDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgcmV0dXJudmFsID0gXCItXCIgKyAoY3VycmVuY3kgKyB2YWx1ZSAqIC0xKTtcbiAgICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwiYXBwZW5kQ3VycmVuY3lTeW1ib2xcIiwgXCJyZXR1cm5WYWxcIiwgcmV0dXJudmFsKTtcbiAgICAgIHJldHVybiByZXR1cm52YWw7XG4gICAgfVxuICB9XG5cbiAgLy8gLyoqXG4gIC8vICAqIFVwZGF0ZXMgdG90YWwgcmVmdW5kXG4gIC8vICAqIEByZXR1cm5zIHRvdGFsIHJlZnVuZFxuICAvLyAgKi9cbiAgLy8gdXBkYXRlVG90YWxSZWZ1bmQoKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAvLyAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQucHJvZHVjdHMuZm9yRWFjaCgocHJvZHVjdCkgPT4ge1xuICAvLyAgICAgcHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5ID0gcHJvZHVjdC5xdWFudGl0eTtcbiAgLy8gICAgIHByb2R1Y3QucmVmdW5kZWRUb3RhbCA9IHByb2R1Y3QudG90YWxMaW5lUHJpY2UgKiAtMTtcbiAgLy8gICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFxuICAvLyAgICAgICBcImViYXNrZXQ6IFRyYW5zYWN0aW9uIHByaWNlIG92ZXJyaWRlIDpcIixcbiAgLy8gICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnRcbiAgLy8gICAgICk7XG5cbiAgLy8gICAgIGlmIChcbiAgLy8gICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lUHJvbW90aW9uICYmXG4gIC8vICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZVByb21vdGlvbi5sZW5ndGggPiAwXG4gIC8vICAgICApIHtcbiAgLy8gICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lUHJvbW90aW9uLmZvckVhY2goKGxpbmVQcm9tb3Rpb24pID0+IHtcbiAgLy8gICAgICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcbiAgLy8gICAgICAgICAgIFwiUHJvbW90aW9uOiBiYXNrZXQgbGluZVByb21vdGlvbiA6IFwiLFxuICAvLyAgICAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lUHJvbW90aW9uXG4gIC8vICAgICAgICAgKTtcbiAgLy8gICAgICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcbiAgLy8gICAgICAgICAgIFwibGluZVByb21vdGlvbi5pdGVtTGluZUlkLnRvU3RyaW5nKCkgOiBcIixcbiAgLy8gICAgICAgICAgIGxpbmVQcm9tb3Rpb24uaXRlbUxpbmVJZC50b1N0cmluZygpXG4gIC8vICAgICAgICAgKTtcbiAgLy8gICAgICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcbiAgLy8gICAgICAgICAgIFwiY29uZGl0aW9uIDogXCIgK1xuICAvLyAgICAgICAgICAgKHByb2R1Y3QuaXRlbUxpbmVJZCA9PT0gbGluZVByb21vdGlvbi5pdGVtTGluZUlkLnRvU3RyaW5nKCkpXG4gIC8vICAgICAgICAgKTtcblxuICAvLyAgICAgICAgIGlmIChwcm9kdWN0Lml0ZW1MaW5lSWQgPT09IGxpbmVQcm9tb3Rpb24uaXRlbUxpbmVJZC50b1N0cmluZygpKSB7XG4gIC8vICAgICAgICAgICBwcm9kdWN0LnJlZnVuZGVkVG90YWwgPVxuICAvLyAgICAgICAgICAgICBsaW5lUHJvbW90aW9uLnByb21vdGlvbkxpbmVQcmljZSAqIC0xO1xuICAvLyAgICAgICAgIH1cbiAgLy8gICAgICAgfSk7XG4gIC8vICAgICB9IGVsc2VcbiAgLy8gICAgICAgaWYgKFxuICAvLyAgICAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQubGluZURpc2NvdW50ICYmXG4gIC8vICAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnQubGVuZ3RoID4gMFxuICAvLyAgICAgICApIHtcbiAgLy8gICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LmxpbmVEaXNjb3VudC5mb3JFYWNoKChsaW5lRGlzY291bnQpID0+IHtcbiAgLy8gICAgICAgICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFxuICAvLyAgICAgICAgICAgICBcInByb2R1Y3QuaXRlbUxpbmVJZCA6IFwiICtcbiAgLy8gICAgICAgICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC5saW5lRGlzY291bnRcbiAgLy8gICAgICAgICAgICk7XG4gIC8vICAgICAgICAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcbiAgLy8gICAgICAgICAgICAgXCJsaW5lRGlzY291bnQuaXRlbUxpbmVJZC50b1N0cmluZygpIDogXCIgK1xuICAvLyAgICAgICAgICAgICBsaW5lRGlzY291bnQuaXRlbUxpbmVJZC50b1N0cmluZygpXG4gIC8vICAgICAgICAgICApO1xuICAvLyAgICAgICAgICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXG4gIC8vICAgICAgICAgICAgIFwiY29uZGl0aW9uIDogXCIgK1xuICAvLyAgICAgICAgICAgICAocHJvZHVjdC5pdGVtTGluZUlkID09PSBsaW5lRGlzY291bnQuaXRlbUxpbmVJZC50b1N0cmluZygpKVxuICAvLyAgICAgICAgICAgKTtcblxuICAvLyAgICAgICAgICAgaWYgKHByb2R1Y3QuaXRlbUxpbmVJZCA9PT0gbGluZURpc2NvdW50Lml0ZW1MaW5lSWQudG9TdHJpbmcoKSkge1xuICAvLyAgICAgICAgICAgICBwcm9kdWN0LnJlZnVuZGVkVG90YWwgPSBsaW5lRGlzY291bnQudW5pdFByaWNlICogcHJvZHVjdC5yZWZ1bmRlZFF1YW50aXR5ICogLTE7XG4gIC8vICAgICAgICAgICB9XG4gIC8vICAgICAgICAgfSk7XG4gIC8vICAgICAgIH1cblxuICAvLyAgICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJQcm9kdWN0IGRlc2NyaXB0aW9uIDpcIiArIHByb2R1Y3QuZGVzY3JpcHRpb24pO1xuICAvLyAgICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJQcm9kdWN0IHRvdGFsIDpcIiArIHByb2R1Y3QucmVmdW5kZWRUb3RhbCk7XG4gIC8vICAgICAvLyBwcm9kdWN0LmRpc3BsYXlyZWZ1bmRlZGFtb3VudD10aGlzLmFwcGVuZEN1cnJlbmN5U3ltYm9sKENVUlJFTkNZW3RoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNlQ3VycmVuY3ldLHByb2R1Y3QucmVmdW5kZWRUb3RhbCk7XG4gIC8vICAgICAvLyBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBwcm9kdWN0LmRpc3BsYXlyZWZ1bmRlZGFtb3VudCxcImRpc3BsYXlyZWZ1bmRlZGFtb3VudFwiKTtcbiAgLy8gICAgIHByb2R1Y3QucmVmdW5kZWQgPSB0cnVlO1xuICAvLyAgIH0pO1xuICAvLyAgIGNvbnN0IGJhc2tldHRvdGFsID0gKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmJhc2tldFRvdGFsICo9IC0xKTtcbiAgLy8gICAvLyB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5kaXNwbGF5YmFza2V0dG90YWw9dGhpcy5hcHBlbmRDdXJyZW5jeVN5bWJvbChDVVJSRU5DWVt0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFzZUN1cnJlbmN5XSwgYmFza2V0dG90YWwpO1xuICAvLyAgIGNvbnN0IHNhbGV0b3RhbCA9ICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5zYWxlVG90YWwgKj0gLTEpO1xuICAvLyAgIC8vIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LmRpc3BsYXlzYWxldG90YWwgPSB0aGlzLmFwcGVuZEN1cnJlbmN5U3ltYm9sKENVUlJFTkNZW3RoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNlQ3VycmVuY3ldLCBzYWxldG90YWwpO1xuICAvLyAgICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5WQVRUb3RhbCAqPSAtMSk7XG4gIC8vICAgcmV0dXJuIHRoaXM7XG4gIC8vIH1cblxuICAvKipcbiAgICogU2FsZSBUb3RhbFxuICAgKiBAcGFyYW0gYmFza2V0RGV0YWlsc1xuICAgKiBAcmV0dXJucyBTYWxlIFRvdGFsXG4gICAqL1xuICB1cGRhdGVTYWxlVG90YWwoYmFza2V0RGV0YWlsczogeyBwcm9kdWN0czogYW55W107IH0pIHtcbiAgICBjb25zdCBzYWxlVG90YWwgPSBiYXNrZXREZXRhaWxzLnByb2R1Y3RzLnJlZHVjZShcbiAgICAgIChuOiBhbnksIHsgdG90YWxMaW5lUHJpY2UgfTogYW55KSA9PiBuICsgdG90YWxMaW5lUHJpY2UsXG4gICAgICAwXG4gICAgKTtcbiAgICByZXR1cm4gc2FsZVRvdGFsXG4gIH1cblxuICBnZXRUb3RhbFdpdGhMaW5lRGlzY291bnRBbmRMaW5lUHJvbW90aW9uQXBwbGllZChiYXNrZXREZXRhaWxzOiB7IHByb2R1Y3RzOiBhbnk7IH0pOiBudW1iZXIge1xuICAgIGxldCBzYWxldG90YWw6IG51bWJlciA9IDAuMDtcbiAgICBmb3IgKGxldCBwcm9kdWN0IG9mIGJhc2tldERldGFpbHMucHJvZHVjdHMpIHtcbiAgICAgIC8vIGlmIChwcm9kdWN0LmxpbmVQcm9tb3Rpb25zKSB7XG4gICAgICAvLyAgIHNhbGV0b3RhbCArPSBwcm9kdWN0LmxpbmVQcm9tb3Rpb25zLnByb21vdGlvbkxpbmVQcmljZTtcbiAgICAgIC8vIH0gZWxzZSBpZiAoXG4gICAgICAvLyAgIHByb2R1Y3QubGluZURpc2NvdW50ICYmXG4gICAgICAvLyAgICFwcm9kdWN0LmxpbmVQcm9tb3Rpb25zXG4gICAgICAvLyApIHtcbiAgICAgIC8vICAgc2FsZXRvdGFsICs9XG4gICAgICAvLyAgICAgcHJvZHVjdC5xdWFudGl0eSAqIE51bWJlcihwcm9kdWN0LmxpbmVEaXNjb3VudC51bml0UHJpY2UudG9GaXhlZCgyKSk7XG4gICAgICAvLyB9IGVsc2Uge1xuICAgICAgLy8gICBzYWxldG90YWwgKz1cbiAgICAgIC8vICAgICBwcm9kdWN0LnF1YW50aXR5ICogTnVtYmVyKHByb2R1Y3Quc2VsZWN0ZWRQcmljZS50b0ZpeGVkKDIpKTtcbiAgICAgIC8vIH1cbiAgICAgIHNhbGV0b3RhbCArPSBwcm9kdWN0LnRvdGFsO1xuICAgICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJnZXRUb3RhbFdpdGhMaW5lRGlzY291bnRBbmRMaW5lUHJvbW90aW9uQXBwbGllZFwiLFxuICAgICAgICBcImUtYmFza2V0OnVwZGF0ZSBwcm9kdWN0IFRvdGFsOlwiICsgc2FsZXRvdGFsLFxuICAgICAgICBwcm9kdWN0XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gc2FsZXRvdGFsO1xuICB9XG5cbiAgZ2V0UmVmdW5kZWRUb3RhbFdpdGhRdWFudGl0eShiYXNrZXREZXRhaWxzOiB7IHByb2R1Y3RzOiBzdHJpbmcgfCBhbnlbXTsgfSk6IG51bWJlciB7XG4gICAgbGV0IHF1YW50aXR5ID0gMDtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgYmFza2V0RGV0YWlscy5wcm9kdWN0cy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgIGNvbnN0IHByb2R1Y3Q6IGFueSA9IGJhc2tldERldGFpbHMucHJvZHVjdHNbaW5kZXhdO1xuXG4gICAgICBpZiAoIXByb2R1Y3QucmVmdW5kZWRSZWFzb25EZXNjcmlwdGlvbikge1xuXG4gICAgICAgIHF1YW50aXR5ID0gcXVhbnRpdHkgKyBwcm9kdWN0LnF1YW50aXR5O1xuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBxdWFudGl0eSA9IHF1YW50aXR5ICsgKHByb2R1Y3QucXVhbnRpdHkgLSBwcm9kdWN0LnJlZnVuZGVkUXVhbnRpdHkpO1xuXG4gICAgICAgIC8vIGJhc2tldERldGFpbHMudG90YWwgPSBiYXNrZXREZXRhaWxzLnRvdGFsICsgcHJvZHVjdC5yZWZ1bmRlZFRvdGFsO1xuXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBxdWFudGl0eTtcblxuICB9XG5cbiAgLyoqXG4gICAqIERpc2NvdW50IFRvdGFsXG4gICAqIEByZXR1cm5zIERpc2NvdW50IFRvdGFsXG4gICAqL1xuICB1cGRhdGVEaXNjb3VudFRvdGFsKCkge1xuICAgIGxldCByZWZ1bmRUb3RhbCA9IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXRTdW1tYXJ5LnJlZnVuZFRvdGFsID8gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkucmVmdW5kVG90YWwgOiAwO1xuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nSW5mbyh0aGlzLmNsYXNzTmFtZSwgXCJ1cGRhdGVEaXNjb3VudFRvdGFsXCIsIGByZWZ1bmRUb3RhbDogJHtyZWZ1bmRUb3RhbH0gdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnk6ICR7dGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnl9YCk7XG4gICAgY29uc3QgZGlzY291bnRUb3RhbCA9XG4gICAgICBNYXRoLmFicyhcbiAgICAgICAgTWF0aC5hYnModGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldFN1bW1hcnkuc2FsZVRvdGFsKSAtXG4gICAgICAgIChcbiAgICAgICAgICBNYXRoLmFicyh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0U3VtbWFyeS5iYXNrZXRUb3RhbCkgKyBNYXRoLmFicyhyZWZ1bmRUb3RhbClcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcInVwZGF0ZURpc2NvdW50VG90YWxcIiwgXCJkaXNjb3VudFRvdGFsXCIsIGRpc2NvdW50VG90YWwpXG4gICAgcmV0dXJuIE51bWJlcihkaXNjb3VudFRvdGFsLnRvRml4ZWQoMikpO1xuICB9XG5cbiAgdXBkYXRlUmVhc29uQ29kZShyZWFzb25Db2RlOiB7XG4gICAgY29kZTogc3RyaW5nO1xuICAgIG5hbWU6IHN0cmluZztcbiAgfSk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQucmVhc29uQ29kZSA9IHJlYXNvbkNvZGUuY29kZTtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQucmVhc29uRGVzY3JpcHRpb24gPSByZWFzb25Db2RlLm5hbWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB1cGRhdGVNYW5hZ2VyT3ZlcnJpZGUoXG4gICAgdXNlcm92ZXJyaWRlOiBVc2VyT3ZlcnJpZGVcbiAgKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5vdmVycmlkZSA9IHVzZXJvdmVycmlkZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHVwZGF0ZVVzZXJJRChcbiAgICB1c2VySUQ6IHN0cmluZ1xuICApOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnVzZXJJZCA9IHVzZXJJRDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHVwZGF0ZVVzZXJOYW1lKG5hbWU6IGFueSkgOiBUcmFuc2FjdGlvbkRvY3VtZW50QnVpbGRlciB7XG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnVzZXJOYW1lID0gbmFtZTtcbiAgICByZXR1cm4gdGhpcztcblxuICB9XG4gIFxuICBhZGRDdXN0b21lckRldGFpbHMoY3VzdG9tZXJEZXRhaWw6IEN1c3RvbWVyKTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5jdXN0b21lciA9IGN1c3RvbWVyRGV0YWlsO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdXBkYXRlVGF4QnJlYWtkb3duKGJhc2tldERldGFpbHM6IEJhc2tldCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICAvLyBsZXQgdHJhbnNhY3Rpb25EaXNjb3VudFRvdGFsID0gMDtcbiAgICBsZXQgdGF4QnJlYWtkb3duOiBUYXhCcmVha2Rvd24gPSB7XG4gICAgICB0YXhMaW5lczogW10sXG4gICAgICB0b3RhbFRheGFibGVBbW91bnQ6IDAsXG4gICAgfTtcblxuXG5cbiAgICAvLyBpZiAodGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50cmFuc2FjdGlvbkRpc2NvdW50ICYmIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25EaXNjb3VudC5sZW5ndGggPiAwKSB7XG4gICAgLy8gICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uRGlzY291bnQuZm9yRWFjaCgoZGlzY291bnQpID0+IHtcbiAgICAvLyAgICAgdHJhbnNhY3Rpb25EaXNjb3VudFRvdGFsICs9IGRpc2NvdW50LmRpc2NvdW50QW1vdW50O1xuICAgIC8vICAgfSk7XG4gICAgLy8gfVxuXG4gICAgLy8gaWYgKHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudHJhbnNhY3Rpb25Qcm9tb3Rpb24gJiYgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50cmFuc2FjdGlvblByb21vdGlvbi5sZW5ndGggPiAwKSB7XG4gICAgLy8gICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRyYW5zYWN0aW9uUHJvbW90aW9uLmZvckVhY2goXG4gICAgLy8gICAgIChwcm9tb3Rpb24pID0+IHtcbiAgICAvLyAgICAgICB0cmFuc2FjdGlvbkRpc2NvdW50VG90YWwgKz0gcHJvbW90aW9uLnByb21vdGlvbkFtb3VudDtcbiAgICAvLyAgICAgfVxuICAgIC8vICAgKTtcbiAgICAvLyB9XG5cbiAgICBiYXNrZXREZXRhaWxzLnByb2R1Y3RzLmZvckVhY2goKHByb2R1Y3Q6IGFueSkgPT4ge1xuICAgICAgbGV0IHRheExpbmU6IFRheExpbmUgPSB7XG4gICAgICAgIGl0ZW1MaW5lSWQ6IHByb2R1Y3QuaXRlbUxpbmVJZCxcbiAgICAgICAgVkFUOiBwcm9kdWN0LnNlbGVjdGVkVkFUID8gcHJvZHVjdC5zZWxlY3RlZFZBVCA6IDAsXG4gICAgICAgIFZBVENvZGU6IHByb2R1Y3Quc2VsZWN0ZWRWQVRDb2RlLFxuICAgICAgICB0YXhMaW5lVG90YWw6IDAsXG4gICAgICAgIHRheGFibGVBbW91bnQ6IHByb2R1Y3QudG90YWwsXG4gICAgICAgIFByZVRheDogMFxuICAgICAgfTtcbiAgICAgIEFwcExvZ2dlclNlcnZpY2UubG9nSW5mbyh0aGlzLmNsYXNzTmFtZSwgXCJ1cGRhdGVUYXhCcmVha2Rvd25cIiwgYGl0ZW0gbGluZSBJRCA6LCAke3Byb2R1Y3QuaXRlbUxpbmVJZH0sXG4gICAgICAgIFwidGF4IGxpbmUgOlwiLCAke3RheExpbmV9YCk7XG5cbiAgICAgIC8vIHN0ZXAgMVxuICAgICAgLy8gaWYgVHJhbnNhY3Rpb24gRGlzY291bnQgYW5kL29yIHByb21vdGlvbiBhcHBsaWVkLCBmaW5kIG5ldCBzZWxsaW5nIHByaWNlIG9mIGVhY2ggcHJvZHVjdCBhcyB0YXhhYmxlYW1vdW50XG4gICAgICAvLyBpZiAodHJhbnNhY3Rpb25EaXNjb3VudFRvdGFsID4gMCkge1xuICAgICAgcHJvZHVjdCA9IHRoaXMuYmFza2V0U2VydmljZS52YWxpZGF0ZVByb2R1Y3RJdGVtRGlzY291bnQocHJvZHVjdCk7XG5cbiAgICAgIGNvbnN0IHByb2R1Y3RDb250cmlidXRpb25JblRvdGFsID1cbiAgICAgICAgcHJvZHVjdC5pdGVtRGlzY291bnRzLnRybkRpc2NvdW50c1BvcnRpb24gK1xuICAgICAgICBwcm9kdWN0Lml0ZW1EaXNjb3VudHMudHJuUHJvbW90aW9uc1BvcnRpb24gLVxuICAgICAgICBwcm9kdWN0Lml0ZW1EaXNjb3VudHMucmVmdW5kUG9ydGlvbjtcbiAgICAgIC8vICB0cCt0ZC1ycDtcblxuICAgICAgQXBwTG9nZ2VyU2VydmljZS5sb2dJbmZvKHRoaXMuY2xhc3NOYW1lLCBcInVwZGF0ZVRheEJyZWFrZG93blwiLCBgaXRlbSBsaW5lIElEICwgJHtwcm9kdWN0Lml0ZW1MaW5lSWR9LFxuICAgICAgICBcImNvbnRyaWJ1dGlvbiA6XCIsICR7cHJvZHVjdENvbnRyaWJ1dGlvbkluVG90YWx9YCk7XG4gICAgICAvLyBjYWxjdWxhdGUgbmV0IHNlbGxpbmcgcHJpY2UgYWZ0ZXIgYXBwbHlpbmcgdHJhbnNhY3Rpb24gZGlzY291bnQgYXMgcGVyIHByb2R1Y3QgY29udHJpYnV0aW9uXG4gICAgICB0YXhMaW5lLnRheGFibGVBbW91bnQgLT0gcHJvZHVjdENvbnRyaWJ1dGlvbkluVG90YWw7XG4gICAgICAvLyB9XG5cbiAgICAgIC8vc3RlcCAyIC0gZmluZCBwcmUgdGF4XG4gICAgICB0YXhMaW5lLlByZVRheCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKCh0YXhMaW5lLnRheGFibGVBbW91bnQgKiAxMDApIC8gKDEwMCArIHRheExpbmUuVkFUKSk7XG5cbiAgICAgIC8vc3RlcCAzIC0gVXBkYXRlIHRheGJyZWFrZG93blxuICAgICAgdGF4QnJlYWtkb3duLnRvdGFsVGF4YWJsZUFtb3VudCArPSB0YXhMaW5lLnRheGFibGVBbW91bnQ7XG4gICAgICB0YXhMaW5lLnRheGFibGVBbW91bnQgPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMih0YXhMaW5lLnRheGFibGVBbW91bnQpO1xuICAgICAgXG4gICAgICAvLyBzdGVwIDQgLSB1cGRhdGUgdGF4IExpbmUgdG90YWxcbiAgICAgIHRheExpbmUudGF4TGluZVRvdGFsID0gIHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRheExpbmUudGF4YWJsZUFtb3VudCAtIHRheExpbmUuUHJlVGF4KTtcbiAgICAgIHRheEJyZWFrZG93bi50YXhMaW5lcy5wdXNoKHRheExpbmUpO1xuICAgIH0pO1xuXG4gICAgdGF4QnJlYWtkb3duLnRvdGFsVGF4YWJsZUFtb3VudCA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKHRheEJyZWFrZG93bi50b3RhbFRheGFibGVBbW91bnQpO1xuICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudGF4QnJlYWtkb3duID0gdGF4QnJlYWtkb3duO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdXBkYXRlVG90YWxUYXhTdW1tYXJ5KCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcblxuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwidXBkYXRlVG90YWxUYXhTdW1tYXJ5XCIsIFwiVG90YWwgVGF4IFN1bW1lcnkgUmVxdWVzdCA6XCIsIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudGF4QnJlYWtkb3duKTtcblxuXG4gICAgbGV0IHRvdGFsVGF4U3VtbWFyeUFycmF5OiBUb3RhbFRheFN1bW1hcnlbXSA9IFtdXG4gICAgbGV0IHRvdGFsVGF4U3VtbWFyeUdyb3VwID0gW11cblxuICAgIEFwcExvZ2dlclNlcnZpY2UubG9nRGVidWcodGhpcy5jbGFzc05hbWUsIFwidXBkYXRlVG90YWxUYXhTdW1tYXJ5XCIsIFwiVGF4IExpbmVzIGZvciBUb3RhbCBUYXggU3VtbWVyeSA6XCIsIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQudGF4QnJlYWtkb3duLnRheExpbmVzKTtcblxuXG4gICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LmJhc2tldC50YXhCcmVha2Rvd24udGF4TGluZXMuZm9yRWFjaCgoZWxlbWVudDogeyBWQVRDb2RlOiBhbnk7IFZBVDogYW55OyBQcmVUYXg6IGFueTsgdGF4TGluZVRvdGFsOiBhbnk7IH0pID0+IHtcbiAgICAgIGxldCBUYXhTdW1tYXJ5OiBUb3RhbFRheFN1bW1hcnkgPSB7XG4gICAgICAgIFZBVENvZGU6IFwiXCIsXG4gICAgICAgIFZBVDogLTEyMzQ1LFxuICAgICAgICBQcmVUYXhTdW06IDAsXG4gICAgICAgIFRheFN1bTogMCxcbiAgICAgICAgVFhyYXRlU3VtOiAwXG4gIFxuICAgICAgfTtcbiAgICAgICBUYXhTdW1tYXJ5LlZBVENvZGUgPSBlbGVtZW50LlZBVENvZGU7XG4gICAgICAgIFRheFN1bW1hcnkuVkFUID0gZWxlbWVudC5WQVQ7ICAgICAgICBcbiAgICAgICAgVGF4U3VtbWFyeS5QcmVUYXhTdW0gPSB0aGlzLm51bWJlclV0aWxTZXJ2aWNlLnRyaW1UbzJEZWNpbWFsMihlbGVtZW50LlByZVRheCk7XG4gICAgICAgIFRheFN1bW1hcnkuVGF4U3VtID0gdGhpcy5udW1iZXJVdGlsU2VydmljZS50cmltVG8yRGVjaW1hbDIoZWxlbWVudC50YXhMaW5lVG90YWwpO1xuICAgICAgICBUYXhTdW1tYXJ5LlRYcmF0ZVN1bSA9IHRoaXMubnVtYmVyVXRpbFNlcnZpY2UudHJpbVRvMkRlY2ltYWwyKFRheFN1bW1hcnkuUHJlVGF4U3VtICsgVGF4U3VtbWFyeS5UYXhTdW0pOyAgICAgIFxuICAgICAgICB0b3RhbFRheFN1bW1hcnlBcnJheS5wdXNoKFRheFN1bW1hcnkpO1xuICAgIH0pXG5cbiAgICBBcHBMb2dnZXJTZXJ2aWNlLmxvZ0RlYnVnKHRoaXMuY2xhc3NOYW1lLCBcInVwZGF0ZVRvdGFsVGF4U3VtbWFyeVwiLCBcIlRvdGFsIFRheCBTdW1tZXJ5ICBXaXRob3V0IEdyb3VwZWQgOiBcIiwgdG90YWxUYXhTdW1tYXJ5QXJyYXkpO1xuICAgIFxuICAgIHRvdGFsVGF4U3VtbWFyeUdyb3VwID0gdG90YWxUYXhTdW1tYXJ5QXJyYXkucmVkdWNlKChwcmVwYXJlZEFycmF5OmFueSxjdXJyZW50T2JqKSA9PiB7XG5cbiAgICAgIGxldCBpbmQgPSBwcmVwYXJlZEFycmF5LmZpbmRJbmRleCgoeDogeyBWQVQ6IGFueTsgfSkgPT4geC5WQVQgPT09IGN1cnJlbnRPYmouVkFUKTtcbiAgICAgIGlmKGluZCA9PT0gLTEpe1xuICAgICAgICBwcmVwYXJlZEFycmF5LnB1c2goY3VycmVudE9iailcbiAgICAgIH1lbHNlIHtcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlZBVENvZGUgPSBjdXJyZW50T2JqLlZBVENvZGU7XG4gICAgICAgIHByZXBhcmVkQXJyYXlbaW5kXS5WQVQgPSBjdXJyZW50T2JqLlZBVDtcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlByZVRheFN1bSArPSBjdXJyZW50T2JqLlByZVRheFN1bTtcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlRheFN1bSArPSBjdXJyZW50T2JqLlRheFN1bTtcbiAgICAgICAgcHJlcGFyZWRBcnJheVtpbmRdLlRYcmF0ZVN1bSArPSBjdXJyZW50T2JqLlRYcmF0ZVN1bTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwcmVwYXJlZEFycmF5O1xuICAgIH0sW10pXG4gICAgXG4gICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJ1cGRhdGVUb3RhbFRheFN1bW1hcnlcIiwgXCJUb3RhbCAgVGF4IFN1bW1lciBHcm91cCA6XCIsdG90YWxUYXhTdW1tYXJ5R3JvdXApO1xuXG5cbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQuYmFza2V0LnRvdGFsVGF4U3VtbWFyeSA9IHRvdGFsVGF4U3VtbWFyeUdyb3VwO1xuXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgfVxuXG5cbiAgLyoqXG4gICAqIFRyYW5zYWN0aW9uSWRcbiAgICogQHJldHVybnMgT3JpZ2luYWxUcmFuc2FjdGlvbklkXG4gICAqL1xuICBhZGRPcmlnaW5hbFRyYW5zSWQodHJhbkRvYzpUcmFuc2FjdGlvbkRvY3VtZW50KTogVHJhbnNhY3Rpb25Eb2N1bWVudEJ1aWxkZXIge1xuICAgIGlmICh0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudHlwZSA9PT0gVFJBTlNBQ1RJT05fVFlQRS5SRUZVTkQgfHwgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnR5cGUgPT09IFRSQU5TQUNUSU9OX1RZUEUuU0FMRV9SRUZVTkQgfHwgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50LnR5cGUgPT09IFRSQU5TQUNUSU9OX1RZUEUuU0FMRV9FWENIQU5HRSkge1xuICAgICAgdGhpcy50cmFuc2FjdGlvbkRvY3VtZW50Lm9yaWdpbmFsVHJhbnNJZCA9IHRyYW5Eb2MudHJhbnNhY3Rpb25JZDtcbiAgICAgIGlmKHRyYW5Eb2MuYXBpUmVzcG9uc2UgJiYgdHJhbkRvYy5hcGlSZXNwb25zZS5pbnRlcm5hbElkKVxuICAgICAge1xuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQub3JpZ2luYWxFeHRlcm5hbElkID0gdHJhbkRvYy5hcGlSZXNwb25zZS5pbnRlcm5hbElkLnRvU3RyaW5nKCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIHVucmVmZXJlbmNlZCBSZWZ1bmRcbiAgICogQHJldHVybnMgYm9vbGVhbiB2YWx1ZVxuICAgKi9cbiAgYWRkVW5yZWZlcmVuY2VkUmVmdW5kKCk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRG9jdW1lbnQudW5yZWZlcmVuY2VkUmVmdW5kID0gdHJ1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGdldFJlZnVuZFRvdGFsKCkge1xuICAgIGxldCB0b3RhbFJlZnVuZCA9IDA7XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQucHJvZHVjdHMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjb25zdCBwcm9kdWN0OiBUUHJvZHVjdCA9IHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5iYXNrZXQucHJvZHVjdHNbaW5kZXhdO1xuICAgICAgaWYgKHByb2R1Y3QucmVmdW5kZWRUb3RhbCkge1xuICAgICAgICB0b3RhbFJlZnVuZCA9IHRvdGFsUmVmdW5kICsgcHJvZHVjdC5yZWZ1bmRlZFRvdGFsO1xuICAgICAgfVxuICAgICAgQXBwTG9nZ2VyU2VydmljZS5sb2dEZWJ1Zyh0aGlzLmNsYXNzTmFtZSwgXCJnZXRSZWZ1bmRUb3RhbFwiLCBcInRvdGFsUmVmdW5kXCIgLCB0b3RhbFJlZnVuZClcbiAgICB9XG4gICAgcmV0dXJuIHRvdGFsUmVmdW5kO1xuICB9XG5cbiAgZG9jSWQoZG9jSWQ6IGFueSk6IFRyYW5zYWN0aW9uRG9jdW1lbnRCdWlsZGVyIHtcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25Eb2N1bWVudC5pZCA9IGRvY0lkO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59XG4iXX0=
|