var Nav = Class.create();Nav.prototype = {	initialize: function(container) {		this.container = $('nav');		this.togglers  = this.container.childElements('li');		this.tabs      = this.container.childElements('div.callout');		this.setup();	},	setup: function() {		this.togglers.each(function(el, i) {			if (el.down('a.tab')) {				Event.observe(el, 'mouseenter', this.open.bindAsEventListener(this, i));				Event.observe(el, 'mouseleave', this.hide.bindAsEventListener(this, i));			}		}.bind(this));	},	open: function(event, i) {		this.timeout = setTimeout(this.show.bind(this,i), 100);		Event.stop(event);	},	show: function(i) {		for(var j=0, l=this.togglers.length; j<l; j++){			this.togglers[j].style.zIndex = 1;		}		this.load(this.togglers[i]);		this.togglers[i].style.zIndex = 5;		this.togglers[i].className = 'active';		clearTimeout(this.timeout);			},	hide: function(event, i) {		if (this.timeout) {			clearTimeout(this.timeout);		}		this.togglers[i].className = '';		Event.stop(event);	},	load: function(tab) {		var target = tab.down('div.progress');		if (!target) return;				switch(tab.id) {			case 'account' :				new Ajax.Updater(target, '/ae/control/myAccountTab',					{ method: 'get', onComplete:Element.removeClassName(target, 'progress') });				break;			case 'reorder' :				new Ajax.Updater(target, '/ae/control/reorderCenterTab',					{ method: 'get', onComplete:Element.removeClassName(target, 'progress') });				break;		}	}}/*--------------------------------------------------------------------------*/var Tabs = Class.create();Tabs.prototype = {	initialize: function(container, active) {		this.container = $(container);		this.togglers  = this.container.getElementsBySelector('ul.togglers li');		this.tabs      = this.container.getElementsBySelector('div.tab');		this.active    = active || 0;		this.setup();	},	setup: function() {		this.tabs[this.active].addClassName('active');		this.togglers[this.active].addClassName('active');		this.togglers.each(function(el, i) {			el.onclick = function() {				if (i != this.active) {					el.addClassName('active');					this.togglers[this.active].removeClassName('active');										if(this.tabs.length == this.togglers.length){						this.tabs[this.active].removeClassName('active');						this.tabs[i].addClassName('active');					}				}				this.active = i;				return false;			}.bind(this);		}.bind(this));	}}/*--------------------------------------------------------------------------*/var MiniCart = Class.create();MiniCart.prototype = {	initialize: function() {		this.container = $('miniCart');		this.checkout  = this.container.down('span.checkout');		this.total     = this.container.down('span.total');		this.setup();	},	setup: function() {		var sessionId    = Cookie.get('JSESSIONID');		var shoppingCart = Cookie.get('ShoppingCart');		if (shoppingCart) {			var matches = shoppingCart.match(/^QTY:([^|]+)\|TOTAL:([^|]+)\|JSESSIONID:([^|]+)$/);			if (!sessionId || (sessionId != matches[3])) {				Cookie.erase('ShoppingCart');			} else if (matches[1] > 0) {				this.total.innerHTML    = '(' + Format.dollar(matches[2]) + ')';				this.checkout.innerHTML = '<a href="/ae/control/checkout">Checkout</a>';			} else {				this.total.innerHTML    = '';				this.checkout.innerHTML = 'Checkout';			}		}	}}/*--------------------------------------------------------------------------*/// Prototype-based javascript window dimensions// http://textsnippets.com/posts/show/835Position.GetWindowSize = function(w) {	w = w ? w : window;	var width = w.innerWidth || (w.document.documentElement.clientWidth || w.document.body.clientWidth);	var height = w.innerHeight || (w.document.documentElement.clientHeight || w.document.body.clientHeight);	return [width, height];}/*--------------------------------------------------------------------------*/// Center a DOM element, prototype based// http://textsnippets.com/posts/show/836Position.Center = function(element, parent) {	var w, h, pw, ph;	w = element.offsetWidth;	h = element.offsetHeight;	Position.prepare();	if (!parent) {		var ws = Position.GetWindowSize();		pw = ws[0];		ph = ws[1];	} else {		pw = parent.offsetWidth;		ph = parent.offsetHeight;	}	element.style.top = Math.round(Position.deltaY + 130) + 'px';	element.style.left = Math.round((pw/2) - (w/2) -  Position.deltaX) + "px";}/*--------------------------------------------------------------------------*/var PopUp = Class.create();PopUp.i = 0;PopUp.prototype = {	initialize: function(trigger, popup) {		PopUp.open   = false;		this.trigger = trigger;		this.popup   = $(popup);		this.options = Object.extend({}, arguments[2] || {});		this.start();	},	start: function() {		if (this.trigger instanceof Array) {			this.triggers = this.trigger;		} else {			this.triggers = [this.trigger];		}				this.popup.hide();				this.triggers.each(function(t) {			Event.observe(t, 'click', this.openInternal.bindAsEventListener(this));		}.bind(this));	},	openInternal: function(event) {		this.toTop();		Position.Center(this.popup, $('container'));				this.closebtn  = this.popup.getElementsBySelector('.close').first();		this.handle    = this.popup.getElementsBySelector('.tbar').first();		this.draggable = new Draggable(this.popup, {handle: this.handle, starteffect: false, endeffect: false });				this.closeListener = this.closeInternal.bindAsEventListener(this);		Event.observe(document, 'click', this.closeListener);		Event.observe(this.closebtn, 'click', this.closeListener);		Event.observe(this.popup, 'click', function(event) {			this.falseAlarm = true;			this.toTop();		}.bind(this));		Event.stop(event);				if (PopUp.open) { PopUp.open.closeInternal(false); }		PopUp.open = this;				(this.options.onOpen || Prototype.emptyFunction)();	},	closeInternal: function(event) {		if (this.falseAlarm) {			this.falseAlarm = false;			return;		}				PopUp.open = false;		this.popup.hide();				this.draggable.destroy();				Event.stopObserving(document, 'click', this.closeListener);		Event.stopObserving(this.closebtn, 'click', this.closeListener);		Event.stop(event);				(this.options.onClose || Prototype.emptyFunction)();	},	toTop: function() {		PopUp.i = PopUp.i + 1;		this.popup.style.zIndex = PopUp.i + 120;		this.popup.show();	}}/*--------------------------------------------------------------------------*/var ForgotPassword = Class.create();Object.extend(Object.extend(ForgotPassword.prototype, PopUp.prototype), {	initialize: function(trigger, popup) {		this.trigger = trigger;		this.popup   = $(popup);		this.options = {			onOpen: this.open.bind(this)		}		this.start();	},	open: function() {		this.popup.removeClassName('successful');		this.popup.removeClassName('failure');		this.form = this.popup.getElementsBySelector('form').first();		this.validation = new Validation(this.form);		this.validation.reset();		if (this.setup_complete) return;		this.setup_complete = true;		Event.observe(this.form, 'submit', function(event) {			if(this.validation.validate()){				var myAjax = new Ajax.Request('/ae/control/forgotpassword',					{ method: 'post', parameters: Form.serialize(this.form), onComplete: this.showResponse.bind(this) });			}			Event.stop(event);		}.bind(this));	},	showResponse: function(request) {		if (request.responseText) {			var response = request.responseText.evalJSON();			var status = response.message;			if(status=='undefined' || status==null){				status = response.status;			}			if (status == 'SUCCESS') {				this.popup.addClassName('successful');			} else {				this.popup.addClassName('failure');			}		}	}});/*--------------------------------------------------------------------------*/var Subscriber = Class.create();Object.extend(Object.extend(Subscriber.prototype, ForgotPassword.prototype), {	open: function() {		this.popup.removeClassName('successful');		this.popup.removeClassName('failure');		this.form = this.popup.getElementsBySelector('form').first();		this.validation = new Validation(this.form);		this.validation.reset();		if (this.setup_complete) return;		this.setup_complete = true;		Event.observe(this.form, 'submit', function(event) {			if(this.validation.validate()){				var myAjax = new Ajax.Request('/ae/control/newsletterSubscription',					{ method: 'post', parameters: Form.serialize(this.form), onComplete: this.showResponse.bind(this) });			}			Event.stop(event);		}.bind(this));	}});/*--------------------------------------------------------------------------*/var Highlights = Class.create();Highlights.prototype = {	initialize: function(container) {		this.container = $(container);		this.container && this.setup();	},	setup: function() {		var items = $$('.item');		items.each(function(el) {			Event.observe(el, 'mouseover', function() {				Element.addClassName(el, 'active');			});			Event.observe(el, 'mouseout', function() {				Element.removeClassName(el, 'active');			});			Event.observe(el, 'click', function() {				var link = el.getElementsByTagName('a')[0]				document.location.href = link.href;			});		});	}}/*--------------------------------------------------------------------------*/// Read and write cookies// http://wiki.script.aculo.us/scriptaculous/show/Cookievar Cookie = {	set: function(name, value, daysToExpire) {		var expire = '';		if (daysToExpire != undefined) {			var d = new Date();			d.setTime(d.getTime() + (86400000 * parseFloat(daysToExpire)));			expire = '; expires=' + d.toGMTString();		}		return (document.cookie = escape(name) + '=' + escape(value || '') + expire + '; path=/');	},	get: function(name) {		var cookie = document.cookie.match(new RegExp('(^|;)\\s*' + escape(name) + '=([^;\\s]*)'));		return (cookie ? unescape(cookie[2]) : null);	},	erase: function(name) {		var cookie = Cookie.get(name) || true;		Cookie.set(name, '', -1);		return cookie;	},	accept: function() {		if (typeof navigator.cookieEnabled == 'boolean') {			return navigator.cookieEnabled;		}		Cookie.set('_test', '1');		return (Cookie.erase('_test') === '1');	}}/*--------------------------------------------------------------------------*/// Prototype's EventObserver fires only once when observing radio buttons// http://dev.rubyonrails.org/ticket/7895Form.Element.RadioEventObserver = Class.create();Form.Element.RadioEventObserver.prototype = Object.extend(new Abstract.EventObserver(), {	initialize: function(form, name, callback) {		this.elements = [];				myElements = Form.getElements(form);		for (var i = 0; i < myElements.length; i++) {			if ((myElements[i].type == 'radio') && (myElements[i].name == name)) {				this.elements.push(myElements[i]);			}		}				this.callback = callback;		this.lastValue = this.getValue();		for (var i = 0; i < this.elements.length; i++) {			this.registerCallback(this.elements[i]);		}	},		getValue: function() {		for (var i = 0; i < this.elements.length; i++) {			var value = Form.Element.getValue(this.elements[i]);			if (value) {				return value;			}		}	},		onElementEvent: function() {		var value = this.getValue();		if (this.lastValue != value) {			for (var i = 0; i < this.elements.length; i++) {				if (Form.Element.getValue(this.elements[i])) { 					this.callback(this.elements[i], value);				}			}			this.lastValue = value;		}	}});/*--------------------------------------------------------------------------*/// Scroll to an element inside an overflow:auto container.// http://elia.wordpress.com/2007/01/18/overflow-smooth-scroll-with-scriptaculous/Effect.MoveTo = Class.create();Object.extend(Object.extend(Effect.MoveTo.prototype, Effect.Base.prototype), {	initialize: function(element) {		this.element = $(element);		var options = Object.extend({			x: 0,			y: 0,			to_element: null,			mode: 'absolute'		} , arguments[1] || {} );		this.start(options);	},	setup: function() {		if (this.options.continuous && !this.element._ext ) {			this.element.cleanWhitespace();			this.element._ext=true;			this.element.appendChild(this.element.firstChild);		}		this.originalLeft=this.element.scrollLeft;		this.originalTop=this.element.scrollTop;		if (this.options.to_element) {			toElement=$(this.options.to_element)			container_dims=this.element.getDimensions()			to_element_dims=toElement.getDimensions()			Position.prepare();			containerOffset = Position.cumulativeOffset(this.element);			elementOffset = Position.cumulativeOffset(toElement);			this.options.x=this.options.x+elementOffset[0]-containerOffset[0]-(container_dims.width/2 - to_element_dims.width/2)			this.options.y=this.options.y+elementOffset[1]-containerOffset[1]-(container_dims.height/2 - to_element_dims.height/2)		}		if(this.options.mode == 'absolute') {			this.options.x -= this.originalLeft;			this.options.y -= this.originalTop;		}	},	update: function(position) {		this.element.scrollLeft = this.options.x * position + this.originalLeft;		this.element.scrollTop = this.options.y * position + this.originalTop;	}});/*--------------------------------------------------------------------------*/Effect.Persistent = Class.create();Effect.Persistent.prototype = {	initialize: function(element, container) {		this.element   = $(element);		this.container = $(container);		this.setup();	},	setup: function() {		Event.observe(window, 'scroll', this.test.bind(this));	},	test: function() {		if (this.timeout) {			clearTimeout(this.timeout);		} else {			Position.prepare();			this.startY = Position.deltaY;		}		this.timeout = setInterval(this.slide.bind(this), 300);	},	slide: function() {		Position.prepare();		if (this.startY == Position.deltaY) {			clearInterval(this.timeout);			this.timeout = null;			this.move(Position.deltaY)		}		this.startY = Position.deltaY;	},	move: function(y) {		Position.prepare();		var pos       = Position.cumulativeOffset(this.element.up());		var height    = this.element.getHeight();		var maxHeight = this.container.getHeight();				if (y + height > maxHeight) {			new Effect.Move(this.element, {x:0, y: maxHeight - height - 30, mode: 'absolute'});		} else if (y > (pos[1] - 10)) {			new Effect.Move(this.element, {x:0, y: y - (pos[1] - 10), mode: 'absolute'});		} else {			new Effect.Move(this.element, {x:0, y: 0, mode: 'absolute'});		}	}}/*--------------------------------------------------------------------------*/var Format = {	dollar: function(num) {		num = num.toString().replace(/\$|\,/g,'');		if(isNaN(num)) { num = "0"; }		sign = (num == (num = Math.abs(num)));		num = Math.floor(num*100+0.50000000001);		cents = num%100;		num = Math.floor(num/100).toString();		if(cents<10) { cents = "0" + cents; }		for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++) {			num = num.substring(0,num.length-(4*i+3))+','+num.substring(num.length-(4*i+3));		}		return (((sign)?'':'-') + '$' + num + '.' + cents);	},	bytes: function(size) {		var str = 'bytes';		if (size > 1024 + 256) { size /= 1024; str = 'KB'; }		if (size > 1024 + 256) { size /= 1024; str = 'MB'; }		if (size > 1024 + 256) { size /= 1024; str = 'GB'; }		if (size > 1024 + 256) { size /= 1024; str = 'TB'; }		size = Math.round(size * 100) / 100;		return size + ' ' + str;	}}/*--------------------------------------------------------------------------*/// Returns the value of the selected radio button in the radio group, null if// none are selected, and false if the button group doesn't exist// http://aaron.xavisys.com/using-prototype-javascript-to-get-the-value-of-a-radio-group/function $RF(el, radioGroup) {	if($(el).type && $(el).type.toLowerCase() == 'radio') {		var radioGroup = $(el).name;		var el = $(el).form;	} else if ($(el).tagName.toLowerCase() != 'form') {		return false;	}	var checked = $(el).getInputs('radio', radioGroup).find(		function(re) { return re.checked; }	);		return (checked) ? $F(checked) : null;}/*--------------------------------------------------------------------------*/Event.onDOMReady(function(){	new Nav('nav');		if ($('miniCart')) {		new MiniCart();	}		if($('searchBtn')){		$('searchBtn').onclick = function(){			$('search').submit();		}	}		if($('forgotCallout')) {		new ForgotPassword($$('a.forgot'), 'forgotCallout');	}		if ($('subscribeLink') && $('subscribeCallout')) {		new Subscriber('subscribeLink', 'subscribeCallout');	}		if ($('holidayLink') && $('holidayCallout')) {		new PopUp('holidayLink', 'holidayCallout');	}		if ($('examplesLink') && $('examplesCallout')) {		new PopUp('examplesLink', 'examplesCallout');	}		if ($('itemList')) {		new Highlights('itemList');	}});