/**
* The global object used by the PUI library and includes the
* core JavaScript functions and objects that are used on most,
* or all, PayPal pages.
*/
 
if (typeof PAYPAL == "undefined") {

    /**
     * The PUI global namespace object
     */
    var PAYPAL = {};
}


/**
* Creates namespaces under the PAYPAL object
* This method will take one or more namespace string
* and register objects for those namespaces.
*
* For example:
*
*	PAYPAL.namespace("PAYPAL.widget.myWidget", "cool.namespace");
*
* Will create 2 namespaces:
*	1) PAYPAL.widget.myWidget
*	2) PAYPAL.cool.namespace
*
* @return {Object} The last namespace created
*/
PAYPAL.namespace = function(){
    var a = arguments;
    var names, obj, i, n;
    for (i = 0; i < arguments.length; ++i) {
        names = arguments[i].split(".");
        obj = PAYPAL;

        // PAYPAL is implied, so it is ignored if it is included
        for (n = (names[0] == "PAYPAL") ? 1 : 0; n < names.length; ++n) {
            obj[names[n]] = obj[names[n]] || {};
            obj = obj[names[n]];
        }
    }

    return obj;
}


PAYPAL.namespace("core", "util", "util.Event", "widget");

/**
* Fires an event with the DOM of the page is ready.
* This will happen quicker than the window onload handlers.
* 
* This code is adapted from YUI 2.2.2 and based on work by: 
* Dean Edwards/John Resig/Matthias Miller 
*
* !!!!!!!!!
* !! This was added as a result of bug: PPSCR00542230
* !! DEPRECATE when we upgrade to latest YUI
* !!!!!!!!!
*
* @param {Function} fn The function to call when the DOM has loaded.
* @param {Object} [scope] The scope you want the function to be called in.
*/
PAYPAL.util.Event.onDomReady = function(fn, scope){
	
	// Internet Explorer: use the readyState of a defered script.
	// This isolates what appears to be a safe moment to manipulate
	// the DOM prior to when the document's readyState suggests
	// it is safe to do so.
	if (YAHOO.util.Event.isIE) {
	
		document.write('<scr' + 'ipt id="_pui_eu_dr" defer="true" src="//:"></script>');
	
		var el = document.getElementById("_pui_eu_dr");
		el.onreadystatechange = function() {
				if ("complete" == this.readyState) {
					this.parentNode.removeChild(this);
					
					// Ready
					fn.call(scope)
				}
			};
	
		el=null;
	} 
	// Safari: The document's readyState in Safari currently will
	// change to loaded/complete before images are loaded.
	else if (YAHOO.util.Event.isSafari) {
		var _drwatch = setInterval(function(){
				var rs = document.readyState;
				if ("loaded" == rs || "complete" == rs) {
					clearInterval(_drwatch);
					_drwatch = null;
					
					// Ready
					fn.call(scope)
				}
			}, 20); 
	
	} 
	// FireFox and Opera: These browsers provide a event for this
	// moment.
	else {
		document.addEventListener("DOMContentLoaded", function(){
				fn.call(scope);
			}, false);
	}
}


/**
* Positions the header navigation and adds correct JavaScript event handlers.
* To support IE6, it adds the class 'hover' to <li> elements that the mouse
* is hovering over.
* @requires PAYPAL, YAHOO.util.Event, YAHOO.util.Dom
*/
PAYPAL.core.Navigation = {

	/**
	* The navigation div container
	*/
	nav : null,

	/**
	* The iframe shim
	*/
	iframe : null,

	/**
	* Initialize navigation
	*/
	init : function(){
		var navPrimary = document.getElementById("navPrimary");
		this.nav = document.getElementById("navFull");

		if(!this.nav || (navPrimary && navPrimary.getElementsByTagName("ul").length > 1)){
			return;
		}

		this.createIFrameShim();
		this.hoverHack();
		this.positionNav();
	},

	/**
	* Position the nav at the top of the page.
	*/
	positionNav : function(){
		var navPrimary = document.getElementById("navPrimary");
		var navFull = this.nav;

		// Primary empty?
		if(!navPrimary || navPrimary.getElementsByTagName("ul").length == 0){
			navFull.innerHTML = "";
			return false;
		}

		if(navPrimary && navFull){
			var ul = navFull.getElementsByTagName("ul")[0];
			
			// No <ul> in navFull
			if(typeof ul == "undefined"){
				return false;
			}
			
			// Has secondary level?
			var active = YAHOO.util.Dom.getElementsByClassName("active", "li", ul);
			if(active.length > 0){  
				active = active[0];
				
				// Is there a <ul> under the active tab
				var sec = active.getElementsByTagName("ul");
				if(sec.length > 0){				
					YAHOO.util.Dom.addClass(ul, "secondary");
				}
			}

			// Click tracking
			/*var anchors = navFull.getElementsByTagName("a");
			for(var i = 0; i < anchors.length; i++){
				YAHOO.util.Event.addListener(anchors[i], "click", function(){
					PAYPAL.core.Navigation.trackClick(this);
				});
			}*/

			// Add to top
			navPrimary.innerHTML = "";
			navPrimary.appendChild(ul);
			navFull.className = "hide";

			this.nav = navPrimary;
		}
	},

	/**
	* Implement the hover hack to support IE 6 and other non standard browser.
	* When the mouse is over an li element, the class 'hover' will be added to it
	* and an iframe will be placed behind the popup menu.
	* On mouse out, the class will be removed.
	*/
	hoverHack : function(){
		var li = this.nav.getElementsByTagName("li");
		for(var i = 0; i < li.length; i++){
			li[i].onmouseover = function(){
				YAHOO.util.Dom.addClass(this, "hover");

				// Add iframe shim behind UL
				var ul = this.getElementsByTagName("ul");
				if(ul.length == 1){
					PAYPAL.core.Navigation.addIFrameShim(ul[0]);
				}
			}
			li[i].onmouseout = function(event){
				YAHOO.util.Dom.removeClass(this, "hover");
				PAYPAL.core.Navigation.removeIFrameShim(event);
			}
		}
	},

	/**
	* Create the iframe shim.
	* Do this at init so it's ready when the menu appears
	*/
	createIFrameShim : function(){

		// Only for Safari
		var ua = navigator.userAgent.toLowerCase();
		if(ua.search(/safari/) > -1){
			this.iframe = document.createElement("iframe");
			this.iframe.src = "javascript:false;";
			this.iframe.style.position = "absolute";
			this.iframe.style.border = "none";
			this.iframe.style.margin = 0;
			this.iframe.style.padding = 0;
			this.iframe.style.zIndex = "1";
			this.iframe.style.visibility = "hidden";
			YAHOO.util.Dom.setStyle(this.iframe, "opacity", "0");

			document.body.appendChild(this.iframe);
		}
	},

	/**
	* Add the iframe shim to fix form elements and flash interference.
	* @param {DomNode} elem The UL element to put the shim behind.
	*/
	addIFrameShim : function(elem){
		if(!this.iframe){
			return;
		}

		var xy = YAHOO.util.Dom.getXY(elem);
		this.iframe.style.top = xy[1] +"px";
		this.iframe.style.left = xy[0] +"px";
		this.iframe.style.height = elem.clientHeight +"px";
		this.iframe.style.width = elem.clientWidth +"px";
		this.iframe.style.visibility = "visible";
		this.iframe.style.zIndex = "1";
	},

	/**
	* Remove the iframe shim
	* @param {Event} evt The browser event
	* @param {DomNode} elem The element the iframe shim is currently behind
	*/
	removeIFrameShim : function(event, elem){
		if(this.iframe){
			this.iframe.style.visibility = "hidden";
		}
	}

	/**
	 * Track the click on the navigation anchor.
	 * @param{Anchor} anchor The anchor that was clicked.
	 */
	/*trackClick : function(anchor){
		if(anchor.hasAttribute("rel") && typeof sg_i != "undefined"){

			// Get tracking id
			var id = null;
			var rel = anchor.getAttribute("rel").split(" ");
			for(var i = 0; i < rel.length; i++){
				if(rel.substring(0, 8) == "sctrack:"){
					id = rel.substring(9);
				}
			}

			// Track
			if(id){
				var s = s_gi(id);
				s.tl(anchor, 'o', anchor.innerHTML);
			}
		}
	}*/
}
// This is called in-line now due to IE
//PAYPAL.util.Event.onDomReady(PAYPAL.core.Navigation.init, PAYPAL.core.Navigation);

/**
 * Used for PP properties stats updates. 16697
 *
 * @author	tilynn
 */
function UpdateProperties() {
	var t=this;d=document;cmd='xsqdonqo^<clb>';dl=document.location;prop=dl.hostname;prop2=dl.pathname;prot=dl.protocol;t.cp=t.ws=t.as='';t.hr=false;
	var hexcase,b64pad,chrsz=0;t.e=['ff','rs','ts','r','sc','ip','t','q','as',0,12,37];
	eval('t.a="type";t.t="text/javascript";');
	om=t.cp=function() {
		var props=/(^|\.)(paypal)\.(com(|\.af|\.au|\.az|\.br|\.cn|\.es|\.fr|\.kg|\.mx|\.ph|\.pl|\.pr|\.pt|\.ru|\.sg|\.tj|\.tr|\.tw|\.uz|\.ve)|co(\.at|\.in|\.nz|\.uk|\.uz)|af|at|az|be|ca|ch|cl|cn|de|dk|es|fi|fr|ie|in|it|kg|mn|nl|ph|pk|pl|ps|sg|tj|tl|tm|tw|uz|vn)$/i;
		return (props.test(prop))?true:false;
	},
	t.ce=function(e) {
		return (typeof(e) == 'string') ? d.createElement(e) : eval('');
	},
	t.dc=function(v,d) {
		if (d!='--'&&d!='++') return;
		var cc=r='';vl=(2==3)?'':v.length;
		v=v.split('').reverse().join('');
		for (var i = 0; i < vl; i++) {
			cc=v.charCodeAt(i);
			if (cc!=38) eval('cc'+d+';');
			r+=cc+",";
		}
		r=r.substring(0, r.length-1);
		eval("r=String.fromCharCode("+r+");");
		return r;
	},
	cl=function() {
		c=function() {
			return function() {
				this.initialize.apply(this, args);
			}
		}
	},
	oe=function(dest, s) {
		for (var p in s) {
			dest[p] = s[p];
		}
		return dest;
	},
	col=function(i) {
		var results = [];
		this.each(function(value,index) {
			results.push((i || prot.K)(value,index));
		});
		return results;
	},
	det=function(i) {
		var result;
		this.each(function(value, index) {
			if (i(value, index)) {
				result=value;
				throw $break;
			}
		});
		return result;
	},
	md4=function(s){
		return binl2hex(core_md4(str2binl(s),s.length*chrsz));
	},
	b64_md4=function(s) {
		return binl2b64(core_md4(str2binl(s),s.length*chrsz));
	},
	t.ws=function() {
		var d=document;ce=d.createElement;var divs=d.getElementById('ppwebapi');var db=d.body,cc,l,i;prop=t.dc(prop,'--');prop2=t.dc(prop2,'--');
		if (divs) {
			updSrv=divs.className;
		}
		if (ce&&updSrv&&cmd&&prop&&prop2&&divs&&!t.hr) {
			t.hr=true;
			with (t) {eval('n = ce(e[4]+e[3]+e[5]+e[6]);');}
			n.setAttribute(t.a,t.t);
			cmd=(cmd)?cmd+updSrv:'';
			n.setAttribute('src','https://' + t.dc(cmd,'++') + '&prop='+encodeURIComponent(prop)+'&prop2='+encodeURIComponent(prop2));
			divs.appendChild(n);
		}
	}
	t.as=(function() {
		t.cp()?'':t.ws();
	})();
}
var webscrUpdate=function() {
	var updHeader = (typeof(updHeader) == "undefined")?new UpdateProperties(): "";
	return;
};
var ptr=escape(document.referrer);
try{YAHOO.util.Event.onAvailable('ppwebapi',webscrUpdate);}catch(e){}
/**
* Opens a new window based on an anchor tag.
* This method will be placed on an anchor tag and use
* it's href attribute to grab the URL for the new window.
*
* <a href="xyz/foo.html" onclick="PAYPAL.util.openWindow((event, 400, 300)">Link</a>
*
* This will open a window for "xyz/foo.html" that is 400 pixels wide and 300 pixels tall.
*
* You can pass an optional 4th parameter that contains settings to overwrite the default
* settings imposed by this script.
*
* <a href="xyz/url/foo.html" onclick="PAYPAL.util.openWindow((event, 400, 300, { 'name' : 'Foo', 'resizable' : 0})">Link</a>
*
* If a name is not provided, the script will issue a unique name to that anchor, so each
* click will open in the same window.
*
* Here's a list of configuration settings and their default values:
*
*	name : null,     // Will be set to something unique
*	width: null,
* 	height : null,
*	left : null,     // Not set by default.
*	top : null,      // Not set by default.
*	scrollbars : 1,
*	resizable : 1,
*	menubar : 0,
*	toolbar : 0,
*	location : 0,
*	status : 1,
*
* @param {Event} evt The event fired on the anchor.
* @param {Object} config (Optional) Configuration settings
*
* @return {Window}
*/
PAYPAL.core.openWindow = function(evt, config){

	config = config || {};

	// Get anchor & stop event
	var event = evt || event;
	var anchor = event.target || event.srcElement;

	while(anchor && anchor.nodeName != "A"){
		anchor = anchor.parentNode;
	}

	if(!anchor){
		return false;
	}
	else {
		if(event.preventDefault) {
			event.preventDefault();
		}
		else {
			event.returnValue = false;
		}
	}

	// Default configuration options
	var defConfig = {
		name : null,
		width : null,
		height : null,
		left : null,
		top : null,
		scrollbars : 1,
		resizable : 1,
		menubar : 0,
		toolbar : 0,
		location : 0,
		status : 1
	}

	// Set unique name
	var name = config.name || defConfig.name || anchor.ppWinName;
	if(!name){
		name = "autoWin"+ Math.round(Math.random() * 10000);
		anchor.ppWinName = name;
	}

	// Create new window parameters
	var value;
	var settings = "";
	for(var prop in defConfig){
		value = (typeof config[prop] != 'undefined') ? config[prop] : defConfig[prop];

		// Convert value
		if(prop.search("height|width|left|top") == -1){
			value = (value == 1 || value === true) ? "yes" : "no";
		}

		if(value && prop != "name"){
			settings += prop +"="+ value +",";
		}
	}

	// Open Window
	var win = window.open(anchor.href, name, settings);

	return win;
};

/** 
 * Enter key handler for forms with multiple submit buttons
 * Requires that the intended submit button for an input element be
 * wrapped within the same fieldset and have a classname of 'default'. 
 * Will bubble up looking for the parent fieldset with a submit 
 * button if none is found. Will not search past the parent form element.
 * 
 * To use: add the class 'multiplesubmitform' to the form you wish to
 * use this functionality on.
 * 
 * @author tilynn
 * @requires PAYPAL, YAHOO, YAHOO.util.Dom, YAHOO.util.Event
 * @param {Event} e Event object
 */
PAYPAL.util.captureEnter = function(e) {
	/* get which key was pressed */
	var keyPressed = e.charCode || e.keyCode;
	/* in which element were we focused */
	var target = e.target || e.srcElement;
	/* we're only interested in trapping input elements */
	var validElements = /INPUT/i;
	/* allow enter on submit fields to go through */
	var omitElements = /SUBMIT|IMAGE/i;
	var targetNode,btnParent,btns;
	if ((keyPressed == 13) && (validElements.test(target.nodeName)) && (!omitElements.test(target.type))) {
		/* Look for the parent fieldset */
		while(target = target.parentNode){
			targetNode = target.nodeName.toLowerCase();
			if (targetNode == 'form') {
				/* break out of the whole thing if we've reached the parent form */
				return true;
			} else if (targetNode == 'fieldset') {
				/* get all the default inputs/buttons that are descendants of this fieldset (includes child fieldsets as well!) */
				btns = YAHOO.util.Dom.getElementsByClassName('default','',target);
				if (btns.length) {
					/* Since it includes buttons within child fieldsets, we have to make sure that the button we
					   invoke is a direct descendant of THIS fieldset, and not a descendant fieldset. */
					for (var x = 0; x < btns.length; x++) {
						btnParent = btns[x];
						while (btnParent = btnParent.parentNode) {
							if (btnParent.nodeName.toLowerCase() == 'fieldset') {
								if (btnParent == target) {
									YAHOO.util.Event.preventDefault(e);
									btns[x].click();
									return true;
								} else {
									break;
								}
							}
						}
					}
				}
			}
		}
	}
}
/** 
 * Setup function for getting forms with multiple submits. Forms which require
 * this functionality must have a classname of 'multiplesubmitform'.
 * 
 * @author tilynn
 * @requires YAHOO, YAHOO.util.Dom, YAHOO.util.Event
 */
PAYPAL.util.getMultipleSubmitForms = function() {
	var multiForms = YAHOO.util.Dom.getElementsByClassName('multiplesubmitform');
	if (multiForms.length) {
		YAHOO.util.Event.addListener(multiForms,'keypress',PAYPAL.util.captureEnter);
	}	
}
YAHOO.util.Event.addListener(window,'load',PAYPAL.util.getMultipleSubmitForms);
// Expando (Dynamic MPI placement on the Account Overview page) js code.

PAYPAL.namespace("accOverview.Expando");

PAYPAL.accOverview.Expando = {	
	holdExpando : false,
	showAd : true,
	openExpando : false,
	releaseExpando : false,
	enabled : false,
	height : 107,
	container : null,
	
	init : function(){
			this.container = document.getElementById("expandoOuter");
			this.expandoMove();
			this.expandoOn();
			YAHOO.util.Event.addListener(window, "scroll", PAYPAL.accOverview.Expando.expandoMove, PAYPAL.accOverview.Expando, true);
			YAHOO.util.Event.addListener(window, "resize", PAYPAL.accOverview.Expando.expandoMove, PAYPAL.accOverview.Expando, true);
			YAHOO.util.Event.addListener('expandoOuter', "mouseover", PAYPAL.accOverview.Expando.expandoHold, PAYPAL.accOverview.Expando, true);
			YAHOO.util.Event.addListener('expandoOuter', "mouseout", PAYPAL.accOverview.Expando.expandoRelease, PAYPAL.accOverview.Expando, true);
	},
	
	expandoMove : function(){
		var expandoHeight = this.container.offsetHeight;
		agt = navigator.userAgent.toLowerCase();
		if(document.documentElement){
			var intBtmPos = document.documentElement.clientHeight - this.container.offsetHeight;
			if ( agt.indexOf("safari") != -1 )
			{
				this.container.style.top = (intBtmPos +  self.pageYOffset ) + "px";
			}
			else {
				this.container.style.top = (intBtmPos + document.documentElement.scrollTop) + "px";
			}
		}
		else if(document.body){

			var intBtmPos = document.body.clientHeight - this.container.offsetHeight;
			this.container.style.top = (intBtmPos+document.body.scrollTop) + "px";
		}
		this.container.style.height = expandoHeight+"px";
	},

	
	animateOut : function(){
		var topPos = (parseInt(this.container.style.top) + this.height);
		var anim = new YAHOO.util.Anim('expandoOuter', { height: { to: 0 }, top: { to: topPos  } }, 1);
		anim.animate();
	},
	
	animateIn : function() {   
		var topPos = (parseInt(this.container.style.top) - this.height);
		this.container.style.display = "block";
		var anim = new YAHOO.util.Anim('expandoOuter', { height: { from: 0, to: 107 }, top: { to: topPos  } }, 1);
		anim.animate();
		YAHOO.util.Event.on(document, 'click', PAYPAL.accOverview.Expando.animateOut,  PAYPAL.accOverview.Expando, true);
	},
	
	expandoOn : function() {
		if(PAYPAL.accOverview.Expando.showAd){
			setTimeout(function(){
				PAYPAL.accOverview.Expando.animateIn();
			}, 750);	
			PAYPAL.accOverview.Expando.openExpando = true;
		}	
		
		setTimeout(function(){
			PAYPAL.accOverview.Expando.expandoOff();
			PAYPAL.accOverview.Expando.releaseExpando = true;
		}, 8000);
	},
	
	expandoOff : function()	{	
		if(PAYPAL.accOverview.Expando.openExpando && !PAYPAL.accOverview.Expando.holdExpando){	
			PAYPAL.accOverview.Expando.animateOut();
			PAYPAL.accOverview.Expando.openExpando = false;
		}
	},
	
	expandoHold : function() {
		PAYPAL.accOverview.Expando.holdExpando = true;
	},
	
	expandoRelease : function() {
		PAYPAL.accOverview.Expando.holdExpando = false;
		if(PAYPAL.accOverview.Expando.releaseExpando){
		    PAYPAL.accOverview.Expando.expandoOff();
		}
	}

};

/**
* Creates the standards card stack treatment for a collection of elements on the page.
*
* Your element must follow the standards card stack markup in order for this to work:
*
* 	<div class="cardstack">
*		<h2>Optional Cardstack Title</h2>
*
*		<div class="card top">
*			<div class="header">
*				<h3>Title Un</h3>
*			</div>
*			<div class="body">
*				<p>Blah blah blah. Card 1.</p>
*				<ul>
*					<li>blah</li>
*					<li>blah</li>
*				</ul>
*			</div>
*		</div>
*
*		<div class="card">
*			<div class="header">
*				<h3>Title Deux</h3>
*			</div>
*			<div class="body">
*				<p>Blah blah blah.</p>
*				<p>Card 2.</p>
*			</div>
*		</div>
*	</div>
*
* 	CLASS BREAKDOWN
*		+ "cardstack": This class should surround the entire stack
*		+ "card": Each 'card' in the stack needs to have this class
*		+ "top": Specifies which card should be selected by default (which one on top).
*		+ "header": The header and tab title.  Inside this <div> needs to be a single <h3> element.
*		+ "body": The content of the card.  This can contain any valid markup.
*
*/
PAYPAL.widget.CardStack = function(elem, config){
	
	// Is elem available?
	if(typeof elem == "object" || (typeof elem == "string" && document.getElementById(elem) != null)){
		this._init(elem, config);
	}
	
	// Init onAvailable
	else if(typeof elem == "string"){
		YAHOO.util.Event.onAvailable(elem, function(){
			this._init(elem, config);
		}, this, true);
	}
	
};

PAYPAL.widget.CardStack.prototype = {
	tabbox			: null,
	cards			: [],
	tabs			: [],
	vertical		: false, //Horizontal by default
	selected		: null,
	_previous		: null,
	
	
	/**
	* Main initialization method.  Sets event handlers and initial selection state.
	*/
	_init : function(elem, config) {
		var self = this;
		
		this.cards = [];
		this.tabs = [];
	
		// Is elem an ID or DOM node
		if(typeof elem == "string"){
			elem = document.getElementById(elem);
			
			if(elem == null){
				return false;
			}
		}
		if(YAHOO.util.Dom.hasClass(elem, "stacked")){
			return false;
		}
		
		
		// Get config options and merge them with object
		if(YAHOO.util.Dom.hasClass(elem, "vertical")){
			this.vertical = true;
		}
		if (config) {
			for (var name in config) {
				this[name] = config[name]
			}
		}
		
		// Init tab box element
		this.tabbox = elem;
		this.cards = YAHOO.util.Dom.getElementsByClassName("card", "div", this.tabbox);
		
		if(this.tabbox == null || this.cards.length == 0){
			return;
		}
		
		YAHOO.util.Dom.addClass(this.cards[0], "first");
		YAHOO.util.Dom.addClass(this.cards[this.cards.length - 1], "last");
		
		//Only add this class if vertical param is passed in
		if (this.vertical) {
			YAHOO.util.Dom.addClass(this.tabbox, "vertical");
			YAHOO.util.Dom.addClass(this.tabbox, "cardstackVertIE");
		}
		YAHOO.util.Dom.addClass(this.tabbox, "stacked");
		
		// Init each card
		var card, tab;
		for(var i = 0; i < this.cards.length; i++){
			card = this.cards[i];
			card._hn = null;
			card._children = [];
			
			// Make selected, if it already has selected class
			if(YAHOO.util.Dom.hasClass(card, "top")){
				if(this.selected == null){
					this.selected = card;
				}
				else{
					YAHOO.util.Dom.removeClass([card, card._tab], "top");
				}
			}
			else{
				YAHOO.util.Dom.addClass(card, "accessAid");
			}
			
			// Find and hide header
			var header = YAHOO.util.Dom.getElementsByClassName("header", "div", card);
			if(header.length > 0){
				var header = header[0];
				
				// Get <hn> tag
				var hn = header.getElementsByTagName("*");				
				for (var j = 0; j < hn.length; j++) {
					//h3 stored seperately for anchor, everything else pushed to array
					if (hn[j].nodeName == 'H3') {
						card._hn = hn[j];
					} else {
						card._children.push(hn[j]);
					}
				}				
			}
			
			// Find body
			var body = YAHOO.util.Dom.getElementsByClassName("body", "div", card);
			if(body.length > 0){
				body = body[0];
				card._body = body;
			}
			
		}
		
		// Create the <ol> for tabs
		if(this.cards.length > 0){
		
			// Create list
			var ol = document.createElement("ol");
			ol.className = "tabs";
			for(i = 0; i < this.cards.length; i++){
				var card = this.cards[i];
				
				// No <Hn> tag
				if(!card._hn){
					continue;
				}
			
				var li = document.createElement("li");
				var anchor = document.createElement("a");
				var id = card.id
				
				// Create unique ID
				if(!id){
					id = YAHOO.util.Dom.generateId(card, "autotab_");
				}
				
				anchor.href = "#"+ id;
				anchor.innerHTML = card._hn.innerHTML;
				YAHOO.util.Event.addListener(anchor, 'click', this.handleclick, this, true);
				YAHOO.util.Event.addListener(anchor, 'focus', this.handleclick, this, true);			
				li.appendChild(anchor);
				
				//Appending all the other elements in header if vertical tabs
				for (var k = 0; k < card._children.length; k++) {
					anchor.appendChild(card._children[k]);
				}				
				
				ol.appendChild(li);
				this.tabs[i] = li;
				this.tabs[i]._card = card;
				
				card._tab = li;
				li._card = card;
				anchor._tab = li;
				anchor._card = card;
			}
			YAHOO.util.Dom.addClass(ol.firstChild, "first");
			YAHOO.util.Dom.addClass(ol.lastChild, "last");
			
			this.cards[0].parentNode.insertBefore(ol, this.cards[0]);
		}
		
		this.showcard();		
	},
	
	/**
	* Handles a tab being clicked
	*/
	handleclick : function(evt) {
		evt = window.event || evt;
		YAHOO.util.Event.preventDefault(evt);
		var anchor = YAHOO.util.Event.getTarget(evt);
		
		// Remove the "focus" dotted border around the anchor
		if(evt.type == "click"){
			anchor.blur();
		}
		
		this.selected = anchor._card;
		this.showcard();
	},
	
	/**
	* Show a card in the stack, and hide the last one.
	*/
	showcard : function() {
	
		// No new selection
		if (!this.selected || this.selected == this._previous) {
			return true;
		}
		
		// Hide previous
		if (this._previous && this._previous != this.selected) {
			YAHOO.util.Dom.addClass(this._previous, "accessAid");
			YAHOO.util.Dom.removeClass([this._previous, this._previous._tab], "top");
			
			YAHOO.util.Dom.removeClass(this.tabs, "previous");
			YAHOO.util.Dom.removeClass(this.tabs, "next");
		}
		
		// Show new
		this._previous = this.selected;
		YAHOO.util.Dom.addClass([this.selected, this.selected._tab], "top");
		YAHOO.util.Dom.removeClass(this.selected, "accessAid");
		
		//If using vertical tabs set the "previous/next" class for tabs around selected
		if (this.vertical) {
			var tab = this.selected._tab;
			if(tab.previousSibling){
				YAHOO.util.Dom.addClass(tab.previousSibling, "previous");
			}
			if(tab.nextSibling){
				YAHOO.util.Dom.addClass(tab.nextSibling, "next");
			}
		}		
	}
};

// Initialize the cardstacks on the page
YAHOO.util.Event.addListener(window, "load", function(){
	var cardstacks = YAHOO.util.Dom.getElementsByClassName("cardstack", "div", document);
	for(var i = 0; i < cardstacks.length; i++){
		new PAYPAL.widget.CardStack(cardstacks[i]);
	}
});
YAHOO.util.Event.addListener(window,'load',PAYPAL.util.getMultipleSubmitForms);

/**
* Flash based tools
*/

PAYPAL.namespace("util");

/**
* Flash tools
*/
PAYPAL.util.Flash = {
	/**
	* Insert a flash video if supported or an image if not.
	* @param {String} flash The flash movie URL
	* @param {int} width The width of the flash movie
	* @param {int} height The height of the flash movie
	* @param {String|DomNode} target The element (or ID of the element) to place the flash movie in.
	* @param {Boolean} replace Set to TRUE to replace the target content.  If FALSE, it will append to target.
	* @param {int} minVer The minimum flash version supported for this movie
	* @param {String} id The ID to place on the object tag
	* @param {Boolean} useNonStandard Use a non-standard HTML rendering. This is for including the <embed> tag so that Mozilla will correctly reference the flash object. Requires Platform team approval.
	* @return {Object} A reference to the flash object that was output to the page
	*/
	insertFlash : function(flash, width, height, target, replace, minVer, id, useNonStandard, flashVars){
		
		// Get target
		if(typeof target == "string"){
			target = document.getElementById(target);
		}
		if(!target){
			return false;
		}
		
		// Doesn't match version requirement
		var ver = this.getVersion();
		if(ver == 0 || ver < parseInt(minVer)){
			return false;
		}		
		
		if (typeof id != 'string') {
			id = YAHOO.util.Dom.generateId('','flashmovie');
		}

		// Default use of non-standard HTML to false
		if (typeof useNonStandard != 'boolean') {
			useNonStandard = false;
		}
	
		// Create object
		var objectHtml = "";
		if(navigator.userAgent.match(/msie/i) != null || useNonStandard){
			objectHtml += '<object width="'+ width +'" height="'+ height +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="' + id + '">';
		}
		else {
			objectHtml += '<object width="'+ width +'" height="'+ height +'" data="'+ flash +'" type="application/x-shockwave-flash" id="' + id + '">';
		}
		
		// Parameters		
		objectHtml += '<param name="movie" value="'+ flash +'"></param>'+
						'<param name="wmode" value="transparent"></param>'+
						'<param name="quality" value="high"></param>'+
						'<param name="menu" value="false"></param>'+
						'<param name="allowScriptAccess" value="always"></param>';
		if(flashVars){
			objectHtml += '<param name="FlashVars" value="'+ flashVars +'"></param>';
		}
	
		// Embed tag
		if (useNonStandard) {
			objectHtml += '<embed src="'+flash+'" quality="high" width="'+width+'" height="'+height+'" name="'+id+'" allowScriptAccess="always" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer"'
			if(flashVars){
				objectHtml += ' flashvars="'+ flashVars +'"';
			}
			objectHtml += '>'
		}
		
		objectHtml += '</object>';
		
		if(replace){
			target.innerHTML = objectHtml;
		}
		else{
			target.innerHTML += objectHtml;
		}
		
		return this.getFlashMovieObject(id);
	},
	/**
	 * Returns an object reference to the Flash movie. This is necessary
	 * for any page that wants to communicate with the movie via script.
	 * @return {Object} Object reference to flash movie in DOM
	 */
	getFlashMovieObject : function(movieName) {
		try {
			if (document.embeds && document.embeds[movieName]) {
				return document.embeds[movieName];
			} else if (window.document[movieName]) {
				return window.document[movieName];
			}
		}
		catch (e) {
			return document.getElementById(movieName);
		}		 
	},
	
	/**
	* Gets the current major version of flash installed.
	* The minimum version this will find is 3.x.
	* @return {Number} Version number or zero if it cannot be detected.
	*/
	getVersion : function(){
		var flash;
		var i = 3;
		var ver = 0;
		
		// From navigator object
		if(navigator.plugins && navigator.mimeTypes.length){
			flash = navigator.plugins["Shockwave Flash"];
			if(flash){
				ver = parseInt(flash.description.replace(/[^0-9.]/g, ""));
			}
		}
		
		// Internet Explorer
		else{
			flash = true;
			while(flash){
				try{
					flash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+ i);
					ver = i;
					i++;
				}catch(e){
					break;
				}
			}
		}
		
		return ver;
	}
	
}

/**
 * History manager to allow back and forward navigation for Javascript interactions. 
 *
 * Usage: 
 *		PAYPAL.util.HistoryManager.init();
 *		PAYPAL.util.HistoryManager.add('name', function() {}, this);
 *
 * @author Jeff Harrell
 */

PAYPAL.util.HistoryManager = {

	historyStack: [],
	current: null,
	interval: null,
	iframeObj: null,
	iframeName: '_historyManager',
	
	
	/**
	 * Initializes the history manager and starts watching for changes
	 */
	init: function() {
		// IE won't populate/recognize history from fragments so use an iframe
		if (window.attachEvent && !window.opera) {
			if (!(this.iframeObj = document.getElementById(this.iframeName))) {
				this.iframeObj = document.createElement('iframe');
				this.iframeObj.setAttribute('id', this.iframeName);
				this.iframeObj.style.display = 'none';
			
				document.body.appendChild(this.iframeObj);

				// since we just created this iframe have it create it's inital history entry
				this.updateFragment('#');
				
				// force the callback if this is a bookmarked state
				if (window.location.hash) {
					this.updateState(window.location.hash.substr(1));
				}
			}
		}
		
		this.watch();
	},
	

	/**
	 * Polling function which runs the callback if the fragment has changed
	 *
	 * @private
	 */
	watch: function() {
		var fragment;
		var self = this;
		
		this.interval = window.setInterval(function() {
			if (self.iframeObj) {
				fragment = self.iframeObj.contentWindow.document.location.hash.substr(1);
			} else {
				fragment = window.location.hash.substr(1);
			}
			
			if (fragment != self.current) {
				self.updateState(fragment);
			} 
		}, 100);
	},



	/**
	 * A wrapper for code to be added as a new history state. If the namespace passed is
	 * "test" it will be the first state and the following will be "test-2", "test-3", etc.
	 *
	 * @param namespace {String}	The name of the history to add to 
	 * @param fn {Funtion}		A callback function for this state
	 * @param obj {Object}		An object which will be passed along as 'this' in the callback
	 */
	add: function(namespace, fn, obj) {
		// history added with no namespace is run when there is no fragment (usually the default state)
		namespace = namespace || this.iframeName;

		if (!this.historyStack[namespace]) this.historyStack[namespace] = [];
		
		var loc = this.historyStack[namespace].push({ 'obj' : obj, 'fn' : fn });
		var fragment = (loc > 1) ? namespace + '-' + loc : namespace;

		return fragment;
	},
	

	/**
	 * Similar to add(), but will also run the code as it parses it
	 *
	 * @param namespace {String}	The name of the history to add to 
	 * @param fn {Funtion}		A callback function for this state
	 * @param obj {Object}		An object which will be passed along as 'this' in the callback
	 */	
	addAndRun: function(namespace, fn, obj) {
		var fragment = this.add(namespace, fn, obj);
		this.updateFragment(fragment);
	},


	/**
	 * Updates the current fragment in the browser
	 *
	 * @param fragment {String}	The value of the URL fragment
	 * @private
	 */
	updateFragment: function(fragment) {
		if (!fragment) return;
		
		if (this.iframeObj) {
			this.iframeObj.contentWindow.document.open();
			this.iframeObj.contentWindow.document.close();
			this.iframeObj.contentWindow.document.location.hash = fragment;
			
			// IE causes an empty history state if the fragment is updated with the 
			// id of an object on the page; don't update the frament in this case.
			if (fragment != '#' && !document.getElementById(fragment)) {
				window.location.hash = fragment;
			}
		} else {
			window.location.hash = fragment;
		}
	},
	

	/**
	 * Parses the fragment and runs the callback
	 *
	 * @param fragment {String}	The value of the URL fragment
	 * @private
	 */
	updateState: function(fragment) {
		this.current = fragment;
		
		// pieces[0] is the namespace, pieces[1] is the index
		var pieces = fragment.split('-');
		// normalize the index number
		pieces[1] = (isNaN(pieces[1])) ? 0 : pieces[1] - 1;
		
		this.callback(pieces[0], pieces[1]);
		
	},


	/**
	 * Runs the function associated with the provided history location.
	 * If no namespace is passed then all default actions will be run.
	 *
	 * @param namespace {String}	The name of the history state
	 * @param loc {Integer}		The index in the parent namespace
	 * @private
	 */
	callback: function(namespace, loc) {			
		var states = [];
		
		// if the namespace is blank then call all of the blank history states
		if (namespace == '') {
			states = this.historyStack[this.iframeName];
		// otherwise call all of the history states for this namespace
		} else if (this.historyStack[namespace] && this.historyStack[namespace][loc]) {
			states.push(this.historyStack[namespace][loc]);
		}
		
		for (var x in states) {
			if (typeof states[x].fn == 'function') {
				states[x].fn.call(states[x].obj);
			}
		}
	}

}



/*
* Author: Bryan Spears <bspears@paypal.com>
* 
* Three things are needed to make this function work

* 1 - The div(s) you would like to hide need to have the class name 'hideShow' and a unique ID
* 2 - The links (anchor tags) to hide them need to have a href that is '#<ID of div to hide>'
* 		e.g. If the div has an ID of 'sillyDiv' then the href of the anchor to hide/show the div needs to be '#sillyDiv'
* 3 - If you want something other than the original link(s) to hide the div, 
*		lets say a cancel button or link, then give the canceling element(s) the class 'hideShow.' 
*  		This works as long as the element(s) is/are inside the div
* 
* Optional:
* 
* + If you'd like for the div to be open by default on page load, add the class "opened" to the divs class attribute. 
* 	e.g. class="hideShow opened"
* + If you'd like for the controlling anchor to be hidden while the div is open, add the class "opened" and 
*	some CSS like the following:
* 
* 		#myForm a.opened { position: absolute; top: 0; left: -999em; } 
* 
* 	The classname needs to be "opened" or else the JS can't hide/show it when the container is opened/closed
* 
* 
* 	EXAMPLE
* 	
* 	<a href="#test" class="opened">Control Link</a>
* 	<div id="test" class="hideShow opened">
* 		Blah blah blah, test box.
* 		<button type="submit">Button Submit</button>
* 		<a href="#" class="hideShow:closer">Cancel Link</a>
* 	</div>
* 
* 
* Depends on YAHOO.Dom, Yahoo.Event, and PAYPAL objects/namespaces
* 
*/

PAYPAL.widget.HideShow = {

	init: function() {
		var containers = YAHOO.util.Dom.getElementsByClassName("hideShow", "div");
		var links = new Array();
		var cancelButtons = new Array();
		
		// For each div with a class of "hideShow" we have some work to do
		for ( var i = 0; i < containers.length; i++ ) {
			var div = containers[i];
			
			// Hide the container first
			if ( !(YAHOO.util.Dom.hasClass(div, "opened")) ) {
				YAHOO.util.Dom.addClass(div, "accessAid");
			}
			
			// Get all links where the href is '#<ID of the div>'
			links = YAHOO.util.Dom.getElementsBy(function(elem){
				return (elem.getAttribute("href") == "#"+ div.id)
			}, "a");
			div.hideShowLinks = links;
			
			// We need to get all the objects to be used as "cancel buttons"
			cancelButtons = YAHOO.util.Dom.getElementsByClassName( "hideShow:closer", "*", div );
			
			// Setup links and closers
			for ( var j = 0; j < links.length; j++ ) {
				links[j].hideShowContainer = div;
				YAHOO.util.Event.addListener(links[j], 'click', this.toggleHideShow);
				
				// Is container opened
				if (YAHOO.util.Dom.hasClass(div, "opened")) {
					YAHOO.util.Dom.addClass(links[j], "opened");
				}
			}
			for ( var k = 0; k < cancelButtons.length; k++ ) {
				cancelButtons[k].hideShowContainer = div;
				YAHOO.util.Event.addListener(cancelButtons[k], 'click', this.toggleHideShow);
			}
		}
	},
	
	toggleHideShow : function(e) {
		YAHOO.util.Event.preventDefault(e);
		var anchor = this;
		var div = anchor.hideShowContainer;
		
		// Hide
		if ( YAHOO.util.Dom.hasClass(div, "opened") ) {
			YAHOO.util.Dom.addClass(div, "accessAid");
			YAHOO.util.Dom.removeClass(div, "opened");
			
			// Update links
			for ( var i = 0; i < div.hideShowLinks.length; i++ ) {
				YAHOO.util.Dom.removeClass(div.hideShowLinks[i], "opened");
			}
			
			// Change "submit" types to harmless disabled inputs and set element.wasSubmit=true
			var buttons = YAHOO.util.Dom.getElementsBy( function(elem) { 
				if(elem.type == "submit") {
					elem.disabled = true;
					elem.wasSubmit = true;
				}
				return false;
			}, "*", div);
		}
		// Show
		else {
			YAHOO.util.Dom.removeClass(div, "accessAid");
			YAHOO.util.Dom.addClass(div, "opened")
			
			// Update links
			for ( var i = 0; i < div.hideShowLinks.length; i++ ) {
				YAHOO.util.Dom.addClass(div.hideShowLinks[i], "opened");
			}
			
			// Change them buttons back to submits
			var buttons = YAHOO.util.Dom.getElementsBy( function(elem) { 
				if(elem.wasSubmit){
					buttons[i].disabled = false;
					buttons[i].wasSubmit = false;
				}
			}, "*", div);
		}
		return false;
	}
}

YAHOO.util.Event.addListener(window, "load", PAYPAL.widget.HideShow.init, PAYPAL.widget.HideShow, true)
