<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -116,8 +116,8 @@ MessageDetailAssistant.prototype.activate = function(event) {
 						sch.dump('Message '+data.status_id+' pulled from DB');
 						jQuery().trigger('get_one_status_succeeded', [data]);
 					} else { // if nothing is returned, get it from Twitter
-						// thisA.twit.getOne(thisA.status_id);
-						thisA.showAlert($L('There was an error retrieving this direct message'));
+						sch.error('DM was not in sc.app.Tweets cache');
+						thisA.showAlert($L('There was an error retrieving this direct message from cache'));
 					}
 					
 				},</diff>
      <filename>app/assistants/message-detail-assistant.js</filename>
    </modified>
    <modified>
      <diff>@@ -197,7 +197,7 @@ MyTimelineAssistant.prototype.activate = function(event) {
 			var new_count = jQuery('#my-timeline div.timeline-entry.new:visible').length;
 			
 			if (new_count &gt; 0) {
-				thisA.playAudioCue('newmsg');
+				// thisA.playAudioCue('newmsg');
 				
 				if (previous_count &gt; 0) {
 					if (sc.app.prefs.get('timeline-scrollonupdate')) {
@@ -213,6 +213,8 @@ MyTimelineAssistant.prototype.activate = function(event) {
 				dump(&quot;I am not showing a banner! in &quot;+thisA.controller.sceneElement.id);
 			}
 			thisA.hideInlineSpinner('activity-spinner-my-timeline');
+			
+			thisA.saveTimelineCache();
 		},
 		'data_failure': function(e, error_array) {
 			dump('error_combined_timeline_data - response:');</diff>
      <filename>app/assistants/my-timeline-assistant.js</filename>
    </modified>
    <modified>
      <diff>@@ -148,16 +148,6 @@ PostAssistant.prototype.setup = function() {
 		e.data.thisAssistant.reportFailedPost(error_obj);
 	});
 
-
-	// jQuery('#post-textfield').bind('keyup',   function(e) {
-	// 	thisA._updateCharCount();
-	// });
-	// jQuery('#post-textfield').bind('blur',    function(e) {
-	// 	thisA._updateCharCount();
-	// });
-	// jQuery('#post-textfield').bind('focus',   function(e) {
-	// 	thisA._updateCharCount();
-	// });
 	
 	Mojo.Event.listen($('post-textfield'), Mojo.Event.propertyChange, this._updateCharCount.bindAsEventListener(this));	
 	
@@ -239,9 +229,6 @@ PostAssistant.prototype._updateCharCount = function() {
 	var thisA = this;
 	
 	_updateCharCountNow();
-	// if (thisA._updateCharCountTimeout) {
-	// 	clearTimeout(thisA._updateCharCountTimeout);
-	// }
 
 	function _updateCharCountNow() {
 		var numchars  = thisA.postTextFieldModel.value.length;
@@ -262,8 +249,6 @@ PostAssistant.prototype._updateCharCount = function() {
 		}	
 	}
 	
-	// this._updateCharCountTimeout = setTimeout(_updateCharCountNow, 250);
-	
 	
 };
 
@@ -429,7 +414,6 @@ PostAssistant.prototype.sendPost = function(event) {
 	var status = this.postTextFieldModel.value;
 	
 	if (this.postMode === 'email') {
-		
 		var api_label = this.imageUploaderModel['image-uploader'];
 		var email = this.imageUploaderEmailModel['image-uploader-email'];
 		var emailobj = {'name':api_label, 'address':email};
@@ -657,7 +641,7 @@ PostAssistant.prototype.renderSuccessfulPost = function(event, data) {
 	*/
 	this.filterTimeline();
 	
-	this.playAudioCue('send');
+	// this.playAudioCue('send');
 	
 	this.deactivateSpinner();
 	</diff>
      <filename>app/assistants/post-assistant.js</filename>
    </modified>
    <modified>
      <diff>@@ -49,22 +49,26 @@ PreferencesAssistant.prototype.setup = function() {
 	/*
 		Setup checkboxes
 	*/
-	this.controller.setupWidget(&quot;checkbox-sound-enabled&quot;,
-		this.soundEnabledAtts = {
-			fieldName: 'sound-enabled',
-			modelProperty: 'sound-enabled',
-			disabledProperty: 'sound-enabled_disabled'
-		},
-		this.model
-	);
-	this.controller.setupWidget(&quot;checkbox-vibration-enabled&quot;,
-		this.soundEnabledAtts = {
-			fieldName: 'vibration-enabled',
-			modelProperty: 'vibration-enabled',
-			disabledProperty: 'vibration-enabled_disabled'
-		},
-		this.model
-	);
+	
+	/*
+		temporarily disabling sound and vibration prefs until we can sort out how to tell if sound is off
+	*/
+	// this.controller.setupWidget(&quot;checkbox-sound-enabled&quot;,
+	// 	this.soundEnabledAtts = {
+	// 		fieldName: 'sound-enabled',
+	// 		modelProperty: 'sound-enabled',
+	// 		disabledProperty: 'sound-enabled_disabled'
+	// 	},
+	// 	this.model
+	// );
+	// this.controller.setupWidget(&quot;checkbox-vibration-enabled&quot;,
+	// 	this.soundEnabledAtts = {
+	// 		fieldName: 'vibration-enabled',
+	// 		modelProperty: 'vibration-enabled',
+	// 		disabledProperty: 'vibration-enabled_disabled'
+	// 	},
+	// 	this.model
+	// );
 	this.controller.setupWidget(&quot;checkbox-timeline-scrollonupdate&quot;,
 		this.soundEnabledAtts = {
 			fieldName: 'timeline-scrollonupdate',
@@ -74,8 +78,11 @@ PreferencesAssistant.prototype.setup = function() {
 		this.model
 	);
 	
-	this.controller.listen('checkbox-sound-enabled', Mojo.Event.propertyChange, this.saveSettings.bindAsEventListener(this));
-	this.controller.listen('checkbox-vibration-enabled', Mojo.Event.propertyChange, this.saveSettings.bindAsEventListener(this));
+	/*
+		temporarily disabling sound and vibration prefs until we can sort out how to tell if sound is off
+	*/
+	// this.controller.listen('checkbox-sound-enabled', Mojo.Event.propertyChange, this.saveSettings.bindAsEventListener(this));
+	// this.controller.listen('checkbox-vibration-enabled', Mojo.Event.propertyChange, this.saveSettings.bindAsEventListener(this));
 	this.controller.listen('checkbox-timeline-scrollonupdate', Mojo.Event.propertyChange, this.saveSettings.bindAsEventListener(this));
 
 
@@ -250,9 +257,12 @@ PreferencesAssistant.prototype.cleanup = function(event) {
 	Mojo.Event.stopListening($('clear-cache-button'), Mojo.Event.tap, function(e) {
 		thisA.clearTimelineCache();
 	});
-
-	this.controller.stopListening('checkbox-sound-enabled', Mojo.Event.propertyChange, this.saveSettings);
-	this.controller.stopListening('checkbox-vibration-enabled', Mojo.Event.propertyChange, this.saveSettings);
+	
+	/*
+		temporarily disabling sound and vibration prefs until we can sort out how to tell if sound is off
+	*/
+	// this.controller.stopListening('checkbox-sound-enabled', Mojo.Event.propertyChange, this.saveSettings);
+	// this.controller.stopListening('checkbox-vibration-enabled', Mojo.Event.propertyChange, this.saveSettings);
 	this.controller.stopListening('checkbox-timeline-scrollonupdate', Mojo.Event.propertyChange, this.saveSettings);
 	
 };</diff>
      <filename>app/assistants/preferences-assistant.js</filename>
    </modified>
    <modified>
      <diff>@@ -228,7 +228,7 @@ SearchTwitterAssistant.prototype.activate = function(event) {
 		
 		if (new_count &gt; 0 &amp;&amp; !thisA.isFullScreen) {
 			thisA.newSearchResultsBanner(new_count, e.data.thisAssistant.lastQuery);
-			thisA.playAudioCue('newmsg');
+			// thisA.playAudioCue('newmsg');
 		} else if (thisA.isFullScreen) {
 			dump(&quot;I am not showing a banner! in &quot;+thisA.controller.sceneElement.id);
 		}
@@ -329,8 +329,7 @@ SearchTwitterAssistant.prototype.search = function(e, type) {
 	dump(&quot;search called&quot;);
 	
 	if (type &amp;&amp; type.toLowerCase() !== 'refresh') { // empty unless this is a refresh
-		jQuery('#search-timeline').empty();
-		dump('Emptied #search-timeline');
+		this.clear();
 	} else {
 		sch.markAllAsRead('#search-timeline&gt;div.timeline-entry');
 		dump('Marked all as read in #search-timeline&gt;div.timeline-entry');
@@ -338,21 +337,32 @@ SearchTwitterAssistant.prototype.search = function(e, type) {
 		
 	if (sch.isString(e)) {
 		dump(&quot;Searching for:&quot;, e);
-		this.lastQuery = sch.fromHTMLSpecialChars(e);
-		this.twit.search(this.lastQuery);
-
+		
 		/*
 			clear any existing results
 		*/
+		if (e !== this.lastQuery) {
+			this.clear()
+		}
+		
+		this.lastQuery = sch.fromHTMLSpecialChars(e);
+		this.twit.search(this.lastQuery);
+
+
 		
 		this.activateSpinner();
 		
 	} else if (e.value) {
 		this.lastQuery = e.value;
 		this.twit.search(e.value);		
+
 		/*
 			clear any existing results
 		*/
+		if (e.value !== this.lastQuery) {
+			this.clear()
+		}
+
 
 		this.activateSpinner();
 		
@@ -367,7 +377,10 @@ SearchTwitterAssistant.prototype.refresh = function() {
 	this.search(this.searchBoxModel.value, 'refresh');
 };
 
-
+SearchTwitterAssistant.prototype.clear = function() {
+	jQuery('#search-timeline').empty();
+	dump('Emptied #search-timeline');
+}
 
 
 SearchTwitterAssistant.prototype.startRefresher = function() {</diff>
      <filename>app/assistants/search-twitter-assistant.js</filename>
    </modified>
    <modified>
      <diff>@@ -1016,263 +1016,6 @@ scene_helpers.addCommonSceneMethods = function(assistant) {
 
 
 
-
-
-
-
-/*
-	Small controller class used for the new account dialog
-*/
-var PostDialogAssistant = Class.create({
-	
-	initialize: function(sceneAssistant) {
-		this.sceneAssistant = sceneAssistant;
-		this.controller = sceneAssistant.controller;
-	},
-	
-	setup : function(widget) {
-		this.widget = widget;
-		
-		this.postButtonAttributes = {
-			type: Mojo.Widget.activityButton
-		};
-		this.postButtonModel = {
-			buttonLabel : &quot;Post&quot;,
-			buttonClass: 'Primary'
-		};
-		
-		this.controller.setupWidget('post-send-button', this.postButtonAttributes, this.postButtonModel);
-
-		
-	},
-	
-	activate: function() {
-		var thisA = this;
-		/*
-			What to do if we succeed
-			Note that we pass the assistant object as data into the closure
-		*/				
-
-		Mojo.Event.listen($('post-send-button'), Mojo.Event.tap, this.sendPost.bind(this));
-
-		jQuery('#post-panel-username').text(sc.app.username);
-
-		
-		/*
-			if update succeeds
-		*/
-		jQuery().bind('update_succeeded', { thisAssistant:this }, function(e, data) {
-			e.data.thisAssistant.renderSuccessfulPost(e, data);
-		});
-
-		/*
-			if update fails
-		*/
-		jQuery().bind('update_failed', { thisAssistant:this }, function(e, error_obj) {
-			e.data.thisAssistant.reportFailedPost(error_obj);
-		});
-
-				
-		jQuery('#post-panel-textarea').bind('keyup',   function(e) {
-			thisA._updateCharCount();
-		});
-		jQuery('#post-panel-textarea').bind('keydown', function(e) {
-			thisA._updateCharCount();
-		});
-		jQuery('#post-panel-textarea').bind('blur',    function(e) {
-			thisA._updateCharCount();
-		});
-		jQuery('#post-panel-textarea').bind('focus',   function(e) {
-			thisA._updateCharCount();
-		});
-				
-		jQuery('#post-panel-irt-dismiss').bind(Mojo.Event.tap, function(e) {
-			thisA.clearPostIRT();
-		});
-
-
-	},
-	
-	
-	deactivate: function() {
-		Mojo.Event.stopListening($('post-send-button'), Mojo.Event.tap, this.sendPost); 
-				
-		jQuery('#post-panel-textarea').unbind('keyup');
-		jQuery('#post-panel-textarea').unbind('keydown');
-		jQuery('#post-panel-textarea').unbind('blur');
-		jQuery('#post-panel-textarea').unbind('focus');
-		
-		jQuery('#post-panel-irt-dismiss').unbind(Mojo.Event.tap);
-		
-		jQuery().unbind('update_succeeded');
-		jQuery().unbind('update_failed');
-		
-	},
-	
-	
-	
-	
-	/**
-	 * @private 
-	 */
-	_updateCharCount: function() {
-		var thisA = this;
-		
-		if (thisA._updateCharCountTimeout) {
-			clearTimeout(thisA._updateCharCountTimeout);
-		}
-
-		function _updateCharCountNow() {
-			var numchars  = document.getElementById('post-panel-textarea').value.length;
-			var charcount = 140 - numchars;
-			document.getElementById('post-panel-counter-number').innerHTML = charcount.toString();
-			if (charcount &lt; 0) {
-				jQuery('#post-panel-counter', thisA.controller.getSceneScroller()).addClass('over-limit');
-				/*
-					disable post send button
-				*/
-				jQuery('#post-send-button', thisA.controller.getSceneScroller()).attr('disabled', 'disabled');
-			} else {
-				jQuery('#post-panel-counter', thisA.controller.getSceneScroller()).removeClass('over-limit');
-				/*
-					enable post send button
-				*/
-				jQuery('#post-send-button', thisA.controller.getSceneScroller()).attr('disabled', '');
-			}	
-		};
-		
-		this._updateCharCountTimeout = setTimeout(_updateCharCountNow, 500);
-		
-		
-	},
-	
-	
-	
-	clearPostPanel: function() {
-		this.clearPostIRT();
-		jQuery('#post-panel-textarea', this.controller.getSceneScroller()).val('');
-		this._updateCharCount();
-	},
-
-
-	clearPostIRT: function() {
-		jQuery('#post-panel-irt', this.controller.getSceneScroller()).slideUp('fast');
-		jQuery('#post-panel-irt-message').html('').attr('data-status-id', '0');
-	},
-
-
-	/**
-	 *  
-	 */
-	sendPost: function(event) {
-		var status = jQuery('#post-panel-textarea').val();
-
-		if (status.length &gt; 0) {
-			
-			var in_reply_to = parseInt(jQuery('#post-panel-irt-message', this.controller.getSceneScroller()).attr('data-status-id'), 10);
-			
-			if (in_reply_to &gt; 0) {
-				this.sceneAssistant.twit.update(status, null, in_reply_to);
-			} else {
-				this.sceneAssistant.twit.update(status, null, null);
-			}
-			
-		}
-	},
-	
-	
-
-	/**
-	 *  
-	 */
-	renderSuccessfulPost: function(event, data) {
-		if (sch.isArray(data)) {
-			data = data[0];
-		}
-
-		data.text = Spaz.makeItemsClickable(data.text);
-		
-		/*
-			save this tweet to Depot
-		*/
-		sc.app.Tweets.save(data);
-		
-		dump(data);
-
-		var itemhtml = sc.app.tpl.parseTemplate('tweet', data);
-		
-
-
-		/*
-			prepend the rendered markup to the timeline, so it shows on top
-		*/
-		if (jQuery('#my-timeline').length == 1) {
-			jQuery('#my-timeline').prepend(itemhtml);
-		}
-			
-		
-
-
-		/*
-			remove extra items
-		*/
-		// sch.removeExtraElements('#my-timeline div.timeline-entry', sc.app.prefs.get('timeline-maxentries'));
-		
-		sch.removeExtraElements('#my-timeline div.timeline-entry:not(.reply):not(.dm)', sc.app.prefs.get('timeline-maxentries'));
-		sch.removeExtraElements('#my-timeline div.timeline-entry.reply', sc.app.prefs.get('timeline-maxentries-reply'));
-		sch.removeExtraElements('#my-timeline div.timeline-entry.dm', sc.app.prefs.get('timeline-maxentries-dm'));
-		
-
-		/*
-			Update relative dates
-		*/
-		sch.updateRelativeTimes('div.timeline-entry .meta&gt;.date', 'data-created_at');
-		
-		/*
-			re-apply filtering
-		*/
-		this.sceneAssistant.filterTimeline();
-
-		this.sceneAssistant.playAudioCue('send');
-		
-		this.deactivateSpinner();
-		
-				
-		this.hidePostPanel(event);
-		// this.clearPostPanel(event);
-
-	},
-	
-	
-	/**
-	 *  
-	 */
-	reportFailedPost: function(error_obj) {
-		this.deactivateSpinner();
-
-		var err_msg = $L(&quot;There was a problem posting your status&quot;);
-		this.sceneAssistant.displayErrorInfo(err_msg, error_obj);
-		this.hidePostPanel(event);
-	},
-	
-	hidePostPanel: function() {
-		this.widget.mojo.close();
-	},
-	
-	deactivateSpinner: function() {
-		this.buttonWidget = this.controller.get('post-send-button');
-		this.buttonWidget.mojo.deactivate();
-	}
-	
-	
-	
-});
-
-
-
-
-
-
 /*
 	Small controller class used for the update location account dialog
 */</diff>
      <filename>app/helpers/scene.js</filename>
    </modified>
    <modified>
      <diff>@@ -75,7 +75,7 @@
 
 
 
-&lt;div class=&quot;palm-group palm-group-spaz&quot;&gt;
+&lt;!-- &lt;div class=&quot;palm-group palm-group-spaz&quot;&gt;
 	&lt;div class=&quot;palm-group-title&quot; id=&quot;search-toggle&quot; x-mojo-loc=''&gt;Other options&lt;/div&gt;
 	&lt;div class=&quot;palm-list&quot;&gt;
 		&lt;div class=&quot;palm-row single&quot;&gt;
@@ -93,7 +93,7 @@
 		
       
 	&lt;/div&gt;
-&lt;/div&gt;
+&lt;/div&gt; --&gt;
 
 
 </diff>
      <filename>app/views/preferences/preferences-scene.html</filename>
    </modified>
    <modified>
      <diff>@@ -22,6 +22,8 @@
 
 &lt;div id=&quot;search-spinner-container&quot;&gt;&lt;/div&gt;
 
-&lt;div id=&quot;search-timeline&quot; class=&quot;timeline&quot;&gt;&lt;/div&gt;
+&lt;!-- &lt;div id=&quot;search-timeline&quot; class=&quot;timeline&quot;&gt;&lt;/div&gt; --&gt;
+
+&lt;div id=&quot;search-timeline&quot; name=&quot;search-timeline&quot; x-mojo-element='List'&gt;&lt;/div&gt;
 
 &lt;/div&gt;
\ No newline at end of file</diff>
      <filename>app/views/search-twitter/search-twitter-scene.html</filename>
    </modified>
    <modified>
      <diff>@@ -23,7 +23,7 @@ sc.app.tpl.addTemplateMethod('message-detail', function(d) {
 	+ '		'+thumbHTML
 	+ '		&lt;div class=&quot;text&quot;&gt;'+d.text+'&lt;/div&gt;'
 	+ '		&lt;div class=&quot;meta&quot; data-status-id=&quot;'+d.id+'&quot;&gt;'
-	+ '			&lt;div class=&quot;date&quot;&gt;&lt;strong&gt;Posted&lt;/strong&gt; &lt;span class=&quot;date-relative&quot; data-created_at=&quot;'+d.created_at+'&quot;&gt;'+d.relative_time+'&lt;/span&gt; &lt;strong&gt;from&lt;/strong&gt; &lt;span class=&quot;source-link&quot;&gt;'+d.source+'&lt;/span&gt;&lt;/div&gt;';
+	+ '			&lt;div class=&quot;date&quot;&gt;&lt;strong&gt;Posted&lt;/strong&gt; &lt;span class=&quot;date-relative&quot; data-created_at=&quot;'+d.created_at+'&quot;&gt;'+sch.getRelativeTime(d.created_at)+'&lt;/span&gt; &lt;strong&gt;from&lt;/strong&gt; &lt;span class=&quot;source-link&quot;&gt;'+d.source+'&lt;/span&gt;&lt;/div&gt;';
 	if (d.in_reply_to_status_id) {
 		html += '			&lt;div class=&quot;in-reply-to&quot;&gt;&lt;strong&gt;In-reply-to&lt;/strong&gt;: &lt;span class=&quot;in-reply-to-link clickable&quot; data-irt-status-id=&quot;'+d.in_reply_to_status_id+'&quot;&gt;@'+d.in_reply_to_screen_name+'&lt;/span&gt;&lt;/div&gt;';
 	}
@@ -69,12 +69,12 @@ sc.app.tpl.addTemplateMethod('message-detail-dm', function(d) {
 	var html = '';
 	
 	html += '&lt;div data-user-screen_name=&quot;'+d.sender.screen_name+'&quot; data-user-id=&quot;'+d.sender.id+'&quot; data-status-id=&quot;'+d.id+'&quot; data-isdm=&quot;true&quot;&gt;'
-	+ ' &lt;div class=&quot;rounded-user-image&quot; style=&quot;background-image:url('+d.user.sender+')&quot; id=&quot;message-detail-image&quot; data-screen_name=&quot;'+d.sender.screen_name+'&quot; title=&quot;View user\'s profile&quot;&gt;&lt;/div&gt;'
+	+ ' &lt;div class=&quot;rounded-user-image&quot; style=&quot;background-image:url('+d.sender.profile_image_url+')&quot; id=&quot;message-detail-image&quot; data-screen_name=&quot;'+d.sender.screen_name+'&quot; title=&quot;View user\'s profile&quot;&gt;&lt;/div&gt;'
 	+ '	&lt;div class=&quot;status&quot;&gt;'
 	+ '		&lt;div class=&quot;screen_name&quot; data-screen_name=&quot;'+d.sender.screen_name+'&quot;&gt;'+d.sender.screen_name+'&lt;/div&gt;'
 	+ '		&lt;div class=&quot;text&quot;&gt;'+d.text+'&lt;/div&gt;'
 	+ '		&lt;div class=&quot;meta&quot; data-status-id=&quot;'+d.id+'&quot;&gt;'
-	+ '			&lt;div class=&quot;date&quot;&gt;&lt;strong&gt;Direct message sent&lt;/strong&gt; &lt;span class=&quot;date-relative&quot; data-created_at=&quot;'+d.created_at+'&quot;&gt;'+d.relative_time+'&lt;/span&gt;&lt;/div&gt;'
+	+ '			&lt;div class=&quot;date&quot;&gt;&lt;strong&gt;Direct message sent&lt;/strong&gt; &lt;span class=&quot;date-relative&quot; data-created_at=&quot;'+d.created_at+'&quot;&gt;'+sch.getRelativeTime(d.created_at)+'&lt;/span&gt;&lt;/div&gt;'
 	+ '		&lt;/div&gt;'
 	+ '	&lt;/div&gt;';
 	if (sc.app.username &amp;&amp; sc.app.password) {
@@ -219,7 +219,7 @@ sc.app.tpl.addTemplateMethod('tweet', function(d) {
 		html += '			&lt;div class=&quot;protected-icon&quot;&gt;&lt;/div&gt;';
 	}
 	html += '			&lt;/div&gt;'
-	+ '			&lt;div class=&quot;meta&quot; data-status-id=&quot;'+d.id+'&quot;&gt;&lt;span class=&quot;date&quot; data-created_at=&quot;'+d.created_at+'&quot;&gt;'+d.relative_time+'&lt;/span&gt;&lt;/div&gt;'
+	+ '			&lt;div class=&quot;meta&quot; data-status-id=&quot;'+d.id+'&quot;&gt;&lt;span class=&quot;date&quot; data-created_at=&quot;'+d.created_at+'&quot;&gt;'+sch.getRelativeTime(d.created_at)+'&lt;/span&gt;&lt;/div&gt;'
 	+ '		&lt;/div&gt;'
 	+ '	 	&lt;div class=&quot;text&quot;&gt;'
 	+ '			'+d.text+''
@@ -244,7 +244,7 @@ sc.app.tpl.addTemplateMethod('dm', function(d) {
 	+ '	&lt;div class=&quot;status&quot;&gt;'
 	+ '		&lt;div class=&quot;meta-wrapper&quot;&gt;'
 	+ '			&lt;div class=&quot;screen-name&quot;&gt;'+d.sender.screen_name+'&lt;/div&gt;'
-	+ '			&lt;div class=&quot;meta&quot; data-status-id=&quot;'+d.id+'&quot;&gt;&lt;span class=&quot;date&quot; data-created_at=&quot;'+d.created_at+'&quot;&gt;'+d.relative_time+'&lt;/span&gt;&lt;/div&gt;'
+	+ '			&lt;div class=&quot;meta&quot; data-status-id=&quot;'+d.id+'&quot;&gt;&lt;span class=&quot;date&quot; data-created_at=&quot;'+d.created_at+'&quot;&gt;'+sch.getRelativeTime(d.created_at)+'&lt;/span&gt;&lt;/div&gt;'
 	+ '		&lt;/div&gt;'
 	+ '	 	&lt;div class=&quot;text&quot;&gt;'
 	+ '			'+d.text+''
@@ -267,7 +267,7 @@ sc.app.tpl.addTemplateMethod('search-item', function(d) {
 	+ '	&lt;div class=&quot;status&quot;&gt;'
 	+ '		&lt;div class=&quot;meta-wrapper&quot;&gt;'
 	+ '			&lt;div class=&quot;screen-name&quot;&gt;'+d.from_user+'&lt;/div&gt;'
-	+ '			&lt;div class=&quot;meta&quot; data-status-id=&quot;'+d.id+'&quot;&gt;&lt;span class=&quot;date&quot; data-created_at=&quot;'+d.created_at+'&quot;&gt;'+d.relative_time+'&lt;/span&gt;&lt;/div&gt;'
+	+ '			&lt;div class=&quot;meta&quot; data-status-id=&quot;'+d.id+'&quot;&gt;&lt;span class=&quot;date&quot; data-created_at=&quot;'+d.created_at+'&quot;&gt;'+sch.getRelativeTime(d.created_at)+'&lt;/span&gt;&lt;/div&gt;'
 	+ '		&lt;/div&gt;'
 	+ '	 	&lt;div class=&quot;text&quot;&gt;'
 	+ '			'+d.text+''</diff>
      <filename>app/views/templates.js</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,6 @@
 {
 	&quot;title&quot;: &quot;Spaz&quot;,
-	&quot;version&quot;: &quot;0.5.10&quot;,
+	&quot;version&quot;: &quot;0.5.11&quot;,
 	&quot;type&quot;: &quot;web&quot;,
 	&quot;main&quot;: &quot;index.html&quot;,
 	&quot;id&quot;: &quot;com.funkatron.app.spaz&quot;,</diff>
      <filename>appinfo.json</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,5 @@
 {
-&quot;logLevel&quot;: 99,
+&quot;logLevel&quot;: 0,
 &quot;timingEnabled&quot;: false,
 &quot;useNativeJSONParser&quot;:false,
 &quot;debuggingEnabled&quot;:false,</diff>
      <filename>framework_config.json</filename>
    </modified>
    <modified>
      <diff>@@ -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
@@ -8968,8 +8968,12 @@ 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) {};</diff>
      <filename>spazcore/spazcore-webos.js</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>8184c3ca9b23f7e673b068bf887bb396c669982f</id>
    </parent>
  </parents>
  <author>
    <name>Ed Finkler</name>
    <email>funkatron@gmail.com</email>
  </author>
  <url>http://github.com/funkatron/spaz-webos/commit/885c0a9af95ffac03f9280d84b4cdbc618fd2ae8</url>
  <id>885c0a9af95ffac03f9280d84b4cdbc618fd2ae8</id>
  <committed-date>2009-10-27T06:39:17-07:00</committed-date>
  <authored-date>2009-10-27T06:39:17-07:00</authored-date>
  <message>- v 0.5.11
- modified error message when DM can't be pulled from cache
- No audio cues played, anywhere
- UI prefs for audio and vibration removed
- main timeline cache now saved on every refresh, not just on deactivate of scene
- removed some comment cruft
- search timeline now clears if new query does not match last query
- fixed bug in obj ref in message-detail-dm template
- get_relative_time now applied on render of template in addition to after timeline built
- new spazcore
- fixed bug where update_success would fire twice because we were adding to two timelines (_HOME and no-longer-used _FRIENDS)</message>
  <tree>abae0ed3ccbc368d0ee9ccd28e16870bd839874c</tree>
  <committer>
    <name>Ed Finkler</name>
    <email>funkatron@gmail.com</email>
  </committer>
</commit>
