/* *  Sudo Slider ver 1.0.12 - jQuery plugin  *  Written by Erik Kristensen info@webbies.dk.  *  Based on Easy Slider 1.7 by Alen Grakalic http://cssglobe.com/post/5780/easy-slider-17-numeric-navigation-jquery-slider *	 *	 Dual licensed under the MIT *	 and GPL licenses. *  *	 Built for jQuery library *	 http://jquery.com * */ /*  TODO: Finding and fixing bugs. (No known bugs atm.)  TODO for next major version: (i've had 10 minor versions now, don't think i'm ever going to do a major).  */(function($){	$.fn.sudoSlider = function(options)	{		if (typeof(options) != 'object' && options != '' && options) 		{ 			// Here, i just trigger it to do something, it's way down the actual action happens. 			this.each(function(){				$(this).trigger("sudoSliderEvent", [options]);			});		}		else		{			// default configuration properties			var defaults = {				prevNext:          true,				prevHtml:          '<a href="#" class="prevBtn"> previous </a>',				nextHtml:          '<a href="#" class="nextBtn"> next </a>',				controlsShow:      true,				controlsAttr:      'id="controls"',				controlsFadeSpeed: '400',				controlsFade:      true,				insertAfter:       true,				firstShow:         false,				firstHtml:         '<a href="#" class="firstBtn"> first </a>',				lastShow:          false,				lastHtml:          '<a href="#" class="lastBtn"> last </a>',				numericAttr:       'class="controls"',				numericText:       ['1'],				vertical:          false,				speed:             '800',				ease:              'swing',				auto:              false,				pause:             '2000',				continuous:        false,				clickableAni:      false,				numeric:           false,				updateBefore:      false,				history:           false,				speedhistory:      '400',				autoheight:        true,				customLink:        false,				fade:              false,				crossFade:         true,				fadespeed:         '1000',				ajax:              false,				loadingText:       false,				preloadAjax:       false,				startSlide:        false,				imgAjaxFunction:   false,				docAjaxFunction:   false,				beforeAniFunc:     false,				afterAniFunc:      false,				uncurrentFunc:     false,				currentFunc:       false			};			var options = $.extend(defaults, options);						// To make it smaller when minimized.			// Not including the variables only used once in the code. 			// I just found out that this (as in now, not the same as final release) makes the script 572 bytes smaller. (That's about 6%)			//var optionscontrolsShow = options.controlsShow; // Only used once.			var optionscontrolsFadeSpeed = options.controlsFadeSpeed;			//var optionscontrolsBefore = options.controlsBefore; // Only used once.			//var optionscontrolsAfter = options.controlsAfter; // Only used once.			var optionscontrolsFade = options.controlsFade;			//var optionsinsertAfter = options.insertAfter;// Only used once.			var optionsfirstShow = options.firstShow;			var optionslastShow = options.lastShow;			var optionsvertical = options.vertical;			var optionsspeed = options.speed;			var optionsease = options.ease;			var optionsauto = options.auto;			var optionspause = options.pause;			var optionscontinuous = options.continuous;			var optionsprevNext = options.prevNext;			var optionsnumeric = options.numeric;			var optionsnumericAttr = options.numericAttr;			var optionsnumericText = options.numericText;			//var optionsclickableAni = options.clickableAni; // Only used once.			var optionshistory = options.history;			var optionsspeedhistory = options.speedhistory;			var optionsautoheight = options.autoheight;			var optionscustomLink = options.customLink;			var optionsfade = options.fade;			var optionscrossFade = options.crossFade;			var optionsfadespeed = options.fadespeed;			var optionsupdateBefore = options.updateBefore;			var optionsajax = options.ajax;			//var optionspreloadAjax= options.preloadAjax; // Only used once.			var optionsstartSlide = options.startSlide;			var optionsimgAjaxFunction = options.imgAjaxFunction;			var optionsdocAjaxFunction = options.docAjaxFunction;			var optionsbeforeAniFunc = options.beforeAniFunc;			var optionsafterAniFunc = options.afterAniFunc;			var optionsuncurrentFunc = options.uncurrentFunc;			var optionscurrentFunc = options.currentFunc;						return this.each(function()			{					// There are some things we don't do at init. 				var init = true; // I know it's an ugly workaround, but it works. 				// If auto is on, so is continuous. (People tend to forget things they don't think about :p)				if (optionsauto) optionscontinuous = true;								// Setting up some variables. 				var obj = $(this);								// Fix for nested list items				var ul = obj.children("ul");				var li = ul.children("li");								// Some variables i'm gonna use alot. 				var s = li.length;				var w = li.eq(0).width(); // All slides must be same width, so this shouldn't be a problem. 				var h = obj.height();								// Now we are going to fix the document, if it's 'broken'. (No <ul> or no <li>). 				// I assume that it's can only be broken, if ajax is enabled. If it's broken without Ajax being enabled, the script doesn't have anything to fill the holes. 				if (optionsajax)				{					// Is the ul element there?					if (ul.length == 0)					{						// No it's not, lets create it. 						obj.append('<ul></ul>');						ul = obj.children("ul");					}									// Do we have enough list elements to fill out all the ajax documents. 					if (optionsajax.length > s)					{						// No we dont. 						for (var i = 1; i <= optionsajax.length - s; i++) ul.append('<li><p>' + returnFunnyLoadingText() + '</p></li>');						li = ul.children("li");						s = li.length;						w = li.eq(0).width();					}				}								// i just love stackoverflow (http://stackoverflow.com/questions/182112/what-are-some-funny-loading-statements-to-keep-users-amused-closed)				// i know this is just an easter egg, because you really should never see it. 				// But what the heck, i want it. 				function returnFunnyLoadingText()				{					var funnyLoadingTexts = [						//"Locating the required gigapixels to render",						"Spinning up the hamster",						//"&pi; &times; 1337% == 42",						//"&pi; &times; 1337% != 42!",						//"Shovelling coal into the server",						"Programming the flux capacitor",						//"The last time I tried this the monkey didn't survive",						"Testing data on Timmy... ... ... We need another Timmy",						//"I should have had a V8 this morning",						//"My other load screen is much faster. You should try that one instead",						//"The version I have of this in testing has much funnier load screens",						"Warming up Large Hadron Collider",						"It looks like you're waiting for something to load"					];					return options.loadingText ? options.loadingText : (funnyLoadingTexts[Math.round(Math.random()*(funnyLoadingTexts.length-1))] + '...');				};												// Continuing with the variables. 				var t = 0;				var ot = t;				var nt = t;				var ts = s-1;								var clickable = true;				var buttonclicked = false;				var fading = false;				var ajaxloading = false;				var autoheightdocument = 0;				var numericControls = new Array();				var numericContainer = false;				var destroyed = false;								// Set obj overflow to hidden (and position to relative <strike>, if fade is enabled. </strike>)				obj.css("overflow","hidden");				if (obj.css("position") == "static") obj.css("position","relative"); // Fixed a lot of IE6 + IE7 bugs. 					// Float items to the left				li.css('float', 'left');								// They doens't always put a text in the numericText. 				// With this, if the user dont, the code will. 				for(var i=0;i<s;i++)				{					if (optionsnumericText[i] == undefined) optionsnumericText[i] = (i+1);					// Same thing for ajax thingy. 					if (optionsajax && optionsajax[i] == undefined) optionsajax[i] = false;				}								// Clone elements for continuous scrolling				if(optionscontinuous)				{					if(optionsvertical)					{						// First we create the elements, pretending AJAX is a city in Russia. 						ul.prepend(li.filter(":last-child").clone().css("margin-top","-"+ h +"px"));						ul.append(li.filter(":nth-child(2)").clone());						ul.height((s+1)*h);					} else {						// First we create the elements, pretending AJAX is a city in Russia. 						ul.prepend(li.filter(":last-child").clone().css("margin-left","-"+ w +"px"));						ul.append(li.filter(":nth-child(2)").clone());						ul.width((s+1)*w);					}					// Now, lets check if AJAX really is a city in Russia.					if (optionsajax)					{						// Now we move from Russia back to reallity (nothing bad about the Russians, it's just a saying in Denmark.)						// Starting with putting the first document after the last. 						if (optionsajax[0]) {							ajaxLoad('last', 0, false, 0);							// ajaxLoad(0, 0, false, 0); //And this would just be a waste of brandwith. 						}						// And putting the last document before the first. 						if (optionsajax[s-1])						{							ajaxLoad('first', (s-1), false, 0);							// And then preloading the last document (the same document, but into it's entended position). No need to preload the first slide, it gets loaded elsewhere. 							ajaxLoad(ts, ts, false, 0);							optionsajax[s-1] = false;						}					}				}				else // <strike>Bug fix</strike> feature.				{					if(optionsvertical)	ul.height(s*h);					else ul.width(s*w);				};								// Display the controls.				if(options.controlsShow)				{					var controls = $('<span ' + options.controlsAttr + '></span>');					if (options.insertAfter) $(obj).after(controls);					else $(obj).before(controls);										var html = options.controlsBefore;					if(optionsnumeric) {						numericContainer = controls.prepend('<ol '+ optionsnumericAttr +'></ol>').children();						for(var i=0;i<s;i++)						{							numericControls[i] = $(document.createElement("li"))							.attr({'rel' : (i+1)})							.html('<a href="#"><span>'+ optionsnumericText[i] +'</span></a>') 							.appendTo(numericContainer)							.click(function(){								goToSlide($(this).attr('rel') - 1, true);								return false;							});						};					}					if(optionsfirstShow) {						var firstbutton = makecontrol(options.firstHtml, "first");					}					if(optionslastShow) {						var lastbutton = makecontrol(options.lastHtml, "last");					}					if(optionsprevNext){						var nextbutton = makecontrol(options.nextHtml, "next");						var prevbutton = makecontrol(options.prevHtml, "prev");					}				};								// Preload elements. 				if (options.preloadAjax)				{					for (var i=0;i<=ts;i++) // Preload everything.					{												if (optionsajax[i])						{							// If somethings is to be loaded, lets load it. 							ajaxLoad(i, i, false, 0);							// Making sure it aint loaded again. 							optionsajax[i] = false;						}					}				}								function goToSlide(i, clicked)				{					if (!destroyed)					{						if (optionsfade)						{							fadeto(i, clicked);						} else {							animate(i,clicked,true);						}					}				};				// I go a long way to save lines of code. 				function makecontrol(html, action)				{					var button = $(html);					controls.prepend(button);					button.click(function(){						goToSlide(action, true);						return false;					});					return button;				}								// Lets make those fast/normal/fast into some numbers we can make calculations with.				optionscontrolsFadeSpeed = textSpeedToNumber(optionscontrolsFadeSpeed);				optionsspeed = textSpeedToNumber(optionsspeed);				optionspause = textSpeedToNumber(optionspause);				optionsspeedhistory = textSpeedToNumber(optionsspeedhistory);				optionsfadespeed = textSpeedToNumber(optionsfadespeed);				// The functions do the magic.				function textSpeedToNumber(speed)				{					if (parseInt(speed)) var returnspeed = parseInt(speed);					else 					{						var returnspeed = 400;						switch(speed)						{						case 'fast':							returnspeed = 200;							break;						case 'normal':							returnspeed = 400;							break;						case 'medium':							returnspeed = 400;							break;						case 'slow':							returnspeed = 600;							break;						}					}					return returnspeed;				};				function runOnImagesLoaded(e,_cb)				{					// This function is based on the onImagesLoaded plugin by soundphed, that was in a comment on this page "http://engineeredweb.com/blog/09/12/preloading-images-jquery-and-javascript#comment-92". 					e.each(function() {						var $imgs = (this.tagName.toLowerCase()==='img')?$(this):$('img',this),						_cont = this,						i = 0,						_done=function() {							if( typeof _cb === 'function' ) _cb(_cont);						};												if( $imgs.length ) {							$imgs.each(function() {								var _img = this,								_checki=function(e) {									if((_img.complete) || (_img.readyState=='complete'&&e.type=='readystatechange') )									{										if( ++i===$imgs.length ) _done();									}									else if( _img.readyState === undefined ) // dont for IE									{										$(_img).attr('src',$(_img).attr('src')); // re-fire load event									}								}; // _checki \\								$(_img).bind('load readystatechange', function(e){_checki(e);});								_checki({type:'readystatechange'}); // bind to 'load' event...							});						} else _done();					});				};								// Is the file a image? (This function is not only used in the Ajaxload function)				function imageCheck(file)				{					var image = false;										var len = file.length;					var ext = file.substr(len-4, 4);										if (ext == '.jpg' || ext == '.png' || ext == '.bmp' || ext == '.gif') 					{						image = true;					}					var ext = file.substr(len-5, 5);					if (ext == '.jpeg')					{						image = true;					}										return image;				}				function fadeControl (fadeOpacity,fadetime,nextcontrol)				{					if (nextcontrol)					{						var eA = nextbutton;						var eB = lastbutton;						var directionA = 'next';						var directionB = 'last';						var firstlastshow = optionslastShow;					}					else					{						var eA = prevbutton;						var eB = firstbutton;						var directionA = 'prev';						var directionB = 'first';						var firstlastshow = optionsfirstShow;					}					if (!optionscontinuous)					{						if (optionsprevNext) eA.fadeTo(fadetime, fadeOpacity, function() { if (fadeOpacity == 0) $(this).hide();});						if (firstlastshow) eB.fadeTo(fadetime, fadeOpacity, function() { if (fadeOpacity == 0) $(this).hide();});						if(optionscustomLink)						{							$(optionscustomLink)							.filter(function(index) { 								return ($(this).attr("rel") == directionA || $(this).attr("rel") == directionB);							})							.fadeTo(fadetime, fadeOpacity, function() { if (fadeOpacity == 0) $(this).hide();});						} 					}				};				// Fade the controls, if we are at the end of the slide. 				// It's all the different kind of controls. 				function fadeControls (a,fadetime)				{					if(a==0) fadeControl (0,fadetime,false);					else fadeControl (1,fadetime,false);										if(a==ts) fadeControl (0,fadetime,true);					else fadeControl (1,fadetime,true);				};																// Updating the 'current' class				function setCurrent(i)				{					i = parseInt((i>ts) ? i=0 : ((i<0)? i=ts: i)) + 1;					for(var a=0;a<numericControls.length;a++) setCurrentElement(numericControls[a], i);					if(optionscustomLink) setCurrentElement(optionscustomLink, i);				};				function setCurrentElement(element,i)				{					$(element)						.filter(".current")						.removeClass("current")						.each(function() {							if ($.isFunction(optionsuncurrentFunc)){ optionsuncurrentFunc.call(this, $(this).attr("rel")); }						});					$(element)						.filter(function() { 							return $(this).attr("rel") == i; 						})						.addClass("current")						.each(function(index) {							if ($.isFunction(optionscurrentFunc)){ optionscurrentFunc.call(this, i); }						});				};				// Find out wich numericText fits the current url. 				function filterUrlHash(t)				{					var te = 0;					for (var i=0;i<=s;i=i+1) if (optionsnumericText[i] == t) te = i;					return te;				};				// Automaticly adjust the height, i love this function. 				function autoheight(i, speed)				{					if (i == s) i = 0;					// First i run it. In case there are no images. 					var target = li.eq(i);					var nheight = target.height();					if (nheight != 0) setHeight(nheight, speed);					// Then i run it again after the images has been loaded. (If any)					runOnImagesLoaded(target,function(imgtarget){						nheight = $(imgtarget).height();						if (nheight != 0) setHeight(nheight, speed);					});				};				function setHeight(nheight, speed)				{					obj.animate(						{ height:nheight},						{							queue:false,							duration:speed,							easing:optionsease						}					);				};				// When the animation finishes (fade or sliding), we need to adjust the slider. 				function adjust()				{					if(t>ts) t=0;					if(t<0) t=ts;					if (!optionsupdateBefore) setCurrent(t);					if(optionsvertical) ul.css("margin-top",(t*h*-1)); 	 				else ul.css("margin-left",(t*w*-1)); 					clickable = true;					if(optionshistory && buttonclicked) window.location.hash = optionsnumericText[t];					if (!fading)					{						// Lets run the after animation function.						if ($.isFunction(optionsafterAniFunc)){optionsafterAniFunc.call(li.eq(t) , t + 1);}					}				};				// Convert the direction into a usefull number.				function filterDir(dir, ot)				{					var nt = t; // i dont want to mess with the 't' variable.					switch(dir)					{						case "next":							nt = (ot>=ts) ? (optionscontinuous ? nt+1 : ts) : nt+1;							break;						case "prev":							nt = (t<=0) ? (optionscontinuous ? nt-1 : 0) : nt-1;							break;						case "first":							nt = 0;							break;						case "last":							nt = ts;							break;						default:							nt = parseInt(dir);						break;					};					return nt;				};				// Load a ajax document (or i image) into a list element. 				// If testing this locally (loading everything from a harddisk instead of the internet), it may not work. 				// But then try to upload it to a server, and see it shine. 				function ajaxLoad(i, l, adjust, speed)				{					var targetslide = false;					if (parseInt(i) || i == 0) targetslide = li.eq(i);					else					{						if (i == 'last') targetslide = $('li:last', obj);						else targetslide = $('li:first', obj);					}					// What speed should the autoheight function animate with?					var ajaxspeed = (fading) ? (!optionscrossFade ? parseInt(optionsfadespeed * (2/5)) : optionsfadespeed) : speed;					// The script itself is not using the 'tt' variable. But a custom function can use it. 					var tt = l + 1;					if (imageCheck(optionsajax[l])) 					{						// Load the image.						targetslide.html(' ').append($(new Image()).attr('src', optionsajax[l]));						// When the document is ready again, we launch a autoheight event. 						runOnImagesLoaded(targetslide,function(img){							var target = $(img).children();							// If the image is to wide, shrink it. 							var width = target.width();							var height = target.height();							target.attr({'oldheight' : height, 'oldwidth' : width});							if (width > w) target.animate({ width: w, height: (height/width)*w}, 0);							// If we want, we can launch a function here. 							if ($.isFunction(optionsimgAjaxFunction)){optionsimgAjaxFunction.call($(img), tt);}							// Then do the autoheight.							if (optionsautoheight && adjust) autoheight(t, ajaxspeed);						});					}					else					{												// Load the document into the list element. 						targetslide.load(optionsajax[l], function(response, status, xhr) {							if (status == "error" || !$(this).html()) $(this).html("Sorry but there was an error: " + (xhr.status ? xhr.status: 'no content') + " " + xhr.statusText);							// If we want, we can launch a function here. 							if (status != "error" && $.isFunction(optionsdocAjaxFunction)){optionsdocAjaxFunction.call($(this), tt);}							// Lets adjust the height, i don't care if there's an error or not. 							// var nheight = $(this).height(); // Why did i put that there??? Delete this comment when reason is found. 							if (optionsautoheight && adjust) autoheight(l, ajaxspeed); // This is theoreticly a bug-fix, if there are no images in the loaded document. 						});					}				};				// It's not only a slider, it can also fade from slide to slide. 				function fadeto(i, clicked)				{					if (i != t && !destroyed) // We doesn't want something to happen all the time. The URL can change a lot, and cause som "flickering". 					{						if (clickable)						{							ajaxloading = false;							// Stop auto if cliked.							if(clicked) clearTimeout(timeout);							// Update the current class of the buttons. 							if (optionsupdateBefore) setCurrent(filterDir(i, ot));							// Only clickable if not clicked.							clickable = !clicked;							// Setting the speed. 							var speed = (!clicked && !optionsauto && optionshistory) ? optionsfadespeed * (optionsspeedhistory / optionsspeed) : optionsfadespeed;							var ll = filterDir(i, ot);							// Lets make sure that the target actually exists. 							if(ll>ts) ll=0; 							if(ll<0) ll=ts;							// Lets make sure the prev/next buttons also fade. 							if(optionscontrolsFade) fadeControls (ll,optionscontrolsFadeSpeed);							// Lets adjust the height, but not if the ajax document isn't loaded. 							if (optionsautoheight) 							{								if (optionsajax)								{									// If Ajax is enabled									if (!optionsajax[ll]) autoheight(ll,optionsfadespeed); // we only want to change the height, if the document we are fading to, is allready loaded.								}								else autoheight(ll,optionsfadespeed); // The height animation takes the full lenght of the fade animation (fadein + fadeout if it's not crossfading).  							}							// Define the target. 							var target = li.eq(ll);							// So lets run the function.							if ($.isFunction(optionsbeforeAniFunc)){optionsbeforeAniFunc.call(target, ll + 1);}							// Crossfading?							if (optionscrossFade)							{								// I clone the target, and fade it in, then hide the cloned element while adjusting the slider to show the real target.								// I dont hide it right away, because that breaks the autoheight function, and the function that auto-resizes ajax-loaded images.								var fadeIntarget = target.clone().prependTo(obj).css({'z-index' : '100000', 'position' : 'absolute', 'list-style' : 'none', 'top' : '0', 'left' : '0'});								// Maybe we need to load some content into it first?								if (optionsajax[ll])								{									// I have to load the Ajax-content into the target clone, and the target itself. 									// First the target clone.									ajaxLoad(0, ll, false, speed);									// Then the target.									if (imageCheck(optionsajax[ll])) // Weird bugs, weird fixes. But this works. 									{										ajaxLoad(ll+1, ll, false, speed);										runOnImagesLoaded(li.eq(ll+1),function(){											if (optionsautoheight) autoheight(ll, optionsfadespeed);										});									}									else									{										ajaxLoad(ll+1, ll, true, speed);									}									optionsajax[ll] = false;								}								// Lets fade it in. 								fadeIntarget.hide().fadeIn(optionsfadespeed, function() {									// So the animate function knows what to do. 									clickable = true;									fading = true;									animate(i,false,false); // Moving to the correct place.									// Removing it again, if i dont, it will just be a pain in the ....									$(this).remove();									if(optionshistory && clicked) window.location.hash = optionsnumericText[t]; // It's just one line of code, no need to make a function of it. 									// Lets put that variable back to the default (and not during animation) value. 									fading = false;									// Now run that after animation function.									// We already got the target and the slider number from earlier.									// So lets run the function.									if ($.isFunction(optionsafterAniFunc)){optionsafterAniFunc.call(target, ll + 1);}								});							}							else							{								// fadeOut and fadeIn.								var fadeinspeed = parseInt((speed)*(3/5));								var fadeoutspeed = speed - fadeinspeed;								// I set the opacity to something higher than 0, because if it's 0, the content that i try to read (to make the autoheight work etc.) aint there.								var noncrossfadetargets = li.children();								noncrossfadetargets.stop().fadeTo(fadeoutspeed, 0.0001, function(){									// So the animation function knows what to do. 									clickable = true;									fading = true;									animate(i,false,false); // Moving to the correct place.									// Only clickable if not clicked.									clickable = !clicked; 									// Now, lets fade the slider back in. 									// Got no idea why the .add(li) is nesecary, but it is. (If it isn't there, the first slide never fades back in). 									noncrossfadetargets.add(li).stop().fadeTo(fadeinspeed, 1, function(){										if(optionshistory && clicked) window.location.hash = optionsnumericText[t]; // It's just one line of code, no need to make a function of it. 										clickable = true;										fading = false;										// Now run that after animation function.										// We already got the target and the slider number from earlier.										// So lets run the function.										if ($.isFunction(optionsafterAniFunc)){optionsafterAniFunc.call(target, ll + 1);}									});								});							}						}					}				};				function animate(dir,clicked,time) // (Direction, did the user click something, is this to be done in >1ms?) 				{					if (clickable && !destroyed && (filterDir(dir, ot) != t || init))					{						ajaxloading = false;						clickable = (!clicked && !optionsauto) ? true : options.clickableAni;						// to the adjust function. 						buttonclicked = clicked;						ot = t;						t = filterDir(dir, ot);						if (optionsupdateBefore) setCurrent(t);						// Calculating the speed to do the animation with. 						var diff = Math.sqrt(Math.abs(ot-t));						var speed = parseInt(diff*optionsspeed);						if (!clicked && !optionsauto) speed = parseInt(diff*optionsspeedhistory); // Auto:true and history:true doens't work well together, and they ain't supposed to. 						if (!time) speed = 0;												// Ajax begins here 						// I also these variables in the below code (running custom function).						var i = t;						if(t>ts) i=0;						if(t<0) i=ts;						if (optionsajax)						{							// Loading the target slide, if not already loaded. 							if (optionsajax[i]) 							{								ajaxLoad(i, i, true, speed);								optionsajax[i] = false; 								ajaxloading = true;							}							// It can look stupid the script scroll over some not-loaded slides. Therefore, they are loaded. 							// It can produce some heavy load, so the script wont do it, it it's more than 10 slides.							if (!fading)							{								// I dont like copypasting the same code, but this is the most efficient way i can think of atm. 								var countajax = 0;								if (ot > t)								{									for (a = t; a <= ot; a++)									{										if (a<=ts && a>=0)										{											if (optionsajax[a]) 											{												ajaxLoad(a, a, false, speed);												optionsajax[a] = false; 												countajax++;											}										}										if (countajax == 10) a = ot;									}								}								else								{									for (a = ot; a <= t; a++)									{										if (a<=ts && a>=0)										{											if (optionsajax[a]) 											{												ajaxLoad(a, a, false, speed);												optionsajax[a] = false; 												countajax++;											}										}										if (countajax == 10) a = t;									}								}							}							// Then we have to preload the next one. 						 	if (i + 1 <= ts)							{								if (optionsajax[i + 1]) 								{									ajaxLoad(i + 1, i + 1, false, 0);									optionsajax[i + 1] = false;								}							}							// And the previous one. 							if (i - 1 >= 0)							{								if (optionsajax[i - 1]) 								{									ajaxLoad(i - 1, i - 1, false, 0);									optionsajax[i - 1] = false;								}							}						}						// Ajax ends here						if (!fading)						{							// Lets run the before animation function.							if ($.isFunction(optionsbeforeAniFunc)){								optionsbeforeAniFunc.call(li.eq(i), i + 1);								if (t == -1 || t == s) optionsbeforeAniFunc.call(ul.children("li").eq((t == -1) ? 0 : -1), i + 1);							}													}						// Start animation. 						if(!optionsvertical) {							if (optionsautoheight && !fading && !ajaxloading) autoheight(t, speed);							p = (t*w*-1);							ul.animate(								{ marginLeft: p},								{									queue:false,									duration:speed,									easing:optionsease,									complete:adjust								}							);						} else {							p = (t*h*-1);							ul.animate(								{ marginTop: p },								{									queue:false,									duration:speed,									easing:optionsease,									complete:adjust								}							);						};						// End animation. 												// Fading the next/prev/last/first controls in/out if needed. 						if(optionscontrolsFade)						{							var fadetime = optionscontrolsFadeSpeed;							if (!clicked && !optionsauto) fadetime = (optionsspeedhistory / optionsspeed) * optionscontrolsFadeSpeed;												if (!time) fadetime = 0;							if (fading) fadetime = parseInt((optionsfadespeed)*(3/5));							fadeControls (t,fadetime);						}												// Stopping auto if clicked. 						if(clicked) clearTimeout(timeout);						// Continuing if not clicked.						if(optionsauto && dir=="next" && !clicked){							timeout = startAuto(optionspause + optionsspeed);						};						// Stop init, first animation is done. 						init = false; //nasty workaround, but it works. 					};				};				// init				var timeout;								// Starting auto. 				if(optionsauto) timeout = startAuto(optionspause);				function startAuto(pause)				{					return setTimeout(function(){						goToSlide("next", false);					},pause);				}				if (optionscustomLink) // customLinks. Easy to make, great to use. 				{					// Using live, that way javascript ajax-loaded buttons and javascript generated content will work.					$(optionscustomLink).live('click', function() {						var a = $(this).attr('rel');						if (a) doExternalInput(a);						return false;					}); 				}				obj.bind('sudoSliderEvent', function(e, a) { 					doExternalInput(a);				});				function doExternalInput(a)				{					// Check for special events					if (a == 'stop') clearTimeout(timeout)					else if (a == 'start')					{						timeout = startAuto(optionspause);						optionsauto = true;					}					else if (a == 'block') clickable = false; // Simple, beautifull.					else if (a == 'unblock') clickable = true; // -||-					else if (a == 'action') alert('The slider just performed an action'); // Kind of an easter egg. When explaining how to use "actions", i use '$("#slider").sudoSlider("action");', so i thought that the useless example should actually do something. 					else if (a == 'destroy') // For good. 					{						// First, i remove the controls. 						controls.remove(); // that's it.						// Now to set a variable, so nothing is run. 						destroyed = true; // No animation, no fading, no clicking from now. 						// Then remove the customLink bindings:						$(optionscustomLink).die("click");						// Now remove the "continuous clones". 						if (optionscontinuous)						{							ul.children("li").eq(0).remove();							ul.children("li").eq(-1).remove();						}					}					// The general case. 					// That means, typeof(a) == numbers and first,last,next,prev					// I dont make any kind of input validation, meaning that it's quite easy to break the script with non-valid input. 					else if (clickable) goToSlide((a == parseInt(a)) ? a - 1 : a, true);				};												// Lets make those bookmarks and back/forward buttons work. 				if (optionshistory) {					// Going to the correct slide at load. 					$.address.init(function(e) {						var i = filterUrlHash(e.value);				 	 	animate(i,false,false);					})					// Sliding/fading to the correct slide, on url change. 					.change(function(e) {						var i = filterUrlHash(e.value);						if (i != t) goToSlide(i, false);					});				}				// The startSlide setting only require one line of code. And here it is:	 			else if (optionsstartSlide) animate(optionsstartSlide - 1,false,false); 				// doing it anyway. good way to fix bugs. 				// And i only preload the next and previous slide after init (which this is). So i'm doing it. 				// + if i didn't do this, a lot of things wouldn't happen on page load. By always animating, i ensure that everthing that's supposed to happen, do happen. 				else animate(0,false,false); 			});		}	};})(jQuery);
