@ng-bootstrap/ng-bootstrap
Version:
Angular powered Bootstrap
207 lines • 26 kB
JavaScript
import { NgbDate } from '../ngb-date';
/**
* Returns the equivalent JS date value for a give input Jalali date.
* `jalaliDate` is an Jalali date to be converted to Gregorian.
*/
export function toGregorian(jalaliDate) {
let jdn = jalaliToJulian(jalaliDate.year, jalaliDate.month, jalaliDate.day);
let date = julianToGregorian(jdn);
date.setHours(6, 30, 3, 200);
return date;
}
/**
* Returns the equivalent jalali date value for a give input Gregorian date.
* `gdate` is a JS Date to be converted to jalali.
* utc to local
*/
export function fromGregorian(gdate) {
let g2d = gregorianToJulian(gdate.getFullYear(), gdate.getMonth() + 1, gdate.getDate());
return julianToJalali(g2d);
}
export function setJalaliYear(date, yearValue) {
date.year = +yearValue;
return date;
}
export function setJalaliMonth(date, month) {
month = +month;
date.year = date.year + Math.floor((month - 1) / 12);
date.month = Math.floor((((month - 1) % 12) + 12) % 12) + 1;
return date;
}
export function setJalaliDay(date, day) {
let mDays = getDaysPerMonth(date.month, date.year);
if (day <= 0) {
while (day <= 0) {
date = setJalaliMonth(date, date.month - 1);
mDays = getDaysPerMonth(date.month, date.year);
day += mDays;
}
}
else if (day > mDays) {
while (day > mDays) {
day -= mDays;
date = setJalaliMonth(date, date.month + 1);
mDays = getDaysPerMonth(date.month, date.year);
}
}
date.day = day;
return date;
}
function mod(a, b) {
return a - b * Math.floor(a / b);
}
function div(a, b) {
return Math.trunc(a / b);
}
/*
This function determines if the Jalali (Persian) year is
leap (366-day long) or is the common year (365 days), and
finds the day in March (Gregorian calendar) of the first
day of the Jalali year (jalaliYear).
@param jalaliYear Jalali calendar year (-61 to 3177)
@return
leap: number of years since the last leap year (0 to 4)
gYear: Gregorian year of the beginning of Jalali year
march: the March day of Farvardin the 1st (1st day of jalaliYear)
@see: http://www.astro.uni.torun.pl/~kb/Papers/EMP/PersianC-EMP.htm
@see: http://www.fourmilab.ch/documents/calendar/
*/
function jalCal(jalaliYear) {
// Jalali years starting the 33-year rule.
let breaks = [
-61, 9, 38, 199, 426, 686, 756, 818, 1111, 1181, 1210, 1635, 2060, 2097, 2192, 2262, 2324, 2394, 2456, 3178,
];
const breaksLength = breaks.length;
const gYear = jalaliYear + 621;
let leapJ = -14;
let jp = breaks[0];
if (jalaliYear < jp || jalaliYear >= breaks[breaksLength - 1]) {
throw new Error('Invalid Jalali year ' + jalaliYear);
}
// Find the limiting years for the Jalali year jalaliYear.
let jump;
for (let i = 1; i < breaksLength; i += 1) {
const jm = breaks[i];
jump = jm - jp;
if (jalaliYear < jm) {
break;
}
leapJ = leapJ + div(jump, 33) * 8 + div(mod(jump, 33), 4);
jp = jm;
}
let n = jalaliYear - jp;
// Find the number of leap years from AD 621 to the beginning
// of the current Jalali year in the Persian calendar.
leapJ = leapJ + div(n, 33) * 8 + div(mod(n, 33) + 3, 4);
if (mod(jump, 33) === 4 && jump - n === 4) {
leapJ += 1;
}
// And the same in the Gregorian calendar (until the year gYear).
const leapG = div(gYear, 4) - div((div(gYear, 100) + 1) * 3, 4) - 150;
// Determine the Gregorian date of Farvardin the 1st.
const march = 20 + leapJ - leapG;
// Find how many years have passed since the last leap year.
if (jump - n < 6) {
n = n - jump + div(jump + 4, 33) * 33;
}
let leap = mod(mod(n + 1, 33) - 1, 4);
if (leap === -1) {
leap = 4;
}
return { leap: leap, gy: gYear, march: march };
}
/*
Calculates Gregorian and Julian calendar dates from the Julian Day number
(jdn) for the period since jdn=-34839655 (i.e. the year -100100 of both
calendars) to some millions years ahead of the present.
@param jdn Julian Day number
@return
gYear: Calendar year (years BC numbered 0, -1, -2, ...)
gMonth: Calendar month (1 to 12)
gDay: Calendar day of the month M (1 to 28/29/30/31)
*/
function julianToGregorian(julianDayNumber) {
let j = 4 * julianDayNumber + 139361631;
j = j + div(div(4 * julianDayNumber + 183187720, 146097) * 3, 4) * 4 - 3908;
const i = div(mod(j, 1461), 4) * 5 + 308;
const gDay = div(mod(i, 153), 5) + 1;
const gMonth = mod(div(i, 153), 12) + 1;
const gYear = div(j, 1461) - 100100 + div(8 - gMonth, 6);
return new Date(gYear, gMonth - 1, gDay);
}
/*
Converts a date of the Jalali calendar to the Julian Day number.
@param jy Jalali year (1 to 3100)
@param jm Jalali month (1 to 12)
@param jd Jalali day (1 to 29/31)
@return Julian Day number
*/
function gregorianToJulian(gy, gm, gd) {
let d = div((gy + div(gm - 8, 6) + 100100) * 1461, 4) + div(153 * mod(gm + 9, 12) + 2, 5) + gd - 34840408;
d = d - div(div(gy + 100100 + div(gm - 8, 6), 100) * 3, 4) + 752;
return d;
}
/*
Converts the Julian Day number to a date in the Jalali calendar.
@param julianDayNumber Julian Day number
@return
jalaliYear: Jalali year (1 to 3100)
jalaliMonth: Jalali month (1 to 12)
jalaliDay: Jalali day (1 to 29/31)
*/
function julianToJalali(julianDayNumber) {
let gy = julianToGregorian(julianDayNumber).getFullYear(), // Calculate Gregorian year (gy).
jalaliYear = gy - 621, r = jalCal(jalaliYear), gregorianDay = gregorianToJulian(gy, 3, r.march), jalaliDay, jalaliMonth, numberOfDays;
// Find number of days that passed since 1 Farvardin.
numberOfDays = julianDayNumber - gregorianDay;
if (numberOfDays >= 0) {
if (numberOfDays <= 185) {
// The first 6 months.
jalaliMonth = 1 + div(numberOfDays, 31);
jalaliDay = mod(numberOfDays, 31) + 1;
return new NgbDate(jalaliYear, jalaliMonth, jalaliDay);
}
else {
// The remaining months.
numberOfDays -= 186;
}
}
else {
// Previous Jalali year.
jalaliYear -= 1;
numberOfDays += 179;
if (r.leap === 1) {
numberOfDays += 1;
}
}
jalaliMonth = 7 + div(numberOfDays, 30);
jalaliDay = mod(numberOfDays, 30) + 1;
return new NgbDate(jalaliYear, jalaliMonth, jalaliDay);
}
/*
Converts a date of the Jalali calendar to the Julian Day number.
@param jYear Jalali year (1 to 3100)
@param jMonth Jalali month (1 to 12)
@param jDay Jalali day (1 to 29/31)
@return Julian Day number
*/
function jalaliToJulian(jYear, jMonth, jDay) {
let r = jalCal(jYear);
return gregorianToJulian(r.gy, 3, r.march) + (jMonth - 1) * 31 - div(jMonth, 7) * (jMonth - 7) + jDay - 1;
}
/**
* Returns the number of days in a specific jalali month.
*/
function getDaysPerMonth(month, year) {
if (month <= 6) {
return 31;
}
if (month <= 11) {
return 30;
}
if (jalCal(year).leap === 0) {
return 30;
}
return 29;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiamFsYWxpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2RhdGVwaWNrZXIvamFsYWxpL2phbGFsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRXRDOzs7R0FHRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUMsVUFBbUI7SUFDOUMsSUFBSSxHQUFHLEdBQUcsY0FBYyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUUsSUFBSSxJQUFJLEdBQUcsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDbEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUM3QixPQUFPLElBQUksQ0FBQztBQUNiLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxLQUFXO0lBQ3hDLElBQUksR0FBRyxHQUFHLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQ3hGLE9BQU8sY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLENBQUM7QUFFRCxNQUFNLFVBQVUsYUFBYSxDQUFDLElBQWEsRUFBRSxTQUFpQjtJQUM3RCxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsU0FBUyxDQUFDO0lBQ3ZCLE9BQU8sSUFBSSxDQUFDO0FBQ2IsQ0FBQztBQUVELE1BQU0sVUFBVSxjQUFjLENBQUMsSUFBYSxFQUFFLEtBQWE7SUFDMUQsS0FBSyxHQUFHLENBQUMsS0FBSyxDQUFDO0lBQ2YsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFDckQsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUQsT0FBTyxJQUFJLENBQUM7QUFDYixDQUFDO0FBRUQsTUFBTSxVQUFVLFlBQVksQ0FBQyxJQUFhLEVBQUUsR0FBVztJQUN0RCxJQUFJLEtBQUssR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkQsSUFBSSxHQUFHLElBQUksQ0FBQyxFQUFFO1FBQ2IsT0FBTyxHQUFHLElBQUksQ0FBQyxFQUFFO1lBQ2hCLElBQUksR0FBRyxjQUFjLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDNUMsS0FBSyxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMvQyxHQUFHLElBQUksS0FBSyxDQUFDO1NBQ2I7S0FDRDtTQUFNLElBQUksR0FBRyxHQUFHLEtBQUssRUFBRTtRQUN2QixPQUFPLEdBQUcsR0FBRyxLQUFLLEVBQUU7WUFDbkIsR0FBRyxJQUFJLEtBQUssQ0FBQztZQUNiLElBQUksR0FBRyxjQUFjLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDNUMsS0FBSyxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUMvQztLQUNEO0lBQ0QsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7SUFDZixPQUFPLElBQUksQ0FBQztBQUNiLENBQUM7QUFFRCxTQUFTLEdBQUcsQ0FBQyxDQUFTLEVBQUUsQ0FBUztJQUNoQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDbEMsQ0FBQztBQUVELFNBQVMsR0FBRyxDQUFDLENBQVMsRUFBRSxDQUFTO0lBQ2hDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDMUIsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILFNBQVMsTUFBTSxDQUFDLFVBQWtCO0lBQ2pDLDBDQUEwQztJQUMxQyxJQUFJLE1BQU0sR0FBRztRQUNaLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUk7S0FDM0csQ0FBQztJQUNGLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDbkMsTUFBTSxLQUFLLEdBQUcsVUFBVSxHQUFHLEdBQUcsQ0FBQztJQUMvQixJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQztJQUNoQixJQUFJLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFbkIsSUFBSSxVQUFVLEdBQUcsRUFBRSxJQUFJLFVBQVUsSUFBSSxNQUFNLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQyxFQUFFO1FBQzlELE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLEdBQUcsVUFBVSxDQUFDLENBQUM7S0FDckQ7SUFFRCwwREFBMEQ7SUFDMUQsSUFBSSxJQUFJLENBQUM7SUFDVCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsWUFBWSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDekMsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO1FBQ2YsSUFBSSxVQUFVLEdBQUcsRUFBRSxFQUFFO1lBQ3BCLE1BQU07U0FDTjtRQUNELEtBQUssR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUQsRUFBRSxHQUFHLEVBQUUsQ0FBQztLQUNSO0lBQ0QsSUFBSSxDQUFDLEdBQUcsVUFBVSxHQUFHLEVBQUUsQ0FBQztJQUV4Qiw2REFBNkQ7SUFDN0Qsc0RBQXNEO0lBQ3RELEtBQUssR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3hELElBQUksR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFDMUMsS0FBSyxJQUFJLENBQUMsQ0FBQztLQUNYO0lBRUQsaUVBQWlFO0lBQ2pFLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0lBRXRFLHFEQUFxRDtJQUNyRCxNQUFNLEtBQUssR0FBRyxFQUFFLEdBQUcsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUVqQyw0REFBNEQ7SUFDNUQsSUFBSSxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtRQUNqQixDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7S0FDdEM7SUFDRCxJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLElBQUksSUFBSSxLQUFLLENBQUMsQ0FBQyxFQUFFO1FBQ2hCLElBQUksR0FBRyxDQUFDLENBQUM7S0FDVDtJQUVELE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDO0FBQ2hELENBQUM7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCxTQUFTLGlCQUFpQixDQUFDLGVBQXVCO0lBQ2pELElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxlQUFlLEdBQUcsU0FBUyxDQUFDO0lBQ3hDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsZUFBZSxHQUFHLFNBQVMsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztJQUM1RSxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDO0lBQ3pDLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNyQyxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEMsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFekQsT0FBTyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsTUFBTSxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUMxQyxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBUyxpQkFBaUIsQ0FBQyxFQUFVLEVBQUUsRUFBVSxFQUFFLEVBQVU7SUFDNUQsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsUUFBUSxDQUFDO0lBQzFHLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsTUFBTSxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7SUFDakUsT0FBTyxDQUFDLENBQUM7QUFDVixDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILFNBQVMsY0FBYyxDQUFDLGVBQXVCO0lBQzlDLElBQUksRUFBRSxHQUFHLGlCQUFpQixDQUFDLGVBQWUsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLGlDQUFpQztJQUMzRixVQUFVLEdBQUcsRUFBRSxHQUFHLEdBQUcsRUFDckIsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFDdEIsWUFBWSxHQUFHLGlCQUFpQixDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUNoRCxTQUFTLEVBQ1QsV0FBVyxFQUNYLFlBQVksQ0FBQztJQUVkLHFEQUFxRDtJQUNyRCxZQUFZLEdBQUcsZUFBZSxHQUFHLFlBQVksQ0FBQztJQUM5QyxJQUFJLFlBQVksSUFBSSxDQUFDLEVBQUU7UUFDdEIsSUFBSSxZQUFZLElBQUksR0FBRyxFQUFFO1lBQ3hCLHNCQUFzQjtZQUN0QixXQUFXLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDeEMsU0FBUyxHQUFHLEdBQUcsQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3RDLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBVSxFQUFFLFdBQVcsRUFBRSxTQUFTLENBQUMsQ0FBQztTQUN2RDthQUFNO1lBQ04sd0JBQXdCO1lBQ3hCLFlBQVksSUFBSSxHQUFHLENBQUM7U0FDcEI7S0FDRDtTQUFNO1FBQ04sd0JBQXdCO1FBQ3hCLFVBQVUsSUFBSSxDQUFDLENBQUM7UUFDaEIsWUFBWSxJQUFJLEdBQUcsQ0FBQztRQUNwQixJQUFJLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxFQUFFO1lBQ2pCLFlBQVksSUFBSSxDQUFDLENBQUM7U0FDbEI7S0FDRDtJQUNELFdBQVcsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN4QyxTQUFTLEdBQUcsR0FBRyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFdEMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFVLEVBQUUsV0FBVyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ3hELENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFTLGNBQWMsQ0FBQyxLQUFhLEVBQUUsTUFBYyxFQUFFLElBQVk7SUFDbEUsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3RCLE9BQU8saUJBQWlCLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUM7QUFDM0csQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxlQUFlLENBQUMsS0FBYSxFQUFFLElBQVk7SUFDbkQsSUFBSSxLQUFLLElBQUksQ0FBQyxFQUFFO1FBQ2YsT0FBTyxFQUFFLENBQUM7S0FDVjtJQUNELElBQUksS0FBSyxJQUFJLEVBQUUsRUFBRTtRQUNoQixPQUFPLEVBQUUsQ0FBQztLQUNWO0lBQ0QsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBRTtRQUM1QixPQUFPLEVBQUUsQ0FBQztLQUNWO0lBQ0QsT0FBTyxFQUFFLENBQUM7QUFDWCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdiRGF0ZSB9IGZyb20gJy4uL25nYi1kYXRlJztcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBlcXVpdmFsZW50IEpTIGRhdGUgdmFsdWUgZm9yIGEgZ2l2ZSBpbnB1dCBKYWxhbGkgZGF0ZS5cbiAqIGBqYWxhbGlEYXRlYCBpcyBhbiBKYWxhbGkgZGF0ZSB0byBiZSBjb252ZXJ0ZWQgdG8gR3JlZ29yaWFuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9HcmVnb3JpYW4oamFsYWxpRGF0ZTogTmdiRGF0ZSk6IERhdGUge1xuXHRsZXQgamRuID0gamFsYWxpVG9KdWxpYW4oamFsYWxpRGF0ZS55ZWFyLCBqYWxhbGlEYXRlLm1vbnRoLCBqYWxhbGlEYXRlLmRheSk7XG5cdGxldCBkYXRlID0ganVsaWFuVG9HcmVnb3JpYW4oamRuKTtcblx0ZGF0ZS5zZXRIb3Vycyg2LCAzMCwgMywgMjAwKTtcblx0cmV0dXJuIGRhdGU7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZXF1aXZhbGVudCBqYWxhbGkgZGF0ZSB2YWx1ZSBmb3IgYSBnaXZlIGlucHV0IEdyZWdvcmlhbiBkYXRlLlxuICogYGdkYXRlYCBpcyBhIEpTIERhdGUgdG8gYmUgY29udmVydGVkIHRvIGphbGFsaS5cbiAqIHV0YyB0byBsb2NhbFxuICovXG5leHBvcnQgZnVuY3Rpb24gZnJvbUdyZWdvcmlhbihnZGF0ZTogRGF0ZSk6IE5nYkRhdGUge1xuXHRsZXQgZzJkID0gZ3JlZ29yaWFuVG9KdWxpYW4oZ2RhdGUuZ2V0RnVsbFllYXIoKSwgZ2RhdGUuZ2V0TW9udGgoKSArIDEsIGdkYXRlLmdldERhdGUoKSk7XG5cdHJldHVybiBqdWxpYW5Ub0phbGFsaShnMmQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0SmFsYWxpWWVhcihkYXRlOiBOZ2JEYXRlLCB5ZWFyVmFsdWU6IG51bWJlcik6IE5nYkRhdGUge1xuXHRkYXRlLnllYXIgPSAreWVhclZhbHVlO1xuXHRyZXR1cm4gZGF0ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldEphbGFsaU1vbnRoKGRhdGU6IE5nYkRhdGUsIG1vbnRoOiBudW1iZXIpOiBOZ2JEYXRlIHtcblx0bW9udGggPSArbW9udGg7XG5cdGRhdGUueWVhciA9IGRhdGUueWVhciArIE1hdGguZmxvb3IoKG1vbnRoIC0gMSkgLyAxMik7XG5cdGRhdGUubW9udGggPSBNYXRoLmZsb29yKCgoKG1vbnRoIC0gMSkgJSAxMikgKyAxMikgJSAxMikgKyAxO1xuXHRyZXR1cm4gZGF0ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldEphbGFsaURheShkYXRlOiBOZ2JEYXRlLCBkYXk6IG51bWJlcik6IE5nYkRhdGUge1xuXHRsZXQgbURheXMgPSBnZXREYXlzUGVyTW9udGgoZGF0ZS5tb250aCwgZGF0ZS55ZWFyKTtcblx0aWYgKGRheSA8PSAwKSB7XG5cdFx0d2hpbGUgKGRheSA8PSAwKSB7XG5cdFx0XHRkYXRlID0gc2V0SmFsYWxpTW9udGgoZGF0ZSwgZGF0ZS5tb250aCAtIDEpO1xuXHRcdFx0bURheXMgPSBnZXREYXlzUGVyTW9udGgoZGF0ZS5tb250aCwgZGF0ZS55ZWFyKTtcblx0XHRcdGRheSArPSBtRGF5cztcblx0XHR9XG5cdH0gZWxzZSBpZiAoZGF5ID4gbURheXMpIHtcblx0XHR3aGlsZSAoZGF5ID4gbURheXMpIHtcblx0XHRcdGRheSAtPSBtRGF5cztcblx0XHRcdGRhdGUgPSBzZXRKYWxhbGlNb250aChkYXRlLCBkYXRlLm1vbnRoICsgMSk7XG5cdFx0XHRtRGF5cyA9IGdldERheXNQZXJNb250aChkYXRlLm1vbnRoLCBkYXRlLnllYXIpO1xuXHRcdH1cblx0fVxuXHRkYXRlLmRheSA9IGRheTtcblx0cmV0dXJuIGRhdGU7XG59XG5cbmZ1bmN0aW9uIG1vZChhOiBudW1iZXIsIGI6IG51bWJlcik6IG51bWJlciB7XG5cdHJldHVybiBhIC0gYiAqIE1hdGguZmxvb3IoYSAvIGIpO1xufVxuXG5mdW5jdGlvbiBkaXYoYTogbnVtYmVyLCBiOiBudW1iZXIpIHtcblx0cmV0dXJuIE1hdGgudHJ1bmMoYSAvIGIpO1xufVxuXG4vKlxuIFRoaXMgZnVuY3Rpb24gZGV0ZXJtaW5lcyBpZiB0aGUgSmFsYWxpIChQZXJzaWFuKSB5ZWFyIGlzXG4gbGVhcCAoMzY2LWRheSBsb25nKSBvciBpcyB0aGUgY29tbW9uIHllYXIgKDM2NSBkYXlzKSwgYW5kXG4gZmluZHMgdGhlIGRheSBpbiBNYXJjaCAoR3JlZ29yaWFuIGNhbGVuZGFyKSBvZiB0aGUgZmlyc3RcbiBkYXkgb2YgdGhlIEphbGFsaSB5ZWFyIChqYWxhbGlZZWFyKS5cbiBAcGFyYW0gamFsYWxpWWVhciBKYWxhbGkgY2FsZW5kYXIgeWVhciAoLTYxIHRvIDMxNzcpXG4gQHJldHVyblxuIGxlYXA6IG51bWJlciBvZiB5ZWFycyBzaW5jZSB0aGUgbGFzdCBsZWFwIHllYXIgKDAgdG8gNClcbiBnWWVhcjogR3JlZ29yaWFuIHllYXIgb2YgdGhlIGJlZ2lubmluZyBvZiBKYWxhbGkgeWVhclxuIG1hcmNoOiB0aGUgTWFyY2ggZGF5IG9mIEZhcnZhcmRpbiB0aGUgMXN0ICgxc3QgZGF5IG9mIGphbGFsaVllYXIpXG4gQHNlZTogaHR0cDovL3d3dy5hc3Ryby51bmkudG9ydW4ucGwvfmtiL1BhcGVycy9FTVAvUGVyc2lhbkMtRU1QLmh0bVxuIEBzZWU6IGh0dHA6Ly93d3cuZm91cm1pbGFiLmNoL2RvY3VtZW50cy9jYWxlbmRhci9cbiAqL1xuZnVuY3Rpb24gamFsQ2FsKGphbGFsaVllYXI6IG51bWJlcikge1xuXHQvLyBKYWxhbGkgeWVhcnMgc3RhcnRpbmcgdGhlIDMzLXllYXIgcnVsZS5cblx0bGV0IGJyZWFrcyA9IFtcblx0XHQtNjEsIDksIDM4LCAxOTksIDQyNiwgNjg2LCA3NTYsIDgxOCwgMTExMSwgMTE4MSwgMTIxMCwgMTYzNSwgMjA2MCwgMjA5NywgMjE5MiwgMjI2MiwgMjMyNCwgMjM5NCwgMjQ1NiwgMzE3OCxcblx0XTtcblx0Y29uc3QgYnJlYWtzTGVuZ3RoID0gYnJlYWtzLmxlbmd0aDtcblx0Y29uc3QgZ1llYXIgPSBqYWxhbGlZZWFyICsgNjIxO1xuXHRsZXQgbGVhcEogPSAtMTQ7XG5cdGxldCBqcCA9IGJyZWFrc1swXTtcblxuXHRpZiAoamFsYWxpWWVhciA8IGpwIHx8IGphbGFsaVllYXIgPj0gYnJlYWtzW2JyZWFrc0xlbmd0aCAtIDFdKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIEphbGFsaSB5ZWFyICcgKyBqYWxhbGlZZWFyKTtcblx0fVxuXG5cdC8vIEZpbmQgdGhlIGxpbWl0aW5nIHllYXJzIGZvciB0aGUgSmFsYWxpIHllYXIgamFsYWxpWWVhci5cblx0bGV0IGp1bXA7XG5cdGZvciAobGV0IGkgPSAxOyBpIDwgYnJlYWtzTGVuZ3RoOyBpICs9IDEpIHtcblx0XHRjb25zdCBqbSA9IGJyZWFrc1tpXTtcblx0XHRqdW1wID0gam0gLSBqcDtcblx0XHRpZiAoamFsYWxpWWVhciA8IGptKSB7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cdFx0bGVhcEogPSBsZWFwSiArIGRpdihqdW1wLCAzMykgKiA4ICsgZGl2KG1vZChqdW1wLCAzMyksIDQpO1xuXHRcdGpwID0gam07XG5cdH1cblx0bGV0IG4gPSBqYWxhbGlZZWFyIC0ganA7XG5cblx0Ly8gRmluZCB0aGUgbnVtYmVyIG9mIGxlYXAgeWVhcnMgZnJvbSBBRCA2MjEgdG8gdGhlIGJlZ2lubmluZ1xuXHQvLyBvZiB0aGUgY3VycmVudCBKYWxhbGkgeWVhciBpbiB0aGUgUGVyc2lhbiBjYWxlbmRhci5cblx0bGVhcEogPSBsZWFwSiArIGRpdihuLCAzMykgKiA4ICsgZGl2KG1vZChuLCAzMykgKyAzLCA0KTtcblx0aWYgKG1vZChqdW1wLCAzMykgPT09IDQgJiYganVtcCAtIG4gPT09IDQpIHtcblx0XHRsZWFwSiArPSAxO1xuXHR9XG5cblx0Ly8gQW5kIHRoZSBzYW1lIGluIHRoZSBHcmVnb3JpYW4gY2FsZW5kYXIgKHVudGlsIHRoZSB5ZWFyIGdZZWFyKS5cblx0Y29uc3QgbGVhcEcgPSBkaXYoZ1llYXIsIDQpIC0gZGl2KChkaXYoZ1llYXIsIDEwMCkgKyAxKSAqIDMsIDQpIC0gMTUwO1xuXG5cdC8vIERldGVybWluZSB0aGUgR3JlZ29yaWFuIGRhdGUgb2YgRmFydmFyZGluIHRoZSAxc3QuXG5cdGNvbnN0IG1hcmNoID0gMjAgKyBsZWFwSiAtIGxlYXBHO1xuXG5cdC8vIEZpbmQgaG93IG1hbnkgeWVhcnMgaGF2ZSBwYXNzZWQgc2luY2UgdGhlIGxhc3QgbGVhcCB5ZWFyLlxuXHRpZiAoanVtcCAtIG4gPCA2KSB7XG5cdFx0biA9IG4gLSBqdW1wICsgZGl2KGp1bXAgKyA0LCAzMykgKiAzMztcblx0fVxuXHRsZXQgbGVhcCA9IG1vZChtb2QobiArIDEsIDMzKSAtIDEsIDQpO1xuXHRpZiAobGVhcCA9PT0gLTEpIHtcblx0XHRsZWFwID0gNDtcblx0fVxuXG5cdHJldHVybiB7IGxlYXA6IGxlYXAsIGd5OiBnWWVhciwgbWFyY2g6IG1hcmNoIH07XG59XG5cbi8qXG4gQ2FsY3VsYXRlcyBHcmVnb3JpYW4gYW5kIEp1bGlhbiBjYWxlbmRhciBkYXRlcyBmcm9tIHRoZSBKdWxpYW4gRGF5IG51bWJlclxuIChqZG4pIGZvciB0aGUgcGVyaW9kIHNpbmNlIGpkbj0tMzQ4Mzk2NTUgKGkuZS4gdGhlIHllYXIgLTEwMDEwMCBvZiBib3RoXG4gY2FsZW5kYXJzKSB0byBzb21lIG1pbGxpb25zIHllYXJzIGFoZWFkIG9mIHRoZSBwcmVzZW50LlxuIEBwYXJhbSBqZG4gSnVsaWFuIERheSBudW1iZXJcbiBAcmV0dXJuXG4gZ1llYXI6IENhbGVuZGFyIHllYXIgKHllYXJzIEJDIG51bWJlcmVkIDAsIC0xLCAtMiwgLi4uKVxuIGdNb250aDogQ2FsZW5kYXIgbW9udGggKDEgdG8gMTIpXG4gZ0RheTogQ2FsZW5kYXIgZGF5IG9mIHRoZSBtb250aCBNICgxIHRvIDI4LzI5LzMwLzMxKVxuICovXG5mdW5jdGlvbiBqdWxpYW5Ub0dyZWdvcmlhbihqdWxpYW5EYXlOdW1iZXI6IG51bWJlcikge1xuXHRsZXQgaiA9IDQgKiBqdWxpYW5EYXlOdW1iZXIgKyAxMzkzNjE2MzE7XG5cdGogPSBqICsgZGl2KGRpdig0ICoganVsaWFuRGF5TnVtYmVyICsgMTgzMTg3NzIwLCAxNDYwOTcpICogMywgNCkgKiA0IC0gMzkwODtcblx0Y29uc3QgaSA9IGRpdihtb2QoaiwgMTQ2MSksIDQpICogNSArIDMwODtcblx0Y29uc3QgZ0RheSA9IGRpdihtb2QoaSwgMTUzKSwgNSkgKyAxO1xuXHRjb25zdCBnTW9udGggPSBtb2QoZGl2KGksIDE1MyksIDEyKSArIDE7XG5cdGNvbnN0IGdZZWFyID0gZGl2KGosIDE0NjEpIC0gMTAwMTAwICsgZGl2KDggLSBnTW9udGgsIDYpO1xuXG5cdHJldHVybiBuZXcgRGF0ZShnWWVhciwgZ01vbnRoIC0gMSwgZ0RheSk7XG59XG5cbi8qXG4gQ29udmVydHMgYSBkYXRlIG9mIHRoZSBKYWxhbGkgY2FsZW5kYXIgdG8gdGhlIEp1bGlhbiBEYXkgbnVtYmVyLlxuIEBwYXJhbSBqeSBKYWxhbGkgeWVhciAoMSB0byAzMTAwKVxuIEBwYXJhbSBqbSBKYWxhbGkgbW9udGggKDEgdG8gMTIpXG4gQHBhcmFtIGpkIEphbGFsaSBkYXkgKDEgdG8gMjkvMzEpXG4gQHJldHVybiBKdWxpYW4gRGF5IG51bWJlclxuICovXG5mdW5jdGlvbiBncmVnb3JpYW5Ub0p1bGlhbihneTogbnVtYmVyLCBnbTogbnVtYmVyLCBnZDogbnVtYmVyKSB7XG5cdGxldCBkID0gZGl2KChneSArIGRpdihnbSAtIDgsIDYpICsgMTAwMTAwKSAqIDE0NjEsIDQpICsgZGl2KDE1MyAqIG1vZChnbSArIDksIDEyKSArIDIsIDUpICsgZ2QgLSAzNDg0MDQwODtcblx0ZCA9IGQgLSBkaXYoZGl2KGd5ICsgMTAwMTAwICsgZGl2KGdtIC0gOCwgNiksIDEwMCkgKiAzLCA0KSArIDc1Mjtcblx0cmV0dXJuIGQ7XG59XG5cbi8qXG4gQ29udmVydHMgdGhlIEp1bGlhbiBEYXkgbnVtYmVyIHRvIGEgZGF0ZSBpbiB0aGUgSmFsYWxpIGNhbGVuZGFyLlxuIEBwYXJhbSBqdWxpYW5EYXlOdW1iZXIgSnVsaWFuIERheSBudW1iZXJcbiBAcmV0dXJuXG4gamFsYWxpWWVhcjogSmFsYWxpIHllYXIgKDEgdG8gMzEwMClcbiBqYWxhbGlNb250aDogSmFsYWxpIG1vbnRoICgxIHRvIDEyKVxuIGphbGFsaURheTogSmFsYWxpIGRheSAoMSB0byAyOS8zMSlcbiAqL1xuZnVuY3Rpb24ganVsaWFuVG9KYWxhbGkoanVsaWFuRGF5TnVtYmVyOiBudW1iZXIpIHtcblx0bGV0IGd5ID0ganVsaWFuVG9HcmVnb3JpYW4oanVsaWFuRGF5TnVtYmVyKS5nZXRGdWxsWWVhcigpLCAvLyBDYWxjdWxhdGUgR3JlZ29yaWFuIHllYXIgKGd5KS5cblx0XHRqYWxhbGlZZWFyID0gZ3kgLSA2MjEsXG5cdFx0ciA9IGphbENhbChqYWxhbGlZZWFyKSxcblx0XHRncmVnb3JpYW5EYXkgPSBncmVnb3JpYW5Ub0p1bGlhbihneSwgMywgci5tYXJjaCksXG5cdFx0amFsYWxpRGF5LFxuXHRcdGphbGFsaU1vbnRoLFxuXHRcdG51bWJlck9mRGF5cztcblxuXHQvLyBGaW5kIG51bWJlciBvZiBkYXlzIHRoYXQgcGFzc2VkIHNpbmNlIDEgRmFydmFyZGluLlxuXHRudW1iZXJPZkRheXMgPSBqdWxpYW5EYXlOdW1iZXIgLSBncmVnb3JpYW5EYXk7XG5cdGlmIChudW1iZXJPZkRheXMgPj0gMCkge1xuXHRcdGlmIChudW1iZXJPZkRheXMgPD0gMTg1KSB7XG5cdFx0XHQvLyBUaGUgZmlyc3QgNiBtb250aHMuXG5cdFx0XHRqYWxhbGlNb250aCA9IDEgKyBkaXYobnVtYmVyT2ZEYXlzLCAzMSk7XG5cdFx0XHRqYWxhbGlEYXkgPSBtb2QobnVtYmVyT2ZEYXlzLCAzMSkgKyAxO1xuXHRcdFx0cmV0dXJuIG5ldyBOZ2JEYXRlKGphbGFsaVllYXIsIGphbGFsaU1vbnRoLCBqYWxhbGlEYXkpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBUaGUgcmVtYWluaW5nIG1vbnRocy5cblx0XHRcdG51bWJlck9mRGF5cyAtPSAxODY7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdC8vIFByZXZpb3VzIEphbGFsaSB5ZWFyLlxuXHRcdGphbGFsaVllYXIgLT0gMTtcblx0XHRudW1iZXJPZkRheXMgKz0gMTc5O1xuXHRcdGlmIChyLmxlYXAgPT09IDEpIHtcblx0XHRcdG51bWJlck9mRGF5cyArPSAxO1xuXHRcdH1cblx0fVxuXHRqYWxhbGlNb250aCA9IDcgKyBkaXYobnVtYmVyT2ZEYXlzLCAzMCk7XG5cdGphbGFsaURheSA9IG1vZChudW1iZXJPZkRheXMsIDMwKSArIDE7XG5cblx0cmV0dXJuIG5ldyBOZ2JEYXRlKGphbGFsaVllYXIsIGphbGFsaU1vbnRoLCBqYWxhbGlEYXkpO1xufVxuXG4vKlxuIENvbnZlcnRzIGEgZGF0ZSBvZiB0aGUgSmFsYWxpIGNhbGVuZGFyIHRvIHRoZSBKdWxpYW4gRGF5IG51bWJlci5cbiBAcGFyYW0galllYXIgSmFsYWxpIHllYXIgKDEgdG8gMzEwMClcbiBAcGFyYW0gak1vbnRoIEphbGFsaSBtb250aCAoMSB0byAxMilcbiBAcGFyYW0gakRheSBKYWxhbGkgZGF5ICgxIHRvIDI5LzMxKVxuIEByZXR1cm4gSnVsaWFuIERheSBudW1iZXJcbiAqL1xuZnVuY3Rpb24gamFsYWxpVG9KdWxpYW4oalllYXI6IG51bWJlciwgak1vbnRoOiBudW1iZXIsIGpEYXk6IG51bWJlcikge1xuXHRsZXQgciA9IGphbENhbChqWWVhcik7XG5cdHJldHVybiBncmVnb3JpYW5Ub0p1bGlhbihyLmd5LCAzLCByLm1hcmNoKSArIChqTW9udGggLSAxKSAqIDMxIC0gZGl2KGpNb250aCwgNykgKiAoak1vbnRoIC0gNykgKyBqRGF5IC0gMTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZGF5cyBpbiBhIHNwZWNpZmljIGphbGFsaSBtb250aC5cbiAqL1xuZnVuY3Rpb24gZ2V0RGF5c1Blck1vbnRoKG1vbnRoOiBudW1iZXIsIHllYXI6IG51bWJlcik6IG51bWJlciB7XG5cdGlmIChtb250aCA8PSA2KSB7XG5cdFx0cmV0dXJuIDMxO1xuXHR9XG5cdGlmIChtb250aCA8PSAxMSkge1xuXHRcdHJldHVybiAzMDtcblx0fVxuXHRpZiAoamFsQ2FsKHllYXIpLmxlYXAgPT09IDApIHtcblx0XHRyZXR1cm4gMzA7XG5cdH1cblx0cmV0dXJuIDI5O1xufVxuIl19