	// handy - !!(typeof(object) != undefined) == isset('object');
	// note ... does not work on anonymous stuff .. must be root level/have namespace assigned
		var isset = function(obj) { return (typeof(window[obj]) != 'undefined'); }




	// support image rollovers by file naming convention, and menu behaviours.
		var setRollovers = function() {
		// permits you to spoof url, to allow pages with non-matching urls to highlight links.
			var spoofLoc = document.body.getAttribute('spoofloc');
			if (spoofLoc) { window.spoofUrl = document.location.href.substring(0, document.location.href.lastIndexOf('/')) + '/' + spoofLoc; }
			window.spoofUrl = window.spoofUrl || document.location.href;
		// url stripping function
			var bareUrl  = function(string) {
				string   = string.substring(string.lastIndexOf('#'));
				string   = string.substring(string.lastIndexOf('?'));
				return string;
			}
		// makes image current state
			var makeCurrent = function(imgObj) {
				imgObj.onmouseover();
				imgObj.onmouseover = null;
				imgObj.onmouseout  = null;
			}
			var allImages = document.getElementsByTagName('img');
			for (var i = 0; i < allImages.length; i++) {
				var thisImage = allImages[i];
			// get complete image src, make sure you extract src from MS filter in case image has been converted for ie 6
				if (thisImage.style.filter && thisImage.style.filter.indexOf('(src=\'') != -1 && thisImage.style.filter.indexOf('\', sizingMethod=') != -1 ) {
					var imgSrc = thisImage.style.filter.split('(src=\'')[1].split('\', sizingMethod=')[0]
				} else {
					var imgSrc = thisImage.src;
				}
			// extract path, file, parentNode
				var thisPath        = imgSrc.substring(0, (imgSrc.lastIndexOf('/')+1));
				var thisFile        = imgSrc.substring(imgSrc.lastIndexOf('/')+1);
				var thisParent      = thisImage.parentNode;
				var thisGrandParent = thisParent.parentNode;
				var isNavList       = (thisParent.nodeName == 'A' && thisGrandParent.nodeName == 'LI');
			// check for rollover naming convention
				if ((/_off$/.test(thisFile.split('.')[0])) || (/_ovr$/.test(thisFile.split('.')[0]))) {
			// set over and out image states
					thisImage.setAttribute('isnavlist', isNavList);
					thisImage.setAttribute('imagpath', thisPath);
					thisImage.setAttribute('ovrimage', thisFile.split('_off.').join('_ovr.'));
					thisImage.setAttribute('offimage', thisFile);
				// set over/out events
					thisImage.ovrState = function() {
						this.src = this.getAttribute('imagpath') + this.getAttribute('ovrimage');
						if (isset('makePngIe6Friendly')) { makePngIe6Friendly(this); }
					}
					thisImage.outState = function() {
						this.src = this.getAttribute('imagpath') + this.getAttribute('offimage');
						if (isset('makePngIe6Friendly')) { makePngIe6Friendly(this); }
					}
					thisImage.onmouseover = function() {
						if (this.getAttribute('isnavlist') == 'true') {
							var listItems = this.parentNode.parentNode.parentNode.getElementsByTagName('li');
							for (var ii = 0; ii < listItems.length; ii++) {
								var otherImg = listItems[ii].getElementsByTagName('img')[0]; // slower, but safer
								if (otherImg.getAttribute('offimage') && otherImg !== this) { otherImg.outState(); }
							}
						}
						this.ovrState();
					}
					thisImage.onmouseout  = function() {
						if (this.getAttribute('isnavlist') == 'true') {
							var listItems = this.parentNode.parentNode.parentNode.getElementsByTagName('li');
							for (var ii = 0; ii < listItems.length; ii++) {
								var otherImg = listItems[ii].getElementsByTagName('img')[0]; // slower, but safer
								if (otherImg.getAttribute('offimage') && otherImg.getAttribute('isCurrent') == 'true') { otherImg.ovrState(); }
							}
						}
						this.outState();
					}
				// if image is a link, and we are at the link destination, set over state and remove over/out events
					if (thisImage.parentNode && thisImage.parentNode.nodeName == 'A') {
						var linkURL = thisImage.parentNode.href;
						var linkANC = linkURL.split('#')[1] || false;
						var pageURL = spoofUrl;
						var pageANC = pageURL.split('#')[1] || false;
						if (linkANC) {
						// for anchor links, link must be an exact match
							if (linkURL == pageURL) {
								thisImage.setAttribute('isCurrent', 'true');
								makeCurrent(thisImage);
							}
						} else {
						// for page links, link match can exclude anchor
							if (pageURL.indexOf(linkURL) == 0) {
								thisImage.setAttribute('isCurrent', 'true')
								makeCurrent(thisImage);
							}
						}
					}
				}
			}
		}




	// add tab switching support for the html
		var setTabContent = function(forceTab) {
			var allDivs = document.getElementById('body-content').getElementsByTagName('div');
			for (i = 0; i < allDivs.length; i++) {
				var thisDiv = allDivs[i];
			// skip irrelevent elements
				if (thisDiv.className != 'body-contBox') { continue; }
			// test for/get subnav element, skip if nonexistant
				var subNav   = thisDiv.getElementsByTagName('ul')[0];
				if (!subNav) { continue; }
			// normalize element and get some references
				var subItems = subNav.getElementsByTagName('li');
				var subCont  = thisDiv.getElementsByTagName('div')[0];
				var subSects = subCont.getElementsByTagName('div');
					subCont.normalize();
			// determine tabIndex target
				var tabIndex = (document.location.href.indexOf('#contSect-') != -1) ? parseInt(document.location.href.split('#contSect-')[1]) : 0;
					tabIndex = forceTab || tabIndex;
				if (tabIndex > (subItems.length-1)) { tabIndex = 0; }
			// show/classify the tabs/content correctly. Add events for future clicks
				for (ii = 0; ii < subItems.length; ii++) {
					var thisNav             = subItems[ii];
					var thisCont            = subSects[ii];
					var thisImg             = thisNav.getElementsByTagName('img')[0];
						thisNav.setAttribute('tabIndex', ii);
					// remove standard mouse over/out events on tab bg images
						thisImg.onmouseover = null;
						thisImg.onmouseout  = null;
					// create events for page-life clicks,
						thisNav.onmousedown = function() { document.location.href = '#contSect-' + this.getAttribute('tabIndex'); }
						thisNav.onmouseup   = function() { setTabContent(); }
					// classify elements
					var isCurrent = (parseInt(ii) == parseInt(tabIndex));
						thisNav.className   = (isCurrent) ? 'current' : '';
						thisCont.className  = (isCurrent) ? 'body-contSect-a' : 'body-contSect-p';
					// set image state
						if (isCurrent)  { thisImg.ovrState(); }
						if (!isCurrent) { thisImg.outState(); }
						if (isset('makePngIe6Friendly')) { makePngIe6Friendly(this); }
					// blur focus
						thisNav.getElementsByTagName('a')[0].onfocus = function() { this.blur(); }
				}
			}
		}




	// post-process swf.movie creation objects, to permit deeplinking.
		var deepLinking = function(flashObj) {
			if (!(/banner/.test(flashObj.url))) {
			// video rotation
				if (document.body.id == 'welcome-sam') { 
					var showVid  = cookie.pairs.introvideo || 0;                    // get cookie
						flashObj.url += '&introvideo=' + showVid;                   // set url
						showVid++; if (showVid>3) { showVid = 0; }                  // increment value
						cookie.set({name:'introvideo', value:showVid, expires:30}); // write cookie
				}
			// deeplinking
				if (document.location.href.indexOf('#contSect-') != -1 ) {
					flashObj.url += '&selectedTab=' + (parseInt(document.location.href.split('#contSect-')[1]));//+1 <-- old
				}
			}
			return flashObj;
		}




	// resets intro video counter
		var resetCounter = function() {
			if (cookie.get('introvideo')) { cookie.expire('introvideo'); }
			document.reload();
		}




	// if site is loaded as msn of no-flash version artificially via querystring, 
	// the carry those querystring values through to all other links on the site.
		var carryQuerys = function(){
			var ignoredValues = ['referrer', 'custoffer','p', 'o', 'a']; // array of pairs to ignore
			var allLinks      = document.getElementsByTagName('a');
			var pageUrl       = new urlHandler(document.location.href);
			var pageQstr      = pageUrl.querystring;
			for (var i = 0; i < allLinks.length; i++) {
				var thisLink  = allLinks[i];
				if (thisLink.getAttribute('linkey')) { continue; }
				var thisHref  = thisLink.href;
			// dissect url
				var thisUrl   = new urlHandler(thisHref);
				var thisFile  = thisUrl.file
				var thisAnch  = thisUrl.hash;
			// rebuild url, carrying over current query params.
				var newUrl             =  new urlHandler(thisFile);
				if (thisUrl.domain == pageUrl.domain && thisUrl.path == pageUrl.path) {
						newUrl.protocol    = thisUrl.protocol;
						newUrl.domain      = thisUrl.domain;
						newUrl.path        = thisUrl.path;
						newUrl.querystring = thisUrl.querystring;
						newUrl.hash        = thisUrl.hash;
					for (var ii in pageQstr.pairs) {
					// skip excluded values
						var skip = false;
						for (var iii in ignoredValues) { if (ignoredValues[iii] == ii) { skip = true; } }
						if (skip) { continue; }
					// append non-excluded values
						newUrl.querystring.pairs[ii] = pageQstr.pairs[ii];
					}
				// some browsers don't seem to encode slashes ...
					if (typeof(newUrl.querystring.pairs.referrer) != 'undefined') { newUrl.querystring.pairs.referrer = newUrl.querystring.pairs.referrer.split('/').join('%2F'); }
				// update link url
					thisLink.href = newUrl.string();
				}
			}
		}




	// call popup by linkage key in linkage.js
		var callPopByKey = function(linkTag) {
		// first determine sitelet version
			if (isMsnSite()) {
				var siteVersion = 'msn';
			} else if (swf.rev >= 8) {
				var siteVersion = 'swf';
			} else {
				var siteVersion = 'std';
			}
		// get dimensions
			var winDimensions = linkage[linkTag].pop.toString().split('x');
		// make window
			window.open(linkage[linkTag][siteVersion],'popup','height='+winDimensions[1]+',width='+winDimensions[0]+',resizable=1,scrollbars=1,location=0,toolbar=0,status=0').focus;
		}




	// if site is loaded as msn of no-flash version artificially via querystring, 
	// the carry those querystring values through to all other links on the site.
		var setLinkage = function(){
		// first determine sitelet version
			if (isMsnSite()) {
				var siteVersion = 'msn';
			} else if (swf.ref >= 8) {
				var siteVersion = 'swf';
			} else {
				var siteVersion = 'std';
			}
		// get all links and loop through them
			var allLinks = document.getElementsByTagName('a');
			for (var i = 0; i < allLinks.length; i++) {
				var thisLink  = allLinks[i];
				var thisHref  = thisLink.href;
				var linkTag   = thisLink.getAttribute('linkey');
			// if link is tagged, customize link
				if (linkTag && linkage[linkTag]) {
				// add popup support
					// _blank  - standard popup
					if (linkage[linkTag].pop == true) { thisLink.setAttribute('target', '_blank'); }
					// same window
					if (!(linkage[linkTag].pop))      { thisLink.removeAttribute('target');        }
					// NUMxNUM - scaled/chromeless popup
					if (/\d+x\d+/.test(linkage[linkTag].pop)) {
						thisLink.onclick = function() {
							var linkTag   = this.getAttribute('linkey');
							var winDimensions = linkage[linkTag].pop.toString().split('x');
							window.open(linkage[linkTag][siteVersion],'popup','height='+winDimensions[1]+',width='+winDimensions[0]+',resizable=1,scrollbars=1,location=0,toolbar=0,status=0').focus;
							return false;
						}
					}
				// add tracking support
					if (linkage[linkTag].trk != false) {
				// the onmouseup event for tracking, to prevent
				// interfering/interferance from onmouseup events
						thisLink.onmousedown = function() {
							savedPage = s.pageName;
							var linkStr = 'click:' + s.pageName.substring(0, s.pageName.lastIndexOf(':')) + ':' + currentTab() + '::' + linkage[this.getAttribute('linkey')].trk;
							tdaTrack(linkStr);
							s.pageName = savedPage;
						}
					}
				// update href value, if case supplied
					thisLink.href = linkage[linkTag][siteVersion] || thisLink.href;
				}
			}
		}




	// tests to see if sitelet is deployed on msn.com. returns boolean.
		var isMsnSite  = function() {
			var is_msnSitelet = false;
			try {
				// we will try and set the boolean based upon the location of the framseet it is being hosted within, this will probably return an error, if the framset and this documents location do not match.
					if (document.location.href.split('//')[1].indexOf('/msn/') != -1) {
						is_msnSitelet = true;
					} else if (document.location.href.indexOf('/msn/') != -1) {
						is_msnSitelet = true; // somewhat academic as this will throw an error if we are in a frameset ... see error handling below.
					} else if (top.parent.document.domain == 'moneycentral.msn.com') {
						is_msnSitelet = true; // somewhat academic as this will throw an error if we are in a frameset ... see error handling below.
					} else if (/msn\=true/.test(document.location.href)) {
						is_msnSitelet = true;
					} else {
						is_msnSitelet = false;
					}
			} catch (e) {
				is_msnSitelet = true;
			}
			return is_msnSitelet;
		}




	// compensates for scrollbars on content area boxex that also have butttons
		var fixContentScrolling  = function() {
			if (document.location.href.indexOf('special.html') == -1) {
				var body       = document.getElementById('body-subCont')
				var buttonWrap = document.getElementById('body-subFoot')
				if (body && buttonWrap && buttonWrap.getElementsByTagName('img').length) {
					body.style.height = '200px';
				}
			}
		}



	// boolean for preventing double iniits
		var startSiteHasRun = false;
	// site initialization sequence
		var startsite = function() {
			if (!startSiteHasRun){
				if (typeof(cosProc) == 'function') {  cosProc(); }
				if (isMsnSite()) { swf.rev = false; }                    // supress flash if msn sitelet
				swf.setAll()
				window.images = new imageHandler();
				setRollovers();                                          // set rollover images and navigation
				setTabContent();                                         // enable tab switching
				setLinkage();                                            // set custom linkage by sitelet deployment
				carryQuerys();                                           // carry through developer querysting pairs
				trackPageLoad();                                         // perform page tracking request last, so as not to delay onload event
				fixContentScrolling();
				startSiteHasRun = true;
			}
		// msie bugfix.
			if (client.engine == 'msie') {
				var pageTitle = document.title;
				setInterval(function() { document.title = pageTitle; }, 250);
			}
		}



	// if memetrics is disabled, we need to assign the onload event, otherwise we don't.
		if (typeof(XOS) == 'undefined') { window.onload = function() { startsite(); } }



	// build the swf object
		window.swf    = new swfHandler({revreq:8, procobj:deepLinking});



