systelab-components
Version:
systelab-components is a set of components that use wide accepted and adopted standard technologies like Angular and Bootstrap, as well as other popular libraries. Please read the ATTRIBUTION.md file for a complete list of dependencies.
218 lines • 38.4 kB
JavaScript
import { Component, EventEmitter, Input, Output } from '@angular/core';
import * as i0 from "@angular/core";
import * as i1 from "systelab-translate";
import * as i2 from "@angular/common";
import * as i3 from "@angular/forms";
import * as i4 from "../calendar/calendar-header.component";
export class Week {
constructor(week, text, day, month, year, isActive) {
this.week = week;
this.text = text;
this.day = day;
this.month = month;
this.year = year;
this.isActive = isActive;
}
}
export class WeekSelectorComponent {
get selectedWeek() {
return this._selectedWeek;
}
set selectedWeek(value) {
this._selectedWeek = value;
this.selectedWeekChange.emit(this._selectedWeek);
}
constructor(i18nService) {
this.i18nService = i18nService;
this.selectedWeekChange = new EventEmitter();
this.weeks = [];
this.months = [];
this.isOpened = false;
this.monthNames = [];
this.daysNames = [];
const year = new Date();
for (let i = 1; i <= 12; i++) {
const month = this.i18nService.formatMonthAndYear(new Date(i + '/01/' + year.getFullYear()))
.split(',');
this.monthNames.push(month[0]);
}
this.daysNames.push(this.i18nService.instant('COMMON_SUNDAY'));
this.daysNames.push(this.i18nService.instant('COMMON_MONDAY'));
this.daysNames.push(this.i18nService.instant('COMMON_TUESDAY'));
this.daysNames.push(this.i18nService.instant('COMMON_WEDNESDAY'));
this.daysNames.push(this.i18nService.instant('COMMON_THURSDAY'));
this.daysNames.push(this.i18nService.instant('COMMON_FRIDAY'));
this.daysNames.push(this.i18nService.instant('COMMON_SATURDAY'));
}
ngOnInit() {
if (!this.currentDate) {
this.currentDate = new Date();
}
this.getMonths();
}
onClicked(e) {
this.isOpened = true;
}
hideSelector() {
this.isOpened = false;
}
getMonths() {
this.months = [];
const month = this.currentDate.getMonth();
const year = this.currentDate.getFullYear();
for (let i = 0; i <= 11; i++) {
const dateStart = new Date(year, i, 1, 0, 0, 0, 0);
const dateEnd = new Date(year, i + 1, 0);
if (this.checkDateIntoIntervals(dateStart) || this.checkDateIntoIntervals(dateEnd)) {
const isActive = (i === month);
this.months.push({ month: i, year: year, text: this.monthNames[i], isActive: isActive });
}
}
this.getWeeks();
}
getWeeks() {
this.weeks = [];
const monthActive = this.months.filter(x => x.month === this.currentDate.getMonth())[0];
const weekInfo = this.getWeeksInMonth(monthActive.month, monthActive.year);
const week = this.getWeek(this.currentDate.getFullYear(), this.currentDate.getMonth(), this.currentDate.getDate(), true);
for (let i = 0; i < weekInfo.length - 1; i++) {
let isActive = false;
const dateStart = new Date(monthActive.year, monthActive.month, weekInfo[i].start, 0, 0, 0, 0);
const dateEnd = new Date(monthActive.year, monthActive.month, weekInfo[i].end, 0, 0, 0, 0);
if (this.checkDateIntoIntervals(dateStart) || this.checkDateIntoIntervals(dateEnd)) {
const text = this.i18nService.instant('COMMON_WEEK') + ' ' + weekInfo[i].number + ': ' + this.daysNames[dateStart.getDay()] + ' ' + weekInfo[i].start + ' ' + this.i18nService.instant('COMMON_TO') + ' ' + this.daysNames[dateEnd.getDay()] + ' ' + weekInfo[i].end;
if (weekInfo[i].number === week) {
isActive = true;
}
const weekObj = new Week(weekInfo[i].number, text, weekInfo[i].start, monthActive.month, monthActive.year, isActive);
this.weeks.push(weekObj);
if (isActive) {
this.selectedWeek = weekObj;
}
}
}
}
onClickedWeek(week) {
this.currentDate = new Date(week.year, week.month, week.day);
this.hideSelector();
this.getWeeks();
}
onClickedMonth(month) {
this.currentDate = new Date(month.year, month.month, 1);
this.getMonths();
}
addYear(num) {
const newDate = new Date(this.currentDate.getFullYear() + (num), this.currentDate.getMonth(), this.currentDate.getDate());
if (this.checkDateIntoIntervals(newDate)) {
this.currentDate = newDate;
this.getMonths();
}
}
addMonth(num) {
const dateStart = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() + (num), 1);
const dateEnd = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() + 1 + (num), 0);
if (this.checkDateIntoIntervals(dateStart) || this.checkDateIntoIntervals(dateEnd)) {
this.currentDate = dateStart;
this.getMonths();
}
}
checkDateIntoIntervals(date) {
if (this.minDate && this.maxDate) {
if (date >= this.minDate && date <= this.maxDate) {
return true;
}
else {
return false;
}
}
else if (this.minDate) {
if (date >= this.minDate) {
return true;
}
else {
return false;
}
}
else if (this.maxDate) {
if (date <= this.maxDate) {
return true;
}
else {
return false;
}
}
else {
return true;
}
}
// TODO: Move to Translate Library
getWeeksInMonth(monthActual, yearActual) {
const firstDate = new Date(yearActual, monthActual, 1);
const lastDate = new Date(yearActual, monthActual + 1, 0);
const numDays = lastDate.getDate();
const weeks = [];
let endDay = 7 - firstDate.getDay(), startDay = 1;
if (firstDate.getDay() === 0) {
endDay = 1;
}
else {
endDay = 7 - firstDate.getDay() + 1;
}
while (startDay <= numDays) {
if (startDay === 1) {
weeks.push({ start: startDay, end: endDay, number: this.getWeek(yearActual, monthActual, startDay, true) });
}
startDay = endDay + 1;
endDay = endDay + 7;
endDay = startDay === 1 && endDay === 8 ? 1 : endDay;
if (endDay > numDays) {
endDay = numDays;
}
weeks.push({ start: startDay, end: endDay, number: this.getWeek(yearActual, monthActual, startDay, true) });
}
return weeks;
}
// TODO: Move to Translate Library
getWeek(yearActual, monthActual, dayActual, isGregorian) {
monthActual += 1; // use 1-12
const binaryMod = Math.floor((14 - (monthActual)) / 12); // Only can have as result 1 or 0
const yearValue = yearActual + 4800 - binaryMod;
const monthValue = (monthActual) + (12 * binaryMod) - 3;
// Find JulianDay
let julianday = 0;
if (isGregorian) {
julianday = dayActual + Math.floor(((153 * monthValue) + 2) / 5) +
(365 * yearValue) + Math.floor(yearValue / 4) - Math.floor(yearValue / 100) +
Math.floor(yearValue / 400) - 32045; // (gregorian calendar)
}
else {
julianday = (dayActual + 1) + Math.round(((153 * monthValue) + 2) / 5) + (365 + yearValue) +
Math.round(yearValue / 4) - 32083; // (julian calendar)
}
// now calc weekNumber according to Julian Day
const d4 = (julianday + 31741 - (julianday % 7)) % 146097 % 36524 % 1461;
const l = Math.floor(d4 / 1460);
const totalDays = ((d4 - l) % 365) + l;
const weekNumber = Math.floor(totalDays / 7) + 1;
return weekNumber;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: WeekSelectorComponent, deps: [{ token: i1.I18nService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.0.9", type: WeekSelectorComponent, selector: "systelab-week-selector", inputs: { maxDate: "maxDate", minDate: "minDate", currentDate: "currentDate", disabled: "disabled", selectedWeek: "selectedWeek" }, outputs: { selectedWeekChange: "selectedWeekChange" }, ngImport: i0, template: "<div class=\"dropdown slab-combobox slab-week-selector d-flex w-100\" [ngClass]=\"{'disabled': disabled}\">\n <div class=\"slab-flex-1 d-flex dropdown-toggle slab-dropdown-toogle\">\n <input #input type=\"text\" class=\"slab-flex-1 d-flex slab-combo-input\" [disabled]=\"disabled\" [(ngModel)]=\"this.selectedWeek.text\"\n (click)=\"onClicked($event)\"/>\n <button #combobutton type=\"button\" class=\"slab-combo-button slab-combo-button-icon\" [disabled]=\"disabled\" (click)=\"onClicked($event)\"></button>\n </div>\n <div *ngIf=\"isOpened\" class=\"slab-week-selector-dropdown\" [ngClass]=\"{'disabled': disabled}\" (mouseleave)=\"hideSelector()\">\n <div class=\"header-selector\">\n <systelab-calendar-header [currentDate]=\"currentDate\" (previousYear)=\"addYear(-1)\" (previousMonth)=\"addMonth(-1)\" (nextMonth)=\"addMonth(1)\" (nextYear)=\"addYear(1)\">\n </systelab-calendar-header>\n </div>\n <div class=\"box\">\n <ul>\n @for (week of weeks; track week) {\n <li [class.active]=\"week.isActive\" (click)=\"onClickedWeek(week)\">\n {{week.text}}\n </li>\n }\n </ul>\n </div>\n <div class=\"box\">\n <ul>\n @for (month of months; track month) {\n <li [class.active]=\"month.isActive\" (click)=\"onClickedMonth(month)\">\n {{month.text}}\n </li>\n }\n </ul>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.CalendarHeaderComponent, selector: "systelab-calendar-header", inputs: ["currentDate"], outputs: ["previousYear", "previousMonth", "nextMonth", "nextYear"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: WeekSelectorComponent, decorators: [{
type: Component,
args: [{ selector: 'systelab-week-selector', template: "<div class=\"dropdown slab-combobox slab-week-selector d-flex w-100\" [ngClass]=\"{'disabled': disabled}\">\n <div class=\"slab-flex-1 d-flex dropdown-toggle slab-dropdown-toogle\">\n <input #input type=\"text\" class=\"slab-flex-1 d-flex slab-combo-input\" [disabled]=\"disabled\" [(ngModel)]=\"this.selectedWeek.text\"\n (click)=\"onClicked($event)\"/>\n <button #combobutton type=\"button\" class=\"slab-combo-button slab-combo-button-icon\" [disabled]=\"disabled\" (click)=\"onClicked($event)\"></button>\n </div>\n <div *ngIf=\"isOpened\" class=\"slab-week-selector-dropdown\" [ngClass]=\"{'disabled': disabled}\" (mouseleave)=\"hideSelector()\">\n <div class=\"header-selector\">\n <systelab-calendar-header [currentDate]=\"currentDate\" (previousYear)=\"addYear(-1)\" (previousMonth)=\"addMonth(-1)\" (nextMonth)=\"addMonth(1)\" (nextYear)=\"addYear(1)\">\n </systelab-calendar-header>\n </div>\n <div class=\"box\">\n <ul>\n @for (week of weeks; track week) {\n <li [class.active]=\"week.isActive\" (click)=\"onClickedWeek(week)\">\n {{week.text}}\n </li>\n }\n </ul>\n </div>\n <div class=\"box\">\n <ul>\n @for (month of months; track month) {\n <li [class.active]=\"month.isActive\" (click)=\"onClickedMonth(month)\">\n {{month.text}}\n </li>\n }\n </ul>\n </div>\n </div>\n</div>\n" }]
}], ctorParameters: () => [{ type: i1.I18nService }], propDecorators: { maxDate: [{
type: Input
}], minDate: [{
type: Input
}], currentDate: [{
type: Input
}], disabled: [{
type: Input
}], selectedWeek: [{
type: Input
}], selectedWeekChange: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vlay1zZWxlY3Rvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zeXN0ZWxhYi1jb21wb25lbnRzL3NyYy9saWIvd2Vlay1zZWxlY3Rvci93ZWVrLXNlbGVjdG9yLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N5c3RlbGFiLWNvbXBvbmVudHMvc3JjL2xpYi93ZWVrLXNlbGVjdG9yL3dlZWstc2VsZWN0b3IuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFVLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQzs7Ozs7O0FBSS9FLE1BQU0sT0FBTyxJQUFJO0lBQ2hCLFlBQW1CLElBQVksRUFBUyxJQUFZLEVBQVMsR0FBVyxFQUFTLEtBQWEsRUFBUyxJQUFZLEVBQVMsUUFBaUI7UUFBMUgsU0FBSSxHQUFKLElBQUksQ0FBUTtRQUFTLFNBQUksR0FBSixJQUFJLENBQVE7UUFBUyxRQUFHLEdBQUgsR0FBRyxDQUFRO1FBQVMsVUFBSyxHQUFMLEtBQUssQ0FBUTtRQUFTLFNBQUksR0FBSixJQUFJLENBQVE7UUFBUyxhQUFRLEdBQVIsUUFBUSxDQUFTO0lBQzdJLENBQUM7Q0FDRDtBQU1ELE1BQU0sT0FBTyxxQkFBcUI7SUFRakMsSUFDSSxZQUFZO1FBQ2YsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDO0lBQzNCLENBQUM7SUFJRCxJQUFJLFlBQVksQ0FBQyxLQUFXO1FBQzNCLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO1FBQzNCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFRRCxZQUFvQixXQUF3QjtRQUF4QixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQWIzQix1QkFBa0IsR0FBRyxJ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LE9BQU87c0JBQXRCLEtBQUs7Z0JBQ1UsT0FBTztzQkFBdEIsS0FBSztnQkFDVSxXQUFXO3NCQUExQixLQUFLO2dCQUNVLFFBQVE7c0JBQXZCLEtBQUs7Z0JBSUYsWUFBWTtzQkFEZixLQUFLO2dCQUtXLGtCQUFrQjtzQkFBbEMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9uSW5pdCwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEkxOG5TZXJ2aWNlIH0gZnJvbSAnc3lzdGVsYWItdHJhbnNsYXRlJztcbmltcG9ydCB7IE1vbnRoIH0gZnJvbSAnLi4vbW9udGgtc2VsZWN0b3IvbW9udGgtc2VsZWN0b3IuY29tcG9uZW50JztcblxuZXhwb3J0IGNsYXNzIFdlZWsge1xuXHRjb25zdHJ1Y3RvcihwdWJsaWMgd2VlazogbnVtYmVyLCBwdWJsaWMgdGV4dDogc3RyaW5nLCBwdWJsaWMgZGF5OiBudW1iZXIsIHB1YmxpYyBtb250aDogbnVtYmVyLCBwdWJsaWMgeWVhcjogbnVtYmVyLCBwdWJsaWMgaXNBY3RpdmU6IGJvb2xlYW4pIHtcblx0fVxufVxuXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3I6ICdzeXN0ZWxhYi13ZWVrLXNlbGVjdG9yJyxcblx0dGVtcGxhdGVVcmw6ICcuL3dlZWstc2VsZWN0b3IuY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIFdlZWtTZWxlY3RvckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cblx0QElucHV0KCkgcHVibGljIG1heERhdGU6IERhdGU7XG5cdEBJbnB1dCgpIHB1YmxpYyBtaW5EYXRlOiBEYXRlO1xuXHRASW5wdXQoKSBwdWJsaWMgY3VycmVudERhdGU6IERhdGU7XG5cdEBJbnB1dCgpIHB1YmxpYyBkaXNhYmxlZDogYm9vbGVhbjtcblxuXHRwcml2YXRlIF9zZWxlY3RlZFdlZWs6IFdlZWs7XG5cdEBJbnB1dCgpXG5cdGdldCBzZWxlY3RlZFdlZWsoKTogV2VlayB7XG5cdFx0cmV0dXJuIHRoaXMuX3NlbGVjdGVkV2Vlaztcblx0fVxuXG5cdEBPdXRwdXQoKSBwdWJsaWMgc2VsZWN0ZWRXZWVrQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG5cdHNldCBzZWxlY3RlZFdlZWsodmFsdWU6IFdlZWspIHtcblx0XHR0aGlzLl9zZWxlY3RlZFdlZWsgPSB2YWx1ZTtcblx0XHR0aGlzLnNlbGVjdGVkV2Vla0NoYW5nZS5lbWl0KHRoaXMuX3NlbGVjdGVkV2Vlayk7XG5cdH1cblxuXHRwdWJsaWMgd2Vla3M6IEFycmF5PFdlZWs+ID0gW107XG5cdHB1YmxpYyBtb250aHM6IEFycmF5PE1vbnRoPiA9IFtdO1xuXHRwdWJsaWMgaXNPcGVuZWQgPSBmYWxzZTtcblx0cHVibGljIG1vbnRoTmFtZXMgPSBbXTtcblx0cHVibGljIGRheXNOYW1lcyA9IFtdO1xuXG5cdGNvbnN0cnVjdG9yKHByaXZhdGUgaTE4blNlcnZpY2U6IEkxOG5TZXJ2aWNlKSB7XG5cdFx0Y29uc3QgeWVhciA9IG5ldyBEYXRlKCk7XG5cdFx0Zm9yIChsZXQgaSA9IDE7IGkgPD0gMTI7IGkrKykge1xuXHRcdFx0Y29uc3QgbW9udGggPSB0aGlzLmkxOG5TZXJ2aWNlLmZvcm1hdE1vbnRoQW5kWWVhcihuZXcgRGF0ZShpICsgJy8wMS8nICsgeWVhci5nZXRGdWxsWWVhcigpKSlcblx0XHRcdFx0LnNwbGl0KCcsJyk7XG5cdFx0XHR0aGlzLm1vbnRoTmFtZXMucHVzaChtb250aFswXSk7XG5cdFx0fVxuXHRcdHRoaXMuZGF5c05hbWVzLnB1c2godGhpcy5pMThuU2VydmljZS5pbnN0YW50KCdDT01NT05fU1VOREFZJykpO1xuXHRcdHRoaXMuZGF5c05hbWVzLnB1c2godGhpcy5pMThuU2VydmljZS5pbnN0YW50KCdDT01NT05fTU9OREFZJykpO1xuXHRcdHRoaXMuZGF5c05hbWVzLnB1c2godGhpcy5pMThuU2VydmljZS5pbnN0YW50KCdDT01NT05fVFVFU0RBWScpKTtcblx0XHR0aGlzLmRheXNOYW1lcy5wdXNoKHRoaXMuaTE4blNlcnZpY2UuaW5zdGFudCgnQ09NTU9OX1dFRE5FU0RBWScpKTtcblx0XHR0aGlzLmRheXNOYW1lcy5wdXNoKHRoaXMuaTE4blNlcnZpY2UuaW5zdGFudCgnQ09NTU9OX1RIVVJTREFZJykpO1xuXHRcdHRoaXMuZGF5c05hbWVzLnB1c2godGhpcy5pMThuU2VydmljZS5pbnN0YW50KCdDT01NT05fRlJJREFZJykpO1xuXHRcdHRoaXMuZGF5c05hbWVzLnB1c2godGhpcy5pMThuU2VydmljZS5pbnN0YW50KCdDT01NT05fU0FUVVJEQVknKSk7XG5cdH1cblxuXHRwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG5cdFx0aWYgKCF0aGlzLmN1cnJlbnREYXRlKSB7XG5cdFx0XHR0aGlzLmN1cnJlbnREYXRlID0gbmV3IERhdGUoKTtcblx0XHR9XG5cdFx0dGhpcy5nZXRNb250aHMoKTtcblx0fVxuXG5cdHB1YmxpYyBvbkNsaWNrZWQoZSkge1xuXHRcdHRoaXMuaXNPcGVuZWQgPSB0cnVlO1xuXHR9XG5cblx0cHVibGljIGhpZGVTZWxlY3RvcigpIHtcblx0XHR0aGlzLmlzT3BlbmVkID0gZmFsc2U7XG5cdH1cblxuXHRwdWJsaWMgZ2V0TW9udGhzKCkge1xuXHRcdHRoaXMubW9udGhzID0gW107XG5cdFx0Y29uc3QgbW9udGggPSB0aGlzLmN1cnJlbnREYXRlLmdldE1vbnRoKCk7XG5cdFx0Y29uc3QgeWVhciA9IHRoaXMuY3VycmVudERhdGUuZ2V0RnVsbFllYXIoKTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8PSAxMTsgaSsrKSB7XG5cdFx0XHRjb25zdCBkYXRlU3RhcnQgPSBuZXcgRGF0ZSh5ZWFyLCBpLCAxLCAwLCAwLCAwLCAwKTtcblx0XHRcdGNvbnN0IGRhdGVFbmQgPSBuZXcgRGF0ZSh5ZWFyLCBpICsgMSwgMCk7XG5cdFx0XHRpZiAodGhpcy5jaGVja0RhdGVJbnRvSW50ZXJ2YWxzKGRhdGVTdGFydCkgfHwgdGhpcy5jaGVja0RhdGVJbnRvSW50ZXJ2YWxzKGRhdGVFbmQpKSB7XG5cdFx0XHRcdGNvbnN0IGlzQWN0aXZlID0gKGkgPT09IG1vbnRoKTtcblx0XHRcdFx0dGhpcy5tb250aHMucHVzaCh7bW9udGg6IGksIHllYXI6IHllYXIsIHRleHQ6IHRoaXMubW9udGhOYW1lc1tpXSwgaXNBY3RpdmU6IGlzQWN0aXZlfSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRoaXMuZ2V0V2Vla3MoKTtcblx0fVxuXG5cdHB1YmxpYyBnZXRXZWVrcygpIHtcblx0XHR0aGlzLndlZWtzID0gW107XG5cdFx0Y29uc3QgbW9udGhBY3RpdmUgPSB0aGlzLm1vbnRocy5maWx0ZXIoeCA9PiB4Lm1vbnRoID09PSB0aGlzLmN1cnJlbnREYXRlLmdldE1vbnRoKCkpWzBdO1xuXHRcdGNvbnN0IHdlZWtJbmZvID0gdGhpcy5nZXRXZWVrc0luTW9udGgobW9udGhBY3RpdmUubW9udGgsIG1vbnRoQWN0aXZlLnllYXIpO1xuXHRcdGNvbnN0IHdlZWsgPSB0aGlzLmdldFdlZWsodGhpcy5jdXJyZW50RGF0ZS5nZXRGdWxsWWVhcigpLCB0aGlzLmN1cnJlbnREYXRlLmdldE1vbnRoKCksIHRoaXMuY3VycmVudERhdGUuZ2V0RGF0ZSgpLCB0cnVlKTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHdlZWtJbmZvLmxlbmd0aCAtIDE7IGkrKykge1xuXHRcdFx0bGV0IGlzQWN0aXZlID0gZmFsc2U7XG5cdFx0XHRjb25zdCBkYXRlU3RhcnQgPSBuZXcgRGF0ZShtb250aEFjdGl2ZS55ZWFyLCBtb250aEFjdGl2ZS5tb250aCwgd2Vla0luZm9baV0uc3RhcnQsIDAsIDAsIDAsIDApO1xuXHRcdFx0Y29uc3QgZGF0ZUVuZCA9IG5ldyBEYXRlKG1vbnRoQWN0aXZlLnllYXIsIG1vbnRoQWN0aXZlLm1vbnRoLCB3ZWVrSW5mb1tpXS5lbmQsIDAsIDAsIDAsIDApO1xuXHRcdFx0aWYgKHRoaXMuY2hlY2tEYXRlSW50b0ludGVydmFscyhkYXRlU3RhcnQpIHx8IHRoaXMuY2hlY2tEYXRlSW50b0ludGVydmFscyhkYXRlRW5kKSkge1xuXHRcdFx0XHRjb25zdCB0ZXh0ID0gdGhpcy5pMThuU2VydmljZS5pbnN0YW50KCdDT01NT05fV0VFSycpICsgJyAnICsgd2Vla0luZm9baV0ubnVtYmVyICsgJzogJyArIHRoaXMuZGF5c05hbWVzW2RhdGVTdGFydC5nZXREYXkoKV0gKyAnICcgKyB3ZWVrSW5mb1tpXS5zdGFydCArICcgJyArIHRoaXMuaTE4blNlcnZpY2UuaW5zdGFudCgnQ09NTU9OX1RPJykgKyAnICcgKyB0aGlzLmRheXNOYW1lc1tkYXRlRW5kLmdldERheSgpXSArICcgJyArIHdlZWtJbmZvW2ldLmVuZDtcblx0XHRcdFx0aWYgKHdlZWtJbmZvW2ldLm51bWJlciA9PT0gd2Vlaykge1xuXHRcdFx0XHRcdGlzQWN0aXZlID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRjb25zdCB3ZWVrT2JqOiBXZWVrID0gbmV3IFdlZWsod2Vla0luZm9baV0ubnVtYmVyLCB0ZXh0LCB3ZWVrSW5mb1tpXS5zdGFydCwgbW9udGhBY3RpdmUubW9udGgsIG1vbnRoQWN0aXZlLnllYXIsIGlzQWN0aXZlKTtcblx0XHRcdFx0dGhpcy53ZWVrcy5wdXNoKHdlZWtPYmopO1xuXHRcdFx0XHRpZiAoaXNBY3RpdmUpIHtcblx0XHRcdFx0XHR0aGlzLnNlbGVjdGVkV2VlayA9IHdlZWtPYmo7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBvbkNsaWNrZWRXZWVrKHdlZWs6IFdlZWspIHtcblx0XHR0aGlzLmN1cnJlbnREYXRlID0gbmV3IERhdGUod2Vlay55ZWFyLCB3ZWVrLm1vbnRoLCB3ZWVrLmRheSk7XG5cdFx0dGhpcy5oaWRlU2VsZWN0b3IoKTtcblx0XHR0aGlzLmdldFdlZWtzKCk7XG5cdH1cblxuXHRwdWJsaWMgb25DbGlja2VkTW9udGgobW9udGg6IE1vbnRoKSB7XG5cdFx0dGhpcy5jdXJyZW50RGF0ZSA9IG5ldyBEYXRlKG1vbnRoLnllYXIsIG1vbnRoLm1vbnRoLCAxKTtcblx0XHR0aGlzLmdldE1vbnRocygpO1xuXHR9XG5cblx0cHVibGljIGFkZFllYXIobnVtOiBudW1iZXIpIHtcblx0XHRjb25zdCBuZXdEYXRlID0gbmV3IERhdGUodGhpcy5jdXJyZW50RGF0ZS5nZXRGdWxsWWVhcigpICsgKG51bSksIHRoaXMuY3VycmVudERhdGUuZ2V0TW9udGgoKSwgdGhpcy5jdXJyZW50RGF0ZS5nZXREYXRlKCkpO1xuXHRcdGlmICh0aGlzLmNoZWNrRGF0ZUludG9JbnRlcnZhbHMobmV3RGF0ZSkpIHtcblx0XHRcdHRoaXMuY3VycmVudERhdGUgPSBuZXdEYXRlO1xuXHRcdFx0dGhpcy5nZXRNb250aHMoKTtcblx0XHR9XG5cdH1cblxuXHRwdWJsaWMgYWRkTW9udGgobnVtOiBudW1iZXIpIHtcblx0XHRjb25zdCBkYXRlU3RhcnQgPSBuZXcgRGF0ZSh0aGlzLmN1cnJlbnREYXRlLmdldEZ1bGxZZWFyKCksIHRoaXMuY3VycmVudERhdGUuZ2V0TW9udGgoKSArIChudW0pLCAxKTtcblx0XHRjb25zdCBkYXRlRW5kID0gbmV3IERhdGUodGhpcy5jdXJyZW50RGF0ZS5nZXRGdWxsWWVhcigpLCB0aGlzLmN1cnJlbnREYXRlLmdldE1vbnRoKCkgKyAxICsgKG51bSksIDApO1xuXHRcdGlmICh0aGlzLmNoZWNrRGF0ZUludG9JbnRlcnZhbHMoZGF0ZVN0YXJ0KSB8fCB0aGlzLmNoZWNrRGF0ZUludG9JbnRlcnZhbHMoZGF0ZUVuZCkpIHtcblx0XHRcdHRoaXMuY3VycmVudERhdGUgPSBkYXRlU3RhcnQ7XG5cdFx0XHR0aGlzLmdldE1vbnRocygpO1xuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBjaGVja0RhdGVJbnRvSW50ZXJ2YWxzKGRhdGU6IERhdGUpIHtcblx0XHRpZiAodGhpcy5taW5EYXRlICYmIHRoaXMubWF4RGF0ZSkge1xuXHRcdFx0aWYgKGRhdGUgPj0gdGhpcy5taW5EYXRlICYmIGRhdGUgPD0gdGhpcy5tYXhEYXRlKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZiAodGhpcy5taW5EYXRlKSB7XG5cdFx0XHRpZiAoZGF0ZSA+PSB0aGlzLm1pbkRhdGUpIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmICh0aGlzLm1heERhdGUpIHtcblx0XHRcdGlmIChkYXRlIDw9IHRoaXMubWF4RGF0ZSkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHR9XG5cblx0Ly8gVE9ETzogTW92ZSB0byBUcmFuc2xhdGUgTGlicmFyeVxuXHRwdWJsaWMgZ2V0V2Vla3NJbk1vbnRoKG1vbnRoQWN0dWFsOiBudW1iZXIsIHllYXJBY3R1YWw6IG51bWJlcikge1xuXHRcdGNvbnN0IGZpcnN0RGF0ZSA9IG5ldyBEYXRlKHllYXJBY3R1YWwsIG1vbnRoQWN0dWFsLCAxKTtcblx0XHRjb25zdCBsYXN0RGF0ZSA9IG5ldyBEYXRlKHllYXJBY3R1YWwsIG1vbnRoQWN0dWFsICsgMSwgMCk7XG5cdFx0Y29uc3QgbnVtRGF5cyA9IGxhc3REYXRlLmdldERhdGUoKTtcblx0XHRjb25zdCB3ZWVrcyA9IFtdO1xuXHRcdGxldCBlbmREYXkgPSA3IC0gZmlyc3REYXRlLmdldERheSgpLCBzdGFydERheSA9IDE7XG5cdFx0aWYgKGZpcnN0RGF0ZS5nZXREYXkoKSA9PT0gMCkge1xuXHRcdFx0ZW5kRGF5ID0gMTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZW5kRGF5ID0gNyAtIGZpcnN0RGF0ZS5nZXREYXkoKSArIDE7XG5cdFx0fVxuXHRcdHdoaWxlIChzdGFydERheSA8PSBudW1EYXlzKSB7XG5cdFx0XHRpZiAoc3RhcnREYXkgPT09IDEpIHtcblx0XHRcdFx0d2Vla3MucHVzaCh7c3RhcnQ6IHN0YXJ0RGF5LCBlbmQ6IGVuZERheSwgbnVtYmVyOiB0aGlzLmdldFdlZWsoeWVhckFjdHVhbCwgbW9udGhBY3R1YWwsIHN0YXJ0RGF5LCB0cnVlKX0pO1xuXHRcdFx0fVxuXHRcdFx0c3RhcnREYXkgPSBlbmREYXkgKyAxO1xuXHRcdFx0ZW5kRGF5ID0gZW5kRGF5ICsgNztcblx0XHRcdGVuZERheSA9IHN0YXJ0RGF5ID09PSAxICYmIGVuZERheSA9PT0gOCA/IDEgOiBlbmREYXk7XG5cdFx0XHRpZiAoZW5kRGF5ID4gbnVtRGF5cykge1xuXHRcdFx0XHRlbmREYXkgPSBudW1EYXlzO1xuXHRcdFx0fVxuXHRcdFx0d2Vla3MucHVzaCh7c3RhcnQ6IHN0YXJ0RGF5LCBlbmQ6IGVuZERheSwgbnVtYmVyOiB0aGlzLmdldFdlZWsoeWVhckFjdHVhbCwgbW9udGhBY3R1YWwsIHN0YXJ0RGF5LCB0cnVlKX0pO1xuXHRcdH1cblx0XHRyZXR1cm4gd2Vla3M7XG5cdH1cblxuXHQvLyBUT0RPOiBNb3ZlIHRvIFRyYW5zbGF0ZSBMaWJyYXJ5XG5cdHB1YmxpYyBnZXRXZWVrKHllYXJBY3R1YWwsIG1vbnRoQWN0dWFsLCBkYXlBY3R1YWwsIGlzR3JlZ29yaWFuKSB7XG5cdFx0bW9udGhBY3R1YWwgKz0gMTsgLy8gdXNlIDEtMTJcblx0XHRjb25zdCBiaW5hcnlNb2QgPSBNYXRoLmZsb29yKCgxNCAtIChtb250aEFjdHVhbCkpIC8gMTIpOyAvLyBPbmx5IGNhbiBoYXZlIGFzIHJlc3VsdCAxIG9yIDBcblx0XHRjb25zdCB5ZWFyVmFsdWUgPSB5ZWFyQWN0dWFsICsgNDgwMCAtIGJpbmFyeU1vZDtcblx0XHRjb25zdCBtb250aFZhbHVlID0gKG1vbnRoQWN0dWFsKSArICgxMiAqIGJpbmFyeU1vZCkgLSAzO1xuXHRcdC8vIEZpbmQgSnVsaWFuRGF5XG5cdFx0bGV0IGp1bGlhbmRheSA9IDA7XG5cdFx0aWYgKGlzR3JlZ29yaWFuKSB7XG5cdFx0XHRqdWxpYW5kYXkgPSBkYXlBY3R1YWwgKyBNYXRoLmZsb29yKCgoMTUzICogbW9udGhWYWx1ZSkgKyAyKSAvIDUpICtcblx0XHRcdFx0KDM2NSAqIHllYXJWYWx1ZSkgKyBNYXRoLmZsb29yKHllYXJWYWx1ZSAvIDQpIC0gTWF0aC5mbG9vcih5ZWFyVmFsdWUgLyAxMDApICtcblx0XHRcdFx0TWF0aC5mbG9vcih5ZWFyVmFsdWUgLyA0MDApIC0gMzIwNDU7ICAvLyAoZ3JlZ29yaWFuIGNhbGVuZGFyKVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRqdWxpYW5kYXkgPSAoZGF5QWN0dWFsICsgMSkgKyBNYXRoLnJvdW5kKCgoMTUzICogbW9udGhWYWx1ZSkgKyAyKSAvIDUpICsgKDM2NSArIHllYXJWYWx1ZSkgK1xuXHRcdFx0XHRNYXRoLnJvdW5kKHllYXJWYWx1ZSAvIDQpIC0gMzIwODM7ICAgIC8vIChqdWxpYW4gY2FsZW5kYXIpXG5cdFx0fVxuXHRcdC8vIG5vdyBjYWxjIHdlZWtOdW1iZXIgYWNjb3JkaW5nIHRvIEp1bGlhbiBEYXlcblx0XHRjb25zdCBkNCA9IChqdWxpYW5kYXkgKyAzMTc0MSAtIChqdWxpYW5kYXkgJSA3KSkgJSAxNDYwOTcgJSAzNjUyNCAlIDE0NjE7XG5cdFx0Y29uc3QgbCA9IE1hdGguZmxvb3IoZDQgLyAxNDYwKTtcblx0XHRjb25zdCB0b3RhbERheXMgPSAoKGQ0IC0gbCkgJSAzNjUpICsgbDtcblx0XHRjb25zdCB3ZWVrTnVtYmVyID0gTWF0aC5mbG9vcih0b3RhbERheXMgLyA3KSArIDE7XG5cdFx0cmV0dXJuIHdlZWtOdW1iZXI7XG5cdH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJkcm9wZG93biBzbGFiLWNvbWJvYm94IHNsYWItd2Vlay1zZWxlY3RvciBkLWZsZXggdy0xMDBcIiBbbmdDbGFzc109XCJ7J2Rpc2FibGVkJzogZGlzYWJsZWR9XCI+XG4gICAgPGRpdiBjbGFzcz1cInNsYWItZmxleC0xIGQtZmxleCBkcm9wZG93bi10b2dnbGUgc2xhYi1kcm9wZG93bi10b29nbGVcIj5cbiAgICAgICAgPGlucHV0ICNpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwic2xhYi1mbGV4LTEgZC1mbGV4IHNsYWItY29tYm8taW5wdXRcIiBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiBbKG5nTW9kZWwpXT1cInRoaXMuc2VsZWN0ZWRXZWVrLnRleHRcIlxuICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ2xpY2tlZCgkZXZlbnQpXCIvPlxuICAgICAgICA8YnV0dG9uICNjb21ib2J1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzbGFiLWNvbWJvLWJ1dHRvbiBzbGFiLWNvbWJvLWJ1dHRvbi1pY29uXCIgW2Rpc2FibGVkXT1cImRpc2FibGVkXCIgKGNsaWNrKT1cIm9uQ2xpY2tlZCgkZXZlbnQpXCI+PC9idXR0b24+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdJZj1cImlzT3BlbmVkXCIgY2xhc3M9XCJzbGFiLXdlZWstc2VsZWN0b3ItZHJvcGRvd25cIiBbbmdDbGFzc109XCJ7J2Rpc2FibGVkJzogZGlzYWJsZWR9XCIgKG1vdXNlbGVhdmUpPVwiaGlkZVNlbGVjdG9yKClcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImhlYWRlci1zZWxlY3RvclwiPlxuICAgICAgICAgICAgPHN5c3RlbGFiLWNhbGVuZGFyLWhlYWRlciBbY3VycmVudERhdGVdPVwiY3VycmVudERhdGVcIiAocHJldmlvdXNZZWFyKT1cImFkZFllYXIoLTEpXCIgKHByZXZpb3VzTW9udGgpPVwiYWRkTW9udGgoLTEpXCIgKG5leHRNb250aCk9XCJhZGRNb250aCgxKVwiIChuZXh0WWVhcik9XCJhZGRZZWFyKDEpXCI+XG4gICAgICAgICAgICA8L3N5c3RlbGFiLWNhbGVuZGFyLWhlYWRlcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJib3hcIj5cbiAgICAgICAgICAgIDx1bD5cbiAgICAgICAgICAgICAgICBAZm9yICh3ZWVrIG9mIHdlZWtzOyB0cmFjayB3ZWVrKSB7XG4gICAgICAgICAgICAgICAgPGxpIFtjbGFzcy5hY3RpdmVdPVwid2Vlay5pc0FjdGl2ZVwiIChjbGljayk9XCJvbkNsaWNrZWRXZWVrKHdlZWspXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7d2Vlay50ZXh0fX1cbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvdWw+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYm94XCI+XG4gICAgICAgICAgICA8dWw+XG4gICAgICAgICAgICAgICAgQGZvciAobW9udGggb2YgbW9udGhzOyB0cmFjayBtb250aCkge1xuICAgICAgICAgICAgICAgICAgICA8bGkgW2NsYXNzLmFjdGl2ZV09XCJtb250aC5pc0FjdGl2ZVwiIChjbGljayk9XCJvbkNsaWNrZWRNb250aChtb250aClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7bW9udGgudGV4dH19XG4gICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC91bD5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==