<commit_before>(function () {

'use strict';

// SimpleDatePicker.
var SimpleDatePicker = window.SimpleDatePicker = {};

// Bind a function to a context.
SimpleDatePicker.bind = function (fn, context) {
  var args = arguments.length > 2 ? Array.prototype.slice.call(arguments, 2) : null;
  return function () {
    return fn.apply(context, args || arguments);
  };
};


// Add an event to an element. Return the handler.
SimpleDatePicker.addEventListener = function (element, eventName, handler, context) {
  var names = eventName.split(/\s+/), i, l;

  if (!document.addEventListener) {
    var callback = handler;
    handler = function (event) {
      event.target = event.target || event.srcElement;
      callback.call(this, event);
    };
  }

  if (context) {
    handler = SimpleDatePicker.bind(handler, context);
  }

  for (i = 0, l = names.length; i < l; i++) {
    eventName = names[i];
    if (element.addEventListener) {
      element.addEventListener(eventName, handler, false);
    }
    else if (element.attachEvent) {
      element.attachEvent('on' + eventName, handler);
    }
    else {
      element['on' + eventName] = handler;
    }
  }

  return handler;
};

// Remove an event from an element.
SimpleDatePicker.removeEventListener = function (element, eventName, handler) {
  var names = eventName.split(/\s+/), i, l;

  for (i = 0, l = names.length; i < l; i++) {
    eventName = names[i];
    if (element.removeEventListener) {
      element.removeEventListener(eventName, handler, false);
    }
    else if (element.detachEvent) {
      element.detachEvent('on' + eventName, handler);
    }
    else {
      element['on' + eventName] = null;
    }
  }
};

// Get a css style of an element. (Possible unexpected results in IE8).
SimpleDatePicker.getStyle = function (element, property, pseudoElement) {
  if (window.getComputedStyle) {
    return window.getComputedStyle(element, pseudoElement)[property];
  }
  else if (document.defaultView && document.defaultView.getComputedStyle) {
    return document.defaultView.getComputedStyle(element, pseudoElement)[property];
  }
  else if (element.currentStyle) {
    return element.currentStyle[property];
  }
  else {
    return element.style[property];
  }
};

// Handle DOM element classes.
SimpleDatePicker.hasClass = function (element, className) {
  if (element && element.className.length > 0) {
    return element.className === className || (' ' + element.className + ' ').indexOf(' ' + className + ' ') !== -1;
  }
  return false;
};
SimpleDatePicker.addClass = function (element, className) {
  if (element && !SimpleDatePicker.hasClass(element, className)) {
    element.className += (element.className.length > 0 ? ' ' : '') + className;
  }
};
SimpleDatePicker.removeClass = function (element, className) {
  if (element && element.className.length > 0) {
    element.className = SimpleDatePicker.trim((' ' + element.className + ' ').replace(' ' + className + ' ', ''));
  }
};

// Create a DOM element and set attributes.
SimpleDatePicker.createElement = function (tagName, attributes, parent, content) {
  var element = document.createElement(tagName),
      attribute;
  if (attributes) {
    for (attribute in attributes) {
      if (attributes.hasOwnProperty(attribute)) {
        element.setAttribute(attribute, attributes[attribute]);
      }
    }
  }
  if (content) {
    element.innerHTML = content;
  }
  if (parent) {
    parent.appendChild(element);
  }
  return element;
};

// Trim a string.
SimpleDatePicker.trim = function (string){
  var ws = /\s/, i = string.length, result = true;
  string = string.replace(/^\s\s*/, '');
  while (result) { result = ws.test(string.charAt(--i)); }
  return string.slice(0, i + 1);
};

// Merge properties of objects passed as arguments into target.
SimpleDatePicker.extend = function (target) {
  var sources = Array.prototype.slice.call(arguments, 1),
      i, l, property, source;
  for (i = 0, l = sources.length; i < l; i++) {
    source = sources[i] || {};
    for (property in source) {
      if (source.hasOwnProperty(property)) {
        target[property] = source[property];
      }
    }
  }
  return target;
};

/**
* Simple Class.
*/
SimpleDatePicker.Class = function () {};

// Extend a class.
SimpleDatePicker.Class.extend = function (properties) {
  properties = properties || {};

  // Extended class.
  var NewClass = function () {
    if (this.initialize) {
      this.initialize.apply(this, arguments);
    }
  };

  // Instantiate the class without calling the constructor.
  var Instance = function () {};
  Instance.prototype = this.prototype;

  var prototype = new Instance();
  prototype.constructor = NewClass;

  NewClass.prototype = prototype;

  // Inherit the parent's static properties.
  for (var property in this) {
    if (this.hasOwnProperty(property) && property !== 'prototype') {
      NewClass[property] = this[property];
    }
  }

  // Merge static properties.
  if (properties.statics) {
    SimpleDatePicker.extend(NewClass, properties.statics);
    delete properties.statics;
  }

  // Merge includes.
  if (properties.includes) {
    SimpleDatePicker.extend.apply(null, [prototype].concat(properties.includes));
    delete properties.includes;
  }

  // Merge options.
  if (properties.options && prototype.options) {
    properties.options = SimpleDatePicker.extend({}, prototype.options, properties.options);
  }

  // Merge properties into the prototype.
  SimpleDatePicker.extend(prototype, properties);

  // Parent.
  NewClass._super = this.prototype;

  NewClass.prototype.setOptions = function (options) {
    this.options = SimpleDatePicker.extend({}, this.options, options);
  };

  return NewClass;
};

/**
 * Date manipulation class.
 */
SimpleDatePicker.Date = SimpleDatePicker.Class.extend({
  options: {
    months: ['January', 'Febuary', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
    weekDays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
    utc: true,
    formats: /(YYYY|YY|MMMM|MMM|MM|M|DDDD|DDD|DD|D|dddd|ddd|dd|d)/g
  },

  initialize: function (date, options) {
    this.setOptions(options);

    this.create(date);

    this.replace = SimpleDatePicker.bind(this.replace, this);
  },

  create: function (date) {
    this.dateObject = typeof date === 'undefined' || date === null ? new Date() : new Date(date);
  },

  utc: function (date) {
    if (typeof date !== 'undefined') {
      this.create(date);
    }
    this.options.utc = true;
    return this;
  },

  day: function (day) {
    if (typeof day === 'number') {
      this.add('date', day - this.get('day'));
      return this;
    }
    return this.get('day');
  },

  days: function (days) {
    return this.date(days);
  },

  millisecond: function (millisecond) {
    return this.milliseconds(millisecond);
  },

  milliseconds: function (milliseconds) {
    return this.set('milliseconds', milliseconds);
  },

  second: function (second) {
    return this.seconds(second);
  },

  seconds: function (seconds) {
    return this.set('seconds', seconds);
  },

  minute: function (minute) {
    return this.minutes(minute);
  },

  minutes: function (minutes) {
    return this.set('minutes', minutes);
  },

  hour: function (hour) {
    return this.hours(hour);
  },

  hours: function (hours) {
    return this.set('hours', hours);
  },

  date: function (date) {
    return this.set('date', date);
  },

  dates: function (dates) {
    return this.date(dates);
  },

  month: function (month) {
    return this.set('month', month);
  },

  months: function (months) {
    return this.month(months);
  },

  year: function (year) {
    return this.set('year', year);
  },

  years: function (years) {
    return this.year(years);
  },

  get: function (type) {
    return this.set(type);
  },

  set: function (type, value) {
    type = type === 'year' ? 'FullYear' : type;
    type = type.charAt(0).toUpperCase() + type.slice(1);
    if (typeof value === 'number') {
      this.dateObject['set' + (this.options.utc ? 'UTC' : '') + type](value);
      return this;
    }
    return this.dateObject['get' + (this.options.utc ? 'UTC' : '') + type]();
  },

  daysInMonth: function () {
    var date = new Date(this.year(), this.month() + 1, 0);
    return this.options.utc ? date.getUTCDate() : date.getDate();
  },

  add: function (type, value) {
    return this[type](this[type]() + value);
  },

  substract: function (type, value) {
    return this[type](this[type]() - value);
  },

  valueOf: function () {
    return this.dateObject.valueOf();
  },

  unix: function () {
    return Math.round(this.valueOf() / 1000);
  },

  format: function (format) {
    return format.replace(this.options.formats, this.replace);
  },

  replace: function (data) {
    var date, month, day;
    switch (data) {
      case 'YYYY':
        return this.year();

      case 'YY':
        return ('' + this.year()).slice(-2);

      case 'MMMM':
        return this.options.months[this.month()];

      case 'MMM':
        return ('' + this.options.months[this.month()]).substr(0, 3);

      case 'MM':
        month = this.month() + 1;
        return (month < 10 ? '0' : '') + month;

      case 'M':
        return this.month() + 1;

      case 'DDDD':
      case 'DDD':
        date = new Date(this.year(), 0, 1);
        date = '' + Math.ceil((this.dateObject - date) / 86400000);
        return (data === 'DDDD' ? '00'.substr(0, 2 - date.length) : '') + date;

      case 'DD':
        date = this.date();
        return (date < 10 ? '0' : '') + date;

      case 'D':
        return this.date();

      case 'dddd':
      case 'ddd':
      case 'dd':
        day = this.options.weekDays[this.get('day')];
        return (data === 'dddd' ? day : day.substr(0, data.length));

      case 'd':
        return this.get('day');
    }
  },

  clone: function () {
    return new SimpleDatePicker.Date(this.dateObject, this.options);
  }
});

SimpleDatePicker.date = function (date, options) {
  return new SimpleDatePicker.Date(date, options);
};

/**
 * DatePicker class.
 */
SimpleDatePicker.DatePicker = SimpleDatePicker.Class.extend({
  options: {
    // Selection mode of the calendar(s). Can be 'single', 'muliple' or 'range'.
    mode: 'single',
    // Number of calendars to display.
    calendars: 1,
    // Indicates if calendars are linked or not
    // (changing month/year affects all calendars).
    linked: true,
    // Default date.
    date: null,
    // Date creation function, moment.js like.
    dateFunction:  SimpleDatePicker.date,
    // First day of the week. 0 is Sunday, 1 is Monday etc.
    firstWeekDay: 0,
    // Whether to highlight today's day or not.
    highlightToday: true,
    // Classes used for theme the calendars.
    classes: {
      container: 'simpledatepicker-container',
      calendar: 'simpledatepicker-calendar',
      calendarFirst: 'simpledatepicker-calendar-first',
      calendarMIddle: 'simpledatepicker-calendar-middle',
      calendarLast: 'simpledatepicker-calendar-last',
      title: 'simpledatepicker-title',
      titleDate: 'simpledatepicker-title-date',
      titlePrevious: 'simpledatepicker-title-previous',
      titleNext: 'simpledatepicker-title-next',
      titleMonth : 'simpledatepicker-title-month',
      titleYear: 'simpledatepicker-title-year',
      header: 'simpledatepicker-header',
      days: 'simpledatepicker-days',
      time: 'simpledatepicker-time',
      dayIn: 'simpledatepicker-day-in',
      dayOut: 'simpledatepicker-day-out',
      firstWeekDay: 'simpledatepicker-first-week-day',
      selectedDay: 'simpledatepicker-selected-day',
      activeDay: 'simpledatepicker-active-day',
      today: 'simpledatepicker-today',
      multiple: 'simpledatepicker-multiple',
      linked: 'simpledatepicker-linked'
    },
    // Navigation.
    navigation: {
      previousYear: {
        content: '&#x00AB;',
        title: 'previous year'
      },
      previousMonth: {
        content: '&#x2039;',
        title: 'previous month'
      },
      nextMonth: {
        content: '&#x203A;',
        title: 'next month'
      },
      nextYear: {
        content: '&#x00BB;',
        title: 'next year'
      }
    },
    // Date formats.
    formats: {
      titleDate: 'MMMM, YYYY',
      headerDay: 'dd',
      day: 'D'
    },
    // Element to which attach the datepicker.
    element: null,
    // Container in which to insert the datepicker,
    // defaults to document.body if not defined.
    container: null,
    // Default visibility.
    visible: true,
    // Automatically update the calendar position before display.
    autoUpdatePosition: false
  },

  // Initialize the class object.
  initialize: function (options) {
    this.setOptions(options);

    // Bind methods.
    var bind = SimpleDatePicker.bind, property;
    for (property in this) {
      if (typeof this[property] === 'function') {
        this[property] = bind(this[property], this);
      }
    }

    // Event listeners.
    this.listeners = {};

    // Regexp used to extract the date from a day element.
    this.timeMatcher = new RegExp(this.options.classes.time + '-(\\d+)');

    this.selection = [];

    // Set up today.
    this.today = this.options.highlightToday === true ? this.createDate(null, true).valueOf() : null;

    this.create();
  },

  // Handle click on the calendar days and navigation elements.
  handleClick: function (event) {
    var target = event.target,
        hasClass = SimpleDatePicker.hasClass,
        options = this.options,
        classes = options.classes,
        classDayIn = classes.dayIn,
        classPrevious = classes.titlePrevious,
        classNext = classes.titleNext,
        classYear = classes.titleYear,
        calendar;

    if (hasClass(target, classDayIn)) {
      this.select(target);
    }
    else if (hasClass(target, classPrevious)) {
      calendar = options.linked ? null : this.retrieveCalendar(target);
      this.updateCalendars(hasClass(target, classYear) ? 'years' : 'months', -1, calendar);
    }
    else if (hasClass(target, classNext)) {
      calendar = options.linked ? null : this.retrieveCalendar(target);
      this.updateCalendars(hasClass(target, classYear) ? 'years' : 'months', 1, calendar);
    }
    return false;
  },

  // Retrieve a calendar from an element.
  retrieveCalendar: function (element) {
    var hasClass = SimpleDatePicker.hasClass,
        calendarElement = null,
        calendarClass = this.options.classes.calendar,
        calendars = this.calendars,
        calendar, i, l;

    while (element !== this.container) {
      if (hasClass(element, calendarClass)) {
        calendarElement = element;
        break;
      }
      element = element.parentNode;
    }

    if (calendarElement) {
      for (i = 0, l = calendars.length; i < l; i++) {
        calendar = calendars[i];
        if (calendar.calendar === calendarElement) {
          return calendar;
        }
      }
    }
    return null;
  },

  // Retrieve the date associated with a day element.
  retrieveDate: function (day, toDate) {
    var date = parseInt(this.timeMatcher.exec(day.className)[1], 10);
    return toDate === true ? this.createDate(date) : date;
  },

  // Retrieve a list of days matching the given date.
  retrieveDays: function (date) {
    if (this.container.getElementsByClassName) {
      return this.container.getElementsByClassName(this.options.classes.time + '-' + date);
    }
    else {
      var retrieveDate = this.retrieveDate,
          calendars = this.calendars, elements = [],
          days, day, i, l, j, m;
      for (j = 0, m = calendars.length; j < m; j++) {
        days = calendars[j].days;
        for (i = 0, l = days.length; i < l; i++) {
          day = days[i];
          if (retrieveDate(day) === date) {
            elements.push(day);
          }
        }
      }
      return elements;
    }
  },

  // Day selection callback.
  select: function (day) {
    var hasClass = SimpleDatePicker.hasClass,
        options = this.options,
        classSelectedDay = options.classes.selectedDay,
        selected = hasClass(day, classSelectedDay),
        selection = this.selection,
        selectionLength = selection.length,
        mode = options.mode,
        date = this.retrieveDate(day);

    switch (mode) {
      case 'single':
        if (selectionLength > 0) {
          this.unselectAll();
        }
        this.selectDay(date);
        break;

      case 'multiple':
        if (selected) {
          this.unselectDay(date);
        }
        else {
          this.selectDay(date);
        }
        break;

      case 'range':
        if (selectionLength === 1 && selection[0] !== date) {
          this.selectRange(selection[0], date);
        }
        else {
          if (selectionLength > 1) {
            this.unselectAll();
          }
          this.selectDay(date);
        }
        break;
    }

    this.fire('select', this.getSelection());
  },

  // Select a calendar day based on the given date.
  selectDay: function (date, select) {
    var addClass = SimpleDatePicker.addClass,
        removeClass = SimpleDatePicker.removeClass,
        selection = this.selection,
        classSelectedDay = this.options.classes.selectedDay,
        days = this.retrieveDays(date),
        day, i, l;

    // We select all the days of all the calendars with the same date.
    for (i = 0, l = days.length; i < l; i++) {
      day = days[i];
      if (select !== false) {
        addClass(day, classSelectedDay);
      }
      else {
        removeClass(day, classSelectedDay);
      }
    }


    for (i = 0, l = selection.length; i < l; i++) {
      if (selection[i] === date) {
        return select !== false ? null : selection.splice(i, 1);
      }
    }
    selection.push(date);
  },

  // Unselect a day.
  unselectDay: function (date) {
    this.selectDay(date, false);
  },

  // Select a range of days.
  selectRange: function (dateStart, dateEnd) {
    var addClass = SimpleDatePicker.addClass,
        retrieveDate = this.retrieveDate,
        options = this.options,
        classes = options.classes,
        classSelectedDay = classes.selectedDay,
        classActiveDay = classes.activeDay,
        calendars = this.calendars,
        days, day, dateDay,
        temp, i, l, j, m;

    if (dateStart > dateEnd) {
      temp = dateStart;
      dateStart = dateEnd;
      dateEnd = temp;
    }

    for (j = 0, m = calendars.length; j < m; j++) {
      days = calendars[j].days;

      for (i = 0, l = days.length; i < l; i++) {
        day = days[i];
        dateDay = retrieveDate(day);
        if (dateDay > dateStart && dateDay < dateEnd) {
          addClass(day, classActiveDay);
        }
        else if (dateDay === dateStart || dateDay === dateEnd) {
          addClass(day, classSelectedDay);
        }
      }
    }
    this.selection = [dateStart, dateEnd];
  },

  // Unselect all selected days.
  unselectAll: function () {
    var removeClass = SimpleDatePicker.removeClass,
        classes = this.options.classes,
        classSelectedDay = classes.selectedDay,
        classActiveDay = classes.activeDay,
        calendars = this.calendars,
        days, day, i, l, j, m;

    for (j = 0, m = calendars.length; j < m; j++) {
      days = calendars[j].days;
      for (i = 0, l = days.length; i < l; i++) {
        day = days[i];
        removeClass(day, classSelectedDay);
        removeClass(day, classActiveDay);
      }
    }

    this.selection = [];
  },

  // Update a calendar based on the new date.
  updateCalendar: function (calendar, date) {
    calendar.date = date;
    calendar.titleDate.innerHTML = date.format(this.options.formats.titleDate);
    this.updateDays(date, calendar.days);
  },

  // Update calendars when previous/next month/year is pressed.
  updateCalendars: function (type, value, calendar) {
    var calendars = calendar ? [calendar] : this.calendars,
        i, l;
    for (i = 0, l = calendars.length; i < l; i++) {
      calendar = calendars[i];
      if (typeof type !== 'undefined') {
        calendar.date.add(type, value);
      }
      this.updateCalendar(calendar, calendar.date);
    }
  },

  // Mark day as selected if in selection.
  updateSelectedDay: function (day, date) {
    var addClass = SimpleDatePicker.addClass,
        selection = this.selection,
        selectionLength = selection.length,
        options = this.options, i;

    if (options.mode === 'range' && selectionLength > 1 && date > selection[0] && date < selection[1]) {
      addClass(day, options.classes.activeDay);
    }
    else {
      for (i = 0; i < selectionLength; i++) {
        if (selection[i] === date) {
          addClass(day, options.classes.selectedDay);
          break;
        }
      }
    }
  },

  // Update the class and date for a given day element.
  updateDay: function (element, month, date) {
    var options = this.options,
        firstWeekDay = options.firstWeekDay,
        formatDay = options.formats.day,
        classes = options.classes,
        classTime = classes.time,
        classDayIn = classes.dayIn,
        classDayOut = classes.dayOut,
        classFirstWeekDay = classes.firstWeekDay,
        classToday = classes.today,
        time = date.valueOf();

    element.className = (classTime + '-' + time + ' ') +
                        (date.day() === firstWeekDay ? classFirstWeekDay + ' ' : '') +
                        (date.month() === month ? classDayIn : classDayOut) +
                        (this.today === time ? ' ' + classToday : '');
    element.innerHTML = date.format(formatDay);

    this.updateSelectedDay(element, time);

    return element;
  },

  // Update the days of a calendar.
  updateDays: function (date, days) {
    var updateDay = this.updateDay,
        month = date.month(), i;

    date = date.clone().date(0).day(this.options.firstWeekDay);

    // Update the days.
    for (i = 0; i < 42; i++) {
      updateDay(days[i], month, date);
      date.add('days', 1);
    }
  },

  // Create the days of a calendar.
  createDays: function (date, container) {
    var createElement = SimpleDatePicker.createElement,
        updateDay = this.updateDay,
        month = date.month(),
        days = [], i = 42;

    date = date.clone().date(0).day(this.options.firstWeekDay);

    // Create the days.
    while (i--) {
      days.push(updateDay(createElement('span', null, container), month, date));
      date.add('days', 1);
    }

    return days;
  },

  // Create a calendar;
  createCalendar: function (container, date, position) {
    var createElement = SimpleDatePicker.createElement,
        options = this.options,
        classes = options.classes,
        classPrevious = classes.titlePrevious,
        classNext = classes.titleNext,
        classYear = classes.titleYear,
        classMonth = classes.titleMonth,
        navigation = options.navigation,
        previousYear = navigation.previousYear,
        previousMonth = navigation.previousMonth,
        nextMonth = navigation.nextMonth,
        nextYear = navigation.nextYear,
        formats = options.formats,
        formatTitleDate = formats.titleDate,
        formatHeaderDay = formats.headerDay,
        calendar, title, titleDate, header, days,
        day = date.clone().day(options.firstWeekDay),
        i = 7;

    // Calendar.
    calendar = createElement('div', {'class': classes.calendar}, container);

    if (options.calendars > 1) {
      if (position === 0) {
        SimpleDatePicker.addClass(calendar, classes.calendarFirst);
      }
      else if (options.calendars - 1) {
        SimpleDatePicker.addClass(calendar, classes.calendarLast);
      }
      else {
        SimpleDatePicker.addClass(calendar, classes.calendarMiddle);
      }
    }

    // Month, Year header and navigation.
    title = createElement('div', {'class': classes.title}, calendar);
    createElement('span', {'class': classPrevious + ' ' + classYear, title: previousYear.title}, title, previousYear.content);
    createElement('span', {'class': classPrevious + ' ' + classMonth, title: previousMonth.title}, title, previousMonth.content);
    titleDate = createElement('span', {'class': classes.titleDate}, title, date.format(formatTitleDate));
    createElement('span', {'class': classNext + ' ' + classMonth, title: nextMonth.title}, title, nextMonth.content);
    createElement('span', {'class': classNext + ' ' + classYear, title: nextYear.title}, title, nextYear.content);

    // Days header.
    header = createElement('div', {'class': classes.header}, calendar);
    while (i--) {
      createElement('span', null, header, day.format(formatHeaderDay));
      day.add('days', 1);
    }

    // Calendar days.
    days = createElement('div', {'class': classes.days}, calendar);
    days = this.createDays(date, days);

    return {
      calendar: calendar,
      titleDate: titleDate,
      days: days,
      date: date
    };
  },

  // Link calendars, changing month/year affects all calendars.
  linkCalendars: function() {
    SimpleDatePicker.addClass(this.container, this.options.classes.linked);
    return this;
  },

  // Unlink calendars, changing month/year affects only the current calendar.
  unlinkCalendars: function() {
    SimpleDatePicker.removeClass(this.container, this.options.classes.linked);
    return this;
  },

  // Create the calendars.
  create: function () {
    var createElement = SimpleDatePicker.createElement,
        options = this.options,
        container = createElement('div', {'class': options.classes.container}),
        date =  this.createDate(this.options.date, true).date(1),
        calendar, calendars = [],
        i, l;

    for (i = 0, l = options.calendars; i < l; i++) {
      calendar = this.createCalendar(container, date.clone(), i);
      calendars.push(calendar);
      date.add('months', 1);
    }

    if (options.calendars > 1) {
      SimpleDatePicker.addClass(container, options.classes.multiple);

      if (options.linked) {
        this.linkCalendars();
      }
    }

    this.container = container;
    this.calendars = calendars;

    this.updatePosition();

    if (!options.visible) {
      this.hide();
    }

    if (this.options.container) {
      this.options.container.appendChild(container);
    }
    else {
      document.body.appendChild(container);
    }

    SimpleDatePicker.addEventListener(container, 'click', this.handleClick);
  },

  // Create a date wrapper object.
  createDate: function (date, stripTime, utc) {
    if (typeof date === 'string' && utc !== false) {
      date = date.replace(/\s*\+\d{4}/, '') + ' +0000';
    }
    date = this.options.dateFunction(date);
    if (utc !== false) {
      date.utc();
    }
    if (stripTime === true) {
      date.hours(0).minutes(0).seconds(0).milliseconds(0);
    }
    return date;
  },

  // Show the calendars.
  show: function () {
    if (this.container.style.display === 'none') {<commit_msg>Fix issue when parsing date strings<commit_after>(function () {

'use strict';

// SimpleDatePicker.
var SimpleDatePicker = window.SimpleDatePicker = {};

// Bind a function to a context.
SimpleDatePicker.bind = function (fn, context) {
  var args = arguments.length > 2 ? Array.prototype.slice.call(arguments, 2) : null;
  return function () {
    return fn.apply(context, args || arguments);
  };
};


// Add an event to an element. Return the handler.
SimpleDatePicker.addEventListener = function (element, eventName, handler, context) {
  var names = eventName.split(/\s+/), i, l;

  if (!document.addEventListener) {
    var callback = handler;
    handler = function (event) {
      event.target = event.target || event.srcElement;
      callback.call(this, event);
    };
  }

  if (context) {
    handler = SimpleDatePicker.bind(handler, context);
  }

  for (i = 0, l = names.length; i < l; i++) {
    eventName = names[i];
    if (element.addEventListener) {
      element.addEventListener(eventName, handler, false);
    }
    else if (element.attachEvent) {
      element.attachEvent('on' + eventName, handler);
    }
    else {
      element['on' + eventName] = handler;
    }
  }

  return handler;
};

// Remove an event from an element.
SimpleDatePicker.removeEventListener = function (element, eventName, handler) {
  var names = eventName.split(/\s+/), i, l;

  for (i = 0, l = names.length; i < l; i++) {
    eventName = names[i];
    if (element.removeEventListener) {
      element.removeEventListener(eventName, handler, false);
    }
    else if (element.detachEvent) {
      element.detachEvent('on' + eventName, handler);
    }
    else {
      element['on' + eventName] = null;
    }
  }
};

// Get a css style of an element. (Possible unexpected results in IE8).
SimpleDatePicker.getStyle = function (element, property, pseudoElement) {
  if (window.getComputedStyle) {
    return window.getComputedStyle(element, pseudoElement)[property];
  }
  else if (document.defaultView && document.defaultView.getComputedStyle) {
    return document.defaultView.getComputedStyle(element, pseudoElement)[property];
  }
  else if (element.currentStyle) {
    return element.currentStyle[property];
  }
  else {
    return element.style[property];
  }
};

// Handle DOM element classes.
SimpleDatePicker.hasClass = function (element, className) {
  if (element && element.className.length > 0) {
    return element.className === className || (' ' + element.className + ' ').indexOf(' ' + className + ' ') !== -1;
  }
  return false;
};
SimpleDatePicker.addClass = function (element, className) {
  if (element && !SimpleDatePicker.hasClass(element, className)) {
    element.className += (element.className.length > 0 ? ' ' : '') + className;
  }
};
SimpleDatePicker.removeClass = function (element, className) {
  if (element && element.className.length > 0) {
    element.className = SimpleDatePicker.trim((' ' + element.className + ' ').replace(' ' + className + ' ', ''));
  }
};

// Create a DOM element and set attributes.
SimpleDatePicker.createElement = function (tagName, attributes, parent, content) {
  var element = document.createElement(tagName),
      attribute;
  if (attributes) {
    for (attribute in attributes) {
      if (attributes.hasOwnProperty(attribute)) {
        element.setAttribute(attribute, attributes[attribute]);
      }
    }
  }
  if (content) {
    element.innerHTML = content;
  }
  if (parent) {
    parent.appendChild(element);
  }
  return element;
};

// Trim a string.
SimpleDatePicker.trim = function (string){
  var ws = /\s/, i = string.length, result = true;
  string = string.replace(/^\s\s*/, '');
  while (result) { result = ws.test(string.charAt(--i)); }
  return string.slice(0, i + 1);
};

// Merge properties of objects passed as arguments into target.
SimpleDatePicker.extend = function (target) {
  var sources = Array.prototype.slice.call(arguments, 1),
      i, l, property, source;
  for (i = 0, l = sources.length; i < l; i++) {
    source = sources[i] || {};
    for (property in source) {
      if (source.hasOwnProperty(property)) {
        target[property] = source[property];
      }
    }
  }
  return target;
};

/**
* Simple Class.
*/
SimpleDatePicker.Class = function () {};

// Extend a class.
SimpleDatePicker.Class.extend = function (properties) {
  properties = properties || {};

  // Extended class.
  var NewClass = function () {
    if (this.initialize) {
      this.initialize.apply(this, arguments);
    }
  };

  // Instantiate the class without calling the constructor.
  var Instance = function () {};
  Instance.prototype = this.prototype;

  var prototype = new Instance();
  prototype.constructor = NewClass;

  NewClass.prototype = prototype;

  // Inherit the parent's static properties.
  for (var property in this) {
    if (this.hasOwnProperty(property) && property !== 'prototype') {
      NewClass[property] = this[property];
    }
  }

  // Merge static properties.
  if (properties.statics) {
    SimpleDatePicker.extend(NewClass, properties.statics);
    delete properties.statics;
  }

  // Merge includes.
  if (properties.includes) {
    SimpleDatePicker.extend.apply(null, [prototype].concat(properties.includes));
    delete properties.includes;
  }

  // Merge options.
  if (properties.options && prototype.options) {
    properties.options = SimpleDatePicker.extend({}, prototype.options, properties.options);
  }

  // Merge properties into the prototype.
  SimpleDatePicker.extend(prototype, properties);

  // Parent.
  NewClass._super = this.prototype;

  NewClass.prototype.setOptions = function (options) {
    this.options = SimpleDatePicker.extend({}, this.options, options);
  };

  return NewClass;
};

/**
 * Date manipulation class.
 */
SimpleDatePicker.Date = SimpleDatePicker.Class.extend({
  options: {
    months: ['January', 'Febuary', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
    weekDays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
    utc: true,
    formats: /(YYYY|YY|MMMM|MMM|MM|M|DDDD|DDD|DD|D|dddd|ddd|dd|d)/g
  },

  initialize: function (date, options) {
    this.setOptions(options);

    this.create(date);

    this.replace = SimpleDatePicker.bind(this.replace, this);
  },

  create: function (date) {
    this.dateObject = typeof date === 'undefined' || date === null ? new Date() : new Date(date);
  },

  utc: function (date) {
    if (typeof date !== 'undefined') {
      this.create(date);
    }
    this.options.utc = true;
    return this;
  },

  day: function (day) {
    if (typeof day === 'number') {
      this.add('date', day - this.get('day'));
      return this;
    }
    return this.get('day');
  },

  days: function (days) {
    return this.date(days);
  },

  millisecond: function (millisecond) {
    return this.milliseconds(millisecond);
  },

  milliseconds: function (milliseconds) {
    return this.set('milliseconds', milliseconds);
  },

  second: function (second) {
    return this.seconds(second);
  },

  seconds: function (seconds) {
    return this.set('seconds', seconds);
  },

  minute: function (minute) {
    return this.minutes(minute);
  },

  minutes: function (minutes) {
    return this.set('minutes', minutes);
  },

  hour: function (hour) {
    return this.hours(hour);
  },

  hours: function (hours) {
    return this.set('hours', hours);
  },

  date: function (date) {
    return this.set('date', date);
  },

  dates: function (dates) {
    return this.date(dates);
  },

  month: function (month) {
    return this.set('month', month);
  },

  months: function (months) {
    return this.month(months);
  },

  year: function (year) {
    return this.set('year', year);
  },

  years: function (years) {
    return this.year(years);
  },

  get: function (type) {
    return this.set(type);
  },

  set: function (type, value) {
    type = type === 'year' ? 'FullYear' : type;
    type = type.charAt(0).toUpperCase() + type.slice(1);
    if (typeof value === 'number') {
      this.dateObject['set' + (this.options.utc ? 'UTC' : '') + type](value);
      return this;
    }
    return this.dateObject['get' + (this.options.utc ? 'UTC' : '') + type]();
  },

  daysInMonth: function () {
    var date = new Date(this.year(), this.month() + 1, 0);
    return this.options.utc ? date.getUTCDate() : date.getDate();
  },

  add: function (type, value) {
    return this[type](this[type]() + value);
  },

  substract: function (type, value) {
    return this[type](this[type]() - value);
  },

  valueOf: function () {
    return this.dateObject.valueOf();
  },

  unix: function () {
    return Math.round(this.valueOf() / 1000);
  },

  format: function (format) {
    return format.replace(this.options.formats, this.replace);
  },

  replace: function (data) {
    var date, month, day;
    switch (data) {
      case 'YYYY':
        return this.year();

      case 'YY':
        return ('' + this.year()).slice(-2);

      case 'MMMM':
        return this.options.months[this.month()];

      case 'MMM':
        return ('' + this.options.months[this.month()]).substr(0, 3);

      case 'MM':
        month = this.month() + 1;
        return (month < 10 ? '0' : '') + month;

      case 'M':
        return this.month() + 1;

      case 'DDDD':
      case 'DDD':
        date = new Date(this.year(), 0, 1);
        date = '' + Math.ceil((this.dateObject - date) / 86400000);
        return (data === 'DDDD' ? '00'.substr(0, 2 - date.length) : '') + date;

      case 'DD':
        date = this.date();
        return (date < 10 ? '0' : '') + date;

      case 'D':
        return this.date();

      case 'dddd':
      case 'ddd':
      case 'dd':
        day = this.options.weekDays[this.get('day')];
        return (data === 'dddd' ? day : day.substr(0, data.length));

      case 'd':
        return this.get('day');
    }
  },

  clone: function () {
    return new SimpleDatePicker.Date(this.dateObject, this.options);
  }
});

SimpleDatePicker.date = function (date, options) {
  return new SimpleDatePicker.Date(date, options);
};

/**
 * DatePicker class.
 */
SimpleDatePicker.DatePicker = SimpleDatePicker.Class.extend({
  options: {
    // Selection mode of the calendar(s). Can be 'single', 'muliple' or 'range'.
    mode: 'single',
    // Number of calendars to display.
    calendars: 1,
    // Indicates if calendars are linked or not
    // (changing month/year affects all calendars).
    linked: true,
    // Default date.
    date: null,
    // Date creation function, moment.js like.
    dateFunction:  SimpleDatePicker.date,
    // First day of the week. 0 is Sunday, 1 is Monday etc.
    firstWeekDay: 0,
    // Whether to highlight today's day or not.
    highlightToday: true,
    // Classes used for theme the calendars.
    classes: {
      container: 'simpledatepicker-container',
      calendar: 'simpledatepicker-calendar',
      calendarFirst: 'simpledatepicker-calendar-first',
      calendarMIddle: 'simpledatepicker-calendar-middle',
      calendarLast: 'simpledatepicker-calendar-last',
      title: 'simpledatepicker-title',
      titleDate: 'simpledatepicker-title-date',
      titlePrevious: 'simpledatepicker-title-previous',
      titleNext: 'simpledatepicker-title-next',
      titleMonth : 'simpledatepicker-title-month',
      titleYear: 'simpledatepicker-title-year',
      header: 'simpledatepicker-header',
      days: 'simpledatepicker-days',
      time: 'simpledatepicker-time',
      dayIn: 'simpledatepicker-day-in',
      dayOut: 'simpledatepicker-day-out',
      firstWeekDay: 'simpledatepicker-first-week-day',
      selectedDay: 'simpledatepicker-selected-day',
      activeDay: 'simpledatepicker-active-day',
      today: 'simpledatepicker-today',
      multiple: 'simpledatepicker-multiple',
      linked: 'simpledatepicker-linked'
    },
    // Navigation.
    navigation: {
      previousYear: {
        content: '&#x00AB;',
        title: 'previous year'
      },
      previousMonth: {
        content: '&#x2039;',
        title: 'previous month'
      },
      nextMonth: {
        content: '&#x203A;',
        title: 'next month'
      },
      nextYear: {
        content: '&#x00BB;',
        title: 'next year'
      }
    },
    // Date formats.
    formats: {
      titleDate: 'MMMM, YYYY',
      headerDay: 'dd',
      day: 'D'
    },
    // Element to which attach the datepicker.
    element: null,
    // Container in which to insert the datepicker,
    // defaults to document.body if not defined.
    container: null,
    // Default visibility.
    visible: true,
    // Automatically update the calendar position before display.
    autoUpdatePosition: false
  },

  // Initialize the class object.
  initialize: function (options) {
    this.setOptions(options);

    // Bind methods.
    var bind = SimpleDatePicker.bind, property;
    for (property in this) {
      if (typeof this[property] === 'function') {
        this[property] = bind(this[property], this);
      }
    }

    // Event listeners.
    this.listeners = {};

    // Regexp used to extract the date from a day element.
    this.timeMatcher = new RegExp(this.options.classes.time + '-(\\d+)');

    this.selection = [];

    // Set up today.
    this.today = this.options.highlightToday === true ? this.createDate(null, true).valueOf() : null;

    this.create();
  },

  // Handle click on the calendar days and navigation elements.
  handleClick: function (event) {
    var target = event.target,
        hasClass = SimpleDatePicker.hasClass,
        options = this.options,
        classes = options.classes,
        classDayIn = classes.dayIn,
        classPrevious = classes.titlePrevious,
        classNext = classes.titleNext,
        classYear = classes.titleYear,
        calendar;

    if (hasClass(target, classDayIn)) {
      this.select(target);
    }
    else if (hasClass(target, classPrevious)) {
      calendar = options.linked ? null : this.retrieveCalendar(target);
      this.updateCalendars(hasClass(target, classYear) ? 'years' : 'months', -1, calendar);
    }
    else if (hasClass(target, classNext)) {
      calendar = options.linked ? null : this.retrieveCalendar(target);
      this.updateCalendars(hasClass(target, classYear) ? 'years' : 'months', 1, calendar);
    }
    return false;
  },

  // Retrieve a calendar from an element.
  retrieveCalendar: function (element) {
    var hasClass = SimpleDatePicker.hasClass,
        calendarElement = null,
        calendarClass = this.options.classes.calendar,
        calendars = this.calendars,
        calendar, i, l;

    while (element !== this.container) {
      if (hasClass(element, calendarClass)) {
        calendarElement = element;
        break;
      }
      element = element.parentNode;
    }

    if (calendarElement) {
      for (i = 0, l = calendars.length; i < l; i++) {
        calendar = calendars[i];
        if (calendar.calendar === calendarElement) {
          return calendar;
        }
      }
    }
    return null;
  },

  // Retrieve the date associated with a day element.
  retrieveDate: function (day, toDate) {
    var date = parseInt(this.timeMatcher.exec(day.className)[1], 10);
    return toDate === true ? this.createDate(date) : date;
  },

  // Retrieve a list of days matching the given date.
  retrieveDays: function (date) {
    if (this.container.getElementsByClassName) {
      return this.container.getElementsByClassName(this.options.classes.time + '-' + date);
    }
    else {
      var retrieveDate = this.retrieveDate,
          calendars = this.calendars, elements = [],
          days, day, i, l, j, m;
      for (j = 0, m = calendars.length; j < m; j++) {
        days = calendars[j].days;
        for (i = 0, l = days.length; i < l; i++) {
          day = days[i];
          if (retrieveDate(day) === date) {
            elements.push(day);
          }
        }
      }
      return elements;
    }
  },

  // Day selection callback.
  select: function (day) {
    var hasClass = SimpleDatePicker.hasClass,
        options = this.options,
        classSelectedDay = options.classes.selectedDay,
        selected = hasClass(day, classSelectedDay),
        selection = this.selection,
        selectionLength = selection.length,
        mode = options.mode,
        date = this.retrieveDate(day);

    switch (mode) {
      case 'single':
        if (selectionLength > 0) {
          this.unselectAll();
        }
        this.selectDay(date);
        break;

      case 'multiple':
        if (selected) {
          this.unselectDay(date);
        }
        else {
          this.selectDay(date);
        }
        break;

      case 'range':
        if (selectionLength === 1 && selection[0] !== date) {
          this.selectRange(selection[0], date);
        }
        else {
          if (selectionLength > 1) {
            this.unselectAll();
          }
          this.selectDay(date);
        }
        break;
    }

    this.fire('select', this.getSelection());
  },

  // Select a calendar day based on the given date.
  selectDay: function (date, select) {
    var addClass = SimpleDatePicker.addClass,
        removeClass = SimpleDatePicker.removeClass,
        selection = this.selection,
        classSelectedDay = this.options.classes.selectedDay,
        days = this.retrieveDays(date),
        day, i, l;

    // We select all the days of all the calendars with the same date.
    for (i = 0, l = days.length; i < l; i++) {
      day = days[i];
      if (select !== false) {
        addClass(day, classSelectedDay);
      }
      else {
        removeClass(day, classSelectedDay);
      }
    }


    for (i = 0, l = selection.length; i < l; i++) {
      if (selection[i] === date) {
        return select !== false ? null : selection.splice(i, 1);
      }
    }
    selection.push(date);
  },

  // Unselect a day.
  unselectDay: function (date) {
    this.selectDay(date, false);
  },

  // Select a range of days.
  selectRange: function (dateStart, dateEnd) {
    var addClass = SimpleDatePicker.addClass,
        retrieveDate = this.retrieveDate,
        options = this.options,
        classes = options.classes,
        classSelectedDay = classes.selectedDay,
        classActiveDay = classes.activeDay,
        calendars = this.calendars,
        days, day, dateDay,
        temp, i, l, j, m;

    if (dateStart > dateEnd) {
      temp = dateStart;
      dateStart = dateEnd;
      dateEnd = temp;
    }

    for (j = 0, m = calendars.length; j < m; j++) {
      days = calendars[j].days;

      for (i = 0, l = days.length; i < l; i++) {
        day = days[i];
        dateDay = retrieveDate(day);
        if (dateDay > dateStart && dateDay < dateEnd) {
          addClass(day, classActiveDay);
        }
        else if (dateDay === dateStart || dateDay === dateEnd) {
          addClass(day, classSelectedDay);
        }
      }
    }
    this.selection = [dateStart, dateEnd];
  },

  // Unselect all selected days.
  unselectAll: function () {
    var removeClass = SimpleDatePicker.removeClass,
        classes = this.options.classes,
        classSelectedDay = classes.selectedDay,
        classActiveDay = classes.activeDay,
        calendars = this.calendars,
        days, day, i, l, j, m;

    for (j = 0, m = calendars.length; j < m; j++) {
      days = calendars[j].days;
      for (i = 0, l = days.length; i < l; i++) {
        day = days[i];
        removeClass(day, classSelectedDay);
        removeClass(day, classActiveDay);
      }
    }

    this.selection = [];
  },

  // Update a calendar based on the new date.
  updateCalendar: function (calendar, date) {
    calendar.date = date;
    calendar.titleDate.innerHTML = date.format(this.options.formats.titleDate);
    this.updateDays(date, calendar.days);
  },

  // Update calendars when previous/next month/year is pressed.
  updateCalendars: function (type, value, calendar) {
    var calendars = calendar ? [calendar] : this.calendars,
        i, l;
    for (i = 0, l = calendars.length; i < l; i++) {
      calendar = calendars[i];
      if (typeof type !== 'undefined') {
        calendar.date.add(type, value);
      }
      this.updateCalendar(calendar, calendar.date);
    }
  },

  // Mark day as selected if in selection.
  updateSelectedDay: function (day, date) {
    var addClass = SimpleDatePicker.addClass,
        selection = this.selection,
        selectionLength = selection.length,
        options = this.options, i;

    if (options.mode === 'range' && selectionLength > 1 && date > selection[0] && date < selection[1]) {
      addClass(day, options.classes.activeDay);
    }
    else {
      for (i = 0; i < selectionLength; i++) {
        if (selection[i] === date) {
          addClass(day, options.classes.selectedDay);
          break;
        }
      }
    }
  },

  // Update the class and date for a given day element.
  updateDay: function (element, month, date) {
    var options = this.options,
        firstWeekDay = options.firstWeekDay,
        formatDay = options.formats.day,
        classes = options.classes,
        classTime = classes.time,
        classDayIn = classes.dayIn,
        classDayOut = classes.dayOut,
        classFirstWeekDay = classes.firstWeekDay,
        classToday = classes.today,
        time = date.valueOf();

    element.className = (classTime + '-' + time + ' ') +
                        (date.day() === firstWeekDay ? classFirstWeekDay + ' ' : '') +
                        (date.month() === month ? classDayIn : classDayOut) +
                        (this.today === time ? ' ' + classToday : '');
    element.innerHTML = date.format(formatDay);

    this.updateSelectedDay(element, time);

    return element;
  },

  // Update the days of a calendar.
  updateDays: function (date, days) {
    var updateDay = this.updateDay,
        month = date.month(), i;

    date = date.clone().date(0).day(this.options.firstWeekDay);

    // Update the days.
    for (i = 0; i < 42; i++) {
      updateDay(days[i], month, date);
      date.add('days', 1);
    }
  },

  // Create the days of a calendar.
  createDays: function (date, container) {
    var createElement = SimpleDatePicker.createElement,
        updateDay = this.updateDay,
        month = date.month(),
        days = [], i = 42;

    date = date.clone().date(0).day(this.options.firstWeekDay);

    // Create the days.
    while (i--) {
      days.push(updateDay(createElement('span', null, container), month, date));
      date.add('days', 1);
    }

    return days;
  },

  // Create a calendar;
  createCalendar: function (container, date, position) {
    var createElement = SimpleDatePicker.createElement,
        options = this.options,
        classes = options.classes,
        classPrevious = classes.titlePrevious,
        classNext = classes.titleNext,
        classYear = classes.titleYear,
        classMonth = classes.titleMonth,
        navigation = options.navigation,
        previousYear = navigation.previousYear,
        previousMonth = navigation.previousMonth,
        nextMonth = navigation.nextMonth,
        nextYear = navigation.nextYear,
        formats = options.formats,
        formatTitleDate = formats.titleDate,
        formatHeaderDay = formats.headerDay,
        calendar, title, titleDate, header, days,
        day = date.clone().day(options.firstWeekDay),
        i = 7;

    // Calendar.
    calendar = createElement('div', {'class': classes.calendar}, container);

    if (options.calendars > 1) {
      if (position === 0) {
        SimpleDatePicker.addClass(calendar, classes.calendarFirst);
      }
      else if (options.calendars - 1) {
        SimpleDatePicker.addClass(calendar, classes.calendarLast);
      }
      else {
        SimpleDatePicker.addClass(calendar, classes.calendarMiddle);
      }
    }

    // Month, Year header and navigation.
    title = createElement('div', {'class': classes.title}, calendar);
    createElement('span', {'class': classPrevious + ' ' + classYear, title: previousYear.title}, title, previousYear.content);
    createElement('span', {'class': classPrevious + ' ' + classMonth, title: previousMonth.title}, title, previousMonth.content);
    titleDate = createElement('span', {'class': classes.titleDate}, title, date.format(formatTitleDate));
    createElement('span', {'class': classNext + ' ' + classMonth, title: nextMonth.title}, title, nextMonth.content);
    createElement('span', {'class': classNext + ' ' + classYear, title: nextYear.title}, title, nextYear.content);

    // Days header.
    header = createElement('div', {'class': classes.header}, calendar);
    while (i--) {
      createElement('span', null, header, day.format(formatHeaderDay));
      day.add('days', 1);
    }

    // Calendar days.
    days = createElement('div', {'class': classes.days}, calendar);
    days = this.createDays(date, days);

    return {
      calendar: calendar,
      titleDate: titleDate,
      days: days,
      date: date
    };
  },

  // Link calendars, changing month/year affects all calendars.
  linkCalendars: function() {
    SimpleDatePicker.addClass(this.container, this.options.classes.linked);
    return this;
  },

  // Unlink calendars, changing month/year affects only the current calendar.
  unlinkCalendars: function() {
    SimpleDatePicker.removeClass(this.container, this.options.classes.linked);
    return this;
  },

  // Create the calendars.
  create: function () {
    var createElement = SimpleDatePicker.createElement,
        options = this.options,
        container = createElement('div', {'class': options.classes.container}),
        date =  this.createDate(this.options.date, true).date(1),
        calendar, calendars = [],
        i, l;

    for (i = 0, l = options.calendars; i < l; i++) {
      calendar = this.createCalendar(container, date.clone(), i);
      calendars.push(calendar);
      date.add('months', 1);
    }

    if (options.calendars > 1) {
      SimpleDatePicker.addClass(container, options.classes.multiple);

      if (options.linked) {
        this.linkCalendars();
      }
    }

    this.container = container;
    this.calendars = calendars;

    this.updatePosition();

    if (!options.visible) {
      this.hide();
    }

    if (this.options.container) {
      this.options.container.appendChild(container);
    }
    else {
      document.body.appendChild(container);
    }

    SimpleDatePicker.addEventListener(container, 'click', this.handleClick);
  },

  // Create a date wrapper object.
  createDate: function (date, stripTime, utc) {
    date = this.options.dateFunction(date);
    if (utc !== false) {
      date.utc();
    }
    if (stripTime === true) {
      date.hours(0).minutes(0).seconds(0).milliseconds(0);
    }
    return date;
  },

  // Show the calendars.
  show: function () {
    if (this.container.style.display === 'none') {
{'fraction_non_alphanumeric': 0.14053482287007998, 'fraction_numerical': 0.00413828938333921, 'mean_word_length': 2.6297992725313217, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '70729', 'n_tokens_mistral': 16583, 'n_tokens_neox': 16044, 'n_words': 3952}