@clr/angular
Version:
Angular components for Clarity
156 lines • 22.6 kB
JavaScript
/*
* Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
import { NO_OF_DAYS_IN_A_WEEK, NO_OF_ROWS_IN_CALENDAR_VIEW, TOTAL_DAYS_IN_DAYS_VIEW } from '../utils/constants';
import { getDay } from '../utils/date-utils';
import { DayViewModel } from './day-view.model';
import { DayModel } from './day.model';
export class CalendarViewModel {
constructor(calendar, selectedDay, focusableDay, today, firstDayOfWeek, excludedDates) {
this.calendar = calendar;
this.selectedDay = selectedDay;
this.focusableDay = focusableDay;
this.today = today;
this.firstDayOfWeek = firstDayOfWeek;
this.excludedDates = excludedDates;
this.currMonthDayViews = [];
this.initializeCalendarView();
}
/**
* DayViewModel matrix. Size 6x7
*/
get calendarView() {
return this._calendarView;
}
/**
* Updates the focusable day in the calendar.
*/
updateFocusableDay(day) {
this.setFocusableFlag(this.focusableDay, false);
this.setFocusableFlag(day, true);
this.focusableDay = day;
}
/**
* Generates a 6x7 matrix of DayViewModel based on the Calendar.
* The 6x7 matrix is structured according to the first day of the week.
* 6 rows to accommodate months which might have dates spanning over 6 weeks.
* 7 columns because there are 7 days in a week :P :D
*/
initializeCalendarView() {
// Generate prev and next month calendar models.
const prevMonthCalendar = this.calendar.previousMonth();
const nextMonthCalendar = this.calendar.nextMonth();
// Get no of days from prev and next months.
const daysFromPrevMonthInCalView = this.numDaysFromPrevMonthInCalView(this.calendar.year, this.calendar.month);
const daysFromNextMonthInCalView = TOTAL_DAYS_IN_DAYS_VIEW - (this.calendar.days.length + daysFromPrevMonthInCalView);
// Generate prev, curr and next day view models
let prevMonthDayViews = [];
let nextMonthDayViews = [];
if (daysFromPrevMonthInCalView > 0) {
prevMonthDayViews = this.generateDayViewModels(prevMonthCalendar.days.slice(-1 * daysFromPrevMonthInCalView), true, false);
}
this.currMonthDayViews = this.generateDayViewModels(this.calendar.days, false, true);
if (daysFromNextMonthInCalView > 0) {
nextMonthDayViews = this.generateDayViewModels(nextMonthCalendar.days.slice(0, daysFromNextMonthInCalView), true, false);
}
// Generate calendar view and initialize flags
this._calendarView = this.generateCalendarView(prevMonthDayViews, this.currMonthDayViews, nextMonthDayViews);
this.initializeSelectedDay();
this.initializeFocusableDay();
}
isDateExcluded(date) {
const { minDate, maxDate } = this.excludedDates;
const from = minDate.toComparisonString();
const to = maxDate.toComparisonString();
const today = date.toComparisonString();
return !(today >= from && today <= to);
}
/**
* Generates a DayViewModel array based on the DayModel passed
*/
generateDayViewModels(days, isExcluded, isCurrentCalendar) {
const dayViews = days.map(day => {
return new DayViewModel(day, false, isExcluded, this.isDateExcluded(day), false, false);
});
if (isCurrentCalendar && this.calendar.isDayInCalendar(this.today)) {
dayViews[this.today.date - 1].isTodaysDate = true;
}
return dayViews;
}
/**
* Gets the first day of the current month to figure out how many dates of previous month
* are needed to complete the Calendar View based on the first day of the week.
* eg: Assuming locale en-US, the first day of the week is Sunday,
* if first day of the current month lands on Wednesday, then
* (this.getDay function would return 3 since
* first day of the week is 0), we need the 3 days from the previous month.
*/
numDaysFromPrevMonthInCalView(currentYear, currentMonth) {
const firstDayOfCurrMonth = getDay(currentYear, currentMonth, 1);
if (firstDayOfCurrMonth >= this.firstDayOfWeek) {
return firstDayOfCurrMonth - this.firstDayOfWeek;
}
else {
return NO_OF_DAYS_IN_A_WEEK + firstDayOfCurrMonth - this.firstDayOfWeek;
}
}
/**
* Checks if the Day passed is in the CalendarView.
*/
isDayInCalendarView(day) {
if (!this.calendar.isDayInCalendar(day)) {
return false;
}
return true;
}
/**
* Using the DayViewModels from the previous, current and next month, this function
* generates the CalendarView.
*/
generateCalendarView(prev, curr, next) {
const combinationArr = [...prev, ...curr, ...next];
const calendarView = [];
for (let i = 0; i < NO_OF_ROWS_IN_CALENDAR_VIEW; i++) {
calendarView[i] = combinationArr.slice(i * NO_OF_DAYS_IN_A_WEEK, (i + 1) * NO_OF_DAYS_IN_A_WEEK);
}
return calendarView;
}
/**
* Initialize the selected day if the day is in the calendar.
*/
initializeSelectedDay() {
if (this.selectedDay && this.isDayInCalendarView(this.selectedDay)) {
this.currMonthDayViews[this.selectedDay.date - 1].isSelected = true;
}
}
/**
* Initializes the focusable day if the day is in the calendar. If focusable day is not set, then
* we check for the selected day. If selected day is not set then check if today is in the current
* calendar. If not then just set the 15th of the current calendar month.
*/
initializeFocusableDay() {
if (this.focusableDay && this.isDayInCalendarView(this.focusableDay)) {
this.setFocusableFlag(this.focusableDay, true);
}
else if (this.selectedDay && this.isDayInCalendarView(this.selectedDay)) {
this.setFocusableFlag(this.selectedDay, true);
this.focusableDay = this.selectedDay.clone();
}
else if (this.isDayInCalendarView(this.today)) {
this.setFocusableFlag(this.today, true);
this.focusableDay = this.today.clone();
}
else {
this.focusableDay = new DayModel(this.calendar.year, this.calendar.month, 15);
this.setFocusableFlag(this.focusableDay, true);
}
}
setFocusableFlag(day, flag) {
if (day) {
this.currMonthDayViews[day.date - 1].isFocusable = flag;
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXItdmlldy5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXIvc3JjL2Zvcm1zL2RhdGVwaWNrZXIvbW9kZWwvY2FsZW5kYXItdmlldy5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBR0gsT0FBTyxFQUFFLG9CQUFvQixFQUFFLDJCQUEyQixFQUFFLHVCQUF1QixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDaEgsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRTdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRXZDLE1BQU0sT0FBTyxpQkFBaUI7SUFJNUIsWUFDUyxRQUF1QixFQUN0QixXQUFxQixFQUNyQixZQUFzQixFQUN0QixLQUFlLEVBQ2hCLGNBQXNCLEVBQ3JCLGFBQXdCO1FBTHpCLGFBQVEsR0FBUixRQUFRLENBQWU7UUFDdEIsZ0JBQVcsR0FBWCxXQUFXLENBQVU7UUFDckIsaUJBQVksR0FBWixZQUFZLENBQVU7UUFDdEIsVUFBSyxHQUFMLEtBQUssQ0FBVTtRQUNoQixtQkFBYyxHQUFkLGNBQWMsQ0FBUTtRQUNyQixrQkFBYSxHQUFiLGFBQWEsQ0FBVztRQVQxQixzQkFBaUIsR0FBbUIsRUFBRSxDQUFDO1FBVzdDLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7T0FFRztJQUNILElBQUksWUFBWTtRQUNkLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM1QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxrQkFBa0IsQ0FBQyxHQUFhO1FBQzlCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FB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RSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztZQUM5RSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsQ0FBQztTQUNoRDtJQUNILENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxHQUFhLEVBQUUsSUFBYTtRQUNuRCxJQUFJLEdBQUcsRUFBRTtZQUNQLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7U0FDekQ7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE2LTIwMjMgVk13YXJlLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBUaGlzIHNvZnR3YXJlIGlzIHJlbGVhc2VkIHVuZGVyIE1JVCBsaWNlbnNlLlxuICogVGhlIGZ1bGwgbGljZW5zZSBpbmZvcm1hdGlvbiBjYW4gYmUgZm91bmQgaW4gTElDRU5TRSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBwcm9qZWN0LlxuICovXG5cbmltcG9ydCB7IERhdGVSYW5nZSB9IGZyb20gJy4uL2ludGVyZmFjZXMvZGF0ZS1yYW5nZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgTk9fT0ZfREFZU19JTl9BX1dFRUssIE5PX09GX1JPV1NfSU5fQ0FMRU5EQVJfVklFVywgVE9UQUxfREFZU19JTl9EQVlTX1ZJRVcgfSBmcm9tICcuLi91dGlscy9jb25zdGFudHMnO1xuaW1wb3J0IHsgZ2V0RGF5IH0gZnJvbSAnLi4vdXRpbHMvZGF0ZS11dGlscyc7XG5pbXBvcnQgeyBDYWxlbmRhck1vZGVsIH0gZnJvbSAnLi9jYWxlbmRhci5tb2RlbCc7XG5pbXBvcnQgeyBEYXlWaWV3TW9kZWwgfSBmcm9tICcuL2RheS12aWV3Lm1vZGVsJztcbmltcG9ydCB7IERheU1vZGVsIH0gZnJvbSAnLi9kYXkubW9kZWwnO1xuXG5leHBvcnQgY2xhc3MgQ2FsZW5kYXJWaWV3TW9kZWwge1xuICBwcml2YXRlIGN1cnJNb250aERheVZpZXdzOiBEYXlWaWV3TW9kZWxbXSA9IFtdO1xuICBwcml2YXRlIF9jYWxlbmRhclZpZXc6IERheVZpZXdNb2RlbFtdW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGNhbGVuZGFyOiBDYWxlbmRhck1vZGVsLFxuICAgIHByaXZhdGUgc2VsZWN0ZWREYXk6IERheU1vZGVsLFxuICAgIHByaXZhdGUgZm9jdXNhYmxlRGF5OiBEYXlNb2RlbCxcbiAgICBwcml2YXRlIHRvZGF5OiBEYXlNb2RlbCxcbiAgICBwdWJsaWMgZmlyc3REYXlPZldlZWs6IG51bWJlcixcbiAgICBwcml2YXRlIGV4Y2x1ZGVkRGF0ZXM6IERhdGVSYW5nZVxuICApIHtcbiAgICB0aGlzLmluaXRpYWxpemVDYWxlbmRhclZpZXcoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEYXlWaWV3TW9kZWwgbWF0cml4LiBTaXplIDZ4N1xuICAgKi9cbiAgZ2V0IGNhbGVuZGFyVmlldygpOiBEYXlWaWV3TW9kZWxbXVtdIHtcbiAgICByZXR1cm4gdGhpcy5fY2FsZW5kYXJWaWV3O1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIGZvY3VzYWJsZSBkYXkgaW4gdGhlIGNhbGVuZGFyLlxuICAgKi9cbiAgdXBkYXRlRm9jdXNhYmxlRGF5KGRheTogRGF5TW9kZWwpOiB2b2lkIHtcbiAgICB0aGlzLnNldEZvY3VzYWJsZUZsYWcodGhpcy5mb2N1c2FibGVEYXksIGZhbHNlKTtcbiAgICB0aGlzLnNldEZvY3VzYWJsZUZsYWcoZGF5LCB0cnVlKTtcbiAgICB0aGlzLmZvY3VzYWJsZURheSA9IGRheTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYSA2eDcgbWF0cml4IG9mIERheVZpZXdNb2RlbCBiYXNlZCBvbiB0aGUgQ2FsZW5kYXIuXG4gICAqIFRoZSA2eDcgbWF0cml4IGlzIHN0cnVjdHVyZWQgYWNjb3JkaW5nIHRvIHRoZSBmaXJzdCBkYXkgb2YgdGhlIHdlZWsuXG4gICAqIDYgcm93cyB0byBhY2NvbW1vZGF0ZSBtb250aHMgd2hpY2ggbWlnaHQgaGF2ZSBkYXRlcyBzcGFubmluZyBvdmVyIDYgd2Vla3MuXG4gICAqIDcgY29sdW1ucyBiZWNhdXNlIHRoZXJlIGFyZSA3IGRheXMgaW4gYSB3ZWVrIDpQIDpEXG4gICAqL1xuICBwcml2YXRlIGluaXRpYWxpemVDYWxlbmRhclZpZXcoKTogdm9pZCB7XG4gICAgLy8gR2VuZXJhdGUgcHJldiBhbmQgbmV4dCBtb250aCBjYWxlbmRhciBtb2RlbHMuXG4gICAgY29uc3QgcHJldk1vbnRoQ2FsZW5kYXI6IENhbGVuZGFyTW9kZWwgPSB0aGlzLmNhbGVuZGFyLnByZXZpb3VzTW9udGgoKTtcbiAgICBjb25zdCBuZXh0TW9udGhDYWxlbmRhcjogQ2FsZW5kYXJNb2RlbCA9IHRoaXMuY2FsZW5kYXIubmV4dE1vbnRoKCk7XG5cbiAgICAvLyBHZXQgbm8gb2YgZGF5cyBmcm9tIHByZXYgYW5kIG5leHQgbW9udGhzLlxuICAgIGNvbnN0IGRheXNGcm9tUHJldk1vbnRoSW5DYWxWaWV3OiBudW1iZXIgPSB0aGlzLm51bURheXNGcm9tUHJldk1vbnRoSW5DYWxWaWV3KFxuICAgICAgdGhpcy5jYWxlbmRhci55ZWFyLFxuICAgICAgdGhpcy5jYWxlbmRhci5tb250aFxuICAgICk7XG4gICAgY29uc3QgZGF5c0Zyb21OZXh0TW9udGhJbkNhbFZpZXc6IG51bWJlciA9XG4gICAgICBUT1RBTF9EQVlTX0lOX0RBWVNfVklFVyAtICh0aGlzLmNhbGVuZGFyLmRheXMubGVuZ3RoICsgZGF5c0Zyb21QcmV2TW9udGhJbkNhbFZpZXcpO1xuXG4gICAgLy8gR2VuZXJhdGUgcHJldiwgY3VyciBhbmQgbmV4dCBkYXkgdmlldyBtb2RlbHNcbiAgICBsZXQgcHJldk1vbnRoRGF5Vmlld3M6IERheVZpZXdNb2RlbFtdID0gW107XG4gICAgbGV0IG5leHRNb250aERheVZpZXdzOiBEYXlWaWV3TW9kZWxbXSA9IFtdO1xuXG4gICAgaWYgKGRheXNGcm9tUHJldk1vbnRoSW5DYWxWaWV3ID4gMCkge1xuICAgICAgcHJldk1vbnRoRGF5Vmlld3MgPSB0aGlzLmdlbmVyYXRlRGF5Vmlld01vZGVscyhcbiAgICAgICAgcHJldk1vbnRoQ2FsZW5kYXIuZGF5cy5zbGljZSgtMSAqIGRheXNGcm9tUHJldk1vbnRoSW5DYWxWaWV3KSxcbiAgICAgICAgdHJ1ZSxcbiAgICAgICAgZmFsc2VcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5jdXJyTW9udGhEYXlWaWV3cyA9IHRoaXMuZ2VuZXJhdGVEYXlWaWV3TW9kZWxzKHRoaXMuY2FsZW5kYXIuZGF5cywgZmFsc2UsIHRydWUpO1xuXG4gICAgaWYgKGRheXNGcm9tTmV4dE1vbnRoSW5DYWxWaWV3ID4gMCkge1xuICAgICAgbmV4dE1vbnRoRGF5Vmlld3MgPSB0aGlzLmdlbmVyYXRlRGF5Vmlld01vZGVscyhcbiAgICAgICAgbmV4dE1vbnRoQ2FsZW5kYXIuZGF5cy5zbGljZSgwLCBkYXlzRnJvbU5leHRNb250aEluQ2FsVmlldyksXG4gICAgICAgIHRydWUsXG4gICAgICAgIGZhbHNlXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIEdlbmVyYXRlIGNhbGVuZGFyIHZpZXcgYW5kIGluaXRpYWxpemUgZmxhZ3NcbiAgICB0aGlzLl9jYWxlbmRhclZpZXcgPSB0aGlzLmdlbmVyYXRlQ2FsZW5kYXJWaWV3KHByZXZNb250aERheVZpZXdzLCB0aGlzLmN1cnJNb250aERheVZpZXdzLCBuZXh0TW9udGhEYXlWaWV3cyk7XG4gICAgdGhpcy5pbml0aWFsaXplU2VsZWN0ZWREYXkoKTtcbiAgICB0aGlzLmluaXRpYWxpemVGb2N1c2FibGVEYXkoKTtcbiAgfVxuXG4gIHByaXZhdGUgaXNEYXRlRXhjbHVkZWQoZGF0ZTogRGF5TW9kZWwpIHtcbiAgICBjb25zdCB7IG1pbkRhdGUsIG1heERhdGUgfTogRGF0ZVJhbmdlID0gdGhpcy5leGNsdWRlZERhdGVzO1xuICAgIGNvbnN0IGZyb20gPSBtaW5EYXRlLnRvQ29tcGFyaXNvblN0cmluZygpO1xuICAgIGNvbnN0IHRvID0gbWF4RGF0ZS50b0NvbXBhcmlzb25TdHJpbmcoKTtcbiAgICBjb25zdCB0b2RheSA9IGRhdGUudG9Db21wYXJpc29uU3RyaW5nKCk7XG5cbiAgICByZXR1cm4gISh0b2RheSA+PSBmcm9tICYmIHRvZGF5IDw9IHRvKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYSBEYXlWaWV3TW9kZWwgYXJyYXkgYmFzZWQgb24gdGhlIERheU1vZGVsIHBhc3NlZFxuICAgKi9cbiAgcHJpdmF0ZSBnZW5lcmF0ZURheVZpZXdNb2RlbHMoZGF5czogRGF5TW9kZWxbXSwgaXNFeGNsdWRlZDogYm9vbGVhbiwgaXNDdXJyZW50Q2FsZW5kYXI6IGJvb2xlYW4pOiBEYXlWaWV3TW9kZWxbXSB7XG4gICAgY29uc3QgZGF5Vmlld3M6IERheVZpZXdNb2RlbFtdID0gZGF5cy5tYXAoZGF5ID0+IHtcbiAgICAgIHJldHVybiBuZXcgRGF5Vmlld01vZGVsKGRheSwgZmFsc2UsIGlzRXhjbHVkZWQsIHRoaXMuaXNEYXRlRXhjbHVkZWQoZGF5KSwgZmFsc2UsIGZhbHNlKTtcbiAgICB9KTtcbiAgICBpZiAoaXNDdXJyZW50Q2FsZW5kYXIgJiYgdGhpcy5jYWxlbmRhci5pc0RheUluQ2FsZW5kYXIodGhpcy50b2RheSkpIHtcbiAgICAgIGRheVZpZXdzW3RoaXMudG9kYXkuZGF0ZSAtIDFdLmlzVG9kYXlzRGF0ZSA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBkYXlWaWV3cztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBmaXJzdCBkYXkgb2YgdGhlIGN1cnJlbnQgbW9udGggdG8gZmlndXJlIG91dCBob3cgbWFueSBkYXRlcyBvZiBwcmV2aW91cyBtb250aFxuICAgKiBhcmUgbmVlZGVkIHRvIGNvbXBsZXRlIHRoZSBDYWxlbmRhciBWaWV3IGJhc2VkIG9uIHRoZSBmaXJzdCBkYXkgb2YgdGhlIHdlZWsuXG4gICAqIGVnOiBBc3N1bWluZyBsb2NhbGUgZW4tVVMsIHRoZSBmaXJzdCBkYXkgb2YgdGhlIHdlZWsgaXMgU3VuZGF5LFxuICAgKiBpZiBmaXJzdCBkYXkgb2YgdGhlIGN1cnJlbnQgbW9udGggbGFuZHMgb24gV2VkbmVzZGF5LCB0aGVuXG4gICAqICh0aGlzLmdldERheSBmdW5jdGlvbiB3b3VsZCByZXR1cm4gMyBzaW5jZVxuICAgKiBmaXJzdCBkYXkgb2YgdGhlIHdlZWsgaXMgMCksIHdlIG5lZWQgdGhlIDMgZGF5cyBmcm9tIHRoZSBwcmV2aW91cyBtb250aC5cbiAgICovXG4gIHByaXZhdGUgbnVtRGF5c0Zyb21QcmV2TW9udGhJbkNhbFZpZXcoY3VycmVudFllYXI6IG51bWJlciwgY3VycmVudE1vbnRoOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGNvbnN0IGZpcnN0RGF5T2ZDdXJyTW9udGg6IG51bWJlciA9IGdldERheShjdXJyZW50WWVhciwgY3VycmVudE1vbnRoLCAxKTtcblxuICAgIGlmIChmaXJzdERheU9mQ3Vyck1vbnRoID49IHRoaXMuZmlyc3REYXlPZldlZWspIHtcbiAgICAgIHJldHVybiBmaXJzdERheU9mQ3Vyck1vbnRoIC0gdGhpcy5maXJzdERheU9mV2VlaztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIE5PX09GX0RBWVNfSU5fQV9XRUVLICsgZmlyc3REYXlPZkN1cnJNb250aCAtIHRoaXMuZmlyc3REYXlPZldlZWs7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgRGF5IHBhc3NlZCBpcyBpbiB0aGUgQ2FsZW5kYXJWaWV3LlxuICAgKi9cbiAgcHJpdmF0ZSBpc0RheUluQ2FsZW5kYXJWaWV3KGRheTogRGF5TW9kZWwpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMuY2FsZW5kYXIuaXNEYXlJbkNhbGVuZGFyKGRheSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogVXNpbmcgdGhlIERheVZpZXdNb2RlbHMgZnJvbSB0aGUgcHJldmlvdXMsIGN1cnJlbnQgYW5kIG5leHQgbW9udGgsIHRoaXMgZnVuY3Rpb25cbiAgICogZ2VuZXJhdGVzIHRoZSBDYWxlbmRhclZpZXcuXG4gICAqL1xuICBwcml2YXRlIGdlbmVyYXRlQ2FsZW5kYXJWaWV3KHByZXY6IERheVZpZXdNb2RlbFtdLCBjdXJyOiBEYXlWaWV3TW9kZWxbXSwgbmV4dDogRGF5Vmlld01vZGVsW10pOiBEYXlWaWV3TW9kZWxbXVtdIHtcbiAgICBjb25zdCBjb21iaW5hdGlvbkFycjogRGF5Vmlld01vZGVsW10gPSBbLi4ucHJldiwgLi4uY3VyciwgLi4ubmV4dF07XG5cbiAgICBjb25zdCBjYWxlbmRhclZpZXc6IERheVZpZXdNb2RlbFtdW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IE5PX09GX1JPV1NfSU5fQ0FMRU5EQVJfVklFVzsgaSsrKSB7XG4gICAgICBjYWxlbmRhclZpZXdbaV0gPSBjb21iaW5hdGlvbkFyci5zbGljZShpICogTk9fT0ZfREFZU19JTl9BX1dFRUssIChpICsgMSkgKiBOT19PRl9EQVlTX0lOX0FfV0VFSyk7XG4gICAgfVxuICAgIHJldHVybiBjYWxlbmRhclZpZXc7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSB0aGUgc2VsZWN0ZWQgZGF5IGlmIHRoZSBkYXkgaXMgaW4gdGhlIGNhbGVuZGFyLlxuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplU2VsZWN0ZWREYXkoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWREYXkgJiYgdGhpcy5pc0RheUluQ2FsZW5kYXJWaWV3KHRoaXMuc2VsZWN0ZWREYXkpKSB7XG4gICAgICB0aGlzLmN1cnJNb250aERheVZpZXdzW3RoaXMuc2VsZWN0ZWREYXkuZGF0ZSAtIDFdLmlzU2VsZWN0ZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyB0aGUgZm9jdXNhYmxlIGRheSBpZiB0aGUgZGF5IGlzIGluIHRoZSBjYWxlbmRhci4gSWYgZm9jdXNhYmxlIGRheSBpcyBub3Qgc2V0LCB0aGVuXG4gICAqIHdlIGNoZWNrIGZvciB0aGUgc2VsZWN0ZWQgZGF5LiBJZiBzZWxlY3RlZCBkYXkgaXMgbm90IHNldCB0aGVuIGNoZWNrIGlmIHRvZGF5IGlzIGluIHRoZSBjdXJyZW50XG4gICAqIGNhbGVuZGFyLiBJZiBub3QgdGhlbiBqdXN0IHNldCB0aGUgMTV0aCBvZiB0aGUgY3VycmVudCBjYWxlbmRhciBtb250aC5cbiAgICovXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUZvY3VzYWJsZURheSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5mb2N1c2FibGVEYXkgJiYgdGhpcy5pc0RheUluQ2FsZW5kYXJWaWV3KHRoaXMuZm9jdXNhYmxlRGF5KSkge1xuICAgICAgdGhpcy5zZXRGb2N1c2FibGVGbGFnKHRoaXMuZm9jdXNhYmxlRGF5LCB0cnVlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWREYXkgJiYgdGhpcy5pc0RheUluQ2FsZW5kYXJWaWV3KHRoaXMuc2VsZWN0ZWREYXkpKSB7XG4gICAgICB0aGlzLnNldEZvY3VzYWJsZUZsYWcodGhpcy5zZWxlY3RlZERheSwgdHJ1ZSk7XG4gICAgICB0aGlzLmZvY3VzYWJsZURheSA9IHRoaXMuc2VsZWN0ZWREYXkuY2xvbmUoKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuaXNEYXlJbkNhbGVuZGFyVmlldyh0aGlzLnRvZGF5KSkge1xuICAgICAgdGhpcy5zZXRGb2N1c2FibGVGbGFnKHRoaXMudG9kYXksIHRydWUpO1xuICAgICAgdGhpcy5mb2N1c2FibGVEYXkgPSB0aGlzLnRvZGF5LmNsb25lKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZm9jdXNhYmxlRGF5ID0gbmV3IERheU1vZGVsKHRoaXMuY2FsZW5kYXIueWVhciwgdGhpcy5jYWxlbmRhci5tb250aCwgMTUpO1xuICAgICAgdGhpcy5zZXRGb2N1c2FibGVGbGFnKHRoaXMuZm9jdXNhYmxlRGF5LCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldEZvY3VzYWJsZUZsYWcoZGF5OiBEYXlNb2RlbCwgZmxhZzogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmIChkYXkpIHtcbiAgICAgIHRoaXMuY3Vyck1vbnRoRGF5Vmlld3NbZGF5LmRhdGUgLSAxXS5pc0ZvY3VzYWJsZSA9IGZsYWc7XG4gICAgfVxuICB9XG59XG4iXX0=