Index: /trunk/prototype/plugins/datejs/core.js
===================================================================
--- /trunk/prototype/plugins/datejs/core.js	(revision 5341)
+++ /trunk/prototype/plugins/datejs/core.js	(revision 7143)
@@ -1,39 +1,48 @@
 /**
- * Version: 1.0 Alpha-1 
- * Build Date: 13-Nov-2007
- * Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
- * License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
- * Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
+ * @version: 1.0 Alpha-1
+ * @author: Coolite Inc. http://www.coolite.com/
+ * @date: 2008-05-13
+ * @copyright: Copyright (c) 2006-2008, Coolite Inc. (http://www.coolite.com/). All rights reserved.
+ * @license: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
+ * @website: http://www.datejs.com/
  */
-Date.getMonthNumberFromName=function(name){var n=Date.CultureInfo.monthNames,m=Date.CultureInfo.abbreviatedMonthNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
-return-1;};Date.getDayNumberFromName=function(name){var n=Date.CultureInfo.dayNames,m=Date.CultureInfo.abbreviatedDayNames,o=Date.CultureInfo.shortestDayNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
-return-1;};Date.isLeapYear=function(year){return(((year%4===0)&&(year%100!==0))||(year%400===0));};Date.getDaysInMonth=function(year,month){return[31,(Date.isLeapYear(year)?29:28),31,30,31,30,31,31,30,31,30,31][month];};Date.getTimezoneOffset=function(s,dst){return(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST[s.toUpperCase()]:Date.CultureInfo.abbreviatedTimeZoneStandard[s.toUpperCase()];};Date.getTimezoneAbbreviation=function(offset,dst){var n=(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST:Date.CultureInfo.abbreviatedTimeZoneStandard,p;for(p in n){if(n[p]===offset){return p;}}
-return null;};Date.prototype.clone=function(){return new Date(this.getTime());};Date.prototype.compareTo=function(date){if(isNaN(this)){throw new Error(this);}
-if(date instanceof Date&&!isNaN(date)){return(this>date)?1:(this<date)?-1:0;}else{throw new TypeError(date);}};Date.prototype.equals=function(date){return(this.compareTo(date)===0);};Date.prototype.between=function(start,end){var t=this.getTime();return t>=start.getTime()&&t<=end.getTime();};Date.prototype.addMilliseconds=function(value){this.setMilliseconds(this.getMilliseconds()+value);return this;};Date.prototype.addSeconds=function(value){return this.addMilliseconds(value*1000);};Date.prototype.addMinutes=function(value){return this.addMilliseconds(value*60000);};Date.prototype.addHours=function(value){return this.addMilliseconds(value*3600000);};Date.prototype.addDays=function(value){return this.addMilliseconds(value*86400000);};Date.prototype.addWeeks=function(value){return this.addMilliseconds(value*604800000);};Date.prototype.addMonths=function(value){var n=this.getDate();this.setDate(1);this.setMonth(this.getMonth()+value);this.setDate(Math.min(n,this.getDaysInMonth()));return this;};Date.prototype.addYears=function(value){return this.addMonths(value*12);};Date.prototype.add=function(config){if(typeof config=="number"){this._orient=config;return this;}
-var x=config;if(x.millisecond||x.milliseconds){this.addMilliseconds(x.millisecond||x.milliseconds);}
-if(x.second||x.seconds){this.addSeconds(x.second||x.seconds);}
-if(x.minute||x.minutes){this.addMinutes(x.minute||x.minutes);}
-if(x.hour||x.hours){this.addHours(x.hour||x.hours);}
-if(x.month||x.months){this.addMonths(x.month||x.months);}
-if(x.year||x.years){this.addYears(x.year||x.years);}
-if(x.day||x.days){this.addDays(x.day||x.days);}
-return this;};Date._validate=function(value,min,max,name){if(typeof value!="number"){throw new TypeError(value+" is not a Number.");}else if(value<min||value>max){throw new RangeError(value+" is not a valid value for "+name+".");}
-return true;};Date.validateMillisecond=function(n){return Date._validate(n,0,999,"milliseconds");};Date.validateSecond=function(n){return Date._validate(n,0,59,"seconds");};Date.validateMinute=function(n){return Date._validate(n,0,59,"minutes");};Date.validateHour=function(n){return Date._validate(n,0,23,"hours");};Date.validateDay=function(n,year,month){return Date._validate(n,1,Date.getDaysInMonth(year,month),"days");};Date.validateMonth=function(n){return Date._validate(n,0,11,"months");};Date.validateYear=function(n){return Date._validate(n,1,9999,"seconds");};Date.prototype.set=function(config){var x=config;if(!x.millisecond&&x.millisecond!==0){x.millisecond=-1;}
-if(!x.second&&x.second!==0){x.second=-1;}
-if(!x.minute&&x.minute!==0){x.minute=-1;}
-if(!x.hour&&x.hour!==0){x.hour=-1;}
-if(!x.day&&x.day!==0){x.day=-1;}
-if(!x.month&&x.month!==0){x.month=-1;}
-if(!x.year&&x.year!==0){x.year=-1;}
-if(x.millisecond!=-1&&Date.validateMillisecond(x.millisecond)){this.addMilliseconds(x.millisecond-this.getMilliseconds());}
-if(x.second!=-1&&Date.validateSecond(x.second)){this.addSeconds(x.second-this.getSeconds());}
-if(x.minute!=-1&&Date.validateMinute(x.minute)){this.addMinutes(x.minute-this.getMinutes());}
-if(x.hour!=-1&&Date.validateHour(x.hour)){this.addHours(x.hour-this.getHours());}
-if(x.month!==-1&&Date.validateMonth(x.month)){this.addMonths(x.month-this.getMonth());}
-if(x.year!=-1&&Date.validateYear(x.year)){this.addYears(x.year-this.getFullYear());}
-if(x.day!=-1&&Date.validateDay(x.day,this.getFullYear(),this.getMonth())){this.addDays(x.day-this.getDate());}
-if(x.timezone){this.setTimezone(x.timezone);}
-if(x.timezoneOffset){this.setTimezoneOffset(x.timezoneOffset);}
-return this;};Date.prototype.clearTime=function(){this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};Date.prototype.isLeapYear=function(){var y=this.getFullYear();return(((y%4===0)&&(y%100!==0))||(y%400===0));};Date.prototype.isWeekday=function(){return!(this.is().sat()||this.is().sun());};Date.prototype.getDaysInMonth=function(){return Date.getDaysInMonth(this.getFullYear(),this.getMonth());};Date.prototype.moveToFirstDayOfMonth=function(){return this.set({day:1});};Date.prototype.moveToLastDayOfMonth=function(){return this.set({day:this.getDaysInMonth()});};Date.prototype.moveToDayOfWeek=function(day,orient){var diff=(day-this.getDay()+7*(orient||+1))%7;return this.addDays((diff===0)?diff+=7*(orient||+1):diff);};Date.prototype.moveToMonth=function(month,orient){var diff=(month-this.getMonth()+12*(orient||+1))%12;return this.addMonths((diff===0)?diff+=12*(orient||+1):diff);};Date.prototype.getDayOfYear=function(){return Math.floor((this-new Date(this.getFullYear(),0,1))/86400000);};Date.prototype.getWeekOfYear=function(firstDayOfWeek){var y=this.getFullYear(),m=this.getMonth(),d=this.getDate();var dow=firstDayOfWeek||Date.CultureInfo.firstDayOfWeek;var offset=7+1-new Date(y,0,1).getDay();if(offset==8){offset=1;}
-var daynum=((Date.UTC(y,m,d,0,0,0)-Date.UTC(y,0,1,0,0,0))/86400000)+1;var w=Math.floor((daynum-offset+7)/7);if(w===dow){y--;var prevOffset=7+1-new Date(y,0,1).getDay();if(prevOffset==2||prevOffset==8){w=53;}else{w=52;}}
-return w;};Date.prototype.isDST=function(){console.log('isDST');return this.toString().match(/(E|C|M|P)(S|D)T/)[2]=="D";};Date.prototype.getTimezone=function(){return Date.getTimezoneAbbreviation(this.getUTCOffset,this.isDST());};Date.prototype.setTimezoneOffset=function(s){var here=this.getTimezoneOffset(),there=Number(s)*-6/10;this.addMinutes(there-here);return this;};Date.prototype.setTimezone=function(s){return this.setTimezoneOffset(Date.getTimezoneOffset(s));};Date.prototype.getUTCOffset=function(){var n=this.getTimezoneOffset()*-10/6,r;if(n<0){r=(n-10000).toString();return r[0]+r.substr(2);}else{r=(n+10000).toString();return"+"+r.substr(1);}};Date.prototype.getDayName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedDayNames[this.getDay()]:Date.CultureInfo.dayNames[this.getDay()];};Date.prototype.getMonthName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedMonthNames[this.getMonth()]:Date.CultureInfo.monthNames[this.getMonth()];};Date.prototype._toString=Date.prototype.toString;Date.prototype.toString=function(format){var self=this;var p=function p(s){return(s.toString().length==1)?"0"+s:s;};return format?format.replace(/dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?/g,function(format){switch(format){case"hh":return p(self.getHours()<13?self.getHours():(self.getHours()-12));case"h":return self.getHours()<13?self.getHours():(self.getHours()-12);case"HH":return p(self.getHours());case"H":return self.getHours();case"mm":return p(self.getMinutes());case"m":return self.getMinutes();case"ss":return p(self.getSeconds());case"s":return self.getSeconds();case"yyyy":return self.getFullYear();case"yy":return self.getFullYear().toString().substring(2,4);case"dddd":return self.getDayName();case"ddd":return self.getDayName(true);case"dd":return p(self.getDate());case"d":return self.getDate().toString();case"MMMM":return self.getMonthName();case"MMM":return self.getMonthName(true);case"MM":return p((self.getMonth()+1));case"M":return self.getMonth()+1;case"t":return self.getHours()<12?Date.CultureInfo.amDesignator.substring(0,1):Date.CultureInfo.pmDesignator.substring(0,1);case"tt":return self.getHours()<12?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;case"zzz":case"zz":case"z":return"";}}):this._toString();};
+(function(){var $D=Date,$P=$D.prototype,$C=$D.CultureInfo,p=function(s,l){if(!l){l=2;}
+return("000"+s).slice(l*-1);};$P.clearTime=function(){this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};$P.setTimeToNow=function(){var n=new Date();this.setHours(n.getHours());this.setMinutes(n.getMinutes());this.setSeconds(n.getSeconds());this.setMilliseconds(n.getMilliseconds());return this;};$D.today=function(){return new Date().clearTime();};$D.compare=function(date1,date2){if(isNaN(date1)||isNaN(date2)){throw new Error(date1+" - "+date2);}else if(date1 instanceof Date&&date2 instanceof Date){return(date1<date2)?-1:(date1>date2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s||o[i].toLowerCase()==s){return i;}}
+return-1;};$D.getMonthNumberFromName=function(name){var n=$C.monthNames,m=$C.abbreviatedMonthNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
+return-1;};$D.isLeapYear=function(year){return((year%4===0&&year%100!==0)||year%400===0);};$D.getDaysInMonth=function(year,month){return[31,($D.isLeapYear(year)?29:28),31,30,31,30,31,31,30,31,30,31][month];};$D.getTimezoneAbbreviation=function(offset){var z=$C.timezones,p;for(var i=0;i<z.length;i++){if(z[i].offset===offset){return z[i].name;}}
+return null;};$D.getTimezoneOffset=function(name){var z=$C.timezones,p;for(var i=0;i<z.length;i++){if(z[i].name===name.toUpperCase()){return z[i].offset;}}
+return null;};$P.clone=function(){return new Date(this.getTime());};$P.compareTo=function(date){return Date.compare(this,date);};$P.equals=function(date){return Date.equals(this,date||new Date());};$P.between=function(start,end){return this.getTime()>=start.getTime()&&this.getTime()<=end.getTime();};$P.isAfter=function(date){return this.compareTo(date||new Date())===1;};$P.isBefore=function(date){return(this.compareTo(date||new Date())===-1);};$P.isToday=function(){return this.isSameDay(new Date());};$P.isSameDay=function(date){return this.clone().clearTime().equals(date.clone().clearTime());};$P.addMilliseconds=function(value){this.setMilliseconds(this.getMilliseconds()+value);return this;};$P.addSeconds=function(value){return this.addMilliseconds(value*1000);};$P.addMinutes=function(value){return this.addMilliseconds(value*60000);};$P.addHours=function(value){return this.addMilliseconds(value*3600000);};$P.addDays=function(value){this.setDate(this.getDate()+value);return this;};$P.addWeeks=function(value){return this.addDays(value*7);};$P.addMonths=function(value){var n=this.getDate();this.setDate(1);this.setMonth(this.getMonth()+value);this.setDate(Math.min(n,$D.getDaysInMonth(this.getFullYear(),this.getMonth())));return this;};$P.addYears=function(value){return this.addMonths(value*12);};$P.add=function(config){if(typeof config=="number"){this._orient=config;return this;}
+var x=config;if(x.milliseconds){this.addMilliseconds(x.milliseconds);}
+if(x.seconds){this.addSeconds(x.seconds);}
+if(x.minutes){this.addMinutes(x.minutes);}
+if(x.hours){this.addHours(x.hours);}
+if(x.weeks){this.addWeeks(x.weeks);}
+if(x.months){this.addMonths(x.months);}
+if(x.years){this.addYears(x.years);}
+if(x.days){this.addDays(x.days);}
+return this;};var $y,$m,$d;$P.getWeek=function(){var a,b,c,d,e,f,g,n,s,w;$y=(!$y)?this.getFullYear():$y;$m=(!$m)?this.getMonth()+1:$m;$d=(!$d)?this.getDate():$d;if($m<=2){a=$y-1;b=(a/4|0)-(a/100|0)+(a/400|0);c=((a-1)/4|0)-((a-1)/100|0)+((a-1)/400|0);s=b-c;e=0;f=$d-1+(31*($m-1));}else{a=$y;b=(a/4|0)-(a/100|0)+(a/400|0);c=((a-1)/4|0)-((a-1)/100|0)+((a-1)/400|0);s=b-c;e=s+1;f=$d+((153*($m-3)+2)/5)+58+s;}
+g=(a+b)%7;d=(f+g-e)%7;n=(f+3-d)|0;if(n<0){w=53-((g-s)/5|0);}else if(n>364+s){w=1;}else{w=(n/7|0)+1;}
+$y=$m=$d=null;return w;};$P.getISOWeek=function(){$y=this.getUTCFullYear();$m=this.getUTCMonth()+1;$d=this.getUTCDate();return p(this.getWeek());};$P.setWeek=function(n){return this.moveToDayOfWeek(1).addWeeks(n-this.getWeek());};$D._validate=function(n,min,max,name){if(typeof n=="undefined"){return false;}else if(typeof n!="number"){throw new TypeError(n+" is not a Number.");}else if(n<min||n>max){throw new RangeError(n+" is not a valid value for "+name+".");}
+return true;};$D.validateMillisecond=function(value){return $D._validate(value,0,999,"millisecond");};$D.validateSecond=function(value){return $D._validate(value,0,59,"second");};$D.validateMinute=function(value){return $D._validate(value,0,59,"minute");};$D.validateHour=function(value){return $D._validate(value,0,23,"hour");};$D.validateDay=function(value,year,month){return $D._validate(value,1,$D.getDaysInMonth(year,month),"day");};$D.validateMonth=function(value){return $D._validate(value,0,11,"month");};$D.validateYear=function(value){return $D._validate(value,0,9999,"year");};$P.set=function(config){if($D.validateMillisecond(config.millisecond)){this.addMilliseconds(config.millisecond-this.getMilliseconds());}
+if($D.validateSecond(config.second)){this.addSeconds(config.second-this.getSeconds());}
+if($D.validateMinute(config.minute)){this.addMinutes(config.minute-this.getMinutes());}
+if($D.validateHour(config.hour)){this.addHours(config.hour-this.getHours());}
+if($D.validateMonth(config.month)){this.addMonths(config.month-this.getMonth());}
+if($D.validateYear(config.year)){this.addYears(config.year-this.getFullYear());}
+if($D.validateDay(config.day,this.getFullYear(),this.getMonth())){this.addDays(config.day-this.getDate());}
+if(config.timezone){this.setTimezone(config.timezone);}
+if(config.timezoneOffset){this.setTimezoneOffset(config.timezoneOffset);}
+if(config.week&&$D._validate(config.week,0,53,"week")){this.setWeek(config.week);}
+return this;};$P.moveToFirstDayOfMonth=function(){return this.set({day:1});};$P.moveToLastDayOfMonth=function(){return this.set({day:$D.getDaysInMonth(this.getFullYear(),this.getMonth())});};$P.moveToNthOccurrence=function(dayOfWeek,occurrence){var shift=0;if(occurrence>0){shift=occurrence-1;}
+else if(occurrence===-1){this.moveToLastDayOfMonth();if(this.getDay()!==dayOfWeek){this.moveToDayOfWeek(dayOfWeek,-1);}
+return this;}
+return this.moveToFirstDayOfMonth().addDays(-1).moveToDayOfWeek(dayOfWeek,+1).addWeeks(shift);};$P.moveToDayOfWeek=function(dayOfWeek,orient){var diff=(dayOfWeek-this.getDay()+7*(orient||+1))%7;return this.addDays((diff===0)?diff+=7*(orient||+1):diff);};$P.moveToMonth=function(month,orient){var diff=(month-this.getMonth()+12*(orient||+1))%12;return this.addMonths((diff===0)?diff+=12*(orient||+1):diff);};$P.getOrdinalNumber=function(){return Math.ceil((this.clone().clearTime()-new Date(this.getFullYear(),0,1))/86400000)+1;};$P.getTimezone=function(){return $D.getTimezoneAbbreviation(this.getUTCOffset());};$P.setTimezoneOffset=function(offset){var here=this.getTimezoneOffset(),there=Number(offset)*-6/10;return this.addMinutes(there-here);};$P.setTimezone=function(offset){return this.setTimezoneOffset($D.getTimezoneOffset(offset));};$P.hasDaylightSavingTime=function(){return(Date.today().set({month:0,day:1}).getTimezoneOffset()!==Date.today().set({month:6,day:1}).getTimezoneOffset());};$P.isDaylightSavingTime=function(){return(this.hasDaylightSavingTime()&&new Date().getTimezoneOffset()===Date.today().set({month:6,day:1}).getTimezoneOffset());};$P.getUTCOffset=function(){var n=this.getTimezoneOffset()*-10/6,r;if(n<0){r=(n-10000).toString();return r.charAt(0)+r.substr(2);}else{r=(n+10000).toString();return"+"+r.substr(1);}};$P.getElapsed=function(date){return(date||new Date())-this;};if(!$P.toISOString){$P.toISOString=function(){function f(n){return n<10?'0'+n:n;}
+return'"'+this.getUTCFullYear()+'-'+
+f(this.getUTCMonth()+1)+'-'+
+f(this.getUTCDate())+'T'+
+f(this.getUTCHours())+':'+
+f(this.getUTCMinutes())+':'+
+f(this.getUTCSeconds())+'Z"';};}
+$P._toString=$P.toString;$P.toString=function(format){var x=this;if(format&&format.length==1){var c=$C.formatPatterns;x.t=x.toString;switch(format){case"d":return x.t(c.shortDate);case"D":return x.t(c.longDate);case"F":return x.t(c.fullDateTime);case"m":return x.t(c.monthDay);case"r":return x.t(c.rfc1123);case"s":return x.t(c.sortableDateTime);case"t":return x.t(c.shortTime);case"T":return x.t(c.longTime);case"u":return x.t(c.universalSortableDateTime);case"y":return x.t(c.yearMonth);}}
+var ord=function(n){switch(n*1){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}};return format?format.replace(/(\\)?(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|S)/g,function(m){if(m.charAt(0)==="\\"){return m.replace("\\","");}
+x.h=x.getHours;switch(m){case"hh":return p(x.h()<13?(x.h()===0?12:x.h()):(x.h()-12));case"h":return x.h()<13?(x.h()===0?12:x.h()):(x.h()-12);case"HH":return p(x.h());case"H":return x.h();case"mm":return p(x.getMinutes());case"m":return x.getMinutes();case"ss":return p(x.getSeconds());case"s":return x.getSeconds();case"yyyy":return p(x.getFullYear(),4);case"yy":return p(x.getFullYear());case"dddd":return $C.dayNames[x.getDay()];case"ddd":return $C.abbreviatedDayNames[x.getDay()];case"dd":return p(x.getDate());case"d":return x.getDate();case"MMMM":return $C.monthNames[x.getMonth()];case"MMM":return $C.abbreviatedMonthNames[x.getMonth()];case"MM":return p((x.getMonth()+1));case"M":return x.getMonth()+1;case"t":return x.h()<12?$C.amDesignator.substring(0,1):$C.pmDesignator.substring(0,1);case"tt":return x.h()<12?$C.amDesignator:$C.pmDesignator;case"S":return ord(x.getDate());default:return m;}}):this._toString();};}());
Index: /trunk/prototype/plugins/datejs/core-debug.js
===================================================================
--- /trunk/prototype/plugins/datejs/core-debug.js	(revision 5341)
+++ /trunk/prototype/plugins/datejs/core-debug.js	(revision 7143)
@@ -1,651 +1,865 @@
 /**
- * Version: 1.0 Alpha-1 
- * Build Date: 12-Nov-2007
- * Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
- * License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
- * Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
+ * @version: 1.0 Alpha-1
+ * @author: Coolite Inc. http://www.coolite.com/
+ * @date: 2008-04-13
+ * @copyright: Copyright (c) 2006-2008, Coolite Inc. (http://www.coolite.com/). All rights reserved.
+ * @license: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
+ * @website: http://www.datejs.com/
  */
-
-/**
- * Gets the month number (0-11) if given a Culture Info specific string which is a valid monthName or abbreviatedMonthName.
- * @param {String}   The name of the month (eg. "February, "Feb", "october", "oct").
- * @return {Number}  The day number
- */
-Date.getMonthNumberFromName = function (name) {
-    var n = Date.CultureInfo.monthNames, m = Date.CultureInfo.abbreviatedMonthNames, s = name.toLowerCase();
-    for (var i = 0; i < n.length; i++) {
-        if (n[i].toLowerCase() == s || m[i].toLowerCase() == s) { 
-            return i; 
-        }
+ 
+(function () {
+    var $D = Date, 
+        $P = $D.prototype, 
+        $C = $D.CultureInfo,
+        p = function (s, l) {
+            if (!l) {
+                l = 2;
+            }
+            return ("000" + s).slice(l * -1);
+        };
+            
+    /**
+     * Resets the time of this Date object to 12:00 AM (00:00), which is the start of the day.
+     * @param {Boolean}  .clone() this date instance before clearing Time
+     * @return {Date}    this
+     */
+    $P.clearTime = function () {
+        this.setHours(0);
+        this.setMinutes(0);
+        this.setSeconds(0);
+        this.setMilliseconds(0);
+        return this;
+    };
+
+    /**
+     * Resets the time of this Date object to the current time ('now').
+     * @return {Date}    this
+     */
+    $P.setTimeToNow = function () {
+        var n = new Date();
+        this.setHours(n.getHours());
+        this.setMinutes(n.getMinutes());
+        this.setSeconds(n.getSeconds());
+        this.setMilliseconds(n.getMilliseconds());
+        return this;
+    };
+
+    /** 
+     * Gets a date that is set to the current date. The time is set to the start of the day (00:00 or 12:00 AM).
+     * @return {Date}    The current date.
+     */
+    $D.today = function () {
+        return new Date().clearTime();
+    };
+
+    /**
+     * Compares the first date to the second date and returns an number indication of their relative values.  
+     * @param {Date}     First Date object to compare [Required].
+     * @param {Date}     Second Date object to compare to [Required].
+     * @return {Number}  -1 = date1 is lessthan date2. 0 = values are equal. 1 = date1 is greaterthan date2.
+     */
+    $D.compare = function (date1, date2) {
+        if (isNaN(date1) || isNaN(date2)) { 
+            throw new Error(date1 + " - " + date2); 
+        } else if (date1 instanceof Date && date2 instanceof Date) {
+            return (date1 < date2) ? -1 : (date1 > date2) ? 1 : 0;
+        } else { 
+            throw new TypeError(date1 + " - " + date2); 
+        }
+    };
+    
+    /**
+     * Compares the first Date object to the second Date object and returns true if they are equal.  
+     * @param {Date}     First Date object to compare [Required]
+     * @param {Date}     Second Date object to compare to [Required]
+     * @return {Boolean} true if dates are equal. false if they are not equal.
+     */
+    $D.equals = function (date1, date2) { 
+        return (date1.compareTo(date2) === 0); 
+    };
+
+    /**
+     * Gets the day number (0-6) if given a CultureInfo specific string which is a valid dayName, abbreviatedDayName or shortestDayName (two char).
+     * @param {String}   The name of the day (eg. "Monday, "Mon", "tuesday", "tue", "We", "we").
+     * @return {Number}  The day number
+     */
+    $D.getDayNumberFromName = function (name) {
+        var n = $C.dayNames, m = $C.abbreviatedDayNames, o = $C.shortestDayNames, s = name.toLowerCase();
+        for (var i = 0; i < n.length; i++) { 
+            if (n[i].toLowerCase() == s || m[i].toLowerCase() == s || o[i].toLowerCase() == s) { 
+                return i; 
+            }
+        }
+        return -1;  
+    };
+    
+    /**
+     * Gets the month number (0-11) if given a Culture Info specific string which is a valid monthName or abbreviatedMonthName.
+     * @param {String}   The name of the month (eg. "February, "Feb", "october", "oct").
+     * @return {Number}  The day number
+     */
+    $D.getMonthNumberFromName = function (name) {
+        var n = $C.monthNames, m = $C.abbreviatedMonthNames, s = name.toLowerCase();
+        for (var i = 0; i < n.length; i++) {
+            if (n[i].toLowerCase() == s || m[i].toLowerCase() == s) { 
+                return i; 
+            }
+        }
+        return -1;
+    };
+
+    /**
+     * Determines if the current date instance is within a LeapYear.
+     * @param {Number}   The year.
+     * @return {Boolean} true if date is within a LeapYear, otherwise false.
+     */
+    $D.isLeapYear = function (year) { 
+        return ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0); 
+    };
+
+    /**
+     * Gets the number of days in the month, given a year and month value. Automatically corrects for LeapYear.
+     * @param {Number}   The year.
+     * @param {Number}   The month (0-11).
+     * @return {Number}  The number of days in the month.
+     */
+    $D.getDaysInMonth = function (year, month) {
+        return [31, ($D.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
+    };
+ 
+    $D.getTimezoneAbbreviation = function (offset) {
+        var z = $C.timezones, p;
+        for (var i = 0; i < z.length; i++) {
+            if (z[i].offset === offset) {
+                return z[i].name;
+            }
+        }
+        return null;
+    };
+    
+    $D.getTimezoneOffset = function (name) {
+        var z = $C.timezones, p;
+        for (var i = 0; i < z.length; i++) {
+            if (z[i].name === name.toUpperCase()) {
+                return z[i].offset;
+            }
+        }
+        return null;
+    };
+
+    /**
+     * Returns a new Date object that is an exact date and time copy of the original instance.
+     * @return {Date}    A new Date instance
+     */
+    $P.clone = function () {
+        return new Date(this.getTime()); 
+    };
+
+    /**
+     * Compares this instance to a Date object and returns an number indication of their relative values.  
+     * @param {Date}     Date object to compare [Required]
+     * @return {Number}  -1 = this is lessthan date. 0 = values are equal. 1 = this is greaterthan date.
+     */
+    $P.compareTo = function (date) {
+        return Date.compare(this, date);
+    };
+
+    /**
+     * Compares this instance to another Date object and returns true if they are equal.  
+     * @param {Date}     Date object to compare. If no date to compare, new Date() [now] is used.
+     * @return {Boolean} true if dates are equal. false if they are not equal.
+     */
+    $P.equals = function (date) {
+        return Date.equals(this, date || new Date());
+    };
+
+    /**
+     * Determines if this instance is between a range of two dates or equal to either the start or end dates.
+     * @param {Date}     Start of range [Required]
+     * @param {Date}     End of range [Required]
+     * @return {Boolean} true is this is between or equal to the start and end dates, else false
+     */
+    $P.between = function (start, end) {
+        return this.getTime() >= start.getTime() && this.getTime() <= end.getTime();
+    };
+
+    /**
+     * Determines if this date occurs after the date to compare to.
+     * @param {Date}     Date object to compare. If no date to compare, new Date() ("now") is used.
+     * @return {Boolean} true if this date instance is greater than the date to compare to (or "now"), otherwise false.
+     */
+    $P.isAfter = function (date) {
+        return this.compareTo(date || new Date()) === 1;
+    };
+
+    /**
+     * Determines if this date occurs before the date to compare to.
+     * @param {Date}     Date object to compare. If no date to compare, new Date() ("now") is used.
+     * @return {Boolean} true if this date instance is less than the date to compare to (or "now").
+     */
+    $P.isBefore = function (date) {
+        return (this.compareTo(date || new Date()) === -1);
+    };
+
+    /**
+     * Determines if the current Date instance occurs today.
+     * @return {Boolean} true if this date instance is 'today', otherwise false.
+     */
+    
+    /**
+     * Determines if the current Date instance occurs on the same Date as the supplied 'date'. 
+     * If no 'date' to compare to is provided, the current Date instance is compared to 'today'. 
+     * @param {date}     Date object to compare. If no date to compare, the current Date ("now") is used.
+     * @return {Boolean} true if this Date instance occurs on the same Day as the supplied 'date'.
+     */
+    $P.isToday = $P.isSameDay = function (date) {
+        return this.clone().clearTime().equals((date || new Date()).clone().clearTime());
+    };
+    
+    /**
+     * Adds the specified number of milliseconds to this instance. 
+     * @param {Number}   The number of milliseconds to add. The number can be positive or negative [Required]
+     * @return {Date}    this
+     */
+    $P.addMilliseconds = function (value) {
+        this.setMilliseconds(this.getMilliseconds() + value * 1);
+        return this;
+    };
+
+    /**
+     * Adds the specified number of seconds to this instance. 
+     * @param {Number}   The number of seconds to add. The number can be positive or negative [Required]
+     * @return {Date}    this
+     */
+    $P.addSeconds = function (value) { 
+        return this.addMilliseconds(value * 1000); 
+    };
+
+    /**
+     * Adds the specified number of seconds to this instance. 
+     * @param {Number}   The number of seconds to add. The number can be positive or negative [Required]
+     * @return {Date}    this
+     */
+    $P.addMinutes = function (value) { 
+        return this.addMilliseconds(value * 60000); /* 60*1000 */
+    };
+
+    /**
+     * Adds the specified number of hours to this instance. 
+     * @param {Number}   The number of hours to add. The number can be positive or negative [Required]
+     * @return {Date}    this
+     */
+    $P.addHours = function (value) { 
+        return this.addMilliseconds(value * 3600000); /* 60*60*1000 */
+    };
+
+    /**
+     * Adds the specified number of days to this instance. 
+     * @param {Number}   The number of days to add. The number can be positive or negative [Required]
+     * @return {Date}    this
+     */
+    $P.addDays = function (value) {
+        this.setDate(this.getDate() + value * 1);
+        return this;
+    };
+
+    /**
+     * Adds the specified number of weeks to this instance. 
+     * @param {Number}   The number of weeks to add. The number can be positive or negative [Required]
+     * @return {Date}    this
+     */
+    $P.addWeeks = function (value) { 
+        return this.addDays(value * 7);
+    };
+
+    /**
+     * Adds the specified number of months to this instance. 
+     * @param {Number}   The number of months to add. The number can be positive or negative [Required]
+     * @return {Date}    this
+     */
+    $P.addMonths = function (value) {
+        var n = this.getDate();
+        this.setDate(1);
+        this.setMonth(this.getMonth() + value * 1);
+        this.setDate(Math.min(n, $D.getDaysInMonth(this.getFullYear(), this.getMonth())));
+        return this;
+    };
+
+    /**
+     * Adds the specified number of years to this instance. 
+     * @param {Number}   The number of years to add. The number can be positive or negative [Required]
+     * @return {Date}    this
+     */
+    $P.addYears = function (value) {
+        return this.addMonths(value * 12);
+    };
+
+    /**
+     * Adds (or subtracts) to the value of the years, months, weeks, days, hours, minutes, seconds, milliseconds of the date instance using given configuration object. Positive and Negative values allowed.
+     * Example
+    <pre><code>
+    Date.today().add( { days: 1, months: 1 } )
+     
+    new Date().add( { years: -1 } )
+    </code></pre> 
+     * @param {Object}   Configuration object containing attributes (months, days, etc.)
+     * @return {Date}    this
+     */
+    $P.add = function (config) {
+        if (typeof config == "number") {
+            this._orient = config;
+            return this;    
+        }
+        
+        var x = config;
+        
+        if (x.milliseconds) { 
+            this.addMilliseconds(x.milliseconds); 
+        }
+        if (x.seconds) { 
+            this.addSeconds(x.seconds); 
+        }
+        if (x.minutes) { 
+            this.addMinutes(x.minutes); 
+        }
+        if (x.hours) { 
+            this.addHours(x.hours); 
+        }
+        if (x.weeks) { 
+            this.addWeeks(x.weeks); 
+        }    
+        if (x.months) { 
+            this.addMonths(x.months); 
+        }
+        if (x.years) { 
+            this.addYears(x.years); 
+        }
+        if (x.days) {
+            this.addDays(x.days); 
+        }
+        return this;
+    };
+    
+    var $y, $m, $d;
+    
+    /**
+     * Get the week number. Week one (1) is the week which contains the first Thursday of the year. Monday is considered the first day of the week.
+     * This algorithm is a JavaScript port of the work presented by Claus Tøndering at http://www.tondering.dk/claus/cal/node8.html#SECTION00880000000000000000
+     * .getWeek() Algorithm Copyright (c) 2008 Claus Tondering.
+     * The .getWeek() function does NOT convert the date to UTC. The local datetime is used. Please use .getISOWeek() to get the week of the UTC converted date.
+     * @return {Number}  1 to 53
+     */
+    $P.getWeek = function () {
+        var a, b, c, d, e, f, g, n, s, w;
+        
+        $y = (!$y) ? this.getFullYear() : $y;
+        $m = (!$m) ? this.getMonth() + 1 : $m;
+        $d = (!$d) ? this.getDate() : $d;
+
+        if ($m <= 2) {
+            a = $y - 1;
+            b = (a / 4 | 0) - (a / 100 | 0) + (a / 400 | 0);
+            c = ((a - 1) / 4 | 0) - ((a - 1) / 100 | 0) + ((a - 1) / 400 | 0);
+            s = b - c;
+            e = 0;
+            f = $d - 1 + (31 * ($m - 1));
+        } else {
+            a = $y;
+            b = (a / 4 | 0) - (a / 100 | 0) + (a / 400 | 0);
+            c = ((a - 1) / 4 | 0) - ((a - 1) / 100 | 0) + ((a - 1) / 400 | 0);
+            s = b - c;
+            e = s + 1;
+            f = $d + ((153 * ($m - 3) + 2) / 5) + 58 + s;
+        }
+        
+        g = (a + b) % 7;
+        d = (f + g - e) % 7;
+        n = (f + 3 - d) | 0;
+
+        if (n < 0) {
+            w = 53 - ((g - s) / 5 | 0);
+        } else if (n > 364 + s) {
+            w = 1;
+        } else {
+            w = (n / 7 | 0) + 1;
+        }
+        
+        $y = $m = $d = null;
+        
+        return w;
+    };
+    
+    /**
+     * Get the ISO 8601 week number. Week one ("01") is the week which contains the first Thursday of the year. Monday is considered the first day of the week.
+     * The .getISOWeek() function does convert the date to it's UTC value. Please use .getWeek() to get the week of the local date.
+     * @return {String}  "01" to "53"
+     */
+    $P.getISOWeek = function () {
+        $y = this.getUTCFullYear();
+        $m = this.getUTCMonth() + 1;
+        $d = this.getUTCDate();
+        return p(this.getWeek());
+    };
+
+    /**
+     * Moves the date to Monday of the week set. Week one (1) is the week which contains the first Thursday of the year.
+     * @param {Number}   A Number (1 to 53) that represents the week of the year.
+     * @return {Date}    this
+     */    
+    $P.setWeek = function (n) {
+        return this.moveToDayOfWeek(1).addWeeks(n - this.getWeek());
+    };
+
+    // private
+    var validate = function (n, min, max, name) {
+        if (typeof n == "undefined") {
+            return false;
+        } else if (typeof n != "number") {
+            throw new TypeError(n + " is not a Number."); 
+        } else if (n < min || n > max) {
+            throw new RangeError(n + " is not a valid value for " + name + "."); 
+        }
+        return true;
+    };
+
+    /**
+     * Validates the number is within an acceptable range for milliseconds [0-999].
+     * @param {Number}   The number to check if within range.
+     * @return {Boolean} true if within range, otherwise false.
+     */
+    $D.validateMillisecond = function (value) {
+        return validate(value, 0, 999, "millisecond");
+    };
+
+    /**
+     * Validates the number is within an acceptable range for seconds [0-59].
+     * @param {Number}   The number to check if within range.
+     * @return {Boolean} true if within range, otherwise false.
+     */
+    $D.validateSecond = function (value) {
+        return validate(value, 0, 59, "second");
+    };
+
+    /**
+     * Validates the number is within an acceptable range for minutes [0-59].
+     * @param {Number}   The number to check if within range.
+     * @return {Boolean} true if within range, otherwise false.
+     */
+    $D.validateMinute = function (value) {
+        return validate(value, 0, 59, "minute");
+    };
+
+    /**
+     * Validates the number is within an acceptable range for hours [0-23].
+     * @param {Number}   The number to check if within range.
+     * @return {Boolean} true if within range, otherwise false.
+     */
+    $D.validateHour = function (value) {
+        return validate(value, 0, 23, "hour");
+    };
+
+    /**
+     * Validates the number is within an acceptable range for the days in a month [0-MaxDaysInMonth].
+     * @param {Number}   The number to check if within range.
+     * @return {Boolean} true if within range, otherwise false.
+     */
+    $D.validateDay = function (value, year, month) {
+        return validate(value, 1, $D.getDaysInMonth(year, month), "day");
+    };
+
+    /**
+     * Validates the number is within an acceptable range for months [0-11].
+     * @param {Number}   The number to check if within range.
+     * @return {Boolean} true if within range, otherwise false.
+     */
+    $D.validateMonth = function (value) {
+        return validate(value, 0, 11, "month");
+    };
+
+    /**
+     * Validates the number is within an acceptable range for years.
+     * @param {Number}   The number to check if within range.
+     * @return {Boolean} true if within range, otherwise false.
+     */
+    $D.validateYear = function (value) {
+        return validate(value, 0, 9999, "year");
+    };
+
+    /**
+     * Set the value of year, month, day, hour, minute, second, millisecond of date instance using given configuration object.
+     * Example
+    <pre><code>
+    Date.today().set( { day: 20, month: 1 } )
+
+    new Date().set( { millisecond: 0 } )
+    </code></pre>
+     * 
+     * @param {Object}   Configuration object containing attributes (month, day, etc.)
+     * @return {Date}    this
+     */
+    $P.set = function (config) {
+        if ($D.validateMillisecond(config.millisecond)) {
+            this.addMilliseconds(config.millisecond - this.getMilliseconds()); 
+        }
+        
+        if ($D.validateSecond(config.second)) {
+            this.addSeconds(config.second - this.getSeconds()); 
+        }
+        
+        if ($D.validateMinute(config.minute)) {
+            this.addMinutes(config.minute - this.getMinutes()); 
+        }
+        
+        if ($D.validateHour(config.hour)) {
+            this.addHours(config.hour - this.getHours()); 
+        }
+        
+        if ($D.validateMonth(config.month)) {
+            this.addMonths(config.month - this.getMonth()); 
+        }
+
+        if ($D.validateYear(config.year)) {
+            this.addYears(config.year - this.getFullYear()); 
+        }
+        
+	    /* day has to go last because you can't validate the day without first knowing the month */
+        if ($D.validateDay(config.day, this.getFullYear(), this.getMonth())) {
+            this.addDays(config.day - this.getDate()); 
+        }
+        
+        if (config.timezone) { 
+            this.setTimezone(config.timezone); 
+        }
+        
+        if (config.timezoneOffset) { 
+            this.setTimezoneOffset(config.timezoneOffset); 
+        }
+
+        if (config.week && validate(config.week, 0, 53, "week")) {
+            this.setWeek(config.week);
+        }
+        
+        return this;   
+    };
+
+    /**
+     * Moves the date to the first day of the month.
+     * @return {Date}    this
+     */
+    $P.moveToFirstDayOfMonth = function () {
+        return this.set({ day: 1 });
+    };
+
+    /**
+     * Moves the date to the last day of the month.
+     * @return {Date}    this
+     */
+    $P.moveToLastDayOfMonth = function () { 
+        return this.set({ day: $D.getDaysInMonth(this.getFullYear(), this.getMonth())});
+    };
+
+    /**
+     * Moves the date to the next n'th occurrence of the dayOfWeek starting from the beginning of the month. The number (-1) is a magic number and will return the last occurrence of the dayOfWeek in the month.
+     * @param {Number}   The dayOfWeek to move to
+     * @param {Number}   The n'th occurrence to move to. Use (-1) to return the last occurrence in the month
+     * @return {Date}    this
+     */
+    $P.moveToNthOccurrence = function (dayOfWeek, occurrence) {
+        var shift = 0;
+        if (occurrence > 0) {
+            shift = occurrence - 1;
+        }
+        else if (occurrence === -1) {
+            this.moveToLastDayOfMonth();
+            if (this.getDay() !== dayOfWeek) {
+                this.moveToDayOfWeek(dayOfWeek, -1);
+            }
+            return this;
+        }
+        return this.moveToFirstDayOfMonth().addDays(-1).moveToDayOfWeek(dayOfWeek, +1).addWeeks(shift);
+    };
+
+    /**
+     * Move to the next or last dayOfWeek based on the orient value.
+     * @param {Number}   The dayOfWeek to move to
+     * @param {Number}   Forward (+1) or Back (-1). Defaults to +1. [Optional]
+     * @return {Date}    this
+     */
+    $P.moveToDayOfWeek = function (dayOfWeek, orient) {
+        var diff = (dayOfWeek - this.getDay() + 7 * (orient || +1)) % 7;
+        return this.addDays((diff === 0) ? diff += 7 * (orient || +1) : diff);
+    };
+
+    /**
+     * Move to the next or last month based on the orient value.
+     * @param {Number}   The month to move to. 0 = January, 11 = December
+     * @param {Number}   Forward (+1) or Back (-1). Defaults to +1. [Optional]
+     * @return {Date}    this
+     */
+    $P.moveToMonth = function (month, orient) {
+        var diff = (month - this.getMonth() + 12 * (orient || +1)) % 12;
+        return this.addMonths((diff === 0) ? diff += 12 * (orient || +1) : diff);
+    };
+
+    /**
+     * Get the Ordinal day (numeric day number) of the year, adjusted for leap year.
+     * @return {Number} 1 through 365 (366 in leap years)
+     */
+    $P.getOrdinalNumber = function () {
+        return Math.ceil((this.clone().clearTime() - new Date(this.getFullYear(), 0, 1)) / 86400000) + 1;
+    };
+
+    /**
+     * Get the time zone abbreviation of the current date.
+     * @return {String} The abbreviated time zone name (e.g. "EST")
+     */
+    $P.getTimezone = function () {
+        return $D.getTimezoneAbbreviation(this.getUTCOffset());
+    };
+
+    $P.setTimezoneOffset = function (offset) {
+        var here = this.getTimezoneOffset(), there = Number(offset) * -6 / 10;
+        return this.addMinutes(there - here); 
+    };
+
+    $P.setTimezone = function (offset) { 
+        return this.setTimezoneOffset($D.getTimezoneOffset(offset)); 
+    };
+
+    /**
+     * Indicates whether Daylight Saving Time is observed in the current time zone.
+     * @return {Boolean} true|false
+     */
+    $P.hasDaylightSavingTime = function () { 
+        return (Date.today().set({month: 0, day: 1}).getTimezoneOffset() !== Date.today().set({month: 6, day: 1}).getTimezoneOffset());
+    };
+    
+    /**
+     * Indicates whether this Date instance is within the Daylight Saving Time range for the current time zone.
+     * @return {Boolean} true|false
+     */
+    $P.isDaylightSavingTime = function () {
+        return Date.today().set({month: 0, day: 1}).getTimezoneOffset() != this.getTimezoneOffset();
+    };
+
+    /**
+     * Get the offset from UTC of the current date.
+     * @return {String} The 4-character offset string prefixed with + or - (e.g. "-0500")
+     */
+    $P.getUTCOffset = function () {
+        var n = this.getTimezoneOffset() * -10 / 6, r;
+        if (n < 0) { 
+            r = (n - 10000).toString(); 
+            return r.charAt(0) + r.substr(2); 
+        } else { 
+            r = (n + 10000).toString();  
+            return "+" + r.substr(1); 
+        }
+    };
+
+    /**
+     * Returns the number of milliseconds between this date and date.
+     * @param {Date} Defaults to now
+     * @return {Number} The diff in milliseconds
+     */
+    $P.getElapsed = function (date) {
+        return (date || new Date()) - this;
+    };
+
+    if (!$P.toISOString) {
+        /**
+         * Converts the current date instance into a string with an ISO 8601 format. The date is converted to it's UTC value.
+         * @return {String}  ISO 8601 string of date
+         */
+        $P.toISOString = function () {
+            // From http://www.json.org/json.js. Public Domain. 
+            function f(n) {
+                return n < 10 ? '0' + n : n;
+            }
+
+            return '"' + this.getUTCFullYear()   + '-' +
+                f(this.getUTCMonth() + 1) + '-' +
+                f(this.getUTCDate())      + 'T' +
+                f(this.getUTCHours())     + ':' +
+                f(this.getUTCMinutes())   + ':' +
+                f(this.getUTCSeconds())   + 'Z"';
+        };
     }
-    return -1;
-};
-
-/**
- * Gets the day number (0-6) if given a CultureInfo specific string which is a valid dayName, abbreviatedDayName or shortestDayName (two char).
- * @param {String}   The name of the day (eg. "Monday, "Mon", "tuesday", "tue", "We", "we").
- * @return {Number}  The day number
- */
-Date.getDayNumberFromName = function (name) {
-    var n = Date.CultureInfo.dayNames, m = Date.CultureInfo.abbreviatedDayNames, o = Date.CultureInfo.shortestDayNames, s = name.toLowerCase();
-    for (var i = 0; i < n.length; i++) { 
-        if (n[i].toLowerCase() == s || m[i].toLowerCase() == s) { 
-            return i; 
-        }
-    }
-    return -1;  
-};
-
-/**
- * Determines if the current date instance is within a LeapYear.
- * @param {Number}   The year (0-9999).
- * @return {Boolean} true if date is within a LeapYear, otherwise false.
- */
-Date.isLeapYear = function (year) { 
-    return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)); 
-};
-
-/**
- * Gets the number of days in the month, given a year and month value. Automatically corrects for LeapYear.
- * @param {Number}   The year (0-9999).
- * @param {Number}   The month (0-11).
- * @return {Number}  The number of days in the month.
- */
-Date.getDaysInMonth = function (year, month) {
-    return [31, (Date.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
-};
-
-Date.getTimezoneOffset = function (s, dst) {
-    return (dst || false) ? Date.CultureInfo.abbreviatedTimeZoneDST[s.toUpperCase()] :
-        Date.CultureInfo.abbreviatedTimeZoneStandard[s.toUpperCase()];
-};
-
-Date.getTimezoneAbbreviation = function (offset, dst) {
-    var n = (dst || false) ? Date.CultureInfo.abbreviatedTimeZoneDST : Date.CultureInfo.abbreviatedTimeZoneStandard, p;
-    for (p in n) { 
-        if (n[p] === offset) { 
-            return p; 
-        }
-    }
-    return null;
-};
-
-/**
- * Returns a new Date object that is an exact date and time copy of the original instance.
- * @return {Date}    A new Date instance
- */
-Date.prototype.clone = function () {
-    return new Date(this.getTime()); 
-};
-
-/**
- * Compares this instance to a Date object and return an number indication of their relative values.  
- * @param {Date}     Date object to compare [Required]
- * @return {Number}  1 = this is greaterthan date. -1 = this is lessthan date. 0 = values are equal
- */
-Date.prototype.compareTo = function (date) {
-    if (isNaN(this)) { 
-        throw new Error(this); 
-    }
-    if (date instanceof Date && !isNaN(date)) {
-        return (this > date) ? 1 : (this < date) ? -1 : 0;
-    } else { 
-        throw new TypeError(date); 
-    }
-};
-
-/**
- * Compares this instance to another Date object and returns true if they are equal.  
- * @param {Date}     Date object to compare [Required]
- * @return {Boolean} true if dates are equal. false if they are not equal.
- */
-Date.prototype.equals = function (date) { 
-    return (this.compareTo(date) === 0); 
-};
-
-/**
- * Determines is this instance is between a range of two dates or equal to either the start or end dates.
- * @param {Date}     Start of range [Required]
- * @param {Date}     End of range [Required]
- * @return {Boolean} true is this is between or equal to the start and end dates, else false
- */
-Date.prototype.between = function (start, end) {
-    var t = this.getTime();
-    return t >= start.getTime() && t <= end.getTime();
-};
-
-/**
- * Adds the specified number of milliseconds to this instance. 
- * @param {Number}   The number of milliseconds to add. The number can be positive or negative [Required]
- * @return {Date}    this
- */
-Date.prototype.addMilliseconds = function (value) {
-    this.setMilliseconds(this.getMilliseconds() + value);
-    return this;
-};
-
-/**
- * Adds the specified number of seconds to this instance. 
- * @param {Number}   The number of seconds to add. The number can be positive or negative [Required]
- * @return {Date}    this
- */
-Date.prototype.addSeconds = function (value) { 
-    return this.addMilliseconds(value * 1000); 
-};
-
-/**
- * Adds the specified number of seconds to this instance. 
- * @param {Number}   The number of seconds to add. The number can be positive or negative [Required]
- * @return {Date}    this
- */
-Date.prototype.addMinutes = function (value) { 
-    return this.addMilliseconds(value * 60000); /* 60*1000 */
-};
-
-/**
- * Adds the specified number of hours to this instance. 
- * @param {Number}   The number of hours to add. The number can be positive or negative [Required]
- * @return {Date}    this
- */
-Date.prototype.addHours = function (value) { 
-    return this.addMilliseconds(value * 3600000); /* 60*60*1000 */
-};
-
-/**
- * Adds the specified number of days to this instance. 
- * @param {Number}   The number of days to add. The number can be positive or negative [Required]
- * @return {Date}    this
- */
-Date.prototype.addDays = function (value) { 
-    return this.addMilliseconds(value * 86400000); /* 60*60*24*1000 */
-};
-
-/**
- * Adds the specified number of weeks to this instance. 
- * @param {Number}   The number of weeks to add. The number can be positive or negative [Required]
- * @return {Date}    this
- */
-Date.prototype.addWeeks = function (value) { 
-    return this.addMilliseconds(value * 604800000); /* 60*60*24*7*1000 */
-};
-
-/**
- * Adds the specified number of months to this instance. 
- * @param {Number}   The number of months to add. The number can be positive or negative [Required]
- * @return {Date}    this
- */
-Date.prototype.addMonths = function (value) {
-    var n = this.getDate();
-    this.setDate(1);
-    this.setMonth(this.getMonth() + value);
-    this.setDate(Math.min(n, this.getDaysInMonth()));
-    return this;
-};
-
-/**
- * Adds the specified number of years to this instance. 
- * @param {Number}   The number of years to add. The number can be positive or negative [Required]
- * @return {Date}    this
- */
-Date.prototype.addYears = function (value) {
-    return this.addMonths(value * 12);
-};
-
-/**
- * Adds (or subtracts) to the value of the year, month, day, hour, minute, second, millisecond of the date instance using given configuration object. Positive and Negative values allowed.
- * Example
-<pre><code>
-Date.today().add( { day: 1, month: 1 } )
- 
-new Date().add( { year: -1 } )
-</code></pre> 
- * @param {Object}   Configuration object containing attributes (month, day, etc.)
- * @return {Date}    this
- */
-Date.prototype.add = function (config) {
-    if (typeof config == "number") {
-        this._orient = config;
-        return this;    
-    }
-    var x = config;
-    if (x.millisecond || x.milliseconds) { 
-        this.addMilliseconds(x.millisecond || x.milliseconds); 
-    }
-    if (x.second || x.seconds) { 
-        this.addSeconds(x.second || x.seconds); 
-    }
-    if (x.minute || x.minutes) { 
-        this.addMinutes(x.minute || x.minutes); 
-    }
-    if (x.hour || x.hours) { 
-        this.addHours(x.hour || x.hours); 
-    }
-    if (x.month || x.months) { 
-        this.addMonths(x.month || x.months); 
-    }
-    if (x.year || x.years) { 
-        this.addYears(x.year || x.years); 
-    }
-    if (x.day || x.days) {
-        this.addDays(x.day || x.days); 
-    }
-    return this;
-};
-
-// private
-Date._validate = function (value, min, max, name) {
-    if (typeof value != "number") {
-        throw new TypeError(value + " is not a Number."); 
-    } else if (value < min || value > max) {
-        throw new RangeError(value + " is not a valid value for " + name + "."); 
-    }
-    return true;
-};
-
-/**
- * Validates the number is within an acceptable range for milliseconds [0-999].
- * @param {Number}   The number to check if within range.
- * @return {Boolean} true if within range, otherwise false.
- */
-Date.validateMillisecond = function (n) {
-    return Date._validate(n, 0, 999, "milliseconds");
-};
-
-/**
- * Validates the number is within an acceptable range for seconds [0-59].
- * @param {Number}   The number to check if within range.
- * @return {Boolean} true if within range, otherwise false.
- */
-Date.validateSecond = function (n) {
-    return Date._validate(n, 0, 59, "seconds");
-};
-
-/**
- * Validates the number is within an acceptable range for minutes [0-59].
- * @param {Number}   The number to check if within range.
- * @return {Boolean} true if within range, otherwise false.
- */
-Date.validateMinute = function (n) {
-    return Date._validate(n, 0, 59, "minutes");
-};
-
-/**
- * Validates the number is within an acceptable range for hours [0-23].
- * @param {Number}   The number to check if within range.
- * @return {Boolean} true if within range, otherwise false.
- */
-Date.validateHour = function (n) {
-    return Date._validate(n, 0, 23, "hours");
-};
-
-/**
- * Validates the number is within an acceptable range for the days in a month [0-MaxDaysInMonth].
- * @param {Number}   The number to check if within range.
- * @return {Boolean} true if within range, otherwise false.
- */
-Date.validateDay = function (n, year, month) {
-    return Date._validate(n, 1, Date.getDaysInMonth(year, month), "days");
-};
-
-/**
- * Validates the number is within an acceptable range for months [0-11].
- * @param {Number}   The number to check if within range.
- * @return {Boolean} true if within range, otherwise false.
- */
-Date.validateMonth = function (n) {
-    return Date._validate(n, 0, 11, "months");
-};
-
-/**
- * Validates the number is within an acceptable range for years [0-9999].
- * @param {Number}   The number to check if within range.
- * @return {Boolean} true if within range, otherwise false.
- */
-Date.validateYear = function (n) {
-    return Date._validate(n, 1, 9999, "seconds");
-};
-
-/**
- * Set the value of year, month, day, hour, minute, second, millisecond of date instance using given configuration object.
- * Example
-<pre><code>
-Date.today().set( { day: 20, month: 1 } )
-
-new Date().set( { millisecond: 0 } )
-</code></pre>
- * 
- * @param {Object}   Configuration object containing attributes (month, day, etc.)
- * @return {Date}    this
- */
-Date.prototype.set = function (config) {
-    var x = config;
-
-    if (!x.millisecond && x.millisecond !== 0) { 
-        x.millisecond = -1; 
-    }
-    if (!x.second && x.second !== 0) { 
-        x.second = -1; 
-    }
-    if (!x.minute && x.minute !== 0) { 
-        x.minute = -1; 
-    }
-    if (!x.hour && x.hour !== 0) { 
-        x.hour = -1; 
-    }
-    if (!x.day && x.day !== 0) { 
-        x.day = -1; 
-    }
-    if (!x.month && x.month !== 0) { 
-        x.month = -1; 
-    }
-    if (!x.year && x.year !== 0) { 
-        x.year = -1; 
-    }
-
-    if (x.millisecond != -1 && Date.validateMillisecond(x.millisecond)) {
-        this.addMilliseconds(x.millisecond - this.getMilliseconds()); 
-    }
-    if (x.second != -1 && Date.validateSecond(x.second)) {
-        this.addSeconds(x.second - this.getSeconds()); 
-    }
-    if (x.minute != -1 && Date.validateMinute(x.minute)) {
-        this.addMinutes(x.minute - this.getMinutes()); 
-    }
-    if (x.hour != -1 && Date.validateHour(x.hour)) {
-        this.addHours(x.hour - this.getHours()); 
-    }
-    if (x.month !== -1 && Date.validateMonth(x.month)) {
-        this.addMonths(x.month - this.getMonth()); 
-    }
-    if (x.year != -1 && Date.validateYear(x.year)) {
-        this.addYears(x.year - this.getFullYear()); 
-    }
-    
-	/* day has to go last because you can't validate the day without first knowing the month */
-    if (x.day != -1 && Date.validateDay(x.day, this.getFullYear(), this.getMonth())) {
-        this.addDays(x.day - this.getDate()); 
-    }
-    if (x.timezone) { 
-        this.setTimezone(x.timezone); 
-    }
-    if (x.timezoneOffset) { 
-        this.setTimezoneOffset(x.timezoneOffset); 
-    }
-    
-    return this;   
-};
-
-/**
- * Resets the time of this Date object to 12:00 AM (00:00), which is the start of the day.
- * @return {Date}    this
- */
-Date.prototype.clearTime = function () {
-    this.setHours(0); 
-    this.setMinutes(0); 
-    this.setSeconds(0);
-    this.setMilliseconds(0); 
-    return this;
-};
-
-/**
- * Determines whether or not this instance is in a leap year.
- * @return {Boolean} true if this instance is in a leap year, else false
- */
-Date.prototype.isLeapYear = function () { 
-    var y = this.getFullYear(); 
-    return (((y % 4 === 0) && (y % 100 !== 0)) || (y % 400 === 0)); 
-};
-
-/**
- * Determines whether or not this instance is a weekday.
- * @return {Boolean} true if this instance is a weekday
- */
-Date.prototype.isWeekday = function () { 
-    return !(this.is().sat() || this.is().sun());
-};
-
-/**
- * Get the number of days in the current month, adjusted for leap year.
- * @return {Number}  The number of days in the month
- */
-Date.prototype.getDaysInMonth = function () { 
-    return Date.getDaysInMonth(this.getFullYear(), this.getMonth());
-};
-
-/**
- * Moves the date to the first day of the month.
- * @return {Date}    this
- */
-Date.prototype.moveToFirstDayOfMonth = function () {
-    return this.set({ day: 1 });
-};
-
-/**
- * Moves the date to the last day of the month.
- * @return {Date}    this
- */
-Date.prototype.moveToLastDayOfMonth = function () { 
-    return this.set({ day: this.getDaysInMonth()});
-};
-
-/**
- * Move to the next or last dayOfWeek based on the orient value.
- * @param {Number}   The dayOfWeek to move to.
- * @param {Number}   Forward (+1) or Back (-1). Defaults to +1. [Optional]
- * @return {Date}    this
- */
-Date.prototype.moveToDayOfWeek = function (day, orient) {
-    var diff = (day - this.getDay() + 7 * (orient || +1)) % 7;
-    return this.addDays((diff === 0) ? diff += 7 * (orient || +1) : diff);
-};
-
-/**
- * Move to the next or last month based on the orient value.
- * @param {Number}   The month to move to. 0 = January, 11 = December.
- * @param {Number}   Forward (+1) or Back (-1). Defaults to +1. [Optional]
- * @return {Date}    this
- */
-Date.prototype.moveToMonth = function (month, orient) {
-    var diff = (month - this.getMonth() + 12 * (orient || +1)) % 12;
-    return this.addMonths((diff === 0) ? diff += 12 * (orient || +1) : diff);
-};
-
-/**
- * Get the numeric day number of the year, adjusted for leap year.
- * @return {Number} 0 through 364 (365 in leap years)
- */
-Date.prototype.getDayOfYear = function () {
-    return Math.floor((this - new Date(this.getFullYear(), 0, 1)) / 86400000);
-};
-
-/**
- * Get the week of the year for the current date instance.
- * @param {Number}   A Number that represents the first day of the week (0-6) [Optional]
- * @return {Number}  0 through 53
- */
-Date.prototype.getWeekOfYear = function (firstDayOfWeek) {
-    var y = this.getFullYear(), m = this.getMonth(), d = this.getDate();
-    
-    var dow = firstDayOfWeek || Date.CultureInfo.firstDayOfWeek;
-	
-    var offset = 7 + 1 - new Date(y, 0, 1).getDay();
-    if (offset == 8) {
-        offset = 1;
-    }
-    var daynum = ((Date.UTC(y, m, d, 0, 0, 0) - Date.UTC(y, 0, 1, 0, 0, 0)) / 86400000) + 1;
-    var w = Math.floor((daynum - offset + 7) / 7);
-    if (w === dow) {
-        y--;
-        var prevOffset = 7 + 1 - new Date(y, 0, 1).getDay();
-        if (prevOffset == 2 || prevOffset == 8) { 
-            w = 53; 
-        } else { 
-            w = 52; 
-        }
-    }
-    return w;
-};
-
-/**
- * Determine whether Daylight Saving Time (DST) is in effect
- * @return {Boolean} True if DST is in effect.
- */
-Date.prototype.isDST = function () {
-    console.log('isDST');
-    /* TODO: not sure if this is portable ... get from Date.CultureInfo? */
-    return this.toString().match(/(E|C|M|P)(S|D)T/)[2] == "D";
-};
-
-/**
- * Get the timezone abbreviation of the current date.
- * @return {String} The abbreviated timezone name (e.g. "EST")
- */
-Date.prototype.getTimezone = function () {
-    return Date.getTimezoneAbbreviation(this.getUTCOffset, this.isDST());
-};
-
-Date.prototype.setTimezoneOffset = function (s) {
-    var here = this.getTimezoneOffset(), there = Number(s) * -6 / 10;
-    this.addMinutes(there - here); 
-    return this;
-};
-
-Date.prototype.setTimezone = function (s) { 
-    return this.setTimezoneOffset(Date.getTimezoneOffset(s)); 
-};
-
-/**
- * Get the offset from UTC of the current date.
- * @return {String} The 4-character offset string prefixed with + or - (e.g. "-0500")
- */
-Date.prototype.getUTCOffset = function () {
-    var n = this.getTimezoneOffset() * -10 / 6, r;
-    if (n < 0) { 
-        r = (n - 10000).toString(); 
-        return r[0] + r.substr(2); 
-    } else { 
-        r = (n + 10000).toString();  
-        return "+" + r.substr(1); 
-    }
-};
-
-/**
- * Gets the name of the day of the week.
- * @param {Boolean}  true to return the abbreviated name of the day of the week
- * @return {String}  The name of the day
- */
-Date.prototype.getDayName = function (abbrev) {
-    return abbrev ? Date.CultureInfo.abbreviatedDayNames[this.getDay()] : 
-        Date.CultureInfo.dayNames[this.getDay()];
-};
-
-/**
- * Gets the month name.
- * @param {Boolean}  true to return the abbreviated name of the month
- * @return {String}  The name of the month
- */
-Date.prototype.getMonthName = function (abbrev) {
-    return abbrev ? Date.CultureInfo.abbreviatedMonthNames[this.getMonth()] : 
-        Date.CultureInfo.monthNames[this.getMonth()];
-};
-
-// private
-Date.prototype._toString = Date.prototype.toString;
-
-/**
- * Converts the value of the current Date object to its equivalent string representation.
- * Format Specifiers
-<pre>
-Format  Description                                                                  Example
-------  ---------------------------------------------------------------------------  -----------------------
- s      The seconds of the minute between 1-59.                                      "1" to "59"
- ss     The seconds of the minute with leading zero if required.                     "01" to "59"
- 
- m      The minute of the hour between 0-59.                                         "1"  or "59"
- mm     The minute of the hour with leading zero if required.                        "01" or "59"
- 
- h      The hour of the day between 1-12.                                            "1"  to "12"
- hh     The hour of the day with leading zero if required.                           "01" to "12"
- 
- H      The hour of the day between 1-23.                                            "1"  to "23"
- HH     The hour of the day with leading zero if required.                           "01" to "23"
- 
- d      The day of the month between 1 and 31.                                       "1"  to "31"
- dd     The day of the month with leading zero if required.                          "01" to "31"
- ddd    Abbreviated day name. Date.CultureInfo.abbreviatedDayNames.                  "Mon" to "Sun" 
- dddd   The full day name. Date.CultureInfo.dayNames.                                "Monday" to "Sunday"
- 
- M      The month of the year between 1-12.                                          "1" to "12"
- MM     The month of the year with leading zero if required.                         "01" to "12"
- MMM    Abbreviated month name. Date.CultureInfo.abbreviatedMonthNames.              "Jan" to "Dec"
- MMMM   The full month name. Date.CultureInfo.monthNames.                            "January" to "December"
-
- yy     Displays the year as a maximum two-digit number.                             "99" or "07"
- yyyy   Displays the full four digit year.                                           "1999" or "2007"
- 
- t      Displays the first character of the A.M./P.M. designator.                    "A" or "P"
-        Date.CultureInfo.amDesignator or Date.CultureInfo.pmDesignator
- tt     Displays the A.M./P.M. designator.                                           "AM" or "PM"
-        Date.CultureInfo.amDesignator or Date.CultureInfo.pmDesignator
-</pre>
- * @param {String}   A format string consisting of one or more format spcifiers [Optional].
- * @return {String}  A string representation of the current Date object.
- */
-Date.prototype.toString = function (format) {
-    var self = this;
-
-    var p = function p(s) {
-        return (s.toString().length == 1) ? "0" + s : s;
-    };
-
-    return format ? format.replace(/dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?/g, 
-    function (format) {
-        switch (format) {
-        case "hh":
-            return p(self.getHours() < 13 ? self.getHours() : (self.getHours() - 12));
-        case "h":
-            return self.getHours() < 13 ? self.getHours() : (self.getHours() - 12);
-        case "HH":
-            return p(self.getHours());
-        case "H":
-            return self.getHours();
-        case "mm":
-            return p(self.getMinutes());
-        case "m":
-            return self.getMinutes();
-        case "ss":
-            return p(self.getSeconds());
-        case "s":
-            return self.getSeconds();
-        case "yyyy":
-            return self.getFullYear();
-        case "yy":
-            return self.getFullYear().toString().substring(2, 4);
-        case "dddd":
-            return self.getDayName();
-        case "ddd":
-            return self.getDayName(true);
-        case "dd":
-            return p(self.getDate());
-        case "d":
-            return self.getDate().toString();
-        case "MMMM":
-            return self.getMonthName();
-        case "MMM":
-            return self.getMonthName(true);
-        case "MM":
-            return p((self.getMonth() + 1));
-        case "M":
-            return self.getMonth() + 1;
-        case "t":
-            return self.getHours() < 12 ? Date.CultureInfo.amDesignator.substring(0, 1) : Date.CultureInfo.pmDesignator.substring(0, 1);
-        case "tt":
-            return self.getHours() < 12 ? Date.CultureInfo.amDesignator : Date.CultureInfo.pmDesignator;
-        case "zzz":
-        case "zz":
-        case "z":
-            return "";
-        }
-    }
-    ) : this._toString();
-};
+    
+    // private
+    $P._toString = $P.toString;
+
+    /**
+     * Converts the value of the current Date object to its equivalent string representation.
+     * Format Specifiers
+    <pre>
+    CUSTOM DATE AND TIME FORMAT STRINGS
+    Format  Description                                                                  Example
+    ------  ---------------------------------------------------------------------------  -----------------------
+     s      The seconds of the minute between 0-59.                                      "0" to "59"
+     ss     The seconds of the minute with leading zero if required.                     "00" to "59"
+     
+     m      The minute of the hour between 0-59.                                         "0"  or "59"
+     mm     The minute of the hour with leading zero if required.                        "00" or "59"
+     
+     h      The hour of the day between 1-12.                                            "1"  to "12"
+     hh     The hour of the day with leading zero if required.                           "01" to "12"
+     
+     H      The hour of the day between 0-23.                                            "0"  to "23"
+     HH     The hour of the day with leading zero if required.                           "00" to "23"
+     
+     d      The day of the month between 1 and 31.                                       "1"  to "31"
+     dd     The day of the month with leading zero if required.                          "01" to "31"
+     ddd    Abbreviated day name. $C.abbreviatedDayNames.                                "Mon" to "Sun" 
+     dddd   The full day name. $C.dayNames.                                              "Monday" to "Sunday"
+     
+     M      The month of the year between 1-12.                                          "1" to "12"
+     MM     The month of the year with leading zero if required.                         "01" to "12"
+     MMM    Abbreviated month name. $C.abbreviatedMonthNames.                            "Jan" to "Dec"
+     MMMM   The full month name. $C.monthNames.                                          "January" to "December"
+
+     yy     The year as a two-digit number.                                              "99" or "08"
+     yyyy   The full four digit year.                                                    "1999" or "2008"
+     
+     t      Displays the first character of the A.M./P.M. designator.                    "A" or "P"
+            $C.amDesignator or $C.pmDesignator
+     tt     Displays the A.M./P.M. designator.                                           "AM" or "PM"
+            $C.amDesignator or $C.pmDesignator
+     
+     S      The ordinal suffix ("st, "nd", "rd" or "th") of the current day.            "st, "nd", "rd" or "th"
+
+|| *Format* || *Description* || *Example* ||
+|| d      || The CultureInfo shortDate Format Pattern                                     || "M/d/yyyy" ||
+|| D      || The CultureInfo longDate Format Pattern                                      || "dddd, MMMM dd, yyyy" ||
+|| F      || The CultureInfo fullDateTime Format Pattern                                  || "dddd, MMMM dd, yyyy h:mm:ss tt" ||
+|| m      || The CultureInfo monthDay Format Pattern                                      || "MMMM dd" ||
+|| r      || The CultureInfo rfc1123 Format Pattern                                       || "ddd, dd MMM yyyy HH:mm:ss GMT" ||
+|| s      || The CultureInfo sortableDateTime Format Pattern                              || "yyyy-MM-ddTHH:mm:ss" ||
+|| t      || The CultureInfo shortTime Format Pattern                                     || "h:mm tt" ||
+|| T      || The CultureInfo longTime Format Pattern                                      || "h:mm:ss tt" ||
+|| u      || The CultureInfo universalSortableDateTime Format Pattern                     || "yyyy-MM-dd HH:mm:ssZ" ||
+|| y      || The CultureInfo yearMonth Format Pattern                                     || "MMMM, yyyy" ||
+     
+
+    STANDARD DATE AND TIME FORMAT STRINGS
+    Format  Description                                                                  Example ("en-US")
+    ------  ---------------------------------------------------------------------------  -----------------------
+     d      The CultureInfo shortDate Format Pattern                                     "M/d/yyyy"
+     D      The CultureInfo longDate Format Pattern                                      "dddd, MMMM dd, yyyy"
+     F      The CultureInfo fullDateTime Format Pattern                                  "dddd, MMMM dd, yyyy h:mm:ss tt"
+     m      The CultureInfo monthDay Format Pattern                                      "MMMM dd"
+     r      The CultureInfo rfc1123 Format Pattern                                       "ddd, dd MMM yyyy HH:mm:ss GMT"
+     s      The CultureInfo sortableDateTime Format Pattern                              "yyyy-MM-ddTHH:mm:ss"
+     t      The CultureInfo shortTime Format Pattern                                     "h:mm tt"
+     T      The CultureInfo longTime Format Pattern                                      "h:mm:ss tt"
+     u      The CultureInfo universalSortableDateTime Format Pattern                     "yyyy-MM-dd HH:mm:ssZ"
+     y      The CultureInfo yearMonth Format Pattern                                     "MMMM, yyyy"
+    </pre>
+     * @param {String}   A format string consisting of one or more format spcifiers [Optional].
+     * @return {String}  A string representation of the current Date object.
+     */
+    $P.toString = function (format) {
+        var x = this;
+        
+        // Standard Date and Time Format Strings. Formats pulled from CultureInfo file and
+        // may vary by culture. 
+        if (format && format.length == 1) {
+            var c = $C.formatPatterns;
+            x.t = x.toString;
+            switch (format) {
+            case "d": 
+                return x.t(c.shortDate);
+            case "D":
+                return x.t(c.longDate);
+            case "F":
+                return x.t(c.fullDateTime);
+            case "m":
+                return x.t(c.monthDay);
+            case "r":
+                return x.t(c.rfc1123);
+            case "s":
+                return x.t(c.sortableDateTime);
+            case "t":
+                return x.t(c.shortTime);
+            case "T":
+                return x.t(c.longTime);
+            case "u":
+                return x.t(c.universalSortableDateTime);
+            case "y":
+                return x.t(c.yearMonth);
+            }    
+        }
+        
+        var ord = function (n) {
+                switch (n * 1) {
+                case 1: 
+                case 21: 
+                case 31: 
+                    return "st";
+                case 2: 
+                case 22: 
+                    return "nd";
+                case 3: 
+                case 23: 
+                    return "rd";
+                default: 
+                    return "th";
+                }
+            };
+        
+        return format ? format.replace(/(\\)?(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|S)/g, 
+        function (m) {
+            if (m.charAt(0) === "\\") {
+                return m.replace("\\", "");
+            }
+            x.h = x.getHours;
+            switch (m) {
+            case "hh":
+                return p(x.h() < 13 ? (x.h() === 0 ? 12 : x.h()) : (x.h() - 12));
+            case "h":
+                return x.h() < 13 ? (x.h() === 0 ? 12 : x.h()) : (x.h() - 12);
+            case "HH":
+                return p(x.h());
+            case "H":
+                return x.h();
+            case "mm":
+                return p(x.getMinutes());
+            case "m":
+                return x.getMinutes();
+            case "ss":
+                return p(x.getSeconds());
+            case "s":
+                return x.getSeconds();
+            case "yyyy":
+                return p(x.getFullYear(), 4);
+            case "yy":
+                return p(x.getFullYear());
+            case "dddd":
+                return $C.dayNames[x.getDay()];
+            case "ddd":
+                return $C.abbreviatedDayNames[x.getDay()];
+            case "dd":
+                return p(x.getDate());
+            case "d":
+                return x.getDate();
+            case "MMMM":
+                return $C.monthNames[x.getMonth()];
+            case "MMM":
+                return $C.abbreviatedMonthNames[x.getMonth()];
+            case "MM":
+                return p((x.getMonth() + 1));
+            case "M":
+                return x.getMonth() + 1;
+            case "t":
+                return x.h() < 12 ? $C.amDesignator.substring(0, 1) : $C.pmDesignator.substring(0, 1);
+            case "tt":
+                return x.h() < 12 ? $C.amDesignator : $C.pmDesignator;
+            case "S":
+                return ord(x.getDate());
+            default: 
+                return m;
+            }
+        }
+        ) : this._toString();
+    };
+}());    
Index: /trunk/prototype/plugins/datejs/parser.js
===================================================================
--- /trunk/prototype/plugins/datejs/parser.js	(revision 5341)
+++ /trunk/prototype/plugins/datejs/parser.js	(revision 7143)
@@ -1,8 +1,9 @@
 /**
- * Version: 1.0 Alpha-1 
- * Build Date: 13-Nov-2007
- * Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
- * License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
- * Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
+ * @version: 1.0 Alpha-1
+ * @author: Coolite Inc. http://www.coolite.com/
+ * @date: 2008-05-13
+ * @copyright: Copyright (c) 2006-2008, Coolite Inc. (http://www.coolite.com/). All rights reserved.
+ * @license: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
+ * @website: http://www.datejs.com/
  */
 (function(){Date.Parsing={Exception:function(s){this.message="Parse error at '"+s.substring(0,10)+" ...'";}};var $P=Date.Parsing;var _=$P.Operators={rtoken:function(r){return function(s){var mx=s.match(r);if(mx){return([mx[0],s.substring(mx[0].length)]);}else{throw new $P.Exception(s);}};},token:function(s){return function(s){return _.rtoken(new RegExp("^\s*"+s+"\s*"))(s);};},stoken:function(s){return _.rtoken(new RegExp("^"+s));},until:function(p){return function(s){var qx=[],rx=null;while(s.length){try{rx=p.call(this,s);}catch(e){qx.push(rx[0]);s=rx[1];continue;}
@@ -40,26 +41,44 @@
 return rx;};}};var _generator=function(op){return function(){var args=null,rx=[];if(arguments.length>1){args=Array.prototype.slice.call(arguments);}else if(arguments[0]instanceof Array){args=arguments[0];}
 if(args){for(var i=0,px=args.shift();i<px.length;i++){args.unshift(px[i]);rx.push(op.apply(null,args));args.shift();return rx;}}else{return op.apply(null,arguments);}};};var gx="optional not ignore cache".split(/\s/);for(var i=0;i<gx.length;i++){_[gx[i]]=_generator(_[gx[i]]);}
-var _vector=function(op){return function(){if(arguments[0]instanceof Array){return op.apply(null,arguments[0]);}else{return op.apply(null,arguments);}};};var vx="each any all".split(/\s/);for(var j=0;j<vx.length;j++){_[vx[j]]=_vector(_[vx[j]]);}}());(function(){var flattenAndCompact=function(ax){var rx=[];for(var i=0;i<ax.length;i++){if(ax[i]instanceof Array){rx=rx.concat(flattenAndCompact(ax[i]));}else{if(ax[i]){rx.push(ax[i]);}}}
-return rx;};Date.Grammar={};Date.Translator={hour:function(s){return function(){this.hour=Number(s);};},minute:function(s){return function(){this.minute=Number(s);};},second:function(s){return function(){this.second=Number(s);};},meridian:function(s){return function(){this.meridian=s.slice(0,1).toLowerCase();};},timezone:function(s){return function(){var n=s.replace(/[^\d\+\-]/g,"");if(n.length){this.timezoneOffset=Number(n);}else{this.timezone=s.toLowerCase();}};},day:function(x){var s=x[0];return function(){this.day=Number(s.match(/\d+/)[0]);};},month:function(s){return function(){this.month=((s.length==3)?Date.getMonthNumberFromName(s):(Number(s)-1));};},year:function(s){return function(){var n=Number(s);this.year=((s.length>2)?n:(n+(((n+2000)<Date.CultureInfo.twoDigitYearMax)?2000:1900)));};},rday:function(s){return function(){switch(s){case"yesterday":this.days=-1;break;case"tomorrow":this.days=1;break;case"today":this.days=0;break;case"now":this.days=0;this.now=true;break;}};},finishExact:function(x){x=(x instanceof Array)?x:[x];var now=new Date();this.year=now.getFullYear();this.month=now.getMonth();this.day=1;this.hour=0;this.minute=0;this.second=0;for(var i=0;i<x.length;i++){if(x[i]){x[i].call(this);}}
-this.hour=(this.meridian=="p"&&this.hour<13)?this.hour+12:this.hour;if(this.day>Date.getDaysInMonth(this.year,this.month)){throw new RangeError(this.day+" is not a valid value for days.");}
+var _vector=function(op){return function(){if(arguments[0]instanceof Array){return op.apply(null,arguments[0]);}else{return op.apply(null,arguments);}};};var vx="each any all".split(/\s/);for(var j=0;j<vx.length;j++){_[vx[j]]=_vector(_[vx[j]]);}}());(function(){var $D=Date,$P=$D.prototype,$C=$D.CultureInfo;var flattenAndCompact=function(ax){var rx=[];for(var i=0;i<ax.length;i++){if(ax[i]instanceof Array){rx=rx.concat(flattenAndCompact(ax[i]));}else{if(ax[i]){rx.push(ax[i]);}}}
+return rx;};$D.Grammar={};$D.Translator={hour:function(s){return function(){this.hour=Number(s);};},minute:function(s){return function(){this.minute=Number(s);};},second:function(s){return function(){this.second=Number(s);};},meridian:function(s){return function(){this.meridian=s.slice(0,1).toLowerCase();};},timezone:function(s){return function(){var n=s.replace(/[^\d\+\-]/g,"");if(n.length){this.timezoneOffset=Number(n);}else{this.timezone=s.toLowerCase();}};},day:function(x){var s=x[0];return function(){this.day=Number(s.match(/\d+/)[0]);};},month:function(s){return function(){this.month=(s.length==3)?"jan feb mar apr may jun jul aug sep oct nov dec".indexOf(s)/4:Number(s)-1;};},year:function(s){return function(){var n=Number(s);this.year=((s.length>2)?n:(n+(((n+2000)<$C.twoDigitYearMax)?2000:1900)));};},rday:function(s){return function(){switch(s){case"yesterday":this.days=-1;break;case"tomorrow":this.days=1;break;case"today":this.days=0;break;case"now":this.days=0;this.now=true;break;}};},finishExact:function(x){x=(x instanceof Array)?x:[x];for(var i=0;i<x.length;i++){if(x[i]){x[i].call(this);}}
+var now=new Date();if((this.hour||this.minute)&&(!this.month&&!this.year&&!this.day)){this.day=now.getDate();}
+if(!this.year){this.year=now.getFullYear();}
+if(!this.month&&this.month!==0){this.month=now.getMonth();}
+if(!this.day){this.day=1;}
+if(!this.hour){this.hour=0;}
+if(!this.minute){this.minute=0;}
+if(!this.second){this.second=0;}
+if(this.meridian&&this.hour){if(this.meridian=="p"&&this.hour<12){this.hour=this.hour+12;}else if(this.meridian=="a"&&this.hour==12){this.hour=0;}}
+if(this.day>$D.getDaysInMonth(this.year,this.month)){throw new RangeError(this.day+" is not a valid value for days.");}
 var r=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second);if(this.timezone){r.set({timezone:this.timezone});}else if(this.timezoneOffset){r.set({timezoneOffset:this.timezoneOffset});}
 return r;},finish:function(x){x=(x instanceof Array)?flattenAndCompact(x):[x];if(x.length===0){return null;}
 for(var i=0;i<x.length;i++){if(typeof x[i]=="function"){x[i].call(this);}}
-if(this.now){return new Date();}
-var today=Date.today();var method=null;var expression=!!(this.days!=null||this.orient||this.operator);if(expression){var gap,mod,orient;orient=((this.orient=="past"||this.operator=="subtract")?-1:1);if(this.weekday){this.unit="day";gap=(Date.getDayNumberFromName(this.weekday)-today.getDay());mod=7;this.days=gap?((gap+(orient*mod))%mod):(orient*mod);}
-if(this.month){this.unit="month";gap=(this.month-today.getMonth());mod=12;this.months=gap?((gap+(orient*mod))%mod):(orient*mod);this.month=null;}
+var today=$D.today();if(this.now&&!this.unit&&!this.operator){return new Date();}else if(this.now){today=new Date();}
+var expression=!!(this.days&&this.days!==null||this.orient||this.operator);var gap,mod,orient;orient=((this.orient=="past"||this.operator=="subtract")?-1:1);if(!this.now&&"hour minute second".indexOf(this.unit)!=-1){today.setTimeToNow();}
+if(this.month||this.month===0){if("year day hour minute second".indexOf(this.unit)!=-1){this.value=this.month+1;this.month=null;expression=true;}}
+if(!expression&&this.weekday&&!this.day&&!this.days){var temp=Date[this.weekday]();this.day=temp.getDate();if(!this.month){this.month=temp.getMonth();}
+this.year=temp.getFullYear();}
+if(expression&&this.weekday&&this.unit!="month"){this.unit="day";gap=($D.getDayNumberFromName(this.weekday)-today.getDay());mod=7;this.days=gap?((gap+(orient*mod))%mod):(orient*mod);}
+if(this.month&&this.unit=="day"&&this.operator){this.value=(this.month+1);this.month=null;}
+if(this.value!=null&&this.month!=null&&this.year!=null){this.day=this.value*1;}
+if(this.month&&!this.day&&this.value){today.set({day:this.value*1});if(!expression){this.day=this.value*1;}}
+if(!this.month&&this.value&&this.unit=="month"&&!this.now){this.month=this.value;expression=true;}
+if(expression&&(this.month||this.month===0)&&this.unit!="year"){this.unit="month";gap=(this.month-today.getMonth());mod=12;this.months=gap?((gap+(orient*mod))%mod):(orient*mod);this.month=null;}
 if(!this.unit){this.unit="day";}
-if(this[this.unit+"s"]==null||this.operator!=null){if(!this.value){this.value=1;}
-if(this.unit=="week"){this.unit="day";this.value=this.value*7;}
+if(!this.value&&this.operator&&this.operator!==null&&this[this.unit+"s"]&&this[this.unit+"s"]!==null){this[this.unit+"s"]=this[this.unit+"s"]+((this.operator=="add")?1:-1)+(this.value||0)*orient;}else if(this[this.unit+"s"]==null||this.operator!=null){if(!this.value){this.value=1;}
 this[this.unit+"s"]=this.value*orient;}
-return today.add(this);}else{if(this.meridian&&this.hour){this.hour=(this.hour<13&&this.meridian=="p")?this.hour+12:this.hour;}
-if(this.weekday&&!this.day){this.day=(today.addDays((Date.getDayNumberFromName(this.weekday)-today.getDay()))).getDate();}
-if(this.month&&!this.day){this.day=1;}
-return today.set(this);}}};var _=Date.Parsing.Operators,g=Date.Grammar,t=Date.Translator,_fn;g.datePartDelimiter=_.rtoken(/^([\s\-\.\,\/\x27]+)/);g.timePartDelimiter=_.stoken(":");g.whiteSpace=_.rtoken(/^\s*/);g.generalDelimiter=_.rtoken(/^(([\s\,]|at|on)+)/);var _C={};g.ctoken=function(keys){var fn=_C[keys];if(!fn){var c=Date.CultureInfo.regexPatterns;var kx=keys.split(/\s+/),px=[];for(var i=0;i<kx.length;i++){px.push(_.replace(_.rtoken(c[kx[i]]),kx[i]));}
+if(this.meridian&&this.hour){if(this.meridian=="p"&&this.hour<12){this.hour=this.hour+12;}else if(this.meridian=="a"&&this.hour==12){this.hour=0;}}
+if(this.weekday&&!this.day&&!this.days){var temp=Date[this.weekday]();this.day=temp.getDate();if(temp.getMonth()!==today.getMonth()){this.month=temp.getMonth();}}
+if((this.month||this.month===0)&&!this.day){this.day=1;}
+if(!this.orient&&!this.operator&&this.unit=="week"&&this.value&&!this.day&&!this.month){return Date.today().setWeek(this.value);}
+if(expression&&this.timezone&&this.day&&this.days){this.day=this.days;}
+return(expression)?today.add(this):today.set(this);}};var _=$D.Parsing.Operators,g=$D.Grammar,t=$D.Translator,_fn;g.datePartDelimiter=_.rtoken(/^([\s\-\.\,\/\x27]+)/);g.timePartDelimiter=_.stoken(":");g.whiteSpace=_.rtoken(/^\s*/);g.generalDelimiter=_.rtoken(/^(([\s\,]|at|@|on)+)/);var _C={};g.ctoken=function(keys){var fn=_C[keys];if(!fn){var c=$C.regexPatterns;var kx=keys.split(/\s+/),px=[];for(var i=0;i<kx.length;i++){px.push(_.replace(_.rtoken(c[kx[i]]),kx[i]));}
 fn=_C[keys]=_.any.apply(null,px);}
-return fn;};g.ctoken2=function(key){return _.rtoken(Date.CultureInfo.regexPatterns[key]);};g.h=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2]|[1-9])/),t.hour));g.hh=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2])/),t.hour));g.H=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/),t.hour));g.HH=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3])/),t.hour));g.m=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.minute));g.mm=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.minute));g.s=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.second));g.ss=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.second));g.hms=_.cache(_.sequence([g.H,g.mm,g.ss],g.timePartDelimiter));g.t=_.cache(_.process(g.ctoken2("shortMeridian"),t.meridian));g.tt=_.cache(_.process(g.ctoken2("longMeridian"),t.meridian));g.z=_.cache(_.process(_.rtoken(/^(\+|\-)?\s*\d\d\d\d?/),t.timezone));g.zz=_.cache(_.process(_.rtoken(/^(\+|\-)\s*\d\d\d\d/),t.timezone));g.zzz=_.cache(_.process(g.ctoken2("timezone"),t.timezone));g.timeSuffix=_.each(_.ignore(g.whiteSpace),_.set([g.tt,g.zzz]));g.time=_.each(_.optional(_.ignore(_.stoken("T"))),g.hms,g.timeSuffix);g.d=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.dd=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.ddd=g.dddd=_.cache(_.process(g.ctoken("sun mon tue wed thu fri sat"),function(s){return function(){this.weekday=s;};}));g.M=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d|\d)/),t.month));g.MM=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d)/),t.month));g.MMM=g.MMMM=_.cache(_.process(g.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"),t.month));g.y=_.cache(_.process(_.rtoken(/^(\d\d?)/),t.year));g.yy=_.cache(_.process(_.rtoken(/^(\d\d)/),t.year));g.yyy=_.cache(_.process(_.rtoken(/^(\d\d?\d?\d?)/),t.year));g.yyyy=_.cache(_.process(_.rtoken(/^(\d\d\d\d)/),t.year));_fn=function(){return _.each(_.any.apply(null,arguments),_.not(g.ctoken2("timeContext")));};g.day=_fn(g.d,g.dd);g.month=_fn(g.M,g.MMM);g.year=_fn(g.yyyy,g.yy);g.orientation=_.process(g.ctoken("past future"),function(s){return function(){this.orient=s;};});g.operator=_.process(g.ctoken("add subtract"),function(s){return function(){this.operator=s;};});g.rday=_.process(g.ctoken("yesterday tomorrow today now"),t.rday);g.unit=_.process(g.ctoken("minute hour day week month year"),function(s){return function(){this.unit=s;};});g.value=_.process(_.rtoken(/^\d\d?(st|nd|rd|th)?/),function(s){return function(){this.value=s.replace(/\D/g,"");};});g.expression=_.set([g.rday,g.operator,g.value,g.unit,g.orientation,g.ddd,g.MMM]);_fn=function(){return _.set(arguments,g.datePartDelimiter);};g.mdy=_fn(g.ddd,g.month,g.day,g.year);g.ymd=_fn(g.ddd,g.year,g.month,g.day);g.dmy=_fn(g.ddd,g.day,g.month,g.year);g.date=function(s){return((g[Date.CultureInfo.dateElementOrder]||g.mdy).call(this,s));};g.format=_.process(_.many(_.any(_.process(_.rtoken(/^(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/),function(fmt){if(g[fmt]){return g[fmt];}else{throw Date.Parsing.Exception(fmt);}}),_.process(_.rtoken(/^[^dMyhHmstz]+/),function(s){return _.ignore(_.stoken(s));}))),function(rules){return _.process(_.each.apply(null,rules),t.finishExact);});var _F={};var _get=function(f){return _F[f]=(_F[f]||g.format(f)[0]);};g.formats=function(fx){if(fx instanceof Array){var rx=[];for(var i=0;i<fx.length;i++){rx.push(_get(fx[i]));}
-return _.any.apply(null,rx);}else{return _get(fx);}};g._formats=g.formats(["yyyy-MM-ddTHH:mm:ss","ddd, MMM dd, yyyy H:mm:ss tt","ddd MMM d yyyy HH:mm:ss zzz","d"]);g._start=_.process(_.set([g.date,g.time,g.expression],g.generalDelimiter,g.whiteSpace),t.finish);g.start=function(s){try{var r=g._formats.call({},s);if(r[1].length===0){return r;}}catch(e){}
-return g._start.call({},s);};}());Date._parse=Date.parse;Date.parse=function(s){var r=null;if(!s){return null;}
-try{r=Date.Grammar.start.call({},s);}catch(e){return null;}
-return((r[1].length===0)?r[0]:null);};Date.getParseFunction=function(fx){var fn=Date.Grammar.formats(fx);return function(s){var r=null;try{r=fn.call({},s);}catch(e){return null;}
-return((r[1].length===0)?r[0]:null);};};Date.parseExact=function(s,fx){return Date.getParseFunction(fx)(s);};
+return fn;};g.ctoken2=function(key){return _.rtoken($C.regexPatterns[key]);};g.h=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2]|[1-9])/),t.hour));g.hh=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2])/),t.hour));g.H=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/),t.hour));g.HH=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3])/),t.hour));g.m=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.minute));g.mm=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.minute));g.s=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.second));g.ss=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.second));g.hms=_.cache(_.sequence([g.H,g.m,g.s],g.timePartDelimiter));g.t=_.cache(_.process(g.ctoken2("shortMeridian"),t.meridian));g.tt=_.cache(_.process(g.ctoken2("longMeridian"),t.meridian));g.z=_.cache(_.process(_.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/),t.timezone));g.zz=_.cache(_.process(_.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/),t.timezone));g.zzz=_.cache(_.process(g.ctoken2("timezone"),t.timezone));g.timeSuffix=_.each(_.ignore(g.whiteSpace),_.set([g.tt,g.zzz]));g.time=_.each(_.optional(_.ignore(_.stoken("T"))),g.hms,g.timeSuffix);g.d=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.dd=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.ddd=g.dddd=_.cache(_.process(g.ctoken("sun mon tue wed thu fri sat"),function(s){return function(){this.weekday=s;};}));g.M=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d|\d)/),t.month));g.MM=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d)/),t.month));g.MMM=g.MMMM=_.cache(_.process(g.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"),t.month));g.y=_.cache(_.process(_.rtoken(/^(\d\d?)/),t.year));g.yy=_.cache(_.process(_.rtoken(/^(\d\d)/),t.year));g.yyy=_.cache(_.process(_.rtoken(/^(\d\d?\d?\d?)/),t.year));g.yyyy=_.cache(_.process(_.rtoken(/^(\d\d\d\d)/),t.year));_fn=function(){return _.each(_.any.apply(null,arguments),_.not(g.ctoken2("timeContext")));};g.day=_fn(g.d,g.dd);g.month=_fn(g.M,g.MMM);g.year=_fn(g.yyyy,g.yy);g.orientation=_.process(g.ctoken("past future"),function(s){return function(){this.orient=s;};});g.operator=_.process(g.ctoken("add subtract"),function(s){return function(){this.operator=s;};});g.rday=_.process(g.ctoken("yesterday tomorrow today now"),t.rday);g.unit=_.process(g.ctoken("second minute hour day week month year"),function(s){return function(){this.unit=s;};});g.value=_.process(_.rtoken(/^\d\d?(st|nd|rd|th)?/),function(s){return function(){this.value=s.replace(/\D/g,"");};});g.expression=_.set([g.rday,g.operator,g.value,g.unit,g.orientation,g.ddd,g.MMM]);_fn=function(){return _.set(arguments,g.datePartDelimiter);};g.mdy=_fn(g.ddd,g.month,g.day,g.year);g.ymd=_fn(g.ddd,g.year,g.month,g.day);g.dmy=_fn(g.ddd,g.day,g.month,g.year);g.date=function(s){return((g[$C.dateElementOrder]||g.mdy).call(this,s));};g.format=_.process(_.many(_.any(_.process(_.rtoken(/^(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/),function(fmt){if(g[fmt]){return g[fmt];}else{throw $D.Parsing.Exception(fmt);}}),_.process(_.rtoken(/^[^dMyhHmstz]+/),function(s){return _.ignore(_.stoken(s));}))),function(rules){return _.process(_.each.apply(null,rules),t.finishExact);});var _F={};var _get=function(f){return _F[f]=(_F[f]||g.format(f)[0]);};g.formats=function(fx){if(fx instanceof Array){var rx=[];for(var i=0;i<fx.length;i++){rx.push(_get(fx[i]));}
+return _.any.apply(null,rx);}else{return _get(fx);}};g._formats=g.formats(["\"yyyy-MM-ddTHH:mm:ssZ\"","yyyy-MM-ddTHH:mm:ssZ","yyyy-MM-ddTHH:mm:ssz","yyyy-MM-ddTHH:mm:ss","yyyy-MM-ddTHH:mmZ","yyyy-MM-ddTHH:mmz","yyyy-MM-ddTHH:mm","ddd, MMM dd, yyyy H:mm:ss tt","ddd MMM d yyyy HH:mm:ss zzz","MMddyyyy","ddMMyyyy","Mddyyyy","ddMyyyy","Mdyyyy","dMyyyy","yyyy","Mdyy","dMyy","d"]);g._start=_.process(_.set([g.date,g.time,g.expression],g.generalDelimiter,g.whiteSpace),t.finish);g.start=function(s){try{var r=g._formats.call({},s);if(r[1].length===0){return r;}}catch(e){}
+return g._start.call({},s);};$D._parse=$D.parse;$D.parse=function(s){var r=null;if(!s){return null;}
+if(s instanceof Date){return s;}
+try{r=$D.Grammar.start.call({},s.replace(/^\s*(\S*(\s+\S+)*)\s*$/,"$1"));}catch(e){return null;}
+return((r[1].length===0)?r[0]:null);};$D.getParseFunction=function(fx){var fn=$D.Grammar.formats(fx);return function(s){var r=null;try{r=fn.call({},s);}catch(e){return null;}
+return((r[1].length===0)?r[0]:null);};};$D.parseExact=function(s,fx){return $D.getParseFunction(fx)(s);};}());
Index: /trunk/prototype/plugins/datejs/date.js
===================================================================
--- /trunk/prototype/plugins/datejs/date.js	(revision 5341)
+++ /trunk/prototype/plugins/datejs/date.js	(revision 7143)
@@ -1,21 +1,145 @@
 /**
- * Please include a date.js file from the /build/ folder.
- * 
- * Individual date.js files have been compiled for each of the 150+ supported Cultures.
- * 
- * Example:
- * date.js       // English (United States)
- * date-en-US.js // English (United States)
- * date-de-DE.js // Deutsch (Deutschland)
- * date-es-MX.js // français (France)
+ * @version: 1.0 Alpha-1
+ * @author: Coolite Inc. http://www.coolite.com/
+ * @date: 2008-05-13
+ * @copyright: Copyright (c) 2006-2008, Coolite Inc. (http://www.coolite.com/). All rights reserved.
+ * @license: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
+ * @website: http://www.datejs.com/
  */
-
-alert(
-    "Please include a date.js file from the /build/ folder.\n\n" +
-    "Individual date.js files have been compiled for each supported Culture.\n\n" + 
-    "Example:\n" + 
-    "    date.js       // English (United States)\n" + 
-    "    date-en-US.js // English (United States)\n" + 
-    "    date-de-DE.js // Deutsch (Deutschland)\n" + 
-    "    date-es-MX.js // français (France)\n"
-    );
+Date.CultureInfo={name:"en-US",englishName:"English (United States)",nativeName:"English (United States)",dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbreviatedDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],shortestDayNames:["Su","Mo","Tu","We","Th","Fr","Sa"],firstLetterDayNames:["S","M","T","W","T","F","S"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],abbreviatedMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],amDesignator:"AM",pmDesignator:"PM",firstDayOfWeek:0,twoDigitYearMax:2029,dateElementOrder:"mdy",formatPatterns:{shortDate:"M/d/yyyy",longDate:"dddd, MMMM dd, yyyy",shortTime:"h:mm tt",longTime:"h:mm:ss tt",fullDateTime:"dddd, MMMM dd, yyyy h:mm:ss tt",sortableDateTime:"yyyy-MM-ddTHH:mm:ss",universalSortableDateTime:"yyyy-MM-dd HH:mm:ssZ",rfc1123:"ddd, dd MMM yyyy HH:mm:ss GMT",monthDay:"MMMM dd",yearMonth:"MMMM, yyyy"},regexPatterns:{jan:/^jan(uary)?/i,feb:/^feb(ruary)?/i,mar:/^mar(ch)?/i,apr:/^apr(il)?/i,may:/^may/i,jun:/^jun(e)?/i,jul:/^jul(y)?/i,aug:/^aug(ust)?/i,sep:/^sep(t(ember)?)?/i,oct:/^oct(ober)?/i,nov:/^nov(ember)?/i,dec:/^dec(ember)?/i,sun:/^su(n(day)?)?/i,mon:/^mo(n(day)?)?/i,tue:/^tu(e(s(day)?)?)?/i,wed:/^we(d(nesday)?)?/i,thu:/^th(u(r(s(day)?)?)?)?/i,fri:/^fr(i(day)?)?/i,sat:/^sa(t(urday)?)?/i,future:/^next/i,past:/^last|past|prev(ious)?/i,add:/^(\+|aft(er)?|from|hence)/i,subtract:/^(\-|bef(ore)?|ago)/i,yesterday:/^yes(terday)?/i,today:/^t(od(ay)?)?/i,tomorrow:/^tom(orrow)?/i,now:/^n(ow)?/i,millisecond:/^ms|milli(second)?s?/i,second:/^sec(ond)?s?/i,minute:/^mn|min(ute)?s?/i,hour:/^h(our)?s?/i,week:/^w(eek)?s?/i,month:/^m(onth)?s?/i,day:/^d(ay)?s?/i,year:/^y(ear)?s?/i,shortMeridian:/^(a|p)/i,longMeridian:/^(a\.?m?\.?|p\.?m?\.?)/i,timezone:/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt|utc)/i,ordinalSuffix:/^\s*(st|nd|rd|th)/i,timeContext:/^\s*(\:|a(?!u|p)|p)/i},timezones:[{name:"UTC",offset:"-000"},{name:"GMT",offset:"-000"},{name:"EST",offset:"-0500"},{name:"EDT",offset:"-0400"},{name:"CST",offset:"-0600"},{name:"CDT",offset:"-0500"},{name:"MST",offset:"-0700"},{name:"MDT",offset:"-0600"},{name:"PST",offset:"-0800"},{name:"PDT",offset:"-0700"}]};
+(function(){var $D=Date,$P=$D.prototype,$C=$D.CultureInfo,p=function(s,l){if(!l){l=2;}
+return("000"+s).slice(l*-1);};$P.clearTime=function(){this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};$P.setTimeToNow=function(){var n=new Date();this.setHours(n.getHours());this.setMinutes(n.getMinutes());this.setSeconds(n.getSeconds());this.setMilliseconds(n.getMilliseconds());return this;};$D.today=function(){return new Date().clearTime();};$D.compare=function(date1,date2){if(isNaN(date1)||isNaN(date2)){throw new Error(date1+" - "+date2);}else if(date1 instanceof Date&&date2 instanceof Date){return(date1<date2)?-1:(date1>date2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s||o[i].toLowerCase()==s){return i;}}
+return-1;};$D.getMonthNumberFromName=function(name){var n=$C.monthNames,m=$C.abbreviatedMonthNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
+return-1;};$D.isLeapYear=function(year){return((year%4===0&&year%100!==0)||year%400===0);};$D.getDaysInMonth=function(year,month){return[31,($D.isLeapYear(year)?29:28),31,30,31,30,31,31,30,31,30,31][month];};$D.getTimezoneAbbreviation=function(offset){var z=$C.timezones,p;for(var i=0;i<z.length;i++){if(z[i].offset===offset){return z[i].name;}}
+return null;};$D.getTimezoneOffset=function(name){var z=$C.timezones,p;for(var i=0;i<z.length;i++){if(z[i].name===name.toUpperCase()){return z[i].offset;}}
+return null;};$P.clone=function(){return new Date(this.getTime());};$P.compareTo=function(date){return Date.compare(this,date);};$P.equals=function(date){return Date.equals(this,date||new Date());};$P.between=function(start,end){return this.getTime()>=start.getTime()&&this.getTime()<=end.getTime();};$P.isAfter=function(date){return this.compareTo(date||new Date())===1;};$P.isBefore=function(date){return(this.compareTo(date||new Date())===-1);};$P.isToday=function(){return this.isSameDay(new Date());};$P.isSameDay=function(date){return this.clone().clearTime().equals(date.clone().clearTime());};$P.addMilliseconds=function(value){this.setMilliseconds(this.getMilliseconds()+value);return this;};$P.addSeconds=function(value){return this.addMilliseconds(value*1000);};$P.addMinutes=function(value){return this.addMilliseconds(value*60000);};$P.addHours=function(value){return this.addMilliseconds(value*3600000);};$P.addDays=function(value){this.setDate(this.getDate()+value);return this;};$P.addWeeks=function(value){return this.addDays(value*7);};$P.addMonths=function(value){var n=this.getDate();this.setDate(1);this.setMonth(this.getMonth()+value);this.setDate(Math.min(n,$D.getDaysInMonth(this.getFullYear(),this.getMonth())));return this;};$P.addYears=function(value){return this.addMonths(value*12);};$P.add=function(config){if(typeof config=="number"){this._orient=config;return this;}
+var x=config;if(x.milliseconds){this.addMilliseconds(x.milliseconds);}
+if(x.seconds){this.addSeconds(x.seconds);}
+if(x.minutes){this.addMinutes(x.minutes);}
+if(x.hours){this.addHours(x.hours);}
+if(x.weeks){this.addWeeks(x.weeks);}
+if(x.months){this.addMonths(x.months);}
+if(x.years){this.addYears(x.years);}
+if(x.days){this.addDays(x.days);}
+return this;};var $y,$m,$d;$P.getWeek=function(){var a,b,c,d,e,f,g,n,s,w;$y=(!$y)?this.getFullYear():$y;$m=(!$m)?this.getMonth()+1:$m;$d=(!$d)?this.getDate():$d;if($m<=2){a=$y-1;b=(a/4|0)-(a/100|0)+(a/400|0);c=((a-1)/4|0)-((a-1)/100|0)+((a-1)/400|0);s=b-c;e=0;f=$d-1+(31*($m-1));}else{a=$y;b=(a/4|0)-(a/100|0)+(a/400|0);c=((a-1)/4|0)-((a-1)/100|0)+((a-1)/400|0);s=b-c;e=s+1;f=$d+((153*($m-3)+2)/5)+58+s;}
+g=(a+b)%7;d=(f+g-e)%7;n=(f+3-d)|0;if(n<0){w=53-((g-s)/5|0);}else if(n>364+s){w=1;}else{w=(n/7|0)+1;}
+$y=$m=$d=null;return w;};$P.getISOWeek=function(){$y=this.getUTCFullYear();$m=this.getUTCMonth()+1;$d=this.getUTCDate();return p(this.getWeek());};$P.setWeek=function(n){return this.moveToDayOfWeek(1).addWeeks(n-this.getWeek());};$D._validate=function(n,min,max,name){if(typeof n=="undefined"){return false;}else if(typeof n!="number"){throw new TypeError(n+" is not a Number.");}else if(n<min||n>max){throw new RangeError(n+" is not a valid value for "+name+".");}
+return true;};$D.validateMillisecond=function(value){return $D._validate(value,0,999,"millisecond");};$D.validateSecond=function(value){return $D._validate(value,0,59,"second");};$D.validateMinute=function(value){return $D._validate(value,0,59,"minute");};$D.validateHour=function(value){return $D._validate(value,0,23,"hour");};$D.validateDay=function(value,year,month){return $D._validate(value,1,$D.getDaysInMonth(year,month),"day");};$D.validateMonth=function(value){return $D._validate(value,0,11,"month");};$D.validateYear=function(value){return $D._validate(value,0,9999,"year");};$P.set=function(config){if($D.validateMillisecond(config.millisecond)){this.addMilliseconds(config.millisecond-this.getMilliseconds());}
+if($D.validateSecond(config.second)){this.addSeconds(config.second-this.getSeconds());}
+if($D.validateMinute(config.minute)){this.addMinutes(config.minute-this.getMinutes());}
+if($D.validateHour(config.hour)){this.addHours(config.hour-this.getHours());}
+if($D.validateMonth(config.month)){this.addMonths(config.month-this.getMonth());}
+if($D.validateYear(config.year)){this.addYears(config.year-this.getFullYear());}
+if($D.validateDay(config.day,this.getFullYear(),this.getMonth())){this.addDays(config.day-this.getDate());}
+if(config.timezone){this.setTimezone(config.timezone);}
+if(config.timezoneOffset){this.setTimezoneOffset(config.timezoneOffset);}
+if(config.week&&$D._validate(config.week,0,53,"week")){this.setWeek(config.week);}
+return this;};$P.moveToFirstDayOfMonth=function(){return this.set({day:1});};$P.moveToLastDayOfMonth=function(){return this.set({day:$D.getDaysInMonth(this.getFullYear(),this.getMonth())});};$P.moveToNthOccurrence=function(dayOfWeek,occurrence){var shift=0;if(occurrence>0){shift=occurrence-1;}
+else if(occurrence===-1){this.moveToLastDayOfMonth();if(this.getDay()!==dayOfWeek){this.moveToDayOfWeek(dayOfWeek,-1);}
+return this;}
+return this.moveToFirstDayOfMonth().addDays(-1).moveToDayOfWeek(dayOfWeek,+1).addWeeks(shift);};$P.moveToDayOfWeek=function(dayOfWeek,orient){var diff=(dayOfWeek-this.getDay()+7*(orient||+1))%7;return this.addDays((diff===0)?diff+=7*(orient||+1):diff);};$P.moveToMonth=function(month,orient){var diff=(month-this.getMonth()+12*(orient||+1))%12;return this.addMonths((diff===0)?diff+=12*(orient||+1):diff);};$P.getOrdinalNumber=function(){return Math.ceil((this.clone().clearTime()-new Date(this.getFullYear(),0,1))/86400000)+1;};$P.getTimezone=function(){return $D.getTimezoneAbbreviation(this.getUTCOffset());};$P.setTimezoneOffset=function(offset){var here=this.getTimezoneOffset(),there=Number(offset)*-6/10;return this.addMinutes(there-here);};$P.setTimezone=function(offset){return this.setTimezoneOffset($D.getTimezoneOffset(offset));};$P.hasDaylightSavingTime=function(){return(Date.today().set({month:0,day:1}).getTimezoneOffset()!==Date.today().set({month:6,day:1}).getTimezoneOffset());};$P.isDaylightSavingTime=function(){return(this.hasDaylightSavingTime()&&new Date().getTimezoneOffset()===Date.today().set({month:6,day:1}).getTimezoneOffset());};$P.getUTCOffset=function(){var n=this.getTimezoneOffset()*-10/6,r;if(n<0){r=(n-10000).toString();return r.charAt(0)+r.substr(2);}else{r=(n+10000).toString();return"+"+r.substr(1);}};$P.getElapsed=function(date){return(date||new Date())-this;};if(!$P.toISOString){$P.toISOString=function(){function f(n){return n<10?'0'+n:n;}
+return'"'+this.getUTCFullYear()+'-'+
+f(this.getUTCMonth()+1)+'-'+
+f(this.getUTCDate())+'T'+
+f(this.getUTCHours())+':'+
+f(this.getUTCMinutes())+':'+
+f(this.getUTCSeconds())+'Z"';};}
+$P._toString=$P.toString;$P.toString=function(format){var x=this;if(format&&format.length==1){var c=$C.formatPatterns;x.t=x.toString;switch(format){case"d":return x.t(c.shortDate);case"D":return x.t(c.longDate);case"F":return x.t(c.fullDateTime);case"m":return x.t(c.monthDay);case"r":return x.t(c.rfc1123);case"s":return x.t(c.sortableDateTime);case"t":return x.t(c.shortTime);case"T":return x.t(c.longTime);case"u":return x.t(c.universalSortableDateTime);case"y":return x.t(c.yearMonth);}}
+var ord=function(n){switch(n*1){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}};return format?format.replace(/(\\)?(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|S)/g,function(m){if(m.charAt(0)==="\\"){return m.replace("\\","");}
+x.h=x.getHours;switch(m){case"hh":return p(x.h()<13?(x.h()===0?12:x.h()):(x.h()-12));case"h":return x.h()<13?(x.h()===0?12:x.h()):(x.h()-12);case"HH":return p(x.h());case"H":return x.h();case"mm":return p(x.getMinutes());case"m":return x.getMinutes();case"ss":return p(x.getSeconds());case"s":return x.getSeconds();case"yyyy":return p(x.getFullYear(),4);case"yy":return p(x.getFullYear());case"dddd":return $C.dayNames[x.getDay()];case"ddd":return $C.abbreviatedDayNames[x.getDay()];case"dd":return p(x.getDate());case"d":return x.getDate();case"MMMM":return $C.monthNames[x.getMonth()];case"MMM":return $C.abbreviatedMonthNames[x.getMonth()];case"MM":return p((x.getMonth()+1));case"M":return x.getMonth()+1;case"t":return x.h()<12?$C.amDesignator.substring(0,1):$C.pmDesignator.substring(0,1);case"tt":return x.h()<12?$C.amDesignator:$C.pmDesignator;case"S":return ord(x.getDate());default:return m;}}):this._toString();};}());
+(function(){var $D=Date,$P=$D.prototype,$C=$D.CultureInfo,$N=Number.prototype;$P._orient=+1;$P._nth=null;$P._is=false;$P._same=false;$P._isSecond=false;$N._dateElement="day";$P.next=function(){this._orient=+1;return this;};$D.next=function(){return $D.today().next();};$P.last=$P.prev=$P.previous=function(){this._orient=-1;return this;};$D.last=$D.prev=$D.previous=function(){return $D.today().last();};$P.is=function(){this._is=true;return this;};$P.same=function(){this._same=true;this._isSecond=false;return this;};$P.today=function(){return this.same().day();};$P.weekday=function(){if(this._is){this._is=false;return(!this.is().sat()&&!this.is().sun());}
+return false;};$P.at=function(time){return(typeof time==="string")?$D.parse(this.toString("d")+" "+time):this.set(time);};$N.fromNow=$N.after=function(date){var c={};c[this._dateElement]=this;return((!date)?new Date():date.clone()).add(c);};$N.ago=$N.before=function(date){var c={};c[this._dateElement]=this*-1;return((!date)?new Date():date.clone()).add(c);};var dx=("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),mx=("january february march april may june july august september october november december").split(/\s/),px=("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),pxf=("Milliseconds Seconds Minutes Hours Date Week Month FullYear").split(/\s/),nth=("final first second third fourth fifth").split(/\s/),de;$P.toObject=function(){var o={};for(var i=0;i<px.length;i++){o[px[i].toLowerCase()]=this["get"+pxf[i]]();}
+return o;};$D.fromObject=function(config){config.week=null;return Date.today().set(config);};var df=function(n){return function(){if(this._is){this._is=false;return this.getDay()==n;}
+if(this._nth!==null){if(this._isSecond){this.addSeconds(this._orient*-1);}
+this._isSecond=false;var ntemp=this._nth;this._nth=null;var temp=this.clone().moveToLastDayOfMonth();this.moveToNthOccurrence(n,ntemp);if(this>temp){throw new RangeError($D.getDayName(n)+" does not occur "+ntemp+" times in the month of "+$D.getMonthName(temp.getMonth())+" "+temp.getFullYear()+".");}
+return this;}
+return this.moveToDayOfWeek(n,this._orient);};};var sdf=function(n){return function(){var t=$D.today(),shift=n-t.getDay();if(n===0&&$C.firstDayOfWeek===1&&t.getDay()!==0){shift=shift+7;}
+return t.addDays(shift);};};for(var i=0;i<dx.length;i++){$D[dx[i].toUpperCase()]=$D[dx[i].toUpperCase().substring(0,3)]=i;$D[dx[i]]=$D[dx[i].substring(0,3)]=sdf(i);$P[dx[i]]=$P[dx[i].substring(0,3)]=df(i);}
+var mf=function(n){return function(){if(this._is){this._is=false;return this.getMonth()===n;}
+return this.moveToMonth(n,this._orient);};};var smf=function(n){return function(){return $D.today().set({month:n,day:1});};};for(var j=0;j<mx.length;j++){$D[mx[j].toUpperCase()]=$D[mx[j].toUpperCase().substring(0,3)]=j;$D[mx[j]]=$D[mx[j].substring(0,3)]=smf(j);$P[mx[j]]=$P[mx[j].substring(0,3)]=mf(j);}
+var ef=function(j){return function(){if(this._isSecond){this._isSecond=false;return this;}
+if(this._same){this._same=this._is=false;var o1=this.toObject(),o2=(arguments[0]||new Date()).toObject(),v="",k=j.toLowerCase();for(var m=(px.length-1);m>-1;m--){v=px[m].toLowerCase();if(o1[v]!=o2[v]){return false;}
+if(k==v){break;}}
+return true;}
+if(j.substring(j.length-1)!="s"){j+="s";}
+return this["add"+j](this._orient);};};var nf=function(n){return function(){this._dateElement=n;return this;};};for(var k=0;k<px.length;k++){de=px[k].toLowerCase();$P[de]=$P[de+"s"]=ef(px[k]);$N[de]=$N[de+"s"]=nf(de);}
+$P._ss=ef("Second");var nthfn=function(n){return function(dayOfWeek){if(this._same){return this._ss(arguments[0]);}
+if(dayOfWeek||dayOfWeek===0){return this.moveToNthOccurrence(dayOfWeek,n);}
+this._nth=n;if(n===2&&(dayOfWeek===undefined||dayOfWeek===null)){this._isSecond=true;return this.addSeconds(this._orient);}
+return this;};};for(var l=0;l<nth.length;l++){$P[nth[l]]=(l===0)?nthfn(-1):nthfn(l);}}());
+(function(){Date.Parsing={Exception:function(s){this.message="Parse error at '"+s.substring(0,10)+" ...'";}};var $P=Date.Parsing;var _=$P.Operators={rtoken:function(r){return function(s){var mx=s.match(r);if(mx){return([mx[0],s.substring(mx[0].length)]);}else{throw new $P.Exception(s);}};},token:function(s){return function(s){return _.rtoken(new RegExp("^\s*"+s+"\s*"))(s);};},stoken:function(s){return _.rtoken(new RegExp("^"+s));},until:function(p){return function(s){var qx=[],rx=null;while(s.length){try{rx=p.call(this,s);}catch(e){qx.push(rx[0]);s=rx[1];continue;}
+break;}
+return[qx,s];};},many:function(p){return function(s){var rx=[],r=null;while(s.length){try{r=p.call(this,s);}catch(e){return[rx,s];}
+rx.push(r[0]);s=r[1];}
+return[rx,s];};},optional:function(p){return function(s){var r=null;try{r=p.call(this,s);}catch(e){return[null,s];}
+return[r[0],r[1]];};},not:function(p){return function(s){try{p.call(this,s);}catch(e){return[null,s];}
+throw new $P.Exception(s);};},ignore:function(p){return p?function(s){var r=null;r=p.call(this,s);return[null,r[1]];}:null;},product:function(){var px=arguments[0],qx=Array.prototype.slice.call(arguments,1),rx=[];for(var i=0;i<px.length;i++){rx.push(_.each(px[i],qx));}
+return rx;},cache:function(rule){var cache={},r=null;return function(s){try{r=cache[s]=(cache[s]||rule.call(this,s));}catch(e){r=cache[s]=e;}
+if(r instanceof $P.Exception){throw r;}else{return r;}};},any:function(){var px=arguments;return function(s){var r=null;for(var i=0;i<px.length;i++){if(px[i]==null){continue;}
+try{r=(px[i].call(this,s));}catch(e){r=null;}
+if(r){return r;}}
+throw new $P.Exception(s);};},each:function(){var px=arguments;return function(s){var rx=[],r=null;for(var i=0;i<px.length;i++){if(px[i]==null){continue;}
+try{r=(px[i].call(this,s));}catch(e){throw new $P.Exception(s);}
+rx.push(r[0]);s=r[1];}
+return[rx,s];};},all:function(){var px=arguments,_=_;return _.each(_.optional(px));},sequence:function(px,d,c){d=d||_.rtoken(/^\s*/);c=c||null;if(px.length==1){return px[0];}
+return function(s){var r=null,q=null;var rx=[];for(var i=0;i<px.length;i++){try{r=px[i].call(this,s);}catch(e){break;}
+rx.push(r[0]);try{q=d.call(this,r[1]);}catch(ex){q=null;break;}
+s=q[1];}
+if(!r){throw new $P.Exception(s);}
+if(q){throw new $P.Exception(q[1]);}
+if(c){try{r=c.call(this,r[1]);}catch(ey){throw new $P.Exception(r[1]);}}
+return[rx,(r?r[1]:s)];};},between:function(d1,p,d2){d2=d2||d1;var _fn=_.each(_.ignore(d1),p,_.ignore(d2));return function(s){var rx=_fn.call(this,s);return[[rx[0][0],r[0][2]],rx[1]];};},list:function(p,d,c){d=d||_.rtoken(/^\s*/);c=c||null;return(p instanceof Array?_.each(_.product(p.slice(0,-1),_.ignore(d)),p.slice(-1),_.ignore(c)):_.each(_.many(_.each(p,_.ignore(d))),px,_.ignore(c)));},set:function(px,d,c){d=d||_.rtoken(/^\s*/);c=c||null;return function(s){var r=null,p=null,q=null,rx=null,best=[[],s],last=false;for(var i=0;i<px.length;i++){q=null;p=null;r=null;last=(px.length==1);try{r=px[i].call(this,s);}catch(e){continue;}
+rx=[[r[0]],r[1]];if(r[1].length>0&&!last){try{q=d.call(this,r[1]);}catch(ex){last=true;}}else{last=true;}
+if(!last&&q[1].length===0){last=true;}
+if(!last){var qx=[];for(var j=0;j<px.length;j++){if(i!=j){qx.push(px[j]);}}
+p=_.set(qx,d).call(this,q[1]);if(p[0].length>0){rx[0]=rx[0].concat(p[0]);rx[1]=p[1];}}
+if(rx[1].length<best[1].length){best=rx;}
+if(best[1].length===0){break;}}
+if(best[0].length===0){return best;}
+if(c){try{q=c.call(this,best[1]);}catch(ey){throw new $P.Exception(best[1]);}
+best[1]=q[1];}
+return best;};},forward:function(gr,fname){return function(s){return gr[fname].call(this,s);};},replace:function(rule,repl){return function(s){var r=rule.call(this,s);return[repl,r[1]];};},process:function(rule,fn){return function(s){var r=rule.call(this,s);return[fn.call(this,r[0]),r[1]];};},min:function(min,rule){return function(s){var rx=rule.call(this,s);if(rx[0].length<min){throw new $P.Exception(s);}
+return rx;};}};var _generator=function(op){return function(){var args=null,rx=[];if(arguments.length>1){args=Array.prototype.slice.call(arguments);}else if(arguments[0]instanceof Array){args=arguments[0];}
+if(args){for(var i=0,px=args.shift();i<px.length;i++){args.unshift(px[i]);rx.push(op.apply(null,args));args.shift();return rx;}}else{return op.apply(null,arguments);}};};var gx="optional not ignore cache".split(/\s/);for(var i=0;i<gx.length;i++){_[gx[i]]=_generator(_[gx[i]]);}
+var _vector=function(op){return function(){if(arguments[0]instanceof Array){return op.apply(null,arguments[0]);}else{return op.apply(null,arguments);}};};var vx="each any all".split(/\s/);for(var j=0;j<vx.length;j++){_[vx[j]]=_vector(_[vx[j]]);}}());(function(){var $D=Date,$P=$D.prototype,$C=$D.CultureInfo;var flattenAndCompact=function(ax){var rx=[];for(var i=0;i<ax.length;i++){if(ax[i]instanceof Array){rx=rx.concat(flattenAndCompact(ax[i]));}else{if(ax[i]){rx.push(ax[i]);}}}
+return rx;};$D.Grammar={};$D.Translator={hour:function(s){return function(){this.hour=Number(s);};},minute:function(s){return function(){this.minute=Number(s);};},second:function(s){return function(){this.second=Number(s);};},meridian:function(s){return function(){this.meridian=s.slice(0,1).toLowerCase();};},timezone:function(s){return function(){var n=s.replace(/[^\d\+\-]/g,"");if(n.length){this.timezoneOffset=Number(n);}else{this.timezone=s.toLowerCase();}};},day:function(x){var s=x[0];return function(){this.day=Number(s.match(/\d+/)[0]);};},month:function(s){return function(){this.month=(s.length==3)?"jan feb mar apr may jun jul aug sep oct nov dec".indexOf(s)/4:Number(s)-1;};},year:function(s){return function(){var n=Number(s);this.year=((s.length>2)?n:(n+(((n+2000)<$C.twoDigitYearMax)?2000:1900)));};},rday:function(s){return function(){switch(s){case"yesterday":this.days=-1;break;case"tomorrow":this.days=1;break;case"today":this.days=0;break;case"now":this.days=0;this.now=true;break;}};},finishExact:function(x){x=(x instanceof Array)?x:[x];for(var i=0;i<x.length;i++){if(x[i]){x[i].call(this);}}
+var now=new Date();if((this.hour||this.minute)&&(!this.month&&!this.year&&!this.day)){this.day=now.getDate();}
+if(!this.year){this.year=now.getFullYear();}
+if(!this.month&&this.month!==0){this.month=now.getMonth();}
+if(!this.day){this.day=1;}
+if(!this.hour){this.hour=0;}
+if(!this.minute){this.minute=0;}
+if(!this.second){this.second=0;}
+if(this.meridian&&this.hour){if(this.meridian=="p"&&this.hour<12){this.hour=this.hour+12;}else if(this.meridian=="a"&&this.hour==12){this.hour=0;}}
+if(this.day>$D.getDaysInMonth(this.year,this.month)){throw new RangeError(this.day+" is not a valid value for days.");}
+var r=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second);if(this.timezone){r.set({timezone:this.timezone});}else if(this.timezoneOffset){r.set({timezoneOffset:this.timezoneOffset});}
+return r;},finish:function(x){x=(x instanceof Array)?flattenAndCompact(x):[x];if(x.length===0){return null;}
+for(var i=0;i<x.length;i++){if(typeof x[i]=="function"){x[i].call(this);}}
+var today=$D.today();if(this.now&&!this.unit&&!this.operator){return new Date();}else if(this.now){today=new Date();}
+var expression=!!(this.days&&this.days!==null||this.orient||this.operator);var gap,mod,orient;orient=((this.orient=="past"||this.operator=="subtract")?-1:1);if(!this.now&&"hour minute second".indexOf(this.unit)!=-1){today.setTimeToNow();}
+if(this.month||this.month===0){if("year day hour minute second".indexOf(this.unit)!=-1){this.value=this.month+1;this.month=null;expression=true;}}
+if(!expression&&this.weekday&&!this.day&&!this.days){var temp=Date[this.weekday]();this.day=temp.getDate();if(!this.month){this.month=temp.getMonth();}
+this.year=temp.getFullYear();}
+if(expression&&this.weekday&&this.unit!="month"){this.unit="day";gap=($D.getDayNumberFromName(this.weekday)-today.getDay());mod=7;this.days=gap?((gap+(orient*mod))%mod):(orient*mod);}
+if(this.month&&this.unit=="day"&&this.operator){this.value=(this.month+1);this.month=null;}
+if(this.value!=null&&this.month!=null&&this.year!=null){this.day=this.value*1;}
+if(this.month&&!this.day&&this.value){today.set({day:this.value*1});if(!expression){this.day=this.value*1;}}
+if(!this.month&&this.value&&this.unit=="month"&&!this.now){this.month=this.value;expression=true;}
+if(expression&&(this.month||this.month===0)&&this.unit!="year"){this.unit="month";gap=(this.month-today.getMonth());mod=12;this.months=gap?((gap+(orient*mod))%mod):(orient*mod);this.month=null;}
+if(!this.unit){this.unit="day";}
+if(!this.value&&this.operator&&this.operator!==null&&this[this.unit+"s"]&&this[this.unit+"s"]!==null){this[this.unit+"s"]=this[this.unit+"s"]+((this.operator=="add")?1:-1)+(this.value||0)*orient;}else if(this[this.unit+"s"]==null||this.operator!=null){if(!this.value){this.value=1;}
+this[this.unit+"s"]=this.value*orient;}
+if(this.meridian&&this.hour){if(this.meridian=="p"&&this.hour<12){this.hour=this.hour+12;}else if(this.meridian=="a"&&this.hour==12){this.hour=0;}}
+if(this.weekday&&!this.day&&!this.days){var temp=Date[this.weekday]();this.day=temp.getDate();if(temp.getMonth()!==today.getMonth()){this.month=temp.getMonth();}}
+if((this.month||this.month===0)&&!this.day){this.day=1;}
+if(!this.orient&&!this.operator&&this.unit=="week"&&this.value&&!this.day&&!this.month){return Date.today().setWeek(this.value);}
+if(expression&&this.timezone&&this.day&&this.days){this.day=this.days;}
+return(expression)?today.add(this):today.set(this);}};var _=$D.Parsing.Operators,g=$D.Grammar,t=$D.Translator,_fn;g.datePartDelimiter=_.rtoken(/^([\s\-\.\,\/\x27]+)/);g.timePartDelimiter=_.stoken(":");g.whiteSpace=_.rtoken(/^\s*/);g.generalDelimiter=_.rtoken(/^(([\s\,]|at|@|on)+)/);var _C={};g.ctoken=function(keys){var fn=_C[keys];if(!fn){var c=$C.regexPatterns;var kx=keys.split(/\s+/),px=[];for(var i=0;i<kx.length;i++){px.push(_.replace(_.rtoken(c[kx[i]]),kx[i]));}
+fn=_C[keys]=_.any.apply(null,px);}
+return fn;};g.ctoken2=function(key){return _.rtoken($C.regexPatterns[key]);};g.h=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2]|[1-9])/),t.hour));g.hh=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2])/),t.hour));g.H=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/),t.hour));g.HH=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3])/),t.hour));g.m=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.minute));g.mm=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.minute));g.s=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.second));g.ss=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.second));g.hms=_.cache(_.sequence([g.H,g.m,g.s],g.timePartDelimiter));g.t=_.cache(_.process(g.ctoken2("shortMeridian"),t.meridian));g.tt=_.cache(_.process(g.ctoken2("longMeridian"),t.meridian));g.z=_.cache(_.process(_.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/),t.timezone));g.zz=_.cache(_.process(_.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/),t.timezone));g.zzz=_.cache(_.process(g.ctoken2("timezone"),t.timezone));g.timeSuffix=_.each(_.ignore(g.whiteSpace),_.set([g.tt,g.zzz]));g.time=_.each(_.optional(_.ignore(_.stoken("T"))),g.hms,g.timeSuffix);g.d=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.dd=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.ddd=g.dddd=_.cache(_.process(g.ctoken("sun mon tue wed thu fri sat"),function(s){return function(){this.weekday=s;};}));g.M=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d|\d)/),t.month));g.MM=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d)/),t.month));g.MMM=g.MMMM=_.cache(_.process(g.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"),t.month));g.y=_.cache(_.process(_.rtoken(/^(\d\d?)/),t.year));g.yy=_.cache(_.process(_.rtoken(/^(\d\d)/),t.year));g.yyy=_.cache(_.process(_.rtoken(/^(\d\d?\d?\d?)/),t.year));g.yyyy=_.cache(_.process(_.rtoken(/^(\d\d\d\d)/),t.year));_fn=function(){return _.each(_.any.apply(null,arguments),_.not(g.ctoken2("timeContext")));};g.day=_fn(g.d,g.dd);g.month=_fn(g.M,g.MMM);g.year=_fn(g.yyyy,g.yy);g.orientation=_.process(g.ctoken("past future"),function(s){return function(){this.orient=s;};});g.operator=_.process(g.ctoken("add subtract"),function(s){return function(){this.operator=s;};});g.rday=_.process(g.ctoken("yesterday tomorrow today now"),t.rday);g.unit=_.process(g.ctoken("second minute hour day week month year"),function(s){return function(){this.unit=s;};});g.value=_.process(_.rtoken(/^\d\d?(st|nd|rd|th)?/),function(s){return function(){this.value=s.replace(/\D/g,"");};});g.expression=_.set([g.rday,g.operator,g.value,g.unit,g.orientation,g.ddd,g.MMM]);_fn=function(){return _.set(arguments,g.datePartDelimiter);};g.mdy=_fn(g.ddd,g.month,g.day,g.year);g.ymd=_fn(g.ddd,g.year,g.month,g.day);g.dmy=_fn(g.ddd,g.day,g.month,g.year);g.date=function(s){return((g[$C.dateElementOrder]||g.mdy).call(this,s));};g.format=_.process(_.many(_.any(_.process(_.rtoken(/^(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/),function(fmt){if(g[fmt]){return g[fmt];}else{throw $D.Parsing.Exception(fmt);}}),_.process(_.rtoken(/^[^dMyhHmstz]+/),function(s){return _.ignore(_.stoken(s));}))),function(rules){return _.process(_.each.apply(null,rules),t.finishExact);});var _F={};var _get=function(f){return _F[f]=(_F[f]||g.format(f)[0]);};g.formats=function(fx){if(fx instanceof Array){var rx=[];for(var i=0;i<fx.length;i++){rx.push(_get(fx[i]));}
+return _.any.apply(null,rx);}else{return _get(fx);}};g._formats=g.formats(["\"yyyy-MM-ddTHH:mm:ssZ\"","yyyy-MM-ddTHH:mm:ssZ","yyyy-MM-ddTHH:mm:ssz","yyyy-MM-ddTHH:mm:ss","yyyy-MM-ddTHH:mmZ","yyyy-MM-ddTHH:mmz","yyyy-MM-ddTHH:mm","ddd, MMM dd, yyyy H:mm:ss tt","ddd MMM d yyyy HH:mm:ss zzz","MMddyyyy","ddMMyyyy","Mddyyyy","ddMyyyy","Mdyyyy","dMyyyy","yyyy","Mdyy","dMyy","d"]);g._start=_.process(_.set([g.date,g.time,g.expression],g.generalDelimiter,g.whiteSpace),t.finish);g.start=function(s){try{var r=g._formats.call({},s);if(r[1].length===0){return r;}}catch(e){}
+return g._start.call({},s);};$D._parse=$D.parse;$D.parse=function(s){var r=null;if(!s){return null;}
+if(s instanceof Date){return s;}
+try{r=$D.Grammar.start.call({},s.replace(/^\s*(\S*(\s+\S+)*)\s*$/,"$1"));}catch(e){return null;}
+return((r[1].length===0)?r[0]:null);};$D.getParseFunction=function(fx){var fn=$D.Grammar.formats(fx);return function(s){var r=null;try{r=fn.call({},s);}catch(e){return null;}
+return((r[1].length===0)?r[0]:null);};};$D.parseExact=function(s,fx){return $D.getParseFunction(fx)(s);};}());
Index: /trunk/prototype/plugins/datejs/sugarpak.js
===================================================================
--- /trunk/prototype/plugins/datejs/sugarpak.js	(revision 5341)
+++ /trunk/prototype/plugins/datejs/sugarpak.js	(revision 7143)
@@ -1,13 +1,28 @@
 /**
- * Version: 1.0 Alpha-1 
- * Build Date: 13-Nov-2007
- * Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
- * License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
- * Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
+ * @version: 1.0 Alpha-1
+ * @author: Coolite Inc. http://www.coolite.com/
+ * @date: 2008-05-13
+ * @copyright: Copyright (c) 2006-2008, Coolite Inc. (http://www.coolite.com/). All rights reserved.
+ * @license: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
+ * @website: http://www.datejs.com/
  */
-Date.now=function(){return new Date();};Date.today=function(){return Date.now().clearTime();};Date.prototype._orient=+1;Date.prototype.next=function(){this._orient=+1;return this;};Date.prototype.last=Date.prototype.prev=Date.prototype.previous=function(){this._orient=-1;return this;};Date.prototype._is=false;Date.prototype.is=function(){this._is=true;return this;};Number.prototype._dateElement="day";Number.prototype.fromNow=function(){var c={};c[this._dateElement]=this;return Date.now().add(c);};Number.prototype.ago=function(){var c={};c[this._dateElement]=this*-1;return Date.now().add(c);};(function(){var $D=Date.prototype,$N=Number.prototype;var dx=("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),mx=("january february march april may june july august september october november december").split(/\s/),px=("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),de;var df=function(n){return function(){if(this._is){this._is=false;return this.getDay()==n;}
-return this.moveToDayOfWeek(n,this._orient);};};for(var i=0;i<dx.length;i++){$D[dx[i]]=$D[dx[i].substring(0,3)]=df(i);}
+(function(){var $D=Date,$P=$D.prototype,$C=$D.CultureInfo,$N=Number.prototype;$P._orient=+1;$P._nth=null;$P._is=false;$P._same=false;$P._isSecond=false;$N._dateElement="day";$P.next=function(){this._orient=+1;return this;};$D.next=function(){return $D.today().next();};$P.last=$P.prev=$P.previous=function(){this._orient=-1;return this;};$D.last=$D.prev=$D.previous=function(){return $D.today().last();};$P.is=function(){this._is=true;return this;};$P.same=function(){this._same=true;this._isSecond=false;return this;};$P.today=function(){return this.same().day();};$P.weekday=function(){if(this._is){this._is=false;return(!this.is().sat()&&!this.is().sun());}
+return false;};$P.at=function(time){return(typeof time==="string")?$D.parse(this.toString("d")+" "+time):this.set(time);};$N.fromNow=$N.after=function(date){var c={};c[this._dateElement]=this;return((!date)?new Date():date.clone()).add(c);};$N.ago=$N.before=function(date){var c={};c[this._dateElement]=this*-1;return((!date)?new Date():date.clone()).add(c);};var dx=("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),mx=("january february march april may june july august september october november december").split(/\s/),px=("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),pxf=("Milliseconds Seconds Minutes Hours Date Week Month FullYear").split(/\s/),nth=("final first second third fourth fifth").split(/\s/),de;$P.toObject=function(){var o={};for(var i=0;i<px.length;i++){o[px[i].toLowerCase()]=this["get"+pxf[i]]();}
+return o;};$D.fromObject=function(config){config.week=null;return Date.today().set(config);};var df=function(n){return function(){if(this._is){this._is=false;return this.getDay()==n;}
+if(this._nth!==null){if(this._isSecond){this.addSeconds(this._orient*-1);}
+this._isSecond=false;var ntemp=this._nth;this._nth=null;var temp=this.clone().moveToLastDayOfMonth();this.moveToNthOccurrence(n,ntemp);if(this>temp){throw new RangeError($D.getDayName(n)+" does not occur "+ntemp+" times in the month of "+$D.getMonthName(temp.getMonth())+" "+temp.getFullYear()+".");}
+return this;}
+return this.moveToDayOfWeek(n,this._orient);};};var sdf=function(n){return function(){var t=$D.today(),shift=n-t.getDay();if(n===0&&$C.firstDayOfWeek===1&&t.getDay()!==0){shift=shift+7;}
+return t.addDays(shift);};};for(var i=0;i<dx.length;i++){$D[dx[i].toUpperCase()]=$D[dx[i].toUpperCase().substring(0,3)]=i;$D[dx[i]]=$D[dx[i].substring(0,3)]=sdf(i);$P[dx[i]]=$P[dx[i].substring(0,3)]=df(i);}
 var mf=function(n){return function(){if(this._is){this._is=false;return this.getMonth()===n;}
-return this.moveToMonth(n,this._orient);};};for(var j=0;j<mx.length;j++){$D[mx[j]]=$D[mx[j].substring(0,3)]=mf(j);}
-var ef=function(j){return function(){if(j.substring(j.length-1)!="s"){j+="s";}
-return this["add"+j](this._orient);};};var nf=function(n){return function(){this._dateElement=n;return this;};};for(var k=0;k<px.length;k++){de=px[k].toLowerCase();$D[de]=$D[de+"s"]=ef(px[k]);$N[de]=$N[de+"s"]=nf(de);}}());Date.prototype.toJSONString=function(){return this.toString("yyyy-MM-ddThh:mm:ssZ");};Date.prototype.toShortDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortDatePattern);};Date.prototype.toLongDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.longDatePattern);};Date.prototype.toShortTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortTimePattern);};Date.prototype.toLongTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.longTimePattern);};Date.prototype.getOrdinal=function(){switch(this.getDate()){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}};
+return this.moveToMonth(n,this._orient);};};var smf=function(n){return function(){return $D.today().set({month:n,day:1});};};for(var j=0;j<mx.length;j++){$D[mx[j].toUpperCase()]=$D[mx[j].toUpperCase().substring(0,3)]=j;$D[mx[j]]=$D[mx[j].substring(0,3)]=smf(j);$P[mx[j]]=$P[mx[j].substring(0,3)]=mf(j);}
+var ef=function(j){return function(){if(this._isSecond){this._isSecond=false;return this;}
+if(this._same){this._same=this._is=false;var o1=this.toObject(),o2=(arguments[0]||new Date()).toObject(),v="",k=j.toLowerCase();for(var m=(px.length-1);m>-1;m--){v=px[m].toLowerCase();if(o1[v]!=o2[v]){return false;}
+if(k==v){break;}}
+return true;}
+if(j.substring(j.length-1)!="s"){j+="s";}
+return this["add"+j](this._orient);};};var nf=function(n){return function(){this._dateElement=n;return this;};};for(var k=0;k<px.length;k++){de=px[k].toLowerCase();$P[de]=$P[de+"s"]=ef(px[k]);$N[de]=$N[de+"s"]=nf(de);}
+$P._ss=ef("Second");var nthfn=function(n){return function(dayOfWeek){if(this._same){return this._ss(arguments[0]);}
+if(dayOfWeek||dayOfWeek===0){return this.moveToNthOccurrence(dayOfWeek,n);}
+this._nth=n;if(n===2&&(dayOfWeek===undefined||dayOfWeek===null)){this._isSecond=true;return this.addSeconds(this._orient);}
+return this;};};for(var l=0;l<nth.length;l++){$P[nth[l]]=(l===0)?nthfn(-1):nthfn(l);}}());
Index: /trunk/prototype/plugins/datejs/time.js
===================================================================
--- /trunk/prototype/plugins/datejs/time.js	(revision 5341)
+++ /trunk/prototype/plugins/datejs/time.js	(revision 7143)
@@ -1,19 +1,19 @@
 /**
- * Version: 1.0 Alpha-1 
- * Build Date: 13-Nov-2007
- * Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
- * License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
- * Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
+ * @version: 1.0 Alpha-1
+ * @author: Coolite Inc. http://www.coolite.com/
+ * @date: 2008-05-13
+ * @copyright: Copyright (c) 2006-2008, Coolite Inc. (http://www.coolite.com/). All rights reserved.
+ * @license: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
+ * @website: http://www.datejs.com/
  */
-TimeSpan=function(days,hours,minutes,seconds,milliseconds){this.days=0;this.hours=0;this.minutes=0;this.seconds=0;this.milliseconds=0;if(arguments.length==5){this.days=days;this.hours=hours;this.minutes=minutes;this.seconds=seconds;this.milliseconds=milliseconds;}
-else if(arguments.length==1&&typeof days=="number"){var orient=(days<0)?-1:+1;this.milliseconds=Math.abs(days);this.days=Math.floor(this.milliseconds/(24*60*60*1000))*orient;this.milliseconds=this.milliseconds%(24*60*60*1000);this.hours=Math.floor(this.milliseconds/(60*60*1000))*orient;this.milliseconds=this.milliseconds%(60*60*1000);this.minutes=Math.floor(this.milliseconds/(60*1000))*orient;this.milliseconds=this.milliseconds%(60*1000);this.seconds=Math.floor(this.milliseconds/1000)*orient;this.milliseconds=this.milliseconds%1000;this.milliseconds=this.milliseconds*orient;return this;}
-else{return null;}};TimeSpan.prototype.compare=function(timeSpan){var t1=new Date(1970,1,1,this.hours(),this.minutes(),this.seconds()),t2;if(timeSpan===null){t2=new Date(1970,1,1,0,0,0);}
-else{t2=new Date(1970,1,1,timeSpan.hours(),timeSpan.minutes(),timeSpan.seconds());}
-return(t1>t2)?1:(t1<t2)?-1:0;};TimeSpan.prototype.add=function(timeSpan){return(timeSpan===null)?this:this.addSeconds(timeSpan.getTotalMilliseconds()/1000);};TimeSpan.prototype.subtract=function(timeSpan){return(timeSpan===null)?this:this.addSeconds(-timeSpan.getTotalMilliseconds()/1000);};TimeSpan.prototype.addDays=function(n){return new TimeSpan(this.getTotalMilliseconds()+(n*24*60*60*1000));};TimeSpan.prototype.addHours=function(n){return new TimeSpan(this.getTotalMilliseconds()+(n*60*60*1000));};TimeSpan.prototype.addMinutes=function(n){return new TimeSpan(this.getTotalMilliseconds()+(n*60*1000));};TimeSpan.prototype.addSeconds=function(n){return new TimeSpan(this.getTotalMilliseconds()+(n*1000));};TimeSpan.prototype.addMilliseconds=function(n){return new TimeSpan(this.getTotalMilliseconds()+n);};TimeSpan.prototype.getTotalMilliseconds=function(){return(this.days()*(24*60*60*1000))+(this.hours()*(60*60*1000))+(this.minutes()*(60*1000))+(this.seconds()*(1000));};TimeSpan.prototype.get12HourHour=function(){return((h=this.hours()%12)?h:12);};TimeSpan.prototype.getDesignator=function(){return(this.hours()<12)?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;};TimeSpan.prototype.toString=function(format){function _toString(){if(this.days()!==null&&this.days()>0){return this.days()+"."+this.hours()+":"+p(this.minutes())+":"+p(this.seconds());}
-else{return this.hours()+":"+p(this.minutes())+":"+p(this.seconds());}}
-function p(s){return(s.toString().length<2)?"0"+s:s;}
-var self=this;return format?format.replace(/d|dd|HH|H|hh|h|mm|m|ss|s|tt|t/g,function(format){switch(format){case"d":return self.days();case"dd":return p(self.days());case"H":return self.hours();case"HH":return p(self.hours());case"h":return self.get12HourHour();case"hh":return p(self.get12HourHour());case"m":return self.minutes();case"mm":return p(self.minutes());case"s":return self.seconds();case"ss":return p(self.seconds());case"t":return((this.hours()<12)?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator).substring(0,1);case"tt":return(this.hours()<12)?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;}}):this._toString();};var TimePeriod=function(years,months,days,hours,minutes,seconds,milliseconds){this.years=0;this.months=0;this.days=0;this.hours=0;this.minutes=0;this.seconds=0;this.milliseconds=0;if(arguments.length==2&&arguments[0]instanceof Date&&arguments[1]instanceof Date){var date1=years.clone();var date2=months.clone();var temp=date1.clone();var orient=(date1>date2)?-1:+1;this.years=date2.getFullYear()-date1.getFullYear();temp.addYears(this.years);if(orient==+1){if(temp>date2){if(this.years!==0){this.years--;}}}else{if(temp<date2){if(this.years!==0){this.years++;}}}
-date1.addYears(this.years);if(orient==+1){while(date1<date2&&date1.clone().addDays(date1.getDaysInMonth())<date2){date1.addMonths(1);this.months++;}}
-else{while(date1>date2&&date1.clone().addDays(-date1.getDaysInMonth())>date2){date1.addMonths(-1);this.months--;}}
-var diff=date2-date1;if(diff!==0){var ts=new TimeSpan(diff);this.days=ts.days;this.hours=ts.hours;this.minutes=ts.minutes;this.seconds=ts.seconds;this.milliseconds=ts.milliseconds;}
-return this;}};
+var TimeSpan=function(days,hours,minutes,seconds,milliseconds){var attrs="days hours minutes seconds milliseconds".split(/\s+/);var gFn=function(attr){return function(){return this[attr];};};var sFn=function(attr){return function(val){this[attr]=val;return this;};};for(var i=0;i<attrs.length;i++){var $a=attrs[i],$b=$a.slice(0,1).toUpperCase()+$a.slice(1);TimeSpan.prototype[$a]=0;TimeSpan.prototype["get"+$b]=gFn($a);TimeSpan.prototype["set"+$b]=sFn($a);}
+if(arguments.length==4){this.setDays(days);this.setHours(hours);this.setMinutes(minutes);this.setSeconds(seconds);}else if(arguments.length==5){this.setDays(days);this.setHours(hours);this.setMinutes(minutes);this.setSeconds(seconds);this.setMilliseconds(milliseconds);}else if(arguments.length==1&&typeof days=="number"){var orient=(days<0)?-1:+1;this.setMilliseconds(Math.abs(days));this.setDays(Math.floor(this.getMilliseconds()/86400000)*orient);this.setMilliseconds(this.getMilliseconds()%86400000);this.setHours(Math.floor(this.getMilliseconds()/3600000)*orient);this.setMilliseconds(this.getMilliseconds()%3600000);this.setMinutes(Math.floor(this.getMilliseconds()/60000)*orient);this.setMilliseconds(this.getMilliseconds()%60000);this.setSeconds(Math.floor(this.getMilliseconds()/1000)*orient);this.setMilliseconds(this.getMilliseconds()%1000);this.setMilliseconds(this.getMilliseconds()*orient);}
+this.getTotalMilliseconds=function(){return(this.getDays()*86400000)+(this.getHours()*3600000)+(this.getMinutes()*60000)+(this.getSeconds()*1000);};this.compareTo=function(time){var t1=new Date(1970,1,1,this.getHours(),this.getMinutes(),this.getSeconds()),t2;if(time===null){t2=new Date(1970,1,1,0,0,0);}
+else{t2=new Date(1970,1,1,time.getHours(),time.getMinutes(),time.getSeconds());}
+return(t1<t2)?-1:(t1>t2)?1:0;};this.equals=function(time){return(this.compareTo(time)===0);};this.add=function(time){return(time===null)?this:this.addSeconds(time.getTotalMilliseconds()/1000);};this.subtract=function(time){return(time===null)?this:this.addSeconds(-time.getTotalMilliseconds()/1000);};this.addDays=function(n){return new TimeSpan(this.getTotalMilliseconds()+(n*86400000));};this.addHours=function(n){return new TimeSpan(this.getTotalMilliseconds()+(n*3600000));};this.addMinutes=function(n){return new TimeSpan(this.getTotalMilliseconds()+(n*60000));};this.addSeconds=function(n){return new TimeSpan(this.getTotalMilliseconds()+(n*1000));};this.addMilliseconds=function(n){return new TimeSpan(this.getTotalMilliseconds()+n);};this.get12HourHour=function(){return(this.getHours()>12)?this.getHours()-12:(this.getHours()===0)?12:this.getHours();};this.getDesignator=function(){return(this.getHours()<12)?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;};this.toString=function(format){this._toString=function(){if(this.getDays()!==null&&this.getDays()>0){return this.getDays()+"."+this.getHours()+":"+this.p(this.getMinutes())+":"+this.p(this.getSeconds());}
+else{return this.getHours()+":"+this.p(this.getMinutes())+":"+this.p(this.getSeconds());}};this.p=function(s){return(s.toString().length<2)?"0"+s:s;};var me=this;return format?format.replace(/dd?|HH?|hh?|mm?|ss?|tt?/g,function(format){switch(format){case"d":return me.getDays();case"dd":return me.p(me.getDays());case"H":return me.getHours();case"HH":return me.p(me.getHours());case"h":return me.get12HourHour();case"hh":return me.p(me.get12HourHour());case"m":return me.getMinutes();case"mm":return me.p(me.getMinutes());case"s":return me.getSeconds();case"ss":return me.p(me.getSeconds());case"t":return((me.getHours()<12)?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator).substring(0,1);case"tt":return(me.getHours()<12)?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;}}):this._toString();};return this;};Date.prototype.getTimeOfDay=function(){return new TimeSpan(0,this.getHours(),this.getMinutes(),this.getSeconds(),this.getMilliseconds());};var TimePeriod=function(years,months,days,hours,minutes,seconds,milliseconds){var attrs="years months days hours minutes seconds milliseconds".split(/\s+/);var gFn=function(attr){return function(){return this[attr];};};var sFn=function(attr){return function(val){this[attr]=val;return this;};};for(var i=0;i<attrs.length;i++){var $a=attrs[i],$b=$a.slice(0,1).toUpperCase()+$a.slice(1);TimePeriod.prototype[$a]=0;TimePeriod.prototype["get"+$b]=gFn($a);TimePeriod.prototype["set"+$b]=sFn($a);}
+if(arguments.length==7){this.years=years;this.months=months;this.setDays(days);this.setHours(hours);this.setMinutes(minutes);this.setSeconds(seconds);this.setMilliseconds(milliseconds);}else if(arguments.length==2&&arguments[0]instanceof Date&&arguments[1]instanceof Date){var d1=years.clone();var d2=months.clone();var temp=d1.clone();var orient=(d1>d2)?-1:+1;this.years=d2.getFullYear()-d1.getFullYear();temp.addYears(this.years);if(orient==+1){if(temp>d2){if(this.years!==0){this.years--;}}}else{if(temp<d2){if(this.years!==0){this.years++;}}}
+d1.addYears(this.years);if(orient==+1){while(d1<d2&&d1.clone().addDays(Date.getDaysInMonth(d1.getYear(),d1.getMonth()))<d2){d1.addMonths(1);this.months++;}}
+else{while(d1>d2&&d1.clone().addDays(-d1.getDaysInMonth())>d2){d1.addMonths(-1);this.months--;}}
+var diff=d2-d1;if(diff!==0){var ts=new TimeSpan(diff);this.setDays(ts.getDays());this.setHours(ts.getHours());this.setMinutes(ts.getMinutes());this.setSeconds(ts.getSeconds());this.setMilliseconds(ts.getMilliseconds());}}
+return this;};
Index: /trunk/prototype/plugins/datejs/date-pt-BR.js
===================================================================
--- /trunk/prototype/plugins/datejs/date-pt-BR.js	(revision 5341)
+++ /trunk/prototype/plugins/datejs/date-pt-BR.js	(revision 7143)
@@ -1,48 +1,71 @@
 /**
- * Version: 1.0 Alpha-1 
- * Build Date: 13-Nov-2007
- * Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
- * License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
- * Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
+ * @version: 1.0 Alpha-1
+ * @author: Coolite Inc. http://www.coolite.com/
+ * @date: 2008-05-13
+ * @copyright: Copyright (c) 2006-2008, Coolite Inc. (http://www.coolite.com/). All rights reserved.
+ * @license: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
+ * @website: http://www.datejs.com/
  */
-Date.CultureInfo={name:"pt-BR",englishName:"Portuguese (Brazil)",nativeName:"PortuguÃªs (Brasil)",dayNames:["domingo","segunda-feira","terÃ§a-feira","quarta-feira","quinta-feira","sexta-feira","sÃ¡bado"],abbreviatedDayNames:["dom","seg","ter","qua","qui","sex","sÃ¡b"],shortestDayNames:["dom","seg","ter","qua","qui","sex","sÃ¡b"],firstLetterDayNames:["d","s","t","q","q","s","s"],monthNames:["janeiro","fevereiro","marÃ§o","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro"],abbreviatedMonthNames:["jan","fev","mar","abr","mai","jun","jul","ago","set","out","nov","dez"],amDesignator:"",pmDesignator:"",firstDayOfWeek:0,twoDigitYearMax:2029,dateElementOrder:"dmy",formatPatterns:{shortDate:"d/M/yyyy",longDate:"dddd, d' de 'MMMM' de 'yyyy",shortTime:"H:mm",longTime:"H:mm:ss",fullDateTime:"dddd, d' de 'MMMM' de 'yyyy H:mm:ss",sortableDateTime:"yyyy-MM-ddTHH:mm:ss",universalSortableDateTime:"yyyy-MM-dd HH:mm:ssZ",rfc1123:"ddd, dd MMM yyyy HH:mm:ss GMT",monthDay:"dd' de 'MMMM",yearMonth:"MMMM' de 'yyyy"},regexPatterns:{jan:/^jan(eiro)?/i,feb:/^fev(ereiro)?/i,mar:/^mar(Ã§o)?/i,apr:/^abr(il)?/i,may:/^mai(o)?/i,jun:/^jun(ho)?/i,jul:/^jul(ho)?/i,aug:/^ago(sto)?/i,sep:/^set(embro)?/i,oct:/^out(ubro)?/i,nov:/^nov(embro)?/i,dec:/^dez(embro)?/i,sun:/^domingo/i,mon:/^segunda-feira/i,tue:/^terÃ§a-feira/i,wed:/^quarta-feira/i,thu:/^quinta-feira/i,fri:/^sexta-feira/i,sat:/^sÃ¡bado/i,future:/^next/i,past:/^last|past|prev(ious)?/i,add:/^(\+|after|from)/i,subtract:/^(\-|before|ago)/i,yesterday:/^yesterday/i,today:/^t(oday)?/i,tomorrow:/^tomorrow/i,now:/^n(ow)?/i,millisecond:/^ms|milli(second)?s?/i,second:/^sec(ond)?s?/i,minute:/^min(ute)?s?/i,hour:/^h(ou)?rs?/i,week:/^w(ee)?k/i,month:/^m(o(nth)?s?)?/i,day:/^d(ays?)?/i,year:/^y((ea)?rs?)?/i,shortMeridian:/^(a|p)/i,longMeridian:/^(a\.?m?\.?|p\.?m?\.?)/i,timezone:/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt)/i,ordinalSuffix:/^\s*(st|nd|rd|th)/i,timeContext:/^\s*(\:|a|p)/i},abbreviatedTimeZoneStandard:{GMT:"-000",EST:"-0400",CST:"-0500",MST:"-0600",PST:"-0700"},abbreviatedTimeZoneDST:{GMT:"-000",EDT:"-0500",CDT:"-0600",MDT:"-0700",PDT:"-0800"}};
-Date.getMonthNumberFromName=function(name){var n=Date.CultureInfo.monthNames,m=Date.CultureInfo.abbreviatedMonthNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
-return-1;};Date.getDayNumberFromName=function(name){var n=Date.CultureInfo.dayNames,m=Date.CultureInfo.abbreviatedDayNames,o=Date.CultureInfo.shortestDayNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
-return-1;};Date.isLeapYear=function(year){return(((year%4===0)&&(year%100!==0))||(year%400===0));};Date.getDaysInMonth=function(year,month){return[31,(Date.isLeapYear(year)?29:28),31,30,31,30,31,31,30,31,30,31][month];};Date.getTimezoneOffset=function(s,dst){return(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST[s.toUpperCase()]:Date.CultureInfo.abbreviatedTimeZoneStandard[s.toUpperCase()];};Date.getTimezoneAbbreviation=function(offset,dst){var n=(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST:Date.CultureInfo.abbreviatedTimeZoneStandard,p;for(p in n){if(n[p]===offset){return p;}}
-return null;};Date.prototype.clone=function(){return new Date(this.getTime());};Date.prototype.compareTo=function(date){if(isNaN(this)){throw new Error(this);}
-if(date instanceof Date&&!isNaN(date)){return(this>date)?1:(this<date)?-1:0;}else{throw new TypeError(date);}};Date.prototype.equals=function(date){return(this.compareTo(date)===0);};Date.prototype.between=function(start,end){var t=this.getTime();return t>=start.getTime()&&t<=end.getTime();};Date.prototype.addMilliseconds=function(value){this.setMilliseconds(this.getMilliseconds()+value);return this;};Date.prototype.addSeconds=function(value){return this.addMilliseconds(value*1000);};Date.prototype.addMinutes=function(value){return this.addMilliseconds(value*60000);};Date.prototype.addHours=function(value){return this.addMilliseconds(value*3600000);};Date.prototype.addDays=function(value){return this.addMilliseconds(value*86400000);};Date.prototype.addWeeks=function(value){return this.addMilliseconds(value*604800000);};Date.prototype.addMonths=function(value){var n=this.getDate();this.setDate(1);this.setMonth(this.getMonth()+value);this.setDate(Math.min(n,this.getDaysInMonth()));return this;};Date.prototype.addYears=function(value){return this.addMonths(value*12);};Date.prototype.add=function(config){if(typeof config=="number"){this._orient=config;return this;}
-var x=config;if(x.millisecond||x.milliseconds){this.addMilliseconds(x.millisecond||x.milliseconds);}
-if(x.second||x.seconds){this.addSeconds(x.second||x.seconds);}
-if(x.minute||x.minutes){this.addMinutes(x.minute||x.minutes);}
-if(x.hour||x.hours){this.addHours(x.hour||x.hours);}
-if(x.month||x.months){this.addMonths(x.month||x.months);}
-if(x.year||x.years){this.addYears(x.year||x.years);}
-if(x.day||x.days){this.addDays(x.day||x.days);}
-return this;};Date._validate=function(value,min,max,name){if(typeof value!="number"){throw new TypeError(value+" is not a Number.");}else if(value<min||value>max){throw new RangeError(value+" is not a valid value for "+name+".");}
-return true;};Date.validateMillisecond=function(n){return Date._validate(n,0,999,"milliseconds");};Date.validateSecond=function(n){return Date._validate(n,0,59,"seconds");};Date.validateMinute=function(n){return Date._validate(n,0,59,"minutes");};Date.validateHour=function(n){return Date._validate(n,0,23,"hours");};Date.validateDay=function(n,year,month){return Date._validate(n,1,Date.getDaysInMonth(year,month),"days");};Date.validateMonth=function(n){return Date._validate(n,0,11,"months");};Date.validateYear=function(n){return Date._validate(n,1,9999,"seconds");};Date.prototype.set=function(config){var x=config;if(!x.millisecond&&x.millisecond!==0){x.millisecond=-1;}
-if(!x.second&&x.second!==0){x.second=-1;}
-if(!x.minute&&x.minute!==0){x.minute=-1;}
-if(!x.hour&&x.hour!==0){x.hour=-1;}
-if(!x.day&&x.day!==0){x.day=-1;}
-if(!x.month&&x.month!==0){x.month=-1;}
-if(!x.year&&x.year!==0){x.year=-1;}
-if(x.millisecond!=-1&&Date.validateMillisecond(x.millisecond)){this.addMilliseconds(x.millisecond-this.getMilliseconds());}
-if(x.second!=-1&&Date.validateSecond(x.second)){this.addSeconds(x.second-this.getSeconds());}
-if(x.minute!=-1&&Date.validateMinute(x.minute)){this.addMinutes(x.minute-this.getMinutes());}
-if(x.hour!=-1&&Date.validateHour(x.hour)){this.addHours(x.hour-this.getHours());}
-if(x.month!==-1&&Date.validateMonth(x.month)){this.addMonths(x.month-this.getMonth());}
-if(x.year!=-1&&Date.validateYear(x.year)){this.addYears(x.year-this.getFullYear());}
-if(x.day!=-1&&Date.validateDay(x.day,this.getFullYear(),this.getMonth())){this.addDays(x.day-this.getDate());}
-if(x.timezone){this.setTimezone(x.timezone);}
-if(x.timezoneOffset){this.setTimezoneOffset(x.timezoneOffset);}
-return this;};Date.prototype.clearTime=function(){this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};Date.prototype.isLeapYear=function(){var y=this.getFullYear();return(((y%4===0)&&(y%100!==0))||(y%400===0));};Date.prototype.isWeekday=function(){return!(this.is().sat()||this.is().sun());};Date.prototype.getDaysInMonth=function(){return Date.getDaysInMonth(this.getFullYear(),this.getMonth());};Date.prototype.moveToFirstDayOfMonth=function(){return this.set({day:1});};Date.prototype.moveToLastDayOfMonth=function(){return this.set({day:this.getDaysInMonth()});};Date.prototype.moveToDayOfWeek=function(day,orient){var diff=(day-this.getDay()+7*(orient||+1))%7;return this.addDays((diff===0)?diff+=7*(orient||+1):diff);};Date.prototype.moveToMonth=function(month,orient){var diff=(month-this.getMonth()+12*(orient||+1))%12;return this.addMonths((diff===0)?diff+=12*(orient||+1):diff);};Date.prototype.getDayOfYear=function(){return Math.floor((this-new Date(this.getFullYear(),0,1))/86400000);};Date.prototype.getWeekOfYear=function(firstDayOfWeek){var y=this.getFullYear(),m=this.getMonth(),d=this.getDate();var dow=firstDayOfWeek||Date.CultureInfo.firstDayOfWeek;var offset=7+1-new Date(y,0,1).getDay();if(offset==8){offset=1;}
-var daynum=((Date.UTC(y,m,d,0,0,0)-Date.UTC(y,0,1,0,0,0))/86400000)+1;var w=Math.floor((daynum-offset+7)/7);if(w===dow){y--;var prevOffset=7+1-new Date(y,0,1).getDay();if(prevOffset==2||prevOffset==8){w=53;}else{w=52;}}
-return w;};Date.prototype.isDST=function(){console.log('isDST');return this.toString().match(/(E|C|M|P)(S|D)T/)[2]=="D";};Date.prototype.getTimezone=function(){return Date.getTimezoneAbbreviation(this.getUTCOffset,this.isDST());};Date.prototype.setTimezoneOffset=function(s){var here=this.getTimezoneOffset(),there=Number(s)*-6/10;this.addMinutes(there-here);return this;};Date.prototype.setTimezone=function(s){return this.setTimezoneOffset(Date.getTimezoneOffset(s));};Date.prototype.getUTCOffset=function(){var n=this.getTimezoneOffset()*-10/6,r;if(n<0){r=(n-10000).toString();return r[0]+r.substr(2);}else{r=(n+10000).toString();return"+"+r.substr(1);}};Date.prototype.getDayName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedDayNames[this.getDay()]:Date.CultureInfo.dayNames[this.getDay()];};Date.prototype.getMonthName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedMonthNames[this.getMonth()]:Date.CultureInfo.monthNames[this.getMonth()];};Date.prototype._toString=Date.prototype.toString;Date.prototype.toString=function(format){var self=this;var p=function p(s){return(s.toString().length==1)?"0"+s:s;};return format?format.replace(/dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?/g,function(format){switch(format){case"hh":return p(self.getHours()<13?self.getHours():(self.getHours()-12));case"h":return self.getHours()<13?self.getHours():(self.getHours()-12);case"HH":return p(self.getHours());case"H":return self.getHours();case"mm":return p(self.getMinutes());case"m":return self.getMinutes();case"ss":return p(self.getSeconds());case"s":return self.getSeconds();case"yyyy":return self.getFullYear();case"yy":return self.getFullYear().toString().substring(2,4);case"dddd":return self.getDayName();case"ddd":return self.getDayName(true);case"dd":return p(self.getDate());case"d":return self.getDate().toString();case"MMMM":return self.getMonthName();case"MMM":return self.getMonthName(true);case"MM":return p((self.getMonth()+1));case"M":return self.getMonth()+1;case"t":return self.getHours()<12?Date.CultureInfo.amDesignator.substring(0,1):Date.CultureInfo.pmDesignator.substring(0,1);case"tt":return self.getHours()<12?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;case"zzz":case"zz":case"z":return"";}}):this._toString();};
-Date.now=function(){return new Date();};Date.today=function(){return Date.now().clearTime();};Date.prototype._orient=+1;Date.prototype.next=function(){this._orient=+1;return this;};Date.prototype.last=Date.prototype.prev=Date.prototype.previous=function(){this._orient=-1;return this;};Date.prototype._is=false;Date.prototype.is=function(){this._is=true;return this;};Number.prototype._dateElement="day";Number.prototype.fromNow=function(){var c={};c[this._dateElement]=this;return Date.now().add(c);};Number.prototype.ago=function(){var c={};c[this._dateElement]=this*-1;return Date.now().add(c);};(function(){var $D=Date.prototype,$N=Number.prototype;var dx=("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),mx=("january february march april may june july august september october november december").split(/\s/),px=("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),de;var df=function(n){return function(){if(this._is){this._is=false;return this.getDay()==n;}
-return this.moveToDayOfWeek(n,this._orient);};};for(var i=0;i<dx.length;i++){$D[dx[i]]=$D[dx[i].substring(0,3)]=df(i);}
+Date.CultureInfo={name:"pt-BR",englishName:"Portuguese (Brazil)",nativeName:"PortuguÃªs (Brasil)",dayNames:["domingo","segunda-feira","terÃ§a-feira","quarta-feira","quinta-feira","sexta-feira","sÃ¡bado"],abbreviatedDayNames:["dom","seg","ter","qua","qui","sex","sÃ¡b"],shortestDayNames:["dom","seg","ter","qua","qui","sex","sÃ¡b"],firstLetterDayNames:["d","s","t","q","q","s","s"],monthNames:["janeiro","fevereiro","marÃ§o","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro"],abbreviatedMonthNames:["jan","fev","mar","abr","mai","jun","jul","ago","set","out","nov","dez"],amDesignator:"",pmDesignator:"",firstDayOfWeek:0,twoDigitYearMax:2029,dateElementOrder:"dmy",formatPatterns:{shortDate:"d/M/yyyy",longDate:"dddd, d' de 'MMMM' de 'yyyy",shortTime:"H:mm",longTime:"H:mm:ss",fullDateTime:"dddd, d' de 'MMMM' de 'yyyy H:mm:ss",sortableDateTime:"yyyy-MM-ddTHH:mm:ss",universalSortableDateTime:"yyyy-MM-dd HH:mm:ssZ",rfc1123:"ddd, dd MMM yyyy HH:mm:ss GMT",monthDay:"dd' de 'MMMM",yearMonth:"MMMM' de 'yyyy"},regexPatterns:{jan:/^jan(eiro)?/i,feb:/^fev(ereiro)?/i,mar:/^mar(Ã§o)?/i,apr:/^abr(il)?/i,may:/^mai(o)?/i,jun:/^jun(ho)?/i,jul:/^jul(ho)?/i,aug:/^ago(sto)?/i,sep:/^set(embro)?/i,oct:/^out(ubro)?/i,nov:/^nov(embro)?/i,dec:/^dez(embro)?/i,sun:/^domingo/i,mon:/^segunda-feira/i,tue:/^terÃ§a-feira/i,wed:/^quarta-feira/i,thu:/^quinta-feira/i,fri:/^sexta-feira/i,sat:/^sÃ¡bado/i,future:/^next/i,past:/^last|past|prev(ious)?/i,add:/^(\+|aft(er)?|from|hence)/i,subtract:/^(\-|bef(ore)?|ago)/i,yesterday:/^yes(terday)?/i,today:/^t(od(ay)?)?/i,tomorrow:/^tom(orrow)?/i,now:/^n(ow)?/i,millisecond:/^ms|milli(second)?s?/i,second:/^sec(ond)?s?/i,minute:/^mn|min(ute)?s?/i,hour:/^h(our)?s?/i,week:/^w(eek)?s?/i,month:/^m(onth)?s?/i,day:/^d(ay)?s?/i,year:/^y(ear)?s?/i,shortMeridian:/^(a|p)/i,longMeridian:/^(a\.?m?\.?|p\.?m?\.?)/i,timezone:/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt|utc)/i,ordinalSuffix:/^\s*(st|nd|rd|th)/i,timeContext:/^\s*(\:|a(?!u|p)|p)/i},timezones:[{name:"UTC",offset:"-000"},{name:"GMT",offset:"-000"},{name:"EST",offset:"-0500"},{name:"EDT",offset:"-0400"},{name:"CST",offset:"-0600"},{name:"CDT",offset:"-0500"},{name:"MST",offset:"-0700"},{name:"MDT",offset:"-0600"},{name:"PST",offset:"-0800"},{name:"PDT",offset:"-0700"}]};
+(function(){var $D=Date,$P=$D.prototype,$C=$D.CultureInfo,p=function(s,l){if(!l){l=2;}
+return("000"+s).slice(l*-1);};$P.clearTime=function(){this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};$P.setTimeToNow=function(){var n=new Date();this.setHours(n.getHours());this.setMinutes(n.getMinutes());this.setSeconds(n.getSeconds());this.setMilliseconds(n.getMilliseconds());return this;};$D.today=function(){return new Date().clearTime();};$D.compare=function(date1,date2){if(isNaN(date1)||isNaN(date2)){throw new Error(date1+" - "+date2);}else if(date1 instanceof Date&&date2 instanceof Date){return(date1<date2)?-1:(date1>date2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s||o[i].toLowerCase()==s){return i;}}
+return-1;};$D.getMonthNumberFromName=function(name){var n=$C.monthNames,m=$C.abbreviatedMonthNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
+return-1;};$D.isLeapYear=function(year){return((year%4===0&&year%100!==0)||year%400===0);};$D.getDaysInMonth=function(year,month){return[31,($D.isLeapYear(year)?29:28),31,30,31,30,31,31,30,31,30,31][month];};$D.getTimezoneAbbreviation=function(offset){var z=$C.timezones,p;for(var i=0;i<z.length;i++){if(z[i].offset===offset){return z[i].name;}}
+return null;};$D.getTimezoneOffset=function(name){var z=$C.timezones,p;for(var i=0;i<z.length;i++){if(z[i].name===name.toUpperCase()){return z[i].offset;}}
+return null;};$P.clone=function(){return new Date(this.getTime());};$P.compareTo=function(date){return Date.compare(this,date);};$P.equals=function(date){return Date.equals(this,date||new Date());};$P.between=function(start,end){return this.getTime()>=start.getTime()&&this.getTime()<=end.getTime();};$P.isAfter=function(date){return this.compareTo(date||new Date())===1;};$P.isBefore=function(date){return(this.compareTo(date||new Date())===-1);};$P.isToday=function(){return this.isSameDay(new Date());};$P.isSameDay=function(date){return this.clone().clearTime().equals(date.clone().clearTime());};$P.addMilliseconds=function(value){this.setMilliseconds(this.getMilliseconds()+value);return this;};$P.addSeconds=function(value){return this.addMilliseconds(value*1000);};$P.addMinutes=function(value){return this.addMilliseconds(value*60000);};$P.addHours=function(value){return this.addMilliseconds(value*3600000);};$P.addDays=function(value){this.setDate(this.getDate()+value);return this;};$P.addWeeks=function(value){return this.addDays(value*7);};$P.addMonths=function(value){var n=this.getDate();this.setDate(1);this.setMonth(this.getMonth()+value);this.setDate(Math.min(n,$D.getDaysInMonth(this.getFullYear(),this.getMonth())));return this;};$P.addYears=function(value){return this.addMonths(value*12);};$P.add=function(config){if(typeof config=="number"){this._orient=config;return this;}
+var x=config;if(x.milliseconds){this.addMilliseconds(x.milliseconds);}
+if(x.seconds){this.addSeconds(x.seconds);}
+if(x.minutes){this.addMinutes(x.minutes);}
+if(x.hours){this.addHours(x.hours);}
+if(x.weeks){this.addWeeks(x.weeks);}
+if(x.months){this.addMonths(x.months);}
+if(x.years){this.addYears(x.years);}
+if(x.days){this.addDays(x.days);}
+return this;};var $y,$m,$d;$P.getWeek=function(){var a,b,c,d,e,f,g,n,s,w;$y=(!$y)?this.getFullYear():$y;$m=(!$m)?this.getMonth()+1:$m;$d=(!$d)?this.getDate():$d;if($m<=2){a=$y-1;b=(a/4|0)-(a/100|0)+(a/400|0);c=((a-1)/4|0)-((a-1)/100|0)+((a-1)/400|0);s=b-c;e=0;f=$d-1+(31*($m-1));}else{a=$y;b=(a/4|0)-(a/100|0)+(a/400|0);c=((a-1)/4|0)-((a-1)/100|0)+((a-1)/400|0);s=b-c;e=s+1;f=$d+((153*($m-3)+2)/5)+58+s;}
+g=(a+b)%7;d=(f+g-e)%7;n=(f+3-d)|0;if(n<0){w=53-((g-s)/5|0);}else if(n>364+s){w=1;}else{w=(n/7|0)+1;}
+$y=$m=$d=null;return w;};$P.getISOWeek=function(){$y=this.getUTCFullYear();$m=this.getUTCMonth()+1;$d=this.getUTCDate();return p(this.getWeek());};$P.setWeek=function(n){return this.moveToDayOfWeek(1).addWeeks(n-this.getWeek());};$D._validate=function(n,min,max,name){if(typeof n=="undefined"){return false;}else if(typeof n!="number"){throw new TypeError(n+" is not a Number.");}else if(n<min||n>max){throw new RangeError(n+" is not a valid value for "+name+".");}
+return true;};$D.validateMillisecond=function(value){return $D._validate(value,0,999,"millisecond");};$D.validateSecond=function(value){return $D._validate(value,0,59,"second");};$D.validateMinute=function(value){return $D._validate(value,0,59,"minute");};$D.validateHour=function(value){return $D._validate(value,0,23,"hour");};$D.validateDay=function(value,year,month){return $D._validate(value,1,$D.getDaysInMonth(year,month),"day");};$D.validateMonth=function(value){return $D._validate(value,0,11,"month");};$D.validateYear=function(value){return $D._validate(value,0,9999,"year");};$P.set=function(config){if($D.validateMillisecond(config.millisecond)){this.addMilliseconds(config.millisecond-this.getMilliseconds());}
+if($D.validateSecond(config.second)){this.addSeconds(config.second-this.getSeconds());}
+if($D.validateMinute(config.minute)){this.addMinutes(config.minute-this.getMinutes());}
+if($D.validateHour(config.hour)){this.addHours(config.hour-this.getHours());}
+if($D.validateMonth(config.month)){this.addMonths(config.month-this.getMonth());}
+if($D.validateYear(config.year)){this.addYears(config.year-this.getFullYear());}
+if($D.validateDay(config.day,this.getFullYear(),this.getMonth())){this.addDays(config.day-this.getDate());}
+if(config.timezone){this.setTimezone(config.timezone);}
+if(config.timezoneOffset){this.setTimezoneOffset(config.timezoneOffset);}
+if(config.week&&$D._validate(config.week,0,53,"week")){this.setWeek(config.week);}
+return this;};$P.moveToFirstDayOfMonth=function(){return this.set({day:1});};$P.moveToLastDayOfMonth=function(){return this.set({day:$D.getDaysInMonth(this.getFullYear(),this.getMonth())});};$P.moveToNthOccurrence=function(dayOfWeek,occurrence){var shift=0;if(occurrence>0){shift=occurrence-1;}
+else if(occurrence===-1){this.moveToLastDayOfMonth();if(this.getDay()!==dayOfWeek){this.moveToDayOfWeek(dayOfWeek,-1);}
+return this;}
+return this.moveToFirstDayOfMonth().addDays(-1).moveToDayOfWeek(dayOfWeek,+1).addWeeks(shift);};$P.moveToDayOfWeek=function(dayOfWeek,orient){var diff=(dayOfWeek-this.getDay()+7*(orient||+1))%7;return this.addDays((diff===0)?diff+=7*(orient||+1):diff);};$P.moveToMonth=function(month,orient){var diff=(month-this.getMonth()+12*(orient||+1))%12;return this.addMonths((diff===0)?diff+=12*(orient||+1):diff);};$P.getOrdinalNumber=function(){return Math.ceil((this.clone().clearTime()-new Date(this.getFullYear(),0,1))/86400000)+1;};$P.getTimezone=function(){return $D.getTimezoneAbbreviation(this.getUTCOffset());};$P.setTimezoneOffset=function(offset){var here=this.getTimezoneOffset(),there=Number(offset)*-6/10;return this.addMinutes(there-here);};$P.setTimezone=function(offset){return this.setTimezoneOffset($D.getTimezoneOffset(offset));};$P.hasDaylightSavingTime=function(){return(Date.today().set({month:0,day:1}).getTimezoneOffset()!==Date.today().set({month:6,day:1}).getTimezoneOffset());};$P.isDaylightSavingTime=function(){return(this.hasDaylightSavingTime()&&new Date().getTimezoneOffset()===Date.today().set({month:6,day:1}).getTimezoneOffset());};$P.getUTCOffset=function(){var n=this.getTimezoneOffset()*-10/6,r;if(n<0){r=(n-10000).toString();return r.charAt(0)+r.substr(2);}else{r=(n+10000).toString();return"+"+r.substr(1);}};$P.getElapsed=function(date){return(date||new Date())-this;};if(!$P.toISOString){$P.toISOString=function(){function f(n){return n<10?'0'+n:n;}
+return'"'+this.getUTCFullYear()+'-'+
+f(this.getUTCMonth()+1)+'-'+
+f(this.getUTCDate())+'T'+
+f(this.getUTCHours())+':'+
+f(this.getUTCMinutes())+':'+
+f(this.getUTCSeconds())+'Z"';};}
+$P._toString=$P.toString;$P.toString=function(format){var x=this;if(format&&format.length==1){var c=$C.formatPatterns;x.t=x.toString;switch(format){case"d":return x.t(c.shortDate);case"D":return x.t(c.longDate);case"F":return x.t(c.fullDateTime);case"m":return x.t(c.monthDay);case"r":return x.t(c.rfc1123);case"s":return x.t(c.sortableDateTime);case"t":return x.t(c.shortTime);case"T":return x.t(c.longTime);case"u":return x.t(c.universalSortableDateTime);case"y":return x.t(c.yearMonth);}}
+var ord=function(n){switch(n*1){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}};return format?format.replace(/(\\)?(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|S)/g,function(m){if(m.charAt(0)==="\\"){return m.replace("\\","");}
+x.h=x.getHours;switch(m){case"hh":return p(x.h()<13?(x.h()===0?12:x.h()):(x.h()-12));case"h":return x.h()<13?(x.h()===0?12:x.h()):(x.h()-12);case"HH":return p(x.h());case"H":return x.h();case"mm":return p(x.getMinutes());case"m":return x.getMinutes();case"ss":return p(x.getSeconds());case"s":return x.getSeconds();case"yyyy":return p(x.getFullYear(),4);case"yy":return p(x.getFullYear());case"dddd":return $C.dayNames[x.getDay()];case"ddd":return $C.abbreviatedDayNames[x.getDay()];case"dd":return p(x.getDate());case"d":return x.getDate();case"MMMM":return $C.monthNames[x.getMonth()];case"MMM":return $C.abbreviatedMonthNames[x.getMonth()];case"MM":return p((x.getMonth()+1));case"M":return x.getMonth()+1;case"t":return x.h()<12?$C.amDesignator.substring(0,1):$C.pmDesignator.substring(0,1);case"tt":return x.h()<12?$C.amDesignator:$C.pmDesignator;case"S":return ord(x.getDate());default:return m;}}):this._toString();};}());
+(function(){var $D=Date,$P=$D.prototype,$C=$D.CultureInfo,$N=Number.prototype;$P._orient=+1;$P._nth=null;$P._is=false;$P._same=false;$P._isSecond=false;$N._dateElement="day";$P.next=function(){this._orient=+1;return this;};$D.next=function(){return $D.today().next();};$P.last=$P.prev=$P.previous=function(){this._orient=-1;return this;};$D.last=$D.prev=$D.previous=function(){return $D.today().last();};$P.is=function(){this._is=true;return this;};$P.same=function(){this._same=true;this._isSecond=false;return this;};$P.today=function(){return this.same().day();};$P.weekday=function(){if(this._is){this._is=false;return(!this.is().sat()&&!this.is().sun());}
+return false;};$P.at=function(time){return(typeof time==="string")?$D.parse(this.toString("d")+" "+time):this.set(time);};$N.fromNow=$N.after=function(date){var c={};c[this._dateElement]=this;return((!date)?new Date():date.clone()).add(c);};$N.ago=$N.before=function(date){var c={};c[this._dateElement]=this*-1;return((!date)?new Date():date.clone()).add(c);};var dx=("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),mx=("january february march april may june july august september october november december").split(/\s/),px=("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),pxf=("Milliseconds Seconds Minutes Hours Date Week Month FullYear").split(/\s/),nth=("final first second third fourth fifth").split(/\s/),de;$P.toObject=function(){var o={};for(var i=0;i<px.length;i++){o[px[i].toLowerCase()]=this["get"+pxf[i]]();}
+return o;};$D.fromObject=function(config){config.week=null;return Date.today().set(config);};var df=function(n){return function(){if(this._is){this._is=false;return this.getDay()==n;}
+if(this._nth!==null){if(this._isSecond){this.addSeconds(this._orient*-1);}
+this._isSecond=false;var ntemp=this._nth;this._nth=null;var temp=this.clone().moveToLastDayOfMonth();this.moveToNthOccurrence(n,ntemp);if(this>temp){throw new RangeError($D.getDayName(n)+" does not occur "+ntemp+" times in the month of "+$D.getMonthName(temp.getMonth())+" "+temp.getFullYear()+".");}
+return this;}
+return this.moveToDayOfWeek(n,this._orient);};};var sdf=function(n){return function(){var t=$D.today(),shift=n-t.getDay();if(n===0&&$C.firstDayOfWeek===1&&t.getDay()!==0){shift=shift+7;}
+return t.addDays(shift);};};for(var i=0;i<dx.length;i++){$D[dx[i].toUpperCase()]=$D[dx[i].toUpperCase().substring(0,3)]=i;$D[dx[i]]=$D[dx[i].substring(0,3)]=sdf(i);$P[dx[i]]=$P[dx[i].substring(0,3)]=df(i);}
 var mf=function(n){return function(){if(this._is){this._is=false;return this.getMonth()===n;}
-return this.moveToMonth(n,this._orient);};};for(var j=0;j<mx.length;j++){$D[mx[j]]=$D[mx[j].substring(0,3)]=mf(j);}
-var ef=function(j){return function(){if(j.substring(j.length-1)!="s"){j+="s";}
-return this["add"+j](this._orient);};};var nf=function(n){return function(){this._dateElement=n;return this;};};for(var k=0;k<px.length;k++){de=px[k].toLowerCase();$D[de]=$D[de+"s"]=ef(px[k]);$N[de]=$N[de+"s"]=nf(de);}}());Date.prototype.toJSONString=function(){return this.toString("yyyy-MM-ddThh:mm:ssZ");};Date.prototype.toShortDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortDatePattern);};Date.prototype.toLongDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.longDatePattern);};Date.prototype.toShortTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortTimePattern);};Date.prototype.toLongTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.longTimePattern);};Date.prototype.getOrdinal=function(){switch(this.getDate()){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}};
+return this.moveToMonth(n,this._orient);};};var smf=function(n){return function(){return $D.today().set({month:n,day:1});};};for(var j=0;j<mx.length;j++){$D[mx[j].toUpperCase()]=$D[mx[j].toUpperCase().substring(0,3)]=j;$D[mx[j]]=$D[mx[j].substring(0,3)]=smf(j);$P[mx[j]]=$P[mx[j].substring(0,3)]=mf(j);}
+var ef=function(j){return function(){if(this._isSecond){this._isSecond=false;return this;}
+if(this._same){this._same=this._is=false;var o1=this.toObject(),o2=(arguments[0]||new Date()).toObject(),v="",k=j.toLowerCase();for(var m=(px.length-1);m>-1;m--){v=px[m].toLowerCase();if(o1[v]!=o2[v]){return false;}
+if(k==v){break;}}
+return true;}
+if(j.substring(j.length-1)!="s"){j+="s";}
+return this["add"+j](this._orient);};};var nf=function(n){return function(){this._dateElement=n;return this;};};for(var k=0;k<px.length;k++){de=px[k].toLowerCase();$P[de]=$P[de+"s"]=ef(px[k]);$N[de]=$N[de+"s"]=nf(de);}
+$P._ss=ef("Second");var nthfn=function(n){return function(dayOfWeek){if(this._same){return this._ss(arguments[0]);}
+if(dayOfWeek||dayOfWeek===0){return this.moveToNthOccurrence(dayOfWeek,n);}
+this._nth=n;if(n===2&&(dayOfWeek===undefined||dayOfWeek===null)){this._isSecond=true;return this.addSeconds(this._orient);}
+return this;};};for(var l=0;l<nth.length;l++){$P[nth[l]]=(l===0)?nthfn(-1):nthfn(l);}}());
 (function(){Date.Parsing={Exception:function(s){this.message="Parse error at '"+s.substring(0,10)+" ...'";}};var $P=Date.Parsing;var _=$P.Operators={rtoken:function(r){return function(s){var mx=s.match(r);if(mx){return([mx[0],s.substring(mx[0].length)]);}else{throw new $P.Exception(s);}};},token:function(s){return function(s){return _.rtoken(new RegExp("^\s*"+s+"\s*"))(s);};},stoken:function(s){return _.rtoken(new RegExp("^"+s));},until:function(p){return function(s){var qx=[],rx=null;while(s.length){try{rx=p.call(this,s);}catch(e){qx.push(rx[0]);s=rx[1];continue;}
 break;}
@@ -79,26 +102,44 @@
 return rx;};}};var _generator=function(op){return function(){var args=null,rx=[];if(arguments.length>1){args=Array.prototype.slice.call(arguments);}else if(arguments[0]instanceof Array){args=arguments[0];}
 if(args){for(var i=0,px=args.shift();i<px.length;i++){args.unshift(px[i]);rx.push(op.apply(null,args));args.shift();return rx;}}else{return op.apply(null,arguments);}};};var gx="optional not ignore cache".split(/\s/);for(var i=0;i<gx.length;i++){_[gx[i]]=_generator(_[gx[i]]);}
-var _vector=function(op){return function(){if(arguments[0]instanceof Array){return op.apply(null,arguments[0]);}else{return op.apply(null,arguments);}};};var vx="each any all".split(/\s/);for(var j=0;j<vx.length;j++){_[vx[j]]=_vector(_[vx[j]]);}}());(function(){var flattenAndCompact=function(ax){var rx=[];for(var i=0;i<ax.length;i++){if(ax[i]instanceof Array){rx=rx.concat(flattenAndCompact(ax[i]));}else{if(ax[i]){rx.push(ax[i]);}}}
-return rx;};Date.Grammar={};Date.Translator={hour:function(s){return function(){this.hour=Number(s);};},minute:function(s){return function(){this.minute=Number(s);};},second:function(s){return function(){this.second=Number(s);};},meridian:function(s){return function(){this.meridian=s.slice(0,1).toLowerCase();};},timezone:function(s){return function(){var n=s.replace(/[^\d\+\-]/g,"");if(n.length){this.timezoneOffset=Number(n);}else{this.timezone=s.toLowerCase();}};},day:function(x){var s=x[0];return function(){this.day=Number(s.match(/\d+/)[0]);};},month:function(s){return function(){this.month=((s.length==3)?Date.getMonthNumberFromName(s):(Number(s)-1));};},year:function(s){return function(){var n=Number(s);this.year=((s.length>2)?n:(n+(((n+2000)<Date.CultureInfo.twoDigitYearMax)?2000:1900)));};},rday:function(s){return function(){switch(s){case"yesterday":this.days=-1;break;case"tomorrow":this.days=1;break;case"today":this.days=0;break;case"now":this.days=0;this.now=true;break;}};},finishExact:function(x){x=(x instanceof Array)?x:[x];var now=new Date();this.year=now.getFullYear();this.month=now.getMonth();this.day=1;this.hour=0;this.minute=0;this.second=0;for(var i=0;i<x.length;i++){if(x[i]){x[i].call(this);}}
-this.hour=(this.meridian=="p"&&this.hour<13)?this.hour+12:this.hour;if(this.day>Date.getDaysInMonth(this.year,this.month)){throw new RangeError(this.day+" is not a valid value for days.");}
+var _vector=function(op){return function(){if(arguments[0]instanceof Array){return op.apply(null,arguments[0]);}else{return op.apply(null,arguments);}};};var vx="each any all".split(/\s/);for(var j=0;j<vx.length;j++){_[vx[j]]=_vector(_[vx[j]]);}}());(function(){var $D=Date,$P=$D.prototype,$C=$D.CultureInfo;var flattenAndCompact=function(ax){var rx=[];for(var i=0;i<ax.length;i++){if(ax[i]instanceof Array){rx=rx.concat(flattenAndCompact(ax[i]));}else{if(ax[i]){rx.push(ax[i]);}}}
+return rx;};$D.Grammar={};$D.Translator={hour:function(s){return function(){this.hour=Number(s);};},minute:function(s){return function(){this.minute=Number(s);};},second:function(s){return function(){this.second=Number(s);};},meridian:function(s){return function(){this.meridian=s.slice(0,1).toLowerCase();};},timezone:function(s){return function(){var n=s.replace(/[^\d\+\-]/g,"");if(n.length){this.timezoneOffset=Number(n);}else{this.timezone=s.toLowerCase();}};},day:function(x){var s=x[0];return function(){this.day=Number(s.match(/\d+/)[0]);};},month:function(s){return function(){this.month=(s.length==3)?"jan feb mar apr may jun jul aug sep oct nov dec".indexOf(s)/4:Number(s)-1;};},year:function(s){return function(){var n=Number(s);this.year=((s.length>2)?n:(n+(((n+2000)<$C.twoDigitYearMax)?2000:1900)));};},rday:function(s){return function(){switch(s){case"yesterday":this.days=-1;break;case"tomorrow":this.days=1;break;case"today":this.days=0;break;case"now":this.days=0;this.now=true;break;}};},finishExact:function(x){x=(x instanceof Array)?x:[x];for(var i=0;i<x.length;i++){if(x[i]){x[i].call(this);}}
+var now=new Date();if((this.hour||this.minute)&&(!this.month&&!this.year&&!this.day)){this.day=now.getDate();}
+if(!this.year){this.year=now.getFullYear();}
+if(!this.month&&this.month!==0){this.month=now.getMonth();}
+if(!this.day){this.day=1;}
+if(!this.hour){this.hour=0;}
+if(!this.minute){this.minute=0;}
+if(!this.second){this.second=0;}
+if(this.meridian&&this.hour){if(this.meridian=="p"&&this.hour<12){this.hour=this.hour+12;}else if(this.meridian=="a"&&this.hour==12){this.hour=0;}}
+if(this.day>$D.getDaysInMonth(this.year,this.month)){throw new RangeError(this.day+" is not a valid value for days.");}
 var r=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second);if(this.timezone){r.set({timezone:this.timezone});}else if(this.timezoneOffset){r.set({timezoneOffset:this.timezoneOffset});}
 return r;},finish:function(x){x=(x instanceof Array)?flattenAndCompact(x):[x];if(x.length===0){return null;}
 for(var i=0;i<x.length;i++){if(typeof x[i]=="function"){x[i].call(this);}}
-if(this.now){return new Date();}
-var today=Date.today();var method=null;var expression=!!(this.days!=null||this.orient||this.operator);if(expression){var gap,mod,orient;orient=((this.orient=="past"||this.operator=="subtract")?-1:1);if(this.weekday){this.unit="day";gap=(Date.getDayNumberFromName(this.weekday)-today.getDay());mod=7;this.days=gap?((gap+(orient*mod))%mod):(orient*mod);}
-if(this.month){this.unit="month";gap=(this.month-today.getMonth());mod=12;this.months=gap?((gap+(orient*mod))%mod):(orient*mod);this.month=null;}
+var today=$D.today();if(this.now&&!this.unit&&!this.operator){return new Date();}else if(this.now){today=new Date();}
+var expression=!!(this.days&&this.days!==null||this.orient||this.operator);var gap,mod,orient;orient=((this.orient=="past"||this.operator=="subtract")?-1:1);if(!this.now&&"hour minute second".indexOf(this.unit)!=-1){today.setTimeToNow();}
+if(this.month||this.month===0){if("year day hour minute second".indexOf(this.unit)!=-1){this.value=this.month+1;this.month=null;expression=true;}}
+if(!expression&&this.weekday&&!this.day&&!this.days){var temp=Date[this.weekday]();this.day=temp.getDate();if(!this.month){this.month=temp.getMonth();}
+this.year=temp.getFullYear();}
+if(expression&&this.weekday&&this.unit!="month"){this.unit="day";gap=($D.getDayNumberFromName(this.weekday)-today.getDay());mod=7;this.days=gap?((gap+(orient*mod))%mod):(orient*mod);}
+if(this.month&&this.unit=="day"&&this.operator){this.value=(this.month+1);this.month=null;}
+if(this.value!=null&&this.month!=null&&this.year!=null){this.day=this.value*1;}
+if(this.month&&!this.day&&this.value){today.set({day:this.value*1});if(!expression){this.day=this.value*1;}}
+if(!this.month&&this.value&&this.unit=="month"&&!this.now){this.month=this.value;expression=true;}
+if(expression&&(this.month||this.month===0)&&this.unit!="year"){this.unit="month";gap=(this.month-today.getMonth());mod=12;this.months=gap?((gap+(orient*mod))%mod):(orient*mod);this.month=null;}
 if(!this.unit){this.unit="day";}
-if(this[this.unit+"s"]==null||this.operator!=null){if(!this.value){this.value=1;}
-if(this.unit=="week"){this.unit="day";this.value=this.value*7;}
+if(!this.value&&this.operator&&this.operator!==null&&this[this.unit+"s"]&&this[this.unit+"s"]!==null){this[this.unit+"s"]=this[this.unit+"s"]+((this.operator=="add")?1:-1)+(this.value||0)*orient;}else if(this[this.unit+"s"]==null||this.operator!=null){if(!this.value){this.value=1;}
 this[this.unit+"s"]=this.value*orient;}
-return today.add(this);}else{if(this.meridian&&this.hour){this.hour=(this.hour<13&&this.meridian=="p")?this.hour+12:this.hour;}
-if(this.weekday&&!this.day){this.day=(today.addDays((Date.getDayNumberFromName(this.weekday)-today.getDay()))).getDate();}
-if(this.month&&!this.day){this.day=1;}
-return today.set(this);}}};var _=Date.Parsing.Operators,g=Date.Grammar,t=Date.Translator,_fn;g.datePartDelimiter=_.rtoken(/^([\s\-\.\,\/\x27]+)/);g.timePartDelimiter=_.stoken(":");g.whiteSpace=_.rtoken(/^\s*/);g.generalDelimiter=_.rtoken(/^(([\s\,]|at|on)+)/);var _C={};g.ctoken=function(keys){var fn=_C[keys];if(!fn){var c=Date.CultureInfo.regexPatterns;var kx=keys.split(/\s+/),px=[];for(var i=0;i<kx.length;i++){px.push(_.replace(_.rtoken(c[kx[i]]),kx[i]));}
+if(this.meridian&&this.hour){if(this.meridian=="p"&&this.hour<12){this.hour=this.hour+12;}else if(this.meridian=="a"&&this.hour==12){this.hour=0;}}
+if(this.weekday&&!this.day&&!this.days){var temp=Date[this.weekday]();this.day=temp.getDate();if(temp.getMonth()!==today.getMonth()){this.month=temp.getMonth();}}
+if((this.month||this.month===0)&&!this.day){this.day=1;}
+if(!this.orient&&!this.operator&&this.unit=="week"&&this.value&&!this.day&&!this.month){return Date.today().setWeek(this.value);}
+if(expression&&this.timezone&&this.day&&this.days){this.day=this.days;}
+return(expression)?today.add(this):today.set(this);}};var _=$D.Parsing.Operators,g=$D.Grammar,t=$D.Translator,_fn;g.datePartDelimiter=_.rtoken(/^([\s\-\.\,\/\x27]+)/);g.timePartDelimiter=_.stoken(":");g.whiteSpace=_.rtoken(/^\s*/);g.generalDelimiter=_.rtoken(/^(([\s\,]|at|@|on)+)/);var _C={};g.ctoken=function(keys){var fn=_C[keys];if(!fn){var c=$C.regexPatterns;var kx=keys.split(/\s+/),px=[];for(var i=0;i<kx.length;i++){px.push(_.replace(_.rtoken(c[kx[i]]),kx[i]));}
 fn=_C[keys]=_.any.apply(null,px);}
-return fn;};g.ctoken2=function(key){return _.rtoken(Date.CultureInfo.regexPatterns[key]);};g.h=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2]|[1-9])/),t.hour));g.hh=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2])/),t.hour));g.H=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/),t.hour));g.HH=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3])/),t.hour));g.m=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.minute));g.mm=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.minute));g.s=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.second));g.ss=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.second));g.hms=_.cache(_.sequence([g.H,g.mm,g.ss],g.timePartDelimiter));g.t=_.cache(_.process(g.ctoken2("shortMeridian"),t.meridian));g.tt=_.cache(_.process(g.ctoken2("longMeridian"),t.meridian));g.z=_.cache(_.process(_.rtoken(/^(\+|\-)?\s*\d\d\d\d?/),t.timezone));g.zz=_.cache(_.process(_.rtoken(/^(\+|\-)\s*\d\d\d\d/),t.timezone));g.zzz=_.cache(_.process(g.ctoken2("timezone"),t.timezone));g.timeSuffix=_.each(_.ignore(g.whiteSpace),_.set([g.tt,g.zzz]));g.time=_.each(_.optional(_.ignore(_.stoken("T"))),g.hms,g.timeSuffix);g.d=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.dd=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.ddd=g.dddd=_.cache(_.process(g.ctoken("sun mon tue wed thu fri sat"),function(s){return function(){this.weekday=s;};}));g.M=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d|\d)/),t.month));g.MM=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d)/),t.month));g.MMM=g.MMMM=_.cache(_.process(g.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"),t.month));g.y=_.cache(_.process(_.rtoken(/^(\d\d?)/),t.year));g.yy=_.cache(_.process(_.rtoken(/^(\d\d)/),t.year));g.yyy=_.cache(_.process(_.rtoken(/^(\d\d?\d?\d?)/),t.year));g.yyyy=_.cache(_.process(_.rtoken(/^(\d\d\d\d)/),t.year));_fn=function(){return _.each(_.any.apply(null,arguments),_.not(g.ctoken2("timeContext")));};g.day=_fn(g.d,g.dd);g.month=_fn(g.M,g.MMM);g.year=_fn(g.yyyy,g.yy);g.orientation=_.process(g.ctoken("past future"),function(s){return function(){this.orient=s;};});g.operator=_.process(g.ctoken("add subtract"),function(s){return function(){this.operator=s;};});g.rday=_.process(g.ctoken("yesterday tomorrow today now"),t.rday);g.unit=_.process(g.ctoken("minute hour day week month year"),function(s){return function(){this.unit=s;};});g.value=_.process(_.rtoken(/^\d\d?(st|nd|rd|th)?/),function(s){return function(){this.value=s.replace(/\D/g,"");};});g.expression=_.set([g.rday,g.operator,g.value,g.unit,g.orientation,g.ddd,g.MMM]);_fn=function(){return _.set(arguments,g.datePartDelimiter);};g.mdy=_fn(g.ddd,g.month,g.day,g.year);g.ymd=_fn(g.ddd,g.year,g.month,g.day);g.dmy=_fn(g.ddd,g.day,g.month,g.year);g.date=function(s){return((g[Date.CultureInfo.dateElementOrder]||g.mdy).call(this,s));};g.format=_.process(_.many(_.any(_.process(_.rtoken(/^(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/),function(fmt){if(g[fmt]){return g[fmt];}else{throw Date.Parsing.Exception(fmt);}}),_.process(_.rtoken(/^[^dMyhHmstz]+/),function(s){return _.ignore(_.stoken(s));}))),function(rules){return _.process(_.each.apply(null,rules),t.finishExact);});var _F={};var _get=function(f){return _F[f]=(_F[f]||g.format(f)[0]);};g.formats=function(fx){if(fx instanceof Array){var rx=[];for(var i=0;i<fx.length;i++){rx.push(_get(fx[i]));}
-return _.any.apply(null,rx);}else{return _get(fx);}};g._formats=g.formats(["yyyy-MM-ddTHH:mm:ss","ddd, MMM dd, yyyy H:mm:ss tt","ddd MMM d yyyy HH:mm:ss zzz","d"]);g._start=_.process(_.set([g.date,g.time,g.expression],g.generalDelimiter,g.whiteSpace),t.finish);g.start=function(s){try{var r=g._formats.call({},s);if(r[1].length===0){return r;}}catch(e){}
-return g._start.call({},s);};}());Date._parse=Date.parse;Date.parse=function(s){var r=null;if(!s){return null;}
-try{r=Date.Grammar.start.call({},s);}catch(e){return null;}
-return((r[1].length===0)?r[0]:null);};Date.getParseFunction=function(fx){var fn=Date.Grammar.formats(fx);return function(s){var r=null;try{r=fn.call({},s);}catch(e){return null;}
-return((r[1].length===0)?r[0]:null);};};Date.parseExact=function(s,fx){return Date.getParseFunction(fx)(s);};
+return fn;};g.ctoken2=function(key){return _.rtoken($C.regexPatterns[key]);};g.h=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2]|[1-9])/),t.hour));g.hh=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2])/),t.hour));g.H=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/),t.hour));g.HH=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3])/),t.hour));g.m=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.minute));g.mm=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.minute));g.s=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.second));g.ss=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.second));g.hms=_.cache(_.sequence([g.H,g.m,g.s],g.timePartDelimiter));g.t=_.cache(_.process(g.ctoken2("shortMeridian"),t.meridian));g.tt=_.cache(_.process(g.ctoken2("longMeridian"),t.meridian));g.z=_.cache(_.process(_.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/),t.timezone));g.zz=_.cache(_.process(_.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/),t.timezone));g.zzz=_.cache(_.process(g.ctoken2("timezone"),t.timezone));g.timeSuffix=_.each(_.ignore(g.whiteSpace),_.set([g.tt,g.zzz]));g.time=_.each(_.optional(_.ignore(_.stoken("T"))),g.hms,g.timeSuffix);g.d=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.dd=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.ddd=g.dddd=_.cache(_.process(g.ctoken("sun mon tue wed thu fri sat"),function(s){return function(){this.weekday=s;};}));g.M=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d|\d)/),t.month));g.MM=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d)/),t.month));g.MMM=g.MMMM=_.cache(_.process(g.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"),t.month));g.y=_.cache(_.process(_.rtoken(/^(\d\d?)/),t.year));g.yy=_.cache(_.process(_.rtoken(/^(\d\d)/),t.year));g.yyy=_.cache(_.process(_.rtoken(/^(\d\d?\d?\d?)/),t.year));g.yyyy=_.cache(_.process(_.rtoken(/^(\d\d\d\d)/),t.year));_fn=function(){return _.each(_.any.apply(null,arguments),_.not(g.ctoken2("timeContext")));};g.day=_fn(g.d,g.dd);g.month=_fn(g.M,g.MMM);g.year=_fn(g.yyyy,g.yy);g.orientation=_.process(g.ctoken("past future"),function(s){return function(){this.orient=s;};});g.operator=_.process(g.ctoken("add subtract"),function(s){return function(){this.operator=s;};});g.rday=_.process(g.ctoken("yesterday tomorrow today now"),t.rday);g.unit=_.process(g.ctoken("second minute hour day week month year"),function(s){return function(){this.unit=s;};});g.value=_.process(_.rtoken(/^\d\d?(st|nd|rd|th)?/),function(s){return function(){this.value=s.replace(/\D/g,"");};});g.expression=_.set([g.rday,g.operator,g.value,g.unit,g.orientation,g.ddd,g.MMM]);_fn=function(){return _.set(arguments,g.datePartDelimiter);};g.mdy=_fn(g.ddd,g.month,g.day,g.year);g.ymd=_fn(g.ddd,g.year,g.month,g.day);g.dmy=_fn(g.ddd,g.day,g.month,g.year);g.date=function(s){return((g[$C.dateElementOrder]||g.mdy).call(this,s));};g.format=_.process(_.many(_.any(_.process(_.rtoken(/^(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/),function(fmt){if(g[fmt]){return g[fmt];}else{throw $D.Parsing.Exception(fmt);}}),_.process(_.rtoken(/^[^dMyhHmstz]+/),function(s){return _.ignore(_.stoken(s));}))),function(rules){return _.process(_.each.apply(null,rules),t.finishExact);});var _F={};var _get=function(f){return _F[f]=(_F[f]||g.format(f)[0]);};g.formats=function(fx){if(fx instanceof Array){var rx=[];for(var i=0;i<fx.length;i++){rx.push(_get(fx[i]));}
+return _.any.apply(null,rx);}else{return _get(fx);}};g._formats=g.formats(["\"yyyy-MM-ddTHH:mm:ssZ\"","yyyy-MM-ddTHH:mm:ssZ","yyyy-MM-ddTHH:mm:ssz","yyyy-MM-ddTHH:mm:ss","yyyy-MM-ddTHH:mmZ","yyyy-MM-ddTHH:mmz","yyyy-MM-ddTHH:mm","ddd, MMM dd, yyyy H:mm:ss tt","ddd MMM d yyyy HH:mm:ss zzz","MMddyyyy","ddMMyyyy","Mddyyyy","ddMyyyy","Mdyyyy","dMyyyy","yyyy","Mdyy","dMyy","d"]);g._start=_.process(_.set([g.date,g.time,g.expression],g.generalDelimiter,g.whiteSpace),t.finish);g.start=function(s){try{var r=g._formats.call({},s);if(r[1].length===0){return r;}}catch(e){}
+return g._start.call({},s);};$D._parse=$D.parse;$D.parse=function(s){var r=null;if(!s){return null;}
+if(s instanceof Date){return s;}
+try{r=$D.Grammar.start.call({},s.replace(/^\s*(\S*(\s+\S+)*)\s*$/,"$1"));}catch(e){return null;}
+return((r[1].length===0)?r[0]:null);};$D.getParseFunction=function(fx){var fn=$D.Grammar.formats(fx);return function(s){var r=null;try{r=fn.call({},s);}catch(e){return null;}
+return((r[1].length===0)?r[0]:null);};};$D.parseExact=function(s,fx){return $D.getParseFunction(fx)(s);};}());
Index: /trunk/prototype/plugins/datejs/parser-debug.js
===================================================================
--- /trunk/prototype/plugins/datejs/parser-debug.js	(revision 5341)
+++ /trunk/prototype/plugins/datejs/parser-debug.js	(revision 7143)
@@ -1,13 +1,14 @@
 /**
- * Version: 1.0 Alpha-1 
- * Build Date: 12-Nov-2007
- * Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
- * License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
- * Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
+ * @version: 1.0 Alpha-1
+ * @author: Coolite Inc. http://www.coolite.com/
+ * @date: 2008-04-13
+ * @copyright: Copyright (c) 2006-2008, Coolite Inc. (http://www.coolite.com/). All rights reserved.
+ * @license: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
+ * @website: http://www.datejs.com/
  */
  
 (function () {
     Date.Parsing = {
-        Exception: function (s) { 
+        Exception: function (s) {
             this.message = "Parse error at '" + s.substring(0, 10) + " ...'"; 
         }
@@ -465,4 +466,6 @@
 
 (function () {
+    var $D = Date, $P = $D.prototype, $C = $D.CultureInfo;
+
     var flattenAndCompact = function (ax) { 
         var rx = []; 
@@ -479,7 +482,7 @@
     };
     
-    Date.Grammar = {};
+    $D.Grammar = {};
 	
-    Date.Translator = {
+    $D.Translator = {
         hour: function (s) { 
             return function () { 
@@ -520,5 +523,5 @@
         month: function (s) {
             return function () {
-                this.month = ((s.length == 3) ? Date.getMonthNumberFromName(s) : (Number(s) - 1));
+                this.month = (s.length == 3) ? "jan feb mar apr may jun jul aug sep oct nov dec".indexOf(s)/4 : Number(s) - 1;
             };
         },
@@ -527,5 +530,5 @@
                 var n = Number(s);
                 this.year = ((s.length > 2) ? n : 
-                    (n + (((n + 2000) < Date.CultureInfo.twoDigitYearMax) ? 2000 : 1900))); 
+                    (n + (((n + 2000) < $C.twoDigitYearMax) ? 2000 : 1900))); 
             };
         },
@@ -551,14 +554,4 @@
         finishExact: function (x) {  
             x = (x instanceof Array) ? x : [ x ]; 
-	        
-            var now = new Date();
-
-            this.year = now.getFullYear(); 
-            this.month = now.getMonth(); 
-            this.day = 1; 
-
-            this.hour = 0; 
-            this.minute = 0; 
-            this.second = 0;
 
             for (var i = 0 ; i < x.length ; i++) { 
@@ -566,9 +559,45 @@
                     x[i].call(this); 
                 }
-            } 
-
-            this.hour = (this.meridian == "p" && this.hour < 13) ? this.hour + 12 : this.hour;
-
-            if (this.day > Date.getDaysInMonth(this.year, this.month)) {
+            }
+            
+            var now = new Date();
+            
+            if ((this.hour || this.minute) && (!this.month && !this.year && !this.day)) {
+                this.day = now.getDate();
+            }
+
+            if (!this.year) {
+                this.year = now.getFullYear();
+            }
+            
+            if (!this.month && this.month !== 0) {
+                this.month = now.getMonth();
+            }
+            
+            if (!this.day) {
+                this.day = 1;
+            }
+            
+            if (!this.hour) {
+                this.hour = 0;
+            }
+            
+            if (!this.minute) {
+                this.minute = 0;
+            }
+
+            if (!this.second) {
+                this.second = 0;
+            }
+
+            if (this.meridian && this.hour) {
+                if (this.meridian == "p" && this.hour < 12) {
+                    this.hour = this.hour + 12;
+                } else if (this.meridian == "a" && this.hour == 12) {
+                    this.hour = 0;
+                }
+            }
+            
+            if (this.day > $D.getDaysInMonth(this.year, this.month)) {
                 throw new RangeError(this.day + " is not a valid value for days.");
             }
@@ -581,4 +610,5 @@
                 r.set({ timezoneOffset: this.timezoneOffset }); 
             }
+            
             return r;
         },			
@@ -595,67 +625,126 @@
                 }
             }
-
-            if (this.now) { 
+            
+            var today = $D.today();
+            
+            if (this.now && !this.unit && !this.operator) { 
                 return new Date(); 
-            }
-
-            var today = Date.today(); 
-            var method = null;
-
-            var expression = !!(this.days != null || this.orient || this.operator);
-            if (expression) {
-                var gap, mod, orient;
-                orient = ((this.orient == "past" || this.operator == "subtract") ? -1 : 1);
-
-                if (this.weekday) {
-                    this.unit = "day";
-                    gap = (Date.getDayNumberFromName(this.weekday) - today.getDay());
-                    mod = 7;
-                    this.days = gap ? ((gap + (orient * mod)) % mod) : (orient * mod);
-                }
-                if (this.month) {
-                    this.unit = "month";
-                    gap = (this.month - today.getMonth());
-                    mod = 12;
-                    this.months = gap ? ((gap + (orient * mod)) % mod) : (orient * mod);
+            } else if (this.now) {
+                today = new Date();
+            }
+            
+            var expression = !!(this.days && this.days !== null || this.orient || this.operator);
+            
+            var gap, mod, orient;
+            orient = ((this.orient == "past" || this.operator == "subtract") ? -1 : 1);
+            
+            if(!this.now && "hour minute second".indexOf(this.unit) != -1) {
+                today.setTimeToNow();
+            }
+
+            if (this.month || this.month === 0) {
+                if ("year day hour minute second".indexOf(this.unit) != -1) {
+                    this.value = this.month + 1;
                     this.month = null;
-                }
-                if (!this.unit) { 
-                    this.unit = "day"; 
-                }
-                if (this[this.unit + "s"] == null || this.operator != null) {
-                    if (!this.value) { 
-                        this.value = 1;
-                    }
-
-                    if (this.unit == "week") { 
-                        this.unit = "day"; 
-                        this.value = this.value * 7; 
-                    }
-
-                    this[this.unit + "s"] = this.value * orient;
-                }
-                return today.add(this);
-            } else {
-                if (this.meridian && this.hour) {
-                    this.hour = (this.hour < 13 && this.meridian == "p") ? this.hour + 12 : this.hour;			
-                }
-                if (this.weekday && !this.day) {
-                    this.day = (today.addDays((Date.getDayNumberFromName(this.weekday) - today.getDay()))).getDate();
-                }
-                if (this.month && !this.day) { 
-                    this.day = 1; 
-                }
-                return today.set(this);
-            }
-        }
-    };
-
-    var _ = Date.Parsing.Operators, g = Date.Grammar, t = Date.Translator, _fn;
+                    expression = true;
+                }
+            }
+            
+            if (!expression && this.weekday && !this.day && !this.days) {
+                var temp = Date[this.weekday]();
+                this.day = temp.getDate();
+                if (!this.month) {
+                    this.month = temp.getMonth();
+                }
+                this.year = temp.getFullYear();
+            }
+            
+            if (expression && this.weekday && this.unit != "month") {
+                this.unit = "day";
+                gap = ($D.getDayNumberFromName(this.weekday) - today.getDay());
+                mod = 7;
+                this.days = gap ? ((gap + (orient * mod)) % mod) : (orient * mod);
+            }
+            
+            if (this.month && this.unit == "day" && this.operator) {
+                this.value = (this.month + 1);
+                this.month = null;
+            }
+       
+            if (this.value != null && this.month != null && this.year != null) {
+                this.day = this.value * 1;
+            }
+     
+            if (this.month && !this.day && this.value) {
+                today.set({ day: this.value * 1 });
+                if (!expression) {
+                    this.day = this.value * 1;
+                }
+            }
+
+            if (!this.month && this.value && this.unit == "month" && !this.now) {
+                this.month = this.value;
+                expression = true;
+            }
+
+            if (expression && (this.month || this.month === 0) && this.unit != "year") {
+                this.unit = "month";
+                gap = (this.month - today.getMonth());
+                mod = 12;
+                this.months = gap ? ((gap + (orient * mod)) % mod) : (orient * mod);
+                this.month = null;
+            }
+
+            if (!this.unit) { 
+                this.unit = "day"; 
+            }
+            
+            if (!this.value && this.operator && this.operator !== null && this[this.unit + "s"] && this[this.unit + "s"] !== null) {
+                this[this.unit + "s"] = this[this.unit + "s"] + ((this.operator == "add") ? 1 : -1) + (this.value||0) * orient;
+            } else if (this[this.unit + "s"] == null || this.operator != null) {
+                if (!this.value) {
+                    this.value = 1;
+                }
+                this[this.unit + "s"] = this.value * orient;
+            }
+
+            if (this.meridian && this.hour) {
+                if (this.meridian == "p" && this.hour < 12) {
+                    this.hour = this.hour + 12;
+                } else if (this.meridian == "a" && this.hour == 12) {
+                    this.hour = 0;
+                }
+            }
+            
+            if (this.weekday && !this.day && !this.days) {
+                var temp = Date[this.weekday]();
+                this.day = temp.getDate();
+                if (temp.getMonth() !== today.getMonth()) {
+                    this.month = temp.getMonth();
+                }
+            }
+            
+            if ((this.month || this.month === 0) && !this.day) { 
+                this.day = 1; 
+            }
+            
+            if (!this.orient && !this.operator && this.unit == "week" && this.value && !this.day && !this.month) {
+                return Date.today().setWeek(this.value);
+            }
+
+            if (expression && this.timezone && this.day && this.days) {
+                this.day = this.days;
+            }
+            
+            return (expression) ? today.add(this) : today.set(this);
+        }
+    };
+
+    var _ = $D.Parsing.Operators, g = $D.Grammar, t = $D.Translator, _fn;
 
     g.datePartDelimiter = _.rtoken(/^([\s\-\.\,\/\x27]+)/); 
     g.timePartDelimiter = _.stoken(":");
     g.whiteSpace = _.rtoken(/^\s*/);
-    g.generalDelimiter = _.rtoken(/^(([\s\,]|at|on)+)/);
+    g.generalDelimiter = _.rtoken(/^(([\s\,]|at|@|on)+)/);
   
     var _C = {};
@@ -663,5 +752,5 @@
         var fn = _C[keys];
         if (! fn) {
-            var c = Date.CultureInfo.regexPatterns;
+            var c = $C.regexPatterns;
             var kx = keys.split(/\s+/), px = []; 
             for (var i = 0; i < kx.length ; i++) {
@@ -673,5 +762,5 @@
     };
     g.ctoken2 = function (key) { 
-        return _.rtoken(Date.CultureInfo.regexPatterns[key]);
+        return _.rtoken($C.regexPatterns[key]);
     };
 
@@ -685,15 +774,16 @@
     g.s = _.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/), t.second));
     g.ss = _.cache(_.process(_.rtoken(/^[0-5][0-9]/), t.second));
-    g.hms = _.cache(_.sequence([g.H, g.mm, g.ss], g.timePartDelimiter));
+    g.hms = _.cache(_.sequence([g.H, g.m, g.s], g.timePartDelimiter));
   
     // _.min(1, _.set([ g.H, g.m, g.s ], g._t));
     g.t = _.cache(_.process(g.ctoken2("shortMeridian"), t.meridian));
     g.tt = _.cache(_.process(g.ctoken2("longMeridian"), t.meridian));
-    g.z = _.cache(_.process(_.rtoken(/^(\+|\-)?\s*\d\d\d\d?/), t.timezone));
-    g.zz = _.cache(_.process(_.rtoken(/^(\+|\-)\s*\d\d\d\d/), t.timezone));
+    g.z = _.cache(_.process(_.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/), t.timezone));
+    g.zz = _.cache(_.process(_.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/), t.timezone));
+    
     g.zzz = _.cache(_.process(g.ctoken2("timezone"), t.timezone));
     g.timeSuffix = _.each(_.ignore(g.whiteSpace), _.set([ g.tt, g.zzz ]));
     g.time = _.each(_.optional(_.ignore(_.stoken("T"))), g.hms, g.timeSuffix);
-	  
+    	  
     // days, months, years
     g.d = _.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/), 
@@ -742,5 +832,5 @@
     );  
     g.rday = _.process(g.ctoken("yesterday tomorrow today now"), t.rday);
-    g.unit = _.process(g.ctoken("minute hour day week month year"), 
+    g.unit = _.process(g.ctoken("second minute hour day week month year"), 
         function (s) { 
             return function () { 
@@ -766,5 +856,5 @@
     g.dmy = _fn(g.ddd, g.day, g.month, g.year);
     g.date = function (s) { 
-        return ((g[Date.CultureInfo.dateElementOrder] || g.mdy).call(this, s));
+        return ((g[$C.dateElementOrder] || g.mdy).call(this, s));
     }; 
 
@@ -781,5 +871,5 @@
             return g[fmt]; 
         } else { 
-            throw Date.Parsing.Exception(fmt); 
+            throw $D.Parsing.Exception(fmt); 
         }
     }
@@ -830,7 +920,22 @@
 	// check for these formats first
     g._formats = g.formats([
+        "\"yyyy-MM-ddTHH:mm:ssZ\"",
+        "yyyy-MM-ddTHH:mm:ssZ",
+        "yyyy-MM-ddTHH:mm:ssz",
         "yyyy-MM-ddTHH:mm:ss",
+        "yyyy-MM-ddTHH:mmZ",
+        "yyyy-MM-ddTHH:mmz",
+        "yyyy-MM-ddTHH:mm",
         "ddd, MMM dd, yyyy H:mm:ss tt",
         "ddd MMM d yyyy HH:mm:ss zzz",
+        "MMddyyyy",
+        "ddMMyyyy",
+        "Mddyyyy",
+        "ddMyyyy",
+        "Mdyyyy",
+        "dMyyyy",
+        "yyyy",
+        "Mdyy",
+        "dMyy",
         "d"
     ]);
@@ -851,129 +956,117 @@
         return g._start.call({}, s);
     };
-		
-}());
-
-
-Date._parse = Date.parse;
-
-/**
- * Converts the specified string value into its JavaScript Date equivalent using CultureInfo specific format information.
- * 
- * Example
-<pre><code>
-///////////
-// Dates //
-///////////
-
-// 15-Oct-2004
-var d1 = Date.parse("10/15/2004");
-
-// 15-Oct-2004
-var d1 = Date.parse("15-Oct-2004");
-
-// 15-Oct-2004
-var d1 = Date.parse("2004.10.15");
-
-//Fri Oct 15, 2004
-var d1 = Date.parse("Fri Oct 15, 2004");
-
-///////////
-// Times //
-///////////
-
-// Today at 10 PM.
-var d1 = Date.parse("10 PM");
-
-// Today at 10:30 PM.
-var d1 = Date.parse("10:30 P.M.");
-
-// Today at 6 AM.
-var d1 = Date.parse("06am");
-
-/////////////////////
-// Dates and Times //
-/////////////////////
-
-// 8-July-2004 @ 10:30 PM
-var d1 = Date.parse("July 8th, 2004, 10:30 PM");
-
-// 1-July-2004 @ 10:30 PM
-var d1 = Date.parse("2004-07-01T22:30:00");
-
-////////////////////
-// Relative Dates //
-////////////////////
-
-// Returns today's date. The string "today" is culture specific.
-var d1 = Date.parse("today");
-
-// Returns yesterday's date. The string "yesterday" is culture specific.
-var d1 = Date.parse("yesterday");
-
-// Returns the date of the next thursday.
-var d1 = Date.parse("Next thursday");
-
-// Returns the date of the most previous monday.
-var d1 = Date.parse("last monday");
-
-// Returns today's day + one year.
-var d1 = Date.parse("next year");
-
-///////////////
-// Date Math //
-///////////////
-
-// Today + 2 days
-var d1 = Date.parse("t+2");
-
-// Today + 2 days
-var d1 = Date.parse("today + 2 days");
-
-// Today + 3 months
-var d1 = Date.parse("t+3m");
-
-// Today - 1 year
-var d1 = Date.parse("today - 1 year");
-
-// Today - 1 year
-var d1 = Date.parse("t-1y"); 
-
-
-/////////////////////////////
-// Partial Dates and Times //
-/////////////////////////////
-
-// July 15th of this year.
-var d1 = Date.parse("July 15");
-
-// 15th day of current day and year.
-var d1 = Date.parse("15");
-
-// July 1st of current year at 10pm.
-var d1 = Date.parse("7/1 10pm");
-</code></pre>
- *
- * @param {String}   The string value to convert into a Date object [Required]
- * @return {Date}    A Date object or null if the string cannot be converted into a Date.
- */
-Date.parse = function (s) {
-    var r = null; 
-    if (!s) { 
-        return null; 
-    }
-    try { 
-        r = Date.Grammar.start.call({}, s); 
-    } catch (e) { 
-        return null; 
-    }
-    return ((r[1].length === 0) ? r[0] : null);
-};
-
-Date.getParseFunction = function (fx) {
-    var fn = Date.Grammar.formats(fx);
-    return function (s) {
-        var r = null;
+	
+	$D._parse = $D.parse;
+
+    /**
+     * Converts the specified string value into its JavaScript Date equivalent using CultureInfo specific format information.
+     * 
+     * Example
+    <pre><code>
+    ///////////
+    // Dates //
+    ///////////
+
+    // 15-Oct-2004
+    var d1 = Date.parse("10/15/2004");
+
+    // 15-Oct-2004
+    var d1 = Date.parse("15-Oct-2004");
+
+    // 15-Oct-2004
+    var d1 = Date.parse("2004.10.15");
+
+    //Fri Oct 15, 2004
+    var d1 = Date.parse("Fri Oct 15, 2004");
+
+    ///////////
+    // Times //
+    ///////////
+
+    // Today at 10 PM.
+    var d1 = Date.parse("10 PM");
+
+    // Today at 10:30 PM.
+    var d1 = Date.parse("10:30 P.M.");
+
+    // Today at 6 AM.
+    var d1 = Date.parse("06am");
+
+    /////////////////////
+    // Dates and Times //
+    /////////////////////
+
+    // 8-July-2004 @ 10:30 PM
+    var d1 = Date.parse("July 8th, 2004, 10:30 PM");
+
+    // 1-July-2004 @ 10:30 PM
+    var d1 = Date.parse("2004-07-01T22:30:00");
+
+    ////////////////////
+    // Relative Dates //
+    ////////////////////
+
+    // Returns today's date. The string "today" is culture specific.
+    var d1 = Date.parse("today");
+
+    // Returns yesterday's date. The string "yesterday" is culture specific.
+    var d1 = Date.parse("yesterday");
+
+    // Returns the date of the next thursday.
+    var d1 = Date.parse("Next thursday");
+
+    // Returns the date of the most previous monday.
+    var d1 = Date.parse("last monday");
+
+    // Returns today's day + one year.
+    var d1 = Date.parse("next year");
+
+    ///////////////
+    // Date Math //
+    ///////////////
+
+    // Today + 2 days
+    var d1 = Date.parse("t+2");
+
+    // Today + 2 days
+    var d1 = Date.parse("today + 2 days");
+
+    // Today + 3 months
+    var d1 = Date.parse("t+3m");
+
+    // Today - 1 year
+    var d1 = Date.parse("today - 1 year");
+
+    // Today - 1 year
+    var d1 = Date.parse("t-1y"); 
+
+
+    /////////////////////////////
+    // Partial Dates and Times //
+    /////////////////////////////
+
+    // July 15th of this year.
+    var d1 = Date.parse("July 15");
+
+    // 15th day of current day and year.
+    var d1 = Date.parse("15");
+
+    // July 1st of current year at 10pm.
+    var d1 = Date.parse("7/1 10pm");
+    </code></pre>
+     *
+     * @param {String}   The string value to convert into a Date object [Required]
+     * @return {Date}    A Date object or null if the string cannot be converted into a Date.
+     */
+    $D.parse = function (s) {
+        var r = null; 
+        if (!s) { 
+            return null; 
+        }
+        if (s instanceof Date) {
+            return s;
+        }
         try { 
-            r = fn.call({}, s); 
+            r = $D.Grammar.start.call({}, s.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1")); 
         } catch (e) { 
             return null; 
@@ -981,29 +1074,43 @@
         return ((r[1].length === 0) ? r[0] : null);
     };
-};
-/**
- * Converts the specified string value into its JavaScript Date equivalent using the specified format {String} or formats {Array} and the CultureInfo specific format information.
- * The format of the string value must match one of the supplied formats exactly.
- * 
- * Example
-<pre><code>
-// 15-Oct-2004
-var d1 = Date.parseExact("10/15/2004", "M/d/yyyy");
-
-// 15-Oct-2004
-var d1 = Date.parse("15-Oct-2004", "M-ddd-yyyy");
-
-// 15-Oct-2004
-var d1 = Date.parse("2004.10.15", "yyyy.MM.dd");
-
-// Multiple formats
-var d1 = Date.parseExact("10/15/2004", [ "M/d/yyyy" , "MMMM d, yyyy" ]);
-</code></pre>
- *
- * @param {String}   The string value to convert into a Date object [Required].
- * @param {Object}   The expected format {String} or an array of expected formats {Array} of the date string [Required].
- * @return {Date}    A Date object or null if the string cannot be converted into a Date.
- */
-Date.parseExact = function (s, fx) { 
-    return Date.getParseFunction(fx)(s); 
-};
+
+    $D.getParseFunction = function (fx) {
+        var fn = $D.Grammar.formats(fx);
+        return function (s) {
+            var r = null;
+            try { 
+                r = fn.call({}, s); 
+            } catch (e) { 
+                return null; 
+            }
+            return ((r[1].length === 0) ? r[0] : null);
+        };
+    };
+    
+    /**
+     * Converts the specified string value into its JavaScript Date equivalent using the specified format {String} or formats {Array} and the CultureInfo specific format information.
+     * The format of the string value must match one of the supplied formats exactly.
+     * 
+     * Example
+    <pre><code>
+    // 15-Oct-2004
+    var d1 = Date.parseExact("10/15/2004", "M/d/yyyy");
+
+    // 15-Oct-2004
+    var d1 = Date.parse("15-Oct-2004", "M-ddd-yyyy");
+
+    // 15-Oct-2004
+    var d1 = Date.parse("2004.10.15", "yyyy.MM.dd");
+
+    // Multiple formats
+    var d1 = Date.parseExact("10/15/2004", ["M/d/yyyy", "MMMM d, yyyy"]);
+    </code></pre>
+     *
+     * @param {String}   The string value to convert into a Date object [Required].
+     * @param {Object}   The expected format {String} or an array of expected formats {Array} of the date string [Required].
+     * @return {Date}    A Date object or null if the string cannot be converted into a Date.
+     */
+    $D.parseExact = function (s, fx) { 
+        return $D.getParseFunction(fx)(s); 
+    };	
+}());
Index: /trunk/prototype/plugins/datejs/sugarpak-debug.js
===================================================================
--- /trunk/prototype/plugins/datejs/sugarpak-debug.js	(revision 5341)
+++ /trunk/prototype/plugins/datejs/sugarpak-debug.js	(revision 7143)
@@ -1,8 +1,9 @@
 /**
- * Version: 1.0 Alpha-1 
- * Build Date: 12-Nov-2007
- * Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
- * License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
- * Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
+ * @version: 1.0 Alpha-1
+ * @author: Coolite Inc. http://www.coolite.com/
+ * @date: 2008-04-13
+ * @copyright: Copyright (c) 2006-2008, Coolite Inc. (http://www.coolite.com/). All rights reserved.
+ * @license: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
+ * @website: http://www.datejs.com/
  */
 
@@ -13,134 +14,297 @@
  */
  
-/**
- * Gets a date that is set to the current date and time. 
- * @return {Date}    The current date and time.
- */
-Date.now = function () {
-    return new Date();
-};
-
-/** 
- * Gets a date that is set to the current date. The time is set to the start of the day (00:00 or 12:00 AM).
- * @return {Date}    The current date.
- */
-Date.today = function () {
-    return Date.now().clearTime();
-};
-
-// private
-Date.prototype._orient = +1;
-
-/** 
- * Moves the date to the next instance of a date as specified by a trailing date element function (eg. .day(), .month()), month name function (eg. .january(), .jan()) or day name function (eg. .friday(), fri()).
- * Example
-<pre><code>
-Date.today().next().friday();
-Date.today().next().fri();
-Date.today().next().march();
-Date.today().next().mar();
-Date.today().next().week();
-</code></pre>
- * 
- * @return {Date}    this
- */
-Date.prototype.next = function () {
-    this._orient = +1;
-    return this;
-};
-
-/** 
- * Moves the date to the previous instance of a date as specified by a trailing date element function (eg. .day(), .month()), month name function (eg. .january(), .jan()) or day name function (eg. .friday(), fri()).
- * Example
-<pre><code>
-Date.today().last().friday();
-Date.today().last().fri();
-Date.today().last().march();
-Date.today().last().mar();
-Date.today().last().week();
-</code></pre>
- *  
- * @return {Date}    this
- */
-Date.prototype.last = Date.prototype.prev = Date.prototype.previous = function () {
-    this._orient = -1;
-    return this;
-};
-
-// private
-Date.prototype._is = false;
-    
-/** 
- * Performs a equality check when followed by either a month name or day name function.
- * Example
-<pre><code>
-Date.today().is().friday(); // true|false
-Date.today().is().fri();
-Date.today().is().march();
-Date.today().is().mar();
-</code></pre>
- *  
- * @return {bool}    true|false
- */
-Date.prototype.is = function () { 
-    this._is = true; 
-    return this; 
-}; 
-
-// private
-Number.prototype._dateElement = "day";
-
-/** 
- * Creates a new Date (Date.now()) and adds this (Number) to the date based on the preceding date element function (eg. second|minute|hour|day|month|year).
- * Example
-<pre><code>
-// Undeclared Numbers must be wrapped with parentheses. Requirment of JavaScript.
-(3).days().fromNow();
-(6).months().fromNow();
-
-// Declared Number variables do not require parentheses. 
-var n = 6;
-n.months().fromNow();
-</code></pre>
- *  
- * @return {Date}    A new Date instance
- */
-Number.prototype.fromNow = function () {
-    var c = {};
-    c[this._dateElement] = this;
-    return Date.now().add(c);
-};
-
-/** 
- * Creates a new Date (Date.now()) and subtract this (Number) from the date based on the preceding date element function (eg. second|minute|hour|day|month|year).
- * Example
-<pre><code>
-// Undeclared Numbers must be wrapped with parentheses. Requirment of JavaScript.
-(3).days().ago();
-(6).months().ago();
-
-// Declared Number variables do not require parentheses. 
-var n = 6;
-n.months().ago();
-</code></pre>
- *  
- * @return {Date}    A new Date instance
- */
-Number.prototype.ago = function () {
-    var c = {};
-    c[this._dateElement] = this * -1;
-    return Date.now().add(c);
-};
-
-// Build dynamic date element, month name and day name functions.
 (function () {
-    var $D = Date.prototype, $N = Number.prototype;
-
-    /* Do NOT modify the following string tokens. These tokens are used to build dynamic functions. */
+    var $D = Date, $P = $D.prototype, $C = $D.CultureInfo, $N = Number.prototype;
+
+    // private
+    $P._orient = +1;
+
+    // private
+    $P._nth = null;
+
+    // private
+    $P._is = false;
+
+    // private
+    $P._same = false;
+    
+    // private
+    $P._isSecond = false;
+
+    // private
+    $N._dateElement = "day";
+
+    /** 
+     * Moves the date to the next instance of a date as specified by the subsequent date element function (eg. .day(), .month()), month name function (eg. .january(), .jan()) or day name function (eg. .friday(), fri()).
+     * Example
+    <pre><code>
+    Date.today().next().friday();
+    Date.today().next().fri();
+    Date.today().next().march();
+    Date.today().next().mar();
+    Date.today().next().week();
+    </code></pre>
+     * 
+     * @return {Date}    date
+     */
+    $P.next = function () {
+        this._orient = +1;
+        return this;
+    };
+
+    /** 
+     * Creates a new Date (Date.today()) and moves the date to the next instance of the date as specified by the subsequent date element function (eg. .day(), .month()), month name function (eg. .january(), .jan()) or day name function (eg. .friday(), fri()).
+     * Example
+    <pre><code>
+    Date.next().friday();
+    Date.next().fri();
+    Date.next().march();
+    Date.next().mar();
+    Date.next().week();
+    </code></pre>
+     * 
+     * @return {Date}    date
+     */    
+    $D.next = function () {
+        return $D.today().next();
+    };
+
+    /** 
+     * Moves the date to the previous instance of a date as specified by the subsequent date element function (eg. .day(), .month()), month name function (eg. .january(), .jan()) or day name function (eg. .friday(), fri()).
+     * Example
+    <pre><code>
+    Date.today().last().friday();
+    Date.today().last().fri();
+    Date.today().last().march();
+    Date.today().last().mar();
+    Date.today().last().week();
+    </code></pre>
+     *  
+     * @return {Date}    date
+     */
+    $P.last = $P.prev = $P.previous = function () {
+        this._orient = -1;
+        return this;
+    };
+
+    /** 
+     * Creates a new Date (Date.today()) and moves the date to the previous instance of the date as specified by the subsequent date element function (eg. .day(), .month()), month name function (eg. .january(), .jan()) or day name function (eg. .friday(), fri()).
+     * Example
+    <pre><code>
+    Date.last().friday();
+    Date.last().fri();
+    Date.previous().march();
+    Date.prev().mar();
+    Date.last().week();
+    </code></pre>
+     *  
+     * @return {Date}    date
+     */
+    $D.last = $D.prev = $D.previous = function () {
+        return $D.today().last();
+    };    
+
+    /** 
+     * Performs a equality check when followed by either a month name, day name or .weekday() function.
+     * Example
+    <pre><code>
+    Date.today().is().friday(); // true|false
+    Date.today().is().fri();
+    Date.today().is().march();
+    Date.today().is().mar();
+    </code></pre>
+     *  
+     * @return {Boolean}    true|false
+     */
+    $P.is = function () { 
+        this._is = true; 
+        return this; 
+    };
+
+    /** 
+     * Determines if two date objects occur on/in exactly the same instance of the subsequent date part function.
+     * The function .same() must be followed by a date part function (example: .day(), .month(), .year(), etc).
+     *
+     * An optional Date can be passed in the date part function. If now date is passed as a parameter, 'Now' is used. 
+     *
+     * The following example demonstrates how to determine if two dates fall on the exact same day.
+     *
+     * Example
+    <pre><code>
+    var d1 = Date.today(); // today at 00:00
+    var d2 = new Date();   // exactly now.
+
+    // Do they occur on the same day?
+    d1.same().day(d2); // true
+    
+     // Do they occur on the same hour?
+    d1.same().hour(d2); // false, unless d2 hour is '00' (midnight).
+    
+    // What if it's the same day, but one year apart?
+    var nextYear = Date.today().add(1).year();
+
+    d1.same().day(nextYear); // false, because the dates must occur on the exact same day. 
+    </code></pre>
+     *
+     * Scenario: Determine if a given date occurs during some week period 2 months from now. 
+     *
+     * Example
+    <pre><code>
+    var future = Date.today().add(2).months();
+    return someDate.same().week(future); // true|false;
+    </code></pre>
+     *  
+     * @return {Boolean}    true|false
+     */    
+    $P.same = function () { 
+        this._same = true;
+        this._isSecond = false;
+        return this; 
+    };
+
+    /** 
+     * Determines if the current date/time occurs during Today. Must be preceded by the .is() function.
+     * Example
+    <pre><code>
+    someDate.is().today();    // true|false
+    new Date().is().today();  // true
+    Date.today().is().today();// true
+    Date.today().add(-1).day().is().today(); // false
+    </code></pre>
+     *  
+     * @return {Boolean}    true|false
+     */    
+    $P.today = function () {
+        return this.same().day();
+    };
+
+    /** 
+     * Determines if the current date is a weekday. This function must be preceded by the .is() function.
+     * Example
+    <pre><code>
+    Date.today().is().weekday(); // true|false
+    </code></pre>
+     *  
+     * @return {Boolean}    true|false
+     */
+    $P.weekday = function () {
+        if (this._is) { 
+            this._is = false;
+            return (!this.is().sat() && !this.is().sun());
+        }
+        return false;
+    };
+
+    /** 
+     * Sets the Time of the current Date instance. A string "6:15 pm" or config object {hour:18, minute:15} are accepted.
+     * Example
+    <pre><code>
+    // Set time to 6:15pm with a String
+    Date.today().at("6:15pm");
+
+    // Set time to 6:15pm with a config object
+    Date.today().at({hour:18, minute:15});
+    </code></pre>
+     *  
+     * @return {Date}    date
+     */
+    $P.at = function (time) {
+        return (typeof time === "string") ? $D.parse(this.toString("d") + " " + time) : this.set(time);
+    }; 
+        
+    /** 
+     * Creates a new Date() and adds this (Number) to the date based on the preceding date element function (eg. second|minute|hour|day|month|year).
+     * Example
+    <pre><code>
+    // Undeclared Numbers must be wrapped with parentheses. Requirment of JavaScript.
+    (3).days().fromNow();
+    (6).months().fromNow();
+
+    // Declared Number variables do not require parentheses. 
+    var n = 6;
+    n.months().fromNow();
+    </code></pre>
+     *  
+     * @return {Date}    A new Date instance
+     */
+    $N.fromNow = $N.after = function (date) {
+        var c = {};
+        c[this._dateElement] = this;
+        return ((!date) ? new Date() : date.clone()).add(c);
+    };
+
+    /** 
+     * Creates a new Date() and subtract this (Number) from the date based on the preceding date element function (eg. second|minute|hour|day|month|year).
+     * Example
+    <pre><code>
+    // Undeclared Numbers must be wrapped with parentheses. Requirment of JavaScript.
+    (3).days().ago();
+    (6).months().ago();
+
+    // Declared Number variables do not require parentheses. 
+    var n = 6;
+    n.months().ago();
+    </code></pre>
+     *  
+     * @return {Date}    A new Date instance
+     */
+    $N.ago = $N.before = function (date) {
+        var c = {};
+        c[this._dateElement] = this * -1;
+        return ((!date) ? new Date() : date.clone()).add(c);
+    };
+
+    // Do NOT modify the following string tokens. These tokens are used to build dynamic functions.
+    // All culture-specific strings can be found in the CultureInfo files. See /trunk/src/globalization/.
     var dx = ("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),
         mx = ("january february march april may june july august september october november december").split(/\s/),
         px = ("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),
+        pxf = ("Milliseconds Seconds Minutes Hours Date Week Month FullYear").split(/\s/),
+		nth = ("final first second third fourth fifth").split(/\s/),
         de;
-    
+
+   /** 
+     * Returns an object literal of all the date parts.
+     * Example
+    <pre><code>
+	var o = new Date().toObject();
+	
+	// { year: 2008, month: 4, week: 20, day: 13, hour: 18, minute: 9, second: 32, millisecond: 812 }
+	
+	// The object properties can be referenced directly from the object.
+	
+	alert(o.day);  // alerts "13"
+	alert(o.year); // alerts "2008"
+    </code></pre>
+     *  
+     * @return {Date}    An object literal representing the original date object.
+     */
+    $P.toObject = function () {
+        var o = {};
+        for (var i = 0; i < px.length; i++) {
+            o[px[i].toLowerCase()] = this["get" + pxf[i]]();
+        }
+        return o;
+    }; 
+   
+   /** 
+     * Returns a date created from an object literal. Ignores the .week property if set in the config. 
+     * Example
+    <pre><code>
+	var o = new Date().toObject();
+	
+	return Date.fromObject(o); // will return the same date. 
+
+    var o2 = {month: 1, day: 20, hour: 18}; // birthday party!
+    Date.fromObject(o2);
+    </code></pre>
+     *  
+     * @return {Date}    An object literal representing the original date object.
+     */    
+    $D.fromObject = function(config) {
+        config.week = null;
+        return Date.today().set(config);
+    };
+        
     // Create day name functions and abbreviated day name functions (eg. monday(), friday(), fri()).
     var df = function (n) {
@@ -150,10 +314,55 @@
                 return this.getDay() == n; 
             }
+            if (this._nth !== null) {
+                // If the .second() function was called earlier, remove the _orient 
+                // from the date, and then continue.
+                // This is required because 'second' can be used in two different context.
+                // 
+                // Example
+                //
+                //   Date.today().add(1).second();
+                //   Date.march().second().monday();
+                // 
+                // Things get crazy with the following...
+                //   Date.march().add(1).second().second().monday(); // but it works!!
+                //  
+                if (this._isSecond) {
+                    this.addSeconds(this._orient * -1);
+                }
+                // make sure we reset _isSecond
+                this._isSecond = false;
+
+                var ntemp = this._nth;
+                this._nth = null;
+                var temp = this.clone().moveToLastDayOfMonth();
+                this.moveToNthOccurrence(n, ntemp);
+                if (this > temp) {
+                    throw new RangeError($D.getDayName(n) + " does not occur " + ntemp + " times in the month of " + $D.getMonthName(temp.getMonth()) + " " + temp.getFullYear() + ".");
+                }
+                return this;
+            }			
             return this.moveToDayOfWeek(n, this._orient);
         };
     };
     
-    for (var i = 0 ; i < dx.length ; i++) { 
-        $D[dx[i]] = $D[dx[i].substring(0, 3)] = df(i);
+    var sdf = function (n) {
+        return function () {
+            var t = $D.today(), shift = n - t.getDay();
+            if (n === 0 && $C.firstDayOfWeek === 1 && t.getDay() !== 0) {
+                shift = shift + 7;
+            }
+            return t.addDays(shift);
+        };
+    };
+	
+    for (var i = 0; i < dx.length; i++) {
+        // Create constant static Day Name variables. Example: Date.MONDAY or Date.MON
+        $D[dx[i].toUpperCase()] = $D[dx[i].toUpperCase().substring(0, 3)] = i;
+
+        // Create Day Name functions. Example: Date.monday() or Date.mon()
+        $D[dx[i]] = $D[dx[i].substring(0, 3)] = sdf(i);
+
+        // Create Day Name instance functions. Example: Date.today().next().monday()
+        $P[dx[i]] = $P[dx[i].substring(0, 3)] = df(i);
     }
     
@@ -169,19 +378,58 @@
     };
     
-    for (var j = 0 ; j < mx.length ; j++) { 
-        $D[mx[j]] = $D[mx[j].substring(0, 3)] = mf(j);
+    var smf = function (n) {
+        return function () {
+            return $D.today().set({ month: n, day: 1 });
+        };
+    };
+    
+    for (var j = 0; j < mx.length; j++) {
+        // Create constant static Month Name variables. Example: Date.MARCH or Date.MAR
+        $D[mx[j].toUpperCase()] = $D[mx[j].toUpperCase().substring(0, 3)] = j;
+
+        // Create Month Name functions. Example: Date.march() or Date.mar()
+        $D[mx[j]] = $D[mx[j].substring(0, 3)] = smf(j);
+
+        // Create Month Name instance functions. Example: Date.today().next().march()
+        $P[mx[j]] = $P[mx[j].substring(0, 3)] = mf(j);
     }
     
     // Create date element functions and plural date element functions used with Date (eg. day(), days(), months()).
-    var ef = function (j) { 
+    var ef = function (j) {
         return function () {
-            if (j.substring(j.length - 1) != "s") { 
+            // if the .second() function was called earlier, the _orient 
+            // has alread been added. Just return this and reset _isSecond.
+            if (this._isSecond) {
+                this._isSecond = false;
+                return this;
+            }
+
+            if (this._same) {
+                this._same = this._is = false; 
+                var o1 = this.toObject(),
+                    o2 = (arguments[0] || new Date()).toObject(),
+                    v = "",
+                    k = j.toLowerCase();
+                    
+                for (var m = (px.length - 1); m > -1; m--) {
+                    v = px[m].toLowerCase();
+                    if (o1[v] != o2[v]) {
+                        return false;
+                    }
+                    if (k == v) {
+                        break;
+                    }
+                }
+                return true;
+            }
+            
+            if (j.substring(j.length - 1) != "s") {
                 j += "s"; 
             }
-            return this["add" + j](this._orient); 
-        };
-    };
-    
-    // Create date element functions and plural date element functions used with Number (eg. day(), days(), months()).
+            return this["add" + j](this._orient);
+        };
+    };
+    
+    
     var nf = function (n) {
         return function () {
@@ -190,70 +438,38 @@
         };
     };
-    
-    for (var k = 0 ; k < px.length ; k++) {
+   
+    for (var k = 0; k < px.length; k++) {
         de = px[k].toLowerCase();
-        $D[de] = $D[de + "s"] = ef(px[k]);
+    
+        // Create date element functions and plural date element functions used with Date (eg. day(), days(), months()).
+        $P[de] = $P[de + "s"] = ef(px[k]);
+        
+        // Create date element functions and plural date element functions used with Number (eg. day(), days(), months()).
         $N[de] = $N[de + "s"] = nf(de);
     }
+    
+    $P._ss = ef("Second");
+	
+    var nthfn = function (n) {
+        return function (dayOfWeek) {
+            if (this._same) {
+                return this._ss(arguments[0]);
+            }
+            if (dayOfWeek || dayOfWeek === 0) {
+                return this.moveToNthOccurrence(dayOfWeek, n);
+            }
+            this._nth = n;
+
+            // if the operator is 'second' add the _orient, then deal with it later...
+            if (n === 2 && (dayOfWeek === undefined || dayOfWeek === null)) {
+                this._isSecond = true;
+                return this.addSeconds(this._orient);
+            }
+            return this;
+        };
+    };
+
+    for (var l = 0; l < nth.length; l++) {
+        $P[nth[l]] = (l === 0) ? nthfn(-1) : nthfn(l);
+    }
 }());
-
-/**
- * Converts the current date instance into a JSON string value.
- * @return {String}  JSON string of date
- */
-Date.prototype.toJSONString = function () {
-    return this.toString("yyyy-MM-ddThh:mm:ssZ");
-};
-
-/**
- * Converts the current date instance to a string using the culture specific shortDatePattern.
- * @return {String}  A string formatted as per the culture specific shortDatePattern
- */
-Date.prototype.toShortDateString = function () {
-    return this.toString(Date.CultureInfo.formatPatterns.shortDatePattern);
-};
-
-/**
- * Converts the current date instance to a string using the culture specific longDatePattern.
- * @return {String}  A string formatted as per the culture specific longDatePattern
- */
-Date.prototype.toLongDateString = function () {
-    return this.toString(Date.CultureInfo.formatPatterns.longDatePattern);
-};
-
-/**
- * Converts the current date instance to a string using the culture specific shortTimePattern.
- * @return {String}  A string formatted as per the culture specific shortTimePattern
- */
-Date.prototype.toShortTimeString = function () {
-    return this.toString(Date.CultureInfo.formatPatterns.shortTimePattern);
-};
-
-/**
- * Converts the current date instance to a string using the culture specific longTimePattern.
- * @return {String}  A string formatted as per the culture specific longTimePattern
- */
-Date.prototype.toLongTimeString = function () {
-    return this.toString(Date.CultureInfo.formatPatterns.longTimePattern);
-};
-
-/**
- * Get the ordinal suffix of the current day.
- * @return {String}  "st, "nd", "rd" or "th"
- */
-Date.prototype.getOrdinal = function () {
-    switch (this.getDate()) {
-    case 1: 
-    case 21: 
-    case 31: 
-        return "st";
-    case 2: 
-    case 22: 
-        return "nd";
-    case 3: 
-    case 23: 
-        return "rd";
-    default: 
-        return "th";
-    }
-};
Index: /trunk/prototype/plugins/datejs/time-debug.js
===================================================================
--- /trunk/prototype/plugins/datejs/time-debug.js	(revision 5341)
+++ /trunk/prototype/plugins/datejs/time-debug.js	(revision 7143)
@@ -1,174 +1,231 @@
 /**
- * Version: 1.0 Alpha-1 
- * Build Date: 12-Nov-2007
- * Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
- * License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
- * Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
+ * @version: 1.0 Alpha-1
+ * @author: Coolite Inc. http://www.coolite.com/
+ * @date: 2008-04-13
+ * @copyright: Copyright (c) 2006-2008, Coolite Inc. (http://www.coolite.com/). All rights reserved.
+ * @license: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. 
+ * @website: http://www.datejs.com/
  */
  
 /* 
+ * TimeSpan(milliseconds);
+ * TimeSpan(days, hours, minutes, seconds);
  * TimeSpan(days, hours, minutes, seconds, milliseconds);
- * TimeSpan(milliseconds);
- */
-TimeSpan = function (days, hours, minutes, seconds, milliseconds) {
-    this.days = 0;
-    this.hours = 0;
-    this.minutes = 0;
-    this.seconds = 0;
-    this.milliseconds = 0;
-    
-    if (arguments.length == 5) { 
-        this.days = days; 
-        this.hours = hours; 
-        this.minutes = minutes; 
-        this.seconds = seconds; 
-        this.milliseconds = milliseconds; 
-    } 
-    else if (arguments.length == 1 && typeof days == "number") {
+ */
+var TimeSpan = function (days, hours, minutes, seconds, milliseconds) {
+    var attrs = "days hours minutes seconds milliseconds".split(/\s+/);
+    
+    var gFn = function (attr) { 
+        return function () { 
+            return this[attr]; 
+        }; 
+    };
+	
+    var sFn = function (attr) { 
+        return function (val) { 
+            this[attr] = val; 
+            return this; 
+        }; 
+    };
+	
+    for (var i = 0; i < attrs.length ; i++) {
+        var $a = attrs[i], $b = $a.slice(0, 1).toUpperCase() + $a.slice(1);
+        TimeSpan.prototype[$a] = 0;
+        TimeSpan.prototype["get" + $b] = gFn($a);
+        TimeSpan.prototype["set" + $b] = sFn($a);
+    }
+
+    if (arguments.length == 4) { 
+        this.setDays(days); 
+        this.setHours(hours); 
+        this.setMinutes(minutes); 
+        this.setSeconds(seconds); 
+    } else if (arguments.length == 5) { 
+        this.setDays(days); 
+        this.setHours(hours); 
+        this.setMinutes(minutes); 
+        this.setSeconds(seconds); 
+        this.setMilliseconds(milliseconds); 
+    } else if (arguments.length == 1 && typeof days == "number") {
         var orient = (days < 0) ? -1 : +1;
-        this.milliseconds = Math.abs(days);
-        
-        this.days = Math.floor(this.milliseconds / (24 * 60 * 60 * 1000)) * orient;
-        this.milliseconds = this.milliseconds % (24 * 60 * 60 * 1000);
-
-        this.hours = Math.floor(this.milliseconds / (60 * 60 * 1000)) * orient;
-        this.milliseconds = this.milliseconds % (60 * 60 * 1000);
-
-        this.minutes = Math.floor(this.milliseconds / (60 * 1000)) * orient;
-        this.milliseconds = this.milliseconds % (60 * 1000);
-
-        this.seconds = Math.floor(this.milliseconds / 1000) * orient;
-        this.milliseconds = this.milliseconds % 1000;
-
-        this.milliseconds = this.milliseconds * orient;
-        return this;
-    } 
-    else {
-        return null;
-    }
-};
-
-TimeSpan.prototype.compare = function (timeSpan) {
-    var t1 = new Date(1970, 1, 1, this.hours(), this.minutes(), this.seconds()), t2;
-    if (timeSpan === null) { 
-        t2 = new Date(1970, 1, 1, 0, 0, 0); 
-    }
-    else { 
-        t2 = new Date(1970, 1, 1, timeSpan.hours(), timeSpan.minutes(), timeSpan.seconds()); /* t2 = t2.addDays(timeSpan.days()); */ 
-    }
-    return (t1 > t2) ? 1 : (t1 < t2) ? -1 : 0;
-};
-
-TimeSpan.prototype.add = function (timeSpan) { 
-    return (timeSpan === null) ? this : this.addSeconds(timeSpan.getTotalMilliseconds() / 1000); 
-};
-
-TimeSpan.prototype.subtract = function (timeSpan) { 
-    return (timeSpan === null) ? this : this.addSeconds(-timeSpan.getTotalMilliseconds() / 1000); 
-};
-
-TimeSpan.prototype.addDays = function (n) { 
-    return new TimeSpan(this.getTotalMilliseconds() + (n * 24 * 60 * 60 * 1000)); 
-};
-
-TimeSpan.prototype.addHours = function (n) { 
-    return new TimeSpan(this.getTotalMilliseconds() + (n * 60 * 60 * 1000)); 
-};
-
-TimeSpan.prototype.addMinutes = function (n) { 
-    return new TimeSpan(this.getTotalMilliseconds() + (n * 60 * 1000)); 
-};
-
-TimeSpan.prototype.addSeconds = function (n) {
-    return new TimeSpan(this.getTotalMilliseconds() + (n * 1000)); 
-};
-
-TimeSpan.prototype.addMilliseconds = function (n) {
-    return new TimeSpan(this.getTotalMilliseconds() + n); 
-};
-
-TimeSpan.prototype.getTotalMilliseconds = function () {
-    return (this.days() * (24 * 60 * 60 * 1000)) + (this.hours() * (60 * 60 * 1000)) + (this.minutes() * (60 * 1000)) + (this.seconds() * (1000)); 
-};
-
-TimeSpan.prototype.get12HourHour = function () {
-    return ((h = this.hours() % 12) ? h : 12); 
-};
-
-TimeSpan.prototype.getDesignator = function () { 
-    return (this.hours() < 12) ? Date.CultureInfo.amDesignator : Date.CultureInfo.pmDesignator;
-};
-
-TimeSpan.prototype.toString = function (format) {
-    function _toString() {
-        if (this.days() !== null && this.days() > 0) {
-            return this.days() + "." + this.hours() + ":" + p(this.minutes()) + ":" + p(this.seconds());
-        }
-        else { 
-            return this.hours() + ":" + p(this.minutes()) + ":" + p(this.seconds());
-        }
-    }
-    function p(s) {
-        return (s.toString().length < 2) ? "0" + s : s;
-    } 
-    var self = this;
-    return format ? format.replace(/d|dd|HH|H|hh|h|mm|m|ss|s|tt|t/g, 
-    function (format) {
-        switch (format) {
-        case "d":	
-            return self.days();
-        case "dd":	
-            return p(self.days());
-        case "H":	
-            return self.hours();
-        case "HH":	
-            return p(self.hours());
-        case "h":	
-            return self.get12HourHour();
-        case "hh":	
-            return p(self.get12HourHour());
-        case "m":	
-            return self.minutes();
-        case "mm":	
-            return p(self.minutes());
-        case "s":	
-            return self.seconds();
-        case "ss":	
-            return p(self.seconds());
-        case "t":	
-            return ((this.hours() < 12) ? Date.CultureInfo.amDesignator : Date.CultureInfo.pmDesignator).substring(0, 1);
-        case "tt":	
-            return (this.hours() < 12) ? Date.CultureInfo.amDesignator : Date.CultureInfo.pmDesignator;
-        }
-    }
-    ) : this._toString();
+        this.setMilliseconds(Math.abs(days));
+        
+        this.setDays(Math.floor(this.getMilliseconds() / 86400000) * orient);
+        this.setMilliseconds(this.getMilliseconds() % 86400000);
+
+        this.setHours(Math.floor(this.getMilliseconds() / 3600000) * orient);
+        this.setMilliseconds(this.getMilliseconds() % 3600000);
+
+        this.setMinutes(Math.floor(this.getMilliseconds() / 60000) * orient);
+        this.setMilliseconds(this.getMilliseconds() % 60000);
+
+        this.setSeconds(Math.floor(this.getMilliseconds() / 1000) * orient);
+        this.setMilliseconds(this.getMilliseconds() % 1000);
+
+        this.setMilliseconds(this.getMilliseconds() * orient);
+    }
+
+    this.getTotalMilliseconds = function () {
+        return (this.getDays() * 86400000) + (this.getHours() * 3600000) + (this.getMinutes() * 60000) + (this.getSeconds() * 1000); 
+    };
+    
+    this.compareTo = function (time) {
+        var t1 = new Date(1970, 1, 1, this.getHours(), this.getMinutes(), this.getSeconds()), t2;
+        if (time === null) { 
+            t2 = new Date(1970, 1, 1, 0, 0, 0); 
+        }
+        else {
+            t2 = new Date(1970, 1, 1, time.getHours(), time.getMinutes(), time.getSeconds());
+        }
+        return (t1 < t2) ? -1 : (t1 > t2) ? 1 : 0;
+    };
+
+    this.equals = function (time) {
+        return (this.compareTo(time) === 0);
+    };    
+
+    this.add = function (time) { 
+        return (time === null) ? this : this.addSeconds(time.getTotalMilliseconds() / 1000); 
+    };
+
+    this.subtract = function (time) { 
+        return (time === null) ? this : this.addSeconds(-time.getTotalMilliseconds() / 1000); 
+    };
+
+    this.addDays = function (n) { 
+        return new TimeSpan(this.getTotalMilliseconds() + (n * 86400000)); 
+    };
+
+    this.addHours = function (n) { 
+        return new TimeSpan(this.getTotalMilliseconds() + (n * 3600000)); 
+    };
+
+    this.addMinutes = function (n) { 
+        return new TimeSpan(this.getTotalMilliseconds() + (n * 60000)); 
+    };
+
+    this.addSeconds = function (n) {
+        return new TimeSpan(this.getTotalMilliseconds() + (n * 1000)); 
+    };
+
+    this.addMilliseconds = function (n) {
+        return new TimeSpan(this.getTotalMilliseconds() + n); 
+    };
+
+    this.get12HourHour = function () {
+        return (this.getHours() > 12) ? this.getHours() - 12 : (this.getHours() === 0) ? 12 : this.getHours();
+    };
+
+    this.getDesignator = function () { 
+        return (this.getHours() < 12) ? Date.CultureInfo.amDesignator : Date.CultureInfo.pmDesignator;
+    };
+
+    this.toString = function (format) {
+        this._toString = function () {
+            if (this.getDays() !== null && this.getDays() > 0) {
+                return this.getDays() + "." + this.getHours() + ":" + this.p(this.getMinutes()) + ":" + this.p(this.getSeconds());
+            }
+            else { 
+                return this.getHours() + ":" + this.p(this.getMinutes()) + ":" + this.p(this.getSeconds());
+            }
+        };
+        
+        this.p = function (s) {
+            return (s.toString().length < 2) ? "0" + s : s;
+        };
+        
+        var me = this;
+        
+        return format ? format.replace(/dd?|HH?|hh?|mm?|ss?|tt?/g, 
+        function (format) {
+            switch (format) {
+            case "d":	
+                return me.getDays();
+            case "dd":	
+                return me.p(me.getDays());
+            case "H":	
+                return me.getHours();
+            case "HH":	
+                return me.p(me.getHours());
+            case "h":	
+                return me.get12HourHour();
+            case "hh":	
+                return me.p(me.get12HourHour());
+            case "m":	
+                return me.getMinutes();
+            case "mm":	
+                return me.p(me.getMinutes());
+            case "s":	
+                return me.getSeconds();
+            case "ss":	
+                return me.p(me.getSeconds());
+            case "t":	
+                return ((me.getHours() < 12) ? Date.CultureInfo.amDesignator : Date.CultureInfo.pmDesignator).substring(0, 1);
+            case "tt":	
+                return (me.getHours() < 12) ? Date.CultureInfo.amDesignator : Date.CultureInfo.pmDesignator;
+            }
+        }
+        ) : this._toString();
+    };
+    return this;
+};    
+
+/**
+ * Gets the time of day for this date instances. 
+ * @return {TimeSpan} TimeSpan
+ */
+Date.prototype.getTimeOfDay = function () {
+    return new TimeSpan(0, this.getHours(), this.getMinutes(), this.getSeconds(), this.getMilliseconds());
 };
 
 /* 
  * TimePeriod(startDate, endDate);
+ * TimePeriod(years, months, days, hours, minutes, seconds, milliseconds);
  */
 var TimePeriod = function (years, months, days, hours, minutes, seconds, milliseconds) {
-    this.years = 0;
-    this.months = 0;
-    this.days = 0;
-    this.hours = 0;
-    this.minutes = 0;
-    this.seconds = 0;
-    this.milliseconds = 0;
-    
-    // startDate and endDate as arguments
-    if (arguments.length == 2 && arguments[0] instanceof Date && arguments[1] instanceof Date) {
-    
-        var date1 = years.clone();
-        var date2 = months.clone();
-    
-        var temp = date1.clone();
-        var orient = (date1 > date2) ? -1 : +1;
-        
-        this.years = date2.getFullYear() - date1.getFullYear();
+    var attrs = "years months days hours minutes seconds milliseconds".split(/\s+/);
+    
+    var gFn = function (attr) { 
+        return function () { 
+            return this[attr]; 
+        }; 
+    };
+	
+    var sFn = function (attr) { 
+        return function (val) { 
+            this[attr] = val; 
+            return this; 
+        }; 
+    };
+	
+    for (var i = 0; i < attrs.length ; i++) {
+        var $a = attrs[i], $b = $a.slice(0, 1).toUpperCase() + $a.slice(1);
+        TimePeriod.prototype[$a] = 0;
+        TimePeriod.prototype["get" + $b] = gFn($a);
+        TimePeriod.prototype["set" + $b] = sFn($a);
+    }
+    
+    if (arguments.length == 7) { 
+        this.years = years;
+        this.months = months;
+        this.setDays(days);
+        this.setHours(hours); 
+        this.setMinutes(minutes); 
+        this.setSeconds(seconds); 
+        this.setMilliseconds(milliseconds);
+    } else if (arguments.length == 2 && arguments[0] instanceof Date && arguments[1] instanceof Date) {
+        // startDate and endDate as arguments
+    
+        var d1 = years.clone();
+        var d2 = months.clone();
+    
+        var temp = d1.clone();
+        var orient = (d1 > d2) ? -1 : +1;
+        
+        this.years = d2.getFullYear() - d1.getFullYear();
         temp.addYears(this.years);
         
         if (orient == +1) {
-            if (temp > date2) {
+            if (temp > d2) {
                 if (this.years !== 0) {
                     this.years--;
@@ -176,5 +233,5 @@
             }
         } else {
-            if (temp < date2) {
+            if (temp < d2) {
                 if (this.years !== 0) {
                     this.years++;
@@ -183,34 +240,30 @@
         }
         
-        date1.addYears(this.years);
+        d1.addYears(this.years);
 
         if (orient == +1) {
-            while (date1 < date2 && date1.clone().addDays(date1.getDaysInMonth()) < date2) {
-                date1.addMonths(1);
+            while (d1 < d2 && d1.clone().addDays(Date.getDaysInMonth(d1.getYear(), d1.getMonth()) ) < d2) {
+                d1.addMonths(1);
                 this.months++;
             }
         }
         else {
-            while (date1 > date2 && date1.clone().addDays(-date1.getDaysInMonth()) > date2) {
-                date1.addMonths(-1);
+            while (d1 > d2 && d1.clone().addDays(-d1.getDaysInMonth()) > d2) {
+                d1.addMonths(-1);
                 this.months--;
             }
         }
         
-        var diff = date2 - date1;
+        var diff = d2 - d1;
 
         if (diff !== 0) {
             var ts = new TimeSpan(diff);
-            
-            this.days = ts.days;
-            this.hours = ts.hours;
-            this.minutes = ts.minutes;
-            this.seconds = ts.seconds;
-            this.milliseconds = ts.milliseconds;
-        }
-
-        // UTC Hacks required...
-        return this;
-    }
- 
+            this.setDays(ts.getDays());
+            this.setHours(ts.getHours());
+            this.setMinutes(ts.getMinutes());
+            this.setSeconds(ts.getSeconds());
+            this.setMilliseconds(ts.getMilliseconds());
+        }
+    }
+    return this;
 };
Index: /trunk/prototype/modules/calendar/templates/preferences_calendar.ejs
===================================================================
--- /trunk/prototype/modules/calendar/templates/preferences_calendar.ejs	(revision 6996)
+++ /trunk/prototype/modules/calendar/templates/preferences_calendar.ejs	(revision 7143)
@@ -23,6 +23,6 @@
 				<label for="hourFormat">Formato de hora:</label>
 				<select name="hourFormat" >
-					<option value="HH:mm" <%= data.preferences.hourFormat =='HH:mm' ? 'selected="selected"':'' %>>13:00</option>
-					<option value="hh:mm tt" <%= data.preferences.hourFormat =='hh:mm tt' ? 'selected="selected"':'' %>>01:00pm</option>
+					<option value="HH:mm" <%= data.preferences.hourFormat =='HH:mm' ? 'selected="selected"':'' %>>24 horas</option>
+					<option value="hh:mm tt" <%= data.preferences.hourFormat =='hh:mm tt' ? 'selected="selected"':'' %>>12 horas (am/pm)</option>
 				</select>
 			</p>
