ngx-obelisco-example
Version:
Componentes funcionales y reutilizables para Angular.
184 lines • 36.2 kB
JavaScript
import { Component, Input } from '@angular/core';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
export class OCalendarComponent {
constructor() {
this.activeDays = [];
this.isCollapsed = false;
this.hasList = true;
this.customClasses = '';
this.month = null;
this.year = null;
this.start = 0;
this.MONTH_TITLE = [
'Enero',
'Febrero',
'Marzo',
'Abril',
'Mayo',
'Junio',
'Julio',
'Agosto',
'Septiembre',
'Octubre',
'Noviembre',
'Diciembre'
];
this.DAYS_HEADER_TABLE = ['D', 'L', 'M', 'M', 'J', 'V', 'S'];
this.daysArray = [];
this.emptyDaysArray = [];
this.firstWeekDays = 0;
this.firstWeekDaysArray = [];
this.weekDaysArray = [];
this.analizedActiveDays = [];
//Define número de días por mes
this.monthAmountOfDays = (month, year) => {
if (typeof month !== 'number' || month < 1 || month > 12) {
return 0;
}
if (month === 4 || month === 6 || month === 9 || month === 11) {
return 30;
}
else if (month === 2) {
return (year ? year : 2024) % 4 === 0 ? 29 : 28;
}
else {
return 31;
}
};
//Define texto del mes
this.monthsTitles = (month) => {
if (month && month >= 1 && month <= 12) {
return this.MONTH_TITLE[month - 1];
}
else {
return 'Mes inválido';
}
};
}
//Determina el dia de la semana en que empieza del mes de determinado año
getStartDayOfMonth(year, month) {
const firstDayOfMonth = new Date(year, month - 1, 1);
const dayOfWeek = firstDayOfMonth.getDay();
this.start = dayOfWeek;
return this.start;
}
// Genera filas de 7 días cada una
get weekDaysArrayRows() {
const rows = [];
const rowSize = 7;
const arrayLength = this.weekDaysArray.length;
let counter = 0;
for (let i = 0; i < arrayLength; i += rowSize) {
rows.push(this.weekDaysArray.slice(i, i + rowSize));
counter += 1;
}
// Se añaden elementos vacios si es necesario para completar la última fila
const lastChunkLength = rows[rows.length - 1].length;
if (lastChunkLength < rowSize) {
const remainingSpecials = rowSize - lastChunkLength;
for (let i = 0; i < remainingSpecials; i++) {
rows[rows.length - 1].push(-1);
}
}
return { rows, counter };
}
//Evalua si hay numeros de activeDays que coincidan
isActiveDay(day) {
return !!this.analizedActiveDays?.find((activeDay) => activeDay.day === day);
}
getActiveDay(day) {
return this.analizedActiveDays?.find((activeDay) => activeDay.day === day);
}
//Convierte array de days en objetos
convertArrayIntoObject(objeto) {
const dayArray = objeto.day;
if (Array.isArray(dayArray)) {
return dayArray.map((day) => ({
...objeto,
day: day
}));
}
else {
return [objeto];
}
}
//Evalua cada activeDay
generateArrayActiveDays(activeDays) {
for (const key in activeDays) {
if (Object.prototype.hasOwnProperty.call(activeDays, key)) {
const element = activeDays[key];
if (typeof element.day == 'number') {
this.analizedActiveDays.push(element);
}
else {
for (const obj of this.convertArrayIntoObject(element)) {
this.analizedActiveDays.push(obj);
}
}
}
}
return this.analizedActiveDays;
}
//Obtiene clase de cada activeDay acorde al type
getClassByType(type) {
if (type == undefined) {
return 'active';
}
else if (type == 'secondary') {
return 'active-secondary';
}
else {
return `active bg-${type}`;
}
}
//Obtiene el tipo de day y lo asigna a la lista
typeOfDays(day) {
if (!day) {
return '';
}
else if (typeof day === 'number') {
return `${day}.`;
}
else {
if (day.length > 2) {
return `${day[0]} al ${day[day.length - 1]}.`;
}
else {
return `${day[0]}, ${day[day.length - 1]}.`;
}
}
}
ngOnInit() {
if (this.date) {
this.month = this.date.month;
this.year = this.date.year;
}
this.getStartDayOfMonth(this.year, this.month);
this.daysArray = Array.from({ length: this.monthAmountOfDays(this.month, this.year) }, (_, index) => index + 1);
this.emptyDaysArray = this.start < 7 ? Array.from({ length: this.start }, (_, index) => ({ key: index })) : [];
this.firstWeekDays = 7 - this.start;
this.firstWeekDaysArray = this.daysArray.slice(0, this.firstWeekDays);
this.weekDaysArray = this.daysArray.slice(this.firstWeekDays);
if (this.activeDays) {
this.generateArrayActiveDays(this.activeDays);
}
}
}
OCalendarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: OCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
OCalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: OCalendarComponent, selector: "o-calendar", inputs: { date: "date", activeDays: "activeDays", isCollapsed: "isCollapsed", hasList: "hasList", customClasses: "customClasses" }, ngImport: i0, template: "<div class=\"calendar\" [ngClass]=\"customClasses\">\r\n <div class=\"calendar-header\">\r\n <h2 class=\"calendar-title\">{{ monthsTitles(month!) }}</h2>\r\n <span class=\"calendar-year\">{{ year }}</span>\r\n </div>\r\n <div class=\"calendar-body\">\r\n <table>\r\n <thead>\r\n <tr class=\"calendar-week-header\">\r\n <th *ngFor=\"let day of DAYS_HEADER_TABLE\">\r\n <span>{{ day }}</span>\r\n </th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr class=\"calendar-week\">\r\n <ng-container *ngIf=\"emptyDaysArray.length != 0\">\r\n <td *ngFor=\"let empatyDay of emptyDaysArray\"></td>\r\n </ng-container>\r\n <td *ngFor=\"let day of firstWeekDaysArray\">\r\n <ng-container *ngTemplateOutlet=\"activeDay; context: { day: day }\"></ng-container>\r\n </td>\r\n </tr>\r\n\r\n <tr class=\"calendar-week\" *ngFor=\"let chunkObject of weekDaysArrayRows.rows\">\r\n <ng-container *ngFor=\"let day of chunkObject; let i = index\">\r\n <td>\r\n <ng-container *ngIf=\"day >= 0\">\r\n <ng-container *ngTemplateOutlet=\"activeDay; context: { day: day }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"day < 0\">\r\n <span></span>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n <tr class=\"calendar-week\" *ngIf=\"weekDaysArrayRows.counter === 4\">\r\n <td *ngFor=\"let _ of [1, 2, 3, 4, 5, 6, 7]\">\r\n <span></span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n <div class=\"calendar-footer\" *ngIf=\"activeDays && hasList\">\r\n <ng-container *ngIf=\"isCollapsed; else calendarList\">\r\n <div class=\"accordion\">\r\n <div class=\"card\">\r\n <button\r\n class=\"card-header collapsed\"\r\n data-toggle=\"collapse\"\r\n [attr.data-target]=\"'#collapse' + monthsTitles(month!)\"\r\n >\r\n <i class=\"bx bx-calendar\"></i>\r\n <span class=\"collapse-title\">Referencias</span>\r\n </button>\r\n <div id=\"collapse{{ monthsTitles(month!) }}\" class=\"collapse\">\r\n <div class=\"card-body\">\r\n <ng-container *ngTemplateOutlet=\"calendarList\"></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n</div>\r\n\r\n<ng-template #calendarList>\r\n <ul class=\"calendar-footer-list\">\r\n <li *ngFor=\"let activeDay of activeDays\">\r\n <strong>\r\n {{ typeOfDays(activeDay.day) }}\r\n </strong>\r\n {{ activeDay.title }}\r\n </li>\r\n </ul>\r\n</ng-template>\r\n\r\n<ng-template #activeDay let-day=\"day\">\r\n <ng-container *ngIf=\"isActiveDay(day); else notActive\">\r\n <a\r\n *ngIf=\"getActiveDay(day)?.url != undefined; else activeNoLink\"\r\n href=\"{{ getActiveDay(day)?.url }}\"\r\n class=\"calendar-link\"\r\n title=\"{{ getActiveDay(day)?.title }}\"\r\n [class.disabled]=\"getActiveDay(day)?.isDisabled\"\r\n (click)=\"getActiveDay(day)?.isDisabled && $event.preventDefault()\"\r\n >\r\n <span [ngClass]=\"getClassByType(getActiveDay(day)?.type)\">{{ day }}</span>\r\n </a>\r\n <ng-template #activeNoLink>\r\n <span title=\"{{ getActiveDay(day)?.title }}\" [class.disabled]=\"getActiveDay(day)?.isDisabled\">\r\n <span [ngClass]=\"getClassByType(getActiveDay(day)?.type)\">{{ day }}</span>\r\n </span>\r\n </ng-template>\r\n </ng-container>\r\n <ng-template #notActive>\r\n <span>{{ day }}</span>\r\n </ng-template>\r\n</ng-template>\r\n", styles: [".calendar .calendar-body table .calendar-week td .calendar-link.disabled,.calendar .calendar-body table .calendar-week td>span.disabled{cursor:not-allowed;pointer-events:none}.calendar .calendar-body table .calendar-week td .calendar-link.disabled span,.calendar .calendar-body table .calendar-week td>span.disabled span{background-color:transparent!important;color:#9eaab8}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: OCalendarComponent, decorators: [{
type: Component,
args: [{ selector: 'o-calendar', template: "<div class=\"calendar\" [ngClass]=\"customClasses\">\r\n <div class=\"calendar-header\">\r\n <h2 class=\"calendar-title\">{{ monthsTitles(month!) }}</h2>\r\n <span class=\"calendar-year\">{{ year }}</span>\r\n </div>\r\n <div class=\"calendar-body\">\r\n <table>\r\n <thead>\r\n <tr class=\"calendar-week-header\">\r\n <th *ngFor=\"let day of DAYS_HEADER_TABLE\">\r\n <span>{{ day }}</span>\r\n </th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr class=\"calendar-week\">\r\n <ng-container *ngIf=\"emptyDaysArray.length != 0\">\r\n <td *ngFor=\"let empatyDay of emptyDaysArray\"></td>\r\n </ng-container>\r\n <td *ngFor=\"let day of firstWeekDaysArray\">\r\n <ng-container *ngTemplateOutlet=\"activeDay; context: { day: day }\"></ng-container>\r\n </td>\r\n </tr>\r\n\r\n <tr class=\"calendar-week\" *ngFor=\"let chunkObject of weekDaysArrayRows.rows\">\r\n <ng-container *ngFor=\"let day of chunkObject; let i = index\">\r\n <td>\r\n <ng-container *ngIf=\"day >= 0\">\r\n <ng-container *ngTemplateOutlet=\"activeDay; context: { day: day }\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"day < 0\">\r\n <span></span>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n <tr class=\"calendar-week\" *ngIf=\"weekDaysArrayRows.counter === 4\">\r\n <td *ngFor=\"let _ of [1, 2, 3, 4, 5, 6, 7]\">\r\n <span></span>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n <div class=\"calendar-footer\" *ngIf=\"activeDays && hasList\">\r\n <ng-container *ngIf=\"isCollapsed; else calendarList\">\r\n <div class=\"accordion\">\r\n <div class=\"card\">\r\n <button\r\n class=\"card-header collapsed\"\r\n data-toggle=\"collapse\"\r\n [attr.data-target]=\"'#collapse' + monthsTitles(month!)\"\r\n >\r\n <i class=\"bx bx-calendar\"></i>\r\n <span class=\"collapse-title\">Referencias</span>\r\n </button>\r\n <div id=\"collapse{{ monthsTitles(month!) }}\" class=\"collapse\">\r\n <div class=\"card-body\">\r\n <ng-container *ngTemplateOutlet=\"calendarList\"></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n</div>\r\n\r\n<ng-template #calendarList>\r\n <ul class=\"calendar-footer-list\">\r\n <li *ngFor=\"let activeDay of activeDays\">\r\n <strong>\r\n {{ typeOfDays(activeDay.day) }}\r\n </strong>\r\n {{ activeDay.title }}\r\n </li>\r\n </ul>\r\n</ng-template>\r\n\r\n<ng-template #activeDay let-day=\"day\">\r\n <ng-container *ngIf=\"isActiveDay(day); else notActive\">\r\n <a\r\n *ngIf=\"getActiveDay(day)?.url != undefined; else activeNoLink\"\r\n href=\"{{ getActiveDay(day)?.url }}\"\r\n class=\"calendar-link\"\r\n title=\"{{ getActiveDay(day)?.title }}\"\r\n [class.disabled]=\"getActiveDay(day)?.isDisabled\"\r\n (click)=\"getActiveDay(day)?.isDisabled && $event.preventDefault()\"\r\n >\r\n <span [ngClass]=\"getClassByType(getActiveDay(day)?.type)\">{{ day }}</span>\r\n </a>\r\n <ng-template #activeNoLink>\r\n <span title=\"{{ getActiveDay(day)?.title }}\" [class.disabled]=\"getActiveDay(day)?.isDisabled\">\r\n <span [ngClass]=\"getClassByType(getActiveDay(day)?.type)\">{{ day }}</span>\r\n </span>\r\n </ng-template>\r\n </ng-container>\r\n <ng-template #notActive>\r\n <span>{{ day }}</span>\r\n </ng-template>\r\n</ng-template>\r\n", styles: [".calendar .calendar-body table .calendar-week td .calendar-link.disabled,.calendar .calendar-body table .calendar-week td>span.disabled{cursor:not-allowed;pointer-events:none}.calendar .calendar-body table .calendar-week td .calendar-link.disabled span,.calendar .calendar-body table .calendar-week td>span.disabled span{background-color:transparent!important;color:#9eaab8}\n"] }]
}], ctorParameters: function () { return []; }, propDecorators: { date: [{
type: Input
}], activeDays: [{
type: Input
}], isCollapsed: [{
type: Input
}], hasList: [{
type: Input
}], customClasses: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiby1jYWxlbmRhci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtb2JlbGlzY28vY2FsZW5kYXIvby1jYWxlbmRhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtb2JlbGlzY28vY2FsZW5kYXIvby1jYWxlbmRhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBVSxNQUFNLGVBQWUsQ0FBQzs7O0FBUXpELE1BQU0sT0FBTyxrQkFBa0I7SUF3SjdCO1FBdEpnQixlQUFVLEdBQWdCLEVBQUUsQ0FBQztRQUM3QixnQkFBVyxHQUFZLEtBQUssQ0FBQztRQUM3QixZQUFPLEdBQVksSUFBSSxDQUFDO1FBQ3hCLGtCQUFhLEdBQVcsRUFBRSxDQUFDO1FBRXBDLFVBQUssR0FBa0IsSUFBSSxDQUFDO1FBQzVCLFNBQUksR0FBa0IsSUFBSSxDQUFDO1FBQzNCLFVBQUssR0FBVyxDQUFDLENBQUM7UUFDbEIsZ0JBQVcsR0FBRztZQUNuQixPQUFPO1lBQ1AsU0FBUztZQUNULE9BQU87WUFDUCxPQUFPO1lBQ1AsTUFBTTtZQUNOLE9BQU87WUFDUCxPQUFPO1lBQ1AsUUFBUTtZQUNSLFlBQVk7WUFDWixTQUFTO1lBQ1QsV0FBVztZQUNYLFdBQVc7U0FDWixDQUFDO1FBQ0ssc0JBQWlCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN4RCxjQUFTLEdBQWEsRUFBRSxDQUFDO1FBQ3pCLG1CQUFjLEdBQVUsRUFBRSxDQUFDO1FBQzNCLGtCQUFhLEdBQVcsQ0FBQyxDQUFDO1FBQzFCLHVCQUFrQixHQUFhLEVBQUUsQ0FBQztRQUNsQyxrQkFBYSxHQUFhLEVBQUUsQ0FBQztRQUM3Qix1QkFBa0Is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OytCQUNFLFlBQVk7MEVBS04sSUFBSTtzQkFBbkIsS0FBSztnQkFDVSxVQUFVO3NCQUF6QixLQUFLO2dCQUNVLFdBQVc7c0JBQTFCLEtBQUs7Z0JBQ1UsT0FBTztzQkFBdEIsS0FBSztnQkFDVSxhQUFhO3NCQUE1QixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEFjdGl2ZURheSwgQ2FsZW5kYXJEYXRlIH0gZnJvbSAnbmd4LW9iZWxpc2NvLWV4YW1wbGUvY29yZS9tb2RlbHMnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdvLWNhbGVuZGFyJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vby1jYWxlbmRhci5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vby1jYWxlbmRhci5jb21wb25lbnQuc2NzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBPQ2FsZW5kYXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBkYXRlITogQ2FsZW5kYXJEYXRlO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBhY3RpdmVEYXlzOiBBY3RpdmVEYXlbXSA9IFtdO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBpc0NvbGxhcHNlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBoYXNMaXN0OiBib29sZWFuID0gdHJ1ZTtcclxuICBASW5wdXQoKSBwdWJsaWMgY3VzdG9tQ2xhc3Nlczogc3RyaW5nID0gJyc7XHJcblxyXG4gIHB1YmxpYyBtb250aDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XHJcbiAgcHVibGljIHllYXI6IG51bWJlciB8IG51bGwgPSBudWxsO1xyXG4gIHB1YmxpYyBzdGFydDogbnVtYmVyID0gMDtcclxuICBwdWJsaWMgTU9OVEhfVElUTEUgPSBbXHJcbiAgICAnRW5lcm8nLFxyXG4gICAgJ0ZlYnJlcm8nLFxyXG4gICAgJ01hcnpvJyxcclxuICAgICdBYnJpbCcsXHJcbiAgICAnTWF5bycsXHJcbiAgICAnSnVuaW8nLFxyXG4gICAgJ0p1bGlvJyxcclxuICAgICdBZ29zdG8nLFxyXG4gICAgJ1NlcHRpZW1icmUnLFxyXG4gICAgJ09jdHVicmUnLFxyXG4gICAgJ05vdmllbWJyZScsXHJcbiAgICAnRGljaWVtYnJlJ1xyXG4gIF07XHJcbiAgcHVibGljIERBWVNfSEVBREVSX1RBQkxFID0gWydEJywgJ0wnLCAnTScsICdNJywgJ0onLCAnVicsICdTJ107XHJcbiAgcHVibGljIGRheXNBcnJheTogbnVtYmVyW10gPSBbXTtcclxuICBwdWJsaWMgZW1wdHlEYXlzQXJyYXk6IGFueVtdID0gW107XHJcbiAgcHVibGljIGZpcnN0V2Vla0RheXM6IG51bWJlciA9IDA7XHJcbiAgcHVibGljIGZpcnN0V2Vla0RheXNBcnJheTogbnVtYmVyW10gPSBbXTtcclxuICBwdWJsaWMgd2Vla0RheXNBcnJheTogbnVtYmVyW10gPSBbXTtcclxuICBwdWJsaWMgYW5hbGl6ZWRBY3RpdmVEYXlzOiBBY3RpdmVEYXlbXSA9IFtdO1xyXG5cclxuICAvL0RldGVybWluYSBlbCBkaWEgZGUgbGEgc2VtYW5hIGVuIHF1ZSBlbXBpZXphIGRlbCBtZXMgZGUgZGV0ZXJtaW5hZG8gYcOxb1xyXG4gIGdldFN0YXJ0RGF5T2ZNb250aCh5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgY29uc3QgZmlyc3REYXlPZk1vbnRoID0gbmV3IERhdGUoeWVhciwgbW9udGggLSAxLCAxKTtcclxuICAgIGNvbnN0IGRheU9mV2VlayA9IGZpcnN0RGF5T2ZNb250aC5nZXREYXkoKTtcclxuICAgIHRoaXMuc3RhcnQgPSBkYXlPZldlZWs7XHJcbiAgICByZXR1cm4gdGhpcy5zdGFydDtcclxuICB9XHJcblxyXG4gIC8vRGVmaW5lIG7Dum1lcm8gZGUgZMOtYXMgcG9yIG1lc1xyXG4gIHB1YmxpYyBtb250aEFtb3VudE9mRGF5cyA9IChtb250aDogbnVtYmVyLCB5ZWFyPzogbnVtYmVyKTogbnVtYmVyID0+IHtcclxuICAgIGlmICh0eXBlb2YgbW9udGggIT09ICdudW1iZXInIHx8IG1vbnRoIDwgMSB8fCBtb250aCA+IDEyKSB7XHJcbiAgICAgIHJldHVybiAwO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChtb250aCA9PT0gNCB8fCBtb250aCA9PT0gNiB8fCBtb250aCA9PT0gOSB8fCBtb250aCA9PT0gMTEpIHtcclxuICAgICAgcmV0dXJuIDMwO1xyXG4gICAgfSBlbHNlIGlmIChtb250aCA9PT0gMikge1xyXG4gICAgICByZXR1cm4gKHllYXIgPyB5ZWFyIDogMjAyNCkgJSA0ID09PSAwID8gMjkgOiAyODtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiAzMTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICAvL0RlZmluZSB0ZXh0byBkZWwgbWVzXHJcbiAgcHVibGljIG1vbnRoc1RpdGxlcyA9IChtb250aD86IG51bWJlcikgPT4ge1xyXG4gICAgaWYgKG1vbnRoICYmIG1vbnRoID49IDEgJiYgbW9udGggPD0gMTIpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuTU9OVEhfVElUTEVbbW9udGggLSAxXTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiAnTWVzIGludsOhbGlkbyc7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgLy8gR2VuZXJhIGZpbGFzIGRlIDcgZMOtYXMgY2FkYSB1bmFcclxuICBnZXQgd2Vla0RheXNBcnJheVJvd3MoKTogeyByb3dzOiBudW1iZXJbXVtdOyBjb3VudGVyOiBudW1iZXIgfSB7XHJcbiAgICBjb25zdCByb3dzOiBudW1iZXJbXVtdID0gW107XHJcbiAgICBjb25zdCByb3dTaXplID0gNztcclxuICAgIGNvbnN0IGFycmF5TGVuZ3RoID0gdGhpcy53ZWVrRGF5c0FycmF5Lmxlbmd0aDtcclxuICAgIGxldCBjb3VudGVyOiBudW1iZXIgPSAwO1xyXG5cclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXlMZW5ndGg7IGkgKz0gcm93U2l6ZSkge1xyXG4gICAgICByb3dzLnB1c2godGhpcy53ZWVrRGF5c0FycmF5LnNsaWNlKGksIGkgKyByb3dTaXplKSk7XHJcbiAgICAgIGNvdW50ZXIgKz0gMTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBTZSBhw7FhZGVuIGVsZW1lbnRvcyB2YWNpb3Mgc2kgZXMgbmVjZXNhcmlvIHBhcmEgY29tcGxldGFyIGxhIMO6bHRpbWEgZmlsYVxyXG4gICAgY29uc3QgbGFzdENodW5rTGVuZ3RoID0gcm93c1tyb3dzLmxlbmd0aCAtIDFdLmxlbmd0aDtcclxuICAgIGlmIChsYXN0Q2h1bmtMZW5ndGggPCByb3dTaXplKSB7XHJcbiAgICAgIGNvbnN0IHJlbWFpbmluZ1NwZWNpYWxzID0gcm93U2l6ZSAtIGxhc3RDaHVua0xlbmd0aDtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZW1haW5pbmdTcGVjaWFsczsgaSsrKSB7XHJcbiAgICAgICAgcm93c1tyb3dzLmxlbmd0aCAtIDFdLnB1c2goLTEpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4geyByb3dzLCBjb3VudGVyIH07XHJcbiAgfVxyXG5cclxuICAvL0V2YWx1YSBzaSBoYXkgbnVtZXJvcyBkZSBhY3RpdmVEYXlzIHF1ZSBjb2luY2lkYW5cclxuICBpc0FjdGl2ZURheShkYXk6IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuICEhdGhpcy5hbmFsaXplZEFjdGl2ZURheXM/LmZpbmQoKGFjdGl2ZURheSkgPT4gYWN0aXZlRGF5LmRheSA9PT0gZGF5KTtcclxuICB9XHJcblxyXG4gIGdldEFjdGl2ZURheShkYXk6IG51bWJlcik6IEFjdGl2ZURheSB8IHVuZGVmaW5lZCB7XHJcbiAgICByZXR1cm4gdGhpcy5hbmFsaXplZEFjdGl2ZURheXM/LmZpbmQoKGFjdGl2ZURheSkgPT4gYWN0aXZlRGF5LmRheSA9PT0gZGF5KTtcclxuICB9XHJcblxyXG4gIC8vQ29udmllcnRlIGFycmF5IGRlIGRheXMgZW4gb2JqZXRvc1xyXG4gIGNvbnZlcnRBcnJheUludG9PYmplY3Qob2JqZXRvOiBhbnkpOiBhbnlbXSB7XHJcbiAgICBjb25zdCBkYXlBcnJheSA9IG9iamV0by5kYXk7XHJcbiAgICBpZiAoQXJyYXkuaXNBcnJheShkYXlBcnJheSkpIHtcclxuICAgICAgcmV0dXJuIGRheUFycmF5Lm1hcCgoZGF5KSA9PiAoe1xyXG4gICAgICAgIC4uLm9iamV0byxcclxuICAgICAgICBkYXk6IGRheVxyXG4gICAgICB9KSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gW29iamV0b107XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvL0V2YWx1YSBjYWRhIGFjdGl2ZURheVxyXG4gIGdlbmVyYXRlQXJyYXlBY3RpdmVEYXlzKGFjdGl2ZURheXM6IEFjdGl2ZURheVtdKTogQWN0aXZlRGF5W10gfCB1bmRlZmluZWQge1xyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gYWN0aXZlRGF5cykge1xyXG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGFjdGl2ZURheXMsIGtleSkpIHtcclxuICAgICAgICBjb25zdCBlbGVtZW50ID0gYWN0aXZlRGF5c1trZXldO1xyXG4gICAgICAgIGlmICh0eXBlb2YgZWxlbWVudC5kYXkgPT0gJ251bWJlcicpIHtcclxuICAgICAgICAgIHRoaXMuYW5hbGl6ZWRBY3RpdmVEYXlzLnB1c2goZWxlbWVudCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGZvciAoY29uc3Qgb2JqIG9mIHRoaXMuY29udmVydEFycmF5SW50b09iamVjdChlbGVtZW50KSkge1xyXG4gICAgICAgICAgICB0aGlzLmFuYWxpemVkQWN0aXZlRGF5cy5wdXNoKG9iaik7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5hbmFsaXplZEFjdGl2ZURheXM7XHJcbiAgfVxyXG5cclxuICAvL09idGllbmUgY2xhc2UgZGUgY2FkYSBhY3RpdmVEYXkgYWNvcmRlIGFsIHR5cGVcclxuICBnZXRDbGFzc0J5VHlwZSh0eXBlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xyXG4gICAgaWYgKHR5cGUgPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIHJldHVybiAnYWN0aXZlJztcclxuICAgIH0gZWxzZSBpZiAodHlwZSA9PSAnc2Vjb25kYXJ5Jykge1xyXG4gICAgICByZXR1cm4gJ2FjdGl2ZS1zZWNvbmRhcnknO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIGBhY3RpdmUgYmctJHt0eXBlfWA7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvL09idGllbmUgZWwgdGlwbyBkZSBkYXkgeSBsbyBhc2lnbmEgYSBsYSBsaXN0YVxyXG4gIHR5cGVPZkRheXMoZGF5OiBudW1iZXIgfCBudW1iZXJbXSB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XHJcbiAgICBpZiAoIWRheSkge1xyXG4gICAgICByZXR1cm4gJyc7XHJcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXkgPT09ICdudW1iZXInKSB7XHJcbiAgICAgIHJldHVybiBgJHtkYXl9LmA7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAoZGF5Lmxlbmd0aCA+IDIpIHtcclxuICAgICAgICByZXR1cm4gYCR7ZGF5WzBdfSBhbCAke2RheVtkYXkubGVuZ3RoIC0gMV19LmA7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIGAke2RheVswXX0sICR7ZGF5W2RheS5sZW5ndGggLSAxXX0uYDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IoKSB7fVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmRhdGUpIHtcclxuICAgICAgdGhpcy5tb250aCA9IHRoaXMuZGF0ZS5tb250aDtcclxuICAgICAgdGhpcy55ZWFyID0gdGhpcy5kYXRlLnllYXI7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5nZXRTdGFydERheU9mTW9udGgodGhpcy55ZWFyISwgdGhpcy5tb250aCEpO1xyXG5cclxuICAgIHRoaXMuZGF5c0FycmF5ID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogdGhpcy5tb250aEFtb3VudE9mRGF5cyh0aGlzLm1vbnRoISwgdGhpcy55ZWFyISkgfSwgKF8sIGluZGV4KSA9PiBpbmRleCArIDEpO1xyXG5cclxuICAgIHRoaXMuZW1wdHlEYXlzQXJyYXkgPSB0aGlzLnN0YXJ0IDwgNyA/IEFycmF5LmZyb20oeyBsZW5ndGg6IHRoaXMuc3RhcnQgfSwgKF8sIGluZGV4KSA9PiAoeyBrZXk6IGluZGV4IH0pKSA6IFtdO1xyXG5cclxuICAgIHRoaXMuZmlyc3RXZWVrRGF5cyA9IDcgLSB0aGlzLnN0YXJ0O1xyXG5cclxuICAgIHRoaXMuZmlyc3RXZWVrRGF5c0FycmF5ID0gdGhpcy5kYXlzQXJyYXkuc2xpY2UoMCwgdGhpcy5maXJzdFdlZWtEYXlzKTtcclxuXHJcbiAgICB0aGlzLndlZWtEYXlzQXJyYXkgPSB0aGlzLmRheXNBcnJheS5zbGljZSh0aGlzLmZpcnN0V2Vla0RheXMpO1xyXG5cclxuICAgIGlmICh0aGlzLmFjdGl2ZURheXMpIHtcclxuICAgICAgdGhpcy5nZW5lcmF0ZUFycmF5QWN0aXZlRGF5cyh0aGlzLmFjdGl2ZURheXMpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwiY2FsZW5kYXJcIiBbbmdDbGFzc109XCJjdXN0b21DbGFzc2VzXCI+XHJcbiAgPGRpdiBjbGFzcz1cImNhbGVuZGFyLWhlYWRlclwiPlxyXG4gICAgPGgyIGNsYXNzPVwiY2FsZW5kYXItdGl0bGVcIj57eyBtb250aHNUaXRsZXMobW9udGghKSB9fTwvaDI+XHJcbiAgICA8c3BhbiBjbGFzcz1cImNhbGVuZGFyLXllYXJcIj57eyB5ZWFyIH19PC9zcGFuPlxyXG4gIDwvZGl2PlxyXG4gIDxkaXYgY2xhc3M9XCJjYWxlbmRhci1ib2R5XCI+XHJcbiAgICA8dGFibGU+XHJcbiAgICAgIDx0aGVhZD5cclxuICAgICAgICA8dHIgY2xhc3M9XCJjYWxlbmRhci13ZWVrLWhlYWRlclwiPlxyXG4gICAgICAgICAgPHRoICpuZ0Zvcj1cImxldCBkYXkgb2YgREFZU19IRUFERVJfVEFCTEVcIj5cclxuICAgICAgICAgICAgPHNwYW4+e3sgZGF5IH19PC9zcGFuPlxyXG4gICAgICAgICAgPC90aD5cclxuICAgICAgICA8L3RyPlxyXG4gICAgICA8L3RoZWFkPlxyXG4gICAgICA8dGJvZHk+XHJcbiAgICAgICAgPHRyIGNsYXNzPVwiY2FsZW5kYXItd2Vla1wiPlxyXG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImVtcHR5RGF5c0FycmF5Lmxlbmd0aCAhPSAwXCI+XHJcbiAgICAgICAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgZW1wYXR5RGF5IG9mIGVtcHR5RGF5c0FycmF5XCI+PC90ZD5cclxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgPHRkICpuZ0Zvcj1cImxldCBkYXkgb2YgZmlyc3RXZWVrRGF5c0FycmF5XCI+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJhY3RpdmVEYXk7IGNvbnRleHQ6IHsgZGF5OiBkYXkgfVwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgPC90ZD5cclxuICAgICAgICA8L3RyPlxyXG5cclxuICAgICAgICA8dHIgY2xhc3M9XCJjYWxlbmRhci13ZWVrXCIgKm5nRm9yPVwibGV0IGNodW5rT2JqZWN0IG9mIHdlZWtEYXlzQXJyYXlSb3dzLnJvd3NcIj5cclxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGRheSBvZiBjaHVua09iamVjdDsgbGV0IGkgPSBpbmRleFwiPlxyXG4gICAgICAgICAgICA8dGQ+XHJcbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImRheSA+PSAwXCI+XHJcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYWN0aXZlRGF5OyBjb250ZXh0OiB7IGRheTogZGF5IH1cIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZGF5IDwgMFwiPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4+PC9zcGFuPlxyXG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPC90cj5cclxuICAgICAgICA8dHIgY2xhc3M9XCJjYWxlbmRhci13ZWVrXCIgKm5nSWY9XCJ3ZWVrRGF5c0FycmF5Um93cy5jb3VudGVyID09PSA0XCI+XHJcbiAgICAgICAgICA8dGQgKm5nRm9yPVwibGV0IF8gb2YgWzEsIDIsIDMsIDQsIDUsIDYsIDddXCI+XHJcbiAgICAgICAgICAgIDxzcGFuPjwvc3Bhbj5cclxuICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgPC90cj5cclxuICAgICAgPC90Ym9keT5cclxuICAgIDwvdGFibGU+XHJcbiAgPC9kaXY+XHJcbiAgPGRpdiBjbGFzcz1cImNhbGVuZGFyLWZvb3RlclwiICpuZ0lmPVwiYWN0aXZlRGF5cyAmJiBoYXNMaXN0XCI+XHJcbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNDb2xsYXBzZWQ7IGVsc2UgY2FsZW5kYXJMaXN0XCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJhY2NvcmRpb25cIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZFwiPlxyXG4gICAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgICBjbGFzcz1cImNhcmQtaGVhZGVyIGNvbGxhcHNlZFwiXHJcbiAgICAgICAgICAgIGRhdGEtdG9nZ2xlPVwiY29sbGFwc2VcIlxyXG4gICAgICAgICAgICBbYXR0ci5kYXRhLXRhcmdldF09XCInI2NvbGxhcHNlJyArIG1vbnRoc1RpdGxlcyhtb250aCEpXCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPGkgY2xhc3M9XCJieCBieC1jYWxlbmRhclwiPjwvaT5cclxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb2xsYXBzZS10aXRsZVwiPlJlZmVyZW5jaWFzPC9zcGFuPlxyXG4gICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICA8ZGl2IGlkPVwiY29sbGFwc2V7eyBtb250aHNUaXRsZXMobW9udGghKSB9fVwiIGNsYXNzPVwiY29sbGFwc2VcIj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtYm9keVwiPlxyXG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjYWxlbmRhckxpc3RcIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L25nLWNvbnRhaW5lcj5cclxuICA8L2Rpdj5cclxuPC9kaXY+XHJcblxyXG48bmctdGVtcGxhdGUgI2NhbGVuZGFyTGlzdD5cclxuICA8dWwgY2xhc3M9XCJjYWxlbmRhci1mb290ZXItbGlzdFwiPlxyXG4gICAgPGxpICpuZ0Zvcj1cImxldCBhY3RpdmVEYXkgb2YgYWN0aXZlRGF5c1wiPlxyXG4gICAgICA8c3Ryb25nPlxyXG4gICAgICAgIHt7IHR5cGVPZkRheXMoYWN0aXZlRGF5LmRheSkgfX1cclxuICAgICAgPC9zdHJvbmc+XHJcbiAgICAgIHt7IGFjdGl2ZURheS50aXRsZSB9fVxyXG4gICAgPC9saT5cclxuICA8L3VsPlxyXG48L25nLXRlbXBsYXRlPlxyXG5cclxuPG5nLXRlbXBsYXRlICNhY3RpdmVEYXkgbGV0LWRheT1cImRheVwiPlxyXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0FjdGl2ZURheShkYXkpOyBlbHNlIG5vdEFjdGl2ZVwiPlxyXG4gICAgPGFcclxuICAgICAgKm5nSWY9XCJnZXRBY3RpdmVEYXkoZGF5KT8udXJsICE9IHVuZGVmaW5lZDsgZWxzZSBhY3RpdmVOb0xpbmtcIlxyXG4gICAgICBocmVmPVwie3sgZ2V0QWN0aXZlRGF5KGRheSk/LnVybCB9fVwiXHJcbiAgICAgIGNsYXNzPVwiY2FsZW5kYXItbGlua1wiXHJcbiAgICAgIHRpdGxlPVwie3sgZ2V0QWN0aXZlRGF5KGRheSk/LnRpdGxlIH19XCJcclxuICAgICAgW2NsYXNzLmRpc2FibGVkXT1cImdldEFjdGl2ZURheShkYXkpPy5pc0Rpc2FibGVkXCJcclxuICAgICAgKGNsaWNrKT1cImdldEFjdGl2ZURheShkYXkpPy5pc0Rpc2FibGVkICYmICRldmVudC5wcmV2ZW50RGVmYXVsdCgpXCJcclxuICAgID5cclxuICAgICAgPHNwYW4gW25nQ2xhc3NdPVwiZ2V0Q2xhc3NCeVR5cGUoZ2V0QWN0aXZlRGF5KGRheSk/LnR5cGUpXCI+e3sgZGF5IH19PC9zcGFuPlxyXG4gICAgPC9hPlxyXG4gICAgPG5nLXRlbXBsYXRlICNhY3RpdmVOb0xpbms+XHJcbiAgICAgIDxzcGFuIHRpdGxlPVwie3sgZ2V0QWN0aXZlRGF5KGRheSk/LnRpdGxlIH19XCIgW2NsYXNzLmRpc2FibGVkXT1cImdldEFjdGl2ZURheShkYXkpPy5pc0Rpc2FibGVkXCI+XHJcbiAgICAgICAgPHNwYW4gW25nQ2xhc3NdPVwiZ2V0Q2xhc3NCeVR5cGUoZ2V0QWN0aXZlRGF5KGRheSk/LnR5cGUpXCI+e3sgZGF5IH19PC9zcGFuPlxyXG4gICAgICA8L3NwYW4+XHJcbiAgICA8L25nLXRlbXBsYXRlPlxyXG4gIDwvbmctY29udGFpbmVyPlxyXG4gIDxuZy10ZW1wbGF0ZSAjbm90QWN0aXZlPlxyXG4gICAgPHNwYW4+e3sgZGF5IH19PC9zcGFuPlxyXG4gIDwvbmctdGVtcGxhdGU+XHJcbjwvbmctdGVtcGxhdGU+XHJcbiJdfQ==