PageSourceSearch

https://www.msab.com/wp-content/themes/msab/dist/js/vendor/lightpick.js?ver=1780463504

js msab.com collected 2026-09-24 21:56:08 UTC 45,962 bytes, 1,543 lines download raw bytes

vendor: 45,962 bytes, lines 1-1543
1/**
2 * @author: Rinat G. http://coding.kz
3 * @copyright: Copyright (c) 2019 Rinat G.
4 * @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php
5 */
6
7// Following the UMD template https://github.com/umdjs/umd/blob/master/templates/returnExportsGlobal.js
8(function(root, factory) {
9  if (typeof define === 'function' && define.amd) {
10    // AMD. Make globaly available as well
11    define(['moment'], function(moment) {
12      return factory(moment);
13    });
14  } else if (typeof module === 'object' && module.exports) {
15    // Node / Browserify
16    var moment =
17      typeof window != 'undefined' && typeof window.moment != 'undefined'
18        ? window.moment
19        : require('moment');
20    module.exports = factory(moment);
21  } else {
22    // Browser globals
23    root.Lightpick = factory(root.moment);
24  }
25})(this, function(moment) {
26  'use strict';
27
28  var document = window.document,
29    defaults = {
30      field: null,
31      secondField: null,
32      firstDay: 1,
33      parentEl: 'body',
34      lang: 'auto',
35      format: 'DD/MM/YYYY',
36      separator: ' - ',
37      numberOfMonths: 1,
38      numberOfColumns: 2,
39      singleDate: true,
40      autoclose: true,
41      repick: false,
42      startDate: null,
43      endDate: null,
44      minDate: null,
45      maxDate: null,
46      disableDates: null,
47      selectForward: false,
48      selectBackward: false,
49      minDays: null,
50      maxDays: null,
51      hoveringTooltip: true,
52      hideOnBodyClick: true,
53      footer: false,
54      disabledDatesInRange: true,
55      tooltipNights: false,
56      orientation: 'auto',
57      disableWeekends: false,
58      inline: false,
59      weekdayStyle: 'short',
60      dropdowns: {
61        years: {
62          min: 1900,
63          max: null
64        },
65        months: true
66      },
67      locale: {
68        buttons: {
69          prev: '←',
70          next: '→',
71          close: '×',
72          reset: 'Reset',
73          apply: 'Apply'
74        },
75        tooltip: {
76          one: 'day',
77          other: 'days'
78        },
79        tooltipOnDisabled: null,
80        pluralize: function(i, locale) {
81          if (typeof i === 'string') i = parseInt(i, 10);
82
83          if (i === 1 && 'one' in locale) return locale.one;
84          if ('other' in locale) return locale.other;
85
86          return '';
87        }
88      },
89
90      onSelect: null,
91      onSelectStart: null,
92      onSelectEnd: null,
93      onOpen: null,
94      onClose: null,
95      onError: null,
96      onMonthsChange: null,
97      onYearsChange: null
98    },
99    renderTopButtons = function(opts) {
100      return (
101        '<div class="lightpick__toolbar">' +
102        '' +
103        '<button type="button" class="lightpick__previous-action">' +
104        opts.locale.buttons.prev +
105        '</button>' +
106        '<button type="button" class="lightpick__next-action">' +
107        opts.locale.buttons.next +
108        '</button>' +
109        (!opts.autoclose && !opts.inline
110          ? '<button type="button" class="lightpick__close-action">' +
111            opts.locale.buttons.close +
112            '</button>'
113          : '') +
114        '</div>'
115      );
116    },
117    weekdayName = function(opts, day, weekdayStyle) {
118      return new Date(1970, 0, day, 12, 0, 0, 0).toLocaleString(opts.lang, {
119        weekday: weekdayStyle || opts.weekdayStyle
120      });
121    },
122    renderDay = function(opts, date, dummy, extraClass) {
123      if (dummy) return '<div></div>';
124
125      var date = moment(date),
126        prevMonth = moment(date).subtract(1, 'month'),
127        nextMonth = moment(date).add(1, 'month');
128
129      var day = {
130        time: moment(date).valueOf(),
131        className: ['lightpick__day', 'is-available']
132      };
133
134      if (
135        extraClass instanceof Array ||
136        Object.prototype.toString.call(extraClass) === '[object Array]'
137      ) {
138        extraClass = extraClass.filter(function(el) {
139          return (
140            [
141              'lightpick__day',
142              'is-available',
143              'is-previous-month',
144              'is-next-month'
145            ].indexOf(el) >= 0
146          );
147        });
148        day.className = day.className.concat(extraClass);
149      } else {
150        day.className.push(extraClass);
151      }
152
153      if (opts.disableDates) {
154        for (var i = 0; i < opts.disableDates.length; i++) {
155          if (
156            opts.disableDates[i] instanceof Array ||
157            Object.prototype.toString.call(opts.disableDates[i]) ===
158              '[object Array]'
159          ) {
160            var _from = moment(opts.disableDates[i][0], opts.format),
161              _to = moment(opts.disableDates[i][1], opts.format);
162
163            if (
164              _from.isValid() &&
165              _to.isValid() &&
166              date.isBetween(_from, _to, 'day', '[]')
167            ) {
168              day.className.push('is-disabled');
169            }
170          } else if (
171            moment(opts.disableDates[i], opts.format).isValid() &&
172            moment(opts.disableDates[i], opts.format).isSame(date, 'day')
173          ) {
174            day.className.push('is-disabled');
175          }
176
177          if (day.className.indexOf('is-disabled') >= 0) {
178            if (
179              opts.locale.tooltipOnDisabled &&
180              (!opts.startDate ||
181                date.isAfter(opts.startDate) ||
182                (opts.startDate && opts.endDate))
183            ) {
184              day.className.push('disabled-tooltip');
185            }
186
187            if (day.className.indexOf('is-start-date') >= 0) {
188              this.setStartDate(null);
189              this.setEndDate(null);
190            } else if (day.className.indexOf('is-end-date') >= 0) {
191              this.setEndDate(null);
192            }
193          }
194        }
195      }
196
197      if (opts.minDays && opts.startDate && !opts.endDate) {
198        if (
199          date.isBetween(
200            moment(opts.startDate).subtract(opts.minDays - 1, 'day'),
201            moment(opts.startDate).add(opts.minDays - 1, 'day'),
202            'day'
203          )
204        ) {
205          day.className.push('is-disabled');
206
207          if (opts.selectForward && date.isSameOrAfter(opts.startDate)) {
208            day.className.push('is-forward-selected');
209            day.className.push('is-in-range');
210          }
211        }
212      }
213
214      if (opts.maxDays && opts.startDate && !opts.endDate) {
215        if (
216          date.isSameOrBefore(
217            moment(opts.startDate).subtract(opts.maxDays, 'day'),
218            'day'
219          )
220        ) {
221          day.className.push('is-disabled');
222        } else if (
223          date.isSameOrAfter(
224            moment(opts.startDate).add(opts.maxDays, 'day'),
225            'day'
226          )
227        ) {
228          day.className.push('is-disabled');
229        }
230      }
231
232      if (
233        opts.repick &&
234        (opts.minDays || opts.maxDays) &&
235        opts.startDate &&
236        opts.endDate
237      ) {
238        var tempStartDate = moment(
239          opts.repickTrigger == opts.field ? opts.endDate : opts.startDate
240        );
241
242        if (opts.minDays) {
243          if (
244            date.isBetween(
245              moment(tempStartDate).subtract(opts.minDays - 1, 'day'),
246              moment(tempStartDate).add(opts.minDays - 1, 'day'),
247              'day'
248            )
249          ) {
250            day.className.push('is-disabled');
251          }
252        }
253
254        if (opts.maxDays) {
255          if (
256            date.isSameOrBefore(
257              moment(tempStartDate).subtract(opts.maxDays, 'day'),
258              'day'
259            )
260          ) {
261            day.className.push('is-disabled');
262          } else if (
263            date.isSameOrAfter(
264              moment(tempStartDate).add(opts.maxDays, 'day'),
265              'day'
266            )
267          ) {
268            day.className.push('is-disabled');
269          }
270        }
271      }
272
273      if (date.isSame(new Date(), 'day')) {
274        day.className.push('is-today');
275      }
276
277      if (date.isSame(opts.startDate, 'day')) {
278        day.className.push('is-start-date');
279      }
280
281      if (date.isSame(opts.endDate, 'day')) {
282        day.className.push('is-end-date');
283      }
284
285      if (
286        opts.startDate &&
287        opts.endDate &&
288        date.isBetween(opts.startDate, opts.endDate, 'day', '[]')
289      ) {
290        day.className.push('is-in-range');
291      }
292
293      if (moment().isSame(date, 'month')) {
294      } else if (prevMonth.isSame(date, 'month')) {
295        day.className.push('is-previous-month');
296      } else if (nextMonth.isSame(date, 'month')) {
297        day.className.push('is-next-month');
298      }
299
300      if (opts.minDate && date.isBefore(opts.minDate, 'day')) {
301        day.className.push('is-disabled');
302      }
303
304      if (opts.maxDate && date.isAfter(opts.maxDate, 'day')) {
305        day.className.push('is-disabled');
306      }
307
308      if (
309        opts.selectForward &&
310        !opts.singleDate &&
311        opts.startDate &&
312        !opts.endDate &&
313        date.isBefore(opts.startDate, 'day')
314      ) {
315        day.className.push('is-disabled');
316      }
317
318      if (
319        opts.selectBackward &&
320        !opts.singleDate &&
321        opts.startDate &&
322        !opts.endDate &&
323        date.isAfter(opts.startDate, 'day')
324      ) {
325        day.className.push('is-disabled');
326      }
327
328      if (
329        opts.disableWeekends &&
330        (date.isoWeekday() == 6 || date.isoWeekday() == 7)
331      ) {
332        day.className.push('is-disabled');
333      }
334
335      day.className = day.className.filter(function(value, index, self) {
336        return self.indexOf(value) === index;
337      });
338
339      if (
340        day.className.indexOf('is-disabled') >= 0 &&
341        day.className.indexOf('is-available') >= 0
342      ) {
343        day.className.splice(day.className.indexOf('is-available'), 1);
344      }
345
346      var div = document.createElement('div');
347      div.className = day.className.join(' ');
348      div.innerHTML = date.get('date');
349      div.setAttribute('data-time', day.time);
350
351      return div.outerHTML;
352    },
353    renderMonthsList = function(date, opts) {
354      var d = moment(date),
355        select = document.createElement('select');
356
357      for (var idx = 0; idx < 12; idx++) {
358        d.set('month', idx);
359
360        var option = document.createElement('option');
361        option.value = d.toDate().getMonth();
362        option.text = d.toDate().toLocaleString(opts.lang, { month: 'long' });
363
364        if (idx === date.toDate().getMonth()) {
365          option.setAttribute('selected', 'selected');
366        }
367
368        select.appendChild(option);
369      }
370
371      select.className = 'lightpick__select lightpick__select-months';
372
373      // for text align to right
374      select.dir = 'rtl';
375
376      if (!opts.dropdowns || !opts.dropdowns.months) {
377        select.disabled = true;
378      }
379
380      return select.outerHTML;
381    },
382    renderYearsList = function(date, opts) {
383      var d = moment(date),
384        select = document.createElement('select'),
385        years =
386          opts.dropdowns && opts.dropdowns.years ? opts.dropdowns.years : null,
387        minYear = years && years.min ? years.min : 1900,
388        maxYear =
389          years && years.max
390            ? years.max
391            : Number.parseInt(moment().format('YYYY'));
392
393      if (Number.parseInt(date.format('YYYY')) < minYear) {
394        minYear = Number.parseInt(date.format('YYYY'));
395      }
396
397      if (Number.parseInt(date.format('YYYY')) > maxYear) {
398        maxYear = Number.parseInt(date.format('YYYY'));
399      }
400
401      for (var idx = minYear; idx <= maxYear; idx++) {
402        d.set('year', idx);
403
404        var option = document.createElement('option');
405        option.value = d.toDate().getFullYear();
406        option.text = d.toDate().getFullYear();
407
408        if (idx === date.toDate().getFullYear()) {
409          option.setAttribute('selected', 'selected');
410        }
411
412        select.appendChild(option);
413      }
414
415      select.className = 'lightpick__select lightpick__select-years';
416
417      if (!opts.dropdowns || !opts.dropdowns.years) {
418        select.disabled = true;
419      }
420
421      return select.outerHTML;
422    },
423    renderCalendar = function(el, opts) {
424      var html = '',
425        monthDate = moment(opts.calendar[0]);
426
427      for (var i = 0; i < opts.numberOfMonths; i++) {
428        var day = moment(monthDate);
429
430        html += '<section class="lightpick__month">';
431        html += '<div class="lightpick__month-title-bar">';
432        html +=
433          '<div class="lightpick__month-title">' +
434          renderMonthsList(day, opts) +
435          renderYearsList(day, opts) +
436          '</div>';
437
438        if (opts.numberOfMonths === 1) {
439          html += renderTopButtons(opts, 'days');
440        }
441
442        html += '</div>'; // lightpick__month-title-bar
443
444        html += '<div class="lightpick__days-of-the-week">';
445        for (var w = opts.firstDay + 4; w < 7 + opts.firstDay + 4; ++w) {
446          html +=
447            '<div class="lightpick__day-of-the-week" title="' +
448            weekdayName(opts, w, 'long') +
449            '">' +
450            weekdayName(opts, w) +
451            '</div>';
452        }
453        html += '</div>'; // lightpick__days-of-the-week
454
455        html += '<div class="lightpick__days">';
456
457        if (day.isoWeekday() !== opts.firstDay) {
458          var prevDays =
459              day.isoWeekday() - opts.firstDay > 0
460                ? day.isoWeekday() - opts.firstDay
461                : day.isoWeekday(),
462            prevMonth = moment(day).subtract(prevDays, 'day'),
463            daysInMonth = prevMonth.daysInMonth();
464
465          for (var d = prevMonth.get('date'); d <= daysInMonth; d++) {
466            html += renderDay(opts, prevMonth, i > 0, 'is-previous-month');
467
468            prevMonth.add(1, 'day');
469          }
470        }
471
472        var daysInMonth = day.daysInMonth(),
473          today = new Date();
474
475        for (var d = 0; d < daysInMonth; d++) {
476          html += renderDay(opts, day);
477
478          day.add(1, 'day');
479        }
480
481        var nextMonth = moment(day),
482          nextDays = 7 - nextMonth.isoWeekday() + opts.firstDay;
483
484        if (nextDays < 7) {
485          for (var d = nextMonth.get('date'); d <= nextDays; d++) {
486            html += renderDay(
487              opts,
488              nextMonth,
489              i < opts.numberOfMonths - 1,
490              'is-next-month'
491            );
492
493            nextMonth.add(1, 'day');
494          }
495        }
496
497        html += '</div>'; // lightpick__days
498
499        html += '</section>'; // lightpick__month
500
501        monthDate.add(1, 'month');
502      }
503
504      opts.calendar[1] = moment(monthDate);
505
506      el.querySelector('.lightpick__months').innerHTML = html;
507    },
508    updateDates = function(el, opts) {
509      var days = el.querySelectorAll('.lightpick__day');
510      [].forEach.call(days, function(day) {
511        day.outerHTML = renderDay(
512          opts,
513          parseInt(day.getAttribute('data-time')),
514          false,
515          day.className.split(' ')
516        );
517      });
518
519      checkDisabledDatesInRange(el, opts);
520    },
521    checkDisabledDatesInRange = function(el, opts) {
522      if (
523        opts.disabledDatesInRange ||
524        !opts.startDate ||
525        opts.endDate ||
526        !opts.disableDates
527      )
528        return;
529
530      var days = el.querySelectorAll('.lightpick__day'),
531        disabledArray = opts.disableDates.map(function(entry) {
532          return entry instanceof Array ||
533            Object.prototype.toString.call(entry) === '[object Array]'
534            ? entry[0]
535            : entry;
536        }),
537        closestPrev = moment(
538          disabledArray
539            .filter(function(d) {
540              return moment(d).isBefore(opts.startDate);
541            })
542            .sort(function(a, b) {
543              return moment(b).isAfter(moment(a));
544            })[0]
545        ),
546        closestNext = moment(
547          disabledArray
548            .filter(function(d) {
549              return moment(d).isAfter(opts.startDate);
550            })
551            .sort(function(a, b) {
552              return moment(a).isAfter(moment(b));
553            })[0]
554        );
555
556      [].forEach.call(days, function(dayCell) {
557        var day = moment(parseInt(dayCell.getAttribute('data-time')));
558        if (
559          (closestPrev &&
560            day.isBefore(closestPrev) &&
561            opts.startDate.isAfter(closestPrev)) ||
562          (closestNext &&
563            day.isAfter(closestNext) &&
564            closestNext.isAfter(opts.startDate))
565        ) {
566          dayCell.classList.remove('is-available');
567          dayCell.classList.add('is-disabled');
568        }
569      });
570    },
571    Lightpick = function(options) {
572      var self = this,
573        opts = self.config(options);
574
575      self.el = document.createElement('section');
576
577      self.el.className =
578        'lightpick lightpick--' + opts.numberOfColumns + '-columns is-hidden';
579
580      if (opts.inline) {
581        self.el.className += ' lightpick--inlined';
582      }
583
584      var html =
585        '<div class="lightpick__inner">' +
586        (opts.numberOfMonths > 1 ? renderTopButtons(opts, 'days') : '') +
587        '<div class="lightpick__months"></div>' +
588        '<div class="lightpick__tooltip" style="visibility: hidden"></div>';
589
590      if (opts.footer) {
591        html += '<div class="lightpick__footer">';
592        if (opts.footer === true) {
593          html +=
594            '<button type="button" class="lightpick__reset-action">' +
595            opts.locale.buttons.reset +
596            '</button>';
597          html += '<div class="lightpick__footer-message"></div>';
598          html +=
599            '<button type="button" class="lightpick__apply-action">' +
600            opts.locale.buttons.apply +
601            '</button>';
602        } else {
603          html += opts.footer;
604        }
605        html += '</div>';
606      }
607
608      html += '</div>';
609
610      self.el.innerHTML = html;
611
612      if (opts.parentEl instanceof Node) {
613        opts.parentEl.appendChild(self.el);
614      } else if (opts.parentEl === 'body' && opts.inline) {
615        opts.field.parentNode.appendChild(self.el);
616      } else {
617        document.querySelector(opts.parentEl).appendChild(self.el);
618      }
619
620      self._onMouseDown = function(e) {
621        if (!self.isShowing) {
622          return;
623        }
624
625        e = e || window.event;
626        var target = e.target || e.srcElement;
627        if (!target) {
628          return;
629        }
630
631        e.stopPropagation();
632
633        if (!target.classList.contains('lightpick__select')) {
634          e.preventDefault();
635        }
636
637        var opts = self._opts;
638
639        if (
640          target.classList.contains('lightpick__day') &&
641          target.classList.contains('is-available')
642        ) {
643          var day = moment(parseInt(target.getAttribute('data-time')));
644
645          if (
646            !opts.disabledDatesInRange &&
647            opts.disableDates &&
648            opts.startDate
649          ) {
650            var start = day.isAfter(opts.startDate)
651                ? moment(opts.startDate)
652                : moment(day),
653              end = day.isAfter(opts.startDate)
654                ? moment(day)
655                : moment(opts.startDate),
656              isInvalidRange = opts.disableDates.filter(function(d) {
657                if (
658                  d instanceof Array ||
659                  Object.prototype.toString.call(d) === '[object Array]'
660                ) {
661                  var _from = moment(d[0]),
662                    _to = moment(d[1]);
663
664                  return (
665                    _from.isValid() &&
666                    _to.isValid() &&
667                    (_from.isBetween(start, end, 'day', '[]') ||
668                      _to.isBetween(start, end, 'day', '[]'))
669                  );
670                }
671
672                return moment(d).isBetween(start, end, 'day', '[]');
673              });
674
675            if (isInvalidRange.length) {
676              self.setStartDate(null);
677              self.setEndDate(null);
678
679              target.dispatchEvent(new Event('mousedown'));
680              self.el.querySelector('.lightpick__tooltip').style.visibility =
681                'hidden';
682
683              updateDates(self.el, opts);
684              return;
685            }
686          }
687
688          if (
689            opts.singleDate ||
690            (!opts.startDate && !opts.endDate) ||
691            (opts.startDate && opts.endDate)
692          ) {
693            if (opts.repick && opts.startDate && opts.endDate) {
694              if (opts.repickTrigger === opts.field) {
695                self.setStartDate(day);
696                target.classList.add('is-start-date');
697              } else {
698                self.setEndDate(day);
699                target.classList.add('is-end-date');
700              }
701
702              if (opts.startDate.isAfter(opts.endDate)) {
703                self.swapDate();
704              }
705
706              if (opts.autoclose) {
707                setTimeout(function() {
708                  self.hide();
709                }, 100);
710              }
711            } else {
712              self.setStartDate(day);
713              self.setEndDate(null);
714
715              target.classList.add('is-start-date');
716
717              if (opts.singleDate && opts.autoclose) {
718                setTimeout(function() {
719                  self.hide();
720                }, 100);
721              } else if (!opts.singleDate || opts.inline || !opts.autoclose) {
722                updateDates(self.el, opts);
723              }
724            }
725          } else if (opts.startDate && !opts.endDate) {
726            self.setEndDate(day);
727
728            if (opts.startDate.isAfter(opts.endDate)) {
729              self.swapDate();
730            }
731
732            target.classList.add('is-end-date');
733
734            if (opts.autoclose) {
735              setTimeout(function() {
736                self.hide();
737              }, 100);
738            } else {
739              updateDates(self.el, opts);
740            }
741          }
742
743          if (!opts.disabledDatesInRange) {
744            if (
745              self.el.querySelectorAll('.lightpick__day.is-available')
746                .length === 0
747            ) {
748              self.setStartDate(null);
749              updateDates(self.el, opts);
750
751              if (opts.footer) {
752                if (typeof self._opts.onError === 'function') {
753                  self._opts.onError.call(self, 'Invalid range');
754                } else {
755                  var footerMessage = self.el.querySelector(
756                    '.lightpick__footer-message'
757                  );
758
759                  if (footerMessage) {
760                    footerMessage.innerHTML = opts.locale.not_allowed_range;
761
762                    setTimeout(function() {
763                      footerMessage.innerHTML = '';
764                    }, 3000);
765                  }
766                }
767              }
768            }
769          }
770        } else if (target.classList.contains('lightpick__previous-action')) {
771          self.prevMonth();
772        } else if (target.classList.contains('lightpick__next-action')) {
773          self.nextMonth();
774        } else if (
775          target.classList.contains('lightpick__close-action') ||
776          target.classList.contains('lightpick__apply-action')
777        ) {
778          self.hide();
779        } else if (target.classList.contains('lightpick__reset-action')) {
780          self.reset();
781        }
782      };
783      self._onMouseEnter = function(e) {
784        if (!self.isShowing) {
785          return;
786        }
787
788        e = e || window.event;
789        var target = e.target || e.srcElement;
790        if (!target) {
791          return;
792        }
793
794        var opts = self._opts;
795
796        if (
797          target.classList.contains('lightpick__day') &&
798          target.classList.contains('disabled-tooltip') &&
799          opts.locale.tooltipOnDisabled
800        ) {
801          self.showTooltip(target, opts.locale.tooltipOnDisabled);
802          return;
803        } else {
804          self.hideTooltip();
805        }
806
807        if (opts.singleDate || (!opts.startDate && !opts.endDate)) {
808          return;
809        }
810
811        if (
812          !target.classList.contains('lightpick__day') &&
813          !target.classList.contains('is-available')
814        ) {
815          return;
816        }
817
818        if ((opts.startDate && !opts.endDate) || opts.repick) {
819          var hoverDate = moment(parseInt(target.getAttribute('data-time')));
820
821          if (!hoverDate.isValid()) {
822            return;
823          }
824
825          var startDate =
826            (opts.startDate && !opts.endDate) ||
827            (opts.repick && opts.repickTrigger === opts.secondField)
828              ? opts.startDate
829              : opts.endDate;
830
831          var days = self.el.querySelectorAll('.lightpick__day');
832          [].forEach.call(days, function(day) {
833            var dt = moment(parseInt(day.getAttribute('data-time')));
834
835            day.classList.remove('is-flipped');
836
837            if (
838              dt.isValid() &&
839              dt.isSameOrAfter(startDate, 'day') &&
840              dt.isSameOrBefore(hoverDate, 'day')
841            ) {
842              day.classList.add('is-in-range');
843
844              if (
845                opts.repickTrigger === opts.field &&
846                dt.isSameOrAfter(opts.endDate)
847              ) {
848                day.classList.add('is-flipped');
849              }
850            } else if (
851              dt.isValid() &&
852              dt.isSameOrAfter(hoverDate, 'day') &&
853              dt.isSameOrBefore(startDate, 'day')
854            ) {
855              day.classList.add('is-in-range');
856
857              if (
858                ((opts.startDate && !opts.endDate) ||
859                  opts.repickTrigger === opts.secondField) &&
860                dt.isSameOrBefore(opts.startDate)
861              ) {
862                day.classList.add('is-flipped');
863              }
864            } else {
865              day.classList.remove('is-in-range');
866            }
867
868            if (
869              opts.startDate &&
870              opts.endDate &&
871              opts.repick &&
872              opts.repickTrigger === opts.field
873            ) {
874              day.classList.remove('is-start-date');
875            } else {
876              day.classList.remove('is-end-date');
877            }
878          });
879
880          if (opts.hoveringTooltip) {
881            days = Math.abs(
882              hoverDate.isAfter(startDate)
883                ? hoverDate.diff(startDate, 'day')
884                : startDate.diff(hoverDate, 'day')
885            );
886
887            if (!opts.tooltipNights) {
888              days += 1;
889            }
890
891            var tooltip = self.el.querySelector('.lightpick__tooltip');
892
893            if (days > 0 && !target.classList.contains('is-disabled')) {
894              var pluralText = '';
895              if (typeof opts.locale.pluralize === 'function') {
896                pluralText = opts.locale.pluralize.call(
897                  self,
898                  days,
899                  opts.locale.tooltip
900                );
901              }
902
903              self.showTooltip(target, days + ' ' + pluralText);
904            } else {
905              self.hideTooltip();
906            }
907          }
908
909          if (
910            opts.startDate &&
911            opts.endDate &&
912            opts.repick &&
913            opts.repickTrigger === opts.field
914          ) {
915            target.classList.add('is-start-date');
916          } else {
917            target.classList.add('is-end-date');
918          }
919        }
920      };
921      self._onChange = function(e) {
922        e = e || window.event;
923        var target = e.target || e.srcElement;
924        if (!target) {
925          return;
926        }
927
928        if (target.classList.contains('lightpick__select-months')) {
929          if (typeof self._opts.onMonthsChange === 'function') {
930            self._opts.onMonthsChange.call(this, target.value);
931          }
932
933          self.gotoMonth(target.value);
934        } else if (target.classList.contains('lightpick__select-years')) {
935          if (typeof self._opts.onYearsChange === 'function') {
936            self._opts.onYearsChange.call(this, target.value);
937          }
938
939          self.gotoYear(target.value);
940        }
941      };
942
943      self._onInputChange = function(e) {
944        var target = e.target || e.srcElement;
945
946        if (self._opts.singleDate) {
947          if (!self._opts.autoclose) {
948            self.gotoDate(opts.field.value);
949          }
950        }
951
952        self.syncFields();
953
954        if (!self.isShowing) {
955          self.show();
956        }
957      };
958
959      self._onInputFocus = function(e) {
960        var target = e.target || e.srcElement;
961
962        self.show(target);
963      };
964
965      self._onInputClick = function(e) {
966        var target = e.target || e.srcElement;
967
968        self.show(target);
969      };
970
971      self._onClick = function(e) {
972        e = e || window.event;
973        var target = e.target || e.srcElement,
974          parentEl = target;
975
976        if (!target) {
977          return;
978        }
979
980        do {
981          if (
982            (parentEl.classList && parentEl.classList.contains('lightpick')) ||
983            parentEl === opts.field ||
984            (opts.secondField && parentEl === opts.secondField)
985          ) {
986            return;
987          }
988        } while ((parentEl = parentEl.parentNode));
989
990        if (
991          self.isShowing &&
992          opts.hideOnBodyClick &&
993          target !== opts.field &&
994          parentEl !== opts.field
995        ) {
996          self.hide();
997        }
998      };
999
1000      self.showTooltip = function(target, text) {
1001        var tooltip = self.el.querySelector('.lightpick__tooltip');
1002
1003        var hasParentEl = self.el.classList.contains('lightpick--inlined'),
1004          dayBounding = target.getBoundingClientRect(),
1005          pickerBouding = hasParentEl
1006            ? self.el.parentNode.getBoundingClientRect()
1007            : self.el.getBoundingClientRect(),
1008          _left = dayBounding.left - pickerBouding.left + dayBounding.width / 2,
1009          _top = dayBounding.top - pickerBouding.top;
1010
1011        tooltip.style.visibility = 'visible';
1012        tooltip.textContent = text;
1013
1014        var tooltipBounding = tooltip.getBoundingClientRect();
1015
1016        _top -= tooltipBounding.height;
1017        _left -= tooltipBounding.width / 2;
1018
1019        setTimeout(function() {
1020          tooltip.style.top = _top + 'px';
1021          tooltip.style.left = _left + 'px';
1022        }, 10);
1023      };
1024
1025      self.hideTooltip = function() {
1026        var tooltip = self.el.querySelector('.lightpick__tooltip');
1027        tooltip.style.visibility = 'hidden';
1028      };
1029
1030      self.el.addEventListener('mousedown', self._onMouseDown, true);
1031      self.el.addEventListener('mouseenter', self._onMouseEnter, true);
1032      self.el.addEventListener('touchend', self._onMouseDown, true);
1033      self.el.addEventListener('change', self._onChange, true);
1034
1035      if (opts.inline) {
1036        self.show();
1037      } else {
1038        self.hide();
1039      }
1040
1041      opts.field.addEventListener('change', self._onInputChange);
1042      opts.field.addEventListener('click', self._onInputClick);
1043      opts.field.addEventListener('focus', self._onInputFocus);
1044
1045      if (opts.secondField) {
1046        opts.secondField.addEventListener('change', self._onInputChange);
1047        opts.secondField.addEventListener('click', self._onInputClick);
1048        opts.secondField.addEventListener('focus', self._onInputFocus);
1049      }
1050    };
1051
1052  Lightpick.prototype = {
1053    config: function(options) {
1054      var opts = Object.assign({}, defaults, options);
1055
1056      opts.field = opts.field && opts.field.nodeName ? opts.field : null;
1057
1058      opts.calendar = [moment().set('date', 1)];
1059
1060      if (opts.numberOfMonths === 1 && opts.numberOfColumns > 1) {
1061        opts.numberOfColumns = 1;
1062      }
1063
1064      opts.minDate =
1065        opts.minDate && moment(opts.minDate, opts.format).isValid()
1066          ? moment(opts.minDate, opts.format)
1067          : null;
1068
1069      opts.maxDate =
1070        opts.maxDate && moment(opts.maxDate, opts.format).isValid()
1071          ? moment(opts.maxDate, opts.format)
1072          : null;
1073
1074      if (opts.lang === 'auto') {
1075        var browserLang = navigator.language || navigator.userLanguage;
1076        if (browserLang) {
1077          opts.lang = browserLang;
1078        } else {
1079          opts.lang = 'en-US';
1080        }
1081      }
1082
1083      if (opts.secondField && opts.singleDate) {
1084        opts.singleDate = false;
1085      }
1086
1087      if (opts.hoveringTooltip && opts.singleDate) {
1088        opts.hoveringTooltip = false;
1089      }
1090
1091      if (
1092        Object.prototype.toString.call(options.locale) === '[object Object]'
1093      ) {
1094        opts.locale = Object.assign({}, defaults.locale, options.locale);
1095      }
1096
1097      if (window.innerWidth < 480 && opts.numberOfMonths > 1) {
1098        opts.numberOfMonths = 1;
1099        opts.numberOfColumns = 1;
1100      }
1101
1102      if (opts.repick && !opts.secondField) {
1103        opts.repick = false;
1104      }
1105
1106      if (opts.inline) {
1107        opts.autoclose = false;
1108        opts.hideOnBodyClick = false;
1109      }
1110
1111      this._opts = Object.assign({}, opts);
1112
1113      this.syncFields();
1114
1115      this.setStartDate(this._opts.startDate, true);
1116      this.setEndDate(this._opts.endDate, true);
1117
1118      return this._opts;
1119    },
1120
1121    syncFields: function() {
1122      if (this._opts.singleDate || this._opts.secondField) {
1123        if (moment(this._opts.field.value, this._opts.format).isValid()) {
1124          this._opts.startDate = moment(
1125            this._opts.field.value,
1126            this._opts.format
1127          );
1128        }
1129
1130        if (
1131          this._opts.secondField &&
1132          moment(this._opts.secondField.value, this._opts.format).isValid()
1133        ) {
1134          this._opts.endDate = moment(
1135            this._opts.secondField.value,
1136            this._opts.format
1137          );
1138        }
1139      } else {
1140        var dates = this._opts.field.value.split(this._opts.separator);
1141
1142        if (dates.length === 2) {
1143          if (moment(dates[0], this._opts.format).isValid()) {
1144            this._opts.startDate = moment(dates[0], this._opts.format);
1145          }
1146
1147          if (moment(dates[1], this._opts.format).isValid()) {
1148            this._opts.endDate = moment(dates[1], this._opts.format);
1149          }
1150        }
1151      }
1152    },
1153
1154    swapDate: function() {
1155      var tmp = moment(this._opts.startDate);
1156      this.setDateRange(this._opts.endDate, tmp);
1157    },
1158
1159    gotoToday: function() {
1160      this.gotoDate(new Date());
1161    },
1162
1163    gotoDate: function(date) {
1164      var date = moment(date, this._opts.format);
1165
1166      if (!date.isValid()) {
1167        date = moment();
1168      }
1169
1170      date.set('date', 1);
1171
1172      this._opts.calendar = [moment(date)];
1173
1174      renderCalendar(this.el, this._opts);
1175    },
1176
1177    gotoMonth: function(month) {
1178      if (isNaN(month)) {
1179        return;
1180      }
1181
1182      this._opts.calendar[0].set('month', month);
1183
1184      renderCalendar(this.el, this._opts);
1185    },
1186
1187    gotoYear: function(year) {
1188      if (isNaN(year)) {
1189        return;
1190      }
1191
1192      this._opts.calendar[0].set('year', year);
1193
1194      renderCalendar(this.el, this._opts);
1195    },
1196
1197    prevMonth: function() {
1198      this._opts.calendar[0] = moment(this._opts.calendar[0]).subtract(
1199        this._opts.numberOfMonths,
1200        'month'
1201      );
1202
1203      renderCalendar(this.el, this._opts);
1204
1205      checkDisabledDatesInRange(this.el, this._opts);
1206    },
1207
1208    nextMonth: function() {
1209      this._opts.calendar[0] = moment(this._opts.calendar[1]);
1210
1211      renderCalendar(this.el, this._opts);
1212
1213      checkDisabledDatesInRange(this.el, this._opts);
1214    },
1215
1216    updatePosition: function() {
1217      if (this.el.classList.contains('lightpick--inlined')) return;
1218
1219      // remove `is-hidden` class for getBoundingClientRect
1220      this.el.classList.remove('is-hidden');
1221
1222      var rect = this._opts.field.getBoundingClientRect(),
1223        calRect = this.el.getBoundingClientRect(),
1224        orientation = this._opts.orientation.split(' '),
1225        top = 0,
1226        left = 0;
1227
1228      if (orientation[0] == 'auto' || !/top|bottom/.test(orientation[0])) {
1229        if (
1230          rect.bottom + calRect.height > window.innerHeight &&
1231          window.pageYOffset > calRect.height
1232        ) {
1233          top = rect.top + window.pageYOffset - calRect.height;
1234        } else {
1235          top = rect.bottom + window.pageYOffset;
1236        }
1237      } else {
1238        top = rect[orientation[0]] + window.pageYOffset;
1239
1240        if (orientation[0] == 'top') {
1241          top -= calRect.height;
1242        }
1243      }
1244
1245      if (
1246        !/left|right/.test(orientation[0]) &&
1247        (!orientation[1] ||
1248          orientation[1] == 'auto' ||
1249          !/left|right/.test(orientation[1]))
1250      ) {
1251        if (rect.left + calRect.width > window.innerWidth) {
1252          left = rect.right + window.pageXOffset - calRect.width;
1253        } else {
1254          left = rect.left + window.pageXOffset;
1255        }
1256      } else {
1257        if (/left|right/.test(orientation[0])) {
1258          left = rect[orientation[0]] + window.pageXOffset;
1259        } else {
1260          left = rect[orientation[1]] + window.pageXOffset;
1261        }
1262
1263        if (orientation[0] == 'right' || orientation[1] == 'right') {
1264          left -= calRect.width;
1265        }
1266      }
1267
1268      this.el.classList.add('is-hidden');
1269
1270      this.el.style.top = top + 'px';
1271      this.el.style.left = left + 'px';
1272    },
1273
1274    setStartDate: function(date, preventOnSelect) {
1275      var dateISO = moment(date, moment.ISO_8601),
1276        dateOptFormat = moment(date, this._opts.format);
1277
1278      if (!dateISO.isValid() && !dateOptFormat.isValid()) {
1279        this._opts.startDate = null;
1280        this._opts.field.value = '';
1281        return;
1282      }
1283
1284      this._opts.startDate = moment(
1285        dateISO.isValid() ? dateISO : dateOptFormat
1286      );
1287
1288      if (this._opts.singleDate || this._opts.secondField) {
1289        this._opts.field.value = this._opts.startDate.format(this._opts.format);
1290      } else {
1291        this._opts.field.value =
1292          this._opts.startDate.format(this._opts.format) +
1293          this._opts.separator +
1294          '...';
1295      }
1296
1297      if (!preventOnSelect && typeof this._opts.onSelect === 'function') {
1298        this._opts.onSelect.call(this, this.getStartDate(), this.getEndDate());
1299      }
1300
1301      if (
1302        !preventOnSelect &&
1303        !this._opts.singleDate &&
1304        typeof this._opts.onSelectStart === 'function'
1305      ) {
1306        this._opts.onSelectStart.call(this, this.getStartDate());
1307      }
1308    },
1309
1310    setEndDate: function(date, preventOnSelect) {
1311      var dateISO = moment(date, moment.ISO_8601),
1312        dateOptFormat = moment(date, this._opts.format);
1313
1314      if (!dateISO.isValid() && !dateOptFormat.isValid()) {
1315        this._opts.endDate = null;
1316
1317        if (this._opts.secondField) {
1318          this._opts.secondField.value = '';
1319        } else if (!this._opts.singleDate && this._opts.startDate) {
1320          this._opts.field.value =
1321            this._opts.startDate.format(this._opts.format) +
1322            this._opts.separator +
1323            '...';
1324        }
1325        return;
1326      }
1327
1328      this._opts.endDate = moment(dateISO.isValid() ? dateISO : dateOptFormat);
1329
1330      if (this._opts.secondField) {
1331        this._opts.field.value = this._opts.startDate.format(this._opts.format);
1332        this._opts.secondField.value = this._opts.endDate.format(
1333          this._opts.format
1334        );
1335      } else {
1336        this._opts.field.value =
1337          this._opts.startDate.format(this._opts.format) +
1338          this._opts.separator +
1339          this._opts.endDate.format(this._opts.format);
1340      }
1341
1342      if (!preventOnSelect && typeof this._opts.onSelect === 'function') {
1343        this._opts.onSelect.call(this, this.getStartDate(), this.getEndDate());
1344      }
1345
1346      if (
1347        !preventOnSelect &&
1348        !this._opts.singleDate &&
1349        typeof this._opts.onSelectEnd === 'function'
1350      ) {
1351        this._opts.onSelectEnd.call(this, this.getEndDate());
1352      }
1353    },
1354
1355    setDate: function(date, preventOnSelect) {
1356      if (!this._opts.singleDate) {
1357        return;
1358      }
1359      this.setStartDate(date, preventOnSelect);
1360
1361      if (this.isShowing) {
1362        updateDates(this.el, this._opts);
1363      }
1364    },
1365
1366    setDateRange: function(start, end, preventOnSelect) {
1367      if (this._opts.singleDate) {
1368        return;
1369      }
1370      this.setStartDate(start, true);
1371      this.setEndDate(end, true);
1372
1373      if (this.isShowing) {
1374        updateDates(this.el, this._opts);
1375      }
1376
1377      if (!preventOnSelect && typeof this._opts.onSelect === 'function') {
1378        this._opts.onSelect.call(this, this.getStartDate(), this.getEndDate());
1379      }
1380    },
1381
1382    setDisableDates: function(dates) {
1383      this._opts.disableDates = dates;
1384
1385      if (this.isShowing) {
1386        updateDates(this.el, this._opts);
1387      }
1388    },
1389
1390    getStartDate: function() {
1391      return moment(this._opts.startDate).isValid()
1392        ? this._opts.startDate.clone()
1393        : null;
1394    },
1395
1396    getEndDate: function() {
1397      return moment(this._opts.endDate).isValid()
1398        ? this._opts.endDate.clone()
1399        : null;
1400    },
1401
1402    getDate: function() {
1403      return moment(this._opts.startDate).isValid()
1404        ? this._opts.startDate.clone()
1405        : null;
1406    },
1407
1408    toString: function(format) {
1409      if (this._opts.singleDate) {
1410        return moment(this._opts.startDate).isValid()
1411          ? this._opts.startDate.format(format)
1412          : '';
1413      }
1414
1415      if (
1416        moment(this._opts.startDate).isValid() &&
1417        moment(this._opts.endDate).isValid()
1418      ) {
1419        return (
1420          this._opts.startDate.format(format) +
1421          this._opts.separator +
1422          this._opts.endDate.format(format)
1423        );
1424      }
1425
1426      if (
1427        moment(this._opts.startDate).isValid() &&
1428        !moment(this._opts.endDate).isValid()
1429      ) {
1430        return (
1431          this._opts.startDate.format(format) + this._opts.separator + '...'
1432        );
1433      }
1434
1435      if (
1436        !moment(this._opts.startDate).isValid() &&
1437        moment(this._opts.endDate).isValid()
1438      ) {
1439        return '...' + this._opts.separator + this._opts.endDate.format(format);
1440      }
1441
1442      return '';
1443    },
1444
1445    show: function(target) {
1446      if (!this.isShowing) {
1447        this.isShowing = true;
1448
1449        if (this._opts.repick) {
1450          this._opts.repickTrigger = target;
1451        }
1452
1453        this.syncFields();
1454
1455        if (
1456          this._opts.secondField &&
1457          this._opts.secondField === target &&
1458          this._opts.endDate
1459        ) {
1460          this.gotoDate(this._opts.endDate);
1461        } else {
1462          this.gotoDate(this._opts.startDate || this._opts.minDate);
1463        }
1464
1465        document.addEventListener('mousedown', this._onClick);
1466
1467        this.updatePosition();
1468
1469        this.el.classList.remove('is-hidden');
1470
1471        if (typeof this._opts.onOpen === 'function') {
1472          this._opts.onOpen.call(this);
1473        }
1474      }
1475    },
1476
1477    hide: function() {
1478      if (this.isShowing) {
1479        this.isShowing = false;
1480
1481        document.removeEventListener('mousedown', this._onClick);
1482
1483        this.el.classList.add('is-hidden');
1484
1485        this.el.querySelector('.lightpick__tooltip').style.visibility =
1486          'hidden';
1487
1488        if (typeof this._opts.onClose === 'function') {
1489          this._opts.onClose.call(this);
1490        }
1491      }
1492    },
1493
1494    destroy: function() {
1495      var opts = this._opts;
1496
1497      this.hide();
1498
1499      this.el.removeEventListener('mousedown', self._onMouseDown, true);
1500      this.el.removeEventListener('mouseenter', self._onMouseEnter, true);
1501      this.el.removeEventListener('touchend', self._onMouseDown, true);
1502      this.el.removeEventListener('change', self._onChange, true);
1503
1504      opts.field.removeEventListener('change', this._onInputChange);
1505      opts.field.removeEventListener('click', this._onInputClick);
1506      opts.field.removeEventListener('focus', this._onInputFocus);
1507
1508      if (opts.secondField) {
1509        opts.secondField.removeEventListener('change', this._onInputChange);
1510        opts.secondField.removeEventListener('click', this._onInputClick);
1511        opts.secondField.removeEventListener('focus', this._onInputFocus);
1512      }
1513
1514      if (this.el.parentNode) {
1515        this.el.parentNode.removeChild(this.el);
1516      }
1517    },
1518
1519    reset: function() {
1520      this.setStartDate(null, true);
1521      this.setEndDate(null, true);
1522
1523      updateDates(this.el, this._opts);
1524
1525      if (typeof this._opts.onSelect === 'function') {
1526        this._opts.onSelect.call(this, this.getStartDate(), this.getEndDate());
1527      }
1528
1529      this.el.querySelector('.lightpick__tooltip').style.visibility = 'hidden';
1530    },
1531
1532    reloadOptions: function(options) {
1533      var dropdowns = this._opts.dropdowns;
1534      var locale = this._opts.locale;
1535
1536      Object.assign(this._opts, this._opts, options);
1537      Object.assign(this._opts.dropdowns, dropdowns, options.dropdowns);
1538      Object.assign(this._opts.locale, locale, options.locale);
1539    }
1540  };
1541
1542  return Lightpick;
1543});

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.