@almatar/smart-booking-dashboard 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +132 -0
- package/esm2022/almatar-smart-booking-dashboard.mjs +5 -0
- package/esm2022/lib/components/action-card/action-card.component.mjs +19 -0
- package/esm2022/lib/components/action-dialog/action-dialog.component.mjs +177 -0
- package/esm2022/lib/components/action-grid/action-grid.component.mjs +18 -0
- package/esm2022/lib/components/add-note-dialog/add-note-dialog.component.mjs +62 -0
- package/esm2022/lib/components/booking-input/booking-input.component.mjs +43 -0
- package/esm2022/lib/components/cancel-dialog/cancel-dialog.component.mjs +1441 -0
- package/esm2022/lib/components/data-search/data-search.component.mjs +84 -0
- package/esm2022/lib/components/flight-itinerary-card/flight-itinerary-card.component.mjs +73 -0
- package/esm2022/lib/components/result-panel/result-panel.component.mjs +46 -0
- package/esm2022/lib/components/workflow-actions/workflow-actions.component.mjs +19 -0
- package/esm2022/lib/config/dashboard.config.mjs +16 -0
- package/esm2022/lib/config/flight-actions.config.mjs +906 -0
- package/esm2022/lib/config/hotel-actions.config.mjs +53 -0
- package/esm2022/lib/config/labels.ar.mjs +116 -0
- package/esm2022/lib/models/action.types.mjs +2 -0
- package/esm2022/lib/models/booking.types.mjs +2 -0
- package/esm2022/lib/pages/smart-booking-dashboard/smart-booking-dashboard.component.mjs +145 -0
- package/esm2022/lib/services/booking.service.mjs +65 -0
- package/esm2022/lib/services/toast.service.mjs +19 -0
- package/esm2022/lib/smart-booking-dashboard.module.mjs +17 -0
- package/esm2022/lib/smart-booking-dashboard.routes.mjs +7 -0
- package/esm2022/public-api.mjs +9 -0
- package/fesm2022/almatar-smart-booking-dashboard.mjs +3259 -0
- package/fesm2022/almatar-smart-booking-dashboard.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/components/action-card/action-card.component.d.ts +10 -0
- package/lib/components/action-dialog/action-dialog.component.d.ts +26 -0
- package/lib/components/action-grid/action-grid.component.d.ts +10 -0
- package/lib/components/add-note-dialog/add-note-dialog.component.d.ts +25 -0
- package/lib/components/booking-input/booking-input.component.d.ts +23 -0
- package/lib/components/cancel-dialog/cancel-dialog.component.d.ts +395 -0
- package/lib/components/data-search/data-search.component.d.ts +21 -0
- package/lib/components/flight-itinerary-card/flight-itinerary-card.component.d.ts +17 -0
- package/lib/components/result-panel/result-panel.component.d.ts +14 -0
- package/lib/components/workflow-actions/workflow-actions.component.d.ts +7 -0
- package/lib/config/dashboard.config.d.ts +15 -0
- package/lib/config/flight-actions.config.d.ts +2 -0
- package/lib/config/hotel-actions.config.d.ts +2 -0
- package/lib/config/labels.ar.d.ts +2 -0
- package/lib/models/action.types.d.ts +34 -0
- package/lib/models/booking.types.d.ts +6 -0
- package/lib/pages/smart-booking-dashboard/smart-booking-dashboard.component.d.ts +43 -0
- package/lib/services/booking.service.d.ts +22 -0
- package/lib/services/toast.service.d.ts +10 -0
- package/lib/smart-booking-dashboard.module.d.ts +7 -0
- package/lib/smart-booking-dashboard.routes.d.ts +2 -0
- package/package.json +50 -0
- package/public-api.d.ts +5 -0
|
@@ -0,0 +1,1441 @@
|
|
|
1
|
+
import { Component, input, output, inject, effect, signal, computed } from '@angular/core';
|
|
2
|
+
import { NgTemplateOutlet, NgClass } from '@angular/common';
|
|
3
|
+
import { DialogModule } from 'primeng/dialog';
|
|
4
|
+
import { ButtonModule } from 'primeng/button';
|
|
5
|
+
import { SkeletonModule } from 'primeng/skeleton';
|
|
6
|
+
import { SbdBookingService } from '../../services/booking.service';
|
|
7
|
+
import { SbdToastService } from '../../services/toast.service';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "primeng/dialog";
|
|
10
|
+
import * as i2 from "primeng/button";
|
|
11
|
+
const DEDUCTION_DEFS = [
|
|
12
|
+
{ key: 'totalPenaltyPoints', label: 'Airline Cancellation Fee', badge: '' },
|
|
13
|
+
{ key: 'handlingFee', label: 'Handling Fee', badge: '' },
|
|
14
|
+
{ key: 'totalNonRefundableServiceCharge', label: 'Service Charge', badge: '' },
|
|
15
|
+
{ key: 'totalAncillaryRefundAmount', label: 'Ancillary Fee', badge: '' },
|
|
16
|
+
{ key: 'totalGiftAmount', label: 'Add on Fee', badge: '' },
|
|
17
|
+
// `totalLoyaltyPoints` (points spent at booking time, now forfeited) is
|
|
18
|
+
// intentionally not listed here — it's already surfaced under its own
|
|
19
|
+
// program name (e.g. "Qitaf") in the "Total Paid" breakdown, so listing it
|
|
20
|
+
// again here would double up the same amount under two different sections.
|
|
21
|
+
];
|
|
22
|
+
const REFUND_DEFS = [
|
|
23
|
+
{ key: 'totalCardRefundAmount', label: 'Refund Amount' },
|
|
24
|
+
{ key: 'totalCreditRefundAmount', label: 'Credit Shell Refund' },
|
|
25
|
+
{ key: 'walletRefundAmount', label: 'Almatar Wallet' },
|
|
26
|
+
{ key: 'totalLoyaltyPointsRefundAmount', label: 'Loyalty Points Refund' },
|
|
27
|
+
];
|
|
28
|
+
/** Labels for `paymentMethodCustomerUsed` gateway codes returned by the backend. */
|
|
29
|
+
const PAYMENT_GATEWAY_LABELS = {
|
|
30
|
+
CH: 'Card',
|
|
31
|
+
HP: 'Hyperpay',
|
|
32
|
+
MF: 'My Fatoora',
|
|
33
|
+
WT: 'Wire Transfer',
|
|
34
|
+
STC: 'STC',
|
|
35
|
+
TM: 'Tamara',
|
|
36
|
+
TB: 'Tabby',
|
|
37
|
+
RAJHI: 'Al Rajhi Mokafaa',
|
|
38
|
+
PPB: 'Customer Balance',
|
|
39
|
+
PP: 'Postpay',
|
|
40
|
+
TAMAM: 'Tamam',
|
|
41
|
+
QITAF: 'Qitaf',
|
|
42
|
+
MIS: 'MIS Pay',
|
|
43
|
+
MATAR: 'Almatar Pay',
|
|
44
|
+
CB: 'Company Balance',
|
|
45
|
+
ANB: 'ANB',
|
|
46
|
+
AMWAL: 'Amwal',
|
|
47
|
+
WALA: 'Wala',
|
|
48
|
+
YGG: 'YGG',
|
|
49
|
+
};
|
|
50
|
+
/** Gateway codes that refund to an installment plan rather than the original card. */
|
|
51
|
+
const INSTALLMENT_GATEWAY_CODES = ['TM', 'TB'];
|
|
52
|
+
/** Gateway codes that refund to a loyalty-program account rather than the original card. */
|
|
53
|
+
const LOYALTY_GATEWAY_CODES = ['RAJHI', 'QITAF', 'STC', 'WALA'];
|
|
54
|
+
/**
|
|
55
|
+
* Internal payment-processor/gateway names, never customer-recognizable
|
|
56
|
+
* brands — must not be surfaced verbatim (e.g. a card refund processed
|
|
57
|
+
* through Hyperpay must read as "Card"/"Original Payment Method", never
|
|
58
|
+
* "Hyperpay"). Callers fall back to a generic label whenever the normalized
|
|
59
|
+
* lookup returns ''.
|
|
60
|
+
*/
|
|
61
|
+
const INTERNAL_GATEWAY_CODES = ['HP', 'MF', 'WT', 'PPB', 'PP', 'TAMAM'];
|
|
62
|
+
/**
|
|
63
|
+
* Result/confirmation-screen-only override: these gateways process card
|
|
64
|
+
* payments through Mada — shown specifically as "Mada Card" instead of
|
|
65
|
+
* falling back to the generic "Original Payment Method" label used
|
|
66
|
+
* everywhere else `INTERNAL_GATEWAY_CODES` applies.
|
|
67
|
+
*/
|
|
68
|
+
const MADA_GATEWAY_CODES = ['HP', 'CH'];
|
|
69
|
+
const CREDIT_SHELL_SUFFIX = 'It can be used only for future booking on the airline website.';
|
|
70
|
+
const GIFT_HINT = 'Please note: If you cancel either leg of your round-trip booking, the add-on/gift service will be cancelled automatically.';
|
|
71
|
+
export class SbdCancelDialogComponent {
|
|
72
|
+
/**
|
|
73
|
+
* The return leg is matched by an explicit 'Return' direction; the onward
|
|
74
|
+
* leg is whatever's left (some bookings don't tag the outbound leg with an
|
|
75
|
+
* explicit 'Departure' value), falling back to the first entry.
|
|
76
|
+
*/
|
|
77
|
+
itineraryLeg(kind) {
|
|
78
|
+
const legs = this.itineraryLegs();
|
|
79
|
+
if (!legs.length)
|
|
80
|
+
return null;
|
|
81
|
+
const returnLeg = legs.find((l) => (l.direction ?? '').toLowerCase() === 'return') ?? null;
|
|
82
|
+
if (kind === 'return')
|
|
83
|
+
return returnLeg;
|
|
84
|
+
return (legs.find((l) => (l.direction ?? '').toLowerCase() === 'departure') ??
|
|
85
|
+
legs.find((l) => l !== returnLeg) ??
|
|
86
|
+
legs[0] ??
|
|
87
|
+
null);
|
|
88
|
+
}
|
|
89
|
+
fmtTime(dt) {
|
|
90
|
+
if (!dt)
|
|
91
|
+
return '—';
|
|
92
|
+
try {
|
|
93
|
+
return new Date(dt).toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' });
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return dt;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
fmtShortDate(dt) {
|
|
100
|
+
if (!dt)
|
|
101
|
+
return '—';
|
|
102
|
+
try {
|
|
103
|
+
return new Date(dt).toLocaleDateString('en-GB', { weekday: 'short', day: '2-digit', month: 'short' });
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return dt;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
fmtMins(mins) {
|
|
110
|
+
if (mins == null)
|
|
111
|
+
return '';
|
|
112
|
+
return `${Math.floor(mins / 60)}h ${mins % 60}m`;
|
|
113
|
+
}
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
115
|
+
applySourceOverride(base, breakdown) {
|
|
116
|
+
const sel = this.selectedSource();
|
|
117
|
+
if (!sel || !breakdown || !breakdown[sel])
|
|
118
|
+
return this.reconcileSoleDestination(base);
|
|
119
|
+
const src = breakdown[sel];
|
|
120
|
+
const sourceRefundable = src.isRefundable !== false; // default true if not set
|
|
121
|
+
if (!sourceRefundable) {
|
|
122
|
+
// Source cannot process refund — zero out financial fields
|
|
123
|
+
return this.reconcileSoleDestination({
|
|
124
|
+
...base,
|
|
125
|
+
isRefundable: false,
|
|
126
|
+
totalPenaltyPoints: 0,
|
|
127
|
+
totalSupplierPenaltyPoints: 0,
|
|
128
|
+
totalCancellationFee: 0,
|
|
129
|
+
totalRefundAmount: 0,
|
|
130
|
+
totalCardRefundAmount: 0,
|
|
131
|
+
handlingFee: 0,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// Prefer the source's own walletRefundAmount/totalCardRefundAmount when
|
|
135
|
+
// the API provides them (they're already net of each other for this
|
|
136
|
+
// source) — only fall back to deriving cardRefund when the API doesn't.
|
|
137
|
+
const newTotal = Number(src.totalRefundAmount || 0);
|
|
138
|
+
const walletRefund = src.walletRefundAmount !== undefined
|
|
139
|
+
? Number(src.walletRefundAmount || 0)
|
|
140
|
+
: Number(base.walletRefundAmount || 0);
|
|
141
|
+
const cardRefund = src.totalCardRefundAmount !== undefined
|
|
142
|
+
? Number(src.totalCardRefundAmount || 0)
|
|
143
|
+
: Math.max(0, newTotal -
|
|
144
|
+
Number(base.totalCreditRefundAmount || 0) -
|
|
145
|
+
walletRefund -
|
|
146
|
+
Number(base.totalLoyaltyPointsRefundAmount || 0));
|
|
147
|
+
return this.reconcileSoleDestination({
|
|
148
|
+
...base,
|
|
149
|
+
isRefundable: true,
|
|
150
|
+
totalPenaltyPoints: Number(src.totalSupplierPenaltyPoints || 0),
|
|
151
|
+
totalSupplierPenaltyPoints: Number(src.totalSupplierPenaltyPoints || 0),
|
|
152
|
+
totalCancellationFee: Number(src.totalCancellationFee || 0),
|
|
153
|
+
totalRefundAmount: newTotal,
|
|
154
|
+
walletRefundAmount: walletRefund,
|
|
155
|
+
totalCardRefundAmount: cardRefund,
|
|
156
|
+
handlingFee: Number(src.handlingFee || 0),
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* When exactly one of the four refund-destination fields (wallet / card /
|
|
161
|
+
* credit / loyalty) is non-zero, the backend has occasionally sent that
|
|
162
|
+
* field as a pre-deduction value that disagrees with the declared total
|
|
163
|
+
* (e.g. wallet = total + cancellation fee) — there's no ambiguity about
|
|
164
|
+
* *where* the money goes, only a stale number in that one field, so trust
|
|
165
|
+
* the declared total and correct the sole destination to match rather
|
|
166
|
+
* than surfacing a false discrepancy.
|
|
167
|
+
*/
|
|
168
|
+
reconcileSoleDestination(d) {
|
|
169
|
+
if (!d?.isRefundable)
|
|
170
|
+
return d;
|
|
171
|
+
const wallet = Number(d.walletRefundAmount ?? 0);
|
|
172
|
+
const card = Number(d.totalCardRefundAmount ?? 0);
|
|
173
|
+
const credit = Number(d.totalCreditRefundAmount ?? 0);
|
|
174
|
+
const loyalty = Number(d.totalLoyaltyPointsRefundAmount ?? 0);
|
|
175
|
+
// A forfeited-points destination (e.g. Qitaf points funded separately
|
|
176
|
+
// from the card refund) also counts as a real destination here — without
|
|
177
|
+
// this, a legitimately split card+loyalty-points refund (e.g. 918 card +
|
|
178
|
+
// 50 Qitaf points = 968 total) looks like a single stale "card" field to
|
|
179
|
+
// this heuristic, which then force-overwrites the correct 918 with the
|
|
180
|
+
// full 968 total and silently erases the split.
|
|
181
|
+
const forfeitedLoyalty = this.forfeitedLoyaltyPointsFallback(d);
|
|
182
|
+
const nonZero = [wallet, card, credit, loyalty, forfeitedLoyalty].filter((v) => v > 0);
|
|
183
|
+
if (nonZero.length !== 1)
|
|
184
|
+
return d;
|
|
185
|
+
const total = Number(d.totalRefundAmountBeforeCeil ?? d.totalRefundAmount ?? 0);
|
|
186
|
+
if (wallet > 0 && Math.abs(wallet - total) >= 0.01)
|
|
187
|
+
return { ...d, walletRefundAmount: total };
|
|
188
|
+
if (card > 0 && Math.abs(card - total) >= 0.01)
|
|
189
|
+
return { ...d, totalCardRefundAmount: total };
|
|
190
|
+
if (credit > 0 && Math.abs(credit - total) >= 0.01)
|
|
191
|
+
return { ...d, totalCreditRefundAmount: total };
|
|
192
|
+
if (loyalty > 0 && Math.abs(loyalty - total) >= 0.01)
|
|
193
|
+
return { ...d, totalLoyaltyPointsRefundAmount: total };
|
|
194
|
+
return d;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Per-leg refund view (independent of the checkbox inclusion state) — used
|
|
198
|
+
* to render both legs' own breakdown cards simultaneously.
|
|
199
|
+
*/
|
|
200
|
+
legAdjustedData(legType) {
|
|
201
|
+
const root = this.refundData();
|
|
202
|
+
const leg = root?.legInfo?.[legType];
|
|
203
|
+
if (!root || !leg)
|
|
204
|
+
return null;
|
|
205
|
+
const base = this.buildLegData(root, leg, legType);
|
|
206
|
+
return this.applySourceOverride(base, leg.sourceBreakdown ?? null);
|
|
207
|
+
}
|
|
208
|
+
/** Deduction rows for a single leg's card. */
|
|
209
|
+
legDeductions(legType) {
|
|
210
|
+
return this.deductionRows(this.legAdjustedData(legType));
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Refundable pool ("Fare") for a leg — that leg's own paid amount
|
|
214
|
+
* (`totalSupplierBookingAmount`). `totalRefundAmount + totalCancellationFee`
|
|
215
|
+
* isn't reliable: `totalCancellationFee` doesn't include every deduction
|
|
216
|
+
* (e.g. `handlingFee`), which produced a Fare that didn't reconcile with
|
|
217
|
+
* Total Refund + the shown deductions.
|
|
218
|
+
*/
|
|
219
|
+
legRefundPool(legType) {
|
|
220
|
+
const d = this.legAdjustedData(legType);
|
|
221
|
+
if (!d)
|
|
222
|
+
return 0;
|
|
223
|
+
return Number(d.totalSupplierBookingAmount || 0);
|
|
224
|
+
}
|
|
225
|
+
/** True once a leg's own departure time has passed. */
|
|
226
|
+
legAlreadyFlown(legType) {
|
|
227
|
+
const depTime = this.itineraryLeg(legType)?.depTime;
|
|
228
|
+
if (!depTime)
|
|
229
|
+
return false;
|
|
230
|
+
const t = new Date(depTime).getTime();
|
|
231
|
+
return !Number.isNaN(t) && t < Date.now();
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Toggle a leg's inclusion. A non-refundable leg can't be checked, and the
|
|
235
|
+
* last checked leg can't be unchecked. Used on both the select-leg screen
|
|
236
|
+
* and the round-trip leg cards.
|
|
237
|
+
*/
|
|
238
|
+
toggleLeg(legType) {
|
|
239
|
+
const refundable = legType === 'onward' ? this.onwardRefundable() : this.returnRefundable();
|
|
240
|
+
if (!refundable)
|
|
241
|
+
return;
|
|
242
|
+
const self = legType === 'onward' ? this.onwardChecked : this.returnChecked;
|
|
243
|
+
const other = legType === 'onward' ? this.returnChecked : this.onwardChecked;
|
|
244
|
+
if (self() && !other())
|
|
245
|
+
return;
|
|
246
|
+
const isTurningOff = self();
|
|
247
|
+
if (isTurningOff &&
|
|
248
|
+
this.isRoundTrip() &&
|
|
249
|
+
!this.isCrossSeller() &&
|
|
250
|
+
!this.legAlreadyFlown(legType)) {
|
|
251
|
+
// Airline doesn't allow cancelling this leg on its own — block the
|
|
252
|
+
// uncheck, keep it checked+frozen, and surface the note.
|
|
253
|
+
this.forcedLegType.set(legType);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
this.forcedLegType.set(null);
|
|
257
|
+
self.set(!self());
|
|
258
|
+
// A leg may carry its own source list — re-resolve the selection.
|
|
259
|
+
const breakdown = this.activeSourceBreakdown() ?? {};
|
|
260
|
+
const sources = Object.keys(breakdown);
|
|
261
|
+
if (sources.length && !breakdown[this.selectedSource()]) {
|
|
262
|
+
this.selectedSource.set(sources[0]);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/** Toggle a leg card's expanded/collapsed state. */
|
|
266
|
+
toggleLegExpanded(legType) {
|
|
267
|
+
const sig = legType === 'onward' ? this.onwardExpanded : this.returnExpanded;
|
|
268
|
+
sig.set(!sig());
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Itemized refundable rows ("Fare" + named refundable add-ons/ancillaries)
|
|
272
|
+
* from `refundBreakdown.refundable`. Empty when the backend hasn't sent a
|
|
273
|
+
* breakdown yet — callers fall back to the single aggregate Fare row.
|
|
274
|
+
*/
|
|
275
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
276
|
+
refundableBreakdownRows(d) {
|
|
277
|
+
const b = d?.refundBreakdown?.refundable;
|
|
278
|
+
if (!b)
|
|
279
|
+
return [];
|
|
280
|
+
// Fare always shows from refundBreakdown.refundable.fare, even when 0 —
|
|
281
|
+
// never falls back to originalAmount.
|
|
282
|
+
const rows = [{ label: 'Fare', value: Number(b.fare ?? 0) }];
|
|
283
|
+
[...(b.addOns ?? []), ...(b.ancillaries ?? [])]
|
|
284
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
285
|
+
.filter((item) => Number(item.amount) > 0)
|
|
286
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
287
|
+
.forEach((item) => rows.push({ label: item.name, value: Number(item.amount) }));
|
|
288
|
+
return rows;
|
|
289
|
+
}
|
|
290
|
+
/** Named refundable add-ons/ancillaries only (excludes Fare) — drives the "processed separately" note. */
|
|
291
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
292
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
293
|
+
refundableAddonItems(d) {
|
|
294
|
+
// Only `addOns` need manual Customer Service processing — `ancillaries`
|
|
295
|
+
// (baggage, seat, auto check-in, …) are already itemized/refunded
|
|
296
|
+
// automatically as part of the total, no separate note needed for them.
|
|
297
|
+
const b = d?.refundBreakdown?.refundable;
|
|
298
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
299
|
+
return (b?.addOns ?? []).filter((item) => Number(item.amount) > 0);
|
|
300
|
+
}
|
|
301
|
+
/** Whether to show the "add-on refund processed separately by Customer Service" note. */
|
|
302
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
303
|
+
hasRefundableAddonNote(d) {
|
|
304
|
+
return this.refundableAddonItems(d).length > 0;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Deduction rows for the "Not Refunded" section. When an itemized
|
|
308
|
+
* breakdown is present, its named add-ons/ancillaries replace the
|
|
309
|
+
* aggregate `totalAncillaryRefundAmount`/`totalGiftAmount` rows (same
|
|
310
|
+
* money, named instead of lumped); the other generic rows (cancellation
|
|
311
|
+
* fee, handling fee, service charge) are unaffected.
|
|
312
|
+
*/
|
|
313
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
314
|
+
deductionRows(d) {
|
|
315
|
+
if (!d)
|
|
316
|
+
return [];
|
|
317
|
+
const b = d.refundBreakdown?.nonRefundable;
|
|
318
|
+
if (!b) {
|
|
319
|
+
return DEDUCTION_DEFS
|
|
320
|
+
.filter(def => Number(d[def.key]) > 0)
|
|
321
|
+
.map(def => ({ label: def.label, value: Number(d[def.key]), badge: def.badge }));
|
|
322
|
+
}
|
|
323
|
+
const itemRows = [...(b.addOns ?? []), ...(b.ancillaries ?? [])]
|
|
324
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
325
|
+
.filter((item) => Number(item.amount) > 0)
|
|
326
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
327
|
+
.map((item) => ({ label: item.name, value: Number(item.amount), badge: '' }));
|
|
328
|
+
const aggregateRows = DEDUCTION_DEFS
|
|
329
|
+
.filter(def => def.key !== 'totalAncillaryRefundAmount' && def.key !== 'totalGiftAmount')
|
|
330
|
+
.filter(def => Number(d[def.key]) > 0)
|
|
331
|
+
.map(def => ({ label: def.label, value: Number(d[def.key]), badge: def.badge }));
|
|
332
|
+
return [...itemRows, ...aggregateRows];
|
|
333
|
+
}
|
|
334
|
+
// Resolve the PNR for the currently selected leg from the booking's pnr_info list.
|
|
335
|
+
resolvePnr() {
|
|
336
|
+
const list = this.pnrInfo() ?? [];
|
|
337
|
+
if (!list.length)
|
|
338
|
+
return '';
|
|
339
|
+
const sel = this.selectedLeg();
|
|
340
|
+
const byDir = (dir) => list.find(p => p.LegDirectionality === dir)?.pnr;
|
|
341
|
+
if (sel === 'return')
|
|
342
|
+
return byDir('Return') ?? list[0]?.pnr ?? '';
|
|
343
|
+
if (sel === 'onward')
|
|
344
|
+
return byDir('Departure') ?? list[0]?.pnr ?? '';
|
|
345
|
+
return byDir('Departure') ?? list[0]?.pnr ?? '';
|
|
346
|
+
}
|
|
347
|
+
/** Rows that land in the wallet — plain wallet, wallet+loyalty combined, or loyalty-only — share the wallet icon/layout on the result screen. */
|
|
348
|
+
isWalletDestinationRow(r) {
|
|
349
|
+
return r.key === 'walletRefundAmount' || r.key === 'totalLoyaltyPoints';
|
|
350
|
+
}
|
|
351
|
+
fmtResult(value) {
|
|
352
|
+
const cur = this.cancelResult()?.currency ?? this.refundData()?.currency ?? 'SAR';
|
|
353
|
+
return `${Number(value || 0).toLocaleString('en-SA', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} ${cur}`;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* `totalLoyaltyPoints` is normally the forfeited-at-booking points count
|
|
357
|
+
* (no refund destination of its own). But when the backend never
|
|
358
|
+
* populates `totalLoyaltyPointsRefundAmount` for a `loyaltyPaymentType`
|
|
359
|
+
* booking, this is the only signal that a loyalty program was involved,
|
|
360
|
+
* so it doubles as a split-refund row (alongside Card/Wallet) rather than
|
|
361
|
+
* disappearing from the refund breakdown entirely. Always shown as its
|
|
362
|
+
* own row under the program name (e.g. "Wala") — never merged into the
|
|
363
|
+
* generic Wallet row, even when `walletRefundAmount` is also non-zero.
|
|
364
|
+
*/
|
|
365
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
366
|
+
forfeitedLoyaltyPointsFallback(d) {
|
|
367
|
+
if (!d?.loyaltyPaymentType)
|
|
368
|
+
return 0;
|
|
369
|
+
if (Number(d.totalLoyaltyPointsRefundAmount ?? 0) > 0)
|
|
370
|
+
return 0;
|
|
371
|
+
return Number(d.totalLoyaltyPoints ?? 0);
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Some `/confirm` responses for a single-leg (non-cross-seller) booking
|
|
375
|
+
* put `walletRefundAmount`/`totalLoyaltyPoints` on the wrong side at the
|
|
376
|
+
* root — e.g. root reads `walletRefundAmount: 40, totalLoyaltyPoints: 0`
|
|
377
|
+
* while the single leg (which should mirror root exactly here) reads
|
|
378
|
+
* `walletRefundAmount: 0, totalLoyaltyPoints: 40`. Detected narrowly: root
|
|
379
|
+
* shows no forfeited loyalty despite `loyaltyPaymentType` being set, the
|
|
380
|
+
* root wallet amount exactly equals the leg's loyalty points, and the
|
|
381
|
+
* leg's own wallet amount disagrees — in that specific case the leg's
|
|
382
|
+
* values are trusted instead, since with only one leg they're unambiguous.
|
|
383
|
+
*
|
|
384
|
+
* A second, more common shape: root doesn't swap at all, it folds the
|
|
385
|
+
* points straight into `walletRefundAmount` as one opaque lump sum (e.g.
|
|
386
|
+
* root wallet 340 = the leg's own cash wallet 300 + the leg's forfeited
|
|
387
|
+
* loyalty points 40). Split that back into the two parts the leg already
|
|
388
|
+
* tells us about too, so the result screen can show a combined wallet card
|
|
389
|
+
* with the program named instead of one unexplained total.
|
|
390
|
+
*/
|
|
391
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
392
|
+
correctedConfirmWalletAndLoyalty(d) {
|
|
393
|
+
const rootWallet = Number(d.walletRefundAmount ?? 0);
|
|
394
|
+
const forfeitedFromRoot = this.forfeitedLoyaltyPointsFallback(d);
|
|
395
|
+
if (forfeitedFromRoot > 0 || !d.loyaltyPaymentType) {
|
|
396
|
+
return { wallet: rootWallet, forfeitedLoyalty: forfeitedFromRoot };
|
|
397
|
+
}
|
|
398
|
+
const onward = d.legInfo?.onward;
|
|
399
|
+
const ret = d.legInfo?.return;
|
|
400
|
+
const leg = onward && !ret ? onward : ret && !onward ? ret : null;
|
|
401
|
+
if (!leg)
|
|
402
|
+
return { wallet: rootWallet, forfeitedLoyalty: 0 };
|
|
403
|
+
const legLoyalty = Number(leg.totalLoyaltyPoints ?? 0);
|
|
404
|
+
const legWallet = Number(leg.walletRefundAmount ?? 0);
|
|
405
|
+
// Full swap: root reads the leg's loyalty amount where its wallet should be.
|
|
406
|
+
if (legLoyalty > 0 &&
|
|
407
|
+
rootWallet === legLoyalty &&
|
|
408
|
+
legWallet !== rootWallet &&
|
|
409
|
+
Number(d.totalLoyaltyPointsRefundAmount ?? 0) === 0) {
|
|
410
|
+
return { wallet: legWallet, forfeitedLoyalty: legLoyalty };
|
|
411
|
+
}
|
|
412
|
+
// Lump sum: root wallet = leg's cash wallet + leg's forfeited loyalty.
|
|
413
|
+
if (legLoyalty > 0 &&
|
|
414
|
+
legWallet > 0 &&
|
|
415
|
+
Math.abs(rootWallet - (legWallet + legLoyalty)) < 1 &&
|
|
416
|
+
Number(d.totalLoyaltyPointsRefundAmount ?? 0) === 0) {
|
|
417
|
+
return { wallet: legWallet, forfeitedLoyalty: legLoyalty };
|
|
418
|
+
}
|
|
419
|
+
// Newer `/confirm` responses drop the loyalty portion from both root and
|
|
420
|
+
// leg totals — `walletRefundAmount` arrives as one opaque lump that's the
|
|
421
|
+
// cash-wallet portion (`totalWalletAmount`) plus a loyalty-program amount.
|
|
422
|
+
// When `loyaltyPaymentType` is set, the lump exceeds the cash-wallet
|
|
423
|
+
// portion, and it's a genuine card+wallet split (not a "send everything to
|
|
424
|
+
// the wallet" refund), the difference is that loyalty amount.
|
|
425
|
+
const cashWallet = Number(d.totalWalletAmount ?? 0);
|
|
426
|
+
const impliedLoyalty = rootWallet - cashWallet;
|
|
427
|
+
if (impliedLoyalty > 0.01 &&
|
|
428
|
+
cashWallet > 0 &&
|
|
429
|
+
Number(d.totalCardRefundAmount ?? 0) > 0 &&
|
|
430
|
+
Number(d.totalLoyaltyPointsRefundAmount ?? 0) === 0) {
|
|
431
|
+
return { wallet: cashWallet, forfeitedLoyalty: impliedLoyalty };
|
|
432
|
+
}
|
|
433
|
+
// The whole wallet refund is the loyalty-program balance — no cash-wallet
|
|
434
|
+
// portion (`totalWalletAmount` 0) and no card portion, but
|
|
435
|
+
// `loyaltyPaymentType` is set. Attribute all of it to the program so the
|
|
436
|
+
// popup names it (e.g. "Wala") with the permanent-points note.
|
|
437
|
+
if (cashWallet === 0 &&
|
|
438
|
+
rootWallet > 0 &&
|
|
439
|
+
Number(d.totalCardRefundAmount ?? 0) === 0 &&
|
|
440
|
+
Number(d.totalLoyaltyPointsRefundAmount ?? 0) === 0) {
|
|
441
|
+
return { wallet: 0, forfeitedLoyalty: rootWallet };
|
|
442
|
+
}
|
|
443
|
+
return { wallet: rootWallet, forfeitedLoyalty: 0 };
|
|
444
|
+
}
|
|
445
|
+
togglePaidSummary() {
|
|
446
|
+
this.paidSummaryExpanded.set(!this.paidSummaryExpanded());
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* The backend has sent `paymentMethodCustomerUsed` as both a short code
|
|
450
|
+
* (`"CH"`) and a full gateway name (`"Card"`) at different times — match
|
|
451
|
+
* either, case-insensitively, against the known codes/labels rather than
|
|
452
|
+
* assuming one format.
|
|
453
|
+
*/
|
|
454
|
+
normalizeGatewayCode(raw) {
|
|
455
|
+
if (!raw)
|
|
456
|
+
return '';
|
|
457
|
+
const needle = raw.trim().toLowerCase();
|
|
458
|
+
const codes = Object.keys(PAYMENT_GATEWAY_LABELS);
|
|
459
|
+
const byCode = codes.find((code) => code.toLowerCase() === needle);
|
|
460
|
+
if (byCode)
|
|
461
|
+
return byCode;
|
|
462
|
+
return codes.find((code) => PAYMENT_GATEWAY_LABELS[code].toLowerCase() === needle) ?? '';
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Wallet-row label for a loyalty-program redemption — `loyaltyPaymentType`
|
|
466
|
+
* (e.g. Wala, Qitaf) names the program that redeemed into the wallet
|
|
467
|
+
* balance and applies regardless of `paymentMethodCustomerUsed`; the
|
|
468
|
+
* backend can report an unrelated original payment gateway (e.g. Tabby)
|
|
469
|
+
* alongside a wallet portion that's actually a loyalty redemption.
|
|
470
|
+
*/
|
|
471
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
472
|
+
walletOrLoyaltyLabel(d) {
|
|
473
|
+
const loyalty = d?.loyaltyPaymentType ?? '';
|
|
474
|
+
return PAYMENT_GATEWAY_LABELS[loyalty] ?? '';
|
|
475
|
+
}
|
|
476
|
+
constructor() {
|
|
477
|
+
this.bookingService = inject(SbdBookingService);
|
|
478
|
+
this.toast = inject(SbdToastService);
|
|
479
|
+
this.visible = input(false);
|
|
480
|
+
this.bookingId = input('');
|
|
481
|
+
this.product = input('flight');
|
|
482
|
+
this.pnrInfo = input([]);
|
|
483
|
+
/** Same `booking_info` payload the dashboard already fetches (getBooking(..., 'booking_info')) — reused here to render real route/time details on the select-leg cards, instead of a second API call. */
|
|
484
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
485
|
+
this.bookingInfo = input(null);
|
|
486
|
+
this.closed = output();
|
|
487
|
+
this.confirmed = output();
|
|
488
|
+
/** Per-leg route/time details, mirroring app-sbd-flight-itinerary-card's mapping of booking_info.leg_info. */
|
|
489
|
+
this.itineraryLegs = computed(() => {
|
|
490
|
+
const bi = this.bookingInfo()?.data?.booking_info;
|
|
491
|
+
if (!bi)
|
|
492
|
+
return [];
|
|
493
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
494
|
+
return (bi.leg_info ?? []).map((leg, i) => ({
|
|
495
|
+
direction: leg.LegDirectionality,
|
|
496
|
+
airlineName: (leg.LegAirlinesNames ?? []).join(', '),
|
|
497
|
+
cabin: leg.LegCabins?.[0]?.Name ?? '',
|
|
498
|
+
from: leg.LegDepartureAirportCode,
|
|
499
|
+
to: leg.LegArrivalAirportCode,
|
|
500
|
+
depTime: leg.LegDepartureDateTime,
|
|
501
|
+
arrTime: leg.LegArrivalDateTime,
|
|
502
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
503
|
+
stops: (leg.Stops ?? []),
|
|
504
|
+
totalMinutes: bi.duration?.legs?.[i]?.Segments
|
|
505
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
506
|
+
?.reduce((sum, s) => sum + (s.SegmentElapsedTimeMinutes ?? 0), 0) ?? null,
|
|
507
|
+
operatedBy: leg.supplierName ? [leg.supplierName] : [],
|
|
508
|
+
}));
|
|
509
|
+
});
|
|
510
|
+
this.refundData = signal(null);
|
|
511
|
+
this.cancelResult = signal(null);
|
|
512
|
+
this.loading = signal(false);
|
|
513
|
+
this.cancelling = signal(false);
|
|
514
|
+
this.confirming = signal(false);
|
|
515
|
+
/**
|
|
516
|
+
* 'select-leg' shown once the refund preview resolves, for round-trip
|
|
517
|
+
* bookings the backend hasn't already restricted to a single leg — mirrors
|
|
518
|
+
* almatar-b2c's select-leg screen. Skipped straight to 'details' otherwise.
|
|
519
|
+
*/
|
|
520
|
+
this.step = signal('loading');
|
|
521
|
+
/** Per-leg inclusion (checkbox) and expand/collapse state — round-trip only. */
|
|
522
|
+
this.onwardChecked = signal(true);
|
|
523
|
+
this.returnChecked = signal(true);
|
|
524
|
+
this.onwardExpanded = signal(true);
|
|
525
|
+
this.returnExpanded = signal(true);
|
|
526
|
+
this.selectedSource = signal('');
|
|
527
|
+
this.cancelHint = signal('');
|
|
528
|
+
this.paidSummaryExpanded = signal(false);
|
|
529
|
+
this.preferredRefundMethod = signal('originalPaymentMethod');
|
|
530
|
+
this.CANCEL_HINTS = [
|
|
531
|
+
'Loading your data...',
|
|
532
|
+
'Fetching Sabre data...',
|
|
533
|
+
'Fetching ATC data...',
|
|
534
|
+
'Calculating refund amount...',
|
|
535
|
+
'We are almost done, please wait...',
|
|
536
|
+
];
|
|
537
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
538
|
+
this.hintTimer = null;
|
|
539
|
+
this.hasOnward = computed(() => !!this.refundData()?.legInfo?.onward);
|
|
540
|
+
this.hasReturn = computed(() => !!this.refundData()?.legInfo?.return);
|
|
541
|
+
this.isRoundTrip = computed(() => this.hasOnward() && this.hasReturn());
|
|
542
|
+
/** Which leg(s) the backend allows cancelling, from the refund preview response. */
|
|
543
|
+
this.legDirectionality = computed(() => this.refundData()?.legDirectionality);
|
|
544
|
+
/**
|
|
545
|
+
* Whether to render the round-trip "two leg cards" UI. Only when the
|
|
546
|
+
* backend explicitly allows cancelling both legs — otherwise (ONWARD-only /
|
|
547
|
+
* RETURN-only) show a single card for that leg, same as a one-way booking.
|
|
548
|
+
*/
|
|
549
|
+
this.showRoundTripLegCards = computed(() => this.isRoundTrip() && (this.legDirectionality() ?? 'BOTH') === 'BOTH');
|
|
550
|
+
/** Derived from the per-leg checkboxes — 'both' unless exactly one is unchecked. */
|
|
551
|
+
this.selectedLeg = computed(() => {
|
|
552
|
+
if (!this.isRoundTrip())
|
|
553
|
+
return 'both';
|
|
554
|
+
const dir = this.legDirectionality();
|
|
555
|
+
if (dir === 'ONWARD')
|
|
556
|
+
return 'onward';
|
|
557
|
+
if (dir === 'RETURN')
|
|
558
|
+
return 'return';
|
|
559
|
+
const onward = this.onwardChecked();
|
|
560
|
+
const ret = this.returnChecked();
|
|
561
|
+
if (onward && ret)
|
|
562
|
+
return 'both';
|
|
563
|
+
return onward ? 'onward' : 'return';
|
|
564
|
+
});
|
|
565
|
+
// Returns the sourceBreakdown for the currently selected leg (or root for "both")
|
|
566
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
567
|
+
this.activeSourceBreakdown = computed(() => {
|
|
568
|
+
const sel = this.selectedLeg();
|
|
569
|
+
const root = this.refundData();
|
|
570
|
+
if (!root)
|
|
571
|
+
return null;
|
|
572
|
+
// A leg-scoped view (single leg, or both legs summed) must not fall back
|
|
573
|
+
// to root.sourceBreakdown — its totals are for the whole/original
|
|
574
|
+
// itinerary, not scoped to the leg(s) actually shown, and applying it
|
|
575
|
+
// would clobber the correctly leg-scoped totals computed in
|
|
576
|
+
// `currentData()`.
|
|
577
|
+
if (sel === 'onward')
|
|
578
|
+
return root.legInfo?.onward?.sourceBreakdown ?? null;
|
|
579
|
+
if (sel === 'return')
|
|
580
|
+
return root.legInfo?.return?.sourceBreakdown ?? null;
|
|
581
|
+
if (root.legInfo?.onward && root.legInfo?.return)
|
|
582
|
+
return null;
|
|
583
|
+
return root.sourceBreakdown ?? null;
|
|
584
|
+
});
|
|
585
|
+
this.availableSources = computed(() => Object.keys(this.activeSourceBreakdown() ?? {}));
|
|
586
|
+
this.currentData = computed(() => {
|
|
587
|
+
const root = this.refundData();
|
|
588
|
+
if (!root)
|
|
589
|
+
return null;
|
|
590
|
+
const sel = this.selectedLeg();
|
|
591
|
+
if (sel === 'onward' && root.legInfo?.onward)
|
|
592
|
+
return this.buildLegData(root, root.legInfo.onward, 'onward');
|
|
593
|
+
if (sel === 'return' && root.legInfo?.return)
|
|
594
|
+
return this.buildLegData(root, root.legInfo.return, 'return');
|
|
595
|
+
// Payment/refund figures come from `legInfo`, never root (root isn't
|
|
596
|
+
// reliably scoped to whichever leg(s) ended up selected) — combine both
|
|
597
|
+
// legs when both are in play, otherwise use whichever one exists.
|
|
598
|
+
const onward = root.legInfo?.onward;
|
|
599
|
+
const ret = root.legInfo?.return;
|
|
600
|
+
if (onward && ret)
|
|
601
|
+
return this.buildCombinedLegData(root, onward, ret);
|
|
602
|
+
if (onward && !ret)
|
|
603
|
+
return this.buildLegData(root, onward, 'onward');
|
|
604
|
+
if (ret && !onward)
|
|
605
|
+
return this.buildLegData(root, ret, 'return');
|
|
606
|
+
return root;
|
|
607
|
+
});
|
|
608
|
+
// currentData with source-specific penalty/refund/refundability overrides applied
|
|
609
|
+
this.adjustedData = computed(() => {
|
|
610
|
+
const base = this.currentData();
|
|
611
|
+
if (!base)
|
|
612
|
+
return null;
|
|
613
|
+
return this.applySourceOverride(base, this.activeSourceBreakdown());
|
|
614
|
+
});
|
|
615
|
+
/**
|
|
616
|
+
* Non-CrossSeller airlines require the whole round-trip/multicity
|
|
617
|
+
* itinerary to be cancelled together — a leg can't be excluded on its own
|
|
618
|
+
* unless it has already flown (which naturally degrades to a one-way
|
|
619
|
+
* cancellation of just the remaining leg). Set when an uncheck attempt was
|
|
620
|
+
* blocked for this reason, so the leg's checkbox can be frozen (locked)
|
|
621
|
+
* and the note shown.
|
|
622
|
+
*/
|
|
623
|
+
this.forcedLegType = signal(null);
|
|
624
|
+
this.sourceNonRefundableHint = computed(() => {
|
|
625
|
+
const sel = this.selectedSource();
|
|
626
|
+
if (!sel)
|
|
627
|
+
return '';
|
|
628
|
+
const src = (this.activeSourceBreakdown() ?? {})[sel];
|
|
629
|
+
if (!src || src.isRefundable !== false)
|
|
630
|
+
return '';
|
|
631
|
+
return `Cancellation via ${sel} is not eligible for a refund. Please select a different source.`;
|
|
632
|
+
});
|
|
633
|
+
this.deductions = computed(() => this.deductionRows(this.adjustedData()));
|
|
634
|
+
this.refunds = computed(() => {
|
|
635
|
+
const d = this.adjustedData();
|
|
636
|
+
if (!d)
|
|
637
|
+
return [];
|
|
638
|
+
const isLoyalty = this.isLoyaltyMethod();
|
|
639
|
+
const paymentLabel = this.customerPaymentLabel();
|
|
640
|
+
const rows = REFUND_DEFS
|
|
641
|
+
.filter(def => Number(d[def.key]) > 0)
|
|
642
|
+
.map(def => ({
|
|
643
|
+
// Wallet row always reads "Almatar Wallet" (def.label) — the loyalty
|
|
644
|
+
// program that funded it gets its own dedicated row below via
|
|
645
|
+
// `forfeitedLoyaltyPointsFallback`, so the two stay visually
|
|
646
|
+
// distinct instead of merging into one label.
|
|
647
|
+
// Card row: card/loyalty stay distinct — don't relabel the card
|
|
648
|
+
// portion with the loyalty program name too, and never surface an
|
|
649
|
+
// internal processor name (empty `paymentLabel` falls back to the
|
|
650
|
+
// generic def.label, e.g. "Refund Amount").
|
|
651
|
+
label: def.key === 'totalCardRefundAmount' && !isLoyalty && paymentLabel
|
|
652
|
+
? `${def.label} ${paymentLabel}`
|
|
653
|
+
: def.label,
|
|
654
|
+
value: Number(d[def.key]),
|
|
655
|
+
}));
|
|
656
|
+
const forfeitedLoyalty = this.forfeitedLoyaltyPointsFallback(d);
|
|
657
|
+
if (forfeitedLoyalty > 0) {
|
|
658
|
+
rows.push({ label: this.walletOrLoyaltyLabel(d), value: forfeitedLoyalty });
|
|
659
|
+
}
|
|
660
|
+
return rows;
|
|
661
|
+
});
|
|
662
|
+
this.creditShellNote = computed(() => {
|
|
663
|
+
// Golden Guarantee overrides credit-shell messaging entirely — the
|
|
664
|
+
// dedicated success notice (`goldenGuaranteeNote`) is shown instead.
|
|
665
|
+
if (this.hasGoldenGuaranteeGift())
|
|
666
|
+
return '';
|
|
667
|
+
const d = this.currentData();
|
|
668
|
+
if (!d)
|
|
669
|
+
return '';
|
|
670
|
+
const legInfo = d.legInfo ?? {};
|
|
671
|
+
const hasO = !!legInfo.onward;
|
|
672
|
+
const hasR = !!legInfo.return;
|
|
673
|
+
const oShell = legInfo.onward?.isCreditShell === true;
|
|
674
|
+
const rShell = legInfo.return?.isCreditShell === true;
|
|
675
|
+
const isShell = (hasO && hasR && oShell && rShell) ||
|
|
676
|
+
(hasO && !hasR && oShell) ||
|
|
677
|
+
(!hasO && hasR && rShell) ||
|
|
678
|
+
(hasO && hasR && (oShell || rShell));
|
|
679
|
+
if (!isShell)
|
|
680
|
+
return '';
|
|
681
|
+
const amount = this.fmt(Number(this.adjustedData()?.totalRefundAmount ?? d.totalRefundAmount ?? 0));
|
|
682
|
+
const pnr = this.resolvePnr();
|
|
683
|
+
const pnrText = pnr ? `the same PNR (${pnr})` : 'the same PNR';
|
|
684
|
+
return `The refund of ${amount} will be issued as airline credit under ${pnrText}. ${CREDIT_SHELL_SUFFIX}`;
|
|
685
|
+
});
|
|
686
|
+
/**
|
|
687
|
+
* Booking includes a Golden Guarantee gift ("Cancel for any reason") —
|
|
688
|
+
* overrides all credit-shell handling below, since a Golden Guarantee
|
|
689
|
+
* cancellation always refunds 100% through the standard payment method
|
|
690
|
+
* rather than the airline credit shell. May be carried on either the
|
|
691
|
+
* preview (`refundData`) or the confirm (`cancelResult`) response — both
|
|
692
|
+
* share the same shape, and either one may set it independently of the
|
|
693
|
+
* other.
|
|
694
|
+
*/
|
|
695
|
+
this.hasGoldenGuaranteeGift = computed(() => this.refundData()?.hasGoldenGuaranteeGift === true ||
|
|
696
|
+
this.cancelResult()?.hasGoldenGuaranteeGift === true);
|
|
697
|
+
// Whether the refund is a credit-shell refund (whole booking or either leg).
|
|
698
|
+
// Such refunds can only return to the airline credit shell, so the
|
|
699
|
+
// refund-method picker is replaced with a single read-only credit notice.
|
|
700
|
+
// A Golden Guarantee gift overrides this to `false` — that portion needs an
|
|
701
|
+
// actual destination choice, so the booking falls back to the standard
|
|
702
|
+
// refund-method flow despite being flagged credit-shell.
|
|
703
|
+
this.isCreditShell = computed(() => {
|
|
704
|
+
if (this.hasGoldenGuaranteeGift())
|
|
705
|
+
return false;
|
|
706
|
+
const d = this.refundData();
|
|
707
|
+
return (d?.isCreditShell === true ||
|
|
708
|
+
d?.legInfo?.onward?.isCreditShell === true ||
|
|
709
|
+
d?.legInfo?.return?.isCreditShell === true);
|
|
710
|
+
});
|
|
711
|
+
/**
|
|
712
|
+
* Refundable ancillaries (baggage, seats, …) that carry their own
|
|
713
|
+
* `isCreditShell` flag, independent of the booking-level flag — rendered
|
|
714
|
+
* as individual cards on the credit-shell refund-method screen so each
|
|
715
|
+
* one can show either the credit-shell card style or the normal wallet
|
|
716
|
+
* card style (both include the same nested credit-shell note when true).
|
|
717
|
+
*/
|
|
718
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
719
|
+
this.creditShellAncillaryItems = computed(() => (this.adjustedData()?.refundBreakdown?.refundable?.ancillaries ?? [])
|
|
720
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
721
|
+
.filter((item) => Number(item.amount) > 0));
|
|
722
|
+
// Airline that issues the credit shell, for the "<supplier> website credit" card.
|
|
723
|
+
this.creditShellSupplierName = computed(() => {
|
|
724
|
+
const d = this.refundData();
|
|
725
|
+
return (d?.legInfo?.onward?.supplierName ??
|
|
726
|
+
d?.legInfo?.return?.supplierName ??
|
|
727
|
+
d?.supplierName ??
|
|
728
|
+
d?.appliedSource ??
|
|
729
|
+
'');
|
|
730
|
+
});
|
|
731
|
+
// Header title reflecting the refund type for the active selection.
|
|
732
|
+
this.refundTypeLabel = computed(() => {
|
|
733
|
+
if (!this.refundData()?.isRefundable)
|
|
734
|
+
return 'Refund Details';
|
|
735
|
+
return this.creditShellNote() ? 'Credit Shell Refund' : 'Refund Details';
|
|
736
|
+
});
|
|
737
|
+
this.currency = computed(() => this.refundData()?.currency ?? 'SAR');
|
|
738
|
+
// Self-consistency check between the paid amount, deductions and the system refund.
|
|
739
|
+
// Surfaced to the agent so mismatched/over-deducted refunds can be caught before confirming.
|
|
740
|
+
this.discrepancyNote = computed(() => {
|
|
741
|
+
const d = this.adjustedData();
|
|
742
|
+
if (!d || !d.isRefundable)
|
|
743
|
+
return '';
|
|
744
|
+
const paid = Number(d.originalAmount || 0);
|
|
745
|
+
const deduction = Number(d.totalCancellationFee || 0);
|
|
746
|
+
const refund = Number(d.totalRefundAmount || 0);
|
|
747
|
+
const issues = [];
|
|
748
|
+
if (deduction > paid + 0.01)
|
|
749
|
+
issues.push(`Total deduction (${this.fmt(deduction)}) exceeds the paid amount (${this.fmt(paid)}).`);
|
|
750
|
+
if (Math.abs((paid - deduction) - refund) > 0.01)
|
|
751
|
+
issues.push(`Computed refund (${this.fmt(paid - deduction)}) doesn't match the system refund (${this.fmt(refund)}).`);
|
|
752
|
+
return issues.join(' ');
|
|
753
|
+
});
|
|
754
|
+
/** Real per-booking CrossSeller flag from the refund preview — CrossSeller suppliers allow cancelling either leg independently. */
|
|
755
|
+
this.isCrossSeller = computed(() => this.refundData()?.isCrossSeller === true);
|
|
756
|
+
// Non-CrossSeller round trips are one itinerary sold as a single fare —
|
|
757
|
+
// both legs share the same refundability, sourced from root, even when
|
|
758
|
+
// the backend's legInfo entry for a leg is missing or inconsistent.
|
|
759
|
+
// CrossSeller legs are independently sellable, so each leg's own field
|
|
760
|
+
// still governs there.
|
|
761
|
+
this.onwardRefundable = computed(() => {
|
|
762
|
+
if (!this.hasOnward())
|
|
763
|
+
return false;
|
|
764
|
+
return this.isCrossSeller()
|
|
765
|
+
? this.refundData()?.legInfo?.onward?.isRefundable === true
|
|
766
|
+
: this.refundData()?.isRefundable === true;
|
|
767
|
+
});
|
|
768
|
+
this.returnRefundable = computed(() => {
|
|
769
|
+
if (!this.hasReturn())
|
|
770
|
+
return false;
|
|
771
|
+
return this.isCrossSeller()
|
|
772
|
+
? this.refundData()?.legInfo?.return?.isRefundable === true
|
|
773
|
+
: this.refundData()?.isRefundable === true;
|
|
774
|
+
});
|
|
775
|
+
this.isMixed = computed(() => this.isRoundTrip() && this.onwardRefundable() !== this.returnRefundable());
|
|
776
|
+
/** Both legs present and BOTH non-refundable — nothing can be refunded for this booking. */
|
|
777
|
+
this.allLegsNonRefundable = computed(() => this.isRoundTrip() && !this.onwardRefundable() && !this.returnRefundable());
|
|
778
|
+
this.mixedHint = computed(() => {
|
|
779
|
+
// Only relevant when agent is about to cancel both legs together —
|
|
780
|
+
// individual leg tabs already show their own non-refundable notice.
|
|
781
|
+
if (!this.isMixed() || this.selectedLeg() !== 'both')
|
|
782
|
+
return '';
|
|
783
|
+
if (!this.onwardRefundable())
|
|
784
|
+
return '⚠️ Onward leg is not eligible for refund. Please contact customer service if you want to cancel it.';
|
|
785
|
+
if (!this.returnRefundable())
|
|
786
|
+
return '⚠️ Return leg is not eligible for refund. Please contact customer service if you want to cancel it.';
|
|
787
|
+
return '';
|
|
788
|
+
});
|
|
789
|
+
this.giftHint = computed(() => {
|
|
790
|
+
const root = this.refundData();
|
|
791
|
+
if (!root || !this.isRoundTrip())
|
|
792
|
+
return '';
|
|
793
|
+
const hasGift = Number(root.totalGiftAmount || 0) > 0 ||
|
|
794
|
+
Number(root.legInfo?.onward?.totalGiftAmount || 0) > 0 ||
|
|
795
|
+
Number(root.legInfo?.return?.totalGiftAmount || 0) > 0;
|
|
796
|
+
return hasGift ? GIFT_HINT : '';
|
|
797
|
+
});
|
|
798
|
+
this.selectionHint = computed(() => {
|
|
799
|
+
if (!this.isRoundTrip())
|
|
800
|
+
return '';
|
|
801
|
+
const map = {
|
|
802
|
+
onward: 'You are about to cancel: Onward leg only',
|
|
803
|
+
return: 'You are about to cancel: Return leg only',
|
|
804
|
+
both: 'You are about to cancel: Both legs',
|
|
805
|
+
};
|
|
806
|
+
return map[this.selectedLeg()];
|
|
807
|
+
});
|
|
808
|
+
this.confirmDeductions = computed(() => {
|
|
809
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
810
|
+
const d = this.cancelResult();
|
|
811
|
+
if (!d)
|
|
812
|
+
return [];
|
|
813
|
+
return DEDUCTION_DEFS.filter(def => Number(d[def.key]) > 0).map(def => ({ label: def.label, value: Number(d[def.key]) }));
|
|
814
|
+
});
|
|
815
|
+
this.confirmRefunds = computed(() => {
|
|
816
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
817
|
+
const d = this.cancelResult();
|
|
818
|
+
if (!d)
|
|
819
|
+
return [];
|
|
820
|
+
const code = this.normalizeGatewayCode(d.paymentMethodCustomerUsed);
|
|
821
|
+
const isLoyalty = LOYALTY_GATEWAY_CODES.includes(code);
|
|
822
|
+
const isMada = this.confirmIsMadaMethod();
|
|
823
|
+
const paymentLabel = code && !INTERNAL_GATEWAY_CODES.includes(code) ? PAYMENT_GATEWAY_LABELS[code] : '';
|
|
824
|
+
const rows = [];
|
|
825
|
+
const { wallet, forfeitedLoyalty } = this.correctedConfirmWalletAndLoyalty(d);
|
|
826
|
+
// Golden Guarantee overrides credit-shell handling on the result screen
|
|
827
|
+
// too — whatever landed as a credit-shell amount folds into the normal
|
|
828
|
+
// original-payment-method row instead of getting its own "airline
|
|
829
|
+
// credit" card, so the confirmation reads like an ordinary Sabre/Amadeus
|
|
830
|
+
// refund.
|
|
831
|
+
const goldenGuaranteeOverride = this.hasGoldenGuaranteeGift();
|
|
832
|
+
// Credit-shell row goes first — matches the design (airline credit above
|
|
833
|
+
// the wallet row) — before the card and wallet rows below.
|
|
834
|
+
if (!goldenGuaranteeOverride) {
|
|
835
|
+
const credit = Number(d.totalCreditRefundAmount ?? 0);
|
|
836
|
+
if (credit > 0) {
|
|
837
|
+
const supplier = d.appliedSource || this.creditShellSupplierName();
|
|
838
|
+
rows.push({
|
|
839
|
+
key: 'totalCreditRefundAmount',
|
|
840
|
+
label: supplier ? `${supplier} website credit` : 'Credit Shell Refund',
|
|
841
|
+
value: credit,
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
const cardAmount = Number(d.totalCardRefundAmount ?? 0) +
|
|
846
|
+
(goldenGuaranteeOverride ? Number(d.totalCreditRefundAmount ?? 0) : 0);
|
|
847
|
+
if (cardAmount > 0) {
|
|
848
|
+
rows.push({
|
|
849
|
+
key: 'totalCardRefundAmount',
|
|
850
|
+
label: isMada
|
|
851
|
+
? 'Mada Card'
|
|
852
|
+
: !isLoyalty && paymentLabel
|
|
853
|
+
? `Refund Amount ${paymentLabel}`
|
|
854
|
+
: 'Refund Amount',
|
|
855
|
+
value: cardAmount,
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
if (wallet > 0 && forfeitedLoyalty > 0) {
|
|
859
|
+
// Wallet cash + a loyalty program's points both landed in the wallet —
|
|
860
|
+
// shown as one combined card with the two sources broken out as named
|
|
861
|
+
// sub-rows, rather than two separate top-level cards.
|
|
862
|
+
rows.push({
|
|
863
|
+
key: 'walletRefundAmount',
|
|
864
|
+
label: 'Almatar Wallet',
|
|
865
|
+
value: wallet + forfeitedLoyalty,
|
|
866
|
+
subRows: [
|
|
867
|
+
{ label: 'Almatar wallet points', value: wallet },
|
|
868
|
+
{ label: `${this.walletOrLoyaltyLabel(d)} points`, value: forfeitedLoyalty },
|
|
869
|
+
],
|
|
870
|
+
hasLoyaltyNote: true,
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
else if (wallet > 0) {
|
|
874
|
+
rows.push({ key: 'walletRefundAmount', label: 'Almatar Wallet', value: wallet });
|
|
875
|
+
}
|
|
876
|
+
else if (forfeitedLoyalty > 0) {
|
|
877
|
+
// Loyalty-only — no wallet cash involved, still lands as permanent
|
|
878
|
+
// wallet points, so it keeps the wallet-style card + note.
|
|
879
|
+
rows.push({
|
|
880
|
+
key: 'totalLoyaltyPoints',
|
|
881
|
+
label: this.walletOrLoyaltyLabel(d),
|
|
882
|
+
value: forfeitedLoyalty,
|
|
883
|
+
hasLoyaltyNote: true,
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
REFUND_DEFS
|
|
887
|
+
.filter((def) => def.key !== 'walletRefundAmount' &&
|
|
888
|
+
def.key !== 'totalCardRefundAmount' &&
|
|
889
|
+
def.key !== 'totalCreditRefundAmount' &&
|
|
890
|
+
Number(d[def.key]) > 0)
|
|
891
|
+
.forEach((def) => {
|
|
892
|
+
rows.push({ key: def.key, label: def.label, value: Number(d[def.key]) });
|
|
893
|
+
});
|
|
894
|
+
return rows;
|
|
895
|
+
});
|
|
896
|
+
/**
|
|
897
|
+
* The result screen's "issued as an Airline Credit Shell" note. Golden
|
|
898
|
+
* Guarantee overrides this to '' — the confirmation renders like a
|
|
899
|
+
* standard Sabre/Amadeus refund instead (see `confirmRefunds`' folding
|
|
900
|
+
* of any credit-shell amount into the normal payment-method row).
|
|
901
|
+
*/
|
|
902
|
+
this.confirmCreditShellNote = computed(() => {
|
|
903
|
+
if (this.hasGoldenGuaranteeGift())
|
|
904
|
+
return '';
|
|
905
|
+
const d = this.cancelResult();
|
|
906
|
+
if (!d)
|
|
907
|
+
return '';
|
|
908
|
+
const legInfo = d.legInfo ?? {};
|
|
909
|
+
const hasO = !!legInfo.onward;
|
|
910
|
+
const hasR = !!legInfo.return;
|
|
911
|
+
const oShell = legInfo.onward?.isCreditShell === true;
|
|
912
|
+
const rShell = legInfo.return?.isCreditShell === true;
|
|
913
|
+
const topShell = d.isCreditShell === true;
|
|
914
|
+
if ((hasO && hasR && oShell && rShell) || (hasO && !hasR && oShell) || (!hasO && hasR && rShell) || topShell)
|
|
915
|
+
return 'The refund has been issued as an Airline Credit Shell and can be used for future bookings on the airline website.';
|
|
916
|
+
if (hasO && hasR) {
|
|
917
|
+
if (oShell)
|
|
918
|
+
return 'The refund for the onward flight has been issued as an Airline Credit Shell.';
|
|
919
|
+
if (rShell)
|
|
920
|
+
return 'The refund for the return flight has been issued as an Airline Credit Shell.';
|
|
921
|
+
}
|
|
922
|
+
return '';
|
|
923
|
+
});
|
|
924
|
+
/**
|
|
925
|
+
* The customer-facing total (ceiled) must match the pre-rounding total the
|
|
926
|
+
* refund is actually computed from — i.e. `totalRefundAmount` must be
|
|
927
|
+
* `totalRefundAmountBeforeCeil` rounded up to a whole currency unit (e.g.
|
|
928
|
+
* 1454.5 → 1455). A mismatch here means the supplier response itself is
|
|
929
|
+
* internally inconsistent and must block confirmation.
|
|
930
|
+
*/
|
|
931
|
+
this.refundReconciles = computed(() => {
|
|
932
|
+
const d = this.adjustedData();
|
|
933
|
+
if (!d || !d.isRefundable)
|
|
934
|
+
return true;
|
|
935
|
+
const beforeCeil = Number(d.totalRefundAmountBeforeCeil ?? d.totalRefundAmount ?? 0);
|
|
936
|
+
const total = Number(d.totalRefundAmount ?? beforeCeil);
|
|
937
|
+
return Math.abs(Math.ceil(beforeCeil) - total) < 1;
|
|
938
|
+
});
|
|
939
|
+
this.canConfirm = computed(() => {
|
|
940
|
+
const d = this.adjustedData();
|
|
941
|
+
return !!d?.isRefundable && this.refundReconciles() && !this.cancelling();
|
|
942
|
+
});
|
|
943
|
+
/** How many of {wallet, card, loyalty} the refund is actually split across. */
|
|
944
|
+
this.splitPartsCount = computed(() => {
|
|
945
|
+
const d = this.adjustedData();
|
|
946
|
+
if (!d)
|
|
947
|
+
return 0;
|
|
948
|
+
return [
|
|
949
|
+
d.walletRefundAmount,
|
|
950
|
+
d.totalCardRefundAmount,
|
|
951
|
+
d.totalLoyaltyPointsRefundAmount,
|
|
952
|
+
this.forfeitedLoyaltyPointsFallback(d),
|
|
953
|
+
].filter((v) => Number(v ?? 0) > 0).length;
|
|
954
|
+
});
|
|
955
|
+
/**
|
|
956
|
+
* A portion of the refund is forced to the wallet (e.g. loyalty points used)
|
|
957
|
+
* — in that case offer a "Split Refund" option instead of a pure
|
|
958
|
+
* original-payment-method option, since the whole amount can't go to card.
|
|
959
|
+
*/
|
|
960
|
+
this.hasSplitRefund = computed(() => Number(this.adjustedData()?.totalRefundAmount ?? 0) > 0 && this.splitPartsCount() >= 2);
|
|
961
|
+
/**
|
|
962
|
+
* Wallet covers the whole refund (no card or loyalty portion at all) — show
|
|
963
|
+
* the wallet option alone rather than a "split" with empty other sides.
|
|
964
|
+
*/
|
|
965
|
+
this.isWalletOnlyRefund = computed(() => {
|
|
966
|
+
const d = this.adjustedData();
|
|
967
|
+
return (Number(d?.walletRefundAmount ?? 0) > 0 &&
|
|
968
|
+
Number(d?.totalCardRefundAmount ?? 0) === 0 &&
|
|
969
|
+
Number(d?.totalLoyaltyPointsRefundAmount ?? 0) === 0 &&
|
|
970
|
+
this.forfeitedLoyaltyPointsFallback(d) === 0);
|
|
971
|
+
});
|
|
972
|
+
/**
|
|
973
|
+
* The entire refund is forfeited loyalty points (e.g. Wala) landing back as
|
|
974
|
+
* wallet balance — no cash-wallet, card, credit or real
|
|
975
|
+
* loyalty-points-refund portion at all. Without this the picker falls
|
|
976
|
+
* through to the "Original Payment Method" card and mislabels the
|
|
977
|
+
* destination as the original gateway (e.g. "Tabby"), even though
|
|
978
|
+
* `totalCardRefundAmount` is 0 and nothing goes back to that card.
|
|
979
|
+
*/
|
|
980
|
+
this.isLoyaltyOnlyRefund = computed(() => {
|
|
981
|
+
const d = this.adjustedData();
|
|
982
|
+
return (this.forfeitedLoyaltyPointsFallback(d) > 0 &&
|
|
983
|
+
Number(d?.walletRefundAmount ?? 0) === 0 &&
|
|
984
|
+
Number(d?.totalCardRefundAmount ?? 0) === 0 &&
|
|
985
|
+
Number(d?.totalCreditRefundAmount ?? 0) === 0 &&
|
|
986
|
+
Number(d?.totalLoyaltyPointsRefundAmount ?? 0) === 0);
|
|
987
|
+
});
|
|
988
|
+
/** A real cash-wallet portion is part of the refund (distinct from forfeited loyalty points landing in the wallet). */
|
|
989
|
+
this.hasCashWalletRefund = computed(() => Number(this.adjustedData()?.walletRefundAmount ?? 0) > 0);
|
|
990
|
+
/**
|
|
991
|
+
* Wallet card's title — normally "Almatar Wallet", but the loyalty program
|
|
992
|
+
* name (Wala, Qitaf, …) when the whole refund is that program's forfeited
|
|
993
|
+
* balance landing back in the wallet.
|
|
994
|
+
*/
|
|
995
|
+
this.walletCardLabel = computed(() => this.isLoyaltyOnlyRefund()
|
|
996
|
+
? this.walletOrLoyaltyLabel(this.adjustedData()) || 'Almatar Wallet'
|
|
997
|
+
: 'Almatar Wallet');
|
|
998
|
+
/**
|
|
999
|
+
* Part of the refund came from converting external loyalty points into
|
|
1000
|
+
* wallet funds — surfaced as a note under the wallet destination so the
|
|
1001
|
+
* agent knows those points land as permanent wallet balance, not cash.
|
|
1002
|
+
*/
|
|
1003
|
+
this.hasLoyaltyPointsRefund = computed(() => Number(this.adjustedData()?.totalLoyaltyPoints ?? 0) > 0);
|
|
1004
|
+
/**
|
|
1005
|
+
* The booking is refundable but nets to 0.00 after deductions — a
|
|
1006
|
+
* dedicated NIL Refund state, distinct from "not refundable": no refund
|
|
1007
|
+
* method to choose between, just confirmation that nothing is owed back.
|
|
1008
|
+
*/
|
|
1009
|
+
this.isNilRefund = computed(() => {
|
|
1010
|
+
const d = this.adjustedData();
|
|
1011
|
+
return !!d?.isRefundable && Number(d.totalRefundAmount ?? 0) === 0;
|
|
1012
|
+
});
|
|
1013
|
+
/** Same as `isNilRefund`, scoped to the confirmed cancellation result — drives the result screen's title. */
|
|
1014
|
+
this.confirmIsNilRefund = computed(() => {
|
|
1015
|
+
const d = this.cancelResult();
|
|
1016
|
+
return !!d?.isRefundable && Number(d.totalRefundAmount ?? 0) === 0;
|
|
1017
|
+
});
|
|
1018
|
+
/** Whether the customer may send the whole refund to their Almatar Wallet. */
|
|
1019
|
+
this.isFullWalletRefundAllowed = computed(() => !!this.adjustedData()?.isFullWalletRefundAllowed);
|
|
1020
|
+
/** Whether the customer paid via an installment gateway (Tamara, Tabby, …). */
|
|
1021
|
+
this.isInstallmentMethod = computed(() => INSTALLMENT_GATEWAY_CODES.includes(this.normalizeGatewayCode(this.adjustedData()?.paymentMethodCustomerUsed)));
|
|
1022
|
+
/** Whether the customer paid via a loyalty-program gateway (Al Rajhi Mokafaa, …). */
|
|
1023
|
+
this.isLoyaltyMethod = computed(() => LOYALTY_GATEWAY_CODES.includes(this.normalizeGatewayCode(this.adjustedData()?.paymentMethodCustomerUsed)));
|
|
1024
|
+
/** Any gateway that refunds somewhere other than a plain card — used for the wallet-style icon. */
|
|
1025
|
+
this.isSpecialGatewayMethod = computed(() => this.isInstallmentMethod() || this.isLoyaltyMethod());
|
|
1026
|
+
/**
|
|
1027
|
+
* Card-refund settlement-timeline badge — Tabby and Tamara each have their
|
|
1028
|
+
* own processing window, distinct from a plain card's generic bank policy.
|
|
1029
|
+
*/
|
|
1030
|
+
this.cardBadgeText = computed(() => {
|
|
1031
|
+
const code = this.normalizeGatewayCode(this.adjustedData()?.paymentMethodCustomerUsed);
|
|
1032
|
+
if (code === 'TB')
|
|
1033
|
+
return 'From 5-7 business days';
|
|
1034
|
+
if (code === 'TM')
|
|
1035
|
+
return 'Up to 10 business days';
|
|
1036
|
+
if (this.isLoyaltyMethod())
|
|
1037
|
+
return 'Loyalty Program Policy';
|
|
1038
|
+
return 'Up to 15 business days, bank policy';
|
|
1039
|
+
});
|
|
1040
|
+
/** Same as `cardBadgeText`, scoped to the confirmed cancellation result. */
|
|
1041
|
+
this.confirmCardBadgeText = computed(() => {
|
|
1042
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1043
|
+
const d = this.cancelResult();
|
|
1044
|
+
const code = this.normalizeGatewayCode(d?.paymentMethodCustomerUsed);
|
|
1045
|
+
if (code === 'TB')
|
|
1046
|
+
return 'From 5-7 business days';
|
|
1047
|
+
if (code === 'TM')
|
|
1048
|
+
return 'Up to 10 business days';
|
|
1049
|
+
if (LOYALTY_GATEWAY_CODES.includes(code))
|
|
1050
|
+
return 'Loyalty Program Policy';
|
|
1051
|
+
return 'Up to 15 business days, bank policy';
|
|
1052
|
+
});
|
|
1053
|
+
/**
|
|
1054
|
+
* Per-method breakdown of the "Total paid" amount. The backend doesn't
|
|
1055
|
+
* (yet) expose a dedicated original-payment breakdown, so the known
|
|
1056
|
+
* refund-destination fields (card / wallet / loyalty) are used as a proxy
|
|
1057
|
+
* for how the booking was originally paid, and whatever's left over after
|
|
1058
|
+
* those (e.g. a non-refundable leg/fee that never shows up in any refund
|
|
1059
|
+
* field) is folded into the primary payment method — so the rows always
|
|
1060
|
+
* add up to the full `originalAmount` shown above them, instead of only
|
|
1061
|
+
* covering the refundable portion.
|
|
1062
|
+
*/
|
|
1063
|
+
this.paidBreakdownRows = computed(() => {
|
|
1064
|
+
const d = this.adjustedData();
|
|
1065
|
+
if (!d)
|
|
1066
|
+
return [];
|
|
1067
|
+
// Card and loyalty stay distinct labels (same categorization as
|
|
1068
|
+
// `refunds`) so a gateway like Al Rajhi Mokafaa doesn't swallow an
|
|
1069
|
+
// actual separate card portion under one label.
|
|
1070
|
+
const cardLabel = (!this.isLoyaltyMethod() && this.customerPaymentLabel()) || 'Original Payment Method';
|
|
1071
|
+
// The wallet destination row always reads "Almatar Wallet" — unlike
|
|
1072
|
+
// `refunds`/`confirmRefunds`, this row never swaps to the loyalty
|
|
1073
|
+
// program name, since `forfeitedLoyaltyLabel` below is that program's
|
|
1074
|
+
// own dedicated row and the two must stay visually distinct here.
|
|
1075
|
+
const walletLabel = 'Almatar Wallet';
|
|
1076
|
+
const forfeitedLoyaltyLabel = this.walletOrLoyaltyLabel(d) || 'Loyalty Points';
|
|
1077
|
+
const loyaltyLabel = this.customerPaymentLabel() || 'Loyalty Points Refund';
|
|
1078
|
+
const amounts = new Map();
|
|
1079
|
+
const add = (label, value) => {
|
|
1080
|
+
if (value <= 0)
|
|
1081
|
+
return;
|
|
1082
|
+
amounts.set(label, (amounts.get(label) ?? 0) + value);
|
|
1083
|
+
};
|
|
1084
|
+
add(cardLabel, Number(d.totalCardRefundAmount ?? 0));
|
|
1085
|
+
// This row shows how much of the *original* payment went through the
|
|
1086
|
+
// wallet — `totalWalletAmount`, not `walletRefundAmount` (a refund
|
|
1087
|
+
// destination amount that can differ, e.g. only part of the wallet
|
|
1088
|
+
// payment is refundable after deductions).
|
|
1089
|
+
add(walletLabel, Number(d.totalWalletAmount ?? 0));
|
|
1090
|
+
add(loyaltyLabel, Number(d.totalLoyaltyPointsRefundAmount ?? 0));
|
|
1091
|
+
// `totalLoyaltyPoints` is the portion of the *original* payment made with
|
|
1092
|
+
// loyalty points (now forfeited/deducted, not refunded) — distinct from
|
|
1093
|
+
// `totalLoyaltyPointsRefundAmount` above and from `walletRefundAmount`
|
|
1094
|
+
// (an unrelated refund-destination amount). Always shown as its own row
|
|
1095
|
+
// under the program name (e.g. "Qitaf"/"Wala") rather than merged into
|
|
1096
|
+
// the generic Wallet row or silently folded into the leftover remainder.
|
|
1097
|
+
add(forfeitedLoyaltyLabel, Number(d.totalLoyaltyPoints ?? 0));
|
|
1098
|
+
const total = Number(d.originalAmount ?? 0);
|
|
1099
|
+
const known = [...amounts.values()].reduce((a, b) => a + b, 0);
|
|
1100
|
+
const remainder = total - known;
|
|
1101
|
+
if (remainder > 0.01) {
|
|
1102
|
+
// Unaccounted leftover (e.g. a non-refundable portion) is folded into
|
|
1103
|
+
// the primary/default payment channel rather than a fabricated 4th row.
|
|
1104
|
+
add(cardLabel, remainder);
|
|
1105
|
+
}
|
|
1106
|
+
return [...amounts.entries()].map(([label, value]) => ({ label, value }));
|
|
1107
|
+
});
|
|
1108
|
+
/** The "Total paid" row always expands — there's always at least one method to show. */
|
|
1109
|
+
this.hasPaidBreakdown = computed(() => this.paidBreakdownRows().length > 0);
|
|
1110
|
+
/**
|
|
1111
|
+
* Display label for `paymentMethodCustomerUsed`, or '' if unknown/internal.
|
|
1112
|
+
* Never surfaces an internal processor name (e.g. Hyperpay) to the agent —
|
|
1113
|
+
* callers fall back to a generic "Original Payment Method" label whenever
|
|
1114
|
+
* this returns ''.
|
|
1115
|
+
*/
|
|
1116
|
+
this.customerPaymentLabel = computed(() => {
|
|
1117
|
+
const code = this.normalizeGatewayCode(this.adjustedData()?.paymentMethodCustomerUsed);
|
|
1118
|
+
if (code && INTERNAL_GATEWAY_CODES.includes(code))
|
|
1119
|
+
return '';
|
|
1120
|
+
return code ? PAYMENT_GATEWAY_LABELS[code] : '';
|
|
1121
|
+
});
|
|
1122
|
+
/** Whether the confirmed cancellation's card refund settles via Mada. */
|
|
1123
|
+
this.isMadaMethod = computed(() => {
|
|
1124
|
+
const code = this.normalizeGatewayCode(this.adjustedData()?.paymentMethodCustomerUsed);
|
|
1125
|
+
return !!code && MADA_GATEWAY_CODES.includes(code);
|
|
1126
|
+
});
|
|
1127
|
+
/**
|
|
1128
|
+
* Label for the standalone "Original Payment Method" option card (shown
|
|
1129
|
+
* when the whole refund goes to one destination). Mada wins over
|
|
1130
|
+
* everything else, reading "Mada Card" instead of the generic gateway
|
|
1131
|
+
* name or the "Original Payment Method" fallback.
|
|
1132
|
+
*/
|
|
1133
|
+
this.originalPaymentLabel = computed(() => {
|
|
1134
|
+
if (this.isMadaMethod())
|
|
1135
|
+
return 'Mada Card';
|
|
1136
|
+
return this.customerPaymentLabel() || 'Original Payment Method';
|
|
1137
|
+
});
|
|
1138
|
+
/** Same as `isMadaMethod`, scoped to the confirmed cancellation result. */
|
|
1139
|
+
this.confirmIsMadaMethod = computed(() => {
|
|
1140
|
+
const code = this.normalizeGatewayCode(this.cancelResult()?.paymentMethodCustomerUsed);
|
|
1141
|
+
return !!code && MADA_GATEWAY_CODES.includes(code);
|
|
1142
|
+
});
|
|
1143
|
+
/**
|
|
1144
|
+
* Split-refund destination rows — up to four: Almatar Wallet (generic
|
|
1145
|
+
* label), the original payment method (card/installment gateway), a
|
|
1146
|
+
* separate loyalty-points-refund row when the backend sends one, and a
|
|
1147
|
+
* dedicated loyalty-program row (Wala, Qitaf, …) for forfeited points
|
|
1148
|
+
* (`forfeitedLoyaltyPointsFallback`) — kept distinct from the Wallet row
|
|
1149
|
+
* even when both are non-zero.
|
|
1150
|
+
*/
|
|
1151
|
+
this.splitRefundRows = computed(() => {
|
|
1152
|
+
const d = this.adjustedData();
|
|
1153
|
+
if (!d)
|
|
1154
|
+
return [];
|
|
1155
|
+
const rows = [];
|
|
1156
|
+
const wallet = Number(d.walletRefundAmount ?? 0);
|
|
1157
|
+
if (wallet > 0) {
|
|
1158
|
+
rows.push({ label: 'Almatar Wallet', value: wallet, instant: true, isLoyalty: false, badgeText: 'Instant' });
|
|
1159
|
+
}
|
|
1160
|
+
const card = Number(d.totalCardRefundAmount ?? 0);
|
|
1161
|
+
if (card > 0) {
|
|
1162
|
+
const badgeText = this.cardBadgeText();
|
|
1163
|
+
rows.push({
|
|
1164
|
+
label: this.isMadaMethod()
|
|
1165
|
+
? 'Mada Card'
|
|
1166
|
+
: (!this.isLoyaltyMethod() && this.customerPaymentLabel()) || 'Original Payment Method',
|
|
1167
|
+
value: card,
|
|
1168
|
+
instant: false,
|
|
1169
|
+
isLoyalty: false,
|
|
1170
|
+
badgeText,
|
|
1171
|
+
isMada: this.isMadaMethod(),
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1174
|
+
const loyalty = Number(d.totalLoyaltyPointsRefundAmount ?? 0);
|
|
1175
|
+
if (loyalty > 0) {
|
|
1176
|
+
rows.push({
|
|
1177
|
+
label: this.customerPaymentLabel() || 'Loyalty Points Refund',
|
|
1178
|
+
value: loyalty,
|
|
1179
|
+
instant: true,
|
|
1180
|
+
isLoyalty: true,
|
|
1181
|
+
badgeText: 'Instant',
|
|
1182
|
+
});
|
|
1183
|
+
}
|
|
1184
|
+
const forfeitedLoyalty = this.forfeitedLoyaltyPointsFallback(d);
|
|
1185
|
+
if (forfeitedLoyalty > 0) {
|
|
1186
|
+
rows.push({
|
|
1187
|
+
label: this.walletOrLoyaltyLabel(d) || 'Loyalty Points',
|
|
1188
|
+
value: forfeitedLoyalty,
|
|
1189
|
+
instant: true,
|
|
1190
|
+
isLoyalty: true,
|
|
1191
|
+
badgeText: 'Instant',
|
|
1192
|
+
});
|
|
1193
|
+
}
|
|
1194
|
+
return rows;
|
|
1195
|
+
});
|
|
1196
|
+
effect(() => {
|
|
1197
|
+
if (this.visible() && this.bookingId()) {
|
|
1198
|
+
this.loadRefund();
|
|
1199
|
+
}
|
|
1200
|
+
else {
|
|
1201
|
+
this.stopHints();
|
|
1202
|
+
this.refundData.set(null);
|
|
1203
|
+
this.cancelResult.set(null);
|
|
1204
|
+
this.onwardChecked.set(true);
|
|
1205
|
+
this.returnChecked.set(true);
|
|
1206
|
+
this.forcedLegType.set(null);
|
|
1207
|
+
this.onwardExpanded.set(true);
|
|
1208
|
+
this.returnExpanded.set(true);
|
|
1209
|
+
this.selectedSource.set('');
|
|
1210
|
+
this.preferredRefundMethod.set('originalPaymentMethod');
|
|
1211
|
+
this.confirming.set(false);
|
|
1212
|
+
this.cancelling.set(false);
|
|
1213
|
+
this.step.set('loading');
|
|
1214
|
+
}
|
|
1215
|
+
}, { allowSignalWrites: true });
|
|
1216
|
+
}
|
|
1217
|
+
loadRefund() {
|
|
1218
|
+
this.loading.set(true);
|
|
1219
|
+
this.startHints();
|
|
1220
|
+
this.bookingService.getRefundDetails(this.bookingId(), this.product()).subscribe({
|
|
1221
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1222
|
+
next: (raw) => {
|
|
1223
|
+
let data = raw?.data ?? raw;
|
|
1224
|
+
this.stopHints();
|
|
1225
|
+
this.refundData.set(data);
|
|
1226
|
+
// Auto-select source: prefer appliedSource, otherwise pick first available
|
|
1227
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1228
|
+
const breakdown = data?.sourceBreakdown ?? {};
|
|
1229
|
+
const sources = Object.keys(breakdown);
|
|
1230
|
+
if (sources.length > 0) {
|
|
1231
|
+
const applied = data?.appliedSource;
|
|
1232
|
+
this.selectedSource.set(applied && breakdown[applied] ? applied : sources[0]);
|
|
1233
|
+
}
|
|
1234
|
+
this.loading.set(false);
|
|
1235
|
+
// Only show the leg picker for a genuine round-trip the backend hasn't
|
|
1236
|
+
// already restricted to a single leg — otherwise go straight to details.
|
|
1237
|
+
if (this.showRoundTripLegCards()) {
|
|
1238
|
+
// Pre-check whichever legs are actually refundable, matching the
|
|
1239
|
+
// consumer app's "non-refundable legs can't be selected" behavior.
|
|
1240
|
+
this.onwardChecked.set(this.onwardRefundable());
|
|
1241
|
+
this.returnChecked.set(this.returnRefundable());
|
|
1242
|
+
this.step.set('select-leg');
|
|
1243
|
+
}
|
|
1244
|
+
else {
|
|
1245
|
+
this.step.set('details');
|
|
1246
|
+
}
|
|
1247
|
+
},
|
|
1248
|
+
error: () => { this.stopHints(); this.loading.set(false); this.toast.error('Could not load refund details.'); },
|
|
1249
|
+
});
|
|
1250
|
+
}
|
|
1251
|
+
/**
|
|
1252
|
+
* Both legs in play — sum each leg's own figures instead of trusting root
|
|
1253
|
+
* (root isn't reliably scoped to the picked alternatives, e.g. rounding
|
|
1254
|
+
* can drift between leg totals and the combined root total).
|
|
1255
|
+
*/
|
|
1256
|
+
buildCombinedLegData(root, onward, ret) {
|
|
1257
|
+
const onwardData = this.buildLegData(root, onward, 'onward');
|
|
1258
|
+
const returnData = this.buildLegData(root, ret, 'return');
|
|
1259
|
+
const sum = (key) => Number(onwardData[key] || 0) + Number(returnData[key] || 0);
|
|
1260
|
+
return {
|
|
1261
|
+
...root,
|
|
1262
|
+
isRefundable: onward.isRefundable === true && ret.isRefundable === true,
|
|
1263
|
+
totalRefundAmount: sum('totalRefundAmount'),
|
|
1264
|
+
totalRefundAmountBeforeCeil: sum('totalRefundAmountBeforeCeil'),
|
|
1265
|
+
totalCardRefundAmount: sum('totalCardRefundAmount'),
|
|
1266
|
+
totalCreditRefundAmount: sum('totalCreditRefundAmount'),
|
|
1267
|
+
totalNonRefundableServiceCharge: sum('totalNonRefundableServiceCharge'),
|
|
1268
|
+
totalCouponAmount: sum('totalCouponAmount'),
|
|
1269
|
+
walletRefundAmount: sum('walletRefundAmount'),
|
|
1270
|
+
totalPenaltyPoints: sum('totalPenaltyPoints'),
|
|
1271
|
+
totalSupplierPenaltyPoints: sum('totalSupplierPenaltyPoints'),
|
|
1272
|
+
totalLoyaltyPoints: sum('totalLoyaltyPoints'),
|
|
1273
|
+
totalGiftAmount: sum('totalGiftAmount'),
|
|
1274
|
+
totalAncillaryRefundAmount: sum('totalAncillaryRefundAmount'),
|
|
1275
|
+
totalLoyaltyPointsRefundAmount: sum('totalLoyaltyPointsRefundAmount'),
|
|
1276
|
+
totalCancellationFee: sum('totalCancellationFee'),
|
|
1277
|
+
totalSupplierBookingAmount: sum('totalSupplierBookingAmount'),
|
|
1278
|
+
originalAmount: Number(root.originalAmount || 0),
|
|
1279
|
+
refundBreakdown: this.mergeBreakdowns(onwardData.refundBreakdown, returnData.refundBreakdown),
|
|
1280
|
+
legInfo: { onward, return: ret },
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
/** Combine two legs' itemized breakdowns for the "both legs" combined view. */
|
|
1284
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1285
|
+
mergeBreakdowns(a, b) {
|
|
1286
|
+
if (!a && !b)
|
|
1287
|
+
return undefined;
|
|
1288
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1289
|
+
const mergeSide = (sa, sb) => ({
|
|
1290
|
+
fare: Number(sa?.fare || 0) + Number(sb?.fare || 0) || undefined,
|
|
1291
|
+
addOns: [...(sa?.addOns ?? []), ...(sb?.addOns ?? [])],
|
|
1292
|
+
ancillaries: [...(sa?.ancillaries ?? []), ...(sb?.ancillaries ?? [])],
|
|
1293
|
+
serviceFee: Number(sa?.serviceFee || 0) + Number(sb?.serviceFee || 0) || undefined,
|
|
1294
|
+
handlingFee: Number(sa?.handlingFee || 0) + Number(sb?.handlingFee || 0) || undefined,
|
|
1295
|
+
cancellationPenalty: Number(sa?.cancellationPenalty || 0) + Number(sb?.cancellationPenalty || 0) || undefined,
|
|
1296
|
+
});
|
|
1297
|
+
return {
|
|
1298
|
+
refundable: mergeSide(a?.refundable, b?.refundable),
|
|
1299
|
+
nonRefundable: mergeSide(a?.nonRefundable, b?.nonRefundable),
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
buildLegData(root, leg, legType) {
|
|
1303
|
+
// When this leg has no sibling in `legInfo` (a genuine one-way booking,
|
|
1304
|
+
// or a narrowed CrossSeller selection where the API only ever sent the
|
|
1305
|
+
// one leg), root necessarily describes this same single leg — so a
|
|
1306
|
+
// destination total the leg's own object left at 0 can safely fall back
|
|
1307
|
+
// to root's figure instead of silently zeroing out a real refund
|
|
1308
|
+
// destination. With a sibling leg present, root aggregates both legs and
|
|
1309
|
+
// is not trustworthy per-leg, so the leg's own value (even 0) wins.
|
|
1310
|
+
const hasSiblingLeg = legType === 'onward' ? !!root.legInfo?.return : !!root.legInfo?.onward;
|
|
1311
|
+
const fallback = (value, rootValue) => Number(value || (hasSiblingLeg ? 0 : rootValue) || 0);
|
|
1312
|
+
const isCreditShell = leg.isCreditShell === true;
|
|
1313
|
+
const legRefund = Number(leg.totalRefundAmount ?? 0);
|
|
1314
|
+
const cardRefund = isCreditShell ? 0 : fallback(leg.totalCardRefundAmount, root.totalCardRefundAmount);
|
|
1315
|
+
const creditRefund = isCreditShell ? legRefund : fallback(leg.totalCreditRefundAmount, root.totalCreditRefundAmount);
|
|
1316
|
+
// The backend sometimes omits `isRefundable` on a single-leg booking's
|
|
1317
|
+
// leg object entirely (not `false`, just absent) while the root/source
|
|
1318
|
+
// breakdown both say the booking is refundable — trust the root flag
|
|
1319
|
+
// rather than defaulting a missing field to "not eligible for a refund".
|
|
1320
|
+
const legIsRefundable = leg.isRefundable === undefined ? root.isRefundable === true : leg.isRefundable === true;
|
|
1321
|
+
return {
|
|
1322
|
+
...root,
|
|
1323
|
+
isRefundable: legIsRefundable,
|
|
1324
|
+
totalRefundAmount: legRefund,
|
|
1325
|
+
// Pre-rounding total — the backend ceils `totalRefundAmount` to a whole
|
|
1326
|
+
// currency unit, so wallet+card+credit+loyalty legitimately fall a few
|
|
1327
|
+
// cents short of it; reconciliation must compare against this instead.
|
|
1328
|
+
totalRefundAmountBeforeCeil: Number(leg.totalRefundAmountBeforeCeil ?? leg.totalRefundAmount ?? 0),
|
|
1329
|
+
totalCardRefundAmount: cardRefund,
|
|
1330
|
+
totalCreditRefundAmount: creditRefund,
|
|
1331
|
+
totalNonRefundableServiceCharge: Number(leg.totalNonRefundableServiceCharge || 0),
|
|
1332
|
+
totalCouponAmount: Number(leg.totalCouponAmount || 0),
|
|
1333
|
+
walletRefundAmount: fallback(leg.walletRefundAmount, root.walletRefundAmount),
|
|
1334
|
+
totalPenaltyPoints: Number(leg.totalPenaltyPoints || 0),
|
|
1335
|
+
totalSupplierPenaltyPoints: Number(leg.totalSupplierPenaltyPoints || 0),
|
|
1336
|
+
totalLoyaltyPoints: Number(leg.totalLoyaltyPoints || 0),
|
|
1337
|
+
totalGiftAmount: Number(leg.totalGiftAmount || 0),
|
|
1338
|
+
totalAncillaryRefundAmount: Number(leg.totalAncillaryRefundAmount || 0),
|
|
1339
|
+
totalLoyaltyPointsRefundAmount: fallback(leg.totalLoyaltyPointsRefundAmount, root.totalLoyaltyPointsRefundAmount),
|
|
1340
|
+
totalCancellationFee: Number(leg.totalCancellationFee ?? leg.totalPenaltyPoints ?? 0),
|
|
1341
|
+
totalSupplierBookingAmount: Number(leg.totalSupplierBookingAmount || 0),
|
|
1342
|
+
originalAmount: Number(root.originalAmount || 0),
|
|
1343
|
+
// Leg-scoped breakdown wins when the backend sends one; a single-leg
|
|
1344
|
+
// booking may only carry it at the root instead.
|
|
1345
|
+
refundBreakdown: leg.refundBreakdown ?? root.refundBreakdown,
|
|
1346
|
+
legInfo: legType === 'onward' ? { onward: leg } : { return: leg },
|
|
1347
|
+
};
|
|
1348
|
+
}
|
|
1349
|
+
startHints() {
|
|
1350
|
+
let i = 0;
|
|
1351
|
+
this.cancelHint.set(this.CANCEL_HINTS[0]);
|
|
1352
|
+
this.hintTimer = setInterval(() => {
|
|
1353
|
+
if (i < this.CANCEL_HINTS.length - 1) {
|
|
1354
|
+
i++;
|
|
1355
|
+
this.cancelHint.set(this.CANCEL_HINTS[i]);
|
|
1356
|
+
}
|
|
1357
|
+
else {
|
|
1358
|
+
clearInterval(this.hintTimer);
|
|
1359
|
+
this.hintTimer = null;
|
|
1360
|
+
}
|
|
1361
|
+
}, 1800);
|
|
1362
|
+
}
|
|
1363
|
+
stopHints() {
|
|
1364
|
+
if (this.hintTimer) {
|
|
1365
|
+
clearInterval(this.hintTimer);
|
|
1366
|
+
this.hintTimer = null;
|
|
1367
|
+
}
|
|
1368
|
+
this.cancelHint.set('');
|
|
1369
|
+
}
|
|
1370
|
+
fmt(value, currency) {
|
|
1371
|
+
const cur = currency ?? this.refundData()?.currency ?? 'SAR';
|
|
1372
|
+
return `${this.fmtNum(value)} ${cur}`;
|
|
1373
|
+
}
|
|
1374
|
+
// Plain formatted number without a currency suffix (used by the calc divider / formula box).
|
|
1375
|
+
fmtNum(value) {
|
|
1376
|
+
return Number(value || 0).toLocaleString('en-SA', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
1377
|
+
}
|
|
1378
|
+
fmtNeg(value, currency) {
|
|
1379
|
+
const n = Number(value || 0);
|
|
1380
|
+
const str = this.fmt(n, currency);
|
|
1381
|
+
return n > 0 ? `− ${str}` : str;
|
|
1382
|
+
}
|
|
1383
|
+
fmtNegResult(value) {
|
|
1384
|
+
const n = Number(value || 0);
|
|
1385
|
+
const str = this.fmtResult(n);
|
|
1386
|
+
return n > 0 ? `− ${str}` : str;
|
|
1387
|
+
}
|
|
1388
|
+
// Entry point from the details screen: always goes to the refund-method
|
|
1389
|
+
// step. For credit-shell refunds that step shows a single read-only credit
|
|
1390
|
+
// notice instead of a picker, since the refund can only go to the shell —
|
|
1391
|
+
// but the agent still sees it before confirming, same as the standard flow.
|
|
1392
|
+
requestCancel() {
|
|
1393
|
+
// NIL refund: nothing to refund at all — skip the refund-method popup
|
|
1394
|
+
// and cancel directly.
|
|
1395
|
+
if (this.isNilRefund()) {
|
|
1396
|
+
this.confirm();
|
|
1397
|
+
}
|
|
1398
|
+
else {
|
|
1399
|
+
this.confirming.set(true);
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
confirm() {
|
|
1403
|
+
const sel = this.selectedLeg();
|
|
1404
|
+
// Build legInfo array: omit when cancelling both (backend treats absence as both)
|
|
1405
|
+
const legInfo = sel === 'onward' ? ['onward'] :
|
|
1406
|
+
sel === 'return' ? ['return'] :
|
|
1407
|
+
undefined; // both legs — omit the field
|
|
1408
|
+
const source = this.selectedSource() || undefined;
|
|
1409
|
+
const preferredRefundMethod = this.preferredRefundMethod();
|
|
1410
|
+
const splitAmounts = preferredRefundMethod === 'split'
|
|
1411
|
+
? {
|
|
1412
|
+
walletRefundAmount: Number(this.adjustedData()?.walletRefundAmount ?? 0),
|
|
1413
|
+
totalCardRefundAmount: Number(this.adjustedData()?.totalCardRefundAmount ?? 0),
|
|
1414
|
+
}
|
|
1415
|
+
: undefined;
|
|
1416
|
+
this.confirming.set(false);
|
|
1417
|
+
this.stopHints();
|
|
1418
|
+
this.cancelling.set(true);
|
|
1419
|
+
this.bookingService.confirmCancel(this.bookingId(), this.product(), legInfo, source, preferredRefundMethod, splitAmounts).subscribe({
|
|
1420
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1421
|
+
next: (raw) => {
|
|
1422
|
+
this.stopHints();
|
|
1423
|
+
this.cancelling.set(false);
|
|
1424
|
+
this.cancelResult.set(raw?.data ?? raw);
|
|
1425
|
+
this.confirmed.emit(sel);
|
|
1426
|
+
},
|
|
1427
|
+
error: () => {
|
|
1428
|
+
this.stopHints();
|
|
1429
|
+
this.cancelling.set(false);
|
|
1430
|
+
this.toast.error('Cancellation failed. Please try again.');
|
|
1431
|
+
},
|
|
1432
|
+
});
|
|
1433
|
+
}
|
|
1434
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdCancelDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1435
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SbdCancelDialogComponent, isStandalone: true, selector: "app-sbd-cancel-dialog", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, bookingId: { classPropertyName: "bookingId", publicName: "bookingId", isSignal: true, isRequired: false, transformFunction: null }, product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: false, transformFunction: null }, pnrInfo: { classPropertyName: "pnrInfo", publicName: "pnrInfo", isSignal: true, isRequired: false, transformFunction: null }, bookingInfo: { classPropertyName: "bookingInfo", publicName: "bookingInfo", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", confirmed: "confirmed" }, ngImport: i0, template: "<p-dialog [visible]=\"visible()\" (visibleChange)=\"$event ? null : closed.emit()\"\n [modal]=\"true\" [blockScroll]=\"true\" [draggable]=\"false\" [resizable]=\"false\"\n [showHeader]=\"false\" [style]=\"{ width: '560px', padding: '0' }\" styleClass=\"sbd-cancel-dialog-wrapper\">\n\n <div class=\"sbd-cancel\">\n\n <!-- Loading refund details \u2014 shows cycling hints -->\n @if (loading()) {\n <div class=\"sbd-cancel__are-you-sure\">\n <button type=\"button\" class=\"sbd-cancel__close-btn sbd-cancel__close-btn--floating\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-cancel__ays-icon\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n </div>\n @for (h of [cancelHint()]; track h) {\n <div class=\"sbd-cancel__ays-hint\">{{ h }}</div>\n }\n <div class=\"sbd-cancel__ays-dots\">\n <span></span><span></span><span></span>\n </div>\n </div>\n }\n\n <!-- Select leg \u2014 shown once the refund preview has fully loaded, before the\n refund breakdown, for round-trip bookings the backend hasn't already\n restricted to a single leg. Same card design as almatar-b2c's\n select-leg screen (checkbox overlay, refundable badge, disclaimer). -->\n @else if (step() === 'select-leg') {\n <div class=\"sbd-cancel__method-header\">\n <button type=\"button\" class=\"sbd-cancel__method-close\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-cancel__method-header-text\">\n <h3 class=\"sbd-cancel__method-title\">Select Leg to Cancel</h3>\n <span class=\"sbd-cancel__method-sub\">Booking ID #{{ bookingId() }}</span>\n </div>\n </div>\n\n <div class=\"sbd-cancel__select-leg-body\">\n @if (forcedLegType(); as forced) {\n <div class=\"sbd-cancel__single-leg-note\">\n <i class=\"pi pi-info-circle\"></i>\n <span>This airline doesn't allow cancelling a single flight \u2014 {{ itineraryLeg(forced)?.from }} to {{ itineraryLeg(forced)?.to }} will be included automatically.</span>\n </div>\n }\n @if (allLegsNonRefundable()) {\n <div class=\"sbd-cancel__all-non-refundable-note\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <span>Sorry, we're unable to provide a refund for this booking, as both flights are non-refundable based on airline rules.</span>\n </div>\n }\n <!-- Onward -->\n <div class=\"sbd-cancel__leg-select-card\"\n [ngClass]=\"{\n 'sbd-cancel__leg-select-card--selected': onwardChecked() && onwardRefundable(),\n 'sbd-cancel__leg-select-card--disabled': !onwardRefundable(),\n 'sbd-cancel__leg-select-card--frozen': forcedLegType() === 'onward'\n }\">\n @if (forcedLegType() !== 'onward') {\n <label class=\"sbd-cancel__leg-select-checkbox\">\n <input type=\"checkbox\" [checked]=\"onwardChecked()\" [disabled]=\"!onwardRefundable()\"\n (change)=\"toggleLeg('onward')\" />\n <span class=\"sbd-cancel__leg-select-icon\"><i class=\"pi pi-check\"></i></span>\n </label>\n } @else {\n <i class=\"pi pi-lock sbd-cancel__leg-select-lock\"></i>\n }\n <div class=\"sbd-cancel__leg-select-content\">\n @if (itineraryLeg('onward'); as leg) {\n <div class=\"sbd-cancel__leg-select-top\">\n <div>\n <span class=\"sbd-cancel__leg-select-name\">{{ leg.from }} to {{ leg.to }}</span>\n <div class=\"sbd-cancel__leg-select-date\">{{ fmtShortDate(leg.depTime) }}</div>\n </div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"onwardRefundable() && forcedLegType() !== 'onward' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ onwardRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n <div class=\"sbd-cancel__leg-select-times\">\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.depTime) }}</span>\n <span class=\"sbd-cancel__leg-select-line\">\n <span class=\"sbd-cancel__leg-select-line-stops\">{{ leg.stops.length > 0 ? (leg.stops.length + ' stop' + (leg.stops.length > 1 ? 's' : '')) : 'Direct' }}</span>\n @if (fmtMins(leg.totalMinutes)) { <span class=\"sbd-cancel__leg-select-line-dur\">{{ fmtMins(leg.totalMinutes) }}</span> }\n <i class=\"pi pi-arrow-right sbd-cancel__leg-select-line-arrow\"></i>\n </span>\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.arrTime) }}</span>\n </div>\n @if (leg.airlineName || leg.cabin) {\n <span class=\"sbd-cancel__leg-select-airline\">\n {{ leg.airlineName }}{{ leg.airlineName && leg.cabin ? ' \u00B7 ' : '' }}{{ leg.cabin }}\n </span>\n }\n <div class=\"sbd-cancel__leg-select-footer\">\n @if (leg.operatedBy.length) {\n <span class=\"sbd-cancel__leg-select-operated-by\">Operated by {{ leg.operatedBy.join(', ') }}</span>\n }\n <!-- <i class=\"pi pi-chevron-down sbd-cancel__leg-select-chevron\"></i> -->\n </div>\n } @else {\n <div class=\"sbd-cancel__leg-select-top\">\n <span class=\"sbd-cancel__leg-select-name\">Onward</span>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"onwardRefundable() && forcedLegType() !== 'onward' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ onwardRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n }\n @if (!onwardRefundable()) {\n <div class=\"sbd-cancel__leg-select-notice\">\n <i class=\"pi pi-info-circle\"></i>\n <span>This flight type doesn't allow refunds on cancellation, based on the airline's fare rules.</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Return -->\n <div class=\"sbd-cancel__leg-select-card\"\n [ngClass]=\"{\n 'sbd-cancel__leg-select-card--selected': returnChecked() && returnRefundable(),\n 'sbd-cancel__leg-select-card--disabled': !returnRefundable(),\n 'sbd-cancel__leg-select-card--frozen': forcedLegType() === 'return'\n }\">\n @if (forcedLegType() !== 'return') {\n <label class=\"sbd-cancel__leg-select-checkbox\">\n <input type=\"checkbox\" [checked]=\"returnChecked()\" [disabled]=\"!returnRefundable()\"\n (change)=\"toggleLeg('return')\" />\n <span class=\"sbd-cancel__leg-select-icon\"><i class=\"pi pi-check\"></i></span>\n </label>\n } @else {\n <i class=\"pi pi-lock sbd-cancel__leg-select-lock\"></i>\n }\n <div class=\"sbd-cancel__leg-select-content\">\n @if (itineraryLeg('return'); as leg) {\n <div class=\"sbd-cancel__leg-select-top\">\n <div>\n <span class=\"sbd-cancel__leg-select-name\">{{ leg.from }} to {{ leg.to }}</span>\n <div class=\"sbd-cancel__leg-select-date\">{{ fmtShortDate(leg.depTime) }}</div>\n </div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"returnRefundable() && forcedLegType() !== 'return' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ returnRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n <div class=\"sbd-cancel__leg-select-times\">\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.depTime) }}</span>\n <span class=\"sbd-cancel__leg-select-line\">\n <span class=\"sbd-cancel__leg-select-line-stops\">{{ leg.stops.length > 0 ? (leg.stops.length + ' stop' + (leg.stops.length > 1 ? 's' : '')) : 'Direct' }}</span>\n @if (fmtMins(leg.totalMinutes)) { <span class=\"sbd-cancel__leg-select-line-dur\">{{ fmtMins(leg.totalMinutes) }}</span> }\n <i class=\"pi pi-arrow-right sbd-cancel__leg-select-line-arrow\"></i>\n </span>\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.arrTime) }}</span>\n </div>\n @if (leg.airlineName || leg.cabin) {\n <span class=\"sbd-cancel__leg-select-airline\">\n {{ leg.airlineName }}{{ leg.airlineName && leg.cabin ? ' \u00B7 ' : '' }}{{ leg.cabin }}\n </span>\n }\n <div class=\"sbd-cancel__leg-select-footer\">\n @if (leg.operatedBy.length) {\n <span class=\"sbd-cancel__leg-select-operated-by\">Operated by {{ leg.operatedBy.join(', ') }}</span>\n }\n <!-- <i class=\"pi pi-chevron-down sbd-cancel__leg-select-chevron\"></i> -->\n </div>\n } @else {\n <div class=\"sbd-cancel__leg-select-top\">\n <span class=\"sbd-cancel__leg-select-name\">Return</span>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"returnRefundable() && forcedLegType() !== 'return' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ returnRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n }\n @if (!returnRefundable()) {\n <div class=\"sbd-cancel__leg-select-notice\">\n <i class=\"pi pi-info-circle\"></i>\n <span>This flight type doesn't allow refunds on cancellation, based on the airline's fare rules.</span>\n </div>\n }\n </div>\n </div>\n </div>\n\n @if (!allLegsNonRefundable() && !onwardChecked() && !returnChecked()) {\n <div class=\"sbd-cancel__leg-select-hint\">Select at least one flight to continue</div>\n }\n\n <div class=\"sbd-cancel__footer\">\n <button pButton\n styleClass=\"sbd-cancel__btn-primary\"\n label=\"Continue\"\n [disabled]=\"allLegsNonRefundable() || (!onwardChecked() && !returnChecked())\"\n (click)=\"step.set('details')\"></button>\n </div>\n }\n\n <!-- Refund method \u2014 replaces the old are-you-sure + radio picker.\n Stays mounted (dimmed) behind the result overlay once confirmed. -->\n @else if (confirming() || cancelResult()) {\n <div class=\"sbd-cancel__method-header\">\n <button type=\"button\" class=\"sbd-cancel__method-close\" (click)=\"confirming.set(false)\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-cancel__method-header-text\">\n <h3 class=\"sbd-cancel__method-title\">Refund Method</h3>\n <span class=\"sbd-cancel__method-sub\">Booking ID #{{ bookingId() }}</span>\n </div>\n </div>\n\n <div class=\"sbd-cancel__method-body\">\n <div class=\"sbd-cancel__method-amount\">\n <span>You will get back</span>\n <strong>{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n </div>\n\n @if (isCreditShell()) {\n <!-- Credit-shell refunds have exactly one destination \u2014 the airline\n credit shell \u2014 so show it as a read-only card, not a picker. -->\n <div class=\"sbd-cancel__method-option sbd-cancel__method-option--active\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ creditShellSupplierName() }} website credit</span>\n <span class=\"sbd-cancel__method-desc\">Your refund will be issued instantly by {{ creditShellSupplierName() }}.</span>\n <span class=\"sbd-cancel__method-badge sbd-cancel__method-badge--instant\">\n <svg width=\"12\" height=\"9\" viewBox=\"0 0 12 9\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.31818 0C8.42727 0 9.49093 0.440583 10.2752 1.22483C11.0594 2.00907 11.5 3.07273 11.5 4.18182C11.5 5.2909 11.0594 6.35457 10.2752 7.13881C9.49093 7.92305 8.42727 8.36364 7.31818 8.36364C6.20909 8.36364 5.14543 7.92305 4.36119 7.13881C3.57695 6.35457 3.13636 5.2909 3.13636 4.18182C3.13636 3.07273 3.57695 2.00907 4.36119 1.22483C5.14543 0.440583 6.20909 0 7.31818 0ZM7.31818 1.04545C6.48637 1.04545 5.68862 1.37589 5.10044 1.96407C4.51226 2.55226 4.18182 3.35 4.18182 4.18182C4.18182 5.01363 4.51226 5.81138 5.10044 6.39956C5.68862 6.98774 6.48637 7.31818 7.31818 7.31818C8.15 7.31818 8.94774 6.98774 9.53593 6.39956C10.1241 5.81138 10.4545 5.01363 10.4545 4.18182C10.4545 3.35 10.1241 2.55226 9.53593 1.96407C8.94774 1.37589 8.15 1.04545 7.31818 1.04545ZM6.79545 2.09091H7.57955V4.06682L8.7975 5.28477L8.24341 5.83886L6.79545 4.39091V2.09091ZM0.522727 7.31818C0.384091 7.31818 0.251134 7.26311 0.153103 7.16508C0.0550729 7.06705 0 6.93409 0 6.79545C0 6.65682 0.0550729 6.52386 0.153103 6.42583C0.251134 6.3278 0.384091 6.27273 0.522727 6.27273H2.52477C2.68682 6.64386 2.89591 6.99409 3.13636 7.31818H0.522727ZM1.04545 4.70455C0.906819 4.70455 0.773861 4.64947 0.67583 4.55144C0.5778 4.45341 0.522727 4.32045 0.522727 4.18182C0.522727 4.04318 0.5778 3.91022 0.67583 3.81219C0.773861 3.71416 0.906819 3.65909 1.04545 3.65909H2.11705L2.09091 4.18182L2.11705 4.70455H1.04545ZM1.56818 2.09091C1.42955 2.09091 1.29659 2.03584 1.19856 1.93781C1.10053 1.83978 1.04545 1.70682 1.04545 1.56818C1.04545 1.42955 1.10053 1.29659 1.19856 1.19856C1.29659 1.10053 1.42955 1.04545 1.56818 1.04545H3.13636C2.89591 1.36955 2.68682 1.71977 2.52477 2.09091H1.56818Z\"\n fill=\"#15803C\"\n />\n </svg>\n Instant\n </span>\n </span>\n </div>\n\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-info-circle\"></i>\n <span>\n Your refund will be issued as airline credit under the same PNR.\n It can be used only for future booking on {{ creditShellSupplierName() }} website.\n </span>\n </div>\n\n <!-- Refundable ancillaries (baggage, seats, \u2026) can independently be\n flagged credit-shell or not \u2014 each renders as its own card,\n matching either the credit-shell style above or the normal\n wallet style, both with the same nested note when credit-shell. -->\n @for (item of creditShellAncillaryItems(); track item.name) {\n <div class=\"sbd-cancel__method-option sbd-cancel__method-option--active\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">\n {{ item.isCreditShell ? (creditShellSupplierName() + ' website credit') : 'Almatar Wallet' }}\n \u2014 {{ item.name }}\n </span>\n <span class=\"sbd-cancel__method-desc\">\n @if (item.isCreditShell) {\n Your refund will be issued instantly by {{ creditShellSupplierName() }}.\n } @else {\n Usable for future bookings\n }\n </span>\n <span class=\"sbd-cancel__method-badge sbd-cancel__method-badge--instant\">\n <svg width=\"12\" height=\"9\" viewBox=\"0 0 12 9\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.31818 0C8.42727 0 9.49093 0.440583 10.2752 1.22483C11.0594 2.00907 11.5 3.07273 11.5 4.18182C11.5 5.2909 11.0594 6.35457 10.2752 7.13881C9.49093 7.92305 8.42727 8.36364 7.31818 8.36364C6.20909 8.36364 5.14543 7.92305 4.36119 7.13881C3.57695 6.35457 3.13636 5.2909 3.13636 4.18182C3.13636 3.07273 3.57695 2.00907 4.36119 1.22483C5.14543 0.440583 6.20909 0 7.31818 0ZM7.31818 1.04545C6.48637 1.04545 5.68862 1.37589 5.10044 1.96407C4.51226 2.55226 4.18182 3.35 4.18182 4.18182C4.18182 5.01363 4.51226 5.81138 5.10044 6.39956C5.68862 6.98774 6.48637 7.31818 7.31818 7.31818C8.15 7.31818 8.94774 6.98774 9.53593 6.39956C10.1241 5.81138 10.4545 5.01363 10.4545 4.18182C10.4545 3.35 10.1241 2.55226 9.53593 1.96407C8.94774 1.37589 8.15 1.04545 7.31818 1.04545ZM6.79545 2.09091H7.57955V4.06682L8.7975 5.28477L8.24341 5.83886L6.79545 4.39091V2.09091ZM0.522727 7.31818C0.384091 7.31818 0.251134 7.26311 0.153103 7.16508C0.0550729 7.06705 0 6.93409 0 6.79545C0 6.65682 0.0550729 6.52386 0.153103 6.42583C0.251134 6.3278 0.384091 6.27273 0.522727 6.27273H2.52477C2.68682 6.64386 2.89591 6.99409 3.13636 7.31818H0.522727ZM1.04545 4.70455C0.906819 4.70455 0.773861 4.64947 0.67583 4.55144C0.5778 4.45341 0.522727 4.32045 0.522727 4.18182C0.522727 4.04318 0.5778 3.91022 0.67583 3.81219C0.773861 3.71416 0.906819 3.65909 1.04545 3.65909H2.11705L2.09091 4.18182L2.11705 4.70455H1.04545ZM1.56818 2.09091C1.42955 2.09091 1.29659 2.03584 1.19856 1.93781C1.10053 1.83978 1.04545 1.70682 1.04545 1.56818C1.04545 1.42955 1.10053 1.29659 1.19856 1.19856C1.29659 1.10053 1.42955 1.04545 1.56818 1.04545H3.13636C2.89591 1.36955 2.68682 1.71977 2.52477 2.09091H1.56818Z\"\n fill=\"#15803C\"\n />\n </svg>\n Instant\n </span>\n @if (item.isCreditShell) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your refund will be issued as airline credit under the same PNR. It can be used only for future booking on {{ creditShellSupplierName() }} website.</span>\n </span>\n }\n </span>\n <strong>{{ fmt(item.amount) }}</strong>\n </div>\n }\n } @else {\n\n @if (isFullWalletRefundAllowed() || isWalletOnlyRefund() || isLoyaltyOnlyRefund()) {\n <button type=\"button\" class=\"sbd-cancel__method-option\"\n [ngClass]=\"{ 'sbd-cancel__method-option--active': preferredRefundMethod() === 'wallet' }\"\n (click)=\"preferredRefundMethod.set('wallet')\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ walletCardLabel() }}</span>\n <span class=\"sbd-cancel__method-desc\">Usable for future bookings</span>\n <span class=\"sbd-cancel__method-badge sbd-cancel__method-badge--instant\">\n <svg width=\"12\" height=\"9\" viewBox=\"0 0 12 9\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.31818 0C8.42727 0 9.49093 0.440583 10.2752 1.22483C11.0594 2.00907 11.5 3.07273 11.5 4.18182C11.5 5.2909 11.0594 6.35457 10.2752 7.13881C9.49093 7.92305 8.42727 8.36364 7.31818 8.36364C6.20909 8.36364 5.14543 7.92305 4.36119 7.13881C3.57695 6.35457 3.13636 5.2909 3.13636 4.18182C3.13636 3.07273 3.57695 2.00907 4.36119 1.22483C5.14543 0.440583 6.20909 0 7.31818 0ZM7.31818 1.04545C6.48637 1.04545 5.68862 1.37589 5.10044 1.96407C4.51226 2.55226 4.18182 3.35 4.18182 4.18182C4.18182 5.01363 4.51226 5.81138 5.10044 6.39956C5.68862 6.98774 6.48637 7.31818 7.31818 7.31818C8.15 7.31818 8.94774 6.98774 9.53593 6.39956C10.1241 5.81138 10.4545 5.01363 10.4545 4.18182C10.4545 3.35 10.1241 2.55226 9.53593 1.96407C8.94774 1.37589 8.15 1.04545 7.31818 1.04545ZM6.79545 2.09091H7.57955V4.06682L8.7975 5.28477L8.24341 5.83886L6.79545 4.39091V2.09091ZM0.522727 7.31818C0.384091 7.31818 0.251134 7.26311 0.153103 7.16508C0.0550729 7.06705 0 6.93409 0 6.79545C0 6.65682 0.0550729 6.52386 0.153103 6.42583C0.251134 6.3278 0.384091 6.27273 0.522727 6.27273H2.52477C2.68682 6.64386 2.89591 6.99409 3.13636 7.31818H0.522727ZM1.04545 4.70455C0.906819 4.70455 0.773861 4.64947 0.67583 4.55144C0.5778 4.45341 0.522727 4.32045 0.522727 4.18182C0.522727 4.04318 0.5778 3.91022 0.67583 3.81219C0.773861 3.71416 0.906819 3.65909 1.04545 3.65909H2.11705L2.09091 4.18182L2.11705 4.70455H1.04545ZM1.56818 2.09091C1.42955 2.09091 1.29659 2.03584 1.19856 1.93781C1.10053 1.83978 1.04545 1.70682 1.04545 1.56818C1.04545 1.42955 1.10053 1.29659 1.19856 1.19856C1.29659 1.10053 1.42955 1.04545 1.56818 1.04545H3.13636C2.89591 1.36955 2.68682 1.71977 2.52477 2.09091H1.56818Z\"\n fill=\"#15803C\"\n />\n </svg>\n Instant Refund\n </span>\n @if (hasLoyaltyPointsRefund() && !hasCashWalletRefund()) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>External loyalty points are refunded to your almatar Wallet as permanent points and ready to use in your next booking.</span>\n </span>\n }\n </span>\n <span class=\"sbd-cancel__method-radio\"></span>\n </button>\n }\n\n <!-- Original payment method \u2014 replaced with a \"Split Refund\" card whenever\n part of the refund is forced to the wallet (e.g. loyalty points used),\n since the total can't go 100% to the original payment method.\n Name/desc/badge/icon become gateway-specific for installment (Tamara,\n Tabby) and loyalty (Al Rajhi Mokafaa) payment methods. -->\n @if (!hasSplitRefund() && !isWalletOnlyRefund() && !isLoyaltyOnlyRefund()) {\n <button type=\"button\" class=\"sbd-cancel__method-option\"\n [ngClass]=\"{ 'sbd-cancel__method-option--active': preferredRefundMethod() === 'originalPaymentMethod' }\"\n (click)=\"preferredRefundMethod.set('originalPaymentMethod')\">\n <span class=\"sbd-cancel__method-icon\">\n <i class=\"pi\" [ngClass]=\"isSpecialGatewayMethod() ? 'pi-wallet' : 'pi-credit-card'\"></i>\n </span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ originalPaymentLabel() }}</span>\n <span class=\"sbd-cancel__method-desc\">\n @if (isInstallmentMethod()) {\n Returned to your {{ customerPaymentLabel() }} installment plan\n } @else if (isLoyaltyMethod()) {\n Refunded to your {{ customerPaymentLabel() }} account\n } @else {\n Returned to your original payment method\n }\n </span>\n <span class=\"sbd-cancel__method-badge\" [ngClass]=\"isLoyaltyMethod() ? 'sbd-cancel__method-badge--loyalty' : 'sbd-cancel__method-badge--days'\">\n @if (!isLoyaltyMethod()) {\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M3.30078 6.50195C3.20312 6.50195 3.12174 6.4694 3.05664 6.4043C2.99154 6.33919 2.95898 6.25781 2.95898 6.16016C2.95898 6.06576 2.99154 5.986 3.05664 5.9209C3.12174 5.85579 3.20312 5.82324 3.30078 5.82324H5.5127V2.86914C5.5127 2.77474 5.54525 2.69499 5.61035 2.62988C5.67546 2.56478 5.75521 2.53223 5.84961 2.53223C5.94727 2.53223 6.02865 2.56478 6.09375 2.62988C6.15885 2.69499 6.19141 2.77474 6.19141 2.86914V6.16016C6.19141 6.25781 6.15885 6.33919 6.09375 6.4043C6.02865 6.4694 5.94727 6.50195 5.84961 6.50195H3.30078ZM5.85449 10.9551C5.16764 10.9551 4.52311 10.8249 3.9209 10.5645C3.31868 10.3073 2.78971 9.95085 2.33398 9.49512C1.87826 9.03939 1.52018 8.51042 1.25977 7.9082C1.0026 7.30599 0.874023 6.66146 0.874023 5.97461C0.874023 5.28776 1.0026 4.64323 1.25977 4.04102C1.52018 3.4388 1.87826 2.90983 2.33398 2.4541C2.78971 1.99512 3.31868 1.63704 3.9209 1.37988C4.52311 1.12272 5.16764 0.994141 5.85449 0.994141C6.54134 0.994141 7.18587 1.12272 7.78809 1.37988C8.3903 1.63704 8.91927 1.99512 9.375 2.4541C9.83073 2.90983 10.1872 3.4388 10.4443 4.04102C10.7048 4.64323 10.835 5.28776 10.835 5.97461C10.835 6.66146 10.7048 7.30599 10.4443 7.9082C10.1872 8.51042 9.83073 9.03939 9.375 9.49512C8.91927 9.95085 8.3903 10.3073 7.78809 10.5645C7.18587 10.8249 6.54134 10.9551 5.85449 10.9551ZM5.85449 10.125C6.42741 10.125 6.96452 10.0176 7.46582 9.80273C7.96712 9.58789 8.4082 9.29004 8.78906 8.90918C9.16992 8.52832 9.46777 8.08724 9.68262 7.58594C9.89746 7.08464 10.0049 6.54753 10.0049 5.97461C10.0049 5.40169 9.89746 4.86458 9.68262 4.36328C9.46777 3.85872 9.16992 3.41764 8.78906 3.04004C8.4082 2.65918 7.96712 2.36133 7.46582 2.14648C6.96452 1.93164 6.42741 1.82422 5.85449 1.82422C5.28158 1.82422 4.74447 1.93164 4.24316 2.14648C3.74186 2.36133 3.30078 2.65918 2.91992 3.04004C2.53906 3.41764 2.24121 3.85872 2.02637 4.36328C1.81152 4.86458 1.7041 5.40169 1.7041 5.97461C1.7041 6.54753 1.81152 7.08464 2.02637 7.58594C2.24121 8.08724 2.53906 8.52832 2.91992 8.90918C3.30078 9.29004 3.74186 9.58789 4.24316 9.80273C4.74447 10.0176 5.28158 10.125 5.85449 10.125Z\"\n fill=\"#0B54C2\"\n />\n </svg>\n } @else {\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"#0B54C2\" stroke-width=\"1.2\" />\n <path d=\"M6 5.5v3M6 3.9v.01\" stroke=\"#0B54C2\" stroke-width=\"1.2\" stroke-linecap=\"round\" />\n </svg>\n }\n {{ cardBadgeText() }}\n </span>\n </span>\n <span class=\"sbd-cancel__option-end\">\n @if (isMadaMethod()) {\n <span class=\"sbd-cancel__mada-logo\" aria-hidden=\"true\">\n <ng-container *ngTemplateOutlet=\"madaLogo\"></ng-container>\n </span>\n }\n <span class=\"sbd-cancel__method-radio\"></span>\n </span>\n </button>\n }\n\n <!-- Split Refund -->\n @if (hasSplitRefund()) {\n <button type=\"button\" class=\"sbd-cancel__method-option sbd-cancel__method-option--split\"\n [ngClass]=\"{ 'sbd-cancel__method-option--active': preferredRefundMethod() === 'split' }\"\n (click)=\"preferredRefundMethod.set('split')\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">Split Refund</span>\n <span class=\"sbd-cancel__method-desc\">Returned to your original payment method</span>\n </span>\n <strong class=\"sbd-cancel__method-split-total\">{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n <span class=\"sbd-cancel__method-radio\"></span>\n\n <span class=\"sbd-cancel__method-split-breakdown\">\n @for (row of splitRefundRows(); track row.label) {\n <span class=\"sbd-cancel__method-split-row\">\n <span class=\"sbd-cancel__method-split-label\">\n {{ row.label }}\n @if (row.isMada) {\n <span class=\"sbd-cancel__mada-logo\" aria-hidden=\"true\">\n <ng-container *ngTemplateOutlet=\"madaLogo\"></ng-container>\n </span>\n }\n </span>\n <strong>{{ fmt(row.value) }}</strong>\n </span>\n <span class=\"sbd-cancel__method-badge\"\n [ngClass]=\"row.instant ? 'sbd-cancel__method-badge--instant' : (isLoyaltyMethod() ? 'sbd-cancel__method-badge--loyalty' : 'sbd-cancel__method-badge--days')\">\n {{ row.badgeText }}\n </span>\n @if (row.isLoyalty) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>External loyalty points are refunded to your almatar Wallet as permanent points and ready to use in your next booking.</span>\n </span>\n }\n }\n </span>\n </button>\n }\n }\n </div>\n\n <div class=\"sbd-cancel__footer\">\n <button pButton\n styleClass=\"sbd-cancel__btn-danger-pill\"\n [label]=\"cancelling() ? 'Cancelling...' : 'Confirm Cancellation'\"\n [disabled]=\"cancelling()\" (click)=\"confirm()\"></button>\n </div>\n }\n\n <!-- Main card -->\n @else if (refundData() && step() === 'details') {\n <!-- Card header -->\n <div class=\"sbd-cancel__header sbd-cancel__header--stack\">\n <div class=\"sbd-cancel__header-titles\">\n <span class=\"sbd-cancel__header-title\">Cancel Booking Request</span>\n <span class=\"sbd-cancel__header-sub\">#{{ refundData()?.bookingId ?? bookingId() }}</span>\n </div>\n <button type=\"button\" class=\"sbd-cancel__close-btn\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n\n <div class=\"sbd-cancel__body\">\n\n <!-- Non-refundable -->\n @if (!refundData()?.isRefundable) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <div>\n <strong>This booking is not eligible for a refund.</strong>\n @if (refundData()?.cause) {\n <p>{{ refundData()?.cause }}</p>\n } @else {\n <p>Please escalate to the relevant team for manual handling.</p>\n }\n </div>\n </div>\n }\n\n <!-- Refundable flow -->\n @else {\n\n <!-- Top summary: paid / get back -->\n <div class=\"sbd-cancel__summary\">\n <div class=\"sbd-cancel__summary-row\"\n [ngClass]=\"{ 'sbd-cancel__summary-row--toggle': hasPaidBreakdown() && !!adjustedData()?.totalWalletAmount }\"\n (click)=\"hasPaidBreakdown() && !!adjustedData()?.totalWalletAmount && togglePaidSummary()\">\n <span class=\"sbd-cancel__summary-label\"><i class=\"pi pi-wallet\"></i> Total paid</span>\n <span class=\"sbd-cancel__summary-value\">\n <strong>{{ fmt(adjustedData()?.originalAmount) }}</strong>\n @if (hasPaidBreakdown() && !!adjustedData()?.totalWalletAmount) {\n <button type=\"button\" class=\"sbd-cancel__leg-chevron\"\n [ngClass]=\"{ 'sbd-cancel__leg-chevron--collapsed': !paidSummaryExpanded() }\"\n aria-label=\"Toggle paid breakdown\">\n <i class=\"pi pi-chevron-up\"></i>\n </button>\n }\n </span>\n </div>\n\n @if (hasPaidBreakdown() && paidSummaryExpanded() && !!adjustedData()?.totalWalletAmount) {\n <div class=\"sbd-cancel__summary-breakdown\">\n @for (row of paidBreakdownRows(); track row.label) {\n @if (row.label === 'Almatar Wallet') {\n <div class=\"sbd-cancel__summary-breakdown-row\">\n <span>{{ row.label }}</span>\n <span>{{ fmt(row.value) }}</span>\n </div>\n }\n }\n </div>\n }\n\n <div class=\"sbd-cancel__summary-row sbd-cancel__summary-row--refund\">\n <span class=\"sbd-cancel__summary-label\"><i class=\"pi pi-dollar\"></i> You will get back</span>\n <strong>{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n </div>\n </div>\n\n <!-- Golden Guarantee gift \u2014 overrides credit-shell messaging below -->\n @if (hasGoldenGuaranteeGift()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--success\">\n <i class=\"pi pi-shield\"></i>\n <span>You're covered by Cancel for any reason service, you'll get 100% refund, minus any applicable fees. See the breakdown below.</span>\n </div>\n }\n\n <!-- One-way (or a round-trip restricted to a single leg): single card -->\n @if (!showRoundTripLegCards()) {\n <!-- Source selector (multiple suppliers) -->\n @if (availableSources().length > 1) {\n <div class=\"sbd-cancel__source-selector\">\n <span class=\"sbd-cancel__source-label\">Cancel via</span>\n @for (src of availableSources(); track src) {\n <button class=\"sbd-cancel__source-chip\"\n [ngClass]=\"{\n 'sbd-cancel__source-chip--active': selectedSource() === src,\n 'sbd-cancel__source-chip--no-refund': activeSourceBreakdown()?.[src]?.isRefundable === false\n }\"\n (click)=\"selectedSource.set(src)\">\n {{ src }}\n @if (activeSourceBreakdown()?.[src]?.isRefundable === false) {\n <i class=\"pi pi-ban\" style=\"font-size:10px; margin-left:4px;\"></i>\n }\n </button>\n }\n </div>\n @if (sourceNonRefundableHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>{{ sourceNonRefundableHint() }}</span>\n </div>\n }\n }\n\n <!-- Not refundable -->\n @if (!currentData()?.isRefundable) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <div>\n <strong>This leg is not eligible for a refund.</strong>\n <p>Please escalate to the relevant team for manual handling.</p>\n </div>\n </div>\n } @else {\n <div class=\"sbd-cancel__section-title\">Refund Details</div>\n\n <div class=\"sbd-cancel__refund-card\">\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--green\">Refundable</span>\n\n @if (refundableBreakdownRows(adjustedData()).length) {\n @for (r of refundableBreakdownRows(adjustedData()); track r.label) {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>{{ r.label }}</span>\n <strong>{{ fmt(r.value) }}</strong>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>Fare</span>\n <strong>{{ fmt(adjustedData()?.originalAmount) }}</strong>\n </div>\n }\n\n <!-- hide addon note new CR from CX -->\n <!-- @if (hasRefundableAddonNote(adjustedData())) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--neutral\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your add-on service/s refund will be processed separately by our Customer Service team shortly.</span>\n </div>\n } -->\n\n <!-- Deductions -->\n @if (deductions().length) {\n <div class=\"sbd-cancel__refund-card-divider\"></div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--muted\">Not Refunded - Deductions</span>\n @for (d of deductions(); track d.label) {\n <div class=\"sbd-cancel__refund-card-line\">\n <span>\n {{ d.label }}\n @if (d.badge) { <span class=\"sbd-cancel__tag\">{{ d.badge }}</span> }\n </span>\n <span class=\"sbd-cancel__refund-card-line--neg\">{{ fmtNeg(d.value) }}</span>\n </div>\n }\n }\n\n <div class=\"sbd-cancel__refund-card-divider sbd-cancel__refund-card-divider--dashed\"></div>\n <div class=\"sbd-cancel__refund-card-total\">\n <span>Total Refund</span>\n <strong>{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n </div>\n </div>\n\n <!-- Credit shell -->\n @if (creditShellNote()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F {{ creditShellNote() }}</span>\n </div>\n }\n }\n }\n\n <!-- Round trip: one collapsible card per leg (only when both legs are cancellable) -->\n @if (showRoundTripLegCards()) {\n <!-- Gift hint -->\n @if (giftHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--tip\">\n <i class=\"pi pi-info-circle\"></i>\n <span>{{ giftHint() }}</span>\n </div>\n }\n\n <!-- Mixed hint -->\n @if (mixedHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <span>{{ mixedHint() }}</span>\n </div>\n }\n\n <!-- Source selector (multiple suppliers) -->\n @if (availableSources().length > 1) {\n <div class=\"sbd-cancel__source-selector\">\n <span class=\"sbd-cancel__source-label\">Cancel via</span>\n @for (src of availableSources(); track src) {\n <button class=\"sbd-cancel__source-chip\"\n [ngClass]=\"{\n 'sbd-cancel__source-chip--active': selectedSource() === src,\n 'sbd-cancel__source-chip--no-refund': activeSourceBreakdown()?.[src]?.isRefundable === false\n }\"\n (click)=\"selectedSource.set(src)\">\n {{ src }}\n @if (activeSourceBreakdown()?.[src]?.isRefundable === false) {\n <i class=\"pi pi-ban\" style=\"font-size:10px; margin-left:4px;\"></i>\n }\n </button>\n }\n </div>\n @if (sourceNonRefundableHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>{{ sourceNonRefundableHint() }}</span>\n </div>\n }\n }\n\n <!-- Onward leg card -->\n @if (onwardChecked()) {\n <div class=\"sbd-cancel__leg-card\">\n <div class=\"sbd-cancel__leg-card-header\" (click)=\"toggleLegExpanded('onward')\">\n <span class=\"sbd-cancel__leg-checkbox\">Onward</span>\n <button type=\"button\" class=\"sbd-cancel__leg-chevron\"\n [ngClass]=\"{ 'sbd-cancel__leg-chevron--collapsed': !onwardExpanded() }\"\n aria-label=\"Toggle\">\n <i class=\"pi pi-chevron-up\"></i>\n </button>\n </div>\n\n @if (onwardExpanded()) {\n <div class=\"sbd-cancel__leg-card-body\">\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"legAdjustedData('onward')?.isRefundable ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--red'\">\n {{ legAdjustedData('onward')?.isRefundable ? 'Refundable' : 'Non-Refundable' }}\n </span>\n\n @if (legAdjustedData('onward')?.isRefundable) {\n @if (refundableBreakdownRows(legAdjustedData('onward')).length) {\n @for (r of refundableBreakdownRows(legAdjustedData('onward')); track r.label) {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>{{ r.label }}</span>\n <strong>{{ fmt(r.value) }}</strong>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>Fare</span>\n <strong>{{ fmt(legRefundPool('onward')) }}</strong>\n </div>\n }\n\n <!-- hide addon note new CR from CX -->\n <!-- @if (hasRefundableAddonNote(legAdjustedData('onward'))) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--neutral\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your add-on service/s refund will be processed separately by our Customer Service team shortly.</span>\n </div>\n } -->\n\n @if (legDeductions('onward').length && !isCreditShell()) {\n <div class=\"sbd-cancel__refund-card-divider\"></div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--muted\">Not Refunded - Deductions</span>\n @for (d of legDeductions('onward'); track d.label) {\n <div class=\"sbd-cancel__refund-card-line\">\n <span>\n {{ d.label }}\n @if (d.badge) { <span class=\"sbd-cancel__tag\">{{ d.badge }}</span> }\n </span>\n <span class=\"sbd-cancel__refund-card-line--neg\">{{ fmtNeg(d.value) }}</span>\n </div>\n }\n }\n\n <div class=\"sbd-cancel__refund-card-divider sbd-cancel__refund-card-divider--dashed\"></div>\n <div class=\"sbd-cancel__refund-card-total\">\n <span>Departure Total Refund</span>\n <strong>{{ fmt(legAdjustedData('onward')?.totalRefundAmount) }}</strong>\n </div>\n\n @if (refundData()?.legInfo?.onward?.isCreditShell && !hasGoldenGuaranteeGift()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F The refund for the onward flight has been issued as an Airline Credit Shell.</span>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>This leg is not eligible for a refund.</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Return leg card -->\n @if (returnChecked()) {\n <div class=\"sbd-cancel__leg-card\">\n <div class=\"sbd-cancel__leg-card-header\" (click)=\"toggleLegExpanded('return')\">\n <span class=\"sbd-cancel__leg-checkbox\">Return</span>\n <button type=\"button\" class=\"sbd-cancel__leg-chevron\"\n [ngClass]=\"{ 'sbd-cancel__leg-chevron--collapsed': !returnExpanded() }\"\n aria-label=\"Toggle\">\n <i class=\"pi pi-chevron-up\"></i>\n </button>\n </div>\n\n @if (returnExpanded()) {\n <div class=\"sbd-cancel__leg-card-body\">\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"legAdjustedData('return')?.isRefundable ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--red'\">\n {{ legAdjustedData('return')?.isRefundable ? 'Refundable' : 'Non-Refundable' }}\n </span>\n\n @if (legAdjustedData('return')?.isRefundable) {\n @if (refundableBreakdownRows(legAdjustedData('return')).length) {\n @for (r of refundableBreakdownRows(legAdjustedData('return')); track r.label) {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>{{ r.label }}</span>\n <strong>{{ fmt(r.value) }}</strong>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>Fare</span>\n <strong>{{ fmt(legRefundPool('return')) }}</strong>\n </div>\n }\n\n <!-- hide addon note new CR from CX -->\n <!-- @if (hasRefundableAddonNote(legAdjustedData('return'))) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--neutral\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your add-on service/s refund will be processed separately by our Customer Service team shortly.</span>\n </div>\n } -->\n\n @if (legDeductions('return').length && !isCreditShell()) {\n <div class=\"sbd-cancel__refund-card-divider\"></div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--muted\">Not Refunded - Deductions</span>\n @for (d of legDeductions('return'); track d.label) {\n <div class=\"sbd-cancel__refund-card-line\">\n <span>\n {{ d.label }}\n @if (d.badge) { <span class=\"sbd-cancel__tag\">{{ d.badge }}</span> }\n </span>\n <span class=\"sbd-cancel__refund-card-line--neg\">{{ fmtNeg(d.value) }}</span>\n </div>\n }\n }\n\n <div class=\"sbd-cancel__refund-card-divider sbd-cancel__refund-card-divider--dashed\"></div>\n <div class=\"sbd-cancel__refund-card-total\">\n <span>Return Total Refund</span>\n <strong>{{ fmt(legAdjustedData('return')?.totalRefundAmount) }}</strong>\n </div>\n\n @if (refundData()?.legInfo?.return?.isCreditShell && !hasGoldenGuaranteeGift()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F The refund for the return flight has been issued as an Airline Credit Shell.</span>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>This leg is not eligible for a refund.</span>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n\n <!-- Instant refund notice -->\n @if (currentData()?.isRefundable) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--shield\">\n <i class=\"pi pi-shield\"></i>\n <span>\n @if (isNilRefund()) {\n We're sorry, as per airline policy, no refund applies because the cancellation fees equal or exceed your refundable fare amount.\n } @else {\n @if (isWalletOnlyRefund() || isLoyaltyOnlyRefund()) {\n Your refund is instant to the customer's almatar Wallet.\n } @else {\n Your refund is instant from our side, your bank may take up to 15 business days to reflect it.\n }\n }\n @if (!isNilRefund() && !isCreditShell()) {\n <strong>You can select refund option in the next step</strong>\n }\n </span>\n </div>\n }\n }\n\n </div>\n\n <!-- Footer -->\n <div class=\"sbd-cancel__footer\">\n @if (refundData()?.isRefundable) {\n <button pButton label=\"Keep booking\" styleClass=\"p-button-outlined p-button-secondary sbd-cancel__btn-keep\" (click)=\"closed.emit()\"></button>\n @if (currentData()?.isRefundable) {\n <button pButton\n styleClass=\"sbd-cancel__btn-primary\"\n [label]=\"isCreditShell() ? 'Continue Cancellation' : 'Select refund option'\"\n [disabled]=\"!canConfirm()\" (click)=\"requestCancel()\"></button>\n }\n } @else {\n <button pButton label=\"Close\" styleClass=\"p-button-outlined p-button-secondary\" (click)=\"closed.emit()\"></button>\n }\n </div>\n }\n\n <!-- \u2500\u2500 Result overlay: floating modal over the dimmed refund-method screen (scoped to this dialog, not the whole viewport) \u2500\u2500 -->\n @if (cancelResult()) {\n <div class=\"sbd-cancel__result-overlay\">\n <div class=\"sbd-cancel__result-backdrop\"></div>\n <div class=\"sbd-cancel__result-modal\">\n <div class=\"sbd-cancel__result-hero\">\n <span class=\"sbd-cancel__result-icon sbd-cancel__result-icon--green\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3 class=\"sbd-cancel__result-title\">{{ confirmIsNilRefund() ? 'Cancel Confirmed' : 'Refund Confirmed' }}</h3>\n </div>\n\n @for (r of confirmRefunds(); track r.label) {\n <div class=\"sbd-cancel__result-row\">\n <span class=\"sbd-cancel__method-icon\">\n <i class=\"pi\" [ngClass]=\"isWalletDestinationRow(r) ? 'pi-wallet' : 'pi-credit-card'\"></i>\n </span>\n <span class=\"sbd-cancel__result-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ r.label }}</span>\n @if (r.subRows?.length) {\n <span class=\"sbd-cancel__result-sub-rows\">\n @for (sub of r.subRows; track sub.label) {\n <span class=\"sbd-cancel__result-sub-row\">\n <span>{{ sub.label }}</span>\n <strong>{{ fmtResult(sub.value) }}</strong>\n </span>\n }\n </span>\n }\n <span class=\"sbd-cancel__method-badge\"\n [ngClass]=\"isWalletDestinationRow(r) ? 'sbd-cancel__method-badge--instant' : 'sbd-cancel__method-badge--days'\">\n {{ isWalletDestinationRow(r) ? 'Ready Now' : (r.key === 'totalCardRefundAmount' ? confirmCardBadgeText() : 'Up to 15 business days, bank policy') }}\n </span>\n @if (r.hasLoyaltyNote) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>External loyalty points are refunded to your almatar Wallet as permanent points and ready to use in your next booking.</span>\n </span>\n }\n </span>\n <strong class=\"sbd-cancel__result-amount\">{{ fmtResult(r.value) }}</strong>\n </div>\n }\n\n @if (confirmCreditShellNote()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F {{ confirmCreditShellNote() }}</span>\n </div>\n }\n\n <button pButton styleClass=\"sbd-cancel__btn-primary sbd-cancel__result-done\" label=\"Close\" (click)=\"closed.emit()\"></button>\n </div>\n </div>\n }\n\n </div>\n\n</p-dialog>\n\n<ng-template #madaLogo>\n <svg width=\"43\" height=\"15\" viewBox=\"0 0 43 15\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_sbd_mada)\">\n <path d=\"M18.1894 8.6543H0V14.9933H18.1894V8.6543Z\" fill=\"#84B740\" />\n <path d=\"M18.1894 0H0V6.34463H18.1894V0Z\" fill=\"#259BD6\" />\n <path\n d=\"M36.3779 13.7034L36.2969 13.7203C36.016 13.7768 35.9134 13.7994 35.7082 13.7994C35.233 13.7994 34.6713 13.5452 34.6713 12.3475C34.6713 11.7316 34.7685 10.9124 35.6542 10.9124H35.6596C35.8108 10.9237 35.9836 10.9407 36.3077 11.0424L36.3779 11.065V13.7034ZM36.5237 7.73164L36.3779 7.75989V9.97458L36.2483 9.93503L36.2105 9.92373C36.0647 9.87853 35.7298 9.77684 35.4058 9.77684C33.6344 9.77684 33.2617 11.178 33.2617 12.3531C33.2617 13.9633 34.1258 14.8898 35.6326 14.8898C36.2699 14.8898 36.7397 14.822 37.215 14.6582C37.6524 14.5113 37.8091 14.3023 37.8091 13.8559V7.5C37.3878 7.5791 36.9504 7.65819 36.5237 7.73164Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M41.651 13.7385L41.5754 13.7611L41.3053 13.8345C41.0515 13.9023 40.8247 13.9419 40.6519 13.9419C40.236 13.9419 39.9876 13.7272 39.9876 13.36C39.9876 13.1227 40.0902 12.7215 40.7707 12.7215H41.651V13.7385ZM41.0299 9.74414C40.4844 9.74414 39.9228 9.84584 39.2261 10.0718L38.7724 10.2131L38.9236 11.2865L39.3665 11.134C39.831 10.9758 40.4088 10.8741 40.8409 10.8741C41.0353 10.8741 41.6294 10.8741 41.6294 11.5464V11.8402H40.8031C39.2963 11.8402 38.5996 12.343 38.5996 13.4221C38.5996 14.343 39.2423 14.8967 40.3224 14.8967C40.6573 14.8967 41.1217 14.8289 41.5214 14.7272L41.543 14.7215L41.5646 14.7272L41.6996 14.7498C42.1208 14.8289 42.5583 14.908 42.9849 14.9927V11.4673C42.9849 10.3261 42.3261 9.74414 41.0299 9.74414Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M31.1527 13.7385L31.0771 13.7611L30.807 13.8345C30.5532 13.9023 30.3318 13.9419 30.1536 13.9419C29.7377 13.9419 29.4893 13.7272 29.4893 13.36C29.4893 13.1227 29.5919 12.7215 30.267 12.7215H31.1473L31.1527 13.7385ZM30.537 9.74414C29.9861 9.74414 29.4299 9.84584 28.7332 10.0718L28.2795 10.2131L28.4308 11.2865L28.8736 11.134C29.3381 10.9758 29.9159 10.8741 30.348 10.8741C30.5424 10.8741 31.1365 10.8741 31.1365 11.5464V11.8402H30.3102C28.8034 11.8402 28.1013 12.343 28.1013 13.4221C28.1013 14.343 28.744 14.8967 29.8295 14.8967C30.1644 14.8967 30.6288 14.8289 31.0285 14.7272L31.0501 14.7215L31.0717 14.7272L31.2013 14.7498C31.6279 14.8289 32.06 14.908 32.4866 14.9984V11.473C32.492 10.3204 31.8332 9.74414 30.537 9.74414Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M25.4701 9.7576C24.7842 9.7576 24.2172 9.99489 24.0065 10.0966L23.9525 10.1248L23.9039 10.0853C23.6123 9.86495 23.1856 9.75195 22.5916 9.75195C22.0677 9.75195 21.5762 9.83105 21.0416 9.99489C20.5825 10.1418 20.4043 10.3734 20.4043 10.8085V14.8367H21.8409V11.1135L21.9111 11.0909C22.2027 10.9892 22.3755 10.9723 22.543 10.9723C22.9588 10.9723 23.1694 11.2039 23.1694 11.6559V14.8423H24.5844V11.5938C24.5844 11.4017 24.5466 11.2887 24.5412 11.2661L24.4926 11.17L24.5898 11.1248C24.8058 11.0231 25.0435 10.9723 25.2919 10.9723C25.5781 10.9723 25.9184 11.0909 25.9184 11.6559V14.8423H27.3279V11.509C27.3279 10.3282 26.7231 9.7576 25.4701 9.7576Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M40.5866 4.13559C40.3759 4.13559 40.0249 4.113 39.7495 4.0565L39.6684 4.03955V1.86441C39.6684 1.68362 39.636 1.57062 39.6306 1.55367L39.5874 1.46328L39.6793 1.42373C39.7009 1.41243 39.7225 1.40678 39.7495 1.39548L39.7657 1.38418C39.7981 1.37288 39.8305 1.36158 39.8629 1.35028C39.8791 1.34463 39.8899 1.33898 39.9007 1.33898C40.2193 1.24859 40.511 1.25989 40.6406 1.24859H40.646C41.5263 1.24859 41.6289 2.0678 41.6289 2.68362C41.6235 3.88136 41.0564 4.13559 40.5866 4.13559ZM40.5812 0C40.5704 0 40.5542 0 40.5434 0C39.7171 0 38.8692 0.237288 38.5667 0.700565C38.4047 0.926554 38.3129 1.20904 38.3075 1.54237V3.78531C38.3075 3.9774 38.2697 4.05085 38.2643 4.0678L38.2157 4.16384H35.6072V2.60452H35.6018C35.5694 0.960452 34.6404 0.0564972 33.2957 0.0564972H33.1391H31.9833C31.9293 0.457627 31.8861 0.740113 31.8321 1.14124H33.1391C33.8249 1.14124 34.1868 1.75141 34.1868 2.68927V4.25989L34.095 4.20904C34.0788 4.20339 33.9654 4.16384 33.7871 4.16384H31.5297C31.4865 4.46328 31.4325 4.85311 31.373 5.24294H38.3129C38.5505 5.19209 38.8259 5.14689 39.0636 5.10735C39.4146 5.28814 40.0681 5.38418 40.5164 5.38418C42.0231 5.38418 43.0007 4.32768 43.0007 2.70057C42.9953 1.0904 42.0501 0.0338983 40.5812 0Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M28.4189 5.90821H28.4837C29.9905 5.90821 30.6925 5.38844 30.6925 4.10595C30.6925 3.18505 30.0499 2.45059 28.9697 2.45059H27.5818C27.1659 2.45059 26.9175 2.202 26.9175 1.78392C26.9175 1.50143 27.0201 1.15115 27.7006 1.15115H30.7357C30.8006 0.738723 30.833 0.478836 30.8924 0.0664062H27.7384C26.2694 0.0664062 25.5295 0.710474 25.5295 1.78392C25.5295 2.84607 26.1722 3.39974 27.2523 3.39974H28.6403C29.0561 3.39974 29.3046 3.74437 29.3046 4.10595C29.3046 4.34324 29.202 4.83477 28.5269 4.83477H28.2947L23.8499 4.82347H23.0398C22.3539 4.82347 21.8733 4.41669 21.8733 3.47319V2.82347C21.8733 1.84042 22.2459 1.23025 23.0398 1.23025H24.3576C24.417 0.812169 24.4548 0.546632 24.5088 0.151152H22.867H22.7104C21.3656 0.151152 20.4367 1.09466 20.4043 2.73872V2.80087V3.47319C20.4367 5.11725 21.3656 5.90256 22.7104 5.90256H22.867H24.0227L26.4314 5.90821H27.868H28.4189Z\"\n fill=\"#747583\"\n />\n </g>\n <defs>\n <clipPath id=\"clip0_sbd_mada\">\n <rect width=\"43\" height=\"15\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n</ng-template>\n", styles: [":host ::ng-deep .sbd-cancel-dialog-wrapper{border-radius:16px;overflow:hidden;box-shadow:0 24px 60px #0f172a38}:host ::ng-deep .sbd-cancel-dialog-wrapper .p-dialog-content{padding:0;border-radius:16px;overflow-y:auto;overflow-x:hidden}.sbd-cancel{font-family:inherit;border-radius:16px;overflow:visible;position:relative}.sbd-cancel__loading{padding:24px}.sbd-cancel__loading-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.sbd-cancel__loading-rows{display:flex;flex-direction:column;gap:10px;margin-top:20px}.sbd-cancel__loading-row{display:flex;justify-content:space-between}.sbd-cancel__are-you-sure{padding:36px 24px 28px;display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center;border-top:1px solid #e2e8f0}.sbd-cancel__ays-icon{width:56px;height:56px;border-radius:50%;background:#fff7ed;border:2px solid #fed7aa;display:flex;align-items:center;justify-content:center}.sbd-cancel__ays-icon .pi{font-size:24px;color:#f97316}.sbd-cancel__ays-icon--warn{background:#fef2f2;border-color:#fecaca}.sbd-cancel__ays-icon--warn .pi{color:#ef4444}.sbd-cancel__ays-hint{font-size:13px;color:#64748b;min-height:20px;animation:sbd-hint-fade .35s ease-out}.sbd-cancel__ays-dots{display:flex;gap:6px}.sbd-cancel__ays-dots span{width:7px;height:7px;border-radius:50%;background:#f97316;opacity:.3;animation:sbd-dot-pulse 1.2s ease-in-out infinite}.sbd-cancel__ays-dots span:nth-child(2){animation-delay:.2s}.sbd-cancel__ays-dots span:nth-child(3){animation-delay:.4s}@keyframes sbd-hint-fade{0%{opacity:0;transform:translateY(5px)}to{opacity:1;transform:translateY(0)}}@keyframes sbd-dot-pulse{0%,to{opacity:.3;transform:scale(1)}50%{opacity:1;transform:scale(1.4)}}.sbd-cancel__header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid #e2e8f0;background:#f8fafc}.sbd-cancel__header-left{display:flex;align-items:center;gap:10px}.sbd-cancel__header-icon{font-size:18px;color:#475569}.sbd-cancel__header-title{font-size:15px;font-weight:700;color:#1e2e4a}.sbd-cancel__header--stack{align-items:flex-start}.sbd-cancel__header-titles{display:flex;flex-direction:column;gap:2px}.sbd-cancel__header-sub{font-size:12.5px;font-weight:600;color:#94a3b8;font-variant-numeric:tabular-nums}.sbd-cancel__badge{font-size:11.5px;font-weight:700;border-radius:20px;padding:3px 12px;letter-spacing:.03em;width:max-content;text-transform:uppercase}.sbd-cancel__badge--green{background:#dcfce7;color:#166534}.sbd-cancel__badge--red{background:#fee2e2;color:#991b1b}.sbd-cancel__badge--orange{background:#fff7ed;color:#9a3412}.sbd-cancel__badge--outline{background:transparent;box-shadow:inset 0 0 0 1.5px currentColor;padding:4px 14px}.sbd-cancel__badge--outline.sbd-cancel__badge--green{color:#16a34a}.sbd-cancel__badge--outline.sbd-cancel__badge--red{color:#dc2626}.sbd-cancel__badge--muted{background:#f8fafc;color:#64748b;box-shadow:inset 0 0 0 1px #e2e8f0}.sbd-cancel__close-btn{width:30px;height:30px;border-radius:8px;border:none;background:transparent;color:#64748b;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .15s,color .15s}.sbd-cancel__close-btn .pi{font-size:14px}.sbd-cancel__close-btn:hover{background:#e2e8f0;color:#1e2e4a}.sbd-cancel__close-btn--floating{position:absolute;top:12px;inset-inline-end:12px}.sbd-cancel__summary{background:#f8fafc;border:1px solid #e2e8f0;border-radius:12px;padding:14px 16px;display:flex;flex-direction:column;gap:10px}.sbd-cancel__summary-row{display:flex;align-items:center;justify-content:space-between;font-size:13.5px}.sbd-cancel__summary-row strong{font-size:15px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__summary-row--refund .sbd-cancel__summary-label,.sbd-cancel__summary-row--refund strong{color:#16a34a}.sbd-cancel__summary-row--toggle{cursor:pointer}.sbd-cancel__summary-label{display:inline-flex;align-items:center;gap:8px;font-weight:600;color:#475569}.sbd-cancel__summary-label .pi{font-size:13px}.sbd-cancel__summary-value{display:flex;align-items:center;gap:4px}.sbd-cancel__summary-breakdown{display:flex;flex-direction:column;gap:6px;padding:2px 0 2px 22px}.sbd-cancel__summary-breakdown-row{display:flex;align-items:center;justify-content:space-between;font-size:12.5px;color:#64748b}.sbd-cancel__summary-breakdown-row span:last-child{font-variant-numeric:tabular-nums;font-weight:600;color:#475569}.sbd-cancel__section-title{font-size:14px;font-weight:700;color:#1e2e4a}.sbd-cancel__refund-card{border:1px solid #e2e8f0;border-radius:12px;padding:16px;display:flex;flex-direction:column;gap:4px}.sbd-cancel__refund-card-row{display:flex;align-items:center;justify-content:space-between;margin-top:10px;font-size:14px}.sbd-cancel__refund-card-row span{color:#334155;font-weight:600}.sbd-cancel__refund-card-row strong{color:#1e2e4a;font-weight:700;font-variant-numeric:tabular-nums}.sbd-cancel__refund-card-divider{border-top:1px solid #e2e8f0;margin:10px 0}.sbd-cancel__refund-card-divider--dashed{border-top-style:dashed}.sbd-cancel__refund-card-line{display:flex;align-items:center;justify-content:space-between;padding:5px 0;font-size:13px}.sbd-cancel__refund-card-line span:first-child{color:#64748b;display:inline-flex;align-items:center}.sbd-cancel__refund-card-line--neg{color:#64748b;font-weight:600;font-variant-numeric:tabular-nums}.sbd-cancel__refund-card-total{display:flex;align-items:center;justify-content:space-between}.sbd-cancel__refund-card-total span{font-size:14.5px;font-weight:700;color:#1e2e4a}.sbd-cancel__refund-card-total strong{font-size:17px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__btn-keep{flex:1 1 0}.sbd-cancel__btn-primary{flex:1 1 0;background:#6d4aff!important;border-color:#6d4aff!important;color:#fff!important}.sbd-cancel__btn-primary:hover:not(:disabled){background:#5c3ce6!important;border-color:#5c3ce6!important}.sbd-cancel__btn-primary:disabled{opacity:.5}.sbd-cancel__paid{display:flex;align-items:center;justify-content:space-between;margin:0 -20px;padding:14px 20px;border-radius:0;background:#f1f0fb;border-top:1px solid #e7e5f7;border-bottom:1px solid #e7e5f7}.sbd-cancel__paid span{font-size:13.5px;font-weight:600;color:#4b4670}.sbd-cancel__paid strong{font-size:18px;font-weight:800;color:#2b2747;font-variant-numeric:tabular-nums;letter-spacing:.01em}.sbd-cancel__group{display:flex;flex-direction:column}.sbd-cancel__group-label{font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.07em;margin-bottom:2px}.sbd-cancel__group-label--deduct{color:#e05656}.sbd-cancel__group-label--refund{color:#16a34a}.sbd-cancel__line{display:flex;justify-content:space-between;align-items:center;padding:11px 0;font-size:13.5px;border-bottom:1px dashed #e5e7eb}.sbd-cancel__line:last-child{border-bottom:none}.sbd-cancel__line-label{display:inline-flex;align-items:center;color:#334155}.sbd-cancel__line-val{font-weight:700;font-variant-numeric:tabular-nums}.sbd-cancel__line-val--neg{color:#dc2626}.sbd-cancel__line-val--pos{color:#16a34a}.sbd-cancel__tag{margin-left:8px;font-size:10px;font-weight:700;line-height:1;padding:3px 8px;border-radius:6px;background:#ede9fe;color:#6d28d9;letter-spacing:.02em}.sbd-cancel__total-deduct{display:flex;align-items:center;justify-content:space-between;padding:13px 16px;border-radius:10px;background:#fdf2f2;border:1px solid #f6c9c9}.sbd-cancel__total-deduct span{font-size:14px;font-weight:700;color:#b3344a}.sbd-cancel__total-deduct strong{font-size:15px;font-weight:800;color:#dc2626;font-variant-numeric:tabular-nums}.sbd-cancel__calc{display:flex;align-items:center;gap:12px;margin:2px 0;color:#94a3b8;font-size:13px;font-variant-numeric:tabular-nums}.sbd-cancel__calc:before,.sbd-cancel__calc:after{content:\"\";flex:1;height:1px;background:#e5e7eb}.sbd-cancel__refund-total{display:flex;align-items:center;justify-content:space-between}.sbd-cancel__refund-total span{font-size:16px;font-weight:800;color:#1e2e4a}.sbd-cancel__refund-total strong{font-size:26px;font-weight:800;color:#16a34a;font-variant-numeric:tabular-nums;letter-spacing:.01em}.sbd-cancel__formula{text-align:center;padding:14px 16px;border-radius:10px;background:#1f2438;color:#f1f5f9;font-family:SFMono-Regular,ui-monospace,Menlo,Consolas,monospace;font-size:14px;font-weight:600;letter-spacing:.04em;font-variant-numeric:tabular-nums}.sbd-cancel__discrepancy{display:flex;align-items:flex-start;gap:10px;padding:11px 13px;border-radius:8px;font-size:12.5px;line-height:1.45;background:#fffbeb;border:1px solid #fde68a;color:#92400e}.sbd-cancel__discrepancy i{flex-shrink:0;margin-top:1px;font-size:14px;color:#d97706}.sbd-cancel__body{padding:16px 20px;display:flex;flex-direction:column;gap:12px}.sbd-cancel__leg-card{width:100%;border-radius:12px;border:1px solid #e2e8f0;background:#fff;overflow:hidden}.sbd-cancel__leg-card-header{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:14px 16px;cursor:pointer}.sbd-cancel__leg-checkbox{display:flex;align-items:center;gap:10px;font-size:13.5px;font-weight:700;color:#1e2e4a;cursor:pointer}.sbd-cancel__leg-checkbox input[type=checkbox]{width:17px;height:17px;accent-color:#6d4aff;cursor:pointer}.sbd-cancel__leg-chevron{flex-shrink:0;width:26px;height:26px;display:flex;align-items:center;justify-content:center;border:none;background:transparent;color:#64748b;cursor:pointer;transition:transform .15s}.sbd-cancel__leg-chevron i{font-size:13px}.sbd-cancel__leg-chevron--collapsed{transform:rotate(180deg)}.sbd-cancel__leg-card-body{display:flex;flex-direction:column;gap:4px;padding:0 16px 16px}.sbd-cancel__leg-card-body--excluded{opacity:.5}.sbd-cancel__notice{display:flex;align-items:flex-start;gap:10px;padding:10px 12px;border-radius:8px;font-size:12.5px}.sbd-cancel__notice i{flex-shrink:0;margin-top:1px;font-size:14px}.sbd-cancel__notice p{margin:2px 0 0;font-size:12px;opacity:.8}.sbd-cancel__notice strong{display:block;font-weight:700}.sbd-cancel__notice--warning{background:#fff7ed;border:1px solid #fed7aa;color:#9a3412}.sbd-cancel__notice--warning i{color:#f97316}.sbd-cancel__notice--info{background:#eff6ff;border:1px solid #bfdbfe;color:#1e40af}.sbd-cancel__notice--info i{color:#3b82f6}.sbd-cancel__notice--neutral{background:#f7f7f8;border:1px solid #e5e7eb;color:#111827}.sbd-cancel__notice--neutral i{color:#111827}.sbd-cancel__notice--tip{background:#f0fdf4;border:1px solid #bbf7d0;color:#14532d}.sbd-cancel__notice--tip i{color:#22c55e}.sbd-cancel__notice--success{background:#f0fdf4;border:1px solid #bbf7d0;color:#15803c}.sbd-cancel__notice--success i{color:#16a34a}.sbd-cancel__notice--credit{background:#faf5ff;border:1px solid #e9d5ff;color:#5b21b6;font-size:12px}.sbd-cancel__notice--credit i{color:#a855f7}.sbd-cancel__notice--shield{background:#eff6ff;border:1px solid #bfdbfe;color:#1e40af}.sbd-cancel__notice--shield strong{display:inline;font-weight:700}.sbd-cancel__notice--shield i{color:#3b82f6}.sbd-cancel__source-selector{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:4px 0}.sbd-cancel__source-label{font-size:11px;font-weight:700;color:#94a3b8;text-transform:uppercase;letter-spacing:.06em;white-space:nowrap;margin-right:2px}.sbd-cancel__source-chip{font-size:12px;font-weight:600;padding:4px 14px;border-radius:20px;border:1.5px solid #e2e8f0;background:#f8fafc;color:#475569;cursor:pointer;transition:border-color .15s,color .15s,background .15s;display:inline-flex;align-items:center}.sbd-cancel__source-chip:hover{border-color:#94a3b8;color:#475569;background:#f1f5f9}.sbd-cancel__source-chip--active{background:#eff6ff;color:#1d4ed8;border-color:#93c5fd}.sbd-cancel__source-chip--active:hover{background:#dbeafe;color:#1d4ed8;border-color:#93c5fd}.sbd-cancel__source-chip--no-refund{border-color:#fecaca;color:#b91c1c;background:#fff5f5}.sbd-cancel__source-chip--no-refund:hover{border-color:#fca5a5;background:#fee2e2;color:#b91c1c}.sbd-cancel__source-chip--active.sbd-cancel__source-chip--no-refund{background:#fee2e2;color:#991b1b;border-color:#fca5a5}.sbd-cancel__source-chip--active.sbd-cancel__source-chip--no-refund:hover{background:#fecaca}.sbd-cancel__footer{display:flex;justify-content:flex-end;gap:10px;align-items:stretch;padding:14px 20px;border-top:1px solid #e2e8f0;background:#fff}.sbd-cancel__btn-danger-pill{flex:1 1 0;border-radius:999px!important;background:#fee2e2!important;border-color:#fee2e2!important;color:#dc2626!important;font-weight:700!important}.sbd-cancel__btn-danger-pill:hover:not(:disabled){background:#fecaca!important;border-color:#fecaca!important}.sbd-cancel__btn-danger-pill:disabled{opacity:.5}.sbd-cancel__method-header{display:flex;align-items:flex-start;gap:12px;padding:20px 20px 0}.sbd-cancel__method-close{flex-shrink:0;width:32px;height:32px;border-radius:50%;background:#f8fafc;border:none;color:#1e2e4a;display:flex;align-items:center;justify-content:center;cursor:pointer}.sbd-cancel__method-close .pi{font-size:13px}.sbd-cancel__method-close:hover{background:#e2e8f0}.sbd-cancel__method-header-text{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;text-align:center;margin-right:32px}.sbd-cancel__method-title{font-size:19px;font-weight:800;color:#1e2e4a;margin:0}.sbd-cancel__method-sub{font-size:12.5px;color:#94a3b8}.sbd-cancel__method-body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:14px}.sbd-cancel__select-leg-body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:12px}.sbd-cancel__leg-select-card{position:relative;border:1.5px solid #e2e8f0;border-radius:16px;padding:16px 16px 16px 48px;transition:border-color .15s}.sbd-cancel__leg-select-card--selected:not(.sbd-cancel__leg-select-card--frozen){border-color:#6d4aff}.sbd-cancel__leg-select-card--disabled{opacity:.7}.sbd-cancel__leg-select-card--frozen{opacity:.6;border-color:#e2e8f0}.sbd-cancel__leg-select-lock{position:absolute;top:16px;left:16px;width:22px;height:22px;display:flex;align-items:center;justify-content:center;font-size:14px;color:#94a3b8}.sbd-cancel__single-leg-note{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:12px;background:#eaf2ff;border:1px solid #b9d6ff;color:#1a5fd6;font-size:13px;line-height:1.5}.sbd-cancel__single-leg-note i{flex-shrink:0;margin-top:1px}.sbd-cancel__all-non-refundable-note{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:12px;background:#fdf3e3;border:1px solid #f3d9a4;color:#8a5a1e;font-size:13px;line-height:1.5}.sbd-cancel__all-non-refundable-note i{flex-shrink:0;margin-top:1px;color:#b98a3e}.sbd-cancel__leg-select-checkbox{position:absolute;top:16px;left:16px;width:22px;height:22px;cursor:pointer}.sbd-cancel__leg-select-checkbox input{position:absolute;inset:0;opacity:0;margin:0;cursor:pointer}.sbd-cancel__leg-select-checkbox input:disabled{cursor:not-allowed}.sbd-cancel__leg-select-icon{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:6px;border:1.5px solid #cbd5e1;background:#fff;color:#fff;font-size:12px}input:checked+.sbd-cancel__leg-select-icon{background:#6d4aff;border-color:#6d4aff}input:disabled+.sbd-cancel__leg-select-icon{background:#f1f5f9;border-color:#e2e8f0}.sbd-cancel__leg-select-content{display:flex;flex-direction:column;gap:8px}.sbd-cancel__leg-select-top{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.sbd-cancel__leg-select-name{font-size:15px;font-weight:700;color:#1e2e4a}.sbd-cancel__leg-select-date{font-size:13px;color:#64748b;margin-top:2px}.sbd-cancel__leg-select-times{display:flex;align-items:center;gap:8px}.sbd-cancel__leg-select-time{font-size:18px;font-weight:700;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__leg-select-line{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;gap:2px;padding:0 16px 0 8px}.sbd-cancel__leg-select-line:before{content:\"\";position:absolute;left:0;right:14px;top:50%;height:2px;background:#cbd5e1;z-index:1}.sbd-cancel__leg-select-line-stops{font-size:12px;color:#64748b}.sbd-cancel__leg-select-line-dur{font-size:11px;color:#94a3b8}.sbd-cancel__leg-select-line-arrow{position:absolute;right:4px;top:51%;transform:translateY(-50%);font-size:11px;color:#64748b}.sbd-cancel__leg-select-footer{display:flex;align-items:center;gap:8px}.sbd-cancel__leg-select-airline{font-size:12.5px;color:#64748b}.sbd-cancel__leg-select-operated-by{font-size:12px;color:#94a3b8}.sbd-cancel__leg-select-chevron{font-size:12px;color:#94a3b8;margin-inline-start:auto}.sbd-cancel__leg-select-hint{text-align:center;padding:8px 20px 0;font-size:13px;color:#94a3b8}.sbd-cancel__leg-select-notice{display:flex;align-items:flex-start;gap:8px;padding:10px 12px;border-radius:10px;background:#fdf1e0;color:#6b4a16;font-size:12.5px;line-height:1.4}.sbd-cancel__leg-select-notice i{flex-shrink:0;margin-top:1px;color:#b98a3e}.sbd-cancel__method-amount{display:flex;align-items:center;justify-content:space-between}.sbd-cancel__method-amount span{font-size:14px;color:#1e2e4a}.sbd-cancel__method-amount strong{font-size:22px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__method-option{display:flex;align-items:flex-start;gap:12px;width:100%;text-align:left;padding:16px;border-radius:16px;border:1.5px solid #e2e8f0;background:#fff;cursor:pointer;transition:border-color .15s,box-shadow .15s}.sbd-cancel__method-option--active{border-color:#6d4aff;box-shadow:0 0 0 1px #6d4aff}.sbd-cancel__method-option:disabled{opacity:.5;cursor:not-allowed}.sbd-cancel__method-icon{flex-shrink:0;width:44px;height:44px;border-radius:10px;display:flex;align-items:center;justify-content:center;border:1px solid #e2e8f0;color:#1e2e4a}.sbd-cancel__method-icon .pi{font-size:16px}.sbd-cancel__method-body-text{flex:1;display:flex;flex-direction:column;align-items:flex-start;gap:4px}.sbd-cancel__method-name{font-size:16px;font-weight:700;color:#1e2e4a;display:inline-flex;align-items:center;gap:6px}.sbd-cancel__method-desc{font-size:13px;color:#64748b}.sbd-cancel__method-badge{display:inline-flex;align-items:center;gap:5px;margin-top:4px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;padding:4px 10px;border-radius:20px}.sbd-cancel__method-badge svg{flex-shrink:0}.sbd-cancel__method-badge--instant{background:#dcfce7;color:#166534}.sbd-cancel__method-badge--days,.sbd-cancel__method-badge--loyalty{background:#eff6ff;color:#1e40af}.sbd-cancel__option-end{flex-shrink:0;display:flex;align-items:center;gap:8px}.sbd-cancel__method-radio{flex-shrink:0;width:18px;height:18px;margin-top:2px;border-radius:50%;border:2px solid #7c3aed;position:relative}.sbd-cancel__method-option--active .sbd-cancel__method-radio{border-color:#6d4aff}.sbd-cancel__method-option--active .sbd-cancel__method-radio:after{content:\"\";position:absolute;inset:3px;border-radius:50%;background:#6d4aff}.sbd-cancel__method-option--split{flex-wrap:wrap}.sbd-cancel__method-split-total{flex-shrink:0;font-size:16px;font-weight:700;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__method-split-breakdown{flex-basis:100%;display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;margin-top:12px;padding-top:12px;border-top:1px solid #e2e8f0}.sbd-cancel__method-split-row{flex:1 1 auto;display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;font-size:14px;color:#1e2e4a}.sbd-cancel__method-split-row strong{font-weight:700;font-variant-numeric:tabular-nums}.sbd-cancel__method-split-label{color:#64748b;display:inline-flex;align-items:center;gap:6px}.sbd-cancel__mada-logo{display:inline-flex;align-items:center;flex-shrink:0}.sbd-cancel__mada-logo svg{display:block}.sbd-cancel__result-hero{display:flex;flex-direction:column;align-items:center;gap:18px;padding:28px 0 8px}.sbd-cancel__result-icon{width:84px;height:84px;border-radius:50%;display:flex;align-items:center;justify-content:center}.sbd-cancel__result-icon .pi{font-size:30px;color:#fff}.sbd-cancel__result-icon--green{background:#4ade80}.sbd-cancel__result-icon--orange{background:#fb923c}.sbd-cancel__result-title{font-size:19px;font-weight:800;color:#1e2e4a;margin:0;text-align:center}.sbd-cancel__result-row{display:flex;align-items:flex-start;gap:12px;width:100%;padding:12px 14px;border-radius:14px;background:#f8fafc}.sbd-cancel__result-body-text{flex:1;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:5px}.sbd-cancel__result-body-text .sbd-cancel__method-badge{text-transform:none;letter-spacing:normal;line-height:1.35;white-space:normal}.sbd-cancel__result-sub-rows{display:flex;flex-direction:column;gap:2px;width:100%}.sbd-cancel__result-sub-row{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;font-size:12.5px;color:#64748b}.sbd-cancel__result-sub-row strong{font-weight:700;color:#64748b;font-variant-numeric:tabular-nums}.sbd-cancel__result-amount{font-size:16px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums;white-space:nowrap}.sbd-cancel__result-overlay{position:absolute;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:24px}.sbd-cancel__result-backdrop{position:absolute;inset:0;background:#0000008c}.sbd-cancel__result-modal{position:relative;width:100%;max-width:400px;max-height:90%;overflow-y:auto;display:flex;flex-direction:column;gap:16px;padding:24px 20px;border-radius:20px;background:#fff;box-shadow:0 24px 60px #00000059}.sbd-cancel__result-done{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: DialogModule }, { kind: "component", type: i1.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
|
1436
|
+
}
|
|
1437
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdCancelDialogComponent, decorators: [{
|
|
1438
|
+
type: Component,
|
|
1439
|
+
args: [{ selector: 'app-sbd-cancel-dialog', standalone: true, imports: [DialogModule, ButtonModule, SkeletonModule, NgTemplateOutlet, NgClass], template: "<p-dialog [visible]=\"visible()\" (visibleChange)=\"$event ? null : closed.emit()\"\n [modal]=\"true\" [blockScroll]=\"true\" [draggable]=\"false\" [resizable]=\"false\"\n [showHeader]=\"false\" [style]=\"{ width: '560px', padding: '0' }\" styleClass=\"sbd-cancel-dialog-wrapper\">\n\n <div class=\"sbd-cancel\">\n\n <!-- Loading refund details \u2014 shows cycling hints -->\n @if (loading()) {\n <div class=\"sbd-cancel__are-you-sure\">\n <button type=\"button\" class=\"sbd-cancel__close-btn sbd-cancel__close-btn--floating\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-cancel__ays-icon\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n </div>\n @for (h of [cancelHint()]; track h) {\n <div class=\"sbd-cancel__ays-hint\">{{ h }}</div>\n }\n <div class=\"sbd-cancel__ays-dots\">\n <span></span><span></span><span></span>\n </div>\n </div>\n }\n\n <!-- Select leg \u2014 shown once the refund preview has fully loaded, before the\n refund breakdown, for round-trip bookings the backend hasn't already\n restricted to a single leg. Same card design as almatar-b2c's\n select-leg screen (checkbox overlay, refundable badge, disclaimer). -->\n @else if (step() === 'select-leg') {\n <div class=\"sbd-cancel__method-header\">\n <button type=\"button\" class=\"sbd-cancel__method-close\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-cancel__method-header-text\">\n <h3 class=\"sbd-cancel__method-title\">Select Leg to Cancel</h3>\n <span class=\"sbd-cancel__method-sub\">Booking ID #{{ bookingId() }}</span>\n </div>\n </div>\n\n <div class=\"sbd-cancel__select-leg-body\">\n @if (forcedLegType(); as forced) {\n <div class=\"sbd-cancel__single-leg-note\">\n <i class=\"pi pi-info-circle\"></i>\n <span>This airline doesn't allow cancelling a single flight \u2014 {{ itineraryLeg(forced)?.from }} to {{ itineraryLeg(forced)?.to }} will be included automatically.</span>\n </div>\n }\n @if (allLegsNonRefundable()) {\n <div class=\"sbd-cancel__all-non-refundable-note\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <span>Sorry, we're unable to provide a refund for this booking, as both flights are non-refundable based on airline rules.</span>\n </div>\n }\n <!-- Onward -->\n <div class=\"sbd-cancel__leg-select-card\"\n [ngClass]=\"{\n 'sbd-cancel__leg-select-card--selected': onwardChecked() && onwardRefundable(),\n 'sbd-cancel__leg-select-card--disabled': !onwardRefundable(),\n 'sbd-cancel__leg-select-card--frozen': forcedLegType() === 'onward'\n }\">\n @if (forcedLegType() !== 'onward') {\n <label class=\"sbd-cancel__leg-select-checkbox\">\n <input type=\"checkbox\" [checked]=\"onwardChecked()\" [disabled]=\"!onwardRefundable()\"\n (change)=\"toggleLeg('onward')\" />\n <span class=\"sbd-cancel__leg-select-icon\"><i class=\"pi pi-check\"></i></span>\n </label>\n } @else {\n <i class=\"pi pi-lock sbd-cancel__leg-select-lock\"></i>\n }\n <div class=\"sbd-cancel__leg-select-content\">\n @if (itineraryLeg('onward'); as leg) {\n <div class=\"sbd-cancel__leg-select-top\">\n <div>\n <span class=\"sbd-cancel__leg-select-name\">{{ leg.from }} to {{ leg.to }}</span>\n <div class=\"sbd-cancel__leg-select-date\">{{ fmtShortDate(leg.depTime) }}</div>\n </div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"onwardRefundable() && forcedLegType() !== 'onward' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ onwardRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n <div class=\"sbd-cancel__leg-select-times\">\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.depTime) }}</span>\n <span class=\"sbd-cancel__leg-select-line\">\n <span class=\"sbd-cancel__leg-select-line-stops\">{{ leg.stops.length > 0 ? (leg.stops.length + ' stop' + (leg.stops.length > 1 ? 's' : '')) : 'Direct' }}</span>\n @if (fmtMins(leg.totalMinutes)) { <span class=\"sbd-cancel__leg-select-line-dur\">{{ fmtMins(leg.totalMinutes) }}</span> }\n <i class=\"pi pi-arrow-right sbd-cancel__leg-select-line-arrow\"></i>\n </span>\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.arrTime) }}</span>\n </div>\n @if (leg.airlineName || leg.cabin) {\n <span class=\"sbd-cancel__leg-select-airline\">\n {{ leg.airlineName }}{{ leg.airlineName && leg.cabin ? ' \u00B7 ' : '' }}{{ leg.cabin }}\n </span>\n }\n <div class=\"sbd-cancel__leg-select-footer\">\n @if (leg.operatedBy.length) {\n <span class=\"sbd-cancel__leg-select-operated-by\">Operated by {{ leg.operatedBy.join(', ') }}</span>\n }\n <!-- <i class=\"pi pi-chevron-down sbd-cancel__leg-select-chevron\"></i> -->\n </div>\n } @else {\n <div class=\"sbd-cancel__leg-select-top\">\n <span class=\"sbd-cancel__leg-select-name\">Onward</span>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"onwardRefundable() && forcedLegType() !== 'onward' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ onwardRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n }\n @if (!onwardRefundable()) {\n <div class=\"sbd-cancel__leg-select-notice\">\n <i class=\"pi pi-info-circle\"></i>\n <span>This flight type doesn't allow refunds on cancellation, based on the airline's fare rules.</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Return -->\n <div class=\"sbd-cancel__leg-select-card\"\n [ngClass]=\"{\n 'sbd-cancel__leg-select-card--selected': returnChecked() && returnRefundable(),\n 'sbd-cancel__leg-select-card--disabled': !returnRefundable(),\n 'sbd-cancel__leg-select-card--frozen': forcedLegType() === 'return'\n }\">\n @if (forcedLegType() !== 'return') {\n <label class=\"sbd-cancel__leg-select-checkbox\">\n <input type=\"checkbox\" [checked]=\"returnChecked()\" [disabled]=\"!returnRefundable()\"\n (change)=\"toggleLeg('return')\" />\n <span class=\"sbd-cancel__leg-select-icon\"><i class=\"pi pi-check\"></i></span>\n </label>\n } @else {\n <i class=\"pi pi-lock sbd-cancel__leg-select-lock\"></i>\n }\n <div class=\"sbd-cancel__leg-select-content\">\n @if (itineraryLeg('return'); as leg) {\n <div class=\"sbd-cancel__leg-select-top\">\n <div>\n <span class=\"sbd-cancel__leg-select-name\">{{ leg.from }} to {{ leg.to }}</span>\n <div class=\"sbd-cancel__leg-select-date\">{{ fmtShortDate(leg.depTime) }}</div>\n </div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"returnRefundable() && forcedLegType() !== 'return' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ returnRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n <div class=\"sbd-cancel__leg-select-times\">\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.depTime) }}</span>\n <span class=\"sbd-cancel__leg-select-line\">\n <span class=\"sbd-cancel__leg-select-line-stops\">{{ leg.stops.length > 0 ? (leg.stops.length + ' stop' + (leg.stops.length > 1 ? 's' : '')) : 'Direct' }}</span>\n @if (fmtMins(leg.totalMinutes)) { <span class=\"sbd-cancel__leg-select-line-dur\">{{ fmtMins(leg.totalMinutes) }}</span> }\n <i class=\"pi pi-arrow-right sbd-cancel__leg-select-line-arrow\"></i>\n </span>\n <span class=\"sbd-cancel__leg-select-time\">{{ fmtTime(leg.arrTime) }}</span>\n </div>\n @if (leg.airlineName || leg.cabin) {\n <span class=\"sbd-cancel__leg-select-airline\">\n {{ leg.airlineName }}{{ leg.airlineName && leg.cabin ? ' \u00B7 ' : '' }}{{ leg.cabin }}\n </span>\n }\n <div class=\"sbd-cancel__leg-select-footer\">\n @if (leg.operatedBy.length) {\n <span class=\"sbd-cancel__leg-select-operated-by\">Operated by {{ leg.operatedBy.join(', ') }}</span>\n }\n <!-- <i class=\"pi pi-chevron-down sbd-cancel__leg-select-chevron\"></i> -->\n </div>\n } @else {\n <div class=\"sbd-cancel__leg-select-top\">\n <span class=\"sbd-cancel__leg-select-name\">Return</span>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"returnRefundable() && forcedLegType() !== 'return' ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--muted'\">\n {{ returnRefundable() ? 'Refundable' : 'Non-Refundable' }}\n </span>\n </div>\n }\n @if (!returnRefundable()) {\n <div class=\"sbd-cancel__leg-select-notice\">\n <i class=\"pi pi-info-circle\"></i>\n <span>This flight type doesn't allow refunds on cancellation, based on the airline's fare rules.</span>\n </div>\n }\n </div>\n </div>\n </div>\n\n @if (!allLegsNonRefundable() && !onwardChecked() && !returnChecked()) {\n <div class=\"sbd-cancel__leg-select-hint\">Select at least one flight to continue</div>\n }\n\n <div class=\"sbd-cancel__footer\">\n <button pButton\n styleClass=\"sbd-cancel__btn-primary\"\n label=\"Continue\"\n [disabled]=\"allLegsNonRefundable() || (!onwardChecked() && !returnChecked())\"\n (click)=\"step.set('details')\"></button>\n </div>\n }\n\n <!-- Refund method \u2014 replaces the old are-you-sure + radio picker.\n Stays mounted (dimmed) behind the result overlay once confirmed. -->\n @else if (confirming() || cancelResult()) {\n <div class=\"sbd-cancel__method-header\">\n <button type=\"button\" class=\"sbd-cancel__method-close\" (click)=\"confirming.set(false)\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-cancel__method-header-text\">\n <h3 class=\"sbd-cancel__method-title\">Refund Method</h3>\n <span class=\"sbd-cancel__method-sub\">Booking ID #{{ bookingId() }}</span>\n </div>\n </div>\n\n <div class=\"sbd-cancel__method-body\">\n <div class=\"sbd-cancel__method-amount\">\n <span>You will get back</span>\n <strong>{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n </div>\n\n @if (isCreditShell()) {\n <!-- Credit-shell refunds have exactly one destination \u2014 the airline\n credit shell \u2014 so show it as a read-only card, not a picker. -->\n <div class=\"sbd-cancel__method-option sbd-cancel__method-option--active\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ creditShellSupplierName() }} website credit</span>\n <span class=\"sbd-cancel__method-desc\">Your refund will be issued instantly by {{ creditShellSupplierName() }}.</span>\n <span class=\"sbd-cancel__method-badge sbd-cancel__method-badge--instant\">\n <svg width=\"12\" height=\"9\" viewBox=\"0 0 12 9\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.31818 0C8.42727 0 9.49093 0.440583 10.2752 1.22483C11.0594 2.00907 11.5 3.07273 11.5 4.18182C11.5 5.2909 11.0594 6.35457 10.2752 7.13881C9.49093 7.92305 8.42727 8.36364 7.31818 8.36364C6.20909 8.36364 5.14543 7.92305 4.36119 7.13881C3.57695 6.35457 3.13636 5.2909 3.13636 4.18182C3.13636 3.07273 3.57695 2.00907 4.36119 1.22483C5.14543 0.440583 6.20909 0 7.31818 0ZM7.31818 1.04545C6.48637 1.04545 5.68862 1.37589 5.10044 1.96407C4.51226 2.55226 4.18182 3.35 4.18182 4.18182C4.18182 5.01363 4.51226 5.81138 5.10044 6.39956C5.68862 6.98774 6.48637 7.31818 7.31818 7.31818C8.15 7.31818 8.94774 6.98774 9.53593 6.39956C10.1241 5.81138 10.4545 5.01363 10.4545 4.18182C10.4545 3.35 10.1241 2.55226 9.53593 1.96407C8.94774 1.37589 8.15 1.04545 7.31818 1.04545ZM6.79545 2.09091H7.57955V4.06682L8.7975 5.28477L8.24341 5.83886L6.79545 4.39091V2.09091ZM0.522727 7.31818C0.384091 7.31818 0.251134 7.26311 0.153103 7.16508C0.0550729 7.06705 0 6.93409 0 6.79545C0 6.65682 0.0550729 6.52386 0.153103 6.42583C0.251134 6.3278 0.384091 6.27273 0.522727 6.27273H2.52477C2.68682 6.64386 2.89591 6.99409 3.13636 7.31818H0.522727ZM1.04545 4.70455C0.906819 4.70455 0.773861 4.64947 0.67583 4.55144C0.5778 4.45341 0.522727 4.32045 0.522727 4.18182C0.522727 4.04318 0.5778 3.91022 0.67583 3.81219C0.773861 3.71416 0.906819 3.65909 1.04545 3.65909H2.11705L2.09091 4.18182L2.11705 4.70455H1.04545ZM1.56818 2.09091C1.42955 2.09091 1.29659 2.03584 1.19856 1.93781C1.10053 1.83978 1.04545 1.70682 1.04545 1.56818C1.04545 1.42955 1.10053 1.29659 1.19856 1.19856C1.29659 1.10053 1.42955 1.04545 1.56818 1.04545H3.13636C2.89591 1.36955 2.68682 1.71977 2.52477 2.09091H1.56818Z\"\n fill=\"#15803C\"\n />\n </svg>\n Instant\n </span>\n </span>\n </div>\n\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-info-circle\"></i>\n <span>\n Your refund will be issued as airline credit under the same PNR.\n It can be used only for future booking on {{ creditShellSupplierName() }} website.\n </span>\n </div>\n\n <!-- Refundable ancillaries (baggage, seats, \u2026) can independently be\n flagged credit-shell or not \u2014 each renders as its own card,\n matching either the credit-shell style above or the normal\n wallet style, both with the same nested note when credit-shell. -->\n @for (item of creditShellAncillaryItems(); track item.name) {\n <div class=\"sbd-cancel__method-option sbd-cancel__method-option--active\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">\n {{ item.isCreditShell ? (creditShellSupplierName() + ' website credit') : 'Almatar Wallet' }}\n \u2014 {{ item.name }}\n </span>\n <span class=\"sbd-cancel__method-desc\">\n @if (item.isCreditShell) {\n Your refund will be issued instantly by {{ creditShellSupplierName() }}.\n } @else {\n Usable for future bookings\n }\n </span>\n <span class=\"sbd-cancel__method-badge sbd-cancel__method-badge--instant\">\n <svg width=\"12\" height=\"9\" viewBox=\"0 0 12 9\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.31818 0C8.42727 0 9.49093 0.440583 10.2752 1.22483C11.0594 2.00907 11.5 3.07273 11.5 4.18182C11.5 5.2909 11.0594 6.35457 10.2752 7.13881C9.49093 7.92305 8.42727 8.36364 7.31818 8.36364C6.20909 8.36364 5.14543 7.92305 4.36119 7.13881C3.57695 6.35457 3.13636 5.2909 3.13636 4.18182C3.13636 3.07273 3.57695 2.00907 4.36119 1.22483C5.14543 0.440583 6.20909 0 7.31818 0ZM7.31818 1.04545C6.48637 1.04545 5.68862 1.37589 5.10044 1.96407C4.51226 2.55226 4.18182 3.35 4.18182 4.18182C4.18182 5.01363 4.51226 5.81138 5.10044 6.39956C5.68862 6.98774 6.48637 7.31818 7.31818 7.31818C8.15 7.31818 8.94774 6.98774 9.53593 6.39956C10.1241 5.81138 10.4545 5.01363 10.4545 4.18182C10.4545 3.35 10.1241 2.55226 9.53593 1.96407C8.94774 1.37589 8.15 1.04545 7.31818 1.04545ZM6.79545 2.09091H7.57955V4.06682L8.7975 5.28477L8.24341 5.83886L6.79545 4.39091V2.09091ZM0.522727 7.31818C0.384091 7.31818 0.251134 7.26311 0.153103 7.16508C0.0550729 7.06705 0 6.93409 0 6.79545C0 6.65682 0.0550729 6.52386 0.153103 6.42583C0.251134 6.3278 0.384091 6.27273 0.522727 6.27273H2.52477C2.68682 6.64386 2.89591 6.99409 3.13636 7.31818H0.522727ZM1.04545 4.70455C0.906819 4.70455 0.773861 4.64947 0.67583 4.55144C0.5778 4.45341 0.522727 4.32045 0.522727 4.18182C0.522727 4.04318 0.5778 3.91022 0.67583 3.81219C0.773861 3.71416 0.906819 3.65909 1.04545 3.65909H2.11705L2.09091 4.18182L2.11705 4.70455H1.04545ZM1.56818 2.09091C1.42955 2.09091 1.29659 2.03584 1.19856 1.93781C1.10053 1.83978 1.04545 1.70682 1.04545 1.56818C1.04545 1.42955 1.10053 1.29659 1.19856 1.19856C1.29659 1.10053 1.42955 1.04545 1.56818 1.04545H3.13636C2.89591 1.36955 2.68682 1.71977 2.52477 2.09091H1.56818Z\"\n fill=\"#15803C\"\n />\n </svg>\n Instant\n </span>\n @if (item.isCreditShell) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your refund will be issued as airline credit under the same PNR. It can be used only for future booking on {{ creditShellSupplierName() }} website.</span>\n </span>\n }\n </span>\n <strong>{{ fmt(item.amount) }}</strong>\n </div>\n }\n } @else {\n\n @if (isFullWalletRefundAllowed() || isWalletOnlyRefund() || isLoyaltyOnlyRefund()) {\n <button type=\"button\" class=\"sbd-cancel__method-option\"\n [ngClass]=\"{ 'sbd-cancel__method-option--active': preferredRefundMethod() === 'wallet' }\"\n (click)=\"preferredRefundMethod.set('wallet')\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ walletCardLabel() }}</span>\n <span class=\"sbd-cancel__method-desc\">Usable for future bookings</span>\n <span class=\"sbd-cancel__method-badge sbd-cancel__method-badge--instant\">\n <svg width=\"12\" height=\"9\" viewBox=\"0 0 12 9\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.31818 0C8.42727 0 9.49093 0.440583 10.2752 1.22483C11.0594 2.00907 11.5 3.07273 11.5 4.18182C11.5 5.2909 11.0594 6.35457 10.2752 7.13881C9.49093 7.92305 8.42727 8.36364 7.31818 8.36364C6.20909 8.36364 5.14543 7.92305 4.36119 7.13881C3.57695 6.35457 3.13636 5.2909 3.13636 4.18182C3.13636 3.07273 3.57695 2.00907 4.36119 1.22483C5.14543 0.440583 6.20909 0 7.31818 0ZM7.31818 1.04545C6.48637 1.04545 5.68862 1.37589 5.10044 1.96407C4.51226 2.55226 4.18182 3.35 4.18182 4.18182C4.18182 5.01363 4.51226 5.81138 5.10044 6.39956C5.68862 6.98774 6.48637 7.31818 7.31818 7.31818C8.15 7.31818 8.94774 6.98774 9.53593 6.39956C10.1241 5.81138 10.4545 5.01363 10.4545 4.18182C10.4545 3.35 10.1241 2.55226 9.53593 1.96407C8.94774 1.37589 8.15 1.04545 7.31818 1.04545ZM6.79545 2.09091H7.57955V4.06682L8.7975 5.28477L8.24341 5.83886L6.79545 4.39091V2.09091ZM0.522727 7.31818C0.384091 7.31818 0.251134 7.26311 0.153103 7.16508C0.0550729 7.06705 0 6.93409 0 6.79545C0 6.65682 0.0550729 6.52386 0.153103 6.42583C0.251134 6.3278 0.384091 6.27273 0.522727 6.27273H2.52477C2.68682 6.64386 2.89591 6.99409 3.13636 7.31818H0.522727ZM1.04545 4.70455C0.906819 4.70455 0.773861 4.64947 0.67583 4.55144C0.5778 4.45341 0.522727 4.32045 0.522727 4.18182C0.522727 4.04318 0.5778 3.91022 0.67583 3.81219C0.773861 3.71416 0.906819 3.65909 1.04545 3.65909H2.11705L2.09091 4.18182L2.11705 4.70455H1.04545ZM1.56818 2.09091C1.42955 2.09091 1.29659 2.03584 1.19856 1.93781C1.10053 1.83978 1.04545 1.70682 1.04545 1.56818C1.04545 1.42955 1.10053 1.29659 1.19856 1.19856C1.29659 1.10053 1.42955 1.04545 1.56818 1.04545H3.13636C2.89591 1.36955 2.68682 1.71977 2.52477 2.09091H1.56818Z\"\n fill=\"#15803C\"\n />\n </svg>\n Instant Refund\n </span>\n @if (hasLoyaltyPointsRefund() && !hasCashWalletRefund()) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>External loyalty points are refunded to your almatar Wallet as permanent points and ready to use in your next booking.</span>\n </span>\n }\n </span>\n <span class=\"sbd-cancel__method-radio\"></span>\n </button>\n }\n\n <!-- Original payment method \u2014 replaced with a \"Split Refund\" card whenever\n part of the refund is forced to the wallet (e.g. loyalty points used),\n since the total can't go 100% to the original payment method.\n Name/desc/badge/icon become gateway-specific for installment (Tamara,\n Tabby) and loyalty (Al Rajhi Mokafaa) payment methods. -->\n @if (!hasSplitRefund() && !isWalletOnlyRefund() && !isLoyaltyOnlyRefund()) {\n <button type=\"button\" class=\"sbd-cancel__method-option\"\n [ngClass]=\"{ 'sbd-cancel__method-option--active': preferredRefundMethod() === 'originalPaymentMethod' }\"\n (click)=\"preferredRefundMethod.set('originalPaymentMethod')\">\n <span class=\"sbd-cancel__method-icon\">\n <i class=\"pi\" [ngClass]=\"isSpecialGatewayMethod() ? 'pi-wallet' : 'pi-credit-card'\"></i>\n </span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ originalPaymentLabel() }}</span>\n <span class=\"sbd-cancel__method-desc\">\n @if (isInstallmentMethod()) {\n Returned to your {{ customerPaymentLabel() }} installment plan\n } @else if (isLoyaltyMethod()) {\n Refunded to your {{ customerPaymentLabel() }} account\n } @else {\n Returned to your original payment method\n }\n </span>\n <span class=\"sbd-cancel__method-badge\" [ngClass]=\"isLoyaltyMethod() ? 'sbd-cancel__method-badge--loyalty' : 'sbd-cancel__method-badge--days'\">\n @if (!isLoyaltyMethod()) {\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M3.30078 6.50195C3.20312 6.50195 3.12174 6.4694 3.05664 6.4043C2.99154 6.33919 2.95898 6.25781 2.95898 6.16016C2.95898 6.06576 2.99154 5.986 3.05664 5.9209C3.12174 5.85579 3.20312 5.82324 3.30078 5.82324H5.5127V2.86914C5.5127 2.77474 5.54525 2.69499 5.61035 2.62988C5.67546 2.56478 5.75521 2.53223 5.84961 2.53223C5.94727 2.53223 6.02865 2.56478 6.09375 2.62988C6.15885 2.69499 6.19141 2.77474 6.19141 2.86914V6.16016C6.19141 6.25781 6.15885 6.33919 6.09375 6.4043C6.02865 6.4694 5.94727 6.50195 5.84961 6.50195H3.30078ZM5.85449 10.9551C5.16764 10.9551 4.52311 10.8249 3.9209 10.5645C3.31868 10.3073 2.78971 9.95085 2.33398 9.49512C1.87826 9.03939 1.52018 8.51042 1.25977 7.9082C1.0026 7.30599 0.874023 6.66146 0.874023 5.97461C0.874023 5.28776 1.0026 4.64323 1.25977 4.04102C1.52018 3.4388 1.87826 2.90983 2.33398 2.4541C2.78971 1.99512 3.31868 1.63704 3.9209 1.37988C4.52311 1.12272 5.16764 0.994141 5.85449 0.994141C6.54134 0.994141 7.18587 1.12272 7.78809 1.37988C8.3903 1.63704 8.91927 1.99512 9.375 2.4541C9.83073 2.90983 10.1872 3.4388 10.4443 4.04102C10.7048 4.64323 10.835 5.28776 10.835 5.97461C10.835 6.66146 10.7048 7.30599 10.4443 7.9082C10.1872 8.51042 9.83073 9.03939 9.375 9.49512C8.91927 9.95085 8.3903 10.3073 7.78809 10.5645C7.18587 10.8249 6.54134 10.9551 5.85449 10.9551ZM5.85449 10.125C6.42741 10.125 6.96452 10.0176 7.46582 9.80273C7.96712 9.58789 8.4082 9.29004 8.78906 8.90918C9.16992 8.52832 9.46777 8.08724 9.68262 7.58594C9.89746 7.08464 10.0049 6.54753 10.0049 5.97461C10.0049 5.40169 9.89746 4.86458 9.68262 4.36328C9.46777 3.85872 9.16992 3.41764 8.78906 3.04004C8.4082 2.65918 7.96712 2.36133 7.46582 2.14648C6.96452 1.93164 6.42741 1.82422 5.85449 1.82422C5.28158 1.82422 4.74447 1.93164 4.24316 2.14648C3.74186 2.36133 3.30078 2.65918 2.91992 3.04004C2.53906 3.41764 2.24121 3.85872 2.02637 4.36328C1.81152 4.86458 1.7041 5.40169 1.7041 5.97461C1.7041 6.54753 1.81152 7.08464 2.02637 7.58594C2.24121 8.08724 2.53906 8.52832 2.91992 8.90918C3.30078 9.29004 3.74186 9.58789 4.24316 9.80273C4.74447 10.0176 5.28158 10.125 5.85449 10.125Z\"\n fill=\"#0B54C2\"\n />\n </svg>\n } @else {\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"#0B54C2\" stroke-width=\"1.2\" />\n <path d=\"M6 5.5v3M6 3.9v.01\" stroke=\"#0B54C2\" stroke-width=\"1.2\" stroke-linecap=\"round\" />\n </svg>\n }\n {{ cardBadgeText() }}\n </span>\n </span>\n <span class=\"sbd-cancel__option-end\">\n @if (isMadaMethod()) {\n <span class=\"sbd-cancel__mada-logo\" aria-hidden=\"true\">\n <ng-container *ngTemplateOutlet=\"madaLogo\"></ng-container>\n </span>\n }\n <span class=\"sbd-cancel__method-radio\"></span>\n </span>\n </button>\n }\n\n <!-- Split Refund -->\n @if (hasSplitRefund()) {\n <button type=\"button\" class=\"sbd-cancel__method-option sbd-cancel__method-option--split\"\n [ngClass]=\"{ 'sbd-cancel__method-option--active': preferredRefundMethod() === 'split' }\"\n (click)=\"preferredRefundMethod.set('split')\">\n <span class=\"sbd-cancel__method-icon\"><i class=\"pi pi-wallet\"></i></span>\n <span class=\"sbd-cancel__method-body-text\">\n <span class=\"sbd-cancel__method-name\">Split Refund</span>\n <span class=\"sbd-cancel__method-desc\">Returned to your original payment method</span>\n </span>\n <strong class=\"sbd-cancel__method-split-total\">{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n <span class=\"sbd-cancel__method-radio\"></span>\n\n <span class=\"sbd-cancel__method-split-breakdown\">\n @for (row of splitRefundRows(); track row.label) {\n <span class=\"sbd-cancel__method-split-row\">\n <span class=\"sbd-cancel__method-split-label\">\n {{ row.label }}\n @if (row.isMada) {\n <span class=\"sbd-cancel__mada-logo\" aria-hidden=\"true\">\n <ng-container *ngTemplateOutlet=\"madaLogo\"></ng-container>\n </span>\n }\n </span>\n <strong>{{ fmt(row.value) }}</strong>\n </span>\n <span class=\"sbd-cancel__method-badge\"\n [ngClass]=\"row.instant ? 'sbd-cancel__method-badge--instant' : (isLoyaltyMethod() ? 'sbd-cancel__method-badge--loyalty' : 'sbd-cancel__method-badge--days')\">\n {{ row.badgeText }}\n </span>\n @if (row.isLoyalty) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>External loyalty points are refunded to your almatar Wallet as permanent points and ready to use in your next booking.</span>\n </span>\n }\n }\n </span>\n </button>\n }\n }\n </div>\n\n <div class=\"sbd-cancel__footer\">\n <button pButton\n styleClass=\"sbd-cancel__btn-danger-pill\"\n [label]=\"cancelling() ? 'Cancelling...' : 'Confirm Cancellation'\"\n [disabled]=\"cancelling()\" (click)=\"confirm()\"></button>\n </div>\n }\n\n <!-- Main card -->\n @else if (refundData() && step() === 'details') {\n <!-- Card header -->\n <div class=\"sbd-cancel__header sbd-cancel__header--stack\">\n <div class=\"sbd-cancel__header-titles\">\n <span class=\"sbd-cancel__header-title\">Cancel Booking Request</span>\n <span class=\"sbd-cancel__header-sub\">#{{ refundData()?.bookingId ?? bookingId() }}</span>\n </div>\n <button type=\"button\" class=\"sbd-cancel__close-btn\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n\n <div class=\"sbd-cancel__body\">\n\n <!-- Non-refundable -->\n @if (!refundData()?.isRefundable) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <div>\n <strong>This booking is not eligible for a refund.</strong>\n @if (refundData()?.cause) {\n <p>{{ refundData()?.cause }}</p>\n } @else {\n <p>Please escalate to the relevant team for manual handling.</p>\n }\n </div>\n </div>\n }\n\n <!-- Refundable flow -->\n @else {\n\n <!-- Top summary: paid / get back -->\n <div class=\"sbd-cancel__summary\">\n <div class=\"sbd-cancel__summary-row\"\n [ngClass]=\"{ 'sbd-cancel__summary-row--toggle': hasPaidBreakdown() && !!adjustedData()?.totalWalletAmount }\"\n (click)=\"hasPaidBreakdown() && !!adjustedData()?.totalWalletAmount && togglePaidSummary()\">\n <span class=\"sbd-cancel__summary-label\"><i class=\"pi pi-wallet\"></i> Total paid</span>\n <span class=\"sbd-cancel__summary-value\">\n <strong>{{ fmt(adjustedData()?.originalAmount) }}</strong>\n @if (hasPaidBreakdown() && !!adjustedData()?.totalWalletAmount) {\n <button type=\"button\" class=\"sbd-cancel__leg-chevron\"\n [ngClass]=\"{ 'sbd-cancel__leg-chevron--collapsed': !paidSummaryExpanded() }\"\n aria-label=\"Toggle paid breakdown\">\n <i class=\"pi pi-chevron-up\"></i>\n </button>\n }\n </span>\n </div>\n\n @if (hasPaidBreakdown() && paidSummaryExpanded() && !!adjustedData()?.totalWalletAmount) {\n <div class=\"sbd-cancel__summary-breakdown\">\n @for (row of paidBreakdownRows(); track row.label) {\n @if (row.label === 'Almatar Wallet') {\n <div class=\"sbd-cancel__summary-breakdown-row\">\n <span>{{ row.label }}</span>\n <span>{{ fmt(row.value) }}</span>\n </div>\n }\n }\n </div>\n }\n\n <div class=\"sbd-cancel__summary-row sbd-cancel__summary-row--refund\">\n <span class=\"sbd-cancel__summary-label\"><i class=\"pi pi-dollar\"></i> You will get back</span>\n <strong>{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n </div>\n </div>\n\n <!-- Golden Guarantee gift \u2014 overrides credit-shell messaging below -->\n @if (hasGoldenGuaranteeGift()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--success\">\n <i class=\"pi pi-shield\"></i>\n <span>You're covered by Cancel for any reason service, you'll get 100% refund, minus any applicable fees. See the breakdown below.</span>\n </div>\n }\n\n <!-- One-way (or a round-trip restricted to a single leg): single card -->\n @if (!showRoundTripLegCards()) {\n <!-- Source selector (multiple suppliers) -->\n @if (availableSources().length > 1) {\n <div class=\"sbd-cancel__source-selector\">\n <span class=\"sbd-cancel__source-label\">Cancel via</span>\n @for (src of availableSources(); track src) {\n <button class=\"sbd-cancel__source-chip\"\n [ngClass]=\"{\n 'sbd-cancel__source-chip--active': selectedSource() === src,\n 'sbd-cancel__source-chip--no-refund': activeSourceBreakdown()?.[src]?.isRefundable === false\n }\"\n (click)=\"selectedSource.set(src)\">\n {{ src }}\n @if (activeSourceBreakdown()?.[src]?.isRefundable === false) {\n <i class=\"pi pi-ban\" style=\"font-size:10px; margin-left:4px;\"></i>\n }\n </button>\n }\n </div>\n @if (sourceNonRefundableHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>{{ sourceNonRefundableHint() }}</span>\n </div>\n }\n }\n\n <!-- Not refundable -->\n @if (!currentData()?.isRefundable) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <div>\n <strong>This leg is not eligible for a refund.</strong>\n <p>Please escalate to the relevant team for manual handling.</p>\n </div>\n </div>\n } @else {\n <div class=\"sbd-cancel__section-title\">Refund Details</div>\n\n <div class=\"sbd-cancel__refund-card\">\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--green\">Refundable</span>\n\n @if (refundableBreakdownRows(adjustedData()).length) {\n @for (r of refundableBreakdownRows(adjustedData()); track r.label) {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>{{ r.label }}</span>\n <strong>{{ fmt(r.value) }}</strong>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>Fare</span>\n <strong>{{ fmt(adjustedData()?.originalAmount) }}</strong>\n </div>\n }\n\n <!-- hide addon note new CR from CX -->\n <!-- @if (hasRefundableAddonNote(adjustedData())) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--neutral\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your add-on service/s refund will be processed separately by our Customer Service team shortly.</span>\n </div>\n } -->\n\n <!-- Deductions -->\n @if (deductions().length) {\n <div class=\"sbd-cancel__refund-card-divider\"></div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--muted\">Not Refunded - Deductions</span>\n @for (d of deductions(); track d.label) {\n <div class=\"sbd-cancel__refund-card-line\">\n <span>\n {{ d.label }}\n @if (d.badge) { <span class=\"sbd-cancel__tag\">{{ d.badge }}</span> }\n </span>\n <span class=\"sbd-cancel__refund-card-line--neg\">{{ fmtNeg(d.value) }}</span>\n </div>\n }\n }\n\n <div class=\"sbd-cancel__refund-card-divider sbd-cancel__refund-card-divider--dashed\"></div>\n <div class=\"sbd-cancel__refund-card-total\">\n <span>Total Refund</span>\n <strong>{{ fmt(adjustedData()?.totalRefundAmount) }}</strong>\n </div>\n </div>\n\n <!-- Credit shell -->\n @if (creditShellNote()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F {{ creditShellNote() }}</span>\n </div>\n }\n }\n }\n\n <!-- Round trip: one collapsible card per leg (only when both legs are cancellable) -->\n @if (showRoundTripLegCards()) {\n <!-- Gift hint -->\n @if (giftHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--tip\">\n <i class=\"pi pi-info-circle\"></i>\n <span>{{ giftHint() }}</span>\n </div>\n }\n\n <!-- Mixed hint -->\n @if (mixedHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <span>{{ mixedHint() }}</span>\n </div>\n }\n\n <!-- Source selector (multiple suppliers) -->\n @if (availableSources().length > 1) {\n <div class=\"sbd-cancel__source-selector\">\n <span class=\"sbd-cancel__source-label\">Cancel via</span>\n @for (src of availableSources(); track src) {\n <button class=\"sbd-cancel__source-chip\"\n [ngClass]=\"{\n 'sbd-cancel__source-chip--active': selectedSource() === src,\n 'sbd-cancel__source-chip--no-refund': activeSourceBreakdown()?.[src]?.isRefundable === false\n }\"\n (click)=\"selectedSource.set(src)\">\n {{ src }}\n @if (activeSourceBreakdown()?.[src]?.isRefundable === false) {\n <i class=\"pi pi-ban\" style=\"font-size:10px; margin-left:4px;\"></i>\n }\n </button>\n }\n </div>\n @if (sourceNonRefundableHint()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>{{ sourceNonRefundableHint() }}</span>\n </div>\n }\n }\n\n <!-- Onward leg card -->\n @if (onwardChecked()) {\n <div class=\"sbd-cancel__leg-card\">\n <div class=\"sbd-cancel__leg-card-header\" (click)=\"toggleLegExpanded('onward')\">\n <span class=\"sbd-cancel__leg-checkbox\">Onward</span>\n <button type=\"button\" class=\"sbd-cancel__leg-chevron\"\n [ngClass]=\"{ 'sbd-cancel__leg-chevron--collapsed': !onwardExpanded() }\"\n aria-label=\"Toggle\">\n <i class=\"pi pi-chevron-up\"></i>\n </button>\n </div>\n\n @if (onwardExpanded()) {\n <div class=\"sbd-cancel__leg-card-body\">\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"legAdjustedData('onward')?.isRefundable ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--red'\">\n {{ legAdjustedData('onward')?.isRefundable ? 'Refundable' : 'Non-Refundable' }}\n </span>\n\n @if (legAdjustedData('onward')?.isRefundable) {\n @if (refundableBreakdownRows(legAdjustedData('onward')).length) {\n @for (r of refundableBreakdownRows(legAdjustedData('onward')); track r.label) {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>{{ r.label }}</span>\n <strong>{{ fmt(r.value) }}</strong>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>Fare</span>\n <strong>{{ fmt(legRefundPool('onward')) }}</strong>\n </div>\n }\n\n <!-- hide addon note new CR from CX -->\n <!-- @if (hasRefundableAddonNote(legAdjustedData('onward'))) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--neutral\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your add-on service/s refund will be processed separately by our Customer Service team shortly.</span>\n </div>\n } -->\n\n @if (legDeductions('onward').length && !isCreditShell()) {\n <div class=\"sbd-cancel__refund-card-divider\"></div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--muted\">Not Refunded - Deductions</span>\n @for (d of legDeductions('onward'); track d.label) {\n <div class=\"sbd-cancel__refund-card-line\">\n <span>\n {{ d.label }}\n @if (d.badge) { <span class=\"sbd-cancel__tag\">{{ d.badge }}</span> }\n </span>\n <span class=\"sbd-cancel__refund-card-line--neg\">{{ fmtNeg(d.value) }}</span>\n </div>\n }\n }\n\n <div class=\"sbd-cancel__refund-card-divider sbd-cancel__refund-card-divider--dashed\"></div>\n <div class=\"sbd-cancel__refund-card-total\">\n <span>Departure Total Refund</span>\n <strong>{{ fmt(legAdjustedData('onward')?.totalRefundAmount) }}</strong>\n </div>\n\n @if (refundData()?.legInfo?.onward?.isCreditShell && !hasGoldenGuaranteeGift()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F The refund for the onward flight has been issued as an Airline Credit Shell.</span>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>This leg is not eligible for a refund.</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Return leg card -->\n @if (returnChecked()) {\n <div class=\"sbd-cancel__leg-card\">\n <div class=\"sbd-cancel__leg-card-header\" (click)=\"toggleLegExpanded('return')\">\n <span class=\"sbd-cancel__leg-checkbox\">Return</span>\n <button type=\"button\" class=\"sbd-cancel__leg-chevron\"\n [ngClass]=\"{ 'sbd-cancel__leg-chevron--collapsed': !returnExpanded() }\"\n aria-label=\"Toggle\">\n <i class=\"pi pi-chevron-up\"></i>\n </button>\n </div>\n\n @if (returnExpanded()) {\n <div class=\"sbd-cancel__leg-card-body\">\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline\"\n [ngClass]=\"legAdjustedData('return')?.isRefundable ? 'sbd-cancel__badge--green' : 'sbd-cancel__badge--red'\">\n {{ legAdjustedData('return')?.isRefundable ? 'Refundable' : 'Non-Refundable' }}\n </span>\n\n @if (legAdjustedData('return')?.isRefundable) {\n @if (refundableBreakdownRows(legAdjustedData('return')).length) {\n @for (r of refundableBreakdownRows(legAdjustedData('return')); track r.label) {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>{{ r.label }}</span>\n <strong>{{ fmt(r.value) }}</strong>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__refund-card-row\">\n <span>Fare</span>\n <strong>{{ fmt(legRefundPool('return')) }}</strong>\n </div>\n }\n\n <!-- hide addon note new CR from CX -->\n <!-- @if (hasRefundableAddonNote(legAdjustedData('return'))) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--neutral\">\n <i class=\"pi pi-info-circle\"></i>\n <span>Your add-on service/s refund will be processed separately by our Customer Service team shortly.</span>\n </div>\n } -->\n\n @if (legDeductions('return').length && !isCreditShell()) {\n <div class=\"sbd-cancel__refund-card-divider\"></div>\n <span class=\"sbd-cancel__badge sbd-cancel__badge--outline sbd-cancel__badge--muted\">Not Refunded - Deductions</span>\n @for (d of legDeductions('return'); track d.label) {\n <div class=\"sbd-cancel__refund-card-line\">\n <span>\n {{ d.label }}\n @if (d.badge) { <span class=\"sbd-cancel__tag\">{{ d.badge }}</span> }\n </span>\n <span class=\"sbd-cancel__refund-card-line--neg\">{{ fmtNeg(d.value) }}</span>\n </div>\n }\n }\n\n <div class=\"sbd-cancel__refund-card-divider sbd-cancel__refund-card-divider--dashed\"></div>\n <div class=\"sbd-cancel__refund-card-total\">\n <span>Return Total Refund</span>\n <strong>{{ fmt(legAdjustedData('return')?.totalRefundAmount) }}</strong>\n </div>\n\n @if (refundData()?.legInfo?.return?.isCreditShell && !hasGoldenGuaranteeGift()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F The refund for the return flight has been issued as an Airline Credit Shell.</span>\n </div>\n }\n } @else {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--warning\">\n <i class=\"pi pi-ban\"></i>\n <span>This leg is not eligible for a refund.</span>\n </div>\n }\n </div>\n }\n </div>\n }\n }\n\n <!-- Instant refund notice -->\n @if (currentData()?.isRefundable) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--shield\">\n <i class=\"pi pi-shield\"></i>\n <span>\n @if (isNilRefund()) {\n We're sorry, as per airline policy, no refund applies because the cancellation fees equal or exceed your refundable fare amount.\n } @else {\n @if (isWalletOnlyRefund() || isLoyaltyOnlyRefund()) {\n Your refund is instant to the customer's almatar Wallet.\n } @else {\n Your refund is instant from our side, your bank may take up to 15 business days to reflect it.\n }\n }\n @if (!isNilRefund() && !isCreditShell()) {\n <strong>You can select refund option in the next step</strong>\n }\n </span>\n </div>\n }\n }\n\n </div>\n\n <!-- Footer -->\n <div class=\"sbd-cancel__footer\">\n @if (refundData()?.isRefundable) {\n <button pButton label=\"Keep booking\" styleClass=\"p-button-outlined p-button-secondary sbd-cancel__btn-keep\" (click)=\"closed.emit()\"></button>\n @if (currentData()?.isRefundable) {\n <button pButton\n styleClass=\"sbd-cancel__btn-primary\"\n [label]=\"isCreditShell() ? 'Continue Cancellation' : 'Select refund option'\"\n [disabled]=\"!canConfirm()\" (click)=\"requestCancel()\"></button>\n }\n } @else {\n <button pButton label=\"Close\" styleClass=\"p-button-outlined p-button-secondary\" (click)=\"closed.emit()\"></button>\n }\n </div>\n }\n\n <!-- \u2500\u2500 Result overlay: floating modal over the dimmed refund-method screen (scoped to this dialog, not the whole viewport) \u2500\u2500 -->\n @if (cancelResult()) {\n <div class=\"sbd-cancel__result-overlay\">\n <div class=\"sbd-cancel__result-backdrop\"></div>\n <div class=\"sbd-cancel__result-modal\">\n <div class=\"sbd-cancel__result-hero\">\n <span class=\"sbd-cancel__result-icon sbd-cancel__result-icon--green\">\n <i class=\"pi pi-check\"></i>\n </span>\n <h3 class=\"sbd-cancel__result-title\">{{ confirmIsNilRefund() ? 'Cancel Confirmed' : 'Refund Confirmed' }}</h3>\n </div>\n\n @for (r of confirmRefunds(); track r.label) {\n <div class=\"sbd-cancel__result-row\">\n <span class=\"sbd-cancel__method-icon\">\n <i class=\"pi\" [ngClass]=\"isWalletDestinationRow(r) ? 'pi-wallet' : 'pi-credit-card'\"></i>\n </span>\n <span class=\"sbd-cancel__result-body-text\">\n <span class=\"sbd-cancel__method-name\">{{ r.label }}</span>\n @if (r.subRows?.length) {\n <span class=\"sbd-cancel__result-sub-rows\">\n @for (sub of r.subRows; track sub.label) {\n <span class=\"sbd-cancel__result-sub-row\">\n <span>{{ sub.label }}</span>\n <strong>{{ fmtResult(sub.value) }}</strong>\n </span>\n }\n </span>\n }\n <span class=\"sbd-cancel__method-badge\"\n [ngClass]=\"isWalletDestinationRow(r) ? 'sbd-cancel__method-badge--instant' : 'sbd-cancel__method-badge--days'\">\n {{ isWalletDestinationRow(r) ? 'Ready Now' : (r.key === 'totalCardRefundAmount' ? confirmCardBadgeText() : 'Up to 15 business days, bank policy') }}\n </span>\n @if (r.hasLoyaltyNote) {\n <span class=\"sbd-cancel__notice sbd-cancel__notice--info\">\n <i class=\"pi pi-info-circle\"></i>\n <span>External loyalty points are refunded to your almatar Wallet as permanent points and ready to use in your next booking.</span>\n </span>\n }\n </span>\n <strong class=\"sbd-cancel__result-amount\">{{ fmtResult(r.value) }}</strong>\n </div>\n }\n\n @if (confirmCreditShellNote()) {\n <div class=\"sbd-cancel__notice sbd-cancel__notice--credit\">\n <i class=\"pi pi-wallet\"></i>\n <span>\u2139\uFE0F {{ confirmCreditShellNote() }}</span>\n </div>\n }\n\n <button pButton styleClass=\"sbd-cancel__btn-primary sbd-cancel__result-done\" label=\"Close\" (click)=\"closed.emit()\"></button>\n </div>\n </div>\n }\n\n </div>\n\n</p-dialog>\n\n<ng-template #madaLogo>\n <svg width=\"43\" height=\"15\" viewBox=\"0 0 43 15\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_sbd_mada)\">\n <path d=\"M18.1894 8.6543H0V14.9933H18.1894V8.6543Z\" fill=\"#84B740\" />\n <path d=\"M18.1894 0H0V6.34463H18.1894V0Z\" fill=\"#259BD6\" />\n <path\n d=\"M36.3779 13.7034L36.2969 13.7203C36.016 13.7768 35.9134 13.7994 35.7082 13.7994C35.233 13.7994 34.6713 13.5452 34.6713 12.3475C34.6713 11.7316 34.7685 10.9124 35.6542 10.9124H35.6596C35.8108 10.9237 35.9836 10.9407 36.3077 11.0424L36.3779 11.065V13.7034ZM36.5237 7.73164L36.3779 7.75989V9.97458L36.2483 9.93503L36.2105 9.92373C36.0647 9.87853 35.7298 9.77684 35.4058 9.77684C33.6344 9.77684 33.2617 11.178 33.2617 12.3531C33.2617 13.9633 34.1258 14.8898 35.6326 14.8898C36.2699 14.8898 36.7397 14.822 37.215 14.6582C37.6524 14.5113 37.8091 14.3023 37.8091 13.8559V7.5C37.3878 7.5791 36.9504 7.65819 36.5237 7.73164Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M41.651 13.7385L41.5754 13.7611L41.3053 13.8345C41.0515 13.9023 40.8247 13.9419 40.6519 13.9419C40.236 13.9419 39.9876 13.7272 39.9876 13.36C39.9876 13.1227 40.0902 12.7215 40.7707 12.7215H41.651V13.7385ZM41.0299 9.74414C40.4844 9.74414 39.9228 9.84584 39.2261 10.0718L38.7724 10.2131L38.9236 11.2865L39.3665 11.134C39.831 10.9758 40.4088 10.8741 40.8409 10.8741C41.0353 10.8741 41.6294 10.8741 41.6294 11.5464V11.8402H40.8031C39.2963 11.8402 38.5996 12.343 38.5996 13.4221C38.5996 14.343 39.2423 14.8967 40.3224 14.8967C40.6573 14.8967 41.1217 14.8289 41.5214 14.7272L41.543 14.7215L41.5646 14.7272L41.6996 14.7498C42.1208 14.8289 42.5583 14.908 42.9849 14.9927V11.4673C42.9849 10.3261 42.3261 9.74414 41.0299 9.74414Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M31.1527 13.7385L31.0771 13.7611L30.807 13.8345C30.5532 13.9023 30.3318 13.9419 30.1536 13.9419C29.7377 13.9419 29.4893 13.7272 29.4893 13.36C29.4893 13.1227 29.5919 12.7215 30.267 12.7215H31.1473L31.1527 13.7385ZM30.537 9.74414C29.9861 9.74414 29.4299 9.84584 28.7332 10.0718L28.2795 10.2131L28.4308 11.2865L28.8736 11.134C29.3381 10.9758 29.9159 10.8741 30.348 10.8741C30.5424 10.8741 31.1365 10.8741 31.1365 11.5464V11.8402H30.3102C28.8034 11.8402 28.1013 12.343 28.1013 13.4221C28.1013 14.343 28.744 14.8967 29.8295 14.8967C30.1644 14.8967 30.6288 14.8289 31.0285 14.7272L31.0501 14.7215L31.0717 14.7272L31.2013 14.7498C31.6279 14.8289 32.06 14.908 32.4866 14.9984V11.473C32.492 10.3204 31.8332 9.74414 30.537 9.74414Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M25.4701 9.7576C24.7842 9.7576 24.2172 9.99489 24.0065 10.0966L23.9525 10.1248L23.9039 10.0853C23.6123 9.86495 23.1856 9.75195 22.5916 9.75195C22.0677 9.75195 21.5762 9.83105 21.0416 9.99489C20.5825 10.1418 20.4043 10.3734 20.4043 10.8085V14.8367H21.8409V11.1135L21.9111 11.0909C22.2027 10.9892 22.3755 10.9723 22.543 10.9723C22.9588 10.9723 23.1694 11.2039 23.1694 11.6559V14.8423H24.5844V11.5938C24.5844 11.4017 24.5466 11.2887 24.5412 11.2661L24.4926 11.17L24.5898 11.1248C24.8058 11.0231 25.0435 10.9723 25.2919 10.9723C25.5781 10.9723 25.9184 11.0909 25.9184 11.6559V14.8423H27.3279V11.509C27.3279 10.3282 26.7231 9.7576 25.4701 9.7576Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M40.5866 4.13559C40.3759 4.13559 40.0249 4.113 39.7495 4.0565L39.6684 4.03955V1.86441C39.6684 1.68362 39.636 1.57062 39.6306 1.55367L39.5874 1.46328L39.6793 1.42373C39.7009 1.41243 39.7225 1.40678 39.7495 1.39548L39.7657 1.38418C39.7981 1.37288 39.8305 1.36158 39.8629 1.35028C39.8791 1.34463 39.8899 1.33898 39.9007 1.33898C40.2193 1.24859 40.511 1.25989 40.6406 1.24859H40.646C41.5263 1.24859 41.6289 2.0678 41.6289 2.68362C41.6235 3.88136 41.0564 4.13559 40.5866 4.13559ZM40.5812 0C40.5704 0 40.5542 0 40.5434 0C39.7171 0 38.8692 0.237288 38.5667 0.700565C38.4047 0.926554 38.3129 1.20904 38.3075 1.54237V3.78531C38.3075 3.9774 38.2697 4.05085 38.2643 4.0678L38.2157 4.16384H35.6072V2.60452H35.6018C35.5694 0.960452 34.6404 0.0564972 33.2957 0.0564972H33.1391H31.9833C31.9293 0.457627 31.8861 0.740113 31.8321 1.14124H33.1391C33.8249 1.14124 34.1868 1.75141 34.1868 2.68927V4.25989L34.095 4.20904C34.0788 4.20339 33.9654 4.16384 33.7871 4.16384H31.5297C31.4865 4.46328 31.4325 4.85311 31.373 5.24294H38.3129C38.5505 5.19209 38.8259 5.14689 39.0636 5.10735C39.4146 5.28814 40.0681 5.38418 40.5164 5.38418C42.0231 5.38418 43.0007 4.32768 43.0007 2.70057C42.9953 1.0904 42.0501 0.0338983 40.5812 0Z\"\n fill=\"#747583\"\n />\n <path\n d=\"M28.4189 5.90821H28.4837C29.9905 5.90821 30.6925 5.38844 30.6925 4.10595C30.6925 3.18505 30.0499 2.45059 28.9697 2.45059H27.5818C27.1659 2.45059 26.9175 2.202 26.9175 1.78392C26.9175 1.50143 27.0201 1.15115 27.7006 1.15115H30.7357C30.8006 0.738723 30.833 0.478836 30.8924 0.0664062H27.7384C26.2694 0.0664062 25.5295 0.710474 25.5295 1.78392C25.5295 2.84607 26.1722 3.39974 27.2523 3.39974H28.6403C29.0561 3.39974 29.3046 3.74437 29.3046 4.10595C29.3046 4.34324 29.202 4.83477 28.5269 4.83477H28.2947L23.8499 4.82347H23.0398C22.3539 4.82347 21.8733 4.41669 21.8733 3.47319V2.82347C21.8733 1.84042 22.2459 1.23025 23.0398 1.23025H24.3576C24.417 0.812169 24.4548 0.546632 24.5088 0.151152H22.867H22.7104C21.3656 0.151152 20.4367 1.09466 20.4043 2.73872V2.80087V3.47319C20.4367 5.11725 21.3656 5.90256 22.7104 5.90256H22.867H24.0227L26.4314 5.90821H27.868H28.4189Z\"\n fill=\"#747583\"\n />\n </g>\n <defs>\n <clipPath id=\"clip0_sbd_mada\">\n <rect width=\"43\" height=\"15\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n</ng-template>\n", styles: [":host ::ng-deep .sbd-cancel-dialog-wrapper{border-radius:16px;overflow:hidden;box-shadow:0 24px 60px #0f172a38}:host ::ng-deep .sbd-cancel-dialog-wrapper .p-dialog-content{padding:0;border-radius:16px;overflow-y:auto;overflow-x:hidden}.sbd-cancel{font-family:inherit;border-radius:16px;overflow:visible;position:relative}.sbd-cancel__loading{padding:24px}.sbd-cancel__loading-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.sbd-cancel__loading-rows{display:flex;flex-direction:column;gap:10px;margin-top:20px}.sbd-cancel__loading-row{display:flex;justify-content:space-between}.sbd-cancel__are-you-sure{padding:36px 24px 28px;display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center;border-top:1px solid #e2e8f0}.sbd-cancel__ays-icon{width:56px;height:56px;border-radius:50%;background:#fff7ed;border:2px solid #fed7aa;display:flex;align-items:center;justify-content:center}.sbd-cancel__ays-icon .pi{font-size:24px;color:#f97316}.sbd-cancel__ays-icon--warn{background:#fef2f2;border-color:#fecaca}.sbd-cancel__ays-icon--warn .pi{color:#ef4444}.sbd-cancel__ays-hint{font-size:13px;color:#64748b;min-height:20px;animation:sbd-hint-fade .35s ease-out}.sbd-cancel__ays-dots{display:flex;gap:6px}.sbd-cancel__ays-dots span{width:7px;height:7px;border-radius:50%;background:#f97316;opacity:.3;animation:sbd-dot-pulse 1.2s ease-in-out infinite}.sbd-cancel__ays-dots span:nth-child(2){animation-delay:.2s}.sbd-cancel__ays-dots span:nth-child(3){animation-delay:.4s}@keyframes sbd-hint-fade{0%{opacity:0;transform:translateY(5px)}to{opacity:1;transform:translateY(0)}}@keyframes sbd-dot-pulse{0%,to{opacity:.3;transform:scale(1)}50%{opacity:1;transform:scale(1.4)}}.sbd-cancel__header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid #e2e8f0;background:#f8fafc}.sbd-cancel__header-left{display:flex;align-items:center;gap:10px}.sbd-cancel__header-icon{font-size:18px;color:#475569}.sbd-cancel__header-title{font-size:15px;font-weight:700;color:#1e2e4a}.sbd-cancel__header--stack{align-items:flex-start}.sbd-cancel__header-titles{display:flex;flex-direction:column;gap:2px}.sbd-cancel__header-sub{font-size:12.5px;font-weight:600;color:#94a3b8;font-variant-numeric:tabular-nums}.sbd-cancel__badge{font-size:11.5px;font-weight:700;border-radius:20px;padding:3px 12px;letter-spacing:.03em;width:max-content;text-transform:uppercase}.sbd-cancel__badge--green{background:#dcfce7;color:#166534}.sbd-cancel__badge--red{background:#fee2e2;color:#991b1b}.sbd-cancel__badge--orange{background:#fff7ed;color:#9a3412}.sbd-cancel__badge--outline{background:transparent;box-shadow:inset 0 0 0 1.5px currentColor;padding:4px 14px}.sbd-cancel__badge--outline.sbd-cancel__badge--green{color:#16a34a}.sbd-cancel__badge--outline.sbd-cancel__badge--red{color:#dc2626}.sbd-cancel__badge--muted{background:#f8fafc;color:#64748b;box-shadow:inset 0 0 0 1px #e2e8f0}.sbd-cancel__close-btn{width:30px;height:30px;border-radius:8px;border:none;background:transparent;color:#64748b;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .15s,color .15s}.sbd-cancel__close-btn .pi{font-size:14px}.sbd-cancel__close-btn:hover{background:#e2e8f0;color:#1e2e4a}.sbd-cancel__close-btn--floating{position:absolute;top:12px;inset-inline-end:12px}.sbd-cancel__summary{background:#f8fafc;border:1px solid #e2e8f0;border-radius:12px;padding:14px 16px;display:flex;flex-direction:column;gap:10px}.sbd-cancel__summary-row{display:flex;align-items:center;justify-content:space-between;font-size:13.5px}.sbd-cancel__summary-row strong{font-size:15px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__summary-row--refund .sbd-cancel__summary-label,.sbd-cancel__summary-row--refund strong{color:#16a34a}.sbd-cancel__summary-row--toggle{cursor:pointer}.sbd-cancel__summary-label{display:inline-flex;align-items:center;gap:8px;font-weight:600;color:#475569}.sbd-cancel__summary-label .pi{font-size:13px}.sbd-cancel__summary-value{display:flex;align-items:center;gap:4px}.sbd-cancel__summary-breakdown{display:flex;flex-direction:column;gap:6px;padding:2px 0 2px 22px}.sbd-cancel__summary-breakdown-row{display:flex;align-items:center;justify-content:space-between;font-size:12.5px;color:#64748b}.sbd-cancel__summary-breakdown-row span:last-child{font-variant-numeric:tabular-nums;font-weight:600;color:#475569}.sbd-cancel__section-title{font-size:14px;font-weight:700;color:#1e2e4a}.sbd-cancel__refund-card{border:1px solid #e2e8f0;border-radius:12px;padding:16px;display:flex;flex-direction:column;gap:4px}.sbd-cancel__refund-card-row{display:flex;align-items:center;justify-content:space-between;margin-top:10px;font-size:14px}.sbd-cancel__refund-card-row span{color:#334155;font-weight:600}.sbd-cancel__refund-card-row strong{color:#1e2e4a;font-weight:700;font-variant-numeric:tabular-nums}.sbd-cancel__refund-card-divider{border-top:1px solid #e2e8f0;margin:10px 0}.sbd-cancel__refund-card-divider--dashed{border-top-style:dashed}.sbd-cancel__refund-card-line{display:flex;align-items:center;justify-content:space-between;padding:5px 0;font-size:13px}.sbd-cancel__refund-card-line span:first-child{color:#64748b;display:inline-flex;align-items:center}.sbd-cancel__refund-card-line--neg{color:#64748b;font-weight:600;font-variant-numeric:tabular-nums}.sbd-cancel__refund-card-total{display:flex;align-items:center;justify-content:space-between}.sbd-cancel__refund-card-total span{font-size:14.5px;font-weight:700;color:#1e2e4a}.sbd-cancel__refund-card-total strong{font-size:17px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__btn-keep{flex:1 1 0}.sbd-cancel__btn-primary{flex:1 1 0;background:#6d4aff!important;border-color:#6d4aff!important;color:#fff!important}.sbd-cancel__btn-primary:hover:not(:disabled){background:#5c3ce6!important;border-color:#5c3ce6!important}.sbd-cancel__btn-primary:disabled{opacity:.5}.sbd-cancel__paid{display:flex;align-items:center;justify-content:space-between;margin:0 -20px;padding:14px 20px;border-radius:0;background:#f1f0fb;border-top:1px solid #e7e5f7;border-bottom:1px solid #e7e5f7}.sbd-cancel__paid span{font-size:13.5px;font-weight:600;color:#4b4670}.sbd-cancel__paid strong{font-size:18px;font-weight:800;color:#2b2747;font-variant-numeric:tabular-nums;letter-spacing:.01em}.sbd-cancel__group{display:flex;flex-direction:column}.sbd-cancel__group-label{font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.07em;margin-bottom:2px}.sbd-cancel__group-label--deduct{color:#e05656}.sbd-cancel__group-label--refund{color:#16a34a}.sbd-cancel__line{display:flex;justify-content:space-between;align-items:center;padding:11px 0;font-size:13.5px;border-bottom:1px dashed #e5e7eb}.sbd-cancel__line:last-child{border-bottom:none}.sbd-cancel__line-label{display:inline-flex;align-items:center;color:#334155}.sbd-cancel__line-val{font-weight:700;font-variant-numeric:tabular-nums}.sbd-cancel__line-val--neg{color:#dc2626}.sbd-cancel__line-val--pos{color:#16a34a}.sbd-cancel__tag{margin-left:8px;font-size:10px;font-weight:700;line-height:1;padding:3px 8px;border-radius:6px;background:#ede9fe;color:#6d28d9;letter-spacing:.02em}.sbd-cancel__total-deduct{display:flex;align-items:center;justify-content:space-between;padding:13px 16px;border-radius:10px;background:#fdf2f2;border:1px solid #f6c9c9}.sbd-cancel__total-deduct span{font-size:14px;font-weight:700;color:#b3344a}.sbd-cancel__total-deduct strong{font-size:15px;font-weight:800;color:#dc2626;font-variant-numeric:tabular-nums}.sbd-cancel__calc{display:flex;align-items:center;gap:12px;margin:2px 0;color:#94a3b8;font-size:13px;font-variant-numeric:tabular-nums}.sbd-cancel__calc:before,.sbd-cancel__calc:after{content:\"\";flex:1;height:1px;background:#e5e7eb}.sbd-cancel__refund-total{display:flex;align-items:center;justify-content:space-between}.sbd-cancel__refund-total span{font-size:16px;font-weight:800;color:#1e2e4a}.sbd-cancel__refund-total strong{font-size:26px;font-weight:800;color:#16a34a;font-variant-numeric:tabular-nums;letter-spacing:.01em}.sbd-cancel__formula{text-align:center;padding:14px 16px;border-radius:10px;background:#1f2438;color:#f1f5f9;font-family:SFMono-Regular,ui-monospace,Menlo,Consolas,monospace;font-size:14px;font-weight:600;letter-spacing:.04em;font-variant-numeric:tabular-nums}.sbd-cancel__discrepancy{display:flex;align-items:flex-start;gap:10px;padding:11px 13px;border-radius:8px;font-size:12.5px;line-height:1.45;background:#fffbeb;border:1px solid #fde68a;color:#92400e}.sbd-cancel__discrepancy i{flex-shrink:0;margin-top:1px;font-size:14px;color:#d97706}.sbd-cancel__body{padding:16px 20px;display:flex;flex-direction:column;gap:12px}.sbd-cancel__leg-card{width:100%;border-radius:12px;border:1px solid #e2e8f0;background:#fff;overflow:hidden}.sbd-cancel__leg-card-header{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:14px 16px;cursor:pointer}.sbd-cancel__leg-checkbox{display:flex;align-items:center;gap:10px;font-size:13.5px;font-weight:700;color:#1e2e4a;cursor:pointer}.sbd-cancel__leg-checkbox input[type=checkbox]{width:17px;height:17px;accent-color:#6d4aff;cursor:pointer}.sbd-cancel__leg-chevron{flex-shrink:0;width:26px;height:26px;display:flex;align-items:center;justify-content:center;border:none;background:transparent;color:#64748b;cursor:pointer;transition:transform .15s}.sbd-cancel__leg-chevron i{font-size:13px}.sbd-cancel__leg-chevron--collapsed{transform:rotate(180deg)}.sbd-cancel__leg-card-body{display:flex;flex-direction:column;gap:4px;padding:0 16px 16px}.sbd-cancel__leg-card-body--excluded{opacity:.5}.sbd-cancel__notice{display:flex;align-items:flex-start;gap:10px;padding:10px 12px;border-radius:8px;font-size:12.5px}.sbd-cancel__notice i{flex-shrink:0;margin-top:1px;font-size:14px}.sbd-cancel__notice p{margin:2px 0 0;font-size:12px;opacity:.8}.sbd-cancel__notice strong{display:block;font-weight:700}.sbd-cancel__notice--warning{background:#fff7ed;border:1px solid #fed7aa;color:#9a3412}.sbd-cancel__notice--warning i{color:#f97316}.sbd-cancel__notice--info{background:#eff6ff;border:1px solid #bfdbfe;color:#1e40af}.sbd-cancel__notice--info i{color:#3b82f6}.sbd-cancel__notice--neutral{background:#f7f7f8;border:1px solid #e5e7eb;color:#111827}.sbd-cancel__notice--neutral i{color:#111827}.sbd-cancel__notice--tip{background:#f0fdf4;border:1px solid #bbf7d0;color:#14532d}.sbd-cancel__notice--tip i{color:#22c55e}.sbd-cancel__notice--success{background:#f0fdf4;border:1px solid #bbf7d0;color:#15803c}.sbd-cancel__notice--success i{color:#16a34a}.sbd-cancel__notice--credit{background:#faf5ff;border:1px solid #e9d5ff;color:#5b21b6;font-size:12px}.sbd-cancel__notice--credit i{color:#a855f7}.sbd-cancel__notice--shield{background:#eff6ff;border:1px solid #bfdbfe;color:#1e40af}.sbd-cancel__notice--shield strong{display:inline;font-weight:700}.sbd-cancel__notice--shield i{color:#3b82f6}.sbd-cancel__source-selector{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:4px 0}.sbd-cancel__source-label{font-size:11px;font-weight:700;color:#94a3b8;text-transform:uppercase;letter-spacing:.06em;white-space:nowrap;margin-right:2px}.sbd-cancel__source-chip{font-size:12px;font-weight:600;padding:4px 14px;border-radius:20px;border:1.5px solid #e2e8f0;background:#f8fafc;color:#475569;cursor:pointer;transition:border-color .15s,color .15s,background .15s;display:inline-flex;align-items:center}.sbd-cancel__source-chip:hover{border-color:#94a3b8;color:#475569;background:#f1f5f9}.sbd-cancel__source-chip--active{background:#eff6ff;color:#1d4ed8;border-color:#93c5fd}.sbd-cancel__source-chip--active:hover{background:#dbeafe;color:#1d4ed8;border-color:#93c5fd}.sbd-cancel__source-chip--no-refund{border-color:#fecaca;color:#b91c1c;background:#fff5f5}.sbd-cancel__source-chip--no-refund:hover{border-color:#fca5a5;background:#fee2e2;color:#b91c1c}.sbd-cancel__source-chip--active.sbd-cancel__source-chip--no-refund{background:#fee2e2;color:#991b1b;border-color:#fca5a5}.sbd-cancel__source-chip--active.sbd-cancel__source-chip--no-refund:hover{background:#fecaca}.sbd-cancel__footer{display:flex;justify-content:flex-end;gap:10px;align-items:stretch;padding:14px 20px;border-top:1px solid #e2e8f0;background:#fff}.sbd-cancel__btn-danger-pill{flex:1 1 0;border-radius:999px!important;background:#fee2e2!important;border-color:#fee2e2!important;color:#dc2626!important;font-weight:700!important}.sbd-cancel__btn-danger-pill:hover:not(:disabled){background:#fecaca!important;border-color:#fecaca!important}.sbd-cancel__btn-danger-pill:disabled{opacity:.5}.sbd-cancel__method-header{display:flex;align-items:flex-start;gap:12px;padding:20px 20px 0}.sbd-cancel__method-close{flex-shrink:0;width:32px;height:32px;border-radius:50%;background:#f8fafc;border:none;color:#1e2e4a;display:flex;align-items:center;justify-content:center;cursor:pointer}.sbd-cancel__method-close .pi{font-size:13px}.sbd-cancel__method-close:hover{background:#e2e8f0}.sbd-cancel__method-header-text{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;text-align:center;margin-right:32px}.sbd-cancel__method-title{font-size:19px;font-weight:800;color:#1e2e4a;margin:0}.sbd-cancel__method-sub{font-size:12.5px;color:#94a3b8}.sbd-cancel__method-body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:14px}.sbd-cancel__select-leg-body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:12px}.sbd-cancel__leg-select-card{position:relative;border:1.5px solid #e2e8f0;border-radius:16px;padding:16px 16px 16px 48px;transition:border-color .15s}.sbd-cancel__leg-select-card--selected:not(.sbd-cancel__leg-select-card--frozen){border-color:#6d4aff}.sbd-cancel__leg-select-card--disabled{opacity:.7}.sbd-cancel__leg-select-card--frozen{opacity:.6;border-color:#e2e8f0}.sbd-cancel__leg-select-lock{position:absolute;top:16px;left:16px;width:22px;height:22px;display:flex;align-items:center;justify-content:center;font-size:14px;color:#94a3b8}.sbd-cancel__single-leg-note{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:12px;background:#eaf2ff;border:1px solid #b9d6ff;color:#1a5fd6;font-size:13px;line-height:1.5}.sbd-cancel__single-leg-note i{flex-shrink:0;margin-top:1px}.sbd-cancel__all-non-refundable-note{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:12px;background:#fdf3e3;border:1px solid #f3d9a4;color:#8a5a1e;font-size:13px;line-height:1.5}.sbd-cancel__all-non-refundable-note i{flex-shrink:0;margin-top:1px;color:#b98a3e}.sbd-cancel__leg-select-checkbox{position:absolute;top:16px;left:16px;width:22px;height:22px;cursor:pointer}.sbd-cancel__leg-select-checkbox input{position:absolute;inset:0;opacity:0;margin:0;cursor:pointer}.sbd-cancel__leg-select-checkbox input:disabled{cursor:not-allowed}.sbd-cancel__leg-select-icon{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:6px;border:1.5px solid #cbd5e1;background:#fff;color:#fff;font-size:12px}input:checked+.sbd-cancel__leg-select-icon{background:#6d4aff;border-color:#6d4aff}input:disabled+.sbd-cancel__leg-select-icon{background:#f1f5f9;border-color:#e2e8f0}.sbd-cancel__leg-select-content{display:flex;flex-direction:column;gap:8px}.sbd-cancel__leg-select-top{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.sbd-cancel__leg-select-name{font-size:15px;font-weight:700;color:#1e2e4a}.sbd-cancel__leg-select-date{font-size:13px;color:#64748b;margin-top:2px}.sbd-cancel__leg-select-times{display:flex;align-items:center;gap:8px}.sbd-cancel__leg-select-time{font-size:18px;font-weight:700;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__leg-select-line{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;gap:2px;padding:0 16px 0 8px}.sbd-cancel__leg-select-line:before{content:\"\";position:absolute;left:0;right:14px;top:50%;height:2px;background:#cbd5e1;z-index:1}.sbd-cancel__leg-select-line-stops{font-size:12px;color:#64748b}.sbd-cancel__leg-select-line-dur{font-size:11px;color:#94a3b8}.sbd-cancel__leg-select-line-arrow{position:absolute;right:4px;top:51%;transform:translateY(-50%);font-size:11px;color:#64748b}.sbd-cancel__leg-select-footer{display:flex;align-items:center;gap:8px}.sbd-cancel__leg-select-airline{font-size:12.5px;color:#64748b}.sbd-cancel__leg-select-operated-by{font-size:12px;color:#94a3b8}.sbd-cancel__leg-select-chevron{font-size:12px;color:#94a3b8;margin-inline-start:auto}.sbd-cancel__leg-select-hint{text-align:center;padding:8px 20px 0;font-size:13px;color:#94a3b8}.sbd-cancel__leg-select-notice{display:flex;align-items:flex-start;gap:8px;padding:10px 12px;border-radius:10px;background:#fdf1e0;color:#6b4a16;font-size:12.5px;line-height:1.4}.sbd-cancel__leg-select-notice i{flex-shrink:0;margin-top:1px;color:#b98a3e}.sbd-cancel__method-amount{display:flex;align-items:center;justify-content:space-between}.sbd-cancel__method-amount span{font-size:14px;color:#1e2e4a}.sbd-cancel__method-amount strong{font-size:22px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__method-option{display:flex;align-items:flex-start;gap:12px;width:100%;text-align:left;padding:16px;border-radius:16px;border:1.5px solid #e2e8f0;background:#fff;cursor:pointer;transition:border-color .15s,box-shadow .15s}.sbd-cancel__method-option--active{border-color:#6d4aff;box-shadow:0 0 0 1px #6d4aff}.sbd-cancel__method-option:disabled{opacity:.5;cursor:not-allowed}.sbd-cancel__method-icon{flex-shrink:0;width:44px;height:44px;border-radius:10px;display:flex;align-items:center;justify-content:center;border:1px solid #e2e8f0;color:#1e2e4a}.sbd-cancel__method-icon .pi{font-size:16px}.sbd-cancel__method-body-text{flex:1;display:flex;flex-direction:column;align-items:flex-start;gap:4px}.sbd-cancel__method-name{font-size:16px;font-weight:700;color:#1e2e4a;display:inline-flex;align-items:center;gap:6px}.sbd-cancel__method-desc{font-size:13px;color:#64748b}.sbd-cancel__method-badge{display:inline-flex;align-items:center;gap:5px;margin-top:4px;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;padding:4px 10px;border-radius:20px}.sbd-cancel__method-badge svg{flex-shrink:0}.sbd-cancel__method-badge--instant{background:#dcfce7;color:#166534}.sbd-cancel__method-badge--days,.sbd-cancel__method-badge--loyalty{background:#eff6ff;color:#1e40af}.sbd-cancel__option-end{flex-shrink:0;display:flex;align-items:center;gap:8px}.sbd-cancel__method-radio{flex-shrink:0;width:18px;height:18px;margin-top:2px;border-radius:50%;border:2px solid #7c3aed;position:relative}.sbd-cancel__method-option--active .sbd-cancel__method-radio{border-color:#6d4aff}.sbd-cancel__method-option--active .sbd-cancel__method-radio:after{content:\"\";position:absolute;inset:3px;border-radius:50%;background:#6d4aff}.sbd-cancel__method-option--split{flex-wrap:wrap}.sbd-cancel__method-split-total{flex-shrink:0;font-size:16px;font-weight:700;color:#1e2e4a;font-variant-numeric:tabular-nums}.sbd-cancel__method-split-breakdown{flex-basis:100%;display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;margin-top:12px;padding-top:12px;border-top:1px solid #e2e8f0}.sbd-cancel__method-split-row{flex:1 1 auto;display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;font-size:14px;color:#1e2e4a}.sbd-cancel__method-split-row strong{font-weight:700;font-variant-numeric:tabular-nums}.sbd-cancel__method-split-label{color:#64748b;display:inline-flex;align-items:center;gap:6px}.sbd-cancel__mada-logo{display:inline-flex;align-items:center;flex-shrink:0}.sbd-cancel__mada-logo svg{display:block}.sbd-cancel__result-hero{display:flex;flex-direction:column;align-items:center;gap:18px;padding:28px 0 8px}.sbd-cancel__result-icon{width:84px;height:84px;border-radius:50%;display:flex;align-items:center;justify-content:center}.sbd-cancel__result-icon .pi{font-size:30px;color:#fff}.sbd-cancel__result-icon--green{background:#4ade80}.sbd-cancel__result-icon--orange{background:#fb923c}.sbd-cancel__result-title{font-size:19px;font-weight:800;color:#1e2e4a;margin:0;text-align:center}.sbd-cancel__result-row{display:flex;align-items:flex-start;gap:12px;width:100%;padding:12px 14px;border-radius:14px;background:#f8fafc}.sbd-cancel__result-body-text{flex:1;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:5px}.sbd-cancel__result-body-text .sbd-cancel__method-badge{text-transform:none;letter-spacing:normal;line-height:1.35;white-space:normal}.sbd-cancel__result-sub-rows{display:flex;flex-direction:column;gap:2px;width:100%}.sbd-cancel__result-sub-row{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;font-size:12.5px;color:#64748b}.sbd-cancel__result-sub-row strong{font-weight:700;color:#64748b;font-variant-numeric:tabular-nums}.sbd-cancel__result-amount{font-size:16px;font-weight:800;color:#1e2e4a;font-variant-numeric:tabular-nums;white-space:nowrap}.sbd-cancel__result-overlay{position:absolute;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:24px}.sbd-cancel__result-backdrop{position:absolute;inset:0;background:#0000008c}.sbd-cancel__result-modal{position:relative;width:100%;max-width:400px;max-height:90%;overflow-y:auto;display:flex;flex-direction:column;gap:16px;padding:24px 20px;border-radius:20px;background:#fff;box-shadow:0 24px 60px #00000059}.sbd-cancel__result-done{width:100%}\n"] }]
|
|
1440
|
+
}], ctorParameters: () => [] });
|
|
1441
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FuY2VsLWRpYWxvZy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zbWFydC1ib29raW5nLWRhc2hib2FyZC9zcmMvbGliL2NvbXBvbmVudHMvY2FuY2VsLWRpYWxvZy9jYW5jZWwtZGlhbG9nLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LWJvb2tpbmctZGFzaGJvYXJkL3NyYy9saWIvY29tcG9uZW50cy9jYW5jZWwtZGlhbG9nL2NhbmNlbC1kaWFsb2cuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDNUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbkUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7O0FBVS9ELE1BQU0sY0FBYyxHQUFHO0lBQ3JCLEVBQUUsR0FBRyxFQUFFLG9CQUFvQixFQUFnQixLQUFLLEVBQUUsMEJBQTBCLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRTtJQUN6RixFQUFFLEdBQUcsRUFBRSxhQUFhLEVBQXVCLEtBQUssRUFBRSxjQUFjLEVBQWMsS0FBSyxFQUFFLEVBQUUsRUFBRTtJQUN6RixFQUFFLEdBQUcsRUFBRSxpQ0FBaUMs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MTBCWSxZQUFZLDB0QkFBRSxZQUFZLHNLQUFFLGNBQWMsK0JBQUUsZ0JBQWdCLG9KQUFFLE9BQU87OzRGQUlwRSx3QkFBd0I7a0JBUHBDLFNBQVM7K0JBQ0UsdUJBQXVCLGNBQ3JCLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgaW5wdXQsIG91dHB1dCwgaW5qZWN0LCBlZmZlY3QsIHNpZ25hbCwgY29tcHV0ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5nVGVtcGxhdGVPdXRsZXQsIE5nQ2xhc3MgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRGlhbG9nTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9kaWFsb2cnO1xuaW1wb3J0IHsgQnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHsgU2tlbGV0b25Nb2R1bGUgfSBmcm9tICdwcmltZW5nL3NrZWxldG9uJztcbmltcG9ydCB7IFNiZEJvb2tpbmdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvYm9va2luZy5zZXJ2aWNlJztcbmltcG9ydCB7IFNiZFRvYXN0U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3RvYXN0LnNlcnZpY2UnO1xuXG50eXBlIExlZ1NlbGVjdGlvbiA9ICdvbndhcmQnIHwgJ3JldHVybicgfCAnYm90aCc7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG50eXBlIExlZ0RldGFpbHMgPSBhbnk7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG50eXBlIFJlZnVuZERhdGEgPSBhbnk7XG5cbmNvbnN0IERFRFVDVElPTl9ERUZTID0gW1xuICB7IGtleTogJ3RvdGFsUGVuYWx0eVBvaW50cycsICAgICAgICAgICAgICAgbGFiZWw6ICdBaXJsaW5lIENhbmNlbGxhdGlvbiBGZWUnLCBiYWRnZTogJycgfSxcbiAgeyBrZXk6ICdoYW5kbGluZ0ZlZScsICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiAnSGFuZGxpbmcgRmVlJywgICAgICAgICAgICAgYmFkZ2U6ICcnIH0sXG4gIHsga2V5OiAndG90YWxOb25SZWZ1bmRhYmxlU2VydmljZUNoYXJnZScsICBsYWJlbDogJ1NlcnZpY2UgQ2hhcmdlJywgICAgICAgICAgIGJhZGdlOiAnJyB9LFxuICB7IGtleTogJ3RvdGFsQW5jaWxsYXJ5UmVmdW5kQW1vdW50JywgICAgICAgbGFiZWw6ICdBbmNpbGxhcnkgRmVlJywgICAgICAgICAgICBiYWRnZTogJycgfSxcbiAgeyBrZXk6ICd0b3RhbEdpZnRBbW91bnQnLCAgICAgICAgICAgICAgICAgIGxhYmVsOiAnQWRkIG9uIEZlZScsICAgICAgICAgICAgICAgYmFkZ2U6ICcnIH0sXG4gIC8vIGB0b3RhbExveWFsdHlQb2ludHNgIChwb2ludHMgc3BlbnQgYXQgYm9va2luZyB0aW1lLCBub3cgZm9yZmVpdGVkKSBpc1xuICAvLyBpbnRlbnRpb25hbGx5IG5vdCBsaXN0ZWQgaGVyZSDigJQgaXQncyBhbHJlYWR5IHN1cmZhY2VkIHVuZGVyIGl0cyBvd25cbiAgLy8gcHJvZ3JhbSBuYW1lIChlLmcuIFwiUWl0YWZcIikgaW4gdGhlIFwiVG90YWwgUGFpZFwiIGJyZWFrZG93biwgc28gbGlzdGluZyBpdFxuICAvLyBhZ2FpbiBoZXJlIHdvdWxkIGRvdWJsZSB1cCB0aGUgc2FtZSBhbW91bnQgdW5kZXIgdHdvIGRpZmZlcmVudCBzZWN0aW9ucy5cbl07XG5cbmNvbnN0IFJFRlVORF9ERUZTID0gW1xuICB7IGtleTogJ3RvdGFsQ2FyZFJlZnVuZEFtb3VudCcsICAgICAgICAgICAgbGFiZWw6ICdSZWZ1bmQgQW1vdW50JyB9LFxuICB7IGtleTogJ3RvdGFsQ3JlZGl0UmVmdW5kQW1vdW50JywgICAgICAgICAgbGFiZWw6ICdDcmVkaXQgU2hlbGwgUmVmdW5kJyB9LFxuICB7IGtleTogJ3dhbGxldFJlZnVuZEFtb3VudCcsICAgICAgICAgICAgICAgbGFiZWw6ICdBbG1hdGFyIFdhbGxldCcgfSxcbiAgeyBrZXk6ICd0b3RhbExveWFsdHlQb2ludHNSZWZ1bmRBbW91bnQnLCAgIGxhYmVsOiAnTG95YWx0eSBQb2ludHMgUmVmdW5kJyB9LFxuXTtcblxuLyoqIExhYmVscyBmb3IgYHBheW1lbnRNZXRob2RDdXN0b21lclVzZWRgIGdhdGV3YXkgY29kZXMgcmV0dXJuZWQgYnkgdGhlIGJhY2tlbmQuICovXG5jb25zdCBQQVlNRU5UX0dBVEVXQVlfTEFCRUxTOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICBDSDogJ0NhcmQnLFxuICBIUDogJ0h5cGVycGF5JyxcbiAgTUY6ICdNeSBGYXRvb3JhJyxcbiAgV1Q6ICdXaXJlIFRyYW5zZmVyJyxcbiAgU1RDOiAnU1RDJyxcbiAgVE06ICdUYW1hcmEnLFxuICBUQjogJ1RhYmJ5JyxcbiAgUkFKSEk6ICdBbCBSYWpoaSBNb2thZmFhJyxcbiAgUFBCOiAnQ3VzdG9tZXIgQmFsYW5jZScsXG4gIFBQOiAnUG9zdHBheScsXG4gIFRBTUFNOiAnVGFtYW0nLFxuICBRSVRBRjogJ1FpdGFmJyxcbiAgTUlTOiAnTUlTIFBheScsXG4gIE1BVEFSOiAnQWxtYXRhciBQYXknLFxuICBDQjogJ0NvbXBhbnkgQmFsYW5jZScsXG4gIEFOQjogJ0FOQicsXG4gIEFNV0FMOiAnQW13YWwnLFxuICBXQUxBOiAnV2FsYScsXG4gIFlHRzogJ1lHRycsXG59O1xuXG4vKiogR2F0ZXdheSBjb2RlcyB0aGF0IHJlZnVuZCB0byBhbiBpbnN0YWxsbWVudCBwbGFuIHJhdGhlciB0aGFuIHRoZSBvcmlnaW5hbCBjYXJkLiAqL1xuY29uc3QgSU5TVEFMTE1FTlRfR0FURVdBWV9DT0RFUyA9IFsnVE0nLCAnVEInXTtcblxuLyoqIEdhdGV3YXkgY29kZXMgdGhhdCByZWZ1bmQgdG8gYSBsb3lhbHR5LXByb2dyYW0gYWNjb3VudCByYXRoZXIgdGhhbiB0aGUgb3JpZ2luYWwgY2FyZC4gKi9cbmNvbnN0IExPWUFMVFlfR0FURVdBWV9DT0RFUyA9IFsnUkFKSEknLCAnUUlUQUYnLCAnU1RDJywgJ1dBTEEnXTtcblxuLyoqXG4gKiBJbnRlcm5hbCBwYXltZW50LXByb2Nlc3Nvci9nYXRld2F5IG5hbWVzLCBuZXZlciBjdXN0b21lci1yZWNvZ25pemFibGVcbiAqIGJyYW5kcyDigJQgbXVzdCBub3QgYmUgc3VyZmFjZWQgdmVyYmF0aW0gKGUuZy4gYSBjYXJkIHJlZnVuZCBwcm9jZXNzZWRcbiAqIHRocm91Z2ggSHlwZXJwYXkgbXVzdCByZWFkIGFzIFwiQ2FyZFwiL1wiT3JpZ2luYWwgUGF5bWVudCBNZXRob2RcIiwgbmV2ZXJcbiAqIFwiSHlwZXJwYXlcIikuIENhbGxlcnMgZmFsbCBiYWNrIHRvIGEgZ2VuZXJpYyBsYWJlbCB3aGVuZXZlciB0aGUgbm9ybWFsaXplZFxuICogbG9va3VwIHJldHVybnMgJycuXG4gKi9cbmNvbnN0IElOVEVSTkFMX0dBVEVXQVlfQ09ERVMgPSBbJ0hQJywgJ01GJywgJ1dUJywgJ1BQQicsICdQUCcsICdUQU1BTSddO1xuXG4vKipcbiAqIFJlc3VsdC9jb25maXJtYXRpb24tc2NyZWVuLW9ubHkgb3ZlcnJpZGU6IHRoZXNlIGdhdGV3YXlzIHByb2Nlc3MgY2FyZFxuICogcGF5bWVudHMgdGhyb3VnaCBNYWRhIOKAlCBzaG93biBzcGVjaWZpY2FsbHkgYXMgXCJNYWRhIENhcmRcIiBpbnN0ZWFkIG9mXG4gKiBmYWxsaW5nIGJhY2sgdG8gdGhlIGdlbmVyaWMgXCJPcmlnaW5hbCBQYXltZW50IE1ldGhvZFwiIGxhYmVsIHVzZWRcbiAqIGV2ZXJ5d2hlcmUgZWxzZSBgSU5URVJOQUxfR0FURVdBWV9DT0RFU2AgYXBwbGllcy5cbiAqL1xuY29uc3QgTUFEQV9HQVRFV0FZX0NPREVTID0gWydIUCcsICdDSCddO1xuXG5jb25zdCBDUkVESVRfU0hFTExfU1VGRklYID0gJ0l0IGNhbiBiZSB1c2VkIG9ubHkgZm9yIGZ1dHVyZSBib29raW5nIG9uIHRoZSBhaXJsaW5lIHdlYnNpdGUuJztcblxuY29uc3QgR0lGVF9ISU5UID0gJ1BsZWFzZSBub3RlOiBJZiB5b3UgY2FuY2VsIGVpdGhlciBsZWcgb2YgeW91ciByb3VuZC10cmlwIGJvb2tpbmcsIHRoZSBhZGQtb24vZ2lmdCBzZXJ2aWNlIHdpbGwgYmUgY2FuY2VsbGVkIGF1dG9tYXRpY2FsbHkuJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXNiZC1jYW5jZWwtZGlhbG9nJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0RpYWxvZ01vZHVsZSwgQnV0dG9uTW9kdWxlLCBTa2VsZXRvbk1vZHVsZSwgTmdUZW1wbGF0ZU91dGxldCwgTmdDbGFzc10sXG4gIHRlbXBsYXRlVXJsOiAnLi9jYW5jZWwtZGlhbG9nLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL2NhbmNlbC1kaWFsb2cuY29tcG9uZW50LnNjc3MnLFxufSlcbmV4cG9ydCBjbGFzcyBTYmRDYW5jZWxEaWFsb2dDb21wb25lbnQge1xuICBwcml2YXRlIGJvb2tpbmdTZXJ2aWNlID0gaW5qZWN0KFNiZEJvb2tpbmdTZXJ2aWNlKTtcbiAgcHJpdmF0ZSB0b2FzdCA9IGluamVjdChTYmRUb2FzdFNlcnZpY2UpO1xuXG4gIHZpc2libGUgPSBpbnB1dChmYWxzZSk7XG4gIGJvb2tpbmdJZCA9IGlucHV0KCcnKTtcbiAgcHJvZHVjdCA9IGlucHV0PCdmbGlnaHQnIHwgJ2hvdGVsJz4oJ2ZsaWdodCcpO1xuICBwbnJJbmZvID0gaW5wdXQ8eyBwbnI/OiBzdHJpbmc7IExlZ0RpcmVjdGlvbmFsaXR5Pzogc3RyaW5nIH1bXT4oW10pO1xuICAvKiogU2FtZSBgYm9va2luZ19pbmZvYCBwYXlsb2FkIHRoZSBkYXNoYm9hcmQgYWxyZWFkeSBmZXRjaGVzIChnZXRCb29raW5nKC4uLiwgJ2Jvb2tpbmdfaW5mbycpKSDigJQgcmV1c2VkIGhlcmUgdG8gcmVuZGVyIHJlYWwgcm91dGUvdGltZSBkZXRhaWxzIG9uIHRoZSBzZWxlY3QtbGVnIGNhcmRzLCBpbnN0ZWFkIG9mIGEgc2Vjb25kIEFQSSBjYWxsLiAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBib29raW5nSW5mbyA9IGlucHV0PGFueT4obnVsbCk7XG4gIGNsb3NlZCA9IG91dHB1dDx2b2lkPigpO1xuICBjb25maXJtZWQgPSBvdXRwdXQ8TGVnU2VsZWN0aW9uPigpO1xuXG4gIC8qKiBQZXItbGVnIHJvdXRlL3RpbWUgZGV0YWlscywgbWlycm9yaW5nIGFwcC1zYmQtZmxpZ2h0LWl0aW5lcmFyeS1jYXJkJ3MgbWFwcGluZyBvZiBib29raW5nX2luZm8ubGVnX2luZm8uICovXG4gIGl0aW5lcmFyeUxlZ3MgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgYmkgPSB0aGlzLmJvb2tpbmdJbmZvKCk/LmRhdGE/LmJvb2tpbmdfaW5mbztcbiAgICBpZiAoIWJpKSByZXR1cm4gW107XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICByZXR1cm4gKGJpLmxlZ19pbmZvID8/IFtdKS5tYXAoKGxlZzogYW55LCBpOiBudW1iZXIpID0+ICh7XG4gICAgICBkaXJlY3Rpb246IGxlZy5MZWdEaXJlY3Rpb25hbGl0eSBhcyBzdHJpbmcsXG4gICAgICBhaXJsaW5lTmFtZTogKGxlZy5MZWdBaXJsaW5lc05hbWVzID8/IFtdKS5qb2luKCcsICcpLFxuICAgICAgY2FiaW46IGxlZy5MZWdDYWJpbnM/LlswXT8uTmFtZSA/PyAnJyxcbiAgICAgIGZyb206IGxlZy5MZWdEZXBhcnR1cmVBaXJwb3J0Q29kZSBhcyBzdHJpbmcsXG4gICAgICB0bzogbGVnLkxlZ0Fycml2YWxBaXJwb3J0Q29kZSBhcyBzdHJpbmcsXG4gICAgICBkZXBUaW1lOiBsZWcuTGVnRGVwYXJ0dXJlRGF0ZVRpbWUgYXMgc3RyaW5nLFxuICAgICAgYXJyVGltZTogbGVnLkxlZ0Fycml2YWxEYXRlVGltZSBhcyBzdHJpbmcsXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgc3RvcHM6IChsZWcuU3RvcHMgPz8gW10pIGFzIGFueVtdLFxuICAgICAgdG90YWxNaW51dGVzOiBiaS5kdXJhdGlvbj8ubGVncz8uW2ldPy5TZWdtZW50c1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICA/LnJlZHVjZSgoc3VtOiBudW1iZXIsIHM6IGFueSkgPT4gc3VtICsgKHMuU2VnbWVudEVsYXBzZWRUaW1lTWludXRlcyA/PyAwKSwgMCkgPz8gbnVsbCxcbiAgICAgIG9wZXJhdGVkQnk6IGxlZy5zdXBwbGllck5hbWUgPyBbbGVnLnN1cHBsaWVyTmFtZSBhcyBzdHJpbmddIDogW10sXG4gICAgfSkpO1xuICB9KTtcblxuICAvKipcbiAgICogVGhlIHJldHVybiBsZWcgaXMgbWF0Y2hlZCBieSBhbiBleHBsaWNpdCAnUmV0dXJuJyBkaXJlY3Rpb247IHRoZSBvbndhcmRcbiAgICogbGVnIGlzIHdoYXRldmVyJ3MgbGVmdCAoc29tZSBib29raW5ncyBkb24ndCB0YWcgdGhlIG91dGJvdW5kIGxlZyB3aXRoIGFuXG4gICAqIGV4cGxpY2l0ICdEZXBhcnR1cmUnIHZhbHVlKSwgZmFsbGluZyBiYWNrIHRvIHRoZSBmaXJzdCBlbnRyeS5cbiAgICovXG4gIGl0aW5lcmFyeUxlZyhraW5kOiAnb253YXJkJyB8ICdyZXR1cm4nKSB7XG4gICAgY29uc3QgbGVncyA9IHRoaXMuaXRpbmVyYXJ5TGVncygpO1xuICAgIGlmICghbGVncy5sZW5ndGgpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IHJldHVybkxlZyA9IGxlZ3MuZmluZCgobDogeyBkaXJlY3Rpb246IHN0cmluZyB9KSA9PiAobC5kaXJlY3Rpb24gPz8gJycpLnRvTG93ZXJDYXNlKCkgPT09ICdyZXR1cm4nKSA/PyBudWxsO1xuICAgIGlmIChraW5kID09PSAncmV0dXJuJykgcmV0dXJuIHJldHVybkxlZztcbiAgICByZXR1cm4gKFxuICAgICAgbGVncy5maW5kKChsOiB7IGRpcmVjdGlvbjogc3RyaW5nIH0pID0+IChsLmRpcmVjdGlvbiA/PyAnJykudG9Mb3dlckNhc2UoKSA9PT0gJ2RlcGFydHVyZScpID8/XG4gICAgICBsZWdzLmZpbmQoKGwpID0+IGwgIT09IHJldHVybkxlZykgPz9cbiAgICAgIGxlZ3NbMF0gPz9cbiAgICAgIG51bGxcbiAgICApO1xuICB9XG5cbiAgZm10VGltZShkdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIWR0KSByZXR1cm4gJ+KAlCc7XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBEYXRlKGR0KS50b0xvY2FsZVRpbWVTdHJpbmcoJ2VuLUdCJywgeyBob3VyOiAnMi1kaWdpdCcsIG1pbnV0ZTogJzItZGlnaXQnIH0pOyB9XG4gICAgY2F0Y2ggeyByZXR1cm4gZHQ7IH1cbiAgfVxuXG4gIGZtdFNob3J0RGF0ZShkdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIWR0KSByZXR1cm4gJ+KAlCc7XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBEYXRlKGR0KS50b0xvY2FsZURhdGVTdHJpbmcoJ2VuLUdCJywgeyB3ZWVrZGF5OiAnc2hvcnQnLCBkYXk6ICcyLWRpZ2l0JywgbW9udGg6ICdzaG9ydCcgfSk7IH1cbiAgICBjYXRjaCB7IHJldHVybiBkdDsgfVxuICB9XG5cbiAgZm10TWlucyhtaW5zOiBudW1iZXIgfCBudWxsKTogc3RyaW5nIHtcbiAgICBpZiAobWlucyA9PSBudWxsKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIGAke01hdGguZmxvb3IobWlucyAvIDYwKX1oICR7bWlucyAlIDYwfW1gO1xuICB9XG5cbiAgcmVmdW5kRGF0YSAgICAgPSBzaWduYWw8UmVmdW5kRGF0YSB8IG51bGw+KG51bGwpO1xuICBjYW5jZWxSZXN1bHQgICA9IHNpZ25hbDxSZWZ1bmREYXRhIHwgbnVsbD4obnVsbCk7XG4gIGxvYWRpbmcgICAgICAgID0gc2lnbmFsKGZhbHNlKTtcbiAgY2FuY2VsbGluZyAgICAgPSBzaWduYWwoZmFsc2UpO1xuICBjb25maXJtaW5nICAgICA9IHNpZ25hbChmYWxzZSk7XG4gIC8qKlxuICAgKiAnc2VsZWN0LWxlZycgc2hvd24gb25jZSB0aGUgcmVmdW5kIHByZXZpZXcgcmVzb2x2ZXMsIGZvciByb3VuZC10cmlwXG4gICAqIGJvb2tpbmdzIHRoZSBiYWNrZW5kIGhhc24ndCBhbHJlYWR5IHJlc3RyaWN0ZWQgdG8gYSBzaW5nbGUgbGVnIOKAlCBtaXJyb3JzXG4gICAqIGFsbWF0YXItYjJjJ3Mgc2VsZWN0LWxlZyBzY3JlZW4uIFNraXBwZWQgc3RyYWlnaHQgdG8gJ2RldGFpbHMnIG90aGVyd2lzZS5cbiAgICovXG4gIHN0ZXAgICAgICAgICAgID0gc2lnbmFsPCdsb2FkaW5nJyB8ICdzZWxlY3QtbGVnJyB8ICdkZXRhaWxzJz4oJ2xvYWRpbmcnKTtcbiAgLyoqIFBlci1sZWcgaW5jbHVzaW9uIChjaGVja2JveCkgYW5kIGV4cGFuZC9jb2xsYXBzZSBzdGF0ZSDigJQgcm91bmQtdHJpcCBvbmx5LiAqL1xuICBvbndhcmRDaGVja2VkICA9IHNpZ25hbCh0cnVlKTtcbiAgcmV0dXJuQ2hlY2tlZCAgPSBzaWduYWwodHJ1ZSk7XG4gIG9ud2FyZEV4cGFuZGVkID0gc2lnbmFsKHRydWUpO1xuICByZXR1cm5FeHBhbmRlZCA9IHNpZ25hbCh0cnVlKTtcbiAgc2VsZWN0ZWRTb3VyY2UgPSBzaWduYWw8c3RyaW5nPignJyk7XG4gIGNhbmNlbEhpbnQgICAgID0gc2lnbmFsPHN0cmluZz4oJycpO1xuICBwYWlkU3VtbWFyeUV4cGFuZGVkID0gc2lnbmFsKGZhbHNlKTtcbiAgcHJlZmVycmVkUmVmdW5kTWV0aG9kID0gc2lnbmFsPCd3YWxsZXQnIHwgJ29yaWdpbmFsUGF5bWVudE1ldGhvZCcgfCAnc3BsaXQnPignb3JpZ2luYWxQYXltZW50TWV0aG9kJyk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBDQU5DRUxfSElOVFMgPSBbXG4gICAgJ0xvYWRpbmcgeW91ciBkYXRhLi4uJyxcbiAgICAnRmV0Y2hpbmcgU2FicmUgZGF0YS4uLicsXG4gICAgJ0ZldGNoaW5nIEFUQyBkYXRhLi4uJyxcbiAgICAnQ2FsY3VsYXRpbmcgcmVmdW5kIGFtb3VudC4uLicsXG4gICAgJ1dlIGFyZSBhbG1vc3QgZG9uZSwgcGxlYXNlIHdhaXQuLi4nLFxuICBdO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBwcml2YXRlIGhpbnRUaW1lcjogYW55ID0gbnVsbDtcblxuICBoYXNPbndhcmQgID0gY29tcHV0ZWQoKCkgPT4gISF0aGlzLnJlZnVuZERhdGEoKT8ubGVnSW5mbz8ub253YXJkKTtcbiAgaGFzUmV0dXJuICA9IGNvbXB1dGVkKCgpID0+ICEhdGhpcy5yZWZ1bmREYXRhKCk/LmxlZ0luZm8/LnJldHVybik7XG4gIGlzUm91bmRUcmlwID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5oYXNPbndhcmQoKSAmJiB0aGlzLmhhc1JldHVybigpKTtcblxuICAvKiogV2hpY2ggbGVnKHMpIHRoZSBiYWNrZW5kIGFsbG93cyBjYW5jZWxsaW5nLCBmcm9tIHRoZSByZWZ1bmQgcHJldmlldyByZXNwb25zZS4gKi9cbiAgbGVnRGlyZWN0aW9uYWxpdHkgPSBjb21wdXRlZDwnT05XQVJEJyB8ICdSRVRVUk4nIHwgJ0JPVEgnIHwgdW5kZWZpbmVkPihcbiAgICAoKSA9PiB0aGlzLnJlZnVuZERhdGEoKT8ubGVnRGlyZWN0aW9uYWxpdHksXG4gICk7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gcmVuZGVyIHRoZSByb3VuZC10cmlwIFwidHdvIGxlZyBjYXJkc1wiIFVJLiBPbmx5IHdoZW4gdGhlXG4gICAqIGJhY2tlbmQgZXhwbGljaXRseSBhbGxvd3MgY2FuY2VsbGluZyBib3RoIGxlZ3Mg4oCUIG90aGVyd2lzZSAoT05XQVJELW9ubHkgL1xuICAgKiBSRVRVUk4tb25seSkgc2hvdyBhIHNpbmdsZSBjYXJkIGZvciB0aGF0IGxlZywgc2FtZSBhcyBhIG9uZS13YXkgYm9va2luZy5cbiAgICovXG4gIHNob3dSb3VuZFRyaXBMZWdDYXJkcyA9IGNvbXB1dGVkKFxuICAgICgpID0+IHRoaXMuaXNSb3VuZFRyaXAoKSAmJiAodGhpcy5sZWdEaXJlY3Rpb25hbGl0eSgpID8/ICdCT1RIJykgPT09ICdCT1RIJyxcbiAgKTtcblxuICAvKiogRGVyaXZlZCBmcm9tIHRoZSBwZXItbGVnIGNoZWNrYm94ZXMg4oCUICdib3RoJyB1bmxlc3MgZXhhY3RseSBvbmUgaXMgdW5jaGVja2VkLiAqL1xuICBzZWxlY3RlZExlZyA9IGNvbXB1dGVkPExlZ1NlbGVjdGlvbj4oKCkgPT4ge1xuICAgIGlmICghdGhpcy5pc1JvdW5kVHJpcCgpKSByZXR1cm4gJ2JvdGgnO1xuICAgIGNvbnN0IGRpciA9IHRoaXMubGVnRGlyZWN0aW9uYWxpdHkoKTtcbiAgICBpZiAoZGlyID09PSAnT05XQVJEJykgcmV0dXJuICdvbndhcmQnO1xuICAgIGlmIChkaXIgPT09ICdSRVRVUk4nKSByZXR1cm4gJ3JldHVybic7XG4gICAgY29uc3Qgb253YXJkID0gdGhpcy5vbndhcmRDaGVja2VkKCk7XG4gICAgY29uc3QgcmV0ID0gdGhpcy5yZXR1cm5DaGVja2VkKCk7XG4gICAgaWYgKG9ud2FyZCAmJiByZXQpIHJldHVybiAnYm90aCc7XG4gICAgcmV0dXJuIG9ud2FyZCA/ICdvbndhcmQnIDogJ3JldHVybic7XG4gIH0pO1xuXG4gIC8vIFJldHVybnMgdGhlIHNvdXJjZUJyZWFrZG93biBmb3IgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBsZWcgKG9yIHJvb3QgZm9yIFwiYm90aFwiKVxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBhY3RpdmVTb3VyY2VCcmVha2Rvd24gPSBjb21wdXRlZCgoKTogUmVjb3JkPHN0cmluZywgYW55PiB8IG51bGwgPT4ge1xuICAgIGNvbnN0IHNlbCA9IHRoaXMuc2VsZWN0ZWRMZWcoKTtcbiAgICBjb25zdCByb290ID0gdGhpcy5yZWZ1bmREYXRhKCk7XG4gICAgaWYgKCFyb290KSByZXR1cm4gbnVsbDtcbiAgICAvLyBBIGxlZy1zY29wZWQgdmlldyAoc2luZ2xlIGxlZywgb3IgYm90aCBsZWdzIHN1bW1lZCkgbXVzdCBub3QgZmFsbCBiYWNrXG4gICAgLy8gdG8gcm9vdC5zb3VyY2VCcmVha2Rvd24g4oCUIGl0cyB0b3RhbHMgYXJlIGZvciB0aGUgd2hvbGUvb3JpZ2luYWxcbiAgICAvLyBpdGluZXJhcnksIG5vdCBzY29wZWQgdG8gdGhlIGxlZyhzKSBhY3R1YWxseSBzaG93biwgYW5kIGFwcGx5aW5nIGl0XG4gICAgLy8gd291bGQgY2xvYmJlciB0aGUgY29ycmVjdGx5IGxlZy1zY29wZWQgdG90YWxzIGNvbXB1dGVkIGluXG4gICAgLy8gYGN1cnJlbnREYXRhKClgLlxuICAgIGlmIChzZWwgPT09ICdvbndhcmQnKSByZXR1cm4gcm9vdC5sZWdJbmZvPy5vbndhcmQ/LnNvdXJjZUJyZWFrZG93biA/PyBudWxsO1xuICAgIGlmIChzZWwgPT09ICdyZXR1cm4nKSByZXR1cm4gcm9vdC5sZWdJbmZvPy5yZXR1cm4/LnNvdXJjZUJyZWFrZG93biA/PyBudWxsO1xuICAgIGlmIChyb290LmxlZ0luZm8/Lm9ud2FyZCAmJiByb290LmxlZ0luZm8/LnJldHVybikgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHJvb3Quc291cmNlQnJlYWtkb3duID8/IG51bGw7XG4gIH0pO1xuXG4gIGF2YWlsYWJsZVNvdXJjZXMgPSBjb21wdXRlZCgoKTogc3RyaW5nW10gPT5cbiAgICBPYmplY3Qua2V5cyh0aGlzLmFjdGl2ZVNvdXJjZUJyZWFrZG93bigpID8/IHt9KVxuICApO1xuXG4gIGN1cnJlbnREYXRhID0gY29tcHV0ZWQ8UmVmdW5kRGF0YSB8IG51bGw+KCgpID0+IHtcbiAgICBjb25zdCByb290ID0gdGhpcy5yZWZ1bmREYXRhKCk7XG4gICAgaWYgKCFyb290KSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBzZWwgPSB0aGlzLnNlbGVjdGVkTGVnKCk7XG4gICAgaWYgKHNlbCA9PT0gJ29ud2FyZCcgJiYgcm9vdC5sZWdJbmZvPy5vbndhcmQpXG4gICAgICByZXR1cm4gdGhpcy5idWlsZExlZ0RhdGEocm9vdCwgcm9vdC5sZWdJbmZvLm9ud2FyZCwgJ29ud2FyZCcpO1xuICAgIGlmIChzZWwgPT09ICdyZXR1cm4nICYmIHJvb3QubGVnSW5mbz8ucmV0dXJuKVxuICAgICAgcmV0dXJuIHRoaXMuYnVpbGRMZWdEYXRhKHJvb3QsIHJvb3QubGVnSW5mby5yZXR1cm4sICdyZXR1cm4nKTtcbiAgICAvLyBQYXltZW50L3JlZnVuZCBmaWd1cmVzIGNvbWUgZnJvbSBgbGVnSW5mb2AsIG5ldmVyIHJvb3QgKHJvb3QgaXNuJ3RcbiAgICAvLyByZWxpYWJseSBzY29wZWQgdG8gd2hpY2hldmVyIGxlZyhzKSBlbmRlZCB1cCBzZWxlY3RlZCkg4oCUIGNvbWJpbmUgYm90aFxuICAgIC8vIGxlZ3Mgd2hlbiBib3RoIGFyZSBpbiBwbGF5LCBvdGhlcndpc2UgdXNlIHdoaWNoZXZlciBvbmUgZXhpc3RzLlxuICAgIGNvbnN0IG9ud2FyZCA9IHJvb3QubGVnSW5mbz8ub253YXJkO1xuICAgIGNvbnN0IHJldCA9IHJvb3QubGVnSW5mbz8ucmV0dXJuO1xuICAgIGlmIChvbndhcmQgJiYgcmV0KSByZXR1cm4gdGhpcy5idWlsZENvbWJpbmVkTGVnRGF0YShyb290LCBvbndhcmQsIHJldCk7XG4gICAgaWYgKG9ud2FyZCAmJiAhcmV0KSByZXR1cm4gdGhpcy5idWlsZExlZ0RhdGEocm9vdCwgb253YXJkLCAnb253YXJkJyk7XG4gICAgaWYgKHJldCAmJiAhb253YXJkKSByZXR1cm4gdGhpcy5idWlsZExlZ0RhdGEocm9vdCwgcmV0LCAncmV0dXJuJyk7XG4gICAgcmV0dXJuIHJvb3Q7XG4gIH0pO1xuXG4gIC8vIGN1cnJlbnREYXRhIHdpdGggc291cmNlLXNwZWNpZmljIHBlbmFsdHkvcmVmdW5kL3JlZnVuZGFiaWxpdHkgb3ZlcnJpZGVzIGFwcGxpZWRcbiAgYWRqdXN0ZWREYXRhID0gY29tcHV0ZWQ8UmVmdW5kRGF0YSB8IG51bGw+KCgpID0+IHtcbiAgICBjb25zdCBiYXNlID0gdGhpcy5jdXJyZW50RGF0YSgpO1xuICAgIGlmICghYmFzZSkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHRoaXMuYXBwbHlTb3VyY2VPdmVycmlkZShiYXNlLCB0aGlzLmFjdGl2ZVNvdXJjZUJyZWFrZG93bigpKTtcbiAgfSk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgcHJpdmF0ZSBhcHBseVNvdXJjZU92ZXJyaWRlKGJhc2U6IFJlZnVuZERhdGEsIGJyZWFrZG93bjogUmVjb3JkPHN0cmluZywgYW55PiB8IG51bGwpOiBSZWZ1bmREYXRhIHtcbiAgICBjb25zdCBzZWwgPSB0aGlzLnNlbGVjdGVkU291cmNlKCk7XG4gICAgaWYgKCFzZWwgfHwgIWJyZWFrZG93biB8fCAhYnJlYWtkb3duW3NlbF0pIHJldHVybiB0aGlzLnJlY29uY2lsZVNvbGVEZXN0aW5hdGlvbihiYXNlKTtcbiAgICBjb25zdCBzcmMgPSBicmVha2Rvd25bc2VsXTtcbiAgICBjb25zdCBzb3VyY2VSZWZ1bmRhYmxlID0gc3JjLmlzUmVmdW5kYWJsZSAhPT0gZmFsc2U7IC8vIGRlZmF1bHQgdHJ1ZSBpZiBub3Qgc2V0XG4gICAgaWYgKCFzb3VyY2VSZWZ1bmRhYmxlKSB7XG4gICAgICAvLyBTb3VyY2UgY2Fubm90IHByb2Nlc3MgcmVmdW5kIOKAlCB6ZXJvIG91dCBmaW5hbmNpYWwgZmllbGRzXG4gICAgICByZXR1cm4gdGhpcy5yZWNvbmNpbGVTb2xlRGVzdGluYXRpb24oe1xuICAgICAgICAuLi5iYXNlLFxuICAgICAgICBpc1JlZnVuZGFibGU6ICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgIHRvdGFsUGVuYWx0eVBvaW50czogICAgICAgICAwLFxuICAgICAgICB0b3RhbFN1cHBsaWVyUGVuYWx0eVBvaW50czogMCxcbiAgICAgICAgdG90YWxDYW5jZWxsYXRpb25GZWU6ICAgICAgIDAsXG4gICAgICAgIHRvdGFsUmVmdW5kQW1vdW50OiAgICAgICAgICAwLFxuICAgICAgICB0b3RhbENhcmRSZWZ1bmRBbW91bnQ6ICAgICAgMCxcbiAgICAgICAgaGFuZGxpbmdGZWU6ICAgICAgICAgICAgICAgIDAsXG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gUHJlZmVyIHRoZSBzb3VyY2UncyBvd24gd2FsbGV0UmVmdW5kQW1vdW50L3RvdGFsQ2FyZFJlZnVuZEFtb3VudCB3aGVuXG4gICAgLy8gdGhlIEFQSSBwcm92aWRlcyB0aGVtICh0aGV5J3JlIGFscmVhZHkgbmV0IG9mIGVhY2ggb3RoZXIgZm9yIHRoaXNcbiAgICAvLyBzb3VyY2UpIOKAlCBvbmx5IGZhbGwgYmFjayB0byBkZXJpdmluZyBjYXJkUmVmdW5kIHdoZW4gdGhlIEFQSSBkb2Vzbid0LlxuICAgIGNvbnN0IG5ld1RvdGFsICAgICAgPSBOdW1iZXIoc3JjLnRvdGFsUmVmdW5kQW1vdW50IHx8IDApO1xuICAgIGNvbnN0IHdhbGxldFJlZnVuZCAgPVxuICAgICAgc3JjLndhbGxldFJlZnVuZEFtb3VudCAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gTnVtYmVyKHNyYy53YWxsZXRSZWZ1bmRBbW91bnQgfHwgMClcbiAgICAgICAgOiBOdW1iZXIoYmFzZS53YWxsZXRSZWZ1bmRBbW91bnQgfHwgMCk7XG4gICAgY29uc3QgY2FyZFJlZnVuZCAgICA9XG4gICAgICBzcmMudG90YWxDYXJkUmVmdW5kQW1vdW50ICE9PSB1bmRlZmluZWRcbiAgICAgICAgPyBOdW1iZXIoc3JjLnRvdGFsQ2FyZFJlZnVuZEFtb3VudCB8fCAwKVxuICAgICAgICA6IE1hdGgubWF4KFxuICAgICAgICAgICAgMCxcbiAgICAgICAgICAgIG5ld1RvdGFsIC1cbiAgICAgICAgICAgICAgTnVtYmVyKGJhc2UudG90YWxDcmVkaXRSZWZ1bmRBbW91bnQgfHwgMCkgLVxuICAgICAgICAgICAgICB3YWxsZXRSZWZ1bmQgLVxuICAgICAgICAgICAgICBOdW1iZXIoYmFzZS50b3RhbExveWFsdHlQb2ludHNSZWZ1bmRBbW91bnQgfHwgMCksXG4gICAgICAgICAgKTtcbiAgICByZXR1cm4gdGhpcy5yZWNvbmNpbGVTb2xlRGVzdGluYXRpb24oe1xuICAgICAgLi4uYmFzZSxcbiAgICAgIGlzUmVmdW5kYWJsZTogICAgICAgICAgICAgICB0cnVlLFxuICAgICAgdG90YWxQZW5hbHR5UG9pbnRzOiAgICAgICAgIE51bWJlcihzcmMudG90YWxTdXBwbGllclBlbmFsdHlQb2ludHMgfHwgMCksXG4gICAgICB0b3RhbFN1cHBsaWVyUGVuYWx0eVBvaW50czogTnVtYmVyKHNyYy50b3RhbFN1cHBsaWVyUGVuYWx0eVBvaW50cyB8fCAwKSxcbiAgICAgIHRvdGFsQ2FuY2VsbGF0aW9uRmVlOiAgICAgICBOdW1iZXIoc3JjLnRvdGFsQ2FuY2VsbGF0aW9uRmVlIHx8IDApLFxuICAgICAgdG90YWxSZWZ1bmRBbW91bnQ6ICAgICAgICAgIG5ld1RvdGFsLFxuICAgICAgd2FsbGV0UmVmdW5kQW1vdW50OiAgICAgICAgIHdhbGxldFJlZnVuZCxcbiAgICAgIHRvdGFsQ2FyZFJlZnVuZEFtb3VudDogICAgICBjYXJkUmVmdW5kLFxuICAgICAgaGFuZGxpbmdGZWU6ICAgICAgICAgICAgICAgIE51bWJlcihzcmMuaGFuZGxpbmdGZWUgfHwgMCksXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogV2hlbiBleGFjdGx5IG9uZSBvZiB0aGUgZm91ciByZWZ1bmQtZGVzdGluYXRpb24gZmllbGRzICh3YWxsZXQgLyBjYXJkIC9cbiAgICogY3JlZGl0IC8gbG95YWx0eSkgaXMgbm9uLXplcm8sIHRoZSBiYWNrZW5kIGhhcyBvY2Nhc2lvbmFsbHkgc2VudCB0aGF0XG4gICAqIGZpZWxkIGFzIGEgcHJlLWRlZHVjdGlvbiB2YWx1ZSB0aGF0IGRpc2FncmVlcyB3aXRoIHRoZSBkZWNsYXJlZCB0b3RhbFxuICAgKiAoZS5nLiB3YWxsZXQgPSB0b3RhbCArIGNhbmNlbGxhdGlvbiBmZWUpIOKAlCB0aGVyZSdzIG5vIGFtYmlndWl0eSBhYm91dFxuICAgKiAqd2hlcmUqIHRoZSBtb25leSBnb2VzLCBvbmx5IGEgc3RhbGUgbnVtYmVyIGluIHRoYXQgb25lIGZpZWxkLCBzbyB0cnVzdFxuICAgKiB0aGUgZGVjbGFyZWQgdG90YWwgYW5kIGNvcnJlY3QgdGhlIHNvbGUgZGVzdGluYXRpb24gdG8gbWF0Y2ggcmF0aGVyXG4gICAqIHRoYW4gc3VyZmFjaW5nIGEgZmFsc2UgZGlzY3JlcGFuY3kuXG4gICAqL1xuICBwcml2YXRlIHJlY29uY2lsZVNvbGVEZXN0aW5hdGlvbihkOiBSZWZ1bmREYXRhKTogUmVmdW5kRGF0YSB7XG4gICAgaWYgKCFkPy5pc1JlZnVuZGFibGUpIHJldHVybiBkO1xuICAgIGNvbnN0IHdhbGxldCAgPSBOdW1iZXIoZC53YWxsZXRSZWZ1bmRBbW91bnQgPz8gMCk7XG4gICAgY29uc3QgY2FyZCAgICA9IE51bWJlcihkLnRvdGFsQ2FyZFJlZnVuZEFtb3VudCA/PyAwKTtcbiAgICBjb25zdCBjcmVkaXQgID0gTnVtYmVyKGQudG90YWxDcmVkaXRSZWZ1bmRBbW91bnQgPz8gMCk7XG4gICAgY29uc3QgbG95YWx0eSA9IE51bWJlcihkLnRvdGFsTG95YWx0eVBvaW50c1JlZnVuZEFtb3VudCA/PyAwKTtcbiAgICAvLyBBIGZvcmZlaXRlZC1wb2ludHMgZGVzdGluYXRpb24gKGUuZy4gUWl0YWYgcG9pbnRzIGZ1bmRlZCBzZXBhcmF0ZWx5XG4gICAgLy8gZnJvbSB0aGUgY2FyZCByZWZ1bmQpIGFsc28gY291bnRzIGFzIGEgcmVhbCBkZXN0aW5hdGlvbiBoZXJlIOKAlCB3aXRob3V0XG4gICAgLy8gdGhpcywgYSBsZWdpdGltYXRlbHkgc3BsaXQgY2FyZCtsb3lhbHR5LXBvaW50cyByZWZ1bmQgKGUuZy4gOTE4IGNhcmQgK1xuICAgIC8vIDUwIFFpdGFmIHBvaW50cyA9IDk2OCB0b3RhbCkgbG9va3MgbGlrZSBhIHNpbmdsZSBzdGFsZSBcImNhcmRcIiBmaWVsZCB0b1xuICAgIC8vIHRoaXMgaGV1cmlzdGljLCB3aGljaCB0aGVuIGZvcmNlLW92ZXJ3cml0ZXMgdGhlIGNvcnJlY3QgOTE4IHdpdGggdGhlXG4gICAgLy8gZnVsbCA5NjggdG90YWwgYW5kIHNpbGVudGx5IGVyYXNlcyB0aGUgc3BsaXQuXG4gICAgY29uc3QgZm9yZmVpdGVkTG95YWx0eSA9IHRoaXMuZm9yZmVpdGVkTG95YWx0eVBvaW50c0ZhbGxiYWNrKGQpO1xuICAgIGNvbnN0IG5vblplcm8gPSBbd2FsbGV0LCBjYXJkLCBjcmVkaXQsIGxveWFsdHksIGZvcmZlaXRlZExveWFsdHldLmZpbHRlcigodikgPT4gdiA+IDApO1xuICAgIGlmIChub25aZXJvLmxlbmd0aCAhPT0gMSkgcmV0dXJuIGQ7XG4gICAgY29uc3QgdG90YWwgPSBOdW1iZXIoZC50b3RhbFJlZnVuZEFtb3VudEJlZm9yZUNlaWwgPz8gZC50b3RhbFJlZnVuZEFtb3VudCA/PyAwKTtcbiAgICBpZiAod2FsbGV0ID4gMCAmJiBNYXRoLmFicyh3YWxsZXQgLSB0b3RhbCkgPj0gMC4wMSkgcmV0dXJuIHsgLi4uZCwgd2FsbGV0UmVmdW5kQW1vdW50OiB0b3RhbCB9O1xuICAgIGlmIChjYXJkID4gMCAmJiBNYXRoLmFicyhjYXJkIC0gdG90YWwpID49IDAuMDEpIHJldHVybiB7IC4uLmQsIHRvdGFsQ2FyZFJlZnVuZEFtb3VudDogdG90YWwgfTtcbiAgICBpZiAoY3JlZGl0ID4gMCAmJiBNYXRoLmFicyhjcmVkaXQgLSB0b3RhbCkgPj0gMC4wMSkgcmV0dXJuIHsgLi4uZCwgdG90YWxDcmVkaXRSZWZ1bmRBbW91bnQ6IHRvdGFsIH07XG4gICAgaWYgKGxveWFsdHkgPiAwICYmIE1hdGguYWJzKGxveWFsdHkgLSB0b3RhbCkgPj0gMC4wMSkgcmV0dXJuIHsgLi4uZCwgdG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50OiB0b3RhbCB9O1xuICAgIHJldHVybiBkO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlci1sZWcgcmVmdW5kIHZpZXcgKGluZGVwZW5kZW50IG9mIHRoZSBjaGVja2JveCBpbmNsdXNpb24gc3RhdGUpIOKAlCB1c2VkXG4gICAqIHRvIHJlbmRlciBib3RoIGxlZ3MnIG93biBicmVha2Rvd24gY2FyZHMgc2ltdWx0YW5lb3VzbHkuXG4gICAqL1xuICBsZWdBZGp1c3RlZERhdGEobGVnVHlwZTogJ29ud2FyZCcgfCAncmV0dXJuJyk6IFJlZnVuZERhdGEgfCBudWxsIHtcbiAgICBjb25zdCByb290ID0gdGhpcy5yZWZ1bmREYXRhKCk7XG4gICAgY29uc3QgbGVnID0gcm9vdD8ubGVnSW5mbz8uW2xlZ1R5cGVdO1xuICAgIGlmICghcm9vdCB8fCAhbGVnKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBiYXNlID0gdGhpcy5idWlsZExlZ0RhdGEocm9vdCwgbGVnLCBsZWdUeXBlKTtcbiAgICByZXR1cm4gdGhpcy5hcHBseVNvdXJjZU92ZXJyaWRlKGJhc2UsIGxlZy5zb3VyY2VCcmVha2Rvd24gPz8gbnVsbCk7XG4gIH1cblxuICAvKiogRGVkdWN0aW9uIHJvd3MgZm9yIGEgc2luZ2xlIGxlZydzIGNhcmQuICovXG4gIGxlZ0RlZHVjdGlvbnMobGVnVHlwZTogJ29ud2FyZCcgfCAncmV0dXJuJykge1xuICAgIHJldHVybiB0aGlzLmRlZHVjdGlvblJvd3ModGhpcy5sZWdBZGp1c3RlZERhdGEobGVnVHlwZSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZnVuZGFibGUgcG9vbCAoXCJGYXJlXCIpIGZvciBhIGxlZyDigJQgdGhhdCBsZWcncyBvd24gcGFpZCBhbW91bnRcbiAgICogKGB0b3RhbFN1cHBsaWVyQm9va2luZ0Ftb3VudGApLiBgdG90YWxSZWZ1bmRBbW91bnQgKyB0b3RhbENhbmNlbGxhdGlvbkZlZWBcbiAgICogaXNuJ3QgcmVsaWFibGU6IGB0b3RhbENhbmNlbGxhdGlvbkZlZWAgZG9lc24ndCBpbmNsdWRlIGV2ZXJ5IGRlZHVjdGlvblxuICAgKiAoZS5nLiBgaGFuZGxpbmdGZWVgKSwgd2hpY2ggcHJvZHVjZWQgYSBGYXJlIHRoYXQgZGlkbid0IHJlY29uY2lsZSB3aXRoXG4gICAqIFRvdGFsIFJlZnVuZCArIHRoZSBzaG93biBkZWR1Y3Rpb25zLlxuICAgKi9cbiAgbGVnUmVmdW5kUG9vbChsZWdUeXBlOiAnb253YXJkJyB8ICdyZXR1cm4nKTogbnVtYmVyIHtcbiAgICBjb25zdCBkID0gdGhpcy5sZWdBZGp1c3RlZERhdGEobGVnVHlwZSk7XG4gICAgaWYgKCFkKSByZXR1cm4gMDtcbiAgICByZXR1cm4gTnVtYmVyKGQudG90YWxTdXBwbGllckJvb2tpbmdBbW91bnQgfHwgMCk7XG4gIH1cblxuICAvKiogVHJ1ZSBvbmNlIGEgbGVnJ3Mgb3duIGRlcGFydHVyZSB0aW1lIGhhcyBwYXNzZWQuICovXG4gIGxlZ0FscmVhZHlGbG93bihsZWdUeXBlOiAnb253YXJkJyB8ICdyZXR1cm4nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZGVwVGltZSA9IHRoaXMuaXRpbmVyYXJ5TGVnKGxlZ1R5cGUpPy5kZXBUaW1lO1xuICAgIGlmICghZGVwVGltZSkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IHQgPSBuZXcgRGF0ZShkZXBUaW1lKS5nZXRUaW1lKCk7XG4gICAgcmV0dXJuICFOdW1iZXIuaXNOYU4odCkgJiYgdCA8IERhdGUubm93KCk7XG4gIH1cblxuICAvKipcbiAgICogTm9uLUNyb3NzU2VsbGVyIGFpcmxpbmVzIHJlcXVpcmUgdGhlIHdob2xlIHJvdW5kLXRyaXAvbXVsdGljaXR5XG4gICAqIGl0aW5lcmFyeSB0byBiZSBjYW5jZWxsZWQgdG9nZXRoZXIg4oCUIGEgbGVnIGNhbid0IGJlIGV4Y2x1ZGVkIG9uIGl0cyBvd25cbiAgICogdW5sZXNzIGl0IGhhcyBhbHJlYWR5IGZsb3duICh3aGljaCBuYXR1cmFsbHkgZGVncmFkZXMgdG8gYSBvbmUtd2F5XG4gICAqIGNhbmNlbGxhdGlvbiBvZiBqdXN0IHRoZSByZW1haW5pbmcgbGVnKS4gU2V0IHdoZW4gYW4gdW5jaGVjayBhdHRlbXB0IHdhc1xuICAgKiBibG9ja2VkIGZvciB0aGlzIHJlYXNvbiwgc28gdGhlIGxlZydzIGNoZWNrYm94IGNhbiBiZSBmcm96ZW4gKGxvY2tlZClcbiAgICogYW5kIHRoZSBub3RlIHNob3duLlxuICAgKi9cbiAgZm9yY2VkTGVnVHlwZSA9IHNpZ25hbDwnb253YXJkJyB8ICdyZXR1cm4nIHwgbnVsbD4obnVsbCk7XG5cbiAgLyoqXG4gICAqIFRvZ2dsZSBhIGxlZydzIGluY2x1c2lvbi4gQSBub24tcmVmdW5kYWJsZSBsZWcgY2FuJ3QgYmUgY2hlY2tlZCwgYW5kIHRoZVxuICAgKiBsYXN0IGNoZWNrZWQgbGVnIGNhbid0IGJlIHVuY2hlY2tlZC4gVXNlZCBvbiBib3RoIHRoZSBzZWxlY3QtbGVnIHNjcmVlblxuICAgKiBhbmQgdGhlIHJvdW5kLXRyaXAgbGVnIGNhcmRzLlxuICAgKi9cbiAgdG9nZ2xlTGVnKGxlZ1R5cGU6ICdvbndhcmQnIHwgJ3JldHVybicpIHtcbiAgICBjb25zdCByZWZ1bmRhYmxlID0gbGVnVHlwZSA9PT0gJ29ud2FyZCcgPyB0aGlzLm9ud2FyZFJlZnVuZGFibGUoKSA6IHRoaXMucmV0dXJuUmVmdW5kYWJsZSgpO1xuICAgIGlmICghcmVmdW5kYWJsZSkgcmV0dXJuO1xuICAgIGNvbnN0IHNlbGYgPSBsZWdUeXBlID09PSAnb253YXJkJyA/IHRoaXMub253YXJkQ2hlY2tlZCA6IHRoaXMucmV0dXJuQ2hlY2tlZDtcbiAgICBjb25zdCBvdGhlciA9IGxlZ1R5cGUgPT09ICdvbndhcmQnID8gdGhpcy5yZXR1cm5DaGVja2VkIDogdGhpcy5vbndhcmRDaGVja2VkO1xuICAgIGlmIChzZWxmKCkgJiYgIW90aGVyKCkpIHJldHVybjtcblxuICAgIGNvbnN0IGlzVHVybmluZ09mZiA9IHNlbGYoKTtcbiAgICBpZiAoXG4gICAgICBpc1R1cm5pbmdPZmYgJiZcbiAgICAgIHRoaXMuaXNSb3VuZFRyaXAoKSAmJlxuICAgICAgIXRoaXMuaXNDcm9zc1NlbGxlcigpICYmXG4gICAgICAhdGhpcy5sZWdBbHJlYWR5Rmxvd24obGVnVHlwZSlcbiAgICApIHtcbiAgICAgIC8vIEFpcmxpbmUgZG9lc24ndCBhbGxvdyBjYW5jZWxsaW5nIHRoaXMgbGVnIG9uIGl0cyBvd24g4oCUIGJsb2NrIHRoZVxuICAgICAgLy8gdW5jaGVjaywga2VlcCBpdCBjaGVja2VkK2Zyb3plbiwgYW5kIHN1cmZhY2UgdGhlIG5vdGUuXG4gICAgICB0aGlzLmZvcmNlZExlZ1R5cGUuc2V0KGxlZ1R5cGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmZvcmNlZExlZ1R5cGUuc2V0KG51bGwpO1xuICAgIHNlbGYuc2V0KCFzZWxmKCkpO1xuICAgIC8vIEEgbGVnIG1heSBjYXJyeSBpdHMgb3duIHNvdXJjZSBsaXN0IOKAlCByZS1yZXNvbHZlIHRoZSBzZWxlY3Rpb24uXG4gICAgY29uc3QgYnJlYWtkb3duID0gdGhpcy5hY3RpdmVTb3VyY2VCcmVha2Rvd24oKSA/PyB7fTtcbiAgICBjb25zdCBzb3VyY2VzID0gT2JqZWN0LmtleXMoYnJlYWtkb3duKTtcbiAgICBpZiAoc291cmNlcy5sZW5ndGggJiYgIWJyZWFrZG93blt0aGlzLnNlbGVjdGVkU291cmNlKCldKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkU291cmNlLnNldChzb3VyY2VzWzBdKTtcbiAgICB9XG4gIH1cblxuICAvKiogVG9nZ2xlIGEgbGVnIGNhcmQncyBleHBhbmRlZC9jb2xsYXBzZWQgc3RhdGUuICovXG4gIHRvZ2dsZUxlZ0V4cGFuZGVkKGxlZ1R5cGU6ICdvbndhcmQnIHwgJ3JldHVybicpIHtcbiAgICBjb25zdCBzaWcgPSBsZWdUeXBlID09PSAnb253YXJkJyA/IHRoaXMub253YXJkRXhwYW5kZWQgOiB0aGlzLnJldHVybkV4cGFuZGVkO1xuICAgIHNpZy5zZXQoIXNpZygpKTtcbiAgfVxuXG4gIHNvdXJjZU5vblJlZnVuZGFibGVIaW50ID0gY29tcHV0ZWQoKCk6IHN0cmluZyA9PiB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5zZWxlY3RlZFNvdXJjZSgpO1xuICAgIGlmICghc2VsKSByZXR1cm4gJyc7XG4gICAgY29uc3Qgc3JjID0gKHRoaXMuYWN0aXZlU291cmNlQnJlYWtkb3duKCkgPz8ge30pW3NlbF07XG4gICAgaWYgKCFzcmMgfHwgc3JjLmlzUmVmdW5kYWJsZSAhPT0gZmFsc2UpIHJldHVybiAnJztcbiAgICByZXR1cm4gYENhbmNlbGxhdGlvbiB2aWEgJHtzZWx9IGlzIG5vdCBlbGlnaWJsZSBmb3IgYSByZWZ1bmQuIFBsZWFzZSBzZWxlY3QgYSBkaWZmZXJlbnQgc291cmNlLmA7XG4gIH0pO1xuXG4gIGRlZHVjdGlvbnMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmRlZHVjdGlvblJvd3ModGhpcy5hZGp1c3RlZERhdGEoKSkpO1xuXG4gIC8qKlxuICAgKiBJdGVtaXplZCByZWZ1bmRhYmxlIHJvd3MgKFwiRmFyZVwiICsgbmFtZWQgcmVmdW5kYWJsZSBhZGQtb25zL2FuY2lsbGFyaWVzKVxuICAgKiBmcm9tIGByZWZ1bmRCcmVha2Rvd24ucmVmdW5kYWJsZWAuIEVtcHR5IHdoZW4gdGhlIGJhY2tlbmQgaGFzbid0IHNlbnQgYVxuICAgKiBicmVha2Rvd24geWV0IOKAlCBjYWxsZXJzIGZhbGwgYmFjayB0byB0aGUgc2luZ2xlIGFnZ3JlZ2F0ZSBGYXJlIHJvdy5cbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIHJlZnVuZGFibGVCcmVha2Rvd25Sb3dzKGQ6IGFueSk6IHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IG51bWJlciB9W10ge1xuICAgIGNvbnN0IGIgPSBkPy5yZWZ1bmRCcmVha2Rvd24/LnJlZnVuZGFibGU7XG4gICAgaWYgKCFiKSByZXR1cm4gW107XG4gICAgLy8gRmFyZSBhbHdheXMgc2hvd3MgZnJvbSByZWZ1bmRCcmVha2Rvd24ucmVmdW5kYWJsZS5mYXJlLCBldmVuIHdoZW4gMCDigJRcbiAgICAvLyBuZXZlciBmYWxscyBiYWNrIHRvIG9yaWdpbmFsQW1vdW50LlxuICAgIGNvbnN0IHJvd3M6IHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IG51bWJlciB9W10gPSBbeyBsYWJlbDogJ0ZhcmUnLCB2YWx1ZTogTnVtYmVyKGIuZmFyZSA/PyAwKSB9XTtcbiAgICBbLi4uKGIuYWRkT25zID8/IFtdKSwgLi4uKGIuYW5jaWxsYXJpZXMgPz8gW10pXVxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgIC5maWx0ZXIoKGl0ZW06IGFueSkgPT4gTnVtYmVyKGl0ZW0uYW1vdW50KSA+IDApXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgLmZvckVhY2goKGl0ZW06IGFueSkgPT4gcm93cy5wdXNoKHsgbGFiZWw6IGl0ZW0ubmFtZSwgdmFsdWU6IE51bWJlcihpdGVtLmFtb3VudCkgfSkpO1xuICAgIHJldHVybiByb3dzO1xuICB9XG5cbiAgLyoqIE5hbWVkIHJlZnVuZGFibGUgYWRkLW9ucy9hbmNpbGxhcmllcyBvbmx5IChleGNsdWRlcyBGYXJlKSDigJQgZHJpdmVzIHRoZSBcInByb2Nlc3NlZCBzZXBhcmF0ZWx5XCIgbm90ZS4gKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgcHJpdmF0ZSByZWZ1bmRhYmxlQWRkb25JdGVtcyhkOiBhbnkpOiBhbnlbXSB7XG4gICAgLy8gT25seSBgYWRkT25zYCBuZWVkIG1hbnVhbCBDdXN0b21lciBTZXJ2aWNlIHByb2Nlc3Npbmcg4oCUIGBhbmNpbGxhcmllc2BcbiAgICAvLyAoYmFnZ2FnZSwgc2VhdCwgYXV0byBjaGVjay1pbiwg4oCmKSBhcmUgYWxyZWFkeSBpdGVtaXplZC9yZWZ1bmRlZFxuICAgIC8vIGF1dG9tYXRpY2FsbHkgYXMgcGFydCBvZiB0aGUgdG90YWwsIG5vIHNlcGFyYXRlIG5vdGUgbmVlZGVkIGZvciB0aGVtLlxuICAgIGNvbnN0IGIgPSBkPy5yZWZ1bmRCcmVha2Rvd24/LnJlZnVuZGFibGU7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICByZXR1cm4gKGI/LmFkZE9ucyA/PyBbXSkuZmlsdGVyKChpdGVtOiBhbnkpID0+IE51bWJlcihpdGVtLmFtb3VudCkgPiAwKTtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIHRvIHNob3cgdGhlIFwiYWRkLW9uIHJlZnVuZCBwcm9jZXNzZWQgc2VwYXJhdGVseSBieSBDdXN0b21lciBTZXJ2aWNlXCIgbm90ZS4gKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgaGFzUmVmdW5kYWJsZUFkZG9uTm90ZShkOiBhbnkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yZWZ1bmRhYmxlQWRkb25JdGVtcyhkKS5sZW5ndGggPiAwO1xuICB9XG5cbiAgLyoqXG4gICAqIERlZHVjdGlvbiByb3dzIGZvciB0aGUgXCJOb3QgUmVmdW5kZWRcIiBzZWN0aW9uLiBXaGVuIGFuIGl0ZW1pemVkXG4gICAqIGJyZWFrZG93biBpcyBwcmVzZW50LCBpdHMgbmFtZWQgYWRkLW9ucy9hbmNpbGxhcmllcyByZXBsYWNlIHRoZVxuICAgKiBhZ2dyZWdhdGUgYHRvdGFsQW5jaWxsYXJ5UmVmdW5kQW1vdW50YC9gdG90YWxHaWZ0QW1vdW50YCByb3dzIChzYW1lXG4gICAqIG1vbmV5LCBuYW1lZCBpbnN0ZWFkIG9mIGx1bXBlZCk7IHRoZSBvdGhlciBnZW5lcmljIHJvd3MgKGNhbmNlbGxhdGlvblxuICAgKiBmZWUsIGhhbmRsaW5nIGZlZSwgc2VydmljZSBjaGFyZ2UpIGFyZSB1bmFmZmVjdGVkLlxuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgcHJpdmF0ZSBkZWR1Y3Rpb25Sb3dzKGQ6IGFueSk6IHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IG51bWJlcjsgYmFkZ2U6IHN0cmluZyB9W10ge1xuICAgIGlmICghZCkgcmV0dXJuIFtdO1xuICAgIGNvbnN0IGIgPSBkLnJlZnVuZEJyZWFrZG93bj8ubm9uUmVmdW5kYWJsZTtcbiAgICBpZiAoIWIpIHtcbiAgICAgIHJldHVybiBERURVQ1RJT05fREVGU1xuICAgICAgICAuZmlsdGVyKGRlZiA9PiBOdW1iZXIoZFtkZWYua2V5XSkgPiAwKVxuICAgICAgICAubWFwKGRlZiA9PiAoeyBsYWJlbDogZGVmLmxhYmVsLCB2YWx1ZTogTnVtYmVyKGRbZGVmLmtleV0pLCBiYWRnZTogZGVmLmJhZGdlIH0pKTtcbiAgICB9XG4gICAgY29uc3QgaXRlbVJvd3MgPSBbLi4uKGIuYWRkT25zID8/IFtdKSwgLi4uKGIuYW5jaWxsYXJpZXMgPz8gW10pXVxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgIC5maWx0ZXIoKGl0ZW06IGFueSkgPT4gTnVtYmVyKGl0ZW0uYW1vdW50KSA+IDApXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgLm1hcCgoaXRlbTogYW55KSA9PiAoeyBsYWJlbDogaXRlbS5uYW1lLCB2YWx1ZTogTnVtYmVyKGl0ZW0uYW1vdW50KSwgYmFkZ2U6ICcnIH0pKTtcbiAgICBjb25zdCBhZ2dyZWdhdGVSb3dzID0gREVEVUNUSU9OX0RFRlNcbiAgICAgIC5maWx0ZXIoZGVmID0+IGRlZi5rZXkgIT09ICd0b3RhbEFuY2lsbGFyeVJlZnVuZEFtb3VudCcgJiYgZGVmLmtleSAhPT0gJ3RvdGFsR2lmdEFtb3VudCcpXG4gICAgICAuZmlsdGVyKGRlZiA9PiBOdW1iZXIoZFtkZWYua2V5XSkgPiAwKVxuICAgICAgLm1hcChkZWYgPT4gKHsgbGFiZWw6IGRlZi5sYWJlbCwgdmFsdWU6IE51bWJlcihkW2RlZi5rZXldKSwgYmFkZ2U6IGRlZi5iYWRnZSB9KSk7XG4gICAgcmV0dXJuIFsuLi5pdGVtUm93cywgLi4uYWdncmVnYXRlUm93c107XG4gIH1cblxuICByZWZ1bmRzID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGQgPSB0aGlzLmFkanVzdGVkRGF0YSgpO1xuICAgIGlmICghZCkgcmV0dXJuIFtdO1xuICAgIGNvbnN0IGlzTG95YWx0eSA9IHRoaXMuaXNMb3lhbHR5TWV0aG9kKCk7XG4gICAgY29uc3QgcGF5bWVudExhYmVsID0gdGhpcy5jdXN0b21lclBheW1lbnRMYWJlbCgpO1xuICAgIGNvbnN0IHJvd3MgPSBSRUZVTkRfREVGU1xuICAgICAgLmZpbHRlcihkZWYgPT4gTnVtYmVyKGRbZGVmLmtleV0pID4gMClcbiAgICAgIC5tYXAoZGVmID0+ICh7XG4gICAgICAgIC8vIFdhbGxldCByb3cgYWx3YXlzIHJlYWRzIFwiQWxtYXRhciBXYWxsZXRcIiAoZGVmLmxhYmVsKSDigJQgdGhlIGxveWFsdHlcbiAgICAgICAgLy8gcHJvZ3JhbSB0aGF0IGZ1bmRlZCBpdCBnZXRzIGl0cyBvd24gZGVkaWNhdGVkIHJvdyBiZWxvdyB2aWFcbiAgICAgICAgLy8gYGZvcmZlaXRlZExveWFsdHlQb2ludHNGYWxsYmFja2AsIHNvIHRoZSB0d28gc3RheSB2aXN1YWxseVxuICAgICAgICAvLyBkaXN0aW5jdCBpbnN0ZWFkIG9mIG1lcmdpbmcgaW50byBvbmUgbGFiZWwuXG4gICAgICAgIC8vIENhcmQgcm93OiBjYXJkL2xveWFsdHkgc3RheSBkaXN0aW5jdCDigJQgZG9uJ3QgcmVsYWJlbCB0aGUgY2FyZFxuICAgICAgICAvLyBwb3J0aW9uIHdpdGggdGhlIGxveWFsdHkgcHJvZ3JhbSBuYW1lIHRvbywgYW5kIG5ldmVyIHN1cmZhY2UgYW5cbiAgICAgICAgLy8gaW50ZXJuYWwgcHJvY2Vzc29yIG5hbWUgKGVtcHR5IGBwYXltZW50TGFiZWxgIGZhbGxzIGJhY2sgdG8gdGhlXG4gICAgICAgIC8vIGdlbmVyaWMgZGVmLmxhYmVsLCBlLmcuIFwiUmVmdW5kIEFtb3VudFwiKS5cbiAgICAgICAgbGFiZWw6XG4gICAgICAgICAgZGVmLmtleSA9PT0gJ3RvdGFsQ2FyZFJlZnVuZEFtb3VudCcgJiYgIWlzTG95YWx0eSAmJiBwYXltZW50TGFiZWxcbiAgICAgICAgICAgID8gYCR7ZGVmLmxhYmVsfSAke3BheW1lbnRMYWJlbH1gXG4gICAgICAgICAgICA6IGRlZi5sYWJlbCxcbiAgICAgICAgdmFsdWU6IE51bWJlcihkW2RlZi5rZXldKSxcbiAgICAgIH0pKTtcbiAgICBjb25zdCBmb3JmZWl0ZWRMb3lhbHR5ID0gdGhpcy5mb3JmZWl0ZWRMb3lhbHR5UG9pbnRzRmFsbGJhY2soZCk7XG4gICAgaWYgKGZvcmZlaXRlZExveWFsdHkgPiAwKSB7XG4gICAgICByb3dzLnB1c2goeyBsYWJlbDogdGhpcy53YWxsZXRPckxveWFsdHlMYWJlbChkKSwgdmFsdWU6IGZvcmZlaXRlZExveWFsdHkgfSk7XG4gICAgfVxuICAgIHJldHVybiByb3dzO1xuICB9KTtcblxuICBjcmVkaXRTaGVsbE5vdGUgPSBjb21wdXRlZCgoKTogc3RyaW5nID0+IHtcbiAgICAvLyBHb2xkZW4gR3VhcmFudGVlIG92ZXJyaWRlcyBjcmVkaXQtc2hlbGwgbWVzc2FnaW5nIGVudGlyZWx5IOKAlCB0aGVcbiAgICAvLyBkZWRpY2F0ZWQgc3VjY2VzcyBub3RpY2UgKGBnb2xkZW5HdWFyYW50ZWVOb3RlYCkgaXMgc2hvd24gaW5zdGVhZC5cbiAgICBpZiAodGhpcy5oYXNHb2xkZW5HdWFyYW50ZWVHaWZ0KCkpIHJldHVybiAnJztcbiAgICBjb25zdCBkID0gdGhpcy5jdXJyZW50RGF0YSgpO1xuICAgIGlmICghZCkgcmV0dXJuICcnO1xuICAgIGNvbnN0IGxlZ0luZm8gPSBkLmxlZ0luZm8gPz8ge307XG4gICAgY29uc3QgaGFzTyA9ICEhbGVnSW5mby5vbndhcmQ7XG4gICAgY29uc3QgaGFzUiA9ICEhbGVnSW5mby5yZXR1cm47XG4gICAgY29uc3Qgb1NoZWxsID0gbGVnSW5mby5vbndhcmQ/LmlzQ3JlZGl0U2hlbGwgPT09IHRydWU7XG4gICAgY29uc3QgclNoZWxsID0gbGVnSW5mby5yZXR1cm4/LmlzQ3JlZGl0U2hlbGwgPT09IHRydWU7XG4gICAgY29uc3QgaXNTaGVsbCA9XG4gICAgICAoaGFzTyAmJiBoYXNSICYmIG9TaGVsbCAmJiByU2hlbGwpIHx8XG4gICAgICAoaGFzTyAmJiAhaGFzUiAmJiBvU2hlbGwpIHx8XG4gICAgICAoIWhhc08gJiYgaGFzUiAmJiByU2hlbGwpIHx8XG4gICAgICAoaGFzTyAmJiBoYXNSICYmIChvU2hlbGwgfHwgclNoZWxsKSk7XG4gICAgaWYgKCFpc1NoZWxsKSByZXR1cm4gJyc7XG4gICAgY29uc3QgYW1vdW50ID0gdGhpcy5mbXQoTnVtYmVyKHRoaXMuYWRqdXN0ZWREYXRhKCk/LnRvdGFsUmVmdW5kQW1vdW50ID8/IGQudG90YWxSZWZ1bmRBbW91bnQgPz8gMCkpO1xuICAgIGNvbnN0IHBuciA9IHRoaXMucmVzb2x2ZVBucigpO1xuICAgIGNvbnN0IHBuclRleHQgPSBwbnIgPyBgdGhlIHNhbWUgUE5SICgke3Bucn0pYCA6ICd0aGUgc2FtZSBQTlInO1xuICAgIHJldHVybiBgVGhlIHJlZnVuZCBvZiAke2Ftb3VudH0gd2lsbCBiZSBpc3N1ZWQgYXMgYWlybGluZSBjcmVkaXQgdW5kZXIgJHtwbnJUZXh0fS4gJHtDUkVESVRfU0hFTExfU1VGRklYfWA7XG4gIH0pO1xuXG4gIC8vIFJlc29sdmUgdGhlIFBOUiBmb3IgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBsZWcgZnJvbSB0aGUgYm9va2luZydzIHBucl9pbmZvIGxpc3QuXG4gIHByaXZhdGUgcmVzb2x2ZVBucigpOiBzdHJpbmcge1xuICAgIGNvbnN0IGxpc3QgPSB0aGlzLnBuckluZm8oKSA/PyBbXTtcbiAgICBpZiAoIWxpc3QubGVuZ3RoKSByZXR1cm4gJyc7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5zZWxlY3RlZExlZygpO1xuICAgIGNvbnN0IGJ5RGlyID0gKGRpcjogc3RyaW5nKSA9PiBsaXN0LmZpbmQocCA9PiBwLkxlZ0RpcmVjdGlvbmFsaXR5ID09PSBkaXIpPy5wbnI7XG4gICAgaWYgKHNlbCA9PT0gJ3JldHVybicpIHJldHVybiBieURpcignUmV0dXJuJykgPz8gbGlzdFswXT8ucG5yID8/ICcnO1xuICAgIGlmIChzZWwgPT09ICdvbndhcmQnKSByZXR1cm4gYnlEaXIoJ0RlcGFydHVyZScpID8/IGxpc3RbMF0/LnBuciA/PyAnJztcbiAgICByZXR1cm4gYnlEaXIoJ0RlcGFydHVyZScpID8/IGxpc3RbMF0/LnBuciA/PyAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBCb29raW5nIGluY2x1ZGVzIGEgR29sZGVuIEd1YXJhbnRlZSBnaWZ0IChcIkNhbmNlbCBmb3IgYW55IHJlYXNvblwiKSDigJRcbiAgICogb3ZlcnJpZGVzIGFsbCBjcmVkaXQtc2hlbGwgaGFuZGxpbmcgYmVsb3csIHNpbmNlIGEgR29sZGVuIEd1YXJhbnRlZVxuICAgKiBjYW5jZWxsYXRpb24gYWx3YXlzIHJlZnVuZHMgMTAwJSB0aHJvdWdoIHRoZSBzdGFuZGFyZCBwYXltZW50IG1ldGhvZFxuICAgKiByYXRoZXIgdGhhbiB0aGUgYWlybGluZSBjcmVkaXQgc2hlbGwuIE1heSBiZSBjYXJyaWVkIG9uIGVpdGhlciB0aGVcbiAgICogcHJldmlldyAoYHJlZnVuZERhdGFgKSBvciB0aGUgY29uZmlybSAoYGNhbmNlbFJlc3VsdGApIHJlc3BvbnNlIOKAlCBib3RoXG4gICAqIHNoYXJlIHRoZSBzYW1lIHNoYXBlLCBhbmQgZWl0aGVyIG9uZSBtYXkgc2V0IGl0IGluZGVwZW5kZW50bHkgb2YgdGhlXG4gICAqIG90aGVyLlxuICAgKi9cbiAgaGFzR29sZGVuR3VhcmFudGVlR2lmdCA9IGNvbXB1dGVkKCgpOiBib29sZWFuID0+XG4gICAgdGhpcy5yZWZ1bmREYXRhKCk/Lmhhc0dvbGRlbkd1YXJhbnRlZUdpZnQgPT09IHRydWUgfHxcbiAgICB0aGlzLmNhbmNlbFJlc3VsdCgpPy5oYXNHb2xkZW5HdWFyYW50ZWVHaWZ0ID09PSB0cnVlLFxuICApO1xuXG4gIC8vIFdoZXRoZXIgdGhlIHJlZnVuZCBpcyBhIGNyZWRpdC1zaGVsbCByZWZ1bmQgKHdob2xlIGJvb2tpbmcgb3IgZWl0aGVyIGxlZykuXG4gIC8vIFN1Y2ggcmVmdW5kcyBjYW4gb25seSByZXR1cm4gdG8gdGhlIGFpcmxpbmUgY3JlZGl0IHNoZWxsLCBzbyB0aGVcbiAgLy8gcmVmdW5kLW1ldGhvZCBwaWNrZXIgaXMgcmVwbGFjZWQgd2l0aCBhIHNpbmdsZSByZWFkLW9ubHkgY3JlZGl0IG5vdGljZS5cbiAgLy8gQSBHb2xkZW4gR3VhcmFudGVlIGdpZnQgb3ZlcnJpZGVzIHRoaXMgdG8gYGZhbHNlYCDigJQgdGhhdCBwb3J0aW9uIG5lZWRzIGFuXG4gIC8vIGFjdHVhbCBkZXN0aW5hdGlvbiBjaG9pY2UsIHNvIHRoZSBib29raW5nIGZhbGxzIGJhY2sgdG8gdGhlIHN0YW5kYXJkXG4gIC8vIHJlZnVuZC1tZXRob2QgZmxvdyBkZXNwaXRlIGJlaW5nIGZsYWdnZWQgY3JlZGl0LXNoZWxsLlxuICBpc0NyZWRpdFNoZWxsID0gY29tcHV0ZWQoKCk6IGJvb2xlYW4gPT4ge1xuICAgIGlmICh0aGlzLmhhc0dvbGRlbkd1YXJhbnRlZUdpZnQoKSkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGQgPSB0aGlzLnJlZnVuZERhdGEoKTtcbiAgICByZXR1cm4gKFxuICAgICAgZD8uaXNDcmVkaXRTaGVsbCA9PT0gdHJ1ZSB8fFxuICAgICAgZD8ubGVnSW5mbz8ub253YXJkPy5pc0NyZWRpdFNoZWxsID09PSB0cnVlIHx8XG4gICAgICBkPy5sZWdJbmZvPy5yZXR1cm4/LmlzQ3JlZGl0U2hlbGwgPT09IHRydWVcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogUmVmdW5kYWJsZSBhbmNpbGxhcmllcyAoYmFnZ2FnZSwgc2VhdHMsIOKApikgdGhhdCBjYXJyeSB0aGVpciBvd25cbiAgICogYGlzQ3JlZGl0U2hlbGxgIGZsYWcsIGluZGVwZW5kZW50IG9mIHRoZSBib29raW5nLWxldmVsIGZsYWcg4oCUIHJlbmRlcmVkXG4gICAqIGFzIGluZGl2aWR1YWwgY2FyZHMgb24gdGhlIGNyZWRpdC1zaGVsbCByZWZ1bmQtbWV0aG9kIHNjcmVlbiBzbyBlYWNoXG4gICAqIG9uZSBjYW4gc2hvdyBlaXRoZXIgdGhlIGNyZWRpdC1zaGVsbCBjYXJkIHN0eWxlIG9yIHRoZSBub3JtYWwgd2FsbGV0XG4gICAqIGNhcmQgc3R5bGUgKGJvdGggaW5jbHVkZSB0aGUgc2FtZSBuZXN0ZWQgY3JlZGl0LXNoZWxsIG5vdGUgd2hlbiB0cnVlKS5cbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIGNyZWRpdFNoZWxsQW5jaWxsYXJ5SXRlbXMgPSBjb21wdXRlZCgoKTogYW55W10gPT5cbiAgICAodGhpcy5hZGp1c3RlZERhdGEoKT8ucmVmdW5kQnJlYWtkb3duPy5yZWZ1bmRhYmxlPy5hbmNpbGxhcmllcyA/PyBbXSlcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAuZmlsdGVyKChpdGVtOiBhbnkpID0+IE51bWJlcihpdGVtLmFtb3VudCkgPiAwKSxcbiAgKTtcblxuICAvLyBBaXJsaW5lIHRoYXQgaXNzdWVzIHRoZSBjcmVkaXQgc2hlbGwsIGZvciB0aGUgXCI8c3VwcGxpZXI+IHdlYnNpdGUgY3JlZGl0XCIgY2FyZC5cbiAgY3JlZGl0U2hlbGxTdXBwbGllck5hbWUgPSBjb21wdXRlZCgoKTogc3RyaW5nID0+IHtcbiAgICBjb25zdCBkID0gdGhpcy5yZWZ1bmREYXRhKCk7XG4gICAgcmV0dXJuIChcbiAgICAgIGQ/LmxlZ0luZm8/Lm9ud2FyZD8uc3VwcGxpZXJOYW1lID8/XG4gICAgICBkPy5sZWdJbmZvPy5yZXR1cm4/LnN1cHBsaWVyTmFtZSA/P1xuICAgICAgZD8uc3VwcGxpZXJOYW1lID8/XG4gICAgICBkPy5hcHBsaWVkU291cmNlID8/XG4gICAgICAnJ1xuICAgICk7XG4gIH0pO1xuXG4gIC8vIEhlYWRlciB0aXRsZSByZWZsZWN0aW5nIHRoZSByZWZ1bmQgdHlwZSBmb3IgdGhlIGFjdGl2ZSBzZWxlY3Rpb24uXG4gIHJlZnVuZFR5cGVMYWJlbCA9IGNvbXB1dGVkKCgpOiBzdHJpbmcgPT4ge1xuICAgIGlmICghdGhpcy5yZWZ1bmREYXRhKCk/LmlzUmVmdW5kYWJsZSkgcmV0dXJuICdSZWZ1bmQgRGV0YWlscyc7XG4gICAgcmV0dXJuIHRoaXMuY3JlZGl0U2hlbGxOb3RlKCkgPyAnQ3JlZGl0IFNoZWxsIFJlZnVuZCcgOiAnUmVmdW5kIERldGFpbHMnO1xuICB9KTtcblxuICBjdXJyZW5jeSA9IGNvbXB1dGVkKCgpOiBzdHJpbmcgPT4gdGhpcy5yZWZ1bmREYXRhKCk/LmN1cnJlbmN5ID8/ICdTQVInKTtcblxuICAvLyBTZWxmLWNvbnNpc3RlbmN5IGNoZWNrIGJldHdlZW4gdGhlIHBhaWQgYW1vdW50LCBkZWR1Y3Rpb25zIGFuZCB0aGUgc3lzdGVtIHJlZnVuZC5cbiAgLy8gU3VyZmFjZWQgdG8gdGhlIGFnZW50IHNvIG1pc21hdGNoZWQvb3Zlci1kZWR1Y3RlZCByZWZ1bmRzIGNhbiBiZSBjYXVnaHQgYmVmb3JlIGNvbmZpcm1pbmcuXG4gIGRpc2NyZXBhbmN5Tm90ZSA9IGNvbXB1dGVkKCgpOiBzdHJpbmcgPT4ge1xuICAgIGNvbnN0IGQgPSB0aGlzLmFkanVzdGVkRGF0YSgpO1xuICAgIGlmICghZCB8fCAhZC5pc1JlZnVuZGFibGUpIHJldHVybiAnJztcbiAgICBjb25zdCBwYWlkICAgICAgPSBOdW1iZXIoZC5vcmlnaW5hbEFtb3VudCB8fCAwKTtcbiAgICBjb25zdCBkZWR1Y3Rpb24gPSBOdW1iZXIoZC50b3RhbENhbmNlbGxhdGlvbkZlZSB8fCAwKTtcbiAgICBjb25zdCByZWZ1bmQgICAgPSBOdW1iZXIoZC50b3RhbFJlZnVuZEFtb3VudCB8fCAwKTtcbiAgICBjb25zdCBpc3N1ZXM6IHN0cmluZ1tdID0gW107XG4gICAgaWYgKGRlZHVjdGlvbiA+IHBhaWQgKyAwLjAxKVxuICAgICAgaXNzdWVzLnB1c2goYFRvdGFsIGRlZHVjdGlvbiAoJHt0aGlzLmZtdChkZWR1Y3Rpb24pfSkgZXhjZWVkcyB0aGUgcGFpZCBhbW91bnQgKCR7dGhpcy5mbXQocGFpZCl9KS5gKTtcbiAgICBpZiAoTWF0aC5hYnMoKHBhaWQgLSBkZWR1Y3Rpb24pIC0gcmVmdW5kKSA+IDAuMDEpXG4gICAgICBpc3N1ZXMucHVzaChgQ29tcHV0ZWQgcmVmdW5kICgke3RoaXMuZm10KHBhaWQgLSBkZWR1Y3Rpb24pfSkgZG9lc24ndCBtYXRjaCB0aGUgc3lzdGVtIHJlZnVuZCAoJHt0aGlzLmZtdChyZWZ1bmQpfSkuYCk7XG4gICAgcmV0dXJuIGlzc3Vlcy5qb2luKCcgJyk7XG4gIH0pO1xuXG4gIC8qKiBSZWFsIHBlci1ib29raW5nIENyb3NzU2VsbGVyIGZsYWcgZnJvbSB0aGUgcmVmdW5kIHByZXZpZXcg4oCUIENyb3NzU2VsbGVyIHN1cHBsaWVycyBhbGxvdyBjYW5jZWxsaW5nIGVpdGhlciBsZWcgaW5kZXBlbmRlbnRseS4gKi9cbiAgaXNDcm9zc1NlbGxlciA9IGNvbXB1dGVkKCgpID0+IHRoaXMucmVmdW5kRGF0YSgpPy5pc0Nyb3NzU2VsbGVyID09PSB0cnVlKTtcblxuICAvLyBOb24tQ3Jvc3NTZWxsZXIgcm91bmQgdHJpcHMgYXJlIG9uZSBpdGluZXJhcnkgc29sZCBhcyBhIHNpbmdsZSBmYXJlIOKAlFxuICAvLyBib3RoIGxlZ3Mgc2hhcmUgdGhlIHNhbWUgcmVmdW5kYWJpbGl0eSwgc291cmNlZCBmcm9tIHJvb3QsIGV2ZW4gd2hlblxuICAvLyB0aGUgYmFja2VuZCdzIGxlZ0luZm8gZW50cnkgZm9yIGEgbGVnIGlzIG1pc3Npbmcgb3IgaW5jb25zaXN0ZW50LlxuICAvLyBDcm9zc1NlbGxlciBsZWdzIGFyZSBpbmRlcGVuZGVudGx5IHNlbGxhYmxlLCBzbyBlYWNoIGxlZydzIG93biBmaWVsZFxuICAvLyBzdGlsbCBnb3Zlcm5zIHRoZXJlLlxuICBvbndhcmRSZWZ1bmRhYmxlICA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBpZiAoIXRoaXMuaGFzT253YXJkKCkpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdGhpcy5pc0Nyb3NzU2VsbGVyKClcbiAgICAgID8gdGhpcy5yZWZ1bmREYXRhKCk/LmxlZ0luZm8/Lm9ud2FyZD8uaXNSZWZ1bmRhYmxlID09PSB0cnVlXG4gICAgICA6IHRoaXMucmVmdW5kRGF0YSgpPy5pc1JlZnVuZGFibGUgPT09IHRydWU7XG4gIH0pO1xuICByZXR1cm5SZWZ1bmRhYmxlICA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBpZiAoIXRoaXMuaGFzUmV0dXJuKCkpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdGhpcy5pc0Nyb3NzU2VsbGVyKClcbiAgICAgID8gdGhpcy5yZWZ1bmREYXRhKCk/LmxlZ0luZm8/LnJldHVybj8uaXNSZWZ1bmRhYmxlID09PSB0cnVlXG4gICAgICA6IHRoaXMucmVmdW5kRGF0YSgpPy5pc1JlZnVuZGFibGUgPT09IHRydWU7XG4gIH0pO1xuICBpc01peGVkICAgICAgICAgICA9IGNvbXB1dGVkKCgpID0+IHRoaXMuaXNSb3VuZFRyaXAoKSAmJiB0aGlzLm9ud2FyZFJlZnVuZGFibGUoKSAhPT0gdGhpcy5yZXR1cm5SZWZ1bmRhYmxlKCkpO1xuXG4gIC8qKiBCb3RoIGxlZ3MgcHJlc2VudCBhbmQgQk9USCBub24tcmVmdW5kYWJsZSDigJQgbm90aGluZyBjYW4gYmUgcmVmdW5kZWQgZm9yIHRoaXMgYm9va2luZy4gKi9cbiAgYWxsTGVnc05vblJlZnVuZGFibGUgPSBjb21wdXRlZChcbiAgICAoKSA9PiB0aGlzLmlzUm91bmRUcmlwKCkgJiYgIXRoaXMub253YXJkUmVmdW5kYWJsZSgpICYmICF0aGlzLnJldHVyblJlZnVuZGFibGUoKSxcbiAgKTtcblxuICBtaXhlZEhpbnQgPSBjb21wdXRlZCgoKTogc3RyaW5nID0+IHtcbiAgICAvLyBPbmx5IHJlbGV2YW50IHdoZW4gYWdlbnQgaXMgYWJvdXQgdG8gY2FuY2VsIGJvdGggbGVncyB0b2dldGhlciDigJRcbiAgICAvLyBpbmRpdmlkdWFsIGxlZyB0YWJzIGFscmVhZHkgc2hvdyB0aGVpciBvd24gbm9uLXJlZnVuZGFibGUgbm90aWNlLlxuICAgIGlmICghdGhpcy5pc01peGVkKCkgfHwgdGhpcy5zZWxlY3RlZExlZygpICE9PSAnYm90aCcpIHJldHVybiAnJztcbiAgICBpZiAoIXRoaXMub253YXJkUmVmdW5kYWJsZSgpKSByZXR1cm4gJ+KaoO+4jyBPbndhcmQgbGVnIGlzIG5vdCBlbGlnaWJsZSBmb3IgcmVmdW5kLiBQbGVhc2UgY29udGFjdCBjdXN0b21lciBzZXJ2aWNlIGlmIHlvdSB3YW50IHRvIGNhbmNlbCBpdC4nO1xuICAgIGlmICghdGhpcy5yZXR1cm5SZWZ1bmRhYmxlKCkpIHJldHVybiAn4pqg77iPIFJldHVybiBsZWcgaXMgbm90IGVsaWdpYmxlIGZvciByZWZ1bmQuIFBsZWFzZSBjb250YWN0IGN1c3RvbWVyIHNlcnZpY2UgaWYgeW91IHdhbnQgdG8gY2FuY2VsIGl0Lic7XG4gICAgcmV0dXJuICcnO1xuICB9KTtcblxuICBnaWZ0SGludCA9IGNvbXB1dGVkKCgpOiBzdHJpbmcgPT4ge1xuICAgIGNvbnN0IHJvb3QgPSB0aGlzLnJlZnVuZERhdGEoKTtcbiAgICBpZiAoIXJvb3QgfHwgIXRoaXMuaXNSb3VuZFRyaXAoKSkgcmV0dXJuICcnO1xuICAgIGNvbnN0IGhhc0dpZnQgPSBOdW1iZXIocm9vdC50b3RhbEdpZnRBbW91bnQgfHwgMCkgPiAwIHx8XG4gICAgICBOdW1iZXIocm9vdC5sZWdJbmZvPy5vbndhcmQ/LnRvdGFsR2lmdEFtb3VudCB8fCAwKSA+IDAgfHxcbiAgICAgIE51bWJlcihyb290LmxlZ0luZm8/LnJldHVybj8udG90YWxHaWZ0QW1vdW50IHx8IDApID4gMDtcbiAgICByZXR1cm4gaGFzR2lmdCA/IEdJRlRfSElOVCA6ICcnO1xuICB9KTtcblxuICBzZWxlY3Rpb25IaW50ID0gY29tcHV0ZWQoKCk6IHN0cmluZyA9PiB7XG4gICAgaWYgKCF0aGlzLmlzUm91bmRUcmlwKCkpIHJldHVybiAnJztcbiAgICBjb25zdCBtYXA6IFJlY29yZDxMZWdTZWxlY3Rpb24sIHN0cmluZz4gPSB7XG4gICAgICBvbndhcmQ6ICdZb3UgYXJlIGFib3V0IHRvIGNhbmNlbDogT253YXJkIGxlZyBvbmx5JyxcbiAgICAgIHJldHVybjogJ1lvdSBhcmUgYWJvdXQgdG8gY2FuY2VsOiBSZXR1cm4gbGVnIG9ubHknLFxuICAgICAgYm90aDogICAnWW91IGFyZSBhYm91dCB0byBjYW5jZWw6IEJvdGggbGVncycsXG4gICAgfTtcbiAgICByZXR1cm4gbWFwW3RoaXMuc2VsZWN0ZWRMZWcoKV07XG4gIH0pO1xuXG4gIGNvbmZpcm1EZWR1Y3Rpb25zID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgZDogYW55ID0gdGhpcy5jYW5jZWxSZXN1bHQoKTtcbiAgICBpZiAoIWQpIHJldHVybiBbXTtcbiAgICByZXR1cm4gREVEVUNUSU9OX0RFRlMuZmlsdGVyKGRlZiA9PiBOdW1iZXIoZFtkZWYua2V5XSkgPiAwKS5tYXAoZGVmID0+ICh7IGxhYmVsOiBkZWYubGFiZWwsIHZhbHVlOiBOdW1iZXIoZFtkZWYua2V5XSkgfSkpO1xuICB9KTtcblxuICBjb25maXJtUmVmdW5kcyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IGQ6IGFueSA9IHRoaXMuY2FuY2VsUmVzdWx0KCk7XG4gICAgaWYgKCFkKSByZXR1cm4gW107XG4gICAgY29uc3QgY29kZSA9IHRoaXMubm9ybWFsaXplR2F0ZXdheUNvZGUoZC5wYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkKTtcbiAgICBjb25zdCBpc0xveWFsdHkgPSBMT1lBTFRZX0dBVEVXQVlfQ09ERVMuaW5jbHVkZXMoY29kZSk7XG4gICAgY29uc3QgaXNNYWRhID0gdGhpcy5jb25maXJtSXNNYWRhTWV0aG9kKCk7XG4gICAgY29uc3QgcGF5bWVudExhYmVsID0gY29kZSAmJiAhSU5URVJOQUxfR0FURVdBWV9DT0RFUy5pbmNsdWRlcyhjb2RlKSA/IFBBWU1FTlRfR0FURVdBWV9MQUJFTFNbY29kZV0gOiAnJztcbiAgICBjb25zdCByb3dzOiB7XG4gICAgICBrZXk6IHN0cmluZztcbiAgICAgIGxhYmVsOiBzdHJpbmc7XG4gICAgICB2YWx1ZTogbnVtYmVyO1xuICAgICAgc3ViUm93cz86IHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IG51bWJlciB9W107XG4gICAgICBoYXNMb3lhbHR5Tm90ZT86IGJvb2xlYW47XG4gICAgfVtdID0gW107XG4gICAgY29uc3QgeyB3YWxsZXQsIGZvcmZlaXRlZExveWFsdHkgfSA9IHRoaXMuY29ycmVjdGVkQ29uZmlybVdhbGxldEFuZExveWFsdHkoZCk7XG4gICAgLy8gR29sZGVuIEd1YXJhbnRlZSBvdmVycmlkZXMgY3JlZGl0LXNoZWxsIGhhbmRsaW5nIG9uIHRoZSByZXN1bHQgc2NyZWVuXG4gICAgLy8gdG9vIOKAlCB3aGF0ZXZlciBsYW5kZWQgYXMgYSBjcmVkaXQtc2hlbGwgYW1vdW50IGZvbGRzIGludG8gdGhlIG5vcm1hbFxuICAgIC8vIG9yaWdpbmFsLXBheW1lbnQtbWV0aG9kIHJvdyBpbnN0ZWFkIG9mIGdldHRpbmcgaXRzIG93biBcImFpcmxpbmVcbiAgICAvLyBjcmVkaXRcIiBjYXJkLCBzbyB0aGUgY29uZmlybWF0aW9uIHJlYWRzIGxpa2UgYW4gb3JkaW5hcnkgU2FicmUvQW1hZGV1c1xuICAgIC8vIHJlZnVuZC5cbiAgICBjb25zdCBnb2xkZW5HdWFyYW50ZWVPdmVycmlkZSA9IHRoaXMuaGFzR29sZGVuR3VhcmFudGVlR2lmdCgpO1xuICAgIC8vIENyZWRpdC1zaGVsbCByb3cgZ29lcyBmaXJzdCDigJQgbWF0Y2hlcyB0aGUgZGVzaWduIChhaXJsaW5lIGNyZWRpdCBhYm92ZVxuICAgIC8vIHRoZSB3YWxsZXQgcm93KSDigJQgYmVmb3JlIHRoZSBjYXJkIGFuZCB3YWxsZXQgcm93cyBiZWxvdy5cbiAgICBpZiAoIWdvbGRlbkd1YXJhbnRlZU92ZXJyaWRlKSB7XG4gICAgICBjb25zdCBjcmVkaXQgPSBOdW1iZXIoZC50b3RhbENyZWRpdFJlZnVuZEFtb3VudCA/PyAwKTtcbiAgICAgIGlmIChjcmVkaXQgPiAwKSB7XG4gICAgICAgIGNvbnN0IHN1cHBsaWVyID0gZC5hcHBsaWVkU291cmNlIHx8IHRoaXMuY3JlZGl0U2hlbGxTdXBwbGllck5hbWUoKTtcbiAgICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAgICBrZXk6ICd0b3RhbENyZWRpdFJlZnVuZEFtb3VudCcsXG4gICAgICAgICAgbGFiZWw6IHN1cHBsaWVyID8gYCR7c3VwcGxpZXJ9IHdlYnNpdGUgY3JlZGl0YCA6ICdDcmVkaXQgU2hlbGwgUmVmdW5kJyxcbiAgICAgICAgICB2YWx1ZTogY3JlZGl0LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgY2FyZEFtb3VudCA9XG4gICAgICBOdW1iZXIoZC50b3RhbENhcmRSZWZ1bmRBbW91bnQgPz8gMCkgK1xuICAgICAgKGdvbGRlbkd1YXJhbnRlZU92ZXJyaWRlID8gTnVtYmVyKGQudG90YWxDcmVkaXRSZWZ1bmRBbW91bnQgPz8gMCkgOiAwKTtcbiAgICBpZiAoY2FyZEFtb3VudCA+IDApIHtcbiAgICAgIHJvd3MucHVzaCh7XG4gICAgICAgIGtleTogJ3RvdGFsQ2FyZFJlZnVuZEFtb3VudCcsXG4gICAgICAgIGxhYmVsOiBpc01hZGFcbiAgICAgICAgICA/ICdNYWRhIENhcmQnXG4gICAgICAgICAgOiAhaXNMb3lhbHR5ICYmIHBheW1lbnRMYWJlbFxuICAgICAgICAgICAgPyBgUmVmdW5kIEFtb3VudCAke3BheW1lbnRMYWJlbH1gXG4gICAgICAgICAgICA6ICdSZWZ1bmQgQW1vdW50JyxcbiAgICAgICAgdmFsdWU6IGNhcmRBbW91bnQsXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHdhbGxldCA+IDAgJiYgZm9yZmVpdGVkTG95YWx0eSA+IDApIHtcbiAgICAgIC8vIFdhbGxldCBjYXNoICsgYSBsb3lhbHR5IHByb2dyYW0ncyBwb2ludHMgYm90aCBsYW5kZWQgaW4gdGhlIHdhbGxldCDigJRcbiAgICAgIC8vIHNob3duIGFzIG9uZSBjb21iaW5lZCBjYXJkIHdpdGggdGhlIHR3byBzb3VyY2VzIGJyb2tlbiBvdXQgYXMgbmFtZWRcbiAgICAgIC8vIHN1Yi1yb3dzLCByYXRoZXIgdGhhbiB0d28gc2VwYXJhdGUgdG9wLWxldmVsIGNhcmRzLlxuICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAga2V5OiAnd2FsbGV0UmVmdW5kQW1vdW50JyxcbiAgICAgICAgbGFiZWw6ICdBbG1hdGFyIFdhbGxldCcsXG4gICAgICAgIHZhbHVlOiB3YWxsZXQgKyBmb3JmZWl0ZWRMb3lhbHR5LFxuICAgICAgICBzdWJSb3dzOiBbXG4gICAgICAgICAgeyBsYWJlbDogJ0FsbWF0YXIgd2FsbGV0IHBvaW50cycsIHZhbHVlOiB3YWxsZXQgfSxcbiAgICAgICAgICB7IGxhYmVsOiBgJHt0aGlzLndhbGxldE9yTG95YWx0eUxhYmVsKGQpfSBwb2ludHNgLCB2YWx1ZTogZm9yZmVpdGVkTG95YWx0eSB9LFxuICAgICAgICBdLFxuICAgICAgICBoYXNMb3lhbHR5Tm90ZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAod2FsbGV0ID4gMCkge1xuICAgICAgcm93cy5wdXNoKHsga2V5OiAnd2FsbGV0UmVmdW5kQW1vdW50JywgbGFiZWw6ICdBbG1hdGFyIFdhbGxldCcsIHZhbHVlOiB3YWxsZXQgfSk7XG4gICAgfSBlbHNlIGlmIChmb3JmZWl0ZWRMb3lhbHR5ID4gMCkge1xuICAgICAgLy8gTG95YWx0eS1vbmx5IOKAlCBubyB3YWxsZXQgY2FzaCBpbnZvbHZlZCwgc3RpbGwgbGFuZHMgYXMgcGVybWFuZW50XG4gICAgICAvLyB3YWxsZXQgcG9pbnRzLCBzbyBpdCBrZWVwcyB0aGUgd2FsbGV0LXN0eWxlIGNhcmQgKyBub3RlLlxuICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAga2V5OiAndG90YWxMb3lhbHR5UG9pbnRzJyxcbiAgICAgICAgbGFiZWw6IHRoaXMud2FsbGV0T3JMb3lhbHR5TGFiZWwoZCksXG4gICAgICAgIHZhbHVlOiBmb3JmZWl0ZWRMb3lhbHR5LFxuICAgICAgICBoYXNMb3lhbHR5Tm90ZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBSRUZVTkRfREVGU1xuICAgICAgLmZpbHRlcigoZGVmKSA9PlxuICAgICAgICBkZWYua2V5ICE9PSAnd2FsbGV0UmVmdW5kQW1vdW50JyAmJlxuICAgICAgICBkZWYua2V5ICE9PSAndG90YWxDYXJkUmVmdW5kQW1vdW50JyAmJlxuICAgICAgICBkZWYua2V5ICE9PSAndG90YWxDcmVkaXRSZWZ1bmRBbW91bnQnICYmXG4gICAgICAgIE51bWJlcihkW2RlZi5rZXldKSA+IDAsXG4gICAgICApXG4gICAgICAuZm9yRWFjaCgoZGVmKSA9PiB7XG4gICAgICAgIHJvd3MucHVzaCh7IGtleTogZGVmLmtleSwgbGFiZWw6IGRlZi5sYWJlbCwgdmFsdWU6IE51bWJlcihkW2RlZi5rZXldKSB9KTtcbiAgICAgIH0pO1xuICAgIHJldHVybiByb3dzO1xuICB9KTtcblxuICAvKiogUm93cyB0aGF0IGxhbmQgaW4gdGhlIHdhbGxldCDigJQgcGxhaW4gd2FsbGV0LCB3YWxsZXQrbG95YWx0eSBjb21iaW5lZCwgb3IgbG95YWx0eS1vbmx5IOKAlCBzaGFyZSB0aGUgd2FsbGV0IGljb24vbGF5b3V0IG9uIHRoZSByZXN1bHQgc2NyZWVuLiAqL1xuICBpc1dhbGxldERlc3RpbmF0aW9uUm93KHI6IHsga2V5OiBzdHJpbmcgfSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiByLmtleSA9PT0gJ3dhbGxldFJlZnVuZEFtb3VudCcgfHwgci5rZXkgPT09ICd0b3RhbExveWFsdHlQb2ludHMnO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSByZXN1bHQgc2NyZWVuJ3MgXCJpc3N1ZWQgYXMgYW4gQWlybGluZSBDcmVkaXQgU2hlbGxcIiBub3RlLiBHb2xkZW5cbiAgICogR3VhcmFudGVlIG92ZXJyaWRlcyB0aGlzIHRvICcnIOKAlCB0aGUgY29uZmlybWF0aW9uIHJlbmRlcnMgbGlrZSBhXG4gICAqIHN0YW5kYXJkIFNhYnJlL0FtYWRldXMgcmVmdW5kIGluc3RlYWQgKHNlZSBgY29uZmlybVJlZnVuZHNgJyBmb2xkaW5nXG4gICAqIG9mIGFueSBjcmVkaXQtc2hlbGwgYW1vdW50IGludG8gdGhlIG5vcm1hbCBwYXltZW50LW1ldGhvZCByb3cpLlxuICAgKi9cbiAgY29uZmlybUNyZWRpdFNoZWxsTm90ZSA9IGNvbXB1dGVkKCgpOiBzdHJpbmcgPT4ge1xuICAgIGlmICh0aGlzLmhhc0dvbGRlbkd1YXJhbnRlZUdpZnQoKSkgcmV0dXJuICcnO1xuICAgIGNvbnN0IGQgPSB0aGlzLmNhbmNlbFJlc3VsdCgpO1xuICAgIGlmICghZCkgcmV0dXJuICcnO1xuICAgIGNvbnN0IGxlZ0luZm8gPSBkLmxlZ0luZm8gPz8ge307XG4gICAgY29uc3QgaGFzTyA9ICEhbGVnSW5mby5vbndhcmQ7XG4gICAgY29uc3QgaGFzUiA9ICEhbGVnSW5mby5yZXR1cm47XG4gICAgY29uc3Qgb1NoZWxsID0gbGVnSW5mby5vbndhcmQ/LmlzQ3JlZGl0U2hlbGwgPT09IHRydWU7XG4gICAgY29uc3QgclNoZWxsID0gbGVnSW5mby5yZXR1cm4/LmlzQ3JlZGl0U2hlbGwgPT09IHRydWU7XG4gICAgY29uc3QgdG9wU2hlbGwgPSBkLmlzQ3JlZGl0U2hlbGwgPT09IHRydWU7XG4gICAgaWYgKChoYXNPICYmIGhhc1IgJiYgb1NoZWxsICYmIHJTaGVsbCkgfHwgKGhhc08gJiYgIWhhc1IgJiYgb1NoZWxsKSB8fCAoIWhhc08gJiYgaGFzUiAmJiByU2hlbGwpIHx8IHRvcFNoZWxsKVxuICAgICAgcmV0dXJuICdUaGUgcmVmdW5kIGhhcyBiZWVuIGlzc3VlZCBhcyBhbiBBaXJsaW5lIENyZWRpdCBTaGVsbCBhbmQgY2FuIGJlIHVzZWQgZm9yIGZ1dHVyZSBib29raW5ncyBvbiB0aGUgYWlybGluZSB3ZWJzaXRlLic7XG4gICAgaWYgKGhhc08gJiYgaGFzUikge1xuICAgICAgaWYgKG9TaGVsbCkgcmV0dXJuICdUaGUgcmVmdW5kIGZvciB0aGUgb253YXJkIGZsaWdodCBoYXMgYmVlbiBpc3N1ZWQgYXMgYW4gQWlybGluZSBDcmVkaXQgU2hlbGwuJztcbiAgICAgIGlmIChyU2hlbGwpIHJldHVybiAnVGhlIHJlZnVuZCBmb3IgdGhlIHJldHVybiBmbGlnaHQgaGFzIGJlZW4gaXNzdWVkIGFzIGFuIEFpcmxpbmUgQ3JlZGl0IFNoZWxsLic7XG4gICAgfVxuICAgIHJldHVybiAnJztcbiAgfSk7XG5cbiAgZm10UmVzdWx0KHZhbHVlOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGNvbnN0IGN1ciA9IHRoaXMuY2FuY2VsUmVzdWx0KCk/LmN1cnJlbmN5ID8/IHRoaXMucmVmdW5kRGF0YSgpPy5jdXJyZW5jeSA/PyAnU0FSJztcbiAgICByZXR1cm4gYCR7TnVtYmVyKHZhbHVlIHx8IDApLnRvTG9jYWxlU3RyaW5nKCdlbi1TQScsIHsgbWluaW11bUZyYWN0aW9uRGlnaXRzOiAyLCBtYXhpbXVtRnJhY3Rpb25EaWdpdHM6IDIgfSl9ICR7Y3VyfWA7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGN1c3RvbWVyLWZhY2luZyB0b3RhbCAoY2VpbGVkKSBtdXN0IG1hdGNoIHRoZSBwcmUtcm91bmRpbmcgdG90YWwgdGhlXG4gICAqIHJlZnVuZCBpcyBhY3R1YWxseSBjb21wdXRlZCBmcm9tIOKAlCBpLmUuIGB0b3RhbFJlZnVuZEFtb3VudGAgbXVzdCBiZVxuICAgKiBgdG90YWxSZWZ1bmRBbW91bnRCZWZvcmVDZWlsYCByb3VuZGVkIHVwIHRvIGEgd2hvbGUgY3VycmVuY3kgdW5pdCAoZS5nLlxuICAgKiAxNDU0LjUg4oaSIDE0NTUpLiBBIG1pc21hdGNoIGhlcmUgbWVhbnMgdGhlIHN1cHBsaWVyIHJlc3BvbnNlIGl0c2VsZiBpc1xuICAgKiBpbnRlcm5hbGx5IGluY29uc2lzdGVudCBhbmQgbXVzdCBibG9jayBjb25maXJtYXRpb24uXG4gICAqL1xuICByZWZ1bmRSZWNvbmNpbGVzID0gY29tcHV0ZWQoKCk6IGJvb2xlYW4gPT4ge1xuICAgIGNvbnN0IGQgPSB0aGlzLmFkanVzdGVkRGF0YSgpO1xuICAgIGlmICghZCB8fCAhZC5pc1JlZnVuZGFibGUpIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IGJlZm9yZUNlaWwgPSBOdW1iZXIoZC50b3RhbFJlZnVuZEFtb3VudEJlZm9yZUNlaWwgPz8gZC50b3RhbFJlZnVuZEFtb3VudCA/PyAwKTtcbiAgICBjb25zdCB0b3RhbCA9IE51bWJlcihkLnRvdGFsUmVmdW5kQW1vdW50ID8/IGJlZm9yZUNlaWwpO1xuICAgIHJldHVybiBNYXRoLmFicyhNYXRoLmNlaWwoYmVmb3JlQ2VpbCkgLSB0b3RhbCkgPCAxO1xuICB9KTtcblxuICBjYW5Db25maXJtID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGQgPSB0aGlzLmFkanVzdGVkRGF0YSgpO1xuICAgIHJldHVybiAhIWQ/LmlzUmVmdW5kYWJsZSAmJiB0aGlzLnJlZnVuZFJlY29uY2lsZXMoKSAmJiAhdGhpcy5jYW5jZWxsaW5nKCk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBgdG90YWxMb3lhbHR5UG9pbnRzYCBpcyBub3JtYWxseSB0aGUgZm9yZmVpdGVkLWF0LWJvb2tpbmcgcG9pbnRzIGNvdW50XG4gICAqIChubyByZWZ1bmQgZGVzdGluYXRpb24gb2YgaXRzIG93bikuIEJ1dCB3aGVuIHRoZSBiYWNrZW5kIG5ldmVyXG4gICAqIHBvcHVsYXRlcyBgdG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50YCBmb3IgYSBgbG95YWx0eVBheW1lbnRUeXBlYFxuICAgKiBib29raW5nLCB0aGlzIGlzIHRoZSBvbmx5IHNpZ25hbCB0aGF0IGEgbG95YWx0eSBwcm9ncmFtIHdhcyBpbnZvbHZlZCxcbiAgICogc28gaXQgZG91YmxlcyBhcyBhIHNwbGl0LXJlZnVuZCByb3cgKGFsb25nc2lkZSBDYXJkL1dhbGxldCkgcmF0aGVyIHRoYW5cbiAgICogZGlzYXBwZWFyaW5nIGZyb20gdGhlIHJlZnVuZCBicmVha2Rvd24gZW50aXJlbHkuIEFsd2F5cyBzaG93biBhcyBpdHNcbiAgICogb3duIHJvdyB1bmRlciB0aGUgcHJvZ3JhbSBuYW1lIChlLmcuIFwiV2FsYVwiKSDigJQgbmV2ZXIgbWVyZ2VkIGludG8gdGhlXG4gICAqIGdlbmVyaWMgV2FsbGV0IHJvdywgZXZlbiB3aGVuIGB3YWxsZXRSZWZ1bmRBbW91bnRgIGlzIGFsc28gbm9uLXplcm8uXG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBwcml2YXRlIGZvcmZlaXRlZExveWFsdHlQb2ludHNGYWxsYmFjayhkOiBhbnkpOiBudW1iZXIge1xuICAgIGlmICghZD8ubG95YWx0eVBheW1lbnRUeXBlKSByZXR1cm4gMDtcbiAgICBpZiAoTnVtYmVyKGQudG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50ID8/IDApID4gMCkgcmV0dXJuIDA7XG4gICAgcmV0dXJuIE51bWJlcihkLnRvdGFsTG95YWx0eVBvaW50cyA/PyAwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTb21lIGAvY29uZmlybWAgcmVzcG9uc2VzIGZvciBhIHNpbmdsZS1sZWcgKG5vbi1jcm9zcy1zZWxsZXIpIGJvb2tpbmdcbiAgICogcHV0IGB3YWxsZXRSZWZ1bmRBbW91bnRgL2B0b3RhbExveWFsdHlQb2ludHNgIG9uIHRoZSB3cm9uZyBzaWRlIGF0IHRoZVxuICAgKiByb290IOKAlCBlLmcuIHJvb3QgcmVhZHMgYHdhbGxldFJlZnVuZEFtb3VudDogNDAsIHRvdGFsTG95YWx0eVBvaW50czogMGBcbiAgICogd2hpbGUgdGhlIHNpbmdsZSBsZWcgKHdoaWNoIHNob3VsZCBtaXJyb3Igcm9vdCBleGFjdGx5IGhlcmUpIHJlYWRzXG4gICAqIGB3YWxsZXRSZWZ1bmRBbW91bnQ6IDAsIHRvdGFsTG95YWx0eVBvaW50czogNDBgLiBEZXRlY3RlZCBuYXJyb3dseTogcm9vdFxuICAgKiBzaG93cyBubyBmb3JmZWl0ZWQgbG95YWx0eSBkZXNwaXRlIGBsb3lhbHR5UGF5bWVudFR5cGVgIGJlaW5nIHNldCwgdGhlXG4gICAqIHJvb3Qgd2FsbGV0IGFtb3VudCBleGFjdGx5IGVxdWFscyB0aGUgbGVnJ3MgbG95YWx0eSBwb2ludHMsIGFuZCB0aGVcbiAgICogbGVnJ3Mgb3duIHdhbGxldCBhbW91bnQgZGlzYWdyZWVzIOKAlCBpbiB0aGF0IHNwZWNpZmljIGNhc2UgdGhlIGxlZydzXG4gICAqIHZhbHVlcyBhcmUgdHJ1c3RlZCBpbnN0ZWFkLCBzaW5jZSB3aXRoIG9ubHkgb25lIGxlZyB0aGV5J3JlIHVuYW1iaWd1b3VzLlxuICAgKlxuICAgKiBBIHNlY29uZCwgbW9yZSBjb21tb24gc2hhcGU6IHJvb3QgZG9lc24ndCBzd2FwIGF0IGFsbCwgaXQgZm9sZHMgdGhlXG4gICAqIHBvaW50cyBzdHJhaWdodCBpbnRvIGB3YWxsZXRSZWZ1bmRBbW91bnRgIGFzIG9uZSBvcGFxdWUgbHVtcCBzdW0gKGUuZy5cbiAgICogcm9vdCB3YWxsZXQgMzQwID0gdGhlIGxlZydzIG93biBjYXNoIHdhbGxldCAzMDAgKyB0aGUgbGVnJ3MgZm9yZmVpdGVkXG4gICAqIGxveWFsdHkgcG9pbnRzIDQwKS4gU3BsaXQgdGhhdCBiYWNrIGludG8gdGhlIHR3byBwYXJ0cyB0aGUgbGVnIGFscmVhZHlcbiAgICogdGVsbHMgdXMgYWJvdXQgdG9vLCBzbyB0aGUgcmVzdWx0IHNjcmVlbiBjYW4gc2hvdyBhIGNvbWJpbmVkIHdhbGxldCBjYXJkXG4gICAqIHdpdGggdGhlIHByb2dyYW0gbmFtZWQgaW5zdGVhZCBvZiBvbmUgdW5leHBsYWluZWQgdG90YWwuXG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBwcml2YXRlIGNvcnJlY3RlZENvbmZpcm1XYWxsZXRBbmRMb3lhbHR5KGQ6IGFueSk6IHsgd2FsbGV0OiBudW1iZXI7IGZvcmZlaXRlZExveWFsdHk6IG51bWJlciB9IHtcbiAgICBjb25zdCByb290V2FsbGV0ID0gTnVtYmVyKGQud2FsbGV0UmVmdW5kQW1vdW50ID8/IDApO1xuICAgIGNvbnN0IGZvcmZlaXRlZEZyb21Sb290ID0gdGhpcy5mb3JmZWl0ZWRMb3lhbHR5UG9pbnRzRmFsbGJhY2soZCk7XG4gICAgaWYgKGZvcmZlaXRlZEZyb21Sb290ID4gMCB8fCAhZC5sb3lhbHR5UGF5bWVudFR5cGUpIHtcbiAgICAgIHJldHVybiB7IHdhbGxldDogcm9vdFdhbGxldCwgZm9yZmVpdGVkTG95YWx0eTogZm9yZmVpdGVkRnJvbVJvb3QgfTtcbiAgICB9XG4gICAgY29uc3Qgb253YXJkID0gZC5sZWdJbmZvPy5vbndhcmQ7XG4gICAgY29uc3QgcmV0ID0gZC5sZWdJbmZvPy5yZXR1cm47XG4gICAgY29uc3QgbGVnID0gb253YXJkICYmICFyZXQgPyBvbndhcmQgOiByZXQgJiYgIW9ud2FyZCA/IHJldCA6IG51bGw7XG4gICAgaWYgKCFsZWcpIHJldHVybiB7IHdhbGxldDogcm9vdFdhbGxldCwgZm9yZmVpdGVkTG95YWx0eTogMCB9O1xuICAgIGNvbnN0IGxlZ0xveWFsdHkgPSBOdW1iZXIobGVnLnRvdGFsTG95YWx0eVBvaW50cyA/PyAwKTtcbiAgICBjb25zdCBsZWdXYWxsZXQgPSBOdW1iZXIobGVnLndhbGxldFJlZnVuZEFtb3VudCA/PyAwKTtcbiAgICAvLyBGdWxsIHN3YXA6IHJvb3QgcmVhZHMgdGhlIGxlZydzIGxveWFsdHkgYW1vdW50IHdoZXJlIGl0cyB3YWxsZXQgc2hvdWxkIGJlLlxuICAgIGlmIChcbiAgICAgIGxlZ0xveWFsdHkgPiAwICYmXG4gICAgICByb290V2FsbGV0ID09PSBsZWdMb3lhbHR5ICYmXG4gICAgICBsZWdXYWxsZXQgIT09IHJvb3RXYWxsZXQgJiZcbiAgICAgIE51bWJlcihkLnRvdGFsTG95YWx0eVBvaW50c1JlZnVuZEFtb3VudCA/PyAwKSA9PT0gMFxuICAgICkge1xuICAgICAgcmV0dXJuIHsgd2FsbGV0OiBsZWdXYWxsZXQsIGZvcmZlaXRlZExveWFsdHk6IGxlZ0xveWFsdHkgfTtcbiAgICB9XG4gICAgLy8gTHVtcCBzdW06IHJvb3Qgd2FsbGV0ID0gbGVnJ3MgY2FzaCB3YWxsZXQgKyBsZWcncyBmb3JmZWl0ZWQgbG95YWx0eS5cbiAgICBpZiAoXG4gICAgICBsZWdMb3lhbHR5ID4gMCAmJlxuICAgICAgbGVnV2FsbGV0ID4gMCAmJlxuICAgICAgTWF0aC5hYnMocm9vdFdhbGxldCAtIChsZWdXYWxsZXQgKyBsZWdMb3lhbHR5KSkgPCAxICYmXG4gICAgICBOdW1iZXIoZC50b3RhbExveWFsdHlQb2ludHNSZWZ1bmRBbW91bnQgPz8gMCkgPT09IDBcbiAgICApIHtcbiAgICAgIHJldHVybiB7IHdhbGxldDogbGVnV2FsbGV0LCBmb3JmZWl0ZWRMb3lhbHR5OiBsZWdMb3lhbHR5IH07XG4gICAgfVxuICAgIC8vIE5ld2VyIGAvY29uZmlybWAgcmVzcG9uc2VzIGRyb3AgdGhlIGxveWFsdHkgcG9ydGlvbiBmcm9tIGJvdGggcm9vdCBhbmRcbiAgICAvLyBsZWcgdG90YWxzIOKAlCBgd2FsbGV0UmVmdW5kQW1vdW50YCBhcnJpdmVzIGFzIG9uZSBvcGFxdWUgbHVtcCB0aGF0J3MgdGhlXG4gICAgLy8gY2FzaC13YWxsZXQgcG9ydGlvbiAoYHRvdGFsV2FsbGV0QW1vdW50YCkgcGx1cyBhIGxveWFsdHktcHJvZ3JhbSBhbW91bnQuXG4gICAgLy8gV2hlbiBgbG95YWx0eVBheW1lbnRUeXBlYCBpcyBzZXQsIHRoZSBsdW1wIGV4Y2VlZHMgdGhlIGNhc2gtd2FsbGV0XG4gICAgLy8gcG9ydGlvbiwgYW5kIGl0J3MgYSBnZW51aW5lIGNhcmQrd2FsbGV0IHNwbGl0IChub3QgYSBcInNlbmQgZXZlcnl0aGluZyB0b1xuICAgIC8vIHRoZSB3YWxsZXRcIiByZWZ1bmQpLCB0aGUgZGlmZmVyZW5jZSBpcyB0aGF0IGxveWFsdHkgYW1vdW50LlxuICAgIGNvbnN0IGNhc2hXYWxsZXQgPSBOdW1iZXIoZC50b3RhbFdhbGxldEFtb3VudCA/PyAwKTtcbiAgICBjb25zdCBpbXBsaWVkTG95YWx0eSA9IHJvb3RXYWxsZXQgLSBjYXNoV2FsbGV0O1xuICAgIGlmIChcbiAgICAgIGltcGxpZWRMb3lhbHR5ID4gMC4wMSAmJlxuICAgICAgY2FzaFdhbGxldCA+IDAgJiZcbiAgICAgIE51bWJlcihkLnRvdGFsQ2FyZFJlZnVuZEFtb3VudCA/PyAwKSA+IDAgJiZcbiAgICAgIE51bWJlcihkLnRvdGFsTG95YWx0eVBvaW50c1JlZnVuZEFtb3VudCA/PyAwKSA9PT0gMFxuICAgICkge1xuICAgICAgcmV0dXJuIHsgd2FsbGV0OiBjYXNoV2FsbGV0LCBmb3JmZWl0ZWRMb3lhbHR5OiBpbXBsaWVkTG95YWx0eSB9O1xuICAgIH1cbiAgICAvLyBUaGUgd2hvbGUgd2FsbGV0IHJlZnVuZCBpcyB0aGUgbG95YWx0eS1wcm9ncmFtIGJhbGFuY2Ug4oCUIG5vIGNhc2gtd2FsbGV0XG4gICAgLy8gcG9ydGlvbiAoYHRvdGFsV2FsbGV0QW1vdW50YCAwKSBhbmQgbm8gY2FyZCBwb3J0aW9uLCBidXRcbiAgICAvLyBgbG95YWx0eVBheW1lbnRUeXBlYCBpcyBzZXQuIEF0dHJpYnV0ZSBhbGwgb2YgaXQgdG8gdGhlIHByb2dyYW0gc28gdGhlXG4gICAgLy8gcG9wdXAgbmFtZXMgaXQgKGUuZy4gXCJXYWxhXCIpIHdpdGggdGhlIHBlcm1hbmVudC1wb2ludHMgbm90ZS5cbiAgICBpZiAoXG4gICAgICBjYXNoV2FsbGV0ID09PSAwICYmXG4gICAgICByb290V2FsbGV0ID4gMCAmJlxuICAgICAgTnVtYmVyKGQudG90YWxDYXJkUmVmdW5kQW1vdW50ID8/IDApID09PSAwICYmXG4gICAgICBOdW1iZXIoZC50b3RhbExveWFsdHlQb2ludHNSZWZ1bmRBbW91bnQgPz8gMCkgPT09IDBcbiAgICApIHtcbiAgICAgIHJldHVybiB7IHdhbGxldDogMCwgZm9yZmVpdGVkTG95YWx0eTogcm9vdFdhbGxldCB9O1xuICAgIH1cbiAgICByZXR1cm4geyB3YWxsZXQ6IHJvb3RXYWxsZXQsIGZvcmZlaXRlZExveWFsdHk6IDAgfTtcbiAgfVxuXG4gIC8qKiBIb3cgbWFueSBvZiB7d2FsbGV0LCBjYXJkLCBsb3lhbHR5fSB0aGUgcmVmdW5kIGlzIGFjdHVhbGx5IHNwbGl0IGFjcm9zcy4gKi9cbiAgcHJpdmF0ZSBzcGxpdFBhcnRzQ291bnQgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgZCA9IHRoaXMuYWRqdXN0ZWREYXRhKCk7XG4gICAgaWYgKCFkKSByZXR1cm4gMDtcbiAgICByZXR1cm4gW1xuICAgICAgZC53YWxsZXRSZWZ1bmRBbW91bnQsXG4gICAgICBkLnRvdGFsQ2FyZFJlZnVuZEFtb3VudCxcbiAgICAgIGQudG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50LFxuICAgICAgdGhpcy5mb3JmZWl0ZWRMb3lhbHR5UG9pbnRzRmFsbGJhY2soZCksXG4gICAgXS5maWx0ZXIoKHYpID0+IE51bWJlcih2ID8/IDApID4gMCkubGVuZ3RoO1xuICB9KTtcblxuICAvKipcbiAgICogQSBwb3J0aW9uIG9mIHRoZSByZWZ1bmQgaXMgZm9yY2VkIHRvIHRoZSB3YWxsZXQgKGUuZy4gbG95YWx0eSBwb2ludHMgdXNlZClcbiAgICog4oCUIGluIHRoYXQgY2FzZSBvZmZlciBhIFwiU3BsaXQgUmVmdW5kXCIgb3B0aW9uIGluc3RlYWQgb2YgYSBwdXJlXG4gICAqIG9yaWdpbmFsLXBheW1lbnQtbWV0aG9kIG9wdGlvbiwgc2luY2UgdGhlIHdob2xlIGFtb3VudCBjYW4ndCBnbyB0byBjYXJkLlxuICAgKi9cbiAgaGFzU3BsaXRSZWZ1bmQgPSBjb21wdXRlZChcbiAgICAoKSA9PiBOdW1iZXIodGhpcy5hZGp1c3RlZERhdGEoKT8udG90YWxSZWZ1bmRBbW91bnQgPz8gMCkgPiAwICYmIHRoaXMuc3BsaXRQYXJ0c0NvdW50KCkgPj0gMixcbiAgKTtcblxuICAvKipcbiAgICogV2FsbGV0IGNvdmVycyB0aGUgd2hvbGUgcmVmdW5kIChubyBjYXJkIG9yIGxveWFsdHkgcG9ydGlvbiBhdCBhbGwpIOKAlCBzaG93XG4gICAqIHRoZSB3YWxsZXQgb3B0aW9uIGFsb25lIHJhdGhlciB0aGFuIGEgXCJzcGxpdFwiIHdpdGggZW1wdHkgb3RoZXIgc2lkZXMuXG4gICAqL1xuICBpc1dhbGxldE9ubHlSZWZ1bmQgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgZCA9IHRoaXMuYWRqdXN0ZWREYXRhKCk7XG4gICAgcmV0dXJuIChcbiAgICAgIE51bWJlcihkPy53YWxsZXRSZWZ1bmRBbW91bnQgPz8gMCkgPiAwICYmXG4gICAgICBOdW1iZXIoZD8udG90YWxDYXJkUmVmdW5kQW1vdW50ID8/IDApID09PSAwICYmXG4gICAgICBOdW1iZXIoZD8udG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50ID8/IDApID09PSAwICYmXG4gICAgICB0aGlzLmZvcmZlaXRlZExveWFsdHlQb2ludHNGYWxsYmFjayhkKSA9PT0gMFxuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBUaGUgZW50aXJlIHJlZnVuZCBpcyBmb3JmZWl0ZWQgbG95YWx0eSBwb2ludHMgKGUuZy4gV2FsYSkgbGFuZGluZyBiYWNrIGFzXG4gICAqIHdhbGxldCBiYWxhbmNlIOKAlCBubyBjYXNoLXdhbGxldCwgY2FyZCwgY3JlZGl0IG9yIHJlYWxcbiAgICogbG95YWx0eS1wb2ludHMtcmVmdW5kIHBvcnRpb24gYXQgYWxsLiBXaXRob3V0IHRoaXMgdGhlIHBpY2tlciBmYWxsc1xuICAgKiB0aHJvdWdoIHRvIHRoZSBcIk9yaWdpbmFsIFBheW1lbnQgTWV0aG9kXCIgY2FyZCBhbmQgbWlzbGFiZWxzIHRoZVxuICAgKiBkZXN0aW5hdGlvbiBhcyB0aGUgb3JpZ2luYWwgZ2F0ZXdheSAoZS5nLiBcIlRhYmJ5XCIpLCBldmVuIHRob3VnaFxuICAgKiBgdG90YWxDYXJkUmVmdW5kQW1vdW50YCBpcyAwIGFuZCBub3RoaW5nIGdvZXMgYmFjayB0byB0aGF0IGNhcmQuXG4gICAqL1xuICBpc0xveWFsdHlPbmx5UmVmdW5kID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGQgPSB0aGlzLmFkanVzdGVkRGF0YSgpO1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmZvcmZlaXRlZExveWFsdHlQb2ludHNGYWxsYmFjayhkKSA+IDAgJiZcbiAgICAgIE51bWJlcihkPy53YWxsZXRSZWZ1bmRBbW91bnQgPz8gMCkgPT09IDAgJiZcbiAgICAgIE51bWJlcihkPy50b3RhbENhcmRSZWZ1bmRBbW91bnQgPz8gMCkgPT09IDAgJiZcbiAgICAgIE51bWJlcihkPy50b3RhbENyZWRpdFJlZnVuZEFtb3VudCA/PyAwKSA9PT0gMCAmJlxuICAgICAgTnVtYmVyKGQ/LnRvdGFsTG95YWx0eVBvaW50c1JlZnVuZEFtb3VudCA/PyAwKSA9PT0gMFxuICAgICk7XG4gIH0pO1xuXG4gIC8qKiBBIHJlYWwgY2FzaC13YWxsZXQgcG9ydGlvbiBpcyBwYXJ0IG9mIHRoZSByZWZ1bmQgKGRpc3RpbmN0IGZyb20gZm9yZmVpdGVkIGxveWFsdHkgcG9pbnRzIGxhbmRpbmcgaW4gdGhlIHdhbGxldCkuICovXG4gIGhhc0Nhc2hXYWxsZXRSZWZ1bmQgPSBjb21wdXRlZChcbiAgICAoKSA9PiBOdW1iZXIodGhpcy5hZGp1c3RlZERhdGEoKT8ud2FsbGV0UmVmdW5kQW1vdW50ID8/IDApID4gMCxcbiAgKTtcblxuICAvKipcbiAgICogV2FsbGV0IGNhcmQncyB0aXRsZSDigJQgbm9ybWFsbHkgXCJBbG1hdGFyIFdhbGxldFwiLCBidXQgdGhlIGxveWFsdHkgcHJvZ3JhbVxuICAgKiBuYW1lIChXYWxhLCBRaXRhZiwg4oCmKSB3aGVuIHRoZSB3aG9sZSByZWZ1bmQgaXMgdGhhdCBwcm9ncmFtJ3MgZm9yZmVpdGVkXG4gICAqIGJhbGFuY2UgbGFuZGluZyBiYWNrIGluIHRoZSB3YWxsZXQuXG4gICAqL1xuICB3YWxsZXRDYXJkTGFiZWwgPSBjb21wdXRlZCgoKSA9PlxuICAgIHRoaXMuaXNMb3lhbHR5T25seVJlZnVuZCgpXG4gICAgICA/IHRoaXMud2FsbGV0T3JMb3lhbHR5TGFiZWwodGhpcy5hZGp1c3RlZERhdGEoKSkgfHwgJ0FsbWF0YXIgV2FsbGV0J1xuICAgICAgOiAnQWxtYXRhciBXYWxsZXQnLFxuICApO1xuXG4gIC8qKlxuICAgKiBQYXJ0IG9mIHRoZSByZWZ1bmQgY2FtZSBmcm9tIGNvbnZlcnRpbmcgZXh0ZXJuYWwgbG95YWx0eSBwb2ludHMgaW50b1xuICAgKiB3YWxsZXQgZnVuZHMg4oCUIHN1cmZhY2VkIGFzIGEgbm90ZSB1bmRlciB0aGUgd2FsbGV0IGRlc3RpbmF0aW9uIHNvIHRoZVxuICAgKiBhZ2VudCBrbm93cyB0aG9zZSBwb2ludHMgbGFuZCBhcyBwZXJtYW5lbnQgd2FsbGV0IGJhbGFuY2UsIG5vdCBjYXNoLlxuICAgKi9cbiAgaGFzTG95YWx0eVBvaW50c1JlZnVuZCA9IGNvbXB1dGVkKFxuICAgICgpID0+IE51bWJlcih0aGlzLmFkanVzdGVkRGF0YSgpPy50b3RhbExveWFsdHlQb2ludHMgPz8gMCkgPiAwLFxuICApO1xuXG4gIC8qKlxuICAgKiBUaGUgYm9va2luZyBpcyByZWZ1bmRhYmxlIGJ1dCBuZXRzIHRvIDAuMDAgYWZ0ZXIgZGVkdWN0aW9ucyDigJQgYVxuICAgKiBkZWRpY2F0ZWQgTklMIFJlZnVuZCBzdGF0ZSwgZGlzdGluY3QgZnJvbSBcIm5vdCByZWZ1bmRhYmxlXCI6IG5vIHJlZnVuZFxuICAgKiBtZXRob2QgdG8gY2hvb3NlIGJldHdlZW4sIGp1c3QgY29uZmlybWF0aW9uIHRoYXQgbm90aGluZyBpcyBvd2VkIGJhY2suXG4gICAqL1xuICBpc05pbFJlZnVuZCA9IGNvbXB1dGVkKCgpOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBkID0gdGhpcy5hZGp1c3RlZERhdGEoKTtcbiAgICByZXR1cm4gISFkPy5pc1JlZnVuZGFibGUgJiYgTnVtYmVyKGQudG90YWxSZWZ1bmRBbW91bnQgPz8gMCkgPT09IDA7XG4gIH0pO1xuXG4gIC8qKiBTYW1lIGFzIGBpc05pbFJlZnVuZGAsIHNjb3BlZCB0byB0aGUgY29uZmlybWVkIGNhbmNlbGxhdGlvbiByZXN1bHQg4oCUIGRyaXZlcyB0aGUgcmVzdWx0IHNjcmVlbidzIHRpdGxlLiAqL1xuICBjb25maXJtSXNOaWxSZWZ1bmQgPSBjb21wdXRlZCgoKTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3QgZCA9IHRoaXMuY2FuY2VsUmVzdWx0KCk7XG4gICAgcmV0dXJuICEhZD8uaXNSZWZ1bmRhYmxlICYmIE51bWJlcihkLnRvdGFsUmVmdW5kQW1vdW50ID8/IDApID09PSAwO1xuICB9KTtcblxuICAvKiogV2hldGhlciB0aGUgY3VzdG9tZXIgbWF5IHNlbmQgdGhlIHdob2xlIHJlZnVuZCB0byB0aGVpciBBbG1hdGFyIFdhbGxldC4gKi9cbiAgaXNGdWxsV2FsbGV0UmVmdW5kQWxsb3dlZCA9IGNvbXB1dGVkKCgpID0+ICEhdGhpcy5hZGp1c3RlZERhdGEoKT8uaXNGdWxsV2FsbGV0UmVmdW5kQWxsb3dlZCk7XG5cbiAgLyoqIFdoZXRoZXIgdGhlIGN1c3RvbWVyIHBhaWQgdmlhIGFuIGluc3RhbGxtZW50IGdhdGV3YXkgKFRhbWFyYSwgVGFiYnksIOKApikuICovXG4gIGlzSW5zdGFsbG1lbnRNZXRob2QgPSBjb21wdXRlZCgoKSA9PlxuICAgIElOU1RBTExNRU5UX0dBVEVXQVlfQ09ERVMuaW5jbHVkZXMoXG4gICAgICB0aGlzLm5vcm1hbGl6ZUdhdGV3YXlDb2RlKHRoaXMuYWRqdXN0ZWREYXRhKCk/LnBheW1lbnRNZXRob2RDdXN0b21lclVzZWQpLFxuICAgICksXG4gICk7XG5cbiAgLyoqIFdoZXRoZXIgdGhlIGN1c3RvbWVyIHBhaWQgdmlhIGEgbG95YWx0eS1wcm9ncmFtIGdhdGV3YXkgKEFsIFJhamhpIE1va2FmYWEsIOKApikuICovXG4gIGlzTG95YWx0eU1ldGhvZCA9IGNvbXB1dGVkKCgpID0+XG4gICAgTE9ZQUxUWV9HQVRFV0FZX0NPREVTLmluY2x1ZGVzKFxuICAgICAgdGhpcy5ub3JtYWxpemVHYXRld2F5Q29kZSh0aGlzLmFkanVzdGVkRGF0YSgpPy5wYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkKSxcbiAgICApLFxuICApO1xuXG4gIC8qKiBBbnkgZ2F0ZXdheSB0aGF0IHJlZnVuZHMgc29tZXdoZXJlIG90aGVyIHRoYW4gYSBwbGFpbiBjYXJkIOKAlCB1c2VkIGZvciB0aGUgd2FsbGV0LXN0eWxlIGljb24uICovXG4gIGlzU3BlY2lhbEdhdGV3YXlNZXRob2QgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmlzSW5zdGFsbG1lbnRNZXRob2QoKSB8fCB0aGlzLmlzTG95YWx0eU1ldGhvZCgpKTtcblxuICAvKipcbiAgICogQ2FyZC1yZWZ1bmQgc2V0dGxlbWVudC10aW1lbGluZSBiYWRnZSDigJQgVGFiYnkgYW5kIFRhbWFyYSBlYWNoIGhhdmUgdGhlaXJcbiAgICogb3duIHByb2Nlc3Npbmcgd2luZG93LCBkaXN0aW5jdCBmcm9tIGEgcGxhaW4gY2FyZCdzIGdlbmVyaWMgYmFuayBwb2xpY3kuXG4gICAqL1xuICBjYXJkQmFkZ2VUZXh0ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGNvZGUgPSB0aGlzLm5vcm1hbGl6ZUdhdGV3YXlDb2RlKHRoaXMuYWRqdXN0ZWREYXRhKCk/LnBheW1lbnRNZXRob2RDdXN0b21lclVzZWQpO1xuICAgIGlmIChjb2RlID09PSAnVEInKSByZXR1cm4gJ0Zyb20gNS03IGJ1c2luZXNzIGRheXMnO1xuICAgIGlmIChjb2RlID09PSAnVE0nKSByZXR1cm4gJ1VwIHRvIDEwIGJ1c2luZXNzIGRheXMnO1xuICAgIGlmICh0aGlzLmlzTG95YWx0eU1ldGhvZCgpKSByZXR1cm4gJ0xveWFsdHkgUHJvZ3JhbSBQb2xpY3knO1xuICAgIHJldHVybiAnVXAgdG8gMTUgYnVzaW5lc3MgZGF5cywgYmFuayBwb2xpY3knO1xuICB9KTtcblxuICAvKiogU2FtZSBhcyBgY2FyZEJhZGdlVGV4dGAsIHNjb3BlZCB0byB0aGUgY29uZmlybWVkIGNhbmNlbGxhdGlvbiByZXN1bHQuICovXG4gIGNvbmZpcm1DYXJkQmFkZ2VUZXh0ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgZDogYW55ID0gdGhpcy5jYW5jZWxSZXN1bHQoKTtcbiAgICBjb25zdCBjb2RlID0gdGhpcy5ub3JtYWxpemVHYXRld2F5Q29kZShkPy5wYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkKTtcbiAgICBpZiAoY29kZSA9PT0gJ1RCJykgcmV0dXJuICdGcm9tIDUtNyBidXNpbmVzcyBkYXlzJztcbiAgICBpZiAoY29kZSA9PT0gJ1RNJykgcmV0dXJuICdVcCB0byAxMCBidXNpbmVzcyBkYXlzJztcbiAgICBpZiAoTE9ZQUxUWV9HQVRFV0FZX0NPREVTLmluY2x1ZGVzKGNvZGUpKSByZXR1cm4gJ0xveWFsdHkgUHJvZ3JhbSBQb2xpY3knO1xuICAgIHJldHVybiAnVXAgdG8gMTUgYnVzaW5lc3MgZGF5cywgYmFuayBwb2xpY3knO1xuICB9KTtcblxuICAvKipcbiAgICogUGVyLW1ldGhvZCBicmVha2Rvd24gb2YgdGhlIFwiVG90YWwgcGFpZFwiIGFtb3VudC4gVGhlIGJhY2tlbmQgZG9lc24ndFxuICAgKiAoeWV0KSBleHBvc2UgYSBkZWRpY2F0ZWQgb3JpZ2luYWwtcGF5bWVudCBicmVha2Rvd24sIHNvIHRoZSBrbm93blxuICAgKiByZWZ1bmQtZGVzdGluYXRpb24gZmllbGRzIChjYXJkIC8gd2FsbGV0IC8gbG95YWx0eSkgYXJlIHVzZWQgYXMgYSBwcm94eVxuICAgKiBmb3IgaG93IHRoZSBib29raW5nIHdhcyBvcmlnaW5hbGx5IHBhaWQsIGFuZCB3aGF0ZXZlcidzIGxlZnQgb3ZlciBhZnRlclxuICAgKiB0aG9zZSAoZS5nLiBhIG5vbi1yZWZ1bmRhYmxlIGxlZy9mZWUgdGhhdCBuZXZlciBzaG93cyB1cCBpbiBhbnkgcmVmdW5kXG4gICAqIGZpZWxkKSBpcyBmb2xkZWQgaW50byB0aGUgcHJpbWFyeSBwYXltZW50IG1ldGhvZCDigJQgc28gdGhlIHJvd3MgYWx3YXlzXG4gICAqIGFkZCB1cCB0byB0aGUgZnVsbCBgb3JpZ2luYWxBbW91bnRgIHNob3duIGFib3ZlIHRoZW0sIGluc3RlYWQgb2Ygb25seVxuICAgKiBjb3ZlcmluZyB0aGUgcmVmdW5kYWJsZSBwb3J0aW9uLlxuICAgKi9cbiAgcGFpZEJyZWFrZG93blJvd3MgPSBjb21wdXRlZCgoKTogeyBsYWJlbDogc3RyaW5nOyB2YWx1ZTogbnVtYmVyIH1bXSA9PiB7XG4gICAgY29uc3QgZCA9IHRoaXMuYWRqdXN0ZWREYXRhKCk7XG4gICAgaWYgKCFkKSByZXR1cm4gW107XG4gICAgLy8gQ2FyZCBhbmQgbG95YWx0eSBzdGF5IGRpc3RpbmN0IGxhYmVscyAoc2FtZSBjYXRlZ29yaXphdGlvbiBhc1xuICAgIC8vIGByZWZ1bmRzYCkgc28gYSBnYXRld2F5IGxpa2UgQWwgUmFqaGkgTW9rYWZhYSBkb2Vzbid0IHN3YWxsb3cgYW5cbiAgICAvLyBhY3R1YWwgc2VwYXJhdGUgY2FyZCBwb3J0aW9uIHVuZGVyIG9uZSBsYWJlbC5cbiAgICBjb25zdCBjYXJkTGFiZWwgPVxuICAgICAgKCF0aGlzLmlzTG95YWx0eU1ldGhvZCgpICYmIHRoaXMuY3VzdG9tZXJQYXltZW50TGFiZWwoKSkgfHwgJ09yaWdpbmFsIFBheW1lbnQgTWV0aG9kJztcbiAgICAvLyBUaGUgd2FsbGV0IGRlc3RpbmF0aW9uIHJvdyBhbHdheXMgcmVhZHMgXCJBbG1hdGFyIFdhbGxldFwiIOKAlCB1bmxpa2VcbiAgICAvLyBgcmVmdW5kc2AvYGNvbmZpcm1SZWZ1bmRzYCwgdGhpcyByb3cgbmV2ZXIgc3dhcHMgdG8gdGhlIGxveWFsdHlcbiAgICAvLyBwcm9ncmFtIG5hbWUsIHNpbmNlIGBmb3JmZWl0ZWRMb3lhbHR5TGFiZWxgIGJlbG93IGlzIHRoYXQgcHJvZ3JhbSdzXG4gICAgLy8gb3duIGRlZGljYXRlZCByb3cgYW5kIHRoZSB0d28gbXVzdCBzdGF5IHZpc3VhbGx5IGRpc3RpbmN0IGhlcmUuXG4gICAgY29uc3Qgd2FsbGV0TGFiZWwgPSAnQWxtYXRhciBXYWxsZXQnO1xuICAgIGNvbnN0IGZvcmZlaXRlZExveWFsdHlMYWJlbCA9IHRoaXMud2FsbGV0T3JMb3lhbHR5TGFiZWwoZCkgfHwgJ0xveWFsdHkgUG9pbnRzJztcbiAgICBjb25zdCBsb3lhbHR5TGFiZWwgPSB0aGlzLmN1c3RvbWVyUGF5bWVudExhYmVsKCkgfHwgJ0xveWFsdHkgUG9pbnRzIFJlZnVuZCc7XG4gICAgY29uc3QgYW1vdW50cyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gICAgY29uc3QgYWRkID0gKGxhYmVsOiBzdHJpbmcsIHZhbHVlOiBudW1iZXIpID0+IHtcbiAgICAgIGlmICh2YWx1ZSA8PSAwKSByZXR1cm47XG4gICAgICBhbW91bnRzLnNldChsYWJlbCwgKGFtb3VudHMuZ2V0KGxhYmVsKSA/PyAwKSArIHZhbHVlKTtcbiAgICB9O1xuICAgIGFkZChjYXJkTGFiZWwsIE51bWJlcihkLnRvdGFsQ2FyZFJlZnVuZEFtb3VudCA/PyAwKSk7XG4gICAgLy8gVGhpcyByb3cgc2hvd3MgaG93IG11Y2ggb2YgdGhlICpvcmlnaW5hbCogcGF5bWVudCB3ZW50IHRocm91Z2ggdGhlXG4gICAgLy8gd2FsbGV0IOKAlCBgdG90YWxXYWxsZXRBbW91bnRgLCBub3QgYHdhbGxldFJlZnVuZEFtb3VudGAgKGEgcmVmdW5kXG4gICAgLy8gZGVzdGluYXRpb24gYW1vdW50IHRoYXQgY2FuIGRpZmZlciwgZS5nLiBvbmx5IHBhcnQgb2YgdGhlIHdhbGxldFxuICAgIC8vIHBheW1lbnQgaXMgcmVmdW5kYWJsZSBhZnRlciBkZWR1Y3Rpb25zKS5cbiAgICBhZGQod2FsbGV0TGFiZWwsIE51bWJlcihkLnRvdGFsV2FsbGV0QW1vdW50ID8/IDApKTtcbiAgICBhZGQobG95YWx0eUxhYmVsLCBOdW1iZXIoZC50b3RhbExveWFsdHlQb2ludHNSZWZ1bmRBbW91bnQgPz8gMCkpO1xuICAgIC8vIGB0b3RhbExveWFsdHlQb2ludHNgIGlzIHRoZSBwb3J0aW9uIG9mIHRoZSAqb3JpZ2luYWwqIHBheW1lbnQgbWFkZSB3aXRoXG4gICAgLy8gbG95YWx0eSBwb2ludHMgKG5vdyBmb3JmZWl0ZWQvZGVkdWN0ZWQsIG5vdCByZWZ1bmRlZCkg4oCUIGRpc3RpbmN0IGZyb21cbiAgICAvLyBgdG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50YCBhYm92ZSBhbmQgZnJvbSBgd2FsbGV0UmVmdW5kQW1vdW50YFxuICAgIC8vIChhbiB1bnJlbGF0ZWQgcmVmdW5kLWRlc3RpbmF0aW9uIGFtb3VudCkuIEFsd2F5cyBzaG93biBhcyBpdHMgb3duIHJvd1xuICAgIC8vIHVuZGVyIHRoZSBwcm9ncmFtIG5hbWUgKGUuZy4gXCJRaXRhZlwiL1wiV2FsYVwiKSByYXRoZXIgdGhhbiBtZXJnZWQgaW50b1xuICAgIC8vIHRoZSBnZW5lcmljIFdhbGxldCByb3cgb3Igc2lsZW50bHkgZm9sZGVkIGludG8gdGhlIGxlZnRvdmVyIHJlbWFpbmRlci5cbiAgICBhZGQoZm9yZmVpdGVkTG95YWx0eUxhYmVsLCBOdW1iZXIoZC50b3RhbExveWFsdHlQb2ludHMgPz8gMCkpO1xuXG4gICAgY29uc3QgdG90YWwgPSBOdW1iZXIoZC5vcmlnaW5hbEFtb3VudCA/PyAwKTtcbiAgICBjb25zdCBrbm93biA9IFsuLi5hbW91bnRzLnZhbHVlcygpXS5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiLCAwKTtcbiAgICBjb25zdCByZW1haW5kZXIgPSB0b3RhbCAtIGtub3duO1xuICAgIGlmIChyZW1haW5kZXIgPiAwLjAxKSB7XG4gICAgICAvLyBVbmFjY291bnRlZCBsZWZ0b3ZlciAoZS5nLiBhIG5vbi1yZWZ1bmRhYmxlIHBvcnRpb24pIGlzIGZvbGRlZCBpbnRvXG4gICAgICAvLyB0aGUgcHJpbWFyeS9kZWZhdWx0IHBheW1lbnQgY2hhbm5lbCByYXRoZXIgdGhhbiBhIGZhYnJpY2F0ZWQgNHRoIHJvdy5cbiAgICAgIGFkZChjYXJkTGFiZWwsIHJlbWFpbmRlcik7XG4gICAgfVxuICAgIHJldHVybiBbLi4uYW1vdW50cy5lbnRyaWVzKCldLm1hcCgoW2xhYmVsLCB2YWx1ZV0pID0+ICh7IGxhYmVsLCB2YWx1ZSB9KSk7XG4gIH0pO1xuXG4gIC8qKiBUaGUgXCJUb3RhbCBwYWlkXCIgcm93IGFsd2F5cyBleHBhbmRzIOKAlCB0aGVyZSdzIGFsd2F5cyBhdCBsZWFzdCBvbmUgbWV0aG9kIHRvIHNob3cuICovXG4gIGhhc1BhaWRCcmVha2Rvd24gPSBjb21wdXRlZCgoKSA9PiB0aGlzLnBhaWRCcmVha2Rvd25Sb3dzKCkubGVuZ3RoID4gMCk7XG5cbiAgdG9nZ2xlUGFpZFN1bW1hcnkoKSB7XG4gICAgdGhpcy5wYWlkU3VtbWFyeUV4cGFuZGVkLnNldCghdGhpcy5wYWlkU3VtbWFyeUV4cGFuZGVkKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYWNrZW5kIGhhcyBzZW50IGBwYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkYCBhcyBib3RoIGEgc2hvcnQgY29kZVxuICAgKiAoYFwiQ0hcImApIGFuZCBhIGZ1bGwgZ2F0ZXdheSBuYW1lIChgXCJDYXJkXCJgKSBhdCBkaWZmZXJlbnQgdGltZXMg4oCUIG1hdGNoXG4gICAqIGVpdGhlciwgY2FzZS1pbnNlbnNpdGl2ZWx5LCBhZ2FpbnN0IHRoZSBrbm93biBjb2Rlcy9sYWJlbHMgcmF0aGVyIHRoYW5cbiAgICogYXNzdW1pbmcgb25lIGZvcm1hdC5cbiAgICovXG4gIHByaXZhdGUgbm9ybWFsaXplR2F0ZXdheUNvZGUocmF3Pzogc3RyaW5nIHwgbnVsbCk6IHN0cmluZyB7XG4gICAgaWYgKCFyYXcpIHJldHVybiAnJztcbiAgICBjb25zdCBuZWVkbGUgPSByYXcudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3QgY29kZXMgPSBPYmplY3Qua2V5cyhQQVlNRU5UX0dBVEVXQVlfTEFCRUxTKTtcbiAgICBjb25zdCBieUNvZGUgPSBjb2Rlcy5maW5kKChjb2RlKSA9PiBjb2RlLnRvTG93ZXJDYXNlKCkgPT09IG5lZWRsZSk7XG4gICAgaWYgKGJ5Q29kZSkgcmV0dXJuIGJ5Q29kZTtcbiAgICByZXR1cm4gY29kZXMuZmluZCgoY29kZSkgPT4gUEFZTUVOVF9HQVRFV0FZX0xBQkVMU1tjb2RlXS50b0xvd2VyQ2FzZSgpID09PSBuZWVkbGUpID8/ICcnO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc3BsYXkgbGFiZWwgZm9yIGBwYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkYCwgb3IgJycgaWYgdW5rbm93bi9pbnRlcm5hbC5cbiAgICogTmV2ZXIgc3VyZmFjZXMgYW4gaW50ZXJuYWwgcHJvY2Vzc29yIG5hbWUgKGUuZy4gSHlwZXJwYXkpIHRvIHRoZSBhZ2VudCDigJRcbiAgICogY2FsbGVycyBmYWxsIGJhY2sgdG8gYSBnZW5lcmljIFwiT3JpZ2luYWwgUGF5bWVudCBNZXRob2RcIiBsYWJlbCB3aGVuZXZlclxuICAgKiB0aGlzIHJldHVybnMgJycuXG4gICAqL1xuICBjdXN0b21lclBheW1lbnRMYWJlbCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBjb2RlID0gdGhpcy5ub3JtYWxpemVHYXRld2F5Q29kZSh0aGlzLmFkanVzdGVkRGF0YSgpPy5wYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkKTtcbiAgICBpZiAoY29kZSAmJiBJTlRFUk5BTF9HQVRFV0FZX0NPREVTLmluY2x1ZGVzKGNvZGUpKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIGNvZGUgPyBQQVlNRU5UX0dBVEVXQVlfTEFCRUxTW2NvZGVdIDogJyc7XG4gIH0pO1xuXG4gIC8qKiBXaGV0aGVyIHRoZSBjb25maXJtZWQgY2FuY2VsbGF0aW9uJ3MgY2FyZCByZWZ1bmQgc2V0dGxlcyB2aWEgTWFkYS4gKi9cbiAgaXNNYWRhTWV0aG9kID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGNvZGUgPSB0aGlzLm5vcm1hbGl6ZUdhdGV3YXlDb2RlKHRoaXMuYWRqdXN0ZWREYXRhKCk/LnBheW1lbnRNZXRob2RDdXN0b21lclVzZWQpO1xuICAgIHJldHVybiAhIWNvZGUgJiYgTUFEQV9HQVRFV0FZX0NPREVTLmluY2x1ZGVzKGNvZGUpO1xuICB9KTtcblxuICAvKipcbiAgICogTGFiZWwgZm9yIHRoZSBzdGFuZGFsb25lIFwiT3JpZ2luYWwgUGF5bWVudCBNZXRob2RcIiBvcHRpb24gY2FyZCAoc2hvd25cbiAgICogd2hlbiB0aGUgd2hvbGUgcmVmdW5kIGdvZXMgdG8gb25lIGRlc3RpbmF0aW9uKS4gTWFkYSB3aW5zIG92ZXJcbiAgICogZXZlcnl0aGluZyBlbHNlLCByZWFkaW5nIFwiTWFkYSBDYXJkXCIgaW5zdGVhZCBvZiB0aGUgZ2VuZXJpYyBnYXRld2F5XG4gICAqIG5hbWUgb3IgdGhlIFwiT3JpZ2luYWwgUGF5bWVudCBNZXRob2RcIiBmYWxsYmFjay5cbiAgICovXG4gIG9yaWdpbmFsUGF5bWVudExhYmVsID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGlmICh0aGlzLmlzTWFkYU1ldGhvZCgpKSByZXR1cm4gJ01hZGEgQ2FyZCc7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tZXJQYXltZW50TGFiZWwoKSB8fCAnT3JpZ2luYWwgUGF5bWVudCBNZXRob2QnO1xuICB9KTtcblxuICAvKiogU2FtZSBhcyBgaXNNYWRhTWV0aG9kYCwgc2NvcGVkIHRvIHRoZSBjb25maXJtZWQgY2FuY2VsbGF0aW9uIHJlc3VsdC4gKi9cbiAgY29uZmlybUlzTWFkYU1ldGhvZCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBjb2RlID0gdGhpcy5ub3JtYWxpemVHYXRld2F5Q29kZSh0aGlzLmNhbmNlbFJlc3VsdCgpPy5wYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkKTtcbiAgICByZXR1cm4gISFjb2RlICYmIE1BREFfR0FURVdBWV9DT0RFUy5pbmNsdWRlcyhjb2RlKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqIFNwbGl0LXJlZnVuZCBkZXN0aW5hdGlvbiByb3dzIOKAlCB1cCB0byBmb3VyOiBBbG1hdGFyIFdhbGxldCAoZ2VuZXJpY1xuICAgKiBsYWJlbCksIHRoZSBvcmlnaW5hbCBwYXltZW50IG1ldGhvZCAoY2FyZC9pbnN0YWxsbWVudCBnYXRld2F5KSwgYVxuICAgKiBzZXBhcmF0ZSBsb3lhbHR5LXBvaW50cy1yZWZ1bmQgcm93IHdoZW4gdGhlIGJhY2tlbmQgc2VuZHMgb25lLCBhbmQgYVxuICAgKiBkZWRpY2F0ZWQgbG95YWx0eS1wcm9ncmFtIHJvdyAoV2FsYSwgUWl0YWYsIOKApikgZm9yIGZvcmZlaXRlZCBwb2ludHNcbiAgICogKGBmb3JmZWl0ZWRMb3lhbHR5UG9pbnRzRmFsbGJhY2tgKSDigJQga2VwdCBkaXN0aW5jdCBmcm9tIHRoZSBXYWxsZXQgcm93XG4gICAqIGV2ZW4gd2hlbiBib3RoIGFyZSBub24temVyby5cbiAgICovXG4gIHNwbGl0UmVmdW5kUm93cyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBkID0gdGhpcy5hZGp1c3RlZERhdGEoKTtcbiAgICBpZiAoIWQpIHJldHVybiBbXTtcbiAgICBjb25zdCByb3dzOiB7IGxhYmVsOiBzdHJpbmc7IHZhbHVlOiBudW1iZXI7IGluc3RhbnQ6IGJvb2xlYW47IGlzTG95YWx0eTogYm9vbGVhbjsgYmFkZ2VUZXh0OiBzdHJpbmc7IGlzTWFkYT86IGJvb2xlYW4gfVtdID0gW107XG4gICAgY29uc3Qgd2FsbGV0ID0gTnVtYmVyKGQud2FsbGV0UmVmdW5kQW1vdW50ID8/IDApO1xuICAgIGlmICh3YWxsZXQgPiAwKSB7XG4gICAgICByb3dzLnB1c2goeyBsYWJlbDogJ0FsbWF0YXIgV2FsbGV0JywgdmFsdWU6IHdhbGxldCwgaW5zdGFudDogdHJ1ZSwgaXNMb3lhbHR5OiBmYWxzZSwgYmFkZ2VUZXh0OiAnSW5zdGFudCcgfSk7XG4gICAgfVxuICAgIGNvbnN0IGNhcmQgPSBOdW1iZXIoZC50b3RhbENhcmRSZWZ1bmRBbW91bnQgPz8gMCk7XG4gICAgaWYgKGNhcmQgPiAwKSB7XG4gICAgICBjb25zdCBiYWRnZVRleHQgPSB0aGlzLmNhcmRCYWRnZVRleHQoKTtcbiAgICAgIHJvd3MucHVzaCh7XG4gICAgICAgIGxhYmVsOiB0aGlzLmlzTWFkYU1ldGhvZCgpXG4gICAgICAgICAgPyAnTWFkYSBDYXJkJ1xuICAgICAgICAgIDogKCF0aGlzLmlzTG95YWx0eU1ldGhvZCgpICYmIHRoaXMuY3VzdG9tZXJQYXltZW50TGFiZWwoKSkgfHwgJ09yaWdpbmFsIFBheW1lbnQgTWV0aG9kJyxcbiAgICAgICAgdmFsdWU6IGNhcmQsXG4gICAgICAgIGluc3RhbnQ6IGZhbHNlLFxuICAgICAgICBpc0xveWFsdHk6IGZhbHNlLFxuICAgICAgICBiYWRnZVRleHQsXG4gICAgICAgIGlzTWFkYTogdGhpcy5pc01hZGFNZXRob2QoKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjb25zdCBsb3lhbHR5ID0gTnVtYmVyKGQudG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50ID8/IDApO1xuICAgIGlmIChsb3lhbHR5ID4gMCkge1xuICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAgbGFiZWw6IHRoaXMuY3VzdG9tZXJQYXltZW50TGFiZWwoKSB8fCAnTG95YWx0eSBQb2ludHMgUmVmdW5kJyxcbiAgICAgICAgdmFsdWU6IGxveWFsdHksXG4gICAgICAgIGluc3RhbnQ6IHRydWUsXG4gICAgICAgIGlzTG95YWx0eTogdHJ1ZSxcbiAgICAgICAgYmFkZ2VUZXh0OiAnSW5zdGFudCcsXG4gICAgICB9KTtcbiAgICB9XG4gICAgY29uc3QgZm9yZmVpdGVkTG95YWx0eSA9IHRoaXMuZm9yZmVpdGVkTG95YWx0eVBvaW50c0ZhbGxiYWNrKGQpO1xuICAgIGlmIChmb3JmZWl0ZWRMb3lhbHR5ID4gMCkge1xuICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAgbGFiZWw6IHRoaXMud2FsbGV0T3JMb3lhbHR5TGFiZWwoZCkgfHwgJ0xveWFsdHkgUG9pbnRzJyxcbiAgICAgICAgdmFsdWU6IGZvcmZlaXRlZExveWFsdHksXG4gICAgICAgIGluc3RhbnQ6IHRydWUsXG4gICAgICAgIGlzTG95YWx0eTogdHJ1ZSxcbiAgICAgICAgYmFkZ2VUZXh0OiAnSW5zdGFudCcsXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJvd3M7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBXYWxsZXQtcm93IGxhYmVsIGZvciBhIGxveWFsdHktcHJvZ3JhbSByZWRlbXB0aW9uIOKAlCBgbG95YWx0eVBheW1lbnRUeXBlYFxuICAgKiAoZS5nLiBXYWxhLCBRaXRhZikgbmFtZXMgdGhlIHByb2dyYW0gdGhhdCByZWRlZW1lZCBpbnRvIHRoZSB3YWxsZXRcbiAgICogYmFsYW5jZSBhbmQgYXBwbGllcyByZWdhcmRsZXNzIG9mIGBwYXltZW50TWV0aG9kQ3VzdG9tZXJVc2VkYDsgdGhlXG4gICAqIGJhY2tlbmQgY2FuIHJlcG9ydCBhbiB1bnJlbGF0ZWQgb3JpZ2luYWwgcGF5bWVudCBnYXRld2F5IChlLmcuIFRhYmJ5KVxuICAgKiBhbG9uZ3NpZGUgYSB3YWxsZXQgcG9ydGlvbiB0aGF0J3MgYWN0dWFsbHkgYSBsb3lhbHR5IHJlZGVtcHRpb24uXG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICB3YWxsZXRPckxveWFsdHlMYWJlbChkOiBhbnkpOiBzdHJpbmcge1xuICAgIGNvbnN0IGxveWFsdHkgPSBkPy5sb3lhbHR5UGF5bWVudFR5cGUgPz8gJyc7XG4gICAgcmV0dXJuIFBBWU1FTlRfR0FURVdBWV9MQUJFTFNbbG95YWx0eV0gPz8gJyc7XG4gIH1cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMudmlzaWJsZSgpICYmIHRoaXMuYm9va2luZ0lkKCkpIHtcbiAgICAgICAgdGhpcy5sb2FkUmVmdW5kKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnN0b3BIaW50cygpO1xuICAgICAgICB0aGlzLnJlZnVuZERhdGEuc2V0KG51bGwpO1xuICAgICAgICB0aGlzLmNhbmNlbFJlc3VsdC5zZXQobnVsbCk7XG4gICAgICAgIHRoaXMub253YXJkQ2hlY2tlZC5zZXQodHJ1ZSk7XG4gICAgICAgIHRoaXMucmV0dXJuQ2hlY2tlZC5zZXQodHJ1ZSk7XG4gICAgICAgIHRoaXMuZm9yY2VkTGVnVHlwZS5zZXQobnVsbCk7XG4gICAgICAgIHRoaXMub253YXJkRXhwYW5kZWQuc2V0KHRydWUpO1xuICAgICAgICB0aGlzLnJldHVybkV4cGFuZGVkLnNldCh0cnVlKTtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFNvdXJjZS5zZXQoJycpO1xuICAgICAgICB0aGlzLnByZWZlcnJlZFJlZnVuZE1ldGhvZC5zZXQoJ29yaWdpbmFsUGF5bWVudE1ldGhvZCcpO1xuICAgICAgICB0aGlzLmNvbmZpcm1pbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgdGhpcy5jYW5jZWxsaW5nLnNldChmYWxzZSk7XG4gICAgICAgIHRoaXMuc3RlcC5zZXQoJ2xvYWRpbmcnKTtcbiAgICAgIH1cbiAgICB9LCB7IGFsbG93U2lnbmFsV3JpdGVzOiB0cnVlIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2FkUmVmdW5kKCk6IHZvaWQge1xuICAgIHRoaXMubG9hZGluZy5zZXQodHJ1ZSk7XG4gICAgdGhpcy5zdGFydEhpbnRzKCk7XG4gICAgdGhpcy5ib29raW5nU2VydmljZS5nZXRSZWZ1bmREZXRhaWxzKHRoaXMuYm9va2luZ0lkKCksIHRoaXMucHJvZHVjdCgpKS5zdWJzY3JpYmUoe1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgIG5leHQ6IChyYXc6IGFueSkgPT4ge1xuICAgICAgICBsZXQgZGF0YSA9IHJhdz8uZGF0YSA/PyByYXc7XG5cbiAgICAgICAgdGhpcy5zdG9wSGludHMoKTtcbiAgICAgICAgdGhpcy5yZWZ1bmREYXRhLnNldChkYXRhKTtcbiAgICAgICAgLy8gQXV0by1zZWxlY3Qgc291cmNlOiBwcmVmZXIgYXBwbGllZFNvdXJjZSwgb3RoZXJ3aXNlIHBpY2sgZmlyc3QgYXZhaWxhYmxlXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgIGNvbnN0IGJyZWFrZG93bjogUmVjb3JkPHN0cmluZywgYW55PiA9IGRhdGE/LnNvdXJjZUJyZWFrZG93biA/PyB7fTtcbiAgICAgICAgY29uc3Qgc291cmNlcyA9IE9iamVjdC5rZXlzKGJyZWFrZG93bik7XG4gICAgICAgIGlmIChzb3VyY2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBjb25zdCBhcHBsaWVkID0gZGF0YT8uYXBwbGllZFNvdXJjZTtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkU291cmNlLnNldChhcHBsaWVkICYmIGJyZWFrZG93blthcHBsaWVkXSA/IGFwcGxpZWQgOiBzb3VyY2VzWzBdKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgLy8gT25seSBzaG93IHRoZSBsZWcgcGlja2VyIGZvciBhIGdlbnVpbmUgcm91bmQtdHJpcCB0aGUgYmFja2VuZCBoYXNuJ3RcbiAgICAgICAgLy8gYWxyZWFkeSByZXN0cmljdGVkIHRvIGEgc2luZ2xlIGxlZyDigJQgb3RoZXJ3aXNlIGdvIHN0cmFpZ2h0IHRvIGRldGFpbHMuXG4gICAgICAgIGlmICh0aGlzLnNob3dSb3VuZFRyaXBMZWdDYXJkcygpKSB7XG4gICAgICAgICAgLy8gUHJlLWNoZWNrIHdoaWNoZXZlciBsZWdzIGFyZSBhY3R1YWxseSByZWZ1bmRhYmxlLCBtYXRjaGluZyB0aGVcbiAgICAgICAgICAvLyBjb25zdW1lciBhcHAncyBcIm5vbi1yZWZ1bmRhYmxlIGxlZ3MgY2FuJ3QgYmUgc2VsZWN0ZWRcIiBiZWhhdmlvci5cbiAgICAgICAgICB0aGlzLm9ud2FyZENoZWNrZWQuc2V0KHRoaXMub253YXJkUmVmdW5kYWJsZSgpKTtcbiAgICAgICAgICB0aGlzLnJldHVybkNoZWNrZWQuc2V0KHRoaXMucmV0dXJuUmVmdW5kYWJsZSgpKTtcbiAgICAgICAgICB0aGlzLnN0ZXAuc2V0KCdzZWxlY3QtbGVnJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zdGVwLnNldCgnZGV0YWlscycpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZXJyb3I6ICgpID0+IHsgdGhpcy5zdG9wSGludHMoKTsgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7IHRoaXMudG9hc3QuZXJyb3IoJ0NvdWxkIG5vdCBsb2FkIHJlZnVuZCBkZXRhaWxzLicpOyB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEJvdGggbGVncyBpbiBwbGF5IOKAlCBzdW0gZWFjaCBsZWcncyBvd24gZmlndXJlcyBpbnN0ZWFkIG9mIHRydXN0aW5nIHJvb3RcbiAgICogKHJvb3QgaXNuJ3QgcmVsaWFibHkgc2NvcGVkIHRvIHRoZSBwaWNrZWQgYWx0ZXJuYXRpdmVzLCBlLmcuIHJvdW5kaW5nXG4gICAqIGNhbiBkcmlmdCBiZXR3ZWVuIGxlZyB0b3RhbHMgYW5kIHRoZSBjb21iaW5lZCByb290IHRvdGFsKS5cbiAgICovXG4gIHByaXZhdGUgYnVpbGRDb21iaW5lZExlZ0RhdGEocm9vdDogUmVmdW5kRGF0YSwgb253YXJkOiBMZWdEZXRhaWxzLCByZXQ6IExlZ0RldGFpbHMpOiBSZWZ1bmREYXRhIHtcbiAgICBjb25zdCBvbndhcmREYXRhID0gdGhpcy5idWlsZExlZ0RhdGEocm9vdCwgb253YXJkLCAnb253YXJkJyk7XG4gICAgY29uc3QgcmV0dXJuRGF0YSA9IHRoaXMuYnVpbGRMZWdEYXRhKHJvb3QsIHJldCwgJ3JldHVybicpO1xuICAgIGNvbnN0IHN1bSA9IChrZXk6IHN0cmluZykgPT4gTnVtYmVyKG9ud2FyZERhdGFba2V5XSB8fCAwKSArIE51bWJlcihyZXR1cm5EYXRhW2tleV0gfHwgMCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnJvb3QsXG4gICAgICBpc1JlZnVuZGFibGU6ICAgICAgICAgICAgICAgICAgICBvbndhcmQuaXNSZWZ1bmRhYmxlID09PSB0cnVlICYmIHJldC5pc1JlZnVuZGFibGUgPT09IHRydWUsXG4gICAgICB0b3RhbFJlZnVuZEFtb3VudDogICAgICAgICAgICAgICBzdW0oJ3RvdGFsUmVmdW5kQW1vdW50JyksXG4gICAgICB0b3RhbFJlZnVuZEFtb3VudEJlZm9yZUNlaWw6ICAgICBzdW0oJ3RvdGFsUmVmdW5kQW1vdW50QmVmb3JlQ2VpbCcpLFxuICAgICAgdG90YWxDYXJkUmVmdW5kQW1vdW50OiAgICAgICAgICAgc3VtKCd0b3RhbENhcmRSZWZ1bmRBbW91bnQnKSxcbiAgICAgIHRvdGFsQ3JlZGl0UmVmdW5kQW1vdW50OiAgICAgICAgIHN1bSgndG90YWxDcmVkaXRSZWZ1bmRBbW91bnQnKSxcbiAgICAgIHRvdGFsTm9uUmVmdW5kYWJsZVNlcnZpY2VDaGFyZ2U6IHN1bSgndG90YWxOb25SZWZ1bmRhYmxlU2VydmljZUNoYXJnZScpLFxuICAgICAgdG90YWxDb3Vwb25BbW91bnQ6ICAgICAgICAgICAgICAgc3VtKCd0b3RhbENvdXBvbkFtb3VudCcpLFxuICAgICAgd2FsbGV0UmVmdW5kQW1vdW50OiAgICAgICAgICAgICAgc3VtKCd3YWxsZXRSZWZ1bmRBbW91bnQnKSxcbiAgICAgIHRvdGFsUGVuYWx0eVBvaW50czogICAgICAgICAgICAgIHN1bSgndG90YWxQZW5hbHR5UG9pbnRzJyksXG4gICAgICB0b3RhbFN1cHBsaWVyUGVuYWx0eVBvaW50czogICAgICBzdW0oJ3RvdGFsU3VwcGxpZXJQZW5hbHR5UG9pbnRzJyksXG4gICAgICB0b3RhbExveWFsdHlQb2ludHM6ICAgICAgICAgICAgICBzdW0oJ3RvdGFsTG95YWx0eVBvaW50cycpLFxuICAgICAgdG90YWxHaWZ0QW1vdW50OiAgICAgICAgICAgICAgICAgc3VtKCd0b3RhbEdpZnRBbW91bnQnKSxcbiAgICAgIHRvdGFsQW5jaWxsYXJ5UmVmdW5kQW1vdW50OiAgICAgIHN1bSgndG90YWxBbmNpbGxhcnlSZWZ1bmRBbW91bnQnKSxcbiAgICAgIHRvdGFsTG95YWx0eVBvaW50c1JlZnVuZEFtb3VudDogIHN1bSgndG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50JyksXG4gICAgICB0b3RhbENhbmNlbGxhdGlvbkZlZTogICAgICAgICAgICBzdW0oJ3RvdGFsQ2FuY2VsbGF0aW9uRmVlJyksXG4gICAgICB0b3RhbFN1cHBsaWVyQm9va2luZ0Ftb3VudDogICAgICBzdW0oJ3RvdGFsU3VwcGxpZXJCb29raW5nQW1vdW50JyksXG4gICAgICBvcmlnaW5hbEFtb3VudDogICAgICAgICAgICAgICAgICBOdW1iZXIocm9vdC5vcmlnaW5hbEFtb3VudCB8fCAwKSxcbiAgICAgIHJlZnVuZEJyZWFrZG93bjogdGhpcy5tZXJnZUJyZWFrZG93bnMob253YXJkRGF0YS5yZWZ1bmRCcmVha2Rvd24sIHJldHVybkRhdGEucmVmdW5kQnJlYWtkb3duKSxcbiAgICAgIGxlZ0luZm86IHsgb253YXJkLCByZXR1cm46IHJldCB9LFxuICAgIH07XG4gIH1cblxuICAvKiogQ29tYmluZSB0d28gbGVncycgaXRlbWl6ZWQgYnJlYWtkb3ducyBmb3IgdGhlIFwiYm90aCBsZWdzXCIgY29tYmluZWQgdmlldy4gKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgcHJpdmF0ZSBtZXJnZUJyZWFrZG93bnMoYTogYW55LCBiOiBhbnkpOiBhbnkge1xuICAgIGlmICghYSAmJiAhYikgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIGNvbnN0IG1lcmdlU2lkZSA9IChzYTogYW55LCBzYjogYW55KSA9PiAoe1xuICAgICAgZmFyZTogTnVtYmVyKHNhPy5mYXJlIHx8IDApICsgTnVtYmVyKHNiPy5mYXJlIHx8IDApIHx8IHVuZGVmaW5lZCxcbiAgICAgIGFkZE9uczogWy4uLihzYT8uYWRkT25zID8/IFtdKSwgLi4uKHNiPy5hZGRPbnMgPz8gW10pXSxcbiAgICAgIGFuY2lsbGFyaWVzOiBbLi4uKHNhPy5hbmNpbGxhcmllcyA/PyBbXSksIC4uLihzYj8uYW5jaWxsYXJpZXMgPz8gW10pXSxcbiAgICAgIHNlcnZpY2VGZWU6IE51bWJlcihzYT8uc2VydmljZUZlZSB8fCAwKSArIE51bWJlcihzYj8uc2VydmljZUZlZSB8fCAwKSB8fCB1bmRlZmluZWQsXG4gICAgICBoYW5kbGluZ0ZlZTogTnVtYmVyKHNhPy5oYW5kbGluZ0ZlZSB8fCAwKSArIE51bWJlcihzYj8uaGFuZGxpbmdGZWUgfHwgMCkgfHwgdW5kZWZpbmVkLFxuICAgICAgY2FuY2VsbGF0aW9uUGVuYWx0eTpcbiAgICAgICAgTnVtYmVyKHNhPy5jYW5jZWxsYXRpb25QZW5hbHR5IHx8IDApICsgTnVtYmVyKHNiPy5jYW5jZWxsYXRpb25QZW5hbHR5IHx8IDApIHx8IHVuZGVmaW5lZCxcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgcmVmdW5kYWJsZTogbWVyZ2VTaWRlKGE/LnJlZnVuZGFibGUsIGI/LnJlZnVuZGFibGUpLFxuICAgICAgbm9uUmVmdW5kYWJsZTogbWVyZ2VTaWRlKGE/Lm5vblJlZnVuZGFibGUsIGI/Lm5vblJlZnVuZGFibGUpLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkTGVnRGF0YShyb290OiBSZWZ1bmREYXRhLCBsZWc6IExlZ0RldGFpbHMsIGxlZ1R5cGU6ICdvbndhcmQnIHwgJ3JldHVybicpOiBSZWZ1bmREYXRhIHtcbiAgICAvLyBXaGVuIHRoaXMgbGVnIGhhcyBubyBzaWJsaW5nIGluIGBsZWdJbmZvYCAoYSBnZW51aW5lIG9uZS13YXkgYm9va2luZyxcbiAgICAvLyBvciBhIG5hcnJvd2VkIENyb3NzU2VsbGVyIHNlbGVjdGlvbiB3aGVyZSB0aGUgQVBJIG9ubHkgZXZlciBzZW50IHRoZVxuICAgIC8vIG9uZSBsZWcpLCByb290IG5lY2Vzc2FyaWx5IGRlc2NyaWJlcyB0aGlzIHNhbWUgc2luZ2xlIGxlZyDigJQgc28gYVxuICAgIC8vIGRlc3RpbmF0aW9uIHRvdGFsIHRoZSBsZWcncyBvd24gb2JqZWN0IGxlZnQgYXQgMCBjYW4gc2FmZWx5IGZhbGwgYmFja1xuICAgIC8vIHRvIHJvb3QncyBmaWd1cmUgaW5zdGVhZCBvZiBzaWxlbnRseSB6ZXJvaW5nIG91dCBhIHJlYWwgcmVmdW5kXG4gICAgLy8gZGVzdGluYXRpb24uIFdpdGggYSBzaWJsaW5nIGxlZyBwcmVzZW50LCByb290IGFnZ3JlZ2F0ZXMgYm90aCBsZWdzIGFuZFxuICAgIC8vIGlzIG5vdCB0cnVzdHdvcnRoeSBwZXItbGVnLCBzbyB0aGUgbGVnJ3Mgb3duIHZhbHVlIChldmVuIDApIHdpbnMuXG4gICAgY29uc3QgaGFzU2libGluZ0xlZyA9XG4gICAgICBsZWdUeXBlID09PSAnb253YXJkJyA/ICEhcm9vdC5sZWdJbmZvPy5yZXR1cm4gOiAhIXJvb3QubGVnSW5mbz8ub253YXJkO1xuICAgIGNvbnN0IGZhbGxiYWNrID0gKHZhbHVlOiBudW1iZXIgfCB1bmRlZmluZWQsIHJvb3RWYWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkKSA9PlxuICAgICAgTnVtYmVyKHZhbHVlIHx8IChoYXNTaWJsaW5nTGVnID8gMCA6IHJvb3RWYWx1ZSkgfHwgMCk7XG5cbiAgICBjb25zdCBpc0NyZWRpdFNoZWxsID0gbGVnLmlzQ3JlZGl0U2hlbGwgPT09IHRydWU7XG4gICAgY29uc3QgbGVnUmVmdW5kICAgID0gTnVtYmVyKGxlZy50b3RhbFJlZnVuZEFtb3VudCA/PyAwKTtcbiAgICBjb25zdCBjYXJkUmVmdW5kICAgPSBpc0NyZWRpdFNoZWxsID8gMCA6IGZhbGxiYWNrKGxlZy50b3RhbENhcmRSZWZ1bmRBbW91bnQsIHJvb3QudG90YWxDYXJkUmVmdW5kQW1vdW50KTtcbiAgICBjb25zdCBjcmVkaXRSZWZ1bmQgPSBpc0NyZWRpdFNoZWxsID8gbGVnUmVmdW5kIDogZmFsbGJhY2sobGVnLnRvdGFsQ3JlZGl0UmVmdW5kQW1vdW50LCByb290LnRvdGFsQ3JlZGl0UmVmdW5kQW1vdW50KTtcbiAgICAvLyBUaGUgYmFja2VuZCBzb21ldGltZXMgb21pdHMgYGlzUmVmdW5kYWJsZWAgb24gYSBzaW5nbGUtbGVnIGJvb2tpbmcnc1xuICAgIC8vIGxlZyBvYmplY3QgZW50aXJlbHkgKG5vdCBgZmFsc2VgLCBqdXN0IGFic2VudCkgd2hpbGUgdGhlIHJvb3Qvc291cmNlXG4gICAgLy8gYnJlYWtkb3duIGJvdGggc2F5IHRoZSBib29raW5nIGlzIHJlZnVuZGFibGUg4oCUIHRydXN0IHRoZSByb290IGZsYWdcbiAgICAvLyByYXRoZXIgdGhhbiBkZWZhdWx0aW5nIGEgbWlzc2luZyBmaWVsZCB0byBcIm5vdCBlbGlnaWJsZSBmb3IgYSByZWZ1bmRcIi5cbiAgICBjb25zdCBsZWdJc1JlZnVuZGFibGUgPVxuICAgICAgbGVnLmlzUmVmdW5kYWJsZSA9PT0gdW5kZWZpbmVkID8gcm9vdC5pc1JlZnVuZGFibGUgPT09IHRydWUgOiBsZWcuaXNSZWZ1bmRhYmxlID09PSB0cnVlO1xuICAgIHJldHVybiB7XG4gICAgICAuLi5yb290LFxuICAgICAgaXNSZWZ1bmRhYmxlOiAgICAgICAgICAgICAgICAgICAgbGVnSXNSZWZ1bmRhYmxlLFxuICAgICAgdG90YWxSZWZ1bmRBbW91bnQ6ICAgICAgICAgICAgICAgbGVnUmVmdW5kLFxuICAgICAgLy8gUHJlLXJvdW5kaW5nIHRvdGFsIOKAlCB0aGUgYmFja2VuZCBjZWlscyBgdG90YWxSZWZ1bmRBbW91bnRgIHRvIGEgd2hvbGVcbiAgICAgIC8vIGN1cnJlbmN5IHVuaXQsIHNvIHdhbGxldCtjYXJkK2NyZWRpdCtsb3lhbHR5IGxlZ2l0aW1hdGVseSBmYWxsIGEgZmV3XG4gICAgICAvLyBjZW50cyBzaG9ydCBvZiBpdDsgcmVjb25jaWxpYXRpb24gbXVzdCBjb21wYXJlIGFnYWluc3QgdGhpcyBpbnN0ZWFkLlxuICAgICAgdG90YWxSZWZ1bmRBbW91bnRCZWZvcmVDZWlsOiAgICAgTnVtYmVyKGxlZy50b3RhbFJlZnVuZEFtb3VudEJlZm9yZUNlaWwgPz8gbGVnLnRvdGFsUmVmdW5kQW1vdW50ID8/IDApLFxuICAgICAgdG90YWxDYXJkUmVmdW5kQW1vdW50OiAgICAgICAgICAgY2FyZFJlZnVuZCxcbiAgICAgIHRvdGFsQ3JlZGl0UmVmdW5kQW1vdW50OiAgICAgICAgIGNyZWRpdFJlZnVuZCxcbiAgICAgIHRvdGFsTm9uUmVmdW5kYWJsZVNlcnZpY2VDaGFyZ2U6IE51bWJlcihsZWcudG90YWxOb25SZWZ1bmRhYmxlU2VydmljZUNoYXJnZSB8fCAwKSxcbiAgICAgIHRvdGFsQ291cG9uQW1vdW50OiAgICAgICAgICAgICAgIE51bWJlcihsZWcudG90YWxDb3Vwb25BbW91bnQgfHwgMCksXG4gICAgICB3YWxsZXRSZWZ1bmRBbW91bnQ6ICAgICAgICAgICAgICBmYWxsYmFjayhsZWcud2FsbGV0UmVmdW5kQW1vdW50LCByb290LndhbGxldFJlZnVuZEFtb3VudCksXG4gICAgICB0b3RhbFBlbmFsdHlQb2ludHM6ICAgICAgICAgICAgICBOdW1iZXIobGVnLnRvdGFsUGVuYWx0eVBvaW50cyB8fCAwKSxcbiAgICAgIHRvdGFsU3VwcGxpZXJQZW5hbHR5UG9pbnRzOiAgICAgIE51bWJlcihsZWcudG90YWxTdXBwbGllclBlbmFsdHlQb2ludHMgfHwgMCksXG4gICAgICB0b3RhbExveWFsdHlQb2ludHM6ICAgICAgICAgICAgICBOdW1iZXIobGVnLnRvdGFsTG95YWx0eVBvaW50cyB8fCAwKSxcbiAgICAgIHRvdGFsR2lmdEFtb3VudDogICAgICAgICAgICAgICAgIE51bWJlcihsZWcudG90YWxHaWZ0QW1vdW50IHx8IDApLFxuICAgICAgdG90YWxBbmNpbGxhcnlSZWZ1bmRBbW91bnQ6ICAgICAgTnVtYmVyKGxlZy50b3RhbEFuY2lsbGFyeVJlZnVuZEFtb3VudCB8fCAwKSxcbiAgICAgIHRvdGFsTG95YWx0eVBvaW50c1JlZnVuZEFtb3VudDogIGZhbGxiYWNrKGxlZy50b3RhbExveWFsdHlQb2ludHNSZWZ1bmRBbW91bnQsIHJvb3QudG90YWxMb3lhbHR5UG9pbnRzUmVmdW5kQW1vdW50KSxcbiAgICAgIHRvdGFsQ2FuY2VsbGF0aW9uRmVlOiAgICAgICAgICAgIE51bWJlcihsZWcudG90YWxDYW5jZWxsYXRpb25GZWUgPz8gbGVnLnRvdGFsUGVuYWx0eVBvaW50cyA/PyAwKSxcbiAgICAgIHRvdGFsU3VwcGxpZXJCb29raW5nQW1vdW50OiAgICAgIE51bWJlcihsZWcudG90YWxTdXBwbGllckJvb2tpbmdBbW91bnQgfHwgMCksXG4gICAgICBvcmlnaW5hbEFtb3VudDogICAgICAgICAgICAgICAgICBOdW1iZXIocm9vdC5vcmlnaW5hbEFtb3VudCB8fCAwKSxcbiAgICAgIC8vIExlZy1zY29wZWQgYnJlYWtkb3duIHdpbnMgd2hlbiB0aGUgYmFja2VuZCBzZW5kcyBvbmU7IGEgc2luZ2xlLWxlZ1xuICAgICAgLy8gYm9va2luZyBtYXkgb25seSBjYXJyeSBpdCBhdCB0aGUgcm9vdCBpbnN0ZWFkLlxuICAgICAgcmVmdW5kQnJlYWtkb3duOiAgICAgICAgICAgICAgICAgbGVnLnJlZnVuZEJyZWFrZG93biA/PyByb290LnJlZnVuZEJyZWFrZG93bixcbiAgICAgIGxlZ0luZm86IGxlZ1R5cGUgPT09ICdvbndhcmQnID8geyBvbndhcmQ6IGxlZyB9IDogeyByZXR1cm46IGxlZyB9LFxuICAgIH07XG4gIH1cblxuICBzdGFydEhpbnRzKCk6IHZvaWQge1xuICAgIGxldCBpID0gMDtcbiAgICB0aGlzLmNhbmNlbEhpbnQuc2V0KHRoaXMuQ0FOQ0VMX0hJTlRTWzBdKTtcbiAgICB0aGlzLmhpbnRUaW1lciA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIGlmIChpIDwgdGhpcy5DQU5DRUxfSElOVFMubGVuZ3RoIC0gMSkge1xuICAgICAgICBpKys7XG4gICAgICAgIHRoaXMuY2FuY2VsSGludC5zZXQodGhpcy5DQU5DRUxfSElOVFNbaV0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmhpbnRUaW1lcik7XG4gICAgICAgIHRoaXMuaGludFRpbWVyID0gbnVsbDtcbiAgICAgIH1cbiAgICB9LCAxODAwKTtcbiAgfVxuXG4gIHN0b3BIaW50cygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5oaW50VGltZXIpIHsgY2xlYXJJbnRlcnZhbCh0aGlzLmhpbnRUaW1lcik7IHRoaXMuaGludFRpbWVyID0gbnVsbDsgfVxuICAgIHRoaXMuY2FuY2VsSGludC5zZXQoJycpO1xuICB9XG5cbiAgZm10KHZhbHVlOiBudW1iZXIsIGN1cnJlbmN5Pzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBjdXIgPSBjdXJyZW5jeSA/PyB0aGlzLnJlZnVuZERhdGEoKT8uY3VycmVuY3kgPz8gJ1NBUic7XG4gICAgcmV0dXJuIGAke3RoaXMuZm10TnVtKHZhbHVlKX0gJHtjdXJ9YDtcbiAgfVxuXG4gIC8vIFBsYWluIGZvcm1hdHRlZCBudW1iZXIgd2l0aG91dCBhIGN1cnJlbmN5IHN1ZmZpeCAodXNlZCBieSB0aGUgY2FsYyBkaXZpZGVyIC8gZm9ybXVsYSBib3gpLlxuICBmbXROdW0odmFsdWU6IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIE51bWJlcih2YWx1ZSB8fCAwKS50b0xvY2FsZVN0cmluZygnZW4tU0EnLCB7IG1pbmltdW1GcmFjdGlvbkRpZ2l0czogMiwgbWF4aW11bUZyYWN0aW9uRGlnaXRzOiAyIH0pO1xuICB9XG5cbiAgZm10TmVnKHZhbHVlOiBudW1iZXIsIGN1cnJlbmN5Pzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBuID0gTnVtYmVyKHZhbHVlIHx8IDApO1xuICAgIGNvbnN0IHN0ciA9IHRoaXMuZm10KG4sIGN1cnJlbmN5KTtcbiAgICByZXR1cm4gbiA+IDAgPyBg4oiSICR7c3RyfWAgOiBzdHI7XG4gIH1cblxuICBmbXROZWdSZXN1bHQodmFsdWU6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgbiA9IE51bWJlcih2YWx1ZSB8fCAwKTtcbiAgICBjb25zdCBzdHIgPSB0aGlzLmZtdFJlc3VsdChuKTtcbiAgICByZXR1cm4gbiA+IDAgPyBg4oiSICR7c3RyfWAgOiBzdHI7XG4gIH1cblxuICAvLyBFbnRyeSBwb2ludCBmcm9tIHRoZSBkZXRhaWxzIHNjcmVlbjogYWx3YXlzIGdvZXMgdG8gdGhlIHJlZnVuZC1tZXRob2RcbiAgLy8gc3RlcC4gRm9yIGNyZWRpdC1zaGVsbCByZWZ1bmRzIHRoYXQgc3RlcCBzaG93cyBhIHNpbmdsZSByZWFkLW9ubHkgY3JlZGl0XG4gIC8vIG5vdGljZSBpbnN0ZWFkIG9mIGEgcGlja2VyLCBzaW5jZSB0aGUgcmVmdW5kIGNhbiBvbmx5IGdvIHRvIHRoZSBzaGVsbCDigJRcbiAgLy8gYnV0IHRoZSBhZ2VudCBzdGlsbCBzZWVzIGl0IGJlZm9yZSBjb25maXJtaW5nLCBzYW1lIGFzIHRoZSBzdGFuZGFyZCBmbG93LlxuICByZXF1ZXN0Q2FuY2VsKCk6IHZvaWQge1xuICAgIC8vIE5JTCByZWZ1bmQ6IG5vdGhpbmcgdG8gcmVmdW5kIGF0IGFsbCDigJQgc2tpcCB0aGUgcmVmdW5kLW1ldGhvZCBwb3B1cFxuICAgIC8vIGFuZCBjYW5jZWwgZGlyZWN0bHkuXG4gICAgaWYgKHRoaXMuaXNOaWxSZWZ1bmQoKSkge1xuICAgICAgdGhpcy5jb25maXJtKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29uZmlybWluZy5zZXQodHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgY29uZmlybSgpOiB2b2lkIHtcbiAgICBjb25zdCBzZWwgPSB0aGlzLnNlbGVjdGVkTGVnKCk7XG5cbiAgICAvLyBCdWlsZCBsZWdJbmZvIGFycmF5OiBvbWl0IHdoZW4gY2FuY2VsbGluZyBib3RoIChiYWNrZW5kIHRyZWF0cyBhYnNlbmNlIGFzIGJvdGgpXG4gICAgY29uc3QgbGVnSW5mbzogc3RyaW5nW10gfCB1bmRlZmluZWQgPVxuICAgICAgc2VsID09PSAnb253YXJkJyA/IFsnb253YXJkJ10gOlxuICAgICAgc2VsID09PSAncmV0dXJuJyA/IFsncmV0dXJuJ10gOlxuICAgICAgdW5kZWZpbmVkOyAvLyBib3RoIGxlZ3Mg4oCUIG9taXQgdGhlIGZpZWxkXG5cbiAgICBjb25zdCBzb3VyY2UgPSB0aGlzLnNlbGVjdGVkU291cmNlKCkgfHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IHByZWZlcnJlZFJlZnVuZE1ldGhvZCA9IHRoaXMucHJlZmVycmVkUmVmdW5kTWV0aG9kKCk7XG4gICAgY29uc3Qgc3BsaXRBbW91bnRzID1cbiAgICAgIHByZWZlcnJlZFJlZnVuZE1ldGhvZCA9PT0gJ3NwbGl0J1xuICAgICAgICA/IHtcbiAgICAgICAgICAgIHdhbGxldFJlZnVuZEFtb3VudDogTnVtYmVyKHRoaXMuYWRqdXN0ZWREYXRhKCk/LndhbGxldFJlZnVuZEFtb3VudCA/PyAwKSxcbiAgICAgICAgICAgIHRvdGFsQ2FyZFJlZnVuZEFtb3VudDogTnVtYmVyKHRoaXMuYWRqdXN0ZWREYXRhKCk/LnRvdGFsQ2FyZFJlZnVuZEFtb3VudCA/PyAwKSxcbiAgICAgICAgICB9XG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgIHRoaXMuY29uZmlybWluZy5zZXQoZmFsc2UpO1xuICAgIHRoaXMuc3RvcEhpbnRzKCk7XG4gICAgdGhpcy5jYW5jZWxsaW5nLnNldCh0cnVlKTtcbiAgICB0aGlzLmJvb2tpbmdTZXJ2aWNlLmNvbmZpcm1DYW5jZWwodGhpcy5ib29raW5nSWQoKSwgdGhpcy5wcm9kdWN0KCksIGxlZ0luZm8sIHNvdXJjZSwgcHJlZmVycmVkUmVmdW5kTWV0aG9kLCBzcGxpdEFtb3VudHMpLnN1YnNjcmliZSh7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgbmV4dDogKHJhdzogYW55KSA9PiB7XG4gICAgICAgIHRoaXMuc3RvcEhpbnRzKCk7XG4gICAgICAgIHRoaXMuY2FuY2VsbGluZy5zZXQoZmFsc2UpO1xuICAgICAgICB0aGlzLmNhbmNlbFJlc3VsdC5zZXQocmF3Py5kYXRhID8/IHJhdyk7XG4gICAgICAgIHRoaXMuY29uZmlybWVkLmVtaXQoc2VsKTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLnN0b3BIaW50cygpO1xuICAgICAgICB0aGlzLmNhbmNlbGxpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgdGhpcy50b2FzdC5lcnJvcignQ2FuY2VsbGF0aW9uIGZhaWxlZC4gUGxlYXNlIHRyeSBhZ2Fpbi4nKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cbn1cbiIsIjxwLWRpYWxvZyBbdmlzaWJsZV09XCJ2aXNpYmxlKClcIiAodmlzaWJsZUNoYW5nZSk9XCIkZXZlbnQgPyBudWxsIDogY2xvc2VkLmVtaXQoKVwiXG4gIFttb2RhbF09XCJ0cnVlXCIgW2Jsb2NrU2Nyb2xsXT1cInRydWVcIiBbZHJhZ2dhYmxlXT1cImZhbHNlXCIgW3Jlc2l6YWJsZV09XCJmYWxzZVwiXG4gIFtzaG93SGVhZGVyXT1cImZhbHNlXCIgW3N0eWxlXT1cInsgd2lkdGg6ICc1NjBweCcsIHBhZGRpbmc6ICcwJyB9XCIgc3R5bGVDbGFzcz1cInNiZC1jYW5jZWwtZGlhbG9nLXdyYXBwZXJcIj5cblxuICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbFwiPlxuXG4gICAgPCEtLSBMb2FkaW5nIHJlZnVuZCBkZXRhaWxzIOKAlCBzaG93cyBjeWNsaW5nIGhpbnRzIC0tPlxuICAgIEBpZiAobG9hZGluZygpKSB7XG4gICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fYXJlLXlvdS1zdXJlXCI+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2JkLWNhbmNlbF9fY2xvc2UtYnRuIHNiZC1jYW5jZWxfX2Nsb3NlLWJ0bi0tZmxvYXRpbmdcIiAoY2xpY2spPVwiY2xvc2VkLmVtaXQoKVwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktdGltZXNcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fYXlzLWljb25cIj5cbiAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXNwaW4gcGktc3Bpbm5lclwiPjwvaT5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIEBmb3IgKGggb2YgW2NhbmNlbEhpbnQoKV07IHRyYWNrIGgpIHtcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fYXlzLWhpbnRcIj57eyBoIH19PC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2F5cy1kb3RzXCI+XG4gICAgICAgICAgPHNwYW4+PC9zcGFuPjxzcGFuPjwvc3Bhbj48c3Bhbj48L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgfVxuXG4gICAgPCEtLSBTZWxlY3QgbGVnIOKAlCBzaG93biBvbmNlIHRoZSByZWZ1bmQgcHJldmlldyBoYXMgZnVsbHkgbG9hZGVkLCBiZWZvcmUgdGhlXG4gICAgICAgICByZWZ1bmQgYnJlYWtkb3duLCBmb3Igcm91bmQtdHJpcCBib29raW5ncyB0aGUgYmFja2VuZCBoYXNuJ3QgYWxyZWFkeVxuICAgICAgICAgcmVzdHJpY3RlZCB0byBhIHNpbmdsZSBsZWcuIFNhbWUgY2FyZCBkZXNpZ24gYXMgYWxtYXRhci1iMmMnc1xuICAgICAgICAgc2VsZWN0LWxlZyBzY3JlZW4gKGNoZWNrYm94IG92ZXJsYXksIHJlZnVuZGFibGUgYmFkZ2UsIGRpc2NsYWltZXIpLiAtLT5cbiAgICBAZWxzZSBpZiAoc3RlcCgpID09PSAnc2VsZWN0LWxlZycpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtaGVhZGVyXCI+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWNsb3NlXCIgKGNsaWNrKT1cImNsb3NlZC5lbWl0KClcIiBhcmlhLWxhYmVsPVwiQ2xvc2VcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXRpbWVzXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1oZWFkZXItdGV4dFwiPlxuICAgICAgICAgIDxoMyBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC10aXRsZVwiPlNlbGVjdCBMZWcgdG8gQ2FuY2VsPC9oMz5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1zdWJcIj5Cb29raW5nIElEICN7eyBib29raW5nSWQoKSB9fTwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3NlbGVjdC1sZWctYm9keVwiPlxuICAgICAgICBAaWYgKGZvcmNlZExlZ1R5cGUoKTsgYXMgZm9yY2VkKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3NpbmdsZS1sZWctbm90ZVwiPlxuICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1pbmZvLWNpcmNsZVwiPjwvaT5cbiAgICAgICAgICAgIDxzcGFuPlRoaXMgYWlybGluZSBkb2Vzbid0IGFsbG93IGNhbmNlbGxpbmcgYSBzaW5nbGUgZmxpZ2h0IOKAlCB7eyBpdGluZXJhcnlMZWcoZm9yY2VkKT8uZnJvbSB9fSB0byB7eyBpdGluZXJhcnlMZWcoZm9yY2VkKT8udG8gfX0gd2lsbCBiZSBpbmNsdWRlZCBhdXRvbWF0aWNhbGx5Ljwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgICBAaWYgKGFsbExlZ3NOb25SZWZ1bmRhYmxlKCkpIHtcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fYWxsLW5vbi1yZWZ1bmRhYmxlLW5vdGVcIj5cbiAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktZXhjbGFtYXRpb24tdHJpYW5nbGVcIj48L2k+XG4gICAgICAgICAgICA8c3Bhbj5Tb3JyeSwgd2UncmUgdW5hYmxlIHRvIHByb3ZpZGUgYSByZWZ1bmQgZm9yIHRoaXMgYm9va2luZywgYXMgYm90aCBmbGlnaHRzIGFyZSBub24tcmVmdW5kYWJsZSBiYXNlZCBvbiBhaXJsaW5lIHJ1bGVzLjwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgICA8IS0tIE9ud2FyZCAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtY2FyZFwiXG4gICAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICAgJ3NiZC1jYW5jZWxfX2xlZy1zZWxlY3QtY2FyZC0tc2VsZWN0ZWQnOiBvbndhcmRDaGVja2VkKCkgJiYgb253YXJkUmVmdW5kYWJsZSgpLFxuICAgICAgICAgICAgJ3NiZC1jYW5jZWxfX2xlZy1zZWxlY3QtY2FyZC0tZGlzYWJsZWQnOiAhb253YXJkUmVmdW5kYWJsZSgpLFxuICAgICAgICAgICAgJ3NiZC1jYW5jZWxfX2xlZy1zZWxlY3QtY2FyZC0tZnJvemVuJzogZm9yY2VkTGVnVHlwZSgpID09PSAnb253YXJkJ1xuICAgICAgICAgIH1cIj5cbiAgICAgICAgICBAaWYgKGZvcmNlZExlZ1R5cGUoKSAhPT0gJ29ud2FyZCcpIHtcbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtY2hlY2tib3hcIj5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtjaGVja2VkXT1cIm9ud2FyZENoZWNrZWQoKVwiIFtkaXNhYmxlZF09XCIhb253YXJkUmVmdW5kYWJsZSgpXCJcbiAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInRvZ2dsZUxlZygnb253YXJkJylcIiAvPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtaWNvblwiPjxpIGNsYXNzPVwicGkgcGktY2hlY2tcIj48L2k+PC9zcGFuPlxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktbG9jayBzYmQtY2FuY2VsX19sZWctc2VsZWN0LWxvY2tcIj48L2k+XG4gICAgICAgICAgfVxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LWNvbnRlbnRcIj5cbiAgICAgICAgICAgIEBpZiAoaXRpbmVyYXJ5TGVnKCdvbndhcmQnKTsgYXMgbGVnKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LXRvcFwiPlxuICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtbmFtZVwiPnt7IGxlZy5mcm9tIH19IHRvIHt7IGxlZy50byB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LWRhdGVcIj57eyBmbXRTaG9ydERhdGUobGVnLmRlcFRpbWUpIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19iYWRnZSBzYmQtY2FuY2VsX19iYWRnZS0tb3V0bGluZVwiXG4gICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJvbndhcmRSZWZ1bmRhYmxlKCkgJiYgZm9yY2VkTGVnVHlwZSgpICE9PSAnb253YXJkJyA/ICdzYmQtY2FuY2VsX19iYWRnZS0tZ3JlZW4nIDogJ3NiZC1jYW5jZWxfX2JhZGdlLS1tdXRlZCdcIj5cbiAgICAgICAgICAgICAgICAgIHt7IG9ud2FyZFJlZnVuZGFibGUoKSA/ICdSZWZ1bmRhYmxlJyA6ICdOb24tUmVmdW5kYWJsZScgfX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC10aW1lc1wiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC10aW1lXCI+e3sgZm10VGltZShsZWcuZGVwVGltZSkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LWxpbmVcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1saW5lLXN0b3BzXCI+e3sgbGVnLnN0b3BzLmxlbmd0aCA+IDAgPyAobGVnLnN0b3BzLmxlbmd0aCArICcgc3RvcCcgKyAobGVnLnN0b3BzLmxlbmd0aCA+IDEgPyAncycgOiAnJykpIDogJ0RpcmVjdCcgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICBAaWYgKGZtdE1pbnMobGVnLnRvdGFsTWludXRlcykpIHsgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LWxpbmUtZHVyXCI+e3sgZm10TWlucyhsZWcudG90YWxNaW51dGVzKSB9fTwvc3Bhbj4gfVxuICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1hcnJvdy1yaWdodCBzYmQtY2FuY2VsX19sZWctc2VsZWN0LWxpbmUtYXJyb3dcIj48L2k+XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC10aW1lXCI+e3sgZm10VGltZShsZWcuYXJyVGltZSkgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBAaWYgKGxlZy5haXJsaW5lTmFtZSB8fCBsZWcuY2FiaW4pIHtcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtYWlybGluZVwiPlxuICAgICAgICAgICAgICAgICAge3sgbGVnLmFpcmxpbmVOYW1lIH19e3sgbGVnLmFpcmxpbmVOYW1lICYmIGxlZy5jYWJpbiA/ICcgwrcgJyA6ICcnIH19e3sgbGVnLmNhYmluIH19XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LWZvb3RlclwiPlxuICAgICAgICAgICAgICAgIEBpZiAobGVnLm9wZXJhdGVkQnkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3Qtb3BlcmF0ZWQtYnlcIj5PcGVyYXRlZCBieSB7eyBsZWcub3BlcmF0ZWRCeS5qb2luKCcsICcpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8IS0tIDxpIGNsYXNzPVwicGkgcGktY2hldnJvbi1kb3duIHNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtY2hldnJvblwiPjwvaT4gLS0+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LXRvcFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1uYW1lXCI+T253YXJkPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fYmFkZ2Ugc2JkLWNhbmNlbF9fYmFkZ2UtLW91dGxpbmVcIlxuICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwib253YXJkUmVmdW5kYWJsZSgpICYmIGZvcmNlZExlZ1R5cGUoKSAhPT0gJ29ud2FyZCcgPyAnc2JkLWNhbmNlbF9fYmFkZ2UtLWdyZWVuJyA6ICdzYmQtY2FuY2VsX19iYWRnZS0tbXV0ZWQnXCI+XG4gICAgICAgICAgICAgICAgICB7eyBvbndhcmRSZWZ1bmRhYmxlKCkgPyAnUmVmdW5kYWJsZScgOiAnTm9uLVJlZnVuZGFibGUnIH19XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBpZiAoIW9ud2FyZFJlZnVuZGFibGUoKSkge1xuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1ub3RpY2VcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWluZm8tY2lyY2xlXCI+PC9pPlxuICAgICAgICAgICAgICAgIDxzcGFuPlRoaXMgZmxpZ2h0IHR5cGUgZG9lc24ndCBhbGxvdyByZWZ1bmRzIG9uIGNhbmNlbGxhdGlvbiwgYmFzZWQgb24gdGhlIGFpcmxpbmUncyBmYXJlIHJ1bGVzLjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gUmV0dXJuIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1jYXJkXCJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgICAnc2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1jYXJkLS1zZWxlY3RlZCc6IHJldHVybkNoZWNrZWQoKSAmJiByZXR1cm5SZWZ1bmRhYmxlKCksXG4gICAgICAgICAgICAnc2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1jYXJkLS1kaXNhYmxlZCc6ICFyZXR1cm5SZWZ1bmRhYmxlKCksXG4gICAgICAgICAgICAnc2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1jYXJkLS1mcm96ZW4nOiBmb3JjZWRMZWdUeXBlKCkgPT09ICdyZXR1cm4nXG4gICAgICAgICAgfVwiPlxuICAgICAgICAgIEBpZiAoZm9yY2VkTGVnVHlwZSgpICE9PSAncmV0dXJuJykge1xuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1jaGVja2JveFwiPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgW2NoZWNrZWRdPVwicmV0dXJuQ2hlY2tlZCgpXCIgW2Rpc2FibGVkXT1cIiFyZXR1cm5SZWZ1bmRhYmxlKClcIlxuICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwidG9nZ2xlTGVnKCdyZXR1cm4nKVwiIC8+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1pY29uXCI+PGkgY2xhc3M9XCJwaSBwaS1jaGVja1wiPjwvaT48L3NwYW4+XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1sb2NrIHNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtbG9ja1wiPjwvaT5cbiAgICAgICAgICB9XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtY29udGVudFwiPlxuICAgICAgICAgICAgQGlmIChpdGluZXJhcnlMZWcoJ3JldHVybicpOyBhcyBsZWcpIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtdG9wXCI+XG4gICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1uYW1lXCI+e3sgbGVnLmZyb20gfX0gdG8ge3sgbGVnLnRvIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtZGF0ZVwiPnt7IGZtdFNob3J0RGF0ZShsZWcuZGVwVGltZSkgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2JhZGdlIHNiZC1jYW5jZWxfX2JhZGdlLS1vdXRsaW5lXCJcbiAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInJldHVyblJlZnVuZGFibGUoKSAmJiBmb3JjZWRMZWdUeXBlKCkgIT09ICdyZXR1cm4nID8gJ3NiZC1jYW5jZWxfX2JhZGdlLS1ncmVlbicgOiAnc2JkLWNhbmNlbF9fYmFkZ2UtLW11dGVkJ1wiPlxuICAgICAgICAgICAgICAgICAge3sgcmV0dXJuUmVmdW5kYWJsZSgpID8gJ1JlZnVuZGFibGUnIDogJ05vbi1SZWZ1bmRhYmxlJyB9fVxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LXRpbWVzXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LXRpbWVcIj57eyBmbXRUaW1lKGxlZy5kZXBUaW1lKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtbGluZVwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LWxpbmUtc3RvcHNcIj57eyBsZWcuc3RvcHMubGVuZ3RoID4gMCA/IChsZWcuc3RvcHMubGVuZ3RoICsgJyBzdG9wJyArIChsZWcuc3RvcHMubGVuZ3RoID4gMSA/ICdzJyA6ICcnKSkgOiAnRGlyZWN0JyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIEBpZiAoZm10TWlucyhsZWcudG90YWxNaW51dGVzKSkgeyA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtbGluZS1kdXJcIj57eyBmbXRNaW5zKGxlZy50b3RhbE1pbnV0ZXMpIH19PC9zcGFuPiB9XG4gICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWFycm93LXJpZ2h0IHNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtbGluZS1hcnJvd1wiPjwvaT5cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LXRpbWVcIj57eyBmbXRUaW1lKGxlZy5hcnJUaW1lKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIEBpZiAobGVnLmFpcmxpbmVOYW1lIHx8IGxlZy5jYWJpbikge1xuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1haXJsaW5lXCI+XG4gICAgICAgICAgICAgICAgICB7eyBsZWcuYWlybGluZU5hbWUgfX17eyBsZWcuYWlybGluZU5hbWUgJiYgbGVnLmNhYmluID8gJyDCtyAnIDogJycgfX17eyBsZWcuY2FiaW4gfX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtZm9vdGVyXCI+XG4gICAgICAgICAgICAgICAgQGlmIChsZWcub3BlcmF0ZWRCeS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1vcGVyYXRlZC1ieVwiPk9wZXJhdGVkIGJ5IHt7IGxlZy5vcGVyYXRlZEJ5LmpvaW4oJywgJykgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwhLS0gPGkgY2xhc3M9XCJwaSBwaS1jaGV2cm9uLWRvd24gc2JkLWNhbmNlbF9fbGVnLXNlbGVjdC1jaGV2cm9uXCI+PC9pPiAtLT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtdG9wXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LW5hbWVcIj5SZXR1cm48L3NwYW4+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19iYWRnZSBzYmQtY2FuY2VsX19iYWRnZS0tb3V0bGluZVwiXG4gICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJyZXR1cm5SZWZ1bmRhYmxlKCkgJiYgZm9yY2VkTGVnVHlwZSgpICE9PSAncmV0dXJuJyA/ICdzYmQtY2FuY2VsX19iYWRnZS0tZ3JlZW4nIDogJ3NiZC1jYW5jZWxfX2JhZGdlLS1tdXRlZCdcIj5cbiAgICAgICAgICAgICAgICAgIHt7IHJldHVyblJlZnVuZGFibGUoKSA/ICdSZWZ1bmRhYmxlJyA6ICdOb24tUmVmdW5kYWJsZScgfX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGlmICghcmV0dXJuUmVmdW5kYWJsZSgpKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctc2VsZWN0LW5vdGljZVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktaW5mby1jaXJjbGVcIj48L2k+XG4gICAgICAgICAgICAgICAgPHNwYW4+VGhpcyBmbGlnaHQgdHlwZSBkb2Vzbid0IGFsbG93IHJlZnVuZHMgb24gY2FuY2VsbGF0aW9uLCBiYXNlZCBvbiB0aGUgYWlybGluZSdzIGZhcmUgcnVsZXMuPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgQGlmICghYWxsTGVnc05vblJlZnVuZGFibGUoKSAmJiAhb253YXJkQ2hlY2tlZCgpICYmICFyZXR1cm5DaGVja2VkKCkpIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1zZWxlY3QtaGludFwiPlNlbGVjdCBhdCBsZWFzdCBvbmUgZmxpZ2h0IHRvIGNvbnRpbnVlPC9kaXY+XG4gICAgICB9XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19mb290ZXJcIj5cbiAgICAgICAgPGJ1dHRvbiBwQnV0dG9uXG4gICAgICAgICAgc3R5bGVDbGFzcz1cInNiZC1jYW5jZWxfX2J0bi1wcmltYXJ5XCJcbiAgICAgICAgICBsYWJlbD1cIkNvbnRpbnVlXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiYWxsTGVnc05vblJlZnVuZGFibGUoKSB8fCAoIW9ud2FyZENoZWNrZWQoKSAmJiAhcmV0dXJuQ2hlY2tlZCgpKVwiXG4gICAgICAgICAgKGNsaWNrKT1cInN0ZXAuc2V0KCdkZXRhaWxzJylcIj48L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIH1cblxuICAgIDwhLS0gUmVmdW5kIG1ldGhvZCDigJQgcmVwbGFjZXMgdGhlIG9sZCBhcmUteW91LXN1cmUgKyByYWRpbyBwaWNrZXIuXG4gICAgICAgICBTdGF5cyBtb3VudGVkIChkaW1tZWQpIGJlaGluZCB0aGUgcmVzdWx0IG92ZXJsYXkgb25jZSBjb25maXJtZWQuIC0tPlxuICAgIEBlbHNlIGlmIChjb25maXJtaW5nKCkgfHwgY2FuY2VsUmVzdWx0KCkpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtaGVhZGVyXCI+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWNsb3NlXCIgKGNsaWNrKT1cImNvbmZpcm1pbmcuc2V0KGZhbHNlKVwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktdGltZXNcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWhlYWRlci10ZXh0XCI+XG4gICAgICAgICAgPGgzIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLXRpdGxlXCI+UmVmdW5kIE1ldGhvZDwvaDM+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2Qtc3ViXCI+Qm9va2luZyBJRCAje3sgYm9va2luZ0lkKCkgfX08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYm9keVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWFtb3VudFwiPlxuICAgICAgICAgIDxzcGFuPllvdSB3aWxsIGdldCBiYWNrPC9zcGFuPlxuICAgICAgICAgIDxzdHJvbmc+e3sgZm10KGFkanVzdGVkRGF0YSgpPy50b3RhbFJlZnVuZEFtb3VudCkgfX08L3N0cm9uZz5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgQGlmIChpc0NyZWRpdFNoZWxsKCkpIHtcbiAgICAgICAgPCEtLSBDcmVkaXQtc2hlbGwgcmVmdW5kcyBoYXZlIGV4YWN0bHkgb25lIGRlc3RpbmF0aW9uIOKAlCB0aGUgYWlybGluZVxuICAgICAgICAgICAgIGNyZWRpdCBzaGVsbCDigJQgc28gc2hvdyBpdCBhcyBhIHJlYWQtb25seSBjYXJkLCBub3QgYSBwaWNrZXIuIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLW9wdGlvbiBzYmQtY2FuY2VsX19tZXRob2Qtb3B0aW9uLS1hY3RpdmVcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1pY29uXCI+PGkgY2xhc3M9XCJwaSBwaS13YWxsZXRcIj48L2k+PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWJvZHktdGV4dFwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtbmFtZVwiPnt7IGNyZWRpdFNoZWxsU3VwcGxpZXJOYW1lKCkgfX0gd2Vic2l0ZSBjcmVkaXQ8L3NwYW4+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1kZXNjXCI+WW91ciByZWZ1bmQgd2lsbCBiZSBpc3N1ZWQgaW5zdGFudGx5IGJ5IHt7IGNyZWRpdFNoZWxsU3VwcGxpZXJOYW1lKCkgfX0uPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2Ugc2JkLWNhbmNlbF9fbWV0aG9kLWJhZGdlLS1pbnN0YW50XCI+XG4gICAgICAgICAgICAgIDxzdmcgd2lkdGg9XCIxMlwiIGhlaWdodD1cIjlcIiB2aWV3Qm94PVwiMCAwIDEyIDlcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgICAgICAgZD1cIk03LjMxODE4IDBDOC40MjcyNyAwIDkuNDkwOTMgMC40NDA1ODMgMTAuMjc1MiAxLjIyNDgzQzExLjA1OTQgMi4wMDkwNyAxMS41IDMuMDcyNzMgMTEuNSA0LjE4MTgyQzExLjUgNS4yOTA5IDExLjA1OTQgNi4zNTQ1NyAxMC4yNzUyIDcuMTM4ODFDOS40OTA5MyA3LjkyMzA1IDguNDI3MjcgOC4zNjM2NCA3LjMxODE4IDguMzYzNjRDNi4yMDkwOSA4LjM2MzY0IDUuMTQ1NDMgNy45MjMwNSA0LjM2MTE5IDcuMTM4ODFDMy41NzY5NSA2LjM1NDU3IDMuMTM2MzYgNS4yOTA5IDMuMTM2MzYgNC4xODE4MkMzLjEzNjM2IDMuMDcyNzMgMy41NzY5NSAyLjAwOTA3IDQuMzYxMTkgMS4yMjQ4M0M1LjE0NTQzIDAuNDQwNTgzIDYuMjA5MDkgMCA3LjMxODE4IDBaTTcuMzE4MTggMS4wNDU0NUM2LjQ4NjM3IDEuMDQ1NDUgNS42ODg2MiAxLjM3NTg5IDUuMTAwNDQgMS45NjQwN0M0LjUxMjI2IDIuNTUyMjYgNC4xODE4MiAzLjM1IDQuMTgxODIgNC4xODE4MkM0LjE4MTgyIDUuMDEzNjMgNC41MTIyNiA1LjgxMTM4IDUuMTAwNDQgNi4zOTk1NkM1LjY4ODYyIDYuOTg3NzQgNi40ODYzNyA3LjMxODE4IDcuMzE4MTggNy4zMTgxOEM4LjE1IDcuMzE4MTggOC45NDc3NCA2Ljk4Nzc0IDkuNTM1OTMgNi4zOTk1NkMxMC4xMjQxIDUuODExMzggMTAuNDU0NSA1LjAxMzYzIDEwLjQ1NDUgNC4xODE4MkMxMC40NTQ1IDMuMzUgMTAuMTI0MSAyLjU1MjI2IDkuNTM1OTMgMS45NjQwN0M4Ljk0Nzc0IDEuMzc1ODkgOC4xNSAxLjA0NTQ1IDcuMzE4MTggMS4wNDU0NVpNNi43OTU0NSAyLjA5MDkxSDcuNTc5NTVWNC4wNjY4Mkw4Ljc5NzUgNS4yODQ3N0w4LjI0MzQxIDUuODM4ODZMNi43OTU0NSA0LjM5MDkxVjIuMDkwOTFaTTAuNTIyNzI3IDcuMzE4MThDMC4zODQwOTEgNy4zMTgxOCAwLjI1MTEzNCA3LjI2MzExIDAuMTUzMTAzIDcuMTY1MDhDMC4wNTUwNzI5IDcuMDY3MDUgMCA2LjkzNDA5IDAgNi43OTU0NUMwIDYuNjU2ODIgMC4wNTUwNzI5IDYuNTIzODYgMC4xNTMxMDMgNi40MjU4M0MwLjI1MTEzNCA2LjMyNzggMC4zODQwOTEgNi4yNzI3MyAwLjUyMjcyNyA2LjI3MjczSDIuNTI0NzdDMi42ODY4MiA2LjY0Mzg2IDIuODk1OTEgNi45OTQwOSAzLjEzNjM2IDcuMzE4MThIMC41MjI3MjdaTTEuMDQ1NDUgNC43MDQ1NUMwLjkwNjgxOSA0LjcwNDU1IDAuNzczODYxIDQuNjQ5NDcgMC42NzU4MyA0LjU1MTQ0QzAuNTc3OCA0LjQ1MzQxIDAuNTIyNzI3IDQuMzIwNDUgMC41MjI3MjcgNC4xODE4MkMwLjUyMjcyNyA0LjA0MzE4IDAuNTc3OCAzLjkxMDIyIDAuNjc1ODMgMy44MTIxOUMwLjc3Mzg2MSAzLjcxNDE2IDAuOTA2ODE5IDMuNjU5MDkgMS4wNDU0NSAzLjY1OTA5SDIuMTE3MDVMMi4wOTA5MSA0LjE4MTgyTDIuMTE3MDUgNC43MDQ1NUgxLjA0NTQ1Wk0xLjU2ODE4IDIuMDkwOTFDMS40Mjk1NSAyLjA5MDkxIDEuMjk2NTkgMi4wMzU4NCAxLjE5ODU2IDEuOTM3ODFDMS4xMDA1MyAxLjgzOTc4IDEuMDQ1NDUgMS43MDY4MiAxLjA0NTQ1IDEuNTY4MThDMS4wNDU0NSAxLjQyOTU1IDEuMTAwNTMgMS4yOTY1OSAxLjE5ODU2IDEuMTk4NTZDMS4yOTY1OSAxLjEwMDUzIDEuNDI5NTUgMS4wNDU0NSAxLjU2ODE4IDEuMDQ1NDVIMy4xMzYzNkMyLjg5NTkxIDEuMzY5NTUgMi42ODY4MiAxLjcxOTc3IDIuNTI0NzcgMi4wOTA5MUgxLjU2ODE4WlwiXG4gICAgICAgICAgICAgICAgICBmaWxsPVwiIzE1ODAzQ1wiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgIEluc3RhbnRcbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19ub3RpY2Ugc2JkLWNhbmNlbF9fbm90aWNlLS1jcmVkaXRcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWluZm8tY2lyY2xlXCI+PC9pPlxuICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgWW91ciByZWZ1bmQgd2lsbCBiZSBpc3N1ZWQgYXMgYWlybGluZSBjcmVkaXQgdW5kZXIgdGhlIHNhbWUgUE5SLlxuICAgICAgICAgICAgSXQgY2FuIGJlIHVzZWQgb25seSBmb3IgZnV0dXJlIGJvb2tpbmcgb24ge3sgY3JlZGl0U2hlbGxTdXBwbGllck5hbWUoKSB9fSB3ZWJzaXRlLlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBSZWZ1bmRhYmxlIGFuY2lsbGFyaWVzIChiYWdnYWdlLCBzZWF0cywg4oCmKSBjYW4gaW5kZXBlbmRlbnRseSBiZVxuICAgICAgICAgICAgIGZsYWdnZWQgY3JlZGl0LXNoZWxsIG9yIG5vdCDigJQgZWFjaCByZW5kZXJzIGFzIGl0cyBvd24gY2FyZCxcbiAgICAgICAgICAgICBtYXRjaGluZyBlaXRoZXIgdGhlIGNyZWRpdC1zaGVsbCBzdHlsZSBhYm92ZSBvciB0aGUgbm9ybWFsXG4gICAgICAgICAgICAgd2FsbGV0IHN0eWxlLCBib3RoIHdpdGggdGhlIHNhbWUgbmVzdGVkIG5vdGUgd2hlbiBjcmVkaXQtc2hlbGwuIC0tPlxuICAgICAgICBAZm9yIChpdGVtIG9mIGNyZWRpdFNoZWxsQW5jaWxsYXJ5SXRlbXMoKTsgdHJhY2sgaXRlbS5uYW1lKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1vcHRpb24gc2JkLWNhbmNlbF9fbWV0aG9kLW9wdGlvbi0tYWN0aXZlXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1pY29uXCI+PGkgY2xhc3M9XCJwaSBwaS13YWxsZXRcIj48L2k+PC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYm9keS10ZXh0XCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLW5hbWVcIj5cbiAgICAgICAgICAgICAgICB7eyBpdGVtLmlzQ3JlZGl0U2hlbGwgPyAoY3JlZGl0U2hlbGxTdXBwbGllck5hbWUoKSArICcgd2Vic2l0ZSBjcmVkaXQnKSA6ICdBbG1hdGFyIFdhbGxldCcgfX1cbiAgICAgICAgICAgICAgICDigJQge3sgaXRlbS5uYW1lIH19XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtZGVzY1wiPlxuICAgICAgICAgICAgICAgIEBpZiAoaXRlbS5pc0NyZWRpdFNoZWxsKSB7XG4gICAgICAgICAgICAgICAgICBZb3VyIHJlZnVuZCB3aWxsIGJlIGlzc3VlZCBpbnN0YW50bHkgYnkge3sgY3JlZGl0U2hlbGxTdXBwbGllck5hbWUoKSB9fS5cbiAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIFVzYWJsZSBmb3IgZnV0dXJlIGJvb2tpbmdzXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWJhZGdlIHNiZC1jYW5jZWxfX21ldGhvZC1iYWRnZS0taW5zdGFudFwiPlxuICAgICAgICAgICAgICAgIDxzdmcgd2lkdGg9XCIxMlwiIGhlaWdodD1cIjlcIiB2aWV3Qm94PVwiMCAwIDEyIDlcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgICAgICAgIGQ9XCJNNy4zMTgxOCAwQzguNDI3MjcgMCA5LjQ5MDkzIDAuNDQwNTgzIDEwLjI3NTIgMS4yMjQ4M0MxMS4wNTk0IDIuMDA5MDcgMTEuNSAzLjA3MjczIDExLjUgNC4xODE4MkMxMS41IDUuMjkwOSAxMS4wNTk0IDYuMzU0NTcgMTAuMjc1MiA3LjEzODgxQzkuNDkwOTMgNy45MjMwNSA4LjQyNzI3IDguMzYzNjQgNy4zMTgxOCA4LjM2MzY0QzYuMjA5MDkgOC4zNjM2NCA1LjE0NTQzIDcuOTIzMDUgNC4zNjExOSA3LjEzODgxQzMuNTc2OTUgNi4zNTQ1NyAzLjEzNjM2IDUuMjkwOSAzLjEzNjM2IDQuMTgxODJDMy4xMzYzNiAzLjA3MjczIDMuNTc2OTUgMi4wMDkwNyA0LjM2MTE5IDEuMjI0ODNDNS4xNDU0MyAwLjQ0MDU4MyA2LjIwOTA5IDAgNy4zMTgxOCAwWk03LjMxODE4IDEuMDQ1NDVDNi40ODYzNyAxLjA0NTQ1IDUuNjg4NjIgMS4zNzU4OSA1LjEwMDQ0IDEuOTY0MDdDNC41MTIyNiAyLjU1MjI2IDQuMTgxODIgMy4zNSA0LjE4MTgyIDQuMTgxODJDNC4xODE4MiA1LjAxMzYzIDQuNTEyMjYgNS44MTEzOCA1LjEwMDQ0IDYuMzk5NTZDNS42ODg2MiA2Ljk4Nzc0IDYuNDg2MzcgNy4zMTgxOCA3LjMxODE4IDcuMzE4MThDOC4xNSA3LjMxODE4IDguOTQ3NzQgNi45ODc3NCA5LjUzNTkzIDYuMzk5NTZDMTAuMTI0MSA1LjgxMTM4IDEwLjQ1NDUgNS4wMTM2MyAxMC40NTQ1IDQuMTgxODJDMTAuNDU0NSAzLjM1IDEwLjEyNDEgMi41NTIyNiA5LjUzNTkzIDEuOTY0MDdDOC45NDc3NCAxLjM3NTg5IDguMTUgMS4wNDU0NSA3LjMxODE4IDEuMDQ1NDVaTTYuNzk1NDUgMi4wOTA5MUg3LjU3OTU1VjQuMDY2ODJMOC43OTc1IDUuMjg0NzdMOC4yNDM0MSA1LjgzODg2TDYuNzk1NDUgNC4zOTA5MVYyLjA5MDkxWk0wLjUyMjcyNyA3LjMxODE4QzAuMzg0MDkxIDcuMzE4MTggMC4yNTExMzQgNy4yNjMxMSAwLjE1MzEwMyA3LjE2NTA4QzAuMDU1MDcyOSA3LjA2NzA1IDAgNi45MzQwOSAwIDYuNzk1NDVDMCA2LjY1NjgyIDAuMDU1MDcyOSA2LjUyMzg2IDAuMTUzMTAzIDYuNDI1ODNDMC4yNTExMzQgNi4zMjc4IDAuMzg0MDkxIDYuMjcyNzMgMC41MjI3MjcgNi4yNzI3M0gyLjUyNDc3QzIuNjg2ODIgNi42NDM4NiAyLjg5NTkxIDYuOTk0MDkgMy4xMzYzNiA3LjMxODE4SDAuNTIyNzI3Wk0xLjA0NTQ1IDQuNzA0NTVDMC45MDY4MTkgNC43MDQ1NSAwLjc3Mzg2MSA0LjY0OTQ3IDAuNjc1ODMgNC41NTE0NEMwLjU3NzggNC40NTM0MSAwLjUyMjcyNyA0LjMyMDQ1IDAuNTIyNzI3IDQuMTgxODJDMC41MjI3MjcgNC4wNDMxOCAwLjU3NzggMy45MTAyMiAwLjY3NTgzIDMuODEyMTlDMC43NzM4NjEgMy43MTQxNiAwLjkwNjgxOSAzLjY1OTA5IDEuMDQ1NDUgMy42NTkwOUgyLjExNzA1TDIuMDkwOTEgNC4xODE4MkwyLjExNzA1IDQuNzA0NTVIMS4wNDU0NVpNMS41NjgxOCAyLjA5MDkxQzEuNDI5NTUgMi4wOTA5MSAxLjI5NjU5IDIuMDM1ODQgMS4xOTg1NiAxLjkzNzgxQzEuMTAwNTMgMS44Mzk3OCAxLjA0NTQ1IDEuNzA2ODIgMS4wNDU0NSAxLjU2ODE4QzEuMDQ1NDUgMS40Mjk1NSAxLjEwMDUzIDEuMjk2NTkgMS4xOTg1NiAxLjE5ODU2QzEuMjk2NTkgMS4xMDA1MyAxLjQyOTU1IDEuMDQ1NDUgMS41NjgxOCAxLjA0NTQ1SDMuMTM2MzZDMi44OTU5MSAxLjM2OTU1IDIuNjg2ODIgMS43MTk3NyAyLjUyNDc3IDIuMDkwOTFIMS41NjgxOFpcIlxuICAgICAgICAgICAgICAgICAgICBmaWxsPVwiIzE1ODAzQ1wiXG4gICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgIEluc3RhbnRcbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICBAaWYgKGl0ZW0uaXNDcmVkaXRTaGVsbCkge1xuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0taW5mb1wiPlxuICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1pbmZvLWNpcmNsZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPllvdXIgcmVmdW5kIHdpbGwgYmUgaXNzdWVkIGFzIGFpcmxpbmUgY3JlZGl0IHVuZGVyIHRoZSBzYW1lIFBOUi4gSXQgY2FuIGJlIHVzZWQgb25seSBmb3IgZnV0dXJlIGJvb2tpbmcgb24ge3sgY3JlZGl0U2hlbGxTdXBwbGllck5hbWUoKSB9fSB3ZWJzaXRlLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDxzdHJvbmc+e3sgZm10KGl0ZW0uYW1vdW50KSB9fTwvc3Ryb25nPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIH0gQGVsc2Uge1xuXG4gICAgICAgIEBpZiAoaXNGdWxsV2FsbGV0UmVmdW5kQWxsb3dlZCgpIHx8IGlzV2FsbGV0T25seVJlZnVuZCgpIHx8IGlzTG95YWx0eU9ubHlSZWZ1bmQoKSkge1xuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1vcHRpb25cIlxuICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ3NiZC1jYW5jZWxfX21ldGhvZC1vcHRpb24tLWFjdGl2ZSc6IHByZWZlcnJlZFJlZnVuZE1ldGhvZCgpID09PSAnd2FsbGV0JyB9XCJcbiAgICAgICAgICAoY2xpY2spPVwicHJlZmVycmVkUmVmdW5kTWV0aG9kLnNldCgnd2FsbGV0JylcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1pY29uXCI+PGkgY2xhc3M9XCJwaSBwaS13YWxsZXRcIj48L2k+PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWJvZHktdGV4dFwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtbmFtZVwiPnt7IHdhbGxldENhcmRMYWJlbCgpIH19PC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtZGVzY1wiPlVzYWJsZSBmb3IgZnV0dXJlIGJvb2tpbmdzPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2Ugc2JkLWNhbmNlbF9fbWV0aG9kLWJhZGdlLS1pbnN0YW50XCI+XG4gICAgICAgICAgICAgIDxzdmcgd2lkdGg9XCIxMlwiIGhlaWdodD1cIjlcIiB2aWV3Qm94PVwiMCAwIDEyIDlcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgICAgICAgZD1cIk03LjMxODE4IDBDOC40MjcyNyAwIDkuNDkwOTMgMC40NDA1ODMgMTAuMjc1MiAxLjIyNDgzQzExLjA1OTQgMi4wMDkwNyAxMS41IDMuMDcyNzMgMTEuNSA0LjE4MTgyQzExLjUgNS4yOTA5IDExLjA1OTQgNi4zNTQ1NyAxMC4yNzUyIDcuMTM4ODFDOS40OTA5MyA3LjkyMzA1IDguNDI3MjcgOC4zNjM2NCA3LjMxODE4IDguMzYzNjRDNi4yMDkwOSA4LjM2MzY0IDUuMTQ1NDMgNy45MjMwNSA0LjM2MTE5IDcuMTM4ODFDMy41NzY5NSA2LjM1NDU3IDMuMTM2MzYgNS4yOTA5IDMuMTM2MzYgNC4xODE4MkMzLjEzNjM2IDMuMDcyNzMgMy41NzY5NSAyLjAwOTA3IDQuMzYxMTkgMS4yMjQ4M0M1LjE0NTQzIDAuNDQwNTgzIDYuMjA5MDkgMCA3LjMxODE4IDBaTTcuMzE4MTggMS4wNDU0NUM2LjQ4NjM3IDEuMDQ1NDUgNS42ODg2MiAxLjM3NTg5IDUuMTAwNDQgMS45NjQwN0M0LjUxMjI2IDIuNTUyMjYgNC4xODE4MiAzLjM1IDQuMTgxODIgNC4xODE4MkM0LjE4MTgyIDUuMDEzNjMgNC41MTIyNiA1LjgxMTM4IDUuMTAwNDQgNi4zOTk1NkM1LjY4ODYyIDYuOTg3NzQgNi40ODYzNyA3LjMxODE4IDcuMzE4MTggNy4zMTgxOEM4LjE1IDcuMzE4MTggOC45NDc3NCA2Ljk4Nzc0IDkuNTM1OTMgNi4zOTk1NkMxMC4xMjQxIDUuODExMzggMTAuNDU0NSA1LjAxMzYzIDEwLjQ1NDUgNC4xODE4MkMxMC40NTQ1IDMuMzUgMTAuMTI0MSAyLjU1MjI2IDkuNTM1OTMgMS45NjQwN0M4Ljk0Nzc0IDEuMzc1ODkgOC4xNSAxLjA0NTQ1IDcuMzE4MTggMS4wNDU0NVpNNi43OTU0NSAyLjA5MDkxSDcuNTc5NTVWNC4wNjY4Mkw4Ljc5NzUgNS4yODQ3N0w4LjI0MzQxIDUuODM4ODZMNi43OTU0NSA0LjM5MDkxVjIuMDkwOTFaTTAuNTIyNzI3IDcuMzE4MThDMC4zODQwOTEgNy4zMTgxOCAwLjI1MTEzNCA3LjI2MzExIDAuMTUzMTAzIDcuMTY1MDhDMC4wNTUwNzI5IDcuMDY3MDUgMCA2LjkzNDA5IDAgNi43OTU0NUMwIDYuNjU2ODIgMC4wNTUwNzI5IDYuNTIzODYgMC4xNTMxMDMgNi40MjU4M0MwLjI1MTEzNCA2LjMyNzggMC4zODQwOTEgNi4yNzI3MyAwLjUyMjcyNyA2LjI3MjczSDIuNTI0NzdDMi42ODY4MiA2LjY0Mzg2IDIuODk1OTEgNi45OTQwOSAzLjEzNjM2IDcuMzE4MThIMC41MjI3MjdaTTEuMDQ1NDUgNC43MDQ1NUMwLjkwNjgxOSA0LjcwNDU1IDAuNzczODYxIDQuNjQ5NDcgMC42NzU4MyA0LjU1MTQ0QzAuNTc3OCA0LjQ1MzQxIDAuNTIyNzI3IDQuMzIwNDUgMC41MjI3MjcgNC4xODE4MkMwLjUyMjcyNyA0LjA0MzE4IDAuNTc3OCAzLjkxMDIyIDAuNjc1ODMgMy44MTIxOUMwLjc3Mzg2MSAzLjcxNDE2IDAuOTA2ODE5IDMuNjU5MDkgMS4wNDU0NSAzLjY1OTA5SDIuMTE3MDVMMi4wOTA5MSA0LjE4MTgyTDIuMTE3MDUgNC43MDQ1NUgxLjA0NTQ1Wk0xLjU2ODE4IDIuMDkwOTFDMS40Mjk1NSAyLjA5MDkxIDEuMjk2NTkgMi4wMzU4NCAxLjE5ODU2IDEuOTM3ODFDMS4xMDA1MyAxLjgzOTc4IDEuMDQ1NDUgMS43MDY4MiAxLjA0NTQ1IDEuNTY4MThDMS4wNDU0NSAxLjQyOTU1IDEuMTAwNTMgMS4yOTY1OSAxLjE5ODU2IDEuMTk4NTZDMS4yOTY1OSAxLjEwMDUzIDEuNDI5NTUgMS4wNDU0NSAxLjU2ODE4IDEuMDQ1NDVIMy4xMzYzNkMyLjg5NTkxIDEuMzY5NTUgMi42ODY4MiAxLjcxOTc3IDIuNTI0NzcgMi4wOTA5MUgxLjU2ODE4WlwiXG4gICAgICAgICAgICAgICAgICBmaWxsPVwiIzE1ODAzQ1wiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgIEluc3RhbnQgUmVmdW5kXG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICBAaWYgKGhhc0xveWFsdHlQb2ludHNSZWZ1bmQoKSAmJiAhaGFzQ2FzaFdhbGxldFJlZnVuZCgpKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0taW5mb1wiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktaW5mby1jaXJjbGVcIj48L2k+XG4gICAgICAgICAgICAgICAgPHNwYW4+RXh0ZXJuYWwgbG95YWx0eSBwb2ludHMgYXJlIHJlZnVuZGVkIHRvIHlvdXIgYWxtYXRhciBXYWxsZXQgYXMgcGVybWFuZW50IHBvaW50cyBhbmQgcmVhZHkgdG8gdXNlIGluIHlvdXIgbmV4dCBib29raW5nLjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1yYWRpb1wiPjwvc3Bhbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIH1cblxuICAgICAgICA8IS0tIE9yaWdpbmFsIHBheW1lbnQgbWV0aG9kIOKAlCByZXBsYWNlZCB3aXRoIGEgXCJTcGxpdCBSZWZ1bmRcIiBjYXJkIHdoZW5ldmVyXG4gICAgICAgICAgICAgcGFydCBvZiB0aGUgcmVmdW5kIGlzIGZvcmNlZCB0byB0aGUgd2FsbGV0IChlLmcuIGxveWFsdHkgcG9pbnRzIHVzZWQpLFxuICAgICAgICAgICAgIHNpbmNlIHRoZSB0b3RhbCBjYW4ndCBnbyAxMDAlIHRvIHRoZSBvcmlnaW5hbCBwYXltZW50IG1ldGhvZC5cbiAgICAgICAgICAgICBOYW1lL2Rlc2MvYmFkZ2UvaWNvbiBiZWNvbWUgZ2F0ZXdheS1zcGVjaWZpYyBmb3IgaW5zdGFsbG1lbnQgKFRhbWFyYSxcbiAgICAgICAgICAgICBUYWJieSkgYW5kIGxveWFsdHkgKEFsIFJhamhpIE1va2FmYWEpIHBheW1lbnQgbWV0aG9kcy4gLS0+XG4gICAgICAgIEBpZiAoIWhhc1NwbGl0UmVmdW5kKCkgJiYgIWlzV2FsbGV0T25seVJlZnVuZCgpICYmICFpc0xveWFsdHlPbmx5UmVmdW5kKCkpIHtcbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2Qtb3B0aW9uXCJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7ICdzYmQtY2FuY2VsX19tZXRob2Qtb3B0aW9uLS1hY3RpdmUnOiBwcmVmZXJyZWRSZWZ1bmRNZXRob2QoKSA9PT0gJ29yaWdpbmFsUGF5bWVudE1ldGhvZCcgfVwiXG4gICAgICAgICAgKGNsaWNrKT1cInByZWZlcnJlZFJlZnVuZE1ldGhvZC5zZXQoJ29yaWdpbmFsUGF5bWVudE1ldGhvZCcpXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtaWNvblwiPlxuICAgICAgICAgICAgPGkgY2xhc3M9XCJwaVwiIFtuZ0NsYXNzXT1cImlzU3BlY2lhbEdhdGV3YXlNZXRob2QoKSA/ICdwaS13YWxsZXQnIDogJ3BpLWNyZWRpdC1jYXJkJ1wiPjwvaT5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYm9keS10ZXh0XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1uYW1lXCI+e3sgb3JpZ2luYWxQYXltZW50TGFiZWwoKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWRlc2NcIj5cbiAgICAgICAgICAgICAgQGlmIChpc0luc3RhbGxtZW50TWV0aG9kKCkpIHtcbiAgICAgICAgICAgICAgICBSZXR1cm5lZCB0byB5b3VyIHt7IGN1c3RvbWVyUGF5bWVudExhYmVsKCkgfX0gaW5zdGFsbG1lbnQgcGxhblxuICAgICAgICAgICAgICB9IEBlbHNlIGlmIChpc0xveWFsdHlNZXRob2QoKSkge1xuICAgICAgICAgICAgICAgIFJlZnVuZGVkIHRvIHlvdXIge3sgY3VzdG9tZXJQYXltZW50TGFiZWwoKSB9fSBhY2NvdW50XG4gICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgIFJldHVybmVkIHRvIHlvdXIgb3JpZ2luYWwgcGF5bWVudCBtZXRob2RcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2VcIiBbbmdDbGFzc109XCJpc0xveWFsdHlNZXRob2QoKSA/ICdzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2UtLWxveWFsdHknIDogJ3NiZC1jYW5jZWxfX21ldGhvZC1iYWRnZS0tZGF5cydcIj5cbiAgICAgICAgICAgICAgQGlmICghaXNMb3lhbHR5TWV0aG9kKCkpIHtcbiAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTJcIiBoZWlnaHQ9XCIxMlwiIHZpZXdCb3g9XCIwIDAgMTIgMTJcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgICAgICAgIGQ9XCJNMy4zMDA3OCA2LjUwMTk1QzMuMjAzMTIgNi41MDE5NSAzLjEyMTc0IDYuNDY5NCAzLjA1NjY0IDYuNDA0M0MyLjk5MTU0IDYuMzM5MTkgMi45NTg5OCA2LjI1NzgxIDIuOTU4OTggNi4xNjAxNkMyLjk1ODk4IDYuMDY1NzYgMi45OTE1NCA1Ljk4NiAzLjA1NjY0IDUuOTIwOUMzLjEyMTc0IDUuODU1NzkgMy4yMDMxMiA1LjgyMzI0IDMuMzAwNzggNS44MjMyNEg1LjUxMjdWMi44NjkxNEM1LjUxMjcgMi43NzQ3NCA1LjU0NTI1IDIuNjk0OTkgNS42MTAzNSAyLjYyOTg4QzUuNjc1NDYgMi41NjQ3OCA1Ljc1NTIxIDIuNTMyMjMgNS44NDk2MSAyLjUzMjIzQzUuOTQ3MjcgMi41MzIyMyA2LjAyODY1IDIuNTY0NzggNi4wOTM3NSAyLjYyOTg4QzYuMTU4ODUgMi42OTQ5OSA2LjE5MTQxIDIuNzc0NzQgNi4xOTE0MSAyLjg2OTE0VjYuMTYwMTZDNi4xOTE0MSA2LjI1NzgxIDYuMTU4ODUgNi4zMzkxOSA2LjA5Mzc1IDYuNDA0M0M2LjAyODY1IDYuNDY5NCA1Ljk0NzI3IDYuNTAxOTUgNS44NDk2MSA2LjUwMTk1SDMuMzAwNzhaTTUuODU0NDkgMTAuOTU1MUM1LjE2NzY0IDEwLjk1NTEgNC41MjMxMSAxMC44MjQ5IDMuOTIwOSAxMC41NjQ1QzMuMzE4NjggMTAuMzA3MyAyLjc4OTcxIDkuOTUwODUgMi4zMzM5OCA5LjQ5NTEyQzEuODc4MjYgOS4wMzkzOSAxLjUyMDE4IDguNTEwNDIgMS4yNTk3NyA3LjkwODJDMS4wMDI2IDcuMzA1OTkgMC44NzQwMjMgNi42NjE0NiAwLjg3NDAyMyA1Ljk3NDYxQzAuODc0MDIzIDUuMjg3NzYgMS4wMDI2IDQuNjQzMjMgMS4yNTk3NyA0LjA0MTAyQzEuNTIwMTggMy40Mzg4IDEuODc4MjYgMi45MDk4MyAyLjMzMzk4IDIuNDU0MUMyLjc4OTcxIDEuOTk1MTIgMy4zMTg2OCAxLjYzNzA0IDMuOTIwOSAxLjM3OTg4QzQuNTIzMTEgMS4xMjI3MiA1LjE2NzY0IDAuOTk0MTQxIDUuODU0NDkgMC45OTQxNDFDNi41NDEzNCAwLjk5NDE0MSA3LjE4NTg3IDEuMTIyNzIgNy43ODgwOSAxLjM3OTg4QzguMzkwMyAxLjYzNzA0IDguOTE5MjcgMS45OTUxMiA5LjM3NSAyLjQ1NDFDOS44MzA3MyAyLjkwOTgzIDEwLjE4NzIgMy40Mzg4IDEwLjQ0NDMgNC4wNDEwMkMxMC43MDQ4IDQuNjQzMjMgMTAuODM1IDUuMjg3NzYgMTAuODM1IDUuOTc0NjFDMTAuODM1IDYuNjYxNDYgMTAuNzA0OCA3LjMwNTk5IDEwLjQ0NDMgNy45MDgyQzEwLjE4NzIgOC41MTA0MiA5LjgzMDczIDkuMDM5MzkgOS4zNzUgOS40OTUxMkM4LjkxOTI3IDkuOTUwODUgOC4zOTAzIDEwLjMwNzMgNy43ODgwOSAxMC41NjQ1QzcuMTg1ODcgMTAuODI0OSA2LjU0MTM0IDEwLjk1NTEgNS44NTQ0OSAxMC45NTUxWk01Ljg1NDQ5IDEwLjEyNUM2LjQyNzQxIDEwLjEyNSA2Ljk2NDUyIDEwLjAxNzYgNy40NjU4MiA5LjgwMjczQzcuOTY3MTIgOS41ODc4OSA4LjQwODIgOS4yOTAwNCA4Ljc4OTA2IDguOTA5MThDOS4xNjk5MiA4LjUyODMyIDkuNDY3NzcgOC4wODcyNCA5LjY4MjYyIDcuNTg1OTRDOS44OTc0NiA3LjA4NDY0IDEwLjAwNDkgNi41NDc1MyAxMC4wMDQ5IDUuOTc0NjFDMTAuMDA0OSA1LjQwMTY5IDkuODk3NDYgNC44NjQ1OCA5LjY4MjYyIDQuMzYzMjhDOS40Njc3NyAzLjg1ODcyIDkuMTY5OTIgMy40MTc2NCA4Ljc4OTA2IDMuMDQwMDRDOC40MDgyIDIuNjU5MTggNy45NjcxMiAyLjM2MTMzIDcuNDY1ODIgMi4xNDY0OEM2Ljk2NDUyIDEuOTMxNjQgNi40Mjc0MSAxLjgyNDIyIDUuODU0NDkgMS44MjQyMkM1LjI4MTU4IDEuODI0MjIgNC43NDQ0NyAxLjkzMTY0IDQuMjQzMTYgMi4xNDY0OEMzLjc0MTg2IDIuMzYxMzMgMy4zMDA3OCAyLjY1OTE4IDIuOTE5OTIgMy4wNDAwNEMyLjUzOTA2IDMuNDE3NjQgMi4yNDEyMSAzLjg1ODcyIDIuMDI2MzcgNC4zNjMyOEMxLjgxMTUyIDQuODY0NTggMS43MDQxIDUuNDAxNjkgMS43MDQxIDUuOTc0NjFDMS43MDQxIDYuNTQ3NTMgMS44MTE1MiA3LjA4NDY0IDIuMDI2MzcgNy41ODU5NEMyLjI0MTIxIDguMDg3MjQgMi41MzkwNiA4LjUyODMyIDIuOTE5OTIgOC45MDkxOEMzLjMwMDc4IDkuMjkwMDQgMy43NDE4NiA5LjU4Nzg5IDQuMjQzMTYgOS44MDI3M0M0Ljc0NDQ3IDEwLjAxNzYgNS4yODE1OCAxMC4xMjUgNS44NTQ0OSAxMC4xMjVaXCJcbiAgICAgICAgICAgICAgICAgICAgZmlsbD1cIiMwQjU0QzJcIlxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjEyXCIgaGVpZ2h0PVwiMTJcIiB2aWV3Qm94PVwiMCAwIDEyIDEyXCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PVwiNlwiIGN5PVwiNlwiIHI9XCI1XCIgc3Ryb2tlPVwiIzBCNTRDMlwiIHN0cm9rZS13aWR0aD1cIjEuMlwiIC8+XG4gICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTYgNS41djNNNiAzLjl2LjAxXCIgc3Ryb2tlPVwiIzBCNTRDMlwiIHN0cm9rZS13aWR0aD1cIjEuMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHt7IGNhcmRCYWRnZVRleHQoKSB9fVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX29wdGlvbi1lbmRcIj5cbiAgICAgICAgICAgIEBpZiAoaXNNYWRhTWV0aG9kKCkpIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tYWRhLWxvZ29cIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWFkYUxvZ29cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtcmFkaW9cIj48L3NwYW4+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgfVxuXG4gICAgICAgIDwhLS0gU3BsaXQgUmVmdW5kIC0tPlxuICAgICAgICBAaWYgKGhhc1NwbGl0UmVmdW5kKCkpIHtcbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2Qtb3B0aW9uIHNiZC1jYW5jZWxfX21ldGhvZC1vcHRpb24tLXNwbGl0XCJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7ICdzYmQtY2FuY2VsX19tZXRob2Qtb3B0aW9uLS1hY3RpdmUnOiBwcmVmZXJyZWRSZWZ1bmRNZXRob2QoKSA9PT0gJ3NwbGl0JyB9XCJcbiAgICAgICAgICAoY2xpY2spPVwicHJlZmVycmVkUmVmdW5kTWV0aG9kLnNldCgnc3BsaXQnKVwiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLWljb25cIj48aSBjbGFzcz1cInBpIHBpLXdhbGxldFwiPjwvaT48L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYm9keS10ZXh0XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1uYW1lXCI+U3BsaXQgUmVmdW5kPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtZGVzY1wiPlJldHVybmVkIHRvIHlvdXIgb3JpZ2luYWwgcGF5bWVudCBtZXRob2Q8L3NwYW4+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDxzdHJvbmcgY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2Qtc3BsaXQtdG90YWxcIj57eyBmbXQoYWRqdXN0ZWREYXRhKCk/LnRvdGFsUmVmdW5kQW1vdW50KSB9fTwvc3Ryb25nPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLXJhZGlvXCI+PC9zcGFuPlxuXG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2Qtc3BsaXQtYnJlYWtkb3duXCI+XG4gICAgICAgICAgICBAZm9yIChyb3cgb2Ygc3BsaXRSZWZ1bmRSb3dzKCk7IHRyYWNrIHJvdy5sYWJlbCkge1xuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1zcGxpdC1yb3dcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX21ldGhvZC1zcGxpdC1sYWJlbFwiPlxuICAgICAgICAgICAgICAgICAge3sgcm93LmxhYmVsIH19XG4gICAgICAgICAgICAgICAgICBAaWYgKHJvdy5pc01hZGEpIHtcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tYWRhLWxvZ29cIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWFkYUxvZ29cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3Ryb25nPnt7IGZtdChyb3cudmFsdWUpIH19PC9zdHJvbmc+XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2VcIlxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInJvdy5pbnN0YW50ID8gJ3NiZC1jYW5jZWxfX21ldGhvZC1iYWRnZS0taW5zdGFudCcgOiAoaXNMb3lhbHR5TWV0aG9kKCkgPyAnc2JkLWNhbmNlbF9fbWV0aG9kLWJhZGdlLS1sb3lhbHR5JyA6ICdzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2UtLWRheXMnKVwiPlxuICAgICAgICAgICAgICAgIHt7IHJvdy5iYWRnZVRleHQgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICBAaWYgKHJvdy5pc0xveWFsdHkpIHtcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX25vdGljZSBzYmQtY2FuY2VsX19ub3RpY2UtLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktaW5mby1jaXJjbGVcIj48L2k+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj5FeHRlcm5hbCBsb3lhbHR5IHBvaW50cyBhcmUgcmVmdW5kZWQgdG8geW91ciBhbG1hdGFyIFdhbGxldCBhcyBwZXJtYW5lbnQgcG9pbnRzIGFuZCByZWFkeSB0byB1c2UgaW4geW91ciBuZXh0IGJvb2tpbmcuPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19mb290ZXJcIj5cbiAgICAgICAgPGJ1dHRvbiBwQnV0dG9uXG4gICAgICAgICAgc3R5bGVDbGFzcz1cInNiZC1jYW5jZWxfX2J0bi1kYW5nZXItcGlsbFwiXG4gICAgICAgICAgW2xhYmVsXT1cImNhbmNlbGxpbmcoKSA/ICdDYW5jZWxsaW5nLi4uJyA6ICdDb25maXJtIENhbmNlbGxhdGlvbidcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCJjYW5jZWxsaW5nKClcIiAoY2xpY2spPVwiY29uZmlybSgpXCI+PC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICB9XG5cbiAgICA8IS0tIE1haW4gY2FyZCAtLT5cbiAgICBAZWxzZSBpZiAocmVmdW5kRGF0YSgpICYmIHN0ZXAoKSA9PT0gJ2RldGFpbHMnKSB7XG4gICAgICA8IS0tIENhcmQgaGVhZGVyIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2hlYWRlciBzYmQtY2FuY2VsX19oZWFkZXItLXN0YWNrXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19oZWFkZXItdGl0bGVzXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19oZWFkZXItdGl0bGVcIj5DYW5jZWwgQm9va2luZyBSZXF1ZXN0PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9faGVhZGVyLXN1YlwiPiN7eyByZWZ1bmREYXRhKCk/LmJvb2tpbmdJZCA/PyBib29raW5nSWQoKSB9fTwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2JkLWNhbmNlbF9fY2xvc2UtYnRuXCIgKGNsaWNrKT1cImNsb3NlZC5lbWl0KClcIiBhcmlhLWxhYmVsPVwiQ2xvc2VcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXRpbWVzXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fYm9keVwiPlxuXG4gICAgICAgIDwhLS0gTm9uLXJlZnVuZGFibGUgLS0+XG4gICAgICAgIEBpZiAoIXJlZnVuZERhdGEoKT8uaXNSZWZ1bmRhYmxlKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX25vdGljZSBzYmQtY2FuY2VsX19ub3RpY2UtLXdhcm5pbmdcIj5cbiAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktZXhjbGFtYXRpb24tdHJpYW5nbGVcIj48L2k+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8c3Ryb25nPlRoaXMgYm9va2luZyBpcyBub3QgZWxpZ2libGUgZm9yIGEgcmVmdW5kLjwvc3Ryb25nPlxuICAgICAgICAgICAgICBAaWYgKHJlZnVuZERhdGEoKT8uY2F1c2UpIHtcbiAgICAgICAgICAgICAgICA8cD57eyByZWZ1bmREYXRhKCk/LmNhdXNlIH19PC9wPlxuICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICA8cD5QbGVhc2UgZXNjYWxhdGUgdG8gdGhlIHJlbGV2YW50IHRlYW0gZm9yIG1hbnVhbCBoYW5kbGluZy48L3A+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG5cbiAgICAgICAgPCEtLSBSZWZ1bmRhYmxlIGZsb3cgLS0+XG4gICAgICAgIEBlbHNlIHtcblxuICAgICAgICAgIDwhLS0gVG9wIHN1bW1hcnk6IHBhaWQgLyBnZXQgYmFjayAtLT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fc3VtbWFyeVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3N1bW1hcnktcm93XCJcbiAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAnc2JkLWNhbmNlbF9fc3VtbWFyeS1yb3ctLXRvZ2dsZSc6IGhhc1BhaWRCcmVha2Rvd24oKSAmJiAhIWFkanVzdGVkRGF0YSgpPy50b3RhbFdhbGxldEFtb3VudCB9XCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImhhc1BhaWRCcmVha2Rvd24oKSAmJiAhIWFkanVzdGVkRGF0YSgpPy50b3RhbFdhbGxldEFtb3VudCAmJiB0b2dnbGVQYWlkU3VtbWFyeSgpXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fc3VtbWFyeS1sYWJlbFwiPjxpIGNsYXNzPVwicGkgcGktd2FsbGV0XCI+PC9pPiBUb3RhbCBwYWlkPC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX3N1bW1hcnktdmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8c3Ryb25nPnt7IGZtdChhZGp1c3RlZERhdGEoKT8ub3JpZ2luYWxBbW91bnQpIH19PC9zdHJvbmc+XG4gICAgICAgICAgICAgICAgQGlmIChoYXNQYWlkQnJlYWtkb3duKCkgJiYgISFhZGp1c3RlZERhdGEoKT8udG90YWxXYWxsZXRBbW91bnQpIHtcbiAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLWNoZXZyb25cIlxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdzYmQtY2FuY2VsX19sZWctY2hldnJvbi0tY29sbGFwc2VkJzogIXBhaWRTdW1tYXJ5RXhwYW5kZWQoKSB9XCJcbiAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD1cIlRvZ2dsZSBwYWlkIGJyZWFrZG93blwiPlxuICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWNoZXZyb24tdXBcIj48L2k+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICBAaWYgKGhhc1BhaWRCcmVha2Rvd24oKSAmJiBwYWlkU3VtbWFyeUV4cGFuZGVkKCkgJiYgISFhZGp1c3RlZERhdGEoKT8udG90YWxXYWxsZXRBbW91bnQpIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3N1bW1hcnktYnJlYWtkb3duXCI+XG4gICAgICAgICAgICAgICAgQGZvciAocm93IG9mIHBhaWRCcmVha2Rvd25Sb3dzKCk7IHRyYWNrIHJvdy5sYWJlbCkge1xuICAgICAgICAgICAgICAgICAgQGlmIChyb3cubGFiZWwgPT09ICdBbG1hdGFyIFdhbGxldCcpIHtcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3N1bW1hcnktYnJlYWtkb3duLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IHJvdy5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBmbXQocm93LnZhbHVlKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3N1bW1hcnktcm93IHNiZC1jYW5jZWxfX3N1bW1hcnktcm93LS1yZWZ1bmRcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19zdW1tYXJ5LWxhYmVsXCI+PGkgY2xhc3M9XCJwaSBwaS1kb2xsYXJcIj48L2k+IFlvdSB3aWxsIGdldCBiYWNrPC9zcGFuPlxuICAgICAgICAgICAgICA8c3Ryb25nPnt7IGZtdChhZGp1c3RlZERhdGEoKT8udG90YWxSZWZ1bmRBbW91bnQpIH19PC9zdHJvbmc+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gR29sZGVuIEd1YXJhbnRlZSBnaWZ0IOKAlCBvdmVycmlkZXMgY3JlZGl0LXNoZWxsIG1lc3NhZ2luZyBiZWxvdyAtLT5cbiAgICAgICAgICBAaWYgKGhhc0dvbGRlbkd1YXJhbnRlZUdpZnQoKSkge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX25vdGljZSBzYmQtY2FuY2VsX19ub3RpY2UtLXN1Y2Nlc3NcIj5cbiAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1zaGllbGRcIj48L2k+XG4gICAgICAgICAgICAgIDxzcGFuPllvdSdyZSBjb3ZlcmVkIGJ5IENhbmNlbCBmb3IgYW55IHJlYXNvbiBzZXJ2aWNlLCB5b3UnbGwgZ2V0IDEwMCUgcmVmdW5kLCBtaW51cyBhbnkgYXBwbGljYWJsZSBmZWVzLiBTZWUgdGhlIGJyZWFrZG93biBiZWxvdy48L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICA8IS0tIE9uZS13YXkgKG9yIGEgcm91bmQtdHJpcCByZXN0cmljdGVkIHRvIGEgc2luZ2xlIGxlZyk6IHNpbmdsZSBjYXJkIC0tPlxuICAgICAgICAgIEBpZiAoIXNob3dSb3VuZFRyaXBMZWdDYXJkcygpKSB7XG4gICAgICAgICAgICA8IS0tIFNvdXJjZSBzZWxlY3RvciAobXVsdGlwbGUgc3VwcGxpZXJzKSAtLT5cbiAgICAgICAgICAgIEBpZiAoYXZhaWxhYmxlU291cmNlcygpLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3NvdXJjZS1zZWxlY3RvclwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fc291cmNlLWxhYmVsXCI+Q2FuY2VsIHZpYTwvc3Bhbj5cbiAgICAgICAgICAgICAgICBAZm9yIChzcmMgb2YgYXZhaWxhYmxlU291cmNlcygpOyB0cmFjayBzcmMpIHtcbiAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJzYmQtY2FuY2VsX19zb3VyY2UtY2hpcFwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAgICAgICAgICAgICAnc2JkLWNhbmNlbF9fc291cmNlLWNoaXAtLWFjdGl2ZSc6ICAgIHNlbGVjdGVkU291cmNlKCkgPT09IHNyYyxcbiAgICAgICAgICAgICAgICAgICAgICAnc2JkLWNhbmNlbF9fc291cmNlLWNoaXAtLW5vLXJlZnVuZCc6IGFjdGl2ZVNvdXJjZUJyZWFrZG93bigpPy5bc3JjXT8uaXNSZWZ1bmRhYmxlID09PSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdGVkU291cmNlLnNldChzcmMpXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IHNyYyB9fVxuICAgICAgICAgICAgICAgICAgICBAaWYgKGFjdGl2ZVNvdXJjZUJyZWFrZG93bigpPy5bc3JjXT8uaXNSZWZ1bmRhYmxlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktYmFuXCIgc3R5bGU9XCJmb250LXNpemU6MTBweDsgbWFyZ2luLWxlZnQ6NHB4O1wiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgQGlmIChzb3VyY2VOb25SZWZ1bmRhYmxlSGludCgpKSB7XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX25vdGljZSBzYmQtY2FuY2VsX19ub3RpY2UtLXdhcm5pbmdcIj5cbiAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktYmFuXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgc291cmNlTm9uUmVmdW5kYWJsZUhpbnQoKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICA8IS0tIE5vdCByZWZ1bmRhYmxlIC0tPlxuICAgICAgICAgICAgQGlmICghY3VycmVudERhdGEoKT8uaXNSZWZ1bmRhYmxlKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19ub3RpY2Ugc2JkLWNhbmNlbF9fbm90aWNlLS13YXJuaW5nXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1iYW5cIj48L2k+XG4gICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgIDxzdHJvbmc+VGhpcyBsZWcgaXMgbm90IGVsaWdpYmxlIGZvciBhIHJlZnVuZC48L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgIDxwPlBsZWFzZSBlc2NhbGF0ZSB0byB0aGUgcmVsZXZhbnQgdGVhbSBmb3IgbWFudWFsIGhhbmRsaW5nLjwvcD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3NlY3Rpb24tdGl0bGVcIj5SZWZ1bmQgRGV0YWlsczwvZGl2PlxuXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19yZWZ1bmQtY2FyZFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fYmFkZ2Ugc2JkLWNhbmNlbF9fYmFkZ2UtLW91dGxpbmUgc2JkLWNhbmNlbF9fYmFkZ2UtLWdyZWVuXCI+UmVmdW5kYWJsZTwvc3Bhbj5cblxuICAgICAgICAgICAgICAgIEBpZiAocmVmdW5kYWJsZUJyZWFrZG93blJvd3MoYWRqdXN0ZWREYXRhKCkpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgQGZvciAociBvZiByZWZ1bmRhYmxlQnJlYWtkb3duUm93cyhhZGp1c3RlZERhdGEoKSk7IHRyYWNrIHIubGFiZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3JlZnVuZC1jYXJkLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IHIubGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPHN0cm9uZz57eyBmbXQoci52YWx1ZSkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPkZhcmU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+e3sgZm10KGFkanVzdGVkRGF0YSgpPy5vcmlnaW5hbEFtb3VudCkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIDwhLS0gaGlkZSBhZGRvbiBub3RlIG5ldyBDUiBmcm9tIENYIC0tPlxuICAgICAgICAgICAgICAgIDwhLS0gQGlmIChoYXNSZWZ1bmRhYmxlQWRkb25Ob3RlKGFkanVzdGVkRGF0YSgpKSkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX25vdGljZSBzYmQtY2FuY2VsX19ub3RpY2UtLW5ldXRyYWxcIj5cbiAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1pbmZvLWNpcmNsZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+WW91ciBhZGQtb24gc2VydmljZS9zIHJlZnVuZCB3aWxsIGJlIHByb2Nlc3NlZCBzZXBhcmF0ZWx5IGJ5IG91ciBDdXN0b21lciBTZXJ2aWNlIHRlYW0gc2hvcnRseS48L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9IC0tPlxuXG4gICAgICAgICAgICAgICAgPCEtLSBEZWR1Y3Rpb25zIC0tPlxuICAgICAgICAgICAgICAgIEBpZiAoZGVkdWN0aW9ucygpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3JlZnVuZC1jYXJkLWRpdmlkZXJcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fYmFkZ2Ugc2JkLWNhbmNlbF9fYmFkZ2UtLW91dGxpbmUgc2JkLWNhbmNlbF9fYmFkZ2UtLW11dGVkXCI+Tm90IFJlZnVuZGVkIC0gRGVkdWN0aW9uczwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIEBmb3IgKGQgb2YgZGVkdWN0aW9ucygpOyB0cmFjayBkLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19yZWZ1bmQtY2FyZC1saW5lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBkLmxhYmVsIH19XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGQuYmFkZ2UpIHsgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX190YWdcIj57eyBkLmJhZGdlIH19PC9zcGFuPiB9XG4gICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtbGluZS0tbmVnXCI+e3sgZm10TmVnKGQudmFsdWUpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtZGl2aWRlciBzYmQtY2FuY2VsX19yZWZ1bmQtY2FyZC1kaXZpZGVyLS1kYXNoZWRcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtdG90YWxcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPlRvdGFsIFJlZnVuZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzdHJvbmc+e3sgZm10KGFkanVzdGVkRGF0YSgpPy50b3RhbFJlZnVuZEFtb3VudCkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgPCEtLSBDcmVkaXQgc2hlbGwgLS0+XG4gICAgICAgICAgICAgIEBpZiAoY3JlZGl0U2hlbGxOb3RlKCkpIHtcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0tY3JlZGl0XCI+XG4gICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXdhbGxldFwiPjwvaT5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPuKEue+4jyB7eyBjcmVkaXRTaGVsbE5vdGUoKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIDwhLS0gUm91bmQgdHJpcDogb25lIGNvbGxhcHNpYmxlIGNhcmQgcGVyIGxlZyAob25seSB3aGVuIGJvdGggbGVncyBhcmUgY2FuY2VsbGFibGUpIC0tPlxuICAgICAgICAgIEBpZiAoc2hvd1JvdW5kVHJpcExlZ0NhcmRzKCkpIHtcbiAgICAgICAgICAgIDwhLS0gR2lmdCBoaW50IC0tPlxuICAgICAgICAgICAgQGlmIChnaWZ0SGludCgpKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19ub3RpY2Ugc2JkLWNhbmNlbF9fbm90aWNlLS10aXBcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWluZm8tY2lyY2xlXCI+PC9pPlxuICAgICAgICAgICAgICAgIDxzcGFuPnt7IGdpZnRIaW50KCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICA8IS0tIE1peGVkIGhpbnQgLS0+XG4gICAgICAgICAgICBAaWYgKG1peGVkSGludCgpKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19ub3RpY2Ugc2JkLWNhbmNlbF9fbm90aWNlLS13YXJuaW5nXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1leGNsYW1hdGlvbi10cmlhbmdsZVwiPjwvaT5cbiAgICAgICAgICAgICAgICA8c3Bhbj57eyBtaXhlZEhpbnQoKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIDwhLS0gU291cmNlIHNlbGVjdG9yIChtdWx0aXBsZSBzdXBwbGllcnMpIC0tPlxuICAgICAgICAgICAgQGlmIChhdmFpbGFibGVTb3VyY2VzKCkubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fc291cmNlLXNlbGVjdG9yXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19zb3VyY2UtbGFiZWxcIj5DYW5jZWwgdmlhPC9zcGFuPlxuICAgICAgICAgICAgICAgIEBmb3IgKHNyYyBvZiBhdmFpbGFibGVTb3VyY2VzKCk7IHRyYWNrIHNyYykge1xuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInNiZC1jYW5jZWxfX3NvdXJjZS1jaGlwXCJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICAgICAgICAgICAgICdzYmQtY2FuY2VsX19zb3VyY2UtY2hpcC0tYWN0aXZlJzogICAgc2VsZWN0ZWRTb3VyY2UoKSA9PT0gc3JjLFxuICAgICAgICAgICAgICAgICAgICAgICdzYmQtY2FuY2VsX19zb3VyY2UtY2hpcC0tbm8tcmVmdW5kJzogYWN0aXZlU291cmNlQnJlYWtkb3duKCk/LltzcmNdPy5pc1JlZnVuZGFibGUgPT09IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0ZWRTb3VyY2Uuc2V0KHNyYylcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgc3JjIH19XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoYWN0aXZlU291cmNlQnJlYWtkb3duKCk/LltzcmNdPy5pc1JlZnVuZGFibGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1iYW5cIiBzdHlsZT1cImZvbnQtc2l6ZToxMHB4OyBtYXJnaW4tbGVmdDo0cHg7XCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBAaWYgKHNvdXJjZU5vblJlZnVuZGFibGVIaW50KCkpIHtcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0td2FybmluZ1wiPlxuICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1iYW5cIj48L2k+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj57eyBzb3VyY2VOb25SZWZ1bmRhYmxlSGludCgpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIDwhLS0gT253YXJkIGxlZyBjYXJkIC0tPlxuICAgICAgICAgICAgQGlmIChvbndhcmRDaGVja2VkKCkpIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1jYXJkXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1jYXJkLWhlYWRlclwiIChjbGljayk9XCJ0b2dnbGVMZWdFeHBhbmRlZCgnb253YXJkJylcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLWNoZWNrYm94XCI+T253YXJkPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctY2hldnJvblwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ3NiZC1jYW5jZWxfX2xlZy1jaGV2cm9uLS1jb2xsYXBzZWQnOiAhb253YXJkRXhwYW5kZWQoKSB9XCJcbiAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD1cIlRvZ2dsZVwiPlxuICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWNoZXZyb24tdXBcIj48L2k+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIEBpZiAob253YXJkRXhwYW5kZWQoKSkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1jYXJkLWJvZHlcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19iYWRnZSBzYmQtY2FuY2VsX19iYWRnZS0tb3V0bGluZVwiXG4gICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwibGVnQWRqdXN0ZWREYXRhKCdvbndhcmQnKT8uaXNSZWZ1bmRhYmxlID8gJ3NiZC1jYW5jZWxfX2JhZGdlLS1ncmVlbicgOiAnc2JkLWNhbmNlbF9fYmFkZ2UtLXJlZCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICB7eyBsZWdBZGp1c3RlZERhdGEoJ29ud2FyZCcpPy5pc1JlZnVuZGFibGUgPyAnUmVmdW5kYWJsZScgOiAnTm9uLVJlZnVuZGFibGUnIH19XG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cblxuICAgICAgICAgICAgICAgICAgICBAaWYgKGxlZ0FkanVzdGVkRGF0YSgnb253YXJkJyk/LmlzUmVmdW5kYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAgIEBpZiAocmVmdW5kYWJsZUJyZWFrZG93blJvd3MobGVnQWRqdXN0ZWREYXRhKCdvbndhcmQnKSkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBAZm9yIChyIG9mIHJlZnVuZGFibGVCcmVha2Rvd25Sb3dzKGxlZ0FkanVzdGVkRGF0YSgnb253YXJkJykpOyB0cmFjayByLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19yZWZ1bmQtY2FyZC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyByLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+e3sgZm10KHIudmFsdWUpIH19PC9zdHJvbmc+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3JlZnVuZC1jYXJkLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5GYXJlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Ryb25nPnt7IGZtdChsZWdSZWZ1bmRQb29sKCdvbndhcmQnKSkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgIDwhLS0gaGlkZSBhZGRvbiBub3RlIG5ldyBDUiBmcm9tIENYIC0tPlxuICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQGlmIChoYXNSZWZ1bmRhYmxlQWRkb25Ob3RlKGxlZ0FkanVzdGVkRGF0YSgnb253YXJkJykpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0tbmV1dHJhbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWluZm8tY2lyY2xlXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5Zb3VyIGFkZC1vbiBzZXJ2aWNlL3MgcmVmdW5kIHdpbGwgYmUgcHJvY2Vzc2VkIHNlcGFyYXRlbHkgYnkgb3VyIEN1c3RvbWVyIFNlcnZpY2UgdGVhbSBzaG9ydGx5Ljwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIH0gLS0+XG5cbiAgICAgICAgICAgICAgICAgICAgICBAaWYgKGxlZ0RlZHVjdGlvbnMoJ29ud2FyZCcpLmxlbmd0aCAmJiAhaXNDcmVkaXRTaGVsbCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtZGl2aWRlclwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19iYWRnZSBzYmQtY2FuY2VsX19iYWRnZS0tb3V0bGluZSBzYmQtY2FuY2VsX19iYWRnZS0tbXV0ZWRcIj5Ob3QgUmVmdW5kZWQgLSBEZWR1Y3Rpb25zPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGZvciAoZCBvZiBsZWdEZWR1Y3Rpb25zKCdvbndhcmQnKTsgdHJhY2sgZC5sYWJlbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtbGluZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZC5sYWJlbCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChkLmJhZGdlKSB7IDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fdGFnXCI+e3sgZC5iYWRnZSB9fTwvc3Bhbj4gfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX3JlZnVuZC1jYXJkLWxpbmUtLW5lZ1wiPnt7IGZtdE5lZyhkLnZhbHVlKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3JlZnVuZC1jYXJkLWRpdmlkZXIgc2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtZGl2aWRlci0tZGFzaGVkXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3JlZnVuZC1jYXJkLXRvdGFsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5EZXBhcnR1cmUgVG90YWwgUmVmdW5kPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHN0cm9uZz57eyBmbXQobGVnQWRqdXN0ZWREYXRhKCdvbndhcmQnKT8udG90YWxSZWZ1bmRBbW91bnQpIH19PC9zdHJvbmc+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICBAaWYgKHJlZnVuZERhdGEoKT8ubGVnSW5mbz8ub253YXJkPy5pc0NyZWRpdFNoZWxsICYmICFoYXNHb2xkZW5HdWFyYW50ZWVHaWZ0KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19ub3RpY2Ugc2JkLWNhbmNlbF9fbm90aWNlLS1jcmVkaXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS13YWxsZXRcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPuKEue+4jyBUaGUgcmVmdW5kIGZvciB0aGUgb253YXJkIGZsaWdodCBoYXMgYmVlbiBpc3N1ZWQgYXMgYW4gQWlybGluZSBDcmVkaXQgU2hlbGwuPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0td2FybmluZ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1iYW5cIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5UaGlzIGxlZyBpcyBub3QgZWxpZ2libGUgZm9yIGEgcmVmdW5kLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgPCEtLSBSZXR1cm4gbGVnIGNhcmQgLS0+XG4gICAgICAgICAgICBAaWYgKHJldHVybkNoZWNrZWQoKSkge1xuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLWNhcmRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLWNhcmQtaGVhZGVyXCIgKGNsaWNrKT1cInRvZ2dsZUxlZ0V4cGFuZGVkKCdyZXR1cm4nKVwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19sZWctY2hlY2tib3hcIj5SZXR1cm48L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNiZC1jYW5jZWxfX2xlZy1jaGV2cm9uXCJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAnc2JkLWNhbmNlbF9fbGVnLWNoZXZyb24tLWNvbGxhcHNlZCc6ICFyZXR1cm5FeHBhbmRlZCgpIH1cIlxuICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPVwiVG9nZ2xlXCI+XG4gICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktY2hldnJvbi11cFwiPjwvaT5cbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgQGlmIChyZXR1cm5FeHBhbmRlZCgpKSB7XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbGVnLWNhcmQtYm9keVwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2JhZGdlIHNiZC1jYW5jZWxfX2JhZGdlLS1vdXRsaW5lXCJcbiAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJsZWdBZGp1c3RlZERhdGEoJ3JldHVybicpPy5pc1JlZnVuZGFibGUgPyAnc2JkLWNhbmNlbF9fYmFkZ2UtLWdyZWVuJyA6ICdzYmQtY2FuY2VsX19iYWRnZS0tcmVkJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgIHt7IGxlZ0FkanVzdGVkRGF0YSgncmV0dXJuJyk/LmlzUmVmdW5kYWJsZSA/ICdSZWZ1bmRhYmxlJyA6ICdOb24tUmVmdW5kYWJsZScgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgICAgICAgICAgIEBpZiAobGVnQWRqdXN0ZWREYXRhKCdyZXR1cm4nKT8uaXNSZWZ1bmRhYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgQGlmIChyZWZ1bmRhYmxlQnJlYWtkb3duUm93cyhsZWdBZGp1c3RlZERhdGEoJ3JldHVybicpKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEBmb3IgKHIgb2YgcmVmdW5kYWJsZUJyZWFrZG93blJvd3MobGVnQWRqdXN0ZWREYXRhKCdyZXR1cm4nKSk7IHRyYWNrIHIubGFiZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3JlZnVuZC1jYXJkLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IHIubGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN0cm9uZz57eyBmbXQoci52YWx1ZSkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPkZhcmU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+e3sgZm10KGxlZ1JlZnVuZFBvb2woJ3JldHVybicpKSB9fTwvc3Ryb25nPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgPCEtLSBoaWRlIGFkZG9uIG5vdGUgbmV3IENSIGZyb20gQ1ggLS0+XG4gICAgICAgICAgICAgICAgICAgICAgPCEtLSBAaWYgKGhhc1JlZnVuZGFibGVBZGRvbk5vdGUobGVnQWRqdXN0ZWREYXRhKCdyZXR1cm4nKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19ub3RpY2Ugc2JkLWNhbmNlbF9fbm90aWNlLS1uZXV0cmFsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktaW5mby1jaXJjbGVcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPllvdXIgYWRkLW9uIHNlcnZpY2UvcyByZWZ1bmQgd2lsbCBiZSBwcm9jZXNzZWQgc2VwYXJhdGVseSBieSBvdXIgQ3VzdG9tZXIgU2VydmljZSB0ZWFtIHNob3J0bHkuPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgfSAtLT5cblxuICAgICAgICAgICAgICAgICAgICAgIEBpZiAobGVnRGVkdWN0aW9ucygncmV0dXJuJykubGVuZ3RoICYmICFpc0NyZWRpdFNoZWxsKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19yZWZ1bmQtY2FyZC1kaXZpZGVyXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX2JhZGdlIHNiZC1jYW5jZWxfX2JhZGdlLS1vdXRsaW5lIHNiZC1jYW5jZWxfX2JhZGdlLS1tdXRlZFwiPk5vdCBSZWZ1bmRlZCAtIERlZHVjdGlvbnM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICBAZm9yIChkIG9mIGxlZ0RlZHVjdGlvbnMoJ3JldHVybicpOyB0cmFjayBkLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19yZWZ1bmQtY2FyZC1saW5lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBkLmxhYmVsIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGQuYmFkZ2UpIHsgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX190YWdcIj57eyBkLmJhZGdlIH19PC9zcGFuPiB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtbGluZS0tbmVnXCI+e3sgZm10TmVnKGQudmFsdWUpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtZGl2aWRlciBzYmQtY2FuY2VsX19yZWZ1bmQtY2FyZC1kaXZpZGVyLS1kYXNoZWRcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fcmVmdW5kLWNhcmQtdG90YWxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPlJldHVybiBUb3RhbCBSZWZ1bmQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Ryb25nPnt7IGZtdChsZWdBZGp1c3RlZERhdGEoJ3JldHVybicpPy50b3RhbFJlZnVuZEFtb3VudCkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgIEBpZiAocmVmdW5kRGF0YSgpPy5sZWdJbmZvPy5yZXR1cm4/LmlzQ3JlZGl0U2hlbGwgJiYgIWhhc0dvbGRlbkd1YXJhbnRlZUdpZnQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX25vdGljZSBzYmQtY2FuY2VsX19ub3RpY2UtLWNyZWRpdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXdhbGxldFwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+4oS577iPIFRoZSByZWZ1bmQgZm9yIHRoZSByZXR1cm4gZmxpZ2h0IGhhcyBiZWVuIGlzc3VlZCBhcyBhbiBBaXJsaW5lIENyZWRpdCBTaGVsbC48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19ub3RpY2Ugc2JkLWNhbmNlbF9fbm90aWNlLS13YXJuaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInBpIHBpLWJhblwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPlRoaXMgbGVnIGlzIG5vdCBlbGlnaWJsZSBmb3IgYSByZWZ1bmQuPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIDwhLS0gSW5zdGFudCByZWZ1bmQgbm90aWNlIC0tPlxuICAgICAgICAgIEBpZiAoY3VycmVudERhdGEoKT8uaXNSZWZ1bmRhYmxlKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0tc2hpZWxkXCI+XG4gICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktc2hpZWxkXCI+PC9pPlxuICAgICAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgICAgICBAaWYgKGlzTmlsUmVmdW5kKCkpIHtcbiAgICAgICAgICAgICAgICAgIFdlJ3JlIHNvcnJ5LCBhcyBwZXIgYWlybGluZSBwb2xpY3ksIG5vIHJlZnVuZCBhcHBsaWVzIGJlY2F1c2UgdGhlIGNhbmNlbGxhdGlvbiBmZWVzIGVxdWFsIG9yIGV4Y2VlZCB5b3VyIHJlZnVuZGFibGUgZmFyZSBhbW91bnQuXG4gICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICBAaWYgKGlzV2FsbGV0T25seVJlZnVuZCgpIHx8IGlzTG95YWx0eU9ubHlSZWZ1bmQoKSkge1xuICAgICAgICAgICAgICAgICAgICBZb3VyIHJlZnVuZCBpcyBpbnN0YW50IHRvIHRoZSBjdXN0b21lcidzIGFsbWF0YXIgV2FsbGV0LlxuICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIFlvdXIgcmVmdW5kIGlzIGluc3RhbnQgZnJvbSBvdXIgc2lkZSwgeW91ciBiYW5rIG1heSB0YWtlIHVwIHRvIDE1IGJ1c2luZXNzIGRheXMgdG8gcmVmbGVjdCBpdC5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgQGlmICghaXNOaWxSZWZ1bmQoKSAmJiAhaXNDcmVkaXRTaGVsbCgpKSB7XG4gICAgICAgICAgICAgICAgICA8c3Ryb25nPllvdSBjYW4gc2VsZWN0IHJlZnVuZCBvcHRpb24gaW4gdGhlIG5leHQgc3RlcDwvc3Ryb25nPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIEZvb3RlciAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19mb290ZXJcIj5cbiAgICAgICAgQGlmIChyZWZ1bmREYXRhKCk/LmlzUmVmdW5kYWJsZSkge1xuICAgICAgICAgIDxidXR0b24gcEJ1dHRvbiBsYWJlbD1cIktlZXAgYm9va2luZ1wiIHN0eWxlQ2xhc3M9XCJwLWJ1dHRvbi1vdXRsaW5lZCBwLWJ1dHRvbi1zZWNvbmRhcnkgc2JkLWNhbmNlbF9fYnRuLWtlZXBcIiAoY2xpY2spPVwiY2xvc2VkLmVtaXQoKVwiPjwvYnV0dG9uPlxuICAgICAgICAgIEBpZiAoY3VycmVudERhdGEoKT8uaXNSZWZ1bmRhYmxlKSB7XG4gICAgICAgICAgICA8YnV0dG9uIHBCdXR0b25cbiAgICAgICAgICAgICAgc3R5bGVDbGFzcz1cInNiZC1jYW5jZWxfX2J0bi1wcmltYXJ5XCJcbiAgICAgICAgICAgICAgW2xhYmVsXT1cImlzQ3JlZGl0U2hlbGwoKSA/ICdDb250aW51ZSBDYW5jZWxsYXRpb24nIDogJ1NlbGVjdCByZWZ1bmQgb3B0aW9uJ1wiXG4gICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhY2FuQ29uZmlybSgpXCIgKGNsaWNrKT1cInJlcXVlc3RDYW5jZWwoKVwiPjwvYnV0dG9uPlxuICAgICAgICAgIH1cbiAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIGxhYmVsPVwiQ2xvc2VcIiBzdHlsZUNsYXNzPVwicC1idXR0b24tb3V0bGluZWQgcC1idXR0b24tc2Vjb25kYXJ5XCIgKGNsaWNrKT1cImNsb3NlZC5lbWl0KClcIj48L2J1dHRvbj5cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG4gICAgfVxuXG4gICAgPCEtLSDilIDilIAgUmVzdWx0IG92ZXJsYXk6IGZsb2F0aW5nIG1vZGFsIG92ZXIgdGhlIGRpbW1lZCByZWZ1bmQtbWV0aG9kIHNjcmVlbiAoc2NvcGVkIHRvIHRoaXMgZGlhbG9nLCBub3QgdGhlIHdob2xlIHZpZXdwb3J0KSDilIDilIAgLS0+XG4gICAgQGlmIChjYW5jZWxSZXN1bHQoKSkge1xuICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3Jlc3VsdC1vdmVybGF5XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19yZXN1bHQtYmFja2Ryb3BcIj48L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3Jlc3VsdC1tb2RhbFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtY2FuY2VsX19yZXN1bHQtaGVyb1wiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19yZXN1bHQtaWNvbiBzYmQtY2FuY2VsX19yZXN1bHQtaWNvbi0tZ3JlZW5cIj5cbiAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1jaGVja1wiPjwvaT5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDxoMyBjbGFzcz1cInNiZC1jYW5jZWxfX3Jlc3VsdC10aXRsZVwiPnt7IGNvbmZpcm1Jc05pbFJlZnVuZCgpID8gJ0NhbmNlbCBDb25maXJtZWQnIDogJ1JlZnVuZCBDb25maXJtZWQnIH19PC9oMz5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIEBmb3IgKHIgb2YgY29uZmlybVJlZnVuZHMoKTsgdHJhY2sgci5sYWJlbCkge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1jYW5jZWxfX3Jlc3VsdC1yb3dcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtaWNvblwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwicGlcIiBbbmdDbGFzc109XCJpc1dhbGxldERlc3RpbmF0aW9uUm93KHIpID8gJ3BpLXdhbGxldCcgOiAncGktY3JlZGl0LWNhcmQnXCI+PC9pPlxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fcmVzdWx0LWJvZHktdGV4dFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fbWV0aG9kLW5hbWVcIj57eyByLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIEBpZiAoci5zdWJSb3dzPy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fcmVzdWx0LXN1Yi1yb3dzXCI+XG4gICAgICAgICAgICAgICAgICAgIEBmb3IgKHN1YiBvZiByLnN1YlJvd3M7IHRyYWNrIHN1Yi5sYWJlbCkge1xuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JkLWNhbmNlbF9fcmVzdWx0LXN1Yi1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IHN1Yi5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+e3sgZm10UmVzdWx0KHN1Yi52YWx1ZSkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2VcIlxuICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiaXNXYWxsZXREZXN0aW5hdGlvblJvdyhyKSA/ICdzYmQtY2FuY2VsX19tZXRob2QtYmFkZ2UtLWluc3RhbnQnIDogJ3NiZC1jYW5jZWxfX21ldGhvZC1iYWRnZS0tZGF5cydcIj5cbiAgICAgICAgICAgICAgICAgIHt7IGlzV2FsbGV0RGVzdGluYXRpb25Sb3cocikgPyAnUmVhZHkgTm93JyA6IChyLmtleSA9PT0gJ3RvdGFsQ2FyZFJlZnVuZEFtb3VudCcgPyBjb25maXJtQ2FyZEJhZGdlVGV4dCgpIDogJ1VwIHRvIDE1IGJ1c2luZXNzIGRheXMsIGJhbmsgcG9saWN5JykgfX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgQGlmIChyLmhhc0xveWFsdHlOb3RlKSB7XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1jYW5jZWxfX25vdGljZSBzYmQtY2FuY2VsX19ub3RpY2UtLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJwaSBwaS1pbmZvLWNpcmNsZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+RXh0ZXJuYWwgbG95YWx0eSBwb2ludHMgYXJlIHJlZnVuZGVkIHRvIHlvdXIgYWxtYXRhciBXYWxsZXQgYXMgcGVybWFuZW50IHBvaW50cyBhbmQgcmVhZHkgdG8gdXNlIGluIHlvdXIgbmV4dCBib29raW5nLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPHN0cm9uZyBjbGFzcz1cInNiZC1jYW5jZWxfX3Jlc3VsdC1hbW91bnRcIj57eyBmbXRSZXN1bHQoci52YWx1ZSkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cblxuICAgICAgICAgIEBpZiAoY29uZmlybUNyZWRpdFNoZWxsTm90ZSgpKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLWNhbmNlbF9fbm90aWNlIHNiZC1jYW5jZWxfX25vdGljZS0tY3JlZGl0XCI+XG4gICAgICAgICAgICAgIDxpIGNsYXNzPVwicGkgcGktd2FsbGV0XCI+PC9pPlxuICAgICAgICAgICAgICA8c3Bhbj7ihLnvuI8ge3sgY29uZmlybUNyZWRpdFNoZWxsTm90ZSgpIH19PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIHN0eWxlQ2xhc3M9XCJzYmQtY2FuY2VsX19idG4tcHJpbWFyeSBzYmQtY2FuY2VsX19yZXN1bHQtZG9uZVwiIGxhYmVsPVwiQ2xvc2VcIiAoY2xpY2spPVwiY2xvc2VkLmVtaXQoKVwiPjwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIH1cblxuICA8L2Rpdj5cblxuPC9wLWRpYWxvZz5cblxuPG5nLXRlbXBsYXRlICNtYWRhTG9nbz5cbiAgPHN2ZyB3aWR0aD1cIjQzXCIgaGVpZ2h0PVwiMTVcIiB2aWV3Qm94PVwiMCAwIDQzIDE1XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgPGcgY2xpcC1wYXRoPVwidXJsKCNjbGlwMF9zYmRfbWFkYSlcIj5cbiAgICAgIDxwYXRoIGQ9XCJNMTguMTg5NCA4LjY1NDNIMFYxNC45OTMzSDE4LjE4OTRWOC42NTQzWlwiIGZpbGw9XCIjODRCNzQwXCIgLz5cbiAgICAgIDxwYXRoIGQ9XCJNMTguMTg5NCAwSDBWNi4zNDQ2M0gxOC4xODk0VjBaXCIgZmlsbD1cIiMyNTlCRDZcIiAvPlxuICAgICAgPHBhdGhcbiAgICAgICAgZD1cIk0zNi4zNzc5IDEzLjcwMzRMMzYuMjk2OSAxMy43MjAzQzM2LjAxNiAxMy43NzY4IDM1LjkxMzQgMTMuNzk5NCAzNS43MDgyIDEzLjc5OTRDMzUuMjMzIDEzLjc5OTQgMzQuNjcxMyAxMy41NDUyIDM0LjY3MTMgMTIuMzQ3NUMzNC42NzEzIDExLjczMTYgMzQuNzY4NSAxMC45MTI0IDM1LjY1NDIgMTAuOTEyNEgzNS42NTk2QzM1LjgxMDggMTAuOTIzNyAzNS45ODM2IDEwLjk0MDcgMzYuMzA3NyAxMS4wNDI0TDM2LjM3NzkgMTEuMDY1VjEzLjcwMzRaTTM2LjUyMzcgNy43MzE2NEwzNi4zNzc5IDcuNzU5ODlWOS45NzQ1OEwzNi4yNDgzIDkuOTM1MDNMMzYuMjEwNSA5LjkyMzczQzM2LjA2NDcgOS44Nzg1MyAzNS43Mjk4IDkuNzc2ODQgMzUuNDA1OCA5Ljc3Njg0QzMzLjYzNDQgOS43NzY4NCAzMy4yNjE3IDExLjE3OCAzMy4yNjE3IDEyLjM1MzFDMzMuMjYxNyAxMy45NjMzIDM0LjEyNTggMTQuODg5OCAzNS42MzI2IDE0Ljg4OThDMzYuMjY5OSAxNC44ODk4IDM2LjczOTcgMTQuODIyIDM3LjIxNSAxNC42NTgyQzM3LjY1MjQgMTQuNTExMyAzNy44MDkxIDE0LjMwMjMgMzcuODA5MSAxMy44NTU5VjcuNUMzNy4zODc4IDcuNTc5MSAzNi45NTA0IDcuNjU4MTkgMzYuNTIzNyA3LjczMTY0WlwiXG4gICAgICAgIGZpbGw9XCIjNzQ3NTgzXCJcbiAgICAgIC8+XG4gICAgICA8cGF0aFxuICAgICAgICBkPVwiTTQxLjY1MSAxMy43Mzg1TDQxLjU3NTQgMTMuNzYxMUw0MS4zMDUzIDEzLjgzNDVDNDEuMDUxNSAxMy45MDIzIDQwLjgyNDcgMTMuOTQxOSA0MC42NTE5IDEzLjk0MTlDNDAuMjM2IDEzLjk0MTkgMzkuOTg3NiAxMy43MjcyIDM5Ljk4NzYgMTMuMzZDMzkuOTg3NiAxMy4xMjI3IDQwLjA5MDIgMTIuNzIxNSA0MC43NzA3IDEyLjcyMTVINDEuNjUxVjEzLjczODVaTTQxLjAyOTkgOS43NDQxNEM0MC40ODQ0IDkuNzQ0MTQgMzkuOTIyOCA5Ljg0NTg0IDM5LjIyNjEgMTAuMDcxOEwzOC43NzI0IDEwLjIxMzFMMzguOTIzNiAxMS4yODY1TDM5LjM2NjUgMTEuMTM0QzM5LjgzMSAxMC45NzU4IDQwLjQwODggMTAuODc0MSA0MC44NDA5IDEwLjg3NDFDNDEuMDM1MyAxMC44NzQxIDQxLjYyOTQgMTAuODc0MSA0MS42Mjk0IDExLjU0NjRWMTEuODQwMkg0MC44MDMxQzM5LjI5NjMgMTEuODQwMiAzOC41OTk2IDEyLjM0MyAzOC41OTk2IDEzLjQyMjFDMzguNTk5NiAxNC4zNDMgMzkuMjQyMyAxNC44OTY3IDQwLjMyMjQgMTQuODk2N0M0MC42NTczIDE0Ljg5NjcgNDEuMTIxNyAxNC44Mjg5IDQxLjUyMTQgMTQuNzI3Mkw0MS41NDMgMTQuNzIxNUw0MS41NjQ2IDE0LjcyNzJMNDEuNjk5NiAxNC43NDk4QzQyLjEyMDggMTQuODI4OSA0Mi41NTgzIDE0LjkwOCA0Mi45ODQ5IDE0Ljk5MjdWMTEuNDY3M0M0Mi45ODQ5IDEwLjMyNjEgNDIuMzI2MSA5Ljc0NDE0IDQxLjAyOTkgOS43NDQxNFpcIlxuICAgICAgICBmaWxsPVwiIzc0NzU4M1wiXG4gICAgICAvPlxuICAgICAgPHBhdGhcbiAgICAgICAgZD1cIk0zMS4xNTI3IDEzLjczODVMMzEuMDc3MSAxMy43NjExTDMwLjgwNyAxMy44MzQ1QzMwLjU1MzIgMTMuOTAyMyAzMC4zMzE4IDEzLjk0MTkgMzAuMTUzNiAxMy45NDE5QzI5LjczNzcgMTMuOTQxOSAyOS40ODkzIDEzLjcyNzIgMjkuNDg5MyAxMy4zNkMyOS40ODkzIDEzLjEyMjcgMjkuNTkxOSAxMi43MjE1IDMwLjI2NyAxMi43MjE1SDMxLjE0NzNMMzEuMTUyNyAxMy43Mzg1Wk0zMC41MzcgOS43NDQxNEMyOS45ODYxIDkuNzQ0MTQgMjkuNDI5OSA5Ljg0NTg0IDI4LjczMzIgMTAuMDcxOEwyOC4yNzk1IDEwLjIxMzFMMjguNDMwOCAxMS4yODY1TDI4Ljg3MzYgMTEuMTM0QzI5LjMzODEgMTAuOTc1OCAyOS45MTU5IDEwLjg3NDEgMzAuMzQ4IDEwLjg3NDFDMzAuNTQyNCAxMC44NzQxIDMxLjEzNjUgMTAuODc0MSAzMS4xMzY1IDExLjU0NjRWMTEuODQwMkgzMC4zMTAyQzI4LjgwMzQgMTEuODQwMiAyOC4xMDEzIDEyLjM0MyAyOC4xMDEzIDEzLjQyMjFDMjguMTAxMyAxNC4zNDMgMjguNzQ0IDE0Ljg5NjcgMjkuODI5NSAxNC44OTY3QzMwLjE2NDQgMTQuODk2NyAzMC42Mjg4IDE0LjgyODkgMzEuMDI4NSAxNC43MjcyTDMxLjA1MDEgMTQuNzIxNUwzMS4wNzE3IDE0LjcyNzJMMzEuMjAxMyAxNC43NDk4QzMxLjYyNzkgMTQuODI4OSAzMi4wNiAxNC45MDggMzIuNDg2NiAxNC45OTg0VjExLjQ3M0MzMi40OTIgMTAuMzIwNCAzMS44MzMyIDkuNzQ0MTQgMzAuNTM3IDkuNzQ0MTRaXCJcbiAgICAgICAgZmlsbD1cIiM3NDc1ODNcIlxuICAgICAgLz5cbiAgICAgIDxwYXRoXG4gICAgICAgIGQ9XCJNMjUuNDcwMSA5Ljc1NzZDMjQuNzg0MiA5Ljc1NzYgMjQuMjE3MiA5Ljk5NDg5IDI0LjAwNjUgMTAuMDk2NkwyMy45NTI1IDEwLjEyNDhMMjMuOTAzOSAxMC4wODUzQzIzLjYxMjMgOS44NjQ5NSAyMy4xODU2IDkuNzUxOTUgMjIuNTkxNiA5Ljc1MTk1QzIyLjA2NzcgOS43NTE5NSAyMS41NzYyIDkuODMxMDUgMjEuMDQxNiA5Ljk5NDg5QzIwLjU4MjUgMTAuMTQxOCAyMC40MDQzIDEwLjM3MzQgMjAuNDA0MyAxMC44MDg1VjE0LjgzNjdIMjEuODQwOVYxMS4xMTM1TDIxLjkxMTEgMTEuMDkwOUMyMi4yMDI3IDEwLjk4OTIgMjIuMzc1NSAxMC45NzIzIDIyLjU0MyAxMC45NzIzQzIyLjk1ODggMTAuOTcyMyAyMy4xNjk0IDExLjIwMzkgMjMuMTY5NCAxMS42NTU5VjE0Ljg0MjNIMjQuNTg0NFYxMS41OTM4QzI0LjU4NDQgMTEuNDAxNyAyNC41NDY2IDExLjI4ODcgMjQuNTQxMiAxMS4yNjYxTDI0LjQ5MjYgMTEuMTdMMjQuNTg5OCAxMS4xMjQ4QzI0LjgwNTggMTEuMDIzMSAyNS4wNDM1IDEwLjk3MjMgMjUuMjkxOSAxMC45NzIzQzI1LjU3ODEgMTAuOTcyMyAyNS45MTg0IDExLjA5MDkgMjUuOTE4NCAxMS42NTU5VjE0Ljg0MjNIMjcuMzI3OVYxMS41MDlDMjcuMzI3OSAxMC4zMjgyIDI2LjcyMzEgOS43NTc2IDI1LjQ3MDEgOS43NTc2WlwiXG4gICAgICAgIGZpbGw9XCIjNzQ3NTgzXCJcbiAgICAgIC8+XG4gICAgICA8cGF0aFxuICAgICAgICBkPVwiTTQwLjU4NjYgNC4xMzU1OUM0MC4zNzU5IDQuMTM1NTkgNDAuMDI0OSA0LjExMyAzOS43NDk1IDQuMDU2NUwzOS42Njg0IDQuMDM5NTVWMS44NjQ0MUMzOS42Njg0IDEuNjgzNjIgMzkuNjM2IDEuNTcwNjIgMzkuNjMwNiAxLjU1MzY3TDM5LjU4NzQgMS40NjMyOEwzOS42NzkzIDEuNDIzNzNDMzkuNzAwOSAxLjQxMjQzIDM5LjcyMjUgMS40MDY3OCAzOS43NDk1IDEuMzk1NDhMMzkuNzY1NyAxLjM4NDE4QzM5Ljc5ODEgMS4zNzI4OCAzOS44MzA1IDEuMzYxNTggMzkuODYyOSAxLjM1MDI4QzM5Ljg3OTEgMS4zNDQ2MyAzOS44ODk5IDEuMzM4OTggMzkuOTAwNyAxLjMzODk4QzQwLjIxOTMgMS4yNDg1OSA0MC41MTEgMS4yNTk4OSA0MC42NDA2IDEuMjQ4NTlINDAuNjQ2QzQxLjUyNjMgMS4yNDg1OSA0MS42Mjg5IDIuMDY3OCA0MS42Mjg5IDIuNjgzNjJDNDEuNjIzNSAzLjg4MTM2IDQxLjA1NjQgNC4xMzU1OSA0MC41ODY2IDQuMTM1NTlaTTQwLjU4MTIgMEM0MC41NzA0IDAgNDAuNTU0MiAwIDQwLjU0MzQgMEMzOS43MTcxIDAgMzguODY5MiAwLjIzNzI4OCAzOC41NjY3IDAuNzAwNTY1QzM4LjQwNDcgMC45MjY1NTQgMzguMzEyOSAxLjIwOTA0IDM4LjMwNzUgMS41NDIzN1YzLjc4NTMxQzM4LjMwNzUgMy45Nzc0IDM4LjI2OTcgNC4wNTA4NSAzOC4yNjQzIDQuMDY3OEwzOC4yMTU3IDQuMTYzODRIMzUuNjA3MlYyLjYwNDUySDM1LjYwMThDMzUuNTY5NCAwLjk2MDQ1MiAzNC42NDA0IDAuMDU2NDk3MiAzMy4yOTU3IDAuMDU2NDk3MkgzMy4xMzkxSDMxLjk4MzNDMzEuOTI5MyAwLjQ1NzYyNyAzMS44ODYxIDAuNzQwMTEzIDMxLjgzMjEgMS4xNDEyNEgzMy4xMzkxQzMzLjgyNDkgMS4xNDEyNCAzNC4xODY4IDEuNzUxNDEgMzQuMTg2OCAyLjY4OTI3VjQuMjU5ODlMMzQuMDk1IDQuMjA5MDRDMzQuMDc4OCA0LjIwMzM5IDMzLjk2NTQgNC4xNjM4NCAzMy43ODcxIDQuMTYzODRIMzEuNTI5N0MzMS40ODY1IDQuNDYzMjggMzEuNDMyNSA0Ljg1MzExIDMxLjM3MyA1LjI0Mjk0SDM4LjMxMjlDMzguNTUwNSA1LjE5MjA5IDM4LjgyNTkgNS4xNDY4OSAzOS4wNjM2IDUuMTA3MzVDMzkuNDE0NiA1LjI4ODE0IDQwLjA2ODEgNS4zODQxOCA0MC41MTY0IDUuMzg0MThDNDIuMDIzMSA1LjM4NDE4IDQzLjAwMDcgNC4zMjc2OCA0My4wMDA3IDIuNzAwNTdDNDIuOTk1MyAxLjA5MDQgNDIuMDUwMSAwLjAzMzg5ODMgNDAuNTgxMiAwWlwiXG4gICAgICAgIGZpbGw9XCIjNzQ3NTgzXCJcbiAgICAgIC8+XG4gICAgICA8cGF0aFxuICAgICAgICBkPVwiTTI4LjQxODkgNS45MDgyMUgyOC40ODM3QzI5Ljk5MDUgNS45MDgyMSAzMC42OTI1IDUuMzg4NDQgMzAuNjkyNSA0LjEwNTk1QzMwLjY5MjUgMy4xODUwNSAzMC4wNDk5IDIuNDUwNTkgMjguOTY5NyAyLjQ1MDU5SDI3LjU4MThDMjcuMTY1OSAyLjQ1MDU5IDI2LjkxNzUgMi4yMDIgMjYuOTE3NSAxLjc4MzkyQzI2LjkxNzUgMS41MDE0MyAyNy4wMjAxIDEuMTUxMTUgMjcuNzAwNiAxLjE1MTE1SDMwLjczNTdDMzAuODAwNiAwLjczODcyMyAzMC44MzMgMC40Nzg4MzYgMzAuODkyNCAwLjA2NjQwNjJIMjcuNzM4NEMyNi4yNjk0IDAuMDY2NDA2MiAyNS41Mjk1IDAuNzEwNDc0IDI1LjUyOTUgMS43ODM5MkMyNS41Mjk1IDIuODQ2MDcgMjYuMTcyMiAzLjM5OTc0IDI3LjI1MjMgMy4zOTk3NEgyOC42NDAzQzI5LjA1NjEgMy4zOTk3NCAyOS4zMDQ2IDMuNzQ0MzcgMjkuMzA0NiA0LjEwNTk1QzI5LjMwNDYgNC4zNDMyNCAyOS4yMDIgNC44MzQ3NyAyOC41MjY5IDQuODM0NzdIMjguMjk0N0wyMy44NDk5IDQuODIzNDdIMjMuMDM5OEMyMi4zNTM5IDQuODIzNDcgMjEuODczMyA0LjQxNjY5IDIxLjg3MzMgMy40NzMxOVYyLjgyMzQ3QzIxLjg3MzMgMS44NDA0MiAyMi4yNDU5IDEuMjMwMjUgMjMuMDM5OCAxLjIzMDI1SDI0LjM1NzZDMjQuNDE3IDAuODEyMTY5IDI0LjQ1NDggMC41NDY2MzIgMjQuNTA4OCAwLjE1MTE1MkgyMi44NjdIMjIuNzEwNEMyMS4zNjU2IDAuMTUxMTUyIDIwLjQzNjcgMS4wOTQ2NiAyMC40MDQzIDIuNzM4NzJWMi44MDA4N1YzLjQ3MzE5QzIwLjQzNjcgNS4xMTcyNSAyMS4zNjU2IDUuOTAyNTYgMjIuNzEwNCA1LjkwMjU2SDIyLjg2N0gyNC4wMjI3TDI2LjQzMTQgNS45MDgyMUgyNy44NjhIMjguNDE4OVpcIlxuICAgICAgICBmaWxsPVwiIzc0NzU4M1wiXG4gICAgICAvPlxuICAgIDwvZz5cbiAgICA8ZGVmcz5cbiAgICAgIDxjbGlwUGF0aCBpZD1cImNsaXAwX3NiZF9tYWRhXCI+XG4gICAgICAgIDxyZWN0IHdpZHRoPVwiNDNcIiBoZWlnaHQ9XCIxNVwiIGZpbGw9XCJ3aGl0ZVwiIC8+XG4gICAgICA8L2NsaXBQYXRoPlxuICAgIDwvZGVmcz5cbiAgPC9zdmc+XG48L25nLXRlbXBsYXRlPlxuIl19
|