PageSourceSearch

https://www.city.fukushima.fukushima.jp/theme/base/js/jquery.smartslider.js

js city.fukushima.fukushima.jp collected 2026-10-02 05:30:31 UTC 62,780 bytes, 1,546 lines download raw bytes

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