/*! Echospin API Loader 1.9
   Copyright (c) 2010 Echospin LLC (echospin.com)
*/

var echospin = new function() {
	this.version = "1.9";
	this.initialized = true;
	this.loadArgs = {};
	
	this.visitor = {
		domainScope: "global",
		sessionTimeout: 1800
	};
	
	this.tracking = {
		webTrends: false,
		googleAnalytics: false,
		siteCatalyst: false
	};

	var	m_sAPIKey = 'c94783bef99b48aca8455015015370f3',
			m_sAPIMode = '',
			m_sAjaxURL = (location.protocol == "file:" ? "http:" : location.protocol) + "//api.echospin.com/" + (m_sAPIMode ? m_sAPIMode + "/" : "") + m_sAPIKey + "/ajax/",
			
			m_arrAPIList = [
				"preview", 
				"cart", 
				"checkout", 
				"orders", 
				"promo"
			],
																	
			m_objEchospin = this,
			//m_objWindow = window,
			m_objDocument = document,
			m_objLocation = m_objDocument.location,
			
			m_sCookieDomain = m_objLocation.hostname.toLowerCase(),
			
			m_bDisabled,
			//m_dtInitialized = new Date(),
			
			m_objVisitor = {
				id: (Math.round(Math.random() * 2147483647) * (Math.random() * 2147483647)).toString(),
				created: null
			},
			m_nVisitorTimeout = 631138519,
			
			m_objSession = {
				id: (Math.round(Math.random() * 2147483647) * (Math.random() * 2147483647)).toString(),
				created: null,
				pageCount: 1,
				landing: "",
				referrer: ""
			},

			m_sJQueryURL = "ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js",
			//m_sGoogleAjaxURL = "www.google.com/jsapi",
			
			m_objCompatibleAgents = {
				opera: 9,
				msie: 6,
				applewebkit: 522.11,
				firefox: 2
			},

			m_bBrowserIsCompatible,
			m_bJQueryLoaded,
			
			m_i,
			
			m_sErrorAjax = "Ajax Error",
			m_sErrorAjaxProcessing = "Ajax Processing Error",

			m_sConstantJSPath = "/js/",
			m_sConstantEchospin = "echospin",
			
			m_sConstantUndefined = "undefined",
			m_sConstantFunction = "function",
			m_sConstantNumber = "number",
			m_sConstantString = "string",
			m_sConstantObject = "object",
			
			m_sConstantUTMForm = "utmform",
			m_sConstantUTMTrans = "utmtrans",
			
			m_sConstantForwardSlash = "/",
			m_sConstantDot = ".",
			m_sConstantPipe = m_sConstantPipe,
			
			ajaxResponseCode = {
				processingError: -100,
				success: 0
			},

			API = function(sName) {
				this.load = function(args) {
					return loadAPI(sName, args);
				};
			};
			
	this.trace = function() {
		if (!m_sAPIMode ||
				!arguments.length) return;
				
		try {
			if (console) {
				var args = (new Array()).slice.call(arguments, 0);
				
				if (typeof args[0] == m_sConstantString &&
						args[0].indexOf(m_sConstantEchospin) != 0) args[0] = m_sConstantEchospin + m_sConstantDot + args[0];
					
				if (typeof console.dir == m_sConstantFunction) console.log(m_sConstantEchospin + " trace", args); 
				else console.log(m_sConstantEchospin + " trace " + args.join(", ")); 
			}
		} catch(e) {}
	};
	
	this.log = function() {
		if (!m_sAPIMode ||
				!arguments.length) return;
				
		try {
			if (console) {
				var args = (new Array()).slice.call(arguments, 0);

				if (typeof console.dir == m_sConstantFunction) console.log(m_sConstantEchospin + " log", args);
				else console.log(m_sConstantEchospin + " log " + args.join(", "));
			}
		} catch(e) {}
	};

	this.log("API Loader", this.version, m_sAPIKey);

	this.track = function() {
		if ((!this.tracking.webTrands &&
				 !this.tracking.googleAnalytics &&
				 !this.tracking.siteCatalyst) ||
				!arguments.length) return;

		var args,
				tmp,
				sBaseUrl = ((m_objLocation.pathname.substring(m_objLocation.pathname.length - 1) != m_sConstantForwardSlash) ? m_objLocation.pathname + m_sConstantForwardSlash : m_objLocation.pathname).toLowerCase();

		try {
			if (this.tracking.webTrends &&
					typeof dcsMultiTrack == m_sConstantFunction) {
				args = (new Array()).slice.call(arguments, 0);
				this.log("Tracking WebTrends", args);
				
				if (typeof args[0] == m_sConstantString) {
					args[0] = sBaseUrl + m_sConstantEchospin + args[0];
					args[0] = encodeURIComponent(args[0]);
					if (typeof args[1] == m_sConstantString) args[1] = m_objDocument.title + " [" + args[1] + "]";
					else args[1] = m_objDocument.title;
					args[1] = encodeURIComponent(args[1]);
				}
				
				if (typeof args[2] == m_sConstantObject) {
					/*
					WT.si_n="Shoppingcart";
					WT.si_x="4";
					WT.tx_it="hh:mm:ss";
					WT.tx_id="mm/dd/yy";
					
					WT.pn_fa="Desktop and PC Workstation;Be Seen On The Road";
					WT.pn_gr="3M Select;3M Select";
					WT.pn_sc="3M Precise™ Mouse Mats;null";
					*/
					tmp = new Array(5);
					for (m_i = 0; m_i < args[2].items.length; m_i++) {
						if (tmp[0]) tmp[0] += ";"
						else tmp[0] = "";
						tmp[0] += args[2].items[m_i].id;

						if (tmp[1]) tmp[1] += ";"
						else tmp[1] = "";
						tmp[1] += encodeURIComponent(args[2].items[m_i].artist + " - " + args[2].items[m_i].title);

						if (tmp[2]) tmp[2] += ";"
						else tmp[2] = "";
						tmp[2] += args[2].items[m_i].category;

						if (tmp[3]) tmp[3] += ";"
						else tmp[3] = "";
						tmp[3] += args[2].items[m_i].price;

						if (tmp[4]) tmp[4] += ";"
						else tmp[4] = "";
						tmp[4] += args[2].items[m_i].quantity;
					}
									
					this.log("dcsMultiTrack()", "DCS.dcsuri=" + args[0], "WT.ti=" + args[1], "WT.tx_i=" + args[2].orderId, "WT.tx_cartid=" + m_objSession.id, "WT.tx_e=p", "WT.pn_sku=" + tmp[0], "WT.pn=" + tmp[1], "WT.pc=" + tmp[2], "WT.tx_s=" + tmp[3], "WT.tx_u=" + tmp[4]);
					dcsMultiTrack("DCS.dcsuri", args[0], "WT.ti", args[1], "WT.tx_i", args[2].orderId, "WT.tx_cartid", m_objSession.id, "WT.tx_e", "p", "WT.pn_sku", tmp[0], "WT.pn", tmp[1], "WT.pc", tmp[2], "WT.tx_s", tmp[3], "WT.tx_u", tmp[4]);
				} else if (typeof args[0] == m_sConstantString) {
					this.log("dcsMultiTrack()", "DCS.dcsuri=" + args[0], "WT.ti=" + args[1]);
					dcsMultiTrack("DCS.dcsuri", args[0], "WT.ti", args[1]);
				}				
			}
		} catch(e) {}
		
		try {
			if (this.tracking.googleAnalytics &&
					typeof urchinTracker == m_sConstantFunction) {
				this.log("Tracking Google Analytics (urchin.js)", args);
				args = (new Array()).slice.call(arguments, 0);
				
				if (typeof args[0] == m_sConstantString) {
					args[0] = sBaseUrl + m_sConstantEchospin + args[0];
					if (typeof args[1] == m_sConstantString) {
						tmp = m_objDocument.title;
						args[1] = tmp + " [" + args[1] + "]";
						m_objDocument.title = args[1];
					}
					this.log("urchinTracker()", args[0], args[1]);
					urchinTracker(args[0]);
					if (tmp) m_objDocument.title = tmp;
				}
				
				if (typeof args[2] == m_sConstantObject) {
					$("body").append(this.ml(["form", { "id": m_sConstantUTMForm, "name": m_sConstantUTMForm, "style": "display: none;" }]).append(this.ml(["textarea", { "id": m_sConstantUTMTrans, "name": m_sConstantUTMTrans }])));
					this.log("UTM:T", args[2].orderId, args[2].affiliation, args[2].total, args[2].tax, args[2].shipping, args[2].city, args[2].region, args[2].country);
					tmp = " UTM:T|" & args[2].orderId + m_sConstantPipe + args[2].affiliation + m_sConstantPipe + args[2].total + m_sConstantPipe + args[2].tax + m_sConstantPipe + args[2].shipping + m_sConstantPipe + args[2].city + m_sConstantPipe + args[2].region + m_sConstantPipe + args[2].country + " \n";
					
					for (m_i = 0; m_i < args[2].items.length; m_i++) {
						this.log("UTM:I", args[2].orderId, args[2].items[m_i].id, args[2].items[m_i].artist + " - " + args[2].items[m_i].title, args[2].items[m_i].category, args[2].items[m_i].price, args[2].items[m_i].quantity);
						tmp += " UTM:I|" + args[2].orderId + m_sConstantPipe + args[2].items[m_i].id + m_sConstantPipe + args[2].items[m_i].artist + " - " + args[2].items[m_i].title + m_sConstantPipe + args[2].items[m_i].category + m_sConstantPipe + args[2].items[m_i].price + m_sConstantPipe + args[2].items[m_i].quantity + " \n";
					}
					$("#utmtrans").val(tmp);
					
					this.log("__utmSetTrans()");
					__utmSetTrans();
				}
			}
		} catch(e) {}

		try {
			if (this.tracking.googleAnalytics &&
					typeof pageTracker == m_sConstantObject) {
				args = (new Array()).slice.call(arguments, 0);
				this.log("Tracking Google Analytics (Traditional ga.js)", args);
				
				if (typeof args[0] == m_sConstantString) {
					args[0] = sBaseUrl + m_sConstantEchospin + args[0];
					if (typeof args[1] == m_sConstantString) {
						tmp = m_objDocument.title;
						args[1] = tmp + " [" + args[1] + "]";
						m_objDocument.title = args[1];
					}
					this.log("_trackPageview()", args[0], args[1]);
					pageTracker._trackPageview(args[0]);
					if (tmp) m_objDocument.title = tmp;
				}
				
				if (typeof args[2] == m_sConstantObject) {
					this.log("_addTrans()", args[2].orderId, args[2].affiliation, args[2].total, args[2].tax, args[2].shipping, args[2].city, args[2].region, args[2].country);
					pageTracker._addTrans(args[2].orderId, args[2].affiliation, args[2].total, args[2].tax, args[2].shipping, args[2].city, args[2].region, args[2].country);
					
					for (m_i = 0; m_i < args[2].items.length; m_i++) {
						this.log("_addItem()", args[2].orderId, args[2].items[m_i].id, args[2].items[m_i].artist + " - " + args[2].items[m_i].title, args[2].items[m_i].category, args[2].items[m_i].price, args[2].items[m_i].quantity);
						pageTracker._addItem(args[2].orderId, args[2].items[m_i].id, args[2].items[m_i].artist + " - " + args[2].items[m_i].title, args[2].items[m_i].category, args[2].items[m_i].price, args[2].items[m_i].quantity);
					}
						
					this.log("_trackTrans()");
					pageTracker._trackTrans();
				}
			} else if (this.tracking.googleAnalytics &&
					typeof _gaq.push == m_sConstantFunction) {
				args = (new Array()).slice.call(arguments, 0);
				this.log("Tracking Google Analytics (Async ga.js)", args);
				
				if (typeof args[0] == m_sConstantString) {
					args[0] = sBaseUrl + m_sConstantEchospin + args[0];
					if (typeof args[1] == m_sConstantString) {
						tmp = m_objDocument.title;
						args[1] = tmp + " [" + args[1] + "]";
						m_objDocument.title = args[1];
					}
					this.log("_gaq.push([\"_trackPageview\"])", args[0], args[1]);
					_gaq.push(["_trackPageview", args[0]]);
					if (tmp) m_objDocument.title = tmp;
				}
				
				if (typeof args[2] == m_sConstantObject) {
					this.log("_gaq.push([\"_addTrans\"])", args[2].orderId, args[2].affiliation, args[2].total, args[2].tax, args[2].shipping, args[2].city, args[2].region, args[2].country);
					_gaq.push(["_addTrans", args[2].orderId, args[2].affiliation, args[2].total, args[2].tax, args[2].shipping, args[2].city, args[2].region, args[2].country]);
					
					for (m_i = 0; m_i < args[2].items.length; m_i++) {
						this.log("_gaq.push([\"_addItem\"])", args[2].orderId, args[2].items[m_i].id, args[2].items[m_i].artist + " - " + args[2].items[m_i].title, args[2].items[m_i].category, args[2].items[m_i].price, args[2].items[m_i].quantity);
						_gaq.push(["_addItem", args[2].orderId, args[2].items[m_i].id, args[2].items[m_i].artist + " - " + args[2].items[m_i].title, args[2].items[m_i].category, args[2].items[m_i].price, args[2].items[m_i].quantity]);
					}
						
					this.log("_gaq.push([\"_trackTrans\"])");
					_gaq.push(["_trackTrans"]);
				}
			}
		} catch(e) {}
	};
	
	this.browserIsCompatible = function() {
		if (m_bBrowserIsCompatible) return true;
		else if (m_bBrowserIsCompatible === false) return false;
			
		var sAgent = navigator.userAgent,
				i;
		
		this.cookie.initialize();

		this.trace("browserIsCompatible", {
			userAgent: sAgent
		});

		for (i in m_objCompatibleAgents)
			if (sAgent.toLowerCase().indexOf(i) != -1) {
				if (RegExp(i + "[ \/]?([0-9]+(\.[0-9]+)?)").exec(sAgent.toLowerCase()) != null) {
					if (parseFloat(RegExp.$1) >= m_objCompatibleAgents[i]) return m_bBrowserIsCompatible = true;
				}
			}
		
		return m_bBrowserIsCompatible = false;
	};
			
	function jQueryLoaded() {
		try {
			$(function() {
				m_objEchospin.log("DOM Ready");
				m_objEchospin.cookie.load();
			});
			
			m_bJQueryLoaded = true;
		} catch(e) {
			m_bDisabled = true;
		}
	}

	try {
		if (typeof jQuery == m_sConstantFunction) jQueryLoaded();
		else loadScript((m_objLocation.protocol == "file:" ? "http:" : m_objLocation.protocol) + "//" + m_sJQueryURL, function() {
			jQueryLoaded();
		});
	} catch(e) {
		m_bDisabled = true;
	}

	for (m_i = 0; m_i < m_arrAPIList.length; m_i++) this[m_arrAPIList[m_i]] = new API(m_arrAPIList[m_i]);

	function loadAPI(sName, objArgs) {
		if (m_bDisabled) return false;
		if (m_bBrowserIsCompatible == null) m_objEchospin.browserIsCompatible();
		
		if (!sName ||
				m_bBrowserIsCompatible === false) return false;
		
		if (!m_bJQueryLoaded) {
			setTimeout(function() {
				loadAPI(sName, objArgs);
			}, 10);
			
			return true;
		}

		//m_objEchospin.trace(sName + ".load", objArgs);

		var sScript = (m_objLocation.protocol == "file:" ? "http:" : m_objLocation.protocol) + "//api." + m_sConstantEchospin + ".com" + m_sConstantForwardSlash + (m_sAPIMode ? m_sAPIMode + m_sConstantForwardSlash : "") + m_sAPIKey + m_sConstantJSPath + sName + m_sConstantForwardSlash,
				ptrFunc;

		try {						
			if (objArgs) m_objEchospin.loadArgs[sName] = objArgs;
			if (!loadScript(sScript)) return false;
		} catch(e) {		
			return false;
		}
		
		return true;
	}
		
	function loadScript(sScript, ptrFunc) {
		if (m_bDisabled) return false;
		if (!sScript) return false;
		else if (m_objDocument.getElementById(sScript)) return true;

	  try {
	  	var sConstantHead = "head",
	  			objScript = m_objDocument.createElement("script"),
	  			objHead = m_objDocument.getElementsByTagName(sConstantHead)[0],
	  			ptrNewFunc;
	  		  
			objScript.id = sScript;
		  objScript.src = sScript;
		  objScript.type = "text/javascript";
		  		  
		  ptrNewFunc = function(event) {
				m_objEchospin.log("Script Loaded", sScript);
				if (typeof ptrFunc == m_sConstantFunction) ptrFunc.call();
			}
			
			if (objScript.addEventListener) objScript.addEventListener("load", ptrNewFunc, false);
			else if (objScript.attachEvent) objScript.attachEvent("onreadystatechange", function() {
				if (objScript.readyState == "loaded" ||
						objScript.readyState == "complete") {
					if (ptrNewFunc) {
						ptrNewFunc.call();
						ptrNewFunc = null;
					}
				}
			});

			if (!objHead) objHead = m_objDocument.body.parentNode.appendChild(m_objDocument.createElement(sConstantHead));
			objHead.appendChild(objScript);

			m_objEchospin.log("Loading Script", sScript);
		} catch(e) {
			return false;
		}
		
		return true;
	}

	/*
	function queueLoadEvent(func) {
		if (m_objWindow.addEventListener) m_objWindow.addEventListener("load", func, false);
		else if (m_objWindow.attachEvent) m_objWindow.attachEvent("onload", func);
		else if (m_objWindow.onload) {
		  var onload = m_objWindow.onload;
		  
		  m_objWindow.onload = function() {
		    func();
		    onload();
		  }
		}
	}
	*/
	
	this.getSession = function() {
		return [
			encodeURIComponent(m_sCookieDomain),
			m_objVisitor.id,
			m_objVisitor.created.getTime() / 1000,
			m_objSession.id,
			m_objSession.pageCount,
			encodeURIComponent("REDACTED"), //m_objSession.landing
			encodeURIComponent(m_objLocation.href),
			encodeURIComponent("REDACTED"), //m_objSession.referrer.substring(0, 50)
			(new Date()).getTimezoneOffset() / 60 * -1,
			m_objSession.created.getTime() / 1000,
			(new Date()).getTime() / 1000
		].join("&");
	};
	
	this.trim = function(str) {
		str = str.replace(/^\s+/, '');
		
		for (var i = str.length - 1; i >= 0; i--)
			if (/\S/.test(str.charAt(i))) {
				str = str.substring(0, i + 1);
				break;
			}

		return str;
	};

	this.lengthOf = function(objArray) {
		var nLength = 0,
				i;
		
		for (i in objArray) nLength++;
		
		return nLength;
	};

	this.lzwEncode = function (string) {
		return string;
		if (!string) return string;
			
    var dict = {},
    		data = (string + "").split(""),
    		out = [],
    		currChar,
    		phrase = data[0],
    		code = 256,
    		i;
    		
    for (i = 1; i < data.length; i++) {
      currChar = data[i];
      
      if (dict[phrase + currChar] != null) phrase += currChar;
      else {
        out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
        dict[phrase + currChar] = code;
        code++;
        phrase = currChar;
      }
    }
    out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));

    for (i = 0; i < out.length; i++) 
    	out[i] = String.fromCharCode(out[i]);

    return out.join("");
	};

	this.lzwDecode = function(string) {
		return string;
		if (!string) return string;

    var dict = {},
    		data = (string + "").split(""),
    		currChar = data[0],
    		oldPhrase = currChar,
    		out = [currChar],
    		code = 256,
    		phrase,
    		i,
    		currCode;
    		
    for (i = 1; i < data.length; i++) {
      currCode = data[i].charCodeAt(0);
      if (currCode < 256) phrase = data[i];
      else phrase = dict[currCode] ? dict[currCode] : (oldPhrase + currChar);

      out.push(phrase);
      currChar = phrase.charAt(0);
      dict[code] = oldPhrase + currChar;
      code++;
      oldPhrase = phrase;
    }
    
    return out.join("");
	};

	this.itemTypes = new function() {
		var m_objTypes = {
			typeCD: {
				value: 0,
				label: "CD"
			},
			typeMP3s: {
				value: 1,
				label: "MP3s"
			},
			typeMP3: {
				value: 2,
				label: "MP3"
			},
			typeMP4: {
				value: 3,
				label: "MP4"
			},
			typeDVD: {
				value: 4,
				label: "DVD"
			},
			typeRingtone: {
				value: 5,
				label: "Ringtone"
			},
			typeApparel: {
				value: 6,
				label: "Apparel"
			},
			typeVinyl: {
				value: 7,
				label: "Vinyl"
			},
			typeMerchandise: {
				value: 8,
				label: "Merchandise"
			},
			typeTicket: {
				value: 9,
				label: "Ticket"
			},
			typeBundle: {
				value: 10,
				label: "Bundle"
			},
			typeDigitalBooklet: {
				value: 11,
				label: "Digital Booklet"
			},
			typeSubscription: {
				value: 12,
				label: "Subscription"
			},
			typeUserPlaylist: {
				value: 13,
				label: "User Playlist"
			}
		};
		
		this.labels = {};
		this.types = {};
			
		for (m_i in m_objTypes) {
			this[m_i] = m_objTypes[m_i].value;
			this.labels[m_i] = m_objTypes[m_i].label;
			this.labels[m_objTypes[m_i].value] = m_objTypes[m_i].label;
			this.types[m_objTypes[m_i].value] = m_i.toString();
		}
	};
	
	this.cookie = new function() {
		var sVisitorCookie = m_sConstantEchospin + ".visitor",
				sInstanceCookie = m_sConstantEchospin + ".instance",
				sSessionCookie = m_sConstantEchospin + ".session",
				sCartCookie = m_sConstantEchospin + ".cart",
				sFormCookie = m_sConstantEchospin + ".form",
				sTestCookie = m_sConstantEchospin + ".test",
				sDomainHash,
				arrVisitor = [],
				arrSession = [],
				bCookiesAllowed = false;
										
		this.initialize = function() {
			if (m_objLocation.hostname.toLowerCase() == "127.0.0.1" ||
					m_objLocation.hostname.toLowerCase() == "localhost") m_sCookieDomain = m_objLocation.hostname.toLowerCase();
			else if (m_objEchospin.visitor.domainScope.toLowerCase() == "global") {
				m_sCookieDomain = m_objLocation.hostname.toLowerCase();
				while (m_sCookieDomain.indexOf(m_sConstantDot) != m_sCookieDomain.lastIndexOf(m_sConstantDot)) m_sCookieDomain = m_sCookieDomain.substring(m_sCookieDomain.indexOf(m_sConstantDot) + 1);
				m_sCookieDomain = m_sConstantDot + m_sCookieDomain;
			} else if (m_objEchospin.visitor.domainScope &&
								 m_objEchospin.visitor.domainScope.toLowerCase() != "local") m_sCookieDomain = m_objEchospin.visitor.domainScope.toLowerCase();
				
			sDomainHash = hash(m_sCookieDomain);
			sVisitorCookie += sDomainHash;
			sInstanceCookie += sDomainHash;
			sSessionCookie += sDomainHash;
			sCartCookie += sDomainHash;
			
			setCookie(sTestCookie, sTestCookie);
			if (getCookie(sTestCookie) === sTestCookie) {
				bCookiesAllowed = true;
				clearCookie(sTestCookie);
			}
			
			m_objEchospin.trace(m_sConstantEchospin + ".cookie.initialize", {
				permitted: bCookiesAllowed,
				domain: m_sCookieDomain
			});
		}; 
		
		this.load = function() {
			m_objEchospin.trace(m_sConstantEchospin + ".cookie.load");

			m_objVisitor.created = new Date();
			m_objSession.created = new Date();

			arrVisitor = getCookie(sVisitorCookie).split("&");
		  if (arrVisitor.length == 2) {
		  	m_objVisitor.id = arrVisitor[0];
		  	m_objVisitor.created.setTime(parseInt(arrVisitor[1]) * 1000);
			} else {
				arrVisitor[0] = m_objVisitor.id;
				arrVisitor[1] = Date.parse(m_objVisitor.created) / 1000;
			}
	  	setCookie(sVisitorCookie, arrVisitor.join("&"), m_nVisitorTimeout);
			m_objEchospin.log(sVisitorCookie, m_objVisitor.id, m_objVisitor.created);
	
	  	if (getCookie(sInstanceCookie).length > 0) arrSession = getCookie(sSessionCookie).split("&");
	  	else setCookie(sInstanceCookie, Date.parse(m_objSession.created) / 1000);
	  		
		  if (arrSession.length == 5) {
		  	m_objSession.id = arrSession[0];
		  	m_objSession.created.setTime(parseInt(arrSession[1]) * 1000);
		  	m_objSession.pageCount = arrSession[2] = parseInt(arrSession[2]) + 1;
		  	m_objSession.landing = decodeURIComponent(arrSession[3]);
		  	m_objSession.referrer = decodeURIComponent(arrSession[4]);	  	
			} else {
				arrSession[0] = m_objSession.id;
				arrSession[1] = Date.parse(m_objSession.created) / 1000;
				arrSession[2] = m_objSession.pageCount;
				arrSession[3] = m_objSession.landing = encodeURIComponent(m_objLocation.href);
				arrSession[4] = m_objSession.referrer = encodeURIComponent(m_objDocument.referrer);
			}
	  	setCookie(sSessionCookie, arrSession.join("&"), m_objEchospin.visitor.sessionTimeout);
			m_objEchospin.log(sSessionCookie, m_objSession.id, m_objSession.created, m_objSession.pageCount, m_objSession.landing, m_objSession.referrer);
			
			m_bCookieLoaded = true;
		};

		this.getCart = function(param1, param2) {
			if (bCookiesAllowed) return getCookie(sCartCookie);
			else return ajaxProcess("get", {
				name: sCartCookie
			}, arguments.callee.caller, param1, param2);
		};
	
		this.setCart = function(value) {
			if (bCookiesAllowed) setCookie(sCartCookie, value);
			else ajaxProcess("set", {
				name: sCartCookie,
				value: value
			});
		};
	
		this.clearCart = function() {
			if (bCookiesAllowed) clearCookie(sCartCookie);
			else ajaxProcess("clear", {
				name: sCartCookie
			});
		};
		
		this.getForm = function(param1, param2) {
			if (bCookiesAllowed) return getCookie(sFormCookie);
			else return ajaxProcess("get", {
				name: sFormCookie
			}, arguments.callee.caller, param1, param2);
		};
		
		this.setForm = function(value) {
			if (bCookiesAllowed) setCookie(sFormCookie, value);
			else ajaxProcess("set", {
				name: sFormCookie,
				value: value
			});
		};
		
		this.clearForm = function() {
			if (bCookiesAllowed) clearCookie(sFormCookie);
			else ajaxProcess("clear", {
				name: sFormCookie
			});
		};
		
		function ajaxProcess(sCommand, objData, fCalback, vParam1, vParam2) {
			if (!sCommand ||
					!objData) return;

			m_objEchospin.trace(m_sConstantEchospin + ".cookie.onAjaxProcess", {
				command: sCommand,
				data: objData
			});

			$.ajax({
				data: objData,
				success: function(data) {
					if (!data) m_objEchospin.trace(m_sConstantEchospin + ".cookie.onAjaxError", {
							error: m_sErrorAjax
						});
					else if (data.resultcode <= ajaxResponseCode.processingError) m_objEchospin.trace(m_sConstantEchospin + ".cookie.onAjaxError", {
							error: m_sErrorAjax
						});
					else if (data.value !== undefined) {
						m_objEchospin.trace(m_sConstantEchospin + ".cookie.onAjaxSuccess", {
							value: data.value
						});
						setTimeout(function() {
							if (vParam2 !== undefined) fCalback(vParam1, vParam2, data.value);
							else if (vParam1 !== undefined) fCalback(vParam1, data.value);
							else fCalback(data.value);
						}, 10);
					} else m_objEchospin.trace(m_sConstantEchospin + ".cookie.onAjaxSuccess");
				},
				type: "GET",
				dataType: "jsonp",
				jsonp: "jsoncallback",
				url: m_sAjaxURL + "cookie/" + sCommand + "/",
				cache: false,
				timeout: 30000,
				error: function(XMLHttpRequest, textStatus, errorThrown) {
					m_objEchospin.trace(m_sConstantEchospin + ".cookie.onAjaxError", {
						error: m_sErrorAjax
					});
				}
			});
			
			if (sCommand === "get") return "ASYNC";
		}
			
		function getCookie(name) {
			if (!name) return;
			
			return m_objEchospin.lzwDecode(cookie(name)) || "";
		}

		function setCookie(name, value, expires) {
			if (!name) return;
			
			if (!value) clearCookie(name);
			else cookie(name, m_objEchospin.lzwEncode(value), {
				expires: expires,
				path: m_sConstantForwardSlash,
				domain: m_sCookieDomain, 
				secure: false
			});
		}
		
		function clearCookie(name) {
			if (!name) return;
			
			cookie(name, "", {
				expires: -1, 
				path: m_sConstantForwardSlash, 
				domain: m_sCookieDomain, 
				secure: false
			});
		}

		function cookie(name, value, options) {
			var expires,
					date,
					path,
					domain,
					secure,
					cookieValue,
					cookies,
					cookie;
					
	    if (typeof value != m_sConstantUndefined) { // name and value given, set cookie
	      options = options || {};
	      expires = "";
	      if (options.expires && (typeof options.expires == m_sConstantNumber || options.expires.toGMTString)) {
	        if (typeof options.expires == m_sConstantNumber) {
	          date = new Date();
	          date.setTime(date.getTime() + (options.expires * 1000)); // * 24 * 60 * 60 * 1000
	        } else date = options.expires;
	        expires = "; expires=" + date.toGMTString(); // use expires attribute, max-age is not supported by IE
	      }
	      path = options.path ? "; path=" + options.path : "";
	      domain = options.domain ? "; domain=" + options.domain : "";
	      secure = options.secure ? "; secure" : "";
	      m_objDocument.cookie = [name, "=", encodeURIComponent(value), expires, path, domain, secure].join("");
	    } else { // only name given, get cookie
	      cookieValue = null;
	      if (m_objDocument.cookie && m_objDocument.cookie != "") {
	        cookies = m_objDocument.cookie.split(";");
	        for (m_i = 0; m_i < cookies.length; m_i++) {
	          cookie = m_objEchospin.trim(cookies[m_i]);
	          // Does this cookie string begin with the name we want?
	          if (cookie.substring(0, name.length + 1) == (name + "=")) {
	            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
	            break;
	          }
	        }
	      }
	      return cookieValue;
	    }
		}

		function hash(sString) {
		  if (!sString ||
		  		sString == "") return "";
		
		  var h = 0,
		  		g = 0,
		  		i,
		  		c;
		
		  for (i = sString.length-1; i >= 0; i--) {
		    c = parseInt(sString.charCodeAt(i));
		    h = ((h << 6) & 0xfffffff) + c + (c << 14);
		    if ((g = h & 0xfe00000) != 0) h = (h ^ (g >> 21));
		  }
		  
		  return m_sConstantDot + h;
		}
	};
	
	//queueLoadEvent(m_objEchospin.cookie.load);

	/** JSONML Array to DOM - quick DOM creation
	 * @author  Andrea Giammarchi
	 * @since   07/07/2008
	 * @specs   JSONML http://jsonml.org/
	 * @extra   events assignment
	 */ 
	
	this.ml = new function(multi) {
		return function(a) {
			var length,
					node,
					value,
					key;
					
		  for (m_i = 1, length = a.length, node = $(m_objDocument.createElement(a[0])), value; m_i < length; m_i++) {
		    switch (typeof(value = a[m_i])) {
		      case m_sConstantString:
		        node.append(value);
		        break;
		      
		      case m_sConstantObject:
		        if (value instanceof Array) node.append(echospin.ml(value));
		        else
		          for (key in value)
		            switch (typeof value[key]) {
		              case m_sConstantString:
		                node.attr(key, value[key]);
		                break;
		              
		              case m_sConstantNumber:
		                node.attr(key, value[key].toString());
		                break;
		              
		              case "boolean":
		                node.attr(key, (value[key]) ? "true" : "false");
		                break;
		              
		              case m_sConstantFunction:
		                value[key] = [value[key], undefined];
		              
		              case m_sConstantObject:
		                node.bind(key.replace(multi, " "), value[key][0], value[key][1]);
		                break;
		            }
		         break;
		    }
		  }
	  	return node;
		};
	};

	/*
	this.JSON = new function() {
    function f(n) {
      return n < 10 ? '0' + n : n;
    }

    if (typeof Date.prototype.toJSON !== 'function') {
      Date.prototype.toJSON = function (key) {
        return isFinite(this.valueOf()) ?
               this.getUTCFullYear()   + '-' +
             f(this.getUTCMonth() + 1) + '-' +
             f(this.getUTCDate())      + 'T' +
             f(this.getUTCHours())     + ':' +
             f(this.getUTCMinutes())   + ':' +
             f(this.getUTCSeconds())   + 'Z' : null;
      };

      String.prototype.toJSON =
      Number.prototype.toJSON =
      Boolean.prototype.toJSON = function (key) {
        return this.valueOf();
      };
    }

    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        gap,
        indent,
        meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        rep;

    function quote(string) {	
      escapable.lastIndex = 0;
      return escapable.test(string) ?
          '"' + string.replace(escapable, function (a) {
              var c = meta[a];
              return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
          }) + '"' :
          '"' + string + '"';
    }

    function str(key, holder) {	
      var i,          // The loop counter.
          k,          // The member key.
          v,          // The member value.
          length,
          mind = gap,
          partial,
          value = holder[key];

      if (value && typeof value === 'object' &&
        typeof value.toJSON === 'function') value = value.toJSON(key);

      if (typeof rep === 'function') value = rep.call(holder, key, value);

      switch (typeof value) {
        case 'string':
          return quote(value);

        case 'number':
          return isFinite(value) ? String(value) : 'null';

        case 'boolean':
        case 'null':
          return String(value);

        case 'object':
          if (!value) return 'null';

          gap += indent;
          partial = [];

          if (Object.prototype.toString.apply(value) === '[object Array]') {
            length = value.length;

            for (i = 0; i < length; i += 1)
            	partial[i] = str(i, value) || 'null';

            v = partial.length === 0 ? '[]' :
                gap ? '[\n' + gap +
                        partial.join(',\n' + gap) + '\n' +
                            mind + ']' :
                      '[' + partial.join(',') + ']';
            gap = mind;
            return v;
          }

          if (rep && typeof rep === 'object') {
            length = rep.length;

            for (i = 0; i < length; i += 1) {
              k = rep[i];
              if (typeof k === 'string') {
                v = str(k, value);
                if (v) partial.push(quote(k) + (gap ? ': ' : ':') + v);
              }
            }
          } else {	
            for (k in value) {
              if (Object.hasOwnProperty.call(value, k)) {
                v = str(k, value);
                if (v) partial.push(quote(k) + (gap ? ': ' : ':') + v);
              }
            }
          }

          v = partial.length === 0 ? '{}' :
              gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
                      mind + '}' : '{' + partial.join(',') + '}';
          gap = mind;
          return v;
        }
    }

    this.stringify = function (value, replacer, space) {	
      var i;
      gap = '';
      indent = '';

      if (typeof space === 'number') {
        for (i = 0; i < space; i += 1) 
        	indent += ' ';
      } else if (typeof space === 'string') indent = space;

      rep = replacer;
      if (replacer && typeof replacer !== 'function' &&
          (typeof replacer !== 'object' ||
           typeof replacer.length !== 'number')) throw new Error('JSON.stringify');

      return str('', {'': value});
    };

    this.parse = function (text, reviver) {
      var j;

      function walk(holder, key) {
        var k, v, value = holder[key];

        if (value && typeof value === 'object') {
          for (k in value) {
            if (Object.hasOwnProperty.call(value, k)) {
              v = walk(value, k);

              if (v !== undefined) value[k] = v;
              else delete value[k];
            }
          }
        }
        return reviver.call(holder, key, value);
      }

      cx.lastIndex = 0;
      if (cx.test(text)) {
        text = text.replace(cx, function (a) {
          return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
        });
      }

      if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
        j = eval('(' + text + ')');

        return typeof reviver === 'function' ? walk({'': j}, '') : j;
      }

      throw new SyntaxError('JSON.parse');
    };
	};
	*/
};
