PageSourceSearch

https://www.cryptoseries.fr/components/com_b2jcontact/js/glDatePicker.js

js cryptoseries.fr collected 2026-10-02 03:39:24 UTC 25,882 bytes, 818 lines download raw bytes

1/*!
2 * glDatePicker v2.0
3 * http://glad.github.com/glDatePicker/
4 *
5 * Copyright (c) 2013 Gautam Lad.  All rights reserved.
6 * Released under the MIT license.
7 *
8 * Date: Tue Jan 1 2013
9 */
10 ;(function() {
11	jQuery.fn.glDatePicker = function(options) {
12		var pluginName = 'glDatePicker';
13
14		// Find the plugin attached to the element
15		var instance = this.data(pluginName);
16
17		// If the instance wasn't found, create it...
18		if(!instance) {
19			// Return the element being bound to
20			return this.each(function() {
21				return jQuery(this).data(pluginName, new glDatePicker(this, options));
22			});
23		}
24
25		// ...otherwise if the user passes true to the plugin (on the second call),
26		// then return the instance of the plugin itself
27		return (options === true) ? instance : this;
28	};
29
30	// Default options
31	jQuery.fn.glDatePicker.defaults =
32	{
33		// Style to use for the calendar.  This name must match the name used in
34		// the stylesheet, using the class naming convention "gldp-cssName".
35		cssName: 'default',
36
37		// The z-index for the calendar control.
38		zIndex: 1000,
39
40		// Thickness of border (in pixels)
41		borderSize: 1,
42
43		// The number of pixels to offset the calendar's position on the page.
44		calendarOffset: { x: 0, y: 1 },
45
46		// Set to true if you want the calendar to be visible at all times.
47		// NOTE: If your target element is hidden, the calendar will be hidden as well.
48		showAlways: false,
49
50		// Hide the calendar when a date is selected (only if showAlways is set to false).
51		hideOnClick: true,
52
53		// Allow selection of months by clicking on the month in the title.
54		allowMonthSelect: true,
55
56		// Allow selection of years by clicking on the year in the title.
57		allowYearSelect: true,
58
59		// The date that will be treated as 'today'.
60		todayDate: new Date(),
61
62		// The date that will appear selected when the calendar renders.
63		// By default it will be set to todayDate.
64		selectedDate: null,
65
66		// Arrows used for the Previous and Next month buttons on the title.
67		// Set these to blank to hide the arrows completely.
68		prevArrow: '\u25c4',
69		nextArrow: '\u25ba',
70
71		// A collection of dates that can be selectable by the user.
72		// The dates can be a one-time selection or made repeatable by setting
73		// the repeatYear or repeatMonth flag to true.
74		// By default repeatYear and repeatMonth are false.
75		//
76		// This example creates 4-individual dates that can be selected;
77		// The first date will repeat every year, the second date will repeat every
78		// month and year, the third date will repeat every month and the fourth date
79		// will only be selectable one-time and not repeat:
80		//
81		//    selectableDates: [
82		//        { date: new Date(0, 8, 5), repeatYear: true },
83		//        { date: new Date(0, 0, 14), repeatMonth: true, repeatYear: true },
84		//        { date: new Date(2013, 0, 24), repeatMonth: true },
85		//        { date: new Date(2013, 11, 25) },
86		//    ]
87		selectableDates: null,
88
89		// A collection of date ranges that are selectable by the user.
90		// The ranges can be made to repeat by setting repeatYear to true
91		// (repeatMonth is not supported).
92		//
93		// This example will create 3-sets of selectable date ranges with
94		// specific from and to ranges.  The 4th and 5th ranges don't specify
95		// the "to" date in which case the "to" date will be the maximum days for
96		// the month specified in "from".  The 4th and 5th ranges also repeat every year:
97		//
98		//     selectableDateRange: [
99		//         { from: new Date(2013, 1, 1), to: newDate (2013, 2, 1) },
100		//         { from: new Date(2013, 4, 1), to: newDate (2013, 8, 1) },
101		//         { from: new Date(2013, 7, 10), to: newDate (2013, 9, 10) },
102		//         { from: new Date(0, 8, 10), repeatYear: true }
103		//         { from: new Date(0, 9, 1), repeatYear: true }
104		//     ]
105		selectableDateRange: null,
106
107		// Mark certain dates as special dates.  Similar to selectableDates, this
108		// property supports both repeatYear and repeatMonth flags.
109		// Each special date can be styled using custom style names and can have
110		// data attached to it that will be returned in the onClick callback.
111		// The data field can be any custom (JSON style) object.
112		//
113		// This example creates two (repeatable by year) dates with special data in them.
114		// The first date also assigns a special class (which you will have to define).
115		//    specialDates: [
116		//        {
117		//            date: new Date(0, 8, 5),
118		//            data: { message: 'Happy Birthday!' },
119		//            repeatYear: true,
120		//            cssClass: 'special-bday'
121		//        },
122		//        {
123		//            date: new Date(2013, 0, 8),
124		//            data: { message: 'Meeting every day 8 of the month' },
125		//            repeatMonth: true
126		//        }
127		//    ]
128		specialDates: null,
129
130		// List of months that can be selectable, including when the user clicks
131		// on the title to select from the dropdown.
132		// This example only makes two months visible; September and December:
133		//    selectableMonths: [8, 11]
134		selectableMonths : null,
135
136		// List of selectable years.  If not provided, will default to 5-years
137		// back and forward.
138		// This example only allows selection of dates that have year 2012, 2013, 2015
139		//    selectableYears: [2012, 2013, 2015]
140		selectableYears: null,
141
142		// List of selectable days of the week.  0 is Sunday, 1 is Monday, and so on.
143		// This example allows only Sunday, Tuesday, Thursday:
144		//    selectableDOW: [0, 2, 4]
145		selectableDOW : null,
146
147		// Names of the month that will be shown in the title.
148		// Will default to long-form names:
149		//     January, February, March, April, May, June, July,
150		//     August, September, October, November, December
151		monthNames: null,
152
153		// Names of the days of the Week that will be shown below the title.
154		// Will default to short-form names:
155		//     Sun, Mon, Tue, Wed, Thu, Fri, Sat
156		dowNames: null,
157
158		// The day of the week to start the calendar on.  0 is Sunday, 1 is Monday and so on.
159		dowOffset: 0,
160
161		// Callback that will trigger when the user clicks a selectable date.
162		// Parameters that are passed to the callback:
163		//     el : The input element the date picker is bound to
164		//   cell : The cell on the calendar that triggered this event
165		//   date : The date associated with the cell
166		//   data : Special data associated with the cell (if available, otherwise, null)
167		onClick: (function(el, cell, date, data) {
168			el.val(date.toLocaleDateString());
169		}),
170
171		// Callback that will trigger when the user hovers over a selectable date.
172		// This callback receives the same set of parameters as onClick.
173		onHover: function(el, cell, date, data) {},
174
175		// Callback that will trigger when the calendar needs to show.
176		// You can use this callback to animate the opening of the calendar.
177		onShow: function(calendar) { calendar.show(); },
178
179		// Callback that will trigger when the calendar needs to hide.
180		// You can use this callback to animate the hiding of the calendar.
181		onHide: function(calendar) { calendar.hide(); },
182
183		// First date of the month.
184		firstDate: null
185	};
186
187	// Our plugin object
188	var glDatePicker = (function() {
189		// Main entry point.  Initialize the plugin
190		function glDatePicker(element, userOptions) {
191			// Grab handle to this
192			var self = this;
193
194			// Save bound element to el
195			self.el = jQuery(element);
196			var el = self.el;
197
198			// Merge user options into default options
199			self.options = jQuery.extend(true, {}, jQuery.fn.glDatePicker.defaults, userOptions);
200			var options = self.options;
201
202			// Find the calendar element if the user provided one
203			self.calendar = jQuery(jQuery.find('[gldp-el=' + el.attr('gldp-id') + ' ]'));
204
205			// Default first date to selected
206			options.selectedDate = options.selectedDate || options.todayDate;
207			options.firstDate = (new Date((options.firstDate || options.selectedDate)))._first();
208
209			if(!(el.attr('gldp-id') || '').length) {
210				el.attr('gldp-id', 'gldp-' + Math.round(Math.random() * 1e10))
211			}
212
213			// Show the plugin on focus
214			el
215				.addClass('gldp-el')
216				.bind('click', function(e) { self.show(e); })
217				.bind('focus', function(e) { self.show(e); });
218
219			// If the user is defining the container and it exists, hide it on initial creation.
220			// The update function will handle showing if it's showAlways = true
221			if(self.calendar.length && !options.showAlways) {
222				self.calendar.hide();
223			}
224
225			// Hide the plugin on mouse up outside of the plugin
226			jQuery(document).bind('mouseup', function(e) {
227				var target = e.target;
228				var calendar = self.calendar;
229
230				if(!el.is(target) && !calendar.is(target) && calendar.has(target).length === 0 && calendar.is(':visible')) {
231					self.hide();
232				}
233			});
234
235			// Render calendar
236			self.render();
237		};
238
239		// Public methods
240		glDatePicker.prototype =
241		{
242			show: function() {
243				// Hide others and show this calendar
244				jQuery.each(jQuery('.gldp-el').not(this.el), function(i, o) {
245					if(o.length) { o.options.onHide(o.calendar) ; }
246				});
247
248				// Show this calendar
249				this.options.onShow(this.calendar);
250			},
251
252			hide: function() {
253				if(this.options && !this.options.showAlways) {
254					this.options.onHide(this.calendar);
255				}
256			},
257
258			// Render the calendar
259			render: function(renderCalback) {
260				var self = this;
261				var el = self.el;
262				var options = self.options;
263				var calendar = self.calendar;
264
265				// Build a core class (with border) that every element would have
266				var coreClass = ' core border ';
267				var cssName = 'gldp-' + options.cssName;
268
269				// Get today
270				var todayVal = options.todayDate._val();
271				var todayTime = todayVal.time;
272
273				// Constants
274				var maxRow = 6;
275				var maxCol = 7;
276				var borderSize = options.borderSize + 'px';
277
278				// Helper function to build selectable list
279				var getSelectableList = function(min, max, userList) {
280					// Build a default list using min/max
281					var resultList = [];
282					for(var i = min; i <= max; i++) { resultList.push(i); }
283
284					// If user provided a collection, sanitize list by ensuring it's within range and unique
285					if(userList) {
286						var newList = [];
287						jQuery.each(userList, function(i, v) {
288							if(v >= min && v <= max && newList._indexOf(v) < 0) {
289								newList.push(v);
290							}
291						});
292
293						resultList = newList.length ? newList : resultList;
294					};
295
296					// Sort the values before returning it
297					resultList.sort();
298
299					return resultList;
300				};
301
302				// Selectable (constants)
303				var selectableMonths = getSelectableList(0, 11, options.selectableMonths);
304				var selectableYears = getSelectableList(todayVal.year - 5, todayVal.year + 5, options.selectableYears);
305				var selectableDOW = getSelectableList(0, 6, options.selectableDOW);
306				var dowNames = options.dowNames || [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ];
307				var monthNames = options.monthNames || [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ];
308
309				// Create cell width based on el size
310				var containerWidth = el.outerWidth();
311				var containerHeight = containerWidth;
312
313				// Create cell size based on container size
314				var getCellSize = function(_size, _count) {
315					return (_size / _count) + ((options.borderSize / _count) * (_count - 1));
316				};
317				var cellWidth = getCellSize(containerWidth, maxCol);
318				var cellHeight = getCellSize(containerHeight, maxRow + 2);
319
320				// If calendar doesn't exist, create it and re-assign it to self
321				if(!calendar.length) {
322					self.calendar = calendar = jQuery('<div/>')
323						.attr('gldp-el', el.attr('gldp-id'))
324						.data('is', true)
325						.css(
326						{
327							display: (options.showAlways ? undefined : 'none'),
328							zIndex: options.zIndex,
329							width: (cellWidth * maxCol) + 'px'
330						});
331
332					jQuery('body').append(calendar);
333				}
334				else {
335					if(!eval(calendar.data('is'))) {
336						containerWidth = calendar.outerWidth();
337						containerHeight = calendar.outerHeight();
338
339						cellWidth = getCellSize(containerWidth, maxCol);
340						cellHeight = getCellSize(containerHeight, maxRow + 2);
341					}
342				}
343
344				// Hide calendar if the target element isn't visible
345				if(!el.is(':visible')) { calendar.hide(); }
346
347				// Add core classes and remove calendar's children
348				calendar
349					.removeClass()
350					.addClass(cssName)
351					.children().remove();
352
353				// Bind to resize event to position calendar
354				var onResize = function() {
355					var elPos = el.offset();
356					calendar.css(
357					{
358						top: (elPos.top + el.outerHeight() + options.calendarOffset.y) + 'px',
359						left: (elPos.left + options.calendarOffset.x) + 'px'
360					});
361				};
362				jQuery(window).resize(onResize);
363				onResize();
364
365				// Create variables for cells
366				var cellCSS =
367				{
368					width: cellWidth + 'px',
369					height: cellHeight + 'px',
370					lineHeight: cellHeight + 'px'
371				};
372
373				// Helper function to setDate
374				var setFirstDate = function(_date) {
375					if(_date) {
376						// Get first date
377						options.firstDate = _date;
378
379						// Update the calendar
380						self.render();
381					}
382				};
383
384				var getFirstDate = function(_offset) {
385					// Create start date as the first date of the month
386					var _date = new Date(options.firstDate);
387
388					// Default to no offset
389					_offset = _offset || 0;
390
391					// Find out which months are selectable
392					while(true) {
393						// Adjust date for month offset
394						_date.setMonth(_date.getMonth() + _offset);
395						_date.setDate(Math.min(1, _date._max()));
396
397						// If not an offset, break out of the loop
398						if(_offset == 0) { break; }
399
400						// Get _date's value
401						var dateVal = _date._val();
402
403						// Get local vars
404						var dateMonth = dateVal.month;
405						var dateYear = dateVal.year;
406
407						// Find the month first
408						if(selectableMonths._indexOf(dateMonth) != -1) {
409							// If year is in our collection, break...
410							if(selectableYears._indexOf(dateYear) != -1) {
411								break;
412							}
413							else {
414								// ...otherwise, if it's out of bounds, exit loop
415								if(dateYear < selectableYears[0] || dateYear > selectableYears[selectableYears.length - 1]) {
416									return null;
417								}
418							}
419						}
420					}
421
422					return _date;
423				};
424
425				// Get the previous, next first dates
426				var prevFirstDate = getFirstDate(-1);
427				var nextFirstDate = getFirstDate(1);
428
429				// Get the first date for the current month being rendered
430				var firstDate = (options.firstDate = getFirstDate());
431				var firstDateVal = firstDate._val();
432				var firstDateMonth = firstDateVal.month;
433				var firstDateYear = firstDateVal.year;
434
435				// Get the start date in the calendar
436				var startDate = new Date(firstDate);
437
438				// Sanitize days of the week offset
439				var dowOffset = Math.abs(Math.min(6, Math.max(0, options.dowOffset)));
440
441				// Offset weekdays
442				var startOffset = startDate.getDay() - dowOffset;
443					startOffset = startOffset < 1 ? -7 - startOffset : -startOffset;
444					dowNames = (dowNames.concat(dowNames))
445								.slice(dowOffset, dowOffset + 7);
446
447				// Offset the start date
448				startDate._add(startOffset);
449
450				// Gather flags for prev/next arrows
451				var showPrev = (prevFirstDate);
452				var showNext = (nextFirstDate);
453
454				// Create the arrows and title
455				var monyearClass = coreClass + 'monyear ';
456
457				var prevCell = jQuery('<div/>')
458								.addClass(monyearClass)
459								.css(
460									jQuery.extend({}, cellCSS,
461									{
462										borderWidth: borderSize + ' 0 0 ' + borderSize
463									})
464								)
465								.append(
466									jQuery('<a/>')
467										.addClass('prev-arrow' + (showPrev ? '' : '-off'))
468										.html(options.prevArrow)
469								)
470								.mousedown(function() { return false; })
471								.click(function(e) {
472									if(options.prevArrow != '' && showPrev) {
473										e.stopPropagation();
474										setFirstDate(prevFirstDate);
475									}
476								});
477
478				var titleCellCount = maxCol - 2;
479				var titleWidth = (cellWidth * titleCellCount) - (titleCellCount * options.borderSize) + (options.borderSize);
480				var titleCell = jQuery('<div/>')
481								.addClass(monyearClass + 'title')
482								.css(
483									jQuery.extend({}, cellCSS,
484									{
485										width: titleWidth + 'px',
486										borderTopWidth: borderSize,
487										marginLeft: '-' + (borderSize)
488									})
489								);
490
491				var nextCell = jQuery('<div/>')
492								.addClass(monyearClass)
493								.css(
494									jQuery.extend({}, cellCSS,
495									{
496										marginLeft: '-' + (borderSize),
497										borderWidth: borderSize + ' ' + borderSize + ' 0 0'
498									})
499								)
500								.append(
501									jQuery('<a/>')
502										.addClass('next-arrow' + (showNext ? '' : '-off'))
503										.html(options.nextArrow)
504								)
505								.mousedown(function() { return false; })
506								.click(function(e) {
507									if(options.nextArrow != '' && showNext) {
508										e.stopPropagation();
509										setFirstDate(nextFirstDate);
510									}
511								});
512
513				// Add cells for prev/title/next
514				calendar
515					.append(prevCell)
516					.append(titleCell)
517					.append(nextCell);
518
519				// Add all the cells to the calendar
520				for(var row = 0, cellIndex = 0; row < maxRow + 1; row++) {
521					for(var col = 0; col < maxCol; col++, cellIndex++) {
522						var cellDate = new Date(startDate);
523						var cellClass = 'day';
524						var cellZIndex = options.zIndex + (cellIndex);
525						var cell = jQuery('<div/>')
526
527						if(!row) {
528							cellClass = 'dow';
529							cell.html(dowNames[col]);
530							cellDate = null;
531						}
532						else {
533							// Get the new date for this cell
534							cellDate._add(col + ((row - 1) * maxCol));
535
536							// Get value for this date
537							var cellDateVal = cellDate._val();
538							var cellDateTime = cellDateVal.time;
539
540							// Variable to hold special data
541							var specialData = null;
542
543							// Determine if this date is selectable
544							var isSelectable = true;
545
546							// Helper function to get repeat friendly date against current date
547							var getRepeatDate = function(v, date) {
548								// If repeating, set the date's year and month accordingly
549								if(v.repeatYear === true) { date.setYear(cellDateVal.year); }
550								if(v.repeatMonth === true) { date.setMonth(cellDateVal.month); }
551
552								return date._val();
553							};
554
555							// Assign date for the cell
556							cell.html(cellDateVal.date);
557
558							// If we have selectable date ranges
559							if(options.selectableDateRange) {
560								isSelectable = false;
561								jQuery.each(options.selectableDateRange, function(i, v) {
562									var dateFrom = v.from;
563									var dateTo = (v.to || null);
564
565									// If to is not specified, default to max days in the from month
566									dateTo = dateTo || new Date(v.from.getFullYear(), v.from.getMonth(), v.from._max());
567
568									// If repeating year, set the from and two to the current date's year
569									dateFrom = getRepeatDate(v, dateFrom);
570									dateTo = getRepeatDate(v, dateTo);
571
572									// Test to see if this date is selectable
573									if(cellDateTime >= dateFrom.time && cellDateTime <= dateTo.time) {
574										isSelectable = true;
575										return true;
576									}
577								});
578							}
579
580							// Handle date ranges and collections
581							if(options.selectableDates) {
582								if((options.selectableDateRange && !isSelectable) || (isSelectable && !options.selectableDateRange)) {
583									isSelectable = false;
584								}
585								jQuery.each(options.selectableDates, function(i, v) {
586									var vDate = getRepeatDate(v, v.date);
587
588									if(vDate.time == cellDateTime) {
589										return (isSelectable = true);
590									}
591								});
592							}
593
594							// If not active or if not within selectableMonths, set to noday otherwise evaluate accordingly
595							if(!isSelectable ||
596								selectableYears._indexOf(cellDateVal.year) < 0 ||
597								selectableMonths._indexOf(cellDateVal.month) < 0 ||
598								selectableDOW._indexOf(cellDateVal.day) < 0) {
599								cellClass = 'noday';
600							}
601							else {
602								// Handle active dates and weekends
603								cellClass = ([ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ])[cellDateVal.day];
604
605								// Handle today or selected dates
606								if(firstDateMonth != cellDateVal.month) { cellClass += ' outday'; }
607								if(todayTime == cellDateTime) { cellClass = 'today'; cellZIndex += 50; }
608								if(options.selectedDate._time() == cellDateTime) { cellClass = 'selected'; cellZIndex += 51; }
609
610								// Handle special dates
611								if(options.specialDates) {
612									jQuery.each(options.specialDates, function(i, v) {
613										var vDate = getRepeatDate(v, v.date);
614
615										if(vDate.time == cellDateTime) {
616											cellClass = (v.cssClass || 'special');
617											cellZIndex += 52;
618											specialData = v.data;
619										}
620									});
621								}
622
623								cell
624									.mousedown(function() { return false; })
625									.hover(function(e) {
626										e.stopPropagation();
627
628										// Get the data from this cell
629										var hoverData = jQuery(this).data('data');
630
631										// Call callback
632										options.onHover(el, cell, hoverData.date, hoverData.data);
633									})
634									.click(function(e) {
635										e.stopPropagation();
636
637										// Get the data from this cell
638										var clickedData = jQuery(this).data('data');
639
640										// Save date to selected and first
641										options.selectedDate = options.firstDate = clickedData.date;
642
643										// Update calendar (and auto-hide if necessary)
644										self.render(function() {
645											if(!options.showAlways && options.hideOnClick) {
646												self.hide();
647											}
648										});
649
650										// Call callback
651										options.onClick(el, jQuery(this), clickedData.date, clickedData.data);
652									});
653							}
654						}
655
656						// Update the css for the cell
657						jQuery.extend(cellCSS,
658						{
659							borderTopWidth: borderSize,
660							borderBottomWidth: borderSize,
661							borderLeftWidth: (row > 0 || (!row && !col)) ? borderSize : 0,
662							borderRightWidth: (row > 0 || (!row && col == 6)) ? borderSize : 0,
663							marginLeft: (col > 0) ? '-' + (borderSize) : 0,
664							marginTop: (row > 0) ? '-' + (borderSize) : 0,
665							zIndex: cellZIndex
666						});
667
668						// Assign other properties to the cell
669						cell
670							.data('data', { date: cellDate, data: specialData})
671							.addClass(coreClass + cellClass)
672							.css(cellCSS);
673
674						// Add cell to calendar
675						calendar.append(cell);
676					}
677				}
678
679				// Render the month / year title
680
681				// Helper function for toggling select and text
682				var toggleYearMonthSelect = function(showYear) {
683					var show = 'inline-block';
684					var hide = 'none';
685
686					if(options.allowMonthSelect) {
687						monthText.css({ display: !showYear ? hide : show });
688						monthSelect.css({ display: !showYear ? show : hide });
689					}
690
691					if(options.allowYearSelect) {
692						yearText.css({ display: showYear ? hide : show });
693						yearSelect.css({ display: showYear ? show : hide });
694					}
695				};
696
697				// Helper function when select is updated
698				var onYearMonthSelect = function() {
699					options.firstDate = new Date(yearSelect.val(), monthSelect.val(), 1);
700					self.render();
701				};
702
703				// Build month selector
704				var monthSelect = jQuery('<select/>')
705									.hide()
706									.change(onYearMonthSelect);
707
708				// Build year selector
709				var yearSelect = jQuery('<select/>')
710									.hide()
711									.change(onYearMonthSelect);
712
713				// Build month label
714				var monthText = jQuery('<span/>')
715									.html(monthNames[firstDateMonth])
716									.mousedown(function() { return false; })
717									.click(function(e) {
718										e.stopPropagation();
719										toggleYearMonthSelect(false);
720									});
721
722				// Build year label
723				var yearText = jQuery('<span/>')
724									.html(firstDateYear)
725									.mousedown(function() { return false; })
726									.click(function(e) {
727										e.stopPropagation();
728										toggleYearMonthSelect(true);
729									});
730
731				// Populate month select
732				jQuery.each(monthNames, function(i, v) {
733					if(options.allowMonthSelect && selectableMonths._indexOf(i) != -1) {
734						var o = jQuery('<option/>').html(v).attr('value', i);
735						if(i == firstDateMonth) { o.attr('selected', 'selected');}
736						monthSelect.append(o);
737					}
738				});
739
740				// Populate year select
741				jQuery.each(selectableYears, function(i, v) {
742					if(options.allowYearSelect) {
743						var o = jQuery('<option/>').html(v).attr('value', v);
744						if(v == firstDateYear) { o.attr('selected', 'selected'); }
745						yearSelect.append(o);
746					}
747				});
748
749				var titleYearMonth = jQuery('<div/>')
750										.append(monthText)
751										.append(monthSelect)
752										.append(yearText)
753										.append(yearSelect);
754
755				// Add to title
756				titleCell.children().remove();
757				titleCell.append(titleYearMonth);
758
759				// Run the callback signaling end of the render
760				renderCalback = renderCalback || (function() {});
761				renderCalback();
762			}
763		};
764
765		// Return the plugin
766		return glDatePicker;
767	})();
768
769	// One time initialization of useful prototypes
770	(function() {
771		Date.prototype._clear = function() {
772			this.setHours(0);
773			this.setMinutes(0);
774			this.setSeconds(0);
775			this.setMilliseconds(0);
776
777			return this;
778		};
779
780		Date.prototype._time = function() {
781			return this._clear().getTime();
782		};
783
784		Date.prototype._max = function() {
785			var isLeapYear = (new Date(this.getYear(), 1, 29).getMonth() == 1) ? 1 : 0;
786			var days = [31, 28 + isLeapYear, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
787
788			return days[this.getMonth()];
789		};
790
791		Date.prototype._add = function(days) {
792			this.setDate(this.getDate() + days);
793		};
794
795		Date.prototype._first = function() {
796			var date = new Date(this);
797				date.setDate(1);
798
799			return date;
800		};
801
802		Date.prototype._val = function() {
803			this._clear();
804
805			return {
806				year: this.getFullYear(),
807				month: this.getMonth(),
808				date: this.getDate(),
809				time: this.getTime(),
810				day: this.getDay()
811			};
812		};
813
814		Array.prototype._indexOf = function(value) {
815			return jQuery.inArray(value, this);
816		}
817	})();
818})();

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.