/* * DEK JavaScript Library * Copyright(c) 2008-2010, DEK International * * Version 1.0.12 *//* ############################## Core ############################## *//** * A utitlities class giving access to core functions. * @class Core * @singleton */Core = {	/**	 * Copies all the properties from source to destination.	 * @method copy	 * @static	 * @param Object desination The object where properties are copied to.	 * @param Object source The object with the properties to be copied.  You can specify more than one source that are copied in order left to right.	 * @params Object destination, Object source[, Object additionalSource[, ...]]	 * @return Object destination	 */	copy: function(destination, source) {		if(destination && source) {			for(var property in source) {				destination[property] = source[property];			}		}		if(arguments.length > 2) {			var args = Array.prototype.slice.call(arguments);					args.splice(1,1);			Core.copy.apply(Core, args);		}		return destination;	},	/**	 * Copies all the properties from source to destination but only if they are new to the destination.	 * @method copyNew	 * @static	 * @param Object desination The object where properties are copied to.	 * @param Object source The object with the properties to be copied.  You can specify more than one source that are copied in order left to right.	 * @params Object destination, Object source[, Object additionalSource[, ...]]	 * @return Object destination	 */	copyNew: function(destination, source) {		if(destination && source) {			for(var property in source) {				if(!destination[property]) {					destination[property] = source[property];				}			}		}		if(arguments.length > 2) {			var args = Array.prototype.slice.call(arguments);					args.splice(1,1);			Core.copyNew.apply(Core, args);		}		return destination;	},	/**	 * Creates a class and performs basic inheritance.	 * @method create	 * @static	 * @todo exand description, look at old core.js class for an example	 * @param {Function} parent (Optional) The parent constructor from which to inherit from.	 * @param Object definition A literal with the properties that define the new class.	 * @return {Function} The new classes constructor	 */	/* inspired by Alex Arnell's inheritance implementation (http://www.twologic.com/projects/inheritance/) */	create: function(parent, definition) {		// deal with optional parent parameter		if(!definition) {			definition = parent; 			parent = null;		}				// create constructor		var newClass = function() {			this.init.apply(this, arguments);		}		// inherit from parent				if(parent) {			Core.copy(newClass.prototype, parent.prototype);		}		// add other properties		if(definition) {			Core.copy(newClass.prototype, definition);		}		// check for an init method		if(!newClass.prototype.init) {			newClass.prototype.init = function() { };		}		// set the constructor and return		newClass.prototype.constructor = newClass;				return newClass;	},	/** 	 * A simple function which always returns false.  This is can be usefull when dealing with events if you want to stop the default action.	 * @method returnFalse	 * @static	 * @return Boolean false	 */	returnFalse : function() {		return false;	}, 	/**	 * Creates a cookie.	 * @method createCookie	 * @static	 * @param {String} name The name of the cookie.	 * @param {String} value The value of the cookie.	 * @param {Number} hours (Optional) The number of hours before this cookie should expire, if not specified the cookie will expire when the browser is closed.  Specifing zero will set the cookie to expire in 100 years.	 * @param {String} path (Optional) The path this cookie should belong to.  Normally this would the same as the application createing the cookie.  Defaults to "/".	 */	createCookie: function(name, value, hours, path) {		var expires = "";		if (hours) {			var date = new Date();			if(hours==0) {				date.setFullYear(date.getFullYear()+100);			} else {				date.setTime(date.getTime()+(hours*60*60*1000));			}			expires = "; expires="+date.toGMTString();		}		path = path ? path : "/";					document.cookie = name+"="+escape(value)+expires+"; path="+path;	},	/**	 * Attemepts to read a cookie.	 * @method readCookie	 * @static	 * @param {String} name The name of the cookie to read.	 * @return {String} The value of the cookie if found, null if it could not be found.	 */	readCookie: function(name) {		var cookies = document.cookie.split(';');		for(var index=0; index<cookies.length; index++) {			var cookie = cookies[index].trim();			if(cookie.indexOf(name+"=") == 0) {				return unescape(cookie.substring(name.length+1));			}		}		return null;	},	/**	 * Erases a cookie by setting the expiry date 1 hour in the past.	 * @method eraseCookie	 * @static	 * @param {String} name The name of the cookie.	 * @param {String} path (Optional) The path this cookie should belong to. Defaults to "/".	 */	eraseCookie: function(name, path) {		Core.createCookie(name,"",-1, path);	},	/**	 * Encodes a string in to UTF-8.	 * @method encode	 * @static	 * @param {String} text The text to encode.	 * @return {String} The encoded version of <code>text</code>.	 */	encode : function (string) {		/*string = string.replace(/\r\n/g,"\n");		var utftext = ""; 		for (var n = 0; n < string.length; n++) {			var c = string.charCodeAt(n); 			if (c < 128) {				utftext += String.fromCharCode(c);			} else if((c > 127) && (c < 2048)) {				utftext += String.fromCharCode((c >> 6) | 192);				utftext += String.fromCharCode((c & 63) | 128);			} else {				utftext += String.fromCharCode((c >> 12) | 224);				utftext += String.fromCharCode(((c >> 6) & 63) | 128);				utftext += String.fromCharCode((c & 63) | 128);			} 		} 		return escape(utftext);*/		return encodeURIComponent(string).replace(/%20/g, '+');	}, 	/**	 * Decodes a string from UTF-8.	 * @method decode	 * @static	 * @param {String} utf_text The text to decode.	 * @return {String} The decoded version of <code>utf_text</code>.	 */	decode : function (utftext) {		utftext = unescape(utftext);		var string = "";		var i = 0;		var c = c1 = c2 = 0; 		while ( i < utftext.length ) { 			c = utftext.charCodeAt(i); 						if (c < 128) {				string += String.fromCharCode(c);				i++;			} else if((c > 191) && (c < 224)) {				c2 = utftext.charCodeAt(i+1);				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));				i += 2;			} else {				c2 = utftext.charCodeAt(i+1);				c3 = utftext.charCodeAt(i+2);				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));				i += 3;			} 		} 		return string;	},	/**	 * Converts the following special characters:<table cellspaceing="0" cellpadding="0"><tr><th>From</th><th>To</th></tr><tr><td>&amp;</td><td>&amp;amp;</td></tr><tr><td>&quot;</td><td>&amp;quot;</td></tr><tr><td>&lt;</td><td>&amp;lt;</td></tr><tr><td>&gt;</td><td>&amp;gt;</td></tr></table>	 * @method htmlSpecialChars	 * @param {String} text The text to be converted	 * @param Boolean brTags (Optional) When true, carrage returns are converted in to <br/> tags.  Defatuls to false.	 * @return {String} The converted text.	 */	htmlSpecialChars: function (text, br) {		text = text.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");		if(br) {			text = text.replace(/\n/g, "<br/>");		}		return text;	},	/**	 * Returns a unique reference for use on this page.  It uses a simple counter that is reset every time the page loads.	 * @method unique	 * @static	 * @return {String} A string in the format "REF00000"	 */	uniqueCounter: 10000,	unique: function() {		Core.uniqueCounter++;		return "REF"+Core.uniqueCounter;	},	/*	 * Creates and returns a text represntaion of the Core class.	 * @method toString	 	 * @static	 * @return {String}	 */	toString : function() {		return "[Core]";	}};(function() {	ua = navigator.userAgent.toLowerCase();		/**	 * Set to true when the browser is in strict mode.	 * @property isStrict	 * @type Boolean	 * @static	 */	Core.isStrict = document.compatMode == "CSS1Compat";	/**	 * Set to true when the browser is Opera	 * @property isOpera	 * @type Boolean	 * @static	 */	Core.isOpera = /opera/.test(ua);	/**	 * Set to true when the browser is Chrome	 * @property isChrome	 * @type Boolean	 * @static	 */	Core.isChrome = /chrome/.test(ua);	Core.isWebKit = /webkit/.test(ua);	/**	 * Set to true when the browser is Safari	 * @property isSafari	 * @type Boolean	 * @static	 */	Core.isSafari = !Core.isChrome && /safari/.test(ua);	/**	 * Set to true when the browser is Safari version 2	 * @property isSafari2	 * @type Boolean	 * @static	 */	Core.isSafari2 = Core.isSafari && /applewebkit\/4/.test(ua);	/**	 * Set to true when the browser is Safari version 3	 * @property isSafari3	 * @type Boolean	 * @static	 */	Core.isSafari3 = Core.isSafari && /version\/3/.test(ua);	/**	 * Set to true when the browser is Safari version 4	 * @property isSafari4	 * @type Boolean	 * @static	 */	Core.isSafari4 = Core.isSafari && /version\/4/.test(ua);	/**	 * Set to true when the browser is Internet Explorer	 * @property isIE	 * @type Boolean	 * @static	 */	Core.isIE = !Core.isOpera && /msie/.test(ua);	/**	 * Set to true when the browser is Internet Explorer version 6	 * @property isIE6	 * @type Boolean	 * @static	 */	Core.isIE6 = Core.isIE && /msie 6/.test(ua);	/**	 * Set to true when the browser is Internet Explorer version 7	 * @property isIE7	 * @type Boolean	 * @static	 */	Core.isIE7 = Core.isIE && /msie 7/.test(ua);	/**	 * Set to true when the browser is Internet Explorer verision 8	 * @property isIE8	 * @type Boolean	 * @static	 */	Core.isIE8 = Core.isIE && /msie 8/.test(ua);	/**	 * Set to true when the browser is using the gecko engine (Firefox)	 * @property isGecko	 * @type Boolean	 * @static	 */	Core.isGecko = !Core.isWebKit && /gecko/.test(ua);	/**	 * Set to true when the browser is using the gecko engine version 1.8 (Firefox 2)	 * @property isGecko2	 * @type Boolean	 * @static	 */	Core.isGecko2 = Core.isGecko && /rv:1\.8/.test(ua);	/**	 * Set to true when the browser is using the gecko engine version 1.9 (Firefox 3)	 * @property isGecko3	 * @type Boolean	 * @static	 */	Core.isGecko3 = Core.isGecko && /rv:1\.9/.test(ua);		Core.isBorderBox = Core.isIE && !Core.isStrict;	Core.isWindows = /windows|win32/.test(ua);	Core.isMac = /macintosh|mac os x/.test(ua);	Core.isAir = /adobeair/.test(ua);	Core.isLinux = /linux/.test(ua);	Core.isSecure = /^https/i.test(window.location.protocol);})();/* ############################## Number ############################## *//** * Number is a built-in JavaScript class which has been augmented with the following additional methods. * @class Number */Core.copyNew(Number.prototype, {	/**	 * Formats a number by adding the specified number of decimal places and comma seperating the number.	 * @method format	 * @param {Number} decimals the number of decimal places to show.	 * @return {String} The formated number	 */	format: function(decimals) {		var numberString = ""+this.toFixed(decimals);		var numberParts = numberString.split('.');		var integerString = numberParts[0];		var decimalString = numberParts.length > 1 ? '.' + numberParts[1] : '';			var regex = /(\d+)(\d{3})/;		while (regex.test(integerString)) {			integerString = integerString.replace(regex, '$1' + ',' + '$2');		}		return integerString + decimalString;	}});/* ############################## String ############################## *//** * String is a built-in JavaScript class which has been augmented with the following additional methods. * @class String */Core.copyNew(String.prototype, {	/**	 * Removes leading and trailing white space from a string	 * @method trim	 * @return {String} The trimed string	 */	trim : function() {		return this.replace(/^\s{1,}/, "").replace(/\s{1,}$/, "");	},	/**	 * Check to see if this string starts with particular sequence of characters.	 * @method startsWith	 * @param {String} str The sequence of characters to look for.	 * @return Boolean True if the string starts with <code>str</code>, false if not.	 */	startsWith : function(str) {		return this.substr(0, str.length)==str;	},	/**	 * Check to see if this string ends with particular sequence of characters.	 * @method endsWith	 * @param {String} str The sequence of characters to look for.	 * @return Boolean True if the string ends with <code>str</code>, false if not.	 */	endsWith : function(str) {		return this.substr(this.length-str.length)==str;	},	/**	 * Tries to convert this string into a date.	 * @method parseDate	 * @param {String} formatString (Optional) A string specifiy how the date is formated, see the format date command for a list of option.  When unspecifed, javascript is left to it's own devises to try and parse the date.	 * @return {Date} The new date object or null if the date was invalid.	 * @see Date	 */	parseDate : function(formatString) {		if(!formatString) {			// try common formats first			var formats = [				"d/m/yyyy", "d/m/yy", "yyyy/m/d", "yy/m/d",				"d.m.yyyy", "d.m.yy", "yyyy.m.d", "yy.m.d",				"d,m,yyyy", "d,m,yy", "yyyy,m,d", "yy,m,d",				"d-m-yyyy", "d-m-yy", "yyyy-m-d", "yy-m-d",				"d:m:yyyy", "d:m:yy", "yyyy:m:d", "yy:m:d",				"d m yyyy", "d m yy", "yyyy m d", "yy m d",				"yyyymmdd"			];						var date = null;			for(var i=0; i<formats.length && date==null; i++) {				date = this.parseDate(formats[i]);			}												// let javascript have a shot			if(date==null) {				date = new Date(this.toString());						if(date.toString()=="NaN" || date.toString()=="Invalid Date") {					return null;				} else {					return date;				}			} else {				return date;			}		} else {			var date = new Date();			var year = 1970;			var month = 1;			var day = 1;			var hours = 0;			var minutes = 0;			var seconds = 0;						var dateString = new String(this);			for(var index=0; index<formatString.length; index++) {	 			switch(formatString.charAt(index)) {				case "y":					if(formatString.substr(index, 4)=="yyyy") {						var test = parseInt(dateString.substr(0, 4), 10);						if(isNaN(test)) {							return null;						}						year = test;						if(year<70) {							year+=2000;						} else if(year<100) {							year+=1900;						}						dateString = dateString.substr(4);						index+=3;					} else if(formatString.substr(index, 2)=="yy") {						var test = parseInt(dateString.substr(0, 2), 10);						if(isNaN(test)) {							return null;						}						year = test;						if(year<70) {							year+=2000;						} else if(year<100) {							year+=1900;						}						dateString = dateString.substr(2);						index++;					}					break;				case "m":					if(formatString.substr(index, 4)=="mmmm") {						switch(dateString.substr(0, 3).toLowerCase()) {							case "jan": 								month=1;								dateString = dateString.substr(7);								break;							case "feb": 								month=2;								dateString = dateString.substr(8);								break;							case "mar": 								month=3;								dateString = dateString.substr(5);								break;							case "apr": 								month=4;								dateString = dateString.substr(5);								break;							case "may": 								month=5;								dateString = dateString.substr(3);								break;							case "jun": 								month=6;								dateString = dateString.substr(4);								break;							case "jul": 								month=7;								dateString = dateString.substr(4);								break;							case "aug": 								month=8;								dateString = dateString.substr(6);								break;							case "sep": 								month=9;								dateString = dateString.substr(9);								break;							case "oct": 								month=10;								dateString = dateString.substr(7);								break;							case "nov": 								month=11;								dateString = dateString.substr(8);								break;							case "dec": 								month=12;								dateString = dateString.substr(8);								break;							default :								return null;						}										index+=3;					} else if(formatString.substr(index, 3)=="mmm") {						switch(dateString.substr(0, 3).toLowerCase()) {							case "jan": 								month=1;								break;							case "feb": 								month=2;								break;							case "mar": 								month=3;								break;							case "apr": 								month=4;								break;							case "may": 								month=5;								break;							case "jun": 								month=6;								break;							case "jul": 								month=7;								break;							case "aug": 								month=8;								break;							case "sep": 								month=9;								break;							case "oct": 								month=10;								break;							case "nov": 								month=11;								break;							case "dec": 								month=12;								break;							default :								return null;								}						dateString = dateString.substr(3);										index+=2;					} else {						var test = parseInt(dateString.substr(0, 2), 10);						if(isNaN(test) || test>12 || test<1) {							return null;						}						month = test;						if(formatString.substr(index, 2)=="mm" || test>=10 || dateString.substr(0, 1)=="0") {							dateString = dateString.substr(1);							}						if(formatString.substr(index, 2)=="mm") {							index++;						}						dateString = dateString.substr(1);											}					break;				case "d":					var test = parseInt(dateString.substr(0, 2), 10);					if(isNaN(test) || test>31 || test<1) {						return null;					}					day = test;					if(formatString.substr(index, 2)=="dd" || test>=10 || dateString.substr(0, 1)=="0") {						dateString = dateString.substr(1);						}					if(formatString.substr(index, 2)=="dd") {						index++;					}					dateString = dateString.substr(1);						break;				case "S":					dateString = dateString.substr(2);						break;				case "a":				case "A":					if(dateString.substr(0, 2).toLowerCase()=="pm") {						hours += 12;					}					dateString = dateString.substr(2);						break;				case "h":					var test = parseInt(dateString.substr(0, 2), 10);					if(isNaN(test)) {						return null;					}					hours += test;					if(formatString.substr(index, 2)=="hh" || test>=10) {						dateString = dateString.substr(1);						}					if(formatString.substr(index, 2)=="hh") {						index++;					}					dateString = dateString.substr(1);						break;				case "H":					var test = parseInt(dateString.substr(0, 2), 10);					if(isNaN(test)) {						return null;					}					hours = test;					if(formatString.substr(index, 2)=="HH" || test>=10) {						dateString = dateString.substr(1);						}					if(formatString.substr(index, 2)=="HH") {						index++;					}					dateString = dateString.substr(1);						break;				case "n":					var test = parseInt(dateString.substr(0, 2), 10);					if(isNaN(test)) {						return null;					}					minutes = test;					if(formatString.substr(index, 2)=="nn" || test>=10) {						dateString = dateString.substr(1);						}					if(formatString.substr(index, 2)=="nn") {						index++;					}					dateString = dateString.substr(1);						break;				case "s":					var test = parseInt(dateString.substr(0, 2), 10);					if(isNaN(test)) {						return null;					}					seconds = test;					if(formatString.substr(index, 2)=="ss" || test>=10) {						dateString = dateString.substr(1);						}					if(formatString.substr(index, 2)=="ss") {						index++;					}					dateString = dateString.substr(1);						break;				case dateString.substr(0, 1) :					dateString = dateString.substr(1);						break;				default :					return null;				} 			}						date.setFullYear(year, month-1, day);			date.setHours(hours, minutes, seconds);			return date;		}	}});/* ############################## Array ############################## *//** * Array is a built-in JavaScript class which has been augmented with the following additional methods. * @class Array */Core.copyNew(Array.prototype, {	/**	 * Searches this array for an element and returns it's location.	 * @method indexOf	 * @param Mixed element	 * @return {Number} The index of object in the array, if the element is not found returns -1.	 */	indexOf : function(element) {		for(var i=0; i<this.length; i++){			if(this[i]==element){				return i;			}		}		return -1;	},	/**	 * Adds an element to the end of an array if it not currently a member.	 * @method pushUnique	 * @param Mixed element the emlement to delete.	 */	pushUnique : function(element) {		if(this.indexOf(element)<0) {			this.push(element);		}	},	/**	 * Deletes an item from an array, if it can be found.	 * @method deleteElement	 * @param Mixed element the emlement to delete.	 */	deleteElement : function(element) {		if(this.indexOf(element)>=0) {			this.splice(this.indexOf(element), 1);		}	},	/**	 * Removes empty elements from the array.	 * @method trim	 */	trim : function() {		for(var i=0; i<this.length;){			if(typeof(this[i])=="undefined" || this[i]==null || this[i].toString()==""){				this.splice(i, 1);			} else {				i++;			}		}	}});/* ############################## Date ############################## *//** * Date is a built-in JavaScript class which has been augmented with the following additional methods. * @class Date */Core.copyNew(Date, {	/**	 * Return the number of days in this days in the specified month and year	 * @method getDaysInMonth	 * @static	 * @param {Number} month The month (0-11).	 * @param Number} year (Optional) The year, needed for leep years.  When unspecified February will return 28.	 * @return {Number} The number of days in the month.	 */	getDaysInMonth: function(month, year) {		switch(month+1) {			case 1:			case 3:			case 5:			case 7:			case 8:			case 10:			case 12:				return 31;				break;			case 4: 			case 6: 			case 9: 			case 11:				return 30;				break;						case 2:				if(isNaN(year)) {					return 28;				} else {					if(year % 4!=0) {						return 28;					} else {						if(year % 100==0 && year % 400!=0) {							return 28;						} else {							return 29;						}					}				}				break;							}		}});Core.copyNew(Date.prototype, {	/**	 * Retruns as text representation of a date formated as specified in the format string.  This is based	 * loosley on the date/time part of format function in lotus script.  It has much more potential but for	 * now supports the following formating<pre>Format  Description                                           Returned Values------  ----------------------------------------------------  ----------------yy      The last two digits of the year                       00 to 99yyyy    The full (four-digit) year                            0000 to 9999m       Numeric value for the month without a leading zero    1 to 12mm      Numeric value for the month with a leading zero       01 to 12mmm     Month name as a 3-letter abbreviation                 Jan to Decmmmm    Full month name                                       January to Decemberd       Day of the month without a leading zero               1 to 31dd      Day of the month with a leading zero                  01 to 31S       English ordinal suffix for the day of the month       st, nd, rd or tha       Lowercase Ante meridiem and Post meridiem             am or pmA       Uppercase Ante meridiem and Post meridiem             AM or PMh       12-hour format of an Hour without a leading zero      1 to 12hh      12-hour format of an with a leading zero              01 to 12H       24-hour format of an Hour without a leading zero      0 to 23HH      24-hour format of an with a leading zero              00 to 23n       Minutes without a leading zero                        0 to 59nn      Minutes with a leading zero                           00 to 59s       Seconds without a leading zero                        0 to 59ss      Seconds with a leading zero                           00 to 59</pre>	 	 * All other characters are simply passed to the output text.	 * @method format	 * @todo expand formating options	 * @param {String} formatString A string specifiy how to format the date	 * @return {String} The formated date	 */	format : function(formatString) {		var rv ="";					for(var index=0; index<formatString.length; index++) {			switch(formatString.charAt(index)) {				case "y":					var year = this.getFullYear();					if(year<70) {						year+=2000;					} else if(year<100) {						year+=1900;					}					if(formatString.substr(index, 4)=="yyyy") {						rv += new String(year);						index+=3;					} else if(formatString.substr(index, 2)=="yy") {						rv += (new String(year)).substr(2, 2);						index++;					}					break;				case "m":					var month = this.getMonth()+1;					if(formatString.substr(index, 4)=="mmmm") {						switch(month) {							case 1: rv += "January"; break;							case 2: rv += "February"; break;							case 3: rv += "March"; break;							case 4: rv += "April"; break;							case 5: rv += "May"; break;							case 6: rv += "June"; break;							case 7: rv += "July"; break;							case 8: rv += "August"; break;							case 9: rv += "September"; break;							case 10: rv += "October"; break;							case 11: rv += "November"; break;							case 12: rv += "December"; break;									}										index+=3;					} else if(formatString.substr(index, 3)=="mmm") {						switch(month) {							case 1: rv += "Jan"; break;							case 2: rv += "Feb"; break;							case 3: rv += "Mar"; break;							case 4: rv += "Apr"; break;							case 5: rv += "May"; break;							case 6: rv += "Jun"; break;							case 7: rv += "Jul"; break;							case 8: rv += "Aug"; break;							case 9: rv += "Sep"; break;							case 10: rv += "Oct"; break;							case 11: rv += "Nov"; break;							case 12: rv += "Dec"; break;												}										index+=2;					} else if(formatString.substr(index, 2)=="mm") {						if(month<10) {							rv += "0";						}						rv += new String(month);						index++;					} else {						rv += new String(month);					}					break;				case "d":					var day = new String(this.getDate());					if(formatString.substr(index, 2)=="dd") {						if(day.length==1) day = "0"+day;						index++;					}					rv+= day;					break;				case "S":					var day = this.getDate();					switch(day) {						case 1:						case 21:						case 31:							rv += "st";							break;						case 2:						case 22:							rv += "nd";							break;						case 3:						case 23:							rv += "rd";							break;						default :							rv+="th";					}					break;				case "a":					if(this.getHours()<12) {						rv += "am";					} else {						rv += "pm";					}					break;				case "A":					if(this.getHours()<12) {						rv += "AM";					} else {						rv += "PM";					}					break;				case "h":					var hour;					if(this.getHours()==0) {						hour = "12";					} else if(this.getHours()>12) {						hour = new String(this.getHours()-12);					} else {						hour = new String(this.getHours());						}										if(formatString.substr(index, 2)=="hh") {						if(hour.length==1) hour = "0"+hour;						index++;					}					rv += hour;					break;				case "H":					var hour = new String(this.getHours());					if(formatString.substr(index, 2)=="HH") {						if(hour.length==1) hour = "0"+hour;						index++;					}					rv += hour;					break;				case "n":					var minute = new String(this.getMinutes());					if(formatString.substr(index, 2)=="nn") {						if(minute.length==1) minute = "0"+minute;						index++;					}					rv += minute;					break;				case "s":					var second = new String(this.getSeconds());					if(formatString.substr(index, 2)=="ss") {						if(second.length==1) second = "0"+second;						index++;					}					rv+= second;					break;				default :					rv+= formatString.charAt(index);			}		}				return rv;	},	/**	 * Adjusts the current date by the specified amount	 * @method adjust	 * @param {Number} years	 * @param {Number} months	 * @param {Number} days	 * @param {Number} hours	 * @param {Number} minuets	 * @param {Number} seconds	 */	adjust: function(years,months,days,hours,minuets,seconds) {		var newMonth = this.getMonth() + months;		var newYear = this.getFullYear() + years + Math.floor(newMonth/12);		if(newMonth < 0) {			var newMonth = 12 + (newMonth%12);		} else {			var newMonth = newMonth%12;		}		this.setFullYear(newYear, newMonth, Math.min(this.getDate(), Date.getDaysInMonth(newMonth, newYear)));				var time = this.getTime();		time += (days * 86400000);		time += (hours * 3600000);		time += (minuets * 60000);		time += (seconds * 1000);		this.setTime(time);	},	/**	 * Return the number of days in this day in this month.	 * @method getDaysInMonth	 * @return {Number} The number of days in this month.	 */	getDaysInMonth: function() {		return Date.getDaysInMonth(this.getMonth(), this.getFullYear());		},	/**	 * Returns a copy of this date set to the same date and time.	 * @method clone	 * @return {Date} The new date object.	 */	clone: function() {		var newDate  = new Date();		newDate.setTime(this.getTime());		return newDate;	}});/* ############################## Function ############################## *//** * Function is a built-in JavaScript class which has been augmented with the following additional methods. * @class Function */Core.copyNew(Function.prototype, {	/**	 * Creates a wrapper function for this function that will run with the specified scope and arguments.  	 * This is very usefull for event handling, when assigning a function as an event handler you can pre-specify what 	 * parameter to pass and ensure the scope will be the current object.	 * @method bind	 * @param Object scope (Optional) The scope of the callback function, if not specified window is used as the scope.	 * @param {Array} args (Optional) An array of arguments to pass this function.	 * @param Boolean override (Optional) Specifies if the normal arguments should be over riden with the arguments in the args array.  The default is false.	 * @param Boolean appendArgs (Optional) If override is false the arguments are appended or prepended to the normal arguments.  When appendArgs is true the arguments in the args array is appended, when false they are prepended.  The default is to append.	 * @return Function The callback function.	 */	bind : function(scope, args, override, appendArgs) {		var method = this;		if(arguments.length==0) {			return method;		}		if(!scope || typeof(scope)!="object" || scope.length) {			appendArgs = override;			override = args;			args = scope;			scope = window;		}		if(!args || typeof(args)!="object" || !args.length) {			args = new Array();		}		if(typeof(override)!="boolean") {			override=false;		}		if(typeof(appendArgs)!="boolean") {			appendArgs=true;		}		return function() {			if(override) {				return method.apply(scope, args);			} else {				var callArgs;				var normalArgs = Array.prototype.slice.call(arguments);				if(appendArgs) {					callArgs = normalArgs.concat(args);				} else {					callArgs = args.concat(normalArgs);				}				return method.apply(scope, callArgs);							}					};	}});/* ############################## Options ############################## *//** * <p>Uses as a base class for options objects.  These are basicly hash maps or assositave arrays and this adds methods of intergating these values.</p> * <h5>Example</h5><p>Options are used by Core.Ui.Table.  In the following example a simple object with the required options are initally set up as <code>tableOptions</code> * The options are then passed to the Core.Ui.Table.</p><pre><code>var tableOptions = {  element: "view",  header: false,  selectMany: true,  checkBoxes: true,  boundColumn: 1});var table = new Core.Ui.Table(tableOptions);</code></pre> * <p>The constructor for Core.Ui.Table then uses Core.copy to add the Core.Options methods to the option object passed, it can then use those methods to check which options have been set</p> <pre><code>init: function(options) {  Core.copyNew(options, Core.Options);  // html element  this.element = Core.get(options.readOption("element", null));  this.title = options.readOption("title", "");  this.tableClass = options.readOption("tableClass", "");  this.header = options.readBooleanOption("header", true);  this.footer = options.readBooleanOption("footer", true);  this.fitContent = options.readBooleanOption("fitContent", false);  ...</code></pre> * @class Core.Options */Core.Options = {	/**	 * This checks to see if the current object has the specified property.	 * @method hasOption	 * @param {String} name The name of the property to return.	 * @return Boolean True if the property was found.	 */	hasOption: function(name, defaultValue) {		return typeof(this[name])!="undefined"	},	/**	 * This checks to see if the current object has the specified property and returns it if avalible.  If it is not avalible the <code>defaultValue</code> is returned.	 * @method readOption	 * @param {String} name The name of the property to return.	 * @param mixed defaultValue (Optional) The value to return if the property is not found, defaults to an empty string.	 * @return mixed The property if it was found, the <code>defaultValue</code> if not.	 */	readOption: function(name, defaultValue) {		if(typeof(this[name])!="undefined") {			return this[name]		} else {			if(typeof(defaultValue)!="undefined") {				return defaultValue;			} else {				return "";			}		}	},	/**	 * This checks to see if the current object has the specified property, if avalible it attempts to convert it to an integer and return that value.  If it is not avalible or can not be converted to an integer the <code>defaultValue</code> is returned.	 * @method readIntOption	 * @param {String} name The name of the property to return.	 * @param {Number} defaultValue (Optional) The value to return if the property is not found, defaults to 0.	 * @return {Number} The property if it was found, the <code>defaultValue</code> if not.	 */	readIntOption: function(name, defaultValue) {		var value = parseInt(this.readOption(name, defaultValue), 10);		if(!isNaN(value)) {			return value;		} else {			if(!isNaN(defaultValue)) {				return defaultValue;					} else {				return 0;			}		}	},	/**	 * This checks to see if the current object has the specified property, if avalible and it is a boolean, the value is returned.  If it is not avalible or it is not a boolean the <code>defaultValue</code> is returned.	 * @method readBooleanOption	 * @param {String} name The name of the property to return.	 * @param Boolean defaultValue (Optional) The value to return if the property is not found, defaults to false.	 * @return Boolean The property if it was found, the <code>defaultValue</code> if not.	 */	readBooleanOption: function(options, name, defaultValue) {		var value = this.readOption(options, name, defaultValue);		if(typeof(value)=="boolean") {			return value;		} else {			if(typeof(defaultValue)=="boolean") {				return defaultValue;			} else {				return false;			}		}	}}/* ############################## Event Manager ############################## *//** * EventManager contains methods for managing events * @class Core.EventManager * @singleton */Core.EventManager = {	/**	 * Bootstaps the specified class so an instance of it is created once the document is ready.  	 * On platforms that support it, this will be when "onDOMContentLoaded" is fired, on all other it will be "onload".	 * @method bootstrap	 * @static	 * @param Class class The class to created when the document is ready.	 */	bootstrap: function(klass) {		if(!this.bootstrapList) {			this.bootstrapList = new Array();			this.loadListener = this.loadListener.bind(this);			Core.EventManager.addListener(document, "DOMContentLoaded", this.loadListener);			Core.EventManager.addListener(window, "load", this.loadListener);		}		this.bootstrapList.push(klass);			},	loadListener: function() {		Core.EventManager.removeListener(document, "DOMContentLoaded", this.loadListener);		Core.EventManager.removeListener(window, "load", this.loadListener);				if(this.bootstrapList) {			for(var index=0; index<this.bootstrapList.length; index++) {				new this.bootstrapList[index]();			}		}	},	/**	 * Calls both preventDefault and stopPropagation for this event	 * @method catchEvent	 * @static	 * @param event event The event object to catch.	 */	catchEvent: function(event) {		this.preventDefault(event);		this.stopPropagation(event);		},	toString : function() {		return "[Core.EventManager]";	}}if (document.addEventListener) { // w3c	Core.copy(Core.EventManager, {		/**		 * Adds a listener to a html element.		 * @method addListener		 * @static		 * @param HTMLElement/{String} target A DOM element or the ID of an element the listener should be added to.		 * @param {String} action The name of the event which will trigger the event, for example "click" for onClick events.		 * @param {Function} listener The function to be called when the event fires.		 */		addListener: function(target, action, listener) {			if(typeof(target)=="string") {				target = document.getElementById(target);			}			if(target != null) {				target.addEventListener(action, listener, false);				}		},		/**		 * <p>Removes a listener from a html element.</p>		 * <p>If a listener is a bound function (created using the Function.bind), you will need to pass this bound function to removeListener for it to be removed.</p>		 * @method removeListener		 * @static		 * @param HTMLElement/{String} target A DOM element or the ID of an element the listener should be removed from.		 * @param {String} action The name of the event which triggers the event, for example "click" for onClick events.		 * @param {Function} listener The function to be removed.		 */		removeListener: function(target, action, listener) {			if(typeof(target)=="string") {				target = document.getElementById(target);			}			if(target != null) {				target.removeEventListener(action, listener, false);				}		},		/**		 * Stops the default action from occuring for this event.		 * @method preventDefault		 * @static		 * @param event event The event object.		 */		preventDefault: function(event) {			event.preventDefault();		},		/**		 * Stops the event from bubbling up the dom tree		 * @method stopPropagation		 * @static		 * @param event event The event object.		 */		stopPropagation: function(event) {			event.stopPropagation();		}	});} else if (document.attachEvent) { // internet explorer	Core.copy(Core.EventManager, {		/* used to track functions */		emid: 0,		/*		 * ie version of add listener		 */		addListener: function(target, action, listener) {			if(!listener.emid) {				listener.emid = "L"+(Core.EventManager.emid++);			}			if(typeof(target)=="string") {				target = document.getElementById(target);			}			if(target != null) {				if (!target.listeners) target.listeners = new Array();				if (!target.listeners[action]) target.listeners[action] = new Array();				if (!target.listeners[action][listener.emid]) {					var wrapperFunction = function(event) {						if(event==null) {							event = window.event;						}							if(event==null) {							listener(null);						} else {							event.target = event.srcElement;							listener(event);						}											}					target.listeners[action][listener.emid] = wrapperFunction;					target.attachEvent('on' + action, wrapperFunction);				}			}		},		/*		 * ie version of remove listener		 */		removeListener: function(target, action, listener) {			if(listener.emid) {				if(typeof(target)=="string") {					target = document.getElementById(target);				}				if(target != null) {					if (target.listeners && target.listeners[action] && target.listeners[action][listener.emid]) {						target.detachEvent('on' + action, target.listeners[action][listener.emid]);						delete target.listeners[action][listener.emid];					}				}			}		},		/*		 * ie version of prevent default		 */		preventDefault: function(event) {			event.returnValue = false;		},		/*		 * ie version of stop propogation		 */		stopPropagation: function(event) {			event.cancelBubble = true;		}	});}/* ############################## Event ############################## *//** * <p>Represents a custom event.  It contains the methods for adding/removing listeners and fireing events.</p> * <h5>Example</h5> * <p>An event would normaly be created by the constructor of a class, for example the Core.Ui.Dialog * creates a close event in it construtor.</p> * <pre><code>this.closeEvent = new Core.Event("Core.Ui.Dialog:close");</code></pre> * <p>The code attached to the buttons in the dialog hides the dialog and fires the event.  In this case the information * in the event include a link back to the dialog and which button was pressed</p><pre><code>closeDialog: function(button) {  this.hide();  this.closeEvent.fire({    dialog: this,     result: button  });},</code></pre> * <p>Other objects can subsribe to the event by calling the events addListener method and passing a reference to a  * call back function which will be called every time the event is fired.</p> * <pre><code>dialog.closeEvent.addListener(this.dialogHasBeenClosed.bind(this));</code></pre> <pre><code>dialogHasBeenClosed: function(event) {  msgbox("The dialog has been closed, the button pressed was: "+event.result);},</code></pre> * @class Core.Event */Core.Event = Core.create({	/**	 * Creates a new custom event.	 * @method init 	 * @constructor	 * @param {String} name The event name.	 */	init: function(name) {		this.name = name;		this.listeners = new Array();		this.tempListeners = new Array();	},	/**	 * This adds a listener to this event.	 * @method addListener	 * @param {Function} listener The function to be called when the event fires.	 */	addListener: function(listener) {		if(this.listeners.indexOf(listener)<0) {			this.listeners.push(listener);		}	},	/**	 * This adds a temporary listener to this event.  The listener will only be called once, the next time the event fires.	 * @method addTempListener	 * @param {Function} listener The function to be called when the event fires.	 */	addTempListener: function(listener) {		if(this.listeners.indexOf(listener)<0 && this.tempListeners.indexOf(listener)<0) {			this.tempListeners.push(listener);		}	},	/**	 * <p>This removes a listener from this event. </p>	 * <p>If a listener is a bound function (created using the Function.bind), you will need to pass this bound function to removeListener for it to be removed.</p>	 * @method removeListener	 * @param {Function} listener The function to be called when the event fires.	 */	removeListener: function(listener) {		this.listeners.deleteElement(listener);		this.tempListeners.deleteElement(listener);	},	/**	 * This fires the event.  This meas all the listener function will be called and passed the info object.	 * @method fire	 * @param Object info (Optional) An object with information about this event, defaults to an object with type set to the event name.	 */	fire: function(info) {		if(typeof(info)!="object") {			info = {};		}		info.type = this.name;		for(var index=0; index<this.listeners.length; index++) {			this.listeners[index](info);		}		for(var index=0; index<this.tempListeners.length; index++) {			this.tempListeners[index](info);		}		this.tempListeners = new Array();	},	/**	 * Creates and returns a text represntaion of this Event object.	 * @method toString	 * @return {String}	 */	toString : function() {		return "[Core.Event "+this.name+"]";	}});/* ############################## HTTP Request ############################## *//** * <p>A class to create a HTTP Requests commonly used in AJAX style applications.</p> * <h5>Example</h5><p>In this example a HTTP request is made to page which retuns an xml document  * with various statistics.</p> * <pre><code>new Core.HttpRequest("GET", "http://www.dek.com/documentStats.xml", "", this.alertDocCount.bind(this));</code></pre> * <p>The code referres to a method call alertDocCount which is shown below extrating an attribute from the returned xml and displaying the value.</p><pre><code>alertDocCount: function(event) {  var xml = event.request.responseXML;	  var rootNode = Core.XML.findFirstChild(xml, "documents");  if(rootNode!=null) {    alert(Core.XML.getAttribute(rootNode, "count", "0");  }}</code></pre> * @class Core.HttpRequest * @todo Fire an error event when the HTTP Request fails */Core.HttpRequest = Core.create({ 	/**	 * Creates a HTTP.	 * @method init	 * @constructor	 * @param {String} method The HTTP protocol to use, valid options are "GET" or "POST".	 * @param {String} url The URL to be requested.	 * @param {String} data (Optional) The data to sent in the request, this would only normaly be used for POST requests, on other occasions a blank string would be sufficient. Defaults to a blank string.	 * @param {Function} listener (Optional) A function to be called with the results of the request.  The function will be passed an event information object with a request property containing the http request.  See the example above.	 * @param Boolean async (Optional) When set to true the request will be made a asynchronously, the default is false.	 */		init: function(method, url, data, listener, async, manager) {		this.method = typeof(method)==="string" ? method.toUpperCase() : "GET";		this.url = url;		this.data = typeof(data)==="string" ? data : "";		this.listener = listener;		this.async = typeof(async)==="boolean" ? async : true;		this.manager = manager;					this.httpRequest = null;		if(!this.manager) {			this.start();		}	},	start: function() {		// create the http request object		if(window.XMLHttpRequest) { // Mozilla, Safari, ...			this.httpRequest = new XMLHttpRequest();		} else if (window.ActiveXObject) { // IE			try {				this.httpRequest = new ActiveXObject("Msxml2.XMLHTTP");			} catch (e) {				try {					this.httpRequest = new ActiveXObject("Microsoft.XMLHTTP");				} catch (e) {}			}		}					// send the request		if(!this.httpRequest) {			throw Error("Unable to make HTTP Request");		} else {			if(this.async) {				this.httpRequest.onreadystatechange = this.stateChanged.bind(this);			}							this.httpRequest.open(this.method, this.url, this.async);			this.httpRequest.setRequestHeader("Cache-Control", "no-cache");			if(this.method=="POST") {				this.httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");			}			this.httpRequest.send(this.data);			if(!this.async) {				this.stateChanged();			}						}	},	/* private: called when the http reques state changes */	stateChanged : function() {		//try {			if(this.httpRequest.readyState == 4) {				if (this.httpRequest.status == 200) {					var eventInfo = {request: this.httpRequest};										if(this.manager) {						this.manager.requestComplete(eventInfo);					}					if(this.listener) {						this.listener(eventInfo);					}				} else {					//this.errorEvent.fire({request: this.httpRequest});				}				delete this.httpRequest.onreadystatechange;			}		//} catch(e) {			//this.notifyListeners(new HttpResponse(this, null, "exception"));		//}	},	/**	 * Creates and returns a text represntaion of this HTTP Request Manager.	 * @method toString	 * @return {String}	 */		toString : function() {		return "[HttpRequest]";	}});Core.copy(Core, {	/**	 * Equivalent code to calling  <code>new Core.HttpRequest()</code>, in the library for backwards compatibility.	 * @method addRequest	 * @member Core	 * @static	 * @param {String} method The HTTP protocol to use, valid options are "GET" or "POST".	 * @param {String} url The URL to be requested.	 * @param {String} data (Optional) The data to sent in the request, this would only normaly be used for POST requests, on other occasions a blank string would be sufficient. Defaults to a blank string.	 * @param {Function} listener (Optional) A function to be called with the results of the request.  The function will be passed an event information object with a request property containing the http request.  See the example in {Core.HttpRequestManager}.	 * @param Boolean async (Optional) When set to true the request will be made a asynchronously, the default is false.	 * @see Core.HttpRequest	 */		addRequest : function(method, url, data, listener, async) {		new Core.HttpRequest(method, url, data, listener, async);	}});/** * A class to manage HTTP Requests in a sequential manor.  The manager * adds all requests to a queue and performs each request in turn. * @class Core.HttpRequestManager */ Core.HttpRequestManager = Core.create({ 	/**	 * Creates a HTTP Request Manager.	 * @method init	 * @constructor	 */		init: function() {		this.queue = new Array();		this.currentRequest = null;	},	/**	 * Adds a HTTP request to the queue.	 * @method addRequest	 * @param {String} method The HTTP protocol to use, valid options are "GET" or "POST".	 * @param {String} url The URL to be requested.	 * @param {String} data (Optional) The data to sent in the request, this would only normaly be used for POST requests, on other occasions a blank string would be sufficient. Defaults to a blank string.	 * @param {Function} listener (Optional) A function to be called with the results of the request.  The function will be passed an event information object with a request property containing the http request.  See the example above.	 */			addRequest : function(method, url, data, listener) {		this.queue.push(new Core.HttpRequest(method, url, data, listener, false, this));		this.checkQueue();	},	/* private: checks the queue for outstanding request */	checkQueue : function() {		if(this.currentRequest==null) {			if(this.queue.length>0) {				this.currentRequest = this.queue.shift();				this.currentRequest.start();			} 		}	},	/* called by the http request when the request is successfull and complete */	requestComplete: function(event) {		this.currentRequest==null;		this.checkQueue.bind(this);		//window.setTimeout(this.checkQueue.bind(this), 25);	},	/**	 * Creates and returns a text represntaion of this HTTP Request Manager.	 * @method toString	 * @return {String}	 */		toString : function() {		return "[HttpRequestManager]";	}});/* ############################## Point ############################## *//** * Represnets a 2D cordinate with x and y components.  The class has several methods * alowing common operations to be made to the points.  Most of these operations return  * a refrence to the point so they can be chained together. * @class Core.Point */Core.Point = Core.create({	/**	 * Creates a new point.	 * @method init	 * @constructor	 * @param {Number} x The x component.	 * @param {Number} y The y component.	 */	init : function(x, y) {			/**		 * Stores the x components of this point		 * @property x		 * @type Number		 */		this.x=x;			/**		 * Stores the y components of this point		 * @property y		 * @type Number		 */		this.y=y;	},	/**	 * Reset the values for this point.	 * @method set	 * @param {Number} x The x component.	 * @param {Number} y The y component.	 */	set : function(x, y) {		this.x=x;			this.y=y;		return this;	},	/**	 * Adds the x component of the specified point to this point's x component	 * and the y component of the specified point to this point's y component.	 * @method add	 * @param {Core.Point} point The point to add.	 * @param Boolean createNew (Optional) When true the result is stored in a new Core.Point object.  When false (the default) this point is updated with the result.	 * @return {Core.Point} When createNew is true, the new point is returned, when false a refrerence to this point is returned.	 */	add : function(point, createNew) {		if(createNew) {			return new Core.Point(this.x+point.x, this.y+point.y);		} else {			return this.set(this.x+point.x, this.y+point.y);		}	},	/**	 * Subtracts the x component of the specified point from this point's x component	 * and the y component of the specified point from this point's y component.	 * @method minus	 * @param {Core.Point} point The point to subtract.	 * @param Boolean createNew (Optional) When true the result is stored in a new Core.Point object.  When false (the default) this point is updated with the result.	 * @return {Core.Point} When createNew is true, the new point is returned, when false a refrerence to this point is returned.	 */	minus : function(point, createNew) {		if(createNew) {			return new Core.Point(this.x-point.x, this.y-point.y);		} else {			return this.set(this.x-point.x, this.y-point.y);		}	},	/**	 * Multiplies the x component of the specified point with this point's x component	 * and the y component of the specified point with this point's y component.	 * @method multiply	 * @param {Core.Point} point The point to multiply.	 * @param Boolean createNew (Optional) When true the result is stored in a new Core.Point object.  When false (the default) this point is updated with the result.	 * @return {Core.Point} When createNew is true, the new point is returned, when false a refrerence to this point is returned.	 */	multiply : function(multiplier, createNew) {		if(multiplier instanceof Core.Point) {			if(createNew) {				return new Core.Point(this.x*multiplier.x, this.y*multiplier.y);			} else {				return this.set(this.x*multiplier.x, this.y*multiplier.y);			}		} else {			if(createNew) {				return new Core.Point(this.x*multiplier, this.y*multiplier);			} else {				return this.set(this.x*multiplier, this.y*multiplier);			}		}	},	/**	 * Uses the smallest x and y components from this and the specifed point.	 * @method min	 * @param {Core.Point} point The point to compare.	 * @param Boolean createNew (Optional) When true the result is stored in a new Core.Point object.  When false (the default) this point is updated with the result.	 * @return {Core.Point} When createNew is true, the new point is returned, when false a refrerence to this point is returned.	 */	min : function(point, createNew) {		if(createNew) {			return new Core.Point(Math.min(this.x, point.x), Math.min(this.y, point.y));		} else {			return this.set(Math.min(this.x, point.x), Math.min(this.y, point.y));		}	},	/**	 * Uses the largest x and y components from this and the specifed point.	 * @method max	 * @param {Core.Point} point The point to compare.	 * @param Boolean createNew (Optional) When true the result is stored in a new Core.Point object.  When false (the default) this point is updated with the result.	 * @return {Core.Point} When createNew is true, the new point is returned, when false a refrerence to this point is returned.	 */		max : function(point, createNew) {		if(createNew) {			return new Core.Point(Math.max(this.x, point.x), Math.max(this.y, point.y));		} else {			return this.set(Math.max(this.x, point.x), Math.max(this.y, point.y));		}	},	/**	 * Makes sure this point is contained within the rectangle defined by the two specified points.	 * @method constrainTo	 * @param {Core.Point} point1 One corner of a rectangle	 * @param {Core.Point} point2 The opposite corner of a rectangle	 * @param Boolean createNew (Optional) When true the result is stored in a new Core.Point object.  When false (the default) this point is updated with the result.	 * @return {Core.Point} When createNew is true, the new point is returned, when false a refrerence to this point is returned.	 */		constrainTo : function(point1, point2, createNew) {		var topLeft = point1.min(point2, true);		var bottomRight = point1.max(point2, true);		if(createNew) {			return this.max(topLeft, true).min(bottomRight);		} else {			return this.max(topLeft).min(bottomRight);		}			},	/**	 * Creates a copy of this point with the same x and y values.	 * @method clone	 * @return {Core.Point} The new point.	 */		clone: function() {		return new Core.Point(this.x, this.y);	},	/*	 * Creates and returns a text represntaion of this Point object.	 * @method toString	 * @return {String}	 */	toString : function() {		return "[Core.Point x:"+this.x+" y:"+this.y+"]";	}});
