PageSourceSearch

https://theoasisaz.com/wp-content/themes/church/assets/js/plugins/idangerous.swiper.js?ver=1.0.0

js theoasisaz.com collected 2026-10-04 21:18:49 UTC 113,805 bytes, 2,879 lines download raw bytes

1var Swiper = function (selector, params) {
2    'use strict';
3
4    /*=========================
5      A little bit dirty but required part for IE8 and old FF support
6      ===========================*/
7    if (!document.body.outerHTML && document.body.__defineGetter__) {
8        if (HTMLElement) {
9            var element = HTMLElement.prototype;
10            if (element.__defineGetter__) {
11                element.__defineGetter__('outerHTML', function () { return new XMLSerializer().serializeToString(this); });
12            }
13        }
14    }
15
16    if (!window.getComputedStyle) {
17        window.getComputedStyle = function (el, pseudo) {
18            this.el = el;
19            this.getPropertyValue = function (prop) {
20                var re = /(\-([a-z]){1})/g;
21                if (prop === 'float') prop = 'styleFloat';
22                if (re.test(prop)) {
23                    prop = prop.replace(re, function () {
24                        return arguments[2].toUpperCase();
25                    });
26                }
27                return el.currentStyle[prop] ? el.currentStyle[prop] : null;
28            };
29            return this;
30        };
31    }
32    if (!Array.prototype.indexOf) {
33        Array.prototype.indexOf = function (obj, start) {
34            for (var i = (start || 0), j = this.length; i < j; i++) {
35                if (this[i] === obj) { return i; }
36            }
37            return -1;
38        };
39    }
40    if (!document.querySelectorAll) {
41        if (!window.jQuery) return;
42    }
43    function $$(selector, context) {
44        if (document.querySelectorAll)
45            return (context || document).querySelectorAll(selector);
46        else
47            return jQuery(selector, context);
48    }
49
50    /*=========================
51      Check for correct selector
52      ===========================*/
53    if (typeof selector === 'undefined') return;
54
55    if (!(selector.nodeType)) {
56        if ($$(selector).length === 0) return;
57    }
58
59     /*=========================
60      _this
61      ===========================*/
62    var _this = this;
63
64     /*=========================
65      Default Flags and vars
66      ===========================*/
67    _this.touches = {
68        start: 0,
69        startX: 0,
70        startY: 0,
71        current: 0,
72        currentX: 0,
73        currentY: 0,
74        diff: 0,
75        abs: 0
76    };
77    _this.positions = {
78        start: 0,
79        abs: 0,
80        diff: 0,
81        current: 0
82    };
83    _this.times = {
84        start: 0,
85        end: 0
86    };
87
88    _this.id = (new Date()).getTime();
89    _this.container = (selector.nodeType) ? selector : $$(selector)[0];
90    _this.isTouched = false;
91    _this.isMoved = false;
92    _this.activeIndex = 0;
93    _this.centerIndex = 0;
94    _this.activeLoaderIndex = 0;
95    _this.activeLoopIndex = 0;
96    _this.previousIndex = null;
97    _this.velocity = 0;
98    _this.snapGrid = [];
99    _this.slidesGrid = [];
100    _this.imagesToLoad = [];
101    _this.imagesLoaded = 0;
102    _this.wrapperLeft = 0;
103    _this.wrapperRight = 0;
104    _this.wrapperTop = 0;
105    _this.wrapperBottom = 0;
106    _this.isAndroid = navigator.userAgent.toLowerCase().indexOf('android') >= 0;
107    var wrapper, slideSize, wrapperSize, direction, isScrolling, containerSize;
108
109    /*=========================
110      Default Parameters
111      ===========================*/
112    var defaults = {
113        eventTarget: 'wrapper', // or 'container'
114        mode : 'horizontal', // or 'vertical'
115        touchRatio : 1,
116        speed : 300,
117        freeMode : false,
118        freeModeFluid : false,
119        momentumRatio: 1,
120        momentumBounce: true,
121        momentumBounceRatio: 1,
122        slidesPerView : 1,
123        slidesPerGroup : 1,
124        slidesPerViewFit: true, //Fit to slide when spv "auto" and slides larger than container
125        simulateTouch : true,
126        followFinger : true,
127        shortSwipes : true,
128        longSwipesRatio: 0.5,
129        moveStartThreshold: false,
130        onlyExternal : false,
131        createPagination : true,
132        pagination : false,
133        paginationElement: 'span',
134        paginationClickable: false,
135        paginationAsRange: true,
136        resistance : true, // or false or 100%
137        scrollContainer : false,
138        preventLinks : true,
139        preventLinksPropagation: false,
140        noSwiping : false, // or class
141        noSwipingClass : 'swiper-no-swiping', //:)
142        initialSlide: 0,
143        keyboardControl: false,
144        mousewheelControl : false,
145        mousewheelControlForceToAxis : false,
146        useCSS3Transforms : true,
147        // Autoplay
148        autoplay: false,
149        autoplayDisableOnInteraction: true,
150        autoplayStopOnLast: false,
151        //Loop mode
152        loop: false,
153        loopAdditionalSlides: 0,
154        // Round length values
155        roundLengths: false,
156        //Auto Height
157        calculateHeight: false,
158        //Apply CSS for width and/or height
159        cssWidthAndHeight: false, // or true or 'width' or 'height'
160        //Images Preloader
161        updateOnImagesReady : true,
162        //Form elements
163        releaseFormElements : true,
164        //Watch for active slide, useful when use effects on different slide states
165        watchActiveIndex: false,
166        //Slides Visibility Fit
167        visibilityFullFit : false,
168        //Slides Offset
169        offsetPxBefore : 0,
170        offsetPxAfter : 0,
171        offsetSlidesBefore : 0,
172        offsetSlidesAfter : 0,
173        centeredSlides: false,
174        //Queue callbacks
175        queueStartCallbacks : false,
176        queueEndCallbacks : false,
177        //Auto Resize
178        autoResize : true,
179        resizeReInit : false,
180        //DOMAnimation
181        DOMAnimation : true,
182        //Slides Loader
183        loader: {
184            slides: [], //array with slides
185            slidesHTMLType: 'inner', // or 'outer'
186            surroundGroups: 1, //keep preloaded slides groups around view
187            logic: 'reload', //or 'change'
188            loadAllSlides: false
189        },
190        // One way swipes
191        swipeToPrev: true,
192        swipeToNext: true,
193        //Namespace
194        slideElement: 'div',
195        slideClass: 'swiper-slide',
196        slideActiveClass: 'swiper-slide-active',
197        slideVisibleClass: 'swiper-slide-visible',
198        slideDuplicateClass: 'swiper-slide-duplicate',
199        wrapperClass: 'swiper-wrapper',
200        paginationElementClass: 'swiper-pagination-switch',
201        paginationActiveClass: 'swiper-active-switch',
202        paginationVisibleClass: 'swiper-visible-switch'
203    };
204    params = params || {};
205    for (var prop in defaults) {
206        if (prop in params && typeof params[prop] === 'object') {
207            for (var subProp in defaults[prop]) {
208                if (! (subProp in params[prop])) {
209                    params[prop][subProp] = defaults[prop][subProp];
210                }
211            }
212        }
213        else if (! (prop in params)) {
214            params[prop] = defaults[prop];
215        }
216    }
217    _this.params = params;
218    if (params.scrollContainer) {
219        params.freeMode = true;
220        params.freeModeFluid = true;
221    }
222    if (params.loop) {
223        params.resistance = '100%';
224    }
225    var isH = params.mode === 'horizontal';
226
227    /*=========================
228      Define Touch Events
229      ===========================*/
230    var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];
231    if (_this.browser.ie10) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];
232    if (_this.browser.ie11) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];
233
234    _this.touchEvents = {
235        touchStart : _this.support.touch || !params.simulateTouch  ? 'touchstart' : desktopEvents[0],
236        touchMove : _this.support.touch || !params.simulateTouch ? 'touchmove' : desktopEvents[1],
237        touchEnd : _this.support.touch || !params.simulateTouch ? 'touchend' : desktopEvents[2]
238    };
239
240    /*=========================
241      Wrapper
242      ===========================*/
243    for (var i = _this.container.childNodes.length - 1; i >= 0; i--) {
244        if (_this.container.childNodes[i].className) {
245            var _wrapperClasses = _this.container.childNodes[i].className.split(/\s+/);
246            for (var j = 0; j < _wrapperClasses.length; j++) {
247                if (_wrapperClasses[j] === params.wrapperClass) {
248                    wrapper = _this.container.childNodes[i];
249                }
250            }
251        }
252    }
253
254    _this.wrapper = wrapper;
255    /*=========================
256      Slide API
257      ===========================*/
258    _this._extendSwiperSlide = function  (el) {
259        el.append = function () {
260            if (params.loop) {
261                el.insertAfter(_this.slides.length - _this.loopedSlides);
262            }
263            else {
264                _this.wrapper.appendChild(el);
265                _this.reInit();
266            }
267
268            return el;
269        };
270        el.prepend = function () {
271            if (params.loop) {
272                _this.wrapper.insertBefore(el, _this.slides[_this.loopedSlides]);
273                _this.removeLoopedSlides();
274                _this.calcSlides();
275                _this.createLoop();
276            }
277            else {
278                _this.wrapper.insertBefore(el, _this.wrapper.firstChild);
279            }
280            _this.reInit();
281            return el;
282        };
283        el.insertAfter = function (index) {
284            if (typeof index === 'undefined') return false;
285            var beforeSlide;
286
287            if (params.loop) {
288                beforeSlide = _this.slides[index + 1 + _this.loopedSlides];
289                if (beforeSlide) {
290                    _this.wrapper.insertBefore(el, beforeSlide);
291                }
292                else {
293                    _this.wrapper.appendChild(el);
294                }
295                _this.removeLoopedSlides();
296                _this.calcSlides();
297                _this.createLoop();
298            }
299            else {
300                beforeSlide = _this.slides[index + 1];
301                _this.wrapper.insertBefore(el, beforeSlide);
302            }
303            _this.reInit();
304            return el;
305        };
306        el.clone = function () {
307            return _this._extendSwiperSlide(el.cloneNode(true));
308        };
309        el.remove = function () {
310            _this.wrapper.removeChild(el);
311            _this.reInit();
312        };
313        el.html = function (html) {
314            if (typeof html === 'undefined') {
315                return el.innerHTML;
316            }
317            else {
318                el.innerHTML = html;
319                return el;
320            }
321        };
322        el.index = function () {
323            var index;
324            for (var i = _this.slides.length - 1; i >= 0; i--) {
325                if (el === _this.slides[i]) index = i;
326            }
327            return index;
328        };
329        el.isActive = function () {
330            if (el.index() === _this.activeIndex) return true;
331            else return false;
332        };
333        if (!el.swiperSlideDataStorage) el.swiperSlideDataStorage = {};
334        el.getData = function (name) {
335            return el.swiperSlideDataStorage[name];
336        };
337        el.setData = function (name, value) {
338            el.swiperSlideDataStorage[name] = value;
339            return el;
340        };
341        el.data = function (name, value) {
342            if (typeof value === 'undefined') {
343                return el.getAttribute('data-' + name);
344            }
345            else {
346                el.setAttribute('data-' + name, value);
347                return el;
348            }
349        };
350        el.getWidth = function (outer, round) {
351            return _this.h.getWidth(el, outer, round);
352        };
353        el.getHeight = function (outer, round) {
354            return _this.h.getHeight(el, outer, round);
355        };
356        el.getOffset = function () {
357            return _this.h.getOffset(el);
358        };
359        return el;
360    };
361
362    //Calculate information about number of slides
363    _this.calcSlides = function (forceCalcSlides) {
364        var oldNumber = _this.slides ? _this.slides.length : false;
365        _this.slides = [];
366        _this.displaySlides = [];
367        for (var i = 0; i < _this.wrapper.childNodes.length; i++) {
368            if (_this.wrapper.childNodes[i].className) {
369                var _className = _this.wrapper.childNodes[i].className;
370                var _slideClasses = _className.split(/\s+/);
371                for (var j = 0; j < _slideClasses.length; j++) {
372                    if (_slideClasses[j] === params.slideClass) {
373                        _this.slides.push(_this.wrapper.childNodes[i]);
374                    }
375                }
376            }
377        }
378        for (i = _this.slides.length - 1; i >= 0; i--) {
379            _this._extendSwiperSlide(_this.slides[i]);
380        }
381        if (oldNumber === false) return;
382        if (oldNumber !== _this.slides.length || forceCalcSlides) {
383
384            // Number of slides has been changed
385            removeSlideEvents();
386            addSlideEvents();
387            _this.updateActiveSlide();
388            if (_this.params.pagination) _this.createPagination();
389            _this.callPlugins('numberOfSlidesChanged');
390        }
391    };
392
393    //Create Slide
394    _this.createSlide = function (html, slideClassList, el) {
395        slideClassList = slideClassList || _this.params.slideClass;
396        el = el || params.slideElement;
397        var newSlide = document.createElement(el);
398        newSlide.innerHTML = html || '';
399        newSlide.className = slideClassList;
400        return _this._extendSwiperSlide(newSlide);
401    };
402
403    //Append Slide
404    _this.appendSlide = function (html, slideClassList, el) {
405        if (!html) return;
406        if (html.nodeType) {
407            return _this._extendSwiperSlide(html).append();
408        }
409        else {
410            return _this.createSlide(html, slideClassList, el).append();
411        }
412    };
413    _this.prependSlide = function (html, slideClassList, el) {
414        if (!html) return;
415        if (html.nodeType) {
416            return _this._extendSwiperSlide(html).prepend();
417        }
418        else {
419            return _this.createSlide(html, slideClassList, el).prepend();
420        }
421    };
422    _this.insertSlideAfter = function (index, html, slideClassList, el) {
423        if (typeof index === 'undefined') return false;
424        if (html.nodeType) {
425            return _this._extendSwiperSlide(html).insertAfter(index);
426        }
427        else {
428            return _this.createSlide(html, slideClassList, el).insertAfter(index);
429        }
430    };
431    _this.removeSlide = function (index) {
432        if (_this.slides[index]) {
433            if (params.loop) {
434                if (!_this.slides[index + _this.loopedSlides]) return false;
435                _this.slides[index + _this.loopedSlides].remove();
436                _this.removeLoopedSlides();
437                _this.calcSlides();
438                _this.createLoop();
439            }
440            else _this.slides[index].remove();
441            return true;
442        }
443        else return false;
444    };
445    _this.removeLastSlide = function () {
446        if (_this.slides.length > 0) {
447            if (params.loop) {
448                _this.slides[_this.slides.length - 1 - _this.loopedSlides].remove();
449                _this.removeLoopedSlides();
450                _this.calcSlides();
451                _this.createLoop();
452            }
453            else _this.slides[_this.slides.length - 1].remove();
454            return true;
455        }
456        else {
457            return false;
458        }
459    };
460    _this.removeAllSlides = function () {
461        var num = _this.slides.length;
462        for (var i = _this.slides.length - 1; i >= 0; i--) {
463            _this.slides[i].remove();
464            if (i === num - 1) {
465                _this.setWrapperTranslate(0);
466            }
467        }
468    };
469    _this.getSlide = function (index) {
470        return _this.slides[index];
471    };
472    _this.getLastSlide = function () {
473        return _this.slides[_this.slides.length - 1];
474    };
475    _this.getFirstSlide = function () {
476        return _this.slides[0];
477    };
478
479    //Currently Active Slide
480    _this.activeSlide = function () {
481        return _this.slides[_this.activeIndex];
482    };
483
484    /*=========================
485     Wrapper for Callbacks : Allows additive callbacks via function arrays
486     ===========================*/
487    _this.fireCallback = function () {
488        var callback = arguments[0];
489        if (Object.prototype.toString.call(callback) === '[object Array]') {
490            for (var i = 0; i < callback.length; i++) {
491                if (typeof callback[i] === 'function') {
492                    callback[i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
493                }
494            }
495        } else if (Object.prototype.toString.call(callback) === '[object String]') {
496            if (params['on' + callback]) _this.fireCallback(params['on' + callback], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
497        } else {
498            callback(arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
499        }
500    };
501    function isArray(obj) {
502        if (Object.prototype.toString.apply(obj) === '[object Array]') return true;
503        return false;
504    }
505
506    /**
507     * Allows user to add callbacks, rather than replace them
508     * @param callback
509     * @param func
510     * @return {*}
511     */
512    _this.addCallback = function (callback, func) {
513        var _this = this, tempFunc;
514        if (_this.params['on' + callback]) {
515            if (isArray(this.params['on' + callback])) {
516                return this.params['on' + callback].push(func);
517            } else if (typeof this.params['on' + callback] === 'function') {
518                tempFunc = this.params['on' + callback];
519                this.params['on' + callback] = [];
520                this.params['on' + callback].push(tempFunc);
521                return this.params['on' + callback].push(func);
522            }
523        } else {
524            this.params['on' + callback] = [];
525            return this.params['on' + callback].push(func);
526        }
527    };
528    _this.removeCallbacks = function (callback) {
529        if (_this.params['on' + callback]) {
530            _this.params['on' + callback] = null;
531        }
532    };
533
534    /*=========================
535      Plugins API
536      ===========================*/
537    var _plugins = [];
538    for (var plugin in _this.plugins) {
539        if (params[plugin]) {
540            var p = _this.plugins[plugin](_this, params[plugin]);
541            if (p) _plugins.push(p);
542        }
543    }
544    _this.callPlugins = function (method, args) {
545        if (!args) args = {};
546        for (var i = 0; i < _plugins.length; i++) {
547            if (method in _plugins[i]) {
548                _plugins[i][method](args);
549            }
550        }
551    };
552
553    /*=========================
554      Windows Phone 8 Fix
555      ===========================*/
556    if ((_this.browser.ie10 || _this.browser.ie11) && !params.onlyExternal) {
557        _this.wrapper.classList.add('swiper-wp8-' + (isH ? 'horizontal' : 'vertical'));
558    }
559
560    /*=========================
561      Free Mode Class
562      ===========================*/
563    if (params.freeMode) {
564        _this.container.className += ' swiper-free-mode';
565    }
566
567    /*==================================================
568        Init/Re-init/Resize Fix
569    ====================================================*/
570    _this.initialized = false;
571    _this.init = function (force, forceCalcSlides) {
572        var _width = _this.h.getWidth(_this.container, false, params.roundLengths);
573        var _height = _this.h.getHeight(_this.container, false, params.roundLengths);
574        if (_width === _this.width && _height === _this.height && !force) return;
575
576        _this.width = _width;
577        _this.height = _height;
578
579        var slideWidth, slideHeight, slideMaxHeight, wrapperWidth, wrapperHeight, slideLeft;
580        var i; // loop index variable to avoid JSHint W004 / W038
581        containerSize = isH ? _width : _height;
582        var wrapper = _this.wrapper;
583
584        if (force) {
585            _this.calcSlides(forceCalcSlides);
586        }
587
588        if (params.slidesPerView === 'auto') {
589            //Auto mode
590            var slidesWidth = 0;
591            var slidesHeight = 0;
592
593            //Unset Styles
594            if (params.slidesOffset > 0) {
595                wrapper.style.paddingLeft = '';
596                wrapper.style.paddingRight = '';
597                wrapper.style.paddingTop = '';
598                wrapper.style.paddingBottom = '';
599            }
600            wrapper.style.width = '';
601            wrapper.style.height = '';
602            if (params.offsetPxBefore > 0) {
603                if (isH) _this.wrapperLeft = params.offsetPxBefore;
604                else _this.wrapperTop = params.offsetPxBefore;
605            }
606            if (params.offsetPxAfter > 0) {
607                if (isH) _this.wrapperRight = params.offsetPxAfter;
608                else _this.wrapperBottom = params.offsetPxAfter;
609            }
610
611            if (params.centeredSlides) {
612                if (isH) {
613                    _this.wrapperLeft = (containerSize - this.slides[0].getWidth(true, params.roundLengths)) / 2;
614                    _this.wrapperRight = (containerSize - _this.slides[_this.slides.length - 1].getWidth(true, params.roundLengths)) / 2;
615                }
616                else {
617                    _this.wrapperTop = (containerSize - _this.slides[0].getHeight(true, params.roundLengths)) / 2;
618                    _this.wrapperBottom = (containerSize - _this.slides[_this.slides.length - 1].getHeight(true, params.roundLengths)) / 2;
619                }
620            }
621
622            if (isH) {
623                if (_this.wrapperLeft >= 0) wrapper.style.paddingLeft = _this.wrapperLeft + 'px';
624                if (_this.wrapperRight >= 0) wrapper.style.paddingRight = _this.wrapperRight + 'px';
625            }
626            else {
627                if (_this.wrapperTop >= 0) wrapper.style.paddingTop = _this.wrapperTop + 'px';
628                if (_this.wrapperBottom >= 0) wrapper.style.paddingBottom = _this.wrapperBottom + 'px';
629            }
630            slideLeft = 0;
631            var centeredSlideLeft = 0;
632            _this.snapGrid = [];
633            _this.slidesGrid = [];
634
635            slideMaxHeight = 0;
636            for (i = 0; i < _this.slides.length; i++) {
637                slideWidth = _this.slides[i].getWidth(true, params.roundLengths);
638                slideHeight = _this.slides[i].getHeight(true, params.roundLengths);
639                if (params.calculateHeight) {
640                    slideMaxHeight = Math.max(slideMaxHeight, slideHeight);
641                }
642                var _slideSize = isH ? slideWidth : slideHeight;
643                if (params.centeredSlides) {
644                    var nextSlideWidth = i === _this.slides.length - 1 ? 0 : _this.slides[i + 1].getWidth(true, params.roundLengths);
645                    var nextSlideHeight = i === _this.slides.length - 1 ? 0 : _this.slides[i + 1].getHeight(true, params.roundLengths);
646                    var nextSlideSize = isH ? nextSlideWidth : nextSlideHeight;
647                    if (_slideSize > containerSize) {
648                        if (params.slidesPerViewFit) {
649                            _this.snapGrid.push(slideLeft + _this.wrapperLeft);
650                            _this.snapGrid.push(slideLeft + _slideSize - containerSize + _this.wrapperLeft);
651                        }
652                        else {
653                            for (var j = 0; j <= Math.floor(_slideSize / (containerSize + _this.wrapperLeft)); j++) {
654                                if (j === 0) _this.snapGrid.push(slideLeft + _this.wrapperLeft);
655                                else _this.snapGrid.push(slideLeft + _this.wrapperLeft + containerSize * j);
656                            }
657                        }
658                        _this.slidesGrid.push(slideLeft + _this.wrapperLeft);
659                    }
660                    else {
661                        _this.snapGrid.push(centeredSlideLeft);
662                        _this.slidesGrid.push(centeredSlideLeft);
663                    }
664                    centeredSlideLeft += _slideSize / 2 + nextSlideSize / 2;
665                }
666                else {
667                    if (_slideSize > containerSize) {
668                        if (params.slidesPerViewFit) {
669                            _this.snapGrid.push(slideLeft);
670                            _this.snapGrid.push(slideLeft + _slideSize - containerSize);
671                        }
672                        else {
673                            if (containerSize !== 0) {
674                                for (var k = 0; k <= Math.floor(_slideSize / containerSize); k++) {
675                                    _this.snapGrid.push(slideLeft + containerSize * k);
676                                }
677                            }
678                            else {
679                                _this.snapGrid.push(slideLeft);
680                            }
681                        }
682
683                    }
684                    else {
685                        _this.snapGrid.push(slideLeft);
686                    }
687                    _this.slidesGrid.push(slideLeft);
688                }
689
690                slideLeft += _slideSize;
691
692                slidesWidth += slideWidth;
693                slidesHeight += slideHeight;
694            }
695            if (params.calculateHeight) _this.height = slideMaxHeight;
696            if (isH) {
697                wrapperSize = slidesWidth + _this.wrapperRight + _this.wrapperLeft;
698                if (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'height') {
699                    wrapper.style.width = (slidesWidth) + 'px';
700                }
701                if (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'width') {
702                    wrapper.style.height = (_this.height) + 'px';
703                }
704            }
705            else {
706                if (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'height') {
707                    wrapper.style.width = (_this.width) + 'px';
708                }
709                if (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'width') {
710                    wrapper.style.height = (slidesHeight) + 'px';
711                }
712                wrapperSize = slidesHeight + _this.wrapperTop + _this.wrapperBottom;
713            }
714
715        }
716        else if (params.scrollContainer) {
717            //Scroll Container
718            wrapper.style.width = '';
719            wrapper.style.height = '';
720            wrapperWidth = _this.slides[0].getWidth(true, params.roundLengths);
721            wrapperHeight = _this.slides[0].getHeight(true, params.roundLengths);
722            wrapperSize = isH ? wrapperWidth : wrapperHeight;
723            wrapper.style.width = wrapperWidth + 'px';
724            wrapper.style.height = wrapperHeight + 'px';
725            slideSize = isH ? wrapperWidth : wrapperHeight;
726
727        }
728        else {
729            //For usual slides
730            if (params.calculateHeight) {
731                slideMaxHeight = 0;
732                wrapperHeight = 0;
733                //ResetWrapperSize
734                if (!isH) _this.container.style.height = '';
735                wrapper.style.height = '';
736
737                for (i = 0; i < _this.slides.length; i++) {
738                    //ResetSlideSize
739                    _this.slides[i].style.height = '';
740                    slideMaxHeight = Math.max(_this.slides[i].getHeight(true), slideMaxHeight);
741                    if (!isH) wrapperHeight += _this.slides[i].getHeight(true);
742                }
743                slideHeight = slideMaxHeight;
744                _this.height = slideHeight;
745
746                if (isH) wrapperHeight = slideHeight;
747                else {
748                    containerSize = slideHeight;
749                    _this.container.style.height = containerSize + 'px';
750                }
751            }
752            else {
753                slideHeight = isH ? _this.height : _this.height / params.slidesPerView;
754                if (params.roundLengths) slideHeight = Math.ceil(slideHeight);
755                wrapperHeight = isH ? _this.height : _this.slides.length * slideHeight;
756            }
757            slideWidth = isH ? _this.width / params.slidesPerView : _this.width;
758            if (params.roundLengths) slideWidth = Math.ceil(slideWidth);
759            wrapperWidth = isH ? _this.slides.length * slideWidth : _this.width;
760            slideSize = isH ? slideWidth : slideHeight;
761
762            if (params.offsetSlidesBefore > 0) {
763                if (isH) _this.wrapperLeft = slideSize * params.offsetSlidesBefore;
764                else _this.wrapperTop = slideSize * params.offsetSlidesBefore;
765            }
766            if (params.offsetSlidesAfter > 0) {
767                if (isH) _this.wrapperRight = slideSize * params.offsetSlidesAfter;
768                else _this.wrapperBottom = slideSize * params.offsetSlidesAfter;
769            }
770            if (params.offsetPxBefore > 0) {
771                if (isH) _this.wrapperLeft = params.offsetPxBefore;
772                else _this.wrapperTop = params.offsetPxBefore;
773            }
774            if (params.offsetPxAfter > 0) {
775                if (isH) _this.wrapperRight = params.offsetPxAfter;
776                else _this.wrapperBottom = params.offsetPxAfter;
777            }
778            if (params.centeredSlides) {
779                if (isH) {
780                    _this.wrapperLeft = (containerSize - slideSize) / 2;
781                    _this.wrapperRight = (containerSize - slideSize) / 2;
782                }
783                else {
784                    _this.wrapperTop = (containerSize - slideSize) / 2;
785                    _this.wrapperBottom = (containerSize - slideSize) / 2;
786                }
787            }
788            if (isH) {
789                if (_this.wrapperLeft > 0) wrapper.style.paddingLeft = _this.wrapperLeft + 'px';
790                if (_this.wrapperRight > 0) wrapper.style.paddingRight = _this.wrapperRight + 'px';
791            }
792            else {
793                if (_this.wrapperTop > 0) wrapper.style.paddingTop = _this.wrapperTop + 'px';
794                if (_this.wrapperBottom > 0) wrapper.style.paddingBottom = _this.wrapperBottom + 'px';
795            }
796
797            wrapperSize = isH ? wrapperWidth + _this.wrapperRight + _this.wrapperLeft : wrapperHeight + _this.wrapperTop + _this.wrapperBottom;
798            if (parseFloat(wrapperWidth) > 0 && (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'height')) {
799                wrapper.style.width = wrapperWidth + 'px';
800            }
801            if (parseFloat(wrapperHeight) > 0 && (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'width')) {
802                wrapper.style.height = wrapperHeight + 'px';
803            }
804            slideLeft = 0;
805            _this.snapGrid = [];
806            _this.slidesGrid = [];
807            for (i = 0; i < _this.slides.length; i++) {
808                _this.snapGrid.push(slideLeft);
809                _this.slidesGrid.push(slideLeft);
810                slideLeft += slideSize;
811                if (parseFloat(slideWidth) > 0 && (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'height')) {
812                    _this.slides[i].style.width = slideWidth + 'px';
813                }
814                if (parseFloat(slideHeight) > 0 && (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'width')) {
815                    _this.slides[i].style.height = slideHeight + 'px';
816                }
817            }
818
819        }
820
821        if (!_this.initialized) {
822            _this.callPlugins('onFirstInit');
823            if (params.onFirstInit) _this.fireCallback(params.onFirstInit, _this);
824        }
825        else {
826            _this.callPlugins('onInit');
827            if (params.onInit) _this.fireCallback(params.onInit, _this);
828        }
829        _this.initialized = true;
830    };
831
832    _this.reInit = function (forceCalcSlides) {
833        _this.init(true, forceCalcSlides);
834    };
835
836    _this.resizeFix = function (reInit) {
837        _this.callPlugins('beforeResizeFix');
838
839        _this.init(params.resizeReInit || reInit);
840
841        // swipe to active slide in fixed mode
842        if (!params.freeMode) {
843            _this.swipeTo((params.loop ? _this.activeLoopIndex : _this.activeIndex), 0, false);
844            // Fix autoplay
845            if (params.autoplay) {
846                if (_this.support.transitions && typeof autoplayTimeoutId !== 'undefined') {
847                    if (typeof autoplayTimeoutId !== 'undefined') {
848                        clearTimeout(autoplayTimeoutId);
849                        autoplayTimeoutId = undefined;
850                        _this.startAutoplay();
851                    }
852                }
853                else {
854                    if (typeof autoplayIntervalId !== 'undefined') {
855                        clearInterval(autoplayIntervalId);
856                        autoplayIntervalId = undefined;
857                        _this.startAutoplay();
858                    }
859                }
860            }
861        }
862        // move wrapper to the beginning in free mode
863        else if (_this.getWrapperTranslate() < -maxWrapperPosition()) {
864            _this.setWrapperTransition(0);
865            _this.setWrapperTranslate(-maxWrapperPosition());
866        }
867
868        _this.callPlugins('afterResizeFix');
869    };
870
871    /*==========================================
872        Max and Min Positions
873    ============================================*/
874    function maxWrapperPosition() {
875        var a = (wrapperSize - containerSize);
876        if (params.freeMode) {
877            a = wrapperSize - containerSize;
878        }
879        // if (params.loop) a -= containerSize;
880        if (params.slidesPerView > _this.slides.length && !params.centeredSlides) {
881            a = 0;
882        }
883        if (a < 0) a = 0;
884        return a;
885    }
886
887    /*==========================================
888        Event Listeners
889    ============================================*/
890    function initEvents() {
891        var bind = _this.h.addEventListener;
892        var eventTarget = params.eventTarget === 'wrapper' ? _this.wrapper : _this.container;
893        //Touch Events
894        if (! (_this.browser.ie10 || _this.browser.ie11)) {
895            if (_this.support.touch) {
896                bind(eventTarget, 'touchstart', onTouchStart);
897                bind(eventTarget, 'touchmove', onTouchMove);
898                bind(eventTarget, 'touchend', onTouchEnd);
899            }
900            if (params.simulateTouch) {
901                bind(eventTarget, 'mousedown', onTouchStart);
902                bind(document, 'mousemove', onTouchMove);
903                bind(document, 'mouseup', onTouchEnd);
904            }
905        }
906        else {
907            bind(eventTarget, _this.touchEvents.touchStart, onTouchStart);
908            bind(document, _this.touchEvents.touchMove, onTouchMove);
909            bind(document, _this.touchEvents.touchEnd, onTouchEnd);
910        }
911
912        //Resize Event
913        if (params.autoResize) {
914            bind(window, 'resize', _this.resizeFix);
915        }
916        //Slide Events
917        addSlideEvents();
918        //Mousewheel
919        _this._wheelEvent = false;
920        if (params.mousewheelControl) {
921            if (document.onmousewheel !== undefined) {
922                _this._wheelEvent = 'mousewheel';
923            }
924            if (!_this._wheelEvent) {
925                try {
926                    new WheelEvent('wheel');
927                    _this._wheelEvent = 'wheel';
928                } catch (e) {}
929            }
930            if (!_this._wheelEvent) {
931                _this._wheelEvent = 'DOMMouseScroll';
932            }
933            if (_this._wheelEvent) {
934                bind(_this.container, _this._wheelEvent, handleMousewheel);
935            }
936        }
937
938        //Keyboard
939		function _loadImage(img) {
940			var image, src;
941			var onReady = function () {
942				if (typeof _this === 'undefined' || _this === null) return;
943				if (_this.imagesLoaded !== undefined) _this.imagesLoaded++;
944				if (_this.imagesLoaded === _this.imagesToLoad.length) {
945					_this.reInit();
946					if (params.onImagesReady) _this.fireCallback(params.onImagesReady, _this);
947				}
948			};
949
950			if (!img.complete) {
951				src = (img.currentSrc || img.getAttribute('src'));
952				if (src) {
953					image = new Image();
954					image.onload = onReady;
955					image.onerror = onReady;
956					image.src = src;
957				} else {
958					onReady();
959				}
960
961			} else {//image already loaded...
962				onReady();
963			}
964		}
965
966		if (params.keyboardControl) {
967			bind(document, 'keydown', handleKeyboardKeys);
968		}
969		if (params.updateOnImagesReady) {
970			_this.imagesToLoad = $$('img', _this.container);
971
972			for (var i = 0; i < _this.imagesToLoad.length; i++) {
973				_loadImage(_this.imagesToLoad[i]);
974			}
975		}
976    }
977
978    //Remove Event Listeners
979    _this.destroy = function (removeStyles) {
980        var unbind = _this.h.removeEventListener;
981        var eventTarget = params.eventTarget === 'wrapper' ? _this.wrapper : _this.container;
982        //Touch Events
983        if (! (_this.browser.ie10 || _this.browser.ie11)) {
984            if (_this.support.touch) {
985                unbind(eventTarget, 'touchstart', onTouchStart);
986                unbind(eventTarget, 'touchmove', onTouchMove);
987                unbind(eventTarget, 'touchend', onTouchEnd);
988            }
989            if (params.simulateTouch) {
990                unbind(eventTarget, 'mousedown', onTouchStart);
991                unbind(document, 'mousemove', onTouchMove);
992                unbind(document, 'mouseup', onTouchEnd);
993            }
994        }
995        else {
996            unbind(eventTarget, _this.touchEvents.touchStart, onTouchStart);
997            unbind(document, _this.touchEvents.touchMove, onTouchMove);
998            unbind(document, _this.touchEvents.touchEnd, onTouchEnd);
999        }
1000
1001        //Resize Event
1002        if (params.autoResize) {
1003            unbind(window, 'resize', _this.resizeFix);
1004        }
1005
1006        //Init Slide Events
1007        removeSlideEvents();
1008
1009        //Pagination
1010        if (params.paginationClickable) {
1011            removePaginationEvents();
1012        }
1013
1014        //Mousewheel
1015        if (params.mousewheelControl && _this._wheelEvent) {
1016            unbind(_this.container, _this._wheelEvent, handleMousewheel);
1017        }
1018
1019        //Keyboard
1020        if (params.keyboardControl) {
1021            unbind(document, 'keydown', handleKeyboardKeys);
1022        }
1023
1024        //Stop autoplay
1025        if (params.autoplay) {
1026            _this.stopAutoplay();
1027        }
1028        // Remove styles
1029        if (removeStyles) {
1030            _this.wrapper.removeAttribute('style');
1031            for (var i = 0; i < _this.slides.length; i++) {
1032                _this.slides[i].removeAttribute('style');
1033            }
1034        }
1035        // Plugins
1036        _this.callPlugins('onDestroy');
1037
1038        // Check jQuery/Zepto data
1039        if (window.jQuery && window.jQuery(_this.container).data('swiper')) {
1040            window.jQuery(_this.container).removeData('swiper');
1041        }
1042        if (window.Zepto && window.Zepto(_this.container).data('swiper')) {
1043            window.Zepto(_this.container).removeData('swiper');
1044        }
1045
1046        //Destroy variable
1047        _this = null;
1048    };
1049
1050    function addSlideEvents() {
1051        var bind = _this.h.addEventListener,
1052            i;
1053
1054        //Prevent Links Events
1055        if (params.preventLinks) {
1056            var links = $$('a', _this.container);
1057            for (i = 0; i < links.length; i++) {
1058                bind(links[i], 'click', preventClick);
1059            }
1060        }
1061        //Release Form Elements
1062        if (params.releaseFormElements) {
1063            var formElements = $$('input, textarea, select', _this.container);
1064            for (i = 0; i < formElements.length; i++) {
1065                bind(formElements[i], _this.touchEvents.touchStart, releaseForms, true);
1066                if (_this.support.touch && params.simulateTouch) {
1067                    bind(formElements[i], 'mousedown', releaseForms, true);
1068                }
1069            }
1070        }
1071
1072        //Slide Clicks & Touches
1073        if (params.onSlideClick) {
1074            for (i = 0; i < _this.slides.length; i++) {
1075                bind(_this.slides[i], 'click', slideClick);
1076            }
1077        }
1078        if (params.onSlideTouch) {
1079            for (i = 0; i < _this.slides.length; i++) {
1080                bind(_this.slides[i], _this.touchEvents.touchStart, slideTouch);
1081            }
1082        }
1083    }
1084    function removeSlideEvents() {
1085        var unbind = _this.h.removeEventListener,
1086            i;
1087
1088        //Slide Clicks & Touches
1089        if (params.onSlideClick) {
1090            for (i = 0; i < _this.slides.length; i++) {
1091                unbind(_this.slides[i], 'click', slideClick);
1092            }
1093        }
1094        if (params.onSlideTouch) {
1095            for (i = 0; i < _this.slides.length; i++) {
1096                unbind(_this.slides[i], _this.touchEvents.touchStart, slideTouch);
1097            }
1098        }
1099        //Release Form Elements
1100        if (params.releaseFormElements) {
1101            var formElements = $$('input, textarea, select', _this.container);
1102            for (i = 0; i < formElements.length; i++) {
1103                unbind(formElements[i], _this.touchEvents.touchStart, releaseForms, true);
1104                if (_this.support.touch && params.simulateTouch) {
1105                    unbind(formElements[i], 'mousedown', releaseForms, true);
1106                }
1107            }
1108        }
1109        //Prevent Links Events
1110        if (params.preventLinks) {
1111            var links = $$('a', _this.container);
1112            for (i = 0; i < links.length; i++) {
1113                unbind(links[i], 'click', preventClick);
1114            }
1115        }
1116    }
1117    /*==========================================
1118        Keyboard Control
1119    ============================================*/
1120    function handleKeyboardKeys(e) {
1121        var kc = e.keyCode || e.charCode;
1122        if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) return;
1123        if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {
1124            var inView = false;
1125            //Check that swiper should be inside of visible area of window
1126            var swiperOffset = _this.h.getOffset(_this.container);
1127            var scrollLeft = _this.h.windowScroll().left;
1128            var scrollTop = _this.h.windowScroll().top;
1129            var windowWidth = _this.h.windowWidth();
1130            var windowHeight = _this.h.windowHeight();
1131            var swiperCoord = [
1132                [swiperOffset.left, swiperOffset.top],
1133                [swiperOffset.left + _this.width, swiperOffset.top],
1134                [swiperOffset.left, swiperOffset.top + _this.height],
1135                [swiperOffset.left + _this.width, swiperOffset.top + _this.height]
1136            ];
1137            for (var i = 0; i < swiperCoord.length; i++) {
1138                var point = swiperCoord[i];
1139                if (
1140                    point[0] >= scrollLeft && point[0] <= scrollLeft + windowWidth &&
1141                    point[1] >= scrollTop && point[1] <= scrollTop + windowHeight
1142                ) {
1143                    inView = true;
1144                }
1145
1146            }
1147            if (!inView) return;
1148        }
1149        if (isH) {
1150            if (kc === 37 || kc === 39) {
1151                if (e.preventDefault) e.preventDefault();
1152                else e.returnValue = false;
1153            }
1154            if (kc === 39) _this.swipeNext();
1155            if (kc === 37) _this.swipePrev();
1156        }
1157        else {
1158            if (kc === 38 || kc === 40) {
1159                if (e.preventDefault) e.preventDefault();
1160                else e.returnValue = false;
1161            }
1162            if (kc === 40) _this.swipeNext();
1163            if (kc === 38) _this.swipePrev();
1164        }
1165    }
1166
1167    _this.disableKeyboardControl = function () {
1168        params.keyboardControl = false;
1169        _this.h.removeEventListener(document, 'keydown', handleKeyboardKeys);
1170    };
1171
1172    _this.enableKeyboardControl = function () {
1173        params.keyboardControl = true;
1174        _this.h.addEventListener(document, 'keydown', handleKeyboardKeys);
1175    };
1176
1177    /*==========================================
1178        Mousewheel Control
1179    ============================================*/
1180    var lastScrollTime = (new Date()).getTime();
1181    function handleMousewheel(e) {
1182        var we = _this._wheelEvent;
1183        var delta = 0;
1184
1185        //Opera & IE
1186        if (e.detail) delta = -e.detail;
1187        //WebKits
1188        else if (we === 'mousewheel') {
1189            if (params.mousewheelControlForceToAxis) {
1190                if (isH) {
1191                    if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX;
1192                    else return;
1193                }
1194                else {
1195                    if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY;
1196                    else return;
1197                }
1198            }
1199            else {
1200                delta = e.wheelDelta;
1201            }
1202        }
1203        //Old FireFox
1204        else if (we === 'DOMMouseScroll') delta = -e.detail;
1205        //New FireFox
1206        else if (we === 'wheel') {
1207            if (params.mousewheelControlForceToAxis) {
1208                if (isH) {
1209                    if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX;
1210                    else return;
1211                }
1212                else {
1213                    if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY;
1214                    else return;
1215                }
1216            }
1217            else {
1218                delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX : - e.deltaY;
1219            }
1220        }
1221
1222        if (!params.freeMode) {
1223            if ((new Date()).getTime() - lastScrollTime > 60) {
1224                if (delta < 0) _this.swipeNext();
1225                else _this.swipePrev();
1226            }
1227            lastScrollTime = (new Date()).getTime();
1228
1229        }
1230        else {
1231            //Freemode or scrollContainer:
1232            var position = _this.getWrapperTranslate() + delta;
1233
1234            if (position > 0) position = 0;
1235            if (position < -maxWrapperPosition()) position = -maxWrapperPosition();
1236
1237            _this.setWrapperTransition(0);
1238            _this.setWrapperTranslate(position);
1239            _this.updateActiveSlide(position);
1240
1241            // Return page scroll on edge positions
1242            if (position === 0 || position === -maxWrapperPosition()) return;
1243        }
1244        if (params.autoplay) _this.stopAutoplay(true);
1245
1246        if (e.preventDefault) e.preventDefault();
1247        else e.returnValue = false;
1248        return false;
1249    }
1250    _this.disableMousewheelControl = function () {
1251        if (!_this._wheelEvent) return false;
1252        params.mousewheelControl = false;
1253        _this.h.removeEventListener(_this.container, _this._wheelEvent, handleMousewheel);
1254        return true;
1255    };
1256
1257    _this.enableMousewheelControl = function () {
1258        if (!_this._wheelEvent) return false;
1259        params.mousewheelControl = true;
1260        _this.h.addEventListener(_this.container, _this._wheelEvent, handleMousewheel);
1261        return true;
1262    };
1263
1264    /*=========================
1265      Grab Cursor
1266      ===========================*/
1267    if (params.grabCursor) {
1268        var containerStyle = _this.container.style;
1269        containerStyle.cursor = 'move';
1270        containerStyle.cursor = 'grab';
1271        containerStyle.cursor = '-moz-grab';
1272        containerStyle.cursor = '-webkit-grab';
1273    }
1274
1275    /*=========================
1276      Slides Events Handlers
1277      ===========================*/
1278
1279    _this.allowSlideClick = true;
1280    function slideClick(event) {
1281        if (_this.allowSlideClick) {
1282            setClickedSlide(event);
1283            _this.fireCallback(params.onSlideClick, _this, event);
1284        }
1285    }
1286
1287    function slideTouch(event) {
1288        setClickedSlide(event);
1289        _this.fireCallback(params.onSlideTouch, _this, event);
1290    }
1291
1292    function setClickedSlide(event) {
1293
1294        // IE 6-8 support
1295        if (!event.currentTarget) {
1296            var element = event.srcElement;
1297            do {
1298                if (element.className.indexOf(params.slideClass) > -1) {
1299                    break;
1300                }
1301                element = element.parentNode;
1302            } while (element);
1303            _this.clickedSlide = element;
1304        }
1305        else {
1306            _this.clickedSlide = event.currentTarget;
1307        }
1308
1309        _this.clickedSlideIndex     = _this.slides.indexOf(_this.clickedSlide);
1310        _this.clickedSlideLoopIndex = _this.clickedSlideIndex - (_this.loopedSlides || 0);
1311    }
1312
1313    _this.allowLinks = true;
1314    function preventClick(e) {
1315        if (!_this.allowLinks) {
1316            if (e.preventDefault) e.preventDefault();
1317            else e.returnValue = false;
1318            if (params.preventLinksPropagation && 'stopPropagation' in e) {
1319                e.stopPropagation();
1320            }
1321            return false;
1322        }
1323    }
1324    function releaseForms(e) {
1325        if (e.stopPropagation) e.stopPropagation();
1326        else e.returnValue = false;
1327        return false;
1328
1329    }
1330
1331    /*==================================================
1332        Event Handlers
1333    ====================================================*/
1334    var isTouchEvent = false;
1335    var allowThresholdMove;
1336    var allowMomentumBounce = true;
1337    function onTouchStart(event) {
1338        if (params.preventLinks) _this.allowLinks = true;
1339        //Exit if slider is already was touched
1340        if (_this.isTouched || params.onlyExternal) {
1341            return false;
1342        }
1343
1344        // Blur active elements
1345        var eventTarget = event.target || event.srcElement;
1346        if (document.activeElement && document.activeElement !== document.body) {
1347            if (document.activeElement !== eventTarget) document.activeElement.blur();
1348        }
1349
1350        // Form tag names
1351        var formTagNames = ('input select textarea').split(' ');
1352
1353        // Check for no swiping
1354        if (params.noSwiping && (eventTarget) && noSwipingSlide(eventTarget)) return false;
1355        allowMomentumBounce = false;
1356        //Check For Nested Swipers
1357        _this.isTouched = true;
1358        isTouchEvent = event.type === 'touchstart';
1359
1360        // prevent user enter with right and the swiper move (needs isTouchEvent)
1361        if (!isTouchEvent && 'which' in event && event.which === 3) {
1362            _this.isTouched = false;
1363            return false;
1364        }
1365
1366        if (!isTouchEvent || event.targetTouches.length === 1) {
1367            _this.callPlugins('onTouchStartBegin');
1368            if (!isTouchEvent && !_this.isAndroid && formTagNames.indexOf(eventTarget.tagName.toLowerCase()) < 0) {
1369
1370                if (event.preventDefault) event.preventDefault();
1371                else event.returnValue = false;
1372            }
1373
1374            var pageX = isTouchEvent ? event.targetTouches[0].pageX : (event.pageX || event.clientX);
1375            var pageY = isTouchEvent ? event.targetTouches[0].pageY : (event.pageY || event.clientY);
1376
1377            //Start Touches to check the scrolling
1378            _this.touches.startX = _this.touches.currentX = pageX;
1379            _this.touches.startY = _this.touches.currentY = pageY;
1380
1381            _this.touches.start = _this.touches.current = isH ? pageX : pageY;
1382
1383            //Set Transition Time to 0
1384            _this.setWrapperTransition(0);
1385
1386            //Get Start Translate Position
1387            _this.positions.start = _this.positions.current = _this.getWrapperTranslate();
1388
1389            //Set Transform
1390            _this.setWrapperTranslate(_this.positions.start);
1391
1392            //TouchStartTime
1393            _this.times.start = (new Date()).getTime();
1394
1395            //Unset Scrolling
1396            isScrolling = undefined;
1397
1398            //Set Treshold
1399            if (params.moveStartThreshold > 0) {
1400                allowThresholdMove = false;
1401            }
1402
1403            //CallBack
1404            if (params.onTouchStart) _this.fireCallback(params.onTouchStart, _this, event);
1405            _this.callPlugins('onTouchStartEnd');
1406
1407        }
1408    }
1409    var velocityPrevPosition, velocityPrevTime;
1410    function onTouchMove(event) {
1411        // If slider is not touched - exit
1412        if (!_this.isTouched || params.onlyExternal) return;
1413        if (isTouchEvent && event.type === 'mousemove') return;
1414
1415        var pageX = isTouchEvent ? event.targetTouches[0].pageX : (event.pageX || event.clientX);
1416        var pageY = isTouchEvent ? event.targetTouches[0].pageY : (event.pageY || event.clientY);
1417
1418        //check for scrolling
1419        if (typeof isScrolling === 'undefined' && isH) {
1420            isScrolling = !!(isScrolling || Math.abs(pageY - _this.touches.startY) > Math.abs(pageX - _this.touches.startX));
1421        }
1422        if (typeof isScrolling === 'undefined' && !isH) {
1423            isScrolling = !!(isScrolling || Math.abs(pageY - _this.touches.startY) < Math.abs(pageX - _this.touches.startX));
1424        }
1425        if (isScrolling) {
1426            _this.isTouched = false;
1427            return;
1428        }
1429
1430        // One way swipes
1431        if (isH) {
1432            if ((!params.swipeToNext && pageX < _this.touches.startX) || ((!params.swipeToPrev && pageX > _this.touches.startX))) {
1433                return;
1434            }
1435        }
1436        else {
1437            if ((!params.swipeToNext && pageY < _this.touches.startY) || ((!params.swipeToPrev && pageY > _this.touches.startY))) {
1438                return;
1439            }
1440        }
1441
1442        //Check For Nested Swipers
1443        if (event.assignedToSwiper) {
1444            _this.isTouched = false;
1445            return;
1446        }
1447        event.assignedToSwiper = true;
1448
1449        //Block inner links
1450        if (params.preventLinks) {
1451            _this.allowLinks = false;
1452        }
1453        if (params.onSlideClick) {
1454            _this.allowSlideClick = false;
1455        }
1456
1457        //Stop AutoPlay if exist
1458        if (params.autoplay) {
1459            _this.stopAutoplay(true);
1460        }
1461        if (!isTouchEvent || event.touches.length === 1) {
1462
1463            //Moved Flag
1464            if (!_this.isMoved) {
1465                _this.callPlugins('onTouchMoveStart');
1466
1467                if (params.loop) {
1468                    _this.fixLoop();
1469                    _this.positions.start = _this.getWrapperTranslate();
1470                }
1471                if (params.onTouchMoveStart) _this.fireCallback(params.onTouchMoveStart, _this);
1472            }
1473            _this.isMoved = true;
1474
1475            // cancel event
1476            if (event.preventDefault) event.preventDefault();
1477            else event.returnValue = false;
1478
1479            _this.touches.current = isH ? pageX : pageY;
1480
1481            _this.positions.current = (_this.touches.current - _this.touches.start) * params.touchRatio + _this.positions.start;
1482
1483            //Resistance Callbacks
1484            if (_this.positions.current > 0 && params.onResistanceBefore) {
1485                _this.fireCallback(params.onResistanceBefore, _this, _this.positions.current);
1486            }
1487            if (_this.positions.current < -maxWrapperPosition() && params.onResistanceAfter) {
1488                _this.fireCallback(params.onResistanceAfter, _this, Math.abs(_this.positions.current + maxWrapperPosition()));
1489            }
1490            //Resistance
1491            if (params.resistance && params.resistance !== '100%') {
1492                var resistance;
1493                //Resistance for Negative-Back sliding
1494                if (_this.positions.current > 0) {
1495                    resistance = 1 - _this.positions.current / containerSize / 2;
1496                    if (resistance < 0.5)
1497                        _this.positions.current = (containerSize / 2);
1498                    else
1499                        _this.positions.current = _this.positions.current * resistance;
1500                }
1501                //Resistance for After-End Sliding
1502                if (_this.positions.current < -maxWrapperPosition()) {
1503
1504                    var diff = (_this.touches.current - _this.touches.start) * params.touchRatio + (maxWrapperPosition() + _this.positions.start);
1505                    resistance = (containerSize + diff) / (containerSize);
1506                    var newPos = _this.positions.current - diff * (1 - resistance) / 2;
1507                    var stopPos = -maxWrapperPosition() - containerSize / 2;
1508
1509                    if (newPos < stopPos || resistance <= 0)
1510                        _this.positions.current = stopPos;
1511                    else
1512                        _this.positions.current = newPos;
1513                }
1514            }
1515            if (params.resistance && params.resistance === '100%') {
1516                //Resistance for Negative-Back sliding
1517                if (_this.positions.current > 0 && !(params.freeMode && !params.freeModeFluid)) {
1518                    _this.positions.current = 0;
1519                }
1520                //Resistance for After-End Sliding
1521                if (_this.positions.current < -maxWrapperPosition() && !(params.freeMode && !params.freeModeFluid)) {
1522                    _this.positions.current = -maxWrapperPosition();
1523                }
1524            }
1525            //Move Slides
1526            if (!params.followFinger) return;
1527
1528            if (!params.moveStartThreshold) {
1529                _this.setWrapperTranslate(_this.positions.current);
1530            }
1531            else {
1532                if (Math.abs(_this.touches.current - _this.touches.start) > params.moveStartThreshold || allowThresholdMove) {
1533                    if (!allowThresholdMove) {
1534                        allowThresholdMove = true;
1535                        _this.touches.start = _this.touches.current;
1536                        return;
1537                    }
1538                    _this.setWrapperTranslate(_this.positions.current);
1539                }
1540                else {
1541                    _this.positions.current = _this.positions.start;
1542                }
1543            }
1544
1545            if (params.freeMode || params.watchActiveIndex) {
1546                _this.updateActiveSlide(_this.positions.current);
1547            }
1548
1549            //Grab Cursor
1550            if (params.grabCursor) {
1551                _this.container.style.cursor = 'move';
1552                _this.container.style.cursor = 'grabbing';
1553                _this.container.style.cursor = '-moz-grabbin';
1554                _this.container.style.cursor = '-webkit-grabbing';
1555            }
1556            //Velocity
1557            if (!velocityPrevPosition) velocityPrevPosition = _this.touches.current;
1558            if (!velocityPrevTime) velocityPrevTime = (new Date()).getTime();
1559            _this.velocity = (_this.touches.current - velocityPrevPosition) / ((new Date()).getTime() - velocityPrevTime) / 2;
1560            if (Math.abs(_this.touches.current - velocityPrevPosition) < 2) _this.velocity = 0;
1561            velocityPrevPosition = _this.touches.current;
1562            velocityPrevTime = (new Date()).getTime();
1563            //Callbacks
1564            _this.callPlugins('onTouchMoveEnd');
1565            if (params.onTouchMove) _this.fireCallback(params.onTouchMove, _this, event);
1566
1567            return false;
1568        }
1569    }
1570    function onTouchEnd(event) {
1571        //Check For scrolling
1572        if (isScrolling) {
1573            _this.swipeReset();
1574        }
1575        // If slider is not touched exit
1576        if (params.onlyExternal || !_this.isTouched) return;
1577        _this.isTouched = false;
1578
1579        //Return Grab Cursor
1580        if (params.grabCursor) {
1581            _this.container.style.cursor = 'move';
1582            _this.container.style.cursor = 'grab';
1583            _this.container.style.cursor = '-moz-grab';
1584            _this.container.style.cursor = '-webkit-grab';
1585        }
1586
1587        //Check for Current Position
1588        if (!_this.positions.current && _this.positions.current !== 0) {
1589            _this.positions.current = _this.positions.start;
1590        }
1591
1592        //For case if slider touched but not moved
1593        if (params.followFinger) {
1594            _this.setWrapperTranslate(_this.positions.current);
1595        }
1596
1597        // TouchEndTime
1598        _this.times.end = (new Date()).getTime();
1599
1600        //Difference
1601        _this.touches.diff = _this.touches.current - _this.touches.start;
1602        _this.touches.abs = Math.abs(_this.touches.diff);
1603
1604        _this.positions.diff = _this.positions.current - _this.positions.start;
1605        _this.positions.abs = Math.abs(_this.positions.diff);
1606
1607        var diff = _this.positions.diff;
1608        var diffAbs = _this.positions.abs;
1609        var timeDiff = _this.times.end - _this.times.start;
1610
1611        if (diffAbs < 5 && (timeDiff) < 300 && _this.allowLinks === false) {
1612            if (!params.freeMode && diffAbs !== 0) _this.swipeReset();
1613            //Release inner links
1614            if (params.preventLinks) {
1615                _this.allowLinks = true;
1616            }
1617            if (params.onSlideClick) {
1618                _this.allowSlideClick = true;
1619            }
1620        }
1621
1622        setTimeout(function () {
1623            //Release inner links
1624            if (typeof _this === 'undefined' || _this === null) return;
1625            if (params.preventLinks) {
1626                _this.allowLinks = true;
1627            }
1628            if (params.onSlideClick) {
1629                _this.allowSlideClick = true;
1630            }
1631        }, 100);
1632
1633        var maxPosition = maxWrapperPosition();
1634
1635        //Not moved or Prevent Negative Back Sliding/After-End Sliding
1636        if (!_this.isMoved && params.freeMode) {
1637            _this.isMoved = false;
1638            if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this, event);
1639            _this.callPlugins('onTouchEnd');
1640            return;
1641        }
1642        if (!_this.isMoved || _this.positions.current > 0 || _this.positions.current < -maxPosition) {
1643            _this.swipeReset();
1644            if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this, event);
1645            _this.callPlugins('onTouchEnd');
1646            return;
1647        }
1648
1649        _this.isMoved = false;
1650
1651        //Free Mode
1652        if (params.freeMode) {
1653            if (params.freeModeFluid) {
1654                var momentumDuration = 1000 * params.momentumRatio;
1655                var momentumDistance = _this.velocity * momentumDuration;
1656                var newPosition = _this.positions.current + momentumDistance;
1657                var doBounce = false;
1658                var afterBouncePosition;
1659                var bounceAmount = Math.abs(_this.velocity) * 20 * params.momentumBounceRatio;
1660                if (newPosition < -maxPosition) {
1661                    if (params.momentumBounce && _this.support.transitions) {
1662                        if (newPosition + maxPosition < -bounceAmount) newPosition = -maxPosition - bounceAmount;
1663                        afterBouncePosition = -maxPosition;
1664                        doBounce = true;
1665                        allowMomentumBounce = true;
1666                    }
1667                    else newPosition = -maxPosition;
1668                }
1669                if (newPosition > 0) {
1670                    if (params.momentumBounce && _this.support.transitions) {
1671                        if (newPosition > bounceAmount) newPosition = bounceAmount;
1672                        afterBouncePosition = 0;
1673                        doBounce = true;
1674                        allowMomentumBounce = true;
1675                    }
1676                    else newPosition = 0;
1677                }
1678                //Fix duration
1679                if (_this.velocity !== 0) momentumDuration = Math.abs((newPosition - _this.positions.current) / _this.velocity);
1680
1681                _this.setWrapperTranslate(newPosition);
1682
1683                _this.setWrapperTransition(momentumDuration);
1684
1685                if (params.momentumBounce && doBounce) {
1686                    _this.wrapperTransitionEnd(function () {
1687                        if (!allowMomentumBounce) return;
1688                        if (params.onMomentumBounce) _this.fireCallback(params.onMomentumBounce, _this);
1689                        _this.callPlugins('onMomentumBounce');
1690
1691                        _this.setWrapperTranslate(afterBouncePosition);
1692                        _this.setWrapperTransition(300);
1693                    });
1694                }
1695
1696                _this.updateActiveSlide(newPosition);
1697            }
1698            if (!params.freeModeFluid || timeDiff >= 300) _this.updateActiveSlide(_this.positions.current);
1699
1700            if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this, event);
1701            _this.callPlugins('onTouchEnd');
1702            return;
1703        }
1704
1705        //Direction
1706        direction = diff < 0 ? 'toNext' : 'toPrev';
1707
1708        //Short Touches
1709        if (direction === 'toNext' && (timeDiff <= 300)) {
1710            if (diffAbs < 30 || !params.shortSwipes) _this.swipeReset();
1711            else _this.swipeNext(true, true);
1712        }
1713
1714        if (direction === 'toPrev' && (timeDiff <= 300)) {
1715            if (diffAbs < 30 || !params.shortSwipes) _this.swipeReset();
1716            else _this.swipePrev(true, true);
1717        }
1718
1719        //Long Touches
1720        var targetSlideSize = 0;
1721        if (params.slidesPerView === 'auto') {
1722            //Define current slide's width
1723            var currentPosition = Math.abs(_this.getWrapperTranslate());
1724            var slidesOffset = 0;
1725            var _slideSize;
1726            for (var i = 0; i < _this.slides.length; i++) {
1727                _slideSize = isH ? _this.slides[i].getWidth(true, params.roundLengths) : _this.slides[i].getHeight(true, params.roundLengths);
1728                slidesOffset += _slideSize;
1729                if (slidesOffset > currentPosition) {
1730                    targetSlideSize = _slideSize;
1731                    break;
1732                }
1733            }
1734            if (targetSlideSize > containerSize) targetSlideSize = containerSize;
1735        }
1736        else {
1737            targetSlideSize = slideSize * params.slidesPerView;
1738        }
1739        if (direction === 'toNext' && (timeDiff > 300)) {
1740            if (diffAbs >= targetSlideSize * params.longSwipesRatio) {
1741                _this.swipeNext(true, true);
1742            }
1743            else {
1744                _this.swipeReset();
1745            }
1746        }
1747        if (direction === 'toPrev' && (timeDiff > 300)) {
1748            if (diffAbs >= targetSlideSize * params.longSwipesRatio) {
1749                _this.swipePrev(true, true);
1750            }
1751            else {
1752                _this.swipeReset();
1753            }
1754        }
1755        if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this, event);
1756        _this.callPlugins('onTouchEnd');
1757    }
1758
1759
1760    /*==================================================
1761        noSwiping Bubble Check by Isaac Strack
1762    ====================================================*/
1763    function hasClass(el, classname) {
1764        return el && el.getAttribute('class') && el.getAttribute('class').indexOf(classname) > -1;
1765    }
1766    function noSwipingSlide(el) {
1767        /*This function is specifically designed to check the parent elements for the noSwiping class, up to the wrapper.
1768        We need to check parents because while onTouchStart bubbles, _this.isTouched is checked in onTouchStart, which stops the bubbling.
1769        So, if a text box, for example, is the initial target, and the parent slide container has the noSwiping class, the _this.isTouched
1770        check will never find it, and what was supposed to be noSwiping is able to be swiped.
1771        This function will iterate up and check for the noSwiping class in parents, up through the wrapperClass.*/
1772
1773        // First we create a truthy variable, which is that swiping is allowd (noSwiping = false)
1774        var noSwiping = false;
1775
1776        // Now we iterate up (parentElements) until we reach the node with the wrapperClass.
1777        do {
1778
1779            // Each time, we check to see if there's a 'swiper-no-swiping' class (noSwipingClass).
1780            if (hasClass(el, params.noSwipingClass))
1781            {
1782                noSwiping = true; // If there is, we set noSwiping = true;
1783            }
1784
1785            el = el.parentElement;  // now we iterate up (parent node)
1786
1787        } while (!noSwiping && el.parentElement && !hasClass(el, params.wrapperClass)); // also include el.parentElement truthy, just in case.
1788
1789        // because we didn't check the wrapper itself, we do so now, if noSwiping is false:
1790        if (!noSwiping && hasClass(el, params.wrapperClass) && hasClass(el, params.noSwipingClass))
1791            noSwiping = true; // if the wrapper has the noSwipingClass, we set noSwiping = true;
1792
1793        return noSwiping;
1794    }
1795
1796    function addClassToHtmlString(klass, outerHtml) {
1797        var par = document.createElement('div');
1798        var child;
1799
1800        par.innerHTML = outerHtml;
1801        child = par.firstChild;
1802        child.className += ' ' + klass;
1803
1804        return child.outerHTML;
1805    }
1806
1807
1808    /*==================================================
1809        Swipe Functions
1810    ====================================================*/
1811    _this.swipeNext = function (runCallbacks, internal) {
1812        if (typeof runCallbacks === 'undefined') runCallbacks = true;
1813        if (!internal && params.loop) _this.fixLoop();
1814        if (!internal && params.autoplay) _this.stopAutoplay(true);
1815        _this.callPlugins('onSwipeNext');
1816        var currentPosition = _this.getWrapperTranslate().toFixed(2);
1817        var newPosition = currentPosition;
1818        if (params.slidesPerView === 'auto') {
1819            for (var i = 0; i < _this.snapGrid.length; i++) {
1820                if (-currentPosition >= _this.snapGrid[i].toFixed(2) && -currentPosition < _this.snapGrid[i + 1].toFixed(2)) {
1821                    newPosition = -_this.snapGrid[i + 1];
1822                    break;
1823                }
1824            }
1825        }
1826        else {
1827            var groupSize = slideSize * params.slidesPerGroup;
1828            newPosition = -(Math.floor(Math.abs(currentPosition) / Math.floor(groupSize)) * groupSize + groupSize);
1829        }
1830        if (newPosition < -maxWrapperPosition()) {
1831            newPosition = -maxWrapperPosition();
1832        }
1833        if (newPosition === currentPosition) return false;
1834        swipeToPosition(newPosition, 'next', {runCallbacks: runCallbacks});
1835        return true;
1836    };
1837    _this.swipePrev = function (runCallbacks, internal) {
1838        if (typeof runCallbacks === 'undefined') runCallbacks = true;
1839        if (!internal && params.loop) _this.fixLoop();
1840        if (!internal && params.autoplay) _this.stopAutoplay(true);
1841        _this.callPlugins('onSwipePrev');
1842
1843        var currentPosition = Math.ceil(_this.getWrapperTranslate());
1844        var newPosition;
1845        if (params.slidesPerView === 'auto') {
1846            newPosition = 0;
1847            for (var i = 1; i < _this.snapGrid.length; i++) {
1848                if (-currentPosition === _this.snapGrid[i]) {
1849                    newPosition = -_this.snapGrid[i - 1];
1850                    break;
1851                }
1852                if (-currentPosition > _this.snapGrid[i] && -currentPosition < _this.snapGrid[i + 1]) {
1853                    newPosition = -_this.snapGrid[i];
1854                    break;
1855                }
1856            }
1857        }
1858        else {
1859            var groupSize = slideSize * params.slidesPerGroup;
1860            newPosition = -(Math.ceil(-currentPosition / groupSize) - 1) * groupSize;
1861        }
1862
1863        if (newPosition > 0) newPosition = 0;
1864
1865        if (newPosition === currentPosition) return false;
1866        swipeToPosition(newPosition, 'prev', {runCallbacks: runCallbacks});
1867        return true;
1868
1869    };
1870    _this.swipeReset = function (runCallbacks) {
1871        if (typeof runCallbacks === 'undefined') runCallbacks = true;
1872        _this.callPlugins('onSwipeReset');
1873        var currentPosition = _this.getWrapperTranslate();
1874        var groupSize = slideSize * params.slidesPerGroup;
1875        var newPosition;
1876        var maxPosition = -maxWrapperPosition();
1877        if (params.slidesPerView === 'auto') {
1878            newPosition = 0;
1879            for (var i = 0; i < _this.snapGrid.length; i++) {
1880                if (-currentPosition === _this.snapGrid[i]) return;
1881                if (-currentPosition >= _this.snapGrid[i] && -currentPosition < _this.snapGrid[i + 1]) {
1882                    if (_this.positions.diff > 0) newPosition = -_this.snapGrid[i + 1];
1883                    else newPosition = -_this.snapGrid[i];
1884                    break;
1885                }
1886            }
1887            if (-currentPosition >= _this.snapGrid[_this.snapGrid.length - 1]) newPosition = -_this.snapGrid[_this.snapGrid.length - 1];
1888            if (currentPosition <= -maxWrapperPosition()) newPosition = -maxWrapperPosition();
1889        }
1890        else {
1891            newPosition = currentPosition < 0 ? Math.round(currentPosition / groupSize) * groupSize : 0;
1892            if (currentPosition <= -maxWrapperPosition()) newPosition = -maxWrapperPosition();
1893        }
1894        if (params.scrollContainer)  {
1895            newPosition = currentPosition < 0 ? currentPosition : 0;
1896        }
1897        if (newPosition < -maxWrapperPosition()) {
1898            newPosition = -maxWrapperPosition();
1899        }
1900        if (params.scrollContainer && (containerSize > slideSize)) {
1901            newPosition = 0;
1902        }
1903
1904        if (newPosition === currentPosition) return false;
1905
1906        swipeToPosition(newPosition, 'reset', {runCallbacks: runCallbacks});
1907        return true;
1908    };
1909
1910    _this.swipeTo = function (index, speed, runCallbacks) {
1911        index = parseInt(index, 10);
1912        _this.callPlugins('onSwipeTo', {index: index, speed: speed});
1913        if (params.loop) index = index + _this.loopedSlides;
1914        var currentPosition = _this.getWrapperTranslate();
1915        if (!isFinite(index) || index > (_this.slides.length - 1) || index < 0) return;
1916        var newPosition;
1917        if (params.slidesPerView === 'auto') {
1918            newPosition = -_this.slidesGrid[index];
1919        }
1920        else {
1921            newPosition = -index * slideSize;
1922        }
1923        if (newPosition < - maxWrapperPosition()) {
1924            newPosition = - maxWrapperPosition();
1925        }
1926
1927        if (newPosition === currentPosition) return false;
1928
1929        if (typeof runCallbacks === 'undefined') runCallbacks = true;
1930        swipeToPosition(newPosition, 'to', {index: index, speed: speed, runCallbacks: runCallbacks});
1931        return true;
1932    };
1933
1934    function swipeToPosition(newPosition, action, toOptions) {
1935        var speed = (action === 'to' && toOptions.speed >= 0) ? toOptions.speed : params.speed;
1936        var timeOld = + new Date();
1937
1938        function anim() {
1939            var timeNew = + new Date();
1940            var time = timeNew - timeOld;
1941            currentPosition += animationStep * time / (1000 / 60);
1942            condition = direction === 'toNext' ? currentPosition > newPosition : currentPosition < newPosition;
1943            if (condition) {
1944                _this.setWrapperTranslate(Math.ceil(currentPosition));
1945                _this._DOMAnimating = true;
1946                window.setTimeout(function () {
1947                    anim();
1948                }, 1000 / 60);
1949            }
1950            else {
1951                if (params.onSlideChangeEnd) {
1952                    if (action === 'to') {
1953                        if (toOptions.runCallbacks === true) _this.fireCallback(params.onSlideChangeEnd, _this, direction);
1954                    }
1955                    else {
1956                        _this.fireCallback(params.onSlideChangeEnd, _this, direction);
1957                    }
1958
1959                }
1960                _this.setWrapperTranslate(newPosition);
1961                _this._DOMAnimating = false;
1962            }
1963        }
1964
1965        if (_this.support.transitions || !params.DOMAnimation) {
1966            _this.setWrapperTransition(speed);
1967            _this.setWrapperTranslate(newPosition);
1968        }
1969        else {
1970            //Try the DOM animation
1971            var currentPosition = _this.getWrapperTranslate();
1972            var animationStep = Math.ceil((newPosition - currentPosition) / speed * (1000 / 60));
1973            var direction = currentPosition > newPosition ? 'toNext' : 'toPrev';
1974            var condition = direction === 'toNext' ? currentPosition > newPosition : currentPosition < newPosition;
1975            if (_this._DOMAnimating) return;
1976
1977            anim();
1978        }
1979
1980        //Update Active Slide Index
1981        _this.updateActiveSlide(newPosition);
1982
1983        //Callbacks
1984        if (params.onSlideNext && action === 'next' && toOptions.runCallbacks === true) {
1985            _this.fireCallback(params.onSlideNext, _this, newPosition);
1986        }
1987        if (params.onSlidePrev && action === 'prev' && toOptions.runCallbacks === true) {
1988            _this.fireCallback(params.onSlidePrev, _this, newPosition);
1989        }
1990        //'Reset' Callback
1991        if (params.onSlideReset && action === 'reset' && toOptions.runCallbacks === true) {
1992            _this.fireCallback(params.onSlideReset, _this, newPosition);
1993        }
1994
1995        //'Next', 'Prev' and 'To' Callbacks
1996        if ((action === 'next' || action === 'prev' || action === 'to') && toOptions.runCallbacks === true)
1997            slideChangeCallbacks(action);
1998    }
1999    /*==================================================
2000        Transition Callbacks
2001    ====================================================*/
2002    //Prevent Multiple Callbacks
2003    _this._queueStartCallbacks = false;
2004    _this._queueEndCallbacks = false;
2005    function slideChangeCallbacks(direction) {
2006        //Transition Start Callback
2007        _this.callPlugins('onSlideChangeStart');
2008        if (params.onSlideChangeStart) {
2009            if (params.queueStartCallbacks && _this.support.transitions) {
2010                if (_this._queueStartCallbacks) return;
2011                _this._queueStartCallbacks = true;
2012                _this.fireCallback(params.onSlideChangeStart, _this, direction);
2013                _this.wrapperTransitionEnd(function () {
2014                    _this._queueStartCallbacks = false;
2015                });
2016            }
2017            else _this.fireCallback(params.onSlideChangeStart, _this, direction);
2018        }
2019        //Transition End Callback
2020        if (params.onSlideChangeEnd) {
2021            if (_this.support.transitions) {
2022                if (params.queueEndCallbacks) {
2023                    if (_this._queueEndCallbacks) return;
2024                    _this._queueEndCallbacks = true;
2025                    _this.wrapperTransitionEnd(function (swiper) {
2026                        _this.fireCallback(params.onSlideChangeEnd, swiper, direction);
2027                    });
2028                }
2029                else {
2030                    _this.wrapperTransitionEnd(function (swiper) {
2031                        _this.fireCallback(params.onSlideChangeEnd, swiper, direction);
2032                    });
2033                }
2034            }
2035            else {
2036                if (!params.DOMAnimation) {
2037                    setTimeout(function () {
2038                        _this.fireCallback(params.onSlideChangeEnd, _this, direction);
2039                    }, 10);
2040                }
2041            }
2042        }
2043    }
2044
2045    /*==================================================
2046        Update Active Slide Index
2047    ====================================================*/
2048    _this.updateActiveSlide = function (position) {
2049        if (!_this.initialized) return;
2050        if (_this.slides.length === 0) return;
2051        _this.previousIndex = _this.activeIndex;
2052        if (typeof position === 'undefined') position = _this.getWrapperTranslate();
2053        if (position > 0) position = 0;
2054        var i;
2055        if (params.slidesPerView === 'auto') {
2056            var slidesOffset = 0;
2057            _this.activeIndex = _this.slidesGrid.indexOf(-position);
2058            if (_this.activeIndex < 0) {
2059                for (i = 0; i < _this.slidesGrid.length - 1; i++) {
2060                    if (-position > _this.slidesGrid[i] && -position < _this.slidesGrid[i + 1]) {
2061                        break;
2062                    }
2063                }
2064                var leftDistance = Math.abs(_this.slidesGrid[i] + position);
2065                var rightDistance = Math.abs(_this.slidesGrid[i + 1] + position);
2066                if (leftDistance <= rightDistance) _this.activeIndex = i;
2067                else _this.activeIndex = i + 1;
2068            }
2069        }
2070        else {
2071            _this.activeIndex = Math[params.visibilityFullFit ? 'ceil' : 'round'](-position / slideSize);
2072        }
2073
2074        if (_this.activeIndex === _this.slides.length) _this.activeIndex = _this.slides.length - 1;
2075        if (_this.activeIndex < 0) _this.activeIndex = 0;
2076
2077        // Check for slide
2078        if (!_this.slides[_this.activeIndex]) return;
2079
2080        // Calc Visible slides
2081        _this.calcVisibleSlides(position);
2082
2083        // Mark visible and active slides with additonal classes
2084        if (_this.support.classList) {
2085            var slide;
2086            for (i = 0; i < _this.slides.length; i++) {
2087                slide = _this.slides[i];
2088                slide.classList.remove(params.slideActiveClass);
2089                if (_this.visibleSlides.indexOf(slide) >= 0) {
2090                    slide.classList.add(params.slideVisibleClass);
2091                } else {
2092                    slide.classList.remove(params.slideVisibleClass);
2093                }
2094            }
2095            _this.slides[_this.activeIndex].classList.add(params.slideActiveClass);
2096        } else {
2097            var activeClassRegexp = new RegExp('\\s*' + params.slideActiveClass);
2098            var inViewClassRegexp = new RegExp('\\s*' + params.slideVisibleClass);
2099
2100            for (i = 0; i < _this.slides.length; i++) {
2101                _this.slides[i].className = _this.slides[i].className.replace(activeClassRegexp, '').replace(inViewClassRegexp, '');
2102                if (_this.visibleSlides.indexOf(_this.slides[i]) >= 0) {
2103                    _this.slides[i].className += ' ' + params.slideVisibleClass;
2104                }
2105            }
2106            _this.slides[_this.activeIndex].className += ' ' + params.slideActiveClass;
2107        }
2108
2109        //Update loop index
2110        if (params.loop) {
2111            var ls = _this.loopedSlides;
2112            _this.activeLoopIndex = _this.activeIndex - ls;
2113            if (_this.activeLoopIndex >= _this.slides.length - ls * 2) {
2114                _this.activeLoopIndex = _this.slides.length - ls * 2 - _this.activeLoopIndex;
2115            }
2116            if (_this.activeLoopIndex < 0) {
2117                _this.activeLoopIndex = _this.slides.length - ls * 2 + _this.activeLoopIndex;
2118            }
2119            if (_this.activeLoopIndex < 0) _this.activeLoopIndex = 0;
2120        }
2121        else {
2122            _this.activeLoopIndex = _this.activeIndex;
2123        }
2124        //Update Pagination
2125        if (params.pagination) {
2126            _this.updatePagination(position);
2127        }
2128    };
2129    /*==================================================
2130        Pagination
2131    ====================================================*/
2132    _this.createPagination = function (firstInit) {
2133        if (params.paginationClickable && _this.paginationButtons) {
2134            removePaginationEvents();
2135        }
2136        _this.paginationContainer = params.pagination.nodeType ? params.pagination : $$(params.pagination)[0];
2137        if (params.createPagination) {
2138            var paginationHTML = '';
2139            var numOfSlides = _this.slides.length;
2140            var numOfButtons = numOfSlides;
2141            if (params.loop) numOfButtons -= _this.loopedSlides * 2;
2142            for (var i = 0; i < numOfButtons; i++) {
2143                paginationHTML += '<' + params.paginationElement + ' class="' + params.paginationElementClass + '"></' + params.paginationElement + '>';
2144            }
2145            _this.paginationContainer.innerHTML = paginationHTML;
2146        }
2147        _this.paginationButtons = $$('.' + params.paginationElementClass, _this.paginationContainer);
2148        if (!firstInit) _this.updatePagination();
2149        _this.callPlugins('onCreatePagination');
2150        if (params.paginationClickable) {
2151            addPaginationEvents();
2152        }
2153    };
2154    function removePaginationEvents() {
2155        var pagers = _this.paginationButtons;
2156        if (pagers) {
2157            for (var i = 0; i < pagers.length; i++) {
2158                _this.h.removeEventListener(pagers[i], 'click', paginationClick);
2159            }
2160        }
2161    }
2162    function addPaginationEvents() {
2163        var pagers = _this.paginationButtons;
2164        if (pagers) {
2165            for (var i = 0; i < pagers.length; i++) {
2166                _this.h.addEventListener(pagers[i], 'click', paginationClick);
2167            }
2168        }
2169    }
2170    function paginationClick(e) {
2171        var index;
2172        var target = e.target || e.srcElement;
2173        var pagers = _this.paginationButtons;
2174        for (var i = 0; i < pagers.length; i++) {
2175            if (target === pagers[i]) index = i;
2176        }
2177        if (params.autoplay) _this.stopAutoplay(true);
2178        _this.swipeTo(index);
2179    }
2180    _this.updatePagination = function (position) {
2181        if (!params.pagination) return;
2182        if (_this.slides.length < 1) return;
2183        var activePagers = $$('.' + params.paginationActiveClass, _this.paginationContainer);
2184        if (!activePagers) return;
2185
2186        //Reset all Buttons' class to not active
2187        var pagers = _this.paginationButtons;
2188        if (pagers.length === 0) return;
2189        for (var i = 0; i < pagers.length; i++) {
2190            pagers[i].className = params.paginationElementClass;
2191        }
2192
2193        var indexOffset = params.loop ? _this.loopedSlides : 0;
2194        if (params.paginationAsRange) {
2195            if (!_this.visibleSlides) _this.calcVisibleSlides(position);
2196            //Get Visible Indexes
2197            var visibleIndexes = [];
2198            var j; // lopp index - avoid JSHint W004 / W038
2199            for (j = 0; j < _this.visibleSlides.length; j++) {
2200                var visIndex = _this.slides.indexOf(_this.visibleSlides[j]) - indexOffset;
2201
2202                if (params.loop && visIndex < 0) {
2203                    visIndex = _this.slides.length - _this.loopedSlides * 2 + visIndex;
2204                }
2205                if (params.loop && visIndex >= _this.slides.length - _this.loopedSlides * 2) {
2206                    visIndex = _this.slides.length - _this.loopedSlides * 2 - visIndex;
2207                    visIndex = Math.abs(visIndex);
2208                }
2209                visibleIndexes.push(visIndex);
2210            }
2211
2212            for (j = 0; j < visibleIndexes.length; j++) {
2213                if (pagers[visibleIndexes[j]]) pagers[visibleIndexes[j]].className += ' ' + params.paginationVisibleClass;
2214            }
2215
2216            if (params.loop) {
2217                if (pagers[_this.activeLoopIndex] !== undefined) {
2218                    pagers[_this.activeLoopIndex].className += ' ' + params.paginationActiveClass;
2219                }
2220            }
2221            else {
2222                if (pagers[_this.activeIndex]) pagers[_this.activeIndex].className += ' ' + params.paginationActiveClass;
2223            }
2224        }
2225        else {
2226            if (params.loop) {
2227                if (pagers[_this.activeLoopIndex]) pagers[_this.activeLoopIndex].className += ' ' + params.paginationActiveClass + ' ' + params.paginationVisibleClass;
2228            }
2229            else {
2230                if (pagers[_this.activeIndex]) pagers[_this.activeIndex].className += ' ' + params.paginationActiveClass + ' ' + params.paginationVisibleClass;
2231            }
2232        }
2233    };
2234    _this.calcVisibleSlides = function (position) {
2235        var visibleSlides = [];
2236        var _slideLeft = 0, _slideSize = 0, _slideRight = 0;
2237        if (isH && _this.wrapperLeft > 0) position = position + _this.wrapperLeft;
2238        if (!isH && _this.wrapperTop > 0) position = position + _this.wrapperTop;
2239
2240        for (var i = 0; i < _this.slides.length; i++) {
2241            _slideLeft += _slideSize;
2242            if (params.slidesPerView === 'auto')
2243                _slideSize  = isH ? _this.h.getWidth(_this.slides[i], true, params.roundLengths) : _this.h.getHeight(_this.slides[i], true, params.roundLengths);
2244            else _slideSize = slideSize;
2245
2246            _slideRight = _slideLeft + _slideSize;
2247            var isVisibile = false;
2248            if (params.visibilityFullFit) {
2249                if (_slideLeft >= -position && _slideRight <= -position + containerSize) isVisibile = true;
2250                if (_slideLeft <= -position && _slideRight >= -position + containerSize) isVisibile = true;
2251            }
2252            else {
2253                if (_slideRight > -position && _slideRight <= ((-position + containerSize))) isVisibile = true;
2254                if (_slideLeft >= -position && _slideLeft < ((-position + containerSize))) isVisibile = true;
2255                if (_slideLeft < -position && _slideRight > ((-position + containerSize))) isVisibile = true;
2256            }
2257
2258            if (isVisibile) visibleSlides.push(_this.slides[i]);
2259
2260        }
2261        if (visibleSlides.length === 0) visibleSlides = [_this.slides[_this.activeIndex]];
2262
2263        _this.visibleSlides = visibleSlides;
2264    };
2265
2266    /*==========================================
2267        Autoplay
2268    ============================================*/
2269    var autoplayTimeoutId, autoplayIntervalId;
2270    _this.startAutoplay = function () {
2271        if (_this.support.transitions) {
2272            if (typeof autoplayTimeoutId !== 'undefined') return false;
2273            if (!params.autoplay) return;
2274            _this.callPlugins('onAutoplayStart');
2275            if (params.onAutoplayStart) _this.fireCallback(params.onAutoplayStart, _this);
2276            autoplay();
2277        }
2278        else {
2279            if (typeof autoplayIntervalId !== 'undefined') return false;
2280            if (!params.autoplay) return;
2281            _this.callPlugins('onAutoplayStart');
2282            if (params.onAutoplayStart) _this.fireCallback(params.onAutoplayStart, _this);
2283            autoplayIntervalId = setInterval(function () {
2284                if (params.loop) {
2285                    _this.fixLoop();
2286                    _this.swipeNext(true, true);
2287                }
2288                else if (!_this.swipeNext(true, true)) {
2289                    if (!params.autoplayStopOnLast) _this.swipeTo(0);
2290                    else {
2291                        clearInterval(autoplayIntervalId);
2292                        autoplayIntervalId = undefined;
2293                    }
2294                }
2295            }, params.autoplay);
2296        }
2297    };
2298    _this.stopAutoplay = function (internal) {
2299        if (_this.support.transitions) {
2300            if (!autoplayTimeoutId) return;
2301            if (autoplayTimeoutId) clearTimeout(autoplayTimeoutId);
2302            autoplayTimeoutId = undefined;
2303            if (internal && !params.autoplayDisableOnInteraction) {
2304                _this.wrapperTransitionEnd(function () {
2305                    autoplay();
2306                });
2307            }
2308            _this.callPlugins('onAutoplayStop');
2309            if (params.onAutoplayStop) _this.fireCallback(params.onAutoplayStop, _this);
2310        }
2311        else {
2312            if (autoplayIntervalId) clearInterval(autoplayIntervalId);
2313            autoplayIntervalId = undefined;
2314            _this.callPlugins('onAutoplayStop');
2315            if (params.onAutoplayStop) _this.fireCallback(params.onAutoplayStop, _this);
2316        }
2317    };
2318    function autoplay() {
2319        autoplayTimeoutId = setTimeout(function () {
2320            if (params.loop) {
2321                _this.fixLoop();
2322                _this.swipeNext(true, true);
2323            }
2324            else if (!_this.swipeNext(true, true)) {
2325                if (!params.autoplayStopOnLast) _this.swipeTo(0);
2326                else {
2327                    clearTimeout(autoplayTimeoutId);
2328                    autoplayTimeoutId = undefined;
2329                }
2330            }
2331            _this.wrapperTransitionEnd(function () {
2332                if (typeof autoplayTimeoutId !== 'undefined') autoplay();
2333            });
2334        }, params.autoplay);
2335    }
2336    /*==================================================
2337        Loop
2338    ====================================================*/
2339    _this.loopCreated = false;
2340    _this.removeLoopedSlides = function () {
2341        if (_this.loopCreated) {
2342            for (var i = 0; i < _this.slides.length; i++) {
2343                if (_this.slides[i].getData('looped') === true) _this.wrapper.removeChild(_this.slides[i]);
2344            }
2345        }
2346    };
2347
2348    _this.createLoop = function () {
2349        if (_this.slides.length === 0) return;
2350        if (params.slidesPerView === 'auto') {
2351            _this.loopedSlides = params.loopedSlides || 1;
2352        }
2353        else {
2354            _this.loopedSlides = Math.floor(params.slidesPerView) + params.loopAdditionalSlides;
2355        }
2356
2357        if (_this.loopedSlides > _this.slides.length) {
2358            _this.loopedSlides = _this.slides.length;
2359        }
2360
2361        var slideFirstHTML = '',
2362            slideLastHTML = '',
2363            i;
2364        var slidesSetFullHTML = '';
2365        /**
2366                loopedSlides is too large if loopAdditionalSlides are set.
2367                Need to divide the slides by maximum number of slides existing.
2368
2369                @author        Tomaz Lovrec <[email protected]>
2370        */
2371        var numSlides = _this.slides.length;
2372        var fullSlideSets = Math.floor(_this.loopedSlides / numSlides);
2373        var remainderSlides = _this.loopedSlides % numSlides;
2374        // assemble full sets of slides
2375        for (i = 0; i < (fullSlideSets * numSlides); i++) {
2376            var j = i;
2377            if (i >= numSlides) {
2378                var over = Math.floor(i / numSlides);
2379                j = i - (numSlides * over);
2380            }
2381            slidesSetFullHTML += _this.slides[j].outerHTML;
2382        }
2383        // assemble remainder slides
2384        // assemble remainder appended to existing slides
2385        for (i = 0; i < remainderSlides;i++) {
2386            slideLastHTML += addClassToHtmlString(params.slideDuplicateClass, _this.slides[i].outerHTML);
2387        }
2388        // assemble slides that get preppended to existing slides
2389        for (i = numSlides - remainderSlides; i < numSlides;i++) {
2390            slideFirstHTML += addClassToHtmlString(params.slideDuplicateClass, _this.slides[i].outerHTML);
2391        }
2392        // assemble all slides
2393        var slides = slideFirstHTML + slidesSetFullHTML + wrapper.innerHTML + slidesSetFullHTML + slideLastHTML;
2394        // set the slides
2395        wrapper.innerHTML = slides;
2396
2397        _this.loopCreated = true;
2398        _this.calcSlides();
2399
2400        //Update Looped Slides with special class
2401        for (i = 0; i < _this.slides.length; i++) {
2402            if (i < _this.loopedSlides || i >= _this.slides.length - _this.loopedSlides) _this.slides[i].setData('looped', true);
2403        }
2404        _this.callPlugins('onCreateLoop');
2405
2406    };
2407
2408    _this.fixLoop = function () {
2409        var newIndex;
2410        //Fix For Negative Oversliding
2411        if (_this.activeIndex < _this.loopedSlides) {
2412            newIndex = _this.slides.length - _this.loopedSlides * 3 + _this.activeIndex;
2413            _this.swipeTo(newIndex, 0, false);
2414        }
2415        //Fix For Positive Oversliding
2416        else if ((params.slidesPerView === 'auto' && _this.activeIndex >= _this.loopedSlides * 2) || (_this.activeIndex > _this.slides.length - params.slidesPerView * 2)) {
2417            newIndex = -_this.slides.length + _this.activeIndex + _this.loopedSlides;
2418            _this.swipeTo(newIndex, 0, false);
2419        }
2420    };
2421
2422    /*==================================================
2423        Slides Loader
2424    ====================================================*/
2425    _this.loadSlides = function () {
2426        var slidesHTML = '';
2427        _this.activeLoaderIndex = 0;
2428        var slides = params.loader.slides;
2429        var slidesToLoad = params.loader.loadAllSlides ? slides.length : params.slidesPerView * (1 + params.loader.surroundGroups);
2430        for (var i = 0; i < slidesToLoad; i++) {
2431            if (params.loader.slidesHTMLType === 'outer') slidesHTML += slides[i];
2432            else {
2433                slidesHTML += '<' + params.slideElement + ' class="' + params.slideClass + '" data-swiperindex="' + i + '">' + slides[i] + '</' + params.slideElement + '>';
2434            }
2435        }
2436        _this.wrapper.innerHTML = slidesHTML;
2437        _this.calcSlides(true);
2438        //Add permanent transitionEnd callback
2439        if (!params.loader.loadAllSlides) {
2440            _this.wrapperTransitionEnd(_this.reloadSlides, true);
2441        }
2442    };
2443
2444    _this.reloadSlides = function () {
2445        var slides = params.loader.slides;
2446        var newActiveIndex = parseInt(_this.activeSlide().data('swiperindex'), 10);
2447        if (newActiveIndex < 0 || newActiveIndex > slides.length - 1) return; //<-- Exit
2448        _this.activeLoaderIndex = newActiveIndex;
2449        var firstIndex = Math.max(0, newActiveIndex - params.slidesPerView * params.loader.surroundGroups);
2450        var lastIndex = Math.min(newActiveIndex + params.slidesPerView * (1 + params.loader.surroundGroups) - 1, slides.length - 1);
2451        //Update Transforms
2452        if (newActiveIndex > 0) {
2453            var newTransform = -slideSize * (newActiveIndex - firstIndex);
2454            _this.setWrapperTranslate(newTransform);
2455            _this.setWrapperTransition(0);
2456        }
2457        var i; // loop index
2458        //New Slides
2459        if (params.loader.logic === 'reload') {
2460            _this.wrapper.innerHTML = '';
2461            var slidesHTML = '';
2462            for (i = firstIndex; i <= lastIndex; i++) {
2463                slidesHTML += params.loader.slidesHTMLType === 'outer' ? slides[i] : '<' + params.slideElement + ' class="' + params.slideClass + '" data-swiperindex="' + i + '">' + slides[i] + '</' + params.slideElement + '>';
2464            }
2465            _this.wrapper.innerHTML = slidesHTML;
2466        }
2467        else {
2468            var minExistIndex = 1000;
2469            var maxExistIndex = 0;
2470
2471            for (i = 0; i < _this.slides.length; i++) {
2472                var index = _this.slides[i].data('swiperindex');
2473                if (index < firstIndex || index > lastIndex) {
2474                    _this.wrapper.removeChild(_this.slides[i]);
2475                }
2476                else {
2477                    minExistIndex = Math.min(index, minExistIndex);
2478                    maxExistIndex = Math.max(index, maxExistIndex);
2479                }
2480            }
2481            for (i = firstIndex; i <= lastIndex; i++) {
2482                var newSlide;
2483                if (i < minExistIndex) {
2484                    newSlide = document.createElement(params.slideElement);
2485                    newSlide.className = params.slideClass;
2486                    newSlide.setAttribute('data-swiperindex', i);
2487                    newSlide.innerHTML = slides[i];
2488                    _this.wrapper.insertBefore(newSlide, _this.wrapper.firstChild);
2489                }
2490                if (i > maxExistIndex) {
2491                    newSlide = document.createElement(params.slideElement);
2492                    newSlide.className = params.slideClass;
2493                    newSlide.setAttribute('data-swiperindex', i);
2494                    newSlide.innerHTML = slides[i];
2495                    _this.wrapper.appendChild(newSlide);
2496                }
2497            }
2498        }
2499        //reInit
2500        _this.reInit(true);
2501    };
2502
2503    /*==================================================
2504        Make Swiper
2505    ====================================================*/
2506    function makeSwiper() {
2507        _this.calcSlides();
2508        if (params.loader.slides.length > 0 && _this.slides.length === 0) {
2509            _this.loadSlides();
2510        }
2511        if (params.loop) {
2512            _this.createLoop();
2513        }
2514        _this.init();
2515        initEvents();
2516        if (params.pagination) {
2517            _this.createPagination(true);
2518        }
2519
2520        if (params.loop || params.initialSlide > 0) {
2521            _this.swipeTo(params.initialSlide, 0, false);
2522        }
2523        else {
2524            _this.updateActiveSlide(0);
2525        }
2526        if (params.autoplay) {
2527            _this.startAutoplay();
2528        }
2529        /**
2530         * Set center slide index.
2531         *
2532         * @author        Tomaz Lovrec <[email protected]>
2533         */
2534        _this.centerIndex = _this.activeIndex;
2535
2536        // Callbacks
2537        if (params.onSwiperCreated) _this.fireCallback(params.onSwiperCreated, _this);
2538        _this.callPlugins('onSwiperCreated');
2539    }
2540
2541    makeSwiper();
2542};
2543
2544Swiper.prototype = {
2545    plugins : {},
2546
2547    /*==================================================
2548        Wrapper Operations
2549    ====================================================*/
2550    wrapperTransitionEnd : function (callback, permanent) {
2551        'use strict';
2552        var a = this,
2553            el = a.wrapper,
2554            events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],
2555            i;
2556
2557        function fireCallBack(e) {
2558            if (e.target !== el) return;
2559            callback(a);
2560            if (a.params.queueEndCallbacks) a._queueEndCallbacks = false;
2561            if (!permanent) {
2562                for (i = 0; i < events.length; i++) {
2563                    a.h.removeEventListener(el, events[i], fireCallBack);
2564                }
2565            }
2566        }
2567
2568        if (callback) {
2569            for (i = 0; i < events.length; i++) {
2570                a.h.addEventListener(el, events[i], fireCallBack);
2571            }
2572        }
2573    },
2574
2575    getWrapperTranslate : function (axis) {
2576        'use strict';
2577        var el = this.wrapper,
2578            matrix, curTransform, curStyle, transformMatrix;
2579
2580        // automatic axis detection
2581        if (typeof axis === 'undefined') {
2582            axis = this.params.mode === 'horizontal' ? 'x' : 'y';
2583        }
2584
2585        if (this.support.transforms && this.params.useCSS3Transforms) {
2586            curStyle = window.getComputedStyle(el, null);
2587            if (window.WebKitCSSMatrix) {
2588                // Some old versions of Webkit choke when 'none' is passed; pass
2589                // empty string instead in this case
2590                transformMatrix = new WebKitCSSMatrix(curStyle.webkitTransform === 'none' ? '' : curStyle.webkitTransform);
2591            }
2592            else {
2593                transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform  || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
2594                matrix = transformMatrix.toString().split(',');
2595            }
2596
2597            if (axis === 'x') {
2598                //Latest Chrome and webkits Fix
2599                if (window.WebKitCSSMatrix)
2600                    curTransform = transformMatrix.m41;
2601                //Crazy IE10 Matrix
2602                else if (matrix.length === 16)
2603                    curTransform = parseFloat(matrix[12]);
2604                //Normal Browsers
2605                else
2606                    curTransform = parseFloat(matrix[4]);
2607            }
2608            if (axis === 'y') {
2609                //Latest Chrome and webkits Fix
2610                if (window.WebKitCSSMatrix)
2611                    curTransform = transformMatrix.m42;
2612                //Crazy IE10 Matrix
2613                else if (matrix.length === 16)
2614                    curTransform = parseFloat(matrix[13]);
2615                //Normal Browsers
2616                else
2617                    curTransform = parseFloat(matrix[5]);
2618            }
2619        }
2620        else {
2621            if (axis === 'x') curTransform = parseFloat(el.style.left, 10) || 0;
2622            if (axis === 'y') curTransform = parseFloat(el.style.top, 10) || 0;
2623        }
2624        return curTransform || 0;
2625    },
2626
2627    setWrapperTranslate : function (x, y, z) {
2628        'use strict';
2629        var es = this.wrapper.style,
2630            coords = {x: 0, y: 0, z: 0},
2631            translate;
2632
2633        // passed all coordinates
2634        if (arguments.length === 3) {
2635            coords.x = x;
2636            coords.y = y;
2637            coords.z = z;
2638        }
2639
2640        // passed one coordinate and optional axis
2641        else {
2642            if (typeof y === 'undefined') {
2643                y = this.params.mode === 'horizontal' ? 'x' : 'y';
2644            }
2645            coords[y] = x;
2646        }
2647
2648        if (this.support.transforms && this.params.useCSS3Transforms) {
2649            translate = this.support.transforms3d ? 'translate3d(' + coords.x + 'px, ' + coords.y + 'px, ' + coords.z + 'px)' : 'translate(' + coords.x + 'px, ' + coords.y + 'px)';
2650            es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = translate;
2651        }
2652        else {
2653            es.left = coords.x + 'px';
2654            es.top  = coords.y + 'px';
2655        }
2656        this.callPlugins('onSetWrapperTransform', coords);
2657        if (this.params.onSetWrapperTransform) this.fireCallback(this.params.onSetWrapperTransform, this, coords);
2658    },
2659
2660    setWrapperTransition : function (duration) {
2661        'use strict';
2662        var es = this.wrapper.style;
2663        es.webkitTransitionDuration = es.MsTransitionDuration = es.msTransitionDuration = es.MozTransitionDuration = es.OTransitionDuration = es.transitionDuration = (duration / 1000) + 's';
2664        this.callPlugins('onSetWrapperTransition', {duration: duration});
2665        if (this.params.onSetWrapperTransition) this.fireCallback(this.params.onSetWrapperTransition, this, duration);
2666
2667    },
2668
2669    /*==================================================
2670        Helpers
2671    ====================================================*/
2672    h : {
2673        getWidth: function (el, outer, round) {
2674            'use strict';
2675            var width = window.getComputedStyle(el, null).getPropertyValue('width');
2676            var returnWidth = parseFloat(width);
2677            //IE Fixes
2678            if (isNaN(returnWidth) || width.indexOf('%') > 0 || returnWidth < 0) {
2679                returnWidth = el.offsetWidth - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-left')) - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-right'));
2680            }
2681            if (outer) returnWidth += parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-left')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-right'));
2682            if (round) return Math.ceil(returnWidth);
2683            else return returnWidth;
2684        },
2685        getHeight: function (el, outer, round) {
2686            'use strict';
2687            if (outer) return el.offsetHeight;
2688
2689            var height = window.getComputedStyle(el, null).getPropertyValue('height');
2690            var returnHeight = parseFloat(height);
2691            //IE Fixes
2692            if (isNaN(returnHeight) || height.indexOf('%') > 0 || returnHeight < 0) {
2693                returnHeight = el.offsetHeight - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-top')) - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-bottom'));
2694            }
2695            if (outer) returnHeight += parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-top')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-bottom'));
2696            if (round) return Math.ceil(returnHeight);
2697            else return returnHeight;
2698        },
2699        getOffset: function (el) {
2700            'use strict';
2701            var box = el.getBoundingClientRect();
2702            var body = document.body;
2703            var clientTop  = el.clientTop  || body.clientTop  || 0;
2704            var clientLeft = el.clientLeft || body.clientLeft || 0;
2705            var scrollTop  = window.pageYOffset || el.scrollTop;
2706            var scrollLeft = window.pageXOffset || el.scrollLeft;
2707            if (document.documentElement && !window.pageYOffset) {
2708                //IE7-8
2709                scrollTop  = document.documentElement.scrollTop;
2710                scrollLeft = document.documentElement.scrollLeft;
2711            }
2712            return {
2713                top: box.top  + scrollTop  - clientTop,
2714                left: box.left + scrollLeft - clientLeft
2715            };
2716        },
2717        windowWidth : function () {
2718            'use strict';
2719            if (window.innerWidth) return window.innerWidth;
2720            else if (document.documentElement && document.documentElement.clientWidth) return document.documentElement.clientWidth;
2721        },
2722        windowHeight : function () {
2723            'use strict';
2724            if (window.innerHeight) return window.innerHeight;
2725            else if (document.documentElement && document.documentElement.clientHeight) return document.documentElement.clientHeight;
2726        },
2727        windowScroll : function () {
2728            'use strict';
2729            if (typeof pageYOffset !== 'undefined') {
2730                return {
2731                    left: window.pageXOffset,
2732                    top: window.pageYOffset
2733                };
2734            }
2735            else if (document.documentElement) {
2736                return {
2737                    left: document.documentElement.scrollLeft,
2738                    top: document.documentElement.scrollTop
2739                };
2740            }
2741        },
2742
2743        addEventListener : function (el, event, listener, useCapture) {
2744            'use strict';
2745            if (typeof useCapture === 'undefined') {
2746                useCapture = false;
2747            }
2748
2749            if (el.addEventListener) {
2750                el.addEventListener(event, listener, useCapture);
2751            }
2752            else if (el.attachEvent) {
2753                el.attachEvent('on' + event, listener);
2754            }
2755        },
2756
2757        removeEventListener : function (el, event, listener, useCapture) {
2758            'use strict';
2759            if (typeof useCapture === 'undefined') {
2760                useCapture = false;
2761            }
2762
2763            if (el.removeEventListener) {
2764                el.removeEventListener(event, listener, useCapture);
2765            }
2766            else if (el.detachEvent) {
2767                el.detachEvent('on' + event, listener);
2768            }
2769        }
2770    },
2771    setTransform : function (el, transform) {
2772        'use strict';
2773        var es = el.style;
2774        es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = transform;
2775    },
2776    setTranslate : function (el, translate) {
2777        'use strict';
2778        var es = el.style;
2779        var pos = {
2780            x : translate.x || 0,
2781            y : translate.y || 0,
2782            z : translate.z || 0
2783        };
2784        var transformString = this.support.transforms3d ? 'translate3d(' + (pos.x) + 'px,' + (pos.y) + 'px,' + (pos.z) + 'px)' : 'translate(' + (pos.x) + 'px,' + (pos.y) + 'px)';
2785        es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = transformString;
2786        if (!this.support.transforms) {
2787            es.left = pos.x + 'px';
2788            es.top = pos.y + 'px';
2789        }
2790    },
2791    setTransition : function (el, duration) {
2792        'use strict';
2793        var es = el.style;
2794        es.webkitTransitionDuration = es.MsTransitionDuration = es.msTransitionDuration = es.MozTransitionDuration = es.OTransitionDuration = es.transitionDuration = duration + 'ms';
2795    },
2796    /*==================================================
2797        Feature Detection
2798    ====================================================*/
2799    support: {
2800
2801        touch : (window.Modernizr && Modernizr.touch === true) || (function () {
2802            'use strict';
2803            return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
2804        })(),
2805
2806        transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {
2807            'use strict';
2808            var div = document.createElement('div').style;
2809            return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);
2810        })(),
2811
2812        transforms : (window.Modernizr && Modernizr.csstransforms === true) || (function () {
2813            'use strict';
2814            var div = document.createElement('div').style;
2815            return ('transform' in div || 'WebkitTransform' in div || 'MozTransform' in div || 'msTransform' in div || 'MsTransform' in div || 'OTransform' in div);
2816        })(),
2817
2818        transitions : (window.Modernizr && Modernizr.csstransitions === true) || (function () {
2819            'use strict';
2820            var div = document.createElement('div').style;
2821            return ('transition' in div || 'WebkitTransition' in div || 'MozTransition' in div || 'msTransition' in div || 'MsTransition' in div || 'OTransition' in div);
2822        })(),
2823
2824        classList : (function () {
2825            'use strict';
2826            var div = document.createElement('div');
2827            return 'classList' in div;
2828        })()
2829    },
2830
2831    browser : {
2832
2833        ie8 : (function () {
2834            'use strict';
2835            var rv = -1; // Return value assumes failure.
2836            if (navigator.appName === 'Microsoft Internet Explorer') {
2837                var ua = navigator.userAgent;
2838                var re = new RegExp(/MSIE ([0-9]{1,}[\.0-9]{0,})/);
2839                if (re.exec(ua) !== null)
2840                    rv = parseFloat(RegExp.$1);
2841            }
2842            return rv !== -1 && rv < 9;
2843        })(),
2844
2845        ie10 : window.navigator.msPointerEnabled,
2846        ie11 : window.navigator.pointerEnabled
2847    }
2848};
2849
2850/*=========================
2851  jQuery & Zepto Plugins
2852  ===========================*/
2853if (window.jQuery || window.Zepto) {
2854    (function ($) {
2855        'use strict';
2856        $.fn.swiper = function (params) {
2857            var firstInstance;
2858            this.each(function (i) {
2859                var that = $(this);
2860                var s = new Swiper(that[0], params);
2861                if (!i) firstInstance = s;
2862                that.data('swiper', s);
2863            });
2864            return firstInstance;
2865        };
2866    })(window.jQuery || window.Zepto);
2867}
2868
2869// CommonJS support
2870if (typeof(module) !== 'undefined') {
2871    module.exports = Swiper;
2872
2873// requirejs support
2874} else if (typeof define === 'function' && define.amd) {
2875    define([], function () {
2876        'use strict';
2877        return Swiper;
2878    });
2879}

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.