var appVersion = navigator.appVersion,
	ie4 = (document.all) ? true : false,
	ie5 = ( navigator.appVersion.indexOf("MSIE 5") != -1 ),
	ie7 = ( navigator.appVersion.indexOf("MSIE 7") != -1 ),
	ns4 = ( document.layers) ? true : false,
	ns6 = ( (navigator.appName.indexOf("Netscape") != -1) && parseInt(navigator.appVersion) >= 5 ),
	mac = ( navigator.userAgent.indexOf("Mac") != -1) ? true : false,
	gek = ( navigator.userAgent.indexOf("Firefox") != -1 ),
	sf01 = ( navigator.userAgent.indexOf("KHTML") != -1),
	sf12 = ( parseInt(navigator.appVersion.replace(/.*AppleWebKit\//i, "")) >= 124 ) ,
	sf3 = ( parseInt(navigator.appVersion.replace(/.*AppleWebKit\//i, "")) >= 500 ) ,
	saf = ( navigator.userAgent.indexOf("Safari") > -1 ),
	iph = ( navigator.userAgent.indexOf("iPhone") > -1 );

if (ns4) { window.onresize=fixMe; }
if (ns4) { origWidth = innerWidth; origHeight = innerHeight; }
function fixMe() { if (innerWidth != origWidth || innerHeight != origHeight) self.location.reload(); }

function imgComplete( img ) { return ( img.complete ); }
function sfImgComplete( img ) { return ( img.width > 0 ); }
function ieRedrawWindow() { window.blur(); 	self.focus(); }
function redrawWindow() { }

if ( mac && ie5 ) Array.prototype.push = function()
{
	redrawWindow = ieRedrawWindow;

	var thisArray = this, x;
	for ( x=0; x < arguments.length; x++ )
	{
		thisArray[ thisArray.length ] = arguments[x];
	}
	return thisArray.length;
}

if ( sf01 || sf12 ) imgComplete = sfImgComplete;


var urlValueOf = new Array(), queryDataArray = location.search.substr(1).split(/\&|;|\&;/);
for ( var x=0; x < queryDataArray.length; x++ )
{
	var thisQueryVariable = queryDataArray[x].split("=");
	urlValueOf[ thisQueryVariable[0] ] = new Object();
	urlValueOf[ thisQueryVariable[0] ] = thisQueryVariable[1];
}


function nsD(elementName, w){ w = (w) ? w : top; return w.document.layers[elementName]; }
function nsShow(element, w) { d(element, w).display = "block"; }
function nsHide(element, w) { d(element, w).display = "none"; }
function nsClip(element, t, r, b, l) 
{
	var obj = d(element);
	obj.clip.top = t;
	obj.clip.right = r;
	obj.clip.bottom = b;
	obj.clip.left = l;
}

function mozD(elementName, w) { w = (w) ? w : self; return w.document.getElementById(elementName); }
function mozShow(elementID, w)  { w = (w) ? w : self; d(elementID, w).style.display = "block"; }
function mozHide(elementID, w)  { w = (w) ? w : self; d(elementID, w).style.display = "none"; }
function mozvShow(elementID, w)  { w = (w) ? w : self; d(elementID, w).style.visibility = "visible"; }
function mozvHide(elementID, w)  { w = (w) ? w : self; d(elementID, w).style.visibility = "hidden"; }
function mozClip(elementID, t, r, b, l)  { w = (w) ? w : self; d(elementID, w).style.clip = "rect(" + t + "," + r + "," + b + "," + l + ")"; }
function mozSetOpacity(element, alpha) { element.style.MozOpacity = alpha; }
function w3cSetOpacity(element, alpha) { element.style.opacity = alpha; }
function ieSetOpacity(element, alpha) { element.style.filter = "Alpha(Opacity=" + alpha*100 + ")"; }
function fakeSetOpacity(element, alpha) { if ( alpha > 0 ) Show(element.id); else Hide(element.id); }
function ie_bindEvent( element, event, func ) {	element.attachEvent( 'on' + event, func ); }
function w3_bindEvent( element, event, func ) {	element.addEventListener(event, func, false ); }
function w3_unBindEvent( element, event, func ) {	element.removeEventListener(event, func, false ); }

var d, Show, Hide, Clip, setOpacity, bindEvent;
if ( ns4 )
{
	d = nsD,
	Show = nsShow;
	Hide = nsHide;
	Clip = nsClip;
}
else
{
	d = mozD;
	Show = mozShow;
	Hide = mozHide;
	vShow = mozvShow;
	vHide = mozvHide;
	Clip = mozClip;
	redrawWindow = ieRedrawWindow;
	bindEvent = w3_bindEvent;

	if ( (mac && ie4) || (sf01 && !sf12) ) setOpacity = fakeSetOpacity;
	else if ( !mac && ie4 )
	{
		bindEvent = ie_bindEvent;
		setOpacity = ieSetOpacity;
	}
	else if ( sf12 || document.getElementById ) setOpacity = w3cSetOpacity;
	else if ( ns6 ) setOpacity = mozSetOpacity;
}

function Swap( oldID, newID, w )
{
	var win = ( w ) ? w : self;
	if ( newID )
	{
		Hide( oldID, win );
		Show( newID, win );
		return newID;
	}
	else
	{
		if ( d(oldID).style.display != "block" )
			Show( oldID );
		else
			Hide( oldID );
	}
}

if ( typeof window.innerHeight == "undefined" )
{
	var innerWidth, innerHeight;
	bindEvent( window, 'load', function() { innerHeight = document.body.clientHeight, innerWidth = document.body.clientWidth } );
	bindEvent( window, 'resize', function() { innerHeight = document.body.clientHeight, innerWidth = document.body.clientWidth } );
}


var sr =
{
/**************************************************************
	C R E A T E    E L E M E N T   &   B I N D    E V E N T

attaches all HTML element attributes to a newly created element
and returns the element
style:	accepts standard CSS syntax
event:	array of trigger & func object pair
**************************************************************/
	CreateElement: function()
	{
		var thisElement = document.createElement( arguments[0].tagName )

		// apply the attributes
		for ( var p in arguments[0] )
			try{thisElement[p] = arguments[0][p];}
			catch(e){};

		//	style attributes must be applied using setAttribute
		if ( arguments[0].style )
			thisElement.setAttribute( 'style', arguments[0].style );

		// bind the events
		if ( arguments[0].events )
			for ( var e=0; e<arguments[0].events.length; e++ )
				bindEvent( thisElement, thisElement.events[e].trigger, thisElement.events[e].func );

		return thisElement;
	},

/**************************************************************
	F A D I N G    F U N C T I O N S

element:	the element to be faded
ramp:		(optional) array of opacity ramp, fadeSteps is default
rate:		(optional) specify a delay other than the default of 60ms
sr.Faders:	contains the instantiated fading objects
**************************************************************/
	Faders:
	{
		// presets to reduce processor load of realtime math.  The ramps below are S-curves
		// other curves can be specified upon object instantiation
		rate: 60,	// miliseconds between steps
		halfRamp: [ .999999, .9575, .8306, .6656, .5406, .5 ],
		smoothFade: [ 0, 0.15, 0.3090169943749475, 0.435, 0.5877852522924731, 0.69, 0.8090169943749475, 0.875, 0.9510565162951535, 0.975, .999 ],
		fadeSteps: [ 0, 0.3090169943749475, 0.5877852522924731, 0.8090169943749475, 0.9510565162951535, .999 ],
		quickFade: [ 0, .33, .66, .9999 ],
		cutsOnly: [ 0, .9999 ],
		length: 0
	},
	Fader:  function()
	{
		var thisObj = {};

		//	set all presets to cuts on iPhone to avoid overloading the resources
		if ( iph )
			thisObj.smoothFade = sr.Faders.fadeSteps = sr.Faders.quickFade = sr.Faders.cutsOnly;

		//	apply the properties
		for ( var p in sr.Fader )
			thisObj[p] = sr.Fader[p];

		thisObj.style = arguments[0].element.style;
		thisObj.buffer = 0;			//  during fades, buffer subsequent events to address after the fade is done
		thisObj.idle = true;		// to ignore events while a fade is in progress
		thisObj.timerCache = null;
		thisObj.ramp = ( arguments[0].ramp ) ? arguments[0].ramp : sr.Faders.fadeSteps;
		thisObj.f = thisObj.ramp.length;
		thisObj.HTMLelement = arguments[0].element;
		thisObj.id = arguments[0].element.id;

		// Benchmarking variables
		thisObj.performance = new Object();
		thisObj.performance.enable = false;												// Performance calibration is inactive by default. To enable, set this to true
		thisObj.performance.referenceTime = ( thisObj.ramp.length-1 ) * sr.rate;		// ideal time required to complete fade in milliseconds
		thisObj.performance.startTimeIndex = 0;
		thisObj.performance.stopTimeIndex = 0;
		thisObj.performance.actualDuration = 0;
		thisObj.performance.benchmark = 0;
	
		thisObj.fade = function()		//	determines fade direction
		{
			if ( thisObj.idle )
			{
				thisObj.idle = false;
				if (thisObj.f > 0) thisObj.fadeDown();
				else thisObj.fadeUp();
			}
			else thisObj.buffer++;
		}
		
		thisObj.fadeUp = function()
		{
			if ( thisObj.f == 0 )
				thisObj.performance.startTimeIndex = new Date().getTime();
			var x = thisObj.f+1;
			if ( x < thisObj.ramp.length )
			{
				thisObj.f++;
				setOpacity(thisObj.HTMLelement, thisObj.ramp[x]);
				thisObj.timerCache = setTimeout(function() {thisObj.fadeUp() }, sr.Faders.rate);
			}
			else
			{
				thisObj.f = thisObj.ramp.length;
				thisObj.callibrate();
		
				thisObj.callBack();
				if ( thisObj.buffer > 0 )
				{
					thisObj.buffer--;
					thisObj.idle = true;
					thisObj.fade();
				}
				else thisObj.idle = true;
			}
		}

		thisObj.fadeDown = function()
		{
			if ( thisObj.f == thisObj.ramp.length )
				thisObj.performance.startTimeIndex = new Date().getTime();
			var x = thisObj.f-2;
			if ( x > -1 )
			{
				thisObj.f--;
				setOpacity(thisObj.HTMLelement, thisObj.ramp[x]);
				thisObj.timerCache = setTimeout(function() { thisObj.fadeDown() }, sr.Faders.rate);
			}
			else
			{
				thisObj.f = 0;
				thisObj.callibrate();
		
				thisObj.callBack();
				if ( thisObj.buffer > 0 )
				{
					thisObj.buffer--;
					thisObj.idle = true;
					thisObj.fade();
				}
				else thisObj.idle = true;
			}
		}
		
		thisObj.setOpacity = function() { setOpacity(this, 0); this.f = 0; }	// depricated
		
		thisObj.snapOff = function() { setOpacity(this, this.ramp[0]); this.f = 0; }
		thisObj.snapOn = function() { setOpacity(this, this.ramp[ this.ramp.length-1 ]); this.f = this.ramp.length; }
		thisObj.callBack = function() {}
		thisObj.callibrate = function()
		{
			var thisObj = this,
				bench1 = 1.5, bench2 = 3, bench3 = 6, bench4 = Infinity;
			if ( thisObj.performance.enable )
			{
				thisObj.performance.stopTimeIndex = new Date().getTime();
				thisObj.performance.actualDuration = thisObj.performance.stopTimeIndex - thisObj.performance.startTimeIndex;
				thisObj.performance.benchmark = thisObj.performance.actualDuration / thisObj.performance.referenceTime;
				if ( thisObj.performance.benchmark < bench1 )
				{
					thisObj.ramp = smoothFade;
				}
				if ( thisObj.performance.benchmark > bench1 && thisObj.performance.benchmark <= bench2 )
				{
					thisObj.ramp = sr.Faders.fadeSteps;
				}
				else if ( thisObj.performance.benchmark > bench2 && thisObj.performance.benchmark <= bench3 )
				{
					thisObj.ramp = quickFade;
				}
				else if ( thisObj.performance.benchmark > bench3 && thisObj.performance.benchmark != bench4 )
				{
					thisObj.ramp = cutsOnly;
				}
				thisObj.performance.referenceTime = ( thisObj.ramp.length-2 ) * sr.rate;
		// window.status = 'actual: ' + thisObj.performance.actualDuration + ', ref: ' + thisObj.performance.referenceTime + ', bench: ' + thisObj.performance.benchmark;
			}
		}
		sr.Faders[thisObj.id] = thisObj;
		sr.Faders.length++;
		return thisObj;
	},

/*************************************************************
					S L I D E S H O W S						**
imgDir;
thumbsDir;
container:		viewer ID
slides:			array of image objects containing filenames & captions
transition:		cutFade, cut, dip, dissolve, crossdissolve;
fadeRamp:		quick, standard, smooth;
arrows:			array containing prev & next string or images;
counter:		'counter', 'digits', 'bullets', or false;
displayOrder:	array changing default order of display: pic, caption, nav, thumbs
delay:			seconds;
initialDelay:	seconds;
playButton:		true, FALSE;
autoplay:		true, FALSE;
hoverpause:		true, FALSE;
draggable:		TRUE, false;
scale:			true, FALSE; scale image to fill container (req: draggable=true)
shortcuts:		TRUE, false; (keyboard navigation)
syncURL:		true, FALSE; HTML5 required, slideshow updates location field

sr.Slideshows:	contains the instantiated slideshows
*************************************************************/
	Slideshows:	[],
	Slideshow: function()
	{
		var thisObj = {};
		for ( var p in arguments[0] )
			thisObj[p] = arguments[0][p];

		//	jump to currentSlide if passed in URL
		thisObj.currentSlide = ( urlValueOf[ "s" ] ) ? parseInt( urlValueOf[ "s" ]-1) : 0;
		thisObj.defaultDelay = 4000;
		thisObj.thumbsRamp = [ .6, .64, .72, .88, .96, .99999 ];

		if ( thisObj.arrows )
		{
			var SlideshowNav = sr.CreateElement( { tagName: 'div', id: thisObj.container + 'srGalleryNav', className: 'srGalleryNav' } );
			// create previous button and its event
			SlideshowNav.appendChild(
				sr.CreateElement(
				{
					tagName:	'a',
					href:		'javascript:',
					innerHTML:	thisObj.arrows[0],
					title:		'previous',
					className:	'srPrev',
					events:		[
									{ trigger: 'mouseup', func: function() { eval('sr.Slideshows["' + thisObj.container + '"].prev()') } }
								]
				})
			);

			//	create counter
			SlideshowNav.appendChild( sr.CreateElement( { tagName: 'span', className: 'srCounter', id: thisObj.container + 'srCounter' } ) );

			//	create next button and its event
			SlideshowNav.appendChild(
				sr.CreateElement(
				{
					tagName:	'a',
					href:		'javascript:',
					innerHTML:	thisObj.arrows[1],
					title:		'next',
					className:	'srNext',
					events:		[
									{ trigger: 'mouseup', func: function() { eval('sr.Slideshows["' + thisObj.container + '"].next()') } }
								]
				})
			);

		}
		if ( thisObj.shortcuts == true )
			// "event is not defined" error in Firefox
			bindEvent( window,			"keyup",	function() { eval('sr.Slideshows["' + thisObj.container + '"].keys(event)') } );

		//	create main image container and its events
		var SlideshowFrame = sr.CreateElement(
		{
			tagName: 'div',
			id: thisObj.container + 'srSlideshowFrame',
			className: 'srSlideshowFrame',
			events:	//	for linked images in the slideshow
			[
				{ trigger: 'click',		func: function() { eval('sr.Slideshows["' + thisObj.container + '"].getLink()') } },
				{ trigger: 'mouseover',	func: function() { eval('sr.Slideshows["' + thisObj.container + '"].showLinkInStatus()') } },
				{ trigger: 'mouseout',	func: function() { window.status = '' } }
			]
		}),
			SlideshowInfo = sr.CreateElement({ tagName: 'div', id: thisObj.container + 'srInfo', className: 'srInfo'});

		// to protect photos from easy theft
		if ( thisObj.draggable == false )
		{
			//	display the images as DIV backgrounds and define replaceImg accordingly
			var SlideshowFramePicA = sr.CreateElement({ tagName: 'div', id: thisObj.container + 'srGalleryPicA' }),
				SlideshowFramePicB = sr.CreateElement({ tagName: 'div', id: thisObj.container + 'srGalleryPicB' }),
				replaceImg = function( id )
				{
					d( id ).style.backgroundImage = "url('" + thisObj.cacheImg.src + "')";
/* 					d( id ).style.width = thisObj.cacheImg.width + 'px'; */
					d( id ).style.height = thisObj.cacheImg.height + 'px';

					//	append "link" to the parent's class if the photo is a link, otherwise remove it
					if ( thisObj.slides[ thisObj.currentSlide ].href )
					{
						if (  d( id ).parentNode.className.indexOf(' link') == -1 )
							d( id ).parentNode.className += ' link';
					}
					else
						d( id ).parentNode.className = d( id ).parentNode.className.replace(/\ link/g, '');
				};
		}
		// display photos in <img> tags
		else
		{
			// display photos as IMG src and define replaceImg accordingly
			var SlideshowFramePicA = sr.CreateElement({ tagName: 'img', id: thisObj.container + 'srGalleryPicA', src: '/img/casper.gif', alt: '' }),
				SlideshowFramePicB = sr.CreateElement({ tagName: 'img', id: thisObj.container + 'srGalleryPicB', src: '/img/casper.gif', alt: '' }),
				replaceImg = function( id )
				{
					document.images[ id ].src = thisObj.cacheImg.src;
					document.images[ id ].width = thisObj.cacheImg.width;
					document.images[ id ].height = thisObj.cacheImg.height;
					if ( thisObj.slides[ thisObj.currentSlide ].href )
						d( id ).parentNode.className += ' link';
					else
						d( id ).parentNode.className = d( id ).parentNode.className.replace(/\ link/g, '');
				};
		}
				thisObj.scaleImg = function()
				{
					var offsetX = d( thisObj.container + 'srSlideshowFrame').offsetLeft +  d( thisObj.container + 'srSlideshowFrame').offsetParent.offsetLeft +1,
						offsetY = d( thisObj.container + 'srSlideshowFrame').offsetTop +  d( thisObj.container + 'srSlideshowFrame').offsetParent.offsetTop + 3,
						idA = thisObj.container + 'srGalleryPicA',
						idB = thisObj.container + 'srGalleryPicB';
					if ( window.innerHeight < document.images[ idA ].height + offsetY || document.images[ idA ].height < document.images[ idA ].width)
					{
						d( idA ).style.height = window.innerHeight - offsetY + 'px';
						d( idA ).style.width = 'auto';
					}
					if ( window.innerWidth < document.images[ idA ].width + offsetX || document.images[ idA ].width < document.images[ idA ].height )
					{
						d( idA ).style.width = window.innerWidth - offsetX + 'px';
						d( idA ).style.height = 'auto';
					}
/* 					window.status = 'window/img: ' + window.innerWidth + '/' + (document.images[ idA ].width + offsetX) + ', ' + window.innerHeight + '/' + ( document.images[ idA ].height + offsetY ); */
				}
				if ( thisObj.scale )
				{
					bindEvent( window, 'load', thisObj.scaleImg );
					bindEvent( window, 'resize', thisObj.scaleImg );
					bindEvent( SlideshowFramePicA, 'load', thisObj.scaleImg );
					bindEvent( SlideshowFramePicB, 'load', thisObj.scaleImg );
				}
		SlideshowFrame.appendChild( SlideshowFramePicA );

		thisObj.getLink = function()
		{
			//	use absolute object references because they're called at runtime rather than upon instantiation
			if ( sr.Slideshows[ thisObj.container ].slides[ sr.Slideshows[ thisObj.container ].currentSlide ].href )
			{
				window.location = sr.Slideshows[ thisObj.container ].slides[ sr.Slideshows[ thisObj.container ].currentSlide ].href;
			}
		},

		//	display the URL of linked photos in the statusbar to mimic behavior of regular links
		thisObj.showLinkInStatus = function()
		{
			if ( sr.Slideshows[ thisObj.container ].slides[ sr.Slideshows[ thisObj.container ].currentSlide ].href )
			{
				var thisLink = sr.Slideshows[ thisObj.container ].slides[ sr.Slideshows[ thisObj.container ].currentSlide ].href;
				window.status = 'Go to "' + thisLink + '"';
			}
		}

		//	append the second image container for overlapping transitions
		if ( thisObj.transition == "dissolve" || thisObj.transition == "crossdissolve" )
			SlideshowFrame.appendChild( SlideshowFramePicB );

		//	I don't think this one is working quite right yet, but it pauses playback onmouseover
		if ( thisObj.hoverpause )
		{
			bindEvent( SlideshowFrame, 'mouseover', function() { sr.Slideshows[ thisObj.container ].pause() } );
			bindEvent( SlideshowFrame, 'mouseout', function() { sr.Slideshows[ thisObj.container ].play() } );
		}

		//	assemble slideshow elements in the default order if unspecified, or the order specified by displayOrder property
		thisObj.displayOrder = ( thisObj.displayOrder ) ? thisObj.displayOrder : [ 'pic', 'caption', 'nav', 'thumbs'  ];
		for ( var x=0; x < thisObj.displayOrder.length; x++ )
		{
			switch ( thisObj.displayOrder[x] )
			{
				case "pic":
					d(thisObj.container).appendChild( SlideshowFrame );
					break;
				
				case "caption":
					d(thisObj.container).appendChild( SlideshowInfo );
					break;
				
				case "nav":
					if ( thisObj.arrows )
						d(thisObj.container).appendChild( SlideshowNav );
					break;
				
				case "thumbs":
					if ( thisObj.thumbsDir )
					{
						var srSlideshowThumbs = sr.CreateElement({ tagName: 'div', id: thisObj.container + "srSlideshowThumbs", className: 'srSlideshowThumbs' });
						d(thisObj.container).appendChild( srSlideshowThumbs );
			
						for ( var x=0; x < thisObj.slides.length; x++ )
						{
							var thisPic = thisObj.slides[x],
								thisThumb = sr.CreateElement(
								{
									tagName:	'img',
									src:		'/img/casper.gif',
									style:		"background: url('" + thisObj.thumbsDir + thisPic.file + "') no-repeat center black",
									id:			thisPic.id = thisPic.file.replace( /\..*/, ''),
									alt:		x,
									className:	"thumb",
									events:		[
													{ trigger: 'mouseover',	func: function() { sr.Slideshows[ thisObj.container ].thumbOver(this.alt) } },
													{ trigger: 'mouseout',	func: function() { sr.Slideshows[ thisObj.container ].thumbOut(this.alt) } },
													{ trigger: 'click',		func: function() { sr.Slideshows[ thisObj.container ].loadImage(this.alt) } }
												]
								});
							sr.Fader( { element: thisThumb, ramp: sr.Faders.halfRamp } );
							sr.Faders[ thisThumb.id ].snapOn();
							srSlideshowThumbs.appendChild( thisThumb );
						}
					}
				break;
			}
		}

		if ( thisObj.transition == "dissolve" || thisObj.transition == "crossdissolve" )
		{
			d( thisObj.container + "srGalleryPicA").setAttribute( 'style', 'position: absolute; left: 0px; top: 0px; background-position: center center; background-repeat: no-repeat;')
			if ( document.all )
			{
				d( thisObj.container + "srGalleryPicB").setAttribute( 'style', 'position: absolute; left: 0px; top: 0px;')
			}
			thisObj.mainPhotoA = new sr.Fader( { element: d( thisObj.container + "srGalleryPicA"), ramp: thisObj.fadeRamp } );
			thisObj.mainPhotoB = new sr.Fader( { element: d( thisObj.container + "srGalleryPicB"), ramp: thisObj.fadeRamp } );
			thisObj.mainPhotoB.snapOff();
			Hide( thisObj.container + "srGalleryPicB" );			
		}
		else if ( thisObj.transition != "cut" )
		{
			thisObj.mainPhotoA = new sr.Fader( { element: d( thisObj.container + "srGalleryPicA"), ramp: thisObj.fadeRamp } );
			thisObj.mainPhotoA.snapOff();
		}

		thisObj.alreadyLoaded = true;
		setTimeout( function() { thisObj.loadImage( thisObj.currentSlide ) }, 0 );
		if ( thisObj.autoplay )
		{
			thisObj.delay = ( thisObj.delay ) ? thisObj.delay*1000 : thisObj.defaultDelay;
			thisObj.slideShowTimer = setTimeout( function() { thisObj.next() }, thisObj.delay );
		}
		else
			thisObj.paused = true;
		switch ( thisObj.transition )
		{
			default:	// cut out, fade in
				thisObj.change = function()
				{
					thisObj.mainPhotoA.snapOff();
					replaceImg( thisObj.container + "srGalleryPicA" );
					setTimeout( function() { thisObj.mainPhotoA.fadeUp() }, 200 );
				}
				break;
		
			case "dissolve":
				thisObj.change = function()
				{
					if ( d( thisObj.container + "srGalleryPicB").style.display == "block" )
					{
						replaceImg( thisObj.container + "srGalleryPicA" );
						thisObj.mainPhotoB.callBack = function() { Hide( thisObj.container + "srGalleryPicB"); thisObj.mainPhotoB.callBack = function() {} }
						Show( thisObj.container + "srGalleryPicA");
						thisObj.mainPhotoB.fadeDown();
					}
					else
					{
						replaceImg( thisObj.container + "srGalleryPicB", thisObj.cacheImg.src );
						thisObj.mainPhotoB.callBack = function() { Hide( thisObj.container + "srGalleryPicA"); thisObj.mainPhotoB.callBack = function() {} }
						Show( thisObj.container + "srGalleryPicB");
						thisObj.mainPhotoB.fadeUp();
					}
					d( thisObj.container + "srSlideshowFrame").style.height = thisObj.cacheImg.height + 'px';
				}
				break;
		
			case "crossdissolve":
				thisObj.change = function()
				{
					if ( d( thisObj.container + "srGalleryPicB").style.display == "block" )
					{
						replaceImg( thisObj.container + "srGalleryPicA" );
						thisObj.mainPhotoB.callBack = function() { Hide( thisObj.container + "srGalleryPicB"); thisObj.mainPhotoB.callBack = function() {} }
						Show( thisObj.container + "srGalleryPicA");
						thisObj.mainPhotoA.fadeUp();
						thisObj.mainPhotoB.fadeDown();
					}
					else
					{
						replaceImg( thisObj.container + "srGalleryPicB", thisObj.cacheImg.src );
						thisObj.mainPhotoB.callBack = function() { Hide( thisObj.container + "srGalleryPicA"); thisObj.mainPhotoB.callBack = function() {} }
						Show( thisObj.container + "srGalleryPicB");
						thisObj.mainPhotoB.fadeUp();
						thisObj.mainPhotoA.fadeDown();
					}
					d( thisObj.container + "srSlideshowFrame").style.height = thisObj.cacheImg.height + 'px';
				}
				break;
		
			case "cut":
				thisObj.change = function()
				{
					replaceImg( thisObj.container + "srGalleryPicA" );
				}
				break;
		
			case "dip":
				thisObj.change = function()
				{
					thisObj.mainPhotoA.callBack = function()
					{
					replaceImg( thisObj.container + "srGalleryPicA" );
					}
					thisObj.mainPhotoA.snapOn();
					thisObj.mainPhotoA.fade();
					thisObj.mainPhotoA.fade();
				}
				break;
		}
		switch ( thisObj.counter )
		{
			case 'counter':
				thisObj.updateCounter = function()
				{
					d( thisObj.container + "srCounter").innerHTML = parseInt( parseInt( thisObj.currentSlide )+1 ) + " / " + thisObj.slides.length;
				}
				break;
	
			case 'digits':
				thisObj.updateCounter = function()
				{
					d( thisObj.container + "srCounter").innerHTML = '';
					for ( var x = 0; x < thisObj.slides.length; x++ )
						d( thisObj.container + "srCounter").innerHTML += ( thisObj.currentSlide == x )
							? '<span>' + parseInt( thisObj.currentSlide + 1 ) + '</span>'
							: '<a href="javascript:sr.Slideshows[\'' + thisObj.container + '\'].loadImage(' + x + ')" title="' + thisObj.slides[x].caption + '">' + ( x + 1 ) + '</a>';
				}
				break;
	
			case 'bullets':
				thisObj.updateCounter = function()
				{
					d( thisObj.container + "srCounter").innerHTML = '';
					for ( var x = 0; x < thisObj.slides.length; x++ )
						d( thisObj.container + "srCounter").innerHTML += ( thisObj.currentSlide == x )
							? '<span>&bull;</span>'
							: '<a href="javascript:sr.Slideshows[\'' + thisObj.container + '\'].loadImage(' + x + ')" title="' + thisObj.slides[x].caption + '">&bull;</a>';
				}
				break;
	
			case 'list':
				thisObj.updateCounter = function()
				{
					d( thisObj.container + "srCounter").innerHTML = '';
					for ( var x = 0; x < thisObj.photoData.length; x++ )
						d( thisObj.container + "srCounter").innerHTML += ( thisObj.currentSlide == x )
							? '<span>' + thisObj.slides[x].id + '</span>, '
							: '<a href="javascript:sr.Slideshows[\'' + thisObj.container + '\']' + thisObj.container + '.loadImage(' + x + ')">' + thisObj.slides[x].id + '</a>, ';
				}
				break;
		}

		thisObj.callback = function() {return},
		thisObj.showLoadedImg = function()
		{
			this.change();
			if ( thisObj.syncURL && window.history.replaceState )
			{
				var realCurrentSlide = parseInt(thisObj.currentSlide) + 1
					currentQuery = window.location.search + '';
				if ( currentQuery == '' )
					var newQuery = currentQuery + '?s=' + realCurrentSlide;
				else if ( currentQuery.search(/(\?|\&)s=/ ) < 0)
					var newQuery = currentQuery + '&s=' + realCurrentSlide;
				else
				{
					var currentQuery = currentQuery + '',
						newQuery = currentQuery.replace( /s=\d+/g, 's=' + realCurrentSlide);
				}
				window.history.replaceState(true, document.title + ': ' + thisObj.slides[thisObj.currentSlide].caption, newQuery );
			}
			if ( thisObj.counter )
				setTimeout( thisObj.updateCounter );
		},
		
		thisPic = {},
		thisObj.loadImage = function( picIndex )
		{
			thisPic = this.slides[ picIndex ];
			thisPic.id = thisPic.file.replace( /\..*/, '');
			this.cacheImg = new Image();
			bindEvent( thisObj.cacheImg, "load", function() { thisObj.showLoadedImg() } );
			this.cacheImg.src = this.imgDir + thisPic.file;
			d( this.container + "srInfo").innerHTML = ( thisPic.caption ) ? thisPic.caption : '';
		
			if ( this.thumbsDir )
			{
				sr.Faders[ this.slides[ thisObj.currentSlide ].id ].snapOn();
				sr.Faders[ thisPic.id ].snapOff();
				d( this.slides[ this.currentSlide ].id ).className = d( this.slides[ this.currentSlide ].id ).className.replace(/ currentSlide/gi, '');
				d( thisObj.slides[picIndex].id ).className += ' currentSlide';
			}
			thisObj.currentSlide = picIndex;
		},

		thisObj.thumbOver = function( picIndex )
		{
			if ( sr.Slideshows[ thisObj.container ].currentSlide != picIndex )
				sr.Faders[ sr.Slideshows[ thisObj.container ].slides[ picIndex ].id ].fade();
		},

		thisObj.thumbOut = function( picIndex)
		{
			if ( sr.Slideshows[ thisObj.container ].currentSlide != picIndex )
				sr.Faders[ sr.Slideshows[ thisObj.container ].slides[ picIndex ].id ].fade();
		},

		thisObj.next = function()
		{
			clearTimeout( sr.Slideshows[ thisObj.container ].slideShowTimer );
			if ( this.currentSlide < this.slides.length-1 )
				this.loadImage( parseInt( thisObj.currentSlide ) + 1 );
			else
				this.loadImage( 0 );
		
			if ( !this.paused )
				this.slideShowTimer = setTimeout( function() { sr.Slideshows[ thisObj.container ].next() }, this.delay );
		},
		
		thisObj.prev = function()
		{
			clearTimeout( this.slideShowTimer );
			if ( this.currentSlide > 0 )
				this.loadImage( this.currentSlide -1 );
			else
				this.loadImage( this.slides.length-1 );
		},

		thisObj.keys = function(e)
		{
			if (!e) e = window.event;
			switch (e.keyCode )
			{
				case 37:
					this.prev();
					break;

				case 39:
					this.next();
					break;
				case 36:
					this.loadImage( 0 );
					break;

				case 35:
					this.loadImage( this.slides.length-1 );
					break;
			}
		},

		thisObj.pause = function()
		{
			this.paused = true;
			this.pauseStartTime = new Date().getTime();
			clearInterval( sr.Slideshows[ thisObj.container ].slideShowTimer );
		},
		
		thisObj.play = function()
		{
			this.paused = false;
			if ( this.pauseStartTime > 0 )
			{
				this.pauseStopTime = new Date().getTime();
				remainingPauseLength = this.delay - ( this.pauseStopTime - this.pauseStartTime );
				this.slideShowTimer = setTimeout( function() { sr.Slideshows[ thisObj.container ].next(); sr.Slideshows[ thisObj.container ].play(); }, remainingPauseLength );
				this.pauseStartTime = 0;
			}
			else
				this.slideShowTimer = setTimeout( function() { sr.Slideshows[ thisObj.container ].next() }, sr.Slideshows[ thisObj.container ].delay );
		
			if ( !this.paused )
				this.slideShowTimer = setTimeout( function() { sr.Slideshows[ thisObj.container ].next() }, sr.Slideshows[ thisObj.container ].delay );
		}
		sr.Slideshows[ thisObj.container ] = thisObj;
		sr.Slideshows.length++;
		return thisObj;
	},


/*************************************************************
						V I D E O S							**
vidDir;
thumbsDir;
container:	ID of the containing DIV
src;
width;
height;
caption;
splash:		path to placeholder image
**************************************************************/
	Videos:
	{
		width: 640,
		height: 360,
		length: 0
	},
	Video: function()
	{
		var thisObj = {};
		for ( var p in arguments[0] )
			thisObj[p] = arguments[0][p];

		thisObj.width = ( thisObj.width ) ? thisObj.width : sr.Videos.width;
		thisObj.height = ( thisObj.height ) ? thisObj.height : sr.Videos.height;

		d( thisObj.container ).innerHTML = '';
		var videoFrame =	sr.CreateElement({ tagName: 'div', style: 'width: ' + thisObj.width + 'px; height: ' + thisObj.height + 'px;' }),
			videoCaption =	sr.CreateElement({ tagName: 'div', innerHTML: thisObj.caption, className: 'videoCaption' });

		d( thisObj.container ).appendChild( videoFrame );
		d( thisObj.container ).appendChild( videoCaption );

		//  If it's Flash Video, use FlowPlayer
		if ( thisObj.src.search(/(flv)|(f4v)/) > -1 )
		{
			flowplayer( videoFrame.id, '/swf/flowplayer-3.2.5.swf',
			{
				playlist: [
					{
						url: thisObj.vidDir + thisObj.src
					},
					{
						// these two configuration variables does the trick
						accelerated: true,
						scaling: 'fit',
						autoPlay: true,
						autoBuffering: true // <- do not place a comma here  
					}
				]
			});
		}
		else if ( thisObj.src.search(/<embed|<ifram|<object/) > -1 )
		{
			var qtCode = thisObj.src;
			videoFrame.innerHTML = qtCode;
		}
		else
		{
			var qtCode = 
				  '\n	<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="' + thisObj.width + '" height="' + thisObj.height + '" codebase="http://www.apple.com/qtactivex/qtplugin.cab">'
				+ '\n		<param name="src" value="' + thisObj.vidDir + thisObj.src + '">'
				+ '\n		<param name="controller" value="true">'
				+ ( ( thisObj.splash ) ? '\n		<param name="src" value="' + thisObj.splash + '">' : '' )
				+ '\n		<param name="target" value="myself">'
				+ '\n		<param name="autoplay" value="true">'
				+ '\n		<param name="bgcolor" value="black">'
				+ '\n		<param name="scale" value="tofit">'
				+ '\n		<param name="kioskmode value="true">'
				+ '\n		<param name="pluginspage" value="http://www.apple.com/quicktime/download/">'
				+ '\n		<embed autoplay="true" scale="tofit" kioskmode="true" width="' + thisObj.width + '" height="' + thisObj.height + '" ' + ( ( thisObj.splash ) ? 'src="' + thisObj.splash + '"' : '' ) + ' controller="true" target="myself" src="' + thisObj.vidDir + thisObj.src + '" bgcolor="black" border="0" pluginspage="http://www.apple.com/quicktime/download/indext.html"></embed>\r	</object>';

			if ( gek )
				videoFrame.innerHTML = qtCode;
			else
				videoFrame.innerHTML = '<video src="' + thisObj.vidDir + thisObj.src + '" width="' + thisObj.width + '" height="' + thisObj.height + '" controls="controls" autoplay="autoplay">' + qtCode + '</video>';
		}

		if ( !sr.Videos[ thisObj.container ] )
		{
			sr.Videos[ thisObj.container ] = thisObj;
			sr.Videos.length++;
		}
	}
}

/**************************************************************
	S C R O L L B A R    F U N C T I O N S
**************************************************************/
var sThumb, scrollWell, scrollableContent, scrollbableContentHeight, scrollableWindow, originalScrollableWindowHeight, sWell, sWellHeight, sWellDist, sWinDist, scrollPaneIncr, scrollTimer, scrollIncrement = 15, scrollDelay = 50;

/* Initialize elements for scrolling: container, contents, scrollbar, well, and shuttle */
function initScrollbar( scrollableElementID, scrollContainerID )
{
	var upArrow = d("upArrow"),
		downArrow = d("downArrow");

	sThumb = d("scrollThumbShell");
	scrollWell = d("scrollWell");
	scrollableContent = d( scrollableElementID );

	scrollableWindow = d( scrollContainerID );
// 	originalScrollableWindowHeight = scrollableWindow.innerHeight || scrollableWindow.clientHeight;

	bindEvent( window,		"keypress",			keyboardEvents );
	bindEvent( window,		"DOMMouseScroll",	getMouseWheel );
 	bindEvent( window,		"resize",			applyScrollBar );
	bindEvent( window,		"mousewheel",		getMouseWheel );
	bindEvent( scrollWell,	"mousedown",		setMouseOffset );

	bindEvent( document,	"mousewheel",		getMouseWheel );
	bindEvent( document,	'mousemove',		dragPane );
	bindEvent( document,	'mouseup',			function() { mouseDown = false; } );

	bindEvent( upArrow,		"click",			moveUp );
	bindEvent( upArrow,		"doubleclick",		moveUp );
	bindEvent( upArrow,		"mousedown",		function() { scrollUp(); upArrow.blur(); } );
	bindEvent( upArrow,		"mouseup",			stopScrolling );
	bindEvent( upArrow,		"mouseout",			stopScrolling );

	bindEvent( downArrow,	"click",			moveDown );
	bindEvent( downArrow,	"doubleclick",		moveDown );
	bindEvent( downArrow,	"mousedown",		function() { scrollDown(); downArrow.blur() } );
	bindEvent( downArrow,	"mouseup",			stopScrolling );
	bindEvent( downArrow,	"mouseout",			stopScrolling );
	redrawWindow();

	setTimeout( "applyScrollBar()", 10 );
}


function applyScrollBar()
{
	var containerHeight = scrollableWindow.parentNode.innerHeight - 5 || scrollableWindow.parentNode.clientHeight - 5,
		containerWidth  = scrollableWindow.parentNode.innerWidth - 20 || scrollableWindow.parentNode.clientWidth - 20;

	scrollableContent.style.width = containerWidth - 20 + 'px';
// 	if ( originalScrollableWindowHeight > containerHeight )
// 		scrollableWindow.style.height = containerHeight + 'px';
	scrollbableContentHeight = scrollableContent.innerHeight || scrollableContent.clientHeight;

	sWellHeight = containerHeight - 32;
	scrollWell.style.height = sWellHeight + 'px';

	sThumbHeight = ( containerHeight >= scrollbableContentHeight ) ? sWellHeight : containerHeight / scrollbableContentHeight * sWellHeight;
	sWellDist = sWellHeight - sThumbHeight;
	sWinDist = scrollbableContentHeight - containerHeight;
	d("scrollThumb").style.height = sThumbHeight + "px";

	if ( scrollbableContentHeight <= containerHeight + 10 )
		Hide('scrollBar');
	else
		Show('scrollBar');

	sThumb.style.top = '0px';
	scrollableContent.style.top = '0px';
	redrawWindow();
}

function debugScroller()
{
	top.window.status = 'scrollbableContentHeight: ' + scrollbableContentHeight + ', sWellHeight: ' + sWellHeight + ', sWellDist: ' + sWellDist + ', sWinDist: ' + sWinDist + ', mouseDown: ' + mouseDown + ', sThumb.offsetTop: ' + sThumb.offsetTop + ', scrollableContent.offsetTop: ' + scrollableContent.offsetTop + ', scrollTimer: ' + scrollTimer + ', scrollDelay: ' + scrollDelay;
}

function getMouseWheel(event)
{
	var delta = 0;
	if (!event)
		event = window.event;
	if (event.wheelDelta)
	{
		delta = event.wheelDelta/120; 
		if (window.opera)
			delta = -delta;
	}
	else if (event.detail)
	{
		delta = -event.detail/3;
	}
	scrollPage(delta*5);
}

function scrollPage( distance )
{
	if ( distance < 0 )
		moveDown( -distance );
	else
		moveUp( distance );
}

function keyboardEvents(event)
{
top.window.status = event.keyCode + '     ' + event.which;
	var upArrowCode, upArrowCode, pageUpCode, pageDownCode, homeCode, endCode;
	if ( sf01 || sf12 )
	{
		upArrowCode = 63232;
		downArrowCode = 63233;
		pageUpCode = 63276;
		pageDownCode =63277;
		homeCode = 63273;
		endCode = 63275;
	}
	else
	{
		upArrowCode = 38;
		downArrowCode = 40;
		pageUpCode = 33;
		pageDownCode = 34;
		homeCode = 36;
		endCode = 35;
	}
	switch( event.keyCode )
	{
		case upArrowCode:
			moveUp();
			break;
		case downArrowCode:
			moveDown();
			break;
		case pageUpCode:
			moveUp( sWellHeight>>1 );
			break;
		case pageDownCode:
			moveDown( sWellHeight>>1 );
			break;
		case homeCode:
			moveUp( sWinDist );
			break;
		case endCode:
			moveDown( 99999999 );
			break;
	}
}

function moveUp( page )
{
// debugScroller();
	if ( sThumb.offsetTop >= 0 )
	{
		var increment = ( page ) ? page : scrollIncrement,
			newPaneTop = ( scrollableContent.offsetTop + increment > 0 ) ? 0 : scrollableContent.offsetTop + increment,
			newThumbTop = 1-newPaneTop/sWinDist * sWellDist;

		sThumb.style.top = newThumbTop + "px";
		scrollableContent.style.top = newPaneTop + "px";
	}
}

function moveDown( page )
{
// debugScroller();
	if ( sThumb.offsetTop < sWellDist )
	{
		var increment = ( page ) ? page : scrollIncrement,
			newPaneTop =  ( scrollableContent.offsetTop - increment < sWinDist * -1 ) ? 0 - sWinDist : scrollableContent.offsetTop - increment,
			newThumbTop = 1-newPaneTop/sWinDist * sWellDist;

		sThumb.style.top = newThumbTop + "px";
		scrollableContent.style.top = newPaneTop + "px";
	}
}

function scrollUp() { clearInterval( scrollTimer ); scrollTimer = setInterval( "moveUp()", scrollDelay ); }
function scrollDown() { clearInterval( scrollTimer ); scrollTimer = setInterval( "moveDown()", scrollDelay ); }
function stopScrolling() { redrawWindow(); clearInterval( scrollTimer ); }

var mouseDown = false, offsetY;
function setMouseOffset( event )
{
	offsetY = event.clientY - sThumb.offsetTop - 1;
	mouseDown=true;
}

function dragPane( event )
{
// debugScroller();
	var coordY = event.clientY, newThumbY;
	if ( coordY - offsetY < 0 ) newThumbY = 0;
	else if ( coordY - offsetY > sWellDist ) newThumbY = sWellDist;
	else newThumbY = coordY - offsetY;
	if ( mouseDown == true )
	{
		sThumb.style.top = newThumbY + "px";
		scrollableContent.style.top = Math.round(0 - newThumbY / sWellDist * sWinDist ) + "px";
		redrawWindow();
	}
}

/**************************************************************
	H O V E R I N G    F U N C T I O N S
**************************************************************/
var mouseX, mouseY,
	midPointX, midPointY,					//	Midpoint where hovering changes direction
	nonHoverThrottle = 500,					//	Throttle setting that generates no movement
	initialHoverThrottle = 6,				//	Higher values produce slower motion
	hoverThrottle = initialHoverThrottle,
	hoverTimeout,
	hoverDelay = 50,
	captureMouse = ( saf && !sf3 )
	?
		function(event)
		{
			mouseX = event.clientX - window.scrollX;
			mouseY = event.clientY - window.scrollY;
		}
	:
		function(event)
		{
			mouseX = event.clientX;
			mouseY = event.clientY;
	};

function initHover( axis )
{
	if ( axis == "x" )
		setInterval( hoverRailX, hoverDelay );
	else if ( axis == "y" )
		setInterval( hoverRailY, hoverDelay );
	else
	{
		setInterval( hoverRailX, hoverDelay );
		setInterval( hoverRailY, hoverDelay );
	}
	setHoverMidPoints();
	bindEvent( self, 'resize', setHoverMidPoints );
	bindEvent( document.body, 'mouseover', startHover );
	bindEvent( document.getElementsByTagName("html")[0], 'mousemove', captureMouse );
	bindEvent( window, 'mouseout', stopHover );
}

function setHoverMidPoints()
{
	midPointX = parent.document.getElementById(window.name).clientWidth/2;
	midPointY = parent.document.getElementById(window.name).clientHeight/2;
// top.window.status = window.name + ' ' + midPointX;
}

function hoverRailX() { window.scrollBy( ( mouseX - midPointX )/ hoverThrottle, 0 ); }
function hoverRailY() { window.scrollBy( 0, ( mouseY - midPointY )/ hoverThrottle ); }

/* startHover & stopHover gradually accellerate & decellerate hovering */
function startHover()
{
	clearTimeout( hoverTimeout );
	hoverThrottle = initialHoverThrottle;
/*	if (  hoverThrottle > initialHoverThrottle )
{
		hoverThrottle = hoverThrottle - 30;
		hoverTimeout = setTimeout( startHover, 100 );
	}
	else hoverThrottle = initialHoverThrottle;
*/
}

function stopHover()
{
	if (  hoverThrottle < nonHoverThrottle )
	{
		hoverThrottle = hoverThrottle + 10;
		hoverTimeout = setTimeout( stopHover, 100 );
	}
}



/**************************************************************
	Parses hidden data contained in hidden span tags
	and returns an array of the data:
		ID's are used as entry IDs
		classNames are used as field names
**************************************************************/
function parseHTMLData( data )
{
	var DataObject = [], thisEntry;
	DataObject.fields = [];
	for ( var x=0; x < data.getElementsByTagName('div').length; x++ )
	{
		thisEntry = data.getElementsByTagName('div')[x];
		thisObject = new Object();
		thisObject.id = thisEntry.id.substr(1);
		DataObject.fields = [ 'id' ];

		for ( var y=0; y < thisEntry.getElementsByTagName('span').length; y++ )
		{
			var	thisVaiable = thisEntry.getElementsByTagName('span')[y],
				thisKey = thisVaiable.className,
				thisValue = thisVaiable.innerHTML;
			eval( "thisObject." + thisKey + " = thisValue " );

			if ( DataObject.fields.toString().indexOf( thisKey ) == -1 ) DataObject.fields.push( thisKey );
		}
		DataObject.push( thisObject );
	}
	return DataObject;
}


function HTMLtemplate( middle, first, last )
{
	this.middle = middle;
	this.first = ( first ) ? first : middle;
	this.last = ( last ) ? last : middle;
}

/* Returns a template populated with data */
function buildContent( template, data, debug )
{
	var out = '', thisChunk, thisField, thisToken;

	// Populate first item using first template
	thisChunk = template.first;
	for ( var y=0; y < data.fields.length; y++ )
	{
		thisField = data.fields[y];
		thisToken = new RegExp('@@' + data.fields[y] + '@@', 'gi');
		thisChunk = thisChunk.replace( thisToken, eval( 'data[0].' + thisField ) );
	}
	thisChunk = thisChunk.replace( /@@index@@/gi, '0' );
	out += thisChunk;

	// Populate 2nd thru last-1 item using middle template
	for ( var x=1; x < data.length-1; x++ )
	{
		thisChunk = template.middle;
		for ( var y=0; y < data.fields.length; y++ )
		{
			thisField = data.fields[y];
			thisToken = new RegExp('@@' + data.fields[y] + '@@', 'gi');
			thisChunk = thisChunk.replace( thisToken, eval( 'data[x].' + thisField ) );
		}
		thisChunk = thisChunk.replace( /@@index@@/gi, x );
		out += thisChunk;
	}

	// Populate last item using last template
	thisChunk = template.last;
	for ( var y=0; y < data.fields.length; y++ )
	{
		thisField = data.fields[y];
		thisToken = new RegExp('@@' + data.fields[y] + '@@', 'gi');
		thisChunk = thisChunk.replace( thisToken, eval( 'data[ data.length-1].' + thisField ) );
	}
	thisChunk = thisChunk.replace( /@@index@@/gi, data.length-1 );
	out += thisChunk;

	if ( debug ) Debug( out, true );
	return out;
}

/************************************************************
	Returned parsed XML file as a DOM object
************************************************************/
function parseXMLdata( xmlFile )
{
	if ( !window.XMLHttpRequest )
		window.XMLHttpRequest = function() { return new ActiveXObject('MSXML2.XMLHTTP.3.0') }

	var xmlObj = new window.XMLHttpRequest();
	xmlObj.open("GET", xmlFile, false);
	xmlObj.send("");
	xmlObj = xmlObj.responseXML;

	return xmlObj;
}

function newWin( url, name, options )
{
	var newWin = window.open( url, name, options );
}

/* Sets a Cookie with the given name and value.
	name       Name of the cookie
	value      Value of the cookie
	[expires]  Expiration date of the cookie (default: end of current session)
	[path]     Path where the cookie is valid (default: path of calling document)
	[domain]   Domain where the cookie is valid
					(default: domain of calling document)
	[secure]   Boolean value indicating if the cookie transmission requires a
					secure transmission
*/
function setCookie(name, value, path, expires, domain, secure)
{
	document.cookie = 
		name + "=" + escape(value) +
		((expires) ? "; expires=" + expires.toGMTString() : "") +
		((path) ? "; path=" + path : "") +
		((domain) ? "; domain=" + domain : "") +
		((secure) ? "; secure" : "");
}

function clearCookie ( name )
{
	var cookie_date = new Date ();			// current date & time
	cookie_date.setTime ( cookie_date.getTime() - 1 );
	document.cookie = name += "=; expires=" + cookie_date.toGMTString();
}

function getCookie(name)
{
	var dc = document.cookie;
	var prefix = name + "=";
	var begin = dc.indexOf("; " + prefix);
	if (begin == -1)
	{
		begin = dc.indexOf(prefix);
		if (begin != 0) return null;
	}
	else
	{
		begin += 2;
	}
	var end = document.cookie.indexOf(";", begin);
	if (end == -1)
	{
		end = dc.length;
	}
	return unescape(dc.substring(begin + prefix.length, end));
}




function Debug(str,code)
{
	var str_debug = "";
	if ( code )
	{
		str_debug += '<body marginheight="0" marginwidth="0">\n\n';
		str_debug += str;
	}
	else
	{
		str_debug += '<html><body marginheight="0" style="white-space: pre;font-family: Monaco,Courier;font-size:9px;">\n\n';
		str_debug += str.replace(/</g, "&lt;").replace(/>/g, "&gt;");
	}
	str_debug += "\n\n</body></html>";
	var win_debug = window.open();
	win_debug.document.write( str_debug );
}

