angular-nepali-datepicker
Version:
Simple Nepali datepicker component for angular applications
380 lines • 36.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, forwardRef, Input, ViewEncapsulation } from "@angular/core";
import * as NepaliDateConverter from "nepali-date";
import { NG_VALUE_ACCESSOR } from "@angular/forms";
import { daysMapping, monthsMapping } from "./mapping";
var DatepickerComponent = /** @class */ (function () {
function DatepickerComponent() {
var _this = this;
this.nepaliDateToday = { day: 0, month: 0, year: 0 };
this.currentNepaliDate = { day: 0, month: 0, year: 0 };
this.formattedDate = "";
this.currentDate = new Date();
this.years = [];
this.daysMapping = daysMapping;
this.monthsMapping = monthsMapping;
this.isOpen = false;
this.hideInput = false;
this.alwaysVisible = false;
this.language = "ne";
this.monthDisplayType = "default";
this.dayDisplayType = "default";
this.dateFormatter = function (selectedDate) {
/** @type {?} */
var dd = selectedDate.day < 10 ? "0" + selectedDate.day : selectedDate.day;
/** @type {?} */
var mm = selectedDate.month < 10 ? "0" + selectedDate.month : selectedDate.month;
return dd + "/" + mm + "/" + _this.selectedDate.year;
};
this.propagateChange = function (_) { };
this.propagateTouch = function (_) { };
}
/**
* @return {?}
*/
DatepickerComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
/** @type {?} */
var nepaliDateToday = new NepaliDateConverter(new Date());
this.nepaliDateToday = {
year: nepaliDateToday.getYear(),
month: nepaliDateToday.getMonth(),
day: nepaliDateToday.getDate()
};
this.setCurrentDate();
this.populateYears();
this.setCurrentMonthData();
};
/**
* @return {?}
*/
DatepickerComponent.prototype.setCurrentDate = /**
* @return {?}
*/
function () {
/** @type {?} */
var currentNepaliDate;
if (!this.selectedDate) {
currentNepaliDate = new NepaliDateConverter(this.currentDate);
}
else {
var _a = this.selectedDate, year = _a.year, month = _a.month, day = _a.day;
currentNepaliDate = new NepaliDateConverter(year, month, day);
this.currentDate = currentNepaliDate.getEnglishDate();
}
this.currentNepaliDate = {
year: currentNepaliDate.getYear(),
month: currentNepaliDate.getMonth(),
day: currentNepaliDate.getDate()
};
};
/**
* @return {?}
*/
DatepickerComponent.prototype.populateYears = /**
* @return {?}
*/
function () {
for (var i = 2001; i <= 2088; i++) {
this.years.push(i);
}
};
/**
* @return {?}
*/
DatepickerComponent.prototype.resetCurrentMonthData = /**
* @return {?}
*/
function () {
this.currentMonthData = {
0: [],
1: [],
2: [],
3: [],
4: [],
5: [],
6: []
};
};
/**
* @return {?}
*/
DatepickerComponent.prototype.formatValue = /**
* @return {?}
*/
function () {
if (this.selectedDate) {
this.formattedDate = this.dateFormatter(this.selectedDate);
}
};
/**
* @param {?} value
* @return {?}
*/
DatepickerComponent.prototype.writeValue = /**
* @param {?} value
* @return {?}
*/
function (value) {
if (value) {
this.selectedDate = value;
this.currentNepaliDate = value;
this.formatValue();
}
};
/**
* @return {?}
*/
DatepickerComponent.prototype.registerOnTouched = /**
* @return {?}
*/
function () { };
/**
* @param {?} fn
* @return {?}
*/
DatepickerComponent.prototype.registerOnChange = /**
* @param {?} fn
* @return {?}
*/
function (fn) {
this.propagateChange = fn;
};
/**
* @return {?}
*/
DatepickerComponent.prototype.setCurrentMonthData = /**
* @return {?}
*/
function () {
this.resetCurrentMonthData();
// fill the currentMonthData with current date
/** @type {?} */
var day = this.currentDate.getDay();
this.currentMonthData[day] = [this.currentNepaliDate.day];
// fill the currentMonthData with day before the current date
this.setMonthDataBefore(day - 1, this.currentNepaliDate.day - 1);
// fill the currentMonthData with day after the current date
this.setMonthDataAfter(day + 1, this.currentNepaliDate.day + 1);
// we need some empty spaces in place so that the dates are shown in correct order
// eg if the 1st day starts on monday then we need 1 empty space for non existingn date on Sunday
this.createEmptySpaces();
};
/**
* @param {?} day
* @param {?} date
* @return {?}
*/
DatepickerComponent.prototype.setMonthDataBefore = /**
* @param {?} day
* @param {?} date
* @return {?}
*/
function (day, date) {
if (date >= 1) {
if (day < 0) {
day = 6;
}
this.currentMonthData[day] = tslib_1.__spread([date], this.currentMonthData[day]);
this.setMonthDataBefore(--day, --date);
}
};
/**
* @param {?} day
* @param {?} date
* @return {?}
*/
DatepickerComponent.prototype.setMonthDataAfter = /**
* @param {?} day
* @param {?} date
* @return {?}
*/
function (day, date) {
/** @type {?} */
var nepaliDate = new NepaliDateConverter(this.currentNepaliDate.year, this.currentNepaliDate.month, date);
// only add the data if the current month matches
if (nepaliDate.getMonth() === this.currentNepaliDate.month) {
if (day > 6) {
day = 0;
}
this.currentMonthData[day] = tslib_1.__spread(this.currentMonthData[day], [date]);
this.setMonthDataAfter(++day, ++date);
}
};
/**
* @return {?}
*/
DatepickerComponent.prototype.createEmptySpaces = /**
* @return {?}
*/
function () {
// first find out which day has the 1st
// if its a Sunday, then don't do anything else add 1 space on each previous day
/** @type {?} */
var dayIndex = 0;
Object.values(this.currentMonthData).find(function (value, index) {
if (value.includes(1)) {
dayIndex = index;
}
return value.includes(1);
});
if (dayIndex) {
for (dayIndex; dayIndex > 0; dayIndex--) {
/** @type {?} */
var monthData = this.currentMonthData[dayIndex - 1];
this.currentMonthData[dayIndex - 1] = tslib_1.__spread([null], monthData);
}
}
};
/**
* @param {?} day
* @return {?}
*/
DatepickerComponent.prototype.selectDate = /**
* @param {?} day
* @return {?}
*/
function (day) {
this.selectedDate = tslib_1.__assign({}, this.currentNepaliDate, { day: day });
this.formatValue();
this.close();
this.propagateChange(this.selectedDate);
};
/**
* @param {?} year
* @return {?}
*/
DatepickerComponent.prototype.selectYear = /**
* @param {?} year
* @return {?}
*/
function (year) {
this.currentNepaliDate.year = +year;
/** @type {?} */
var newDate = new NepaliDateConverter(this.currentNepaliDate.year, this.currentNepaliDate.month, this.currentNepaliDate.day);
this.currentDate = newDate.getEnglishDate();
this.setCurrentMonthData();
};
/**
* @param {?} month
* @return {?}
*/
DatepickerComponent.prototype.selectMonth = /**
* @param {?} month
* @return {?}
*/
function (month) {
this.currentNepaliDate.month = this.monthsMapping[this.language][this.monthDisplayType].indexOf(month);
/** @type {?} */
var newDate = new NepaliDateConverter(this.currentNepaliDate.year, this.currentNepaliDate.month, this.currentNepaliDate.day);
this.currentDate = newDate.getEnglishDate();
this.setCurrentMonthData();
};
/**
* @return {?}
*/
DatepickerComponent.prototype.toggleOpen = /**
* @return {?}
*/
function () {
if (!this.alwaysVisible) {
this.isOpen = !this.isOpen;
}
};
/**
* @return {?}
*/
DatepickerComponent.prototype.open = /**
* @return {?}
*/
function () {
this.isOpen = true;
};
/**
* @return {?}
*/
DatepickerComponent.prototype.close = /**
* @return {?}
*/
function () {
this.isOpen = false;
this.setCurrentDate();
};
DatepickerComponent.decorators = [
{ type: Component, args: [{
selector: "np-datepicker",
template: "<input\r\n class=\"datepicker__input\"\r\n type=\"text\"\r\n [value]=\"formattedDate | toNp: language\"\r\n [ngClass]=\"inputClass\"\r\n #origin=\"cdkOverlayOrigin\"\r\n cdk-overlay-origin\r\n (focus)=\"open()\"\r\n (keydown)=\"$event.preventDefault()\"\r\n aria-hidden=\"true\"\r\n [hidden]=\"hideInput\">\r\n<ng-template\r\n cdk-connected-overlay\r\n cdkConnectedOverlayLockPosition\r\n cdkConnectedOverlayHasBackdrop\r\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\r\n [cdkConnectedOverlayOrigin]=\"origin\"\r\n [cdkConnectedOverlayOpen]=\"isOpen\"\r\n (backdropClick)=\"close()\"\r\n (detach)=\"close()\">\r\n <ng-container [ngTemplateOutlet]=\"dp\"></ng-container>\r\n</ng-template>\r\n\r\n<ng-container [ngTemplateOutlet]=\"dp\" *ngIf=\"alwaysVisible\"></ng-container>\r\n\r\n<ng-template #dp>\r\n <div class=\"datepicker__container\">\r\n <div class=\"datepicker__options-container\">\r\n <span class=\"datepicker__options-year-container\">\r\n <span>\r\n {{'Year' | toNp : language : 'word'}}:\r\n </span>\r\n <select (change)=\"selectYear($event.target.value)\">\r\n <option\r\n *ngFor=\"let year of years\"\r\n [value]=\"year\"\r\n [selected]=\"year === currentNepaliDate?.year\">\r\n {{year | toNp: language }}\r\n </option>\r\n </select>\r\n </span>\r\n <span class=\"datepicker__options-month-container\">\r\n <span>{{'Month' | toNp : language : 'word'}}: </span>\r\n <select (change)=\"selectMonth($event.target.value)\">\r\n <option\r\n *ngFor=\"let month of monthsMapping[language][monthDisplayType]; index as i\"\r\n [value]=\"month\"\r\n [selected]=\"i === currentNepaliDate?.month\">\r\n {{month}}\r\n </option>\r\n </select>\r\n </span>\r\n </div>\r\n <div class=\"datepicker__days-container\">\r\n <div class=\"datepicker__days\" *ngFor=\"let day of daysMapping[language][dayDisplayType]; index as i\">\r\n <div class=\"datepicker__weekday\">{{day}}</div>\r\n <div class=\"datepicker__date-container\" *ngFor=\"let date of currentMonthData[i]\">\r\n <div\r\n class=\"datepicker__date\"\r\n [class.datepicker__date--active]=\"\r\n date === selectedDate?.day &&\r\n currentNepaliDate.month === selectedDate?.month &&\r\n currentNepaliDate.year === selectedDate?.year\r\n \"\r\n [class.datepicker__date--current-day]=\"\r\n date === nepaliDateToday.day &&\r\n currentNepaliDate.month === nepaliDateToday.month &&\r\n currentNepaliDate.year === nepaliDateToday.year\r\n \"\r\n [class.datepicker__date--disabled]=\"!date\"\r\n (click)=\"selectDate(date)\">\r\n <span *ngIf=\"!date\"> </span>\r\n {{date | toNp: language }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>",
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(function () { return DatepickerComponent; }),
multi: true
}
],
encapsulation: ViewEncapsulation.None,
styles: [".cdk-global-overlay-wrapper,.cdk-overlay-container{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed;z-index:1000}.cdk-overlay-container:empty{display:none}.cdk-global-overlay-wrapper{display:flex;position:absolute;z-index:1000}.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box;z-index:1000;display:flex;max-width:100%;max-height:100%}.cdk-overlay-backdrop{position:absolute;top:0;bottom:0;left:0;right:0;z-index:1000;pointer-events:auto;-webkit-tap-highlight-color:transparent;transition:opacity .4s cubic-bezier(.25,.8,.25,1);opacity:0}.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:1}@media screen and (-ms-high-contrast:active){.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:.6}}.cdk-overlay-dark-backdrop{background:rgba(0,0,0,.32)}.cdk-overlay-transparent-backdrop,.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing{opacity:0}.cdk-overlay-connected-position-bounding-box{position:absolute;z-index:1000;display:flex;flex-direction:column;min-width:1px;min-height:1px}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}.datepicker__input{display:block}.datepicker__container{--font-family:arial,sans-serif;--font-size:14px;--container-padding:8px 5px;--container-border-color:lightgray;--container-border:1px solid;--container-background-color:white;--select-height:24px;--option-margin:0 0 7px;--option-year-container-margin:0 10px 0;--days-size:40px;--weekday-margin:0 0 5px;--active-day-color:white;--active-day-background:#27a4f7;--hover-color:#27a4f7;--selected-color:#27a4f7;display:inline-block;font-family:\"arial, sans-serif\";font-family:var(--font-family);font-size:14px;font-size:var(--font-size);padding:8px 5px;padding:var(--container-padding);border:1px solid #d3d3d3;border:var(--container-border);border-color:var(--container-border-color);background-color:#fff;background-color:var(--container-background-color)}.datepicker__options-container{margin:0 0 7px;margin:var(--option-margin)}.datepicker__options-container select{height:24px;height:var(--select-height)}.datepicker__options-year-container{display:inline-block;margin:0 10px;margin:var(--option-year-container-margin)}.datepicker__days{display:inline-block;vertical-align:top;text-align:center;width:40px;width:var(--days-size)}.datepicker__weekday{margin:0 0 5px;margin:var(--weekday-margin);font-weight:700;text-align:center}.datepicker__date{width:40px;width:var(--days-size);height:40px;height:var(--days-size);line-height:40px;line-height:var(--days-size);cursor:pointer}.datepicker__date--active{color:#fff;color:var(--active-day-color);background:#27a4f7;background:var(--active-day-background)}.datepicker__date--current-day:not(.datepicker__date--active){color:#27a4f7;color:var(--selected-color);font-weight:700}.datepicker__date--disabled{pointer-events:none}.datepicker__date:hover:not(.datepicker__date--active){color:#27a4f7;color:var(--hover-color);transition:color .3s}"]
}] }
];
/** @nocollapse */
DatepickerComponent.ctorParameters = function () { return []; };
DatepickerComponent.propDecorators = {
hideInput: [{ type: Input }],
alwaysVisible: [{ type: Input }],
inputClass: [{ type: Input }],
language: [{ type: Input }],
monthDisplayType: [{ type: Input }],
dayDisplayType: [{ type: Input }],
dateFormatter: [{ type: Input }]
};
return DatepickerComponent;
}());
export { DatepickerComponent };
if (false) {
/** @type {?} */
DatepickerComponent.prototype.nepaliDateToday;
/** @type {?} */
DatepickerComponent.prototype.currentNepaliDate;
/** @type {?} */
DatepickerComponent.prototype.selectedDate;
/** @type {?} */
DatepickerComponent.prototype.formattedDate;
/** @type {?} */
DatepickerComponent.prototype.currentDate;
/** @type {?} */
DatepickerComponent.prototype.displayDate;
/** @type {?} */
DatepickerComponent.prototype.years;
/** @type {?} */
DatepickerComponent.prototype.currentMonthData;
/** @type {?} */
DatepickerComponent.prototype.daysMapping;
/** @type {?} */
DatepickerComponent.prototype.monthsMapping;
/** @type {?} */
DatepickerComponent.prototype.isOpen;
/** @type {?} */
DatepickerComponent.prototype.hideInput;
/** @type {?} */
DatepickerComponent.prototype.alwaysVisible;
/** @type {?} */
DatepickerComponent.prototype.inputClass;
/** @type {?} */
DatepickerComponent.prototype.language;
/** @type {?} */
DatepickerComponent.prototype.monthDisplayType;
/** @type {?} */
DatepickerComponent.prototype.dayDisplayType;
/** @type {?} */
DatepickerComponent.prototype.dateFormatter;
/** @type {?} */
DatepickerComponent.prototype.propagateChange;
/** @type {?} */
DatepickerComponent.prototype.propagateTouch;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXBpY2tlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9hbmd1bGFyLW5lcGFsaS1kYXRlcGlja2VyLyIsInNvdXJjZXMiOlsibGliL2RhdGVwaWNrZXIvZGF0ZXBpY2tlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULFVBQVUsRUFDVixLQUFLLEVBQ0wsaUJBQWlCLEVBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sS0FBSyxtQkFBbUIsTUFBTSxhQUFhLENBQUM7QUFDbkQsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBUXpFLE9BQU8sRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRXZEO0lBMkRFO1FBQUEsaUJBQWdCO1FBN0NoQixvQkFBZSxHQUFlLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUM1RCxzQkFBaUIsR0FBZSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFFOUQsa0JBQWEsR0FBRyxFQUFFLENBQUM7UUFDbkIsZ0JBQVcsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBSXpCLFVBQUssR0FBYSxFQUFFLENBQUM7UUFJckIsZ0JBQVcsR0FBZ0IsV0FBVyxDQUFDO1FBRXZDLGtCQUFhLEdBQWlCLGFBQWEsQ0FBQztRQUU1QyxXQUFNLEdBQUcsS0FBSyxDQUFDO1FBR2YsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUdsQixrQkFBYSxHQUFHLEtBQUssQ0FBQztRQU10QixhQUFRLEdBQWdCLElBQUksQ0FBQztRQUc3QixxQkFBZ0IsR0FBbUMsU0FBUyxDQUFDO1FBRzdELG1CQUFjLEdBQXdCLFNBQVMsQ0FBQztRQUdoRCxrQkFB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QzVELGdEQUE4RDs7SUFDOUQsMkNBQXlCOztJQUN6Qiw0Q0FBbUI7O0lBQ25CLDBDQUF5Qjs7SUFFekIsMENBQW9COztJQUVwQixvQ0FBcUI7O0lBRXJCLCtDQUE0Qjs7SUFFNUIsMENBQXVDOztJQUV2Qyw0Q0FBNEM7O0lBRTVDLHFDQUFlOztJQUVmLHdDQUNrQjs7SUFFbEIsNENBQ3NCOztJQUV0Qix5Q0FDbUI7O0lBRW5CLHVDQUM2Qjs7SUFFN0IsK0NBQzZEOztJQUU3RCw2Q0FDZ0Q7O0lBRWhELDRDQU9FOztJQXlERiw4Q0FBaUM7O0lBRWpDLDZDQUFnQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgQ29tcG9uZW50LFxyXG4gIE9uSW5pdCxcclxuICBmb3J3YXJkUmVmLFxyXG4gIElucHV0LFxyXG4gIFZpZXdFbmNhcHN1bGF0aW9uXHJcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuaW1wb3J0ICogYXMgTmVwYWxpRGF0ZUNvbnZlcnRlciBmcm9tIFwibmVwYWxpLWRhdGVcIjtcclxuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XHJcbmltcG9ydCB7XHJcbiAgTmVwYWxpRGF0ZSxcclxuICBNb250aERhdGEsXHJcbiAgRGF5c01hcHBpbmcsXHJcbiAgTW9udGhNYXBwaW5nLFxyXG4gIERhdGVGb3JtYXR0ZXJcclxufSBmcm9tIFwiLi90eXBlc1wiO1xyXG5pbXBvcnQgeyBkYXlzTWFwcGluZywgbW9udGhzTWFwcGluZyB9IGZyb20gXCIuL21hcHBpbmdcIjtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiBcIm5wLWRhdGVwaWNrZXJcIixcclxuICB0ZW1wbGF0ZVVybDogXCIuL2RhdGVwaWNrZXIuY29tcG9uZW50Lmh0bWxcIixcclxuICBzdHlsZVVybHM6IFtcIi4vZGF0ZXBpY2tlci5jb21wb25lbnQuc2Nzc1wiXSxcclxuICBwcm92aWRlcnM6IFtcclxuICAgIHtcclxuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IERhdGVwaWNrZXJDb21wb25lbnQpLFxyXG4gICAgICBtdWx0aTogdHJ1ZVxyXG4gICAgfVxyXG4gIF0sXHJcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxyXG59KVxyXG5leHBvcnQgY2xhc3MgRGF0ZXBpY2tlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xyXG4gIG5lcGFsaURhdGVUb2RheTogTmVwYWxpRGF0ZSA9IHsgZGF5OiAwLCBtb250aDogMCwgeWVhcjogMCB9O1xyXG4gIGN1cnJlbnROZXBhbGlEYXRlOiBOZXBhbGlEYXRlID0geyBkYXk6IDAsIG1vbnRoOiAwLCB5ZWFyOiAwIH07XHJcbiAgc2VsZWN0ZWREYXRlOiBOZXBhbGlEYXRlO1xyXG4gIGZvcm1hdHRlZERhdGUgPSBcIlwiO1xyXG4gIGN1cnJlbnREYXRlID0gbmV3IERhdGUoKTtcclxuXHJcbiAgZGlzcGxheURhdGU6IHN0cmluZztcclxuXHJcbiAgeWVhcnM6IG51bWJlcltdID0gW107XHJcblxyXG4gIGN1cnJlbnRNb250aERhdGE6IE1vbnRoRGF0YTtcclxuXHJcbiAgZGF5c01hcHBpbmc6IERheXNNYXBwaW5nID0gZGF5c01hcHBpbmc7XHJcblxyXG4gIG1vbnRoc01hcHBpbmc6IE1vbnRoTWFwcGluZyA9IG1vbnRoc01hcHBpbmc7XHJcblxyXG4gIGlzT3BlbiA9IGZhbHNlO1xyXG5cclxuICBASW5wdXQoKVxyXG4gIGhpZGVJbnB1dCA9IGZhbHNlO1xyXG5cclxuICBASW5wdXQoKVxyXG4gIGFsd2F5c1Zpc2libGUgPSBmYWxzZTtcclxuXHJcbiAgQElucHV0KClcclxuICBpbnB1dENsYXNzOiBzdHJpbmc7XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgbGFuZ3VhZ2U6IFwiZW5cIiB8IFwibmVcIiA9IFwibmVcIjtcclxuXHJcbiAgQElucHV0KClcclxuICBtb250aERpc3BsYXlUeXBlOiBcImRlZmF1bHRcIiB8IFwibW9kZXJuXCIgfCBcInNob3J0XCIgPSBcImRlZmF1bHRcIjtcclxuXHJcbiAgQElucHV0KClcclxuICBkYXlEaXNwbGF5VHlwZTogXCJkZWZhdWx0XCIgfCBcInNob3J0XCIgPSBcImRlZmF1bHRcIjtcclxuXHJcbiAgQElucHV0KClcclxuICBkYXRlRm9ybWF0dGVyOiBEYXRlRm9ybWF0dGVyID0gKHNlbGVjdGVkRGF0ZTogTmVwYWxpRGF0ZSkgPT4ge1xyXG4gICAgY29uc3QgZGQgPVxyXG4gICAgICBzZWxlY3RlZERhdGUuZGF5IDwgMTAgPyBcIjBcIiArIHNlbGVjdGVkRGF0ZS5kYXkgOiBzZWxlY3RlZERhdGUuZGF5O1xyXG4gICAgY29uc3QgbW0gPVxyXG4gICAgICBzZWxlY3RlZERhdGUubW9udGggPCAxMCA/IFwiMFwiICsgc2VsZWN0ZWREYXRlLm1vbnRoIDogc2VsZWN0ZWREYXRlLm1vbnRoO1xyXG4gICAgcmV0dXJuIGAke2RkfS8ke21tfS8ke3RoaXMuc2VsZWN0ZWREYXRlLnllYXJ9YDtcclxuICB9O1xyXG5cclxuICBjb25zdHJ1Y3RvcigpIHt9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgY29uc3QgbmVwYWxpRGF0ZVRvZGF5ID0gbmV3IE5lcGFsaURhdGVDb252ZXJ0ZXIobmV3IERhdGUoKSk7XHJcbiAgICB0aGlzLm5lcGFsaURhdGVUb2RheSA9IHtcclxuICAgICAgeWVhcjogbmVwYWxpRGF0ZVRvZGF5LmdldFllYXIoKSxcclxuICAgICAgbW9udGg6IG5lcGFsaURhdGVUb2RheS5nZXRNb250aCgpLFxyXG4gICAgICBkYXk6IG5lcGFsaURhdGVUb2RheS5nZXREYXRlKClcclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5zZXRDdXJyZW50RGF0ZSgpO1xyXG4gICAgdGhpcy5wb3B1bGF0ZVllYXJzKCk7XHJcbiAgICB0aGlzLnNldEN1cnJlbnRNb250aERhdGEoKTtcclxuICB9XHJcblxyXG4gIHNldEN1cnJlbnREYXRlKCkge1xyXG4gICAgbGV0IGN1cnJlbnROZXBhbGlEYXRlO1xyXG4gICAgaWYgKCF0aGlzLnNlbGVjdGVkRGF0ZSkge1xyXG4gICAgICBjdXJyZW50TmVwYWxpRGF0ZSA9IG5ldyBOZXBhbGlEYXRlQ29udmVydGVyKHRoaXMuY3VycmVudERhdGUpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgeyB5ZWFyLCBtb250aCwgZGF5IH0gPSB0aGlzLnNlbGVjdGVkRGF0ZTtcclxuICAgICAgY3VycmVudE5lcGFsaURhdGUgPSBuZXcgTmVwYWxpRGF0ZUNvbnZlcnRlcih5ZWFyLCBtb250aCwgZGF5KTtcclxuICAgICAgdGhpcy5jdXJyZW50RGF0ZSA9IGN1cnJlbnROZXBhbGlEYXRlLmdldEVuZ2xpc2hEYXRlKCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmN1cnJlbnROZXBhbGlEYXRlID0ge1xyXG4gICAgICB5ZWFyOiBjdXJyZW50TmVwYWxpRGF0ZS5nZXRZZWFyKCksXHJcbiAgICAgIG1vbnRoOiBjdXJyZW50TmVwYWxpRGF0ZS5nZXRNb250aCgpLFxyXG4gICAgICBkYXk6IGN1cnJlbnROZXBhbGlEYXRlLmdldERhdGUoKVxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHBvcHVsYXRlWWVhcnMoKSB7XHJcbiAgICBmb3IgKGxldCBpID0gMjAwMTsgaSA8PSAyMDg4OyBpKyspIHtcclxuICAgICAgdGhpcy55ZWFycy5wdXNoKGkpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmVzZXRDdXJyZW50TW9udGhEYXRhKCkge1xyXG4gICAgdGhpcy5jdXJyZW50TW9udGhEYXRhID0ge1xyXG4gICAgICAwOiBbXSxcclxuICAgICAgMTogW10sXHJcbiAgICAgIDI6IFtdLFxyXG4gICAgICAzOiBbXSxcclxuICAgICAgNDogW10sXHJcbiAgICAgIDU6IFtdLFxyXG4gICAgICA2OiBbXVxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIGZvcm1hdFZhbHVlKCkge1xyXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWREYXRlKSB7XHJcbiAgICAgIHRoaXMuZm9ybWF0dGVkRGF0ZSA9IHRoaXMuZGF0ZUZvcm1hdHRlcih0aGlzLnNlbGVjdGVkRGF0ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcm9wYWdhdGVDaGFuZ2UgPSAoXzogYW55KSA9PiB7fTtcclxuXHJcbiAgcHJvcGFnYXRlVG91Y2ggPSAoXzogYW55KSA9PiB7fTtcclxuXHJcbiAgd3JpdGVWYWx1ZSh2YWx1ZTogYW55KSB7XHJcbiAgICBpZiAodmFsdWUpIHtcclxuICAgICAgdGhpcy5zZWxlY3RlZERhdGUgPSB2YWx1ZTtcclxuICAgICAgdGhpcy5jdXJyZW50TmVwYWxpRGF0ZSA9IHZhbHVlO1xyXG4gICAgICB0aGlzLmZvcm1hdFZhbHVlKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZWdpc3Rlck9uVG91Y2hlZCgpIHt9XHJcblxyXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm4pIHtcclxuICAgIHRoaXMucHJvcGFnYXRlQ2hhbmdlID0gZm47XHJcbiAgfVxyXG5cclxuICBzZXRDdXJyZW50TW9udGhEYXRhKCkge1xyXG4gICAgdGhpcy5yZXNldEN1cnJlbnRNb250aERhdGEoKTtcclxuICAgIC8vIGZpbGwgdGhlIGN1cnJlbnRNb250aERhdGEgd2l0aCBjdXJyZW50IGRhdGVcclxuICAgIGNvbnN0IGRheSA9IHRoaXMuY3VycmVudERhdGUuZ2V0RGF5KCk7XHJcbiAgICB0aGlzLmN1cnJlbnRNb250aERhdGFbZGF5XSA9IFt0aGlzLmN1cnJlbnROZXBhbGlEYXRlLmRheV07XHJcblxyXG4gICAgLy8gZmlsbCB0aGUgY3VycmVudE1vbnRoRGF0YSB3aXRoIGRheSBiZWZvcmUgdGhlIGN1cnJlbnQgZGF0ZVxyXG4gICAgdGhpcy5zZXRNb250aERhdGFCZWZvcmUoZGF5IC0gMSwgdGhpcy5jdXJyZW50TmVwYWxpRGF0ZS5kYXkgLSAxKTtcclxuXHJcbiAgICAvLyBmaWxsIHRoZSBjdXJyZW50TW9udGhEYXRhIHdpdGggZGF5IGFmdGVyIHRoZSBjdXJyZW50IGRhdGVcclxuICAgIHRoaXMuc2V0TW9udGhEYXRhQWZ0ZXIoZGF5ICsgMSwgdGhpcy5jdXJyZW50TmVwYWxpRGF0ZS5kYXkgKyAxKTtcclxuXHJcbiAgICAvLyB3ZSBuZWVkIHNvbWUgZW1wdHkgc3BhY2VzIGluIHBsYWNlIHNvIHRoYXQgdGhlIGRhdGVzIGFyZSBzaG93biBpbiBjb3JyZWN0IG9yZGVyXHJcbiAgICAvLyBlZyBpZiB0aGUgMXN0IGRheSBzdGFydHMgb24gbW9uZGF5IHRoZW4gd2UgbmVlZCAxIGVtcHR5IHNwYWNlIGZvciBub24gZXhpc3RpbmduIGRhdGUgb24gU3VuZGF5XHJcbiAgICB0aGlzLmNyZWF0ZUVtcHR5U3BhY2VzKCk7XHJcbiAgfVxyXG5cclxuICBzZXRNb250aERhdGFCZWZvcmUoZGF5LCBkYXRlKSB7XHJcbiAgICBpZiAoZGF0ZSA+PSAxKSB7XHJcbiAgICAgIGlmIChkYXkgPCAwKSB7XHJcbiAgICAgICAgZGF5ID0gNjtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmN1cnJlbnRNb250aERhdGFbZGF5XSA9IFtkYXRlLCAuLi50aGlzLmN1cnJlbnRNb250aERhdGFbZGF5XV07XHJcbiAgICAgIHRoaXMuc2V0TW9udGhEYXRhQmVmb3JlKC0tZGF5LCAtLWRhdGUpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgc2V0TW9udGhEYXRhQWZ0ZXIoZGF5LCBkYXRlKSB7XHJcbiAgICBjb25zdCBuZXBhbGlEYXRlID0gbmV3IE5lcGFsaURhdGVDb252ZXJ0ZXIoXHJcbiAgICAgIHRoaXMuY3VycmVudE5lcGFsaURhdGUueWVhcixcclxuICAgICAgdGhpcy5jdXJyZW50TmVwYWxpRGF0ZS5tb250aCxcclxuICAgICAgZGF0ZVxyXG4gICAgKTtcclxuICAgIC8vICBvbmx5IGFkZCB0aGUgZGF0YSBpZiB0aGUgY3VycmVudCBtb250aCBtYXRjaGVzXHJcbiAgICBpZiAobmVwYWxpRGF0ZS5nZXRNb250aCgpID09PSB0aGlzLmN1cnJlbnROZXBhbGlEYXRlLm1vbnRoKSB7XHJcbiAgICAgIGlmIChkYXkgPiA2KSB7XHJcbiAgICAgICAgZGF5ID0gMDtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmN1cnJlbnRNb250aERhdGFbZGF5XSA9IFsuLi50aGlzLmN1cnJlbnRNb250aERhdGFbZGF5XSwgZGF0ZV07XHJcbiAgICAgIHRoaXMuc2V0TW9udGhEYXRhQWZ0ZXIoKytkYXksICsrZGF0ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjcmVhdGVFbXB0eVNwYWNlcygpIHtcclxuICAgIC8vIGZpcnN0IGZpbmQgb3V0IHdoaWNoIGRheSBoYXMgdGhlIDFzdFxyXG4gICAgLy8gIGlmIGl0cyBhIFN1bmRheSwgdGhlbiBkb24ndCBkbyBhbnl0aGluZyBlbHNlIGFkZCAxIHNwYWNlIG9uIGVhY2ggcHJldmlvdXMgZGF5XHJcbiAgICBsZXQgZGF5SW5kZXggPSAwO1xyXG4gICAgT2JqZWN0LnZhbHVlcyh0aGlzLmN1cnJlbnRNb250aERhdGEpLmZpbmQoKHZhbHVlLCBpbmRleCkgPT4ge1xyXG4gICAgICBpZiAodmFsdWUuaW5jbHVkZXMoMSkpIHtcclxuICAgICAgICBkYXlJbmRleCA9IGluZGV4O1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiB2YWx1ZS5pbmNsdWRlcygxKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGlmIChkYXlJbmRleCkge1xyXG4gICAgICBmb3IgKGRheUluZGV4OyBkYXlJbmRleCA+IDA7IGRheUluZGV4LS0pIHtcclxuICAgICAgICBjb25zdCBtb250aERhdGEgPSB0aGlzLmN1cnJlbnRNb250aERhdGFbZGF5SW5kZXggLSAxXTtcclxuICAgICAgICB0aGlzLmN1cnJlbnRNb250aERhdGFbZGF5SW5kZXggLSAxXSA9IFtudWxsLCAuLi5tb250aERhdGFdO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzZWxlY3REYXRlKGRheTogbnVtYmVyKSB7XHJcbiAgICB0aGlzLnNlbGVjdGVkRGF0ZSA9IHsgLi4udGhpcy5jdXJyZW50TmVwYWxpRGF0ZSwgZGF5IH07XHJcbiAgICB0aGlzLmZvcm1hdFZhbHVlKCk7XHJcbiAgICB0aGlzLmNsb3NlKCk7XHJcbiAgICB0aGlzLnByb3BhZ2F0ZUNoYW5nZSh0aGlzLnNlbGVjdGVkRGF0ZSk7XHJcbiAgfVxyXG5cclxuICBzZWxlY3RZZWFyKHllYXI6IHN0cmluZykge1xyXG4gICAgdGhpcy5jdXJyZW50TmVwYWxpRGF0ZS55ZWFyID0gK3llYXI7XHJcbiAgICBjb25zdCBuZXdEYXRlID0gbmV3IE5lcGFsaURhdGVDb252ZXJ0ZXIoXHJcbiAgICAgIHRoaXMuY3VycmVudE5lcGFsaURhdGUueWVhcixcclxuICAgICAgdGhpcy5jdXJyZW50TmVwYWxpRGF0ZS5tb250aCxcclxuICAgICAgdGhpcy5jdXJyZW50TmVwYWxpRGF0ZS5kYXlcclxuICAgICk7XHJcbiAgICB0aGlzLmN1cnJlbnREYXRlID0gbmV3RGF0ZS5nZXRFbmdsaXNoRGF0ZSgpO1xyXG4gICAgdGhpcy5zZXRDdXJyZW50TW9udGhEYXRhKCk7XHJcbiAgfVxyXG5cclxuICBzZWxlY3RNb250aChtb250aDogc3RyaW5nKSB7XHJcbiAgICB0aGlzLmN1cnJlbnROZXBhbGlEYXRlLm1vbnRoID0gdGhpcy5tb250aHNNYXBwaW5nW3RoaXMubGFuZ3VhZ2VdW1xyXG4gICAgICB0aGlzLm1vbnRoRGlzcGxheVR5cGVcclxuICAgIF0uaW5kZXhPZihtb250aCk7XHJcbiAgICBjb25zdCBuZXdEYXRlID0gbmV3IE5lcGFsaURhdGVDb252ZXJ0ZXIoXHJcbiAgICAgIHRoaXMuY3VycmVudE5lcGFsaURhdGUueWVhcixcclxuICAgICAgdGhpcy5jdXJyZW50TmVwYWxpRGF0ZS5tb250aCxcclxuICAgICAgdGhpcy5jdXJyZW50TmVwYWxpRGF0ZS5kYXlcclxuICAgICk7XHJcbiAgICB0aGlzLmN1cnJlbnREYXRlID0gbmV3RGF0ZS5nZXRFbmdsaXNoRGF0ZSgpO1xyXG4gICAgdGhpcy5zZXRDdXJyZW50TW9udGhEYXRhKCk7XHJcbiAgfVxyXG5cclxuICB0b2dnbGVPcGVuKCkge1xyXG4gICAgaWYgKCF0aGlzLmFsd2F5c1Zpc2libGUpIHtcclxuICAgICAgdGhpcy5pc09wZW4gPSAhdGhpcy5pc09wZW47XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvcGVuKCkge1xyXG4gICAgdGhpcy5pc09wZW4gPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgY2xvc2UoKSB7XHJcbiAgICB0aGlzLmlzT3BlbiA9IGZhbHNlO1xyXG4gICAgdGhpcy5zZXRDdXJyZW50RGF0ZSgpO1xyXG4gIH1cclxufVxyXG4iXX0=