(function($){
  function Datepicker(){
    this.debug = false;
    this._nextId = 0;
    this._inst = [];
    this._curInst = null;
    this._disabledInputs = [];
    this._datepickerShowing = false;
    this._inDialog = false;
    this.regional = [];
    this.regional[""] = {
      clearText: "Clear",
      clearStatus: "Erase the current date",
      closeText: "Close",
      closeStatus: "Close without change",
      prevText: "&#x3c;Prev",
      prevStatus: "Show the previous month",
      nextText: "Next&#x3e;",
      nextStatus: "Show the next month",
      currentText: "Today",
      currentStatus: "Show the current month",
      monthNames: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
      monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
      monthStatus: "Show a different month",
      yearStatus: "Show a different year",
      weekHeader: "Wk",
      weekStatus: "Week of the year",
      dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
      dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
      dayNamesMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
      dayStatus: "Set DD as first week day",
      dateStatus: "Select DD, M d",
      dateFormat: "mm/dd/yy",
      firstDay: 0,
      initStatus: "Select a date",
      isRTL: false
    };
    this._defaults = {
      showOn: "focus",
      showAnim: "show",
      defaultDate: null,
      appendText: "",
      buttonText: "...",
      buttonImage: "",
      buttonImageOnly: false,
      closeAtTop: true,
      mandatory: false,
      hideIfNoPrevNext: false,
      changeMonth: true,
      changeYear: true,
      yearRange: "-10:+10",
      changeFirstDay: true,
      showOtherMonths: false,
      showWeeks: false,
      calculateWeek: this.iso8601Week,
      shortYearCutoff: "+10",
      showStatus: false,
      statusForDate: this.dateStatus,
      minDate: null,
      maxDate: null,
      speed: "normal",
      beforeShowDay: null,
      beforeShow: null,
      onSelect: null,
      onClose: null,
      numberOfMonths: 1,
      stepMonths: 1,
      rangeSelect: false,
      rangeSeparator: " - "
    };
    $.extend(this._defaults, this.regional[""]);
    this._datepickerDiv = $('<div id="datepicker_div"></div>')
  }
  $.extend(Datepicker.prototype, {
    markerClassName: "hasDatepicker",
    log: function(){
      if (this.debug) 
      {
        console.log.apply("", arguments)
      }
    },
    _register: function(inst){
      var id = this._nextId++;
      this._inst[id] = inst;
      return id
    },
    _getInst: function(id){
      return this._inst[id] || id
    },
    setDefaults: function(settings){
      extendRemove(this._defaults, settings ||
      {});
      return this
    },
    _attachDatepicker: function(target, settings){
      var inlineSettings = null;
      for (attrName in this._defaults) 
      {
        var attrValue = target.getAttribute("date:" + attrName);
        if (attrValue) 
        {
          inlineSettings = inlineSettings ||
          {};
          try 
          {
            inlineSettings[attrName] = eval(attrValue)
          } 
          catch (err) 
          {
            inlineSettings[attrName] = attrValue
          }
        }
      }
      var nodeName = target.nodeName.toLowerCase();
      var instSettings = (inlineSettings ? $.extend(settings ||
      {}, inlineSettings ||
      {}) : settings);
      if (nodeName == "input") 
      {
        var inst = (inst && !inlineSettings ? inst : new DatepickerInstance(instSettings, false));
        this._connectDatepicker(target, inst)
      }
      else 
      {
        if (nodeName == "div" || nodeName == "span") 
        {
          var inst = new DatepickerInstance(instSettings, true);
          this._inlineDatepicker(target, inst)
        }
      }
    },
    _destroyDatepicker: function(target){
      var nodeName = target.nodeName.toLowerCase();
      var calId = target._calId;
      target._calId = null;
      var $target = $(target);
      if (nodeName == "input") 
      {
        $target.siblings(".datepicker_append").replaceWith("").end().siblings(".datepicker_trigger").replaceWith("").end().removeClass(this.markerClassName).unbind("focus", this._showDatepicker).unbind("keydown", this._doKeyDown).unbind("keypress", this._doKeyPress);
        var wrapper = $target.parents(".datepicker_wrap");
        if (wrapper) 
        {
          wrapper.replaceWith(wrapper.html())
        }
      }
      else 
      {
        if (nodeName == "div" || nodeName == "span") 
        {
          $target.removeClass(this.markerClassName).empty()
        }
      }
      if ($("input[_calId=" + calId + "]").length == 0) 
      {
        this._inst[calId] = null
      }
    },
    _enableDatepicker: function(target){
      target.disabled = false;
      $(target).siblings("button.datepicker_trigger").each(function(){
        this.disabled = false
      }).end().siblings("img.datepicker_trigger").css({
        opacity: "1.0",
        cursor: ""
      });
      this._disabledInputs = $.map(this._disabledInputs, function(value){
        return (value == target ? null : value)
      })
    },
    _disableDatepicker: function(target){
      target.disabled = true;
      $(target).siblings("button.datepicker_trigger").each(function(){
        this.disabled = true
      }).end().siblings("img.datepicker_trigger").css({
        opacity: "0.5",
        cursor: "default"
      });
      this._disabledInputs = $.map($.datepicker._disabledInputs, function(value){
        return (value == target ? null : value)
      });
      this._disabledInputs[$.datepicker._disabledInputs.length] = target
    },
    _isDisabledDatepicker: function(target){
      if (!target) 
      {
        return false
      }
      for (var i = 0; i < this._disabledInputs.length; i++) 
      {
        if (this._disabledInputs[i] == target) 
        {
          return true
        }
      }
      return false
    },
    _changeDatepicker: function(target, name, value){
      var settings = name ||
      {};
      if (typeof name == "string") 
      {
        settings = {};
        settings[name] = value
      }
      if (inst = this._getInst(target._calId)) 
      {
        extendRemove(inst._settings, settings);
        this._updateDatepicker(inst)
      }
    },
    _setDateDatepicker: function(target, date, endDate){
      if (inst = this._getInst(target._calId)) 
      {
        inst._setDate(date, endDate);
        this._updateDatepicker(inst)
      }
    },
    _getDateDatepicker: function(target){
      var inst = this._getInst(target._calId);
      return (inst ? inst._getDate() : null)
    },
    _doKeyDown: function(e){
      var inst = $.datepicker._getInst(this._calId);
      if ($.datepicker._datepickerShowing) 
      {
        switch (e.keyCode)
        {
          case 9:
            $.datepicker._hideDatepicker(null, "");
            break;
          case 13:
            $.datepicker._selectDay(inst, inst._selectedMonth, inst._selectedYear, $("td.datepicker_daysCellOver", inst._datepickerDiv)[0]);
            return false;
            break;
          case 27:
            $.datepicker._hideDatepicker(null, inst._get("speed"));
            break;
          case 33:
            $.datepicker._adjustDate(inst, (e.ctrlKey ? -1 : -inst._get("stepMonths")), (e.ctrlKey ? "Y" : "M"));
            break;
          case 34:
            $.datepicker._adjustDate(inst, (e.ctrlKey ? +1 : +inst._get("stepMonths")), (e.ctrlKey ? "Y" : "M"));
            break;
          case 35:
            if (e.ctrlKey) 
            {
              $.datepicker._clearDate(inst)
            }
            break;
          case 36:
            if (e.ctrlKey) 
            {
              $.datepicker._gotoToday(inst)
            }
            break;
          case 37:
            if (e.ctrlKey) 
            {
              $.datepicker._adjustDate(inst, -1, "D")
            }
            break;
          case 38:
            if (e.ctrlKey) 
            {
              $.datepicker._adjustDate(inst, -7, "D")
            }
            break;
          case 39:
            if (e.ctrlKey) 
            {
              $.datepicker._adjustDate(inst, +1, "D")
            }
            break;
          case 40:
            if (e.ctrlKey) 
            {
              $.datepicker._adjustDate(inst, +7, "D")
            }
            break
        }
      }
      else 
      {
        if (e.keyCode == 36 && e.ctrlKey) 
        {
          $.datepicker._showDatepicker(this)
        }
      }
    },
    _doKeyPress: function(e){
      var inst = $.datepicker._getInst(this._calId);
      var chars = $.datepicker._possibleChars(inst._get("dateFormat"));
      var chr = String.fromCharCode(e.charCode == undefined ? e.keyCode : e.charCode);
      return e.ctrlKey || (chr < " " || !chars || chars.indexOf(chr) > -1)
    },
    _connectDatepicker: function(target, inst){
      var input = $(target);
      if (input.is("." + this.markerClassName)) 
      {
        return
      }
      var appendText = inst._get("appendText");
      var isRTL = inst._get("isRTL");
      if (appendText) 
      {
        if (isRTL) 
        {
          input.before('<span class="datepicker_append">' + appendText)
        }
        else 
        {
          input.after('<span class="datepicker_append">' + appendText)
        }
      }
      var showOn = inst._get("showOn");
      if (showOn == "focus" || showOn == "both") 
      {
        input.focus(this._showDatepicker)
      }
      if (showOn == "button" || showOn == "both") 
      {
        input.wrap('<span class="datepicker_wrap">');
        var buttonText = inst._get("buttonText");
        var buttonImage = inst._get("buttonImage");
        var trigger = $(inst._get("buttonImageOnly") ? $("<img>").addClass("datepicker_trigger").attr({
          src: buttonImage,
          alt: buttonText,
          title: buttonText
        }) : $("<button>").addClass("datepicker_trigger").attr({
          type: "button"
        }).html(buttonImage != "" ? $("<img>").attr({
          src: buttonImage,
          alt: buttonText,
          title: buttonText
        }) : buttonText));
        if (isRTL) 
        {
          input.before(trigger)
        }
        else 
        {
          input.after(trigger)
        }
        trigger.click(function(){
          if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target) 
          {
            $.datepicker._hideDatepicker()
          }
          else 
          {
            $.datepicker._showDatepicker(target)
          }
        })
      }
      input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).bind("setData.datepicker", function(event, key, value){
        inst._settings[key] = value
      }).bind("getData.datepicker", function(event, key){
        return inst._get(key)
      });
      input[0]._calId = inst._id
    },
    _inlineDatepicker: function(target, inst){
      var input = $(target);
      if (input.is("." + this.markerClassName)) 
      {
        return
      }
      input.addClass(this.markerClassName).append(inst._datepickerDiv).bind("setData.datepicker", function(event, key, value){
        inst._settings[key] = value
      }).bind("getData.datepicker", function(event, key){
        return inst._get(key)
      });
      input[0]._calId = inst._id;
      this._updateDatepicker(inst)
    },
    _inlineShow: function(inst){
      var numMonths = inst._getNumberOfMonths();
      inst._datepickerDiv.width(numMonths[1] * $(".datepicker", inst._datepickerDiv[0]).width())
    },
    _dialogDatepicker: function(input, dateText, onSelect, settings, pos){
      var inst = this._dialogInst;
      if (!inst) 
      {
        inst = this._dialogInst = new DatepickerInstance({}, false);
        this._dialogInput = $('<input type="text" size="1" style="position: absolute; top: -100px;"/>');
        this._dialogInput.keydown(this._doKeyDown);
        $("body").append(this._dialogInput);
        this._dialogInput[0]._calId = inst._id
      }
      extendRemove(inst._settings, settings ||
      {});
      this._dialogInput.val(dateText);
      this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
      if (!this._pos) 
      {
        var browserWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
        var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
        var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
        var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
        this._pos = [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]
      }
      this._dialogInput.css("left", this._pos[0] + "px").css("top", this._pos[1] + "px");
      inst._settings.onSelect = onSelect;
      this._inDialog = true;
      this._datepickerDiv.addClass("datepicker_dialog");
      this._showDatepicker(this._dialogInput[0]);
      if ($.blockUI) 
      {
        $.blockUI(this._datepickerDiv)
      }
      return this
    },
    _showDatepicker: function(input){
      input = input.target || input;
      if (input.nodeName.toLowerCase() != "input") 
      {
        input = $("input", input.parentNode)[0]
      }
      if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) 
      {
        return
      }
      var inst = $.datepicker._getInst(input._calId);
      var beforeShow = inst._get("beforeShow");
      extendRemove(inst._settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
      $.datepicker._hideDatepicker(null, "");
      $.datepicker._lastInput = input;
      inst._setDateFromField(input);
      if ($.datepicker._inDialog) 
      {
        input.value = ""
      }
      if (!$.datepicker._pos) 
      {
        $.datepicker._pos = $.datepicker._findPos(input);
        $.datepicker._pos[1] += input.offsetHeight
      }
      var isFixed = false;
      $(input).parents().each(function(){
        isFixed |= $(this).css("position") == "fixed"
      });
      if (isFixed && $.browser.opera) 
      {
        $.datepicker._pos[0] -= document.documentElement.scrollLeft;
        $.datepicker._pos[1] -= document.documentElement.scrollTop
      }
      inst._datepickerDiv.css("position", ($.datepicker._inDialog && $.blockUI ? "static" : (isFixed ? "fixed" : "absolute"))).css({
        left: $.datepicker._pos[0] + "px",
        top: $.datepicker._pos[1] + "px"
      });
      $.datepicker._pos = null;
      inst._rangeStart = null;
      $.datepicker._updateDatepicker(inst);
      if (!inst._inline) 
      {
        var speed = inst._get("speed");
        var postProcess = function(){
          $.datepicker._datepickerShowing = true;
          $.datepicker._afterShow(inst)
        };
        var showAnim = inst._get("showAnim") || "show";
        inst._datepickerDiv[showAnim](speed, postProcess);
        if (speed == "") 
        {
          postProcess()
        }
        if (inst._input[0].type != "hidden") 
        {
          inst._input[0].focus()
        }
        $.datepicker._curInst = inst
      }
    },
    _updateDatepicker: function(inst){
      inst._datepickerDiv.empty().append(inst._generateDatepicker());
      var numMonths = inst._getNumberOfMonths();
      if (numMonths[0] != 1 || numMonths[1] != 1) 
      {
        inst._datepickerDiv.addClass("datepicker_multi")
      }
      else 
      {
        inst._datepickerDiv.removeClass("datepicker_multi")
      }
      if (inst._get("isRTL")) 
      {
        inst._datepickerDiv.addClass("datepicker_rtl")
      }
      else 
      {
        inst._datepickerDiv.removeClass("datepicker_rtl")
      }
      if (inst._input && inst._input[0].type != "hidden") 
      {
        $(inst._input[0]).focus()
      }
    },
    _afterShow: function(inst){
      var numMonths = inst._getNumberOfMonths();
      inst._datepickerDiv.width(numMonths[1] * $(".datepicker", inst._datepickerDiv[0])[0].offsetWidth);
      if ($.browser.msie && parseInt($.browser.version) < 7) 
      {
        $("iframe.datepicker_cover").css({
          width: inst._datepickerDiv.width() + 4,
          height: inst._datepickerDiv.height() + 4
        })
      }
      var isFixed = inst._datepickerDiv.css("position") == "fixed";
      var pos = inst._input ? $.datepicker._findPos(inst._input[0]) : null;
      var browserWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
      var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
      var scrollX = (isFixed ? 0 : document.documentElement.scrollLeft || document.body.scrollLeft);
      var scrollY = (isFixed ? 0 : document.documentElement.scrollTop || document.body.scrollTop);
      if ((inst._datepickerDiv.offset().left + inst._datepickerDiv.width() - (isFixed && $.browser.msie ? document.documentElement.scrollLeft : 0)) > (browserWidth + scrollX)) 
      {
        inst._datepickerDiv.css("left", Math.max(scrollX, pos[0] + (inst._input ? $(inst._input[0]).width() : null) - inst._datepickerDiv.width() - (isFixed && $.browser.opera ? document.documentElement.scrollLeft : 0)) + "px")
      }
      if ((inst._datepickerDiv.offset().top + inst._datepickerDiv.height() - (isFixed && $.browser.msie ? document.documentElement.scrollTop : 0)) > (browserHeight + scrollY)) 
      {
        inst._datepickerDiv.css("top", Math.max(scrollY, pos[1] - (this._inDialog ? 0 : inst._datepickerDiv.height()) - (isFixed && $.browser.opera ? document.documentElement.scrollTop : 0)) + "px")
      }
    },
    _findPos: function(obj){
      while (obj && (obj.type == "hidden" || obj.nodeType != 1)) 
      {
        obj = obj.nextSibling
      }
      var position = $(obj).offset();
      return [position.left, position.top]
    },
    _hideDatepicker: function(input, speed){
      var inst = this._curInst;
      if (!inst) 
      {
        return
      }
      var rangeSelect = inst._get("rangeSelect");
      if (rangeSelect && this._stayOpen) 
      {
        this._selectDate(inst, inst._formatDate(inst._currentDay, inst._currentMonth, inst._currentYear))
      }
      this._stayOpen = false;
      if (this._datepickerShowing) 
      {
        speed = (speed != null ? speed : inst._get("speed"));
        var showAnim = inst._get("showAnim");
        inst._datepickerDiv[(showAnim == "slideDown" ? "slideUp" : (showAnim == "fadeIn" ? "fadeOut" : "hide"))](speed, function(){
          $.datepicker._tidyDialog(inst)
        });
        if (speed == "") 
        {
          this._tidyDialog(inst)
        }
        var onClose = inst._get("onClose");
        if (onClose) 
        {
          onClose.apply((inst._input ? inst._input[0] : null), [inst._getDate(), inst])
        }
        this._datepickerShowing = false;
        this._lastInput = null;
        inst._settings.prompt = null;
        if (this._inDialog) 
        {
          this._dialogInput.css({
            position: "absolute",
            left: "0",
            top: "-100px"
          });
          if ($.blockUI) 
          {
            $.unblockUI();
            $("body").append(this._datepickerDiv)
          }
        }
        this._inDialog = false
      }
      this._curInst = null
    },
    _tidyDialog: function(inst){
      inst._datepickerDiv.removeClass("datepicker_dialog").unbind(".datepicker");
      $(".datepicker_prompt", inst._datepickerDiv).remove()
    },
    _checkExternalClick: function(event){
      if (!$.datepicker._curInst) 
      {
        return
      }
      var $target = $(event.target);
      if (($target.parents("#datepicker_div").length == 0) && ($target.attr("class") != "datepicker_trigger") && $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI)) 
      {
        $.datepicker._hideDatepicker(null, "")
      }
    },
    _adjustDate: function(id, offset, period){
      var inst = this._getInst(id);
      inst._adjustDate(offset, period);
      this._updateDatepicker(inst)
    },
    _gotoToday: function(id){
      var date = new Date();
      var inst = this._getInst(id);
      inst._selectedDay = date.getDate();
      inst._drawMonth = inst._selectedMonth = date.getMonth();
      inst._drawYear = inst._selectedYear = date.getFullYear();
      this._adjustDate(inst)
    },
    _selectMonthYear: function(id, select, period){
      var inst = this._getInst(id);
      inst._selectingMonthYear = false;
      inst[period == "M" ? "_drawMonth" : "_drawYear"] = select.options[select.selectedIndex].value - 0;
      this._adjustDate(inst)
    },
    _clickMonthYear: function(id){
      var inst = this._getInst(id);
      if (inst._input && inst._selectingMonthYear && !$.browser.msie) 
      {
        inst._input[0].focus()
      }
      inst._selectingMonthYear = !inst._selectingMonthYear
    },
    _changeFirstDay: function(id, day){
      var inst = this._getInst(id);
      inst._settings.firstDay = day;
      this._updateDatepicker(inst)
    },
    _selectDay: function(id, month, year, td){
      if ($(td).is(".datepicker_unselectable")) 
      {
        return
      }
      var inst = this._getInst(id);
      var rangeSelect = inst._get("rangeSelect");
      if (rangeSelect) 
      {
        if (!this._stayOpen) 
        {
          $(".datepicker td").removeClass("datepicker_currentDay");
          $(td).addClass("datepicker_currentDay")
        }
        this._stayOpen = !this._stayOpen
      }
      inst._selectedDay = inst._currentDay = $("a", td).html();
      inst._selectedMonth = inst._currentMonth = month;
      inst._selectedYear = inst._currentYear = year;
      this._selectDate(id, inst._formatDate(inst._currentDay, inst._currentMonth, inst._currentYear));
      if (this._stayOpen) 
      {
        inst._endDay = inst._endMonth = inst._endYear = null;
        inst._rangeStart = new Date(inst._currentYear, inst._currentMonth, inst._currentDay);
        this._updateDatepicker(inst)
      }
      else 
      {
        if (rangeSelect) 
        {
          inst._endDay = inst._currentDay;
          inst._endMonth = inst._currentMonth;
          inst._endYear = inst._currentYear;
          inst._selectedDay = inst._currentDay = inst._rangeStart.getDate();
          inst._selectedMonth = inst._currentMonth = inst._rangeStart.getMonth();
          inst._selectedYear = inst._currentYear = inst._rangeStart.getFullYear();
          inst._rangeStart = null;
          if (inst._inline) 
          {
            this._updateDatepicker(inst)
          }
        }
      }
    },
    _clearDate: function(id){
      var inst = this._getInst(id);
      if (inst._get("mandatory")) 
      {
        return
      }
      this._stayOpen = false;
      inst._endDay = inst._endMonth = inst._endYear = inst._rangeStart = null;
      this._selectDate(inst, "")
    },
    _selectDate: function(id, dateStr){
      var inst = this._getInst(id);
      dateStr = (dateStr != null ? dateStr : inst._formatDate());
      if (inst._rangeStart) 
      {
        dateStr = inst._formatDate(inst._rangeStart) + inst._get("rangeSeparator") + dateStr
      }
      if (inst._input) 
      {
        inst._input.val(dateStr)
      }
      var onSelect = inst._get("onSelect");
      if (onSelect) 
      {
        onSelect.apply((inst._input ? inst._input[0] : null), [dateStr, inst])
      }
      else 
      {
        if (inst._input) 
        {
          inst._input.trigger("change")
        }
      }
      if (inst._inline) 
      {
        this._updateDatepicker(inst)
      }
      else 
      {
        if (!this._stayOpen) 
        {
          this._hideDatepicker(null, inst._get("speed"));
          this._lastInput = inst._input[0];
          if (typeof(inst._input[0]) != "object") 
          {
            inst._input[0].focus()
          }
          this._lastInput = null
        }
      }
    },
    noWeekends: function(date){
      var day = date.getDay();
      return [(day > 0 && day < 6), ""]
    },
    iso8601Week: function(date){
      var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), (date.getTimezoneOffset() / -60));
      var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4);
      var firstDay = firstMon.getDay() || 7;
      firstMon.setDate(firstMon.getDate() + 1 - firstDay);
      if (firstDay < 4 && checkDate < firstMon) 
      {
        checkDate.setDate(checkDate.getDate() - 3);
        return $.datepicker.iso8601Week(checkDate)
      }
      else 
      {
        if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) 
        {
          firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7;
          if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) 
          {
            checkDate.setDate(checkDate.getDate() + 3);
            return $.datepicker.iso8601Week(checkDate)
          }
        }
      }
      return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1
    },
    dateStatus: function(date, inst){
      return $.datepicker.formatDate(inst._get("dateStatus"), date, inst._getFormatConfig())
    },
    parseDate: function(format, value, settings){
      if (format == null || value == null) 
      {
        throw "Invalid arguments"
      }
      value = (typeof value == "object" ? value.toString() : value + "");
      if (value == "") 
      {
        return null
      }
      var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
      var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
      var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
      var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
      var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
      var year = -1;
      var month = -1;
      var day = -1;
      var literal = false;
      var lookAhead = function(match){
        var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
        if (matches) 
        {
          iFormat++
        }
        return matches
      };
      var getNumber = function(match){
        lookAhead(match);
        var size = (match == "y" ? 4 : 2);
        var num = 0;
        while (size > 0 && iValue < value.length && value.charAt(iValue) >= "0" && value.charAt(iValue) <= "9") 
        {
          num = num * 10 + (value.charAt(iValue++) - 0);
          size--
        }
        if (size == (match == "y" ? 4 : 2)) 
        {
          throw "Missing number at position " + iValue
        }
        return num
      };
      var getName = function(match, shortNames, longNames){
        var names = (lookAhead(match) ? longNames : shortNames);
        var size = 0;
        for (var j = 0; j < names.length; j++) 
        {
          size = Math.max(size, names[j].length)
        }
        var name = "";
        var iInit = iValue;
        while (size > 0 && iValue < value.length) 
        {
          name += value.charAt(iValue++);
          for (var i = 0; i < names.length; i++) 
          {
            if (name == names[i]) 
            {
              return i + 1
            }
          }
          size--
        }
        throw "Unknown name at position " + iInit
      };
      var checkLiteral = function(){
        if (value.charAt(iValue) != format.charAt(iFormat)) 
        {
          throw "Unexpected literal at position " + iValue
        }
        iValue++
      };
      var iValue = 0;
      for (var iFormat = 0; iFormat < format.length; iFormat++) 
      {
        if (literal) 
        {
          if (format.charAt(iFormat) == "'" && !lookAhead("'")) 
          {
            literal = false
          }
          else 
          {
            checkLiteral()
          }
        }
        else 
        {
          switch (format.charAt(iFormat))
          {
            case "d":
              day = getNumber("d");
              break;
            case "D":
              getName("D", dayNamesShort, dayNames);
              break;
            case "m":
              month = getNumber("m");
              break;
            case "M":
              month = getName("M", monthNamesShort, monthNames);
              break;
            case "y":
              year = getNumber("y");
              break;
            case "'":
              if (lookAhead("'")) 
              {
                checkLiteral()
              }
              else 
              {
                literal = true
              }
              break;
            default:
              checkLiteral()
          }
        }
      }
      if (year < 100) 
      {
        year += new Date().getFullYear() - new Date().getFullYear() % 100 + (year <= shortYearCutoff ? 0 : -100)
      }
      var date = new Date(year, month - 1, day);
      if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) 
      {
        throw "Invalid date"
      }
      return date
    },
    formatDate: function(format, date, settings){
      if (!date) 
      {
        return ""
      }
      var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
      var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
      var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
      var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
      var lookAhead = function(match){
        var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
        if (matches) 
        {
          iFormat++
        }
        return matches
      };
      var formatNumber = function(match, value){
        return (lookAhead(match) && value < 10 ? "0" : "") + value
      };
      var formatName = function(match, value, shortNames, longNames){
        return (lookAhead(match) ? longNames[value] : shortNames[value])
      };
      var output = "";
      var literal = false;
      if (date) 
      {
        for (var iFormat = 0; iFormat < format.length; iFormat++) 
        {
          if (literal) 
          {
            if (format.charAt(iFormat) == "'" && !lookAhead("'")) 
            {
              literal = false
            }
            else 
            {
              output += format.charAt(iFormat)
            }
          }
          else 
          {
            switch (format.charAt(iFormat))
            {
              case "d":
                output += formatNumber("d", date.getDate());
                break;
              case "D":
                output += formatName("D", date.getDay(), dayNamesShort, dayNames);
                break;
              case "m":
                output += formatNumber("m", date.getMonth() + 1);
                break;
              case "M":
                output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
                break;
              case "y":
                output += (lookAhead("y") ? date.getFullYear() : (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
                break;
              case "'":
                if (lookAhead("'")) 
                {
                  output += "'"
                }
                else 
                {
                  literal = true
                }
                break;
              default:
                output += format.charAt(iFormat)
            }
          }
        }
      }
      return output
    },
    _possibleChars: function(format){
      var chars = "";
      var literal = false;
      for (var iFormat = 0; iFormat < format.length; iFormat++) 
      {
        if (literal) 
        {
          if (format.charAt(iFormat) == "'" && !lookAhead("'")) 
          {
            literal = false
          }
          else 
          {
            chars += format.charAt(iFormat)
          }
        }
        else 
        {
          switch (format.charAt(iFormat))
          {
            case "d" || "m" || "y":
              chars += "0123456789";
              break;
            case "D" || "M":
              return null;
            case "'":
              if (lookAhead("'")) 
              {
                chars += "'"
              }
              else 
              {
                literal = true
              }
              break;
            default:
              chars += format.charAt(iFormat)
          }
        }
      }
      return chars
    }
  });
  function DatepickerInstance(settings, inline){
    this._id = $.datepicker._register(this);
    this._selectedDay = 0;
    this._selectedMonth = 0;
    this._selectedYear = 0;
    this._drawMonth = 0;
    this._drawYear = 0;
    this._input = null;
    this._inline = inline;
    this._datepickerDiv = (!inline ? $.datepicker._datepickerDiv : $('<div id="datepicker_div_' + this._id + '" class="datepicker_inline">'));
    this._settings = extendRemove(settings ||
    {});
    if (inline) 
    {
      this._setDate(this._getDefaultDate())
    }
  }
  $.extend(DatepickerInstance.prototype, {
    _get: function(name){
      return this._settings[name] !== undefined ? this._settings[name] : $.datepicker._defaults[name]
    },
    _setDateFromField: function(input){
      this._input = $(input);
      var dateFormat = this._get("dateFormat");
      var dates = this._input ? this._input.val().split(this._get("rangeSeparator")) : null;
      this._endDay = this._endMonth = this._endYear = null;
      var date = defaultDate = this._getDefaultDate();
      if (dates.length > 0) 
      {
        var settings = this._getFormatConfig();
        if (dates.length > 1) 
        {
          date = $.datepicker.parseDate(dateFormat, dates[1], settings) || defaultDate;
          this._endDay = date.getDate();
          this._endMonth = date.getMonth();
          this._endYear = date.getFullYear()
        }
        try 
        {
          date = $.datepicker.parseDate(dateFormat, dates[0], settings) || defaultDate
        } 
        catch (e) 
        {
          $.datepicker.log(e);
          date = defaultDate
        }
      }
      this._selectedDay = date.getDate();
      this._drawMonth = this._selectedMonth = date.getMonth();
      this._drawYear = this._selectedYear = date.getFullYear();
      this._currentDay = (dates[0] ? date.getDate() : 0);
      this._currentMonth = (dates[0] ? date.getMonth() : 0);
      this._currentYear = (dates[0] ? date.getFullYear() : 0);
      this._adjustDate()
    },
    _getDefaultDate: function(){
      var date = this._determineDate("defaultDate", new Date());
      var minDate = this._getMinMaxDate("min", true);
      var maxDate = this._getMinMaxDate("max");
      date = (minDate && date < minDate ? minDate : date);
      date = (maxDate && date > maxDate ? maxDate : date);
      return date
    },
    _determineDate: function(name, defaultDate){
      var offsetNumeric = function(offset){
        var date = new Date();
        date.setDate(date.getDate() + offset);
        return date
      };
      var offsetString = function(offset, getDaysInMonth){
        var date = new Date();
        var matches = /^([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?$/.exec(offset);
        if (matches) 
        {
          var year = date.getFullYear();
          var month = date.getMonth();
          var day = date.getDate();
          switch (matches[2] || "d")
          {
            case "d":
            case "D":
              day += (matches[1] - 0);
              break;
            case "w":
            case "W":
              day += (matches[1] * 7);
              break;
            case "m":
            case "M":
              month += (matches[1] - 0);
              day = Math.min(day, getDaysInMonth(year, month));
              break;
            case "y":
            case "Y":
              year += (matches[1] - 0);
              day = Math.min(day, getDaysInMonth(year, month));
              break
          }
          date = new Date(year, month, day)
        }
        return date
      };
      var date = this._get(name);
      return (date == null ? defaultDate : (typeof date == "string" ? offsetString(date, this._getDaysInMonth) : (typeof date == "number" ? offsetNumeric(date) : date)))
    },
    _setDate: function(date, endDate){
      this._selectedDay = this._currentDay = date.getDate();
      this._drawMonth = this._selectedMonth = this._currentMonth = date.getMonth();
      this._drawYear = this._selectedYear = this._currentYear = date.getFullYear();
      if (this._get("rangeSelect")) 
      {
        if (endDate) 
        {
          this._endDay = endDate.getDate();
          this._endMonth = endDate.getMonth();
          this._endYear = endDate.getFullYear()
        }
        else 
        {
          this._endDay = this._currentDay;
          this._endMonth = this._currentMonth;
          this._endYear = this._currentYear
        }
      }
      this._adjustDate()
    },
    _getDate: function(){
      var startDate = (!this._currentYear || (this._input && this._input.val() == "") ? null : new Date(this._currentYear, this._currentMonth, this._currentDay));
      if (this._get("rangeSelect")) 
      {
        return [startDate, (!this._endYear ? null : new Date(this._endYear, this._endMonth, this._endDay))]
      }
      else 
      {
        return startDate
      }
    },
    _generateDatepicker: function(){
      var today = new Date();
      today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
      var showStatus = this._get("showStatus");
      var isRTL = this._get("isRTL");
      var clear = (this._get("mandatory") ? "" : '<div class="datepicker_clear"><a onclick="jQuery.datepicker._clearDate(' + this._id + ');"' + (showStatus ? this._addStatus(this._get("clearStatus") || "&#xa0;") : "") + ">" + this._get("clearText") + "</a></div>");
      var controls = '<div class="datepicker_control">' + (isRTL ? "" : clear) + '<div class="datepicker_close"><a onclick="jQuery.datepicker._hideDatepicker();"' + (showStatus ? this._addStatus(this._get("closeStatus") || "&#xa0;") : "") + ">" + this._get("closeText") + "</a></div>" + (isRTL ? clear : "") + "</div>";
      var prompt = this._get("prompt");
      var closeAtTop = this._get("closeAtTop");
      var hideIfNoPrevNext = this._get("hideIfNoPrevNext");
      var numMonths = this._getNumberOfMonths();
      var stepMonths = this._get("stepMonths");
      var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
      var minDate = this._getMinMaxDate("min", true);
      var maxDate = this._getMinMaxDate("max");
      var drawMonth = this._drawMonth;
      var drawYear = this._drawYear;
      if (maxDate) 
      {
        var maxDraw = new Date(maxDate.getFullYear(), maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate());
        maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
        while (new Date(drawYear, drawMonth, 1) > maxDraw) 
        {
          drawMonth--;
          if (drawMonth < 0) 
          {
            drawMonth = 11;
            drawYear--
          }
        }
      }
      var prev = '<div class="datepicker_prev">' + (this._canAdjustMonth(-1, drawYear, drawMonth) ? '<a onclick="jQuery.datepicker._adjustDate(' + this._id + ", -" + stepMonths + ", 'M');\"" + (showStatus ? this._addStatus(this._get("prevStatus") || "&#xa0;") : "") + ">" + this._get("prevText") + "</a>" : (hideIfNoPrevNext ? "" : "<label>" + this._get("prevText") + "</label>")) + "</div>";
      var next = '<div class="datepicker_next">' + (this._canAdjustMonth(+1, drawYear, drawMonth) ? '<a onclick="jQuery.datepicker._adjustDate(' + this._id + ", +" + stepMonths + ", 'M');\"" + (showStatus ? this._addStatus(this._get("nextStatus") || "&#xa0;") : "") + ">" + this._get("nextText") + "</a>" : (hideIfNoPrevNext ? ">" : "<label>" + this._get("nextText") + "</label>")) + "</div>";
      var html = (prompt ? '<div class="datepicker_prompt">' + prompt + "</div>" : "") + (closeAtTop && !this._inline ? controls : "") + '<div class="datepicker_links">' + (isRTL ? next : prev) + (this._isInRange(today) ? '<div class="datepicker_current"><a onclick="jQuery.datepicker._gotoToday(' + this._id + ');"' + (showStatus ? this._addStatus(this._get("currentStatus") || "&#xa0;") : "") + ">" + this._get("currentText") + "</a></div>" : "") + (isRTL ? prev : next) + "</div>";
      var showWeeks = this._get("showWeeks");
      for (var row = 0; row < numMonths[0]; row++) 
      {
        for (var col = 0; col < numMonths[1]; col++) 
        {
          var selectedDate = new Date(drawYear, drawMonth, this._selectedDay);
          html += '<div class="datepicker_oneMonth' + (col == 0 ? " datepicker_newRow" : "") + '">' + this._generateMonthYearHeader(drawMonth, drawYear, minDate, maxDate, selectedDate, row > 0 || col > 0) + '<table class="datepicker" cellpadding="0" cellspacing="0"><thead><tr class="datepicker_titleRow">' + (showWeeks ? "<td>" + this._get("weekHeader") + "</td>" : "");
          var firstDay = this._get("firstDay");
          var changeFirstDay = this._get("changeFirstDay");
          var dayNames = this._get("dayNames");
          var dayNamesShort = this._get("dayNamesShort");
          var dayNamesMin = this._get("dayNamesMin");
          for (var dow = 0; dow < 7; dow++) 
          {
            var day = (dow + firstDay) % 7;
            var status = this._get("dayStatus") || "&#xa0;";
            status = (status.indexOf("DD") > -1 ? status.replace(/DD/, dayNames[day]) : status.replace(/D/, dayNamesShort[day]));
            html += "<td" + ((dow + firstDay + 6) % 7 >= 5 ? ' class="datepicker_weekEndCell"' : "") + ">" + (!changeFirstDay ? "<span" : '<a onclick="jQuery.datepicker._changeFirstDay(' + this._id + ", " + day + ');"') + (showStatus ? this._addStatus(status) : "") + ' title="' + dayNames[day] + '">' + dayNamesMin[day] + (changeFirstDay ? "</a>" : "</span>") + "</td>"
          }
          html += "</tr></thead><tbody>";
          var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
          if (drawYear == this._selectedYear && drawMonth == this._selectedMonth) 
          {
            this._selectedDay = Math.min(this._selectedDay, daysInMonth)
          }
          var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
          var currentDate = (!this._currentDay ? new Date(9999, 9, 9) : new Date(this._currentYear, this._currentMonth, this._currentDay));
          var endDate = this._endDay ? new Date(this._endYear, this._endMonth, this._endDay) : currentDate;
          var printDate = new Date(drawYear, drawMonth, 1 - leadDays);
          var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7));
          var beforeShowDay = this._get("beforeShowDay");
          var showOtherMonths = this._get("showOtherMonths");
          var calculateWeek = this._get("calculateWeek") || $.datepicker.iso8601Week;
          var dateStatus = this._get("statusForDate") || $.datepicker.dateStatus;
          for (var dRow = 0; dRow < numRows; dRow++) 
          {
            html += '<tr class="datepicker_daysRow">' + (showWeeks ? '<td class="datepicker_weekCol">' + calculateWeek(printDate) + "</td>" : "");
            for (var dow = 0; dow < 7; dow++) 
            {
              var daySettings = (beforeShowDay ? beforeShowDay.apply((this._input ? this._input[0] : null), [printDate]) : [true, ""]);
              var otherMonth = (printDate.getMonth() != drawMonth);
              var unselectable = otherMonth || !daySettings[0] || (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
              html += '<td class="datepicker_daysCell' + ((dow + firstDay + 6) % 7 >= 5 ? " datepicker_weekEndCell" : "") + (otherMonth ? " datepicker_otherMonth" : "") + (printDate.getTime() == selectedDate.getTime() && drawMonth == this._selectedMonth ? " datepicker_daysCellOver" : "") + (unselectable ? " datepicker_unselectable" : "") + (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? " datepicker_currentDay" : "") + (printDate.getTime() == today.getTime() ? " datepicker_today" : "")) + '"' + (unselectable ? "" : " onmouseover=\"jQuery(this).addClass('datepicker_daysCellOver');" + (!showStatus || (otherMonth && !showOtherMonths) ? "" : "jQuery('#datepicker_status_" + this._id + "').html('" + (dateStatus.apply((this._input ? this._input[0] : null), [printDate, this]) || "&#xa0;") + "');") + "\" onmouseout=\"jQuery(this).removeClass('datepicker_daysCellOver');" + (!showStatus || (otherMonth && !showOtherMonths) ? "" : "jQuery('#datepicker_status_" + this._id + "').html('&#xa0;');") + '" onclick="jQuery.datepicker._selectDay(' + this._id + "," + drawMonth + "," + drawYear + ', this);"') + ">" + (otherMonth ? (showOtherMonths ? printDate.getDate() : "&#xa0;") : (unselectable ? printDate.getDate() : "<a>" + printDate.getDate() + "</a>")) + "</td>";
              printDate.setDate(printDate.getDate() + 1)
            }
            html += "</tr>"
          }
          drawMonth++;
          if (drawMonth > 11) 
          {
            drawMonth = 0;
            drawYear++
          }
          html += "</tbody></table></div>"
        }
      }
      html += (showStatus ? '<div style="clear: both;"></div><div id="datepicker_status_' + this._id + '" class="datepicker_status">' + (this._get("initStatus") || "&#xa0;") + "</div>" : "") + (!closeAtTop && !this._inline ? controls : "") + '<div style="clear: both;"></div>' + ($.browser.msie && parseInt($.browser.version) < 7 && !this._inline ? '<iframe src="javascript:false;" class="datepicker_cover"></iframe>' : "");
      return html
    },
    _generateMonthYearHeader: function(drawMonth, drawYear, minDate, maxDate, selectedDate, secondary){
      minDate = (this._rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate);
      var showStatus = this._get("showStatus");
      var html = '<div class="datepicker_header">';
      var monthNames = this._get("monthNames");
      if (secondary || !this._get("changeMonth")) 
      {
        html += monthNames[drawMonth] + "&#xa0;"
      }
      else 
      {
        var inMinYear = (minDate && minDate.getFullYear() == drawYear);
        var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
        html += '<select class="datepicker_newMonth" onchange="jQuery.datepicker._selectMonthYear(' + this._id + ", this, 'M');\" onclick=\"jQuery.datepicker._clickMonthYear(" + this._id + ');"' + (showStatus ? this._addStatus(this._get("monthStatus") || "&#xa0;") : "") + ">";
        for (var month = 0; month < 12; month++) 
        {
          if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) 
          {
            html += '<option value="' + month + '"' + (month == drawMonth ? ' selected="selected"' : "") + ">" + monthNames[month] + "</option>"
          }
        }
        html += "</select>"
      }
      if (secondary || !this._get("changeYear")) 
      {
        html += drawYear
      }
      else 
      {
        var years = this._get("yearRange").split(":");
        var year = 0;
        var endYear = 0;
        if (years.length != 2) 
        {
          year = drawYear - 10;
          endYear = drawYear + 10
        }
        else 
        {
          if (years[0].charAt(0) == "+" || years[0].charAt(0) == "-") 
          {
            year = drawYear + parseInt(years[0], 10);
            endYear = drawYear + parseInt(years[1], 10)
          }
          else 
          {
            year = parseInt(years[0], 10);
            endYear = parseInt(years[1], 10)
          }
        }
        year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
        endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
        html += '<select class="datepicker_newYear" onchange="jQuery.datepicker._selectMonthYear(' + this._id + ", this, 'Y');\" onclick=\"jQuery.datepicker._clickMonthYear(" + this._id + ');"' + (showStatus ? this._addStatus(this._get("yearStatus") || "&#xa0;") : "") + ">";
        for (; year <= endYear; year++) 
        {
          html += '<option value="' + year + '"' + (year == drawYear ? ' selected="selected"' : "") + ">" + year + "</option>"
        }
        html += "</select>"
      }
      html += "</div>";
      return html
    },
    _addStatus: function(text){
      return " onmouseover=\"jQuery('#datepicker_status_" + this._id + "').html('" + text + "');\" onmouseout=\"jQuery('#datepicker_status_" + this._id + "').html('&#xa0;');\""
    },
    _adjustDate: function(offset, period){
      var year = this._drawYear + (period == "Y" ? offset : 0);
      var month = this._drawMonth + (period == "M" ? offset : 0);
      var day = Math.min(this._selectedDay, this._getDaysInMonth(year, month)) + (period == "D" ? offset : 0);
      var date = new Date(year, month, day);
      var minDate = this._getMinMaxDate("min", true);
      var maxDate = this._getMinMaxDate("max");
      date = (minDate && date < minDate ? minDate : date);
      date = (maxDate && date > maxDate ? maxDate : date);
      this._selectedDay = date.getDate();
      this._drawMonth = this._selectedMonth = date.getMonth();
      this._drawYear = this._selectedYear = date.getFullYear()
    },
    _getNumberOfMonths: function(){
      var numMonths = this._get("numberOfMonths");
      return (numMonths == null ? [1, 1] : (typeof numMonths == "number" ? [1, numMonths] : numMonths))
    },
    _getMinMaxDate: function(minMax, checkRange){
      var date = this._determineDate(minMax + "Date", null);
      if (date) 
      {
        date.setHours(0);
        date.setMinutes(0);
        date.setSeconds(0);
        date.setMilliseconds(0)
      }
      return date || (checkRange ? this._rangeStart : null)
    },
    _getDaysInMonth: function(year, month){
      return 32 - new Date(year, month, 32).getDate()
    },
    _getFirstDayOfMonth: function(year, month){
      return new Date(year, month, 1).getDay()
    },
    _canAdjustMonth: function(offset, curYear, curMonth){
      var numMonths = this._getNumberOfMonths();
      var date = new Date(curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1);
      if (offset < 0) 
      {
        date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()))
      }
      return this._isInRange(date)
    },
    _isInRange: function(date){
      var newMinDate = (!this._rangeStart ? null : new Date(this._selectedYear, this._selectedMonth, this._selectedDay));
      newMinDate = (newMinDate && this._rangeStart < newMinDate ? this._rangeStart : newMinDate);
      var minDate = newMinDate || this._getMinMaxDate("min");
      var maxDate = this._getMinMaxDate("max");
      return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate))
    },
    _getFormatConfig: function(){
      var shortYearCutoff = this._get("shortYearCutoff");
      shortYearCutoff = (typeof shortYearCutoff != "string" ? shortYearCutoff : new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
      return {
        shortYearCutoff: shortYearCutoff,
        dayNamesShort: this._get("dayNamesShort"),
        dayNames: this._get("dayNames"),
        monthNamesShort: this._get("monthNamesShort"),
        monthNames: this._get("monthNames")
      }
    },
    _formatDate: function(day, month, year){
      if (!day) 
      {
        this._currentDay = this._selectedDay;
        this._currentMonth = this._selectedMonth;
        this._currentYear = this._selectedYear
      }
      var date = (day ? (typeof day == "object" ? day : new Date(year, month, day)) : new Date(this._currentYear, this._currentMonth, this._currentDay));
      return $.datepicker.formatDate(this._get("dateFormat"), date, this._getFormatConfig())
    }
  });
  function extendRemove(target, props){
    $.extend(target, props);
    for (var name in props) 
    {
      if (props[name] == null) 
      {
        target[name] = null
      }
    }
    return target
  }
  $.fn.datepicker = function(options){
    var otherArgs = Array.prototype.slice.call(arguments, 1);
    if (typeof options == "string" && (options == "isDisabled" || options == "getDate")) 
    {
      return $.datepicker["_" + options + "Datepicker"].apply($.datepicker, [this[0]].concat(otherArgs))
    }
    return this.each(function(){
      typeof options == "string" ? $.datepicker["_" + options + "Datepicker"].apply($.datepicker, [this].concat(otherArgs)) : $.datepicker._attachDatepicker(this, options)
    })
  };
  $.datepicker = new Datepicker();
  $(document).ready(function(){
    $(document.body).append($.datepicker._datepickerDiv).mousedown($.datepicker._checkExternalClick)
  })
})(jQuery);

