PageSourceSearch

https://eideford.com/js/plugins/calendar.js?v=12.1.255

js eideford.com collected 2026-10-07 15:18:56 UTC 53,025 bytes, 1,364 lines download raw bytes

1/*
2 * # Semantic UI 0.0.6
vendor: 12,234 bytes, lines 2-299
2 - Calendar
3 * http://github.com/semantic-org/semantic-ui/
4 *
5 *
6 * Released under the MIT license
7 * http://opensource.org/licenses/MIT
8 */
9
10;
11(function ($, window, document, undefined) {
12
13  "use strict";
14
15  window = (typeof window != 'undefined' && window.Math == Math)
16    ? window
17    : (typeof self != 'undefined' && self.Math == Math)
18    ? self
19    : Function('return this')()
20  ;
21
22  $.fn.calendar = function (parameters) {
23
24    var
25      $allModules = $(this),
26
27      moduleSelector = $allModules.selector || '',
28
29      time = new Date().getTime(),
30      performance = [],
31
32      query = arguments[0],
33      methodInvoked = (typeof query == 'string'),
34      queryArguments = [].slice.call(arguments, 1),
35      returnedValue
36      ;
37
38    $allModules
39      .each(function () {
40        var
41          settings = ( $.isPlainObject(parameters) )
42            ? $.extend(true, {}, $.fn.calendar.settings, parameters)
43            : $.extend({}, $.fn.calendar.settings),
44
45          className = settings.className,
46          namespace = settings.namespace,
47          selector = settings.selector,
48          formatter = settings.formatter,
49          parser = settings.parser,
50          metadata = settings.metadata,
51          error = settings.error,
52
53          eventNamespace = '.' + namespace,
54          moduleNamespace = 'module-' + namespace,
55
56          $module = $(this),
57          $input = $module.find(selector.input),
58          $container = $module.find(selector.popup),
59          $activator = $module.find(selector.activator),
60
61          element = this,
62          instance = $module.data(moduleNamespace),
63
64          isTouch,
65          isTouchDown = false,
66          focusDateUsedForRange = false,
67          module
68          ;
69
70        module = {
71
72          initialize: function () {
73            module.debug('Initializing calendar for', element);
74
75            isTouch = module.get.isTouch();
76            module.setup.popup();
77            module.setup.inline();
78            module.setup.input();
79            module.setup.date();
80            module.create.calendar();
81
82            module.bind.events();
83            module.instantiate();
84          },
85
86          instantiate: function () {
87            module.verbose('Storing instance of calendar');
88            instance = module;
89            $module.data(moduleNamespace, instance);
90          },
91
92          destroy: function () {
93            module.verbose('Destroying previous calendar for', element);
94            $module.removeData(moduleNamespace);
95            module.unbind.events();
96          },
97
98          setup: {
99            popup: function () {
100              if (settings.inline) {
101                return;
102              }
103              if (!$activator.length) {
104                $activator = $module.children().first();
105                if (!$activator.length) {
106                  return;
107                }
108              }
109              if ($.fn.popup === undefined) {
110                module.error(error.popup);
111                return;
112              }
113              if (!$container.length) {
114                //prepend the popup element to the activator's parent so that it has less chance of messing with
115                //the styling (eg input action button needs to be the last child to have correct border radius)
116                $container = $('<div/>').addClass(className.popup).prependTo($activator.parent());
117              }
118              $container.addClass(className.calendar);
119              var onVisible = settings.onVisible;
120              var onHidden = settings.onHidden;
121              if (!$input.length) {
122                //no input, $container has to handle focus/blur
123                $container.attr('tabindex', '0');
124                onVisible = function () {
125                  module.focus();
126                  return settings.onVisible.apply($container, arguments);
127                };
128                onHidden = function () {
129                  module.blur();
130                  return settings.onHidden.apply($container, arguments);
131                };
132              }
133              var onShow = function () {
134                //reset the focus date onShow
135                module.set.focusDate(module.get.date());
136                module.set.mode(settings.startMode);
137                return settings.onShow.apply($container, arguments);
138              };
139              var on = settings.on || ($input.length ? 'focus' : 'click');
140              var options = $.extend({}, settings.popupOptions, {
141                popup: $container,
142                on: on,
143                hoverable: on === 'hover',
144                onShow: onShow,
145                onVisible: onVisible,
146                onHide: settings.onHide,
147                onHidden: onHidden
148              });
149              module.popup(options);
150            },
151            inline: function () {
152              if ($activator.length && !settings.inline) {
153                return;
154              }
155              $container = $('<div/>').addClass(className.calendar).appendTo($module);
156              if (!$input.length) {
157                $container.attr('tabindex', '0');
158              }
159            },
160            input: function () {
161              if (settings.touchReadonly && $input.length && isTouch) {
162                $input.prop('readonly', true);
163              }
164            },
165            date: function () {
166              if ($input.length) {
167                var val = $input.val();
168                var date = parser.date(val, settings);
169                module.set.date(date, settings.formatInput, false);
170              }
171            }
172          },
173
174          create: {
175            calendar: function () {
176              var i, r, c, p, row, cell, pageGrid;
177
178              var mode = module.get.mode();
179              var today = new Date();
180              var date = module.get.date();
181              var focusDate = module.get.focusDate();
182              var display = focusDate || date || settings.initialDate || today;
183              display = module.helper.dateInRange(display);
184
185              if (!focusDate) {
186                focusDate = display;
187                module.set.focusDate(focusDate, false, false);
188              }
189
190              var isYear = mode === 'year';
191              var isMonth = mode === 'month';
192              var isDay = mode === 'day';
193              var isHour = mode === 'hour';
194              var isMinute = mode === 'minute';
195              var isTimeOnly = settings.type === 'time';
196
197              var multiMonth = Math.max(settings.multiMonth, 1);
198              var monthOffset = !isDay ? 0 : module.get.monthOffset();
199
200              var minute = display.getMinutes();
201              var hour = display.getHours();
202              var day = display.getDate();
203              var startMonth = display.getMonth() + monthOffset;
204              var year = display.getFullYear();
205
206              var columns = isDay ? 7 : isHour ? 4 : 3;
207              var columnsString = columns === 7 ? 'seven' : columns === 4 ? 'four' : 'three';
208              var rows = isDay || isHour ? 6 : 4;
209              var pages = isDay ? multiMonth : 1;
210
211              var container = $container;
212              container.empty();
213              if (pages > 1) {
214                pageGrid = $('<div/>').addClass(className.grid).appendTo(container);
215              }
216
217              for (p = 0; p < pages; p++) {
218                if (pages > 1) {
219                  var pageColumn = $('<div/>').addClass(className.column).appendTo(pageGrid);
220                  container = pageColumn;
221                }
222
223                var month = startMonth + p;
224                var firstMonthDayColumn = (new Date(year, month, 1).getDay() - settings.firstDayOfWeek % 7 + 7) % 7;
225                if (!settings.constantHeight && isDay) {
226                  var requiredCells = new Date(year, month + 1, 0).getDate() + firstMonthDayColumn;
227                  rows = Math.ceil(requiredCells / 7);
228                }
229
230                var yearChange = isYear ? 10 : isMonth ? 1 : 0;
231                var monthChange = isDay ? 1 : 0;
232                var dayChange = isHour || isMinute ? 1 : 0;
233                var prevNextDay = isHour || isMinute ? day : 1;
234                var prevDate = new Date(year - yearChange, month - monthChange, prevNextDay - dayChange, hour);
235                var nextDate = new Date(year + yearChange, month + monthChange, prevNextDay + dayChange, hour);
236
237                var prevLast = isYear ? new Date(Math.ceil(year / 10) * 10 - 9, 0, 0) :
238                  isMonth ? new Date(year, 0, 0) : isDay ? new Date(year, month, 0) : new Date(year, month, day, -1);
239                var nextFirst = isYear ? new Date(Math.ceil(year / 10) * 10 + 1, 0, 1) :
240                  isMonth ? new Date(year + 1, 0, 1) : isDay ? new Date(year, month + 1, 1) : new Date(year, month, day + 1);
241
242                var table = $('<table/>').addClass(className.table).addClass(columnsString + ' column').addClass(mode).appendTo(container);
243
244                //no header for time-only mode
245                if (!isTimeOnly) {
246                  var thead = $('<thead/>').appendTo(table);
247
248                  row = $('<tr/>').appendTo(thead);
249                  cell = $('<th/>').attr('colspan', '' + columns).appendTo(row);
250
251                  var headerDate = isYear || isMonth ? new Date(year, 0, 1) :
252                    isDay ? new Date(year, month, 1) : new Date(year, month, day, hour, minute);
253                  var headerText = $('<span/>').addClass(className.link).appendTo(cell);
254                  headerText.text(formatter.header(headerDate, mode, settings));
255                  var newMode = isMonth ? (settings.disableYear ? 'day' : 'year') :
256                    isDay ? (settings.disableMonth ? 'year' : 'month') : 'day';
257                  headerText.data(metadata.mode, newMode);
258
259                  if (p === 0) {
260                    var prev = $('<span/>').addClass(className.prev).appendTo(cell);
261                    prev.data(metadata.focusDate, prevDate);
262                    prev.toggleClass(className.disabledCell, !module.helper.isDateInRange(prevLast, mode));
263                    $('<i/>').addClass(className.prevIcon).appendTo(prev);
264                  }
265
266                  if (p === pages - 1) {
267                    var next = $('<span/>').addClass(className.next).appendTo(cell);
268                    next.data(metadata.focusDate, nextDate);
269                    next.toggleClass(className.disabledCell, !module.helper.isDateInRange(nextFirst, mode));
270                    $('<i/>').addClass(className.nextIcon).appendTo(next);
271                  }
272
273                  if (isDay) {
274                    row = $('<tr/>').appendTo(thead);
275                    for (i = 0; i < columns; i++) {
276                      cell = $('<th/>').appendTo(row);
277                      cell.text(formatter.dayColumnHeader((i + settings.firstDayOfWeek) % 7, settings));
278                    }
279                  }
280                }
281
282                var tbody = $('<tbody/>').appendTo(table);
283                i = isYear ? Math.ceil(year / 10) * 10 - 9 : isDay ? 1 - firstMonthDayColumn : 0;
284                for (r = 0; r < rows; r++) {
285                  row = $('<tr/>').appendTo(tbody);
286                  for (c = 0; c < columns; c++, i++) {
287                    var cellDate = isYear ? new Date(i, month, 1, hour, minute) :
288                      isMonth ? new Date(year, i, 1, hour, minute) : isDay ? new Date(year, month, i, hour, minute) :
289                        isHour ? new Date(year, month, day, i) : new Date(year, month, day, hour, i * 5);
290                    var cellText = isYear ? i :
291                      isMonth ? settings.text.monthsShort[i] : isDay ? cellDate.getDate() :
292                        formatter.time(cellDate, settings, true);
293                    cell = $('<td/>').addClass(className.cell).appendTo(row);
294                    cell.text(cellText);
295                    cell.data(metadata.date, cellDate);
296                    var adjacent = isDay && cellDate.getMonth() !== ((month + 12) % 12);
297                    var disabled = adjacent || !module.helper.isDateInRange(cellDate, mode) || settings.isDisabled(cellDate, mode);
298                    var active = module.helper.dateEqual(cellDate, date, mode);
299                    
299cell.toggleClass(className.adjacentCell, adjacent);
300                    cell.toggleClass(className.disabledCell, disabled);
301                    cell.toggleClass(className.activeCell, active && !adjacent);
302                    if (!isHour && !isMinute) {
303                      cell.toggleClass(className.todayCell, !adjacent && module.helper.dateEqual(cellDate, today, mode));
304                    }
vendor: 40,370 bytes, lines 304-1364
304
305                    if (module.helper.dateEqual(cellDate, focusDate, mode)) {
306                      //ensure that the focus date is exactly equal to the cell date
307                      //so that, if selected, the correct value is set
308                      module.set.focusDate(cellDate, false, false);
309                    }
310                  }
311                }
312
313                if (settings.today) {
314                  var todayRow = $('<tr/>').appendTo(tbody);
315                  var todayButton = $('<td/>').attr('colspan', '' + columns).addClass(className.today).appendTo(todayRow);
316                  todayButton.text(formatter.today(settings));
317                  todayButton.data(metadata.date, today);
318                }
319
320                module.update.focus(false, table);
321              }
322            }
323          },
324
325          update: {
326            focus: function (updateRange, container) {
327              container = container || $container;
328              var mode = module.get.mode();
329              var date = module.get.date();
330              var focusDate = module.get.focusDate();
331              var startDate = module.get.startDate();
332              var endDate = module.get.endDate();
333              var rangeDate = (updateRange ? focusDate : null) || date || (!isTouch ? focusDate : null);
334
335              container.find('td').each(function () {
336                var cell = $(this);
337                var cellDate = cell.data(metadata.date);
338                if (!cellDate) {
339                  return;
340                }
341                var disabled = cell.hasClass(className.disabledCell);
342                var active = cell.hasClass(className.activeCell);
343                var adjacent = cell.hasClass(className.adjacentCell);
344                var focused = module.helper.dateEqual(cellDate, focusDate, mode);
345                var inRange = !rangeDate ? false :
346                  ((!!startDate && module.helper.isDateInRange(cellDate, mode, startDate, rangeDate)) ||
347                  (!!endDate && module.helper.isDateInRange(cellDate, mode, rangeDate, endDate)));
348                cell.toggleClass(className.focusCell, focused && (!isTouch || isTouchDown) && !adjacent);
349                cell.toggleClass(className.rangeCell, inRange && !active && !disabled);
350              });
351            }
352          },
353
354          refresh: function () {
355            module.create.calendar();
356          },
357
358          bind: {
359            events: function () {
360              $container.on('mousedown' + eventNamespace, module.event.mousedown);
361              $container.on('touchstart' + eventNamespace, module.event.mousedown);
362              $container.on('mouseup' + eventNamespace, module.event.mouseup);
363              $container.on('touchend' + eventNamespace, module.event.mouseup);
364              $container.on('mouseover' + eventNamespace, module.event.mouseover);
365              if ($input.length) {
366                $input.on('input' + eventNamespace, module.event.inputChange);
367                $input.on('focus' + eventNamespace, module.event.inputFocus);
368                $input.on('blur' + eventNamespace, module.event.inputBlur);
369                $input.on('click' + eventNamespace, module.event.inputClick);
370                $input.on('keydown' + eventNamespace, module.event.keydown);
371              } else {
372                $container.on('keydown' + eventNamespace, module.event.keydown);
373              }
374            }
375          },
376
377          unbind: {
378            events: function () {
379              $container.off(eventNamespace);
380              if ($input.length) {
381                $input.off(eventNamespace);
382              }
383            }
384          },
385
386          event: {
387            mouseover: function (event) {
388              var target = $(event.target);
389              var date = target.data(metadata.date);
390              var mousedown = event.buttons === 1;
391              if (date) {
392                module.set.focusDate(date, false, true, mousedown);
393              }
394            },
395            mousedown: function (event) {
396              if ($input.length) {
397                //prevent the mousedown on the calendar causing the input to lose focus
398                event.preventDefault();
399              }
400              isTouchDown = event.type.indexOf('touch') >= 0;
401              var target = $(event.target);
402              var date = target.data(metadata.date);
403              if (date) {
404                module.set.focusDate(date, false, true, true);
405              }
406            },
407            mouseup: function (event) {
408              //ensure input has focus so that it receives keydown events for calendar navigation
409              module.focus();
410              event.preventDefault();
411              event.stopPropagation();
412              isTouchDown = false;
413              var target = $(event.target);
414              var parent = target.parent();
415              if (parent.data(metadata.date) || parent.data(metadata.focusDate) || parent.data(metadata.mode)) {
416                //clicked on a child element, switch to parent (used when clicking directly on prev/next <i> icon element)
417                target = parent;
418              }
419              var date = target.data(metadata.date);
420              var focusDate = target.data(metadata.focusDate);
421              var mode = target.data(metadata.mode);
422              if (date) {
423                var forceSet = target.hasClass(className.today);
424                module.selectDate(date, forceSet);
425              }
426              else if (focusDate) {
427                module.set.focusDate(focusDate);
428              }
429              else if (mode) {
430                module.set.mode(mode);
431              }
432            },
433            keydown: function (event) {
434              if (event.keyCode === 27 || event.keyCode === 9) {
435                //esc || tab
436                module.popup('hide');
437              }
438
439              if (module.popup('is visible')) {
440                if (event.keyCode === 37 || event.keyCode === 38 || event.keyCode === 39 || event.keyCode === 40) {
441                  //arrow keys
442                  var mode = module.get.mode();
443                  var bigIncrement = mode === 'day' ? 7 : mode === 'hour' ? 4 : 3;
444                  var increment = event.keyCode === 37 ? -1 : event.keyCode === 38 ? -bigIncrement : event.keyCode == 39 ? 1 : bigIncrement;
445                  increment *= mode === 'minute' ? 5 : 1;
446                  var focusDate = module.get.focusDate() || module.get.date() || new Date();
447                  var year = focusDate.getFullYear() + (mode === 'year' ? increment : 0);
448                  var month = focusDate.getMonth() + (mode === 'month' ? increment : 0);
449                  var day = focusDate.getDate() + (mode === 'day' ? increment : 0);
450                  var hour = focusDate.getHours() + (mode === 'hour' ? increment : 0);
451                  var minute = focusDate.getMinutes() + (mode === 'minute' ? increment : 0);
452                  var newFocusDate = new Date(year, month, day, hour, minute);
453                  if (settings.type === 'time') {
454                    newFocusDate = module.helper.mergeDateTime(focusDate, newFocusDate);
455                  }
456                  if (module.helper.isDateInRange(newFocusDate, mode)) {
457                    module.set.focusDate(newFocusDate);
458                  }
459                } else if (event.keyCode === 13) {
460                  //enter
461                  var mode = module.get.mode();
462                  var date = module.get.focusDate();
463                  if (date && !settings.isDisabled(date, mode)) {
464                    module.selectDate(date);
465                  }
466                  //disable form submission:
467                  event.preventDefault();
468                  event.stopPropagation();
469                }
470              }
471
472              if (event.keyCode === 38 || event.keyCode === 40) {
473                //arrow-up || arrow-down
474                event.preventDefault(); //don't scroll
475                module.popup('show');
476              }
477            },
478            inputChange: function () {
479              var val = $input.val();
480              var date = parser.date(val, settings);
481              module.set.date(date, false);
482            },
483            inputFocus: function () {
484              $container.addClass(className.active);
485            },
486            inputBlur: function () {
487              $container.removeClass(className.active);
488              if (settings.formatInput) {
489                var date = module.get.date();
490                var text = formatter.datetime(date, settings);
491                $input.val(text);
492              }
493            },
494            inputClick: function () {
495              module.popup('show');
496            }
497          },
498
499          get: {
500            date: function () {
501              return $module.data(metadata.date) || null;
502            },
503            focusDate: function () {
504              return $module.data(metadata.focusDate) || null;
505            },
506            startDate: function () {
507              var startModule = module.get.calendarModule(settings.startCalendar);
508              return (startModule ? startModule.get.date() : $module.data(metadata.startDate)) || null;
509            },
510            endDate: function () {
511              var endModule = module.get.calendarModule(settings.endCalendar);
512              return (endModule ? endModule.get.date() : $module.data(metadata.endDate)) || null;
513            },
514            monthOffset: function () {
515              return $module.data(metadata.monthOffset) || 0;
516            },
517            mode: function () {
518              //only returns valid modes for the current settings
519              var mode = $module.data(metadata.mode) || settings.startMode;
520              var validModes = module.get.validModes();
521              if ($.inArray(mode, validModes) >= 0) {
522                return mode;
523              }
524              return settings.type === 'time' ? 'hour' :
525                settings.type === 'month' ? 'month' :
526                  settings.type === 'year' ? 'year' : 'day';
527            },
528            validModes: function () {
529              var validModes = [];
530              if (settings.type !== 'time') {
531                if (!settings.disableYear || settings.type === 'year') {
532                  validModes.push('year');
533                }
534                if (!(settings.disableMonth || settings.type === 'year') || settings.type === 'month') {
535                  validModes.push('month');
536                }
537                if (settings.type.indexOf('date') >= 0) {
538                  validModes.push('day');
539                }
540              }
541              if (settings.type.indexOf('time') >= 0) {
542                validModes.push('hour');
543                if (!settings.disableMinute) {
544                  validModes.push('minute');
545                }
546              }
547              return validModes;
548            },
549            isTouch: function () {
550              try {
551                document.createEvent('TouchEvent');
552                return true;
553              }
554              catch (e) {
555                return false;
556              }
557            },
558            calendarModule: function (selector) {
559              if (!selector) {
560                return null;
561              }
562              if (!(selector instanceof $)) {
563                selector = $module.parent().children(selector).first();
564              }
565              //assume range related calendars are using the same namespace
566              return selector.data(moduleNamespace);
567            }
568          },
569
570          set: {
571            date: function (date, updateInput, fireChange) {
572              updateInput = updateInput !== false;
573              fireChange = fireChange !== false;
574              date = module.helper.sanitiseDate(date);
575              date = module.helper.dateInRange(date);
576
577              var mode = module.get.mode();
578              var text = formatter.datetime(date, settings);
579              if (fireChange && settings.onChange.call(element, date, text, mode) === false) {
580                return false;
581              }
582
583              module.set.focusDate(date);
584
585              if (settings.isDisabled(date, mode)) {
586                return false;
587              }
588
589              var endDate = module.get.endDate();
590              if (!!endDate && !!date && date > endDate) {
591                //selected date is greater than end date in range, so clear end date
592                module.set.endDate(undefined);
593              }
594              module.set.dataKeyValue(metadata.date, date);
595
596              if (updateInput && $input.length) {
597                $input.val(text);
598              }
599            },
600            startDate: function (date, refreshCalendar) {
601              date = module.helper.sanitiseDate(date);
602              var startModule = module.get.calendarModule(settings.startCalendar);
603              if (startModule) {
604                startModule.set.date(date);
605              }
606              module.set.dataKeyValue(metadata.startDate, date, refreshCalendar);
607            },
608            endDate: function (date, refreshCalendar) {
609              date = module.helper.sanitiseDate(date);
610              var endModule = module.get.calendarModule(settings.endCalendar);
611              if (endModule) {
612                endModule.set.date(date);
613              }
614              module.set.dataKeyValue(metadata.endDate, date, refreshCalendar);
615            },
616            focusDate: function (date, refreshCalendar, updateFocus, updateRange) {
617              date = module.helper.sanitiseDate(date);
618              date = module.helper.dateInRange(date);
619              var isDay = module.get.mode() === 'day';
620              var oldFocusDate = module.get.focusDate();
621              if (isDay && date && oldFocusDate) {
622                var yearDelta = date.getFullYear() - oldFocusDate.getFullYear();
623                var monthDelta = yearDelta * 12 + date.getMonth() - oldFocusDate.getMonth();
624                if (monthDelta) {
625                  var monthOffset = module.get.monthOffset() - monthDelta;
626                  module.set.monthOffset(monthOffset, false);
627                }
628              }
629              var changed = module.set.dataKeyValue(metadata.focusDate, date, refreshCalendar);
630              updateFocus = (updateFocus !== false && changed && refreshCalendar === false) || focusDateUsedForRange != updateRange;
631              focusDateUsedForRange = updateRange;
632              if (updateFocus) {
633                module.update.focus(updateRange);
634              }
635            },
636            monthOffset: function (monthOffset, refreshCalendar) {
637              var multiMonth = Math.max(settings.multiMonth, 1);
638              monthOffset = Math.max(1 - multiMonth, Math.min(0, monthOffset));
639              module.set.dataKeyValue(metadata.monthOffset, monthOffset, refreshCalendar);
640            },
641            mode: function (mode, refreshCalendar) {
642              module.set.dataKeyValue(metadata.mode, mode, refreshCalendar);
643            },
644            dataKeyValue: function (key, value, refreshCalendar) {
645              var oldValue = $module.data(key);
646              var equal = oldValue === value || (oldValue <= value && oldValue >= value); //equality test for dates and string objects
647              if (value) {
648                $module.data(key, value);
649              } else {
650                $module.removeData(key);
651              }
652              refreshCalendar = refreshCalendar !== false && !equal;
653              if (refreshCalendar) {
654                module.create.calendar();
655              }
656              return !equal;
657            }
658          },
659
660          selectDate: function (date, forceSet) {
661            var mode = module.get.mode();
662            var complete = forceSet || mode === 'minute' ||
663              (settings.disableMinute && mode === 'hour') ||
664              (settings.type === 'date' && mode === 'day') ||
665              (settings.type === 'month' && mode === 'month') ||
666              (settings.type === 'year' && mode === 'year');
667            if (complete) {
668              var canceled = module.set.date(date) === false;
669              if (!canceled && settings.closable) {
670                module.popup('hide');
671                //if this is a range calendar, show the end date calendar popup and focus the input
672                var endModule = module.get.calendarModule(settings.endCalendar);
673                if (endModule) {
674                  endModule.popup('show');
675                  endModule.focus();
676                }
677              }
678            } else {
679              var newMode = mode === 'year' ? (!settings.disableMonth ? 'month' : 'day') :
680                mode === 'month' ? 'day' : mode === 'day' ? 'hour' : 'minute';
681              module.set.mode(newMode);
682              if (mode === 'hour' || (mode === 'day' && module.get.date())) {
683                //the user has chosen enough to consider a valid date/time has been chosen
684                module.set.date(date);
685              } else {
686                module.set.focusDate(date);
687              }
688            }
689          },
690
691          changeDate: function (date) {
692            module.set.date(date);
693          },
694
695          clear: function () {
696            module.set.date(undefined);
697          },
698
699          popup: function () {
700            return $activator.popup.apply($activator, arguments);
701          },
702
703          focus: function () {
704            if ($input.length) {
705              $input.focus();
706            } else {
707              $container.focus();
708            }
709          },
710          blur: function () {
711            if ($input.length) {
712              $input.blur();
713            } else {
714              $container.blur();
715            }
716          },
717
718          helper: {
719            sanitiseDate: function (date) {
720              if (!date) {
721                return undefined;
722              }
723              if (!(date instanceof Date)) {
724                date = parser.date('' + date, settings);
725              }
726              if (isNaN(date.getTime())) {
727                return undefined;
728              }
729              return date;
730            },
731            dateDiff: function (date1, date2, mode) {
732              mode = mode || 'day';
733              var isTimeOnly = settings.type === 'time';
734              var isYear = mode === 'year';
735              var isYearOrMonth = isYear || mode === 'month';
736              var isMinute = mode === 'minute';
737              var isHourOrMinute = isMinute || mode === 'hour';
738              //only care about a minute accuracy of 5
739              date1 = new Date(
740                isTimeOnly ? 2000 : date1.getFullYear(),
741                isTimeOnly ? 0 : isYear ? 0 : date1.getMonth(),
742                isTimeOnly ? 1 : isYearOrMonth ? 1 : date1.getDate(),
743                !isHourOrMinute ? 0 : date1.getHours(),
744                !isMinute ? 0 : 5 * Math.floor(date1.getMinutes() / 5));
745              date2 = new Date(
746                isTimeOnly ? 2000 : date2.getFullYear(),
747                isTimeOnly ? 0 : isYear ? 0 : date2.getMonth(),
748                isTimeOnly ? 1 : isYearOrMonth ? 1 : date2.getDate(),
749                !isHourOrMinute ? 0 : date2.getHours(),
750                !isMinute ? 0 : 5 * Math.floor(date2.getMinutes() / 5));
751              return date2.getTime() - date1.getTime();
752            },
753            dateEqual: function (date1, date2, mode) {
754              return !!date1 && !!date2 && module.helper.dateDiff(date1, date2, mode) === 0;
755            },
756            isDateInRange: function (date, mode, minDate, maxDate) {
757              if (!minDate && !maxDate) {
758                var startDate = module.get.startDate();
759                minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
760                maxDate = settings.maxDate;
761              }
762              minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), 5 * Math.ceil(minDate.getMinutes() / 5));
763              return !(!date ||
764              (minDate && module.helper.dateDiff(date, minDate, mode) > 0) ||
765              (maxDate && module.helper.dateDiff(maxDate, date, mode) > 0));
766            },
767            dateInRange: function (date, minDate, maxDate) {
768              if (!minDate && !maxDate) {
769                var startDate = module.get.startDate();
770                minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
771                maxDate = settings.maxDate;
772              }
773              minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), 5 * Math.ceil(minDate.getMinutes() / 5));
774              var isTimeOnly = settings.type === 'time';
775              return !date ? date :
776                (minDate && module.helper.dateDiff(date, minDate, 'minute') > 0) ?
777                  (isTimeOnly ? module.helper.mergeDateTime(date, minDate) : minDate) :
778                  (maxDate && module.helper.dateDiff(maxDate, date, 'minute') > 0) ?
779                    (isTimeOnly ? module.helper.mergeDateTime(date, maxDate) : maxDate) :
780                    date;
781            },
782            mergeDateTime: function (date, time) {
783              return (!date || !time) ? time :
784                new Date(date.getFullYear(), date.getMonth(), date.getDate(), time.getHours(), time.getMinutes());
785            }
786          },
787
788          setting: function (name, value) {
789            module.debug('Changing setting', name, value);
790            if ($.isPlainObject(name)) {
791              $.extend(true, settings, name);
792            }
793            else if (value !== undefined) {
794              if ($.isPlainObject(settings[name])) {
795                $.extend(true, settings[name], value);
796              }
797              else {
798                settings[name] = value;
799              }
800            }
801            else {
802              return settings[name];
803            }
804          },
805          internal: function (name, value) {
806            module.debug('Changing internal', name, value);
807            if (value !== undefined) {
808              if ($.isPlainObject(name)) {
809                $.extend(true, module, name);
810              }
811              else {
812                module[name] = value;
813              }
814            }
815            else {
816              return module[name];
817            }
818          },
819          debug: function () {
820            if (!settings.silent && settings.debug) {
821              if (settings.performance) {
822                module.performance.log(arguments);
823              }
824              else {
825                module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
826                module.debug.apply(console, arguments);
827              }
828            }
829          },
830          verbose: function () {
831            if (!settings.silent && settings.verbose && settings.debug) {
832              if (settings.performance) {
833                module.performance.log(arguments);
834              }
835              else {
836                module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
837                module.verbose.apply(console, arguments);
838              }
839            }
840          },
841          error: function () {
842            if (!settings.silent) {
843              module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
844              module.error.apply(console, arguments);
845            }
846          },
847          performance: {
848            log: function (message) {
849              var
850                currentTime,
851                executionTime,
852                previousTime
853                ;
854              if (settings.performance) {
855                currentTime = new Date().getTime();
856                previousTime = time || currentTime;
857                executionTime = currentTime - previousTime;
858                time = currentTime;
859                performance.push({
860                  'Name': message[0],
861                  'Arguments': [].slice.call(message, 1) || '',
862                  'Element': element,
863                  'Execution Time': executionTime
864                });
865              }
866              clearTimeout(module.performance.timer);
867              module.performance.timer = setTimeout(module.performance.display, 500);
868            },
869            display: function () {
870              var
871                title = settings.name + ':',
872                totalTime = 0
873                ;
874              time = false;
875              clearTimeout(module.performance.timer);
876              $.each(performance, function (index, data) {
877                totalTime += data['Execution Time'];
878              });
879              title += ' ' + totalTime + 'ms';
880              if (moduleSelector) {
881                title += ' \'' + moduleSelector + '\'';
882              }
883              if ((console.group !== undefined || console.table !== undefined) && performance.length > 0) {
884                console.groupCollapsed(title);
885                if (console.table) {
886                  console.table(performance);
887                }
888                else {
889                  $.each(performance, function (index, data) {
890                    console.log(data['Name'] + ': ' + data['Execution Time'] + 'ms');
891                  });
892                }
893                console.groupEnd();
894              }
895              performance = [];
896            }
897          },
898          invoke: function (query, passedArguments, context) {
899            var
900              object = instance,
901              maxDepth,
902              found,
903              response
904              ;
905            passedArguments = passedArguments || queryArguments;
906            context = element || context;
907            if (typeof query == 'string' && object !== undefined) {
908              query = query.split(/[\. ]/);
909              maxDepth = query.length - 1;
910              $.each(query, function (depth, value) {
911                var camelCaseValue = (depth != maxDepth)
912                    ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
913                    : query
914                  ;
915                if ($.isPlainObject(object[camelCaseValue]) && (depth != maxDepth)) {
916                  object = object[camelCaseValue];
917                }
918                else if (object[camelCaseValue] !== undefined) {
919                  found = object[camelCaseValue];
920                  return false;
921                }
922                else if ($.isPlainObject(object[value]) && (depth != maxDepth)) {
923                  object = object[value];
924                }
925                else if (object[value] !== undefined) {
926                  found = object[value];
927                  return false;
928                }
929                else {
930                  module.error(error.method, query);
931                  return false;
932                }
933              });
934            }
935            if ($.isFunction(found)) {
936              response = found.apply(context, passedArguments);
937            }
938            else if (found !== undefined) {
939              response = found;
940            }
941            if ($.isArray(returnedValue)) {
942              returnedValue.push(response);
943            }
944            else if (returnedValue !== undefined) {
945              returnedValue = [returnedValue, response];
946            }
947            else if (response !== undefined) {
948              returnedValue = response;
949            }
950            return found;
951          }
952        };
953
954        if (methodInvoked) {
955          if (instance === undefined) {
956            module.initialize();
957          }
958          module.invoke(query);
959        }
960        else {
961          if (instance !== undefined) {
962            instance.invoke('destroy');
963          }
964          module.initialize();
965        }
966      })
967    ;
968    return (returnedValue !== undefined)
969      ? returnedValue
970      : this
971      ;
972  };
973
974  $.fn.calendar.settings = {
975
976    name: 'Calendar',
977    namespace: 'calendar',
978
979    silent: false,
980    debug: false,
981    verbose: false,
982    performance: false,
983
984    type: 'datetime',     // picker type, can be 'datetime', 'date', 'time', 'month', or 'year'
985    firstDayOfWeek: 0,    // day for first day column (0 = Sunday)
986    constantHeight: true, // add rows to shorter months to keep day calendar height consistent (6 rows)
987    today: false,         // show a 'today/now' button at the bottom of the calendar
988    closable: true,       // close the popup after selecting a date/time
989    monthFirst: true,     // month before day when parsing/converting date from/to text
990    touchReadonly: true,  // set input to readonly on touch devices
991    inline: false,        // create the calendar inline instead of inside a popup
992    on: null,             // when to show the popup (defaults to 'focus' for input, 'click' for others)
993    initialDate: null,    // date to display initially when no date is selected (null = now)
994    startMode: false,     // display mode to start in, can be 'year', 'month', 'day', 'hour', 'minute' (false = 'day')
995    minDate: null,        // minimum date/time that can be selected, dates/times before are disabled
996    maxDate: null,        // maximum date/time that can be selected, dates/times after are disabled
997    ampm: true,           // show am/pm in time mode
998    disableYear: false,   // disable year selection mode
999    disableMonth: false,  // disable month selection mode
1000    disableMinute: false, // disable minute selection mode
1001    formatInput: true,    // format the input text upon input blur and module creation
1002    startCalendar: null,  // jquery object or selector for another calendar that represents the start date of a date range
1003    endCalendar: null,    // jquery object or selector for another calendar that represents the end date of a date range
1004    multiMonth: 1,        // show multiple months when in 'day' mode
1005
1006    // popup options ('popup', 'on', 'hoverable', and show/hide callbacks are overridden)
1007    popupOptions: {
1008      position: 'bottom left',
1009      lastResort: 'bottom left',
1010      prefer: 'opposite',
1011      hideOnScroll: false
1012    },
1013
1014    text: {
1015      days: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
1016      months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
1017      monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
1018      today: 'Today',
1019      now: 'Now',
1020      am: 'AM',
1021      pm: 'PM'
1022    },
1023
1024    formatter: {
1025      header: function (date, mode, settings) {
1026        return mode === 'year' ? settings.formatter.yearHeader(date, settings) :
1027          mode === 'month' ? settings.formatter.monthHeader(date, settings) :
1028            mode === 'day' ? settings.formatter.dayHeader(date, settings) :
1029              mode === 'hour' ? settings.formatter.hourHeader(date, settings) :
1030                settings.formatter.minuteHeader(date, settings);
1031      },
1032      yearHeader: function (date, settings) {
1033        var decadeYear = Math.ceil(date.getFullYear() / 10) * 10;
1034        return (decadeYear - 9) + ' - ' + (decadeYear + 2);
1035      },
1036      monthHeader: function (date, settings) {
1037        return date.getFullYear();
1038      },
1039      dayHeader: function (date, settings) {
1040        var month = settings.text.months[date.getMonth()];
1041        var year = date.getFullYear();
1042        return month + ' ' + year;
1043      },
1044      hourHeader: function (date, settings) {
1045        return settings.formatter.date(date, settings);
1046      },
1047      minuteHeader: function (date, settings) {
1048        return settings.formatter.date(date, settings);
1049      },
1050      dayColumnHeader: function (day, settings) {
1051        return settings.text.days[day];
1052      },
1053      datetime: function (date, settings) {
1054        if (!date) {
1055          return '';
1056        }
1057        var day = settings.type === 'time' ? '' : settings.formatter.date(date, settings);
1058        var time = settings.type.indexOf('time') < 0 ? '' : settings.formatter.time(date, settings, false);
1059        var separator = settings.type === 'datetime' ? ' ' : '';
1060        return day + separator + time;
1061      },
1062      date: function (date, settings) {
1063        if (!date) {
1064          return '';
1065        }
1066        var day = date.getDate();
1067        var month = settings.text.months[date.getMonth()];
1068        var year = date.getFullYear();
1069        return settings.type === 'year' ? year :
1070          settings.type === 'month' ? month + ' ' + year :
1071          (settings.monthFirst ? month + ' ' + day : day + ' ' + month) + ', ' + year;
1072      },
1073      time: function (date, settings, forCalendar) {
1074        if (!date) {
1075          return '';
1076        }
1077        var hour = date.getHours();
1078        var minute = date.getMinutes();
1079        var ampm = '';
1080        if (settings.ampm) {
1081          ampm = ' ' + (hour < 12 ? settings.text.am : settings.text.pm);
1082          hour = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
1083        }
1084        return hour + ':' + (minute < 10 ? '0' : '') + minute + ampm;
1085      },
1086      today: function (settings) {
1087        return settings.type === 'date' ? settings.text.today : settings.text.now;
1088      }
1089    },
1090
1091    parser: {
1092      date: function (text, settings) {
1093        if (!text) {
1094          return null;
1095        }
1096        text = ('' + text).trim().toLowerCase();
1097        if (text.length === 0) {
1098          return null;
1099        }
1100
1101        var i, j, k;
1102        var minute = -1, hour = -1, day = -1, month = -1, year = -1;
1103        var isAm = undefined;
1104
1105        var isTimeOnly = settings.type === 'time';
1106        var isDateOnly = settings.type.indexOf('time') < 0;
1107
1108        var words = text.split(settings.regExp.dateWords);
1109        var numbers = text.split(settings.regExp.dateNumbers);
1110
1111        if (!isDateOnly) {
1112          //am/pm
1113          isAm = $.inArray(settings.text.am.toLowerCase(), words) >= 0 ? true :
1114            $.inArray(settings.text.pm.toLowerCase(), words) >= 0 ? false : undefined;
1115
1116          //time with ':'
1117          for (i = 0; i < numbers.length; i++) {
1118            var number = numbers[i];
1119            if (number.indexOf(':') >= 0) {
1120              if (hour < 0 || minute < 0) {
1121                var parts = number.split(':');
1122                for (k = 0; k < Math.min(2, parts.length); k++) {
1123                  j = parseInt(parts[k]);
1124                  if (isNaN(j)) {
1125                    j = 0;
1126                  }
1127                  if (k === 0) {
1128                    hour = j % 24;
1129                  } else {
1130                    minute = j % 60;
1131                  }
1132                }
1133              }
1134              numbers.splice(i, 1);
1135            }
1136          }
1137        }
1138
1139        if (!isTimeOnly) {
1140          //textual month
1141          for (i = 0; i < words.length; i++) {
1142            var word = words[i];
1143            if (word.length <= 0) {
1144              continue;
1145            }
1146            word = word.substring(0, Math.min(word.length, 3));
1147            for (j = 0; j < settings.text.months.length; j++) {
1148              var monthString = settings.text.months[j];
1149              monthString = monthString.substring(0, Math.min(word.length, Math.min(monthString.length, 3))).toLowerCase();
1150              if (monthString === word) {
1151                month = j + 1;
1152                break;
1153              }
1154            }
1155            if (month >= 0) {
1156              break;
1157            }
1158          }
1159
1160          //year > 59
1161          for (i = 0; i < numbers.length; i++) {
1162            j = parseInt(numbers[i]);
1163            if (isNaN(j)) {
1164              continue;
1165            }
1166            if (j > 59) {
1167              year = j;
1168              numbers.splice(i, 1);
1169              break;
1170            }
1171          }
1172
1173          //numeric month
1174          if (month < 0) {
1175            for (i = 0; i < numbers.length; i++) {
1176              k = i > 1 || settings.monthFirst ? i : i === 1 ? 0 : 1;
1177              j = parseInt(numbers[k]);
1178              if (isNaN(j)) {
1179                continue;
1180              }
1181              if (1 <= j && j <= 12) {
1182                month = j;
1183                numbers.splice(k, 1);
1184                break;
1185              }
1186            }
1187          }
1188
1189          //day
1190          for (i = 0; i < numbers.length; i++) {
1191            j = parseInt(numbers[i]);
1192            if (isNaN(j)) {
1193              continue;
1194            }
1195            if (1 <= j && j <= 31) {
1196              day = j;
1197              numbers.splice(i, 1);
1198              break;
1199            }
1200          }
1201
1202          //year <= 59
1203          if (year < 0) {
1204            for (i = numbers.length - 1; i >= 0; i--) {
1205              j = parseInt(numbers[i]);
1206              if (isNaN(j)) {
1207                continue;
1208              }
1209              if (j < 99) {
1210                j += 2000;
1211              }
1212              year = j;
1213              numbers.splice(i, 1);
1214              break;
1215            }
1216          }
1217        }
1218
1219        if (!isDateOnly) {
1220          //hour
1221          if (hour < 0) {
1222            for (i = 0; i < numbers.length; i++) {
1223              j = parseInt(numbers[i]);
1224              if (isNaN(j)) {
1225                continue;
1226              }
1227              if (0 <= j && j <= 23) {
1228                hour = j;
1229                numbers.splice(i, 1);
1230                break;
1231              }
1232            }
1233          }
1234
1235          //minute
1236          if (minute < 0) {
1237            for (i = 0; i < numbers.length; i++) {
1238              j = parseInt(numbers[i]);
1239              if (isNaN(j)) {
1240                continue;
1241              }
1242              if (0 <= j && j <= 59) {
1243                minute = j;
1244                numbers.splice(i, 1);
1245                break;
1246              }
1247            }
1248          }
1249        }
1250
1251        if (minute < 0 && hour < 0 && day < 0 && month < 0 && year < 0) {
1252          return null;
1253        }
1254
1255        if (minute < 0) {
1256          minute = 0;
1257        }
1258        if (hour < 0) {
1259          hour = 0;
1260        }
1261        if (day < 0) {
1262          day = 1;
1263        }
1264        if (month < 0) {
1265          month = 1;
1266        }
1267        if (year < 0) {
1268          year = new Date().getFullYear();
1269        }
1270
1271        if (isAm !== undefined) {
1272          if (isAm) {
1273            if (hour === 12) {
1274              hour = 0;
1275            }
1276          } else if (hour < 12) {
1277            hour += 12;
1278          }
1279        }
1280
1281        var date = new Date(year, month - 1, day, hour, minute);
1282        if (date.getMonth() !== month - 1 || date.getFullYear() !== year) {
1283          //month or year don't match up, switch to last day of the month
1284          date = new Date(year, month, 0, hour, minute);
1285        }
1286        return isNaN(date.getTime()) ? null : date;
1287      }
1288    },
1289
1290    // callback when date changes, return false to cancel the change
1291    onChange: function (date, text, mode) {
1292      return true;
1293    },
1294
1295    // callback before show animation, return false to prevent show
1296    onShow: function () {
1297    },
1298
1299    // callback after show animation
1300    onVisible: function () {
1301    },
1302
1303    // callback before hide animation, return false to prevent hide
1304    onHide: function () {
1305    },
1306
1307    // callback after hide animation
1308    onHidden: function () {
1309    },
1310
1311    // is the given date disabled?
1312    isDisabled: function (date, mode) {
1313      return false;
1314    },
1315
1316    selector: {
1317      popup: '.ui.popup',
1318      input: 'input',
1319      activator: 'input'
1320    },
1321
1322    regExp: {
1323      dateWords: /[^A-Za-z\u00C0-\u024F]+/g,
1324      dateNumbers: /[^\d:]+/g
1325    },
1326
1327    error: {
1328      popup: 'UI Popup, a required component is not included in this page',
1329      method: 'The method you called is not defined.'
1330    },
1331
1332    className: {
1333      calendar: 'calendar',
1334      active: 'active',
1335      popup: 'ui popup',
1336      grid: 'ui equal width grid',
1337      column: 'column',
1338      table: 'ui celled center aligned unstackable table',
1339      prev: 'prev link',
1340      next: 'next link',
1341      prevIcon: 'chevron left icon',
1342      nextIcon: 'chevron right icon',
1343      link: 'link',
1344      cell: 'link',
1345      disabledCell: 'disabled',
1346      adjacentCell: 'adjacent',
1347      activeCell: 'active',
1348      rangeCell: 'range',
1349      focusCell: 'focus',
1350      todayCell: 'today',
1351      today: 'today link'
1352    },
1353
1354    metadata: {
1355      date: 'date',
1356      focusDate: 'focusDate',
1357      startDate: 'startDate',
1358      endDate: 'endDate',
1359      mode: 'mode',
1360      monthOffset: 'monthOffset'
1361    }
1362  };
1363
1364})(jQuery, window, document);

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.