simpo-component-library 3.6.935 → 3.6.937
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/esm2022/lib/ecommerce/sections/book-appointment/book-appointment.component.mjs +270 -0
- package/esm2022/lib/ecommerce/sections/cart/cart.component.mjs +3 -3
- package/esm2022/lib/ecommerce/sections/product-desc/product-desc.component.mjs +15 -164
- package/esm2022/lib/ecommerce/sections/product-list/product-list.component.mjs +15 -162
- package/esm2022/lib/elements/booking-cart-groups/booking-cart-groups.component.mjs +11 -13
- package/esm2022/lib/elements/schedule-video-call/schedule-video-call.component.mjs +19 -23
- package/esm2022/lib/sections/appointment-form/appointment-booking/appointment-booking/appointment-booking.component.mjs +1 -1
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/simpo-component-library.mjs +2046 -2100
- package/fesm2022/simpo-component-library.mjs.map +1 -1
- package/lib/ecommerce/sections/book-appointment/book-appointment.component.d.ts +77 -0
- package/lib/ecommerce/sections/product-desc/product-desc.component.d.ts +8 -15
- package/lib/ecommerce/sections/product-list/product-list.component.d.ts +7 -17
- package/lib/elements/booking-cart-groups/booking-cart-groups.component.d.ts +4 -2
- package/lib/elements/schedule-video-call/schedule-video-call.component.d.ts +3 -1
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
- package/simpo-component-library-3.6.937.tgz +0 -0
- package/simpo-component-library-3.6.935.tgz +0 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { Component, HostListener, Input } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { MatIcon, MatIconModule } from '@angular/material/icon';
|
|
4
|
+
import { FormsModule } from '@angular/forms';
|
|
5
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
6
|
+
import { MatDatepickerModule } from '@angular/material/datepicker';
|
|
7
|
+
import { MatNativeDateModule } from '@angular/material/core';
|
|
8
|
+
import { MatInputModule } from '@angular/material/input';
|
|
9
|
+
import { ToastModule } from 'primeng/toast';
|
|
10
|
+
import { MessageService } from 'primeng/api';
|
|
11
|
+
import BaseSection from '../../../sections/BaseSection';
|
|
12
|
+
import { LettersOnlyDirective } from '../../../directive/letters-only.directive';
|
|
13
|
+
import { NumbersOnlyDirective } from '../../../directive/numbers-only.directive';
|
|
14
|
+
import * as i0 from "@angular/core";
|
|
15
|
+
import * as i1 from "@angular/router";
|
|
16
|
+
import * as i2 from "../../../services/rest.service";
|
|
17
|
+
import * as i3 from "../../../services/events.service";
|
|
18
|
+
import * as i4 from "primeng/api";
|
|
19
|
+
import * as i5 from "../../../services/storage.service";
|
|
20
|
+
import * as i6 from "../../../services/booking-product-cart.service";
|
|
21
|
+
import * as i7 from "@angular/common";
|
|
22
|
+
import * as i8 from "@angular/material/datepicker";
|
|
23
|
+
import * as i9 from "@angular/forms";
|
|
24
|
+
import * as i10 from "primeng/toast";
|
|
25
|
+
/**
|
|
26
|
+
* Standalone page section for a product-only Home Visit / Video Call booking (a customer's
|
|
27
|
+
* "Continue Booking" click from the product cart, PDP, or header drawer navigates here instead of
|
|
28
|
+
* opening AppointmentBookingComponent as a dialog). Matches the Claude Design prototype's
|
|
29
|
+
* `isWizardSingle` screen: date + time + contact all together on one page, rendered within the
|
|
30
|
+
* site's normal header/footer (this is a plain CMS page section, not an overlay), no service or
|
|
31
|
+
* staff picker - staff is auto-assigned. The full multi-step wizard (service bookings) is
|
|
32
|
+
* unaffected and still opens as a dialog.
|
|
33
|
+
*/
|
|
34
|
+
export class BookAppointmentComponent extends BaseSection {
|
|
35
|
+
constructor(route, router, restService, _eventService, messageService, storageService, bookingProductCartService) {
|
|
36
|
+
super();
|
|
37
|
+
this.route = route;
|
|
38
|
+
this.router = router;
|
|
39
|
+
this.restService = restService;
|
|
40
|
+
this._eventService = _eventService;
|
|
41
|
+
this.messageService = messageService;
|
|
42
|
+
this.storageService = storageService;
|
|
43
|
+
this.bookingProductCartService = bookingProductCartService;
|
|
44
|
+
this.mode = 'HOME_VISIT';
|
|
45
|
+
this.step = 'form';
|
|
46
|
+
this.screenWidth = 0;
|
|
47
|
+
this.businessName = localStorage.getItem('businessName') ?? localStorage.getItem('bName') ?? '';
|
|
48
|
+
this.businessId = localStorage.getItem('businessId') ?? localStorage.getItem('bId') ?? '';
|
|
49
|
+
this.productCartItems = [];
|
|
50
|
+
this.loading = false;
|
|
51
|
+
this.isProcessing = false;
|
|
52
|
+
this.apiStatus = false;
|
|
53
|
+
this.bookingGroup = null;
|
|
54
|
+
this.showCalendar = false;
|
|
55
|
+
this.selectedDate = null;
|
|
56
|
+
this.selectedDateStr = '';
|
|
57
|
+
this.selectedSlot = null;
|
|
58
|
+
this.slots = [];
|
|
59
|
+
this.slotsLoading = false;
|
|
60
|
+
this.homeVisitAddress = { receiverName: '', receiverPhone: '', addressLine1: '', addressLine2: '', city: '', state: '', zipCode: '' };
|
|
61
|
+
this.instructions = '';
|
|
62
|
+
this.appointmentPayload = { customerDetail: { name: '', phoneNumber: '', email: '' } };
|
|
63
|
+
this.dateFilter = (d) => {
|
|
64
|
+
const date = (d || new Date());
|
|
65
|
+
const today = new Date();
|
|
66
|
+
today.setHours(0, 0, 0, 0);
|
|
67
|
+
return date.getTime() >= today.getTime();
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
getScreenSize() { this.screenWidth = window.innerWidth; }
|
|
71
|
+
closeOnOutsideClick() { this.showCalendar = false; }
|
|
72
|
+
get bannerTitle() {
|
|
73
|
+
return this.mode === 'HOME_VISIT' ? 'Try at Home Service' : 'Live Video Call';
|
|
74
|
+
}
|
|
75
|
+
get bannerDesc() {
|
|
76
|
+
return this.mode === 'HOME_VISIT'
|
|
77
|
+
? 'A consultant will visit your address to show you the pieces in your cart.'
|
|
78
|
+
: 'Join a live video call with a consultant to see the pieces in your cart.';
|
|
79
|
+
}
|
|
80
|
+
ngOnInit() {
|
|
81
|
+
this.getScreenSize();
|
|
82
|
+
this.route.queryParams.subscribe((params) => {
|
|
83
|
+
if (params['mode'] === 'HOME_VISIT' || params['mode'] === 'VIDEO_CALL') {
|
|
84
|
+
this.mode = params['mode'];
|
|
85
|
+
}
|
|
86
|
+
if (params['prefillName'])
|
|
87
|
+
this.appointmentPayload.customerDetail.name = params['prefillName'];
|
|
88
|
+
if (params['prefillPhone'])
|
|
89
|
+
this.appointmentPayload.customerDetail.phoneNumber = params['prefillPhone'];
|
|
90
|
+
});
|
|
91
|
+
// Same guard as AppointmentBookingComponent - a real redirect here instead of closing a
|
|
92
|
+
// dialog, since this is now a real page. The booking cart lives in IndexedDB independent of
|
|
93
|
+
// auth state, so nothing is lost by bouncing to /login and back.
|
|
94
|
+
if (!this.edit && !this.storageService.getUser()) {
|
|
95
|
+
this.router.navigate(['/login'], { queryParams: { redirectTo: this.router.url } });
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
this.loadProductCart();
|
|
99
|
+
}
|
|
100
|
+
async loadProductCart() {
|
|
101
|
+
this.productCartItems = await this.bookingProductCartService.getItems(this.mode);
|
|
102
|
+
}
|
|
103
|
+
toggleCalendar(event) {
|
|
104
|
+
if (event)
|
|
105
|
+
event.stopPropagation();
|
|
106
|
+
this.showCalendar = !this.showCalendar;
|
|
107
|
+
}
|
|
108
|
+
formatDate(d) {
|
|
109
|
+
const dd = String(d.getDate()).padStart(2, '0');
|
|
110
|
+
const mm = String(d.getMonth() + 1).padStart(2, '0');
|
|
111
|
+
const yyyy = d.getFullYear();
|
|
112
|
+
return `${dd}-${mm}-${yyyy}`;
|
|
113
|
+
}
|
|
114
|
+
toIsoDate(d) {
|
|
115
|
+
const date = d ?? new Date();
|
|
116
|
+
const yyyy = date.getFullYear();
|
|
117
|
+
const mm = String(date.getMonth() + 1).padStart(2, '0');
|
|
118
|
+
const dd = String(date.getDate()).padStart(2, '0');
|
|
119
|
+
return `${yyyy}-${mm}-${dd}T00:00:00.000Z`;
|
|
120
|
+
}
|
|
121
|
+
convertTo24Hour(time) {
|
|
122
|
+
const [hourMin, modifierRaw] = time.split(' ');
|
|
123
|
+
const modifier = modifierRaw.toUpperCase();
|
|
124
|
+
let [hours, minutes] = hourMin.split(':').map(Number);
|
|
125
|
+
if (modifier === 'PM' && hours < 12)
|
|
126
|
+
hours += 12;
|
|
127
|
+
if (modifier === 'AM' && hours === 12)
|
|
128
|
+
hours = 0;
|
|
129
|
+
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')} ${modifier}`;
|
|
130
|
+
}
|
|
131
|
+
onDateSelected(date) {
|
|
132
|
+
this.selectedDate = date;
|
|
133
|
+
this.selectedDateStr = this.formatDate(date);
|
|
134
|
+
this.showCalendar = false;
|
|
135
|
+
this.selectedSlot = null;
|
|
136
|
+
this.slots = [];
|
|
137
|
+
this.staffId = undefined;
|
|
138
|
+
this.staffName = undefined;
|
|
139
|
+
this.autoAssignStaffAndFetchSlots();
|
|
140
|
+
}
|
|
141
|
+
// No staff picker shown to the customer - product-only bookings just take the first eligible
|
|
142
|
+
// staff member, same eligibility rule the wizard's manual-pick list uses.
|
|
143
|
+
autoAssignStaffAndFetchSlots() {
|
|
144
|
+
this.loading = true;
|
|
145
|
+
const payload = { serviceId: '', storeId: '', businessId: this.businessId ?? '' };
|
|
146
|
+
this.restService.getAllStaff(payload).subscribe((res) => {
|
|
147
|
+
const eligible = (res || []).filter((staff) => staff.active === true && staff.bookingAllowed);
|
|
148
|
+
if (eligible.length === 0) {
|
|
149
|
+
this.loading = false;
|
|
150
|
+
this.messageService.add({ severity: 'error', summary: 'No Staff Available', detail: 'No one is available to fulfil this booking right now - please try another date.' });
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
this.staffId = eligible[0].staffId;
|
|
154
|
+
this.staffName = eligible[0].staffName;
|
|
155
|
+
this.fetchSlots();
|
|
156
|
+
}, () => {
|
|
157
|
+
this.loading = false;
|
|
158
|
+
this.messageService.add({ severity: 'error', summary: 'Unable to check availability', detail: 'Please try again' });
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
fetchSlots() {
|
|
162
|
+
this.slotsLoading = true;
|
|
163
|
+
const payload = {
|
|
164
|
+
serviceIds: [],
|
|
165
|
+
businessId: this.businessId,
|
|
166
|
+
bookingDate: this.toIsoDate(this.selectedDate),
|
|
167
|
+
staffId: this.staffId,
|
|
168
|
+
mode: this.mode
|
|
169
|
+
};
|
|
170
|
+
this.restService.getBookingSlots(payload).subscribe((res) => {
|
|
171
|
+
this.slots = (res || []).map((v) => ({ selected: false, value: v }));
|
|
172
|
+
this.slotsLoading = false;
|
|
173
|
+
this.loading = false;
|
|
174
|
+
}, () => {
|
|
175
|
+
this.slotsLoading = false;
|
|
176
|
+
this.loading = false;
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
selectSlot(slot) {
|
|
180
|
+
this.slots.forEach((s) => s.selected = false);
|
|
181
|
+
slot.selected = true;
|
|
182
|
+
this.selectedSlot = slot;
|
|
183
|
+
}
|
|
184
|
+
invalid() {
|
|
185
|
+
const c = this.appointmentPayload.customerDetail;
|
|
186
|
+
const emailOk = !!c.email && /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/.test(c.email);
|
|
187
|
+
const contactOk = !!c.name && emailOk && c.phoneNumber?.length === 10;
|
|
188
|
+
const addressOk = this.mode !== 'HOME_VISIT' ||
|
|
189
|
+
(!!this.homeVisitAddress.addressLine1 && !!this.homeVisitAddress.city && !!this.homeVisitAddress.zipCode);
|
|
190
|
+
return !(contactOk && !!this.selectedSlot && addressOk);
|
|
191
|
+
}
|
|
192
|
+
goToReview() {
|
|
193
|
+
if (this.invalid())
|
|
194
|
+
return;
|
|
195
|
+
this.step = 'review';
|
|
196
|
+
}
|
|
197
|
+
backToForm() {
|
|
198
|
+
this.step = 'form';
|
|
199
|
+
}
|
|
200
|
+
confirmBooking() {
|
|
201
|
+
if (!this.edit && !this.storageService.getUser()) {
|
|
202
|
+
this.router.navigate(['/login'], { queryParams: { redirectTo: this.router.url } });
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
this.isProcessing = true;
|
|
206
|
+
const lines = [{
|
|
207
|
+
serviceIds: [],
|
|
208
|
+
staffId: this.staffId,
|
|
209
|
+
startTime: this.selectedSlot ? this.convertTo24Hour(this.selectedSlot.value).slice(0, 5) : undefined
|
|
210
|
+
}];
|
|
211
|
+
const holdPayload = {
|
|
212
|
+
businessId: this.businessId,
|
|
213
|
+
mode: this.mode,
|
|
214
|
+
bookingDate: this.toIsoDate(this.selectedDate),
|
|
215
|
+
customerDetail: this.appointmentPayload.customerDetail,
|
|
216
|
+
lines,
|
|
217
|
+
productLines: this.productCartItems.map((p) => this.bookingProductCartService.toProductLine(p)),
|
|
218
|
+
addressDetails: this.mode === 'HOME_VISIT' ? { ...this.homeVisitAddress, instructions: this.instructions } : undefined
|
|
219
|
+
};
|
|
220
|
+
this.restService.holdBooking(holdPayload).subscribe((group) => {
|
|
221
|
+
this.bookingGroup = group;
|
|
222
|
+
if (this.productCartItems.length > 0) {
|
|
223
|
+
this.bookingProductCartService.clear(this.mode);
|
|
224
|
+
}
|
|
225
|
+
if (group.status === 'HOLD' && group.totalCollectedAtBooking > 0) {
|
|
226
|
+
// Must act on this immediately - the hold expires in 10 minutes.
|
|
227
|
+
this.restService.generatePaymentToken(group.groupId).subscribe((order) => {
|
|
228
|
+
localStorage.setItem('appointmentPaymentId', order.pgOrderId);
|
|
229
|
+
this.isProcessing = false;
|
|
230
|
+
this._eventService.cashFreeEvent.emit({ data: { orderSignature: order.orderSignature } });
|
|
231
|
+
}, (error) => {
|
|
232
|
+
this.isProcessing = false;
|
|
233
|
+
this.messageService.add({ severity: 'error', summary: 'Payment Failed', detail: error.error?.message });
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
this.apiStatus = true;
|
|
238
|
+
this.step = 'done';
|
|
239
|
+
this.isProcessing = false;
|
|
240
|
+
}
|
|
241
|
+
}, (error) => {
|
|
242
|
+
this.isProcessing = false;
|
|
243
|
+
this.apiStatus = false;
|
|
244
|
+
this.messageService.add({ severity: 'error', summary: 'Booking Failed', detail: error.error?.message });
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BookAppointmentComponent, deps: [{ token: i1.ActivatedRoute }, { token: i1.Router }, { token: i2.RestService }, { token: i3.EventsService }, { token: i4.MessageService }, { token: i5.StorageServiceService }, { token: i6.BookingProductCartService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
248
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: BookAppointmentComponent, isStandalone: true, selector: "simpo-book-appointment", inputs: { data: "data", index: "index", edit: "edit", delete: "delete", customClass: "customClass" }, host: { listeners: { "window:resize": "getScreenSize($event)", "document:click": "closeOnOutsideClick()" } }, providers: [MessageService], usesInheritance: true, ngImport: i0, template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\">\n <div class=\"main_header\">\n <div class=\"header d-flex justify-content-between align-items-center\">\n <div class=\"header-title\">\n <h1>{{bannerTitle}}</h1>\n <p>{{bannerDesc}}</p>\n </div>\n </div>\n </div>\n\n <div class=\"main_body w-100 d-flex justify-content-center\">\n <ng-container *ngIf=\"step === 'form'\">\n <div class=\"w-60 date_section\">\n <div class=\"row justify-content-center h-100\">\n <div class=\"col-12 h-100\">\n <div class=\"d-flex gap-4 main_container\">\n <div [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Select Date</h3>\n\n <div class=\"date-picker-container d-flex align-items-center justify-content-between\"\n (click)=\"$event.stopPropagation()\">\n <input type=\"text\" class=\"date-input border-0 rounded-2\" placeholder=\"dd-mm-yyyy\"\n [value]=\"selectedDateStr\" readonly (click)=\"toggleCalendar($event)\">\n\n <mat-icon class=\"ms-2\" (click)=\"toggleCalendar($event)\">calendar_today</mat-icon>\n </div>\n <div class=\"position-relative\" (click)=\"$event.stopPropagation()\">\n <div class=\"datepicker-popover\" *ngIf=\"showCalendar\">\n <mat-calendar [(selected)]=\"selectedDate\" [dateFilter]=\"dateFilter\"\n (selectedChange)=\"onDateSelected($event)\" class=\"datepicker-calendar\">\n </mat-calendar>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"time_selection\" [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card h-100 rounded-3 p-4\">\n <h3 class=\"section-title\">Select Time</h3>\n <div class=\"row g-2 mb-4 overflow-scroll\">\n <ng-container *ngIf=\"!slotsLoading\">\n <div class=\"col-4\" *ngFor=\"let time of slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlot(time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n </ng-container>\n <p class=\"mb-0\" *ngIf=\"!selectedDateStr\">Pick a date to see available times.</p>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex gap-3 details_container flex-column w-100 mt-4\">\n <div class=\"d-flex gap-4\">\n <div [ngClass]=\"{'w-50' : mode === 'HOME_VISIT', 'w-100' : mode !== 'HOME_VISIT'}\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Contact Details</h3>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Full Name\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"text\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.name\" simpoLettersOnly>\n </div>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Email Address\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"email\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.email\"\n pattern=\"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" name=\"email\" required>\n </div>\n\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">\n Phone Number\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"tel\" class=\"form-control rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.phoneNumber\" simpoNumbersOnly\n [ngClass]=\"{'mobile_number' : appointmentPayload.customerDetail.phoneNumber.length != 10}\">\n </div>\n </div>\n </div>\n\n <div class=\"w-50\" *ngIf=\"mode === 'HOME_VISIT'\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Home Visit Details</h3>\n\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Name</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.receiverName\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Phone</label>\n <input type=\"tel\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.receiverPhone\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 1</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine1\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 2 (optional)</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine2\">\n </div>\n <div class=\"d-flex gap-2 mb-3\">\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">City</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.city\">\n </div>\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">State</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.state\">\n </div>\n </div>\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">Pincode</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.zipCode\">\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex justify-content-end mt-4\">\n <button class=\"continue-btn\" [disabled]=\"invalid()\" (click)=\"goToReview()\">Review\n Booking</button>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"step === 'review'\">\n <div class=\"w-60 payment_section\">\n <div class=\"w-100 h-100\">\n <div class=\"w-100 d-flex justify-content-center align-items-center flex-column\">\n <div class=\"payment-header mb-3 w-100\">\n <h1 style=\"font-size:24px;font-weight: 600;\">Booking Summary</h1>\n <p class=\"payment-subtitle mb-0\">Review your booking before confirming</p>\n </div>\n\n <div class=\"booking-summary-card\" [ngClass]=\"{'w-100' : screenWidth < 475,'w-50':screenWidth > 475}\">\n <div class=\"summary-row\">\n <div class=\"summary-label\">Date & Time</div>\n <div class=\"summary-value\">{{selectedDateStr}} at {{selectedSlot?.value ?? 'N/A'}}</div>\n </div>\n\n <div *ngIf=\"productCartItems.length > 0\">\n <h2 class=\"summary-title\">Products</h2>\n <div class=\"summary-row\" *ngFor=\"let p of productCartItems\">\n <div class=\"summary-label\">{{p.itemName}} x{{p.quantity}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{(p.sellingPrice ?? p.price ?? 0) * (p.quantity ?? 1)}}</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"step === 'done'\">\n <div class=\"booking-confirmation\">\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book your appointment. Please\n try again later'}}\n </p>\n\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && mode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Your Video Call Link</h3>\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n <div class=\"details-row\">\n <span class=\"detail-label\">{{productCartItems.length ? 'Products' : (mode === 'HOME_VISIT' ? 'Home Visit' : 'Video Call')}}</span>\n <span class=\"detail-value\">{{selectedDateStr}} at {{selectedSlot?.value ?? 'N/A'}}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n\n <div class=\"main_footer d-flex justify-content-center align-items-center\" *ngIf=\"step === 'review'\">\n <div class=\"footer-buttons\" style=\"justify-content:space-between\">\n <span class=\"back-footer-btn cursor-pointer\" (click)=\"backToForm()\">Back</span>\n <button class=\"cursor-pointer d-flex justify-content-evenly align-items-center\"\n (click)=\"confirmBooking()\" [disabled]=\"isProcessing\"\n [ngClass]=\"{'pay-now-btn' : bookingGroup?.totalCollectedAtBooking > 0 || !bookingGroup,'complete_booking' : bookingGroup && !bookingGroup?.totalCollectedAtBooking}\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/304012c1753440087996Background.png\">\n {{isProcessing ? 'Please wait...' : 'Confirm Booking'}}\n </button>\n </div>\n </div>\n</section>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.date-picker-container{border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;transition:var(--transition-smooth);background-color:var(--slate-50);cursor:pointer}.date-picker-container:hover{border-color:var(--slate-400);background-color:#fff}.date-input{font-size:.95rem;font-weight:600;color:var(--slate-800)!important;background:transparent;border:none;outline:none;cursor:pointer;width:100%}.date-picker-container mat-icon{color:var(--color-primary)!important;font-size:20px!important;width:20px!important;height:20px!important}.datepicker-popover{position:absolute;z-index:1000;margin-top:4px;border-radius:var(--border-radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);background:#fff;border:1px solid var(--slate-200);width:320px}::ng-deep .datepicker-calendar{border-radius:var(--border-radius-lg)!important;width:100%!important}::ng-deep .mat-calendar-header{background:var(--color-accent-gradient)!important;color:#fff!important;padding:.5rem!important}::ng-deep .mat-calendar-content{padding:8px!important}::ng-deep .mat-calendar-controls{margin:0!important}::ng-deep .mat-calendar-period-button{color:#fff!important;font-weight:700!important;font-size:1rem!important}::ng-deep .mat-calendar-arrow{fill:#fff!important}::ng-deep .mat-calendar-previous-button,::ng-deep .mat-calendar-next-button{color:#fff!important}::ng-deep .mat-calendar-body-cell{font-size:13px!important}::ng-deep .mat-calendar-body-cell-content{font-weight:600!important;color:var(--slate-800)!important;border-radius:8px!important}::ng-deep .mat-calendar-body-selected{background:var(--color-accent-gradient)!important;color:#fff!important;box-shadow:0 4px 10px #23086033!important}::ng-deep .mat-calendar-body-today:not(.mat-calendar-body-selected){border:2px solid var(--color-primary)!important;color:var(--color-primary)!important}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.9rem;font-weight:600;color:var(--slate-800)!important;padding:.75rem .5rem;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.main_footer{border-top:1px solid var(--slate-200);background-color:#fff;padding:15px;flex-shrink:0;display:flex;justify-content:center;box-shadow:0 -4px 12px #00000005}.footer-buttons{width:100%;max-width:800px;display:flex;align-items:center}.back-footer-btn{font-size:.95rem;font-weight:600;color:var(--slate-600)!important;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);cursor:pointer}.back-footer-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.complete_booking,.pay-now-btn{background:var(--color-accent-gradient)!important;color:#fff!important;border:none;padding:.75rem 2.25rem!important;font-size:.95rem!important;font-weight:600;border-radius:var(--border-radius-md)!important;box-shadow:0 4px 12px #23086040;transition:var(--transition-smooth);cursor:pointer;display:flex;align-items:center;gap:.5rem;width:max-content!important}.complete_booking img,.pay-now-btn img{width:20px;height:20px;filter:brightness(0) invert(1)}.complete_booking:hover:not([disabled]),.pay-now-btn:hover:not([disabled]){transform:translateY(-2px);box-shadow:0 6px 18px #23086059}.complete_booking:disabled,.pay-now-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed;box-shadow:none}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.datepicker-popover{width:100%;left:0}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}h1{font-size:24px!important;font-weight:600!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i8.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i9.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i9.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: LettersOnlyDirective, selector: "[simpoLettersOnly]" }, { kind: "directive", type: NumbersOnlyDirective, selector: "[simpoNumbersOnly]" }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i10.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }] }); }
|
|
249
|
+
}
|
|
250
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BookAppointmentComponent, decorators: [{
|
|
251
|
+
type: Component,
|
|
252
|
+
args: [{ selector: 'simpo-book-appointment', standalone: true, imports: [CommonModule, MatIcon, MatIconModule, MatFormFieldModule, MatDatepickerModule, FormsModule, MatNativeDateModule, MatInputModule, LettersOnlyDirective, NumbersOnlyDirective, ToastModule], providers: [MessageService], template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\">\n <div class=\"main_header\">\n <div class=\"header d-flex justify-content-between align-items-center\">\n <div class=\"header-title\">\n <h1>{{bannerTitle}}</h1>\n <p>{{bannerDesc}}</p>\n </div>\n </div>\n </div>\n\n <div class=\"main_body w-100 d-flex justify-content-center\">\n <ng-container *ngIf=\"step === 'form'\">\n <div class=\"w-60 date_section\">\n <div class=\"row justify-content-center h-100\">\n <div class=\"col-12 h-100\">\n <div class=\"d-flex gap-4 main_container\">\n <div [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Select Date</h3>\n\n <div class=\"date-picker-container d-flex align-items-center justify-content-between\"\n (click)=\"$event.stopPropagation()\">\n <input type=\"text\" class=\"date-input border-0 rounded-2\" placeholder=\"dd-mm-yyyy\"\n [value]=\"selectedDateStr\" readonly (click)=\"toggleCalendar($event)\">\n\n <mat-icon class=\"ms-2\" (click)=\"toggleCalendar($event)\">calendar_today</mat-icon>\n </div>\n <div class=\"position-relative\" (click)=\"$event.stopPropagation()\">\n <div class=\"datepicker-popover\" *ngIf=\"showCalendar\">\n <mat-calendar [(selected)]=\"selectedDate\" [dateFilter]=\"dateFilter\"\n (selectedChange)=\"onDateSelected($event)\" class=\"datepicker-calendar\">\n </mat-calendar>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"time_selection\" [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card h-100 rounded-3 p-4\">\n <h3 class=\"section-title\">Select Time</h3>\n <div class=\"row g-2 mb-4 overflow-scroll\">\n <ng-container *ngIf=\"!slotsLoading\">\n <div class=\"col-4\" *ngFor=\"let time of slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlot(time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n </ng-container>\n <p class=\"mb-0\" *ngIf=\"!selectedDateStr\">Pick a date to see available times.</p>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex gap-3 details_container flex-column w-100 mt-4\">\n <div class=\"d-flex gap-4\">\n <div [ngClass]=\"{'w-50' : mode === 'HOME_VISIT', 'w-100' : mode !== 'HOME_VISIT'}\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Contact Details</h3>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Full Name\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"text\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.name\" simpoLettersOnly>\n </div>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Email Address\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"email\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.email\"\n pattern=\"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" name=\"email\" required>\n </div>\n\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">\n Phone Number\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"tel\" class=\"form-control rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.phoneNumber\" simpoNumbersOnly\n [ngClass]=\"{'mobile_number' : appointmentPayload.customerDetail.phoneNumber.length != 10}\">\n </div>\n </div>\n </div>\n\n <div class=\"w-50\" *ngIf=\"mode === 'HOME_VISIT'\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Home Visit Details</h3>\n\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Name</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.receiverName\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Phone</label>\n <input type=\"tel\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.receiverPhone\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 1</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine1\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 2 (optional)</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine2\">\n </div>\n <div class=\"d-flex gap-2 mb-3\">\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">City</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.city\">\n </div>\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">State</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.state\">\n </div>\n </div>\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">Pincode</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.zipCode\">\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex justify-content-end mt-4\">\n <button class=\"continue-btn\" [disabled]=\"invalid()\" (click)=\"goToReview()\">Review\n Booking</button>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"step === 'review'\">\n <div class=\"w-60 payment_section\">\n <div class=\"w-100 h-100\">\n <div class=\"w-100 d-flex justify-content-center align-items-center flex-column\">\n <div class=\"payment-header mb-3 w-100\">\n <h1 style=\"font-size:24px;font-weight: 600;\">Booking Summary</h1>\n <p class=\"payment-subtitle mb-0\">Review your booking before confirming</p>\n </div>\n\n <div class=\"booking-summary-card\" [ngClass]=\"{'w-100' : screenWidth < 475,'w-50':screenWidth > 475}\">\n <div class=\"summary-row\">\n <div class=\"summary-label\">Date & Time</div>\n <div class=\"summary-value\">{{selectedDateStr}} at {{selectedSlot?.value ?? 'N/A'}}</div>\n </div>\n\n <div *ngIf=\"productCartItems.length > 0\">\n <h2 class=\"summary-title\">Products</h2>\n <div class=\"summary-row\" *ngFor=\"let p of productCartItems\">\n <div class=\"summary-label\">{{p.itemName}} x{{p.quantity}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{(p.sellingPrice ?? p.price ?? 0) * (p.quantity ?? 1)}}</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"step === 'done'\">\n <div class=\"booking-confirmation\">\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book your appointment. Please\n try again later'}}\n </p>\n\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && mode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Your Video Call Link</h3>\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n <div class=\"details-row\">\n <span class=\"detail-label\">{{productCartItems.length ? 'Products' : (mode === 'HOME_VISIT' ? 'Home Visit' : 'Video Call')}}</span>\n <span class=\"detail-value\">{{selectedDateStr}} at {{selectedSlot?.value ?? 'N/A'}}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n\n <div class=\"main_footer d-flex justify-content-center align-items-center\" *ngIf=\"step === 'review'\">\n <div class=\"footer-buttons\" style=\"justify-content:space-between\">\n <span class=\"back-footer-btn cursor-pointer\" (click)=\"backToForm()\">Back</span>\n <button class=\"cursor-pointer d-flex justify-content-evenly align-items-center\"\n (click)=\"confirmBooking()\" [disabled]=\"isProcessing\"\n [ngClass]=\"{'pay-now-btn' : bookingGroup?.totalCollectedAtBooking > 0 || !bookingGroup,'complete_booking' : bookingGroup && !bookingGroup?.totalCollectedAtBooking}\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/304012c1753440087996Background.png\">\n {{isProcessing ? 'Please wait...' : 'Confirm Booking'}}\n </button>\n </div>\n </div>\n</section>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.date-picker-container{border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;transition:var(--transition-smooth);background-color:var(--slate-50);cursor:pointer}.date-picker-container:hover{border-color:var(--slate-400);background-color:#fff}.date-input{font-size:.95rem;font-weight:600;color:var(--slate-800)!important;background:transparent;border:none;outline:none;cursor:pointer;width:100%}.date-picker-container mat-icon{color:var(--color-primary)!important;font-size:20px!important;width:20px!important;height:20px!important}.datepicker-popover{position:absolute;z-index:1000;margin-top:4px;border-radius:var(--border-radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);background:#fff;border:1px solid var(--slate-200);width:320px}::ng-deep .datepicker-calendar{border-radius:var(--border-radius-lg)!important;width:100%!important}::ng-deep .mat-calendar-header{background:var(--color-accent-gradient)!important;color:#fff!important;padding:.5rem!important}::ng-deep .mat-calendar-content{padding:8px!important}::ng-deep .mat-calendar-controls{margin:0!important}::ng-deep .mat-calendar-period-button{color:#fff!important;font-weight:700!important;font-size:1rem!important}::ng-deep .mat-calendar-arrow{fill:#fff!important}::ng-deep .mat-calendar-previous-button,::ng-deep .mat-calendar-next-button{color:#fff!important}::ng-deep .mat-calendar-body-cell{font-size:13px!important}::ng-deep .mat-calendar-body-cell-content{font-weight:600!important;color:var(--slate-800)!important;border-radius:8px!important}::ng-deep .mat-calendar-body-selected{background:var(--color-accent-gradient)!important;color:#fff!important;box-shadow:0 4px 10px #23086033!important}::ng-deep .mat-calendar-body-today:not(.mat-calendar-body-selected){border:2px solid var(--color-primary)!important;color:var(--color-primary)!important}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.9rem;font-weight:600;color:var(--slate-800)!important;padding:.75rem .5rem;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.main_footer{border-top:1px solid var(--slate-200);background-color:#fff;padding:15px;flex-shrink:0;display:flex;justify-content:center;box-shadow:0 -4px 12px #00000005}.footer-buttons{width:100%;max-width:800px;display:flex;align-items:center}.back-footer-btn{font-size:.95rem;font-weight:600;color:var(--slate-600)!important;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);cursor:pointer}.back-footer-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.complete_booking,.pay-now-btn{background:var(--color-accent-gradient)!important;color:#fff!important;border:none;padding:.75rem 2.25rem!important;font-size:.95rem!important;font-weight:600;border-radius:var(--border-radius-md)!important;box-shadow:0 4px 12px #23086040;transition:var(--transition-smooth);cursor:pointer;display:flex;align-items:center;gap:.5rem;width:max-content!important}.complete_booking img,.pay-now-btn img{width:20px;height:20px;filter:brightness(0) invert(1)}.complete_booking:hover:not([disabled]),.pay-now-btn:hover:not([disabled]){transform:translateY(-2px);box-shadow:0 6px 18px #23086059}.complete_booking:disabled,.pay-now-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed;box-shadow:none}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.datepicker-popover{width:100%;left:0}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}h1{font-size:24px!important;font-weight:600!important}\n"] }]
|
|
253
|
+
}], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i1.Router }, { type: i2.RestService }, { type: i3.EventsService }, { type: i4.MessageService }, { type: i5.StorageServiceService }, { type: i6.BookingProductCartService }], propDecorators: { data: [{
|
|
254
|
+
type: Input
|
|
255
|
+
}], index: [{
|
|
256
|
+
type: Input
|
|
257
|
+
}], edit: [{
|
|
258
|
+
type: Input
|
|
259
|
+
}], delete: [{
|
|
260
|
+
type: Input
|
|
261
|
+
}], customClass: [{
|
|
262
|
+
type: Input
|
|
263
|
+
}], getScreenSize: [{
|
|
264
|
+
type: HostListener,
|
|
265
|
+
args: ['window:resize', ['$event']]
|
|
266
|
+
}], closeOnOutsideClick: [{
|
|
267
|
+
type: HostListener,
|
|
268
|
+
args: ['document:click']
|
|
269
|
+
}] } });
|
|
270
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9vay1hcHBvaW50bWVudC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zaW1wby11aS9zcmMvbGliL2Vjb21tZXJjZS9zZWN0aW9ucy9ib29rLWFwcG9pbnRtZW50L2Jvb2stYXBwb2ludG1lbnQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2ltcG8tdWkvc3JjL2xpYi9lY29tbWVyY2Uvc2VjdGlvbnMvYm9vay1hcHBvaW50bWVudC9ib29rLWFwcG9pbnRtZW50LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUN2RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNoRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbkUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXpELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM3QyxPQUFPLFdBQVcsTUFBTSwrQkFBK0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUNqRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUs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O3NCQURaLFlBQVk7dUJBQUMsZUFBZSxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQUd6QyxtQkFBbUI7c0JBRGxCLFlBQVk7dUJBQUMsZ0JBQWdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBNYXRJY29uLCBNYXRJY29uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE1hdEZvcm1GaWVsZE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgTWF0RGF0ZXBpY2tlck1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RhdGVwaWNrZXInO1xuaW1wb3J0IHsgTWF0TmF0aXZlRGF0ZU1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NvcmUnO1xuaW1wb3J0IHsgTWF0SW5wdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSwgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFRvYXN0TW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b2FzdCc7XG5pbXBvcnQgeyBNZXNzYWdlU2VydmljZSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCBCYXNlU2VjdGlvbiBmcm9tICcuLi8uLi8uLi9zZWN0aW9ucy9CYXNlU2VjdGlvbic7XG5pbXBvcnQgeyBMZXR0ZXJzT25seURpcmVjdGl2ZSB9IGZyb20gJy4uLy4uLy4uL2RpcmVjdGl2ZS9sZXR0ZXJzLW9ubHkuZGlyZWN0aXZlJztcbmltcG9ydCB7IE51bWJlcnNPbmx5RGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vLi4vZGlyZWN0aXZlL251bWJlcnMtb25seS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgUmVzdFNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9yZXN0LnNlcnZpY2UnO1xuaW1wb3J0IHsgRXZlbnRzU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2V2ZW50cy5zZXJ2aWNlJztcbmltcG9ydCB7IFN0b3JhZ2VTZXJ2aWNlU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL3N0b3JhZ2Uuc2VydmljZSc7XG5pbXBvcnQgeyBCb29raW5nUHJvZHVjdENhcnRTZXJ2aWNlLCBCb29raW5nQ2FydE1vZGUgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9ib29raW5nLXByb2R1Y3QtY2FydC5zZXJ2aWNlJztcblxudHlwZSBQcm9kdWN0VmlzaXRNb2RlID0gJ0hPTUVfVklTSVQnIHwgJ1ZJREVPX0NBTEwnO1xuXG4vKipcbiAqIFN0YW5kYWxvbmUgcGFnZSBzZWN0aW9uIGZvciBhIHByb2R1Y3Qtb25seSBIb21lIFZpc2l0IC8gVmlkZW8gQ2FsbCBib29raW5nIChhIGN1c3RvbWVyJ3NcbiAqIFwiQ29udGludWUgQm9va2luZ1wiIGNsaWNrIGZyb20gdGhlIHByb2R1Y3QgY2FydCwgUERQLCBvciBoZWFkZXIgZHJhd2VyIG5hdmlnYXRlcyBoZXJlIGluc3RlYWQgb2ZcbiAqIG9wZW5pbmcgQXBwb2ludG1lbnRCb29raW5nQ29tcG9uZW50IGFzIGEgZGlhbG9nKS4gTWF0Y2hlcyB0aGUgQ2xhdWRlIERlc2lnbiBwcm90b3R5cGUnc1xuICogYGlzV2l6YXJkU2luZ2xlYCBzY3JlZW46IGRhdGUgKyB0aW1lICsgY29udGFjdCBhbGwgdG9nZXRoZXIgb24gb25lIHBhZ2UsIHJlbmRlcmVkIHdpdGhpbiB0aGVcbiAqIHNpdGUncyBub3JtYWwgaGVhZGVyL2Zvb3RlciAodGhpcyBpcyBhIHBsYWluIENNUyBwYWdlIHNlY3Rpb24sIG5vdCBhbiBvdmVybGF5KSwgbm8gc2VydmljZSBvclxuICogc3RhZmYgcGlja2VyIC0gc3RhZmYgaXMgYXV0by1hc3NpZ25lZC4gVGhlIGZ1bGwgbXVsdGktc3RlcCB3aXphcmQgKHNlcnZpY2UgYm9va2luZ3MpIGlzXG4gKiB1bmFmZmVjdGVkIGFuZCBzdGlsbCBvcGVucyBhcyBhIGRpYWxvZy5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc2ltcG8tYm9vay1hcHBvaW50bWVudCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIE1hdEljb24sIE1hdEljb25Nb2R1bGUsIE1hdEZvcm1GaWVsZE1vZHVsZSwgTWF0RGF0ZXBpY2tlck1vZHVsZSwgRm9ybXNNb2R1bGUsIE1hdE5hdGl2ZURhdGVNb2R1bGUsIE1hdElucHV0TW9kdWxlLCBMZXR0ZXJzT25seURpcmVjdGl2ZSwgTnVtYmVyc09ubHlEaXJlY3RpdmUsIFRvYXN0TW9kdWxlXSxcbiAgcHJvdmlkZXJzOiBbTWVzc2FnZVNlcnZpY2VdLFxuICB0ZW1wbGF0ZVVybDogJy4vYm9vay1hcHBvaW50bWVudC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9ib29rLWFwcG9pbnRtZW50LmNvbXBvbmVudC5jc3MnXG59KVxuZXhwb3J0IGNsYXNzIEJvb2tBcHBvaW50bWVudENvbXBvbmVudCBleHRlbmRzIEJhc2VTZWN0aW9uIGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCkgZGF0YT86IGFueTtcbiAgQElucHV0KCkgaW5kZXg/OiBudW1iZXI7XG4gIEBJbnB1dCgpIGVkaXQ/OiBib29sZWFuO1xuICBASW5wdXQoKSBkZWxldGU/OiBib29sZWFuO1xuICBASW5wdXQoKSBjdXN0b21DbGFzcz86IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlcjogUm91dGVyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVzdFNlcnZpY2U6IFJlc3RTZXJ2aWNlLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2V2ZW50U2VydmljZTogRXZlbnRzU2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1lc3NhZ2VTZXJ2aWNlOiBNZXNzYWdlU2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN0b3JhZ2VTZXJ2aWNlOiBTdG9yYWdlU2VydmljZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWFkb25seSBib29raW5nUHJvZHVjdENhcnRTZXJ2aWNlOiBCb29raW5nUHJvZHVjdENhcnRTZXJ2aWNlLFxuICApIHsgc3VwZXIoKTsgfVxuXG4gIG1vZGU6IFByb2R1Y3RWaXNpdE1vZGUgPSAnSE9NRV9WSVNJVCc7XG4gIHN0ZXA6ICdmb3JtJyB8ICdyZXZpZXcnIHwgJ2RvbmUnID0gJ2Zvcm0nO1xuICBzY3JlZW5XaWR0aDogbnVtYmVyID0gMDtcbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScsIFsnJGV2ZW50J10pXG4gIGdldFNjcmVlblNpemUoKSB7IHRoaXMuc2NyZWVuV2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDsgfVxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycpXG4gIGNsb3NlT25PdXRzaWRlQ2xpY2soKSB7IHRoaXMuc2hvd0NhbGVuZGFyID0gZmFsc2U7IH1cblxuICBidXNpbmVzc05hbWUgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYnVzaW5lc3NOYW1lJykgPz8gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2JOYW1lJykgPz8gJyc7XG4gIGJ1c2luZXNzSWQ6IGFueSA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdidXNpbmVzc0lkJykgPz8gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2JJZCcpID8/ICcnO1xuXG4gIHByb2R1Y3RDYXJ0SXRlbXM6IGFueVtdID0gW107XG4gIGxvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgaXNQcm9jZXNzaW5nOiBib29sZWFuID0gZmFsc2U7XG4gIGFwaVN0YXR1czogYm9vbGVhbiA9IGZhbHNlO1xuICBib29raW5nR3JvdXA6IGFueSA9IG51bGw7XG5cbiAgc2hvd0NhbGVuZGFyID0gZmFsc2U7XG4gIHNlbGVjdGVkRGF0ZTogRGF0ZSB8IG51bGwgPSBudWxsO1xuICBzZWxlY3RlZERhdGVTdHIgPSAnJztcbiAgc2VsZWN0ZWRTbG90OiBhbnkgPSBudWxsO1xuICBzbG90czogYW55W10gPSBbXTtcbiAgc2xvdHNMb2FkaW5nOiBib29sZWFuID0gZmFsc2U7XG4gIHByaXZhdGUgc3RhZmZJZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHN0YWZmTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIGhvbWVWaXNpdEFkZHJlc3M6IGFueSA9IHsgcmVjZWl2ZXJOYW1lOiAnJywgcmVjZWl2ZXJQaG9uZTogJycsIGFkZHJlc3NMaW5lMTogJycsIGFkZHJlc3NMaW5lMjogJycsIGNpdHk6ICcnLCBzdGF0ZTogJycsIHppcENvZGU6ICcnIH07XG4gIGluc3RydWN0aW9uczogc3RyaW5nID0gJyc7XG4gIGFwcG9pbnRtZW50UGF5bG9hZDogYW55ID0geyBjdXN0b21lckRldGFpbDogeyBuYW1lOiAnJywgcGhvbmVOdW1iZXI6ICcnLCBlbWFpbDogJycgfSB9O1xuXG4gIGRhdGVGaWx0ZXIgPSAoZDogRGF0ZSB8IG51bGwpOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBkYXRlID0gKGQgfHwgbmV3IERhdGUoKSk7XG4gICAgY29uc3QgdG9kYXkgPSBuZXcgRGF0ZSgpO1xuICAgIHRvZGF5LnNldEhvdXJzKDAsIDAsIDAsIDApO1xuICAgIHJldHVybiBkYXRlLmdldFRpbWUoKSA+PSB0b2RheS5nZXRUaW1lKCk7XG4gIH1cblxuICBnZXQgYmFubmVyVGl0bGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5tb2RlID09PSAnSE9NRV9WSVNJVCcgPyAnVHJ5IGF0IEhvbWUgU2VydmljZScgOiAnTGl2ZSBWaWRlbyBDYWxsJztcbiAgfVxuICBnZXQgYmFubmVyRGVzYygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLm1vZGUgPT09ICdIT01FX1ZJU0lUJ1xuICAgICAgPyAnQSBjb25zdWx0YW50IHdpbGwgdmlzaXQgeW91ciBhZGRyZXNzIHRvIHNob3cgeW91IHRoZSBwaWVjZXMgaW4geW91ciBjYXJ0LidcbiAgICAgIDogJ0pvaW4gYSBsaXZlIHZpZGVvIGNhbGwgd2l0aCBhIGNvbnN1bHRhbnQgdG8gc2VlIHRoZSBwaWVjZXMgaW4geW91ciBjYXJ0Lic7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmdldFNjcmVlblNpemUoKTtcbiAgICB0aGlzLnJvdXRlLnF1ZXJ5UGFyYW1zLnN1YnNjcmliZSgocGFyYW1zOiBhbnkpID0+IHtcbiAgICAgIGlmIChwYXJhbXNbJ21vZGUnXSA9PT0gJ0hPTUVfVklTSVQnIHx8IHBhcmFtc1snbW9kZSddID09PSAnVklERU9fQ0FMTCcpIHtcbiAgICAgICAgdGhpcy5tb2RlID0gcGFyYW1zWydtb2RlJ107XG4gICAgICB9XG4gICAgICBpZiAocGFyYW1zWydwcmVmaWxsTmFtZSddKSB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5uYW1lID0gcGFyYW1zWydwcmVmaWxsTmFtZSddO1xuICAgICAgaWYgKHBhcmFtc1sncHJlZmlsbFBob25lJ10pIHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLnBob25lTnVtYmVyID0gcGFyYW1zWydwcmVmaWxsUGhvbmUnXTtcbiAgICB9KTtcblxuICAgIC8vIFNhbWUgZ3VhcmQgYXMgQXBwb2ludG1lbnRCb29raW5nQ29tcG9uZW50IC0gYSByZWFsIHJlZGlyZWN0IGhlcmUgaW5zdGVhZCBvZiBjbG9zaW5nIGFcbiAgICAvLyBkaWFsb2csIHNpbmNlIHRoaXMgaXMgbm93IGEgcmVhbCBwYWdlLiBUaGUgYm9va2luZyBjYXJ0IGxpdmVzIGluIEluZGV4ZWREQiBpbmRlcGVuZGVudCBvZlxuICAgIC8vIGF1dGggc3RhdGUsIHNvIG5vdGhpbmcgaXMgbG9zdCBieSBib3VuY2luZyB0byAvbG9naW4gYW5kIGJhY2suXG4gICAgaWYgKCF0aGlzLmVkaXQgJiYgIXRoaXMuc3RvcmFnZVNlcnZpY2UuZ2V0VXNlcigpKSB7XG4gICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbJy9sb2dpbiddLCB7IHF1ZXJ5UGFyYW1zOiB7IHJlZGlyZWN0VG86IHRoaXMucm91dGVyLnVybCB9IH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMubG9hZFByb2R1Y3RDYXJ0KCk7XG4gIH1cblxuICBhc3luYyBsb2FkUHJvZHVjdENhcnQoKSB7XG4gICAgdGhpcy5wcm9kdWN0Q2FydEl0ZW1zID0gYXdhaXQgdGhpcy5ib29raW5nUHJvZHVjdENhcnRTZXJ2aWNlLmdldEl0ZW1zKHRoaXMubW9kZSBhcyBCb29raW5nQ2FydE1vZGUpO1xuICB9XG5cbiAgdG9nZ2xlQ2FsZW5kYXIoZXZlbnQ/OiBFdmVudCkge1xuICAgIGlmIChldmVudCkgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5zaG93Q2FsZW5kYXIgPSAhdGhpcy5zaG93Q2FsZW5kYXI7XG4gIH1cblxuICBwcml2YXRlIGZvcm1hdERhdGUoZDogRGF0ZSk6IHN0cmluZyB7XG4gICAgY29uc3QgZGQgPSBTdHJpbmcoZC5nZXREYXRlKCkpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgY29uc3QgbW0gPSBTdHJpbmcoZC5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICBjb25zdCB5eXl5ID0gZC5nZXRGdWxsWWVhcigpO1xuICAgIHJldHVybiBgJHtkZH0tJHttbX0tJHt5eXl5fWA7XG4gIH1cbiAgcHJpdmF0ZSB0b0lzb0RhdGUoZDogRGF0ZSB8IG51bGwpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRhdGUgPSBkID8/IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgeXl5eSA9IGRhdGUuZ2V0RnVsbFllYXIoKTtcbiAgICBjb25zdCBtbSA9IFN0cmluZyhkYXRlLmdldE1vbnRoKCkgKyAxKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIGNvbnN0IGRkID0gU3RyaW5nKGRhdGUuZ2V0RGF0ZSgpKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIHJldHVybiBgJHt5eXl5fS0ke21tfS0ke2RkfVQwMDowMDowMC4wMDBaYDtcbiAgfVxuICBwcml2YXRlIGNvbnZlcnRUbzI0SG91cih0aW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IFtob3VyTWluLCBtb2RpZmllclJhd10gPSB0aW1lLnNwbGl0KCcgJyk7XG4gICAgY29uc3QgbW9kaWZpZXIgPSBtb2RpZmllclJhdy50b1VwcGVyQ2FzZSgpO1xuICAgIGxldCBbaG91cnMsIG1pbnV0ZXNdID0gaG91ck1pbi5zcGxpdCgnOicpLm1hcChOdW1iZXIpO1xuICAgIGlmIChtb2RpZmllciA9PT0gJ1BNJyAmJiBob3VycyA8IDEyKSBob3VycyArPSAxMjtcbiAgICBpZiAobW9kaWZpZXIgPT09ICdBTScgJiYgaG91cnMgPT09IDEyKSBob3VycyA9IDA7XG4gICAgcmV0dXJuIGAke2hvdXJzLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKX06JHttaW51dGVzLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKX0gJHttb2RpZmllcn1gO1xuICB9XG5cbiAgb25EYXRlU2VsZWN0ZWQoZGF0ZTogYW55KSB7XG4gICAgdGhpcy5zZWxlY3RlZERhdGUgPSBkYXRlO1xuICAgIHRoaXMuc2VsZWN0ZWREYXRlU3RyID0gdGhpcy5mb3JtYXREYXRlKGRhdGUpO1xuICAgIHRoaXMuc2hvd0NhbGVuZGFyID0gZmFsc2U7XG4gICAgdGhpcy5zZWxlY3RlZFNsb3QgPSBudWxsO1xuICAgIHRoaXMuc2xvdHMgPSBbXTtcbiAgICB0aGlzLnN0YWZmSWQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5zdGFmZk5hbWUgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5hdXRvQXNzaWduU3RhZmZBbmRGZXRjaFNsb3RzKCk7XG4gIH1cblxuICAvLyBObyBzdGFmZiBwaWNrZXIgc2hvd24gdG8gdGhlIGN1c3RvbWVyIC0gcHJvZHVjdC1vbmx5IGJvb2tpbmdzIGp1c3QgdGFrZSB0aGUgZmlyc3QgZWxpZ2libGVcbiAgLy8gc3RhZmYgbWVtYmVyLCBzYW1lIGVsaWdpYmlsaXR5IHJ1bGUgdGhlIHdpemFyZCdzIG1hbnVhbC1waWNrIGxpc3QgdXNlcy5cbiAgYXV0b0Fzc2lnblN0YWZmQW5kRmV0Y2hTbG90cygpIHtcbiAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xuICAgIGNvbnN0IHBheWxvYWQgPSB7IHNlcnZpY2VJZDogJycsIHN0b3JlSWQ6ICcnLCBidXNpbmVzc0lkOiB0aGlzLmJ1c2luZXNzSWQgPz8gJycgfTtcbiAgICB0aGlzLnJlc3RTZXJ2aWNlLmdldEFsbFN0YWZmKHBheWxvYWQpLnN1YnNjcmliZSgocmVzOiBhbnkpID0+IHtcbiAgICAgIGNvbnN0IGVsaWdpYmxlID0gKHJlcyB8fCBbXSkuZmlsdGVyKChzdGFmZjogYW55KSA9PiBzdGFmZi5hY3RpdmUgPT09IHRydWUgJiYgc3RhZmYuYm9va2luZ0FsbG93ZWQpO1xuICAgICAgaWYgKGVsaWdpYmxlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBzZXZlcml0eTogJ2Vycm9yJywgc3VtbWFyeTogJ05vIFN0YWZmIEF2YWlsYWJsZScsIGRldGFpbDogJ05vIG9uZSBpcyBhdmFpbGFibGUgdG8gZnVsZmlsIHRoaXMgYm9va2luZyByaWdodCBub3cgLSBwbGVhc2UgdHJ5IGFub3RoZXIgZGF0ZS4nIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnN0YWZmSWQgPSBlbGlnaWJsZVswXS5zdGFmZklkO1xuICAgICAgdGhpcy5zdGFmZk5hbWUgPSBlbGlnaWJsZVswXS5zdGFmZk5hbWU7XG4gICAgICB0aGlzLmZldGNoU2xvdHMoKTtcbiAgICB9LCAoKSA9PiB7XG4gICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsgc2V2ZXJpdHk6ICdlcnJvcicsIHN1bW1hcnk6ICdVbmFibGUgdG8gY2hlY2sgYXZhaWxhYmlsaXR5JywgZGV0YWlsOiAnUGxlYXNlIHRyeSBhZ2FpbicgfSk7XG4gICAgfSk7XG4gIH1cblxuICBmZXRjaFNsb3RzKCkge1xuICAgIHRoaXMuc2xvdHNMb2FkaW5nID0gdHJ1ZTtcbiAgICBjb25zdCBwYXlsb2FkOiBhbnkgPSB7XG4gICAgICBzZXJ2aWNlSWRzOiBbXSxcbiAgICAgIGJ1c2luZXNzSWQ6IHRoaXMuYnVzaW5lc3NJZCxcbiAgICAgIGJvb2tpbmdEYXRlOiB0aGlzLnRvSXNvRGF0ZSh0aGlzLnNlbGVjdGVkRGF0ZSksXG4gICAgICBzdGFmZklkOiB0aGlzLnN0YWZmSWQsXG4gICAgICBtb2RlOiB0aGlzLm1vZGVcbiAgICB9O1xuICAgIHRoaXMucmVzdFNlcnZpY2UuZ2V0Qm9va2luZ1Nsb3RzKHBheWxvYWQpLnN1YnNjcmliZSgocmVzOiBhbnkpID0+IHtcbiAgICAgIHRoaXMuc2xvdHMgPSAocmVzIHx8IFtdKS5tYXAoKHY6IHN0cmluZykgPT4gKHsgc2VsZWN0ZWQ6IGZhbHNlLCB2YWx1ZTogdiB9KSk7XG4gICAgICB0aGlzLnNsb3RzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgfSwgKCkgPT4ge1xuICAgICAgdGhpcy5zbG90c0xvYWRpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICAgIH0pO1xuICB9XG5cbiAgc2VsZWN0U2xvdChzbG90OiBhbnkpIHtcbiAgICB0aGlzLnNsb3RzLmZvckVhY2goKHM6IGFueSkgPT4gcy5zZWxlY3RlZCA9IGZhbHNlKTtcbiAgICBzbG90LnNlbGVjdGVkID0gdHJ1ZTtcbiAgICB0aGlzLnNlbGVjdGVkU2xvdCA9IHNsb3Q7XG4gIH1cblxuICBpbnZhbGlkKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGMgPSB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbDtcbiAgICBjb25zdCBlbWFpbE9rID0gISFjLmVtYWlsICYmIC9eW2EtejAtOS5fJSstXStAW2EtejAtOS4tXStcXC5bYS16XXsyLDR9JC8udGVzdChjLmVtYWlsKTtcbiAgICBjb25zdCBjb250YWN0T2sgPSAhIWMubmFtZSAmJiBlbWFpbE9rICYmIGMucGhvbmVOdW1iZXI/Lmxlbmd0aCA9PT0gMTA7XG4gICAgY29uc3QgYWRkcmVzc09rID0gdGhpcy5tb2RlICE9PSAnSE9NRV9WSVNJVCcgfHxcbiAgICAgICghIXRoaXMuaG9tZVZpc2l0QWRkcmVzcy5hZGRyZXNzTGluZTEgJiYgISF0aGlzLmhvbWVWaXNpdEFkZHJlc3MuY2l0eSAmJiAhIXRoaXMuaG9tZVZpc2l0QWRkcmVzcy56aXBDb2RlKTtcbiAgICByZXR1cm4gIShjb250YWN0T2sgJiYgISF0aGlzLnNlbGVjdGVkU2xvdCAmJiBhZGRyZXNzT2spO1xuICB9XG5cbiAgZ29Ub1JldmlldygpIHtcbiAgICBpZiAodGhpcy5pbnZhbGlkKCkpIHJldHVybjtcbiAgICB0aGlzLnN0ZXAgPSAncmV2aWV3JztcbiAgfVxuICBiYWNrVG9Gb3JtKCkge1xuICAgIHRoaXMuc3RlcCA9ICdmb3JtJztcbiAgfVxuXG4gIGNvbmZpcm1Cb29raW5nKCkge1xuICAgIGlmICghdGhpcy5lZGl0ICYmICF0aGlzLnN0b3JhZ2VTZXJ2aWNlLmdldFVzZXIoKSkge1xuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycvbG9naW4nXSwgeyBxdWVyeVBhcmFtczogeyByZWRpcmVjdFRvOiB0aGlzLnJvdXRlci51cmwgfSB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSB0cnVlO1xuICAgIGNvbnN0IGxpbmVzID0gW3tcbiAgICAgIHNlcnZpY2VJZHM6IFtdLFxuICAgICAgc3RhZmZJZDogdGhpcy5zdGFmZklkLFxuICAgICAgc3RhcnRUaW1lOiB0aGlzLnNlbGVjdGVkU2xvdCA/IHRoaXMuY29udmVydFRvMjRIb3VyKHRoaXMuc2VsZWN0ZWRTbG90LnZhbHVlKS5zbGljZSgwLCA1KSA6IHVuZGVmaW5lZFxuICAgIH1dO1xuXG4gICAgY29uc3QgaG9sZFBheWxvYWQ6IGFueSA9IHtcbiAgICAgIGJ1c2luZXNzSWQ6IHRoaXMuYnVzaW5lc3NJZCxcbiAgICAgIG1vZGU6IHRoaXMubW9kZSxcbiAgICAgIGJvb2tpbmdEYXRlOiB0aGlzLnRvSXNvRGF0ZSh0aGlzLnNlbGVjdGVkRGF0ZSksXG4gICAgICBjdXN0b21lckRldGFpbDogdGhpcy5hcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwsXG4gICAgICBsaW5lcyxcbiAgICAgIHByb2R1Y3RMaW5lczogdGhpcy5wcm9kdWN0Q2FydEl0ZW1zLm1hcCgocDogYW55KSA9PiB0aGlzLmJvb2tpbmdQcm9kdWN0Q2FydFNlcnZpY2UudG9Qcm9kdWN0TGluZShwKSksXG4gICAgICBhZGRyZXNzRGV0YWlsczogdGhpcy5tb2RlID09PSAnSE9NRV9WSVNJVCcgPyB7IC4uLnRoaXMuaG9tZVZpc2l0QWRkcmVzcywgaW5zdHJ1Y3Rpb25zOiB0aGlzLmluc3RydWN0aW9ucyB9IDogdW5kZWZpbmVkXG4gICAgfTtcblxuICAgIHRoaXMucmVzdFNlcnZpY2UuaG9sZEJvb2tpbmcoaG9sZFBheWxvYWQpLnN1YnNjcmliZSgoZ3JvdXA6IGFueSkgPT4ge1xuICAgICAgdGhpcy5ib29raW5nR3JvdXAgPSBncm91cDtcbiAgICAgIGlmICh0aGlzLnByb2R1Y3RDYXJ0SXRlbXMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmJvb2tpbmdQcm9kdWN0Q2FydFNlcnZpY2UuY2xlYXIodGhpcy5tb2RlIGFzIEJvb2tpbmdDYXJ0TW9kZSk7XG4gICAgICB9XG4gICAgICBpZiAoZ3JvdXAuc3RhdHVzID09PSAnSE9MRCcgJiYgZ3JvdXAudG90YWxDb2xsZWN0ZWRBdEJvb2tpbmcgPiAwKSB7XG4gICAgICAgIC8vIE11c3QgYWN0IG9uIHRoaXMgaW1tZWRpYXRlbHkgLSB0aGUgaG9sZCBleHBpcmVzIGluIDEwIG1pbnV0ZXMuXG4gICAgICAgIHRoaXMucmVzdFNlcnZpY2UuZ2VuZXJhdGVQYXltZW50VG9rZW4oZ3JvdXAuZ3JvdXBJZCkuc3Vic2NyaWJlKChvcmRlcjogYW55KSA9PiB7XG4gICAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2FwcG9pbnRtZW50UGF5bWVudElkJywgb3JkZXIucGdPcmRlcklkKTtcbiAgICAgICAgICB0aGlzLmlzUHJvY2Vzc2luZyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMuX2V2ZW50U2VydmljZS5jYXNoRnJlZUV2ZW50LmVtaXQoeyBkYXRhOiB7IG9yZGVyU2lnbmF0dXJlOiBvcmRlci5vcmRlclNpZ25hdHVyZSB9IH0pO1xuICAgICAgICB9LCAoZXJyb3I6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMuaXNQcm9jZXNzaW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBzZXZlcml0eTogJ2Vycm9yJywgc3VtbWFyeTogJ1BheW1lbnQgRmFpbGVkJywgZGV0YWlsOiBlcnJvci5lcnJvcj8ubWVzc2FnZSB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFwaVN0YXR1cyA9IHRydWU7XG4gICAgICAgIHRoaXMuc3RlcCA9ICdkb25lJztcbiAgICAgICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9LCAoZXJyb3I6IGFueSkgPT4ge1xuICAgICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuYXBpU3RhdHVzID0gZmFsc2U7XG4gICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7IHNldmVyaXR5OiAnZXJyb3InLCBzdW1tYXJ5OiAnQm9va2luZyBGYWlsZWQnLCBkZXRhaWw6IGVycm9yLmVycm9yPy5tZXNzYWdlIH0pO1xuICAgIH0pO1xuICB9XG59XG4iLCI8cC10b2FzdCBwb3NpdGlvbj1cImJvdHRvbS1yaWdodFwiIFtiYXNlWkluZGV4XT1cIjEwMDAwMDAwMDAwXCIgW2F1dG9aSW5kZXhdPVwidHJ1ZVwiXG4gICAgW3Nob3dUcmFuc2Zvcm1PcHRpb25zXT1cInNjcmVlbldpZHRoIDwgNDc1ID8gJ3RyYW5zbGF0ZVkoLTEwMCUpJyA6ICcnXCI+PC9wLXRvYXN0PlxuPHNlY3Rpb24gY2xhc3M9XCJtYWluX3NlY3Rpb25cIj5cbiAgICA8ZGl2IGNsYXNzPVwibWFpbl9oZWFkZXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImhlYWRlciBkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyLXRpdGxlXCI+XG4gICAgICAgICAgICAgICAgPGgxPnt7YmFubmVyVGl0bGV9fTwvaDE+XG4gICAgICAgICAgICAgICAgPHA+e3tiYW5uZXJEZXNjfX08L3A+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwibWFpbl9ib2R5IHctMTAwIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzdGVwID09PSAnZm9ybSdcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LTYwIGRhdGVfc2VjdGlvblwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3cganVzdGlmeS1jb250ZW50LWNlbnRlciBoLTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTEyIGgtMTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGdhcC00IG1haW5fY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJ7J3ctNTAnIDogc2NyZWVuV2lkdGggPiA0NzUgLCAndy0xMDAnOnNjcmVlbldpZHRoIDwgNDc1fVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbi1jYXJkIGNhcmQgcm91bmRlZC0zIHAtNCBoLTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwic2VjdGlvbi10aXRsZVwiPlNlbGVjdCBEYXRlPC9oMz5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRhdGUtcGlja2VyLWNvbnRhaW5lciBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1iZXR3ZWVuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJkYXRlLWlucHV0IGJvcmRlci0wIHJvdW5kZWQtMlwiIHBsYWNlaG9sZGVyPVwiZGQtbW0teXl5eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJzZWxlY3RlZERhdGVTdHJcIiByZWFkb25seSAoY2xpY2spPVwidG9nZ2xlQ2FsZW5kYXIoJGV2ZW50KVwiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibXMtMlwiIChjbGljayk9XCJ0b2dnbGVDYWxlbmRhcigkZXZlbnQpXCI+Y2FsZW5kYXJfdG9kYXk8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9zaXRpb24tcmVsYXRpdmVcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRhdGVwaWNrZXItcG9wb3ZlclwiICpuZ0lmPVwic2hvd0NhbGVuZGFyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2FsZW5kYXIgWyhzZWxlY3RlZCldPVwic2VsZWN0ZWREYXRlXCIgW2RhdGVGaWx0ZXJdPVwiZGF0ZUZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc2VsZWN0ZWRDaGFuZ2UpPVwib25EYXRlU2VsZWN0ZWQoJGV2ZW50KVwiIGNsYXNzPVwiZGF0ZXBpY2tlci1jYWxlbmRhclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1jYWxlbmRhcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0aW1lX3NlbGVjdGlvblwiIFtuZ0NsYXNzXT1cInsndy01MCcgOiBzY3JlZW5XaWR0aCA+IDQ3NSAsICd3LTEwMCc6c2NyZWVuV2lkdGggPCA0NzV9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWN0aW9uLWNhcmQgY2FyZCBoLTEwMCByb3VuZGVkLTMgcC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJzZWN0aW9uLXRpdGxlXCI+U2VsZWN0IFRpbWU8L2gzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvdyBnLTIgbWItNCBvdmVyZmxvdy1zY3JvbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXNsb3RzTG9hZGluZ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTRcIiAqbmdGb3I9XCJsZXQgdGltZSBvZiBzbG90c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWUtc2xvdCByb3VuZGVkLTJcIiBbY2xhc3Muc2VsZWN0ZWRdPVwidGltZS5zZWxlY3RlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdFNsb3QodGltZSlcIj57e3RpbWUgPyB0aW1lPy52YWx1ZSA6ICdOL0EnfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtYi0wXCIgKm5nSWY9XCIhc2VsZWN0ZWREYXRlU3RyXCI+UGljayBhIGRhdGUgdG8gc2VlIGF2YWlsYWJsZSB0aW1lcy48L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtMyBkZXRhaWxzX2NvbnRhaW5lciBmbGV4LWNvbHVtbiB3LTEwMCBtdC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsndy01MCcgOiBtb2RlID09PSAnSE9NRV9WSVNJVCcsICd3LTEwMCcgOiBtb2RlICE9PSAnSE9NRV9WSVNJVCd9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1zZWN0aW9uIGNhcmQgcm91bmRlZC0zIHAtNCBoLTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cInNlY3Rpb24tdGl0bGVcIj5Db250YWN0IERldGFpbHM8L2gzPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbCBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGdWxsIE5hbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVxdWlyZWQtYXN0ZXJpc2tcIj4qPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWlucHV0IHJvdW5kZWQtMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5uYW1lXCIgc2ltcG9MZXR0ZXJzT25seT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW1haWwgQWRkcmVzc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXF1aXJlZC1hc3Rlcmlza1wiPio8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiZW1haWxcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWlucHV0IHJvdW5kZWQtMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5lbWFpbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuPVwiXlthLXowLTkuXyUrLV0rQFthLXowLTkuLV0rXFwuW2Etel17Miw0fSRcIiBuYW1lPVwiZW1haWxcIiByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0wXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGhvbmUgTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlcXVpcmVkLWFzdGVyaXNrXCI+Kjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZWxcIiBjbGFzcz1cImZvcm0tY29udHJvbCByb3VuZGVkLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJhcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwucGhvbmVOdW1iZXJcIiBzaW1wb051bWJlcnNPbmx5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J21vYmlsZV9udW1iZXInIDogYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLnBob25lTnVtYmVyLmxlbmd0aCAhPSAxMH1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy01MFwiICpuZ0lmPVwibW9kZSA9PT0gJ0hPTUVfVklTSVQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1zZWN0aW9uIGNhcmQgcm91bmRlZC0zIHAtNCBoLTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cInNlY3Rpb24tdGl0bGVcIj5Ib21lIFZpc2l0IERldGFpbHM8L2gzPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbCBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+UmVjZWl2ZXIgTmFtZTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCIgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLnJlY2VpdmVyTmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlJlY2VpdmVyIFBob25lPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZWxcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWlucHV0IHJvdW5kZWQtMlwiIHNpbXBvTnVtYmVyc09ubHkgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLnJlY2VpdmVyUGhvbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItM1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5BZGRyZXNzIExpbmUgMTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCIgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLmFkZHJlc3NMaW5lMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPkFkZHJlc3MgTGluZSAyIChvcHRpb25hbCk8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWlucHV0IHJvdW5kZWQtMlwiIFsobmdNb2RlbCldPVwiaG9tZVZpc2l0QWRkcmVzcy5hZGRyZXNzTGluZTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGdhcC0yIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctNTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPkNpdHk8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1pbnB1dCByb3VuZGVkLTJcIiBbKG5nTW9kZWwpXT1cImhvbWVWaXNpdEFkZHJlc3MuY2l0eVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctNTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlN0YXRlPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCIgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLnN0YXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0wXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlBpbmNvZGU8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWlucHV0IHJvdW5kZWQtMlwiIHNpbXBvTnVtYmVyc09ubHkgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLnppcENvZGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1lbmQgbXQtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJjb250aW51ZS1idG5cIiBbZGlzYWJsZWRdPVwiaW52YWxpZCgpXCIgKGNsaWNrKT1cImdvVG9SZXZpZXcoKVwiPlJldmlld1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCb29raW5nPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInN0ZXAgPT09ICdyZXZpZXcnXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy02MCBwYXltZW50X3NlY3Rpb25cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy0xMDAgaC0xMDBcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctMTAwIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyIGFsaWduLWl0ZW1zLWNlbnRlciBmbGV4LWNvbHVtblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBheW1lbnQtaGVhZGVyIG1iLTMgdy0xMDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDEgc3R5bGU9XCJmb250LXNpemU6MjRweDtmb250LXdlaWdodDogNjAwO1wiPkJvb2tpbmcgU3VtbWFyeTwvaDE+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJwYXltZW50LXN1YnRpdGxlIG1iLTBcIj5SZXZpZXcgeW91ciBib29raW5nIGJlZm9yZSBjb25maXJtaW5nPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJib29raW5nLXN1bW1hcnktY2FyZFwiIFtuZ0NsYXNzXT1cInsndy0xMDAnIDogc2NyZWVuV2lkdGggPCA0NzUsJ3ctNTAnOnNjcmVlbldpZHRoID4gNDc1fVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1sYWJlbFwiPkRhdGUgJiBUaW1lPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+e3tzZWxlY3RlZERhdGVTdHJ9fSBhdCB7e3NlbGVjdGVkU2xvdD8udmFsdWUgPz8gJ04vQSd9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInByb2R1Y3RDYXJ0SXRlbXMubGVuZ3RoID4gMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDIgY2xhc3M9XCJzdW1tYXJ5LXRpdGxlXCI+UHJvZHVjdHM8L2gyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1yb3dcIiAqbmdGb3I9XCJsZXQgcCBvZiBwcm9kdWN0Q2FydEl0ZW1zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1sYWJlbFwiPnt7cC5pdGVtTmFtZX19IHh7e3AucXVhbnRpdHl9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj48c3BhbiBjbGFzcz1cImN1cnJlbmN5LXN5bWJvbFwiPuKCuTwvc3Bhbj57eyhwLnNlbGxpbmdQcmljZSA/PyBwLnByaWNlID8/IDApICogKHAucXVhbnRpdHkgPz8gMSl9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic3RlcCA9PT0gJ2RvbmUnXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm9va2luZy1jb25maXJtYXRpb25cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VjY2Vzcy1pY29uXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjaGVja21hcmstY2lyY2xlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cImh0dHBzOi8vZDJ6OTQ5N3hwOHhiMTIuY2xvdWRmcm9udC5uZXQvcHJvZC1pbWFnZXMvODgxMjkzYzE3NTg2OTU1Nzg1MThzdWNjZXNzLmdpZlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ3LTEwMCBoLTEwMFwiICpuZ0lmPVwiYXBpU3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cImh0dHBzOi8vZDJ6OTQ5N3hwOHhiMTIuY2xvdWRmcm9udC5uZXQvcHJvZC1pbWFnZXMvMzI1MDAwYzE3NTg2OTU1NjQ1MThmYWlsLmdpZlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ3LTEwMCBoLTEwMFwiICpuZ0lmPVwiIWFwaVN0YXR1c1wiPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25maXJtYXRpb24tY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICA8aDEgY2xhc3M9XCJjb25maXJtYXRpb24tdGl0bGVcIj57e2FwaVN0YXR1cyA/ICdCb29raW5nIENvbmZpcm1lZCEnIDogJ0Jvb2tpbmcgRmFpbGVkJ319PC9oMT5cbiAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJjb25maXJtYXRpb24tbWVzc2FnZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3thcGlTdGF0dXMgPyAnWW91ciBhcHBvaW50bWVudCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYm9va2VkLic6J0ZhaWxlZCB0byBib29rIHlvdXIgYXBwb2ludG1lbnQuIFBsZWFzZVxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IGFnYWluIGxhdGVyJ319XG4gICAgICAgICAgICAgICAgICAgIDwvcD5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidmlkZW8tY2FsbC1saW5rLWNhcmQgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCIgKm5nSWY9XCJhcGlTdGF0dXMgJiYgbW9kZSA9PT0gJ1ZJREVPX0NBTEwnICYmIGJvb2tpbmdHcm91cD8udmlkZW9DYWxsTGlua1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbHMtY2FyZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cImRldGFpbHMtdGl0bGVcIj5Zb3VyIFZpZGVvIENhbGwgTGluazwvaDM+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgW2hyZWZdPVwiYm9va2luZ0dyb3VwLnZpZGVvQ2FsbExpbmtcIiB0YXJnZXQ9XCJfYmxhbmtcIj57e2Jvb2tpbmdHcm91cC52aWRlb0NhbGxMaW5rfX08L2E+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCB3LTEwMCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiICpuZ0lmPVwiYXBpU3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlscy1jYXJkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwiZGV0YWlscy10aXRsZVwiPkFwcG9pbnRtZW50IERldGFpbHM8L2gzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWxzLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPnt7cHJvZHVjdENhcnRJdGVtcy5sZW5ndGggPyAnUHJvZHVjdHMnIDogKG1vZGUgPT09ICdIT01FX1ZJU0lUJyA/ICdIb21lIFZpc2l0JyA6ICdWaWRlbyBDYWxsJyl9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtdmFsdWVcIj57e3NlbGVjdGVkRGF0ZVN0cn19IGF0IHt7c2VsZWN0ZWRTbG90Py52YWx1ZSA/PyAnTi9BJ319PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cIm1haW5fZm9vdGVyIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyIGFsaWduLWl0ZW1zLWNlbnRlclwiICpuZ0lmPVwic3RlcCA9PT0gJ3JldmlldydcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZvb3Rlci1idXR0b25zXCIgc3R5bGU9XCJqdXN0aWZ5LWNvbnRlbnQ6c3BhY2UtYmV0d2VlblwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJiYWNrLWZvb3Rlci1idG4gY3Vyc29yLXBvaW50ZXJcIiAoY2xpY2spPVwiYmFja1RvRm9ybSgpXCI+QmFjazwvc3Bhbj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBkLWZsZXgganVzdGlmeS1jb250ZW50LWV2ZW5seSBhbGlnbi1pdGVtcy1jZW50ZXJcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJjb25maXJtQm9va2luZygpXCIgW2Rpc2FibGVkXT1cImlzUHJvY2Vzc2luZ1wiXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydwYXktbm93LWJ0bicgOiBib29raW5nR3JvdXA/LnRvdGFsQ29sbGVjdGVkQXRCb29raW5nID4gMCB8fCAhYm9va2luZ0dyb3VwLCdjb21wbGV0ZV9ib29raW5nJyA6IGJvb2tpbmdHcm91cCAmJiAhYm9va2luZ0dyb3VwPy50b3RhbENvbGxlY3RlZEF0Qm9va2luZ31cIj5cbiAgICAgICAgICAgICAgICA8aW1nIHNyYz1cImh0dHBzOi8vZDJ6OTQ5N3hwOHhiMTIuY2xvdWRmcm9udC5uZXQvcHJvZC1pbWFnZXMvMzA0MDEyYzE3NTM0NDAwODc5OTZCYWNrZ3JvdW5kLnBuZ1wiPlxuICAgICAgICAgICAgICAgIHt7aXNQcm9jZXNzaW5nID8gJ1BsZWFzZSB3YWl0Li4uJyA6ICdDb25maXJtIEJvb2tpbmcnfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvc2VjdGlvbj5cbiJdfQ==
|