<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>images/dreadnaught/page-bg-darkgreen-start.png</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,55 +1,7 @@
-## APRIL 15 TASKS
-* Login/splash
-	* Need to listen for Ajax errors on trends (just leave msg in inline spinner)
-	* insert way to pull news to send out updates
-* My Timeline
-* Message Detail
-* User Detail
-	* Need to listen for Ajax errors on user timeline
-* Search
-* Preferences
-
-
-
-* Notifications
-* Posting
-	* Need to listen for Ajax errors in posting
-SpazTwit
-	* Need to be able to lookup and return object for spcific tweet
-* Login/splash
-	* How to map *back* gesture to arbitrary action?
-* My Timeline
-	* Weirdness with spacing in timeline sometimes
-	* items sometimes load out of order (New data will load before cached)
-* Message Detail
-	* reveal IRT instead of just linking to it
-	* add star to favorite button (that reflects status)
-* User Detail
-	* Data timeline should only load on request
-	* add ability to view user's favorites
-* Search
-	* Trends button needs to actually do something
-* Preferences
-	* Twitter API Base URL
-* Notifications
-* Posting
-	* posting a dm returns the last &quot;regular&quot; message and prepends it to the timeline (even if dupe)
-
-SpazTwit
-	* Add generic event raised on Ajax errors
-	* Make sure all methods raise specific error events
-	* add event for &quot;no new messages&quot; so view can do any necessary updates
-	* complete min_age limits on refresh, and &quot;force refresh&quot; functionality
-	* Need to be able to lookup and return object for specific tweet
-
-
 ## UPCOMING FEATURES
 	* Support stocktwits links ($JAVA, $PALM)
 	* User lookup shortcut (from App menu)
-	* Photo posting
-	* Photo taking and posting
 	* Search history and saved searches (use API)
-	* Updating location with GPS services
 	* View User's favs
 	* Ping.fm posting
 	* People Picker widget to integrate with contacts for posting(?)</diff>
      <filename>TODO</filename>
    </modified>
    <modified>
      <diff>@@ -24,8 +24,8 @@ function AppAssistant(appController) {
 			var obj = Mojo.parseJSON(str);
 			return obj;
 		} catch(e) {
-			dump('There was a problem decoding the JSON string');
-			dump('Here is the JSON string: '+str);
+			sch.warn('There was a problem decoding the JSON string');
+			sch.warn('Here is the JSON string: '+str);
 			return null;
 		}
 		
@@ -64,8 +64,8 @@ AppAssistant.prototype.handleLaunch = function(launchParams) {
 	Mojo.Log.info(&quot;Logging from AppAssistant handleLaunch&quot;);
 	var thisA = this;
 
-	dump(&quot;Launch Parameters:&quot;);
-	dump(launchParams);
+	Mojo.Log.info(&quot;Launch Parameters:&quot;);
+	Mojo.Log.info(launchParams);
 
 	Spaz.closeDashboard();
 
@@ -108,7 +108,7 @@ AppAssistant.prototype.handleLaunch = function(launchParams) {
  */
 AppAssistant.prototype.handleCommand = function(event){
 	
-	dump(event.command);
+	sch.debug(event.command);
 	
 	if (event.type == Mojo.Event.command) {
 		switch (event.command) {</diff>
      <filename>app/assistants/app-assistant.js</filename>
    </modified>
    <modified>
      <diff>@@ -51,6 +51,8 @@ function MyTimelineAssistant(argFromPusher) {
 
 MyTimelineAssistant.prototype.setup = function() {
 	
+	sch.debug('SETUP');
+	
 	var thisA = this;
 	
 	// this.tweetsModel = [];
@@ -128,27 +130,100 @@ MyTimelineAssistant.prototype.setup = function() {
 	sch.listen(document, 'temp_cache_cleared', this.resetTwitState);
 	
 	this.loadTimelineCache();
+	
+	
+	this.initTimeline();
+	
 };
 
 
 
 MyTimelineAssistant.prototype.activate = function(event) {
-
+	
+	sch.debug('ACTIVATE');
+	
 	var thisA = this; // for closures
 
 	var tts = sc.app.prefs.get('timeline-text-size');
 	this.setTimelineTextSize('#my-timeline', tts);
 	
-	/* put in event handlers here that should only be in effect when this scene is active. For
-	   example, key handlers that are observing the document */
 	this.activateStarted = true;
 	
+
 	/*
 		Prepare for timeline entry taps
 	*/
 	this.bindTimelineEntryTaps('#my-timeline');
 
 	/*
+		start the mytimeline 
+	*/
+	if (this.refreshOnActivate) {
+		this.mytl.start();
+		this.refreshOnActivate = false;
+	}
+
+};
+
+
+MyTimelineAssistant.prototype.deactivate = function(event) {
+	
+	sch.debug('DEACTIVATE');
+	
+	/* remove any event handlers you added in activate and do any other cleanup that should happen before
+	   this scene is popped or another scene is pushed on top */
+	
+	/*
+		stop listening for timeline entry taps
+	*/
+	this.unbindTimelineEntryTaps('#my-timeline');
+	
+	
+
+	
+	
+	/*
+		save timeline cache
+	*/
+	this.saveTimelineCache();
+	
+};
+
+
+
+MyTimelineAssistant.prototype.cleanup = function(event) {
+	
+	sch.dump('CLEANUP');
+	
+	/* this function should do any cleanup needed before the scene is destroyed as 
+	   a result of being popped off the scene stack */
+	
+	// jQuery().unbind('load_from_mytimeline_cache_done');
+
+	this.cleanupTimeline();
+
+	this.stopTrackingStageActiveState();
+	
+	sch.unlisten(document, 'temp_cache_cleared', this.resetTwitState);
+	
+	
+	// this.stopRefresher();
+};
+
+
+/**
+ * initializes the timeline 
+ */
+MyTimelineAssistant.prototype.initTimeline = function() {
+	
+	sch.debug('initializing Timeline in assistant');
+	
+	
+	var thisA = this;
+	
+
+
+	/*
 		set up the public timeline
 	*/
 	this.mytl   = new SpazTimeline({
@@ -238,57 +313,27 @@ MyTimelineAssistant.prototype.activate = function(event) {
 		override the standard removeExtraItems
 	*/
 	this.mytl.removeExtraItems = this.removeExtraItems;
-	
-	/*
-		start the mytimeline 
-	*/
-	if (this.refreshOnActivate) {
-		this.mytl.start();
-		this.refreshOnActivate = false;
-	}
-
 };
 
 
-MyTimelineAssistant.prototype.deactivate = function(event) {
-	
-	sch.dump('DEACTIVATE');
-	
-	/* remove any event handlers you added in activate and do any other cleanup that should happen before
-	   this scene is popped or another scene is pushed on top */
-	
-	/*
-		stop listening for timeline entry taps
-	*/
-	this.unbindTimelineEntryTaps('#my-timeline');
 
-	/*
-		unbind and stop refresher for public timeline
-	*/
-	this.mytl.cleanup();
+MyTimelineAssistant.prototype.cleanupTimeline = function() {
 	
-	this.saveTimelineCache();
+	sch.debug('cleaning up Timeline in assistant');
 	
-};
-
-MyTimelineAssistant.prototype.cleanup = function(event) {
-	
-	sch.dump('CLEANUP');
-	
-	/* this function should do any cleanup needed before the scene is destroyed as 
-	   a result of being popped off the scene stack */
-	
-	// jQuery().unbind('load_from_mytimeline_cache_done');
-
-	this.stopTrackingStageActiveState();
-	
-	sch.unlisten(document, 'temp_cache_cleared', this.resetTwitState);
+	var thisA = this;
 	
+	if (this.mytl &amp;&amp; this.mytl.cleanup) {
+		/*
+			unbind and stop refresher for public timeline
+		*/
+		this.mytl.cleanup();		
+	}
 	
-	// this.stopRefresher();
 };
 
 
+
 MyTimelineAssistant.prototype.loadTimelineCache = function() {
 	
 	var thisA = this;</diff>
      <filename>app/assistants/my-timeline-assistant.js</filename>
    </modified>
    <modified>
      <diff>@@ -8,7 +8,7 @@
 		&lt;/div&gt;		
 	&lt;/div&gt; --&gt;
 	
-	&lt;div id=&quot;activity-spinner-favorites-container&quot;&gt;
+	&lt;div id=&quot;activity-spinner-favorites-container&quot; class='spaz-activity-spinner-container'&gt;
 		&lt;div class=&quot;palm-row first&quot;&gt;
 			&lt;div class=&quot;palm-row-wrapper&quot;&gt;
 				&lt;div id=&quot;activity-spinner-favorites&quot; x-mojo-element=&quot;Spinner&quot;&gt;&lt;/div&gt;</diff>
      <filename>app/views/favorites/favorites-scene.html</filename>
    </modified>
    <modified>
      <diff>@@ -8,7 +8,7 @@
 		&lt;/div&gt;		
 	&lt;/div&gt; --&gt;
 	
-	&lt;div id=&quot;activity-spinner-my-timeline-container&quot;&gt;
+	&lt;div id=&quot;activity-spinner-my-timeline-container&quot; class='spaz-activity-spinner-container'&gt;
 		&lt;div class=&quot;palm-row first&quot;&gt;
 			&lt;div class=&quot;palm-row-wrapper&quot;&gt;
 				&lt;div id=&quot;activity-spinner-my-timeline&quot; x-mojo-element=&quot;Spinner&quot;&gt;&lt;/div&gt;</diff>
      <filename>app/views/my-timeline/my-timeline-scene.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,9 +1,7 @@
 
-&lt;div id=&quot;start-scene&quot; class=&quot;palm-dark&quot; style=&quot;display:none&quot;&gt;
-	
-	&lt;div id=&quot;start-section&quot; style=&quot;text-align:center&quot;&gt;
-		&lt;div&gt;&lt;img src=&quot;images/spaz-icon-alpha_256.png&quot; width=&quot;256&quot; height=&quot;245&quot; alt=&quot;Spaz Icon Alpha 256&quot;&gt;&lt;/div&gt;
+&lt;div id=&quot;start-scene&quot; class=&quot;palm-dark&quot;&gt;
 
+	&lt;div id=&quot;start-section&quot; style=&quot;text-align:center&quot;&gt;
 		&lt;div class=&quot;palm-group palm-group-spaz&quot;&gt;
 			&lt;div class=&quot;palm-group-title&quot; x-mojo-loc=''&gt;Welcome to Spaz &lt;spaz id=&quot;app-version&quot;&gt;&lt;/spaz&gt;&lt;/div&gt;
 			&lt;div class=&quot;palm-list&quot;&gt;</diff>
      <filename>app/views/start/start-scene.html</filename>
    </modified>
    <modified>
      <diff>@@ -4,6 +4,8 @@
 
 sc.app.tpl = new SpazTemplate();
 
+console.log(sc.app.tpl);
+
 sc.app.tpl.addTemplateMethod('message-detail', function(d) {
 	var html = '', thumbHTML = '';
 </diff>
      <filename>app/views/templates.js</filename>
    </modified>
    <modified>
      <diff></diff>
      <filename>images/dreadnaught/page-bg-darkgreen.png</filename>
    </modified>
    <modified>
      <diff>@@ -19,6 +19,10 @@
 	
 	&lt;!-- SpazCore --&gt;
 	&lt;script src=&quot;spazcore/spazcore-webos.js&quot; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
+	&lt;script type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;
+		sc.setDumpLevel(1);
+	&lt;/script&gt;
+	
 	
 	&lt;!-- Template methods for SpazTemplates --&gt;
 	&lt;script src=&quot;app/views/templates.js&quot; type=&quot;text/javascript&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;</diff>
      <filename>index.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-/*********** Built 2009-09-23 17:25:43 EDT ***********/
+/*********** Built 2009-11-04 17:06:27 EST ***********/
 /*jslint 
 browser: true,
 nomen: false,
@@ -323,1985 +323,1985 @@ Date.CultureInfo = {
  * end                 end
  * long                long
  * short               short
- *//**
- * @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 () {
-    var $D = Date, 
-        $P = $D.prototype, 
-        $C = $D.CultureInfo,
-        p = function (s, l) {
-            if (!l) {
-                l = 2;
-            }
-            return (&quot;000&quot; + 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 + &quot; - &quot; + date2); 
-        } else if (date1 instanceof Date &amp;&amp; date2 instanceof Date) {
-            return (date1 &lt; date2) ? -1 : (date1 &gt; date2) ? 1 : 0;
-        } else { 
-            throw new TypeError(date1 + &quot; - &quot; + 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. &quot;Monday, &quot;Mon&quot;, &quot;tuesday&quot;, &quot;tue&quot;, &quot;We&quot;, &quot;we&quot;).
-     * @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 &lt; 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. &quot;February, &quot;Feb&quot;, &quot;october&quot;, &quot;oct&quot;).
-     * @return {Number}  The day number
-     */
-    $D.getMonthNumberFromName = function (name) {
-        var n = $C.monthNames, m = $C.abbreviatedMonthNames, s = name.toLowerCase();
-        for (var i = 0; i &lt; 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 &amp;&amp; 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 &lt; 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 &lt; 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() &gt;= start.getTime() &amp;&amp; this.getTime() &lt;= 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() (&quot;now&quot;) is used.
-     * @return {Boolean} true if this date instance is greater than the date to compare to (or &quot;now&quot;), 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() (&quot;now&quot;) is used.
-     * @return {Boolean} true if this date instance is less than the date to compare to (or &quot;now&quot;).
-     */
-    $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 (&quot;now&quot;) 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
-    &lt;pre&gt;&lt;code&gt;
-    Date.today().add( { days: 1, months: 1 } )
-     
-    new Date().add( { years: -1 } )
-    &lt;/code&gt;&lt;/pre&gt; 
-     * @param {Object}   Configuration object containing attributes (months, days, etc.)
-     * @return {Date}    this
-     */
-    $P.add = function (config) {
-        if (typeof config == &quot;number&quot;) {
-            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&#248;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 &lt;= 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 &lt; 0) {
-            w = 53 - ((g - s) / 5 | 0);
-        } else if (n &gt; 364 + s) {
-            w = 1;
-        } else {
-            w = (n / 7 | 0) + 1;
-        }
-        
-        $y = $m = $d = null;
-        
-        return w;
-    };
-    
-    /**
-     * Get the ISO 8601 week number. Week one (&quot;01&quot;) 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}  &quot;01&quot; to &quot;53&quot;
-     */
-    $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 == &quot;undefined&quot;) {
-            return false;
-        } else if (typeof n != &quot;number&quot;) {
-            throw new TypeError(n + &quot; is not a Number.&quot;); 
-        } else if (n &lt; min || n &gt; max) {
-            throw new RangeError(n + &quot; is not a valid value for &quot; + name + &quot;.&quot;); 
-        }
-        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, &quot;millisecond&quot;);
-    };
-
-    /**
-     * 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, &quot;second&quot;);
-    };
-
-    /**
-     * 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, &quot;minute&quot;);
-    };
-
-    /**
-     * 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, &quot;hour&quot;);
-    };
-
-    /**
-     * 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), &quot;day&quot;);
-    };
-
-    /**
-     * 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, &quot;month&quot;);
-    };
-
-    /**
-     * 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, &quot;year&quot;);
-    };
-
-    /**
-     * Set the value of year, month, day, hour, minute, second, millisecond of date instance using given configuration object.
-     * Example
-    &lt;pre&gt;&lt;code&gt;
-    Date.today().set( { day: 20, month: 1 } )
-
-    new Date().set( { millisecond: 0 } )
-    &lt;/code&gt;&lt;/pre&gt;
-     * 
-     * @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 &amp;&amp; validate(config.week, 0, 53, &quot;week&quot;)) {
-            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 &gt; 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. &quot;EST&quot;)
-     */
-    $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. &quot;-0500&quot;)
-     */
-    $P.getUTCOffset = function () {
-        var n = this.getTimezoneOffset() * -10 / 6, r;
-        if (n &lt; 0) { 
-            r = (n - 10000).toString(); 
-            return r.charAt(0) + r.substr(2); 
-        } else { 
-            r = (n + 10000).toString();  
-            return &quot;+&quot; + 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 &lt; 10 ? '0' + n : n;
-            }
-
-            return '&quot;' + this.getUTCFullYear()   + '-' +
-                f(this.getUTCMonth() + 1) + '-' +
-                f(this.getUTCDate())      + 'T' +
-                f(this.getUTCHours())     + ':' +
-                f(this.getUTCMinutes())   + ':' +
-                f(this.getUTCSeconds())   + 'Z&quot;';
-        };
-    }
-    
-    // private
-    $P._toString = $P.toString;
-
-    /**
-     * Converts the value of the current Date object to its equivalent string representation.
-     * Format Specifiers
-    &lt;pre&gt;
-    CUSTOM DATE AND TIME FORMAT STRINGS
-    Format  Description                                                                  Example
-    ------  ---------------------------------------------------------------------------  -----------------------
-     s      The seconds of the minute between 0-59.                                      &quot;0&quot; to &quot;59&quot;
-     ss     The seconds of the minute with leading zero if required.                     &quot;00&quot; to &quot;59&quot;
-     
-     m      The minute of the hour between 0-59.                                         &quot;0&quot;  or &quot;59&quot;
-     mm     The minute of the hour with leading zero if required.                        &quot;00&quot; or &quot;59&quot;
-     
-     h      The hour of the day between 1-12.                                            &quot;1&quot;  to &quot;12&quot;
-     hh     The hour of the day with leading zero if required.                           &quot;01&quot; to &quot;12&quot;
-     
-     H      The hour of the day between 0-23.                                            &quot;0&quot;  to &quot;23&quot;
-     HH     The hour of the day with leading zero if required.                           &quot;00&quot; to &quot;23&quot;
-     
-     d      The day of the month between 1 and 31.                                       &quot;1&quot;  to &quot;31&quot;
-     dd     The day of the month with leading zero if required.                          &quot;01&quot; to &quot;31&quot;
-     ddd    Abbreviated day name. $C.abbreviatedDayNames.                                &quot;Mon&quot; to &quot;Sun&quot; 
-     dddd   The full day name. $C.dayNames.                                              &quot;Monday&quot; to &quot;Sunday&quot;
-     
-     M      The month of the year between 1-12.                                          &quot;1&quot; to &quot;12&quot;
-     MM     The month of the year with leading zero if required.                         &quot;01&quot; to &quot;12&quot;
-     MMM    Abbreviated month name. $C.abbreviatedMonthNames.                            &quot;Jan&quot; to &quot;Dec&quot;
-     MMMM   The full month name. $C.monthNames.                                          &quot;January&quot; to &quot;December&quot;
-
-     yy     The year as a two-digit number.                                              &quot;99&quot; or &quot;08&quot;
-     yyyy   The full four digit year.                                                    &quot;1999&quot; or &quot;2008&quot;
-     
-     t      Displays the first character of the A.M./P.M. designator.                    &quot;A&quot; or &quot;P&quot;
-            $C.amDesignator or $C.pmDesignator
-     tt     Displays the A.M./P.M. designator.                                           &quot;AM&quot; or &quot;PM&quot;
-            $C.amDesignator or $C.pmDesignator
-     
-     S      The ordinal suffix (&quot;st, &quot;nd&quot;, &quot;rd&quot; or &quot;th&quot;) of the current day.            &quot;st, &quot;nd&quot;, &quot;rd&quot; or &quot;th&quot;
-
-|| *Format* || *Description* || *Example* ||
-|| d      || The CultureInfo shortDate Format Pattern                                     || &quot;M/d/yyyy&quot; ||
-|| D      || The CultureInfo longDate Format Pattern                                      || &quot;dddd, MMMM dd, yyyy&quot; ||
-|| F      || The CultureInfo fullDateTime Format Pattern                                  || &quot;dddd, MMMM dd, yyyy h:mm:ss tt&quot; ||
-|| m      || The CultureInfo monthDay Format Pattern                                      || &quot;MMMM dd&quot; ||
-|| r      || The CultureInfo rfc1123 Format Pattern                                       || &quot;ddd, dd MMM yyyy HH:mm:ss GMT&quot; ||
-|| s      || The CultureInfo sortableDateTime Format Pattern                              || &quot;yyyy-MM-ddTHH:mm:ss&quot; ||
-|| t      || The CultureInfo shortTime Format Pattern                                     || &quot;h:mm tt&quot; ||
-|| T      || The CultureInfo longTime Format Pattern                                      || &quot;h:mm:ss tt&quot; ||
-|| u      || The CultureInfo universalSortableDateTime Format Pattern                     || &quot;yyyy-MM-dd HH:mm:ssZ&quot; ||
-|| y      || The CultureInfo yearMonth Format Pattern                                     || &quot;MMMM, yyyy&quot; ||
-     
-
-    STANDARD DATE AND TIME FORMAT STRINGS
-    Format  Description                                                                  Example (&quot;en-US&quot;)
-    ------  ---------------------------------------------------------------------------  -----------------------
-     d      The CultureInfo shortDate Format Pattern                                     &quot;M/d/yyyy&quot;
-     D      The CultureInfo longDate Format Pattern                                      &quot;dddd, MMMM dd, yyyy&quot;
-     F      The CultureInfo fullDateTime Format Pattern                                  &quot;dddd, MMMM dd, yyyy h:mm:ss tt&quot;
-     m      The CultureInfo monthDay Format Pattern                                      &quot;MMMM dd&quot;
-     r      The CultureInfo rfc1123 Format Pattern                                       &quot;ddd, dd MMM yyyy HH:mm:ss GMT&quot;
-     s      The CultureInfo sortableDateTime Format Pattern                              &quot;yyyy-MM-ddTHH:mm:ss&quot;
-     t      The CultureInfo shortTime Format Pattern                                     &quot;h:mm tt&quot;
-     T      The CultureInfo longTime Format Pattern                                      &quot;h:mm:ss tt&quot;
-     u      The CultureInfo universalSortableDateTime Format Pattern                     &quot;yyyy-MM-dd HH:mm:ssZ&quot;
-     y      The CultureInfo yearMonth Format Pattern                                     &quot;MMMM, yyyy&quot;
-    &lt;/pre&gt;
-     * @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 &amp;&amp; format.length == 1) {
-            var c = $C.formatPatterns;
-            x.t = x.toString;
-            switch (format) {
-            case &quot;d&quot;: 
-                return x.t(c.shortDate);
-            case &quot;D&quot;:
-                return x.t(c.longDate);
-            case &quot;F&quot;:
-                return x.t(c.fullDateTime);
-            case &quot;m&quot;:
-                return x.t(c.monthDay);
-            case &quot;r&quot;:
-                return x.t(c.rfc1123);
-            case &quot;s&quot;:
-                return x.t(c.sortableDateTime);
-            case &quot;t&quot;:
-                return x.t(c.shortTime);
-            case &quot;T&quot;:
-                return x.t(c.longTime);
-            case &quot;u&quot;:
-                return x.t(c.universalSortableDateTime);
-            case &quot;y&quot;:
-                return x.t(c.yearMonth);
-            }    
-        }
-        
-        var ord = function (n) {
-                switch (n * 1) {
-                case 1: 
-                case 21: 
-                case 31: 
-                    return &quot;st&quot;;
-                case 2: 
-                case 22: 
-                    return &quot;nd&quot;;
-                case 3: 
-                case 23: 
-                    return &quot;rd&quot;;
-                default: 
-                    return &quot;th&quot;;
-                }
-            };
-        
-        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) === &quot;\\&quot;) {
-                return m.replace(&quot;\\&quot;, &quot;&quot;);
-            }
-            x.h = x.getHours;
-            switch (m) {
-            case &quot;hh&quot;:
-                return p(x.h() &lt; 13 ? (x.h() === 0 ? 12 : x.h()) : (x.h() - 12));
-            case &quot;h&quot;:
-                return x.h() &lt; 13 ? (x.h() === 0 ? 12 : x.h()) : (x.h() - 12);
-            case &quot;HH&quot;:
-                return p(x.h());
-            case &quot;H&quot;:
-                return x.h();
-            case &quot;mm&quot;:
-                return p(x.getMinutes());
-            case &quot;m&quot;:
-                return x.getMinutes();
-            case &quot;ss&quot;:
-                return p(x.getSeconds());
-            case &quot;s&quot;:
-                return x.getSeconds();
-            case &quot;yyyy&quot;:
-                return p(x.getFullYear(), 4);
-            case &quot;yy&quot;:
-                return p(x.getFullYear());
-            case &quot;dddd&quot;:
-                return $C.dayNames[x.getDay()];
-            case &quot;ddd&quot;:
-                return $C.abbreviatedDayNames[x.getDay()];
-            case &quot;dd&quot;:
-                return p(x.getDate());
-            case &quot;d&quot;:
-                return x.getDate();
-            case &quot;MMMM&quot;:
-                return $C.monthNames[x.getMonth()];
-            case &quot;MMM&quot;:
-                return $C.abbreviatedMonthNames[x.getMonth()];
-            case &quot;MM&quot;:
-                return p((x.getMonth() + 1));
-            case &quot;M&quot;:
-                return x.getMonth() + 1;
-            case &quot;t&quot;:
-                return x.h() &lt; 12 ? $C.amDesignator.substring(0, 1) : $C.pmDesignator.substring(0, 1);
-            case &quot;tt&quot;:
-                return x.h() &lt; 12 ? $C.amDesignator : $C.pmDesignator;
-            case &quot;S&quot;:
-                return ord(x.getDate());
-            default: 
-                return m;
-            }
-        }
-        ) : this._toString();
-    };
-}());    /**
- * @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) {
-            this.message = &quot;Parse error at '&quot; + s.substring(0, 10) + &quot; ...'&quot;; 
-        }
-    };
-    
-    var $P = Date.Parsing; 
-    var _ = $P.Operators = {
-        //
-        // Tokenizers
-        //
-        rtoken: function (r) { // regex token
-            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) { // whitespace-eating token
-            return function (s) {
-                return _.rtoken(new RegExp(&quot;^\s*&quot; + s + &quot;\s*&quot;))(s);
-                // Removed .strip()
-                // return _.rtoken(new RegExp(&quot;^\s*&quot; + s + &quot;\s*&quot;))(s).strip();
-            };
-        },
-        stoken: function (s) { // string token
-            return _.rtoken(new RegExp(&quot;^&quot; + s)); 
-        },
-
-        //
-        // Atomic Operators
-        // 
-
-        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 ];
-            };
-        },
-
-        // generator operators -- see below
-        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 &lt; 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; 
-                }
-            };
-        },
-    	  
-        // vector operators -- see below
-        any: function () {
-            var px = arguments;
-            return function (s) { 
-                var r = null;
-                for (var i = 0; i &lt; 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 &lt; 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)); 
-        },
-
-        // delimited operators
-        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 &lt; 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) ];
-            };
-        },
-    		
-	    //
-	    // Composite Operators
-	    //
-    		
-        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) {
-                // r is the current match, best the current 'best' match
-                // which means it parsed the most amount of input
-                var r = null, p = null, q = null, rx = null, best = [[], s], last = false;
-
-                // go through the rules in the given set
-                for (var i = 0; i &lt; px.length ; i++) {
-
-                    // last is a flag indicating whether this must be the last element
-                    // if there is only 1 element, then it MUST be the last one
-                    q = null; 
-                    p = null; 
-                    r = null; 
-                    last = (px.length == 1); 
-
-                    // first, we try simply to match the current pattern
-                    // if not, try the next pattern
-                    try { 
-                        r = px[i].call(this, s);
-                    } catch (e) { 
-                        continue; 
-                    }
-
-                    // since we are matching against a set of elements, the first
-                    // thing to do is to add r[0] to matched elements
-                    rx = [[r[0]], r[1]];
-
-                    // if we matched and there is still input to parse and 
-                    // we don't already know this is the last element,
-                    // we're going to next check for the delimiter ...
-                    // if there's none, or if there's no input left to parse
-                    // than this must be the last element after all ...
-                    if (r[1].length &gt; 0 &amp;&amp; ! last) {
-                        try { 
-                            q = d.call(this, r[1]); 
-                        } catch (ex) { 
-                            last = true; 
-                        }
-                    } else { 
-                        last = true; 
-                    }
-
-				    // if we parsed the delimiter and now there's no more input,
-				    // that means we shouldn't have parsed the delimiter at all
-				    // so don't update r and mark this as the last element ...
-                    if (!last &amp;&amp; q[1].length === 0) { 
-                        last = true; 
-                    }
-
-
-				    // so, if this isn't the last element, we're going to see if
-				    // we can get any more matches from the remaining (unmatched)
-				    // elements ...
-                    if (!last) {
-
-                        // build a list of the remaining rules we can match against,
-                        // i.e., all but the one we just matched against
-                        var qx = []; 
-                        for (var j = 0; j &lt; px.length ; j++) { 
-                            if (i != j) { 
-                                qx.push(px[j]); 
-                            }
-                        }
-
-                        // now invoke recursively set with the remaining input
-                        // note that we don't include the closing delimiter ...
-                        // we'll check for that ourselves at the end
-                        p = _.set(qx, d).call(this, q[1]);
-
-                        // if we got a non-empty set as a result ...
-                        // (otw rx already contains everything we want to match)
-                        if (p[0].length &gt; 0) {
-                            // update current result, which is stored in rx ...
-                            // basically, pick up the remaining text from p[1]
-                            // and concat the result from p[0] so that we don't
-                            // get endless nesting ...
-                            rx[0] = rx[0].concat(p[0]); 
-                            rx[1] = p[1]; 
-                        }
-                    }
-
-				    // at this point, rx either contains the last matched element
-				    // or the entire matched set that starts with this element.
-
-				    // now we just check to see if this variation is better than
-				    // our best so far, in terms of how much of the input is parsed
-                    if (rx[1].length &lt; best[1].length) { 
-                        best = rx; 
-                    }
-
-				    // if we've parsed all the input, then we're finished
-                    if (best[1].length === 0) { 
-                        break; 
-                    }
-                }
-
-			    // so now we've either gone through all the patterns trying them
-			    // as the initial match; or we found one that parsed the entire
-			    // input string ...
-
-			    // if best has no matches, just return empty set ...
-                if (best[0].length === 0) { 
-                    return best; 
-                }
-
-			    // if a closing delimiter is provided, then we have to check it also
-                if (c) {
-                    // we try this even if there is no remaining input because the pattern
-                    // may well be optional or match empty input ...
-                    try { 
-                        q = c.call(this, best[1]); 
-                    } catch (ey) { 
-                        throw new $P.Exception(best[1]); 
-                    }
-
-                    // it parsed ... be sure to update the best match remaining input
-                    best[1] = q[1];
-                }
-
-			    // if we're here, either there was no closing delimiter or we parsed it
-			    // so now we have the best match; just return it!
-                return best;
-            };
-        },
-        forward: function (gr, fname) {
-            return function (s) { 
-                return gr[fname].call(this, s); 
-            };
-        },
-
-        //
-        // Translation Operators
-        //
-        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 &lt; min) { 
-                    throw new $P.Exception(s); 
-                }
-                return rx;
-            };
-        }
-    };
-	
-
-	// Generator Operators And Vector Operators
-
-	// Generators are operators that have a signature of F(R) =&gt; R,
-	// taking a given rule and returning another rule, such as 
-	// ignore, which parses a given rule and throws away the result.
-
-	// Vector operators are those that have a signature of F(R1,R2,...) =&gt; R,
-	// take a list of rules and returning a new rule, such as each.
-
-	// Generator operators are converted (via the following _generator
-	// function) into functions that can also take a list or array of rules
-	// and return an array of new rules as though the function had been
-	// called on each rule in turn (which is what actually happens).
-
-	// This allows generators to be used with vector operators more easily.
-	// Example:
-	// each(ignore(foo, bar)) instead of each(ignore(foo), ignore(bar))
-
-	// This also turns generators into vector operators, which allows
-	// constructs like:
-	// not(cache(foo, bar))
-	
-    var _generator = function (op) {
-        return function () {
-            var args = null, rx = [];
-            if (arguments.length &gt; 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 &lt; 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 = &quot;optional not ignore cache&quot;.split(/\s/);
-    
-    for (var i = 0 ; i &lt; 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 = &quot;each any all&quot;.split(/\s/);
-    
-    for (var j = 0 ; j &lt; 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 &lt; 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, &quot;&quot;);
-                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) ? &quot;jan feb mar apr may jun jul aug sep oct nov dec&quot;.indexOf(s)/4 : Number(s) - 1;
-            };
-        },
-        year: function (s) {
-            return function () {
-                var n = Number(s);
-                this.year = ((s.length &gt; 2) ? n : 
-                    (n + (((n + 2000) &lt; $C.twoDigitYearMax) ? 2000 : 1900))); 
-            };
-        },
-        rday: function (s) { 
-            return function () {
-                switch (s) {
-                case &quot;yesterday&quot;: 
-                    this.days = -1;
-                    break;
-                case &quot;tomorrow&quot;:  
-                    this.days = 1;
-                    break;
-                case &quot;today&quot;: 
-                    this.days = 0;
-                    break;
-                case &quot;now&quot;: 
-                    this.days = 0; 
-                    this.now = true; 
-                    break;
-                }
-            };
-        },
-        finishExact: function (x) {  
-            x = (x instanceof Array) ? x : [ x ]; 
-
-            for (var i = 0 ; i &lt; x.length ; i++) { 
-                if (x[i]) { 
-                    x[i].call(this); 
-                }
-            }
-            
-            var now = new Date();
-            
-            if ((this.hour || this.minute) &amp;&amp; (!this.month &amp;&amp; !this.year &amp;&amp; !this.day)) {
-                this.day = now.getDate();
-            }
-
-            if (!this.year) {
-                this.year = now.getFullYear();
-            }
-            
-            if (!this.month &amp;&amp; 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 &amp;&amp; this.hour) {
-                if (this.meridian == &quot;p&quot; &amp;&amp; this.hour &lt; 12) {
-                    this.hour = this.hour + 12;
-                } else if (this.meridian == &quot;a&quot; &amp;&amp; this.hour == 12) {
-                    this.hour = 0;
-                }
-            }
-            
-            if (this.day &gt; $D.getDaysInMonth(this.year, this.month)) {
-                throw new RangeError(this.day + &quot; is not a valid value for days.&quot;);
-            }
-
-            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 &lt; x.length ; i++) { 
-                if (typeof x[i] == &quot;function&quot;) {
-                    x[i].call(this); 
-                }
-            }
-            
-            var today = $D.today();
-            
-            if (this.now &amp;&amp; !this.unit &amp;&amp; !this.operator) { 
-                return new Date(); 
-            } else if (this.now) {
-                today = new Date();
-            }
-            
-            var expression = !!(this.days &amp;&amp; this.days !== null || this.orient || this.operator);
-            
-            var gap, mod, orient;
-            orient = ((this.orient == &quot;past&quot; || this.operator == &quot;subtract&quot;) ? -1 : 1);
-            
-            if(!this.now &amp;&amp; &quot;hour minute second&quot;.indexOf(this.unit) != -1) {
-                today.setTimeToNow();
-            }
-
-            if (this.month || this.month === 0) {
-                if (&quot;year day hour minute second&quot;.indexOf(this.unit) != -1) {
-                    this.value = this.month + 1;
-                    this.month = null;
-                    expression = true;
-                }
-            }
-            
-            if (!expression &amp;&amp; this.weekday &amp;&amp; !this.day &amp;&amp; !this.days) {
-                var temp = Date[this.weekday]();
-                this.day = temp.getDate();
-                if (!this.month) {
-                    this.month = temp.getMonth();
-                }
-                this.year = temp.getFullYear();
-            }
-            
-            if (expression &amp;&amp; this.weekday &amp;&amp; this.unit != &quot;month&quot;) {
-                this.unit = &quot;day&quot;;
-                gap = ($D.getDayNumberFromName(this.weekday) - today.getDay());
-                mod = 7;
-                this.days = gap ? ((gap + (orient * mod)) % mod) : (orient * mod);
-            }
-            
-            if (this.month &amp;&amp; this.unit == &quot;day&quot; &amp;&amp; this.operator) {
-                this.value = (this.month + 1);
-                this.month = null;
-            }
-       
-            if (this.value != null &amp;&amp; this.month != null &amp;&amp; this.year != null) {
-                this.day = this.value * 1;
-            }
-     
-            if (this.month &amp;&amp; !this.day &amp;&amp; this.value) {
-                today.set({ day: this.value * 1 });
-                if (!expression) {
-                    this.day = this.value * 1;
-                }
-            }
-
-            if (!this.month &amp;&amp; this.value &amp;&amp; this.unit == &quot;month&quot; &amp;&amp; !this.now) {
-                this.month = this.value;
-                expression = true;
-            }
-
-            if (expression &amp;&amp; (this.month || this.month === 0) &amp;&amp; this.unit != &quot;year&quot;) {
-                this.unit = &quot;month&quot;;
-                gap = (this.month - today.getMonth());
-                mod = 12;
-                this.months = gap ? ((gap + (orient * mod)) % mod) : (orient * mod);
-                this.month = null;
-            }
-
-            if (!this.unit) { 
-                this.unit = &quot;day&quot;; 
-            }
-            
-            if (!this.value &amp;&amp; this.operator &amp;&amp; this.operator !== null &amp;&amp; this[this.unit + &quot;s&quot;] &amp;&amp; this[this.unit + &quot;s&quot;] !== null) {
-                this[this.unit + &quot;s&quot;] = this[this.unit + &quot;s&quot;] + ((this.operator == &quot;add&quot;) ? 1 : -1) + (this.value||0) * orient;
-            } else if (this[this.unit + &quot;s&quot;] == null || this.operator != null) {
-                if (!this.value) {
-                    this.value = 1;
-                }
-                this[this.unit + &quot;s&quot;] = this.value * orient;
-            }
-
-            if (this.meridian &amp;&amp; this.hour) {
-                if (this.meridian == &quot;p&quot; &amp;&amp; this.hour &lt; 12) {
-                    this.hour = this.hour + 12;
-                } else if (this.meridian == &quot;a&quot; &amp;&amp; this.hour == 12) {
-                    this.hour = 0;
-                }
-            }
-            
-            if (this.weekday &amp;&amp; !this.day &amp;&amp; !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) &amp;&amp; !this.day) { 
-                this.day = 1; 
-            }
-            
-            if (!this.orient &amp;&amp; !this.operator &amp;&amp; this.unit == &quot;week&quot; &amp;&amp; this.value &amp;&amp; !this.day &amp;&amp; !this.month) {
-                return Date.today().setWeek(this.value);
-            }
-
-            if (expression &amp;&amp; this.timezone &amp;&amp; this.day &amp;&amp; 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(&quot;:&quot;);
-    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 &lt; 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]);
-    };
-
-    // hour, minute, second, meridian, timezone
-    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));
-  
-    // _.min(1, _.set([ g.H, g.m, g.s ], g._t));
-    g.t = _.cache(_.process(g.ctoken2(&quot;shortMeridian&quot;), t.meridian));
-    g.tt = _.cache(_.process(g.ctoken2(&quot;longMeridian&quot;), 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(&quot;timezone&quot;), t.timezone));
-    g.timeSuffix = _.each(_.ignore(g.whiteSpace), _.set([ g.tt, g.zzz ]));
-    g.time = _.each(_.optional(_.ignore(_.stoken(&quot;T&quot;))), g.hms, g.timeSuffix);
-    	  
-    // days, months, years
-    g.d = _.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/), 
-        _.optional(g.ctoken2(&quot;ordinalSuffix&quot;))), t.day));
-    g.dd = _.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/), 
-        _.optional(g.ctoken2(&quot;ordinalSuffix&quot;))), t.day));
-    g.ddd = g.dddd = _.cache(_.process(g.ctoken(&quot;sun mon tue wed thu fri sat&quot;), 
-        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(&quot;jan feb mar apr may jun jul aug sep oct nov dec&quot;), 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));
-	
-	// rolling these up into general purpose rules
-    _fn = function () { 
-        return _.each(_.any.apply(null, arguments), _.not(g.ctoken2(&quot;timeContext&quot;)));
-    };
-    
-    g.day = _fn(g.d, g.dd); 
-    g.month = _fn(g.M, g.MMM); 
-    g.year = _fn(g.yyyy, g.yy);
-
-    // relative date / time expressions
-    g.orientation = _.process(g.ctoken(&quot;past future&quot;), 
-        function (s) { 
-            return function () { 
-                this.orient = s; 
-            }; 
-        }
-    );
-    g.operator = _.process(g.ctoken(&quot;add subtract&quot;), 
-        function (s) { 
-            return function () { 
-                this.operator = s; 
-            }; 
-        }
-    );  
-    g.rday = _.process(g.ctoken(&quot;yesterday tomorrow today now&quot;), t.rday);
-    g.unit = _.process(g.ctoken(&quot;second minute hour day week month year&quot;), 
-        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, &quot;&quot;); 
-            }; 
-        }
-    );
-    g.expression = _.set([ g.rday, g.operator, g.value, g.unit, g.orientation, g.ddd, g.MMM ]);
-
-    // pre-loaded rules for different date part order preferences
-    _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));
-    }; 
-
-    // parsing date format specifiers - ex: &quot;h:m:s tt&quot; 
-    // this little guy will generate a custom parser based
-    // on the format string, ex: g.format(&quot;h:m:s tt&quot;)
-    g.format = _.process(_.many(
-        _.any(
-        // translate format specifiers into grammar rules
-        _.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); 
-        }
-    }
-    ),
-    // translate separator tokens into token rules
-    _.process(
-    _.rtoken(/^[^dMyhHmstz]+/), // all legal separators 
-        function (s) { 
-            return _.ignore(_.stoken(s)); 
-        } 
-    )
-    )), 
-        // construct the parser ...
-        function (rules) { 
-            return _.process(_.each.apply(null, rules), t.finishExact); 
-        }
-    );
-    
-    var _F = {
-		//&quot;M/d/yyyy&quot;: function (s) { 
-		//	var m = s.match(/^([0-2]\d|3[0-1]|\d)\/(1[0-2]|0\d|\d)\/(\d\d\d\d)/);
-		//	if (m!=null) { 
-		//		var r =  [ t.month.call(this,m[1]), t.day.call(this,m[2]), t.year.call(this,m[3]) ];
-		//		r = t.finishExact.call(this,r);
-		//		return [ r, &quot;&quot; ];
-		//	} else {
-		//		throw new Date.Parsing.Exception(s);
-		//	}
-		//}
-		//&quot;M/d/yyyy&quot;: function (s) { return [ new Date(Date._parse(s)), &quot;&quot;]; }
-	}; 
-    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 &lt; fx.length ; i++) {
-                rx.push(_get(fx[i])); 
-            }
-            return _.any.apply(null, rx);
-        } else { 
-            return _get(fx); 
-        }
-    };
-
-	// check for these formats first
-    g._formats = g.formats([
-        &quot;\&quot;yyyy-MM-ddTHH:mm:ssZ\&quot;&quot;,
-        &quot;yyyy-MM-ddTHH:mm:ssZ&quot;,
-        &quot;yyyy-MM-ddTHH:mm:ssz&quot;,
-        &quot;yyyy-MM-ddTHH:mm:ss&quot;,
-        &quot;yyyy-MM-ddTHH:mmZ&quot;,
-        &quot;yyyy-MM-ddTHH:mmz&quot;,
-        &quot;yyyy-MM-ddTHH:mm&quot;,
-        &quot;ddd, MMM dd, yyyy H:mm:ss tt&quot;,
-        &quot;ddd MMM d yyyy HH:mm:ss zzz&quot;,
-        &quot;MMddyyyy&quot;,
-        &quot;ddMMyyyy&quot;,
-        &quot;Mddyyyy&quot;,
-        &quot;ddMyyyy&quot;,
-        &quot;Mdyyyy&quot;,
-        &quot;dMyyyy&quot;,
-        &quot;yyyy&quot;,
-        &quot;Mdyy&quot;,
-        &quot;dMyy&quot;,
-        &quot;d&quot;
-    ]);
-
-	// starting rule for general purpose grammar
-    g._start = _.process(_.set([ g.date, g.time, g.expression ], 
-        g.generalDelimiter, g.whiteSpace), t.finish);
-	
-	// real starting rule: tries selected formats first, 
-	// then general purpose rule
-    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;
-
-    /**
-     * Converts the specified string value into its JavaScript Date equivalent using CultureInfo specific format information.
-     * 
-     * Example
-    &lt;pre&gt;&lt;code&gt;
-    ///////////
-    // Dates //
-    ///////////
-
-    // 15-Oct-2004
-    var d1 = Date.parse(&quot;10/15/2004&quot;);
-
-    // 15-Oct-2004
-    var d1 = Date.parse(&quot;15-Oct-2004&quot;);
-
-    // 15-Oct-2004
-    var d1 = Date.parse(&quot;2004.10.15&quot;);
-
-    //Fri Oct 15, 2004
-    var d1 = Date.parse(&quot;Fri Oct 15, 2004&quot;);
-
-    ///////////
-    // Times //
-    ///////////
-
-    // Today at 10 PM.
-    var d1 = Date.parse(&quot;10 PM&quot;);
-
-    // Today at 10:30 PM.
-    var d1 = Date.parse(&quot;10:30 P.M.&quot;);
-
-    // Today at 6 AM.
-    var d1 = Date.parse(&quot;06am&quot;);
-
-    /////////////////////
-    // Dates and Times //
-    /////////////////////
-
-    // 8-July-2004 @ 10:30 PM
-    var d1 = Date.parse(&quot;July 8th, 2004, 10:30 PM&quot;);
-
-    // 1-July-2004 @ 10:30 PM
-    var d1 = Date.parse(&quot;2004-07-01T22:30:00&quot;);
-
-    ////////////////////
-    // Relative Dates //
-    ////////////////////
-
-    // Returns today's date. The string &quot;today&quot; is culture specific.
-    var d1 = Date.parse(&quot;today&quot;);
-
-    // Returns yesterday's date. The string &quot;yesterday&quot; is culture specific.
-    var d1 = Date.parse(&quot;yesterday&quot;);
-
-    // Returns the date of the next thursday.
-    var d1 = Date.parse(&quot;Next thursday&quot;);
-
-    // Returns the date of the most previous monday.
-    var d1 = Date.parse(&quot;last monday&quot;);
-
-    // Returns today's day + one year.
-    var d1 = Date.parse(&quot;next year&quot;);
-
-    ///////////////
-    // Date Math //
-    ///////////////
-
-    // Today + 2 days
-    var d1 = Date.parse(&quot;t+2&quot;);
-
-    // Today + 2 days
-    var d1 = Date.parse(&quot;today + 2 days&quot;);
-
-    // Today + 3 months
-    var d1 = Date.parse(&quot;t+3m&quot;);
-
-    // Today - 1 year
-    var d1 = Date.parse(&quot;today - 1 year&quot;);
-
-    // Today - 1 year
-    var d1 = Date.parse(&quot;t-1y&quot;); 
-
-
-    /////////////////////////////
-    // Partial Dates and Times //
-    /////////////////////////////
-
-    // July 15th of this year.
-    var d1 = Date.parse(&quot;July 15&quot;);
-
-    // 15th day of current day and year.
-    var d1 = Date.parse(&quot;15&quot;);
-
-    // July 1st of current year at 10pm.
-    var d1 = Date.parse(&quot;7/1 10pm&quot;);
-    &lt;/code&gt;&lt;/pre&gt;
-     *
-     * @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 = $D.Grammar.start.call({}, s.replace(/^\s*(\S*(\s+\S+)*)\s*$/, &quot;$1&quot;)); 
-        } 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);
-        };
-    };
-    
-    /**
-     * 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
-    &lt;pre&gt;&lt;code&gt;
-    // 15-Oct-2004
-    var d1 = Date.parseExact(&quot;10/15/2004&quot;, &quot;M/d/yyyy&quot;);
-
-    // 15-Oct-2004
-    var d1 = Date.parse(&quot;15-Oct-2004&quot;, &quot;M-ddd-yyyy&quot;);
-
-    // 15-Oct-2004
-    var d1 = Date.parse(&quot;2004.10.15&quot;, &quot;yyyy.MM.dd&quot;);
-
-    // Multiple formats
-    var d1 = Date.parseExact(&quot;10/15/2004&quot;, [&quot;M/d/yyyy&quot;, &quot;MMMM d, yyyy&quot;]);
-    &lt;/code&gt;&lt;/pre&gt;
-     *
-     * @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); 
-    };	
+ *//**
+ * @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 () {
+    var $D = Date, 
+        $P = $D.prototype, 
+        $C = $D.CultureInfo,
+        p = function (s, l) {
+            if (!l) {
+                l = 2;
+            }
+            return (&quot;000&quot; + 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 + &quot; - &quot; + date2); 
+        } else if (date1 instanceof Date &amp;&amp; date2 instanceof Date) {
+            return (date1 &lt; date2) ? -1 : (date1 &gt; date2) ? 1 : 0;
+        } else { 
+            throw new TypeError(date1 + &quot; - &quot; + 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. &quot;Monday, &quot;Mon&quot;, &quot;tuesday&quot;, &quot;tue&quot;, &quot;We&quot;, &quot;we&quot;).
+     * @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 &lt; 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. &quot;February, &quot;Feb&quot;, &quot;october&quot;, &quot;oct&quot;).
+     * @return {Number}  The day number
+     */
+    $D.getMonthNumberFromName = function (name) {
+        var n = $C.monthNames, m = $C.abbreviatedMonthNames, s = name.toLowerCase();
+        for (var i = 0; i &lt; 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 &amp;&amp; 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 &lt; 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 &lt; 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() &gt;= start.getTime() &amp;&amp; this.getTime() &lt;= 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() (&quot;now&quot;) is used.
+     * @return {Boolean} true if this date instance is greater than the date to compare to (or &quot;now&quot;), 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() (&quot;now&quot;) is used.
+     * @return {Boolean} true if this date instance is less than the date to compare to (or &quot;now&quot;).
+     */
+    $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 (&quot;now&quot;) 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
+    &lt;pre&gt;&lt;code&gt;
+    Date.today().add( { days: 1, months: 1 } )
+     
+    new Date().add( { years: -1 } )
+    &lt;/code&gt;&lt;/pre&gt; 
+     * @param {Object}   Configuration object containing attributes (months, days, etc.)
+     * @return {Date}    this
+     */
+    $P.add = function (config) {
+        if (typeof config == &quot;number&quot;) {
+            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&#248;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 &lt;= 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 &lt; 0) {
+            w = 53 - ((g - s) / 5 | 0);
+        } else if (n &gt; 364 + s) {
+            w = 1;
+        } else {
+            w = (n / 7 | 0) + 1;
+        }
+        
+        $y = $m = $d = null;
+        
+        return w;
+    };
+    
+    /**
+     * Get the ISO 8601 week number. Week one (&quot;01&quot;) 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}  &quot;01&quot; to &quot;53&quot;
+     */
+    $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 == &quot;undefined&quot;) {
+            return false;
+        } else if (typeof n != &quot;number&quot;) {
+            throw new TypeError(n + &quot; is not a Number.&quot;); 
+        } else if (n &lt; min || n &gt; max) {
+            throw new RangeError(n + &quot; is not a valid value for &quot; + name + &quot;.&quot;); 
+        }
+        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, &quot;millisecond&quot;);
+    };
+
+    /**
+     * 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, &quot;second&quot;);
+    };
+
+    /**
+     * 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, &quot;minute&quot;);
+    };
+
+    /**
+     * 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, &quot;hour&quot;);
+    };
+
+    /**
+     * 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), &quot;day&quot;);
+    };
+
+    /**
+     * 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, &quot;month&quot;);
+    };
+
+    /**
+     * 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, &quot;year&quot;);
+    };
+
+    /**
+     * Set the value of year, month, day, hour, minute, second, millisecond of date instance using given configuration object.
+     * Example
+    &lt;pre&gt;&lt;code&gt;
+    Date.today().set( { day: 20, month: 1 } )
+
+    new Date().set( { millisecond: 0 } )
+    &lt;/code&gt;&lt;/pre&gt;
+     * 
+     * @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 &amp;&amp; validate(config.week, 0, 53, &quot;week&quot;)) {
+            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 &gt; 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. &quot;EST&quot;)
+     */
+    $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. &quot;-0500&quot;)
+     */
+    $P.getUTCOffset = function () {
+        var n = this.getTimezoneOffset() * -10 / 6, r;
+        if (n &lt; 0) { 
+            r = (n - 10000).toString(); 
+            return r.charAt(0) + r.substr(2); 
+        } else { 
+            r = (n + 10000).toString();  
+            return &quot;+&quot; + 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 &lt; 10 ? '0' + n : n;
+            }
+
+            return '&quot;' + this.getUTCFullYear()   + '-' +
+                f(this.getUTCMonth() + 1) + '-' +
+                f(this.getUTCDate())      + 'T' +
+                f(this.getUTCHours())     + ':' +
+                f(this.getUTCMinutes())   + ':' +
+                f(this.getUTCSeconds())   + 'Z&quot;';
+        };
+    }
+    
+    // private
+    $P._toString = $P.toString;
+
+    /**
+     * Converts the value of the current Date object to its equivalent string representation.
+     * Format Specifiers
+    &lt;pre&gt;
+    CUSTOM DATE AND TIME FORMAT STRINGS
+    Format  Description                                                                  Example
+    ------  ---------------------------------------------------------------------------  -----------------------
+     s      The seconds of the minute between 0-59.                                      &quot;0&quot; to &quot;59&quot;
+     ss     The seconds of the minute with leading zero if required.                     &quot;00&quot; to &quot;59&quot;
+     
+     m      The minute of the hour between 0-59.                                         &quot;0&quot;  or &quot;59&quot;
+     mm     The minute of the hour with leading zero if required.                        &quot;00&quot; or &quot;59&quot;
+     
+     h      The hour of the day between 1-12.                                            &quot;1&quot;  to &quot;12&quot;
+     hh     The hour of the day with leading zero if required.                           &quot;01&quot; to &quot;12&quot;
+     
+     H      The hour of the day between 0-23.                                            &quot;0&quot;  to &quot;23&quot;
+     HH     The hour of the day with leading zero if required.                           &quot;00&quot; to &quot;23&quot;
+     
+     d      The day of the month between 1 and 31.                                       &quot;1&quot;  to &quot;31&quot;
+     dd     The day of the month with leading zero if required.                          &quot;01&quot; to &quot;31&quot;
+     ddd    Abbreviated day name. $C.abbreviatedDayNames.                                &quot;Mon&quot; to &quot;Sun&quot; 
+     dddd   The full day name. $C.dayNames.                                              &quot;Monday&quot; to &quot;Sunday&quot;
+     
+     M      The month of the year between 1-12.                                          &quot;1&quot; to &quot;12&quot;
+     MM     The month of the year with leading zero if required.                         &quot;01&quot; to &quot;12&quot;
+     MMM    Abbreviated month name. $C.abbreviatedMonthNames.                            &quot;Jan&quot; to &quot;Dec&quot;
+     MMMM   The full month name. $C.monthNames.                                          &quot;January&quot; to &quot;December&quot;
+
+     yy     The year as a two-digit number.                                              &quot;99&quot; or &quot;08&quot;
+     yyyy   The full four digit year.                                                    &quot;1999&quot; or &quot;2008&quot;
+     
+     t      Displays the first character of the A.M./P.M. designator.                    &quot;A&quot; or &quot;P&quot;
+            $C.amDesignator or $C.pmDesignator
+     tt     Displays the A.M./P.M. designator.                                           &quot;AM&quot; or &quot;PM&quot;
+            $C.amDesignator or $C.pmDesignator
+     
+     S      The ordinal suffix (&quot;st, &quot;nd&quot;, &quot;rd&quot; or &quot;th&quot;) of the current day.            &quot;st, &quot;nd&quot;, &quot;rd&quot; or &quot;th&quot;
+
+|| *Format* || *Description* || *Example* ||
+|| d      || The CultureInfo shortDate Format Pattern                                     || &quot;M/d/yyyy&quot; ||
+|| D      || The CultureInfo longDate Format Pattern                                      || &quot;dddd, MMMM dd, yyyy&quot; ||
+|| F      || The CultureInfo fullDateTime Format Pattern                                  || &quot;dddd, MMMM dd, yyyy h:mm:ss tt&quot; ||
+|| m      || The CultureInfo monthDay Format Pattern                                      || &quot;MMMM dd&quot; ||
+|| r      || The CultureInfo rfc1123 Format Pattern                                       || &quot;ddd, dd MMM yyyy HH:mm:ss GMT&quot; ||
+|| s      || The CultureInfo sortableDateTime Format Pattern                              || &quot;yyyy-MM-ddTHH:mm:ss&quot; ||
+|| t      || The CultureInfo shortTime Format Pattern                                     || &quot;h:mm tt&quot; ||
+|| T      || The CultureInfo longTime Format Pattern                                      || &quot;h:mm:ss tt&quot; ||
+|| u      || The CultureInfo universalSortableDateTime Format Pattern                     || &quot;yyyy-MM-dd HH:mm:ssZ&quot; ||
+|| y      || The CultureInfo yearMonth Format Pattern                                     || &quot;MMMM, yyyy&quot; ||
+     
+
+    STANDARD DATE AND TIME FORMAT STRINGS
+    Format  Description                                                                  Example (&quot;en-US&quot;)
+    ------  ---------------------------------------------------------------------------  -----------------------
+     d      The CultureInfo shortDate Format Pattern                                     &quot;M/d/yyyy&quot;
+     D      The CultureInfo longDate Format Pattern                                      &quot;dddd, MMMM dd, yyyy&quot;
+     F      The CultureInfo fullDateTime Format Pattern                                  &quot;dddd, MMMM dd, yyyy h:mm:ss tt&quot;
+     m      The CultureInfo monthDay Format Pattern                                      &quot;MMMM dd&quot;
+     r      The CultureInfo rfc1123 Format Pattern                                       &quot;ddd, dd MMM yyyy HH:mm:ss GMT&quot;
+     s      The CultureInfo sortableDateTime Format Pattern                              &quot;yyyy-MM-ddTHH:mm:ss&quot;
+     t      The CultureInfo shortTime Format Pattern                                     &quot;h:mm tt&quot;
+     T      The CultureInfo longTime Format Pattern                                      &quot;h:mm:ss tt&quot;
+     u      The CultureInfo universalSortableDateTime Format Pattern                     &quot;yyyy-MM-dd HH:mm:ssZ&quot;
+     y      The CultureInfo yearMonth Format Pattern                                     &quot;MMMM, yyyy&quot;
+    &lt;/pre&gt;
+     * @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 &amp;&amp; format.length == 1) {
+            var c = $C.formatPatterns;
+            x.t = x.toString;
+            switch (format) {
+            case &quot;d&quot;: 
+                return x.t(c.shortDate);
+            case &quot;D&quot;:
+                return x.t(c.longDate);
+            case &quot;F&quot;:
+                return x.t(c.fullDateTime);
+            case &quot;m&quot;:
+                return x.t(c.monthDay);
+            case &quot;r&quot;:
+                return x.t(c.rfc1123);
+            case &quot;s&quot;:
+                return x.t(c.sortableDateTime);
+            case &quot;t&quot;:
+                return x.t(c.shortTime);
+            case &quot;T&quot;:
+                return x.t(c.longTime);
+            case &quot;u&quot;:
+                return x.t(c.universalSortableDateTime);
+            case &quot;y&quot;:
+                return x.t(c.yearMonth);
+            }    
+        }
+        
+        var ord = function (n) {
+                switch (n * 1) {
+                case 1: 
+                case 21: 
+                case 31: 
+                    return &quot;st&quot;;
+                case 2: 
+                case 22: 
+                    return &quot;nd&quot;;
+                case 3: 
+                case 23: 
+                    return &quot;rd&quot;;
+                default: 
+                    return &quot;th&quot;;
+                }
+            };
+        
+        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) === &quot;\\&quot;) {
+                return m.replace(&quot;\\&quot;, &quot;&quot;);
+            }
+            x.h = x.getHours;
+            switch (m) {
+            case &quot;hh&quot;:
+                return p(x.h() &lt; 13 ? (x.h() === 0 ? 12 : x.h()) : (x.h() - 12));
+            case &quot;h&quot;:
+                return x.h() &lt; 13 ? (x.h() === 0 ? 12 : x.h()) : (x.h() - 12);
+            case &quot;HH&quot;:
+                return p(x.h());
+            case &quot;H&quot;:
+                return x.h();
+            case &quot;mm&quot;:
+                return p(x.getMinutes());
+            case &quot;m&quot;:
+                return x.getMinutes();
+            case &quot;ss&quot;:
+                return p(x.getSeconds());
+            case &quot;s&quot;:
+                return x.getSeconds();
+            case &quot;yyyy&quot;:
+                return p(x.getFullYear(), 4);
+            case &quot;yy&quot;:
+                return p(x.getFullYear());
+            case &quot;dddd&quot;:
+                return $C.dayNames[x.getDay()];
+            case &quot;ddd&quot;:
+                return $C.abbreviatedDayNames[x.getDay()];
+            case &quot;dd&quot;:
+                return p(x.getDate());
+            case &quot;d&quot;:
+                return x.getDate();
+            case &quot;MMMM&quot;:
+                return $C.monthNames[x.getMonth()];
+            case &quot;MMM&quot;:
+                return $C.abbreviatedMonthNames[x.getMonth()];
+            case &quot;MM&quot;:
+                return p((x.getMonth() + 1));
+            case &quot;M&quot;:
+                return x.getMonth() + 1;
+            case &quot;t&quot;:
+                return x.h() &lt; 12 ? $C.amDesignator.substring(0, 1) : $C.pmDesignator.substring(0, 1);
+            case &quot;tt&quot;:
+                return x.h() &lt; 12 ? $C.amDesignator : $C.pmDesignator;
+            case &quot;S&quot;:
+                return ord(x.getDate());
+            default: 
+                return m;
+            }
+        }
+        ) : this._toString();
+    };
+}());    /**
+ * @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) {
+            this.message = &quot;Parse error at '&quot; + s.substring(0, 10) + &quot; ...'&quot;; 
+        }
+    };
+    
+    var $P = Date.Parsing; 
+    var _ = $P.Operators = {
+        //
+        // Tokenizers
+        //
+        rtoken: function (r) { // regex token
+            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) { // whitespace-eating token
+            return function (s) {
+                return _.rtoken(new RegExp(&quot;^\s*&quot; + s + &quot;\s*&quot;))(s);
+                // Removed .strip()
+                // return _.rtoken(new RegExp(&quot;^\s*&quot; + s + &quot;\s*&quot;))(s).strip();
+            };
+        },
+        stoken: function (s) { // string token
+            return _.rtoken(new RegExp(&quot;^&quot; + s)); 
+        },
+
+        //
+        // Atomic Operators
+        // 
+
+        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 ];
+            };
+        },
+
+        // generator operators -- see below
+        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 &lt; 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; 
+                }
+            };
+        },
+    	  
+        // vector operators -- see below
+        any: function () {
+            var px = arguments;
+            return function (s) { 
+                var r = null;
+                for (var i = 0; i &lt; 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 &lt; 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)); 
+        },
+
+        // delimited operators
+        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 &lt; 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) ];
+            };
+        },
+    		
+	    //
+	    // Composite Operators
+	    //
+    		
+        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) {
+                // r is the current match, best the current 'best' match
+                // which means it parsed the most amount of input
+                var r = null, p = null, q = null, rx = null, best = [[], s], last = false;
+
+                // go through the rules in the given set
+                for (var i = 0; i &lt; px.length ; i++) {
+
+                    // last is a flag indicating whether this must be the last element
+                    // if there is only 1 element, then it MUST be the last one
+                    q = null; 
+                    p = null; 
+                    r = null; 
+                    last = (px.length == 1); 
+
+                    // first, we try simply to match the current pattern
+                    // if not, try the next pattern
+                    try { 
+                        r = px[i].call(this, s);
+                    } catch (e) { 
+                        continue; 
+                    }
+
+                    // since we are matching against a set of elements, the first
+                    // thing to do is to add r[0] to matched elements
+                    rx = [[r[0]], r[1]];
+
+                    // if we matched and there is still input to parse and 
+                    // we don't already know this is the last element,
+                    // we're going to next check for the delimiter ...
+                    // if there's none, or if there's no input left to parse
+                    // than this must be the last element after all ...
+                    if (r[1].length &gt; 0 &amp;&amp; ! last) {
+                        try { 
+                            q = d.call(this, r[1]); 
+                        } catch (ex) { 
+                            last = true; 
+                        }
+                    } else { 
+                        last = true; 
+                    }
+
+				    // if we parsed the delimiter and now there's no more input,
+				    // that means we shouldn't have parsed the delimiter at all
+				    // so don't update r and mark this as the last element ...
+                    if (!last &amp;&amp; q[1].length === 0) { 
+                        last = true; 
+                    }
+
+
+				    // so, if this isn't the last element, we're going to see if
+				    // we can get any more matches from the remaining (unmatched)
+				    // elements ...
+                    if (!last) {
+
+                        // build a list of the remaining rules we can match against,
+                        // i.e., all but the one we just matched against
+                        var qx = []; 
+                        for (var j = 0; j &lt; px.length ; j++) { 
+                            if (i != j) { 
+                                qx.push(px[j]); 
+                            }
+                        }
+
+                        // now invoke recursively set with the remaining input
+                        // note that we don't include the closing delimiter ...
+                        // we'll check for that ourselves at the end
+                        p = _.set(qx, d).call(this, q[1]);
+
+                        // if we got a non-empty set as a result ...
+                        // (otw rx already contains everything we want to match)
+                        if (p[0].length &gt; 0) {
+                            // update current result, which is stored in rx ...
+                            // basically, pick up the remaining text from p[1]
+                            // and concat the result from p[0] so that we don't
+                            // get endless nesting ...
+                            rx[0] = rx[0].concat(p[0]); 
+                            rx[1] = p[1]; 
+                        }
+                    }
+
+				    // at this point, rx either contains the last matched element
+				    // or the entire matched set that starts with this element.
+
+				    // now we just check to see if this variation is better than
+				    // our best so far, in terms of how much of the input is parsed
+                    if (rx[1].length &lt; best[1].length) { 
+                        best = rx; 
+                    }
+
+				    // if we've parsed all the input, then we're finished
+                    if (best[1].length === 0) { 
+                        break; 
+                    }
+                }
+
+			    // so now we've either gone through all the patterns trying them
+			    // as the initial match; or we found one that parsed the entire
+			    // input string ...
+
+			    // if best has no matches, just return empty set ...
+                if (best[0].length === 0) { 
+                    return best; 
+                }
+
+			    // if a closing delimiter is provided, then we have to check it also
+                if (c) {
+                    // we try this even if there is no remaining input because the pattern
+                    // may well be optional or match empty input ...
+                    try { 
+                        q = c.call(this, best[1]); 
+                    } catch (ey) { 
+                        throw new $P.Exception(best[1]); 
+                    }
+
+                    // it parsed ... be sure to update the best match remaining input
+                    best[1] = q[1];
+                }
+
+			    // if we're here, either there was no closing delimiter or we parsed it
+			    // so now we have the best match; just return it!
+                return best;
+            };
+        },
+        forward: function (gr, fname) {
+            return function (s) { 
+                return gr[fname].call(this, s); 
+            };
+        },
+
+        //
+        // Translation Operators
+        //
+        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 &lt; min) { 
+                    throw new $P.Exception(s); 
+                }
+                return rx;
+            };
+        }
+    };
+	
+
+	// Generator Operators And Vector Operators
+
+	// Generators are operators that have a signature of F(R) =&gt; R,
+	// taking a given rule and returning another rule, such as 
+	// ignore, which parses a given rule and throws away the result.
+
+	// Vector operators are those that have a signature of F(R1,R2,...) =&gt; R,
+	// take a list of rules and returning a new rule, such as each.
+
+	// Generator operators are converted (via the following _generator
+	// function) into functions that can also take a list or array of rules
+	// and return an array of new rules as though the function had been
+	// called on each rule in turn (which is what actually happens).
+
+	// This allows generators to be used with vector operators more easily.
+	// Example:
+	// each(ignore(foo, bar)) instead of each(ignore(foo), ignore(bar))
+
+	// This also turns generators into vector operators, which allows
+	// constructs like:
+	// not(cache(foo, bar))
+	
+    var _generator = function (op) {
+        return function () {
+            var args = null, rx = [];
+            if (arguments.length &gt; 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 &lt; 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 = &quot;optional not ignore cache&quot;.split(/\s/);
+    
+    for (var i = 0 ; i &lt; 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 = &quot;each any all&quot;.split(/\s/);
+    
+    for (var j = 0 ; j &lt; 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 &lt; 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, &quot;&quot;);
+                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) ? &quot;jan feb mar apr may jun jul aug sep oct nov dec&quot;.indexOf(s)/4 : Number(s) - 1;
+            };
+        },
+        year: function (s) {
+            return function () {
+                var n = Number(s);
+                this.year = ((s.length &gt; 2) ? n : 
+                    (n + (((n + 2000) &lt; $C.twoDigitYearMax) ? 2000 : 1900))); 
+            };
+        },
+        rday: function (s) { 
+            return function () {
+                switch (s) {
+                case &quot;yesterday&quot;: 
+                    this.days = -1;
+                    break;
+                case &quot;tomorrow&quot;:  
+                    this.days = 1;
+                    break;
+                case &quot;today&quot;: 
+                    this.days = 0;
+                    break;
+                case &quot;now&quot;: 
+                    this.days = 0; 
+                    this.now = true; 
+                    break;
+                }
+            };
+        },
+        finishExact: function (x) {  
+            x = (x instanceof Array) ? x : [ x ]; 
+
+            for (var i = 0 ; i &lt; x.length ; i++) { 
+                if (x[i]) { 
+                    x[i].call(this); 
+                }
+            }
+            
+            var now = new Date();
+            
+            if ((this.hour || this.minute) &amp;&amp; (!this.month &amp;&amp; !this.year &amp;&amp; !this.day)) {
+                this.day = now.getDate();
+            }
+
+            if (!this.year) {
+                this.year = now.getFullYear();
+            }
+            
+            if (!this.month &amp;&amp; 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 &amp;&amp; this.hour) {
+                if (this.meridian == &quot;p&quot; &amp;&amp; this.hour &lt; 12) {
+                    this.hour = this.hour + 12;
+                } else if (this.meridian == &quot;a&quot; &amp;&amp; this.hour == 12) {
+                    this.hour = 0;
+                }
+            }
+            
+            if (this.day &gt; $D.getDaysInMonth(this.year, this.month)) {
+                throw new RangeError(this.day + &quot; is not a valid value for days.&quot;);
+            }
+
+            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 &lt; x.length ; i++) { 
+                if (typeof x[i] == &quot;function&quot;) {
+                    x[i].call(this); 
+                }
+            }
+            
+            var today = $D.today();
+            
+            if (this.now &amp;&amp; !this.unit &amp;&amp; !this.operator) { 
+                return new Date(); 
+            } else if (this.now) {
+                today = new Date();
+            }
+            
+            var expression = !!(this.days &amp;&amp; this.days !== null || this.orient || this.operator);
+            
+            var gap, mod, orient;
+            orient = ((this.orient == &quot;past&quot; || this.operator == &quot;subtract&quot;) ? -1 : 1);
+            
+            if(!this.now &amp;&amp; &quot;hour minute second&quot;.indexOf(this.unit) != -1) {
+                today.setTimeToNow();
+            }
+
+            if (this.month || this.month === 0) {
+                if (&quot;year day hour minute second&quot;.indexOf(this.unit) != -1) {
+                    this.value = this.month + 1;
+                    this.month = null;
+                    expression = true;
+                }
+            }
+            
+            if (!expression &amp;&amp; this.weekday &amp;&amp; !this.day &amp;&amp; !this.days) {
+                var temp = Date[this.weekday]();
+                this.day = temp.getDate();
+                if (!this.month) {
+                    this.month = temp.getMonth();
+                }
+                this.year = temp.getFullYear();
+            }
+            
+            if (expression &amp;&amp; this.weekday &amp;&amp; this.unit != &quot;month&quot;) {
+                this.unit = &quot;day&quot;;
+                gap = ($D.getDayNumberFromName(this.weekday) - today.getDay());
+                mod = 7;
+                this.days = gap ? ((gap + (orient * mod)) % mod) : (orient * mod);
+            }
+            
+            if (this.month &amp;&amp; this.unit == &quot;day&quot; &amp;&amp; this.operator) {
+                this.value = (this.month + 1);
+                this.month = null;
+            }
+       
+            if (this.value != null &amp;&amp; this.month != null &amp;&amp; this.year != null) {
+                this.day = this.value * 1;
+            }
+     
+            if (this.month &amp;&amp; !this.day &amp;&amp; this.value) {
+                today.set({ day: this.value * 1 });
+                if (!expression) {
+                    this.day = this.value * 1;
+                }
+            }
+
+            if (!this.month &amp;&amp; this.value &amp;&amp; this.unit == &quot;month&quot; &amp;&amp; !this.now) {
+                this.month = this.value;
+                expression = true;
+            }
+
+            if (expression &amp;&amp; (this.month || this.month === 0) &amp;&amp; this.unit != &quot;year&quot;) {
+                this.unit = &quot;month&quot;;
+                gap = (this.month - today.getMonth());
+                mod = 12;
+                this.months = gap ? ((gap + (orient * mod)) % mod) : (orient * mod);
+                this.month = null;
+            }
+
+            if (!this.unit) { 
+                this.unit = &quot;day&quot;; 
+            }
+            
+            if (!this.value &amp;&amp; this.operator &amp;&amp; this.operator !== null &amp;&amp; this[this.unit + &quot;s&quot;] &amp;&amp; this[this.unit + &quot;s&quot;] !== null) {
+                this[this.unit + &quot;s&quot;] = this[this.unit + &quot;s&quot;] + ((this.operator == &quot;add&quot;) ? 1 : -1) + (this.value||0) * orient;
+            } else if (this[this.unit + &quot;s&quot;] == null || this.operator != null) {
+                if (!this.value) {
+                    this.value = 1;
+                }
+                this[this.unit + &quot;s&quot;] = this.value * orient;
+            }
+
+            if (this.meridian &amp;&amp; this.hour) {
+                if (this.meridian == &quot;p&quot; &amp;&amp; this.hour &lt; 12) {
+                    this.hour = this.hour + 12;
+                } else if (this.meridian == &quot;a&quot; &amp;&amp; this.hour == 12) {
+                    this.hour = 0;
+                }
+            }
+            
+            if (this.weekday &amp;&amp; !this.day &amp;&amp; !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) &amp;&amp; !this.day) { 
+                this.day = 1; 
+            }
+            
+            if (!this.orient &amp;&amp; !this.operator &amp;&amp; this.unit == &quot;week&quot; &amp;&amp; this.value &amp;&amp; !this.day &amp;&amp; !this.month) {
+                return Date.today().setWeek(this.value);
+            }
+
+            if (expression &amp;&amp; this.timezone &amp;&amp; this.day &amp;&amp; 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(&quot;:&quot;);
+    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 &lt; 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]);
+    };
+
+    // hour, minute, second, meridian, timezone
+    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));
+  
+    // _.min(1, _.set([ g.H, g.m, g.s ], g._t));
+    g.t = _.cache(_.process(g.ctoken2(&quot;shortMeridian&quot;), t.meridian));
+    g.tt = _.cache(_.process(g.ctoken2(&quot;longMeridian&quot;), 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(&quot;timezone&quot;), t.timezone));
+    g.timeSuffix = _.each(_.ignore(g.whiteSpace), _.set([ g.tt, g.zzz ]));
+    g.time = _.each(_.optional(_.ignore(_.stoken(&quot;T&quot;))), g.hms, g.timeSuffix);
+    	  
+    // days, months, years
+    g.d = _.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/), 
+        _.optional(g.ctoken2(&quot;ordinalSuffix&quot;))), t.day));
+    g.dd = _.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/), 
+        _.optional(g.ctoken2(&quot;ordinalSuffix&quot;))), t.day));
+    g.ddd = g.dddd = _.cache(_.process(g.ctoken(&quot;sun mon tue wed thu fri sat&quot;), 
+        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(&quot;jan feb mar apr may jun jul aug sep oct nov dec&quot;), 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));
+	
+	// rolling these up into general purpose rules
+    _fn = function () { 
+        return _.each(_.any.apply(null, arguments), _.not(g.ctoken2(&quot;timeContext&quot;)));
+    };
+    
+    g.day = _fn(g.d, g.dd); 
+    g.month = _fn(g.M, g.MMM); 
+    g.year = _fn(g.yyyy, g.yy);
+
+    // relative date / time expressions
+    g.orientation = _.process(g.ctoken(&quot;past future&quot;), 
+        function (s) { 
+            return function () { 
+                this.orient = s; 
+            }; 
+        }
+    );
+    g.operator = _.process(g.ctoken(&quot;add subtract&quot;), 
+        function (s) { 
+            return function () { 
+                this.operator = s; 
+            }; 
+        }
+    );  
+    g.rday = _.process(g.ctoken(&quot;yesterday tomorrow today now&quot;), t.rday);
+    g.unit = _.process(g.ctoken(&quot;second minute hour day week month year&quot;), 
+        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, &quot;&quot;); 
+            }; 
+        }
+    );
+    g.expression = _.set([ g.rday, g.operator, g.value, g.unit, g.orientation, g.ddd, g.MMM ]);
+
+    // pre-loaded rules for different date part order preferences
+    _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));
+    }; 
+
+    // parsing date format specifiers - ex: &quot;h:m:s tt&quot; 
+    // this little guy will generate a custom parser based
+    // on the format string, ex: g.format(&quot;h:m:s tt&quot;)
+    g.format = _.process(_.many(
+        _.any(
+        // translate format specifiers into grammar rules
+        _.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); 
+        }
+    }
+    ),
+    // translate separator tokens into token rules
+    _.process(
+    _.rtoken(/^[^dMyhHmstz]+/), // all legal separators 
+        function (s) { 
+            return _.ignore(_.stoken(s)); 
+        } 
+    )
+    )), 
+        // construct the parser ...
+        function (rules) { 
+            return _.process(_.each.apply(null, rules), t.finishExact); 
+        }
+    );
+    
+    var _F = {
+		//&quot;M/d/yyyy&quot;: function (s) { 
+		//	var m = s.match(/^([0-2]\d|3[0-1]|\d)\/(1[0-2]|0\d|\d)\/(\d\d\d\d)/);
+		//	if (m!=null) { 
+		//		var r =  [ t.month.call(this,m[1]), t.day.call(this,m[2]), t.year.call(this,m[3]) ];
+		//		r = t.finishExact.call(this,r);
+		//		return [ r, &quot;&quot; ];
+		//	} else {
+		//		throw new Date.Parsing.Exception(s);
+		//	}
+		//}
+		//&quot;M/d/yyyy&quot;: function (s) { return [ new Date(Date._parse(s)), &quot;&quot;]; }
+	}; 
+    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 &lt; fx.length ; i++) {
+                rx.push(_get(fx[i])); 
+            }
+            return _.any.apply(null, rx);
+        } else { 
+            return _get(fx); 
+        }
+    };
+
+	// check for these formats first
+    g._formats = g.formats([
+        &quot;\&quot;yyyy-MM-ddTHH:mm:ssZ\&quot;&quot;,
+        &quot;yyyy-MM-ddTHH:mm:ssZ&quot;,
+        &quot;yyyy-MM-ddTHH:mm:ssz&quot;,
+        &quot;yyyy-MM-ddTHH:mm:ss&quot;,
+        &quot;yyyy-MM-ddTHH:mmZ&quot;,
+        &quot;yyyy-MM-ddTHH:mmz&quot;,
+        &quot;yyyy-MM-ddTHH:mm&quot;,
+        &quot;ddd, MMM dd, yyyy H:mm:ss tt&quot;,
+        &quot;ddd MMM d yyyy HH:mm:ss zzz&quot;,
+        &quot;MMddyyyy&quot;,
+        &quot;ddMMyyyy&quot;,
+        &quot;Mddyyyy&quot;,
+        &quot;ddMyyyy&quot;,
+        &quot;Mdyyyy&quot;,
+        &quot;dMyyyy&quot;,
+        &quot;yyyy&quot;,
+        &quot;Mdyy&quot;,
+        &quot;dMyy&quot;,
+        &quot;d&quot;
+    ]);
+
+	// starting rule for general purpose grammar
+    g._start = _.process(_.set([ g.date, g.time, g.expression ], 
+        g.generalDelimiter, g.whiteSpace), t.finish);
+	
+	// real starting rule: tries selected formats first, 
+	// then general purpose rule
+    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;
+
+    /**
+     * Converts the specified string value into its JavaScript Date equivalent using CultureInfo specific format information.
+     * 
+     * Example
+    &lt;pre&gt;&lt;code&gt;
+    ///////////
+    // Dates //
+    ///////////
+
+    // 15-Oct-2004
+    var d1 = Date.parse(&quot;10/15/2004&quot;);
+
+    // 15-Oct-2004
+    var d1 = Date.parse(&quot;15-Oct-2004&quot;);
+
+    // 15-Oct-2004
+    var d1 = Date.parse(&quot;2004.10.15&quot;);
+
+    //Fri Oct 15, 2004
+    var d1 = Date.parse(&quot;Fri Oct 15, 2004&quot;);
+
+    ///////////
+    // Times //
+    ///////////
+
+    // Today at 10 PM.
+    var d1 = Date.parse(&quot;10 PM&quot;);
+
+    // Today at 10:30 PM.
+    var d1 = Date.parse(&quot;10:30 P.M.&quot;);
+
+    // Today at 6 AM.
+    var d1 = Date.parse(&quot;06am&quot;);
+
+    /////////////////////
+    // Dates and Times //
+    /////////////////////
+
+    // 8-July-2004 @ 10:30 PM
+    var d1 = Date.parse(&quot;July 8th, 2004, 10:30 PM&quot;);
+
+    // 1-July-2004 @ 10:30 PM
+    var d1 = Date.parse(&quot;2004-07-01T22:30:00&quot;);
+
+    ////////////////////
+    // Relative Dates //
+    ////////////////////
+
+    // Returns today's date. The string &quot;today&quot; is culture specific.
+    var d1 = Date.parse(&quot;today&quot;);
+
+    // Returns yesterday's date. The string &quot;yesterday&quot; is culture specific.
+    var d1 = Date.parse(&quot;yesterday&quot;);
+
+    // Returns the date of the next thursday.
+    var d1 = Date.parse(&quot;Next thursday&quot;);
+
+    // Returns the date of the most previous monday.
+    var d1 = Date.parse(&quot;last monday&quot;);
+
+    // Returns today's day + one year.
+    var d1 = Date.parse(&quot;next year&quot;);
+
+    ///////////////
+    // Date Math //
+    ///////////////
+
+    // Today + 2 days
+    var d1 = Date.parse(&quot;t+2&quot;);
+
+    // Today + 2 days
+    var d1 = Date.parse(&quot;today + 2 days&quot;);
+
+    // Today + 3 months
+    var d1 = Date.parse(&quot;t+3m&quot;);
+
+    // Today - 1 year
+    var d1 = Date.parse(&quot;today - 1 year&quot;);
+
+    // Today - 1 year
+    var d1 = Date.parse(&quot;t-1y&quot;); 
+
+
+    /////////////////////////////
+    // Partial Dates and Times //
+    /////////////////////////////
+
+    // July 15th of this year.
+    var d1 = Date.parse(&quot;July 15&quot;);
+
+    // 15th day of current day and year.
+    var d1 = Date.parse(&quot;15&quot;);
+
+    // July 1st of current year at 10pm.
+    var d1 = Date.parse(&quot;7/1 10pm&quot;);
+    &lt;/code&gt;&lt;/pre&gt;
+     *
+     * @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 = $D.Grammar.start.call({}, s.replace(/^\s*(\S*(\s+\S+)*)\s*$/, &quot;$1&quot;)); 
+        } 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);
+        };
+    };
+    
+    /**
+     * 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
+    &lt;pre&gt;&lt;code&gt;
+    // 15-Oct-2004
+    var d1 = Date.parseExact(&quot;10/15/2004&quot;, &quot;M/d/yyyy&quot;);
+
+    // 15-Oct-2004
+    var d1 = Date.parse(&quot;15-Oct-2004&quot;, &quot;M-ddd-yyyy&quot;);
+
+    // 15-Oct-2004
+    var d1 = Date.parse(&quot;2004.10.15&quot;, &quot;yyyy.MM.dd&quot;);
+
+    // Multiple formats
+    var d1 = Date.parseExact(&quot;10/15/2004&quot;, [&quot;M/d/yyyy&quot;, &quot;MMMM d, yyyy&quot;]);
+    &lt;/code&gt;&lt;/pre&gt;
+     *
+     * @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); 
+    };	
 }());/*
     http://www.JSON.org/json2.js
     2008-11-19
@@ -6934,6 +6934,7 @@ var SpazTimeline = function(opts) {
 	 * @function
 	 */
 	this.refresh = function() {
+		sch.debug('Refreshing timeline');
 		thisTL.requestData.call(thisTL);
 	};
 	
@@ -6942,6 +6943,7 @@ var SpazTimeline = function(opts) {
 	 * Again, due to scope issues, we define this here to take advantage of the closure 
 	 */
 	this.onSuccess = function(e) {
+		sch.debug('onSuccess timeline');
 		var data = sc.helpers.getEventData(e);
 		thisTL.data_success.call(thisTL, e, data);
 		thisTL.startRefresher();	
@@ -6951,6 +6953,7 @@ var SpazTimeline = function(opts) {
 	 * Again, due to scope issues, we define this here to take advantage of the closure 
 	 */
 	this.onFailure = function(e) {
+		sch.debug('onFailure timeline');
 		var data = sc.helpers.getEventData(e);
 		thisTL.data_failure.call(thisTL, e, data);
 		thisTL.startRefresher();	
@@ -7007,6 +7010,7 @@ SpazTimeline.prototype._init = function(opts) {
  * call this after initialization 
  */
 SpazTimeline.prototype.start = function() {
+	sch.debug('Starting timeline');
 	this.requestData();
 };
 
@@ -7014,6 +7018,7 @@ SpazTimeline.prototype.start = function() {
  * right now this does the same as start(), but could change in the future 
  */
 SpazTimeline.prototype.refresh = function() {
+	sch.debug('Refreshing timeline (prototype)');
 	this.requestData();
 };
 
@@ -7024,6 +7029,7 @@ SpazTimeline.prototype.refresh = function() {
  * @todo needs to be written to handle async call
  */
 SpazTimeline.prototype.requestData = function() {
+	sch.debug('Requesting data timeline');
 	this.stopRefresher();
 	
 	this.stopListening();
@@ -7037,7 +7043,7 @@ SpazTimeline.prototype.requestData = function() {
 
 SpazTimeline.prototype.startListening = function() {
 	var thisTL = this;
-	sch.dump(&quot;Listening for &quot;+thisTL.success_event);
+	sc.helpers.debug(&quot;Listening for &quot;+thisTL.success_event);
 	sc.helpers.listen(thisTL.event_target, thisTL.success_event, thisTL.onSuccess);
 	sc.helpers.listen(thisTL.event_target, thisTL.failure_event, thisTL.onFailure);
 };
@@ -7045,19 +7051,26 @@ SpazTimeline.prototype.startListening = function() {
 
 SpazTimeline.prototype.stopListening = function() {
 	var thisTL = this;
+	sc.helpers.debug(&quot;Stopping listening for &quot;+thisTL.success_event);
 	sc.helpers.unlisten(thisTL.event_target, thisTL.success_event, thisTL.onSuccess);
 	sc.helpers.unlisten(thisTL.event_target, thisTL.failure_event, thisTL.onFailure);
 };
 
 SpazTimeline.prototype.startRefresher = function() {
 	this.stopRefresher();
+	
+	sc.helpers.debug('Starting refresher');
 	if (this.refresh_time &gt; 1000) { // the minimum refresh is 1000ms. Otherwise we don't auto-refresh
+		sc.helpers.debug('Refresh time is '+this.refresh_time+'ms');
 		this.refresher = setInterval(this.refresh, this.refresh_time);
+	} else {
+		sc.helpers.debug('Not starting refresher; refresh time is '+this.refresh_time+'ms');
 	}
 };
 
 
 SpazTimeline.prototype.stopRefresher = function() {
+	sc.helpers.debug('Stopping refresher');
 	clearInterval(this.refresher);
 };
 
@@ -7071,6 +7084,7 @@ SpazTimeline.prototype.stopRefresher = function() {
  * removing event listeners an stopping the refresher 
  */
 SpazTimeline.prototype.cleanup = function() {
+	sch.debug('Cleaning up timeline');
 	this.stopListening();
 	this.stopRefresher();
 };
@@ -7080,6 +7094,8 @@ SpazTimeline.prototype.cleanup = function() {
  * @param {array} items
  */
 SpazTimeline.prototype.addItems = function(items) {
+	sch.debug('Adding items to timeline');
+	
 	var items_html    = [];
 	var timeline_html = '';
 	
@@ -7102,6 +7118,7 @@ SpazTimeline.prototype.addItems = function(items) {
 
 
 SpazTimeline.prototype.renderItem = function(item, templatefunc) {
+	sch.debug('Rendering item in timeline');
 	
 	var html = templatefunc(item);
 	
@@ -7112,6 +7129,8 @@ SpazTimeline.prototype.renderItem = function(item, templatefunc) {
 
 SpazTimeline.prototype.removeExtraItems = function() {
 	
+	sch.debug('Removing extra items in timeline');
+	
 	if (this.add_method === 'append') {
 		var remove_from_top = true;
 	} else {
@@ -7132,6 +7151,9 @@ SpazTimeline.prototype.removeItem = function(selector) {};
  * @return {boolean} 
  */
 SpazTimeline.prototype.itemExists = function(selector) {
+	
+	sch.debug('Checking it item ('+selector+') exists in timeline');
+	
 	var items = this.select(selector);
 	if (items.length&gt;0) {
 		return true;
@@ -7143,11 +7165,15 @@ SpazTimeline.prototype.itemExists = function(selector) {
 
 
 SpazTimeline.prototype.hideItems = function(selector) {
+	sch.debug('Hiding items in timeline');
+	
 	this.filterItems(selector, 'blacklist');
 };
 
 
 SpazTimeline.prototype.showItems = function(selector) {
+	sch.debug('Showing items in timeline');
+	
 	this.filterItems(selector, 'whitelist');
 };
 
@@ -7163,6 +7189,9 @@ SpazTimeline.prototype.filterItems = function(selector, type) {};
  * sorts the elements in the timeline according to the sorting function 
  */
 SpazTimeline.prototype.sortItems = function(selector, sortfunc) {
+	
+	sch.debug('Sorting items in timeline');
+	
 	var items = this.select(selector);
 	items.sort(sortfunc);
 };
@@ -7236,7 +7265,7 @@ var SPAZCORE_SECTION_FOLLOWERSLIST = 'followerslist';
 var SPAZCORE_SERVICE_TWITTER = 'twitter';
 var SPAZCORE_SERVICE_IDENTICA = 'identi.ca';
 var SPAZCORE_SERVICE_CUSTOM = 'custom';
-var SPAZCORE_SERVICEURL_TWITTER = 'https://twitter.com/';
+var SPAZCORE_SERVICEURL_TWITTER = 'https://api.twitter.com/1/';
 var SPAZCORE_SERVICEURL_IDENTICA = 'https://identi.ca/api/';
 
 /**
@@ -8204,7 +8233,8 @@ SpazTwit.prototype._processSearchItem = function(item, section_name) {
 	*/
 	item.user = {
 		'profile_image_url':item.profile_image_url,
-		'screen_name':item.from_user
+		'screen_name':item.from_user,
+		'id':item.from_user_id
 	};
 	
 	/*
@@ -8968,12 +8998,8 @@ SpazTwit.prototype._processUpdateReturn = function(data, finished_event) {
 		this item needs to be added to the friends + home timeline
 		so we can avoid dupes
 	*/
-	/*
-		not processing home timeline yet; we need to pick one or the other
-		to avoid duplicate events firing for updates
-	*/
 	this._processTimeline(SPAZCORE_SECTION_HOME, [data], finished_event);
-	// this._processTimeline(SPAZCORE_SECTION_FRIENDS, [data], finished_event);
+	this._processTimeline(SPAZCORE_SECTION_FRIENDS, [data], finished_event);
 };
 
 SpazTwit.prototype.destroy = function(id) {};
@@ -9314,6 +9340,53 @@ SpazTwit.prototype.removeSavedSearch = function(search_id) {
 
 
 
+
+/**
+ * retrieves the list of lists 
+ */
+SpazTwit.prototype.getLists = function() {};
+
+/**
+ * retrieves a given list timeline
+ * @param {string} list 
+ */
+SpazTwit.prototype.getList = function(list) {};
+
+/**
+ * retrieves a given list's members
+ * @param {string} list 
+ */
+SpazTwit.prototype.getListMembers = function(list) {};
+
+/**
+ * create a new list
+ * @param {string} list  The list name
+ * @param {string} visibility   &quot;public&quot; or &quot;private&quot;
+ */
+SpazTwit.prototype.addList = function(list, visibility) {};
+
+/**
+ * delete a list
+ * @param {string} list  The list name 
+ */
+SpazTwit.prototype.removeList = function(list) {};
+
+/**
+ * add a user to a list
+ */
+SpazTwit.prototype.addUserToList = function(user, list) {};
+
+/**
+ * delete a user from a list 
+ */
+SpazTwit.prototype.removeUserFromList = function(user, list) {};
+
+
+
+
+/**
+ *  
+ */
 SpazTwit.prototype.triggerEvent = function(type, data) {
 	var target = this.opts.event_target || document;
 	data   = data || null;</diff>
      <filename>spazcore/spazcore-webos.js</filename>
    </modified>
    <modified>
      <diff>@@ -73,6 +73,11 @@ a:link, a:visited, .clickable {
 	-webkit-border-image: url(../images/dreadnaught/palm-group.png) 40 18 14 18;	
 }
 
+.palm-dark .palm-group-spaz .palm-group-title{
+	color:#CCC;
+}
+
+
 .palm-popup-container {
 	color:#111111;
 }
@@ -91,11 +96,10 @@ div.timeline {
 }
 
 div.timeline-entry {
-	padding: 2px 6px 12px;
-/*	border-width: 1px 0 1px 0;*/
-/*	border-style: solid;*/
-/*	border-color: #333;*/
-	border-bottom: 1px solid #222;
+	padding: 2px 6px 6px;
+	margin-bottom:5px;
+	-khtml-border-radius: 10px;
+/*	border-bottom: 1px solid #222;*/
 	clear:both;
 	overflow:hidden;
 	min-height:64px;
@@ -104,51 +108,37 @@ div.timeline-entry {
 	background-image: url('../images/dreadnaught/entry-gradient-bg_short.png');
 	background-repeat: repeat-x;
 	background-color:#101010;
+	background-position: 0px -3px;
 }
 
-	div.timeline-entry:active {	}
-
-	/*
-		the .even and .odd classes are really only used in the timelines, but 
-		they're usedful and probably could be reused elsewhere.
-	*/
-	div.timeline-entry:nth-of-type(odd), .odd {
-/*		background-color: #2b3a3c;*/
-	}
-	div.timeline-entry:nth-of-type(even), .even {
-/*		background-color: #25303f;*/
+	div.timeline-entry.new {
+		color:#FFFF88;
 	}
-	
+
+
 	/*
 		Entries that are replies directed at the user
 	*/
-	div.timeline-entry.reply:nth-of-type(odd),
-	div.timeline-entry.reply:nth-of-type(even) {
+	div.timeline-entry.reply {
 		background-color: #2B3235;
 	}
 	/*
 		Entries that are direct messages to the user
 	*/
-	div.timeline-entry.dm:nth-of-type(odd),
-	div.timeline-entry.dm:nth-of-type(even) {
+	div.timeline-entry.dm {
 		background-color: #301616;
 	}
-	
-	div.timeline-entry.new {
+
+	div.timeline-entry.reply:active,
+	div.timeline-entry.dm:active,
+	div.timeline-entry:active {	
+		background-color:#222222;
 		color:#FFFFCC;
-/*		border-bottom:1px solid #FFFFCC;*/
 	}
-		div.timeline-entry.new:first-of-type {
-			color:#FFFFCC;
-/*			border-top:   1px solid #FFFFCC;*/
-/*			border-bottom:1px solid #FFFFCC;*/
-		}
-		div.timeline-entry.new:nth-of-type(odd) {
-/*			background-color: #2b3a3c;*/
-		}
-		div.timeline-entry.new:nth-of-type(even) {
-/*			background-color: #25303f;*/
-		}
+	
+
+	
+
 
 		
 
@@ -157,7 +147,6 @@ div.timeline-entry {
 		text-align:center;
 		width:48px;
 		height:48px;
-/*		border:1px solid #333;*/
 		margin-top:10px;
 		margin-left:3px;
 
@@ -165,10 +154,6 @@ div.timeline-entry {
 		div.timeline-entry .user .user-img, div.timeline-entry .user img {
 			width:48px;
 			height:48px;
-/*			border:0px single #333;*/
-/*			-webkit-box-shadow:0px 1px 5px #333;*/
-/*			background-image:url('../images/dreadnaught/details-image-generic.png');*/
-/*			opacity:.9;*/
 		}
 	
 	div.timeline-entry .status {
@@ -302,8 +287,24 @@ div.timeline-entry {
 /*
 	login scene stuff
 */
+#mojo-scene-start-scene-scroller {
+/*	border:1px solid green;*/
+	background-image: url('../images/dreadnaught/page-bg-darkgreen-start.png');
+}
+
+#mojo-scene-start {
+	position:absolute !important;
+	bottom:10px;
+}
+
 #start-scene {
-	color:#CCC;
+	color:#EEEEEE;
+/*	position:relative !important;*/
+/*	top:0px;*/
+	bottom:0px;
+	vertical-align: bottom;
+/*	border:1px solid yellow;*/
+	height:175px;
 }
 
 #splash-logo {
@@ -913,7 +914,6 @@ div.spaz-row {
 div.inline-spinner {
 	height: 24px;
 	margin:5px 8px;
-
 	padding: 6px 16px 10px;
 	border-width: 0 18px 0 18px;
 	-webkit-border-image: url(../images/dreadnaught/spaz-roundeditem-darker-bg.png) 0 18 0 18;
@@ -934,6 +934,13 @@ div.inline-spinner {
 
 	}
 	
+
+/*
+	Remove row separator background
+*/	
+.palm-dark  .spaz-activity-spinner-container .palm-row {
+	background:none;
+}
 	
 
 div.error_info {</diff>
      <filename>stylesheets/Dreadnaught.css</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,6 @@
 // Required
 _APP_Name = 'Spaz';
-_APP_VersionNumber = '0.5.10';
+_APP_VersionNumber = '0.5.11';
 _APP_PublisherName = 'Funkatron.com';
 _APP_Copyright = '&amp;copy; Copyright 2009 Funkatron Productions.';
 </diff>
      <filename>support_info.js</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>885c0a9af95ffac03f9280d84b4cdbc618fd2ae8</id>
    </parent>
  </parents>
  <author>
    <name>Ed Finkler</name>
    <email>funkatron@gmail.com</email>
  </author>
  <url>http://github.com/funkatron/spaz-webos/commit/17e6c4af2d1de0d07a8c0823b6a9c901d799cb0f</url>
  <id>17e6c4af2d1de0d07a8c0823b6a9c901d799cb0f</id>
  <committed-date>2009-11-07T19:27:42-08:00</committed-date>
  <authored-date>2009-11-07T19:27:42-08:00</authored-date>
  <message>-Changed JSON decode helper to dump a sch.warn()
-Timeline in MyTimeline scene now inits on setup, not activate, and doesn't get destroyed until cleanup. Timeline keeps refreshing while other scenes are pushed above it
-Some CSS changes to make rounded corners across the board
-removed background w/ separator from activity spinner in timelines
-new spazcore
-Splash page reformatted to fit Pixi screen resolution</message>
  <tree>6f34a87087126ed539ec13501c20c47afd57526b</tree>
  <committer>
    <name>Ed Finkler</name>
    <email>funkatron@gmail.com</email>
  </committer>
</commit>
