lucy-calendar
Version:
LucyCalendar is a powerful and flexible date picker library for Angular applications, specifically designed for Ethiopian dates. It provides a user-friendly interface for selecting dates and supports various customization options to fit your needs.
164 lines • 26 kB
JavaScript
import { Directive, HostListener, Input, Output, EventEmitter } from '@angular/core';
import { LucyCalendarComponent } from './lucy-calendar.component';
import * as i0 from "@angular/core";
export class LucyCalendarDirective {
el;
viewContainerRef;
renderer;
label = 'Select Date';
value = null;
valueChange = new EventEmitter();
dateValue = null;
dateValueChange = new EventEmitter();
placeholder = null;
min = null;
max = null;
dateFormat = 'dd/mm/yyyy';
// @Input() disabled: boolean = false;
// @Input() readonly: boolean = true;
componentRef;
isCalendarOpen = false; // Track open/closed state
calendarElement = null;
constructor(el, viewContainerRef, renderer) {
this.el = el;
this.viewContainerRef = viewContainerRef;
this.renderer = renderer;
this.componentRef = this.viewContainerRef.createComponent(LucyCalendarComponent);
this.calendarElement = this.componentRef.location.nativeElement;
}
// Open/close on input click
onClick() {
this.componentRef.instance.toggleCalendar();
}
// Close when clicking outside the input or calendar
onDocumentClick(event) {
const target = event.target;
const clickedInsideInput = this.el.nativeElement.contains(target);
const clickedInsideCalendar = this.calendarElement?.contains(target);
if (!clickedInsideInput && !clickedInsideCalendar && this.isCalendarOpen) {
this.closeCalendar();
}
}
ngOnInit() {
// Create the button element
const button = this.renderer.createElement('button');
// this.renderer.setAttribute(button, 'type', 'button');
if (this.el.nativeElement.disabled) {
this.renderer.setAttribute(button, 'disabled', 'true');
}
if (this.el.nativeElement.readonly) {
this.renderer.setAttribute(button, 'readonly', 'true');
}
this.renderer.setAttribute(button, 'class', 'absolute inset-y-0 right-0 flex items-center pr-3 cursor-pointer disabled:cursor-not-allowed disabled:text-gray-300');
// Create the SVG element
const svg = this.renderer.createElement('svg', 'svg');
this.renderer.setAttribute(svg, 'xmlns', 'http://www.w3.org/2000/svg');
this.renderer.setAttribute(svg, 'fill', 'none');
this.renderer.setAttribute(svg, 'viewBox', '0 0 24 24');
this.renderer.setAttribute(svg, 'stroke-width', '1.5');
this.renderer.setAttribute(svg, 'stroke', 'currentColor');
this.renderer.setAttribute(svg, 'class', 'h-6 w-6 text-gray-500 hover:text-gray-700 calendar-icon');
// set the SVG attributes
const path = this.renderer.createElement('path', 'svg');
this.renderer.setAttribute(path, 'class', 'calendar-icon');
this.renderer.setAttribute(path, 'stroke-linecap', 'round');
this.renderer.setAttribute(path, 'stroke-linejoin', 'round');
this.renderer.setAttribute(path, 'd', 'M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z');
// Append the path to the SVG
this.renderer.appendChild(svg, path);
// Append the SVG to the button
this.renderer.appendChild(button, svg);
// append class to the host element
this.renderer.addClass(this.el.nativeElement, 'block');
this.renderer.addClass(this.el.nativeElement, 'lucy-host');
const parentDiv = this.renderer.createElement('div');
this.renderer.addClass(parentDiv, 'relative');
const computedWidth = window.getComputedStyle(this.el.nativeElement).width;
this.renderer.setStyle(parentDiv, 'width', computedWidth);
const parent = this.renderer.parentNode(this.el.nativeElement);
this.renderer.insertBefore(parent, parentDiv, this.el.nativeElement);
this.renderer.appendChild(parentDiv, this.el.nativeElement);
this.renderer.appendChild(parentDiv, button);
this.renderer.appendChild(this.el.nativeElement.parentElement, this.calendarElement);
this.renderer.listen(button, 'click', () => {
this.componentRef.instance.toggleCalendar();
this.renderer.appendChild(this.el.nativeElement.parentElement, this.calendarElement);
});
this.openCalendar();
}
ngOnChanges(changes) {
if (changes['dateValue'] && !changes['dateValue'].firstChange) {
this.componentRef.instance.ngOnChanges(changes);
}
}
ngOnDestroy() {
this.closeCalendar();
}
openCalendar() {
// Pass inputs to the calendar component
// this.componentRef.instance.label = this.label;
// this.componentRef.instance.value = this.value;
this.componentRef.instance.dateValue = this.dateValue;
this.componentRef.instance.placeholder = this.placeholder;
this.componentRef.instance.min = this.min;
this.componentRef.instance.max = this.max;
this.componentRef.instance.dateFormat = this.dateFormat;
// Handle outputs
// this.componentRef.instance.valueChange.subscribe((value: string | null) => {
// this.renderer.setProperty(this.el.nativeElement, 'value', value ?? this.placeholder ?? this.dateFormat);
// if (value === this.value) return
// this.valueChange.emit(value);
// });
this.componentRef.instance.dateValueChange.subscribe((date) => {
// setTimeout(() => {
// this.value = this.componentRef.instance.formatDate();
// });
const et = date !== null ? this.componentRef.instance.formatDate() : null;
this.renderer.setProperty(this.el.nativeElement, 'value', et ?? this.placeholder ?? this.dateFormat);
// this.valueChange.emit(this.value);
this.dateValueChange.emit(date);
this.valueChange.emit(et);
});
this.componentRef.instance.emitChange();
// Append to the input's parent (not document.body)
this.renderer.appendChild(this.el.nativeElement.parentElement, this.calendarElement);
// }
}
closeCalendar() {
this.componentRef.destroy();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LucyCalendarDirective, deps: [{ token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: LucyCalendarDirective, isStandalone: true, selector: "[lucyCalendar]", inputs: { label: "label", value: "value", dateValue: "dateValue", placeholder: "placeholder", min: "min", max: "max", dateFormat: "dateFormat" }, outputs: { valueChange: "valueChange", dateValueChange: "dateValueChange" }, host: { listeners: { "click": "onClick()", "document:click": "onDocumentClick($event)" } }, usesOnChanges: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LucyCalendarDirective, decorators: [{
type: Directive,
args: [{
selector: '[lucyCalendar]',
standalone: true,
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i0.Renderer2 }], propDecorators: { label: [{
type: Input
}], value: [{
type: Input
}], valueChange: [{
type: Output
}], dateValue: [{
type: Input
}], dateValueChange: [{
type: Output
}], placeholder: [{
type: Input
}], min: [{
type: Input
}], max: [{
type: Input
}], dateFormat: [{
type: Input
}], onClick: [{
type: HostListener,
args: ['click']
}], onDocumentClick: [{
type: HostListener,
args: ['document:click', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibHVjeS1jYWxlbmRhci5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9sdWN5LWNhbGVuZGFyL3NyYy9saWIvbHVjeS1jYWxlbmRhci5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNILFNBQVMsRUFBYyxZQUFZLEVBQUUsS0FBSyxFQUM1QixNQUFNLEVBQUUsWUFBWSxFQUdyQyxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7QUFNbEUsTUFBTSxPQUFPLHFCQUFxQjtJQWtCbEI7SUFDQTtJQUNBO0lBbkJILEtBQUssR0FBVyxhQUFhLENBQUM7SUFDOUIsS0FBSyxHQUFrQixJQUFJLENBQUM7SUFDM0IsV0FBVyxHQUFnQyxJQUFJLFlBQVksRUFBaUIsQ0FBQztJQUM5RSxTQUFTLEdBQWdCLElBQUksQ0FBQztJQUM3QixlQUFlLEdBQThCLElBQUksWUFBWSxFQUFlLENBQUM7SUFDOUUsV0FBVyxHQUFrQixJQUFJLENBQUM7SUFDbEMsR0FBRyxHQUFnQixJQUFJLENBQUM7SUFDeEIsR0FBRyxHQUFnQixJQUFJLENBQUM7SUFDeEIsVUFBVSxHQUFXLFlBQVksQ0FBQztJQUMzQyxzQ0FBc0M7SUFDdEMscUNBQXFDO0lBRTdCLFlBQVksQ0FBc0M7SUFDbEQsY0FBYyxHQUFHLEtBQUssQ0FBQyxDQUFDLDBCQUEwQjtJQUNsRCxlQUFlLEdBQXVCLElBQUksQ0FBQztJQUVuRCxZQUNZLEVBQWMsRUFDZCxnQkFBa0MsRUFDbEMsUUFBbUI7UUFGbkIsT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQUNkLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUUzQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxlQUFlLENBQUMscUJBQXFCLENB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QyxlQUFlLENBQUMsQ0FBQztRQUNyRixJQUFJO0lBQ1IsQ0FBQztJQUVPLGFBQWE7UUFDakIsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNoQyxDQUFDO3dHQWxKUSxxQkFBcUI7NEZBQXJCLHFCQUFxQjs7NEZBQXJCLHFCQUFxQjtrQkFKakMsU0FBUzttQkFBQztvQkFDUCxRQUFRLEVBQUUsZ0JBQWdCO29CQUMxQixVQUFVLEVBQUUsSUFBSTtpQkFDbkI7c0lBRVksS0FBSztzQkFBYixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDSSxXQUFXO3NCQUFwQixNQUFNO2dCQUNFLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0ksZUFBZTtzQkFBeEIsTUFBTTtnQkFDRSxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLEdBQUc7c0JBQVgsS0FBSztnQkFDRyxHQUFHO3NCQUFYLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFrQmlCLE9BQU87c0JBQTdCLFlBQVk7dUJBQUMsT0FBTztnQkFNckIsZUFBZTtzQkFEZCxZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICAgIERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBJbnB1dCwgVmlld0NvbnRhaW5lclJlZixcclxuICAgIENvbXBvbmVudFJlZiwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIFJlbmRlcmVyMiwgT25Jbml0LCBPbkRlc3Ryb3ksXHJcbiAgICBTaW1wbGVDaGFuZ2VzLFxyXG4gICAgT25DaGFuZ2VzXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEx1Y3lDYWxlbmRhckNvbXBvbmVudCB9IGZyb20gJy4vbHVjeS1jYWxlbmRhci5jb21wb25lbnQnO1xyXG5cclxuQERpcmVjdGl2ZSh7XHJcbiAgICBzZWxlY3RvcjogJ1tsdWN5Q2FsZW5kYXJdJyxcclxuICAgIHN0YW5kYWxvbmU6IHRydWUsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBMdWN5Q2FsZW5kYXJEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcclxuICAgIEBJbnB1dCgpIGxhYmVsOiBzdHJpbmcgPSAnU2VsZWN0IERhdGUnO1xyXG4gICAgQElucHV0KCkgdmFsdWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xyXG4gICAgQE91dHB1dCgpIHZhbHVlQ2hhbmdlOiBFdmVudEVtaXR0ZXI8c3RyaW5nIHwgbnVsbD4gPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZyB8IG51bGw+KCk7XHJcbiAgICBASW5wdXQoKSBkYXRlVmFsdWU6IERhdGUgfCBudWxsID0gbnVsbDtcclxuICAgIEBPdXRwdXQoKSBkYXRlVmFsdWVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxEYXRlIHwgbnVsbD4gPSBuZXcgRXZlbnRFbWl0dGVyPERhdGUgfCBudWxsPigpO1xyXG4gICAgQElucHV0KCkgcGxhY2Vob2xkZXI6IHN0cmluZyB8IG51bGwgPSBudWxsO1xyXG4gICAgQElucHV0KCkgbWluOiBEYXRlIHwgbnVsbCA9IG51bGw7XHJcbiAgICBASW5wdXQoKSBtYXg6IERhdGUgfCBudWxsID0gbnVsbDtcclxuICAgIEBJbnB1dCgpIGRhdGVGb3JtYXQ6IHN0cmluZyA9ICdkZC9tbS95eXl5JztcclxuICAgIC8vIEBJbnB1dCgpIGRpc2FibGVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICAvLyBASW5wdXQoKSByZWFkb25seTogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gICAgcHJpdmF0ZSBjb21wb25lbnRSZWY6IENvbXBvbmVudFJlZjxMdWN5Q2FsZW5kYXJDb21wb25lbnQ+O1xyXG4gICAgcHJpdmF0ZSBpc0NhbGVuZGFyT3BlbiA9IGZhbHNlOyAvLyBUcmFjayBvcGVuL2Nsb3NlZCBzdGF0ZVxyXG4gICAgcHJpdmF0ZSBjYWxlbmRhckVsZW1lbnQ6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XHJcblxyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHJpdmF0ZSBlbDogRWxlbWVudFJlZixcclxuICAgICAgICBwcml2YXRlIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYsXHJcbiAgICAgICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyXHJcbiAgICApIHtcclxuICAgICAgICB0aGlzLmNvbXBvbmVudFJlZiA9IHRoaXMudmlld0NvbnRhaW5lclJlZi5jcmVhdGVDb21wb25lbnQoTHVjeUNhbGVuZGFyQ29tcG9uZW50KTtcclxuICAgICAgICB0aGlzLmNhbGVuZGFyRWxlbWVudCA9IHRoaXMuY29tcG9uZW50UmVmLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gT3Blbi9jbG9zZSBvbiBpbnB1dCBjbGlja1xyXG4gICAgQEhvc3RMaXN0ZW5lcignY2xpY2snKSBvbkNsaWNrKCkge1xyXG4gICAgICAgIHRoaXMuY29tcG9uZW50UmVmLmluc3RhbmNlLnRvZ2dsZUNhbGVuZGFyKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2xvc2Ugd2hlbiBjbGlja2luZyBvdXRzaWRlIHRoZSBpbnB1dCBvciBjYWxlbmRhclxyXG4gICAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxyXG4gICAgb25Eb2N1bWVudENsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KSB7XHJcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xyXG4gICAgICAgIGNvbnN0IGNsaWNrZWRJbnNpZGVJbnB1dCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5jb250YWlucyh0YXJnZXQpO1xyXG4gICAgICAgIGNvbnN0IGNsaWNrZWRJbnNpZGVDYWxlbmRhciA9IHRoaXMuY2FsZW5kYXJFbGVtZW50Py5jb250YWlucyh0YXJnZXQpO1xyXG5cclxuICAgICAgICBpZiAoIWNsaWNrZWRJbnNpZGVJbnB1dCAmJiAhY2xpY2tlZEluc2lkZUNhbGVuZGFyICYmIHRoaXMuaXNDYWxlbmRhck9wZW4pIHtcclxuICAgICAgICAgICAgdGhpcy5jbG9zZUNhbGVuZGFyKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG5nT25Jbml0KCkge1xyXG5cclxuICAgICAgICAvLyBDcmVhdGUgdGhlIGJ1dHRvbiBlbGVtZW50XHJcbiAgICAgICAgY29uc3QgYnV0dG9uID0gdGhpcy5yZW5kZXJlci5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcclxuICAgICAgICAvLyB0aGlzLnJlbmRlcmVyLnNldEF0dHJpYnV0ZShidXR0b24sICd0eXBlJywgJ2J1dHRvbicpO1xyXG4gICAgICAgIGlmICh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuZGlzYWJsZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUoYnV0dG9uLCAnZGlzYWJsZWQnLCAndHJ1ZScpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5lbC5uYXRpdmVFbGVtZW50LnJlYWRvbmx5KSB7XHJcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0QXR0cmlidXRlKGJ1dHRvbiwgJ3JlYWRvbmx5JywgJ3RydWUnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUoYnV0dG9uLCAnY2xhc3MnLCAnYWJzb2x1dGUgaW5zZXQteS0wIHJpZ2h0LTAgZmxleCBpdGVtcy1jZW50ZXIgcHItMyBjdXJzb3ItcG9pbnRlciBkaXNhYmxlZDpjdXJzb3Itbm90LWFsbG93ZWQgZGlzYWJsZWQ6dGV4dC1ncmF5LTMwMCcpO1xyXG5cclxuICAgICAgICAvLyBDcmVhdGUgdGhlIFNWRyBlbGVtZW50XHJcbiAgICAgICAgY29uc3Qgc3ZnID0gdGhpcy5yZW5kZXJlci5jcmVhdGVFbGVtZW50KCdzdmcnLCAnc3ZnJyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUoc3ZnLCAneG1sbnMnLCAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldEF0dHJpYnV0ZShzdmcsICdmaWxsJywgJ25vbmUnKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldEF0dHJpYnV0ZShzdmcsICd2aWV3Qm94JywgJzAgMCAyNCAyNCcpO1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0QXR0cmlidXRlKHN2ZywgJ3N0cm9rZS13aWR0aCcsICcxLjUnKTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldEF0dHJpYnV0ZShzdmcsICdzdHJva2UnLCAnY3VycmVudENvbG9yJyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUoc3ZnLCAnY2xhc3MnLCAnaC02IHctNiB0ZXh0LWdyYXktNTAwIGhvdmVyOnRleHQtZ3JheS03MDAgY2FsZW5kYXItaWNvbicpO1xyXG4gICAgICAgIC8vIHNldCB0aGUgU1ZHIGF0dHJpYnV0ZXNcclxuICAgICAgICBjb25zdCBwYXRoID0gdGhpcy5yZW5kZXJlci5jcmVhdGVFbGVtZW50KCdwYXRoJywgJ3N2ZycpO1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0QXR0cmlidXRlKHBhdGgsICdjbGFzcycsICdjYWxlbmRhci1pY29uJyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUocGF0aCwgJ3N0cm9rZS1saW5lY2FwJywgJ3JvdW5kJyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUocGF0aCwgJ3N0cm9rZS1saW5lam9pbicsICdyb3VuZCcpO1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0QXR0cmlidXRlKHBhdGgsICdkJywgJ004IDdWM204IDRWM20tOSA4aDEwTTUgMjFoMTRhMiAyIDAgMDAyLTJWN2EyIDIgMCAwMC0yLTJINWEyIDIgMCAwMC0yIDJ2MTJhMiAyIDAgMDAyIDJ6Jyk7XHJcblxyXG4gICAgICAgIC8vIEFwcGVuZCB0aGUgcGF0aCB0byB0aGUgU1ZHXHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZChzdmcsIHBhdGgpO1xyXG4gICAgICAgIC8vIEFwcGVuZCB0aGUgU1ZHIHRvIHRoZSBidXR0b25cclxuICAgICAgICB0aGlzLnJlbmRlcmVyLmFwcGVuZENoaWxkKGJ1dHRvbiwgc3ZnKTtcclxuXHJcblxyXG4gICAgICAgIC8vIGFwcGVuZCBjbGFzcyB0byB0aGUgaG9zdCBlbGVtZW50XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQsICdibG9jaycpO1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5lbC5uYXRpdmVFbGVtZW50LCAnbHVjeS1ob3N0Jyk7XHJcblxyXG4gICAgICAgIGNvbnN0IHBhcmVudERpdiA9IHRoaXMucmVuZGVyZXIuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyhwYXJlbnREaXYsICdyZWxhdGl2ZScpO1xyXG4gICAgICAgIGNvbnN0IGNvbXB1dGVkV2lkdGggPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpLndpZHRoO1xyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUocGFyZW50RGl2LCAnd2lkdGgnLCBjb21wdXRlZFdpZHRoKTtcclxuXHJcbiAgICAgICAgY29uc3QgcGFyZW50ID0gdGhpcy5yZW5kZXJlci5wYXJlbnROb2RlKHRoaXMuZWwubmF0aXZlRWxlbWVudCk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5pbnNlcnRCZWZvcmUocGFyZW50LCBwYXJlbnREaXYsIHRoaXMuZWwubmF0aXZlRWxlbWVudCk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZChwYXJlbnREaXYsIHRoaXMuZWwubmF0aXZlRWxlbWVudCk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZChwYXJlbnREaXYsIGJ1dHRvbik7XHJcblxyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuYXBwZW5kQ2hpbGQodGhpcy5lbC5uYXRpdmVFbGVtZW50LnBhcmVudEVsZW1lbnQsIHRoaXMuY2FsZW5kYXJFbGVtZW50KTtcclxuXHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5saXN0ZW4oYnV0dG9uLCAnY2xpY2snLCAoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuY29tcG9uZW50UmVmIS5pbnN0YW5jZS50b2dnbGVDYWxlbmRhcigpO1xyXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmFwcGVuZENoaWxkKHRoaXMuZWwubmF0aXZlRWxlbWVudC5wYXJlbnRFbGVtZW50LCB0aGlzLmNhbGVuZGFyRWxlbWVudCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5vcGVuQ2FsZW5kYXIoKTtcclxuICAgIH1cclxuXHJcbiAgICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGNoYW5nZXNbJ2RhdGVWYWx1ZSddICYmICFjaGFuZ2VzWydkYXRlVmFsdWUnXS5maXJzdENoYW5nZSkge1xyXG4gICAgICAgICAgICB0aGlzLmNvbXBvbmVudFJlZi5pbnN0YW5jZS5uZ09uQ2hhbmdlcyhjaGFuZ2VzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICAgICAgdGhpcy5jbG9zZUNhbGVuZGFyKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBvcGVuQ2FsZW5kYXIoKSB7XHJcblxyXG4gICAgICAgIC8vIFBhc3MgaW5wdXRzIHRvIHRoZSBjYWxlbmRhciBjb21wb25lbnRcclxuICAgICAgICAvLyB0aGlzLmNvbXBvbmVudFJlZi5pbnN0YW5jZS5sYWJlbCA9IHRoaXMubGFiZWw7XHJcbiAgICAgICAgLy8gdGhpcy5jb21wb25lbnRSZWYuaW5zdGFuY2UudmFsdWUgPSB0aGlzLnZhbHVlO1xyXG4gICAgICAgIHRoaXMuY29tcG9uZW50UmVmLmluc3RhbmNlLmRhdGVWYWx1ZSA9IHRoaXMuZGF0ZVZhbHVlO1xyXG4gICAgICAgIHRoaXMuY29tcG9uZW50UmVmLmluc3RhbmNlLnBsYWNlaG9sZGVyID0gdGhpcy5wbGFjZWhvbGRlcjtcclxuICAgICAgICB0aGlzLmNvbXBvbmVudFJlZi5pbnN0YW5jZS5taW4gPSB0aGlzLm1pbjtcclxuICAgICAgICB0aGlzLmNvbXBvbmVudFJlZi5pbnN0YW5jZS5tYXggPSB0aGlzLm1heDtcclxuICAgICAgICB0aGlzLmNvbXBvbmVudFJlZi5pbnN0YW5jZS5kYXRlRm9ybWF0ID0gdGhpcy5kYXRlRm9ybWF0O1xyXG5cclxuICAgICAgICAvLyBIYW5kbGUgb3V0cHV0c1xyXG4gICAgICAgIC8vIHRoaXMuY29tcG9uZW50UmVmLmluc3RhbmNlLnZhbHVlQ2hhbmdlLnN1YnNjcmliZSgodmFsdWU6IHN0cmluZyB8IG51bGwpID0+IHtcclxuICAgICAgICAvLyAgICAgdGhpcy5yZW5kZXJlci5zZXRQcm9wZXJ0eSh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQsICd2YWx1ZScsIHZhbHVlID8/IHRoaXMucGxhY2Vob2xkZXIgPz8gdGhpcy5kYXRlRm9ybWF0KTtcclxuICAgICAgICAvLyAgICAgaWYgKHZhbHVlID09PSB0aGlzLnZhbHVlKSByZXR1cm5cclxuICAgICAgICAvLyAgICAgdGhpcy52YWx1ZUNoYW5nZS5lbWl0KHZhbHVlKTtcclxuICAgICAgICAvLyB9KTtcclxuICAgICAgICB0aGlzLmNvbXBvbmVudFJlZi5pbnN0YW5jZS5kYXRlVmFsdWVDaGFuZ2Uuc3Vic2NyaWJlKChkYXRlOiBEYXRlIHwgbnVsbCkgPT4ge1xyXG4gICAgICAgICAgICAvLyBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgLy8gICAgIHRoaXMudmFsdWUgPSB0aGlzLmNvbXBvbmVudFJlZi5pbnN0YW5jZS5mb3JtYXREYXRlKCk7XHJcbiAgICAgICAgICAgIC8vIH0pO1xyXG4gICAgICAgICAgICBjb25zdCBldCA9IGRhdGUgIT09IG51bGwgPyB0aGlzLmNvbXBvbmVudFJlZi5pbnN0YW5jZS5mb3JtYXREYXRlKCkgOiBudWxsO1xyXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFByb3BlcnR5KHRoaXMuZWwubmF0aXZlRWxlbWVudCwgJ3ZhbHVlJywgZXQgPz8gdGhpcy5wbGFjZWhvbGRlciA/PyB0aGlzLmRhdGVGb3JtYXQpO1xyXG4gICAgICAgICAgICAvLyB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQodGhpcy52YWx1ZSk7XHJcbiAgICAgICAgICAgIHRoaXMuZGF0ZVZhbHVlQ2hhbmdlLmVtaXQoZGF0ZSk7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdChldCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5jb21wb25lbnRSZWYuaW5zdGFuY2UuZW1pdENoYW5nZSgpO1xyXG5cclxuICAgICAgICAvLyBBcHBlbmQgdG8gdGhlIGlucHV0J3MgcGFyZW50IChub3QgZG9jdW1lbnQuYm9keSlcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLmFwcGVuZENoaWxkKHRoaXMuZWwubmF0aXZlRWxlbWVudC5wYXJlbnRFbGVtZW50LCB0aGlzLmNhbGVuZGFyRWxlbWVudCk7XHJcbiAgICAgICAgLy8gfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgY2xvc2VDYWxlbmRhcigpIHtcclxuICAgICAgICB0aGlzLmNvbXBvbmVudFJlZi5kZXN0cm95KCk7XHJcbiAgICB9XHJcbn1cclxuIl19