PageSourceSearch

http://www.safety2021canada.com/wp-content/plugins/gs-logo-slider/gsl-files/js/jquery.bxslider.min.js

js safety2021canada.com collected 2026-09-28 11:03:45 UTC 64,423 bytes, 1,729 lines download raw bytes

1/**
2 * BxSlider v4.1.2 - Fully loaded, responsive content slider
3 * http://bxslider.com
4 *
5 * Copyright 2014, Steven Wanderski - http://stevenwanderski.com - http://bxcreative.com
6 * Written while drinking Belgian ales and listening to jazz
7 *
8 * Released under the MIT license - http://opensource.org/licenses/MIT
9 */
10 /* ===================================================================================== */
11 /**
12 * Custom modifications of one of my favourite responsive sliders.
13 * ---------------------------------------------------------------------------------------
14 * - Author: Rahisify
15 * - Url   : http://rahisify.com
16 * ---------------------------------------------------------------------------------------
17 * (1) Added data attributes support
18 * (2) Added break points support
19 * (3) Added automatic reload option
20 * (4) Added automatic slide width calculation 
21 * (4) Added self calling capability
22 * ---------------------------------------------------------------------------------------
23 * - Would not be possible without the awesome work of Steven Wanderski.
24 * - Released under same license - not for sale!
25 * ---------------------------------------------------------------------------------------
26 */
27
28;(function($){
29
30	var plugin = {};
31
32	var defaults = {
33
34		// GENERAL
35		mode: 'horizontal',
36		slideSelector: '',
37		infiniteLoop: true,
38		hideControlOnEnd: false,
39		speed: 500,
40		easing: null,
41		slideMargin: 0,
42		startSlide: 0,
43		randomStart: false,
44		captions: false,
45		ticker: false,
46		tickerHover: false,
47		adaptiveHeight: false,
48		adaptiveHeightSpeed: 500,
49		video: false,
50		useCSS: true,
51		preloadImages: 'visible',
52		responsive: true,
53		slideZIndex: 50,
54		wrapperClass: 'bx-wrapper',
55
56		// TOUCH
57		touchEnabled: true,
58		swipeThreshold: 50,
59		oneToOneTouch: true,
60		preventDefaultSwipeX: true,
61		preventDefaultSwipeY: false,
62
63		// PAGER
64		pager: true,
65		pagerType: 'full',
66		pagerShortSeparator: ' / ',
67		pagerSelector: null,
68		buildPager: null,
69		pagerCustom: null,
70
71		// CONTROLS
72		controls: true,
73		nextText: 'Next',
74		prevText: 'Prev',
75		nextSelector: null,
76		prevSelector: null,
77		autoControls: false,
78		startText: 'Start',
79		stopText: 'Stop',
80		autoControlsCombine: false,
81		autoControlsSelector: null,
82
83		// AUTO
84		auto: false,
85		pause: 4000,
86		autoStart: true,
87		autoDirection: 'next',
88		autoHover: false,
89		autoDelay: 0,
90		autoSlideForOnePage: false,
91
92		// CAROUSEL
93		minSlides: 1,
94		maxSlides: 1,
95		moveSlides: 0,
96		slideWidth: 0,
97    autoReload: false,
98
99		// CALLBACKS
100		onSliderLoad: function() {},
101		onSlideBefore: function() {},
102		onSlideAfter: function() {},
103		onSlideNext: function() {},
104		onSlidePrev: function() {},
105		onSliderResize: function() {}
106	}
107
108	$.fn.bxSlider = function(options){
109
110		if(this.length == 0) return this;
111
112		// support mutltiple elements
113		if(this.length > 1){
114			this.each(function(){$(this).bxSlider(options)});
115			return this;
116		}
117
118		// create a namespace to be used throughout the plugin
119		var slider = {};
120		// set a reference to our slider element
121		var el = this;
122		plugin.el = this;
123
124		/**
125		 * Makes slideshow responsive
126		 */
127		// first get the original window dimens (thanks alot IE)
128		var windowWidth = $(window).width();
129		var windowHeight = $(window).height();
130
131
132
133		/**
134		 * ===================================================================================
135		 * = PRIVATE FUNCTIONS
136		 * ===================================================================================
137		 */
138
139		/**
140		 * Initializes namespace settings to be used throughout plugin
141		 */
142		var init = function(){
143    
144      // merge user-supplied options with the defaults
145			slider.settings = $.extend({}, defaults, options);
146      
147		 /** 
148     * ===================================================================================
149		 *  CUSTOM MODIFICATIONS (Delete this block if you disapprove!)
150		 * ===================================================================================
151		 */
152     
153      // set up carousel if initial options intended to do so
154      setupCarousel();
155      
156      // screen width we will be referring to
157      var currentWidth = $(window).width();
158      // force the slider to use this width(disable if you disapprove!)
159      windowWidth = currentWidth;
160      
161      /* DEFINE FUNCTIONS WE WILL USE
162      -----------------------------------------------------------------*/
163
164      // calculates slide width
165      function calcSlideWidth (fullW, numSlides, margin) {
166      
167        var calcWidth = (fullW-(margin*(numSlides-1))) / numSlides;
168        return Math.floor(calcWidth);
169        
170      }
171      
172      // sets break point options
173      function setBreakOptions(breakObj) {
174      
175        for(var key in breakObj) {
176          slider.settings[key] = breakObj[key];
177        }
178
179      }
180      
181      // sets up carousel from available options
182      function setupCarousel() {
183
184        if(slider.settings.slides) {
185          slider.settings.maxSlides = slider.settings.slides;
186          slider.settings.minSlides = slider.settings.slides;
187          slider.settings.slideWidth = calcSlideWidth (windowWidth, slider.settings.slides, slider.settings.slideMargin);
188        } 
189        
190      }
191      
192      // converts string into valid JSON format
193      function jsonify(str) {
194        
195        str = str.replace(/([a-zA-Z0-9]+?):/g, '"$1":');
196        str = str.replace(/'/g, '"');
197        var jsonArray = jQuery.parseJSON(str);
198        return jsonArray;
199      
200      }
201      
202      // (1) Grab data options if available
203      // ---------------------------------------------------------------------------------
204      
205      var dataOptions = $(el).attr('data-options');
206
207      if(dataOptions) {
208      
209        //add curly brackets if not there
210        var lastChar = dataOptions.charAt(dataOptions.length-1);
211        var firstChar = dataOptions.charAt(0);
212        
213        if(firstChar != "{" && lastChar != "}" ) {
214          dataOptions = "{" + dataOptions + "}";
215        }
216      
217        // exploit JSON parser to lessen work
218        var opts = jsonify(dataOptions);
219        
220        for (var key in opts) {
221          slider.settings[key] = opts[key];
222        }
223        // set up carousel if options intended to do so
224        setupCarousel();
225
226      }
227      
228      // (2) Grab breaks from data attributes if available
229      // ---------------------------------------------------------------------------------
230      
231      var dataBreaks = $(el).attr('data-breaks');
232      
233      
234      if(dataBreaks) {
235        // exploit JSON parser to lessen work
236        slider.settings.breaks = jsonify(dataBreaks);
237      }
238      
239      // (3) proceed to process(if available) the user supplied break points
240      // ---------------------------------------------------------------------------------
241      
242      if(slider.settings.breaks) {
243
244        // Sort in ascending order in case of mix up
245         slider.settings.breaks.sort(function(a, b) {
246          return a.screen - b.screen;
247         });
248        
249        // Process breaks
250        for(var i = 0; i < slider.settings.breaks.length; ++i) {
251          
252          var currentBreak =  slider.settings.breaks[i];
253          var nextBreak = {};
254          var min = currentBreak.screen;
255          var max;
256          
257          if(i < slider.settings.breaks.length - 1) { // next break exists
258          
259            nextBreak = slider.settings.breaks[i+1];
260            max = nextBreak.screen;
261            
262            if(currentWidth >= min && currentWidth < max) {
263              setBreakOptions(currentBreak);
264            }
265            
266          } else { // just use current break coz next one does not exist
267          
268            if(currentWidth >= min) {
269              setBreakOptions(currentBreak);
270            }
271          }
272
273        }
274        
275        // set up carousel if options intended to do so
276        setupCarousel();
277
278      }
279      
280
281		/**
282		 * ===================================================================================
283		 * = CUSTOM MODIFICATIONS /END
284		 * ===================================================================================
285		 */
286
287			// parse slideWidth setting
288			slider.settings.slideWidth = parseInt(slider.settings.slideWidth);
289			// store the original children
290			slider.children = el.children(slider.settings.slideSelector);
291			// check if actual number of slides is less than minSlides / maxSlides
292			if(slider.children.length < slider.settings.minSlides) slider.settings.minSlides = slider.children.length;
293			if(slider.children.length < slider.settings.maxSlides) slider.settings.maxSlides = slider.children.length;
294			// if random start, set the startSlide setting to random number
295			if(slider.settings.randomStart) slider.settings.startSlide = Math.floor(Math.random() * slider.children.length);
296			// store active slide information
297			slider.active = { index: slider.settings.startSlide }
298			// store if the slider is in carousel mode (displaying / moving multiple slides)
299			slider.carousel = slider.settings.minSlides > 1 || slider.settings.maxSlides > 1;
300			// if carousel, force preloadImages = 'all'
301			if(slider.carousel) slider.settings.preloadImages = 'all';
302			// calculate the min / max width thresholds based on min / max number of slides
303			// used to setup and update carousel slides dimensions
304			slider.minThreshold = (slider.settings.minSlides * slider.settings.slideWidth) + ((slider.settings.minSlides - 1) * slider.settings.slideMargin);
305			slider.maxThreshold = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin);
306			// store the current state of the slider (if currently animating, working is true)
307			slider.working = false;
308			// initialize the controls object
309			slider.controls = {};
310			// initialize an auto interval
311			slider.interval = null;
312			// determine which property to use for transitions
313			slider.animProp = slider.settings.mode == 'vertical' ? 'top' : 'left';
314			// determine if hardware acceleration can be used
315			slider.usingCSS = slider.settings.useCSS && slider.settings.mode != 'fade' && (function(){
316				// create our test div element
317				var div = document.createElement('div');
318				// css transition properties
319				var props = ['WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective'];
320				// test for each property
321				for(var i in props){
322					if(div.style[props[i]] !== undefined){
323						slider.cssPrefix = props[i].replace('Perspective', '').toLowerCase();
324						slider.animProp = '-' + slider.cssPrefix + '-transform';
325						return true;
326					}
327				}
328				return false;
329			}());
330			// if vertical mode always make maxSlides and minSlides equal
331			if(slider.settings.mode == 'vertical') slider.settings.maxSlides = slider.settings.minSlides;
332			// save original style data
333			el.data("origStyle", el.attr("style"));
334			el.children(slider.settings.slideSelector).each(function() {
335			  $(this).data("origStyle", $(this).attr("style"));
336			});
337			// perform all DOM / CSS modifications
338			setup();
339		}
340
341		/**
342		 * Performs all DOM and CSS modifications
343		 */
344		var setup = function(){
345			// wrap el in a wrapper
346			el.wrap('<div class="' + slider.settings.wrapperClass + '"><div class="bx-viewport"></div></div>');
347			// store a namspace reference to .bx-viewport
348			slider.viewport = el.parent();
349			// add a loading div to display while images are loading
350			slider.loader = $('<div class="bx-loading" />');
351			slider.viewport.prepend(slider.loader);
352			// set el to a massive width, to hold any needed slides
353			// also strip any margin and padding from el
354			el.css({
355				width: slider.settings.mode == 'horizontal' ? (slider.children.length * 100 + 215) + '%' : 'auto',
356				position: 'relative'
357			});
358			// if using CSS, add the easing property
359			if(slider.usingCSS && slider.settings.easing){
360				el.css('-' + slider.cssPrefix + '-transition-timing-function', slider.settings.easing);
361			// if not using CSS and no easing value was supplied, use the default JS animation easing (swing)
362			}else if(!slider.settings.easing){
363				slider.settings.easing = 'swing';
364			}
365			var slidesShowing = getNumberSlidesShowing();
366			// make modifications to the viewport (.bx-viewport)
367			slider.viewport.css({
368				width: '100%',
369				overflow: 'hidden',
370				position: 'relative'
371			});
372			slider.viewport.parent().css({
373				maxWidth: getViewportMaxWidth()
374			});
375			// make modification to the wrapper (.bx-wrapper)
376			if(!slider.settings.pager) {
377				slider.viewport.parent().css({
378				margin: '0 auto 0px'
379				});
380			}
381			// apply css to all slider children
382			slider.children.css({
383				'float': slider.settings.mode == 'horizontal' ? 'left' : 'none',
384				listStyle: 'none',
385				position: 'relative'
386			});
387			// apply the calculated width after the float is applied to prevent scrollbar interference
388			slider.children.css('width', calcSlideWidthidth());
389			// if slideMargin is supplied, add the css
390			if(slider.settings.mode == 'horizontal' && slider.settings.slideMargin > 0) slider.children.css('marginRight', slider.settings.slideMargin);
391			if(slider.settings.mode == 'vertical' && slider.settings.slideMargin > 0) slider.children.css('marginBottom', slider.settings.slideMargin);
392			// if "fade" mode, add positioning and z-index CSS
393			if(slider.settings.mode == 'fade'){
394				slider.children.css({
395					position: 'absolute',
396					zIndex: 0,
397					display: 'none'
398				});
399				// prepare the z-index on the showing element
400				slider.children.eq(slider.settings.startSlide).css({zIndex: slider.settings.slideZIndex, display: 'block'});
401			}
402			// create an element to contain all slider controls (pager, start / stop, etc)
403			slider.controls.el = $('<div class="bx-controls" />');
404			// if captions are requested, add them
405			if(slider.settings.captions) appendCaptions();
406			// check if startSlide is last slide
407			slider.active.last = slider.settings.startSlide == getPagerQty() - 1;
408			// if video is true, set up the fitVids plugin
409			if(slider.settings.video) el.fitVids();
410			// set the default preload selector (visible)
411			var preloadSelector = slider.children.eq(slider.settings.startSlide);
412			if (slider.settings.preloadImages == "all") preloadSelector = slider.children;
413			// only check for control addition if not in "ticker" mode
414			if(!slider.settings.ticker){
415				// if pager is requested, add it
416				if(slider.settings.pager) appendPager();
417				// if controls are requested, add them
418				if(slider.settings.controls) appendControls();
419				// if auto is true, and auto controls are requested, add them
420				if(slider.settings.auto && slider.settings.autoControls) appendControlsAuto();
421				// if any control option is requested, add the controls wrapper
422				if(slider.settings.controls || slider.settings.autoControls || slider.settings.pager) slider.viewport.after(slider.controls.el);
423			// if ticker mode, do not allow a pager
424			}else{
425				slider.settings.pager = false;
426			}
427			// preload all images, then perform final DOM / CSS modifications that depend on images being loaded
428			loadElements(preloadSelector, start);
429		}
430
431		var loadElements = function(selector, callback){
432			var total = selector.find('img, iframe').length;
433			if (total == 0){
434				callback();
435				return;
436			}
437			var count = 0;
438			selector.find('img, iframe').each(function(){
439				$(this).one('load', function() {
440				  if(++count == total) callback();
441				}).each(function() {
442				  if(this.complete) $(this).load();
443				});
444			});
445		}
446
447		/**
448		 * Start the slider
449		 */
450		var start = function(){
451
452			// if infinite loop, prepare additional slides
453			if(slider.settings.infiniteLoop && slider.settings.mode != 'fade' && !slider.settings.ticker){
454				var slice = slider.settings.mode == 'vertical' ? slider.settings.minSlides : slider.settings.maxSlides;
455				var sliceAppend = slider.children.slice(0, slice).clone().addClass('bx-clone');
456				var slicePrepend = slider.children.slice(-slice).clone().addClass('bx-clone');
457				el.append(sliceAppend).prepend(slicePrepend);
458			}
459			// remove the loading DOM element
460			slider.loader.remove();
461			// set the left / top position of "el"
462			setSlidePosition();
463			// if "vertical" mode, always use adaptiveHeight to prevent odd behavior
464			if (slider.settings.mode == 'vertical') slider.settings.adaptiveHeight = true;
465			// set the viewport height
466			slider.viewport.height(getViewportHeight());
467			// make sure everything is positioned just right (same as a window resize)
468			el.redrawSlider();
469			// onSliderLoad callback
470			slider.settings.onSliderLoad(slider.active.index);
471			// slider has been fully initialized
472			slider.initialized = true;
473			// bind the resize call to the window
474			if (slider.settings.responsive) $(window).bind('resize', resizeWindow);
475			// if auto is true and has more than 1 page, start the show
476			if (slider.settings.auto && slider.settings.autoStart && (getPagerQty() > 1 || slider.settings.autoSlideForOnePage)) initAuto();
477			// if ticker is true, start the ticker
478			if (slider.settings.ticker) initTicker();
479			// if pager is requested, make the appropriate pager link active
480			if (slider.settings.pager) updatePagerActive(slider.settings.startSlide);
481			// check for any updates to the controls (like hideControlOnEnd updates)
482			if (slider.settings.controls) updateDirectionControls();
483			// if touchEnabled is true, setup the touch events
484			if (slider.settings.touchEnabled && !slider.settings.ticker) initTouch();
485		}
486
487		/**
488		 * Returns the calculated height of the viewport, used to determine either adaptiveHeight or the maxHeight value
489		 */
490		var getViewportHeight = function(){
491			var height = 0;
492			// first determine which children (slides) should be used in our height calculation
493			var children = $();
494			// if mode is not "vertical" and adaptiveHeight is false, include all children
495			if(slider.settings.mode != 'vertical' && !slider.settings.adaptiveHeight){
496				children = slider.children;
497			}else{
498				// if not carousel, return the single active child
499				if(!slider.carousel){
500					children = slider.children.eq(slider.active.index);
501				// if carousel, return a slice of children
502				}else{
503					// get the individual slide index
504					var currentIndex = slider.settings.moveSlides == 1 ? slider.active.index : slider.active.index * getMoveBy();
505					// add the current slide to the children
506					children = slider.children.eq(currentIndex);
507					// cycle through the remaining "showing" slides
508					for (i = 1; i <= slider.settings.maxSlides - 1; i++){
509						// if looped back to the start
510						if(currentIndex + i >= slider.children.length){
511							children = children.add(slider.children.eq(i - 1));
512						}else{
513							children = children.add(slider.children.eq(currentIndex + i));
514						}
515					}
516				}
517			}
518			// if "vertical" mode, calculate the sum of the heights of the children
519			if(slider.settings.mode == 'vertical'){
520				children.each(function(index) {
521				  height += $(this).outerHeight();
522				});
523				// add user-supplied margins
524				if(slider.settings.slideMargin > 0){
525					height += slider.settings.slideMargin * (slider.settings.minSlides - 1);
526				}
527			// if not "vertical" mode, calculate the max height of the children
528			}else{
529				height = Math.max.apply(Math, children.map(function(){
530					return $(this).outerHeight(false);
531				}).get());
532			}
533
534			if(slider.viewport.css('box-sizing') == 'border-box'){
535				height +=	parseFloat(slider.viewport.css('padding-top')) + parseFloat(slider.viewport.css('padding-bottom')) +
536							parseFloat(slider.viewport.css('border-top-width')) + parseFloat(slider.viewport.css('border-bottom-width'));
537			}else if(slider.viewport.css('box-sizing') == 'padding-box'){
538				height +=	parseFloat(slider.viewport.css('padding-top')) + parseFloat(slider.viewport.css('padding-bottom'));
539			}
540
541			return height;
542		}
543
544		/**
545		 * Returns the calculated width to be used for the outer wrapper / viewport
546		 */
547		var getViewportMaxWidth = function(){
548			var width = '100%';
549			if(slider.settings.slideWidth > 0){
550				if(slider.settings.mode == 'horizontal'){
551					width = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin);
552				}else{
553					width = slider.settings.slideWidth;
554				}
555			}
556			return width;
557		}
558
559		/**
560		 * Returns the calculated width to be applied to each slide
561		 */
562		var calcSlideWidthidth = function(){
563			// start with any user-supplied slide width
564			var newElWidth = slider.settings.slideWidth;
565			// get the current viewport width
566			var wrapWidth = slider.viewport.width();
567			// if slide width was not supplied, or is larger than the viewport use the viewport width
568			if(slider.settings.slideWidth == 0 ||
569				(slider.settings.slideWidth > wrapWidth && !slider.carousel) ||
570				slider.settings.mode == 'vertical'){
571				newElWidth = wrapWidth;
572			// if carousel, use the thresholds to determine the width
573			}else if(slider.settings.maxSlides > 1 && slider.settings.mode == 'horizontal'){
574				if(wrapWidth > slider.maxThreshold){
575					// newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.maxSlides - 1))) / slider.settings.maxSlides;
576				}else if(wrapWidth < slider.minThreshold){
577					newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.minSlides - 1))) / slider.settings.minSlides;
578				}
579			}
580			return newElWidth;
581		}
582
583		/**
584		 * Returns the number of slides currently visible in the viewport (includes partially visible slides)
585		 */
586		var getNumberSlidesShowing = function(){
587			var slidesShowing = 1;
588			if(slider.settings.mode == 'horizontal' && slider.settings.slideWidth > 0){
589				// if viewport is smaller than minThreshold, return minSlides
590				if(slider.viewport.width() < slider.minThreshold){
591					slidesShowing = slider.settings.minSlides;
592				// if viewport is larger than minThreshold, return maxSlides
593				}else if(slider.viewport.width() > slider.maxThreshold){
594					slidesShowing = slider.settings.maxSlides;
595				// if viewport is between min / max thresholds, divide viewport width by first child width
596				}else{
597					var childWidth = slider.children.first().width() + slider.settings.slideMargin;
598					slidesShowing = Math.floor((slider.viewport.width() +
599						slider.settings.slideMargin) / childWidth);
600				}
601			// if "vertical" mode, slides showing will always be minSlides
602			}else if(slider.settings.mode == 'vertical'){
603				slidesShowing = slider.settings.minSlides;
604			}
605			return slidesShowing;
606		}
607
608		/**
609		 * Returns the number of pages (one full viewport of slides is one "page")
610		 */
611		var getPagerQty = function(){
612			var pagerQty = 0;
613			// if moveSlides is specified by the user
614			if(slider.settings.moveSlides > 0){
615				if(slider.settings.infiniteLoop){
616					pagerQty = Math.ceil(slider.children.length / getMoveBy());
617				}else{
618					// use a while loop to determine pages
619					var breakPoint = 0;
620					var counter = 0
621					// when breakpoint goes above children length, counter is the number of pages
622					while (breakPoint < slider.children.length){
623						++pagerQty;
624						breakPoint = counter + getNumberSlidesShowing();
625						counter += slider.settings.moveSlides <= getNumberSlidesShowing() ? slider.settings.moveSlides : getNumberSlidesShowing();
626					}
627				}
628			// if moveSlides is 0 (auto) divide children length by sides showing, then round up
629			}else{
630				pagerQty = Math.ceil(slider.children.length / getNumberSlidesShowing());
631			}
632			return pagerQty;
633		}
634
635		/**
636		 * Returns the number of indivual slides by which to shift the slider
637		 */
638		var getMoveBy = function(){
639			// if moveSlides was set by the user and moveSlides is less than number of slides showing
640			if(slider.settings.moveSlides > 0 && slider.settings.moveSlides <= getNumberSlidesShowing()){
641				return slider.settings.moveSlides;
642			}
643			// if moveSlides is 0 (auto)
644			return getNumberSlidesShowing();
645		}
646
647		/**
648		 * Sets the slider's (el) left or top position
649		 */
650		var setSlidePosition = function(){
651			// if last slide, not infinite loop, and number of children is larger than specified maxSlides
652			if(slider.children.length > slider.settings.maxSlides && slider.active.last && !slider.settings.infiniteLoop){
653				if (slider.settings.mode == 'horizontal'){
654					// get the last child's position
655					var lastChild = slider.children.last();
656					var position = lastChild.position();
657					// set the left position
658					setPositionProperty(-(position.left - (slider.viewport.width() - lastChild.outerWidth())), 'reset', 0);
659				}else if(slider.settings.mode == 'vertical'){
660					// get the last showing index's position
661					var lastShowingIndex = slider.children.length - slider.settings.minSlides;
662					var position = slider.children.eq(lastShowingIndex).position();
663					// set the top position
664					setPositionProperty(-position.top, 'reset', 0);
665				}
666			// if not last slide
667			}else{
668				// get the position of the first showing slide
669				var position = slider.children.eq(slider.active.index * getMoveBy()).position();
670				// check for last slide
671				if (slider.active.index == getPagerQty() - 1) slider.active.last = true;
672				// set the repective position
673				if (position != undefined){
674					if (slider.settings.mode == 'horizontal') setPositionProperty(-position.left, 'reset', 0);
675					else if (slider.settings.mode == 'vertical') setPositionProperty(-position.top, 'reset', 0);
676				}
677			}
678		}
679
680		/**
681		 * Sets the el's animating property position (which in turn will sometimes animate el).
682		 * If using CSS, sets the transform property. If not using CSS, sets the top / left property.
683		 *
684		 * @param value (int)
685		 *  - the animating property's value
686		 *
687		 * @param type (string) 'slider', 'reset', 'ticker'
688		 *  - the type of instance for which the function is being
689		 *
690		 * @param duration (int)
691		 *  - the amount of time (in ms) the transition should occupy
692		 *
693		 * @param params (array) optional
694		 *  - an optional parameter containing any variables that need to be passed in
695		 */
696		var setPositionProperty = function(value, type, duration, params){
697			// use CSS transform
698			if(slider.usingCSS){
699				// determine the translate3d value
700				var propValue = slider.settings.mode == 'vertical' ? 'translate3d(0, ' + value + 'px, 0)' : 'translate3d(' + value + 'px, 0, 0)';
701				// add the CSS transition-duration
702				el.css('-' + slider.cssPrefix + '-transition-duration', duration / 1000 + 's');
703				if(type == 'slide'){
704					// set the property value
705					el.css(slider.animProp, propValue);
706					// bind a callback method - executes when CSS transition completes
707					el.bind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){
708						// unbind the callback
709						el.unbind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd');
710						updateAfterSlideTransition();
711					});
712				}else if(type == 'reset'){
713					el.css(slider.animProp, propValue);
714				}else if(type == 'ticker'){
715					// make the transition use 'linear'
716					el.css('-' + slider.cssPrefix + '-transition-timing-function', 'linear');
717					el.css(slider.animProp, propValue);
718					// bind a callback method - executes when CSS transition completes
719					el.bind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){
720						// unbind the callback
721						el.unbind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd');
722						// reset the position
723						setPositionProperty(params['resetValue'], 'reset', 0);
724						// start the loop again
725						tickerLoop();
726					});
727				}
728			// use JS animate
729			}else{
730				var animateObj = {};
731				animateObj[slider.animProp] = value;
732				if(type == 'slide'){
733					el.animate(animateObj, duration, slider.settings.easing, function(){
734						updateAfterSlideTransition();
735					});
736				}else if(type == 'reset'){
737					el.css(slider.animProp, value)
738				}else if(type == 'ticker'){
739					el.animate(animateObj, speed, 'linear', function(){
740						setPositionProperty(params['resetValue'], 'reset', 0);
741						// run the recursive loop after animation
742						tickerLoop();
743					});
744				}
745			}
746		}
747
748		/**
749		 * Populates the pager with proper amount of pages
750		 */
751		var populatePager = function(){
752			var pagerHtml = '';
753			var pagerQty = getPagerQty();
754			// loop through each pager item
755			for(var i=0; i < pagerQty; i++){
756				var linkContent = '';
757				// if a buildPager function is supplied, use it to get pager link value, else use index + 1
758				if(slider.settings.buildPager && $.isFunction(slider.settings.buildPager)){
759					linkContent = slider.settings.buildPager(i);
760					slider.pagerEl.addClass('bx-custom-pager');
761				}else{
762					linkContent = i + 1;
763					slider.pagerEl.addClass('bx-default-pager');
764				}
765				// var linkContent = slider.settings.buildPager && $.isFunction(slider.settings.buildPager) ? slider.settings.buildPager(i) : i + 1;
766				// add the markup to the string
767				pagerHtml += '<div class="bx-pager-item">
vendor: 3,630 bytes, lines 767-849
767<a href="" data-slide-index="' + i + '" class="bx-pager-link">' + linkContent + '</a></div>';
768			};
769			// populate the pager element with pager links
770			slider.pagerEl.html(pagerHtml);
771		}
772
773		/**
774		 * Appends the pager to the controls element
775		 */
776		var appendPager = function(){
777			if(!slider.settings.pagerCustom){
778				// create the pager DOM element
779				slider.pagerEl = $('<div class="bx-pager" />');
780				// if a pager selector was supplied, populate it with the pager
781				if(slider.settings.pagerSelector){
782					$(slider.settings.pagerSelector).html(slider.pagerEl);
783				// if no pager selector was supplied, add it after the wrapper
784				}else{
785					slider.controls.el.addClass('bx-has-pager').append(slider.pagerEl);
786				}
787				// populate the pager
788				populatePager();
789			}else{
790				slider.pagerEl = $(slider.settings.pagerCustom);
791			}
792			// assign the pager click binding
793			slider.pagerEl.on('click', 'a', clickPagerBind);
794		}
795
796		/**
797		 * Appends prev / next controls to the controls element
798		 */
799		var appendControls = function(){
800			slider.controls.next = $('<a class="bx-next" href="">' + slider.settings.nextText + '</a>');
801			slider.controls.prev = $('<a class="bx-prev" href="">' + slider.settings.prevText + '</a>');
802			// bind click actions to the controls
803			slider.controls.next.bind('click', clickNextBind);
804			slider.controls.prev.bind('click', clickPrevBind);
805			// if nextSlector was supplied, populate it
806			if(slider.settings.nextSelector){
807				$(slider.settings.nextSelector).append(slider.controls.next);
808			}
809			// if prevSlector was supplied, populate it
810			if(slider.settings.prevSelector){
811				$(slider.settings.prevSelector).append(slider.controls.prev);
812			}
813			// if no custom selectors were supplied
814			if(!slider.settings.nextSelector && !slider.settings.prevSelector){
815				// add the controls to the DOM
816				slider.controls.directionEl = $('<div class="bx-controls-direction" />');
817				// add the control elements to the directionEl
818				slider.controls.directionEl.append(slider.controls.prev).append(slider.controls.next);
819				// slider.viewport.append(slider.controls.directionEl);
820				slider.controls.el.addClass('bx-has-controls-direction').append(slider.controls.directionEl);
821			}
822		}
823
824		/**
825		 * Appends start / stop auto controls to the controls element
826		 */
827		var appendControlsAuto = function(){
828			slider.controls.start = $('<div class="bx-controls-auto-item"><a class="bx-start" href="">' + slider.settings.startText + '</a></div>');
829			slider.controls.stop = $('<div class="bx-controls-auto-item"><a class="bx-stop" href="">' + slider.settings.stopText + '</a></div>');
830			// add the controls to the DOM
831			slider.controls.autoEl = $('<div class="bx-controls-auto" />');
832			// bind click actions to the controls
833			slider.controls.autoEl.on('click', '.bx-start', clickStartBind);
834			slider.controls.autoEl.on('click', '.bx-stop', clickStopBind);
835			// if autoControlsCombine, insert only the "start" control
836			if(slider.settings.autoControlsCombine){
837				slider.controls.autoEl.append(slider.controls.start);
838			// if autoControlsCombine is false, insert both controls
839			}else{
840				slider.controls.autoEl.append(slider.controls.start).append(slider.controls.stop);
841			}
842			// if auto controls selector was supplied, populate it with the controls
843			if(slider.settings.autoControlsSelector){
844				$(slider.settings.autoControlsSelector).html(slider.controls.autoEl);
845			// if auto controls selector was not supplied, add it after the wrapper
846			}else{
847				slider.controls.el.addClass('bx-has-controls-auto').append(slider.controls.autoEl);
848			}
849			// update the auto controls
850			updateAutoControls(slider.settings.autoStart ? 'stop' : 'start');
851		}
852
853		/**
854		 * Appends image captions to the DOM
855		 */
856		var appendCaptions = function(){
857			// cycle through each child
858			slider.children.each(function(index){
859				// get the image title attribute
860				var title = $(this).find('img:first').attr('title');
861				// append the caption
862				if (title != undefined && ('' + title).length) {
863                    $(this).append('<div class="bx-caption"><span>' + title + '</span></div>');
864                }
865			});
866		}
867
868		/**
869		 * Click next binding
870		 *
871		 * @param e (event)
872		 *  - DOM event object
873		 */
874		var clickNextBind = function(e){
875			// if auto show is running, stop it
876			if (slider.settings.auto) el.stopAuto();
877			el.goToNextSlide();
878			e.preventDefault();
879		}
880
881		/**
882		 * Click prev binding
883		 *
884		 * @param e (event)
885		 *  - DOM event object
886		 */
887		var clickPrevBind = function(e){
888			// if auto show is running, stop it
889			if (slider.settings.auto) el.stopAuto();
890			el.goToPrevSlide();
891			e.preventDefault();
892		}
893
894		/**
895		 * Click start binding
896		 *
897		 * @param e (event)
898		 *  - DOM event object
899		 */
900		var clickStartBind = function(e){
901			el.startAuto();
902			e.preventDefault();
903		}
904
905		/**
906		 * Click stop binding
907		 *
908		 * @param e (event)
909		 *  - DOM event object
910		 */
911		var clickStopBind = function(e){
912			el.stopAuto();
913			e.preventDefault();
914		}
915
916		/**
917		 * Click pager binding
918		 *
919		 * @param e (event)
920		 *  - DOM event object
921		 */
922		var clickPagerBind = function(e){
923			// if auto show is running, stop it
924			if (slider.settings.auto) el.stopAuto();
925			var pagerLink = $(e.currentTarget);
926			if(pagerLink.attr('data-slide-index') !== undefined){
927				var pagerIndex = parseInt(pagerLink.attr('data-slide-index'));
928				// if clicked pager link is not active, continue with the goToSlide call
929				if(pagerIndex != slider.active.index) el.goToSlide(pagerIndex);
930				e.preventDefault();
931			}
932		}
933
934		/**
935		 * Updates the pager links with an active class
936		 *
937		 * @param slideIndex (int)
938		 *  - index of slide to make active
939		 */
940		var updatePagerActive = function(slideIndex){
941			// if "short" pager type
942			var len = slider.children.length; // nb of children
943			if(slider.settings.pagerType == 'short'){
944				if(slider.settings.maxSlides > 1) {
945					len = Math.ceil(slider.children.length/slider.settings.maxSlides);
946				}
947				slider.pagerEl.html( (slideIndex + 1) + slider.settings.pagerShortSeparator + len);
948				return;
949			}
950			// remove all pager active classes
951			slider.pagerEl.find('a').removeClass('active');
952			// apply the active class for all pagers
953			slider.pagerEl.each(function(i, el) { $(el).find('a').eq(slideIndex).addClass('active'); });
954		}
955
956		/**
957		 * Performs needed actions after a slide transition
958		 */
959		var updateAfterSlideTransition = function(){
960			// if infinte loop is true
961			if(slider.settings.infiniteLoop){
962				var position = '';
963				// first slide
964				if(slider.active.index == 0){
965					// set the new position
966					position = slider.children.eq(0).position();
967				// carousel, last slide
968				}else if(slider.active.index == getPagerQty() - 1 && slider.carousel){
969					position = slider.children.eq((getPagerQty() - 1) * getMoveBy()).position();
970				// last slide
971				}else if(slider.active.index == slider.children.length - 1){
972					position = slider.children.eq(slider.children.length - 1).position();
973				}
974				if(position){
975					if (slider.settings.mode == 'horizontal') { setPositionProperty(-position.left, 'reset', 0); }
976					else if (slider.settings.mode == 'vertical') { setPositionProperty(-position.top, 'reset', 0); }
977				}
978			}
979			// declare that the transition is complete
980			slider.working = false;
981			// onSlideAfter callback
982			slider.settings.onSlideAfter(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);
983		}
984
985		/**
986		 * Updates the auto controls state (either active, or combined switch)
987		 *
988		 * @param state (string) "start", "stop"
989		 *  - the new state of the auto show
990		 */
991		var updateAutoControls = function(state){
992			// if autoControlsCombine is true, replace the current control with the new state
993			if(slider.settings.autoControlsCombine){
994				slider.controls.autoEl.html(slider.controls[state]);
995			// if autoControlsCombine is false, apply the "active" class to the appropriate control
996			}else{
997				slider.controls.autoEl.find('a').removeClass('active');
998				slider.controls.autoEl.find('a:not(.bx-' + state + ')').addClass('active');
999			}
1000		}
1001
1002		/**
1003		 * Updates the direction controls (checks if either should be hidden)
1004		 */
1005		var updateDirectionControls = function(){
1006			if(getPagerQty() == 1){
1007				slider.controls.prev.addClass('disabled');
1008				slider.controls.next.addClass('disabled');
1009			}else if(!slider.settings.infiniteLoop && slider.settings.hideControlOnEnd){
1010				// if first slide
1011				if (slider.active.index == 0){
1012					slider.controls.prev.addClass('disabled');
1013					slider.controls.next.removeClass('disabled');
1014				// if last slide
1015				}else if(slider.active.index == getPagerQty() - 1){
1016					slider.controls.next.addClass('disabled');
1017					slider.controls.prev.removeClass('disabled');
1018				// if any slide in the middle
1019				}else{
1020					slider.controls.prev.removeClass('disabled');
1021					slider.controls.next.removeClass('disabled');
1022				}
1023			}
1024		}
1025
1026		/**
1027		 * Initialzes the auto process
1028		 */
1029		var initAuto = function(){
1030			// if autoDelay was supplied, launch the auto show using a setTimeout() call
1031			if(slider.settings.autoDelay > 0){
1032				var timeout = setTimeout(el.startAuto, slider.settings.autoDelay);
1033			// if autoDelay was not supplied, start the auto show normally
1034			}else{
1035				el.startAuto();
1036			}
1037			// if autoHover is requested
1038			if(slider.settings.autoHover){
1039				// on el hover
1040				el.hover(function(){
1041					// if the auto show is currently playing (has an active interval)
1042					if(slider.interval){
1043						// stop the auto show and pass true agument which will prevent control update
1044						el.stopAuto(true);
1045						// create a new autoPaused value which will be used by the relative "mouseout" event
1046						slider.autoPaused = true;
1047					}
1048				}, function(){
1049					// if the autoPaused value was created be the prior "mouseover" event
1050					if(slider.autoPaused){
1051						// start the auto show and pass true agument which will prevent control update
1052						el.startAuto(true);
1053						// reset the autoPaused value
1054						slider.autoPaused = null;
1055					}
1056				});
1057			}
1058		}
1059
1060		/**
1061		 * Initialzes the ticker process
1062		 */
1063		var initTicker = function(){
1064			var startPosition = 0;
1065			// if autoDirection is "next", append a clone of the entire slider
1066			if(slider.settings.autoDirection == 'next'){
1067				el.append(slider.children.clone().addClass('bx-clone'));
1068			// if autoDirection is "prev", prepend a clone of the entire slider, and set the left position
1069			}else{
1070				el.prepend(slider.children.clone().addClass('bx-clone'));
1071				var position = slider.children.first().position();
1072				startPosition = slider.settings.mode == 'horizontal' ? -position.left : -position.top;
1073			}
1074			setPositionProperty(startPosition, 'reset', 0);
1075			// do not allow controls in ticker mode
1076			slider.settings.pager = false;
1077			slider.settings.controls = false;
1078			slider.settings.autoControls = false;
1079			// if autoHover is requested
1080			if(slider.settings.tickerHover && !slider.usingCSS){
1081				// on el hover
1082				slider.viewport.hover(function(){
1083					el.stop();
1084				}, function(){
1085					// calculate the total width of children (used to calculate the speed ratio)
1086					var totalDimens = 0;
1087					slider.children.each(function(index){
1088					  totalDimens += slider.settings.mode == 'horizontal' ? $(this).outerWidth(true) : $(this).outerHeight(true);
1089					});
1090					// calculate the speed ratio (used to determine the new speed to finish the paused animation)
1091					var ratio = slider.settings.speed / totalDimens;
1092					// determine which property to use
1093					var property = slider.settings.mode == 'horizontal' ? 'left' : 'top';
1094					// calculate the new speed
1095					var newSpeed = ratio * (totalDimens - (Math.abs(parseInt(el.css(property)))));
1096					tickerLoop(newSpeed);
1097				});
1098			}
1099			// start the ticker loop
1100			tickerLoop();
1101		}
1102
1103		/**
1104		 * Runs a continuous loop, news ticker-style
1105		 */
1106		var tickerLoop = function(resumeSpeed){
1107			speed = resumeSpeed ? resumeSpeed : slider.settings.speed;
1108			var position = {left: 0, top: 0};
1109			var reset = {left: 0, top: 0};
1110			// if "next" animate left position to last child, then reset left to 0
1111			if(slider.settings.autoDirection == 'next'){
1112				position = el.find('.bx-clone').first().position();
1113			// if "prev" animate left position to 0, then reset left to first non-clone child
1114			}else{
1115				reset = slider.children.first().position();
1116			}
1117			var animateProperty = slider.settings.mode == 'horizontal' ? -position.left : -position.top;
1118			var resetValue = slider.settings.mode == 'horizontal' ? -reset.left : -reset.top;
1119			var params = {resetValue: resetValue};
1120			setPositionProperty(animateProperty, 'ticker', speed, params);
1121		}
1122
1123		/**
1124		 * Initializes touch events
1125		 */
1126		var initTouch = function(){
1127			// initialize object to contain all touch values
1128			slider.touch = {
1129				start: {x: 0, y: 0},
1130				end: {x: 0, y: 0}
1131			}
1132			slider.viewport.bind('touchstart', onTouchStart);
1133		}
1134
1135		/**
1136		 * Event handler for "touchstart"
1137		 *
1138		 * @param e (event)
1139		 *  - DOM event object
1140		 */
1141		var onTouchStart = function(e){
1142			if(slider.working){
1143				e.preventDefault();
1144			}else{
1145				// record the original position when touch starts
1146				slider.touch.originalPos = el.position();
1147				var orig = e.originalEvent;
1148				// record the starting touch x, y coordinates
1149				slider.touch.start.x = orig.changedTouches[0].pageX;
1150				slider.touch.start.y = orig.changedTouches[0].pageY;
1151				// bind a "touchmove" event to the viewport
1152				slider.viewport.bind('touchmove', onTouchMove);
1153				// bind a "touchend" event to the viewport
1154				slider.viewport.bind('touchend', onTouchEnd);
1155			}
1156		}
1157
1158		/**
1159		 * Event handler for "touchmove"
1160		 *
1161		 * @param e (event)
1162		 *  - DOM event object
1163		 */
1164		var onTouchMove = function(e){
1165			var orig = e.originalEvent;
1166			// if scrolling on y axis, do not prevent default
1167			var xMovement = Math.abs(orig.changedTouches[0].pageX - slider.touch.start.x);
1168			var yMovement = Math.abs(orig.changedTouches[0].pageY - slider.touch.start.y);
1169			// x axis swipe
1170			if((xMovement * 3) > yMovement && slider.settings.preventDefaultSwipeX){
1171				e.preventDefault();
1172			// y axis swipe
1173			}else if((yMovement * 3) > xMovement && slider.settings.preventDefaultSwipeY){
1174				e.preventDefault();
1175			}
1176			if(slider.settings.mode != 'fade' && slider.settings.oneToOneTouch){
1177				var value = 0;
1178				// if horizontal, drag along x axis
1179				if(slider.settings.mode == 'horizontal'){
1180					var change = orig.changedTouches[0].pageX - slider.touch.start.x;
1181					value = slider.touch.originalPos.left + change;
1182				// if vertical, drag along y axis
1183				}else{
1184					var change = orig.changedTouches[0].pageY - slider.touch.start.y;
1185					value = slider.touch.originalPos.top + change;
1186				}
1187				setPositionProperty(value, 'reset', 0);
1188			}
1189		}
1190
1191		/**
1192		 * Event handler for "touchend"
1193		 *
1194		 * @param e (event)
1195		 *  - DOM event object
1196		 */
1197		var onTouchEnd = function(e){
1198			slider.viewport.unbind('touchmove', onTouchMove);
1199			var orig = e.originalEvent;
1200			var value = 0;
1201			// record end x, y positions
1202			slider.touch.end.x = orig.changedTouches[0].pageX;
1203			slider.touch.end.y = orig.changedTouches[0].pageY;
1204			// if fade mode, check if absolute x distance clears the threshold
1205			if(slider.settings.mode == 'fade'){
1206				var distance = Math.abs(slider.touch.start.x - slider.touch.end.x);
1207				if(distance >= slider.settings.swipeThreshold){
1208					slider.touch.start.x > slider.touch.end.x ? el.goToNextSlide() : el.goToPrevSlide();
1209					el.stopAuto();
1210				}
1211			// not fade mode
1212			}else{
1213				var distance = 0;
1214				// calculate distance and el's animate property
1215				if(slider.settings.mode == 'horizontal'){
1216					distance = slider.touch.end.x - slider.touch.start.x;
1217					value = slider.touch.originalPos.left;
1218				}else{
1219					distance = slider.touch.end.y - slider.touch.start.y;
1220					value = slider.touch.originalPos.top;
1221				}
1222				// if not infinite loop and first / last slide, do not attempt a slide transition
1223				if(!slider.settings.infiniteLoop && ((slider.active.index == 0 && distance > 0) || (slider.active.last && distance < 0))){
1224					setPositionProperty(value, 'reset', 200);
1225				}else{
1226					// check if distance clears threshold
1227					if(Math.abs(distance) >= slider.settings.swipeThreshold){
1228						distance < 0 ? el.goToNextSlide() : el.goToPrevSlide();
1229						el.stopAuto();
1230					}else{
1231						// el.animate(property, 200);
1232						setPositionProperty(value, 'reset', 200);
1233					}
1234				}
1235			}
1236			slider.viewport.unbind('touchend', onTouchEnd);
1237		}
1238
1239		/**
1240		 * Window resize event callback
1241		 */
1242		var resizeWindow = function(e){
1243			// don't do anything if slider isn't initialized.
1244			if(!slider.initialized) return;
1245			// get the new window dimens (again, thank you IE)
1246			var windowWidthNew = $(window).width();
1247			var windowHeightNew = $(window).height();
1248			// make sure that it is a true window resize
1249			// *we must check this because our dinosaur friend IE fires a window resize event when certain DOM elements
1250			// are resized. Can you just die already?*
1251			if(windowWidth != windowWidthNew || windowHeight != windowHeightNew){
1252				// set the new window dimens
1253				windowWidth = windowWidthNew;
1254				windowHeight = windowHeightNew;
1255				// update all dynamic elements
1256				el.redrawSlider();
1257				// Call user resize handler
1258				slider.settings.onSliderResize.call(el, slider.active.index);
1259			}
1260		}
1261
1262		/**
1263		 * ===================================================================================
1264		 * = PUBLIC FUNCTIONS
1265		 * ===================================================================================
1266		 */
1267
1268		/**
1269		 * Performs slide transition to the specified slide
1270		 *
1271		 * @param slideIndex (int)
1272		 *  - the destination slide's index (zero-based)
1273		 *
1274		 * @param direction (string)
1275		 *  - INTERNAL USE ONLY - the direction of travel ("prev" / "next")
1276		 */
1277		el.goToSlide = function(slideIndex, direction){
1278			// if plugin is currently in motion, ignore request
1279			if(slider.working || slider.active.index == slideIndex) return;
1280			// declare that plugin is in motion
1281			slider.working = true;
1282			// store the old index
1283			slider.oldIndex = slider.active.index;
1284			// if slideIndex is less than zero, set active index to last child (this happens during infinite loop)
1285			if(slideIndex < 0){
1286				slider.active.index = getPagerQty() - 1;
1287			// if slideIndex is greater than children length, set active index to 0 (this happens during infinite loop)
1288			}else if(slideIndex >= getPagerQty()){
1289				slider.active.index = 0;
1290			// set active index to requested slide
1291			}else{
1292				slider.active.index = slideIndex;
1293			}
1294			// onSlideBefore, onSlideNext, onSlidePrev callbacks
1295			slider.settings.onSlideBefore(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);
1296			if(direction == 'next'){
1297				slider.settings.onSlideNext(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);
1298			}else if(direction == 'prev'){
1299				slider.settings.onSlidePrev(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);
1300			}
1301			// check if last slide
1302			slider.active.last = slider.active.index >= getPagerQty() - 1;
1303			// update the pager with active class
1304			if(slider.settings.pager) updatePagerActive(slider.active.index);
1305			// // check for direction control update
1306			if(slider.settings.controls) updateDirectionControls();
1307			// if slider is set to mode: "fade"
1308			if(slider.settings.mode == 'fade'){
1309				// if adaptiveHeight is true and next height is different from current height, animate to the new height
1310				if(slider.settings.adaptiveHeight && slider.viewport.height() != getViewportHe
1310ight()){
1311					slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed);
1312				}
1313				// fade out the visible child and reset its z-index value
1314				slider.children.filter(':visible').fadeOut(slider.settings.speed).css({zIndex: 0});
1315				// fade in the newly requested slide
1316				slider.children.eq(slider.active.index).css('zIndex', slider.settings.slideZIndex+1).fadeIn(slider.settings.speed, function(){
1317					$(this).css('zIndex', slider.settings.slideZIndex);
1318					updateAfterSlideTransition();
1319				});
1320			// slider mode is not "fade"
1321			}else{
1322				// if adaptiveHeight is true and next height is different from current height, animate to the new height
1323				if(slider.settings.adaptiveHeight && slider.viewport.height() != getViewportHeight()){
1324					slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed);
1325				}
1326				var moveBy = 0;
1327				var position = {left: 0, top: 0};
1328				// if carousel and not infinite loop
1329				if(!slider.settings.infiniteLoop && slider.carousel && slider.active.last){
1330					if(slider.settings.mode == 'horizontal'){
1331						// get the last child position
1332						var lastChild = slider.children.eq(slider.children.length - 1);
1333						position = lastChild.position();
1334						// calculate the position of the last slide
1335						moveBy = slider.viewport.width() - lastChild.outerWidth();
1336					}else{
1337						// get last showing index position
1338						var lastShowingIndex = slider.children.length - slider.settings.minSlides;
1339						position = slider.children.eq(lastShowingIndex).position();
1340					}
1341					// horizontal carousel, going previous while on first slide (infiniteLoop mode)
1342				}else if(slider.carousel && slider.active.last && direction == 'prev'){
1343					// get the last child position
1344					var eq = slider.settings.moveSlides == 1 ? slider.settings.maxSlides - getMoveBy() : ((getPagerQty() - 1) * getMoveBy()) - (slider.children.length - slider.settings.maxSlides);
1345					var lastChild = el.children('.bx-clone').eq(eq);
1346					position = lastChild.position();
1347				// if infinite loop and "Next" is clicked on the last slide
1348				}else if(direction == 'next' && slider.active.index == 0){
1349					// get the last clone position
1350					position = el.find('> .bx-clone').eq(slider.settings.maxSlides).position();
1351					slider.active.last = false;
1352				// normal non-zero requests
1353				}else if(slideIndex >= 0){
1354					var requestEl = slideIndex * getMoveBy();
1355					position = slider.children.eq(requestEl).position();
1356				}
1357
1358				/* If the position doesn't exist
1359				 * (e.g. if you destroy the slider on a next click),
1360				 * it doesn't throw an error.
1361				 */
1362				if ("undefined" !== typeof(position)) {
1363					var value = slider.settings.mode == 'horizontal' ? -(position.left - moveBy) : -position.top;
1364					// plugin values to be animated
1365					setPositionProperty(value, 'slide', slider.settings.speed);
1366				}
1367			}
1368		}
1369
1370		/**
1371		 * Transitions to the next slide in the show
1372		 */
1373		el.goToNextSlide = function(){
1374			// if infiniteLoop is false and last page is showing, disregard call
1375			if (!slider.settings.infiniteLoop && slider.active.last) return;
1376			var pagerIndex = parseInt(slider.active.index) + 1;
1377			el.goToSlide(pagerIndex, 'next');
1378		}
1379
1380		/**
1381		 * Transitions to the prev slide in the show
1382		 */
1383		el.goToPrevSlide = function(){
1384			// if infiniteLoop is false and last page is showing, disregard call
1385			if (!slider.settings.infiniteLoop && slider.active.index == 0) return;
1386			var pagerIndex = parseInt(slider.active.index) - 1;
1387			el.goToSlide(pagerIndex, 'prev');
1388		}
1389
1390		/**
1391		 * Starts the auto show
1392		 *
1393		 * @param preventControlUpdate (boolean)
1394		 *  - if true, auto controls state will not be updated
1395		 */
1396		el.startAuto = function(preventControlUpdate){
1397			// if an interval already exists, disregard call
1398			if(slider.interval) return;
1399			// create an interval
1400			slider.interval = setInterval(function(){
1401				slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide();
1402			}, slider.settings.pause);
1403			// if auto controls are displayed and preventControlUpdate is not true
1404			if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('stop');
1405		}
1406
1407		/**
1408		 * Stops the auto show
1409		 *
1410		 * @param preventControlUpdate (boolean)
1411		 *  - if true, auto controls state will not be updated
1412		 */
1413		el.stopAuto = function(preventControlUpdate){
1414			// if no interval exists, disregard call
1415			if(!slider.interval) return;
1416			// clear the interval
1417			clearInterval(slider.interval);
1418			slider.interval = null;
1419			// if auto controls are displayed and preventControlUpdate is not true
1420			if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('start');
1421		}
1422
1423		/**
1424		 * Returns current slide index (zero-based)
1425		 */
1426		el.getCurrentSlide = function(){
1427			return slider.active.index;
1428		}
1429
1430		/**
1431		 * Returns current slide element
1432		 */
1433		el.getCurrentSlideElement = function(){
1434			return slider.children.eq(slider.active.index);
1435		}
1436
1437		/**
1438		 * Returns number of slides in show
1439		 */
1440		el.getSlideCount = function(){
1441			return slider.children.length;
1442		}
1443
1444		/**
1445		 * Update all dynamic slider elements
1446		 */
1447		el.redrawSlider = function(){
1448			// resize all children in ratio to new screen size
1449			slider.children.add(el.find('.bx-clone')).width(calcSlideWidthidth());
1450			// adjust the height
1451			slider.viewport.css('height', getViewportHeight());
1452			// update the slide position
1453			if(!slider.settings.ticker) setSlidePosition();
1454			// if active.last was true before the screen resize, we want
1455			// to keep it last no matter what screen size we end on
1456			if (slider.active.last) slider.active.index = getPagerQty() - 1;
1457			// if the active index (page) no longer exists due to the resize, simply set the index as last
1458			if (slider.active.index >= getPagerQty()) slider.active.last = true;
1459			// if a pager is being displayed and a custom pager is not being used, update it
1460			if(slider.settings.pager && !slider.settings.pagerCustom){
1461				populatePager();
1462				updatePagerActive(slider.active.index);
1463			}
1464		}
1465
1466		/**
1467		 * Destroy the current instance of the slider (revert everything back to original state)
1468		 */
1469		el.destroySlider = function(){
1470			// don't do anything if slider has already been destroyed
1471			if(!slider.initialized) return;
1472			slider.initialized = false;
1473			$('.bx-clone', this).remove();
1474			slider.children.each(function() {
1475				$(this).data("origStyle") != undefined ? $(this).attr("style", $(this).data("origStyle")) : $(this).removeAttr('style');
1476			});
1477			$(this).data("origStyle") != undefined ? this.attr("style", $(this).data("origStyle")) : $(this).removeAttr('style');
1478			$(this).unwrap().unwrap();
1479			if(slider.controls.el) slider.controls.el.remove();
1480			if(slider.controls.next) slider.controls.next.remove();
1481			if(slider.controls.prev) slider.controls.prev.remove();
1482			if(slider.pagerEl && slider.settings.controls) slider.pagerEl.remove();
1483			$('.bx-caption', this).remove();
1484			if(slider.controls.autoEl) slider.controls.autoEl.remove();
1485			clearInterval(slider.interval);
1486			if(slider.settings.responsive) $(window).unbind('resize', resizeWindow);
1487		}
1488
1489		/**
1490		 * Reload the slider (revert all DOM changes, and re-initialize)
1491		 */
1492		el.reloadSlider = function(settings){
1493			if (settings != undefined) options = settings;
1494			el.destroySlider();
1495			init();
1496		}
1497    
1498		/**
1499		 * auto reload functionality
1500		 */
1501    $(window).resize(function() {
1502      if(slider.settings.autoReload) {
1503        el.reloadSlider();
1504      }
1505    });
1506
1507		init();
1508
1509		// returns the current jQuery object
1510		return this;
1511	}
1512
1513})(jQuery);
1514
1515 /**
1516 * Self calling functionality
1517 * --------------------------------------------------------------------------------------- */
1518 
1519 // $('[data-call="bxslider"]').each(function() {
1520 //    $(this).bxSlider();
1521 // });
1522 
1523 
1524
1525/*
1526 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
1527 *
1528 * Uses the built in easing capabilities added In jQuery 1.1
1529 * to offer multiple easing options
1530 *
1531 * TERMS OF USE - jQuery Easing
1532 * 
1533 * Open source under the BSD License. 
1534 * 
1535 * Copyright © 2008 George McGinley Smith
1536 * All rights reserved.
1537 * 
1538 * Redistribution and use in source and binary forms, with or without modification, 
1539 * are permitted provided that the following conditions are met:
1540 * 
1541 * Redistributions of source code must retain the above copyright notice, this list of 
1542 * conditions and the following disclaimer.
1543 * Redistributions in binary form must reproduce the above copyright notice, this list 
1544 * of conditions and the following disclaimer in the documentation and/or other materials 
1545 * provided with the distribution.
1546 * 
1547 * Neither the name of the author nor the names of contributors may be used to endorse 
1548 * or promote products derived from this software without specific prior written permission.
1549 * 
1550 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
1551 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1552 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
1553 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
vendor: 5,091 bytes, lines 1554-1699
1554 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
1555 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
1556 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1557 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
1558 * OF THE POSSIBILITY OF SUCH DAMAGE. 
1559 *
1560*/
1561
1562// t: current time, b: begInnIng value, c: change In value, d: duration
1563jQuery.easing['jswing'] = jQuery.easing['swing'];
1564
1565jQuery.extend( jQuery.easing,
1566{
1567	def: 'easeOutQuad',
1568	swing: function (x, t, b, c, d) {
1569		//alert(jQuery.easing.default);
1570		return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
1571	},
1572	easeInQuad: function (x, t, b, c, d) {
1573		return c*(t/=d)*t + b;
1574	},
1575	easeOutQuad: function (x, t, b, c, d) {
1576		return -c *(t/=d)*(t-2) + b;
1577	},
1578	easeInOutQuad: function (x, t, b, c, d) {
1579		if ((t/=d/2) < 1) return c/2*t*t + b;
1580		return -c/2 * ((--t)*(t-2) - 1) + b;
1581	},
1582	easeInCubic: function (x, t, b, c, d) {
1583		return c*(t/=d)*t*t + b;
1584	},
1585	easeOutCubic: function (x, t, b, c, d) {
1586		return c*((t=t/d-1)*t*t + 1) + b;
1587	},
1588	easeInOutCubic: function (x, t, b, c, d) {
1589		if ((t/=d/2) < 1) return c/2*t*t*t + b;
1590		return c/2*((t-=2)*t*t + 2) + b;
1591	},
1592	easeInQuart: function (x, t, b, c, d) {
1593		return c*(t/=d)*t*t*t + b;
1594	},
1595	easeOutQuart: function (x, t, b, c, d) {
1596		return -c * ((t=t/d-1)*t*t*t - 1) + b;
1597	},
1598	easeInOutQuart: function (x, t, b, c, d) {
1599		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
1600		return -c/2 * ((t-=2)*t*t*t - 2) + b;
1601	},
1602	easeInQuint: function (x, t, b, c, d) {
1603		return c*(t/=d)*t*t*t*t + b;
1604	},
1605	easeOutQuint: function (x, t, b, c, d) {
1606		return c*((t=t/d-1)*t*t*t*t + 1) + b;
1607	},
1608	easeInOutQuint: function (x, t, b, c, d) {
1609		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
1610		return c/2*((t-=2)*t*t*t*t + 2) + b;
1611	},
1612	easeInSine: function (x, t, b, c, d) {
1613		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
1614	},
1615	easeOutSine: function (x, t, b, c, d) {
1616		return c * Math.sin(t/d * (Math.PI/2)) + b;
1617	},
1618	easeInOutSine: function (x, t, b, c, d) {
1619		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
1620	},
1621	easeInExpo: function (x, t, b, c, d) {
1622		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
1623	},
1624	easeOutExpo: function (x, t, b, c, d) {
1625		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
1626	},
1627	easeInOutExpo: function (x, t, b, c, d) {
1628		if (t==0) return b;
1629		if (t==d) return b+c;
1630		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
1631		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
1632	},
1633	easeInCirc: function (x, t, b, c, d) {
1634		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
1635	},
1636	easeOutCirc: function (x, t, b, c, d) {
1637		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
1638	},
1639	easeInOutCirc: function (x, t, b, c, d) {
1640		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
1641		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
1642	},
1643	easeInElastic: function (x, t, b, c, d) {
1644		var s=1.70158;var p=0;var a=c;
1645		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
1646		if (a < Math.abs(c)) { a=c; var s=p/4; }
1647		else var s = p/(2*Math.PI) * Math.asin (c/a);
1648		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
1649	},
1650	easeOutElastic: function (x, t, b, c, d) {
1651		var s=1.70158;var p=0;var a=c;
1652		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
1653		if (a < Math.abs(c)) { a=c; var s=p/4; }
1654		else var s = p/(2*Math.PI) * Math.asin (c/a);
1655		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
1656	},
1657	easeInOutElastic: function (x, t, b, c, d) {
1658		var s=1.70158;var p=0;var a=c;
1659		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
1660		if (a < Math.abs(c)) { a=c; var s=p/4; }
1661		else var s = p/(2*Math.PI) * Math.asin (c/a);
1662		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
1663		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
1664	},
1665	easeInBack: function (x, t, b, c, d, s) {
1666		if (s == undefined) s = 1.70158;
1667		return c*(t/=d)*t*((s+1)*t - s) + b;
1668	},
1669	easeOutBack: function (x, t, b, c, d, s) {
1670		if (s == undefined) s = 1.70158;
1671		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
1672	},
1673	easeInOutBack: function (x, t, b, c, d, s) {
1674		if (s == undefined) s = 1.70158; 
1675		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
1676		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
1677	},
1678	easeInBounce: function (x, t, b, c, d) {
1679		return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
1680	},
1681	easeOutBounce: function (x, t, b, c, d) {
1682		if ((t/=d) < (1/2.75)) {
1683			return c*(7.5625*t*t) + b;
1684		} else if (t < (2/2.75)) {
1685			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
1686		} else if (t < (2.5/2.75)) {
1687			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
1688		} else {
1689			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
1690		}
1691	},
1692	easeInOutBounce: function (x, t, b, c, d) {
1693		if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
1694		return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
1695	}
1696});
1697
1698/*
1699 *
1700 * TERMS OF USE - EASING EQUATIONS
1701 * 
1702 * Open source under the BSD License. 
1703 * 
1704 * Copyright © 2001 Robert Penner
1705 * All rights reserved.
1706 * 
1707 * Redistribution and use in source and binary forms, with or without modification, 
1708 * are permitted provided that the following conditions are met:
1709 * 
1710 * Redistributions of source code must retain the above copyright notice, this list of 
1711 * conditions and the following disclaimer.
1712 * Redistributions in binary form must reproduce the above copyright notice, this list 
1713 * of conditions and the following disclaimer in the documentation and/or other materials 
1714 * provided with the distribution.
1715 * 
1716 * Neither the name of the author nor the names of contributors may be used to endorse 
1717 * or promote products derived from this software without specific prior written permission.
1718 * 
1719 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
1720 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1721 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
1722 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1723 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
1724 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
1725 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1726 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
1727 * OF THE POSSIBILITY OF SUCH DAMAGE. 
1728 *
1729 */

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.