@almatar/smart-booking-dashboard 0.0.2-alpha.2 → 0.0.2-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/esm2022/lib/components/almatar-aside/aside.component.mjs +6 -7
  2. package/esm2022/lib/components/hotel-cancel/almatar-hotel-auto-cancellation.component.mjs +2 -2
  3. package/esm2022/lib/components/hotel-cancel/components/almatar-hotel-auto-cancellation-select-rooms/components/almatar-hotel-auto-cancellation-non-refundable-room/almatar-hotel-auto-cancellation-non-refundable-room.component.mjs +2 -2
  4. package/esm2022/lib/components/hotel-cancel/services/almatar-hotel-auto-cancellation-endpoints.service.mjs +13 -4
  5. package/esm2022/lib/components/reissue-dialog/reissue-dialog.component.mjs +135 -0
  6. package/esm2022/lib/components/reissue-dialog/reissue-upgrade.store.mjs +305 -0
  7. package/esm2022/lib/components/reissue-dialog/reissue.store.mjs +349 -0
  8. package/esm2022/lib/components/reissue-dialog/steps/reissue-date-step/reissue-date-step.component.mjs +45 -0
  9. package/esm2022/lib/components/reissue-dialog/steps/reissue-legs-step/reissue-legs-step.component.mjs +140 -0
  10. package/esm2022/lib/components/reissue-dialog/steps/reissue-notice/reissue-notice.component.mjs +16 -0
  11. package/esm2022/lib/components/reissue-dialog/steps/reissue-route-step/reissue-route-step.component.mjs +104 -0
  12. package/esm2022/lib/components/reissue-dialog/steps/reissue-service-step/reissue-service-step.component.mjs +44 -0
  13. package/esm2022/lib/components/reissue-dialog/steps/reissue-upgrade-confirm-step/reissue-upgrade-confirm-step.component.mjs +193 -0
  14. package/esm2022/lib/components/reissue-dialog/steps/reissue-upgrade-step/reissue-upgrade-step.component.mjs +88 -0
  15. package/esm2022/lib/components/workflow-actions/workflow-actions.component.mjs +5 -3
  16. package/esm2022/lib/config/dashboard.config.mjs +3 -1
  17. package/esm2022/lib/models/reissue.types.mjs +2 -0
  18. package/esm2022/lib/pages/smart-booking-dashboard/smart-booking-dashboard.component.mjs +9 -3
  19. package/esm2022/lib/services/reissue.service.mjs +142 -0
  20. package/esm2022/lib/services/toast.service.mjs +15 -7
  21. package/esm2022/lib/utils/reissue-format.mjs +64 -0
  22. package/esm2022/lib/utils/reissue-url.builder.mjs +314 -0
  23. package/esm2022/public-api.mjs +3 -1
  24. package/fesm2022/almatar-smart-booking-dashboard.mjs +1919 -25
  25. package/fesm2022/almatar-smart-booking-dashboard.mjs.map +1 -1
  26. package/lib/components/action-dialog/action-dialog.component.d.ts +1 -1
  27. package/lib/components/almatar-aside/aside.component.d.ts +1 -2
  28. package/lib/components/hotel-cancel/components/hotel-content/hotel-content.component.d.ts +1 -1
  29. package/lib/components/hotel-cancel/services/almatar-hotel-auto-cancellation-endpoints.service.d.ts +6 -0
  30. package/lib/components/reissue-dialog/reissue-dialog.component.d.ts +34 -0
  31. package/lib/components/reissue-dialog/reissue-upgrade.store.d.ts +96 -0
  32. package/lib/components/reissue-dialog/reissue.store.d.ts +124 -0
  33. package/lib/components/reissue-dialog/steps/reissue-date-step/reissue-date-step.component.d.ts +11 -0
  34. package/lib/components/reissue-dialog/steps/reissue-legs-step/reissue-legs-step.component.d.ts +16 -0
  35. package/lib/components/reissue-dialog/steps/reissue-notice/reissue-notice.component.d.ts +8 -0
  36. package/lib/components/reissue-dialog/steps/reissue-route-step/reissue-route-step.component.d.ts +21 -0
  37. package/lib/components/reissue-dialog/steps/reissue-service-step/reissue-service-step.component.d.ts +17 -0
  38. package/lib/components/reissue-dialog/steps/reissue-upgrade-confirm-step/reissue-upgrade-confirm-step.component.d.ts +28 -0
  39. package/lib/components/reissue-dialog/steps/reissue-upgrade-step/reissue-upgrade-step.component.d.ts +13 -0
  40. package/lib/components/result-panel/result-panel.component.d.ts +1 -1
  41. package/lib/components/workflow-actions/workflow-actions.component.d.ts +3 -1
  42. package/lib/config/dashboard.config.d.ts +29 -0
  43. package/lib/models/reissue.types.d.ts +147 -0
  44. package/lib/pages/smart-booking-dashboard/smart-booking-dashboard.component.d.ts +4 -1
  45. package/lib/services/reissue.service.d.ts +45 -0
  46. package/lib/services/toast.service.d.ts +14 -1
  47. package/lib/utils/reissue-format.d.ts +28 -0
  48. package/lib/utils/reissue-url.builder.d.ts +24 -0
  49. package/package.json +9 -7
  50. package/public-api.d.ts +5 -1
@@ -0,0 +1,135 @@
1
+ import { ChangeDetectionStrategy, Component, Injector, computed, effect, inject, input, output, runInInjectionContext, untracked, } from '@angular/core';
2
+ import { firstValueFrom, isObservable } from 'rxjs';
3
+ import { DialogModule } from 'primeng/dialog';
4
+ import { ButtonModule } from 'primeng/button';
5
+ import { SBD_CONFIG } from '../../config/dashboard.config';
6
+ import { appendAuthParams } from '../../utils/reissue-url.builder';
7
+ import { SbdReissueStore } from './reissue.store';
8
+ import { SbdReissueUpgradeStore } from './reissue-upgrade.store';
9
+ import { SbdReissueUpgradeStepComponent } from './steps/reissue-upgrade-step/reissue-upgrade-step.component';
10
+ import { SbdReissueUpgradeConfirmStepComponent } from './steps/reissue-upgrade-confirm-step/reissue-upgrade-confirm-step.component';
11
+ import { SbdReissueNoticeComponent } from './steps/reissue-notice/reissue-notice.component';
12
+ import { SbdReissueServiceStepComponent } from './steps/reissue-service-step/reissue-service-step.component';
13
+ import { SbdReissueLegsStepComponent } from './steps/reissue-legs-step/reissue-legs-step.component';
14
+ import { SbdReissueDateStepComponent } from './steps/reissue-date-step/reissue-date-step.component';
15
+ import { SbdReissueRouteStepComponent } from './steps/reissue-route-step/reissue-route-step.component';
16
+ import * as i0 from "@angular/core";
17
+ import * as i1 from "primeng/dialog";
18
+ import * as i2 from "primeng/button";
19
+ /**
20
+ * Reissue dialog shell: owns the p-dialog, the loading / error states and the footer, and swaps the step
21
+ * components. All state and rules live in `SbdReissueStore`; the steps only render and emit.
22
+ */
23
+ export class SbdReissueDialogComponent {
24
+ constructor() {
25
+ this.store = inject(SbdReissueStore);
26
+ this.upgrade = inject(SbdReissueUpgradeStore);
27
+ this.config = inject(SBD_CONFIG);
28
+ this.injector = inject(Injector);
29
+ this.visible = input(false);
30
+ this.bookingId = input('');
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ this.bookingData = input(null);
33
+ this.closed = output();
34
+ /** Header title per screen, like the cancel dialog's "Select Leg to Cancel" / "Refund Method". */
35
+ this.title = computed(() => {
36
+ switch (this.store.step()) {
37
+ case 'legs': return 'Select Flight to Change';
38
+ case 'edit': return this.store.service() === 'change_date' ? 'Choose New Date' : 'Choose New Route';
39
+ case 'upgrade-legs': return 'Select Flight to Upgrade';
40
+ case 'upgrade': return 'Choose New Class';
41
+ case 'confirm': return 'Review Upgrade';
42
+ default: return 'Reissue Booking';
43
+ }
44
+ });
45
+ /** Gray hint above the footer (cancel's "Select at least one flight to continue"), or why Search is disabled. */
46
+ this.hint = computed(() => {
47
+ switch (this.store.step()) {
48
+ case 'legs':
49
+ return this.store.anyAvailable() && !this.store.canContinue() ? 'Select at least one flight to continue' : null;
50
+ case 'edit':
51
+ return this.store.validationError();
52
+ case 'upgrade-legs':
53
+ return this.upgrade.anyLegUpgradable() && !this.upgrade.canContinueFromLegs() && !this.upgrade.submitting()
54
+ ? 'Select at least one flight to continue'
55
+ : null;
56
+ case 'upgrade':
57
+ return this.upgrade.sections().some(s => s.options.length) && !this.upgrade.canContinue() && !this.upgrade.submitting()
58
+ ? 'Select a class to continue'
59
+ : null;
60
+ default:
61
+ return null;
62
+ }
63
+ });
64
+ // Depends only on these three inputs; whatever the store reads while opening must not retrigger it.
65
+ effect(() => {
66
+ const [visible, data, id] = [this.visible(), this.bookingData(), this.bookingId()];
67
+ if (visible)
68
+ untracked(() => this.store.open(data, id));
69
+ }, { allowSignalWrites: true });
70
+ }
71
+ onServiceChosen(service) {
72
+ if (service === 'upgrade_class')
73
+ this.upgrade.start();
74
+ else
75
+ this.store.chooseService(service);
76
+ }
77
+ /** Back from the options returns to "select leg" only when that step was shown (the upgrade store knows). */
78
+ onBack() {
79
+ if (this.store.step() === 'upgrade')
80
+ this.upgrade.back();
81
+ else
82
+ this.store.back();
83
+ }
84
+ /** The payment link expired: redo the whole reissue from the start (a new post-booking, the service list again). */
85
+ restartFlow() {
86
+ this.store.open(this.bookingData(), this.bookingId());
87
+ }
88
+ /** Redirects to the web search (new tab: the agent keeps the dashboard open next to the web flow). */
89
+ async searchFlights() {
90
+ const url = this.store.searchUrl();
91
+ if (!url)
92
+ return;
93
+ // Open the tab now, inside the click, so the browser does not block it while the host's token is awaited.
94
+ const tab = window.open('about:blank', '_blank');
95
+ const finalUrl = appendAuthParams(url, await this.redirectAuthParams(), this.config.redirectAuthIn);
96
+ if (tab) {
97
+ tab.opener = null; // same protection as `noopener`
98
+ tab.location.href = finalUrl;
99
+ }
100
+ else {
101
+ window.open(finalUrl, '_blank', 'noopener');
102
+ }
103
+ this.closed.emit();
104
+ }
105
+ /** The host's auth parameters for the web link; `{}` when it has none or it fails (the web then asks to log in). */
106
+ async redirectAuthParams() {
107
+ const provide = this.config.redirectAuthParams;
108
+ if (!provide)
109
+ return {};
110
+ try {
111
+ const result = runInInjectionContext(this.injector, provide);
112
+ return (isObservable(result) ? await firstValueFrom(result) : await result) ?? {};
113
+ }
114
+ catch {
115
+ return {};
116
+ }
117
+ }
118
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdReissueDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
119
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SbdReissueDialogComponent, isStandalone: true, selector: "app-sbd-reissue-dialog", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, bookingId: { classPropertyName: "bookingId", publicName: "bookingId", isSignal: true, isRequired: false, transformFunction: null }, bookingData: { classPropertyName: "bookingData", publicName: "bookingData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, providers: [SbdReissueStore, SbdReissueUpgradeStore], ngImport: i0, template: "<p-dialog [visible]=\"visible()\" (visibleChange)=\"$event ? null : closed.emit()\"\n [modal]=\"true\" [blockScroll]=\"true\" [draggable]=\"false\" [resizable]=\"false\"\n [showHeader]=\"false\" [style]=\"{ width: '560px', padding: '0' }\" styleClass=\"sbd-reissue-dialog-wrapper\">\n\n <div class=\"sbd-reissue\">\n\n <!-- Header: same layout as the cancel dialog (round close button, centered title + booking id) -->\n <div class=\"sbd-reissue__header\">\n <button type=\"button\" class=\"sbd-reissue__close\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-reissue__header-text\">\n <h3 class=\"sbd-reissue__title\">{{ title() }}</h3>\n <span class=\"sbd-reissue__sub\">Booking ID #{{ bookingId() }}</span>\n </div>\n </div>\n\n @if (store.loading()) {\n <div class=\"sbd-reissue__state\">\n <div class=\"sbd-reissue__state-icon\"><i class=\"pi pi-spin pi-spinner\"></i></div>\n <div class=\"sbd-reissue__state-text\">Checking availability\u2026</div>\n <div class=\"sbd-reissue__dots\"><span></span><span></span><span></span></div>\n </div>\n } @else if (store.error()) {\n <div class=\"sbd-reissue__state\">\n <div class=\"sbd-reissue__state-icon sbd-reissue__state-icon--warn\"><i class=\"pi pi-exclamation-triangle\"></i></div>\n <div class=\"sbd-reissue__state-text\">{{ store.error() }}</div>\n <button pButton type=\"button\" label=\"Retry\" class=\"p-button-outlined p-button-secondary\" (click)=\"store.load()\"></button>\n </div>\n } @else if (store.blocked()) {\n <!-- No leg can be reissued online: same idea as the cancel dialog's \"not eligible, escalate\" notice. -->\n <div class=\"sbd-reissue__body\">\n <app-sbd-reissue-notice tone=\"warn\" icon=\"pi pi-exclamation-triangle\">\n <strong>{{ store.blocked()?.title }}</strong><br>{{ store.blocked()?.text }}\n </app-sbd-reissue-notice>\n </div>\n <div class=\"sbd-reissue__footer\">\n <button pButton type=\"button\" label=\"Close\" class=\"p-button-outlined p-button-secondary sbd-reissue__btn\"\n (click)=\"closed.emit()\"></button>\n </div>\n } @else {\n <div class=\"sbd-reissue__body\">\n @switch (store.step()) {\n @case ('service') {\n <app-sbd-reissue-notice>Change requests are subject to availability from the airline.</app-sbd-reissue-notice>\n <app-sbd-reissue-service-step\n [upgradeAvailable]=\"store.upgradeAvailable()\"\n (chosen)=\"onServiceChosen($event)\" />\n }\n @case ('legs') {\n <app-sbd-reissue-legs-step\n [rows]=\"store.legRows()\"\n [anyAvailable]=\"store.anyAvailable()\"\n (toggled)=\"store.toggleLeg($event)\" />\n }\n @case ('edit') {\n @if (store.service() === 'change_date') {\n <app-sbd-reissue-date-step\n [rows]=\"store.dateRows()\"\n (changed)=\"store.setDate($event.legId, $event.date)\" />\n } @else {\n <app-sbd-reissue-route-step\n [rows]=\"store.routeRows()\"\n [options]=\"store.airportOptions()\"\n (airportChanged)=\"store.setAirport($event.legId, $event.side, $event.airport)\"\n (searched)=\"store.searchAirports($event)\"\n (swapped)=\"store.swapAirports($event)\" />\n }\n }\n @case ('upgrade-legs') {\n <app-sbd-reissue-legs-step\n unavailableText=\"None of these flights can be upgraded online. Handle this booking manually.\"\n [rows]=\"upgrade.legRows()\"\n [anyAvailable]=\"upgrade.anyLegUpgradable()\"\n [note]=\"store.allowSingleLegSelection() ? null : 'These flights must be upgraded together.'\"\n [error]=\"upgrade.error()\"\n (toggled)=\"upgrade.toggleLeg($event)\" />\n }\n @case ('upgrade') {\n <app-sbd-reissue-upgrade-step\n [sections]=\"upgrade.sections()\"\n [error]=\"upgrade.error()\"\n (picked)=\"upgrade.select($event.sectionId, $event.key)\" />\n }\n @case ('confirm') {\n <app-sbd-reissue-upgrade-confirm-step\n [rows]=\"upgrade.summary()\"\n [total]=\"upgrade.total()\"\n [totalLabel]=\"upgrade.totalLabel()\"\n [priceChanged]=\"upgrade.priceChanged()\"\n [booked]=\"upgrade.booked()\"\n [link]=\"upgrade.paymentLink()\"\n [error]=\"upgrade.error()\"\n (restart)=\"restartFlow()\" />\n }\n }\n </div>\n\n @if (hint(); as text) {\n <div class=\"sbd-reissue__hint\">{{ text }}</div>\n }\n\n @if (store.step() !== 'service') {\n <div class=\"sbd-reissue__footer\">\n <button pButton type=\"button\" label=\"Back\" class=\"p-button-outlined p-button-secondary sbd-reissue__btn\"\n [disabled]=\"store.step() === 'confirm' && upgrade.locked()\" (click)=\"onBack()\"></button>\n\n @switch (store.step()) {\n @case ('legs') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\"\n [disabled]=\"!store.canContinue()\" (click)=\"store.goToEdit()\"></button>\n }\n @case ('edit') {\n <button pButton type=\"button\" icon=\"pi pi-search\" label=\"Search flights\" class=\"sbd-reissue__btn\"\n [disabled]=\"!!store.validationError()\" (click)=\"searchFlights()\"></button>\n }\n @case ('upgrade-legs') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\" [loading]=\"upgrade.submitting()\"\n [disabled]=\"!upgrade.canContinueFromLegs()\" (click)=\"upgrade.continueFromLegs()\"></button>\n }\n @case ('upgrade') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\" [loading]=\"upgrade.submitting()\"\n [disabled]=\"!upgrade.canContinue()\" (click)=\"upgrade.continue()\"></button>\n }\n @case ('confirm') {\n @switch (upgrade.action()) {\n @case ('done') {\n <button pButton type=\"button\" label=\"Close\" class=\"sbd-reissue__btn\" (click)=\"closed.emit()\"></button>\n }\n @case ('book') {\n <button pButton type=\"button\" label=\"Confirm upgrade\" class=\"sbd-reissue__btn\"\n [loading]=\"upgrade.submitting()\" (click)=\"upgrade.confirm()\"></button>\n }\n @case ('link') {\n <button pButton type=\"button\" icon=\"pi pi-link\" label=\"Generate payment link\" class=\"sbd-reissue__btn\"\n [loading]=\"upgrade.submitting()\" (click)=\"upgrade.confirm()\"></button>\n }\n }\n }\n }\n </div>\n }\n }\n </div>\n</p-dialog>\n", styles: [":host ::ng-deep .sbd-reissue-dialog-wrapper{border-radius:16px;box-shadow:0 24px 60px #0f172a38}:host ::ng-deep .sbd-reissue-dialog-wrapper .p-dialog-content{padding:0;border-radius:16px;overflow:visible}.sbd-reissue{font-family:inherit;position:relative}.sbd-reissue__header{display:flex;align-items:flex-start;gap:12px;padding:20px 20px 0}.sbd-reissue__close{flex-shrink:0;width:32px;height:32px;border-radius:50%;background:#f8fafc;border:none;color:#1e2e4a;display:flex;align-items:center;justify-content:center;cursor:pointer}.sbd-reissue__close .pi{font-size:13px}.sbd-reissue__close:hover{background:#e2e8f0}.sbd-reissue__header-text{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;text-align:center;margin-right:32px}.sbd-reissue__title{font-size:19px;font-weight:800;color:#1e2e4a;margin:0}.sbd-reissue__sub{font-size:12.5px;color:#94a3b8}.sbd-reissue__body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:12px}.sbd-reissue__hint{text-align:center;padding:0 20px 12px;font-size:13px;color:#94a3b8}.sbd-reissue__footer{display:flex;justify-content:flex-end;gap:10px;align-items:stretch;padding:14px 20px;border-top:1px solid #e2e8f0;background:#fff;border-radius:0 0 16px 16px}.sbd-reissue__btn{flex:1 1 0;justify-content:center}.sbd-reissue__state{padding:36px 24px 28px;display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center}.sbd-reissue__state-icon{width:56px;height:56px;border-radius:50%;background:#fff7ed;border:2px solid #fed7aa;display:flex;align-items:center;justify-content:center}.sbd-reissue__state-icon .pi{font-size:24px;color:#f97316}.sbd-reissue__state-icon--warn{background:#fef2f2;border-color:#fecaca}.sbd-reissue__state-icon--warn .pi{color:#ef4444}.sbd-reissue__state-text{font-size:13px;color:#64748b;min-height:20px}.sbd-reissue__dots{display:flex;gap:6px}.sbd-reissue__dots span{width:7px;height:7px;border-radius:50%;background:#f97316;opacity:.3;animation:sbd-reissue-dot 1.2s ease-in-out infinite}.sbd-reissue__dots span:nth-child(2){animation-delay:.2s}.sbd-reissue__dots span:nth-child(3){animation-delay:.4s}@keyframes sbd-reissue-dot{0%,to{opacity:.3;transform:scale(1)}50%{opacity:1;transform:scale(1.4)}}\n"], dependencies: [{ kind: "ngmodule", type: DialogModule }, { kind: "component", type: i1.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { kind: "component", type: SbdReissueNoticeComponent, selector: "app-sbd-reissue-notice", inputs: ["icon", "tone"] }, { kind: "component", type: SbdReissueServiceStepComponent, selector: "app-sbd-reissue-service-step", inputs: ["upgradeAvailable"], outputs: ["chosen"] }, { kind: "component", type: SbdReissueLegsStepComponent, selector: "app-sbd-reissue-legs-step", inputs: ["rows", "anyAvailable", "unavailableText", "note", "error"], outputs: ["toggled"] }, { kind: "component", type: SbdReissueDateStepComponent, selector: "app-sbd-reissue-date-step", inputs: ["rows"], outputs: ["changed"] }, { kind: "component", type: SbdReissueRouteStepComponent, selector: "app-sbd-reissue-route-step", inputs: ["rows", "options"], outputs: ["airportChanged", "searched", "swapped"] }, { kind: "component", type: SbdReissueUpgradeStepComponent, selector: "app-sbd-reissue-upgrade-step", inputs: ["sections", "error"], outputs: ["picked"] }, { kind: "component", type: SbdReissueUpgradeConfirmStepComponent, selector: "app-sbd-reissue-upgrade-confirm-step", inputs: ["rows", "total", "totalLabel", "priceChanged", "booked", "link", "error"], outputs: ["restart"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
120
+ }
121
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdReissueDialogComponent, decorators: [{
122
+ type: Component,
123
+ args: [{ selector: 'app-sbd-reissue-dialog', standalone: true, imports: [
124
+ DialogModule,
125
+ ButtonModule,
126
+ SbdReissueNoticeComponent,
127
+ SbdReissueServiceStepComponent,
128
+ SbdReissueLegsStepComponent,
129
+ SbdReissueDateStepComponent,
130
+ SbdReissueRouteStepComponent,
131
+ SbdReissueUpgradeStepComponent,
132
+ SbdReissueUpgradeConfirmStepComponent,
133
+ ], providers: [SbdReissueStore, SbdReissueUpgradeStore], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-dialog [visible]=\"visible()\" (visibleChange)=\"$event ? null : closed.emit()\"\n [modal]=\"true\" [blockScroll]=\"true\" [draggable]=\"false\" [resizable]=\"false\"\n [showHeader]=\"false\" [style]=\"{ width: '560px', padding: '0' }\" styleClass=\"sbd-reissue-dialog-wrapper\">\n\n <div class=\"sbd-reissue\">\n\n <!-- Header: same layout as the cancel dialog (round close button, centered title + booking id) -->\n <div class=\"sbd-reissue__header\">\n <button type=\"button\" class=\"sbd-reissue__close\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-reissue__header-text\">\n <h3 class=\"sbd-reissue__title\">{{ title() }}</h3>\n <span class=\"sbd-reissue__sub\">Booking ID #{{ bookingId() }}</span>\n </div>\n </div>\n\n @if (store.loading()) {\n <div class=\"sbd-reissue__state\">\n <div class=\"sbd-reissue__state-icon\"><i class=\"pi pi-spin pi-spinner\"></i></div>\n <div class=\"sbd-reissue__state-text\">Checking availability\u2026</div>\n <div class=\"sbd-reissue__dots\"><span></span><span></span><span></span></div>\n </div>\n } @else if (store.error()) {\n <div class=\"sbd-reissue__state\">\n <div class=\"sbd-reissue__state-icon sbd-reissue__state-icon--warn\"><i class=\"pi pi-exclamation-triangle\"></i></div>\n <div class=\"sbd-reissue__state-text\">{{ store.error() }}</div>\n <button pButton type=\"button\" label=\"Retry\" class=\"p-button-outlined p-button-secondary\" (click)=\"store.load()\"></button>\n </div>\n } @else if (store.blocked()) {\n <!-- No leg can be reissued online: same idea as the cancel dialog's \"not eligible, escalate\" notice. -->\n <div class=\"sbd-reissue__body\">\n <app-sbd-reissue-notice tone=\"warn\" icon=\"pi pi-exclamation-triangle\">\n <strong>{{ store.blocked()?.title }}</strong><br>{{ store.blocked()?.text }}\n </app-sbd-reissue-notice>\n </div>\n <div class=\"sbd-reissue__footer\">\n <button pButton type=\"button\" label=\"Close\" class=\"p-button-outlined p-button-secondary sbd-reissue__btn\"\n (click)=\"closed.emit()\"></button>\n </div>\n } @else {\n <div class=\"sbd-reissue__body\">\n @switch (store.step()) {\n @case ('service') {\n <app-sbd-reissue-notice>Change requests are subject to availability from the airline.</app-sbd-reissue-notice>\n <app-sbd-reissue-service-step\n [upgradeAvailable]=\"store.upgradeAvailable()\"\n (chosen)=\"onServiceChosen($event)\" />\n }\n @case ('legs') {\n <app-sbd-reissue-legs-step\n [rows]=\"store.legRows()\"\n [anyAvailable]=\"store.anyAvailable()\"\n (toggled)=\"store.toggleLeg($event)\" />\n }\n @case ('edit') {\n @if (store.service() === 'change_date') {\n <app-sbd-reissue-date-step\n [rows]=\"store.dateRows()\"\n (changed)=\"store.setDate($event.legId, $event.date)\" />\n } @else {\n <app-sbd-reissue-route-step\n [rows]=\"store.routeRows()\"\n [options]=\"store.airportOptions()\"\n (airportChanged)=\"store.setAirport($event.legId, $event.side, $event.airport)\"\n (searched)=\"store.searchAirports($event)\"\n (swapped)=\"store.swapAirports($event)\" />\n }\n }\n @case ('upgrade-legs') {\n <app-sbd-reissue-legs-step\n unavailableText=\"None of these flights can be upgraded online. Handle this booking manually.\"\n [rows]=\"upgrade.legRows()\"\n [anyAvailable]=\"upgrade.anyLegUpgradable()\"\n [note]=\"store.allowSingleLegSelection() ? null : 'These flights must be upgraded together.'\"\n [error]=\"upgrade.error()\"\n (toggled)=\"upgrade.toggleLeg($event)\" />\n }\n @case ('upgrade') {\n <app-sbd-reissue-upgrade-step\n [sections]=\"upgrade.sections()\"\n [error]=\"upgrade.error()\"\n (picked)=\"upgrade.select($event.sectionId, $event.key)\" />\n }\n @case ('confirm') {\n <app-sbd-reissue-upgrade-confirm-step\n [rows]=\"upgrade.summary()\"\n [total]=\"upgrade.total()\"\n [totalLabel]=\"upgrade.totalLabel()\"\n [priceChanged]=\"upgrade.priceChanged()\"\n [booked]=\"upgrade.booked()\"\n [link]=\"upgrade.paymentLink()\"\n [error]=\"upgrade.error()\"\n (restart)=\"restartFlow()\" />\n }\n }\n </div>\n\n @if (hint(); as text) {\n <div class=\"sbd-reissue__hint\">{{ text }}</div>\n }\n\n @if (store.step() !== 'service') {\n <div class=\"sbd-reissue__footer\">\n <button pButton type=\"button\" label=\"Back\" class=\"p-button-outlined p-button-secondary sbd-reissue__btn\"\n [disabled]=\"store.step() === 'confirm' && upgrade.locked()\" (click)=\"onBack()\"></button>\n\n @switch (store.step()) {\n @case ('legs') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\"\n [disabled]=\"!store.canContinue()\" (click)=\"store.goToEdit()\"></button>\n }\n @case ('edit') {\n <button pButton type=\"button\" icon=\"pi pi-search\" label=\"Search flights\" class=\"sbd-reissue__btn\"\n [disabled]=\"!!store.validationError()\" (click)=\"searchFlights()\"></button>\n }\n @case ('upgrade-legs') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\" [loading]=\"upgrade.submitting()\"\n [disabled]=\"!upgrade.canContinueFromLegs()\" (click)=\"upgrade.continueFromLegs()\"></button>\n }\n @case ('upgrade') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\" [loading]=\"upgrade.submitting()\"\n [disabled]=\"!upgrade.canContinue()\" (click)=\"upgrade.continue()\"></button>\n }\n @case ('confirm') {\n @switch (upgrade.action()) {\n @case ('done') {\n <button pButton type=\"button\" label=\"Close\" class=\"sbd-reissue__btn\" (click)=\"closed.emit()\"></button>\n }\n @case ('book') {\n <button pButton type=\"button\" label=\"Confirm upgrade\" class=\"sbd-reissue__btn\"\n [loading]=\"upgrade.submitting()\" (click)=\"upgrade.confirm()\"></button>\n }\n @case ('link') {\n <button pButton type=\"button\" icon=\"pi pi-link\" label=\"Generate payment link\" class=\"sbd-reissue__btn\"\n [loading]=\"upgrade.submitting()\" (click)=\"upgrade.confirm()\"></button>\n }\n }\n }\n }\n </div>\n }\n }\n </div>\n</p-dialog>\n", styles: [":host ::ng-deep .sbd-reissue-dialog-wrapper{border-radius:16px;box-shadow:0 24px 60px #0f172a38}:host ::ng-deep .sbd-reissue-dialog-wrapper .p-dialog-content{padding:0;border-radius:16px;overflow:visible}.sbd-reissue{font-family:inherit;position:relative}.sbd-reissue__header{display:flex;align-items:flex-start;gap:12px;padding:20px 20px 0}.sbd-reissue__close{flex-shrink:0;width:32px;height:32px;border-radius:50%;background:#f8fafc;border:none;color:#1e2e4a;display:flex;align-items:center;justify-content:center;cursor:pointer}.sbd-reissue__close .pi{font-size:13px}.sbd-reissue__close:hover{background:#e2e8f0}.sbd-reissue__header-text{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;text-align:center;margin-right:32px}.sbd-reissue__title{font-size:19px;font-weight:800;color:#1e2e4a;margin:0}.sbd-reissue__sub{font-size:12.5px;color:#94a3b8}.sbd-reissue__body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:12px}.sbd-reissue__hint{text-align:center;padding:0 20px 12px;font-size:13px;color:#94a3b8}.sbd-reissue__footer{display:flex;justify-content:flex-end;gap:10px;align-items:stretch;padding:14px 20px;border-top:1px solid #e2e8f0;background:#fff;border-radius:0 0 16px 16px}.sbd-reissue__btn{flex:1 1 0;justify-content:center}.sbd-reissue__state{padding:36px 24px 28px;display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center}.sbd-reissue__state-icon{width:56px;height:56px;border-radius:50%;background:#fff7ed;border:2px solid #fed7aa;display:flex;align-items:center;justify-content:center}.sbd-reissue__state-icon .pi{font-size:24px;color:#f97316}.sbd-reissue__state-icon--warn{background:#fef2f2;border-color:#fecaca}.sbd-reissue__state-icon--warn .pi{color:#ef4444}.sbd-reissue__state-text{font-size:13px;color:#64748b;min-height:20px}.sbd-reissue__dots{display:flex;gap:6px}.sbd-reissue__dots span{width:7px;height:7px;border-radius:50%;background:#f97316;opacity:.3;animation:sbd-reissue-dot 1.2s ease-in-out infinite}.sbd-reissue__dots span:nth-child(2){animation-delay:.2s}.sbd-reissue__dots span:nth-child(3){animation-delay:.4s}@keyframes sbd-reissue-dot{0%,to{opacity:.3;transform:scale(1)}50%{opacity:1;transform:scale(1.4)}}\n"] }]
134
+ }], ctorParameters: () => [] });
135
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVpc3N1ZS1kaWFsb2cuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc21hcnQtYm9va2luZy1kYXNoYm9hcmQvc3JjL2xpYi9jb21wb25lbnRzL3JlaXNzdWUtZGlhbG9nL3JlaXNzdWUtZGlhbG9nLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LWJvb2tpbmctZGFzaGJvYXJkL3NyYy9saWIvY29tcG9uZW50cy9yZWlzc3VlLWRpYWxvZy9yZWlzc3VlLWRpYWxvZy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxRQUFRLEVBQ1IsUUFBUSxFQUNSLE1BQU0sRUFDTixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFDTixxQkFBcUIsRUFDckIsU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3BELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFOUMsT0FBTyxFQUFFLFVBQVUsRUFBeUIsTUFBTSwrQkFBK0IsQ0FBQztBQUNsRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVuRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDbEQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDakUsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sNkRBQTZELENBQUM7QUFDN0csT0FBTyxFQUFFLHFDQUFxQyxFQUFFLE1BQU0sNkVBQTZFLENBQUM7QUFDcEksT0FBTyxFQUFFLHlCQUF5QixFQUFF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QUM7SUFDSCxDQUFDOytHQWpHVSx5QkFBeUI7bUdBQXpCLHlCQUF5Qiw0ZkFMekIsQ0FBQyxlQUFlLEVBQUUsc0JBQXNCLENBQUMsMEJDL0N0RCx1bE9BaUpBLDB0RUQ1R0ksWUFBWSwwdEJBQ1osWUFBWSx1S0FDWix5QkFBeUIsNkZBQ3pCLDhCQUE4Qiw0SEFDOUIsMkJBQTJCLGtLQUMzQiwyQkFBMkIsOEdBQzNCLDRCQUE0Qix3SkFDNUIsOEJBQThCLDZIQUM5QixxQ0FBcUM7OzRGQU81Qix5QkFBeUI7a0JBbkJyQyxTQUFTOytCQUNFLHdCQUF3QixjQUN0QixJQUFJLFdBQ1A7d0JBQ1AsWUFBWTt3QkFDWixZQUFZO3dCQUNaLHlCQUF5Qjt3QkFDekIsOEJBQThCO3dCQUM5QiwyQkFBMkI7d0JBQzNCLDJCQUEyQjt3QkFDM0IsNEJBQTRCO3dCQUM1Qiw4QkFBOEI7d0JBQzlCLHFDQUFxQztxQkFDdEMsYUFDVSxDQUFDLGVBQWUsRUFBRSxzQkFBc0IsQ0FBQyxtQkFDbkMsdUJBQXVCLENBQUMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIEluamVjdG9yLFxuICBjb21wdXRlZCxcbiAgZWZmZWN0LFxuICBpbmplY3QsXG4gIGlucHV0LFxuICBvdXRwdXQsXG4gIHJ1bkluSW5qZWN0aW9uQ29udGV4dCxcbiAgdW50cmFja2VkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGZpcnN0VmFsdWVGcm9tLCBpc09ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IERpYWxvZ01vZHVsZSB9IGZyb20gJ3ByaW1lbmcvZGlhbG9nJztcbmltcG9ydCB7IEJ1dHRvbk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYnV0dG9uJztcblxuaW1wb3J0IHsgU0JEX0NPTkZJRywgU2JkUmVkaXJlY3RBdXRoUGFyYW1zIH0gZnJvbSAnLi4vLi4vY29uZmlnL2Rhc2hib2FyZC5jb25maWcnO1xuaW1wb3J0IHsgYXBwZW5kQXV0aFBhcmFtcyB9IGZyb20gJy4uLy4uL3V0aWxzL3JlaXNzdWUtdXJsLmJ1aWxkZXInO1xuaW1wb3J0IHsgUmVpc3N1ZVNlcnZpY2VLZXkgfSBmcm9tICcuLi8uLi9tb2RlbHMvcmVpc3N1ZS50eXBlcyc7XG5pbXBvcnQgeyBTYmRSZWlzc3VlU3RvcmUgfSBmcm9tICcuL3JlaXNzdWUuc3RvcmUnO1xuaW1wb3J0IHsgU2JkUmVpc3N1ZVVwZ3JhZGVTdG9yZSB9IGZyb20gJy4vcmVpc3N1ZS11cGdyYWRlLnN0b3JlJztcbmltcG9ydCB7IFNiZFJlaXNzdWVVcGdyYWRlU3RlcENvbXBvbmVudCB9IGZyb20gJy4vc3RlcHMvcmVpc3N1ZS11cGdyYWRlLXN0ZXAvcmVpc3N1ZS11cGdyYWRlLXN0ZXAuY29tcG9uZW50JztcbmltcG9ydCB7IFNiZFJlaXNzdWVVcGdyYWRlQ29uZmlybVN0ZXBDb21wb25lbnQgfSBmcm9tICcuL3N0ZXBzL3JlaXNzdWUtdXBncmFkZS1jb25maXJtLXN0ZXAvcmVpc3N1ZS11cGdyYWRlLWNvbmZpcm0tc3RlcC5jb21wb25lbnQnO1xuaW1wb3J0IHsgU2JkUmVpc3N1ZU5vdGljZUNvbXBvbmVudCB9IGZyb20gJy4vc3RlcHMvcmVpc3N1ZS1ub3RpY2UvcmVpc3N1ZS1ub3RpY2UuY29tcG9uZW50JztcbmltcG9ydCB7IFNiZFJlaXNzdWVTZXJ2aWNlU3RlcENvbXBvbmVudCB9IGZyb20gJy4vc3RlcHMvcmVpc3N1ZS1zZXJ2aWNlLXN0ZXAvcmVpc3N1ZS1zZXJ2aWNlLXN0ZXAuY29tcG9uZW50JztcbmltcG9ydCB7IFNiZFJlaXNzdWVMZWdzU3RlcENvbXBvbmVudCB9IGZyb20gJy4vc3RlcHMvcmVpc3N1ZS1sZWdzLXN0ZXAvcmVpc3N1ZS1sZWdzLXN0ZXAuY29tcG9uZW50JztcbmltcG9ydCB7IFNiZFJlaXNzdWVEYXRlU3RlcENvbXBvbmVudCB9IGZyb20gJy4vc3RlcHMvcmVpc3N1ZS1kYXRlLXN0ZXAvcmVpc3N1ZS1kYXRlLXN0ZXAuY29tcG9uZW50JztcbmltcG9ydCB7IFNiZFJlaXNzdWVSb3V0ZVN0ZXBDb21wb25lbnQgfSBmcm9tICcuL3N0ZXBzL3JlaXNzdWUtcm91dGUtc3RlcC9yZWlzc3VlLXJvdXRlLXN0ZXAuY29tcG9uZW50JztcblxuLyoqXG4gKiBSZWlzc3VlIGRpYWxvZyBzaGVsbDogb3ducyB0aGUgcC1kaWFsb2csIHRoZSBsb2FkaW5nIC8gZXJyb3Igc3RhdGVzIGFuZCB0aGUgZm9vdGVyLCBhbmQgc3dhcHMgdGhlIHN0ZXBcbiAqIGNvbXBvbmVudHMuIEFsbCBzdGF0ZSBhbmQgcnVsZXMgbGl2ZSBpbiBgU2JkUmVpc3N1ZVN0b3JlYDsgdGhlIHN0ZXBzIG9ubHkgcmVuZGVyIGFuZCBlbWl0LlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtc2JkLXJlaXNzdWUtZGlhbG9nJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIERpYWxvZ01vZHVsZSxcbiAgICBCdXR0b25Nb2R1bGUsXG4gICAgU2JkUmVpc3N1ZU5vdGljZUNvbXBvbmVudCxcbiAgICBTYmRSZWlzc3VlU2VydmljZVN0ZXBDb21wb25lbnQsXG4gICAgU2JkUmVpc3N1ZUxlZ3NTdGVwQ29tcG9uZW50LFxuICAgIFNiZFJlaXNzdWVEYXRlU3RlcENvbXBvbmVudCxcbiAgICBTYmRSZWlzc3VlUm91dGVTdGVwQ29tcG9uZW50LFxuICAgIFNiZFJlaXNzdWVVcGdyYWRlU3RlcENvbXBvbmVudCxcbiAgICBTYmRSZWlzc3VlVXBncmFkZUNvbmZpcm1TdGVwQ29tcG9uZW50LFxuICBdLFxuICBwcm92aWRlcnM6IFtTYmRSZWlzc3VlU3RvcmUsIFNiZFJlaXNzdWVVcGdyYWRlU3RvcmVdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgdGVtcGxhdGVVcmw6ICcuL3JlaXNzdWUtZGlhbG9nLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL3JlaXNzdWUtZGlhbG9nLmNvbXBvbmVudC5zY3NzJyxcbn0pXG5leHBvcnQgY2xhc3MgU2JkUmVpc3N1ZURpYWxvZ0NvbXBvbmVudCB7XG4gIHByb3RlY3RlZCByZWFkb25seSBzdG9yZSA9IGluamVjdChTYmRSZWlzc3VlU3RvcmUpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgdXBncmFkZSA9IGluamVjdChTYmRSZWlzc3VlVXBncmFkZVN0b3JlKTtcbiAgcHJpdmF0ZSByZWFkb25seSBjb25maWcgPSBpbmplY3QoU0JEX0NPTkZJRyk7XG4gIHByaXZhdGUgcmVhZG9ubHkgaW5qZWN0b3IgPSBpbmplY3QoSW5qZWN0b3IpO1xuXG4gIHZpc2libGUgPSBpbnB1dChmYWxzZSk7XG4gIGJvb2tpbmdJZCA9IGlucHV0KCcnKTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgYm9va2luZ0RhdGEgPSBpbnB1dDxhbnkgfCBudWxsPihudWxsKTtcbiAgY2xvc2VkID0gb3V0cHV0PHZvaWQ+KCk7XG5cbiAgLyoqIEhlYWRlciB0aXRsZSBwZXIgc2NyZWVuLCBsaWtlIHRoZSBjYW5jZWwgZGlhbG9nJ3MgXCJTZWxlY3QgTGVnIHRvIENhbmNlbFwiIC8gXCJSZWZ1bmQgTWV0aG9kXCIuICovXG4gIHByb3RlY3RlZCByZWFkb25seSB0aXRsZSA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBzd2l0Y2ggKHRoaXMuc3RvcmUuc3RlcCgpKSB7XG4gICAgICBjYXNlICdsZWdzJzogcmV0dXJuICdTZWxlY3QgRmxpZ2h0IHRvIENoYW5nZSc7XG4gICAgICBjYXNlICdlZGl0JzogcmV0dXJuIHRoaXMuc3RvcmUuc2VydmljZSgpID09PSAnY2hhbmdlX2RhdGUnID8gJ0Nob29zZSBOZXcgRGF0ZScgOiAnQ2hvb3NlIE5ldyBSb3V0ZSc7XG4gICAgICBjYXNlICd1cGdyYWRlLWxlZ3MnOiByZXR1cm4gJ1NlbGVjdCBGbGlnaHQgdG8gVXBncmFkZSc7XG4gICAgICBjYXNlICd1cGdyYWRlJzogcmV0dXJuICdDaG9vc2UgTmV3IENsYXNzJztcbiAgICAgIGNhc2UgJ2NvbmZpcm0nOiByZXR1cm4gJ1JldmlldyBVcGdyYWRlJztcbiAgICAgIGRlZmF1bHQ6IHJldHVybiAnUmVpc3N1ZSBCb29raW5nJztcbiAgICB9XG4gIH0pO1xuXG4gIC8qKiBHcmF5IGhpbnQgYWJvdmUgdGhlIGZvb3RlciAoY2FuY2VsJ3MgXCJTZWxlY3QgYXQgbGVhc3Qgb25lIGZsaWdodCB0byBjb250aW51ZVwiKSwgb3Igd2h5IFNlYXJjaCBpcyBkaXNhYmxlZC4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGhpbnQgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgc3dpdGNoICh0aGlzLnN0b3JlLnN0ZXAoKSkge1xuICAgICAgY2FzZSAnbGVncyc6XG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JlLmFueUF2YWlsYWJsZSgpICYmICF0aGlzLnN0b3JlLmNhbkNvbnRpbnVlKCkgPyAnU2VsZWN0IGF0IGxlYXN0IG9uZSBmbGlnaHQgdG8gY29udGludWUnIDogbnVsbDtcbiAgICAgIGNhc2UgJ2VkaXQnOlxuICAgICAgICByZXR1cm4gdGhpcy5zdG9yZS52YWxpZGF0aW9uRXJyb3IoKTtcbiAgICAgIGNhc2UgJ3VwZ3JhZGUtbGVncyc6XG4gICAgICAgIHJldHVybiB0aGlzLnVwZ3JhZGUuYW55TGVnVXBncmFkYWJsZSgpICYmICF0aGlzLnVwZ3JhZGUuY2FuQ29udGludWVGcm9tTGVncygpICYmICF0aGlzLnVwZ3JhZGUuc3VibWl0dGluZygpXG4gICAgICAgICAgPyAnU2VsZWN0IGF0IGxlYXN0IG9uZSBmbGlnaHQgdG8gY29udGludWUnXG4gICAgICAgICAgOiBudWxsO1xuICAgICAgY2FzZSAndXBncmFkZSc6XG4gICAgICAgIHJldHVybiB0aGlzLnVwZ3JhZGUuc2VjdGlvbnMoKS5zb21lKHMgPT4gcy5vcHRpb25zLmxlbmd0aCkgJiYgIXRoaXMudXBncmFkZS5jYW5Db250aW51ZSgpICYmICF0aGlzLnVwZ3JhZGUuc3VibWl0dGluZygpXG4gICAgICAgICAgPyAnU2VsZWN0IGEgY2xhc3MgdG8gY29udGludWUnXG4gICAgICAgICAgOiBudWxsO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9KTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvLyBEZXBlbmRzIG9ubHkgb24gdGhlc2UgdGhyZWUgaW5wdXRzOyB3aGF0ZXZlciB0aGUgc3RvcmUgcmVhZHMgd2hpbGUgb3BlbmluZyBtdXN0IG5vdCByZXRyaWdnZXIgaXQuXG4gICAgZWZmZWN0KFxuICAgICAgKCkgPT4ge1xuICAgICAgICBjb25zdCBbdmlzaWJsZSwgZGF0YSwgaWRdID0gW3RoaXMudmlzaWJsZSgpLCB0aGlzLmJvb2tpbmdEYXRhKCksIHRoaXMuYm9va2luZ0lkKCldO1xuICAgICAgICBpZiAodmlzaWJsZSkgdW50cmFja2VkKCgpID0+IHRoaXMuc3RvcmUub3BlbihkYXRhLCBpZCkpO1xuICAgICAgfSxcbiAgICAgIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfSxcbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIG9uU2VydmljZUNob3NlbihzZXJ2aWNlOiBSZWlzc3VlU2VydmljZUtleSk6IHZvaWQge1xuICAgIGlmIChzZXJ2aWNlID09PSAndXBncmFkZV9jbGFzcycpIHRoaXMudXBncmFkZS5zdGFydCgpO1xuICAgIGVsc2UgdGhpcy5zdG9yZS5jaG9vc2VTZXJ2aWNlKHNlcnZpY2UpO1xuICB9XG5cbiAgLyoqIEJhY2sgZnJvbSB0aGUgb3B0aW9ucyByZXR1cm5zIHRvIFwic2VsZWN0IGxlZ1wiIG9ubHkgd2hlbiB0aGF0IHN0ZXAgd2FzIHNob3duICh0aGUgdXBncmFkZSBzdG9yZSBrbm93cykuICovXG4gIHByb3RlY3RlZCBvbkJhY2soKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc3RvcmUuc3RlcCgpID09PSAndXBncmFkZScpIHRoaXMudXBncmFkZS5iYWNrKCk7XG4gICAgZWxzZSB0aGlzLnN0b3JlLmJhY2soKTtcbiAgfVxuXG4gIC8qKiBUaGUgcGF5bWVudCBsaW5rIGV4cGlyZWQ6IHJlZG8gdGhlIHdob2xlIHJlaXNzdWUgZnJvbSB0aGUgc3RhcnQgKGEgbmV3IHBvc3QtYm9va2luZywgdGhlIHNlcnZpY2UgbGlzdCBhZ2FpbikuICovXG4gIHByb3RlY3RlZCByZXN0YXJ0RmxvdygpOiB2b2lkIHtcbiAgICB0aGlzLnN0b3JlLm9wZW4odGhpcy5ib29raW5nRGF0YSgpLCB0aGlzLmJvb2tpbmdJZCgpKTtcbiAgfVxuXG4gIC8qKiBSZWRpcmVjdHMgdG8gdGhlIHdlYiBzZWFyY2ggKG5ldyB0YWI6IHRoZSBhZ2VudCBrZWVwcyB0aGUgZGFzaGJvYXJkIG9wZW4gbmV4dCB0byB0aGUgd2ViIGZsb3cpLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgc2VhcmNoRmxpZ2h0cygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB1cmwgPSB0aGlzLnN0b3JlLnNlYXJjaFVybCgpO1xuICAgIGlmICghdXJsKSByZXR1cm47XG4gICAgLy8gT3BlbiB0aGUgdGFiIG5vdywgaW5zaWRlIHRoZSBjbGljaywgc28gdGhlIGJyb3dzZXIgZG9lcyBub3QgYmxvY2sgaXQgd2hpbGUgdGhlIGhvc3QncyB0b2tlbiBpcyBhd2FpdGVkLlxuICAgIGNvbnN0IHRhYiA9IHdpbmRvdy5vcGVuKCdhYm91dDpibGFuaycsICdfYmxhbmsnKTtcbiAgICBjb25zdCBmaW5hbFVybCA9IGFwcGVuZEF1dGhQYXJhbXModXJsLCBhd2FpdCB0aGlzLnJlZGlyZWN0QXV0aFBhcmFtcygpLCB0aGlzLmNvbmZpZy5yZWRpcmVjdEF1dGhJbik7XG4gICAgaWYgKHRhYikge1xuICAgICAgdGFiLm9wZW5lciA9IG51bGw7IC8vIHNhbWUgcHJvdGVjdGlvbiBhcyBgbm9vcGVuZXJgXG4gICAgICB0YWIubG9jYXRpb24uaHJlZiA9IGZpbmFsVXJsO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aW5kb3cub3BlbihmaW5hbFVybCwgJ19ibGFuaycsICdub29wZW5lcicpO1xuICAgIH1cbiAgICB0aGlzLmNsb3NlZC5lbWl0KCk7XG4gIH1cblxuICAvKiogVGhlIGhvc3QncyBhdXRoIHBhcmFtZXRlcnMgZm9yIHRoZSB3ZWIgbGluazsgYHt9YCB3aGVuIGl0IGhhcyBub25lIG9yIGl0IGZhaWxzICh0aGUgd2ViIHRoZW4gYXNrcyB0byBsb2cgaW4pLiAqL1xuICBwcml2YXRlIGFzeW5jIHJlZGlyZWN0QXV0aFBhcmFtcygpOiBQcm9taXNlPFNiZFJlZGlyZWN0QXV0aFBhcmFtcz4ge1xuICAgIGNvbnN0IHByb3ZpZGUgPSB0aGlzLmNvbmZpZy5yZWRpcmVjdEF1dGhQYXJhbXM7XG4gICAgaWYgKCFwcm92aWRlKSByZXR1cm4ge307XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHJ1bkluSW5qZWN0aW9uQ29udGV4dCh0aGlzLmluamVjdG9yLCBwcm92aWRlKTtcbiAgICAgIHJldHVybiAoaXNPYnNlcnZhYmxlKHJlc3VsdCkgPyBhd2FpdCBmaXJzdFZhbHVlRnJvbShyZXN1bHQpIDogYXdhaXQgcmVzdWx0KSA/PyB7fTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gIH1cbn1cbiIsIjxwLWRpYWxvZyBbdmlzaWJsZV09XCJ2aXNpYmxlKClcIiAodmlzaWJsZUNoYW5nZSk9XCIkZXZlbnQgPyBudWxsIDogY2xvc2VkLmVtaXQoKVwiXG4gIFttb2RhbF09XCJ0cnVlXCIgW2Jsb2NrU2Nyb2xsXT1cInRydWVcIiBbZHJhZ2dhYmxlXT1cImZhbHNlXCIgW3Jlc2l6YWJsZV09XCJmYWxzZVwiXG4gIFtzaG93SGVhZGVyXT1cImZhbHNlXCIgW3N0eWxlXT1cInsgd2lkdGg6ICc1NjBweCcsIHBhZGRpbmc6ICcwJyB9XCIgc3R5bGVDbGFzcz1cInNiZC1yZWlzc3VlLWRpYWxvZy13cmFwcGVyXCI+XG5cbiAgPGRpdiBjbGFzcz1cInNiZC1yZWlzc3VlXCI+XG5cbiAgICA8IS0tIEhlYWRlcjogc2FtZSBsYXlvdXQgYXMgdGhlIGNhbmNlbCBkaWFsb2cgKHJvdW5kIGNsb3NlIGJ1dHRvbiwgY2VudGVyZWQgdGl0bGUgKyBib29raW5nIGlkKSAtLT5cbiAgICA8ZGl2IGNsYXNzPVwic2JkLXJlaXNzdWVfX2hlYWRlclwiPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzYmQtcmVpc3N1ZV9fY2xvc2VcIiAoY2xpY2spPVwiY2xvc2VkLmVtaXQoKVwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiPlxuICAgICAgICA8aSBjbGFzcz1cInBpIHBpLXRpbWVzXCI+PC9pPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8ZGl2IGNsYXNzPVwic2JkLXJlaXNzdWVfX2hlYWRlci10ZXh0XCI+XG4gICAgICAgIDxoMyBjbGFzcz1cInNiZC1yZWlzc3VlX190aXRsZVwiPnt7IHRpdGxlKCkgfX08L2gzPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNiZC1yZWlzc3VlX19zdWJcIj5Cb29raW5nIElEICN7eyBib29raW5nSWQoKSB9fTwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgQGlmIChzdG9yZS5sb2FkaW5nKCkpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtcmVpc3N1ZV9fc3RhdGVcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1yZWlzc3VlX19zdGF0ZS1pY29uXCI+PGkgY2xhc3M9XCJwaSBwaS1zcGluIHBpLXNwaW5uZXJcIj48L2k+PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtcmVpc3N1ZV9fc3RhdGUtdGV4dFwiPkNoZWNraW5nIGF2YWlsYWJpbGl0eeKApjwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2JkLXJlaXNzdWVfX2RvdHNcIj48c3Bhbj48L3NwYW4+PHNwYW4+PC9zcGFuPjxzcGFuPjwvc3Bhbj48L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIH0gQGVsc2UgaWYgKHN0b3JlLmVycm9yKCkpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtcmVpc3N1ZV9fc3RhdGVcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1yZWlzc3VlX19zdGF0ZS1pY29uIHNiZC1yZWlzc3VlX19zdGF0ZS1pY29uLS13YXJuXCI+PGkgY2xhc3M9XCJwaSBwaS1leGNsYW1hdGlvbi10cmlhbmdsZVwiPjwvaT48L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1yZWlzc3VlX19zdGF0ZS10ZXh0XCI+e3sgc3RvcmUuZXJyb3IoKSB9fTwvZGl2PlxuICAgICAgICA8YnV0dG9uIHBCdXR0b24gdHlwZT1cImJ1dHRvblwiIGxhYmVsPVwiUmV0cnlcIiBjbGFzcz1cInAtYnV0dG9uLW91dGxpbmVkIHAtYnV0dG9uLXNlY29uZGFyeVwiIChjbGljayk9XCJzdG9yZS5sb2FkKClcIj48L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIH0gQGVsc2UgaWYgKHN0b3JlLmJsb2NrZWQoKSkge1xuICAgICAgPCEtLSBObyBsZWcgY2FuIGJlIHJlaXNzdWVkIG9ubGluZTogc2FtZSBpZGVhIGFzIHRoZSBjYW5jZWwgZGlhbG9nJ3MgXCJub3QgZWxpZ2libGUsIGVzY2FsYXRlXCIgbm90aWNlLiAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYmQtcmVpc3N1ZV9fYm9keVwiPlxuICAgICAgICA8YXBwLXNiZC1yZWlzc3VlLW5vdGljZSB0b25lPVwid2FyblwiIGljb249XCJwaSBwaS1leGNsYW1hdGlvbi10cmlhbmdsZVwiPlxuICAgICAgICAgIDxzdHJvbmc+e3sgc3RvcmUuYmxvY2tlZCgpPy50aXRsZSB9fTwvc3Ryb25nPjxicj57eyBzdG9yZS5ibG9ja2VkKCk/LnRleHQgfX1cbiAgICAgICAgPC9hcHAtc2JkLXJlaXNzdWUtbm90aWNlPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwic2JkLXJlaXNzdWVfX2Zvb3RlclwiPlxuICAgICAgICA8YnV0dG9uIHBCdXR0b24gdHlwZT1cImJ1dHRvblwiIGxhYmVsPVwiQ2xvc2VcIiBjbGFzcz1cInAtYnV0dG9uLW91dGxpbmVkIHAtYnV0dG9uLXNlY29uZGFyeSBzYmQtcmVpc3N1ZV9fYnRuXCJcbiAgICAgICAgICAoY2xpY2spPVwiY2xvc2VkLmVtaXQoKVwiPjwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgfSBAZWxzZSB7XG4gICAgICA8ZGl2IGNsYXNzPVwic2JkLXJlaXNzdWVfX2JvZHlcIj5cbiAgICAgICAgQHN3aXRjaCAoc3RvcmUuc3RlcCgpKSB7XG4gICAgICAgICAgQGNhc2UgKCdzZXJ2aWNlJykge1xuICAgICAgICAgICAgPGFwcC1zYmQtcmVpc3N1ZS1ub3RpY2U+Q2hhbmdlIHJlcXVlc3RzIGFyZSBzdWJqZWN0IHRvIGF2YWlsYWJpbGl0eSBmcm9tIHRoZSBhaXJsaW5lLjwvYXBwLXNiZC1yZWlzc3VlLW5vdGljZT5cbiAgICAgICAgICAgIDxhcHAtc2JkLXJlaXNzdWUtc2VydmljZS1zdGVwXG4gICAgICAgICAgICAgIFt1cGdyYWRlQXZhaWxhYmxlXT1cInN0b3JlLnVwZ3JhZGVBdmFpbGFibGUoKVwiXG4gICAgICAgICAgICAgIChjaG9zZW4pPVwib25TZXJ2aWNlQ2hvc2VuKCRldmVudClcIiAvPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAY2FzZSAoJ2xlZ3MnKSB7XG4gICAgICAgICAgICA8YXBwLXNiZC1yZWlzc3VlLWxlZ3Mtc3RlcFxuICAgICAgICAgICAgICBbcm93c109XCJzdG9yZS5sZWdSb3dzKClcIlxuICAgICAgICAgICAgICBbYW55QXZhaWxhYmxlXT1cInN0b3JlLmFueUF2YWlsYWJsZSgpXCJcbiAgICAgICAgICAgICAgKHRvZ2dsZWQpPVwic3RvcmUudG9nZ2xlTGVnKCRldmVudClcIiAvPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAY2FzZSAoJ2VkaXQnKSB7XG4gICAgICAgICAgICBAaWYgKHN0b3JlLnNlcnZpY2UoKSA9PT0gJ2NoYW5nZV9kYXRlJykge1xuICAgICAgICAgICAgICA8YXBwLXNiZC1yZWlzc3VlLWRhdGUtc3RlcFxuICAgICAgICAgICAgICAgIFtyb3dzXT1cInN0b3JlLmRhdGVSb3dzKClcIlxuICAgICAgICAgICAgICAgIChjaGFuZ2VkKT1cInN0b3JlLnNldERhdGUoJGV2ZW50LmxlZ0lkLCAkZXZlbnQuZGF0ZSlcIiAvPlxuICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgIDxhcHAtc2JkLXJlaXNzdWUtcm91dGUtc3RlcFxuICAgICAgICAgICAgICAgIFtyb3dzXT1cInN0b3JlLnJvdXRlUm93cygpXCJcbiAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJzdG9yZS5haXJwb3J0T3B0aW9ucygpXCJcbiAgICAgICAgICAgICAgICAoYWlycG9ydENoYW5nZWQpPVwic3RvcmUuc2V0QWlycG9ydCgkZXZlbnQubGVnSWQsICRldmVudC5zaWRlLCAkZXZlbnQuYWlycG9ydClcIlxuICAgICAgICAgICAgICAgIChzZWFyY2hlZCk9XCJzdG9yZS5zZWFyY2hBaXJwb3J0cygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAoc3dhcHBlZCk9XCJzdG9yZS5zd2FwQWlycG9ydHMoJGV2ZW50KVwiIC8+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIEBjYXNlICgndXBncmFkZS1sZWdzJykge1xuICAgICAgICAgICAgPGFwcC1zYmQtcmVpc3N1ZS1sZWdzLXN0ZXBcbiAgICAgICAgICAgICAgdW5hdmFpbGFibGVUZXh0PVwiTm9uZSBvZiB0aGVzZSBmbGlnaHRzIGNhbiBiZSB1cGdyYWRlZCBvbmxpbmUuIEhhbmRsZSB0aGlzIGJvb2tpbmcgbWFudWFsbHkuXCJcbiAgICAgICAgICAgICAgW3Jvd3NdPVwidXBncmFkZS5sZWdSb3dzKClcIlxuICAgICAgICAgICAgICBbYW55QXZhaWxhYmxlXT1cInVwZ3JhZGUuYW55TGVnVXBncmFkYWJsZSgpXCJcbiAgICAgICAgICAgICAgW25vdGVdPVwic3RvcmUuYWxsb3dTaW5nbGVMZWdTZWxlY3Rpb24oKSA/IG51bGwgOiAnVGhlc2UgZmxpZ2h0cyBtdXN0IGJlIHVwZ3JhZGVkIHRvZ2V0aGVyLidcIlxuICAgICAgICAgICAgICBbZXJyb3JdPVwidXBncmFkZS5lcnJvcigpXCJcbiAgICAgICAgICAgICAgKHRvZ2dsZWQpPVwidXBncmFkZS50b2dnbGVMZWcoJGV2ZW50KVwiIC8+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBjYXNlICgndXBncmFkZScpIHtcbiAgICAgICAgICAgIDxhcHAtc2JkLXJlaXNzdWUtdXBncmFkZS1zdGVwXG4gICAgICAgICAgICAgIFtzZWN0aW9uc109XCJ1cGdyYWRlLnNlY3Rpb25zKClcIlxuICAgICAgICAgICAgICBbZXJyb3JdPVwidXBncmFkZS5lcnJvcigpXCJcbiAgICAgICAgICAgICAgKHBpY2tlZCk9XCJ1cGdyYWRlLnNlbGVjdCgkZXZlbnQuc2VjdGlvbklkLCAkZXZlbnQua2V5KVwiIC8+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBjYXNlICgnY29uZmlybScpIHtcbiAgICAgICAgICAgIDxhcHAtc2JkLXJlaXNzdWUtdXBncmFkZS1jb25maXJtLXN0ZXBcbiAgICAgICAgICAgICAgW3Jvd3NdPVwidXBncmFkZS5zdW1tYXJ5KClcIlxuICAgICAgICAgICAgICBbdG90YWxdPVwidXBncmFkZS50b3RhbCgpXCJcbiAgICAgICAgICAgICAgW3RvdGFsTGFiZWxdPVwidXBncmFkZS50b3RhbExhYmVsKClcIlxuICAgICAgICAgICAgICBbcHJpY2VDaGFuZ2VkXT1cInVwZ3JhZGUucHJpY2VDaGFuZ2VkKClcIlxuICAgICAgICAgICAgICBbYm9va2VkXT1cInVwZ3JhZGUuYm9va2VkKClcIlxuICAgICAgICAgICAgICBbbGlua109XCJ1cGdyYWRlLnBheW1lbnRMaW5rKClcIlxuICAgICAgICAgICAgICBbZXJyb3JdPVwidXBncmFkZS5lcnJvcigpXCJcbiAgICAgICAgICAgICAgKHJlc3RhcnQpPVwicmVzdGFydEZsb3coKVwiIC8+XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cblxuICAgICAgQGlmIChoaW50KCk7IGFzIHRleHQpIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cInNiZC1yZWlzc3VlX19oaW50XCI+e3sgdGV4dCB9fTwvZGl2PlxuICAgICAgfVxuXG4gICAgICBAaWYgKHN0b3JlLnN0ZXAoKSAhPT0gJ3NlcnZpY2UnKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzYmQtcmVpc3N1ZV9fZm9vdGVyXCI+XG4gICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIHR5cGU9XCJidXR0b25cIiBsYWJlbD1cIkJhY2tcIiBjbGFzcz1cInAtYnV0dG9uLW91dGxpbmVkIHAtYnV0dG9uLXNlY29uZGFyeSBzYmQtcmVpc3N1ZV9fYnRuXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJzdG9yZS5zdGVwKCkgPT09ICdjb25maXJtJyAmJiB1cGdyYWRlLmxvY2tlZCgpXCIgKGNsaWNrKT1cIm9uQmFjaygpXCI+PC9idXR0b24+XG5cbiAgICAgICAgICBAc3dpdGNoIChzdG9yZS5zdGVwKCkpIHtcbiAgICAgICAgICAgIEBjYXNlICgnbGVncycpIHtcbiAgICAgICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIHR5cGU9XCJidXR0b25cIiBsYWJlbD1cIkNvbnRpbnVlXCIgY2xhc3M9XCJzYmQtcmVpc3N1ZV9fYnRuXCJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiIXN0b3JlLmNhbkNvbnRpbnVlKClcIiAoY2xpY2spPVwic3RvcmUuZ29Ub0VkaXQoKVwiPjwvYnV0dG9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGNhc2UgKCdlZGl0Jykge1xuICAgICAgICAgICAgICA8YnV0dG9uIHBCdXR0b24gdHlwZT1cImJ1dHRvblwiIGljb249XCJwaSBwaS1zZWFyY2hcIiBsYWJlbD1cIlNlYXJjaCBmbGlnaHRzXCIgY2xhc3M9XCJzYmQtcmVpc3N1ZV9fYnRuXCJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiISFzdG9yZS52YWxpZGF0aW9uRXJyb3IoKVwiIChjbGljayk9XCJzZWFyY2hGbGlnaHRzKClcIj48L2J1dHRvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBjYXNlICgndXBncmFkZS1sZWdzJykge1xuICAgICAgICAgICAgICA8YnV0dG9uIHBCdXR0b24gdHlwZT1cImJ1dHRvblwiIGxhYmVsPVwiQ29udGludWVcIiBjbGFzcz1cInNiZC1yZWlzc3VlX19idG5cIiBbbG9hZGluZ109XCJ1cGdyYWRlLnN1Ym1pdHRpbmcoKVwiXG4gICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiF1cGdyYWRlLmNhbkNvbnRpbnVlRnJvbUxlZ3MoKVwiIChjbGljayk9XCJ1cGdyYWRlLmNvbnRpbnVlRnJvbUxlZ3MoKVwiPjwvYnV0dG9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGNhc2UgKCd1cGdyYWRlJykge1xuICAgICAgICAgICAgICA8YnV0dG9uIHBCdXR0b24gdHlwZT1cImJ1dHRvblwiIGxhYmVsPVwiQ29udGludWVcIiBjbGFzcz1cInNiZC1yZWlzc3VlX19idG5cIiBbbG9hZGluZ109XCJ1cGdyYWRlLnN1Ym1pdHRpbmcoKVwiXG4gICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiF1cGdyYWRlLmNhbkNvbnRpbnVlKClcIiAoY2xpY2spPVwidXBncmFkZS5jb250aW51ZSgpXCI+PC9idXR0b24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAY2FzZSAoJ2NvbmZpcm0nKSB7XG4gICAgICAgICAgICAgIEBzd2l0Y2ggKHVwZ3JhZGUuYWN0aW9uKCkpIHtcbiAgICAgICAgICAgICAgICBAY2FzZSAoJ2RvbmUnKSB7XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uIHBCdXR0b24gdHlwZT1cImJ1dHRvblwiIGxhYmVsPVwiQ2xvc2VcIiBjbGFzcz1cInNiZC1yZWlzc3VlX19idG5cIiAoY2xpY2spPVwiY2xvc2VkLmVtaXQoKVwiPjwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBAY2FzZSAoJ2Jvb2snKSB7XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uIHBCdXR0b24gdHlwZT1cImJ1dHRvblwiIGxhYmVsPVwiQ29uZmlybSB1cGdyYWRlXCIgY2xhc3M9XCJzYmQtcmVpc3N1ZV9fYnRuXCJcbiAgICAgICAgICAgICAgICAgICAgW2xvYWRpbmddPVwidXBncmFkZS5zdWJtaXR0aW5nKClcIiAoY2xpY2spPVwidXBncmFkZS5jb25maXJtKClcIj48L2J1dHRvbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgQGNhc2UgKCdsaW5rJykge1xuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIHR5cGU9XCJidXR0b25cIiBpY29uPVwicGkgcGktbGlua1wiIGxhYmVsPVwiR2VuZXJhdGUgcGF5bWVudCBsaW5rXCIgY2xhc3M9XCJzYmQtcmVpc3N1ZV9fYnRuXCJcbiAgICAgICAgICAgICAgICAgICAgW2xvYWRpbmddPVwidXBncmFkZS5zdWJtaXR0aW5nKClcIiAoY2xpY2spPVwidXBncmFkZS5jb25maXJtKClcIj48L2J1dHRvbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgfVxuICAgIH1cbiAgPC9kaXY+XG48L3AtZGlhbG9nPlxuIl19