ngb-calendar.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  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 { NgbDate } from './ngb-date';
  7. import { Injectable } from '@angular/core';
  8. import { isInteger } from '../util/util';
  9. import * as i0 from "@angular/core";
  10. /**
  11. * @param {?} jsDate
  12. * @return {?}
  13. */
  14. export function fromJSDate(jsDate) {
  15. return new NgbDate(jsDate.getFullYear(), jsDate.getMonth() + 1, jsDate.getDate());
  16. }
  17. /**
  18. * @param {?} date
  19. * @return {?}
  20. */
  21. export function toJSDate(date) {
  22. /** @type {?} */
  23. var jsDate = new Date(date.year, date.month - 1, date.day, 12);
  24. // this is done avoid 30 -> 1930 conversion
  25. if (!isNaN(jsDate.getTime())) {
  26. jsDate.setFullYear(date.year);
  27. }
  28. return jsDate;
  29. }
  30. /**
  31. * @return {?}
  32. */
  33. export function NGB_DATEPICKER_CALENDAR_FACTORY() {
  34. return new NgbCalendarGregorian();
  35. }
  36. /**
  37. * A service that represents the calendar used by the datepicker.
  38. *
  39. * The default implementation uses the Gregorian calendar. You can inject it in your own
  40. * implementations if necessary to simplify `NgbDate` calculations.
  41. * @abstract
  42. */
  43. var NgbCalendar = /** @class */ (function () {
  44. function NgbCalendar() {
  45. }
  46. NgbCalendar.decorators = [
  47. { type: Injectable, args: [{ providedIn: 'root', useFactory: NGB_DATEPICKER_CALENDAR_FACTORY },] }
  48. ];
  49. /** @nocollapse */ NgbCalendar.ngInjectableDef = i0.ɵɵdefineInjectable({ factory: NGB_DATEPICKER_CALENDAR_FACTORY, token: NgbCalendar, providedIn: "root" });
  50. return NgbCalendar;
  51. }());
  52. export { NgbCalendar };
  53. if (false) {
  54. /**
  55. * Returns the number of days per week.
  56. * @abstract
  57. * @return {?}
  58. */
  59. NgbCalendar.prototype.getDaysPerWeek = function () { };
  60. /**
  61. * Returns an array of months per year.
  62. *
  63. * With default calendar we use ISO 8601 and return [1, 2, ..., 12];
  64. * @abstract
  65. * @param {?=} year
  66. * @return {?}
  67. */
  68. NgbCalendar.prototype.getMonths = function (year) { };
  69. /**
  70. * Returns the number of weeks per month.
  71. * @abstract
  72. * @return {?}
  73. */
  74. NgbCalendar.prototype.getWeeksPerMonth = function () { };
  75. /**
  76. * Returns the weekday number for a given day.
  77. *
  78. * With the default calendar we use ISO 8601: 'weekday' is 1=Mon ... 7=Sun
  79. * @abstract
  80. * @param {?} date
  81. * @return {?}
  82. */
  83. NgbCalendar.prototype.getWeekday = function (date) { };
  84. /**
  85. * Adds a number of years, months or days to a given date.
  86. *
  87. * * `period` can be `y`, `m` or `d` and defaults to day.
  88. * * `number` defaults to 1.
  89. *
  90. * Always returns a new date.
  91. * @abstract
  92. * @param {?} date
  93. * @param {?=} period
  94. * @param {?=} number
  95. * @return {?}
  96. */
  97. NgbCalendar.prototype.getNext = function (date, period, number) { };
  98. /**
  99. * Subtracts a number of years, months or days from a given date.
  100. *
  101. * * `period` can be `y`, `m` or `d` and defaults to day.
  102. * * `number` defaults to 1.
  103. *
  104. * Always returns a new date.
  105. * @abstract
  106. * @param {?} date
  107. * @param {?=} period
  108. * @param {?=} number
  109. * @return {?}
  110. */
  111. NgbCalendar.prototype.getPrev = function (date, period, number) { };
  112. /**
  113. * Returns the week number for a given week.
  114. * @abstract
  115. * @param {?} week
  116. * @param {?} firstDayOfWeek
  117. * @return {?}
  118. */
  119. NgbCalendar.prototype.getWeekNumber = function (week, firstDayOfWeek) { };
  120. /**
  121. * Returns the today's date.
  122. * @abstract
  123. * @return {?}
  124. */
  125. NgbCalendar.prototype.getToday = function () { };
  126. /**
  127. * Checks if a date is valid in the current calendar.
  128. * @abstract
  129. * @param {?} date
  130. * @return {?}
  131. */
  132. NgbCalendar.prototype.isValid = function (date) { };
  133. }
  134. var NgbCalendarGregorian = /** @class */ (function (_super) {
  135. tslib_1.__extends(NgbCalendarGregorian, _super);
  136. function NgbCalendarGregorian() {
  137. return _super !== null && _super.apply(this, arguments) || this;
  138. }
  139. /**
  140. * @return {?}
  141. */
  142. NgbCalendarGregorian.prototype.getDaysPerWeek = /**
  143. * @return {?}
  144. */
  145. function () { return 7; };
  146. /**
  147. * @return {?}
  148. */
  149. NgbCalendarGregorian.prototype.getMonths = /**
  150. * @return {?}
  151. */
  152. function () { return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; };
  153. /**
  154. * @return {?}
  155. */
  156. NgbCalendarGregorian.prototype.getWeeksPerMonth = /**
  157. * @return {?}
  158. */
  159. function () { return 6; };
  160. /**
  161. * @param {?} date
  162. * @param {?=} period
  163. * @param {?=} number
  164. * @return {?}
  165. */
  166. NgbCalendarGregorian.prototype.getNext = /**
  167. * @param {?} date
  168. * @param {?=} period
  169. * @param {?=} number
  170. * @return {?}
  171. */
  172. function (date, period, number) {
  173. if (period === void 0) { period = 'd'; }
  174. if (number === void 0) { number = 1; }
  175. /** @type {?} */
  176. var jsDate = toJSDate(date);
  177. /** @type {?} */
  178. var checkMonth = true;
  179. /** @type {?} */
  180. var expectedMonth = jsDate.getMonth();
  181. switch (period) {
  182. case 'y':
  183. jsDate.setFullYear(jsDate.getFullYear() + number);
  184. break;
  185. case 'm':
  186. expectedMonth += number;
  187. jsDate.setMonth(expectedMonth);
  188. expectedMonth = expectedMonth % 12;
  189. if (expectedMonth < 0) {
  190. expectedMonth = expectedMonth + 12;
  191. }
  192. break;
  193. case 'd':
  194. jsDate.setDate(jsDate.getDate() + number);
  195. checkMonth = false;
  196. break;
  197. default:
  198. return date;
  199. }
  200. if (checkMonth && jsDate.getMonth() !== expectedMonth) {
  201. // this means the destination month has less days than the initial month
  202. // let's go back to the end of the previous month:
  203. jsDate.setDate(0);
  204. }
  205. return fromJSDate(jsDate);
  206. };
  207. /**
  208. * @param {?} date
  209. * @param {?=} period
  210. * @param {?=} number
  211. * @return {?}
  212. */
  213. NgbCalendarGregorian.prototype.getPrev = /**
  214. * @param {?} date
  215. * @param {?=} period
  216. * @param {?=} number
  217. * @return {?}
  218. */
  219. function (date, period, number) {
  220. if (period === void 0) { period = 'd'; }
  221. if (number === void 0) { number = 1; }
  222. return this.getNext(date, period, -number);
  223. };
  224. /**
  225. * @param {?} date
  226. * @return {?}
  227. */
  228. NgbCalendarGregorian.prototype.getWeekday = /**
  229. * @param {?} date
  230. * @return {?}
  231. */
  232. function (date) {
  233. /** @type {?} */
  234. var jsDate = toJSDate(date);
  235. /** @type {?} */
  236. var day = jsDate.getDay();
  237. // in JS Date Sun=0, in ISO 8601 Sun=7
  238. return day === 0 ? 7 : day;
  239. };
  240. /**
  241. * @param {?} week
  242. * @param {?} firstDayOfWeek
  243. * @return {?}
  244. */
  245. NgbCalendarGregorian.prototype.getWeekNumber = /**
  246. * @param {?} week
  247. * @param {?} firstDayOfWeek
  248. * @return {?}
  249. */
  250. function (week, firstDayOfWeek) {
  251. // in JS Date Sun=0, in ISO 8601 Sun=7
  252. if (firstDayOfWeek === 7) {
  253. firstDayOfWeek = 0;
  254. }
  255. /** @type {?} */
  256. var thursdayIndex = (4 + 7 - firstDayOfWeek) % 7;
  257. /** @type {?} */
  258. var date = week[thursdayIndex];
  259. /** @type {?} */
  260. var jsDate = toJSDate(date);
  261. jsDate.setDate(jsDate.getDate() + 4 - (jsDate.getDay() || 7)); // Thursday
  262. // Thursday
  263. /** @type {?} */
  264. var time = jsDate.getTime();
  265. jsDate.setMonth(0); // Compare with Jan 1
  266. jsDate.setDate(1);
  267. return Math.floor(Math.round((time - jsDate.getTime()) / 86400000) / 7) + 1;
  268. };
  269. /**
  270. * @return {?}
  271. */
  272. NgbCalendarGregorian.prototype.getToday = /**
  273. * @return {?}
  274. */
  275. function () { return fromJSDate(new Date()); };
  276. /**
  277. * @param {?} date
  278. * @return {?}
  279. */
  280. NgbCalendarGregorian.prototype.isValid = /**
  281. * @param {?} date
  282. * @return {?}
  283. */
  284. function (date) {
  285. if (!date || !isInteger(date.year) || !isInteger(date.month) || !isInteger(date.day)) {
  286. return false;
  287. }
  288. // year 0 doesn't exist in Gregorian calendar
  289. if (date.year === 0) {
  290. return false;
  291. }
  292. /** @type {?} */
  293. var jsDate = toJSDate(date);
  294. return !isNaN(jsDate.getTime()) && jsDate.getFullYear() === date.year && jsDate.getMonth() + 1 === date.month &&
  295. jsDate.getDate() === date.day;
  296. };
  297. NgbCalendarGregorian.decorators = [
  298. { type: Injectable }
  299. ];
  300. return NgbCalendarGregorian;
  301. }(NgbCalendar));
  302. export { NgbCalendarGregorian };
  303. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdiLWNhbGVuZGFyLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAvIiwic291cmNlcyI6WyJkYXRlcGlja2VyL25nYi1jYWxlbmRhci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxZQUFZLENBQUM7QUFDbkMsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sY0FBYyxDQUFDOzs7Ozs7QUFFdkMsTUFBTSxVQUFVLFVBQVUsQ0FBQyxNQUFZO0lBQ3JDLE9BQU8sSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLEVBQUUsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFDcEYsQ0FBQzs7Ozs7QUFDRCxNQUFNLFVBQVUsUUFBUSxDQUFDLElBQWE7O1FBQzlCLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDO0lBQ2hFLDJDQUEyQztJQUMzQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFO1FBQzVCLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQy9CO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQzs7OztBQUlELE1BQU0sVUFBVSwrQkFBK0I7SUFDN0MsT0FBTyxJQUFJLG9CQUFvQixFQUFFLENBQUM7QUFDcEMsQ0FBQzs7Ozs7Ozs7QUFRRDtJQUFBO0tBNERDOztnQkE1REEsVUFBVSxTQUFDLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsK0JBQStCLEVBQUM7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LEtBQUssQ0FBQztTQUNkO1FBRUQsNkNBQTZDO1FBQzdDLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxDQUFDLEVBQUU7WUFDbkIsT0FBTyxLQUFLLENBQUM7U0FDZDs7WUFFSyxNQUFNLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQztRQUU3QixPQUFPLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxXQUFXLEVBQUUsS0FBSyxJQUFJLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLEtBQUssSUFBSSxDQUFDLEtBQUs7WUFDekcsTUFBTSxDQUFDLE9BQU8sRUFBRSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDcEMsQ0FBQzs7Z0JBcEZGLFVBQVU7O0lBcUZYLDJCQUFDO0NBQUEsQUFyRkQsQ0FDMEMsV0FBVyxHQW9GcEQ7U0FwRlksb0JBQW9CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtOZ2JEYXRlfSBmcm9tICcuL25nYi1kYXRlJztcbmltcG9ydCB7SW5qZWN0YWJsZX0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge2lzSW50ZWdlcn0gZnJvbSAnLi4vdXRpbC91dGlsJztcblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21KU0RhdGUoanNEYXRlOiBEYXRlKSB7XG4gIHJldHVybiBuZXcgTmdiRGF0ZShqc0RhdGUuZ2V0RnVsbFllYXIoKSwganNEYXRlLmdldE1vbnRoKCkgKyAxLCBqc0RhdGUuZ2V0RGF0ZSgpKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiB0b0pTRGF0ZShkYXRlOiBOZ2JEYXRlKSB7XG4gIGNvbnN0IGpzRGF0ZSA9IG5ldyBEYXRlKGRhdGUueWVhciwgZGF0ZS5tb250aCAtIDEsIGRhdGUuZGF5LCAxMik7XG4gIC8vIHRoaXMgaXMgZG9uZSBhdm9pZCAzMCAtPiAxOTMwIGNvbnZlcnNpb25cbiAgaWYgKCFpc05hTihqc0RhdGUuZ2V0VGltZSgpKSkge1xuICAgIGpzRGF0ZS5zZXRGdWxsWWVhcihkYXRlLnllYXIpO1xuICB9XG4gIHJldHVybiBqc0RhdGU7XG59XG5cbmV4cG9ydCB0eXBlIE5nYlBlcmlvZCA9ICd5JyB8ICdtJyB8ICdkJztcblxuZXhwb3J0IGZ1bmN0aW9uIE5HQl9EQVRFUElDS0VSX0NBTEVOREFSX0ZBQ1RPUlkoKSB7XG4gIHJldHVybiBuZXcgTmdiQ2FsZW5kYXJHcmVnb3JpYW4oKTtcbn1cblxuLyoqXG4gKiBBIHNlcnZpY2UgdGhhdCByZXByZXNlbnRzIHRoZSBjYWxlbmRhciB1c2VkIGJ5IHRoZSBkYXRlcGlja2VyLlxuICpcbiAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHVzZXMgdGhlIEdyZWdvcmlhbiBjYWxlbmRhci4gWW91IGNhbiBpbmplY3QgaXQgaW4geW91ciBvd25cbiAqIGltcGxlbWVudGF0aW9ucyBpZiBuZWNlc3NhcnkgdG8gc2ltcGxpZnkgYE5nYkRhdGVgIGNhbGN1bGF0aW9ucy5cbiAqL1xuQEluamVjdGFibGUoe3Byb3ZpZGVkSW46ICdyb290JywgdXNlRmFjdG9yeTogTkdCX0RBVEVQSUNLRVJfQ0FMRU5EQVJfRkFDVE9SWX0pXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgTmdiQ2FsZW5kYXIge1xuICAvKipcbiAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGRheXMgcGVyIHdlZWsuXG4gICAqL1xuICBhYnN0cmFjdCBnZXREYXlzUGVyV2VlaygpOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gYXJyYXkgb2YgbW9udGhzIHBlciB5ZWFyLlxuICAgKlxuICAgKiBXaXRoIGRlZmF1bHQgY2FsZW5kYXIgd2UgdXNlIElTTyA4NjAxIGFuZCByZXR1cm4gWzEsIDIsIC4uLiwgMTJdO1xuICAgKi9cbiAgYWJzdHJhY3QgZ2V0TW9udGhzKHllYXI/OiBudW1iZXIpOiBudW1iZXJbXTtcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIHdlZWtzIHBlciBtb250aC5cbiAgICovXG4gIGFic3RyYWN0IGdldFdlZWtzUGVyTW9udGgoKTogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSB3ZWVrZGF5IG51bWJlciBmb3IgYSBnaXZlbiBkYXkuXG4gICAqXG4gICAqIFdpdGggdGhlIGRlZmF1bHQgY2FsZW5kYXIgd2UgdXNlIElTTyA4NjAxOiAnd2Vla2RheScgaXMgMT1Nb24gLi4uIDc9U3VuXG4gICAqL1xuICBhYnN0cmFjdCBnZXRXZWVrZGF5KGRhdGU6IE5nYkRhdGUpOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBudW1iZXIgb2YgeWVhcnMsIG1vbnRocyBvciBkYXlzIHRvIGEgZ2l2ZW4gZGF0ZS5cbiAgICpcbiAgICogKiBgcGVyaW9kYCBjYW4gYmUgYHlgLCBgbWAgb3IgYGRgIGFuZCBkZWZhdWx0cyB0byBkYXkuXG4gICAqICogYG51bWJlcmAgZGVmYXVsdHMgdG8gMS5cbiAgICpcbiAgICogQWx3YXlzIHJldHVybnMgYSBuZXcgZGF0ZS5cbiAgICovXG4gIGFic3RyYWN0IGdldE5leHQoZGF0ZTogTmdiRGF0ZSwgcGVyaW9kPzogTmdiUGVyaW9kLCBudW1iZXI/OiBudW1iZXIpOiBOZ2JEYXRlO1xuXG4gIC8qKlxuICAgKiBTdWJ0cmFjdHMgYSBudW1iZXIgb2YgeWVhcnMsIG1vbnRocyBvciBkYXlzIGZyb20gYSBnaXZlbiBkYXRlLlxuICAgKlxuICAgKiAqIGBwZXJpb2RgIGNhbiBiZSBgeWAsIGBtYCBvciBgZGAgYW5kIGRlZmF1bHRzIHRvIGRheS5cbiAgICogKiBgbnVtYmVyYCBkZWZhdWx0cyB0byAxLlxuICAgKlxuICAgKiBBbHdheXMgcmV0dXJucyBhIG5ldyBkYXRlLlxuICAgKi9cbiAgYWJzdHJhY3QgZ2V0UHJldihkYXRlOiBOZ2JEYXRlLCBwZXJpb2Q/OiBOZ2JQZXJpb2QsIG51bWJlcj86IG51bWJlcik6IE5nYkRhdGU7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHdlZWsgbnVtYmVyIGZvciBhIGdpdmVuIHdlZWsuXG4gICAqL1xuICBhYnN0cmFjdCBnZXRXZWVrTnVtYmVyKHdlZWs6IHJlYWRvbmx5IE5nYkRhdGVbXSwgZmlyc3REYXlPZldlZWs6IG51bWJlcik6IG51bWJlcjtcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgdG9kYXkncyBkYXRlLlxuICAgKi9cbiAgYWJzdHJhY3QgZ2V0VG9kYXkoKTogTmdiRGF0ZTtcblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGEgZGF0ZSBpcyB2YWxpZCBpbiB0aGUgY3VycmVudCBjYWxlbmRhci5cbiAgICovXG4gIGFic3RyYWN0IGlzVmFsaWQoZGF0ZTogTmdiRGF0ZSk6IGJvb2xlYW47XG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBOZ2JDYWxlbmRhckdyZWdvcmlhbiBleHRlbmRzIE5nYkNhbGVuZGFyIHtcbiAgZ2V0RGF5c1BlcldlZWsoKSB7IHJldHVybiA3OyB9XG5cbiAgZ2V0TW9udGhzKCkgeyByZXR1cm4gWzEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTJdOyB9XG5cbiAgZ2V0V2Vla3NQZXJNb250aCgpIHsgcmV0dXJuIDY7IH1cblxuICBnZXROZXh0KGRhdGU6IE5nYkRhdGUsIHBlcmlvZDogTmdiUGVyaW9kID0gJ2QnLCBudW1iZXIgPSAxKSB7XG4gICAgbGV0IGpzRGF0ZSA9IHRvSlNEYXRlKGRhdGUpO1xuICAgIGxldCBjaGVja01vbnRoID0gdHJ1ZTtcbiAgICBsZXQgZXhwZWN0ZWRNb250aCA9IGpzRGF0ZS5nZXRNb250aCgpO1xuXG4gICAgc3dpdGNoIChwZXJpb2QpIHtcbiAgICAgIGNhc2UgJ3knOlxuICAgICAgICBqc0RhdGUuc2V0RnVsbFllYXIoanNEYXRlLmdldEZ1bGxZZWFyKCkgKyBudW1iZXIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ20nOlxuICAgICAgICBleHBlY3RlZE1vbnRoICs9IG51bWJlcjtcbiAgICAgICAganNEYXRlLnNldE1vbnRoKGV4cGVjdGVkTW9udGgpO1xuICAgICAgICBleHBlY3RlZE1vbnRoID0gZXhwZWN0ZWRNb250aCAlIDEyO1xuICAgICAgICBpZiAoZXhwZWN0ZWRNb250aCA8IDApIHtcbiAgICAgICAgICBleHBlY3RlZE1vbnRoID0gZXhwZWN0ZWRNb250aCArIDEyO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZCc6XG4gICAgICAgIGpzRGF0ZS5zZXREYXRlKGpzRGF0ZS5nZXREYXRlKCkgKyBudW1iZXIpO1xuICAgICAgICBjaGVja01vbnRoID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuXG4gICAgaWYgKGNoZWNrTW9udGggJiYganNEYXRlLmdldE1vbnRoKCkgIT09IGV4cGVjdGVkTW9udGgpIHtcbiAgICAgIC8vIHRoaXMgbWVhbnMgdGhlIGRlc3RpbmF0aW9uIG1vbnRoIGhhcyBsZXNzIGRheXMgdGhhbiB0aGUgaW5pdGlhbCBtb250aFxuICAgICAgLy8gbGV0J3MgZ28gYmFjayB0byB0aGUgZW5kIG9mIHRoZSBwcmV2aW91cyBtb250aDpcbiAgICAgIGpzRGF0ZS5zZXREYXRlKDApO1xuICAgIH1cblxuICAgIHJldHVybiBmcm9tSlNEYXRlKGpzRGF0ZSk7XG4gIH1cblxuICBnZXRQcmV2KGRhdGU6IE5nYkRhdGUsIHBlcmlvZDogTmdiUGVyaW9kID0gJ2QnLCBudW1iZXIgPSAxKSB7IHJldHVybiB0aGlzLmdldE5leHQoZGF0ZSwgcGVyaW9kLCAtbnVtYmVyKTsgfVxuXG4gIGdldFdlZWtkYXkoZGF0ZTogTmdiRGF0ZSkge1xuICAgIGxldCBqc0RhdGUgPSB0b0pTRGF0ZShkYXRlKTtcbiAgICBsZXQgZGF5ID0ganNEYXRlLmdldERheSgpO1xuICAgIC8vIGluIEpTIERhdGUgU3VuPTAsIGluIElTTyA4NjAxIFN1bj03XG4gICAgcmV0dXJuIGRheSA9PT0gMCA/IDcgOiBkYXk7XG4gIH1cblxuICBnZXRXZWVrTnVtYmVyKHdlZWs6IHJlYWRvbmx5IE5nYkRhdGVbXSwgZmlyc3REYXlPZldlZWs6IG51bWJlcikge1xuICAgIC8vIGluIEpTIERhdGUgU3VuPTAsIGluIElTTyA4NjAxIFN1bj03XG4gICAgaWYgKGZpcnN0RGF5T2ZXZWVrID09PSA3KSB7XG4gICAgICBmaXJzdERheU9mV2VlayA9IDA7XG4gICAgfVxuXG4gICAgY29uc3QgdGh1cnNkYXlJbmRleCA9ICg0ICsgNyAtIGZpcnN0RGF5T2ZXZWVrKSAlIDc7XG4gICAgbGV0IGRhdGUgPSB3ZWVrW3RodXJzZGF5SW5kZXhdO1xuXG4gICAgY29uc3QganNEYXRlID0gdG9KU0RhdGUoZGF0ZSk7XG4gICAganNEYXRlLnNldERhdGUoanNEYXRlLmdldERhdGUoKSArIDQgLSAoanNEYXRlLmdldERheSgpIHx8IDcpKTsgIC8vIFRodXJzZGF5XG4gICAgY29uc3QgdGltZSA9IGpzRGF0ZS5nZXRUaW1lKCk7XG4gICAganNEYXRlLnNldE1vbnRoKDApOyAgLy8gQ29tcGFyZSB3aXRoIEphbiAxXG4gICAganNEYXRlLnNldERhdGUoMSk7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5yb3VuZCgodGltZSAtIGpzRGF0ZS5nZXRUaW1lKCkpIC8gODY0MDAwMDApIC8gNykgKyAxO1xuICB9XG5cbiAgZ2V0VG9kYXkoKTogTmdiRGF0ZSB7IHJldHVybiBmcm9tSlNEYXRlKG5ldyBEYXRlKCkpOyB9XG5cbiAgaXNWYWxpZChkYXRlOiBOZ2JEYXRlKTogYm9vbGVhbiB7XG4gICAgaWYgKCFkYXRlIHx8ICFpc0ludGVnZXIoZGF0ZS55ZWFyKSB8fCAhaXNJbnRlZ2VyKGRhdGUubW9udGgpIHx8ICFpc0ludGVnZXIoZGF0ZS5kYXkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8geWVhciAwIGRvZXNuJ3QgZXhpc3QgaW4gR3JlZ29yaWFuIGNhbGVuZGFyXG4gICAgaWYgKGRhdGUueWVhciA9PT0gMCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGpzRGF0ZSA9IHRvSlNEYXRlKGRhdGUpO1xuXG4gICAgcmV0dXJuICFpc05hTihqc0RhdGUuZ2V0VGltZSgpKSAmJiBqc0RhdGUuZ2V0RnVsbFllYXIoKSA9PT0gZGF0ZS55ZWFyICYmIGpzRGF0ZS5nZXRNb250aCgpICsgMSA9PT0gZGF0ZS5tb250aCAmJlxuICAgICAgICBqc0RhdGUuZ2V0RGF0ZSgpID09PSBkYXRlLmRheTtcbiAgfVxufVxuIl19