Index: branches/2.4/prototype/plugins/datejs/parser-debug.js
===================================================================
--- branches/2.4/prototype/plugins/datejs/parser-debug.js	(revision 5341)
+++ branches/2.4/prototype/plugins/datejs/parser-debug.js	(revision 7151)
@@ -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); 
+    };	
+}());
