UNPKG

@catull/igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

376 lines 40.5 kB
import { __values } from "tslib"; import { DateRangeType } from '../core/dates'; var MDAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; var FEBRUARY = 1; export function range(start, stop, step) { if (start === void 0) { start = 0; } if (step === void 0) { step = 1; } var res = []; var cur = (stop === undefined) ? 0 : start; var max = (stop === undefined) ? start : stop; for (var i = cur; step < 0 ? i > max : i < max; i += step) { res.push(i); } return res; } /** * Returns true for leap years, false for non-leap years. * * @export * @param year * @returns */ export function isLeap(year) { return (year % 4 === 0) && ((year % 100 !== 0) || (year % 400 === 0)); } export function weekDay(year, month, day) { return new Date(year, month, day).getDay(); } /** * Return weekday and number of days for year, month. * * @export * @param year * @param month * @returns */ export function monthRange(year, month) { if ((month < 0) || (month > 11)) { throw new Error('Invalid month specified'); } var day = weekDay(year, month, 1); var nDays = MDAYS[month]; if ((month === FEBRUARY) && (isLeap(year))) { nDays++; } return [day, nDays]; } export function isDateInRanges(date, ranges) { var e_1, _a, e_2, _b; date = new Date(date.getFullYear(), date.getMonth(), date.getDate()); var dateInMs = date.getTime(); if (!ranges) { return false; } try { for (var ranges_1 = __values(ranges), ranges_1_1 = ranges_1.next(); !ranges_1_1.done; ranges_1_1 = ranges_1.next()) { var descriptor = ranges_1_1.value; var dRanges = descriptor.dateRange ? descriptor.dateRange.map(function (r) { return new Date(r.getFullYear(), r.getMonth(), r.getDate()); }) : undefined; switch (descriptor.type) { case (DateRangeType.After): if (dateInMs > dRanges[0].getTime()) { return true; } break; case (DateRangeType.Before): if (dateInMs < dRanges[0].getTime()) { return true; } break; case (DateRangeType.Between): var dRange = dRanges.map(function (d) { return d.getTime(); }); var min = Math.min(dRange[0], dRange[1]); var max = Math.max(dRange[0], dRange[1]); if (dateInMs >= min && dateInMs <= max) { return true; } break; case (DateRangeType.Specific): var datesInMs = dRanges.map(function (d) { return d.getTime(); }); try { for (var datesInMs_1 = (e_2 = void 0, __values(datesInMs)), datesInMs_1_1 = datesInMs_1.next(); !datesInMs_1_1.done; datesInMs_1_1 = datesInMs_1.next()) { var specificDateInMs = datesInMs_1_1.value; if (dateInMs === specificDateInMs) { return true; } } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (datesInMs_1_1 && !datesInMs_1_1.done && (_b = datesInMs_1.return)) _b.call(datesInMs_1); } finally { if (e_2) throw e_2.error; } } break; case (DateRangeType.Weekdays): var day = date.getDay(); if (day % 6 !== 0) { return true; } break; case (DateRangeType.Weekends): var weekday = date.getDay(); if (weekday % 6 === 0) { return true; } break; default: return false; } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (ranges_1_1 && !ranges_1_1.done && (_a = ranges_1.return)) _a.call(ranges_1); } finally { if (e_1) throw e_1.error; } } return false; } export var WEEKDAYS; (function (WEEKDAYS) { WEEKDAYS[WEEKDAYS["SUNDAY"] = 0] = "SUNDAY"; WEEKDAYS[WEEKDAYS["MONDAY"] = 1] = "MONDAY"; WEEKDAYS[WEEKDAYS["TUESDAY"] = 2] = "TUESDAY"; WEEKDAYS[WEEKDAYS["WEDNESDAY"] = 3] = "WEDNESDAY"; WEEKDAYS[WEEKDAYS["THURSDAY"] = 4] = "THURSDAY"; WEEKDAYS[WEEKDAYS["FRIDAY"] = 5] = "FRIDAY"; WEEKDAYS[WEEKDAYS["SATURDAY"] = 6] = "SATURDAY"; })(WEEKDAYS || (WEEKDAYS = {})); var Calendar = /** @class */ (function () { function Calendar(firstWeekDay) { if (firstWeekDay === void 0) { firstWeekDay = WEEKDAYS.SUNDAY; } this._firstWeekDay = firstWeekDay; } Object.defineProperty(Calendar.prototype, "firstWeekDay", { get: function () { return this._firstWeekDay % 7; }, set: function (value) { this._firstWeekDay = value; }, enumerable: true, configurable: true }); /** * Returns an array of weekdays for one week starting * with the currently set `firstWeekDay` * * this.firstWeekDay = 0 (Sunday) --> [0, 1, 2, 3, 4, 5, 6] * this.firstWeekDay = 1 (Monday) --> [1, 2, 3, 4, 5, 6, 0] * * @returns * * @memberof Calendar */ Calendar.prototype.weekdays = function () { var e_3, _a; var res = []; try { for (var _b = __values(range(this.firstWeekDay, this.firstWeekDay + 7)), _c = _b.next(); !_c.done; _c = _b.next()) { var i = _c.value; res.push(i % 7); } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_3) throw e_3.error; } } return res; }; /** * Returns the date values for one month. It will always iterate throught * complete weeks, so it will contain dates outside the specified month. * * @param year * @param month * @param boolean * @returns * * @memberof Calendar */ Calendar.prototype.monthdates = function (year, month, extraWeek) { var e_4, _a; if (extraWeek === void 0) { extraWeek = false; } var date = new Date(year, month, 1); var days = (date.getDay() - this.firstWeekDay) % 7; if (days < 0) { days = 7 - Math.abs(days); } date = this.timedelta(date, 'day', -days); var res = []; var value; while (true) { value = this.generateICalendarDate(date, year, month); res.push(value); date = this.timedelta(date, 'day', 1); if ((date.getMonth() !== month) && (date.getDay() === this.firstWeekDay)) { if (extraWeek && res.length <= 35) { try { for (var _b = (e_4 = void 0, __values(range(0, 7))), _c = _b.next(); !_c.done; _c = _b.next()) { var _ = _c.value; value = this.generateICalendarDate(date, year, month); res.push(value); date = this.timedelta(date, 'day', 1); } } catch (e_4_1) { e_4 = { error: e_4_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_4) throw e_4.error; } } } break; } } return res; }; /** * Returns a matrix (array of arrays) representing a month's calendar. * Each row represents a full week; week entries are ICalendarDate objects. * * @param year * @param month * @returns * * @memberof Calendar */ Calendar.prototype.monthdatescalendar = function (year, month, extraWeek) { var e_5, _a; if (extraWeek === void 0) { extraWeek = false; } var dates = this.monthdates(year, month, extraWeek); var res = []; try { for (var _b = __values(range(0, dates.length, 7)), _c = _b.next(); !_c.done; _c = _b.next()) { var i = _c.value; res.push(dates.slice(i, i + 7)); } } catch (e_5_1) { e_5 = { error: e_5_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_5) throw e_5.error; } } return res; }; Calendar.prototype.timedelta = function (date, interval, units) { var ret = new Date(date); var checkRollover = function () { if (ret.getDate() !== date.getDate()) { ret.setDate(0); } }; switch (interval.toLowerCase()) { case 'year': ret.setFullYear(ret.getFullYear() + units); checkRollover(); break; case 'quarter': ret.setMonth(ret.getMonth() + 3 * units); checkRollover(); break; case 'month': ret.setMonth(ret.getMonth() + units); checkRollover(); break; case 'week': ret.setDate(ret.getDate() + 7 * units); break; case 'day': ret.setDate(ret.getDate() + units); break; case 'hour': ret.setTime(ret.getTime() + units * 3600000); break; case 'minute': ret.setTime(ret.getTime() + units * 60000); break; case 'second': ret.setTime(ret.getTime() + units * 1000); break; default: throw new Error('Invalid interval specifier'); } return ret; }; Calendar.prototype.formatToParts = function (date, locale, options, parts) { var e_6, _a, e_7, _b; var formatter = new Intl.DateTimeFormat(locale, options); var result = { date: date, full: formatter.format(date) }; if (formatter.formatToParts) { var formattedParts_1 = formatter.formatToParts(date); var toType = function (partType) { var index = formattedParts_1.findIndex(function (_a) { var type = _a.type; return type === partType; }); var o = { value: '', literal: '', combined: '' }; if (partType === 'era' && index > -1) { o.value = formattedParts_1[index].value; return o; } else if (partType === 'era' && index === -1) { return o; } o.value = formattedParts_1[index].value; o.literal = formattedParts_1[index + 1] ? formattedParts_1[index + 1].value : ''; o.combined = [o.value, o.literal].join(''); return o; }; try { for (var parts_1 = __values(parts), parts_1_1 = parts_1.next(); !parts_1_1.done; parts_1_1 = parts_1.next()) { var each = parts_1_1.value; result[each] = toType(each); } } catch (e_6_1) { e_6 = { error: e_6_1 }; } finally { try { if (parts_1_1 && !parts_1_1.done && (_a = parts_1.return)) _a.call(parts_1); } finally { if (e_6) throw e_6.error; } } } else { try { for (var parts_2 = __values(parts), parts_2_1 = parts_2.next(); !parts_2_1.done; parts_2_1 = parts_2.next()) { var each = parts_2_1.value; result[each] = { value: '', literal: '', combined: '' }; } } catch (e_7_1) { e_7 = { error: e_7_1 }; } finally { try { if (parts_2_1 && !parts_2_1.done && (_b = parts_2.return)) _b.call(parts_2); } finally { if (e_7) throw e_7.error; } } } return result; }; Calendar.prototype.generateICalendarDate = function (date, year, month) { return { date: date, isCurrentMonth: date.getFullYear() === year && date.getMonth() === month, isNextMonth: this.isNextMonth(date, year, month), isPrevMonth: this.isPreviousMonth(date, year, month) }; }; Calendar.prototype.isPreviousMonth = function (date, year, month) { if (date.getFullYear() === year) { return date.getMonth() < month; } return date.getFullYear() < year; }; Calendar.prototype.isNextMonth = function (date, year, month) { if (date.getFullYear() === year) { return date.getMonth() > month; } return date.getFullYear() > year; }; return Calendar; }()); export { Calendar }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9pZ25pdGV1aS1hbmd1bGFyLyIsInNvdXJjZXMiOlsibGliL2NhbGVuZGFyL2NhbGVuZGFyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQXVCLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuRSxJQUFNLEtBQUssR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDL0QsSUFBTSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBRW5CLE1BQU0sVUFBVSxLQUFLLENBQUMsS0FBUyxFQUFFLElBQUksRUFBRSxJQUFRO0lBQXpCLHNCQUFBLEVBQUEsU0FBUztJQUFRLHFCQUFBLEVBQUEsUUFBUTtJQUMzQyxJQUFNLEdBQUcsR0FBRyxFQUFFLENBQUM7SUFDZixJQUFNLEdBQUcsR0FBRyxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDN0MsSUFBTSxHQUFHLEdBQUcsQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ2hELEtBQUssSUFBSSxDQUFDLEdBQUcsR0FBRyxFQUFFLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLElBQUksRUFBRTtRQUN2RCxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQ2Y7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNmLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxNQUFN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QWUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQztTQUN2RCxDQUFDO0lBQ04sQ0FBQztJQUVPLGtDQUFlLEdBQXZCLFVBQXdCLElBQVUsRUFBRSxJQUFZLEVBQUUsS0FBYTtRQUMzRCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDN0IsT0FBTyxJQUFJLENBQUMsUUFBUSxFQUFFLEdBQUcsS0FBSyxDQUFDO1NBQ2xDO1FBQ0QsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDO0lBQ3JDLENBQUM7SUFFTyw4QkFBVyxHQUFuQixVQUFvQixJQUFVLEVBQUUsSUFBWSxFQUFFLEtBQWE7UUFDdkQsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzdCLE9BQU8sSUFBSSxDQUFDLFFBQVEsRUFBRSxHQUFHLEtBQUssQ0FBQztTQUNsQztRQUVELE9BQU8sSUFBSSxDQUFDLFdBQVcsRUFBRSxHQUFHLElBQUksQ0FBQztJQUNyQyxDQUFDO0lBQ0wsZUFBQztBQUFELENBQUMsQUF4TUQsSUF3TUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEYXRlUmFuZ2VEZXNjcmlwdG9yLCBEYXRlUmFuZ2VUeXBlIH0gZnJvbSAnLi4vY29yZS9kYXRlcyc7XG5cbmNvbnN0IE1EQVlTID0gWzMxLCAyOCwgMzEsIDMwLCAzMSwgMzAsIDMxLCAzMSwgMzAsIDMxLCAzMCwgMzFdO1xuY29uc3QgRkVCUlVBUlkgPSAxO1xuXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2Uoc3RhcnQgPSAwLCBzdG9wLCBzdGVwID0gMSkge1xuICAgIGNvbnN0IHJlcyA9IFtdO1xuICAgIGNvbnN0IGN1ciA9IChzdG9wID09PSB1bmRlZmluZWQpID8gMCA6IHN0YXJ0O1xuICAgIGNvbnN0IG1heCA9IChzdG9wID09PSB1bmRlZmluZWQpID8gc3RhcnQgOiBzdG9wO1xuICAgIGZvciAobGV0IGkgPSBjdXI7IHN0ZXAgPCAwID8gaSA+IG1heCA6IGkgPCBtYXg7IGkgKz0gc3RlcCkge1xuICAgICAgICByZXMucHVzaChpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgZm9yIGxlYXAgeWVhcnMsIGZhbHNlIGZvciBub24tbGVhcCB5ZWFycy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0geWVhclxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTGVhcCh5ZWFyOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKHllYXIgJSA0ID09PSAwKSAmJiAoKHllYXIgJSAxMDAgIT09IDApIHx8ICh5ZWFyICUgNDAwID09PSAwKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB3ZWVrRGF5KHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlciwgZGF5OiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZGF5KS5nZXREYXkoKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gd2Vla2RheSBhbmQgbnVtYmVyIG9mIGRheXMgZm9yIHllYXIsIG1vbnRoLlxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB5ZWFyXG4gKiBAcGFyYW0gbW9udGhcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb250aFJhbmdlKHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlcik6IG51bWJlcltdIHtcbiAgICBpZiAoKG1vbnRoIDwgMCkgfHwgKG1vbnRoID4gMTEpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBtb250aCBzcGVjaWZpZWQnKTtcbiAgICB9XG4gICAgY29uc3QgZGF5ID0gd2Vla0RheSh5ZWFyLCBtb250aCwgMSk7XG4gICAgbGV0IG5EYXlzID0gTURBWVNbbW9udGhdO1xuICAgIGlmICgobW9udGggPT09IEZFQlJVQVJZKSAmJiAoaXNMZWFwKHllYXIpKSkge1xuICAgICAgICBuRGF5cysrO1xuICAgIH1cbiAgICByZXR1cm4gW2RheSwgbkRheXNdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNEYXRlSW5SYW5nZXMoZGF0ZTogRGF0ZSwgcmFuZ2VzOiBEYXRlUmFuZ2VEZXNjcmlwdG9yW10pOiBib29sZWFuIHtcbiAgICBkYXRlID0gbmV3IERhdGUoZGF0ZS5nZXRGdWxsWWVhcigpLCBkYXRlLmdldE1vbnRoKCksIGRhdGUuZ2V0RGF0ZSgpKTtcbiAgICBjb25zdCBkYXRlSW5NcyA9IGRhdGUuZ2V0VGltZSgpO1xuXG4gICAgaWYgKCFyYW5nZXMpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGVzY3JpcHRvciBvZiByYW5nZXMpIHtcbiAgICAgICAgY29uc3QgZFJhbmdlcyA9IGRlc2NyaXB0b3IuZGF0ZVJhbmdlID8gZGVzY3JpcHRvci5kYXRlUmFuZ2UubWFwKFxuICAgICAgICAgICAgciA9PiBuZXcgRGF0ZShyLmdldEZ1bGxZZWFyKCksIHIuZ2V0TW9udGgoKSwgci5nZXREYXRlKCkpKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgc3dpdGNoIChkZXNjcmlwdG9yLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgKERhdGVSYW5nZVR5cGUuQWZ0ZXIpOlxuICAgICAgICAgICAgICAgIGlmIChkYXRlSW5NcyA+IGRSYW5nZXNbMF0uZ2V0VGltZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAoRGF0ZVJhbmdlVHlwZS5CZWZvcmUpOlxuICAgICAgICAgICAgICAgIGlmIChkYXRlSW5NcyA8IGRSYW5nZXNbMF0uZ2V0VGltZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAoRGF0ZVJhbmdlVHlwZS5CZXR3ZWVuKTpcbiAgICAgICAgICAgICAgICBjb25zdCBkUmFuZ2UgPSBkUmFuZ2VzLm1hcChkID0+IGQuZ2V0VGltZSgpKTtcbiAgICAgICAgICAgICAgICBjb25zdCBtaW4gPSBNYXRoLm1pbihkUmFuZ2VbMF0sIGRSYW5nZVsxXSk7XG4gICAgICAgICAgICAgICAgY29uc3QgbWF4ID0gTWF0aC5tYXgoZFJhbmdlWzBdLCBkUmFuZ2VbMV0pO1xuICAgICAgICAgICAgICAgIGlmIChkYXRlSW5NcyA+PSBtaW4gJiYgZGF0ZUluTXMgPD0gbWF4KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAoRGF0ZVJhbmdlVHlwZS5TcGVjaWZpYyk6XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0ZXNJbk1zID0gZFJhbmdlcy5tYXAoZCA9PiBkLmdldFRpbWUoKSk7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBzcGVjaWZpY0RhdGVJbk1zIG9mIGRhdGVzSW5Ncykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZGF0ZUluTXMgPT09IHNwZWNpZmljRGF0ZUluTXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIChEYXRlUmFuZ2VUeXBlLldlZWtkYXlzKTpcbiAgICAgICAgICAgICAgICBjb25zdCBkYXkgPSBkYXRlLmdldERheSgpO1xuICAgICAgICAgICAgICAgIGlmIChkYXkgJSA2ICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAoRGF0ZVJhbmdlVHlwZS5XZWVrZW5kcyk6XG4gICAgICAgICAgICAgICAgY29uc3Qgd2Vla2RheSA9IGRhdGUuZ2V0RGF5KCk7XG4gICAgICAgICAgICAgICAgaWYgKHdlZWtkYXkgJSA2ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUNhbGVuZGFyRGF0ZSB7XG4gICAgZGF0ZTogRGF0ZTtcbiAgICBpc0N1cnJlbnRNb250aDogYm9vbGVhbjtcbiAgICBpc1ByZXZNb250aDogYm9vbGVhbjtcbiAgICBpc05leHRNb250aDogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJRm9ybWF0dGVkUGFydHMge1xuICAgIHZhbHVlOiBzdHJpbmc7XG4gICAgbGl0ZXJhbD86IHN0cmluZztcbiAgICBjb21iaW5lZDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElGb3JtYXR0aW5nT3B0aW9ucyB7XG4gICAgZGF5Pzogc3RyaW5nO1xuICAgIG1vbnRoPzogc3RyaW5nO1xuICAgIHdlZWtkYXk/OiBzdHJpbmc7XG4gICAgeWVhcj86IHN0cmluZztcbn1cblxuXG5leHBvcnQgaW50ZXJmYWNlIElGb3JtYXR0aW5nVmlld3Mge1xuICAgIGRheT86IGJvb2xlYW47XG4gICAgbW9udGg/OiBib29sZWFuO1xuICAgIHllYXI/OiBib29sZWFuO1xufVxuXG5leHBvcnQgZW51bSBXRUVLREFZUyB7XG4gICAgU1VOREFZID0gMCxcbiAgICBNT05EQVkgPSAxLFxuICAgIFRVRVNEQVkgPSAyLFxuICAgIFdFRE5FU0RBWSA9IDMsXG4gICAgVEhVUlNEQVkgPSA0LFxuICAgIEZSSURBWSA9IDUsXG4gICAgU0FUVVJEQVkgPSA2XG59XG5cbmV4cG9ydCBjbGFzcyBDYWxlbmRhciB7XG5cbiAgICBwcml2YXRlIF9maXJzdFdlZWtEYXk6IG51bWJlciB8IFdFRUtEQVlTO1xuXG4gICAgY29uc3RydWN0b3IoZmlyc3RXZWVrRGF5OiBudW1iZXIgfCBXRUVLREFZUyA9IFdFRUtEQVlTLlNVTkRBWSkge1xuICAgICAgICB0aGlzLl9maXJzdFdlZWtEYXkgPSBmaXJzdFdlZWtEYXk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBmaXJzdFdlZWtEYXkoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZpcnN0V2Vla0RheSAlIDc7XG4gICAgfVxuXG4gICAgcHVibGljIHNldCBmaXJzdFdlZWtEYXkodmFsdWU6IG51bWJlcikge1xuICAgICAgICB0aGlzLl9maXJzdFdlZWtEYXkgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHdlZWtkYXlzIGZvciBvbmUgd2VlayBzdGFydGluZ1xuICAgICAqIHdpdGggdGhlIGN1cnJlbnRseSBzZXQgYGZpcnN0V2Vla0RheWBcbiAgICAgKlxuICAgICAqIHRoaXMuZmlyc3RXZWVrRGF5ID0gMCAoU3VuZGF5KSAtLT4gWzAsIDEsIDIsIDMsIDQsIDUsIDZdXG4gICAgICogdGhpcy5maXJzdFdlZWtEYXkgPSAxIChNb25kYXkpIC0tPiBbMSwgMiwgMywgNCwgNSwgNiwgMF1cbiAgICAgKlxuICAgICAqIEByZXR1cm5zXG4gICAgICpcbiAgICAgKiBAbWVtYmVyb2YgQ2FsZW5kYXJcbiAgICAgKi9cbiAgICBwdWJsaWMgd2Vla2RheXMoKTogbnVtYmVyW10ge1xuICAgICAgICBjb25zdCByZXMgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBpIG9mIHJhbmdlKHRoaXMuZmlyc3RXZWVrRGF5LCB0aGlzLmZpcnN0V2Vla0RheSArIDcpKSB7XG4gICAgICAgICAgICByZXMucHVzaChpICUgNyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkYXRlIHZhbHVlcyBmb3Igb25lIG1vbnRoLiBJdCB3aWxsIGFsd2F5cyBpdGVyYXRlIHRocm91Z2h0XG4gICAgICogY29tcGxldGUgd2Vla3MsIHNvIGl0IHdpbGwgY29udGFpbiBkYXRlcyBvdXRzaWRlIHRoZSBzcGVjaWZpZWQgbW9udGguXG4gICAgICpcbiAgICAgKiBAcGFyYW0geWVhclxuICAgICAqIEBwYXJhbSBtb250aFxuICAgICAqIEBwYXJhbSBib29sZWFuXG4gICAgICogQHJldHVybnNcbiAgICAgKlxuICAgICAqIEBtZW1iZXJvZiBDYWxlbmRhclxuICAgICAqL1xuICAgIHB1YmxpYyBtb250aGRhdGVzKHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlciwgZXh0cmFXZWVrOiBib29sZWFuID0gZmFsc2UpOiBJQ2FsZW5kYXJEYXRlW10ge1xuICAgICAgICBsZXQgZGF0ZSA9IG5ldyBEYXRlKHllYXIsIG1vbnRoLCAxKTtcbiAgICAgICAgbGV0IGRheXMgPSAoZGF0ZS5nZXREYXkoKSAtIHRoaXMuZmlyc3RXZWVrRGF5KSAlIDc7XG4gICAgICAgIGlmIChkYXlzIDwgMCkge1xuICAgICAgICAgICAgZGF5cyA9IDcgLSBNYXRoLmFicyhkYXlzKTtcbiAgICAgICAgfVxuICAgICAgICBkYXRlID0gdGhpcy50aW1lZGVsdGEoZGF0ZSwgJ2RheScsIC1kYXlzKTtcbiAgICAgICAgY29uc3QgcmVzID0gW107XG4gICAgICAgIGxldCB2YWx1ZTogSUNhbGVuZGFyRGF0ZTtcblxuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuXG4gICAgICAgICAgICB2YWx1ZSA9IHRoaXMuZ2VuZXJhdGVJQ2FsZW5kYXJEYXRlKGRhdGUsIHllYXIsIG1vbnRoKTtcbiAgICAgICAgICAgIHJlcy5wdXNoKHZhbHVlKTtcblxuICAgICAgICAgICAgZGF0ZSA9IHRoaXMudGltZWRlbHRhKGRhdGUsICdkYXknLCAxKTtcblxuICAgICAgICAgICAgaWYgKChkYXRlLmdldE1vbnRoKCkgIT09IG1vbnRoKSAmJiAoZGF0ZS5nZXREYXkoKSA9PT0gdGhpcy5maXJzdFdlZWtEYXkpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV4dHJhV2VlayAmJiByZXMubGVuZ3RoIDw9IDM1KSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgXyBvZiByYW5nZSgwLCA3KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLmdlbmVyYXRlSUNhbGVuZGFyRGF0ZShkYXRlLCB5ZWFyLCBtb250aCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXMucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRlID0gdGhpcy50aW1lZGVsdGEoZGF0ZSwgJ2RheScsIDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIG1hdHJpeCAoYXJyYXkgb2YgYXJyYXlzKSByZXByZXNlbnRpbmcgYSBtb250aCdzIGNhbGVuZGFyLlxuICAgICAqIEVhY2ggcm93IHJlcHJlc2VudHMgYSBmdWxsIHdlZWs7IHdlZWsgZW50cmllcyBhcmUgSUNhbGVuZGFyRGF0ZSBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHllYXJcbiAgICAgKiBAcGFyYW0gbW9udGhcbiAgICAgKiBAcmV0dXJuc1xuICAgICAqXG4gICAgICogQG1lbWJlcm9mIENhbGVuZGFyXG4gICAgICovXG4gICAgcHVibGljIG1vbnRoZGF0ZXNjYWxlbmRhcih5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXIsIGV4dHJhV2VlazogYm9vbGVhbiA9IGZhbHNlKTogSUNhbGVuZGFyRGF0ZVtdW10ge1xuICAgICAgICBjb25zdCBkYXRlcyA9IHRoaXMubW9udGhkYXRlcyh5ZWFyLCBtb250aCwgZXh0cmFXZWVrKTtcbiAgICAgICAgY29uc3QgcmVzID0gW107XG4gICAgICAgIGZvciAoY29uc3QgaSBvZiByYW5nZSgwLCBkYXRlcy5sZW5ndGgsIDcpKSB7XG4gICAgICAgICAgICByZXMucHVzaChkYXRlcy5zbGljZShpLCBpICsgNykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgcHVibGljIHRpbWVkZWx0YShkYXRlOiBEYXRlLCBpbnRlcnZhbDogc3RyaW5nLCB1bml0czogbnVtYmVyKTogRGF0ZSB7XG4gICAgICAgIGNvbnN0IHJldCA9IG5ldyBEYXRlKGRhdGUpO1xuXG4gICAgICAgIGNvbnN0IGNoZWNrUm9sbG92ZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAocmV0LmdldERhdGUoKSAhPT0gZGF0ZS5nZXREYXRlKCkpIHtcbiAgICAgICAgICAgICAgICByZXQuc2V0RGF0ZSgwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBzd2l0Y2ggKGludGVydmFsLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgJ3llYXInOlxuICAgICAgICAgICAgICAgIHJldC5zZXRGdWxsWWVhcihyZXQuZ2V0RnVsbFllYXIoKSArIHVuaXRzKTtcbiAgICAgICAgICAgICAgICBjaGVja1JvbGxvdmVyKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdxdWFydGVyJzpcbiAgICAgICAgICAgICAgICByZXQuc2V0TW9udGgocmV0LmdldE1vbnRoKCkgKyAzICogdW5pdHMpO1xuICAgICAgICAgICAgICAgIGNoZWNrUm9sbG92ZXIoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgICAgICAgICAgICByZXQuc2V0TW9udGgocmV0LmdldE1vbnRoKCkgKyB1bml0cyk7XG4gICAgICAgICAgICAgICAgY2hlY2tSb2xsb3ZlcigpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnd2Vlayc6XG4gICAgICAgICAgICAgICAgcmV0LnNldERhdGUocmV0LmdldERhdGUoKSArIDcgKiB1bml0cyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdkYXknOlxuICAgICAgICAgICAgICAgIHJldC5zZXREYXRlKHJldC5nZXREYXRlKCkgKyB1bml0cyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgICAgICAgICByZXQuc2V0VGltZShyZXQuZ2V0VGltZSgpICsgdW5pdHMgKiAzNjAwMDAwKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ21pbnV0ZSc6XG4gICAgICAgICAgICAgICAgcmV0LnNldFRpbWUocmV0LmdldFRpbWUoKSArIHVuaXRzICogNjAwMDApO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgICByZXQuc2V0VGltZShyZXQuZ2V0VGltZSgpICsgdW5pdHMgKiAxMDAwKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGludGVydmFsIHNwZWNpZmllcicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgcHVibGljIGZvcm1hdFRvUGFydHMoZGF0ZTogRGF0ZSwgbG9jYWxlOiBzdHJpbmcsIG9wdGlvbnM6IGFueSwgcGFydHM6IHN0cmluZ1tdKSB7XG4gICAgICAgIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBJbnRsLkRhdGVUaW1lRm9ybWF0KGxvY2FsZSwgb3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHtcbiAgICAgICAgICAgIGRhdGUsXG4gICAgICAgICAgICBmdWxsOiBmb3JtYXR0ZXIuZm9ybWF0KGRhdGUpXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKChmb3JtYXR0ZXIgYXMgYW55KS5mb3JtYXRUb1BhcnRzKSB7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWRQYXJ0cyA9IChmb3JtYXR0ZXIgYXMgYW55KS5mb3JtYXRUb1BhcnRzKGRhdGUpO1xuXG4gICAgICAgICAgICBjb25zdCB0b1R5cGUgPSAocGFydFR5cGU6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gZm9ybWF0dGVkUGFydHMuZmluZEluZGV4KCh7IHR5cGUgfSkgPT4gdHlwZSA9PT0gcGFydFR5cGUpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG86IElGb3JtYXR0ZWRQYXJ0cyA9IHsgdmFsdWU6ICcnLCBsaXRlcmFsOiAnJywgY29tYmluZWQ6ICcnIH07XG5cbiAgICAgICAgICAgICAgICBpZiAocGFydFR5cGUgPT09ICdlcmEnICYmIGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgby52YWx1ZSA9IGZvcm1hdHRlZFBhcnRzW2luZGV4XS52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG87XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJ0VHlwZSA9PT0gJ2VyYScgJiYgaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG8udmFsdWUgPSBmb3JtYXR0ZWRQYXJ0c1tpbmRleF0udmFsdWU7XG4gICAgICAgICAgICAgICAgby5saXRlcmFsID0gZm9ybWF0dGVkUGFydHNbaW5kZXggKyAxXSA/IGZvcm1hdHRlZFBhcnRzW2luZGV4ICsgMV0udmFsdWUgOiAnJztcbiAgICAgICAgICAgICAgICBvLmNvbWJpbmVkID0gW28udmFsdWUsIG8ubGl0ZXJhbF0uam9pbignJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG87XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVhY2ggb2YgcGFydHMpIHtcbiAgICAgICAgICAgICAgICByZXN1bHRbZWFjaF0gPSB0b1R5cGUoZWFjaCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVhY2ggb2YgcGFydHMpIHtcbiAgICAgICAgICAgICAgICByZXN1bHRbZWFjaF0gPSB7IHZhbHVlOiAnJywgbGl0ZXJhbDogJycsIGNvbWJpbmVkOiAnJyB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZW5lcmF0ZUlDYWxlbmRhckRhdGUoZGF0ZTogRGF0ZSwgeWVhcjogbnVtYmVyLCBtb250aDogbnVtYmVyKTogSUNhbGVuZGFyRGF0ZSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBkYXRlLFxuICAgICAgICAgICAgaXNDdXJyZW50TW9udGg6IGRhdGUuZ2V0RnVsbFllYXIoKSA9PT0geWVhciAmJiBkYXRlLmdldE1vbnRoKCkgPT09IG1vbnRoLFxuICAgICAgICAgICAgaXNOZXh0TW9udGg6IHRoaXMuaXNOZXh0TW9udGgoZGF0ZSwgeWVhciwgbW9udGgpLFxuICAgICAgICAgICAgaXNQcmV2TW9udGg6IHRoaXMuaXNQcmV2aW91c01vbnRoKGRhdGUsIHllYXIsIG1vbnRoKVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNQcmV2aW91c01vbnRoKGRhdGU6IERhdGUsIHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoZGF0ZS5nZXRGdWxsWWVhcigpID09PSB5ZWFyKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0ZS5nZXRNb250aCgpIDwgbW9udGg7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRhdGUuZ2V0RnVsbFllYXIoKSA8IHllYXI7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc05leHRNb250aChkYXRlOiBEYXRlLCB5ZWFyOiBudW1iZXIsIG1vbnRoOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKGRhdGUuZ2V0RnVsbFllYXIoKSA9PT0geWVhcikge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGUuZ2V0TW9udGgoKSA+IG1vbnRoO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRhdGUuZ2V0RnVsbFllYXIoKSA+IHllYXI7XG4gICAgfVxufVxuIl19