ngb-calendar-islamic-civil.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import * as tslib_1 from "tslib";
  6. import { NgbCalendarHijri } from './ngb-calendar-hijri';
  7. import { NgbDate } from '../ngb-date';
  8. import { Injectable } from '@angular/core';
  9. /**
  10. * Checks if islamic year is a leap year
  11. * @param {?} hYear
  12. * @return {?}
  13. */
  14. function isIslamicLeapYear(hYear) {
  15. return (14 + 11 * hYear) % 30 < 11;
  16. }
  17. /**
  18. * Checks if gregorian years is a leap year
  19. * @param {?} gDate
  20. * @return {?}
  21. */
  22. function isGregorianLeapYear(gDate) {
  23. /** @type {?} */
  24. var year = gDate.getFullYear();
  25. return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
  26. }
  27. /**
  28. * Returns the start of Hijri Month.
  29. * `hMonth` is 0 for Muharram, 1 for Safar, etc.
  30. * `hYear` is any Hijri hYear.
  31. * @param {?} hYear
  32. * @param {?} hMonth
  33. * @return {?}
  34. */
  35. function getIslamicMonthStart(hYear, hMonth) {
  36. return Math.ceil(29.5 * hMonth) + (hYear - 1) * 354 + Math.floor((3 + 11 * hYear) / 30.0);
  37. }
  38. /**
  39. * Returns the start of Hijri year.
  40. * `year` is any Hijri year.
  41. * @param {?} year
  42. * @return {?}
  43. */
  44. function getIslamicYearStart(year) {
  45. return (year - 1) * 354 + Math.floor((3 + 11 * year) / 30.0);
  46. }
  47. /**
  48. * @param {?} a
  49. * @param {?} b
  50. * @return {?}
  51. */
  52. function mod(a, b) {
  53. return a - b * Math.floor(a / b);
  54. }
  55. /**
  56. * The civil calendar is one type of Hijri calendars used in islamic countries.
  57. * Uses a fixed cycle of alternating 29- and 30-day months,
  58. * with a leap day added to the last month of 11 out of every 30 years.
  59. * http://cldr.unicode.org/development/development-process/design-proposals/islamic-calendar-types
  60. * All the calculations here are based on the equations from "Calendrical Calculations" By Edward M. Reingold, Nachum
  61. * Dershowitz.
  62. * @type {?}
  63. */
  64. var GREGORIAN_EPOCH = 1721425.5;
  65. /** @type {?} */
  66. var ISLAMIC_EPOCH = 1948439.5;
  67. var NgbCalendarIslamicCivil = /** @class */ (function (_super) {
  68. tslib_1.__extends(NgbCalendarIslamicCivil, _super);
  69. function NgbCalendarIslamicCivil() {
  70. return _super !== null && _super.apply(this, arguments) || this;
  71. }
  72. /**
  73. * Returns the equivalent islamic(civil) date value for a give input Gregorian date.
  74. * `gDate` is a JS Date to be converted to Hijri.
  75. */
  76. /**
  77. * Returns the equivalent islamic(civil) date value for a give input Gregorian date.
  78. * `gDate` is a JS Date to be converted to Hijri.
  79. * @param {?} gDate
  80. * @return {?}
  81. */
  82. NgbCalendarIslamicCivil.prototype.fromGregorian = /**
  83. * Returns the equivalent islamic(civil) date value for a give input Gregorian date.
  84. * `gDate` is a JS Date to be converted to Hijri.
  85. * @param {?} gDate
  86. * @return {?}
  87. */
  88. function (gDate) {
  89. /** @type {?} */
  90. var gYear = gDate.getFullYear();
  91. /** @type {?} */
  92. var gMonth = gDate.getMonth();
  93. /** @type {?} */
  94. var gDay = gDate.getDate();
  95. /** @type {?} */
  96. var julianDay = GREGORIAN_EPOCH - 1 + 365 * (gYear - 1) + Math.floor((gYear - 1) / 4) +
  97. -Math.floor((gYear - 1) / 100) + Math.floor((gYear - 1) / 400) +
  98. Math.floor((367 * (gMonth + 1) - 362) / 12 + (gMonth + 1 <= 2 ? 0 : isGregorianLeapYear(gDate) ? -1 : -2) + gDay);
  99. julianDay = Math.floor(julianDay) + 0.5;
  100. /** @type {?} */
  101. var days = julianDay - ISLAMIC_EPOCH;
  102. /** @type {?} */
  103. var hYear = Math.floor((30 * days + 10646) / 10631.0);
  104. /** @type {?} */
  105. var hMonth = Math.ceil((days - 29 - getIslamicYearStart(hYear)) / 29.5);
  106. hMonth = Math.min(hMonth, 11);
  107. /** @type {?} */
  108. var hDay = Math.ceil(days - getIslamicMonthStart(hYear, hMonth)) + 1;
  109. return new NgbDate(hYear, hMonth + 1, hDay);
  110. };
  111. /**
  112. * Returns the equivalent JS date value for a give input islamic(civil) date.
  113. * `hDate` is an islamic(civil) date to be converted to Gregorian.
  114. */
  115. /**
  116. * Returns the equivalent JS date value for a give input islamic(civil) date.
  117. * `hDate` is an islamic(civil) date to be converted to Gregorian.
  118. * @param {?} hDate
  119. * @return {?}
  120. */
  121. NgbCalendarIslamicCivil.prototype.toGregorian = /**
  122. * Returns the equivalent JS date value for a give input islamic(civil) date.
  123. * `hDate` is an islamic(civil) date to be converted to Gregorian.
  124. * @param {?} hDate
  125. * @return {?}
  126. */
  127. function (hDate) {
  128. /** @type {?} */
  129. var hYear = hDate.year;
  130. /** @type {?} */
  131. var hMonth = hDate.month - 1;
  132. /** @type {?} */
  133. var hDay = hDate.day;
  134. /** @type {?} */
  135. var julianDay = hDay + Math.ceil(29.5 * hMonth) + (hYear - 1) * 354 + Math.floor((3 + 11 * hYear) / 30) + ISLAMIC_EPOCH - 1;
  136. /** @type {?} */
  137. var wjd = Math.floor(julianDay - 0.5) + 0.5;
  138. /** @type {?} */
  139. var depoch = wjd - GREGORIAN_EPOCH;
  140. /** @type {?} */
  141. var quadricent = Math.floor(depoch / 146097);
  142. /** @type {?} */
  143. var dqc = mod(depoch, 146097);
  144. /** @type {?} */
  145. var cent = Math.floor(dqc / 36524);
  146. /** @type {?} */
  147. var dcent = mod(dqc, 36524);
  148. /** @type {?} */
  149. var quad = Math.floor(dcent / 1461);
  150. /** @type {?} */
  151. var dquad = mod(dcent, 1461);
  152. /** @type {?} */
  153. var yindex = Math.floor(dquad / 365);
  154. /** @type {?} */
  155. var year = quadricent * 400 + cent * 100 + quad * 4 + yindex;
  156. if (!(cent === 4 || yindex === 4)) {
  157. year++;
  158. }
  159. /** @type {?} */
  160. var gYearStart = GREGORIAN_EPOCH + 365 * (year - 1) + Math.floor((year - 1) / 4) - Math.floor((year - 1) / 100) +
  161. Math.floor((year - 1) / 400);
  162. /** @type {?} */
  163. var yearday = wjd - gYearStart;
  164. /** @type {?} */
  165. var tjd = GREGORIAN_EPOCH - 1 + 365 * (year - 1) + Math.floor((year - 1) / 4) - Math.floor((year - 1) / 100) +
  166. Math.floor((year - 1) / 400) + Math.floor(739 / 12 + (isGregorianLeapYear(new Date(year, 3, 1)) ? -1 : -2) + 1);
  167. /** @type {?} */
  168. var leapadj = wjd < tjd ? 0 : isGregorianLeapYear(new Date(year, 3, 1)) ? 1 : 2;
  169. /** @type {?} */
  170. var month = Math.floor(((yearday + leapadj) * 12 + 373) / 367);
  171. /** @type {?} */
  172. var tjd2 = GREGORIAN_EPOCH - 1 + 365 * (year - 1) + Math.floor((year - 1) / 4) - Math.floor((year - 1) / 100) +
  173. Math.floor((year - 1) / 400) +
  174. Math.floor((367 * month - 362) / 12 + (month <= 2 ? 0 : isGregorianLeapYear(new Date(year, month - 1, 1)) ? -1 : -2) +
  175. 1);
  176. /** @type {?} */
  177. var day = wjd - tjd2 + 1;
  178. return new Date(year, month - 1, day);
  179. };
  180. /**
  181. * Returns the number of days in a specific Hijri month.
  182. * `month` is 1 for Muharram, 2 for Safar, etc.
  183. * `year` is any Hijri year.
  184. */
  185. /**
  186. * Returns the number of days in a specific Hijri month.
  187. * `month` is 1 for Muharram, 2 for Safar, etc.
  188. * `year` is any Hijri year.
  189. * @param {?} month
  190. * @param {?} year
  191. * @return {?}
  192. */
  193. NgbCalendarIslamicCivil.prototype.getDaysPerMonth = /**
  194. * Returns the number of days in a specific Hijri month.
  195. * `month` is 1 for Muharram, 2 for Safar, etc.
  196. * `year` is any Hijri year.
  197. * @param {?} month
  198. * @param {?} year
  199. * @return {?}
  200. */
  201. function (month, year) {
  202. year = year + Math.floor(month / 13);
  203. month = ((month - 1) % 12) + 1;
  204. /** @type {?} */
  205. var length = 29 + month % 2;
  206. if (month === 12 && isIslamicLeapYear(year)) {
  207. length++;
  208. }
  209. return length;
  210. };
  211. NgbCalendarIslamicCivil.decorators = [
  212. { type: Injectable }
  213. ];
  214. return NgbCalendarIslamicCivil;
  215. }(NgbCalendarHijri));
  216. export { NgbCalendarIslamicCivil };
  217. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdiLWNhbGVuZGFyLWlzbGFtaWMtY2l2aWwuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcC8iLCJzb3VyY2VzIjpbImRhdGVwaWNrZXIvaGlqcmkvbmdiLWNhbGVuZGFyLWlzbGFtaWMtY2l2aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUN0RCxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sYUFBYSxDQUFDO0FBQ3BDLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxlQUFlLENBQUM7Ozs7OztBQUt6QyxTQUFTLGlCQUFpQixDQUFDLEtBQWE7SUFDdEMsT0FBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNyQyxDQUFDOzs7Ozs7QUFLRCxTQUFTLG1CQUFtQixDQUFDLEtBQVc7O1FBQ2hDLElBQUksR0FBRyxLQUFLLENBQUMsV0FBVyxFQUFFO0lBQ2hDLE9BQU8sSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxHQUFHLEdBQUcsS0FBSyxDQUFDLElBQUksSUFBSSxHQUFHLEdBQUcsS0FBSyxDQUFDLENBQUM7QUFDaEUsQ0FBQzs7Ozs7Ozs7O0FBT0QsU0FBUyxvQkFBb0IsQ0FBQyxLQUFhLEVBQUUsTUFBYztJQUN6RCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztBQUM1RixDQUFDOzs7Ozs7O0FBTUQsU0FBUyxtQkFBbUIsQ0FBQyxJQUFZO0lBQ3ZDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQy9ELENBQUM7Ozs7OztBQUVELFNBQVMsR0FBRyxDQUFDLENBQVMsRUFBRSxDQUFTO0lBQy9CLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNuQyxDQUFDOzs7Ozs7Ozs7O0lBV0ssZUFBZSxHQUFHLFNBQVM7O0lBQzNCLGFBQWEsR0FBRyxTQUFTO0FBRS9CO0lBQzZDLG1EQUFnQjtJQUQ3RDs7SUErRUEsQ0FBQztJQTdFQzs7O09BR0c7Ozs7Ozs7SUFDSCwrQ0FBYTs7Ozs7O0lBQWIsVUFBYyxLQUFXOztZQUNqQixLQUFLLEdBQUcsS0FBSyxDQUFDLFdBQVcsRUFBRTs7WUFBRSxNQUFNLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBRTs7WUFBRSxJQUFJLEdBQUcsS0FBSyxDQUFDLE9BQU8sRUFBRTs7WUFFaEYsU0FBUyxHQUFHLGVBQWUsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2pGLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztZQUM5RCxJQUFJLENBQUMsS0FBSyxDQUNOLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7UUFDOUcsU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEdBQUcsR0FBRyxDQUFDOztZQUVsQyxJQUFJLEdBQUcsU0FBUyxHQUFHLGFBQWE7O1lBQ2hDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxHQUFHLElBQUksR0FBRyxLQUFLLENBQUMsR0FBRyxPQUFPLENBQUM7O1lBQ25ELE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxHQUFHLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQztRQUN2RSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7O1lBQ3hCLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxvQkFBb0IsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ3RFLE9BQU8sSUFBSSxPQUFPLENBQUMsS0FBSyxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVEOzs7T0FHRzs7Ozs7OztJQUNILDZDQUFXOzs7Ozs7SUFBWCxVQUFZLEtBQWM7O1lBQ2xCLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSTs7WUFDbEIsTUFBTSxHQUFHLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQzs7WUFDeEIsSUFBSSxHQUFHLEtBQUssQ0FBQyxHQUFHOztZQUNoQixTQUFTLEdBQ1gsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxhQUFhLEdBQUcsQ0FBQzs7WUFFekcsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUc7O1lBQUUsTUFBTSxHQUFHLEdBQUcsR0FBRyxlQUFlOztZQUN2RSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDOztZQUFFLEdBQUcsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQzs7WUFBRSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDOztZQUNuRyxLQUFLLEdBQUcsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUM7O1lBQUUsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQzs7WUFBRSxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUM7O1lBQ2xGLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUM7O1lBQ2xDLElBQUksR0FBRyxVQUFVLEdBQUcsR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxNQUFNO1FBQzVELElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLElBQUksTUFBTSxLQUFLLENBQUMsQ0FBQyxFQUFFO1lBQ2pDLElBQUksRUFBRSxDQUFDO1NBQ1I7O1lBRUssVUFBVSxHQUFHLGVBQWUsR0FBRyxHQUFHLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztZQUM3RyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQzs7WUFFMUIsT0FBTyxHQUFHLEdBQUcsR0FBRyxVQUFVOztZQUUxQixHQUFHLEdBQUcsZUFBZSxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztZQUMxRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLEVBQUUsR0FBRyxDQUFDLG1CQUFtQixDQUFDLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDOztZQUU3RyxPQUFPLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzs7WUFFM0UsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDOztZQUMxRCxJQUFJLEdBQUcsZUFBZSxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztZQUMzRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztZQUM1QixJQUFJLENBQUMsS0FBSyxDQUNOLENBQUMsR0FBRyxHQUFHLEtBQUssR0FBRyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDekcsQ0FBQyxDQUFDOztZQUVKLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7UUFFMUIsT0FBTyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQ7Ozs7T0FJRzs7Ozs7Ozs7O0lBQ0gsaURBQWU7Ozs7Ozs7O0lBQWYsVUFBZ0IsS0FBYSxFQUFFLElBQVk7UUFDekMsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQztRQUNyQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7O1lBQzNCLE1BQU0sR0FBRyxFQUFFLEdBQUcsS0FBSyxHQUFHLENBQUM7UUFDM0IsSUFBSSxLQUFLLEtBQUssRUFBRSxJQUFJLGlCQUFpQixDQUFDLElBQUksQ0FBQyxFQUFFO1lBQzNDLE1BQU0sRUFBRSxDQUFDO1NBQ1Y7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDOztnQkE5RUYsVUFBVTs7SUErRVgsOEJBQUM7Q0FBQSxBQS9FRCxDQUM2QyxnQkFBZ0IsR0E4RTVEO1NBOUVZLHVCQUF1QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7TmdiQ2FsZW5kYXJIaWpyaX0gZnJvbSAnLi9uZ2ItY2FsZW5kYXItaGlqcmknO1xuaW1wb3J0IHtOZ2JEYXRlfSBmcm9tICcuLi9uZ2ItZGF0ZSc7XG5pbXBvcnQge0luamVjdGFibGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG4vKipcbiAqIENoZWNrcyBpZiBpc2xhbWljIHllYXIgaXMgYSBsZWFwIHllYXJcbiAqL1xuZnVuY3Rpb24gaXNJc2xhbWljTGVhcFllYXIoaFllYXI6IG51bWJlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gKDE0ICsgMTEgKiBoWWVhcikgJSAzMCA8IDExO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBncmVnb3JpYW4geWVhcnMgaXMgYSBsZWFwIHllYXJcbiAqL1xuZnVuY3Rpb24gaXNHcmVnb3JpYW5MZWFwWWVhcihnRGF0ZTogRGF0ZSk6IGJvb2xlYW4ge1xuICBjb25zdCB5ZWFyID0gZ0RhdGUuZ2V0RnVsbFllYXIoKTtcbiAgcmV0dXJuIHllYXIgJSA0ID09PSAwICYmIHllYXIgJSAxMDAgIT09IDAgfHwgeWVhciAlIDQwMCA9PT0gMDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzdGFydCBvZiBIaWpyaSBNb250aC5cbiAqIGBoTW9udGhgIGlzIDAgZm9yIE11aGFycmFtLCAxIGZvciBTYWZhciwgZXRjLlxuICogYGhZZWFyYCBpcyBhbnkgSGlqcmkgaFllYXIuXG4gKi9cbmZ1bmN0aW9uIGdldElzbGFtaWNNb250aFN0YXJ0KGhZZWFyOiBudW1iZXIsIGhNb250aDogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGguY2VpbCgyOS41ICogaE1vbnRoKSArIChoWWVhciAtIDEpICogMzU0ICsgTWF0aC5mbG9vcigoMyArIDExICogaFllYXIpIC8gMzAuMCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3RhcnQgb2YgSGlqcmkgeWVhci5cbiAqIGB5ZWFyYCBpcyBhbnkgSGlqcmkgeWVhci5cbiAqL1xuZnVuY3Rpb24gZ2V0SXNsYW1pY1llYXJTdGFydCh5ZWFyOiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gKHllYXIgLSAxKSAqIDM1NCArIE1hdGguZmxvb3IoKDMgKyAxMSAqIHllYXIpIC8gMzAuMCk7XG59XG5cbmZ1bmN0aW9uIG1vZChhOiBudW1iZXIsIGI6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiBhIC0gYiAqIE1hdGguZmxvb3IoYSAvIGIpO1xufVxuXG4vKipcbiAqIFRoZSBjaXZpbCBjYWxlbmRhciBpcyBvbmUgdHlwZSBvZiBIaWpyaSBjYWxlbmRhcnMgdXNlZCBpbiBpc2xhbWljIGNvdW50cmllcy5cbiAqIFVzZXMgYSBmaXhlZCBjeWNsZSBvZiBhbHRlcm5hdGluZyAyOS0gYW5kIDMwLWRheSBtb250aHMsXG4gKiB3aXRoIGEgbGVhcCBkYXkgYWRkZWQgdG8gdGhlIGxhc3QgbW9udGggb2YgMTEgb3V0IG9mIGV2ZXJ5IDMwIHllYXJzLlxuICogaHR0cDovL2NsZHIudW5pY29kZS5vcmcvZGV2ZWxvcG1lbnQvZGV2ZWxvcG1lbnQtcHJvY2Vzcy9kZXNpZ24tcHJvcG9zYWxzL2lzbGFtaWMtY2FsZW5kYXItdHlwZXNcbiAqIEFsbCB0aGUgY2FsY3VsYXRpb25zIGhlcmUgYXJlIGJhc2VkIG9uIHRoZSBlcXVhdGlvbnMgZnJvbSBcIkNhbGVuZHJpY2FsIENhbGN1bGF0aW9uc1wiIEJ5IEVkd2FyZCBNLiBSZWluZ29sZCwgTmFjaHVtXG4gKiBEZXJzaG93aXR6LlxuICovXG5cbmNvbnN0IEdSRUdPUklBTl9FUE9DSCA9IDE3MjE0MjUuNTtcbmNvbnN0IElTTEFNSUNfRVBPQ0ggPSAxOTQ4NDM5LjU7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBOZ2JDYWxlbmRhcklzbGFtaWNDaXZpbCBleHRlbmRzIE5nYkNhbGVuZGFySGlqcmkge1xuICAvKipcbiAgICogUmV0dXJucyB0aGUgZXF1aXZhbGVudCBpc2xhbWljKGNpdmlsKSBkYXRlIHZhbHVlIGZvciBhIGdpdmUgaW5wdXQgR3JlZ29yaWFuIGRhdGUuXG4gICAqIGBnRGF0ZWAgaXMgYSBKUyBEYXRlIHRvIGJlIGNvbnZlcnRlZCB0byBIaWpyaS5cbiAgICovXG4gIGZyb21HcmVnb3JpYW4oZ0RhdGU6IERhdGUpOiBOZ2JEYXRlIHtcbiAgICBjb25zdCBnWWVhciA9IGdEYXRlLmdldEZ1bGxZZWFyKCksIGdNb250aCA9IGdEYXRlLmdldE1vbnRoKCksIGdEYXkgPSBnRGF0ZS5nZXREYXRlKCk7XG5cbiAgICBsZXQganVsaWFuRGF5ID0gR1JFR09SSUFOX0VQT0NIIC0gMSArIDM2NSAqIChnWWVhciAtIDEpICsgTWF0aC5mbG9vcigoZ1llYXIgLSAxKSAvIDQpICtcbiAgICAgICAgLU1hdGguZmxvb3IoKGdZZWFyIC0gMSkgLyAxMDApICsgTWF0aC5mbG9vcigoZ1llYXIgLSAxKSAvIDQwMCkgK1xuICAgICAgICBNYXRoLmZsb29yKFxuICAgICAgICAgICAgKDM2NyAqIChnTW9udGggKyAxKSAtIDM2MikgLyAxMiArIChnTW9udGggKyAxIDw9IDIgPyAwIDogaXNHcmVnb3JpYW5MZWFwWWVhcihnRGF0ZSkgPyAtMSA6IC0yKSArIGdEYXkpO1xuICAgIGp1bGlhbkRheSA9IE1hdGguZmxvb3IoanVsaWFuRGF5KSArIDAuNTtcblxuICAgIGNvbnN0IGRheXMgPSBqdWxpYW5EYXkgLSBJU0xBTUlDX0VQT0NIO1xuICAgIGNvbnN0IGhZZWFyID0gTWF0aC5mbG9vcigoMzAgKiBkYXlzICsgMTA2NDYpIC8gMTA2MzEuMCk7XG4gICAgbGV0IGhNb250aCA9IE1hdGguY2VpbCgoZGF5cyAtIDI5IC0gZ2V0SXNsYW1pY1llYXJTdGFydChoWWVhcikpIC8gMjkuNSk7XG4gICAgaE1vbnRoID0gTWF0aC5taW4oaE1vbnRoLCAxMSk7XG4gICAgY29uc3QgaERheSA9IE1hdGguY2VpbChkYXlzIC0gZ2V0SXNsYW1pY01vbnRoU3RhcnQoaFllYXIsIGhNb250aCkpICsgMTtcbiAgICByZXR1cm4gbmV3IE5nYkRhdGUoaFllYXIsIGhNb250aCArIDEsIGhEYXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGVxdWl2YWxlbnQgSlMgZGF0ZSB2YWx1ZSBmb3IgYSBnaXZlIGlucHV0IGlzbGFtaWMoY2l2aWwpIGRhdGUuXG4gICAqIGBoRGF0ZWAgaXMgYW4gaXNsYW1pYyhjaXZpbCkgZGF0ZSB0byBiZSBjb252ZXJ0ZWQgdG8gR3JlZ29yaWFuLlxuICAgKi9cbiAgdG9HcmVnb3JpYW4oaERhdGU6IE5nYkRhdGUpOiBEYXRlIHtcbiAgICBjb25zdCBoWWVhciA9IGhEYXRlLnllYXI7XG4gICAgY29uc3QgaE1vbnRoID0gaERhdGUubW9udGggLSAxO1xuICAgIGNvbnN0IGhEYXkgPSBoRGF0ZS5kYXk7XG4gICAgY29uc3QganVsaWFuRGF5ID1cbiAgICAgICAgaERheSArIE1hdGguY2VpbCgyOS41ICogaE1vbnRoKSArIChoWWVhciAtIDEpICogMzU0ICsgTWF0aC5mbG9vcigoMyArIDExICogaFllYXIpIC8gMzApICsgSVNMQU1JQ19FUE9DSCAtIDE7XG5cbiAgICBjb25zdCB3amQgPSBNYXRoLmZsb29yKGp1bGlhbkRheSAtIDAuNSkgKyAwLjUsIGRlcG9jaCA9IHdqZCAtIEdSRUdPUklBTl9FUE9DSCxcbiAgICAgICAgICBxdWFkcmljZW50ID0gTWF0aC5mbG9vcihkZXBvY2ggLyAxNDYwOTcpLCBkcWMgPSBtb2QoZGVwb2NoLCAxNDYwOTcpLCBjZW50ID0gTWF0aC5mbG9vcihkcWMgLyAzNjUyNCksXG4gICAgICAgICAgZGNlbnQgPSBtb2QoZHFjLCAzNjUyNCksIHF1YWQgPSBNYXRoLmZsb29yKGRjZW50IC8gMTQ2MSksIGRxdWFkID0gbW9kKGRjZW50LCAxNDYxKSxcbiAgICAgICAgICB5aW5kZXggPSBNYXRoLmZsb29yKGRxdWFkIC8gMzY1KTtcbiAgICBsZXQgeWVhciA9IHF1YWRyaWNlbnQgKiA0MDAgKyBjZW50ICogMTAwICsgcXVhZCAqIDQgKyB5aW5kZXg7XG4gICAgaWYgKCEoY2VudCA9PT0gNCB8fCB5aW5kZXggPT09IDQpKSB7XG4gICAgICB5ZWFyKys7XG4gICAgfVxuXG4gICAgY29uc3QgZ1llYXJTdGFydCA9IEdSRUdPUklBTl9FUE9DSCArIDM2NSAqICh5ZWFyIC0gMSkgKyBNYXRoLmZsb29yKCh5ZWFyIC0gMSkgLyA0KSAtIE1hdGguZmxvb3IoKHllYXIgLSAxKSAvIDEwMCkgK1xuICAgICAgICBNYXRoLmZsb29yKCh5ZWFyIC0gMSkgLyA0MDApO1xuXG4gICAgY29uc3QgeWVhcmRheSA9IHdqZCAtIGdZZWFyU3RhcnQ7XG5cbiAgICBjb25zdCB0amQgPSBHUkVHT1JJQU5fRVBPQ0ggLSAxICsgMzY1ICogKHllYXIgLSAxKSArIE1hdGguZmxvb3IoKHllYXIgLSAxKSAvIDQpIC0gTWF0aC5mbG9vcigoeWVhciAtIDEpIC8gMTAwKSArXG4gICAgICAgIE1hdGguZmxvb3IoKHllYXIgLSAxKSAvIDQwMCkgKyBNYXRoLmZsb29yKDczOSAvIDEyICsgKGlzR3JlZ29yaWFuTGVhcFllYXIobmV3IERhdGUoeWVhciwgMywgMSkpID8gLTEgOiAtMikgKyAxKTtcblxuICAgIGNvbnN0IGxlYXBhZGogPSB3amQgPCB0amQgPyAwIDogaXNHcmVnb3JpYW5MZWFwWWVhcihuZXcgRGF0ZSh5ZWFyLCAzLCAxKSkgPyAxIDogMjtcblxuICAgIGNvbnN0IG1vbnRoID0gTWF0aC5mbG9vcigoKHllYXJkYXkgKyBsZWFwYWRqKSAqIDEyICsgMzczKSAvIDM2Nyk7XG4gICAgY29uc3QgdGpkMiA9IEdSRUdPUklBTl9FUE9DSCAtIDEgKyAzNjUgKiAoeWVhciAtIDEpICsgTWF0aC5mbG9vcigoeWVhciAtIDEpIC8gNCkgLSBNYXRoLmZsb29yKCh5ZWFyIC0gMSkgLyAxMDApICtcbiAgICAgICAgTWF0aC5mbG9vcigoeWVhciAtIDEpIC8gNDAwKSArXG4gICAgICAgIE1hdGguZmxvb3IoXG4gICAgICAgICAgICAoMzY3ICogbW9udGggLSAzNjIpIC8gMTIgKyAobW9udGggPD0gMiA/IDAgOiBpc0dyZWdvcmlhbkxlYXBZZWFyKG5ldyBEYXRlKHllYXIsIG1vbnRoIC0gMSwgMSkpID8gLTEgOiAtMikgK1xuICAgICAgICAgICAgMSk7XG5cbiAgICBjb25zdCBkYXkgPSB3amQgLSB0amQyICsgMTtcblxuICAgIHJldHVybiBuZXcgRGF0ZSh5ZWFyLCBtb250aCAtIDEsIGRheSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGRheXMgaW4gYSBzcGVjaWZpYyBIaWpyaSBtb250aC5cbiAgICogYG1vbnRoYCBpcyAxIGZvciBNdWhhcnJhbSwgMiBmb3IgU2FmYXIsIGV0Yy5cbiAgICogYHllYXJgIGlzIGFueSBIaWpyaSB5ZWFyLlxuICAgKi9cbiAgZ2V0RGF5c1Blck1vbnRoKG1vbnRoOiBudW1iZXIsIHllYXI6IG51bWJlcik6IG51bWJlciB7XG4gICAgeWVhciA9IHllYXIgKyBNYXRoLmZsb29yKG1vbnRoIC8gMTMpO1xuICAgIG1vbnRoID0gKChtb250aCAtIDEpICUgMTIpICsgMTtcbiAgICBsZXQgbGVuZ3RoID0gMjkgKyBtb250aCAlIDI7XG4gICAgaWYgKG1vbnRoID09PSAxMiAmJiBpc0lzbGFtaWNMZWFwWWVhcih5ZWFyKSkge1xuICAgICAgbGVuZ3RoKys7XG4gICAgfVxuICAgIHJldHVybiBsZW5ndGg7XG4gIH1cbn1cbiJdfQ==