PageSourceSearch

https://caritascambodia.org/wp-content/themes/caritas-cambodia/ass…/bootstrap-datepicker.js?ver=1790977120

js caritascambodia.org collected 2026-10-02 21:39:46 UTC 53,594 bytes, 1,709 lines download raw bytes

1'use strict';
2
3var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
4
5
6(function (factory) {
7	if (typeof define === 'function' && define.amd) {
8		define(['jquery'], factory);
9	} else if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object') {
10		factory(require('jquery'));
11	} else {
12		factory(jQuery);
13	}
14})(function ($, undefined) {
15	function UTCDate() {
16		return new Date(Date.UTC.apply(Date, arguments));
17	}
18	function UTCToday() {
19		var today = new Date();
20		return UTCDate(today.getFullYear(), today.getMonth(), today.getDate());
21	}
22	function isUTCEquals(date1, date2) {
23		return date1.getUTCFullYear() === date2.getUTCFullYear() && date1.getUTCMonth() === date2.getUTCMonth() && date1.getUTCDate() === date2.getUTCDate();
24	}
25	function alias(method, deprecationMsg) {
26		return function () {
27			if (deprecationMsg !== undefined) {
28				$.fn.datepicker.deprecated(deprecationMsg);
29			}
30
31			return this[method].apply(this, arguments);
32		};
33	}
34	function isValidDate(d) {
35		return d && !isNaN(d.getTime());
36	}
37
38	var DateArray = function () {
39		var extras = {
40			get: function get(i) {
41				return this.slice(i)[0];
42			},
43			contains: function contains(d) {
44				var val = d && d.valueOf();
45				for (var i = 0, l = this.length; i < l; i++) {
46					if (0 <= this[i].valueOf() - val && this[i].valueOf() - val < 1000 * 60 * 60 * 24) return i;
47				}return -1;
48			},
49			remove: function remove(i) {
50				this.splice(i, 1);
51			},
52			replace: function replace(new_array) {
53				if (!new_array) return;
54				if (!$.isArray(new_array)) new_array = [new_array];
55				this.clear();
56				this.push.apply(this, new_array);
57			},
58			clear: function clear() {
59				this.length = 0;
60			},
61			copy: function copy() {
62				var a = new DateArray();
63				a.replace(this);
64				return a;
65			}
66		};
67
68		return function () {
69			var a = [];
70			a.push.apply(a, arguments);
71			$.extend(a, extras);
72			return a;
73		};
74	}();
75
76
77	var Datepicker = function Datepicker(element, options) {
78		$.data(element, 'datepicker', this);
79
80		this._events = [];
81		this._secondaryEvents = [];
82
83		this._process_options(options);
84
85		this.dates = new DateArray();
86		this.viewDate = this.o.defaultViewDate;
87		this.focusDate = null;
88
89		this.element = $(element);
90		this.isInput = this.element.is('input');
91		this.inputField = this.isInput ? this.element : this.element.find('input');
92		this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn') : false;
93		if (this.component && this.component.length === 0) this.component = false;
94		this.isInline = !this.component && this.element.is('div');
95
96		this.picker = $(DPGlobal.template);
97
98		if (this._check_template(this.o.templates.leftArrow)) {
99			this.picker.find('.prev').html(this.o.templates.leftArrow);
100		}
101
102		if (this._check_template(this.o.templates.rightArrow)) {
103			this.picker.find('.next').html(this.o.templates.rightArrow);
104		}
105
106		this._buildEvents();
107		this._attachEvents();
108
109		if (this.isInline) {
110			this.picker.addClass('datepicker-inline').appendTo(this.element);
111		} else {
112			this.picker.addClass('datepicker-dropdown dropdown-menu');
113		}
114
115		if (this.o.rtl) {
116			this.picker.addClass('datepicker-rtl');
117		}
118
119		if (this.o.calendarWeeks) {
120			this.picker.find('.datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear').attr('colspan', function (i, val) {
121				return Number(val) + 1;
122			});
123		}
124
125		this._process_options({
126			startDate: this._o.startDate,
127			endDate: this._o.endDate,
128			daysOfWeekDisabled: this.o.daysOfWeekDisabled,
129			daysOfWeekHighlighted: this.o.daysOfWeekHighlighted,
130			datesDisabled: this.o.datesDisabled
131		});
132
133		this._allow_update = false;
134		this.setViewMode(this.o.startView);
135		this._allow_update = true;
136
137		this.fillDow();
138		this.fillMonths();
139
140		this.update();
141
142		if (this.isInline) {
143			this.show();
144		}
145	};
146
147	Datepicker.prototype = {
148		constructor: Datepicker,
149
150		_resolveViewName: function _resolveViewName(view) {
vendor: 49,128 bytes, lines 151-1700
151			$.each(DPGlobal.viewModes, function (i, viewMode) {
152				if (view === i || $.inArray(view, viewMode.names) !== -1) {
153					view = i;
154					return false;
155				}
156			});
157
158			return view;
159		},
160
161		_resolveDaysOfWeek: function _resolveDaysOfWeek(daysOfWeek) {
162			if (!$.isArray(daysOfWeek)) daysOfWeek = daysOfWeek.split(/[,\s]*/);
163			return $.map(daysOfWeek, Number);
164		},
165
166		_check_template: function _check_template(tmp) {
167			try {
168				if (tmp === undefined || tmp === "") {
169					return false;
170				}
171				if ((tmp.match(/[<>]/g) || []).length <= 0) {
172					return true;
173				}
174				var jDom = $(tmp);
175				return jDom.length > 0;
176			} catch (ex) {
177				return false;
178			}
179		},
180
181		_process_options: function _process_options(opts) {
182			this._o = $.extend({}, this._o, opts);
183			var o = this.o = $.extend({}, this._o);
184
185			var lang = o.language;
186			if (!dates[lang]) {
187				lang = lang.split('-')[0];
188				if (!dates[lang]) lang = defaults.language;
189			}
190			o.language = lang;
191
192			o.startView = this._resolveViewName(o.startView);
193			o.minViewMode = this._resolveViewName(o.minViewMode);
194			o.maxViewMode = this._resolveViewName(o.maxViewMode);
195
196			o.startView = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, o.startView));
197
198			if (o.multidate !== true) {
199				o.multidate = Number(o.multidate) || false;
200				if (o.multidate !== false) o.multidate = Math.max(0, o.multidate);
201			}
202			o.multidateSeparator = String(o.multidateSeparator);
203
204			o.weekStart %= 7;
205			o.weekEnd = (o.weekStart + 6) % 7;
206
207			var format = DPGlobal.parseFormat(o.format);
208			if (o.startDate !== -Infinity) {
209				if (!!o.startDate) {
210					if (o.startDate instanceof Date) o.startDate = this._local_to_utc(this._zero_time(o.startDate));else o.startDate = DPGlobal.parseDate(o.startDate, format, o.language, o.assumeNearbyYear);
211				} else {
212					o.startDate = -Infinity;
213				}
214			}
215			if (o.endDate !== Infinity) {
216				if (!!o.endDate) {
217					if (o.endDate instanceof Date) o.endDate = this._local_to_utc(this._zero_time(o.endDate));else o.endDate = DPGlobal.parseDate(o.endDate, format, o.language, o.assumeNearbyYear);
218				} else {
219					o.endDate = Infinity;
220				}
221			}
222
223			o.daysOfWeekDisabled = this._resolveDaysOfWeek(o.daysOfWeekDisabled || []);
224			o.daysOfWeekHighlighted = this._resolveDaysOfWeek(o.daysOfWeekHighlighted || []);
225
226			o.datesDisabled = o.datesDisabled || [];
227			if (!$.isArray(o.datesDisabled)) {
228				o.datesDisabled = o.datesDisabled.split(',');
229			}
230			o.datesDisabled = $.map(o.datesDisabled, function (d) {
231				return DPGlobal.parseDate(d, format, o.language, o.assumeNearbyYear);
232			});
233
234			var plc = String(o.orientation).toLowerCase().split(/\s+/g),
235			    _plc = o.orientation.toLowerCase();
236			plc = $.grep(plc, function (word) {
237				return (/^auto|left|right|top|bottom$/.test(word)
238				);
239			});
240			o.orientation = { x: 'auto', y: 'auto' };
241			if (!_plc || _plc === 'auto') ; 
242			else if (plc.length === 1) {
243					switch (plc[0]) {
244						case 'top':
245						case 'bottom':
246							o.orientation.y = plc[0];
247							break;
248						case 'left':
249						case 'right':
250							o.orientation.x = plc[0];
251							break;
252					}
253				} else {
254					_plc = $.grep(plc, function (word) {
255						return (/^left|right$/.test(word)
256						);
257					});
258					o.orientation.x = _plc[0] || 'auto';
259
260					_plc = $.grep(plc, function (word) {
261						return (/^top|bottom$/.test(word)
262						);
263					});
264					o.orientation.y = _plc[0] || 'auto';
265				}
266			if (o.defaultViewDate instanceof Date || typeof o.defaultViewDate === 'string') {
267				o.defaultViewDate = DPGlobal.parseDate(o.defaultViewDate, format, o.language, o.assumeNearbyYear);
268			} else if (o.defaultViewDate) {
269				var year = o.defaultViewDate.year || new Date().getFullYear();
270				var month = o.defaultViewDate.month || 0;
271				var day = o.defaultViewDate.day || 1;
272				o.defaultViewDate = UTCDate(year, month, day);
273			} else {
274				o.defaultViewDate = UTCToday();
275			}
276		},
277		_applyEvents: function _applyEvents(evs) {
278			for (var i = 0, el, ch, ev; i < evs.length; i++) {
279				el = evs[i][0];
280				if (evs[i].length === 2) {
281					ch = undefined;
282					ev = evs[i][1];
283				} else if (evs[i].length === 3) {
284					ch = evs[i][1];
285					ev = evs[i][2];
286				}
287				el.on(ev, ch);
288			}
289		},
290		_unapplyEvents: function _unapplyEvents(evs) {
291			for (var i = 0, el, ev, ch; i < evs.length; i++) {
292				el = evs[i][0];
293				if (evs[i].length === 2) {
294					ch = undefined;
295					ev = evs[i][1];
296				} else if (evs[i].length === 3) {
297					ch = evs[i][1];
298					ev = evs[i][2];
299				}
300				el.off(ev, ch);
301			}
302		},
303		_buildEvents: function _buildEvents() {
304			var events = {
305				keyup: $.proxy(function (e) {
306					if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1) this.update();
307				}, this),
308				keydown: $.proxy(this.keydown, this),
309				paste: $.proxy(this.paste, this)
310			};
311
312			if (this.o.showOnFocus === true) {
313				events.focus = $.proxy(this.show, this);
314			}
315
316			if (this.isInput) {
317				this._events = [[this.element, events]];
318			}
319			else if (this.component && this.inputField.length) {
320					this._events = [
321					[this.inputField, events], [this.component, {
322						click: $.proxy(this.show, this)
323					}]];
324				} else {
325					this._events = [[this.element, {
326						click: $.proxy(this.show, this),
327						keydown: $.proxy(this.keydown, this)
328					}]];
329				}
330			this._events.push(
331			[this.element, '*', {
332				blur: $.proxy(function (e) {
333					this._focused_from = e.target;
334				}, this)
335			}],
336			[this.element, {
337				blur: $.proxy(function (e) {
338					this._focused_from = e.target;
339				}, this)
340			}]);
341
342			if (this.o.immediateUpdates) {
343				this._events.push([this.element, {
344					'changeYear changeMonth': $.proxy(function (e) {
345						this.update(e.date);
346					}, this)
347				}]);
348			}
349
350			this._secondaryEvents = [[this.picker, {
351				click: $.proxy(this.click, this)
352			}], [this.picker, '.prev, .next', {
353				click: $.proxy(this.navArrowsClick, this)
354			}], [this.picker, '.day:not(.disabled)', {
355				click: $.proxy(this.dayCellClick, this)
356			}], [$(window), {
357				resize: $.proxy(this.place, this)
358			}], [$(document), {
359				'mousedown touchstart': $.proxy(function (e) {
360					if (!(this.element.is(e.target) || this.element.find(e.target).length || this.picker.is(e.target) || this.picker.find(e.target).length || this.isInline)) {
361						this.hide();
362					}
363				}, this)
364			}]];
365		},
366		_attachEvents: function _attachEvents() {
367			this._detachEvents();
368			this._applyEvents(this._events);
369		},
370		_detachEvents: function _detachEvents() {
371			this._unapplyEvents(this._events);
372		},
373		_attachSecondaryEvents: function _attachSecondaryEvents() {
374			this._detachSecondaryEvents();
375			this._applyEvents(this._secondaryEvents);
376		},
377		_detachSecondaryEvents: function _detachSecondaryEvents() {
378			this._unapplyEvents(this._secondaryEvents);
379		},
380		_trigger: function _trigger(event, altdate) {
381			var date = altdate || this.dates.get(-1),
382			    local_date = this._utc_to_local(date);
383
384			this.element.trigger({
385				type: event,
386				date: local_date,
387				viewMode: this.viewMode,
388				dates: $.map(this.dates, this._utc_to_local),
389				format: $.proxy(function (ix, format) {
390					if (arguments.length === 0) {
391						ix = this.dates.length - 1;
392						format = this.o.format;
393					} else if (typeof ix === 'string') {
394						format = ix;
395						ix = this.dates.length - 1;
396					}
397					format = format || this.o.format;
398					var date = this.dates.get(ix);
399					return DPGlobal.formatDate(date, format, this.o.language);
400				}, this)
401			});
402		},
403
404		show: function show() {
405			if (this.inputField.is(':disabled') || this.inputField.prop('readonly') && this.o.enableOnReadonly === false) return;
406			if (!this.isInline) this.picker.appendTo(this.o.container);
407			this.place();
408			this.picker.show();
409			this._attachSecondaryEvents();
410			this._trigger('show');
411			if ((window.navigator.msMaxTouchPoints || 'ontouchstart' in document) && this.o.disableTouchKeyboard) {
412				$(this.element).blur();
413			}
414			return this;
415		},
416
417		hide: function hide() {
418			if (this.isInline || !this.picker.is(':visible')) return this;
419			this.focusDate = null;
420			this.picker.hide().detach();
421			this._detachSecondaryEvents();
422			this.setViewMode(this.o.startView);
423
424			if (this.o.forceParse && this.inputField.val()) this.setValue();
425			this._trigger('hide');
426			return this;
427		},
428
429		destroy: function destroy() {
430			this.hide();
431			this._detachEvents();
432			this._detachSecondaryEvents();
433			this.picker.remove();
434			delete this.element.data().datepicker;
435			if (!this.isInput) {
436				delete this.element.data().date;
437			}
438			return this;
439		},
440
441		paste: function paste(e) {
442			var dateString;
443			if (e.originalEvent.clipboardData && e.originalEvent.clipboardData.types && $.inArray('text/plain', e.originalEvent.clipboardData.types) !== -1) {
444				dateString = e.originalEvent.clipboardData.getData('text/plain');
445			} else if (window.clipboardData) {
446				dateString = window.clipboardData.getData('Text');
447			} else {
448				return;
449			}
450			this.setDate(dateString);
451			this.update();
452			e.preventDefault();
453		},
454
455		_utc_to_local: function _utc_to_local(utc) {
456			if (!utc) {
457				return utc;
458			}
459
460			var local = new Date(utc.getTime() + utc.getTimezoneOffset() * 60000);
461
462			if (local.getTimezoneOffset() !== utc.getTimezoneOffset()) {
463				local = new Date(utc.getTime() + local.getTimezoneOffset() * 60000);
464			}
465
466			return local;
467		},
468		_local_to_utc: function _local_to_utc(local) {
469			return local && new Date(local.getTime() - local.getTimezoneOffset() * 60000);
470		},
471		_zero_time: function _zero_time(local) {
472			return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
473		},
474		_zero_utc_time: function _zero_utc_time(utc) {
475			return utc && UTCDate(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate());
476		},
477
478		getDates: function getDates() {
479			return $.map(this.dates, this._utc_to_local);
480		},
481
482		getUTCDates: function getUTCDates() {
483			return $.map(this.dates, function (d) {
484				return new Date(d);
485			});
486		},
487
488		getDate: function getDate() {
489			return this._utc_to_local(this.getUTCDate());
490		},
491
492		getUTCDate: function getUTCDate() {
493			var selected_date = this.dates.get(-1);
494			if (selected_date !== undefined) {
495				return new Date(selected_date);
496			} else {
497				return null;
498			}
499		},
500
501		clearDates: function clearDates() {
502			this.inputField.val('');
503			this.update();
504			this._trigger('changeDate');
505
506			if (this.o.autoclose) {
507				this.hide();
508			}
509		},
510
511		setDates: function setDates() {
512			var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
513			this.update.apply(this, args);
514			this._trigger('changeDate');
515			this.setValue();
516			return this;
517		},
518
519		setUTCDates: function setUTCDates() {
520			var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
521			this.setDates.apply(this, $.map(args, this._utc_to_local));
522			return this;
523		},
524
525		setDate: alias('setDates'),
526		setUTCDate: alias('setUTCDates'),
527		remove: alias('destroy', 'Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead'),
528
529		setValue: function setValue() {
530			var formatted = this.getFormattedDate();
531			this.inputField.val(formatted);
532			return this;
533		},
534
535		getFormattedDate: function getFormattedDate(format) {
536			if (format === undefined) format = this.o.format;
537
538			var lang = this.o.language;
539			return $.map(this.dates, function (d) {
540				return DPGlobal.formatDate(d, format, lang);
541			}).join(this.o.multidateSeparator);
542		},
543
544		getStartDate: function getStartDate() {
545			return this.o.startDate;
546		},
547
548		setStartDate: function setStartDate(startDate) {
549			this._process_options({ startDate: startDate });
550			this.update();
551			this.updateNavArrows();
552			return this;
553		},
554
555		getEndDate: function getEndDate() {
556			return this.o.endDate;
557		},
558
559		setEndDate: function setEndDate(endDate) {
560			this._process_options({ endDate: endDate });
561			this.update();
562			this.updateNavArrows();
563			return this;
564		},
565
566		setDaysOfWeekDisabled: function setDaysOfWeekDisabled(daysOfWeekDisabled) {
567			this._process_options({ daysOfWeekDisabled: daysOfWeekDisabled });
568			this.update();
569			return this;
570		},
571
572		setDaysOfWeekHighlighted: function setDaysOfWeekHighlighted(daysOfWeekHighlighted) {
573			this._process_options({ daysOfWeekHighlighted: daysOfWeekHighlighted });
574			this.update();
575			return this;
576		},
577
578		setDatesDisabled: function setDatesDisabled(datesDisabled) {
579			this._process_options({ datesDisabled: datesDisabled });
580			this.update();
581			return this;
582		},
583
584		place: function place() {
585			if (this.isInline) return this;
586			var calendarWidth = this.picker.outerWidth(),
587			    calendarHeight = this.picker.outerHeight(),
588			    visualPadding = 10,
589			    container = $(this.o.container),
590			    windowWidth = container.width(),
591			    scrollTop = this.o.container === 'body' ? $(document).scrollTop() : container.scrollTop(),
592			    appendOffset = container.offset();
593
594			var parentsZindex = [0];
595			this.element.parents().each(function () {
596				var itemZIndex = $(this).css('z-index');
597				if (itemZIndex !== 'auto' && Number(itemZIndex) !== 0) parentsZindex.push(Number(itemZIndex));
598			});
599			var zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset;
600			var offset = this.component ? this.component.parent().offset() : this.element.offset();
601			var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);
602			var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);
603			var left = offset.left - appendOffset.left;
604			var top = offset.top - appendOffset.top;
605
606			if (this.o.container !== 'body') {
607				top += scrollTop;
608			}
609
610			this.picker.removeClass('datepicker-orient-top datepicker-orient-bottom ' + 'datepicker-orient-right datepicker-orient-left');
611
612			if (this.o.orientation.x !== 'auto') {
613				this.picker.addClass('datepicker-orient-' + this.o.orientation.x);
614				if (this.o.orientation.x === 'right') left -= calendarWidth - width;
615			}
616			else {
617					if (offset.left < 0) {
618						this.picker.addClass('datepicker-orient-left');
619						left -= offset.left - visualPadding;
620					} else if (left + calendarWidth > windowWidth) {
621						this.picker.addClass('datepicker-orient-right');
622						left += width - calendarWidth;
623					} else {
624						if (this.o.rtl) {
625							this.picker.addClass('datepicker-orient-right');
626						} else {
627							this.picker.addClass('datepicker-orient-left');
628						}
629					}
630				}
631
632			var yorient = this.o.orientation.y,
633			    top_overflow;
634			if (yorient === 'auto') {
635				top_overflow = -scrollTop + top - calendarHeight;
636				yorient = top_overflow < 0 ? 'bottom' : 'top';
637			}
638
639			this.picker.addClass('datepicker-orient-' + yorient);
640			if (yorient === 'top') top -= calendarHeight + parseInt(this.picker.css('padding-top'));else top += height;
641
642			if (this.o.rtl) {
643				var right = windowWidth - (left + width);
644				this.picker.css({
645					top: top,
646					right: right,
647					zIndex: zIndex
648				});
649			} else {
650				this.picker.css({
651					top: top,
652					left: left,
653					zIndex: zIndex
654				});
655			}
656			return this;
657		},
658
659		_allow_update: true,
660		update: function update() {
661			if (!this._allow_update) return this;
662
663			var oldDates = this.dates.copy(),
664			    dates = [],
665			    fromArgs = false;
666			if (arguments.length) {
667				$.each(arguments, $.proxy(function (i, date) {
668					if (date instanceof Date) date = this._local_to_utc(date);
669					dates.push(date);
670				}, this));
671				fromArgs = true;
672			} else {
673				dates = this.isInput ? this.element.val() : this.element.data('date') || this.inputField.val();
674				if (dates && this.o.multidate) dates = dates.split(this.o.multidateSeparator);else dates = [dates];
675				delete this.element.data().date;
676			}
677
678			dates = $.map(dates, $.proxy(function (date) {
679				return DPGlobal.parseDate(date, this.o.format, this.o.language, this.o.assumeNearbyYear);
680			}, this));
681			dates = $.grep(dates, $.proxy(function (date) {
682				return !this.dateWithinRange(date) || !date;
683			}, this), true);
684			this.dates.replace(dates);
685
686			if (this.o.updateViewDate) {
687				if (this.dates.length) this.viewDate = new Date(this.dates.get(-1));else if (this.viewDate < this.o.startDate) this.viewDate = new Date(this.o.startDate);else if (this.viewDate > this.o.endDate) this.viewDate = new Date(this.o.endDate);else this.viewDate = this.o.defaultViewDate;
688			}
689
690			if (fromArgs) {
691				this.setValue();
692				this.element.change();
693			} else if (this.dates.length) {
694				if (String(oldDates) !== String(this.dates) && fromArgs) {
695					this._trigger('changeDate');
696					this.element.change();
697				}
698			}
699			if (!this.dates.length && oldDates.length) {
700				this._trigger('clearDate');
701				this.element.change();
702			}
703
704			this.fill();
705			return this;
706		},
707
708		fillDow: function fillDow() {
709			if (this.o.showWeekDays) {
710				var dowCnt = this.o.weekStart,
711				    html = '<tr>';
712				if (this.o.calendarWeeks) {
713					html += '<th class="cw">&#160;</th>';
714				}
715				while (dowCnt < this.o.weekStart + 7) {
716					html += '<th class="dow';
717					if ($.inArray(dowCnt, this.o.daysOfWeekDisabled) !== -1) html += ' disabled';
718					html += '">' + dates[this.o.language].daysMin[dowCnt++ % 7] + '</th>';
719				}
720				html += '</tr>';
721				this.picker.find('.datepicker-days thead').append(html);
722			}
723		},
724
725		fillMonths: function fillMonths() {
726			var localDate = this._utc_to_local(this.viewDate);
727			var html = '';
728			var focused;
729			for (var i = 0; i < 12; i++) {
730				focused = localDate && localDate.getMonth() === i ? ' focused' : '';
731				html += '<span class="month' + focused + '">' + dates[this.o.language].monthsShort[i] + '</span>';
732			}
733			this.picker.find('.datepicker-months td').html(html);
734		},
735
736		setRange: function setRange(range) {
737			if (!range || !range.length) delete this.range;else this.range = $.map(range, function (d) {
738				return d.valueOf();
739			});
740			this.fill();
741		},
742
743		getClassNames: function getClassNames(date) {
744			var cls = [],
745			    year = this.viewDate.getUTCFullYear(),
746			    month = this.viewDate.getUTCMonth(),
747			    today = UTCToday();
748			if (date.getUTCFullYear() < year || date.getUTCFullYear() === year && date.getUTCMonth() < month) {
749				cls.push('old');
750			} else if (date.getUTCFullYear() > year || date.getUTCFullYear() === year && date.getUTCMonth() > month) {
751				cls.push('new');
752			}
753			if (this.focusDate && date.valueOf() === this.focusDate.valueOf()) cls.push('focused');
754			if (this.o.todayHighlight && isUTCEquals(date, today)) {
755				cls.push('today');
756			}
757			if (this.dates.contains(date) !== -1) cls.push('active');
758			if (!this.dateWithinRange(date)) {
759				cls.push('disabled');
760			}
761			if (this.dateIsDisabled(date)) {
762				cls.push('disabled', 'disabled-date');
763			}
764			if ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1) {
765				cls.push('highlighted');
766			}
767
768			if (this.range) {
769				if (date > this.range[0] && date < this.range[this.range.length - 1]) {
770					cls.push('range');
771				}
772				if ($.inArray(date.valueOf(), this.range) !== -1) {
773					cls.push('selected');
774				}
775				if (date.valueOf() === this.range[0]) {
776					cls.push('range-start');
777				}
778				if (date.valueOf() === this.range[this.range.length - 1]) {
779					cls.push('range-end');
780				}
781			}
782			return cls;
783		},
784
785		_fill_yearsView: function _fill_yearsView(selector, cssClass, factor, year, startYear, endYear, beforeFn) {
786			var html = '';
787			var step = factor / 10;
788			var view = this.picker.find(selector);
789			var startVal = Math.floor(year / factor) * factor;
790			var endVal = startVal + step * 9;
791			var focusedVal = Math.floor(this.viewDate.getFullYear() / step) * step;
792			var selected = $.map(this.dates, function (d) {
793				return Math.floor(d.getUTCFullYear() / step) * step;
794			});
795
796			var classes, tooltip, before;
797			for (var currVal = startVal - step; currVal <= endVal + step; currVal += step) {
798				classes = [cssClass];
799				tooltip = null;
800
801				if (currVal === startVal - step) {
802					classes.push('old');
803				} else if (currVal === endVal + step) {
804					classes.push('new');
805				}
806				if ($.inArray(currVal, selected) !== -1) {
807					classes.push('active');
808				}
809				if (currVal < startYear || currVal > endYear) {
810					classes.push('disabled');
811				}
812				if (currVal === focusedVal) {
813					classes.push('focused');
814				}
815
816				if (beforeFn !== $.noop) {
817					before = beforeFn(new Date(currVal, 0, 1));
818					if (before === undefined) {
819						before = {};
820					} else if (typeof before === 'boolean') {
821						before = { enabled: before };
822					} else if (typeof before === 'string') {
823						before = { classes: before };
824					}
825					if (before.enabled === false) {
826						classes.push('disabled');
827					}
828					if (before.classes) {
829						classes = classes.concat(before.classes.split(/\s+/));
830					}
831					if (before.tooltip) {
832						tooltip = before.tooltip;
833					}
834				}
835
836				html += '<span class="' + classes.join(' ') + '"' + (tooltip ? ' title="' + tooltip + '"' : '') + '>' + currVal + '</span>';
837			}
838
839			view.find('.datepicker-switch').text(startVal + '-' + endVal);
840			view.find('td').html(html);
841		},
842
843		fill: function fill() {
844			var d = new Date(this.viewDate),
845			    year = d.getUTCFullYear(),
846			    month = d.getUTCMonth(),
847			    startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
848			    startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
849			    endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
850			    endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
851			    todaytxt = dates[this.o.language].today || dates['en'].today || '',
852			    cleartxt = dates[this.o.language].clear || dates['en'].clear || '',
853			    titleFormat = dates[this.o.language].titleFormat || dates['en'].titleFormat,
854			    todayDate = UTCToday(),
855			    titleBtnVisible = (this.o.todayBtn === true || this.o.todayBtn === 'linked') && todayDate >= this.o.startDate && todayDate <= this.o.endDate && !this.weekOfDateIsDisabled(todayDate),
856			    tooltip,
857			    before;
858			if (isNaN(year) || isNaN(month)) return;
859			this.picker.find('.datepicker-days .datepicker-switch').text(DPGlobal.formatDate(d, titleFormat, this.o.language));
860			this.picker.find('tfoot .today').text(todaytxt).css('display', titleBtnVisible ? 'table-cell' : 'none');
861			this.picker.find('tfoot .clear').text(cleartxt).css('display', this.o.clearBtn === true ? 'table-cell' : 'none');
862			this.picker.find('thead .datepicker-title').text(this.o.title).css('display', typeof this.o.title === 'string' && this.o.title !== '' ? 'table-cell' : 'none');
863			this.updateNavArrows();
864			this.fillMonths();
865			var prevMonth = UTCDate(year, month, 0),
866			    day = prevMonth.getUTCDate();
867			prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7) % 7);
868			var nextMonth = new Date(prevMonth);
869			if (prevMonth.getUTCFullYear() < 100) {
870				nextMonth.setUTCFullYear(prevMonth.getUTCFullYear());
871			}
872			nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
873			nextMonth = nextMonth.valueOf();
874			var html = [];
875			var weekDay, clsName;
876			while (prevMonth.valueOf() < nextMonth) {
877				weekDay = prevMonth.getUTCDay();
878				if (weekDay === this.o.weekStart) {
879					html.push('<tr>');
880					if (this.o.calendarWeeks) {
881						var
882						ws = new Date(+prevMonth + (this.o.weekStart - weekDay - 7) % 7 * 864e5),
883
884						th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
885
886						yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay()) % 7 * 864e5),
887
888						calWeek = (th - yth) / 864e5 / 7 + 1;
889						html.push('<td class="cw">' + calWeek + '</td>');
890					}
891				}
892				clsName = this.getClassNames(prevMonth);
893				clsName.push('day');
894
895				var content = prevMonth.getUTCDate();
896
897				if (this.o.beforeShowDay !== $.noop) {
898					before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
899					if (before === undefined) before = {};else if (typeof before === 'boolean') before = { enabled: before };else if (typeof before === 'string') before = { classes: before };
900					if (before.enabled === false) clsName.push('disabled');
901					if (before.classes) clsName = clsName.concat(before.classes.split(/\s+/));
902					if (before.tooltip) tooltip = before.tooltip;
903					if (before.content) content = before.content;
904				}
905
906				if ($.isFunction($.uniqueSort)) {
907					clsName = $.uniqueSort(clsName);
908				} else {
909					clsName = $.unique(clsName);
910				}
911
912				html.push('<td class="' + clsName.join(' ') + '"' + (tooltip ? ' title="' + tooltip + '"' : '') + ' data-date="' + prevMonth.getTime().toString() + '">' + content + '</td>');
913				tooltip = null;
914				if (weekDay === this.o.weekEnd) {
915					html.push('</tr>');
916				}
917				prevMonth.setUTCDate(prevMonth.getUTCDate() + 1);
918			}
919			this.picker.find('.datepicker-days tbody').html(html.join(''));
920
921			var monthsTitle = dates[this.o.language].monthsTitle || dates['en'].monthsTitle || 'Months';
922			var months = this.picker.find('.datepicker-months').find('.datepicker-switch').text(this.o.maxViewMode < 2 ? monthsTitle : year).end().find('tbody span').removeClass('active');
923
924			$.each(this.dates, function (i, d) {
925				if (d.getUTCFullYear() === year) months.eq(d.getUTCMonth()).addClass('active');
926			});
927
928			if (year < startYear || year > endYear) {
929				months.addClass('disabled');
930			}
931			if (year === startYear) {
932				months.slice(0, startMonth).addClass('disabled');
933			}
934			if (year === endYear) {
935				months.slice(endMonth + 1).addClass('disabled');
936			}
937
938			if (this.o.beforeShowMonth !== $.noop) {
939				var that = this;
940				$.each(months, function (i, month) {
941					var moDate = new Date(year, i, 1);
942					var before = that.o.beforeShowMonth(moDate);
943					if (before === undefined) before = {};else if (typeof before === 'boolean') before = { enabled: before };else if (typeof before === 'string') before = { classes: before };
944					if (before.enabled === false && !$(month).hasClass('disabled')) $(month).addClass('disabled');
945					if (before.classes) $(month).addClass(before.classes);
946					if (before.tooltip) $(month).prop('title', before.tooltip);
947				});
948			}
949
950			this._fill_yearsView('.datepicker-years', 'year', 10, year, startYear, endYear, this.o.beforeShowYear);
951
952			this._fill_yearsView('.datepicker-decades', 'decade', 100, year, startYear, endYear, this.o.beforeShowDecade);
953
954			this._fill_yearsView('.datepicker-centuries', 'century', 1000, year, startYear, endYear, this.o.beforeShowCentury);
955		},
956
957		updateNavArrows: function updateNavArrows() {
958			if (!this._allow_update) return;
959
960			var d = new Date(this.viewDate),
961			    year = d.getUTCFullYear(),
962			    month = d.getUTCMonth(),
963			    startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
964			    startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
965			    endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
966			    endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
967			    prevIsDisabled,
968			    nextIsDisabled,
969			    factor = 1;
970			switch (this.viewMode) {
971				case 4:
972					factor *= 10;
973				case 3:
974					factor *= 10;
975				case 2:
976					factor *= 10;
977				case 1:
978					prevIsDisabled = Math.floor(year / factor) * factor <= startYear;
979					nextIsDisabled = Math.floor(year / factor) * factor + factor > endYear;
980					break;
981				case 0:
982					prevIsDisabled = year <= startYear && month <= startMonth;
983					nextIsDisabled = year >= endYear && month >= endMonth;
984					break;
985			}
986
987			this.picker.find('.prev').toggleClass('disabled', prevIsDisabled);
988			this.picker.find('.next').toggleClass('disabled', nextIsDisabled);
989		},
990
991		click: function click(e) {
992			e.preventDefault();
993			e.stopPropagation();
994
995			var target, dir, day, year, month;
996			target = $(e.target);
997
998			if (target.hasClass('datepicker-switch') && this.viewMode !== this.o.maxViewMode) {
999				this.setViewMode(this.viewMode + 1);
1000			}
1001
1002			if (target.hasClass('today') && !target.hasClass('day')) {
1003				this.setViewMode(0);
1004				this._setDate(UTCToday(), this.o.todayBtn === 'linked' ? null : 'view');
1005			}
1006
1007			if (target.hasClass('clear')) {
1008				this.clearDates();
1009			}
1010
1011			if (!target.hasClass('disabled')) {
1012				if (target.hasClass('month') || target.hasClass('year') || target.hasClass('decade') || target.hasClass('century')) {
1013					this.viewDate.setUTCDate(1);
1014
1015					day = 1;
1016					if (this.viewMode === 1) {
1017						month = target.parent().find('span').index(target);
1018						year = this.viewDate.getUTCFullYear();
1019						this.viewDate.setUTCMonth(month);
1020					} else {
1021						month = 0;
1022						year = Number(target.text());
1023						this.viewDate.setUTCFullYear(year);
1024					}
1025
1026					this._trigger(DPGlobal.viewModes[this.viewMode - 1].e, this.viewDate);
1027
1028					if (this.viewMode === this.o.minViewMode) {
1029						this._setDate(UTCDate(year, month, day));
1030					} else {
1031						this.setViewMode(this.viewMode - 1);
1032						this.fill();
1033					}
1034				}
1035			}
1036
1037			if (this.picker.is(':visible') && this._focused_from) {
1038				this._focused_from.focus();
1039			}
1040			delete this._focused_from;
1041		},
1042
1043		dayCellClick: function dayCellClick(e) {
1044			var $target = $(e.currentTarget);
1045			var timestamp = $target.data('date');
1046			var date = new Date(timestamp);
1047
1048			if (this.o.updateViewDate) {
1049				if (date.getUTCFullYear() !== this.viewDate.getUTCFullYear()) {
1050					this._trigger('changeYear', this.viewDate);
1051				}
1052
1053				if (date.getUTCMonth() !== this.viewDate.getUTCMonth()) {
1054					this._trigger('changeMonth', this.viewDate);
1055				}
1056			}
1057			this._setDate(date);
1058		},
1059
1060		navArrowsClick: function navArrowsClick(e) {
1061			var $target = $(e.currentTarget);
1062			var dir = $target.hasClass('prev') ? -1 : 1;
1063			if (this.viewMode !== 0) {
1064				dir *= DPGlobal.viewModes[this.viewMode].navStep * 12;
1065			}
1066			this.viewDate = this.moveMonth(this.viewDate, dir);
1067			this._trigger(DPGlobal.viewModes[this.viewMode].e, this.viewDate);
1068			this.fill();
1069		},
1070
1071		_toggle_multidate: function _toggle_multidate(date) {
1072			var ix = this.dates.contains(date);
1073			if (!date) {
1074				this.dates.clear();
1075			}
1076
1077			if (ix !== -1) {
1078				if (this.o.multidate === true || this.o.multidate > 1 || this.o.toggleActive) {
1079					this.dates.remove(ix);
1080				}
1081			} else if (this.o.multidate === false) {
1082				this.dates.clear();
1083				this.dates.push(date);
1084			} else {
1085				this.dates.push(date);
1086			}
1087
1088			if (typeof this.o.multidate === 'number') while (this.dates.length > this.o.multidate) {
1089				this.dates.remove(0);
1090			}
1091		},
1092
1093		_setDate: function _setDate(date, which) {
1094			if (!which || which === 'date') this._toggle_multidate(date && new Date(date));
1095			if (!which && this.o.updateViewDate || which === 'view') this.viewDate = date && new Date(date);
1096
1097			this.fill();
1098			this.setValue();
1099			if (!which || which !== 'view') {
1100				this._trigger('changeDate');
1101			}
1102			this.inputField.trigger('change');
1103			if (this.o.autoclose && (!which || which === 'date')) {
1104				this.hide();
1105			}
1106		},
1107
1108		moveDay: function moveDay(date, dir) {
1109			var newDate = new Date(date);
1110			newDate.setUTCDate(date.getUTCDate() + dir);
1111
1112			return newDate;
1113		},
1114
1115		moveWeek: function moveWeek(date, dir) {
1116			return this.moveDay(date, dir * 7);
1117		},
1118
1119		moveMonth: function moveMonth(date, dir) {
1120			if (!isValidDate(date)) return this.o.defaultViewDate;
1121			if (!dir) return date;
1122			var new_date = new Date(date.valueOf()),
1123			    day = new_date.getUTCDate(),
1124			    month = new_date.getUTCMonth(),
1125			    mag = Math.abs(dir),
1126			    new_month,
1127			    test;
1128			dir = dir > 0 ? 1 : -1;
1129			if (mag === 1) {
1130				test = dir === -1
1131				? function () {
1132					return new_date.getUTCMonth() === month;
1133				}
1134				: function () {
1135					return new_date.getUTCMonth() !== new_month;
1136				};
1137				new_month = month + dir;
1138				new_date.setUTCMonth(new_month);
1139				new_month = (new_month + 12) % 12;
1140			} else {
1141				for (var i = 0; i < mag; i++) {
1142					new_date = this.moveMonth(new_date, dir);
1143				} 
1144				new_month = new_date.getUTCMonth();
1145				new_date.setUTCDate(day);
1146				test = function test() {
1147					return new_month !== new_date.getUTCMonth();
1148				};
1149			}
1150			while (test()) {
1151				new_date.setUTCDate(--day);
1152				new_date.setUTCMonth(new_month);
1153			}
1154			return new_date;
1155		},
1156
1157		moveYear: function moveYear(date, dir) {
1158			return this.moveMonth(date, dir * 12);
1159		},
1160
1161		moveAvailableDate: function moveAvailableDate(date, dir, fn) {
1162			do {
1163				date = this[fn](date, dir);
1164
1165				if (!this.dateWithinRange(date)) return false;
1166
1167				fn = 'moveDay';
1168			} while (this.dateIsDisabled(date));
1169
1170			return date;
1171		},
1172
1173		weekOfDateIsDisabled: function weekOfDateIsDisabled(date) {
1174			return $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1;
1175		},
1176
1177		dateIsDisabled: function dateIsDisabled(date) {
1178			return this.weekOfDateIsDisabled(date) || $.grep(this.o.datesDisabled, function (d) {
1179				return isUTCEquals(date, d);
1180			}).length > 0;
1181		},
1182
1183		dateWithinRange: function dateWithinRange(date) {
1184			return date >= this.o.startDate && date <= this.o.endDate;
1185		},
1186
1187		keydown: function keydown(e) {
1188			if (!this.picker.is(':visible')) {
1189				if (e.keyCode === 40 || e.keyCode === 27) {
1190					this.show();
1191					e.stopPropagation();
1192				}
1193				return;
1194			}
1195			var dateChanged = false,
1196			    dir,
1197			    newViewDate,
1198			    focusDate = this.focusDate || this.viewDate;
1199			switch (e.keyCode) {
1200				case 27:
1201					if (this.focusDate) {
1202						this.focusDate = null;
1203						this.viewDate = this.dates.get(-1) || this.viewDate;
1204						this.fill();
1205					} else this.hide();
1206					e.preventDefault();
1207					e.stopPropagation();
1208					break;
1209				case 37: 
1210				case 38: 
1211				case 39: 
1212				case 40:
1213					if (!this.o.keyboardNavigation || this.o.daysOfWeekDisabled.length === 7) break;
1214					dir = e.keyCode === 37 || e.keyCode === 38 ? -1 : 1;
1215					if (this.viewMode === 0) {
1216						if (e.ctrlKey) {
1217							newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');
1218
1219							if (newViewDate) this._trigger('changeYear', this.viewDate);
1220						} else if (e.shiftKey) {
1221							newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');
1222
1223							if (newViewDate) this._trigger('changeMonth', this.viewDate);
1224						} else if (e.keyCode === 37 || e.keyCode === 39) {
1225							newViewDate = this.moveAvailableDate(focusDate, dir, 'moveDay');
1226						} else if (!this.weekOfDateIsDisabled(focusDate)) {
1227							newViewDate = this.moveAvailableDate(focusDate, dir, 'moveWeek');
1228						}
1229					} else if (this.viewMode === 1) {
1230						if (e.keyCode === 38 || e.keyCode === 40) {
1231							dir = dir * 4;
1232						}
1233						newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');
1234					} else if (this.viewMode === 2) {
1235						if (e.keyCode === 38 || e.keyCode === 40) {
1236							dir = dir * 4;
1237						}
1238						newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');
1239					}
1240					if (newViewDate) {
1241						this.focusDate = this.viewDate = newViewDate;
1242						this.setValue();
1243						this.fill();
1244						e.preventDefault();
1245					}
1246					break;
1247				case 13:
1248					if (!this.o.forceParse) break;
1249					focusDate = this.focusDate || this.dates.get(-1) || this.viewDate;
1250					if (this.o.keyboardNavigation) {
1251						this._toggle_multidate(focusDate);
1252						dateChanged = true;
1253					}
1254					this.focusDate = null;
1255					this.viewDate = this.dates.get(-1) || this.viewDate;
1256					this.setValue();
1257					this.fill();
1258					if (this.picker.is(':visible')) {
1259						e.preventDefault();
1260						e.stopPropagation();
1261						if (this.o.autoclose) this.hide();
1262					}
1263					break;
1264				case 9:
1265					this.focusDate = null;
1266					this.viewDate = this.dates.get(-1) || this.viewDate;
1267					this.fill();
1268					this.hide();
1269					break;
1270			}
1271			if (dateChanged) {
1272				if (this.dates.length) this._trigger('changeDate');else this._trigger('clearDate');
1273				this.inputField.trigger('change');
1274			}
1275		},
1276
1277		setViewMode: function setViewMode(viewMode) {
1278			this.viewMode = viewMode;
1279			this.picker.children('div').hide().filter('.datepicker-' + DPGlobal.viewModes[this.viewMode].clsName).show();
1280			this.updateNavArrows();
1281			this._trigger('changeViewMode', new Date(this.viewDate));
1282		}
1283	};
1284
1285	var DateRangePicker = function DateRangePicker(element, options) {
1286		$.data(element, 'datepicker', this);
1287		this.element = $(element);
1288		this.inputs = $.map(options.inputs, function (i) {
1289			return i.jquery ? i[0] : i;
1290		});
1291		delete options.inputs;
1292
1293		this.keepEmptyValues = options.keepEmptyValues;
1294		delete options.keepEmptyValues;
1295
1296		datepickerPlugin.call($(this.inputs), options).on('changeDate', $.proxy(this.dateUpdated, this));
1297
1298		this.pickers = $.map(this.inputs, function (i) {
1299			return $.data(i, 'datepicker');
1300		});
1301		this.updateDates();
1302	};
1303	DateRangePicker.prototype = {
1304		updateDates: function updateDates() {
1305			this.dates = $.map(this.pickers, function (i) {
1306				return i.getUTCDate();
1307			});
1308			this.updateRanges();
1309		},
1310		updateRanges: function updateRanges() {
1311			var range = $.map(this.dates, function (d) {
1312				return d.valueOf();
1313			});
1314			$.each(this.pickers, function (i, p) {
1315				p.setRange(range);
1316			});
1317		},
1318		clearDates: function clearDates() {
1319			$.each(this.pickers, function (i, p) {
1320				p.clearDates();
1321			});
1322		},
1323		dateUpdated: function dateUpdated(e) {
1324			if (this.updating) return;
1325			this.updating = true;
1326
1327			var dp = $.data(e.target, 'datepicker');
1328
1329			if (dp === undefined) {
1330				return;
1331			}
1332
1333			var new_date = dp.getUTCDate(),
1334			    keep_empty_values = this.keepEmptyValues,
1335			    i = $.inArray(e.target, this.inputs),
1336			    j = i - 1,
1337			    k = i + 1,
1338			    l = this.inputs.length;
1339			if (i === -1) return;
1340
1341			$.each(this.pickers, function (i, p) {
1342				if (!p.getUTCDate() && (p === dp || !keep_empty_values)) p.setUTCDate(new_date);
1343			});
1344
1345			if (new_date < this.dates[j]) {
1346				while (j >= 0 && new_date < this.dates[j]) {
1347					this.pickers[j--].setUTCDate(new_date);
1348				}
1349			} else if (new_date > this.dates[k]) {
1350				while (k < l && new_date > this.dates[k]) {
1351					this.pickers[k++].setUTCDate(new_date);
1352				}
1353			}
1354			this.updateDates();
1355
1356			delete this.updating;
1357		},
1358		destroy: function destroy() {
1359			$.map(this.pickers, function (p) {
1360				p.destroy();
1361			});
1362			$(this.inputs).off('changeDate', this.dateUpdated);
1363			delete this.element.data().datepicker;
1364		},
1365		remove: alias('destroy', 'Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead')
1366	};
1367
1368	function opts_from_el(el, prefix) {
1369		var data = $(el).data(),
1370		    out = {},
1371		    inkey,
1372		    replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])');
1373		prefix = new RegExp('^' + prefix.toLowerCase());
1374		function re_lower(_, a) {
1375			return a.toLowerCase();
1376		}
1377		for (var key in data) {
1378			if (prefix.test(key)) {
1379				inkey = key.replace(replace, re_lower);
1380				out[inkey] = data[key];
1381			}
1382		}return out;
1383	}
1384
1385	function opts_from_locale(lang) {
1386		var out = {};
1387		if (!dates[lang]) {
1388			lang = lang.split('-')[0];
1389			if (!dates[lang]) return;
1390		}
1391		var d = dates[lang];
1392		$.each(locale_opts, function (i, k) {
1393			if (k in d) out[k] = d[k];
1394		});
1395		return out;
1396	}
1397
1398	var old = $.fn.datepicker;
1399	var datepickerPlugin = function datepickerPlugin(option) {
1400		var args = Array.apply(null, arguments);
1401		args.shift();
1402		var internal_return;
1403		this.each(function () {
1404			var $this = $(this),
1405			    data = $this.data('datepicker'),
1406			    options = (typeof option === 'undefined' ? 'undefined' : _typeof(option)) === 'object' && option;
1407			if (!data) {
1408				var elopts = opts_from_el(this, 'date'),
1409
1410				xopts = $.extend({}, defaults, elopts, options),
1411				    locopts = opts_from_locale(xopts.language),
1412
1413				opts = $.extend({}, defaults, locopts, elopts, options);
1414				if ($this.hasClass('input-daterange') || opts.inputs) {
1415					$.extend(opts, {
1416						inputs: opts.inputs || $this.find('input').toArray()
1417					});
1418					data = new DateRangePicker(this, opts);
1419				} else {
1420					data = new Datepicker(this, opts);
1421				}
1422				$this.data('datepicker', data);
1423			}
1424			if (typeof option === 'string' && typeof data[option] === 'function') {
1425				internal_return = data[option].apply(data, args);
1426			}
1427		});
1428
1429		if (internal_return === undefined || internal_return instanceof Datepicker || internal_return instanceof DateRangePicker) return this;
1430
1431		if (this.length > 1) throw new Error('Using only allowed for the collection of a single element (' + option + ' function)');else return internal_return;
1432	};
1433	$.fn.datepicker = datepickerPlugin;
1434
1435	var defaults = $.fn.datepicker.defaults = {
1436		assumeNearbyYear: false,
1437		autoclose: false,
1438		beforeShowDay: $.noop,
1439		beforeShowMonth: $.noop,
1440		beforeShowYear: $.noop,
1441		beforeShowDecade: $.noop,
1442		beforeShowCentury: $.noop,
1443		calendarWeeks: false,
1444		clearBtn: false,
1445		toggleActive: false,
1446		daysOfWeekDisabled: [],
1447		daysOfWeekHighlighted: [],
1448		datesDisabled: [],
1449		endDate: Infinity,
1450		forceParse: true,
1451		format: 'mm/dd/yyyy',
1452		keepEmptyValues: false,
1453		keyboardNavigation: true,
1454		language: 'en',
1455		minViewMode: 0,
1456		maxViewMode: 4,
1457		multidate: false,
1458		multidateSeparator: ',',
1459		orientation: "auto",
1460		rtl: false,
1461		startDate: -Infinity,
1462		startView: 0,
1463		todayBtn: false,
1464		todayHighlight: false,
1465		updateViewDate: true,
1466		weekStart: 0,
1467		disableTouchKeyboard: false,
1468		enableOnReadonly: true,
1469		showOnFocus: true,
1470		zIndexOffset: 10,
1471		container: 'body',
1472		immediateUpdates: false,
1473		title: '',
1474		templates: {
1475			leftArrow: '&#x00AB;',
1476			rightArrow: '&#x00BB;'
1477		},
1478		showWeekDays: true
1479	};
1480	var locale_opts = $.fn.datepicker.locale_opts = ['format', 'rtl', 'weekStart'];
1481	$.fn.datepicker.Constructor = Datepicker;
1482	var dates = $.fn.datepicker.dates = {
1483		en: {
1484			days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
1485			daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
1486			daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
1487			months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
1488			monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
1489			today: "Today",
1490			clear: "Clear",
1491			titleFormat: "MM yyyy"
1492		}
1493	};
1494
1495	var DPGlobal = {
1496		viewModes: [{
1497			names: ['days', 'month'],
1498			clsName: 'days',
1499			e: 'changeMonth'
1500		}, {
1501			names: ['months', 'year'],
1502			clsName: 'months',
1503			e: 'changeYear',
1504			navStep: 1
1505		}, {
1506			names: ['years', 'decade'],
1507			clsName: 'years',
1508			e: 'changeDecade',
1509			navStep: 10
1510		}, {
1511			names: ['decades', 'century'],
1512			clsName: 'decades',
1513			e: 'changeCentury',
1514			navStep: 100
1515		}, {
1516			names: ['centuries', 'millennium'],
1517			clsName: 'centuries',
1518			e: 'changeMillennium',
1519			navStep: 1000
1520		}],
1521		validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
1522		nonpunctuation: /[^ -\/:-@\u5e74\u6708\u65e5\[-`{-~\t\n\r]+/g,
1523		parseFormat: function parseFormat(format) {
1524			if (typeof format.toValue === 'function' && typeof format.toDisplay === 'function') return format;
1525			var separators = format.replace(this.validParts, '\0').split('\0'),
1526			    parts = format.match(this.validParts);
1527			if (!separators || !separators.length || !parts || parts.length === 0) {
1528				throw new Error("Invalid date format.");
1529			}
1530			return { separators: separators, parts: parts };
1531		},
1532		parseDate: function parseDate(date, format, language, assumeNearby) {
1533			if (!date) return undefined;
1534			if (date instanceof Date) return date;
1535			if (typeof format === 'string') format = DPGlobal.parseFormat(format);
1536			if (format.toValue) return format.toValue(date, format, language);
1537			var fn_map = {
1538				d: 'moveDay',
1539				m: 'moveMonth',
1540				w: 'moveWeek',
1541				y: 'moveYear'
1542			},
1543			    dateAliases = {
1544				yesterday: '-1d',
1545				today: '+0d',
1546				tomorrow: '+1d'
1547			},
1548			    parts,
1549			    part,
1550			    dir,
1551			    i,
1552			    fn;
1553			if (date in dateAliases) {
1554				date = dateAliases[date];
1555			}
1556			if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/i.test(date)) {
1557				parts = date.match(/([\-+]\d+)([dmwy])/gi);
1558				date = new Date();
1559				for (i = 0; i < parts.length; i++) {
1560					part = parts[i].match(/([\-+]\d+)([dmwy])/i);
1561					dir = Number(part[1]);
1562					fn = fn_map[part[2].toLowerCase()];
1563					date = Datepicker.prototype[fn](date, dir);
1564				}
1565				return Datepicker.prototype._zero_utc_time(date);
1566			}
1567
1568			parts = date && date.match(this.nonpunctuation) || [];
1569
1570			function applyNearbyYear(year, threshold) {
1571				if (threshold === true) threshold = 10;
1572
1573				if (year < 100) {
1574					year += 2000;
1575					if (year > new Date().getFullYear() + threshold) {
1576						year -= 100;
1577					}
1578				}
1579
1580				return year;
1581			}
1582
1583			var parsed = {},
1584			    setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
1585			    setters_map = {
1586				yyyy: function yyyy(d, v) {
1587					return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
1588				},
1589				m: function m(d, v) {
1590					if (isNaN(d)) return d;
1591					v -= 1;
1592					while (v < 0) {
1593						v += 12;
1594					}v %= 12;
1595					d.setUTCMonth(v);
1596					while (d.getUTCMonth() !== v) {
1597						d.setUTCDate(d.getUTCDate() - 1);
1598					}return d;
1599				},
1600				d: function d(_d, v) {
1601					return _d.setUTCDate(v);
1602				}
1603			},
1604			    val,
1605			    filtered;
1606			setters_map['yy'] = setters_map['yyyy'];
1607			setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
1608			setters_map['dd'] = setters_map['d'];
1609			date = UTCToday();
1610			var fparts = format.parts.slice();
1611			if (parts.length !== fparts.length) {
1612				fparts = $(fparts).filter(function (i, p) {
1613					return $.inArray(p, setters_order) !== -1;
1614				}).toArray();
1615			}
1616			function match_part() {
1617				var m = this.slice(0, parts[i].length),
1618				    p = parts[i].slice(0, m.length);
1619				return m.toLowerCase() === p.toLowerCase();
1620			}
1621			if (parts.length === fparts.length) {
1622				var cnt;
1623				for (i = 0, cnt = fparts.length; i < cnt; i++) {
1624					val = parseInt(parts[i], 10);
1625					part = fparts[i];
1626					if (isNaN(val)) {
1627						switch (part) {
1628							case 'MM':
1629								filtered = $(dates[language].months).filter(match_part);
1630								val = $.inArray(filtered[0], dates[language].months) + 1;
1631								break;
1632							case 'M':
1633								filtered = $(dates[language].monthsShort).filter(match_part);
1634								val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
1635								break;
1636						}
1637					}
1638					parsed[part] = val;
1639				}
1640				var _date, s;
1641				for (i = 0; i < setters_order.length; i++) {
1642					s = setters_order[i];
1643					if (s in parsed && !isNaN(parsed[s])) {
1644						_date = new Date(date);
1645						setters_map[s](_date, parsed[s]);
1646						if (!isNaN(_date)) date = _date;
1647					}
1648				}
1649			}
1650			return date;
1651		},
1652		formatDate: function formatDate(date, format, language) {
1653			if (!date) return '';
1654			if (typeof format === 'string') format = DPGlobal.parseFormat(format);
1655			if (format.toDisplay) return format.toDisplay(date, format, language);
1656			var val = {
1657				d: date.getUTCDate(),
1658				D: dates[language].daysShort[date.getUTCDay()],
1659				DD: dates[language].days[date.getUTCDay()],
1660				m: date.getUTCMonth() + 1,
1661				M: dates[language].monthsShort[date.getUTCMonth()],
1662				MM: dates[language].months[date.getUTCMonth()],
1663				yy: date.getUTCFullYear().toString().substring(2),
1664				yyyy: date.getUTCFullYear()
1665			};
1666			val.dd = (val.d < 10 ? '0' : '') + val.d;
1667			val.mm = (val.m < 10 ? '0' : '') + val.m;
1668			date = [];
1669			var seps = $.extend([], format.separators);
1670			for (var i = 0, cnt = format.parts.length; i <= cnt; i++) {
1671				if (seps.length) date.push(seps.shift());
1672				date.push(val[format.parts[i]]);
1673			}
1674			return date.join('');
1675		},
1676		headTemplate: '<thead>' + '<tr>' + '<th colspan="7" class="datepicker-title"></th>' + '</tr>' + '<tr>' + '<th class="prev">' + defaults.templates.leftArrow + '</th>' + '<th colspan="5" class="datepicker-switch"></th>' + '<th class="next">' + defaults.templates.rightArrow + '</th>' + '</tr>' + '</thead>',
1677		contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
1678		footTemplate: '<tfoot>' + '<tr>' + '<th colspan="7" class="today"></th>' + '</tr>' + '<tr>' + '<th colspan="7" class="clear"></th>' + '</tr>' + '</tfoot>'
1679	};
1680	DPGlobal.template = '<div class="datepicker">' + '<div class="datepicker-days">' + '<table class="table-condensed">' + DPGlobal.headTemplate + '<tbody></tbody>' + DPGlobal.footTemplate + '</table>' + '</div>' + '<div class="datepicker-months">' + '<table class="table-condensed">' + DPGlobal.headTemplate + DPGlobal.contTemplate + DPGlobal.footTemplate + '</table>' + '</div>' + '<div class="datepicker-years">' + '<table class="table-condensed">' + DPGlobal.headTemplate + DPGlobal.contTemplate + DPGlobal.footTemplate + '</table>' + '</div>' + '<div class="datepicker-decades">' + '<table class="table-condensed">' + DPGlobal.headTemplate + DPGlobal.contTemplate + DPGlobal.footTemplate + '</table>' + '</div>' + '<div class="datepicker-centuries">' + '<table class="table-condensed">' + DPGlobal.headTemplate + DPGlobal.contTemplate + DPGlobal.footTemplate + '</table>' + '</div>' + '</div>';
1681
1682	$.fn.datepicker.DPGlobal = DPGlobal;
1683
1684
1685	$.fn.datepicker.noConflict = function () {
1686		$.fn.datepicker = old;
1687		return this;
1688	};
1689
1690	$.fn.datepicker.version = '1.9.0';
1691
1692	$.fn.datepicker.deprecated = function (msg) {
1693		var console = window.console;
1694		if (console && console.warn) {
1695			console.warn('DEPRECATED: ' + msg);
1696		}
1697	};
1698
1699
1700	$(document).on('focus.datepicker.data-api click.datepicker.data-api', '[data-
1700provide="datepicker"]', function (e) {
1701		var $this = $(this);
1702		if ($this.data('datepicker')) return;
1703		e.preventDefault();
1704		datepickerPlugin.call($this, 'show');
1705	});
1706	$(function () {
1707		datepickerPlugin.call($('[data-provide="datepicker-inline"]'));
1708	});
1709});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.