// Configuration String used in various .js files across the project

//var rootUrl = "http://localhost:9038/";
//var rootUrl = "http://hct-2:9038/";
//var rootUrl = "http://localhost/birmingham_met/";
//var rootUrl = "http://bm.hiltonbusinessonline.com/";
//var rootUrl = "http://www.birminghammetropole.com/";
var rootUrl = "http://localhost/~george/birminghammetropole.com/"

/*****************************************************************************
It is adviced to place the sIFR JavaScript calls in this file, keeping it
separate from the `sifr.js` file. That way, you can easily swap the `sifr.js`
file for a new version, while keeping the configuration.

You must load this file *after* loading `sifr.js`.

That said, you're of course free to merge the JavaScript files. Just make sure
the copyright statement in `sifr.js` is kept intact.
*****************************************************************************/

// Make an object pointing to the location of the Flash movie on your web server.
// Try using the font name as the variable name, makes it easy to remember which
// object you're using. As an example in this file, we'll use Futura.
//var futura = { src: '/path/to/futura.swf' };
var univers_lt_std_57_cn = { src: 'http://www.birminghammetropole.com/swf/sifr/univers_lt_std_57_cn.swf' };
var univers_lt_45 = { src: 'http://www.birminghammetropole.com/swf/sifr/univers_lt_45.swf' };
var bodoni_antiqua_italic = { src: 'http://www.birminghammetropole.com/swf/sifr/bodoni_antiqua_italic.swf' };


// Now you can set some configuration settings.
// See also <http://wiki.novemberborn.net/sifr3/JavaScript+Configuration>.
// One setting you probably want to use is `sIFR.useStyleCheck`. Before you do that,
// read <http://wiki.novemberborn.net/sifr3/DetectingCSSLoad>.

// sIFR.useStyleCheck = true;

// Next, activate sIFR:
//sIFR.activate(futura);
sIFR.activate(univers_lt_std_57_cn,bodoni_antiqua_italic,univers_lt_45);

// If you want, you can use multiple movies, like so:
//
//    var futura = { src: '/path/to/futura.swf' };
//    var garamond = { src '/path/to/garamond.swf' };
//    var rockwell = { src: '/path/to/rockwell.swf' };
//    
//    sIFR.activate(futura, garamond, rockwell);
//
// Remember, there must be *only one* `sIFR.activate()`!

// Now we can do the replacements. You can do as many as you like, but just
// as an example, we'll replace all `<h1>` elements with the Futura movie.
// 
// The first argument to `sIFR.replace` is the `futura` object we created earlier.
// The second argument is another object, on which you can specify a number of
// parameters or "keyword arguemnts". For the full list, see "Keyword arguments"
// under `replace(kwargs, mergeKwargs)` at 
// <http://wiki.novemberborn.net/sifr3/JavaScript+Methods>.
// 
// The first argument you see here is `selector`, which is a normal CSS selector.
// That means you can also do things like '#content h1' or 'h1.title'.
//
// The second argument determines what the Flash text looks like. The main text
// is styled via the `.sIFR-root` class. Here we've specified `background-color`
// of the entire Flash movie to be a light grey, and the `color` of the text to
// be red. Read more about styling at <http://wiki.novemberborn.net/sifr3/Styling>.
sIFR.replace(univers_lt_std_57_cn, {
  selector: '#header address',
  css: '.sIFR-root { background-color:#462915 ; color: #B2A18D; text-align:right }',
  wmode: 'transparent'
});

sIFR.replace(univers_lt_45, {
  selector: '#introtext h1',
  css: '.sIFR-root { background-color:#967D5C ; color: #EDE0D6; text-align:left }',
  wmode: 'transparent'
});

sIFR.replace(univers_lt_45, {
  selector: '#homepage_copy h1',
  css: '.sIFR-root { background-color:#967D5C ;color:#7C6342; text-align:left }',
  wmode: 'transparent'
});

sIFR.replace(univers_lt_45, {
  selector: '#content h1',
  css: '.sIFR-root { background-color:#967D5C ;color:#EDE0D6; text-align:left }',
  wmode: 'transparent'
});



//sIFR.replace(bodoni_antiqua_italic, {
  //selector: '#homepage_copy h1',
  //css: '.sIFR-root { background-color:#F4F1E4 ; color: #7C6342; }, strong{color:#976812}',
  //wmode: 'transparent'
//});

  /**
* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
* 
* @param  f  onMouseOver function || An object with configuration options
* @param  g  onMouseOut function  || Nothing (use configuration options object)
* @author    Brian Cherne <brian@cherne.net>
*/
(function($){$.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};cfg=$.extend(cfg,g?{over:f,out:g}:f);var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY;};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);ob.hoverIntent_s=1;return cfg.over.apply(ob,[ev]);}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=0;return cfg.out.apply(ob,[ev]);};var handleHover=function(e){var p=(e.type=="mouseover"?e.fromElement:e.toElement)||e.relatedTarget;while(p&&p!=this){try{p=p.parentNode;}catch(e){p=this;}}if(p==this){return false;}var ev=jQuery.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);}if(e.type=="mouseover"){pX=ev.pageX;pY=ev.pageY;$(ob).bind("mousemove",track);if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}}else{$(ob).unbind("mousemove",track);if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob);},cfg.timeout);}}};return this.mouseover(handleHover).mouseout(handleHover);};})(jQuery);

/******************** timer.js  ****************************/

(function($) {

  if (typeof $.timeout != "undefined") return; 

  $.extend({
    timeout : function (func,delay) {
      // init
      if (typeof $.timeout.count == "undefined") $.timeout.count = 0;   
      if (typeof $.timeout.funcs == "undefined") $.timeout.funcs = new Array(); 
      // set timeout
      if (typeof func =='string') return setTimeout(func, delay); 
      if (typeof func =='function') {
        $.timeout.count++;
        $.timeout.funcs[$.timeout.count] = func;
        return setTimeout("$.timeout.funcs['"+$.timeout.count+"']();", delay);
      }
    },
    interval : function (func,delay) {
      // init
      if (typeof $.interval.count == "undefined") $.interval.count = 0;   
      if (typeof $.interval.funcs == "undefined") $.interval.funcs = new Array(); 
      // set interval
      if (typeof func =='string') return setInterval(func, delay); 
      if (typeof func =='function') {
        $.interval.count++;
        $.interval.funcs[$.interval.count] = func;
        return setInterval("$.interval.funcs['"+$.interval.count+"']();", delay);
      }
    },
    idle : function (func,delay) {
      // init
      if (typeof $.idle.lasttimeout == "undefined") $.idle.lasttimeout = null;
      if (typeof $.idle.lastfunc == "undefined") $.idle.lastfunc = null;
      // set idle timeout
      if ($.idle.timeout) { clearTimeout($.idle.timeout); $.idle.timeout = null; $.idle.lastfunc = null; }
      if (typeof(func)=='string') { 
        $.idle.timeout = setTimeout(func, delay); 
        return $.idle.timeout;
      }   
      if (typeof(func)=='function') { 
        $.idle.lastfunc = func;
        $.idle.timeout = setTimeout("$.idle.lastfunc();", delay);
        return $.idle.timeout;
      }
    },
    clear : function (countdown) {
    clearInterval(countdown);
    clearTimeout(countdown);
    } 
    
  });
  
  
})(jQuery);

/******************** end of timer.js  ****************************/



/* jQuery UI Date Picker v3.4.3 (previously jQuery Calendar)
   Written by Marc Grabanski (m@marcgrabanski.com) and Keith Wood (kbwood@virginbroadband.com.au).

   Copyright (c) 2007 Marc Grabanski (http://marcgrabanski.com/code/ui-datepicker)
   Dual licensed under the MIT (MIT-LICENSE.txt)
   and GPL (GPL-LICENSE.txt) licenses.
   Date: 09-03-2007  */
   
(function($) { // hide the namespace

/* Date picker manager.
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
   Settings for (groups of) date pickers are maintained in an instance object
   (DatepickerInstance), allowing multiple different settings on the same page. */

function Datepicker() {
  this.debug = false; // Change this to true to start debugging
  this._nextId = 0; // Next ID for a date picker instance
  this._inst = []; // List of instances indexed by ID
  this._curInst = null; // The current instance in use
  this._disabledInputs = []; // List of date picker inputs that have been disabled
  this._datepickerShowing = false; // True if the popup picker is showing , false if not
  this._inDialog = false; // True if showing within a "dialog", false if not
  this.regional = []; // Available regional settings, indexed by language code
  this.regional[''] = { // Default regional settings
    clearText: 'Clear', // Display text for clear link
    clearStatus: 'Erase the current date', // Status text for clear link
    closeText: 'Close', // Display text for close link
    closeStatus: 'Close without change', // Status text for close link
    prevText: '&#x3c;Prev', // Display text for previous month link
    prevStatus: 'Show the previous month', // Status text for previous month link
    nextText: 'Next&#x3e;', // Display text for next month link
    nextStatus: 'Show the next month', // Status text for next month link
    currentText: 'Today', // Display text for current month link
    currentStatus: 'Show the current month', // Status text for current month link
    monthNames: ['January','February','March','April','May','June',
      'July','August','September','October','November','December'], // Names of months for drop-down and formatting
    monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
    monthStatus: 'Show a different month', // Status text for selecting a month
    yearStatus: 'Show a different year', // Status text for selecting a year
    weekHeader: 'Wk', // Header for the week of the year column
    weekStatus: 'Week of the year', // Status text for the week of the year column
    dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
    dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
    dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
    dayStatus: 'Set DD as first week day', // Status text for the day of the week selection
    dateStatus: 'Select DD, M d', // Status text for the date selection
    dateFormat: 'mm/dd/yy', // See format options on parseDate
    firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
    initStatus: 'Select a date', // Initial Status text on opening
    isRTL: false // True if right-to-left language, false if left-to-right
  };
  this._defaults = { // Global defaults for all the date picker instances
    showOn: 'focus', // 'focus' for popup on focus,
      // 'button' for trigger button, or 'both' for either
    showAnim: 'show', // Name of jQuery animation for popup
    defaultDate: null, // Used when field is blank: actual date,
      // +/-number for offset from today, null for today
    appendText: '', // Display text following the input box, e.g. showing the format
    buttonText: '...', // Text for trigger button
    buttonImage: '', // URL for trigger button image
    buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
    closeAtTop: true, // True to have the clear/close at the top,
      // false to have them at the bottom
    mandatory: false, // True to hide the Clear link, false to include it
    hideIfNoPrevNext: false, // True to hide next/previous month links
      // if not applicable, false to just disable them
    changeMonth: true, // True if month can be selected directly, false if only prev/next
    changeYear: true, // True if year can be selected directly, false if only prev/next
    yearRange: '00:+01', // Range of years to display in drop-down,
      // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn)
    changeFirstDay: true, // True to click on day name to change, false to remain as set
    showOtherMonths: false, // True to show dates in other months, false to leave blank
    showWeeks: false, // True to show week of the year, false to omit
    calculateWeek: this.iso8601Week, // How to calculate the week of the year,
      // takes a Date and returns the number of the week for it
    shortYearCutoff: '+12', // Short year values < this are in the current century,
      // > this are in the previous century, 
      // string value starting with '+' for current year + value
    showStatus: false, // True to show status bar at bottom, false to not show it
    statusForDate: this.dateStatus, // Function to provide status text for a date -
      // takes date and instance as parameters, returns display text
    minDate: 0, // The earliest selectable date, or null for no limit
    maxDate: +365, // The latest selectable date, or null for no limit
    speed: 'normal', // Speed of display/closure
    beforeShowDay: null, // Function that takes a date and returns an array with
      // [0] = true if selectable, false if not,
      // [1] = custom CSS class name(s) or '', e.g. $.datepicker.noWeekends
    beforeShow: null, // Function that takes an input field and
      // returns a set of custom settings for the date picker
    onSelect: null, // Define a callback function when a date is selected
    onClose: null, // Define a callback function when the datepicker is closed
    numberOfMonths: 1, // Number of months to show at a time
    stepMonths: 1, // Number of months to step back/forward
    rangeSelect: false, // Allows for selecting a date range on one date picker
    rangeSeparator: ' - ' // Text between two dates in a range
  };
  $.extend(this._defaults, this.regional['']);
  this._datepickerDiv = $('<div id="datepicker_div">');
}

$.extend(Datepicker.prototype, {
  /* Class name added to elements to indicate already configured with a date picker. */
  markerClassName: 'hasDatepicker',

  /* Debug logging (if enabled). */
  log: function () {
    if (this.debug)
      console.log.apply('', arguments);
  },
  
  /* Register a new date picker instance - with custom settings. */
  _register: function(inst) {
    var id = this._nextId++;
    this._inst[id] = inst;
    return id;
  },

  /* Retrieve a particular date picker instance based on its ID. */
  _getInst: function(id) {
    return this._inst[id] || id;
  },

  /* Override the default settings for all instances of the date picker. 
     @param  settings  object - the new settings to use as defaults (anonymous object)
     @return the manager object */
  setDefaults: function(settings) {
    extendRemove(this._defaults, settings || {});
    return this;
  },

  /* Attach the date picker to a jQuery selection.
     @param  target    element - the target input field or division or span
     @param  settings  object - the new settings to use for this date picker instance (anonymous) */
  _attachDatepicker: function(target, settings) {
    // check for settings on the control itself - in namespace 'date:'
    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);
    }
  },

  /* Detach a datepicker from its control.
     @param  target    element - the target input field or division or span */
  _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)
      // clean up if last for this ID
      this._inst[calId] = null;
  },

  /* Enable the date picker to a jQuery selection.
     @param  target    element - the target input field or division or span */
  _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); }); // delete entry
  },

  /* Disable the date picker to a jQuery selection.
     @param  target    element - the target input field or division or span */
  _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); }); // delete entry
    this._disabledInputs[$.datepicker._disabledInputs.length] = target;
  },

  /* Is the first field in a jQuery collection disabled as a datepicker?
     @param  target    element - the target input field or division or span
     @return boolean - true if disabled, false if enabled */
  _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;
  },

  /* Update the settings for a date picker attached to an input field or division.
     @param  target  element - the target input field or division or span
     @param  name    string - the name of the setting to change or
                     object - the new settings to update
     @param  value   any - the new value for the setting (omit if above is an object) */
  _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);
    }
  },

  /* Set the dates for a jQuery selection.
     @param  target   element - the target input field or division or span
     @param  date     Date - the new date
     @param  endDate  Date - the new end date for a range (optional) */
  _setDateDatepicker: function(target, date, endDate) {
    if (inst = this._getInst(target._calId)) {
      inst._setDate(date, endDate);
      this._updateDatepicker(inst);
    }
  },

  /* Get the date(s) for the first entry in a jQuery selection.
     @param  target  element - the target input field or division or span
     @return Date - the current date or
             Date[2] - the current dates for a range */
  _getDateDatepicker: function(target) {
    var inst = this._getInst(target._calId);
    return (inst ? inst._getDate() : null);
  },

  /* Handle keystrokes. */
  _doKeyDown: function(e) {
    var inst = $.datepicker._getInst(this._calId);
    if ($.datepicker._datepickerShowing)
      switch (e.keyCode) {
        case 9:  $.datepicker._hideDatepicker(null, '');
            break; // hide on tab out
        case 13: $.datepicker._selectDay(inst, inst._selectedMonth, inst._selectedYear,
              $('td.datepicker_daysCellOver', inst._datepickerDiv)[0]);
            return false; // don't submit the form
            break; // select the value on enter
        case 27: $.datepicker._hideDatepicker(null, inst._get('speed'));
            break; // hide on escape
        case 33: $.datepicker._adjustDate(inst,
              (e.ctrlKey ? -1 : -inst._get('stepMonths')), (e.ctrlKey ? 'Y' : 'M'));
            break; // previous month/year on page up/+ ctrl
        case 34: $.datepicker._adjustDate(inst,
              (e.ctrlKey ? +1 : +inst._get('stepMonths')), (e.ctrlKey ? 'Y' : 'M'));
            break; // next month/year on page down/+ ctrl
        case 35: if (e.ctrlKey) $.datepicker._clearDate(inst);
            break; // clear on ctrl+end
        case 36: if (e.ctrlKey) $.datepicker._gotoToday(inst);
            break; // current on ctrl+home
        case 37: if (e.ctrlKey) $.datepicker._adjustDate(inst, -1, 'D');
            break; // -1 day on ctrl+left
        case 38: if (e.ctrlKey) $.datepicker._adjustDate(inst, -7, 'D');
            break; // -1 week on ctrl+up
        case 39: if (e.ctrlKey) $.datepicker._adjustDate(inst, +1, 'D');
            break; // +1 day on ctrl+right
        case 40: if (e.ctrlKey) $.datepicker._adjustDate(inst, +7, 'D');
            break; // +1 week on ctrl+down
      }
    else if (e.keyCode == 36 && e.ctrlKey) // display the date picker on ctrl+home
      $.datepicker._showDatepicker(this);
  },

  /* Filter entered characters - based on date format. */
  _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);
  },

  /* Attach the date picker to an input field. */
  _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') // pop-up date picker when in the marked field
      input.focus(this._showDatepicker);
    if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
      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;
  },

  /* Attach an inline date picker to a div. */
  _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);
  },

  /* Tidy up after displaying the date picker. */
  _inlineShow: function(inst) {
    var numMonths = inst._getNumberOfMonths(); // fix width for dynamic number of date pickers
    inst._datepickerDiv.width(numMonths[1] * $('.datepicker', inst._datepickerDiv[0]).width());
  }, 

  /* Pop-up the date picker in a "dialog" box.
     @param  input     element - ignored
     @param  dateText  string - the initial date to display (in the current format)
     @param  onSelect  function - the function(dateText) to call when a date is selected
     @param  settings  object - update the dialog date picker instance's settings (anonymous object)
     @param  pos       int[2] - coordinates for the dialog's position within the screen or
                       event - with x/y coordinates or
                       leave empty for default (screen centre)
     @return the manager object */
  _dialogDatepicker: function(input, dateText, onSelect, settings, pos) {
    var inst = this._dialogInst; // internal instance
    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 = // should use actual width/height below
        [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
    }

    // move input on screen for focus, but hidden behind dialog
    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;
  },

  /* Pop-up the date picker for a given input field.
     @param  input  element - the input field attached to the date picker or
                    event - if triggered by focus */
  _showDatepicker: function(input) {
    input = input.target || input;
    if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
      input = $('input', input.parentNode)[0];
    if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
      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) // hide cursor
      input.value = '';
    if (!$.datepicker._pos) { // position below input
      $.datepicker._pos = $.datepicker._findPos(input);
      $.datepicker._pos[1] += input.offsetHeight; // add the height
    }
    var isFixed = false;
    $(input).parents().each(function() {
      isFixed |= $(this).css('position') == 'fixed';
    });
    if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
      $.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;
    }
  },

  /* Generate the date picker content. */
  _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();
  },

  /* Tidy up after displaying the date picker. */
  _afterShow: function(inst) {
    var numMonths = inst._getNumberOfMonths(); // fix width for dynamic number of date pickers
    inst._datepickerDiv.width(numMonths[1] * $('.datepicker', inst._datepickerDiv[0])[0].offsetWidth);
    if ($.browser.msie && parseInt($.browser.version) < 7) { // fix IE < 7 select problems
      $('#datepicker_cover').css({width: inst._datepickerDiv.width() + 4,
        height: inst._datepickerDiv.height() + 4});
    }
    // re-position on screen if necessary
    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);
    // reposition date picker horizontally if outside the browser window
    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');
    }
    // reposition date picker vertically if outside the browser window
    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');
    }
  },
  
  /* Find an object's position on the screen. */
  _findPos: function(obj) {
        while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
            obj = obj.nextSibling;
        }
        var position = $(obj).offset();
      return [position.left, position.top];
  },

  /* Hide the date picker from view.
     @param  input  element - the input field attached to the date picker
     @param  speed  string - the speed at which to close the date picker */
  _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]);  // trigger custom callback
      }
      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;
  },

  /* Tidy up after a dialog display. */
  _tidyDialog: function(inst) {
    inst._datepickerDiv.removeClass('datepicker_dialog').unbind('.datepicker');
    $('.datepicker_prompt', inst._datepickerDiv).remove();
  },

  /* Close date picker if clicked elsewhere. */
  _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, '');
    }
  },

  /* Adjust one of the date sub-fields. */
  _adjustDate: function(id, offset, period) {
    var inst = this._getInst(id);
    inst._adjustDate(offset, period);
    this._updateDatepicker(inst);
  },

  /* Action for current link. */
  _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);
  },

  /* Action for selecting a new month/year. */
  _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);
  },

  /* Restore input focus after not changing month/year. */
  _clickMonthYear: function(id) {
    var inst = this._getInst(id);
    if (inst._input && inst._selectingMonthYear && !$.browser.msie)
      inst._input[0].focus();
    inst._selectingMonthYear = !inst._selectingMonthYear;
  },

  /* Action for changing the first week day. */
  _changeFirstDay: function(id, day) {
    var inst = this._getInst(id);
    inst._settings.firstDay = day;
    this._updateDatepicker(inst);
  },

  /* Action for selecting a day. */
  _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);
    }
  },

  /* Erase the input field and hide the date picker. */
  _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, '');
  },

  /* Update the input field with the selected date. */
  _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]);  // trigger custom callback
    else if (inst._input)
      inst._input.trigger('change'); // fire the change event
    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(); // restore focus
      this._lastInput = null;
    }
  },

  /* Set as beforeShowDay function to prevent selection of weekends.
     @param  date  Date - the date to customise
     @return [boolean, string] - is this date selectable?, what is its CSS class? */
  noWeekends: function(date) {
    var day = date.getDay();
    return [(day > 0 && day < 6), ''];
  },
  
  /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
     @param  date  Date - the date to get the week for
     @return  number - the number of the week within the year that contains this date */
  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); // First week always contains 4 Jan
    var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7
    firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday
    if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary
      checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year
      return $.datepicker.iso8601Week(checkDate);
    } else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year
      firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7;
      if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary
        checkDate.setDate(checkDate.getDate() + 3); // Generate for next year
        return $.datepicker.iso8601Week(checkDate);
      }
    }
    return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date
  },
  
  /* Provide status text for a particular date.
     @param  date  the date to get the status for
     @param  inst  the current datepicker instance
     @return  the status display text for this date */
  dateStatus: function(date, inst) {
    return $.datepicker.formatDate(inst._get('dateStatus'), date, inst._getFormatConfig());
  },

  /* Parse a string value into a date object.
     The format can be combinations of the following:
     d  - day of month (no leading zero)
     dd - day of month (two digit)
     D  - day name short
     DD - day name long
     m  - month of year (no leading zero)
     mm - month of year (two digit)
     M  - month name short
     MM - month name long
     y  - year (two digit)
     yy - year (four digit)
     '...' - literal text
     '' - single quote

     @param  format           String - the expected format of the date
     @param  value            String - the date in the above format
     @param  settings  Object - attributes include:
                       shortYearCutoff  Number - the cutoff year for determining the century (optional)
                       dayNamesShort    String[7] - abbreviated names of the days from Sunday (optional)
                       dayNames         String[7] - names of the days from Sunday (optional)
                       monthNamesShort  String[12] - abbreviated names of the months (optional)
                       monthNames       String[12] - names of the months (optional)
     @return  Date - the extracted date value or null if value is blank */
  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;
    // Check whether a format character is doubled
    var lookAhead = function(match) {
      var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
      if (matches)
        iFormat++;
      return matches; 
    };
    // Extract a number from the string value
    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;
    };
    // Extract a name from the string value and convert to an index
    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;
    };
    // Confirm that a literal character matches the string value
    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'; // E.g. 31/02/*
    }
    return date;
  },

  /* Format a date object into a string value.
     The format can be combinations of the following:
     d  - day of month (no leading zero)
     dd - day of month (two digit)
     D  - day name short
     DD - day name long
     m  - month of year (no leading zero)
     mm - month of year (two digit)
     M  - month name short
     MM - month name long
     y  - year (two digit)
     yy - year (four digit)
     '...' - literal text
     '' - single quote

     @param  format    String - the desired format of the date
     @param  date      Date - the date value to format
     @param  settings  Object - attributes include:
                       dayNamesShort    String[7] - abbreviated names of the days from Sunday (optional)
                       dayNames         String[7] - names of the days from Sunday (optional)
                       monthNamesShort  String[12] - abbreviated names of the months (optional)
                       monthNames       String[12] - names of the months (optional)
     @return  String - the date in the above format */
  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;
    // Check whether a format character is doubled
    var lookAhead = function(match) {
      var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
      if (matches)
        iFormat++;
      return matches; 
    };
    // Format a number, with leading zero if necessary
    var formatNumber = function(match, value) {
      return (lookAhead(match) && value < 10 ? '0' : '') + value;
    };
    // Format a name, short or long as requested
    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;
  },

  /* Extract all possible characters from the date format. */
  _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; // Accept anything
          case "'":
            if (lookAhead("'"))
              chars += "'";
            else
              literal = true;
            break;
          default:
            chars += format.charAt(iFormat);
        }
    return chars;
  }
});

/* Individualised settings for date picker functionality applied to one or more related inputs.
   Instances are managed and manipulated through the Datepicker manager. */
function DatepickerInstance(settings, inline) {
  this._id = $.datepicker._register(this);
  this._selectedDay = 0; // Current date for selection
  this._selectedMonth = 0; // 0-11
  this._selectedYear = 0; // 4-digit year
  this._drawMonth = 0; // Current month at start of datepicker
  this._drawYear = 0;
  this._input = null; // The attached input field
  this._inline = inline; // True if showing inline, false if used in a popup
  this._datepickerDiv = (!inline ? $.datepicker._datepickerDiv :
    $('<div id="datepicker_div_' + this._id + '" class="datepicker_inline">'));
  // customise the date picker object - uses manager defaults if not overridden
  this._settings = extendRemove(settings || {}); // clone
  if (inline)
    this._setDate(this._getDefaultDate());
}

$.extend(DatepickerInstance.prototype, {
  /* Get a setting value, defaulting if necessary. */
  _get: function(name) {
    return this._settings[name] || $.datepicker._defaults[name];
  },

  /* Parse existing date and initialise date picker. */
  _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();
  },
  
  /* Retrieve the default date shown on opening. */
  _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;
  },

  /* A date may be specified as an exact value or a relative one. */
  _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)));
  },

  /* Set the date(s) directly. */
  _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();
  },

  /* Retrieve the date(s) directly. */
  _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;
  },

  /* Generate the HTML for the current state of the date picker. */
  _generateDatepicker: function() {
    var today = new Date();
    today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); // clear time
    var showStatus = this._get('showStatus');
    var isRTL = this._get('isRTL');
    // build the date picker HTML
    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--;
        }
      }
    }
    // controls and links
    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) + // draw month headers
          '<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++) { // days of the week
          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)); // calculate the number of rows to generate
        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++) { // create date picker rows
          html += '<tr class="datepicker_daysRow">' +
            (showWeeks ? '<td class="datepicker_weekCol">' + calculateWeek(printDate) + '</td>' : '');
          for (var dow = 0; dow < 7; dow++) { // create date picker days
            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' : '') + // highlight weekends
              (otherMonth ? ' datepicker_otherMonth' : '') + // highlight days from other months
              (printDate.getTime() == selectedDate.getTime() && drawMonth == this._selectedMonth ?
              ' datepicker_daysCellOver' : '') + // highlight selected day
              (unselectable ? ' datepicker_unselectable' : '') +  // highlight unselectable days
              (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
              (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ?  // in current range
              ' datepicker_currentDay' : '') + // highlight selected day
              (printDate.getTime() == today.getTime() ? ' datepicker_today' : '')) + '"' + // highlight today (if different)
              (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);"') + '>' + // actions
              (otherMonth ? (showOtherMonths ? printDate.getDate() : '&#xa0;') : // display for other months
              (unselectable ? printDate.getDate() : '<a>' + printDate.getDate() + '</a>')) + '</td>'; // display for this month
            printDate.setDate(printDate.getDate() + 1);
          }
          html += '</tr>';
        }
        drawMonth++;
        if (drawMonth > 11) {
          drawMonth = 0;
          drawYear++;
        }
        html += '</tbody></table></div>';
      }
    html += (showStatus ? '<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;
  },
  
  /* Generate the month and year header. */
  _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">';
    // month selection
    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>';
    }
    // year selection
    if (secondary || !this._get('changeYear'))
      html += drawYear;
    else {
      // determine range of years to display
      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>'; // Close datepicker_header
    return html;
  },

  /* Provide code to set and clear the status panel. */
  _addStatus: function(text) {
    return ' onmouseover="jQuery(\'#datepicker_status_' + this._id + '\').html(\'' + text + '\');" ' +
      'onmouseout="jQuery(\'#datepicker_status_' + this._id + '\').html(\'&#xa0;\');"';
  },

  /* Adjust one of the date sub-fields. */
  _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);
    // ensure it is within the bounds set
    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();
  },
  
  /* Determine the number of months to show. */
  _getNumberOfMonths: function() {
    var numMonths = this._get('numberOfMonths');
    return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
  },

  /* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */
  _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);
  },

  /* Find the number of days in a given month. */
  _getDaysInMonth: function(year, month) {
    return 32 - new Date(year, month, 32).getDate();
  },

  /* Find the day of the week of the first of a month. */
  _getFirstDayOfMonth: function(year, month) {
    return new Date(year, month, 1).getDay();
  },

  /* Determines if we should allow a "next/prev" month display change. */
  _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);
  },

  /* Is the given date in the accepted range? */
  _isInRange: function(date) {
    // during range selection, use minimum of selected date and range start
    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));
  },
  
  /* Provide the configuration settings for formatting/parsing. */
  _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')};
  },

  /* Format the given date for display. */
  _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());
  }
});

/* jQuery extend now ignores nulls! */
function extendRemove(target, props) {
  $.extend(target, props);
  for (var name in props)
    if (props[name] == null)
      target[name] = null;
  return target;
};

/* Invoke the datepicker functionality.
   @param  options  String - a command, optionally followed by additional parameters or
                    Object - settings for attaching new datepicker functionality
   @return  jQuery object */
$.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);
  });
};
  
/* Initialise the date picker. */
$(document).ready(function() {
  $(document.body).append($.datepicker._datepickerDiv)
    .mousedown($.datepicker._checkExternalClick);
});

$.datepicker = new Datepicker(); // singleton instance

})(jQuery);

  $(function() {  
    /**********   Reservation Form  **********/
    $.datepicker.setDefaults({showOn: 'both', buttonImageOnly: true, 
      buttonImage: 'images/calendar.gif', dateFormat: 'dd/mm/y'}); 
    $("#dateinput1").datepicker();                
    $("#dateinput2").datepicker();  
    $("#dateinput3").datepicker();  
    function loadCalLink2() { 
        var longDateFixArr = $("#dateinput1").val();
        var day1 = longDateFixArr.substring(0,2); 
        var month1 = longDateFixArr.substring(3,5); 
        var year1 = 20 + longDateFixArr.substring(6,11);
        var trueMonth1 = month1  - 1;  
        var arrival1 =new Date(year1, trueMonth1, day1);
        
        var longDateFixDep = $("#dateinput2").val();
        var day2 = longDateFixDep.substring(0,2); 
        var month2 = longDateFixDep.substring(3,5); 
        var year2 = 20 + longDateFixDep.substring(6,11);
        var trueMonth2 = month2 - 1;  
        var dep =new Date(year2, trueMonth2, day2);
        
        var theLink2 = "https://secure.hilton.com/en/wa/res/choose_dates.jhtml?hotel=ROMHIWA&arrivalDay=" + day1 + "&arrivalMonth=" + month1
        + "&arrivalYear=" + year1+ "&departureDay=" + day2 + "&departureMonth=" + month2 + "&departureYear=" + year2+ "&WT.mc_id=1HI2MS3rome4en";
        $("p#fixSearch a").attr("href", theLink2);
    }
    function loadCalLink() { 
        var longDate = $("#dateinput3").val();
        var day = longDate.substring(0,2); 
        var month = longDate.substring(3,5); 
        var year = 20 + longDate.substring(6,11);
        var trueMonth = month - 1;  
        var arrival =new Date(year, trueMonth, day);
        var longSecs = arrival.getTime();
        var nights = $("#dateinput4").val(); 
        if(nights.length > 8) {
          var numNights = nights.substring(0,2);
          } else {
          var numNights = nights.substring(0,1);
        }
        var nightSecs = numNights * 60 * 60 * 24*1000;
        var departSecs = longSecs + nightSecs;
        var departDate = new Date(departSecs); 
        var depDay = departDate.getDate();
        var depMonth = (departDate.getMonth()) + 1;
        var depYear = departDate.getFullYear(); 
        var theLink = "https://secure.hilton.com/en/wa/res/choose_dates.jhtml?hotel=ROMHIWA&arrivalDay=" + day + "&arrivalMonth=" + month 
        + "&arrivalYear=" + year+ "&departureDay=" + depDay + "&departureMonth=" + depMonth + "&departureYear=" + depYear+ "&WT.mc_id=1HI2MS3rome4en";
        $("p#flexSearch a").attr("href", theLink);
    }           
         
        $("#flexible input").change(  
          function() {
            loadCalLink();
          }
        ); 
        $("#flexible input").click(  
          function() {
            loadCalLink();
          }
        ); 
        
        $("ul#nightSlide").click(  
          function() {
            loadCalLink();
          }
        );
        
        $("#fixed input").change(  
          function() {
            loadCalLink2();
          }
        ); 
        $("#fixed input").click(  
          function() {
            loadCalLink2();
          }
        ); 
        
        $("p#fix").click(
          function() {
            $("#fixed").hide();
            $("#flexible").show();
          }
        );
        $("p#flex").click(
          function() {
            $("#flexible").hide();
            $("#fixed").show();
          }
        );
        
    $("#fixed ul").hide(); 
    $("img#lengthStayBtn").toggle(
        function() { $("#flexible ul#nightSlide").slideDown("fast");}, 
        function() { $("#flexible ul#nightSlide").fadeOut("normal");} 
      );        
    
    $("#flexible ul#nightSlide li").click(   
        function() {              
          $("#dateinput4").val(this.firstChild.nodeValue);  
          $("#flexible ul#nightSlide").slideUp("fast");
      } 
      );
    
    /**********   Dropdown Navigation **********/
    
    $("li.topLevel ul").hide();   
    $("li.topLevel").hoverIntent (        
      function() {  $("ul", this).slideDown("fast"); } , 
      function() { $("ul", this).slideUp("fast"); }
      );       
    $("a.noclick").click(
      function() { return false;}
    );

  } );   
  
  (function($) {

  if (typeof $.timeout != "undefined") return; 

  $.extend({
    timeout : function (func,delay) {
      // init
      if (typeof $.timeout.count == "undefined") $.timeout.count = 0;   
      if (typeof $.timeout.funcs == "undefined") $.timeout.funcs = new Array(); 
      // set timeout
      if (typeof func =='string') return setTimeout(func, delay); 
      if (typeof func =='function') {
        $.timeout.count++;
        $.timeout.funcs[$.timeout.count] = func;
        return setTimeout("$.timeout.funcs['"+$.timeout.count+"']();", delay);
      }
    },
    interval : function (func,delay) {
      // init
      if (typeof $.interval.count == "undefined") $.interval.count = 0;   
      if (typeof $.interval.funcs == "undefined") $.interval.funcs = new Array(); 
      // set interval
      if (typeof func =='string') return setInterval(func, delay); 
      if (typeof func =='function') {
        $.interval.count++;
        $.interval.funcs[$.interval.count] = func;
        return setInterval("$.interval.funcs['"+$.interval.count+"']();", delay);
      }
    },
    idle : function (func,delay) {
      // init
      if (typeof $.idle.lasttimeout == "undefined") $.idle.lasttimeout = null;
      if (typeof $.idle.lastfunc == "undefined") $.idle.lastfunc = null;
      // set idle timeout
      if ($.idle.timeout) { clearTimeout($.idle.timeout); $.idle.timeout = null; $.idle.lastfunc = null; }
      if (typeof(func)=='string') { 
        $.idle.timeout = setTimeout(func, delay); 
        return $.idle.timeout;
      }   
      if (typeof(func)=='function') { 
        $.idle.lastfunc = func;
        $.idle.timeout = setTimeout("$.idle.lastfunc();", delay);
        return $.idle.timeout;
      }
    },
    clear : function (countdown) {
    clearInterval(countdown);
    clearTimeout(countdown);
    } 
    
  });
  
  
})(jQuery);


(function( $ ){

  var $preload = $.preload = function( original, settings ){
    if( original.split )//selector
      original = $(original);

    settings = $.extend( {}, $preload.defaults, settings );
    var sources = $.map( original, function( source ){
      if( !source ) 
        return;//skip
      if( source.split )//URL Mode
        return settings.base + source + settings.ext;
      var url = source.src || source.href;//save the original source
      if( typeof settings.placeholder == 'string' && source.src )//Placeholder Mode, if it's an image, set it.
        source.src = settings.placeholder;
      if( url && settings.find )//Rollover mode
        url = url.replace( settings.find, settings.replace );
      return url || null;//skip if empty string
    });

    var data = {
      loaded:0,//how many were loaded successfully
      failed:0,//how many urls failed
      next:0,//which one's the next image to load (index)
      done:0,//how many urls were tried
      //found:false,//whether the last one was successful
      total:sources.length//how many images are being preloaded overall
    };
    
    if( !data.total )//nothing to preload
      return finish();
    
    var imgs = '<img/>',//ensure one
      thres = settings.threshold;//save a copy
    
    while( --thres > 0 )//it could be oddly negative
      imgs += '<img/>';
    imgs = $(imgs).load(handler).error(handler).bind('abort',handler).each(fetch);
    
    function handler( e ){
      data.found = e.type == 'load';
      data.image = this.src;
      var orig = data.original = original[this.index];
      data[data.found?'loaded':'failed']++;
      data.done++;
      if( settings.placeholder && orig.src )//special case when on placeholder mode
        orig.src = data.found ? data.image : settings.notFound || orig.src;
      if( settings.onComplete )
        settings.onComplete( data );
      if( data.done < data.total )//let's continue
        fetch( 0, this );
      else{//we are finished
        if( imgs.unbind )//sometimes IE gets here before finishing line 84
          imgs.unbind('load').unbind('error').unbind('abort');//cleanup
        imgs = null;
        finish();
      }
    };
    function fetch( i, img, retry ){
      if( $.browser.msie && data.next && data.next % $preload.gap == 0 && !retry ){//IE problem, can't preload more than 15
        setTimeout(function(){ fetch( i, img, true ); }, 0);
        return false;
      }
      if( data.next == data.total ) return false;//no more to fetch
      img.index = data.next;//save it, we'll need it.
      img.src = sources[data.next++];
      if( settings.onRequest ){
        data.image = img.src;
        data.original = original[data.next-1];
        settings.onRequest( data );
      }
    };
    function finish(){
      if( settings.onFinish )
        settings.onFinish( data );
    };
  };

  // each time we load this amount and it's IE, we must rest for a while, make it lower if you get stack overflow.
  $preload.gap = 14; 

  $preload.defaults = {
    threshold:2,//how many images to load simultaneously
    base:'',//URL mode: a base url can be specified, it is prepended to all string urls
    ext:'',//URL mode:same as base, but it's appended after the original url.
    replace:''//Rollover mode: replacement (can be left empty)
    /*
    find:null,//Rollover mode: a string or regex for the replacement
    notFound:''//Placeholder Mode: Optional url of an image to use when the original wasn't found
    placeholder:'',//Placeholder Mode: url of an image to set while loading
    onRequest:function( data ){ ... },//callback called every time a new url is requested
    onComplete:function( data ){ ... },//callback called every time a response is received(successful or not)
    onFinish:function( data ){ ... }//callback called after all the images were loaded(or failed)
    */
  };

  $.fn.preload = function( settings ){
    $preload( this, settings );
    return this;
  };

})( jQuery );


/****************** slider controls ****************************/

  $(document).ready(function() {
 // hides the slickbox as soon as the DOM is ready
 // (a little sooner than page load)
  $('#slider').hide();


      // shows the slider DIV on clicking the link with an ID of "slider"
        $('a#jshow').click(function() {
          $('#slider').fadeIn('slow');
          return false;
        });

});




$(document).ready(function() {
  
  var day1 = "";
  var month1 = "";
  var year1 = "";
  var day2 = "";
  var month2 = "";
  var year2 = "";
  /////////////////////// Check Rates Link
  var updatereservationslink = function() {

  var checkrateslink = "https://secure.hilton.com/en/hi/res/choose_dates.jhtml?hotel=BHXMETW&arrivalDay=" + day1 + "&arrivalMonth=" + month1
          + "&arrivalYear=" + year1+ "&departureDay=" + day2 + "&departureMonth=" + month2 + "&departureYear=" + year2+ "&WT.mc_id=1HI2MS3BHXMETW4English";
  $("#reservations_container .checkrateslink").attr("href", checkrateslink);
  }
  
/////////////////////      Quick Reservation Panel Listeners
  $(".panel_button").click(function(){
    
    if($('#checkout_div').is(':visible')) {
      $('#checkout_div').hide("blind", { direction: "left" }, 500);
      $('#checkout').css({'border':'2px solid #595959'});
    }
    if($('#checkin_div').is(':visible')) {
      $('#checkin_div').hide("blind", { direction: "left" }, 500);
      $('#checkin').css({'border':'2px solid #595959'});
      
    }
    $("div#panel").animate({
     height: "190px", opacity:100}, 500);
    $("div.panel_button").toggle();
    //this line is to stop the http request in place for non javascript enabled browsers
    return false;
  }); 
  
   $("div#hide_button").click(function(){
    $("div#panel").animate({
      height: "1px", opacity:0}, 500);
    $("#panel_button").toggle();  
   });


//////////// Datepicker Listeners



    $('.checkinpop').click(function(){
      $('#checkin').css({'border':'2px solid #7FA1C0'});
      if($('#checkout_div').is(':visible')) {
        $('#checkout_div').hide();
        $('#checkout').css({'border':'2px solid #595959'});
      }

      if($('#checkin_div').is(':visible')) {
        $('#checkin_div').hide("blind", { direction: "left" }, 500);
      } else if ($('#checkin_div').is(':hidden')) {
        $('#checkin_div').show("blind", { direction: "right" }, 500);
      }
      });


    $('.checkoutpop').click(function(){
      $('#checkout').css({'border':'2px solid #7FA1C0'});
      if($('#checkin_div').is(':visible')) {
        $('#checkin_div').hide();
        $('#checkin').css({'border':'2px solid #595959'});

      }

      if ($('#checkout_div').is(':visible')) {
        $('#checkout_div').hide("blind", { direction: "left" }, 500);

      } else if ($('#checkout_div').is(':hidden')) {
        $('#checkout_div').show("blind", { direction: "right" }, 500);
      }
      });



////////// Create Inline Datepickers
  var checkin =  $('#checkin_div').datepicker({
    dateFormat: 'dd/mm/y',
    defaultDate: null,
    minDate: 0,
    onSelect : function(){
      checkinDate = checkin.datepicker('getDate')
      $('#checkin').val($.datepicker.formatDate('dd/mm/y',checkinDate));
    
      /// update url
      day1 = $.datepicker.formatDate('dd',checkinDate);
      month1 = $.datepicker.formatDate('mm',checkinDate);
      year1 = $.datepicker.formatDate('y',checkinDate);
      updatereservationslink();
      //reduce datepicker panel
      $('#checkin_div').hide();
      $('#checkin').css({'border':'2px solid #595959'});
      
    }
  });
  
  var checkout =  $('#checkout_div').datepicker({
    dateFormat: 'dd/mm/y',
    defaultDate: null,
    minDate: 0,
      onSelect : function(){ 
        checkoutDate = checkout.datepicker('getDate')
        $('#checkout').val($.datepicker.formatDate('dd/mm/y',checkoutDate));

        /// update url
        /// update url
        day2 = $.datepicker.formatDate('dd',checkoutDate);
        month2 = $.datepicker.formatDate('mm',checkoutDate);
        year2 = $.datepicker.formatDate('y',checkoutDate);
        updatereservationslink();
        
        
        //reduce datepicker panel
        $('#checkout_div').hide();
        $('#checkout').css({'border':'2px solid #595959'});
        
        
      }
  });
    


  
});
/*
* jquery-google-analytics plugin
*
* A jQuery plugin that makes it easier to implement Google Analytics tracking, including event and link tracking.
*
* Adds the following methods to jQuery:
* - $.trackPage() - Adds Google Analytics tracking to the page it's called from.
* - $('a').track() - Adds click tracking to elements.
* - $.trackEvent() - Tracks an event using the given parameters. 
* - $.timePageLoad() - Measures the time it takes  an event using the given parameters. 
*
* Features:
*
* - Improves page load times by loading Google Analytics code without blocking
* - Easy and extensible event and link tracking plugin for jQuery and Google Analytics
* - Automatic internal/external link detection. Default behavior is to skip tracking of internal links.
* - Configurable: skip internal link tracking, metadata extraction using callbacks.
* - Enforces that tracking event handler is added only once.
*
* Copyright (c) 2008 Christian Hellsten
*
* Plugin homepage:
* http://aktagon.com/projects/jquery/google-analytics/
* http://github.com/christianhellsten/jquery-google-analytics/
*
* Examples:
* http://aktagon.com/projects/jquery/google-analytics/examples/
* http://code.google.com/apis/analytics/docs/eventTrackerGuide.html
*
* Repository:
* git://github.com/christianhellsten/jquery-google-analytics.git
*
* Version 1.1.1
*
* Tested with:
* - Mac: Firefox 3, Safari 3
* - Linux: Firefox 3
* - Windows: Firefox 3, Internet Explorer 6
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Credits:
*   - http://google.com/analytics: 
*   - http://lyncd.com: 
*       Idea for trackPage method came from this blog post: http://lyncd.com/2009/03/better-google-analytics-javascript/
*
*/

(function($) {

  var pageTracker;

  /**
   * Enables Google Analytics tracking on the page it's called from. 
   *
   * Example:
   *
   *  <script type="text/javascript">
   *    $.trackPage('UA-xxx-xxx', options);
   *  </script>
   *
   * Parameters:
   *
   *  account_id - Your Google Analytics account ID.
   *  options - An associative array containing one or more optional parameters:
   *    - onload - If false, the Google Analytics code is loaded when this method is called instead of on window.onload.
   *    - status_code - The HTTP status code of the current server response. If this is set to something other than 200 then the page is tracked as an error page. See this page for details: http://www.google.com/support/analytics/bin/answer.py?hl=en&answer=86927
   *
   */
  $.trackPage = function(account_id, options) {
    var host = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
    var script;

    // Use default options, if necessary
    var settings = $.extend({}, {onload: true, status_code: 200}, options);
    var src  = host + 'google-analytics.com/ga.js';

    function init_analytics() {
      if (typeof _gat != undefined) {
        debug('Google Analytics loaded');

        pageTracker = _gat._getTracker(account_id);

        if(settings.status_code == null || settings.status_code == 200) {
          pageTracker._trackPageview();
        } else {
          debug('Tracking error ' + settings.status_code);
          pageTracker._trackPageview("/" + settings.status_code + ".html?page=" + document.location.pathname + document.location.search + "&from=" + document.referrer);
        }

      }
      else { 
        throw "_gat is undefined"; // setInterval loading?
      }
    }

    load_script = function() {
      $.getScript(src, function() {
        init_analytics();
      })
    }
    
    // Enable tracking when called or on page load?
    if(settings.onload == true || settings.onload == null) {
      $(window).load(load_script);
    } else {
      load_script();
    }
  }

  /**
   * Tracks an event using the given parameters. 
   *
   * The trackEvent method takes four arguments:
   *
   *  category - required string used to group events
   *  action - required string used to define event type, eg. click, download
   *  label - optional label to attach to event, eg. buy
   *  value - optional numerical value to attach to event, eg. price
   *  skip_internal - optional boolean value. If true then internal links are not tracked.
   *
   */
  $.trackEvent = function(category, action, label, value) {
    if(typeof pageTracker == 'undefined') {
      debug('FATAL: pageTracker is not defined'); // blocked by whatever
    } else {
      pageTracker._trackEvent(category, action, label, value);
    }
  };

  /**
   * Adds click tracking to elements. Usage:
   *
   *  $('a').track()
   *
   */
  $.fn.track = function(options) {
    
    var element = $(this);
    
    // Prevent link from being tracked multiple times 
    if (element.hasClass("tracked")) {
      return;
    }

    element.addClass("tracked");

    // Add click handler to all matching elements
    return this.each(function() {
      var link   = $(this);

      // Use default options, if necessary
      var settings = $.extend({}, $.fn.track.defaults, options);

      var category = evaluate(link, settings.category);
      var action   = evaluate(link, settings.action);
      var label    = evaluate(link, settings.label);
      var value    = evaluate(link, settings.value);
      var event_name = evaluate(link, settings.event_name);
      
      var message  = "category:'" + category + "' action:'" + action + "' label:'" + label + "' value:'" + value + "'";
      
      debug('Tracking ' + event_name + ' ' + message);

      link.bind(event_name, function() {       
        
        // Should we skip internal links?
        var skip = settings.skip_internal && (link[0].hostname == location.hostname);
      
        if(!skip) {
          $.trackEvent(category, action, label, value);
          debug('Tracked ' + message);
        } else {
          debug('Skipped ' + message);
        }

        return true;
      });
    });
    
    /**
     * If second parameter is a string: returns the value of the second parameter.
     * If the second parameter is a function: passes the element to the function and returns function's return value.
     */
    function evaluate(element, text_or_function) {
      if(typeof text_or_function == 'function') {
        text_or_function = text_or_function(element);
      }
      return text_or_function;
    };
  };

  /**
   * Prints to Firebug console if available. 
   */
  function debug(message) {
    if(typeof console != 'undefined' && typeof console.debug != 'undefined') {
      console.debug(message);
    }     
  };

  // Default (overridable) settings
  $.fn.track.defaults = {
    category      : function(element) { return (element[0].hostname == location.hostname) ? 'internal':'external'; },
    action        : 'click',
    label         : function(element) { return element.attr('href') },
    value         : null,
    skip_internal : true,
    event_name    : 'click'
  };
})(jQuery);


/*
 * jQuery UI 1.7.1
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI
 */
;jQuery.ui || (function($) {

var _remove = $.fn.remove,
  isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);

//Helper functions and ui object
$.ui = {
  version: "1.7.1",

  // $.ui.plugin is deprecated.  Use the proxy pattern instead.
  plugin: {
    add: function(module, option, set) {
      var proto = $.ui[module].prototype;
      for(var i in set) {
        proto.plugins[i] = proto.plugins[i] || [];
        proto.plugins[i].push([option, set[i]]);
      }
    },
    call: function(instance, name, args) {
      var set = instance.plugins[name];
      if(!set || !instance.element[0].parentNode) { return; }

      for (var i = 0; i < set.length; i++) {
        if (instance.options[set[i][0]]) {
          set[i][1].apply(instance.element, args);
        }
      }
    }
  },

  contains: function(a, b) {
    return document.compareDocumentPosition
      ? a.compareDocumentPosition(b) & 16
      : a !== b && a.contains(b);
  },

  hasScroll: function(el, a) {

    //If overflow is hidden, the element might have extra content, but the user wants to hide it
    if ($(el).css('overflow') == 'hidden') { return false; }

    var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
      has = false;

    if (el[scroll] > 0) { return true; }

    // TODO: determine which cases actually cause this to happen
    // if the element doesn't have the scroll set, see if it's possible to
    // set the scroll
    el[scroll] = 1;
    has = (el[scroll] > 0);
    el[scroll] = 0;
    return has;
  },

  isOverAxis: function(x, reference, size) {
    //Determines when x coordinate is over "b" element axis
    return (x > reference) && (x < (reference + size));
  },

  isOver: function(y, x, top, left, height, width) {
    //Determines when x, y coordinates is over "b" element
    return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
  },

  keyCode: {
    BACKSPACE: 8,
    CAPS_LOCK: 20,
    COMMA: 188,
    CONTROL: 17,
    DELETE: 46,
    DOWN: 40,
    END: 35,
    ENTER: 13,
    ESCAPE: 27,
    HOME: 36,
    INSERT: 45,
    LEFT: 37,
    NUMPAD_ADD: 107,
    NUMPAD_DECIMAL: 110,
    NUMPAD_DIVIDE: 111,
    NUMPAD_ENTER: 108,
    NUMPAD_MULTIPLY: 106,
    NUMPAD_SUBTRACT: 109,
    PAGE_DOWN: 34,
    PAGE_UP: 33,
    PERIOD: 190,
    RIGHT: 39,
    SHIFT: 16,
    SPACE: 32,
    TAB: 9,
    UP: 38
  }
};

// WAI-ARIA normalization
if (isFF2) {
  var attr = $.attr,
    removeAttr = $.fn.removeAttr,
    ariaNS = "http://www.w3.org/2005/07/aaa",
    ariaState = /^aria-/,
    ariaRole = /^wairole:/;

  $.attr = function(elem, name, value) {
    var set = value !== undefined;

    return (name == 'role'
      ? (set
        ? attr.call(this, elem, name, "wairole:" + value)
        : (attr.apply(this, arguments) || "").replace(ariaRole, ""))
      : (ariaState.test(name)
        ? (set
          ? elem.setAttributeNS(ariaNS,
            name.replace(ariaState, "aaa:"), value)
          : attr.call(this, elem, name.replace(ariaState, "aaa:")))
        : attr.apply(this, arguments)));
  };

  $.fn.removeAttr = function(name) {
    return (ariaState.test(name)
      ? this.each(function() {
        this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
      }) : removeAttr.call(this, name));
  };
}

//jQuery plugins
$.fn.extend({
  remove: function() {
    // Safari has a native remove event which actually removes DOM elements,
    // so we have to use triggerHandler instead of trigger (#3037).
    $("*", this).add(this).each(function() {
      $(this).triggerHandler("remove");
    });
    return _remove.apply(this, arguments );
  },

  enableSelection: function() {
    return this
      .attr('unselectable', 'off')
      .css('MozUserSelect', '')
      .unbind('selectstart.ui');
  },

  disableSelection: function() {
    return this
      .attr('unselectable', 'on')
      .css('MozUserSelect', 'none')
      .bind('selectstart.ui', function() { return false; });
  },

  scrollParent: function() {
    var scrollParent;
    if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
      scrollParent = this.parents().filter(function() {
        return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
      }).eq(0);
    } else {
      scrollParent = this.parents().filter(function() {
        return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
      }).eq(0);
    }

    return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
  }
});


//Additional selectors
$.extend($.expr[':'], {
  data: function(elem, i, match) {
    return !!$.data(elem, match[3]);
  },

  focusable: function(element) {
    var nodeName = element.nodeName.toLowerCase(),
      tabIndex = $.attr(element, 'tabindex');
    return (/input|select|textarea|button|object/.test(nodeName)
      ? !element.disabled
      : 'a' == nodeName || 'area' == nodeName
        ? element.href || !isNaN(tabIndex)
        : !isNaN(tabIndex))
      // the element and all of its ancestors must be visible
      // the browser may report that the area is hidden
      && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
  },

  tabbable: function(element) {
    var tabIndex = $.attr(element, 'tabindex');
    return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
  }
});


// $.widget is a factory to create jQuery plugins
// taking some boilerplate code out of the plugin code
function getter(namespace, plugin, method, args) {
  function getMethods(type) {
    var methods = $[namespace][plugin][type] || [];
    return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
  }

  var methods = getMethods('getter');
  if (args.length == 1 && typeof args[0] == 'string') {
    methods = methods.concat(getMethods('getterSetter'));
  }
  return ($.inArray(method, methods) != -1);
}

$.widget = function(name, prototype) {
  var namespace = name.split(".")[0];
  name = name.split(".")[1];

  // create plugin method
  $.fn[name] = function(options) {
    var isMethodCall = (typeof options == 'string'),
      args = Array.prototype.slice.call(arguments, 1);

    // prevent calls to internal methods
    if (isMethodCall && options.substring(0, 1) == '_') {
      return this;
    }

    // handle getter methods
    if (isMethodCall && getter(namespace, name, options, args)) {
      var instance = $.data(this[0], name);
      return (instance ? instance[options].apply(instance, args)
        : undefined);
    }

    // handle initialization and non-getter methods
    return this.each(function() {
      var instance = $.data(this, name);

      // constructor
      (!instance && !isMethodCall &&
        $.data(this, name, new $[namespace][name](this, options))._init());

      // method call
      (instance && isMethodCall && $.isFunction(instance[options]) &&
        instance[options].apply(instance, args));
    });
  };

  // create widget constructor
  $[namespace] = $[namespace] || {};
  $[namespace][name] = function(element, options) {
    var self = this;

    this.namespace = namespace;
    this.widgetName = name;
    this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
    this.widgetBaseClass = namespace + '-' + name;

    this.options = $.extend({},
      $.widget.defaults,
      $[namespace][name].defaults,
      $.metadata && $.metadata.get(element)[name],
      options);

    this.element = $(element)
      .bind('setData.' + name, function(event, key, value) {
        if (event.target == element) {
          return self._setData(key, value);
        }
      })
      .bind('getData.' + name, function(event, key) {
        if (event.target == element) {
          return self._getData(key);
        }
      })
      .bind('remove', function() {
        return self.destroy();
      });
  };

  // add widget prototype
  $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);

  // TODO: merge getter and getterSetter properties from widget prototype
  // and plugin prototype
  $[namespace][name].getterSetter = 'option';
};

$.widget.prototype = {
  _init: function() {},
  destroy: function() {
    this.element.removeData(this.widgetName)
      .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
      .removeAttr('aria-disabled');
  },

  option: function(key, value) {
    var options = key,
      self = this;

    if (typeof key == "string") {
      if (value === undefined) {
        return this._getData(key);
      }
      options = {};
      options[key] = value;
    }

    $.each(options, function(key, value) {
      self._setData(key, value);
    });
  },
  _getData: function(key) {
    return this.options[key];
  },
  _setData: function(key, value) {
    this.options[key] = value;

    if (key == 'disabled') {
      this.element
        [value ? 'addClass' : 'removeClass'](
          this.widgetBaseClass + '-disabled' + ' ' +
          this.namespace + '-state-disabled')
        .attr("aria-disabled", value);
    }
  },

  enable: function() {
    this._setData('disabled', false);
  },
  disable: function() {
    this._setData('disabled', true);
  },

  _trigger: function(type, event, data) {
    var callback = this.options[type],
      eventName = (type == this.widgetEventPrefix
        ? type : this.widgetEventPrefix + type);

    event = $.Event(event);
    event.type = eventName;

    // copy original event properties over to the new event
    // this would happen if we could call $.event.fix instead of $.Event
    // but we don't have a way to force an event to be fixed multiple times
    if (event.originalEvent) {
      for (var i = $.event.props.length, prop; i;) {
        prop = $.event.props[--i];
        event[prop] = event.originalEvent[prop];
      }
    }

    this.element.trigger(event, data);

    return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false
      || event.isDefaultPrevented());
  }
};

$.widget.defaults = {
  disabled: false
};


/** Mouse Interaction Plugin **/

$.ui.mouse = {
  _mouseInit: function() {
    var self = this;

    this.element
      .bind('mousedown.'+this.widgetName, function(event) {
        return self._mouseDown(event);
      })
      .bind('click.'+this.widgetName, function(event) {
        if(self._preventClickEvent) {
          self._preventClickEvent = false;
          event.stopImmediatePropagation();
          return false;
        }
      });

    // Prevent text selection in IE
    if ($.browser.msie) {
      this._mouseUnselectable = this.element.attr('unselectable');
      this.element.attr('unselectable', 'on');
    }

    this.started = false;
  },

  // TODO: make sure destroying one instance of mouse doesn't mess with
  // other instances of mouse
  _mouseDestroy: function() {
    this.element.unbind('.'+this.widgetName);

    // Restore text selection in IE
    ($.browser.msie
      && this.element.attr('unselectable', this._mouseUnselectable));
  },

  _mouseDown: function(event) {
    // don't let more than one widget handle mouseStart
    // TODO: figure out why we have to use originalEvent
    event.originalEvent = event.originalEvent || {};
    if (event.originalEvent.mouseHandled) { return; }

    // we may have missed mouseup (out of window)
    (this._mouseStarted && this._mouseUp(event));

    this._mouseDownEvent = event;

    var self = this,
      btnIsLeft = (event.which == 1),
      elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
    if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
      return true;
    }

    this.mouseDelayMet = !this.options.delay;
    if (!this.mouseDelayMet) {
      this._mouseDelayTimer = setTimeout(function() {
        self.mouseDelayMet = true;
      }, this.options.delay);
    }

    if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
      this._mouseStarted = (this._mouseStart(event) !== false);
      if (!this._mouseStarted) {
        event.preventDefault();
        return true;
      }
    }

    // these delegates are required to keep context
    this._mouseMoveDelegate = function(event) {
      return self._mouseMove(event);
    };
    this._mouseUpDelegate = function(event) {
      return self._mouseUp(event);
    };
    $(document)
      .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
      .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);

    // preventDefault() is used to prevent the selection of text here -
    // however, in Safari, this causes select boxes not to be selectable
    // anymore, so this fix is needed
    ($.browser.safari || event.preventDefault());

    event.originalEvent.mouseHandled = true;
    return true;
  },

  _mouseMove: function(event) {
    // IE mouseup check - mouseup happened when mouse was out of window
    if ($.browser.msie && !event.button) {
      return this._mouseUp(event);
    }

    if (this._mouseStarted) {
      this._mouseDrag(event);
      return event.preventDefault();
    }

    if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
      this._mouseStarted =
        (this._mouseStart(this._mouseDownEvent, event) !== false);
      (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
    }

    return !this._mouseStarted;
  },

  _mouseUp: function(event) {
    $(document)
      .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
      .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);

    if (this._mouseStarted) {
      this._mouseStarted = false;
      this._preventClickEvent = (event.target == this._mouseDownEvent.target);
      this._mouseStop(event);
    }

    return false;
  },

  _mouseDistanceMet: function(event) {
    return (Math.max(
        Math.abs(this._mouseDownEvent.pageX - event.pageX),
        Math.abs(this._mouseDownEvent.pageY - event.pageY)
      ) >= this.options.distance
    );
  },

  _mouseDelayMet: function(event) {
    return this.mouseDelayMet;
  },

  // These are placeholder methods, to be overriden by extending plugin
  _mouseStart: function(event) {},
  _mouseDrag: function(event) {},
  _mouseStop: function(event) {},
  _mouseCapture: function(event) { return true; }
};

$.ui.mouse.defaults = {
  cancel: null,
  distance: 1,
  delay: 0
};

})(jQuery);
/*
 * jQuery UI Datepicker 1.7.1
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Datepicker
 *
 * Depends:
 *  ui.core.js
 */

(function($) { // hide the namespace

$.extend($.ui, { datepicker: { version: "1.7.1" } });

var PROP_NAME = 'datepicker';

/* Date picker manager.
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
   Settings for (groups of) date pickers are maintained in an instance object,
   allowing multiple different settings on the same page. */

function Datepicker() {
  this.debug = false; // Change this to true to start debugging
  this._curInst = null; // The current instance in use
  this._keyEvent = false; // If the last event was a key event
  this._disabledInputs = []; // List of date picker inputs that have been disabled
  this._datepickerShowing = false; // True if the popup picker is showing , false if not
  this._inDialog = false; // True if showing within a "dialog", false if not
  this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
  this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
  this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
  this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
  this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
  this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
  this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
  this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
  this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
  this.regional = []; // Available regional settings, indexed by language code
  this.regional[''] = { // Default regional settings
    closeText: 'Done', // Display text for close link
    prevText: 'Prev', // Display text for previous month link
    nextText: 'Next', // Display text for next month link
    currentText: 'Today', // Display text for current month link
    monthNames: ['January','February','March','April','May','June',
      'July','August','September','October','November','December'], // Names of months for drop-down and formatting
    monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
    dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
    dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
    dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
    dateFormat: 'mm/dd/yy', // See format options on parseDate
    firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
    isRTL: false // True if right-to-left language, false if left-to-right
  };
  this._defaults = { // Global defaults for all the date picker instances
    showOn: 'focus', // 'focus' for popup on focus,
      // 'button' for trigger button, or 'both' for either
    showAnim: 'show', // Name of jQuery animation for popup
    showOptions: {}, // Options for enhanced animations
    defaultDate: null, // Used when field is blank: actual date,
      // +/-number for offset from today, null for today
    appendText: '', // Display text following the input box, e.g. showing the format
    buttonText: '...', // Text for trigger button
    buttonImage: '', // URL for trigger button image
    buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
    hideIfNoPrevNext: false, // True to hide next/previous month links
      // if not applicable, false to just disable them
    navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
    gotoCurrent: false, // True if today link goes back to current selection instead
    changeMonth: false, // True if month can be selected directly, false if only prev/next
    changeYear: false, // True if year can be selected directly, false if only prev/next
    showMonthAfterYear: false, // True if the year select precedes month, false for month then year
    yearRange: '-10:+10', // Range of years to display in drop-down,
      // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn)
    showOtherMonths: false, // True to show dates in other months, false to leave blank
    calculateWeek: this.iso8601Week, // How to calculate the week of the year,
      // takes a Date and returns the number of the week for it
    shortYearCutoff: '+10', // Short year values < this are in the current century,
      // > this are in the previous century,
      // string value starting with '+' for current year + value
    minDate: null, // The earliest selectable date, or null for no limit
    maxDate: null, // The latest selectable date, or null for no limit
    duration: 'normal', // Duration of display/closure
    beforeShowDay: null, // Function that takes a date and returns an array with
      // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
      // [2] = cell title (optional), e.g. $.datepicker.noWeekends
    beforeShow: null, // Function that takes an input field and
      // returns a set of custom settings for the date picker
    onSelect: null, // Define a callback function when a date is selected
    onChangeMonthYear: null, // Define a callback function when the month or year is changed
    onClose: null, // Define a callback function when the datepicker is closed
    numberOfMonths: 1, // Number of months to show at a time
    showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
    stepMonths: 1, // Number of months to step back/forward
    stepBigMonths: 12, // Number of months to step back/forward for the big links
    altField: '', // Selector for an alternate field to store selected dates into
    altFormat: '', // The date format to use for the alternate field
    constrainInput: true, // The input is constrained by the current date format
    showButtonPanel: false // True to show button panel, false to not show it
  };
  $.extend(this._defaults, this.regional['']);
  this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>');
}

$.extend(Datepicker.prototype, {
  /* Class name added to elements to indicate already configured with a date picker. */
  markerClassName: 'hasDatepicker',

  /* Debug logging (if enabled). */
  log: function () {
    if (this.debug)
      console.log.apply('', arguments);
  },

  /* Override the default settings for all instances of the date picker.
     @param  settings  object - the new settings to use as defaults (anonymous object)
     @return the manager object */
  setDefaults: function(settings) {
    extendRemove(this._defaults, settings || {});
    return this;
  },

  /* Attach the date picker to a jQuery selection.
     @param  target    element - the target input field or division or span
     @param  settings  object - the new settings to use for this date picker instance (anonymous) */
  _attachDatepicker: function(target, settings) {
    // check for settings on the control itself - in namespace 'date:'
    var inlineSettings = null;
    for (var 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 inline = (nodeName == 'div' || nodeName == 'span');
    if (!target.id)
      target.id = 'dp' + (++this.uuid);
    var inst = this._newInst($(target), inline);
    inst.settings = $.extend({}, settings || {}, inlineSettings || {});
    if (nodeName == 'input') {
      this._connectDatepicker(target, inst);
    } else if (inline) {
      this._inlineDatepicker(target, inst);
    }
  },

  /* Create a new instance object. */
  _newInst: function(target, inline) {
    var id = target[0].id.replace(/([:\[\]\.])/g, '\\\\$1'); // escape jQuery meta chars
    return {id: id, input: target, // associated target
      selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
      drawMonth: 0, drawYear: 0, // month being drawn
      inline: inline, // is datepicker inline or not
      dpDiv: (!inline ? this.dpDiv : // presentation div
      $('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))};
  },

  /* Attach the date picker to an input field. */
  _connectDatepicker: function(target, inst) {
    var input = $(target);
    inst.trigger = $([]);
    if (input.hasClass(this.markerClassName))
      return;
    var appendText = this._get(inst, 'appendText');
    var isRTL = this._get(inst, 'isRTL');
    if (appendText)
      input[isRTL ? 'before' : 'after']('<span class="' + this._appendClass + '">' + appendText + '</span>');
    var showOn = this._get(inst, 'showOn');
    if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
      input.focus(this._showDatepicker);
    if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
      var buttonText = this._get(inst, 'buttonText');
      var buttonImage = this._get(inst, 'buttonImage');
      inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
        $('<img/>').addClass(this._triggerClass).
          attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
        $('<button type="button"></button>').addClass(this._triggerClass).
          html(buttonImage == '' ? buttonText : $('<img/>').attr(
          { src:buttonImage, alt:buttonText, title:buttonText })));
      input[isRTL ? 'before' : 'after'](inst.trigger);
      inst.trigger.click(function() {
        if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target)
          $.datepicker._hideDatepicker();
        else
          $.datepicker._showDatepicker(target);
        return false;
      });
    }
    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 this._get(inst, key);
      });
    $.data(target, PROP_NAME, inst);
  },

  /* Attach an inline date picker to a div. */
  _inlineDatepicker: function(target, inst) {
    var divSpan = $(target);
    if (divSpan.hasClass(this.markerClassName))
      return;
    divSpan.addClass(this.markerClassName).append(inst.dpDiv).
      bind("setData.datepicker", function(event, key, value){
        inst.settings[key] = value;
      }).bind("getData.datepicker", function(event, key){
        return this._get(inst, key);
      });
    $.data(target, PROP_NAME, inst);
    this._setDate(inst, this._getDefaultDate(inst));
    this._updateDatepicker(inst);
    this._updateAlternate(inst);
  },

  /* Pop-up the date picker in a "dialog" box.
     @param  input     element - ignored
     @param  dateText  string - the initial date to display (in the current format)
     @param  onSelect  function - the function(dateText) to call when a date is selected
     @param  settings  object - update the dialog date picker instance's settings (anonymous object)
     @param  pos       int[2] - coordinates for the dialog's position within the screen or
                       event - with x/y coordinates or
                       leave empty for default (screen centre)
     @return the manager object */
  _dialogDatepicker: function(input, dateText, onSelect, settings, pos) {
    var inst = this._dialogInst; // internal instance
    if (!inst) {
      var id = 'dp' + (++this.uuid);
      this._dialogInput = $('<input type="text" id="' + id +
        '" size="1" style="position: absolute; top: -100px;"/>');
      this._dialogInput.keydown(this._doKeyDown);
      $('body').append(this._dialogInput);
      inst = this._dialogInst = this._newInst(this._dialogInput, false);
      inst.settings = {};
      $.data(this._dialogInput[0], PROP_NAME, inst);
    }
    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 = // should use actual width/height below
        [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
    }

    // move input on screen for focus, but hidden behind dialog
    this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px');
    inst.settings.onSelect = onSelect;
    this._inDialog = true;
    this.dpDiv.addClass(this._dialogClass);
    this._showDatepicker(this._dialogInput[0]);
    if ($.blockUI)
      $.blockUI(this.dpDiv);
    $.data(this._dialogInput[0], PROP_NAME, inst);
    return this;
  },

  /* Detach a datepicker from its control.
     @param  target    element - the target input field or division or span */
  _destroyDatepicker: function(target) {
    var $target = $(target);
    var inst = $.data(target, PROP_NAME);
    if (!$target.hasClass(this.markerClassName)) {
      return;
    }
    var nodeName = target.nodeName.toLowerCase();
    $.removeData(target, PROP_NAME);
    if (nodeName == 'input') {
      inst.trigger.remove();
      $target.siblings('.' + this._appendClass).remove().end().
        removeClass(this.markerClassName).
        unbind('focus', this._showDatepicker).
        unbind('keydown', this._doKeyDown).
        unbind('keypress', this._doKeyPress);
    } else if (nodeName == 'div' || nodeName == 'span')
      $target.removeClass(this.markerClassName).empty();
  },

  /* Enable the date picker to a jQuery selection.
     @param  target    element - the target input field or division or span */
  _enableDatepicker: function(target) {
    var $target = $(target);
    var inst = $.data(target, PROP_NAME);
    if (!$target.hasClass(this.markerClassName)) {
      return;
    }
    var nodeName = target.nodeName.toLowerCase();
    if (nodeName == 'input') {
    target.disabled = false;
      inst.trigger.filter("button").
      each(function() { this.disabled = false; }).end().
        filter("img").
        css({opacity: '1.0', cursor: ''});
    }
    else if (nodeName == 'div' || nodeName == 'span') {
      var inline = $target.children('.' + this._inlineClass);
      inline.children().removeClass('ui-state-disabled');
    }
    this._disabledInputs = $.map(this._disabledInputs,
      function(value) { return (value == target ? null : value); }); // delete entry
  },

  /* Disable the date picker to a jQuery selection.
     @param  target    element - the target input field or division or span */
  _disableDatepicker: function(target) {
    var $target = $(target);
    var inst = $.data(target, PROP_NAME);
    if (!$target.hasClass(this.markerClassName)) {
      return;
    }
    var nodeName = target.nodeName.toLowerCase();
    if (nodeName == 'input') {
    target.disabled = true;
      inst.trigger.filter("button").
      each(function() { this.disabled = true; }).end().
        filter("img").
        css({opacity: '0.5', cursor: 'default'});
    }
    else if (nodeName == 'div' || nodeName == 'span') {
      var inline = $target.children('.' + this._inlineClass);
      inline.children().addClass('ui-state-disabled');
    }
    this._disabledInputs = $.map(this._disabledInputs,
      function(value) { return (value == target ? null : value); }); // delete entry
    this._disabledInputs[this._disabledInputs.length] = target;
  },

  /* Is the first field in a jQuery collection disabled as a datepicker?
     @param  target    element - the target input field or division or span
     @return boolean - true if disabled, false if enabled */
  _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;
  },

  /* Retrieve the instance data for the target control.
     @param  target  element - the target input field or division or span
     @return  object - the associated instance data
     @throws  error if a jQuery problem getting data */
  _getInst: function(target) {
    try {
      return $.data(target, PROP_NAME);
    }
    catch (err) {
      throw 'Missing instance data for this datepicker';
    }
  },

  /* Update the settings for a date picker attached to an input field or division.
     @param  target  element - the target input field or division or span
     @param  name    object - the new settings to update or
                     string - the name of the setting to change or
     @param  value   any - the new value for the setting (omit if above is an object) */
  _optionDatepicker: function(target, name, value) {
    var settings = name || {};
    if (typeof name == 'string') {
      settings = {};
      settings[name] = value;
    }
    var inst = this._getInst(target);
    if (inst) {
      if (this._curInst == inst) {
        this._hideDatepicker(null);
      }
      extendRemove(inst.settings, settings);
      var date = new Date();
      extendRemove(inst, {rangeStart: null, // start of range
        endDay: null, endMonth: null, endYear: null, // end of range
        selectedDay: date.getDate(), selectedMonth: date.getMonth(),
        selectedYear: date.getFullYear(), // starting point
        currentDay: date.getDate(), currentMonth: date.getMonth(),
        currentYear: date.getFullYear(), // current selection
        drawMonth: date.getMonth(), drawYear: date.getFullYear()}); // month being drawn
      this._updateDatepicker(inst);
    }
  },

  // change method deprecated
  _changeDatepicker: function(target, name, value) {
    this._optionDatepicker(target, name, value);
  },

  /* Redraw the date picker attached to an input field or division.
     @param  target  element - the target input field or division or span */
  _refreshDatepicker: function(target) {
    var inst = this._getInst(target);
    if (inst) {
      this._updateDatepicker(inst);
    }
  },

  /* Set the dates for a jQuery selection.
     @param  target   element - the target input field or division or span
     @param  date     Date - the new date
     @param  endDate  Date - the new end date for a range (optional) */
  _setDateDatepicker: function(target, date, endDate) {
    var inst = this._getInst(target);
    if (inst) {
      this._setDate(inst, date, endDate);
      this._updateDatepicker(inst);
      this._updateAlternate(inst);
    }
  },

  /* Get the date(s) for the first entry in a jQuery selection.
     @param  target  element - the target input field or division or span
     @return Date - the current date or
             Date[2] - the current dates for a range */
  _getDateDatepicker: function(target) {
    var inst = this._getInst(target);
    if (inst && !inst.inline)
      this._setDateFromField(inst);
    return (inst ? this._getDate(inst) : null);
  },

  /* Handle keystrokes. */
  _doKeyDown: function(event) {
    var inst = $.datepicker._getInst(event.target);
    var handled = true;
    var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
    inst._keyEvent = true;
    if ($.datepicker._datepickerShowing)
      switch (event.keyCode) {
        case 9:  $.datepicker._hideDatepicker(null, '');
            break; // hide on tab out
        case 13: var sel = $('td.' + $.datepicker._dayOverClass +
              ', td.' + $.datepicker._currentClass, inst.dpDiv);
            if (sel[0])
              $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
            else
              $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));
            return false; // don't submit the form
            break; // select the value on enter
        case 27: $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));
            break; // hide on escape
        case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
              -$.datepicker._get(inst, 'stepBigMonths') :
              -$.datepicker._get(inst, 'stepMonths')), 'M');
            break; // previous month/year on page up/+ ctrl
        case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
              +$.datepicker._get(inst, 'stepBigMonths') :
              +$.datepicker._get(inst, 'stepMonths')), 'M');
            break; // next month/year on page down/+ ctrl
        case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
            handled = event.ctrlKey || event.metaKey;
            break; // clear on ctrl or command +end
        case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
            handled = event.ctrlKey || event.metaKey;
            break; // current on ctrl or command +home
        case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
            handled = event.ctrlKey || event.metaKey;
            // -1 day on ctrl or command +left
            if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
                  -$.datepicker._get(inst, 'stepBigMonths') :
                  -$.datepicker._get(inst, 'stepMonths')), 'M');
            // next month/year on alt +left on Mac
            break;
        case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
            handled = event.ctrlKey || event.metaKey;
            break; // -1 week on ctrl or command +up
        case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
            handled = event.ctrlKey || event.metaKey;
            // +1 day on ctrl or command +right
            if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
                  +$.datepicker._get(inst, 'stepBigMonths') :
                  +$.datepicker._get(inst, 'stepMonths')), 'M');
            // next month/year on alt +right
            break;
        case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
            handled = event.ctrlKey || event.metaKey;
            break; // +1 week on ctrl or command +down
        default: handled = false;
      }
    else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
      $.datepicker._showDatepicker(this);
    else {
      handled = false;
    }
    if (handled) {
      event.preventDefault();
      event.stopPropagation();
    }
  },

  /* Filter entered characters - based on date format. */
  _doKeyPress: function(event) {
    var inst = $.datepicker._getInst(event.target);
    if ($.datepicker._get(inst, 'constrainInput')) {
      var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
      var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
      return event.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
    }
  },

  /* Pop-up the date picker for a given input field.
     @param  input  element - the input field attached to the date picker or
                    event - if triggered by focus */
  _showDatepicker: function(input) {
    input = input.target || input;
    if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
      input = $('input', input.parentNode)[0];
    if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
      return;
    var inst = $.datepicker._getInst(input);
    var beforeShow = $.datepicker._get(inst, 'beforeShow');
    extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
    $.datepicker._hideDatepicker(null, '');
    $.datepicker._lastInput = input;
    $.datepicker._setDateFromField(inst);
    if ($.datepicker._inDialog) // hide cursor
      input.value = '';
    if (!$.datepicker._pos) { // position below input
      $.datepicker._pos = $.datepicker._findPos(input);
      $.datepicker._pos[1] += input.offsetHeight; // add the height

    }
    var isFixed = false;
    $(input).parents().each(function() {
      isFixed |= $(this).css('position') == 'fixed';
      return !isFixed;
    });
    if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
      $.datepicker._pos[0] -= document.documentElement.scrollLeft;
      $.datepicker._pos[1] -= document.documentElement.scrollTop;
    }
    
    var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
  //  var offset = {left: $('#panel').position.left, top: $('#panel').position.left };
    
    $.datepicker._pos = null;
    inst.rangeStart = null;
    // determine sizing offscreen
    inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
    $.datepicker._updateDatepicker(inst);
    // fix width for dynamic number of date pickers
    // and adjust position before showing
    offset = $.datepicker._checkOffset(inst, offset, isFixed);
    inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
      'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
      left: offset.left + 'px', top: offset.top + 'px'});
    if (!inst.inline) {
      var showAnim = $.datepicker._get(inst, 'showAnim') || 'show';
      var duration = $.datepicker._get(inst, 'duration');
      var postProcess = function() {
        $.datepicker._datepickerShowing = true;
        if ($.browser.msie && parseInt($.browser.version,10) < 7) // fix IE < 7 select problems
          $('iframe.ui-datepicker-cover').css({width: inst.dpDiv.width() + 4,
            height: inst.dpDiv.height() + 4});
      };
      if ($.effects && $.effects[showAnim])
        inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
      else
        inst.dpDiv[showAnim](duration, postProcess);
      if (duration == '')
        postProcess();
      if (inst.input[0].type != 'hidden')
        inst.input[0].focus();
      $.datepicker._curInst = inst;
    }
  },

  /* Generate the date picker content. */
  _updateDatepicker: function(inst) {
    var dims = {width: inst.dpDiv.width() + 4,
      height: inst.dpDiv.height() + 4};
    var self = this;
    inst.dpDiv.empty().append(this._generateHTML(inst))
      .find('iframe.ui-datepicker-cover').
        css({width: dims.width, height: dims.height})
      .end()
      .find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a')
        .bind('mouseout', function(){
          $(this).removeClass('ui-state-hover');
          if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
          if(this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
        })
        .bind('mouseover', function(){
          if (!self._isDisabledDatepicker( inst.inline ? inst.dpDiv.parent()[0] : inst.input[0])) {
            $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
            $(this).addClass('ui-state-hover');
            if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
            if(this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
          }
        })
      .end()
      .find('.' + this._dayOverClass + ' a')
        .trigger('mouseover')
      .end();
    var numMonths = this._getNumberOfMonths(inst);
    var cols = numMonths[1];
    var width = 17;
    if (cols > 1) {
      inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
    } else {
      inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
    }
    inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
      'Class']('ui-datepicker-multi');
    inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
      'Class']('ui-datepicker-rtl');
    if (inst.input && inst.input[0].type != 'hidden' && inst == $.datepicker._curInst)
      $(inst.input[0]).focus();
  },

  /* Check positioning to remain on screen. */
  _checkOffset: function(inst, offset, isFixed) {
    var dpWidth = inst.dpDiv.outerWidth();
    var dpHeight = inst.dpDiv.outerHeight();
    var inputWidth = inst.input ? inst.input.outerWidth() : 0;
    var inputHeight = inst.input ? inst.input.outerHeight() : 0;
    var viewWidth = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) + $(document).scrollLeft();
    var viewHeight = (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) + $(document).scrollTop();

    offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
    offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
    offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;

    // now check if datepicker is showing outside window viewport - move to a better place if so.
    offset.left -= (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? Math.abs(offset.left + dpWidth - viewWidth) : 0;
    offset.top -= (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? Math.abs(offset.top + dpHeight + inputHeight*2 - viewHeight) : 0;

    return offset;
  },

  /* Find an object's position on the screen. */
  _findPos: function(obj) {
        while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
            obj = obj.nextSibling;
        }
        var position = $(obj).offset();
      return [position.left, position.top];
  },

  /* Hide the date picker from view.
     @param  input  element - the input field attached to the date picker
     @param  duration  string - the duration over which to close the date picker */
  _hideDatepicker: function(input, duration) {
    var inst = this._curInst;
    if (!inst || (input && inst != $.data(input, PROP_NAME)))
      return;
    if (inst.stayOpen)
      this._selectDate('#' + inst.id, this._formatDate(inst,
        inst.currentDay, inst.currentMonth, inst.currentYear));
    inst.stayOpen = false;
    if (this._datepickerShowing) {
      duration = (duration != null ? duration : this._get(inst, 'duration'));
      var showAnim = this._get(inst, 'showAnim');
      var postProcess = function() {
        $.datepicker._tidyDialog(inst);
      };
      if (duration != '' && $.effects && $.effects[showAnim])
        inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'),
          duration, postProcess);
      else
        inst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' :
          (showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess);
      if (duration == '')
        this._tidyDialog(inst);
      var onClose = this._get(inst, 'onClose');
      if (onClose)
        onClose.apply((inst.input ? inst.input[0] : null),
          [(inst.input ? inst.input.val() : ''), inst]);  // trigger custom callback
      this._datepickerShowing = false;
      this._lastInput = null;
      if (this._inDialog) {
        this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
        if ($.blockUI) {
          $.unblockUI();
          $('body').append(this.dpDiv);
        }
      }
      this._inDialog = false;
    }
    this._curInst = null;
  },

  /* Tidy up after a dialog display. */
  _tidyDialog: function(inst) {
    inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
  },

  /* Close date picker if clicked elsewhere. */
  _checkExternalClick: function(event) {
    if (!$.datepicker._curInst)
      return;
    var $target = $(event.target);
    if (($target.parents('#' + $.datepicker._mainDivId).length == 0) &&
        !$target.hasClass($.datepicker.markerClassName) &&
        !$target.hasClass($.datepicker._triggerClass) &&
        $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
      $.datepicker._hideDatepicker(null, '');
  },

  /* Adjust one of the date sub-fields. */
  _adjustDate: function(id, offset, period) {
    var target = $(id);
    var inst = this._getInst(target[0]);
    if (this._isDisabledDatepicker(target[0])) {
      return;
    }
    this._adjustInstDate(inst, offset +
      (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
      period);
    this._updateDatepicker(inst);
  },

  /* Action for current link. */
  _gotoToday: function(id) {
    var target = $(id);
    var inst = this._getInst(target[0]);
    if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
      inst.selectedDay = inst.currentDay;
      inst.drawMonth = inst.selectedMonth = inst.currentMonth;
      inst.drawYear = inst.selectedYear = inst.currentYear;
    }
    else {
    var date = new Date();
    inst.selectedDay = date.getDate();
    inst.drawMonth = inst.selectedMonth = date.getMonth();
    inst.drawYear = inst.selectedYear = date.getFullYear();
    }
    this._notifyChange(inst);
    this._adjustDate(target);
  },

  /* Action for selecting a new month/year. */
  _selectMonthYear: function(id, select, period) {
    var target = $(id);
    var inst = this._getInst(target[0]);
    inst._selectingMonthYear = false;
    inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
    inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
      parseInt(select.options[select.selectedIndex].value,10);
    this._notifyChange(inst);
    this._adjustDate(target);
  },

  /* Restore input focus after not changing month/year. */
  _clickMonthYear: function(id) {
    var target = $(id);
    var inst = this._getInst(target[0]);
    if (inst.input && inst._selectingMonthYear && !$.browser.msie)
      inst.input[0].focus();
    inst._selectingMonthYear = !inst._selectingMonthYear;
  },

  /* Action for selecting a day. */
  _selectDay: function(id, month, year, td) {
    var target = $(id);
    if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
      return;
    }
    var inst = this._getInst(target[0]);
    inst.selectedDay = inst.currentDay = $('a', td).html();
    inst.selectedMonth = inst.currentMonth = month;
    inst.selectedYear = inst.currentYear = year;
    if (inst.stayOpen) {
      inst.endDay = inst.endMonth = inst.endYear = null;
    }
    this._selectDate(id, this._formatDate(inst,
      inst.currentDay, inst.currentMonth, inst.currentYear));
    if (inst.stayOpen) {
      inst.rangeStart = this._daylightSavingAdjust(
        new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
      this._updateDatepicker(inst);
    }
  },

  /* Erase the input field and hide the date picker. */
  _clearDate: function(id) {
    var target = $(id);
    var inst = this._getInst(target[0]);
    inst.stayOpen = false;
    inst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null;
    this._selectDate(target, '');
  },

  /* Update the input field with the selected date. */
  _selectDate: function(id, dateStr) {
    var target = $(id);
    var inst = this._getInst(target[0]);
    dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
    if (inst.input)
      inst.input.val(dateStr);
    this._updateAlternate(inst);
    var onSelect = this._get(inst, 'onSelect');
    if (onSelect)
      onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
    else if (inst.input)
      inst.input.trigger('change'); // fire the change event
    if (inst.inline)
      this._updateDatepicker(inst);
    else if (!inst.stayOpen) {
      this._hideDatepicker(null, this._get(inst, 'duration'));
      this._lastInput = inst.input[0];
      if (typeof(inst.input[0]) != 'object')
        inst.input[0].focus(); // restore focus
      this._lastInput = null;
    }
  },

  /* Update any alternate field to synchronise with the main field. */
  _updateAlternate: function(inst) {
    var altField = this._get(inst, 'altField');
    if (altField) { // update alternate field too
      var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
      var date = this._getDate(inst);
      dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
      $(altField).each(function() { $(this).val(dateStr); });
    }
  },

  /* Set as beforeShowDay function to prevent selection of weekends.
     @param  date  Date - the date to customise
     @return [boolean, string] - is this date selectable?, what is its CSS class? */
  noWeekends: function(date) {
    var day = date.getDay();
    return [(day > 0 && day < 6), ''];
  },

  /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
     @param  date  Date - the date to get the week for
     @return  number - the number of the week within the year that contains this date */
  iso8601Week: function(date) {
    var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
    var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan
    var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7
    firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday
    if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary
      checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year
      return $.datepicker.iso8601Week(checkDate);
    } else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year
      firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7;
      if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary
        return 1;
      }
    }
    return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date
  },

  /* Parse a string value into a date object.
     See formatDate below for the possible formats.

     @param  format    string - the expected format of the date
     @param  value     string - the date in the above format
     @param  settings  Object - attributes include:
                       shortYearCutoff  number - the cutoff year for determining the century (optional)
                       dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
                       dayNames         string[7] - names of the days from Sunday (optional)
                       monthNamesShort  string[12] - abbreviated names of the months (optional)
                       monthNames       string[12] - names of the months (optional)
     @return  Date - the extracted date value or null if value is blank */
  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 doy = -1;
    var literal = false;
    // Check whether a format character is doubled
    var lookAhead = function(match) {
      var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
      if (matches)
        iFormat++;
      return matches;
    };
    // Extract a number from the string value
    var getNumber = function(match) {
      lookAhead(match);
      var origSize = (match == '@' ? 14 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2)));
      var size = origSize;
      var num = 0;
      while (size > 0 && iValue < value.length &&
          value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') {
        num = num * 10 + parseInt(value.charAt(iValue++),10);
        size--;
      }
      if (size == origSize)
        throw 'Missing number at position ' + iValue;
      return num;
    };
    // Extract a name from the string value and convert to an index
    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;
    };
    // Confirm that a literal character matches the string value
    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 'o':
            doy = getNumber('o');
            break;
          case 'm':
            month = getNumber('m');
            break;
          case 'M':
            month = getName('M', monthNamesShort, monthNames);
            break;
          case 'y':
            year = getNumber('y');
            break;
          case '@':
            var date = new Date(getNumber('@'));
            year = date.getFullYear();
            month = date.getMonth() + 1;
            day = date.getDate();
            break;
          case "'":
            if (lookAhead("'"))
              checkLiteral();
            else
              literal = true;
            break;
          default:
            checkLiteral();
        }
    }
    if (year == -1)
      year = new Date().getFullYear();
    else if (year < 100)
      year += new Date().getFullYear() - new Date().getFullYear() % 100 +
        (year <= shortYearCutoff ? 0 : -100);
    if (doy > -1) {
      month = 1;
      day = doy;
      do {
        var dim = this._getDaysInMonth(year, month - 1);
        if (day <= dim)
          break;
        month++;
        day -= dim;
      } while (true);
    }
    var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
    if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
      throw 'Invalid date'; // E.g. 31/02/*
    return date;
  },

  /* Standard date formats. */
  ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
  COOKIE: 'D, dd M yy',
  ISO_8601: 'yy-mm-dd',
  RFC_822: 'D, d M y',
  RFC_850: 'DD, dd-M-y',
  RFC_1036: 'D, d M y',
  RFC_1123: 'D, d M yy',
  RFC_2822: 'D, d M yy',
  RSS: 'D, d M y', // RFC 822
  TIMESTAMP: '@',
  W3C: 'yy-mm-dd', // ISO 8601

  /* Format a date object into a string value.
     The format can be combinations of the following:
     d  - day of month (no leading zero)
     dd - day of month (two digit)
     o  - day of year (no leading zeros)
     oo - day of year (three digit)
     D  - day name short
     DD - day name long
     m  - month of year (no leading zero)
     mm - month of year (two digit)
     M  - month name short
     MM - month name long
     y  - year (two digit)
     yy - year (four digit)
     @ - Unix timestamp (ms since 01/01/1970)
     '...' - literal text
     '' - single quote

     @param  format    string - the desired format of the date
     @param  date      Date - the date value to format
     @param  settings  Object - attributes include:
                       dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
                       dayNames         string[7] - names of the days from Sunday (optional)
                       monthNamesShort  string[12] - abbreviated names of the months (optional)
                       monthNames       string[12] - names of the months (optional)
     @return  string - the date in the above format */
  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;
    // Check whether a format character is doubled
    var lookAhead = function(match) {
      var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
      if (matches)
        iFormat++;
      return matches;
    };
    // Format a number, with leading zero if necessary
    var formatNumber = function(match, value, len) {
      var num = '' + value;
      if (lookAhead(match))
        while (num.length < len)
          num = '0' + num;
      return num;
    };
    // Format a name, short or long as requested
    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(), 2);
              break;
            case 'D':
              output += formatName('D', date.getDay(), dayNamesShort, dayNames);
              break;
            case 'o':
              var doy = date.getDate();
              for (var m = date.getMonth() - 1; m >= 0; m--)
                doy += this._getDaysInMonth(date.getFullYear(), m);
              output += formatNumber('o', doy, 3);
              break;
            case 'm':
              output += formatNumber('m', date.getMonth() + 1, 2);
              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 '@':
              output += date.getTime();
              break;
            case "'":
              if (lookAhead("'"))
                output += "'";
              else
                literal = true;
              break;
            default:
              output += format.charAt(iFormat);
          }
      }
    return output;
  },

  /* Extract all possible characters from the date format. */
  _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': case 'm': case 'y': case '@':
            chars += '0123456789';
            break;
          case 'D': case 'M':
            return null; // Accept anything
          case "'":
            if (lookAhead("'"))
              chars += "'";
            else
              literal = true;
            break;
          default:
            chars += format.charAt(iFormat);
        }
    return chars;
  },

  /* Get a setting value, defaulting if necessary. */
  _get: function(inst, name) {
    return inst.settings[name] !== undefined ?
      inst.settings[name] : this._defaults[name];
  },

  /* Parse existing date and initialise date picker. */
  _setDateFromField: function(inst) {
    var dateFormat = this._get(inst, 'dateFormat');
    var dates = inst.input ? inst.input.val() : null;
    inst.endDay = inst.endMonth = inst.endYear = null;
    var date = defaultDate = this._getDefaultDate(inst);
    var settings = this._getFormatConfig(inst);
    try {
      date = this.parseDate(dateFormat, dates, settings) || defaultDate;
    } catch (event) {
      this.log(event);
      date = defaultDate;
    }
    inst.selectedDay = date.getDate();
    inst.drawMonth = inst.selectedMonth = date.getMonth();
    inst.drawYear = inst.selectedYear = date.getFullYear();
    inst.currentDay = (dates ? date.getDate() : 0);
    inst.currentMonth = (dates ? date.getMonth() : 0);
    inst.currentYear = (dates ? date.getFullYear() : 0);
    this._adjustInstDate(inst);
  },

  /* Retrieve the default date shown on opening. */
  _getDefaultDate: function(inst) {
    var date = this._determineDate(this._get(inst, 'defaultDate'), new Date());
    var minDate = this._getMinMaxDate(inst, 'min', true);
    var maxDate = this._getMinMaxDate(inst, 'max');
    date = (minDate && date < minDate ? minDate : date);
    date = (maxDate && date > maxDate ? maxDate : date);
    return date;
  },

  /* A date may be specified as an exact value or a relative one. */
  _determineDate: function(date, 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 year = date.getFullYear();
      var month = date.getMonth();
      var day = date.getDate();
      var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
      var matches = pattern.exec(offset);
      while (matches) {
        switch (matches[2] || 'd') {
          case 'd' : case 'D' :
            day += parseInt(matches[1],10); break;
          case 'w' : case 'W' :
            day += parseInt(matches[1],10) * 7; break;
          case 'm' : case 'M' :
            month += parseInt(matches[1],10);
            day = Math.min(day, getDaysInMonth(year, month));
            break;
          case 'y': case 'Y' :
            year += parseInt(matches[1],10);
            day = Math.min(day, getDaysInMonth(year, month));
            break;
        }
        matches = pattern.exec(offset);
      }
      return new Date(year, month, day);
    };
    date = (date == null ? defaultDate :
      (typeof date == 'string' ? offsetString(date, this._getDaysInMonth) :
      (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : date)));
    date = (date && date.toString() == 'Invalid Date' ? defaultDate : date);
    if (date) {
      date.setHours(0);
      date.setMinutes(0);
      date.setSeconds(0);
      date.setMilliseconds(0);
    }
    return this._daylightSavingAdjust(date);
  },

  /* Handle switch to/from daylight saving.
     Hours may be non-zero on daylight saving cut-over:
     > 12 when midnight changeover, but then cannot generate
     midnight datetime, so jump to 1AM, otherwise reset.
     @param  date  (Date) the date to check
     @return  (Date) the corrected date */
  _daylightSavingAdjust: function(date) {
    if (!date) return null;
    date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
    return date;
  },

  /* Set the date(s) directly. */
  _setDate: function(inst, date, endDate) {
    var clear = !(date);
    var origMonth = inst.selectedMonth;
    var origYear = inst.selectedYear;
    date = this._determineDate(date, new Date());
    inst.selectedDay = inst.currentDay = date.getDate();
    inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth();
    inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear();
    if (origMonth != inst.selectedMonth || origYear != inst.selectedYear)
      this._notifyChange(inst);
    this._adjustInstDate(inst);
    if (inst.input) {
      inst.input.val(clear ? '' : this._formatDate(inst));
    }
  },

  /* Retrieve the date(s) directly. */
  _getDate: function(inst) {
    var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
      this._daylightSavingAdjust(new Date(
      inst.currentYear, inst.currentMonth, inst.currentDay)));
      return startDate;
  },

  /* Generate the HTML for the current state of the date picker. */
  _generateHTML: function(inst) {
    var today = new Date();
    today = this._daylightSavingAdjust(
      new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
    var isRTL = this._get(inst, 'isRTL');
    var showButtonPanel = this._get(inst, 'showButtonPanel');
    var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
    var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
    var numMonths = this._getNumberOfMonths(inst);
    var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
    var stepMonths = this._get(inst, 'stepMonths');
    var stepBigMonths = this._get(inst, 'stepBigMonths');
    var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
    var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
      new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
    var minDate = this._getMinMaxDate(inst, 'min', true);
    var maxDate = this._getMinMaxDate(inst, 'max');
    var drawMonth = inst.drawMonth - showCurrentAtPos;
    var drawYear = inst.drawYear;
    if (drawMonth < 0) {
      drawMonth += 12;
      drawYear--;
    }
    if (maxDate) {
      var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
        maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate()));
      maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
      while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
        drawMonth--;
        if (drawMonth < 0) {
          drawMonth = 11;
          drawYear--;
        }
      }
    }
    inst.drawMonth = drawMonth;
    inst.drawYear = drawYear;
    var prevText = this._get(inst, 'prevText');
    prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
      this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
      this._getFormatConfig(inst)));
    var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
      '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
      ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
      (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
    var nextText = this._get(inst, 'nextText');
    nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
      this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
      this._getFormatConfig(inst)));
    var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
      '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
      ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
      (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
    var currentText = this._get(inst, 'currentText');
    var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
    currentText = (!navigationAsDateFormat ? currentText :
      this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
    var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
    var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
      (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery.datepicker._gotoToday(\'#' + inst.id + '\');"' +
      '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
    var firstDay = parseInt(this._get(inst, 'firstDay'),10);
    firstDay = (isNaN(firstDay) ? 0 : firstDay);
    var dayNames = this._get(inst, 'dayNames');
    var dayNamesShort = this._get(inst, 'dayNamesShort');
    var dayNamesMin = this._get(inst, 'dayNamesMin');
    var monthNames = this._get(inst, 'monthNames');
    var monthNamesShort = this._get(inst, 'monthNamesShort');
    var beforeShowDay = this._get(inst, 'beforeShowDay');
    var showOtherMonths = this._get(inst, 'showOtherMonths');
    var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
    var endDate = inst.endDay ? this._daylightSavingAdjust(
      new Date(inst.endYear, inst.endMonth, inst.endDay)) : currentDate;
    var defaultDate = this._getDefaultDate(inst);
    var html = '';
    for (var row = 0; row < numMonths[0]; row++) {
      var group = '';
      for (var col = 0; col < numMonths[1]; col++) {
        var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
        var cornerClass = ' ui-corner-all';
        var calender = '';
        if (isMultiMonth) {
          calender += '<div class="ui-datepicker-group ui-datepicker-group-';
          switch (col) {
            case 0: calender += 'first'; cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
            case numMonths[1]-1: calender += 'last'; cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
            default: calender += 'middle'; cornerClass = ''; break;
          }
          calender += '">';
        }
        calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
          (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
          (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
          this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
          selectedDate, row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
          '</div><table class="ui-datepicker-calendar"><thead>' +
          '<tr>';
        var thead = '';
        for (var dow = 0; dow < 7; dow++) { // days of the week
          var day = (dow + firstDay) % 7;
          thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
            '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
        }
        calender += thead + '</tr></thead><tbody>';
        var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
        if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
          inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
        var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
        var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate
        var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
        for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
          calender += '<tr>';
          var tbody = '';
          for (var dow = 0; dow < 7; dow++) { // create date picker days
            var daySettings = (beforeShowDay ?
              beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
            var otherMonth = (printDate.getMonth() != drawMonth);
            var unselectable = otherMonth || !daySettings[0] ||
              (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
            tbody += '<td class="' +
              ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
              (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
              ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
              (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
              // or defaultDate is current printedDate and defaultDate is selectedDate
              ' ' + this._dayOverClass : '') + // highlight selected day
              (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
              (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
              (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range
              ' ' + this._currentClass : '') + // highlight selected day
              (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
              ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
              (unselectable ? '' : ' onclick="DP_jQuery.datepicker._selectDay(\'#' +
              inst.id + '\',' + drawMonth + ',' + drawYear + ', this);return false;"') + '>' + // actions
              (otherMonth ? (showOtherMonths ? printDate.getDate() : '&#xa0;') : // display for other months
              (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
              (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
              (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range
              ' ui-state-active' : '') + // highlight selected day
              '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display for this month
            printDate.setDate(printDate.getDate() + 1);
            printDate = this._daylightSavingAdjust(printDate);
          }
          calender += tbody + '</tr>';
        }
        drawMonth++;
        if (drawMonth > 11) {
          drawMonth = 0;
          drawYear++;
        }
        calender += '</tbody></table>' + (isMultiMonth ? '</div>' + 
              ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
        group += calender;
      }
      html += group;
    }
    html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
      '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
    inst._keyEvent = false;
    return html;
  },

  /* Generate the month and year header. */
  _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
      selectedDate, secondary, monthNames, monthNamesShort) {
    minDate = (inst.rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate);
    var changeMonth = this._get(inst, 'changeMonth');
    var changeYear = this._get(inst, 'changeYear');
    var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
    var html = '<div class="ui-datepicker-title">';
    var monthHtml = '';
    // month selection
    if (secondary || !changeMonth)
      monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span> ';
    else {
      var inMinYear = (minDate && minDate.getFullYear() == drawYear);
      var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
      monthHtml += '<select class="ui-datepicker-month" ' +
        'onchange="DP_jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
        'onclick="DP_jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
        '>';
      for (var month = 0; month < 12; month++) {
        if ((!inMinYear || month >= minDate.getMonth()) &&
            (!inMaxYear || month <= maxDate.getMonth()))
          monthHtml += '<option value="' + month + '"' +
            (month == drawMonth ? ' selected="selected"' : '') +
            '>' + monthNamesShort[month] + '</option>';
      }
      monthHtml += '</select>';
    }
    if (!showMonthAfterYear)
      html += monthHtml + ((secondary || changeMonth || changeYear) && (!(changeMonth && changeYear)) ? '&#xa0;' : '');
    // year selection
    if (secondary || !changeYear)
      html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
    else {
      // determine range of years to display
      var years = this._get(inst, '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="ui-datepicker-year" ' +
        'onchange="DP_jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
        'onclick="DP_jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
        '>';
      for (; year <= endYear; year++) {
        html += '<option value="' + year + '"' +
          (year == drawYear ? ' selected="selected"' : '') +
          '>' + year + '</option>';
      }
      html += '</select>';
    }
    if (showMonthAfterYear)
      html += (secondary || changeMonth || changeYear ? '&#xa0;' : '') + monthHtml;
    html += '</div>'; // Close datepicker_header
    return html;
  },

  /* Adjust one of the date sub-fields. */
  _adjustInstDate: function(inst, offset, period) {
    var year = inst.drawYear + (period == 'Y' ? offset : 0);
    var month = inst.drawMonth + (period == 'M' ? offset : 0);
    var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
      (period == 'D' ? offset : 0);
    var date = this._daylightSavingAdjust(new Date(year, month, day));
    // ensure it is within the bounds set
    var minDate = this._getMinMaxDate(inst, 'min', true);
    var maxDate = this._getMinMaxDate(inst, 'max');
    date = (minDate && date < minDate ? minDate : date);
    date = (maxDate && date > maxDate ? maxDate : date);
    inst.selectedDay = date.getDate();
    inst.drawMonth = inst.selectedMonth = date.getMonth();
    inst.drawYear = inst.selectedYear = date.getFullYear();
    if (period == 'M' || period == 'Y')
      this._notifyChange(inst);
  },

  /* Notify change of month/year. */
  _notifyChange: function(inst) {
    var onChange = this._get(inst, 'onChangeMonthYear');
    if (onChange)
      onChange.apply((inst.input ? inst.input[0] : null),
        [inst.selectedYear, inst.selectedMonth + 1, inst]);
  },

  /* Determine the number of months to show. */
  _getNumberOfMonths: function(inst) {
    var numMonths = this._get(inst, 'numberOfMonths');
    return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
  },

  /* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */
  _getMinMaxDate: function(inst, minMax, checkRange) {
    var date = this._determineDate(this._get(inst, minMax + 'Date'), null);
    return (!checkRange || !inst.rangeStart ? date :
      (!date || inst.rangeStart > date ? inst.rangeStart : date));
  },

  /* Find the number of days in a given month. */
  _getDaysInMonth: function(year, month) {
    return 32 - new Date(year, month, 32).getDate();
  },

  /* Find the day of the week of the first of a month. */
  _getFirstDayOfMonth: function(year, month) {
    return new Date(year, month, 1).getDay();
  },

  /* Determines if we should allow a "next/prev" month display change. */
  _canAdjustMonth: function(inst, offset, curYear, curMonth) {
    var numMonths = this._getNumberOfMonths(inst);
    var date = this._daylightSavingAdjust(new Date(
      curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1));
    if (offset < 0)
      date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
    return this._isInRange(inst, date);
  },

  /* Is the given date in the accepted range? */
  _isInRange: function(inst, date) {
    // during range selection, use minimum of selected date and range start
    var newMinDate = (!inst.rangeStart ? null : this._daylightSavingAdjust(
      new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay)));
    newMinDate = (newMinDate && inst.rangeStart < newMinDate ? inst.rangeStart : newMinDate);
    var minDate = newMinDate || this._getMinMaxDate(inst, 'min');
    var maxDate = this._getMinMaxDate(inst, 'max');
    return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate));
  },

  /* Provide the configuration settings for formatting/parsing. */
  _getFormatConfig: function(inst) {
    var shortYearCutoff = this._get(inst, 'shortYearCutoff');
    shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
      new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
    return {shortYearCutoff: shortYearCutoff,
      dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
      monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
  },

  /* Format the given date for display. */
  _formatDate: function(inst, day, month, year) {
    if (!day) {
      inst.currentDay = inst.selectedDay;
      inst.currentMonth = inst.selectedMonth;
      inst.currentYear = inst.selectedYear;
    }
    var date = (day ? (typeof day == 'object' ? day :
      this._daylightSavingAdjust(new Date(year, month, day))) :
      this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
    return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
  }
});

/* jQuery extend now ignores nulls! */
function extendRemove(target, props) {
  $.extend(target, props);
  for (var name in props)
    if (props[name] == null || props[name] == undefined)
      target[name] = props[name];
  return target;
};

/* Determine whether an object is an array. */
function isArray(a) {
  return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
    (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
};

/* Invoke the datepicker functionality.
   @param  options  string - a command, optionally followed by additional parameters or
                    Object - settings for attaching new datepicker functionality
   @return  jQuery object */
$.fn.datepicker = function(options){

  /* Initialise the date picker. */
  if (!$.datepicker.initialized) {
    $(document).mousedown($.datepicker._checkExternalClick).
      find('body').append($.datepicker.dpDiv);
    $.datepicker.initialized = true;
  }

  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(); // singleton instance
$.datepicker.initialized = false;
$.datepicker.uuid = new Date().getTime();
$.datepicker.version = "1.7.1";

// Workaround for #4055
// Add another global to avoid noConflict issues with inline event handlers
window.DP_jQuery = $;

})(jQuery);
/*
 * jQuery UI Effects 1.7.1
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Effects/
 */
;jQuery.effects || (function($) {

$.effects = {
  version: "1.7.1",

  // Saves a set of properties in a data storage
  save: function(element, set) {
    for(var i=0; i < set.length; i++) {
      if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
    }
  },

  // Restores a set of previously saved properties from a data storage
  restore: function(element, set) {
    for(var i=0; i < set.length; i++) {
      if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
    }
  },

  setMode: function(el, mode) {
    if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
    return mode;
  },

  getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
    // this should be a little more flexible in the future to handle a string & hash
    var y, x;
    switch (origin[0]) {
      case 'top': y = 0; break;
      case 'middle': y = 0.5; break;
      case 'bottom': y = 1; break;
      default: y = origin[0] / original.height;
    };
    switch (origin[1]) {
      case 'left': x = 0; break;
      case 'center': x = 0.5; break;
      case 'right': x = 1; break;
      default: x = origin[1] / original.width;
    };
    return {x: x, y: y};
  },

  // Wraps the element around a wrapper that copies position properties
  createWrapper: function(element) {

    //if the element is already wrapped, return it
    if (element.parent().is('.ui-effects-wrapper'))
      return element.parent();

    //Cache width,height and float properties of the element, and create a wrapper around it
    var props = { width: element.outerWidth(true), height: element.outerHeight(true), 'float': element.css('float') };
    element.wrap('<div class="ui-effects-wrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');
    var wrapper = element.parent();

    //Transfer the positioning of the element to the wrapper
    if (element.css('position') == 'static') {
      wrapper.css({ position: 'relative' });
      element.css({ position: 'relative'} );
    } else {
      var top = element.css('top'); if(isNaN(parseInt(top,10))) top = 'auto';
      var left = element.css('left'); if(isNaN(parseInt(left,10))) left = 'auto';
      wrapper.css({ position: element.css('position'), top: top, left: left, zIndex: element.css('z-index') }).show();
      element.css({position: 'relative', top: 0, left: 0 });
    }

    wrapper.css(props);
    return wrapper;
  },

  removeWrapper: function(element) {
    if (element.parent().is('.ui-effects-wrapper'))
      return element.parent().replaceWith(element);
    return element;
  },

  setTransition: function(element, list, factor, value) {
    value = value || {};
    $.each(list, function(i, x){
      unit = element.cssUnit(x);
      if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
    });
    return value;
  },

  //Base function to animate from one class to another in a seamless transition
  animateClass: function(value, duration, easing, callback) {

    var cb = (typeof easing == "function" ? easing : (callback ? callback : null));
    var ea = (typeof easing == "string" ? easing : null);

    return this.each(function() {

      var offset = {}; var that = $(this); var oldStyleAttr = that.attr("style") || '';
      if(typeof oldStyleAttr == 'object') oldStyleAttr = oldStyleAttr["cssText"]; /* Stupidly in IE, style is a object.. */
      if(value.toggle) { that.hasClass(value.toggle) ? value.remove = value.toggle : value.add = value.toggle; }

      //Let's get a style offset
      var oldStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle));
      if(value.add) that.addClass(value.add); if(value.remove) that.removeClass(value.remove);
      var newStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle));
      if(value.add) that.removeClass(value.add); if(value.remove) that.addClass(value.remove);

      // The main function to form the object for animation
      for(var n in newStyle) {
        if( typeof newStyle[n] != "function" && newStyle[n] /* No functions and null properties */
        && n.indexOf("Moz") == -1 && n.indexOf("length") == -1 /* No mozilla spezific render properties. */
        && newStyle[n] != oldStyle[n] /* Only values that have changed are used for the animation */
        && (n.match(/color/i) || (!n.match(/color/i) && !isNaN(parseInt(newStyle[n],10)))) /* Only things that can be parsed to integers or colors */
        && (oldStyle.position != "static" || (oldStyle.position == "static" && !n.match(/left|top|bottom|right/))) /* No need for positions when dealing with static positions */
        ) offset[n] = newStyle[n];
      }

      that.animate(offset, duration, ea, function() { // Animate the newly constructed offset object
        // Change style attribute back to original. For stupid IE, we need to clear the damn object.
        if(typeof $(this).attr("style") == 'object') { $(this).attr("style")["cssText"] = ""; $(this).attr("style")["cssText"] = oldStyleAttr; } else $(this).attr("style", oldStyleAttr);
        if(value.add) $(this).addClass(value.add); if(value.remove) $(this).removeClass(value.remove);
        if(cb) cb.apply(this, arguments);
      });

    });
  }
};


function _normalizeArguments(a, m) {

  var o = a[1] && a[1].constructor == Object ? a[1] : {}; if(m) o.mode = m;
  var speed = a[1] && a[1].constructor != Object ? a[1] : (o.duration ? o.duration : a[2]); //either comes from options.duration or the secon/third argument
    speed = $.fx.off ? 0 : typeof speed === "number" ? speed : $.fx.speeds[speed] || $.fx.speeds._default;
  var callback = o.callback || ( $.isFunction(a[1]) && a[1] ) || ( $.isFunction(a[2]) && a[2] ) || ( $.isFunction(a[3]) && a[3] );

  return [a[0], o, speed, callback];
  
}

//Extend the methods of jQuery
$.fn.extend({

  //Save old methods
  _show: $.fn.show,
  _hide: $.fn.hide,
  __toggle: $.fn.toggle,
  _addClass: $.fn.addClass,
  _removeClass: $.fn.removeClass,
  _toggleClass: $.fn.toggleClass,

  // New effect methods
  effect: function(fx, options, speed, callback) {
    return $.effects[fx] ? $.effects[fx].call(this, {method: fx, options: options || {}, duration: speed, callback: callback }) : null;
  },

  show: function() {
    if(!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0])))
      return this._show.apply(this, arguments);
    else {
      return this.effect.apply(this, _normalizeArguments(arguments, 'show'));
    }
  },

  hide: function() {
    if(!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0])))
      return this._hide.apply(this, arguments);
    else {
      return this.effect.apply(this, _normalizeArguments(arguments, 'hide'));
    }
  },

  toggle: function(){
    if(!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0])) || (arguments[0].constructor == Function))
      return this.__toggle.apply(this, arguments);
    else {
      return this.effect.apply(this, _normalizeArguments(arguments, 'toggle'));
    }
  },

  addClass: function(classNames, speed, easing, callback) {
    return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
  },
  removeClass: function(classNames,speed,easing,callback) {
    return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
  },
  toggleClass: function(classNames,speed,easing,callback) {
    return ( (typeof speed !== "boolean") && speed ) ? $.effects.animateClass.apply(this, [{ toggle: classNames },speed,easing,callback]) : this._toggleClass(classNames, speed);
  },
  morph: function(remove,add,speed,easing,callback) {
    return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
  },
  switchClass: function() {
    return this.morph.apply(this, arguments);
  },

  // helper functions
  cssUnit: function(key) {
    var style = this.css(key), val = [];
    $.each( ['em','px','%','pt'], function(i, unit){
      if(style.indexOf(unit) > 0)
        val = [parseFloat(style), unit];
    });
    return val;
  }
});

 /*
  * jQuery Color Animations
  * Copyright 2007 John Resig
  * Released under the MIT and GPL licenses.
  */

 (function(jQuery){

  // We override the animation for all of these color styles
  jQuery.each( [ 'backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor' ], function( i,attr ) {
    jQuery.fx.step[ attr ] = function( fx ) {
      if (fx.state <= 0.045 ) {
        fx.start = getColor( fx.elem, attr );
        fx.end = getRGB( fx.end );
      }

      fx.elem.style[ attr ] = "rgb(" + [
        Math.max( Math.min( parseInt( ( fx.pos * ( fx.end[ 0 ] - fx.start[ 0 ] ) ) + fx.start[ 0 ] ), 255 ), 0 ),
        Math.max( Math.min( parseInt( ( fx.pos * ( fx.end[ 1 ] - fx.start[ 1 ] ) ) + fx.start[ 1 ] ), 255 ), 0 ),
        Math.max( Math.min( parseInt( ( fx.pos * ( fx.end[ 2 ] - fx.start[ 2 ] ) ) + fx.start[ 2 ] ), 255 ), 0 )
      ].join( "," ) + ")";
    }
  } );

  // Color Conversion functions from highlightFade
  // By Blair Mitchelmore
  // http://jquery.offput.ca/highlightFade/

  // Parse strings looking for color tuples [255,255,255]
  function getRGB( color ) {
    var result;

    // Check if we're already dealing with an array of colors
    if ( color && color.constructor == Array && color.length == 3 )
      return color;

    // Look for rgb(num,num,num)
    if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
      return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];

    // Look for rgb(num%,num%,num%)
    if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
      return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];

    // Look for #a0b1c2
    if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
      return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];

    // Look for #fff
    if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
      return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];

    // Otherwise, we're most likely dealing with a named color
    return colors[jQuery.trim(color).toLowerCase()];
  }

  function getColor(elem, attr) {
    var color;

    do {
      color = jQuery.curCSS(elem, attr);

      // Keep going until we find an element that has color, or we hit the body
      if ( color != '' && color != 'transparent' || jQuery.nodeName(elem, "body") )
        break; 

      attr = "backgroundColor";
    } while ( elem = elem.parentNode );

    return getRGB(color);
  };

  // Some named colors to work with
  // From Interface by Stefan Petre
  // http://interface.eyecon.ro/

  var colors = {
    aqua:[0,255,255],
    azure:[240,255,255],
    beige:[245,245,220],
    black:[0,0,0],
    blue:[0,0,255],
    brown:[165,42,42],
    cyan:[0,255,255],
    darkblue:[0,0,139],
    darkcyan:[0,139,139],
    darkgrey:[169,169,169],
    darkgreen:[0,100,0],
    darkkhaki:[189,183,107],
    darkmagenta:[139,0,139],
    darkolivegreen:[85,107,47],
    darkorange:[255,140,0],
    darkorchid:[153,50,204],
    darkred:[139,0,0],
    darksalmon:[233,150,122],
    darkviolet:[148,0,211],
    fuchsia:[255,0,255],
    gold:[255,215,0],
    green:[0,128,0],
    indigo:[75,0,130],
    khaki:[240,230,140],
    lightblue:[173,216,230],
    lightcyan:[224,255,255],
    lightgreen:[144,238,144],
    lightgrey:[211,211,211],
    lightpink:[255,182,193],
    lightyellow:[255,255,224],
    lime:[0,255,0],
    magenta:[255,0,255],
    maroon:[128,0,0],
    navy:[0,0,128],
    olive:[128,128,0],
    orange:[255,165,0],
    pink:[255,192,203],
    purple:[128,0,128],
    violet:[128,0,128],
    red:[255,0,0],
    silver:[192,192,192],
    white:[255,255,255],
    yellow:[255,255,0]
  };

 })(jQuery);

/*
 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
 *
 * Uses the built in easing capabilities added In jQuery 1.1
 * to offer multiple easing options
 *
 * TERMS OF USE - jQuery Easing
 *
 * Open source under the BSD License.
 *
 * Copyright 2008 George McGinley Smith
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 *
 * Neither the name of the author nor the names of contributors may be used to endorse
 * or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
*/

// t: current time, b: begInnIng value, c: change In value, d: duration
$.easing.jswing = $.easing.swing;

$.extend($.easing,
{
  def: 'easeOutQuad',
  swing: function (x, t, b, c, d) {
    //alert($.easing.default);
    return $.easing[$.easing.def](x, t, b, c, d);
  },
  easeInQuad: function (x, t, b, c, d) {
    return c*(t/=d)*t + b;
  },
  easeOutQuad: function (x, t, b, c, d) {
    return -c *(t/=d)*(t-2) + b;
  },
  easeInOutQuad: function (x, t, b, c, d) {
    if ((t/=d/2) < 1) return c/2*t*t + b;
    return -c/2 * ((--t)*(t-2) - 1) + b;
  },
  easeInCubic: function (x, t, b, c, d) {
    return c*(t/=d)*t*t + b;
  },
  easeOutCubic: function (x, t, b, c, d) {
    return c*((t=t/d-1)*t*t + 1) + b;
  },
  easeInOutCubic: function (x, t, b, c, d) {
    if ((t/=d/2) < 1) return c/2*t*t*t + b;
    return c/2*((t-=2)*t*t + 2) + b;
  },
  easeInQuart: function (x, t, b, c, d) {
    return c*(t/=d)*t*t*t + b;
  },
  easeOutQuart: function (x, t, b, c, d) {
    return -c * ((t=t/d-1)*t*t*t - 1) + b;
  },
  easeInOutQuart: function (x, t, b, c, d) {
    if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
    return -c/2 * ((t-=2)*t*t*t - 2) + b;
  },
  easeInQuint: function (x, t, b, c, d) {
    return c*(t/=d)*t*t*t*t + b;
  },
  easeOutQuint: function (x, t, b, c, d) {
    return c*((t=t/d-1)*t*t*t*t + 1) + b;
  },
  easeInOutQuint: function (x, t, b, c, d) {
    if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
    return c/2*((t-=2)*t*t*t*t + 2) + b;
  },
  easeInSine: function (x, t, b, c, d) {
    return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
  },
  easeOutSine: function (x, t, b, c, d) {
    return c * Math.sin(t/d * (Math.PI/2)) + b;
  },
  easeInOutSine: function (x, t, b, c, d) {
    return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
  },
  easeInExpo: function (x, t, b, c, d) {
    return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
  },
  easeOutExpo: function (x, t, b, c, d) {
    return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
  },
  easeInOutExpo: function (x, t, b, c, d) {
    if (t==0) return b;
    if (t==d) return b+c;
    if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
    return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
  },
  easeInCirc: function (x, t, b, c, d) {
    return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
  },
  easeOutCirc: function (x, t, b, c, d) {
    return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
  },
  easeInOutCirc: function (x, t, b, c, d) {
    if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
    return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
  },
  easeInElastic: function (x, t, b, c, d) {
    var s=1.70158;var p=0;var a=c;
    if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
    if (a < Math.abs(c)) { a=c; var s=p/4; }
    else var s = p/(2*Math.PI) * Math.asin (c/a);
    return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
  },
  easeOutElastic: function (x, t, b, c, d) {
    var s=1.70158;var p=0;var a=c;
    if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
    if (a < Math.abs(c)) { a=c; var s=p/4; }
    else var s = p/(2*Math.PI) * Math.asin (c/a);
    return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
  },
  easeInOutElastic: function (x, t, b, c, d) {
    var s=1.70158;var p=0;var a=c;
    if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
    if (a < Math.abs(c)) { a=c; var s=p/4; }
    else var s = p/(2*Math.PI) * Math.asin (c/a);
    if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
    return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
  },
  easeInBack: function (x, t, b, c, d, s) {
    if (s == undefined) s = 1.70158;
    return c*(t/=d)*t*((s+1)*t - s) + b;
  },
  easeOutBack: function (x, t, b, c, d, s) {
    if (s == undefined) s = 1.70158;
    return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
  },
  easeInOutBack: function (x, t, b, c, d, s) {
    if (s == undefined) s = 1.70158;
    if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
    return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
  },
  easeInBounce: function (x, t, b, c, d) {
    return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
  },
  easeOutBounce: function (x, t, b, c, d) {
    if ((t/=d) < (1/2.75)) {
      return c*(7.5625*t*t) + b;
    } else if (t < (2/2.75)) {
      return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
    } else if (t < (2.5/2.75)) {
      return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
    } else {
      return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
    }
  },
  easeInOutBounce: function (x, t, b, c, d) {
    if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
    return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
  }
});

/*
 *
 * TERMS OF USE - EASING EQUATIONS
 *
 * Open source under the BSD License.
 *
 * Copyright 2001 Robert Penner
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 *
 * Neither the name of the author nor the names of contributors may be used to endorse
 * or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

})(jQuery);
/*
 * jQuery UI Effects Blind 1.7.1
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Effects/Blind
 *
 * Depends:
 *  effects.core.js
 */
(function($) {

$.effects.blind = function(o) {

  return this.queue(function() {

    // Create element
    var el = $(this), props = ['position','top','left'];

    // Set options
    var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
    var direction = o.options.direction || 'vertical'; // Default direction

    // Adjust
    $.effects.save(el, props); el.show(); // Save & Show
    var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
    var ref = (direction == 'vertical') ? 'height' : 'width';
    var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
    if(mode == 'show') wrapper.css(ref, 0); // Shift

    // Animation
    var animation = {};
    animation[ref] = mode == 'show' ? distance : 0;

    // Animate
    wrapper.animate(animation, o.duration, o.options.easing, function() {
      if(mode == 'hide') el.hide(); // Hide
      $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
      if(o.callback) o.callback.apply(el[0], arguments); // Callback
      el.dequeue();
    });

  });

};

})(jQuery);




