PageSourceSearch

https://unionporelperu.org/wp-content/themes/ffashion/js/jquery.sequence.js?ver=7.1.2

js unionporelperu.org collected 2026-10-01 10:25:24 UTC 66,567 bytes, 1,258 lines download raw bytes

1/*
2Sequence.js (http://www.sequencejs.com)
3Version: 1.0
4Author: Ian Lunn @IanLunn
5Author URL: http://www.ianlunn.co.uk/
6Github: https://github.com/IanLunn/Sequence
7
8This is a FREE script and is available under a MIT License:
9http://www.opensource.org/licenses/mit-license.php
10
11Sequence.js and its dependencies are (c) Ian Lunn Design 2012 - 2013 unless otherwise stated.
12
13Sequence also relies on the following open source scripts:
14
15- jQuery imagesLoaded 2.1.0 (http://github.com/desandro/imagesloaded)
16	Paul Irish et al
17	Available under a MIT License: http://www.opensource.org/licenses/mit-license.php
18
19- jQuery TouchWipe 1.1.1 (http://www.netcu.de/jquery-touchwipe-iphone-ipad-library)
20	Andreas Waltl, netCU Internetagentur (http://www.netcu.de)
21	Available under a MIT License: http://www.opensource.org/licenses/mit-license.php
22
23- Modernizr 2.6.1 Custom Build (http://modernizr.com/)
24	Copyright (c) Faruk Ates, Paul Irish, Alex Sexton
25	Available under the BSD and MIT licenses: www.modernizr.com/license/
26	*/
27
28;(function($) {
29	var windowLoaded = false;
30	$(window).on("load", function() {
31		windowLoaded = true;
32	});
33
34	function Sequence(element, options, defaults, get) {
35		var self = this;
36		self.container = $(element); //the Sequence containing element
37		self.canvas = self.container.children('.sequence-canvas'); //the Sequence canvas which holds Sequence's frames (<li> elements)
38		self.frames = self.canvas.children('li'); //the Sequence frames (top level <li> elements within the Sequence canvas)
39
40		try { //is Modernizr.prefixed installed?
41			Modernizr.prefixed;
42			if(Modernizr.prefixed === undefined){
43				throw "undefined";
44			}
45		}
46		catch(err) { //if not...get the custom build necessary for Sequence
47			get.modernizr();
48		}
49
50		var prefixes = { //convert JS transition names to CSS names
51			'WebkitTransition' : '-webkit-',
52			'MozTransition'    : '-moz-',
53			'OTransition'      : '-o-',
54			'msTransition'     : '-ms-',
55			'transition'       : ''
56		},
57		transitions = { //convert JS transition names to JS transition end and animation end event names (also apply a classname of .sequence to the event)
58			'WebkitTransition' : 'webkitTransitionEnd.sequence webkitAnimationEnd.sequence',
59			'MozTransition'    : 'transitionend.sequence animationend.sequence',
60			'OTransition'      : 'otransitionend.sequence oanimationend.sequence',
61			'msTransition'     : 'MSTransitionEnd.sequence MSAnimationEnd.sequence',
62			'transition'       : 'transitionend.sequence animationend.sequence'
63		};
64
65		self.prefix = prefixes[Modernizr.prefixed('transition')], //work out the CSS prefix for the browser being used (-webkit- for example)
66		self.transitionProperties = {},
67		self.transitionEnd = transitions[Modernizr.prefixed('transition')], //work out the JS transitionEnd name for the browser being used (webkitTransitionEnd webkitAnimationEnd for example)
68		self.numberOfFrames = self.frames.length, //number of frames (<li>) Sequence consists of
69
70		self.transitionsSupported = (self.prefix !== undefined) ? true : false, //determine if transitions are supported
71		self.hasTouch = ("ontouchstart" in window) ? true : false, //determine if this is a touch enabled device
72		self.isPaused = false, //whether Sequence is paused
73		self.isBeingHoveredOver = false, //whether the Sequence canvas is currently being hovered over
74
75		self.container.removeClass('sequence-destroyed'); //if Sequence is destroyed using .destroy(), it is given a clas of "destroy", remove that now if present
76
77		//CALLBACKS
78		self.paused = function() {},												//executes when Sequence is paused
79		self.unpaused = function() {},											//executes when Sequence is unpaused
80
81		self.beforeNextFrameAnimatesIn = function() {},			//executes before the next frame animates in
82		self.afterNextFrameAnimatesIn = function() {},			//executes after the next frame animates in
83		self.beforeCurrentFrameAnimatesOut = function() {},	//executes before the current frame animates out
84		self.afterCurrentFrameAnimatesOut = function() {},	//executes after the current frame animates out
85
86		self.afterLoaded = function() {};										//executes after Sequence is initiated
87		self.destroyed = function() {};											//executes when Sequence is destroyed via the destory() function
88
89		//INIT
90		self.settings = $.extend({}, defaults, options); //combine default options with developer defined ones
91		self.settings.preloader = renderUiElements(self, self.settings.preloader, '.sequence-preloader'); //set up the preloader and save it
92		self.isStartingFrame = (self.settings.animateStartingFrameIn) ? true : false; //determine if the first frame should animate in
93		self.settings.unpauseDelay = (self.settings.unpauseDelay === null) ? self.settings.autoPlayDelay 
93: self.settings.unpauseDelay; //if the unpauseDelay is not specified, make it the same as the autoPlayDelay speed
94		self.getHashTagFrom = (self.settings.hashDataAttribute) ? "data-sequence-hashtag": "id"; //get the hashtag from the ID or data attribute?
95		self.frameHashID = []; //array that matches frames with has IDs
96		self.direction = self.settings.autoPlayDirection;
97
98		if(self.settings.hideFramesUntilPreloaded && self.settings.preloader !== undefined  && self.settings.preloader !== false) { //if using a preloader and hiding frames until preloading has completed...
99			self.frames.hide(); //hide Sequence's frames
100		}
101
102		if(self.prefix === "-o-") { //if Opera prefixes are required...
103			self.transitionsSupported = get.operaTest(); //run a test to see if Opera correctly supports transitions (Opera 11 has bugs relating to transitions)
104		}
105
106		self.frames.removeClass("animate-in"); //remove any instance of "animate-in", which should be used incase JS is disabled
107
108		//functionality to run once Sequence has preloaded
109		function oncePreloaded() {
110			self.afterLoaded(); //callback
111			if(self.settings.hideFramesUntilPreloaded && self.settings.preloader !== undefined  && self.settings.preloader !== false) {
112				self.frames.show();
113			}
114			if(self.settings.preloader !== undefined  && self.settings.preloader !== false){
115				if(self.settings.hidePreloaderUsingCSS && self.transitionsSupported) {
116					self.prependPreloadingCompleteTo = (self.settings.prependPreloadingComplete === true) ? self.settings.preloader : $(self.settings.prependPreloadingComplete);
117					self.prependPreloadingCompleteTo.addClass("preloading-complete");
118					setTimeout(init, self.settings.hidePreloaderDelay);
119				}else{
120					self.settings.preloader.fadeOut(self.settings.hidePreloaderDelay, function() {
121						clearInterval(self.defaultPreloader);
122						init();
123					});
124				}
125			}else{
126				init();
127			}
128		}
129
130		var preloadTheseFramesLength = self.settings.preloadTheseFrames.length; //how many frames to preload?
131		var preloadTheseImagesLength = self.settings.preloadTheseImages.length; //how many single images to load?
132
133		function saveImagesToArray(length, srcOnly) {
134			var imagesToPreload = []; //saves the images that are to be preloaded
135			if(!srcOnly){
136				for(var i = length; i > 0; i--){ //for each frame to be preloaded...
137					self.frames.eq(self.settings.preloadTheseFrames[i-1]-1).find("img").each(function() { //find <img>'s in specific frames, and for each found...
138						imagesToPreload.push($(this)[0]); //add it to the array of images to be preloaded
139					});
140				}
141			}else{
142				for(var j = length; j > 0; j--) { //for each frame to be preloaded...
143					imagesToPreload.push($("body").find('img[src="'+self.settings.preloadTheseImages[j-1]+'"]')); //find any <img> with the given source and add it to the array of images to be preloaded
144				}
145			}
146			return imagesToPreload;
147		}
148
149		//jQuery imagesLoaded plugin v2.1.0 (http://github.com/desandro/imagesloaded)
150		function imagesLoaded(imagesToPreload, callback) {
151			var BLANK = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
152			var $this = imagesToPreload,
153			deferred = (typeof $.Deferred === "function") ? $.Deferred() : 0,
154			hasNotify = (typeof deferred.notify === "function"),
155			$images = $this.find('img').add( $this.filter('img') ),
156			loaded = [],
157			proper = [],
158			broken = [];
159
160			//Register deferred callbacks
161			if($.isPlainObject(callback)) {
162				$.each(callback, function(key, value) {
163					if(key === 'callback') {
164						callback = value;
165					}else if(deferred) {
166						deferred[key](value);
167					}
168				});
169			}
170
171			function doneLoading() {
172				var $proper = $(proper),
173				$broken = $(broken);
174
175				if(deferred) {
176					if(broken.length) {
177						deferred.reject($images, $proper, $broken);
178					}else{
179						deferred.resolve($images);
180					}
181				}
182
183				if((typeof callback === "function")) {
184					callback.call($this, $images, $proper, $broken);
185				}
186			}
187
188			function imgLoaded( img, isBroken ) {
189				if(img.src === BLANK || $.inArray(img, loaded) !== -1) { // don't proceed if BLANK image, or image is already loaded
190					return;
191			}
192
193				loaded.push(img); // store element in loaded images array
194
195				if(isBroken) { // keep track of broken and properly loaded images
196					broken.push(img);
197				}else{
198					proper.push(img);
199				}
200
201				$.data(img, 'imagesLoaded', {isBroken: isBroken, src: img.src }); // cache image and its state for future calls
202
203				if(hasNotify) { // trigger deferred progress method if present
204					deferred.notifyWith($(img), [isBroken, $images, $(proper), $(broken)]);
205				}
206
207				if($images.length === loaded.length) { // call doneLoading and clean listeners if all images are loaded
208					setTimeout(doneLoading);
209					$images.off('.imagesLoaded');
210				}
211			}
212
213			if(!$images.length) { // if no images, trigger immediately
214				doneLoading();
215			}else{
216				$images.on('load.imagesLoaded error.imagesLoaded', function(event) {
217					imgLoaded(event.target, event.type === 'error'); // trigger imgLoaded
218				}).each(function(i, el) {
219					var src = el.src;
220					var cached = $.data(el, 'imagesLoaded'); // find out if this image has been already checked for status if it was, and src has not changed, call imgLoaded on it
221					if(cached && cached.src === src) {
222						imgLoaded(el, cached.isBroken);
223						return;
224					}
225
226					if(el.complete && el.naturalWidth !== undefined) { // if complete is true and browser supports natural sizes, try to check for image status manually
227						imgLoaded(el, el.naturalWidth === 0 || el.naturalHeight === 0);
228						return;
229					}
230
231					// cached images don't fire load sometimes, so we reset src, but only when dealing with IE, or image is complete (loaded) and failed manual check webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
232					if(el.readyState || el.complete) {
233						el.src = BLANK;
234						el.src = src;
235					}
236				});
237			}
238		}
239
240		if(self.settings.preloader !== undefined && self.settings.preloader !== false && (preloadTheseFramesLength !== 0 || preloadTheseImagesLength !== 0)) { //if using the preloader and the dev has specified some images should preload...
241			var frameImagesToPreload = saveImagesToArray(preloadTheseFramesLength); //get images from particular Sequence frames to be preloaded
242			var individualImagesToPreload = saveImagesToArray(preloadTheseImagesLength, true); //get images with specific source values to be preloaded
243			var imagesToPreload = $(frameImagesToPreload.concat(individualImagesToPreload)); //combine frame images and individual images
244
245			imagesLoaded(imagesToPreload, oncePreloaded);
246		}else{ //if not using the preloader...
247			if(windowLoaded === true) { //if the window has already loaded...
248				oncePreloaded(); //run the init functionality when the preloader has finished
249				$(this).off("load.sequence"); //unbind the load event as it's no longer needed
250			}else{ //if the window hasn't already loaded...
251				$(window).on("load.sequence", function() { //when the window loads...	
252					oncePreloaded(); //run the init functionality when the preloader has finished
253					$(this).off("load.sequence"); //unbind the load event as it's no longer needed
254				});
255			}
256		}
257
258		function init() {
259			$(self.settings.preloader).remove(); //remove the preloader element
260
261			self.nextButton = renderUiElements(self, self.settings.nextButton, ".sequence-next"); //set up the next button
262			self.prevButton = renderUiElements(self, self.settings.prevButton, ".sequence-prev"); //set up the previous button
263			self.pauseButton = renderUiElements(self, self.settings.pauseButton, ".sequence-pause"); //set up the pause button
264			self.pagination = renderUiElements(self, self.settings.pagination, ".sequence-pagination"); //set up the pagination
265
266			if((self.nextButton !== undefined && self.nextButton !== false) && self.settings.showNextButtonOnInit === true){self.nextButton.show();} //if using a next button, show it
267			if((self.prevButton !== undefined && self.prevButton !== false) && self.settings.showPrevButtonOnInit === true){self.prevButton.show();} //if using a previous button, show it
268			if((self.pauseButton !== undefined && self.pauseButton !== false) && self.settings.showPauseButtonOnInit === true){self.pauseButton.show();} //if using a pause button, show it
269
270			if(self.settings.pauseIcon !== false) {
271				self.pauseIcon = renderUiElements(self, self.settings.pauseIcon, ".sequence-pause-icon");
272				if(self.pauseIcon !== undefined) {
273					self.pauseIcon.hide();
274				}
275			}else{
276				self.pauseIcon = undefined;
277			}
278
279			if(self.pagination !== undefined && self.pagination !== false) {
280				self.paginationLinks = self.pagination.children(); //get each pagination link
281
282				self.paginationLinks.on('click.sequence', function() { //when a pagination link is clicked...
283					var associatedFrameNumber = $(this).index() + 1; //get the number of the frame this link is associated with
284					self.goTo(associatedFrameNumber); //go to the associate frame
285				});
286
287				if(self.settings.showPaginationOnInit === true) {
288					self.pagination.show();
289				}
290			}
291
292			self.nextFrameID = self.settings.startingFrameID;
293
294			if(self.settings.hashTags === true) { //if using hashtags...
295				self.frames.each(function() { //for each frame...
296					self.frameHashID.push($(this).prop(self.getHashTagFrom)); //add the hashtag to an array
297				});
298
299				self.currentHashTag = location.hash.replace("#", ""); //get the current hashtag
300				if(self.currentHashTag === undefined || self.currentHashTag === "") { //if there is no hashtag...
301					self.nextFrameID = self.settings.startingFrameID; //use the startingFrameID
302				}else{
303					self.frameHashIndex = $.inArray(self.currentHashTag, self.frameHashID); //get the index of the frame that matches the hashtag
304					if(self.frameHashIndex !== -1){  //if the hashtag matches a Sequence frame ID...
305						self.nextFrameID = self.frameHashIndex + 1; //use the frame associated to the hashtag
306					}else{
307						self.nextFrameID = self.settings.startingFrameID; //use the startingFrameID
308					}
309				}
310			}
311
312			self.nextFrame = self.frames.eq(self.nextFrameID-1); //get the next frame
313			self.nextFrameChildren = self.nextFrame.children(); //get the elements within the next frame to be animated
314
315			if(self.pagination !== undefined) { //if using pagination, make the starting frame the current one in pagination
316				$(self.paginationLinks[self.settings.startingFrameID-1]).addClass('current'); //add the 'current' class to the current frame
317			}
318
319			if(self.transitionsSupported) { //initiate the full featured Sequence if transitions are supported...
320				if(!self.settings.animateStartingFrameIn) { //start first frame in animated in position
321					self.currentFrameID = self.nextFrameID;
322
323					if(self.settings.moveActiveFrameToTop) {
324						self.nextFrame.css('z-index', self.numberOfFrames);
325					}
326
327					resetElements(self.prefix, self.nextFrameChildren, "0s");
328					self.nextFrame.addClass("animate-in");
329					if(self.settings.hashTags && self.settings.hashChangesOnFirstFrame) {
330						self.currentHashTag = self.nextFrame.prop(self.getHashTagFrom);
331						document.location.hash = "#"+self.currentHashTag;
332					}
333
334					setTimeout(function() {
335						resetElements(self.prefix, self.nextFrameChildren, "");
336					}, 100);
337
338					resetAutoPlay(self, true, self.settings.autoPlayDelay);
339				}else if(self.settings.reverseAnimationsWhenNavigatingBackwards && self.settings.autoPlayDirection -1 && self.settings.animateStartingFrameIn) { //animate in backwards
340					resetElements(self.prefix, self.nextFrameChildren, "0s");
341					self.nextFrame.addClass("animate-out");
342					self.goTo(self.nextFrameID, -1, true);
343				}else{ //animate in forwards
344					self.goTo(self.nextFrameID, 1, true);
345				}
346			}else{ //initiate a basic slider for browsers that don't support CSS3 transitions
347				self.container.addClass("sequence-fallback");
348				self.currentFrameID = self.nextFrameID;
349				if(self.settings.hashTags && self.settings.hashChangesOnFirstFrame){
350					self.currentHashTag = self.nextFrame.prop(self.getHashTagFrom);
351					document.location.hash = "#"+self.currentHashTag;
352				}
353
354				self.frames.addClass("animate-in"); //move each frame into its animate-in position
355				//set all frames (except the next one) to display: none, opacity: 0
356				self.frames.each(function(index){
357					if (index != self.nextFrameID-1) {
358						$(this).css({"display": "none", "opacity": 0});
359					}
360				});
361				resetAutoPlay(self, true, self.settings.autoPlayDelay);
362			}
363			//END INIT
364			//EVENTS
365			if(self.nextButton !== undefined) { //if a next button is defined...
366				self.nextButton.on('click.sequence', function() { //when the next button is clicked...
367					self.next(); //go to the next frame
368				});
369			}
370
371			if(self.prevButton !== undefined) { //if a previous button is defined...
372				self.prevButton.on('click.sequence', function() { //when the previous button is clicked...
373					self.prev(); //go to the previous frame
374				});
375			}
376
377			if(self.pauseButton !== undefined) { //if a pause button is defined...
378				self.pauseButton.on('click.sequence', function() { //when the pause button is clicked...
379					self.pause(true); //pause Sequence and set hardPause to true
380				});
381			}
382
383			function keyEvents(keyPressed, keyDirections) {
384				var keyCode;
385				var keyCodes;
386
387				for(keyCodes in keyDirections) {
388					if(keyCodes === "left" || keyCodes === "right") {
389						keyCode = defaultKeys[keyCodes];
390					}else{
391						keyCode = keyCodes;
392					}
393
394					if(keyPressed === parseFloat(keyCode)) { //if the key pressed is associated with a function...
395						initCustomKeyEvent(self, keyDirections[keyCodes]); //initiate the function
396					}
397				}
398			}
399
400			if(self.settings.keyNavigation) {
401				var defaultKeys = {
402					'left'	: 37,
403					'right'	: 39
404				};
405
406				$(document).on('keydown.sequence', function(e) { //when a key is pressed...
407					var keyCodeChar = String.fromCharCode(e.keyCode);
408					if((keyCodeChar > 0 && keyCodeChar <= self.numberOfFrames) && (self.settings.numericKeysGoToFrames)) {
409						self.nextFrameID = keyCodeChar;
410						self.goTo(self.nextFrameID); //go to specified frame
411					}
412
413					keyEvents(e.keyCode, self.settings.keyEvents); //run default keyevents
414					keyEvents(e.keyCode, self.settings.customKeyEvents); //run custom keyevents
415				});
416			}
417
418			if(self.settings.pauseOnHover && self.settings.autoPlay && !self.hasTouch) { //if using pauseOnHover and autoPlay on non touch devices
419				self.canvas.on({
420					'mouseenter.sequence': function() { //when the mouse enter the Sequence element...
421						self.isBeingHoveredOver = true;
422						if(!self.isHardPaused) { //if Sequence is hard paused (via a pause button)...
423							self.pause(); //pause autoPlay
424						}
425					},
426					'mouseleave.sequence': function() { //when the mouse leaves the Sequence element...
427						self.isBeingHoveredOver = false;
428						if(!self.isHardPaused) { //if Sequence is not hard paused (via a pause button)...
429							self.unpause(); //unpause autoPlay
430						}
431					}
432				});
433			}
434
435			if(self.settings.hashTags) { //if hashchange is enabled in the settings...
436				$(window).on('hashchange.sequence', function() { //when the hashtag changes...
437					var newTag = location.hash.replace("#", ""); //grab the new hashtag
438
439					if(self.currentHashTag !== newTag) { //if the last hashtag is not the same as the current one...
440						self.currentHashTag = newTag; //save the new tag
441						self.frameHashIndex = $.inArray(self.currentHashTag, self.frameHashID); //get the index of the frame that matches the hashtag
442						if(self.frameHashIndex !== -1) { //if the hashtag matches a Sequence frame ID...
443							self.nextFrameID = self.frameHashIndex + 1; //set that frame as the next one
444								self.goTo(self.nextFrameID); //go to the next frame
445							}
446						}
447					});
448			}
449
450			function cancelTouch() {
451				self.canvas.on("touchmove.sequence", onTouchMove);
452				startX = null;
453				isMoving = false;
454			}
455
456			function onTouchMove(e) {
457				if(self.settings.swipePreventsDefault) {
458					e.preventDefault();
459				}
460				if(isMoving) {
461					var x = e.originalEvent.touches[0].pageX;
462					var y = e.originalEvent.touches[0].pageY;
463					var dx = startX - x;
464					var dy = startY - y;
465					if(Math.abs(dx) >= self.settings.swipeThreshold) {
466						cancelTouch();
467						if(dx > 0) {
468							initCustomKeyEvent(self, self.settings.swipeEvents.left);
469						}else{
470							initCustomKeyEvent(self, self.settings.swipeEvents.right);
471						}
472					}else if(Math.abs(dy) >= self.settings.swipeThreshold) {
473						cancelTouch();
474						if(dy > 0) {
475							initCustomKeyEvent(self, self.settings.swipeEvents.down);
476						}else{
477							initCustomKeyEvent(self, self.settings.swipeEvents.up);
478						}
479					}
480				}
481			}
482
483			function onTouchStart(e) {
484				if(e.originalEvent.touches.length === 1) {
485					startX = e.originalEvent.touches[0].pageX;
486					startY = e.originalEvent.touches[0].pageY;
487					isMoving = true;
488					self.canvas.on("touchmove.sequence", onTouchMove);
489				}
490			}
491
492			if(self.settings.swipeNavigation && self.hasTouch) { //if using swipeNavigation and the device has touch capabilities...
493				//jQuery TouchWipe v1.1.1 (http://www.netcu.de/jquery-touchwipe-iphone-ipad-library)
494				var startX;
495				var startY;
496				var isMoving = false;
497
498				self.canvas.on("touchstart.sequence", onTouchStart);
499			}
500			//END EVENTS
501		}
502	} //END CONSTRUCTOR
503
504	Sequence.prototype = {
505
506		//PUBLIC METHODS
507		/*
508		start autoPlay -- causing Sequence to automatically change frame every x amount of milliseconds
509		
510		delay: a time in ms before starting the autoPlay feature (if unspecified, the default will be used)
511		*/
512		startAutoPlay: function(delay) {
513			var self = this;
514			delay = (delay === undefined) ? self.settings.autoPlayDelay : delay; //if a delay isn't specified, use the default
515			self.unpause();
516
517			resetAutoPlay(self); //stop autoPlay before starting it again
518			self.autoPlayTimer = setTimeout(function() { //start a new autoPlay timer and...
519				if(self.settings.autoPlayDirection === 1) { //go to either the next or previous frame
520					self.next();
521				}else{
522					self.prev();
523				}
524			}, delay); //after a specified delay
525		},
526
527		//stop causing Sequence to automatically change frame every x amount of seconds
528		stopAutoPlay: function() {
529			var self = this;
530			self.pause(true);
531			clearTimeout(self.autoPlayTimer); //stop the autoPlay timer
532		},
533
534		/*
535		Toggle startAutoPlay (unpausing autoPlay) and stopAutoPlay (pausing autoPlay)
536
537		hardPause: if true, Sequence's pauseOnHover will not execute. Useful for pause buttons.
538
539		Note: Sequence 0.7.3 and below didn't have an .unpause() function -- .pause() would pause/unpause
540		based on the current state. .unpause() is now included for clarity but the .pause() function will
541		still toggle between paused and unpaused states.
542		*/
543		pause: function(hardPause) {
544			var self = this;
545			if(!self.isSoftPaused) { //if pausing Sequence...
546				if(self.pauseButton !== undefined) { //if a pause button is defined...
547					self.pauseButton.addClass("paused");
547 //add the class of "paused" to the pause button
548					if(self.pauseIcon !== undefined) { //if a pause icon is defined...
549						self.pauseIcon.show(); //show the pause icon
550					}
551				}
552				self.paused(); //callback when Sequence is paused
553				self.isSoftPaused = true;
554				self.isHardPaused = (hardPause) ? true : false; //if hardPausing, set hardPause to true
555				self.isPaused = true;
556				resetAutoPlay(self); //stop autoPlay
557			}else{ //if unpausing Sequence...
558				self.unpause();
559			}
560		},
561
562		/*
563		Start the autoPlay feature, as well as deal with any changes to pauseButtons, pauseIcons and public variables etc
564		
565		callback: if false, the unpause callback will not be initiated (this is because unpause is used internally during the stop and start of each frame)
566		*/
567		unpause: function(callback) {
568			var self = this;
569			if(self.pauseButton !== undefined) { //if a pause button is defined...
570				self.pauseButton.removeClass("paused"); //remove the class of "paused" from the pause button
571				if(self.pauseIcon !== undefined) { //if a pause icon is defined...
572					self.pauseIcon.hide(); //hide the pause icon
573				}
574			}
575
576			self.isSoftPaused = false;
577			self.isHardPaused = false;
578			self.isPaused = false;
579
580			if(!self.active) {
581				if(callback !== false) {
582					self.unpaused(); //callback when Sequence is unpaused
583				}
584				resetAutoPlay(self, true, self.settings.unpauseDelay); //start autoPlay after a delay specified via the unpauseDelay setting
585			}else{
586				self.delayUnpause = true; //Sequence is animating so delay the unpause event until the animation completes
587			}
588		},
589
590		//Go to the frame ahead of the current one
591		next: function() {
592			var self = this;
593			self.nextFrameID = (self.currentFrameID !== self.numberOfFrames) ? self.currentFrameID + 1 : 1; //work out the next frame
594			if(self.active === false || self.active === undefined) { //if Sequence isn't currently animating...
595				self.goTo(self.nextFrameID, 1); //go to the next frame
596			}else{ //if Sequence is currently animating...
597				self.goTo(self.nextFrameID, 1, true); //go immediately to the next frame (ignoring the transition threshold)
598			}
599		},
600
601		//Go to the frame prior to the current one
602		prev: function() {
603			var self = this;
604			self.nextFrameID = (self.currentFrameID === 1) ? self.numberOfFrames : self.currentFrameID - 1; //work out the prev frame
605			if(self.active === false || self.active === undefined) { //if Sequence isn't currently animating...
606				self.goTo(self.nextFrameID, -1); //go to the prev frame
607			}else{ //if Sequence is currently animating...
608				self.goTo(self.nextFrameID, -1, true); //go immediately to the prev frame (ignoring the transition threshold)
609			}
610		},
611
612		/*
613		Go to a specific frame
614		
615		id: number of the frame to go to
616		direction: direction to get to that frame (1 = forward, -1 = reverse)
617		ignoreTransitionThreshold: if true, ignore the transitionThreshold setting and immediately go to the specified frame
618		*/
619		goTo: function(id, direction, ignoreTransitionThreshold) {
620			var self = this;
621			id = parseFloat(id); //convert the id to a number just in case
622			var transitionThreshold = (ignoreTransitionThreshold === true) ? 0 : self.settings.transitionThreshold; //if transitionThreshold is to be ignored, set it to zero
623
624			if((id === self.currentFrameID) //if the id of the frame the user is trying to go to is the same as the currently active one...
625			|| (self.settings.navigationSkip && self.navigationSkipThresholdActive) //or navigationSkip is enabled and the navigationSkipThreshold is active (which prevents frame from being navigated too fast)...
626			|| (!self.settings.navigationSkip && self.active) //or navigationSkip is disbaled but Sequence is animating...
627			|| (!self.transitionsSupported && self.active) //or Sequence is in fallback mode and Sequence is animating...
628			|| (!self.settings.cycle && direction === 1 && self.currentFrameID === self.numberOfFrames) //or cycling is disabled, the user is navigating forward and this is the last frame...
629			|| (!self.settings.cycle && direction === -1 && self.currentFrameID === 1) //or cycling is disabled, the user is navigating backwards and this is the first frame...
630			|| (self.settings.preventReverseSkipping && self.direction !== direction && self.active)) { //or Sequence is animating and the user is trying to change the direction of navigation...
631				return false; //don't go to another frame
632			}else if(self.settings.navigationSkip && self.active) { //if navigationSkip is enabled and Sequence is animating (a frame is being skipped before it has finished animating)...
633				self.navigationSkipThresholdActive = true; //the navigationSkipThreshold is now active
634				if(self.settings.fadeFrameWhenSkipped) { //if a frame should fade when skipped...
635					self.nextFrame.stop().animate({"opacity": 0}, self.settings.fadeFrameTime); //fade
636				}
637
638				clearTimeout(self.transitionThresholdTimer);
639
640				setTimeout(function() { //start the navigationSkipThreshold timer to prevent being able to navigate too quickly
641					self.navigationSkipThresholdActive = false; //once the timer is complete, navigationSkip can occur again
642				}, self.settings.navigationSkipThreshold);
643			}
644
645			if(!self.active || self.settings.navigationSkip) { //if there are no animations running or navigationSkip is enabled...
646				self.active = true; //Sequence is now animating
647				resetAutoPlay(self); //stop any autoPlay timer that may be running
648
649				if(direction === undefined) { //if no direction to navigate was defined...
650					self.direction = (id > self.currentFrameID) ? 1 : -1; //work out which way to go based on what frame is currently active
651				}else{
652					self.direction = direction; //go to the developer defined frame
653				}
654
655				self.currentFrame = self.canvas.children(".animate-in"); //find which frame is active -- the frame currently being viewed (and about to be animated out)
656				self.nextFrame = self.frames.eq(id-1); //grab the next frame
657				self.currentFrameChildren = self.currentFrame.children();	//save the child elements of the current frame
658				self.nextFrameChildren = self.nextFrame.children(); //save the child elements of the next frame
659
660				if(self.pagination !== undefined) { //if using pagination...
661					self.paginationLinks.removeClass('current'); //remove the 'current' class from all pagination links
662					$(self.paginationLinks[id-1]).addClass('current'); //add the 'current' class to the current frame
663				}
664
665				if(self.transitionsSupported) { //if the browser supports CSS3 transitions...
666					if(self.currentFrame.length !== undefined) { //if there is a current frame (one that is in it's animate-in position)...
667						self.beforeCurrentFrameAnimatesOut(); //callback
668						if(self.settings.moveActiveFrameToTop) { //if the active frame should move to the top...
669							self.currentFrame.css("z-index", 1); //move this frame to the bottom as it is now inactive
670						}
671						resetElements(self.prefix, self.nextFrameChildren, "0s"); //give the next frame elements a transition-duration and transition-delay of 0s so they don't transition to their reset position
672						if(!self.settings.reverseAnimationsWhenNavigatingBackwards || self.direction === 1) { //if user hit next button...
673							self.nextFrame.removeClass("animate-out"); //reset the next frame back to its starting position
674							resetElements(self.prefix, self.currentFrameChildren, "");  //remove any inline styles from the elements to be animated so styles via the "animate-out" class can take full effect
675						}else if(self.settings.reverseAnimationsWhenNavigatingBackwards && self.direction === -1) { //if the user hit prev button
676							self.nextFrame.addClass("animate-out"); //reset the next frame back to its animate-out position
677							reverseTransitionProperties(self); //reverse the transition-duration, transition-delay and transition-timing-function
678						}
679					}else{
680						self.isStartingFrame = false; //no longer the first frame
681					}
682
683					self.active = true; //Sequence is now animating
684					self.currentFrame.off(self.transitionEnd); //remove the animation end event
685					self.nextFrame.off(self.transitionEnd); //remove the animation end event
686
687					if(self.settings.fadeFrameWhenSkipped && self.settings.navigationSkip) { //if a frame may have faded out when it was previously skipped...
688						self.nextFrame.css("opacity", 1); //show it again
689					}
690
691					self.beforeNextFrameAnimatesIn(); //callback
692					if(self.settings.moveActiveFrameToTop) { //if an active frame should be moved to the top...
693						self.nextFrame.css('z-index', self.numberOfFrames);
694					}
695
696					//modifications to the current and next frame's elements to get them ready to animate
697					if(!self.settings.reverseAnimationsWhenNavigatingBackwards || self.direction === 1) { //if user hit next button...
698						setTimeout(function() { //50ms timeout to give the browser a chance to modify the DOM sequentially
699							resetElements(self.prefix, self.nextFrameChildren, ""); //remove any inline styles from the elements to be animated so styles via the "animate-in" class can take full effect
700							waitForAnimationsToComplete(self, self.nextFrame, self.nextFrameChildren, "in"); //wait for the next frame to animate in
701							if(self.afterCurrentFrameAnimatesOut !== "function () {}" || (self.settings.transitionThreshold === true && ignoreTransitionThreshold !== true)) { //if the afterCurrentFrameAnimatesOut is being used...
702								waitForAnimationsToComplete(self, self.currentFrame, self.currentFrameChildren, "out", true, 1); //wait for the current frame to animate out as well
703							}
704						}, 50);
705
706						//final class changes to make animations happen
707						setTimeout(function() { //50ms timeout to give the browser a chance to modify the DOM sequentially
708							if(self.settings.transitionThreshold === false || self.settings.transitionThreshold === 0 || ignoreTransitionThreshold === true) { //if not using a transitionThreshold...
709								self.currentFrame.toggleClass("animate-out animate-in"); //remove the "animate-in" class and add the "animate-out" class to the current frame
710								self.nextFrame.addClass("animate-in");
710 //add the "animate-in" class
711							}else { //if using a transitionThreshold...
712								self.currentFrame.toggleClass("animate-out animate-in"); //remove the "animate-in" class and add the "animate-out" class to the current frame
713								if(self.settings.transitionThreshold !== true) { //if there's no transitionThreshold or the dev specified a transitionThreshold in milliseconds
714									self.transitionThresholdTimer = setTimeout(function() { //cause the next frame to animate in after a certain period
715										self.nextFrame.addClass("animate-in"); //add the "animate-in" class
716									}, transitionThreshold);
717								}
718							}
719						}, 50);
720					}else if(self.settings.reverseAnimationsWhenNavigatingBackwards && self.direction === -1) { //if the user hit prev button
721						setTimeout(function() { //50ms timeout to give the browser a chance to modify the DOM sequentially
722							//remove any inline styles from the elements so styles via the "animate-in" and "animate-out" class can take full effect
723							resetElements(self.prefix, self.currentFrameChildren, "");
724							resetElements(self.prefix, self.nextFrameChildren, "");
725							reverseTransitionProperties(self); //reverse the transition-duration, transition-delay and transition-timing-function
726
727							waitForAnimationsToComplete(self, self.nextFrame, self.nextFrameChildren, "in"); //wait for the next frame to animate in
728							if(self.afterCurrentFrameAnimatesOut !== "function () {}" || (self.settings.transitionThreshold === true && ignoreTransitionThreshold !== true)) { //if the afterCurrentFrameAnimatesOut is being used...
729								waitForAnimationsToComplete(self, self.currentFrame, self.currentFrameChildren, "out", true, -1); //wait for the current frame to animate out as well
730							}
731						}, 50);
732
733						//final class changes to make animations happen
734						setTimeout(function() { //50ms timeout to give the browser a chance to modify the DOM sequentially
735							if(self.settings.transitionThreshold === false || self.settings.transitionThreshold === 0 || ignoreTransitionThreshold === true) { //if not using a transitionThreshold...
736								self.currentFrame.removeClass("animate-in"); //remove the "animate-in" class from the current frame
737								self.nextFrame.toggleClass("animate-out animate-in"); //add the "animate-out" class and remove the "animate-in" class from the next frame
738							}else{ //if using a transitionThreshold...
739								self.currentFrame.removeClass("animate-in");
740								if(self.settings.transitionThreshold !== true) { //if there's no transitionThreshold or the dev specified a transitionThreshold in milliseconds
741									self.transitionThresholdTimer = setTimeout(function() { //cause the next frame to animate in after a certain period
742										self.nextFrame.toggleClass("animate-out animate-in"); //add the "animate-in" class and remove the "animate-out" class
743									}, transitionThreshold);
744								}
745							}
746						}, 50);
747					}
748				}else{ //if the browser doesn't support CSS3 transitions...
749					function animationComplete() {
750						setHashTag(self);
751						self.active = false;
752						resetAutoPlay(self, true, self.settings.autoPlayDelay);
753					}
754
755					switch(self.settings.fallback.theme) {
756						case "fade": //if using the fade fallback theme...
757							self.frames.css({"position": "relative"}); //this allows for fadein/out in IE
758							self.beforeCurrentFrameAnimatesOut();
759							self.currentFrame = self.frames.eq(self.currentFrameID-1);
760							self.currentFrame.animate({"opacity": 0}, self.settings.fallback.speed, function() { //hide the current frame
761								self.currentFrame.css({"display": "none", "z-index": "1"});
762								self.afterCurrentFrameAnimatesOut();
763								self.beforeNextFrameAnimatesIn();
764								self.nextFrame.css({"display": "block", "z-index": self.numberOfFrames}).animate({"opacity": 1}, 500, function() {
765									self.afterNextFrameAnimatesIn();
766								}); //make the next frame the current one and show it
767								animationComplete();
768							});
769
770							self.frames.css({"position": "relative"}); //this allows for fadein/out in IE
771						break;
772
773						case "slide": //if using the slide fallback theme...
774						default:
775							//create objects which will save the .css() and .animation() objects
776							var animateOut = {};
777							var animateIn = {};
778							var moveIn = {};
779
780							//construct the .css() and .animation() objects
781							if(self.direction === 1) {
782								animateOut.left = "-100%";
783								animateIn.left = "100%";
784							}else{
785								animateOut.left = "100%";
786								animateIn.left = "-100%";
787							}
788
789							moveIn.left = "0";
790							moveIn.opacity = 1;
791
792							self.currentFrame = self.frames.eq(self.currentFrameID-1);
793							self.beforeCurrentFrameAnimatesOut();
794							self.currentFrame.animate(animateOut, self.settings.fallback.speed, function() {
795								self.currentFrame.css({"display": "none", "z-index": "1"});
796								self.afterCurrentFrameAnimatesOut();
797							}); //cause the current frame to animate out
798							self.beforeNextFrameAnimatesIn(); //callback
799							self.nextFrame.show().css(animateIn);
800							self.nextFrame.css({"display": "block", "z-index": self.numberOfFrames}).animate(moveIn, self.settings.fallback.speed, function() { //cause the next frame to animate in
801								animationComplete();
802								self.afterNextFrameAnimatesIn(); //callback
803							});
804						break;
805					}
806				}
807				self.currentFrameID = id; //make the currentFrameID the same as the one that is to animate in
808			}
809		},
810
811		/* 
812			removes Sequence from the element it's attached to
813
814			callback: a callback to run once .destroy() has finished (or see the sequence.destroyed() callback)
815		*/
816		destroy: function(callback) {
817			var self = this;
818
819			self.container.addClass('sequence-destroyed'); //add a class of "destroyed" in case the developer wants to animate opacity etc
820
821			//REMOVE EVENTS
822			if(self.nextButton !== undefined) { //remove the next button click event if a next button is defined
823				self.nextButton.off('click.sequence');
824			}
825			if(self.prevButton !== undefined) { //remove the previous button click event if a previous button is defined
826				self.prevButton.off('click.sequence');
827			}
828			if(self.pauseButton !== undefined) { //remove the pause button click event if a pause button is defined
829				self.pauseButton.off('click.sequence');
830			}
831
832			if(self.pagination !== undefined) {
833				self.paginationLinks.off('click.sequence');
834			}
835
836			$(document).off('keydown.sequence'); //unbind key events
837			self.canvas.off('mouseenter.sequence, mouseleave.sequence, touchstart.sequence, touchmove.sequence'); //unbind mouse and touch events
838			$(window).off('hashchange.sequence'); //unbind hashchange
839
840			//CLEAR TIMERS
841			self.stopAutoPlay();
842			clearTimeout(self.transitionThresholdTimer);
843
844			//TIDY UP THE DOM
845			self.canvas.children('li').remove(); //because Sequence rearranges frames so the active one is always on top, remove them all...
846			self.canvas.prepend(self.frames); //then add them back in, in their original order
847			self.frames.removeClass('animate-in animate-out').removeAttr('style'); //remove classes and inline styles from all frames
848			self.frames.eq(self.currentFrameID-1).addClass('animate-in'); //keep the current frame in it's animate-in position
849
850			//HIDE UI ELEMENTS
851			if(self.nextButton !== undefined && self.nextButton !== false) { //if a next button is defined and was shown on initiation, hide it
852				self.nextButton.hide();
853			}
854			if(self.prevButton !== undefined && self.prevButton !== false) { //if a prev button is defined and was shown on initiation, hide it
855				self.prevButton.hide();
856			}
857			if(self.pauseButton !== undefined && self.pauseButton !== false) { //if a pause button is defined and was shown on initiation, hide it
858				self.pauseButton.hide();
859			}
860			if(self.pauseIcon !== undefined && self.pauseIcon !== false) { //if a pause icon is defined, hide it
861				self.pauseIcon.hide();
862			}
863			if(self.pagination !== undefined && self.pagination !== false) { //if pagination is defined and was shown on initiation, hide it
864				self.pagination.hide();
865			}
866
867			//CALLBACKS - a callback can either be passed into the destroy() function or by using the sequence.destroyed() publc method
868			if(callback !== undefined) {
869				callback(); //callback past into the function
870			}
871
872			self.destroyed(); //callback
873			self.container.removeData(); //remove data
874		}
875		//END PUBLIC METHODS
876	}; //END PROTOTYPE
877
878	//PRIVATE METHODS
879
880	//trigger keyEvents, customKeyEvents and swipeEvents
881	var initCustomKeyEvent = function(sequence, event) {
882		switch(event) {
883			case "next":
884			sequence.next();
885			break;
886			case "prev":
887			sequence.prev();
888			break;
889			case "pause":
890			sequence.pause(true);
891			break;
892		}
893	};
894
895	/*
896	reset the transition-duration and transition-delay properties of an element
897	
898	elementToReset = the element that is to have it's properties reset
899	cssValue = the value to be given to the transition-duration and transition-delay properties
900	*/
901	var resetElements = function(prefix, elementToReset, cssValue) {
902		elementToReset.css(
903			prefixCSS(prefix, {
904				"transition-duration": cssValue,
905				"transition-delay": cssValue,
906				"transition-timing-function": ""
907			})
908			);
909	};
910
911	/*
912	when navigating backwards and reverseAnimationsWhenNavigatingBackwards is true, take the transition properties for forward animation and manipulate the animated elements to create a perfect reversal
913	*/
914	var reverseTransitionProperties = function(sequence) {
915		var currentFrameChildrenDurations = []; //saves the duration for each of the current frame's element
916		var nextFrameChildrenDurations = []; //saves the duration for each of the next frame's element
917
918		sequence.currentFrameChildren.each(function() { //get the overall duration (including delay) for each animated element in the current frame
919			currentFrameChildrenDurations.push(parseFloat($(this).css(sequence.prefix+'transition-duration').replace('s', '')) + parseFloat($(this).css(sequence.prefix+'transition-delay').replace('s', '')));
920		});
921
922		sequence.nextFrameChildren.each(function() { //get the overall duration (including delay) for each animated element in the current frame
923			nextFrameChildrenDurations.push(parseFloat($(this).css(sequence.prefix+'transition-duration').replace('s', '')) + parseFloat($(this).css(sequence.prefix+'transition-delay').replace('s', '')));
924		});
925
926		var maximumCurrentFrameDuration = Math.max.apply(Math, currentFrameChildrenDurations); //find which transition duration is the longest
927		var maximumNextFrameDuration = Math.max.apply(Math, nextFrameChildrenDurations); //find which transition duration is the longest
928		var transitionDifference = maximumCurrentFrameDuration - maximumNextFrameDuration; //get the overal transition difference between the current and next frame
929		var currentDelay = 0;
930		var nextDelay = 0;
931
932		if(transitionDifference < 0 && !sequence.settings.preventDelayWhenReversingAnimations) { //if the current frame has a greater duration than the next frame...
933			/* note: because the current frame will take longer to animate out than the next to animate in, when this animation is reversed, the current frame will have a delay applied before it animates out. By default, Sequence will aim to avoid this (via the preventDelayWhenReversingAnimations option) because a delay on the current frame may confuse the user. The delay is removed, which means the reversal of animation is slightly out of sync */
934			currentDelay = Math.abs(transitionDifference);
935		}else if(transitionDifference > 0) { //if the next frame has a greater duration than the current frame, add the difference on as a delay
936			nextDelay = Math.abs(transitionDifference);
937		}
938
939		var reverseEachProperty = function(transitionProperties, currentFrameChildren, maximumFrameDuration, frameDelay) {
940			currentFrameChildren.each(function() {
941				var duration = parseFloat($(this).css(sequence.prefix+'transition-duration').replace('s', '')); //get the elements transition-duration
942				var delay = parseFloat($(this).css(sequence.prefix+'transition-delay').replace('s', '')); //get the elements transition-delay
943				var transitionFunction = $(this).css(sequence.prefix+'transition-timing-function'); //get the elements transiion-timing-function
944				if(transitionFunction.indexOf("cubic-bezier") >= 0) { //if the transition is a cubic-bezier...
945					var cubicBezier = transitionFunction.replace('cubic-bezier(', '').replace(')', '').split(','); //remove the CSS function and just get the array
946					$.each(cubicBezier, function(index, value) { //for each point that makes up the cubic bezier...
947						cubicBezier[index] = parseFloat(value); //turn the point into a number (rather than text)
948					});
949
950					//reverse the cubic bezier
951					var reversedCubicBezier = [
952					1 - cubicBezier[2],
953					1 - cubicBezier[3],
954					1 - cubicBezier[0],
955					1 - cubicBezier[1]
956					];
957					transitionFunction = 'cubic-bezier('+reversedCubicBezier+')'; //add the reversed cubic bezier back into a CSS function
958				}else{ //if the function isn't a cubic-bezier (WebKit returns "linear" as a text string rather than a cubic-bezier)
959					transitionFunction = 'linear'; //use a linear transition function
960				}
961				var frameDuration = duration + delay; //get the overall duration of the element
962
963				transitionProperties["transition-duration"] = duration + 's'; //reapply the element's transition-duration (to override any inline styles)
964				transitionProperties["transition-delay"] = (maximumFrameDuration - frameDuration + frameDelay) + 's'; //add a delay if required
965				transitionProperties["transition-timing-function"] = transitionFunction; //reapply the reversed transition function
966				$(this).css(
967					prefixCSS(sequence.prefix, transitionProperties) //set the new transition properties
968					);
969			});
970		};
971
972		reverseEachProperty(sequence.transitionProperties, sequence.currentFrameChildren, maximumCurrentFrameDuration, currentDelay); //reverse properties for each of the current frame's elements
973		reverseEachProperty(sequence.transitionProperties, sequence.nextFrameChildren, maximumNextFrameDuration, nextDelay); //reverse properties for each of the next frame's elements
974	};
975
976	/*
977	adds the browser vendors prefix onto multiple CSS properties
978	
979	prefix = the prefix for the browser Sequence is being viewed in (-webkit- for example)
980	properties = the properties to be prefixed (transition-duration for example)
981	*/
982	var prefixCSS = function(prefix, properties) {
983		var css = {};
984		for(var property in properties) { //for each property to be modified...
985			css[prefix + property] = properties[property]; //add the prefix to the property name
986		}
987		return css; //return the prefixed CSS
988	};
989
990	/*
991	internal function used to start and stop autoPlay
992	start: if true, autoPlay will be started, else it'll be stopped
993	delay: a time in ms before starting the autoPlay feature (if unspecified, the default will be used)
994	*/
995	var resetAutoPlay = function(sequence, start, delay) {
996		if(start === true) { //if starting autoPlay
997			if(sequence.settings.autoPlay && !sequence.isSoftPaused) { //if using autoPlay and Sequence isn't paused...
998				clearTimeout(sequence.autoPlayTimer); //stop the autoPlay timer
999				sequence.autoPlayTimer = setTimeout(function() { //start a new autoPlay timer and...
1000					if(sequence.settings.autoPlayDirection === 1) { //go to either the next or previous frame
1001						sequence.next();
1002					}else{
1003						sequence.prev();
1004					}
1005				}, delay); //after a specified delay
1006			}
1007		}else{ //if stopping autoPlay
1008			clearTimeout(sequence.autoPlayTimer); //stop the autoPlay timer
1009		}
1010	};
1011
1012	/*functionality to initiate the preloader, next/previous buttons and so on
1013	
1014	devOption: true = the developer wants to use the default selector. false = don't use a uiElement. string = the developer defined selector to use for the UI element
1015	defaultOption: the default selector to use for the UI element, when the developer specifies false for devOption
1016	*/
1017	var renderUiElements = function(sequence, devOption, defaultOption) {
1018		switch(devOption) {
1019			case false: //don't set up a uiElement
1020			return undefined;
1021
1022			case true: //use the default uiElement
1023				if(defaultOption === ".sequence-preloader") { //if setting up the preloader...
1024					get.defaultPreloader(sequence.container, sequence.transitionsSupported, sequence.prefix); //get the default preloader
1025				}
1026				return $(defaultOption); //return the default element
1027
1028			default: //if using a developer defined selector...
1029				return $(devOption); //return the developer defined element
1030		}
1031	};
1032
1033	/*
1034	prevents the next frame from animating until the current frame has finished animating
1035
1036	frame: the frame <li> which is animating
1037	self.currentFrameChildren: the animated direct child elements of the frame
1038	transitionPhase: whether the elements are animating "in" to an active position or "out" of an active position
1039	inAfterwards: whether the next frame should animate in afterwards
1040	direction: the direction of animation
1041	*/
1042	var waitForAnimationsToComplete = function(sequence, frame, currentFrameChildren, transitionPhase, inAfterwards, direction) {
1043
1044		if(transitionPhase === "out") { //if waiting on a frame's element to animate out...
1045			var onceComplete = function() {
1046				sequence.afterCurrentFrameAnimatesOut(); //callback
1047
1048				if(sequence.settings.transitionThreshold === true) {
1049					if(direction === 1) {
1050						sequence.nextFrame.addClass("animate-in");
1050 //add the "animate-in" class
1051					}else if(direction === -1) {
1052						sequence.nextFrame.toggleClass("animate-out animate-in");
1053					}
1054				}
1055			};
1056		}else if(transitionPhase === "in") { //if waiting on a frame's element to animate in...
1057			var onceComplete = function() {
1058				sequence.afterNextFrameAnimatesIn(); //callback
1059				setHashTag(sequence); //set the hashtag to represent the newly active frame
1060
1061				sequence.active = false; //Sequence is not animating
1062
1063				if(!sequence.isHardPaused && !sequence.isBeingHoveredOver) { //if Sequence isn't hard paused (via a pause button for example) or being hovered over...
1064					if(!sequence.delayUnpause) { //if unpausing isn't delayed (Sequence wasn't animating when unpause was invoked)...
1065						sequence.unpause(false); //unpause Sequence but don't run the unpause callback
1066					}else{ //if unpausing was delay because Sequence was animating when unpause was invoked...
1067						sequence.delayUnpause = false;
1068						sequence.unpause(); //unpause Sequence
1069					}
1070				}
1071			};
1072		}
1073
1074		currentFrameChildren.data('animationEnded', false); // set the data attribute of each animated element to indicate that the animation has not yet ended
1075		frame.on(sequence.transitionEnd, function(e) { //when an element finishes animating...
1076			$(e.target).data('animationEnded', true); // set the data attrbiute to indicate that the element has finished it's animation
1077
1078			// now check if all elements have finished animating
1079			var allAnimationsEnded = true;
1080			currentFrameChildren.each(function() { //for each element being animated within a frame...
1081				if($(this).data('animationEnded') === false) { //if the animation hasn't ended...
1082					allAnimationsEnded = false; //not all animations have ended yet
1083					return false; //break out of the animationEnded check early
1084				}
1085			});
1086
1087			if(allAnimationsEnded) { //if all animations have ended...
1088				frame.off(sequence.transitionEnd); //stop waiting for animations to end
1089				onceComplete();
1090			}
1091		});
1092	};
1093
1094	var setHashTag = function(sequence) {
1095		if(sequence.settings.hashTags) { //if hashTags is enabled...
1096			sequence.currentHashTag = sequence.nextFrame.prop(sequence.getHashTagFrom); //get the hashtag name
1097			sequence.frameHashIndex = $.inArray(sequence.currentHashTag, sequence.frameHashID); //get the index of the frame that matches the hashtag
1098			if(sequence.frameHashIndex !== -1 && (sequence.settings.hashChangesOnFirstFrame || (!sequence.isStartingFrame || !sequence.transitionsSupported))) { //if the hashtag matches a Sequence frame ID...
1099				sequence.nextFrameID = sequence.frameHashIndex + 1;
1100				document.location.hash = "#"+sequence.currentHashTag;
1101			}else{
1102				sequence.nextFrameID = sequence.settings.startingFrameID;
1103				sequence.isStartingFrame = false;
1104			}
1105		}
1106	};
1107
1108	var get = {
1109		/* Modernizr 2.6.1 (Custom Build) | MIT & BSD
1110		 * Build: http://modernizr.com/download/#-svg-prefixed-testprop-testallprops-domprefixes
1111		 */
1112		modernizr: function() {
1113			;window.Modernizr=function(a,b,c){function x(a){i.cssText=a}function y(a,b){return x(prefixes.join(a+";")+(b||""))}function z(a,b){return typeof a===b}function A(a,b){return!!~(""+a).indexOf(b)}function B(a,b){for(var d in a){var e=a[d];if(!A(e,"-")&&i[e]!==c)return b=="pfx"?e:!0}return!1}function C(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:z(f,"function")?f.bind(d||b):f}return!1}function D(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+m.join(d+" ")+d).split(" ");return z(b,"string")||z(b,"undefined")?B(e,b):(e=(a+" "+n.join(d+" ")+d).split(" "),C(e,b,c))}var d="2.6.1",e={},f=b.documentElement,g="modernizr",h=b.createElement(g),i=h.style,j,k={}.toString,l="Webkit Moz O ms",m=l.split(" "),n=l.toLowerCase().split(" "),o={svg:"http://www.w3.org/2000/svg"},p={},q={},r={},s=[],t=s.slice,u,v={}.hasOwnProperty,w;!z(v,"undefined")&&!z(v.call,"undefined")?w=function(a,b){return v.call(a,b)}:w=function(a,b){return b in a&&z(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=self;if(typeof c!="function")throw new TypeError;
1113var d=t.call(arguments,1),e=function(){if(self instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(t.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(t.call(arguments)))};return e}),p.svg=function(){return!!b.createElementNS&&!!b.createElementNS(o.svg,"svg").createSVGRect};for(var E in p)w(p,E)&&(u=E.toLowerCase(),e[u]=p[E](),s.push((e[u]?"":"no-")+u));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)w(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,enableClasses&&(f.className+=" "+(b?"":"no-")+a),e[a]=b}return e},x(""),h=j=null,e._version=d,e._domPrefixes=n,e._cssomPrefixes=m,e.testProp=function(a){return B([a])},e.testAllProps=D,e.prefixed=function(a,b,c){return b?D(a,b,c):D(a,"pfx")},e}(self,self.document);
1114		},
1115
1116		defaultPreloader: function(prependTo, transitions, prefix) {
1117			var icon = '<div class="sequence-preloader"><svg class="preloading" xmlns="http://www.w3.org/2000/svg"><circle class="circle" cx="6" cy="6" r="6" /><circle class="circle" cx="22" cy="6" r="6" /><circle class="circle" cx="38" cy="6" r="6" /></svg></div>';
1118
1119			$("head").append("<style>.sequence-preloader{height: 100%;position: absolute;width: 100%;z-index: 999999;}@"+prefix+"keyframes preload{0%{opacity: 1;}50%{opacity: 0;}100%{opacity: 1;}}.sequence-preloader .preloading .circle{fill: #ff9442;display: inline-block;height: 12px;position: relative;top: -50%;width: 12px;"+prefix+"animation: preload 1s infinite; animation: preload 1s infinite;}.preloading{display:block;height: 12px;margin: 0 auto;top: 50%;margin-top:-6px;position: relative;width: 48px;}.sequence-preloader .preloading .circle:nth-child(2){"+prefix+"animation-delay: .15s; animation-delay: .15s;}.sequence-preloader .preloading .circle:nth-child(3){"+prefix+"animation-delay: .3s; animation-delay: .3s;}.preloading-complete{opacity: 0;visibility: hidden;"+prefix+"transition-duration: 1s; transition-duration: 1s;}div.inline{background-color: #ff9442; margin-right: 4px; float: left;}</style>");
1120			prependTo.prepend(icon);
1121			if(!Modernizr.svg && !transitions) { //if SVG isn't supported, remain calm and add this fallback instead...
1122				$(".sequence-preloader").prepend('<div class="preloading"><div class="circle inline"></div><div class="circle inline"></div><div class="circle inline"></div></div>');
1123				setInterval(function() {
1124					$(".sequence-preloader .circle").fadeToggle(500);
1125				}, 500);
1126			}else if(!transitions) { //if transitions aren't supported, toggle the opacity instead
1127				setInterval(function() {
1128					$(".sequence-preloader").fadeToggle(500);
1129				}, 500);
1130			}
1131		},
1132
1133		//a quick test to work out if Opera supports transitions properly (to work around the fact that Opera 11 supports transitions but doesn't return a transition value properly)
1134		operaTest: function() {
1135			$("body").append('<span id="sequence-opera-test"></span>');
1136			var $operaTest = $("#sequence-opera-test");
1137			$operaTest.css("-o-transition", "1s");
1138			//if the expected value isn't returned...
1139			if($operaTest.css("-o-transition") !== "1s") {
1140				//cause Opera to go into the fallback theme
1141				return false;
1142			}else{
1143				return true;
1144			}
1145			$operaTest.remove();
1146		}
1147	};
1148	//END PRIVATE METHODS
1149
1150	//PRIVATE VARIABLES
1151
1152	var defaults = {
1153		//General Settings
1154		startingFrameID: 1, //The frame (the list item `<li>`) that should first be displayed when Sequence loads
1155		cycle: true, //Whether Sequence should navigate to the first frame after the last frame and vice versa
1156		animateStartingFrameIn: false, //Whether the first frame should animate in to its active position
1157		transitionThreshold: false, //The delay between a frame animating out and the next animating in (false = no delay, true = the next frame will animate in only once the current frame has animated out)
1158		reverseAnimationsWhenNavigatingBackwards: true, //Whether animations should be reversed when a user navigates backwards by clicking a previous button/swiping/pressing the left key
1159		preventDelayWhenReversingAnimations: false, //Whether a delay should be removed when animations are reversed. This delay is removed by default to prevent user confusion
1160		moveActiveFrameToTop: true, //Whether a frame should be given a higher `z-index` than other frames whilst it is active, to bring it above the others
1161
1162		//Autoplay Settings
1163		autoPlay: false, //Cause Sequence to automatically change between frames over a period of time, as defined in autoPlayDelay
1164		autoPlayDirection: 1, //The direction in which Sequence should auto play
1165		autoPlayDelay: 5000, //The duration in milliseconds at which frames should remain on screen before animating to the next
1166
1167		//Frame Skipping Settings
1168		navigationSkip: true, //Whether the user can navigate through frames before each frame has finished animating
1169		navigationSkipThreshold: 250, //Amount of time that must pass before the next frame can be navigated to
1170		fadeFrameWhenSkipped: true, //If a frame is skipped before it finishes animating, it will quickly fade out
1171		fadeFrameTime: 150, //If fadeFrameWhenSkipped is true, how quickly a frame should fade out when skipped (in milliseconds)
1172		preventReverseSkipping: false, //Whether the user can change the direction of navigation during frames animating (if navigating forward, the user can only skip forwards when other frames are animating).
1173
1174		//Next/Prev Button Settings
1175		nextButton: false, //if true, Sequence will use an element with class ".sequence-next" as the next button, else specify your own selector. false = don't use an in-built next button
1176		showNextButtonOnInit: true, //if true, Sequence will make the next button display: block; once Sequence has loaded (give the next button selector display: none; in the CSS to hide it until its usable)
1177		prevButton: false, //if true, Sequence will use an element with class ".sequence-prev" as the previous button, else specify your own selector. false = don't use an in-built previous button
1178		showPrevButtonOnInit: true, //if true, Sequence will make the previous button display: block; once Sequence has loaded (give the previous button selector display: none; in the CSS to hide it until its usable)
1179
1180		//Pause Settings
1181		pauseButton: false, //if true, Sequence will use an element with class ".sequence-pause" as the pause button, else specify your own selector. false = don't use an in-built pause button
1182		unpauseDelay: null, //the time to wait before navigating to the next frame when Sequence is unpaused. Note that if an unpauseDelay is not specified, the default is the same as the autoPlayDelay setting
1183		pauseOnHover: true, //pause Sequence when the Sequence container is hovered over
1184		pauseIcon: false, 	//if true, Sequence will use an element with class ".sequence-pause-icon" as the pause icon, else specify your own selector. false = don't use an in-built pause icon (the pause icon will display when Sequence is paused)
1185		showPauseButtonOnInit: true, //if true, Sequence will make the pause button display: block; once Sequence has loaded (give the pause button selector display: none; in the CSS to hide it until its usable)
1186
1187		//Pagination Settings
1188		pagination: false, //if true, Sequence will use an element with class ".sequence-pagination" as the paginated navigation, else specify your own selector. false = don't use in-built pagination
1189		showPaginationOnInit: true,  //if true, Sequence will make the pagination display: block; once Sequence has loaded (give the pagination selector display: none; in the CSS to hide it until its usable)
1190
1191		//Preloader Settings
1192		preloader: false,
1193		preloadTheseFrames: [1], //all images in these frames will load before Sequence initiates
1194		preloadTheseImages: [ //specify particular images to load before Sequence initiates
1195			/* Example usage
1196			"images/catEatingSalad.jpg",
1197			"images/meDressedAsBatman.png"
1198			*/
1199		],
1200		/*Note: You can use preloadTheseFrames and preloadTheseImages together. You might want to load all images in frame 1 and just one big image from frame 2 for example*/
1201		hideFramesUntilPreloaded: true,
1202		prependPreloadingComplete: true,
1203		hidePreloaderUsingCSS: true,
1204		hidePreloaderDelay: 0,
1205
1206		//Keyboard settings
1207		keyNavigation: true, //false prevents the following keyboard settings
1208		numericKeysGoToFrames: true,
1209		keyEvents: {
1210			left: "prev",
1211			right: "next"
1212		},
1213		customKeyEvents: {
1214			/* Example usage
1215			65: "prev",	//a
1216			68: "next",	//d
1217			83: "prev",	//s
1218			87: "next"	//w
1219			*/
1220		},
1221
1222		//Touch Swipe Settings
1223		swipeNavigation: true,
1224		swipeThreshold: 20,
1225		swipePreventsDefault: false, //be careful if setting this to true
1226		swipeEvents: {
1227			left: "prev",
1228			right: "next",
1229			up: false,
1230			down: false
1231		},
1232
1233		//hashTags Settings
1234		//when using hashTags, please include a reference to Ben Alman's jQuery HashChange plugin above your reference to Sequence.js
1235
1236		//info: http://benalman.com/projects/jquery-hashchange-plugin/
1237		//plugin: https://raw.github.com/cowboy/jquery-hashchange/v1.3/jquery.ba-hashchange.min.js
1238		//GitHub: https://github.com/cowboy/jquery-hashchange
1239		hashTags: false, //when a frame is navigated to, change the hashtag to the frames ID
1240		hashDataAttribute: false, //false = the hashTag is taken from a frames ID attribute | true = the hashTag is taken from the data attribute "data-sequence-hash"
1241		hashChangesOnFirstFrame: false, //false = the hashTag won't change for the first frame but will for those after
1242
1243		//Fallback Theme Settings (For browsers that don't support CSS3 transitions)
1244		fallback: {
1245			theme: "slide",
1246			speed: 500
1247		}
1248	};
1249	//END PRIVATE VARIABLES
1250
1251	$.fn.sequence = function(options) {
1252		return this.each(function() {
1253			if (!$.data(this, 'sequence')) { //prevent multiple initiations on the same element
1254				$.data(this, 'sequence', new Sequence($(this), options, defaults, get));
1255      }
1256		});
1257	};
1258})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.