Date.implement({timeDiffInWords:function(a){return Date.distanceOfTimeInWords(this,a||new Date)},timeDiff:function(g,b){if(g==null){g=new Date}var f=((g-this)/1000).toInt();if(!f){return"0s"}var a={s:60,m:60,h:24,d:365,y:0};var e,d=[];for(var c in a){if(!f){break}if((e=a[c])){d.unshift((f%e)+c);f=(f/e).toInt()}else{d.unshift(f+c)}}return d.join(b||":")}});Date.alias("timeDiffInWords","timeAgoInWords");Date.extend({distanceOfTimeInWords:function(b,a){return Date.getTimePhrase(((a-b)/1000).toInt())},getTimePhrase:function(f){var d=(f<0)?"Until":"Ago";if(f<0){f*=-1}var b={minute:60,hour:60,day:24,week:7,month:52/12,year:12,eon:Infinity};var e="lessThanMinute";for(var c in b){var a=b[c];if(f<1.5*a){if(f>0.75*a){e=c}break}f/=a;e=c+"s"}return Date.getMsg(e+d,f).substitute({delta:f.round()})}});Date.defineParsers({re:/^(?:tod|tom|yes)/i,handler:function(a){var b=new Date().clearTime();switch(a[0]){case"tom":return b.increment();case"yes":return b.decrement();default:return b}}},{re:/^(next|last) ([a-z]+)$/i,handler:function(e){var f=new Date().clearTime();var b=f.getDay();var c=Date.parseDay(e[2],true);var a=c-b;if(c<=b){a+=7}if(e[1]=="last"){a-=7}return f.set("date",f.getDate()+a)}});